Skip to content

fix: update project structure and rename dashboard to chat#58

Merged
yacosta738 merged 4 commits into
mainfrom
fix/pnpm-lockfile-gradle
Feb 20, 2026
Merged

fix: update project structure and rename dashboard to chat#58
yacosta738 merged 4 commits into
mainfrom
fix/pnpm-lockfile-gradle

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

@yacosta738 yacosta738 commented Feb 20, 2026

This pull request renames the dashboard app to chat throughout the Corvus web monorepo and introduces a new, modern conversational AI chat interface. It updates all related documentation, configuration, and code references, and adds new UI components and styling for the chat experience. The most important changes are grouped below:

App Renaming and Documentation Updates:

  • The dashboard app is renamed to chat everywhere, including folder names, documentation (README.md), and package metadata, to reflect its new purpose as a conversational AI interface. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]

New and Improved Chat UI:

  • Introduces new Vue components for the chat interface, including ChatMessage.vue, a reusable Button.vue, and an Input.vue component, providing a modern, ChatGPT-style conversational workspace. [1] [2] [3]

Styling and Design Tokens:

  • Adds a comprehensive new style.css with design tokens, dark mode support, custom fonts, and animations for a polished, modern look and feel.

Localization and UX Improvements:

  • Updates Spanish localization strings to improve clarity and add new chat-related messages and disclaimers. [1] [2]

Testing Adjustments:

  • Updates component tests to match the new chat UI and empty state behaviors. [1] [2]

These changes collectively modernize the Corvus web frontend, shifting its focus from a dashboard to a user-friendly conversational AI chat experience.

Summary by CodeRabbit

  • New Features

    • Introduces a Chat interface with message history, gateway configuration, secret handling, and improved send/scroll behavior.
    • Adds reusable UI components: buttons, inputs, and message bubbles.
  • Refactor

    • Renamed web app from "Dashboard" to "Chat", updated scripts and port mappings accordingly.
    • Centralized Biome lint/format config at the monorepo level.
  • Documentation

    • README and setup docs updated to reflect the chat-centric structure and app creation guidance.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 20, 2026

Warning

Rate limit exceeded

@yacosta738 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 10 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

The PR replaces the "dashboard" web app with a new "chat" app: renames scripts and ports, consolidates Biome config to the monorepo root, removes the old dashboard implementation, and adds a full Vue 3 chat UI with components, styles, tests, and gateway configuration handling.

Changes

Cohort / File(s) Summary
Root config & scripts
clients/web/README.md, clients/web/package.json, clients/web/build.gradle.kts, clients/web/packages/shared/env.mjs, README.md
Renamed dashboard→chat in README and package scripts; updated build.gradle app config to chat; replaced DASHBOARD port key with CHAT: 4323; added README badge.
New chat app
clients/web/apps/chat/README.md, clients/web/apps/chat/index.html, clients/web/apps/chat/package.json, clients/web/apps/chat/src/App.vue, clients/web/apps/chat/src/App.spec.ts, clients/web/apps/chat/src/style.css
Added chat app metadata, index/title, large App.vue implementing chat UI and gateway config workflow (POST /web/chat/config, AbortController timeout, secret handling, nonce remounts), tests updated, and global styles.
Chat UI components
clients/web/apps/chat/src/components/chat/ChatMessage.vue, clients/web/apps/chat/src/components/ui/button/Button.vue, clients/web/apps/chat/src/components/ui/input/Input.vue, clients/web/apps/chat/src/locales/es.json
New reusable UI components (ChatMessage, Button, Input) with typed props/emits and role-based styling; added Spanish translations for config/chat strings.
Dashboard app removals
clients/web/apps/dashboard/src/App.vue, clients/web/apps/dashboard/src/components/chat/ChatMessage.vue, clients/web/apps/dashboard/src/components/ui/button/Button.vue, clients/web/apps/dashboard/src/components/ui/input/Input.vue, clients/web/apps/dashboard/src/style.css
Deleted the previous dashboard app and its components/styles (chat UI, button, input, CSS).
Biome config consolidation
clients/web/biome.json, clients/web/apps/docs/biome.json, clients/web/apps/docs/package.json, clients/web/apps/marketing/package.json
Promoted Biome config to monorepo root and bumped schema (2.3.15 → 2.4.2); removed local biome.json and @biomejs/biome devDependency entries from app packages.
Shared env & small files
clients/web/packages/shared/env.mjs, clients/web/apps/chat/index.html
Updated PORTS export key to CHAT; changed HTML title to "Corvus Chat".

