Skip to content

chore(repo): version packages - #493

Merged
HugoRCD merged 1 commit into
mainfrom
changeset-release/main
Aug 2, 2026
Merged

chore(repo): version packages#493
HugoRCD merged 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@evlog/cli@0.4.0

Minor Changes

  • #492 31e5084 Thanks @HugoRCD! - feat: add evlog agents — teach the AI agents working in a project how to use evlog. It writes a short, marker-delimited block of evlog conventions into AGENTS.md (one wide event per operation, grouped context via log.set(), createError({ why, fix, internal }) over bare throws, defineErrorCatalog() once an error repeats, log.audit() on sensitive actions, and what never gets logged) and creates a CLAUDE.md pointing at it with @AGENTS.md. The block names the request-logger accessor for the detected framework (useLogger(event) on Nuxt and Nitro, useLogger() from lib/evlog.ts on Next.js, req.context.log on TanStack Start) and falls back to a generic one when detection finds nothing, so the command is useful outside the four frameworks evlog map covers.

    The agent skills are installed by shelling out to npx skills add https://www.evlog.dev, the same way evlog init runs your package manager rather than unpacking a tarball itself. Each agent reads a different directory (.claude/skills, .agents/skills, .codex/skills, …) and the skills CLI already resolves them, symlinks a canonical copy, and supports a global scope — and since it keeps no manifest, a copy written behind its back would be a second one it could never update. Skills already installed, in any agent directory and either scope, are detected and left for npx skills update. --skills <a,b> narrows the selection, --global installs for every project, --no-skills writes the block with nothing spawned, --source points at another host, and --dry-run prints the plan. Interactive runs hand the terminal to the skills CLI so it can ask which agents to install for; non-interactive runs pass --yes so nothing blocks on a prompt nobody will answer.

    evlog init now offers the same step as its last question — the AGENTS.md and CLAUDE.md writes are planned alongside the wiring so there is still one plan and one confirmation, and the skills run next to the package-manager install. --no-agents skips it. The block never needs the network, so a skills failure is reported without costing the rest of the run.

    --source must be an http:/https: URL and --skills entries must be lowercase dashed names, both rejected with a catalog error before anything is spawned — on Windows the spawn needs a shell to resolve npx, so those values would otherwise reach a cmd.exe command line. If the skills install fails, the AGENTS.md block is rewritten without the pointer to a skill that is now known not to be on disk.

    Both flows report the skills step whether or not it did anything — in the plan, in the written report, and through clack in an interactive run — so "already installed" is never confusable with "forgot to do it".

    CliContext gains a home field, so the search for installed skills reads the home directory through the context like every other process.* value rather than calling os.homedir() directly.

Patch Changes

evlog@2.24.0

Minor Changes

  • #495 c739cf8 Thanks @HugoRCD! - feat: publish wide events on a node:diagnostics_channel

    New opt-in entry point evlog/diagnostics. Call enableDiagnosticsChannel() once at startup and every emitted wide event is published on the evlog.event channel:

    // server/plugins/evlog-diagnostics.ts
    import { enableDiagnosticsChannel } from "evlog/diagnostics";
    
    export default defineNitroPlugin(async () => {
      await enableDiagnosticsChannel();
    });

    A consumer then subscribes by channel name alone, with no evlog import and no entry in initLogger():

    import { subscribe } from "node:diagnostics_channel";
    
    subscribe("evlog.event", ({ event }) =>
      metrics.timing("http.request", event.durationMs),
    );

    subscribeToWideEvents() is exported for consumers that already depend on evlog and want the payload typed.

    Subscribers receive the same object drains receive — post-audit, post-redaction, post-enrich — and must treat it as read-only. They run synchronously and are not awaited: this is an observation side channel, not a transport. On Cloudflare, Workers forwards every channel message to a Tail Worker, so enabling it gets wide events out of an isolate with no drain and no waitUntil.

    Off by default, and free when off — node:diagnostics_channel is loaded lazily so it never enters the main bundle graph, and with the channel enabled but unsubscribed the emit path benchmarks identically to having it disabled.

  • #494 44705f7 Thanks @HugoRCD! - feat(core): expose durationMs as a number on the wide event

    Request loggers now write durationMs (a number, in milliseconds) next to the existing duration string. duration keeps its current shape — "12ms", "1.20s" — and is still what the pretty terminal renders; durationMs is the one to query. Backends stop needing a parse step: ClickHouse can avg() and quantile(0.95)() on a real column, LogQL can do | json | durationMs > 1000, and facet-based UIs get a numeric field instead of a string.

    The ClickHouse adapter's default toClickHouseRow() maps it to a new duration_ms column. Add it to an existing table before upgrading:

    ALTER TABLE evlog_events ADD COLUMN duration_ms Nullable(UInt32) AFTER duration;

    Durations are measured with a clamped elapsed helper, so a backward wall-clock step (NTP, manual change) during a request can no longer surface a negative durationMs, duration, or tail-sampling duration.

    BaseWideEvent now declares both fields, so event.durationMs is typed number | undefined in enrichers and drains. Code that read event.duration as a number was already wrong at runtime and will now fail to type-check — switch it to event.durationMs.

@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
evlog-docs Ready Ready Preview, v0 Aug 2, 2026 2:36pm
evlog-render-lab Ready Ready Preview Aug 2, 2026 2:36pm
evlog-telemetry Ready Ready Preview Aug 2, 2026 2:36pm
just-use-evlog Ready Ready Preview Aug 2, 2026 2:36pm

Request Review

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