Conversation
Closes #566 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Environment values are now auto-coerced from strings into numbers and booleans (including number subtypes like ports and epochs). * **Breaking Changes** * The legacy boolean keyword was removed. * Within the coercion scope, string inputs coerce to number/boolean; some number constraints (ranges/divisors) do not apply to coerced numbers — see workarounds. * **Documentation** * Coercion guide, design, spec, and task docs added. * **Tests** * End-to-end coercion integration tests added. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
🦋 Changeset detectedLatest commit: 9cef3a9 The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughImplements schema-directed coercion for environment variables and refactors createEnv to accept a config object Changes
Sequence Diagram(s)sequenceDiagram
participant User as User code
participant CreateEnv as createEnv()
participant Schema as ArkType Schema
participant Introspect as schema.in.toJsonSchema()
participant Coerce as coerce() utility
participant Validate as ArkType validate
User->>CreateEnv: createEnv(schema, { env, coerce: true })
CreateEnv->>Schema: parse/compile schema
CreateEnv->>Introspect: schema.in.toJsonSchema()
Introspect-->>CreateEnv: JSON Schema metadata
CreateEnv->>Coerce: create pipeline wrapper when targets found
User->>Coerce: runtime env (string values)
Coerce->>Coerce: findCoercionPaths → applyCoercion (numbers / booleans)
Coerce->>Validate: pass coerced data into original schema
Validate-->>User: validated, typed env object
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
commit: |
📦 Bundle Size Report
✅ All size limits passed! |
Closes #571 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Environment variables are now auto-coerced from strings to numbers and booleans during env parsing, including numeric refinements (ranges, divisors) and strict literal handling. Parsed-number/boolean behavior applies globally so defaults and dotenv strings become proper numbers/booleans. * **Breaking Changes** * Legacy boolean keyword renamed to parsedBoolean. * number.port now accepts numbers only (string-parsing removed). <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Strengthened type safety and validation in schema coercion utilities, improving inference and consistency of value transformations and preserving original structure when possible. * Improved error detection and messaging for transformation failures and brittle internal cases. * **Chores** * Updated development dependency to support the enhanced internal handling and more reliable schema processing. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
…entation) (#578) Closes #577 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Breaking Changes** * Removed the root-level custom boolean keyword; boolean coercion is now centralized. * Removed strict parsed-number/boolean variants; numeric/boolean handling now uses the centralized approach and a stricter numeric behavior for port-like fields. * **Improvements** * Coercion refactored to a schema-driven, pipeline-based pre-processing step using public introspection. * Eliminated reliance on undocumented internals for more stable, reliable coercion and improved performance via one-time introspection. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
- Correctly process `in` schema for coercion - Add tests for createEnv with morphed schemas - Add tests for coerce utility with morphed schemas <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Environment variable coercion now correctly handles schemas containing type transformations and pipes without errors. * **Documentation** * Updated schema introspection methodology to explain input-side schema analysis approach. * Added guidance on union handling during coercion. * **Tests** * Added comprehensive test coverage for schemas with transformations across multiple test suites. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Use `toJsonSchema` fallback - Handle unjsonifiable types - Preserve base schema structure - Use public API for introspection Closes #594 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Enhanced schema introspection robustness with a fallback mechanism that preserves base schema structure for types that cannot be fully represented in standard formats, enabling more resilient coercion handling. * **Documentation** * Updated design and proposal documentation for schema introspection workflows. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes #568 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Chores** * Updated environment variable validation rules across playgrounds and examples for improved type consistency. * Refactored configuration code structure by streamlining variable declarations and removing intermediate bindings. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added comprehensive coercion documentation explaining automatic type conversion for environment variables. * **Documentation** * Updated documentation structure and navigation to reflect feature changes. * Removed morphs documentation. * **Breaking Changes** * Boolean morph feature has been removed; boolean coercion now handled through standard validation. * Port keyword validation enforced to numeric range 0-65535. * **Chores** * Renamed DEBUG environment variable to DEBUGGING with updated default value. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (5)
packages/arkenv/src/utils/coerce.test.ts (1)
41-48: Consider adding tests for case-insensitive boolean coercion.The tests verify
"true"and"false"coercion, but environment variables are often set with different cases (e.g.,"TRUE","False","TRUE"). It would be valuable to add tests to document expected behavior for case variations.🔎 Example additional test cases
it("should handle boolean case variations", () => { const schema = type({ DEBUG: "boolean", }); const coercedSchema = coerce(schema); // Document expected behavior - either coerce or fail consistently const uppercase = coercedSchema({ DEBUG: "TRUE" }); const mixedCase = coercedSchema({ DEBUG: "True" }); // Assert expected behavior based on implementation });openspec/changes/archive/2025-12-22-coercion-public-api/design.md (4)
28-52: Clarify deduplication strategy and edge cases in union handling.Two areas need clarification:
Deduplication logic (line 43): The comment states paths are "stringified and deduplicated," but the mechanism isn't detailed. For example:
- Would
["port"]and["port", "*"]be treated as different paths (likely correct), or could stringification cause collisions?- Are paths deduplicated by exact match, prefix, or both?
Discriminated unions: The design mentions handling
anyOf,oneOf,allOfrecursively (line 42), but doesn't address discriminated unions (often represented asallOfwith aconstdiscriminator). Would these be traversed correctly, or could they generate redundant coercion targets?Consider adding an example that shows:
- A nested object with arrays of primitives (e.g.,
{ servers: [{ port: number, enabled: boolean }] }).- A discriminated union scenario (if applicable).
54-76: Clarify mutation semantics and edge cases in coercion logic.Several details about the pre-processing phase need clarification:
In-place mutation (line 68): Is the input object mutated directly, or should it be cloned first? If mutated directly, this could cause issues if the caller reuses the input object. State the design decision explicitly.
Coercion order (lines 69–71): The design attempts
maybeParsedNumberfirst, thenmaybeParsedBoolean. What's the rationale? For a schema likenumber | boolean, could a value like"1"be incorrectly coerced to1whentruemight be expected? Consider adding a note on union handling here.Unconvertible values (line 71): Clarify that leaving unconvertible values as-is (e.g.,
"abc"remaining a string) is intentional—the validation phase will catch and report the error. This is correct behavior but deserves explicit documentation.Undefined/null handling: No mention of how
undefinedornullvalues in the input are treated. Are they left untouched? Can they be coerced? Add a rule for this.Pipeline syntax (line 76): The notation
type("unknown").pipe(transform).pipe(schema)is introduced but not explained. Briefly clarify what.pipe()does in this context (likely: chains transformations before validation).
78-84: Expand trade-offs section to cover performance and mutation concerns.The trade-offs section addresses standardization and API stability well, but misses key design decisions:
Performance trade-offs: Discuss whether schema introspection happens at setup time (one-time cost) or runtime (per-call cost). If at setup time, note this as an advantage. If at runtime, explain the performance implications for frequently-used schemas.
Mutation semantics: Explain the trade-off of mutating input data in-place. Benefits: no object cloning overhead. Downsides: caller's input object is modified, which could surprise downstream code. Why was mutation chosen over cloning?
Coercion coverage: The design gracefully handles unjsonifiable refinements by falling back to the base type. Explain the limitation this introduces: custom predicates on
numberfields will still coerce, but only to the primitive type, not applying the predicate. Is this acceptable?Comparison to alternatives: The PR objectives mention two approaches were proposed (conversion layer vs. appending
.parse). Briefly explain why this design (toJsonSchema() introspection + .pipe()) was chosen over those, or reference where that comparison is documented.Note: The section appears incomplete (line 84 has a "+ " indicator). Ensure the full trade-offs analysis is included.
1-5: Add user-facing API context to ground the design.While the design is technically sound and architecturally clear, it jumps directly into implementation details without showing how users interact with coercion. Add a brief introductory section (before or after the Architecture heading) with an example like:
// User creates an env schema and gets automatic coercion const env = createEnv({ env: process.env, coerce: true // enables automatic string → typed primitive coercion }) // PORT: "3000" becomes PORT: 3000 (number) // DEBUG: "true" becomes DEBUG: true (boolean)This grounds readers on the user-visible behavior before diving into the pipeline pattern. It also helps validate that the internal design satisfies the stated feature goal.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
.github/copilot-instructions.mdopenspec/changes/archive/2025-12-20-add-coercion/specs/coercion/spec.mdopenspec/changes/archive/2025-12-22-coercion-public-api/design.mdopenspec/changes/archive/2025-12-22-coercion-public-api/proposal.mdopenspec/changes/archive/2025-12-22-coercion-public-api/specs/coercion-refactor/spec.mdopenspec/changes/archive/2025-12-22-coercion-public-api/tasks.mdopenspec/changes/archive/2025-12-22-update-hero-videos/design.mdopenspec/changes/archive/2025-12-22-update-hero-videos/proposal.mdopenspec/changes/archive/2025-12-22-update-hero-videos/specs/hero-video/spec.mdopenspec/changes/archive/2025-12-22-update-hero-videos/tasks.mdopenspec/changes/update-hero-videos/specs/hero-video/spec.mdopenspec/project.mdopenspec/specs/coercion-refactor/spec.mdopenspec/specs/coercion/spec.mdopenspec/specs/hero-video/spec.mdpackages/arkenv/README.mdpackages/arkenv/src/utils/coerce.test.ts
💤 Files with no reviewable changes (1)
- openspec/changes/update-hero-videos/specs/hero-video/spec.md
✅ Files skipped from review due to trivial changes (3)
- openspec/changes/archive/2025-12-22-coercion-public-api/tasks.md
- openspec/project.md
- openspec/specs/hero-video/spec.md
🚧 Files skipped from review as they are similar to previous changes (2)
- openspec/specs/coercion/spec.md
- openspec/changes/archive/2025-12-20-add-coercion/specs/coercion/spec.md
🧰 Additional context used
📓 Path-based instructions (7)
openspec/**/spec.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
openspec/**/spec.md: Include at least one scenario per requirement using #### Scenario: header format with WHEN and THEN bullet points
Use SHALL/MUST for normative requirements rather than should/may unless intentionally non-normative
Files:
openspec/changes/archive/2025-12-22-update-hero-videos/specs/hero-video/spec.mdopenspec/changes/archive/2025-12-22-coercion-public-api/specs/coercion-refactor/spec.mdopenspec/specs/coercion-refactor/spec.md
**/*.{ts,tsx,json,md}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use Biome for linting and formatting instead of ESLint and Prettier
Files:
openspec/changes/archive/2025-12-22-update-hero-videos/specs/hero-video/spec.mdopenspec/changes/archive/2025-12-22-coercion-public-api/specs/coercion-refactor/spec.mdopenspec/changes/archive/2025-12-22-coercion-public-api/proposal.mdpackages/arkenv/README.mdopenspec/changes/archive/2025-12-22-coercion-public-api/design.mdpackages/arkenv/src/utils/coerce.test.tsopenspec/specs/coercion-refactor/spec.md
**/README.md
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Document environment requirements in README files
Files:
packages/arkenv/README.md
packages/arkenv/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/arktype.mdc)
packages/arkenv/**/*.ts: Use ArkType'stype()function to define schemas in environment variable definitions
Leverage ArkType's type inference for TypeScript types instead of manual type definitions
Use the scoped$type system for custom types defined inscope.ts
Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Use union types for enums in ArkType schemas (e.g.,"'dev' | 'prod'") instead of separate enum definitions
Leverage ArkType's built-in types (e.g.,string.host,number.port) where possible in environment schemas
Convert ArkType validation errors toArkEnvErrorfor user-friendly error messages that include variable name and expected type
Files:
packages/arkenv/src/utils/coerce.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
**/*.{ts,tsx}: Prefertypeoverinterfacefor type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverageconsttype parameters for better inference in TypeScript
Use JSDoc comments for public APIs
Use tabs for indentation (configured in Biome)
Use double quotes for strings (configured in Biome)
Organize imports automatically (Biome handles this)
Avoid explicit types when TypeScript can infer them (noInferrableTypeserror)
Useas constwhere appropriate for immutable values (useAsConstAssertionerror)
Don't reassign function parameters (noParameterAssignerror)
Place default parameters last in function signatures (useDefaultParameterLasterror)
Always initialize enum values (useEnumInitializerserror)
Declare one variable per statement (useSingleVarDeclaratorerror)
Avoid unnecessary template literals (noUnusedTemplateLiteralerror)
PreferNumber.parseIntover globalparseInt(useNumberNamespaceerror)
Use kebab-case for TypeScript filenames (e.g.,create-env.ts)
Use camelCase for function names (e.g.,createEnv)
Use PascalCase for type names (e.g.,ArkEnvError)
Use UPPER_SNAKE_CASE for environment variables and constants
Include examples in JSDoc comments when helpful for public APIs
Document complex type logic with JSDoc comments
UseArkEnvErrorfor environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type
**/*.{ts,tsx}: UsecreateEnv(schema)as the main function for validated environment objects, available as the default export
Use built-in validators (host, port, url, email) fromsrc/types.tswhen available instead of custom validation
UseArkEnvErrorfor environment variable errors, not generic errors
Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Use logical grouping for related environment variables in schemas
Use descriptive env...
Files:
packages/arkenv/src/utils/coerce.test.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Co-locate tests with components:
Component.tsxnext toComponent.test.tsx
**/*.test.{ts,tsx}: Test individual functions, components, and hooks in isolation with mocked dependencies using the*.test.tsor*.test.tsxsuffix
Mockprocess.envin tests for different scenarios and save/restore original env inbeforeEach/afterEachhooks
Use Vitest'sdescribe/itstructure in test files
Test edge cases including invalid and missing environment variable values
Use Vitest for testing framework
**/*.test.{ts,tsx}: Use Vitest for unit and integration tests
Test individual functions, components, and hooks in isolation with mocked dependencies in unit tests
Unit tests should focus on individual function logic and edge cases, component rendering and props, error handling and validation, and type checking
Unit tests should execute in less than 100ms per test
Mock external dependencies (clipboard, network, etc.) in unit tests
Co-locate unit test files with source files using naming convention: source file → test file (e.g., create-env.ts → create-env.test.ts)
Test component behavior, not aesthetics, and focus on what users can do and what the component guarantees through its API
Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests
Do not test pure styling or CSS classes, library internals (Radix/shadcn), implementation details (hooks, setState, private variables), or visual variants in component tests
Use Testing Library with user-event for real user simulation in component tests
Query by role, name, label, and text (accessibility first) in component tests
Use beforeEach/afterEach for cleanup, not beforeAll/afterAll when possible
Keep tests fast, deterministic, and parallelizable
Mock at component boundaries (network, time, context)
Files:
packages/arkenv/src/utils/coerce.test.ts
packages/arkenv/src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Main library implementation should be in
src/create-env.ts, built-in validators insrc/types.ts, error handling insrc/errors.ts, and utilities insrc/utils.ts
Files:
packages/arkenv/src/utils/coerce.test.ts
🧠 Learnings (31)
📓 Common learnings
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use logical grouping for related environment variables in schemas
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Consider bundle size impact when adding new dependencies - aspirational goal: <1kB gzipped, enforced limit: 2kB gzipped
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Keep bundle size small with a goal of < 1kB gzipped
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Always run `pnpm changeset` for version bumps in published packages - never skip changesets
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-29T08:00:08.044Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/pnpm.mdc:0-0
Timestamp: 2025-11-29T08:00:08.044Z
Learning: Applies to pnpm-lock.yaml : Always commit `pnpm-lock.yaml` to version control and never manually edit the lock file. Run `pnpm install` to update it when dependencies change
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: Applies to packages/*/package.json : Packages in packages/ directory must be published to npm and require changesets for versioning, proper exports, and type definitions
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Avoid breaking changes to the public API without explicit approval and a major version changeset
Applied to files:
.github/copilot-instructions.mdopenspec/changes/archive/2025-12-22-coercion-public-api/proposal.md
📚 Learning: 2025-11-29T08:00:08.044Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/pnpm.mdc:0-0
Timestamp: 2025-11-29T08:00:08.044Z
Learning: Applies to {package.json,pnpm-lock.yaml,pnpm-workspace.yaml} : Always use `pnpm` for all package management operations in this monorepo (never use `npm` or `yarn` commands), except for standalone example projects in the `examples/` folder
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: Only packages in packages/ directory are published to npm; publishing is handled by changesets using pnpm release
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Use `pnpm install` instead of directly modifying `pnpm-lock.yaml`
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: Applies to examples/*/package.json : Examples in examples/ directory are not published, may have their own lock files, and are used as test fixtures
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-29T08:00:08.044Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/pnpm.mdc:0-0
Timestamp: 2025-11-29T08:00:08.044Z
Learning: Applies to package.json : Configure only built dependencies (native modules) in `pnpm.onlyBuiltDependencies`, including: biomejs/biome, sentry/cli, swc/core, tailwindcss/oxide, vercel/speed-insights, esbuild, and sharp
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: Applies to openspec/**/spec.md : Include at least one scenario per requirement using #### Scenario: header format with **WHEN** and **THEN** bullet points
Applied to files:
openspec/changes/archive/2025-12-22-update-hero-videos/specs/hero-video/spec.md
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: For MODIFIED requirements, copy the entire existing requirement block and paste under ## MODIFIED Requirements, then edit to reflect new behavior
Applied to files:
openspec/changes/archive/2025-12-22-update-hero-videos/specs/hero-video/spec.md
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Applied to files:
openspec/changes/archive/2025-12-22-coercion-public-api/specs/coercion-refactor/spec.mdopenspec/changes/archive/2025-12-22-coercion-public-api/proposal.mdpackages/arkenv/README.mdpackages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Applied to files:
openspec/changes/archive/2025-12-22-coercion-public-api/specs/coercion-refactor/spec.mdopenspec/changes/archive/2025-12-22-coercion-public-api/proposal.mdpackages/arkenv/README.mdpackages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: For breaking changes, always create an OpenSpec proposal first
Applied to files:
openspec/changes/archive/2025-12-22-coercion-public-api/proposal.md
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Applied to files:
openspec/changes/archive/2025-12-22-coercion-public-api/proposal.mdpackages/arkenv/README.mdpackages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions
Applied to files:
openspec/changes/archive/2025-12-22-coercion-public-api/proposal.mdpackages/arkenv/README.mdpackages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-12-22T19:44:07.593Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:07.593Z
Learning: In examples/basic/index.ts: Use explicit ArkType syntax (e.g., "string.ip | 'localhost'", "0 <= number.integer <= 65535") instead of built-in validators (string.host, number.port) to showcase ArkType's type system capabilities for educational purposes.
Applied to files:
packages/arkenv/README.mdpackages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use ArkType's `type()` function to define schemas in environment variable definitions
Applied to files:
packages/arkenv/README.md
📚 Learning: 2025-09-10T19:35:18.179Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 136
File: .changeset/vast-bananas-win.md:2-3
Timestamp: 2025-09-10T19:35:18.179Z
Learning: The arkenv package is currently in v0.x.x (pre-1.0) development phase, where breaking changes are acceptable in minor version bumps according to semantic versioning conventions.
Applied to files:
packages/arkenv/README.md
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type
Applied to files:
packages/arkenv/README.mdpackages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's type inference for TypeScript types instead of manual type definitions
Applied to files:
packages/arkenv/README.md
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable validation errors
Applied to files:
packages/arkenv/README.md
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable errors, not generic errors
Applied to files:
packages/arkenv/README.md
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Provide clear, actionable error messages that include the variable name and expected type
Applied to files:
packages/arkenv/README.md
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition
Applied to files:
packages/arkenv/README.md
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Unit tests should focus on individual function logic and edge cases, component rendering and props, error handling and validation, and type checking
Applied to files:
packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests
Applied to files:
packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.test.{ts,tsx} : Test edge cases including invalid and missing environment variable values
Applied to files:
packages/arkenv/src/utils/coerce.test.ts
🧬 Code graph analysis (5)
openspec/changes/archive/2025-12-22-update-hero-videos/specs/hero-video/spec.md (3)
apps/www/components/hero-video.tsx (1)
HeroVideo(6-46)apps/www/app/(home)/page.tsx (1)
HomePage(16-108)apps/www/components/page/video-demo.tsx (1)
VideoDemo(15-62)
openspec/changes/archive/2025-12-22-coercion-public-api/proposal.md (2)
packages/arkenv/src/type.test.ts (1)
it(4-218)packages/arkenv/src/create-env.ts (1)
createEnv(35-53)
packages/arkenv/README.md (3)
packages/arkenv/src/type.test.ts (4)
envType(86-108)envType(132-152)envType(121-130)envType(5-9)packages/internal/scope/src/index.test.ts (2)
envType(33-44)hostType(5-9)packages/arkenv/src/custom-types.integration.test.ts (4)
vi(161-173)vi(129-143)vi(145-159)vi(215-223)
packages/arkenv/src/utils/coerce.test.ts (2)
packages/arkenv/src/type.ts (1)
type(3-3)packages/arkenv/src/utils/coerce.ts (1)
coerce(215-238)
openspec/specs/coercion-refactor/spec.md (1)
packages/arkenv/src/type.test.ts (1)
it(4-218)
🪛 LanguageTool
openspec/specs/coercion-refactor/spec.md
[grammar] ~4-~4: Use a hyphen to join words.
Context: ...urpose TBD - created by archiving change coercion-public-api. Update Purpose afte...
(QB_NEW_EN_HYPHEN)
⏰ 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). (5)
- GitHub Check: test-e2e (e2e)
- GitHub Check: test-e2e (a11y)
- GitHub Check: test-typesafety
- GitHub Check: test-build (lts/*)
- GitHub Check: test-build (latest)
🔇 Additional comments (14)
openspec/changes/archive/2025-12-22-update-hero-videos/specs/hero-video/spec.md (3)
1-32: Clarify scenario format relative to spec guidelines.The guidelines specify scenarios should include
**WHEN** and **THEN** bullet points, but this file uses the fuller BDD format with Given, When, Then. While the BDD approach is more comprehensive and your scenarios cover the requirement well, confirm with your team whether the extended format is the preferred pattern for allopenspec/**/spec.mdfiles, or if a stricter When-Then format is expected for consistency.Verify guideline interpretation: Should all scenario sections in
openspec/specs use strictly**WHEN**and**THEN**(as written), or is the extended Given-When-Then BDD format acceptable?
3-4: LGTM!The requirement uses appropriate normative language (MUST) and is clearly stated. The combination of display, behavior, theme-awareness, and responsiveness requirements in a single requirement is cohesive.
29-32: Clarify "gradient overlays" reference.Scenario 4 mentions handling "interfering gradient overlays," but the HeroVideo component implementation uses opacity-based theme switching without explicit gradient overlay handling. Verify whether:
- "Gradient overlays" refers to the top gradient overlay SVG shown in HomePage (from the relevant code snippet), which should not interfere with video blending, or
- The spec should describe the actual mechanism (CSS opacity transitions for theme switching)
This clarification ensures the spec accurately reflects what the component implements.
.github/copilot-instructions.md (1)
284-284: Confirm bundle size measurement for coercion feature before merging. The aspirational goal has been increased from <1kB to <2kB gzipped—verify that actual measurements show the coercion implementation stays within the enforced 2kB limit, and ensure any related documentation updates (README, package.json configuration) are also included if needed.openspec/changes/archive/2025-12-22-coercion-public-api/proposal.md (1)
1-35: Well-structured proposal with clear technical direction.The proposal effectively documents the rationale for moving from internal ArkType APIs to the stable
schema.in.toJsonSchema()approach. The implementation rules (file size limits, modular organization, strict type safety) align with the project's coding guidelines. Based on learnings, this follows the pattern of creating an OpenSpec proposal for breaking changes.packages/arkenv/README.md (3)
44-48: Good use of explicit ArkType syntax in the example.The schema demonstrates ArkType's type system capabilities with
"string.ip | 'localhost'","0 <= number.integer <= 65535", and"boolean = false". This aligns with the educational purpose of the README example.
74-74: Feature list accurately reflects the new coercion capability.Adding "coerced" to the feature description ("Validated, defaultable, coerced, typesafe environment variables") correctly highlights the new automatic coercion behavior introduced in this PR.
71-71: Bundle size claim of "<2kB gzipped" is correctly documented.The claim aligns with the project's enforced 2kB size limit (configured in package.json) and reflects the intentional increase from the previous ~700 byte size after adding the coercion feature. This is documented in the recent commit "Adjust bundle size goal to 2KB across documentation" and matches the project guidelines' enforced limit.
packages/arkenv/src/utils/coerce.test.ts (3)
1-4: Clean import structure following project conventions.Imports are properly organized with external dependencies (
arktype,vitest) followed by internal module (./coerce).
195-215: Excellent NaN handling tests.These tests effectively document the distinction between
number.NaN(which accepts NaN) and plainnumber(which rejects NaN). This is important edge-case coverage that aligns with the coding guidelines for testing edge cases.
216-241: Good array coercion and validation boundary tests.The tests properly verify that array elements are coerced and that type mismatches (array vs. single value) are correctly rejected by validation. The inline comments help clarify the expected behavior.
openspec/changes/archive/2025-12-22-coercion-public-api/specs/coercion-refactor/spec.md (1)
1-23: Well-structured specification following OpenSpec conventions.The spec correctly uses MUST for normative requirements and includes properly formatted scenarios with GIVEN/WHEN/THEN structure. The API reference (
schema.in.toJsonSchema) aligns with the proposal and actual implementation.openspec/specs/coercion-refactor/spec.md (1)
6-22: Specification correctly documents the public API approach.The requirements properly specify the use of
schema.in.toJsonSchema(addressing a previous review comment aboutschema.in.json). The scenarios clearly describe expected behavior for nested paths and pipeline-based coercion.openspec/changes/archive/2025-12-22-coercion-public-api/design.md (1)
7-26:toJsonSchema()fallback API is correctly specified in the design.The approach of using
schema.in.toJsonSchema({ fallback: (ctx) => ctx.base })to introspect schemas while preserving resilience against unjsonifiable refinements is valid and aligns with ArkType's public API. The fallback mechanism properly handles base type extraction even when custom predicates or narrows are present.
…n requirements into the main coercion spec.
…e configuration files.
…umenting goals, scope, and migration guidance after archiving `coercion-public-api`.
… for uppercase values
…n path deduplication.
…ey handling, in-place mutation rationale, sequential coercion logic, and pipeline syntax.
…ives considered for the coercion public API design.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
openspec/specs/coercion/spec.md (1)
4-4: Consider breaking up the long purpose statement.The purpose statement combines multiple concepts (mechanism definition, archive context, refinements, and literals) in a single complex sentence. Breaking it into separate sentences would improve readability.
🔎 Suggested refactor for clarity
-Define the stable coercion mechanism using public ArkType APIs for environment variable type transformation, documenting goals, scope, and migration guidance following the archive of coercion-public-api. This coercion specifically preserves support for numeric refinements like ranges and divisors while maintaining strictness for numeric literals. +Define the stable coercion mechanism using public ArkType APIs for environment variable type transformation. This specification documents goals, scope, and migration guidance following the archive of coercion-public-api. The coercion mechanism preserves support for numeric refinements (ranges and divisors) while maintaining strictness for numeric literals.packages/arkenv/src/utils/coerce.test.ts (1)
221-233: Array coercion test is solid; consider simplifying the comment.The test correctly validates array element coercion. However, the multi-line comment (lines 223-226) could be more concise since the test itself clearly demonstrates the expected behavior.
🔎 Suggested comment simplification
- it("should coerce array elements for numeric properties", () => { - const schema = type({ - // Note: The schema expects a "number", but input might be "5" (coerced -> 5) - // If input is ["1", "2"], current logic iterates and coerces them to [1, 2] - // The validation step will then reject [1, 2] against "number", which is correct behavior. - // This test ensures the traversal logic doesn't crash or behave unexpectedly. - IDS: "number[]", - }); + it("should coerce array elements for numeric properties", () => { + const schema = type({ + // Coerces array elements ["1", "2", "3"] to [1, 2, 3] + IDS: "number[]", + });
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
apps/playgrounds/vite/vite.config.tsexamples/with-vite-react/vite.config.tsopenspec/changes/archive/2025-12-02-update-hero-videos/design.mdopenspec/changes/archive/2025-12-02-update-hero-videos/proposal.mdopenspec/changes/archive/2025-12-02-update-hero-videos/specs/hero-video/spec.mdopenspec/changes/archive/2025-12-02-update-hero-videos/tasks.mdopenspec/changes/archive/2025-12-22-coercion-public-api/design.mdopenspec/specs/coercion/spec.mdpackages/arkenv/README.mdpackages/arkenv/src/utils/coerce.test.tspackages/bun-plugin/package.json
✅ Files skipped from review due to trivial changes (1)
- packages/bun-plugin/package.json
🚧 Files skipped from review as they are similar to previous changes (2)
- openspec/changes/archive/2025-12-22-coercion-public-api/design.md
- packages/arkenv/README.md
🧰 Additional context used
📓 Path-based instructions (8)
openspec/**/spec.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
openspec/**/spec.md: Include at least one scenario per requirement using #### Scenario: header format with WHEN and THEN bullet points
Use SHALL/MUST for normative requirements rather than should/may unless intentionally non-normative
Files:
openspec/changes/archive/2025-12-02-update-hero-videos/specs/hero-video/spec.mdopenspec/specs/coercion/spec.md
**/*.{ts,tsx,json,md}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use Biome for linting and formatting instead of ESLint and Prettier
Files:
openspec/changes/archive/2025-12-02-update-hero-videos/specs/hero-video/spec.mdexamples/with-vite-react/vite.config.tspackages/arkenv/src/utils/coerce.test.tsopenspec/specs/coercion/spec.mdapps/playgrounds/vite/vite.config.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
**/*.{ts,tsx}: Prefertypeoverinterfacefor type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverageconsttype parameters for better inference in TypeScript
Use JSDoc comments for public APIs
Use tabs for indentation (configured in Biome)
Use double quotes for strings (configured in Biome)
Organize imports automatically (Biome handles this)
Avoid explicit types when TypeScript can infer them (noInferrableTypeserror)
Useas constwhere appropriate for immutable values (useAsConstAssertionerror)
Don't reassign function parameters (noParameterAssignerror)
Place default parameters last in function signatures (useDefaultParameterLasterror)
Always initialize enum values (useEnumInitializerserror)
Declare one variable per statement (useSingleVarDeclaratorerror)
Avoid unnecessary template literals (noUnusedTemplateLiteralerror)
PreferNumber.parseIntover globalparseInt(useNumberNamespaceerror)
Use kebab-case for TypeScript filenames (e.g.,create-env.ts)
Use camelCase for function names (e.g.,createEnv)
Use PascalCase for type names (e.g.,ArkEnvError)
Use UPPER_SNAKE_CASE for environment variables and constants
Include examples in JSDoc comments when helpful for public APIs
Document complex type logic with JSDoc comments
UseArkEnvErrorfor environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type
**/*.{ts,tsx}: UsecreateEnv(schema)as the main function for validated environment objects, available as the default export
Use built-in validators (host, port, url, email) fromsrc/types.tswhen available instead of custom validation
UseArkEnvErrorfor environment variable errors, not generic errors
Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Use logical grouping for related environment variables in schemas
Use descriptive env...
Files:
examples/with-vite-react/vite.config.tspackages/arkenv/src/utils/coerce.test.tsapps/playgrounds/vite/vite.config.ts
{bin,examples,playgrounds}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Console usage is allowed in
bin/and example/playground directories, otherwise treated as warning
Files:
examples/with-vite-react/vite.config.ts
examples/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
examples/**/*.{ts,tsx}: Ensure examples demonstrate secure default practices
Add examples in theexamples/directory for new functionality, demonstrating real-world usage patterns
Files:
examples/with-vite-react/vite.config.ts
packages/arkenv/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/arktype.mdc)
packages/arkenv/**/*.ts: Use ArkType'stype()function to define schemas in environment variable definitions
Leverage ArkType's type inference for TypeScript types instead of manual type definitions
Use the scoped$type system for custom types defined inscope.ts
Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Use union types for enums in ArkType schemas (e.g.,"'dev' | 'prod'") instead of separate enum definitions
Leverage ArkType's built-in types (e.g.,string.host,number.port) where possible in environment schemas
Convert ArkType validation errors toArkEnvErrorfor user-friendly error messages that include variable name and expected type
Files:
packages/arkenv/src/utils/coerce.test.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Co-locate tests with components:
Component.tsxnext toComponent.test.tsx
**/*.test.{ts,tsx}: Test individual functions, components, and hooks in isolation with mocked dependencies using the*.test.tsor*.test.tsxsuffix
Mockprocess.envin tests for different scenarios and save/restore original env inbeforeEach/afterEachhooks
Use Vitest'sdescribe/itstructure in test files
Test edge cases including invalid and missing environment variable values
Use Vitest for testing framework
**/*.test.{ts,tsx}: Use Vitest for unit and integration tests
Test individual functions, components, and hooks in isolation with mocked dependencies in unit tests
Unit tests should focus on individual function logic and edge cases, component rendering and props, error handling and validation, and type checking
Unit tests should execute in less than 100ms per test
Mock external dependencies (clipboard, network, etc.) in unit tests
Co-locate unit test files with source files using naming convention: source file → test file (e.g., create-env.ts → create-env.test.ts)
Test component behavior, not aesthetics, and focus on what users can do and what the component guarantees through its API
Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests
Do not test pure styling or CSS classes, library internals (Radix/shadcn), implementation details (hooks, setState, private variables), or visual variants in component tests
Use Testing Library with user-event for real user simulation in component tests
Query by role, name, label, and text (accessibility first) in component tests
Use beforeEach/afterEach for cleanup, not beforeAll/afterAll when possible
Keep tests fast, deterministic, and parallelizable
Mock at component boundaries (network, time, context)
Files:
packages/arkenv/src/utils/coerce.test.ts
packages/arkenv/src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Main library implementation should be in
src/create-env.ts, built-in validators insrc/types.ts, error handling insrc/errors.ts, and utilities insrc/utils.ts
Files:
packages/arkenv/src/utils/coerce.test.ts
🧠 Learnings (25)
📓 Common learnings
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use logical grouping for related environment variables in schemas
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: Use ADDED for new standalone capabilities, MODIFIED for changed behavior with full requirement content, and RENAMED for name-only changes
Applied to files:
openspec/changes/archive/2025-12-02-update-hero-videos/specs/hero-video/spec.md
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use ## ADDED|MODIFIED|REMOVED|RENAMED Requirements as delta headers in spec.md files under changes
Applied to files:
openspec/changes/archive/2025-12-02-update-hero-videos/specs/hero-video/spec.md
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: Applies to openspec/**/spec.md : Include at least one scenario per requirement using #### Scenario: header format with **WHEN** and **THEN** bullet points
Applied to files:
openspec/changes/archive/2025-12-02-update-hero-videos/specs/hero-video/spec.md
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: For MODIFIED requirements, copy the entire existing requirement block and paste under ## MODIFIED Requirements, then edit to reflect new behavior
Applied to files:
openspec/changes/archive/2025-12-02-update-hero-videos/specs/hero-video/spec.md
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Applied to files:
examples/with-vite-react/vite.config.tspackages/arkenv/src/utils/coerce.test.tsopenspec/specs/coercion/spec.mdapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Applied to files:
examples/with-vite-react/vite.config.tspackages/arkenv/src/utils/coerce.test.tsopenspec/specs/coercion/spec.mdapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable errors, not generic errors
Applied to files:
examples/with-vite-react/vite.config.tsapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable validation errors
Applied to files:
examples/with-vite-react/vite.config.tsapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to packages/vite-plugin/src/**/*.test.ts : Test the Vite plugin using the with-vite-react example as a fixture and validate that the plugin works with real Vite projects
Applied to files:
examples/with-vite-react/vite.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use ArkType's `type()` function to define schemas in environment variable definitions
Applied to files:
examples/with-vite-react/vite.config.tsopenspec/specs/coercion/spec.mdapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type
Applied to files:
examples/with-vite-react/vite.config.tspackages/arkenv/src/utils/coerce.test.tsapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use descriptive environment variable names that indicate purpose and format
Applied to files:
examples/with-vite-react/vite.config.tsapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export
Applied to files:
examples/with-vite-react/vite.config.tsapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions
Applied to files:
examples/with-vite-react/vite.config.tspackages/arkenv/src/utils/coerce.test.tsapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition
Applied to files:
examples/with-vite-react/vite.config.tsapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.test.{ts,tsx} : Test edge cases including invalid and missing environment variable values
Applied to files:
examples/with-vite-react/vite.config.tspackages/arkenv/src/utils/coerce.test.tsapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-12-22T19:44:07.593Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:07.593Z
Learning: In examples/basic/index.ts: Use explicit ArkType syntax (e.g., "string.ip | 'localhost'", "0 <= number.integer <= 65535") instead of built-in validators (string.host, number.port) to showcase ArkType's type system capabilities for educational purposes.
Applied to files:
packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests
Applied to files:
packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Unit tests should focus on individual function logic and edge cases, component rendering and props, error handling and validation, and type checking
Applied to files:
packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Applied to files:
packages/arkenv/src/utils/coerce.test.tsopenspec/specs/coercion/spec.mdapps/playgrounds/vite/vite.config.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to packages/arkenv/src/**/*.ts : Main library implementation should be in `src/create-env.ts`, built-in validators in `src/types.ts`, error handling in `src/errors.ts`, and utilities in `src/utils.ts`
Applied to files:
packages/arkenv/src/utils/coerce.test.ts
📚 Learning: 2025-11-24T16:05:17.653Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:17.653Z
Learning: Use `@/openspec/AGENTS.md` to learn spec format and conventions
Applied to files:
openspec/specs/coercion/spec.md
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: Applies to openspec/**/spec.md : Use SHALL/MUST for normative requirements rather than should/may unless intentionally non-normative
Applied to files:
openspec/specs/coercion/spec.md
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use logical grouping for related environment variables in schemas
Applied to files:
apps/playgrounds/vite/vite.config.ts
🧬 Code graph analysis (1)
examples/with-vite-react/vite.config.ts (3)
packages/vite-plugin/src/index.ts (1)
arkenv(49-88)apps/playgrounds/vite/vite.config.ts (1)
Env(11-16)apps/playgrounds/vite-legacy/vite.config.ts (1)
Env(11-16)
⏰ 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: test-e2e (a11y)
- GitHub Check: test-e2e (e2e)
🔇 Additional comments (15)
openspec/changes/archive/2025-12-02-update-hero-videos/specs/hero-video/spec.md (3)
1-33: Scope mismatch: File appears unrelated to PR objectives.The PR objectives describe implementing schema-directed coercion for environment variables (closing issue #228 in the arkenv package). However, this file specifies hero video display behavior for a website. While the PR includes "www" in its labels, clarify whether this hero-video spec is intentional as part of the coercion feature PR or if it was included inadvertently.
7-33: Clarify scenario format: Guideline specifies WHEN/THEN, but implementation uses GIVEN/WHEN/THEN.The coding guideline for openspec files states scenarios should use "WHEN and THEN bullet points," but your scenarios include GIVEN as well (BDD Gherkin format). While GIVEN/WHEN/THEN is standard practice and more explicit, confirm whether the guideline intended to exclude GIVEN or if GIVEN is acceptable.
3-4: Spec content is well-structured and comprehensive.The requirement is clearly stated with MUST (normative), and the four scenarios (Hero Video Display, Theme Switching, Responsiveness, Visual Blending) provide excellent coverage of distinct aspects. Scenarios follow proper #### Scenario: headers and use clear, testable language with theme-aware video selection, responsive scaling, and visual blending well-specified.
examples/with-vite-react/vite.config.ts (2)
11-16: Schema updates correctly leverage new coercion system.The simplified schema definitions (
"number","boolean","unknown") align with the centralized coercion approach. The coercion layer now handles string→primitive conversion automatically based on schema introspection, removing the need for manual parsers.Good use of
number.portbuilt-in validator forPORTas per coding guidelines.
20-20: API signature updated to config object pattern.The change from
arkenv(Env, loadEnv(...))toarkenv(Env, { env: loadEnv(...) })aligns with the refactoredcreateEnvAPI that accepts a config object withenvand optionalcoerceproperties.This matches the pattern used in
packages/vite-plugin/src/index.ts(line 63-65) wherecreateEnvis called with{ env: loadEnv(...) }.apps/playgrounds/vite/vite.config.ts (2)
11-16: Schema definitions correctly simplified with coercion support.The type declarations now leverage the new automatic coercion:
"unknown"accepts any value without transformation"number"and"boolean"trigger automatic string→primitive coercionThis is consistent with
examples/with-vite-react/vite.config.tsand eliminates manual parsing logic.
20-22: API usage and debug logging are appropriate.The updated
arkenv(Env, { env: loadEnv(...) })call follows the new config object pattern. Theconsole.logon line 22 is acceptable per coding guidelines since this is a playground directory—it usefully demonstrates that coercion is working by showing both the value and its runtime type.packages/arkenv/src/utils/coerce.test.ts (8)
1-13: LGTM! Clean test setup and basic coercion test.The imports are appropriate and the first test clearly validates the basic numeric coercion behavior with a straightforward expectation.
15-39: Excellent coverage of numeric refinements.These tests properly validate both successful coercion and validation failures for ranges and divisors, with appropriate error message assertions to ensure user-friendly feedback.
41-53: Good documentation of case-sensitive behavior.The comment on line 49 usefully documents the current implementation's expectation for lowercase "true"/"false", and the test validates this constraint with appropriate error checking.
55-116: Comprehensive coverage of schema variations.Excellent test coverage across optional properties, root-level primitives, strict literals, and mixed unions. The tests validate coercion behavior for diverse schema shapes.
118-157: Strong negative test coverage.These tests appropriately validate that invalid inputs (empty strings, whitespace, non-numeric strings, invalid boolean strings) are properly rejected with clear error messages.
159-198: Good coverage of complex scenarios.The tests validate that coercion works correctly with nested object structures and doesn't interfere with existing ArkType morphs, ensuring compatibility with advanced schema patterns.
200-220: Excellent NaN edge case coverage.These tests properly distinguish between
number.NaN(which accepts NaN) and standardnumber(which rejects NaN), with a helpful comment explaining the coercion-then-validation flow.
235-246: Good validation of type mismatch errors.This test appropriately validates that providing an array when a single value is expected results in a proper validation error after coercion.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
|
Deployment failed with the following error: Learn More: https://vercel.com/yamcodes?upgradeToPro=build-rate-limit |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
openspec/specs/coercion/spec.md
🧰 Additional context used
📓 Path-based instructions (2)
openspec/**/spec.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
openspec/**/spec.md: Include at least one scenario per requirement using #### Scenario: header format with WHEN and THEN bullet points
Use SHALL/MUST for normative requirements rather than should/may unless intentionally non-normative
Files:
openspec/specs/coercion/spec.md
**/*.{ts,tsx,json,md}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use Biome for linting and formatting instead of ESLint and Prettier
Files:
openspec/specs/coercion/spec.md
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use logical grouping for related environment variables in schemas
📚 Learning: 2025-11-24T16:05:17.653Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:17.653Z
Learning: Use `@/openspec/AGENTS.md` to learn spec format and conventions
Applied to files:
openspec/specs/coercion/spec.md
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Applied to files:
openspec/specs/coercion/spec.md
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Ensure change proposals contain delta specs for each affected capability under changes/[change-id]/specs/[capability]/spec.md
Applied to files:
openspec/specs/coercion/spec.md
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: Organize specifications in openspec/specs/[capability]/spec.md with optional design.md for technical patterns
Applied to files:
openspec/specs/coercion/spec.md
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: Applies to openspec/**/spec.md : Use SHALL/MUST for normative requirements rather than should/may unless intentionally non-normative
Applied to files:
openspec/specs/coercion/spec.md
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Applied to files:
openspec/specs/coercion/spec.md
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Applied to files:
openspec/specs/coercion/spec.md
⏰ 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: test-e2e (a11y)
- GitHub Check: test-e2e (e2e)
|
Deployment failed with the following error: Learn More: https://vercel.com/yamcodes?upgradeToPro=build-rate-limit |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
tooling/playwright-www/package.json (1)
20-20: Usecatalog:protocol for@playwright/testconsistency.The
@playwright/testdependency is pinned to"1.57.0"while other devDependencies use thecatalog:protocol. Update to"@playwright/test": "catalog:"to align with the monorepo's dependency management pattern.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (5)
tooling/playwright-www/package.jsontooling/playwright-www/tests/a11y.test.tstooling/playwright-www/tests/docs-navigation.test.tstooling/playwright-www/tests/morphs.test.tstooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
💤 Files with no reviewable changes (1)
- tooling/playwright-www/tests/morphs.test.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
**/*.{ts,tsx}: Prefertypeoverinterfacefor type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverageconsttype parameters for better inference in TypeScript
Use JSDoc comments for public APIs
Use tabs for indentation (configured in Biome)
Use double quotes for strings (configured in Biome)
Organize imports automatically (Biome handles this)
Avoid explicit types when TypeScript can infer them (noInferrableTypeserror)
Useas constwhere appropriate for immutable values (useAsConstAssertionerror)
Don't reassign function parameters (noParameterAssignerror)
Place default parameters last in function signatures (useDefaultParameterLasterror)
Always initialize enum values (useEnumInitializerserror)
Declare one variable per statement (useSingleVarDeclaratorerror)
Avoid unnecessary template literals (noUnusedTemplateLiteralerror)
PreferNumber.parseIntover globalparseInt(useNumberNamespaceerror)
Use kebab-case for TypeScript filenames (e.g.,create-env.ts)
Use camelCase for function names (e.g.,createEnv)
Use PascalCase for type names (e.g.,ArkEnvError)
Use UPPER_SNAKE_CASE for environment variables and constants
Include examples in JSDoc comments when helpful for public APIs
Document complex type logic with JSDoc comments
UseArkEnvErrorfor environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type
**/*.{ts,tsx}: UsecreateEnv(schema)as the main function for validated environment objects, available as the default export
Use built-in validators (host, port, url, email) fromsrc/types.tswhen available instead of custom validation
UseArkEnvErrorfor environment variable errors, not generic errors
Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Use logical grouping for related environment variables in schemas
Use descriptive env...
Files:
tooling/playwright-www/tests/docs-navigation.test.tstooling/playwright-www/tests/a11y.test.tstooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Co-locate tests with components:
Component.tsxnext toComponent.test.tsx
**/*.test.{ts,tsx}: Test individual functions, components, and hooks in isolation with mocked dependencies using the*.test.tsor*.test.tsxsuffix
Mockprocess.envin tests for different scenarios and save/restore original env inbeforeEach/afterEachhooks
Use Vitest'sdescribe/itstructure in test files
Test edge cases including invalid and missing environment variable values
Use Vitest for testing framework
**/*.test.{ts,tsx}: Use Vitest for unit and integration tests
Test individual functions, components, and hooks in isolation with mocked dependencies in unit tests
Unit tests should focus on individual function logic and edge cases, component rendering and props, error handling and validation, and type checking
Unit tests should execute in less than 100ms per test
Mock external dependencies (clipboard, network, etc.) in unit tests
Co-locate unit test files with source files using naming convention: source file → test file (e.g., create-env.ts → create-env.test.ts)
Test component behavior, not aesthetics, and focus on what users can do and what the component guarantees through its API
Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests
Do not test pure styling or CSS classes, library internals (Radix/shadcn), implementation details (hooks, setState, private variables), or visual variants in component tests
Use Testing Library with user-event for real user simulation in component tests
Query by role, name, label, and text (accessibility first) in component tests
Use beforeEach/afterEach for cleanup, not beforeAll/afterAll when possible
Keep tests fast, deterministic, and parallelizable
Mock at component boundaries (network, time, context)
Files:
tooling/playwright-www/tests/docs-navigation.test.tstooling/playwright-www/tests/a11y.test.tstooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
tooling/playwright-www/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
End-to-end tests should be located in
tooling/playwright-www/and test complete user workflows in real browsers with no mocking
tooling/playwright-www/**/*.{ts,tsx}: Use Playwright for end-to-end tests to validate real browser behavior across Chromium, Firefox, and WebKit
End-to-end tests should focus on user-facing behavior, not implementation details
Files:
tooling/playwright-www/tests/docs-navigation.test.tstooling/playwright-www/tests/a11y.test.tstooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
**/*.{ts,tsx,json,md}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use Biome for linting and formatting instead of ESLint and Prettier
Files:
tooling/playwright-www/tests/docs-navigation.test.tstooling/playwright-www/package.jsontooling/playwright-www/tests/a11y.test.tstooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
tooling/*/package.json
📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)
Tooling in tooling/ directory contains development and testing tools that are not published to npm and excluded from changesets
Files:
tooling/playwright-www/package.json
**/package.json
📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)
Use workspace:* protocol for workspace dependencies between packages
Files:
tooling/playwright-www/package.json
{packages,apps,tooling}/**/package.json
📄 CodeRabbit inference engine (.cursor/rules/pnpm.mdc)
When referencing workspace packages in dependencies, use the
workspace:*protocol instead of version numbers
Files:
tooling/playwright-www/package.json
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use logical grouping for related environment variables in schemas
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to tooling/playwright-www/**/*.{ts,tsx} : Use Playwright for end-to-end tests to validate real browser behavior across Chromium, Firefox, and WebKit
Applied to files:
tooling/playwright-www/tests/docs-navigation.test.tstooling/playwright-www/package.jsontooling/playwright-www/tests/a11y.test.tstooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to tooling/playwright-www/**/*.{ts,tsx} : End-to-end tests should focus on user-facing behavior, not implementation details
Applied to files:
tooling/playwright-www/tests/docs-navigation.test.tstooling/playwright-www/package.jsontooling/playwright-www/tests/a11y.test.tstooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to tooling/playwright-www/**/*.{ts,tsx} : End-to-end tests should be located in `tooling/playwright-www/` and test complete user workflows in real browsers with no mocking
Applied to files:
tooling/playwright-www/tests/docs-navigation.test.tstooling/playwright-www/package.jsontooling/playwright-www/tests/a11y.test.tstooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests
Applied to files:
tooling/playwright-www/tests/docs-navigation.test.tstooling/playwright-www/tests/a11y.test.tstooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
📚 Learning: 2025-09-09T17:37:19.650Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 132
File: packages/arkenv/README.md:13-14
Timestamp: 2025-09-09T17:37:19.650Z
Learning: For yamcodes/arkenv project: Runtime support documentation should link to specific examples: Node.js (examples/basic), Bun (examples/with-bun), Vite (examples/with-vite-react-ts).
Applied to files:
tooling/playwright-www/tests/docs-navigation.test.tstooling/playwright-www/tests/a11y.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type
Applied to files:
tooling/playwright-www/tests/docs-navigation.test.ts
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable validation errors
Applied to files:
tooling/playwright-www/tests/docs-navigation.test.ts
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: Applies to tooling/*/package.json : Tooling in tooling/ directory contains development and testing tools that are not published to npm and excluded from changesets
Applied to files:
tooling/playwright-www/package.json
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Test component behavior, not aesthetics, and focus on what users can do and what the component guarantees through its API
Applied to files:
tooling/playwright-www/tests/a11y.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Query by role, name, label, and text (accessibility first) in component tests
Applied to files:
tooling/playwright-www/tests/a11y.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.integration.test.{ts,tsx} : Integration tests should focus on component and hook interactions, function composition and data flow, real dependencies between units, and state synchronization across boundaries
Applied to files:
tooling/playwright-www/tests/a11y.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to packages/vite-plugin/src/**/*.test.ts : Test the Vite plugin using the with-vite-react example as a fixture and validate that the plugin works with real Vite projects
Applied to files:
tooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to packages/vite-plugin/src/**/*.test.ts : Use fixture-based testing pattern for Vite plugin tests by placing fixtures in __fixtures__ directory
Applied to files:
tooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.test.{ts,tsx} : Test edge cases including invalid and missing environment variable values
Applied to files:
tooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.test.{ts,tsx} : Use Vitest for testing framework
Applied to files:
tooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Use Vitest for unit and integration tests
Applied to files:
tooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.test.{ts,tsx} : Use Vitest's `describe`/`it` structure in test files
Applied to files:
tooling/playwright-www/tests/vite-plugin-viteconfig.test.ts
🧬 Code graph analysis (1)
tooling/playwright-www/tests/a11y.test.ts (1)
tooling/playwright-www/tests/morphs.test.ts (10)
test(4-149)page(30-43)page(106-126)page(16-28)page(63-72)page(5-14)page(128-144)page(85-94)page(96-104)page(54-61)
⏰ 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: test-e2e (e2e)
- GitHub Check: test-e2e (a11y)
🔇 Additional comments (3)
tooling/playwright-www/tests/vite-plugin-viteconfig.test.ts (1)
45-45: LGTM! Test assertion correctly updated for new API signature.The test now validates the updated
arkenvinvocation pattern where the second argument is a config object with anenvproperty, aligning with the API changes introduced in this PR.tooling/playwright-www/tests/a11y.test.ts (1)
14-14: LGTM! Route updated to reflect new coercion documentation.The accessibility test route has been correctly updated from the removed morphs page to the new coercion page, aligning with the PR's feature implementation.
tooling/playwright-www/tests/docs-navigation.test.ts (1)
10-10: LGTM! Comprehensive update from morphs to coercion.All references to the morphs documentation page have been consistently updated to coercion across multiple test scenarios:
- Documentation pages list (line 10)
- Navigation flow test (lines 107-108)
- Page title expectations (line 145)
- Console error checking array (line 197)
The changes are thorough and align with the feature migration documented in the PR.
Also applies to: 107-108, 145-145, 197-197
This PR was opened by the [Changesets release](https://github.com/changesets/action) 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 ## arkenv@0.8.0 ### Minor Changes - ### Coercion _[`#569`](#569) [`adaada4`](adaada4) [@yamcodes](https://github.com/yamcodes)_ Introduced **Schema-Directed Coercion**: now, environment variables defined as `number` or `boolean` in your schema are automatically parsed to their correct types. If you want to opt-out of this feature, pass `config.coerce: false` to `createEnv()` (`arkenv()`). Example: ```ts arkenv(schema, { coerce: false }); ``` To learn more about the new coercion system, read [the docs](https://arkenv.js.org/docs/arkenv/coercion). - **BREAKING**: The `createEnv()` function signature has changed to support a configuration object. Instead of `createEnv(schema, env)`, use `createEnv(schema, config)` where `config` includes `env` (`process.env` by default, like before) and the newly added `coerce` option (`true` by default). For example, Vite users might need to update their `vite.config.ts`: ```ts const env = arkenv(Env, { env: loadEnv(mode, process.cwd(), "") }); ``` - **BREAKING**: The custom `boolean` morph has been removed. We now use `arktype`'s standard `boolean` instead, which is coerced when used within `createEnv` / `arkenv`. This is only breaking if you specifically use `boolean` unrelated to `createEnv` / `arkenv` / our plugins and expect it to be coerced. - **BREAKING**: `number.port` is now a strict numeric refinement (0-65535). It no longer parses strings automatically outside of `createEnv` / `arkenv`. This is only breaking if you specifically use `port` unrelated to `createEnv` / `arkenv` / our plugins and expect it to be parsed as a number. ### Patch Changes - #### Fix error formatting _[`#582`](#582) [`674a2ad`](674a2ad) [@aruaycodes](https://github.com/aruaycodes)_ The ArkEnv error message is now formatted better, using correct spacing and removing the `f` prefix. Before: apps/playgrounds/node on main [$] via 🤖 v24.11.1 ❯ ns > node-playground@ start /Users/yamcodes/code/arkenv/apps/playgrounds/node > tsx --env-file .env index.ts /Users/yamcodes/code/arkenv/packages/arkenv/src/create-env.ts:49 throw new ArkEnvError(validatedEnv); ^ f [ArkEnvError]: Errors found while validating environment variables ZED_ENV must be present (was missing) at m (/Users/yamcodes/code/arkenv/packages/arkenv/src/create-env.ts:49:9) at <anonymous> (/Users/yamcodes/code/arkenv/apps/playgrounds/node/index.ts:4:13) at ModuleJob.run (node:internal/modules/esm/module_job:377:25) at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:671:26) at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5) Node.js v24.11.1 ELIFECYCLE Command failed with exit code 1. After: apps/playgrounds/node on improve-error-formatting [$?] via 🤖 v24.11.1 ❯ ns > node-playground@ start /Users/yamcodes/code/arkenv/apps/playgrounds/node > tsx --env-file .env index.ts /Users/yamcodes/code/arkenv/packages/arkenv/src/create-env.ts:49 throw new ArkEnvError(validatedEnv); ^ ArkEnvError: Errors found while validating environment variables ZED_ENV must be present (was missing) at m (/Users/yamcodes/code/arkenv/packages/arkenv/src/create-env.ts:49:9) at <anonymous> (/Users/yamcodes/code/arkenv/apps/playgrounds/node/index.ts:4:13) at ModuleJob.run (node:internal/modules/esm/module_job:377:25) at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:671:26) at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5) Node.js v24.11.1 ELIFECYCLE Command failed with exit code 1. ## @arkenv/bun-plugin@0.0.5 ### Patch Changes <details><summary>Updated 1 dependency</summary> <small> [`adaada4`](adaada4) [`674a2ad`](674a2ad) </small> - `arkenv@0.8.0` </details> ## @arkenv/vite-plugin@0.0.22 ### Patch Changes <details><summary>Updated 1 dependency</summary> <small> [`adaada4`](adaada4) [`674a2ad`](674a2ad) </small> - `arkenv@0.8.0` </details> ## @repo/keywords@0.1.0 ### Minor Changes - #### Simplify keywords for central coercion _[`#569`](#569) [`adaada4`](adaada4) [@yamcodes](https://github.com/yamcodes)_ - **BREAKING**: The `boolean` keyword has been removed. Universal boolean coercion is now handled by the `arkenv` package. - **BREAKING**: The `port` keyword has been changed from a `string -> number` morph to a pure `number` refinement. Numeric coercion is now handled centrally. - Added `maybeParsedNumber` and `maybeParsedBoolean` internal morphs to support central coercion (including specific "NaN" support). ## @repo/scope@0.1.0 ### Minor Changes - #### Align scope with central coercion _[`#569`](#569) [`adaada4`](adaada4) [@yamcodes](https://github.com/yamcodes)_ - **BREAKING**: Removed the custom `boolean` keyword from the root scope. ArkEnv now uses the standard ArkType `boolean` primitive combined with global coercion. - Updated `number.port` to use the new strict numeric refinement, as string parsing is now handled by global coercion. ### Patch Changes <details><summary>Updated 1 dependency</summary> <small> [`adaada4`](adaada4) </small> - `@repo/keywords@0.1.0` </details> ## @repo/types@1.0.0 ### Patch Changes <details><summary>Updated 1 dependency</summary> <small> [`adaada4`](adaada4) </small> - `@repo/scope@0.1.0` </details> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Closes #228
Summary by CodeRabbit
New Features
Breaking Changes
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.