Sequence Diagram

sequenceDiagram
    actor User
    participant Browser as Client / Browser
    participant App as Chat App
    participant Backend as Gateway API

    User->>Browser: Fill baseUrl & secrets
    User->>Browser: Click "Save Configuration"
    Browser->>App: saveGatewayConfig()
    App->>App: Build payload (baseUrl + secrets)
    App->>App: Create AbortController (timeout)
    App->>Backend: POST /web/chat/config (payload, signal)
    activate Backend
    Backend-->>App: Response (success / error)
    deactivate Backend
    alt success
        App->>App: clear secrets, increment nonce, show success
        App->>Browser: display success
    else abort (timeout)
        App->>Browser: display timeout error
    else error
        App->>App: log error
        App->>Browser: display save error
    end
    App->>App: reset to idle
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

codex

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the primary change: renaming dashboard to chat and updating project structure. It is clear, specific, and relates directly to the main objectives of the changeset.
Description check ✅ Passed The description covers the main changes (app renaming, new UI components, styling, localization, testing) with good detail. However, the related issues, tested information, and breaking changes sections are not filled in per the template.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/pnpm-lockfile-gradle

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 20, 2026

✅ Contributor Report

User: @yacosta738
Status: Passed (12/13 metrics passed)

Metric Description Value Threshold Status
PR Merge Rate PRs merged vs closed 89% >= 30%
Repo Quality Repos with ≥100 stars 0 >= 0
Positive Reactions Positive reactions received 9 >= 1
Negative Reactions Negative reactions received 0 <= 5
Account Age GitHub account age 3038 days >= 30 days
Activity Consistency Regular activity over time 108% >= 0%
Issue Engagement Issues with community engagement 0 >= 0
Code Reviews Code reviews given to others 364 >= 0
Merger Diversity Unique maintainers who merged PRs 3 >= 0
Repo History Merge Rate Merge rate in this repo 89% >= 0%
Repo History Min PRs Previous PRs in this repo 39 >= 0
Profile Completeness Profile richness (bio, followers) 90 >= 0
Suspicious Patterns Spam-like activity detection 1 N/A

Contributor Report evaluates based on public GitHub activity. Analysis period: 2025-02-20 to 2026-02-20

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
clients/web/build.gradle.kts (1)

18-26: ⚠️ Potential issue | 🟠 Major

Replace the overly broad catch (e: Exception) — Detekt pipeline failure.

Files.createSymbolicLink throws IOException (and SecurityException/UnsupportedOperationException for non-I/O failures). Catching the root Exception swallows programming errors silently.

