dooor
v0.8.8
Published
Dooor CLI - CortexDB schema management and tooling
Maintainers
Readme
DOOOR CLI
██████╗ ██████╗ ██████╗ ██████╗ ██████╗
██╔══██╗██╔═══██╗██╔═══██╗██╔═══██╗██╔══██╗
██║ ██║██║ ██║██║ ██║██║ ██║██████╔╝
██║ ██║██║ ██║██║ ██║██║ ██║██╔══██╗
██████╔╝╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║
╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝Schema Management & Developer Tooling for Dooor OS
📖 Overview
DOOOR CLI is the command-line interface for managing CortexDB schemas declaratively. It's part of the DOOOR AI Operating System – a comprehensive platform for building production-ready AI applications with built-in observability, guard rails, and data management.
What is DOOOR OS?
DOOOR OS is an end-to-end AI development platform that provides:
- CortexDB: Hybrid database (relational + vector + binary files) unified in a single API
- DOOOR AI Toolkit: Guards, evaluations, and observability for LLM applications
- DOOOR CLI: Declarative schema management with automatic migrations and type generation
- TEE Management: Privacy math proofs for AI workloads.
- VS Code Extension: Schema validation, auto-completion, and visual tools
What is CortexDB?
CortexDB unifies three data layers into one API:
- Relational (Postgres): Structured data with full SQL capabilities
- Vector (Qdrant): Semantic search with automatic embeddings
- Binary (MinIO): File storage with automatic text extraction & chunking
Perfect for RAG systems, chatbots, document processing, and AI-powered applications.
🎯 Why DOOOR CLI?
Manage your CortexDB schemas like code – declarative, version-controlled, and automatically migrated.
The Problem
Managing database schemas via HTTP APIs is:
- ❌ Error-prone: Manual API calls, no validation before execution
- ❌ Not version-controlled: Schema changes aren't tracked in Git
- ❌ No type safety: No TypeScript types generated automatically
- ❌ Hard to collaborate: Team members can't review schema changes
The Solution
DOOOR CLI provides:
- ✅ Declarative YAML schemas: Human-readable, git-friendly
- ✅ Automatic migrations: Safe diff → apply workflow
- ✅ Type generation: Auto-generated TypeScript types with full IDE autocomplete
- ✅ Validation: Catch errors before applying changes
- ✅ CI/CD ready: Integrate with GitHub Actions, GitLab CI, etc.
🚀 Quick Start
Installation
npm install --save-dev dooorOr use directly with npx:
npx dooor --helpBasic Usage
You can define schemas using YAML or TypeScript decorators (or both!).
Option 1: YAML Schema
Create dooor/schemas/users.yaml:
name: users
description: User profiles for our application
fields:
- name: email
type: string
required: true
unique: true
indexed: true
- name: full_name
type: string
required: true
- name: bio
type: text
vectorize: true # Automatic embeddings for semantic search
store_in: [postgres, qdrant]
- name: avatar
type: file
extract_config:
extract_text: false # Don't extract text from avatarsOption 2: TypeScript Decorators (NEW! 🎉)
Create dooor/schemas/users.ts:
import { Collection, Field } from '@dooor-ai/cortexdb/schema-decorators';
import { FieldType, StoreLocation } from '@dooor-ai/cortexdb';
@Collection({
name: "users",
description: "User profiles for our application",
})
export class User {
@Field({
type: FieldType.STRING,
required: true,
unique: true,
indexed: true,
storeIn: [StoreLocation.POSTGRES],
})
email!: string;
@Field({
type: FieldType.STRING,
required: true,
})
full_name!: string;
@Field({
type: FieldType.TEXT,
vectorize: true,
storeIn: [StoreLocation.POSTGRES, StoreLocation.QDRANT],
})
bio?: string;
@Field({
type: FieldType.FILE,
storeIn: [StoreLocation.MINIO],
extractConfig: { extract_text: false },
})
avatar?: Buffer;
}Note: TypeScript decorators give you full IDE support, type safety, and autocomplete! See SCHEMA_DECORATORS_GUIDE.md for details.
- Preview changes:
npx dooor schema diffOutput:
📊 Schema Diff: users
+ CREATE COLLECTION users
- email: string (unique, indexed)
- full_name: string
- bio: text (vectorized)
- avatar: file
Total changes: 1 collection created- Apply to CortexDB:
npx dooor schema applyOutput:
✅ Applied changes to CortexDB
📝 Generated types at dooor/generated/cortex-schema.ts- Use in TypeScript (automatic type safety!):
import { CortexClient } from '@dooor-ai/cortexdb';
const client = new CortexClient('cortexdb://api_key@host:port/database');
// ✨ Full autocomplete & type checking!
const user = await client.records.users.create({
email: '[email protected]',
full_name: 'John Doe',
bio: 'AI enthusiast and developer',
avatar: Buffer.from('...')
});
// TypeScript knows the return type automatically!
const users = await client.records.users.search({
query: 'AI developers', // Semantic search on vectorized 'bio'
limit: 10
});📚 Commands
dooor schema diff
Preview schema changes without applying them.
npx dooor schema diff
npx dooor schema diff --dir custom/path/to/schemasUse case: Review changes before applying, useful in CI/CD to show diff in PRs.
dooor schema apply
Apply schema changes to CortexDB with automatic migrations.
# Apply with default settings (auto-generates types)
npx dooor schema apply
# Apply with custom migration name
npx dooor schema apply --name add_user_bio_field
# Generate migration files without applying
npx dooor schema apply --create-only
# Skip automatic type generation
npx dooor schema apply --no-generate-typesFlags:
--name <name>: Custom migration name (default: auto-generated)--create-only: Generate migration files but don't apply--no-generate-types: Skip TypeScript type generation--dir <path>: Schema directory (default:dooor/schemas)
dooor schema generate-types
Generate TypeScript types from your schemas without applying changes.
# Generate with default output location
npx dooor schema generate-types
# Custom output path
npx dooor schema generate-types --out src/types/cortex-schema.ts
# Custom schema directory
npx dooor schema generate-types --dir custom/schemas --out custom/types.tsUse case: Regenerate types after pulling schema changes from teammates.
⚙️ Configuration
Create dooor/config.yaml in your project root:
cortexdb:
# Connection string (supports env variables)
connection: env(CORTEXDB_CONNECTION)
# Default embedding provider for vectorized fields
defaultEmbeddingProvider: default-provider
schema:
# Schema directory (default: dooor/schemas)
dir: dooor/schemas
# Type generation output (default: dooor/generated/cortex-schema.ts)
typesOut: dooor/generated/cortex-schema.tsEnvironment Variables
Create .env or .env.local:
# CortexDB connection string
CORTEXDB_CONNECTION=cortexdb://[email protected]:8000/my_database
# Or individual components
CORTEXDB_HOST=35.223.201.25
CORTEXDB_PORT=8000
CORTEXDB_API_KEY=your_api_key_here
CORTEXDB_DATABASE=my_databaseThe CLI automatically loads .env files from:
- Current working directory
- Directory containing
dooor/config.yaml
🗂️ Schema DSL Reference
Collection Structure
name: collection_name # snake_case identifier
description: Optional description
fields:
- name: field_name
type: string # string, text, int, float, boolean, date, datetime, enum, array, file, json
required: true # Default: false
indexed: true # Create Postgres index (non-array fields)
unique: true # Uniqueness constraint (string/int/float)
filterable: true # Add to Qdrant payload for filtering
vectorize: true # Auto-embed with Gemini for semantic search
store_in: [postgres, qdrant] # Storage locations
default: "default_value" # Default value
config:
embedding_model: models/text-embedding-004 # Override default
chunk_size: 800 # Text chunking size (default: 1000)
chunk_overlap: 100 # Text chunk overlap (default: 200)Field Types
| Type | Description | Example |
|------|-------------|---------|
| string | Short text (< 255 chars) | Email, name, slug |
| text | Long text content | Blog posts, descriptions |
| int | Integer number | Age, count, ID |
| float | Decimal number | Price, rating, percentage |
| boolean | True/false | Is active, published |
| date | Date only (YYYY-MM-DD) | Birth date, deadline |
| datetime | Date + time | Created at, updated at |
| enum | Fixed set of values | Status, role, category |
| array | Nested objects | Tags, addresses |
| file | Binary file (PDF, image) | Documents, avatars |
| json | Arbitrary JSON data | Metadata, settings |
File Fields
Files automatically stored in MinIO with optional text extraction:
fields:
- name: document
type: file
extract_config:
extract_text: true # Extract text from PDF/DOCX
ocr_if_needed: true # Use Gemini OCR for scanned PDFs
chunk_size: 1000 # Override default chunking
chunk_overlap: 200 # Override default overlapArray Fields (Nested Objects)
fields:
- name: addresses
type: array
schema:
- name: street
type: string
required: true
- name: city
type: string
required: true
- name: zip_code
type: string
indexed: trueStored in a dedicated table collection_addresses with foreign key.
Enum Fields
fields:
- name: status
type: enum
required: true
default: pending
values:
- pending
- approved
- rejected🔄 Workflow
Development Workflow
# 1. Edit YAML schemas
vim dooor/schemas/products.yaml
# 2. Preview changes
npx dooor schema diff
# 3. Apply to dev database
CORTEXDB_CONNECTION=cortexdb://key@dev-host/dev_db npx dooor schema apply
# 4. Test your app with new schema
npm run dev
# 5. Commit schema + generated types
git add dooor/schemas/ dooor/generated/
git commit -m "feat: add product reviews schema"CI/CD Integration
GitHub Actions Example
name: Schema Check
on:
pull_request:
paths:
- 'dooor/schemas/**'
jobs:
schema-diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Show schema diff
env:
CORTEXDB_CONNECTION: ${{ secrets.CORTEXDB_DEV }}
run: |
npx dooor schema diff > diff.txt
cat diff.txt
- name: Comment PR with diff
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const diff = fs.readFileSync('diff.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 📊 Schema Changes\n\n\`\`\`\n${diff}\n\`\`\``
});GitLab CI Example
schema_check:
stage: test
script:
- npm install
- npx dooor schema diff
only:
changes:
- dooor/schemas/**🎓 Examples
Example 1: Blog System
dooor/schemas/posts.yaml:
name: blog_posts
description: Blog posts with semantic search
fields:
- name: title
type: string
required: true
indexed: true
- name: slug
type: string
required: true
unique: true
indexed: true
- name: content
type: text
required: true
vectorize: true # Enable semantic search
store_in: [postgres, qdrant]
- name: author_email
type: string
required: true
indexed: true
- name: published_at
type: datetime
indexed: true
- name: tags
type: array
schema:
- name: tag
type: string
indexed: true
config:
chunk_size: 1200
embedding_model: models/text-embedding-004Usage:
// Search blog posts semantically
const results = await client.records.blog_posts.search({
query: 'machine learning best practices',
limit: 5
});
// Filter by tag
const mlPosts = await client.records.blog_posts.list({
filters: { tags: { tag: { $eq: 'machine-learning' } } }
});Example 2: Document Management
dooor/schemas/documents.yaml:
name: documents
description: Document storage with automatic text extraction
fields:
- name: title
type: string
required: true
indexed: true
- name: file
type: file
required: true
extract_config:
extract_text: true
ocr_if_needed: true # OCR for scanned PDFs
chunk_size: 1000
chunk_overlap: 200
- name: extracted_text
type: text
vectorize: true # Semantic search on content
store_in: [qdrant]
- name: category
type: enum
required: true
values:
- invoice
- contract
- report
- other
indexed: true
- name: uploaded_by
type: string
required: true
indexed: trueUsage:
// Upload PDF and search its content
const doc = await client.records.documents.create({
title: 'Q4 Financial Report',
file: fs.readFileSync('report.pdf'),
category: 'report',
uploaded_by: '[email protected]'
});
// Search across all document contents
const results = await client.records.documents.search({
query: 'revenue growth 2024',
filters: { category: { $eq: 'report' } },
limit: 10
});Example 3: E-commerce Products
dooor/schemas/products.yaml:
name: products
description: E-commerce products with reviews
fields:
- name: sku
type: string
required: true
unique: true
indexed: true
- name: name
type: string
required: true
indexed: true
- name: description
type: text
vectorize: true # Semantic product search
- name: price
type: float
required: true
indexed: true
- name: stock
type: int
default: 0
indexed: true
- name: images
type: array
schema:
- name: url
type: string
- name: alt_text
type: string
- name: reviews
type: array
schema:
- name: rating
type: int
required: true
- name: comment
type: text
vectorize: true # Search reviews semantically
- name: author
type: string
required: trueUsage:
// Semantic product search
const products = await client.records.products.search({
query: 'comfortable running shoes for marathon',
limit: 20
});
// Filter by price range
const affordableProducts = await client.records.products.list({
filters: {
price: { $gte: 50, $lte: 150 },
stock: { $gt: 0 }
},
orderBy: { price: 'asc' }
});🧩 TypeScript Integration
After running dooor schema apply or dooor schema generate-types, the CLI:
- Generates types at
dooor/generated/cortex-schema.ts - Creates a shim in
node_modules/@dooor-ai/cortexdb/generated/schema.d.ts - Augments SDK types so your IDE autocompletes collection names and fields
Type Safety Example
import { CortexClient } from '@dooor-ai/cortexdb';
const client = new CortexClient('...');
// ✅ IDE autocompletes collection names
client.records.users.create(/* ... */);
client.records.blog_posts.search(/* ... */);
client.records.products.list(/* ... */);
// ✅ TypeScript validates field types
await client.records.users.create({
email: '[email protected]', // ✅ string
full_name: 'John Doe', // ✅ string
age: 30, // ❌ Error: 'age' field doesn't exist in schema!
});
// ✅ Return types are fully typed
const user = await client.records.users.get('user_id');
// TypeScript knows: user.email is string, user.full_name is string, etc.
// ✅ Search results are typed
const results = await client.records.blog_posts.search({ query: '...' });
// TypeScript knows: results[0].title is string, results[0].content is string, etc.No configuration needed – it just works!
🔗 Integration with DOOOR AI Toolkit
DOOOR CLI pairs perfectly with DOOOR AI Toolkit for comprehensive AI application development:
import { CortexClient } from '@dooor-ai/cortexdb';
import { DOOORChatModel, configureObservability } from '@dooor-ai/toolkit';
import { PromptInjectionGuard, RelevanceEval } from '@dooor-ai/toolkit';
// 1. Configure observability to store traces in CortexDB
configureObservability({
backend: 'cortexdb',
url: 'cortexdb://api_key@host:port/ai_observability_db',
project: 'chatbot-prod'
});
// 2. Create LLM with guards + evals
const llm = new DOOORChatModel({
baseModel: 'gpt-4o',
guards: [new PromptInjectionGuard()],
evals: [new RelevanceEval()],
});
// 3. Store conversation in CortexDB (managed by schemas)
const client = new CortexClient('cortexdb://...');
await client.records.conversations.create({
user_id: 'user-123',
messages: [/* ... */],
created_at: new Date()
});Benefits:
- ✅ Unified platform: Data + AI observability in one place
- ✅ Schema-managed: Conversations, traces, evals all schema-controlled
- ✅ Type-safe: Full TypeScript autocomplete across the stack
📊 Advanced Features
Migration System
DOOOR CLI automatically generates migration files when applying changes:
dooor/migrations/
├── 20250114_120000_initial_schema.sql
├── 20250114_150000_add_user_bio.sql
└── 20250115_100000_create_products.sqlEach migration is:
- ✅ Timestamped: Prevents conflicts in team environments
- ✅ Reversible: Includes up + down migrations (future)
- ✅ Git-friendly: Review changes in PRs
Validation
The CLI validates schemas before applying:
npx dooor schema applyOutput (if errors):
❌ Schema Validation Failed
users.yaml:
- Field 'bio' has vectorize: true but no embedding_provider configured
- Field 'email' marked as unique but not indexed (performance issue)
Fix these issues before applying.Dependency Tracking
Schemas can reference each other (future feature):
# orders.yaml
fields:
- name: user_id
type: string
references: users.id # Foreign keyCLI ensures users collection exists before creating orders.
🤝 Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
MIT License - see LICENSE for details.
🔗 Links
- CortexDB Repository: github.com/Dooor-AI/cortex-db
- Documentation: docs/
- CortexDB TypeScript SDK: @dooor-ai/cortexdb
- CortexDB Python SDK: cortexdb-python
- DOOOR AI Toolkit: @dooor-ai/toolkit
- Issues: github.com/Dooor-AI/cortex-db/issues
🙏 Acknowledgments
Built with ❤️ by the DOOOR team for the AI development community.
Special thanks to:
- LangChain for inspiration on developer experience
- Prisma for setting the standard in schema management
- Qdrant for powerful vector search capabilities
Made with ❤️ by DOOOR.AI
