diff --git a/README.md b/README.md index 147dd3f3a..6b949820d 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,103 @@ # ObjectStack - [](./LICENSE) - +  -> **A metadata protocol and TypeScript toolkit for AI-native business apps.** Describe your objects, permissions, workflows, APIs, UI, and AI tools once as typed, version-controlled Zod metadata — and ObjectStack derives the TypeScript types, REST API, client SDK, UI, and MCP tools from that single definition. +> ## AI writes the app. ObjectStack is what it writes. +> +> The open target format and runtime for AI-written business apps. Your coding +> agent writes models, UI, workflows, and permissions as compact typed metadata — +> often around 1% of a traditional codebase — and strict TypeScript, Zod schemas, +> and a validation gate catch its mistakes at authoring time. The runtime derives +> the database, REST API, UI, and MCP server, and enforces permissions and audit +> on every call. -This repo is the **framework**: the protocol, kernel, SDK, CLI, and production runtime you build — and ship — with. `os start` or the official Docker image [`ghcr.io/objectstack-ai/objectstack`](./docker) runs your compiled app in production, Console and governance included, entirely on open source. · Try a live app in ~30s on [StackBlitz](https://stackblitz.com/github/objectstack-ai/hotcrm) (no install). +`~1% code surface` · `Typed, validated, governed` · `Self-host anywhere` · Apache-2.0
-
One typed definition → TypeScript types, REST API, client SDK, UI, and MCP tools.
+
One typed definition → database · REST API · client SDK · UI · MCP tools.
+
+
+
Prefer clicking? Studio authors the same metadata visually — same artifacts, same gate.
-Everything is **typed metadata**. Define a business object once — fields, a color-coded picklist, validation — all declarative: +## What can it actually build? + +Point an agent at an empty repo and you get a one-off codebase: every screen +hand-invented, every mistake yours to find at runtime. ObjectStack gives the +agent a **vocabulary** instead — typed, validated primitives for what enterprise +software is actually made of. The agent composes the definition; the runtime +already knows how to run it. + +| | Capability | +| :--- | :--- | +| **Objects & fields** | Typed schemas with relations, validation, formulas, files | +| **Permissions** | RBAC plus row- and field-level security, enforced by the runtime | +| **Automation** | DAG flows, record triggers, scheduled jobs, webhooks | +| **Approvals** | Multi-step chains with queues and a full audit trail | +| **Views** | Lists, kanban, calendars, gantt, galleries — declared, not coded | +| **Dashboards & reports** | Charts, aggregations, KPIs bound to live data | +| **Actions** | Permission-checked buttons and server operations | +| **APIs & SDK** | Generated REST + realtime endpoints, typed client SDK | +| **AI tools** | Every object and exposed action doubles as a governed MCP tool | +| **Translations** | Labels and UI text as metadata, per locale | +| **Seed data** | Fixtures and demo datasets that ship with the app | +| **Datasources** | PostgreSQL, MySQL, SQLite, MongoDB, or in-memory | + +Here's the shape of it — one object, and the database table, REST API, UI views, +and MCP tools all follow: ```ts import { ObjectSchema, Field } from '@objectstack/spec/data'; -export const Task = ObjectSchema.create({ - name: 'todo_task', - label: 'Task', +export const Ticket = ObjectSchema.create({ + name: 'support_desk_ticket', + label: 'Ticket', + sharingModel: 'private', // org-wide default — the security gate requires it fields: { subject: Field.text({ label: 'Subject', required: true, searchable: true }), status: Field.select({ label: 'Status', required: true, options: [ - { label: 'In Progress', value: 'in_progress', color: '#3B82F6' }, - { label: 'Completed', value: 'completed', color: '#10B981' }, + { label: 'Open', value: 'open', color: '#3B82F6', default: true }, + { label: 'Resolved', value: 'resolved', color: '#10B981' }, ], }), due_date: Field.date({ label: 'Due Date' }), @@ -62,84 +105,82 @@ export const Task = ObjectSchema.create({ }); ``` -From that single schema, ObjectStack derives the database table, an auto-generated REST API and typed client SDK, UI views (list, board, calendar, Gantt…), and MCP tools for agents — all from one definition. +## Why the mistakes don't ship -Prefer clicking? Author the same metadata visually in **Studio** — objects, relations, validation, and flows — and it compiles to the exact same artifacts: +"AI writes it" is only useful if AI's mistakes don't reach production. Four gates +stand between the agent and your users: -
-
-
-
Model objects as typed metadata · Automate with visual flows — both produce the same analyzable metadata.
- -> **Want to see it running?** `os dev` serves the live Console locally, and `os start` (or the official Docker image) ships the same Console to production — dashboards, boards, calendars, records, and AI working your data under your permissions. +| Gate | Catches | +| :--- | :--- | +| **Typed** | Strict TypeScript + Zod — shape errors die in the editor, seconds after the agent writes them | +| **Validated** | `os validate` rejects metadata that type-checks but would fail silently at runtime: dangling bindings, bad CEL predicates, missing security posture | +| **Reviewed** | You approve a small readable diff in the Console — not fifty thousand lines of glue | +| **Governed** | The runtime enforces permissions and audit on every call, so even a wrong app stays inside the fence | -## Key Features +The reason this works is the same reason TypeScript was the right host language: +**an agent's errors become located, corrective text it can read and fix itself**, +in seconds — instead of a silent runtime failure nobody traces back. -- **AI-native, not retrofitted** — Objects, permissions, flows, APIs, and UI are declarative typed metadata, small enough for an agent to load end-to-end. That metadata generates an automatic tool surface — REST APIs, client SDKs, UI views, and an [MCP](packages/mcp) server — so agents inspect and act through the same contracts you defined. -- **Protocol-first runtime** — Every definition starts as a Zod schema (`z.infer<>` types), compiles into versioned, self-describing JSON artifacts, and runs on a microkernel plugin system (DI container, EventBus, `init → start → destroy` lifecycle). -- **Data & framework reach** — In-memory, PostgreSQL, MySQL, SQLite, and MongoDB drivers; 7 framework adapters (Express, Fastify, Hono, NestJS, Next.js, Nuxt, SvelteKit); a client SDK with React hooks (`useQuery` / `useMutation` / `usePagination`). -- **Governance & built-ins** — better-auth, RBAC / RLS / FLS, a DAG-based automation engine, an [MCP](packages/mcp) server that exposes the app to your own AI (BYO-AI), the ObjectUI Console, and a full CLI (`os init` / `dev` / `compile` / `validate` / …). +And because the whole business system is a few hundred lines of typed metadata +rather than tens of thousands of lines of CRUD and glue, it **fits in an agent's +context window** — so the agent can load it end-to-end, reason about every +dependency, and refactor across data, API, UI, and permissions in one change. +That's the difference between AI as autocomplete and AI as a co-maintainer. -## Why AI-native? +> Your objects, permissions, and flows are your business ontology — and the +> definition layer of the AI era should be an open protocol you own. +> [Read why](https://www.objectos.ai/en/blog/ai-ontology-open-protocol/). -Most internal-tool and low-code platforms were designed for humans clicking screens. AI support is usually added later as a chat box that can call a few predefined queries. ObjectStack starts from a different assumption: **AI agents need a structured, bounded, and auditable business backend before they can safely perform real work** — and the entire business system has to be small enough to fit in an agent's context window. +## Your app is AI-operable, for free -A typical enterprise application is tens of thousands of lines of CRUD, forms, queries, permissions, and API glue spread across dozens of files. ObjectStack collapses the same surface into a few hundred lines of typed metadata — **roughly two orders of magnitude less code for a developer (or an AI agent) to read, write, and maintain.** +Because the app is typed metadata, the runtime serves it as an **MCP server** at +`/api/v1/mcp` — on by default. Point any MCP client at it and an agent can +inspect and *operate* the app you just built, under the same permissions and RLS +as a human: -The point isn't lines of code. The point is **fit in an agent's context window.** When the entire business system is small, typed, and declarative, an AI agent can load it end-to-end, reason about every dependency, and safely refactor across data, API, UI, and permissions in a single change. That turns AI from an autocomplete tool into a real co-maintainer of production business software. +```bash +claude mcp add --transport http my-app http://localhost:3000/api/v1/mcp +``` -| Dimension | Retool / Appsmith-style tools | ObjectStack | -| :--- | :--- | :--- | -| Business model | Implicit in pages, queries, and scripts | Explicit Zod `ObjectSchema` metadata | -| Code footprint | Thousands of lines of queries, JS, and UI state per app | **~100× less** — declarative metadata replaces CRUD, forms, validation, and API glue | -| Business logic | JavaScript snippets and query glue | Flows, policies, conditions, and typed metadata | -| External contract | App-specific UI state | Self-describing JSON Environment Artifact | -| Agent tools | Manually defined one by one | Generated from metadata and permissions | -| Agent reasoning | Calls predefined queries | Reads the full schema, composes safe actions, respects boundaries | -| AI maintainability | Agents must crawl sprawling app code | Whole app fits in an agent's context window | -| Governance | App-level conventions | Auth, RBAC, RLS, FLS, audit, and versioned artifacts | +Objects are exposed automatically; actions opt in with `ai: { exposed: true }`. +See [Connect an MCP Client](https://objectstack.ai/docs/ai/connect-mcp). -Described in ObjectStack and served by its runtime, this is the substrate for AI-native business apps — CRM, support, operations, and workflow agents acting on real business data without bypassing permissions or audit. +## This repo -## Quick Start +The **framework**: the protocol (`@objectstack/spec`), kernel, SDK, CLI, and the +production runtime. `os start` or the official Docker image +[`ghcr.io/objectstack-ai/objectstack`](./docker) ships your compiled app — +Console and governance included — entirely on open source. Try a live app in +~30s on [StackBlitz](https://stackblitz.com/github/objectstack-ai/hotcrm) (no +install). -### For Application Developers +Three layers sit on a microkernel: **ObjectQL** (data), **Kernel** (control), +**ObjectUI** (view). Everything starts as a Zod schema — 1,600+ of them — and +TypeScript types, JSON Schemas, REST routes, UI metadata, and agent tools are all +derived from that one source. See [ARCHITECTURE.md](./ARCHITECTURE.md). -```bash -# Create a new project -npx create-objectstack my-app -cd my-app - -# Start dev server (REST API + console UI) -pnpm dev -# → API: http://localhost:3000/api/v1/ -# → Console: http://localhost:3000/_console/ -``` +**Want it governed and hosted, with Build & Ask AI built in?** +[ObjectOS](https://www.objectos.ai) is the commercial runtime for these +definitions. -Alternatively, with the CLI installed: `os init my-app && cd my-app && os dev`. +## Ship it -Ready for production? The scaffolded project is container-ready: +The scaffolded project is container-ready: ```bash docker build -t my-app . && docker compose up -d # app + Postgres on the official runtime image ``` -See [Self-Hosted Deployment](https://objectstack.ai/docs/deployment/self-hosting) for bare Node, Kubernetes, and the secrets you must pin. +See [Self-Hosted Deployment](https://objectstack.ai/docs/deployment/self-hosting) for bare Node, Kubernetes, and the secrets you must pin — and [Build with Claude Code](https://objectstack.ai/docs/getting-started/build-with-claude-code) to run the whole loop end-to-end. -### For Framework Contributors +## Working on the framework itself ```bash -# 1. Clone and install git clone https://github.com/objectstack-ai/framework.git cd framework -pnpm install - -# 2. Build all packages -pnpm build - -# 4. Start ObjectStack Showcase -pnpm dev +pnpm install # Node 18+, pnpm 8+ (corepack enable) +pnpm build # build all packages +pnpm dev # run the showcase example (REST + Console on :3000) ``` ## Monorepo Scripts diff --git a/content/docs/automation/flows.mdx b/content/docs/automation/flows.mdx index 77034413b..e435b34c1 100644 --- a/content/docs/automation/flows.mdx +++ b/content/docs/automation/flows.mdx @@ -152,8 +152,8 @@ Each node performs a specific action in the flow. label: 'Check Status', config: { conditions: [ - { label: 'Approved', expression: "status == 'approved'" }, - { label: 'Rejected', expression: "status == 'rejected'" }, + { label: 'Approved', expression: "{status} == 'approved'" }, + { label: 'Rejected', expression: "{status} == 'rejected'" }, ], }, }