Skip to content

feat(schema): Standard Schema interop and DSL removal#60

Merged
kjanat merged 9 commits into
masterfrom
delete-schema-dsl-56
Jul 17, 2026
Merged

feat(schema): Standard Schema interop and DSL removal#60
kjanat merged 9 commits into
masterfrom
delete-schema-dsl-56

Conversation

@kjanat

@kjanat kjanat commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Summary

  • replace the private template-literal schema DSL with direct JSON Schema definitions, removing about 1,500 lines of parser, runtime validator, and conversion code
  • accept Standard Schema v1 validators through flag.custom() and arg.custom() with inferred output types and no new runtime dependency
  • run sync or async validation after source resolution, including callable validators, array elements, and variadic arguments
  • expose the Standard Schema types publicly and add focused builder, resolution, documentation, and changelog coverage
  • refresh the GH workspace canary/tooling setup and add repository ownership metadata

Why

The internal DSL existed only to build one static definition schema, while consumers could not reuse validators from libraries such as Zod, Valibot, or ArkType. Direct schema objects make the internal path smaller, and Standard Schema interop provides a dependency-free validation boundary without introducing another runtime schema system.

Closes #56.

Validation

  • bun run ci
  • 87 test files and 2,842 tests passed
  • TypeScript, Biome, dprint, generated metadata, VitePress, tsdown, publint, and package type analysis passed

kjanat added 6 commits July 15, 2026 12:42
Define the generated-definition meta-schema directly as JSON Schema,
eliminating an internal parser and converter used only for that constant.
Accept any Standard Schema v1 validator (zod, valibot, arktype) at the
`flag.custom()` / `arg.custom()` boundary. The spec is vendored as types
only, so consumers bring their own validation with no new runtime
dependency.

Validation runs as one async pass in `resolve()` after a value settles
from any source (CLI, env, config, prompt, default); sync and async
validators both work and `parse()` stays synchronous. Failures surface
as `CONSTRAINT_VIOLATED` errors naming the flag/arg.

Also commits staged tooling: drop `@biomejs/biome` for the `biome`
package, refresh `.zed` formatter/LSP settings.
Let the GH canary link the repository package during install, use explicit
workspace-local tool versions, and exercise whole-`import.meta` manifest
anchoring. Refresh the lockfile to capture the resulting toolchain state.
Match the official v1 namespace and options shape, and detect callable
validators before parse functions so conforming libraries work as advertised.
Validate array and variadic elements individually, expose public types, and
cover the behavior in tests and docs.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
dreamcli 638de6b Commit Preview URL

Branch Preview URL
Jul 17 2026, 01:54 PM

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7de81164-2cd1-463e-a068-5edb03fe248e

📥 Commits

Reviewing files that changed from the base of the PR and between 9b5e9a8 and 638de6b.

📒 Files selected for processing (2)
  • src/core/json-schema/index.ts
  • src/core/json-schema/json-schema.test.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout. (8)
  • GitHub Check: static checks
  • GitHub Check: test (node 22.22.2, bun latest)
  • GitHub Check: test (node latest, bun latest)
  • GitHub Check: Publish Preview
  • GitHub Check: Workers Builds: dreamcli
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (actions)
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (6)
src/core/json-schema/**/*.ts

📄 CodeRabbit inference engine (src/core/json-schema/AGENTS.md)

Use @internal JSDoc tags to mark internal APIs; docs and meta-description tooling filter on them

Files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use tabs, single quotes, semicolons, and LF line endings in TypeScript files.
Use import type for type-only imports.
Include .ts extensions in all relative imports.
Use explicit named re-exports; do not use export *.
Do not add runtime dependencies.

Files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.ts: Add @module JSDoc at the top of source files and use @internal to mark non-public APIs.
Keep the public API factory-first, using factories such as cli(), command(), flag.*(), createOutput(), and createAdapter().

Files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Co-locate tests as *.test.ts; use describe() and it(), em dashes in suite titles, and // === and // --- section markers.
Do not use lifecycle hooks, snapshots, or module mocks in tests.
Include a trailing \n in output assertions.

Files:

  • src/core/json-schema/json-schema.test.ts
src/core/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/core/**/*.ts: Keep core code runtime-agnostic; route host I/O through RuntimeAdapter, WriteFn, or ReadFn.
Do not use process.* or other runtime-specific APIs in core code.

