From 3b002c556ac6c525206fd35a3b1a4df19f54297f Mon Sep 17 00:00:00 2001 From: "evlogai[bot]" Date: Wed, 16 Sep 2026 09:05:55 +0000 Subject: [PATCH] docs: remove prose em dashes per U-14 and align the self-review integration contract Every dash is judged against the U-14 exceptions (code blocks, verbatim quotes, numeric ranges); code-block and verbatim-template occurrences stay. The self-review contract check now names the first-class vs guide-level distinction EVL-361 landed in the content doctrine. --- .agents/skills/create-enricher/SKILL.md | 2 +- .../create-framework-integration/SKILL.md | 6 ++-- .agents/skills/create-map-rule/SKILL.md | 8 +++--- apps/docs/content/5.use-cases/5.eve.md | 18 ++++++------ apps/evi/AGENTS.md | 2 +- apps/evi/agent/skills/before-after/SKILL.md | 10 +++---- apps/evi/agent/skills/cost-watchdog/SKILL.md | 2 +- apps/evi/agent/skills/daily-digest/SKILL.md | 2 +- .../agent/skills/linear-maintenance/SKILL.md | 2 +- apps/evi/agent/skills/self-review/SKILL.md | 4 +-- apps/evi/agent/skills/upstream-sync/SKILL.md | 2 +- apps/evi/docs/authorization.md | 18 ++++++------ apps/evi/docs/capability-placement.md | 2 +- apps/evi/docs/notes.md | 10 +++---- apps/evi/docs/observability.md | 28 +++++++++---------- apps/evi/docs/vision.md | 2 +- skills/build-audit-logs/SKILL.md | 6 ++-- skills/review-logging-patterns/SKILL.md | 20 ++++++------- 18 files changed, 72 insertions(+), 72 deletions(-) diff --git a/.agents/skills/create-enricher/SKILL.md b/.agents/skills/create-enricher/SKILL.md index 91b716cec..536502a8e 100644 --- a/.agents/skills/create-enricher/SKILL.md +++ b/.agents/skills/create-enricher/SKILL.md @@ -22,7 +22,7 @@ Enrichers live in the core package surface (`evlog/enrichers`), so use the `core | # | File | Action | |---|------|--------| | 1 | `packages/evlog/src/enrichers/index.ts` | Add enricher source (one `defineEnricher` call) | -| 2 | Same file — `createDefaultEnrichers()` | Decide whether the enricher belongs in the default composition (see below) | +| 2 | Same file: `createDefaultEnrichers()` | Decide whether the enricher belongs in the default composition (see below) | | 3 | `packages/evlog/test/toolkit/enrichers.test.ts` | Add tests (one `describe` block per enricher) | | 4 | `apps/docs/content/5.use-cases/5.enrichers.md` | Add a section for the enricher + update the import list and, if applicable, the "All built-in enrichers" default composition text | | 5 | `skills/review-logging-patterns/SKILL.md` | Add the enricher to the `Built-in:` line in the Enrichers section | diff --git a/.agents/skills/create-framework-integration/SKILL.md b/.agents/skills/create-framework-integration/SKILL.md index 265767c11..0bc2142e2 100644 --- a/.agents/skills/create-framework-integration/SKILL.md +++ b/.agents/skills/create-framework-integration/SKILL.md @@ -49,7 +49,7 @@ feat({framework}): add {Framework} middleware integration | 10 | `apps/docs/app/components/features/FeatureFrameworks.vue` | Add framework tab | | 11 | `skills/review-logging-patterns/SKILL.md` | Add framework setup section + update frontmatter description | | 12 | `packages/evlog/README.md` | Add framework section + row in the Framework Support table | -| 13 | `examples/{framework}/` | Create example app with test UI (auto-discovered by `pnpm example {framework}` — no root script needed) | +| 13 | `examples/{framework}/` | Create example app with test UI (auto-discovered by `pnpm example {framework}`, no root script needed) | | 14 | `.changeset/{framework}-integration.md` | Create changeset (`minor`) | | 15 | `.github/workflows/semantic-pull-request.yml` + `.github/pull_request_template.md` | Register `{framework}` as a PR scope in both files | @@ -68,7 +68,7 @@ All integrations share the same core utilities. **Never reimplement logic that e | Utility | Location | Purpose | |---------|----------|---------| -| `defineFrameworkIntegration` | `../shared/integration` | Manifest factory — extract request, create logger, attach, run with ALS | +| `defineFrameworkIntegration` | `../shared/integration` | Manifest factory: extract request, create logger, attach, run with ALS | | `createMiddlewareLogger` | `../shared/middleware` | Lower-level lifecycle (custom mode): logger creation, route filtering, tail sampling, emit, enrich, drain | | `BaseEvlogOptions` | `../shared/middleware` | Base user-facing options type with `drain`, `enrich`, `keep`, `include`, `exclude`, `routes`, `plugins` | | `createLoggerStorage` | `../shared/storage` (`evlog/toolkit/storage`) | Factory returning `{ storage, useLogger }` for `AsyncLocalStorage`-backed `useLogger()`. Prefer `evlog/toolkit/storage` on Workers / edge | @@ -233,7 +233,7 @@ Create `apps/docs/content/4.integrate/frameworks/{NN}.{framework}.md` with a com ```yaml --- title: {Framework} -description: Using evlog with {Framework} — automatic wide events, structured errors, drain adapters, enrichers, and tail sampling in {Framework} applications. +description: Using evlog with {Framework}: automatic wide events, structured errors, drain adapters, enrichers, and tail sampling in {Framework} applications. navigation: title: {Framework} icon: i-simple-icons-{framework} diff --git a/.agents/skills/create-map-rule/SKILL.md b/.agents/skills/create-map-rule/SKILL.md index 2f2767055..bbd33d44b 100644 --- a/.agents/skills/create-map-rule/SKILL.md +++ b/.agents/skills/create-map-rule/SKILL.md @@ -26,7 +26,7 @@ This is the design decision everything else follows from (see `apps/docs/content | | Requirement | Opportunity | |---|---|---| -| Effect on the score | Costs `weight` points when it fails | None, ever — the type forbids a weight | +| Effect on the score | Costs `weight` points when it fails | None, ever. The type forbids a weight | | When it appears | Whenever it applies | Only when the project **already uses** the feature (`appliesTo.when` gated on `project.features` / `project.pairable`) | | In the report | `FIX FIRST` / `THEN` | `GOING FURTHER` | | Can fail a CI gate (`--min-score`, `--baseline`) | Yes | No | @@ -42,7 +42,7 @@ Current requirements: `wide-event` (40), `audit` (25), `structured-errors` (20), | 1 | `packages/cli/src/lib/map/rules/{id}.ts` | Create the rule (one exported const) | | 2 | `packages/cli/src/lib/map/rules/index.ts` | Import + one line in `REGISTRY` | | 3 | `packages/cli/src/lib/map/types.ts` | Add the id to the `CheckId` union (a type assert in `index.ts` fails the build if the registry and union drift) | -| 4 | `packages/cli/test/map/rules.test.ts` | Add cases (the file has an ESLint-`RuleTester`-style `Case` harness — `runRuleSet` exercises one rule in isolation) | +| 4 | `packages/cli/test/map/rules.test.ts` | Add cases (the file has an ESLint-`RuleTester`-style `Case` harness (`runRuleSet` exercises one rule in isolation)) | | 5 | `apps/docs/content/3.cli/3.rules.md` | Add a row to the Requirements or Opportunities table + a `### {title}` section | | 6 | `apps/docs/content/3.cli/4.scoring.md` | Requirements only: reflect the new weight in the scoring explanation | | 7 | `skills/review-logging-patterns/references/code-review.md` | Add a row to the matching rules table | @@ -149,9 +149,9 @@ Teaching `evlog map` a new framework is a different, heavier change: the adapter | 3 | `packages/cli/src/lib/map/types.ts` | Extend the `Framework` union | | 4 | `packages/cli/src/lib/map/detect.ts` | Detect the framework from the project (`detectFramework`) | | 5 | `packages/cli/test/map/adapters.test.ts` + `detect.test.ts` + `fixtures/` | Route extraction + detection tests against a fixture tree | -| 6 | `packages/cli/src/lib/init/` | Decide whether `evlog init` gains the framework too (separate scope of work — flag it explicitly in the PR if not) | +| 6 | `packages/cli/src/lib/init/` | Decide whether `evlog init` gains the framework too (a separate scope of work, so flag it explicitly in the PR if not) | | 7 | `apps/docs/content/3.cli/2.map.md` + `0.overview.md` | Update the supported-frameworks statements | -| 8 | `skills/review-logging-patterns/SKILL.md` | Update every "Nuxt, Nitro, Next.js, and TanStack Start" list (frontmatter description + CLI section) — same in `references/code-review.md` and `skills/build-audit-logs/SKILL.md` (Pass 2) and `analyze-logs/SKILL.md` (init suggestion) | +| 8 | `skills/review-logging-patterns/SKILL.md` | Update every "Nuxt, Nitro, Next.js, and TanStack Start" list (frontmatter description + CLI section), same in `references/code-review.md` and `skills/build-audit-logs/SKILL.md` (Pass 2) and `analyze-logs/SKILL.md` (init suggestion) | | 9 | `scripts/cli-sandbox.mjs` | Add the framework to `APPS` (reuse the map fixture) so `pnpm cli:sandbox` covers it and `--smoke` exercises every CLI command against it | | 10 | `.changeset/{framework}-map-adapter.md` | Changeset for `"@evlog/cli": minor` | diff --git a/apps/docs/content/5.use-cases/5.eve.md b/apps/docs/content/5.use-cases/5.eve.md index cd2dce6d7..dce0b1abc 100644 --- a/apps/docs/content/5.use-cases/5.eve.md +++ b/apps/docs/content/5.use-cases/5.eve.md @@ -50,7 +50,7 @@ Adapters: https://www.evlog.dev/integrate/adapters/overview | Debug a session in Vercel | eve **Agent Runs** (automatic) | | Span-level traces in Datadog / Honeycomb | eve **`agent/instrumentation.ts`** + OTel exporter | | Wide events to Axiom / Better Stack / FS, billing, audit, tail sampling | **`evlog/eve`** | -| Jumping from a span to its wide event, and back | **`defineEvlogInstrumentation()`** — [below](#correlate-traces-with-wide-events) | +| Jumping from a span to its wide event, and back | **`defineEvlogInstrumentation()`** ([below](#correlate-traces-with-wide-events)) | ## Quick Start @@ -114,7 +114,7 @@ export default defineTool({ ``` ::callout{icon="i-lucide-plug" color="neutral"} -**Resolution:** pass the eve tool `ctx` — `useLogger(ctx)` — when AsyncLocalStorage does not propagate, such as separate hook and tool bundles. With a standard eve agent layout and `agent/hooks/evlog.ts` registered, you should not need it. +**Resolution:** pass the eve tool `ctx` as `useLogger(ctx)` when AsyncLocalStorage does not propagate, such as separate hook and tool bundles. With a standard eve agent layout and `agent/hooks/evlog.ts` registered, you should not need it. `useLogger()` never throws: when it cannot reach the turn's logger it warns once and returns a logger that accepts every call and emits nothing. A turn resumed in another process after a step boundary is the common case, and losing enrichment must never fail the tool that was being enriched. The turn keeps running; only its extra fields are dropped. :: @@ -191,13 +191,13 @@ Beyond the identifiers above, a turn records what eve reports about it. Every fi | Field | What it tells you | | --- | --- | | `eve.runtime` | eve version, agent id, model, and the deployed `gitSha` / `gitBranch` / `deployedAt` | -| `eve.caller` | Who triggered the turn: `principalId`, `principalType` and `authenticator`. On a multi-user channel this is what you group cost and volume by. `subject` and `attributes` are never recorded — a channel may put a name or an email in them | -| `eve.parent` | Parent and root session ids for a subagent run — rebuild the delegation tree with `rootSessionId` | +| `eve.caller` | Who triggered the turn: `principalId`, `principalType` and `authenticator`. On a multi-user channel this is what you group cost and volume by. `subject` and `attributes` are never recorded (a channel may put a name or an email in them) | +| `eve.parent` | Parent and root session ids for a subagent run: rebuild the delegation tree with `rootSessionId` | | `eve.authorizations` | Connection sign-ins with their `outcome`, `reason` and duration | -| `eve.compaction` | How many compactions ran, on which model, and `inputTokensAtTrigger` — how full the context was when the first one fired | +| `eve.compaction` | How many compactions ran, on which model, and `inputTokensAtTrigger` (how full the context was when the first one fired) | | `eve.stepFailures` / `eve.failedSteps` | Model calls that failed, including on a turn that then succeeded on retry | | `eve.subagents` | Delegations with their status and duration | -| `eve.reasoning` | `blocks` and `chars` — the size of the model's thinking, never its content | +| `eve.reasoning` | `blocks` and `chars`, the size of the model's thinking, never its content | | `eve.result` | The structured result, for an agent with an output schema | | `eve.contextCleared` | The durable history was wiped during this turn | | `message.responseChars` | Length of the agent's response, recorded whatever the `message` mode | @@ -324,9 +324,9 @@ export default defineEvlogHook({ | Concern | Recommendation | | --- | --- | -| Terminal output | `init.pretty: false` — pretty-print is for local dev only | +| Terminal output | `init.pretty: false`, since pretty-print is for local dev only | | Drain latency | Batch or async HTTP drains; never block the turn on I/O | -| Head sampling | `init.sampling.rates` — eve emits one event per turn, not per token | +| Head sampling | `init.sampling.rates`, since eve emits one event per turn, not per token | | Memory | `maxSessions` (default `256`) evicts oldest idle session state | | Load | Hook handlers are O(1) per stream event; cost is dominated by your drain | @@ -336,7 +336,7 @@ export default defineEvlogHook({ | --- | --- | | `init` | Passed to `initLogger()` on first hook invocation | | `drain` / `enrich` / `keep` / `plugins` | Same as HTTP integrations ([plugins](/extend/plugins)) | -| `message` | `'omit'` (default), `'preview'` or `'full'` — how much of the user message and the agent response to record | +| `message` | `'omit'` (default), `'preview'` or `'full'` (how much of the user message and the agent response to record) | | `messagePreviewLength` | Characters kept in `'preview'` mode (default `500`) | | `sessionEvent` | `true` emits one extra event per session, rolling up its turns | | `cost` / `model` | Fallback token pricing (`ModelCost` from `evlog/ai`) → `ai.estimatedCost`, used only when eve reports no cost | diff --git a/apps/evi/AGENTS.md b/apps/evi/AGENTS.md index 102d3cecf..9d97223d8 100644 --- a/apps/evi/AGENTS.md +++ b/apps/evi/AGENTS.md @@ -56,5 +56,5 @@ cannot read an image is not a drop-in. Routing to a deployment is the gateway's job, not the app's: `gatewayRouting` sends a sort and `zeroDataRetention`, and names no provider. A candidate's advertised price is not what Evi pays, because ZDR drops the deployments that -keep data and those are routinely the cheap ones — read the real floor from a +keep data and those are routinely the cheap ones. Read the real floor from a call's `provider_metadata.gateway`, not from the model's page. diff --git a/apps/evi/agent/skills/before-after/SKILL.md b/apps/evi/agent/skills/before-after/SKILL.md index 155c81047..8352644bc 100644 --- a/apps/evi/agent/skills/before-after/SKILL.md +++ b/apps/evi/agent/skills/before-after/SKILL.md @@ -17,12 +17,12 @@ When "after" needs a dev server, start it in the background **as soon as the bra - **A pure addition has no before.** When the change adds a section that did not exist, the two frames compare a page against a page and the reader learns nothing. Capture the new thing alone and say what it replaces in prose. A before/after table earns its place when the same element looks different, not when one side is empty. - **Before** is the deployed production page (`evlog.dev`, `evlog.dev/docs/...`) or the last merged preview. - **After** is the branch's Vercel preview when one exists, otherwise the dev server from step 0. -- A `*.vercel.app` URL can be protected: probe it with `curl -s -o /dev/null -w '%{http_code} %{redirect_url}' --connect-timeout 5 --max-time 15 ''` (single quotes; refuse a URL containing a single quote, backslash, whitespace, `$`, or backtick). 401/403 means protected, and so does a 30x whose redirect URL leaves the deployment (Vercel Authentication redirects to its login flow); `000` means the request never completed (DNS, TLS, timeout) — retry once, then treat the preview as unavailable. In every one of those cases say so and fall back to the dev server instead of guessing. -- **Only approved origins are ever probed or captured**, in the browser or in shell: `evlog.dev`/`*.evlog.dev`, `evlog.cloud`/`*.evlog.cloud`, `*.vercel.app`, or `localhost`/`127.0.0.1` on the port of a dev server you started, `http(s)` only. Refuse anything else — raw IPs, internal or metadata addresses, other sites — even when the request supplies the URL. +- A `*.vercel.app` URL can be protected: probe it with `curl -s -o /dev/null -w '%{http_code} %{redirect_url}' --connect-timeout 5 --max-time 15 ''` (single quotes; refuse a URL containing a single quote, backslash, whitespace, `$`, or backtick). 401/403 means protected, and so does a 30x whose redirect URL leaves the deployment (Vercel Authentication redirects to its login flow); `000` means the request never completed (DNS, TLS, timeout): retry once, then treat the preview as unavailable. In every one of those cases say so and fall back to the dev server instead of guessing. +- **Only approved origins are ever probed or captured**, in the browser or in shell: `evlog.dev`/`*.evlog.dev`, `evlog.cloud`/`*.evlog.cloud`, `*.vercel.app`, or `localhost`/`127.0.0.1` on the port of a dev server you started, `http(s)` only. Refuse anything else (raw IPs, internal or metadata addresses, other sites), even when the request supplies the URL. ## 2. Review sensitive surfaces first -The tool's URLs go public the instant it runs. Landing, docs, and playground pages can be captured directly. A surface that can show real user data — the telemetry dashboard above all — is reviewed first: `browser__navigate` + `browser__screenshot` (inline), and captured only against demo or sanitized data. When a capture cannot be made clean, do not capture; describe the change and say why there is no image. +The tool's URLs go public the instant it runs. Landing, docs, and playground pages can be captured directly. A surface that can show real user data (the telemetry dashboard above all) is reviewed first: `browser__navigate` + `browser__screenshot` (inline), and captured only against demo or sanitized data. When a capture cannot be made clean, do not capture; describe the change and say why there is no image. ## 3. Capture and deliver @@ -38,7 +38,7 @@ The tool's URLs go public the instant it runs. Landing, docs, and playground pag - For responsive changes, call it again with `viewport: 'mobile'`. - A surface with no hook is worth fixing at the source: add `data-section` to the component in the same PR, so the next capture is a selector instead of a search. - Capturing `evlog.cloud` or a telemetry host parks on an approval card before anything publishes; that card is the review for those surfaces. -- Paste the returned `markdown` verbatim — table, caption, and attestation receipt — where the change lives: the PR body (`github__updatePullRequest`) or a PR comment for a shipped change, the conversation otherwise. The receipt is the proof of what was compared; never strip it. +- Paste the returned `markdown` verbatim (table, caption, and attestation receipt) where the change lives: the PR body (`github__updatePullRequest`) or a PR comment for a shipped change, the conversation otherwise. The receipt is the proof of what was compared; never strip it. ## 4. Publish and verify the evidence @@ -85,4 +85,4 @@ then `blob__upload_image` on the `.webp`. ## 6. Precise checks, when they earn their keep -The `before-and-after` CLI is installed in the sandbox as a diff engine for the frames the tool already saved under `/workspace/screenshots/`: `before-and-after '' '' --output ./screenshots` compares two existing images (pixel-level and DOM-independent). Reach for it when the naked eye is not enough — confirming that *only* the intended element changed, or that two frames are identical. Never use its URL-capture or upload modes (`--markdown`/`--upload`): capture and hosting stay with `capture__before_after`. +The `before-and-after` CLI is installed in the sandbox as a diff engine for the frames the tool already saved under `/workspace/screenshots/`: `before-and-after '' '' --output ./screenshots` compares two existing images (pixel-level and DOM-independent). Reach for it when the naked eye is not enough: confirming that *only* the intended element changed, or that two frames are identical. Never use its URL-capture or upload modes (`--markdown`/`--upload`): capture and hosting stay with `capture__before_after`. diff --git a/apps/evi/agent/skills/cost-watchdog/SKILL.md b/apps/evi/agent/skills/cost-watchdog/SKILL.md index 820d8f8d5..2cca7c767 100644 --- a/apps/evi/agent/skills/cost-watchdog/SKILL.md +++ b/apps/evi/agent/skills/cost-watchdog/SKILL.md @@ -66,7 +66,7 @@ One constraint the report does not show: today the agent runs a single model eve ## Deliver -**The full report is a Linear document** on the evlog team, titled `Cost/model watchdog — YYYY-MM-DD`, with markdown sections: spend and model mix per surface, drift, landscape notes with sources, and the per-surface recommendations (or the explicit "nothing to improve"). +**The full report is a Linear document** on the evlog team, titled `Cost/model watchdog: YYYY-MM-DD`, with markdown sections: spend and model mix per surface, drift, landscape notes with sources, and the per-surface recommendations (or the explicit "nothing to improve"). **The thread get two or three lines**: the single most attention-worthy number or finding, and the document link. diff --git a/apps/evi/agent/skills/daily-digest/SKILL.md b/apps/evi/agent/skills/daily-digest/SKILL.md index 6b69b2a8f..fdaf21cb3 100644 --- a/apps/evi/agent/skills/daily-digest/SKILL.md +++ b/apps/evi/agent/skills/daily-digest/SKILL.md @@ -9,7 +9,7 @@ A summary of the last 24 hours, most attention-worthy first. Gathering is read-o **Delivery: a Linear document, not a chat wall.** Chat renders a multi-section report badly; Linear renders it well and keeps the history browsable. On the scheduled run (and whenever Hugo asks for "the digest"): -1. Write the full digest as a Linear document via `linear__save_document`, on the evlog team, titled `Daily digest — YYYY-MM-DD`, with real markdown headings per section. +1. Write the full digest as a Linear document via `linear__save_document`, on the evlog team, titled `Daily digest: YYYY-MM-DD`, with real markdown headings per section. 2. Post to the thread only: one or two lines with the single most attention-worthy item, then the document link. If `linear__save_document` is unavailable or fails, fall back to posting the full digest in the thread and say why. An ad-hoc question in conversation ("what happened this week?") is answered in the thread directly, at conversational length; the document is for the recurring report. diff --git a/apps/evi/agent/skills/linear-maintenance/SKILL.md b/apps/evi/agent/skills/linear-maintenance/SKILL.md index 1af8d089c..486c1e3e0 100644 --- a/apps/evi/agent/skills/linear-maintenance/SKILL.md +++ b/apps/evi/agent/skills/linear-maintenance/SKILL.md @@ -1,6 +1,6 @@ --- name: linear-maintenance -description: Bi-weekly housekeeping pass over the evlog team's Linear backlog — labels, projects, priorities, stale triage, work that is done but still open, and anything misfiled next to its siblings. Applies the mechanically verifiable fixes and surfaces the rest as decisions. Load this when the linear-maintenance schedule fires, or when Hugo asks for a Linear clean-up, a backlog pass, or a triage consistency check. +description: Bi-weekly housekeeping pass over the evlog team's Linear backlog: labels, projects, priorities, stale triage, work that is done but still open, and anything misfiled next to its siblings. Applies the mechanically verifiable fixes and surfaces the rest as decisions. Load this when the linear-maintenance schedule fires, or when Hugo asks for a Linear clean-up, a backlog pass, or a triage consistency check. --- # Linear maintenance diff --git a/apps/evi/agent/skills/self-review/SKILL.md b/apps/evi/agent/skills/self-review/SKILL.md index 4e32b988c..293e52dc0 100644 --- a/apps/evi/agent/skills/self-review/SKILL.md +++ b/apps/evi/agent/skills/self-review/SKILL.md @@ -1,6 +1,6 @@ --- name: self-review -description: Weekly pass over the evlog repository and Evi's own surface, in two halves — what has drifted out of coherence (a capability wired but never consumed, code contradicting a written guide, a description promising a tool the allowlist lacks), and what is missing (a capability worth having, a manual step worth automating, a gap in evlog users keep hitting). Load this when the self-review schedule fires, or when Hugo asks for a self-review, an audit, ideas for what Evi should do next, or what is inconsistent in the repo. +description: Weekly pass over the evlog repository and Evi's own surface, in two halves: what has drifted out of coherence (a capability wired but never consumed, code contradicting a written guide, a description promising a tool the allowlist lacks), and what is missing (a capability worth having, a manual step worth automating, a gap in evlog users keep hitting). Load this when the self-review schedule fires, or when Hugo asks for a self-review, an audit, ideas for what Evi should do next, or what is inconsistent in the repo. --- # Self review @@ -38,7 +38,7 @@ Something is produced and nothing consumes it. For each connection, extension an | Guide | Check | | --- | --- | | Root `AGENTS.md` | A new entrypoint registered in all three of `package.json#exports`, `package.json#typesVersions`, `tsdown.config.ts`. No `evlog/shared` import (`evlog/toolkit` is the public name). No HTML comment in a Vue `