Skip to content

Richer HTTP logging, context tree, and startup banner#255

Merged
PunGrumpy merged 10 commits intomainfrom
feat/logixlysia-rich-logging-banner
Mar 22, 2026
Merged

Richer HTTP logging, context tree, and startup banner#255
PunGrumpy merged 10 commits intomainfrom
feat/logixlysia-rich-logging-banner

Conversation

@PunGrumpy
Copy link
Copy Markdown
Owner

@PunGrumpy PunGrumpy commented Mar 21, 2026

Description

This PR improves HTTP request logging and startup output for logixlysia, and updates the Elysia demo app to exercise the new options.

Logger

  • Introduces formatLogOutput returning a main line plus optional context tree lines; keeps formatLine as a deprecated compatibility wrapper (main line only).
  • Default log format now emphasizes timestamp, optional service tag, level icon, padded method, pathname, status, duration (with slow/very-slow coloring and a ⚡ slow badge when over threshold), and message.
  • New Options.config fields: service, slowThreshold, verySlowThreshold, showContextTree, contextDepth.
  • New format tokens: {icon}, {service}, {statusText}, {speed} (existing tokens like {context} still work; JSON context is inlined when the tree is disabled).
  • HTTP error path uses the same multi-line formatting when context/error tree lines exist.

Startup banner

  • Box banner shows Elysia version, URL line, and an optional logixlysia package version line.

Repo hygiene

  • Minor Changeset: .changeset/rich-logging-banner.md for the next logixlysia release.
  • Tests: format-output.test.ts plus updates to create-logger and start-server tests.
  • Demo: apps/elysia router config updated to showcase service, thresholds, context tree, and timestamp format.

Checklist

  • I've reviewed my code
  • I've written tests
  • I've generated a change set file
  • I've updated the docs, if necessary

Screenshots (if applicable)

image

Summary by CodeRabbit

  • New Features

    • Enhanced logging: service prefix, speed/“⚡ slow” markers, formatted durations, and optional multi-line context tree with configurable depth
    • Improved startup banner showing server URL and optional package version in a boxed layout
    • New/default placeholders: {icon}, {service}, {statusText}, {speed}, and {context}
  • Documentation

    • Updated docs and examples describing new placeholders, defaults, and context-tree behavior
  • Tests

    • Added/updated tests for formatting, context rendering, and startup banner output

@codesandbox
Copy link
Copy Markdown

codesandbox bot commented Mar 21, 2026

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
logixlysia Ready Ready Preview, Comment Mar 22, 2026 11:25am

@PunGrumpy PunGrumpy marked this pull request as draft March 21, 2026 17:00
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 21, 2026

📝 Walkthrough

Walkthrough

Adds multi-line log output with a configurable context-tree renderer, new logger options for service/thresholds/verbosity, replaces the single-line formatter with formatLogOutput (returns { main, contextLines }), updates consumers to append context lines when present, and refactors the startup banner to accept separate URL and optional logixlysia version.

Changes

Cohort / File(s) Summary
Changeset & App config
.changeset/rich-logging-banner.md, apps/elysia/src/routers/index.ts
New changeset documenting the minor bump; demo app updated to set service, change timestamp format, enable context tree, and add slowThreshold/verySlowThreshold.
Logger API & Types
packages/logixlysia/src/interfaces.ts, packages/logixlysia/src/logger/create-logger.ts
Added Options.config fields: service, slowThreshold, verySlowThreshold, showContextTree, contextDepth. Introduced formatLogOutput and FormattedLogOutput type, exported formatDuration, deprecated formatLine, implemented context-tree rendering, and added threshold-based speed/“very slow” markers.
Logger Integration
packages/logixlysia/src/logger/index.ts, packages/logixlysia/src/logger/handle-http-error.ts
Switched callers from formatLine(...) to formatLogOutput(...) and changed message assembly to append newline-separated contextLines under the main line when present.
Banner & Startup
packages/logixlysia/src/extensions/banner.ts, packages/logixlysia/src/extensions/index.ts
Banner now loads package.json via createRequire, exposes getLogixlysiaVersionLine(), renderBanner accepts urlDisplayLine + optional logixlysiaLine, and startServer passes separate URL/version lines.
Tests
packages/logixlysia/__tests__/extensions/start-server.test.ts, packages/logixlysia/__tests__/logger/create-logger.test.ts, packages/logixlysia/__tests__/logger/format-output.test.ts
Start-server test loosened to assert banner components; tests cast fakePino as typeof pino; new format-output.test.ts added to cover duration formatting, main/context outputs, service token, speed thresholds, and context-tree flattening.
Docs & Playground
apps/docs/... (multiple files), packages/logixlysia/README.md, apps/docs/app/(home)/components/playground/index.tsx
Documentation updated to describe new placeholders ({service}, {statusText}, {icon}, {speed}, {context}) and options; playground UI and sample logs adjusted to use durationMs, service, message, and contextLines with tree-style rendering.
Misc UI
apps/docs/app/(home)/components/playground/background.tsx
Background wrapper set aria-hidden and pointer-events-none; next/image updated to use fill layout and rendering hints for presentation/accessibility.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant Logger
    participant Formatter as formatLogOutput()
    participant ContextTree as buildContextTree()
    participant Console as Console/Transport

    Client->>Logger: incoming HTTP request / event
    Logger->>Formatter: formatLogOutput(level, meta, options)
    Formatter->>ContextTree: expand data.context (contextDepth, showContextTree)
    ContextTree-->>Formatter: return contextLines[]
    Formatter->>Formatter: build main line (tokens: icon, service, statusText, speed)
    Formatter-->>Logger: { main, contextLines }
    Logger->>Console: log main (append contextLines if any)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