🛠️ Proposed fix
-    } catch (e: Exception) {
-      logger.warn("⚠️ No se pudo crear symlink de docs: ${e.message}")
-      // Fallback: crear directorio vacío o copiar contenido
-      logger.lifecycle("📁 Creando directorio docs como fallback...")
-      docsSymlink.toFile().mkdirs()
+    } catch (e: java.io.IOException) {
+      logger.warn("⚠️ No se pudo crear symlink de docs: ${e.message}")
+      // Fallback: crear directorio vacío o copiar contenido
+      logger.lifecycle("📁 Creando directorio docs como fallback...")
+      docsSymlink.toFile().mkdirs()
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/build.gradle.kts` around lines 18 - 26, The current catch-all on
Files.createSymbolicLink hides programming errors; replace catch (e: Exception)
with targeted catches for the expected failure modes: catch java.io.IOException
to handle I/O failures, catch SecurityException for permission issues, and catch
UnsupportedOperationException for platforms that don't support symlinks; in each
handler reference docsSymlink and docsTarget and include the caught exception
(e) in the logger.warn message, then run the same fallback (logger.lifecycle
"creating docs" and docsSymlink.toFile().mkdirs()) so only non-recoverable,
unexpected exceptions escape.
clients/web/README.md (1)

43-44: ⚠️ Potential issue | 🟡 Minor

Node.js version requirement is inconsistent across configuration files.

The README states "Node.js 20.19+ (recomendado 22+)" on line 43, but clients/web/package.json enforces "node": ">=22.0.0" (line 29). Additionally, clients/web/apps/chat/package.json specifies "node": ">=20.19.0" (line 8), creating a three-way mismatch. Update the README to reflect that the root workspace requires Node 22.0.0 as a strict minimum.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/README.md` around lines 43 - 44, The README currently advertises
"Node.js 20.19+ (recomendado 22+)" which conflicts with the workspace engines;
change the README Node version to a strict minimum of "Node.js 22.0.0+" to match
the root package.json engines.node value and remove the 20.19 reference; ensure
the README text mirrors the exact engines.node constraint used in package.json
(the "engines.node" entries) so all three references are consistent.
clients/web/apps/chat/package.json (1)

14-15: ⚠️ Potential issue | 🟡 Minor

Remove unused dependencies and verify biome hoisting in CI.

@biomejs/biome is called in the format and check scripts but only listed in the workspace root package.json. This relies on pnpm hoisting—verify this works in your CI environment.

Additionally, class-variance-authority is unused and can be removed. clsx and tailwind-merge are imported in src/lib/utils.ts to create a cn() utility function, but this utility is never called anywhere in the application, making it dead code. Consider removing all three dependencies or refactor to use the cn() utility if it's needed for future components.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/package.json` around lines 14 - 15, Remove unused deps
and ensure biome is available in CI: delete "class-variance-authority" and
decide whether to keep "clsx" and "tailwind-merge"—either remove them from
clients/web/apps/chat/package.json or refactor code to actually use the cn()
utility in src/lib/utils.ts (search for the cn function) so those imports are
justified; additionally update the package.json scripts if you want to avoid
relying on workspace hoisting by adding a devDependency on `@biomejs/biome` here
or confirm CI's pnpm hoisting behavior to ensure the existing "format" and
"check" scripts that invoke biome will run reliably.
🧹 Nitpick comments (7)
clients/web/apps/chat/src/components/ui/input/Input.vue (1)

9-11: _emit underscore prefix is misleading — the variable is actively used in the template.

The _ convention signals "intentionally unused," but _emit is called in @input. Rename it to emit for clarity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/src/components/ui/input/Input.vue` around lines 9 - 11,
Rename the defineEmits binding from _emit to emit so the template usage is
clear: update the const declaration using defineEmits<{ "update:modelValue":
[value: string]; }>() to export/assign as emit instead of _emit, and update any
template references (e.g., the `@input` handler) to call emit(...) accordingly to
remove the misleading underscore that implies “unused.”
clients/web/apps/chat/src/components/chat/ChatMessage.vue (1)

102-111: Redundant @keyframes fade-in — already defined globally in style.css.

Vue's <style scoped> does not scope @keyframes — they are always injected as global CSS. The identical fade-in keyframes in style.css (lines 90–99) cover the .message-row animation at line 42. This local copy can be removed.

♻️ Proposed fix
-.@keyframes fade-in {
-  from {
-    opacity: 0;
-    transform: translateY(8px);
-  }
-  to {
-    opacity: 1;
-    transform: translateY(0);
-  }
-}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/src/components/chat/ChatMessage.vue` around lines 102 -
111, Remove the redundant global keyframes definition from ChatMessage.vue:
delete the local `@keyframes` fade-in block (the one used by .message-row
animation) since `@keyframes` are not scoped and the identical fade-in is already
defined in style.css; keep .message-row animation usage intact and ensure no
other local references to fade-in remain in ChatMessage.vue.
clients/web/apps/chat/src/style.css (2)

1-2: Consider self-hosting the Inter font instead of loading from Google Fonts.

Loading fonts from fonts.googleapis.com makes an external network request on every page load, which can be a GDPR/privacy concern (the user's IP is sent to Google's servers) and a performance dependency.

A common alternative is to bundle the font via fontsource:

-@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap");
+@import "@fontsource-variable/inter";

Install with: pnpm add @fontsource-variable/inter``

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/src/style.css` around lines 1 - 2, Replace the external
Google Fonts import in clients/web/apps/chat/src/style.css (the line with
`@import` url("https://fonts.googleapis.com/css2?family=Inter...")) by
self-hosting Inter: install the package (e.g., pnpm add
`@fontsource-variable/inter` or `@fontsource/inter`), remove the `@import` url(...)
line, import the font from the installed package in your app entry or global
stylesheet (where style.css is consumed), and update the CSS font-family
declarations to use the locally bundled font with suitable fallbacks so the
build serves font files from your own CDN/server rather than
fonts.googleapis.com.

90-99: @keyframes fade-in is duplicated across style.css and ChatMessage.vue.

ChatMessage.vue (lines 102–111) defines an identical fade-in keyframe inside its <style scoped> block. Vue's scoped CSS does not scope @keyframes — they are always global, so both definitions resolve to the same name. The one in ChatMessage.vue is redundant and can be removed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/src/style.css` around lines 90 - 99, The duplicate
global `@keyframes` fade-in is defined in both style.css and ChatMessage.vue;
because `@keyframes` are not scoped, remove the redundant definition from
ChatMessage.vue's <style scoped> block (or alternatively rename the animation in
ChatMessage.vue and update its usage in the component to a unique name) so only
one global `@keyframes` fade-in remains and there are no conflicts.
clients/web/apps/chat/src/components/ui/button/Button.vue (1)

