feat(telemetry): add a live, enriched analytics dashboard#446
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
2 Skipped Deployments
|
|
Thank you for following the naming conventions! 🙏 |
📝 WalkthroughWalkthroughTelemetry ingestion now captures nullable OS and architecture metadata. The telemetry API and mock data expose expanded activity, environment, error, version, and duration statistics, while the dashboard adds live polling, a live feed, new breakdown cards, charts, animations, and Nucleo icon support. ChangesTelemetry analytics dashboard
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant LiveIndicator
participant Dashboard
participant TelemetryAPI
participant LiveFeed
User->>LiveIndicator: toggle live polling
LiveIndicator->>Dashboard: emit toggle
Dashboard->>TelemetryAPI: refresh stats, runs, and feed
TelemetryAPI-->>Dashboard: return aggregates and newest runs
Dashboard->>LiveFeed: render updated feed
LiveFeed-->>Dashboard: emit selected run
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Biome (2.5.3)apps/telemetry/app/assets/css/main.cssFile contains syntax errors that prevent linting: Line 9: Tailwind-specific syntax is disabled.; Line 14: Tailwind-specific syntax is disabled. 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. Comment |
commit: |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/telemetry/app/composables/useFreshIds.ts`:
- Around line 12-25: Update the rows watcher in useFreshIds so seenIds is pruned
to the currently visible row IDs on each update, while preserving existing IDs
needed to detect newly arrived rows in the current batch. Keep the initialized
handling and freshIds flash behavior unchanged, and ensure seenIds cannot retain
IDs absent from the latest rows.
In `@apps/telemetry/app/composables/useLiveRefresh.ts`:
- Around line 40-48: Update the live-refresh flow around tick() so refresh
failures are observable to its callers despite useFetch/useAsyncData refresh()
resolving while populating .error. Surface the failing fetcher error or a
failure timestamp/status from the composable, and ensure index.vue’s polling and
LiveIndicator consume that signal so repeated failures no longer appear as
“Live”.
In `@apps/telemetry/app/pages/index.vue`:
- Around line 256-257: Remove the HTML comment from the Vue template near the
card layout markup in the index page. If the note is still needed, move it into
the script block using the project’s supported comment style; otherwise delete
it without changing the card layout behavior.
In `@apps/telemetry/app/utils/telemetry-icons.ts`:
- Around line 43-45: Document the exported helpers providerIcon and osLabel in
apps/telemetry/app/utils/telemetry-icons.ts at lines 43-45 and 70-73: add JSDoc
for providerIcon describing its provider icon lookup and i-nucleo-server
fallback, and add JSDoc for osLabel describing its OS label lookup and fallback
behavior.
In `@apps/telemetry/server/db/migrations/postgresql/meta/0001_snapshot.json`:
- Around line 1-5: Remove the generated Drizzle migration metadata artifacts:
delete the snapshot file at
apps/telemetry/server/db/migrations/postgresql/meta/0001_snapshot.json and
remove the corresponding journal entry at
apps/telemetry/server/db/migrations/postgresql/meta/_journal.json lines 11-17.
In `@apps/telemetry/shared/types/telemetry.ts`:
- Around line 75-92: Add concise interface-level JSDoc comments to the exported
ErrorCodeStat and DurationStats interfaces, describing the error-code occurrence
statistics and duration percentile/histogram statistics. Leave their existing
fields and the DurationBucket documentation unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: e4d481c3-a74d-4b5c-a522-b0373be010a7
⛔ Files ignored due to path filters (42)
apps/telemetry/app/assets/icons/nucleo/bolt.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/box.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/bug.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/calendar.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/chart-line.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/check.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/chevron-down.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/chevron-up.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/chevrons-expand.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/circle-check.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/circle-info.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/circle-warning.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/clipboard-check.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/code-editor.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/connect.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/copy.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/dial.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/flag.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/gauge.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/inbox.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/key.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/laptop-mobile.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/laptop.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/layers.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/loader.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/log-out.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/pause.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/play.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/plug.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/refresh.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/rocket.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/server.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/sparkle-outline.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/sparkle.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/tags.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/tasks.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/terminal.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/triangle-warning.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/ufo.svgis excluded by!**/*.svgapps/telemetry/app/assets/icons/nucleo/user.svgis excluded by!**/*.svgpackages/telemetry/test/__snapshots__/telemetry.test.ts.snapis excluded by!**/*.snappnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (43)
.changeset/heavy-planes-shout.mdapps/telemetry/app/assets/css/main.cssapps/telemetry/app/components/AgentsBreakdown.vueapps/telemetry/app/components/BreakdownBars.vueapps/telemetry/app/components/CiBreakdown.vueapps/telemetry/app/components/CommandsTable.vueapps/telemetry/app/components/DailyActivityChart.vueapps/telemetry/app/components/DurationHistogram.vueapps/telemetry/app/components/EnvironmentBreakdown.vueapps/telemetry/app/components/ErrorCodesCard.vueapps/telemetry/app/components/LiveFeed.vueapps/telemetry/app/components/LiveIndicator.vueapps/telemetry/app/components/McpConnectButton.vueapps/telemetry/app/components/RunDetailPanel.vueapps/telemetry/app/components/RunsTable.vueapps/telemetry/app/components/StatCard.vueapps/telemetry/app/components/VersionsCard.vueapps/telemetry/app/composables/useFreshIds.tsapps/telemetry/app/composables/useLiveRefresh.tsapps/telemetry/app/pages/index.vueapps/telemetry/app/pages/login.vueapps/telemetry/app/utils/telemetry-icons.tsapps/telemetry/nuxt.config.tsapps/telemetry/package.jsonapps/telemetry/scripts/export-nucleo-icons.mjsapps/telemetry/server/db/migrations/postgresql/0001_legal_goliath.sqlapps/telemetry/server/db/migrations/postgresql/meta/0001_snapshot.jsonapps/telemetry/server/db/migrations/postgresql/meta/_journal.jsonapps/telemetry/server/db/schema.tsapps/telemetry/server/mcp/tools/telemetry-stats.tsapps/telemetry/server/utils/mock-data.tsapps/telemetry/server/utils/store.tsapps/telemetry/server/utils/telemetry-queries.tsapps/telemetry/shared/types/telemetry.tsapps/telemetry/shared/utils/activity-buckets.tsapps/telemetry/shared/utils/duration-buckets.tsapps/telemetry/test/mock-data.test.tspackages/telemetry/src/disclosure.tspackages/telemetry/src/enrich.tspackages/telemetry/src/ingest.tspackages/telemetry/src/types.tspackages/telemetry/test/enrich.test.tspackages/telemetry/test/ingest.test.ts
| async function tick() { | ||
| if (!active.value || inFlight.value) return | ||
| inFlight.value = true | ||
| try { | ||
| await refresh() | ||
| } finally { | ||
| inFlight.value = false | ||
| } | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Does Nuxt useFetch's refresh() reject the returned promise when the request fails, or does it only populate the error ref?
💡 Result:
The refresh (and its alias execute) function returned by Nuxt's useFetch does not reject the promise when a request fails [1][2]. Instead, it handles errors internally by populating the error ref and updating the status ref to 'error' [3][4][1]. Because the promise does not reject, using await refresh within a try/catch block will not catch HTTP or network errors [1][2]. To handle errors when using useFetch, you should check the error ref after the request completes or use the status ref [1]. If you require the ability to catch errors via a promise rejection, you would typically need to use $fetch directly, though this means losing the built-in reactive state management (data, pending, status, error) provided by useFetch [1][2]. As of July 2026, there have been community discussions and requests for a throwOnError option to allow these composables to reject on failure, but they do not do so by default [2].
Citations:
- 1: Why does useFetch().execute() not throw an error inside try-catch? nuxt/nuxt#26307
- 2: Add
throwOnErroroption touseAsyncData/useFetchnuxt/nuxt#34531 - 3: https://nuxt.com/docs/4.x/api/composables/use-fetch
- 4: https://nuxt.com/docs/4.x/getting-started/data-fetching
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate files =="
fd -a 'useLiveRefresh\.ts$|index\.vue$' . | sed 's#^\./##'
echo "== git status/stat =="
git status --short
git diff --stat -- packages apps 2>/dev/null || true
echo "== relevant file outlines =="
for f in $(fd 'useLiveRefresh\.ts|index\.vue$' apps/telemetry/app 2>/dev/null); do
echo "--- $f"
wc -l "$f"
ast-grep outline "$f" --view compact || true
done
echo "== useLiveRefresh.ts =="
f="$(fd 'useLiveRefresh\.ts$' apps/telemetry/app | head -n1)"
if [ -n "${f:-}" ]; then
cat -n "$f"
fi
echo "== index.vue snippets matching refresh/useLiveRefresh =="
for f in $(fd '^index\.vue$' apps/telemetry/app/composables apps/telemetry/app 2>/dev/null); do
if rg -q 'useLiveRefresh|refresh\(' "$f"; then
echo "--- $f"
wc -l "$f"
rg -n -C 8 'useLiveRefresh|refresh\(|LiveIndicator|lastError|stats\.error|runsData|feedData' "$f" || true
fi
done
echo "== package versions =="
for f in package.json apps/telemetry/package.json pnpm-lock.yaml package-lock.json yarn.lock; do
if [ -f "$f" ]; then
echo "--- $f"
if [ "$f" = "package.json" ] || [ "$f" = "apps/telemetry/package.json" ]; then
jq -r '.dependencies.nuxt?, .devDependencies.nuxt?, .packageManager?' "$f" 2>/dev/null || cat "$f"
else
rg -n 'nuxt(@|@)|version:.*(nuxt|nestjs|react|vue)|node_modules' "$f" | head -n 80 || true
fi
fi
doneRepository: HugoRCD/evlog
Length of output: 20175
Report failed live-refresh outcomes.
tick() waits for refresh() but does not expose failures, and Nuxt’s useFetch/useAsyncData refresh() captures errors in the .error ref rather than rejecting the returned promise. With index.vue polling Promise.all([refreshStats(), refreshRuns(), refreshFeed()]), a repeated fetch failure can leave LiveIndicator showing “Live” while data stops updating. Return/report an error or failure timestamp from this composable, or surface the failing fetcher’s .error/status state at the call site.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/telemetry/app/composables/useLiveRefresh.ts` around lines 40 - 48,
Update the live-refresh flow around tick() so refresh failures are observable to
its callers despite useFetch/useAsyncData refresh() resolving while populating
.error. Surface the failing fetcher error or a failure timestamp/status from the
composable, and ensure index.vue’s polling and LiveIndicator consume that signal
so repeated failures no longer appear as “Live”.
| { | ||
| "id": "e46d3faa-6409-4729-a210-71f2b864ab6b", | ||
| "prevId": "4951be6d-5aa0-4026-b064-67cdc0a6ebfe", | ||
| "version": "7", | ||
| "dialect": "postgresql", |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Remove generated Drizzle migration metadata from this PR. Both artifacts violate the repository rule against committing generated files.
apps/telemetry/server/db/migrations/postgresql/meta/0001_snapshot.json#L1-L5: remove the generated snapshot artifact.apps/telemetry/server/db/migrations/postgresql/meta/_journal.json#L11-L17: remove the generated journal entry.
As per coding guidelines, “Do not commit secrets, .env files, API keys, generated files, or modifications to node_modules/.”
📍 Affects 2 files
apps/telemetry/server/db/migrations/postgresql/meta/0001_snapshot.json#L1-L5(this comment)apps/telemetry/server/db/migrations/postgresql/meta/_journal.json#L11-L17
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/telemetry/server/db/migrations/postgresql/meta/0001_snapshot.json`
around lines 1 - 5, Remove the generated Drizzle migration metadata artifacts:
delete the snapshot file at
apps/telemetry/server/db/migrations/postgresql/meta/0001_snapshot.json and
remove the corresponding journal entry at
apps/telemetry/server/db/migrations/postgresql/meta/_journal.json lines 11-17.
Source: Coding guidelines
The Nucleo "glass" display icons ship a single fixed dark gradient with no currentColor hook, so they read as an unexplained dark blob floating on a light card. Frame them in an elevated GlassIconTile instead so the surface (not the icon) adapts to the theme. Chart bar/donut colors were also darkened toward black unconditionally, tuned only for the near-black dark mode background — they now use theme-aware --chart-* tokens that stay full-saturation on light cards.
- useFreshIds: bound seenIds to the current visible row set instead of accumulating every id ever seen for the life of the page - useLiveRefresh: surface a lastError so a repeatedly failing poll no longer shows as "Live" — LiveIndicator now reads "Reconnecting" - drop an HTML comment from index.vue's template (project convention) - add missing JSDoc on providerIcon, osLabel, ErrorCodeStat, DurationStats
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/telemetry/app/pages/index.vue`:
- Line 217: Update the LiveIndicator binding in the dashboard page to mark the
indicator as errored when liveError or any useFetch error ref (statsError,
runsError, or feedError) is present. Preserve the existing liveActive state and
last-event timestamp behavior while combining all relevant errors for the
has-error prop.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5e1ebb99-a261-4736-9ee1-a03e0fae79ac
📒 Files selected for processing (19)
apps/telemetry/app/assets/css/main.cssapps/telemetry/app/components/AgentsBreakdown.vueapps/telemetry/app/components/CiBreakdown.vueapps/telemetry/app/components/CommandsTable.vueapps/telemetry/app/components/DailyActivityChart.vueapps/telemetry/app/components/DurationHistogram.vueapps/telemetry/app/components/EnvironmentBreakdown.vueapps/telemetry/app/components/ErrorCodesCard.vueapps/telemetry/app/components/GlassIconTile.vueapps/telemetry/app/components/LiveFeed.vueapps/telemetry/app/components/LiveIndicator.vueapps/telemetry/app/components/StatCard.vueapps/telemetry/app/components/VersionsCard.vueapps/telemetry/app/composables/useFreshIds.tsapps/telemetry/app/composables/useLiveRefresh.tsapps/telemetry/app/pages/index.vueapps/telemetry/app/pages/login.vueapps/telemetry/app/utils/telemetry-icons.tsapps/telemetry/shared/types/telemetry.ts
| </h1> | ||
|
|
||
| <div class="flex flex-wrap items-center gap-2"> | ||
| <LiveIndicator :live="liveActive" :has-error="!!liveError" :last-event-at="stats?.lastEventAt ?? null" @toggle="toggleLive" /> |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
For Nuxt 4.5, does useFetch expose initial and watched request failures through its error ref without throwing from await useFetch?
💡 Result:
In Nuxt 4.5, useFetch does not throw when a request fails, regardless of whether you await the composable or not [1][2]. Instead, it captures errors into the returned error ref, and you must check this ref to handle failures [1][3][4]. Key points regarding this behavior: 1. No Rejection: The promise returned by useFetch (and its internal refresh/execute functions) does not reject on network or HTTP errors [2][4]. 2. Error Ref: When a fetch fails, the error ref provided by the composable is populated with the error object [1][3][5]. 3. Handling Errors: Because it does not throw, wrapping await useFetch in a try/catch block will not catch request errors [2][4]. You must instead monitor the error state, for example by checking if error.value is truthy [2][4]. 4. Consistent Behavior: This behavior is intentional to maintain the reactive state (data, pending, status, error) provided by the composable [2]. While there have been community discussions and feature requests to add an optional throwOnError configuration, it remains non-throwing in the core Nuxt implementation [2][4]. Note that this behavior is specific to the Nuxt composable. It is distinct from the VueUse useFetch implementation, which provides an execute(true) parameter that can cause the promise to reject if the request fails [6][7].
Citations:
- 1: https://nuxt.com/docs/4.x/api/composables/use-fetch
- 2: Add
throwOnErroroption touseAsyncData/useFetchnuxt/nuxt#34531 - 3: https://nuxt.com/docs/4.x/getting-started/data-fetching
- 4: Why does useFetch().execute() not throw an error inside try-catch? nuxt/nuxt#26307
- 5: https://github.com/nuxt/nuxt/blob/1dc113c9/docs/4.api/2.composables/use-fetch.md
- 6: https://vueuse.org/core/usefetch/
- 7:
useFetch| support options.throwOnFailed config vueuse/vueuse#4601
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate files =="
fd -a 'index\.vue$|LiveIndicator\.vue$' . | sed 's#^\./##' | head -100
echo
echo "== outline index.vue =="
ast-grep outline apps/telemetry/app/pages/index.vue --view compact || true
echo
echo "== relevant index.vue sections =="
sed -n '1,260p' apps/telemetry/app/pages/index.vue | nl -ba
echo
echo "== LiveIndicator files =="
files=$(fd 'LiveIndicator\.vue$' .)
printf '%s\n' "$files" | while read -r f; do
echo "--- $f ---"
wc -l "$f"
sed -n '1,260p' "$f" | nl -ba
doneRepository: HugoRCD/evlog
Length of output: 2008
🏁 Script executed:
#!/bin/bash
set -euxo pipefail
echo "== pwd =="
pwd
echo "== locate files =="
fd 'index\.vue$|LiveIndicator\.vue$' . || true
echo
echo "== files matching telemetry index =="
fd 'index\.vue$' . | sed -n '/apps\/telemetry\/app\/pages\/index.vue/p'
echo
echo "== relevant index.vue sections =="
if [ -f apps/telemetry/app/pages/index.vue ]; then
sed -n '1,280p' apps/telemetry/app/pages/index.vue | nl -ba
fi
echo
echo "== LiveIndicator files =="
fd 'LiveIndicator\.vue$' . | while read -r f; do
echo "--- $f ---"
wc -l "$f"
sed -n '1,260p' "$f" | nl -ba
doneRepository: HugoRCD/evlog
Length of output: 2008
🏁 Script executed:
#!/bin/bash
set -euxo pipefail
echo "== pwd =="
pwd
echo "== top-level =="
git ls-files | sed -n '1,80p'
echo
echo "== locate telemetry index =="
git ls-files | grep -E '^apps/telemetry/app/pages/index\.vue$' || true
echo
echo
echo "== index.vue lines =="
if git ls-files | grep -Eq '^apps/telemetry/app/pages/index\.vue$'; then
git show "HEAD:apps/telemetry/app/pages/index.vue" | sed -n '1,280p' | nl -ba
fi
echo
echo "== locate LiveIndicator =="
git ls-files | grep 'LiveIndicator\.vue$' || true
echo
echo "== LiveIndicator content =="
git ls-files | grep 'LiveIndicator\.vue$' | while read -r f; do
echo "--- $f ---"
git show "HEAD:$f" | sed -n '1,260p' | nl -ba
doneRepository: HugoRCD/evlog
Length of output: 2008
Include fetch errors in the reconnecting state.
LiveIndicator receives only liveError, but Nuxt’s useFetch captures failed initial/watched requests in the returned error ref instead of throwing. A failure in statsError, runsError, or feedError can make the dashboard show “Live” even when that data failed to load.
Proposed fix
- <LiveIndicator :live="liveActive" :has-error="!!liveError" :last-event-at="stats?.lastEventAt ?? null" `@toggle`="toggleLive" />
+ <LiveIndicator :live="liveActive" :has-error="!!(liveError || statsError || runsError || feedError)" :last-event-at="stats?.lastEventAt ?? null" `@toggle`="toggleLive" />📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <LiveIndicator :live="liveActive" :has-error="!!liveError" :last-event-at="stats?.lastEventAt ?? null" @toggle="toggleLive" /> | |
| <LiveIndicator :live="liveActive" :has-error="!!(liveError || statsError || runsError || feedError)" :last-event-at="stats?.lastEventAt ?? null" `@toggle`="toggleLive" /> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/telemetry/app/pages/index.vue` at line 217, Update the LiveIndicator
binding in the dashboard page to mark the indicator as errored when liveError or
any useFetch error ref (statsError, runsError, or feedError) is present.
Preserve the existing liveActive state and last-event timestamp behavior while
combining all relevant errors for the has-error prop.
Summary
GET /api/telemetry/stats, and thetelemetry-statsMCP tool).env.osandenv.archon every run event (nullable, backward compatible with older clients) — new@evlog/telemetryfields, DB columns, and migration.i-nucleo-*) exported from the local Nucleo library, replacing Lucide icons across the dashboard; adds a light/dark color mode toggle.Test plan
pnpm run lint,pnpm run typecheck,pnpm run testall pass at the repo root/api/telemetry/statsreturns fully zero-filled buckets for24h/7d/30drangesSummary by CodeRabbit