website

Poem

🦊 I hop through logs with twigs in hand,
I draw the tree where traces land,
I flag the slow with lightning cheer,
I whisper service names so clear—
A rabbit’s banner bold and grand. 🐇

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main changes: richer HTTP logging with context tree and startup banner improvements.
Description check ✅ Passed The description covers the main changes, includes tests and changeset; however, the 'I've reviewed my code' checkbox is unchecked.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/logixlysia-rich-logging-banner

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 github-actions bot added enhancement 💫 New feature or request source 🏠 Source code files test 🧪 Test files docs 📃 Documentation files changeset 📏 An intent to release a set of packages labels Mar 21, 2026
@coderabbitai coderabbitai bot added the config ⚙️ Configuration files label Mar 21, 2026
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: 1

Caution

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

⚠️ Outside diff range comments (1)
packages/logixlysia/src/logger/create-logger.ts (1)

165-199: ⚠️ Potential issue | 🟡 Minor

Padding before classification makes every colored method fall back to white.

getColoredMethod() compares against exact tokens like GET, but it now receives padded values such as GET    . In TTY output, all known methods will miss their branch and use the fallback style.

🎨 Suggested fix
 const getColoredMethod = (method: string, useColors: boolean): string => {
-  if (!useColors) {
-    return method
-  }
-
   const upper = method.toUpperCase()
+  const padded = upper.padEnd(METHOD_PAD)
+
+  if (!useColors) {
+    return padded
+  }
+
   if (upper === 'GET') {
-    return chalk.green.bold(upper)
+    return chalk.green.bold(padded)
   }
   if (upper === 'POST') {
-    return chalk.blue.bold(upper)
+    return chalk.blue.bold(padded)
   }
   if (upper === 'PUT') {
-    return chalk.yellow.bold(upper)
+    return chalk.yellow.bold(padded)
   }
   if (upper === 'PATCH') {
-    return chalk.yellowBright.bold(upper)
+    return chalk.yellowBright.bold(padded)
   }
   if (upper === 'DELETE') {
-    return chalk.red.bold(upper)
+    return chalk.red.bold(padded)
   }
   if (upper === 'OPTIONS') {
-    return chalk.cyan.bold(upper)
+    return chalk.cyan.bold(padded)
   }
   if (upper === 'HEAD') {
-    return chalk.greenBright.bold(upper)
+    return chalk.greenBright.bold(padded)
   }
   if (upper === 'TRACE') {
-    return chalk.magenta.bold(upper)
+    return chalk.magenta.bold(padded)
   }
   if (upper === 'CONNECT') {
-    return chalk.cyanBright.bold(upper)
+    return chalk.cyanBright.bold(padded)
   }
 
-  return chalk.white.bold(upper)
+  return chalk.white.bold(padded)
 }
@@
-  const methodPadded = request.method.toUpperCase().padEnd(METHOD_PAD)
-  const coloredMethod = getColoredMethod(methodPadded, useColors)
+  const coloredMethod = getColoredMethod(request.method, useColors)

Also applies to: 441-442

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

In `@packages/logixlysia/src/logger/create-logger.ts` around lines 165 - 199,
getColoredMethod is comparing the raw method string against exact tokens but
receives padded values (e.g., "GET    "), causing every known method to hit the
fallback; fix it by trimming whitespace before classification (use method.trim()
then toUpperCase()) so comparisons use the normalized token (update the local
`upper` calculation in getColoredMethod and the other similar occurrence around
the 441-442 area).
🧹 Nitpick comments (2)
packages/logixlysia/src/extensions/banner.ts (1)

57-61: Minor: Simplify spread in Math.max call.

The spread ...(logixlysiaLine ? [logixlysiaLine.length] : [0]) could be simplified since Math.max ignores additional arguments. Using 0 directly would suffice when logixlysiaLine is null.

