Octomind
Same model as opencode, same endpoint, same prices — octomind solved 24/25 to its 19/25, at half the cost. Open-source agent runtime: one binary, any model, runs unattended in CI. Apache 2.0.
翻譯準備中
製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Beta. The onboarding path and core APIs are stable enough to build on; some advanced features are still evolving. Pin versions for production.
A config-first stack for building admin-heavy applications with Next.js App Router — designed so you can describe features to an AI coding agent (Claude Code) and let the framework handle the technical complexity, with access control enforced on every database operation by default.
context.db operation is automatically secured; denied reads return null/[] (no information leakage).CLAUDE.md and MCP tooling, so you build by describing features.You need Node.js 18+ and pnpm (npm install -g pnpm).
# 1. Scaffold — installs deps and generates the schema
npm create opensaas-app@latest my-app
# 2. Run — starts the Dev database, applies the schema, and runs the app
cd my-app
pnpm dev
3. Build with Claude Code. Open the project in Claude Code and describe what you want — e.g. "add a comments feature to posts" or "add authentication". The scaffolded project ships a CLAUDE.md and MCP tooling so Claude builds within the framework's guardrails.
Your app runs at http://localhost:3000; the auto-generated admin UI is at /admin.
Want authentication from the start?
npm create opensaas-app@latest my-app --with-auth
The scaffolder runs install → generate for you. To skip that and run the steps yourself, pass
--no-install.
📚 Full documentation → · Quick Start guide → · Building with Claude Code →
opensaas.config.tsimport { config, list } from '@opensaas/stack-core'
import { text, select, relationship } from '@opensaas/stack-core/fields'
import type { AccessControl } from '@opensaas/stack-core'
// Access control returns a boolean, or a Where filter that scopes the rows.
const isAuthor: AccessControl = ({ session }) =>
session ? { authorId: { equals: session.userId } } : false
export default config({
db: { provider: 'postgresql' },
lists: {
Post: list({
fields: {
title: text({ validation: { isRequired: true } }),
content: text(),
status: select({
options: [
{ label: 'Draft', value: 'draft' },
{ label: 'Published', value: 'published' },
],
defaultValue: 'draft',
}),
author: relationship({ ref: 'User.posts' }),
},
access: {
operation: {
// Anonymous users only see published posts; authors see their own drafts too.
query: ({ session }) => (session ? true : { status: { equals: 'published' } }),
update: isAuthor,
delete: isAuthor,
},
},
}),
User: list({
fields: {
name: text({ validation: { isRequired: true } }),
email: text({ isIndexed: 'unique' }),
posts: relationship({ ref: 'Post.author', many: true }),
},
}),
},
})
pnpm generate # → prisma/contract.ts, prisma/contract.json, .opensaas/types.ts, .opensaas/context.ts
pnpm dev runs this for you on every start and on every edit to opensaas.config.ts — there is no separate database step to run first.
import { getContext } from '@/.opensaas/context'
export async function getPosts() {
const context = await getContext() // pass a session for authenticated access
// Access control is enforced automatically.
return context.db.Post.include('author', (author) => author.select('name')).all()
}
Denied operations return null (single) or [] (many) rather than throwing, so callers can't distinguish "denied" from "doesn't exist". Always null-check writes:
const post = await context.db.Post.update({ where: { id }, data })
if (!post) return { error: 'Not found or access denied' }
Packages
| Package | Purpose |
|---|---|
@opensaas/stack-core | Config system, fields, access-control engine, hooks, generators (MCP runtime via @opensaas/stack-core/mcp) |
@opensaas/stack-cli | opensaas generate / dev and the migration tooling |
@opensaas/stack-ui | Composable admin UI — primitives, field components, standalone CRUD, full admin |
@opensaas/stack-auth | Better-auth integration (sessions, OAuth, MCP adapter via @opensaas/stack-auth/mcp) |
@opensaas/stack-tiptap | Rich-text richText() field (third-party field example) |
@opensaas/stack-rag | Semantic search with vector embeddings |
@opensaas/stack-storage (+ -s3, -vercel) | File/image uploads with pluggable storage adapters |
create-opensaas-app | npm create opensaas-app project scaffolder |
Examples live in examples/: starter, starter-auth, blog, auth-demo, composable-dashboard, custom-field, json-demo, file-upload-demo, mcp-demo, rag-ollama-demo, rag-openai-chatbot, tiptap-demo.
Choose your level of abstraction:
import { Button, Card } from '@opensaas/stack-ui/primitives' // 1. shadcn/ui primitives
import { TextField, SelectField } from '@opensaas/stack-ui/fields' // 2. field components
import { ItemCreateForm, ListTable } from '@opensaas/stack-ui/standalone' // 3. standalone CRUD
import { AdminUI } from '@opensaas/stack-ui' // 4. full admin UI
See examples/composable-dashboard and the UI docs.
npx @opensaas/stack-cli migrate to get started)prisma migrateWorking on OpenSaas Stack itself (not building an app with it)? See CONTRIBUTING.md for monorepo setup, building packages, running tests, and the changeset/plugin-version workflow.
MIT