Files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
**/*

📄 CodeRabbit inference engine (AGENTS.md)

**/*: Read DISCOVERIES.md before planning, editing, or running task workflows.
Use the repository commands for typechecking, linting, formatting, tests, metadata generation, docs builds, and package builds instead of ad hoc replacements.
Do not replace bun run gh-project:* with ad hoc GitHub project mutations.
Use master, not main, as the CI base branch.

Files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
🧠 Learnings (10)
📚 Learning: 2026-02-11T11:57:27.623Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 3
File: src/core/cli/cli-completion-e2e.test.ts:9-16
Timestamp: 2026-02-11T11:57:27.623Z
Learning: Enforce explicit .ts extensions in all relative imports for TypeScript source files (enabled by allowImportingTsExtensions and noEmit in tsconfig.json). This applies to both static and dynamic imports. For each TypeScript file, update relative import paths to end with .ts (e.g., './utils/helper' -> './utils/helper.ts'). Ensure tooling (linting/eslint rules or a codemod) flags missing extensions and provides a quick fix. This guideline should cover all TypeScript files in the repo, not just a single test or module.

Applied to files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
📚 Learning: 2026-02-12T15:52:24.166Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 4
File: src/core/resolve/resolve-arg-env.test.ts:1-7
Timestamp: 2026-02-12T15:52:24.166Z
Learning: In test files, do not require the module JSDoc tag at the top. This rule applies to all test files, while non-test source files should still require the module tag. Use the pattern **/*.test.{ts,tsx} to cover all test TypeScript test files (adjust if your project uses only .ts tests).

Applied to files:

  • src/core/json-schema/json-schema.test.ts
📚 Learning: 2026-04-02T00:14:17.279Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 7
File: src/core/cli/cli.test.ts:14-14
Timestamp: 2026-04-02T00:14:17.279Z
Learning: In kjanat/dreamcli test files (src/**/*.test.ts), do not flag differences in section separator style between `// ---` and `// ===`. This style is intentionally used by the author for all section levels (including top-level sections) in tests, so separator casing/choice should not be treated as a guideline violation in code review.

Applied to files:

  • src/core/json-schema/json-schema.test.ts
📚 Learning: 2026-04-06T11:25:57.444Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: examples/spinner-progress.ts:2-12
Timestamp: 2026-04-06T11:25:57.444Z
Learning: In this repo, enforce that TypeScript source files under `src/` include the required `module` JSDoc tag (where the project’s lint/review rules expect it). Do not flag missing `module` tags in files under `examples/`, since those are documentation/example scripts (e.g., `examples/*.ts`).

Applied to files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
📚 Learning: 2026-04-06T11:26:11.173Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: examples/json-mode.ts:2-15
Timestamp: 2026-04-06T11:26:11.173Z
Learning: In this repository, `module` JSDoc tags are required for TypeScript source files under `src/` (e.g., `src/**/*.ts`). Runnable demo/example scripts under `examples/` are not part of this requirement and should not be flagged for missing `module`.

Applied to files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
📚 Learning: 2026-04-06T11:28:55.224Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: docs/.vitepress/theme/index.ts:1-16
Timestamp: 2026-04-06T11:28:55.224Z
Learning: In the kjanat/dreamcli repo, enforce the `module` JSDoc tag requirement only for TypeScript source files under `src/` (i.e., `src/**/*.ts`). Do not require `module` for files under `docs/`, including anything in `docs/.vitepress/**`, since those are part of the VitePress docs pipeline.

Applied to files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
📚 Learning: 2026-04-06T11:26:04.030Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: examples/middleware.ts:2-11
Timestamp: 2026-04-06T11:26:04.030Z
Learning: In the kjanat/dreamcli repository, require the `module` JSDoc tag only for library source files under `src/` (e.g., `src/**/*.ts`). Files outside `src/` such as runnable demo/example scripts under `examples/` are not considered source code for this rule and should not be required to include `module`.

Applied to files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
📚 Learning: 2026-04-06T18:24:44.371Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: docs/reference/api.md:8-8
Timestamp: 2026-04-06T18:24:44.371Z
Learning: In the kjanat/dreamcli repo, the explicit type annotation `Readonly<Record<string, string>>` applied to `const` object literals is an intentional documentation/intent pattern. Do not flag it as redundant or unnecessary (e.g., for being inferable) when reviewing TypeScript/TSX files; treat this explicitness as acceptable by design.

