From 746e9c9158e4ef8da62d9b3636147a02dedd3d3b Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Tue, 7 Apr 2026 22:06:02 +0200 Subject: [PATCH 01/21] refactor: convert to Bun workspaces monorepo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Single published package stays intact — no breaking changes. Subpath exports, hash imports, and CI all updated. Layout: packages/dreamcli/ — library (src, build, tests) apps/docs/ — VitePress docs site tools/gh-project/ — project workflow CLI examples/standalone/ — teaching examples examples/gh/ — walkthrough workspace Root orchestrates via `bun run --filter`, catalog centralizes shared dep versions. All 2255 tests, typecheck, lint, format, docs build, and package build pass. --- .dprint.jsonc | 8 +- .github/workflows/ci.yml | 9 +- .github/workflows/docs.yml | 7 +- .github/workflows/pkg-pr-new.yml | 2 +- .github/workflows/publish-jsr.yml | 3 +- .github/workflows/publish-npm.yml | 7 +- .gitignore | 2 +- .zed/settings.json | 10 +- README.md | 498 +---------------- {docs => apps/docs}/.vitepress/AGENTS.md | 0 {docs => apps/docs}/.vitepress/config.ts | 20 +- .../docs}/.vitepress/data/api-index.test.ts | 0 .../docs}/.vitepress/data/api-index.ts | 0 .../.vitepress/data/docs-contract.test.ts | 2 +- .../docs}/.vitepress/data/examples.test.ts | 6 +- .../docs}/.vitepress/data/examples.ts | 0 .../data/meta-schema-descriptions.test.ts | 0 .../data/meta-schema-descriptions.ts | 0 {docs => apps/docs}/.vitepress/data/paths.ts | 13 +- .../docs}/.vitepress/data/reference-model.ts | 0 .../docs}/.vitepress/data/symbol-loader.ts | 0 .../.vitepress/data/symbol-pages.test.ts | 0 .../docs}/.vitepress/data/symbol-pages.ts | 0 .../docs}/.vitepress/data/typedoc.test.ts | 0 .../docs}/.vitepress/data/typedoc.ts | 0 .../theme/components/SettingsGear.vue | 0 .../theme/composables/use-doc-settings.ts | 0 .../theme-sketch-1-brand-forward-dark.svg | 0 .../theme-sketch-1-brand-forward.svg | 0 .../theme-sketch-2-neutral-accents-dark.svg | 0 .../theme-sketch-2-neutral-accents.svg | 0 .../theme-sketch-3-warm-cool-dark.svg | 0 .../explorations/theme-sketch-3-warm-cool.svg | 0 {docs => apps/docs}/.vitepress/theme/index.ts | 0 .../docs}/.vitepress/theme/settings.css | 0 .../.vitepress/theme/twoslash-mobile.css | 0 .../.vitepress/twoslash/testing-fixtures.ts | 2 +- .../docs}/.vitepress/vite-plugins/index.ts | 0 .../vite-plugins/shiki-class-css.ts | 0 .../vite-plugins/shiki-dedupe-popup-styles.ts | 0 .../vite-plugins/shiki-jsdoc-tags.ts | 0 .../vite-plugins/source-artifacts.ts | 13 +- {docs => apps/docs}/AGENTS.md | 0 {docs => apps/docs}/concepts/anatomy.md | 0 {docs => apps/docs}/concepts/errors.md | 0 {docs => apps/docs}/concepts/exit-codes.md | 0 {docs => apps/docs}/concepts/input.md | 0 {docs => apps/docs}/concepts/output.md | 0 {docs => apps/docs}/concepts/testing.md | 16 +- {docs => apps/docs}/examples/[slug].md | 0 {docs => apps/docs}/examples/[slug].paths.ts | 0 {docs => apps/docs}/examples/examples.data.ts | 0 {docs => apps/docs}/examples/index.md | 0 {docs => apps/docs}/guide/arguments.md | 0 {docs => apps/docs}/guide/commands.md | 16 +- {docs => apps/docs}/guide/completions.md | 0 {docs => apps/docs}/guide/config.md | 0 {docs => apps/docs}/guide/errors.md | 0 {docs => apps/docs}/guide/flags.md | 0 {docs => apps/docs}/guide/getting-started.md | 0 {docs => apps/docs}/guide/limitations.md | 0 {docs => apps/docs}/guide/middleware.md | 0 {docs => apps/docs}/guide/migration.md | 0 {docs => apps/docs}/guide/output.md | 0 {docs => apps/docs}/guide/prompts.md | 2 +- {docs => apps/docs}/guide/rationale.md | 0 {docs => apps/docs}/guide/runtime.md | 2 +- {docs => apps/docs}/guide/schema-export.md | 0 {docs => apps/docs}/guide/semantics.md | 0 {docs => apps/docs}/guide/testing.md | 8 +- {docs => apps/docs}/guide/troubleshooting.md | 0 {docs => apps/docs}/guide/walkthrough.md | 0 {docs => apps/docs}/guide/why.md | 0 {docs => apps/docs}/index.md | 0 apps/docs/package.json | 30 + .../docs}/public/animations/loadingbar.svg | 0 .../docs}/public/animations/spinner.svg | 0 {docs => apps/docs}/public/app-icon-192.png | Bin {docs => apps/docs}/public/app-icon-512.png | Bin {docs => apps/docs}/public/app-icon.svg | 0 .../docs}/public/apple-touch-icon.png | Bin {docs => apps/docs}/public/favicon-dark.svg | 0 {docs => apps/docs}/public/favicon.ico | Bin {docs => apps/docs}/public/favicon.svg | 0 .../docs}/public/icons/middleware-dark.svg | 0 .../docs}/public/icons/middleware-light.svg | 0 .../public/icons/resolution-chain-dark.svg | 0 .../public/icons/resolution-chain-light.svg | 0 .../public/icons/structured-output-dark.svg | 0 .../public/icons/structured-output-light.svg | 0 .../docs}/public/icons/test-harness-dark.svg | 0 .../docs}/public/icons/test-harness-light.svg | 0 .../public/icons/type-inference-dark.svg | 0 .../public/icons/type-inference-light.svg | 0 .../docs}/public/icons/zero-deps-dark.svg | 0 .../docs}/public/icons/zero-deps-light.svg | 0 {docs => apps/docs}/public/logo-dark.svg | 0 {docs => apps/docs}/public/logo-light.svg | 0 {docs => apps/docs}/public/manifest.json | 0 {docs => apps/docs}/reference/api.data.ts | 0 {docs => apps/docs}/reference/api.md | 0 {docs => apps/docs}/reference/changelog.md | 2 +- .../reference/example-hover-prototype.md | 0 {docs => apps/docs}/reference/main.md | 0 .../docs}/reference/output-contract.md | 0 .../docs}/reference/planner-contract.md | 0 .../docs}/reference/resolver-contract.md | 0 {docs => apps/docs}/reference/runtime.md | 0 {docs => apps/docs}/reference/schema.md | 0 .../docs}/reference/semantic-delta-log.md | 0 .../docs}/reference/support-matrix.md | 0 .../docs}/reference/symbols/main/[slug].md | 0 .../reference/symbols/main/[slug].paths.ts | 0 .../docs}/reference/symbols/runtime/[slug].md | 0 .../reference/symbols/runtime/[slug].paths.ts | 0 .../docs}/reference/symbols/testkit/[slug].md | 0 .../reference/symbols/testkit/[slug].paths.ts | 0 {docs => apps/docs}/reference/testkit.md | 4 +- apps/docs/tsconfig.json | 16 + apps/docs/vitest.config.ts | 19 + bun.lock | 133 ++++- bunfig.toml | 1 - examples/gh/package.json | 2 +- examples/gh/tsconfig.json | 11 + examples/{ => standalone}/basic.ts | 0 examples/{ => standalone}/interactive.ts | 0 examples/{ => standalone}/json-mode.ts | 0 examples/{ => standalone}/middleware.ts | 0 examples/{ => standalone}/multi-command.ts | 0 examples/standalone/package.json | 14 + examples/{ => standalone}/spinner-progress.ts | 0 examples/{ => standalone}/testing.ts | 0 knip.json | 7 +- note-to-self.ts | 44 -- package.json | 140 +---- .attw.json => packages/dreamcli/.attw.json | 0 .../dreamcli/CHANGELOG.md | 0 packages/dreamcli/LICENSE | 22 + packages/dreamcli/README.md | 511 ++++++++++++++++++ deno.json => packages/dreamcli/deno.json | 17 +- packages/dreamcli/dreamcli.schema.json | 290 ++++++++++ packages/dreamcli/package.json | 107 ++++ .../scripts}/emit-definition-schema.ts | 4 +- .../dreamcli/src}/core/cli/AGENTS.md | 0 .../core/cli/cli-completion-contract.test.ts | 0 .../src}/core/cli/cli-completion-e2e.test.ts | 0 .../src}/core/cli/cli-completions.test.ts | 0 .../dreamcli/src}/core/cli/cli-config.test.ts | 0 .../src}/core/cli/cli-default.test.ts | 0 .../src}/core/cli/cli-dispatch.test.ts | 0 .../dreamcli/src}/core/cli/cli-json.test.ts | 0 .../src}/core/cli/cli-middleware.test.ts | 0 .../src}/core/cli/cli-nesting.test.ts | 0 .../src}/core/cli/cli-package-json.test.ts | 0 .../dreamcli/src}/core/cli/cli-plugin.test.ts | 0 .../src}/core/cli/cli-propagate.test.ts | 0 .../dreamcli/src}/core/cli/cli-tty.test.ts | 0 .../dreamcli/src}/core/cli/cli.test.ts | 0 .../dreamcli/src}/core/cli/dispatch.ts | 0 .../dreamcli/src}/core/cli/index.ts | 0 .../dreamcli/src}/core/cli/planner.test.ts | 0 .../dreamcli/src}/core/cli/planner.ts | 0 .../dreamcli/src}/core/cli/plugin.ts | 0 .../dreamcli/src}/core/cli/propagate.ts | 0 .../dreamcli/src}/core/cli/root-help.ts | 0 .../dreamcli/src}/core/cli/root-surface.ts | 0 .../src}/core/cli/runtime-preflight.test.ts | 0 .../src}/core/cli/runtime-preflight.ts | 0 .../dreamcli/src}/core/completion/AGENTS.md | 0 .../completion/completion-test-helpers.ts | 0 .../src}/core/completion/completion.test.ts | 0 .../dreamcli/src}/core/completion/index.ts | 0 .../src}/core/completion/shells/bash.ts | 0 .../src}/core/completion/shells/fish.ts | 0 .../src}/core/completion/shells/powershell.ts | 0 .../src}/core/completion/shells/shared.ts | 0 .../src}/core/completion/shells/zsh.ts | 0 .../dreamcli/src}/core/config/AGENTS.md | 0 .../dreamcli/src}/core/config/config.test.ts | 0 .../dreamcli/src}/core/config/index.ts | 0 .../src}/core/config/package-json.test.ts | 0 .../dreamcli/src}/core/config/package-json.ts | 0 .../dreamcli/src}/core/errors/errors.test.ts | 0 .../dreamcli/src}/core/errors/index.ts | 0 .../dreamcli/src}/core/execution/index.ts | 0 .../dreamcli/src}/core/help/AGENTS.md | 0 .../dreamcli/src}/core/help/help.test.ts | 0 .../dreamcli/src}/core/help/index.ts | 0 .../dreamcli/src}/core/json-schema/AGENTS.md | 0 .../dreamcli/src}/core/json-schema/index.ts | 0 .../src}/core/json-schema/json-schema.test.ts | 0 .../meta-descriptions.generated.ts | 0 .../dreamcli/src}/core/output/AGENTS.md | 0 .../dreamcli/src}/core/output/activity.ts | 0 .../src}/core/output/contracts.test.ts | 0 .../dreamcli/src}/core/output/contracts.ts | 0 .../src}/core/output/display-value.ts | 0 .../dreamcli/src}/core/output/index.ts | 0 .../output/output-activity-dispatch.test.ts | 0 .../src}/core/output/output-progress.test.ts | 0 .../src}/core/output/output-spinner.test.ts | 0 .../src}/core/output/output-table.test.ts | 0 .../src}/core/output/output-tty.test.ts | 0 .../dreamcli/src}/core/output/output.test.ts | 0 .../dreamcli/src}/core/output/renderers.ts | 0 .../dreamcli/src}/core/output/writer.ts | 0 .../dreamcli/src}/core/parse/AGENTS.md | 0 .../dreamcli/src}/core/parse/index.ts | 0 .../dreamcli/src}/core/parse/parse.test.ts | 0 .../dreamcli/src}/core/prompt/AGENTS.md | 0 .../dreamcli/src}/core/prompt/index.ts | 0 .../dreamcli/src}/core/prompt/prompt.test.ts | 0 .../dreamcli/src}/core/resolve/AGENTS.md | 0 .../dreamcli/src}/core/resolve/args.ts | 0 .../dreamcli/src}/core/resolve/coerce.ts | 0 .../dreamcli/src}/core/resolve/config.ts | 0 .../src}/core/resolve/contracts.test.ts | 0 .../dreamcli/src}/core/resolve/contracts.ts | 0 .../dreamcli/src}/core/resolve/errors.ts | 0 .../dreamcli/src}/core/resolve/flags.ts | 0 .../dreamcli/src}/core/resolve/index.ts | 0 .../src}/core/resolve/property.test.ts | 0 .../dreamcli/src}/core/resolve/property.ts | 0 .../core/resolve/resolve-aggregation.test.ts | 0 .../src}/core/resolve/resolve-arg-env.test.ts | 0 .../src}/core/resolve/resolve-config.test.ts | 0 .../src}/core/resolve/resolve-env.test.ts | 0 .../src}/core/resolve/resolve-errors.test.ts | 0 .../core/resolve/resolve-integration.test.ts | 0 .../core/resolve/resolve-interactive.test.ts | 0 .../src}/core/resolve/resolve-prompt.test.ts | 0 .../src}/core/resolve/resolve-stdin.test.ts | 0 .../src}/core/resolve/resolve.test.ts | 0 .../dreamcli/src}/core/schema-dsl/AGENTS.md | 0 .../dreamcli/src}/core/schema-dsl/index.ts | 0 .../dreamcli/src}/core/schema-dsl/parse.ts | 0 .../dreamcli/src}/core/schema-dsl/runtime.ts | 0 .../src}/core/schema-dsl/schema-dsl.test.ts | 0 .../src}/core/schema-dsl/to-json-schema.ts | 0 .../dreamcli/src}/core/schema/AGENTS.md | 0 .../dreamcli/src}/core/schema/activity.ts | 0 .../dreamcli/src}/core/schema/arg.test.ts | 0 .../dreamcli/src}/core/schema/arg.ts | 0 .../dreamcli/src}/core/schema/command.test.ts | 0 .../dreamcli/src}/core/schema/command.ts | 0 .../dreamcli/src}/core/schema/derive.test.ts | 0 .../dreamcli/src}/core/schema/flag.test.ts | 0 .../dreamcli/src}/core/schema/flag.ts | 0 .../dreamcli/src}/core/schema/index.ts | 0 .../src}/core/schema/middleware.test.ts | 0 .../dreamcli/src}/core/schema/middleware.ts | 0 .../dreamcli/src}/core/schema/prompt.test.ts | 0 .../dreamcli/src}/core/schema/prompt.ts | 0 .../dreamcli/src}/core/schema/run.ts | 0 .../dreamcli/src}/core/testkit/AGENTS.md | 0 .../core/testkit/executor-contract.test.ts | 0 .../dreamcli/src}/core/testkit/index.ts | 0 .../testkit/middleware-context-e2e.test.ts | 0 .../src}/core/testkit/output-e2e.test.ts | 0 .../src}/core/testkit/testkit-json.test.ts | 0 .../src}/core/testkit/testkit-nesting.test.ts | 0 .../src}/core/testkit/testkit-prompt.test.ts | 0 .../src}/core/testkit/testkit-stdin.test.ts | 0 .../src}/core/testkit/testkit-tty.test.ts | 0 .../src}/core/testkit/testkit.test.ts | 0 {src => packages/dreamcli/src}/index.test.ts | 0 {src => packages/dreamcli/src}/index.ts | 0 {src => packages/dreamcli/src}/runtime.ts | 0 .../dreamcli/src}/runtime/AGENTS.md | 0 .../dreamcli/src}/runtime/adapter.ts | 0 .../dreamcli/src}/runtime/auto.test.ts | 0 .../dreamcli/src}/runtime/auto.ts | 0 .../dreamcli/src}/runtime/bun.test.ts | 0 {src => packages/dreamcli/src}/runtime/bun.ts | 0 .../dreamcli/src}/runtime/deno.test.ts | 0 .../dreamcli/src}/runtime/deno.ts | 0 .../dreamcli/src}/runtime/detect.test.ts | 0 .../dreamcli/src}/runtime/detect.ts | 0 .../dreamcli/src}/runtime/index.ts | 0 .../dreamcli/src}/runtime/node-builtins.d.ts | 0 .../dreamcli/src}/runtime/node.ts | 0 .../dreamcli/src}/runtime/paths.ts | 0 .../dreamcli/src}/runtime/runtime.test.ts | 0 .../dreamcli/src}/runtime/support.test.ts | 10 +- .../dreamcli/src}/runtime/support.ts | 0 .../dreamcli/src}/runtime/test-helpers.ts | 0 {src => packages/dreamcli/src}/testkit.ts | 0 {src => packages/dreamcli/src}/version.ts | 0 packages/dreamcli/tsconfig.json | 16 + .../dreamcli/tsdown.config.ts | 2 +- .../dreamcli/vitest.config.ts | 5 +- scripts/build-meta-descriptions.ts | 8 +- scripts/check-version-sync.ts | 20 +- scripts/deno-smoke-test.ts | 6 +- scripts/gh-project.ts | 2 +- scripts/release-meta.sh | 12 +- tools/gh-project/package.json | 30 + .../gh-project/src}/commands/finish.ts | 8 +- .../gh-project/src}/commands/list.ts | 8 +- .../gh-project/src}/commands/set.ts | 4 +- .../gh-project/src}/commands/start.ts | 4 +- .../gh-project/src}/commands/sync.ts | 8 +- .../main.ts => tools/gh-project/src/index.ts | 16 +- .../gh-project/src}/lib/prd.ts | 0 .../gh-project/src}/lib/project.ts | 0 .../gh-project/src}/lib/shared.ts | 0 .../gh-project/src}/lib/types.ts | 0 tools/gh-project/src/main.ts | 11 + tools/gh-project/tsconfig.json | 8 + tsconfig.json | 26 +- wrangler.jsonc | 4 +- 311 files changed, 1412 insertions(+), 816 deletions(-) rename {docs => apps/docs}/.vitepress/AGENTS.md (100%) rename {docs => apps/docs}/.vitepress/config.ts (91%) rename {docs => apps/docs}/.vitepress/data/api-index.test.ts (100%) rename {docs => apps/docs}/.vitepress/data/api-index.ts (100%) rename {docs => apps/docs}/.vitepress/data/docs-contract.test.ts (97%) rename {docs => apps/docs}/.vitepress/data/examples.test.ts (93%) rename {docs => apps/docs}/.vitepress/data/examples.ts (100%) rename {docs => apps/docs}/.vitepress/data/meta-schema-descriptions.test.ts (100%) rename {docs => apps/docs}/.vitepress/data/meta-schema-descriptions.ts (100%) rename {docs => apps/docs}/.vitepress/data/paths.ts (58%) rename {docs => apps/docs}/.vitepress/data/reference-model.ts (100%) rename {docs => apps/docs}/.vitepress/data/symbol-loader.ts (100%) rename {docs => apps/docs}/.vitepress/data/symbol-pages.test.ts (100%) rename {docs => apps/docs}/.vitepress/data/symbol-pages.ts (100%) rename {docs => apps/docs}/.vitepress/data/typedoc.test.ts (100%) rename {docs => apps/docs}/.vitepress/data/typedoc.ts (100%) rename {docs => apps/docs}/.vitepress/theme/components/SettingsGear.vue (100%) rename {docs => apps/docs}/.vitepress/theme/composables/use-doc-settings.ts (100%) rename {docs => apps/docs}/.vitepress/theme/explorations/theme-sketch-1-brand-forward-dark.svg (100%) rename {docs => apps/docs}/.vitepress/theme/explorations/theme-sketch-1-brand-forward.svg (100%) rename {docs => apps/docs}/.vitepress/theme/explorations/theme-sketch-2-neutral-accents-dark.svg (100%) rename {docs => apps/docs}/.vitepress/theme/explorations/theme-sketch-2-neutral-accents.svg (100%) rename {docs => apps/docs}/.vitepress/theme/explorations/theme-sketch-3-warm-cool-dark.svg (100%) rename {docs => apps/docs}/.vitepress/theme/explorations/theme-sketch-3-warm-cool.svg (100%) rename {docs => apps/docs}/.vitepress/theme/index.ts (100%) rename {docs => apps/docs}/.vitepress/theme/settings.css (100%) rename {docs => apps/docs}/.vitepress/theme/twoslash-mobile.css (100%) rename {docs => apps/docs}/.vitepress/twoslash/testing-fixtures.ts (96%) rename {docs => apps/docs}/.vitepress/vite-plugins/index.ts (100%) rename {docs => apps/docs}/.vitepress/vite-plugins/shiki-class-css.ts (100%) rename {docs => apps/docs}/.vitepress/vite-plugins/shiki-dedupe-popup-styles.ts (100%) rename {docs => apps/docs}/.vitepress/vite-plugins/shiki-jsdoc-tags.ts (100%) rename {docs => apps/docs}/.vitepress/vite-plugins/source-artifacts.ts (84%) rename {docs => apps/docs}/AGENTS.md (100%) rename {docs => apps/docs}/concepts/anatomy.md (100%) rename {docs => apps/docs}/concepts/errors.md (100%) rename {docs => apps/docs}/concepts/exit-codes.md (100%) rename {docs => apps/docs}/concepts/input.md (100%) rename {docs => apps/docs}/concepts/output.md (100%) rename {docs => apps/docs}/concepts/testing.md (88%) rename {docs => apps/docs}/examples/[slug].md (100%) rename {docs => apps/docs}/examples/[slug].paths.ts (100%) rename {docs => apps/docs}/examples/examples.data.ts (100%) rename {docs => apps/docs}/examples/index.md (100%) rename {docs => apps/docs}/guide/arguments.md (100%) rename {docs => apps/docs}/guide/commands.md (91%) rename {docs => apps/docs}/guide/completions.md (100%) rename {docs => apps/docs}/guide/config.md (100%) rename {docs => apps/docs}/guide/errors.md (100%) rename {docs => apps/docs}/guide/flags.md (100%) rename {docs => apps/docs}/guide/getting-started.md (100%) rename {docs => apps/docs}/guide/limitations.md (100%) rename {docs => apps/docs}/guide/middleware.md (100%) rename {docs => apps/docs}/guide/migration.md (100%) rename {docs => apps/docs}/guide/output.md (100%) rename {docs => apps/docs}/guide/prompts.md (97%) rename {docs => apps/docs}/guide/rationale.md (100%) rename {docs => apps/docs}/guide/runtime.md (96%) rename {docs => apps/docs}/guide/schema-export.md (100%) rename {docs => apps/docs}/guide/semantics.md (100%) rename {docs => apps/docs}/guide/testing.md (92%) rename {docs => apps/docs}/guide/troubleshooting.md (100%) rename {docs => apps/docs}/guide/walkthrough.md (100%) rename {docs => apps/docs}/guide/why.md (100%) rename {docs => apps/docs}/index.md (100%) create mode 100644 apps/docs/package.json rename {docs => apps/docs}/public/animations/loadingbar.svg (100%) rename {docs => apps/docs}/public/animations/spinner.svg (100%) rename {docs => apps/docs}/public/app-icon-192.png (100%) rename {docs => apps/docs}/public/app-icon-512.png (100%) rename {docs => apps/docs}/public/app-icon.svg (100%) rename {docs => apps/docs}/public/apple-touch-icon.png (100%) rename {docs => apps/docs}/public/favicon-dark.svg (100%) rename {docs => apps/docs}/public/favicon.ico (100%) rename {docs => apps/docs}/public/favicon.svg (100%) rename {docs => apps/docs}/public/icons/middleware-dark.svg (100%) rename {docs => apps/docs}/public/icons/middleware-light.svg (100%) rename {docs => apps/docs}/public/icons/resolution-chain-dark.svg (100%) rename {docs => apps/docs}/public/icons/resolution-chain-light.svg (100%) rename {docs => apps/docs}/public/icons/structured-output-dark.svg (100%) rename {docs => apps/docs}/public/icons/structured-output-light.svg (100%) rename {docs => apps/docs}/public/icons/test-harness-dark.svg (100%) rename {docs => apps/docs}/public/icons/test-harness-light.svg (100%) rename {docs => apps/docs}/public/icons/type-inference-dark.svg (100%) rename {docs => apps/docs}/public/icons/type-inference-light.svg (100%) rename {docs => apps/docs}/public/icons/zero-deps-dark.svg (100%) rename {docs => apps/docs}/public/icons/zero-deps-light.svg (100%) rename {docs => apps/docs}/public/logo-dark.svg (100%) rename {docs => apps/docs}/public/logo-light.svg (100%) rename {docs => apps/docs}/public/manifest.json (100%) rename {docs => apps/docs}/reference/api.data.ts (100%) rename {docs => apps/docs}/reference/api.md (100%) rename {docs => apps/docs}/reference/changelog.md (80%) rename {docs => apps/docs}/reference/example-hover-prototype.md (100%) rename {docs => apps/docs}/reference/main.md (100%) rename {docs => apps/docs}/reference/output-contract.md (100%) rename {docs => apps/docs}/reference/planner-contract.md (100%) rename {docs => apps/docs}/reference/resolver-contract.md (100%) rename {docs => apps/docs}/reference/runtime.md (100%) rename {docs => apps/docs}/reference/schema.md (100%) rename {docs => apps/docs}/reference/semantic-delta-log.md (100%) rename {docs => apps/docs}/reference/support-matrix.md (100%) rename {docs => apps/docs}/reference/symbols/main/[slug].md (100%) rename {docs => apps/docs}/reference/symbols/main/[slug].paths.ts (100%) rename {docs => apps/docs}/reference/symbols/runtime/[slug].md (100%) rename {docs => apps/docs}/reference/symbols/runtime/[slug].paths.ts (100%) rename {docs => apps/docs}/reference/symbols/testkit/[slug].md (100%) rename {docs => apps/docs}/reference/symbols/testkit/[slug].paths.ts (100%) rename {docs => apps/docs}/reference/testkit.md (95%) create mode 100644 apps/docs/tsconfig.json create mode 100644 apps/docs/vitest.config.ts create mode 100644 examples/gh/tsconfig.json rename examples/{ => standalone}/basic.ts (100%) rename examples/{ => standalone}/interactive.ts (100%) rename examples/{ => standalone}/json-mode.ts (100%) rename examples/{ => standalone}/middleware.ts (100%) rename examples/{ => standalone}/multi-command.ts (100%) create mode 100644 examples/standalone/package.json rename examples/{ => standalone}/spinner-progress.ts (100%) rename examples/{ => standalone}/testing.ts (100%) delete mode 100755 note-to-self.ts rename .attw.json => packages/dreamcli/.attw.json (100%) rename CHANGELOG.md => packages/dreamcli/CHANGELOG.md (100%) create mode 100644 packages/dreamcli/LICENSE create mode 100644 packages/dreamcli/README.md rename deno.json => packages/dreamcli/deno.json (86%) create mode 100644 packages/dreamcli/dreamcli.schema.json create mode 100644 packages/dreamcli/package.json rename {scripts => packages/dreamcli/scripts}/emit-definition-schema.ts (92%) rename {src => packages/dreamcli/src}/core/cli/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/cli/cli-completion-contract.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-completion-e2e.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-completions.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-config.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-default.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-dispatch.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-json.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-middleware.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-nesting.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-package-json.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-plugin.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-propagate.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli-tty.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/cli.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/dispatch.ts (100%) rename {src => packages/dreamcli/src}/core/cli/index.ts (100%) rename {src => packages/dreamcli/src}/core/cli/planner.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/planner.ts (100%) rename {src => packages/dreamcli/src}/core/cli/plugin.ts (100%) rename {src => packages/dreamcli/src}/core/cli/propagate.ts (100%) rename {src => packages/dreamcli/src}/core/cli/root-help.ts (100%) rename {src => packages/dreamcli/src}/core/cli/root-surface.ts (100%) rename {src => packages/dreamcli/src}/core/cli/runtime-preflight.test.ts (100%) rename {src => packages/dreamcli/src}/core/cli/runtime-preflight.ts (100%) rename {src => packages/dreamcli/src}/core/completion/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/completion/completion-test-helpers.ts (100%) rename {src => packages/dreamcli/src}/core/completion/completion.test.ts (100%) rename {src => packages/dreamcli/src}/core/completion/index.ts (100%) rename {src => packages/dreamcli/src}/core/completion/shells/bash.ts (100%) rename {src => packages/dreamcli/src}/core/completion/shells/fish.ts (100%) rename {src => packages/dreamcli/src}/core/completion/shells/powershell.ts (100%) rename {src => packages/dreamcli/src}/core/completion/shells/shared.ts (100%) rename {src => packages/dreamcli/src}/core/completion/shells/zsh.ts (100%) rename {src => packages/dreamcli/src}/core/config/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/config/config.test.ts (100%) rename {src => packages/dreamcli/src}/core/config/index.ts (100%) rename {src => packages/dreamcli/src}/core/config/package-json.test.ts (100%) rename {src => packages/dreamcli/src}/core/config/package-json.ts (100%) rename {src => packages/dreamcli/src}/core/errors/errors.test.ts (100%) rename {src => packages/dreamcli/src}/core/errors/index.ts (100%) rename {src => packages/dreamcli/src}/core/execution/index.ts (100%) rename {src => packages/dreamcli/src}/core/help/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/help/help.test.ts (100%) rename {src => packages/dreamcli/src}/core/help/index.ts (100%) rename {src => packages/dreamcli/src}/core/json-schema/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/json-schema/index.ts (100%) rename {src => packages/dreamcli/src}/core/json-schema/json-schema.test.ts (100%) rename {src => packages/dreamcli/src}/core/json-schema/meta-descriptions.generated.ts (100%) rename {src => packages/dreamcli/src}/core/output/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/output/activity.ts (100%) rename {src => packages/dreamcli/src}/core/output/contracts.test.ts (100%) rename {src => packages/dreamcli/src}/core/output/contracts.ts (100%) rename {src => packages/dreamcli/src}/core/output/display-value.ts (100%) rename {src => packages/dreamcli/src}/core/output/index.ts (100%) rename {src => packages/dreamcli/src}/core/output/output-activity-dispatch.test.ts (100%) rename {src => packages/dreamcli/src}/core/output/output-progress.test.ts (100%) rename {src => packages/dreamcli/src}/core/output/output-spinner.test.ts (100%) rename {src => packages/dreamcli/src}/core/output/output-table.test.ts (100%) rename {src => packages/dreamcli/src}/core/output/output-tty.test.ts (100%) rename {src => packages/dreamcli/src}/core/output/output.test.ts (100%) rename {src => packages/dreamcli/src}/core/output/renderers.ts (100%) rename {src => packages/dreamcli/src}/core/output/writer.ts (100%) rename {src => packages/dreamcli/src}/core/parse/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/parse/index.ts (100%) rename {src => packages/dreamcli/src}/core/parse/parse.test.ts (100%) rename {src => packages/dreamcli/src}/core/prompt/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/prompt/index.ts (100%) rename {src => packages/dreamcli/src}/core/prompt/prompt.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/resolve/args.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/coerce.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/config.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/contracts.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/contracts.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/errors.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/flags.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/index.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/property.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/property.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/resolve-aggregation.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/resolve-arg-env.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/resolve-config.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/resolve-env.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/resolve-errors.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/resolve-integration.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/resolve-interactive.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/resolve-prompt.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/resolve-stdin.test.ts (100%) rename {src => packages/dreamcli/src}/core/resolve/resolve.test.ts (100%) rename {src => packages/dreamcli/src}/core/schema-dsl/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/schema-dsl/index.ts (100%) rename {src => packages/dreamcli/src}/core/schema-dsl/parse.ts (100%) rename {src => packages/dreamcli/src}/core/schema-dsl/runtime.ts (100%) rename {src => packages/dreamcli/src}/core/schema-dsl/schema-dsl.test.ts (100%) rename {src => packages/dreamcli/src}/core/schema-dsl/to-json-schema.ts (100%) rename {src => packages/dreamcli/src}/core/schema/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/schema/activity.ts (100%) rename {src => packages/dreamcli/src}/core/schema/arg.test.ts (100%) rename {src => packages/dreamcli/src}/core/schema/arg.ts (100%) rename {src => packages/dreamcli/src}/core/schema/command.test.ts (100%) rename {src => packages/dreamcli/src}/core/schema/command.ts (100%) rename {src => packages/dreamcli/src}/core/schema/derive.test.ts (100%) rename {src => packages/dreamcli/src}/core/schema/flag.test.ts (100%) rename {src => packages/dreamcli/src}/core/schema/flag.ts (100%) rename {src => packages/dreamcli/src}/core/schema/index.ts (100%) rename {src => packages/dreamcli/src}/core/schema/middleware.test.ts (100%) rename {src => packages/dreamcli/src}/core/schema/middleware.ts (100%) rename {src => packages/dreamcli/src}/core/schema/prompt.test.ts (100%) rename {src => packages/dreamcli/src}/core/schema/prompt.ts (100%) rename {src => packages/dreamcli/src}/core/schema/run.ts (100%) rename {src => packages/dreamcli/src}/core/testkit/AGENTS.md (100%) rename {src => packages/dreamcli/src}/core/testkit/executor-contract.test.ts (100%) rename {src => packages/dreamcli/src}/core/testkit/index.ts (100%) rename {src => packages/dreamcli/src}/core/testkit/middleware-context-e2e.test.ts (100%) rename {src => packages/dreamcli/src}/core/testkit/output-e2e.test.ts (100%) rename {src => packages/dreamcli/src}/core/testkit/testkit-json.test.ts (100%) rename {src => packages/dreamcli/src}/core/testkit/testkit-nesting.test.ts (100%) rename {src => packages/dreamcli/src}/core/testkit/testkit-prompt.test.ts (100%) rename {src => packages/dreamcli/src}/core/testkit/testkit-stdin.test.ts (100%) rename {src => packages/dreamcli/src}/core/testkit/testkit-tty.test.ts (100%) rename {src => packages/dreamcli/src}/core/testkit/testkit.test.ts (100%) rename {src => packages/dreamcli/src}/index.test.ts (100%) rename {src => packages/dreamcli/src}/index.ts (100%) rename {src => packages/dreamcli/src}/runtime.ts (100%) rename {src => packages/dreamcli/src}/runtime/AGENTS.md (100%) rename {src => packages/dreamcli/src}/runtime/adapter.ts (100%) rename {src => packages/dreamcli/src}/runtime/auto.test.ts (100%) rename {src => packages/dreamcli/src}/runtime/auto.ts (100%) rename {src => packages/dreamcli/src}/runtime/bun.test.ts (100%) rename {src => packages/dreamcli/src}/runtime/bun.ts (100%) rename {src => packages/dreamcli/src}/runtime/deno.test.ts (100%) rename {src => packages/dreamcli/src}/runtime/deno.ts (100%) rename {src => packages/dreamcli/src}/runtime/detect.test.ts (100%) rename {src => packages/dreamcli/src}/runtime/detect.ts (100%) rename {src => packages/dreamcli/src}/runtime/index.ts (100%) rename {src => packages/dreamcli/src}/runtime/node-builtins.d.ts (100%) rename {src => packages/dreamcli/src}/runtime/node.ts (100%) rename {src => packages/dreamcli/src}/runtime/paths.ts (100%) rename {src => packages/dreamcli/src}/runtime/runtime.test.ts (100%) rename {src => packages/dreamcli/src}/runtime/support.test.ts (87%) rename {src => packages/dreamcli/src}/runtime/support.ts (100%) rename {src => packages/dreamcli/src}/runtime/test-helpers.ts (100%) rename {src => packages/dreamcli/src}/testkit.ts (100%) rename {src => packages/dreamcli/src}/version.ts (100%) create mode 100644 packages/dreamcli/tsconfig.json rename tsdown.config.ts => packages/dreamcli/tsdown.config.ts (96%) rename vitest.config.ts => packages/dreamcli/vitest.config.ts (68%) create mode 100644 tools/gh-project/package.json rename {scripts/gh-project => tools/gh-project/src}/commands/finish.ts (89%) rename {scripts/gh-project => tools/gh-project/src}/commands/list.ts (86%) rename {scripts/gh-project => tools/gh-project/src}/commands/set.ts (88%) rename {scripts/gh-project => tools/gh-project/src}/commands/start.ts (86%) rename {scripts/gh-project => tools/gh-project/src}/commands/sync.ts (91%) rename scripts/gh-project/main.ts => tools/gh-project/src/index.ts (57%) rename {scripts/gh-project => tools/gh-project/src}/lib/prd.ts (100%) rename {scripts/gh-project => tools/gh-project/src}/lib/project.ts (100%) rename {scripts/gh-project => tools/gh-project/src}/lib/shared.ts (100%) rename {scripts/gh-project => tools/gh-project/src}/lib/types.ts (100%) create mode 100755 tools/gh-project/src/main.ts create mode 100644 tools/gh-project/tsconfig.json diff --git a/.dprint.jsonc b/.dprint.jsonc index caa1ea9b..fab85166 100644 --- a/.dprint.jsonc +++ b/.dprint.jsonc @@ -9,11 +9,11 @@ "lineWidth": 100, "quoteStyle": "single", "css.enabled": true, - "associations": ["!README.md", "!docs/**/*.md", "!docs/.vitepress/twoslash/*.ts"] + "associations": ["!README.md", "!apps/docs/**/*.md", "!apps/docs/.vitepress/twoslash/*.ts"] }, "markdown": { "textWrap": "maintain", - "associations": ["!README.md", "!docs/**/*.md", "!docs/.vitepress/twoslash/*.ts"] + "associations": ["!README.md", "!apps/docs/**/*.md", "!apps/docs/.vitepress/twoslash/*.ts"] }, "markup": { "html.void.selfClosing": false, @@ -23,7 +23,7 @@ "vue.scriptIndent": true, "vue.styleIndent": true, "scriptFormatter": "biome", - "associations": ["!README.md", "!docs/**/*.md", "!docs/.vitepress/twoslash/*.ts"] + "associations": ["!README.md", "!apps/docs/**/*.md", "!apps/docs/.vitepress/twoslash/*.ts"] }, "yaml": { "printWidth": 160 }, "svg": { "useTabs": false }, @@ -47,7 +47,7 @@ "tabWidth": 2, "useTabs": false, "endOfLine": "lf", - "associations": ["README.md", "docs/**/*.md", "docs/.vitepress/twoslash/*.ts"] + "associations": ["**/README.md", "**/docs/**/*.md", "**/.vitepress/twoslash/*.ts"] }, "excludes": ["**/node_modules", "**/{*-,bun}lock(.*)?", "**/snapshots"], "plugins": [ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e1abd93..07246500 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: - name: Version sync (package.json ↔ deno.json) run: bun run scripts/check-version-sync.ts - run: bun run typecheck - - run: bun run typecheck:tsc + - run: bun run --filter @kjanat/dreamcli typecheck:tsc - run: bun --cwd examples/gh typecheck - run: bun run meta-descriptions:check - run: bun run lint @@ -65,6 +65,7 @@ jobs: - name: Test (Bun) if: matrix.runtime == 'bun' run: bunx --bun vitest run + working-directory: packages/dreamcli - name: Test walkthrough example (Bun) if: matrix.runtime == 'bun' @@ -74,6 +75,7 @@ jobs: - name: Test (Node ${{ matrix.node-version }}) if: matrix.runtime == 'node' run: npx vitest run + working-directory: packages/dreamcli # ───────────────────────────────────────────────────────────────── # Coverage — single Node floor run with explicit thresholds @@ -92,7 +94,7 @@ jobs: - uses: actions/setup-node@v6 with: { node-version: "latest" } - run: bun install --frozen-lockfile - - run: bun run coverage + - run: bun run --filter @kjanat/dreamcli coverage # ───────────────────────────────────────────────────────────────── # Deno smoke — real runtime proof for the built Deno adapter path @@ -113,8 +115,9 @@ jobs: - run: bun install --frozen-lockfile - run: bun run build - name: Deno adapter smoke test - run: deno run --allow-read --allow-env scripts/deno-smoke-test.ts + run: deno run --config packages/dreamcli/deno.json --allow-read --allow-env scripts/deno-smoke-test.ts - run: deno run -A npm:vitest run + working-directory: packages/dreamcli # ───────────────────────────────────────────────────────────────── # Docs — build docs and assert no source drift diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b13f36e5..2f3fde4a 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -4,11 +4,12 @@ on: push: branches: [master] paths: - - docs/** - - src/** + - apps/docs/** + - packages/dreamcli/src/** - examples/** - scripts/** - package.json + - packages/dreamcli/package.json - tsconfig.json - .github/workflows/docs.yml workflow_dispatch: @@ -36,7 +37,7 @@ jobs: - run: bun run docs:build - uses: actions/upload-pages-artifact@v4 - with: { path: docs/.vitepress/dist } + with: { path: apps/docs/.vitepress/dist } deploy: name: Deploy diff --git a/.github/workflows/pkg-pr-new.yml b/.github/workflows/pkg-pr-new.yml index 31a90f92..9654957e 100644 --- a/.github/workflows/pkg-pr-new.yml +++ b/.github/workflows/pkg-pr-new.yml @@ -28,4 +28,4 @@ jobs: run: bun run build - name: Publish preview - run: bunx pkg-pr-new publish --bun --comment=update --packageManager=bun,npm + run: bunx pkg-pr-new publish ./packages/dreamcli --bun --comment=update --packageManager=bun,npm diff --git a/.github/workflows/publish-jsr.yml b/.github/workflows/publish-jsr.yml index a0eb2e80..00fc3c0f 100644 --- a/.github/workflows/publish-jsr.yml +++ b/.github/workflows/publish-jsr.yml @@ -36,7 +36,8 @@ jobs: - run: bun run scripts/check-version-sync.ts - run: bun --bun run ci - name: Deno adapter smoke test - run: deno run --allow-read --allow-env scripts/deno-smoke-test.ts + run: deno run --config packages/dreamcli/deno.json --allow-read --allow-env scripts/deno-smoke-test.ts - name: Publish to JSR run: deno publish + working-directory: packages/dreamcli diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 4da485fb..ad72164a 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -26,16 +26,17 @@ jobs: - uses: actions/checkout@v6 - uses: oven-sh/setup-bun@v2 - run: bun install --frozen-lockfile - - run: bun scripts/emit-definition-schema.ts - - run: bun run scripts/check-version-sync.ts + - run: bun packages/dreamcli/scripts/emit-definition-schema.ts + - run: bun scripts/check-version-sync.ts - run: bun run build - name: Pack tarball id: pack + working-directory: packages/dreamcli run: echo "tarball=$(bun pm pack --quiet --ignore-scripts | tr -d '[:space:]')" >> "${GITHUB_OUTPUT}" - uses: actions/upload-artifact@v7 with: name: tarball - path: ${{ steps.pack.outputs.tarball }} + path: packages/dreamcli/${{ steps.pack.outputs.tarball }} retention-days: 1 publish: diff --git a/.gitignore b/.gitignore index cf94ac9a..602b27e7 100644 --- a/.gitignore +++ b/.gitignore @@ -228,6 +228,6 @@ $RECYCLE.BIN/ /_*.ts /*example*.ts .codex -/dreamcli.schema.json + /.bucket/ .playwright-mcp/ diff --git a/.zed/settings.json b/.zed/settings.json index 9234e383..a02686b2 100644 --- a/.zed/settings.json +++ b/.zed/settings.json @@ -8,7 +8,11 @@ "wrap_guides": [100], "file_types": { "Markdown": ["LICENSE"] }, "prettier": { "allowed": false }, - "formatter": [{ "language_server": { "name": "dprint" } }], + "formatter": [ + { "language_server": { "name": "dprint" } }, + // Fallback to the dprint CLI in case the lsp fucks up, which it does sometimes for some reason... + { "external": { "command": "dprint", "arguments": ["fmt", "--stdin", "{buffer_path}"] } } + ], "languages": { "JavaScript": { "code_actions_on_format": { @@ -37,9 +41,9 @@ }, "dprint": { "binary": { - "path": "node_modules/.bin/dprint", + "path": "bunx", "ignore_system_version": false, - "arguments": ["lsp"] + "arguments": ["dprint", "lsp"] } }, "json-language-server": { diff --git a/README.md b/README.md index fa8da6a3..35eebfac 100644 --- a/README.md +++ b/README.md @@ -1,498 +1,27 @@ # dreamcli +Monorepo for [@kjanat/dreamcli](https://www.npmjs.com/package/@kjanat/dreamcli) — a schema-first, fully typed TypeScript CLI framework. + [![NPM](https://img.shields.io/npm/v/@kjanat/dreamcli?logo=npm&labelColor=CB3837&color=black)][npm] [![JSR](https://img.shields.io/jsr/v/@kjanat/dreamcli?logoColor=083344&logo=jsr&logoSize=auto&label=&labelColor=f7df1e&color=black)][jsr] -Schema-first, fully typed TypeScript CLI framework. Zero runtime dependencies. - -One flag declaration configures the entire resolution pipeline: - -```ts -import { - cli, - command, - flag, - arg, - middleware, - CLIError, -} from '@kjanat/dreamcli'; - -const deploy = command('deploy') - .description('Deploy to an environment') - .arg('target', arg.string().describe('Deploy target')) - .flag( - 'region', - flag - .enum(['us', 'eu', 'ap']) - .alias('r') - .env('DEPLOY_REGION') - .config('deploy.region') - .prompt({ kind: 'select', message: 'Which region?' }) - .default('us') - .propagate(), - ) - .action(({ args, flags, out }) => { - out.log(`Deploying ${args.target} to ${flags.region}`); - }); -``` - -By the time `action` runs, `flags.region` is `"us" | "eu" | "ap"` — not `string | undefined`. - -The value is resolved through a documented chain: **CLI → env → config → interactive prompt → -default**. Every step is opt-in. Every step preserves types. +## Packages -## Install +| Package | Description | +| --------------------------------------- | ------------------------------------------ | +| [`@kjanat/dreamcli`](packages/dreamcli) | Core CLI framework | +| [`@kjanat/dreamcli-docs`](apps/docs) | Documentation site ([dreamcli.kjanat.com]) | -```bash -npm install @kjanat/dreamcli -``` - -
bun/deno +## Development ```bash -bun add @kjanat/dreamcli -``` - -```bash -deno add jsr:@kjanat/dreamcli # or npm:@kjanat/dreamcli -``` - -
- -## Quick start - -### Single command - -```ts -import { command, flag, arg } from '@kjanat/dreamcli'; - -const greet = command('greet') - .description('Greet someone') - .arg('name', arg.string().describe('Who to greet')) - .flag( - 'loud', - flag - .boolean() - .alias('l') - .describe('Shout the greeting'), - ) - .flag( - 'times', - flag.number().default(1).describe('Repeat count'), - ) - .action(({ args, flags, out }) => { - for (let i = 0; i < flags.times; i++) { - const msg = `Hello, ${args.name}!`; - out.log(flags.loud ? msg.toUpperCase() : msg); - } - }); - -greet.run(); -``` - -### Multi-command CLI - -```ts -import { - cli, - command, - group, - flag, - arg, -} from '@kjanat/dreamcli'; - -const deploy = command('deploy') - .description('Deploy to an environment') - .arg('target', arg.string()) - .flag('force', flag.boolean().alias('f')) - .flag( - 'region', - flag.enum(['us', 'eu', 'ap']).env('DEPLOY_REGION'), - ) - .action(({ args, flags, out }) => { - out.log( - `Deploying ${args.target} to ${flags.region ?? 'default'}`, - ); - }); - -const login = command('login') - .description('Authenticate with the service') - .flag('token', flag.string().describe('Auth token')) - .action(({ flags, out }) => { - out.log( - flags.token - ? 'Authenticated via token' - : 'Authenticated interactively', - ); - }); - -// Nested command groups -const migrate = command('migrate') - .description('Run migrations') - .flag('steps', flag.number()) - .action(({ flags, out }) => { - out.log(`migrating ${flags.steps ?? 'all'} steps`); - }); - -const seed = command('seed') - .description('Seed database') - .action(({ out }) => { - out.log('seeding'); - }); - -const db = group('db') - .description('Database operations') - .command(migrate) - .command(seed); - -cli('mycli') - .version('1.0.0') - .description('My awesome tool') - .command(deploy) - .command(login) - .command(db) - .run(); - -// mycli deploy production --force -// mycli login --token abc123 -// mycli db migrate --steps 3 -// mycli db seed -``` - -## Why dreamcli - -Most TypeScript CLI frameworks treat the type system like decoration. -You define flags in one place, then use parsed values somewhere else as a loosely typed blob. -Env vars, config files, and interactive prompts live in separate universes. -Testing means hacking `process.argv`. - -dreamcli collapses all of that into a single typed schema: - -Approximate comparison of first-party, built-in support as documented by each project. -Third-party plugins and custom glue can extend the other libraries. - -| Capability | dreamcli | Commander | Yargs | Citty | CAC | Cleye | -| ------------------------------------------ | ------------------------------------- | ------------------- | ---------------------- | --------------- | ------------- | ------------- | -| Type inference from definition | Full — flags, args, context | Manual `.opts()` | Good | Good | Basic | Good | -| Built-in value sources | CLI, env, config, prompt, default | CLI, defaults, env | CLI, env, config | CLI, defaults | CLI, defaults | CLI, defaults | -| Schema-driven prompts | Integrated | No | No | No | No | No | -| Middleware / hooks | Yes — typed middleware | Lifecycle hooks | Middleware | Plugins / hooks | Events | No | -| Built-in test harness with output capture | `runCommand()` + capture | No | No | No | No | No | -| Shell completions from command definitions | Built-in (bash/zsh/fish/powershell) | No | Built-in (bash/zsh) | No | No | No | -| Structured output primitives | Built-in (`--json`, tables, spinners) | DIY | DIY | DIY | DIY | DIY | -| Config file support | Built-in (XDG discovery, JSON) | DIY | Built-in (`.config()`) | No | No | No | - -The closest analog is what tRPC did to API routes — individual pieces existed, -the insight was wiring them so types flow end-to-end. - -## Features - -### Flag types - -```ts -flag.string(); // string | undefined -flag.number(); // number | undefined -flag.boolean(); // boolean (defaults to false) -flag.enum(['us', 'eu', 'ap']); // "us" | "eu" | "ap" | undefined -flag.array(flag.string()); // string[] | undefined -flag.custom((v) => new URL(v)); // URL | undefined -``` - -Every flag supports: `.default()`, `.required()`, `.alias()`, `.env()`, `.config()`, `.describe()`, -`.prompt()`, `.deprecated()`, `.propagate()`. - -### Resolution chain - -Each flag resolves through an ordered pipeline. Every step is opt-in: - -```text -CLI argv → environment variable → config file → interactive prompt → default value -``` - -Required flags that don't resolve produce a structured error before the action handler runs. In -non-interactive contexts (CI, piped stdin), prompts are automatically skipped. - -### Interactive prompts - -Four prompt types, declared per-flag or per-command: - -```ts -// Per-flag -flag.string().prompt({ kind: 'input', message: 'Name?' }); -flag - .boolean() - .prompt({ kind: 'confirm', message: 'Sure?' }); -flag - .enum(['a', 'b']) - .prompt({ kind: 'select', message: 'Pick one' }); -flag.array(flag.string()).prompt({ - kind: 'multiselect', - message: 'Pick many', - choices: [{ value: 'a' }, { value: 'b' }], -}); - -// Per-command (conditional — receives partially resolved flags) -command('deploy') - .flag('region', flag.enum(['us', 'eu', 'ap'])) - .interactive(({ flags }) => ({ - region: !flags.region && { - kind: 'select', - message: 'Which region?', - }, - })); -``` - -### Derive typed context from resolved input - -```ts -import { CLIError } from '@kjanat/dreamcli'; - -command('deploy') - .flag('token', flag.string().env('AUTH_TOKEN')) - .derive(({ flags }) => { - if (!flags.token) - throw new CLIError('Not authenticated', { - code: 'AUTH_REQUIRED', - suggest: 'Run `mycli login`', - }); - return { token: flags.token }; - }) - .action(({ ctx }) => { - ctx.token; // string — typed - }); +bun install +bun run ci # full check suite +bun run dev # build watch + docs dev server +bun run test # tests across all workspaces +bun run docs:dev # docs dev server only ``` -Use `derive()` when you need typed, command-scoped access to fully resolved flags and args before -the action handler runs. - -### Middleware with typed context - -```ts -import { middleware } from '@kjanat/dreamcli'; - -const timing = middleware<{ startTime: number }>( - async ({ next }) => { - const startTime = Date.now(); - await next({ startTime }); - }, -); - -const trace = middleware<{ traceId: string }>( - async ({ next }) => - next({ traceId: crypto.randomUUID() }), -); - -command('deploy') - .middleware(timing) - .middleware(trace) - .action(({ ctx }) => { - ctx.startTime; // number — typed - ctx.traceId; // string — typed - }); -``` - -Context accumulates through the middleware chain via type intersection. -No manual interface merging. - -Use middleware when you need wrapper behavior with `next()`. - -### Output channel - -Handlers receive `out` instead of `console`. Adapts to context automatically: - -```ts -cli('mycli') - // ... omitted for brevity - .action(({ out }) => { - out.log('Human-readable message'); - out.json({ status: 'ok', count: 42 }); - out.table(rows, [ - { key: 'name', header: 'Name' }, - { key: 'status', header: 'Status' }, - ]); - - const spinner = out.spinner('Deploying...'); - spinner.succeed('Done'); - - const progress = out.progress({ - label: 'Uploading', - total: 100, - }); - progress.update(50); - progress.done('Upload complete'); - }); -``` - -- TTY → pretty formatting, spinners animate -- Piped → minimal stable output, spinners suppressed -- `--json` → structured JSON to stdout, everything else to stderr - -### Shell completions - -Generated from the command schema — always in sync: - -```ts -import { generateCompletion } from '@kjanat/dreamcli'; - -generateCompletion(myCli.schema, 'bash'); -generateCompletion(myCli.schema, 'zsh'); -``` - -### Config file discovery - -```ts -command('deploy').flag( - 'region', - flag.enum(['us', 'eu']).config('deploy.region'), -); -``` - -Searches XDG-standard paths automatically. JSON built-in, plugin hook for YAML/TOML: - -```ts -import { configFormat } from '@kjanat/dreamcli'; -import { parse as parseYAML } from 'yaml'; - -cli('mycli') - .config('mycli') - .configLoader(configFormat(['yaml', 'yml'], parseYAML)); -``` - -### Structured errors - -```ts -throw new CLIError('Deployment failed', { - code: 'DEPLOY_FAILED', - exitCode: 1, - suggest: 'Check your credentials with `mycli login`', - details: { target, region }, -}); -``` - -Parse and validation errors include "did you mean?" suggestions.\ -In `--json` mode, errors serialize to machine-readable JSON. - -## Testing - -`dreamcli`'s test harness runs commands in-process with full control over inputs and outputs. No -subprocesses, no `process.argv` mutation, no mocking. - -```ts -import { arg, command, flag } from '@kjanat/dreamcli'; -import { - runCommand, - createTestPrompter, - PROMPT_CANCEL, -} from '@kjanat/dreamcli/testkit'; - -const greet = command('greet') - .arg('name', arg.string()) - .flag('loud', flag.boolean()) - .action(({ args, flags, out }) => { - const message = `Hello, ${args.name}!`; - out.log(flags.loud ? message.toUpperCase() : message); - }); - -const deploy = command('deploy') - .arg('target', arg.string()) - .flag( - 'region', - flag - .enum(['us', 'eu', 'ap']) - .env('DEPLOY_REGION') - .config('deploy.region') - .required() - .prompt({ kind: 'select', message: 'Which region?' }), - ) - .action(({ args, flags, out }) => { - out.log(`Deploying ${args.target} to ${flags.region}`); - }); - -const build = command('build').action(({ out }) => { - const spinner = out.spinner('Building'); - spinner.succeed('Done'); -}); - -// Basic execution -const basic = await runCommand(greet, ['Alice', '--loud']); - -expect(basic.exitCode).toBe(0); -expect(basic.stdout).toEqual(['HELLO, ALICE!\n']); -expect(basic.stderr).toEqual([]); -expect(basic.error).toBeUndefined(); - -// Resolve from environment -const fromEnv = await runCommand(deploy, ['production'], { - env: { DEPLOY_REGION: 'eu' }, -}); -expect(fromEnv.stdout).toEqual([ - 'Deploying production to eu\n', -]); - -// Resolve from config -const fromConfig = await runCommand( - deploy, - ['production'], - { - config: { deploy: { region: 'us' } }, - }, -); -expect(fromConfig.stdout).toEqual([ - 'Deploying production to us\n', -]); - -// Resolve from prompt answers -const fromPrompt = await runCommand( - deploy, - ['production'], - { - answers: ['ap'], - }, -); -expect(fromPrompt.stdout).toEqual([ - 'Deploying production to ap\n', -]); - -// Simulate prompt cancellation -const cancelled = await runCommand(deploy, ['production'], { - prompter: createTestPrompter([PROMPT_CANCEL]), -}); -expect(cancelled.exitCode).not.toBe(0); - -// Activity events (spinners, progress) -const activity = await runCommand(build, []); -expect(activity.activity).toContainEqual( - expect.objectContaining({ type: 'spinner:start' }), -); -``` - -`RunOptions` accepts: `env`, `config`, `stdinData`, `answers`, `prompter`, `help`, `jsonMode`, -`verbosity`, and `isTTY`. Every dimension of command behavior is controllable from tests. - -## Package structure - -Three subpath exports, each with a focused API surface: - -| Import | Purpose | -| -------------------------- | -------------------------------------------------------------------------------------- | -| `@kjanat/dreamcli` | Schema builders, CLI runner, output, parsing, resolution, errors | -| `@kjanat/dreamcli/testkit` | `runCommand()`, `createCaptureOutput()`, `createTestPrompter()`, `createTestAdapter()` | -| `@kjanat/dreamcli/runtime` | `createAdapter()`, `RuntimeAdapter`, runtime detection, platform adapters | - -ESM-only. Source included in package (`src/`). - -## Runtime support - -| Runtime | Status | -| ------------------ | ----------------------------------- | -| Node.js >= 22.22.2 | Supported | -| Bun >= 1.3.11 | Supported | -| Deno >= 2.6.0 | Supported (JSR: `@kjanat/dreamcli`) | - -Runtime detection is automatic. -The core framework never imports platform-specific APIs directly — a thin `RuntimeAdapter` interface -handles the divergent edges (argv, env, filesystem, TTY detection, exit behavior). - ## License [MIT][LICENSE] © 2026 Kaj Kowalski @@ -500,3 +29,4 @@ handles the divergent edges (argv, env, filesystem, TTY detection, exit behavior [LICENSE]: https://github.com/kjanat/dreamcli/blob/master/LICENSE [npm]: https://npm.im/@kjanat/dreamcli [jsr]: https://jsr.io/@kjanat/dreamcli +[dreamcli.kjanat.com]: https://dreamcli.kjanat.com diff --git a/docs/.vitepress/AGENTS.md b/apps/docs/.vitepress/AGENTS.md similarity index 100% rename from docs/.vitepress/AGENTS.md rename to apps/docs/.vitepress/AGENTS.md diff --git a/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts similarity index 91% rename from docs/.vitepress/config.ts rename to apps/docs/.vitepress/config.ts index 7ee6ae3a..7fcbb553 100644 --- a/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -3,8 +3,9 @@ import { env } from 'node:process'; import { transformerTwoslash } from '@shikijs/vitepress-twoslash'; import { ModuleDetectionKind, ModuleKind, ModuleResolutionKind } from 'typescript'; import { defineConfig } from 'vitepress'; -import pkg from '../../package.json' with { type: 'json' }; -import tsc from '../../tsconfig.json' with { type: 'json' }; +import pkg from '@kjanat/dreamcli/package.json' with { type: 'json' }; +import pkgTsc from '../../../packages/dreamcli/tsconfig.json' with { type: 'json' }; +import baseTsc from '../../../tsconfig.json' with { type: 'json' }; import { collectPublicApiIndex } from './data/api-index.ts'; import { collectExampleMeta } from './data/examples.ts'; import { examplesRoot, packageJsonPath } from './data/paths.ts'; @@ -16,7 +17,8 @@ import { import { dreamcliDocsPlugin, shikiClasses } from './vite-plugins'; import { fixTsProcessedLinkcode, transformerJSDocTags } from './vite-plugins/shiki-jsdoc-tags.ts'; -const projectRoot = normalize(`${import.meta.dirname}/../..`); +const projectRoot = normalize(`${import.meta.dirname}/../../..`); +const packageRoot = normalize(`${projectRoot}/packages/dreamcli`); const exampleMeta = await collectExampleMeta(examplesRoot); const apiIndex = await collectPublicApiIndex(packageJsonPath); const symbolRoutes = new Map(); @@ -44,16 +46,16 @@ const ifCI = (ifCiThen: string, ifNotCiThen: string) => (isCI ? ifCiThen : ifNot const isGithubActions = Boolean(env.GITHUB_ACTIONS); const compilerOptions = { - baseUrl: projectRoot, - lib: tsc.compilerOptions?.lib ?? ['ESNext'], - paths: tsc.compilerOptions?.paths ?? {}, + baseUrl: packageRoot, + lib: baseTsc.compilerOptions?.lib ?? ['ESNext'], + paths: pkgTsc.compilerOptions?.paths ?? {}, moduleDetection: ModuleDetectionKind.Force, module: ModuleKind.ESNext, moduleResolution: ModuleResolutionKind.Bundler, - allowImportingTsExtensions: tsc.compilerOptions?.allowImportingTsExtensions, + allowImportingTsExtensions: baseTsc.compilerOptions?.allowImportingTsExtensions, noEmit: true, - resolveJsonModule: tsc.compilerOptions?.resolveJsonModule, - types: [...(tsc.compilerOptions?.types ?? []), 'vitest/globals'], + resolveJsonModule: baseTsc.compilerOptions?.resolveJsonModule, + types: [...(pkgTsc.compilerOptions?.types ?? []), 'vitest/globals'], }; const links = { diff --git a/docs/.vitepress/data/api-index.test.ts b/apps/docs/.vitepress/data/api-index.test.ts similarity index 100% rename from docs/.vitepress/data/api-index.test.ts rename to apps/docs/.vitepress/data/api-index.test.ts diff --git a/docs/.vitepress/data/api-index.ts b/apps/docs/.vitepress/data/api-index.ts similarity index 100% rename from docs/.vitepress/data/api-index.ts rename to apps/docs/.vitepress/data/api-index.ts diff --git a/docs/.vitepress/data/docs-contract.test.ts b/apps/docs/.vitepress/data/docs-contract.test.ts similarity index 97% rename from docs/.vitepress/data/docs-contract.test.ts rename to apps/docs/.vitepress/data/docs-contract.test.ts index 0cfb3826..7ab9e606 100644 --- a/docs/.vitepress/data/docs-contract.test.ts +++ b/apps/docs/.vitepress/data/docs-contract.test.ts @@ -67,7 +67,7 @@ describe('docs contracts', () => { const [migration, runtime, readme, testingGuide, testkitReference] = await Promise.all([ readUtf8(new URL('../../guide/migration.md', import.meta.url)), readUtf8(new URL('../../guide/runtime.md', import.meta.url)), - readUtf8(new URL('../../../README.md', import.meta.url)), + readUtf8(new URL('../../../../packages/dreamcli/README.md', import.meta.url)), readUtf8(new URL('../../guide/testing.md', import.meta.url)), readUtf8(new URL('../../reference/testkit.md', import.meta.url)), ]); diff --git a/docs/.vitepress/data/examples.test.ts b/apps/docs/.vitepress/data/examples.test.ts similarity index 93% rename from docs/.vitepress/data/examples.test.ts rename to apps/docs/.vitepress/data/examples.test.ts index bcf94c00..bcac6c99 100644 --- a/docs/.vitepress/data/examples.test.ts +++ b/apps/docs/.vitepress/data/examples.test.ts @@ -30,8 +30,8 @@ describe('example docs generation', () => { const basic = examples.find((example) => example.slug === 'basic'); expect(basic).toMatchObject({ routePath: '/examples/basic', - sourcePath: 'examples/basic.ts', - sourceUrl: `https://github.com/kjanat/dreamcli/blob/${gitRef}/examples/basic.ts`, + sourcePath: 'examples/standalone/basic.ts', + sourceUrl: `https://github.com/kjanat/dreamcli/blob/${gitRef}/examples/standalone/basic.ts`, }); expect(basic?.relatedSymbols).toContainEqual({ entrypoint: '@kjanat/dreamcli', @@ -54,7 +54,7 @@ describe('example docs generation', () => { const page = renderExamplePage(example); expect(page).toContain('# Basic single-command CLI.'); expect(page).toContain( - `- Source: [\`examples/basic.ts\`](https://github.com/kjanat/dreamcli/blob/${gitRef}/examples/basic.ts)`, + `- Source: [\`examples/standalone/basic.ts\`](https://github.com/kjanat/dreamcli/blob/${gitRef}/examples/standalone/basic.ts)`, ); expect(page).toContain('## Usage'); expect(page).toContain('npx tsx examples/basic.ts Alice --loud --times 3'); diff --git a/docs/.vitepress/data/examples.ts b/apps/docs/.vitepress/data/examples.ts similarity index 100% rename from docs/.vitepress/data/examples.ts rename to apps/docs/.vitepress/data/examples.ts diff --git a/docs/.vitepress/data/meta-schema-descriptions.test.ts b/apps/docs/.vitepress/data/meta-schema-descriptions.test.ts similarity index 100% rename from docs/.vitepress/data/meta-schema-descriptions.test.ts rename to apps/docs/.vitepress/data/meta-schema-descriptions.test.ts diff --git a/docs/.vitepress/data/meta-schema-descriptions.ts b/apps/docs/.vitepress/data/meta-schema-descriptions.ts similarity index 100% rename from docs/.vitepress/data/meta-schema-descriptions.ts rename to apps/docs/.vitepress/data/meta-schema-descriptions.ts diff --git a/docs/.vitepress/data/paths.ts b/apps/docs/.vitepress/data/paths.ts similarity index 58% rename from docs/.vitepress/data/paths.ts rename to apps/docs/.vitepress/data/paths.ts index 48d6b597..86659fce 100644 --- a/docs/.vitepress/data/paths.ts +++ b/apps/docs/.vitepress/data/paths.ts @@ -7,15 +7,16 @@ import { execSync } from 'node:child_process'; import { normalize } from 'node:path/posix'; -const rootDir = normalize(`${import.meta.dirname}/../../..`); +const rootDir = normalize(`${import.meta.dirname}/../../../..`); export const rootDirPath = rootDir; -export const docsRoot = `${rootDir}/docs`; -export const examplesRoot = `${rootDir}/examples`; -export const packageJsonPath = `${rootDir}/package.json`; -export const tsconfigPath = `${rootDir}/tsconfig.json`; +export const docsRoot = `${rootDir}/apps/docs`; +export const examplesRoot = `${rootDir}/examples/standalone`; +export const packageRoot = `${rootDir}/packages/dreamcli`; +export const packageJsonPath = `${packageRoot}/package.json`; +export const tsconfigPath = `${packageRoot}/tsconfig.json`; export const symbolPagesRoot = `${docsRoot}/reference/symbols`; -export const generatedMetaSchemaDescriptionsPath = `${rootDir}/src/core/json-schema/meta-descriptions.generated.ts`; +export const generatedMetaSchemaDescriptionsPath = `${packageRoot}/src/core/json-schema/meta-descriptions.generated.ts`; /** Git ref for source links. Env override: `DOCS_GIT_REF`. */ export const gitRef: string = (() => { diff --git a/docs/.vitepress/data/reference-model.ts b/apps/docs/.vitepress/data/reference-model.ts similarity index 100% rename from docs/.vitepress/data/reference-model.ts rename to apps/docs/.vitepress/data/reference-model.ts diff --git a/docs/.vitepress/data/symbol-loader.ts b/apps/docs/.vitepress/data/symbol-loader.ts similarity index 100% rename from docs/.vitepress/data/symbol-loader.ts rename to apps/docs/.vitepress/data/symbol-loader.ts diff --git a/docs/.vitepress/data/symbol-pages.test.ts b/apps/docs/.vitepress/data/symbol-pages.test.ts similarity index 100% rename from docs/.vitepress/data/symbol-pages.test.ts rename to apps/docs/.vitepress/data/symbol-pages.test.ts diff --git a/docs/.vitepress/data/symbol-pages.ts b/apps/docs/.vitepress/data/symbol-pages.ts similarity index 100% rename from docs/.vitepress/data/symbol-pages.ts rename to apps/docs/.vitepress/data/symbol-pages.ts diff --git a/docs/.vitepress/data/typedoc.test.ts b/apps/docs/.vitepress/data/typedoc.test.ts similarity index 100% rename from docs/.vitepress/data/typedoc.test.ts rename to apps/docs/.vitepress/data/typedoc.test.ts diff --git a/docs/.vitepress/data/typedoc.ts b/apps/docs/.vitepress/data/typedoc.ts similarity index 100% rename from docs/.vitepress/data/typedoc.ts rename to apps/docs/.vitepress/data/typedoc.ts diff --git a/docs/.vitepress/theme/components/SettingsGear.vue b/apps/docs/.vitepress/theme/components/SettingsGear.vue similarity index 100% rename from docs/.vitepress/theme/components/SettingsGear.vue rename to apps/docs/.vitepress/theme/components/SettingsGear.vue diff --git a/docs/.vitepress/theme/composables/use-doc-settings.ts b/apps/docs/.vitepress/theme/composables/use-doc-settings.ts similarity index 100% rename from docs/.vitepress/theme/composables/use-doc-settings.ts rename to apps/docs/.vitepress/theme/composables/use-doc-settings.ts diff --git a/docs/.vitepress/theme/explorations/theme-sketch-1-brand-forward-dark.svg b/apps/docs/.vitepress/theme/explorations/theme-sketch-1-brand-forward-dark.svg similarity index 100% rename from docs/.vitepress/theme/explorations/theme-sketch-1-brand-forward-dark.svg rename to apps/docs/.vitepress/theme/explorations/theme-sketch-1-brand-forward-dark.svg diff --git a/docs/.vitepress/theme/explorations/theme-sketch-1-brand-forward.svg b/apps/docs/.vitepress/theme/explorations/theme-sketch-1-brand-forward.svg similarity index 100% rename from docs/.vitepress/theme/explorations/theme-sketch-1-brand-forward.svg rename to apps/docs/.vitepress/theme/explorations/theme-sketch-1-brand-forward.svg diff --git a/docs/.vitepress/theme/explorations/theme-sketch-2-neutral-accents-dark.svg b/apps/docs/.vitepress/theme/explorations/theme-sketch-2-neutral-accents-dark.svg similarity index 100% rename from docs/.vitepress/theme/explorations/theme-sketch-2-neutral-accents-dark.svg rename to apps/docs/.vitepress/theme/explorations/theme-sketch-2-neutral-accents-dark.svg diff --git a/docs/.vitepress/theme/explorations/theme-sketch-2-neutral-accents.svg b/apps/docs/.vitepress/theme/explorations/theme-sketch-2-neutral-accents.svg similarity index 100% rename from docs/.vitepress/theme/explorations/theme-sketch-2-neutral-accents.svg rename to apps/docs/.vitepress/theme/explorations/theme-sketch-2-neutral-accents.svg diff --git a/docs/.vitepress/theme/explorations/theme-sketch-3-warm-cool-dark.svg b/apps/docs/.vitepress/theme/explorations/theme-sketch-3-warm-cool-dark.svg similarity index 100% rename from docs/.vitepress/theme/explorations/theme-sketch-3-warm-cool-dark.svg rename to apps/docs/.vitepress/theme/explorations/theme-sketch-3-warm-cool-dark.svg diff --git a/docs/.vitepress/theme/explorations/theme-sketch-3-warm-cool.svg b/apps/docs/.vitepress/theme/explorations/theme-sketch-3-warm-cool.svg similarity index 100% rename from docs/.vitepress/theme/explorations/theme-sketch-3-warm-cool.svg rename to apps/docs/.vitepress/theme/explorations/theme-sketch-3-warm-cool.svg diff --git a/docs/.vitepress/theme/index.ts b/apps/docs/.vitepress/theme/index.ts similarity index 100% rename from docs/.vitepress/theme/index.ts rename to apps/docs/.vitepress/theme/index.ts diff --git a/docs/.vitepress/theme/settings.css b/apps/docs/.vitepress/theme/settings.css similarity index 100% rename from docs/.vitepress/theme/settings.css rename to apps/docs/.vitepress/theme/settings.css diff --git a/docs/.vitepress/theme/twoslash-mobile.css b/apps/docs/.vitepress/theme/twoslash-mobile.css similarity index 100% rename from docs/.vitepress/theme/twoslash-mobile.css rename to apps/docs/.vitepress/theme/twoslash-mobile.css diff --git a/docs/.vitepress/twoslash/testing-fixtures.ts b/apps/docs/.vitepress/twoslash/testing-fixtures.ts similarity index 96% rename from docs/.vitepress/twoslash/testing-fixtures.ts rename to apps/docs/.vitepress/twoslash/testing-fixtures.ts index b75d87dd..a922cb33 100644 --- a/docs/.vitepress/twoslash/testing-fixtures.ts +++ b/apps/docs/.vitepress/twoslash/testing-fixtures.ts @@ -1,4 +1,4 @@ -import { arg, command, flag } from '#dreamcli'; +import { arg, command, flag } from '@kjanat/dreamcli'; export const greet = command('greet') .arg('name', arg.string()) diff --git a/docs/.vitepress/vite-plugins/index.ts b/apps/docs/.vitepress/vite-plugins/index.ts similarity index 100% rename from docs/.vitepress/vite-plugins/index.ts rename to apps/docs/.vitepress/vite-plugins/index.ts diff --git a/docs/.vitepress/vite-plugins/shiki-class-css.ts b/apps/docs/.vitepress/vite-plugins/shiki-class-css.ts similarity index 100% rename from docs/.vitepress/vite-plugins/shiki-class-css.ts rename to apps/docs/.vitepress/vite-plugins/shiki-class-css.ts diff --git a/docs/.vitepress/vite-plugins/shiki-dedupe-popup-styles.ts b/apps/docs/.vitepress/vite-plugins/shiki-dedupe-popup-styles.ts similarity index 100% rename from docs/.vitepress/vite-plugins/shiki-dedupe-popup-styles.ts rename to apps/docs/.vitepress/vite-plugins/shiki-dedupe-popup-styles.ts diff --git a/docs/.vitepress/vite-plugins/shiki-jsdoc-tags.ts b/apps/docs/.vitepress/vite-plugins/shiki-jsdoc-tags.ts similarity index 100% rename from docs/.vitepress/vite-plugins/shiki-jsdoc-tags.ts rename to apps/docs/.vitepress/vite-plugins/shiki-jsdoc-tags.ts diff --git a/docs/.vitepress/vite-plugins/source-artifacts.ts b/apps/docs/.vitepress/vite-plugins/source-artifacts.ts similarity index 84% rename from docs/.vitepress/vite-plugins/source-artifacts.ts rename to apps/docs/.vitepress/vite-plugins/source-artifacts.ts index 7bafcd92..34fc732b 100644 --- a/docs/.vitepress/vite-plugins/source-artifacts.ts +++ b/apps/docs/.vitepress/vite-plugins/source-artifacts.ts @@ -2,7 +2,7 @@ * Vite plugin that keeps docs schema artifact available. * * Twoslash examples import `@kjanat/dreamcli/schema`, which resolves - * through tsconfig paths to the root `dreamcli.schema.json` file. This + * through tsconfig paths to the package `dreamcli.schema.json` file. This * plugin ensures that file exists during docs dev/build and emits it into * docs dist for hosting. * @@ -14,9 +14,10 @@ import { pathToFileURL } from 'node:url'; import type { Plugin } from 'vitepress'; -const rootDir = normalize(`${import.meta.dirname}/../../..`); -const definitionSchemaPath = `${rootDir}/dreamcli.schema.json`; -const emitDefinitionSchemaPath = `${rootDir}/scripts/emit-definition-schema.ts`; +const rootDir = normalize(`${import.meta.dirname}/../../../..`); +const packageRoot = `${rootDir}/packages/dreamcli`; +const definitionSchemaPath = `${packageRoot}/dreamcli.schema.json`; +const emitDefinitionSchemaPath = `${packageRoot}/scripts/emit-definition-schema.ts`; const emitDefinitionSchemaUrl = pathToFileURL(emitDefinitionSchemaPath).href; export function sourceArtifactsPlugin(): Plugin { @@ -70,7 +71,7 @@ export function sourceArtifactsPlugin(): Plugin { const handleSrcChange = (file: string): void => { if ( - file.startsWith(`${rootDir}/src/`) && + file.startsWith(`${packageRoot}/src/`) && file.endsWith('.ts') && !file.endsWith('.test.ts') && !file.endsWith('.generated.ts') @@ -102,7 +103,7 @@ async function readExistingSchema(readFile: ReadFile, schemaPath: string): Promi } catch (error) { const cause = error instanceof Error ? error.message : String(error); throw new Error( - `[dreamcli-source-artifacts] Missing ${schemaPath}: ${cause}. Run \`bun --bun scripts/emit-definition-schema.ts\` before docs build.`, + `[dreamcli-source-artifacts] Missing ${schemaPath}: ${cause}. Run \`bun --cwd packages/dreamcli scripts/emit-definition-schema.ts\` before docs build.`, ); } } diff --git a/docs/AGENTS.md b/apps/docs/AGENTS.md similarity index 100% rename from docs/AGENTS.md rename to apps/docs/AGENTS.md diff --git a/docs/concepts/anatomy.md b/apps/docs/concepts/anatomy.md similarity index 100% rename from docs/concepts/anatomy.md rename to apps/docs/concepts/anatomy.md diff --git a/docs/concepts/errors.md b/apps/docs/concepts/errors.md similarity index 100% rename from docs/concepts/errors.md rename to apps/docs/concepts/errors.md diff --git a/docs/concepts/exit-codes.md b/apps/docs/concepts/exit-codes.md similarity index 100% rename from docs/concepts/exit-codes.md rename to apps/docs/concepts/exit-codes.md diff --git a/docs/concepts/input.md b/apps/docs/concepts/input.md similarity index 100% rename from docs/concepts/input.md rename to apps/docs/concepts/input.md diff --git a/docs/concepts/output.md b/apps/docs/concepts/output.md similarity index 100% rename from docs/concepts/output.md rename to apps/docs/concepts/output.md diff --git a/docs/concepts/testing.md b/apps/docs/concepts/testing.md similarity index 88% rename from docs/concepts/testing.md rename to apps/docs/concepts/testing.md index f6ca56a3..191e74eb 100644 --- a/docs/concepts/testing.md +++ b/apps/docs/concepts/testing.md @@ -64,7 +64,7 @@ Can't test prompts easily. Platform-dependent. Run the command handler as a function, injecting all inputs: ```ts twoslash -import { greet } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { greet } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; @@ -89,7 +89,7 @@ The examples below use dreamcli's test harness, but the patterns apply to any fr The command works with valid input: ```ts twoslash -import { greet } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { greet } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; @@ -103,7 +103,7 @@ expect(result.exitCode).toBe(0); Flags resolve from the right source: ```ts twoslash -import { regionCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { regionCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; @@ -119,7 +119,7 @@ expect(result.stdout).toContain('eu'); Bad input produces helpful errors: ```ts twoslash -import { regionCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { regionCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; @@ -133,7 +133,7 @@ expect(result.stderr.join('')).toContain('Unknown flag'); Required flags that aren't provided, fail clearly: ```ts twoslash -import { promptCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { promptCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; @@ -149,7 +149,7 @@ expect(result.stderr.join('')).toContain( Structured output is valid JSON: ```ts twoslash -import { jsonListCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { jsonListCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; @@ -165,7 +165,7 @@ expect(data).toBeInstanceOf(Array); Prompt answers resolve correctly: ```ts twoslash -import { promptCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { promptCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; @@ -180,7 +180,7 @@ expect(result.exitCode).toBe(0); Ctrl+C during a prompt exits gracefully: ```ts twoslash -import { promptCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { promptCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { PROMPT_CANCEL, diff --git a/docs/examples/[slug].md b/apps/docs/examples/[slug].md similarity index 100% rename from docs/examples/[slug].md rename to apps/docs/examples/[slug].md diff --git a/docs/examples/[slug].paths.ts b/apps/docs/examples/[slug].paths.ts similarity index 100% rename from docs/examples/[slug].paths.ts rename to apps/docs/examples/[slug].paths.ts diff --git a/docs/examples/examples.data.ts b/apps/docs/examples/examples.data.ts similarity index 100% rename from docs/examples/examples.data.ts rename to apps/docs/examples/examples.data.ts diff --git a/docs/examples/index.md b/apps/docs/examples/index.md similarity index 100% rename from docs/examples/index.md rename to apps/docs/examples/index.md diff --git a/docs/guide/arguments.md b/apps/docs/guide/arguments.md similarity index 100% rename from docs/guide/arguments.md rename to apps/docs/guide/arguments.md diff --git a/docs/guide/commands.md b/apps/docs/guide/commands.md similarity index 91% rename from docs/guide/commands.md rename to apps/docs/guide/commands.md index e092d457..81faf118 100644 --- a/docs/guide/commands.md +++ b/apps/docs/guide/commands.md @@ -129,14 +129,14 @@ command('deploy').action( // prettier-ignore // ---cut-end--- ({ args, flags, ctx, meta, out }) => { - //^^^^^^^^^^^^^^^^^^^^^^^^^^^ - // args — typed positional arguments - // flags — typed flag values (fully resolved) - // ctx — typed middleware context - // meta — CLI metadata: name (program name), bin (invoked binary name), - // version (program version), command (leaf command name) - // out — output channel - }, + //^^^^^^^^^^^^^^^^^^^^^^^^^^^ + // args — typed positional arguments + // flags — typed flag values (fully resolved) + // ctx — typed middleware context + // meta — CLI metadata: name (program name), bin (invoked binary name), + // version (program version), command (leaf command name) + // out — output channel + }, ); ``` diff --git a/docs/guide/completions.md b/apps/docs/guide/completions.md similarity index 100% rename from docs/guide/completions.md rename to apps/docs/guide/completions.md diff --git a/docs/guide/config.md b/apps/docs/guide/config.md similarity index 100% rename from docs/guide/config.md rename to apps/docs/guide/config.md diff --git a/docs/guide/errors.md b/apps/docs/guide/errors.md similarity index 100% rename from docs/guide/errors.md rename to apps/docs/guide/errors.md diff --git a/docs/guide/flags.md b/apps/docs/guide/flags.md similarity index 100% rename from docs/guide/flags.md rename to apps/docs/guide/flags.md diff --git a/docs/guide/getting-started.md b/apps/docs/guide/getting-started.md similarity index 100% rename from docs/guide/getting-started.md rename to apps/docs/guide/getting-started.md diff --git a/docs/guide/limitations.md b/apps/docs/guide/limitations.md similarity index 100% rename from docs/guide/limitations.md rename to apps/docs/guide/limitations.md diff --git a/docs/guide/middleware.md b/apps/docs/guide/middleware.md similarity index 100% rename from docs/guide/middleware.md rename to apps/docs/guide/middleware.md diff --git a/docs/guide/migration.md b/apps/docs/guide/migration.md similarity index 100% rename from docs/guide/migration.md rename to apps/docs/guide/migration.md diff --git a/docs/guide/output.md b/apps/docs/guide/output.md similarity index 100% rename from docs/guide/output.md rename to apps/docs/guide/output.md diff --git a/docs/guide/prompts.md b/apps/docs/guide/prompts.md similarity index 97% rename from docs/guide/prompts.md rename to apps/docs/guide/prompts.md index 246b300e..0876d0f8 100644 --- a/docs/guide/prompts.md +++ b/apps/docs/guide/prompts.md @@ -70,7 +70,7 @@ Required flags that would have prompted instead produce a structured error with ## Testing Prompts ```ts twoslash -import { promptCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { promptCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand, diff --git a/docs/guide/rationale.md b/apps/docs/guide/rationale.md similarity index 100% rename from docs/guide/rationale.md rename to apps/docs/guide/rationale.md diff --git a/docs/guide/runtime.md b/apps/docs/guide/runtime.md similarity index 96% rename from docs/guide/runtime.md rename to apps/docs/guide/runtime.md index 28d6d5cc..bdd9b18a 100644 --- a/docs/guide/runtime.md +++ b/apps/docs/guide/runtime.md @@ -57,7 +57,7 @@ deno run --allow-read --allow-env mycli.ts deploy For command behavior tests, `runCommand()` is process-free and injects runtime state directly: ```ts twoslash -import { regionCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { regionCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; diff --git a/docs/guide/schema-export.md b/apps/docs/guide/schema-export.md similarity index 100% rename from docs/guide/schema-export.md rename to apps/docs/guide/schema-export.md diff --git a/docs/guide/semantics.md b/apps/docs/guide/semantics.md similarity index 100% rename from docs/guide/semantics.md rename to apps/docs/guide/semantics.md diff --git a/docs/guide/testing.md b/apps/docs/guide/testing.md similarity index 92% rename from docs/guide/testing.md rename to apps/docs/guide/testing.md index ae53d65d..9e8c7fa2 100644 --- a/docs/guide/testing.md +++ b/apps/docs/guide/testing.md @@ -6,7 +6,7 @@ No subprocesses, no `process.argv` mutation, no mocking. ## Basic Usage ```ts twoslash -import { greet } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { greet } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; @@ -23,7 +23,7 @@ expect(result.error).toBeUndefined(); Control every dimension of CLI behavior from tests: ```ts twoslash -import { deploy } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { deploy } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; @@ -71,7 +71,7 @@ await runCommand(deploy, ['production'], { ## Testing Prompts ```ts twoslash -import { promptCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { promptCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand, @@ -95,7 +95,7 @@ await runCommand(promptCmd, [], { Spinners and progress bars emit testable events: ```ts twoslash -import { activityCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { activityCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; diff --git a/docs/guide/troubleshooting.md b/apps/docs/guide/troubleshooting.md similarity index 100% rename from docs/guide/troubleshooting.md rename to apps/docs/guide/troubleshooting.md diff --git a/docs/guide/walkthrough.md b/apps/docs/guide/walkthrough.md similarity index 100% rename from docs/guide/walkthrough.md rename to apps/docs/guide/walkthrough.md diff --git a/docs/guide/why.md b/apps/docs/guide/why.md similarity index 100% rename from docs/guide/why.md rename to apps/docs/guide/why.md diff --git a/docs/index.md b/apps/docs/index.md similarity index 100% rename from docs/index.md rename to apps/docs/index.md diff --git a/apps/docs/package.json b/apps/docs/package.json new file mode 100644 index 00000000..5520829a --- /dev/null +++ b/apps/docs/package.json @@ -0,0 +1,30 @@ +{ + "name": "@kjanat/dreamcli-docs", + "version": "0.0.0", + "private": true, + "type": "module", + "imports": { + "#dreamcli/testkit": "@kjanat/dreamcli/testkit" + }, + "scripts": { + "build": "bunx --bun vitepress@next build", + "dev": "bunx --bun vitepress@next dev", + "preview": "bunx --bun vitepress@next preview", + "test": "vitest run" + }, + "dependencies": { + "@kjanat/dreamcli": "workspace:*" + }, + "devDependencies": { + "@shikijs/transformers": "^4.0.2", + "@shikijs/vitepress-twoslash": "^4.0.2", + "@types/bun": "catalog:", + "floating-vue": "^5.2.2", + "mermaid": "^11.14.0", + "typedoc": "^0.28.18", + "typescript": "catalog:", + "vite": "^8.0.7", + "vitepress": "^2.0.0-alpha.17", + "vitest": "catalog:" + } +} diff --git a/docs/public/animations/loadingbar.svg b/apps/docs/public/animations/loadingbar.svg similarity index 100% rename from docs/public/animations/loadingbar.svg rename to apps/docs/public/animations/loadingbar.svg diff --git a/docs/public/animations/spinner.svg b/apps/docs/public/animations/spinner.svg similarity index 100% rename from docs/public/animations/spinner.svg rename to apps/docs/public/animations/spinner.svg diff --git a/docs/public/app-icon-192.png b/apps/docs/public/app-icon-192.png similarity index 100% rename from docs/public/app-icon-192.png rename to apps/docs/public/app-icon-192.png diff --git a/docs/public/app-icon-512.png b/apps/docs/public/app-icon-512.png similarity index 100% rename from docs/public/app-icon-512.png rename to apps/docs/public/app-icon-512.png diff --git a/docs/public/app-icon.svg b/apps/docs/public/app-icon.svg similarity index 100% rename from docs/public/app-icon.svg rename to apps/docs/public/app-icon.svg diff --git a/docs/public/apple-touch-icon.png b/apps/docs/public/apple-touch-icon.png similarity index 100% rename from docs/public/apple-touch-icon.png rename to apps/docs/public/apple-touch-icon.png diff --git a/docs/public/favicon-dark.svg b/apps/docs/public/favicon-dark.svg similarity index 100% rename from docs/public/favicon-dark.svg rename to apps/docs/public/favicon-dark.svg diff --git a/docs/public/favicon.ico b/apps/docs/public/favicon.ico similarity index 100% rename from docs/public/favicon.ico rename to apps/docs/public/favicon.ico diff --git a/docs/public/favicon.svg b/apps/docs/public/favicon.svg similarity index 100% rename from docs/public/favicon.svg rename to apps/docs/public/favicon.svg diff --git a/docs/public/icons/middleware-dark.svg b/apps/docs/public/icons/middleware-dark.svg similarity index 100% rename from docs/public/icons/middleware-dark.svg rename to apps/docs/public/icons/middleware-dark.svg diff --git a/docs/public/icons/middleware-light.svg b/apps/docs/public/icons/middleware-light.svg similarity index 100% rename from docs/public/icons/middleware-light.svg rename to apps/docs/public/icons/middleware-light.svg diff --git a/docs/public/icons/resolution-chain-dark.svg b/apps/docs/public/icons/resolution-chain-dark.svg similarity index 100% rename from docs/public/icons/resolution-chain-dark.svg rename to apps/docs/public/icons/resolution-chain-dark.svg diff --git a/docs/public/icons/resolution-chain-light.svg b/apps/docs/public/icons/resolution-chain-light.svg similarity index 100% rename from docs/public/icons/resolution-chain-light.svg rename to apps/docs/public/icons/resolution-chain-light.svg diff --git a/docs/public/icons/structured-output-dark.svg b/apps/docs/public/icons/structured-output-dark.svg similarity index 100% rename from docs/public/icons/structured-output-dark.svg rename to apps/docs/public/icons/structured-output-dark.svg diff --git a/docs/public/icons/structured-output-light.svg b/apps/docs/public/icons/structured-output-light.svg similarity index 100% rename from docs/public/icons/structured-output-light.svg rename to apps/docs/public/icons/structured-output-light.svg diff --git a/docs/public/icons/test-harness-dark.svg b/apps/docs/public/icons/test-harness-dark.svg similarity index 100% rename from docs/public/icons/test-harness-dark.svg rename to apps/docs/public/icons/test-harness-dark.svg diff --git a/docs/public/icons/test-harness-light.svg b/apps/docs/public/icons/test-harness-light.svg similarity index 100% rename from docs/public/icons/test-harness-light.svg rename to apps/docs/public/icons/test-harness-light.svg diff --git a/docs/public/icons/type-inference-dark.svg b/apps/docs/public/icons/type-inference-dark.svg similarity index 100% rename from docs/public/icons/type-inference-dark.svg rename to apps/docs/public/icons/type-inference-dark.svg diff --git a/docs/public/icons/type-inference-light.svg b/apps/docs/public/icons/type-inference-light.svg similarity index 100% rename from docs/public/icons/type-inference-light.svg rename to apps/docs/public/icons/type-inference-light.svg diff --git a/docs/public/icons/zero-deps-dark.svg b/apps/docs/public/icons/zero-deps-dark.svg similarity index 100% rename from docs/public/icons/zero-deps-dark.svg rename to apps/docs/public/icons/zero-deps-dark.svg diff --git a/docs/public/icons/zero-deps-light.svg b/apps/docs/public/icons/zero-deps-light.svg similarity index 100% rename from docs/public/icons/zero-deps-light.svg rename to apps/docs/public/icons/zero-deps-light.svg diff --git a/docs/public/logo-dark.svg b/apps/docs/public/logo-dark.svg similarity index 100% rename from docs/public/logo-dark.svg rename to apps/docs/public/logo-dark.svg diff --git a/docs/public/logo-light.svg b/apps/docs/public/logo-light.svg similarity index 100% rename from docs/public/logo-light.svg rename to apps/docs/public/logo-light.svg diff --git a/docs/public/manifest.json b/apps/docs/public/manifest.json similarity index 100% rename from docs/public/manifest.json rename to apps/docs/public/manifest.json diff --git a/docs/reference/api.data.ts b/apps/docs/reference/api.data.ts similarity index 100% rename from docs/reference/api.data.ts rename to apps/docs/reference/api.data.ts diff --git a/docs/reference/api.md b/apps/docs/reference/api.md similarity index 100% rename from docs/reference/api.md rename to apps/docs/reference/api.md diff --git a/docs/reference/changelog.md b/apps/docs/reference/changelog.md similarity index 80% rename from docs/reference/changelog.md rename to apps/docs/reference/changelog.md index 57d849f5..d3f5b06e 100644 --- a/docs/reference/changelog.md +++ b/apps/docs/reference/changelog.md @@ -5,4 +5,4 @@ This page surfaces the repository changelog directly inside the docs site. - Source of truth: `CHANGELOG.md` - Related pages: [API Reference](/reference/api), [Semantic Delta Log](/reference/semantic-delta-log), [Examples](/examples/) - + diff --git a/docs/reference/example-hover-prototype.md b/apps/docs/reference/example-hover-prototype.md similarity index 100% rename from docs/reference/example-hover-prototype.md rename to apps/docs/reference/example-hover-prototype.md diff --git a/docs/reference/main.md b/apps/docs/reference/main.md similarity index 100% rename from docs/reference/main.md rename to apps/docs/reference/main.md diff --git a/docs/reference/output-contract.md b/apps/docs/reference/output-contract.md similarity index 100% rename from docs/reference/output-contract.md rename to apps/docs/reference/output-contract.md diff --git a/docs/reference/planner-contract.md b/apps/docs/reference/planner-contract.md similarity index 100% rename from docs/reference/planner-contract.md rename to apps/docs/reference/planner-contract.md diff --git a/docs/reference/resolver-contract.md b/apps/docs/reference/resolver-contract.md similarity index 100% rename from docs/reference/resolver-contract.md rename to apps/docs/reference/resolver-contract.md diff --git a/docs/reference/runtime.md b/apps/docs/reference/runtime.md similarity index 100% rename from docs/reference/runtime.md rename to apps/docs/reference/runtime.md diff --git a/docs/reference/schema.md b/apps/docs/reference/schema.md similarity index 100% rename from docs/reference/schema.md rename to apps/docs/reference/schema.md diff --git a/docs/reference/semantic-delta-log.md b/apps/docs/reference/semantic-delta-log.md similarity index 100% rename from docs/reference/semantic-delta-log.md rename to apps/docs/reference/semantic-delta-log.md diff --git a/docs/reference/support-matrix.md b/apps/docs/reference/support-matrix.md similarity index 100% rename from docs/reference/support-matrix.md rename to apps/docs/reference/support-matrix.md diff --git a/docs/reference/symbols/main/[slug].md b/apps/docs/reference/symbols/main/[slug].md similarity index 100% rename from docs/reference/symbols/main/[slug].md rename to apps/docs/reference/symbols/main/[slug].md diff --git a/docs/reference/symbols/main/[slug].paths.ts b/apps/docs/reference/symbols/main/[slug].paths.ts similarity index 100% rename from docs/reference/symbols/main/[slug].paths.ts rename to apps/docs/reference/symbols/main/[slug].paths.ts diff --git a/docs/reference/symbols/runtime/[slug].md b/apps/docs/reference/symbols/runtime/[slug].md similarity index 100% rename from docs/reference/symbols/runtime/[slug].md rename to apps/docs/reference/symbols/runtime/[slug].md diff --git a/docs/reference/symbols/runtime/[slug].paths.ts b/apps/docs/reference/symbols/runtime/[slug].paths.ts similarity index 100% rename from docs/reference/symbols/runtime/[slug].paths.ts rename to apps/docs/reference/symbols/runtime/[slug].paths.ts diff --git a/docs/reference/symbols/testkit/[slug].md b/apps/docs/reference/symbols/testkit/[slug].md similarity index 100% rename from docs/reference/symbols/testkit/[slug].md rename to apps/docs/reference/symbols/testkit/[slug].md diff --git a/docs/reference/symbols/testkit/[slug].paths.ts b/apps/docs/reference/symbols/testkit/[slug].paths.ts similarity index 100% rename from docs/reference/symbols/testkit/[slug].paths.ts rename to apps/docs/reference/symbols/testkit/[slug].paths.ts diff --git a/docs/reference/testkit.md b/apps/docs/reference/testkit.md similarity index 95% rename from docs/reference/testkit.md rename to apps/docs/reference/testkit.md index 757e7d33..bbc18850 100644 --- a/docs/reference/testkit.md +++ b/apps/docs/reference/testkit.md @@ -17,7 +17,7 @@ import { Run a command in-process and return a `RunResult`. ```ts twoslash -import { greet } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { greet } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { runCommand } from '@kjanat/dreamcli/testkit'; @@ -83,7 +83,7 @@ Returns a runtime adapter for testing (no real process access). Sentinel value to simulate prompt cancellation. ```ts twoslash -import { promptCmd } from './docs/.vitepress/twoslash/testing-fixtures.ts'; +import { promptCmd } from './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut--- import { createTestPrompter, diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json new file mode 100644 index 00000000..80d41dd4 --- /dev/null +++ b/apps/docs/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "types": ["bun", "vite", "vitest"], + "paths": { + "#dreamcli/testkit": ["../../packages/dreamcli/src/testkit.ts"], + "@kjanat/dreamcli": ["../../packages/dreamcli/src/index.ts"], + "@kjanat/dreamcli/runtime": ["../../packages/dreamcli/src/runtime.ts"], + "@kjanat/dreamcli/testkit": ["../../packages/dreamcli/src/testkit.ts"], + "@kjanat/dreamcli/schema": ["../../packages/dreamcli/dreamcli.schema.json"], + "@kjanat/dreamcli/package.json": ["../../packages/dreamcli/package.json"] + } + }, + "include": [".vitepress/**/*.ts", "**/*.ts"], + "exclude": ["**/dist", "**/node_modules", "**/cache"] +} diff --git a/apps/docs/vitest.config.ts b/apps/docs/vitest.config.ts new file mode 100644 index 00000000..ea6bfdaa --- /dev/null +++ b/apps/docs/vitest.config.ts @@ -0,0 +1,19 @@ +import { resolve } from 'node:path'; + +import { defineConfig } from 'vitest/config'; + +const packageSrc = resolve(import.meta.dirname, '../../packages/dreamcli/src'); + +export default defineConfig({ + resolve: { + alias: { + '#dreamcli/testkit': `${packageSrc}/testkit.ts`, + '@kjanat/dreamcli/testkit': `${packageSrc}/testkit.ts`, + '@kjanat/dreamcli/runtime': `${packageSrc}/runtime.ts`, + '@kjanat/dreamcli': `${packageSrc}/index.ts`, + }, + }, + test: { + include: ['.vitepress/data/*.test.ts'], + }, +}); diff --git a/bun.lock b/bun.lock index db37101e..273d7cd4 100644 --- a/bun.lock +++ b/bun.lock @@ -5,41 +5,89 @@ "": { "name": "@kjanat/dreamcli", "devDependencies": { - "@arethetypeswrong/core": "^0.18.2", "@biomejs/biome": "^2.4.10", - "@iarna/toml": "^2.2.5", + "@kjanat/dreamcli": "workspace:*", + "@kjanat/dreamcli-docs": "workspace:*", + "@kjanat/gh-project": "workspace:*", + "dprint": "^0.53.2", + "knip": "^6.3.0", + "wrangler": "^4.80.0", + }, + }, + "apps/docs": { + "name": "@kjanat/dreamcli-docs", + "version": "0.0.0", + "dependencies": { + "@kjanat/dreamcli": "workspace:*", + }, + "devDependencies": { "@shikijs/transformers": "^4.0.2", "@shikijs/vitepress-twoslash": "^4.0.2", "@types/bun": "catalog:", + "floating-vue": "^5.2.2", + "mermaid": "^11.14.0", + "typedoc": "^0.28.18", + "typescript": "catalog:", + "vite": "^8.0.7", + "vitepress": "^2.0.0-alpha.17", + "vitest": "catalog:", + }, + }, + "examples/gh": { + "name": "gh", + "version": "0.0.0-example", + "bin": { + "gh": "src/main.ts", + }, + "dependencies": { + "@kjanat/dreamcli": "workspace:*", + }, + "devDependencies": { + "@types/bun": "catalog:", + "typescript": "catalog:", + }, + }, + "examples/standalone": { + "name": "@kjanat/dreamcli-examples", + "version": "0.0.0", + "dependencies": { + "@kjanat/dreamcli": "workspace:*", + }, + "devDependencies": { + "@types/bun": "catalog:", + "typescript": "catalog:", + "vitest": "catalog:", + }, + }, + "packages/dreamcli": { + "name": "@kjanat/dreamcli", + "version": "2.0.1", + "devDependencies": { + "@arethetypeswrong/core": "^0.18.2", + "@iarna/toml": "^2.2.5", + "@types/bun": "catalog:", "@types/deno": "^2.5.0", "@types/node": "catalog:", "@typescript/native-preview": "^7.0.0-dev.20260406.1", "@vitest/coverage-v8": "^4.1.2", - "dprint": "^0.53.2", - "floating-vue": "^5.2.2", - "knip": "^6.3.0", - "mermaid": "^11.14.0", "publint": "^0.3.18", "tsdown": "^0.21.7", - "typedoc": "^0.28.18", "typescript": "catalog:", - "vitepress": "^2.0.0-alpha.17", - "vitest": "^4.1.2", - "wrangler": "^4.80.0", + "vitest": "catalog:", "yaml": "^2.8.3", }, "optionalDependencies": { "vite": "^8", }, }, - "examples/gh": { - "name": "gh", - "version": "0.0.0-example", + "tools/gh-project": { + "name": "@kjanat/gh-project", + "version": "0.0.0", "bin": { - "gh": "src/main.ts", + "gh-project": "src/main.ts", }, "dependencies": { - "@kjanat/dreamcli": "link:@kjanat/dreamcli", + "@kjanat/dreamcli": "workspace:*", }, "devDependencies": { "@types/bun": "catalog:", @@ -51,6 +99,7 @@ "@types/bun": "^1.3.0", "@types/node": ">=22.0.0, <23.0.0", "typescript": "^6.0.2", + "vitest": "^4.1.2", }, "packages": { "@andrewbranch/untar.js": ["@andrewbranch/untar.js@1.0.3", "", {}, "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw=="], @@ -147,11 +196,11 @@ "@dprint/win32-x64": ["@dprint/win32-x64@0.53.2", "", { "os": "win32", "cpu": "x64" }, "sha512-xdOOm4ZG9pqKdnVvgFMp8/c9Ylkt2LcTFqjmxF1CoCZNNYGMUrH60YQl/M9R9wJXSSQOv6K+7Ub+hOWcIlxIjw=="], - "@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], + "@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="], - "@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], + "@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="], - "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="], "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], @@ -279,7 +328,13 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], - "@kjanat/dreamcli": ["@kjanat/dreamcli@link:@kjanat/dreamcli", {}], + "@kjanat/dreamcli": ["@kjanat/dreamcli@workspace:packages/dreamcli"], + + "@kjanat/dreamcli-docs": ["@kjanat/dreamcli-docs@workspace:apps/docs"], + + "@kjanat/dreamcli-examples": ["@kjanat/dreamcli-examples@workspace:examples/standalone"], + + "@kjanat/gh-project": ["@kjanat/gh-project@workspace:tools/gh-project"], "@loaderkit/resolve": ["@loaderkit/resolve@1.0.4", "", { "dependencies": { "@braidai/lang": "^1.0.0" } }, "sha512-rJzYKVcV4dxJv+vW6jlvagF8zvGxHJ2+HTr1e2qOejfmGhAApgJHl8Aog4mMszxceTRiKTTbnpgmTO1bEZHV/A=="], @@ -1225,7 +1280,7 @@ "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - "vite": ["vite@8.0.5", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.12", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-nmu43Qvq9UopTRfMx2jOYW5l16pb3iDC1JH6yMuPkpVbzK0k+L7dfsEDH4jRgYFmsg0sTAqkojoZgzLMlwHsCQ=="], + "vite": ["vite@8.0.7", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.13", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-P1PbweD+2/udplnThz3btF4cf6AgPky7kk23RtHUkJIU5BIxwPprhRGmOAHs6FTI7UiGbTNrgNP6jSYD6JaRnw=="], "vitepress": ["vitepress@2.0.0-alpha.17", "", { "dependencies": { "@docsearch/css": "^4.5.3", "@docsearch/js": "^4.5.3", "@docsearch/sidepanel-js": "^4.5.3", "@iconify-json/simple-icons": "^1.2.69", "@shikijs/core": "^3.22.0", "@shikijs/transformers": "^3.22.0", "@shikijs/types": "^3.22.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^6.0.4", "@vue/devtools-api": "^8.0.5", "@vue/shared": "^3.5.27", "@vueuse/core": "^14.2.0", "@vueuse/integrations": "^14.2.0", "focus-trap": "^8.0.0", "mark.js": "8.11.1", "minisearch": "^7.2.0", "shiki": "^3.22.0", "vite": "^7.3.1", "vue": "^3.5.27" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "oxc-minify": "*", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3", "oxc-minify", "postcss"], "bin": { "vitepress": "bin/vitepress.js" } }, "sha512-Z3VPUpwk/bHYqt1uMVOOK1/4xFiWQov1GNc2FvMdz6kvje4JRXEOngVI9C+bi5jeedMSHiA4dwKkff1NCvbZ9Q=="], @@ -1289,6 +1344,8 @@ "@gerrit0/mini-shiki/@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], + "@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], + "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], "@vitejs/plugin-vue/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.2", "", {}, "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw=="], @@ -1323,6 +1380,8 @@ "rolldown-plugin-dts/@babel/types": ["@babel/types@8.0.0-rc.3", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0-rc.3", "@babel/helper-validator-identifier": "^8.0.0-rc.3" } }, "sha512-mOm5ZrYmphGfqVWoH5YYMTITb3cDXsFgmvFlvkvWDMsR9X8RFnt7a0Wb6yNIdoFsiMO9WjYLq+U/FMtqIYAF8Q=="], + "vite/rolldown": ["rolldown@1.0.0-rc.13", "", { "dependencies": { "@oxc-project/types": "=0.123.0", "@rolldown/pluginutils": "1.0.0-rc.13" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.13", "@rolldown/binding-darwin-arm64": "1.0.0-rc.13", "@rolldown/binding-darwin-x64": "1.0.0-rc.13", "@rolldown/binding-freebsd-x64": "1.0.0-rc.13", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.13", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.13", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.13", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.13", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.13", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.13", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.13" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-bvVj8YJmf0rq4pSFmH7laLa6pYrhghv3PRzrCdRAr23g66zOKVJ4wkvFtgohtPLWmthgg8/rkaqRHrpUEh0Zbw=="], + "vitepress/@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], "vitepress/@shikijs/transformers": ["@shikijs/transformers@3.23.0", "", { "dependencies": { "@shikijs/core": "3.23.0", "@shikijs/types": "3.23.0" } }, "sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ=="], @@ -1345,6 +1404,40 @@ "rolldown-plugin-dts/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.3", "", {}, "sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA=="], + "vite/rolldown/@oxc-project/types": ["@oxc-project/types@0.123.0", "", {}, "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew=="], + + "vite/rolldown/@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.13", "", { "os": "android", "cpu": "arm64" }, "sha512-5ZiiecKH2DXAVJTNN13gNMUcCDg4Jy8ZjbXEsPnqa248wgOVeYRX0iqXXD5Jz4bI9BFHgKsI2qmyJynstbmr+g=="], + + "vite/rolldown/@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-tz/v/8G77seu8zAB3A5sK3UFoOl06zcshEzhUO62sAEtrEuW/H1CcyoupOrD+NbQJytYgA4CppXPzlrmp4JZKA=="], + + "vite/rolldown/@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-8DakphqOz8JrMYWTJmWA+vDJxut6LijZ8Xcdc4flOlAhU7PNVwo2MaWBF9iXjJAPo5rC/IxEFZDhJ3GC7NHvug=="], + + "vite/rolldown/@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.13", "", { "os": "freebsd", "cpu": "x64" }, "sha512-4wBQFfjDuXYN/SVI8inBF3Aa+isq40rc6VMFbk5jcpolUBTe5cYnMsHZ51nFWsx3PVyyNN3vgoESki0Hmr/4BA=="], + + "vite/rolldown/@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.13", "", { "os": "linux", "cpu": "arm" }, "sha512-JW/e4yPIXLms+jmnbwwy5LA/LxVwZUWLN8xug+V200wzaVi5TEGIWQlh8o91gWYFxW609euI98OCCemmWGuPrw=="], + + "vite/rolldown/@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZfKWpXiUymDnavepCaM6KG/uGydJ4l2nBmMxg60Ci4CbeefpqjPWpfaZM7PThOhk2dssqBAcwLc6rAyr0uTdXg=="], + + "vite/rolldown/@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-bmRg3O6Z0gq9yodKKWCIpnlH051sEfdVwt+6m5UDffAQMUUqU0xjnQqqAUm+Gu7ofAAly9DqiQDtKu2nPDEABA=="], + + "vite/rolldown/@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "ppc64" }, "sha512-8Wtnbw4k7pMYN9B/mOEAsQ8HOiq7AZ31Ig4M9BKn2So4xRaFEhtCSa4ZJaOutOWq50zpgR4N5+L/opnlaCx8wQ=="], + + "vite/rolldown/@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "s390x" }, "sha512-D/0Nlo8mQuxSMohNJUF2lDXWRsFDsHldfRRgD9bRgktj+EndGPj4DOV37LqDKPYS+osdyhZEH7fTakTAEcW7qg=="], + + "vite/rolldown/@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "x64" }, "sha512-eRrPvat2YaVQcwwKi/JzOP6MKf1WRnOCr+VaI3cTWz3ZoLcP/654z90lVCJ4dAuMEpPdke0n+qyAqXDZdIC4rA=="], + + "vite/rolldown/@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.13", "", { "os": "linux", "cpu": "x64" }, "sha512-PsdONiFRp8hR8KgVjTWjZ9s7uA3uueWL0t74/cKHfM4dR5zXYv4AjB8BvA+QDToqxAFg4ZkcVEqeu5F7inoz5w=="], + + "vite/rolldown/@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.13", "", { "os": "none", "cpu": "arm64" }, "sha512-hCNXgC5dI3TVOLrPT++PKFNZ+1EtS0mLQwfXXXSUD/+rGlB65gZDwN/IDuxLpQP4x8RYYHqGomlUXzpO8aVI2w=="], + + "vite/rolldown/@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.13", "", { "dependencies": { "@emnapi/core": "1.9.1", "@emnapi/runtime": "1.9.1", "@napi-rs/wasm-runtime": "^1.1.2" }, "cpu": "none" }, "sha512-viLS5C5et8NFtLWw9Sw3M/w4vvnVkbWkO7wSNh3C+7G1+uCkGpr6PcjNDSFcNtmXY/4trjPBqUfcOL+P3sWy/g=="], + + "vite/rolldown/@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-Fqa3Tlt1xL4wzmAYxGNFV36Hb+VfPc9PYU+E25DAnswXv3ODDu/yyWjQDbXMo5AGWkQVjLgQExuVu8I/UaZhPQ=="], + + "vite/rolldown/@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.13", "", { "os": "win32", "cpu": "x64" }, "sha512-/pLI5kPkGEi44TDlnbio3St/5gUFeN51YWNAk/Gnv6mEQBOahRBh52qVFVBpmrnU01n2yysvBML9Ynu7K4kGAQ=="], + + "vite/rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.13", "", {}, "sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA=="], + "vitepress/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA=="], "vitepress/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="], diff --git a/bunfig.toml b/bunfig.toml index 31cbc988..a60b2243 100644 --- a/bunfig.toml +++ b/bunfig.toml @@ -12,7 +12,6 @@ lockfile.save = true silent = true [test] -root = "./src" coverage = true coverageReporter = ["text", "lcov"] reporter.dots = false diff --git a/examples/gh/package.json b/examples/gh/package.json index 723f483e..d720cf68 100644 --- a/examples/gh/package.json +++ b/examples/gh/package.json @@ -24,7 +24,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@kjanat/dreamcli": "link:@kjanat/dreamcli" + "@kjanat/dreamcli": "workspace:*" }, "devDependencies": { "@types/bun": "catalog:", diff --git a/examples/gh/tsconfig.json b/examples/gh/tsconfig.json new file mode 100644 index 00000000..0268363a --- /dev/null +++ b/examples/gh/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "paths": { + "@kjanat/dreamcli": ["../../packages/dreamcli/src/index.ts"], + "@kjanat/dreamcli/testkit": ["../../packages/dreamcli/src/testkit.ts"], + "@kjanat/dreamcli/runtime": ["../../packages/dreamcli/src/runtime.ts"] + } + }, + "include": ["src"] +} diff --git a/examples/basic.ts b/examples/standalone/basic.ts similarity index 100% rename from examples/basic.ts rename to examples/standalone/basic.ts diff --git a/examples/interactive.ts b/examples/standalone/interactive.ts similarity index 100% rename from examples/interactive.ts rename to examples/standalone/interactive.ts diff --git a/examples/json-mode.ts b/examples/standalone/json-mode.ts similarity index 100% rename from examples/json-mode.ts rename to examples/standalone/json-mode.ts diff --git a/examples/middleware.ts b/examples/standalone/middleware.ts similarity index 100% rename from examples/middleware.ts rename to examples/standalone/middleware.ts diff --git a/examples/multi-command.ts b/examples/standalone/multi-command.ts similarity index 100% rename from examples/multi-command.ts rename to examples/standalone/multi-command.ts diff --git a/examples/standalone/package.json b/examples/standalone/package.json new file mode 100644 index 00000000..bb17781f --- /dev/null +++ b/examples/standalone/package.json @@ -0,0 +1,14 @@ +{ + "name": "@kjanat/dreamcli-examples", + "version": "0.0.0", + "private": true, + "type": "module", + "dependencies": { + "@kjanat/dreamcli": "workspace:*" + }, + "devDependencies": { + "@types/bun": "catalog:", + "typescript": "catalog:", + "vitest": "catalog:" + } +} diff --git a/examples/spinner-progress.ts b/examples/standalone/spinner-progress.ts similarity index 100% rename from examples/spinner-progress.ts rename to examples/standalone/spinner-progress.ts diff --git a/examples/testing.ts b/examples/standalone/testing.ts similarity index 100% rename from examples/testing.ts rename to examples/standalone/testing.ts diff --git a/knip.json b/knip.json index 617eeaa6..b416a28f 100644 --- a/knip.json +++ b/knip.json @@ -2,6 +2,11 @@ "$schema": "https://unpkg.com/knip@6/schema.json", "tags": ["-lintignore"], "workspaces": { - ".": {} + ".": {}, + "packages/dreamcli": {}, + "apps/docs": {}, + "tools/gh-project": {}, + "examples/standalone": {}, + "examples/gh": {} } } diff --git a/note-to-self.ts b/note-to-self.ts deleted file mode 100755 index b47c57b5..00000000 --- a/note-to-self.ts +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bun - -/** - * Developer helper for Bun workspace linking behavior. - * - * @module note-to-self - * @internal - */ - -import { $ } from 'bun'; -import { dependencies } from './examples/gh/package.json' with { type: 'json' }; - -/** Prints a clickable link in supported terminals (e.g. iTerm2, VSCode) using OSC 8 escape codes. */ -const osc8Link = (url: string, text?: string) => { - return `\u001B]8;;${url}\u0007${text ?? url}\u001B]8;;\u0007`; -}; - -/** Formats a code block in markdown with optional language and file link. */ -const mdCodeFence = (code: string, language = '', file?: string, filetext?: string) => { - const fence = '```'; - const fileLink = file - ? ` ${osc8Link(`file://${import.meta.dir}/${file}`, filetext ?? file)}` - : ''; - return `${fence}${language}${fileLink}\n${code}\n${fence}`; -}; - -/** Registers the current package as a “linkable” package - * @see https://bun.com/docs/pm/cli/link */ -const link = await $`bun link`.quiet(); -if (link.exitCode !== 0) { - console.error('bun link failed:', new TextDecoder().decode(link.stderr)); - process.exit(link.exitCode); -} - -console.error(`Reminder: verify Bun workspace behavior for root package references. -link: ${osc8Link('https://bun.com/docs/pm/workspaces', 'bun workspaces')}`); - -/** Why this workaround exists. See Bun docs for linking root packages in workspaces. */ -const why = ` -Why this step exists: - -${mdCodeFence(JSON.stringify(dependencies, null, ' '), 'json', 'examples/gh/package.json', "gh example's package.json dependencies")}`; - -console.warn(why); diff --git a/package.json b/package.json index e401a7e8..f75aca6b 100644 --- a/package.json +++ b/package.json @@ -1,86 +1,23 @@ { - "name": "@kjanat/dreamcli", - "version": "2.0.1", - "description": "Schema-first, fully typed TypeScript CLI framework", - "keywords": [ - "cli", - "typescript", - "framework", - "schema-first", - "command-line" - ], - "homepage": "https://dreamcli.kjanat.com", - "bugs": { - "url": "https://github.com/kjanat/dreamcli/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/kjanat/dreamcli.git" - }, - "license": "MIT", - "author": { - "name": "Kaj Kowalski", - "email": "info@kajkowalski.nl", - "url": "https://github.com/kjanat" - }, + "name": "dreamcli-monorepo", + "private": true, "type": "module", - "imports": { - "#dreamcli": "./src/index.ts", - "#dreamcli/runtime": "./src/runtime.ts", - "#dreamcli/testkit": "./src/testkit.ts", - "#internals/*": "./src/*", - "#schema": "./dreamcli.schema.json", - "#package.json": "./package.json" - }, - "exports": { - ".": { - "types": "./dist/index.d.mts", - "bun": "./src/index.ts", - "deno": "./src/index.ts", - "default": "./dist/index.mjs" - }, - "./runtime": { - "types": "./dist/runtime.d.mts", - "bun": "./src/runtime.ts", - "deno": "./src/runtime.ts", - "default": "./dist/runtime.mjs" - }, - "./testkit": { - "types": "./dist/testkit.d.mts", - "bun": "./src/testkit.ts", - "deno": "./src/testkit.ts", - "default": "./dist/testkit.mjs" - }, - "./schema": "./dreamcli.schema.json", - "./package.json": "./package.json" - }, - "files": [ - "CHANGELOG.md", - "LICENSE", - "README.md", - "dist", - "dreamcli.schema.json", - "examples", - "!examples/.cache", - "package.json", - "src", - "!src/**/*.test.ts", - "!src/**/*test-helpers.ts", - "!**/AGENTS.md" - ], "workspaces": [ - "./examples/*" + "packages/*", + "apps/*", + "tools/*", + "examples/*" ], "scripts": { - "bd": "bunx --bun tsdown", - "build": "bunx --bun tsdown", - "build:watch": "bunx --bun tsdown --watch", - "ci": "bun typecheck && bun lint && bun run format:check && bun run meta-descriptions:check && bun run test && bun run docs:build && bun bd", - "coverage": "vitest run --coverage", - "dev": "bunx --bun tsdown --logLevel silent --watch & bunx --bun vitepress@next dev docs --host --port ${PORT:-5173} & wait", - "docs:build": "bunx --bun vitepress@next build docs", - "docs:dev": "bunx --bun vitepress@next dev docs", - "docs:preview": "bunx --bun vitepress@next preview docs", + "bd": "bun run --filter @kjanat/dreamcli bd", + "build": "bun run --filter @kjanat/dreamcli build", + "build:watch": "bun run --filter @kjanat/dreamcli build:watch", + "ci": "bun run typecheck && bun run lint && bun run format:check && bun run meta-descriptions:check && bun run test && bun run docs:build && bun run build", + "coverage": "bun run --filter @kjanat/dreamcli coverage", + "dev": "bun run --filter @kjanat/dreamcli build:watch & bun run --filter @kjanat/dreamcli-docs dev & wait", + "docs:build": "bun run --filter @kjanat/dreamcli-docs build", + "docs:dev": "bun run --filter @kjanat/dreamcli-docs dev", + "docs:preview": "bun run --filter @kjanat/dreamcli-docs preview", "fmt": "dprint fmt", "format": "dprint fmt", "format:check": "dprint check", @@ -95,46 +32,22 @@ "lint:fix": "biome lint --fix", "meta-descriptions": "bun --bun scripts/build-meta-descriptions.ts", "meta-descriptions:check": "bun --bun scripts/build-meta-descriptions.ts --check", - "prepack": "bunx --bun tsdown --logLevel silent", - "test": "vitest run", - "test:watch": "vitest", - "typecheck": "tsgo --noEmit", - "typecheck:tsc": "tsc --noEmit", + "test": "bun run --filter '*' test", + "test:watch": "bun run --filter @kjanat/dreamcli test:watch", + "typecheck": "bun run --filter @kjanat/dreamcli typecheck && bun --cwd examples/gh typecheck", + "typecheck:tsc": "bun run --filter @kjanat/dreamcli typecheck:tsc", "upgrade": "bun update --latest && bun add -D vitepress@next" }, "devDependencies": { - "@arethetypeswrong/core": "^0.18.2", "@biomejs/biome": "^2.4.10", - "@iarna/toml": "^2.2.5", - "@shikijs/transformers": "^4.0.2", - "@shikijs/vitepress-twoslash": "^4.0.2", - "@types/bun": "catalog:", - "@types/deno": "^2.5.0", - "@types/node": "catalog:", - "@typescript/native-preview": "^7.0.0-dev.20260406.1", - "@vitest/coverage-v8": "^4.1.2", + "@kjanat/dreamcli": "workspace:*", + "@kjanat/dreamcli-docs": "workspace:*", + "@kjanat/gh-project": "workspace:*", "dprint": "^0.53.2", - "floating-vue": "^5.2.2", "knip": "^6.3.0", - "mermaid": "^11.14.0", - "publint": "^0.3.18", - "tsdown": "^0.21.7", - "typedoc": "^0.28.18", - "typescript": "catalog:", - "vitepress": "^2.0.0-alpha.17", - "vitest": "^4.1.2", - "wrangler": "^4.80.0", - "yaml": "^2.8.3" - }, - "optionalDependencies": { - "vite": "^8" + "wrangler": "^4.80.0" }, "packageManager": "bun@1.3.11", - "engines": { - "bun": ">=1.3.11", - "deno": ">=2.6.0", - "node": ">=22.22.2" - }, "devEngines": { "packageManager": { "name": "bun", @@ -149,13 +62,10 @@ "node": "25.8.2", "npm": "11.12.1" }, - "publishConfig": { - "access": "public", - "provenance": true - }, "catalog": { "@types/bun": "^1.3.0", "@types/node": ">=22.0.0, <23.0.0", - "typescript": "^6.0.2" + "typescript": "^6.0.2", + "vitest": "^4.1.2" } } diff --git a/.attw.json b/packages/dreamcli/.attw.json similarity index 100% rename from .attw.json rename to packages/dreamcli/.attw.json diff --git a/CHANGELOG.md b/packages/dreamcli/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to packages/dreamcli/CHANGELOG.md diff --git a/packages/dreamcli/LICENSE b/packages/dreamcli/LICENSE new file mode 100644 index 00000000..c1891e2a --- /dev/null +++ b/packages/dreamcli/LICENSE @@ -0,0 +1,22 @@ +MIT License +=========== + +Copyright (c) 2026 Kaj Kowalski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/dreamcli/README.md b/packages/dreamcli/README.md new file mode 100644 index 00000000..fe568eec --- /dev/null +++ b/packages/dreamcli/README.md @@ -0,0 +1,511 @@ +# dreamcli + +[![NPM](https://img.shields.io/npm/v/@kjanat/dreamcli?logo=npm&labelColor=CB3837&color=black)][npm] +[![JSR](https://img.shields.io/jsr/v/@kjanat/dreamcli?logoColor=083344&logo=jsr&logoSize=auto&label=&labelColor=f7df1e&color=black)][jsr] + +Schema-first, fully typed TypeScript CLI framework. Zero runtime dependencies. + +One flag declaration configures the entire resolution pipeline: + +```ts +import { + cli, + command, + flag, + arg, + middleware, + CLIError, +} from '@kjanat/dreamcli'; + +const deploy = command('deploy') + .description('Deploy to an environment') + .arg('target', arg.string().describe('Deploy target')) + .flag( + 'region', + flag + .enum(['us', 'eu', 'ap']) + .alias('r') + .env('DEPLOY_REGION') + .config('deploy.region') + .prompt({ kind: 'select', message: 'Which region?' }) + .default('us') + .propagate(), + ) + .action(({ args, flags, out }) => { + out.log(`Deploying ${args.target} to ${flags.region}`); + }); +``` + +By the time `action` runs, `flags.region` is `"us" | "eu" | "ap"` — not `string | undefined`. + +The value is resolved through a documented chain: + +```mermaid +flowchart LR + A[CLI argv] --> B[Environment variable] + B --> C[Config file] + C --> D[Interactive prompt] + D --> E[Default value] +``` + +Every step is opt-in. Every step preserves types. + +## Install + +```bash +npm install @kjanat/dreamcli +``` + +
bun/deno + +```bash +bun add @kjanat/dreamcli +``` + +```bash +deno add jsr:@kjanat/dreamcli # or npm:@kjanat/dreamcli +``` + +
+ +## Quick start + +### Single command + +```ts +import { command, flag, arg } from '@kjanat/dreamcli'; + +const greet = command('greet') + .description('Greet someone') + .arg('name', arg.string().describe('Who to greet')) + .flag( + 'loud', + flag + .boolean() + .alias('l') + .describe('Shout the greeting'), + ) + .flag( + 'times', + flag.number().default(1).describe('Repeat count'), + ) + .action(({ args, flags, out }) => { + for (let i = 0; i < flags.times; i++) { + const msg = `Hello, ${args.name}!`; + out.log(flags.loud ? msg.toUpperCase() : msg); + } + }); + +greet.run(); +``` + +### Multi-command CLI + +```ts +import { + cli, + command, + group, + flag, + arg, +} from '@kjanat/dreamcli'; + +const deploy = command('deploy') + .description('Deploy to an environment') + .arg('target', arg.string()) + .flag('force', flag.boolean().alias('f')) + .flag( + 'region', + flag.enum(['us', 'eu', 'ap']).env('DEPLOY_REGION'), + ) + .action(({ args, flags, out }) => { + out.log( + `Deploying ${args.target} to ${flags.region ?? 'default'}`, + ); + }); + +const login = command('login') + .description('Authenticate with the service') + .flag('token', flag.string().describe('Auth token')) + .action(({ flags, out }) => { + out.log( + flags.token + ? 'Authenticated via token' + : 'Authenticated interactively', + ); + }); + +// Nested command groups +const migrate = command('migrate') + .description('Run migrations') + .flag('steps', flag.number()) + .action(({ flags, out }) => { + out.log(`migrating ${flags.steps ?? 'all'} steps`); + }); + +const seed = command('seed') + .description('Seed database') + .action(({ out }) => { + out.log('seeding'); + }); + +const db = group('db') + .description('Database operations') + .command(migrate) + .command(seed); + +cli('mycli') + .version('1.0.0') + .description('My awesome tool') + .command(deploy) + .command(login) + .command(db) + .run(); + +// mycli deploy production --force +// mycli login --token abc123 +// mycli db migrate --steps 3 +// mycli db seed +``` + +## Why dreamcli + +Most TypeScript CLI frameworks treat the type system like decoration. +You define flags in one place, then use parsed values somewhere else as a loosely typed blob. +Env vars, config files, and interactive prompts live in separate universes. +Testing means hacking `process.argv`. + +dreamcli collapses all of that into a single typed schema: + +Approximate comparison of first-party, built-in support as documented by each project. +Third-party plugins and custom glue can extend the other libraries. + +| Capability | dreamcli | Commander | Yargs | Citty | CAC | Cleye | +| ------------------------------------------ | ------------------------------------- | ------------------- | ---------------------- | --------------- | ------------- | ------------- | +| Type inference from definition | Full — flags, args, context | Manual `.opts()` | Good | Good | Basic | Good | +| Built-in value sources | CLI, env, config, prompt, default | CLI, defaults, env | CLI, env, config | CLI, defaults | CLI, defaults | CLI, defaults | +| Schema-driven prompts | Integrated | No | No | No | No | No | +| Middleware / hooks | Yes — typed middleware | Lifecycle hooks | Middleware | Plugins / hooks | Events | No | +| Built-in test harness with output capture | `runCommand()` + capture | No | No | No | No | No | +| Shell completions from command definitions | Built-in (bash/zsh/fish/powershell) | No | Built-in (bash/zsh) | No | No | No | +| Structured output primitives | Built-in (`--json`, tables, spinners) | DIY | DIY | DIY | DIY | DIY | +| Config file support | Built-in (XDG discovery, JSON) | DIY | Built-in (`.config()`) | No | No | No | + +The closest analog is what tRPC did to API routes — individual pieces existed, +the insight was wiring them so types flow end-to-end. + +## Features + +### Flag types + +```ts +flag.string(); // string | undefined +flag.number(); // number | undefined +flag.boolean(); // boolean (defaults to false) +flag.enum(['us', 'eu', 'ap']); // "us" | "eu" | "ap" | undefined +flag.array(flag.string()); // string[] | undefined +flag.custom((v) => new URL(v)); // URL | undefined +``` + +Every flag supports: `.default()`, `.required()`, `.alias()`, `.env()`, `.config()`, `.describe()`, +`.prompt()`, `.deprecated()`, `.propagate()`. + +### Resolution chain + +Each flag resolves through an ordered pipeline. Every step is opt-in: + +```text +CLI argv → environment variable → config file → interactive prompt → default value +``` + +Required flags that don't resolve produce a structured error before the action handler runs. In +non-interactive contexts (CI, piped stdin), prompts are automatically skipped. + +### Interactive prompts + +Four prompt types, declared per-flag or per-command: + +```ts +// Per-flag +flag.string().prompt({ kind: 'input', message: 'Name?' }); +flag + .boolean() + .prompt({ kind: 'confirm', message: 'Sure?' }); +flag + .enum(['a', 'b']) + .prompt({ kind: 'select', message: 'Pick one' }); +flag.array(flag.string()).prompt({ + kind: 'multiselect', + message: 'Pick many', + choices: [{ value: 'a' }, { value: 'b' }], +}); + +// Per-command (conditional — receives partially resolved flags) +command('deploy') + .flag('region', flag.enum(['us', 'eu', 'ap'])) + .interactive(({ flags }) => ({ + region: !flags.region && { + kind: 'select', + message: 'Which region?', + }, + })); +``` + +### Derive typed context from resolved input + +```ts +import { CLIError } from '@kjanat/dreamcli'; + +command('deploy') + .flag('token', flag.string().env('AUTH_TOKEN')) + .derive(({ flags }) => { + if (!flags.token) + throw new CLIError('Not authenticated', { + code: 'AUTH_REQUIRED', + suggest: 'Run `mycli login`', + }); + return { token: flags.token }; + }) + .action(({ ctx }) => { + ctx.token; // string — typed + }); +``` + +Use `derive()` when you need typed, command-scoped access to fully resolved flags and args before +the action handler runs. + +### Middleware with typed context + +```ts +import { middleware } from '@kjanat/dreamcli'; + +const timing = middleware<{ startTime: number }>( + async ({ next }) => { + const startTime = Date.now(); + await next({ startTime }); + }, +); + +const trace = middleware<{ traceId: string }>( + async ({ next }) => + next({ traceId: crypto.randomUUID() }), +); + +command('deploy') + .middleware(timing) + .middleware(trace) + .action(({ ctx }) => { + ctx.startTime; // number — typed + ctx.traceId; // string — typed + }); +``` + +Context accumulates through the middleware chain via type intersection. +No manual interface merging. + +Use middleware when you need wrapper behavior with `next()`. + +### Output channel + +Handlers receive `out` instead of `console`. Adapts to context automatically: + +```ts +cli('mycli') + // ... omitted for brevity + .action(({ out }) => { + out.log('Human-readable message'); + out.json({ status: 'ok', count: 42 }); + out.table(rows, [ + { key: 'name', header: 'Name' }, + { key: 'status', header: 'Status' }, + ]); + + const spinner = out.spinner('Deploying...'); + spinner.succeed('Done'); + + const progress = out.progress({ + label: 'Uploading', + total: 100, + }); + progress.update(50); + progress.done('Upload complete'); + }); +``` + +- TTY → pretty formatting, spinners animate +- Piped → minimal stable output, spinners suppressed +- `--json` → structured JSON to stdout, everything else to stderr + +### Shell completions + +Generated from the command schema — always in sync: + +```ts +import { generateCompletion } from '@kjanat/dreamcli'; + +generateCompletion(myCli.schema, 'bash'); +generateCompletion(myCli.schema, 'zsh'); +``` + +### Config file discovery + +```ts +command('deploy').flag( + 'region', + flag.enum(['us', 'eu']).config('deploy.region'), +); +``` + +Searches XDG-standard paths automatically. JSON built-in, plugin hook for YAML/TOML: + +```ts +import { configFormat } from '@kjanat/dreamcli'; +import { parse as parseYAML } from 'yaml'; + +cli('mycli') + .config('mycli') + .configLoader(configFormat(['yaml', 'yml'], parseYAML)); +``` + +### Structured errors + +```ts +throw new CLIError('Deployment failed', { + code: 'DEPLOY_FAILED', + exitCode: 1, + suggest: 'Check your credentials with `mycli login`', + details: { target, region }, +}); +``` + +Parse and validation errors include "did you mean?" suggestions.\ +In `--json` mode, errors serialize to machine-readable JSON. + +## Testing + +`dreamcli`'s test harness runs commands in-process with full control over inputs and outputs. No +subprocesses, no `process.argv` mutation, no mocking. + +```ts +import { arg, command, flag } from '@kjanat/dreamcli'; +import { + runCommand, + createTestPrompter, + PROMPT_CANCEL, +} from '@kjanat/dreamcli/testkit'; + +const greet = command('greet') + .arg('name', arg.string()) + .flag('loud', flag.boolean()) + .action(({ args, flags, out }) => { + const message = `Hello, ${args.name}!`; + out.log(flags.loud ? message.toUpperCase() : message); + }); + +const deploy = command('deploy') + .arg('target', arg.string()) + .flag( + 'region', + flag + .enum(['us', 'eu', 'ap']) + .env('DEPLOY_REGION') + .config('deploy.region') + .required() + .prompt({ kind: 'select', message: 'Which region?' }), + ) + .action(({ args, flags, out }) => { + out.log(`Deploying ${args.target} to ${flags.region}`); + }); + +const build = command('build').action(({ out }) => { + const spinner = out.spinner('Building'); + spinner.succeed('Done'); +}); + +// Basic execution +const basic = await runCommand(greet, ['Alice', '--loud']); + +expect(basic.exitCode).toBe(0); +expect(basic.stdout).toEqual(['HELLO, ALICE!\n']); +expect(basic.stderr).toEqual([]); +expect(basic.error).toBeUndefined(); + +// Resolve from environment +const fromEnv = await runCommand(deploy, ['production'], { + env: { DEPLOY_REGION: 'eu' }, +}); +expect(fromEnv.stdout).toEqual([ + 'Deploying production to eu\n', +]); + +// Resolve from config +const fromConfig = await runCommand( + deploy, + ['production'], + { + config: { deploy: { region: 'us' } }, + }, +); +expect(fromConfig.stdout).toEqual([ + 'Deploying production to us\n', +]); + +// Resolve from prompt answers +const fromPrompt = await runCommand( + deploy, + ['production'], + { + answers: ['ap'], + }, +); +expect(fromPrompt.stdout).toEqual([ + 'Deploying production to ap\n', +]); + +// Simulate prompt cancellation +const cancelled = await runCommand(deploy, ['production'], { + prompter: createTestPrompter([PROMPT_CANCEL]), +}); +expect(cancelled.exitCode).not.toBe(0); + +// Activity events (spinners, progress) +const activity = await runCommand(build, []); +expect(activity.activity).toContainEqual( + expect.objectContaining({ type: 'spinner:start' }), +); +``` + +`RunOptions` accepts: `env`, `config`, `stdinData`, `answers`, `prompter`, `help`, `jsonMode`, +`verbosity`, and `isTTY`. Every dimension of command behavior is controllable from tests. + +## Package structure + +Three subpath exports, each with a focused API surface: + +| Import | Purpose | +| -------------------------- | -------------------------------------------------------------------------------------- | +| `@kjanat/dreamcli` | Schema builders, CLI runner, output, parsing, resolution, errors | +| `@kjanat/dreamcli/testkit` | `runCommand()`, `createCaptureOutput()`, `createTestPrompter()`, `createTestAdapter()` | +| `@kjanat/dreamcli/runtime` | `createAdapter()`, `RuntimeAdapter`, runtime detection, platform adapters | + +ESM-only. Source included in package (`src/`). + +## Runtime support + +| Runtime | Status | +| ------------------ | ----------------------------------- | +| Node.js >= 22.22.2 | Supported | +| Bun >= 1.3.11 | Supported | +| Deno >= 2.6.0 | Supported (JSR: `@kjanat/dreamcli`) | + +Runtime detection is automatic. +The core framework never imports platform-specific APIs directly — a thin `RuntimeAdapter` interface +handles the divergent edges (argv, env, filesystem, TTY detection, exit behavior). + +## License + +[MIT][LICENSE] © 2026 Kaj Kowalski + +[LICENSE]: https://github.com/kjanat/dreamcli/blob/master/LICENSE +[npm]: https://npm.im/@kjanat/dreamcli +[jsr]: https://jsr.io/@kjanat/dreamcli diff --git a/deno.json b/packages/dreamcli/deno.json similarity index 86% rename from deno.json rename to packages/dreamcli/deno.json index eca887a4..ba07b03e 100644 --- a/deno.json +++ b/packages/dreamcli/deno.json @@ -10,7 +10,7 @@ }, "smoke": { "description": "Run Deno adapter smoke test against source via import map", - "command": "deno run --allow-read --allow-env scripts/deno-smoke-test.ts" + "command": "deno run --allow-read --allow-env ../../scripts/deno-smoke-test.ts" }, "publish:dry": { "description": "Dry-run JSR publish to verify package shape", @@ -42,23 +42,12 @@ } }, "publish": { - "include": ["CHANGELOG.md", "LICENSE", "README.md", "dreamcli.schema.json", "examples", "src"], + "include": ["CHANGELOG.md", "LICENSE", "README.md", "dreamcli.schema.json", "src"], "exclude": ["src/**/*.test.ts", "src/**/*test-helpers.ts", "src/**/AGENTS.md"] }, "lib": ["deno.ns", "deno.shared_globals"], "fmt": { "exclude": ["**"] }, "lint": { "rules": { "exclude": ["ban-types", "require-await"] } }, "nodeModulesDir": "manual", - "exclude": [ - "**/*.test.ts", - "*.ts", - ".bucket/", - ".opencode/", - "*cache/", - "coverage/", - "dist/", - "docs/", - "examples/gh/", - "scripts/" - ] + "exclude": ["**/*.test.ts", "*.ts", "*cache/", "coverage/", "dist/", "scripts/"] } diff --git a/packages/dreamcli/dreamcli.schema.json b/packages/dreamcli/dreamcli.schema.json new file mode 100644 index 00000000..c2b02b35 --- /dev/null +++ b/packages/dreamcli/dreamcli.schema.json @@ -0,0 +1,290 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cdn.jsdelivr.net/npm/@kjanat/dreamcli/dreamcli.schema.json", + "title": "@kjanat/dreamcli definition schema", + "description": "Runtime descriptor for the CLI program.\n\nStores the program name, version, description, and registered commands.\\\nBuilt incrementally by CLIBuilder.", + "type": "object", + "additionalProperties": false, + "properties": { + "$schema": { + "const": "https://cdn.jsdelivr.net/npm/@kjanat/dreamcli/dreamcli.schema.json" + }, + "name": { + "type": "string", + "description": "Program name (used in help text, usage lines, and completion scripts)." + }, + "version": { + "type": "string", + "description": "Program version (shown by `--version`)." + }, + "description": { + "type": "string", + "description": "Program description (shown in root help)." + }, + "defaultCommand": { + "type": "string", + "description": "Default command dispatched when no subcommand matches.\n\nWhen set, the CLI root behaves like a hybrid command group: subcommands\ndispatch by name as usual, but empty argv or flags-only argv falls\nthrough to this command instead of showing root help.\n\nSet via the .default() builder method." + }, + "commands": { + "type": "array", + "items": { + "$ref": "#/$defs/command" + }, + "description": "Registered commands (type-erased for heterogeneous storage)." + } + }, + "required": ["$schema", "name", "commands"], + "$defs": { + "command": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The command name (used for dispatch, e.g. `'deploy'`)." + }, + "description": { + "type": "string", + "description": "Human-readable description for help text." + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Alternative names for this command." + }, + "hidden": { + "const": true, + "description": "Whether this command is hidden from help listings." + }, + "examples": { + "type": "array", + "items": { + "$ref": "#/$defs/example" + }, + "description": "Usage examples for help text." + }, + "flags": { + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/flag" + }, + "description": "Named flag schemas, keyed by flag name." + }, + "args": { + "type": "array", + "items": { + "$ref": "#/$defs/arg" + }, + "description": "Ordered positional arg entries (name + schema)." + }, + "commands": { + "type": "array", + "items": { + "$ref": "#/$defs/command" + }, + "description": "Nested subcommand schemas (for help rendering and completion).\n\nPure data — no execution closures. Populated by `.command()` on\n`CommandBuilder`. Empty for leaf commands." + } + }, + "required": ["name", "flags", "args", "commands"], + "description": "Runtime descriptor produced by CommandBuilder.\n\nConsumers (parser, help generator, CLI dispatcher) read this to\nunderstand the command's shape — flags, args, aliases, subcommands,\nmiddleware, and interactive resolver." + }, + "flag": { + "type": "object", + "additionalProperties": false, + "properties": { + "kind": { + "enum": ["string", "number", "boolean", "enum", "array", "custom"], + "description": "What kind of value this flag accepts." + }, + "presence": { + "enum": ["optional", "required", "defaulted"], + "description": "Presence describes whether a flag value is guaranteed to exist when the\naction handler runs:\n\n- `'optional'` — not required; unresolved value follows the kind-specific\n optional fallback (`undefined` for most flags, `[]` for arrays)\n- `'required'` — must be supplied; error if missing\n- `'defaulted'` — always present (falls back to default value)" + }, + "defaultValue": { + "description": "Runtime default value (if any)." + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Short/long aliases (e.g. `[{ name: 'f', hidden: false }]` for `--force`)." + }, + "envVar": { + "type": "string", + "description": "Environment variable name for v0.2+ resolution." + }, + "configPath": { + "type": "string", + "description": "Dotted config path for v0.2+ resolution (e.g. `'deploy.region'`)." + }, + "description": { + "type": "string", + "description": "Human-readable description for help text." + }, + "enumValues": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Allowed literal values when `kind === 'enum'`." + }, + "elementSchema": { + "$ref": "#/$defs/flag", + "description": "Element schema when `kind === 'array'`." + }, + "prompt": { + "$ref": "#/$defs/prompt", + "description": "Interactive prompt configuration for v0.3+ resolution." + }, + "deprecated": { + "oneOf": [ + { + "type": "string" + }, + { + "const": true + } + ], + "description": "Deprecation marker.\n\n- `undefined` — not deprecated (default)\n- `true` — deprecated with no migration message\n- `string` — deprecated with a reason/migration message\n\nWhen a deprecated flag is used, a warning is emitted to stderr.\nHelp text shows `[deprecated]` or `[deprecated: ]`." + }, + "propagate": { + "const": true, + "description": "Whether this flag propagates to subcommands in nested command trees.\n\nWhen `true`, the flag is automatically available to all descendant\ncommands. A child command that defines a flag with the same name\nshadows the propagated parent flag." + } + }, + "required": ["kind", "presence"], + "description": "The runtime descriptor stored inside every FlagBuilder. Consumers (parser,\nhelp generator, resolution chain) read this to understand the flag's shape\nwithout touching generics." + }, + "arg": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "A named positional argument entry in the command schema.\n\nPairs a user-facing arg name with its ArgSchema descriptor.\nThe array ordering in CommandSchema.args determines CLI position." + }, + "kind": { + "enum": ["string", "number", "enum", "custom"], + "description": "What kind of value this arg accepts." + }, + "presence": { + "enum": ["required", "optional", "defaulted"], + "description": "Presence describes whether a positional arg is guaranteed to exist when the\naction handler runs:\n\n- `'required'` — must be supplied; error if missing (default)\n- `'optional'` — may be `undefined` if not supplied\n- `'defaulted'` — always present (falls back to default value)" + }, + "variadic": { + "const": true, + "description": "Whether this arg consumes all remaining positionals." + }, + "stdinMode": { + "const": true, + "description": "Whether this arg may read from stdin during resolution." + }, + "defaultValue": { + "description": "Runtime default value (if any)." + }, + "description": { + "type": "string", + "description": "Human-readable description for help text." + }, + "envVar": { + "type": "string", + "description": "Environment variable name for env resolution.\n\nWhen set and the CLI value is absent, the resolver reads this env var\nand coerces the string to the arg's declared kind." + }, + "enumValues": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Allowed literal values when `kind === 'enum'`." + }, + "deprecated": { + "oneOf": [ + { + "type": "string" + }, + { + "const": true + } + ], + "description": "Deprecation marker.\n\n- `undefined` — not deprecated (default)\n- `true` — deprecated with no migration message\n- `string` — deprecated with a reason/migration message\n\nWhen a deprecated arg is used, a warning is emitted to stderr.\nHelp text shows `[deprecated]` or `[deprecated: ]`." + } + }, + "required": ["name", "kind", "presence"], + "description": "The runtime descriptor stored inside every ArgBuilder. Consumers (parser,\nhelp generator) read this to understand the arg's shape without touching\ngenerics." + }, + "prompt": { + "type": "object", + "additionalProperties": false, + "properties": { + "kind": { + "enum": ["confirm", "input", "select", "multiselect"], + "description": "The kind of interactive prompt to present.\n\n- `'confirm'` — yes/no boolean question\n- `'input'` — free-text string input\n- `'select'` — single selection from a list\n- `'multiselect'` — multiple selections from a list" + }, + "message": { + "type": "string", + "description": "The question displayed to the user." + }, + "placeholder": { + "type": "string", + "description": "Placeholder text shown before user types (informational only)." + }, + "choices": { + "type": "array", + "items": { + "$ref": "#/$defs/choice" + }, + "description": "Available choices. When omitted for `enum` flags, the enum values\nfrom the flag schema are used automatically." + }, + "min": { + "type": "integer", + "description": "Minimum number of selections required." + }, + "max": { + "type": "integer", + "description": "Maximum number of selections allowed." + } + }, + "required": ["kind", "message"], + "description": "Discriminated union of all prompt configurations.\n\nUse the `kind` field to narrow:\n```ts\nif (config.kind === 'select') {\n config.choices // readonly SelectChoice[] | undefined\n}\n```" + }, + "choice": { + "type": "object", + "additionalProperties": false, + "properties": { + "value": { + "type": "string", + "description": "The value returned when this choice is selected." + }, + "label": { + "type": "string", + "description": "Display label shown to the user." + }, + "description": { + "type": "string", + "description": "Optional description shown alongside the choice." + } + }, + "required": ["value"], + "description": "A selectable option for SelectPromptConfig and MultiselectPromptConfig prompts." + }, + "example": { + "type": "object", + "additionalProperties": false, + "properties": { + "command": { + "type": "string", + "description": "The command invocation (e.g. `'deploy production --force'`)." + }, + "description": { + "type": "string", + "description": "Optional description of what this example does." + } + }, + "required": ["command"], + "description": "A single usage example shown in help text." + } + } +} diff --git a/packages/dreamcli/package.json b/packages/dreamcli/package.json new file mode 100644 index 00000000..509bf894 --- /dev/null +++ b/packages/dreamcli/package.json @@ -0,0 +1,107 @@ +{ + "name": "@kjanat/dreamcli", + "version": "2.0.1", + "description": "Schema-first, fully typed TypeScript CLI framework", + "keywords": [ + "cli", + "typescript", + "framework", + "schema-first", + "command-line" + ], + "homepage": "https://dreamcli.kjanat.com", + "bugs": { + "url": "https://github.com/kjanat/dreamcli/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/kjanat/dreamcli.git", + "directory": "packages/dreamcli" + }, + "license": "MIT", + "author": { + "name": "Kaj Kowalski", + "email": "info@kajkowalski.nl", + "url": "https://github.com/kjanat" + }, + "type": "module", + "imports": { + "#dreamcli": "./src/index.ts", + "#dreamcli/runtime": "./src/runtime.ts", + "#dreamcli/testkit": "./src/testkit.ts", + "#internals/*": "./src/*", + "#schema": "./dreamcli.schema.json", + "#package.json": "./package.json" + }, + "exports": { + ".": { + "types": "./dist/index.d.mts", + "bun": "./src/index.ts", + "deno": "./src/index.ts", + "default": "./dist/index.mjs" + }, + "./runtime": { + "types": "./dist/runtime.d.mts", + "bun": "./src/runtime.ts", + "deno": "./src/runtime.ts", + "default": "./dist/runtime.mjs" + }, + "./testkit": { + "types": "./dist/testkit.d.mts", + "bun": "./src/testkit.ts", + "deno": "./src/testkit.ts", + "default": "./dist/testkit.mjs" + }, + "./schema": "./dreamcli.schema.json", + "./package.json": "./package.json" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "dist", + "dreamcli.schema.json", + "package.json", + "src", + "!src/**/*.test.ts", + "!src/**/*test-helpers.ts", + "!**/AGENTS.md" + ], + "scripts": { + "bd": "bunx --bun tsdown", + "build": "bunx --bun tsdown", + "build:watch": "bunx --bun tsdown --watch", + "coverage": "vitest run --coverage", + "prepack": "bunx --bun tsdown --logLevel silent", + "test": "vitest run", + "test:watch": "vitest", + "typecheck": "tsgo --noEmit", + "typecheck:tsc": "tsc --noEmit" + }, + "devDependencies": { + "@arethetypeswrong/core": "^0.18.2", + "@iarna/toml": "^2.2.5", + "@types/bun": "catalog:", + "@types/deno": "^2.5.0", + "@types/node": "catalog:", + "@typescript/native-preview": "^7.0.0-dev.20260406.1", + "@vitest/coverage-v8": "^4.1.2", + "publint": "^0.3.18", + "tsdown": "^0.21.7", + "typescript": "catalog:", + "vitest": "catalog:", + "yaml": "^2.8.3" + }, + "optionalDependencies": { + "vite": "^8" + }, + "engines": { + "bun": ">=1.3.11", + "deno": ">=2.6.0", + "node": ">=22.22.2" + }, + "publishConfig": { + "access": "public", + "provenance": true + } +} diff --git a/scripts/emit-definition-schema.ts b/packages/dreamcli/scripts/emit-definition-schema.ts similarity index 92% rename from scripts/emit-definition-schema.ts rename to packages/dreamcli/scripts/emit-definition-schema.ts index cebda4ba..406f65d9 100755 --- a/scripts/emit-definition-schema.ts +++ b/packages/dreamcli/scripts/emit-definition-schema.ts @@ -12,8 +12,8 @@ import { writeFile } from 'node:fs/promises'; import { normalize } from 'node:path'; import { exit } from 'node:process'; -import { definitionMetaSchema } from '@kjanat/dreamcli'; -import packageJson from '../package.json' with { type: 'json' }; +import { definitionMetaSchema } from '#dreamcli'; +import packageJson from '#package.json' with { type: 'json' }; const outFile = normalize(`${import.meta.dirname}/../dreamcli.schema.json`); diff --git a/src/core/cli/AGENTS.md b/packages/dreamcli/src/core/cli/AGENTS.md similarity index 100% rename from src/core/cli/AGENTS.md rename to packages/dreamcli/src/core/cli/AGENTS.md diff --git a/src/core/cli/cli-completion-contract.test.ts b/packages/dreamcli/src/core/cli/cli-completion-contract.test.ts similarity index 100% rename from src/core/cli/cli-completion-contract.test.ts rename to packages/dreamcli/src/core/cli/cli-completion-contract.test.ts diff --git a/src/core/cli/cli-completion-e2e.test.ts b/packages/dreamcli/src/core/cli/cli-completion-e2e.test.ts similarity index 100% rename from src/core/cli/cli-completion-e2e.test.ts rename to packages/dreamcli/src/core/cli/cli-completion-e2e.test.ts diff --git a/src/core/cli/cli-completions.test.ts b/packages/dreamcli/src/core/cli/cli-completions.test.ts similarity index 100% rename from src/core/cli/cli-completions.test.ts rename to packages/dreamcli/src/core/cli/cli-completions.test.ts diff --git a/src/core/cli/cli-config.test.ts b/packages/dreamcli/src/core/cli/cli-config.test.ts similarity index 100% rename from src/core/cli/cli-config.test.ts rename to packages/dreamcli/src/core/cli/cli-config.test.ts diff --git a/src/core/cli/cli-default.test.ts b/packages/dreamcli/src/core/cli/cli-default.test.ts similarity index 100% rename from src/core/cli/cli-default.test.ts rename to packages/dreamcli/src/core/cli/cli-default.test.ts diff --git a/src/core/cli/cli-dispatch.test.ts b/packages/dreamcli/src/core/cli/cli-dispatch.test.ts similarity index 100% rename from src/core/cli/cli-dispatch.test.ts rename to packages/dreamcli/src/core/cli/cli-dispatch.test.ts diff --git a/src/core/cli/cli-json.test.ts b/packages/dreamcli/src/core/cli/cli-json.test.ts similarity index 100% rename from src/core/cli/cli-json.test.ts rename to packages/dreamcli/src/core/cli/cli-json.test.ts diff --git a/src/core/cli/cli-middleware.test.ts b/packages/dreamcli/src/core/cli/cli-middleware.test.ts similarity index 100% rename from src/core/cli/cli-middleware.test.ts rename to packages/dreamcli/src/core/cli/cli-middleware.test.ts diff --git a/src/core/cli/cli-nesting.test.ts b/packages/dreamcli/src/core/cli/cli-nesting.test.ts similarity index 100% rename from src/core/cli/cli-nesting.test.ts rename to packages/dreamcli/src/core/cli/cli-nesting.test.ts diff --git a/src/core/cli/cli-package-json.test.ts b/packages/dreamcli/src/core/cli/cli-package-json.test.ts similarity index 100% rename from src/core/cli/cli-package-json.test.ts rename to packages/dreamcli/src/core/cli/cli-package-json.test.ts diff --git a/src/core/cli/cli-plugin.test.ts b/packages/dreamcli/src/core/cli/cli-plugin.test.ts similarity index 100% rename from src/core/cli/cli-plugin.test.ts rename to packages/dreamcli/src/core/cli/cli-plugin.test.ts diff --git a/src/core/cli/cli-propagate.test.ts b/packages/dreamcli/src/core/cli/cli-propagate.test.ts similarity index 100% rename from src/core/cli/cli-propagate.test.ts rename to packages/dreamcli/src/core/cli/cli-propagate.test.ts diff --git a/src/core/cli/cli-tty.test.ts b/packages/dreamcli/src/core/cli/cli-tty.test.ts similarity index 100% rename from src/core/cli/cli-tty.test.ts rename to packages/dreamcli/src/core/cli/cli-tty.test.ts diff --git a/src/core/cli/cli.test.ts b/packages/dreamcli/src/core/cli/cli.test.ts similarity index 100% rename from src/core/cli/cli.test.ts rename to packages/dreamcli/src/core/cli/cli.test.ts diff --git a/src/core/cli/dispatch.ts b/packages/dreamcli/src/core/cli/dispatch.ts similarity index 100% rename from src/core/cli/dispatch.ts rename to packages/dreamcli/src/core/cli/dispatch.ts diff --git a/src/core/cli/index.ts b/packages/dreamcli/src/core/cli/index.ts similarity index 100% rename from src/core/cli/index.ts rename to packages/dreamcli/src/core/cli/index.ts diff --git a/src/core/cli/planner.test.ts b/packages/dreamcli/src/core/cli/planner.test.ts similarity index 100% rename from src/core/cli/planner.test.ts rename to packages/dreamcli/src/core/cli/planner.test.ts diff --git a/src/core/cli/planner.ts b/packages/dreamcli/src/core/cli/planner.ts similarity index 100% rename from src/core/cli/planner.ts rename to packages/dreamcli/src/core/cli/planner.ts diff --git a/src/core/cli/plugin.ts b/packages/dreamcli/src/core/cli/plugin.ts similarity index 100% rename from src/core/cli/plugin.ts rename to packages/dreamcli/src/core/cli/plugin.ts diff --git a/src/core/cli/propagate.ts b/packages/dreamcli/src/core/cli/propagate.ts similarity index 100% rename from src/core/cli/propagate.ts rename to packages/dreamcli/src/core/cli/propagate.ts diff --git a/src/core/cli/root-help.ts b/packages/dreamcli/src/core/cli/root-help.ts similarity index 100% rename from src/core/cli/root-help.ts rename to packages/dreamcli/src/core/cli/root-help.ts diff --git a/src/core/cli/root-surface.ts b/packages/dreamcli/src/core/cli/root-surface.ts similarity index 100% rename from src/core/cli/root-surface.ts rename to packages/dreamcli/src/core/cli/root-surface.ts diff --git a/src/core/cli/runtime-preflight.test.ts b/packages/dreamcli/src/core/cli/runtime-preflight.test.ts similarity index 100% rename from src/core/cli/runtime-preflight.test.ts rename to packages/dreamcli/src/core/cli/runtime-preflight.test.ts diff --git a/src/core/cli/runtime-preflight.ts b/packages/dreamcli/src/core/cli/runtime-preflight.ts similarity index 100% rename from src/core/cli/runtime-preflight.ts rename to packages/dreamcli/src/core/cli/runtime-preflight.ts diff --git a/src/core/completion/AGENTS.md b/packages/dreamcli/src/core/completion/AGENTS.md similarity index 100% rename from src/core/completion/AGENTS.md rename to packages/dreamcli/src/core/completion/AGENTS.md diff --git a/src/core/completion/completion-test-helpers.ts b/packages/dreamcli/src/core/completion/completion-test-helpers.ts similarity index 100% rename from src/core/completion/completion-test-helpers.ts rename to packages/dreamcli/src/core/completion/completion-test-helpers.ts diff --git a/src/core/completion/completion.test.ts b/packages/dreamcli/src/core/completion/completion.test.ts similarity index 100% rename from src/core/completion/completion.test.ts rename to packages/dreamcli/src/core/completion/completion.test.ts diff --git a/src/core/completion/index.ts b/packages/dreamcli/src/core/completion/index.ts similarity index 100% rename from src/core/completion/index.ts rename to packages/dreamcli/src/core/completion/index.ts diff --git a/src/core/completion/shells/bash.ts b/packages/dreamcli/src/core/completion/shells/bash.ts similarity index 100% rename from src/core/completion/shells/bash.ts rename to packages/dreamcli/src/core/completion/shells/bash.ts diff --git a/src/core/completion/shells/fish.ts b/packages/dreamcli/src/core/completion/shells/fish.ts similarity index 100% rename from src/core/completion/shells/fish.ts rename to packages/dreamcli/src/core/completion/shells/fish.ts diff --git a/src/core/completion/shells/powershell.ts b/packages/dreamcli/src/core/completion/shells/powershell.ts similarity index 100% rename from src/core/completion/shells/powershell.ts rename to packages/dreamcli/src/core/completion/shells/powershell.ts diff --git a/src/core/completion/shells/shared.ts b/packages/dreamcli/src/core/completion/shells/shared.ts similarity index 100% rename from src/core/completion/shells/shared.ts rename to packages/dreamcli/src/core/completion/shells/shared.ts diff --git a/src/core/completion/shells/zsh.ts b/packages/dreamcli/src/core/completion/shells/zsh.ts similarity index 100% rename from src/core/completion/shells/zsh.ts rename to packages/dreamcli/src/core/completion/shells/zsh.ts diff --git a/src/core/config/AGENTS.md b/packages/dreamcli/src/core/config/AGENTS.md similarity index 100% rename from src/core/config/AGENTS.md rename to packages/dreamcli/src/core/config/AGENTS.md diff --git a/src/core/config/config.test.ts b/packages/dreamcli/src/core/config/config.test.ts similarity index 100% rename from src/core/config/config.test.ts rename to packages/dreamcli/src/core/config/config.test.ts diff --git a/src/core/config/index.ts b/packages/dreamcli/src/core/config/index.ts similarity index 100% rename from src/core/config/index.ts rename to packages/dreamcli/src/core/config/index.ts diff --git a/src/core/config/package-json.test.ts b/packages/dreamcli/src/core/config/package-json.test.ts similarity index 100% rename from src/core/config/package-json.test.ts rename to packages/dreamcli/src/core/config/package-json.test.ts diff --git a/src/core/config/package-json.ts b/packages/dreamcli/src/core/config/package-json.ts similarity index 100% rename from src/core/config/package-json.ts rename to packages/dreamcli/src/core/config/package-json.ts diff --git a/src/core/errors/errors.test.ts b/packages/dreamcli/src/core/errors/errors.test.ts similarity index 100% rename from src/core/errors/errors.test.ts rename to packages/dreamcli/src/core/errors/errors.test.ts diff --git a/src/core/errors/index.ts b/packages/dreamcli/src/core/errors/index.ts similarity index 100% rename from src/core/errors/index.ts rename to packages/dreamcli/src/core/errors/index.ts diff --git a/src/core/execution/index.ts b/packages/dreamcli/src/core/execution/index.ts similarity index 100% rename from src/core/execution/index.ts rename to packages/dreamcli/src/core/execution/index.ts diff --git a/src/core/help/AGENTS.md b/packages/dreamcli/src/core/help/AGENTS.md similarity index 100% rename from src/core/help/AGENTS.md rename to packages/dreamcli/src/core/help/AGENTS.md diff --git a/src/core/help/help.test.ts b/packages/dreamcli/src/core/help/help.test.ts similarity index 100% rename from src/core/help/help.test.ts rename to packages/dreamcli/src/core/help/help.test.ts diff --git a/src/core/help/index.ts b/packages/dreamcli/src/core/help/index.ts similarity index 100% rename from src/core/help/index.ts rename to packages/dreamcli/src/core/help/index.ts diff --git a/src/core/json-schema/AGENTS.md b/packages/dreamcli/src/core/json-schema/AGENTS.md similarity index 100% rename from src/core/json-schema/AGENTS.md rename to packages/dreamcli/src/core/json-schema/AGENTS.md diff --git a/src/core/json-schema/index.ts b/packages/dreamcli/src/core/json-schema/index.ts similarity index 100% rename from src/core/json-schema/index.ts rename to packages/dreamcli/src/core/json-schema/index.ts diff --git a/src/core/json-schema/json-schema.test.ts b/packages/dreamcli/src/core/json-schema/json-schema.test.ts similarity index 100% rename from src/core/json-schema/json-schema.test.ts rename to packages/dreamcli/src/core/json-schema/json-schema.test.ts diff --git a/src/core/json-schema/meta-descriptions.generated.ts b/packages/dreamcli/src/core/json-schema/meta-descriptions.generated.ts similarity index 100% rename from src/core/json-schema/meta-descriptions.generated.ts rename to packages/dreamcli/src/core/json-schema/meta-descriptions.generated.ts diff --git a/src/core/output/AGENTS.md b/packages/dreamcli/src/core/output/AGENTS.md similarity index 100% rename from src/core/output/AGENTS.md rename to packages/dreamcli/src/core/output/AGENTS.md diff --git a/src/core/output/activity.ts b/packages/dreamcli/src/core/output/activity.ts similarity index 100% rename from src/core/output/activity.ts rename to packages/dreamcli/src/core/output/activity.ts diff --git a/src/core/output/contracts.test.ts b/packages/dreamcli/src/core/output/contracts.test.ts similarity index 100% rename from src/core/output/contracts.test.ts rename to packages/dreamcli/src/core/output/contracts.test.ts diff --git a/src/core/output/contracts.ts b/packages/dreamcli/src/core/output/contracts.ts similarity index 100% rename from src/core/output/contracts.ts rename to packages/dreamcli/src/core/output/contracts.ts diff --git a/src/core/output/display-value.ts b/packages/dreamcli/src/core/output/display-value.ts similarity index 100% rename from src/core/output/display-value.ts rename to packages/dreamcli/src/core/output/display-value.ts diff --git a/src/core/output/index.ts b/packages/dreamcli/src/core/output/index.ts similarity index 100% rename from src/core/output/index.ts rename to packages/dreamcli/src/core/output/index.ts diff --git a/src/core/output/output-activity-dispatch.test.ts b/packages/dreamcli/src/core/output/output-activity-dispatch.test.ts similarity index 100% rename from src/core/output/output-activity-dispatch.test.ts rename to packages/dreamcli/src/core/output/output-activity-dispatch.test.ts diff --git a/src/core/output/output-progress.test.ts b/packages/dreamcli/src/core/output/output-progress.test.ts similarity index 100% rename from src/core/output/output-progress.test.ts rename to packages/dreamcli/src/core/output/output-progress.test.ts diff --git a/src/core/output/output-spinner.test.ts b/packages/dreamcli/src/core/output/output-spinner.test.ts similarity index 100% rename from src/core/output/output-spinner.test.ts rename to packages/dreamcli/src/core/output/output-spinner.test.ts diff --git a/src/core/output/output-table.test.ts b/packages/dreamcli/src/core/output/output-table.test.ts similarity index 100% rename from src/core/output/output-table.test.ts rename to packages/dreamcli/src/core/output/output-table.test.ts diff --git a/src/core/output/output-tty.test.ts b/packages/dreamcli/src/core/output/output-tty.test.ts similarity index 100% rename from src/core/output/output-tty.test.ts rename to packages/dreamcli/src/core/output/output-tty.test.ts diff --git a/src/core/output/output.test.ts b/packages/dreamcli/src/core/output/output.test.ts similarity index 100% rename from src/core/output/output.test.ts rename to packages/dreamcli/src/core/output/output.test.ts diff --git a/src/core/output/renderers.ts b/packages/dreamcli/src/core/output/renderers.ts similarity index 100% rename from src/core/output/renderers.ts rename to packages/dreamcli/src/core/output/renderers.ts diff --git a/src/core/output/writer.ts b/packages/dreamcli/src/core/output/writer.ts similarity index 100% rename from src/core/output/writer.ts rename to packages/dreamcli/src/core/output/writer.ts diff --git a/src/core/parse/AGENTS.md b/packages/dreamcli/src/core/parse/AGENTS.md similarity index 100% rename from src/core/parse/AGENTS.md rename to packages/dreamcli/src/core/parse/AGENTS.md diff --git a/src/core/parse/index.ts b/packages/dreamcli/src/core/parse/index.ts similarity index 100% rename from src/core/parse/index.ts rename to packages/dreamcli/src/core/parse/index.ts diff --git a/src/core/parse/parse.test.ts b/packages/dreamcli/src/core/parse/parse.test.ts similarity index 100% rename from src/core/parse/parse.test.ts rename to packages/dreamcli/src/core/parse/parse.test.ts diff --git a/src/core/prompt/AGENTS.md b/packages/dreamcli/src/core/prompt/AGENTS.md similarity index 100% rename from src/core/prompt/AGENTS.md rename to packages/dreamcli/src/core/prompt/AGENTS.md diff --git a/src/core/prompt/index.ts b/packages/dreamcli/src/core/prompt/index.ts similarity index 100% rename from src/core/prompt/index.ts rename to packages/dreamcli/src/core/prompt/index.ts diff --git a/src/core/prompt/prompt.test.ts b/packages/dreamcli/src/core/prompt/prompt.test.ts similarity index 100% rename from src/core/prompt/prompt.test.ts rename to packages/dreamcli/src/core/prompt/prompt.test.ts diff --git a/src/core/resolve/AGENTS.md b/packages/dreamcli/src/core/resolve/AGENTS.md similarity index 100% rename from src/core/resolve/AGENTS.md rename to packages/dreamcli/src/core/resolve/AGENTS.md diff --git a/src/core/resolve/args.ts b/packages/dreamcli/src/core/resolve/args.ts similarity index 100% rename from src/core/resolve/args.ts rename to packages/dreamcli/src/core/resolve/args.ts diff --git a/src/core/resolve/coerce.ts b/packages/dreamcli/src/core/resolve/coerce.ts similarity index 100% rename from src/core/resolve/coerce.ts rename to packages/dreamcli/src/core/resolve/coerce.ts diff --git a/src/core/resolve/config.ts b/packages/dreamcli/src/core/resolve/config.ts similarity index 100% rename from src/core/resolve/config.ts rename to packages/dreamcli/src/core/resolve/config.ts diff --git a/src/core/resolve/contracts.test.ts b/packages/dreamcli/src/core/resolve/contracts.test.ts similarity index 100% rename from src/core/resolve/contracts.test.ts rename to packages/dreamcli/src/core/resolve/contracts.test.ts diff --git a/src/core/resolve/contracts.ts b/packages/dreamcli/src/core/resolve/contracts.ts similarity index 100% rename from src/core/resolve/contracts.ts rename to packages/dreamcli/src/core/resolve/contracts.ts diff --git a/src/core/resolve/errors.ts b/packages/dreamcli/src/core/resolve/errors.ts similarity index 100% rename from src/core/resolve/errors.ts rename to packages/dreamcli/src/core/resolve/errors.ts diff --git a/src/core/resolve/flags.ts b/packages/dreamcli/src/core/resolve/flags.ts similarity index 100% rename from src/core/resolve/flags.ts rename to packages/dreamcli/src/core/resolve/flags.ts diff --git a/src/core/resolve/index.ts b/packages/dreamcli/src/core/resolve/index.ts similarity index 100% rename from src/core/resolve/index.ts rename to packages/dreamcli/src/core/resolve/index.ts diff --git a/src/core/resolve/property.test.ts b/packages/dreamcli/src/core/resolve/property.test.ts similarity index 100% rename from src/core/resolve/property.test.ts rename to packages/dreamcli/src/core/resolve/property.test.ts diff --git a/src/core/resolve/property.ts b/packages/dreamcli/src/core/resolve/property.ts similarity index 100% rename from src/core/resolve/property.ts rename to packages/dreamcli/src/core/resolve/property.ts diff --git a/src/core/resolve/resolve-aggregation.test.ts b/packages/dreamcli/src/core/resolve/resolve-aggregation.test.ts similarity index 100% rename from src/core/resolve/resolve-aggregation.test.ts rename to packages/dreamcli/src/core/resolve/resolve-aggregation.test.ts diff --git a/src/core/resolve/resolve-arg-env.test.ts b/packages/dreamcli/src/core/resolve/resolve-arg-env.test.ts similarity index 100% rename from src/core/resolve/resolve-arg-env.test.ts rename to packages/dreamcli/src/core/resolve/resolve-arg-env.test.ts diff --git a/src/core/resolve/resolve-config.test.ts b/packages/dreamcli/src/core/resolve/resolve-config.test.ts similarity index 100% rename from src/core/resolve/resolve-config.test.ts rename to packages/dreamcli/src/core/resolve/resolve-config.test.ts diff --git a/src/core/resolve/resolve-env.test.ts b/packages/dreamcli/src/core/resolve/resolve-env.test.ts similarity index 100% rename from src/core/resolve/resolve-env.test.ts rename to packages/dreamcli/src/core/resolve/resolve-env.test.ts diff --git a/src/core/resolve/resolve-errors.test.ts b/packages/dreamcli/src/core/resolve/resolve-errors.test.ts similarity index 100% rename from src/core/resolve/resolve-errors.test.ts rename to packages/dreamcli/src/core/resolve/resolve-errors.test.ts diff --git a/src/core/resolve/resolve-integration.test.ts b/packages/dreamcli/src/core/resolve/resolve-integration.test.ts similarity index 100% rename from src/core/resolve/resolve-integration.test.ts rename to packages/dreamcli/src/core/resolve/resolve-integration.test.ts diff --git a/src/core/resolve/resolve-interactive.test.ts b/packages/dreamcli/src/core/resolve/resolve-interactive.test.ts similarity index 100% rename from src/core/resolve/resolve-interactive.test.ts rename to packages/dreamcli/src/core/resolve/resolve-interactive.test.ts diff --git a/src/core/resolve/resolve-prompt.test.ts b/packages/dreamcli/src/core/resolve/resolve-prompt.test.ts similarity index 100% rename from src/core/resolve/resolve-prompt.test.ts rename to packages/dreamcli/src/core/resolve/resolve-prompt.test.ts diff --git a/src/core/resolve/resolve-stdin.test.ts b/packages/dreamcli/src/core/resolve/resolve-stdin.test.ts similarity index 100% rename from src/core/resolve/resolve-stdin.test.ts rename to packages/dreamcli/src/core/resolve/resolve-stdin.test.ts diff --git a/src/core/resolve/resolve.test.ts b/packages/dreamcli/src/core/resolve/resolve.test.ts similarity index 100% rename from src/core/resolve/resolve.test.ts rename to packages/dreamcli/src/core/resolve/resolve.test.ts diff --git a/src/core/schema-dsl/AGENTS.md b/packages/dreamcli/src/core/schema-dsl/AGENTS.md similarity index 100% rename from src/core/schema-dsl/AGENTS.md rename to packages/dreamcli/src/core/schema-dsl/AGENTS.md diff --git a/src/core/schema-dsl/index.ts b/packages/dreamcli/src/core/schema-dsl/index.ts similarity index 100% rename from src/core/schema-dsl/index.ts rename to packages/dreamcli/src/core/schema-dsl/index.ts diff --git a/src/core/schema-dsl/parse.ts b/packages/dreamcli/src/core/schema-dsl/parse.ts similarity index 100% rename from src/core/schema-dsl/parse.ts rename to packages/dreamcli/src/core/schema-dsl/parse.ts diff --git a/src/core/schema-dsl/runtime.ts b/packages/dreamcli/src/core/schema-dsl/runtime.ts similarity index 100% rename from src/core/schema-dsl/runtime.ts rename to packages/dreamcli/src/core/schema-dsl/runtime.ts diff --git a/src/core/schema-dsl/schema-dsl.test.ts b/packages/dreamcli/src/core/schema-dsl/schema-dsl.test.ts similarity index 100% rename from src/core/schema-dsl/schema-dsl.test.ts rename to packages/dreamcli/src/core/schema-dsl/schema-dsl.test.ts diff --git a/src/core/schema-dsl/to-json-schema.ts b/packages/dreamcli/src/core/schema-dsl/to-json-schema.ts similarity index 100% rename from src/core/schema-dsl/to-json-schema.ts rename to packages/dreamcli/src/core/schema-dsl/to-json-schema.ts diff --git a/src/core/schema/AGENTS.md b/packages/dreamcli/src/core/schema/AGENTS.md similarity index 100% rename from src/core/schema/AGENTS.md rename to packages/dreamcli/src/core/schema/AGENTS.md diff --git a/src/core/schema/activity.ts b/packages/dreamcli/src/core/schema/activity.ts similarity index 100% rename from src/core/schema/activity.ts rename to packages/dreamcli/src/core/schema/activity.ts diff --git a/src/core/schema/arg.test.ts b/packages/dreamcli/src/core/schema/arg.test.ts similarity index 100% rename from src/core/schema/arg.test.ts rename to packages/dreamcli/src/core/schema/arg.test.ts diff --git a/src/core/schema/arg.ts b/packages/dreamcli/src/core/schema/arg.ts similarity index 100% rename from src/core/schema/arg.ts rename to packages/dreamcli/src/core/schema/arg.ts diff --git a/src/core/schema/command.test.ts b/packages/dreamcli/src/core/schema/command.test.ts similarity index 100% rename from src/core/schema/command.test.ts rename to packages/dreamcli/src/core/schema/command.test.ts diff --git a/src/core/schema/command.ts b/packages/dreamcli/src/core/schema/command.ts similarity index 100% rename from src/core/schema/command.ts rename to packages/dreamcli/src/core/schema/command.ts diff --git a/src/core/schema/derive.test.ts b/packages/dreamcli/src/core/schema/derive.test.ts similarity index 100% rename from src/core/schema/derive.test.ts rename to packages/dreamcli/src/core/schema/derive.test.ts diff --git a/src/core/schema/flag.test.ts b/packages/dreamcli/src/core/schema/flag.test.ts similarity index 100% rename from src/core/schema/flag.test.ts rename to packages/dreamcli/src/core/schema/flag.test.ts diff --git a/src/core/schema/flag.ts b/packages/dreamcli/src/core/schema/flag.ts similarity index 100% rename from src/core/schema/flag.ts rename to packages/dreamcli/src/core/schema/flag.ts diff --git a/src/core/schema/index.ts b/packages/dreamcli/src/core/schema/index.ts similarity index 100% rename from src/core/schema/index.ts rename to packages/dreamcli/src/core/schema/index.ts diff --git a/src/core/schema/middleware.test.ts b/packages/dreamcli/src/core/schema/middleware.test.ts similarity index 100% rename from src/core/schema/middleware.test.ts rename to packages/dreamcli/src/core/schema/middleware.test.ts diff --git a/src/core/schema/middleware.ts b/packages/dreamcli/src/core/schema/middleware.ts similarity index 100% rename from src/core/schema/middleware.ts rename to packages/dreamcli/src/core/schema/middleware.ts diff --git a/src/core/schema/prompt.test.ts b/packages/dreamcli/src/core/schema/prompt.test.ts similarity index 100% rename from src/core/schema/prompt.test.ts rename to packages/dreamcli/src/core/schema/prompt.test.ts diff --git a/src/core/schema/prompt.ts b/packages/dreamcli/src/core/schema/prompt.ts similarity index 100% rename from src/core/schema/prompt.ts rename to packages/dreamcli/src/core/schema/prompt.ts diff --git a/src/core/schema/run.ts b/packages/dreamcli/src/core/schema/run.ts similarity index 100% rename from src/core/schema/run.ts rename to packages/dreamcli/src/core/schema/run.ts diff --git a/src/core/testkit/AGENTS.md b/packages/dreamcli/src/core/testkit/AGENTS.md similarity index 100% rename from src/core/testkit/AGENTS.md rename to packages/dreamcli/src/core/testkit/AGENTS.md diff --git a/src/core/testkit/executor-contract.test.ts b/packages/dreamcli/src/core/testkit/executor-contract.test.ts similarity index 100% rename from src/core/testkit/executor-contract.test.ts rename to packages/dreamcli/src/core/testkit/executor-contract.test.ts diff --git a/src/core/testkit/index.ts b/packages/dreamcli/src/core/testkit/index.ts similarity index 100% rename from src/core/testkit/index.ts rename to packages/dreamcli/src/core/testkit/index.ts diff --git a/src/core/testkit/middleware-context-e2e.test.ts b/packages/dreamcli/src/core/testkit/middleware-context-e2e.test.ts similarity index 100% rename from src/core/testkit/middleware-context-e2e.test.ts rename to packages/dreamcli/src/core/testkit/middleware-context-e2e.test.ts diff --git a/src/core/testkit/output-e2e.test.ts b/packages/dreamcli/src/core/testkit/output-e2e.test.ts similarity index 100% rename from src/core/testkit/output-e2e.test.ts rename to packages/dreamcli/src/core/testkit/output-e2e.test.ts diff --git a/src/core/testkit/testkit-json.test.ts b/packages/dreamcli/src/core/testkit/testkit-json.test.ts similarity index 100% rename from src/core/testkit/testkit-json.test.ts rename to packages/dreamcli/src/core/testkit/testkit-json.test.ts diff --git a/src/core/testkit/testkit-nesting.test.ts b/packages/dreamcli/src/core/testkit/testkit-nesting.test.ts similarity index 100% rename from src/core/testkit/testkit-nesting.test.ts rename to packages/dreamcli/src/core/testkit/testkit-nesting.test.ts diff --git a/src/core/testkit/testkit-prompt.test.ts b/packages/dreamcli/src/core/testkit/testkit-prompt.test.ts similarity index 100% rename from src/core/testkit/testkit-prompt.test.ts rename to packages/dreamcli/src/core/testkit/testkit-prompt.test.ts diff --git a/src/core/testkit/testkit-stdin.test.ts b/packages/dreamcli/src/core/testkit/testkit-stdin.test.ts similarity index 100% rename from src/core/testkit/testkit-stdin.test.ts rename to packages/dreamcli/src/core/testkit/testkit-stdin.test.ts diff --git a/src/core/testkit/testkit-tty.test.ts b/packages/dreamcli/src/core/testkit/testkit-tty.test.ts similarity index 100% rename from src/core/testkit/testkit-tty.test.ts rename to packages/dreamcli/src/core/testkit/testkit-tty.test.ts diff --git a/src/core/testkit/testkit.test.ts b/packages/dreamcli/src/core/testkit/testkit.test.ts similarity index 100% rename from src/core/testkit/testkit.test.ts rename to packages/dreamcli/src/core/testkit/testkit.test.ts diff --git a/src/index.test.ts b/packages/dreamcli/src/index.test.ts similarity index 100% rename from src/index.test.ts rename to packages/dreamcli/src/index.test.ts diff --git a/src/index.ts b/packages/dreamcli/src/index.ts similarity index 100% rename from src/index.ts rename to packages/dreamcli/src/index.ts diff --git a/src/runtime.ts b/packages/dreamcli/src/runtime.ts similarity index 100% rename from src/runtime.ts rename to packages/dreamcli/src/runtime.ts diff --git a/src/runtime/AGENTS.md b/packages/dreamcli/src/runtime/AGENTS.md similarity index 100% rename from src/runtime/AGENTS.md rename to packages/dreamcli/src/runtime/AGENTS.md diff --git a/src/runtime/adapter.ts b/packages/dreamcli/src/runtime/adapter.ts similarity index 100% rename from src/runtime/adapter.ts rename to packages/dreamcli/src/runtime/adapter.ts diff --git a/src/runtime/auto.test.ts b/packages/dreamcli/src/runtime/auto.test.ts similarity index 100% rename from src/runtime/auto.test.ts rename to packages/dreamcli/src/runtime/auto.test.ts diff --git a/src/runtime/auto.ts b/packages/dreamcli/src/runtime/auto.ts similarity index 100% rename from src/runtime/auto.ts rename to packages/dreamcli/src/runtime/auto.ts diff --git a/src/runtime/bun.test.ts b/packages/dreamcli/src/runtime/bun.test.ts similarity index 100% rename from src/runtime/bun.test.ts rename to packages/dreamcli/src/runtime/bun.test.ts diff --git a/src/runtime/bun.ts b/packages/dreamcli/src/runtime/bun.ts similarity index 100% rename from src/runtime/bun.ts rename to packages/dreamcli/src/runtime/bun.ts diff --git a/src/runtime/deno.test.ts b/packages/dreamcli/src/runtime/deno.test.ts similarity index 100% rename from src/runtime/deno.test.ts rename to packages/dreamcli/src/runtime/deno.test.ts diff --git a/src/runtime/deno.ts b/packages/dreamcli/src/runtime/deno.ts similarity index 100% rename from src/runtime/deno.ts rename to packages/dreamcli/src/runtime/deno.ts diff --git a/src/runtime/detect.test.ts b/packages/dreamcli/src/runtime/detect.test.ts similarity index 100% rename from src/runtime/detect.test.ts rename to packages/dreamcli/src/runtime/detect.test.ts diff --git a/src/runtime/detect.ts b/packages/dreamcli/src/runtime/detect.ts similarity index 100% rename from src/runtime/detect.ts rename to packages/dreamcli/src/runtime/detect.ts diff --git a/src/runtime/index.ts b/packages/dreamcli/src/runtime/index.ts similarity index 100% rename from src/runtime/index.ts rename to packages/dreamcli/src/runtime/index.ts diff --git a/src/runtime/node-builtins.d.ts b/packages/dreamcli/src/runtime/node-builtins.d.ts similarity index 100% rename from src/runtime/node-builtins.d.ts rename to packages/dreamcli/src/runtime/node-builtins.d.ts diff --git a/src/runtime/node.ts b/packages/dreamcli/src/runtime/node.ts similarity index 100% rename from src/runtime/node.ts rename to packages/dreamcli/src/runtime/node.ts diff --git a/src/runtime/paths.ts b/packages/dreamcli/src/runtime/paths.ts similarity index 100% rename from src/runtime/paths.ts rename to packages/dreamcli/src/runtime/paths.ts diff --git a/src/runtime/runtime.test.ts b/packages/dreamcli/src/runtime/runtime.test.ts similarity index 100% rename from src/runtime/runtime.test.ts rename to packages/dreamcli/src/runtime/runtime.test.ts diff --git a/src/runtime/support.test.ts b/packages/dreamcli/src/runtime/support.test.ts similarity index 87% rename from src/runtime/support.test.ts rename to packages/dreamcli/src/runtime/support.test.ts index 24851fb6..bd8fb9f0 100644 --- a/src/runtime/support.test.ts +++ b/packages/dreamcli/src/runtime/support.test.ts @@ -41,7 +41,7 @@ describe('runtime — compatibility matrix stays aligned', () => { }); it('documents the guide runtime support matrix', async () => { - const docs = await readUtf8(new URL('../../docs/guide/runtime.md', import.meta.url)); + const docs = await readUtf8(new URL('../../../../apps/docs/guide/runtime.md', import.meta.url)); for (const runtime of SUPPORTED_RUNTIMES) { expect(docs).toContain(formatRuntimeRequirement(runtime.runtime)); @@ -51,7 +51,9 @@ describe('runtime — compatibility matrix stays aligned', () => { }); it('documents the reference runtime support matrix', async () => { - const docs = await readUtf8(new URL('../../docs/reference/runtime.md', import.meta.url)); + const docs = await readUtf8( + new URL('../../../../apps/docs/reference/runtime.md', import.meta.url), + ); for (const runtime of SUPPORTED_RUNTIMES) { expect(docs).toContain(formatRuntimeRequirement(runtime.runtime)); @@ -60,7 +62,9 @@ describe('runtime — compatibility matrix stays aligned', () => { }); it('mentions the same minimum versions in getting started', async () => { - const docs = await readUtf8(new URL('../../docs/guide/getting-started.md', import.meta.url)); + const docs = await readUtf8( + new URL('../../../../apps/docs/guide/getting-started.md', import.meta.url), + ); for (const runtime of SUPPORTED_RUNTIMES) { const { displayName, minimum } = getRuntimeSupport(runtime.runtime); diff --git a/src/runtime/support.ts b/packages/dreamcli/src/runtime/support.ts similarity index 100% rename from src/runtime/support.ts rename to packages/dreamcli/src/runtime/support.ts diff --git a/src/runtime/test-helpers.ts b/packages/dreamcli/src/runtime/test-helpers.ts similarity index 100% rename from src/runtime/test-helpers.ts rename to packages/dreamcli/src/runtime/test-helpers.ts diff --git a/src/testkit.ts b/packages/dreamcli/src/testkit.ts similarity index 100% rename from src/testkit.ts rename to packages/dreamcli/src/testkit.ts diff --git a/src/version.ts b/packages/dreamcli/src/version.ts similarity index 100% rename from src/version.ts rename to packages/dreamcli/src/version.ts diff --git a/packages/dreamcli/tsconfig.json b/packages/dreamcli/tsconfig.json new file mode 100644 index 00000000..857e5cc9 --- /dev/null +++ b/packages/dreamcli/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "types": ["bun", "node", "deno", "vitest"], + "paths": { + "@kjanat/dreamcli": ["./src/index.ts"], + "@kjanat/dreamcli/runtime": ["./src/runtime.ts"], + "@kjanat/dreamcli/testkit": ["./src/testkit.ts"], + "@kjanat/dreamcli/schema": ["./dreamcli.schema.json"], + "@kjanat/dreamcli/package.json": ["./package.json"] + } + }, + "include": ["src"], + "exclude": ["**/dist", "**/node_modules"] +} diff --git a/tsdown.config.ts b/packages/dreamcli/tsdown.config.ts similarity index 96% rename from tsdown.config.ts rename to packages/dreamcli/tsdown.config.ts index 499a4b94..dca74ad7 100644 --- a/tsdown.config.ts +++ b/packages/dreamcli/tsdown.config.ts @@ -39,5 +39,5 @@ export default defineConfig({ return emitDefinitionSchema(); }, }, - onSuccess: 'bun fmt package.json', + onSuccess: 'bunx --bun dprint fmt package.json', }); diff --git a/vitest.config.ts b/packages/dreamcli/vitest.config.ts similarity index 68% rename from vitest.config.ts rename to packages/dreamcli/vitest.config.ts index 9905a59d..5ded7515 100644 --- a/vitest.config.ts +++ b/packages/dreamcli/vitest.config.ts @@ -2,12 +2,11 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { - include: ['src/**/*.test.ts', 'docs/.vitepress/data/*.test.ts'], + include: ['src/**/*.test.ts'], coverage: { - include: ['src/**/*.ts', 'docs/.vitepress/data/*.ts'], + include: ['src/**/*.ts'], exclude: [ 'src/**/*.test.ts', - 'docs/.vitepress/data/*.test.ts', 'src/**/index.ts', '**/*.d.ts', 'src/core/json-schema/meta-descriptions.generated.ts', diff --git a/scripts/build-meta-descriptions.ts b/scripts/build-meta-descriptions.ts index 993d1961..376211b6 100644 --- a/scripts/build-meta-descriptions.ts +++ b/scripts/build-meta-descriptions.ts @@ -13,16 +13,16 @@ import { readFile, rm, writeFile } from 'node:fs/promises'; import { dirname, join } from 'node:path'; -import { collectPublicApiIndex } from '../docs/.vitepress/data/api-index.ts'; +import { collectPublicApiIndex } from '../apps/docs/.vitepress/data/api-index.ts'; import { buildDefinitionMetaSchemaDescriptions, renderDefinitionMetaSchemaDescriptions, -} from '../docs/.vitepress/data/meta-schema-descriptions.ts'; +} from '../apps/docs/.vitepress/data/meta-schema-descriptions.ts'; import { generatedMetaSchemaDescriptionsPath, packageJsonPath, -} from '../docs/.vitepress/data/paths.ts'; -import { collectTypeDocModel } from '../docs/.vitepress/data/typedoc.ts'; +} from '../apps/docs/.vitepress/data/paths.ts'; +import { collectTypeDocModel } from '../apps/docs/.vitepress/data/typedoc.ts'; const publicApi = await collectPublicApiIndex(packageJsonPath); const typeDoc = await collectTypeDocModel(packageJsonPath, publicApi); diff --git a/scripts/check-version-sync.ts b/scripts/check-version-sync.ts index c6afe7d3..b1df72dc 100755 --- a/scripts/check-version-sync.ts +++ b/scripts/check-version-sync.ts @@ -13,23 +13,23 @@ interface VersionFile { function failToLoad(path: string, error: unknown): never { const details = error instanceof Error ? error.message : String(error); - console.error(`✗ failed to load ${path}: ${details}`); + console.error(`\u2717 failed to load ${path}: ${details}`); process.exit(1); } async function readPackageJson(): Promise { try { - return (await Bun.file('package.json').json()) as VersionFile; + return (await Bun.file('packages/dreamcli/package.json').json()) as VersionFile; } catch (error) { - return failToLoad('package.json', error); + return failToLoad('packages/dreamcli/package.json', error); } } async function readDenoJson(): Promise { try { - return (await Bun.file('deno.json').json()) as VersionFile; + return (await Bun.file('packages/dreamcli/deno.json').json()) as VersionFile; } catch (error) { - return failToLoad('deno.json', error); + return failToLoad('packages/dreamcli/deno.json', error); } } @@ -37,17 +37,19 @@ const pkg = await readPackageJson(); const deno = await readDenoJson(); if (!pkg.version) { - console.error('✗ package.json missing "version"'); + console.error('\u2717 package.json missing "version"'); process.exit(1); } if (!deno.version) { - console.error('✗ deno.json missing "version"'); + console.error('\u2717 deno.json missing "version"'); process.exit(1); } if (pkg.version !== deno.version) { - console.error(`✗ version mismatch — package.json: ${pkg.version}, deno.json: ${deno.version}`); + console.error( + `\u2717 version mismatch \u2014 package.json: ${pkg.version}, deno.json: ${deno.version}`, + ); process.exit(1); } -console.log(`✓ versions in sync: ${pkg.version}`); +console.log(`\u2713 versions in sync: ${pkg.version}`); diff --git a/scripts/deno-smoke-test.ts b/scripts/deno-smoke-test.ts index b7be34e1..88c5dd0e 100755 --- a/scripts/deno-smoke-test.ts +++ b/scripts/deno-smoke-test.ts @@ -13,11 +13,11 @@ * 1 — a check failed */ -import type { RuntimeAdapter } from '#dreamcli/runtime'; +import type { RuntimeAdapter } from '@kjanat/dreamcli/runtime'; // Import via deno.json import map — resolves to src/runtime.ts, // same source tree that `deno publish` ships to JSR. -const runtimeModule = await import('#dreamcli/runtime'); +const runtimeModule = await import('@kjanat/dreamcli/runtime'); function failBoundary(message: string): never { throw new Error(message); @@ -141,7 +141,7 @@ assert(typeof adapter.homedir === 'string', 'homedir is a string'); assert(typeof adapter.configDir === 'string', 'configDir is a string'); // readFile should return contents for existing file -const pkg = await adapter.readFile('./package.json'); +const pkg = await adapter.readFile('./packages/dreamcli/package.json'); assert(pkg !== null, 'readFile returns content for existing file'); assert( typeof pkg === 'string' && pkg.includes('@kjanat/dreamcli'), diff --git a/scripts/gh-project.ts b/scripts/gh-project.ts index 9249f051..c321bf10 100755 --- a/scripts/gh-project.ts +++ b/scripts/gh-project.ts @@ -6,7 +6,7 @@ * @module */ -import { ghProject } from './gh-project/main.ts'; +import { ghProject } from '@kjanat/gh-project'; if (import.meta.main) { void ghProject.run(); diff --git a/scripts/release-meta.sh b/scripts/release-meta.sh index da1f1930..ac4faf95 100755 --- a/scripts/release-meta.sh +++ b/scripts/release-meta.sh @@ -47,8 +47,8 @@ validate_release_tag() { case "${target}" in npm) - package="$(read_field package.json '.name // ""')" - version="$(read_field package.json '.version // ""')" + package="$(read_field packages/dreamcli/package.json '.name // ""')" + version="$(read_field packages/dreamcli/package.json '.version // ""')" if [[ -z "${package}" ]]; then echo 'package.json missing .name' @@ -68,10 +68,10 @@ npm) ;; jsr) - deno_package="$(read_field deno.json '.name // ""')" - package_name="$(read_field package.json '.name // ""')" - deno_version="$(read_field deno.json '.version // ""')" - package_version="$(read_field package.json '.version // ""')" + deno_package="$(read_field packages/dreamcli/deno.json '.name // ""')" + package_name="$(read_field packages/dreamcli/package.json '.name // ""')" + deno_version="$(read_field packages/dreamcli/deno.json '.version // ""')" + package_version="$(read_field packages/dreamcli/package.json '.version // ""')" if [[ -z "${deno_package}" ]]; then echo 'deno.json missing .name' diff --git a/tools/gh-project/package.json b/tools/gh-project/package.json new file mode 100644 index 00000000..c8d1f27c --- /dev/null +++ b/tools/gh-project/package.json @@ -0,0 +1,30 @@ +{ + "name": "@kjanat/gh-project", + "version": "0.0.0", + "private": true, + "type": "module", + "module": "./src/index.ts", + "types": "./src/index.ts", + "bin": { + "gh-project": "src/main.ts" + }, + "files": [ + "src" + ], + "imports": { + "#gh-project": "./src/index.ts", + "#lib/*": "./src/lib/*", + "#commands/*": "./src/commands/*" + }, + "scripts": { + "start": "bun src/main.ts", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@kjanat/dreamcli": "workspace:*" + }, + "devDependencies": { + "@types/bun": "catalog:", + "typescript": "catalog:" + } +} diff --git a/scripts/gh-project/commands/finish.ts b/tools/gh-project/src/commands/finish.ts similarity index 89% rename from scripts/gh-project/commands/finish.ts rename to tools/gh-project/src/commands/finish.ts index a9487a33..368f9405 100644 --- a/scripts/gh-project/commands/finish.ts +++ b/tools/gh-project/src/commands/finish.ts @@ -5,10 +5,10 @@ */ import { arg, command, flag } from '@kjanat/dreamcli'; -import { computeReadyTaskIds, markPrdTaskPassed, readPrdState } from '../lib/prd.ts'; -import { applyWorkflowUpdates, loadProjectContext } from '../lib/project.ts'; -import { ownerFlag, prdFlag, projectFlag } from '../lib/shared.ts'; -import type { WorkflowUpdate } from '../lib/types.ts'; +import { computeReadyTaskIds, markPrdTaskPassed, readPrdState } from '#lib/prd.ts'; +import { applyWorkflowUpdates, loadProjectContext } from '#lib/project.ts'; +import { ownerFlag, prdFlag, projectFlag } from '#lib/shared.ts'; +import type { WorkflowUpdate } from '#lib/types.ts'; const finish = command('finish') .description('Mark a task Done, optionally mark passes=true, and unblock ready tasks') diff --git a/scripts/gh-project/commands/list.ts b/tools/gh-project/src/commands/list.ts similarity index 86% rename from scripts/gh-project/commands/list.ts rename to tools/gh-project/src/commands/list.ts index f2dd5230..26be8bfd 100644 --- a/scripts/gh-project/commands/list.ts +++ b/tools/gh-project/src/commands/list.ts @@ -5,10 +5,10 @@ */ import { command, flag } from '@kjanat/dreamcli'; -import { readPrdState } from '../lib/prd.ts'; -import { loadProjectContext } from '../lib/project.ts'; -import { buildListRows, ownerFlag, parseWorkflow, prdFlag, projectFlag } from '../lib/shared.ts'; -import type { ListRow } from '../lib/types.ts'; +import { readPrdState } from '#lib/prd.ts'; +import { loadProjectContext } from '#lib/project.ts'; +import { buildListRows, ownerFlag, parseWorkflow, prdFlag, projectFlag } from '#lib/shared.ts'; +import type { ListRow } from '#lib/types.ts'; const list = command('list') .description('List PRD tasks alongside GitHub workflow state') diff --git a/scripts/gh-project/commands/set.ts b/tools/gh-project/src/commands/set.ts similarity index 88% rename from scripts/gh-project/commands/set.ts rename to tools/gh-project/src/commands/set.ts index d4ea158f..6c24aec0 100644 --- a/scripts/gh-project/commands/set.ts +++ b/tools/gh-project/src/commands/set.ts @@ -6,8 +6,8 @@ import { arg, command } from '@kjanat/dreamcli'; -import { applyWorkflowUpdates, loadProjectContext } from '../lib/project.ts'; -import { ownerFlag, parseWorkflow, projectFlag } from '../lib/shared.ts'; +import { applyWorkflowUpdates, loadProjectContext } from '#lib/project.ts'; +import { ownerFlag, parseWorkflow, projectFlag } from '#lib/shared.ts'; const setWorkflow = command('set') .description('Set a project task to any workflow value') diff --git a/scripts/gh-project/commands/start.ts b/tools/gh-project/src/commands/start.ts similarity index 86% rename from scripts/gh-project/commands/start.ts rename to tools/gh-project/src/commands/start.ts index 35342749..1fcd4489 100644 --- a/scripts/gh-project/commands/start.ts +++ b/tools/gh-project/src/commands/start.ts @@ -6,8 +6,8 @@ import { arg, command } from '@kjanat/dreamcli'; -import { applyWorkflowUpdates, loadProjectContext } from '../lib/project.ts'; -import { ownerFlag, projectFlag } from '../lib/shared.ts'; +import { applyWorkflowUpdates, loadProjectContext } from '#lib/project.ts'; +import { ownerFlag, projectFlag } from '#lib/shared.ts'; const start = command('start') .description('Mark a project task In Progress') diff --git a/scripts/gh-project/commands/sync.ts b/tools/gh-project/src/commands/sync.ts similarity index 91% rename from scripts/gh-project/commands/sync.ts rename to tools/gh-project/src/commands/sync.ts index c411a71b..f6f0f9ee 100644 --- a/scripts/gh-project/commands/sync.ts +++ b/tools/gh-project/src/commands/sync.ts @@ -5,10 +5,10 @@ */ import { command, flag } from '@kjanat/dreamcli'; -import { computeReadyTaskIds, readPrdState } from '../lib/prd.ts'; -import { applyWorkflowUpdates, createProjectItem, loadProjectContext } from '../lib/project.ts'; -import { ownerFlag, prdFlag, projectFlag } from '../lib/shared.ts'; -import type { WorkflowUpdate } from '../lib/types.ts'; +import { computeReadyTaskIds, readPrdState } from '#lib/prd.ts'; +import { applyWorkflowUpdates, createProjectItem, loadProjectContext } from '#lib/project.ts'; +import { ownerFlag, prdFlag, projectFlag } from '#lib/shared.ts'; +import type { WorkflowUpdate } from '#lib/types.ts'; const sync = command('sync') .description('Sync project workflows from prd.json') diff --git a/scripts/gh-project/main.ts b/tools/gh-project/src/index.ts similarity index 57% rename from scripts/gh-project/main.ts rename to tools/gh-project/src/index.ts index 78cf1f3d..e2f96881 100644 --- a/scripts/gh-project/main.ts +++ b/tools/gh-project/src/index.ts @@ -1,16 +1,16 @@ /** - * GitHub Project helper entrypoint for the DreamCLI re-foundation workflow. + * GitHub Project cli definition for the DreamCLI re-foundation workflow. * * @module */ import { cli } from '@kjanat/dreamcli'; -import { finish } from './commands/finish.ts'; -import { list } from './commands/list.ts'; -import { setWorkflow } from './commands/set.ts'; -import { start } from './commands/start.ts'; -import { sync } from './commands/sync.ts'; +import { finish } from '#commands/finish.ts'; +import { list } from '#commands/list.ts'; +import { setWorkflow } from '#commands/set.ts'; +import { start } from '#commands/start.ts'; +import { sync } from '#commands/sync.ts'; /** The `gh-project` CLI for managing the DreamCLI re-foundation GitHub project. * @@ -24,7 +24,3 @@ export const ghProject = cli('gh-project') .command(finish) .command(sync) .completions({ rootMode: 'surface' }); - -if (import.meta.main) { - ghProject.run(); -} diff --git a/scripts/gh-project/lib/prd.ts b/tools/gh-project/src/lib/prd.ts similarity index 100% rename from scripts/gh-project/lib/prd.ts rename to tools/gh-project/src/lib/prd.ts diff --git a/scripts/gh-project/lib/project.ts b/tools/gh-project/src/lib/project.ts similarity index 100% rename from scripts/gh-project/lib/project.ts rename to tools/gh-project/src/lib/project.ts diff --git a/scripts/gh-project/lib/shared.ts b/tools/gh-project/src/lib/shared.ts similarity index 100% rename from scripts/gh-project/lib/shared.ts rename to tools/gh-project/src/lib/shared.ts diff --git a/scripts/gh-project/lib/types.ts b/tools/gh-project/src/lib/types.ts similarity index 100% rename from scripts/gh-project/lib/types.ts rename to tools/gh-project/src/lib/types.ts diff --git a/tools/gh-project/src/main.ts b/tools/gh-project/src/main.ts new file mode 100755 index 00000000..edfc8152 --- /dev/null +++ b/tools/gh-project/src/main.ts @@ -0,0 +1,11 @@ +/** + * GitHub Project helper entrypoint for the DreamCLI re-foundation workflow. + * + * @module + */ + +import { ghProject } from '#gh-project'; + +if (import.meta.main) { + ghProject.run(); +} diff --git a/tools/gh-project/tsconfig.json b/tools/gh-project/tsconfig.json new file mode 100644 index 00000000..5e4ad45d --- /dev/null +++ b/tools/gh-project/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "types": ["bun"] + }, + "include": ["src"], + "exclude": ["**/node_modules"] +} diff --git a/tsconfig.json b/tsconfig.json index 684aa403..6293923e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,6 @@ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, - "types": ["bun", "node", "deno", "vite", "vitest"], "strict": true, "noUnusedLocals": true, @@ -24,11 +23,26 @@ "forceConsistentCasingInFileNames": true, "paths": { - "@kjanat/dreamcli": ["./src/index.ts"], - "@kjanat/dreamcli/runtime": ["./src/runtime.ts"], - "@kjanat/dreamcli/testkit": ["./src/testkit.ts"], - "@kjanat/dreamcli/schema": ["./dreamcli.schema.json"], - "@kjanat/dreamcli/package.json": ["./package.json"] + "@kjanat/dreamcli": [ + "./packages/dreamcli/src/index.ts", + "../../packages/dreamcli/src/index.ts" + ], + "@kjanat/dreamcli/runtime": [ + "./packages/dreamcli/src/runtime.ts", + "../../packages/dreamcli/src/runtime.ts" + ], + "@kjanat/dreamcli/testkit": [ + "./packages/dreamcli/src/testkit.ts", + "../../packages/dreamcli/src/testkit.ts" + ], + "@kjanat/dreamcli/schema": [ + "./packages/dreamcli/dreamcli.schema.json", + "../../packages/dreamcli/dreamcli.schema.json" + ], + "@kjanat/dreamcli/package.json": [ + "./packages/dreamcli/package.json", + "../../packages/dreamcli/package.json" + ] } }, "exclude": ["**/dist", "**/node_modules"] diff --git a/wrangler.jsonc b/wrangler.jsonc index 275e915d..ec1cafac 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -3,14 +3,14 @@ "name": "dreamcli", "compatibility_date": "2026-04-02", "build": { - "watch_dir": "./src", + "watch_dir": "./packages/dreamcli/src", "command": "bun docs:build", "cwd": "." }, "workers_dev": true, "preview_urls": true, "assets": { - "directory": "./docs/.vitepress/dist/", + "directory": "./apps/docs/.vitepress/dist/", "not_found_handling": "single-page-application", "html_handling": "drop-trailing-slash" }, From 0a655477cedf8c8968964cb305b664c761e653ef Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Tue, 7 Apr 2026 22:13:11 +0200 Subject: [PATCH 02/21] chore: add repository metadata to workspace packages Bun workspaces and npm both use this for provenance linking. Also reorder gh-project fields to match the other workspace manifests. --- apps/docs/package.json | 5 +++++ examples/standalone/package.json | 5 +++++ tools/gh-project/package.json | 15 ++++++++++----- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/apps/docs/package.json b/apps/docs/package.json index 5520829a..9cd9d5cf 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -2,6 +2,11 @@ "name": "@kjanat/dreamcli-docs", "version": "0.0.0", "private": true, + "repository": { + "type": "git", + "url": "git+https://github.com/kjanat/dreamcli.git", + "directory": "apps/docs" + }, "type": "module", "imports": { "#dreamcli/testkit": "@kjanat/dreamcli/testkit" diff --git a/examples/standalone/package.json b/examples/standalone/package.json index bb17781f..de42864a 100644 --- a/examples/standalone/package.json +++ b/examples/standalone/package.json @@ -2,6 +2,11 @@ "name": "@kjanat/dreamcli-examples", "version": "0.0.0", "private": true, + "repository": { + "type": "git", + "url": "git+https://github.com/kjanat/dreamcli.git", + "directory": "examples/standalone" + }, "type": "module", "dependencies": { "@kjanat/dreamcli": "workspace:*" diff --git a/tools/gh-project/package.json b/tools/gh-project/package.json index c8d1f27c..ace79021 100644 --- a/tools/gh-project/package.json +++ b/tools/gh-project/package.json @@ -2,7 +2,17 @@ "name": "@kjanat/gh-project", "version": "0.0.0", "private": true, + "repository": { + "type": "git", + "url": "git+https://github.com/kjanat/dreamcli.git", + "directory": "tools/gh-project" + }, "type": "module", + "imports": { + "#gh-project": "./src/index.ts", + "#lib/*": "./src/lib/*", + "#commands/*": "./src/commands/*" + }, "module": "./src/index.ts", "types": "./src/index.ts", "bin": { @@ -11,11 +21,6 @@ "files": [ "src" ], - "imports": { - "#gh-project": "./src/index.ts", - "#lib/*": "./src/lib/*", - "#commands/*": "./src/commands/*" - }, "scripts": { "start": "bun src/main.ts", "typecheck": "tsc --noEmit" From 0702e1514dee8b79c465d325dde8e7ed11ea8373 Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Tue, 7 Apr 2026 22:20:40 +0200 Subject: [PATCH 03/21] chore: refresh agents + fix review findings Update AGENTS.md files for monorepo layout, add gh-project knowledge base. Use literal glyphs in check-version-sync, add void to floating promise. --- AGENTS.md | 129 ++++++++++-------- apps/docs/.vitepress/AGENTS.md | 16 +-- apps/docs/AGENTS.md | 2 +- examples/AGENTS.md | 17 ++- .../dreamcli/src/core/json-schema/AGENTS.md | 12 +- scripts/check-version-sync.ts | 12 +- tools/gh-project/AGENTS.md | 38 ++++++ tools/gh-project/src/main.ts | 2 +- 8 files changed, 139 insertions(+), 89 deletions(-) create mode 100644 tools/gh-project/AGENTS.md diff --git a/AGENTS.md b/AGENTS.md index 2c8ab900..36dd75be 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,66 +1,78 @@ # PROJECT KNOWLEDGE BASE -**Generated:** 2026-04-07 **Commit:** 1479d26 **Branch:** master +**Generated:** 2026-04-07 **Commit:** 0a65547 **Branch:** workspace ## OVERVIEW -Schema-first, fully typed TypeScript CLI framework. Zero runtime deps. In-repo exports point at -`src/*.ts`; published Node defaults point at `dist/*.mjs`, while Bun and Deno keep source exports. +Schema-first, fully typed TypeScript CLI framework. Zero runtime deps. Bun workspaces monorepo with +the core library, docs site, project tooling, and runnable examples as separate packages. Read `@DISCOVERIES.md` before planning, editing, or running task workflows. ## STRUCTURE ```text -src/ -├── index.ts # public package surface -├── runtime.ts # `./runtime` subpath barrel -├── testkit.ts # `./testkit` subpath barrel -├── core/ -│ ├── cli/ # top-level CLI orchestration, plugins, root surface -│ ├── schema/ # builder DSL, type inference, middleware surface -│ ├── resolve/ # argv/env/config/prompt/default precedence -│ ├── output/ # stdout/stderr/json/table/activity dispatch -│ ├── completion/ # shell completion generators -│ ├── json-schema/ # definition schema + input schema generation -│ ├── parse/ # tokenizer + schema-aware raw parse -│ ├── prompt/ # terminal/test prompt engines -│ ├── config/ # config discovery + package.json walk-up -│ ├── help/ # schema-driven help formatter -│ └── testkit/ # in-process test harness -└── runtime/ # Node/Bun/Deno adapters + detection - -docs/ -├── .vitepress/ # config, data loaders, theme, custom Vite plugins -├── concepts/ # hand-written docs -├── guide/ # hand-written docs -├── examples/ # generated routes backed by `../examples/*.ts` -└── reference/ # overview pages + dynamic symbol routes - -scripts/ # build, release, and project automation -examples/ # runnable examples + `examples/gh` workspace canary -specs/ # planning/design docs +dreamcli-monorepo/ +├── packages/dreamcli/ # core library (@kjanat/dreamcli) +│ └── src/ +│ ├── index.ts # public package surface +│ ├── runtime.ts # `./runtime` subpath barrel +│ ├── testkit.ts # `./testkit` subpath barrel +│ ├── core/ +│ │ ├── cli/ # CLIBuilder, dispatch, plugins, root surface +│ │ ├── schema/ # builder DSL, type inference, middleware surface +│ │ ├── resolve/ # argv/env/config/prompt/default precedence +│ │ ├── output/ # stdout/stderr/json/table/activity dispatch +│ │ ├── completion/ # shell completion generators +│ │ ├── json-schema/ # definition schema + input schema generation +│ │ ├── parse/ # tokenizer + schema-aware raw parse +│ │ ├── prompt/ # terminal/test prompt engines +│ │ ├── config/ # config discovery + package.json walk-up +│ │ ├── help/ # schema-driven help formatter +│ │ ├── schema-dsl/ # string-literal schema definitions +│ │ ├── errors/ # CLIError, ParseError, ValidationError +│ │ ├── execution/ # @internal shared CLI/testkit pipeline +│ │ └── testkit/ # in-process test harness +│ └── runtime/ # Node/Bun/Deno adapters + detection +│ +├── apps/docs/ # VitePress docs site (@kjanat/dreamcli-docs) +│ ├── .vitepress/ # config, data loaders, theme, Vite plugins +│ ├── concepts/ # hand-written fundamentals +│ ├── guide/ # hand-written guides +│ ├── examples/ # route loaders backed by `../examples/standalone/` +│ └── reference/ # overview pages + dynamic symbol routes +│ +├── tools/gh-project/ # GitHub Project helper (@kjanat/gh-project) +│ +├── examples/ +│ ├── standalone/ # single-file teaching examples (docs source) +│ └── gh/ # workspace canary: miniature GitHub CLI clone +│ +├── scripts/ # build, release, project automation +└── specs/ # planning/design docs ``` ## WHERE TO LOOK -| Task | Location | Notes | -| --------------------------------------------- | ------------------------------- | ------------------------------------------ | -| Add command, flag, arg, or middleware API | `src/core/schema/` | most public API work starts here | -| Fix argv parsing | `src/core/parse/` | tokenizer + parser live in one file | -| Fix resolution precedence | `src/core/resolve/` | argv -> env -> config -> prompt -> default | -| Change help text formatting | `src/core/help/` | width-aware text formatter | -| Change config discovery or `packageJson()` | `src/core/config/` | config loaders + package metadata walk-up | -| Change prompt UX or test prompts | `src/core/prompt/` | prompt engines and sentinels | -| Change JSON Schema output | `src/core/json-schema/` | definition schema + input schema | -| Change output, spinner, or progress | `src/core/output/` | stdout/stderr and activity handles | -| Change shell completions | `src/core/completion/` | per-shell generators | -| Change CLI dispatch or plugins | `src/core/cli/` | root help, dispatch, runtime preflight | -| Change runtime adapters | `src/runtime/` | Node, Bun, Deno, detect, support | -| Change docs data, routes, or site build | `docs/.vitepress/` | docs app internals | -| Edit guide/concept prose | `docs/guide/`, `docs/concepts/` | hand-authored Markdown | -| Change build, release, or project automation | `scripts/` | operational scripts | -| Change example-backed docs or consumer canary | `examples/` | docs source + `examples/gh` workspace | +| Task | Location | Notes | +| --------------------------------------------- | ----------------------------------------- | ------------------------------------------ | +| Add command, flag, arg, or middleware API | `packages/dreamcli/src/core/schema/` | most public API work starts here | +| Fix argv parsing | `packages/dreamcli/src/core/parse/` | tokenizer + parser in one file | +| Fix resolution precedence | `packages/dreamcli/src/core/resolve/` | argv -> env -> config -> prompt -> default | +| Change help text formatting | `packages/dreamcli/src/core/help/` | width-aware text formatter | +| Change config discovery or `packageJson()` | `packages/dreamcli/src/core/config/` | config loaders + package metadata walk-up | +| Change prompt UX or test prompts | `packages/dreamcli/src/core/prompt/` | prompt engines and sentinels | +| Change JSON Schema output | `packages/dreamcli/src/core/json-schema/` | definition schema + input schema | +| Change output, spinner, or progress | `packages/dreamcli/src/core/output/` | stdout/stderr and activity handles | +| Change shell completions | `packages/dreamcli/src/core/completion/` | per-shell generators | +| Change CLI dispatch or plugins | `packages/dreamcli/src/core/cli/` | root help, dispatch, runtime preflight | +| Change runtime adapters | `packages/dreamcli/src/runtime/` | Node, Bun, Deno, detect, support | +| Change string-literal schema DSL | `packages/dreamcli/src/core/schema-dsl/` | compile-time + runtime string parser | +| Change docs data, routes, or site build | `apps/docs/.vitepress/` | docs app internals | +| Edit guide/concept prose | `apps/docs/guide/`, `apps/docs/concepts/` | hand-authored Markdown | +| Change build, release, or project automation | `scripts/` | operational scripts | +| Change example-backed docs or consumer canary | `examples/` | docs source + `examples/gh` workspace | +| Change project workflow tooling | `tools/gh-project/` | DreamCLI-powered GitHub Project helper | ## CONVENTIONS @@ -79,24 +91,24 @@ specs/ # planning/design docs ## ANTI-PATTERNS (THIS PROJECT) -- Do not add runtime deps -- Do not use `process.*` or runtime-specific APIs in `src/core/` +- Do not add runtime deps to `packages/dreamcli` +- Do not use `process.*` or runtime-specific APIs in `packages/dreamcli/src/core/` - Do not import through barrels when it would create cycles; direct-file imports are intentional in `cli/`, `completion/`, `output/`, `prompt/`, `resolve/`, and `runtime/` - Do not hand-edit `dreamcli.schema.json` or `src/core/json-schema/meta-descriptions.generated.ts` -- Do not edit `docs/.vitepress/dist/` or `docs/.vitepress/cache/` -- Do not treat `docs/.vitepress/data/` as docs-only; scripts import it for generated source and docs - artifacts +- Do not edit `apps/docs/.vitepress/dist/` or `apps/docs/.vitepress/cache/` +- Do not treat `apps/docs/.vitepress/data/` as docs-only; scripts import it for generated source and + docs artifacts - Do not replace `bun run gh-project:*` with ad hoc GitHub project mutations ## COMMANDS ```bash -bun run typecheck # tsgo --noEmit +bun run typecheck # tsgo --noEmit (dreamcli + examples/gh) bun run typecheck:tsc # tsc fallback bun run lint # biome lint bun run format:check # dprint check -bun run test # vitest run +bun run test # vitest run (all workspaces) bun run meta-descriptions # regenerate JSON Schema meta descriptions bun run meta-descriptions:check bun run docs:build # VitePress build @@ -107,12 +119,15 @@ bun run gh-project:list # workflow/project helper ## NOTES +- **Monorepo**: Bun workspaces (`packages/*`, `apps/*`, `tools/*`, `examples/*`). Root `package.json` + is `dreamcli-monorepo` (private). Scripts proxy to workspace packages via `--filter`. - Public subpath exports: `"."`, `"./runtime"`, `"./testkit"`, `"./schema"` - Node inside this repo resolves bare package imports to `dist`; Bun and Deno resolve to `src` - `tsdown.config.ts` emits `dreamcli.schema.json` before build and formats `package.json` on success - Docs build copies root artifacts into site output via - `docs/.vitepress/vite-plugins/source-artifacts.ts` + `apps/docs/.vitepress/vite-plugins/source-artifacts.ts` - `examples/gh` is a real workspace package, typechecked and tested separately in CI - CI base branch is `master`, not `main` - Docs deploy: Cloudflare Workers (static assets via wrangler) + GitHub Pages fallback -- Cloudflare build env has tight memory limits; VitePress+twoslash OOMs are flaky — retry before investigating +- Cloudflare build env has tight memory limits; VitePress+twoslash OOMs are flaky — retry before + investigating diff --git a/apps/docs/.vitepress/AGENTS.md b/apps/docs/.vitepress/AGENTS.md index b5eb4b4f..c497d7dd 100644 --- a/apps/docs/.vitepress/AGENTS.md +++ b/apps/docs/.vitepress/AGENTS.md @@ -19,14 +19,14 @@ cache/ # generated cache ## WHERE TO LOOK -| Task | Location | Notes | -| ---------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------------------- | -| Sidebar, nav, examples sidebar | `config.ts`, `data/examples.ts` | `config.ts` calls `collectExampleMeta()` | -| API/reference pages | `data/api-index.ts`, `typedoc.ts`, `symbol-pages.ts` | package exports -> TypeDoc -> symbol routes | -| Shared repo paths and source links | `data/paths.ts` | `DOCS_GIT_REF` override, else `git rev-parse HEAD` | -| Schema/meta description pipeline | `data/meta-schema-descriptions.ts`, `../../scripts/build-meta-descriptions.ts` | docs data feeds source generation | -| Artifact copying | `vite-plugins/source-artifacts.ts` | moves root schema into docs dist | -| Theme interactivity | `theme/` | client-only toggles, mobile twoslash UX, Mermaid | +| Task | Location | Notes | +| ---------------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------- | +| Sidebar, nav, examples sidebar | `config.ts`, `data/examples.ts` | `config.ts` calls `collectExampleMeta()` | +| API/reference pages | `data/api-index.ts`, `typedoc.ts`, `symbol-pages.ts` | package exports -> TypeDoc -> symbol routes | +| Shared repo paths and source links | `data/paths.ts` | `DOCS_GIT_REF` override, else `git rev-parse HEAD` | +| Schema/meta description pipeline | `data/meta-schema-descriptions.ts`, `../../../scripts/build-meta-descriptions.ts` | docs data feeds source generation | +| Artifact copying | `vite-plugins/source-artifacts.ts` | moves root schema into docs dist | +| Theme interactivity | `theme/` | client-only toggles, mobile twoslash UX, Mermaid | ## CONVENTIONS diff --git a/apps/docs/AGENTS.md b/apps/docs/AGENTS.md index c516e28f..71db8456 100644 --- a/apps/docs/AGENTS.md +++ b/apps/docs/AGENTS.md @@ -47,4 +47,4 @@ public/ # static assets ## NOTES - Root `dreamcli.schema.json` is required for docs and gets copied into site output during build -- See `docs/.vitepress/AGENTS.md` for plugin, theme, and data-pipeline gotchas +- See `.vitepress/AGENTS.md` for plugin, theme, and data-pipeline gotchas diff --git a/examples/AGENTS.md b/examples/AGENTS.md index 58804faa..fca0d125 100644 --- a/examples/AGENTS.md +++ b/examples/AGENTS.md @@ -8,19 +8,18 @@ workspace package used as a walkthrough and CI canary. ## STRUCTURE ```text -*.ts # single-file teaching examples parsed by docs -gh/ # workspace package: miniature GitHub CLI clone -.cache/ # generated build cache +standalone/ # single-file teaching examples parsed by docs +gh/ # workspace package: miniature GitHub CLI clone ``` ## WHERE TO LOOK -| Task | Location | Notes | -| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| Edit a single-feature example | `basic.ts`, `interactive.ts`, `json-mode.ts`, `middleware.ts`, `multi-command.ts`, `spinner-progress.ts`, `testing.ts` | keep focused, runnable, public-API only | -| Edit docs example metadata | `../docs/.vitepress/data/examples.ts` | parses example docblocks and related symbols | -| Edit the walkthrough package | `gh/` | real package with commands, tests, and build | -| Trace example-backed docs pages | `../docs/examples/`, `../docs/reference/` | generated from example source | +| Task | Location | Notes | +| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| Edit a single-feature example | `standalone/basic.ts`, `standalone/interactive.ts`, `standalone/json-mode.ts`, `standalone/middleware.ts`, `standalone/multi-command.ts`, `standalone/spinner-progress.ts`, `standalone/testing.ts` | keep focused, runnable, public-API only | +| Edit docs example metadata | `../apps/docs/.vitepress/data/examples.ts` | parses example docblocks and related symbols | +| Edit the walkthrough package | `gh/` | real package with commands, tests, and build | +| Trace example-backed docs pages | `../apps/docs/examples/`, `../apps/docs/reference/` | generated from example source | ## CONVENTIONS diff --git a/packages/dreamcli/src/core/json-schema/AGENTS.md b/packages/dreamcli/src/core/json-schema/AGENTS.md index 1dc9e016..7c543d30 100644 --- a/packages/dreamcli/src/core/json-schema/AGENTS.md +++ b/packages/dreamcli/src/core/json-schema/AGENTS.md @@ -16,12 +16,12 @@ output. ## WHERE TO LOOK -| Task | Location | Notes | -| -------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------ | -| Change definition schema shape | `generateSchema()` | CLI tree, flags, args, examples, hidden and prompt filtering | -| Change input validation schema | `generateInputSchema()` | JSON Schema 2020-12 for config/editor use cases | -| Change DSL -> JSON Schema bridge | `parseSchema()`, `nodeToJsonSchema()` in `index.ts` | feeds custom and DSL flag shapes | -| Regenerate descriptions | `meta-descriptions.generated.ts`, `../../../scripts/build-meta-descriptions.ts` | script is source of truth | +| Task | Location | Notes | +| -------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------ | +| Change definition schema shape | `generateSchema()` | CLI tree, flags, args, examples, hidden and prompt filtering | +| Change input validation schema | `generateInputSchema()` | JSON Schema 2020-12 for config/editor use cases | +| Change DSL -> JSON Schema bridge | `parseSchema()`, `nodeToJsonSchema()` in `index.ts` | feeds custom and DSL flag shapes | +| Regenerate descriptions | `meta-descriptions.generated.ts`, `../../../../../scripts/build-meta-descriptions.ts` | script is source of truth | ## CONVENTIONS diff --git a/scripts/check-version-sync.ts b/scripts/check-version-sync.ts index b1df72dc..e200c683 100755 --- a/scripts/check-version-sync.ts +++ b/scripts/check-version-sync.ts @@ -13,7 +13,7 @@ interface VersionFile { function failToLoad(path: string, error: unknown): never { const details = error instanceof Error ? error.message : String(error); - console.error(`\u2717 failed to load ${path}: ${details}`); + console.error(`✗ failed to load ${path}: ${details}`); process.exit(1); } @@ -37,19 +37,17 @@ const pkg = await readPackageJson(); const deno = await readDenoJson(); if (!pkg.version) { - console.error('\u2717 package.json missing "version"'); + console.error('✗ package.json missing "version"'); process.exit(1); } if (!deno.version) { - console.error('\u2717 deno.json missing "version"'); + console.error('✗ deno.json missing "version"'); process.exit(1); } if (pkg.version !== deno.version) { - console.error( - `\u2717 version mismatch \u2014 package.json: ${pkg.version}, deno.json: ${deno.version}`, - ); + console.error(`✗ version mismatch — package.json: ${pkg.version}, deno.json: ${deno.version}`); process.exit(1); } -console.log(`\u2713 versions in sync: ${pkg.version}`); +console.log(`✓ versions in sync: ${pkg.version}`); diff --git a/tools/gh-project/AGENTS.md b/tools/gh-project/AGENTS.md new file mode 100644 index 00000000..e946b481 --- /dev/null +++ b/tools/gh-project/AGENTS.md @@ -0,0 +1,38 @@ +# gh-project — GitHub Project workflow helper + +DreamCLI-powered CLI for managing the re-foundation GitHub project. Bun-native workspace package. + +## FILES + +| File | Purpose | +| ------------------------ | ----------------------------------------------------- | +| `src/main.ts` | Entrypoint — `ghProject.run()` | +| `src/index.ts` | CLI definition — `cli('gh-project')` + 5 commands | +| `src/commands/list.ts` | List project tasks with status/workflow | +| `src/commands/start.ts` | Mark task `In Progress` in project + PRD | +| `src/commands/finish.ts` | Mark task `Done`, write `passes: true` to PRD | +| `src/commands/set.ts` | Set workflow field on a project item | +| `src/commands/sync.ts` | Batch-sync PRD state -> GitHub Project state | +| `src/lib/project.ts` | GitHub GraphQL queries + project mutations | +| `src/lib/prd.ts` | `.opencode/state/dreamcli-re-foundation/prd.json` I/O | +| `src/lib/shared.ts` | Shared constants (project number, field names) | +| `src/lib/types.ts` | Shared types | + +## CONVENTIONS + +- Extends DreamCLI via workspace dep; commands use `command()` + `flag.*()` builder API +- Uses `#commands/*` and `#lib/*` subpath imports (package.json `imports` field) +- All GitHub API calls go through `src/lib/project.ts`; no raw `gh project` in commands +- PRD state file is the local source of truth; GitHub Project is the remote mirror + +## ANTI-PATTERNS + +- Do not call `gh project` directly — use this CLI surface +- Do not edit PRD state outside `src/lib/prd.ts` +- Do not forget to update both `Status` (board-visible) and `Workflow` (detail) fields + +## NOTES + +- `finish` writes `passes: true` to PRD by default; use `--skip-pass` to suppress +- `sync` is idempotent; safe to re-run after manual project edits +- GitHub Project number is `4`, hardcoded in `src/lib/shared.ts` diff --git a/tools/gh-project/src/main.ts b/tools/gh-project/src/main.ts index edfc8152..3fcfb20d 100755 --- a/tools/gh-project/src/main.ts +++ b/tools/gh-project/src/main.ts @@ -7,5 +7,5 @@ import { ghProject } from '#gh-project'; if (import.meta.main) { - ghProject.run(); + void ghProject.run(); } From 942b132e9e5bdfc4f239df25df41e737a81386af Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Tue, 7 Apr 2026 22:24:59 +0200 Subject: [PATCH 04/21] chore(deps): bump wrangler, pin biome, add vitepress override MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wrangler 4.80→4.81 (workerd 20260401→20260405), pin biome exact, override vitepress to next channel, volta node 25.8.2→25.9.0, disable exact installs for devtools. --- bun.lock | 19 +++++++++++-------- bunfig.toml | 3 ++- package.json | 9 ++++++--- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/bun.lock b/bun.lock index 273d7cd4..4e8765cc 100644 --- a/bun.lock +++ b/bun.lock @@ -95,6 +95,9 @@ }, }, }, + "overrides": { + "vitepress": "next", + }, "catalog": { "@types/bun": "^1.3.0", "@types/node": ">=22.0.0, <23.0.0", @@ -156,15 +159,15 @@ "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "1.20260301.1 || ~1.20260302.1 || ~1.20260303.1 || ~1.20260304.1 || >1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-8ovsRpwzPoEqPUzoErAYVv8l3FMZNeBVQfJTvtzP4AgLSRGZISRfuChFxHWUQd3n6cnrwkuTGxT+2cGo8EsyYg=="], - "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260401.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZSmceM70jH6k+/62VkEcmMNzrpr4kSctkX5Lsgqv38KktfhPY/hsh75y1lRoPWS3H3kgMa4p2pUSlidZR1u2hw=="], + "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260405.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-EbmdBcmeIGogKG4V1odSWQe7z4rHssUD4iaXv0cXA22/MFrzH3iQT0R+FJFyhucGtih/9B9E+6j0QbSQD8xT3w=="], - "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260401.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-7UKWF+IUZ3NXMVPsDg8Cjg0r58b+uYlfvs5Yt8bvtU+geCtW4P2MxRHmRSEo8SryckXOJjb/b8tcncgCykFu8g=="], + "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260405.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-r44r418bOQtoP+Odu+L/BQM9q5cRSXRd1N167PgZQIo4MlqzTwHO4L0wwXhxbcV/PF46rrQre/uTFS8R0R+xSQ=="], - "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260401.1", "", { "os": "linux", "cpu": "x64" }, "sha512-MDWUH/0bvL/l9aauN8zEddyYOXId1OueqrUCXXENNJ95R/lSmF6OgGVuXaYhoIhxQkNiEJ/0NOlnVYj9mJq4dw=="], + "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260405.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Aaq3RWnaTCzMBo77wC8fjOx+SFdO/rlcXa6HAf+PJs51LyMISFOBCJKqSlS6Irphen0WHHxFKPHUO9bjfj8g2g=="], - "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260401.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-UgkzpMzVWM/bwbo3vjCTg2aoKfGcUhiEoQoDdo6RGWvbHRJyLVZ4VQCG9ZcISiztkiS2ICCoYOtPy6M/lV6Gcw=="], + "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260405.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-Lbp9Z2wiMzy3Sji3YwMHK5WDlejsH3jF4swAFEv7+jIf3NowZHga3GzwTypNRmcwnfz/XrqQ7Hc0Ul9OoU/lCw=="], - "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260401.1", "", { "os": "win32", "cpu": "x64" }, "sha512-HBLzcQF5iF4Qv20tQ++pG7xs3OsCnaIbc+GAi6fmhUKZhvmzvml/jwrQzLJ+MPm0cQo41K5OO/U3T4S8tvJetQ=="], + "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260405.1", "", { "os": "win32", "cpu": "x64" }, "sha512-FhE0kt93kj5JnSPVqi4BAXpQQENyKnuSOoJLd35mkMMGhtPrwv5EsReJdck0S8hUocCBlb+U0RmP8ta6k41HjQ=="], "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], @@ -1096,7 +1099,7 @@ "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], - "miniflare": ["miniflare@4.20260401.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.4", "workerd": "1.20260401.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-lngHPzZFN9sxYG/mhzvnWiBMNVAN5MsO/7g32ttJ07rymtiK/ZBalODTKb8Od+BQdlU5DOR4CjVt9NydjnUyYg=="], + "miniflare": ["miniflare@4.20260405.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.4", "workerd": "1.20260405.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-tpr4XdWMq7zFdsHH+CS0XS47nQzlRZH0rMJ1vobOZbkrs3cIj7qbD40ON616hDnzHxwqwB2qKHzmmuj6oRisSQ=="], "minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], @@ -1306,9 +1309,9 @@ "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], - "workerd": ["workerd@1.20260401.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260401.1", "@cloudflare/workerd-darwin-arm64": "1.20260401.1", "@cloudflare/workerd-linux-64": "1.20260401.1", "@cloudflare/workerd-linux-arm64": "1.20260401.1", "@cloudflare/workerd-windows-64": "1.20260401.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-mUYCd+ohaWJWF5nhDzxugWaAD/DM8Dw0ze3B7bu8JaA7S70+XQJXcvcvwE8C4qGcxSdCyqjsrFzqxKubECDwzg=="], + "workerd": ["workerd@1.20260405.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260405.1", "@cloudflare/workerd-darwin-arm64": "1.20260405.1", "@cloudflare/workerd-linux-64": "1.20260405.1", "@cloudflare/workerd-linux-arm64": "1.20260405.1", "@cloudflare/workerd-windows-64": "1.20260405.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-bSaRWCv9iO8/FWpgZRjHLGZLolX5s1AErRSYaTECMMHOZKuCbl2+ehnSyc+ZZ/70y+9owADmN6HoYEWvBlJdYw=="], - "wrangler": ["wrangler@4.80.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.16.0", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260401.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260401.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260401.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-2ZKF7uPeOZy65BGk3YfvqBCPo/xH1MrAlMmH9mVP+tCNBrTUMnwOHSj1HrZHgR8LttkAqhko0fGz+I4ax1rzyQ=="], + "wrangler": ["wrangler@4.81.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.16.0", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260405.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260405.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260405.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-9fLPDuDcb8Nu6iXrl5E3HGYt3TVhQr/UvqtTvWr9Nl1X7PlQrmWMwQCfSioqN8VHYyQCyESV5jQsoKg8Sx+sEA=="], "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], diff --git a/bunfig.toml b/bunfig.toml index a60b2243..d4b94701 100644 --- a/bunfig.toml +++ b/bunfig.toml @@ -5,7 +5,8 @@ smol = false [install] auto = "auto" -exact = true +# We don't have ANY dependencies, so this doesn't matter. I want up-to-date devtools. +exact = false lockfile.save = true [run] diff --git a/package.json b/package.json index f75aca6b..b02ed968 100644 --- a/package.json +++ b/package.json @@ -38,14 +38,17 @@ "typecheck:tsc": "bun run --filter @kjanat/dreamcli typecheck:tsc", "upgrade": "bun update --latest && bun add -D vitepress@next" }, + "overrides": { + "vitepress": "next" + }, "devDependencies": { - "@biomejs/biome": "^2.4.10", + "@biomejs/biome": "2.4.10", "@kjanat/dreamcli": "workspace:*", "@kjanat/dreamcli-docs": "workspace:*", "@kjanat/gh-project": "workspace:*", "dprint": "^0.53.2", "knip": "^6.3.0", - "wrangler": "^4.80.0" + "wrangler": "^4.81.0" }, "packageManager": "bun@1.3.11", "devEngines": { @@ -59,7 +62,7 @@ } }, "volta": { - "node": "25.8.2", + "node": "25.9.0", "npm": "11.12.1" }, "catalog": { From 28ee8176b3304e22306598096fb9d7a070b18ce7 Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Tue, 7 Apr 2026 22:29:32 +0200 Subject: [PATCH 05/21] chore(deps): centralize all workspace dep versions in catalog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Single source of truth for every shared version — no more per-package pinning. Root devDeps (biome, dprint, knip, wrangler) also moved to catalog. --- apps/docs/package.json | 14 ++++---- bun.lock | 59 ++++++++++++++++++++++------------ package.json | 29 ++++++++++++++--- packages/dreamcli/deno.json | 10 +++++- packages/dreamcli/package.json | 18 +++++------ 5 files changed, 88 insertions(+), 42 deletions(-) diff --git a/apps/docs/package.json b/apps/docs/package.json index 9cd9d5cf..6b4ab31a 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -21,15 +21,15 @@ "@kjanat/dreamcli": "workspace:*" }, "devDependencies": { - "@shikijs/transformers": "^4.0.2", - "@shikijs/vitepress-twoslash": "^4.0.2", + "@shikijs/transformers": "catalog:", + "@shikijs/vitepress-twoslash": "catalog:", "@types/bun": "catalog:", - "floating-vue": "^5.2.2", - "mermaid": "^11.14.0", - "typedoc": "^0.28.18", + "floating-vue": "catalog:", + "mermaid": "catalog:", + "typedoc": "catalog:", "typescript": "catalog:", - "vite": "^8.0.7", - "vitepress": "^2.0.0-alpha.17", + "vite": "catalog:", + "vitepress": "catalog:", "vitest": "catalog:" } } diff --git a/bun.lock b/bun.lock index 4e8765cc..a3c4f05c 100644 --- a/bun.lock +++ b/bun.lock @@ -5,13 +5,13 @@ "": { "name": "@kjanat/dreamcli", "devDependencies": { - "@biomejs/biome": "^2.4.10", + "@biomejs/biome": "catalog:", "@kjanat/dreamcli": "workspace:*", "@kjanat/dreamcli-docs": "workspace:*", "@kjanat/gh-project": "workspace:*", - "dprint": "^0.53.2", - "knip": "^6.3.0", - "wrangler": "^4.80.0", + "dprint": "catalog:", + "knip": "catalog:", + "wrangler": "catalog:", }, }, "apps/docs": { @@ -21,15 +21,15 @@ "@kjanat/dreamcli": "workspace:*", }, "devDependencies": { - "@shikijs/transformers": "^4.0.2", - "@shikijs/vitepress-twoslash": "^4.0.2", + "@shikijs/transformers": "catalog:", + "@shikijs/vitepress-twoslash": "catalog:", "@types/bun": "catalog:", - "floating-vue": "^5.2.2", - "mermaid": "^11.14.0", - "typedoc": "^0.28.18", + "floating-vue": "catalog:", + "mermaid": "catalog:", + "typedoc": "catalog:", "typescript": "catalog:", - "vite": "^8.0.7", - "vitepress": "^2.0.0-alpha.17", + "vite": "catalog:", + "vitepress": "catalog:", "vitest": "catalog:", }, }, @@ -63,21 +63,21 @@ "name": "@kjanat/dreamcli", "version": "2.0.1", "devDependencies": { - "@arethetypeswrong/core": "^0.18.2", - "@iarna/toml": "^2.2.5", + "@arethetypeswrong/core": "catalog:", + "@iarna/toml": "catalog:", "@types/bun": "catalog:", - "@types/deno": "^2.5.0", + "@types/deno": "catalog:", "@types/node": "catalog:", - "@typescript/native-preview": "^7.0.0-dev.20260406.1", - "@vitest/coverage-v8": "^4.1.2", - "publint": "^0.3.18", - "tsdown": "^0.21.7", + "@typescript/native-preview": "catalog:", + "@vitest/coverage-v8": "catalog:", + "publint": "catalog:", + "tsdown": "catalog:", "typescript": "catalog:", "vitest": "catalog:", - "yaml": "^2.8.3", + "yaml": "catalog:", }, "optionalDependencies": { - "vite": "^8", + "vite": "catalog:", }, }, "tools/gh-project": { @@ -99,10 +99,29 @@ "vitepress": "next", }, "catalog": { + "@arethetypeswrong/core": "^0.18.2", + "@biomejs/biome": "2.4.10", + "@iarna/toml": "^2.2.5", + "@shikijs/transformers": "^4.0.2", + "@shikijs/vitepress-twoslash": "^4.0.2", "@types/bun": "^1.3.0", + "@types/deno": "^2.5.0", "@types/node": ">=22.0.0, <23.0.0", + "@typescript/native-preview": "^7.0.0-dev.20260406.1", + "@vitest/coverage-v8": "^4.1.2", + "dprint": "^0.53.2", + "floating-vue": "^5.2.2", + "knip": "^6.3.0", + "mermaid": "^11.14.0", + "publint": "^0.3.18", + "tsdown": "^0.21.7", + "typedoc": "^0.28.18", "typescript": "^6.0.2", + "vite": "^8.0.7", + "vitepress": "^2.0.0-alpha.17", "vitest": "^4.1.2", + "wrangler": "^4.81.0", + "yaml": "^2.8.3", }, "packages": { "@andrewbranch/untar.js": ["@andrewbranch/untar.js@1.0.3", "", {}, "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw=="], diff --git a/package.json b/package.json index b02ed968..07454d1f 100644 --- a/package.json +++ b/package.json @@ -42,13 +42,13 @@ "vitepress": "next" }, "devDependencies": { - "@biomejs/biome": "2.4.10", + "@biomejs/biome": "catalog:", "@kjanat/dreamcli": "workspace:*", "@kjanat/dreamcli-docs": "workspace:*", "@kjanat/gh-project": "workspace:*", - "dprint": "^0.53.2", - "knip": "^6.3.0", - "wrangler": "^4.81.0" + "dprint": "catalog:", + "knip": "catalog:", + "wrangler": "catalog:" }, "packageManager": "bun@1.3.11", "devEngines": { @@ -66,9 +66,28 @@ "npm": "11.12.1" }, "catalog": { + "@biomejs/biome": "2.4.10", + "@arethetypeswrong/core": "^0.18.2", + "@iarna/toml": "^2.2.5", + "@shikijs/transformers": "^4.0.2", + "@shikijs/vitepress-twoslash": "^4.0.2", "@types/bun": "^1.3.0", + "@types/deno": "^2.5.0", "@types/node": ">=22.0.0, <23.0.0", + "@typescript/native-preview": "^7.0.0-dev.20260406.1", + "@vitest/coverage-v8": "^4.1.2", + "floating-vue": "^5.2.2", + "mermaid": "^11.14.0", + "publint": "^0.3.18", + "tsdown": "^0.21.7", + "typedoc": "^0.28.18", "typescript": "^6.0.2", - "vitest": "^4.1.2" + "vite": "^8.0.7", + "vitepress": "^2.0.0-alpha.17", + "vitest": "^4.1.2", + "yaml": "^2.8.3", + "dprint": "^0.53.2", + "knip": "^6.3.0", + "wrangler": "^4.81.0" } } diff --git a/packages/dreamcli/deno.json b/packages/dreamcli/deno.json index ba07b03e..259e6cdd 100644 --- a/packages/dreamcli/deno.json +++ b/packages/dreamcli/deno.json @@ -42,7 +42,15 @@ } }, "publish": { - "include": ["CHANGELOG.md", "LICENSE", "README.md", "dreamcli.schema.json", "src"], + "include": [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "dreamcli.schema.json", + "src", + "package.json", + "deno.json" + ], "exclude": ["src/**/*.test.ts", "src/**/*test-helpers.ts", "src/**/AGENTS.md"] }, "lib": ["deno.ns", "deno.shared_globals"], diff --git a/packages/dreamcli/package.json b/packages/dreamcli/package.json index 509bf894..4348ddcf 100644 --- a/packages/dreamcli/package.json +++ b/packages/dreamcli/package.json @@ -79,21 +79,21 @@ "typecheck:tsc": "tsc --noEmit" }, "devDependencies": { - "@arethetypeswrong/core": "^0.18.2", - "@iarna/toml": "^2.2.5", + "@arethetypeswrong/core": "catalog:", + "@iarna/toml": "catalog:", "@types/bun": "catalog:", - "@types/deno": "^2.5.0", + "@types/deno": "catalog:", "@types/node": "catalog:", - "@typescript/native-preview": "^7.0.0-dev.20260406.1", - "@vitest/coverage-v8": "^4.1.2", - "publint": "^0.3.18", - "tsdown": "^0.21.7", + "@typescript/native-preview": "catalog:", + "@vitest/coverage-v8": "catalog:", + "publint": "catalog:", + "tsdown": "catalog:", "typescript": "catalog:", "vitest": "catalog:", - "yaml": "^2.8.3" + "yaml": "catalog:" }, "optionalDependencies": { - "vite": "^8" + "vite": "catalog:" }, "engines": { "bun": ">=1.3.11", From f1a6b4b45de03b22cdf2650e9ff34189d21d263e Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Tue, 7 Apr 2026 22:42:16 +0200 Subject: [PATCH 06/21] chore: drop completed re-foundation specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PRD and spec served their purpose — all milestones landed. Sort docs config import alphabetically. --- apps/docs/.vitepress/config.ts | 2 +- specs/dreamcli-re-foundation-prd.md | 1206 --------------------------- specs/dreamcli-re-foundation.md | 847 ------------------- 3 files changed, 1 insertion(+), 2054 deletions(-) delete mode 100644 specs/dreamcli-re-foundation-prd.md delete mode 100644 specs/dreamcli-re-foundation.md diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts index 7fcbb553..097f183c 100644 --- a/apps/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -1,9 +1,9 @@ import { normalize } from 'node:path'; import { env } from 'node:process'; +import pkg from '@kjanat/dreamcli/package.json' with { type: 'json' }; import { transformerTwoslash } from '@shikijs/vitepress-twoslash'; import { ModuleDetectionKind, ModuleKind, ModuleResolutionKind } from 'typescript'; import { defineConfig } from 'vitepress'; -import pkg from '@kjanat/dreamcli/package.json' with { type: 'json' }; import pkgTsc from '../../../packages/dreamcli/tsconfig.json' with { type: 'json' }; import baseTsc from '../../../tsconfig.json' with { type: 'json' }; import { collectPublicApiIndex } from './data/api-index.ts'; diff --git a/specs/dreamcli-re-foundation-prd.md b/specs/dreamcli-re-foundation-prd.md deleted file mode 100644 index a97caf8e..00000000 --- a/specs/dreamcli-re-foundation-prd.md +++ /dev/null @@ -1,1206 +0,0 @@ -# DreamCLI Re-Foundation PRD - -**Status:** Proposed, execution-ready\ -**Owner:** Kaj Kowalski\ -**Repo:** `kjanat/dreamcli`\ -**Related spec:** `specs/dreamcli-re-foundation.md`\ -**Tracking project:** `https://github.com/users/kjanat/projects/4`\ -**Execution model:** Multi-milestone, backlog-driven, mixed-depth delivery\ -**Document intent:** Expand the re-foundation spec into an implementation-driving product requirements document with explicit backlog shape, acceptance criteria, rollout logic, documentation strategy, and governance. - -## 1. Executive Summary - -DreamCLI already has real strengths: strong type inference, a schema-first design, a useful test harness, -cross-runtime support, and a coherent builder surface. What it does not yet have is a coherent operating model -for its own core execution path or a product surface that consistently communicates why the framework is built -this way, how far the current implementation really goes, and how a serious adopter should approach it. - -This PRD proposes a re-foundation of DreamCLI across four coupled layers: - -1. **Execution architecture** -2. **Support truth and semantic clarity** -3. **Documentation and learning surfaces** -4. **Execution tracking and delivery governance** - -This is not a small refactor. It is also not a rewrite for its own sake. - -The core thesis is simple: - -- DreamCLI should have one explicit execution pipeline. -- DreamCLI should have one explicit truth model for what is supported and why. -- DreamCLI docs should feel connected to the actual source tree instead of hand-maintained approximations. -- DreamCLI should make advanced capability discoverable without becoming noisy, gimmicky, or harder to maintain. - -The end state is a framework that feels less like a clever internal architecture experiment and more like a -serious product with a legible execution model, honest support claims, first-class examples, IDE-like inspection -where it helps, and a maintained backlog that can be worked through incrementally without losing the big picture. - -## 2. Background and Why Now - -The current re-foundation need is driven by both code reality and product reality. - -On the code side, the current execution path is distributed across: - -- `src/core/cli/index.ts` -- `src/core/cli/dispatch.ts` -- `src/core/cli/propagate.ts` -- `src/core/testkit/index.ts` -- `src/core/resolve/index.ts` -- `src/core/output/index.ts` -- `src/core/output/activity.ts` -- `src/core/schema/command.ts` -- `src/core/schema/run.ts` - -The code works, but the architecture still makes maintainers answer these questions by reading multiple files at -once: - -- Who actually owns command execution? -- Where does planning stop and execution begin? -- Which layer decides output behavior versus rendering behavior? -- Which semantics are guaranteed versus accidental? -- Which product claims are source-backed versus aspirational? - -On the product side, the current docs have strong bones but incomplete truth. There are good guides, a clear -high-level pitch, and real examples, but the system still lacks: - -- a migration story; -- a consolidated limitations story; -- a troubleshooting story; -- a full explanation of architectural trade-offs; -- a first-class examples surface; -- generated API reference depth; -- calm, scoped IDE-like code inspection where it would add real value. - -The evaluation that triggered this work was not wrong. The evaluator's complaints are mostly symptoms of the same -underlying issue: DreamCLI has already grown past the point where architecture, docs, examples, and support claims -can evolve independently. - -## 3. Problem Statement - -DreamCLI currently has a split identity. - -It is strong enough internally to impress a technical reader, but not yet coherent enough externally to make a -serious adopter feel fully oriented and confident. - -### 3.1 Core problem - -DreamCLI lacks a single, explicit, tested, documented contract for how a command moves from raw invocation to -resolved values to handler execution to rendered output. - -### 3.2 Product impact - -This shows up in several ways: - -- maintainers touch large hot files for changes that should be local; -- architecture decisions are harder to explain because they are not staged clearly; -- advanced features exist but do not yet feel like a connected system; -- docs explain much of the "what" but not enough of the "why"; -- support breadth is not always expressed with full honesty; -- the product risks losing serious users after the first impressive demo. - -### 3.3 Opportunity cost of doing nothing - -If this work is deferred: - -- architecture cleanup gets harder as more features land on the current seams; -- resolver and CLI semantics continue to accrete complexity in the hottest areas; -- docs will either become more manual and stale, or more generated and incoherent if done without a foundation; -- advanced features will remain underused because discoverability will lag behind capability; -- adoption risk remains high even if individual technical features keep improving. - -## 4. Vision - -DreamCLI should become a framework where: - -- a maintainer can explain the execution pipeline in one diagram and one paragraph; -- a contributor can find the right seam for a change without re-deriving the whole system; -- an evaluator can see exactly what is supported, what is intentionally not yet supported, and why; -- a new user can learn through examples quickly; -- an advanced user can navigate from examples to exact API details without friction; -- docs feel directly wired into the codebase, not manually approximated; -- the backlog for finishing this transformation is explicit and actively trackable. - -## 5. Users and Stakeholders - -### 5.1 Primary users - -**Maintainer / framework author** - -Needs: - -- clear seams; -- lower cognitive load in core code; -- explicit test protection for semantics; -- a path to evolve the framework without hidden regressions. - -**Advanced evaluator / power user** - -Needs: - -- architectural coherence; -- truthful support claims; -- a compelling explanation of trade-offs; -- enough examples and reference to judge whether the framework is real. - -**New adopter** - -Needs: - -- a confident getting-started path; -- examples that scale beyond toy snippets; -- discoverability of advanced features; -- guidance for when to use DreamCLI and when not to. - -### 5.2 Secondary stakeholders - -**Future contributors** - -Need: - -- visible contracts; -- docs that map to code; -- a living backlog and project board. - -**Course/evaluation audience** - -Need: - -- strong rationale; -- a coherent explanation of trade-offs and limitations; -- evidence, not just claims. - -## 6. Product Principles - -The re-foundation must preserve and strengthen the project's best existing instincts. - -### 6.1 Schema is still the law - -The system should continue to treat schema definitions as the single source of truth for parsing, resolution, -help, completions, and testing. - -### 6.2 Explicit beats implicit - -If a core stage exists conceptually, it should exist architecturally. - -### 6.3 Calm docs win - -The docs should feel alive and helpful, not loud or over-instrumented. - -### 6.4 Source-backed truth - -Generated surfaces should derive from actual source-of-truth inputs: - -- source code; -- example files; -- changelog; -- explicit docs-health checks. - -### 6.5 Tests protect semantics, not file structure - -The re-foundation should be protected by black-box and contract tests, not by incidental line coverage or internal -shape. - -### 6.6 Ambition must stay operationally boring - -DreamCLI can be distinctive, but the implementation should still prefer durable, build-time, low-magic solutions. - -## 7. Goals - -### 7.1 Architecture goals - -1. Introduce a single shared internal execution engine. -2. Separate runtime preflight, planning, parsing, resolution, execution, and rendering into explicit stages. -3. Reduce mixed-responsibility hotspots in `cli`, `testkit`, `resolve`, and `output`. -4. Support selective redesign where the current semantics are weak or misleading. - -### 7.2 Product-truth goals - -1. Create an explicit support matrix. -2. Align support claims with actual implementation. -3. Explain major architecture and DX trade-offs clearly. - -### 7.3 Docs goals - -1. Make examples a first-class docs surface. -2. Surface `CHANGELOG.md` inside the docs. -3. Add a public docs-health page. -4. Build a real generated API index and later symbol pages. -5. Add Twoslash-style hover on example pages only. - -### 7.4 Delivery goals - -1. Turn the re-foundation into a trackable project with draft backlog items. -2. Sequence work so riskier architecture changes happen before truth-sensitive docs work. -3. Preserve a working multi-session flow via `.opencode/state/`. - -## 8. Non-Goals - -1. Keep the current internal module boundaries. -2. Preserve non-public APIs or type names. -3. Keep fish and PowerShell as unimplemented placeholders. -4. Build a site-wide interactive IDE. -5. Replace authored guides/concepts with generated prose. -6. Introduce runtime dependencies into DreamCLI core. -7. Treat the re-foundation as one giant unrecoverable rewrite. - -## 9. Constraints and Assumptions - -### 9.1 Explicit constraints - -- Breaking changes are acceptable because there are no external consumers to preserve. -- Internal files and names may move freely. -- Human-written docs remain human-written. -- Generated docs should be build-time derived. -- GitHub tracking should use a new private project. -- Tracked items in GitHub should be draft project items, not real repo issues. - -### 9.2 Working assumptions - -- The repo remains centered on Bun/VitePress/Vitest/TypeScript tooling. -- TypeDoc and Twoslash can be added as docs-tooling dependencies if they materially improve the docs platform. -- The current spec in `specs/dreamcli-re-foundation.md` remains the short architectural backbone; this PRD expands it. - -## 10. Scope Model - -This re-foundation includes several major workstreams that must be treated as one coordinated effort. - -### 10.1 In scope - -- support truth inventory and semantic baseline; -- explicit planner/resolver/executor/renderer contracts; -- new shared internal executor; -- CLI planner extraction and runtime preflight split; -- resolver decomposition and selective redesign; -- output policy cleanup; -- fish and PowerShell completion implementation; -- docs preparation pipeline; -- generated examples; -- Twoslash hover on examples; -- changelog surfacing; -- docs health; -- API index; -- TypeDoc normalization and symbol pages; -- rationale, migration, troubleshooting, limitations, and comparison docs; -- CI and coverage hardening relevant to the re-foundation. - -### 10.2 Out of scope for first-wave execution - -- hover across arbitrary guide snippets; -- custom interactive tutorial editor machinery; -- versioned docs; -- animation catalogs and other visually rich side systems; -- bundle-size dashboards; -- custom extractor replacing TypeDoc before real evidence says it is needed. - -## 11. Current-State Diagnosis - -### 11.1 Execution ownership is hidden - -`runCommand()` in `src/core/testkit/index.ts` is effectively the execution owner, but the architecture does not -present it that way. CLI routing, output shaping, and execution wiring remain split enough that ownership still -needs to be inferred rather than read. - -### 11.2 Planning and execution are coupled - -`src/core/cli/index.ts` still mixes several concerns: - -- runtime sourcing; -- config/package metadata discovery; -- root command behavior; -- command erasure; -- dispatch outcome branching; -- command meta assembly; -- final result shaping. - -### 11.3 Resolver density is too high - -`src/core/resolve/index.ts` currently blends: - -- precedence policy; -- prompt orchestration; -- coercion behavior; -- config path traversal; -- arg-specific fallbacks; -- deprecation collection; -- error aggregation; -- source-specific suggestion building. - -Even when correct, that is too much semantic density in one place. - -### 11.4 Output policy and output implementation are not separated cleanly enough - -Output behavior currently works, but the distinction between choosing a mode and rendering that mode is not as -crisp as it should be for future extension or simpler reasoning. - -### 11.5 Docs are strong but not yet systematized - -Docs already have enough substance to support a much richer product surface, but they still rely too much on -manual discoverability and too little on structured derivation. - -## 12. Proposed Future-State Architecture - -### 12.1 Stage model - -The target stage model is: - -```txt -runtime preflight -> invocation planner -> parser -> resolver -> executor -> renderer -``` - -This model is not just explanatory. It must become architectural truth. - -### 12.2 Runtime preflight - -Responsibilities: - -- adapter selection; -- stdin availability facts; -- prompt availability facts; -- package.json discovery; -- config discovery; -- argv normalization at the CLI boundary. - -Non-responsibilities: - -- parsing command values; -- command resolution; -- handler invocation. - -### 12.3 Invocation planner - -Responsibilities: - -- root `--help` and `--version` interception; -- nested command dispatch; -- default-command fallback; -- propagated flag collection and shadowing; -- merged schema handoff; -- command metadata construction. - -Non-responsibilities: - -- prompting; -- env/config lookup; -- running action handlers. - -### 12.4 Parser - -Responsibilities: - -- tokenization; -- argv-to-parse-result conversion. - -Non-responsibilities: - -- runtime facts; -- value sourcing; -- validation against env/config/prompt sources. - -### 12.5 Resolver - -Responsibilities: - -- source precedence; -- prompt behavior; -- coercion and validation; -- deprecation collection; -- aggregated error reporting. - -Non-responsibilities: - -- command routing; -- output rendering; -- lifecycle execution. - -### 12.6 Shared executor - -Responsibilities: - -- parse -> resolve -> hooks -> derive/middleware -> action; -- common cleanup; -- common error wrapping; -- common `RunResult` assembly. - -### 12.7 Renderer - -Responsibilities: - -- CLI-facing terminal rendering and exit behavior; -- in-process capture behavior for testkit; -- CLI-level JSON/text formatting of errors and output. - -## 13. Contract Targets - -The exact names may change, but these contract shapes should exist explicitly. - -### 13.1 Dispatch / planner contract - -```ts -type DispatchOutcome = - | { readonly kind: 'root-help'; readonly help: HelpOptions } - | { readonly kind: 'root-version'; readonly version: string } - | { readonly kind: 'dispatch-error'; readonly error: CLIError } - | { readonly kind: 'match'; readonly plan: CommandExecutionPlan }; - -interface CommandExecutionPlan { - readonly command: ErasedCommand; - readonly mergedSchema: CommandSchema; - readonly argv: readonly string[]; - readonly meta: CommandMeta; - readonly plugins: readonly CLIPlugin[]; - readonly output: OutputPolicy; - readonly help: HelpOptions | undefined; -} -``` - -### 13.2 Resolved input contract - -```ts -interface ResolvedCommandInput { - readonly flags: Readonly>; - readonly args: Readonly>; - readonly deprecations: readonly DeprecationWarning[]; -} -``` - -### 13.3 Output policy contract - -```ts -interface OutputPolicy { - readonly jsonMode: boolean; - readonly isTTY: boolean; - readonly verbosity: Verbosity; -} -``` - -### 13.4 Support truth contract - -```ts -interface SupportMatrixEntry { - readonly claim: string; - readonly status: 'supported' | 'deferred' | 'experimental'; - readonly evidence: readonly string[]; - readonly notes: string | undefined; -} -``` - -## 14. Workstream A - Support Truth and Semantic Baseline - -This workstream exists so the re-foundation can distinguish: - -- behavior that must be preserved; -- behavior that may be redesigned; -- behavior that is currently overclaimed; -- behavior that is intentionally deferred. - -### Requirements - -1. Create an explicit support matrix for major DreamCLI claims. -2. Mark each claim as supported, deferred, or experimental. -3. Link each supported claim to evidence. -4. List every planned semantic redesign explicitly. -5. Resolve completion support truth before broad docs changes. - -### Acceptance criteria - -- [ ] The support matrix includes architecture, runtime, completions, output, prompts, config, testing, examples, and docs surfaces. -- [ ] Each matrix entry includes status and evidence. -- [ ] Fish and PowerShell are not listed as supported until implementation lands. -- [ ] The matrix distinguishes intentional redesign from accidental current-state behavior. -- [ ] The matrix becomes a maintained source for docs and project tracking. - -## 15. Workstream B - Characterization and Contract Testing - -This workstream creates the regression net for the re-foundation. - -### Requirements - -1. Add black-box planner tests. -2. Add precedence matrix tests for flags and args. -3. Add prompt and stdin gating tests. -4. Add lifecycle order tests. -5. Add output policy tests across `jsonMode`, `isTTY`, and `verbosity`. -6. Add completion tests for all supported shells. -7. Keep existing high-value end-to-end suites green throughout refactoring. - -### Acceptance criteria - -- [ ] Planner outcomes can be tested without running handlers. -- [ ] Resolver precedence is covered by matrix-style tests instead of scattered single-source checks only. -- [ ] Prompt cancellation and stdin fallback behavior are black-box tested. -- [ ] Default-command, root-help, root-version, and nested-command behavior are explicitly protected. -- [ ] Completion tests cover bash, zsh, fish, and PowerShell once those shells are implemented. -- [ ] The test suite can distinguish intended semantic changes from regressions. - -## 16. Workstream C - Shared Executor and CLI/Testkit Inversion - -This is the architectural center of the re-foundation. - -### Requirements - -1. Introduce `src/core/execution/` or equivalent. -2. Move common execution flow into that layer. -3. Make testkit a consumer, not the owner, of execution. -4. Make CLI a planner and renderer over the same executor. -5. Consolidate result assembly and cleanup. - -### Acceptance criteria - -- [ ] There is one canonical path from parsed/resolved command input to handler invocation and result assembly. -- [ ] `runCommand()` no longer hides framework-wide execution ownership. -- [ ] CLI and testkit cannot drift in handler execution behavior without tests failing. -- [ ] Cleanup of active output handles is guaranteed in one place. -- [ ] `RunResult` ownership is explicit and no longer reconstructed ad hoc in multiple places. - -## 17. Workstream D - CLI Planning and Runtime Preflight Split - -### Requirements - -1. Separate runtime sourcing from planner logic. -2. Represent planner outcomes as an explicit union. -3. Isolate command erasure and command-tree planning concerns. -4. Make propagated flag handling explicit and locally testable. - -### Acceptance criteria - -- [ ] Runtime preflight can be reasoned about separately from dispatch. -- [ ] Planner code does not also own execution semantics. -- [ ] Propagated flag merge rules are tested independently of handler execution. -- [ ] `cli/index.ts` materially loses mixed responsibilities rather than just moving lines around. - -## 18. Workstream E - Resolver Decomposition and Selective Redesign - -### Requirements - -1. Split resolver code by concern. -2. Decide which semantics are intentionally improved. -3. Improve diagnostic quality where current behavior is opaque. -4. Reduce arg/flag duplication where a shared property model is justified. -5. Preserve the most valuable current invariants unless explicitly redesigning them. - -### Candidate redesign targets - -- stronger source-aware diagnostics; -- clearer aggregation strategy; -- cleaner prompt suppression semantics; -- less fragile arg/flag coercion reuse; -- clearer distinction between authoritative coercion failures and optional fallback behavior. - -### Acceptance criteria - -- [ ] `resolve/index.ts` is no longer the place where every resolution concern lives. -- [ ] Resolver redesign decisions are documented and reflected in tests. -- [ ] Error output tells users which source failed and what to do next. -- [ ] Aggregated errors are consistent across flags and args where appropriate. -- [ ] No redesign is allowed to remain implicit or undocumented. - -## 19. Workstream F - Output Cleanup and Full Completion Support - -### Requirements - -1. Separate output policy selection from output rendering. -2. Preserve or improve activity semantics while making them easier to reason about. -3. Implement real fish completion support. -4. Implement real PowerShell completion support. -5. Align docs, types, and tests with actual shell support. - -### Acceptance criteria - -- [ ] Output policy exists as an explicit concept, not an emergent one. -- [ ] fish completion generation works and is tested. -- [ ] PowerShell completion generation works and is tested. -- [ ] No supported shell throws a placeholder exception. -- [ ] Docs and support matrix match implementation exactly. - -## 20. Workstream G - Docs Preparation Foundation - -This workstream creates the boring foundation for every generated docs surface. - -### Requirements - -1. Add `docs:prepare`. -2. Generate artifacts under `docs/.generated/`. -3. Create extraction scripts under `scripts/docs/`. -4. Wire docs generation into `docs:dev` and `docs:build`. -5. Keep authored and generated content sharply separated. - -### Acceptance criteria - -- [ ] `docs:prepare` can regenerate all generated docs artifacts from source-of-truth inputs. -- [ ] Generated docs live under `docs/.generated/`. -- [ ] `docs:dev` and `docs:build` depend on prepared artifacts. -- [ ] Generated artifacts are reproducible and not hand-edited. -- [ ] The docs platform can add new generated content types without architectural churn. - -## 21. Workstream H - Generated Examples and Hover - -Examples are the highest-ROI docs feature and the right first place for hover. - -### Requirements - -1. Generate an examples index. -2. Generate one docs page per example. -3. Extract metadata from module-level JSDoc and example source. -4. Add top-level Examples navigation. -5. Enable Twoslash hover on example pages only. -6. Keep pages readable without hover. - -### Example page requirements - -Every generated example page should include: - -1. title; -2. summary; -3. what it demonstrates; -4. usage hints; -5. full source; -6. related guides; -7. related API symbols; -8. source path. - -### Acceptance criteria - -- [ ] Adding a new example file creates a new docs page automatically. -- [ ] Example pages are discoverable from nav and search. -- [ ] Hover works against local DreamCLI source on example pages. -- [ ] Hover is not required for comprehension. -- [ ] Example pages link clearly to related guides and symbols. - -## 22. Workstream I - Changelog and Docs Health - -### Requirements - -1. Surface `CHANGELOG.md` inside the docs. -2. Add a factual public docs-health page. -3. Keep docs-health metrics objective and non-gamified. - -### Docs-health v1 metrics - -- total docs pages; -- total generated example pages; -- public API symbol count; -- symbols with summary docs; -- symbols with full signature pages; -- pages missing descriptions; -- broken internal links; -- extraction warnings; -- generation timestamp. - -### Acceptance criteria - -- [ ] The changelog is browsable in the docs site. -- [ ] Docs health is public, factual, and useful. -- [ ] The health page highlights real gaps instead of vanity metrics. -- [ ] Contributors can use the page to spot actionable docs work. - -## 23. Workstream J - API Index and Symbol Pages - -### Requirements - -1. Generate a symbol inventory from public entrypoints. -2. Group symbols by subpath and kind. -3. Generate an API index page. -4. Use TypeDoc JSON for full signature data. -5. Normalize TypeDoc output before rendering. -6. Generate per-symbol pages. -7. Link examples and reference together. - -### Acceptance criteria - -- [ ] Every public export appears in the generated API index. -- [ ] The API index is more complete and more navigable than the current manual overview. -- [ ] TypeDoc output is normalized into DreamCLI's own docs model. -- [ ] Per-symbol pages are stable, linkable, and searchable. -- [ ] Examples and symbol pages can link to each other. - -## 24. Workstream K - Narrative Docs, Rationale, Migration, and Troubleshooting - -This workstream should happen after the architecture and truth surfaces are stable enough to document honestly. - -### Required authored docs - -1. Decision/rationale page. -2. Known limitations and workarounds page. -3. Troubleshooting page. -4. Migration/adoption guide. -5. Realistic side-by-side comparison page. -6. derive vs middleware vs interactive guidance. - -### Acceptance criteria - -- [ ] DreamCLI explains not just what it does, but why it does it this way. -- [ ] Limitations are consolidated with scope and workarounds. -- [ ] Troubleshooting covers the most likely real failure modes. -- [ ] Migration guidance helps a user think about switching from competing tools. -- [ ] Feature decision guidance reduces bounce risk for serious adopters. - -## 25. Workstream L - CI, Coverage, and Reliability Hardening - -### Requirements - -1. Add an explicit coverage command. -2. Add coverage thresholds. -3. Make docs build verification part of the stable workflow. -4. Verify `docs:prepare` behavior in CI. -5. Improve clarity around runtime/platform checks. - -### Acceptance criteria - -- [ ] Coverage is measured and gated intentionally. -- [ ] Docs generation failures are caught in CI. -- [ ] Runtime support claims remain aligned with tests and docs. -- [ ] CI comments and workflow descriptions match actual behavior. - -## 26. Data Models for Generated Docs - -The generated docs platform should not improvise ad hoc JSON shapes per script. - -### Example docs model - -```ts -interface ExampleDoc { - readonly slug: string; - readonly title: string; - readonly summary: string; - readonly demonstrates: readonly string[]; - readonly usage: readonly string[]; - readonly importedSymbols: readonly string[]; - readonly sourceText: string; - readonly sourcePath: string; - readonly relatedGuides: readonly string[]; - readonly relatedSymbols: readonly string[]; -} -``` - -### API symbol model - -```ts -interface ApiSymbolDoc { - readonly id: string; - readonly subpath: '.' | './testkit' | './runtime'; - readonly name: string; - readonly kind: string; - readonly summary: string | undefined; - readonly sourceFile: string; - readonly deprecated: boolean; - readonly examples: readonly string[]; -} -``` - -### Docs-health model - -```ts -interface DocsHealthReport { - readonly generatedAt: string; - readonly totalPages: number; - readonly generatedExamplePages: number; - readonly publicSymbolCount: number; - readonly symbolsWithSummary: number; - readonly symbolsWithSignaturePages: number; - readonly pagesMissingDescriptions: readonly string[]; - readonly brokenInternalLinks: readonly string[]; - readonly extractionWarnings: readonly string[]; -} -``` - -### Acceptance criteria - -- [ ] Generated data models are explicit and reusable. -- [ ] Scripts do not each invent their own incompatible shapes. -- [ ] Rendering code depends on normalized data rather than raw extraction quirks. - -## 27. Functional Requirements Summary - -### FR-1: Shared executor - -DreamCLI must have a single shared internal execution engine used by both CLI and testkit. - -### FR-2: Explicit planner - -DreamCLI must expose invocation planning as an explicit internal stage with clear outcomes. - -### FR-3: Resolver redesign - -DreamCLI must redesign and decompose the resolver so source precedence and diagnostics are explicit and testable. - -### FR-4: Completion breadth - -DreamCLI must support bash, zsh, fish, and PowerShell completions with tests. - -### FR-5: Docs pipeline - -DreamCLI must generate structured docs artifacts via `docs:prepare`. - -### FR-6: Example-first docs - -DreamCLI must generate example pages and make them top-level discoverable. - -### FR-7: Example hover - -DreamCLI must support Twoslash hover on example pages. - -### FR-8: Changelog surfacing - -DreamCLI must expose `CHANGELOG.md` in the docs. - -### FR-9: Docs health - -DreamCLI must publish a factual docs-health page. - -### FR-10: API reference - -DreamCLI must generate an API index and later symbol pages from normalized TypeDoc data. - -### FR-11: Narrative docs completion - -DreamCLI must publish rationale, limitations, troubleshooting, migration, and comparison docs after semantic stabilization. - -### FR-12: Trackable execution - -DreamCLI must maintain a backlog in both `.opencode/state/` and a private GitHub project. - -## 28. Non-Functional Requirements - -### NFR-1: Maintainability - -Changes in planner, resolver, executor, and renderer should become easier to localize. - -### NFR-2: Observability - -Core semantic changes should be visible in tests and changelog/docs, not hidden in internal moves. - -### NFR-3: Reliability - -The architecture should make regressions harder to introduce silently. - -### NFR-4: Docs calmness - -Interactivity should remain scoped and subtle. - -### NFR-5: Build-time orientation - -Docs features should prefer build-time computation over runtime machinery. - -### NFR-6: Truthfulness - -No public docs surface should overstate support relative to implementation. - -## 29. Rollout Strategy - -### Phase 1 - Truth and contracts - -Deliver: - -- support truth matrix; -- semantic baseline; -- contract targets; -- characterization suites. - -### Phase 2 - Core execution re-foundation - -Deliver: - -- shared executor; -- CLI planner split; -- runtime preflight split; -- clear execution ownership. - -### Phase 3 - Resolver and output/completion modernization - -Deliver: - -- resolver decomposition; -- selective semantic redesign; -- fish and PowerShell completions; -- output policy cleanup. - -### Phase 4 - Docs foundation and generated surfaces - -Deliver: - -- `docs:prepare`; -- generated examples; -- hover on examples; -- changelog; -- docs health; -- API index; -- TypeDoc normalization and symbol pages. - -### Phase 5 - Narrative docs and hardening - -Deliver: - -- rationale; -- limitations; -- troubleshooting; -- migration; -- comparison; -- CI hardening. - -## 30. GitHub Project Requirements - -The re-foundation must be trackable outside the repo as active project work. - -### Project configuration - -- Project title: `DreamCLI Re-Foundation` -- Visibility: Private -- Item type: Draft project items -- Default workflow field: `Backlog`, `Ready`, `In Progress`, `Blocked`, `Done` -- Additional fields should support milestone/phase and execution priority. - -### Project purpose - -The project is not just a todo list. It should answer: - -- what phase the work is in; -- what is blocked; -- what is ready next; -- which items are architecture-heavy versus docs/polish-heavy; -- which workstreams are already represented in the PRD. - -### Acceptance criteria - -- [ ] A dedicated private GitHub Project exists for the re-foundation. -- [ ] Draft items mirror the PRD task graph. -- [ ] Workflow states support backlog, readiness, active work, blockage, and done states. -- [ ] The project can be used as the operational board while `.opencode/state/` remains the file-based task source. - -## 31. Backlog Design Principles - -### 31.1 Mixed-depth backlog - -The backlog should be detailed where risk is high and lighter where work is straightforward. - -### 31.2 One PRD, many slices - -This PRD is intentionally large, but execution should happen in bounded slices. - -### 31.3 Dependencies must be real - -Dependencies should reflect architectural blocking relationships, not bureaucratic sequencing. - -### 31.4 Docs work should not outrun truth - -Narrative docs must follow stabilized semantics. - -## 32. Success Metrics - -### Architecture success - -- one shared executor exists and is used consistently; -- planner, resolver, executor, and renderer are each explicit concepts in both code and docs; -- core hotspots lose mixed responsibility, not just lines. - -### Product-truth success - -- every major claim has status and evidence; -- support breadth is honest; -- redesign decisions are visible. - -### Docs success - -- examples are top-level discoverable; -- hover works on examples without making the docs feel noisy; -- changelog is browsable; -- docs health is factual and useful; -- API index and symbol pages exist and are usable. - -### Adoption success - -- the docs explain why DreamCLI exists, who it is for, and where it is limited; -- derive vs middleware vs interactive is easier to reason about; -- the framework feels like a product with a roadmap, not a bag of features. - -## 33. Risks and Mitigations - -### Risk 1: The shared executor becomes just another blurry abstraction - -Mitigation: - -- keep the stage model explicit; -- keep planner and renderer out of the executor; -- test the executor as a boundary, not an implementation detail. - -### Risk 2: Resolver redesign balloons into a local rewrite-without-end - -Mitigation: - -- separate decomposition from semantic redesign; -- require explicit redesign notes; -- protect behavior with matrix tests before movement. - -### Risk 3: Completion breadth steals time from core architecture cleanup - -Mitigation: - -- sequence shell work after planner/executor seams are stable; -- keep shell generators black-box tested. - -### Risk 4: Generated docs become a second product to maintain - -Mitigation: - -- strict extraction/render split; -- build-time only; -- calm UX; -- avoid custom runtime tricks until proven necessary. - -### Risk 5: Hover becomes annoying or performative - -Mitigation: - -- examples only first; -- default Twoslash UI first; -- do not rely on hover for core understanding. - -### Risk 6: TypeDoc shape is imperfect for DreamCLI's API presentation - -Mitigation: - -- normalize the data model; -- start with an API index; -- only consider a custom extractor if TypeDoc proves materially insufficient. - -### Risk 7: Docs narrative is written too early and immediately becomes stale - -Mitigation: - -- keep semantics-sensitive docs until after architecture and truth stabilize. - -## 34. Dependencies and Ordering Logic - -### Hard dependencies - -- truth matrix before narrative truth-sensitive docs; -- characterization tests before core movement; -- shared executor before full CLI/testkit ownership cleanup; -- planner split before broad completion and root-surface polish; -- docs foundation before generated examples/changelog/health/reference; -- TypeDoc normalization before symbol-page rendering. - -### Soft dependencies - -- docs health can begin once docs foundation exists; -- API index can precede full symbol pages; -- migration docs can begin once the major redesign choices are settled, even if some polish remains. - -## 35. Detailed Acceptance Checklist - -### Architecture checklist - -- [ ] Execution ownership is explicit. -- [ ] Planner is a distinct internal concept. -- [ ] Runtime preflight is separated from planner logic. -- [ ] Resolver is decomposed by concern. -- [ ] Output policy is separated from rendering. -- [ ] Shared executor is used by CLI and testkit. -- [ ] Result assembly is not duplicated. - -### Semantics checklist - -- [ ] Preserved semantics are identified. -- [ ] Redesigned semantics are identified. -- [ ] Resolver precedence remains explicit. -- [ ] Error behavior is clearer than before. -- [ ] Completion support claims are honest. - -### Docs checklist - -- [ ] `docs:prepare` exists. -- [ ] Generated docs live under `docs/.generated/`. -- [ ] Examples are top-level discoverable. -- [ ] Twoslash hover works on example pages. -- [ ] `CHANGELOG.md` is visible in docs. -- [ ] Docs health is visible in docs. -- [ ] API index exists. -- [ ] Symbol pages exist. -- [ ] Rationale docs exist. -- [ ] Limitations docs exist. -- [ ] Troubleshooting docs exist. -- [ ] Migration docs exist. - -### Reliability checklist - -- [ ] Contract suites exist for planner, resolver, executor, output, and completions. -- [ ] Coverage thresholds exist. -- [ ] Docs build verification exists. -- [ ] Workflow descriptions in CI match actual behavior. - -### Tracking checklist - -- [ ] `.opencode/state/dreamcli-re-foundation/` exists. -- [ ] `prd.json` is populated and valid. -- [ ] `progress.txt` exists. -- [ ] GitHub project exists. -- [ ] Draft project items mirror the backlog. - -## 36. Execution Readiness Criteria - -The PRD is considered ready to drive work when: - -1. the project backlog can be generated directly from it; -2. the first three phases are sufficiently concrete to start execution immediately; -3. the tracking project exists and is populated; -4. the document gives enough guidance that execution can continue across sessions without re-scoping the effort. - -## 37. Initial Task Breakdown Intent - -The first execution slices should be: - -1. support truth matrix and semantic baseline; -2. characterization and contract tests; -3. shared executor seam; -4. CLI planner/runtime split. - -That ordering is intentional because it minimizes the chance of elegant-looking but semantically unsafe refactors. - -## 38. Out-of-Band Coordination Rules - -While this PRD is active: - -- docs truth should not be updated casually without checking the support matrix; -- completion support should not be marketed beyond what tests confirm; -- architecture moves should update the PRD backlog and progress log when they materially change sequencing; -- major semantic redesigns should be logged explicitly. - -## 39. What Done Looks Like - -When this PRD succeeds, DreamCLI should feel like this: - -- the execution path is easy to explain and safe to change; -- the docs feel connected to the source tree; -- examples are a powerful entry point, not an afterthought; -- hover is useful but not noisy; -- the API reference is real; -- support claims are fully honest; -- the backlog is visible and tractable; -- the framework feels mature enough that a critical evaluator or adopter can trust it. - -## 40. Final Product Judgment Target - -This re-foundation should move DreamCLI from "technically strong with visible gaps" toward -"coherent, evidence-backed, product-grade framework". - -That means the final standard is not merely fewer lines in hot files. - -It is: - -- clearer architecture; -- clearer semantics; -- clearer truth; -- clearer learning path; -- clearer execution discipline. - -## 41. No Open Questions - -The major framing decisions for this PRD are resolved: - -- private dedicated GitHub project; -- draft project items instead of real repo issues; -- mixed-depth backlog; -- PRD expands the existing spec; -- examples, changelog, docs health, TypeDoc reference, and example hover are all in scope; -- fish and PowerShell completion support are in scope. - -Further questions can emerge during execution, but they are implementation questions, not PRD-blocking questions. diff --git a/specs/dreamcli-re-foundation.md b/specs/dreamcli-re-foundation.md deleted file mode 100644 index c23d7746..00000000 --- a/specs/dreamcli-re-foundation.md +++ /dev/null @@ -1,847 +0,0 @@ -# DreamCLI Re-Foundation - -**Status:** Ready for milestone breakdown\ -**Type:** Master RFC / implementation spec\ -**Effort:** XL\ -**Horizon:** Open-ended, multi-milestone\ -**Last updated:** 2026-04-02 - -## Problem Statement - -DreamCLI is technically strong, but the highest-value parts of the product are split across too many -implicit contracts. - -Today: - -- command planning lives in `src/core/cli/index.ts`, `dispatch.ts`, and `propagate.ts`; -- execution lives mostly in `src/core/testkit/index.ts`; -- resolution semantics live in `src/core/resolve/index.ts`; -- output and activity policy live in `src/core/output/index.ts` and `activity.ts`; -- product truth in docs is incomplete or inconsistent with reality in a few places. - -This causes two real problems: - -1. maintainers pay high cognitive cost every time they touch dispatch, resolution, output, or docs; -2. adopters hit ambiguity exactly where DreamCLI should feel most trustworthy: execution semantics, - trade-offs, examples, migration confidence, and feature support claims. - -This spec treats those as one problem, not separate cleanup chores. - -## Goals - -1. Make the execution pipeline explicit, staged, and testable. -2. Replace hidden ownership with a single shared internal executor. -3. Allow selective semantic redesign where current behavior is weak, misleading, or fragmented. -4. Make support claims fully honest, including completions and docs positioning. -5. Build a docs platform that derives structured content from source-of-truth inputs. -6. Turn examples into a first-class learning and reference surface. -7. Ship real fish and PowerShell completions. - -## Non-Goals - -- Preserve existing internal file layout. -- Preserve non-public APIs or type names. -- Keep the current testkit-owned execution model. -- Build a fully custom docs IDE. -- Version the docs site or this spec. -- Add runtime dependencies to the library core. - -## Constraints - -- Selective redesign is allowed. -- Breaking changes are acceptable because there are no external consumers to preserve. -- Internal files and names may move freely. -- New internal seams are encouraged where they reduce coupling. -- Human-written `concepts/` and `guide/` pages remain authored prose. -- Generated docs must be build-time derived, not runtime-clever. - -## Evidence - -This spec is grounded in: - -- the evaluation feedback from 2026-04-02; -- `ROADMAP-DOCS.md`; -- `ROADMAP-DOCS-SICK.md`; -- current hotspots in `src/core/cli/`, `src/core/testkit/`, `src/core/resolve/`, - `src/core/output/`, and `src/core/completion/`; -- current CI and coverage config in `.github/workflows/ci.yml`, `package.json`, and - `vitest.config.ts`. - -## Current State Summary - -### Architectural hotspots - -- `src/core/cli/index.ts` - - owns root preflight, runtime sourcing, command erasure, help/version interception, dispatch, - meta assembly, and result rendering. -- `src/core/testkit/index.ts` - - is the de facto canonical executor even though that ownership is not expressed in the - architecture. -- `src/core/resolve/index.ts` - - mixes precedence rules, prompt handling, coercion, config lookup, arg resolution, error - aggregation, and source-specific suggestion building. -- `src/core/output/index.ts` and `src/core/output/activity.ts` - - mix output policy choice with concrete rendering and fallback behavior. -- `src/core/schema/command.ts` and `src/core/schema/run.ts` - - expose contracts that multiple layers depend on, but the ownership boundaries around those - contracts are not fully explicit. - -### Product-truth hotspots - -- docs lack a stable, explicit “why this design” layer; -- limitations and troubleshooting are scattered instead of consolidated; -- migration/adoption guidance is effectively absent; -- examples exist but are underexposed; -- completion support is broader in type surface than in actual implementation; -- docs and code claims are not always synchronized enough to inspire trust. - -## Recommendation - -Use **staged extraction plus branch-by-abstraction** around a **new shared internal executor**. - -This is not a big-bang rewrite. - -It is a controlled re-foundation with this backbone: - -1. define product truth and target semantics; -2. freeze current and intended behavior with characterization tests; -3. introduce explicit planner, resolver, executor, and renderer contracts; -4. move code behind those contracts in stages; -5. implement missing completion support; -6. build source-backed docs infrastructure; -7. publish the stronger product story after semantics stabilize. - -## Core Decisions - -### D1: New shared executor becomes the canonical execution owner - -Create a new internal execution layer, likely under `src/core/execution/`, and make both CLI and -testkit call it. - -Rationale: - -- execution is currently real but hidden inside `runCommand()`; -- CLI and testkit should not each own policy fragments; -- a shared executor is the narrowest seam that makes the architecture legible. - -### D2: Planner, resolver, executor, and renderer become distinct stages - -The target execution pipeline is: - -```txt -runtime preflight -> invocation planner -> parser -> resolver -> executor -> renderer -``` - -Each stage gets an explicit input/output contract and its own test layer. - -### D3: Selective redesign is allowed, but must be explicit - -This cleanup may intentionally change semantics where current behavior is weak or misleading. - -Examples likely in scope: - -- stronger resolver diagnostics with source traceability; -- consistent aggregation behavior between flags and args; -- clearer output policy boundaries; -- explicit command planning outcomes instead of ad hoc branching. - -Every deliberate semantic change must be called out in changelog/docs and covered by contract tests. - -### D4: Examples become the highest-ROI docs surface - -Examples are the first generated docs product because they already exist, already carry useful JSDoc, -and are the best place to introduce IDE-like hover. - -### D5: TypeDoc plus normalization is the reference strategy - -Do not build a custom symbol extractor first. - -Use TypeDoc JSON as the eventual source for full signature pages, but normalize it into a -DreamCLI-specific docs model before rendering. - -### D6: Hover ships on example pages first - -Use default Twoslash hover on generated example pages first. Do not enable hover across prose-heavy -guide pages until example-page hover proves calm and useful. - -### D7: Completion breadth must match support claims - -Implement fish and PowerShell completions for real. Do not leave those shells in an aspirational, -throwing state once the support matrix is formalized. - -## Stable Contracts - -These contracts must be defined before major code movement. - -### Invocation planner - -```ts -type DispatchOutcome = - | { readonly kind: 'root-help'; readonly help: HelpOptions } - | { readonly kind: 'root-version'; readonly version: string } - | { readonly kind: 'dispatch-error'; readonly error: CLIError } - | { readonly kind: 'match'; readonly plan: CommandExecutionPlan }; - -interface CommandExecutionPlan { - readonly command: ErasedCommand; - readonly mergedSchema: CommandSchema; - readonly argv: readonly string[]; - readonly meta: CommandMeta; - readonly plugins: readonly CLIPlugin[]; - readonly output: OutputPolicy; - readonly help: HelpOptions | undefined; -} -``` - -Requirements: - -- planner owns root help/version/default-command behavior; -- planner owns propagated-flag schema merging; -- planner does not parse values or run handlers; -- planner outcomes are black-box tested without invoking handlers. - -### Resolver contract - -```ts -interface ResolvedCommandInput { - readonly flags: Readonly>; - readonly args: Readonly>; - readonly deprecations: readonly DeprecationWarning[]; -} -``` - -Requirements: - -- precedence rules are explicit and tested; -- hard coercion failures are not silently replaced by prompt/default fallbacks; -- aggregated errors have stable shape and stable ordering rules; -- source-aware diagnostics are possible without leaking implementation detail to handlers. - -### Output policy contract - -```ts -interface OutputPolicy { - readonly jsonMode: boolean; - readonly isTTY: boolean; - readonly verbosity: Verbosity; -} -``` - -Requirements: - -- output policy is chosen outside concrete rendering code; -- JSON, TTY, and quiet semantics are stable and testable; -- activity cleanup is guaranteed in one place. - -### Support truth contract - -```ts -interface SupportMatrixEntry { - readonly claim: string; - readonly status: 'supported' | 'deferred' | 'experimental'; - readonly evidence: readonly string[]; -} -``` - -Requirements: - -- every marketed feature has a status; -- every supported feature points to proof in tests, docs, or generated artifacts; -- docs are generated or updated from this truth, not written independently of it. - -## Target Architecture - -### Runtime preflight - -Owns: - -- adapter selection; -- package.json discovery; -- config discovery; -- root argv normalization; -- prompt and stdin availability facts. - -Should live in CLI-facing code, not in the shared executor. - -### Invocation planner - -Owns: - -- root `--help` and `--version` handling; -- dispatch across nested commands; -- default-command fallback; -- propagated-flag collection and shadowing; -- meta assembly for the matched command; -- handoff to executor. - -### Parser - -Owns: - -- argv tokenization and schema-based parsing only. - -No runtime sourcing, no prompting, no execution decisions. - -### Resolver - -Owns: - -- flag precedence: CLI -> env -> config -> prompt -> default; -- arg precedence: CLI -> stdin -> env -> default; -- prompt gating; -- coercion and validation; -- deprecation collection; -- aggregated error construction. - -### Shared executor - -Owns: - -- parse -> resolve -> hooks -> derive/middleware -> action; -- guaranteed `out.stopActive()` cleanup; -- conversion to `RunResult`; -- common error wrapping. - -### Renderer - -Owns: - -- CLI-facing terminal writes and exit behavior; -- JSON/text rendering policy for CLI-level errors; -- support for in-process result capture via testkit. - -## Docs Architecture - -The docs system should follow the split recommended in `ROADMAP-DOCS-SICK.md`: - -```txt -scripts/docs/ - build-docs-data.ts - extract-examples.ts - extract-changelog.ts - extract-health.ts - extract-api.ts - normalize-typedoc.ts - shared/ - -docs/ - .generated/ - examples/ - reference/ - api/ - examples/ - reference/ - .vitepress/ -``` - -Rules: - -- generated artifacts live under `docs/.generated/`; -- handwritten docs stay outside `.generated/`; -- `docs:prepare` runs before `docs:dev` and `docs:build`; -- generated docs are reproducible build outputs, not hand-maintained content. - -## Deliverables - -| ID | Deliverable | Effort | Depends On | -| -- | ----------------------------------------------------------------------------------------------------- | ------ | ---------- | -| D1 | Product truth matrix and semantic baseline | M | - | -| D2 | Characterization test net for planner, resolver, executor, output, and completions | L | D1 | -| D3 | Shared execution contracts plus new `core/execution` seam | L | D2 | -| D4 | CLI planner extraction and runtime-preflight split | L | D3 | -| D5 | Resolver decomposition and selective redesign | XL | D2, D3 | -| D6 | Output cleanup and full shell completion support | L | D3, D4 | -| D7 | Docs generation foundation (`docs:prepare`, generated artifacts, IA changes) | L | D1, D3 | -| D8 | Generated examples, Twoslash hover, changelog, docs health, API index, TypeDoc pipeline, symbol pages | XL | D6, D7 | -| D9 | Narrative docs, migration/troubleshooting/limitations/rationale, CI hardening | L | D5, D6, D8 | - -## Detailed Deliverables - -### D1: Product truth matrix and semantic baseline - -Purpose: - -- make current claims explicit; -- decide what is supported, deferred, experimental, or being redesigned; -- define what behavior is intentionally preserved versus intentionally changed. - -Outputs: - -- support matrix for major features; -- semantic baseline for planner, resolver, executor, output, completions, and runtime behavior; -- list of current docs claims to keep, revise, or delete. - -Likely files touched: - -- new internal truth artifact under `scripts/` or `docs/.generated/`; -- docs pages that currently overstate or understate support; -- completion and runtime docs. - -Acceptance criteria: - -- every marketed feature has a declared status; -- shell completion support is explicitly scoped and no longer ambiguous; -- known intentional redesign items are listed before code movement begins. - -### D2: Characterization test net - -Purpose: - -- make refactor safety depend on explicit behavior, not intuition or line coverage. - -Must lock down: - -- dispatch semantics; -- root help/version/default-command behavior; -- propagated-flag masking; -- parser plus planner extraction order for `--json`, `--config`, `--help`, `--version`; -- resolver precedence and prompt/stdin gating; -- lifecycle hook order; -- output and activity behavior; -- completion behavior across all supported shells. - -Likely files touched: - -- `src/core/cli/*.test.ts`; -- `src/core/resolve/*.test.ts`; -- `src/core/testkit/*.test.ts`; -- `src/core/output/*.test.ts`; -- `src/core/completion/*.test.ts`. - -Acceptance criteria: - -- planner, resolver, executor, and output each have black-box contract suites; -- there is at least one kitchen-sink test per cross-cutting concern cluster; -- tests distinguish preserved semantics from intended redesigns. - -### D3: Shared execution contracts plus `core/execution` - -Purpose: - -- establish one canonical execution engine. - -Required shape: - -- new internal module owns parse -> resolve -> hooks -> derive/middleware -> action -> result; -- testkit calls that module; -- CLI calls that module through planned invocation state; -- result shaping is not duplicated across CLI and testkit. - -Likely files touched: - -- new `src/core/execution/*`; -- `src/core/testkit/index.ts`; -- `src/core/schema/run.ts`; -- `src/core/schema/command.ts`; -- `src/core/cli/index.ts`. - -Acceptance criteria: - -- testkit is no longer the hidden execution owner; -- CLI and testkit use the same execution path for command invocation; -- `RunResult` ownership is clearer and no longer reconstructed in multiple places. - -### D4: CLI planner extraction and runtime-preflight split - -Purpose: - -- make CLI code explicitly about runtime preflight, planning, and rendering, not hidden execution. - -Sub-deliveries: - -- extract runtime sourcing from planner logic; -- extract planner outcomes into an explicit discriminated union; -- keep dispatch and propagation logic pure where possible; -- reduce `cli/index.ts` to orchestration, not mixed concern ownership. - -Likely files touched: - -- `src/core/cli/index.ts`; -- `src/core/cli/dispatch.ts`; -- `src/core/cli/propagate.ts`; -- `src/core/cli/root-help.ts`; -- possible new planner module(s). - -Acceptance criteria: - -- invocation planning can be tested without running handlers; -- runtime preflight and planner are separate concerns; -- `eraseCommand()` ownership is clearer and documented. - -### D5: Resolver decomposition and selective redesign - -Purpose: - -- make resolution semantics composable, inspectable, and easier to evolve. - -Required work: - -- split `resolve/index.ts` by concern, not by arbitrary line count; -- separate flag resolution orchestration, arg resolution orchestration, coercion helpers, - config/source lookup, and error aggregation; -- decide and implement deliberate semantic upgrades. - -Expected redesign targets: - -- source-aware multi-error diagnostics; -- consistent aggregation strategy for flags and args; -- shared property-schema machinery where it genuinely reduces drift; -- tighter contract between interactive resolution and prompt fallback. - -Likely files touched: - -- new `src/core/resolve/*` modules; -- `src/core/schema/flag.ts` and `arg.ts` only if needed for cleaner shared contracts; -- relevant tests. - -Acceptance criteria: - -- resolver no longer mixes every concern in one file; -- redesigned semantics are explicit in changelog/docs and tests; -- no intended behavior change is accidental or hidden. - -### D6: Output cleanup and full shell completion support - -Purpose: - -- make output policy easier to reason about; -- make completion support breadth match product claims. - -Required work: - -- split output policy choice from rendering implementation; -- make activity semantics explicit and testable; -- implement real fish completion support; -- implement real PowerShell completion support; -- ensure docs and types match shipped support. - -Likely files touched: - -- `src/core/output/index.ts`; -- `src/core/output/activity.ts`; -- `src/core/completion/index.ts`; -- `src/core/completion/shells/*`; -- completion docs/tests. - -Acceptance criteria: - -- fish and PowerShell generators exist and are covered; -- no shell in the public support surface throws as a placeholder; -- output policy is no longer entangled with every concrete output path. - -### D7: Docs generation foundation - -Purpose: - -- create the boring, durable build architecture for generated docs. - -Required work: - -- add `docs:prepare` pipeline; -- wire it into `docs:dev` and `docs:build`; -- generate under `docs/.generated/`; -- update docs IA and nav to include Examples and generated Reference surfaces. - -Likely files touched: - -- `scripts/docs/*`; -- `package.json`; -- `docs/.vitepress/config.ts`; -- `docs/.generated/*` scaffolding. - -Acceptance criteria: - -- generated artifacts are reproducible; -- handwritten and generated content boundaries are crisp; -- build flow supports later examples/reference/health work without further architectural churn. - -### D8: Generated examples, hover, changelog, docs health, API index, symbol pages - -Purpose: - -- turn docs into a source-backed product surface. - -Sub-phases: - -1. generated examples index and one page per example; -2. Twoslash hover on example pages only; -3. changelog page generated from `CHANGELOG.md`; -4. docs health page with factual metrics; -5. generated API symbol inventory from public entrypoints; -6. TypeDoc JSON generation plus normalization; -7. full per-symbol pages. - -Required example-page contents: - -- title and summary; -- what the example demonstrates; -- usage lines; -- full source with hover-enabled TypeScript fence; -- related guide pages; -- related API symbols; -- source file path. - -Required docs-health metrics in v1: - -- total docs pages; -- total generated example pages; -- public API symbol count; -- symbols with summary docs; -- symbols with full signature pages; -- pages missing descriptions; -- broken internal links; -- extraction warnings; -- generation timestamp. - -Likely files touched: - -- `scripts/docs/*`; -- `docs/.generated/examples/*`; -- `docs/.generated/reference/*`; -- `docs/.generated/api/*`; -- `docs/examples/*` and `docs/reference/*` wrappers; -- VitePress theme only if default Twoslash behavior needs light polish. - -Acceptance criteria: - -- adding an example file automatically yields a docs page; -- hover works on example pages against local DreamCLI source; -- changelog is browsable from docs; -- docs health is factual, not gamified; -- every public export appears in the API index; -- per-symbol pages are stable and linkable. - -### D9: Narrative docs and CI hardening - -Purpose: - -- publish the stronger product story only after semantics and generated surfaces stabilize. - -Required narrative docs: - -- rationale / decisions page; -- known limitations and workarounds; -- troubleshooting; -- migration/adoption guidance; -- side-by-side comparison on a realistic scenario; -- feature decision trees where needed, especially derive vs middleware vs interactive. - -Required CI hardening: - -- real coverage command; -- coverage thresholds; -- docs build verification; -- docs-prepare verification; -- clearer runtime/platform checks where practical. - -Likely files touched: - -- `docs/guide/*`; -- `docs/concepts/*`; -- `README.md`; -- `package.json`; -- `vitest.config.ts`; -- `.github/workflows/ci.yml`. - -Acceptance criteria: - -- docs tell a coherent story about what DreamCLI is, when to use it, and where its edges are; -- CI protects the new architecture and docs surfaces from silent regression; -- evaluator-facing gaps around rationale, limitations, and adoption path are concretely closed. - -## Rollout Order - -The order is intentional. - -```txt -D1 truth matrix - -> D2 characterization tests - -> D3 shared executor - -> D4 planner split - -> D5 resolver redesign - -> D6 output + completions - -> D7 docs foundation - -> D8 generated docs + hover + reference - -> D9 narrative docs + CI hardening -``` - -Notes: - -- D7 can begin once D1 and D3 are stable enough, but should stay on foundation work, not semantics- - sensitive prose. -- D8 can start incrementally, but API pages and cross-linking should wait for D6 and D7. -- D9 intentionally comes last because docs truth should follow stabilized semantics, not guess them. - -## Test Strategy - -| Layer | Focus | Requirements | -| ----------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------- | -| Contract | planner, resolver, executor, output, completion contracts | black-box suites for each explicit stage | -| Integration | cross-stage semantics | kitchen-sink commands covering dispatch, resolution, hooks, output, and completions | -| End-to-end | user-visible behavior | help/version/default command, JSON mode, nested commands, generated completions | -| Platform | runtime and shell support | Node, Bun, Deno, plus shell-specific validation for bash, zsh, fish, PowerShell | -| Docs truth | docs claims backed by proof | support matrix entries point to tests/examples/generated artifacts | - -### Mandatory characterization suites before major movement - -- planner outcomes independent of handler execution; -- extraction ordering for `--json`, `--config`, `--help`, `--version`; -- precedence matrices for flags and args; -- prompt gating under TTY, non-TTY, and stdin-backed paths; -- lifecycle hook ordering; -- output policy behavior across `jsonMode`, `isTTY`, and `verbosity`; -- propagated-flag masking across planning, help, and completions; -- shell completion output per supported shell. - -## Documentation Strategy - -### Safe to build early - -- docs IA changes; -- generated examples foundation; -- changelog surfacing; -- docs health foundation; -- generated API inventory foundation; -- frontmatter and searchability improvements; -- cross-link plumbing. - -### Must wait for semantic stabilization - -- migration guides; -- troubleshooting; -- limitations/workarounds; -- decisions/rationale pages that explain settled architecture; -- strong “why switch” positioning claims; -- final example-to-symbol and hover-to-symbol cross-link semantics. - -## Data Model Additions - -These shapes are illustrative targets, not exact exported names. - -### Example docs model - -```ts -interface ExampleDoc { - readonly slug: string; - readonly title: string; - readonly summary: string; - readonly demonstrates: readonly string[]; - readonly usage: readonly string[]; - readonly importedSymbols: readonly string[]; - readonly sourceText: string; - readonly sourcePath: string; - readonly relatedGuides: readonly string[]; - readonly relatedSymbols: readonly string[]; -} -``` - -### API symbol inventory model - -```ts -interface ApiSymbolDoc { - readonly id: string; - readonly subpath: '.' | './testkit' | './runtime'; - readonly name: string; - readonly kind: string; - readonly summary: string | undefined; - readonly sourceFile: string; - readonly deprecated: boolean; - readonly examples: readonly string[]; -} -``` - -### Docs health model - -```ts -interface DocsHealthReport { - readonly generatedAt: string; - readonly totalPages: number; - readonly generatedExamplePages: number; - readonly publicSymbolCount: number; - readonly symbolsWithSummary: number; - readonly symbolsWithSignaturePages: number; - readonly pagesMissingDescriptions: readonly string[]; - readonly brokenInternalLinks: readonly string[]; - readonly extractionWarnings: readonly string[]; -} -``` - -## Trade-offs Made - -| Chose | Over | Because | -| ---------------------------- | ----------------------------- | ----------------------------------------------------------- | -| shared executor | testkit-owned execution | explicit ownership is more valuable than hidden convenience | -| staged re-foundation | big-bang rewrite | behavior must stay inspectable while code moves | -| selective redesign | strict semantic freeze | some pain is semantic, not only structural | -| TypeDoc + normalization | custom extractor first | compiler-shape problems should be outsourced early | -| hover on examples only | hover everywhere | examples are high-ROI and lower-noise | -| build-time generated docs | dynamic runtime docs logic | simpler, calmer, more reproducible | -| real fish/PowerShell support | narrowing the support surface | the product goal here is broader truth-backed capability | - -## Risks And Mitigations - -| Risk | Likelihood | Impact | Mitigation | -| -------------------------------------------------- | ---------- | ------ | -------------------------------------------------------------------------------- | -| cleanup changes behavior accidentally | High | High | D1 truth matrix plus D2 characterization suites before movement | -| shared executor becomes an abstraction blob | Medium | High | keep planner and renderer outside; keep executor contract narrow | -| resolver redesign expands without bound | High | High | separate structural extraction from explicit semantic changes | -| completion breadth steals focus | Medium | Medium | do completions after planner and executor contracts stabilize | -| generated docs become a second product to maintain | Medium | Medium | strict extraction/render split; build-time only; human prose remains human | -| hover becomes noisy | Medium | Medium | examples-only first; default Twoslash UI first; no hover-dependent comprehension | -| TypeDoc model gaps block reference work | Medium | Medium | normalize data and start with API inventory before full symbol pages | -| CI hardening lands too early and slows refactor | Medium | Medium | add gates after major architectural churn settles | - -## Success Metrics - -### Architecture - -- one shared executor owns command execution; -- planner, resolver, executor, and renderer each have explicit contracts and dedicated tests; -- `cli/index.ts`, `testkit/index.ts`, and `resolve/*` each have materially clearer ownership. - -### Product truth - -- every major support claim has a status and evidence path; -- shell completion support is fully implemented across bash, zsh, fish, and PowerShell; -- docs no longer overstate unsupported capability. - -### Docs - -- examples are discoverable from nav and search; -- changelog is visible inside docs; -- docs health is public and factual; -- every public export appears in a generated API index; -- example-page hover is stable, useful, and calm. - -### Adoption - -- docs answer who DreamCLI is for, when not to use it, and how to evaluate or adopt it; -- derive vs middleware vs interactive is documented with concrete decision guidance; -- the framework feels like a coherent product, not a set of clever internals. - -## Definition of Done - -This re-foundation is done when: - -1. the execution path has one clear owner and one clear stage model; -2. selective semantic changes are intentional, documented, and regression-tested; -3. completion support is real across all claimed shells; -4. docs derive structured surfaces from code, examples, and changelog; -5. examples, reference, changelog, and docs health form one coherent docs system; -6. narrative docs explain not just what DreamCLI does, but why it is designed this way and where - its boundaries are; -7. CI protects both the architecture and the docs platform from drift. - -## Open Questions - -None. Major scope decisions are resolved in this spec. - -## First Breakdown Target - -If this spec is converted into concrete tasks, the first breakdown should be: - -1. D1 truth matrix and semantic baseline. -2. D2 characterization suites. -3. D3 shared executor seam. - -Everything else depends on those being real, not assumed. From 7f9d07093c283a55ec4aa6f2cdb0b64c7c282a22 Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Wed, 8 Apr 2026 02:14:09 +0200 Subject: [PATCH 07/21] chore: polish docs site, trim goals, modernize scripts Rework SettingsGear (gear animation, compact toggles), extract custom.css, add JSR/npm social links and hero gradient. Condense GOALS.md from verbose PRD to focused goals. Replace release-meta.sh with TS, relocate gh-project script, add check/typecheck/test:bun scripts, use --cwd for docs commands. Update schema and deps. --- .dprint.jsonc | 2 +- .github/workflows/publish-jsr.yml | 2 +- .github/workflows/publish-npm.yml | 2 +- DISCOVERIES.md | 1 - GOALS.md | 489 +++----------- apps/docs/.vitepress/config.ts | 24 +- .../.vitepress/data/docs-contract.test.ts | 2 +- apps/docs/.vitepress/data/examples.ts | 9 +- .../theme/components/SettingsGear.vue | 190 ++++-- apps/docs/.vitepress/theme/components/jsr.svg | 10 + .../theme/composables/use-doc-settings.ts | 6 +- apps/docs/.vitepress/theme/custom.css | 36 + apps/docs/.vitepress/theme/index.ts | 1 + apps/docs/examples/[slug].paths.ts | 7 +- apps/docs/examples/examples.data.ts | 7 +- apps/docs/index.md | 34 +- apps/docs/package.json | 15 +- apps/docs/public/manifest.json | 2 +- apps/docs/reference/api.data.ts | 6 +- apps/docs/tsconfig.json | 7 +- apps/docs/vitest.config.ts | 12 - bun.lock | 65 ++ examples/gh/package.json | 5 +- examples/gh/tsconfig.json | 8 +- examples/standalone/package.json | 8 + package.json | 20 +- packages/dreamcli/dreamcli.schema.json | 624 ++++++++++-------- scripts/build-meta-descriptions.ts | 9 +- scripts/gh-project.ts | 13 - scripts/release-meta.sh | 119 ---- scripts/release-meta.ts | 85 +++ tools/gh-project/package.json | 4 +- 32 files changed, 869 insertions(+), 955 deletions(-) create mode 100644 apps/docs/.vitepress/theme/components/jsr.svg create mode 100644 apps/docs/.vitepress/theme/custom.css delete mode 100755 scripts/gh-project.ts delete mode 100755 scripts/release-meta.sh create mode 100755 scripts/release-meta.ts diff --git a/.dprint.jsonc b/.dprint.jsonc index fab85166..061cb75d 100644 --- a/.dprint.jsonc +++ b/.dprint.jsonc @@ -49,7 +49,7 @@ "endOfLine": "lf", "associations": ["**/README.md", "**/docs/**/*.md", "**/.vitepress/twoslash/*.ts"] }, - "excludes": ["**/node_modules", "**/{*-,bun}lock(.*)?", "**/snapshots"], + "excludes": ["**/node_modules", "**/{*-,bun}lock(.*)?", "**/snapshots", "**/*.schema.json"], "plugins": [ "https://plugins.dprint.dev/biome-0.12.6.wasm", "https://plugins.dprint.dev/g-plane/malva-v0.15.2.wasm", diff --git a/.github/workflows/publish-jsr.yml b/.github/workflows/publish-jsr.yml index 00fc3c0f..f6143bc0 100644 --- a/.github/workflows/publish-jsr.yml +++ b/.github/workflows/publish-jsr.yml @@ -14,7 +14,7 @@ jobs: - name: Resolve metadata and validate release tag id: version env: { RELEASE_TAG: "${{ github.event.release.tag_name }}" } - run: bash scripts/release-meta.sh jsr + run: node scripts/release-meta.ts jsr publish: name: Publish diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index ad72164a..93b1cb11 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -14,7 +14,7 @@ jobs: - name: Resolve metadata and validate release tag id: version env: { RELEASE_TAG: "${{ github.event.release.tag_name }}" } - run: bash scripts/release-meta.sh npm + run: node scripts/release-meta.ts npm build: name: Build diff --git a/DISCOVERIES.md b/DISCOVERIES.md index 68f8f2e0..c2f97e95 100644 --- a/DISCOVERIES.md +++ b/DISCOVERIES.md @@ -31,7 +31,6 @@ ### dreamcli-re-foundation project commands - Use GitHub Project `4`. -- Use `scripts/gh-project.ts` instead of ad hoc `gh project` calls. It is Bun-native, uses DreamCLI for the command surface, reads `.opencode/state/dreamcli-re-foundation/prd.json`, and batches project metadata fetches once per invocation. - The visible board state on GitHub is driven by built-in `Status`, not the custom `Workflow` field. The helper must update both. Workflow keeps `Backlog/Ready/Blocked` detail; Status is the coarse mirror the board actually shows: `Backlog|Ready -> Todo`, `In Progress|Blocked -> In Progress`, `Done -> Done`. - Exact commands future agents should use: diff --git a/GOALS.md b/GOALS.md index dfba1fa3..66e7d020 100644 --- a/GOALS.md +++ b/GOALS.md @@ -1,118 +1,45 @@ -# PRD — DreamCLI: A Schema-First, Fully Typed TypeScript CLI Framework (Node + Bun + Deno) - -> ## Intro -> -> Today’s TypeScript CLI tooling mostly treats the type system like decoration: you define -> flags/args in one place, then you _use_ parsed values somewhere else as a loosely typed blob. On -> top of that, interactive prompting lives in a separate universe from parsing, config/env/CLI -> merging gets re-invented per project, testing tends to be gross (`process.argv` hacks or shelling -> out), completions are bolted on, and output/error handling is inconsistent and hard to make both -> human-friendly _and_ script-friendly. +# Goals + +> Today's TypeScript CLI tooling mostly treats the type system like decoration: you define flags/args +> in one place, then you _use_ parsed values somewhere else as a loosely typed blob. Interactive +> prompting lives in a separate universe from parsing, config/env/CLI merging gets re-invented per +> project, testing tends to be gross (`process.argv` hacks or shelling out), completions are bolted +> on, and output/error handling is inconsistent and hard to make both human-friendly _and_ +> script-friendly. > -> The proposed fix is “Zod, but for CLIs”: a schema-first builder where the schema is the single -> source of truth and everything (types, parsing, help text, resolution from -> env/config/prompts/defaults, completions, testing, structured output/errors, middleware context) -> flows from it—while staying runtime-agnostic across Node/Bun/Deno via a thin adapter layer. - -### 1) Product vision +> DreamCLI is "Zod, but for CLIs": a schema-first builder where the schema is the single source of +> truth and everything—types, parsing, help text, resolution from env/config/prompts/defaults, +> completions, testing, structured output/errors, middleware context—flows from it. Runtime-agnostic +> across Node, Bun, and Deno via a thin adapter layer. Zero runtime dependencies. -Build the CLI framework that TypeScript developers _wish_ existed: define commands/flags/args once, -get perfect inference everywhere, and have the runtime do the boring-but-hard stuff (resolution -chain, prompts, config, completions, testing, structured output, errors) reliably and portably -across Node/Bun/Deno. +--- -The guiding mantra: +## The mantra **Single source of truth → full type inference → guaranteed resolution → testable without the process → great UX by default.** --- -### 2) Problem statement - -Modern TS CLI frameworks typically fail at the exact thing TypeScript is for: keeping definitions -and usage in sync. +## What we're solving -**Key gaps in the ecosystem:** +Modern TS CLI frameworks typically fail at the exact thing TypeScript is for: keeping definitions and +usage in sync. -- **Type disconnect:** CLI schema definition doesn’t strongly type the parsed result used in +- **Type disconnect.** CLI schema definition doesn't strongly type the parsed result used in handlers. -- **Interactive prompting is duct-tape:** prompts are separate from parsing; developers manually +- **Interactive prompting is duct-tape.** Prompts are separate from parsing; developers manually prompt based on missing flags. -- **Resolution chain is ad-hoc:** merging CLI args + env vars + config + defaults is repeated per +- **Resolution chain is ad-hoc.** Merging CLI args + env vars + config + defaults is repeated per project with slightly different rules. -- **Testing is second-class:** command logic is entangled with `process.argv`, IO, and process - exits. -- **Completions are an afterthought:** added late, brittle, and rarely aligned with the true CLI +- **Testing is second-class.** Command logic is entangled with `process.argv`, IO, and process exits. +- **Completions are an afterthought.** Added late, brittle, and rarely aligned with the true CLI schema. -- **Output & errors are primitive:** hard to support both “nice TTY UX” and “machine output” - cleanly. - ---- - -### 3) Goals & success criteria - -#### Goals (what success looks like) - -1. **Perfect inference in handlers** If you define `.flag("region", enum(["us","eu"]))`, then - `flags.region` is `"us" | "eu"` in `.action()`. No manual interfaces, no generic gymnastics. - -2. **Guaranteed resolution before action** By the time `.action()` runs, every declared flag has a - final value from a documented chain: **CLI → env → config → prompt → default** (and required - values either resolve or produce a structured error). - -3. **Runtime-agnostic core** 95% portable core (parser/type engine/resolution/help/completions - generation), plus thin adapters for Node/Bun/Deno. - -4. **Test-first design** Commands run as pure-ish functions with injected runtime state: - `command.run(argv, { env, config, stdin, stdout, cwd })` - -5. **First-class UX** Beautiful help, sane errors with suggestions, consistent output behaviors, - built-in `--json` mode, and completions aligned to schema. - -#### Non-goals (explicitly not trying to be) - -- A full TUI framework (we’ll support prompts/spinners/tables, but not build a terminal UI empire). -- A build tool / bundler / packaging system (we integrate nicely, we don’t replace). -- A runtime abstraction layer for everything (only the small set of genuinely divergent edges). - -#### Success metrics - -- **DX metrics** - - - Time-to-first-working-command (TTFWC) for a new CLI: target < 10 minutes. - - Zero “define types twice” moments in standard usage. - - “Help text drift” becomes impossible (help is generated from schema). -- **Quality metrics** - - - 100% of parsing/resolution behavior is covered by deterministic tests (no `process.argv` - required). - - Compatibility test suite passes on Node LTS, Bun stable, and Deno stable. -- **Performance metrics** - - - Minimal cold-start overhead from the framework (avoid heavy deps, keep core lean and - tree-shakeable). +- **Output & errors are primitive.** Hard to support both "nice TTY UX" and "machine output" cleanly. --- -### 4) Target users & primary use cases - -#### Target users - -- TS developers building internal tools, devops CLIs, release utilities, codegen, scaffolding tools. -- OSS maintainers who want a serious CLI without inheriting a thousand dependencies and bad typing. -- Teams that need consistent config/env/CLI behaviors across multiple tools. - -#### Core use cases - -- Multi-command tools (`tool deploy`, `tool login`, `tool init`). -- “Hybrid” CLIs: accept flags, but fall back to interactive prompts for missing values. -- Tools that must run in CI (non-interactive) and on laptops (interactive). -- CLIs used both by humans and scripts (TTY pretty output vs JSON output). - ---- - -### 5) Product principles +## Principles 1. **Schema is the law.** Everything derives from it: parsing, types, resolution, help, completions. @@ -126,43 +53,61 @@ and usage in sync. 5. **Ergonomic, not clever.** When forced to choose, pick predictable DX over type-theory stunts. +6. **Zero runtime dependencies.** The core stays lean and tree-shakeable. No transitive dependency + supply-chain anxiety. + --- -### 6) Proposed API (developer-facing) +## What we promise -#### Basic example +### Perfect inference in handlers -```ts -import { arg, cli, command, flag } from '@kjanat/dreamcli'; +Define `.flag("region", enum(["us","eu"]))`, get `flags.region` typed as `"us" | "eu"` in +`.action()`. No manual interfaces, no generic gymnastics. No separate type declaration required for +typical usage—`.action()` types derive entirely from `.arg()` and `.flag()` definitions. +```ts const deploy = command('deploy') .description('Deploy to an environment') .arg('target', arg.string().describe('Deploy target')) .flag('force', flag.boolean().default(false).alias('f')) .flag('region', flag.enum(['us', 'eu', 'ap']).env('DEPLOY_REGION').config('deploy.region')) - .interactive(({ flags }) => ({ - region: !flags.region && { - type: 'select', - message: 'Select region', - options: ['us', 'eu', 'ap'], - }, - })) .middleware(authMiddleware) .action(async ({ args, flags, ctx, out }) => { // args.target: string // flags.force: boolean - // flags.region: "us" | "eu" | "ap" (guaranteed resolved) + // flags.region: "us" | "eu" | "ap" — guaranteed resolved + // ctx.user: User — typed from middleware out.log(`Deploying ${args.target} to ${flags.region}...`); }); -cli('mycli').version('1.0.0').command(deploy).run(); // reads argv/env from runtime adapter by default +cli('mycli').version('1.0.0').command(deploy).run(); ``` -#### Middleware with typed context propagation +### Guaranteed resolution before action -```ts -import { CLIError, middleware } from '@kjanat/dreamcli'; +By the time `.action()` runs, every declared flag has a final value from a documented chain:\ +**CLI → env → config → prompt → default.**\ +The handler never sees "maybe undefined." + +Each flag may declare any combination of sources. Resolution follows the chain in order. If a value +is required and not resolved: in interactive mode, prompt (if a prompt exists), else error. In +non-interactive mode (CI, piped), error with an actionable hint. + +### Prompting without spaghetti +Interactive prompting is declared as part of resolution, not bolted on with imperative "if missing +then prompt" logic. The prompt system receives partially resolved values (after CLI/env/config) and +returns a prompt schema for anything still missing. It's pluggable (custom renderer allowed), +portable (works across runtimes), and safe in non-interactive contexts (auto-disables; errors +instead of hanging). + +### Middleware with typed context + +Middleware composes cleanly and propagates typed context downstream. Auth checks, telemetry, logging, +feature flags—whatever you need before the handler runs—without turning into spaghetti: + +```ts const authMiddleware = middleware(async ({ next }) => { const user = await getUser(); if (!user) { @@ -172,307 +117,83 @@ const authMiddleware = middleware(async ({ next }) => { exitCode: 2, }); } - return next({ user }); // ctx.user becomes typed downstream }); ``` -#### Testability without touching process state - -```ts -const result = await deploy.run(['production', '--force'], { - env: { DEPLOY_REGION: 'eu' }, - config: { deploy: { region: 'us' } }, - stdin: 'tty', // or a stream - stdout: 'capture', -}); - -expect(result.exitCode).toBe(0); -expect(result.output.text).toContain('Deploying production to eu'); -``` - ---- - -### 7) Functional requirements - -#### FR1 — Command & schema builder - -- Support command trees: root CLI → commands → subcommands. -- Commands can define: - - - positional args: required/optional, variadic, typed parsing - - flags/options: boolean/string/number/enum/array/custom - - descriptions, examples, aliases, hidden/deprecated flags -- Handlers receive typed `args`, typed `flags`, typed `ctx`, typed `out`. - -**Acceptance:** no separate type declaration required for typical usage; `.action()` types derive -entirely from `.arg()`/`.flag()` definitions. - ---- - -#### FR2 — Unified resolution chain (guaranteed final values) - -Each flag may declare any of these sources: - -- CLI: `--region eu` -- ENV: `.env("DEPLOY_REGION")` -- Config: `.config("deploy.region")` -- Prompt: `.interactive(...)` or per-flag prompt definition -- Default: `.default("us")` - -Resolution order (default): **CLI → ENV → CONFIG → PROMPT → DEFAULT** - -Rules: - -- If a value is required and not resolved: - - - in interactive mode: prompt (if prompt exists) else error - - in non-interactive mode (CI/piped): error with actionable hint -- The action handler must never see “maybe unresolved” for declared flags unless explicitly opted - into. - -**Acceptance:** with a required `region` flag that has env/config/prompt/default, `.action()` always -sees a `region` value (or fails before handler). - ---- +### Errors that help -#### FR3 — Interactive prompting integrated into schema +Parse and validation errors include "did you mean" suggestions and point to the exact flag or arg. +Every framework error renders nicely in TTY (short message, suggestion, relevant help excerpt) and +emits machine-readable JSON in `--json` mode. All errors carry a stable `code`, an `exitCode`, and +optional structured `details`. -- `.interactive(resolver)` receives partially resolved values (after CLI/env/config). -- It returns a prompt schema for any missing values. -- Prompt system must be: +### Output that respects context - - pluggable (custom renderer allowed) - - portable (works across runtimes) - - safe in non-interactive contexts (auto-disable; errors instead) +Handlers receive an `out` object instead of encouraging raw `console.log`. One code path yields +correct output behavior across interactive use, piping, and CI: -**Acceptance:** developers do not write “if missing then prompt” imperative spaghetti; prompts are -declared as part of resolution. - ---- - -#### FR4 — Structured errors & help-aware failures - -Provide a base error type like `CLIError` with fields: - -- `message` (human) -- `code` (stable identifier) -- `exitCode` (defaults by category) -- `suggest` (one-liner hint) -- `details` (structured payload for JSON output) -- optional `cause` - -Behavior: - -- All framework errors render nicely in TTY: - - - short message - - suggestion(s) - - relevant help excerpt when appropriate -- In `--json` mode, errors emit machine-readable JSON to stdout/stderr (configurable). - -**Acceptance:** parse/validation errors include “did you mean” suggestions and point to the exact -flag/arg. - ---- - -#### FR5 — Output channel that respects context (TTY vs pipe, human vs machine) - -Handlers receive an `out` object instead of encouraging raw `console.log`. `out` supports: - -- `log/info/warn/error` -- `json(value)` (for scripting) -- `table(rows, columns)` (TTY pretty; JSON when piped or `--json`) -- `spinner/progress` that auto-disables when not TTY - -Defaults: - -- TTY → pretty -- piped → minimal + stable +- TTY → pretty, human-friendly +- Piped → minimal, stable - `--json` → structured output -**Acceptance:** one code path yields correct output behavior across interactive use, piping, and CI. - ---- - -#### FR6 — Shell completions generated from schema - -- Generate completion scripts for: bash, zsh, fish, PowerShell (initially at least bash + zsh). -- Completion generation uses the command tree and flag definitions. -- Provide commands like: +Tables, spinners, and progress bars auto-disable when they can't render. No "why is my CI log full +of ANSI garbage" moments. - - `mycli completions generate --shell zsh` - - `mycli completions install --shell zsh` -- Installation path logic is runtime-dependent → handled by adapter. +### Completions from the schema -**Acceptance:** completions reflect the same schema as parsing/help, with no duplicate definition. - ---- +Shell completions are generated from the command tree and flag definitions—the same source of truth +as parsing and help. No duplicate definition, no drift. Completions reflect the real CLI because they +_are_ the real CLI. -#### FR7 — Configuration support baked in (but optional) +### Config discovery baked in -- Config discovery (default): - - - explicit `--config path` - - then standard locations (XDG-style where possible) - - plus local project config (optional) -- Support at least JSON initially; YAML/TOML via optional peer deps or plugin hooks. - -**Acceptance:** `.config("deploy.region")` resolves reliably across runtimes, with documented search -order. - ---- +Flags can declare `.config("deploy.region")` and it just works: explicit `--config path`, then +standard locations (XDG-style), plus local project config. JSON built in; YAML/TOML via plugin +hooks. -#### FR8 — Runtime portability via adapters - -Core must not import runtime-specific modules directly. - -Define a minimal adapter interface: - -- argv/env access -- filesystem read (config, completions) -- path/home/config-dir resolution -- TTY detection -- spawning subprocesses (for advanced features) -- stdin/stdout streams - -Adapters: - -- `runtime/node.ts` -- `runtime/bun.ts` -- `runtime/deno.ts` -- `runtime/detect.ts` chooses default adapter at runtime - -**Acceptance:** same user-facing API works without change on Node/Bun/Deno. - ---- +### Testable without touching process state -### 8) Non-functional requirements +Commands run as pure-ish functions with injected runtime state. No `process.argv` hacks, no shelling +out, no mocking globals: -- **TypeScript ergonomics:** avoid type explosions that make TS slow or unreadable in editor hovers. -- **Small dependency footprint:** prefer zero-dep core; optional extras behind adapters/plugins. -- **Tree-shakeable ESM:** modern packaging with ESM-only exports and clear defaults. -- **Deterministic tests:** no reliance on wall-clock time, real filesystem, or actual TTY unless - explicitly integrated. - ---- +```ts +const result = await deploy.run(['production', '--force'], { + env: { DEPLOY_REGION: 'eu' }, + config: { deploy: { region: 'us' } }, +}); -### 9) System design overview - -#### High-level architecture - -```tree -dreamcli/ - core/ - schema/ # command/flag/arg builders - parse/ # argv tokenization + parsing - resolve/ # CLI/env/config/prompt/default pipeline - help/ # help text generator - completion/ # completion generator (scripts) - output/ # out channel + formatting - errors/ # structured errors - testkit/ # run() harness + capture utilities - runtime/ - adapter.ts # interface - detect.ts # chooses node/bun/deno - node.ts - bun.ts - deno.ts - index.ts # re-exports + default runtime binding +expect(result.exitCode).toBe(0); +expect(result.output.text).toContain('Deploying production to eu'); ``` -#### Execution pipeline (conceptual) +### Runtime portability -1. Build schema (commands/flags/args) -2. Parse argv tokens → typed-ish raw values -3. Resolve each flag: - - - cli → env → config → prompt → default - -4. Run middleware chain → produce typed ctx -5. Execute action handler with fully resolved values -6. Render output/errors according to mode (TTY/pipe/--json) -7. Return structured result (even when invoked via CLI entry) - ---- - -### 10) Packaging & distribution - -- Publish to **npm** (Node/Bun) with: - - - ESM build - - `exports` map with `types` -- Publish to **JSR** (Deno-first, also consumable elsewhere) for first-class TS consumption. -- Keep runtime adapters internal but tree-shakeable. +The core never imports runtime-specific modules directly. A thin adapter interface handles argv/env +access, filesystem reads, path resolution, TTY detection, subprocess spawning, and stdin/stdout +streams. Adapters for Node, Bun, and Deno. Same user-facing API, no code changes. --- -### 11) Release plan (milestones) - -**MVP (v0.1):** Schema builder, parsing, inference into `.action()`, auto-help, basic errors, -`command.run()` test harness. _(done)_ - -**v0.2:** Resolution chain (env/config/default), required handling, non-interactive behavior rules. -_(done)_ - -**v0.3:** Interactive prompting integration (portable prompt engine + pluggable renderer). _(done)_ - -**v0.4:** Middleware + typed context, structured output channel (`--json`, TTY detection, table). -_(done)_ - -**v0.5:** Completions generation (bash/zsh), runtime detection, Bun adapter. _(done)_ - -**v0.6:** Config file discovery + loading (XDG search paths, `--config` flag, JSON loader, plugin -hook for YAML/TOML). Extend `RuntimeAdapter` with filesystem/path primitives (`readFile`, `homedir`, -`configDir`). Add `flag.custom(parseFn)` and `.deprecated()` modifier with help/parse warnings. -_(done)_ - -**v0.7:** Subcommand nesting (command trees: root > group > leaf, nested help, nested completion, -nested dispatch in CLIBuilder). _(done)_ - -**v0.8:** Spinner/progress on Out (`out.spinner()`, `out.progress()`, auto-disable on `!isTTY`, -suppress in `--json` mode, testkit capture). - -**v0.9:** Deno adapter + cross-runtime CI (Deno-specific APIs, permission handling, cross-runtime -test matrix, adapter parity tests). JSR publishing. - -**v1.0:** Stability guarantees, plugin lifecycle hooks (`beforeParse`, `afterResolve`, -`beforeAction`, `afterAction`), public API audit, JSDoc coverage, README, compatibility matrix -locked. - ---- - -### 12) Risks & mitigations - -- **Type inference complexity (TS performance):** Keep inference “local” (accumulate schema types - incrementally), avoid mega-unions, provide escape hatches (`.cast()` or `.unsafe()` only when - necessary). - -- **Prompt portability:** Build a minimal prompt layer on standard streams; allow swapping in a - fancier renderer as an optional integration. - -- **Deno permissions & filesystem constraints:** Make config/completions opt-in when permissions - missing; fail with precise guidance. - -- **ESM-only ecosystem friction:** Provide clean ESM exports and document migration/interop patterns. +## Non-goals -- **Completions installation differences across shells/OS:** Treat install as “best effort”, with a - `generate` command always available and clear manual instructions. +- A full TUI framework. We support prompts, spinners, and tables—we don't build a terminal UI + empire. +- A build tool, bundler, or packaging system. We integrate nicely; we don't replace. +- A runtime abstraction layer for everything. Only the small set of genuinely divergent edges. --- -### 13) What makes this “awesome” (the differentiators) +## What makes this different DreamCLI wins by collapsing five separate toolchains into one coherent, typed system: -- schema-driven parsing **and** inference -- schema-driven prompts (no glue logic) -- schema-driven help **and** completions (no drift) -- schema-driven resolution chain (no bespoke config/env merging) -- test harness built in (no `process.argv` rituals) -- middleware-based composition with typed context (auth/telemetry/logging that doesn’t turn into +- Schema-driven parsing **and** inference +- Schema-driven prompts (no glue logic) +- Schema-driven help **and** completions (no drift) +- Schema-driven resolution chain (no bespoke config/env merging) +- Test harness built in (no `process.argv` rituals) +- Middleware-based composition with typed context (auth/telemetry/logging that doesn't turn into spaghetti) -If you build exactly this—and keep the dependency footprint sane—you end up with the CLI equivalent -of “the framework disappears and your app code is all that remains,” which is basically the highest -compliment developer tooling can get. +The framework disappears and your app code is all that remains. diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts index 097f183c..26fa8a63 100644 --- a/apps/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -4,8 +4,7 @@ import pkg from '@kjanat/dreamcli/package.json' with { type: 'json' }; import { transformerTwoslash } from '@shikijs/vitepress-twoslash'; import { ModuleDetectionKind, ModuleKind, ModuleResolutionKind } from 'typescript'; import { defineConfig } from 'vitepress'; -import pkgTsc from '../../../packages/dreamcli/tsconfig.json' with { type: 'json' }; -import baseTsc from '../../../tsconfig.json' with { type: 'json' }; +import jsr from '../../../packages/dreamcli/deno.json' with { type: 'json' }; import { collectPublicApiIndex } from './data/api-index.ts'; import { collectExampleMeta } from './data/examples.ts'; import { examplesRoot, packageJsonPath } from './data/paths.ts'; @@ -47,25 +46,24 @@ const isGithubActions = Boolean(env.GITHUB_ACTIONS); const compilerOptions = { baseUrl: packageRoot, - lib: baseTsc.compilerOptions?.lib ?? ['ESNext'], - paths: pkgTsc.compilerOptions?.paths ?? {}, + lib: ['ESNext'], moduleDetection: ModuleDetectionKind.Force, module: ModuleKind.ESNext, moduleResolution: ModuleResolutionKind.Bundler, - allowImportingTsExtensions: baseTsc.compilerOptions?.allowImportingTsExtensions, + allowImportingTsExtensions: true, noEmit: true, - resolveJsonModule: baseTsc.compilerOptions?.resolveJsonModule, - types: [...(pkgTsc.compilerOptions?.types ?? []), 'vitest/globals'], + resolveJsonModule: true, + types: ['bun', 'node', 'vue', 'vite/client', 'vitest/globals'], }; const links = { github: pkg.repository.url.replace(/^git[+]/, ''), - npm: 'https://www.npmjs.com/package/@kjanat/dreamcli', - jsr: 'https://jsr.io/@kjanat/dreamcli', + npm: `https://www.npmjs.com/package/${pkg.name}`, + jsr: `https://jsr.io/${pkg.name}`, } as const; export default defineConfig({ - title: pkg.name, + title: 'dreamcli', description: pkg.description, cleanUrls: true, base: isGithubActions ? '/dreamcli' : '/', @@ -229,7 +227,11 @@ export default defineConfig({ }, ], }, - socialLinks: [{ icon: 'github', link: links.github, ariaLabel: 'GitHub' }], + socialLinks: [ + { icon: 'github', link: links.github, ariaLabel: 'GitHub' }, + { icon: 'npm', link: `https://npm.im/${pkg.name}`, ariaLabel: 'NPM' }, + { icon: 'jsr', link: `https://jsr.io/${jsr.name}`, ariaLabel: 'JSR' }, + ], search: { provider: 'local' }, footer: { message: `Released under the ${pkg.license} License.`, diff --git a/apps/docs/.vitepress/data/docs-contract.test.ts b/apps/docs/.vitepress/data/docs-contract.test.ts index 7ab9e606..f2e3f574 100644 --- a/apps/docs/.vitepress/data/docs-contract.test.ts +++ b/apps/docs/.vitepress/data/docs-contract.test.ts @@ -3,8 +3,8 @@ */ import { readFile } from 'node:fs/promises'; +import { createTestPrompter, PROMPT_CANCEL, runCommand } from '@kjanat/dreamcli/testkit'; import { describe, expect, it } from 'vitest'; -import { createTestPrompter, PROMPT_CANCEL, runCommand } from '#dreamcli/testkit'; import { activityCmd, diff --git a/apps/docs/.vitepress/data/examples.ts b/apps/docs/.vitepress/data/examples.ts index 0d353cd0..67ea923f 100644 --- a/apps/docs/.vitepress/data/examples.ts +++ b/apps/docs/.vitepress/data/examples.ts @@ -10,8 +10,9 @@ import { basename, extname, join, relative } from 'node:path'; import { gitRef } from './paths.ts'; import { toSymbolPageRoute } from './symbol-pages.ts'; -const codeFence = '```'; -const codeSnippet = (content: string): string => `\`${content}\``; +const backTick = '`'; +const codeFence = `${backTick}${backTick}${backTick}`; +const codeSnippet = (content: string): string => `${backTick}${content}${backTick}`; export interface ExampleRelatedSymbol { entrypoint: string; @@ -94,9 +95,9 @@ export function renderExamplePage(example: ExampleEntry): string { const usageSection = example.usage.length === 0 ? ['No usage snippets declared in the example docblock.', ''] - : ['```bash', ...example.usage, '```', '']; + : [`${codeFence}bash`, ...example.usage, codeFence, '']; const symbolLinks = example.relatedSymbols.map( - (symbol) => `- [\`${symbol.name}\`](${symbol.href})`, + (symbol) => `- [${backTick}${symbol.name}${backTick}](${symbol.href})`, ); const relatedLinks = [ '- [Examples overview](/examples/)', diff --git a/apps/docs/.vitepress/theme/components/SettingsGear.vue b/apps/docs/.vitepress/theme/components/SettingsGear.vue index 229f0d30..74854452 100644 --- a/apps/docs/.vitepress/theme/components/SettingsGear.vue +++ b/apps/docs/.vitepress/theme/components/SettingsGear.vue @@ -147,25 +147,25 @@ data-settings-option @click="toggleTwoslash" > - Type hovers + Types -
- -
+ + + @@ -180,6 +180,16 @@ --s-radius-sm: 6px; --s-accent: var(--vp-c-brand-1); + /* gear animation */ + --s-hover-rotate: 30deg; + --s-hover-circle-scale: 1.2; + --s-open-rotate: 360deg; + --s-open-circle-scale: 0.8; + --s-open-duration: 0.5s; + --s-open-ease: cubic-bezier(0, 0.7, 0.3, 1); + --s-close-duration: 0.6s; + --s-close-ease: cubic-bezier(0.2, 0, 0, 1); + position: relative; display: flex; align-items: center; @@ -195,25 +205,55 @@ border: none; border-radius: var(--s-radius); background: transparent; - color: var(--vp-c-text-2); + color: var(--vp-c-text-1); cursor: pointer; - transition: - color var(--s-duration) var(--s-ease), - background-color var(--s-duration) var(--s-ease); + transition: color var(--s-duration) var(--s-ease); + } + + @media (min-width: 768px) { + .settings-gear-btn { + color: var(--vp-c-text-2); + } } .settings-gear-btn svg { + transition: transform var(--s-close-duration) var(--s-close-ease); + } + + .settings-gear-btn svg path { transition: transform var(--s-duration) var(--s-ease); + transform-origin: 12px 12px; + } + + .settings-gear-btn svg circle { + transition: transform var(--s-duration) var(--s-ease); + transform-origin: 12px 12px; + } + + .settings-gear-btn:hover svg path { + transform: rotate(var(--s-hover-rotate)); + } + + .settings-gear-btn:hover svg circle { + transform: scale(var(--s-hover-circle-scale)); } .settings-gear.open .settings-gear-btn svg { - transform: rotate(60deg); + transform: rotate(var(--s-open-rotate)); + transition: transform var(--s-open-duration) var(--s-open-ease); + } + + .settings-gear.open .settings-gear-btn svg circle { + transform: scale(var(--s-open-circle-scale)); + } + + .settings-gear.open .settings-gear-btn:hover svg path { + transform: rotate(calc(var(--s-hover-rotate) * -1)); } .settings-gear-btn:hover, .settings-gear.open .settings-gear-btn { color: var(--vp-c-text-1); - background: var(--vp-c-default-soft); } .settings-dropdown { @@ -222,36 +262,41 @@ right: 0; z-index: 100; display: flex; - flex-direction: column; - gap: 8px; - min-width: 170px; - padding: 8px; + align-items: center; + gap: 0; + padding: 4px; border: 1px solid var(--vp-c-border); - border-radius: 10px; + border-radius: 999px; background: var(--vp-c-bg-elv); - box-shadow: var(--vp-shadow-3); + backdrop-filter: blur(12px); + box-shadow: + 0 4px 24px rgba(0, 0, 0, 0.4), + 0 0 0 1px rgba(255, 255, 255, 0.03) inset; + white-space: nowrap; } - /* --- Toggle switch --- */ + /* --- Toggle --- */ .settings-toggle { display: flex; align-items: center; - justify-content: space-between; - width: 100%; - padding: 4px 6px; + gap: 6px; + padding: 6px 10px; border: none; - border-radius: var(--s-radius-sm); + border-radius: 999px; background: transparent; cursor: pointer; font: inherit; - font-size: 13px; - color: var(--vp-c-text-1); - text-align: left; - transition: background-color var(--s-duration) var(--s-ease); + font-size: 11px; + font-weight: 500; + color: var(--vp-c-text-2); + transition: + color var(--s-duration) var(--s-ease), + background-color var(--s-duration) var(--s-ease); } .settings-toggle:hover { + color: var(--vp-c-text-1); background: var(--vp-c-default-soft); } @@ -261,13 +306,17 @@ outline-offset: 2px; } + .toggle-label { + user-select: none; + } + .toggle-track { position: relative; - width: 32px; - height: 18px; - border-radius: 9px; + width: 28px; + height: 16px; + border-radius: 8px; background: var(--vp-c-default-soft); - transition: background-color var(--s-duration) var(--s-ease); + transition: background-color 0.3s var(--s-ease); flex-shrink: 0; } @@ -276,13 +325,13 @@ position: absolute; top: 2px; left: 2px; - width: 14px; - height: 14px; + width: 12px; + height: 12px; border-radius: 50%; background: var(--vp-c-text-3); transition: - transform var(--s-duration) var(--s-ease), - background-color var(--s-duration) var(--s-ease); + transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), + background-color 0.3s var(--s-ease); } .toggle-track.active { @@ -290,33 +339,33 @@ } .toggle-track.active::after { - transform: translateX(14px); + transform: translateX(12px); background: white; } - /* --- Segmented control --- */ + /* --- Divider --- */ - .runtime-options { - display: flex; - flex-direction: column; - gap: 2px; - padding: 3px; - border-radius: var(--s-radius); - background: var(--vp-c-default-soft); + .divider { + width: 1px; + height: 16px; + margin: 0 2px; + background: var(--vp-c-divider); + flex-shrink: 0; } + /* --- Runtime pills --- */ + .runtime-option { display: flex; align-items: center; justify-content: center; - width: 100%; - padding: 5px 8px; + padding: 6px 10px; border: none; - border-radius: var(--s-radius-sm); + border-radius: 999px; background: transparent; cursor: pointer; font: inherit; - font-size: 12px; + font-size: 11px; color: var(--vp-c-text-2); font-family: var(--vp-font-family-mono); transition: @@ -327,26 +376,35 @@ .runtime-option:hover { color: var(--vp-c-text-1); + background: var(--vp-c-default-soft); } .runtime-option.active { - background: var(--vp-c-bg-elv); - color: var(--vp-c-text-1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + background: var(--vp-c-brand-soft); + color: var(--s-accent); } /* --- Transition --- */ - .settings-dropdown-enter-active, + .settings-dropdown-enter-active { + transition: + opacity 0.25s cubic-bezier(0, 0, 0.2, 1), + transform 0.25s cubic-bezier(0, 0, 0.2, 1); + } + .settings-dropdown-leave-active { transition: - opacity var(--s-duration) var(--s-ease), - transform var(--s-duration) var(--s-ease); + opacity 0.15s var(--s-ease), + transform 0.15s var(--s-ease); + } + + .settings-dropdown-enter-from { + opacity: 0; + transform: translateY(-6px) scale(0.95); } - .settings-dropdown-enter-from, .settings-dropdown-leave-to { opacity: 0; - transform: translateY(-4px); + transform: translateY(-3px); } diff --git a/apps/docs/.vitepress/theme/components/jsr.svg b/apps/docs/.vitepress/theme/components/jsr.svg new file mode 100644 index 00000000..ff9850e3 --- /dev/null +++ b/apps/docs/.vitepress/theme/components/jsr.svg @@ -0,0 +1,10 @@ + + + + diff --git a/apps/docs/.vitepress/theme/composables/use-doc-settings.ts b/apps/docs/.vitepress/theme/composables/use-doc-settings.ts index c39b5e1f..ce11e7c2 100644 --- a/apps/docs/.vitepress/theme/composables/use-doc-settings.ts +++ b/apps/docs/.vitepress/theme/composables/use-doc-settings.ts @@ -7,9 +7,9 @@ import { ref, watch } from 'vue'; export const runtimes = [ - { value: 'npx tsx', label: 'npx tsx (Node)' }, - { value: 'bun', label: 'bun' }, - { value: 'deno run -A', label: 'deno run -A' }, + { value: 'npx tsx', label: 'npx tsx (Node)', short: 'tsx' }, + { value: 'bun', label: 'bun', short: 'bun' }, + { value: 'deno run -A', label: 'deno run -A', short: 'deno' }, ] as const; export type Runtime = (typeof runtimes)[number]['value']; diff --git a/apps/docs/.vitepress/theme/custom.css b/apps/docs/.vitepress/theme/custom.css new file mode 100644 index 00000000..3e255e03 --- /dev/null +++ b/apps/docs/.vitepress/theme/custom.css @@ -0,0 +1,36 @@ +:root { + --npm-color: #cb3837; + --github-color: #181717; + --jsr-color: oklch(78.9% 0.154 211.53); +} + +:root.dark { + --npm-color: #cb3837; + --github-color: #f0f0f0; + --jsr-color: #f7df1e; +} + +/* Prevents the user from dragging the image around. */ +.VPImage.image-src, +.VPImage.logo { + -webkit-user-drag: none; +} + +.VPSocialLink:hover .vpi-social-github, +.VPSocialLink:focus-visible .vpi-social-github { + color: var(--github-color); +} + +.VPSocialLink:hover .vpi-social-npm, +.VPSocialLink:focus-visible .vpi-social-npm { + color: var(--npm-color); +} + +.VPSocialLink:hover .vpi-social-jsr, +.VPSocialLink:focus-visible .vpi-social-jsr { + color: var(--jsr-color); +} + +.VPSocialLink [class^='vpi-social-'] { + transition: color 0.25s; +} diff --git a/apps/docs/.vitepress/theme/index.ts b/apps/docs/.vitepress/theme/index.ts index aa29dd35..7c8b0be0 100644 --- a/apps/docs/.vitepress/theme/index.ts +++ b/apps/docs/.vitepress/theme/index.ts @@ -10,6 +10,7 @@ import '@shikijs/vitepress-twoslash/style.css'; import 'virtual:shiki-class.css'; import './twoslash-mobile.css'; import './settings.css'; +import './custom.css'; import SettingsGear from './components/SettingsGear.vue'; import type { Runtime } from './composables/use-doc-settings.ts'; import { useDocSettings } from './composables/use-doc-settings.ts'; diff --git a/apps/docs/examples/[slug].paths.ts b/apps/docs/examples/[slug].paths.ts index 2aaa18e7..5adb821b 100644 --- a/apps/docs/examples/[slug].paths.ts +++ b/apps/docs/examples/[slug].paths.ts @@ -7,8 +7,11 @@ * @module */ -import { collectExamples, renderExamplePage } from '../.vitepress/data/examples.ts'; -import { examplesRoot, rootDirPath } from '../.vitepress/data/paths.ts'; +import { + collectExamples, + renderExamplePage, +} from '@kjanat/dreamcli-docs/vitepress/data/examples.ts'; +import { examplesRoot, rootDirPath } from '@kjanat/dreamcli-docs/vitepress/data/paths.ts'; export default { watch: ['../../examples/**/*.ts'], diff --git a/apps/docs/examples/examples.data.ts b/apps/docs/examples/examples.data.ts index 55b4c68a..f6888044 100644 --- a/apps/docs/examples/examples.data.ts +++ b/apps/docs/examples/examples.data.ts @@ -7,8 +7,11 @@ * @module */ -import { collectExamples, type ExampleEntry } from '../.vitepress/data/examples.ts'; -import { examplesRoot, rootDirPath } from '../.vitepress/data/paths.ts'; +import { + collectExamples, + type ExampleEntry, +} from '@kjanat/dreamcli-docs/vitepress/data/examples.ts'; +import { examplesRoot, rootDirPath } from '@kjanat/dreamcli-docs/vitepress/data/paths.ts'; export type ExampleIndexEntry = Pick< ExampleEntry, diff --git a/apps/docs/index.md b/apps/docs/index.md index 1a179246..f6a7d5a0 100644 --- a/apps/docs/index.md +++ b/apps/docs/index.md @@ -35,44 +35,46 @@ features: dark: /icons/resolution-chain-dark.svg height: 48 title: Resolution Chain - details: CLI → env → config → prompt → default. Every step opt-in. Every step preserves types. + details: CLI → env → config → prompt → default
Every step opt-in. Every step preserves types. - icon: light: /icons/test-harness-light.svg dark: /icons/test-harness-dark.svg height: 48 title: Built-in Test Harness - details: Run commands in-process with full control. No subprocesses, no process.argv mutation. + details: Run commands in-process with full control.
No subprocesses, no process.argv mutation. - icon: light: /icons/middleware-light.svg dark: /icons/middleware-dark.svg height: 48 title: Typed Middleware - details: Context accumulates through the middleware chain via type intersection. No manual interface merging. + details: Context accumulates through the middleware chain via type intersection.
No manual interface merging. - icon: light: /icons/zero-deps-light.svg dark: /icons/zero-deps-dark.svg height: 48 title: Zero Dependencies - details: Lean core with no runtime dependencies. ESM-only. Runs on Node, Bun, and Deno. + details: Lean core with no runtime dependencies.
ESM-only. Runs on Node, Bun, and Deno. - icon: light: /icons/structured-output-light.svg dark: /icons/structured-output-dark.svg height: 48 title: Structured Output - details: 'Spinners, progress bars, tables, JSON mode. Adapts automatically: TTY → pretty, piped → stable.' + details: 'Spinners, progress bars, tables, JSON mode. Adapts automatically:
TTY → pretty, piped → stable' --- diff --git a/apps/docs/package.json b/apps/docs/package.json index 6b4ab31a..70bd70e2 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -11,11 +11,18 @@ "imports": { "#dreamcli/testkit": "@kjanat/dreamcli/testkit" }, + "exports": { + "./*": "./*", + "./dist/*": "./.vitepress/dist/*", + "./vitepress/*": "./.vitepress/*" + }, "scripts": { "build": "bunx --bun vitepress@next build", "dev": "bunx --bun vitepress@next dev", "preview": "bunx --bun vitepress@next preview", - "test": "vitest run" + "test": "vitest run", + "typecheck": "tsgo --noEmit", + "typecheck:tsc": "tsc --noEmit" }, "dependencies": { "@kjanat/dreamcli": "workspace:*" @@ -24,12 +31,16 @@ "@shikijs/transformers": "catalog:", "@shikijs/vitepress-twoslash": "catalog:", "@types/bun": "catalog:", + "@types/node": "catalog:", + "@typescript/native-preview": "catalog:", "floating-vue": "catalog:", "mermaid": "catalog:", + "tsx": "catalog:", "typedoc": "catalog:", "typescript": "catalog:", "vite": "catalog:", "vitepress": "catalog:", - "vitest": "catalog:" + "vitest": "catalog:", + "vue": "catalog:" } } diff --git a/apps/docs/public/manifest.json b/apps/docs/public/manifest.json index c48e05b4..ee8073cc 100644 --- a/apps/docs/public/manifest.json +++ b/apps/docs/public/manifest.json @@ -1,5 +1,5 @@ { - "name": "@kjanat/dreamcli", + "name": "dreamcli", "short_name": "dreamcli", "description": "Schema-first, fully typed TypeScript CLI framework", "start_url": "/", diff --git a/apps/docs/reference/api.data.ts b/apps/docs/reference/api.data.ts index ad9a4cb7..3cd21158 100644 --- a/apps/docs/reference/api.data.ts +++ b/apps/docs/reference/api.data.ts @@ -7,9 +7,9 @@ * @module */ -import type { PublicApiEntrypoint } from '../.vitepress/data/api-index.ts'; -import { countPublicApiSymbols } from '../.vitepress/data/api-index.ts'; -import { loadReferenceModel } from '../.vitepress/data/reference-model.ts'; +import type { PublicApiEntrypoint } from '@kjanat/dreamcli-docs/vitepress/data/api-index.ts'; +import { countPublicApiSymbols } from '@kjanat/dreamcli-docs/vitepress/data/api-index.ts'; +import { loadReferenceModel } from '@kjanat/dreamcli-docs/vitepress/data/reference-model.ts'; export interface SymbolPageEntry { id: string; diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index 80d41dd4..a1c3a26d 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -1,9 +1,10 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "types": ["bun", "vite", "vitest"], + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "types": ["bun", "node", "vue", "vite/client", "vitest"], + "customConditions": ["bun"], "paths": { - "#dreamcli/testkit": ["../../packages/dreamcli/src/testkit.ts"], "@kjanat/dreamcli": ["../../packages/dreamcli/src/index.ts"], "@kjanat/dreamcli/runtime": ["../../packages/dreamcli/src/runtime.ts"], "@kjanat/dreamcli/testkit": ["../../packages/dreamcli/src/testkit.ts"], @@ -11,6 +12,6 @@ "@kjanat/dreamcli/package.json": ["../../packages/dreamcli/package.json"] } }, - "include": [".vitepress/**/*.ts", "**/*.ts"], + "include": ["**/*.ts", "**/*.vue"], "exclude": ["**/dist", "**/node_modules", "**/cache"] } diff --git a/apps/docs/vitest.config.ts b/apps/docs/vitest.config.ts index ea6bfdaa..5f92651c 100644 --- a/apps/docs/vitest.config.ts +++ b/apps/docs/vitest.config.ts @@ -1,18 +1,6 @@ -import { resolve } from 'node:path'; - import { defineConfig } from 'vitest/config'; -const packageSrc = resolve(import.meta.dirname, '../../packages/dreamcli/src'); - export default defineConfig({ - resolve: { - alias: { - '#dreamcli/testkit': `${packageSrc}/testkit.ts`, - '@kjanat/dreamcli/testkit': `${packageSrc}/testkit.ts`, - '@kjanat/dreamcli/runtime': `${packageSrc}/runtime.ts`, - '@kjanat/dreamcli': `${packageSrc}/index.ts`, - }, - }, test: { include: ['.vitepress/data/*.test.ts'], }, diff --git a/bun.lock b/bun.lock index a3c4f05c..19b796db 100644 --- a/bun.lock +++ b/bun.lock @@ -24,13 +24,17 @@ "@shikijs/transformers": "catalog:", "@shikijs/vitepress-twoslash": "catalog:", "@types/bun": "catalog:", + "@types/node": "catalog:", + "@typescript/native-preview": "catalog:", "floating-vue": "catalog:", "mermaid": "catalog:", + "tsx": "catalog:", "typedoc": "catalog:", "typescript": "catalog:", "vite": "catalog:", "vitepress": "catalog:", "vitest": "catalog:", + "vue": "catalog:", }, }, "examples/gh": { @@ -44,6 +48,7 @@ }, "devDependencies": { "@types/bun": "catalog:", + "@typescript/native-preview": "catalog:", "typescript": "catalog:", }, }, @@ -55,6 +60,7 @@ }, "devDependencies": { "@types/bun": "catalog:", + "@typescript/native-preview": "catalog:", "typescript": "catalog:", "vitest": "catalog:", }, @@ -91,6 +97,7 @@ }, "devDependencies": { "@types/bun": "catalog:", + "@typescript/native-preview": "catalog:", "typescript": "catalog:", }, }, @@ -115,11 +122,13 @@ "mermaid": "^11.14.0", "publint": "^0.3.18", "tsdown": "^0.21.7", + "tsx": "^4.21.0", "typedoc": "^0.28.18", "typescript": "^6.0.2", "vite": "^8.0.7", "vitepress": "^2.0.0-alpha.17", "vitest": "^4.1.2", + "vue": "^3.5.32", "wrangler": "^4.81.0", "yaml": "^2.8.3", }, @@ -1258,6 +1267,8 @@ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="], + "twoslash": ["twoslash@0.3.6", "", { "dependencies": { "@typescript/vfs": "^1.6.2", "twoslash-protocol": "0.3.6" }, "peerDependencies": { "typescript": "^5.5.0" } }, "sha512-VuI5OKl+MaUO9UIW3rXKoPgHI3X40ZgB/j12VY6h98Ae1mCBihjPvhOPeJWlxCYcmSbmeZt5ZKkK0dsVtp+6pA=="], "twoslash-protocol": ["twoslash-protocol@0.3.6", "", {}, "sha512-FHGsJ9Q+EsNr5bEbgG3hnbkvEBdW5STgPU824AHUjB4kw0Dn4p8tABT7Ncg1Ie6V0+mDg3Qpy41VafZXcQhWMA=="], @@ -1402,6 +1413,8 @@ "rolldown-plugin-dts/@babel/types": ["@babel/types@8.0.0-rc.3", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0-rc.3", "@babel/helper-validator-identifier": "^8.0.0-rc.3" } }, "sha512-mOm5ZrYmphGfqVWoH5YYMTITb3cDXsFgmvFlvkvWDMsR9X8RFnt7a0Wb6yNIdoFsiMO9WjYLq+U/FMtqIYAF8Q=="], + "tsx/esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], + "vite/rolldown": ["rolldown@1.0.0-rc.13", "", { "dependencies": { "@oxc-project/types": "=0.123.0", "@rolldown/pluginutils": "1.0.0-rc.13" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.13", "@rolldown/binding-darwin-arm64": "1.0.0-rc.13", "@rolldown/binding-darwin-x64": "1.0.0-rc.13", "@rolldown/binding-freebsd-x64": "1.0.0-rc.13", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.13", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.13", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.13", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.13", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.13", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.13", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.13" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-bvVj8YJmf0rq4pSFmH7laLa6pYrhghv3PRzrCdRAr23g66zOKVJ4wkvFtgohtPLWmthgg8/rkaqRHrpUEh0Zbw=="], "vitepress/@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], @@ -1426,6 +1439,58 @@ "rolldown-plugin-dts/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.3", "", {}, "sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA=="], + "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.7", "", { "os": "aix", "cpu": "ppc64" }, "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg=="], + + "tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.7", "", { "os": "android", "cpu": "arm" }, "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ=="], + + "tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.7", "", { "os": "android", "cpu": "arm64" }, "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ=="], + + "tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.7", "", { "os": "android", "cpu": "x64" }, "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg=="], + + "tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw=="], + + "tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ=="], + + "tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.7", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w=="], + + "tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.7", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ=="], + + "tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.7", "", { "os": "linux", "cpu": "arm" }, "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA=="], + + "tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A=="], + + "tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.7", "", { "os": "linux", "cpu": "ia32" }, "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg=="], + + "tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q=="], + + "tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw=="], + + "tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.7", "", { "os": "linux", "cpu": "ppc64" }, "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ=="], + + "tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ=="], + + "tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.7", "", { "os": "linux", "cpu": "s390x" }, "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw=="], + + "tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.7", "", { "os": "linux", "cpu": "x64" }, "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA=="], + + "tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w=="], + + "tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.7", "", { "os": "none", "cpu": "x64" }, "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw=="], + + "tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.7", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A=="], + + "tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.7", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg=="], + + "tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw=="], + + "tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.7", "", { "os": "sunos", "cpu": "x64" }, "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA=="], + + "tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA=="], + + "tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.7", "", { "os": "win32", "cpu": "ia32" }, "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw=="], + + "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="], + "vite/rolldown/@oxc-project/types": ["@oxc-project/types@0.123.0", "", {}, "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew=="], "vite/rolldown/@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.13", "", { "os": "android", "cpu": "arm64" }, "sha512-5ZiiecKH2DXAVJTNN13gNMUcCDg4Jy8ZjbXEsPnqa248wgOVeYRX0iqXXD5Jz4bI9BFHgKsI2qmyJynstbmr+g=="], diff --git a/examples/gh/package.json b/examples/gh/package.json index d720cf68..306e1aab 100644 --- a/examples/gh/package.json +++ b/examples/gh/package.json @@ -20,14 +20,17 @@ "scripts": { "bd": "bun run build", "build": "bun build src/main.ts --install --outdir=dist --format=esm --target=node --external @kjanat/dreamcli", + "start": "bun src/main.ts", "test": "bun test", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit", + "typecheck:tsc": "tsc --noEmit" }, "dependencies": { "@kjanat/dreamcli": "workspace:*" }, "devDependencies": { "@types/bun": "catalog:", + "@typescript/native-preview": "catalog:", "typescript": "catalog:" }, "packageManager": "bun@1.3.11", diff --git a/examples/gh/tsconfig.json b/examples/gh/tsconfig.json index 0268363a..f0b61795 100644 --- a/examples/gh/tsconfig.json +++ b/examples/gh/tsconfig.json @@ -1,11 +1,5 @@ { "extends": "../../tsconfig.json", - "compilerOptions": { - "paths": { - "@kjanat/dreamcli": ["../../packages/dreamcli/src/index.ts"], - "@kjanat/dreamcli/testkit": ["../../packages/dreamcli/src/testkit.ts"], - "@kjanat/dreamcli/runtime": ["../../packages/dreamcli/src/runtime.ts"] - } - }, + "compilerOptions": {}, "include": ["src"] } diff --git a/examples/standalone/package.json b/examples/standalone/package.json index de42864a..a73674bc 100644 --- a/examples/standalone/package.json +++ b/examples/standalone/package.json @@ -8,11 +8,19 @@ "directory": "examples/standalone" }, "type": "module", + "files": [ + "*.ts" + ], + "scripts": { + "typecheck": "tsgo --noEmit", + "typecheck:tsc": "tsc --noEmit" + }, "dependencies": { "@kjanat/dreamcli": "workspace:*" }, "devDependencies": { "@types/bun": "catalog:", + "@typescript/native-preview": "catalog:", "typescript": "catalog:", "vitest": "catalog:" } diff --git a/package.json b/package.json index 07454d1f..48e5acfd 100644 --- a/package.json +++ b/package.json @@ -12,16 +12,19 @@ "bd": "bun run --filter @kjanat/dreamcli bd", "build": "bun run --filter @kjanat/dreamcli build", "build:watch": "bun run --filter @kjanat/dreamcli build:watch", + "check": "biome check", + "check:fix": "biome check --fix", "ci": "bun run typecheck && bun run lint && bun run format:check && bun run meta-descriptions:check && bun run test && bun run docs:build && bun run build", "coverage": "bun run --filter @kjanat/dreamcli coverage", "dev": "bun run --filter @kjanat/dreamcli build:watch & bun run --filter @kjanat/dreamcli-docs dev & wait", - "docs:build": "bun run --filter @kjanat/dreamcli-docs build", - "docs:dev": "bun run --filter @kjanat/dreamcli-docs dev", - "docs:preview": "bun run --filter @kjanat/dreamcli-docs preview", + "docs:build": "bun --cwd=apps/docs run build", + "docs:dev": "bun --cwd=apps/docs run dev", + "docs:dev:tsx": "bun --cwd=apps/docs tsx node_modules/vitepress/bin/vitepress.js dev", + "docs:preview": "bun --cwd=apps/docs run preview", "fmt": "dprint fmt", "format": "dprint fmt", "format:check": "dprint check", - "gh-project": "bun scripts/gh-project.ts", + "gh-project": "bun --cwd=tools/gh-project start", "gh-project:finish": "bun gh-project finish", "gh-project:list": "bun gh-project list", "gh-project:set": "bun gh-project set", @@ -31,11 +34,12 @@ "lint": "biome lint", "lint:fix": "biome lint --fix", "meta-descriptions": "bun --bun scripts/build-meta-descriptions.ts", - "meta-descriptions:check": "bun --bun scripts/build-meta-descriptions.ts --check", + "meta-descriptions:check": "bun meta-descriptions --check", "test": "bun run --filter '*' test", + "test:bun": "bun test", "test:watch": "bun run --filter @kjanat/dreamcli test:watch", - "typecheck": "bun run --filter @kjanat/dreamcli typecheck && bun --cwd examples/gh typecheck", - "typecheck:tsc": "bun run --filter @kjanat/dreamcli typecheck:tsc", + "typecheck": "bun run --filter '*' typecheck", + "typecheck:tsc": "bun run --filter '*' typecheck:tsc", "upgrade": "bun update --latest && bun add -D vitepress@next" }, "overrides": { @@ -83,6 +87,8 @@ "typedoc": "^0.28.18", "typescript": "^6.0.2", "vite": "^8.0.7", + "tsx": "^4.21.0", + "vue": "^3.5.32", "vitepress": "^2.0.0-alpha.17", "vitest": "^4.1.2", "yaml": "^2.8.3", diff --git a/packages/dreamcli/dreamcli.schema.json b/packages/dreamcli/dreamcli.schema.json index c2b02b35..1fe399ef 100644 --- a/packages/dreamcli/dreamcli.schema.json +++ b/packages/dreamcli/dreamcli.schema.json @@ -1,290 +1,338 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://cdn.jsdelivr.net/npm/@kjanat/dreamcli/dreamcli.schema.json", - "title": "@kjanat/dreamcli definition schema", - "description": "Runtime descriptor for the CLI program.\n\nStores the program name, version, description, and registered commands.\\\nBuilt incrementally by CLIBuilder.", - "type": "object", - "additionalProperties": false, - "properties": { - "$schema": { - "const": "https://cdn.jsdelivr.net/npm/@kjanat/dreamcli/dreamcli.schema.json" - }, - "name": { - "type": "string", - "description": "Program name (used in help text, usage lines, and completion scripts)." - }, - "version": { - "type": "string", - "description": "Program version (shown by `--version`)." - }, - "description": { - "type": "string", - "description": "Program description (shown in root help)." - }, - "defaultCommand": { - "type": "string", - "description": "Default command dispatched when no subcommand matches.\n\nWhen set, the CLI root behaves like a hybrid command group: subcommands\ndispatch by name as usual, but empty argv or flags-only argv falls\nthrough to this command instead of showing root help.\n\nSet via the .default() builder method." - }, - "commands": { - "type": "array", - "items": { - "$ref": "#/$defs/command" - }, - "description": "Registered commands (type-erased for heterogeneous storage)." - } - }, - "required": ["$schema", "name", "commands"], - "$defs": { - "command": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "The command name (used for dispatch, e.g. `'deploy'`)." - }, - "description": { - "type": "string", - "description": "Human-readable description for help text." - }, - "aliases": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Alternative names for this command." - }, - "hidden": { - "const": true, - "description": "Whether this command is hidden from help listings." - }, - "examples": { - "type": "array", - "items": { - "$ref": "#/$defs/example" - }, - "description": "Usage examples for help text." - }, - "flags": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/flag" - }, - "description": "Named flag schemas, keyed by flag name." - }, - "args": { - "type": "array", - "items": { - "$ref": "#/$defs/arg" - }, - "description": "Ordered positional arg entries (name + schema)." - }, - "commands": { - "type": "array", - "items": { - "$ref": "#/$defs/command" - }, - "description": "Nested subcommand schemas (for help rendering and completion).\n\nPure data — no execution closures. Populated by `.command()` on\n`CommandBuilder`. Empty for leaf commands." - } - }, - "required": ["name", "flags", "args", "commands"], - "description": "Runtime descriptor produced by CommandBuilder.\n\nConsumers (parser, help generator, CLI dispatcher) read this to\nunderstand the command's shape — flags, args, aliases, subcommands,\nmiddleware, and interactive resolver." - }, - "flag": { - "type": "object", - "additionalProperties": false, - "properties": { - "kind": { - "enum": ["string", "number", "boolean", "enum", "array", "custom"], - "description": "What kind of value this flag accepts." - }, - "presence": { - "enum": ["optional", "required", "defaulted"], - "description": "Presence describes whether a flag value is guaranteed to exist when the\naction handler runs:\n\n- `'optional'` — not required; unresolved value follows the kind-specific\n optional fallback (`undefined` for most flags, `[]` for arrays)\n- `'required'` — must be supplied; error if missing\n- `'defaulted'` — always present (falls back to default value)" - }, - "defaultValue": { - "description": "Runtime default value (if any)." - }, - "aliases": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Short/long aliases (e.g. `[{ name: 'f', hidden: false }]` for `--force`)." - }, - "envVar": { - "type": "string", - "description": "Environment variable name for v0.2+ resolution." - }, - "configPath": { - "type": "string", - "description": "Dotted config path for v0.2+ resolution (e.g. `'deploy.region'`)." - }, - "description": { - "type": "string", - "description": "Human-readable description for help text." - }, - "enumValues": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Allowed literal values when `kind === 'enum'`." - }, - "elementSchema": { - "$ref": "#/$defs/flag", - "description": "Element schema when `kind === 'array'`." - }, - "prompt": { - "$ref": "#/$defs/prompt", - "description": "Interactive prompt configuration for v0.3+ resolution." - }, - "deprecated": { - "oneOf": [ - { - "type": "string" - }, - { - "const": true - } - ], - "description": "Deprecation marker.\n\n- `undefined` — not deprecated (default)\n- `true` — deprecated with no migration message\n- `string` — deprecated with a reason/migration message\n\nWhen a deprecated flag is used, a warning is emitted to stderr.\nHelp text shows `[deprecated]` or `[deprecated: ]`." - }, - "propagate": { - "const": true, - "description": "Whether this flag propagates to subcommands in nested command trees.\n\nWhen `true`, the flag is automatically available to all descendant\ncommands. A child command that defines a flag with the same name\nshadows the propagated parent flag." - } - }, - "required": ["kind", "presence"], - "description": "The runtime descriptor stored inside every FlagBuilder. Consumers (parser,\nhelp generator, resolution chain) read this to understand the flag's shape\nwithout touching generics." - }, - "arg": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "A named positional argument entry in the command schema.\n\nPairs a user-facing arg name with its ArgSchema descriptor.\nThe array ordering in CommandSchema.args determines CLI position." - }, - "kind": { - "enum": ["string", "number", "enum", "custom"], - "description": "What kind of value this arg accepts." - }, - "presence": { - "enum": ["required", "optional", "defaulted"], - "description": "Presence describes whether a positional arg is guaranteed to exist when the\naction handler runs:\n\n- `'required'` — must be supplied; error if missing (default)\n- `'optional'` — may be `undefined` if not supplied\n- `'defaulted'` — always present (falls back to default value)" - }, - "variadic": { - "const": true, - "description": "Whether this arg consumes all remaining positionals." - }, - "stdinMode": { - "const": true, - "description": "Whether this arg may read from stdin during resolution." - }, - "defaultValue": { - "description": "Runtime default value (if any)." - }, - "description": { - "type": "string", - "description": "Human-readable description for help text." - }, - "envVar": { - "type": "string", - "description": "Environment variable name for env resolution.\n\nWhen set and the CLI value is absent, the resolver reads this env var\nand coerces the string to the arg's declared kind." - }, - "enumValues": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Allowed literal values when `kind === 'enum'`." - }, - "deprecated": { - "oneOf": [ - { - "type": "string" - }, - { - "const": true - } - ], - "description": "Deprecation marker.\n\n- `undefined` — not deprecated (default)\n- `true` — deprecated with no migration message\n- `string` — deprecated with a reason/migration message\n\nWhen a deprecated arg is used, a warning is emitted to stderr.\nHelp text shows `[deprecated]` or `[deprecated: ]`." - } - }, - "required": ["name", "kind", "presence"], - "description": "The runtime descriptor stored inside every ArgBuilder. Consumers (parser,\nhelp generator) read this to understand the arg's shape without touching\ngenerics." - }, - "prompt": { - "type": "object", - "additionalProperties": false, - "properties": { - "kind": { - "enum": ["confirm", "input", "select", "multiselect"], - "description": "The kind of interactive prompt to present.\n\n- `'confirm'` — yes/no boolean question\n- `'input'` — free-text string input\n- `'select'` — single selection from a list\n- `'multiselect'` — multiple selections from a list" - }, - "message": { - "type": "string", - "description": "The question displayed to the user." - }, - "placeholder": { - "type": "string", - "description": "Placeholder text shown before user types (informational only)." - }, - "choices": { - "type": "array", - "items": { - "$ref": "#/$defs/choice" - }, - "description": "Available choices. When omitted for `enum` flags, the enum values\nfrom the flag schema are used automatically." - }, - "min": { - "type": "integer", - "description": "Minimum number of selections required." - }, - "max": { - "type": "integer", - "description": "Maximum number of selections allowed." - } - }, - "required": ["kind", "message"], - "description": "Discriminated union of all prompt configurations.\n\nUse the `kind` field to narrow:\n```ts\nif (config.kind === 'select') {\n config.choices // readonly SelectChoice[] | undefined\n}\n```" - }, - "choice": { - "type": "object", - "additionalProperties": false, - "properties": { - "value": { - "type": "string", - "description": "The value returned when this choice is selected." - }, - "label": { - "type": "string", - "description": "Display label shown to the user." - }, - "description": { - "type": "string", - "description": "Optional description shown alongside the choice." - } - }, - "required": ["value"], - "description": "A selectable option for SelectPromptConfig and MultiselectPromptConfig prompts." - }, - "example": { - "type": "object", - "additionalProperties": false, - "properties": { - "command": { - "type": "string", - "description": "The command invocation (e.g. `'deploy production --force'`)." - }, - "description": { - "type": "string", - "description": "Optional description of what this example does." - } - }, - "required": ["command"], - "description": "A single usage example shown in help text." - } - } + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cdn.jsdelivr.net/npm/@kjanat/dreamcli/dreamcli.schema.json", + "title": "@kjanat/dreamcli definition schema", + "description": "Runtime descriptor for the CLI program.\n\nStores the program name, version, description, and registered commands.\\\nBuilt incrementally by CLIBuilder.", + "type": "object", + "additionalProperties": false, + "properties": { + "$schema": { + "const": "https://cdn.jsdelivr.net/npm/@kjanat/dreamcli/dreamcli.schema.json" + }, + "name": { + "type": "string", + "description": "Program name (used in help text, usage lines, and completion scripts)." + }, + "version": { + "type": "string", + "description": "Program version (shown by `--version`)." + }, + "description": { + "type": "string", + "description": "Program description (shown in root help)." + }, + "defaultCommand": { + "type": "string", + "description": "Default command dispatched when no subcommand matches.\n\nWhen set, the CLI root behaves like a hybrid command group: subcommands\ndispatch by name as usual, but empty argv or flags-only argv falls\nthrough to this command instead of showing root help.\n\nSet via the .default() builder method." + }, + "commands": { + "type": "array", + "items": { + "$ref": "#/$defs/command" + }, + "description": "Registered commands (type-erased for heterogeneous storage)." + } + }, + "required": [ + "$schema", + "name", + "commands" + ], + "$defs": { + "command": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The command name (used for dispatch, e.g. `'deploy'`)." + }, + "description": { + "type": "string", + "description": "Human-readable description for help text." + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Alternative names for this command." + }, + "hidden": { + "const": true, + "description": "Whether this command is hidden from help listings." + }, + "examples": { + "type": "array", + "items": { + "$ref": "#/$defs/example" + }, + "description": "Usage examples for help text." + }, + "flags": { + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/flag" + }, + "description": "Named flag schemas, keyed by flag name." + }, + "args": { + "type": "array", + "items": { + "$ref": "#/$defs/arg" + }, + "description": "Ordered positional arg entries (name + schema)." + }, + "commands": { + "type": "array", + "items": { + "$ref": "#/$defs/command" + }, + "description": "Nested subcommand schemas (for help rendering and completion).\n\nPure data — no execution closures. Populated by `.command()` on\n`CommandBuilder`. Empty for leaf commands." + } + }, + "required": [ + "name", + "flags", + "args", + "commands" + ], + "description": "Runtime descriptor produced by CommandBuilder.\n\nConsumers (parser, help generator, CLI dispatcher) read this to\nunderstand the command's shape — flags, args, aliases, subcommands,\nmiddleware, and interactive resolver." + }, + "flag": { + "type": "object", + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "string", + "number", + "boolean", + "enum", + "array", + "custom" + ], + "description": "What kind of value this flag accepts." + }, + "presence": { + "enum": [ + "optional", + "required", + "defaulted" + ], + "description": "Presence describes whether a flag value is guaranteed to exist when the\naction handler runs:\n\n- `'optional'` — not required; unresolved value follows the kind-specific\n optional fallback (`undefined` for most flags, `[]` for arrays)\n- `'required'` — must be supplied; error if missing\n- `'defaulted'` — always present (falls back to default value)" + }, + "defaultValue": { + "description": "Runtime default value (if any)." + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Short/long aliases (e.g. `[{ name: 'f', hidden: false }]` for `--force`)." + }, + "envVar": { + "type": "string", + "description": "Environment variable name for v0.2+ resolution." + }, + "configPath": { + "type": "string", + "description": "Dotted config path for v0.2+ resolution (e.g. `'deploy.region'`)." + }, + "description": { + "type": "string", + "description": "Human-readable description for help text." + }, + "enumValues": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Allowed literal values when `kind === 'enum'`." + }, + "elementSchema": { + "$ref": "#/$defs/flag", + "description": "Element schema when `kind === 'array'`." + }, + "prompt": { + "$ref": "#/$defs/prompt", + "description": "Interactive prompt configuration for v0.3+ resolution." + }, + "deprecated": { + "oneOf": [ + { + "type": "string" + }, + { + "const": true + } + ], + "description": "Deprecation marker.\n\n- `undefined` — not deprecated (default)\n- `true` — deprecated with no migration message\n- `string` — deprecated with a reason/migration message\n\nWhen a deprecated flag is used, a warning is emitted to stderr.\nHelp text shows `[deprecated]` or `[deprecated: ]`." + }, + "propagate": { + "const": true, + "description": "Whether this flag propagates to subcommands in nested command trees.\n\nWhen `true`, the flag is automatically available to all descendant\ncommands. A child command that defines a flag with the same name\nshadows the propagated parent flag." + } + }, + "required": [ + "kind", + "presence" + ], + "description": "The runtime descriptor stored inside every FlagBuilder. Consumers (parser,\nhelp generator, resolution chain) read this to understand the flag's shape\nwithout touching generics." + }, + "arg": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "A named positional argument entry in the command schema.\n\nPairs a user-facing arg name with its ArgSchema descriptor.\nThe array ordering in CommandSchema.args determines CLI position." + }, + "kind": { + "enum": [ + "string", + "number", + "enum", + "custom" + ], + "description": "What kind of value this arg accepts." + }, + "presence": { + "enum": [ + "required", + "optional", + "defaulted" + ], + "description": "Presence describes whether a positional arg is guaranteed to exist when the\naction handler runs:\n\n- `'required'` — must be supplied; error if missing (default)\n- `'optional'` — may be `undefined` if not supplied\n- `'defaulted'` — always present (falls back to default value)" + }, + "variadic": { + "const": true, + "description": "Whether this arg consumes all remaining positionals." + }, + "stdinMode": { + "const": true, + "description": "Whether this arg may read from stdin during resolution." + }, + "defaultValue": { + "description": "Runtime default value (if any)." + }, + "description": { + "type": "string", + "description": "Human-readable description for help text." + }, + "envVar": { + "type": "string", + "description": "Environment variable name for env resolution.\n\nWhen set and the CLI value is absent, the resolver reads this env var\nand coerces the string to the arg's declared kind." + }, + "enumValues": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Allowed literal values when `kind === 'enum'`." + }, + "deprecated": { + "oneOf": [ + { + "type": "string" + }, + { + "const": true + } + ], + "description": "Deprecation marker.\n\n- `undefined` — not deprecated (default)\n- `true` — deprecated with no migration message\n- `string` — deprecated with a reason/migration message\n\nWhen a deprecated arg is used, a warning is emitted to stderr.\nHelp text shows `[deprecated]` or `[deprecated: ]`." + } + }, + "required": [ + "name", + "kind", + "presence" + ], + "description": "The runtime descriptor stored inside every ArgBuilder. Consumers (parser,\nhelp generator) read this to understand the arg's shape without touching\ngenerics." + }, + "prompt": { + "type": "object", + "additionalProperties": false, + "properties": { + "kind": { + "enum": [ + "confirm", + "input", + "select", + "multiselect" + ], + "description": "The kind of interactive prompt to present.\n\n- `'confirm'` — yes/no boolean question\n- `'input'` — free-text string input\n- `'select'` — single selection from a list\n- `'multiselect'` — multiple selections from a list" + }, + "message": { + "type": "string", + "description": "The question displayed to the user." + }, + "placeholder": { + "type": "string", + "description": "Placeholder text shown before user types (informational only)." + }, + "choices": { + "type": "array", + "items": { + "$ref": "#/$defs/choice" + }, + "description": "Available choices. When omitted for `enum` flags, the enum values\nfrom the flag schema are used automatically." + }, + "min": { + "type": "integer", + "description": "Minimum number of selections required." + }, + "max": { + "type": "integer", + "description": "Maximum number of selections allowed." + } + }, + "required": [ + "kind", + "message" + ], + "description": "Discriminated union of all prompt configurations.\n\nUse the `kind` field to narrow:\n```ts\nif (config.kind === 'select') {\n config.choices // readonly SelectChoice[] | undefined\n}\n```" + }, + "choice": { + "type": "object", + "additionalProperties": false, + "properties": { + "value": { + "type": "string", + "description": "The value returned when this choice is selected." + }, + "label": { + "type": "string", + "description": "Display label shown to the user." + }, + "description": { + "type": "string", + "description": "Optional description shown alongside the choice." + } + }, + "required": [ + "value" + ], + "description": "A selectable option for SelectPromptConfig and MultiselectPromptConfig prompts." + }, + "example": { + "type": "object", + "additionalProperties": false, + "properties": { + "command": { + "type": "string", + "description": "The command invocation (e.g. `'deploy production --force'`)." + }, + "description": { + "type": "string", + "description": "Optional description of what this example does." + } + }, + "required": [ + "command" + ], + "description": "A single usage example shown in help text." + } + } } diff --git a/scripts/build-meta-descriptions.ts b/scripts/build-meta-descriptions.ts index 376211b6..4035d230 100644 --- a/scripts/build-meta-descriptions.ts +++ b/scripts/build-meta-descriptions.ts @@ -1,5 +1,4 @@ #!/usr/bin/env bun - /** * Rebuild `src/core/json-schema/meta-descriptions.generated.ts`. * @@ -13,16 +12,16 @@ import { readFile, rm, writeFile } from 'node:fs/promises'; import { dirname, join } from 'node:path'; -import { collectPublicApiIndex } from '../apps/docs/.vitepress/data/api-index.ts'; +import { collectPublicApiIndex } from '@kjanat/dreamcli-docs/vitepress/data/api-index.ts'; import { buildDefinitionMetaSchemaDescriptions, renderDefinitionMetaSchemaDescriptions, -} from '../apps/docs/.vitepress/data/meta-schema-descriptions.ts'; +} from '@kjanat/dreamcli-docs/vitepress/data/meta-schema-descriptions.ts'; import { generatedMetaSchemaDescriptionsPath, packageJsonPath, -} from '../apps/docs/.vitepress/data/paths.ts'; -import { collectTypeDocModel } from '../apps/docs/.vitepress/data/typedoc.ts'; +} from '@kjanat/dreamcli-docs/vitepress/data/paths.ts'; +import { collectTypeDocModel } from '@kjanat/dreamcli-docs/vitepress/data/typedoc.ts'; const publicApi = await collectPublicApiIndex(packageJsonPath); const typeDoc = await collectTypeDocModel(packageJsonPath, publicApi); diff --git a/scripts/gh-project.ts b/scripts/gh-project.ts deleted file mode 100755 index c321bf10..00000000 --- a/scripts/gh-project.ts +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bun - -/** - * Thin wrapper for the GitHub project helper. - * - * @module - */ - -import { ghProject } from '@kjanat/gh-project'; - -if (import.meta.main) { - void ghProject.run(); -} diff --git a/scripts/release-meta.sh b/scripts/release-meta.sh deleted file mode 100755 index ac4faf95..00000000 --- a/scripts/release-meta.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -target="${1:-}" - -if [[ -z "${target}" ]]; then - echo 'usage: scripts/release-meta.sh ' - exit 1 -fi - -if [[ -z "${GITHUB_OUTPUT:-}" ]]; then - echo 'GITHUB_OUTPUT is not set' - exit 1 -fi - -if ! command -v yq >/dev/null 2>&1; then - echo 'yq not found on runner' - exit 1 -fi - -read_field() { - local file="$1" - local query="$2" - yq -r "${query}" "${file}" -} - -validate_release_tag() { - local version="$1" - - if [[ "${GITHUB_EVENT_NAME:-}" != 'release' ]]; then - return - fi - - local expected="v${version}" - - if [[ -z "${RELEASE_TAG:-}" ]]; then - echo 'release event missing tag_name' - exit 1 - fi - - if [[ "${RELEASE_TAG}" != "${expected}" ]]; then - printf "Release tag '%s' does not match package version '%s'\n" "${RELEASE_TAG}" "${expected}" - exit 1 - fi -} - -case "${target}" in -npm) - package="$(read_field packages/dreamcli/package.json '.name // ""')" - version="$(read_field packages/dreamcli/package.json '.version // ""')" - - if [[ -z "${package}" ]]; then - echo 'package.json missing .name' - exit 1 - fi - - if [[ -z "${version}" ]]; then - echo 'package.json missing .version' - exit 1 - fi - - validate_release_tag "${version}" - - url="https://www.npmjs.com/package/${package}/v/${version}" - # yq -n builds one-line JSON; strenv() pulls PACKAGE/VERSION/URL from this env assignment. - meta_json="$(PACKAGE="${package}" VERSION="${version}" URL="${url}" yq -n -o=json -I=0 '.package = strenv(PACKAGE) | .version = strenv(VERSION) | .url = strenv(URL)')" - ;; - -jsr) - deno_package="$(read_field packages/dreamcli/deno.json '.name // ""')" - package_name="$(read_field packages/dreamcli/package.json '.name // ""')" - deno_version="$(read_field packages/dreamcli/deno.json '.version // ""')" - package_version="$(read_field packages/dreamcli/package.json '.version // ""')" - - if [[ -z "${deno_package}" ]]; then - echo 'deno.json missing .name' - exit 1 - fi - - if [[ -z "${package_name}" ]]; then - echo 'package.json missing .name' - exit 1 - fi - - if [[ -z "${deno_version}" ]]; then - echo 'deno.json missing .version' - exit 1 - fi - - if [[ -z "${package_version}" ]]; then - echo 'package.json missing .version' - exit 1 - fi - - if [[ "${deno_version}" != "${package_version}" ]]; then - printf "Version mismatch: deno.json=%s package.json=%s\n" "${deno_version}" "${package_version}" - exit 1 - fi - - if [[ "${deno_package}" != "${package_name}" ]]; then - printf "Name mismatch: deno.json=%s package.json=%s\n" "${deno_package}" "${package_name}" - exit 1 - fi - - validate_release_tag "${deno_version}" - - url="https://jsr.io/${deno_package}@${deno_version}" - # yq -n builds one-line JSON; strenv() pulls PACKAGE/VERSION/URL from this env assignment. - meta_json="$(PACKAGE="${deno_package}" VERSION="${deno_version}" URL="${url}" yq -n -o=json -I=0 '.package = strenv(PACKAGE) | .version = strenv(VERSION) | .url = strenv(URL)')" - ;; - -*) - printf "unknown target: %s (expected npm|jsr)\n" "${target}" - exit 1 - ;; -esac - -printf 'meta=%s\n' "${meta_json}" >>"${GITHUB_OUTPUT}" diff --git a/scripts/release-meta.ts b/scripts/release-meta.ts new file mode 100755 index 00000000..cfad54e3 --- /dev/null +++ b/scripts/release-meta.ts @@ -0,0 +1,85 @@ +#!/usr/bin/env node +import { appendFileSync, readFileSync } from 'node:fs'; +import { relative } from 'node:path'; +import { argv, cwd, env, exit } from 'node:process'; + +type Manifest = { + name?: string; + version?: string; +}; + +const fail = (message: string): never => { + console.error(message); + exit(1); +}; + +const readJson = (path: string): T => { + try { + return JSON.parse(readFileSync(path, 'utf8')) as T; + } catch { + throw new Error(`failed to read ${path}`); + } +}; + +const requireField = (value: string | undefined, file: string, field: 'name' | 'version'): string => + value ?? fail(`${file} missing .${field}`); + +const validateReleaseTag = (version: string) => { + if (env.GITHUB_EVENT_NAME !== 'release') return; + + const tag = env.RELEASE_TAG ?? fail('release event missing tag_name'); + const expected = `v${version}`; + + if (tag !== expected) { + fail(`Release tag '${tag}' does not match package version '${expected}'`); + } +}; + +const target = argv[2]; +if (target !== 'npm' && target !== 'jsr') { + fail(`usage: ${relative(cwd(), import.meta.filename)} `); +} + +const output = env.GITHUB_OUTPUT ?? fail('GITHUB_OUTPUT is not set'); + +const packageJson = readJson('packages/dreamcli/package.json'); + +let pkgName: string; +let version: string; +let url: string; + +if (target === 'npm') { + pkgName = requireField(packageJson.name, 'package.json', 'name'); + version = requireField(packageJson.version, 'package.json', 'version'); + url = `https://www.npmjs.com/package/${pkgName}/v/${version}`; +} else { + const denoJson = readJson('packages/dreamcli/deno.json'); + + const denoName = requireField(denoJson.name, 'deno.json', 'name'); + const denoVersion = requireField(denoJson.version, 'deno.json', 'version'); + const packageName = requireField(packageJson.name, 'package.json', 'name'); + const packageVersion = requireField(packageJson.version, 'package.json', 'version'); + + if (denoName !== packageName) { + fail(`Name mismatch: deno.json=${denoName} package.json=${packageName}`); + } + + if (denoVersion !== packageVersion) { + fail(`Version mismatch: deno.json=${denoVersion} package.json=${packageVersion}`); + } + + pkgName = denoName; + version = denoVersion; + url = `https://jsr.io/${pkgName}@${version}`; +} + +validateReleaseTag(version); + +appendFileSync( + output, + `meta=${JSON.stringify({ + package: pkgName, + version, + url, + })}\n`, +); diff --git a/tools/gh-project/package.json b/tools/gh-project/package.json index ace79021..db36466b 100644 --- a/tools/gh-project/package.json +++ b/tools/gh-project/package.json @@ -23,13 +23,15 @@ ], "scripts": { "start": "bun src/main.ts", - "typecheck": "tsc --noEmit" + "typecheck": "tsgo --noEmit", + "typecheck:tsc": "tsc --noEmit" }, "dependencies": { "@kjanat/dreamcli": "workspace:*" }, "devDependencies": { "@types/bun": "catalog:", + "@typescript/native-preview": "catalog:", "typescript": "catalog:" } } From 2e11c103202e264d1c9114f584bf1cd56c175f0c Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Wed, 8 Apr 2026 04:32:57 +0200 Subject: [PATCH 08/21] fix(docs): resolve all Twoslash compilation errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove explicit `lib` from Twoslash compilerOptions — the VFS can't resolve lib .d.ts files, but default resolution works. Strip shebangs from example source in generated fences, tolerate known-unresolvable imports (node:*, Bun.*, vitest, yaml) via @errors directives, and add global `expect` shim for testing snippets. --- apps/docs/.vitepress/config.ts | 1 - apps/docs/.vitepress/data/examples.ts | 3 ++- .../.vitepress/twoslash/testing-fixtures.ts | 23 +++++++++++++++++++ apps/docs/concepts/testing.md | 1 + apps/docs/guide/config.md | 2 ++ apps/docs/guide/schema-export.md | 2 ++ apps/docs/guide/walkthrough.md | 4 +++- apps/docs/reference/main.md | 1 + apps/docs/tsconfig.json | 3 +-- packages/dreamcli/tsconfig.json | 2 +- 10 files changed, 36 insertions(+), 6 deletions(-) diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts index 26fa8a63..3dc1ffc5 100644 --- a/apps/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -46,7 +46,6 @@ const isGithubActions = Boolean(env.GITHUB_ACTIONS); const compilerOptions = { baseUrl: packageRoot, - lib: ['ESNext'], moduleDetection: ModuleDetectionKind.Force, module: ModuleKind.ESNext, moduleResolution: ModuleResolutionKind.Bundler, diff --git a/apps/docs/.vitepress/data/examples.ts b/apps/docs/.vitepress/data/examples.ts index 67ea923f..afb0a34e 100644 --- a/apps/docs/.vitepress/data/examples.ts +++ b/apps/docs/.vitepress/data/examples.ts @@ -121,7 +121,8 @@ ${usageSection.join('\n')} ## Source ${codeFence}ts twoslash -${example.sourceCode.trimEnd()} +// @errors: 2307 2868 +${example.sourceCode.replace(/^#!.*\n/, '').trimEnd()} ${codeFence} ## Related Links diff --git a/apps/docs/.vitepress/twoslash/testing-fixtures.ts b/apps/docs/.vitepress/twoslash/testing-fixtures.ts index a922cb33..8f4bef18 100644 --- a/apps/docs/.vitepress/twoslash/testing-fixtures.ts +++ b/apps/docs/.vitepress/twoslash/testing-fixtures.ts @@ -1,5 +1,28 @@ import { arg, command, flag } from '@kjanat/dreamcli'; +/** + * Vitest globals shim — vitest/globals provides these at + * runtime but Twoslash can't resolve the package. + */ +declare global { + interface ExpectResult { + toBe(expected: unknown): void; + toEqual(expected: unknown): void; + toContain(expected: unknown): void; + toContainEqual(expected: unknown): void; + toBeInstanceOf(expected: unknown): void; + toBeUndefined(): void; + not: ExpectResult; + } + interface Expect { + (value: unknown): ExpectResult; + objectContaining( + sample: Record, + ): unknown; + } + const expect: Expect; +} + export const greet = command('greet') .arg('name', arg.string()) .flag('loud', flag.boolean()) diff --git a/apps/docs/concepts/testing.md b/apps/docs/concepts/testing.md index 191e74eb..f604926b 100644 --- a/apps/docs/concepts/testing.md +++ b/apps/docs/concepts/testing.md @@ -37,6 +37,7 @@ Good luck doing that with shell scripts. Run the actual compiled binary as a child process: ```ts twoslash +// @noErrors import { execFile } from 'node:child_process'; import { promisify } from 'node:util'; diff --git a/apps/docs/guide/config.md b/apps/docs/guide/config.md index 6d42fe5a..94f7eb16 100644 --- a/apps/docs/guide/config.md +++ b/apps/docs/guide/config.md @@ -51,6 +51,7 @@ Add YAML, TOML, or any other format via `configFormat()`: ::: code-group ```ts twoslash [Bun built-ins] +// @errors: 2868 import { cli, configFormat } from '@kjanat/dreamcli'; cli('mycli') @@ -63,6 +64,7 @@ cli('mycli') ``` ```ts twoslash [npm packages] +// @errors: 2307 import { cli, configFormat } from '@kjanat/dreamcli'; import { parse as parseYaml } from 'yaml'; import { parse as parseTOML } from '@iarna/toml'; diff --git a/apps/docs/guide/schema-export.md b/apps/docs/guide/schema-export.md index 3d6d130b..acd85531 100644 --- a/apps/docs/guide/schema-export.md +++ b/apps/docs/guide/schema-export.md @@ -11,6 +11,7 @@ documentation generation, IDE integration, or config file validation. commands, flags, args, types, constraints, env bindings, prompts, and more. ```ts twoslash +// @errors: 2591 import { writeFileSync } from 'node:fs'; import { cli, @@ -77,6 +78,7 @@ Full example output: validates CLI input as a JSON object — useful for config file validation. ```ts twoslash +// @errors: 2591 import { writeFileSync } from 'node:fs'; import { cli, diff --git a/apps/docs/guide/walkthrough.md b/apps/docs/guide/walkthrough.md index 75164551..d8a07afe 100644 --- a/apps/docs/guide/walkthrough.md +++ b/apps/docs/guide/walkthrough.md @@ -650,13 +650,14 @@ When piped or in `--json` mode, spinners are suppressed automatically — no gar ## Step 10: Testing -This is where it gets interesting. +This is where it gets interesting.\ You don't want to spawn subprocesses to test a CLI. dreamcli's testkit lets you run commands in-process with full control: ```ts twoslash import { runCommand } from '@kjanat/dreamcli/testkit'; // ---cut-start--- import { prList } from './examples/gh/src/docs.ts'; +import './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut-end--- // Test that pr list returns open PRs by default @@ -677,6 +678,7 @@ import { issueTriage, prList, } from './examples/gh/src/docs.ts'; +import './apps/docs/.vitepress/twoslash/testing-fixtures.ts'; // ---cut-end--- // Test that derive blocks unauthenticated access diff --git a/apps/docs/reference/main.md b/apps/docs/reference/main.md index 32688d3e..c735c3f4 100644 --- a/apps/docs/reference/main.md +++ b/apps/docs/reference/main.md @@ -348,6 +348,7 @@ Build the default search-path list dreamcli uses for config discovery. This is m debugging, custom bootstrapping, or help text that wants to show the exact probed paths. ```ts twoslash +// @errors: 2591 import { buildConfigSearchPaths } from '@kjanat/dreamcli'; const paths = buildConfigSearchPaths( diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index a1c3a26d..057acdf0 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "lib": ["ESNext", "DOM", "DOM.Iterable"], - "types": ["bun", "node", "vue", "vite/client", "vitest"], - "customConditions": ["bun"], + "types": ["bun", "node", "vue", "vite/client", "vitest", "vitest/globals"], "paths": { "@kjanat/dreamcli": ["../../packages/dreamcli/src/index.ts"], "@kjanat/dreamcli/runtime": ["../../packages/dreamcli/src/runtime.ts"], diff --git a/packages/dreamcli/tsconfig.json b/packages/dreamcli/tsconfig.json index 857e5cc9..f01bbb5d 100644 --- a/packages/dreamcli/tsconfig.json +++ b/packages/dreamcli/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "composite": true, - "types": ["bun", "node", "deno", "vitest"], + "types": ["bun", "node", "deno", "vitest", "vitest/globals"], "paths": { "@kjanat/dreamcli": ["./src/index.ts"], "@kjanat/dreamcli/runtime": ["./src/runtime.ts"], From 34b405d7349103548a743719f4146bf6c1c78770 Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Wed, 8 Apr 2026 11:50:49 +0200 Subject: [PATCH 09/21] chore(docs): add robots.txt --- apps/docs/public/robots.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 apps/docs/public/robots.txt diff --git a/apps/docs/public/robots.txt b/apps/docs/public/robots.txt new file mode 100644 index 00000000..c2a49f4f --- /dev/null +++ b/apps/docs/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Allow: / From eda57acc9d2cd4169623d232fcf725e7245e3938 Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Wed, 8 Apr 2026 12:28:07 +0200 Subject: [PATCH 10/21] fix(docs): restore Twoslash type resolution for monorepo Inherit paths + typeRoots from tsconfig so Twoslash resolves @kjanat/dreamcli to source and finds vitest in package-level node_modules. Remove bandaid // @errors annotations. --- apps/docs/.vitepress/config.ts | 6 ++++-- apps/docs/.vitepress/data/examples.ts | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts index 3dc1ffc5..3b06f995 100644 --- a/apps/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -5,6 +5,7 @@ import { transformerTwoslash } from '@shikijs/vitepress-twoslash'; import { ModuleDetectionKind, ModuleKind, ModuleResolutionKind } from 'typescript'; import { defineConfig } from 'vitepress'; import jsr from '../../../packages/dreamcli/deno.json' with { type: 'json' }; +import tsc from '../../../tsconfig.json' with { type: 'json' }; import { collectPublicApiIndex } from './data/api-index.ts'; import { collectExampleMeta } from './data/examples.ts'; import { examplesRoot, packageJsonPath } from './data/paths.ts'; @@ -45,14 +46,15 @@ const ifCI = (ifCiThen: string, ifNotCiThen: string) => (isCI ? ifCiThen : ifNot const isGithubActions = Boolean(env.GITHUB_ACTIONS); const compilerOptions = { - baseUrl: packageRoot, + baseUrl: projectRoot, + paths: tsc.compilerOptions?.paths ?? {}, moduleDetection: ModuleDetectionKind.Force, module: ModuleKind.ESNext, moduleResolution: ModuleResolutionKind.Bundler, allowImportingTsExtensions: true, noEmit: true, resolveJsonModule: true, - types: ['bun', 'node', 'vue', 'vite/client', 'vitest/globals'], + typeRoots: [`${packageRoot}/node_modules/@types`, `${packageRoot}/node_modules`], }; const links = { diff --git a/apps/docs/.vitepress/data/examples.ts b/apps/docs/.vitepress/data/examples.ts index afb0a34e..826a4b65 100644 --- a/apps/docs/.vitepress/data/examples.ts +++ b/apps/docs/.vitepress/data/examples.ts @@ -121,7 +121,6 @@ ${usageSection.join('\n')} ## Source ${codeFence}ts twoslash -// @errors: 2307 2868 ${example.sourceCode.replace(/^#!.*\n/, '').trimEnd()} ${codeFence} From 2fce8c487fb77c1856cabe0843ffdd9872afa58b Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Wed, 8 Apr 2026 14:48:34 +0200 Subject: [PATCH 11/21] fix(jsr): wrap schema export in TS module for JSR score MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JSR requires @module docs on all entrypoints — JSON files can't have them. Wrap dreamcli.schema.json in src/schema.ts with re-export + module doc. npm export keeps raw JSON. --- apps/docs/tsconfig.json | 2 +- packages/dreamcli/deno.json | 4 ++-- packages/dreamcli/src/schema.ts | 16 ++++++++++++++++ packages/dreamcli/tsconfig.json | 2 +- tsconfig.json | 4 ++-- 5 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 packages/dreamcli/src/schema.ts diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index 057acdf0..79992da9 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -7,7 +7,7 @@ "@kjanat/dreamcli": ["../../packages/dreamcli/src/index.ts"], "@kjanat/dreamcli/runtime": ["../../packages/dreamcli/src/runtime.ts"], "@kjanat/dreamcli/testkit": ["../../packages/dreamcli/src/testkit.ts"], - "@kjanat/dreamcli/schema": ["../../packages/dreamcli/dreamcli.schema.json"], + "@kjanat/dreamcli/schema": ["../../packages/dreamcli/src/schema.ts"], "@kjanat/dreamcli/package.json": ["../../packages/dreamcli/package.json"] } }, diff --git a/packages/dreamcli/deno.json b/packages/dreamcli/deno.json index 259e6cdd..8e6d3b2d 100644 --- a/packages/dreamcli/deno.json +++ b/packages/dreamcli/deno.json @@ -28,7 +28,7 @@ ".": "./src/index.ts", "./runtime": "./src/runtime.ts", "./testkit": "./src/testkit.ts", - "./schema": "./dreamcli.schema.json" + "./schema": "./src/schema.ts" }, "compilerOptions": { "strict": true, @@ -37,7 +37,7 @@ "@kjanat/dreamcli": ["./src/index.ts"], "@kjanat/dreamcli/runtime": ["./src/runtime.ts"], "@kjanat/dreamcli/testkit": ["./src/testkit.ts"], - "@kjanat/dreamcli/schema": ["./dreamcli.schema.json"], + "@kjanat/dreamcli/schema": ["./src/schema.ts"], "@kjanat/dreamcli/package.json": ["./package.json"] } }, diff --git a/packages/dreamcli/src/schema.ts b/packages/dreamcli/src/schema.ts new file mode 100644 index 00000000..357cb7b5 --- /dev/null +++ b/packages/dreamcli/src/schema.ts @@ -0,0 +1,16 @@ +/** + * JSON Schema for DreamCLI definition files. + * + * Re-exports the generated `dreamcli.schema.json` meta-schema so tooling, + * editors, and validation libraries can import it as a typed module. + * + * @example + * ```ts + * import schema from '@kjanat/dreamcli/schema'; + * + * console.log(schema.$id); // "dreamcli.schema.json" + * ``` + * + * @module @kjanat/dreamcli/schema + */ +export { default } from '../dreamcli.schema.json' with { type: 'json' }; diff --git a/packages/dreamcli/tsconfig.json b/packages/dreamcli/tsconfig.json index f01bbb5d..598a97b3 100644 --- a/packages/dreamcli/tsconfig.json +++ b/packages/dreamcli/tsconfig.json @@ -7,7 +7,7 @@ "@kjanat/dreamcli": ["./src/index.ts"], "@kjanat/dreamcli/runtime": ["./src/runtime.ts"], "@kjanat/dreamcli/testkit": ["./src/testkit.ts"], - "@kjanat/dreamcli/schema": ["./dreamcli.schema.json"], + "@kjanat/dreamcli/schema": ["./src/schema.ts"], "@kjanat/dreamcli/package.json": ["./package.json"] } }, diff --git a/tsconfig.json b/tsconfig.json index 6293923e..e04971ed 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -36,8 +36,8 @@ "../../packages/dreamcli/src/testkit.ts" ], "@kjanat/dreamcli/schema": [ - "./packages/dreamcli/dreamcli.schema.json", - "../../packages/dreamcli/dreamcli.schema.json" + "./packages/dreamcli/src/schema.ts", + "../../packages/dreamcli/src/schema.ts" ], "@kjanat/dreamcli/package.json": [ "./packages/dreamcli/package.json", From 1b4abe0922595d54b057d240e085d95867f97262 Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Wed, 8 Apr 2026 15:20:29 +0200 Subject: [PATCH 12/21] chore(docs): reorganize sidebar, fix Twoslash shims Move entrypoint API links to their own sidebar group, add `Contracts` section. Fix Twoslash `node:fs` resolution with declare-module shims, fix mermaid label spacing, and use `LR` layout for flag masking diagram. --- apps/docs/.vitepress/config.ts | 13 +++++++++---- apps/docs/.vitepress/theme/settings.css | 6 ++++++ apps/docs/guide/schema-export.md | 18 ++++++++++++++++-- apps/docs/guide/semantics.md | 2 +- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts index 3b06f995..43132db8 100644 --- a/apps/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -204,6 +204,15 @@ export default defineConfig({ text: 'API Reference', items: [ { text: 'Overview', link: '/reference/api' }, + { text: '@kjanat/dreamcli', link: '/reference/main' }, + { text: '@kjanat/dreamcli/testkit', link: '/reference/testkit' }, + { text: '@kjanat/dreamcli/runtime', link: '/reference/runtime' }, + { text: '@kjanat/dreamcli/schema', link: '/reference/schema' }, + ], + }, + { + text: 'Contracts And Audits', + items: [ { text: 'Changelog', link: '/reference/changelog' }, { text: 'Semantic Delta Log', @@ -219,11 +228,7 @@ export default defineConfig({ text: 'Example Hover', link: '/reference/example-hover-prototype', }, - { text: 'Schema', link: '/reference/schema' }, { text: 'Support Matrix', link: '/reference/support-matrix' }, - { text: '@kjanat/dreamcli', link: '/reference/main' }, - { text: '@kjanat/dreamcli/testkit', link: '/reference/testkit' }, - { text: '@kjanat/dreamcli/runtime', link: '/reference/runtime' }, ], }, ], diff --git a/apps/docs/.vitepress/theme/settings.css b/apps/docs/.vitepress/theme/settings.css index 5262b0ee..8bf79755 100644 --- a/apps/docs/.vitepress/theme/settings.css +++ b/apps/docs/.vitepress/theme/settings.css @@ -38,3 +38,9 @@ div.language-mermaid button.copy, div.language-mermaid span.lang { display: none; } + +/* Mermaid HTML labels should not inherit prose paragraph spacing/line-height. */ +div.mermaid .nodeLabel p { + margin: 0; + line-height: 1.3; +} diff --git a/apps/docs/guide/schema-export.md b/apps/docs/guide/schema-export.md index acd85531..a9bb2485 100644 --- a/apps/docs/guide/schema-export.md +++ b/apps/docs/guide/schema-export.md @@ -11,7 +11,14 @@ documentation generation, IDE integration, or config file validation. commands, flags, args, types, constraints, env bindings, prompts, and more. ```ts twoslash -// @errors: 2591 +// @noErrors +declare module 'node:fs' { + export function writeFileSync( + path: string, + data: string, + ): void; +} +// ---cut--- import { writeFileSync } from 'node:fs'; import { cli, @@ -78,7 +85,14 @@ Full example output: validates CLI input as a JSON object — useful for config file validation. ```ts twoslash -// @errors: 2591 +// @noErrors +declare module 'node:fs' { + export function writeFileSync( + path: string, + data: string, + ): void; +} +// ---cut--- import { writeFileSync } from 'node:fs'; import { cli, diff --git a/apps/docs/guide/semantics.md b/apps/docs/guide/semantics.md index 25f6ced4..099687bb 100644 --- a/apps/docs/guide/semantics.md +++ b/apps/docs/guide/semantics.md @@ -187,7 +187,7 @@ Important masking rules: Example shape: ```mermaid -flowchart TD +flowchart LR root["root
--verbose (propagate)"] -->|inherits| db["db
--verbose (local, masks)"] db -->|blocked| migrate ``` From c1d52ee85bd5b4af9046d9cec79f23a9866fc187 Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Wed, 8 Apr 2026 15:29:56 +0200 Subject: [PATCH 13/21] docs: polish version constraints, update schema reference Use non-breaking spaces between `>=` and version numbers so they never wrap mid-operator. Remove redundant navbar Links dropdown (already in social links). Rewrite schema reference to document dual npm/JSR export mapping and link it from the API entrypoints table. --- apps/docs/.vitepress/config.ts | 8 -------- apps/docs/guide/getting-started.md | 6 +++--- apps/docs/guide/runtime.md | 10 +++++----- apps/docs/reference/api.md | 2 +- apps/docs/reference/runtime.md | 10 +++++----- apps/docs/reference/schema.md | 19 ++++++++++--------- apps/docs/reference/support-matrix.md | 6 +++--- 7 files changed, 27 insertions(+), 34 deletions(-) diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts index 43132db8..b846794c 100644 --- a/apps/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -121,14 +121,6 @@ export default defineConfig({ { text: 'Guide', link: '/guide/getting-started' }, { text: 'Examples', link: '/examples/' }, { text: 'Reference', link: '/reference/api' }, - { - text: 'Links', - items: [ - { text: 'GitHub', link: links.github }, - { text: 'npm', link: links.npm }, - { text: 'JSR', link: links.jsr }, - ], - }, ], sidebar: { '/concepts/': [ diff --git a/apps/docs/guide/getting-started.md b/apps/docs/guide/getting-started.md index 3de3f368..897b05cc 100644 --- a/apps/docs/guide/getting-started.md +++ b/apps/docs/guide/getting-started.md @@ -19,9 +19,9 @@ deno add jsr:@kjanat/dreamcli ::: Supported minimum runtimes: -Node.js `>= 22.22.2`, -Bun `>= 1.3.11`, -Deno `>= 2.6.0`. +Node.js `>=\u00a022.22.2`, +Bun `>=\u00a01.3.11`, +Deno `>=\u00a02.6.0`. ## Your First Command diff --git a/apps/docs/guide/runtime.md b/apps/docs/guide/runtime.md index bdd9b18a..96e8c761 100644 --- a/apps/docs/guide/runtime.md +++ b/apps/docs/guide/runtime.md @@ -5,11 +5,11 @@ A thin `RuntimeAdapter` interface abstracts the platform-specific edges. ## Supported Runtimes -| Runtime | Status | Package | -| ------------------ | --------- | ------------------------ | -| Node.js >= 22.22.2 | Supported | `@kjanat/dreamcli` (npm) | -| Bun >= 1.3.11 | Supported | `@kjanat/dreamcli` (npm) | -| Deno >= 2.6.0 | Supported | `@kjanat/dreamcli` (JSR) | +| Runtime | Status | Package | +| ----------------------- | --------- | ------------------------ | +| Node.js >=\u00a022.22.2 | Supported | `@kjanat/dreamcli` (npm) | +| Bun >=\u00a01.3.11 | Supported | `@kjanat/dreamcli` (npm) | +| Deno >=\u00a02.6.0 | Supported | `@kjanat/dreamcli` (JSR) | Adapters validate these minimum versions during creation. Unsupported runtimes fail fast with a descriptive error before command execution starts. diff --git a/apps/docs/reference/api.md b/apps/docs/reference/api.md index 11267507..3409f2ad 100644 --- a/apps/docs/reference/api.md +++ b/apps/docs/reference/api.md @@ -36,7 +36,7 @@ and `examples/**` during docs build. | `@kjanat/dreamcli` | schema builders, CLI assembly, parsing, resolution, errors, completions, schema export | [`@kjanat/dreamcli`](/reference/main) | | `@kjanat/dreamcli/testkit` | command tests, output capture, scripted prompts, test adapters | [`@kjanat/dreamcli/testkit`](/reference/testkit) | | `@kjanat/dreamcli/runtime` | runtime detection, explicit adapters, runtime-only helpers | [`@kjanat/dreamcli/runtime`](/reference/runtime) | -| `@kjanat/dreamcli/schema` | generated CLI definition meta-schema JSON | schema asset only | +| `@kjanat/dreamcli/schema` | generated CLI definition meta-schema (export mapping differs by package target) | [`@kjanat/dreamcli/schema`](/reference/schema) | ## Generated Index diff --git a/apps/docs/reference/runtime.md b/apps/docs/reference/runtime.md index ef41b2d6..9f2d9f72 100644 --- a/apps/docs/reference/runtime.md +++ b/apps/docs/reference/runtime.md @@ -60,10 +60,10 @@ const runtime: Runtime = detectRuntime(); ## Supported Runtimes -| Runtime | Adapter | Notes | -| ------------------ | ------------- | ------------------------------ | -| Node.js >= 22.22.2 | `NodeAdapter` | Full support | -| Bun >= 1.3.11 | `BunAdapter` | Delegates to Node adapter | -| Deno >= 2.6.0 | `DenoAdapter` | Permission-safe Deno namespace | +| Runtime | Adapter | Notes | +| ----------------------- | ------------- | ------------------------------ | +| Node.js >=\u00a022.22.2 | `NodeAdapter` | Full support | +| Bun >=\u00a01.3.11 | `BunAdapter` | Delegates to Node adapter | +| Deno >=\u00a02.6.0 | `DenoAdapter` | Permission-safe Deno namespace | Adapter creation validates these minimum versions and throws immediately when the host runtime is too old. diff --git a/apps/docs/reference/schema.md b/apps/docs/reference/schema.md index 1f3ad23b..efd5040c 100644 --- a/apps/docs/reference/schema.md +++ b/apps/docs/reference/schema.md @@ -1,11 +1,12 @@ # Schema -`@kjanat/dreamcli/schema` is the package's published JSON Schema export. -It resolves to `dreamcli.schema.json`, the same definition schema referenced by -`generateSchema()` output. +`@kjanat/dreamcli/schema` is the package's published definition-schema export.\ +It resolves to the same schema referenced by `generateSchema()` output, with a package-target specific mapping: -Use it when you want local or offline validation of dreamcli definition metadata without depending -on the CDN `$schema` URL. +- npm/package export (`package.json`): `./schema` -> `dreamcli.schema.json` +- Deno/JSR export (`deno.json`): `./schema` -> `src/schema.ts` (which re-exports the same schema) + +Use it when you want local or offline validation of dreamcli definition metadata without depending on the CDN `$schema` URL. ## Importing The Schema @@ -16,8 +17,9 @@ schema.$schema; schema.$defs.command; ``` -In TypeScript, this works with `resolveJsonModule`. -At runtime, your loader needs to support JSON imports for the target environment. +In TypeScript, this works with `resolveJsonModule`.\ +Runtime loading behavior depends on the host runtime export target (see notes above). +For Node on the npm/package target, import with `with { type: 'json' }`. ## Common Uses @@ -42,8 +44,7 @@ definition.$schema; schema.$id; ``` -`definition.$schema` points at the public schema URL, while the package export gives you the same -definition locally from the installed package. +`definition.$schema` points at the public schema URL, while the package export gives you the same definition locally from the installed package. ## Related Pages diff --git a/apps/docs/reference/support-matrix.md b/apps/docs/reference/support-matrix.md index 4da77306..47bf61fd 100644 --- a/apps/docs/reference/support-matrix.md +++ b/apps/docs/reference/support-matrix.md @@ -39,9 +39,9 @@ For completions specifically, `Shell` and `SHELLS` now match the shipped shell s | Claim | Status | Evidence | Notes | | ---------------------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | -| Node.js >= 22.22.2 runtime support | Supported | [Runtime Support](/guide/runtime), [`src/runtime/node.ts`](https://github.com/kjanat/dreamcli/blob/master/src/runtime/node.ts), [`docs/reference/runtime.md`](/reference/runtime) | This is the primary adapter implementation. | -| Bun >= 1.3.11 runtime support | Supported | [Runtime Support](/guide/runtime), [`src/runtime/bun.ts`](https://github.com/kjanat/dreamcli/blob/master/src/runtime/bun.ts), [`docs/reference/runtime.md`](/reference/runtime) | Bun currently delegates through the Node adapter strategy. | -| Deno >= 2.6.0 runtime support | Supported | [Runtime Support](/guide/runtime), [`src/runtime/deno.ts`](https://github.com/kjanat/dreamcli/blob/master/src/runtime/deno.ts), [`docs/reference/runtime.md`](/reference/runtime) | Deno support is permission-aware and published through JSR. | +| Node.js >=\u00a022.22.2 runtime support | Supported | [Runtime Support](/guide/runtime), [`src/runtime/node.ts`](https://github.com/kjanat/dreamcli/blob/master/src/runtime/node.ts), [`docs/reference/runtime.md`](/reference/runtime) | This is the primary adapter implementation. | +| Bun >=\u00a01.3.11 runtime support | Supported | [Runtime Support](/guide/runtime), [`src/runtime/bun.ts`](https://github.com/kjanat/dreamcli/blob/master/src/runtime/bun.ts), [`docs/reference/runtime.md`](/reference/runtime) | Bun currently delegates through the Node adapter strategy. | +| Deno >=\u00a02.6.0 runtime support | Supported | [Runtime Support](/guide/runtime), [`src/runtime/deno.ts`](https://github.com/kjanat/dreamcli/blob/master/src/runtime/deno.ts), [`docs/reference/runtime.md`](/reference/runtime) | Deno support is permission-aware and published through JSR. | | Cross-platform CI coverage for all supported runtimes and shells | Deferred | [`docs/reference/runtime.md`](/reference/runtime), [`/.github/workflows/ci.yml`](https://github.com/kjanat/dreamcli/blob/master/.github/workflows/ci.yml) | Runtime support is shipped, but broader platform coverage is still planned. | ## Input Sources and Resolution From 7ab02ec42e63f8a517433968d82623f77b31630e Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Wed, 8 Apr 2026 23:37:46 +0200 Subject: [PATCH 14/21] feat: add cli-creation skill, scaffold script, and templates Agent skill that generates dreamcli-powered CLIs from a spec. Includes: - single/multi-command templates, - Bun test stubs, and - a Python scaffold script. Wire up dprint ruff plugin + ruff.toml for Python formatting, add `*.ts.tpl` associations, and ignore Python caches. Also polish docs SettingsGear and mobile Twoslash styles. --- .dprint.jsonc | 6 +- .gitignore | 2 + .zed/settings.json | 2 +- .../theme/components/SettingsGear.vue | 14 +- apps/docs/.vitepress/theme/custom.css | 2 +- .../docs/.vitepress/theme/twoslash-mobile.css | 18 +- packages/dreamcli/deno.json | 2 +- ruff.toml | 1 + skills/cli-creation/SKILL.md | 79 ++++ skills/cli-creation/agents/openai.yaml | 4 + .../templates/multi-command.bun-test.ts.tpl | 20 + .../templates/multi-command.test.ts.tpl | 20 + .../assets/templates/multi-command.ts.tpl | 89 +++++ .../templates/single-command.bun-test.ts.tpl | 20 + .../templates/single-command.test.ts.tpl | 20 + .../assets/templates/single-command.ts.tpl | 43 +++ .../references/consumer-workflow.md | 55 +++ .../references/pattern-cookbook.md | 70 ++++ .../cli-creation/references/runtime-notes.md | 29 ++ skills/cli-creation/scripts/scaffold_cli.py | 360 ++++++++++++++++++ tsconfig.json | 2 +- 21 files changed, 833 insertions(+), 25 deletions(-) create mode 100644 ruff.toml create mode 100644 skills/cli-creation/SKILL.md create mode 100644 skills/cli-creation/agents/openai.yaml create mode 100644 skills/cli-creation/assets/templates/multi-command.bun-test.ts.tpl create mode 100644 skills/cli-creation/assets/templates/multi-command.test.ts.tpl create mode 100644 skills/cli-creation/assets/templates/multi-command.ts.tpl create mode 100644 skills/cli-creation/assets/templates/single-command.bun-test.ts.tpl create mode 100644 skills/cli-creation/assets/templates/single-command.test.ts.tpl create mode 100644 skills/cli-creation/assets/templates/single-command.ts.tpl create mode 100644 skills/cli-creation/references/consumer-workflow.md create mode 100644 skills/cli-creation/references/pattern-cookbook.md create mode 100644 skills/cli-creation/references/runtime-notes.md create mode 100755 skills/cli-creation/scripts/scaffold_cli.py diff --git a/.dprint.jsonc b/.dprint.jsonc index 061cb75d..82e47e2f 100644 --- a/.dprint.jsonc +++ b/.dprint.jsonc @@ -9,7 +9,7 @@ "lineWidth": 100, "quoteStyle": "single", "css.enabled": true, - "associations": ["!README.md", "!apps/docs/**/*.md", "!apps/docs/.vitepress/twoslash/*.ts"] + "associations": ["!README.md", "!apps/docs/**/*.md", "!apps/docs/.vitepress/twoslash/*.ts", "*.ts.tpl"] }, "markdown": { "textWrap": "maintain", @@ -49,6 +49,7 @@ "endOfLine": "lf", "associations": ["**/README.md", "**/docs/**/*.md", "**/.vitepress/twoslash/*.ts"] }, + "ruff": { "preview": true, "indentWidth": 4 }, "excludes": ["**/node_modules", "**/{*-,bun}lock(.*)?", "**/snapshots", "**/*.schema.json"], "plugins": [ "https://plugins.dprint.dev/biome-0.12.6.wasm", @@ -58,6 +59,7 @@ "https://plugins.dprint.dev/markdown-0.21.1.wasm", "https://plugins.dprint.dev/kjanat/svg-v0.2.6.wasm", "https://plugins.dprint.dev/exec-0.6.2.json@df98f54ffd3092b8a841aedd6d098a2651f16d0a796a40535774f1a8b4b9d463", - "https://plugins.dprint.dev/prettier-0.67.1.json@59ebff9da99fa283ba37ed5c131e73d5acc6b57bb90ba4cd1230b4fbadb19dd1" + "https://plugins.dprint.dev/prettier-0.67.1.json@59ebff9da99fa283ba37ed5c131e73d5acc6b57bb90ba4cd1230b4fbadb19dd1", + "https://plugins.dprint.dev/ruff-0.7.8.wasm" ] } diff --git a/.gitignore b/.gitignore index 602b27e7..271e0f9d 100644 --- a/.gitignore +++ b/.gitignore @@ -231,3 +231,5 @@ $RECYCLE.BIN/ /.bucket/ .playwright-mcp/ +__pycache__ +.*_cache \ No newline at end of file diff --git a/.zed/settings.json b/.zed/settings.json index a02686b2..650249e6 100644 --- a/.zed/settings.json +++ b/.zed/settings.json @@ -6,7 +6,7 @@ "hard_tabs": true, "tab_size": 2, "wrap_guides": [100], - "file_types": { "Markdown": ["LICENSE"] }, + "file_types": { "Markdown": ["LICENSE"], "TypeScript": ["*.ts.tpl"] }, "prettier": { "allowed": false }, "formatter": [ { "language_server": { "name": "dprint" } }, diff --git a/apps/docs/.vitepress/theme/components/SettingsGear.vue b/apps/docs/.vitepress/theme/components/SettingsGear.vue index 74854452..4eacd8ab 100644 --- a/apps/docs/.vitepress/theme/components/SettingsGear.vue +++ b/apps/docs/.vitepress/theme/components/SettingsGear.vue @@ -269,9 +269,7 @@ border-radius: 999px; background: var(--vp-c-bg-elv); backdrop-filter: blur(12px); - box-shadow: - 0 4px 24px rgba(0, 0, 0, 0.4), - 0 0 0 1px rgba(255, 255, 255, 0.03) inset; + box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.03) inset; white-space: nowrap; } @@ -321,7 +319,7 @@ } .toggle-track::after { - content: ''; + content: ""; position: absolute; top: 2px; left: 2px; @@ -329,9 +327,7 @@ height: 12px; border-radius: 50%; background: var(--vp-c-text-3); - transition: - transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), - background-color 0.3s var(--s-ease); + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.3s var(--s-ease); } .toggle-track.active { @@ -393,9 +389,7 @@ } .settings-dropdown-leave-active { - transition: - opacity 0.15s var(--s-ease), - transform 0.15s var(--s-ease); + transition: opacity 0.15s var(--s-ease), transform 0.15s var(--s-ease); } .settings-dropdown-enter-from { diff --git a/apps/docs/.vitepress/theme/custom.css b/apps/docs/.vitepress/theme/custom.css index 3e255e03..5970f07c 100644 --- a/apps/docs/.vitepress/theme/custom.css +++ b/apps/docs/.vitepress/theme/custom.css @@ -31,6 +31,6 @@ color: var(--jsr-color); } -.VPSocialLink [class^='vpi-social-'] { +.VPSocialLink [class^="vpi-social-"] { transition: color 0.25s; } diff --git a/apps/docs/.vitepress/theme/twoslash-mobile.css b/apps/docs/.vitepress/theme/twoslash-mobile.css index 6d60e56c..400d8906 100644 --- a/apps/docs/.vitepress/theme/twoslash-mobile.css +++ b/apps/docs/.vitepress/theme/twoslash-mobile.css @@ -3,19 +3,19 @@ @media (hover: none) { /* - * 1. Always show dotted underline on touch devices. - * Upstream: underline only visible via `.twoslash:hover .twoslash-hover` - * which never fires on touch. Making it permanent tells users "tap me". - */ + * 1. Always show dotted underline on touch devices. + * Upstream: underline only visible via `.twoslash:hover .twoslash-hover` + * which never fires on touch. Making it permanent tells users "tap me". + */ .twoslash .twoslash-hover { border-color: var(--twoslash-underline-color); } /* - * 2. Convert popup to a bottom sheet. - * Upstream: absolute-positioned tooltip that clips and auto-hides on scroll. - * Bottom sheet anchors to viewport, survives scroll, and is draggable. - */ + * 2. Convert popup to a bottom sheet. + * Upstream: absolute-positioned tooltip that clips and auto-hides on scroll. + * Bottom sheet anchors to viewport, survives scroll, and is draggable. + */ .v-popper--theme-twoslash .v-popper__inner { position: fixed !important; bottom: 0 !important; @@ -73,7 +73,7 @@ } .twoslash-drag-handle::before { - content: ''; + content: ""; width: 36px; height: 4px; border-radius: 2px; diff --git a/packages/dreamcli/deno.json b/packages/dreamcli/deno.json index 8e6d3b2d..42805c31 100644 --- a/packages/dreamcli/deno.json +++ b/packages/dreamcli/deno.json @@ -57,5 +57,5 @@ "fmt": { "exclude": ["**"] }, "lint": { "rules": { "exclude": ["ban-types", "require-await"] } }, "nodeModulesDir": "manual", - "exclude": ["**/*.test.ts", "*.ts", "*cache/", "coverage/", "dist/", "scripts/"] + "exclude": ["**/*.test.ts", "*.ts", "*cache/", "coverage/", "dist/", "scripts/", "**/*.tpl"] } diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 00000000..711385d5 --- /dev/null +++ b/ruff.toml @@ -0,0 +1 @@ +preview = true diff --git a/skills/cli-creation/SKILL.md b/skills/cli-creation/SKILL.md new file mode 100644 index 00000000..5c2d74aa --- /dev/null +++ b/skills/cli-creation/SKILL.md @@ -0,0 +1,79 @@ +--- +name: cli-creation +description: Build consumer-facing DreamCLI CLIs from scratch with Bun-first workflows and typed patterns. Use when asked to scaffold or implement a new @kjanat/dreamcli command-line app, add commands/flags/args/prompts/output/testing, or create starter files/tests for DreamCLI users. +--- + +# CLI Creation + +## Overview + +Create runnable DreamCLI starter CLIs and extend them with typed command patterns. +Use this skill for user-facing app code, not DreamCLI framework internals. + +## Quick Start + +1. Choose a starter mode: + - `single`: one root command (`cli(name).default(command)`). + - `multi`: grouped command surface (`group('...').command(...)`). +2. Generate starter files: + - `python scripts/scaffold_cli.py --name mycli --mode single --out .` + - Tests are generated by default; add `--no-test` only when explicitly requested. + - Test template is auto-detected: Bun without Vitest uses `bun:test`; otherwise a Vitest template is generated. +3. Run and validate generated files: + - Use the printed path from the scaffolder output, for example `bun ./mycli.ts --help`. + - Run the generated test unless `--no-test` was used. +4. Extend behavior with references: + - `references/consumer-workflow.md` + - `references/pattern-cookbook.md` + - `references/runtime-notes.md` + +## Grounding Sources + +- Use `examples/standalone/basic.ts` for single-command defaults. +- Use `examples/standalone/multi-command.ts` for grouped-command defaults. +- Use `examples/standalone/testing.ts` for `runCommand()` patterns. +- Use `apps/docs/guide/getting-started.md` for baseline consumer narrative. +- Use `apps/docs/guide/walkthrough.md` for richer end-to-end CLI composition. + +## Workflow Decision Tree + +- User asks for a simple one-command utility: + - Use `--mode single`. +- User asks for nested command groups (git/gh style): + - Use `--mode multi`. +- User asks for tests from the start: + - Do nothing; tests are scaffolded by default. +- User explicitly asks for no tests: + - Add `--no-test`. +- User asks for npm/tsx or Deno instructions: + - Keep generated code unchanged and provide runtime command alternatives from `references/runtime-notes.md`. + +## Extend the Starter + +- Add typed args with `arg.string()`, `arg.number()`, `arg.enum(...)`, and `arg.custom(...)`. +- For repeated positionals, use `.variadic()` on an arg definition. +- Add typed flags with defaults and aliases via `flag.*()`. +- Add env/config/prompt sources on each flag before action logic. +- Branch on `out.jsonMode` for machine-readable responses. +- Use `runCommand()` from `@kjanat/dreamcli/testkit` for in-process tests. +- Keep output assertions explicit, including trailing newlines. + +## Resource Map + +- `scripts/scaffold_cli.py` + - Generate Bun-first starter files and optional tests. +- `assets/templates/*.tpl` + - Source templates used by the scaffold script. +- `references/consumer-workflow.md` + - End-to-end flow from request to validated CLI. +- `references/pattern-cookbook.md` + - Copy-ready snippets for common DreamCLI features. +- `references/runtime-notes.md` + - Runtime and package-manager execution guidance. + +## Guardrails + +- Do not modify DreamCLI core internals for consumer-app requests. +- Keep generated imports on `@kjanat/dreamcli` and `@kjanat/dreamcli/testkit`. +- Preserve typed resolution flow: argv -> env -> config -> prompt -> default. +- Prefer Bun commands first; include npm/tsx and Deno alternatives when requested. diff --git a/skills/cli-creation/agents/openai.yaml b/skills/cli-creation/agents/openai.yaml new file mode 100644 index 00000000..277eb701 --- /dev/null +++ b/skills/cli-creation/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "CLI Creation" + short_description: "Build typed DreamCLI consumer CLIs quickly" + default_prompt: "Use $cli-creation to scaffold a Bun-first DreamCLI CLI with tests." diff --git a/skills/cli-creation/assets/templates/multi-command.bun-test.ts.tpl b/skills/cli-creation/assets/templates/multi-command.bun-test.ts.tpl new file mode 100644 index 00000000..5f9b6a30 --- /dev/null +++ b/skills/cli-creation/assets/templates/multi-command.bun-test.ts.tpl @@ -0,0 +1,20 @@ +import { partyStart } from '__ENTRY_FILE__'; +import { runCommand } from '@kjanat/dreamcli/testkit'; +import { describe, expect, it } from 'bun:test'; + +describe('party start command', () => { + it('applies sparkle middleware when --sparkle is set', async () => { + const result = await runCommand(partyStart, ['--theme', 'midnight', '--sparkle']); + + expect(result.exitCode).toBe(0); + expect(result.stdout).toEqual(['✨ Party started with midnight theme! ✨\n']); + expect(result.stderr).toEqual([]); + }); + + it('renders help text', async () => { + const result = await runCommand(partyStart, ['--help']); + + expect(result.exitCode).toBe(0); + expect(result.stdout.join('')).toContain('Start the pony party'); + }); +}); diff --git a/skills/cli-creation/assets/templates/multi-command.test.ts.tpl b/skills/cli-creation/assets/templates/multi-command.test.ts.tpl new file mode 100644 index 00000000..e53a4b66 --- /dev/null +++ b/skills/cli-creation/assets/templates/multi-command.test.ts.tpl @@ -0,0 +1,20 @@ +import { partyStart } from '__ENTRY_FILE__'; +import { runCommand } from '@kjanat/dreamcli/testkit'; +import { describe, expect, it } from 'vitest'; + +describe('party start command', () => { + it('applies sparkle middleware when --sparkle is set', async () => { + const result = await runCommand(partyStart, ['--theme', 'midnight', '--sparkle']); + + expect(result.exitCode).toBe(0); + expect(result.stdout).toEqual(['✨ Party started with midnight theme! ✨\n']); + expect(result.stderr).toEqual([]); + }); + + it('renders help text', async () => { + const result = await runCommand(partyStart, ['--help']); + + expect(result.exitCode).toBe(0); + expect(result.stdout.join('')).toContain('Start the pony party'); + }); +}); diff --git a/skills/cli-creation/assets/templates/multi-command.ts.tpl b/skills/cli-creation/assets/templates/multi-command.ts.tpl new file mode 100644 index 00000000..50026d7c --- /dev/null +++ b/skills/cli-creation/assets/templates/multi-command.ts.tpl @@ -0,0 +1,89 @@ +#!/usr/bin/env bun +/** + * __CLI_NAME__ - multi-command DreamCLI starter (pony party edition). + * + * Bun: + * bun __CLI_NAME__.ts snack cupcake --count 3 + * bun __CLI_NAME__.ts story "rainbow heist" --mood legendary --sparkle + * bun __CLI_NAME__.ts party start --theme midnight + * bun __CLI_NAME__.ts --help + * + * npm/tsx: + * npx tsx __CLI_NAME__.ts party playlist --genre chaos + * + * Deno: + * deno run -A __CLI_NAME__.ts snack donut --count 2 + */ + +import { arg, cli, command, flag, group, middleware } from '@kjanat/dreamcli'; + +const sparkle = middleware<{ sparkle: (message: string) => string }>(async ({ flags, next }) => { + const sparkleEnabled = flags.sparkle === true; + return next({ + sparkle: (message: string) => (sparkleEnabled ? `✨ ${message} ✨` : message), + }); +}); + +const sparkleFlag = () => flag.boolean().alias('s').env('SPARKLE').describe('Add extra sparkle'); + +export const snack = command('snack') + .description('Serve snacks to the crew') + .arg('treat', arg.string().default('cupcake').describe('Snack to serve')) + .flag('count', flag.number().default(1).alias('c').describe('How many snacks')) + .flag('sparkle', sparkleFlag()) + .middleware(sparkle) + .action(({ args, flags, ctx, out }) => { + const { treat } = args; + const { count } = flags; + out.log(ctx.sparkle(`Serving ${count} ${treat}(s)!`)); + }); + +export const story = command('story') + .description('Tell a dramatic story') + .arg('topic', arg.string().default('the great cupcake rescue').describe('Story topic')) + .flag('mood', flag.enum(['calm', 'chaos', 'legendary']) + .prompt({ kind: 'select', message: 'Set the mood!' }) + .default('calm').describe('Story mood')) + .flag('sparkle', sparkleFlag()) + .middleware(sparkle) + .action(({ args, flags, ctx, out }) => { + const { topic } = args; + const { mood } = flags; + out.log(ctx.sparkle(`Story time: ${topic} (${mood})`)); + out.log(ctx.sparkle('Dramatic glitter intensifies')); + }); + +export const partyStart = command('start') + .description('Start the pony party') + .flag('theme', flag.enum(['rainbow', 'midnight', 'glitter']).default('rainbow').describe('Party theme')) + .flag('sparkle', sparkleFlag()) + .middleware(sparkle) + .action(({ flags, ctx, out }) => { + out.log(ctx.sparkle(`Party started with ${flags.theme} theme!`)); + }); + +export const partyPlaylist = command('playlist') + .description('Pick a party playlist vibe') + .flag('genre', flag.enum(['pop', 'ballad', 'chaos']).default('pop').describe('Playlist genre')) + .flag('sparkle', sparkleFlag()) + .middleware(sparkle) + .action(({ flags, ctx, out }) => { + out.log(ctx.sparkle(`Now playing: ${flags.genre}`)); + }); + +export const party = group('party') + .description('Party controls') + .command(partyStart) + .command(partyPlaylist); + +export const app = cli('__CLI_NAME__') + .version('0.1.0') + .description('Fun DreamCLI starter app') + .command(snack) + .command(story) + .command(party) + .completions(); + +if (import.meta.main) { + app.run(); +} diff --git a/skills/cli-creation/assets/templates/single-command.bun-test.ts.tpl b/skills/cli-creation/assets/templates/single-command.bun-test.ts.tpl new file mode 100644 index 00000000..55a4664e --- /dev/null +++ b/skills/cli-creation/assets/templates/single-command.bun-test.ts.tpl @@ -0,0 +1,20 @@ +import { hello } from '__ENTRY_FILE__'; +import { runCommand } from '@kjanat/dreamcli/testkit'; +import { describe, expect, it } from 'bun:test'; + +describe('hello command', () => { + it('prints sparkly greeting when --sparkle is set', async () => { + const result = await runCommand(hello, ['Twilight', '--sparkle', '--times', '2']); + + expect(result.exitCode).toBe(0); + expect(result.stdout).toEqual(['✨ Hello, Twilight! ✨\n', '✨ Hello, Twilight! ✨\n']); + expect(result.stderr).toEqual([]); + }); + + it('renders help text', async () => { + const result = await runCommand(hello, ['--help']); + + expect(result.exitCode).toBe(0); + expect(result.stdout.join('')).toContain('Say hello with optional sparkle'); + }); +}); diff --git a/skills/cli-creation/assets/templates/single-command.test.ts.tpl b/skills/cli-creation/assets/templates/single-command.test.ts.tpl new file mode 100644 index 00000000..f6ee3315 --- /dev/null +++ b/skills/cli-creation/assets/templates/single-command.test.ts.tpl @@ -0,0 +1,20 @@ +import { hello } from '__ENTRY_FILE__'; +import { runCommand } from '@kjanat/dreamcli/testkit'; +import { describe, expect, it } from 'vitest'; + +describe('hello command', () => { + it('prints sparkly greeting when --sparkle is set', async () => { + const result = await runCommand(hello, ['Twilight', '--sparkle', '--times', '2']); + + expect(result.exitCode).toBe(0); + expect(result.stdout).toEqual(['✨ Hello, Twilight! ✨\n', '✨ Hello, Twilight! ✨\n']); + expect(result.stderr).toEqual([]); + }); + + it('renders help text', async () => { + const result = await runCommand(hello, ['--help']); + + expect(result.exitCode).toBe(0); + expect(result.stdout.join('')).toContain('Say hello with optional sparkle'); + }); +}); diff --git a/skills/cli-creation/assets/templates/single-command.ts.tpl b/skills/cli-creation/assets/templates/single-command.ts.tpl new file mode 100644 index 00000000..97159e24 --- /dev/null +++ b/skills/cli-creation/assets/templates/single-command.ts.tpl @@ -0,0 +1,43 @@ +#!/usr/bin/env bun +/** + * __CLI_NAME__ - hello-world DreamCLI starter. + * + * Bun: + * bun __CLI_NAME__.ts + * bun __CLI_NAME__.ts Twilight --sparkle --times 2 + * bun __CLI_NAME__.ts --help + * + * npm/tsx: + * npx tsx __CLI_NAME__.ts Twilight --sparkle --times 2 + * + * Deno: + * deno run -A __CLI_NAME__.ts Twilight --sparkle --times 2 + */ + +import { arg, cli, command, flag, middleware } from '@kjanat/dreamcli'; + +const sparkle = middleware<{ sparkle: (message: string) => string }>(async ({ flags, next }) => { + const sparkleEnabled = flags.sparkle === true; + return next({ + sparkle: (message: string) => (sparkleEnabled ? `✨ ${message} ✨` : message), + }); +}); + +export const hello = command('hello') + .description('Say hello with optional sparkle') + .arg('name', arg.string().default('World').describe('Who to greet')) + .flag('sparkle', flag.boolean().alias('s').env('SPARKLE').describe('Add sparkles')) + .flag('times', flag.number().default(1).alias('n').describe('Repeat count')) + .middleware(sparkle) + .action(({ args, flags, ctx, out }) => { + for (let i = 0; i < flags.times; i++) { + const base = `Hello, ${args.name}!`; + out.log(ctx.sparkle(base)); + } + }); + +export const app = cli('__CLI_NAME__').default(hello); + +if (import.meta.main) { + app.run(); +} diff --git a/skills/cli-creation/references/consumer-workflow.md b/skills/cli-creation/references/consumer-workflow.md new file mode 100644 index 00000000..370bbd5a --- /dev/null +++ b/skills/cli-creation/references/consumer-workflow.md @@ -0,0 +1,55 @@ +# Consumer Workflow + +## Goal + +Build a consumer-facing CLI app with DreamCLI, starting from a working template and ending with validated behavior. + +## Inputs to confirm + +- CLI name (`--name`). +- Surface shape (`single` or `multi`). +- Whether tests should be skipped (`--no-test`). +- Runtime instructions needed by the user (Bun, npm/tsx, Deno). + +## Implementation flow + +1. Scaffold starter files. + + ```bash + python scripts/scaffold_cli.py --name mycli --mode single --out . + ``` + + The scaffolder detects package manager and Vitest usage to choose either a `bun:test` or Vitest starter test template. + +2. Implement command behavior. + + - Add `.description(...)` on all commands. + - Add typed `.arg(...)` and `.flag(...)` declarations. + - Keep action handlers focused on business logic only. + +3. Add typed value resolution. + + - Use `.env('...')` for environment values. + - Use `.config('...')` for config values. + - Use `.prompt(...)` for interactive fallback. + - Use `.default(...)` for stable action-time values. + +4. Add output behavior. + + - Use `out.log()` for human messages. + - Use `out.table()` for list-shaped data. + - For object responses, branch on `out.jsonMode` and use `out.json(data)`. + +5. Validate behavior. + + ```bash + bun ./mycli.ts --help + bun test ./mycli.test.ts + ``` + +## Done criteria + +- `--help` renders expected command and flag descriptions. +- Happy-path command execution exits with `0`. +- Generated or custom tests pass. +- No mixed human and machine output in `--json` mode. diff --git a/skills/cli-creation/references/pattern-cookbook.md b/skills/cli-creation/references/pattern-cookbook.md new file mode 100644 index 00000000..39700eb3 --- /dev/null +++ b/skills/cli-creation/references/pattern-cookbook.md @@ -0,0 +1,70 @@ +# Pattern Cookbook + +## 1) Flag precedence chain + +```ts +flag + .enum(['us', 'eu', 'ap']) + .env('DEPLOY_REGION') + .config('deploy.region') + .prompt({ kind: 'select', message: 'Which region?' }) + .default('us'); +``` + +Use this when a value can come from CLI args, environment, config, or prompts. + +## 2) JSON mode branching + +```ts +.action(({ out }) => { + const data = { service: 'api', healthy: true }; + + if (out.jsonMode) { + out.json(data); + return; + } + + out.log('Service api is healthy'); +}); +``` + +Avoid mixing `out.log(...)` with JSON output in the same branch. + +## 3) Tabular list output + +```ts +.action(({ out }) => { + out.table([ + { id: 1, name: 'alice', role: 'admin' }, + { id: 2, name: 'bob', role: 'viewer' }, + ]); +}); +``` + +`out.table()` renders pretty tables for humans and arrays in `--json` mode. + +## 4) Structured CLIError for guidance + +```ts +import { CLIError } from '@kjanat/dreamcli'; + +throw new CLIError('Deployment target not found', { + code: 'NOT_FOUND', + exitCode: 1, + suggest: 'Try: mycli deploy --help', +}); +``` + +Use this for actionable failures instead of generic thrown errors. + +## 5) In-process command test + +```ts +import { runCommand } from '@kjanat/dreamcli/testkit'; + +const result = await runCommand(deploy, ['production', '--force']); +expect(result.exitCode).toBe(0); +expect(result.stdout).toEqual(['Deploying production to us\n']); +``` + +Prefer `runCommand()` over subprocess tests for speed and deterministic assertions. diff --git a/skills/cli-creation/references/runtime-notes.md b/skills/cli-creation/references/runtime-notes.md new file mode 100644 index 00000000..84ee1bab --- /dev/null +++ b/skills/cli-creation/references/runtime-notes.md @@ -0,0 +1,29 @@ +# Runtime Notes + +## Bun-first commands + +- Run CLI entrypoint: `bun mycli.ts --help` +- Run tests: `bun test mycli.test.ts` + +The scaffolder prints path-aware run commands; use those exact printed paths when `--out` is not `.`. +The scaffolder auto-detects test style: + +- Bun project + no detected Vitest usage: generate `bun:test` template. +- Otherwise: generate Vitest template. +- Package manager detection checks lockfiles (including `pnpm-*.yaml/.yml`) and manifest `packageManager` entries in `package.json`, `package.json5`, and `package.yaml/.yml`. + +If Vitest template is generated inside a Bun project, `bun test` still runs those tests in this workflow. + +## npm/Node alternative + +- Run CLI entrypoint: `npx tsx mycli.ts --help` +- Run tests: `npx vitest run mycli.test.ts` + +## Deno alternative + +- Run CLI entrypoint: `deno run -A mycli.ts --help` +- Run tests: use Bun/Node test tooling unless the project already has Deno test wiring. + +## Prompt behavior + +DreamCLI skips prompts in non-interactive contexts (CI/piped input). When tests depend on prompts, inject answers with `runCommand(..., { answers: [...] })`. diff --git a/skills/cli-creation/scripts/scaffold_cli.py b/skills/cli-creation/scripts/scaffold_cli.py new file mode 100755 index 00000000..671b8e6a --- /dev/null +++ b/skills/cli-creation/scripts/scaffold_cli.py @@ -0,0 +1,360 @@ +#!/usr/bin/env python3 +# /// script +# requires-python = ">=3.13" +# dependencies = [] +# /// +""" +Generate DreamCLI starter files from bundled templates. +""" + +import argparse +import json +import re +import sys +from pathlib import Path + +MANIFEST_FILENAMES = ( + "package.json", + "package.json5", + "package.yaml", + "package.yml", +) + +LOCKFILE_TO_MANAGER = ( + ("bun.lock", "bun"), + ("bun.lockb", "bun"), + ("pnpm-lock.yaml", "pnpm"), + ("pnpm-lock.yml", "pnpm"), + ("pnpm-workspace.yaml", "pnpm"), + ("pnpm-workspace.yml", "pnpm"), + ("yarn.lock", "yarn"), + ("package-lock.json", "npm"), + ("npm-shrinkwrap.json", "npm"), +) + + +def normalize_name(raw: str) -> str: + name = raw.strip().lower() + name = re.sub(r"[^a-z0-9]+", "-", name) + name = name.strip("-") + name = re.sub(r"-{2,}", "-", name) + return name + + +def read_template(path: Path) -> str: + if not path.exists(): + raise FileNotFoundError(f"Template not found: {path}") + return path.read_text() + + +def render_template(template: str, replacements: dict[str, str]) -> str: + rendered = template + for key, value in replacements.items(): + rendered = rendered.replace(key, value) + if not rendered.endswith("\n"): + rendered += "\n" + return rendered + + +def write_file(path: Path, content: str, force: bool) -> None: + if path.exists() and not force: + raise FileExistsError(f"Refusing to overwrite existing file: {path}. Use --force to overwrite.") + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content) + + +def iter_ancestors(path: Path): + current = path.resolve() + while True: + yield current + if current.parent == current: + break + current = current.parent + + +def lockfiles_for_directory(directory: Path) -> list[Path]: + lockfiles: list[Path] = [] + for lockfile, _ in LOCKFILE_TO_MANAGER: + candidate = directory / lockfile + if candidate.exists(): + lockfiles.append(candidate) + + pnpm_globs = ( + "pnpm-*.yaml", + "pnpm-*.yml", + ) + for pattern in pnpm_globs: + for candidate in sorted(directory.glob(pattern)): + if candidate not in lockfiles: + lockfiles.append(candidate) + return lockfiles + + +def manifests_for_directory(directory: Path) -> list[Path]: + manifests: list[Path] = [] + for filename in MANIFEST_FILENAMES: + candidate = directory / filename + if candidate.exists(): + manifests.append(candidate) + return manifests + + +def package_manager_from_lockfiles(directory: Path) -> str | None: + for candidate in lockfiles_for_directory(directory): + if candidate.name.startswith("pnpm-") and candidate.suffix in {".yaml", ".yml"}: + return "pnpm" + for lockfile, manager in LOCKFILE_TO_MANAGER: + if candidate.name == lockfile: + return manager + return None + + +def package_manager_from_manifest(manifest: dict) -> str | None: + raw_value = manifest.get("packageManager") + if not isinstance(raw_value, str) or not raw_value.strip(): + return None + manager = raw_value.split("@", 1)[0].strip().lower() + if manager in {"bun", "pnpm", "npm", "yarn"}: + return manager + return None + + +def read_text_file(path: Path) -> str | None: + try: + return path.read_text(errors="ignore") + except OSError: + return None + + +def package_manager_from_text(raw_text: str) -> str | None: + match = re.search( + r'(?mi)^[ \t]*["\']?packageManager["\']?[ \t]*:[ \t]*["\']?([^"\',\n\r#]+)', + raw_text, + ) + if match is None: + return None + + value = match.group(1).strip() + manager = value.split("@", 1)[0].strip().lower() + if manager in {"bun", "pnpm", "npm", "yarn"}: + return manager + return None + + +def manifest_text_uses_vitest(raw_text: str) -> bool: + return re.search(r"\bvitest\b", raw_text) is not None + + +def detect_package_manager_with_root(start: Path) -> tuple[str | None, Path | None]: + for directory in iter_ancestors(start): + for manifest_path in manifests_for_directory(directory): + if manifest_path.name == "package.json": + manifest = read_package_json(manifest_path) + if manifest is not None: + from_manifest = package_manager_from_manifest(manifest) + if from_manifest is not None: + return (from_manifest, directory) + + raw_text = read_text_file(manifest_path) + if raw_text is not None: + from_text = package_manager_from_text(raw_text) + if from_text is not None: + return (from_text, directory) + + from_lockfile = package_manager_from_lockfiles(directory) + if from_lockfile is not None: + return (from_lockfile, directory) + return (None, None) + + +def read_package_json(path: Path) -> dict | None: + try: + raw = path.read_text() + parsed = json.loads(raw) + except (OSError, json.JSONDecodeError): + return None + if isinstance(parsed, dict): + return parsed + return None + + +def manifest_uses_vitest(manifest: dict) -> bool: + dependency_fields = ( + "dependencies", + "devDependencies", + "peerDependencies", + "optionalDependencies", + ) + for field in dependency_fields: + deps = manifest.get(field) + if isinstance(deps, dict) and "vitest" in deps: + return True + + scripts = manifest.get("scripts") + if isinstance(scripts, dict): + for script in scripts.values(): + if isinstance(script, str) and "vitest" in script: + return True + + return False + + +def find_project_root(start: Path) -> Path | None: + for directory in iter_ancestors(start): + if package_manager_from_lockfiles(directory) is not None: + return directory + if manifests_for_directory(directory): + return directory + return None + + +def iter_to_ancestor(start: Path, ancestor: Path): + current = start.resolve() + target = ancestor.resolve() + while True: + yield current + if current == target: + break + if current.parent == current: + break + current = current.parent + + +def detect_vitest_usage_in_project(project_root: Path, manager_root: Path | None) -> bool: + stop_at = manager_root.resolve() if manager_root is not None else project_root.resolve() + for directory in iter_to_ancestor(project_root, stop_at): + for manifest_path in manifests_for_directory(directory): + if manifest_path.name == "package.json": + manifest = read_package_json(manifest_path) + if manifest and manifest_uses_vitest(manifest): + return True + + raw_text = read_text_file(manifest_path) + if raw_text is not None and manifest_text_uses_vitest(raw_text): + return True + + if (stop_at / "node_modules" / "vitest" / "package.json").exists(): + return True + + for lockfile in lockfiles_for_directory(stop_at): + try: + if "vitest" in lockfile.read_text(errors="ignore"): + return True + except OSError: + continue + + return False + + +def choose_test_template(mode: str, package_manager: str | None, uses_vitest: bool) -> tuple[str, str]: + if package_manager == "bun" and not uses_vitest: + return (f"{mode}-command.bun-test.ts.tpl", "bun:test") + return (f"{mode}-command.test.ts.tpl", "vitest") + + +def choose_test_command(package_manager: str | None, test_framework: str, test_path: str) -> str: + if test_framework == "bun:test": + return f"bun test {test_path}" + if package_manager == "bun": + return f"bun test {test_path}" + if package_manager == "pnpm": + return f"pnpm vitest run {test_path}" + if package_manager == "yarn": + return f"yarn vitest run {test_path}" + return f"npx vitest run {test_path}" + + +def format_run_path(path: Path, cwd: Path) -> str: + try: + relative = path.relative_to(cwd).as_posix() + if not relative.startswith((".", "..")): + return f"./{relative}" + return relative + except ValueError: + return path.as_posix() + + +def main() -> int: + parser = argparse.ArgumentParser(description="Scaffold Bun-first DreamCLI starter files from templates.") + parser.add_argument("--name", required=True, help="CLI name (e.g. mycli)") + parser.add_argument( + "--mode", + choices=["single", "multi"], + default="single", + help="Starter shape. single=one root command, multi=nested command groups.", + ) + parser.add_argument("--out", required=True, help="Output directory") + parser.add_argument( + "--no-test", + action="store_true", + help="Skip generating the starter test file.", + ) + parser.add_argument( + "--force", + action="store_true", + help="Overwrite existing files if present.", + ) + args = parser.parse_args() + + cli_name = normalize_name(args.name) + if not cli_name: + print("[ERROR] --name must include at least one letter or digit.") + return 1 + + output_dir = Path(args.out).resolve() + output_dir.mkdir(parents=True, exist_ok=True) + + skill_root = Path(__file__).resolve().parent.parent + templates_dir = skill_root / "assets" / "templates" + + entry_template_path = templates_dir / f"{args.mode}-command.ts.tpl" + test_template_path = templates_dir / f"{args.mode}-command.test.ts.tpl" + + entry_filename = f"{cli_name}.ts" + entry_path = output_dir / entry_filename + test_path = output_dir / f"{cli_name}.test.ts" + include_test = not args.no_test + project_root = find_project_root(output_dir) or find_project_root(Path.cwd()) or output_dir + package_manager, manager_root = detect_package_manager_with_root(project_root) + uses_vitest = detect_vitest_usage_in_project(project_root, manager_root) + test_framework = "none" + + replacements = { + "__CLI_NAME__": cli_name, + "__ENTRY_FILE__": f"./{entry_filename}", + } + + try: + entry_template = read_template(entry_template_path) + entry_content = render_template(entry_template, replacements) + write_file(entry_path, entry_content, args.force) + print(f"[OK] Wrote {entry_path}") + + if include_test: + test_template_name, test_framework = choose_test_template(args.mode, package_manager, uses_vitest) + test_template_path = templates_dir / test_template_name + test_template = read_template(test_template_path) + test_content = render_template(test_template, replacements) + write_file(test_path, test_content, args.force) + print(f"[OK] Wrote {test_path}") + except (FileExistsError, FileNotFoundError) as error: + print(f"[ERROR] {error}") + return 1 + + print("\nNext steps:") + run_path = format_run_path(entry_path, Path.cwd()) + test_run_path = format_run_path(test_path, Path.cwd()) + print(f"1. Run: bun {run_path} --help") + if include_test: + test_command = choose_test_command(package_manager, test_framework, test_run_path) + print(f"2. Test: {test_command}") + if test_framework == "bun:test": + print(" Detected Bun without vitest; generated a bun:test starter test.") + else: + print("2. Re-run without --no-test to include a starter test file") + print("3. Adapt commands, flags, and prompts to the user request") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tsconfig.json b/tsconfig.json index e04971ed..aecfb374 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -45,5 +45,5 @@ ] } }, - "exclude": ["**/dist", "**/node_modules"] + "exclude": ["**/dist", "**/node_modules", "**/*.tpl"] } From 400100ad03aa703f75dbffb48940e9da532dc74f Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Thu, 9 Apr 2026 03:39:41 +0200 Subject: [PATCH 15/21] chore: migrate docs tooling to Bun APIs, bump tsgo Replace node:child_process and node:fs with Bun shell ($) and Bun.file/write/spawn in paths.ts and build-meta-descriptions.ts. Pipe dprint via stdin instead of temp files. Resolve package paths through import.meta.resolve for correctness in monorepo. Also: fix Zed biome code-action keys (source. prefix), add *.ts/*.js to dprint associations, bump @typescript/native-preview, add dreamcli-docs tsconfig path mapping. --- .dprint.jsonc | 2 +- .zed/settings.json | 8 +-- apps/docs/.vitepress/data/examples.ts | 2 +- apps/docs/.vitepress/data/paths.ts | 30 ++++++----- apps/docs/.vitepress/data/typedoc.ts | 2 +- apps/docs/package.json | 3 ++ bun.lock | 19 +++---- package.json | 3 +- scripts/build-meta-descriptions.ts | 73 +++++++++++++++------------ tsconfig.json | 4 ++ 10 files changed, 84 insertions(+), 62 deletions(-) mode change 100644 => 100755 scripts/build-meta-descriptions.ts diff --git a/.dprint.jsonc b/.dprint.jsonc index 82e47e2f..f80af8d7 100644 --- a/.dprint.jsonc +++ b/.dprint.jsonc @@ -9,7 +9,7 @@ "lineWidth": 100, "quoteStyle": "single", "css.enabled": true, - "associations": ["!README.md", "!apps/docs/**/*.md", "!apps/docs/.vitepress/twoslash/*.ts", "*.ts.tpl"] + "associations": ["!README.md", "!apps/docs/**/*.md", "!apps/docs/.vitepress/twoslash/*.ts", "*.ts.tpl", "*.ts", "*.js"] }, "markdown": { "textWrap": "maintain", diff --git a/.zed/settings.json b/.zed/settings.json index 650249e6..cc0e1358 100644 --- a/.zed/settings.json +++ b/.zed/settings.json @@ -16,15 +16,15 @@ "languages": { "JavaScript": { "code_actions_on_format": { - "fixAll.biome": true, - "organizeImports.biome": true + "source.fixAll.biome": true, + "source.organizeImports.biome": true }, "language_servers": ["vtsls", "tsgo", "biome", "deno"] }, "TypeScript": { "code_actions_on_format": { - "fixAll.biome": true, - "organizeImports.biome": true + "source.fixAll.biome": true, + "source.organizeImports.biome": true }, "language_servers": ["vtsls", "tsgo", "biome", "deno", "vue-language-server"] } diff --git a/apps/docs/.vitepress/data/examples.ts b/apps/docs/.vitepress/data/examples.ts index 826a4b65..d44ee792 100644 --- a/apps/docs/.vitepress/data/examples.ts +++ b/apps/docs/.vitepress/data/examples.ts @@ -144,7 +144,7 @@ async function parseExample(filePath: string, repoRoot: string): Promise s.trim()); +const dreamcliRoot = fileURLToPath(import.meta.resolve('@kjanat/dreamcli')).split('/src/')[0]!; +const dreamcliPackageJson = fileURLToPath(import.meta.resolve('@kjanat/dreamcli/package.json')); -const rootDir = normalize(`${import.meta.dirname}/../../../..`); +export const rootDirPath = rootdir; -export const rootDirPath = rootDir; -export const docsRoot = `${rootDir}/apps/docs`; -export const examplesRoot = `${rootDir}/examples/standalone`; -export const packageRoot = `${rootDir}/packages/dreamcli`; -export const packageJsonPath = `${packageRoot}/package.json`; -export const tsconfigPath = `${packageRoot}/tsconfig.json`; +export const docsRoot = `${rootdir}/apps/docs`; export const symbolPagesRoot = `${docsRoot}/reference/symbols`; -export const generatedMetaSchemaDescriptionsPath = `${packageRoot}/src/core/json-schema/meta-descriptions.generated.ts`; + +export const examplesRoot = `${rootdir}/examples/standalone`; + +export const packageRoot = dreamcliRoot; +export const packageJsonPath = dreamcliPackageJson; +export const tsconfigPath = `${dreamcliRoot}/tsconfig.json`; + +const metadescPath = 'src/core/json-schema/meta-descriptions.generated.ts'; +export const generatedMetaSchemaDescriptionsPath = `${dreamcliRoot}/${metadescPath}`; /** Git ref for source links. Env override: `DOCS_GIT_REF`. */ -export const gitRef: string = (() => { +export const gitRef = (async (): Promise => { const envRef = process.env['DOCS_GIT_REF']; const trimmedEnvRef = envRef?.trim(); if (trimmedEnvRef !== undefined && trimmedEnvRef.length > 0) { @@ -27,7 +33,7 @@ export const gitRef: string = (() => { } try { - return execSync('git rev-parse HEAD', { encoding: 'utf-8' }).trim(); + return $`git rev-parse HEAD`.text().then((s) => s.trim()); } catch { return 'HEAD'; } diff --git a/apps/docs/.vitepress/data/typedoc.ts b/apps/docs/.vitepress/data/typedoc.ts index b315e4a9..e909c868 100644 --- a/apps/docs/.vitepress/data/typedoc.ts +++ b/apps/docs/.vitepress/data/typedoc.ts @@ -328,7 +328,7 @@ async function collectRawTypeDocProject( entryPoints, entryPointStrategy: 'resolve', plugin: [], - sourceLinkTemplate: `https://github.com/kjanat/dreamcli/blob/${gitRef}/{path}#L{line}`, + sourceLinkTemplate: `https://github.com/kjanat/dreamcli/blob/${await gitRef}/{path}#L{line}`, tsconfig: tsconfigPath, }); const project = await app.convert(); diff --git a/apps/docs/package.json b/apps/docs/package.json index 70bd70e2..07186cfb 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -16,6 +16,9 @@ "./dist/*": "./.vitepress/dist/*", "./vitepress/*": "./.vitepress/*" }, + "files": [ + ".vitepress/dist" + ], "scripts": { "build": "bunx --bun vitepress@next build", "dev": "bunx --bun vitepress@next dev", diff --git a/bun.lock b/bun.lock index 19b796db..405d99da 100644 --- a/bun.lock +++ b/bun.lock @@ -9,6 +9,7 @@ "@kjanat/dreamcli": "workspace:*", "@kjanat/dreamcli-docs": "workspace:*", "@kjanat/gh-project": "workspace:*", + "@typescript/native-preview": "catalog:", "dprint": "catalog:", "knip": "catalog:", "wrangler": "catalog:", @@ -114,7 +115,7 @@ "@types/bun": "^1.3.0", "@types/deno": "^2.5.0", "@types/node": ">=22.0.0, <23.0.0", - "@typescript/native-preview": "^7.0.0-dev.20260406.1", + "@typescript/native-preview": "^7.0.0-dev.20260408.1", "@vitest/coverage-v8": "^4.1.2", "dprint": "^0.53.2", "floating-vue": "^5.2.2", @@ -681,21 +682,21 @@ "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], - "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260406.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260406.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260406.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260406.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260406.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260406.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260406.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260406.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-hlVajr01Y/ZmI9iZ7A6BgPxqXccGqxuc/PmVNdanr/LZdtsH9q11y2H3NFMaOrbPlDoeWxHvGUT3wsZllCphyg=="], + "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260408.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260408.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260408.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260408.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260408.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260408.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260408.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260408.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-N0MZLEUnAoP/aRVk7MY119LDsESkbtEwIw+YeXi/jjx2XCqf7ni3GxIVsUYtf/troyuSedq3V/OUrkoCh5A9gA=="], - "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260406.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-q6AMrDHlD6dQHpRuGOewhvKTCBDWRgJ42678+muvHbdHkBafRSUSBRiYasUp8cInK22jlkVwNLqQn6j7Sl9zVg=="], + "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260408.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-YcPczNLfPDB13eUBYHkTOkL7HyWqqqEhho4eSxhAvigZuxvtHQ1uyILIvLVAwipEVzhJ8QciKmLdLucpfi4XyA=="], - "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260406.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-3v8LplbhJwY4GlBawgJt4ydn0sYeowGMniGiPMBl38ioYAIJOriuBvAk+S/gbOoIfLjMLq0L65fnQN+w9+i5ag=="], + "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260408.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cHqkDg53xxxz21MThLBf4vx1kyIpRPEYNdEiQlvu9O35Tth49+aub6F+/YEMd9MG4TYZmxh1bEjkjErTUIElpA=="], - "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260406.1", "", { "os": "linux", "cpu": "arm" }, "sha512-KLa4bK2BxnQwc9uefI8rtaso3cNiRI5Y19z9Jx7UzFJS4YaxtFp5cVjfy4FlQ55ixtUExmCJH7GhSzuVeFl/Jw=="], + "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260408.1", "", { "os": "linux", "cpu": "arm" }, "sha512-w26Gv9yq9LIYIhxjkQC+i0wBPDdQdX+H06ZhyVRL5grKWTIsk9Xwjp9mDRB/dGlXBKcvnM25JH16OyAA0rFH3A=="], - "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260406.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-hRY2czBKisYtcbwgl8HZBA7u/KKUumNlL0X2OpCK1BtQzKbHXAXi1HxUCPbwgHu4v6uGibvniny0BPA6MVrHDA=="], + "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260408.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-iHG0FEXq/QFsn+qlTPllxdcbvfQ9aRYggy4lc1z0+f11Nyk4YDNCSiR8WW7pbnOTx/VreGbbXhlpuJXTidqL8g=="], - "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260406.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Cbcy+lSctRHNmqvLl+l8RgomL0qX3wxEPKCOIdQ/ooicsIPFbkK57Cwdhw3RSpJ+Xb2LzLdneA2Q1Vg+f/Nwxg=="], + "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260408.1", "", { "os": "linux", "cpu": "x64" }, "sha512-hMcUlUIzYbvbdq6j/B4RPL+kZR917NGnE9AgPZ7dJ92yamH/7LGT1Mnlc6McUx31yqTFBFHdTc7Cfx+ynua7Iw=="], - "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260406.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-IFIkbYABge7f83A16awJJWUCrDG1Lw4//NCdU927i/CjgxG09q4ZJeVXcIbZQ5lJWwraiSTa6AMqvhF/tnR2KQ=="], + "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260408.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-avJWIEKSx4rdBLZD1FOOTuxTU51dQfYb3jZvZMaXD4thJjq+6eSwfzu2elwL36AZDlnaxggGjB5nBxp0t54iOA=="], - "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260406.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Jk7wP6SPaELTGY+ijvpude+dmXX9WeuLQLk9qjevQXTusFVcT8vjvepxJVshSJ1+Thmxy1t9v4l1pHnM3XUMjw=="], + "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260408.1", "", { "os": "win32", "cpu": "x64" }, "sha512-gpvEHkF/WoxkA3711c4uWNCZO9WAuwrq49COdNwxgOTzYHnMc1yCj8CpkCUJwU0f/Ydwp2s6/efn6gTMvtckPg=="], "@typescript/vfs": ["@typescript/vfs@1.6.4", "", { "dependencies": { "debug": "^4.4.3" }, "peerDependencies": { "typescript": "*" } }, "sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ=="], diff --git a/package.json b/package.json index 48e5acfd..9a50ebc4 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@kjanat/dreamcli": "workspace:*", "@kjanat/dreamcli-docs": "workspace:*", "@kjanat/gh-project": "workspace:*", + "@typescript/native-preview": "catalog:", "dprint": "catalog:", "knip": "catalog:", "wrangler": "catalog:" @@ -78,7 +79,7 @@ "@types/bun": "^1.3.0", "@types/deno": "^2.5.0", "@types/node": ">=22.0.0, <23.0.0", - "@typescript/native-preview": "^7.0.0-dev.20260406.1", + "@typescript/native-preview": "^7.0.0-dev.20260408.1", "@vitest/coverage-v8": "^4.1.2", "floating-vue": "^5.2.2", "mermaid": "^11.14.0", diff --git a/scripts/build-meta-descriptions.ts b/scripts/build-meta-descriptions.ts old mode 100644 new mode 100755 index 4035d230..ad07967a --- a/scripts/build-meta-descriptions.ts +++ b/scripts/build-meta-descriptions.ts @@ -9,54 +9,61 @@ * @module */ -import { readFile, rm, writeFile } from 'node:fs/promises'; -import { dirname, join } from 'node:path'; - +import { error, log } from 'node:console'; +import { relative } from 'node:path'; +import { cwd, exit } from 'node:process'; import { collectPublicApiIndex } from '@kjanat/dreamcli-docs/vitepress/data/api-index.ts'; import { - buildDefinitionMetaSchemaDescriptions, - renderDefinitionMetaSchemaDescriptions, + buildDefinitionMetaSchemaDescriptions as bdDefMetaSchDesc, + renderDefinitionMetaSchemaDescriptions as rdrDefMetaSchDesc, } from '@kjanat/dreamcli-docs/vitepress/data/meta-schema-descriptions.ts'; import { - generatedMetaSchemaDescriptionsPath, + generatedMetaSchemaDescriptionsPath as genMetaSchDescPaths, packageJsonPath, } from '@kjanat/dreamcli-docs/vitepress/data/paths.ts'; import { collectTypeDocModel } from '@kjanat/dreamcli-docs/vitepress/data/typedoc.ts'; +import { argv, file, spawn, write } from 'bun'; + +log(new Date().toISOString(), relative(cwd(), import.meta.path), 'generating meta-descriptions'); const publicApi = await collectPublicApiIndex(packageJsonPath); -const typeDoc = await collectTypeDocModel(packageJsonPath, publicApi); -const metaSchemaDescriptions = buildDefinitionMetaSchemaDescriptions(typeDoc.normalized); -const rendered = await formatGeneratedSource( - renderDefinitionMetaSchemaDescriptions(metaSchemaDescriptions), -); -const checkMode = Bun.argv.includes('--check'); +const typedocModel = await collectTypeDocModel(packageJsonPath, publicApi); +const metaSchemaDescriptions = bdDefMetaSchDesc(typedocModel.normalized); +const rendered = await fmtGenSrc(rdrDefMetaSchDesc(metaSchemaDescriptions)); +const checkMode = argv.includes('--check'); + +const relGenPath = relative(cwd(), genMetaSchDescPaths); if (checkMode) { - const existing = await readFile(generatedMetaSchemaDescriptionsPath, 'utf8'); + const existing = await file(genMetaSchDescPaths).text(); + if (existing !== rendered) { - console.error( - '✗ src/core/json-schema/meta-descriptions.generated.ts is out of date. Run `bun run meta-descriptions`.', + error( + new Date().toISOString(), + `✗ ${relGenPath} is out of date. Run \`bun run meta-descriptions\`.`, ); - process.exit(1); + exit(1); } - console.log('✓ src/core/json-schema/meta-descriptions.generated.ts is up to date'); - process.exit(0); + + log(new Date().toISOString(), `✓ ${relGenPath} is up to date`); + exit(0); } -await writeFile(generatedMetaSchemaDescriptionsPath, rendered); -console.log('✓ src/core/json-schema/meta-descriptions.generated.ts updated'); - -async function formatGeneratedSource(source: string): Promise { - const tempFilePath = join( - dirname(generatedMetaSchemaDescriptionsPath), - '.meta-descriptions.generated.tmp.ts', - ); - - try { - await writeFile(tempFilePath, source); - await Bun.$`bunx --bun dprint fmt ${tempFilePath}`.quiet(); - return await readFile(tempFilePath, 'utf8'); - } finally { - await rm(tempFilePath, { force: true }); +await write(genMetaSchDescPaths, rendered); +log(new Date().toISOString(), `✓ ${relGenPath} updated`); + +async function fmtGenSrc(source: string): Promise { + const proc = spawn(['bunx', '--bun', 'dprint', 'fmt', '--stdin', 'file.ts'], { + stdin: new Blob([source]), + stdout: 'pipe', + stderr: 'inherit', + }); + + const [formatted, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]); + + if (exitCode !== 0) { + throw new Error(`dprint exited with code ${exitCode}`); } + + return formatted; } diff --git a/tsconfig.json b/tsconfig.json index aecfb374..8689268a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -42,6 +42,10 @@ "@kjanat/dreamcli/package.json": [ "./packages/dreamcli/package.json", "../../packages/dreamcli/package.json" + ], + "@kjanat/dreamcli-docs": [ + "./apps/docs/src/index.ts", + "../../apps/docs/src/index.ts" ] } }, From 75e51708012eaa1375868d2bdc97e4621c573632 Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Thu, 9 Apr 2026 13:24:11 +0200 Subject: [PATCH 16/21] refactor(docs): centralize paths, drop async Bun shell deps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consolidate all project path constants in paths.ts and re-export them — config.ts and source-artifacts.ts now import instead of recomputing. Replace Bun.$`git …` with synchronous execSync and normalize() so paths resolve without runtime async or Bun APIs. Make gitRef synchronous (no reason for it to be a promise). --- apps/docs/.vitepress/config.ts | 10 +++-- apps/docs/.vitepress/data/paths.ts | 40 +++++++++---------- .../vite-plugins/source-artifacts.ts | 7 +--- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts index b846794c..e5e2ec07 100644 --- a/apps/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -1,4 +1,3 @@ -import { normalize } from 'node:path'; import { env } from 'node:process'; import pkg from '@kjanat/dreamcli/package.json' with { type: 'json' }; import { transformerTwoslash } from '@shikijs/vitepress-twoslash'; @@ -8,7 +7,12 @@ import jsr from '../../../packages/dreamcli/deno.json' with { type: 'json' }; import tsc from '../../../tsconfig.json' with { type: 'json' }; import { collectPublicApiIndex } from './data/api-index.ts'; import { collectExampleMeta } from './data/examples.ts'; -import { examplesRoot, packageJsonPath } from './data/paths.ts'; +import { + examplesRoot, + packageJsonPath, + packageRoot, + rootDirPath as projectRoot, +} from './data/paths.ts'; import { collectCaseInsensitiveCollisions, toCollisionKey, @@ -17,8 +21,6 @@ import { import { dreamcliDocsPlugin, shikiClasses } from './vite-plugins'; import { fixTsProcessedLinkcode, transformerJSDocTags } from './vite-plugins/shiki-jsdoc-tags.ts'; -const projectRoot = normalize(`${import.meta.dirname}/../../..`); -const packageRoot = normalize(`${projectRoot}/packages/dreamcli`); const exampleMeta = await collectExampleMeta(examplesRoot); const apiIndex = await collectPublicApiIndex(packageJsonPath); const symbolRoutes = new Map(); diff --git a/apps/docs/.vitepress/data/paths.ts b/apps/docs/.vitepress/data/paths.ts index a76d63d4..05d9cd3c 100644 --- a/apps/docs/.vitepress/data/paths.ts +++ b/apps/docs/.vitepress/data/paths.ts @@ -3,29 +3,29 @@ * * @module */ -/** biome-ignore-all lint/style/noNonNullAssertion: explanation */ -import { $, fileURLToPath } from 'bun'; -const rootdir = await $`git rev-parse --show-toplevel`.text().then((s) => s.trim()); -const dreamcliRoot = fileURLToPath(import.meta.resolve('@kjanat/dreamcli')).split('/src/')[0]!; -const dreamcliPackageJson = fileURLToPath(import.meta.resolve('@kjanat/dreamcli/package.json')); - -export const rootDirPath = rootdir; - -export const docsRoot = `${rootdir}/apps/docs`; +import { execSync } from 'node:child_process'; +import { normalize } from 'node:path'; + +const rootDir = normalize(`${import.meta.dirname}/../../../..`); + +export const rootDirPath = rootDir; +export const rootTsconfigPath = `${rootDir}/tsconfig.json`; +export const docsRoot = `${rootDir}/apps/docs`; +export const examplesRoot = `${rootDir}/examples/standalone`; +export const packageRoot = `${rootDir}/packages/dreamcli`; +export const packageJsonPath = `${packageRoot}/package.json`; +export const packageDenoJsonPath = `${packageRoot}/deno.json`; +export const tsconfigPath = `${packageRoot}/tsconfig.json`; +export const definitionSchemaPath = `${packageRoot}/dreamcli.schema.json`; +export const emitDefinitionSchemaPath = `${packageRoot}/scripts/emit-definition-schema.ts`; export const symbolPagesRoot = `${docsRoot}/reference/symbols`; - -export const examplesRoot = `${rootdir}/examples/standalone`; - -export const packageRoot = dreamcliRoot; -export const packageJsonPath = dreamcliPackageJson; -export const tsconfigPath = `${dreamcliRoot}/tsconfig.json`; - -const metadescPath = 'src/core/json-schema/meta-descriptions.generated.ts'; -export const generatedMetaSchemaDescriptionsPath = `${dreamcliRoot}/${metadescPath}`; +export const generatedMetaSchemaDescriptionsPath = `${packageRoot}/src/core/json-schema/meta-descriptions.generated.ts`; +export const toolsRoot = `${rootDir}/tools`; +export const skillsRoot = `${rootDir}/skills`; /** Git ref for source links. Env override: `DOCS_GIT_REF`. */ -export const gitRef = (async (): Promise => { +export const gitRef: string = (() => { const envRef = process.env['DOCS_GIT_REF']; const trimmedEnvRef = envRef?.trim(); if (trimmedEnvRef !== undefined && trimmedEnvRef.length > 0) { @@ -33,7 +33,7 @@ export const gitRef = (async (): Promise => { } try { - return $`git rev-parse HEAD`.text().then((s) => s.trim()); + return execSync('git rev-parse HEAD', { encoding: 'utf-8' }).trim(); } catch { return 'HEAD'; } diff --git a/apps/docs/.vitepress/vite-plugins/source-artifacts.ts b/apps/docs/.vitepress/vite-plugins/source-artifacts.ts index 34fc732b..f5e6d835 100644 --- a/apps/docs/.vitepress/vite-plugins/source-artifacts.ts +++ b/apps/docs/.vitepress/vite-plugins/source-artifacts.ts @@ -9,15 +9,12 @@ * @module */ -import { normalize } from 'node:path'; import { pathToFileURL } from 'node:url'; import type { Plugin } from 'vitepress'; -const rootDir = normalize(`${import.meta.dirname}/../../../..`); -const packageRoot = `${rootDir}/packages/dreamcli`; -const definitionSchemaPath = `${packageRoot}/dreamcli.schema.json`; -const emitDefinitionSchemaPath = `${packageRoot}/scripts/emit-definition-schema.ts`; +import { definitionSchemaPath, emitDefinitionSchemaPath, packageRoot } from '../data/paths.ts'; + const emitDefinitionSchemaUrl = pathToFileURL(emitDefinitionSchemaPath).href; export function sourceArtifactsPlugin(): Plugin { From 8aa03e878d087cd54e237a25b92ce7d72f19546b Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Thu, 9 Apr 2026 17:30:39 +0200 Subject: [PATCH 17/21] chore: force bun install, use hoisted linker Switch install.auto to "force" so bun install always runs on bun run, and set linker to "hoisted" for broader tool compat. --- bun.lock | 238 ++++++++++++++-------------------------------------- bunfig.toml | 3 +- 2 files changed, 63 insertions(+), 178 deletions(-) diff --git a/bun.lock b/bun.lock index 405d99da..ce56f8a2 100644 --- a/bun.lock +++ b/bun.lock @@ -3,7 +3,7 @@ "configVersion": 1, "workspaces": { "": { - "name": "@kjanat/dreamcli", + "name": "dreamcli-monorepo", "devDependencies": { "@biomejs/biome": "catalog:", "@kjanat/dreamcli": "workspace:*", @@ -174,15 +174,15 @@ "@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.2", "", {}, "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA=="], - "@chevrotain/cst-dts-gen": ["@chevrotain/cst-dts-gen@11.1.2", "", { "dependencies": { "@chevrotain/gast": "11.1.2", "@chevrotain/types": "11.1.2", "lodash-es": "4.17.23" } }, "sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q=="], + "@chevrotain/cst-dts-gen": ["@chevrotain/cst-dts-gen@12.0.0", "", { "dependencies": { "@chevrotain/gast": "12.0.0", "@chevrotain/types": "12.0.0" } }, "sha512-fSL4KXjTl7cDgf0B5Rip9Q05BOrYvkJV/RrBTE/bKDN096E4hN/ySpcBK5B24T76dlQ2i32Zc3PAE27jFnFrKg=="], - "@chevrotain/gast": ["@chevrotain/gast@11.1.2", "", { "dependencies": { "@chevrotain/types": "11.1.2", "lodash-es": "4.17.23" } }, "sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g=="], + "@chevrotain/gast": ["@chevrotain/gast@12.0.0", "", { "dependencies": { "@chevrotain/types": "12.0.0" } }, "sha512-1ne/m3XsIT8aEdrvT33so0GUC+wkctpUPK6zU9IlOyJLUbR0rg4G7ZiApiJbggpgPir9ERy3FRjT6T7lpgetnQ=="], - "@chevrotain/regexp-to-ast": ["@chevrotain/regexp-to-ast@11.1.2", "", {}, "sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw=="], + "@chevrotain/regexp-to-ast": ["@chevrotain/regexp-to-ast@12.0.0", "", {}, "sha512-p+EW9MaJwgaHguhoqwOtx/FwuGr+DnNn857sXWOi/mClXIkPGl3rn7hGNWvo31HA3vyeQxjqe+H36yZJwYU8cA=="], - "@chevrotain/types": ["@chevrotain/types@11.1.2", "", {}, "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw=="], + "@chevrotain/types": ["@chevrotain/types@12.0.0", "", {}, "sha512-S+04vjFQKeuYw0/eW3U52LkAHQsB1ASxsPGsLPUyQgrZ2iNNibQrsidruDzjEX2JYfespXMG0eZmXlhA6z7nWA=="], - "@chevrotain/utils": ["@chevrotain/utils@11.1.2", "", {}, "sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA=="], + "@chevrotain/utils": ["@chevrotain/utils@12.0.0", "", {}, "sha512-lB59uJoaGIfOOL9knQqQRfhl9g7x8/wqFkp13zTdkRu1huG9kg6IJs1O8hqj9rs6h7orGxHJUKb+mX3rPbWGhA=="], "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.2", "", {}, "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ=="], @@ -228,11 +228,11 @@ "@dprint/win32-x64": ["@dprint/win32-x64@0.53.2", "", { "os": "win32", "cpu": "x64" }, "sha512-xdOOm4ZG9pqKdnVvgFMp8/c9Ylkt2LcTFqjmxF1CoCZNNYGMUrH60YQl/M9R9wJXSSQOv6K+7Ub+hOWcIlxIjw=="], - "@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="], + "@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], - "@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="], + "@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], - "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="], + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], @@ -296,7 +296,7 @@ "@iarna/toml": ["@iarna/toml@2.2.5", "", {}, "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="], - "@iconify-json/simple-icons": ["@iconify-json/simple-icons@1.2.76", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-lLRlA8yaf+1L5VCPRvR9lynoSklsddKHEylchmZJKdj/q2xVQ1ZAEJ8SCQlv9cbgtMefnlyM98U+8Si2aoFZPA=="], + "@iconify-json/simple-icons": ["@iconify-json/simple-icons@1.2.77", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-oaENvo6C3BkAEWMlcQA3XemxU9v2SFOTlApSUCODAkIu1haeLCjzrmH3HgmGqjRnJjM+LevO8sA+MgdMHBFBDA=="], "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], @@ -372,7 +372,7 @@ "@mermaid-js/parser": ["@mermaid-js/parser@1.1.0", "", { "dependencies": { "langium": "^4.0.0" } }, "sha512-gxK9ZX2+Fex5zu8LhRQoMeMPEHbc73UKZ0FQ54YrQtUxE1VVhMwzeNtKRPAu5aXks4FasbMe4xB4bWrmq6Jlxw=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.2", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], @@ -682,21 +682,21 @@ "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], - "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260408.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260408.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260408.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260408.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260408.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260408.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260408.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260408.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-N0MZLEUnAoP/aRVk7MY119LDsESkbtEwIw+YeXi/jjx2XCqf7ni3GxIVsUYtf/troyuSedq3V/OUrkoCh5A9gA=="], + "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260409.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260409.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260409.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260409.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260409.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260409.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260409.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260409.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-CV1HEMGo1xCySwUJbCQOF+mmrTue8KTJ1Od2kKWhcbOpu8fPBfaqIpbAM6tGLcNEykEjMMTYHc/VTLbMgxdScQ=="], - "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260408.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-YcPczNLfPDB13eUBYHkTOkL7HyWqqqEhho4eSxhAvigZuxvtHQ1uyILIvLVAwipEVzhJ8QciKmLdLucpfi4XyA=="], + "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260409.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GcRRnaoeZVrbC47woQ/2t3vPoQcTSjsWPEAQGtwNSdw7Z9TKxG4ES22ghJIQXd3ncTRCMJ+XELnnuqxVutkJ9w=="], - "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260408.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cHqkDg53xxxz21MThLBf4vx1kyIpRPEYNdEiQlvu9O35Tth49+aub6F+/YEMd9MG4TYZmxh1bEjkjErTUIElpA=="], + "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260409.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-7s8DXAa0Xpu/8PEjYIc4I36Ju7eVpoz9k3E+3WQdOF8pIPWYohiOj+zi68m9XYQck+rnkjUFo26ThVKqVetoMA=="], - "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260408.1", "", { "os": "linux", "cpu": "arm" }, "sha512-w26Gv9yq9LIYIhxjkQC+i0wBPDdQdX+H06ZhyVRL5grKWTIsk9Xwjp9mDRB/dGlXBKcvnM25JH16OyAA0rFH3A=="], + "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260409.1", "", { "os": "linux", "cpu": "arm" }, "sha512-fOa07JBUXQpEPq+024g346inYZ2xp63ELuoRq6J0jwDWQ/ftCCuvdQNMncwFhsm1qlMdKT3S68NrnSxX16hiaw=="], - "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260408.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-iHG0FEXq/QFsn+qlTPllxdcbvfQ9aRYggy4lc1z0+f11Nyk4YDNCSiR8WW7pbnOTx/VreGbbXhlpuJXTidqL8g=="], + "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260409.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cGTzTUqRGlIDwdtkDy6qTrvrqpe27W4CdgnFn0FpxpiWnaIi3wqjlzQ1grtqrqainw/yuPy5hn/I86sQgN6nvA=="], - "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260408.1", "", { "os": "linux", "cpu": "x64" }, "sha512-hMcUlUIzYbvbdq6j/B4RPL+kZR917NGnE9AgPZ7dJ92yamH/7LGT1Mnlc6McUx31yqTFBFHdTc7Cfx+ynua7Iw=="], + "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260409.1", "", { "os": "linux", "cpu": "x64" }, "sha512-lQrbc/BJKBxQrR1ttBDU5sYY1Hb2moFQgHL20T6nbapNqGpK4pzy64p+NK39O93D4omiCSk04pkchBCVrMPSAg=="], - "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260408.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-avJWIEKSx4rdBLZD1FOOTuxTU51dQfYb3jZvZMaXD4thJjq+6eSwfzu2elwL36AZDlnaxggGjB5nBxp0t54iOA=="], + "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260409.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-kmCafMo1xZlYx+9WnfpeZJ2tnB/CcJdR8QPX7j9vqcpe51D7b7Intmr921dD48KGpVh5YgjQ1MEFE5mjGqGMaA=="], - "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260408.1", "", { "os": "win32", "cpu": "x64" }, "sha512-gpvEHkF/WoxkA3711c4uWNCZO9WAuwrq49COdNwxgOTzYHnMc1yCj8CpkCUJwU0f/Ydwp2s6/efn6gTMvtckPg=="], + "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260409.1", "", { "os": "win32", "cpu": "x64" }, "sha512-WRd+JpQipTsE15QgYr3w7J0f1NKvGcq2QEgmcq8hB0WZA1X2WhQopNu+MpPQ3tdDD42VjMhm8ZoB8HpuOoXK5w=="], "@typescript/vfs": ["@typescript/vfs@1.6.4", "", { "dependencies": { "debug": "^4.4.3" }, "peerDependencies": { "typescript": "*" } }, "sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ=="], @@ -706,21 +706,21 @@ "@vitejs/plugin-vue": ["@vitejs/plugin-vue@6.0.5", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-rc.2" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", "vue": "^3.2.25" } }, "sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg=="], - "@vitest/coverage-v8": ["@vitest/coverage-v8@4.1.2", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.1.2", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.2.0", "magicast": "^0.5.2", "obug": "^2.1.1", "std-env": "^4.0.0-rc.1", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "@vitest/browser": "4.1.2", "vitest": "4.1.2" }, "optionalPeers": ["@vitest/browser"] }, "sha512-sPK//PHO+kAkScb8XITeB1bf7fsk85Km7+rt4eeuRR3VS1/crD47cmV5wicisJmjNdfeokTZwjMk4Mj2d58Mgg=="], + "@vitest/coverage-v8": ["@vitest/coverage-v8@4.1.4", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.1.4", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.2.0", "magicast": "^0.5.2", "obug": "^2.1.1", "std-env": "^4.0.0-rc.1", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "@vitest/browser": "4.1.4", "vitest": "4.1.4" }, "optionalPeers": ["@vitest/browser"] }, "sha512-x7FptB5oDruxNPDNY2+S8tCh0pcq7ymCe1gTHcsp733jYjrJl8V1gMUlVysuCD9Kz46Xz9t1akkv08dPcYDs1w=="], - "@vitest/expect": ["@vitest/expect@4.1.2", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.2", "@vitest/utils": "4.1.2", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-gbu+7B0YgUJ2nkdsRJrFFW6X7NTP44WlhiclHniUhxADQJH5Szt9mZ9hWnJPJ8YwOK5zUOSSlSvyzRf0u1DSBQ=="], + "@vitest/expect": ["@vitest/expect@4.1.4", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.4", "@vitest/utils": "4.1.4", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww=="], - "@vitest/mocker": ["@vitest/mocker@4.1.2", "", { "dependencies": { "@vitest/spy": "4.1.2", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-Ize4iQtEALHDttPRCmN+FKqOl2vxTiNUhzobQFFt/BM1lRUTG7zRCLOykG/6Vo4E4hnUdfVLo5/eqKPukcWW7Q=="], + "@vitest/mocker": ["@vitest/mocker@4.1.4", "", { "dependencies": { "@vitest/spy": "4.1.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg=="], - "@vitest/pretty-format": ["@vitest/pretty-format@4.1.2", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-dwQga8aejqeuB+TvXCMzSQemvV9hNEtDDpgUKDzOmNQayl2OG241PSWeJwKRH3CiC+sESrmoFd49rfnq7T4RnA=="], + "@vitest/pretty-format": ["@vitest/pretty-format@4.1.4", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A=="], - "@vitest/runner": ["@vitest/runner@4.1.2", "", { "dependencies": { "@vitest/utils": "4.1.2", "pathe": "^2.0.3" } }, "sha512-Gr+FQan34CdiYAwpGJmQG8PgkyFVmARK8/xSijia3eTFgVfpcpztWLuP6FttGNfPLJhaZVP/euvujeNYar36OQ=="], + "@vitest/runner": ["@vitest/runner@4.1.4", "", { "dependencies": { "@vitest/utils": "4.1.4", "pathe": "^2.0.3" } }, "sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ=="], - "@vitest/snapshot": ["@vitest/snapshot@4.1.2", "", { "dependencies": { "@vitest/pretty-format": "4.1.2", "@vitest/utils": "4.1.2", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-g7yfUmxYS4mNxk31qbOYsSt2F4m1E02LFqO53Xpzg3zKMhLAPZAjjfyl9e6z7HrW6LvUdTwAQR3HHfLjpko16A=="], + "@vitest/snapshot": ["@vitest/snapshot@4.1.4", "", { "dependencies": { "@vitest/pretty-format": "4.1.4", "@vitest/utils": "4.1.4", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw=="], - "@vitest/spy": ["@vitest/spy@4.1.2", "", {}, "sha512-DU4fBnbVCJGNBwVA6xSToNXrkZNSiw59H8tcuUspVMsBDBST4nfvsPsEHDHGtWRRnqBERBQu7TrTKskmjqTXKA=="], + "@vitest/spy": ["@vitest/spy@4.1.4", "", {}, "sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ=="], - "@vitest/utils": ["@vitest/utils@4.1.2", "", { "dependencies": { "@vitest/pretty-format": "4.1.2", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-xw2/TiX82lQHA06cgbqRKFb5lCAy3axQ4H4SoUFhUsg+wztiet+co86IAMDtF6Vm1hc7J6j09oh/rgDn+JdKIQ=="], + "@vitest/utils": ["@vitest/utils@4.1.4", "", { "dependencies": { "@vitest/pretty-format": "4.1.4", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw=="], "@volar/language-core": ["@volar/language-core@2.4.28", "", { "dependencies": { "@volar/source-map": "2.4.28" } }, "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ=="], @@ -798,9 +798,9 @@ "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], - "chevrotain": ["chevrotain@11.1.2", "", { "dependencies": { "@chevrotain/cst-dts-gen": "11.1.2", "@chevrotain/gast": "11.1.2", "@chevrotain/regexp-to-ast": "11.1.2", "@chevrotain/types": "11.1.2", "@chevrotain/utils": "11.1.2", "lodash-es": "4.17.23" } }, "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg=="], + "chevrotain": ["chevrotain@12.0.0", "", { "dependencies": { "@chevrotain/cst-dts-gen": "12.0.0", "@chevrotain/gast": "12.0.0", "@chevrotain/regexp-to-ast": "12.0.0", "@chevrotain/types": "12.0.0", "@chevrotain/utils": "12.0.0" } }, "sha512-csJvb+6kEiQaqo1woTdSAuOWdN0WTLIydkKrBnS+V5gZz0oqBrp4kQ35519QgK6TpBThiG3V1vNSHlIkv4AglQ=="], - "chevrotain-allstar": ["chevrotain-allstar@0.3.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^11.0.0" } }, "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw=="], + "chevrotain-allstar": ["chevrotain-allstar@0.4.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^12.0.0" } }, "sha512-PvVJm3oGqrveUVW2Vt/eZGeiAIsJszYweUcYwcskg9e+IubNYKKD+rHHem7A6XVO22eDAL+inxNIGAzZ/VIWlA=="], "cjs-module-lexer": ["cjs-module-lexer@1.4.3", "", {}, "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q=="], @@ -818,7 +818,7 @@ "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - "cytoscape": ["cytoscape@3.33.1", "", {}, "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ=="], + "cytoscape": ["cytoscape@3.33.2", "", {}, "sha512-sj4HXd3DokGhzZAdjDejGvTPLqlt84vNFN8m7bGsOzDY5DyVcxIb2ejIXat2Iy7HxWhdT/N1oKyheJ5YdpsGuw=="], "cytoscape-cose-bilkent": ["cytoscape-cose-bilkent@4.1.0", "", { "dependencies": { "cose-base": "^1.0.0" }, "peerDependencies": { "cytoscape": "^3.2.0" } }, "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ=="], @@ -896,7 +896,7 @@ "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], - "defu": ["defu@6.1.6", "", {}, "sha512-f8mefEW4WIVg4LckePx3mALjQSPQgFlg9U8yaPdlsbdYcHQyj9n2zL2LJEA52smeYxOvmd/nB7TpMtHGMTHcug=="], + "defu": ["defu@6.1.7", "", {}, "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ=="], "delaunator": ["delaunator@5.1.0", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ=="], @@ -972,7 +972,7 @@ "import-without-cache": ["import-without-cache@0.2.5", "", {}, "sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A=="], - "internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="], + "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], @@ -998,9 +998,9 @@ "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], - "knip": ["knip@6.3.0", "", { "dependencies": { "@nodelib/fs.walk": "^1.2.3", "fast-glob": "^3.3.3", "formatly": "^0.3.0", "get-tsconfig": "4.13.7", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.121.0", "oxc-resolver": "^11.19.1", "picocolors": "^1.1.1", "picomatch": "^4.0.1", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "unbash": "^2.2.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-g6dVPoTw6iNm3cubC5IWxVkVsd0r5hXhTBTbAGIEQN53GdA2ZM/slMTPJ7n5l8pBebNQPHpxjmKxuR4xVQ2/hQ=="], + "knip": ["knip@6.3.1", "", { "dependencies": { "@nodelib/fs.walk": "^1.2.3", "fast-glob": "^3.3.3", "formatly": "^0.3.0", "get-tsconfig": "4.13.7", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.121.0", "oxc-resolver": "^11.19.1", "picocolors": "^1.1.1", "picomatch": "^4.0.1", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "unbash": "^2.2.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-22kLJloVcOVOAudCxlFOC0ICAMme7dKsS7pVTEnrmyKGpswb8ieznvAiSKUeFVDJhb01ect6dkDc1Ha1g1sPpg=="], - "langium": ["langium@4.2.1", "", { "dependencies": { "chevrotain": "~11.1.1", "chevrotain-allstar": "~0.3.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.1.0" } }, "sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ=="], + "langium": ["langium@4.2.2", "", { "dependencies": { "@chevrotain/regexp-to-ast": "~12.0.0", "chevrotain": "~12.0.0", "chevrotain-allstar": "~0.4.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.1.0" } }, "sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ=="], "layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="], @@ -1034,7 +1034,7 @@ "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], - "lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], + "lru-cache": ["lru-cache@11.3.3", "", {}, "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ=="], "lunr": ["lunr@2.3.9", "", {}, "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="], @@ -1180,7 +1180,7 @@ "points-on-path": ["points-on-path@0.2.1", "", { "dependencies": { "path-data-parser": "0.1.0", "points-on-curve": "0.2.0" } }, "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g=="], - "postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], + "postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], @@ -1250,9 +1250,9 @@ "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], - "tinyexec": ["tinyexec@1.0.4", "", {}, "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw=="], + "tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="], - "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="], "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], @@ -1314,11 +1314,11 @@ "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - "vite": ["vite@8.0.7", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.13", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-P1PbweD+2/udplnThz3btF4cf6AgPky7kk23RtHUkJIU5BIxwPprhRGmOAHs6FTI7UiGbTNrgNP6jSYD6JaRnw=="], + "vite": ["vite@8.0.8", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.15", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw=="], "vitepress": ["vitepress@2.0.0-alpha.17", "", { "dependencies": { "@docsearch/css": "^4.5.3", "@docsearch/js": "^4.5.3", "@docsearch/sidepanel-js": "^4.5.3", "@iconify-json/simple-icons": "^1.2.69", "@shikijs/core": "^3.22.0", "@shikijs/transformers": "^3.22.0", "@shikijs/types": "^3.22.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^6.0.4", "@vue/devtools-api": "^8.0.5", "@vue/shared": "^3.5.27", "@vueuse/core": "^14.2.0", "@vueuse/integrations": "^14.2.0", "focus-trap": "^8.0.0", "mark.js": "8.11.1", "minisearch": "^7.2.0", "shiki": "^3.22.0", "vite": "^7.3.1", "vue": "^3.5.27" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "oxc-minify": "*", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3", "oxc-minify", "postcss"], "bin": { "vitepress": "bin/vitepress.js" } }, "sha512-Z3VPUpwk/bHYqt1uMVOOK1/4xFiWQov1GNc2FvMdz6kvje4JRXEOngVI9C+bi5jeedMSHiA4dwKkff1NCvbZ9Q=="], - "vitest": ["vitest@4.1.2", "", { "dependencies": { "@vitest/expect": "4.1.2", "@vitest/mocker": "4.1.2", "@vitest/pretty-format": "4.1.2", "@vitest/runner": "4.1.2", "@vitest/snapshot": "4.1.2", "@vitest/spy": "4.1.2", "@vitest/utils": "4.1.2", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.2", "@vitest/browser-preview": "4.1.2", "@vitest/browser-webdriverio": "4.1.2", "@vitest/ui": "4.1.2", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-xjR1dMTVHlFLh98JE3i/f/WePqJsah4A0FK9cc8Ehp9Udk0AZk6ccpIZhh1qJ/yxVWRZ+Q54ocnD8TXmkhspGg=="], + "vitest": ["vitest@4.1.4", "", { "dependencies": { "@vitest/expect": "4.1.4", "@vitest/mocker": "4.1.4", "@vitest/pretty-format": "4.1.4", "@vitest/runner": "4.1.4", "@vitest/snapshot": "4.1.4", "@vitest/spy": "4.1.4", "@vitest/utils": "4.1.4", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.4", "@vitest/browser-preview": "4.1.4", "@vitest/browser-webdriverio": "4.1.4", "@vitest/coverage-istanbul": "4.1.4", "@vitest/coverage-v8": "4.1.4", "@vitest/ui": "4.1.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/coverage-istanbul", "@vitest/coverage-v8", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg=="], "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], @@ -1364,10 +1364,6 @@ "@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], - "@chevrotain/cst-dts-gen/lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="], - - "@chevrotain/gast/lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="], - "@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], "@gerrit0/mini-shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="], @@ -1378,8 +1374,6 @@ "@gerrit0/mini-shiki/@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], - "@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], - "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], "@vitejs/plugin-vue/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.2", "", {}, "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw=="], @@ -1396,8 +1390,6 @@ "ast-kit/@babel/parser": ["@babel/parser@8.0.0-rc.3", "", { "dependencies": { "@babel/types": "^8.0.0-rc.3" }, "bin": "./bin/babel-parser.js" }, "sha512-B20dvP3MfNc/XS5KKCHy/oyWl5IA6Cn9YjXRdDlCjNmUFrjvLXMNUfQq/QUy9fnG2gYkKKcrto2YaF9B32ToOQ=="], - "chevrotain/lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="], - "cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="], "d3-dsv/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], @@ -1414,9 +1406,7 @@ "rolldown-plugin-dts/@babel/types": ["@babel/types@8.0.0-rc.3", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0-rc.3", "@babel/helper-validator-identifier": "^8.0.0-rc.3" } }, "sha512-mOm5ZrYmphGfqVWoH5YYMTITb3cDXsFgmvFlvkvWDMsR9X8RFnt7a0Wb6yNIdoFsiMO9WjYLq+U/FMtqIYAF8Q=="], - "tsx/esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], - - "vite/rolldown": ["rolldown@1.0.0-rc.13", "", { "dependencies": { "@oxc-project/types": "=0.123.0", "@rolldown/pluginutils": "1.0.0-rc.13" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.13", "@rolldown/binding-darwin-arm64": "1.0.0-rc.13", "@rolldown/binding-darwin-x64": "1.0.0-rc.13", "@rolldown/binding-freebsd-x64": "1.0.0-rc.13", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.13", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.13", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.13", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.13", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.13", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.13", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.13", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.13" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-bvVj8YJmf0rq4pSFmH7laLa6pYrhghv3PRzrCdRAr23g66zOKVJ4wkvFtgohtPLWmthgg8/rkaqRHrpUEh0Zbw=="], + "vite/rolldown": ["rolldown@1.0.0-rc.15", "", { "dependencies": { "@oxc-project/types": "=0.124.0", "@rolldown/pluginutils": "1.0.0-rc.15" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-x64": "1.0.0-rc.15", "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g=="], "vitepress/@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], @@ -1426,9 +1416,7 @@ "vitepress/shiki": ["shiki@3.23.0", "", { "dependencies": { "@shikijs/core": "3.23.0", "@shikijs/engine-javascript": "3.23.0", "@shikijs/engine-oniguruma": "3.23.0", "@shikijs/langs": "3.23.0", "@shikijs/themes": "3.23.0", "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA=="], - "vitepress/vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], - - "vitest/vite": ["vite@8.0.3", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.12", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ=="], + "vitepress/vite": ["vite@7.3.2", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg=="], "@babel/generator/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.3", "", {}, "sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA=="], @@ -1436,95 +1424,45 @@ "cytoscape-fcose/cose-base/layout-base": ["layout-base@2.0.1", "", {}, "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="], + "d3-sankey/d3-array/internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="], + "d3-sankey/d3-shape/d3-path": ["d3-path@1.0.9", "", {}, "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="], "rolldown-plugin-dts/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.3", "", {}, "sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA=="], - "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.7", "", { "os": "aix", "cpu": "ppc64" }, "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg=="], - - "tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.7", "", { "os": "android", "cpu": "arm" }, "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ=="], - - "tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.7", "", { "os": "android", "cpu": "arm64" }, "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ=="], - - "tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.7", "", { "os": "android", "cpu": "x64" }, "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg=="], - - "tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw=="], - - "tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ=="], - - "tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.7", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w=="], - - "tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.7", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ=="], - - "tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.7", "", { "os": "linux", "cpu": "arm" }, "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA=="], - - "tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A=="], - - "tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.7", "", { "os": "linux", "cpu": "ia32" }, "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg=="], - - "tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q=="], - - "tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw=="], - - "tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.7", "", { "os": "linux", "cpu": "ppc64" }, "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ=="], - - "tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ=="], - - "tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.7", "", { "os": "linux", "cpu": "s390x" }, "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw=="], - - "tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.7", "", { "os": "linux", "cpu": "x64" }, "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA=="], - - "tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w=="], - - "tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.7", "", { "os": "none", "cpu": "x64" }, "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw=="], - - "tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.7", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A=="], - - "tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.7", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg=="], - - "tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw=="], - - "tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.7", "", { "os": "sunos", "cpu": "x64" }, "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA=="], - - "tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA=="], + "vite/rolldown/@oxc-project/types": ["@oxc-project/types@0.124.0", "", {}, "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg=="], - "tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.7", "", { "os": "win32", "cpu": "ia32" }, "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw=="], + "vite/rolldown/@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.15", "", { "os": "android", "cpu": "arm64" }, "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA=="], - "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="], + "vite/rolldown/@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.15", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg=="], - "vite/rolldown/@oxc-project/types": ["@oxc-project/types@0.123.0", "", {}, "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew=="], + "vite/rolldown/@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.15", "", { "os": "darwin", "cpu": "x64" }, "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw=="], - "vite/rolldown/@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.13", "", { "os": "android", "cpu": "arm64" }, "sha512-5ZiiecKH2DXAVJTNN13gNMUcCDg4Jy8ZjbXEsPnqa248wgOVeYRX0iqXXD5Jz4bI9BFHgKsI2qmyJynstbmr+g=="], + "vite/rolldown/@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.15", "", { "os": "freebsd", "cpu": "x64" }, "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw=="], - "vite/rolldown/@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-tz/v/8G77seu8zAB3A5sK3UFoOl06zcshEzhUO62sAEtrEuW/H1CcyoupOrD+NbQJytYgA4CppXPzlrmp4JZKA=="], + "vite/rolldown/@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm" }, "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA=="], - "vite/rolldown/@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-8DakphqOz8JrMYWTJmWA+vDJxut6LijZ8Xcdc4flOlAhU7PNVwo2MaWBF9iXjJAPo5rC/IxEFZDhJ3GC7NHvug=="], + "vite/rolldown/@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w=="], - "vite/rolldown/@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.13", "", { "os": "freebsd", "cpu": "x64" }, "sha512-4wBQFfjDuXYN/SVI8inBF3Aa+isq40rc6VMFbk5jcpolUBTe5cYnMsHZ51nFWsx3PVyyNN3vgoESki0Hmr/4BA=="], + "vite/rolldown/@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ=="], - "vite/rolldown/@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.13", "", { "os": "linux", "cpu": "arm" }, "sha512-JW/e4yPIXLms+jmnbwwy5LA/LxVwZUWLN8xug+V200wzaVi5TEGIWQlh8o91gWYFxW609euI98OCCemmWGuPrw=="], + "vite/rolldown/@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "ppc64" }, "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ=="], - "vite/rolldown/@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZfKWpXiUymDnavepCaM6KG/uGydJ4l2nBmMxg60Ci4CbeefpqjPWpfaZM7PThOhk2dssqBAcwLc6rAyr0uTdXg=="], + "vite/rolldown/@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "s390x" }, "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ=="], - "vite/rolldown/@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-bmRg3O6Z0gq9yodKKWCIpnlH051sEfdVwt+6m5UDffAQMUUqU0xjnQqqAUm+Gu7ofAAly9DqiQDtKu2nPDEABA=="], + "vite/rolldown/@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "x64" }, "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA=="], - "vite/rolldown/@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "ppc64" }, "sha512-8Wtnbw4k7pMYN9B/mOEAsQ8HOiq7AZ31Ig4M9BKn2So4xRaFEhtCSa4ZJaOutOWq50zpgR4N5+L/opnlaCx8wQ=="], + "vite/rolldown/@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.15", "", { "os": "linux", "cpu": "x64" }, "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw=="], - "vite/rolldown/@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "s390x" }, "sha512-D/0Nlo8mQuxSMohNJUF2lDXWRsFDsHldfRRgD9bRgktj+EndGPj4DOV37LqDKPYS+osdyhZEH7fTakTAEcW7qg=="], + "vite/rolldown/@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.15", "", { "os": "none", "cpu": "arm64" }, "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg=="], - "vite/rolldown/@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.13", "", { "os": "linux", "cpu": "x64" }, "sha512-eRrPvat2YaVQcwwKi/JzOP6MKf1WRnOCr+VaI3cTWz3ZoLcP/654z90lVCJ4dAuMEpPdke0n+qyAqXDZdIC4rA=="], + "vite/rolldown/@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.15", "", { "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.3" }, "cpu": "none" }, "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q=="], - "vite/rolldown/@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.13", "", { "os": "linux", "cpu": "x64" }, "sha512-PsdONiFRp8hR8KgVjTWjZ9s7uA3uueWL0t74/cKHfM4dR5zXYv4AjB8BvA+QDToqxAFg4ZkcVEqeu5F7inoz5w=="], + "vite/rolldown/@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15", "", { "os": "win32", "cpu": "arm64" }, "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA=="], - "vite/rolldown/@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.13", "", { "os": "none", "cpu": "arm64" }, "sha512-hCNXgC5dI3TVOLrPT++PKFNZ+1EtS0mLQwfXXXSUD/+rGlB65gZDwN/IDuxLpQP4x8RYYHqGomlUXzpO8aVI2w=="], + "vite/rolldown/@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.15", "", { "os": "win32", "cpu": "x64" }, "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g=="], - "vite/rolldown/@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.13", "", { "dependencies": { "@emnapi/core": "1.9.1", "@emnapi/runtime": "1.9.1", "@napi-rs/wasm-runtime": "^1.1.2" }, "cpu": "none" }, "sha512-viLS5C5et8NFtLWw9Sw3M/w4vvnVkbWkO7wSNh3C+7G1+uCkGpr6PcjNDSFcNtmXY/4trjPBqUfcOL+P3sWy/g=="], - - "vite/rolldown/@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-Fqa3Tlt1xL4wzmAYxGNFV36Hb+VfPc9PYU+E25DAnswXv3ODDu/yyWjQDbXMo5AGWkQVjLgQExuVu8I/UaZhPQ=="], - - "vite/rolldown/@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.13", "", { "os": "win32", "cpu": "x64" }, "sha512-/pLI5kPkGEi44TDlnbio3St/5gUFeN51YWNAk/Gnv6mEQBOahRBh52qVFVBpmrnU01n2yysvBML9Ynu7K4kGAQ=="], - - "vite/rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.13", "", {}, "sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA=="], + "vite/rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.15", "", {}, "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g=="], "vitepress/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA=="], @@ -1534,60 +1472,6 @@ "vitepress/shiki/@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="], - "vitepress/vite/esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], - "ast-kit/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.3", "", {}, "sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA=="], - - "vitepress/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.7", "", { "os": "aix", "cpu": "ppc64" }, "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg=="], - - "vitepress/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.7", "", { "os": "android", "cpu": "arm" }, "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ=="], - - "vitepress/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.7", "", { "os": "android", "cpu": "arm64" }, "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ=="], - - "vitepress/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.7", "", { "os": "android", "cpu": "x64" }, "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg=="], - - "vitepress/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw=="], - - "vitepress/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ=="], - - "vitepress/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.7", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w=="], - - "vitepress/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.7", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ=="], - - "vitepress/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.7", "", { "os": "linux", "cpu": "arm" }, "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA=="], - - "vitepress/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A=="], - - "vitepress/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.7", "", { "os": "linux", "cpu": "ia32" }, "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg=="], - - "vitepress/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q=="], - - "vitepress/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw=="], - - "vitepress/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.7", "", { "os": "linux", "cpu": "ppc64" }, "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ=="], - - "vitepress/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ=="], - - "vitepress/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.7", "", { "os": "linux", "cpu": "s390x" }, "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw=="], - - "vitepress/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.7", "", { "os": "linux", "cpu": "x64" }, "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA=="], - - "vitepress/vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w=="], - - "vitepress/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.7", "", { "os": "none", "cpu": "x64" }, "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw=="], - - "vitepress/vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.7", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A=="], - - "vitepress/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.7", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg=="], - - "vitepress/vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw=="], - - "vitepress/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.7", "", { "os": "sunos", "cpu": "x64" }, "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA=="], - - "vitepress/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA=="], - - "vitepress/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.7", "", { "os": "win32", "cpu": "ia32" }, "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw=="], - - "vitepress/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="], } } diff --git a/bunfig.toml b/bunfig.toml index d4b94701..e3c7b983 100644 --- a/bunfig.toml +++ b/bunfig.toml @@ -4,7 +4,8 @@ telemetry = false smol = false [install] -auto = "auto" +auto = "force" +linker = "hoisted" # We don't have ANY dependencies, so this doesn't matter. I want up-to-date devtools. exact = false lockfile.save = true From c517f92a221b96e54d40b344960171fd2d9c1e17 Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Thu, 23 Apr 2026 07:21:02 +0200 Subject: [PATCH 18/21] feat(docs): add Cloudflare Web Analytics beacon --- apps/docs/.vitepress/config.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts index e5e2ec07..941ec1bf 100644 --- a/apps/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -111,6 +111,14 @@ export default defineConfig({ }, ], ['meta', { name: 'theme-color', content: '#f8f3e7' }], + [ + 'script', + { + defer: '', + src: 'https://static.cloudflareinsights.com/beacon.min.js', + 'data-cf-beacon': '{"token": "ee9b04d68d3740bebb38f5c20629b7c1"}', + }, + ], ], themeConfig: { logo: { From 3a7406ba59696c3108ce12d6bcbdd34b3382aeeb Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Wed, 29 Apr 2026 05:21:06 +0200 Subject: [PATCH 19/21] chore: refresh formatting and workspace toolchain Move `package.json` sorting into a dprint plugin and bump the formatting and workspace tooling deps so repo formatting stays consistent in one pass. Stop re-awaiting the resolved TypeDoc git ref and regenerate the affected PowerShell, example, and schema artifacts after the formatter refresh. --- .dprint.jsonc | 5 +- apps/docs/.vitepress/data/typedoc.ts | 2 +- bun.lock | 208 ++++++++--------- examples/pwsh-demo/src/main.test.ts | 5 +- examples/pwsh-demo/src/main.ts | 18 +- package.json | 10 +- .../src/core/completion/shells/powershell.ts | 4 +- .../meta-descriptions.generated.ts | 213 ++++++++++-------- 8 files changed, 239 insertions(+), 226 deletions(-) mode change 100644 => 100755 examples/pwsh-demo/src/main.ts diff --git a/.dprint.jsonc b/.dprint.jsonc index bbffafde..8e43a7d7 100644 --- a/.dprint.jsonc +++ b/.dprint.jsonc @@ -37,10 +37,6 @@ "exec": { "cwd": "${configDir}", "commands": [ - { - "command": "bun x sort-package-json --stdin", - "fileNames": ["package.json"], - }, { "command": "bun x tombi format - --stdin-filename {{file_path}}", "exts": ["toml"], @@ -69,5 +65,6 @@ "https://plugins.dprint.dev/prettier-0.69.0.json@3de5c7cf5cdbae7b214f404b12503c92e7964be5fffd442b998e6d5fe4ba0e7b", "https://plugins.dprint.dev/ruff-0.7.10.wasm", "https://plugins.dprint.dev/json-0.21.3.wasm", + "https://plugins.dprint.dev/kjanat/sortpackagejson-0.1.0.wasm", ], } diff --git a/apps/docs/.vitepress/data/typedoc.ts b/apps/docs/.vitepress/data/typedoc.ts index 4419546b..73f3a9b1 100644 --- a/apps/docs/.vitepress/data/typedoc.ts +++ b/apps/docs/.vitepress/data/typedoc.ts @@ -328,7 +328,7 @@ async function collectRawTypeDocProject( entryPoints, entryPointStrategy: 'resolve', plugin: [], - sourceLinkTemplate: `https://github.com/kjanat/dreamcli/blob/${await gitRef}/{path}#L{line}`, + sourceLinkTemplate: `https://github.com/kjanat/dreamcli/blob/${gitRef}/{path}#L{line}`, tsconfig: normalizePath(tsconfigPath), }); const project = await app.convert(); diff --git a/bun.lock b/bun.lock index ce56f8a2..e6993c4c 100644 --- a/bun.lock +++ b/bun.lock @@ -53,6 +53,20 @@ "typescript": "catalog:", }, }, + "examples/pwsh-demo": { + "name": "pwsh-demo", + "version": "0.0.0-example", + "bin": { + "pwsh-demo": "src/main.ts", + }, + "dependencies": { + "@kjanat/dreamcli": "link:@kjanat/dreamcli", + }, + "devDependencies": { + "@types/bun": "catalog:", + "typescript": "catalog:", + }, + }, "examples/standalone": { "name": "@kjanat/dreamcli-examples", "version": "0.0.0", @@ -108,18 +122,18 @@ }, "catalog": { "@arethetypeswrong/core": "^0.18.2", - "@biomejs/biome": "2.4.10", + "@biomejs/biome": "2.4.13", "@iarna/toml": "^2.2.5", "@shikijs/transformers": "^4.0.2", "@shikijs/vitepress-twoslash": "^4.0.2", - "@types/bun": "^1.3.0", + "@types/bun": "^1.3.12", "@types/deno": "^2.5.0", "@types/node": ">=22.0.0, <23.0.0", - "@typescript/native-preview": "^7.0.0-dev.20260408.1", + "@typescript/native-preview": "^7.0.0-dev.20260428.1", "@vitest/coverage-v8": "^4.1.2", - "dprint": "^0.53.2", + "dprint": "^0.54.0", "floating-vue": "^5.2.2", - "knip": "^6.3.0", + "knip": "^6.7.0", "mermaid": "^11.14.0", "publint": "^0.3.18", "tsdown": "^0.21.7", @@ -130,7 +144,7 @@ "vitepress": "^2.0.0-alpha.17", "vitest": "^4.1.2", "vue": "^3.5.32", - "wrangler": "^4.81.0", + "wrangler": "^4.86.0", "yaml": "^2.8.3", }, "packages": { @@ -152,23 +166,23 @@ "@bcoe/v8-coverage": ["@bcoe/v8-coverage@1.0.2", "", {}, "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA=="], - "@biomejs/biome": ["@biomejs/biome@2.4.10", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.10", "@biomejs/cli-darwin-x64": "2.4.10", "@biomejs/cli-linux-arm64": "2.4.10", "@biomejs/cli-linux-arm64-musl": "2.4.10", "@biomejs/cli-linux-x64": "2.4.10", "@biomejs/cli-linux-x64-musl": "2.4.10", "@biomejs/cli-win32-arm64": "2.4.10", "@biomejs/cli-win32-x64": "2.4.10" }, "bin": { "biome": "bin/biome" } }, "sha512-xxA3AphFQ1geij4JTHXv4EeSTda1IFn22ye9LdyVPoJU19fNVl0uzfEuhsfQ4Yue/0FaLs2/ccVi4UDiE7R30w=="], + "@biomejs/biome": ["@biomejs/biome@2.4.13", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.13", "@biomejs/cli-darwin-x64": "2.4.13", "@biomejs/cli-linux-arm64": "2.4.13", "@biomejs/cli-linux-arm64-musl": "2.4.13", "@biomejs/cli-linux-x64": "2.4.13", "@biomejs/cli-linux-x64-musl": "2.4.13", "@biomejs/cli-win32-arm64": "2.4.13", "@biomejs/cli-win32-x64": "2.4.13" }, "bin": { "biome": "bin/biome" } }, "sha512-gLXOwkOBBg0tr7bDsqlkIh4uFeKuMjxvqsrb1Tukww1iDmHcfr4Uu8MoQxp0Rcte+69+osRNWXwHsu/zxT6XqA=="], - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-vuzzI1cWqDVzOMIkYyHbKqp+AkQq4K7k+UCXWpkYcY/HDn1UxdsbsfgtVpa40shem8Kax4TLDLlx8kMAecgqiw=="], + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2KImO1jhNFBa2oWConyr0x6flxbQpGKv6902uGXpYM62Xyem8U80j441SyUJ8KyngsmKbQjeIv1q2CQfDkNnYg=="], - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-14fzASRo+BPotwp7nWULy2W5xeUyFnTaq1V13Etrrxkrih+ez/2QfgFm5Ehtf5vSjtgx/IJycMMpn5kPd5ZNaA=="], + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-BKrJklbaFN4p1Ts4kPBczo+PkbsHQg57kmJ+vON9u2t6uN5okYHaSr7h/MutPCWQgg2lglaWoSmm+zhYW+oOkg=="], - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-7MH1CMW5uuxQ/s7FLST63qF8B3Hgu2HRdZ7tA1X1+mk+St4JOuIrqdhIBnnyqeyWJNI+Bww7Es5QZ0wIc1Cmkw=="], + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-NzkUDSqfvMBrPplKgVr3aXLHZ2NEELvvF4vZxXulEylKWIGqlvNEcwUcj9OLrn75TD3lJ/GIqCVlBwd1MZCuYQ=="], - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-WrJY6UuiSD/Dh+nwK2qOTu8kdMDlLV3dLMmychIghHPAysWFq1/DGC1pVZx8POE3ZkzKR3PUUnVrtZfMfaJjyQ=="], + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-U5MsuBQW25dXaYtqWWSPM3P96H6Y+fHuja3TQpMNnylocHW0tEbtFTDlUj6oM+YJLntvEkQy4grBvQNUD4+RCg=="], - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.10", "", { "os": "linux", "cpu": "x64" }, "sha512-tZLvEEi2u9Xu1zAqRjTcpIDGVtldigVvzug2fTuPG0ME/g8/mXpRPcNgLB22bGn6FvLJpHHnqLnwliOu8xjYrg=="], + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.13", "", { "os": "linux", "cpu": "x64" }, "sha512-Az3ZZedYRBo9EQzNnD9SxFcR1G5QsGo6VEc2hIyVPZ1rdKwee/7E9oeBBZFpE8Z44ekxsDQBqbiWGW5ShOhUSQ=="], - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.10", "", { "os": "linux", "cpu": "x64" }, "sha512-kDTi3pI6PBN6CiczsWYOyP2zk0IJI08EWEQyDMQWW221rPaaEz6FvjLhnU07KMzLv8q3qSuoB93ua6inSQ55Tw=="], + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.13", "", { "os": "linux", "cpu": "x64" }, "sha512-Z601MienRgTBDza/+u2CH3RSrWoXo9rtr8NK6A4KJzqGgfxx+H3VlyLgTJ4sRo40T3pIsqpTmiOQEvYzQvBRvQ=="], - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-umwQU6qPzH+ISTf/eHyJ/QoQnJs3V9Vpjz2OjZXe9MVBZ7prgGafMy7yYeRGnlmDAn87AKTF3Q6weLoMGpeqdQ=="], + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-Px9PS2B5/Q183bUwy/5VHqp3J2lzdOCeVGzMpphYfl8oSa7VDCqenBdqWpy6DCy/en4Rbf/Y1RieZF6dJPcc9A=="], - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.10", "", { "os": "win32", "cpu": "x64" }, "sha512-aW/JU5GuyH4uxMrNYpoC2kjaHlyJGLgIa3XkhPEZI0uKhZhJZU8BuEyJmvgzSPQNGozBwWjC972RaNdcJ9KyJg=="], + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.13", "", { "os": "win32", "cpu": "x64" }, "sha512-tTcMkXyBrmHi9BfrD2VNHs/5rYIUKETqsBlYOvSAABwBkJhSDVb5e7wPukftsQbO3WzQkXe6kaztC6WtUOXSoQ=="], "@braidai/lang": ["@braidai/lang@1.1.2", "", {}, "sha512-qBcknbBufNHlui137Hft8xauQMTZDKdophmLFv05r2eNmdIv/MlPuP4TdUknHG68UdWLgVZwgxVe735HzJNIwA=="], @@ -186,17 +200,17 @@ "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.2", "", {}, "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ=="], - "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "1.20260301.1 || ~1.20260302.1 || ~1.20260303.1 || ~1.20260304.1 || >1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-8ovsRpwzPoEqPUzoErAYVv8l3FMZNeBVQfJTvtzP4AgLSRGZISRfuChFxHWUQd3n6cnrwkuTGxT+2cGo8EsyYg=="], + "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.1", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": ">1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw=="], - "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260405.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-EbmdBcmeIGogKG4V1odSWQe7z4rHssUD4iaXv0cXA22/MFrzH3iQT0R+FJFyhucGtih/9B9E+6j0QbSQD8xT3w=="], + "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260426.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ch7DqsmYzSQRTY87pZpsGsFVz9VVBnLPnCBOHxKt1HH25a7oMu1w1PbPWqVmE0VerCLsj/TScX7Ob3v6E14TZw=="], - "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260405.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-r44r418bOQtoP+Odu+L/BQM9q5cRSXRd1N167PgZQIo4MlqzTwHO4L0wwXhxbcV/PF46rrQre/uTFS8R0R+xSQ=="], + "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260426.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0m0U8vaPRH25SpKjbSyRql6gmPe4rCsETRV2WW0qBnuMdKNr5Vh5/Uez80xVrfiCCRMTULGeg63Nqg2vg6CDOA=="], - "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260405.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Aaq3RWnaTCzMBo77wC8fjOx+SFdO/rlcXa6HAf+PJs51LyMISFOBCJKqSlS6Irphen0WHHxFKPHUO9bjfj8g2g=="], + "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260426.1", "", { "os": "linux", "cpu": "x64" }, "sha512-C8LlC8uSYzg49y51n++75esxZmMp+Uz1OKHHA/4lkv6rjOTbcHQJuEwSLppjybVIXpv7A8MBhbu9iyCTvyv1mw=="], - "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260405.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-Lbp9Z2wiMzy3Sji3YwMHK5WDlejsH3jF4swAFEv7+jIf3NowZHga3GzwTypNRmcwnfz/XrqQ7Hc0Ul9OoU/lCw=="], + "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260426.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-ESVp/OIFMAqjQsa8BOP2BQQz5Vpfv6ncN6lNnIuNeOgsISQBdYk+LA60bwQHMud9tvmnSYtONp1zkZ8OQz+x6w=="], - "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260405.1", "", { "os": "win32", "cpu": "x64" }, "sha512-FhE0kt93kj5JnSPVqi4BAXpQQENyKnuSOoJLd35mkMMGhtPrwv5EsReJdck0S8hUocCBlb+U0RmP8ta6k41HjQ=="], + "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260426.1", "", { "os": "win32", "cpu": "x64" }, "sha512-d3Xj/IjINRgNVwH+eKhpUn4xkkcEewbWXbOvBlapiirKWh5zl9m0Epi3qOqmjyRYK6MICqIGXg4qZBEt0lxudw=="], "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], @@ -206,27 +220,27 @@ "@docsearch/sidepanel-js": ["@docsearch/sidepanel-js@4.6.2", "", {}, "sha512-Pni85AP/GwRj7fFg8cBJp0U04tzbueBvWSd3gysgnOsVnQVSZwSYncfErUScLE1CAtR+qocPDFjmYR9AMRNJtQ=="], - "@dprint/darwin-arm64": ["@dprint/darwin-arm64@0.53.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ecKRF+mFE59layJPpX5AnYN7a9XNovX3f5QlPSdr+BmweoarOV2ieODyJklD5Tob9WiMv8jQyXYak5QH7fxByg=="], + "@dprint/darwin-arm64": ["@dprint/darwin-arm64@0.54.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-yqRI4enH+BDp+4+ZsPVdZM5h873JK1lN7li9l9A5u4C4cvh1oEsiBWAzEPccRkJ2ctF8LgaizBSxO38sqEVYbw=="], - "@dprint/darwin-x64": ["@dprint/darwin-x64@0.53.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-sHe7bsPU9BXnBPovjsq+98S1g64W7ZhyfGKMSVMTwP1BCL+IqOltfd5p7xTvAaRkL8cwRzqPYlj+kmCf24Qydw=="], + "@dprint/darwin-x64": ["@dprint/darwin-x64@0.54.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-W9BARpgHypcQwatg5mnHaCpX6pLX5dBxxiv+tZKruhOmq8MKYOrAYDXlceMuHSowmWREfUF5yL4SRgXDGI6WQw=="], - "@dprint/linux-arm64-glibc": ["@dprint/linux-arm64-glibc@0.53.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-K0aj5bLtPlSsTDAtLwEjwDGPIVpc8lgmvpLzf6IdASJn1kMkowPoZSCNUvmUUJTTmANscMugLsi9XGVbBzkE6Q=="], + "@dprint/linux-arm64-glibc": ["@dprint/linux-arm64-glibc@0.54.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-VhM7p70VFuNqxZMdiv1e+nMboPj/hMFlTIBWrRaX7+6VThs9mJr9+94wrUeXgfnfsyaEKSbRFa/dru1PINoSNw=="], - "@dprint/linux-arm64-musl": ["@dprint/linux-arm64-musl@0.53.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-209yb6BGMiohPuB12wgnodULEs3JC1epLaHyN5s2XpDU7rWi6WqWkzeSuuN2TTAbDz4Z51tqe5KJSRsF0yi+Dg=="], + "@dprint/linux-arm64-musl": ["@dprint/linux-arm64-musl@0.54.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-QS1A74Lv60/L9oemHCzbHgOLbV2smSJG5IxS5fjf8ZWetyUt918WDzIHBilz/+uiB+OlW2UVTsm952UG0YOrLw=="], - "@dprint/linux-loong64-glibc": ["@dprint/linux-loong64-glibc@0.53.2", "", { "os": "linux", "cpu": "none" }, "sha512-IngXJ6c7n/DYd2j1CssLHqxtGILMv0BEQZplx8kIYedGyVbzLSxJu7XpqgThnCuLQjh4elfRkT67Q8g7l//m0Q=="], + "@dprint/linux-loong64-glibc": ["@dprint/linux-loong64-glibc@0.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-8Myka2/0KbhuZnEKL6jagPXTgDKVpd/tfXDRa0oibUBgaqOSku6iRMzHGa/PhqHL+s14Gcp+/cIHz0zU3Tkgug=="], - "@dprint/linux-loong64-musl": ["@dprint/linux-loong64-musl@0.53.2", "", { "os": "linux", "cpu": "none" }, "sha512-ExtcNOjSbXgpoWw5efAO00xYTOlEsEyz58v/HPJzEV5tfn9J7vozSVxTdXLDkTgg+USEQLaZ9qTnXxc1kbraiQ=="], + "@dprint/linux-loong64-musl": ["@dprint/linux-loong64-musl@0.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-/AN3xCuMhC4PK7Pbj7/4zBuhFGr4m0OHV/5uGTfzpkKX/3+AXoyKl7PbT2VlNMGXAK0kuRThfjtx23gIwlWk7Q=="], - "@dprint/linux-riscv64-glibc": ["@dprint/linux-riscv64-glibc@0.53.2", "", { "os": "linux", "cpu": "none" }, "sha512-2UTqXMkIhyK7rYdpBY7tE3x1R36msWjX3lU3MdYM9HauldnsHJx2EhZofIYzHBICH8eziw/W7aY8HWo4oLdJ/A=="], + "@dprint/linux-riscv64-glibc": ["@dprint/linux-riscv64-glibc@0.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-Aw2vXzzwFDpPbXh6ajsSabVCkCc66C3hCyMKprR/IxYvFtjYX80nh1ox0c7iaw6c4HacHMRLGw7FUSXvomPaEQ=="], - "@dprint/linux-x64-glibc": ["@dprint/linux-x64-glibc@0.53.2", "", { "os": "linux", "cpu": "x64" }, "sha512-hO4O7d20IALUCFbFG2H7kvP5Di3/G8fqrMXzX9Fdps4ccM4Kg3Cr9LZ/G+mif4Q9WwwUnkOJ0oXBxeqJ8S65ng=="], + "@dprint/linux-x64-glibc": ["@dprint/linux-x64-glibc@0.54.0", "", { "os": "linux", "cpu": "x64" }, "sha512-zZqj3wQELOX8n6QfT2uuWoMf64Wv0lMXNyam3btm+PKkg0P6a54TPL09Bs9XsViOdxgTcamsiQ7HlErt/LEjIA=="], - "@dprint/linux-x64-musl": ["@dprint/linux-x64-musl@0.53.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XHqYE5nFz1s5Z2J1E9j8JYHE4ISp5KCfaYT7fs4lW14G2B8U/CtutUGWzvP5aYRGfLc6CYGrWgKAQppn846vUQ=="], + "@dprint/linux-x64-musl": ["@dprint/linux-x64-musl@0.54.0", "", { "os": "linux", "cpu": "x64" }, "sha512-it6Qdt06dyW2adbAXpOCb7/KQLxlm4i1UphUAWqWsZk4t3EYetyAza9J0g3Vu9itIWSEIo9MnccgANckQJ6+qw=="], - "@dprint/win32-arm64": ["@dprint/win32-arm64@0.53.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z8N2iwhFN91wK0SlR+oGHGF8rrwOw7BiZTAKwR8E7Fr2lKSTsjbRv3Nr1znk2pHkmRyZ1/6PwzTiVF5sSZcIXQ=="], + "@dprint/win32-arm64": ["@dprint/win32-arm64@0.54.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-F5kjV/6I9YtNOTDWHUpTqM2HHHS510BPL7z4NJuU0nDnaVeks7GwNEltGr56CcsG8XQYhkiAsqZytPu6AhA2hQ=="], - "@dprint/win32-x64": ["@dprint/win32-x64@0.53.2", "", { "os": "win32", "cpu": "x64" }, "sha512-xdOOm4ZG9pqKdnVvgFMp8/c9Ylkt2LcTFqjmxF1CoCZNNYGMUrH60YQl/M9R9wJXSSQOv6K+7Ub+hOWcIlxIjw=="], + "@dprint/win32-x64": ["@dprint/win32-x64@0.54.0", "", { "os": "win32", "cpu": "x64" }, "sha512-AAr2ye/DtgYXDplRoPS+5U++x7T6W4a3I9FvTFWFxziFmUptvAg5G2c4FcXoAduSruhYZJvjDZrLseR2c3IwXg=="], "@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], @@ -372,55 +386,49 @@ "@mermaid-js/parser": ["@mermaid-js/parser@1.1.0", "", { "dependencies": { "langium": "^4.0.0" } }, "sha512-gxK9ZX2+Fex5zu8LhRQoMeMPEHbc73UKZ0FQ54YrQtUxE1VVhMwzeNtKRPAu5aXks4FasbMe4xB4bWrmq6Jlxw=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], - - "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], - - "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], - - "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], - "@oxc-parser/binding-android-arm-eabi": ["@oxc-parser/binding-android-arm-eabi@0.121.0", "", { "os": "android", "cpu": "arm" }, "sha512-n07FQcySwOlzap424/PLMtOkbS7xOu8nsJduKL8P3COGHKgKoDYXwoAHCbChfgFpHnviehrLWIPX0lKGtbEk/A=="], + "@oxc-parser/binding-android-arm-eabi": ["@oxc-parser/binding-android-arm-eabi@0.127.0", "", { "os": "android", "cpu": "arm" }, "sha512-0LC7ye4hvqbIKxAzThzvswgHLFu2AURKzYLeSVvLdu2TBOYWQDmHnTqPLeA597BcUCxiLqLsS4CJ5uoI5WYWCQ=="], - "@oxc-parser/binding-android-arm64": ["@oxc-parser/binding-android-arm64@0.121.0", "", { "os": "android", "cpu": "arm64" }, "sha512-/Dd1xIXboYAicw+twT2utxPD7bL8qh7d3ej0qvaYIMj3/EgIrGR+tSnjCUkiCT6g6uTC0neSS4JY8LxhdSU/sA=="], + "@oxc-parser/binding-android-arm64": ["@oxc-parser/binding-android-arm64@0.127.0", "", { "os": "android", "cpu": "arm64" }, "sha512-b5jtVTH6AU5CJXHNdj7Jj9IEiR9yVjjnwHzPJhGyHGPdcsZSzBCkS9GBbV33niRMvKthDwQRFRJfI4a+k4PvYg=="], - "@oxc-parser/binding-darwin-arm64": ["@oxc-parser/binding-darwin-arm64@0.121.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-A0jNEvv7QMtCO1yk205t3DWU9sWUjQ2KNF0hSVO5W9R9r/R1BIvzG01UQAfmtC0dQm7sCrs5puixurKSfr2bRQ=="], + "@oxc-parser/binding-darwin-arm64": ["@oxc-parser/binding-darwin-arm64@0.127.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-obCE8B7ISKkJidjlhv9xRGJPOSDG2Yu6PRga9Ruaz35uintHxbp1Ki/Yc71wx4rj3Edrm0a1kzG1TAwit0wFpg=="], - "@oxc-parser/binding-darwin-x64": ["@oxc-parser/binding-darwin-x64@0.121.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-SsHzipdxTKUs3I9EOAPmnIimEeJOemqRlRDOp9LIj+96wtxZejF51gNibmoGq8KoqbT1ssAI5po/E3J+vEtXGA=="], + "@oxc-parser/binding-darwin-x64": ["@oxc-parser/binding-darwin-x64@0.127.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-JL6Xb5IwPQT8rUzlpsX7E+AgfcdNklXNPFp8pjCQQ5MQOQo5rtEB2ui+3Hgg9Sn7Y9Egj6YOLLiHhLpdAe12Aw=="], - "@oxc-parser/binding-freebsd-x64": ["@oxc-parser/binding-freebsd-x64@0.121.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-v1APOTkCp+RWOIDAHRoaeW/UoaHF15a60E8eUL6kUQXh+i4K7PBwq2Wi7jm8p0ymID5/m/oC1w3W31Z/+r7HQw=="], + "@oxc-parser/binding-freebsd-x64": ["@oxc-parser/binding-freebsd-x64@0.127.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SDQ/3MQFw58fqQz3Z1PhSKFF3JoCF4gmlNjziDm8X02tTahCw0qJbd7FGPDKw1i4VTBZene9JPyC3mHtSvi+wA=="], - "@oxc-parser/binding-linux-arm-gnueabihf": ["@oxc-parser/binding-linux-arm-gnueabihf@0.121.0", "", { "os": "linux", "cpu": "arm" }, "sha512-PmqPQuqHZyFVWA4ycr0eu4VnTMmq9laOHZd+8R359w6kzuNZPvmmunmNJ8ybkm769A0nCoVp3TJ6dUz7B3FYIQ=="], + "@oxc-parser/binding-linux-arm-gnueabihf": ["@oxc-parser/binding-linux-arm-gnueabihf@0.127.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Av+D1MIqzV0YMGPT9we2SIZaMKD7Cxs4CvXSx/yxaWHewZjYEjScpOf5igc8IILASViw4WTnjlwUdI1KzVtDHQ=="], - "@oxc-parser/binding-linux-arm-musleabihf": ["@oxc-parser/binding-linux-arm-musleabihf@0.121.0", "", { "os": "linux", "cpu": "arm" }, "sha512-vF24htj+MOH+Q7y9A8NuC6pUZu8t/C2Fr/kDOi2OcNf28oogr2xadBPXAbml802E8wRAVfbta6YLDQTearz+jw=="], + "@oxc-parser/binding-linux-arm-musleabihf": ["@oxc-parser/binding-linux-arm-musleabihf@0.127.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Cs2fdJ8cPpFdeebj6p4dag8A4+56hPvZ0AhQQzlaLswGz1tz7bXt1nETLeorrM9+AMcWFFkqxcXwDGfTVidY8g=="], - "@oxc-parser/binding-linux-arm64-gnu": ["@oxc-parser/binding-linux-arm64-gnu@0.121.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-wjH8cIG2Lu/3d64iZpbYr73hREMgKAfu7fqpXjgM2S16y2zhTfDIp8EQjxO8vlDtKP5Rc7waZW72lh8nZtWrpA=="], + "@oxc-parser/binding-linux-arm64-gnu": ["@oxc-parser/binding-linux-arm64-gnu@0.127.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-qdOfTcT6SY8gsJrrV92uyEUyjqMGPpIB5JZUG6QN5dukYd+7/j0kX6MwK1DgQj39jtUYixxPiaRUiEN1+0CXgQ=="], - "@oxc-parser/binding-linux-arm64-musl": ["@oxc-parser/binding-linux-arm64-musl@0.121.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-qT663J/W8yQFw3dtscbEi9LKJevr20V7uWs2MPGTnvNZ3rm8anhhE16gXGpxDOHeg9raySaSHKhd4IGa3YZvuw=="], + "@oxc-parser/binding-linux-arm64-musl": ["@oxc-parser/binding-linux-arm64-musl@0.127.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-EoTCZneNFU/P2qrpEM+RHmQwt+CvDkyGESG6qhr7KaegXLZwePfbrkCDfAk8/rhxbDUVGsZILX+2tqPzFtoFWA=="], - "@oxc-parser/binding-linux-ppc64-gnu": ["@oxc-parser/binding-linux-ppc64-gnu@0.121.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-mYNe4NhVvDBbPkAP8JaVS8lC1dsoJZWH5WCjpw5E+sjhk1R08wt3NnXYUzum7tIiWPfgQxbCMcoxgeemFASbRw=="], + "@oxc-parser/binding-linux-ppc64-gnu": ["@oxc-parser/binding-linux-ppc64-gnu@0.127.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-zALjmZYgxFLHjXeudcDF0xFGNydTAtkAeXAr2EuC17ywCyFxcmQra4w0BMde0Yi/re4Bi4iwEoEXtYN7l6eBLQ=="], - "@oxc-parser/binding-linux-riscv64-gnu": ["@oxc-parser/binding-linux-riscv64-gnu@0.121.0", "", { "os": "linux", "cpu": "none" }, "sha512-+QiFoGxhAbaI/amqX567784cDyyuZIpinBrJNxUzb+/L2aBRX67mN6Jv40pqduHf15yYByI+K5gUEygCuv0z9w=="], + "@oxc-parser/binding-linux-riscv64-gnu": ["@oxc-parser/binding-linux-riscv64-gnu@0.127.0", "", { "os": "linux", "cpu": "none" }, "sha512-fPP8M6zQLS7Jz7o9d5ArUSuAuSK3e+WCYVrCpdzeCOejidtZExJ9tjhDrAd3HEPqARBCPmdpqxESPFqy44vkBQ=="], - "@oxc-parser/binding-linux-riscv64-musl": ["@oxc-parser/binding-linux-riscv64-musl@0.121.0", "", { "os": "linux", "cpu": "none" }, "sha512-9ykEgyTa5JD/Uhv2sttbKnCfl2PieUfOjyxJC/oDL2UO0qtXOtjPLl7H8Kaj5G7p3hIvFgu3YWvAxvE0sqY+hQ=="], + "@oxc-parser/binding-linux-riscv64-musl": ["@oxc-parser/binding-linux-riscv64-musl@0.127.0", "", { "os": "linux", "cpu": "none" }, "sha512-7IcC4Ao02oGpfnjt+X/oF4U2mllo2qoSkw5xxiXNKL9MCTsTiAC6616beOuehdxGcnz1bRoPC1RQ2f1GQDdN+g=="], - "@oxc-parser/binding-linux-s390x-gnu": ["@oxc-parser/binding-linux-s390x-gnu@0.121.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-DB1EW5VHZdc1lIRjOI3bW/wV6R6y0xlfvdVrqj6kKi7Ayu2U3UqUBdq9KviVkcUGd5Oq+dROqvUEEFRXGAM7EQ=="], + "@oxc-parser/binding-linux-s390x-gnu": ["@oxc-parser/binding-linux-s390x-gnu@0.127.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-pbXIhiNFHoqWeqDNLiJ9JkpHz1IM9k4DXa66x+1GTWMG7iLxtkXgE53iiuKSXwmk3zIYmaPVfBvgcAhS583K4Q=="], - "@oxc-parser/binding-linux-x64-gnu": ["@oxc-parser/binding-linux-x64-gnu@0.121.0", "", { "os": "linux", "cpu": "x64" }, "sha512-s4lfobX9p4kPTclvMiH3gcQUd88VlnkMTF6n2MTMDAyX5FPNRhhRSFZK05Ykhf8Zy5NibV4PbGR6DnK7FGNN6A=="], + "@oxc-parser/binding-linux-x64-gnu": ["@oxc-parser/binding-linux-x64-gnu@0.127.0", "", { "os": "linux", "cpu": "x64" }, "sha512-MYCguB9RvBvlSd6gbuNI7QwiLoCCAlGnlRJFPrzLI6U1/9wkC/WK6LtBAUln55H1Ctqw45PWmqrobKoMhsYQzQ=="], - "@oxc-parser/binding-linux-x64-musl": ["@oxc-parser/binding-linux-x64-musl@0.121.0", "", { "os": "linux", "cpu": "x64" }, "sha512-P9KlyTpuBuMi3NRGpJO8MicuGZfOoqZVRP1WjOecwx8yk4L/+mrCRNc5egSi0byhuReblBF2oVoDSMgV9Bj4Hw=="], + "@oxc-parser/binding-linux-x64-musl": ["@oxc-parser/binding-linux-x64-musl@0.127.0", "", { "os": "linux", "cpu": "x64" }, "sha512-5eY0B/bxf1xIUxb4NOTvOI3KWtBQfPWYyKAzgcrCt0mDibSZygVpO1Pz8bkeiSZ5Jj9+M09dkggG3H8I5d0Uyg=="], - "@oxc-parser/binding-openharmony-arm64": ["@oxc-parser/binding-openharmony-arm64@0.121.0", "", { "os": "none", "cpu": "arm64" }, "sha512-R+4jrWOfF2OAPPhj3Eb3U5CaKNAH9/btMveMULIrcNW/hjfysFQlF8wE0GaVBr81dWz8JLgQlsxwctoL78JwXw=="], + "@oxc-parser/binding-openharmony-arm64": ["@oxc-parser/binding-openharmony-arm64@0.127.0", "", { "os": "none", "cpu": "arm64" }, "sha512-Gld0ajrFTUXNtdw20fVBuTQx66FA75nIVg+//pPfR3sXkuABB4mTBhl3r9JNzrJpgW//qiwxf0nWXUWGJSL3UQ=="], - "@oxc-parser/binding-wasm32-wasi": ["@oxc-parser/binding-wasm32-wasi@0.121.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-5TFISkPTymKvsmIlKasPVTPuWxzCcrT8pM+p77+mtQbIZDd1UC8zww4CJcRI46kolmgrEX6QpKO8AvWMVZ+ifw=="], + "@oxc-parser/binding-wasm32-wasi": ["@oxc-parser/binding-wasm32-wasi@0.127.0", "", { "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-T6KVD7rhLzFlwGRXMnxUFfkCZD8FHnb968wVXW1mXzgRFc5RNXOBY2mPPDZ77x5Ln76ltLMgtPg0cOkU1NSrEQ=="], - "@oxc-parser/binding-win32-arm64-msvc": ["@oxc-parser/binding-win32-arm64-msvc@0.121.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-V0pxh4mql4XTt3aiEtRNUeBAUFOw5jzZNxPABLaOKAWrVzSr9+XUaB095lY7jqMf5t8vkfh8NManGB28zanYKw=="], + "@oxc-parser/binding-win32-arm64-msvc": ["@oxc-parser/binding-win32-arm64-msvc@0.127.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Ujvw4X+LD1CCGULcsQcvb4YNVoBGqt+JHgNNzGGaCImELiZLk477ifUH53gIbE7EKd933NdTi25JWEr9K2HwXw=="], - "@oxc-parser/binding-win32-ia32-msvc": ["@oxc-parser/binding-win32-ia32-msvc@0.121.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-4Ob1qvYMPnlF2N9rdmKdkQFdrq16QVcQwBsO8yiPZXof0fHKFF+LmQV501XFbi7lHyrKm8rlJRfQ/M8bZZPVLw=="], + "@oxc-parser/binding-win32-ia32-msvc": ["@oxc-parser/binding-win32-ia32-msvc@0.127.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-0cwxKO7KHQQQfo4Uf4B2SQrhgm+cJaP9OvFFhx52Tkg4bezsacu83GB2/In5bC415Ueeym+kXdnge/57rbSfTw=="], - "@oxc-parser/binding-win32-x64-msvc": ["@oxc-parser/binding-win32-x64-msvc@0.121.0", "", { "os": "win32", "cpu": "x64" }, "sha512-BOp1KCzdboB1tPqoCPXgntgFs0jjeSyOXHzgxVFR7B/qfr3F8r4YDacHkTOUNXtDgM8YwKnkf3rE5gwALYX7NA=="], + "@oxc-parser/binding-win32-x64-msvc": ["@oxc-parser/binding-win32-x64-msvc@0.127.0", "", { "os": "win32", "cpu": "x64" }, "sha512-rOrnSQSCbhI2kowr9XxE7m9a8oQXnBHjnS6j95LxxAnEZ0+Fz20WlRXG4ondQb+ejjt2KOsa65sE6++L6kUd+w=="], - "@oxc-project/types": ["@oxc-project/types@0.121.0", "", {}, "sha512-CGtOARQb9tyv7ECgdAlFxi0Fv7lmzvmlm2rpD/RdijOO9rfk/JvB1CjT8EnoD+tjna/IYgKKw3IV7objRb+aYw=="], + "@oxc-project/types": ["@oxc-project/types@0.127.0", "", {}, "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ=="], "@oxc-resolver/binding-android-arm-eabi": ["@oxc-resolver/binding-android-arm-eabi@11.19.1", "", { "os": "android", "cpu": "arm" }, "sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg=="], @@ -584,7 +592,7 @@ "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], - "@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="], + "@types/bun": ["@types/bun@1.3.13", "", { "dependencies": { "bun-types": "1.3.13" } }, "sha512-9fqXWk5YIHGGnUau9TEi+qdlTYDAnOj+xLCmSTwXfAIqXr2x4tytJb43E9uCvt09zJURKXwAtkoH4nLQfzeTXw=="], "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], @@ -682,21 +690,21 @@ "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], - "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260409.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260409.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260409.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260409.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260409.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260409.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260409.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260409.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-CV1HEMGo1xCySwUJbCQOF+mmrTue8KTJ1Od2kKWhcbOpu8fPBfaqIpbAM6tGLcNEykEjMMTYHc/VTLbMgxdScQ=="], + "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260428.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260428.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260428.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260428.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260428.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260428.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260428.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260428.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-JiM4PYWDGs57TT0mV2KArmaW7BnTkk3XRid79NdG17tfvDbRyg4hBCpKI7vARiQPtxjKrHlxyzxOGDpv5W5T7Q=="], - "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260409.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GcRRnaoeZVrbC47woQ/2t3vPoQcTSjsWPEAQGtwNSdw7Z9TKxG4ES22ghJIQXd3ncTRCMJ+XELnnuqxVutkJ9w=="], + "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260428.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Lll6WmXfgTEj1G3QBIoHlabQwUtJiyhlRgSLksa06QFL5BoA7V+Lu1waa9PtPNZbGsXLDMHodtk/bRQABKuPiw=="], - "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260409.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-7s8DXAa0Xpu/8PEjYIc4I36Ju7eVpoz9k3E+3WQdOF8pIPWYohiOj+zi68m9XYQck+rnkjUFo26ThVKqVetoMA=="], + "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260428.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-WbsBNSHlo+4sGrTxDWdmI7r8x48tCtSCuKdmK62FvVOq58UWAs6sL13Z4Rev4ohLcGHdXC5E/8AIdpLPqDYQpw=="], - "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260409.1", "", { "os": "linux", "cpu": "arm" }, "sha512-fOa07JBUXQpEPq+024g346inYZ2xp63ELuoRq6J0jwDWQ/ftCCuvdQNMncwFhsm1qlMdKT3S68NrnSxX16hiaw=="], + "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260428.1", "", { "os": "linux", "cpu": "arm" }, "sha512-/d/NnZFvEJU67L5mHh+cO3gsfwNCvJ9HGtxGq1KGz1VwTabOIcwLdpTpfsAR39WXzzfh9GJHL28n6GSGZInPow=="], - "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260409.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cGTzTUqRGlIDwdtkDy6qTrvrqpe27W4CdgnFn0FpxpiWnaIi3wqjlzQ1grtqrqainw/yuPy5hn/I86sQgN6nvA=="], + "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260428.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cgcBX/ZBMdepkamLT8g8jQdHe7DZS/s6zTZRof6mvcrnJHlMeUnKoC9UO8/c22IrUMV3n0XPh7R8FYjUP0ll+Q=="], - "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260409.1", "", { "os": "linux", "cpu": "x64" }, "sha512-lQrbc/BJKBxQrR1ttBDU5sYY1Hb2moFQgHL20T6nbapNqGpK4pzy64p+NK39O93D4omiCSk04pkchBCVrMPSAg=="], + "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260428.1", "", { "os": "linux", "cpu": "x64" }, "sha512-4gJCE7wzenx1BH2Vtx2uKWUo8rFxnhGkxNEH1zxbYy/6ASwo+PnOPYmKHAzNE1C3yB5lzw71/vR5p5zyO57Y4A=="], - "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260409.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-kmCafMo1xZlYx+9WnfpeZJ2tnB/CcJdR8QPX7j9vqcpe51D7b7Intmr921dD48KGpVh5YgjQ1MEFE5mjGqGMaA=="], + "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260428.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-yn6Rzbn62L4QTWrp0QgG8al6l/VG7PCPRdbE0vuGDSlKhInlC+Flo4QSc1qA8KHTbpHgl+nEsq9DymiitI4G4g=="], - "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260409.1", "", { "os": "win32", "cpu": "x64" }, "sha512-WRd+JpQipTsE15QgYr3w7J0f1NKvGcq2QEgmcq8hB0WZA1X2WhQopNu+MpPQ3tdDD42VjMhm8ZoB8HpuOoXK5w=="], + "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260428.1", "", { "os": "win32", "cpu": "x64" }, "sha512-T9z13mcMowXmwGjprA2FIR2EEdYZxgqH8+qk7dFZVBlo5vfk41AN/qJfAdN7IsAhEb640MJ8cMN/aiczweZKmA=="], "@typescript/vfs": ["@typescript/vfs@1.6.4", "", { "dependencies": { "debug": "^4.4.3" }, "peerDependencies": { "typescript": "*" } }, "sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ=="], @@ -782,9 +790,7 @@ "brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], - "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], - - "bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="], + "bun-types": ["bun-types@1.3.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-QXKeHLlOLqQX9LgYaHJfzdBaV21T63HhFJnvuRCcjZiaUDpbs5ED1MgxbMra71CsryN/1dAoXuJJJwIv/2drVA=="], "cac": ["cac@7.0.0", "", {}, "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ=="], @@ -908,7 +914,7 @@ "dompurify": ["dompurify@3.3.3", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA=="], - "dprint": ["dprint@0.53.2", "", { "optionalDependencies": { "@dprint/darwin-arm64": "0.53.2", "@dprint/darwin-x64": "0.53.2", "@dprint/linux-arm64-glibc": "0.53.2", "@dprint/linux-arm64-musl": "0.53.2", "@dprint/linux-loong64-glibc": "0.53.2", "@dprint/linux-loong64-musl": "0.53.2", "@dprint/linux-riscv64-glibc": "0.53.2", "@dprint/linux-x64-glibc": "0.53.2", "@dprint/linux-x64-musl": "0.53.2", "@dprint/win32-arm64": "0.53.2", "@dprint/win32-x64": "0.53.2" }, "bin": { "dprint": "bin.cjs" } }, "sha512-3uF+X66vm3UmDG5tbBKUAyetc/FsBn+2fswfVzFlbrIlE2l0BgwRLEssYqW/o93lYn6A39i3lP2+wHA4B+usDg=="], + "dprint": ["dprint@0.54.0", "", { "optionalDependencies": { "@dprint/darwin-arm64": "0.54.0", "@dprint/darwin-x64": "0.54.0", "@dprint/linux-arm64-glibc": "0.54.0", "@dprint/linux-arm64-musl": "0.54.0", "@dprint/linux-loong64-glibc": "0.54.0", "@dprint/linux-loong64-musl": "0.54.0", "@dprint/linux-riscv64-glibc": "0.54.0", "@dprint/linux-x64-glibc": "0.54.0", "@dprint/linux-x64-musl": "0.54.0", "@dprint/win32-arm64": "0.54.0", "@dprint/win32-x64": "0.54.0" }, "bin": { "dprint": "bin.cjs" } }, "sha512-sIy25poR2gRP/tWPTgP0MPeJoJcpv0xzYDcsboapvthbEt1Qw3Al252CA0xFyIh2cYEGGKyBJtKokryv4ERlJw=="], "dts-resolver": ["dts-resolver@2.1.3", "", { "peerDependencies": { "oxc-resolver": ">=11.0.0" }, "optionalPeers": ["oxc-resolver"] }, "sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw=="], @@ -928,18 +934,12 @@ "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], - "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], - - "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], - "fd-package-json": ["fd-package-json@2.0.0", "", { "dependencies": { "walk-up-path": "^4.0.0" } }, "sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ=="], "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="], - "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], - "floating-vue": ["floating-vue@5.2.2", "", { "dependencies": { "@floating-ui/dom": "~1.1.1", "vue-resize": "^2.0.0-alpha.1" }, "peerDependencies": { "@nuxt/kit": "^3.2.0", "vue": "^3.2.0" }, "optionalPeers": ["@nuxt/kit"] }, "sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg=="], "focus-trap": ["focus-trap@8.0.1", "", { "dependencies": { "tabbable": "^6.4.0" } }, "sha512-9ptSG6z51YQOstI/oN4XuVGP/03u2nh0g//qz7L6zX0i6PZiPnkcf3GenXq7N2hZnASXaMxTPpbKwdI+PFvxlw=="], @@ -948,12 +948,10 @@ "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], - "get-tsconfig": ["get-tsconfig@4.13.7", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q=="], + "get-tsconfig": ["get-tsconfig@4.14.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA=="], "gh": ["gh@workspace:examples/gh"], - "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - "hachure-fill": ["hachure-fill@0.5.2", "", {}, "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg=="], "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], @@ -974,12 +972,6 @@ "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], - "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], - - "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], - - "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], - "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="], "istanbul-lib-report": ["istanbul-lib-report@3.0.1", "", { "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" } }, "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw=="], @@ -998,7 +990,7 @@ "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], - "knip": ["knip@6.3.1", "", { "dependencies": { "@nodelib/fs.walk": "^1.2.3", "fast-glob": "^3.3.3", "formatly": "^0.3.0", "get-tsconfig": "4.13.7", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.121.0", "oxc-resolver": "^11.19.1", "picocolors": "^1.1.1", "picomatch": "^4.0.1", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "unbash": "^2.2.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-22kLJloVcOVOAudCxlFOC0ICAMme7dKsS7pVTEnrmyKGpswb8ieznvAiSKUeFVDJhb01ect6dkDc1Ha1g1sPpg=="], + "knip": ["knip@6.7.0", "", { "dependencies": { "fdir": "^6.5.0", "formatly": "^0.3.0", "get-tsconfig": "4.14.0", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.127.0", "oxc-resolver": "^11.19.1", "picomatch": "^4.0.4", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "tinyglobby": "^0.2.16", "unbash": "^3.0.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-ckL51NDH1YJxnv1kNB0iUdDngB4f/e9Igz8uIqYfmNDoyOFmmk1V0WFv3LQ7/hzC63b2Z9X41gGUE9eOWrZpaA=="], "langium": ["langium@4.2.2", "", { "dependencies": { "@chevrotain/regexp-to-ast": "~12.0.0", "chevrotain": "~12.0.0", "chevrotain-allstar": "~0.4.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.1.0" } }, "sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ=="], @@ -1080,8 +1072,6 @@ "mdurl": ["mdurl@2.0.0", "", {}, "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="], - "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], - "mermaid": ["mermaid@11.14.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.1", "@iconify/utils": "^3.0.2", "@mermaid-js/parser": "^1.1.0", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", "cytoscape": "^3.33.1", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.14", "dayjs": "^1.11.19", "dompurify": "^3.3.1", "katex": "^0.16.25", "khroma": "^2.1.0", "lodash-es": "^4.17.23", "marked": "^16.3.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-GSGloRsBs+JINmmhl0JDwjpuezCsHB4WGI4NASHxL3fHo3o/BRXTxhDLKnln8/Q0lRFRyDdEjmk1/d5Sn1Xz8g=="], "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], @@ -1126,9 +1116,7 @@ "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], - "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], - - "miniflare": ["miniflare@4.20260405.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.4", "workerd": "1.20260405.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-tpr4XdWMq7zFdsHH+CS0XS47nQzlRZH0rMJ1vobOZbkrs3cIj7qbD40ON616hDnzHxwqwB2qKHzmmuj6oRisSQ=="], + "miniflare": ["miniflare@4.20260426.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.8", "workerd": "1.20260426.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-KM+v76d04qT+NsPfVKVQEgnnuLNE3uzCCl2QKMTJ5OXor5JbBm1vpkQwQ+l7o5ELCrZ74RnyKhJKLiJyUA39Tw=="], "minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], @@ -1154,7 +1142,7 @@ "oniguruma-to-es": ["oniguruma-to-es@4.3.5", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.1.0", "regex-recursion": "^6.0.2" } }, "sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ=="], - "oxc-parser": ["oxc-parser@0.121.0", "", { "dependencies": { "@oxc-project/types": "^0.121.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.121.0", "@oxc-parser/binding-android-arm64": "0.121.0", "@oxc-parser/binding-darwin-arm64": "0.121.0", "@oxc-parser/binding-darwin-x64": "0.121.0", "@oxc-parser/binding-freebsd-x64": "0.121.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.121.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.121.0", "@oxc-parser/binding-linux-arm64-gnu": "0.121.0", "@oxc-parser/binding-linux-arm64-musl": "0.121.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.121.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.121.0", "@oxc-parser/binding-linux-riscv64-musl": "0.121.0", "@oxc-parser/binding-linux-s390x-gnu": "0.121.0", "@oxc-parser/binding-linux-x64-gnu": "0.121.0", "@oxc-parser/binding-linux-x64-musl": "0.121.0", "@oxc-parser/binding-openharmony-arm64": "0.121.0", "@oxc-parser/binding-wasm32-wasi": "0.121.0", "@oxc-parser/binding-win32-arm64-msvc": "0.121.0", "@oxc-parser/binding-win32-ia32-msvc": "0.121.0", "@oxc-parser/binding-win32-x64-msvc": "0.121.0" } }, "sha512-ek9o58+SCv6AV7nchiAcUJy1DNE2CC5WRdBcO0mF+W4oRjNQfPO7b3pLjTHSFECpHkKGOZSQxx3hk8viIL5YCg=="], + "oxc-parser": ["oxc-parser@0.127.0", "", { "dependencies": { "@oxc-project/types": "^0.127.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.127.0", "@oxc-parser/binding-android-arm64": "0.127.0", "@oxc-parser/binding-darwin-arm64": "0.127.0", "@oxc-parser/binding-darwin-x64": "0.127.0", "@oxc-parser/binding-freebsd-x64": "0.127.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.127.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.127.0", "@oxc-parser/binding-linux-arm64-gnu": "0.127.0", "@oxc-parser/binding-linux-arm64-musl": "0.127.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.127.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.127.0", "@oxc-parser/binding-linux-riscv64-musl": "0.127.0", "@oxc-parser/binding-linux-s390x-gnu": "0.127.0", "@oxc-parser/binding-linux-x64-gnu": "0.127.0", "@oxc-parser/binding-linux-x64-musl": "0.127.0", "@oxc-parser/binding-openharmony-arm64": "0.127.0", "@oxc-parser/binding-wasm32-wasi": "0.127.0", "@oxc-parser/binding-win32-arm64-msvc": "0.127.0", "@oxc-parser/binding-win32-ia32-msvc": "0.127.0", "@oxc-parser/binding-win32-x64-msvc": "0.127.0" } }, "sha512-bkgD4qHlN7WxLdX8bLXdaU54TtQtAIg/ZBAfm0aje/mo3MRDo3P0hZSgr4U7O3xfX+fQmR5AP04JS/TGcZLcFA=="], "oxc-resolver": ["oxc-resolver@11.19.1", "", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.19.1", "@oxc-resolver/binding-android-arm64": "11.19.1", "@oxc-resolver/binding-darwin-arm64": "11.19.1", "@oxc-resolver/binding-darwin-x64": "11.19.1", "@oxc-resolver/binding-freebsd-x64": "11.19.1", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.19.1", "@oxc-resolver/binding-linux-arm-musleabihf": "11.19.1", "@oxc-resolver/binding-linux-arm64-gnu": "11.19.1", "@oxc-resolver/binding-linux-arm64-musl": "11.19.1", "@oxc-resolver/binding-linux-ppc64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-musl": "11.19.1", "@oxc-resolver/binding-linux-s390x-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-musl": "11.19.1", "@oxc-resolver/binding-openharmony-arm64": "11.19.1", "@oxc-resolver/binding-wasm32-wasi": "11.19.1", "@oxc-resolver/binding-win32-arm64-msvc": "11.19.1", "@oxc-resolver/binding-win32-ia32-msvc": "11.19.1", "@oxc-resolver/binding-win32-x64-msvc": "11.19.1" } }, "sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg=="], @@ -1188,9 +1176,9 @@ "punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="], - "quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], + "pwsh-demo": ["pwsh-demo@workspace:examples/pwsh-demo"], - "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + "quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], @@ -1200,8 +1188,6 @@ "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], - "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - "robust-predicates": ["robust-predicates@3.0.3", "", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="], "rolldown": ["rolldown@1.0.0-rc.12", "", { "dependencies": { "@oxc-project/types": "=0.122.0", "@rolldown/pluginutils": "1.0.0-rc.12" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.12", "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", "@rolldown/binding-darwin-x64": "1.0.0-rc.12", "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A=="], @@ -1212,8 +1198,6 @@ "roughjs": ["roughjs@4.6.6", "", { "dependencies": { "hachure-fill": "^0.5.2", "path-data-parser": "^0.1.0", "points-on-curve": "^0.2.0", "points-on-path": "^0.2.1" } }, "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ=="], - "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], - "rw": ["rw@1.3.3", "", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="], "sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="], @@ -1256,8 +1240,6 @@ "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], - "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], - "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="], "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], @@ -1284,11 +1266,11 @@ "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], - "unbash": ["unbash@2.2.0", "", {}, "sha512-X2wH19RAPZE3+ldGicOkoj/SIA83OIxcJ6Cuaw23hf8Xc6fQpvZXY0SftE2JgS0QhYLUG4uwodSI3R53keyh7w=="], + "unbash": ["unbash@3.0.0", "", {}, "sha512-FeFPZ/WFT0mbRCuydiZzpPFlrYN8ZUpphQKoq4EeElVIYjYyGzPMxQR/simUwCOJIyVhpFk4RbtyO7RuMpMnHA=="], "unconfig-core": ["unconfig-core@7.5.0", "", { "dependencies": { "@quansync/fs": "^1.0.0", "quansync": "^1.0.0" } }, "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w=="], - "undici": ["undici@7.24.4", "", {}, "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w=="], + "undici": ["undici@7.24.8", "", {}, "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ=="], "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], @@ -1340,9 +1322,9 @@ "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], - "workerd": ["workerd@1.20260405.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260405.1", "@cloudflare/workerd-darwin-arm64": "1.20260405.1", "@cloudflare/workerd-linux-64": "1.20260405.1", "@cloudflare/workerd-linux-arm64": "1.20260405.1", "@cloudflare/workerd-windows-64": "1.20260405.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-bSaRWCv9iO8/FWpgZRjHLGZLolX5s1AErRSYaTECMMHOZKuCbl2+ehnSyc+ZZ/70y+9owADmN6HoYEWvBlJdYw=="], + "workerd": ["workerd@1.20260426.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260426.1", "@cloudflare/workerd-darwin-arm64": "1.20260426.1", "@cloudflare/workerd-linux-64": "1.20260426.1", "@cloudflare/workerd-linux-arm64": "1.20260426.1", "@cloudflare/workerd-windows-64": "1.20260426.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-ELvGgN8c9oo+E6EPyecxk1TEf6/eAK4TxxQTW5mQ87C7jbjCzhMbg0P2ije49UBHV0dkBYPJcJvcklUltipl2A=="], - "wrangler": ["wrangler@4.81.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.16.0", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260405.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260405.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260405.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-9fLPDuDcb8Nu6iXrl5E3HGYt3TVhQr/UvqtTvWr9Nl1X7PlQrmWMwQCfSioqN8VHYyQCyESV5jQsoKg8Sx+sEA=="], + "wrangler": ["wrangler@4.86.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.16.1", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260426.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260426.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260426.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-9aa/gbF/HiUeeUEwyQpW5LDPBEzyt7iaE6xHwm0vk2Ly8A6J+jh03pzchqVnCCWR832mNyA28MD8oAYt0Kfvlw=="], "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], @@ -1374,8 +1356,12 @@ "@gerrit0/mini-shiki/@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], + "@oxc-resolver/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], + "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], + "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], + "@vitejs/plugin-vue/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.2", "", {}, "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw=="], "@vue/compiler-core/entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], @@ -1398,7 +1384,7 @@ "d3-sankey/d3-shape": ["d3-shape@1.3.7", "", { "dependencies": { "d3-path": "1" } }, "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw=="], - "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + "pwsh-demo/@kjanat/dreamcli": ["dreamcli-monorepo@link:@kjanat/dreamcli", {}], "rolldown/@oxc-project/types": ["@oxc-project/types@0.122.0", "", {}, "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA=="], @@ -1406,6 +1392,10 @@ "rolldown-plugin-dts/@babel/types": ["@babel/types@8.0.0-rc.3", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0-rc.3", "@babel/helper-validator-identifier": "^8.0.0-rc.3" } }, "sha512-mOm5ZrYmphGfqVWoH5YYMTITb3cDXsFgmvFlvkvWDMsR9X8RFnt7a0Wb6yNIdoFsiMO9WjYLq+U/FMtqIYAF8Q=="], + "rolldown-plugin-dts/get-tsconfig": ["get-tsconfig@4.13.7", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q=="], + + "tsx/get-tsconfig": ["get-tsconfig@4.13.7", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q=="], + "vite/rolldown": ["rolldown@1.0.0-rc.15", "", { "dependencies": { "@oxc-project/types": "=0.124.0", "@rolldown/pluginutils": "1.0.0-rc.15" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-x64": "1.0.0-rc.15", "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g=="], "vitepress/@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], @@ -1473,5 +1463,7 @@ "vitepress/shiki/@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="], "ast-kit/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.3", "", {}, "sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA=="], + + "vite/rolldown/@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], } } diff --git a/examples/pwsh-demo/src/main.test.ts b/examples/pwsh-demo/src/main.test.ts index 933faeeb..f21fbb85 100644 --- a/examples/pwsh-demo/src/main.test.ts +++ b/examples/pwsh-demo/src/main.test.ts @@ -40,9 +40,6 @@ describe('pwsh-demo example', () => { const result = await pwshDemo.execute(['bravo', '--profile', 'ops', '--shell', 'cmd']); expect(result.exitCode).toBe(0); - expect(result.stdout).toEqual([ - 'Opening bravo with ops profile in cmd\n', - 'Format: table\n', - ]); + expect(result.stdout).toEqual(['Opening bravo with ops profile in cmd\n', 'Format: table\n']); }); }); diff --git a/examples/pwsh-demo/src/main.ts b/examples/pwsh-demo/src/main.ts old mode 100644 new mode 100755 index b3ada0ed..1c8a3cdf --- a/examples/pwsh-demo/src/main.ts +++ b/examples/pwsh-demo/src/main.ts @@ -35,7 +35,9 @@ const open = command('open') .flag('format', flag.enum(['table', 'json', 'yaml']).alias('f').describe('Output format')) .flag('verbose', flag.boolean().alias('v').describe('Verbose logging')) .action(({ args, flags, out }) => { - out.log(`Opening ${args.workspace} with ${flags.profile ?? 'default'} profile in ${flags.shell}`); + out.log( + `Opening ${args.workspace} with ${flags.profile ?? 'default'} profile in ${flags.shell}`, + ); out.log(`Format: ${flags.format ?? 'table'}`); if (flags.verbose) out.log('Verbose output enabled'); }); @@ -55,7 +57,9 @@ const deploy = command('deploy') .flag('approval', flag.enum(['manual', 'auto']).describe('Approval mode')) .flag('dryRun', flag.boolean().alias('d').describe('Preview the rollout without applying it')) .action(({ args, flags, out }) => { - out.log(`Deploying ${args.target} to ${flags.region ?? 'us'} with ${flags.strategy ?? 'rolling'}`); + out.log( + `Deploying ${args.target} to ${flags.region ?? 'us'} with ${flags.strategy ?? 'rolling'}`, + ); out.log(`Approval: ${flags.approval ?? 'manual'}`); if (flags.dryRun) out.log('Dry run only'); }); @@ -82,7 +86,10 @@ const configSet = command('set') .description('Write a saved setting') .arg('key', arg.enum(['theme', 'region', 'profile']).describe('Setting to write')) .arg('value', arg.string().describe('New value')) - .flag('scope', flag.enum(['user', 'workspace']).alias('s').default('user').describe('Config scope')) + .flag( + 'scope', + flag.enum(['user', 'workspace']).alias('s').default('user').describe('Config scope'), + ) .action(({ args, flags, out }) => { out.log(`Saved ${args.key}=${args.value} to ${flags.scope} scope`); }); @@ -107,7 +114,10 @@ const debugDump = command('debug-dump') .hidden() .flag( 'section', - flag.enum(['schema', 'completions', 'runtime']).default('schema').describe('Section to inspect'), + flag + .enum(['schema', 'completions', 'runtime']) + .default('schema') + .describe('Section to inspect'), ) .action(({ flags, out }) => { out.log(JSON.stringify({ section: flags.section, hidden: true }, null, 2)); diff --git a/package.json b/package.json index e37ab3dc..e88d4bf8 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "npm": "11.12.1" }, "catalog": { - "@biomejs/biome": "2.4.10", + "@biomejs/biome": "2.4.13", "@arethetypeswrong/core": "^0.18.2", "@iarna/toml": "^2.2.5", "@shikijs/transformers": "^4.0.2", @@ -79,7 +79,7 @@ "@types/bun": "^1.3.12", "@types/deno": "^2.5.0", "@types/node": ">=22.0.0, <23.0.0", - "@typescript/native-preview": "^7.0.0-dev.20260408.1", + "@typescript/native-preview": "^7.0.0-dev.20260428.1", "@vitest/coverage-v8": "^4.1.2", "floating-vue": "^5.2.2", "mermaid": "^11.14.0", @@ -93,8 +93,8 @@ "vitepress": "^2.0.0-alpha.17", "vitest": "^4.1.2", "yaml": "^2.8.3", - "dprint": "^0.53.2", - "knip": "^6.3.0", - "wrangler": "^4.81.0" + "dprint": "^0.54.0", + "knip": "^6.7.0", + "wrangler": "^4.86.0" } } diff --git a/packages/dreamcli/src/core/completion/shells/powershell.ts b/packages/dreamcli/src/core/completion/shells/powershell.ts index 8b09dc5d..9f225dc8 100644 --- a/packages/dreamcli/src/core/completion/shells/powershell.ts +++ b/packages/dreamcli/src/core/completion/shells/powershell.ts @@ -318,14 +318,14 @@ function emitPowerShellHelpers(lines: string[], helperPrefix: string, dataVarNam lines.push(`function ${helperPrefix}_FormatCompletionValue {`); lines.push('\tparam([string]$Value)'); lines.push('\tif ($Value.Length -eq 0) {'); - lines.push("\t\treturn \"''\""); + lines.push('\t\treturn "\'\'"'); lines.push('\t}'); lines.push(''); lines.push("\tif ($Value -match '^[a-zA-Z0-9_./:\\\\-]+$') {"); lines.push('\t\treturn $Value'); lines.push('\t}'); lines.push(''); - lines.push("\treturn \"'$([CodeGeneration]::EscapeSingleQuotedStringContent($Value))'\""); + lines.push('\treturn "\'$([CodeGeneration]::EscapeSingleQuotedStringContent($Value))\'"'); lines.push('}'); lines.push(''); lines.push(`function ${helperPrefix}_MatchesCompletionPrefix {`); diff --git a/packages/dreamcli/src/core/json-schema/meta-descriptions.generated.ts b/packages/dreamcli/src/core/json-schema/meta-descriptions.generated.ts index e217db0e..fbea4d22 100644 --- a/packages/dreamcli/src/core/json-schema/meta-descriptions.generated.ts +++ b/packages/dreamcli/src/core/json-schema/meta-descriptions.generated.ts @@ -6,176 +6,193 @@ const definitionMetaSchemaDescriptions = { root: { - description: "Runtime descriptor for the CLI program.\n\nStores the program name, version, description, and registered commands.\\\nBuilt incrementally by CLIBuilder.", + description: + 'Runtime descriptor for the CLI program.\n\nStores the program name, version, description, and registered commands.\\\nBuilt incrementally by CLIBuilder.', properties: { - "name": { - description: "Program name (used in help text, usage lines, and completion scripts).", + name: { + description: 'Program name (used in help text, usage lines, and completion scripts).', }, - "version": { - description: "Program version (shown by `--version`).", + version: { + description: 'Program version (shown by `--version`).', }, - "description": { - description: "Program description (shown in root help).", + description: { + description: 'Program description (shown in root help).', }, - "defaultCommand": { - description: "Default command dispatched when no subcommand matches.\n\nWhen set, the CLI root behaves like a hybrid command group: subcommands\ndispatch by name as usual, but empty argv or flags-only argv falls\nthrough to this command instead of showing root help.\n\nSet via the .default() builder method.", + defaultCommand: { + description: + 'Default command dispatched when no subcommand matches.\n\nWhen set, the CLI root behaves like a hybrid command group: subcommands\ndispatch by name as usual, but empty argv or flags-only argv falls\nthrough to this command instead of showing root help.\n\nSet via the .default() builder method.', }, - "commands": { - description: "Registered commands (type-erased for heterogeneous storage).", + commands: { + description: 'Registered commands (type-erased for heterogeneous storage).', }, }, }, defs: { - "command": { - description: "Runtime descriptor produced by CommandBuilder.\n\nConsumers (parser, help generator, CLI dispatcher) read this to\nunderstand the command's shape — flags, args, aliases, subcommands,\nmiddleware, and interactive resolver.", + command: { + description: + "Runtime descriptor produced by CommandBuilder.\n\nConsumers (parser, help generator, CLI dispatcher) read this to\nunderstand the command's shape — flags, args, aliases, subcommands,\nmiddleware, and interactive resolver.", properties: { - "name": { + name: { description: "The command name (used for dispatch, e.g. `'deploy'`).", }, - "description": { - description: "Human-readable description for help text.", + description: { + description: 'Human-readable description for help text.', }, - "aliases": { - description: "Alternative names for this command.", + aliases: { + description: 'Alternative names for this command.', }, - "hidden": { - description: "Whether this command is hidden from help listings.", + hidden: { + description: 'Whether this command is hidden from help listings.', }, - "examples": { - description: "Usage examples for help text.", + examples: { + description: 'Usage examples for help text.', }, - "flags": { - description: "Named flag schemas, keyed by flag name.", + flags: { + description: 'Named flag schemas, keyed by flag name.', }, - "args": { - description: "Ordered positional arg entries (name + schema).", + args: { + description: 'Ordered positional arg entries (name + schema).', }, - "commands": { - description: "Nested subcommand schemas (for help rendering and completion).\n\nPure data — no execution closures. Populated by `.command()` on\n`CommandBuilder`. Empty for leaf commands.", + commands: { + description: + 'Nested subcommand schemas (for help rendering and completion).\n\nPure data — no execution closures. Populated by `.command()` on\n`CommandBuilder`. Empty for leaf commands.', }, }, }, - "flag": { - description: "The runtime descriptor stored inside every FlagBuilder. Consumers (parser,\nhelp generator, resolution chain) read this to understand the flag's shape\nwithout touching generics.", + flag: { + description: + "The runtime descriptor stored inside every FlagBuilder. Consumers (parser,\nhelp generator, resolution chain) read this to understand the flag's shape\nwithout touching generics.", properties: { - "kind": { - description: "What kind of value this flag accepts.", + kind: { + description: 'What kind of value this flag accepts.', }, - "presence": { - description: "Presence describes whether a flag value is guaranteed to exist when the\naction handler runs:\n\n- `'optional'` — not required; unresolved value follows the kind-specific\n optional fallback (`undefined` for most flags, `[]` for arrays)\n- `'required'` — must be supplied; error if missing\n- `'defaulted'` — always present (falls back to default value)", + presence: { + description: + "Presence describes whether a flag value is guaranteed to exist when the\naction handler runs:\n\n- `'optional'` — not required; unresolved value follows the kind-specific\n optional fallback (`undefined` for most flags, `[]` for arrays)\n- `'required'` — must be supplied; error if missing\n- `'defaulted'` — always present (falls back to default value)", }, - "defaultValue": { - description: "Runtime default value (if any).", + defaultValue: { + description: 'Runtime default value (if any).', }, - "aliases": { + aliases: { description: "Short/long aliases (e.g. `[{ name: 'f', hidden: false }]` for `--force`).", }, - "envVar": { - description: "Environment variable name for v0.2+ resolution.", + envVar: { + description: 'Environment variable name for v0.2+ resolution.', }, - "configPath": { + configPath: { description: "Dotted config path for v0.2+ resolution (e.g. `'deploy.region'`).", }, - "description": { - description: "Human-readable description for help text.", + description: { + description: 'Human-readable description for help text.', }, - "enumValues": { + enumValues: { description: "Allowed literal values when `kind === 'enum'`.", }, - "elementSchema": { + elementSchema: { description: "Element schema when `kind === 'array'`.", }, - "prompt": { - description: "Interactive prompt configuration for v0.3+ resolution.", + prompt: { + description: 'Interactive prompt configuration for v0.3+ resolution.', }, - "deprecated": { - description: "Deprecation marker.\n\n- `undefined` — not deprecated (default)\n- `true` — deprecated with no migration message\n- `string` — deprecated with a reason/migration message\n\nWhen a deprecated flag is used, a warning is emitted to stderr.\nHelp text shows `[deprecated]` or `[deprecated: ]`.", + deprecated: { + description: + 'Deprecation marker.\n\n- `undefined` — not deprecated (default)\n- `true` — deprecated with no migration message\n- `string` — deprecated with a reason/migration message\n\nWhen a deprecated flag is used, a warning is emitted to stderr.\nHelp text shows `[deprecated]` or `[deprecated: ]`.', }, - "propagate": { - description: "Whether this flag propagates to subcommands in nested command trees.\n\nWhen `true`, the flag is automatically available to all descendant\ncommands. A child command that defines a flag with the same name\nshadows the propagated parent flag.", + propagate: { + description: + 'Whether this flag propagates to subcommands in nested command trees.\n\nWhen `true`, the flag is automatically available to all descendant\ncommands. A child command that defines a flag with the same name\nshadows the propagated parent flag.', }, }, }, - "arg": { - description: "The runtime descriptor stored inside every ArgBuilder. Consumers (parser,\nhelp generator) read this to understand the arg's shape without touching\ngenerics.", + arg: { + description: + "The runtime descriptor stored inside every ArgBuilder. Consumers (parser,\nhelp generator) read this to understand the arg's shape without touching\ngenerics.", properties: { - "name": { - description: "A named positional argument entry in the command schema.\n\nPairs a user-facing arg name with its ArgSchema descriptor.\nThe array ordering in CommandSchema.args determines CLI position.", + name: { + description: + 'A named positional argument entry in the command schema.\n\nPairs a user-facing arg name with its ArgSchema descriptor.\nThe array ordering in CommandSchema.args determines CLI position.', }, - "kind": { - description: "What kind of value this arg accepts.", + kind: { + description: 'What kind of value this arg accepts.', }, - "presence": { - description: "Presence describes whether a positional arg is guaranteed to exist when the\naction handler runs:\n\n- `'required'` — must be supplied; error if missing (default)\n- `'optional'` — may be `undefined` if not supplied\n- `'defaulted'` — always present (falls back to default value)", + presence: { + description: + "Presence describes whether a positional arg is guaranteed to exist when the\naction handler runs:\n\n- `'required'` — must be supplied; error if missing (default)\n- `'optional'` — may be `undefined` if not supplied\n- `'defaulted'` — always present (falls back to default value)", }, - "variadic": { - description: "Whether this arg consumes all remaining positionals.", + variadic: { + description: 'Whether this arg consumes all remaining positionals.', }, - "stdinMode": { - description: "Whether this arg may read from stdin during resolution.", + stdinMode: { + description: 'Whether this arg may read from stdin during resolution.', }, - "defaultValue": { - description: "Runtime default value (if any).", + defaultValue: { + description: 'Runtime default value (if any).', }, - "description": { - description: "Human-readable description for help text.", + description: { + description: 'Human-readable description for help text.', }, - "envVar": { - description: "Environment variable name for env resolution.\n\nWhen set and the CLI value is absent, the resolver reads this env var\nand coerces the string to the arg's declared kind.", + envVar: { + description: + "Environment variable name for env resolution.\n\nWhen set and the CLI value is absent, the resolver reads this env var\nand coerces the string to the arg's declared kind.", }, - "enumValues": { + enumValues: { description: "Allowed literal values when `kind === 'enum'`.", }, - "deprecated": { - description: "Deprecation marker.\n\n- `undefined` — not deprecated (default)\n- `true` — deprecated with no migration message\n- `string` — deprecated with a reason/migration message\n\nWhen a deprecated arg is used, a warning is emitted to stderr.\nHelp text shows `[deprecated]` or `[deprecated: ]`.", + deprecated: { + description: + 'Deprecation marker.\n\n- `undefined` — not deprecated (default)\n- `true` — deprecated with no migration message\n- `string` — deprecated with a reason/migration message\n\nWhen a deprecated arg is used, a warning is emitted to stderr.\nHelp text shows `[deprecated]` or `[deprecated: ]`.', }, }, }, - "prompt": { - description: "Discriminated union of all prompt configurations.\n\nUse the `kind` field to narrow:\n```ts\nif (config.kind === 'select') {\n config.choices // readonly SelectChoice[] | undefined\n}\n```", + prompt: { + description: + "Discriminated union of all prompt configurations.\n\nUse the `kind` field to narrow:\n```ts\nif (config.kind === 'select') {\n config.choices // readonly SelectChoice[] | undefined\n}\n```", properties: { - "kind": { - description: "The kind of interactive prompt to present.\n\n- `'confirm'` — yes/no boolean question\n- `'input'` — free-text string input\n- `'select'` — single selection from a list\n- `'multiselect'` — multiple selections from a list", + kind: { + description: + "The kind of interactive prompt to present.\n\n- `'confirm'` — yes/no boolean question\n- `'input'` — free-text string input\n- `'select'` — single selection from a list\n- `'multiselect'` — multiple selections from a list", }, - "message": { - description: "The question displayed to the user.", + message: { + description: 'The question displayed to the user.', }, - "placeholder": { - description: "Placeholder text shown before user types (informational only).", + placeholder: { + description: 'Placeholder text shown before user types (informational only).', }, - "choices": { - description: "Available choices. When omitted for `enum` flags, the enum values\nfrom the flag schema are used automatically.", + choices: { + description: + 'Available choices. When omitted for `enum` flags, the enum values\nfrom the flag schema are used automatically.', }, - "min": { - description: "Minimum number of selections required.", + min: { + description: 'Minimum number of selections required.', }, - "max": { - description: "Maximum number of selections allowed.", + max: { + description: 'Maximum number of selections allowed.', }, }, }, - "choice": { - description: "A selectable option for SelectPromptConfig and MultiselectPromptConfig prompts.", + choice: { + description: + 'A selectable option for SelectPromptConfig and MultiselectPromptConfig prompts.', properties: { - "value": { - description: "The value returned when this choice is selected.", + value: { + description: 'The value returned when this choice is selected.', }, - "label": { - description: "Display label shown to the user.", + label: { + description: 'Display label shown to the user.', }, - "description": { - description: "Optional description shown alongside the choice.", + description: { + description: 'Optional description shown alongside the choice.', }, }, }, - "example": { - description: "A single usage example shown in help text.", + example: { + description: 'A single usage example shown in help text.', properties: { - "command": { + command: { description: "The command invocation (e.g. `'deploy production --force'`).", }, - "description": { - description: "Optional description of what this example does.", + description: { + description: 'Optional description of what this example does.', }, }, }, From 6deb38584a3aa3caa04e235dd2365d2ad1ae06e9 Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Wed, 29 Apr 2026 05:34:47 +0200 Subject: [PATCH 20/21] chore: harden starter example repeat counts Clamp starter repeat counts to finite integers so generated and documented hello-world CLIs cannot spin forever on `Infinity` or other invalid numeric inputs. Clean up nearby review nits by removing a duplicate prompt test name, dropping an unused scaffold variable, and invoking the PowerShell completion script without redundant string coercion. --- apps/docs/guide/getting-started.md | 6 +++++- examples/pwsh-demo/smoke-powershell.ps1 | 2 +- examples/standalone/basic.ts | 6 +++++- packages/dreamcli/README.md | 6 +++++- packages/dreamcli/src/core/schema/prompt.test.ts | 2 +- skills/cli-creation/assets/templates/single-command.ts.tpl | 6 +++++- skills/cli-creation/scripts/scaffold_cli.py | 2 -- 7 files changed, 22 insertions(+), 8 deletions(-) diff --git a/apps/docs/guide/getting-started.md b/apps/docs/guide/getting-started.md index bf6f17cd..3c9407d9 100644 --- a/apps/docs/guide/getting-started.md +++ b/apps/docs/guide/getting-started.md @@ -43,7 +43,11 @@ const greet = command('greet') flag.number().default(1).describe('Repeat count'), ) .action(({ args, flags, out }) => { - for (let i = 0; i < flags.times; i++) { + const repeatCount = Number.isFinite(flags.times) + ? Math.max(0, Math.min(100, Math.floor(flags.times))) + : 1; + + for (let i = 0; i < repeatCount; i++) { const msg = `Hello, ${args.name}!`; out.log(flags.loud ? msg.toUpperCase() : msg); } diff --git a/examples/pwsh-demo/smoke-powershell.ps1 b/examples/pwsh-demo/smoke-powershell.ps1 index 0a77d35e..2552bfc7 100755 --- a/examples/pwsh-demo/smoke-powershell.ps1 +++ b/examples/pwsh-demo/smoke-powershell.ps1 @@ -41,7 +41,7 @@ if ($nativeCompletionScript -ne $completionScript) { throw 'The native pwsh-demo launcher generated a different completion script than the direct Bun invocation.' } -$nativeCompletionScript | Out-String | Invoke-Expression +Invoke-Expression $nativeCompletionScript <# .SYNOPSIS diff --git a/examples/standalone/basic.ts b/examples/standalone/basic.ts index 77d64070..851b3e39 100755 --- a/examples/standalone/basic.ts +++ b/examples/standalone/basic.ts @@ -24,7 +24,11 @@ const greet = command('greet') // args.name: string — required positional // flags.loud: boolean — defaults to false (all booleans do) // flags.times: number — defaults to 1 (never undefined) - for (let i = 0; i < flags.times; i++) { + const repeatCount = Number.isFinite(flags.times) + ? Math.max(0, Math.min(100, Math.floor(flags.times))) + : 1; + + for (let i = 0; i < repeatCount; i++) { const msg = `Hello, ${args.name}!`; out.log(flags.loud ? msg.toUpperCase() : msg); } diff --git a/packages/dreamcli/README.md b/packages/dreamcli/README.md index fe568eec..90c73932 100644 --- a/packages/dreamcli/README.md +++ b/packages/dreamcli/README.md @@ -90,7 +90,11 @@ const greet = command('greet') flag.number().default(1).describe('Repeat count'), ) .action(({ args, flags, out }) => { - for (let i = 0; i < flags.times; i++) { + const repeatCount = Number.isFinite(flags.times) + ? Math.max(0, Math.min(100, Math.floor(flags.times))) + : 1; + + for (let i = 0; i < repeatCount; i++) { const msg = `Hello, ${args.name}!`; out.log(flags.loud ? msg.toUpperCase() : msg); } diff --git a/packages/dreamcli/src/core/schema/prompt.test.ts b/packages/dreamcli/src/core/schema/prompt.test.ts index 7ebbb29c..a33dc5cc 100644 --- a/packages/dreamcli/src/core/schema/prompt.test.ts +++ b/packages/dreamcli/src/core/schema/prompt.test.ts @@ -533,7 +533,7 @@ describe('AllowedPromptConfig type constraints', () => { flag.array(flag.string()).prompt({ kind: 'multiselect', message: 'Tags?' }); }); - it('custom flag allows all prompt kinds', () => { + it('custom flag allows all prompt kinds at runtime', () => { const custom = flag.custom((raw) => raw); custom.prompt({ kind: 'input', message: 'Value?' }); custom.prompt({ kind: 'select', message: 'Pick', choices: [{ value: 'a' }] }); diff --git a/skills/cli-creation/assets/templates/single-command.ts.tpl b/skills/cli-creation/assets/templates/single-command.ts.tpl index 97159e24..5e673a9b 100644 --- a/skills/cli-creation/assets/templates/single-command.ts.tpl +++ b/skills/cli-creation/assets/templates/single-command.ts.tpl @@ -30,7 +30,11 @@ export const hello = command('hello') .flag('times', flag.number().default(1).alias('n').describe('Repeat count')) .middleware(sparkle) .action(({ args, flags, ctx, out }) => { - for (let i = 0; i < flags.times; i++) { + const repeatCount = Number.isFinite(flags.times) + ? Math.max(0, Math.min(100, Math.floor(flags.times))) + : 1; + + for (let i = 0; i < repeatCount; i++) { const base = `Hello, ${args.name}!`; out.log(ctx.sparkle(base)); } diff --git a/skills/cli-creation/scripts/scaffold_cli.py b/skills/cli-creation/scripts/scaffold_cli.py index 671b8e6a..59c6ddc2 100755 --- a/skills/cli-creation/scripts/scaffold_cli.py +++ b/skills/cli-creation/scripts/scaffold_cli.py @@ -308,8 +308,6 @@ def main() -> int: templates_dir = skill_root / "assets" / "templates" entry_template_path = templates_dir / f"{args.mode}-command.ts.tpl" - test_template_path = templates_dir / f"{args.mode}-command.test.ts.tpl" - entry_filename = f"{cli_name}.ts" entry_path = output_dir / entry_filename test_path = output_dir / f"{cli_name}.test.ts" From 6e65de939d5d386fdc96b51289c04eb3da82fcab Mon Sep 17 00:00:00 2001 From: Kaj Kowalski Date: Fri, 1 May 2026 13:03:33 +0200 Subject: [PATCH 21/21] chore: sync docs paths and workspace deps Align moved `examples/standalone` usage docs and watch paths so generated example pages and docs data stay in sync after the move. Refresh formatter and workspace tool versions, restore the `@kjanat/dreamcli-docs/vitepress/*` tsconfig alias, and sync DreamCLI's published runtime support metadata to the 2.1.0 / Bun >=1.3 support line. --- .dprint.jsonc | 10 +- apps/docs/examples/[slug].paths.ts | 2 +- apps/docs/examples/examples.data.ts | 2 +- apps/docs/reference/api.data.ts | 2 +- .../reference/symbols/main/[slug].paths.ts | 5 +- bun.lock | 302 +++++++++++------- examples/standalone/basic.ts | 8 +- examples/standalone/interactive.ts | 8 +- examples/standalone/json-mode.ts | 12 +- examples/standalone/middleware.ts | 4 +- examples/standalone/multi-command.ts | 16 +- examples/standalone/spinner-progress.ts | 6 +- examples/standalone/testing.ts | 4 +- package.json | 20 +- packages/dreamcli/README.md | 2 +- packages/dreamcli/package.json | 4 +- .../src/core/resolve/resolve-prompt.test.ts | 2 +- packages/dreamcli/src/runtime/support.test.ts | 25 +- tsconfig.json | 4 + 19 files changed, 259 insertions(+), 179 deletions(-) diff --git a/.dprint.jsonc b/.dprint.jsonc index 8e43a7d7..88c5b186 100644 --- a/.dprint.jsonc +++ b/.dprint.jsonc @@ -55,16 +55,16 @@ "ruff": { "preview": true, "indentWidth": 4 }, "excludes": ["**/node_modules", "**/{*-,bun}lock(.*)?", "**/snapshots", "**/*.schema.json"], "plugins": [ - "https://plugins.dprint.dev/biome-0.12.8.wasm", - "https://plugins.dprint.dev/g-plane/malva-v0.15.2.wasm", + "https://plugins.dprint.dev/biome-0.12.9.wasm", + "https://plugins.dprint.dev/g-plane/malva-v0.15.3.wasm", "https://plugins.dprint.dev/g-plane/markup_fmt-v0.27.0.wasm", "https://plugins.dprint.dev/g-plane/pretty_yaml-v0.6.0.wasm", "https://plugins.dprint.dev/markdown-0.21.1.wasm", - "https://plugins.dprint.dev/kjanat/svg-v0.2.7.wasm", + "https://plugins.dprint.dev/kjanat/svg-v0.4.0.wasm", "https://plugins.dprint.dev/exec-0.6.2.json@df98f54ffd3092b8a841aedd6d098a2651f16d0a796a40535774f1a8b4b9d463", "https://plugins.dprint.dev/prettier-0.69.0.json@3de5c7cf5cdbae7b214f404b12503c92e7964be5fffd442b998e6d5fe4ba0e7b", - "https://plugins.dprint.dev/ruff-0.7.10.wasm", + "https://plugins.dprint.dev/ruff-0.7.11.wasm", "https://plugins.dprint.dev/json-0.21.3.wasm", - "https://plugins.dprint.dev/kjanat/sortpackagejson-0.1.0.wasm", + "https://plugins.dprint.dev/kjanat/sortpackagejson-0.2.1.wasm", ], } diff --git a/apps/docs/examples/[slug].paths.ts b/apps/docs/examples/[slug].paths.ts index 5adb821b..108797dd 100644 --- a/apps/docs/examples/[slug].paths.ts +++ b/apps/docs/examples/[slug].paths.ts @@ -14,7 +14,7 @@ import { import { examplesRoot, rootDirPath } from '@kjanat/dreamcli-docs/vitepress/data/paths.ts'; export default { - watch: ['../../examples/**/*.ts'], + watch: ['../../../examples/standalone/**/*.ts'], async paths() { const examples = await collectExamples(examplesRoot, rootDirPath); diff --git a/apps/docs/examples/examples.data.ts b/apps/docs/examples/examples.data.ts index f6888044..ed9d29c9 100644 --- a/apps/docs/examples/examples.data.ts +++ b/apps/docs/examples/examples.data.ts @@ -25,7 +25,7 @@ declare const data: Data; export { data }; export default { - watch: ['../../examples/**/*.ts'], + watch: ['../../../examples/standalone/**/*.ts'], async load(): Promise { const examples = await collectExamples(examplesRoot, rootDirPath); diff --git a/apps/docs/reference/api.data.ts b/apps/docs/reference/api.data.ts index 3cd21158..bf60c09f 100644 --- a/apps/docs/reference/api.data.ts +++ b/apps/docs/reference/api.data.ts @@ -31,7 +31,7 @@ declare const data: Data; export { data }; export default { - watch: ['../../src/**/*.ts', '../../examples/**/*.ts'], + watch: ['../../../packages/dreamcli/src/**/*.ts', '../../../examples/standalone/**/*.ts'], async load(): Promise { const { publicApi, symbolPages } = await loadReferenceModel(); diff --git a/apps/docs/reference/symbols/main/[slug].paths.ts b/apps/docs/reference/symbols/main/[slug].paths.ts index cd1e500e..2cca9f69 100644 --- a/apps/docs/reference/symbols/main/[slug].paths.ts +++ b/apps/docs/reference/symbols/main/[slug].paths.ts @@ -10,7 +10,10 @@ import { } from '../../../.vitepress/data/symbol-loader.ts'; export default { - watch: ['../../../../src/**/*.ts', '../../../../examples/**/*.ts'], + watch: [ + '../../../../../packages/dreamcli/src/**/*.ts', + '../../../../../examples/standalone/**/*.ts', + ], async paths() { return symbolPathsForEntrypoint(await loadSymbolPages(), 'main'); diff --git a/bun.lock b/bun.lock index e6993c4c..f099d2f1 100644 --- a/bun.lock +++ b/bun.lock @@ -82,7 +82,7 @@ }, "packages/dreamcli": { "name": "@kjanat/dreamcli", - "version": "2.0.1", + "version": "2.1.0", "devDependencies": { "@arethetypeswrong/core": "catalog:", "@iarna/toml": "catalog:", @@ -129,22 +129,22 @@ "@types/bun": "^1.3.12", "@types/deno": "^2.5.0", "@types/node": ">=22.0.0, <23.0.0", - "@typescript/native-preview": "^7.0.0-dev.20260428.1", - "@vitest/coverage-v8": "^4.1.2", + "@typescript/native-preview": "^7.0.0-dev.20260501.1", + "@vitest/coverage-v8": "^4.1.5", "dprint": "^0.54.0", "floating-vue": "^5.2.2", - "knip": "^6.7.0", + "knip": "^6.9.0", "mermaid": "^11.14.0", "publint": "^0.3.18", - "tsdown": "^0.21.7", + "tsdown": "^0.21.10", "tsx": "^4.21.0", - "typedoc": "^0.28.18", - "typescript": "^6.0.2", - "vite": "^8.0.7", + "typedoc": "^0.28.19", + "typescript": "^6.0.3", + "vite": "^8.0.10", "vitepress": "^2.0.0-alpha.17", - "vitest": "^4.1.2", - "vue": "^3.5.32", - "wrangler": "^4.86.0", + "vitest": "^4.1.5", + "vue": "^3.5.33", + "wrangler": "^4.87.0", "yaml": "^2.8.3", }, "packages": { @@ -198,19 +198,19 @@ "@chevrotain/utils": ["@chevrotain/utils@12.0.0", "", {}, "sha512-lB59uJoaGIfOOL9knQqQRfhl9g7x8/wqFkp13zTdkRu1huG9kg6IJs1O8hqj9rs6h7orGxHJUKb+mX3rPbWGhA=="], - "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.2", "", {}, "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ=="], + "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.5.0", "", {}, "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg=="], "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.1", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": ">1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw=="], - "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260426.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ch7DqsmYzSQRTY87pZpsGsFVz9VVBnLPnCBOHxKt1HH25a7oMu1w1PbPWqVmE0VerCLsj/TScX7Ob3v6E14TZw=="], + "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260430.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-ADohZUHf7NBvPp2PdZig2Opxx+hDkk3ve7jrTne3JRx9kDSB73zc4LzcEeEN8LKkbAcqZmvfRJfpChSlusu0lA=="], - "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260426.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0m0U8vaPRH25SpKjbSyRql6gmPe4rCsETRV2WW0qBnuMdKNr5Vh5/Uez80xVrfiCCRMTULGeg63Nqg2vg6CDOA=="], + "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260430.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-/DoYC/1wHs+YRZzzqSQg1/EHB4hiv1yV5U8FnmapRRIzVaPtnt+ApeOXeMrIdKidgKOI8TqQzgBU8xbIM7Cl4Q=="], - "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260426.1", "", { "os": "linux", "cpu": "x64" }, "sha512-C8LlC8uSYzg49y51n++75esxZmMp+Uz1OKHHA/4lkv6rjOTbcHQJuEwSLppjybVIXpv7A8MBhbu9iyCTvyv1mw=="], + "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260430.1", "", { "os": "linux", "cpu": "x64" }, "sha512-koJhBWvEVZPKCVFtMLp2iMHlYr+lFCF47wGbnlKdHVlemV0zTxJEyHI8aLlrhPLhBmOmYLp46rXw09/qJkRIhQ=="], - "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260426.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-ESVp/OIFMAqjQsa8BOP2BQQz5Vpfv6ncN6lNnIuNeOgsISQBdYk+LA60bwQHMud9tvmnSYtONp1zkZ8OQz+x6w=="], + "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260430.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-hMdapNAzNQZDXGGkg4Slydc3fRJP5FUZLJVVcZCW/+imhhJro9Z1rv5n/wfR+txKoSWhTYR8eOp8Pyi2bzLzlw=="], - "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260426.1", "", { "os": "win32", "cpu": "x64" }, "sha512-d3Xj/IjINRgNVwH+eKhpUn4xkkcEewbWXbOvBlapiirKWh5zl9m0Epi3qOqmjyRYK6MICqIGXg4qZBEt0lxudw=="], + "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260430.1", "", { "os": "win32", "cpu": "x64" }, "sha512-jS3ffixjb5USOwz4frw4WzCz0HrjVxkgyU3WiYb06N7hBAfN6eOrveAJ4QRef0+suK4V1vQFoB1oKdRBsXe9Dw=="], "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], @@ -242,9 +242,9 @@ "@dprint/win32-x64": ["@dprint/win32-x64@0.54.0", "", { "os": "win32", "cpu": "x64" }, "sha512-AAr2ye/DtgYXDplRoPS+5U++x7T6W4a3I9FvTFWFxziFmUptvAg5G2c4FcXoAduSruhYZJvjDZrLseR2c3IwXg=="], - "@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], + "@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], - "@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], + "@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="], "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], @@ -388,47 +388,47 @@ "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], - "@oxc-parser/binding-android-arm-eabi": ["@oxc-parser/binding-android-arm-eabi@0.127.0", "", { "os": "android", "cpu": "arm" }, "sha512-0LC7ye4hvqbIKxAzThzvswgHLFu2AURKzYLeSVvLdu2TBOYWQDmHnTqPLeA597BcUCxiLqLsS4CJ5uoI5WYWCQ=="], + "@oxc-parser/binding-android-arm-eabi": ["@oxc-parser/binding-android-arm-eabi@0.128.0", "", { "os": "android", "cpu": "arm" }, "sha512-aca6ZvzmCBUGOANQRiRQRZuRKYI3ENhcit6GisnknOOmcezfQc7xJ4dxlPU7MV7mOvrC7RNR1u3LAD7xyaiCxA=="], - "@oxc-parser/binding-android-arm64": ["@oxc-parser/binding-android-arm64@0.127.0", "", { "os": "android", "cpu": "arm64" }, "sha512-b5jtVTH6AU5CJXHNdj7Jj9IEiR9yVjjnwHzPJhGyHGPdcsZSzBCkS9GBbV33niRMvKthDwQRFRJfI4a+k4PvYg=="], + "@oxc-parser/binding-android-arm64": ["@oxc-parser/binding-android-arm64@0.128.0", "", { "os": "android", "cpu": "arm64" }, "sha512-BbeDmuohoJ7Rz/it5wnkj69i/OsCPS3Z51nLEzwO/Y6YshtC4JU+15oNwhY8v4LRKRYclRc7ggOikwrsJ/eOEQ=="], - "@oxc-parser/binding-darwin-arm64": ["@oxc-parser/binding-darwin-arm64@0.127.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-obCE8B7ISKkJidjlhv9xRGJPOSDG2Yu6PRga9Ruaz35uintHxbp1Ki/Yc71wx4rj3Edrm0a1kzG1TAwit0wFpg=="], + "@oxc-parser/binding-darwin-arm64": ["@oxc-parser/binding-darwin-arm64@0.128.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-tRUHPt80417QmvNpoSslJT1VY8NUbWdrWR+L14Zn+RbOTcaqB8E6PYE/ZGN8jjWBzqporiA/H4MfO50ew/NCNA=="], - "@oxc-parser/binding-darwin-x64": ["@oxc-parser/binding-darwin-x64@0.127.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-JL6Xb5IwPQT8rUzlpsX7E+AgfcdNklXNPFp8pjCQQ5MQOQo5rtEB2ui+3Hgg9Sn7Y9Egj6YOLLiHhLpdAe12Aw=="], + "@oxc-parser/binding-darwin-x64": ["@oxc-parser/binding-darwin-x64@0.128.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-rWI2Hb1Nt3U/vKsjyNvZzDC8i/l144U20DKjhzaTmwIhIiSRGeroPWWiImwypmKLqrw8GuIixbWJkpGWLbkzrQ=="], - "@oxc-parser/binding-freebsd-x64": ["@oxc-parser/binding-freebsd-x64@0.127.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SDQ/3MQFw58fqQz3Z1PhSKFF3JoCF4gmlNjziDm8X02tTahCw0qJbd7FGPDKw1i4VTBZene9JPyC3mHtSvi+wA=="], + "@oxc-parser/binding-freebsd-x64": ["@oxc-parser/binding-freebsd-x64@0.128.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hhpdVMaNCLgQxjgNPeeFzSeJMmZPc5lKfv0NGSI3egZq9EdnEGqeC8JsYsQjK7PoQgbvZ17xlj0SO5ziH5Obkg=="], - "@oxc-parser/binding-linux-arm-gnueabihf": ["@oxc-parser/binding-linux-arm-gnueabihf@0.127.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Av+D1MIqzV0YMGPT9we2SIZaMKD7Cxs4CvXSx/yxaWHewZjYEjScpOf5igc8IILASViw4WTnjlwUdI1KzVtDHQ=="], + "@oxc-parser/binding-linux-arm-gnueabihf": ["@oxc-parser/binding-linux-arm-gnueabihf@0.128.0", "", { "os": "linux", "cpu": "arm" }, "sha512-093zNw0zZ/e/obML+rhlSdmnzR0mVZluPcAkxunEc5E3F0yBVsFn24Y1ILfsEte11Ud041qn/gp2OJ1jxNqUng=="], - "@oxc-parser/binding-linux-arm-musleabihf": ["@oxc-parser/binding-linux-arm-musleabihf@0.127.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Cs2fdJ8cPpFdeebj6p4dag8A4+56hPvZ0AhQQzlaLswGz1tz7bXt1nETLeorrM9+AMcWFFkqxcXwDGfTVidY8g=="], + "@oxc-parser/binding-linux-arm-musleabihf": ["@oxc-parser/binding-linux-arm-musleabihf@0.128.0", "", { "os": "linux", "cpu": "arm" }, "sha512-fq7DmKmfC+dvD97IXrgbph6Jzwe0EDu+PYMofmzZ6fv5X1k9vtaqLpDGMuICO9MmUnyKAQmVl+wIv2RNy4Dz8g=="], - "@oxc-parser/binding-linux-arm64-gnu": ["@oxc-parser/binding-linux-arm64-gnu@0.127.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-qdOfTcT6SY8gsJrrV92uyEUyjqMGPpIB5JZUG6QN5dukYd+7/j0kX6MwK1DgQj39jtUYixxPiaRUiEN1+0CXgQ=="], + "@oxc-parser/binding-linux-arm64-gnu": ["@oxc-parser/binding-linux-arm64-gnu@0.128.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Xvm48jJah8TlIrURIjNOP/gNiGe6aKvCB+r06VliflFo8Kq7VOLE8PxtgShJzZIqubrgdMdYfvuPPozn7F6MbQ=="], - "@oxc-parser/binding-linux-arm64-musl": ["@oxc-parser/binding-linux-arm64-musl@0.127.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-EoTCZneNFU/P2qrpEM+RHmQwt+CvDkyGESG6qhr7KaegXLZwePfbrkCDfAk8/rhxbDUVGsZILX+2tqPzFtoFWA=="], + "@oxc-parser/binding-linux-arm64-musl": ["@oxc-parser/binding-linux-arm64-musl@0.128.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-M7iwBGmYJTx+pKOYFjI0buop4gJvlmcVzFGaXPt21DKpQkbQZG1f63Yg7LloIYT/t9yLxCw0Lhfx/RFlAlMSjA=="], - "@oxc-parser/binding-linux-ppc64-gnu": ["@oxc-parser/binding-linux-ppc64-gnu@0.127.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-zALjmZYgxFLHjXeudcDF0xFGNydTAtkAeXAr2EuC17ywCyFxcmQra4w0BMde0Yi/re4Bi4iwEoEXtYN7l6eBLQ=="], + "@oxc-parser/binding-linux-ppc64-gnu": ["@oxc-parser/binding-linux-ppc64-gnu@0.128.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-21LGNIZb1Pcfk5/EGsqabrxv4yqQOWis1407JJrClS7XpFCrbvr74YAB1V+m54cYbwvO6UWwQqS4WecxiyfCRg=="], - "@oxc-parser/binding-linux-riscv64-gnu": ["@oxc-parser/binding-linux-riscv64-gnu@0.127.0", "", { "os": "linux", "cpu": "none" }, "sha512-fPP8M6zQLS7Jz7o9d5ArUSuAuSK3e+WCYVrCpdzeCOejidtZExJ9tjhDrAd3HEPqARBCPmdpqxESPFqy44vkBQ=="], + "@oxc-parser/binding-linux-riscv64-gnu": ["@oxc-parser/binding-linux-riscv64-gnu@0.128.0", "", { "os": "linux", "cpu": "none" }, "sha512-gyHjOTFpg9bTTYjxPmQirvufb89+VdZwVfcMtAUyPr6F5H8ZswvCQshK4qOW+Q+2Xyb33hduRgY/eFHJQjU/vQ=="], - "@oxc-parser/binding-linux-riscv64-musl": ["@oxc-parser/binding-linux-riscv64-musl@0.127.0", "", { "os": "linux", "cpu": "none" }, "sha512-7IcC4Ao02oGpfnjt+X/oF4U2mllo2qoSkw5xxiXNKL9MCTsTiAC6616beOuehdxGcnz1bRoPC1RQ2f1GQDdN+g=="], + "@oxc-parser/binding-linux-riscv64-musl": ["@oxc-parser/binding-linux-riscv64-musl@0.128.0", "", { "os": "linux", "cpu": "none" }, "sha512-X6Q2oKUrP5GyDd2xniuEBLk6aFQCZ97W2+aVXGgJXdjx5t4/oFuA9ri0wLOUrBIX+qdSuK581snMBio4z910eA=="], - "@oxc-parser/binding-linux-s390x-gnu": ["@oxc-parser/binding-linux-s390x-gnu@0.127.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-pbXIhiNFHoqWeqDNLiJ9JkpHz1IM9k4DXa66x+1GTWMG7iLxtkXgE53iiuKSXwmk3zIYmaPVfBvgcAhS583K4Q=="], + "@oxc-parser/binding-linux-s390x-gnu": ["@oxc-parser/binding-linux-s390x-gnu@0.128.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-BdzTmqxfxoYkpgokoLaSnOX6T+R3/goL42klre2tnG+kHbG2TXS0VN+P5BPofH1axdKOHy5ei4ENZrjmCOt2lA=="], - "@oxc-parser/binding-linux-x64-gnu": ["@oxc-parser/binding-linux-x64-gnu@0.127.0", "", { "os": "linux", "cpu": "x64" }, "sha512-MYCguB9RvBvlSd6gbuNI7QwiLoCCAlGnlRJFPrzLI6U1/9wkC/WK6LtBAUln55H1Ctqw45PWmqrobKoMhsYQzQ=="], + "@oxc-parser/binding-linux-x64-gnu": ["@oxc-parser/binding-linux-x64-gnu@0.128.0", "", { "os": "linux", "cpu": "x64" }, "sha512-OO1nW2Q7sSYYvJZpDHdvyFSdRaVcQqRijZSSmWVMqFxPYy8cEF45zJ9fcdIYuzIT3jYq6YRhEFm/VMWNWhE22Q=="], - "@oxc-parser/binding-linux-x64-musl": ["@oxc-parser/binding-linux-x64-musl@0.127.0", "", { "os": "linux", "cpu": "x64" }, "sha512-5eY0B/bxf1xIUxb4NOTvOI3KWtBQfPWYyKAzgcrCt0mDibSZygVpO1Pz8bkeiSZ5Jj9+M09dkggG3H8I5d0Uyg=="], + "@oxc-parser/binding-linux-x64-musl": ["@oxc-parser/binding-linux-x64-musl@0.128.0", "", { "os": "linux", "cpu": "x64" }, "sha512-4NehAe404MRdoZVS9DW8C5XbJwbXIc/KfVlYdpi5vE4081zc9Y0YzKVqyOYj/Puye7/Do+ohaONBFWlEHYl9hw=="], - "@oxc-parser/binding-openharmony-arm64": ["@oxc-parser/binding-openharmony-arm64@0.127.0", "", { "os": "none", "cpu": "arm64" }, "sha512-Gld0ajrFTUXNtdw20fVBuTQx66FA75nIVg+//pPfR3sXkuABB4mTBhl3r9JNzrJpgW//qiwxf0nWXUWGJSL3UQ=="], + "@oxc-parser/binding-openharmony-arm64": ["@oxc-parser/binding-openharmony-arm64@0.128.0", "", { "os": "none", "cpu": "arm64" }, "sha512-kVbqgW9xLL8bh8oc7aYOJilRKXE5G33+tE0jan+duo/9OriaFRpijcCwT2waWs2oqYROYq0GlE7/p3ywoshVeg=="], - "@oxc-parser/binding-wasm32-wasi": ["@oxc-parser/binding-wasm32-wasi@0.127.0", "", { "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-T6KVD7rhLzFlwGRXMnxUFfkCZD8FHnb968wVXW1mXzgRFc5RNXOBY2mPPDZ77x5Ln76ltLMgtPg0cOkU1NSrEQ=="], + "@oxc-parser/binding-wasm32-wasi": ["@oxc-parser/binding-wasm32-wasi@0.128.0", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-L38ojghJYHmgiz6fJd7jwLB/ESDBpB02NdFxh+smqVM6P2anCEvHn0jhaSrt5eVNR1Ak8+moOeftUlofeyvniA=="], - "@oxc-parser/binding-win32-arm64-msvc": ["@oxc-parser/binding-win32-arm64-msvc@0.127.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Ujvw4X+LD1CCGULcsQcvb4YNVoBGqt+JHgNNzGGaCImELiZLk477ifUH53gIbE7EKd933NdTi25JWEr9K2HwXw=="], + "@oxc-parser/binding-win32-arm64-msvc": ["@oxc-parser/binding-win32-arm64-msvc@0.128.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-xgvO35GyHBtjlQ5AEpaYr7Rll1rvY7zqIhT6ty8E3ezBW2J1SFLjIDEvI/tcgDg6oaseDAqVcM+jU1HuCekgZw=="], - "@oxc-parser/binding-win32-ia32-msvc": ["@oxc-parser/binding-win32-ia32-msvc@0.127.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-0cwxKO7KHQQQfo4Uf4B2SQrhgm+cJaP9OvFFhx52Tkg4bezsacu83GB2/In5bC415Ueeym+kXdnge/57rbSfTw=="], + "@oxc-parser/binding-win32-ia32-msvc": ["@oxc-parser/binding-win32-ia32-msvc@0.128.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-OY+3eM2SN72prHKRB22mPz8o5A/7dJ+f5DFLBVvggyZhEaNDAH9IB+ElMjmOkOIwf5MDCUAowCK7pAncNxzpBA=="], - "@oxc-parser/binding-win32-x64-msvc": ["@oxc-parser/binding-win32-x64-msvc@0.127.0", "", { "os": "win32", "cpu": "x64" }, "sha512-rOrnSQSCbhI2kowr9XxE7m9a8oQXnBHjnS6j95LxxAnEZ0+Fz20WlRXG4ondQb+ejjt2KOsa65sE6++L6kUd+w=="], + "@oxc-parser/binding-win32-x64-msvc": ["@oxc-parser/binding-win32-x64-msvc@0.128.0", "", { "os": "win32", "cpu": "x64" }, "sha512-NE9ny+cPUCCObXa0IKLfj0tCdPd7pe/dz9ZpkxpUOymB3miNeMPybdlYYTBSGJUalMWeBM85/4JcCErCNTqOXw=="], - "@oxc-project/types": ["@oxc-project/types@0.127.0", "", {}, "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ=="], + "@oxc-project/types": ["@oxc-project/types@0.128.0", "", {}, "sha512-huv1Y/LzBJkBVHt3OlC7u0zHBW9qXf1FdD7sGmc1rXc2P1mTwHssYv7jyGx5KAACSCH+9B3Bhn6Z9luHRvf7pQ=="], "@oxc-resolver/binding-android-arm-eabi": ["@oxc-resolver/binding-android-arm-eabi@11.19.1", "", { "os": "android", "cpu": "arm" }, "sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg=="], @@ -480,37 +480,37 @@ "@quansync/fs": ["@quansync/fs@1.0.0", "", { "dependencies": { "quansync": "^1.0.0" } }, "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ=="], - "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.12", "", { "os": "android", "cpu": "arm64" }, "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.17", "", { "os": "android", "cpu": "arm64" }, "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ=="], - "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg=="], + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.17", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw=="], - "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw=="], + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.17", "", { "os": "darwin", "cpu": "x64" }, "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw=="], - "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q=="], + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.17", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw=="], - "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm" }, "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q=="], + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17", "", { "os": "linux", "cpu": "arm" }, "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ=="], - "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg=="], + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q=="], - "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw=="], + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg=="], - "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g=="], + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17", "", { "os": "linux", "cpu": "ppc64" }, "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA=="], - "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og=="], + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17", "", { "os": "linux", "cpu": "s390x" }, "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA=="], - "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "x64" }, "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg=="], + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.17", "", { "os": "linux", "cpu": "x64" }, "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA=="], - "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.12", "", { "os": "linux", "cpu": "x64" }, "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig=="], + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.17", "", { "os": "linux", "cpu": "x64" }, "sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw=="], - "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.12", "", { "os": "none", "cpu": "arm64" }, "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA=="], + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.17", "", { "os": "none", "cpu": "arm64" }, "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA=="], - "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.12", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg=="], + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.17", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA=="], - "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q=="], + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17", "", { "os": "win32", "cpu": "arm64" }, "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA=="], - "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.12", "", { "os": "win32", "cpu": "x64" }, "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw=="], + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.17", "", { "os": "win32", "cpu": "x64" }, "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg=="], - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.12", "", {}, "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw=="], + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.17", "", {}, "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg=="], "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.1", "", { "os": "android", "cpu": "arm" }, "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA=="], @@ -690,21 +690,21 @@ "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], - "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260428.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260428.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260428.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260428.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260428.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260428.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260428.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260428.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-JiM4PYWDGs57TT0mV2KArmaW7BnTkk3XRid79NdG17tfvDbRyg4hBCpKI7vARiQPtxjKrHlxyzxOGDpv5W5T7Q=="], + "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260501.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260501.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260501.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260501.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260501.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260501.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260501.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260501.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-skD0ig8IzPwSY1L8VmNgfaxkfT8ImBwKeIypfZyJA+zHzWvroRKbRbT2GryOSREl22ZqLOuDfcq+7BdA0rjF2Q=="], - "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260428.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Lll6WmXfgTEj1G3QBIoHlabQwUtJiyhlRgSLksa06QFL5BoA7V+Lu1waa9PtPNZbGsXLDMHodtk/bRQABKuPiw=="], + "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260501.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-OIYsqKouI2U7W5Q6VgUz7+t9FpIXNFk30xSUG7gGlN1bdDniWfW7t5n6mzEtiHUVTxRgJQBjXGAlhVa6A9h+pg=="], - "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260428.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-WbsBNSHlo+4sGrTxDWdmI7r8x48tCtSCuKdmK62FvVOq58UWAs6sL13Z4Rev4ohLcGHdXC5E/8AIdpLPqDYQpw=="], + "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260501.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-hQ5UsEyOz3ErQE3sKKHMCfJJGQenD0DSCi2ob+ywElXirG2NyFNA8cmx1g+MIm1lpQeEQslWZhe9EGwo9DJAbg=="], - "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260428.1", "", { "os": "linux", "cpu": "arm" }, "sha512-/d/NnZFvEJU67L5mHh+cO3gsfwNCvJ9HGtxGq1KGz1VwTabOIcwLdpTpfsAR39WXzzfh9GJHL28n6GSGZInPow=="], + "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260501.1", "", { "os": "linux", "cpu": "arm" }, "sha512-agkTW/t85XSJKWGcXdUV9ZmSi3Akh3POK+HhWehigEJR3W/jebiO9njifETfoUF6cpoYkFn+CZvfAJ00IWGZfA=="], - "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260428.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cgcBX/ZBMdepkamLT8g8jQdHe7DZS/s6zTZRof6mvcrnJHlMeUnKoC9UO8/c22IrUMV3n0XPh7R8FYjUP0ll+Q=="], + "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260501.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-fbaFKE1UvtsQ6i1eJjBiNbglR9ywXrW/CH1sqYPEtr0WgTUpixbE6inQOXjB0jlEA9RzQq+QMzDyaCDmU82Dkw=="], - "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260428.1", "", { "os": "linux", "cpu": "x64" }, "sha512-4gJCE7wzenx1BH2Vtx2uKWUo8rFxnhGkxNEH1zxbYy/6ASwo+PnOPYmKHAzNE1C3yB5lzw71/vR5p5zyO57Y4A=="], + "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260501.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Sd8D+S88P7K0IH1U+a8pK20ZD+GM54t48/GLw9ebSklfCdt0iKdHgprjKIcl54C3SocGCcvEBPr1thwtTO9Vtg=="], - "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260428.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-yn6Rzbn62L4QTWrp0QgG8al6l/VG7PCPRdbE0vuGDSlKhInlC+Flo4QSc1qA8KHTbpHgl+nEsq9DymiitI4G4g=="], + "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260501.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-07sJNDnU7KHfo/trv/cBXpgFBELDYJAsTx5kNvBckSQUxbX+p/b9oQ3eFbtK3zDP4EEKdeiD9EelIy22atBnzA=="], - "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260428.1", "", { "os": "win32", "cpu": "x64" }, "sha512-T9z13mcMowXmwGjprA2FIR2EEdYZxgqH8+qk7dFZVBlo5vfk41AN/qJfAdN7IsAhEb640MJ8cMN/aiczweZKmA=="], + "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260501.1", "", { "os": "win32", "cpu": "x64" }, "sha512-8rzd/eQZyBuR+IRiPnIQrCwSuXIGBFiL8LsUMFqQt2WAUlQ0gGWBlLJHUVU4YNlju9QROjNHUGpJ52XGZbFv0Q=="], "@typescript/vfs": ["@typescript/vfs@1.6.4", "", { "dependencies": { "debug": "^4.4.3" }, "peerDependencies": { "typescript": "*" } }, "sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ=="], @@ -714,33 +714,33 @@ "@vitejs/plugin-vue": ["@vitejs/plugin-vue@6.0.5", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-rc.2" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", "vue": "^3.2.25" } }, "sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg=="], - "@vitest/coverage-v8": ["@vitest/coverage-v8@4.1.4", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.1.4", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.2.0", "magicast": "^0.5.2", "obug": "^2.1.1", "std-env": "^4.0.0-rc.1", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "@vitest/browser": "4.1.4", "vitest": "4.1.4" }, "optionalPeers": ["@vitest/browser"] }, "sha512-x7FptB5oDruxNPDNY2+S8tCh0pcq7ymCe1gTHcsp733jYjrJl8V1gMUlVysuCD9Kz46Xz9t1akkv08dPcYDs1w=="], + "@vitest/coverage-v8": ["@vitest/coverage-v8@4.1.5", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.1.5", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.2.0", "magicast": "^0.5.2", "obug": "^2.1.1", "std-env": "^4.0.0-rc.1", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "@vitest/browser": "4.1.5", "vitest": "4.1.5" }, "optionalPeers": ["@vitest/browser"] }, "sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A=="], - "@vitest/expect": ["@vitest/expect@4.1.4", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.4", "@vitest/utils": "4.1.4", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww=="], + "@vitest/expect": ["@vitest/expect@4.1.5", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.5", "@vitest/utils": "4.1.5", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw=="], - "@vitest/mocker": ["@vitest/mocker@4.1.4", "", { "dependencies": { "@vitest/spy": "4.1.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg=="], + "@vitest/mocker": ["@vitest/mocker@4.1.5", "", { "dependencies": { "@vitest/spy": "4.1.5", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw=="], - "@vitest/pretty-format": ["@vitest/pretty-format@4.1.4", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A=="], + "@vitest/pretty-format": ["@vitest/pretty-format@4.1.5", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g=="], - "@vitest/runner": ["@vitest/runner@4.1.4", "", { "dependencies": { "@vitest/utils": "4.1.4", "pathe": "^2.0.3" } }, "sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ=="], + "@vitest/runner": ["@vitest/runner@4.1.5", "", { "dependencies": { "@vitest/utils": "4.1.5", "pathe": "^2.0.3" } }, "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ=="], - "@vitest/snapshot": ["@vitest/snapshot@4.1.4", "", { "dependencies": { "@vitest/pretty-format": "4.1.4", "@vitest/utils": "4.1.4", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw=="], + "@vitest/snapshot": ["@vitest/snapshot@4.1.5", "", { "dependencies": { "@vitest/pretty-format": "4.1.5", "@vitest/utils": "4.1.5", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ=="], - "@vitest/spy": ["@vitest/spy@4.1.4", "", {}, "sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ=="], + "@vitest/spy": ["@vitest/spy@4.1.5", "", {}, "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ=="], - "@vitest/utils": ["@vitest/utils@4.1.4", "", { "dependencies": { "@vitest/pretty-format": "4.1.4", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw=="], + "@vitest/utils": ["@vitest/utils@4.1.5", "", { "dependencies": { "@vitest/pretty-format": "4.1.5", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug=="], "@volar/language-core": ["@volar/language-core@2.4.28", "", { "dependencies": { "@volar/source-map": "2.4.28" } }, "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ=="], "@volar/source-map": ["@volar/source-map@2.4.28", "", {}, "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ=="], - "@vue/compiler-core": ["@vue/compiler-core@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/shared": "3.5.32", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ=="], + "@vue/compiler-core": ["@vue/compiler-core@3.5.33", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/shared": "3.5.33", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-3PZLQwFw4Za3TC8t0FvTy3wI16Kt+pmwcgNZca4Pj9iWL2E72a/gZlpBtAJvEdDMdCxdG/qq0C7PN0bsJuv0Rw=="], - "@vue/compiler-dom": ["@vue/compiler-dom@3.5.32", "", { "dependencies": { "@vue/compiler-core": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q=="], + "@vue/compiler-dom": ["@vue/compiler-dom@3.5.33", "", { "dependencies": { "@vue/compiler-core": "3.5.33", "@vue/shared": "3.5.33" } }, "sha512-PXq0yrfCLzzL07rbXO4awtXY1Z06LG2eu6Adg3RJFa/j3Cii217XxxLXG22N330gw7GmALCY0Z8RgXEviwgpjA=="], - "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/compiler-core": "3.5.32", "@vue/compiler-dom": "3.5.32", "@vue/compiler-ssr": "3.5.32", "@vue/shared": "3.5.32", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.8", "source-map-js": "^1.2.1" } }, "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg=="], + "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.33", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/compiler-core": "3.5.33", "@vue/compiler-dom": "3.5.33", "@vue/compiler-ssr": "3.5.33", "@vue/shared": "3.5.33", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.10", "source-map-js": "^1.2.1" } }, "sha512-UTUvRO9cY+rROrx/pvN9P5Z7FgA6QGfokUCfhQE4EnmUj3rVnK+CHI0LsEO1pg+I7//iRYMUfcNcCPe7tg0CoA=="], - "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.32", "", { "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw=="], + "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.33", "", { "dependencies": { "@vue/compiler-dom": "3.5.33", "@vue/shared": "3.5.33" } }, "sha512-IErjYdnj1qIupG5xxiVIYiiRvDhGWV4zuh/RCrwfYpuL+HWQzeU6lCk/nF9r7olWMnjKxCAkOctT2qFWFkzb1A=="], "@vue/devtools-api": ["@vue/devtools-api@8.1.1", "", { "dependencies": { "@vue/devtools-kit": "^8.1.1" } }, "sha512-bsDMJ07b3GN1puVwJb/fyFnj/U2imyswK5UQVLZwVl7O05jDrt6BHxeG5XffmOOdasOj/bOmIjxJvGPxU7pcqw=="], @@ -750,13 +750,13 @@ "@vue/language-core": ["@vue/language-core@3.2.6", "", { "dependencies": { "@volar/language-core": "2.4.28", "@vue/compiler-dom": "^3.5.0", "@vue/shared": "^3.5.0", "alien-signals": "^3.0.0", "muggle-string": "^0.4.1", "path-browserify": "^1.0.1", "picomatch": "^4.0.2" } }, "sha512-xYYYX3/aVup576tP/23sEUpgiEnujrENaoNRbaozC1/MA9I6EGFQRJb4xrt/MmUCAGlxTKL2RmT8JLTPqagCkg=="], - "@vue/reactivity": ["@vue/reactivity@3.5.32", "", { "dependencies": { "@vue/shared": "3.5.32" } }, "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ=="], + "@vue/reactivity": ["@vue/reactivity@3.5.33", "", { "dependencies": { "@vue/shared": "3.5.33" } }, "sha512-p8UfIqyIhb0rYGlSgSBV+lPhF2iUSBcRy7enhTmPqKWadHy9kcOFYF1AejYBP9P+avnd3OBbD49DU4pLWX/94A=="], - "@vue/runtime-core": ["@vue/runtime-core@3.5.32", "", { "dependencies": { "@vue/reactivity": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ=="], + "@vue/runtime-core": ["@vue/runtime-core@3.5.33", "", { "dependencies": { "@vue/reactivity": "3.5.33", "@vue/shared": "3.5.33" } }, "sha512-UpFF45RI9//a7rvq7RdOQblb4tup7hHG9QsmIrxkFQLzQ7R8/iNQ5LE15NhLZ1/WcHMU2b47u6P33CPUelHyIQ=="], - "@vue/runtime-dom": ["@vue/runtime-dom@3.5.32", "", { "dependencies": { "@vue/reactivity": "3.5.32", "@vue/runtime-core": "3.5.32", "@vue/shared": "3.5.32", "csstype": "^3.2.3" } }, "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ=="], + "@vue/runtime-dom": ["@vue/runtime-dom@3.5.33", "", { "dependencies": { "@vue/reactivity": "3.5.33", "@vue/runtime-core": "3.5.33", "@vue/shared": "3.5.33", "csstype": "^3.2.3" } }, "sha512-IOxMsAOwquhfITgmOgaPYl7/j8gKUxUFoflRc+u4LxyD3+783xne8vNta1PONVCvCV9A0w7hkyEepINDqfO0tw=="], - "@vue/server-renderer": ["@vue/server-renderer@3.5.32", "", { "dependencies": { "@vue/compiler-ssr": "3.5.32", "@vue/shared": "3.5.32" }, "peerDependencies": { "vue": "3.5.32" } }, "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ=="], + "@vue/server-renderer": ["@vue/server-renderer@3.5.33", "", { "dependencies": { "@vue/compiler-ssr": "3.5.33", "@vue/shared": "3.5.33" }, "peerDependencies": { "vue": "3.5.33" } }, "sha512-0xylq/8/h44lVG0pZFknv1XIdEgymq2E9n59uTWJBG+dIgiT0TMCSsxrN7nO16Z0MU0MPjFcguBbZV8Itk52Hw=="], "@vue/shared": ["@vue/shared@3.5.32", "", {}, "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg=="], @@ -960,7 +960,7 @@ "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], - "hookable": ["hookable@6.1.0", "", {}, "sha512-ZoKZSJgu8voGK2geJS+6YtYjvIzu9AOM/KZXsBxr83uhLL++e9pEv/dlgwgy3dvHg06kTz6JOh1hk3C8Ceiymw=="], + "hookable": ["hookable@6.1.1", "", {}, "sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ=="], "html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="], @@ -968,7 +968,7 @@ "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], - "import-without-cache": ["import-without-cache@0.2.5", "", {}, "sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A=="], + "import-without-cache": ["import-without-cache@0.3.3", "", {}, "sha512-bDxwDdF04gm550DfZHgffvlX+9kUlcz32UD0AeBTmVPFiWkrexF2XVmiuFFbDhiFuP8fQkrkvI2KdSNPYWAXkQ=="], "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], @@ -990,7 +990,7 @@ "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], - "knip": ["knip@6.7.0", "", { "dependencies": { "fdir": "^6.5.0", "formatly": "^0.3.0", "get-tsconfig": "4.14.0", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.127.0", "oxc-resolver": "^11.19.1", "picomatch": "^4.0.4", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "tinyglobby": "^0.2.16", "unbash": "^3.0.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-ckL51NDH1YJxnv1kNB0iUdDngB4f/e9Igz8uIqYfmNDoyOFmmk1V0WFv3LQ7/hzC63b2Z9X41gGUE9eOWrZpaA=="], + "knip": ["knip@6.9.0", "", { "dependencies": { "fdir": "^6.5.0", "formatly": "^0.3.0", "get-tsconfig": "4.14.0", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.128.0", "oxc-resolver": "^11.19.1", "picomatch": "^4.0.4", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "tinyglobby": "^0.2.16", "unbash": "^3.0.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-2GLjxteBwmsSA3Z5sJZpPDaNPBIMnlm4/9Nx4CZadEK7YccJZ2/4kwKgPWhVYEqxhwhD0WO4txWXNGTO/Odkkg=="], "langium": ["langium@4.2.2", "", { "dependencies": { "@chevrotain/regexp-to-ast": "~12.0.0", "chevrotain": "~12.0.0", "chevrotain-allstar": "~0.4.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.1.0" } }, "sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ=="], @@ -1116,7 +1116,7 @@ "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], - "miniflare": ["miniflare@4.20260426.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.8", "workerd": "1.20260426.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-KM+v76d04qT+NsPfVKVQEgnnuLNE3uzCCl2QKMTJ5OXor5JbBm1vpkQwQ+l7o5ELCrZ74RnyKhJKLiJyUA39Tw=="], + "miniflare": ["miniflare@4.20260430.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.8", "workerd": "1.20260430.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-MWvMm3Siho9Yj7lbJZidLs8hbrRvIcOrif2mnsHQZdvoKfedpea+GaN8XJxbpRcq0B2WzNI1BB1ihdnqes3/ZA=="], "minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], @@ -1142,7 +1142,7 @@ "oniguruma-to-es": ["oniguruma-to-es@4.3.5", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.1.0", "regex-recursion": "^6.0.2" } }, "sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ=="], - "oxc-parser": ["oxc-parser@0.127.0", "", { "dependencies": { "@oxc-project/types": "^0.127.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.127.0", "@oxc-parser/binding-android-arm64": "0.127.0", "@oxc-parser/binding-darwin-arm64": "0.127.0", "@oxc-parser/binding-darwin-x64": "0.127.0", "@oxc-parser/binding-freebsd-x64": "0.127.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.127.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.127.0", "@oxc-parser/binding-linux-arm64-gnu": "0.127.0", "@oxc-parser/binding-linux-arm64-musl": "0.127.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.127.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.127.0", "@oxc-parser/binding-linux-riscv64-musl": "0.127.0", "@oxc-parser/binding-linux-s390x-gnu": "0.127.0", "@oxc-parser/binding-linux-x64-gnu": "0.127.0", "@oxc-parser/binding-linux-x64-musl": "0.127.0", "@oxc-parser/binding-openharmony-arm64": "0.127.0", "@oxc-parser/binding-wasm32-wasi": "0.127.0", "@oxc-parser/binding-win32-arm64-msvc": "0.127.0", "@oxc-parser/binding-win32-ia32-msvc": "0.127.0", "@oxc-parser/binding-win32-x64-msvc": "0.127.0" } }, "sha512-bkgD4qHlN7WxLdX8bLXdaU54TtQtAIg/ZBAfm0aje/mo3MRDo3P0hZSgr4U7O3xfX+fQmR5AP04JS/TGcZLcFA=="], + "oxc-parser": ["oxc-parser@0.128.0", "", { "dependencies": { "@oxc-project/types": "^0.128.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.128.0", "@oxc-parser/binding-android-arm64": "0.128.0", "@oxc-parser/binding-darwin-arm64": "0.128.0", "@oxc-parser/binding-darwin-x64": "0.128.0", "@oxc-parser/binding-freebsd-x64": "0.128.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.128.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.128.0", "@oxc-parser/binding-linux-arm64-gnu": "0.128.0", "@oxc-parser/binding-linux-arm64-musl": "0.128.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.128.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.128.0", "@oxc-parser/binding-linux-riscv64-musl": "0.128.0", "@oxc-parser/binding-linux-s390x-gnu": "0.128.0", "@oxc-parser/binding-linux-x64-gnu": "0.128.0", "@oxc-parser/binding-linux-x64-musl": "0.128.0", "@oxc-parser/binding-openharmony-arm64": "0.128.0", "@oxc-parser/binding-wasm32-wasi": "0.128.0", "@oxc-parser/binding-win32-arm64-msvc": "0.128.0", "@oxc-parser/binding-win32-ia32-msvc": "0.128.0", "@oxc-parser/binding-win32-x64-msvc": "0.128.0" } }, "sha512-XkOw3eiIxAgQ19WRew/Bq9wc5Ga/guaWIzDBzq80z1PyuDNGvWBpPby9k6YGwV8A8uMw+Nlq3xqlzuDYmUFYUw=="], "oxc-resolver": ["oxc-resolver@11.19.1", "", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.19.1", "@oxc-resolver/binding-android-arm64": "11.19.1", "@oxc-resolver/binding-darwin-arm64": "11.19.1", "@oxc-resolver/binding-darwin-x64": "11.19.1", "@oxc-resolver/binding-freebsd-x64": "11.19.1", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.19.1", "@oxc-resolver/binding-linux-arm-musleabihf": "11.19.1", "@oxc-resolver/binding-linux-arm64-gnu": "11.19.1", "@oxc-resolver/binding-linux-arm64-musl": "11.19.1", "@oxc-resolver/binding-linux-ppc64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-musl": "11.19.1", "@oxc-resolver/binding-linux-s390x-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-musl": "11.19.1", "@oxc-resolver/binding-openharmony-arm64": "11.19.1", "@oxc-resolver/binding-wasm32-wasi": "11.19.1", "@oxc-resolver/binding-win32-arm64-msvc": "11.19.1", "@oxc-resolver/binding-win32-ia32-msvc": "11.19.1", "@oxc-resolver/binding-win32-x64-msvc": "11.19.1" } }, "sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg=="], @@ -1168,7 +1168,7 @@ "points-on-path": ["points-on-path@0.2.1", "", { "dependencies": { "path-data-parser": "0.1.0", "points-on-curve": "0.2.0" } }, "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g=="], - "postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], + "postcss": ["postcss@8.5.13", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag=="], "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], @@ -1190,7 +1190,7 @@ "robust-predicates": ["robust-predicates@3.0.3", "", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="], - "rolldown": ["rolldown@1.0.0-rc.12", "", { "dependencies": { "@oxc-project/types": "=0.122.0", "@rolldown/pluginutils": "1.0.0-rc.12" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.12", "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", "@rolldown/binding-darwin-x64": "1.0.0-rc.12", "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A=="], + "rolldown": ["rolldown@1.0.0-rc.17", "", { "dependencies": { "@oxc-project/types": "=0.127.0", "@rolldown/pluginutils": "1.0.0-rc.17" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.17", "@rolldown/binding-darwin-arm64": "1.0.0-rc.17", "@rolldown/binding-darwin-x64": "1.0.0-rc.17", "@rolldown/binding-freebsd-x64": "1.0.0-rc.17", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA=="], "rolldown-plugin-dts": ["rolldown-plugin-dts@0.23.2", "", { "dependencies": { "@babel/generator": "8.0.0-rc.3", "@babel/helper-validator-identifier": "8.0.0-rc.3", "@babel/parser": "8.0.0-rc.3", "@babel/types": "8.0.0-rc.3", "ast-kit": "^3.0.0-beta.1", "birpc": "^4.0.0", "dts-resolver": "^2.1.3", "get-tsconfig": "^4.13.7", "obug": "^2.1.1", "picomatch": "^4.0.4" }, "peerDependencies": { "@ts-macro/tsc": "^0.3.6", "@typescript/native-preview": ">=7.0.0-dev.20260325.1", "rolldown": "^1.0.0-rc.12", "typescript": "^5.0.0 || ^6.0.0", "vue-tsc": "~3.2.0" }, "optionalPeers": ["@ts-macro/tsc", "@typescript/native-preview", "typescript", "vue-tsc"] }, "sha512-PbSqLawLgZBGcOGT3yqWBGn4cX+wh2nt5FuBGdcMHyOhoukmjbhYAl8NT9sE4U38Cm9tqLOIQeOrvzeayM0DLQ=="], @@ -1246,7 +1246,7 @@ "ts-dedent": ["ts-dedent@2.2.0", "", {}, "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="], - "tsdown": ["tsdown@0.21.7", "", { "dependencies": { "ansis": "^4.2.0", "cac": "^7.0.0", "defu": "^6.1.4", "empathic": "^2.0.0", "hookable": "^6.1.0", "import-without-cache": "^0.2.5", "obug": "^2.1.1", "picomatch": "^4.0.4", "rolldown": "1.0.0-rc.12", "rolldown-plugin-dts": "^0.23.2", "semver": "^7.7.4", "tinyexec": "^1.0.4", "tinyglobby": "^0.2.15", "tree-kill": "^1.2.2", "unconfig-core": "^7.5.0", "unrun": "^0.2.34" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.21.7", "@tsdown/exe": "0.21.7", "@vitejs/devtools": "*", "publint": "^0.3.0", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@vitejs/devtools", "publint", "typescript", "unplugin-unused"], "bin": { "tsdown": "dist/run.mjs" } }, "sha512-ukKIxKQzngkWvOYJAyptudclkm4VQqbjq+9HF5K5qDO8GJsYtMh8gIRwicbnZEnvFPr6mquFwYAVZ8JKt3rY2g=="], + "tsdown": ["tsdown@0.21.10", "", { "dependencies": { "ansis": "^4.2.0", "cac": "^7.0.0", "defu": "^6.1.7", "empathic": "^2.0.0", "hookable": "^6.1.1", "import-without-cache": "^0.3.3", "obug": "^2.1.1", "picomatch": "^4.0.4", "rolldown": "1.0.0-rc.17", "rolldown-plugin-dts": "^0.23.2", "semver": "^7.7.4", "tinyexec": "^1.1.1", "tinyglobby": "^0.2.16", "tree-kill": "^1.2.2", "unconfig-core": "^7.5.0", "unrun": "^0.2.37" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.21.10", "@tsdown/exe": "0.21.10", "@vitejs/devtools": "*", "publint": "^0.3.0", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@vitejs/devtools", "publint", "typescript", "unplugin-unused"], "bin": { "tsdown": "dist/run.mjs" } }, "sha512-3wk73yBhZe/wX7REqSdivNQ84TDs1mJ+IlnzrrEREP70xlJ/AEIzqaI04l/TzMKVIdkTdC3CPaADn2Lk/0SkdA=="], "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], @@ -1258,9 +1258,9 @@ "twoslash-vue": ["twoslash-vue@0.3.6", "", { "dependencies": { "@vue/language-core": "^3.2.0", "twoslash": "0.3.6", "twoslash-protocol": "0.3.6" }, "peerDependencies": { "typescript": "^5.5.0" } }, "sha512-HXYxU+Y7jZiMXJN4980fQNMYflLD8uqKey1qVW5ri8bqYTm2t5ILmOoCOli7esdCHlMq4/No3iQUWBWDhZNs9w=="], - "typedoc": ["typedoc@0.28.18", "", { "dependencies": { "@gerrit0/mini-shiki": "^3.23.0", "lunr": "^2.3.9", "markdown-it": "^14.1.1", "minimatch": "^10.2.4", "yaml": "^2.8.2" }, "peerDependencies": { "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x" }, "bin": { "typedoc": "bin/typedoc" } }, "sha512-NTWTUOFRQ9+SGKKTuWKUioUkjxNwtS3JDRPVKZAXGHZy2wCA8bdv2iJiyeePn0xkmK+TCCqZFT0X7+2+FLjngA=="], + "typedoc": ["typedoc@0.28.19", "", { "dependencies": { "@gerrit0/mini-shiki": "^3.23.0", "lunr": "^2.3.9", "markdown-it": "^14.1.1", "minimatch": "^10.2.5", "yaml": "^2.8.3" }, "peerDependencies": { "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x" }, "bin": { "typedoc": "bin/typedoc" } }, "sha512-wKh+lhdmMFivMlc6vRRcMGXeGEHGU2g8a2CkPTJjJlwRf1iXbimWIPcFolCqe4E0d/FRtGszpIrsp3WLpDB8Pw=="], - "typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="], + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], "uc.micro": ["uc.micro@2.1.0", "", {}, "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="], @@ -1286,7 +1286,7 @@ "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], - "unrun": ["unrun@0.2.34", "", { "dependencies": { "rolldown": "1.0.0-rc.12" }, "peerDependencies": { "synckit": "^0.11.11" }, "optionalPeers": ["synckit"], "bin": { "unrun": "dist/cli.mjs" } }, "sha512-LyaghRBR++r7svhDK6tnDz2XaYHWdneBOA0jbS8wnRsHerI9MFljX4fIiTgbbNbEVzZ0C9P1OjWLLe1OqoaaEw=="], + "unrun": ["unrun@0.2.37", "", { "dependencies": { "rolldown": "1.0.0-rc.17" }, "peerDependencies": { "synckit": "^0.11.11" }, "optionalPeers": ["synckit"], "bin": { "unrun": "dist/cli.mjs" } }, "sha512-AA7vDuYsgeSYVzJMm16UKA+aXFKhy7nFqW9z5l7q44K4ppFWZAMqYS58ePRZbugMLPH0fwwMzD5A8nP0avxwZQ=="], "uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="], @@ -1296,11 +1296,11 @@ "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - "vite": ["vite@8.0.8", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.15", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw=="], + "vite": ["vite@8.0.10", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.10", "rolldown": "1.0.0-rc.17", "tinyglobby": "^0.2.16" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw=="], "vitepress": ["vitepress@2.0.0-alpha.17", "", { "dependencies": { "@docsearch/css": "^4.5.3", "@docsearch/js": "^4.5.3", "@docsearch/sidepanel-js": "^4.5.3", "@iconify-json/simple-icons": "^1.2.69", "@shikijs/core": "^3.22.0", "@shikijs/transformers": "^3.22.0", "@shikijs/types": "^3.22.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^6.0.4", "@vue/devtools-api": "^8.0.5", "@vue/shared": "^3.5.27", "@vueuse/core": "^14.2.0", "@vueuse/integrations": "^14.2.0", "focus-trap": "^8.0.0", "mark.js": "8.11.1", "minisearch": "^7.2.0", "shiki": "^3.22.0", "vite": "^7.3.1", "vue": "^3.5.27" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "oxc-minify": "*", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3", "oxc-minify", "postcss"], "bin": { "vitepress": "bin/vitepress.js" } }, "sha512-Z3VPUpwk/bHYqt1uMVOOK1/4xFiWQov1GNc2FvMdz6kvje4JRXEOngVI9C+bi5jeedMSHiA4dwKkff1NCvbZ9Q=="], - "vitest": ["vitest@4.1.4", "", { "dependencies": { "@vitest/expect": "4.1.4", "@vitest/mocker": "4.1.4", "@vitest/pretty-format": "4.1.4", "@vitest/runner": "4.1.4", "@vitest/snapshot": "4.1.4", "@vitest/spy": "4.1.4", "@vitest/utils": "4.1.4", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.4", "@vitest/browser-preview": "4.1.4", "@vitest/browser-webdriverio": "4.1.4", "@vitest/coverage-istanbul": "4.1.4", "@vitest/coverage-v8": "4.1.4", "@vitest/ui": "4.1.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/coverage-istanbul", "@vitest/coverage-v8", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg=="], + "vitest": ["vitest@4.1.5", "", { "dependencies": { "@vitest/expect": "4.1.5", "@vitest/mocker": "4.1.5", "@vitest/pretty-format": "4.1.5", "@vitest/runner": "4.1.5", "@vitest/snapshot": "4.1.5", "@vitest/spy": "4.1.5", "@vitest/utils": "4.1.5", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.5", "@vitest/browser-preview": "4.1.5", "@vitest/browser-webdriverio": "4.1.5", "@vitest/coverage-istanbul": "4.1.5", "@vitest/coverage-v8": "4.1.5", "@vitest/ui": "4.1.5", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/coverage-istanbul", "@vitest/coverage-v8", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg=="], "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], @@ -1314,7 +1314,7 @@ "vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="], - "vue": ["vue@3.5.32", "", { "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/compiler-sfc": "3.5.32", "@vue/runtime-dom": "3.5.32", "@vue/server-renderer": "3.5.32", "@vue/shared": "3.5.32" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw=="], + "vue": ["vue@3.5.33", "", { "dependencies": { "@vue/compiler-dom": "3.5.33", "@vue/compiler-sfc": "3.5.33", "@vue/runtime-dom": "3.5.33", "@vue/server-renderer": "3.5.33", "@vue/shared": "3.5.33" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-1AgChhx5w3ALgT4oK3acm2Es/7jyZhWSVUfs3rOBlGQC0rjEDkS7G4lWlJJGGNQD+BV3reCwbQrOe1mPNwKHBQ=="], "vue-resize": ["vue-resize@2.0.0-alpha.1", "", { "peerDependencies": { "vue": "^3.0.0" } }, "sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg=="], @@ -1322,9 +1322,9 @@ "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], - "workerd": ["workerd@1.20260426.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260426.1", "@cloudflare/workerd-darwin-arm64": "1.20260426.1", "@cloudflare/workerd-linux-64": "1.20260426.1", "@cloudflare/workerd-linux-arm64": "1.20260426.1", "@cloudflare/workerd-windows-64": "1.20260426.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-ELvGgN8c9oo+E6EPyecxk1TEf6/eAK4TxxQTW5mQ87C7jbjCzhMbg0P2ije49UBHV0dkBYPJcJvcklUltipl2A=="], + "workerd": ["workerd@1.20260430.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260430.1", "@cloudflare/workerd-darwin-arm64": "1.20260430.1", "@cloudflare/workerd-linux-64": "1.20260430.1", "@cloudflare/workerd-linux-arm64": "1.20260430.1", "@cloudflare/workerd-windows-64": "1.20260430.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-KEgIWyiw3Jmn+DCd/L3ePo5fmiiYb/UcwKvDWPf/nLLOiwShDFzDSsegU5NY/JcwgvO/QsLHVi2FYrbkcXNY5Q=="], - "wrangler": ["wrangler@4.86.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.16.1", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260426.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260426.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260426.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-9aa/gbF/HiUeeUEwyQpW5LDPBEzyt7iaE6xHwm0vk2Ly8A6J+jh03pzchqVnCCWR832mNyA28MD8oAYt0Kfvlw=="], + "wrangler": ["wrangler@4.87.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.5.0", "@cloudflare/unenv-preset": "2.16.1", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260430.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260430.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260430.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-lfhfKwLfQlowwgV0xhlYgE9fU3n0I30d4ccGY/rTCEm/n42Mjvlr0Ng3ZPNqlsrsKBcDR531V7dsPkgELvrk/Q=="], "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], @@ -1356,24 +1356,44 @@ "@gerrit0/mini-shiki/@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], + "@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], + "@oxc-resolver/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], - "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], + "@shikijs/vitepress-twoslash/vue": ["vue@3.5.32", "", { "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/compiler-sfc": "3.5.32", "@vue/runtime-dom": "3.5.32", "@vue/server-renderer": "3.5.32", "@vue/shared": "3.5.32" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw=="], "@vitejs/plugin-vue/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.2", "", {}, "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw=="], + "@vue/compiler-core/@vue/shared": ["@vue/shared@3.5.33", "", {}, "sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ=="], + "@vue/compiler-core/entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], "@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + "@vue/compiler-dom/@vue/shared": ["@vue/shared@3.5.33", "", {}, "sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ=="], + + "@vue/compiler-sfc/@vue/shared": ["@vue/shared@3.5.33", "", {}, "sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ=="], + "@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + "@vue/compiler-ssr/@vue/shared": ["@vue/shared@3.5.33", "", {}, "sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ=="], + "@vue/devtools-kit/birpc": ["birpc@2.9.0", "", {}, "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw=="], "@vue/devtools-kit/hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="], + "@vue/language-core/@vue/compiler-dom": ["@vue/compiler-dom@3.5.32", "", { "dependencies": { "@vue/compiler-core": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q=="], + + "@vue/reactivity/@vue/shared": ["@vue/shared@3.5.33", "", {}, "sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ=="], + + "@vue/runtime-core/@vue/shared": ["@vue/shared@3.5.33", "", {}, "sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ=="], + + "@vue/runtime-dom/@vue/shared": ["@vue/shared@3.5.33", "", {}, "sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ=="], + + "@vue/server-renderer/@vue/shared": ["@vue/shared@3.5.33", "", {}, "sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ=="], + "ast-kit/@babel/parser": ["@babel/parser@8.0.0-rc.3", "", { "dependencies": { "@babel/types": "^8.0.0-rc.3" }, "bin": "./bin/babel-parser.js" }, "sha512-B20dvP3MfNc/XS5KKCHy/oyWl5IA6Cn9YjXRdDlCjNmUFrjvLXMNUfQq/QUy9fnG2gYkKKcrto2YaF9B32ToOQ=="], "cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="], @@ -1386,7 +1406,7 @@ "pwsh-demo/@kjanat/dreamcli": ["dreamcli-monorepo@link:@kjanat/dreamcli", {}], - "rolldown/@oxc-project/types": ["@oxc-project/types@0.122.0", "", {}, "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA=="], + "rolldown/@oxc-project/types": ["@oxc-project/types@0.127.0", "", {}, "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ=="], "rolldown-plugin-dts/@babel/parser": ["@babel/parser@8.0.0-rc.3", "", { "dependencies": { "@babel/types": "^8.0.0-rc.3" }, "bin": "./bin/babel-parser.js" }, "sha512-B20dvP3MfNc/XS5KKCHy/oyWl5IA6Cn9YjXRdDlCjNmUFrjvLXMNUfQq/QUy9fnG2gYkKKcrto2YaF9B32ToOQ=="], @@ -1396,7 +1416,9 @@ "tsx/get-tsconfig": ["get-tsconfig@4.13.7", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q=="], - "vite/rolldown": ["rolldown@1.0.0-rc.15", "", { "dependencies": { "@oxc-project/types": "=0.124.0", "@rolldown/pluginutils": "1.0.0-rc.15" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-x64": "1.0.0-rc.15", "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g=="], + "twoslash/typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="], + + "twoslash-vue/typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="], "vitepress/@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], @@ -1408,8 +1430,22 @@ "vitepress/vite": ["vite@7.3.2", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg=="], + "vitepress/vue": ["vue@3.5.32", "", { "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/compiler-sfc": "3.5.32", "@vue/runtime-dom": "3.5.32", "@vue/server-renderer": "3.5.32", "@vue/shared": "3.5.32" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw=="], + + "vue/@vue/shared": ["@vue/shared@3.5.33", "", {}, "sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ=="], + "@babel/generator/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.3", "", {}, "sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA=="], + "@shikijs/vitepress-twoslash/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.32", "", { "dependencies": { "@vue/compiler-core": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q=="], + + "@shikijs/vitepress-twoslash/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/compiler-core": "3.5.32", "@vue/compiler-dom": "3.5.32", "@vue/compiler-ssr": "3.5.32", "@vue/shared": "3.5.32", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.8", "source-map-js": "^1.2.1" } }, "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg=="], + + "@shikijs/vitepress-twoslash/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.32", "", { "dependencies": { "@vue/reactivity": "3.5.32", "@vue/runtime-core": "3.5.32", "@vue/shared": "3.5.32", "csstype": "^3.2.3" } }, "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ=="], + + "@shikijs/vitepress-twoslash/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.32", "", { "dependencies": { "@vue/compiler-ssr": "3.5.32", "@vue/shared": "3.5.32" }, "peerDependencies": { "vue": "3.5.32" } }, "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ=="], + + "@vue/language-core/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/shared": "3.5.32", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ=="], + "ast-kit/@babel/parser/@babel/types": ["@babel/types@8.0.0-rc.3", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0-rc.3", "@babel/helper-validator-identifier": "^8.0.0-rc.3" } }, "sha512-mOm5ZrYmphGfqVWoH5YYMTITb3cDXsFgmvFlvkvWDMsR9X8RFnt7a0Wb6yNIdoFsiMO9WjYLq+U/FMtqIYAF8Q=="], "cytoscape-fcose/cose-base/layout-base": ["layout-base@2.0.1", "", {}, "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="], @@ -1420,50 +1456,72 @@ "rolldown-plugin-dts/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.3", "", {}, "sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA=="], - "vite/rolldown/@oxc-project/types": ["@oxc-project/types@0.124.0", "", {}, "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg=="], + "vitepress/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA=="], - "vite/rolldown/@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.15", "", { "os": "android", "cpu": "arm64" }, "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA=="], + "vitepress/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="], - "vite/rolldown/@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.15", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg=="], + "vitepress/shiki/@shikijs/langs": ["@shikijs/langs@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg=="], - "vite/rolldown/@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.15", "", { "os": "darwin", "cpu": "x64" }, "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw=="], + "vitepress/shiki/@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="], - "vite/rolldown/@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.15", "", { "os": "freebsd", "cpu": "x64" }, "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw=="], + "vitepress/vite/postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], - "vite/rolldown/@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm" }, "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA=="], + "vitepress/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.32", "", { "dependencies": { "@vue/compiler-core": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q=="], - "vite/rolldown/@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w=="], + "vitepress/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/compiler-core": "3.5.32", "@vue/compiler-dom": "3.5.32", "@vue/compiler-ssr": "3.5.32", "@vue/shared": "3.5.32", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.8", "source-map-js": "^1.2.1" } }, "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg=="], - "vite/rolldown/@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ=="], + "vitepress/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.32", "", { "dependencies": { "@vue/reactivity": "3.5.32", "@vue/runtime-core": "3.5.32", "@vue/shared": "3.5.32", "csstype": "^3.2.3" } }, "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ=="], - "vite/rolldown/@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "ppc64" }, "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ=="], + "vitepress/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.32", "", { "dependencies": { "@vue/compiler-ssr": "3.5.32", "@vue/shared": "3.5.32" }, "peerDependencies": { "vue": "3.5.32" } }, "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ=="], - "vite/rolldown/@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "s390x" }, "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ=="], + "@shikijs/vitepress-twoslash/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/shared": "3.5.32", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ=="], - "vite/rolldown/@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "x64" }, "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA=="], + "@shikijs/vitepress-twoslash/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/shared": "3.5.32", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ=="], - "vite/rolldown/@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.15", "", { "os": "linux", "cpu": "x64" }, "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw=="], + "@shikijs/vitepress-twoslash/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.32", "", { "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw=="], - "vite/rolldown/@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.15", "", { "os": "none", "cpu": "arm64" }, "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg=="], + "@shikijs/vitepress-twoslash/vue/@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], - "vite/rolldown/@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.15", "", { "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.3" }, "cpu": "none" }, "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q=="], + "@shikijs/vitepress-twoslash/vue/@vue/compiler-sfc/postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], - "vite/rolldown/@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15", "", { "os": "win32", "cpu": "arm64" }, "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA=="], + "@shikijs/vitepress-twoslash/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.32", "", { "dependencies": { "@vue/shared": "3.5.32" } }, "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ=="], - "vite/rolldown/@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.15", "", { "os": "win32", "cpu": "x64" }, "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g=="], + "@shikijs/vitepress-twoslash/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.32", "", { "dependencies": { "@vue/reactivity": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ=="], - "vite/rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.15", "", {}, "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g=="], + "@shikijs/vitepress-twoslash/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.32", "", { "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw=="], - "vitepress/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA=="], + "@vue/language-core/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], - "vitepress/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="], + "@vue/language-core/@vue/compiler-dom/@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], - "vitepress/shiki/@shikijs/langs": ["@shikijs/langs@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg=="], + "ast-kit/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.3", "", {}, "sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA=="], - "vitepress/shiki/@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="], + "vitepress/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/shared": "3.5.32", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ=="], - "ast-kit/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.3", "", {}, "sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA=="], + "vitepress/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/shared": "3.5.32", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ=="], + + "vitepress/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.32", "", { "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw=="], + + "vitepress/vue/@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "vitepress/vue/@vue/compiler-sfc/postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], + + "vitepress/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.32", "", { "dependencies": { "@vue/shared": "3.5.32" } }, "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ=="], + + "vitepress/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.32", "", { "dependencies": { "@vue/reactivity": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ=="], + + "vitepress/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.32", "", { "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw=="], + + "@shikijs/vitepress-twoslash/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + + "@shikijs/vitepress-twoslash/vue/@vue/compiler-dom/@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "@shikijs/vitepress-twoslash/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + + "vitepress/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + + "vitepress/vue/@vue/compiler-dom/@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], - "vite/rolldown/@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], + "vitepress/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], } } diff --git a/examples/standalone/basic.ts b/examples/standalone/basic.ts index 851b3e39..c2a9513b 100755 --- a/examples/standalone/basic.ts +++ b/examples/standalone/basic.ts @@ -5,10 +5,10 @@ * Demonstrates: typed positional args, typed flags, aliases, and default values. * * Usage: - * npx tsx examples/basic.ts Alice - * npx tsx examples/basic.ts Alice --loud --times 3 - * npx tsx examples/basic.ts Alice -l -t 3 - * npx tsx examples/basic.ts --help + * npx tsx examples/standalone/basic.ts Alice + * npx tsx examples/standalone/basic.ts Alice --loud --times 3 + * npx tsx examples/standalone/basic.ts Alice -l -t 3 + * npx tsx examples/standalone/basic.ts --help */ import { arg, cli, command, flag } from '@kjanat/dreamcli'; diff --git a/examples/standalone/interactive.ts b/examples/standalone/interactive.ts index 490a3858..508941ef 100755 --- a/examples/standalone/interactive.ts +++ b/examples/standalone/interactive.ts @@ -13,10 +13,10 @@ * 5. Then default value: "us" * * Usage: - * npx tsx examples/interactive.ts # prompts for everything - * npx tsx examples/interactive.ts --region eu # skips region prompt - * DEPLOY_REGION=ap npx tsx examples/interactive.ts # env resolves region - * echo '{}' | npx tsx examples/interactive.ts # non-interactive: uses defaults / errors + * npx tsx examples/standalone/interactive.ts # prompts for everything + * npx tsx examples/standalone/interactive.ts --region eu # skips region prompt + * DEPLOY_REGION=ap npx tsx examples/standalone/interactive.ts # env resolves region + * echo '{}' | npx tsx examples/standalone/interactive.ts # non-interactive: uses defaults / errors */ import { arg, cli, command, flag } from '@kjanat/dreamcli'; diff --git a/examples/standalone/json-mode.ts b/examples/standalone/json-mode.ts index 16935861..60729f9b 100755 --- a/examples/standalone/json-mode.ts +++ b/examples/standalone/json-mode.ts @@ -6,12 +6,12 @@ * side channels, and `--json` for CLI-managed structured errors. * * Usage: - * npx tsx examples/json-mode.ts list # JSON stdout + plain stderr side channel - * npx tsx examples/json-mode.ts list --format table # JSON stdout + table stderr side channel - * npx tsx examples/json-mode.ts list --json # same success output; CLI-managed errors stay JSON-safe - * npx tsx examples/json-mode.ts show web-api - * npx tsx examples/json-mode.ts show nonexistent # structured error - * npx tsx examples/json-mode.ts show nonexistent --json # JSON error + * npx tsx examples/standalone/json-mode.ts list # JSON stdout + plain stderr side channel + * npx tsx examples/standalone/json-mode.ts list --format table # JSON stdout + table stderr side channel + * npx tsx examples/standalone/json-mode.ts list --json # same success output; CLI-managed errors stay JSON-safe + * npx tsx examples/standalone/json-mode.ts show web-api + * npx tsx examples/standalone/json-mode.ts show nonexistent # structured error + * npx tsx examples/standalone/json-mode.ts show nonexistent --json # JSON error */ import { arg, CLIError, cli, command, flag } from '@kjanat/dreamcli'; diff --git a/examples/standalone/middleware.ts b/examples/standalone/middleware.ts index fd981c92..010d4c7a 100755 --- a/examples/standalone/middleware.ts +++ b/examples/standalone/middleware.ts @@ -6,8 +6,8 @@ * wrap-around timing. * * Usage: - * npx tsx examples/middleware.ts deploy production - * npx tsx examples/middleware.ts deploy production --verbose + * npx tsx examples/standalone/middleware.ts deploy production + * npx tsx examples/standalone/middleware.ts deploy production --verbose */ import { arg, CLIError, cli, command, flag, middleware } from '@kjanat/dreamcli'; diff --git a/examples/standalone/multi-command.ts b/examples/standalone/multi-command.ts index 031e232c..481f1049 100755 --- a/examples/standalone/multi-command.ts +++ b/examples/standalone/multi-command.ts @@ -6,14 +6,14 @@ * env-backed flags. * * Usage: - * npx tsx examples/multi-command.ts deploy production --force - * npx tsx examples/multi-command.ts deploy production --region eu - * DEPLOY_REGION=ap npx tsx examples/multi-command.ts deploy production - * npx tsx examples/multi-command.ts db migrate --steps 3 - * npx tsx examples/multi-command.ts db seed - * npx tsx examples/multi-command.ts login --token abc123 - * npx tsx examples/multi-command.ts --help - * npx tsx examples/multi-command.ts --version + * npx tsx examples/standalone/multi-command.ts deploy production --force + * npx tsx examples/standalone/multi-command.ts deploy production --region eu + * DEPLOY_REGION=ap npx tsx examples/standalone/multi-command.ts deploy production + * npx tsx examples/standalone/multi-command.ts db migrate --steps 3 + * npx tsx examples/standalone/multi-command.ts db seed + * npx tsx examples/standalone/multi-command.ts login --token abc123 + * npx tsx examples/standalone/multi-command.ts --help + * npx tsx examples/standalone/multi-command.ts --version */ import { arg, cli, command, flag, group } from '@kjanat/dreamcli'; diff --git a/examples/standalone/spinner-progress.ts b/examples/standalone/spinner-progress.ts index c9eafc2e..cf5fd4eb 100755 --- a/examples/standalone/spinner-progress.ts +++ b/examples/standalone/spinner-progress.ts @@ -6,9 +6,9 @@ * automatic suppression in non-TTY or `--json` mode. * * Usage: - * npx tsx examples/spinner-progress.ts - * npx tsx examples/spinner-progress.ts --json # spinners suppressed, JSON output - * echo | npx tsx examples/spinner-progress.ts # non-TTY: spinners silent + * npx tsx examples/standalone/spinner-progress.ts + * npx tsx examples/standalone/spinner-progress.ts --json # spinners suppressed, JSON output + * echo | npx tsx examples/standalone/spinner-progress.ts # non-TTY: spinners silent */ import { cli, command, flag } from '@kjanat/dreamcli'; diff --git a/examples/standalone/testing.ts b/examples/standalone/testing.ts index f5eebfb3..d1ff621e 100755 --- a/examples/standalone/testing.ts +++ b/examples/standalone/testing.ts @@ -6,10 +6,10 @@ * assertions, middleware context, and activity assertions. * * This file is structured as a Vitest test suite — run with - * `bun test examples/testing.ts`. + * `bun test examples/standalone/testing.ts`. * * Usage: - * bun test examples/testing.ts + * bun test examples/standalone/testing.ts */ import { arg, command, flag, middleware } from '@kjanat/dreamcli'; diff --git a/package.json b/package.json index e88d4bf8..90f468e2 100644 --- a/package.json +++ b/package.json @@ -79,22 +79,22 @@ "@types/bun": "^1.3.12", "@types/deno": "^2.5.0", "@types/node": ">=22.0.0, <23.0.0", - "@typescript/native-preview": "^7.0.0-dev.20260428.1", - "@vitest/coverage-v8": "^4.1.2", + "@typescript/native-preview": "^7.0.0-dev.20260501.1", + "@vitest/coverage-v8": "^4.1.5", "floating-vue": "^5.2.2", "mermaid": "^11.14.0", "publint": "^0.3.18", - "tsdown": "^0.21.7", - "typedoc": "^0.28.18", - "typescript": "^6.0.2", - "vite": "^8.0.7", + "tsdown": "^0.21.10", + "typedoc": "^0.28.19", + "typescript": "^6.0.3", + "vite": "^8.0.10", "tsx": "^4.21.0", - "vue": "^3.5.32", + "vue": "^3.5.33", "vitepress": "^2.0.0-alpha.17", - "vitest": "^4.1.2", + "vitest": "^4.1.5", "yaml": "^2.8.3", "dprint": "^0.54.0", - "knip": "^6.7.0", - "wrangler": "^4.86.0" + "knip": "^6.9.0", + "wrangler": "^4.87.0" } } diff --git a/packages/dreamcli/README.md b/packages/dreamcli/README.md index 90c73932..03d4ea95 100644 --- a/packages/dreamcli/README.md +++ b/packages/dreamcli/README.md @@ -499,7 +499,7 @@ ESM-only. Source included in package (`src/`). | Runtime | Status | | ------------------ | ----------------------------------- | | Node.js >= 22.22.2 | Supported | -| Bun >= 1.3.11 | Supported | +| Bun >= 1.3 | Supported | | Deno >= 2.6.0 | Supported (JSR: `@kjanat/dreamcli`) | Runtime detection is automatic. diff --git a/packages/dreamcli/package.json b/packages/dreamcli/package.json index 4348ddcf..b401a054 100644 --- a/packages/dreamcli/package.json +++ b/packages/dreamcli/package.json @@ -1,6 +1,6 @@ { "name": "@kjanat/dreamcli", - "version": "2.0.1", + "version": "2.1.0", "description": "Schema-first, fully typed TypeScript CLI framework", "keywords": [ "cli", @@ -96,7 +96,7 @@ "vite": "catalog:" }, "engines": { - "bun": ">=1.3.11", + "bun": ">=1.3", "deno": ">=2.6.0", "node": ">=22.22.2" }, diff --git a/packages/dreamcli/src/core/resolve/resolve-prompt.test.ts b/packages/dreamcli/src/core/resolve/resolve-prompt.test.ts index b8562ea1..8b91a8c4 100644 --- a/packages/dreamcli/src/core/resolve/resolve-prompt.test.ts +++ b/packages/dreamcli/src/core/resolve/resolve-prompt.test.ts @@ -13,8 +13,8 @@ import { createTestPrompter, PROMPT_CANCEL } from '#internals/core/prompt/index. import { FLAG_KINDS } from '#internals/core/schema/flag.ts'; import type { CommandSchema } from '#internals/core/schema/index.ts'; import { createSchema } from '#internals/core/schema/index.ts'; -import type { ResolveOptions } from './index.ts'; import { COMPATIBLE_PROMPT_KINDS } from './flags.ts'; +import type { ResolveOptions } from './index.ts'; import { resolve } from './index.ts'; // --- Helpers diff --git a/packages/dreamcli/src/runtime/support.test.ts b/packages/dreamcli/src/runtime/support.test.ts index bd8fb9f0..9954d81e 100644 --- a/packages/dreamcli/src/runtime/support.test.ts +++ b/packages/dreamcli/src/runtime/support.test.ts @@ -5,12 +5,28 @@ import { readFile } from 'node:fs/promises'; import { describe, expect, it } from 'vitest'; -import { formatRuntimeRequirement, getRuntimeSupport, SUPPORTED_RUNTIMES } from './support.ts'; +import { getRuntimeSupport, SUPPORTED_RUNTIMES } from './support.ts'; function readUtf8(path: URL): Promise { return readFile(path, 'utf8'); } +function escapeRegExp(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +function expectContainsRuntimeRequirement( + contents: string, + displayName: string, + minimum: string, +): void { + expect(contents).toMatch( + new RegExp( + `${escapeRegExp(displayName)}[\\s\\S]*?>=(?:\\\\u00a0|\\s)*${escapeRegExp(minimum)}`, + ), + ); +} + function parsePackageEngines(contents: string): Readonly> { const parsed = JSON.parse(contents); if (typeof parsed !== 'object' || parsed === null || !('engines' in parsed)) { @@ -44,7 +60,7 @@ describe('runtime — compatibility matrix stays aligned', () => { const docs = await readUtf8(new URL('../../../../apps/docs/guide/runtime.md', import.meta.url)); for (const runtime of SUPPORTED_RUNTIMES) { - expect(docs).toContain(formatRuntimeRequirement(runtime.runtime)); + expectContainsRuntimeRequirement(docs, runtime.displayName, runtime.minimum); expect(docs).toContain(runtime.packageName); } expect(docs).toContain('Adapters validate these minimum versions during creation.'); @@ -56,7 +72,7 @@ describe('runtime — compatibility matrix stays aligned', () => { ); for (const runtime of SUPPORTED_RUNTIMES) { - expect(docs).toContain(formatRuntimeRequirement(runtime.runtime)); + expectContainsRuntimeRequirement(docs, runtime.displayName, runtime.minimum); expect(docs).toContain(runtime.adapterName); } }); @@ -68,8 +84,7 @@ describe('runtime — compatibility matrix stays aligned', () => { for (const runtime of SUPPORTED_RUNTIMES) { const { displayName, minimum } = getRuntimeSupport(runtime.runtime); - expect(docs).toContain(displayName); - expect(docs).toContain(`>= ${minimum}`); + expectContainsRuntimeRequirement(docs, displayName, minimum); } }); }); diff --git a/tsconfig.json b/tsconfig.json index 8689268a..839be9f4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -46,6 +46,10 @@ "@kjanat/dreamcli-docs": [ "./apps/docs/src/index.ts", "../../apps/docs/src/index.ts" + ], + "@kjanat/dreamcli-docs/vitepress/*": [ + "./apps/docs/.vitepress/*", + "../../apps/docs/.vitepress/*" ] } },