Suggested simplification
   const contentWidth = Math.max(
     versionLine.length,
     urlDisplayLine.length,
-    ...(logixlysiaLine ? [logixlysiaLine.length] : [0])
+    logixlysiaLine?.length ?? 0
   )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/logixlysia/src/extensions/banner.ts` around lines 57 - 61, The
Math.max invocation used to compute contentWidth is overly complex: replace
Math.max(versionLine.length, urlDisplayLine.length, ...(logixlysiaLine ?
[logixlysiaLine.length] : [0])) with a simpler call that passes 0 when
logixlysiaLine is falsy (e.g., Math.max(versionLine.length,
urlDisplayLine.length, logixlysiaLine ? logixlysiaLine.length : 0)); update the
expression that defines contentWidth to use versionLine, urlDisplayLine, and the
conditional logixlysiaLine.length directly.
packages/logixlysia/src/logger/create-logger.ts (1)

291-332: Prefer for...of appends in the context-tree helpers.

Both helpers are on the per-request formatting path, and the current spread-into-accumulator plus indexed loop add avoidable churn for something that can stay simple with for...of.

♻️ Suggested cleanup
 const collectContextEntries = (
   obj: Record<string, unknown>,
   prefix: string,
   depthRemaining: number
 ): [string, string][] => {
   const out: [string, string][] = []
   for (const [k, v] of Object.entries(obj)) {
     const key = prefix ? `${prefix}.${k}` : k
     const expandable = isExpandableObject(v) && depthRemaining > 1
 
     if (expandable) {
-      out.push(...collectContextEntries(v, key, depthRemaining - 1))
+      for (const entry of collectContextEntries(v, key, depthRemaining - 1)) {
+        out.push(entry)
+      }
     } else {
       out.push([key, stringifyTreeValue(v)])
     }
   }
   return out
 }
@@
-  for (let i = 0; i < entries.length; i++) {
-    const branch = i === last ? '└─' : '├─'
-    const pair = entries[i]
-    if (!pair) {
-      continue
-    }
-    const [k, v] = pair
+  for (const [i, [k, v]] of entries.entries()) {
+    const branch = i === last ? '└─' : '├─'
     const keyPart = useColors ? chalk.cyan(k) : k
     const valPart = useColors ? chalk.white(v) : v
     lines.push(`  ${branch} ${keyPart}  ${valPart}`)
   }
As per coding guidelines, "Prefer `for...of` loops over `.forEach()` and indexed `for` loops" and "Avoid spread syntax in accumulators within loops."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/logixlysia/src/logger/create-logger.ts` around lines 291 - 332, The
helpers collectContextEntries and formatEntriesToTreeLines use
spread-into-accumulator and an indexed for loop which causes extra churn;
replace the spread call out.push(...collectContextEntries(v, key, depthRemaining
- 1)) with a direct for...of over the recursive result (for (const entry of
collectContextEntries(...)) out.push(entry)) in collectContextEntries, and
rewrite the indexed for loop in formatEntriesToTreeLines to a for...of over
entries.entries() (or maintain a simple counter) to get index and pair (so you
can still compute last and branch) and push directly into lines without using
array indexing or spread; keep existing key/value coloring and continue to guard
for falsy pair if desired.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/logixlysia/src/logger/create-logger.ts`:
- Around line 430-438: formatLine() currently inherits the new default
showContextTree behavior so ctxString becomes empty for non-empty object
contexts and breaks existing one-line `{context}` users; inside formatLine()
(the function computing ctxString using showTree, ctxString, and
getContextString) override the config to force showContextTree:false (or
otherwise detect callers expecting one-line context) so that
getContextString(data.context) is used for object contexts, preserving the old
one-line payload; update the same logic at the other occurrence (the block
around the second instance noted) to apply the same override.

---

Outside diff comments:
In `@packages/logixlysia/src/logger/create-logger.ts`:
- Around line 165-199: getColoredMethod is comparing the raw method string
against exact tokens but receives padded values (e.g., "GET    "), causing every
known method to hit the fallback; fix it by trimming whitespace before
classification (use method.trim() then toUpperCase()) so comparisons use the
normalized token (update the local `upper` calculation in getColoredMethod and
the other similar occurrence around the 441-442 area).

---

Nitpick comments:
In `@packages/logixlysia/src/extensions/banner.ts`:
- Around line 57-61: The Math.max invocation used to compute contentWidth is
overly complex: replace Math.max(versionLine.length, urlDisplayLine.length,
...(logixlysiaLine ? [logixlysiaLine.length] : [0])) with a simpler call that
passes 0 when logixlysiaLine is falsy (e.g., Math.max(versionLine.length,
urlDisplayLine.length, logixlysiaLine ? logixlysiaLine.length : 0)); update the
expression that defines contentWidth to use versionLine, urlDisplayLine, and the
conditional logixlysiaLine.length directly.

In `@packages/logixlysia/src/logger/create-logger.ts`:
- Around line 291-332: The helpers collectContextEntries and
formatEntriesToTreeLines use spread-into-accumulator and an indexed for loop
which causes extra churn; replace the spread call
out.push(...collectContextEntries(v, key, depthRemaining - 1)) with a direct
for...of over the recursive result (for (const entry of
collectContextEntries(...)) out.push(entry)) in collectContextEntries, and
rewrite the indexed for loop in formatEntriesToTreeLines to a for...of over
entries.entries() (or maintain a simple counter) to get index and pair (so you
can still compute last and branch) and push directly into lines without using
array indexing or spread; keep existing key/value coloring and continue to guard
for falsy pair if desired.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

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: CHILL

Plan: Pro

Run ID: c16d492c-a9e8-4323-a4ca-f19fb6ba4d7b

📥 Commits

Reviewing files that changed from the base of the PR and between a2ed984 and 72d7a12.

📒 Files selected for processing (11)
  • .changeset/rich-logging-banner.md
  • apps/elysia/src/routers/index.ts
  • packages/logixlysia/__tests__/extensions/start-server.test.ts
  • packages/logixlysia/__tests__/logger/create-logger.test.ts
  • packages/logixlysia/__tests__/logger/format-output.test.ts
  • packages/logixlysia/src/extensions/banner.ts
  • packages/logixlysia/src/extensions/index.ts
  • packages/logixlysia/src/interfaces.ts
  • packages/logixlysia/src/logger/create-logger.ts
  • packages/logixlysia/src/logger/handle-http-error.ts
  • packages/logixlysia/src/logger/index.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: 🏗️ Build
  • GitHub Check: agent
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • packages/logixlysia/__tests__/logger/create-logger.test.ts
  • packages/logixlysia/src/logger/index.ts
  • packages/logixlysia/src/logger/handle-http-error.ts
  • packages/logixlysia/src/extensions/index.ts
  • apps/elysia/src/routers/index.ts
  • packages/logixlysia/__tests__/extensions/start-server.test.ts
  • packages/logixlysia/src/interfaces.ts
  • packages/logixlysia/src/extensions/banner.ts
  • packages/logixlysia/__tests__/logger/format-output.test.ts
  • packages/logixlysia/src/logger/create-logger.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{ts,tsx,js,jsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Keep functions focused and under reasonable cognitive complexity limits
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Group related code together and separate concerns
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use proper image components (e.g., Next.js <Image>) over <img> tags

Files:

  • packages/logixlysia/__tests__/logger/create-logger.test.ts
  • packages/logixlysia/src/logger/index.ts
  • packages/logixlysia/src/logger/handle-http-error.ts
  • packages/logixlysia/src/extensions/index.ts
  • apps/elysia/src/routers/index.ts
  • packages/logixlysia/__tests__/extensions/start-server.test.ts
  • packages/logixlysia/src/interfaces.ts
  • packages/logixlysia/src/extensions/banner.ts
  • packages/logixlysia/__tests__/logger/format-output.test.ts
  • packages/logixlysia/src/logger/create-logger.ts
**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{test,spec}.{ts,tsx,js,jsx}: Write assertions inside it() or test() blocks
Avoid done callbacks in async tests - use async/await instead
Don't use .only or .skip in committed code
Keep test suites reasonably flat - avoid excessive describe nesting

Files:

  • packages/logixlysia/__tests__/logger/create-logger.test.ts
  • packages/logixlysia/__tests__/extensions/start-server.test.ts
  • packages/logixlysia/__tests__/logger/format-output.test.ts
**/index.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

Avoid barrel files (index files that re-export everything)

Files:

  • packages/logixlysia/src/logger/index.ts
  • packages/logixlysia/src/extensions/index.ts
  • apps/elysia/src/routers/index.ts
🧠 Learnings (2)
📚 Learning: 2025-12-21T17:02:32.986Z
Learnt from: CR
Repo: PunGrumpy/logixlysia PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-12-21T17:02:32.986Z
Learning: Applies to **/*.{test,spec}.{ts,tsx,js,jsx} : Write assertions inside `it()` or `test()` blocks

Applied to files:

  • packages/logixlysia/__tests__/logger/create-logger.test.ts
  • packages/logixlysia/__tests__/logger/format-output.test.ts
📚 Learning: 2025-12-21T17:02:32.986Z
Learnt from: CR
Repo: PunGrumpy/logixlysia PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-12-21T17:02:32.986Z
Learning: Applies to **/*.{test,spec}.{ts,tsx,js,jsx} : Keep test suites reasonably flat - avoid excessive `describe` nesting

Applied to files:

  • packages/logixlysia/__tests__/logger/create-logger.test.ts
  • packages/logixlysia/__tests__/logger/format-output.test.ts
🔇 Additional comments (16)
packages/logixlysia/src/extensions/banner.ts (3)

12-19: LGTM! Clean version loading pattern.

The IIFE pattern for loading the logixlysia package version mirrors the existing elysiaPkg approach, maintaining consistency. Error handling gracefully falls back to an empty object.


31-84: Well-structured row-spec model for banner rendering.

The discriminated union RowSpec and the row-based rendering loop cleanly separate layout specification from rendering logic. The for...of loop at line 69 aligns with coding guidelines.


86-92: LGTM! Clean helper function.

The function correctly returns null when no version is available, enabling the caller to conditionally include the line.

packages/logixlysia/src/extensions/index.ts (2)

2-2: LGTM! Import updated correctly.

The import now includes getLogixlysiaVersionLine to support the new banner signature.


18-28: Clean separation of simple vs banner formats.

The code maintains backward compatibility for the simple format while using the new two-argument renderBanner call for the banner format. The extra space in urlDisplayLine (🦊 ${url}) is intentional for banner visual alignment.

packages/logixlysia/__tests__/logger/create-logger.test.ts (2)

2-2: LGTM! Type import added for proper casting.

Importing the pino type allows for explicit casting of test doubles, improving type safety.


104-104: Proper test double typing pattern.

The as unknown as typeof pino double-cast is the correct approach when the fake doesn't fully implement the real interface. This pattern is consistently applied across all affected tests.

packages/logixlysia/__tests__/extensions/start-server.test.ts (2)

26-43: Simple format test correctly preserved.

The test for the simple message format verifies the original combined message string '🦊 Elysia is running at http://localhost:3000', which is still used when startupMessageFormat: 'simple' is configured.


19-21: No actionable concern - assertion correctly verifies version inclusion.

The test correctly asserts that the banner output contains 'logixlysia v'. The getLogixlysiaVersionLine() function includes proper error handling and returns null only if the version is unavailable—in which case the banner gracefully omits that line and the test assertion appropriately fails, indicating an actual problem. This is correct test behavior, not brittleness. The package.json is accessible in the test environment with version "6.2.3" available.

packages/logixlysia/src/logger/index.ts (2)

13-13: LGTM! Import updated to new formatting API.

The import correctly switches from formatLine to formatLogOutput to support the new multi-line logging format.


102-110: Clean message assembly from formatLogOutput result.

The destructuring and conditional concatenation correctly handles both single-line and multi-line output scenarios. The pattern contextLines.length > 0 check before joining is appropriate.

packages/logixlysia/src/logger/handle-http-error.ts (2)

5-5: LGTM! Import updated to match new API.

The import correctly uses formatLogOutput from the create-logger module.


59-68: Consistent message assembly pattern.

The message assembly logic mirrors the pattern in index.ts (lines 102-110). While this is duplicated, the scope is small enough that extracting a helper would add unnecessary indirection.

apps/elysia/src/routers/index.ts (1)

12-18: Demo app updated to showcase new logger options.

The configuration demonstrates the new features: service, performance thresholds, and context tree. Note that slowThreshold: 500, verySlowThreshold: 1000, and showContextTree: true match the defaults defined in create-logger.ts, so they're illustrative for the demo rather than functional overrides.

packages/logixlysia/src/interfaces.ts (1)

77-86: Well-documented interface additions.

The new configuration options are properly typed and documented with JSDoc comments that include default values. The defaults mentioned (500, 1000, true, 1) match the implementations in create-logger.ts (per context snippets showing DEFAULT_SLOW_MS = 500, DEFAULT_VERY_SLOW_MS = 1000, and inline defaults for showContextTree and contextDepth).

packages/logixlysia/__tests__/logger/format-output.test.ts (1)

10-184: Nice coverage on the formatter split.

These cases pin the new main/contextLines contract, threshold handling, and nested/error context rendering well.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@PunGrumpy PunGrumpy marked this pull request as ready for review March 22, 2026 10:53
@PunGrumpy

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

…logging options

- Added new configuration options: `service`, `slowThreshold`, `verySlowThreshold`, `showContextTree`, and `contextDepth` to the API reference.
- Updated the usage documentation to reflect changes in placeholder descriptions, including `statusText`, `icon`, and `speed`.
- Improved formatting section to clarify the use of placeholders in custom log formats and the context tree feature.
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: 3

🧹 Nitpick comments (1)
packages/logixlysia/src/logger/create-logger.ts (1)

362-372: Reuse isExpandableObject(ctx) here instead of the casts.

This branch re-implements the same narrowing rules and then asserts ctx twice. Using the existing type guard keeps the top-level check aligned with the recursive renderer and removes the assertions.

♻️ Suggested cleanup
-  if (
-    ctx &&
-    typeof ctx === 'object' &&
-    !Array.isArray(ctx) &&
-    Object.keys(ctx as object).length > 0 &&
-    depth >= 1
-  ) {
-    entries.push(
-      ...collectContextEntries(ctx as Record<string, unknown>, '', depth)
-    )
+  if (isExpandableObject(ctx) && Object.keys(ctx).length > 0 && depth >= 1) {
+    entries.push(...collectContextEntries(ctx, '', depth))
   }

As per coding guidelines, "Leverage TypeScript's type narrowing instead of type assertions".

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

In `@packages/logixlysia/src/logger/create-logger.ts` around lines 362 - 372,
Replace the manual typeof/Array/Object.keys type checks and double-cast of ctx
with the existing type guard isExpandableObject to keep type narrowing
consistent: in create-logger where ctx is evaluated before calling
collectContextEntries, use isExpandableObject(ctx) && depth >= 1 and then call
collectContextEntries(ctx, '', depth) without casting; this removes the
redundant assertions and aligns the top-level check with the recursive renderer
logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/logixlysia/src/logger/create-logger.ts`:
- Around line 430-438: The current ctxString branch uses getContextString()
(which does a raw JSON.stringify) and can throw on circular arrays/objects;
change this path to use the same safe stringify strategy as stringifyTreeValue()
instead of getContextString() whenever showTree is false or when context is an
array, and update the deprecated formatLine() shim (which forces
showContextTree: false) to also call stringifyTreeValue() for its context
serialization; locate references to showTree, ctxString, getContextString,
stringifyTreeValue, and formatLine to replace the unsafe JSON.stringify usage
with the safer stringifyTreeValue approach.
- Around line 441-442: The code pads the HTTP verb before calling
getColoredMethod, causing mismatches (methodPadded like "GET    ") so the color
branches never match; instead pass the raw verb (request.method or
request.method.toUpperCase()) into getColoredMethod and move padding into the
helper (or add a padSize parameter to getColoredMethod and do padEnd(METHOD_PAD)
inside it), then apply coloring and return the already-padded colored string;
update the getColoredMethod signature and call sites accordingly (referencing
methodPadded, getColoredMethod, request.method, METHOD_PAD).
- Around line 334-345: The renderContextTreeLines function accepts
options.config?.contextDepth which may be Infinity and lead to unbounded
recursion; normalize and clamp that value to a finite non-negative integer
(e.g., let depth = Number.isFinite(rawDepth) ? Math.max(0, Math.floor(rawDepth))
: DEFAULT_MAX_DEPTH) and reuse that normalized depth when calling
collectContextEntries and formatEntriesToTreeLines; apply the same
normalization/clamping pattern to the other context-depth usage (the block
around collectContextEntries/formatEntriesToTreeLines at the later occurrence)
so both helpers receive the safe integer depth.