Applied to files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
📚 Learning: 2026-04-06T18:40:01.263Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: docs/.vitepress/vite-plugins/source-artifacts.ts:62-83
Timestamp: 2026-04-06T18:40:01.263Z
Learning: For this repository, Windows is explicitly not a supported/targeted platform. During code review, do not raise issues about Windows-specific path separators or normalization differences (e.g., use of `path.sep`, handling forward-slash vs backslash, or `normalize()`-related concerns). These checks should be treated as out-of-scope because the project is intended for Linux/macOS only.

Applied to files:

  • src/core/json-schema/json-schema.test.ts
  • src/core/json-schema/index.ts
📚 Learning: 2026-06-23T16:38:50.547Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 37
File: src/core/output/output.test.ts:76-76
Timestamp: 2026-06-23T16:38:50.547Z
Learning: In this repository’s test files (`*.test.ts`), do not suggest or require em dashes (—) in `describe()` suite titles. When reviewing, treat the suite-title punctuation as a repo-specific convention: do not flag missing/absent em dashes or recommend adding them to `describe(...)` block names.

Applied to files:

  • src/core/json-schema/json-schema.test.ts
🔍 Remote MCP GitHub Grep

Relevant review context

  • Standard Schema success/failure handling is consistent with established integrations: validators call schema["~standard"].validate(value), treat result.issues as failure, and use result.value on success. Async results are awaited.
  • H3’s implementation demonstrates the same async flow and preserves issue details when constructing validation errors.
  • Zod’s tests confirm successful validation returns { value }, while invalid input returns { issues }; this supports the PR’s result-shape assumptions.
  • Callable and object-shaped validators are both used in the ecosystem; langgraphjs documents a Standard Schema type guard and rivetkit consumes validators through ["~standard"].validate. This supports reviewing isStandardSchemaV1 and callable-validator handling specifically.
🔇 Additional comments (2)
src/core/json-schema/index.ts (1)

259-264: LGTM!

Also applies to: 914-1071

src/core/json-schema/json-schema.test.ts (1)

317-317: LGTM!

Also applies to: 805-813, 887-890


📝 Walkthrough

Replace the private template-literal schema DSL with direct JSON Schema meta-schema definitions, deleting the parser/validator/JSON Schema converter code (~1,500 lines) and the DSL tests while keeping the generated dreamcli.schema.json output aligned.

Add fully typed Standard Schema v1 interoperability at the flag.custom() / arg.custom() boundary (sync/async/callable validators), storing validators on schema descriptors, inferring output types from validator types, and running validation after CLI/env/config/prompt/default source resolution (including per-element validation for flag.array(...) and per-item validation for variadic arg.variadic(...)). Standard Schema validation issues are surfaced as CONSTRAINT_VIOLATED errors, and Standard Schema v1 types are publicly exposed with builder/resolution/documentation and changelog coverage.

Refresh GH workspace canary/tooling and repository metadata (e.g., CODEOWNERS/formatting/LSP config) and adjust schema serialization details (e.g., regex pattern metadata as { source, flags }) to keep the definition meta-schema consistent.

Validated with bun run ci (87 test files, 2,842 tests passed).

Walkthrough

This PR adds Standard Schema v1 support to flag.custom() and arg.custom(), including inferred output types, synchronous or asynchronous validation, transformations, and per-element array or variadic validation. Validation runs after value resolution and reports constraint violations. The internal schema DSL is replaced with a direct definition meta-schema object. Public exports, tests, documentation, editor settings, package configuration, and example metadata loading are updated.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Resolver
  participant StandardValidator
  participant ValidationError
  CLI->>Resolver: resolve flags and arguments
  Resolver->>StandardValidator: validate resolved values
  StandardValidator-->>Resolver: transformed values or issues
  Resolver->>ValidationError: aggregate constraint violations
  Resolver-->>CLI: validated result or error
Loading

Possibly related issues

  • KAJ-291: Directly covers Standard Schema v1 interop and removal of the schema-DSL machinery implemented here.

Possibly related PRs

Suggested labels: kind: breaking, area: schema, area: resolve

Poem

Standard schemas aboard,
DSL ghosts walk the plank,
Flags transform and args obey,
Async validators thank,
The resolver rings its bell—
Fixed code makes pirates rank.

