docs: add noridocs for all source directories#9
Conversation
Add docs.md files to all source directories documenting architecture, system invariants, and implementation details. Fix installDebugHelpers JSDoc that incorrectly claimed it checks import.meta.env.DEV. 🤖 Generated with [Nori](https://nori.ai) Co-Authored-By: Nori <contact@tilework.tech>
WalkthroughAdds comprehensive documentation across the repository and test suite, deletes the CommonJS TypeScript config, adjusts packaging ignore rules, and changes the debug helper installer to require a browser and Changes
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. No actionable comments were generated in the recent review. 🎉 Comment |
🤖 Generated with [Nori](https://nori.ai) Co-Authored-By: Nori <contact@tilework.tech>
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Fix all issues with AI agents
In `@__tests__/docs.md`:
- Around line 5-29: The Markdown uses multiple H3 headings (e.g., "Overview",
"How it fits into the larger codebase", "Core Implementation", "Things to Know")
which triggers MD001; change the heading hierarchy so the document starts with a
single H1 title and demote those H3s to H2 (or H3 as appropriate under a new
H1), ensuring each subsequent section level increments correctly (H1 -> H2 ->
H3) so headings like "Overview" become H2 and nested subsections remain H3.
In `@src/config/docs.md`:
- Around line 5-31: The doc uses multiple same-level H3 headings which triggers
MD001; adjust the heading hierarchy so the top-level title is H1 and the major
sections use H2. Specifically, change "### Overview" to "# Overview" (or add a
top-level title above it) and change the other "###" headings ("How it fits into
the larger codebase", "Core Implementation", "Things to Know") to "##" so
headings increment correctly and avoid MD001 warnings.
In `@src/core/docs.md`:
- Around line 5-39: Update the Markdown to fix MD001/MD040 by adjusting heading
levels (change any incorrect "### Things to Know" style headings to top-level
section headers like "## Things to Know" to match document structure) and add a
language identifier to the existing code fence (replace the opening ``` with a
language-tagged fence such as ```text) in the code block under "Core
Implementation" so the linter recognizes the fence language.
In `@src/debug/docs.md`:
- Around line 5-30: Update the markdown heading levels so H2 is used instead of
H3 to avoid MD001 warnings: change the headings "Overview", "How it fits into
the larger codebase", "Core Implementation", and "Things to Know" from ### to ##
in src/debug/docs.md (leave the H1 intact and ensure subsections beneath those
remain correctly nested); no code changes required—just adjust the markdown
heading markers.
In `@src/docs.md`:
- Around line 5-46: Change the markdown heading level "### Things to Know" to
"## Things to Know" and add a language identifier to the code fence shown in the
suggested fix (replace ```text with a proper language marker like ```md or
```text as chosen) so heading hierarchy is corrected and the fenced block has an
explicit language; target the literal heading line "### Things to Know" and the
opening code fence token in the diff for this change.
In `@src/react/docs.md`:
- Around line 5-43: Change the "### Things to Know" heading in src/react/docs.md
to a level-2 heading ("## Things to Know") and update any plain code fences in
the file to include a language token (e.g., use ```text instead of ```) so
syntax/formatting is explicit; locate the "Things to Know" heading and the
surrounding fenced block(s) and adjust their marker lines accordingly.
In `@src/types/docs.md`:
- Around line 5-31: The markdown uses third-level headings (### Overview, ###
How it fits into the larger codebase, ### Core Implementation, ### Things to
Know) which triggers MD001 about heading hierarchy; change the heading levels so
they increment properly (e.g., promote each "###" to "##" or add a top-level H1
before them) so the document starts with a level-1/level-2 heading and
subsequent sections use level-2 headings; update the headings "Overview", "How
it fits into the larger codebase", "Core Implementation", and "Things to Know"
accordingly to restore a correct heading hierarchy.
| ### Overview | ||
|
|
||
| - Test suite for the library, mirroring the `@/src` directory structure with subdirectories for `config/`, `core/`, and `react/`. | ||
| - Uses vitest with jsdom environment, `@testing-library/react` for React component/hook tests, and a global setup file for browser API mocks. | ||
| - Coverage thresholds are enforced at 80% for statements, branches, functions, and lines (configured in `@/vitest.config.ts`). | ||
|
|
||
| ### How it fits into the larger codebase | ||
|
|
||
| - Tests exercise all public API surfaces from `@/src/core`, `@/src/config`, and `@/src/react`. | ||
| - Coverage excludes barrel `index.ts` files and the `@/src/types` directory, since these contain only re-exports and type definitions. | ||
| - The test setup (`setup.ts`) provides the mock environment that all tests rely on: a sessionStorage mock backed by a plain object with `vi.fn()` wrappers, and a `window.location` mock defaulting to `https://example.com`. | ||
| - CI runs tests across Node 18, 20, and 22. | ||
|
|
||
| ### Core Implementation | ||
|
|
||
| - **`setup.ts`**: Creates a fresh sessionStorage mock and location mock in `beforeEach`, ensuring tests are isolated. The storage mock implements `getItem`, `setItem`, `removeItem`, `clear`, `length`, and `key`. Location is stubbed with `href`, `search`, `hash`, `pathname`, `protocol`, `host`, and `hostname`. | ||
| - **`core/` tests**: Cover capture (URL parsing, allowed parameters, key format conversion, SSR fallback), storage (write/read/clear, format conversion, validation of stored data, silent failure), appender (query/fragment placement, preserveExisting, remove, extract), keys (bidirectional conversion, standard and custom keys, detection, validation), and validator (protocol, domain, normalization, mutable default protocol). | ||
| - **`config/` tests**: Cover `createConfig` merging semantics (nullish coalescing, array replacement, object merge), `validateConfig` error messages, and `loadConfigFromJson` fallback behavior. | ||
| - **`react/` tests**: Use `@testing-library/react` `renderHook` and `render` to test `useUtmTracking` (auto-capture, manual capture, clear, appendToUrl with share context and exclusions) and `UtmProvider`/`useUtmContext` (context propagation, error on missing provider). | ||
|
|
||
| ### Things to Know | ||
|
|
||
| - The sessionStorage mock uses `vi.fn()` wrappers, which means tests can assert on call counts and arguments (`sessionStorage.setItem` calls, etc.). | ||
| - `window.location` is stubbed globally rather than using JSDOM's location, so tests that need specific URLs must override `location.href` and `location.search` in their setup. | ||
| - The `beforeEach` in `setup.ts` resets both mocks, so each test starts with empty storage and a clean `https://example.com` location. |
There was a problem hiding this comment.
Align heading hierarchy to avoid MD001 warnings.
Suggested fix
-### Overview
+## Overview
@@
-### How it fits into the larger codebase
+## How it fits into the larger codebase
@@
-### Core Implementation
+## Core Implementation
@@
-### Things to Know
+## Things to Know🧰 Tools
🪛 LanguageTool
[uncategorized] ~20-~20: Loose punctuation mark.
Context: ...## Core Implementation - setup.ts: Creates a fresh sessionStorage mock and...
(UNLIKELY_OPENING_PUNCTUATION)
[style] ~23-~23: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...omJson fallback behavior. - **react/tests**: Use@testing-library/react render...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.20.0)
[warning] 5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
[warning] 20-20: Strong style
Expected: underscore; Actual: asterisk
(MD050, strong-style)
[warning] 20-20: Strong style
Expected: underscore; Actual: asterisk
(MD050, strong-style)
[warning] 21-21: Strong style
Expected: underscore; Actual: asterisk
(MD050, strong-style)
[warning] 21-21: Strong style
Expected: underscore; Actual: asterisk
(MD050, strong-style)
[warning] 22-22: Strong style
Expected: underscore; Actual: asterisk
(MD050, strong-style)
[warning] 22-22: Strong style
Expected: underscore; Actual: asterisk
(MD050, strong-style)
[warning] 23-23: Strong style
Expected: underscore; Actual: asterisk
(MD050, strong-style)
[warning] 23-23: Strong style
Expected: underscore; Actual: asterisk
(MD050, strong-style)
🤖 Prompt for AI Agents
In `@__tests__/docs.md` around lines 5 - 29, The Markdown uses multiple H3
headings (e.g., "Overview", "How it fits into the larger codebase", "Core
Implementation", "Things to Know") which triggers MD001; change the heading
hierarchy so the document starts with a single H1 title and demote those H3s to
H2 (or H3 as appropriate under a new H1), ensuring each subsequent section level
increments correctly (H1 -> H2 -> H3) so headings like "Overview" become H2 and
nested subsections remain H3.
| ### Overview | ||
|
|
||
| - Defines default configuration values and provides utilities for creating, merging, and validating configuration objects. | ||
| - Produces `ResolvedUtmConfig` objects (all fields required) from partial `UtmConfig` input, establishing the configuration contract for the rest of the library. | ||
| - Re-exported through `@/src/index.ts` and consumed directly by `@/src/react/useUtmTracking.ts` and `@/src/debug`. | ||
|
|
||
| ### How it fits into the larger codebase | ||
|
|
||
| - `createConfig()` is the primary entry point, called by `useUtmTracking` in `@/src/react` to resolve user-provided partial config into a complete `ResolvedUtmConfig`. | ||
| - `@/src/debug` imports `getDefaultConfig()` from here as a fallback when no config is provided to diagnostic functions. | ||
| - `DEFAULT_CONFIG` and `STANDARD_UTM_PARAMETERS` are the canonical definitions of default behavior (enabled, snake_case, sessionStorage key `utm_parameters`, auto-capture on mount, append to shares, the 6 standard UTM params). | ||
| - The config system does not perform side effects -- it is pure data transformation. | ||
|
|
||
| ### Core Implementation | ||
|
|
||
| - `createConfig()` merges a partial user config with defaults using nullish coalescing (`??`) for scalar fields. Array fields (`allowedParameters`, `excludeFromShares`) are replaced wholesale when provided by the user, not merged. Object fields (`defaultParams`, `shareContextParams`) are shallow-merged. | ||
| - `mergeConfig()` follows the same semantics but takes a `ResolvedUtmConfig` as the base instead of implicitly using defaults -- useful for layering configurations. | ||
| - `loadConfigFromJson()` accepts `unknown` input, validates it is a non-null non-array object, then delegates to `createConfig()`. Invalid input falls back to defaults with a `console.warn`. | ||
| - `validateConfig()` performs runtime type checking on each config field and returns an array of error message strings (empty array means valid). | ||
| - `getDefaultConfig()` returns a shallow copy of `DEFAULT_CONFIG` with cloned arrays and objects to prevent mutation of the shared constant. | ||
|
|
||
| ### Things to Know | ||
|
|
||
| - Array replacement (not merge) for `allowedParameters` is intentional: if a consumer provides `allowedParameters: ['utm_source']`, they get only that parameter, not the union with defaults. This is a deliberate design choice. | ||
| - `STANDARD_UTM_PARAMETERS` is declared `as const` and used both as the default `allowedParameters` value and as the source of truth in tests. It defines the 6 standard UTM params: source, medium, campaign, term, content, id. | ||
| - `validateConfig()` and `createConfig()` are independent -- `createConfig()` does not call `validateConfig()`. Validation is opt-in for consumers who want to check config before using it. | ||
|
|
There was a problem hiding this comment.
Align heading hierarchy to avoid MD001 warnings.
Suggested fix
-### Overview
+## Overview
@@
-### How it fits into the larger codebase
+## How it fits into the larger codebase
@@
-### Core Implementation
+## Core Implementation
@@
-### Things to Know
+## Things to Know📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### Overview | |
| - Defines default configuration values and provides utilities for creating, merging, and validating configuration objects. | |
| - Produces `ResolvedUtmConfig` objects (all fields required) from partial `UtmConfig` input, establishing the configuration contract for the rest of the library. | |
| - Re-exported through `@/src/index.ts` and consumed directly by `@/src/react/useUtmTracking.ts` and `@/src/debug`. | |
| ### How it fits into the larger codebase | |
| - `createConfig()` is the primary entry point, called by `useUtmTracking` in `@/src/react` to resolve user-provided partial config into a complete `ResolvedUtmConfig`. | |
| - `@/src/debug` imports `getDefaultConfig()` from here as a fallback when no config is provided to diagnostic functions. | |
| - `DEFAULT_CONFIG` and `STANDARD_UTM_PARAMETERS` are the canonical definitions of default behavior (enabled, snake_case, sessionStorage key `utm_parameters`, auto-capture on mount, append to shares, the 6 standard UTM params). | |
| - The config system does not perform side effects -- it is pure data transformation. | |
| ### Core Implementation | |
| - `createConfig()` merges a partial user config with defaults using nullish coalescing (`??`) for scalar fields. Array fields (`allowedParameters`, `excludeFromShares`) are replaced wholesale when provided by the user, not merged. Object fields (`defaultParams`, `shareContextParams`) are shallow-merged. | |
| - `mergeConfig()` follows the same semantics but takes a `ResolvedUtmConfig` as the base instead of implicitly using defaults -- useful for layering configurations. | |
| - `loadConfigFromJson()` accepts `unknown` input, validates it is a non-null non-array object, then delegates to `createConfig()`. Invalid input falls back to defaults with a `console.warn`. | |
| - `validateConfig()` performs runtime type checking on each config field and returns an array of error message strings (empty array means valid). | |
| - `getDefaultConfig()` returns a shallow copy of `DEFAULT_CONFIG` with cloned arrays and objects to prevent mutation of the shared constant. | |
| ### Things to Know | |
| - Array replacement (not merge) for `allowedParameters` is intentional: if a consumer provides `allowedParameters: ['utm_source']`, they get only that parameter, not the union with defaults. This is a deliberate design choice. | |
| - `STANDARD_UTM_PARAMETERS` is declared `as const` and used both as the default `allowedParameters` value and as the source of truth in tests. It defines the 6 standard UTM params: source, medium, campaign, term, content, id. | |
| - `validateConfig()` and `createConfig()` are independent -- `createConfig()` does not call `validateConfig()`. Validation is opt-in for consumers who want to check config before using it. | |
| ## Overview | |
| - Defines default configuration values and provides utilities for creating, merging, and validating configuration objects. | |
| - Produces `ResolvedUtmConfig` objects (all fields required) from partial `UtmConfig` input, establishing the configuration contract for the rest of the library. | |
| - Re-exported through `@/src/index.ts` and consumed directly by `@/src/react/useUtmTracking.ts` and `@/src/debug`. | |
| ## How it fits into the larger codebase | |
| - `createConfig()` is the primary entry point, called by `useUtmTracking` in `@/src/react` to resolve user-provided partial config into a complete `ResolvedUtmConfig`. | |
| - `@/src/debug` imports `getDefaultConfig()` from here as a fallback when no config is provided to diagnostic functions. | |
| - `DEFAULT_CONFIG` and `STANDARD_UTM_PARAMETERS` are the canonical definitions of default behavior (enabled, snake_case, sessionStorage key `utm_parameters`, auto-capture on mount, append to shares, the 6 standard UTM params). | |
| - The config system does not perform side effects -- it is pure data transformation. | |
| ## Core Implementation | |
| - `createConfig()` merges a partial user config with defaults using nullish coalescing (`??`) for scalar fields. Array fields (`allowedParameters`, `excludeFromShares`) are replaced wholesale when provided by the user, not merged. Object fields (`defaultParams`, `shareContextParams`) are shallow-merged. | |
| - `mergeConfig()` follows the same semantics but takes a `ResolvedUtmConfig` as the base instead of implicitly using defaults -- useful for layering configurations. | |
| - `loadConfigFromJson()` accepts `unknown` input, validates it is a non-null non-array object, then delegates to `createConfig()`. Invalid input falls back to defaults with a `console.warn`. | |
| - `validateConfig()` performs runtime type checking on each config field and returns an array of error message strings (empty array means valid). | |
| - `getDefaultConfig()` returns a shallow copy of `DEFAULT_CONFIG` with cloned arrays and objects to prevent mutation of the shared constant. | |
| ## Things to Know | |
| - Array replacement (not merge) for `allowedParameters` is intentional: if a consumer provides `allowedParameters: ['utm_source']`, they get only that parameter, not the union with defaults. This is a deliberate design choice. | |
| - `STANDARD_UTM_PARAMETERS` is declared `as const` and used both as the default `allowedParameters` value and as the source of truth in tests. It defines the 6 standard UTM params: source, medium, campaign, term, content, id. | |
| - `validateConfig()` and `createConfig()` are independent -- `createConfig()` does not call `validateConfig()`. Validation is opt-in for consumers who want to check config before using it. |
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
🤖 Prompt for AI Agents
In `@src/config/docs.md` around lines 5 - 31, The doc uses multiple same-level H3
headings which triggers MD001; adjust the heading hierarchy so the top-level
title is H1 and the major sections use H2. Specifically, change "### Overview"
to "# Overview" (or add a top-level title above it) and change the other "###"
headings ("How it fits into the larger codebase", "Core Implementation", "Things
to Know") to "##" so headings increment correctly and avoid MD001 warnings.
| ### Overview | ||
|
|
||
| - Framework-agnostic core logic for capturing UTM parameters from URLs, persisting them in sessionStorage, appending them to outbound URLs, converting between key formats, and validating URLs. | ||
| - This is the heart of the library. Every other module (`@/src/react`, `@/src/debug`) builds on top of these utilities. | ||
| - All functions are SSR-safe, returning empty/null/unchanged values when browser APIs are unavailable. | ||
|
|
||
| ### How it fits into the larger codebase | ||
|
|
||
| - `@/src/react/useUtmTracking.ts` orchestrates the core modules: it calls `captureUtmParameters` on mount, `storeUtmParameters`/`getStoredUtmParameters` for persistence, `appendUtmParameters` for URL generation, and `convertParams`/`isSnakeCaseUtmKey` for format handling. | ||
| - `@/src/debug` imports from `capture` and `storage` to assemble diagnostic snapshots. | ||
| - `@/src/index.ts` re-exports everything from this module for direct consumer use without React. | ||
| - All modules import types from `@/src/types`. | ||
|
|
||
| ### Core Implementation | ||
|
|
||
| The data flow through the core modules follows this path: | ||
|
|
||
| ``` | ||
| URL string | ||
| | | ||
| v | ||
| [capture.ts] -- parses URL, filters to utm_* keys, applies allowedParameters, converts key format | ||
| | | ||
| v | ||
| UtmParameters object | ||
| | | ||
| v | ||
| [storage.ts] -- serializes to JSON, writes/reads sessionStorage, validates on read | ||
| | | ||
| v | ||
| [appender.ts] -- converts params to snake_case, merges into target URL query/fragment | ||
| | | ||
| v | ||
| URL string with UTM params | ||
| ``` |
There was a problem hiding this comment.
Fix heading levels and add a code‑fence language.
MD001 and MD040 are both triggered here.
Suggested fix
-### Overview
+## Overview
@@
-### How it fits into the larger codebase
+## How it fits into the larger codebase
@@
-### Core Implementation
+## Core Implementation
@@
-```
+```text
@@
-### Things to Know
+## Things to Know🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
[warning] 22-22: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
In `@src/core/docs.md` around lines 5 - 39, Update the Markdown to fix MD001/MD040
by adjusting heading levels (change any incorrect "### Things to Know" style
headings to top-level section headers like "## Things to Know" to match document
structure) and add a language identifier to the existing code fence (replace the
opening ``` with a language-tagged fence such as ```text) in the code block
under "Core Implementation" so the linter recognizes the fence language.
| ### Overview | ||
|
|
||
| - Development-time diagnostic utilities for inspecting UTM tracking state (config, URL params, stored params, storage availability). | ||
| - Provides console-formatted output, status check messages, and an opt-in `window.utmDebug` helper object for browser console access. | ||
| - Not part of the production data flow; intended for troubleshooting. | ||
|
|
||
| ### How it fits into the larger codebase | ||
|
|
||
| - Imports `captureUtmParameters` from `@/src/core/capture`, `getStoredUtmParameters`/`isSessionStorageAvailable`/`getRawStoredValue` from `@/src/core/storage`, and `getDefaultConfig` from `@/src/config/defaults`. | ||
| - Re-exported through `@/src/index.ts` so consumers can call these functions directly. | ||
| - Does not depend on or interact with `@/src/react` -- it operates on the core layer only. | ||
| - All functions accept an optional `ResolvedUtmConfig`; when omitted, they fall back to `getDefaultConfig()`. | ||
|
|
||
| ### Core Implementation | ||
|
|
||
| - `getDiagnostics()` assembles a `DiagnosticInfo` snapshot: resolves config, captures URL params via `captureUtmParameters`, reads stored params via `getStoredUtmParameters`, and checks `isSessionStorageAvailable()`. SSR-safe (returns empty URL and empty params when `window` is unavailable). | ||
| - `debugUtmState()` calls `getDiagnostics()` and formats output using `console.group`/`console.table` for structured browser console display. | ||
| - `checkUtmTracking()` calls `getDiagnostics()` and returns an array of status strings with emoji prefixes indicating state (e.g., whether params are in the URL, in storage, or if there is a mismatch suggesting the hook has not initialized yet). | ||
| - `installDebugHelpers()` checks for `?debug_utm=true` in the URL query string. If present, it attaches a `window.utmDebug` object with `state()`, `check()`, `diagnostics()`, and `raw()` methods. Only activates in browser environments. | ||
|
|
||
| ### Things to Know | ||
|
|
||
| - `installDebugHelpers()` is gated solely by the `debug_utm=true` URL parameter. It does not check `process.env` or `import.meta.env.DEV`. | ||
| - The `window.utmDebug` object is attached via a cast to `Record<string, unknown>` to avoid TypeScript errors on the global augmentation. | ||
| - `checkUtmTracking()` detects a potential timing issue: when URL params exist but storage is empty and `captureOnMount` is enabled, it warns that the hook may not have initialized yet. | ||
|
|
There was a problem hiding this comment.
Align heading hierarchy to avoid MD001 warnings.
The file jumps from H1 to H3. Please use H2 for the section headings.
Suggested fix
-### Overview
+## Overview
@@
-### How it fits into the larger codebase
+## How it fits into the larger codebase
@@
-### Core Implementation
+## Core Implementation
@@
-### Things to Know
+## Things to Know📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### Overview | |
| - Development-time diagnostic utilities for inspecting UTM tracking state (config, URL params, stored params, storage availability). | |
| - Provides console-formatted output, status check messages, and an opt-in `window.utmDebug` helper object for browser console access. | |
| - Not part of the production data flow; intended for troubleshooting. | |
| ### How it fits into the larger codebase | |
| - Imports `captureUtmParameters` from `@/src/core/capture`, `getStoredUtmParameters`/`isSessionStorageAvailable`/`getRawStoredValue` from `@/src/core/storage`, and `getDefaultConfig` from `@/src/config/defaults`. | |
| - Re-exported through `@/src/index.ts` so consumers can call these functions directly. | |
| - Does not depend on or interact with `@/src/react` -- it operates on the core layer only. | |
| - All functions accept an optional `ResolvedUtmConfig`; when omitted, they fall back to `getDefaultConfig()`. | |
| ### Core Implementation | |
| - `getDiagnostics()` assembles a `DiagnosticInfo` snapshot: resolves config, captures URL params via `captureUtmParameters`, reads stored params via `getStoredUtmParameters`, and checks `isSessionStorageAvailable()`. SSR-safe (returns empty URL and empty params when `window` is unavailable). | |
| - `debugUtmState()` calls `getDiagnostics()` and formats output using `console.group`/`console.table` for structured browser console display. | |
| - `checkUtmTracking()` calls `getDiagnostics()` and returns an array of status strings with emoji prefixes indicating state (e.g., whether params are in the URL, in storage, or if there is a mismatch suggesting the hook has not initialized yet). | |
| - `installDebugHelpers()` checks for `?debug_utm=true` in the URL query string. If present, it attaches a `window.utmDebug` object with `state()`, `check()`, `diagnostics()`, and `raw()` methods. Only activates in browser environments. | |
| ### Things to Know | |
| - `installDebugHelpers()` is gated solely by the `debug_utm=true` URL parameter. It does not check `process.env` or `import.meta.env.DEV`. | |
| - The `window.utmDebug` object is attached via a cast to `Record<string, unknown>` to avoid TypeScript errors on the global augmentation. | |
| - `checkUtmTracking()` detects a potential timing issue: when URL params exist but storage is empty and `captureOnMount` is enabled, it warns that the hook may not have initialized yet. | |
| ## Overview | |
| - Development-time diagnostic utilities for inspecting UTM tracking state (config, URL params, stored params, storage availability). | |
| - Provides console-formatted output, status check messages, and an opt-in `window.utmDebug` helper object for browser console access. | |
| - Not part of the production data flow; intended for troubleshooting. | |
| ## How it fits into the larger codebase | |
| - Imports `captureUtmParameters` from `@/src/core/capture`, `getStoredUtmParameters`/`isSessionStorageAvailable`/`getRawStoredValue` from `@/src/core/storage`, and `getDefaultConfig` from `@/src/config/defaults`. | |
| - Re-exported through `@/src/index.ts` so consumers can call these functions directly. | |
| - Does not depend on or interact with `@/src/react` -- it operates on the core layer only. | |
| - All functions accept an optional `ResolvedUtmConfig`; when omitted, they fall back to `getDefaultConfig()`. | |
| ## Core Implementation | |
| - `getDiagnostics()` assembles a `DiagnosticInfo` snapshot: resolves config, captures URL params via `captureUtmParameters`, reads stored params via `getStoredUtmParameters`, and checks `isSessionStorageAvailable()`. SSR-safe (returns empty URL and empty params when `window` is unavailable). | |
| - `debugUtmState()` calls `getDiagnostics()` and formats output using `console.group`/`console.table` for structured browser console display. | |
| - `checkUtmTracking()` calls `getDiagnostics()` and returns an array of status strings with emoji prefixes indicating state (e.g., whether params are in the URL, in storage, or if there is a mismatch suggesting the hook has not initialized yet). | |
| - `installDebugHelpers()` checks for `?debug_utm=true` in the URL query string. If present, it attaches a `window.utmDebug` object with `state()`, `check()`, `diagnostics()`, and `raw()` methods. Only activates in browser environments. | |
| ## Things to Know | |
| - `installDebugHelpers()` is gated solely by the `debug_utm=true` URL parameter. It does not check `process.env` or `import.meta.env.DEV`. | |
| - The `window.utmDebug` object is attached via a cast to `Record<string, unknown>` to avoid TypeScript errors on the global augmentation. | |
| - `checkUtmTracking()` detects a potential timing issue: when URL params exist but storage is empty and `captureOnMount` is enabled, it warns that the hook may not have initialized yet. |
🧰 Tools
🪛 LanguageTool
[uncategorized] ~29-~29: Use a comma before ‘but’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...tial timing issue: when URL params exist but storage is empty and captureOnMount i...
(COMMA_COMPOUND_SENTENCE_2)
🪛 markdownlint-cli2 (0.20.0)
[warning] 5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
🤖 Prompt for AI Agents
In `@src/debug/docs.md` around lines 5 - 30, Update the markdown heading levels so
H2 is used instead of H3 to avoid MD001 warnings: change the headings
"Overview", "How it fits into the larger codebase", "Core Implementation", and
"Things to Know" from ### to ## in src/debug/docs.md (leave the H1 intact and
ensure subsections beneath those remain correctly nested); no code changes
required—just adjust the markdown heading markers.
| ### Overview | ||
|
|
||
| - Root source directory for `@jackmisner/utm-toolkit`, a TypeScript library for capturing, storing, and appending UTM tracking parameters. | ||
| - Contains framework-agnostic core utilities (`@/src/core`, `@/src/config`, `@/src/debug`, `@/src/types`) and an optional React integration (`@/src/react`). | ||
| - Exposes two package entry points: `@/src/index.ts` (main, imported as `@jackmisner/utm-toolkit`) and `@/src/react/index.ts` (imported as `@jackmisner/utm-toolkit/react`). | ||
|
|
||
| ### How it fits into the larger codebase | ||
|
|
||
| - `@/src/index.ts` is the main barrel export that re-exports everything from `core`, `config`, `debug`, and `types`. This is what consumers get when they `import from '@jackmisner/utm-toolkit'`. | ||
| - `@/src/react/index.ts` is the second entry point for React-specific exports, built as a separate bundle with React externalized. | ||
| - `@/tsup.config.ts` defines these two entry points and produces dual ESM/CJS output with TypeScript declarations. | ||
| - `@/__tests__` mirrors this directory structure for testing. | ||
| - The library has zero runtime dependencies. React is an optional peer dependency used only by `@/src/react`. | ||
|
|
||
| ### Core Implementation | ||
|
|
||
| The library follows a layered architecture: | ||
|
|
||
| ``` | ||
| Consumer API | ||
| | | ||
| +--> src/index.ts (barrel) -----> core/ config/ debug/ types/ | ||
| | | ||
| +--> src/react/index.ts --------> react/ (useUtmTracking, UtmProvider) | ||
| | | ||
| +--> core/ config/ types/ | ||
| ``` | ||
|
|
||
| - **types/** (`@/src/types`): Shared type definitions consumed by all other modules. Defines the dual key format system (snake_case/camelCase) and configuration interfaces. | ||
| - **config/** (`@/src/config`): Pure configuration creation and validation. Merges partial user config with defaults to produce `ResolvedUtmConfig`. | ||
| - **core/** (`@/src/core`): Framework-agnostic UTM operations -- capture from URLs, persist in sessionStorage, append to outbound URLs, convert key formats, validate URLs. All SSR-safe. | ||
| - **debug/** (`@/src/debug`): Development-time diagnostics. Assembles state snapshots and provides formatted console output and optional `window.utmDebug` helpers. | ||
| - **react/** (`@/src/react`): React hook and context provider that orchestrate the core modules into stateful React APIs with auto-capture-on-mount behavior. | ||
|
|
||
| **Key data flow**: URL with UTM params --> `capture` --> `store` in sessionStorage --> `appendToUrl` for outbound link generation. | ||
|
|
||
| ### Things to Know | ||
|
|
||
| - **Dual key format invariant**: The library supports both `snake_case` (URL convention) and `camelCase` (TypeScript convention) throughout, but all URL-facing operations always convert to snake_case internally. This is enforced in `@/src/core/appender.ts`. | ||
| - **SSR safety**: Every module that touches browser APIs (`window`, `sessionStorage`, `URL`, `document`) guards against their absence. The library can be imported and initialized on the server without errors. | ||
| - **Two entry points**: The package.json `exports` map defines separate conditional exports for `.` and `./react`, each with ESM/CJS/types variants. React is externalized in the build so it is not bundled into the output. | ||
| - **No runtime dependencies**: The library is self-contained. All functionality is implemented from scratch using standard Web APIs (`URL`, `URLSearchParams`, `sessionStorage`). |
There was a problem hiding this comment.
Fix heading levels and add a code‑fence language.
Suggested fix
-### Overview
+## Overview
@@
-### How it fits into the larger codebase
+## How it fits into the larger codebase
@@
-### Core Implementation
+## Core Implementation
@@
-```
+```text
@@
-### Things to Know
+## Things to Know🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
[warning] 23-23: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
In `@src/docs.md` around lines 5 - 46, Change the markdown heading level "###
Things to Know" to "## Things to Know" and add a language identifier to the code
fence shown in the suggested fix (replace ```text with a proper language marker
like ```md or ```text as chosen) so heading hierarchy is corrected and the
fenced block has an explicit language; target the literal heading line "###
Things to Know" and the opening code fence token in the diff for this change.
| ### Overview | ||
|
|
||
| - React integration layer providing a hook (`useUtmTracking`) and context provider (`UtmProvider`/`useUtmContext`) for UTM parameter management in React applications. | ||
| - This is the second package entry point, imported as `@jackmisner/utm-toolkit/react` and built as a separate bundle with React externalized. | ||
| - Orchestrates the core modules (`@/src/core`) and config system (`@/src/config`) into a stateful React API. | ||
|
|
||
| ### How it fits into the larger codebase | ||
|
|
||
| - `useUtmTracking` is the primary orchestrator: it calls `createConfig()` from `@/src/config`, then uses `captureUtmParameters`, `storeUtmParameters`, `getStoredUtmParameters`, `clearStoredUtmParameters`, `appendUtmParameters`, `convertParams`, and `isSnakeCaseUtmKey` from `@/src/core`. | ||
| - `UtmProvider` wraps `useUtmTracking` in a React context, enabling tree-wide access via `useUtmContext()`. | ||
| - React is externalized in the build (`tsup.config.ts` declares `external: ['react']`) and declared as an optional peer dependency. The core library works without React. | ||
| - Types (`UseUtmTrackingReturn`, `UtmProviderProps`, etc.) come from `@/src/types`. | ||
|
|
||
| ### Core Implementation | ||
|
|
||
| **Data flow through `useUtmTracking`:** | ||
|
|
||
| ``` | ||
| Mount | ||
| | | ||
| v | ||
| useState initializer --> getStoredUtmParameters() --> initial state from sessionStorage | ||
| | | ||
| v | ||
| useEffect (once, via ref guard) --> if captureOnMount && enabled: | ||
| | | ||
| v | ||
| capture() --> captureUtmParameters(window.location.href) --> if has params: | ||
| | storeUtmParameters() | ||
| | setUtmParameters() | ||
| | else if has defaultParams: | ||
| | store & set defaults | ||
| v | ||
| appendToUrl(url, platform?) --> merges: captured params < default share context < platform context | ||
| | --> filters out excludeFromShares | ||
| | --> appendUtmParameters(url, mergedParams) | ||
| v | ||
| URL with UTM params | ||
| ``` |
There was a problem hiding this comment.
Fix heading levels and add a code‑fence language.
Suggested fix
-### Overview
+## Overview
@@
-### How it fits into the larger codebase
+## How it fits into the larger codebase
@@
-### Core Implementation
+## Core Implementation
@@
-```
+```text
@@
-### Things to Know
+## Things to Know📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### Overview | |
| - React integration layer providing a hook (`useUtmTracking`) and context provider (`UtmProvider`/`useUtmContext`) for UTM parameter management in React applications. | |
| - This is the second package entry point, imported as `@jackmisner/utm-toolkit/react` and built as a separate bundle with React externalized. | |
| - Orchestrates the core modules (`@/src/core`) and config system (`@/src/config`) into a stateful React API. | |
| ### How it fits into the larger codebase | |
| - `useUtmTracking` is the primary orchestrator: it calls `createConfig()` from `@/src/config`, then uses `captureUtmParameters`, `storeUtmParameters`, `getStoredUtmParameters`, `clearStoredUtmParameters`, `appendUtmParameters`, `convertParams`, and `isSnakeCaseUtmKey` from `@/src/core`. | |
| - `UtmProvider` wraps `useUtmTracking` in a React context, enabling tree-wide access via `useUtmContext()`. | |
| - React is externalized in the build (`tsup.config.ts` declares `external: ['react']`) and declared as an optional peer dependency. The core library works without React. | |
| - Types (`UseUtmTrackingReturn`, `UtmProviderProps`, etc.) come from `@/src/types`. | |
| ### Core Implementation | |
| **Data flow through `useUtmTracking`:** | |
| ``` | |
| Mount | |
| | | |
| v | |
| useState initializer --> getStoredUtmParameters() --> initial state from sessionStorage | |
| | | |
| v | |
| useEffect (once, via ref guard) --> if captureOnMount && enabled: | |
| | | |
| v | |
| capture() --> captureUtmParameters(window.location.href) --> if has params: | |
| | storeUtmParameters() | |
| | setUtmParameters() | |
| | else if has defaultParams: | |
| | store & set defaults | |
| v | |
| appendToUrl(url, platform?) --> merges: captured params < default share context < platform context | |
| | --> filters out excludeFromShares | |
| | --> appendUtmParameters(url, mergedParams) | |
| v | |
| URL with UTM params | |
| ``` | |
| ## Overview | |
| - React integration layer providing a hook (`useUtmTracking`) and context provider (`UtmProvider`/`useUtmContext`) for UTM parameter management in React applications. | |
| - This is the second package entry point, imported as `@jackmisner/utm-toolkit/react` and built as a separate bundle with React externalized. | |
| - Orchestrates the core modules (`@/src/core`) and config system (`@/src/config`) into a stateful React API. | |
| ## How it fits into the larger codebase | |
| - `useUtmTracking` is the primary orchestrator: it calls `createConfig()` from `@/src/config`, then uses `captureUtmParameters`, `storeUtmParameters`, `getStoredUtmParameters`, `clearStoredUtmParameters`, `appendUtmParameters`, `convertParams`, and `isSnakeCaseUtmKey` from `@/src/core`. | |
| - `UtmProvider` wraps `useUtmTracking` in a React context, enabling tree-wide access via `useUtmContext()`. | |
| - React is externalized in the build (`tsup.config.ts` declares `external: ['react']`) and declared as an optional peer dependency. The core library works without React. | |
| - Types (`UseUtmTrackingReturn`, `UtmProviderProps`, etc.) come from `@/src/types`. | |
| ## Core Implementation | |
| **Data flow through `useUtmTracking`:** | |
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
[warning] 22-22: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
In `@src/react/docs.md` around lines 5 - 43, Change the "### Things to Know"
heading in src/react/docs.md to a level-2 heading ("## Things to Know") and
update any plain code fences in the file to include a language token (e.g., use
```text instead of ```) so syntax/formatting is explicit; locate the "Things to
Know" heading and the surrounding fenced block(s) and adjust their marker lines
accordingly.
| ### Overview | ||
|
|
||
| - Central type definitions for the entire library, consumed by `@/src/core`, `@/src/config`, `@/src/debug`, and `@/src/react`. | ||
| - Defines the dual key format system (`snake_case` for URLs, `camelCase` for TypeScript) that is a core invariant of the library. | ||
| - All types are re-exported through `@/src/index.ts` to package consumers. | ||
|
|
||
| ### How it fits into the larger codebase | ||
|
|
||
| - Every other module in the library imports types from here. This is the single source of truth for all shared interfaces and type aliases. | ||
| - The `UtmParameters` union type (`UtmParametersSnake | UtmParametersCamel`) is the fundamental data shape that flows through capture, storage, appending, and React state. | ||
| - `UtmConfig` and `ResolvedUtmConfig` define the configuration contract: partial config goes in from consumers, fully-resolved config comes out from `@/src/config`. | ||
| - `UseUtmTrackingReturn` and `UtmProviderProps` define the React integration contract used by `@/src/react`. | ||
| - `SnakeCaseUtmKey` uses a template literal type (`utm_${string}`) that enables support for custom UTM parameters beyond the standard ones, which drives the extensibility design in `@/src/core/keys.ts` and `@/src/core/capture.ts`. | ||
|
|
||
| ### Core Implementation | ||
|
|
||
| - `KeyFormat` is a string literal union (`'snake_case' | 'camelCase'`) that controls key conversion throughout the library. | ||
| - `UtmParametersSnake` uses an index signature `[key: \`utm_${string}\`]` to accept arbitrary `utm_*` keys while also declaring the standard ones explicitly. `UtmParametersCamel` uses a broader `[key: string]` index signature since TypeScript template literals cannot express the camelCase pattern. | ||
| - `ResolvedUtmConfig` mirrors `UtmConfig` but with all fields required -- it represents the result of merging user-provided partial config with defaults. | ||
| - `ShareContextParams` uses `Partial<Record<SharePlatform, UtmParameters>>` with a `default` key for base params and platform-specific overrides, enabling a layered merge strategy in `useUtmTracking`'s `appendToUrl` callback. | ||
| - `AppendOptions` controls whether UTM params go into query string or fragment, and whether existing UTM params on the target URL are preserved. | ||
|
|
||
| ### Things to Know | ||
|
|
||
| - `UtmParameters` is a union, not an intersection. Code that receives it must handle either format, typically by detecting the format or converting via `@/src/core/keys.ts`. | ||
| - `SharePlatform` is `'linkedin' | 'twitter' | 'facebook' | 'copy' | string` -- the named platforms are documentation aids, but any string is accepted. | ||
| - `DiagnosticInfo` is only used by `@/src/debug` and is meant for development-time inspection, not production data flow. |
There was a problem hiding this comment.
Align heading hierarchy to avoid MD001 warnings.
Suggested fix
-### Overview
+## Overview
@@
-### How it fits into the larger codebase
+## How it fits into the larger codebase
@@
-### Core Implementation
+## Core Implementation
@@
-### Things to Know
+## Things to Know📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### Overview | |
| - Central type definitions for the entire library, consumed by `@/src/core`, `@/src/config`, `@/src/debug`, and `@/src/react`. | |
| - Defines the dual key format system (`snake_case` for URLs, `camelCase` for TypeScript) that is a core invariant of the library. | |
| - All types are re-exported through `@/src/index.ts` to package consumers. | |
| ### How it fits into the larger codebase | |
| - Every other module in the library imports types from here. This is the single source of truth for all shared interfaces and type aliases. | |
| - The `UtmParameters` union type (`UtmParametersSnake | UtmParametersCamel`) is the fundamental data shape that flows through capture, storage, appending, and React state. | |
| - `UtmConfig` and `ResolvedUtmConfig` define the configuration contract: partial config goes in from consumers, fully-resolved config comes out from `@/src/config`. | |
| - `UseUtmTrackingReturn` and `UtmProviderProps` define the React integration contract used by `@/src/react`. | |
| - `SnakeCaseUtmKey` uses a template literal type (`utm_${string}`) that enables support for custom UTM parameters beyond the standard ones, which drives the extensibility design in `@/src/core/keys.ts` and `@/src/core/capture.ts`. | |
| ### Core Implementation | |
| - `KeyFormat` is a string literal union (`'snake_case' | 'camelCase'`) that controls key conversion throughout the library. | |
| - `UtmParametersSnake` uses an index signature `[key: \`utm_${string}\`]` to accept arbitrary `utm_*` keys while also declaring the standard ones explicitly. `UtmParametersCamel` uses a broader `[key: string]` index signature since TypeScript template literals cannot express the camelCase pattern. | |
| - `ResolvedUtmConfig` mirrors `UtmConfig` but with all fields required -- it represents the result of merging user-provided partial config with defaults. | |
| - `ShareContextParams` uses `Partial<Record<SharePlatform, UtmParameters>>` with a `default` key for base params and platform-specific overrides, enabling a layered merge strategy in `useUtmTracking`'s `appendToUrl` callback. | |
| - `AppendOptions` controls whether UTM params go into query string or fragment, and whether existing UTM params on the target URL are preserved. | |
| ### Things to Know | |
| - `UtmParameters` is a union, not an intersection. Code that receives it must handle either format, typically by detecting the format or converting via `@/src/core/keys.ts`. | |
| - `SharePlatform` is `'linkedin' | 'twitter' | 'facebook' | 'copy' | string` -- the named platforms are documentation aids, but any string is accepted. | |
| - `DiagnosticInfo` is only used by `@/src/debug` and is meant for development-time inspection, not production data flow. | |
| ## Overview | |
| - Central type definitions for the entire library, consumed by `@/src/core`, `@/src/config`, `@/src/debug`, and `@/src/react`. | |
| - Defines the dual key format system (`snake_case` for URLs, `camelCase` for TypeScript) that is a core invariant of the library. | |
| - All types are re-exported through `@/src/index.ts` to package consumers. | |
| ## How it fits into the larger codebase | |
| - Every other module in the library imports types from here. This is the single source of truth for all shared interfaces and type aliases. | |
| - The `UtmParameters` union type (`UtmParametersSnake | UtmParametersCamel`) is the fundamental data shape that flows through capture, storage, appending, and React state. | |
| - `UtmConfig` and `ResolvedUtmConfig` define the configuration contract: partial config goes in from consumers, fully-resolved config comes out from `@/src/config`. | |
| - `UseUtmTrackingReturn` and `UtmProviderProps` define the React integration contract used by `@/src/react`. | |
| - `SnakeCaseUtmKey` uses a template literal type (`utm_${string}`) that enables support for custom UTM parameters beyond the standard ones, which drives the extensibility design in `@/src/core/keys.ts` and `@/src/core/capture.ts`. | |
| ## Core Implementation | |
| - `KeyFormat` is a string literal union (`'snake_case' | 'camelCase'`) that controls key conversion throughout the library. | |
| - `UtmParametersSnake` uses an index signature `[key: \`utm_${string}\`]` to accept arbitrary `utm_*` keys while also declaring the standard ones explicitly. `UtmParametersCamel` uses a broader `[key: string]` index signature since TypeScript template literals cannot express the camelCase pattern. | |
| - `ResolvedUtmConfig` mirrors `UtmConfig` but with all fields required -- it represents the result of merging user-provided partial config with defaults. | |
| - `ShareContextParams` uses `Partial<Record<SharePlatform, UtmParameters>>` with a `default` key for base params and platform-specific overrides, enabling a layered merge strategy in `useUtmTracking`'s `appendToUrl` callback. | |
| - `AppendOptions` controls whether UTM params go into query string or fragment, and whether existing UTM params on the target URL are preserved. | |
| ## Things to Know | |
| - `UtmParameters` is a union, not an intersection. Code that receives it must handle either format, typically by detecting the format or converting via `@/src/core/keys.ts`. | |
| - `SharePlatform` is `'linkedin' | 'twitter' | 'facebook' | 'copy' | string` -- the named platforms are documentation aids, but any string is accepted. | |
| - `DiagnosticInfo` is only used by `@/src/debug` and is meant for development-time inspection, not production data flow. |
🧰 Tools
🪛 LanguageTool
[uncategorized] ~15-~15: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ... partial config goes in from consumers, fully-resolved config comes out from @/src/config. -...
(HYPHENATED_LY_ADVERB_ADJECTIVE)
[uncategorized] ~22-~22: Possible missing comma found.
Context: ...luses a broader[key: string]` index signature since TypeScript template literals cann...
(AI_HYDRA_LEO_MISSING_COMMA)
[uncategorized] ~30-~30: Did you mean “Twitter” (= microblogging service, capitalized)?
Context: ...src/core/keys.ts. - SharePlatformis'linkedin' | 'twitter' | 'facebook' | 'copy' | string` -- the...
(TWITTER)
🪛 markdownlint-cli2 (0.20.0)
[warning] 5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
🤖 Prompt for AI Agents
In `@src/types/docs.md` around lines 5 - 31, The markdown uses third-level
headings (### Overview, ### How it fits into the larger codebase, ### Core
Implementation, ### Things to Know) which triggers MD001 about heading
hierarchy; change the heading levels so they increment properly (e.g., promote
each "###" to "##" or add a top-level H1 before them) so the document starts
with a level-1/level-2 heading and subsequent sections use level-2 headings;
update the headings "Overview", "How it fits into the larger codebase", "Core
Implementation", and "Things to Know" accordingly to restore a correct heading
hierarchy.
Leftover from the pre-tsup build. The build is entirely driven by tsup now, nothing references this file. 🤖 Generated with [Nori](https://nori.ai) Co-Authored-By: Nori <contact@tilework.tech>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@CLAUDE.md`:
- Line 20: The sentence "The tag push triggers the publish workflow." in the
CLAUDE.md Releases paragraph is awkward; update the wording to "The tag push
triggers the publishing workflow." or rephrase the whole sentence to "Pushing
the tag triggers the publishing workflow." to improve clarity while keeping the
existing meaning (locate the line containing "tag push triggers the publish
workflow" and replace it accordingly).
…ording Address CodeRabbit review feedback: add `text` language identifier to unlabeled code fences in docs.md files (MD040), and minor wording improvement in CLAUDE.md. 🤖 Generated with [Nori](https://nori.ai) Co-Authored-By: Nori <contact@tilework.tech>
Summary
🤖 Generated with Nori
docs.mdfiles to 7 directories (src/,src/types/,src/config/,src/core/,src/debug/,src/react/,__tests__/) documenting architecture, system invariants, and implementation detailsinstallDebugHelpersthat incorrectly claimed it checksimport.meta.env.DEV(it only checks the?debug_utm=trueURL parameter)Test Plan
Share Nori with your team: https://www.npmjs.com/package/nori-ai
Summary by CodeRabbit
Documentation
Bug Fixes / Behaviour
Chores / Packaging