[DEV-99] View devintern worker logs directly in the dashboard via a Logs tab - #90
Open
danii1 wants to merge 2 commits into
Open
[DEV-99] View devintern worker logs directly in the dashboard via a Logs tab#90danii1 wants to merge 2 commits into
danii1 wants to merge 2 commits into
Conversation
…ashboard via a Logs tab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Task: DEV-99
Summary: View devintern worker logs directly in the dashboard via a Logs tab
Implementation Details
Context is clear. Now let me check a couple more patterns before implementing:
All context gathered. Now implementing:
The first draft has several flaws (broken ANSI pattern, unsafe unbounded read in the tail path, confused timestamp fallback). Rewriting the module cleanly:
Fixing three bugs in that file (fd ordering, misplaced import, literal escape characters):
Shell escaping made this worse. Fixing deterministically with python:
Three fixes needed: space-before-timezone offsets, iterate task-key matches past stop-list, shorter Bearer threshold:
Backend API layer next:
Now the
handleLogshandler at the end of the file:Now wire the route in dashboard-server.ts:
Frontend now. First the API types in dashboard-ui:
Pure view helpers + tests:
Now the LogsView component:
Now the App shell — third tab and route:
Backend test file for worker-logs:
That test draft had two sloppy spots (a convoluted assertion and a fake permission test). Rewriting cleanly with a deterministic directory-as-file trick instead of chmod:
Workspace deps missing — installing first:
Curious — isolated eval passes now. Re-running the actual test suites to see if the failure reproduces:
Found it: fractional seconds are consumed by the regex but never appended to the normalized string. Fixing with explicit groups:
Tests pass. Adding endpoint-level cases to dashboard-api.test.ts:
Now appending the logs tests to dashboard-api.test.ts:
Backend green. Now the UI package tests and typecheck:
UI green. Docs next:
All warnings are pre-existing in untouched code. Typecheck + build:
All 986 tests green across the monorepo. Final verification: rebuild formats and confirm the code package bundles:
End-to-end smoke test of the real server with the built UI:
DEV-99 is implemented and fully verified. Summary of the change:
Backend (
@getdevintern/code)src/lib/worker-logs.ts(new): bounded file-tail reader overworker.stdout.log/worker.stderr.log(the pathsworker init's launchd config writes). Reads only ~256 KiB from each file's end via positional reads, snaps to a line boundary, strips ANSI escapes, parses optional ISO timestamps, classifies severity (explicit ❌/ERROR/⚠ markers win over stderr-default), masks credential-shaped content before serving, extracts Jira-style task keys (with a stop-list for SHA-/CVE- style false positives), weaves stdout+stderr round-robin when untimed and true-merges by timestamp when every line carries one.src/lib/dashboard-api.ts: newgetWorkerLogs()onDashboardData(searches the working dir plus the workspace home so standalonedevintern dashboardstill finds the daemon's files) and enriches entries with their latest matching run (runId,runStatus) via the existing run store; new validatedhandleLogshandler (limit1–1000,levelall/info/warn/error).src/dashboard-server.ts: servesGET /api/logs.Frontend (
@devintern/dashboard-ui)#/logs; auto-refreshing via the sharedusePoll(pauses on hidden tabs), server-side level filter, client-side search with a live error/warning count, follow-tail scrolling with "↓ Jump to latest" when you scroll up, level dots + stderr badges, per-entry task chip linking to#/runs/:id, and graceful empty states (no capture files yet / no matches / fetch error) plus a truncation & unreadable-source footnote.Verification
tests/worker-logs.test.ts(parsing + tailing incl. byte-window truncation, stream interleave, unreadable-source handling), logs cases intests/dashboard-api.test.ts(validation, empty state, redaction + run linkage, HTTP end-to-end),log-view.test.tsin the UI package.docs/code/dashboard.md(Logs tab, log sources/redaction/bounds, API table) and a troubleshooting row indocs/code/worker.md.This PR was automatically created by @devintern/code