116-118: Scoped .w-full utility may be better placed in a shared stylesheet.

This utility class is defined in scoped CSS but is passed from the parent (App.vue Line 309: class="w-full"). While this works because the <button> element carries the scoped attribute, a utility class like w-full is a general-purpose pattern that would be more discoverable and reusable in a shared/global stylesheet or via Tailwind's w-full.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/src/components/ui/button/Button.vue` around lines 116 -
118, The scoped utility class `.w-full` in Button.vue is a general-purpose width
utility used by the parent (App.vue uses class="w-full")—move this rule out of
the component's scoped CSS into a shared/global stylesheet (or replace usage
with Tailwind's `w-full`) and remove the `.w-full` entry from the scoped block
in Button.vue so the utility is discoverable and reusable across components.
clients/web/apps/chat/src/App.vue (2)

189-193: Duplicated inline SVGs — consider extracting icon components.

The settings gear SVG is duplicated 3 times (sidebar, mobile header, config header) and the logo SVG is duplicated 3 times as well. Extracting these into small icon components (e.g., IconLogo.vue, IconGear.vue) would reduce template size and improve maintainability.

Also applies to: 218-221, 233-237, 246-249, 258-261, 338-342

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/src/App.vue` around lines 189 - 193, The template
contains repeated inline SVG markup (logo and gear) in App.vue; extract them
into two small single-file components (e.g., IconLogo.vue and IconGear.vue) that
render the SVG, export default with a simple name, then replace each inline SVG
occurrence in App.vue (sidebar, mobile header, config header and other
duplicates) with the new components and import/register them in the App.vue
script block (use the component names like IconLogo and IconGear). Ensure the
new components accept passthrough props for size/class if needed so existing
attributes (width/height/class) can be preserved when used.

152-174: sendMessage does not make an API call — appears to be a stub.

The function appends a canned "processing" template message as the assistant response instead of actually calling the configured gateway. If this is intentional for an initial iteration, consider adding a // TODO comment so it's not overlooked. Otherwise, this should be wired to the backend.

Would you like me to open an issue to track wiring sendMessage to the gateway API?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/src/App.vue` around lines 152 - 174, sendMessage
currently only appends a canned "processing" assistant message instead of
calling the gateway; replace the stub with a real API call: build a request
payload using normalizedText and modelName and POST it to the configured gateway
(baseUrl.value), send the request after pushing the user message, create a
temporary assistant message via nextMessageId() to show loading, then replace or
update that assistant message with the gateway response when the call resolves
(or replace it with an error message on failure), keep prompt.value clearing,
await nextTick() and call scrollChatToBottom() as before, and add a // TODO if
you intend to keep the stub behavior temporarily. Use messages, nextMessageId,
MAX_PROMPT_LENGTH, modelName, baseUrl, t(...) for error text, and ensure errors
are caught and logged/ surfaced to the user.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@clients/web/apps/chat/src/App.vue`:
- Around line 96-113: The code posts sensitive fields (pairingCodeInput,
bearerTokenInput, webhookSecretInput) to gatewayBaseUrl without validating
protocol; update the submit logic that builds payload and calls fetch to parse
gatewayBaseUrl (using the URL constructor) and reject or prompt the user if the
protocol is "http:" and the hostname is not "localhost" or "127.0.0.1" (or
otherwise not explicitly allowed); implement this check before creating
payload/issuing fetch, and surface a clear UI error/warning or disable
submission when the unsafe URL is detected so secrets are not sent over plain
HTTP to remote hosts.
- Around line 365-369: The chat input currently uses only a placeholder
(v-model="prompt" on the element with class "chat-input") which is not
accessible; add an accessible label by either adding an aria-label that reuses
the translation (e.g. :aria-label="t('chat.inputPlaceholder')") or render a
visually-hidden <label> element tied to the input via an id (set :id on the
input and for on the label) so screen readers announce the field; keep the
existing v-model="prompt" and placeholder intact for visual UX and ensure you
use the same i18n key t('chat.inputPlaceholder') for the label text.

In `@clients/web/apps/chat/src/components/chat/ChatMessage.vue`:
- Around line 15-21: The decorative SVGs in ChatMessage.vue are being announced
by assistive tech; add aria-hidden="true" to each presentational SVG to prevent
screen readers from announcing them. Specifically update the <svg> inside the
div rendered when role === 'assistant' (class "avatar avatar--assistant") and
the counterpart SVG used for the other role (the avatar div around lines 29-34)
to include aria-hidden="true" on the <svg> elements so they are treated as
purely decorative.

In `@clients/web/apps/chat/src/components/ui/button/Button.vue`:
- Around line 13-18: The class collision comes from using the same prefix for
variant and size in the :class array in Button.vue (the `btn--${props.variant ??
'default'}` and `btn--${props.size ?? 'default'}` entries); change the size
class to use a distinct prefix (for example `btn-size--${props.size ??
'default'}`) in the :class array so variant and size generate different tokens,
then rename the corresponding CSS selectors (e.g., change `.btn--default-size`
and other `.btn--{size}` rules to the new `btn-size--{size}` names and update
any rules that currently rely on `.btn--default`) so the ghost variant is not
overridden by the default size rule.

In `@clients/web/apps/chat/src/components/ui/input/Input.vue`:
- Around line 1-22: The component currently declares a prop named "class" and
also relies on Vue's default inheritAttrs behavior, causing duplicate/confusing
class application; update the component by calling defineOptions({ inheritAttrs:
false }) at the top, remove or stop using the "class" prop in defineProps (or
rename it to avoid colliding with fallthrough attrs), and adjust the template to
read classes from $attrs.class or a renamed prop as appropriate; also consider
renaming _emit to emit via const emit = defineEmits(...) for clearer emit usage
in the `@input` handler (i.e., use emit('update:modelValue', ...)).

In `@clients/web/apps/chat/src/style.css`:
- Line 2: Replace the current `@import` url(...) line with the string form `@import`
"..." to satisfy stylelint's import-notation rule and Tailwind/Lightning CSS
expectations; locate the `@import` line in style.css and change the url(...)
wrapper to the plain string syntax using the same Google Fonts URL.

---

Outside diff comments:
In `@clients/web/apps/chat/package.json`:
- Around line 14-15: Remove unused deps and ensure biome is available in CI:
delete "class-variance-authority" and decide whether to keep "clsx" and
"tailwind-merge"—either remove them from clients/web/apps/chat/package.json or
refactor code to actually use the cn() utility in src/lib/utils.ts (search for
the cn function) so those imports are justified; additionally update the
package.json scripts if you want to avoid relying on workspace hoisting by
adding a devDependency on `@biomejs/biome` here or confirm CI's pnpm hoisting
behavior to ensure the existing "format" and "check" scripts that invoke biome
will run reliably.

In `@clients/web/build.gradle.kts`:
- Around line 18-26: The current catch-all on Files.createSymbolicLink hides
programming errors; replace catch (e: Exception) with targeted catches for the
expected failure modes: catch java.io.IOException to handle I/O failures, catch
SecurityException for permission issues, and catch UnsupportedOperationException
for platforms that don't support symlinks; in each handler reference docsSymlink
and docsTarget and include the caught exception (e) in the logger.warn message,
then run the same fallback (logger.lifecycle "creating docs" and
docsSymlink.toFile().mkdirs()) so only non-recoverable, unexpected exceptions
escape.

In `@clients/web/README.md`:
- Around line 43-44: The README currently advertises "Node.js 20.19+
(recomendado 22+)" which conflicts with the workspace engines; change the README
Node version to a strict minimum of "Node.js 22.0.0+" to match the root
package.json engines.node value and remove the 20.19 reference; ensure the
README text mirrors the exact engines.node constraint used in package.json (the
"engines.node" entries) so all three references are consistent.

---

Nitpick comments:
In `@clients/web/apps/chat/src/App.vue`:
- Around line 189-193: The template contains repeated inline SVG markup (logo
and gear) in App.vue; extract them into two small single-file components (e.g.,
IconLogo.vue and IconGear.vue) that render the SVG, export default with a simple
name, then replace each inline SVG occurrence in App.vue (sidebar, mobile
header, config header and other duplicates) with the new components and
import/register them in the App.vue script block (use the component names like
IconLogo and IconGear). Ensure the new components accept passthrough props for
size/class if needed so existing attributes (width/height/class) can be
preserved when used.
- Around line 152-174: sendMessage currently only appends a canned "processing"
assistant message instead of calling the gateway; replace the stub with a real
API call: build a request payload using normalizedText and modelName and POST it
to the configured gateway (baseUrl.value), send the request after pushing the
user message, create a temporary assistant message via nextMessageId() to show
loading, then replace or update that assistant message with the gateway response
when the call resolves (or replace it with an error message on failure), keep
prompt.value clearing, await nextTick() and call scrollChatToBottom() as before,
and add a // TODO if you intend to keep the stub behavior temporarily. Use
messages, nextMessageId, MAX_PROMPT_LENGTH, modelName, baseUrl, t(...) for error
text, and ensure errors are caught and logged/ surfaced to the user.

In `@clients/web/apps/chat/src/components/chat/ChatMessage.vue`:
- Around line 102-111: Remove the redundant global keyframes definition from
ChatMessage.vue: delete the local `@keyframes` fade-in block (the one used by
.message-row animation) since `@keyframes` are not scoped and the identical
fade-in is already defined in style.css; keep .message-row animation usage
intact and ensure no other local references to fade-in remain in
ChatMessage.vue.

In `@clients/web/apps/chat/src/components/ui/button/Button.vue`:
- Around line 116-118: The scoped utility class `.w-full` in Button.vue is a
general-purpose width utility used by the parent (App.vue uses
class="w-full")—move this rule out of the component's scoped CSS into a
shared/global stylesheet (or replace usage with Tailwind's `w-full`) and remove
the `.w-full` entry from the scoped block in Button.vue so the utility is
discoverable and reusable across components.

In `@clients/web/apps/chat/src/components/ui/input/Input.vue`:
- Around line 9-11: Rename the defineEmits binding from _emit to emit so the
template usage is clear: update the const declaration using defineEmits<{
"update:modelValue": [value: string]; }>() to export/assign as emit instead of
_emit, and update any template references (e.g., the `@input` handler) to call
emit(...) accordingly to remove the misleading underscore that implies “unused.”

In `@clients/web/apps/chat/src/style.css`:
- Around line 1-2: Replace the external Google Fonts import in
clients/web/apps/chat/src/style.css (the line with `@import`
url("https://fonts.googleapis.com/css2?family=Inter...")) by self-hosting Inter:
install the package (e.g., pnpm add `@fontsource-variable/inter` or
`@fontsource/inter`), remove the `@import` url(...) line, import the font from the
installed package in your app entry or global stylesheet (where style.css is
consumed), and update the CSS font-family declarations to use the locally
bundled font with suitable fallbacks so the build serves font files from your
own CDN/server rather than fonts.googleapis.com.
- Around line 90-99: The duplicate global `@keyframes` fade-in is defined in both
style.css and ChatMessage.vue; because `@keyframes` are not scoped, remove the
redundant definition from ChatMessage.vue's <style scoped> block (or
alternatively rename the animation in ChatMessage.vue and update its usage in
the component to a unique name) so only one global `@keyframes` fade-in remains
and there are no conflicts.

Comment thread clients/web/apps/chat/src/App.vue
Comment thread clients/web/apps/chat/src/App.vue
Comment thread clients/web/apps/chat/src/components/chat/ChatMessage.vue Outdated
Comment thread clients/web/apps/chat/src/components/ui/button/Button.vue
Comment thread clients/web/apps/chat/src/components/ui/input/Input.vue
Comment thread clients/web/apps/chat/src/style.css Outdated
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Feb 20, 2026

Deploying corvus with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7720c3e
Status: ✅  Deploy successful!
Preview URL: https://46534cc0.corvus-42x.pages.dev
Branch Preview URL: https://fix-pnpm-lockfile-gradle.corvus-42x.pages.dev

View logs

@yacosta738 yacosta738 merged commit 39400e8 into main Feb 20, 2026
11 of 13 checks passed
@yacosta738 yacosta738 deleted the fix/pnpm-lockfile-gradle branch February 20, 2026 16:58
@yacosta738 yacosta738 mentioned this pull request Mar 16, 2026
This was referenced Apr 19, 2026
This was referenced Apr 29, 2026
@dallay-bot dallay-bot Bot mentioned this pull request May 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant