Repository navigation
feat(ui): align navbar and footer chrome with the redesign canvas - #452
Conversation
Lunaria Status Overview🌕 This pull request will trigger status changes. Learn moreBy default, every PR changing files present in the Lunaria configuration's You can change this by adding one of the keywords present in the Tracked Files
Warnings reference
|
|
2 findings · reviewed 🟠
|
There was a problem hiding this comment.
ℹ️ No critical issues — two small rough edges inline.
Reviewed changes
Reviewed the full single-commit diff (35 files) against refactor/v3.
- Header menus: desktop
UNavigationMenunow renders#features-contentand#applications-contentslots with icon/avatar rows, a controlledopenMenumodel, and a bordered 36px pill. useHeader(): desktop and mobile menus sharefeaturesGroup,applicationsGroupandcommandsLink, and exposefeatureLinksandapplicationLinks.- Footer: the Netlify badge leads with a status dot, and
BuildEnvironmentbecomes a mono pill. - i18n:
nav.staryl_descriptionandnav.wolfstar_descriptionare added, empty in every non-English locale, with the schema updated. - Tests: new header menu,
useHeaderandBuildEnvironmentspecs, plus a scoped a11y logo assertion.
I checked that the --home-* tokens and apps.*.avatar/explore exist, that color-mix() isn't caught by the design-token guardrail, and that the vertical UNavigationMenu renders only childItem.icon (so the avatar/icon split is correct).
claude-sonnet-5-5 | 𝕏
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## refactor/v3 #452 +/- ##
===============================================
+ Coverage 48.25% 48.41% +0.16%
===============================================
Files 326 326
Lines 7011 7037 +26
Branches 1397 1399 +2
===============================================
+ Hits 3383 3407 +24
Misses 2542 2542
- Partials 1086 1088 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
ℹ️ No critical issues — the new commit is a small CSS change; the two earlier threads are still open.
Reviewed changes
Reviewed the delta since the prior pullfrog review (f7d1a40 → 670c892), one CSS hunk in app/components/app/Header.vue.
- Solid navbar:
.app-navbarnow usesbackground-color: var(--color-base-100)withbackdrop-filter: noneinstead of the translucentcolor-mix()blur, so the header matches the page surface.
The token resolves in both themes (--color-base-100 is defined in app/assets/css/main.css) and no hardcoded colors were added. The earlier threads on the brand lockup (Header.vue:9) and the commandsLink px-4 leaking into the mobile menu (useHeader.ts:76) are not touched by this commit and stay open.
ℹ️ PR description still says the header is translucent
The description states "the header turns translucent", which 670c892 reverses. Update that sentence so the stack's history matches the code.
claude-sonnet-5-5 | 𝕏
670c892 to
7f9cc5c
Compare
f86d8b6 to
8d38d76
Compare
Dismissed because a newer commit was pushed; Greptile will re-review the current head.
7f9cc5c to
1163d5f
Compare
Dismissed because a newer commit was pushed; Greptile will re-review the current head.
1163d5f to
dcc0539
Compare
c6c694a to
1a8fcde
Compare
Dismissed because a newer commit was pushed; Greptile will re-review the current head.
- Brand lockup is the app icon plus its name for both WolfStar and Staryl; the header is translucent so content scrolls under it. - The desktop nav pill gains a border, a 36px item height and an open state. Features entries get leading icons and descriptions, Applications entries get their avatar and a tagline, both rendered by custom `UNavigationMenu` content slots. Selecting an entry closes the panel, since the rows are plain links and the header survives navigation. - `useHeader()` exposes `featureLinks` and `applicationLinks` and builds the desktop and mobile menus from the same groups, so the two can no longer drift. - The footer's Netlify badge leads with a deploy status dot and the build info renders as a bordered mono status pill. - New `nav.wolfstar_description` / `nav.staryl_description` keys, added to every locale as empty placeholders. Co-authored-by: Claude <noreply@anthropic.com>
The redesign's navbar is one flat colour with the home page. The header was translucent with a blur, which showed the page's top gradient and the content scrolling under it through the bar. Co-authored-by: Claude <noreply@anthropic.com>
…e commands padding to desktop
dcc0539 to
342d868
Compare
Dismissed because a newer commit was pushed; Greptile will re-review the current head.
…showcases (#453) ### 🔗 Linked issue Part of the stack superseding #422. Depends on #452. **Stack:** #451 foundation ← #452 header/footer ← #453 marketing ← #454 `/app` dashboard ← #455 V7 schema + Prisma ORM 8 (draft) ### 🧭 Context Marketing sections on `/` and `/staryl` follow the canvas. On top of the visual port from #422 this layer defers hydration of the heavy demos, which the original PR did not do. ### 📚 Description Hero briefs become cards, product proof moves to a three-card grid with an icon per step, CTAs become a centred bordered panel with a faded brand watermark. `OtherApps` renders siblings as `SurfaceCard`s and the WolfStar home shows the dashboard section before the commands demo. The three showcases below the fold (`WolfstarModerationShowcase`, `WolfstarCommandsShowcase`, `StarylCommandsShowcase`) are 600 to 1300 lines each and were already `Lazy` chunks. They now use `hydrate-on-visible`, so the SSR markup is unchanged but their JavaScript stops competing with the hero until they scroll into view. Not measured yet; happy to run Lighthouse before/after on the preview if wanted. > 🤖 AI disclosure: [Wolfstar Agent Kit](https://github.com/wolfstar-project/wolfstar-agent-kit) modified this description. [My AI open-source policy](https://harlanzw.com/blog/ai-in-open-source). <!-- greptile_comment --> <!-- greptile_summary --> <h2><a href="https://app.greptile.com/api/retrigger?id=78359978"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img alt="Retrigger" src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2" align="right"></picture></a>Confidence Score: 5/5</h2> <!-- greptile-impact-verdict --> No outstanding findings block merging this PR. The approved card layout remains a maintainer-owned design-guide decision. <h3>Summary</h3> Updates the marketing pages with card-based hero briefs, proof sections, and centered closing panels. - Product proof appears as three cards with an icon for each step. - The closing calls to action sit in centered panels with faint brand marks. - Showcase demos wait to hydrate until they are near the viewport. - Hero briefs appear as filled cards with primary-color labels. - Other apps appear as cards with their details and actions. <!-- greptile_confidence_score:5 --> <sub>Reviews (6) · Last reviewed commit: ["fix(ui): preload lazy showcases early an..."](1823c81) · [Reviewed by Greptile](https://www.greptile.com/?utm_source=greptile_expert&utm_medium=github&utm_campaign=code_reviews&utm_content=wolfstar-project/wolfstar.rocks)</sub> <!-- /greptile_comment -->
…454) ### 🔗 Linked issue Part of the stack superseding #422. Depends on #453. **Stack:** #451 foundation ← #452 header/footer ← #453 marketing ← #454 `/app` dashboard ← #455 V7 schema + Prisma ORM 8 (draft) ### 🧭 Context The dashboard becomes one client-rendered page that keeps the active guild in state instead of the URL. Unlike #422 this layer does not depend on the V7 schema: it runs against the current database and typechecks. ### 📚 Description `app/pages/app.vue` renders the picker, the section components and the logs panel inside the dashboard layout, which gains a server rail, a Modules summary card and grouped sidebar navigation. `useActiveGuild()` holds guild, section and logs tab; `useDashboardNavigation()` parks any switch behind the unsaved-changes dialog while edits are staged. The three guild stores are keyed per guild, and the save handler captures the guild id before awaiting so a late PATCH response cannot clear another guild's draft. The selection is mirrored to localStorage so a reload lands on the same server. `/guilds/:id/manage/*` and `/guilds/:id/logs/*` stay as shims that record the target into state and forward to `/app`. Route rules: `/app` is `ssr: false`, not prerendered, out of the sitemap and `robots: false`; `/guilds/**` is `robots: false` as well (new here, the auth-gated shims were indexable before). `@vueuse/router` has no remaining usage and is removed; the lockfile diff is limited to that package. Open question: the shims render a spinner on the server and redirect in the browser because the guild id has to land in client state. A route middleware would be cleaner but cannot write that state. Fine with the current shape unless someone has a better idea. ### 🎨 Console layout The dashboard now follows the console redesign (rail, sidebar, title bar, cards), with the phone, foldable and tablet variants. - **Shell.** A server rail, a sidebar whose sections are grouped under Modules and Records, a 48px title bar with the unsaved-changes pill, and a docked save bar. On phones the sidebar and the rail move into a drawer and the main sections get a tab bar. - **Sidebar.** Sections can be pinned and the ones opened last appear as shortcuts. Both are browser-local (`wolfstar-dashboard-nav`) and never reach the server. `app/utils/dashboard-nav.ts` is the single list the sidebar, the tab bar and the page title read. - **Overview.** Counts of the server, the moderation actions of the last seven days as a chart, the module list and the activity feed in cards. Everything shown is read from the existing log and guild routes; the chart is bucketed in the browser from one page of the moderation log (its total is the log's own, so it stays exact past 100 actions and the chart says so). - **Surfaces.** Rail, sidebar, cards and page use the design system's ink scale (`--ink-*`, added next to the spectrum tokens) in the dark theme and white with a tinted rail in the light one. `console-card` and `console-label` are the shared utilities. Later layers adapt what they own: #455 lays the settings sections out as cards, #457 the auto-moderation rules, #461 swaps the `/profile` links for the preferences dialog. ###⚠️ Not in the design The mockup also has Auto-Delete and Auto-Purge pages, a "Prisma 8 contract" badge and an open-reports count. Auto-Delete and Auto-Purge are not here: the tables exist in the contract but the dashboard has no routes for them, so they need their own layer. The badge and the open-reports count are mock data with nothing behind them. > 🤖 AI disclosure: [Wolfstar Agent Kit](https://github.com/wolfstar-project/wolfstar-agent-kit) modified this description. [My AI open-source policy](https://harlanzw.com/blog/ai-in-open-source). <!-- greptile_comment --> <!-- greptile_summary --> <h2><a href="https://app.greptile.com/api/retrigger?id=78359990"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img alt="Retrigger" src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2" align="right"></picture></a>Confidence Score: 4/5</h2> <!-- greptile-risk --> Do not merge until the outstanding settings-edit loss in previous comment 1 is fixed; the two new navigation and activity-display concerns are non-blocking. <h2>T-Rex evidence</h2> **[Evidence from the check](https://app.greptile.com/trex/artifacts/747f3009-3e3d-45fe-bf44-75536b9ebbe8)** - The component test exercises both real card variants with Ctrl, Meta, and ordinary clicks using actual composables; its latest event-observation revision still needs execution. **[Evidence from the check](https://app.greptile.com/trex/artifacts/dd50729a-d872-4d2b-bb7a-bb04b6ddcd5c)** - The configuration launches Chromium through Playwright and supplies click, viewport, video, and poster capture commands; the latest commands still need a completed run. **[Evidence from the check](https://app.greptile.com/trex/artifacts/10446552-fa3f-41b7-a293-b53f0b1f41f4)** - The card was extracted with git show from the specified base and rendered without editing tracked source; this is the executed baseline component. **[Command output from the check](https://app.greptile.com/trex/artifacts/616e8d30-a318-4665-8720-c9f50d4504f9)** - The last completed base run captured unchanged original-tab guild, section, and route after Ctrl-click, then failed because no new tab was observed; this proves only the baseline state behavior. **[Command output from the check](https://app.greptile.com/trex/artifacts/5ae81b80-790f-48a6-87ca-3418dc486b4d)** - Git show captured numbered card and composable source from head and all four requested higher snapshots; the inspected paths retain the unconditional click handler. **[Command output from the check](https://app.greptile.com/trex/artifacts/a0076d94-fec5-4a45-9d22-791ac7467f71)** - The initial Chromium run failed because the real tooltip lacked its provider; the harness subsequently added the provider and reached the click path. **[After: Pr454 Failed Counts Success](https://app.greptile.com/trex/artifacts/293fa0c1-8663-459f-9a98-12b5a00f1c55)** - What the screen looked like at this point in the check. **[After: Pr454 Failed Counts Failure](https://app.greptile.com/trex/artifacts/60997d03-470a-470f-be48-710650912213)** - What the screen looked like at this point in the check. **[After: Pr454 Failed Counts Empty](https://app.greptile.com/trex/artifacts/4979ecb2-b282-4ef4-9013-99f5024e6b98)** - What the screen looked like at this point in the check. **[▶ page@b1577e3ac2036f8690dfae10f2d355d0.webm](https://app.greptile.com/trex/artifacts/b8ad8f63-abf6-4366-ae6b-f57d29efc060)** - The flow T-Rex ran, recorded end to end. **[Before: Pr454 Failed Counts Success](https://app.greptile.com/trex/artifacts/56846c8e-03bc-40ae-ab99-7b8aea18bcd8)** - What the screen looked like at this point in the check. **[Before: Pr454 Failed Counts Failure](https://app.greptile.com/trex/artifacts/9f43d5fc-5383-4dd3-9125-d44291742d2a)** - What the screen looked like at this point in the check. **[Before: Pr454 Failed Counts Empty](https://app.greptile.com/trex/artifacts/90962557-d069-410a-bd12-46842b9a2c3b)** - What the screen looked like at this point in the check. **[▶ page@db1d5220ce2e59a5e6a32fafa94e0c50.webm](https://app.greptile.com/trex/artifacts/64e81fbb-b1cd-46b3-ac38-b081bc7137b7)** - The flow T-Rex ran, recorded end to end. **[▶ Recording of the check](https://app.greptile.com/trex/artifacts/b8ad8f63-abf6-4366-ae6b-f57d29efc060)** - Recorded the base component with populated, failing and empty endpoint configurations; the original overview has no activity counts or chart. **[▶ Recording of the check](https://app.greptile.com/trex/artifacts/64e81fbb-b1cd-46b3-ac38-b081bc7137b7)** - Recorded each condition for approximately six seconds with the real composables; failed requests present the same zero activity as successful empty responses. **[Base overview with populated activity endpoints configured](https://app.greptile.com/trex/artifacts/56846c8e-03bc-40ae-ab99-7b8aea18bcd8)** - Captured the rendered base component with populated endpoints available; it does not display moderation or command activity. **[Base overview with failed activity endpoints configured](https://app.greptile.com/trex/artifacts/9f43d5fc-5383-4dd3-9125-d44291742d2a)** - Captured the rendered base component with failing endpoints available; it has no activity counts or chart to misrepresent those failures. **[Base overview with empty activity endpoints configured](https://app.greptile.com/trex/artifacts/90962557-d069-410a-bd12-46842b9a2c3b)** - Captured the rendered base component with empty endpoints available; its activity presentation remains absent. **[Head overview after populated successful requests](https://app.greptile.com/trex/artifacts/293fa0c1-8663-459f-9a98-12b5a00f1c55)** - Captured the head after successful requests settled; DOM assertions verified six cases, twelve commands and nonzero chart activity. **[Head overview after activity requests failed](https://app.greptile.com/trex/artifacts/60997d03-470a-470f-be48-710650912213)** - Captured the head after both requests reached error status; DOM assertions verified zero counts and seven zero-height bars without failure copy. **[Head overview after successful empty requests](https://app.greptile.com/trex/artifacts/4979ecb2-b282-4ef4-9013-99f5024e6b98)** - Captured the head after successful empty responses; its counts and chart accessibility text match the failed-request condition. **[Evidence from the check](https://app.greptile.com/trex/artifacts/8912b975-e7f7-4bb3-bbdb-498446d0f2d8)** - Executed this uniquely named test against both snapshots; it asserts the observed success, failure and empty-response presentations. **[Evidence from the check](https://app.greptile.com/trex/artifacts/560c70bd-12ce-4505-94a8-1f50ce5516b7)** - Used this configuration to run the component test and capture browser observations; unrelated agent tests were not included. **[Evidence from the check](https://app.greptile.com/trex/artifacts/c4c41f0a-8c42-44d2-b8be-2c55bac4ef3c)** - Exported the exact base component using git show and imported it into the browser test; no checkout was needed. **[Evidence from the check](https://app.greptile.com/trex/artifacts/23cc6a71-ac8b-4cc5-b7cd-d0c78b7a7146)** - Exported the exact head component using git show and imported it into the browser test; its activity failure behavior was exercised directly. **[Command output from the check](https://app.greptile.com/trex/artifacts/1ab25530-22b0-47c1-b5a8-b6709be2f0d1)** - Captured the successful base test command and observed DOM output; the original overview has no activity counts, chart or activity requests. **[Command output from the check](https://app.greptile.com/trex/artifacts/9a6296ab-fe1d-479b-a603-7d5bfc9151c0)** - Captured the successful head test command, request queries, error messages and equality assertions; failed activity is displayed exactly like empty activity. **[Command output from the check](https://app.greptile.com/trex/artifacts/70438c94-ff0c-4686-a05d-440c3264c8f2)** - Repeated the head test and captured rendered text, dimensions and visible ancestors alongside request results; the failure presentation exists in the rendered browser layout. **[Command output from the check](https://app.greptile.com/trex/artifacts/bdf87b92-0d78-4e3c-baaa-e4d828c058d4)** - Captured 19 git show and diff commands with line-numbered output; all four higher snapshots retain the activity status/error omission. **[Evidence from the check](https://app.greptile.com/trex/artifacts/747f3009-3e3d-45fe-bf44-75536b9ebbe8)** - The component test exercises both real card variants with Ctrl, Meta, and ordinary clicks using actual composables; its latest event-observation revision still needs execution. **[Evidence from the check](https://app.greptile.com/trex/artifacts/dd50729a-d872-4d2b-bb7a-bb04b6ddcd5c)** - The configuration launches Chromium through Playwright and supplies click, viewport, video, and poster capture commands; the latest commands still need a completed run. **[Evidence from the check](https://app.greptile.com/trex/artifacts/10446552-fa3f-41b7-a293-b53f0b1f41f4)** - The card was extracted with git show from the specified base and rendered without editing tracked source; this is the executed baseline component. **[Command output from the check](https://app.greptile.com/trex/artifacts/616e8d30-a318-4665-8720-c9f50d4504f9)** - The last completed base run captured unchanged original-tab guild, section, and route after Ctrl-click, then failed because no new tab was observed; this proves only the baseline state behavior. **[Command output from the check](https://app.greptile.com/trex/artifacts/5ae81b80-790f-48a6-87ca-3418dc486b4d)** - Git show captured numbered card and composable source from head and all four requested higher snapshots; the inspected paths retain the unconditional click handler. **[Command output from the check](https://app.greptile.com/trex/artifacts/a0076d94-fec5-4a45-9d22-791ac7467f71)** - The initial Chromium run failed because the real tooltip lacked its provider; the harness subsequently added the provider and reached the click path. **[▶ Recording of the check](https://app.greptile.com/trex/artifacts/b8ad8f63-abf6-4366-ae6b-f57d29efc060)** - Recorded the base component with populated, failing and empty endpoint configurations; the original overview has no activity counts or chart. **[▶ Recording of the check](https://app.greptile.com/trex/artifacts/64e81fbb-b1cd-46b3-ac38-b081bc7137b7)** - Recorded each condition for approximately six seconds with the real composables; failed requests present the same zero activity as successful empty responses. **[Base overview with populated activity endpoints configured](https://app.greptile.com/trex/artifacts/56846c8e-03bc-40ae-ab99-7b8aea18bcd8)** - Captured the rendered base component with populated endpoints available; it does not display moderation or command activity. **[Base overview with failed activity endpoints configured](https://app.greptile.com/trex/artifacts/9f43d5fc-5383-4dd3-9125-d44291742d2a)** - Captured the rendered base component with failing endpoints available; it has no activity counts or chart to misrepresent those failures. **[Base overview with empty activity endpoints configured](https://app.greptile.com/trex/artifacts/90962557-d069-410a-bd12-46842b9a2c3b)** - Captured the rendered base component with empty endpoints available; its activity presentation remains absent. **[Head overview after populated successful requests](https://app.greptile.com/trex/artifacts/293fa0c1-8663-459f-9a98-12b5a00f1c55)** - Captured the head after successful requests settled; DOM assertions verified six cases, twelve commands and nonzero chart activity. **[Head overview after activity requests failed](https://app.greptile.com/trex/artifacts/60997d03-470a-470f-be48-710650912213)** - Captured the head after both requests reached error status; DOM assertions verified zero counts and seven zero-height bars without failure copy. **[Head overview after successful empty requests](https://app.greptile.com/trex/artifacts/4979ecb2-b282-4ef4-9013-99f5024e6b98)** - Captured the head after successful empty responses; its counts and chart accessibility text match the failed-request condition. **[Evidence from the check](https://app.greptile.com/trex/artifacts/8912b975-e7f7-4bb3-bbdb-498446d0f2d8)** - Executed this uniquely named test against both snapshots; it asserts the observed success, failure and empty-response presentations. **[Evidence from the check](https://app.greptile.com/trex/artifacts/560c70bd-12ce-4505-94a8-1f50ce5516b7)** - Used this configuration to run the component test and capture browser observations; unrelated agent tests were not included. **[Evidence from the check](https://app.greptile.com/trex/artifacts/c4c41f0a-8c42-44d2-b8be-2c55bac4ef3c)** - Exported the exact base component using git show and imported it into the browser test; no checkout was needed. **[Evidence from the check](https://app.greptile.com/trex/artifacts/23cc6a71-ac8b-4cc5-b7cd-d0c78b7a7146)** - Exported the exact head component using git show and imported it into the browser test; its activity failure behavior was exercised directly. **[Command output from the check](https://app.greptile.com/trex/artifacts/1ab25530-22b0-47c1-b5a8-b6709be2f0d1)** - Captured the successful base test command and observed DOM output; the original overview has no activity counts, chart or activity requests. **[Command output from the check](https://app.greptile.com/trex/artifacts/9a6296ab-fe1d-479b-a603-7d5bfc9151c0)** - Captured the successful head test command, request queries, error messages and equality assertions; failed activity is displayed exactly like empty activity. **[Command output from the check](https://app.greptile.com/trex/artifacts/70438c94-ff0c-4686-a05d-440c3264c8f2)** - Repeated the head test and captured rendered text, dimensions and visible ancestors alongside request results; the failure presentation exists in the rendered browser layout. **[Command output from the check](https://app.greptile.com/trex/artifacts/bdf87b92-0d78-4e3c-baaa-e4d828c058d4)** - Captured 19 git show and diff commands with line-numbered output; all four higher snapshots retain the activity status/error omission. <a href="https://app.greptile.com/trex/runs/31698547/artifacts?artifact=747f3009-3e3d-45fe-bf44-75536b9ebbe8"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewArtifactsDark.svg?v=4"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewArtifacts.svg?v=4"><img alt="View artifacts" src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewArtifacts.svg?v=4"></picture></a> <h3>Summary</h3> Replaces guild-specific dashboard pages with a client-rendered `/app` page. - Server settings and logs now open inside one `/app` dashboard. - The dashboard adds a grouped sidebar, server rail, and phone navigation. - The dashboard brings server stats, module settings, and logs into sections. - New dashboard and server-setting labels appear across the supported languages. ### T-Rex validation blocked The server-card modifier-click check could not complete because its browser validation session reached its execution limit before running the current-card comparison. The completed baseline run does not establish or contradict the current-card behavior. <!-- greptile_confidence_score:4 --> <sub>Reviews (9) · Last reviewed commit: ["fix(dashboard): keep a single hover high..."](69b75cd) · [Reviewed by Greptile](https://www.greptile.com/?utm_source=greptile_expert&utm_medium=github&utm_campaign=code_reviews&utm_content=wolfstar-project/wolfstar.rocks)</sub> <!-- /greptile_comment -->
…ly (#455) ### 🔗 Linked issue Part of the stack superseding #422. Depends on #454. Follows the bot's V7 branch, wolfstar-project/wolfstar#208. **Stack:** #451 foundation ← #452 header/footer ← #453 marketing ← #454 `/app` dashboard ← #455 V7 contract + ORM 8 only ← #457 auto-moderation rules ### 🧭 Context The bot's V7 branch runs on Prisma ORM 8 only and reshaped the database: settings live in normalized tables under `Modules`, and auto-moderation is one `GuildAutoModerationRule` row per rule instead of per-filter columns. The first commit on this branch followed an earlier snapshot of that contract, kept Prisma 7 next to ORM 8, and left typecheck red because nobody had decided how one settings view maps onto the new tables. The bot has decided since, so this PR copies its answer. ### 📚 Description **Prisma 7 is gone.** `schema.prisma`, `prisma7.config.ts`, `@prisma/client`, the pg adapter, the generator and every `prisma:migrate:*` script are removed. `prisma:generate` now runs `prisma contract emit`, so Netlify and CI call the same task as before. **The contract comes from the bot's repository.** `vendor/wolfstar` is a git submodule of wolfstar-project/wolfstar tracking `V7`, and `prisma.config.ts` reads `projects/database/src/contract.prisma` from it. The bot changes the contract and migrates first; this app follows by bumping the submodule, which Renovate can open as a PR. Versions match the bot's (`@prisma/orm-postgres` rc.13, `prisma` rc.19, the typed-JSON extension with its patch). A unit test compares the emitted storage hash with the one the pinned bot commit records for its migrations: ``` "storageHash":"c43f2589cd8e65306a24f8c685dddf640e494f3301c6087bfe5da06da7e4412c" ``` The artefacts are emitted into the gitignored `server/database/generated/prisma/` on `postinstall`, which also initializes the submodule when a checkout left it empty, so no workflow needs `submodules: true`. **Settings model.** `GuildData` is the bot's flat object; `columns.ts` maps each key to its table and column and `storage.ts` reads and writes the tables in one transaction. The settings UI moves to those keys: Home, Modules, Auto-moderation, Moderation, Channels, Roles, Commands, Reports. V7 has no prefix, no `selfmod*` filters and no `events*` / `messagesModeration*` settings, so the seven filter pages and the Events page are removed here; #457 brings auto-moderation back as rules. **Audit drain on ORM 8.** The façade exposes no isolation level, so appends are serialized with the advisory lock the bot's `AuditLogManager` takes. Two things I found on the way and fixed here: - Channels always opened empty, whatever was saved. It now shows the saved channels. - rc.13 rejects `url: ""` when the client is constructed, which broke prerendering at build time where `DATABASE_URL` is unset. The client gets `undefined` instead and connects lazily. Settings PATCH bodies used to be written as sent. They now go through a validator that refuses unknown keys and wrong value types with a 400. ###⚠️ Things a reviewer should decide - **Migrations belong to the bot now**, and its ORM 8 migrations are visible under `vendor/wolfstar/projects/database/migrations/`. I kept `server/database/migrations/` because `20260920000000_v7_contract_and_modules` is still the only DDL for the tables the contract marks `@@control(external)`; nothing here applies it. It should move to the bot's repo, after which the directory can go. - **Only the contract is shared.** The bot's `columns.ts` / `storage.ts` import its own build output, so they are ported here by hand and have to follow a submodule bump manually; typecheck catches a column that disappeared. Publishing `wolfstar-database` as a package would remove the ports. - **The bot caches settings per process** and only drops the cache on its own writes. A dashboard save reaches the database at once but the bot acts on it only after its cache is invalidated. Same as before this PR, more visible now that both sides share one model. - **The two services hash audit rows differently** (`shared/audit/envelope.ts` here, `AuditLogEnvelope.ts` in the bot), so `pnpm audit:verify` will flag rows the bot wrote. Not introduced here, not solved here. - Locale files: a translation is kept only where its English source did not change, everything else is an empty placeholder. > 🤖 AI disclosure: [Wolfstar Agent Kit](https://github.com/wolfstar-project/wolfstar-agent-kit) modified this description. [My AI open-source policy](https://harlanzw.com/blog/ai-in-open-source). <!-- greptile_comment --> <!-- greptile_summary --> <h2><a href="https://app.greptile.com/api/retrigger?id=78360005"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img alt="Retrigger" src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2" align="right"></picture></a>Confidence Score: 4/5</h2> <!-- greptile-risk --> The unresolved settings-column mismatch blocks merging safely for databases built from the supplied migrations; the duplicate-user validation and older-history formatting concerns are non-blocking. <h3>Summary</h3> This PR switches the dashboard to the bot’s pinned V7 contract and Prisma ORM 8. - The dashboard builds its database client from the bot’s V7 contract. - Dashboard settings map to the bot’s normalized tables. - The dashboard’s settings pages follow the bot’s V7 sections. - Dashboard audit writes share the bot’s lock for the audit chain. - Log pages and API queries use the ORM 8 database contract. - Settings controls use the V7 keys and show saved values. - Locale text and schemas match the V7 dashboard settings. <!-- greptile_confidence_score:4 --> <sub>Reviews (15) · Last reviewed commit: ["feat(dashboard): name the sections Auto ..."](4c434a3) · [Reviewed by Greptile](https://www.greptile.com/?utm_source=greptile_expert&utm_medium=github&utm_campaign=code_reviews&utm_content=wolfstar-project/wolfstar.rocks)</sub> <!-- /greptile_comment -->
### 🔗 Linked issue Part of the stack superseding #422. Depends on #455. **Stack:** #451 foundation ← #452 header/footer ← #453 marketing ← #454 `/app` dashboard ← #455 V7 contract + ORM 8 only ← #457 auto-moderation rules ### 🧭 Context V7 stores auto-moderation as one row per rule (type, thresholds, actions, JSON options). #455 removed the seven V6 filter pages because their columns no longer exist; without this layer the dashboard cannot configure auto-moderation at all. ### 📚 Description A rule list and editor in the Auto-moderation section, backed by `GET/POST /api/guilds/:guild/automod/rules` and `PATCH/DELETE …/rules/:rule`. Rules are rows rather than settings keys, so they skip the staged-changes bar and save when confirmed. Request bodies go through the bot's own validator, ported with its limits and its `confusables` word normalization, so a rule written here is one the bot's API would accept. The editor covers all 21 rule types from the type's default options, plus thresholds, soft actions, punishment, escalation steps and exemptions. ###⚠️ Open questions - **The bot will not see a rule until its cache drops.** It caches rules per process and invalidates on its own shard messages. The bot already exposes these same routes behind its own auth; proxying to them would fix this, but the dashboard cannot authenticate against the bot's API today. I wrote to the database directly, as the settings routes do. If that is not acceptable, hold this PR. - I have not run this against a live V7 database. The service, validator and components are covered with mocked storage only. - Name uniqueness across processes relies on the index `GuildAutoModerationRule_guild_id_name_key`, whose name I took from the bot's code. The contract does not declare it, so I could not confirm it exists. > 🤖 AI disclosure: [Wolfstar Agent Kit](https://github.com/wolfstar-project/wolfstar-agent-kit) modified this description. [My AI open-source policy](https://harlanzw.com/blog/ai-in-open-source). <!-- greptile_comment --> <!-- greptile_summary --> <h2><a href="https://app.greptile.com/api/retrigger?id=78384596"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img alt="Retrigger" src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2" align="right"></picture></a>Confidence Score: 3/5</h2> <!-- greptile-risk --> Do not merge until the two outstanding issues are fixed: a successful API save can leave a Timeout that the bot skips, and saving an older editor can silently undo another admin’s saved configuration. <h3>Summary</h3> Adds dashboard controls to create, edit, enable, and delete auto-moderation rules. - Dashboard admins can create and manage auto-moderation rules. - Guild admins can read and change auto-moderation rules through the API. <!-- greptile_confidence_score:3 --> <sub>Reviews (14) · Last reviewed commit: ["fix(dashboard): lock rule writes across ..."](67278d5) · [Reviewed by Greptile](https://www.greptile.com/?utm_source=greptile_expert&utm_medium=github&utm_campaign=code_reviews&utm_content=wolfstar-project/wolfstar.rocks)</sub> <!-- /greptile_comment -->
### 🔗 Linked issue Part of the stack superseding #422. Depends on #457. **Stack:** #451 foundation ← #452 header/footer ← #453 marketing ← #454 `/app` dashboard ← #455 V7 contract + ORM 8 only ← #457 auto-moderation rules ← #461 deprecate `/profile` ### 🧭 Context Since #454 the dashboard lists the servers you manage itself, so `/profile` was a second server list with a different layout. It was also the only place to change theme, language and reduced motion, which is why it could not simply be deleted: guests use those controls too, and `/app` is sign-in only. ### 📚 Description `/profile` and `/account` now answer with a 301 to `/app`: ``` /profile -> 301 http://localhost:5678/app /account -> 301 http://localhost:5678/app ``` The preferences moved into a dialog opened from the header's Settings button (guests) and from the user menus (signed in), so nobody needs a page for them. Sign-in lands on `/app`, which shows the server picker when no server is selected. ###⚠️ What this removes - **Search, sort and the "manageable only" toggle on the server list.** The picker in `/app` shows every server you can manage, sorted with the ones WolfStar is in first. If someone manages enough servers to need search, it should be added to the picker rather than kept on a second page. - **Servers you cannot manage** are no longer listed anywhere. `/profile` showed them when the toggle was off. - **The profile header**: avatar, username and the copy-user-id button. - `/profile` was indexable and had an OG image. It is now `robots: false` and out of the sitemap. I used 301 because the page is not coming back; say so if you would rather keep it temporary while the stack is in review. > 🤖 AI disclosure: [Wolfstar Agent Kit](https://github.com/wolfstar-project/wolfstar-agent-kit) modified this description. [My AI open-source policy](https://harlanzw.com/blog/ai-in-open-source). <!-- greptile_comment --> <!-- greptile_summary --> <h2><a href="https://app.greptile.com/api/retrigger?id=78706812"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img alt="Retrigger" src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2" align="right"></picture></a>Confidence Score: 4/5</h2> <!-- greptile-risk --> The settings-dialog copy requirements must be satisfied before merging; clipped activity descriptions, stale dates, and incorrect context-menu labels are non-blocking usability concerns. <h2>T-Rex evidence</h2> **[▶ Recording of the check](https://app.greptile.com/trex/artifacts/2e06d5fd-c8bc-44c9-a9bf-ba955fb11453)** - Chromium renders long activity entries at two desktop panel widths and scrolls the narrow table fully right, showing that the original descriptions wrap and remain readable. **[▶ Recording of the check](https://app.greptile.com/trex/artifacts/43922602-d54d-4492-a1a9-9e6c011d9f2e)** - Chromium renders the same entries and exercises scrolling and hover, showing that long descriptions remain clipped without a full-text disclosure. **[Original activity table at maximum horizontal scroll](https://app.greptile.com/trex/artifacts/72ca460a-a115-4bdf-9c7a-7041eda5188e)** - The pre-conversion table is captured at the narrow desktop width after scrolling fully right, showing wrapped action descriptions. **[PR461 activity table at maximum horizontal scroll](https://app.greptile.com/trex/artifacts/5efec520-4094-4d09-b7f3-1ba142c372a2)** - The PR461 table is captured at the same width and scroll position, showing that horizontal scrolling does not recover clipped action text. **[Command output from the check](https://app.greptile.com/trex/artifacts/6087bbe7-5ff0-4aaa-b7bc-f155a36e9878)** - The successful command captured measured cell widths, computed styles, scroll limits, hover results, and checkout checks, confirming the same clipping in both PR heads. **[Evidence from the check](https://app.greptile.com/trex/artifacts/3067230c-b098-4609-9918-8e7d0bac829f)** - The script loads component source directly from local commits and captures runtime measurements and recordings; its final declaration-generation option adjustment was not rerun. **[Evidence from the check](https://app.greptile.com/trex/artifacts/a7b38dd3-b67f-48d5-a6fd-61af2520ae41)** - The harness mounts the selected commit’s activity component with real Nuxt UI components and application CSS, exercising the desktop rendering path. **[Evidence from the check](https://app.greptile.com/trex/artifacts/17ed5882-d56e-49c9-9e6b-8800cb2ba214)** - The fixtures supply long resolved role and channel names plus a short control entry, reproducing clipping without database or authentication access. **[Evidence from the check](https://app.greptile.com/trex/artifacts/1768f28b-a235-43ec-99ed-cf3800440a60)** - The shell command launches the Chromium validation with the installed browser cache and records command, working directory, and exit code in the execution log. **[▶ Recording of the check](https://app.greptile.com/trex/artifacts/2e06d5fd-c8bc-44c9-a9bf-ba955fb11453)** - Chromium renders long activity entries at two desktop panel widths and scrolls the narrow table fully right, showing that the original descriptions wrap and remain readable. **[▶ Recording of the check](https://app.greptile.com/trex/artifacts/43922602-d54d-4492-a1a9-9e6c011d9f2e)** - Chromium renders the same entries and exercises scrolling and hover, showing that long descriptions remain clipped without a full-text disclosure. **[Original activity table at maximum horizontal scroll](https://app.greptile.com/trex/artifacts/72ca460a-a115-4bdf-9c7a-7041eda5188e)** - The pre-conversion table is captured at the narrow desktop width after scrolling fully right, showing wrapped action descriptions. **[PR461 activity table at maximum horizontal scroll](https://app.greptile.com/trex/artifacts/5efec520-4094-4d09-b7f3-1ba142c372a2)** - The PR461 table is captured at the same width and scroll position, showing that horizontal scrolling does not recover clipped action text. **[Command output from the check](https://app.greptile.com/trex/artifacts/6087bbe7-5ff0-4aaa-b7bc-f155a36e9878)** - The successful command captured measured cell widths, computed styles, scroll limits, hover results, and checkout checks, confirming the same clipping in both PR heads. **[Evidence from the check](https://app.greptile.com/trex/artifacts/3067230c-b098-4609-9918-8e7d0bac829f)** - The script loads component source directly from local commits and captures runtime measurements and recordings; its final declaration-generation option adjustment was not rerun. **[Evidence from the check](https://app.greptile.com/trex/artifacts/a7b38dd3-b67f-48d5-a6fd-61af2520ae41)** - The harness mounts the selected commit’s activity component with real Nuxt UI components and application CSS, exercising the desktop rendering path. **[Evidence from the check](https://app.greptile.com/trex/artifacts/17ed5882-d56e-49c9-9e6b-8800cb2ba214)** - The fixtures supply long resolved role and channel names plus a short control entry, reproducing clipping without database or authentication access. **[Evidence from the check](https://app.greptile.com/trex/artifacts/1768f28b-a235-43ec-99ed-cf3800440a60)** - The shell command launches the Chromium validation with the installed browser cache and records command, working directory, and exit code in the execution log. <a href="https://app.greptile.com/trex/runs/31709122/artifacts?artifact=2e06d5fd-c8bc-44c9-a9bf-ba955fb11453"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewArtifactsDark.svg?v=4"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewArtifacts.svg?v=4"><img alt="View artifacts" src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewArtifacts.svg?v=4"></picture></a> <h3>Summary</h3> The PR redirects `/profile` and `/account` to `/app` and moves browser preferences into a shared settings dialog. - Old profile links lead to the dashboard, while settings open in a dialog. - The dashboard picker lists manageable servers and reports load errors. - Dashboard logs use a shared toolbar, responsive rows, and tab counts. - Guild settings and selection controls are updated for the dashboard. <!-- greptile_confidence_score:4 --> <sub>Reviews (14) · Last reviewed commit: ["fix(dashboard): narrow the pager item be..."](aaaf549) · [Reviewed by Greptile](https://www.greptile.com/?utm_source=greptile_expert&utm_medium=github&utm_campaign=code_reviews&utm_content=wolfstar-project/wolfstar.rocks)</sub> <!-- /greptile_comment -->
### 🔗 Linked issue Part of the stack superseding #422. Depends on #461. **Stack:** #451 foundation ← #452 header/footer ← #453 marketing ← #454 `/app` dashboard ← #455 V7 contract + ORM 8 only ← #457 auto-moderation rules ← #461 deprecate `/profile` ← this PR ### 🧭 Context `/commands` was the last public page still on the pre-redesign look: nested Nuxt UI accordions, heavy borders, and a heading that the layout's top glow painted over. This rebuilds it on the Claude Design mockup for the commands page. ### 📚 Description - **Layout.** Centred heading and subtitle, a 52px search field next to the Refresh button, and a single 900px panel holding the category cards. - **Categories.** Each card shows its name and a command count. One category is open at a time and Moderation opens first when the bot reports it. While searching, every category with a match is expanded. - **Commands.** Each command is its own collapsible row: mono name, truncated description, then usage, extended help, explained usage, possible formats, examples, reminder and pill badges for permission level, server-only and guarded commands. - **Search.** The result count is now visible under the field instead of screen-reader only. Matching still goes through Fuse on name, description and category. - **Copy.** Every string on the page moved to `marketing.commands.*`; the page was hardcoded English before. Other locales get empty placeholders, as usual. - **Components.** `CommandSubCategory` is gone. `CommandCategory` is one card, `CommandItem` is one command row, `CommandBase` renders the details and `CommandChips` the badges. ### 🧪 Verification - `test/nuxt/pages/commands.spec.ts` covers the default open category, single-open behaviour, search expansion and count, the no-match state and the retry state. - Checked in a local dev server with sample commands in dark, light and at 390px wide. - Lint, typecheck, knip, i18n check/report, the colour guardrail tests and `build:test` pass locally. ###⚠️ Deviations from the mockup - The mockup's Refresh resets the page state. Here it keeps refetching the command list from the bot, as before. - The mockup shows a note saying details are "pulled live from the bot" on commands without help. Details are already live here, so that note reads "This command takes no arguments and has no extra notes." - Surfaces use the app's own tokens (`base-100`, `base-content` tints, `--home-*`) rather than the mockup's hex values, so the cards sit on the page colour instead of one step lighter in the dark theme. - The loading skeleton, the "no commands available" retry state, the Possible Formats and Reminder blocks and the "Cannot be disabled" badge are not in the mockup. They are kept and restyled to match. > 🤖 AI disclosure: [Wolfstar Agent Kit](https://github.com/wolfstar-project/wolfstar-agent-kit) modified this description. [My AI open-source policy](https://harlanzw.com/blog/ai-in-open-source). <!-- greptile_comment --> <!-- greptile_summary --> <h2><a href="https://app.greptile.com/api/retrigger?id=78748592"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/RetriggerDark.svg?v=2"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2"><img alt="Retrigger" src="https://greptile-static-assets.s3.amazonaws.com/badges/Retrigger.svg?v=2" align="right"></picture></a>Confidence Score: 4/5</h2> <!-- greptile-risk --> The remaining concerns are explicit repository design and copy requirements; both must be satisfied before merging. <h3>Summary</h3> This PR rebuilds `/commands` with category cards, expandable command rows, visible search counts, and translated labels. - Command categories open one at a time and expand to show search matches. - Each command opens to show its help and badges. - The commands page gets translation keys for its labels and help text. - Czech plural forms and English fallback text use the right rules. The design and copy requirements must be satisfied before merging. <!-- greptile_confidence_score:4 --> <sub>Reviews (15) · Last reviewed commit: ["fix(ui): derive command details from the..."](a98bf3a) · [Reviewed by Greptile](https://www.greptile.com/?utm_source=greptile_expert&utm_medium=github&utm_campaign=code_reviews&utm_content=wolfstar-project/wolfstar.rocks)</sub> <!-- /greptile_comment -->

🔗 Linked issue
Part of the stack superseding #422. Depends on #451.
Stack: #451 foundation ← #452 header/footer ← #453 marketing ← #454
/appdashboard ← #455 V7 schema + Prisma ORM 8 (draft)🧭 Context
The header and footer had drifted from the WolfStar Web Redesign canvas.
📚 Description
The brand lockup is unchanged apart from the Staryl wordmark's size (WolfStar keeps its logo mark, Staryl stays text only), the header is one solid surface matching the page, and the desktop nav pill gets a border, a 36px row and an open state. Features entries carry an icon and a description, Applications entries their avatar and a tagline, rendered through
UNavigationMenucontent slots. Those rows are plain links, so the panel closes itself on select or it would stay over an in-page anchor target.Desktop and mobile menus are built from the same groups in
useHeader(). The footer badge leads with a deploy status dot and the build info is a mono status pill. Two newnav.*_descriptionkeys, empty in every non-English locale.
Confidence Score: 5/5
No merge-blocking issues are identified in the reviewed changes.Summary
The PR updates the shared header and footer to match the redesign.
No actionable issues remain in this review. Tests and browser checks were not run.
Reviews (6) · Last reviewed commit: "fix(ui): keep focus on the header menu a..." · Reviewed by Greptile