---

Nitpick comments:
In `@packages/logixlysia/src/logger/create-logger.ts`:
- Around line 362-372: Replace the manual typeof/Array/Object.keys type checks
and double-cast of ctx with the existing type guard isExpandableObject to keep
type narrowing consistent: in create-logger where ctx is evaluated before
calling collectContextEntries, use isExpandableObject(ctx) && depth >= 1 and
then call collectContextEntries(ctx, '', depth) without casting; this removes
the redundant assertions and aligns the top-level check with the recursive
renderer logic.
🪄 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: CHILL

Plan: Pro

Run ID: 5daaa79e-9c9a-4a75-92e0-2e8a28c53e6a

📥 Commits

Reviewing files that changed from the base of the PR and between 72d7a12 and c8b42b3.

📒 Files selected for processing (1)
  • packages/logixlysia/src/logger/create-logger.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • packages/logixlysia/src/logger/create-logger.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{ts,tsx,js,jsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Keep functions focused and under reasonable cognitive complexity limits
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Group related code together and separate concerns
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use proper image components (e.g., Next.js <Image>) over <img> tags

Files:

  • packages/logixlysia/src/logger/create-logger.ts

Comment on lines +334 to +345
export const renderContextTreeLines = (
ctx: Record<string, unknown>,
options: Options,
useColors: boolean
): string[] => {
const depth = options.config?.contextDepth ?? 1
if (depth < 1) {
return []
}

const entries = collectContextEntries(ctx, '', depth)
return formatEntriesToTreeLines(entries, useColors)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Clamp contextDepth to a finite integer before recursing.

depth < 1 still accepts Infinity, and Infinity - 1 stays Infinity. If a caller uses contextDepth: Infinity to mean “expand all”, a cyclic context object will recurse until the stack blows. Please normalize once with something like Number.isFinite() + integer clamping and reuse that value in both helpers.

Also applies to: 357-359

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

In `@packages/logixlysia/src/logger/create-logger.ts` around lines 334 - 345, The
renderContextTreeLines function accepts options.config?.contextDepth which may
be Infinity and lead to unbounded recursion; normalize and clamp that value to a
finite non-negative integer (e.g., let depth = Number.isFinite(rawDepth) ?
Math.max(0, Math.floor(rawDepth)) : DEFAULT_MAX_DEPTH) and reuse that normalized
depth when calling collectContextEntries and formatEntriesToTreeLines; apply the
same normalization/clamping pattern to the other context-depth usage (the block
around collectContextEntries/formatEntriesToTreeLines at the later occurrence)
so both helpers receive the safe integer depth.

Comment on lines +430 to +438
const showTree = config?.showContextTree !== false
const ctxString =
showTree &&
data.context &&
typeof data.context === 'object' &&
!Array.isArray(data.context) &&
Object.keys(data.context as object).length > 0
? ''
: getContextString(data.context)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Inline {context} can still throw on circular values.

This path falls back to getContextString() whenever the tree is disabled, and arrays always go through it. getContextString() does a raw JSON.stringify(), so a circular array/object will raise while formatting logs. That also affects the deprecated formatLine() shim, because it forces showContextTree: false. Please switch this path to the same safe stringify strategy used by stringifyTreeValue().

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

In `@packages/logixlysia/src/logger/create-logger.ts` around lines 430 - 438, The
current ctxString branch uses getContextString() (which does a raw
JSON.stringify) and can throw on circular arrays/objects; change this path to
use the same safe stringify strategy as stringifyTreeValue() instead of
getContextString() whenever showTree is false or when context is an array, and
update the deprecated formatLine() shim (which forces showContextTree: false) to
also call stringifyTreeValue() for its context serialization; locate references
to showTree, ctxString, getContextString, stringifyTreeValue, and formatLine to
replace the unsafe JSON.stringify usage with the safer stringifyTreeValue
approach.

Comment on lines +441 to +442
const methodPadded = request.method.toUpperCase().padEnd(METHOD_PAD)
const coloredMethod = getColoredMethod(methodPadded, useColors)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Pass the raw verb into getColoredMethod().

Line 441 pads before classification, so getColoredMethod() receives values like GET     and POST   . None of those match the exact verb branches, which means colored output falls through to the default white style for every method. Padding needs to happen after the verb has been matched, inside the helper.

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

In `@packages/logixlysia/src/logger/create-logger.ts` around lines 441 - 442, The
code pads the HTTP verb before calling getColoredMethod, causing mismatches
(methodPadded like "GET    ") so the color branches never match; instead pass
the raw verb (request.method or request.method.toUpperCase()) into
getColoredMethod and move padding into the helper (or add a padSize parameter to
getColoredMethod and do padEnd(METHOD_PAD) inside it), then apply coloring and
return the already-padded colored string; update the getColoredMethod signature
and call sites accordingly (referencing methodPadded, getColoredMethod,
request.method, METHOD_PAD).

…options

- Enhanced the demo code to include new logging options: `service`, `showContextTree`, `contextDepth`, `slowThreshold`, and `verySlowThreshold`.
- Updated the README to align with the changes in the demo, ensuring accurate documentation of the new features and their usage.
…ry structure

- Updated the Background component to improve accessibility and visual styling.
- Refactored log entry structure to include new properties: `durationMs`, `service`, `message`, and `contextLines`.
- Adjusted HTTP method color coding for better clarity.
- Introduced utility functions for formatting timestamps and durations, enhancing log readability.
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.

🧹 Nitpick comments (1)
apps/docs/app/(home)/components/playground/index.tsx (1)

186-191: Consider using a generic placeholder instead of an email.

The demo data includes email: 'ada@example.com'. While this is clearly fake data using example.com, consider using a non-email identifier like { key: 'accountId', value: 'acct_123' } to avoid implicitly suggesting that logging emails is a common practice.

🔧 Optional: Replace email with generic identifier
     contextLines: [
-      { key: 'email', value: 'ada@example.com' },
+      { key: 'accountId', value: 'acct_456' },
       { key: 'feature', value: 'signup-flow' }
     ]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/docs/app/`(home)/components/playground/index.tsx around lines 186 - 191,
Replace the fake email in the demo contextLines with a non-email generic
identifier to avoid implying emails should be logged; locate the object literal
that has message: 'User signup' and the contextLines array and change the entry
{ key: 'email', value: 'ada@example.com' } to something like { key: 'accountId',
value: 'acct_123' } (or another non-email key/value) so the demo uses a generic
identifier instead of an email address.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/docs/app/`(home)/components/playground/index.tsx:
- Around line 186-191: Replace the fake email in the demo contextLines with a
non-email generic identifier to avoid implying emails should be logged; locate
the object literal that has message: 'User signup' and the contextLines array
and change the entry { key: 'email', value: 'ada@example.com' } to something
like { key: 'accountId', value: 'acct_123' } (or another non-email key/value) so
the demo uses a generic identifier instead of an email address.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d92939ae-324c-470f-a7db-918d2a26ea6c

📥 Commits

Reviewing files that changed from the base of the PR and between c8b42b3 and 6df8fd5.

⛔ Files ignored due to path filters (1)
  • apps/docs/content/(docs)/preview.png is excluded by !**/*.png
📒 Files selected for processing (8)
  • apps/docs/app/(home)/components/demo.tsx
  • apps/docs/app/(home)/components/playground/background.tsx
  • apps/docs/app/(home)/components/playground/index.tsx
  • apps/docs/content/(docs)/api-reference.mdx
  • apps/docs/content/(docs)/configuration.mdx
  • apps/docs/content/(docs)/usage.mdx
  • apps/docs/content/features/formatting.mdx
  • packages/logixlysia/README.md
✅ Files skipped from review due to trivial changes (3)
  • apps/docs/content/(docs)/api-reference.mdx
  • apps/docs/content/(docs)/usage.mdx
  • apps/docs/app/(home)/components/demo.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: 🏗️ Build
  • GitHub Check: agent
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • apps/docs/app/(home)/components/playground/background.tsx
  • apps/docs/app/(home)/components/playground/index.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{ts,tsx,js,jsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Keep functions focused and under reasonable cognitive complexity limits
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Group related code together and separate concerns
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use proper image components (e.g., Next.js <Image>) over <img> tags

Files:

  • apps/docs/app/(home)/components/playground/background.tsx
  • apps/docs/app/(home)/components/playground/index.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{tsx,jsx}: Use function components over class components in React
Call hooks at the top level only, never conditionally
Specify all dependencies in hook dependency arrays correctly
Use the key prop for elements in iterables (prefer unique IDs over array indices)
Nest children between opening and closing tags instead of passing as props in React
Don't define components inside other components in React
Avoid dangerouslySetInnerHTML unless absolutely necessary
Use Next.js <Image> component for images
Use next/head or App Router metadata API for head elements in Next.js
Use Server Components for async data fetching instead of async Client Components in Next.js
Use ref as a prop instead of React.forwardRef in React 19+

Files:

  • apps/docs/app/(home)/components/playground/background.tsx
  • apps/docs/app/(home)/components/playground/index.tsx
**/*.{html,tsx,jsx,vue,svelte,astro}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{html,tsx,jsx,vue,svelte,astro}: Use semantic HTML and ARIA attributes for accessibility: provide meaningful alt text for images, use proper heading hierarchy, add labels for form inputs, include keyboard event handlers alongside mouse events, and use semantic elements
Add rel="noopener" when using target="_blank" on links

Files:

  • apps/docs/app/(home)/components/playground/background.tsx
  • apps/docs/app/(home)/components/playground/index.tsx
**/index.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

Avoid barrel files (index files that re-export everything)

Files:

  • apps/docs/app/(home)/components/playground/index.tsx
🧠 Learnings (4)
📚 Learning: 2025-12-21T17:02:32.986Z
Learnt from: CR
Repo: PunGrumpy/logixlysia PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-12-21T17:02:32.986Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use proper image components (e.g., Next.js `<Image>`) over `<img>` tags

Applied to files:

  • apps/docs/app/(home)/components/playground/background.tsx
📚 Learning: 2025-12-21T17:02:32.986Z
Learnt from: CR
Repo: PunGrumpy/logixlysia PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-12-21T17:02:32.986Z
Learning: Applies to **/*.{tsx,jsx} : Use Next.js `<Image>` component for images

Applied to files:

  • apps/docs/app/(home)/components/playground/background.tsx
📚 Learning: 2025-12-21T17:02:32.986Z
Learnt from: CR
Repo: PunGrumpy/logixlysia PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-12-21T17:02:32.986Z
Learning: Applies to **/*.{html,tsx,jsx,vue,svelte,astro} : Use semantic HTML and ARIA attributes for accessibility: provide meaningful alt text for images, use proper heading hierarchy, add labels for form inputs, include keyboard event handlers alongside mouse events, and use semantic elements

Applied to files:

  • apps/docs/app/(home)/components/playground/background.tsx
📚 Learning: 2025-12-21T17:02:32.986Z
Learnt from: CR
Repo: PunGrumpy/logixlysia PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-12-21T17:02:32.986Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Remove `console.log`, `debugger`, and `alert` statements from production code

Applied to files:

  • apps/docs/app/(home)/components/playground/index.tsx
🪛 LanguageTool
apps/docs/content/(docs)/configuration.mdx

[grammar] ~154-~154: Ensure spelling is correct
Context: ...assed to logger helpers is printed as tree lines under the main log line instead...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (11)
apps/docs/app/(home)/components/playground/background.tsx (1)

7-15: LGTM!

Good accessibility practices: aria-hidden on the decorative container with alt="" on the image correctly marks this as a decorative element that assistive technologies should ignore. The fill layout with sizes="100vw" is appropriate for a full-width background.

apps/docs/content/(docs)/configuration.mdx (1)

102-173: LGTM!

The documented defaults (slowThreshold: 500, verySlowThreshold: 1000, showContextTree: true, contextDepth: 1) accurately match the implementation in packages/logixlysia/src/logger/create-logger.ts. The placeholder descriptions are clear and consistent with the logger behavior.

packages/logixlysia/README.md (1)

25-36: LGTM!

The README example effectively showcases the new logging configuration options. The threshold values (slowThreshold: 500, verySlowThreshold: 1000) match the documented defaults, and startupMessageFormat: 'banner' correctly demonstrates the new banner feature.

apps/docs/content/features/formatting.mdx (2)

8-37: LGTM!

The placeholder documentation is comprehensive and accurately describes the new tokens ({icon}, {speed}, {service}, {statusText}, {context}). The color/TTY behavior notes for {icon} and duration thresholds are helpful for users.


96-121: LGTM!

The context tree documentation clearly explains the multi-line rendering behavior, tree branch formatting, and how to disable it with showContextTree: false. The example output effectively illustrates the expected format.

apps/docs/app/(home)/components/playground/index.tsx (6)

69-70: LGTM!

The threshold constants (SLOW_MS = 500, VERY_SLOW_MS = 1000) correctly match the logger defaults defined in packages/logixlysia/src/logger/create-logger.ts, ensuring the playground accurately visualizes the speed indicators.


80-103: LGTM!

The formatDurationMs function handles edge cases well (sub-millisecond precision, smart decimal rounding for seconds). The durationClass threshold logic correctly mirrors the logger's color scheme.


402-427: LGTM!

The ContextTree component correctly renders the tree branch characters (├─ and └─) matching the logger's context output format. The composite key using key-value-index is reasonable for this static demo data.


429-486: LGTM!

The LogBlock component cleanly separates the main log line from the context tree, with correct threshold logic for the ⚡ slow indicator. The visual hierarchy with the fox chip, method, pathname, status, and duration matches the logger output format well.


511-517: LGTM!

The composite key ensures uniqueness across repeated random log generation, which is important for the marquee animation effect.


535-545: LGTM!

The terminal header correctly uses aria-hidden on the decorative traffic-light dots, keeping them hidden from assistive technologies while maintaining the macOS-style visual appearance.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 22, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found.

@PunGrumpy PunGrumpy merged commit b92698a into main Mar 22, 2026
18 checks passed
@PunGrumpy PunGrumpy deleted the feat/logixlysia-rich-logging-banner branch March 22, 2026 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changeset 📏 An intent to release a set of packages config ⚙️ Configuration files docs 📃 Documentation files enhancement 💫 New feature or request source 🏠 Source code files test 🧪 Test files website 🌐 Website

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant