From 68d93f1eba2dcaaa648241607adb3083ade02c4c Mon Sep 17 00:00:00 2001 From: dal Date: Mon, 4 Aug 2025 16:16:00 -0600 Subject: [PATCH] migrate cli over to ts --- .claude/tasks/cli-migration-to-typescript.md | 1346 +++++++++++++++++ .gitignore | 1 - .../.cursor/rules/global.mdc | 0 apps/{cli => cli-deprecated}/.gitignore | 0 apps/cli-deprecated/CLAUDE.md | 34 + apps/{cli => cli-deprecated}/Cargo.toml | 0 apps/{cli => cli-deprecated}/Makefile | 0 apps/cli-deprecated/README.md | 370 +++++ apps/{cli => cli-deprecated}/VERSIONING.md | 0 apps/{cli => cli-deprecated}/cli/Cargo.toml | 0 apps/{cli => cli-deprecated}/cli/build.rs | 0 .../cli/docker-compose.yml | 0 .../cli/src/assets/mod.rs | 0 .../cli/src/commands/auth.rs | 0 .../cli/src/commands/chat/args.rs | 0 .../cli/src/commands/chat/completion.rs | 0 .../cli/src/commands/chat/config.rs | 0 .../cli/src/commands/chat/logic.rs | 0 .../cli/src/commands/chat/mod.rs | 0 .../cli/src/commands/chat/state.rs | 0 .../cli/src/commands/chat/ui.rs | 0 .../cli/src/commands/config.rs | 0 .../cli/src/commands/config_utils.rs | 0 .../cli/src/commands/deploy/deploy.rs | 0 .../src/commands/deploy/integration_tests.rs | 0 .../cli/src/commands/deploy/mod.rs | 0 .../cli/src/commands/generate.rs | 0 .../cli/src/commands/init.rs | 0 .../cli/src/commands/mod.rs | 0 .../cli/src/commands/parse.rs | 0 .../cli/src/commands/run.rs | 0 .../cli/src/commands/update.rs | 0 apps/{cli => cli-deprecated}/cli/src/error.rs | 0 apps/{cli => cli-deprecated}/cli/src/lib.rs | 0 apps/{cli => cli-deprecated}/cli/src/main.rs | 0 .../cli/src/types/mod.rs | 0 .../cli/src/utils/buster/api.rs | 0 .../cli/src/utils/buster/mod.rs | 0 .../cli/src/utils/buster/types.rs | 0 .../cli/src/utils/config.rs | 0 .../cli/src/utils/dbt/command.rs | 0 .../cli/src/utils/dbt/mod.rs | 0 .../cli/src/utils/exclusion.rs | 0 .../cli/src/utils/file/buster_credentials.rs | 0 .../cli/src/utils/file/mod.rs | 0 .../cli/src/utils/file/model_files.rs | 0 .../cli/src/utils/file/profiles.rs | 0 .../cli/src/utils/file/project_files.rs | 0 .../cli/src/utils/formatting/mod.rs | 0 .../cli/src/utils/formatting/text.rs | 0 .../cli/src/utils/fs_utils.rs | 0 .../cli/src/utils/mod.rs | 0 .../cli/src/utils/progress.rs | 0 .../cli/src/utils/updater.rs | 0 .../cli/src/utils/version.rs | 0 .../cli/src/utils/yaml_diff_merger.rs | 0 .../libs/dbt_utils/Cargo.toml | 0 .../libs/dbt_utils/src/lib.rs | 0 .../libs/dbt_utils/src/models.rs | 0 .../src/commands/chat/CLAUDE.md | 0 .../tests/command_tests.rs | 0 .../tests/env_vars_test.rs | 0 .../tests/exclusion_test.rs | 0 .../tests/project_config_test.rs | 0 .../tests/test_excluded_tags.sql | 0 apps/cli/CLAUDE.md | 511 ++++++- apps/cli/README.md | 395 +---- apps/cli/biome.json | 3 + apps/cli/env.d.ts | 18 + apps/cli/package.json | 51 + apps/cli/scripts/validate-env.ts | 27 + apps/cli/src/commands/auth/components.tsx | 88 ++ apps/cli/src/commands/auth/helpers.ts | 20 + apps/cli/src/commands/auth/index.ts | 20 + apps/cli/src/commands/auth/types.ts | 19 + apps/cli/src/commands/config/index.ts | 21 + apps/cli/src/commands/deploy/components.tsx | 42 + apps/cli/src/commands/deploy/index.ts | 19 + apps/cli/src/commands/deploy/types.ts | 17 + apps/cli/src/commands/init/components.tsx | 103 ++ apps/cli/src/commands/init/helpers.ts | 49 + apps/cli/src/commands/init/index.ts | 20 + apps/cli/src/commands/init/types.ts | 20 + apps/cli/src/commands/parse/components.tsx | 22 + apps/cli/src/commands/parse/index.ts | 19 + apps/cli/src/commands/parse/types.ts | 8 + apps/cli/src/commands/reset/index.ts | 19 + apps/cli/src/commands/start/index.ts | 19 + apps/cli/src/commands/stop/index.ts | 13 + apps/cli/src/commands/update/index.ts | 19 + apps/cli/src/main.ts | 45 + apps/cli/src/utils/api-client.ts | 78 + apps/cli/src/utils/config.ts | 99 ++ apps/cli/src/utils/errors.ts | 34 + apps/cli/tsconfig.json | 10 + apps/cli/tsup.config.ts | 23 + apps/cli/turbo.json | 15 + apps/cli/vitest.config.ts | 12 + pnpm-lock.yaml | 1244 ++++++++++++--- pnpm-workspace.yaml | 3 +- 100 files changed, 4304 insertions(+), 572 deletions(-) create mode 100644 .claude/tasks/cli-migration-to-typescript.md rename apps/{cli => cli-deprecated}/.cursor/rules/global.mdc (100%) rename apps/{cli => cli-deprecated}/.gitignore (100%) create mode 100644 apps/cli-deprecated/CLAUDE.md rename apps/{cli => cli-deprecated}/Cargo.toml (100%) rename apps/{cli => cli-deprecated}/Makefile (100%) create mode 100644 apps/cli-deprecated/README.md rename apps/{cli => cli-deprecated}/VERSIONING.md (100%) rename apps/{cli => cli-deprecated}/cli/Cargo.toml (100%) rename apps/{cli => cli-deprecated}/cli/build.rs (100%) rename apps/{cli => cli-deprecated}/cli/docker-compose.yml (100%) rename apps/{cli => cli-deprecated}/cli/src/assets/mod.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/auth.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/chat/args.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/chat/completion.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/chat/config.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/chat/logic.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/chat/mod.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/chat/state.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/chat/ui.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/config.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/config_utils.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/deploy/deploy.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/deploy/integration_tests.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/deploy/mod.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/generate.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/init.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/mod.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/parse.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/run.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/commands/update.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/error.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/lib.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/main.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/types/mod.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/buster/api.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/buster/mod.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/buster/types.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/config.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/dbt/command.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/dbt/mod.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/exclusion.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/file/buster_credentials.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/file/mod.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/file/model_files.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/file/profiles.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/file/project_files.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/formatting/mod.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/formatting/text.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/fs_utils.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/mod.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/progress.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/updater.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/version.rs (100%) rename apps/{cli => cli-deprecated}/cli/src/utils/yaml_diff_merger.rs (100%) rename apps/{cli => cli-deprecated}/libs/dbt_utils/Cargo.toml (100%) rename apps/{cli => cli-deprecated}/libs/dbt_utils/src/lib.rs (100%) rename apps/{cli => cli-deprecated}/libs/dbt_utils/src/models.rs (100%) rename apps/{cli => cli-deprecated}/src/commands/chat/CLAUDE.md (100%) rename apps/{cli => cli-deprecated}/tests/command_tests.rs (100%) rename apps/{cli => cli-deprecated}/tests/env_vars_test.rs (100%) rename apps/{cli => cli-deprecated}/tests/exclusion_test.rs (100%) rename apps/{cli => cli-deprecated}/tests/project_config_test.rs (100%) rename apps/{cli => cli-deprecated}/tests/test_excluded_tags.sql (100%) create mode 100644 apps/cli/biome.json create mode 100644 apps/cli/env.d.ts create mode 100644 apps/cli/package.json create mode 100644 apps/cli/scripts/validate-env.ts create mode 100644 apps/cli/src/commands/auth/components.tsx create mode 100644 apps/cli/src/commands/auth/helpers.ts create mode 100644 apps/cli/src/commands/auth/index.ts create mode 100644 apps/cli/src/commands/auth/types.ts create mode 100644 apps/cli/src/commands/config/index.ts create mode 100644 apps/cli/src/commands/deploy/components.tsx create mode 100644 apps/cli/src/commands/deploy/index.ts create mode 100644 apps/cli/src/commands/deploy/types.ts create mode 100644 apps/cli/src/commands/init/components.tsx create mode 100644 apps/cli/src/commands/init/helpers.ts create mode 100644 apps/cli/src/commands/init/index.ts create mode 100644 apps/cli/src/commands/init/types.ts create mode 100644 apps/cli/src/commands/parse/components.tsx create mode 100644 apps/cli/src/commands/parse/index.ts create mode 100644 apps/cli/src/commands/parse/types.ts create mode 100644 apps/cli/src/commands/reset/index.ts create mode 100644 apps/cli/src/commands/start/index.ts create mode 100644 apps/cli/src/commands/stop/index.ts create mode 100644 apps/cli/src/commands/update/index.ts create mode 100644 apps/cli/src/main.ts create mode 100644 apps/cli/src/utils/api-client.ts create mode 100644 apps/cli/src/utils/config.ts create mode 100644 apps/cli/src/utils/errors.ts create mode 100644 apps/cli/tsconfig.json create mode 100644 apps/cli/tsup.config.ts create mode 100644 apps/cli/turbo.json create mode 100644 apps/cli/vitest.config.ts diff --git a/.claude/tasks/cli-migration-to-typescript.md b/.claude/tasks/cli-migration-to-typescript.md new file mode 100644 index 000000000..c985d0744 --- /dev/null +++ b/.claude/tasks/cli-migration-to-typescript.md @@ -0,0 +1,1346 @@ +# CLI Migration to TypeScript - Rich Ink UI Implementation Plan + +## Implementation Status + +### Completed Items ✅ +- Project structure created at `/apps/cli/` +- TypeScript/build configuration (tsup, tsconfig.json, package.json) +- All command file structures created in `/apps/cli/src/commands/` +- Basic Ink component files stubbed in `/apps/cli/src/components/` +- Utils directory structure created (renamed from lib to utils) +- CLAUDE.md and README.md created +- Package.json with all dependencies configured +- Environment validation script created at `/apps/cli/scripts/validate-env.ts` + +### Stubbed Items 🚧 (Structure exists, needs implementation) +- All command implementations (auth, init, deploy, parse, config, update, start/stop/reset) +- API client with basic structure at `/apps/cli/src/utils/api-client.ts` +- Configuration management at `/apps/cli/src/utils/config.ts` +- Error handling classes at `/apps/cli/src/utils/errors.ts` +- Basic Ink UI components (forms, tables, progress, prompts, status) +- YAML validation utilities at `/apps/cli/src/utils/yaml.ts` +- Credential encryption at `/apps/cli/src/utils/credentials.ts` + +### Pending Items ⏳ (Not yet started) +- Actual API integration and server communication +- Complete YAML validation schemas implementation +- Full credential encryption system +- Docker integration for service management +- Auto-update functionality with GitHub releases +- Comprehensive test suites and coverage +- Binary compilation with Bun +- Cross-platform distribution + +### Changes Made During Stubbing +- **Removed generate command**: Server handles semantic model generation via introspection +- **Removed chat command**: Not needed for CLI functionality +- **Renamed lib to utils directory**: Better alignment with CLI patterns +- **Confirmed Ink/React for all UI**: All user interface components use Ink framework +- **Simplified scope**: Focus on file system operations and API client functionality + +### Current State +The CLI has a complete project structure with TypeScript configuration and all file stubs in place. The foundation is ready for implementation of the actual command logic, API integration, and Ink UI components. All major architectural decisions have been made and reflected in the file structure. + +## Overview + +This document outlines the migration of the Rust-based Buster CLI to TypeScript with a **beautiful Ink-based terminal UI**. The CLI is designed as a **thin client with rich UI** that primarily handles file system operations and acts as a gateway to the server API. All business logic, semantic model creation, and data source introspection is handled by the server API. + +**CRITICAL: This CLI uses Ink and React for ALL user interface components. We are NOT building a simple console application.** + +### Core Architecture Principle +The CLI serves as a **file system operator and API client only**: +- File and folder creation/management +- YAML file validation and parsing +- Authentication and configuration management +- Service orchestration (Docker) +- All semantic modeling handled by server API via introspection +- No dbt catalog integration needed +- No direct SQL file processing + +## Current Rust CLI Analysis - SIMPLIFIED SCOPE + +### Simplified Commands and Functionality + +1. **Authentication (`auth`)** + - Interactive credential management + - Environment variable support (BUSTER_HOST, BUSTER_API_KEY) + - Local/cloud instance configuration + - Credential caching and validation + +2. **Initialization (`init`) - SIMPLIFIED** + - Creates buster folder structure only + - Generates buster.yml configuration file + - Creates docs/ and metadata/ folders + - NO database connection setup + - NO data source creation + - NO dbt integration + +3. **~~Generation (`generate`) - REMOVED~~** + - ~~Semantic model YAML generation from dbt catalog~~ + - ~~SQL file processing and model creation~~ + - ~~Directory structure management~~ + - ~~Integration with dbt docs generate~~ + +4. **Deployment (`deploy`)** + - Model validation and deployment via server API + - Cross-project reference validation via server API + - Dry-run support + - File processing via server API + +5. **Parsing (`parse`)** + - YAML model file validation + - Configuration resolution + - Error reporting and validation + +6. **Configuration (`config`)** + - Interactive LLM and Reranker settings management + - API key management + - Environment file updates + +7. **Service Management (`start`, `stop`, `reset`)** + - Docker Compose service orchestration + - Persistent application environment setup + - Asset extraction and configuration + - Telemetry management + +8. **Update (`update`)** + - Self-update functionality with auto-update capability + - GitHub releases integration + - Binary replacement and verification + - Cross-platform support + +9. **~~Chat (TUI Application) - REMOVED~~** + - ~~Interactive terminal UI using Ratatui~~ + - ~~AI agent integration~~ + - ~~File operations and command execution~~ + - ~~Real-time chat interface with completions~~ + +## Zod-First Type System and Validation Strategy + +### Core Philosophy +Following the monorepo pattern: **"We use Zod schemas and then export them as types"** + +All CLI types will be defined as Zod schemas first, then exported as TypeScript types for compile-time checking. This ensures: +- Runtime validation for all inputs (CLI args, YAML files, API responses) +- Type safety throughout the application +- Single source of truth for data structures +- Automatic serialization/deserialization +- Rich error reporting with detailed validation messages + +### Zod Integration Points + +1. **Command Input Validation**: All CLI command arguments and options validated with Zod +2. **YAML File Validation**: buster.yml and semantic model files validated with comprehensive schemas +3. **Configuration Validation**: All configuration files and settings validated at load time +4. **API Integration**: Server API request/response validation using @buster/server-shared schemas +5. **Environment Validation**: Environment variables validated with Zod schemas +6. **File System Operations**: File content validation before processing + +### Dependencies Mapping - SIMPLIFIED + +| Rust Dependency | TypeScript Equivalent | Purpose | CLI Usage Priority | +|----------------|----------------------|---------|-------------------| +| `clap` | `commander` + **Zod validation** | CLI argument parsing + validation | **HIGH** | +| ~~`ratatui` + `crossterm`~~ | ~~**Ink ecosystem**~~ | ~~Terminal UI framework~~ | **REMOVED** | +| ~~- ratatui widgets~~ | ~~`ink-text-input`~~ | ~~Text input components~~ | **REMOVED** | +| ~~- ratatui selectable~~ | ~~`ink-select-input`~~ | ~~Selection components~~ | **REMOVED** | +| ~~- ratatui table~~ | ~~`ink-table`~~ | ~~Table display~~ | **REMOVED** | +| ~~- ratatui progress~~ | ~~Custom Ink progress bars~~ | ~~Progress indicators~~ | **REMOVED** | +| ~~- ratatui spinner~~ | ~~`ink-spinner`~~ | ~~Loading indicators~~ | **REMOVED** | +| `tokio` | Native Node.js async | Async runtime | **HIGH** | +| `reqwest` | Native `fetch` + **Zod response validation** | HTTP client | **HIGH** | +| `serde` + `serde_yaml` | `js-yaml` + **Zod schemas** | YAML parsing + validation | **HIGH** | +| `serde_json` | Native JSON + **Zod schemas** | JSON handling + validation | **HIGH** | +| `inquire` | Simple `readline` + **Zod validation** | Basic interactive prompts | **MEDIUM** | +| ~~`indicatif`~~ | ~~**Ink progress components**~~ | ~~Progress indicators~~ | **REMOVED** | +| ~~`colored`~~ | ~~**Ink color props**~~ | ~~Terminal colors~~ | **REMOVED** | +| `glob` | `fast-glob` | File pattern matching | **MEDIUM** | +| `tempfile` | `tmp` | Temporary files | **LOW** | +| `regex` | Native RegExp | Regular expressions | **MEDIUM** | +| `anyhow`/`thiserror` | **Zod error handling** + Custom errors | Error management | **HIGH** | +| `dirs` | `os.homedir()` | Directory utilities | **HIGH** | +| `confy` | **Zod-validated config management** | Configuration | **HIGH** | +| `zip` | `yauzl`/`yazl` | Archive handling | **MEDIUM** | +| ~~`rustyline`~~ | ~~**Ink chat interface**~~ | ~~Line editing~~ | **REMOVED** | + +### Zod Schema Organization - SIMPLIFIED + +``` +apps/cli/src/schemas/ +├── commands/ # Command-specific schemas (simplified) +│ ├── auth.ts # Auth command validation +│ ├── init.ts # Init command validation (folder creation only) +│ ├── deploy.ts # Deploy command validation (API calls only) +│ ├── parse.ts # Parse command validation +│ ├── config.ts # Config command validation +│ ├── start.ts # Service start command +│ ├── stop.ts # Service stop command +│ ├── reset.ts # Service reset command +│ └── update.ts # Update command validation +├── config/ # Configuration schemas +│ ├── buster-yml.ts # buster.yml file schema (simplified) +│ ├── cli-config.ts # CLI configuration schema +│ ├── credentials.ts # Credential storage schema +│ └── environment.ts # Environment variable schema +├── models/ # Model schemas (minimal) +│ └── model-validation.ts # Basic model YAML validation only +├── api/ # API integration schemas +│ ├── requests.ts # API request schemas +│ ├── responses.ts # API response schemas +│ └── shared.ts # Re-exports from @buster/server-shared +└── index.ts # Central schema exports +``` + +## Monorepo Integration Strategy + +### Package Structure + +``` +apps/ +├── cli/ # New TypeScript CLI (replaces Rust) - SIMPLIFIED +│ ├── src/ +│ │ ├── commands/ # Command-specific folders (simplified) +│ │ │ ├── auth/ +│ │ │ │ ├── index.ts # Command implementation +│ │ │ │ ├── schemas.ts # Command-specific Zod schemas +│ │ │ │ ├── types.ts # Types exported from schemas +│ │ │ │ ├── helpers.ts # Command helpers +│ │ │ │ └── auth.test.ts # Command tests +│ │ │ ├── init/ # SIMPLIFIED - folder creation only +│ │ │ ├── deploy/ # API calls only +│ │ │ ├── parse/ # YAML validation only +│ │ │ ├── config/ # Settings management +│ │ │ ├── start/ # Service start +│ │ │ ├── stop/ # Service stop +│ │ │ ├── reset/ # Service reset +│ │ │ └── update/ # Auto-update +│ │ ├── schemas/ # Centralized Zod schemas (simplified) +│ │ │ ├── commands/ # Command validation schemas +│ │ │ ├── config/ # Configuration schemas +│ │ │ ├── models/ # Basic model schemas +│ │ │ ├── api/ # API integration schemas +│ │ │ └── index.ts # Schema exports +│ │ ├── lib/ # Shared CLI utilities +│ │ │ ├── api-client.ts # Server API client + Zod validation +│ │ │ ├── config.ts # Zod-validated config management +│ │ │ ├── errors.ts # Zod error handling + custom errors +│ │ │ ├── validation.ts # Zod validation utilities +│ │ │ ├── yaml.ts # YAML parsing + Zod validation +│ │ │ ├── fs-utils.ts # File system utilities +│ │ │ └── prompts.tsx # Ink-based prompting components +│ │ ├── components/ # Ink UI components +│ │ │ ├── forms/ # Form components +│ │ │ ├── tables/ # Table display components +│ │ │ ├── progress/ # Progress and spinner components +│ │ │ ├── prompts/ # Input and selection components +│ │ │ └── status/ # Status display components +│ │ └── main.ts # CLI entry point +│ ├── package.json +│ ├── tsconfig.json +│ └── vitest.config.ts +└── (current Rust CLI removed after migration) +``` + +### Integration Points - SIMPLIFIED + +1. **CLI as Thin Client**: CLI is purely a file system operator and API client + - File and folder creation/management + - YAML parsing and validation + - Authentication and configuration + - Service orchestration (Docker) + - ALL business logic via server API +2. **Zod-First Types**: Use Zod schemas from `@buster/server-shared` for API validation only +3. **Server API Gateway**: All semantic modeling, introspection, and data operations via server +4. **Configuration**: Simple Zod-validated configuration system +5. **Testing**: Basic Vitest patterns with focused schema testing +6. **Build**: Minimal turbo pipeline integration (build, lint, test) + +### Zod Integration with Server-Shared + +```typescript +// CLI schemas extend and re-export server-shared schemas +// apps/cli/src/schemas/api/shared.ts +export { + // Re-export server-shared schemas for CLI use + CreateDataSourceRequestSchema, + CreateDataSourceResponseSchema, + ValidateModelRequestSchema, + ValidateModelResponseSchema +} from '@buster/server-shared'; + +// Add CLI-specific extensions +export const CliAuthOptionsSchema = z.object({ + host: z.string().url().optional(), + apiKey: z.string().optional(), + interactive: z.boolean().default(true), +}); + +export type CliAuthOptions = z.infer; +``` + +## YAML Validation Strategy with Zod + +### Core YAML Files Requiring Validation + +1. **buster.yml**: Project configuration file +2. **Semantic Model Files**: YAML files defining data models +3. **dbt_project.yml**: dbt integration configuration +4. **CLI Configuration**: Local CLI settings + +### YAML Parsing and Validation Pipeline + +```typescript +// apps/cli/src/lib/yaml.ts +import yaml from 'js-yaml'; +import type { z } from 'zod'; +import { BusterYmlSchema } from '../schemas/config/buster-yml.js'; +import { SemanticModelSchema } from '../schemas/models/semantic-model.js'; + +export async function parseAndValidateYaml( + filePath: string, + schema: z.ZodSchema +): Promise { + try { + const fileContent = await fs.readFile(filePath, 'utf8'); + const parsedYaml = yaml.load(fileContent); + + // Zod validation with detailed error reporting + const result = schema.safeParse(parsedYaml); + + if (!result.success) { + throw new YamlValidationError( + `Invalid YAML structure in ${filePath}`, + result.error.errors, + filePath + ); + } + + return result.data; + } catch (error) { + if (error instanceof YamlValidationError) throw error; + throw new YamlParsingError(`Failed to parse YAML file: ${filePath}`, error); + } +} + +// Specialized functions for each YAML type +export const parseBusterYml = (filePath: string) => + parseAndValidateYaml(filePath, BusterYmlSchema); + +export const parseSemanticModel = (filePath: string) => + parseAndValidateYaml(filePath, SemanticModelSchema); +``` + +### Buster.yml Schema Definition + +```typescript +// apps/cli/src/schemas/config/buster-yml.ts +import { z } from 'zod'; + +const DatabaseTypeSchema = z.enum([ + 'postgresql', 'mysql', 'redshift', 'bigquery', + 'snowflake', 'sqlserver', 'databricks' +]); + +// SIMPLIFIED - No database connections, just project structure +export const BusterYmlSchema = z.object({ + version: z.string(), + project_name: z.string(), + api_endpoint: z.string().url().optional(), + config: z.object({ + models_path: z.string().default('./models'), + docs_path: z.string().default('./docs'), + metadata_path: z.string().default('./metadata'), + }).optional(), +}); + +export type BusterYmlConfig = z.infer; +``` + +### Basic Model Validation Schema - SIMPLIFIED + +```typescript +// apps/cli/src/schemas/models/model-validation.ts +import { z } from 'zod'; + +// Basic YAML validation only - no complex model structure since server handles introspection +export const BasicModelSchema = z.object({ + version: z.string(), + model: z.object({ + name: z.string(), + description: z.string().optional(), + }), +}); + +export type BasicModel = z.infer; +``` + +### Command Input Validation Patterns + +```typescript +// Example: apps/cli/src/commands/init/schemas.ts - SIMPLIFIED +import { z } from 'zod'; + +export const InitCommandArgsSchema = z.object({ + projectName: z.string().min(1, 'Project name is required'), + outputDir: z.string().default('./'), + force: z.boolean().default(false), +}); + +// No database connection options - server handles that via API +export const InitCommandOptionsSchema = z.object({ + apiEndpoint: z.string().url().optional(), +}); + +export type InitCommandArgs = z.infer; +export type InitCommandOptions = z.infer; +``` + +## Zod Error Handling and Validation Patterns + +### Error Hierarchy with Zod Integration + +```typescript +// apps/cli/src/lib/errors.ts +import type { z } from 'zod'; + +export class BusterCliError extends Error { + constructor(message: string, public code: string) { + super(message); + this.name = 'BusterCliError'; + } +} + +export class ZodValidationError extends BusterCliError { + constructor( + message: string, + public zodErrors: z.ZodError['errors'], + public filePath?: string + ) { + super(message, 'VALIDATION_ERROR'); + this.name = 'ZodValidationError'; + } + + getFormattedErrors(): string { + return this.zodErrors + .map(error => `${error.path.join('.')}: ${error.message}`) + .join('\n'); + } +} + +export class YamlValidationError extends ZodValidationError { + constructor(message: string, zodErrors: z.ZodError['errors'], filePath: string) { + super(message, zodErrors, filePath); + this.code = 'YAML_VALIDATION_ERROR'; + this.name = 'YamlValidationError'; + } +} + +export class CommandValidationError extends ZodValidationError { + constructor(command: string, zodErrors: z.ZodError['errors']) { + super(`Invalid arguments for command: ${command}`, zodErrors); + this.code = 'COMMAND_VALIDATION_ERROR'; + this.name = 'CommandValidationError'; + } +} +``` + +### Validation Utility Functions + +```typescript +// apps/cli/src/lib/validation.ts +import type { z } from 'zod'; +import { CommandValidationError, ZodValidationError } from './errors.js'; + +export function validateWithSchema( + data: unknown, + schema: z.ZodSchema, + context?: string +): T { + const result = schema.safeParse(data); + + if (!result.success) { + if (context) { + throw new ZodValidationError( + `Validation failed for ${context}`, + result.error.errors + ); + } + throw new ZodValidationError('Validation failed', result.error.errors); + } + + return result.data; +} + +export function validateCommandArgs( + args: unknown, + schema: z.ZodSchema, + commandName: string +): T { + const result = schema.safeParse(args); + + if (!result.success) { + throw new CommandValidationError(commandName, result.error.errors); + } + + return result.data; +} + +// Helper for safe parsing with defaults +export function parseWithDefaults( + data: unknown, + schema: z.ZodSchema +): { success: true; data: T } | { success: false; errors: z.ZodError['errors'] } { + const result = schema.safeParse(data); + return result.success + ? { success: true, data: result.data } + : { success: false, errors: result.error.errors }; +} +``` + +### Simple Prompting with Zod Validation - SIMPLIFIED + +```typescript +// Example: Simple readline prompting with validation +// apps/cli/src/lib/prompts.ts +import * as readline from 'node:readline'; +import type { z } from 'zod'; + +export async function promptWithValidation( + question: string, + schema: z.ZodSchema, + retries = 3 +): Promise { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + for (let attempt = 0; attempt < retries; attempt++) { + const answer = await new Promise((resolve) => { + rl.question(question, resolve); + }); + + const result = schema.safeParse(answer); + + if (result.success) { + rl.close(); + return result.data; + } + + console.error(`❌ Invalid input: ${result.error.errors.map(e => e.message).join(', ')}`); + + if (attempt === retries - 1) { + rl.close(); + throw new Error('Max retries exceeded for input validation'); + } + } + + rl.close(); + throw new Error('Input validation failed'); +} +``` + +### Package.json Structure + +```json +{ + "name": "@buster-app/cli", + "type": "module", + "exports": { + ".": { + "types": "./src/main.ts" + } + }, + "bin": { + "buster": "./dist/main.js" + }, + "scripts": { + "prebuild": "tsx scripts/validate-env.ts && pnpm run typecheck", + "build": "tsup", + "build:dry-run": "tsup", + "build:binary": "bun build --compile --outfile buster ./src/main.ts", + "dev": "tsx --watch src/main.ts", + "lint": "biome check --write", + "test": "vitest run", + "test:unit": "vitest run --exclude '**/*.int.test.ts'", + "test:integration": "vitest run **/*.int.test.ts", + "test:watch": "vitest --watch", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@buster/server-shared": "workspace:*", + "@buster/typescript-config": "workspace:*", + "@buster/vitest-config": "workspace:*", + "commander": "^12.0.0", + "zod": "catalog:", + "js-yaml": "^4.1.0", + "fast-glob": "^3.3.2", + "tmp": "^0.2.1", + "yauzl": "^3.0.0", + "yazl": "^2.5.1", + "ink": "^5.0.1", + "react": "^18.2.0", + "ink-text-input": "^6.0.0", + "ink-select-input": "^6.0.0", + "ink-table": "^3.0.0", + "ink-spinner": "^5.0.0" + } +} +``` + +### Turbo Integration Updates + +**Root turbo.json changes**: +```json +{ + "tasks": { + "build": { + "dependsOn": ["^build"], + "outputs": ["dist/**", ".next/**"] + }, + // ... existing tasks + } +} +``` + +**Root vitest.config.ts changes**: +```typescript +export default defineConfig({ + test: { + projects: [ + // ... existing packages + 'apps/cli', // Add CLI to test projects + ], + }, +}); +``` + +**Root tsconfig.json changes**: +```json +{ + "references": [ + // ... existing references + { "path": "./apps/cli" }, // Add CLI reference + ] +} +``` + +## Implementation Plan + +**IMPLEMENTATION REQUIREMENT: All UI components MUST use Ink and React. This is NOT a simple console application.** + +### Phase 1: Core Infrastructure (Week 1-2) + +#### Ticket 1.1: TypeScript CLI Foundation with Zod Schema Infrastructure and Ink UI 🚧 STUBBED +**Dependencies**: None +**Affected Packages**: `apps/cli` + +**Tasks**: +- Set up TypeScript CLI package structure following monorepo patterns +- Configure tsup build system (consistent with apps/server) +- Implement Commander.js command structure with Zod validation +- Set up Ink UI framework with React components +- Create Zod-based error handling system with detailed validation errors +- Set up centralized Zod schema organization (src/schemas/) +- Create Ink component library structure (src/components/) +- Integrate with turbo pipeline (build, lint, test, typecheck, schema-validation tasks) +- Set up vitest configuration using @buster/vitest-config +- Configure TypeScript using @buster/typescript-config + +**Key Files**: +- `/apps/cli/package.json` - Include turbo tasks, workspace dependencies, Zod, Ink ecosystem +- `/apps/cli/src/main.ts` - CLI entry point with commander + Zod validation +- `/apps/cli/src/lib/errors.ts` - Zod validation error hierarchy +- `/apps/cli/src/lib/command-base.ts` - Base command class with Zod validation +- `/apps/cli/src/lib/validation.ts` - Zod validation utilities +- `/apps/cli/src/components/` - Ink UI component library +- `/apps/cli/src/schemas/index.ts` - Central schema exports +- `/apps/cli/vitest.config.ts` - Test configuration +- `/apps/cli/tsconfig.json` - Extends @buster/typescript-config + +**Zod and Ink Integration**: +- Set up schema organization structure (commands/, config/, models/, api/) +- Create validation utilities for CLI arguments and options +- Implement detailed error reporting for validation failures with Ink error components +- Set up Ink component library with forms, tables, progress indicators +- Add schema testing patterns and Ink component testing +- Create reusable Ink components for validation error display + +**Turbo Integration**: +- Add CLI to turbo.json tasks +- Add to root vitest.config.ts projects array +- Add to root tsconfig.json references + +**Test Requirements**: +- Unit tests for command parsing with Zod validation (*.test.ts) +- Ink component rendering tests (*.test.tsx) +- Schema validation tests +- CLI help system verification with Ink components +- Command registration tests +- Zod error handling tests with Ink error display components +- Ink user interaction simulation tests + +#### Ticket 1.2: Server API Client Integration with Zod Validation 🚧 STUBBED +**Dependencies**: Ticket 1.1 +**Affected Packages**: `apps/cli`, `@buster/server-shared` + +**Tasks**: +- Implement HTTP client for server API communication with full Zod validation +- Re-export and extend Zod schemas from @buster/server-shared for all API contracts +- Create authentication wrapper with Zod-validated credentials +- Add comprehensive request/response validation using shared Zod schemas +- Implement retry and error handling with Zod error parsing +- No direct database or AI package usage - all via server API + +**Key Files**: +- `/apps/cli/src/lib/api-client.ts` - Main API client with Zod validation +- `/apps/cli/src/lib/http-client.ts` - HTTP wrapper with auth + validation +- `/apps/cli/src/lib/auth.ts` - Authentication helpers with Zod schemas +- `/apps/cli/src/schemas/api/shared.ts` - Re-exports from @buster/server-shared +- `/apps/cli/src/schemas/api/requests.ts` - CLI-specific request schemas +- `/apps/cli/src/schemas/api/responses.ts` - CLI-specific response schemas + +**Zod Server-Shared Integration**: +```typescript +// Re-export server-shared schemas with CLI extensions +export { + CreateDataSourceRequestSchema, + CreateDataSourceResponseSchema, + ValidateModelRequestSchema, + ValidateModelResponseSchema +} from '@buster/server-shared'; + +// CLI-specific API error schema +export const ApiErrorResponseSchema = z.object({ + error: z.string(), + code: z.string(), + details: z.record(z.any()).optional(), +}); +``` + +**Test Requirements**: +- API client unit tests with Zod-validated mocked responses +- Authentication flow tests with schema validation +- Request/response Zod validation tests +- Zod error handling and parsing tests +- Schema compatibility tests with @buster/server-shared + +#### Ticket 1.3: Configuration and Local Storage with YAML Validation 🚧 STUBBED +**Dependencies**: Ticket 1.2 +**Affected Packages**: `apps/cli` + +**Tasks**: +- Implement Zod-validated local configuration file handling (buster.yml) +- Create comprehensive YAML parsing and validation system +- Add credential storage and retrieval with Zod schemas (encrypted) +- Implement environment variable management with Zod validation using turbo.json globalEnv patterns +- Create configuration validation pipeline with detailed error reporting +- Support for different environments (local, cloud) with schema-based validation + +**Key Files**: +- `/apps/cli/src/lib/config.ts` - Zod-validated configuration management +- `/apps/cli/src/lib/yaml.ts` - YAML parsing and validation utilities +- `/apps/cli/src/lib/credentials.ts` - Secure credential storage with schemas +- `/apps/cli/src/lib/environment.ts` - Environment variable handling with Zod +- `/apps/cli/src/components/forms/ConfigForm.tsx` - Ink configuration form component +- `/apps/cli/src/schemas/config/buster-yml.ts` - buster.yml schema definition +- `/apps/cli/src/schemas/config/cli-config.ts` - CLI configuration schema +- `/apps/cli/src/schemas/config/credentials.ts` - Credential schema +- `/apps/cli/src/schemas/config/environment.ts` - Environment variable schema + +**Zod YAML Integration**: +```typescript +// YAML validation utility +export async function parseAndValidateYaml( + filePath: string, + schema: z.ZodSchema +): Promise { + const fileContent = await fs.readFile(filePath, 'utf8'); + const parsedYaml = yaml.load(fileContent); + + const result = schema.safeParse(parsedYaml); + if (!result.success) { + throw new YamlValidationError( + `Invalid YAML structure in ${filePath}`, + result.error.errors, + filePath + ); + } + return result.data; +} +``` + +**Test Requirements**: +- Configuration loading/saving tests with Zod validation +- YAML parsing and validation tests +- Environment variable precedence tests with schemas +- Credential encryption/decryption tests with Zod validation +- Comprehensive schema validation error testing +- buster.yml schema compatibility tests +- Ink form component tests for configuration management +- Ink table component tests for configuration display + +### Phase 2: Core Commands - SIMPLIFIED (Week 3-4) + +#### Ticket 2.1: Authentication Command with Simple Prompts and Zod Validation 🚧 STUBBED +**Dependencies**: Ticket 1.3 +**Affected Packages**: `apps/cli` + +**Tasks**: +- Implement `auth` command with Zod-validated inputs using simple readline prompts +- Add Zod-validated environment variable support +- Create credential validation via server API with Zod response validation +- Add local/cloud configuration options with schema-based validation + +**Key Files**: +- `/apps/cli/src/commands/auth/index.ts` - Command implementation with Zod validation +- `/apps/cli/src/commands/auth/AuthForm.tsx` - Ink form component for authentication +- `/apps/cli/src/commands/auth/schemas.ts` - Auth-specific Zod schemas +- `/apps/cli/src/commands/auth/types.ts` - Types exported from schemas +- `/apps/cli/src/commands/auth/helpers.ts` - Auth utilities with validation +- `/apps/cli/src/commands/auth/auth.test.ts` - Command tests with schema testing +- `/apps/cli/src/commands/auth/AuthForm.test.tsx` - Ink component tests + +**Zod Auth Schemas**: +```typescript +// apps/cli/src/commands/auth/schemas.ts +export const AuthCommandOptionsSchema = z.object({ + host: z.string().url().optional(), + apiKey: z.string().min(1).optional(), + interactive: z.boolean().default(true), + environment: z.enum(['local', 'cloud']).default('cloud'), +}); + +export const CredentialInputSchema = z.object({ + apiKey: z.string().min(1, 'API key is required'), + host: z.string().url('Invalid host URL'), +}); + +export type AuthCommandOptions = z.infer; +export type CredentialInput = z.infer; +``` + +**Simple Prompts Used**: +- readline for API key entry with Zod validation +- Simple console output for status messages +- Zod validation error display in console + +**Test Requirements**: +- Unit tests for auth logic with Zod validation (*.test.ts) +- Ink component tests for auth forms (*.test.tsx) +- Mocked server API responses with schema validation +- Credential validation tests with Zod schemas +- Environment variable precedence tests with schema validation +- Comprehensive Zod error handling tests +- Ink form interaction and validation display tests + +#### Ticket 2.2: Configuration Command - SIMPLIFIED 🚧 STUBBED +**Dependencies**: Ticket 2.1 +**Affected Packages**: `apps/cli` + +**Tasks**: +- Implement simple configuration management using console output +- Create forms for LLM and Reranker settings using simple prompts +- Add environment file updates with confirmation prompts +- Configuration reset functionality with simple confirmation + +**Key Files**: +- `/apps/cli/src/commands/config/index.ts` - Config command +- `/apps/cli/src/commands/config/types.ts` - Config types +- `/apps/cli/src/commands/config/helpers.ts` - Config utilities +- `/apps/cli/src/commands/config/config.test.ts` - Tests + +**Simple Interface Used**: +- Console table output for configuration display +- readline for option selection +- Simple confirmation prompts for destructive actions + +**Test Requirements**: +- Configuration update tests +- File modification tests +- Form validation tests + +#### Ticket 2.3: Service Management Commands - SIMPLIFIED 🚧 STUBBED +**Dependencies**: Ticket 2.2 +**Affected Packages**: `apps/cli` + +**Tasks**: +- Implement `start`, `stop`, `reset` commands with simple console output +- Add Docker Compose integration with status logging +- Create asset extraction system with basic progress feedback +- Display service status in console format + +**Key Files**: +- `/apps/cli/src/commands/start/index.ts` - Start command +- `/apps/cli/src/commands/stop/index.ts` - Stop command +- `/apps/cli/src/commands/reset/index.ts` - Reset command +- `/apps/cli/src/lib/docker-compose.ts` - Docker integration +- `/apps/cli/src/lib/assets.ts` - Asset management + +**Simple Interface Used**: +- Basic console logging for status +- Simple progress dots for loading states +- Text-based service status display + +**Test Requirements**: +- Docker Compose execution tests +- Asset extraction tests +- Service lifecycle tests + +### Phase 3: File System and API Commands - SIMPLIFIED (Week 5-6) + +#### Ticket 3.1: Initialization Command - File System Only 🚧 STUBBED +**Dependencies**: Ticket 2.3 +**Affected Packages**: `apps/cli` + +**Tasks**: +- Implement folder structure creation (buster/, docs/, metadata/) +- Create basic buster.yml configuration file +- NO database connection setup +- NO data source creation via API +- NO dbt integration + +**Key Files**: +- `/apps/cli/src/commands/init/index.ts` - Init command (file system only) +- `/apps/cli/src/commands/init/types.ts` - Init types (simplified) +- `/apps/cli/src/commands/init/helpers.ts` - File system utilities +- `/apps/cli/src/commands/init/init.test.ts` - Tests +- `/apps/cli/src/lib/fs-utils.ts` - File system utilities + +**File System Operations**: +- Create project directory structure +- Generate basic buster.yml with project name only +- Create empty docs/ and metadata/ folders +- Simple console output for confirmation + +**Test Requirements**: +- File system creation tests +- Configuration generation tests +- Directory structure validation tests +- Error handling for existing projects + +#### Ticket 3.2: Deployment and Parsing Commands via Server API 🚧 STUBBED +**Dependencies**: Ticket 3.1 +**Affected Packages**: `apps/cli`, `apps/server` (existing endpoints) + +**Tasks**: +- Implement deployment validation via server API +- Add model parsing and validation through server endpoints +- Create cross-project reference checking via server +- Add dry-run functionality with console output +- Simple console-based validation result display + +**Key Files**: +- `/apps/cli/src/commands/deploy/index.ts` - Deploy command +- `/apps/cli/src/commands/parse/index.ts` - Parse command +- `/apps/cli/src/commands/deploy/types.ts` - Deploy types +- `/apps/cli/src/commands/parse/types.ts` - Parse types + +**Server API Integration**: +- Use existing server endpoints for model validation +- Stream validation results to console +- Use types from @buster/server-shared +- All business logic handled by server + +**Simple Interface Used**: +- Console table for validation results +- Simple error/warning display in console +- Basic confirmation prompts for deployment +- Text-based progress indicators + +**Test Requirements**: +- Deployment validation API tests +- Model parsing tests +- Cross-reference validation tests +- Dry-run functionality tests + +### Phase 4: Advanced Features - SIMPLIFIED (Week 7) + +#### Ticket 4.1: Update Command with Auto-Update ⏳ PENDING +**Dependencies**: Ticket 3.2 +**Affected Packages**: `apps/cli` + +**Tasks**: +- Implement self-update functionality with auto-update capability +- Add GitHub releases integration +- Create binary replacement system +- Add cross-platform support +- Auto-update check on CLI startup (configurable) + +**Key Files**: +- `/apps/cli/src/commands/update/index.ts` - Update command +- `/apps/cli/src/lib/updater.ts` - Update logic +- `/apps/cli/src/lib/github-releases.ts` - GitHub integration +- `/apps/cli/src/lib/auto-update.ts` - Auto-update functionality + +**Simple Interface Used**: +- Console-based update progress +- Simple confirmation prompts +- Basic version comparison display + +**Test Requirements**: +- Update mechanism tests +- Version comparison tests +- Binary replacement tests +- Auto-update logic tests + +### Phase 5: Testing and Documentation (Week 8) + +#### Ticket 5.1: Comprehensive Testing ⏳ PENDING +**Dependencies**: All previous tickets +**Affected Packages**: `apps/cli` + +**Tasks**: +- Complete unit test coverage for core commands +- Add integration test suites for file system operations +- Create end-to-end test scenarios for API interactions +- Add basic performance benchmarks + +**Test Requirements**: +- Minimum 80% code coverage (reduced scope) +- All command scenarios tested +- Error handling verification +- Cross-platform compatibility tests + +#### Ticket 5.2: Documentation and Migration ⏳ PENDING +**Dependencies**: Ticket 5.1 +**Affected Packages**: `apps/cli`, root documentation + +**Tasks**: +- Create basic CLI documentation +- Add migration guide from Rust CLI +- Update build and deployment scripts +- Create distribution packages + +**Key Files**: +- `/apps/cli/README.md` +- `/apps/cli/MIGRATION.md` +- Distribution configuration files + +### Phase 6: Deployment and Distribution (Week 9) + +#### Ticket 6.1: Bun Compilation and Distribution ⏳ PENDING +**Dependencies**: Ticket 5.2 +**Affected Packages**: `apps/cli`, CI/CD + +**Tasks**: +- Set up Bun binary compilation for single executables +- Create cross-platform builds (Linux, macOS, Windows) +- Implement GitHub releases automation +- Add package distribution (npm, homebrew) +- Integrate with turbo build pipeline + +**Key Files**: +- `/.github/workflows/cli-build.yml` - CI/CD pipeline +- `/apps/cli/scripts/build-binaries.js` - Build scripts +- `/apps/cli/package.json` - Bun build configuration +- Package manager configuration files + +**Bun Integration**: +- Use `bun build --compile` for executable generation +- Cross-platform compilation targets +- Size optimization for distribution + +#### Ticket 6.2: Migration and Rust CLI Removal ⏳ PENDING +**Dependencies**: Ticket 6.1 +**Affected Packages**: `apps/cli`, documentation, CI/CD + +**Tasks**: +- Create migration documentation +- Update installation instructions +- Remove Rust CLI from monorepo +- Update turbo.json and root configurations +- Monitor adoption and feedback + +**Migration Steps**: +- Remove apps/cli Rust directory +- Update root tsconfig.json references +- Update turbo.json task configurations +- Update documentation and README files + +## Simple Console Interface Strategy - SIMPLIFIED + +### Console Output Patterns + +**Basic Console Tools**: +- `console.table()` - Data display and configuration views +- `process.stdout.write()` - Progress indicators with dots/bars +- `readline` - User input prompts with validation +- Simple colored text for status (success/error/warning) + +### UI Replacement Strategy + +| Rust CLI Feature | Simple Console Equivalent | Usage in CLI | +|------------------|---------------------------|--------------| +| Interactive menus | Simple numbered prompts | Command options, selections | +| Data tables | `console.table()` | Configuration display, status | +| Progress bars | Text-based progress dots | File operations, API calls | +| Forms | Sequential readline prompts | Configuration setup | +| Confirmations | Simple y/n prompts | Destructive actions | +| Spinners | Rotating character or dots | Loading states | + +### Console Utilities for CLI + +**File System Operations**: +- Basic folder creation confirmation +- File listing with simple formatting +- Progress feedback for batch operations + +**API Communication**: +- Simple request/response logging +- Error display with clear formatting +- Success/failure status messages + +**Configuration Management**: +- Tabular configuration display +- Simple prompt-based editing +- Validation error display + +### Benefits of Simple Console Interface + +1. **Minimal Dependencies**: No complex UI libraries required +2. **Fast Startup**: No heavy rendering engine to initialize +3. **Universal Compatibility**: Works in all terminal environments +4. **Easy Testing**: Simple console output can be easily tested +5. **Maintainability**: No complex UI state management +6. **Performance**: Minimal overhead for CLI operations + +## Architecture Decisions + +### Framework Choices - RICH INK UI + +1. **CLI Framework**: Commander.js for argument parsing and command structure +2. **Type System & Validation**: **Zod-first approach** - Focused on essential validation + - Zod schemas for CLI args, YAML files, and API requests/responses + - Runtime validation with compile-time type safety + - Integration with @buster/server-shared Zod schemas for API only + - Rich error handling for validation failures with Ink components +3. **Interface**: **REQUIRED Rich Ink UI Interface**: + - `ink-text-input` for user input with Zod validation + - `ink-table` for beautiful data display + - `ink-spinner` and custom progress components + - Rich Ink components with colors, formatting, and interactivity + - React-based component architecture for maintainable UI +4. **HTTP Client**: Fetch API (native Node.js) with Zod request/response validation +5. **YAML Processing**: js-yaml with basic Zod schema validation +6. **Testing**: Vitest following monorepo patterns with focused schema testing +7. **Build System**: tsup (consistent with apps/server) +8. **Binary Generation**: Bun for single executable creation +9. **Type Safety**: Focused Zod integration with @buster/server-shared schemas for API calls only + +### Integration Patterns - REQUIRED INK UI + +1. **CLI as File System Operator**: CLI handles file/folder operations and acts as API client with rich UI + - File and folder creation/management with Ink progress indicators + - YAML parsing and validation with rich error displays + - Authentication and configuration with Ink forms + - Service orchestration (Docker) with real-time status updates +2. **Server-Centric Business Logic**: All semantic modeling, introspection, and data operations via server API +3. **Focused API Integration**: Use Zod schemas from `@buster/server-shared` for API calls only +4. **Rich Configuration UI**: Ink-based forms and displays for CLI settings management +5. **Comprehensive Testing**: Focused vitest patterns with Ink component testing (*.test.ts) +6. **Full Build Integration**: Complete turbo pipeline integration (build, lint, test, UI components) +7. **Rich UI Dependencies**: Workspace dependencies plus Ink ecosystem for professional interface +8. **Essential Validation**: Key data flows validated with Zod and displayed via rich Ink components + +### Error Handling Strategy + +```typescript +// Zod-integrated error hierarchy +export class BusterCliError extends Error { + constructor(message: string, public code: string) { + super(message); + this.name = 'BusterCliError'; + } +} + +export class ZodValidationError extends BusterCliError { + constructor( + message: string, + public zodErrors: z.ZodError['errors'], + public filePath?: string + ) { + super(message, 'VALIDATION_ERROR'); + this.name = 'ZodValidationError'; + } + + getFormattedErrors(): string { + return this.zodErrors + .map(error => `${error.path.join('.')}: ${error.message}`) + .join('\n'); + } +} + +export class YamlValidationError extends ZodValidationError { + constructor(message: string, zodErrors: z.ZodError['errors'], filePath: string) { + super(message, zodErrors, filePath); + this.code = 'YAML_VALIDATION_ERROR'; + } +} + +export class CommandValidationError extends ZodValidationError { + constructor(command: string, zodErrors: z.ZodError['errors']) { + super(`Invalid arguments for command: ${command}`, zodErrors); + this.code = 'COMMAND_VALIDATION_ERROR'; + } +} +``` + +### Testing Strategy - SIMPLIFIED + +1. **Unit Tests (*.test.ts)**: + - Individual functions and command logic + - API client mocking with Zod validation + - Configuration management + - File system utilities + +2. **Integration Tests (*.int.test.ts)**: + - Full command execution with mocked server API + - File system operations + - Configuration file generation + - Basic workflow testing + +3. **Console Interface Tests**: + - Console output verification + - Readline input simulation + - Error message formatting + - Simple progress indicator testing + +4. **Mock Strategy**: + - Mock server API responses using MSW + - Mock file system operations with temp directories + - Mock external process execution (Docker) + - Mock configuration file access + +5. **Test Organization**: + - Command tests in command directories: `/commands/auth/auth.test.ts` + - Utility tests alongside utilities: `/lib/fs-utils.test.ts` + - Integration tests in `/tests/integration/` + - Test utilities in `/tests/utils/` + +### Security Considerations + +1. **Credential Storage**: Encrypt sensitive data at rest +2. **API Communication**: Use HTTPS with proper certificate validation +3. **Input Validation**: Sanitize all user inputs +4. **Environment Variables**: Secure handling of sensitive environment data + +## Migration Timeline - SIMPLIFIED + +- **Weeks 1-2**: Core infrastructure and foundation +- **Weeks 3-4**: Essential commands (auth, config, services) +- **Weeks 5-6**: File system commands (init) and API commands (deploy, parse) +- **Week 7**: Advanced features (auto-update) +- **Week 8**: Testing and documentation +- **Week 9**: Deployment and migration + +## Success Criteria - SIMPLIFIED + +1. **Functional Parity**: Essential Rust CLI commands replicated in TypeScript with simple console interface and focused Zod validation +2. **Performance**: CLI startup time under 300ms with minimal dependencies +3. **Focused Type Safety**: + - Key data structures defined as Zod schemas (CLI args, YAML files, API calls) + - Runtime validation for essential inputs + - Integration with @buster/server-shared Zod schemas for API only + - Clear validation error reporting +4. **Monorepo Integration**: + - Basic turbo pipeline integration (build, lint, test) + - Proper use of @buster/server-shared Zod schemas for API calls + - CLI as thin file system operator and API client +5. **Essential Validation**: + - Basic buster.yml schema validation + - Simple YAML validation for configuration files + - API request/response validation via server-shared schemas +6. **Rich Ink Interface**: + - Beautiful Ink-based interface with rich tables and interactive prompts + - Animated progress indicators and real-time status updates + - React-based component state management for complex UI interactions +7. **Testing**: 80%+ code coverage with focused schema and Ink component testing +8. **Type Safety**: Focused Zod schema integration for essential operations +9. **Distribution**: Bun-compiled single executable for all platforms with Ink UI +10. **Architecture**: Clean separation - CLI handles file system with rich UI, server handles business logic + +## Risk Mitigation + +1. **Parallel Development**: Keep Rust CLI functional during migration +2. **Incremental Migration**: Allow users to gradually adopt new CLI +3. **Compatibility**: Maintain configuration file compatibility +4. **Rollback Plan**: Keep Rust CLI available as fallback +5. **Testing**: Extensive testing across platforms and scenarios + +## Post-Migration Tasks + +1. **Performance Monitoring**: Track CLI usage and performance metrics +2. **User Feedback**: Collect and address user feedback +3. **Feature Enhancements**: Add TypeScript-specific improvements +4. **Maintenance**: Regular updates and security patches +5. **Documentation**: Keep documentation updated with new features + +## Updated Implementation Summary: Rich UI Thin Client CLI + +This updated plan transforms the CLI migration to a **rich UI, thin client architecture**: + +### Core Transformation Principles - REQUIRED INK UI + +1. **CLI as File System Operator**: Primary responsibility is file and folder management + - Create project directory structures + - Generate basic configuration files (buster.yml) + - Handle YAML parsing and validation + - Manage local CLI configuration and credentials + +2. **Server-Centric Business Logic**: All complex operations handled by server API + - Semantic model creation and introspection via server API + - Data source connections managed by server + - Model validation and deployment via server endpoints + - No dbt catalog generation in CLI - server handles via introspection + +3. **Focused Zod Integration**: Validation only where essential + - CLI command arguments and options + - Basic YAML file parsing (simplified buster.yml) + - API request/response validation using @buster/server-shared schemas + - Configuration file validation + +4. **Rich Ink UI Interface**: Professional terminal UI framework + - Ink text input components for user input + - Ink table components for rich data display + - Ink spinner and progress components with animations + - Rich Ink components with colors, borders, and interactive elements + +5. **Rich UI Dependencies**: Professional interface requirements + - Commander.js for CLI structure + - Zod for essential validation + - js-yaml for configuration parsing + - Native Node.js APIs for most operations + - **Ink ecosystem for beautiful terminal UI** + - **React for component-based UI architecture** + +6. **Essential Commands Only**: Focused command set + - **auth**: Authentication and credential management + - **init**: Folder structure creation (no database setup) + - **config**: Simple configuration management + - **deploy**: Model deployment via server API + - **parse**: YAML validation + - **start/stop/reset**: Service management + - **update**: Auto-update functionality + - **REMOVED**: generate command (server handles via introspection) + - **REMOVED**: chat command (not needed) + +7. **Accelerated Timeline**: Reduced from 12 weeks to 9 weeks + - Weeks 1-2: Core infrastructure + - Weeks 3-4: Essential commands + - Weeks 5-6: File system and API commands + - Week 7: Auto-update + - Week 8: Testing and documentation + - Week 9: Deployment + +### Key Benefits of Required Rich Ink UI Approach + +- **Exceptional User Experience**: Beautiful, professional Ink interface with rich interactions +- **Modern Terminal UI**: State-of-the-art React-based components for terminal applications +- **Professional Interface**: Rich visual feedback, colors, animations, and interactive components +- **Component Architecture**: Maintainable React components with proper state management +- **Clear Separation**: CLI handles file system with rich UI, server handles business logic +- **User Focus**: Streamlined commands with beautiful interface focus on essential user workflows +- **Future Flexibility**: Ink-based components can easily be extended and enhanced + +**The CLI is NOT a simple console application**. It uses Ink and React to create a **professional, modern terminal interface** that excels at file system operations while delegating complex business logic to the server. This creates a cleaner architecture with better separation of concerns and an exceptional user experience. \ No newline at end of file diff --git a/.gitignore b/.gitignore index c99174f27..8a575aed3 100644 --- a/.gitignore +++ b/.gitignore @@ -75,7 +75,6 @@ web/playwright-tests/auth-utils/auth.json .trigger -.claude/tasks .claude/commands .claude/settings.local.json diff --git a/apps/cli/.cursor/rules/global.mdc b/apps/cli-deprecated/.cursor/rules/global.mdc similarity index 100% rename from apps/cli/.cursor/rules/global.mdc rename to apps/cli-deprecated/.cursor/rules/global.mdc diff --git a/apps/cli/.gitignore b/apps/cli-deprecated/.gitignore similarity index 100% rename from apps/cli/.gitignore rename to apps/cli-deprecated/.gitignore diff --git a/apps/cli-deprecated/CLAUDE.md b/apps/cli-deprecated/CLAUDE.md new file mode 100644 index 000000000..efb985308 --- /dev/null +++ b/apps/cli-deprecated/CLAUDE.md @@ -0,0 +1,34 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Build Commands +- Build: `cargo build` +- Release build: `cargo build --release` +- Run tests: `cargo test` +- Run specific test: `cargo test test_name` +- Run tests in file: `cargo test --test filename` +- Run package tests: `cargo test -p ` +- Format: `cargo fmt` +- Lint: `cargo clippy` + +## Code Style Guidelines +- **Imports**: Group by std, external crates, internal modules; alphabetical order +- **Formatting**: 4-space indentation (standard Rust) +- **Error Handling**: Use `thiserror` for error types, `anyhow` for general propagation +- **Naming**: Follow Rust conventions (`snake_case` for variables/functions, `PascalCase` for types) +- **Types**: Define custom error types with descriptive messages +- **Dependencies**: Use workspace dependencies with `{ workspace = true }` +- **Testing**: Place in separate `/tests` directory; use `tempfile` for test directories +- **Never log secrets or sensitive data** + +## Project Info +- CLI for managing semantic models in Buster +- Uses semantic versioning (PR title conventions for bumps) + - Major: PR title with "BREAKING CHANGE" or "major", or PR with "major" label + - Minor: PR title with "feat", "feature", or "minor", or PR with "minor" label + - Patch: Default for all other PRs +- Cross-project references supported +- Config defined in `buster.yml` +- File and tag exclusions for deployment +- Row limit of 5000 is enforced for database queries by default \ No newline at end of file diff --git a/apps/cli/Cargo.toml b/apps/cli-deprecated/Cargo.toml similarity index 100% rename from apps/cli/Cargo.toml rename to apps/cli-deprecated/Cargo.toml diff --git a/apps/cli/Makefile b/apps/cli-deprecated/Makefile similarity index 100% rename from apps/cli/Makefile rename to apps/cli-deprecated/Makefile diff --git a/apps/cli-deprecated/README.md b/apps/cli-deprecated/README.md new file mode 100644 index 000000000..f3ea1ffaf --- /dev/null +++ b/apps/cli-deprecated/README.md @@ -0,0 +1,370 @@ +# Buster CLI + +A powerful command-line interface for managing semantic models in Buster. Deploy and manage your data models with ease, whether they're standalone or part of a dbt project. + +## Installation + +Choose the installation command for your operating system: + +### macOS (x86_64) +```bash +mkdir -p ~/.local/bin && curl -L https://github.com/buster-so/buster/releases/latest/download/buster-cli-darwin-x86_64.tar.gz | tar xz && mv buster-cli ~/.local/bin/buster && chmod +x ~/.local/bin/buster +``` + +### macOS (ARM/Apple Silicon) +```bash +mkdir -p ~/.local/bin && curl -L https://github.com/buster-so/buster/releases/latest/download/buster-cli-darwin-arm64.tar.gz | tar xz && mv buster-cli ~/.local/bin/buster && chmod +x ~/.local/bin/buster +``` + +### Linux (x86_64) +```bash +mkdir -p ~/.local/bin && curl -L https://github.com/buster-so/buster/releases/latest/download/buster-cli-linux-x86_64.tar.gz | tar xz && mv buster-cli ~/.local/bin/buster && chmod +x ~/.local/bin/buster +``` + +> **Note**: After installation, make sure `~/.local/bin` is in your PATH. Add this to your shell's config file (`.bashrc`, `.zshrc`, etc.): +> ```bash +> export PATH="$HOME/.local/bin:$PATH" +> ``` + +### Windows (x86_64) +1. Download the Windows binary: +```powershell +Invoke-WebRequest -Uri https://github.com/buster-so/buster/releases/latest/download/buster-cli-windows-x86_64.zip -OutFile buster.zip +``` + +2. Extract and install: +```powershell +Expand-Archive -Path buster.zip -DestinationPath $env:USERPROFILE\buster +Move-Item -Path $env:USERPROFILE\buster\buster-cli.exe -Destination $env:LOCALAPPDATA\Microsoft\WindowsApps\buster.exe +``` + +## Quick Start Guide + +### 1. Authentication + +First, authenticate with Buster using your API key: + +```bash +buster auth +``` + +This will prompt you for: +- API Key (required) - Get this from the Buster Platform +- Host (optional) - Defaults to production if not specified + +You can also configure authentication using environment variables: +```bash +# Set API key via environment variable +export BUSTER_API_KEY=your_api_key_here + +# Optional: Set custom host. For self-hosted instances. +export BUSTER_HOST=your_custom_host +``` + +The CLI will check for these environment variables in the following order: +1. Command line arguments +2. Environment variables +3. Interactive prompt + +This is particularly useful for: +- CI/CD environments +- Automated scripts +- Development workflows where you don't want to enter credentials repeatedly + +### 2. Generate Models + +Generate Buster YAML models from your existing SQL files: + +```bash +buster generate +``` + +Key flags for generation: +- `--source-path`: Directory containing your SQL files (defaults to current directory) +- `--destination-path`: Where to output the generated YAML files (defaults to current directory) +- `--data-source-name`: Name of the data source to use in the models +- `--schema`: Database schema name +- `--database`: Database name +- `--flat-structure`: Output YML files in a flat structure instead of maintaining directory hierarchy + +The generate command will: +- Scan the source directory for SQL files +- Create corresponding YAML model files +- Create a `buster.yml` configuration file if it doesn't exist +- Preserve any existing model customizations + +Example with all options: +```bash +buster generate \ + --source-path ./sql \ + --destination-path ./models \ + --data-source-name my_warehouse \ + --schema analytics \ + --database prod +``` + +### 3. Deploy Models + +Deploy your models to Buster: + +```bash +buster deploy +``` + +Deploy options: +- `--path`: Specific path to deploy (defaults to current directory) +- `--dry-run`: Validate the deployment without actually deploying (defaults to false) +- `--recursive`: Recursively search for model files in subdirectories (defaults to true) + +Examples: +```bash +# Deploy all models in current directory +buster deploy + +# Deploy a specific model or directory +buster deploy --path ./models/customers.yml + +# Validate deployment without applying changes +buster deploy --dry-run + +# Deploy only models in the specified directory (not recursively) +buster deploy --path ./models --recursive=false +``` + +The deploy command will: +1. Discover all YAML model files in the specified path +2. Load and validate the models +3. Check for excluded models based on tags +4. Validate cross-project references +5. Deploy the models to Buster +6. Provide detailed validation feedback and error messages + +## Project Structure + +A typical Buster project structure: + +``` +your-project/ +├── buster.yml # Global configuration +├── models/ # Your semantic model definitions +│ ├── customers.yml +│ ├── orders.yml +│ └── products.yml +└── sql/ # SQL definitions + ├── customers.sql + ├── orders.sql + └── products.sql +``` + +### Configuration (buster.yml) + +```yaml +# buster.yml +data_source_name: "my_warehouse" # Your default data source +schema: "analytics" # Default schema for models +database: "prod" # Optional database name +exclude_files: # Optional list of files to exclude from generation + - "temp_*.sql" # Exclude all SQL files starting with temp_ + - "test/**/*.sql" # Exclude all SQL files in test directories + - "customers.sql" # Exclude a specific file +exclude_tags: # Optional list of tags to exclude from deployment + - "staging" # Exclude models with the 'staging' tag + - "test" # Exclude models with the 'test' tag +``` + +The configuration supports the following fields: +- `data_source_name`: (Required) Default data source for your models +- `schema`: (Required) Default schema for your models +- `database`: (Optional) Default database name +- `exclude_files`: (Optional) List of glob patterns for files to exclude from generation + - Supports standard glob patterns (*, **, ?, etc.) + - Matches against relative paths from source directory + - Common use cases: + - Excluding temporary files: `temp_*.sql` + - Excluding test files: `test/**/*.sql` + - Excluding specific files: `customers.sql` + - Excluding files in directories: `archive/**/*.sql` +- `exclude_tags`: (Optional) List of tags to exclude from deployment + - Looks for tags in SQL files in dbt format: `{{ config(tags=['tag1', 'tag2']) }}` + - Useful for excluding staging models, test models, etc. + - Case-insensitive matching + +### Model Definition Example + +```yaml +# models/customers.yml +version: 1 +models: + - name: customers + description: "Core customer data model" + data_source_name: "my_warehouse" # Overrides buster.yml + schema: "analytics" # Overrides buster.yml + database: "prod" # Overrides buster.yml + + entities: + - name: customer_id + expr: "id" + type: "primary" + description: "Primary customer identifier" + - name: order + expr: "order_id" + type: "foreign" + description: "Reference to order model" + # Optional: reference to another model in a different project + project_path: "path/to/other/project" + # Optional: specify a different name for the referenced model + ref: "orders" + + dimensions: + - name: email + expr: "email" + type: "string" + description: "Customer email address" + searchable: true # Optional: make this dimension searchable + + measures: + - name: total_customers + expr: "customer_id" + agg: "count_distinct" + description: "Total number of unique customers" + type: "integer" # Optional: specify the data type +``` + +## Cross-Project References + +Buster CLI supports referencing models across different projects, enabling you to build complex data relationships: + +```yaml +entities: + - name: user_model + expr: "user_id" + type: "foreign" + description: "Reference to user model in another project" + project_path: "path/to/user/project" + ref: "users" # Optional: specify a different name for the referenced model +``` + +When using cross-project references, the CLI will: +1. Validate that the referenced project exists +2. Check for a valid buster.yml in the referenced project +3. Verify that the data sources match between projects +4. Confirm that the referenced model exists in the target project + +This enables you to organize your models into logical projects while maintaining relationships between them. + +## Tag-Based Exclusion + +You can exclude models from deployment based on tags in your SQL files. This is useful for excluding staging models, test models, or any other models you don't want to deploy. + +In your SQL files, add tags using the dbt format: + +```sql +{{ config( + tags=['staging', 'test'] +) }} + +SELECT * FROM source_table +``` + +Then in your buster.yml, specify which tags to exclude: + +```yaml +exclude_tags: + - "staging" + - "test" +``` + +During deployment, any model with matching tags will be automatically excluded. + +## File and Tag Exclusions + +Buster CLI provides a unified way to exclude files from processing across all commands. You can specify exclusions in your `buster.yml` file: + +```yaml +data_source_name: "my_data_source" +schema: "my_schema" +database: "my_database" +exclude_files: + - "**/*_temp.sql" + - "staging/**/*.sql" + - "tests/**/*.yml" +exclude_tags: + - "test" + - "deprecated" + - "wip" +``` + +### Exclude Files + +The `exclude_files` section allows you to specify glob patterns for files that should be excluded from processing. This works for any command that processes files. + +Common patterns: +- `"**/*_temp.sql"` - Exclude any SQL file ending with _temp.sql in any directory +- `"staging/**/*.sql"` - Exclude all SQL files in the staging directory and its subdirectories +- `"test_*.yml"` - Exclude all YAML files starting with test_ + +### Exclude Tags + +The `exclude_tags` section allows you to exclude files based on tags specified in the file content. This is useful for excluding files that are marked as test, deprecated, etc. + +Tags are specified in the SQL files using the format: `-- tags = ['tag1', 'tag2']` + +When a file contains any of the excluded tags, it will be skipped by all commands. + +## Best Practices + +1. **Organization** + - Keep YAML files in `models/` + - Keep SQL files in `sql/` + - Use `buster.yml` for shared settings + - Group related models into subdirectories + +2. **Model Generation** + - Start with clean SQL files + - Generate models first before customizing + - Review generated models before deployment + - Use tags to organize and filter models + +3. **Deployment** + - Use `--dry-run` to validate changes + - Deploy frequently to catch issues early + - Keep model and SQL files in sync + - Use cross-project references for complex relationships + +4. **Validation** + - Ensure all models have descriptions + - Validate cross-project references before deployment + - Check for missing dependencies + - Review validation errors carefully + +## Troubleshooting + +Common issues and solutions: + +1. **Authentication Issues** + - Verify your API key is correct + - Check if the host is properly specified (if using non-production) + - Ensure network connectivity to Buster + +2. **Generation Issues** + - Verify SQL files are in the correct location + - Check file permissions + - Ensure SQL syntax is valid + - Check for excluded files or tags + +3. **Deployment Issues** + - Validate YAML syntax + - Check for missing dependencies + - Verify data source connectivity + - Look for cross-project reference errors + - Check for tag-based exclusions + +4. **Cross-Project Reference Issues** + - Ensure the referenced project exists + - Verify the referenced project has a valid buster.yml + - Check that data sources match between projects + - Confirm the referenced model exists in the target project + +## License + +MIT License - see [LICENSE](LICENSE) for details. diff --git a/apps/cli/VERSIONING.md b/apps/cli-deprecated/VERSIONING.md similarity index 100% rename from apps/cli/VERSIONING.md rename to apps/cli-deprecated/VERSIONING.md diff --git a/apps/cli/cli/Cargo.toml b/apps/cli-deprecated/cli/Cargo.toml similarity index 100% rename from apps/cli/cli/Cargo.toml rename to apps/cli-deprecated/cli/Cargo.toml diff --git a/apps/cli/cli/build.rs b/apps/cli-deprecated/cli/build.rs similarity index 100% rename from apps/cli/cli/build.rs rename to apps/cli-deprecated/cli/build.rs diff --git a/apps/cli/cli/docker-compose.yml b/apps/cli-deprecated/cli/docker-compose.yml similarity index 100% rename from apps/cli/cli/docker-compose.yml rename to apps/cli-deprecated/cli/docker-compose.yml diff --git a/apps/cli/cli/src/assets/mod.rs b/apps/cli-deprecated/cli/src/assets/mod.rs similarity index 100% rename from apps/cli/cli/src/assets/mod.rs rename to apps/cli-deprecated/cli/src/assets/mod.rs diff --git a/apps/cli/cli/src/commands/auth.rs b/apps/cli-deprecated/cli/src/commands/auth.rs similarity index 100% rename from apps/cli/cli/src/commands/auth.rs rename to apps/cli-deprecated/cli/src/commands/auth.rs diff --git a/apps/cli/cli/src/commands/chat/args.rs b/apps/cli-deprecated/cli/src/commands/chat/args.rs similarity index 100% rename from apps/cli/cli/src/commands/chat/args.rs rename to apps/cli-deprecated/cli/src/commands/chat/args.rs diff --git a/apps/cli/cli/src/commands/chat/completion.rs b/apps/cli-deprecated/cli/src/commands/chat/completion.rs similarity index 100% rename from apps/cli/cli/src/commands/chat/completion.rs rename to apps/cli-deprecated/cli/src/commands/chat/completion.rs diff --git a/apps/cli/cli/src/commands/chat/config.rs b/apps/cli-deprecated/cli/src/commands/chat/config.rs similarity index 100% rename from apps/cli/cli/src/commands/chat/config.rs rename to apps/cli-deprecated/cli/src/commands/chat/config.rs diff --git a/apps/cli/cli/src/commands/chat/logic.rs b/apps/cli-deprecated/cli/src/commands/chat/logic.rs similarity index 100% rename from apps/cli/cli/src/commands/chat/logic.rs rename to apps/cli-deprecated/cli/src/commands/chat/logic.rs diff --git a/apps/cli/cli/src/commands/chat/mod.rs b/apps/cli-deprecated/cli/src/commands/chat/mod.rs similarity index 100% rename from apps/cli/cli/src/commands/chat/mod.rs rename to apps/cli-deprecated/cli/src/commands/chat/mod.rs diff --git a/apps/cli/cli/src/commands/chat/state.rs b/apps/cli-deprecated/cli/src/commands/chat/state.rs similarity index 100% rename from apps/cli/cli/src/commands/chat/state.rs rename to apps/cli-deprecated/cli/src/commands/chat/state.rs diff --git a/apps/cli/cli/src/commands/chat/ui.rs b/apps/cli-deprecated/cli/src/commands/chat/ui.rs similarity index 100% rename from apps/cli/cli/src/commands/chat/ui.rs rename to apps/cli-deprecated/cli/src/commands/chat/ui.rs diff --git a/apps/cli/cli/src/commands/config.rs b/apps/cli-deprecated/cli/src/commands/config.rs similarity index 100% rename from apps/cli/cli/src/commands/config.rs rename to apps/cli-deprecated/cli/src/commands/config.rs diff --git a/apps/cli/cli/src/commands/config_utils.rs b/apps/cli-deprecated/cli/src/commands/config_utils.rs similarity index 100% rename from apps/cli/cli/src/commands/config_utils.rs rename to apps/cli-deprecated/cli/src/commands/config_utils.rs diff --git a/apps/cli/cli/src/commands/deploy/deploy.rs b/apps/cli-deprecated/cli/src/commands/deploy/deploy.rs similarity index 100% rename from apps/cli/cli/src/commands/deploy/deploy.rs rename to apps/cli-deprecated/cli/src/commands/deploy/deploy.rs diff --git a/apps/cli/cli/src/commands/deploy/integration_tests.rs b/apps/cli-deprecated/cli/src/commands/deploy/integration_tests.rs similarity index 100% rename from apps/cli/cli/src/commands/deploy/integration_tests.rs rename to apps/cli-deprecated/cli/src/commands/deploy/integration_tests.rs diff --git a/apps/cli/cli/src/commands/deploy/mod.rs b/apps/cli-deprecated/cli/src/commands/deploy/mod.rs similarity index 100% rename from apps/cli/cli/src/commands/deploy/mod.rs rename to apps/cli-deprecated/cli/src/commands/deploy/mod.rs diff --git a/apps/cli/cli/src/commands/generate.rs b/apps/cli-deprecated/cli/src/commands/generate.rs similarity index 100% rename from apps/cli/cli/src/commands/generate.rs rename to apps/cli-deprecated/cli/src/commands/generate.rs diff --git a/apps/cli/cli/src/commands/init.rs b/apps/cli-deprecated/cli/src/commands/init.rs similarity index 100% rename from apps/cli/cli/src/commands/init.rs rename to apps/cli-deprecated/cli/src/commands/init.rs diff --git a/apps/cli/cli/src/commands/mod.rs b/apps/cli-deprecated/cli/src/commands/mod.rs similarity index 100% rename from apps/cli/cli/src/commands/mod.rs rename to apps/cli-deprecated/cli/src/commands/mod.rs diff --git a/apps/cli/cli/src/commands/parse.rs b/apps/cli-deprecated/cli/src/commands/parse.rs similarity index 100% rename from apps/cli/cli/src/commands/parse.rs rename to apps/cli-deprecated/cli/src/commands/parse.rs diff --git a/apps/cli/cli/src/commands/run.rs b/apps/cli-deprecated/cli/src/commands/run.rs similarity index 100% rename from apps/cli/cli/src/commands/run.rs rename to apps/cli-deprecated/cli/src/commands/run.rs diff --git a/apps/cli/cli/src/commands/update.rs b/apps/cli-deprecated/cli/src/commands/update.rs similarity index 100% rename from apps/cli/cli/src/commands/update.rs rename to apps/cli-deprecated/cli/src/commands/update.rs diff --git a/apps/cli/cli/src/error.rs b/apps/cli-deprecated/cli/src/error.rs similarity index 100% rename from apps/cli/cli/src/error.rs rename to apps/cli-deprecated/cli/src/error.rs diff --git a/apps/cli/cli/src/lib.rs b/apps/cli-deprecated/cli/src/lib.rs similarity index 100% rename from apps/cli/cli/src/lib.rs rename to apps/cli-deprecated/cli/src/lib.rs diff --git a/apps/cli/cli/src/main.rs b/apps/cli-deprecated/cli/src/main.rs similarity index 100% rename from apps/cli/cli/src/main.rs rename to apps/cli-deprecated/cli/src/main.rs diff --git a/apps/cli/cli/src/types/mod.rs b/apps/cli-deprecated/cli/src/types/mod.rs similarity index 100% rename from apps/cli/cli/src/types/mod.rs rename to apps/cli-deprecated/cli/src/types/mod.rs diff --git a/apps/cli/cli/src/utils/buster/api.rs b/apps/cli-deprecated/cli/src/utils/buster/api.rs similarity index 100% rename from apps/cli/cli/src/utils/buster/api.rs rename to apps/cli-deprecated/cli/src/utils/buster/api.rs diff --git a/apps/cli/cli/src/utils/buster/mod.rs b/apps/cli-deprecated/cli/src/utils/buster/mod.rs similarity index 100% rename from apps/cli/cli/src/utils/buster/mod.rs rename to apps/cli-deprecated/cli/src/utils/buster/mod.rs diff --git a/apps/cli/cli/src/utils/buster/types.rs b/apps/cli-deprecated/cli/src/utils/buster/types.rs similarity index 100% rename from apps/cli/cli/src/utils/buster/types.rs rename to apps/cli-deprecated/cli/src/utils/buster/types.rs diff --git a/apps/cli/cli/src/utils/config.rs b/apps/cli-deprecated/cli/src/utils/config.rs similarity index 100% rename from apps/cli/cli/src/utils/config.rs rename to apps/cli-deprecated/cli/src/utils/config.rs diff --git a/apps/cli/cli/src/utils/dbt/command.rs b/apps/cli-deprecated/cli/src/utils/dbt/command.rs similarity index 100% rename from apps/cli/cli/src/utils/dbt/command.rs rename to apps/cli-deprecated/cli/src/utils/dbt/command.rs diff --git a/apps/cli/cli/src/utils/dbt/mod.rs b/apps/cli-deprecated/cli/src/utils/dbt/mod.rs similarity index 100% rename from apps/cli/cli/src/utils/dbt/mod.rs rename to apps/cli-deprecated/cli/src/utils/dbt/mod.rs diff --git a/apps/cli/cli/src/utils/exclusion.rs b/apps/cli-deprecated/cli/src/utils/exclusion.rs similarity index 100% rename from apps/cli/cli/src/utils/exclusion.rs rename to apps/cli-deprecated/cli/src/utils/exclusion.rs diff --git a/apps/cli/cli/src/utils/file/buster_credentials.rs b/apps/cli-deprecated/cli/src/utils/file/buster_credentials.rs similarity index 100% rename from apps/cli/cli/src/utils/file/buster_credentials.rs rename to apps/cli-deprecated/cli/src/utils/file/buster_credentials.rs diff --git a/apps/cli/cli/src/utils/file/mod.rs b/apps/cli-deprecated/cli/src/utils/file/mod.rs similarity index 100% rename from apps/cli/cli/src/utils/file/mod.rs rename to apps/cli-deprecated/cli/src/utils/file/mod.rs diff --git a/apps/cli/cli/src/utils/file/model_files.rs b/apps/cli-deprecated/cli/src/utils/file/model_files.rs similarity index 100% rename from apps/cli/cli/src/utils/file/model_files.rs rename to apps/cli-deprecated/cli/src/utils/file/model_files.rs diff --git a/apps/cli/cli/src/utils/file/profiles.rs b/apps/cli-deprecated/cli/src/utils/file/profiles.rs similarity index 100% rename from apps/cli/cli/src/utils/file/profiles.rs rename to apps/cli-deprecated/cli/src/utils/file/profiles.rs diff --git a/apps/cli/cli/src/utils/file/project_files.rs b/apps/cli-deprecated/cli/src/utils/file/project_files.rs similarity index 100% rename from apps/cli/cli/src/utils/file/project_files.rs rename to apps/cli-deprecated/cli/src/utils/file/project_files.rs diff --git a/apps/cli/cli/src/utils/formatting/mod.rs b/apps/cli-deprecated/cli/src/utils/formatting/mod.rs similarity index 100% rename from apps/cli/cli/src/utils/formatting/mod.rs rename to apps/cli-deprecated/cli/src/utils/formatting/mod.rs diff --git a/apps/cli/cli/src/utils/formatting/text.rs b/apps/cli-deprecated/cli/src/utils/formatting/text.rs similarity index 100% rename from apps/cli/cli/src/utils/formatting/text.rs rename to apps/cli-deprecated/cli/src/utils/formatting/text.rs diff --git a/apps/cli/cli/src/utils/fs_utils.rs b/apps/cli-deprecated/cli/src/utils/fs_utils.rs similarity index 100% rename from apps/cli/cli/src/utils/fs_utils.rs rename to apps/cli-deprecated/cli/src/utils/fs_utils.rs diff --git a/apps/cli/cli/src/utils/mod.rs b/apps/cli-deprecated/cli/src/utils/mod.rs similarity index 100% rename from apps/cli/cli/src/utils/mod.rs rename to apps/cli-deprecated/cli/src/utils/mod.rs diff --git a/apps/cli/cli/src/utils/progress.rs b/apps/cli-deprecated/cli/src/utils/progress.rs similarity index 100% rename from apps/cli/cli/src/utils/progress.rs rename to apps/cli-deprecated/cli/src/utils/progress.rs diff --git a/apps/cli/cli/src/utils/updater.rs b/apps/cli-deprecated/cli/src/utils/updater.rs similarity index 100% rename from apps/cli/cli/src/utils/updater.rs rename to apps/cli-deprecated/cli/src/utils/updater.rs diff --git a/apps/cli/cli/src/utils/version.rs b/apps/cli-deprecated/cli/src/utils/version.rs similarity index 100% rename from apps/cli/cli/src/utils/version.rs rename to apps/cli-deprecated/cli/src/utils/version.rs diff --git a/apps/cli/cli/src/utils/yaml_diff_merger.rs b/apps/cli-deprecated/cli/src/utils/yaml_diff_merger.rs similarity index 100% rename from apps/cli/cli/src/utils/yaml_diff_merger.rs rename to apps/cli-deprecated/cli/src/utils/yaml_diff_merger.rs diff --git a/apps/cli/libs/dbt_utils/Cargo.toml b/apps/cli-deprecated/libs/dbt_utils/Cargo.toml similarity index 100% rename from apps/cli/libs/dbt_utils/Cargo.toml rename to apps/cli-deprecated/libs/dbt_utils/Cargo.toml diff --git a/apps/cli/libs/dbt_utils/src/lib.rs b/apps/cli-deprecated/libs/dbt_utils/src/lib.rs similarity index 100% rename from apps/cli/libs/dbt_utils/src/lib.rs rename to apps/cli-deprecated/libs/dbt_utils/src/lib.rs diff --git a/apps/cli/libs/dbt_utils/src/models.rs b/apps/cli-deprecated/libs/dbt_utils/src/models.rs similarity index 100% rename from apps/cli/libs/dbt_utils/src/models.rs rename to apps/cli-deprecated/libs/dbt_utils/src/models.rs diff --git a/apps/cli/src/commands/chat/CLAUDE.md b/apps/cli-deprecated/src/commands/chat/CLAUDE.md similarity index 100% rename from apps/cli/src/commands/chat/CLAUDE.md rename to apps/cli-deprecated/src/commands/chat/CLAUDE.md diff --git a/apps/cli/tests/command_tests.rs b/apps/cli-deprecated/tests/command_tests.rs similarity index 100% rename from apps/cli/tests/command_tests.rs rename to apps/cli-deprecated/tests/command_tests.rs diff --git a/apps/cli/tests/env_vars_test.rs b/apps/cli-deprecated/tests/env_vars_test.rs similarity index 100% rename from apps/cli/tests/env_vars_test.rs rename to apps/cli-deprecated/tests/env_vars_test.rs diff --git a/apps/cli/tests/exclusion_test.rs b/apps/cli-deprecated/tests/exclusion_test.rs similarity index 100% rename from apps/cli/tests/exclusion_test.rs rename to apps/cli-deprecated/tests/exclusion_test.rs diff --git a/apps/cli/tests/project_config_test.rs b/apps/cli-deprecated/tests/project_config_test.rs similarity index 100% rename from apps/cli/tests/project_config_test.rs rename to apps/cli-deprecated/tests/project_config_test.rs diff --git a/apps/cli/tests/test_excluded_tags.sql b/apps/cli-deprecated/tests/test_excluded_tags.sql similarity index 100% rename from apps/cli/tests/test_excluded_tags.sql rename to apps/cli-deprecated/tests/test_excluded_tags.sql diff --git a/apps/cli/CLAUDE.md b/apps/cli/CLAUDE.md index efb985308..3805d6a32 100644 --- a/apps/cli/CLAUDE.md +++ b/apps/cli/CLAUDE.md @@ -1,34 +1,485 @@ -# CLAUDE.md +# Buster CLI Development Guidelines -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +This document provides specific guidelines for developing the TypeScript-based Buster CLI in this monorepo. -## Build Commands -- Build: `cargo build` -- Release build: `cargo build --release` -- Run tests: `cargo test` -- Run specific test: `cargo test test_name` -- Run tests in file: `cargo test --test filename` -- Run package tests: `cargo test -p ` -- Format: `cargo fmt` -- Lint: `cargo clippy` +## Architecture Overview -## Code Style Guidelines -- **Imports**: Group by std, external crates, internal modules; alphabetical order -- **Formatting**: 4-space indentation (standard Rust) -- **Error Handling**: Use `thiserror` for error types, `anyhow` for general propagation -- **Naming**: Follow Rust conventions (`snake_case` for variables/functions, `PascalCase` for types) -- **Types**: Define custom error types with descriptive messages -- **Dependencies**: Use workspace dependencies with `{ workspace = true }` -- **Testing**: Place in separate `/tests` directory; use `tempfile` for test directories -- **Never log secrets or sensitive data** +The Buster CLI is a **thin client** that serves as a gateway to the Buster server API. It handles: +- File system operations (reading/writing YAML files) +- API communication with the server +- Rich terminal UI using Ink (React for CLI) -## Project Info -- CLI for managing semantic models in Buster -- Uses semantic versioning (PR title conventions for bumps) - - Major: PR title with "BREAKING CHANGE" or "major", or PR with "major" label - - Minor: PR title with "feat", "feature", or "minor", or PR with "minor" label - - Patch: Default for all other PRs -- Cross-project references supported -- Config defined in `buster.yml` -- File and tag exclusions for deployment -- Row limit of 5000 is enforced for database queries by default \ No newline at end of file +**Important**: The CLI does NOT directly access databases or AI services. All business logic is handled by the server. + +## Directory Structure + +``` +apps/cli/ +├── src/ +│ ├── commands/ # Command implementations +│ │ ├── auth/ # Each command in its own folder +│ │ │ ├── index.ts # Command definition and setup +│ │ │ ├── types.ts # Command-specific types (Zod schemas) +│ │ │ ├── helpers.ts # Command utilities +│ │ │ └── auth.test.ts +│ │ ├── init/ +│ │ ├── deploy/ +│ │ └── ... +│ ├── components/ # Reusable Ink UI components +│ │ ├── forms/ # Form components +│ │ ├── tables/ # Table display components +│ │ ├── progress/ # Progress indicators +│ │ ├── prompts/ # Input prompts +│ │ └── status/ # Status displays +│ ├── utils/ # Shared utilities +│ │ ├── api-client.ts # Server API communication +│ │ ├── config.ts # Configuration management +│ │ ├── errors.ts # Error handling +│ │ └── validation.ts # Zod validation utilities +│ ├── schemas/ # Zod schemas +│ │ ├── commands/ # Command argument schemas +│ │ ├── config/ # Configuration schemas +│ │ ├── models/ # Data model schemas +│ │ └── api/ # API request/response schemas +│ └── main.ts # CLI entry point +├── scripts/ +│ └── validate-env.ts # Environment validation +└── tests/ + ├── unit/ # Unit tests + ├── integration/ # Integration tests + └── utils/ # Test utilities +``` + +## Command Development Pattern + +Each command follows a consistent structure: + +### 1. Command Definition (`index.ts`) + +```typescript +import { Command } from 'commander'; +import { z } from 'zod'; +import React from 'react'; +import { render } from 'ink'; +import { AuthUI } from './components.js'; +import { authHandler } from './handlers.js'; +import { AuthArgsSchema } from './types.js'; + +export const authCommand = new Command('auth') + .description('Authenticate with Buster') + .option('-h, --host ', 'API host URL') + .option('-k, --api-key ', 'API key') + .action(async (options) => { + // Validate arguments + const args = AuthArgsSchema.parse(options); + + // Render Ink UI + const { waitUntilExit } = render( + + ); + + await waitUntilExit(); + }); +``` + +### 2. Type Definitions (`types.ts`) + +```typescript +import { z } from 'zod'; + +// Command arguments schema +export const AuthArgsSchema = z.object({ + host: z.string().url().optional(), + apiKey: z.string().optional(), +}); + +export type AuthArgs = z.infer; + +// Internal types +export const CredentialsSchema = z.object({ + apiKey: z.string(), + apiUrl: z.string().url(), + environment: z.enum(['local', 'cloud']), +}); + +export type Credentials = z.infer; +``` + +### 3. Ink UI Components (`components.tsx`) + +```typescript +import React, { useState } from 'react'; +import { Box, Text } from 'ink'; +import TextInput from 'ink-text-input'; +import SelectInput from 'ink-select-input'; +import Spinner from 'ink-spinner'; + +interface AuthUIProps { + args: AuthArgs; + onComplete: (credentials: Credentials) => Promise; +} + +export const AuthUI: React.FC = ({ args, onComplete }) => { + const [step, setStep] = useState<'input' | 'validating' | 'complete'>('input'); + const [apiKey, setApiKey] = useState(args.apiKey || ''); + + // UI implementation with Ink components + return ( + + {step === 'input' && ( + + Enter your API key: + + + )} + {step === 'validating' && ( + + Validating credentials... + + )} + + ); +}; +``` + +### 4. Command Logic (`helpers.ts`) + +```typescript +import { apiClient } from '../../utils/api-client.js'; +import { configManager } from '../../utils/config.js'; +import type { Credentials } from './types.js'; + +export async function validateCredentials(credentials: Credentials): Promise { + try { + await apiClient.validateAuth(credentials); + return true; + } catch (error) { + return false; + } +} + +export async function saveCredentials(credentials: Credentials): Promise { + await configManager.saveCredentials(credentials); +} +``` + +## Zod-First Type System + +We use Zod schemas for all type definitions and runtime validation: + +### 1. Define Schema First + +```typescript +// Always define the schema first +const UserSchema = z.object({ + id: z.string().uuid(), + email: z.string().email(), + name: z.string(), +}); + +// Then export the type +export type User = z.infer; +``` + +### 2. Validate User Input + +```typescript +// In command actions +.action(async (options) => { + const args = ArgsSchema.parse(options); // Throws if invalid + // args is now fully typed and validated +}); +``` + +### 3. YAML File Validation + +```typescript +import yaml from 'js-yaml'; +import { BusterConfigSchema } from '../schemas/config/buster-config.js'; + +export async function loadBusterConfig(path: string): Promise { + const content = await fs.readFile(path, 'utf-8'); + const parsed = yaml.load(content); + return BusterConfigSchema.parse(parsed); // Validates and types +} +``` + +## API Client Pattern + +All server communication goes through the centralized API client: + +```typescript +// utils/api-client.ts +import type { User } from '@buster/server-shared/users'; +import { z } from 'zod'; + +export class ApiClient { + constructor(private baseUrl: string, private apiKey?: string) {} + + async request({ + method, + path, + body, + responseSchema, + }: { + method: string; + path: string; + body?: unknown; + responseSchema: z.ZodSchema; + }): Promise { + const response = await fetch(`${this.baseUrl}${path}`, { + method, + headers: { + 'Content-Type': 'application/json', + ...(this.apiKey && { Authorization: `Bearer ${this.apiKey}` }), + }, + body: body ? JSON.stringify(body) : undefined, + }); + + if (!response.ok) { + throw new ApiError(response.status, await response.text()); + } + + const data = await response.json(); + return responseSchema.parse(data); + } +} +``` + +## Ink UI Components Guidelines + +### 1. Component Organization + +- Place reusable components in `src/components/` +- Command-specific components stay in the command folder +- Export all components from index files + +### 2. Common Patterns + +```typescript +// Progress indicator + + + {message} + + +// Form with validation + + + {error && ❌ {error}} + + +// Status display + + ✓ Operation successful + +``` + +### 3. State Management + +- Use React hooks for local state +- Pass callbacks for command completion +- Handle errors gracefully with try/catch + +## Testing Strategy + +### 1. Unit Tests + +```typescript +// auth.test.ts +import { describe, it, expect, vi } from 'vitest'; +import { validateCredentials } from './helpers.js'; + +describe('auth helpers', () => { + it('should validate correct credentials', async () => { + const mockApiClient = vi.mocked(apiClient); + mockApiClient.validateAuth.mockResolvedValue(true); + + const result = await validateCredentials({ + apiKey: 'test-key', + apiUrl: 'https://api.buster.com', + }); + + expect(result).toBe(true); + }); +}); +``` + +### 2. Integration Tests + +```typescript +// auth.int.test.ts +import { testCLI } from '../../tests/utils/cli-tester.js'; + +describe('auth command integration', () => { + it('should authenticate with valid credentials', async () => { + const result = await testCLI(['auth', '--api-key', 'test-key']); + expect(result.exitCode).toBe(0); + expect(result.stdout).toContain('Successfully authenticated'); + }); +}); +``` + +### 3. Ink Component Tests + +```typescript +import { render } from 'ink-testing-library'; +import { AuthUI } from './components.js'; + +it('should render auth form', () => { + const { lastFrame } = render(); + expect(lastFrame()).toContain('Enter your API key:'); +}); +``` + +## Error Handling + +### 1. Custom Error Classes + +```typescript +export class CLIError extends Error { + constructor(message: string, public code: string) { + super(message); + this.name = 'CLIError'; + } +} + +export class ApiError extends CLIError { + constructor(public status: number, message: string) { + super(message, 'API_ERROR'); + } +} + +export class ValidationError extends CLIError { + constructor(message: string) { + super(message, 'VALIDATION_ERROR'); + } +} +``` + +### 2. Error Display in Ink + +```typescript +interface ErrorDisplayProps { + error: Error; +} + +export const ErrorDisplay: React.FC = ({ error }) => ( + + + ❌ {error.message} + {error instanceof CLIError && ( + (Code: {error.code}) + )} + + +); +``` + +## Configuration Management + +### 1. File Locations + +- Global config: `~/.buster/config.yml` +- Project config: `./buster.yml` +- Credentials: `~/.buster/credentials` (encrypted) + +### 2. Schema Validation + +```typescript +export const BusterConfigSchema = z.object({ + version: z.string(), + projectName: z.string(), + organization: z.string().optional(), + settings: z.object({ + autoUpdate: z.boolean().default(true), + telemetry: z.boolean().default(true), + }).optional(), +}); +``` + +## Best Practices + +1. **Keep Commands Simple**: Commands should only handle argument parsing and UI rendering +2. **Delegate to Handlers**: Business logic goes in handler functions +3. **Use Zod Everywhere**: All user input and file parsing should use Zod validation +4. **Server-First**: All operations should go through the server API +5. **Rich UI Feedback**: Use Ink components to provide clear, beautiful feedback +6. **Handle Errors Gracefully**: Show helpful error messages with recovery suggestions +7. **Test Everything**: Unit test logic, integration test commands, component test UI + +## Common Patterns + +### Loading Configuration + +```typescript +export async function loadProjectConfig(): Promise { + try { + const configPath = path.join(process.cwd(), 'buster.yml'); + const content = await fs.readFile(configPath, 'utf-8'); + const parsed = yaml.load(content); + return BusterConfigSchema.parse(parsed); + } catch (error) { + if (error.code === 'ENOENT') { + return null; // No config file + } + throw new ValidationError('Invalid buster.yml configuration'); + } +} +``` + +### API Request with Progress + +```typescript +const { unmount } = render( + +); + +try { + const result = await apiClient.deployModels(models); + unmount(); + + render(); +} catch (error) { + unmount(); + render(); +} +``` + +### Multi-Step Operations + +```typescript +export const InitUI: React.FC = () => { + const [step, setStep] = useState(0); + const steps = ['Create folders', 'Generate config', 'Validate setup']; + + return ( + + + {/* Step-specific UI */} + + ); +}; +``` + +## Environment Variables + +- `BUSTER_API_URL`: Base URL for the Buster API +- `BUSTER_API_KEY`: API authentication key +- `BUSTER_CONFIG_DIR`: Override config directory location +- `BUSTER_CACHE_DIR`: Override cache directory location +- `BUSTER_AUTO_UPDATE`: Enable/disable auto-updates +- `BUSTER_TELEMETRY_DISABLED`: Disable telemetry + +## Distribution + +The CLI is distributed as: +1. npm package: `npm install -g @buster/cli` +2. Homebrew: `brew install buster-cli` +3. Direct binary: Download from GitHub releases + +Binaries are compiled using Bun's compile feature for all major platforms. \ No newline at end of file diff --git a/apps/cli/README.md b/apps/cli/README.md index f3ea1ffaf..dffa46204 100644 --- a/apps/cli/README.md +++ b/apps/cli/README.md @@ -1,370 +1,69 @@ # Buster CLI -A powerful command-line interface for managing semantic models in Buster. Deploy and manage your data models with ease, whether they're standalone or part of a dbt project. +The official command-line interface for Buster, built with TypeScript, Commander.js, and Ink for a beautiful terminal experience. -## Installation +## Architecture -Choose the installation command for your operating system: +This CLI is designed as a thin client that communicates with the Buster server API. It handles: +- File system operations (reading/writing YAML files) +- API communication +- Rich terminal UI using Ink (React for CLI) -### macOS (x86_64) -```bash -mkdir -p ~/.local/bin && curl -L https://github.com/buster-so/buster/releases/latest/download/buster-cli-darwin-x86_64.tar.gz | tar xz && mv buster-cli ~/.local/bin/buster && chmod +x ~/.local/bin/buster -``` +## Development -### macOS (ARM/Apple Silicon) -```bash -mkdir -p ~/.local/bin && curl -L https://github.com/buster-so/buster/releases/latest/download/buster-cli-darwin-arm64.tar.gz | tar xz && mv buster-cli ~/.local/bin/buster && chmod +x ~/.local/bin/buster -``` - -### Linux (x86_64) -```bash -mkdir -p ~/.local/bin && curl -L https://github.com/buster-so/buster/releases/latest/download/buster-cli-linux-x86_64.tar.gz | tar xz && mv buster-cli ~/.local/bin/buster && chmod +x ~/.local/bin/buster -``` - -> **Note**: After installation, make sure `~/.local/bin` is in your PATH. Add this to your shell's config file (`.bashrc`, `.zshrc`, etc.): -> ```bash -> export PATH="$HOME/.local/bin:$PATH" -> ``` - -### Windows (x86_64) -1. Download the Windows binary: -```powershell -Invoke-WebRequest -Uri https://github.com/buster-so/buster/releases/latest/download/buster-cli-windows-x86_64.zip -OutFile buster.zip -``` - -2. Extract and install: -```powershell -Expand-Archive -Path buster.zip -DestinationPath $env:USERPROFILE\buster -Move-Item -Path $env:USERPROFILE\buster\buster-cli.exe -Destination $env:LOCALAPPDATA\Microsoft\WindowsApps\buster.exe -``` - -## Quick Start Guide - -### 1. Authentication - -First, authenticate with Buster using your API key: +### Setup ```bash -buster auth +# Install dependencies +pnpm install + +# Run in development mode +pnpm dev + +# Build the CLI +pnpm build + +# Run tests +pnpm test ``` -This will prompt you for: -- API Key (required) - Get this from the Buster Platform -- Host (optional) - Defaults to production if not specified +### Commands -You can also configure authentication using environment variables: -```bash -# Set API key via environment variable -export BUSTER_API_KEY=your_api_key_here +- `auth` - Authenticate with Buster +- `init` - Initialize a new Buster project +- `deploy` - Deploy models to Buster +- `parse` - Parse and validate YAML model files +- `config` - Manage Buster configuration +- `update` - Update CLI to the latest version +- `start` - Start Buster services +- `stop` - Stop Buster services +- `reset` - Reset Buster services and data -# Optional: Set custom host. For self-hosted instances. -export BUSTER_HOST=your_custom_host -``` - -The CLI will check for these environment variables in the following order: -1. Command line arguments -2. Environment variables -3. Interactive prompt - -This is particularly useful for: -- CI/CD environments -- Automated scripts -- Development workflows where you don't want to enter credentials repeatedly - -### 2. Generate Models - -Generate Buster YAML models from your existing SQL files: +### Testing ```bash -buster generate +# Run all tests +pnpm test + +# Run unit tests only +pnpm test:unit + +# Run integration tests +pnpm test:integration + +# Watch mode +pnpm test:watch ``` -Key flags for generation: -- `--source-path`: Directory containing your SQL files (defaults to current directory) -- `--destination-path`: Where to output the generated YAML files (defaults to current directory) -- `--data-source-name`: Name of the data source to use in the models -- `--schema`: Database schema name -- `--database`: Database name -- `--flat-structure`: Output YML files in a flat structure instead of maintaining directory hierarchy - -The generate command will: -- Scan the source directory for SQL files -- Create corresponding YAML model files -- Create a `buster.yml` configuration file if it doesn't exist -- Preserve any existing model customizations - -Example with all options: -```bash -buster generate \ - --source-path ./sql \ - --destination-path ./models \ - --data-source-name my_warehouse \ - --schema analytics \ - --database prod -``` - -### 3. Deploy Models - -Deploy your models to Buster: +### Building Binaries ```bash -buster deploy +# Build binaries for all platforms +pnpm build:binary ``` -Deploy options: -- `--path`: Specific path to deploy (defaults to current directory) -- `--dry-run`: Validate the deployment without actually deploying (defaults to false) -- `--recursive`: Recursively search for model files in subdirectories (defaults to true) +This creates standalone executables for Linux, macOS, and Windows using Bun's compile feature. -Examples: -```bash -# Deploy all models in current directory -buster deploy +## Contributing -# Deploy a specific model or directory -buster deploy --path ./models/customers.yml - -# Validate deployment without applying changes -buster deploy --dry-run - -# Deploy only models in the specified directory (not recursively) -buster deploy --path ./models --recursive=false -``` - -The deploy command will: -1. Discover all YAML model files in the specified path -2. Load and validate the models -3. Check for excluded models based on tags -4. Validate cross-project references -5. Deploy the models to Buster -6. Provide detailed validation feedback and error messages - -## Project Structure - -A typical Buster project structure: - -``` -your-project/ -├── buster.yml # Global configuration -├── models/ # Your semantic model definitions -│ ├── customers.yml -│ ├── orders.yml -│ └── products.yml -└── sql/ # SQL definitions - ├── customers.sql - ├── orders.sql - └── products.sql -``` - -### Configuration (buster.yml) - -```yaml -# buster.yml -data_source_name: "my_warehouse" # Your default data source -schema: "analytics" # Default schema for models -database: "prod" # Optional database name -exclude_files: # Optional list of files to exclude from generation - - "temp_*.sql" # Exclude all SQL files starting with temp_ - - "test/**/*.sql" # Exclude all SQL files in test directories - - "customers.sql" # Exclude a specific file -exclude_tags: # Optional list of tags to exclude from deployment - - "staging" # Exclude models with the 'staging' tag - - "test" # Exclude models with the 'test' tag -``` - -The configuration supports the following fields: -- `data_source_name`: (Required) Default data source for your models -- `schema`: (Required) Default schema for your models -- `database`: (Optional) Default database name -- `exclude_files`: (Optional) List of glob patterns for files to exclude from generation - - Supports standard glob patterns (*, **, ?, etc.) - - Matches against relative paths from source directory - - Common use cases: - - Excluding temporary files: `temp_*.sql` - - Excluding test files: `test/**/*.sql` - - Excluding specific files: `customers.sql` - - Excluding files in directories: `archive/**/*.sql` -- `exclude_tags`: (Optional) List of tags to exclude from deployment - - Looks for tags in SQL files in dbt format: `{{ config(tags=['tag1', 'tag2']) }}` - - Useful for excluding staging models, test models, etc. - - Case-insensitive matching - -### Model Definition Example - -```yaml -# models/customers.yml -version: 1 -models: - - name: customers - description: "Core customer data model" - data_source_name: "my_warehouse" # Overrides buster.yml - schema: "analytics" # Overrides buster.yml - database: "prod" # Overrides buster.yml - - entities: - - name: customer_id - expr: "id" - type: "primary" - description: "Primary customer identifier" - - name: order - expr: "order_id" - type: "foreign" - description: "Reference to order model" - # Optional: reference to another model in a different project - project_path: "path/to/other/project" - # Optional: specify a different name for the referenced model - ref: "orders" - - dimensions: - - name: email - expr: "email" - type: "string" - description: "Customer email address" - searchable: true # Optional: make this dimension searchable - - measures: - - name: total_customers - expr: "customer_id" - agg: "count_distinct" - description: "Total number of unique customers" - type: "integer" # Optional: specify the data type -``` - -## Cross-Project References - -Buster CLI supports referencing models across different projects, enabling you to build complex data relationships: - -```yaml -entities: - - name: user_model - expr: "user_id" - type: "foreign" - description: "Reference to user model in another project" - project_path: "path/to/user/project" - ref: "users" # Optional: specify a different name for the referenced model -``` - -When using cross-project references, the CLI will: -1. Validate that the referenced project exists -2. Check for a valid buster.yml in the referenced project -3. Verify that the data sources match between projects -4. Confirm that the referenced model exists in the target project - -This enables you to organize your models into logical projects while maintaining relationships between them. - -## Tag-Based Exclusion - -You can exclude models from deployment based on tags in your SQL files. This is useful for excluding staging models, test models, or any other models you don't want to deploy. - -In your SQL files, add tags using the dbt format: - -```sql -{{ config( - tags=['staging', 'test'] -) }} - -SELECT * FROM source_table -``` - -Then in your buster.yml, specify which tags to exclude: - -```yaml -exclude_tags: - - "staging" - - "test" -``` - -During deployment, any model with matching tags will be automatically excluded. - -## File and Tag Exclusions - -Buster CLI provides a unified way to exclude files from processing across all commands. You can specify exclusions in your `buster.yml` file: - -```yaml -data_source_name: "my_data_source" -schema: "my_schema" -database: "my_database" -exclude_files: - - "**/*_temp.sql" - - "staging/**/*.sql" - - "tests/**/*.yml" -exclude_tags: - - "test" - - "deprecated" - - "wip" -``` - -### Exclude Files - -The `exclude_files` section allows you to specify glob patterns for files that should be excluded from processing. This works for any command that processes files. - -Common patterns: -- `"**/*_temp.sql"` - Exclude any SQL file ending with _temp.sql in any directory -- `"staging/**/*.sql"` - Exclude all SQL files in the staging directory and its subdirectories -- `"test_*.yml"` - Exclude all YAML files starting with test_ - -### Exclude Tags - -The `exclude_tags` section allows you to exclude files based on tags specified in the file content. This is useful for excluding files that are marked as test, deprecated, etc. - -Tags are specified in the SQL files using the format: `-- tags = ['tag1', 'tag2']` - -When a file contains any of the excluded tags, it will be skipped by all commands. - -## Best Practices - -1. **Organization** - - Keep YAML files in `models/` - - Keep SQL files in `sql/` - - Use `buster.yml` for shared settings - - Group related models into subdirectories - -2. **Model Generation** - - Start with clean SQL files - - Generate models first before customizing - - Review generated models before deployment - - Use tags to organize and filter models - -3. **Deployment** - - Use `--dry-run` to validate changes - - Deploy frequently to catch issues early - - Keep model and SQL files in sync - - Use cross-project references for complex relationships - -4. **Validation** - - Ensure all models have descriptions - - Validate cross-project references before deployment - - Check for missing dependencies - - Review validation errors carefully - -## Troubleshooting - -Common issues and solutions: - -1. **Authentication Issues** - - Verify your API key is correct - - Check if the host is properly specified (if using non-production) - - Ensure network connectivity to Buster - -2. **Generation Issues** - - Verify SQL files are in the correct location - - Check file permissions - - Ensure SQL syntax is valid - - Check for excluded files or tags - -3. **Deployment Issues** - - Validate YAML syntax - - Check for missing dependencies - - Verify data source connectivity - - Look for cross-project reference errors - - Check for tag-based exclusions - -4. **Cross-Project Reference Issues** - - Ensure the referenced project exists - - Verify the referenced project has a valid buster.yml - - Check that data sources match between projects - - Confirm the referenced model exists in the target project - -## License - -MIT License - see [LICENSE](LICENSE) for details. +See [CLAUDE.md](./CLAUDE.md) for detailed development guidelines. \ No newline at end of file diff --git a/apps/cli/biome.json b/apps/cli/biome.json new file mode 100644 index 000000000..00182d785 --- /dev/null +++ b/apps/cli/biome.json @@ -0,0 +1,3 @@ +{ + "extends": ["../../biome.json"] +} \ No newline at end of file diff --git a/apps/cli/env.d.ts b/apps/cli/env.d.ts new file mode 100644 index 000000000..8a2f2f4c9 --- /dev/null +++ b/apps/cli/env.d.ts @@ -0,0 +1,18 @@ +/// + +declare namespace NodeJS { + interface ProcessEnv { + // API Configuration + BUSTER_API_URL: string; + BUSTER_API_KEY?: string; + + + // CLI Configuration + BUSTER_CONFIG_DIR?: string; + BUSTER_CACHE_DIR?: string; + + // Feature Flags + BUSTER_AUTO_UPDATE?: string; + BUSTER_TELEMETRY_DISABLED?: string; + } +} \ No newline at end of file diff --git a/apps/cli/package.json b/apps/cli/package.json new file mode 100644 index 000000000..9a73a431e --- /dev/null +++ b/apps/cli/package.json @@ -0,0 +1,51 @@ +{ + "name": "@buster-app/cli", + "version": "0.0.1", + "type": "module", + "exports": { + ".": { + "types": "./src/main.ts" + } + }, + "bin": { + "buster": "./dist/main.js" + }, + "scripts": { + "prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || (tsx scripts/validate-env.ts && pnpm run typecheck)", + "build": "tsup", + "build:dry-run": "tsup", + "build:binary": "bun build --compile --target=bun-linux-x64 --target=bun-darwin-x64 --target=bun-windows-x64 --outfile buster ./src/main.ts", + "dev": "tsx --watch src/main.ts", + "lint": "biome check --write", + "test": "vitest run", + "test:unit": "vitest run --exclude '**/*.int.test.ts' --exclude '**/*.integration.test.ts'", + "test:integration": "vitest run **/*.int.test.ts **/*.integration.test.ts", + "test:coverage": "vitest --coverage", + "test:watch": "vitest --watch", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@buster/server-shared": "workspace:*", + "commander": "^14.0.0", + "ink": "^6.0.1", + "react": "^19.0.0", + "ink-text-input": "^6.0.0", + "ink-select-input": "^6.0.0", + "ink-table": "^3.1.0", + "ink-spinner": "^5.0.0", + "ink-confirm-input": "^2.0.0", + "zod": "catalog:", + "js-yaml": "^4.1.0", + "fast-glob": "^3.3.2", + "chalk": "^5.3.0" + }, + "devDependencies": { + "@buster/typescript-config": "workspace:*", + "@buster/vitest-config": "workspace:*", + "@types/js-yaml": "^4.0.9", + "@types/node": "^24.2.0", + "@types/react": "^19.0.0", + "tsup": "^8.0.0", + "tsx": "^4.7.1" + } +} \ No newline at end of file diff --git a/apps/cli/scripts/validate-env.ts b/apps/cli/scripts/validate-env.ts new file mode 100644 index 000000000..47b4e4351 --- /dev/null +++ b/apps/cli/scripts/validate-env.ts @@ -0,0 +1,27 @@ +import { z } from 'zod'; + +const envSchema = z.object({ + // Required for API communication + BUSTER_API_URL: z.string().url(), + + // Optional environment variables + BUSTER_API_KEY: z.string().optional(), + NODE_ENV: z.enum(['development', 'production', 'test']).default('development'), + BUSTER_CONFIG_DIR: z.string().optional(), + BUSTER_CACHE_DIR: z.string().optional(), + BUSTER_AUTO_UPDATE: z.string().optional(), + BUSTER_TELEMETRY_DISABLED: z.string().optional(), +}); + +try { + envSchema.parse(process.env); + console.log('✅ Environment variables validated successfully'); +} catch (error) { + console.error('❌ Environment validation failed:'); + if (error instanceof z.ZodError) { + error.errors.forEach((err) => { + console.error(` - ${err.path.join('.')}: ${err.message}`); + }); + } + process.exit(1); +} \ No newline at end of file diff --git a/apps/cli/src/commands/auth/components.tsx b/apps/cli/src/commands/auth/components.tsx new file mode 100644 index 000000000..501ad405d --- /dev/null +++ b/apps/cli/src/commands/auth/components.tsx @@ -0,0 +1,88 @@ +import React, { useState } from 'react'; +import { Box, Text } from 'ink'; +import TextInput from 'ink-text-input'; +import SelectInput from 'ink-select-input'; +import Spinner from 'ink-spinner'; +import type { AuthArgs, Credentials } from './types.js'; +import { validateAndSaveCredentials } from './helpers.js'; + +interface AuthUIProps { + args: AuthArgs; +} + +export const AuthUI: React.FC = ({ args }) => { + const [step, setStep] = useState<'input' | 'validating' | 'complete' | 'error'>('input'); + const [apiKey, setApiKey] = useState(args.apiKey || ''); + const [apiUrl, setApiUrl] = useState(args.host || process.env.BUSTER_API_URL || ''); + const [error, setError] = useState(null); + + const handleSubmit = async () => { + setStep('validating'); + + try { + const credentials: Credentials = { + apiKey, + apiUrl, + environment: args.environment, + }; + + await validateAndSaveCredentials(credentials); + setStep('complete'); + } catch (err) { + setError(err instanceof Error ? err.message : 'Authentication failed'); + setStep('error'); + } + }; + + if (step === 'input') { + return ( + + + API URL: + + + + API Key: + + + + ); + } + + if (step === 'validating') { + return ( + + Validating credentials... + + ); + } + + if (step === 'complete') { + return ( + + ✓ Successfully authenticated with Buster! + + ); + } + + if (step === 'error') { + return ( + + ❌ {error} + + ); + } + + return null; +}; \ No newline at end of file diff --git a/apps/cli/src/commands/auth/helpers.ts b/apps/cli/src/commands/auth/helpers.ts new file mode 100644 index 000000000..fd94034ac --- /dev/null +++ b/apps/cli/src/commands/auth/helpers.ts @@ -0,0 +1,20 @@ +import type { Credentials } from './types.js'; +// TODO: Import from lib when created +// import { apiClient } from '../../utils/api-client.js'; +// import { configManager } from '../../utils/config.js'; + +export async function validateAndSaveCredentials(credentials: Credentials): Promise { + // TODO: Implement actual validation via API + // const isValid = await apiClient.validateAuth(credentials); + + // Mock validation for now + if (!credentials.apiKey || credentials.apiKey.length < 10) { + throw new Error('Invalid API key'); + } + + // TODO: Save credentials + // await configManager.saveCredentials(credentials); + + // Mock success + await new Promise(resolve => setTimeout(resolve, 1000)); +} \ No newline at end of file diff --git a/apps/cli/src/commands/auth/index.ts b/apps/cli/src/commands/auth/index.ts new file mode 100644 index 000000000..291bfd7bd --- /dev/null +++ b/apps/cli/src/commands/auth/index.ts @@ -0,0 +1,20 @@ +import { Command } from 'commander'; +import React from 'react'; +import { render } from 'ink'; +import { AuthUI } from './components.js'; +import { AuthArgsSchema } from './types.js'; + +export const authCommand = new Command('auth') + .description('Authenticate with Buster') + .option('-h, --host ', 'API host URL') + .option('-k, --api-key ', 'API key') + .option('-e, --environment ', 'Environment (local/cloud)', 'cloud') + .action(async (options) => { + // Validate arguments + const args = AuthArgsSchema.parse(options); + + // Render Ink UI + const { waitUntilExit } = render(); + + await waitUntilExit(); + }); \ No newline at end of file diff --git a/apps/cli/src/commands/auth/types.ts b/apps/cli/src/commands/auth/types.ts new file mode 100644 index 000000000..76b76c4a6 --- /dev/null +++ b/apps/cli/src/commands/auth/types.ts @@ -0,0 +1,19 @@ +import { z } from 'zod'; + +// Command arguments schema +export const AuthArgsSchema = z.object({ + host: z.string().url().optional(), + apiKey: z.string().optional(), + environment: z.enum(['local', 'cloud']).default('cloud'), +}); + +export type AuthArgs = z.infer; + +// Credentials schema +export const CredentialsSchema = z.object({ + apiKey: z.string(), + apiUrl: z.string().url(), + environment: z.enum(['local', 'cloud']), +}); + +export type Credentials = z.infer; \ No newline at end of file diff --git a/apps/cli/src/commands/config/index.ts b/apps/cli/src/commands/config/index.ts new file mode 100644 index 000000000..3e7faa06e --- /dev/null +++ b/apps/cli/src/commands/config/index.ts @@ -0,0 +1,21 @@ +import { Command } from 'commander'; +import React from 'react'; +import { render } from 'ink'; +import { ConfigUI } from './components.js'; +import { ConfigArgsSchema } from './types.js'; + +export const configCommand = new Command('config') + .description('Manage Buster configuration') + .option('-s, --set ', 'Set a configuration value') + .option('-g, --get ', 'Get a configuration value') + .option('-l, --list', 'List all configuration values') + .option('--reset', 'Reset configuration to defaults') + .action(async (options) => { + // Validate arguments + const args = ConfigArgsSchema.parse(options); + + // Render Ink UI + const { waitUntilExit } = render(); + + await waitUntilExit(); + }); \ No newline at end of file diff --git a/apps/cli/src/commands/deploy/components.tsx b/apps/cli/src/commands/deploy/components.tsx new file mode 100644 index 000000000..c48202d5d --- /dev/null +++ b/apps/cli/src/commands/deploy/components.tsx @@ -0,0 +1,42 @@ +import React, { useState, useEffect } from 'react'; +import { Box, Text } from 'ink'; +import Spinner from 'ink-spinner'; +import type { DeployArgs } from './types.js'; + +interface DeployUIProps { + args: DeployArgs; +} + +export const DeployUI: React.FC = ({ args }) => { + const [status, setStatus] = useState<'validating' | 'deploying' | 'complete' | 'error'>('validating'); + const [message, setMessage] = useState('Validating models...'); + + useEffect(() => { + // Simulate deployment process + const timer = setTimeout(() => { + if (args.dryRun) { + setMessage('Dry run completed successfully'); + setStatus('complete'); + } else { + setMessage('Models deployed successfully'); + setStatus('complete'); + } + }, 2000); + + return () => clearTimeout(timer); + }, [args.dryRun]); + + if (status === 'complete') { + return ( + + ✓ {message} + + ); + } + + return ( + + {message} + + ); +}; \ No newline at end of file diff --git a/apps/cli/src/commands/deploy/index.ts b/apps/cli/src/commands/deploy/index.ts new file mode 100644 index 000000000..c271be1a3 --- /dev/null +++ b/apps/cli/src/commands/deploy/index.ts @@ -0,0 +1,19 @@ +import { Command } from 'commander'; +import React from 'react'; +import { render } from 'ink'; +import { DeployUI } from './components.js'; +import { DeployArgsSchema } from './types.js'; + +export const deployCommand = new Command('deploy') + .description('Deploy models to Buster') + .option('-d, --dry-run', 'Perform a dry run without deploying') + .option('-p, --path ', 'Path to models directory', './buster') + .action(async (options) => { + // Validate arguments + const args = DeployArgsSchema.parse(options); + + // Render Ink UI + const { waitUntilExit } = render(); + + await waitUntilExit(); + }); \ No newline at end of file diff --git a/apps/cli/src/commands/deploy/types.ts b/apps/cli/src/commands/deploy/types.ts new file mode 100644 index 000000000..e524b8698 --- /dev/null +++ b/apps/cli/src/commands/deploy/types.ts @@ -0,0 +1,17 @@ +import { z } from 'zod'; + +export const DeployArgsSchema = z.object({ + dryRun: z.boolean().default(false), + path: z.string().default('./buster'), +}); + +export type DeployArgs = z.infer; + +export const DeploymentResultSchema = z.object({ + success: z.boolean(), + modelsDeployed: z.number(), + errors: z.array(z.string()).optional(), + warnings: z.array(z.string()).optional(), +}); + +export type DeploymentResult = z.infer; \ No newline at end of file diff --git a/apps/cli/src/commands/init/components.tsx b/apps/cli/src/commands/init/components.tsx new file mode 100644 index 000000000..559b4d9b6 --- /dev/null +++ b/apps/cli/src/commands/init/components.tsx @@ -0,0 +1,103 @@ +import React, { useState } from 'react'; +import { Box, Text } from 'ink'; +import TextInput from 'ink-text-input'; +import Spinner from 'ink-spinner'; +import type { InitArgs } from './types.js'; +import { initializeProject } from './helpers.js'; + +interface InitUIProps { + args: InitArgs; +} + +type Step = 'input' | 'creating' | 'complete' | 'error'; + +export const InitUI: React.FC = ({ args }) => { + const [step, setStep] = useState('input'); + const [projectName, setProjectName] = useState(args.name || ''); + const [error, setError] = useState(null); + + const handleSubmit = async () => { + if (!projectName) return; + + setStep('creating'); + + try { + await initializeProject({ + name: projectName, + path: args.path, + }); + setStep('complete'); + } catch (err) { + setError(err instanceof Error ? err.message : 'Initialization failed'); + setStep('error'); + } + }; + + if (args.skipPrompts && !args.name) { + return ( + + ❌ Project name is required when using --skip-prompts + + ); + } + + if (args.skipPrompts && args.name) { + handleSubmit(); + } + + if (step === 'input' && !args.skipPrompts) { + return ( + + Initialize a new Buster project + + Project name: + + + + ); + } + + if (step === 'creating') { + return ( + + + Creating project structure... + + → Creating buster folder + → Creating docs folder + → Creating metadata folder + → Generating buster.yml + + ); + } + + if (step === 'complete') { + return ( + + + ✓ Project initialized successfully! + + Created the following structure: + └─ buster/ + ├─ buster.yml + ├─ docs/ + └─ metadata/ + + ); + } + + if (step === 'error') { + return ( + + ❌ {error} + + ); + } + + return null; +}; \ No newline at end of file diff --git a/apps/cli/src/commands/init/helpers.ts b/apps/cli/src/commands/init/helpers.ts new file mode 100644 index 000000000..ad9399256 --- /dev/null +++ b/apps/cli/src/commands/init/helpers.ts @@ -0,0 +1,49 @@ +import { promises as fs } from 'node:fs'; +import path from 'node:path'; +import yaml from 'js-yaml'; +import type { ProjectConfig } from './types.js'; + +interface InitOptions { + name: string; + path: string; +} + +export async function initializeProject(options: InitOptions): Promise { + const projectPath = path.join(options.path, 'buster'); + + // Check if buster folder already exists + try { + await fs.access(projectPath); + throw new Error('A buster folder already exists in this directory'); + } catch (error: any) { + if (error.code !== 'ENOENT') { + throw error; + } + } + + // Create folder structure + await fs.mkdir(projectPath, { recursive: true }); + await fs.mkdir(path.join(projectPath, 'docs'), { recursive: true }); + await fs.mkdir(path.join(projectPath, 'metadata'), { recursive: true }); + + // Create buster.yml + const config: ProjectConfig = { + version: '1.0', + projectName: options.name, + createdAt: new Date().toISOString(), + }; + + const yamlContent = yaml.dump(config, { + lineWidth: -1, + quotingType: '"', + }); + + await fs.writeFile( + path.join(projectPath, 'buster.yml'), + yamlContent, + 'utf-8' + ); + + // Simulate some work + await new Promise(resolve => setTimeout(resolve, 1500)); +} \ No newline at end of file diff --git a/apps/cli/src/commands/init/index.ts b/apps/cli/src/commands/init/index.ts new file mode 100644 index 000000000..04998b2c3 --- /dev/null +++ b/apps/cli/src/commands/init/index.ts @@ -0,0 +1,20 @@ +import { Command } from 'commander'; +import React from 'react'; +import { render } from 'ink'; +import { InitUI } from './components.js'; +import { InitArgsSchema } from './types.js'; + +export const initCommand = new Command('init') + .description('Initialize a new Buster project') + .option('-n, --name ', 'Project name') + .option('-p, --path ', 'Project path', process.cwd()) + .option('--skip-prompts', 'Skip interactive prompts') + .action(async (options) => { + // Validate arguments + const args = InitArgsSchema.parse(options); + + // Render Ink UI + const { waitUntilExit } = render(); + + await waitUntilExit(); + }); \ No newline at end of file diff --git a/apps/cli/src/commands/init/types.ts b/apps/cli/src/commands/init/types.ts new file mode 100644 index 000000000..b9e021731 --- /dev/null +++ b/apps/cli/src/commands/init/types.ts @@ -0,0 +1,20 @@ +import { z } from 'zod'; + +// Command arguments schema +export const InitArgsSchema = z.object({ + name: z.string().optional(), + path: z.string().default(process.cwd()), + skipPrompts: z.boolean().default(false), +}); + +export type InitArgs = z.infer; + +// Project configuration schema +export const ProjectConfigSchema = z.object({ + version: z.string().default('1.0'), + projectName: z.string(), + organization: z.string().optional(), + createdAt: z.string().datetime(), +}); + +export type ProjectConfig = z.infer; \ No newline at end of file diff --git a/apps/cli/src/commands/parse/components.tsx b/apps/cli/src/commands/parse/components.tsx new file mode 100644 index 000000000..51d33b077 --- /dev/null +++ b/apps/cli/src/commands/parse/components.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { Box, Text } from 'ink'; +import type { ParseArgs } from './types.js'; + +interface ParseUIProps { + args: ParseArgs; +} + +export const ParseUI: React.FC = ({ args }) => { + return ( + + Parsing YAML files... + Path: {args.path} + {args.files.length > 0 && ( + Files: {args.files.join(', ')} + )} + + ✓ All files parsed successfully + + + ); +}; \ No newline at end of file diff --git a/apps/cli/src/commands/parse/index.ts b/apps/cli/src/commands/parse/index.ts new file mode 100644 index 000000000..f99671e1e --- /dev/null +++ b/apps/cli/src/commands/parse/index.ts @@ -0,0 +1,19 @@ +import { Command } from 'commander'; +import React from 'react'; +import { render } from 'ink'; +import { ParseUI } from './components.js'; +import { ParseArgsSchema } from './types.js'; + +export const parseCommand = new Command('parse') + .description('Parse and validate YAML model files') + .argument('[files...]', 'Model files to parse') + .option('-p, --path ', 'Path to models directory', './buster') + .action(async (files, options) => { + // Validate arguments + const args = ParseArgsSchema.parse({ ...options, files }); + + // Render Ink UI + const { waitUntilExit } = render(); + + await waitUntilExit(); + }); \ No newline at end of file diff --git a/apps/cli/src/commands/parse/types.ts b/apps/cli/src/commands/parse/types.ts new file mode 100644 index 000000000..feb5cb7fc --- /dev/null +++ b/apps/cli/src/commands/parse/types.ts @@ -0,0 +1,8 @@ +import { z } from 'zod'; + +export const ParseArgsSchema = z.object({ + path: z.string().default('./buster'), + files: z.array(z.string()).default([]), +}); + +export type ParseArgs = z.infer; \ No newline at end of file diff --git a/apps/cli/src/commands/reset/index.ts b/apps/cli/src/commands/reset/index.ts new file mode 100644 index 000000000..f32a5d3bc --- /dev/null +++ b/apps/cli/src/commands/reset/index.ts @@ -0,0 +1,19 @@ +import { Command } from 'commander'; +import React from 'react'; +import { render } from 'ink'; +import { ResetUI } from './components.js'; +import { ResetArgsSchema } from './types.js'; + +export const resetCommand = new Command('reset') + .description('Reset Buster services and data') + .option('--hard', 'Remove all data and configurations') + .option('--force', 'Skip confirmation prompts') + .action(async (options) => { + // Validate arguments + const args = ResetArgsSchema.parse(options); + + // Render Ink UI + const { waitUntilExit } = render(); + + await waitUntilExit(); + }); \ No newline at end of file diff --git a/apps/cli/src/commands/start/index.ts b/apps/cli/src/commands/start/index.ts new file mode 100644 index 000000000..065cb17f9 --- /dev/null +++ b/apps/cli/src/commands/start/index.ts @@ -0,0 +1,19 @@ +import { Command } from 'commander'; +import React from 'react'; +import { render } from 'ink'; +import { StartUI } from './components.js'; +import { StartArgsSchema } from './types.js'; + +export const startCommand = new Command('start') + .description('Start Buster services') + .option('-d, --detached', 'Run services in detached mode') + .option('--no-telemetry', 'Disable telemetry') + .action(async (options) => { + // Validate arguments + const args = StartArgsSchema.parse(options); + + // Render Ink UI + const { waitUntilExit } = render(); + + await waitUntilExit(); + }); \ No newline at end of file diff --git a/apps/cli/src/commands/stop/index.ts b/apps/cli/src/commands/stop/index.ts new file mode 100644 index 000000000..9622ab73f --- /dev/null +++ b/apps/cli/src/commands/stop/index.ts @@ -0,0 +1,13 @@ +import { Command } from 'commander'; +import React from 'react'; +import { render } from 'ink'; +import { StopUI } from './components.js'; + +export const stopCommand = new Command('stop') + .description('Stop Buster services') + .action(async () => { + // Render Ink UI + const { waitUntilExit } = render(); + + await waitUntilExit(); + }); \ No newline at end of file diff --git a/apps/cli/src/commands/update/index.ts b/apps/cli/src/commands/update/index.ts new file mode 100644 index 000000000..11d6f5815 --- /dev/null +++ b/apps/cli/src/commands/update/index.ts @@ -0,0 +1,19 @@ +import { Command } from 'commander'; +import React from 'react'; +import { render } from 'ink'; +import { UpdateUI } from './components.js'; +import { UpdateArgsSchema } from './types.js'; + +export const updateCommand = new Command('update') + .description('Update Buster CLI to the latest version') + .option('--check', 'Check for updates without installing') + .option('--force', 'Force update even if already on latest version') + .action(async (options) => { + // Validate arguments + const args = UpdateArgsSchema.parse(options); + + // Render Ink UI + const { waitUntilExit } = render(); + + await waitUntilExit(); + }); \ No newline at end of file diff --git a/apps/cli/src/main.ts b/apps/cli/src/main.ts new file mode 100644 index 000000000..3279c7e18 --- /dev/null +++ b/apps/cli/src/main.ts @@ -0,0 +1,45 @@ +#!/usr/bin/env node +import { Command } from 'commander'; +import { readFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +// Import commands +import { authCommand } from './commands/auth/index.js'; +import { initCommand } from './commands/init/index.js'; +import { deployCommand } from './commands/deploy/index.js'; +import { parseCommand } from './commands/parse/index.js'; +import { configCommand } from './commands/config/index.js'; +import { updateCommand } from './commands/update/index.js'; +import { startCommand } from './commands/start/index.js'; +import { stopCommand } from './commands/stop/index.js'; +import { resetCommand } from './commands/reset/index.js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +// Read package.json for version +const packageJson = JSON.parse( + readFileSync(join(__dirname, '..', 'package.json'), 'utf-8') +); + +const program = new Command(); + +program + .name('buster') + .description('Buster CLI - Your gateway to the Buster platform') + .version(packageJson.version); + +// Register commands +program.addCommand(authCommand); +program.addCommand(initCommand); +program.addCommand(deployCommand); +program.addCommand(parseCommand); +program.addCommand(configCommand); +program.addCommand(updateCommand); +program.addCommand(startCommand); +program.addCommand(stopCommand); +program.addCommand(resetCommand); + +// Parse command line arguments +program.parse(process.argv); \ No newline at end of file diff --git a/apps/cli/src/utils/api-client.ts b/apps/cli/src/utils/api-client.ts new file mode 100644 index 000000000..0dde4f1fc --- /dev/null +++ b/apps/cli/src/utils/api-client.ts @@ -0,0 +1,78 @@ +import { z } from 'zod'; +import { CLIError, ApiError } from './errors.js'; + +export class ApiClient { + constructor( + private baseUrl: string, + private apiKey?: string + ) {} + + async request({ + method, + path, + body, + responseSchema, + }: { + method: string; + path: string; + body?: unknown; + responseSchema: z.ZodSchema; + }): Promise { + const url = `${this.baseUrl}${path}`; + + try { + const response = await fetch(url, { + method, + headers: { + 'Content-Type': 'application/json', + ...(this.apiKey && { Authorization: `Bearer ${this.apiKey}` }), + }, + body: body ? JSON.stringify(body) : undefined, + }); + + if (!response.ok) { + const errorText = await response.text(); + throw new ApiError(response.status, errorText || response.statusText); + } + + const data = await response.json(); + return responseSchema.parse(data); + } catch (error) { + if (error instanceof ApiError) { + throw error; + } + if (error instanceof z.ZodError) { + throw new CLIError('Invalid API response format', 'VALIDATION_ERROR'); + } + throw new CLIError('Network error', 'NETWORK_ERROR'); + } + } + + // Convenience methods + async validateAuth(): Promise { + try { + await this.request({ + method: 'GET', + path: '/api/v2/auth/validate', + responseSchema: z.object({ valid: z.boolean() }), + }); + return true; + } catch { + return false; + } + } +} + +// Singleton instance +let apiClient: ApiClient; + +export function initApiClient(baseUrl: string, apiKey?: string): void { + apiClient = new ApiClient(baseUrl, apiKey); +} + +export function getApiClient(): ApiClient { + if (!apiClient) { + throw new CLIError('API client not initialized', 'NOT_INITIALIZED'); + } + return apiClient; +} \ No newline at end of file diff --git a/apps/cli/src/utils/config.ts b/apps/cli/src/utils/config.ts new file mode 100644 index 000000000..05ece24e9 --- /dev/null +++ b/apps/cli/src/utils/config.ts @@ -0,0 +1,99 @@ +import { promises as fs } from 'node:fs'; +import path from 'node:path'; +import os from 'node:os'; +import yaml from 'js-yaml'; +import { z } from 'zod'; +import { ConfigError, FileSystemError } from './errors.js'; + +// Configuration schemas +export const GlobalConfigSchema = z.object({ + version: z.string(), + defaultEnvironment: z.enum(['local', 'cloud']).default('cloud'), + telemetry: z.boolean().default(true), + autoUpdate: z.boolean().default(true), +}); + +export type GlobalConfig = z.infer; + +export const CredentialsSchema = z.object({ + apiUrl: z.string().url(), + apiKey: z.string(), + environment: z.enum(['local', 'cloud']), +}); + +export type Credentials = z.infer; + +export class ConfigManager { + private configDir: string; + private configPath: string; + private credentialsPath: string; + + constructor() { + this.configDir = process.env.BUSTER_CONFIG_DIR || path.join(os.homedir(), '.buster'); + this.configPath = path.join(this.configDir, 'config.yml'); + this.credentialsPath = path.join(this.configDir, 'credentials'); + } + + async ensureConfigDir(): Promise { + try { + await fs.mkdir(this.configDir, { recursive: true }); + } catch (error) { + throw new FileSystemError('Failed to create config directory'); + } + } + + async loadGlobalConfig(): Promise { + try { + const content = await fs.readFile(this.configPath, 'utf-8'); + const parsed = yaml.load(content); + return GlobalConfigSchema.parse(parsed); + } catch (error: any) { + if (error.code === 'ENOENT') { + // Return defaults if config doesn't exist + return GlobalConfigSchema.parse({}); + } + throw new ConfigError('Failed to load configuration'); + } + } + + async saveGlobalConfig(config: GlobalConfig): Promise { + await this.ensureConfigDir(); + const yamlContent = yaml.dump(config); + await fs.writeFile(this.configPath, yamlContent, 'utf-8'); + } + + async loadCredentials(): Promise { + try { + const content = await fs.readFile(this.credentialsPath, 'utf-8'); + const parsed = JSON.parse(content); + return CredentialsSchema.parse(parsed); + } catch (error: any) { + if (error.code === 'ENOENT') { + return null; + } + throw new ConfigError('Failed to load credentials'); + } + } + + async saveCredentials(credentials: Credentials): Promise { + await this.ensureConfigDir(); + // TODO: Encrypt credentials before saving + const jsonContent = JSON.stringify(credentials, null, 2); + await fs.writeFile(this.credentialsPath, jsonContent, 'utf-8'); + // Set restrictive permissions + await fs.chmod(this.credentialsPath, 0o600); + } + + async clearCredentials(): Promise { + try { + await fs.unlink(this.credentialsPath); + } catch (error: any) { + if (error.code !== 'ENOENT') { + throw new ConfigError('Failed to clear credentials'); + } + } + } +} + +// Singleton instance +export const configManager = new ConfigManager(); \ No newline at end of file diff --git a/apps/cli/src/utils/errors.ts b/apps/cli/src/utils/errors.ts new file mode 100644 index 000000000..dfd5735ed --- /dev/null +++ b/apps/cli/src/utils/errors.ts @@ -0,0 +1,34 @@ +export class CLIError extends Error { + constructor(message: string, public code: string) { + super(message); + this.name = 'CLIError'; + } +} + +export class ApiError extends CLIError { + constructor(public status: number, message: string) { + super(message, 'API_ERROR'); + this.name = 'ApiError'; + } +} + +export class ValidationError extends CLIError { + constructor(message: string) { + super(message, 'VALIDATION_ERROR'); + this.name = 'ValidationError'; + } +} + +export class ConfigError extends CLIError { + constructor(message: string) { + super(message, 'CONFIG_ERROR'); + this.name = 'ConfigError'; + } +} + +export class FileSystemError extends CLIError { + constructor(message: string) { + super(message, 'FS_ERROR'); + this.name = 'FileSystemError'; + } +} \ No newline at end of file diff --git a/apps/cli/tsconfig.json b/apps/cli/tsconfig.json new file mode 100644 index 000000000..d50cdbc8c --- /dev/null +++ b/apps/cli/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@buster/typescript-config/base.json", + "compilerOptions": { + "jsx": "react", + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} \ No newline at end of file diff --git a/apps/cli/tsup.config.ts b/apps/cli/tsup.config.ts new file mode 100644 index 000000000..e6f14b1aa --- /dev/null +++ b/apps/cli/tsup.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + entry: ['src/main.ts'], + format: ['esm'], + target: 'node22', + platform: 'node', + outDir: 'dist', + clean: true, + dts: false, + sourcemap: true, + minify: false, + splitting: false, + shims: false, + external: [ + '@buster/server-shared', + '@buster/typescript-config', + '@buster/vitest-config', + ], + esbuildOptions(options) { + options.keepNames = true; + }, +}); \ No newline at end of file diff --git a/apps/cli/turbo.json b/apps/cli/turbo.json new file mode 100644 index 000000000..3fcc50460 --- /dev/null +++ b/apps/cli/turbo.json @@ -0,0 +1,15 @@ +{ + "extends": ["//"], + "$schema": "https://turbo.build/schema.json", + "tasks": { + "build": { + "dependsOn": ["^build"], + "outputs": ["dist/**"] + }, + "dev": { + "cache": false, + "persistent": true, + "dependsOn": ["^build"] + } + } +} \ No newline at end of file diff --git a/apps/cli/vitest.config.ts b/apps/cli/vitest.config.ts new file mode 100644 index 000000000..e5ca74106 --- /dev/null +++ b/apps/cli/vitest.config.ts @@ -0,0 +1,12 @@ +import baseConfig from '@buster/vitest-config'; +import { defineConfig, mergeConfig } from 'vitest/config'; + +export default mergeConfig( + baseConfig, + defineConfig({ + test: { + environment: 'node', + globals: true, + }, + }) +); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb33fd8a9..094c4e9fe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -112,6 +112,70 @@ importers: specifier: workspace:* version: link:../../packages/database + apps/cli: + dependencies: + '@buster/server-shared': + specifier: workspace:* + version: link:../../packages/server-shared + chalk: + specifier: ^5.3.0 + version: 5.4.1 + commander: + specifier: ^14.0.0 + version: 14.0.0 + fast-glob: + specifier: ^3.3.2 + version: 3.3.3 + ink: + specifier: ^6.0.1 + version: 6.1.0(@types/react@19.1.9)(react@19.1.1) + ink-confirm-input: + specifier: ^2.0.0 + version: 2.0.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1) + ink-select-input: + specifier: ^6.0.0 + version: 6.2.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1) + ink-spinner: + specifier: ^5.0.0 + version: 5.0.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1) + ink-table: + specifier: ^3.1.0 + version: 3.1.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1) + ink-text-input: + specifier: ^6.0.0 + version: 6.0.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1) + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + react: + specifier: ^19.0.0 + version: 19.1.1 + zod: + specifier: 'catalog:' + version: 3.25.1 + devDependencies: + '@buster/typescript-config': + specifier: workspace:* + version: link:../../packages/typescript-config + '@buster/vitest-config': + specifier: workspace:* + version: link:../../packages/vitest-config + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 + '@types/node': + specifier: ^24.2.0 + version: 24.2.0 + '@types/react': + specifier: ^19.0.0 + version: 19.1.9 + tsup: + specifier: ^8.0.0 + version: 8.5.0(jiti@2.4.2)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + tsx: + specifier: ^4.7.1 + version: 4.20.3 + apps/electric-server: dependencies: '@buster/database': @@ -162,10 +226,10 @@ importers: version: 2.50.2 '@trigger.dev/sdk': specifier: 'catalog:' - version: 4.0.0-v4-beta.26(ai@4.3.16(react@18.3.1)(zod@3.25.1))(zod@3.25.1) + version: 4.0.0-v4-beta.26(ai@4.3.16(react@19.1.1)(zod@3.25.1))(zod@3.25.1) ai: specifier: 'catalog:' - version: 4.3.16(react@18.3.1)(zod@3.25.1) + version: 4.3.16(react@19.1.1)(zod@3.25.1) drizzle-orm: specifier: 'catalog:' version: 0.44.2(@opentelemetry/api@1.9.0)(@types/pg@8.15.4)(mysql2@3.14.1)(pg@8.16.3)(postgres@3.4.7) @@ -232,22 +296,22 @@ importers: version: link:../../packages/web-tools '@mastra/core': specifier: 'catalog:' - version: 0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@18.3.1)(zod@3.25.1) + version: 0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@19.1.1)(zod@3.25.1) '@trigger.dev/sdk': specifier: 4.0.0-v4-beta.26 - version: 4.0.0-v4-beta.26(ai@4.3.16(react@18.3.1)(zod@3.25.1))(zod@3.25.1) + version: 4.0.0-v4-beta.26(ai@4.3.16(react@19.1.1)(zod@3.25.1))(zod@3.25.1) ai: specifier: 'catalog:' - version: 4.3.16(react@18.3.1)(zod@3.25.1) + version: 4.3.16(react@19.1.1)(zod@3.25.1) braintrust: specifier: 'catalog:' - version: 0.0.209(@aws-sdk/credential-provider-web-identity@3.840.0)(openai@4.104.0(ws@8.18.3)(zod@3.25.1))(react@18.3.1)(sswr@2.2.0(svelte@5.34.9))(svelte@5.34.9)(vue@3.5.17(typescript@5.8.3))(zod@3.25.1) + version: 0.0.209(@aws-sdk/credential-provider-web-identity@3.840.0)(openai@4.104.0(ws@8.18.3)(zod@3.25.1))(react@19.1.1)(sswr@2.2.0(svelte@5.34.9))(svelte@5.34.9)(vue@3.5.17(typescript@5.8.3))(zod@3.25.1) drizzle-orm: specifier: 'catalog:' version: 0.44.2(@opentelemetry/api@1.9.0)(@types/pg@8.15.4)(mysql2@3.14.1)(pg@8.16.3)(postgres@3.4.7) vitest: specifier: 'catalog:' - version: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.0.10)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.0.10)(typescript@5.8.3))(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.2.0)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.2.0)(typescript@5.8.3))(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) zod: specifier: 'catalog:' version: 3.25.1 @@ -302,94 +366,94 @@ importers: version: 4.7.0(monaco-editor@0.52.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/ai': specifier: ^49.2.4 - version: 49.2.4(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + version: 49.2.4(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) '@platejs/autoformat': specifier: 'catalog:' - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/basic-nodes': specifier: 'catalog:' - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/basic-styles': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/callout': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/caption': specifier: ^49.0.0 - version: 49.0.0(@types/react@18.3.23)(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(@types/react@18.3.23)(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/code-block': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/combobox': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/comment': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/date': specifier: ^49.0.2 - version: 49.0.2(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.2(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/dnd': specifier: ^49.2.2 - version: 49.2.2(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dnd-html5-backend@16.0.1)(react-dnd@16.0.1(@types/node@24.0.10)(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.2.2(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dnd-html5-backend@16.0.1)(react-dnd@16.0.1(@types/node@24.0.10)(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/docx': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/emoji': specifier: ^49.0.0 - version: 49.0.0(@emoji-mart/data@1.2.1)(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(@emoji-mart/data@1.2.1)(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/floating': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/indent': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/juice': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/layout': specifier: ^49.2.1 - version: 49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/link': specifier: ^49.1.1 - version: 49.1.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.1.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/list': specifier: ^49.2.0 - version: 49.2.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.2.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/markdown': specifier: 'catalog:' - version: 49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + version: 49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) '@platejs/math': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/media': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/mention': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/resizable': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/selection': specifier: ^49.2.4 - version: 49.2.4(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.2.4(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/slash-command': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/suggestion': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/table': specifier: ^49.1.13 - version: 49.1.13(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.1.13(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/toc': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@platejs/toggle': specifier: ^49.0.0 - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@posthog/nextjs-config': specifier: ^1.1.1 version: 1.1.1(next@14.2.30(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.89.2)) @@ -581,7 +645,7 @@ importers: version: 1.17.1 platejs: specifier: 'catalog:' - version: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + version: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) pluralize: specifier: ^8.0.0 version: 8.0.0 @@ -662,7 +726,7 @@ importers: version: 7.7.3(express@4.21.2)(next@14.2.30(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.89.2))(tailwindcss@4.1.11) use-context-selector: specifier: ^2.0.0 - version: 2.0.0(react@18.3.1)(scheduler@0.23.2) + version: 2.0.0(react@18.3.1)(scheduler@0.26.0) use-file-picker: specifier: ^2.1.4 version: 2.1.4(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react@18.3.1) @@ -882,19 +946,19 @@ importers: version: link:../web-tools '@mastra/core': specifier: 'catalog:' - version: 0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@18.3.1)(zod@3.25.1) + version: 0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@19.1.1)(zod@3.25.1) '@mastra/loggers': specifier: ^0.10.3 - version: 0.10.3(@mastra/core@0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@18.3.1)(zod@3.25.1)) + version: 0.10.3(@mastra/core@0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@19.1.1)(zod@3.25.1)) ai: specifier: 'catalog:' - version: 4.3.16(react@18.3.1)(zod@3.25.1) + version: 4.3.16(react@19.1.1)(zod@3.25.1) autoevals: specifier: ^0.0.130 version: 0.0.130(ws@8.18.3) braintrust: specifier: 'catalog:' - version: 0.0.209(@aws-sdk/credential-provider-web-identity@3.840.0)(openai@4.104.0(ws@8.18.3)(zod@3.25.1))(react@18.3.1)(sswr@2.2.0(svelte@5.34.9))(svelte@5.34.9)(vue@3.5.17(typescript@5.8.3))(zod@3.25.1) + version: 0.0.209(@aws-sdk/credential-provider-web-identity@3.840.0)(openai@4.104.0(ws@8.18.3)(zod@3.25.1))(react@19.1.1)(sswr@2.2.0(svelte@5.34.9))(svelte@5.34.9)(vue@3.5.17(typescript@5.8.3))(zod@3.25.1) drizzle-orm: specifier: 'catalog:' version: 0.44.2(@opentelemetry/api@1.9.0)(@types/pg@8.15.4)(mysql2@3.14.1)(pg@8.16.3)(postgres@3.4.7) @@ -970,7 +1034,7 @@ importers: version: link:../vitest-config ai: specifier: 'catalog:' - version: 4.3.16(react@18.3.1)(zod@3.25.1) + version: 4.3.16(react@19.1.1)(zod@3.25.1) drizzle-kit: specifier: ^0.31.4 version: 0.31.4 @@ -1045,16 +1109,16 @@ importers: version: link:../vitest-config '@platejs/autoformat': specifier: 'catalog:' - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)))(react-dom@18.3.1(react@19.1.1))(react@19.1.1) '@platejs/basic-nodes': specifier: 'catalog:' - version: 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 49.0.0(platejs@49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)))(react-dom@18.3.1(react@19.1.1))(react@19.1.1) '@platejs/markdown': specifier: 'catalog:' - version: 49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + version: 49.2.1(platejs@49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)))(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(typescript@5.8.3) platejs: specifier: 'catalog:' - version: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + version: 49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)) remark-gfm: specifier: 'catalog:' version: 4.0.1 @@ -1070,7 +1134,7 @@ importers: version: 4.20.3 vitest: specifier: 'catalog:' - version: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.0.10)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.0.10)(typescript@5.8.3))(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.2.0)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.2.0)(typescript@5.8.3))(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) packages/slack: dependencies: @@ -1113,7 +1177,7 @@ importers: version: link:../vitest-config ai: specifier: 'catalog:' - version: 4.3.16(react@18.3.1)(zod@3.25.1) + version: 4.3.16(react@19.1.1)(zod@3.25.1) zod: specifier: ^3.0.0 version: 3.25.1 @@ -1162,13 +1226,13 @@ importers: version: 17.1.0 vite: specifier: 'catalog:' - version: 7.0.5(@types/node@24.0.10)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + version: 7.0.5(@types/node@24.2.0)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) vite-tsconfig-paths: specifier: 'catalog:' - version: 6.0.0-beta.3(typescript@5.8.3)(vite@7.0.5(@types/node@24.0.10)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)) + version: 6.0.0-beta.3(typescript@5.8.3)(vite@7.0.5(@types/node@24.2.0)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: 'catalog:' - version: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.0.10)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.0.10)(typescript@5.8.3))(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.2.0)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.2.0)(typescript@5.8.3))(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) packages/web-tools: dependencies: @@ -1298,6 +1362,10 @@ packages: vue: optional: true + '@alcalzone/ansi-tokenize@0.1.3': + resolution: {integrity: sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw==} + engines: {node: '>=14.13.1'} + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -5814,6 +5882,9 @@ packages: '@types/node@24.0.10': resolution: {integrity: sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==} + '@types/node@24.2.0': + resolution: {integrity: sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==} + '@types/oracledb@6.5.2': resolution: {integrity: sha512-kK1eBS/Adeyis+3OlBDMeQQuasIDLUYXsi2T15ccNJ0iyUpQ4xDF7svFu3+bGVrI0CMBUclPciz+lsQR3JX3TQ==} @@ -5869,6 +5940,9 @@ packages: '@types/react@18.3.23': resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==} + '@types/react@19.1.9': + resolution: {integrity: sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==} + '@types/reactcss@1.2.13': resolution: {integrity: sha512-gi3S+aUi6kpkF5vdhUsnkwbiSEIU/BEJyD7kBy2SudWBUuKmJk8AQKE0OVcQQeEy40Azh0lV6uynxlikYIJuwg==} peerDependencies: @@ -6413,6 +6487,10 @@ packages: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} + ansi-html-community@0.0.8: resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} engines: {'0': node >= 0.8.0} @@ -6590,6 +6668,10 @@ packages: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} + auto-bind@5.0.1: + resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + autoevals@0.0.130: resolution: {integrity: sha512-JS0T/YCEH13AAOGiWWGJDkIPP8LsDmRBYr3EazTukHxvd0nidOW7fGj0qVPFx2bARrSNO9AfCR6xoTP/5m3Bmw==} @@ -6783,7 +6865,6 @@ packages: bun@1.2.18: resolution: {integrity: sha512-OR+EpNckoJN4tHMVZPaTPxDj2RgpJgJwLruTIFYbO3bQMguLd0YrmkWKYqsiihcLgm2ehIjF/H1RLfZiRa7+qQ==} - cpu: [arm64, x64, aarch64] os: [darwin, linux, win32] hasBin: true @@ -6979,10 +7060,26 @@ packages: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + + cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-progress@3.12.0: resolution: {integrity: sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==} engines: {node: '>=4'} + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} @@ -7018,6 +7115,10 @@ packages: react: ^18 || ^19 || ^19.0.0-rc react-dom: ^18 || ^19 || ^19.0.0-rc + code-excerpt@4.0.0: + resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + codem-isoboxer@0.3.10: resolution: {integrity: sha512-eNk3TRV+xQMJ1PEj0FQGY8KD4m0GPxT487XJ+Iftm7mVa9WpPFDMWqPt+46buiP5j5Wzqe5oMIhqBcAeKfygSA==} @@ -7068,6 +7169,10 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} + commander@14.0.0: + resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} + engines: {node: '>=20'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -7139,6 +7244,10 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + convert-to-spaces@2.0.1: + resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + convict@6.2.4: resolution: {integrity: sha512-qN60BAwdMVdofckX7AlohVJ2x9UvjTNoKVXCL2LxFk1l7757EJqf1nySdMkPQer0bt8kQ5lQiyZ9/2NvrFBuwQ==} engines: {node: '>=6'} @@ -7676,6 +7785,9 @@ packages: resolution: {integrity: sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==} engines: {node: '>4.0'} + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -7736,6 +7848,10 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -7777,6 +7893,9 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + es-toolkit@1.39.8: + resolution: {integrity: sha512-A8QO9TfF+rltS8BXpdu8OS+rpGgEdnRhqIVxO/ZmNvnXBYgOdSsxukT55ELyP94gZIntWJ+Li9QRrT2u1Kitpg==} + es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} @@ -7810,6 +7929,10 @@ packages: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -8108,6 +8231,10 @@ packages: fft.js@4.0.4: resolution: {integrity: sha512-f9c00hphOgeQTlDyavwTtu6RiK8AIFjD6+jvXkNkpeQ7rirK3uFWVpalkoS4LAwbdX7mfZ8aoBfFVQX1Re/8aw==} + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -8327,6 +8454,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.3.0: + resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} + engines: {node: '>=18'} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -8726,6 +8857,10 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. @@ -8733,6 +8868,60 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ink-confirm-input@2.0.0: + resolution: {integrity: sha512-YCd7a9XW0DIIbOhF3XiLo3WF86mOart9qI1qN56wT5IDJxU+j8BanEZh5/QXoazyIPSv1iXlHPIlRB5cbZIMIA==} + engines: {node: '>=10'} + peerDependencies: + ink: '>=2' + react: '>=16' + + ink-select-input@6.2.0: + resolution: {integrity: sha512-304fZXxkpYxJ9si5lxRCaX01GNlmPBgOZumXXRnPYbHW/iI31cgQynqk2tRypGLOF1cMIwPUzL2LSm6q4I5rQQ==} + engines: {node: '>=18'} + peerDependencies: + ink: '>=5.0.0' + react: '>=18.0.0' + + ink-spinner@5.0.0: + resolution: {integrity: sha512-EYEasbEjkqLGyPOUc8hBJZNuC5GvXGMLu0w5gdTNskPc7Izc5vO3tdQEYnzvshucyGCBXc86ig0ujXPMWaQCdA==} + engines: {node: '>=14.16'} + peerDependencies: + ink: '>=4.0.0' + react: '>=18.0.0' + + ink-table@3.1.0: + resolution: {integrity: sha512-qxVb4DIaEaJryvF9uZGydnmP9Hkmas3DCKVpEcBYC0E4eJd3qNgNe+PZKuzgCERFe9LfAS1TNWxCr9+AU4v3YA==} + peerDependencies: + ink: '>=3.0.0' + react: '>=16.8.0' + + ink-text-input@3.3.0: + resolution: {integrity: sha512-gO4wrOf2ie3YuEARTIwGlw37lMjFn3Gk6CKIDrMlHb46WFMagZU7DplohjM24zynlqfnXA5UDEIfC2NBcvD8kg==} + engines: {node: '>=8'} + peerDependencies: + ink: ^2.0.0 + react: ^16.5.2 + + ink-text-input@6.0.0: + resolution: {integrity: sha512-Fw64n7Yha5deb1rHY137zHTAbSTNelUKuB5Kkk2HACXEtwIHBCf9OH2tP/LQ9fRYTl1F0dZgbW0zPnZk6FA9Lw==} + engines: {node: '>=18'} + peerDependencies: + ink: '>=5' + react: '>=18' + + ink@6.1.0: + resolution: {integrity: sha512-YQ+lbMD79y3FBAJXXZnuRajLEgaMFp102361eY5NrBIEVCi9oFo7gNZU4z2LBWlcjZFiTt7jetlkIbKCCH4KJA==} + engines: {node: '>=20'} + peerDependencies: + '@types/react': '>=19.0.0' + react: '>=19.0.0' + react-devtools-core: ^4.19.1 + peerDependenciesMeta: + '@types/react': + optional: true + react-devtools-core: + optional: true + inline-style-parser@0.2.4: resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} @@ -8837,6 +9026,14 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + is-generator-function@1.1.0: resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} engines: {node: '>= 0.4'} @@ -8851,6 +9048,11 @@ packages: is-hotkey@0.2.0: resolution: {integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==} + is-in-ci@1.0.0: + resolution: {integrity: sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==} + engines: {node: '>=18'} + hasBin: true + is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} @@ -8939,6 +9141,10 @@ packages: is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -9706,6 +9912,10 @@ packages: engines: {node: '>=10.0.0'} hasBin: true + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} @@ -10042,6 +10252,10 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-hash@2.2.0: + resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} + engines: {node: '>= 6'} + object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -10091,6 +10305,10 @@ packages: one-time@1.0.0: resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} @@ -10248,6 +10466,10 @@ packages: pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + patch-console@2.0.0: + resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} @@ -10826,6 +11048,12 @@ packages: react: ^17.0.2 || ^18 || ^19 react-dom: ^17.0.2 || ^18 || ^19 + react-reconciler@0.32.0: + resolution: {integrity: sha512-2NPMOzgTlG0ZWdIf3qG+dcbLSoAc/uLfOwckc3ofy5sSK0pLJqnQLpUFxvGcN2rlXSjnVtGeeFLNimCQEj5gOQ==} + engines: {node: '>=0.10.0'} + peerDependencies: + react: ^19.1.0 + react-refresh@0.14.2: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} @@ -10883,6 +11111,10 @@ packages: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} + react@19.1.1: + resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} + engines: {node: '>=0.10.0'} + reactcss@1.2.3: resolution: {integrity: sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==} peerDependencies: @@ -11040,6 +11272,10 @@ packages: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true + restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + retry-request@7.0.2: resolution: {integrity: sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==} engines: {node: '>=14'} @@ -11154,6 +11390,9 @@ packages: scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + schema-utils@3.3.0: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} @@ -11313,6 +11552,14 @@ packages: slate@0.117.0: resolution: {integrity: sha512-qPReb7Z7OQ5ryoStjlnC9tQd3294SdV5Y1aLjstAK/zckfvVYApI3GVdOawFdPgI+++KpZYiz6EHjwJGFVdbmA==} + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + slick@1.12.2: resolution: {integrity: sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==} @@ -11410,6 +11657,10 @@ packages: stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -11470,6 +11721,10 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + string.prototype.includes@2.0.1: resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} engines: {node: '>= 0.4'} @@ -11803,6 +12058,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + to-rotated@1.0.0: + resolution: {integrity: sha512-KsEID8AfgUy+pxVRLsWp0VzCa69wxzUDZnzGbyIST/bcgcrMvTYoFBX/QORH4YApoD89EDuUovx4BTdpOn319Q==} + engines: {node: '>=18'} + toggle-selection@1.0.6: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} @@ -12078,6 +12337,9 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.10.0: + resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + undici-types@7.8.0: resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} @@ -12633,6 +12895,10 @@ packages: engines: {node: '>=8'} hasBin: true + widest-line@5.0.0: + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} + engines: {node: '>=18'} + winston-transport@4.9.0: resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} engines: {node: '>= 12.0.0'} @@ -12660,6 +12926,10 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -12766,6 +13036,10 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -12778,6 +13052,9 @@ packages: resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} engines: {node: '>=18'} + yoga-layout@3.2.1: + resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} + youtube-video-element@1.6.1: resolution: {integrity: sha512-FDRgXlPxpe1bh6HlhL6GfJVcvVNaZKCcLEZ90X1G3Iu+z2g2cIhm2OWj9abPZq1Zqit6SY7Gwh13H9g7acoBnQ==} @@ -12891,22 +13168,22 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/react@0.0.70(react@18.3.1)(zod@3.25.1)': + '@ai-sdk/react@0.0.70(react@19.1.1)(zod@3.25.1)': dependencies: '@ai-sdk/provider-utils': 1.0.22(zod@3.25.1) '@ai-sdk/ui-utils': 0.0.50(zod@3.25.1) - swr: 2.3.4(react@18.3.1) + swr: 2.3.4(react@19.1.1) throttleit: 2.1.0 optionalDependencies: - react: 18.3.1 + react: 19.1.1 zod: 3.25.1 - '@ai-sdk/react@1.2.12(react@18.3.1)(zod@3.25.1)': + '@ai-sdk/react@1.2.12(react@19.1.1)(zod@3.25.1)': dependencies: '@ai-sdk/provider-utils': 2.2.8(zod@3.25.1) '@ai-sdk/ui-utils': 1.2.11(zod@3.25.1) - react: 18.3.1 - swr: 2.3.4(react@18.3.1) + react: 19.1.1 + swr: 2.3.4(react@19.1.1) throttleit: 2.1.0 optionalDependencies: zod: 3.25.1 @@ -12955,6 +13232,11 @@ snapshots: transitivePeerDependencies: - zod + '@alcalzone/ansi-tokenize@0.1.3': + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + '@alloc/quick-lru@5.2.0': {} '@ampproject/remapping@2.3.0': @@ -15157,6 +15439,14 @@ snapshots: optionalDependencies: '@types/node': 24.0.10 + '@inquirer/confirm@5.1.13(@types/node@24.2.0)': + dependencies: + '@inquirer/core': 10.1.14(@types/node@24.2.0) + '@inquirer/type': 3.0.7(@types/node@24.2.0) + optionalDependencies: + '@types/node': 24.2.0 + optional: true + '@inquirer/core@10.1.14(@types/node@20.19.4)': dependencies: '@inquirer/figures': 1.0.12 @@ -15184,6 +15474,20 @@ snapshots: optionalDependencies: '@types/node': 24.0.10 + '@inquirer/core@10.1.14(@types/node@24.2.0)': + dependencies: + '@inquirer/figures': 1.0.12 + '@inquirer/type': 3.0.7(@types/node@24.2.0) + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + optionalDependencies: + '@types/node': 24.2.0 + optional: true + '@inquirer/figures@1.0.12': {} '@inquirer/type@3.0.7(@types/node@20.19.4)': @@ -15195,6 +15499,11 @@ snapshots: optionalDependencies: '@types/node': 24.0.10 + '@inquirer/type@3.0.7(@types/node@24.2.0)': + optionalDependencies: + '@types/node': 24.2.0 + optional: true + '@isaacs/balanced-match@4.0.1': {} '@isaacs/brace-expansion@5.0.0': @@ -15298,12 +15607,12 @@ snapshots: transitivePeerDependencies: - react - '@mastra/core@0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@18.3.1)(zod@3.25.1)': + '@mastra/core@0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@19.1.1)(zod@3.25.1)': dependencies: '@ai-sdk/provider': 1.1.3 '@ai-sdk/provider-utils': 2.2.8(zod@3.25.1) '@ai-sdk/ui-utils': 1.2.11(zod@3.25.1) - '@mastra/schema-compat': 0.10.3(ai@4.3.16(react@18.3.1)(zod@3.25.1))(zod@3.25.1) + '@mastra/schema-compat': 0.10.3(ai@4.3.16(react@19.1.1)(zod@3.25.1))(zod@3.25.1) '@opentelemetry/api': 1.9.0 '@opentelemetry/auto-instrumentations-node': 0.59.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0)) '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) @@ -15318,7 +15627,7 @@ snapshots: '@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.34.0 '@sindresorhus/slugify': 2.2.1 - ai: 4.3.16(react@18.3.1)(zod@3.25.1) + ai: 4.3.16(react@19.1.1)(zod@3.25.1) cohere-ai: 7.17.1 date-fns: 3.6.0 dotenv: 16.6.1 @@ -15351,15 +15660,15 @@ snapshots: - valibot - zod-openapi - '@mastra/loggers@0.10.3(@mastra/core@0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@18.3.1)(zod@3.25.1))': + '@mastra/loggers@0.10.3(@mastra/core@0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@19.1.1)(zod@3.25.1))': dependencies: - '@mastra/core': 0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@18.3.1)(zod@3.25.1) + '@mastra/core': 0.10.8(effect@3.16.8)(openapi-types@12.1.3)(react@19.1.1)(zod@3.25.1) pino: 9.7.0 pino-pretty: 13.0.0 - '@mastra/schema-compat@0.10.3(ai@4.3.16(react@18.3.1)(zod@3.25.1))(zod@3.25.1)': + '@mastra/schema-compat@0.10.3(ai@4.3.16(react@19.1.1)(zod@3.25.1))(zod@3.25.1)': dependencies: - ai: 4.3.16(react@18.3.1)(zod@3.25.1) + ai: 4.3.16(react@19.1.1)(zod@3.25.1) json-schema: 0.4.0 zod: 3.25.1 zod-from-json-schema: 0.0.5 @@ -16488,72 +16797,85 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@platejs/ai@49.2.4(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@platejs/ai@49.2.4(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': dependencies: - '@platejs/markdown': 49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) - '@platejs/selection': 49.2.4(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@platejs/markdown': 49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3) + '@platejs/selection': 49.2.4(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lodash: 4.17.21 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - supports-color - typescript - '@platejs/autoformat@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/autoformat@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: lodash: 4.17.21 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/basic-nodes@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/autoformat@49.0.0(platejs@49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)))(react-dom@18.3.1(react@19.1.1))(react@19.1.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + lodash: 4.17.21 + platejs: 49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)) + react: 19.1.1 + react-dom: 18.3.1(react@19.1.1) + + '@platejs/basic-nodes@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/basic-styles@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/basic-nodes@49.0.0(platejs@49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)))(react-dom@18.3.1(react@19.1.1))(react@19.1.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)) + react: 19.1.1 + react-dom: 18.3.1(react@19.1.1) + + '@platejs/basic-styles@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/callout@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/callout@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/caption@49.0.0(@types/react@18.3.23)(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/caption@49.0.0(@types/react@18.3.23)(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-textarea-autosize: 8.5.9(@types/react@18.3.23)(react@18.3.1) transitivePeerDependencies: - '@types/react' - '@platejs/code-block@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/code-block@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/combobox@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/combobox@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/comment@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/comment@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: lodash: 4.17.21 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/core@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1))': + '@platejs/core@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1))': dependencies: '@platejs/slate': 49.2.4 '@udecode/react-hotkeys': 37.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -16574,7 +16896,7 @@ snapshots: slate-react: 0.117.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0) use-deep-compare: 1.3.0(react@18.3.1) zustand: 5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) - zustand-x: 6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1))) + zustand-x: 6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1))) transitivePeerDependencies: - '@types/react' - immer @@ -16584,93 +16906,124 @@ snapshots: - slate-dom - use-sync-external-store - '@platejs/date@49.0.2(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/core@49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1))': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + '@platejs/slate': 49.2.4 + '@udecode/react-hotkeys': 37.0.0(react-dom@18.3.1(react@19.1.1))(react@19.1.1) + '@udecode/react-utils': 49.0.15(react-dom@18.3.1(react@19.1.1))(react@19.1.1) + '@udecode/utils': 47.2.7 + clsx: 2.1.1 + html-entities: 2.6.0 + is-hotkey: 0.2.0 + jotai: 2.8.4(react@19.1.1) + jotai-optics: 0.4.0(jotai@2.8.4(react@19.1.1))(optics-ts@2.4.1) + jotai-x: 2.3.3(jotai@2.8.4(react@19.1.1))(react@19.1.1) + lodash: 4.17.21 + nanoid: 5.1.5 + optics-ts: 2.4.1 + react: 19.1.1 + react-dom: 18.3.1(react@19.1.1) + slate-hyperscript: 0.100.0(slate@0.117.0) + slate-react: 0.117.1(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0) + use-deep-compare: 1.3.0(react@19.1.1) + zustand: 5.0.7(immer@10.1.1)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + zustand-x: 6.1.0(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(zustand@5.0.7(immer@10.1.1)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1))) + transitivePeerDependencies: + - '@types/react' + - immer + - react-native + - scheduler + - slate + - slate-dom + - use-sync-external-store + + '@platejs/date@49.0.2(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/diff@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/diff@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: diff-match-patch-ts: 0.6.0 lodash: 4.17.21 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/dnd@49.2.2(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dnd-html5-backend@16.0.1)(react-dnd@16.0.1(@types/node@24.0.10)(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/dnd@49.2.2(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dnd-html5-backend@16.0.1)(react-dnd@16.0.1(@types/node@24.0.10)(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: lodash: 4.17.21 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) raf: 3.4.1 react: 18.3.1 react-dnd: 16.0.1(@types/node@24.0.10)(@types/react@18.3.23)(react@18.3.1) react-dnd-html5-backend: 16.0.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/docx@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/docx@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) validator: 13.15.15 - '@platejs/emoji@49.0.0(@emoji-mart/data@1.2.1)(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/emoji@49.0.0(@emoji-mart/data@1.2.1)(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@emoji-mart/data': 1.2.1 - '@platejs/combobox': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + '@platejs/combobox': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/floating@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/floating@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/core': 1.7.2 '@floating-ui/react': 0.27.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/indent@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/indent@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/juice@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/juice@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: juice: 11.0.1 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/layout@49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/layout@49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/link@49.1.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/link@49.1.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@platejs/floating': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + '@platejs/floating': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/list@49.2.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/list@49.2.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@platejs/indent': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@platejs/indent': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) clsx: 2.1.1 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/markdown@49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': + '@platejs/markdown@49.2.1(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)': dependencies: marked: 15.0.12 mdast-util-math: 3.0.0 mdast-util-mdx: 3.0.0 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) remark-mdx: 3.1.0 @@ -16682,44 +17035,61 @@ snapshots: - supports-color - typescript - '@platejs/math@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/markdown@49.2.1(platejs@49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)))(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(typescript@5.8.3)': + dependencies: + marked: 15.0.12 + mdast-util-math: 3.0.0 + mdast-util-mdx: 3.0.0 + platejs: 49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)) + react: 19.1.1 + react-dom: 18.3.1(react@19.1.1) + remark-mdx: 3.1.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + ts-essentials: 10.1.0(typescript@5.8.3) + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + - typescript + + '@platejs/math@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: katex: 0.16.22 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/media@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/media@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: js-video-url-parser: 0.5.1 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/mention@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/mention@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@platejs/combobox': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + '@platejs/combobox': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/resizable@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/resizable@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/selection@49.2.4(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/selection@49.2.4(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: copy-to-clipboard: 3.3.3 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/slash-command@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/slash-command@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@platejs/combobox': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + '@platejs/combobox': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -16731,39 +17101,39 @@ snapshots: slate: 0.117.0 slate-dom: 0.116.0(slate@0.117.0) - '@platejs/suggestion@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/suggestion@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@platejs/diff': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@platejs/diff': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lodash: 4.17.21 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/table@49.1.13(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/table@49.1.13(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@platejs/resizable': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@platejs/resizable': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lodash: 4.17.21 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/toc@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/toc@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/toggle@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@platejs/toggle@49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@platejs/indent': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@platejs/indent': 49.0.0(platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lodash: 4.17.21 - platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + platejs: 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@platejs/utils@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1))': + '@platejs/utils@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1))': dependencies: - '@platejs/core': 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + '@platejs/core': 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) '@platejs/slate': 49.2.4 '@udecode/react-utils': 49.0.15(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@udecode/utils': 47.2.7 @@ -16780,6 +17150,25 @@ snapshots: - slate-dom - use-sync-external-store + '@platejs/utils@49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1))': + dependencies: + '@platejs/core': 49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)) + '@platejs/slate': 49.2.4 + '@udecode/react-utils': 49.0.15(react-dom@18.3.1(react@19.1.1))(react@19.1.1) + '@udecode/utils': 47.2.7 + clsx: 2.1.1 + lodash: 4.17.21 + react: 19.1.1 + react-dom: 18.3.1(react@19.1.1) + transitivePeerDependencies: + - '@types/react' + - immer + - react-native + - scheduler + - slate + - slate-dom + - use-sync-external-store + '@playwright/test@1.54.2': dependencies: playwright: 1.54.2 @@ -16931,6 +17320,10 @@ snapshots: optionalDependencies: '@types/react': 18.3.23 + '@radix-ui/react-compose-refs@1.1.2(react@19.1.1)': + dependencies: + react: 19.1.1 + '@radix-ui/react-context-menu@2.2.15(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.2 @@ -17252,6 +17645,11 @@ snapshots: optionalDependencies: '@types/react': 18.3.23 + '@radix-ui/react-slot@1.2.3(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(react@19.1.1) + react: 19.1.1 + '@radix-ui/react-switch@1.2.5(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.2 @@ -17532,7 +17930,7 @@ snapshots: '@slack/logger@3.0.0': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@slack/types@2.14.0': {} @@ -17541,7 +17939,7 @@ snapshots: '@slack/logger': 3.0.0 '@slack/types': 2.14.0 '@types/is-stream': 1.1.0 - '@types/node': 24.0.10 + '@types/node': 24.2.0 axios: 1.11.0 eventemitter3: 3.1.2 form-data: 2.5.3 @@ -18649,7 +19047,7 @@ snapshots: - supports-color - utf-8-validate - '@trigger.dev/sdk@4.0.0-v4-beta.26(ai@4.3.16(react@18.3.1)(zod@3.25.1))(zod@3.25.1)': + '@trigger.dev/sdk@4.0.0-v4-beta.26(ai@4.3.16(react@19.1.1)(zod@3.25.1))(zod@3.25.1)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/api-logs': 0.52.1 @@ -18666,7 +19064,7 @@ snapshots: ws: 8.18.3 zod: 3.25.1 optionalDependencies: - ai: 4.3.16(react@18.3.1)(zod@3.25.1) + ai: 4.3.16(react@19.1.1)(zod@3.25.1) transitivePeerDependencies: - bufferutil - supports-color @@ -18704,7 +19102,7 @@ snapshots: '@types/bunyan@1.8.11': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/canvas-confetti@1.9.0': {} @@ -18716,7 +19114,7 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/cookie@0.4.1': {} @@ -18724,7 +19122,7 @@ snapshots: '@types/cors@2.8.19': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/debug@4.1.12': dependencies: @@ -18760,7 +19158,7 @@ snapshots: '@types/is-stream@1.1.0': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/js-cookie@3.0.6': {} @@ -18786,13 +19184,13 @@ snapshots: '@types/memcached@2.2.10': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/ms@2.1.0': {} '@types/mssql@9.1.7': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 tarn: 3.0.2 tedious: 18.6.1 transitivePeerDependencies: @@ -18800,11 +19198,11 @@ snapshots: '@types/mysql@2.15.26': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/node-fetch@2.6.12': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 form-data: 4.0.3 '@types/node@18.19.119': @@ -18819,13 +19217,17 @@ snapshots: dependencies: undici-types: 7.8.0 + '@types/node@24.2.0': + dependencies: + undici-types: 7.10.0 + '@types/oracledb@6.5.2': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/papaparse@5.3.16': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/parse-json@4.0.2': {} @@ -18833,7 +19235,7 @@ snapshots: '@types/pg-cursor@2.7.2': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/pg': 8.15.4 '@types/pg-pool@2.0.6': @@ -18842,13 +19244,13 @@ snapshots: '@types/pg@8.15.4': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 pg-protocol: 1.10.3 pg-types: 2.2.0 '@types/pg@8.6.1': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 pg-protocol: 1.10.3 pg-types: 2.2.0 @@ -18880,18 +19282,22 @@ snapshots: '@types/prop-types': 15.7.15 csstype: 3.1.3 + '@types/react@19.1.9': + dependencies: + csstype: 3.1.3 + '@types/reactcss@1.2.13(@types/react@18.3.23)': dependencies: '@types/react': 18.3.23 '@types/readable-stream@4.0.21': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/request@2.48.12': dependencies: '@types/caseless': 0.12.5 - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/tough-cookie': 4.0.5 form-data: 2.5.3 @@ -18907,7 +19313,7 @@ snapshots: '@types/tedious@4.0.14': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@types/tough-cookie@4.0.5': {} @@ -18921,7 +19327,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 '@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': dependencies: @@ -19078,6 +19484,11 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + '@udecode/react-hotkeys@37.0.0(react-dom@18.3.1(react@19.1.1))(react@19.1.1)': + dependencies: + react: 19.1.1 + react-dom: 18.3.1(react@19.1.1) + '@udecode/react-utils@49.0.15(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-slot': 1.2.3(@types/react@18.3.23)(react@18.3.1) @@ -19088,6 +19499,16 @@ snapshots: transitivePeerDependencies: - '@types/react' + '@udecode/react-utils@49.0.15(react-dom@18.3.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-slot': 1.2.3(react@19.1.1) + '@udecode/utils': 47.2.7 + clsx: 2.1.1 + react: 19.1.1 + react-dom: 18.3.1(react@19.1.1) + transitivePeerDependencies: + - '@types/react' + '@udecode/utils@47.2.7': {} '@ungap/structured-clone@1.3.0': {} @@ -19194,7 +19615,7 @@ snapshots: std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.0.10)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.0.10)(typescript@5.8.3))(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + vitest: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.2.0)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.2.0)(typescript@5.8.3))(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - supports-color @@ -19231,6 +19652,15 @@ snapshots: msw: 2.10.4(@types/node@24.0.10)(typescript@5.8.3) vite: 6.3.5(@types/node@24.0.10)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + '@vitest/mocker@3.2.4(msw@2.10.4(@types/node@24.2.0)(typescript@5.8.3))(vite@6.3.5(@types/node@20.19.4)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + msw: 2.10.4(@types/node@24.2.0)(typescript@5.8.3) + vite: 6.3.5(@types/node@20.19.4)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + '@vitest/pretty-format@2.0.5': dependencies: tinyrainbow: 1.2.0 @@ -19472,11 +19902,11 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - ai@3.4.33(openai@4.104.0(ws@8.18.3)(zod@3.25.1))(react@18.3.1)(sswr@2.2.0(svelte@5.34.9))(svelte@5.34.9)(vue@3.5.17(typescript@5.8.3))(zod@3.25.1): + ai@3.4.33(openai@4.104.0(ws@8.18.3)(zod@3.25.1))(react@19.1.1)(sswr@2.2.0(svelte@5.34.9))(svelte@5.34.9)(vue@3.5.17(typescript@5.8.3))(zod@3.25.1): dependencies: '@ai-sdk/provider': 0.0.26 '@ai-sdk/provider-utils': 1.0.22(zod@3.25.1) - '@ai-sdk/react': 0.0.70(react@18.3.1)(zod@3.25.1) + '@ai-sdk/react': 0.0.70(react@19.1.1)(zod@3.25.1) '@ai-sdk/solid': 0.0.54(zod@3.25.1) '@ai-sdk/svelte': 0.0.57(svelte@5.34.9)(zod@3.25.1) '@ai-sdk/ui-utils': 0.0.50(zod@3.25.1) @@ -19489,7 +19919,7 @@ snapshots: zod-to-json-schema: 3.24.6(zod@3.25.1) optionalDependencies: openai: 4.104.0(ws@8.18.3)(zod@3.25.1) - react: 18.3.1 + react: 19.1.1 sswr: 2.2.0(svelte@5.34.9) svelte: 5.34.9 zod: 3.25.1 @@ -19497,17 +19927,17 @@ snapshots: - solid-js - vue - ai@4.3.16(react@18.3.1)(zod@3.25.1): + ai@4.3.16(react@19.1.1)(zod@3.25.1): dependencies: '@ai-sdk/provider': 1.1.3 '@ai-sdk/provider-utils': 2.2.8(zod@3.25.1) - '@ai-sdk/react': 1.2.12(react@18.3.1)(zod@3.25.1) + '@ai-sdk/react': 1.2.12(react@19.1.1)(zod@3.25.1) '@ai-sdk/ui-utils': 1.2.11(zod@3.25.1) '@opentelemetry/api': 1.9.0 jsondiffpatch: 0.6.0 zod: 3.25.1 optionalDependencies: - react: 18.3.1 + react: 19.1.1 ajv-formats@2.1.1(ajv@8.17.1): optionalDependencies: @@ -19542,6 +19972,10 @@ snapshots: dependencies: type-fest: 0.21.3 + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 + ansi-html-community@0.0.8: {} ansi-html@0.0.9: {} @@ -19734,6 +20168,8 @@ snapshots: atomic-sleep@1.0.0: {} + auto-bind@5.0.1: {} + autoevals@0.0.130(ws@8.18.3): dependencies: ajv: 8.17.1 @@ -19890,13 +20326,13 @@ snapshots: dependencies: fill-range: 7.1.1 - braintrust@0.0.209(@aws-sdk/credential-provider-web-identity@3.840.0)(openai@4.104.0(ws@8.18.3)(zod@3.25.1))(react@18.3.1)(sswr@2.2.0(svelte@5.34.9))(svelte@5.34.9)(vue@3.5.17(typescript@5.8.3))(zod@3.25.1): + braintrust@0.0.209(@aws-sdk/credential-provider-web-identity@3.840.0)(openai@4.104.0(ws@8.18.3)(zod@3.25.1))(react@19.1.1)(sswr@2.2.0(svelte@5.34.9))(svelte@5.34.9)(vue@3.5.17(typescript@5.8.3))(zod@3.25.1): dependencies: '@ai-sdk/provider': 1.1.3 '@braintrust/core': 0.0.89 '@next/env': 14.2.30 '@vercel/functions': 1.6.0(@aws-sdk/credential-provider-web-identity@3.840.0) - ai: 3.4.33(openai@4.104.0(ws@8.18.3)(zod@3.25.1))(react@18.3.1)(sswr@2.2.0(svelte@5.34.9))(svelte@5.34.9)(vue@3.5.17(typescript@5.8.3))(zod@3.25.1) + ai: 3.4.33(openai@4.104.0(ws@8.18.3)(zod@3.25.1))(react@19.1.1)(sswr@2.2.0(svelte@5.34.9))(svelte@5.34.9)(vue@3.5.17(typescript@5.8.3))(zod@3.25.1) argparse: 2.0.1 chalk: 4.1.2 cli-progress: 3.12.0 @@ -20207,10 +20643,23 @@ snapshots: clean-stack@2.2.0: {} + cli-boxes@3.0.0: {} + + cli-cursor@4.0.0: + dependencies: + restore-cursor: 4.0.0 + cli-progress@3.12.0: dependencies: string-width: 4.2.3 + cli-spinners@2.9.2: {} + + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.2.0 + cli-width@4.1.0: {} client-only@0.0.1: {} @@ -20248,6 +20697,10 @@ snapshots: - '@types/react' - '@types/react-dom' + code-excerpt@4.0.0: + dependencies: + convert-to-spaces: 2.0.1 + codem-isoboxer@0.3.10: {} cohere-ai@7.17.1: @@ -20314,6 +20767,8 @@ snapshots: commander@12.1.0: {} + commander@14.0.0: {} + commander@2.20.3: {} commander@4.1.1: {} @@ -20371,6 +20826,8 @@ snapshots: convert-source-map@2.0.0: {} + convert-to-spaces@2.0.1: {} + convict@6.2.4: dependencies: lodash.clonedeep: 4.5.0 @@ -20850,6 +21307,8 @@ snapshots: email-validator@2.0.4: {} + emoji-regex@10.4.0: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -20895,7 +21354,7 @@ snapshots: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.19 - '@types/node': 24.0.10 + '@types/node': 24.2.0 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.4.2 @@ -20921,6 +21380,8 @@ snapshots: env-paths@2.2.1: {} + environment@1.1.0: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -21032,6 +21493,8 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + es-toolkit@1.39.8: {} + es6-error@4.1.1: {} esbuild-register@3.6.0(esbuild@0.25.5): @@ -21102,6 +21565,8 @@ snapshots: escape-string-regexp@1.0.5: {} + escape-string-regexp@2.0.0: {} + escape-string-regexp@4.0.0: {} escape-string-regexp@5.0.0: {} @@ -21502,6 +21967,10 @@ snapshots: fft.js@4.0.4: {} + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 @@ -21748,6 +22217,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.3.0: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -22226,6 +22697,8 @@ snapshots: indent-string@4.0.0: {} + indent-string@5.0.0: {} + inflight@1.0.6: dependencies: once: 1.4.0 @@ -22233,6 +22706,80 @@ snapshots: inherits@2.0.4: {} + ink-confirm-input@2.0.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1): + dependencies: + ink: 6.1.0(@types/react@19.1.9)(react@19.1.1) + ink-text-input: 3.3.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1) + prop-types: 15.8.1 + react: 19.1.1 + yn: 3.1.1 + + ink-select-input@6.2.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1): + dependencies: + figures: 6.1.0 + ink: 6.1.0(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + to-rotated: 1.0.0 + + ink-spinner@5.0.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1): + dependencies: + cli-spinners: 2.9.2 + ink: 6.1.0(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + + ink-table@3.1.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1): + dependencies: + ink: 6.1.0(@types/react@19.1.9)(react@19.1.1) + object-hash: 2.2.0 + react: 19.1.1 + + ink-text-input@3.3.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1): + dependencies: + chalk: 3.0.0 + ink: 6.1.0(@types/react@19.1.9)(react@19.1.1) + prop-types: 15.8.1 + react: 19.1.1 + + ink-text-input@6.0.0(ink@6.1.0(@types/react@19.1.9)(react@19.1.1))(react@19.1.1): + dependencies: + chalk: 5.4.1 + ink: 6.1.0(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + type-fest: 4.41.0 + + ink@6.1.0(@types/react@19.1.9)(react@19.1.1): + dependencies: + '@alcalzone/ansi-tokenize': 0.1.3 + ansi-escapes: 7.0.0 + ansi-styles: 6.2.1 + auto-bind: 5.0.1 + chalk: 5.4.1 + cli-boxes: 3.0.0 + cli-cursor: 4.0.0 + cli-truncate: 4.0.0 + code-excerpt: 4.0.0 + es-toolkit: 1.39.8 + indent-string: 5.0.0 + is-in-ci: 1.0.0 + patch-console: 2.0.0 + react: 19.1.1 + react-reconciler: 0.32.0(react@19.1.1) + scheduler: 0.23.2 + signal-exit: 3.0.7 + slice-ansi: 7.1.0 + stack-utils: 2.0.6 + string-width: 7.2.0 + type-fest: 4.41.0 + widest-line: 5.0.0 + wrap-ansi: 9.0.0 + ws: 8.18.3 + yoga-layout: 3.2.1 + optionalDependencies: + '@types/react': 19.1.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + inline-style-parser@0.2.4: {} install@0.13.0: {} @@ -22329,6 +22876,12 @@ snapshots: is-fullwidth-code-point@3.0.0: {} + is-fullwidth-code-point@4.0.0: {} + + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.3.0 + is-generator-function@1.1.0: dependencies: call-bound: 1.0.4 @@ -22344,6 +22897,8 @@ snapshots: is-hotkey@0.2.0: {} + is-in-ci@1.0.0: {} + is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 @@ -22416,6 +22971,8 @@ snapshots: is-typedarray@1.0.0: {} + is-unicode-supported@2.1.0: {} + is-weakmap@2.0.2: {} is-weakref@1.1.1: @@ -22524,7 +23081,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 24.0.10 + '@types/node': 24.2.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -22539,6 +23096,11 @@ snapshots: jotai: 2.8.4(@types/react@18.3.23)(react@18.3.1) optics-ts: 2.4.1 + jotai-optics@0.4.0(jotai@2.8.4(react@19.1.1))(optics-ts@2.4.1): + dependencies: + jotai: 2.8.4(react@19.1.1) + optics-ts: 2.4.1 + jotai-x@2.3.3(@types/react@18.3.23)(jotai@2.8.4(@types/react@18.3.23)(react@18.3.1))(react@18.3.1): dependencies: jotai: 2.8.4(@types/react@18.3.23)(react@18.3.1) @@ -22546,11 +23108,21 @@ snapshots: '@types/react': 18.3.23 react: 18.3.1 + jotai-x@2.3.3(jotai@2.8.4(react@19.1.1))(react@19.1.1): + dependencies: + jotai: 2.8.4(react@19.1.1) + optionalDependencies: + react: 19.1.1 + jotai@2.8.4(@types/react@18.3.23)(react@18.3.1): optionalDependencies: '@types/react': 18.3.23 react: 18.3.1 + jotai@2.8.4(react@19.1.1): + optionalDependencies: + react: 19.1.1 + joycon@3.1.1: {} js-base64@3.7.2: {} @@ -23436,6 +24008,8 @@ snapshots: mime@3.0.0: {} + mimic-fn@2.1.0: {} + mimic-fn@4.0.0: {} min-indent@1.0.1: {} @@ -23665,6 +24239,32 @@ snapshots: transitivePeerDependencies: - '@types/node' + msw@2.10.4(@types/node@24.2.0)(typescript@5.8.3): + dependencies: + '@bundled-es-modules/cookie': 2.0.1 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 5.1.13(@types/node@24.2.0) + '@mswjs/interceptors': 0.39.2 + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.6 + graphql: 16.11.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + strict-event-emitter: 0.5.1 + type-fest: 4.41.0 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - '@types/node' + optional: true + multipasta@0.2.7: {} mustache@4.2.0: {} @@ -23867,6 +24467,8 @@ snapshots: object-assign@4.1.1: {} + object-hash@2.2.0: {} + object-inspect@1.13.4: {} object-is@1.1.6: @@ -23928,6 +24530,10 @@ snapshots: dependencies: fn.name: 1.1.0 + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + onetime@6.0.0: dependencies: mimic-fn: 4.0.0 @@ -24116,6 +24722,8 @@ snapshots: no-case: 3.0.4 tslib: 2.8.1 + patch-console@2.0.0: {} + path-browserify@1.0.1: {} path-exists@4.0.0: {} @@ -24265,11 +24873,11 @@ snapshots: mlly: 1.7.4 pathe: 2.0.3 - platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)): + platejs@49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)): dependencies: - '@platejs/core': 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + '@platejs/core': 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) '@platejs/slate': 49.2.4 - '@platejs/utils': 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) + '@platejs/utils': 49.2.4(@types/react@18.3.23)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@18.3.1)) '@udecode/react-hotkeys': 37.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@udecode/react-utils': 49.0.15(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@udecode/utils': 47.2.7 @@ -24284,6 +24892,25 @@ snapshots: - slate-dom - use-sync-external-store + platejs@49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)): + dependencies: + '@platejs/core': 49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)) + '@platejs/slate': 49.2.4 + '@platejs/utils': 49.2.4(immer@10.1.1)(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0)(use-sync-external-store@1.5.0(react@19.1.1)) + '@udecode/react-hotkeys': 37.0.0(react-dom@18.3.1(react@19.1.1))(react@19.1.1) + '@udecode/react-utils': 49.0.15(react-dom@18.3.1(react@19.1.1))(react@19.1.1) + '@udecode/utils': 47.2.7 + react: 19.1.1 + react-dom: 18.3.1(react@19.1.1) + transitivePeerDependencies: + - '@types/react' + - immer + - react-native + - scheduler + - slate + - slate-dom + - use-sync-external-store + player.style@0.1.9(react@18.3.1): dependencies: media-chrome: 4.11.1(react@18.3.1) @@ -24479,7 +25106,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 24.0.10 + '@types/node': 24.2.0 long: 5.3.2 proxy-addr@2.0.7: @@ -24634,6 +25261,12 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 + react-dom@18.3.1(react@19.1.1): + dependencies: + loose-envify: 1.4.0 + react: 19.1.1 + scheduler: 0.23.2 + react-hotkeys-hook@5.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: react: 18.3.1 @@ -24686,6 +25319,11 @@ snapshots: transitivePeerDependencies: - '@types/react-dom' + react-reconciler@0.32.0(react@19.1.1): + dependencies: + react: 19.1.1 + scheduler: 0.26.0 + react-refresh@0.14.2: {} react-remove-scroll-bar@2.3.8(@types/react@18.3.23)(react@18.3.1): @@ -24724,19 +25362,30 @@ snapshots: transitivePeerDependencies: - '@types/react' - react-tracked@1.7.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2): + react-tracked@1.7.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0): dependencies: proxy-compare: 2.6.0 react: 18.3.1 - scheduler: 0.23.2 - use-context-selector: 1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2) + scheduler: 0.26.0 + use-context-selector: 1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0) optionalDependencies: react-dom: 18.3.1(react@18.3.1) + react-tracked@1.7.14(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0): + dependencies: + proxy-compare: 2.6.0 + react: 19.1.1 + scheduler: 0.26.0 + use-context-selector: 1.4.4(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0) + optionalDependencies: + react-dom: 18.3.1(react@19.1.1) + react@18.3.1: dependencies: loose-envify: 1.4.0 + react@19.1.1: {} + reactcss@1.2.3(react@18.3.1): dependencies: lodash: 4.17.21 @@ -24960,6 +25609,11 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + restore-cursor@4.0.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + retry-request@7.0.2: dependencies: '@types/request': 2.48.12 @@ -25092,6 +25746,8 @@ snapshots: dependencies: loose-envify: 1.4.0 + scheduler@0.26.0: {} + schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 @@ -25325,11 +25981,34 @@ snapshots: slate-dom: 0.116.0(slate@0.117.0) tiny-invariant: 1.3.1 + slate-react@0.117.1(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(slate-dom@0.116.0(slate@0.117.0))(slate@0.117.0): + dependencies: + '@juggle/resize-observer': 3.4.0 + direction: 1.0.4 + is-hotkey: 0.2.0 + lodash: 4.17.21 + react: 19.1.1 + react-dom: 18.3.1(react@19.1.1) + scroll-into-view-if-needed: 3.1.0 + slate: 0.117.0 + slate-dom: 0.116.0(slate@0.117.0) + tiny-invariant: 1.3.1 + slate@0.117.0: dependencies: immer: 10.1.1 tiny-warning: 1.0.3 + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + slick@1.12.2: {} slug@6.1.0: {} @@ -25480,6 +26159,10 @@ snapshots: stack-trace@0.0.10: {} + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + stackback@0.0.2: {} stackframe@1.3.4: {} @@ -25541,6 +26224,12 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 + string-width@7.2.0: + dependencies: + emoji-regex: 10.4.0 + get-east-asian-width: 1.3.0 + strip-ansi: 7.1.0 + string.prototype.includes@2.0.1: dependencies: call-bind: 1.0.8 @@ -25713,11 +26402,11 @@ snapshots: magic-string: 0.30.17 zimmerframe: 1.1.2 - swr@2.3.4(react@18.3.1): + swr@2.3.4(react@19.1.1): dependencies: dequal: 2.0.3 - react: 18.3.1 - use-sync-external-store: 1.5.0(react@18.3.1) + react: 19.1.1 + use-sync-external-store: 1.5.0(react@19.1.1) swrev@4.0.0: {} @@ -25776,7 +26465,7 @@ snapshots: '@azure/identity': 4.10.2 '@azure/keyvault-keys': 4.10.0 '@js-joda/core': 5.6.5 - '@types/node': 24.0.10 + '@types/node': 24.2.0 bl: 6.1.0 iconv-lite: 0.6.3 js-md4: 0.3.2 @@ -25906,6 +26595,8 @@ snapshots: dependencies: is-number: 7.0.0 + to-rotated@1.0.0: {} + toggle-selection@1.0.6: {} toidentifier@1.0.1: {} @@ -26148,6 +26839,8 @@ snapshots: undici-types@6.21.0: {} + undici-types@7.10.0: {} + undici-types@7.8.0: {} undici@7.12.0: {} @@ -26287,23 +26980,35 @@ snapshots: optionalDependencies: '@types/react': 18.3.23 - use-context-selector@1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2): + use-context-selector@1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0): dependencies: react: 18.3.1 - scheduler: 0.23.2 + scheduler: 0.26.0 optionalDependencies: react-dom: 18.3.1(react@18.3.1) - use-context-selector@2.0.0(react@18.3.1)(scheduler@0.23.2): + use-context-selector@1.4.4(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0): + dependencies: + react: 19.1.1 + scheduler: 0.26.0 + optionalDependencies: + react-dom: 18.3.1(react@19.1.1) + + use-context-selector@2.0.0(react@18.3.1)(scheduler@0.26.0): dependencies: react: 18.3.1 - scheduler: 0.23.2 + scheduler: 0.26.0 use-deep-compare@1.3.0(react@18.3.1): dependencies: dequal: 2.0.3 react: 18.3.1 + use-deep-compare@1.3.0(react@19.1.1): + dependencies: + dequal: 2.0.3 + react: 19.1.1 + use-file-picker@2.1.4(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react@18.3.1): dependencies: '@types/react': 18.3.23 @@ -26336,10 +27041,18 @@ snapshots: dependencies: react: 18.3.1 + use-sync-external-store@1.4.0(react@19.1.1): + dependencies: + react: 19.1.1 + use-sync-external-store@1.5.0(react@18.3.1): dependencies: react: 18.3.1 + use-sync-external-store@1.5.0(react@19.1.1): + dependencies: + react: 19.1.1 + util-deprecate@1.0.2: {} util@0.12.5: @@ -26444,6 +27157,27 @@ snapshots: - tsx - yaml + vite-node@3.2.4(@types/node@24.2.0)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 6.3.5(@types/node@24.2.0)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vite-tsconfig-paths@6.0.0-beta.3(typescript@5.8.3)(vite@7.0.5(@types/node@24.0.10)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)): dependencies: debug: 4.4.1 @@ -26455,6 +27189,17 @@ snapshots: - supports-color - typescript + vite-tsconfig-paths@6.0.0-beta.3(typescript@5.8.3)(vite@7.0.5(@types/node@24.2.0)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)): + dependencies: + debug: 4.4.1 + globrex: 0.1.2 + tsconfck: 3.1.6(typescript@5.8.3) + optionalDependencies: + vite: 7.0.5(@types/node@24.2.0)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + - typescript + vite@6.3.5(@types/node@20.19.4)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0): dependencies: esbuild: 0.25.5 @@ -26491,6 +27236,24 @@ snapshots: tsx: 4.20.3 yaml: 2.8.0 + vite@6.3.5(@types/node@24.2.0)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0): + dependencies: + esbuild: 0.25.5 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.6 + rollup: 4.44.2 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 24.2.0 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + sass: 1.89.2 + terser: 5.43.1 + tsx: 4.20.3 + yaml: 2.8.0 + vite@7.0.5(@types/node@24.0.10)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0): dependencies: esbuild: 0.25.5 @@ -26509,6 +27272,24 @@ snapshots: tsx: 4.20.3 yaml: 2.8.0 + vite@7.0.5(@types/node@24.2.0)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0): + dependencies: + esbuild: 0.25.5 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.6 + rollup: 4.44.2 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 24.2.0 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + sass: 1.89.2 + terser: 5.43.1 + tsx: 4.20.3 + yaml: 2.8.0 + vitest@3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@20.19.4)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.4(@types/node@20.19.4)(typescript@5.8.3))(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 @@ -26599,6 +27380,51 @@ snapshots: - tsx - yaml + vitest@3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.2.0)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.2.0)(typescript@5.8.3))(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0): + dependencies: + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(msw@2.10.4(@types/node@24.2.0)(typescript@5.8.3))(vite@6.3.5(@types/node@20.19.4)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + debug: 4.4.1 + expect-type: 1.2.2 + magic-string: 0.30.17 + pathe: 2.0.3 + picomatch: 4.0.2 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.14 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 6.3.5(@types/node@24.2.0)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@24.2.0)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.2)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@edge-runtime/vm': 3.2.0 + '@types/debug': 4.1.12 + '@types/node': 24.2.0 + '@vitest/ui': 3.2.4(vitest@3.2.4) + jsdom: 26.1.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vm-browserify@1.1.2: {} vscode-jsonrpc@8.2.0: {} @@ -26819,6 +27645,10 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + widest-line@5.0.0: + dependencies: + string-width: 7.2.0 + winston-transport@4.9.0: dependencies: logform: 2.7.0 @@ -26863,6 +27693,12 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.2.0 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} write-file-atomic@3.0.3: @@ -26935,12 +27771,16 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yn@3.1.1: {} + yocto-queue@0.1.0: {} yocto-queue@1.2.1: {} yoctocolors-cjs@2.1.2: {} + yoga-layout@3.2.1: {} + youtube-video-element@1.6.1: {} zimmerframe@1.1.2: {} @@ -26965,12 +27805,12 @@ snapshots: zod@3.25.1: {} - zustand-x@6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)(zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1))): + zustand-x@6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0)(zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1))): dependencies: immer: 10.1.1 lodash.mapvalues: 4.6.0 mutative: 1.1.0 - react-tracked: 1.7.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2) + react-tracked: 1.7.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.26.0) use-sync-external-store: 1.4.0(react@18.3.1) zustand: 5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) transitivePeerDependencies: @@ -26979,6 +27819,20 @@ snapshots: - react-native - scheduler + zustand-x@6.1.0(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0)(zustand@5.0.7(immer@10.1.1)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1))): + dependencies: + immer: 10.1.1 + lodash.mapvalues: 4.6.0 + mutative: 1.1.0 + react-tracked: 1.7.14(react-dom@18.3.1(react@19.1.1))(react@19.1.1)(scheduler@0.26.0) + use-sync-external-store: 1.4.0(react@19.1.1) + zustand: 5.0.7(immer@10.1.1)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + transitivePeerDependencies: + - react + - react-dom + - react-native + - scheduler + zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)): optionalDependencies: '@types/react': 18.3.23 @@ -26986,4 +27840,10 @@ snapshots: react: 18.3.1 use-sync-external-store: 1.5.0(react@18.3.1) + zustand@5.0.7(immer@10.1.1)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): + optionalDependencies: + immer: 10.1.1 + react: 19.1.1 + use-sync-external-store: 1.5.0(react@19.1.1) + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5b6138ed2..26a23ef44 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -8,6 +8,7 @@ packages: - "apps/electric-server" - "apps/trigger" - "apps/api" + - "apps/cli" catalog: "@mastra/core": "^0.10.8" @@ -25,7 +26,7 @@ catalog: hono: "^4.8.0" pg: "^8.16.2" platejs: "^49.2.4" - "remark-gfm": "^4.0.1" + "remark-gfm": "^4.0.1" tsup: "^8.5.0" tsx: "^4.20.0" uuid: "^11.0.0"