Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ objectstack-ai/spec/
├── apps/
│ ├── studio/ # 🎨 Studio UI (React + Hono, web-based)
│ └── docs/ # 📖 Documentation site (Fumadocs + Next.js)
│ ├── docs/ # 📖 Documentation site (Fumadocs + Next.js)
│ └── server/ # 🚀 Production server (multi-app orchestration)
├── examples/ # 📚 Reference implementations
│ ├── app-todo/ # Beginner: simple CRUD
│ ├── app-crm/ # Advanced: full CRM with relations
│ ├── app-host/ # Host application bootstrap
│ └── plugin-bi/ # Plugin example: BI dashboard
├── skills/ # 🤖 AI skill definitions (for Copilot/Cursor)
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Removed `value` field from data API responses** — The `findData` protocol
implementation no longer returns the deprecated `value` field alongside `records`.
Only `records` is returned, matching the `FindDataResponseSchema` spec. All
downstream consumers (Studio, app-host example, tests) updated to use `records`
downstream consumers (Studio, server example, tests) updated to use `records`
exclusively. OData-specific responses (`ODataResponseSchema`) retain `value` per
the OData v4 standard — protocol-to-OData adaptation is handled in the HTTP
dispatch layer.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ os doctor # Check environment health
| :--- | :--- | :--- |
| [`@example/app-todo`](examples/app-todo) | Task management app — objects, views, dashboards, flows | Beginner |
| [`@example/app-crm`](examples/app-crm) | Enterprise CRM — accounts, contacts, opportunities, leads | Intermediate |
| [`@example/app-host`](examples/app-host) | Server host — multi-app orchestration with plugins | Advanced |
| [`@objectstack/server`](apps/server) | Production server — multi-app orchestration with plugins | Advanced |
| [`@example/plugin-bi`](examples/plugin-bi) | BI plugin — analytics objects and reports | Intermediate |

## Codebase Metrics
Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@ Final polish and advanced features.

- [x] **app-todo** — Beginner reference (objects, actions, flows, dashboards, reports, i18n) ✅
- [x] **app-crm** — Enterprise reference (10 objects, 5 AI agents, 4 RAG pipelines, security profiles) ✅
- [x] **app-host**Multi-app orchestration pattern ✅
- [x] **server** (formerly app-host)Production server with multi-app orchestration pattern ✅
- [ ] **plugin-bi** — Business Intelligence plugin (currently a stub/placeholder)
- [ ] **app-hrm** — Human Resource Management example
- [ ] **app-project** — Project Management example
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 7 additions & 7 deletions examples/app-host/DEPLOYMENT.md → apps/server/DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Deploying App Host to Vercel
# Deploying ObjectStack Server to Vercel

This example demonstrates how to deploy the ObjectStack app-host to Vercel using Hono.
This guide demonstrates how to deploy the ObjectStack production server to Vercel using Hono.

## Prerequisites

Expand All @@ -26,9 +26,9 @@ You can get these credentials from [Turso Dashboard](https://turso.tech/).
npm i -g vercel
```

2. Navigate to the app-host directory:
2. Navigate to the server directory:
```bash
cd examples/app-host
cd apps/server
```

3. Deploy to Vercel:
Expand All @@ -46,7 +46,7 @@ You can get these credentials from [Turso Dashboard](https://turso.tech/).
### Option 2: Using Vercel Dashboard

1. Import the repository to Vercel
2. Set the root directory to `examples/app-host`
2. Set the root directory to `apps/server`
3. Add environment variables in the project settings
4. Deploy

Expand All @@ -64,7 +64,7 @@ The build is configured in `vercel.json`:
## How It Works

1. **Build Process** (`scripts/build-vercel.sh`):
- Builds both app-host and Studio using Turbo
- Builds both server and Studio using Turbo
- Studio is built with `VITE_RUNTIME_MODE=server` (set in vercel.json build.env)
- Bundles the server code using esbuild (`scripts/bundle-api.mjs`)
- Copies Studio dist files to `public/` for static file serving
Expand Down Expand Up @@ -95,7 +95,7 @@ The build is configured in `vercel.json`:
The deployment follows Vercel's serverless function pattern:

```
examples/app-host/
apps/server/
├── api/
│ ├── [[...route]].js # Committed entry point
│ └── _handler.js # Generated bundle (not committed)
Expand Down
4 changes: 2 additions & 2 deletions examples/app-host/README.md → apps/server/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# ObjectStack Example Server
# ObjectStack Production Server

This is a reference implementation of the ObjectStack Server Protocol (Kernel).
It demonstrates how to build a metadata-driven backend that dynamically loads object definitions from plugins and automatically generates REST APIs.

## Deployment

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/objectstack-ai/framework/tree/main/examples/app-host&project-name=objectstack-app-host&repository-name=objectstack-app-host)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/objectstack-ai/framework/tree/main/apps/server&project-name=objectstack-server&repository-name=objectstack-server)