🚥 Pre-merge checks | ✅ 9 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Semver Version Bump Validation ⚠️ Warning package.json stayed at 3.0.0-rc.11, yet the PR removes schema-dsl and exported APIs, so the required MAJOR SemVer bump is missing. Update the repo version to a new MAJOR SemVer release in a version file (for example 4.0.0), then rerun the check.
Agents.Md Documentation Updated ⚠️ Warning The PR changes code under multiple directories with AGENTS.md files, but only ./AGENTS.md was updated; the other affected AGENTS files were left untouched. Update the AGENTS.md files for the modified subtrees (e.g. src/core/json-schema, resolve, schema, cli, completion, docs, examples) to match the new behaviour.
✅ Passed checks (9 passed)
Check name Status Explanation
Title check ✅ Passed The title is specific and matches the main changeset, covering Standard Schema interop and schema-dsl removal.
Description check ✅ Passed The description directly matches the schema migration, Standard Schema interop, and supporting docs/tooling changes.
Linked Issues check ✅ Passed It removes schema-dsl, replaces the static meta-schema with JSON objects, and adds fully typed Standard Schema v1 support without a runtime dependency.
Out of Scope Changes check ✅ Passed The supporting docs, changelog, examples, and tooling updates align with the migration work rather than introducing unrelated features.
Docstring Coverage ✅ Passed Docstring coverage is 86.67% which is sufficient. The required threshold is 30.00%.
Release Metadata Sync ✅ Passed package.json and deno.json both declare 3.0.0-rc.11; CHANGELOG latest heading and compare links target the same version.
Runtime Support Sync ✅ Passed No runtime-support edits appear in the PR, and the current support surfaces agree on Node 22.22.2, Bun 1.3, and Deno 2.6.0.
No Generated Docs Artifacts ✅ Passed No changes under docs/.vitepress/dist/ or docs/.vitepress/cache/ appeared in the PR diff.
Changelog Update ✅ Passed CHANGELOG.md is updated under ## [Unreleased] with Added/Changed/Removed entries, and no new version header appears despite source-code changes.
📋 Issue Planner

Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).

View plan for ticket: #56


Comment @coderabbitai help to get the list of available commands.

@socket-security

socket-security Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updateddprint@​0.55.1 ⏵ 0.55.2911007093 +1100
Updatedwrangler@​4.110.0 ⏵ 4.111.099 +110076 -1696 +1100
Updatedtsdown@​0.22.7 ⏵ 0.22.898 +110088 +198 +1100
Updatedknip@​6.26.0 ⏵ 6.27.09910095 +196100
Updated@​biomejs/​biome@​2.5.2 ⏵ 2.5.410010010099100

View full report

@kjanat kjanat self-assigned this Jul 16, 2026
Resolve the repository package by path instead of requiring a globally
registered Bun link, so clean CI runners can install the workspace
without prior machine state.
@pkg-pr-new

pkg-pr-new Bot commented Jul 16, 2026

Copy link
Copy Markdown

Open in StackBlitz

bun add https://pkg.pr.new/@kjanat/dreamcli@60
npm i https://pkg.pr.new/@kjanat/dreamcli@60

commit: 638de6b

@kjanat kjanat added the cr:review Allow CodeRabbit review label Jul 17, 2026
@kjanat
kjanat marked this pull request as ready for review July 17, 2026 11:39
@coderabbitai coderabbitai Bot added area: docs VitePress app, guides, reference pages, and docs UX area: schema Schema builders, schema DSL, and JSON Schema export kind: breaking Breaking API, runtime, or packaging change kind: feature New capability or product enhancement labels Jul 17, 2026
coderabbitai[bot]

This comment was marked as resolved.

Keep generated definitions and their meta-schema aligned for numeric,
string, array, path, and value-hint fields. Add compile-time and runtime
exhaustiveness checks while excluding runtime validators.
@coderabbitai coderabbitai Bot added area: resolve Argv, env, config, prompt, and default resolution and removed area: docs VitePress app, guides, reference pages, and docs UX labels Jul 17, 2026
coderabbitai[bot]

This comment was marked as resolved.

Represent pattern metadata as `{ source, flags }` so generated definitions
retain RegExp semantics. Require both fields in the meta-schema and cover
flagged and unflagged expressions.
@coderabbitai coderabbitai Bot removed the kind: feature New capability or product enhancement label Jul 17, 2026
@kjanat
kjanat merged commit ee46195 into master Jul 17, 2026
19 checks passed
@kjanat
kjanat deleted the delete-schema-dsl-56 branch July 17, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: resolve Argv, env, config, prompt, and default resolution area: schema Schema builders, schema DSL, and JSON Schema export cr:review Allow CodeRabbit review kind: breaking Breaking API, runtime, or packaging change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Standard Schema v1 interop + delete schema-dsl

1 participant