See [DEPLOYMENT.md](./DEPLOYMENT.md) for detailed deployment instructions.

Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { AppPlugin, DriverPlugin } from '@objectstack/runtime';
import { ObjectQLPlugin } from '@objectstack/objectql';
import { InMemoryDriver } from '@objectstack/driver-memory';
import { AuthPlugin } from '@objectstack/plugin-auth';
import CrmApp from '../app-crm/objectstack.config';
import TodoApp from '../app-todo/objectstack.config';
import BiPluginManifest from '../plugin-bi/objectstack.config';
import CrmApp from '../../examples/app-crm/objectstack.config';
import TodoApp from '../../examples/app-todo/objectstack.config';
import BiPluginManifest from '../../examples/plugin-bi/objectstack.config';

// App Host Example
// Production Server
// This project acts as a "Platform Server" that loads multiple apps and plugins.
// It effectively replaces the manual composition in `src/index.ts`.

Expand All @@ -24,11 +24,11 @@ const authPlugin = new AuthPlugin({

export default defineStack({
manifest: {
id: 'com.example.host',
namespace: 'host',
name: 'App Host',
id: 'com.objectstack.server',
namespace: 'server',
name: 'ObjectStack Server',
version: '1.0.0',
description: 'Host application aggregating CRM, Todo and BI plugins',
description: 'Production server aggregating CRM, Todo and BI plugins',
type: 'app',
},

Expand Down Expand Up @@ -92,11 +92,11 @@ export default defineStack({
*/
export const PreviewHostExample = defineStack({
manifest: {
id: 'com.example.host-preview',
namespace: 'host',
name: 'App Host Preview',
id: 'com.objectstack.server-preview',
namespace: 'server',
name: 'ObjectStack Server Preview',
version: '1.0.0',
description: 'Host application in preview/demo mode — bypasses login, simulates admin user',
description: 'Production server in preview/demo mode — bypasses login, simulates admin user',
type: 'app',
},

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@example/app-host",
"name": "@objectstack/server",
"version": "4.0.3",
"license": "Apache-2.0",
"type": "module",
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail

# Build script for Vercel deployment of @example/app-host.
# Build script for Vercel deployment of @objectstack/server.
#
# Follows the Vercel deployment pattern:
# - api/[[...route]].js is committed to the repo (Vercel detects it pre-build)
Expand All @@ -14,13 +14,13 @@ set -euo pipefail
# 2. Bundle the API serverless function (→ api/_handler.js)
# 3. Copy studio dist files to public/ for UI serving

echo "[build-vercel] Starting app-host build..."
echo "[build-vercel] Starting server build..."

# 1. Build the project with turbo (from monorepo root)
# This builds both app-host and studio
# This builds both server and studio
cd ../..
pnpm turbo run build --filter=@example/app-host --filter=@objectstack/studio
cd examples/app-host
pnpm turbo run build --filter=@objectstack/server --filter=@objectstack/studio
cd apps/server

# 2. Bundle API serverless function
node scripts/bundle-api.mjs
Expand All @@ -29,8 +29,8 @@ node scripts/bundle-api.mjs
echo "[build-vercel] Copying studio dist to public/..."
rm -rf public
mkdir -p public
if [ -d "../../apps/studio/dist" ]; then
cp -r ../../apps/studio/dist/* public/
if [ -d "../studio/dist" ]; then
cp -r ../studio/dist/* public/
echo "[build-vercel] ✓ Copied studio dist to public/"
else
echo "[build-vercel] ⚠ Studio dist not found (skipped)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* npm packages), so the deployed function is self-contained. Only packages
* with native bindings are kept external.
*
* Run from the examples/app-host directory during the Vercel build step.
* Run from the apps/server directory during the Vercel build step.
*/

import { build } from 'esbuild';
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion apps/studio/.env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Environment Variables for Development
# Copy this file to .env.local and customize
#
# NOTE: .env.production is used for production builds (e.g., app-host deployment)
# NOTE: .env.production is used for production builds (e.g., server deployment)

# Runtime Mode: 'msw' (default for dev) | 'server'
# - 'msw': Mock Service Worker with in-browser kernel (recommended for local dev)
Expand Down
10 changes: 5 additions & 5 deletions apps/studio/.env.production
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Production Environment Configuration
# This file is used during production builds (vite build)
#
# When Studio is deployed as part of app-host (examples/app-host),
# it should run in server mode and connect to the app-host API server
# When Studio is deployed as part of the server (apps/server),
# it should run in server mode and connect to the server API
# instead of using MSW (Mock Service Worker).

# Runtime Mode: 'server' for production deployment
# - 'server': Connect to real ObjectStack server (app-host API)
# - 'server': Connect to real ObjectStack server API
# - 'msw': Mock Service Worker mode (browser-based kernel, for local dev)
VITE_RUNTIME_MODE=server

# Server URL: Empty string for same-origin (app-host serves both UI and API)
# Server URL: Empty string for same-origin (server serves both UI and API)
# The client SDK will use relative URLs (/api/v1/...)
# Empty string = same origin (recommended for app-host deployment)
# Empty string = same origin (recommended for server deployment)
VITE_SERVER_URL=
29 changes: 13 additions & 16 deletions content/docs/getting-started/examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { CheckSquare, Building2, BarChart3, Server } from 'lucide-react';

# Example Apps

The monorepo includes 4 ready-to-run examples that progressively demonstrate ObjectStack features — from a simple Todo app to a full enterprise CRM.
The monorepo includes 3 ready-to-run examples that progressively demonstrate ObjectStack features — from a simple Todo app to a full enterprise CRM.

<Cards>
<Card
Expand All @@ -25,13 +25,12 @@ The monorepo includes 4 ready-to-run examples that progressively demonstrate Obj
title="plugin-bi"
description="A reusable plugin template. Shows how to package metadata for distribution."
/>
<Card
icon={<Server />}
title="app-host"
description="Platform server that loads multiple apps. Demonstrates multi-app composition."
/>
</Cards>

<Callout type="info">
**Looking for the production server example?** It has been moved to [`apps/server/`](../../apps/server/) — see the [Server documentation](../../apps/server/README.md) for multi-app orchestration and deployment.
</Callout>

---

## Quick Run
Expand Down Expand Up @@ -274,25 +273,23 @@ new AppPlugin(BiPlugin) // Load into host

---

## app-host — Multi-App Composition
## Multi-App Composition Pattern

**Path:** `examples/app-host/`

Demonstrates the **Platform Server** pattern: one host loading multiple apps and plugins. This is how you'd run ObjectStack in production with multiple teams' apps.
The production server at [`apps/server/`](../../apps/server/) demonstrates the **Platform Server** pattern: one host loading multiple apps and plugins. This is how you'd run ObjectStack in production with multiple teams' apps.

```typescript
// examples/app-host/objectstack.config.ts
// apps/server/objectstack.config.ts
import { defineStack } from '@objectstack/spec';
import { AppPlugin, DriverPlugin } from '@objectstack/runtime';
import { ObjectQLPlugin } from '@objectstack/objectql';
import { InMemoryDriver } from '@objectstack/driver-memory';
import CrmApp from '../app-crm/objectstack.config';
import TodoApp from '../app-todo/objectstack.config';
import BiPlugin from '../plugin-bi/objectstack.config';
import CrmApp from '../examples/app-crm/objectstack.config';
import TodoApp from '../examples/app-todo/objectstack.config';
import BiPlugin from '../examples/plugin-bi/objectstack.config';

export default defineStack({
manifest: {
id: 'app-host',
id: 'com.objectstack.server',
version: '1.0.0',
type: 'app',
},
Expand Down Expand Up @@ -321,7 +318,7 @@ The double-underscore `__` separator prevents collisions when multiple apps defi
### Run It

```bash
cd examples/app-host
cd apps/server
pnpm dev # Loads all 3 apps on one server
```

Expand Down
4 changes: 2 additions & 2 deletions docs/DX_ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ This roadmap prioritizes improvements based on the **"Time to First Wow"** metri

- [x] Create StackBlitz starter template from `app-todo`
- [x] Add "Try Online" button to spec README.md and docs site hero
- [x] Add "How to Run" section to each example README (app-todo, app-crm, app-host, plugin-bi)
- [x] Add "How to Run" section to each example README (app-todo, app-crm, server, plugin-bi)
- [x] Add prerequisites section to getting-started docs
- [x] Create first-run troubleshooting page
- [x] Implement `create-objectstack` CLI wizard with 3 templates
- [ ] Record 5-minute getting-started video
- [x] Fix `examples/README.md`: remove `minimal-auth` ghost reference, update metadata
- [x] Fix `plugin-bi` example: add README.md, add package.json scripts
- [x] Fix `app-host` README: use `pnpm dev` instead of `npm run dev`
- [x] Fix `server` (formerly app-host) README: use `pnpm dev` instead of `npm run dev`

</details>

Expand Down
Loading
Loading