Releases: robeshell/castorjs
Release list
v0.4.0 — castor-kit is now Castor
castor-kit is now Castor: a professional name that keeps the beaver. The repository is robeshell/castorjs, the packages are @castorjs/* and the docs live at https://robeshell.github.io/castorjs/. Nothing changes for running installs: databases, cookies, stored secrets and the webhook contract are untouched.
Changed
- castor-kit is now Castor. The product name is Castor (the beaver keeps its place in the logo); the repository is
robeshell/castorjs, the packages are@castorjs/api/@castorjs/web/@castorjs/mcp(sopnpm --filter @castorjs/…), the docs site moves tohttps://robeshell.github.io/castorjs/, the MCP server is namedcastorand its binarycastor-mcp, andAPP_NAMEdefaults toCastor(authenticator apps list new enrollments under Castor). The wordmark is "castor" in the app, the docs site and the README. - Kept on purpose, so existing installs keep working: database, user and volume names (
castor_kit,castor_kit_test,castor_kit_ro,castor-kit_postgres_data/castor-kit_app_data), the session cookie and the key-derivation labels (castor-kit-session,castor-kit-secret-box,castor-kit-assistant-approval), the webhook headersX-Castor-*and User-Agents (castor-kit-webhook,castor-kit-scheduler,castor-kit-assistant), the browser storage keys and the public demo's address. - Upgrading:
git fetch/git mergefrom the old URL keeps working (GitHub redirects renamed repositories), but pointupstreamathttps://github.com/robeshell/castorjs.git; replace@castor-kit/with@castorjs/in your own scripts, CI and MCP client configs.
Full changelog: v0.3.0...v0.4.0
v0.3.0 — Reference implementations and a checked interface
Reference implementations and a checked interface: the component gallery is rebuilt as the pages developers and AI agents copy from, a whole-app interface audit is fixed (accessibility, color, layout, copy), and a project can now start from a release with its own name and the gallery hidden.
Highlights
- A gallery to copy from. Ten page patterns (standard / card / tree / stats list, detail, step form, dynamic form, kanban, gantt, advanced table) on one shared demo backend, eleven component showcase pages (live examples with their exact source and key props) and the new
ConditionBuilder; AGENTS.md, the skills and the docs site say which page to copy for a requirement. - Interface audit fixed. Visible focus everywhere (including Windows high contrast), names and keyboard paths for every control, reduced motion honored, route titles and landmarks, text alternatives for all charts, measured color tokens (234 text / focus pairs across 6 accents × light / dark, none below threshold), pinned row actions, full text for truncated values, errors that say how to recover; axe reports no serious or critical issue on any page.
- Ready for your own project. A Starting a project guide (repository from a release tag, naming, going live, taking later releases including migrations),
APP_NAMEto name the product, and a gallery that nothing else depends on and one line hides. - The AI workflow, dogfooded. Building a module end to end with
/new-feature-autopilotfixed two dozen rough edges inpnpm scaffold,pnpm verify,pnpm db:migrate,seed:rbacand the docs.
Upgrading from 0.2.0
pnpm db:migrate(Docker: on start).0003/0004adddemo_records;0005drops the twelve tables of the old gallery pages (demo data only) and deletes their menus (40, 401–409).pnpm seed:rbac -- --incremental(Docker: on start) adds the 页面模板 (43, 4301–4310) and 组件 (47, 4701–4711) menus and renames the_addbuttons 新增… → 新建….- Color tokens (
apps/web/src/index.css): the light status text steps,--muted-foregroundand--destructive(now the danger red) changed, and each accent preset gained--brand-primary(text, links, focus;--primary/--ringuse it),--brand-strong-from/to(gradients under white text) and--primary-hover. A project with its own presets defines those too. - Focus: controls use
focus-visible:outline-*with--ring, andtest/focus-ring.test.tsnow rejects a bareoutline-noneand translucent focus rings in your own components as well. Chartrequires asummary(its accessible name);DataTablegainedpin: 'end'for actions columns,primary,isRowActive,filtered/onClearFiltersand new empty states;FilterSelect/SearchInputtake alabel.- The dashboard's system status reads
GET /api/admin/dashboard/system;pnpm scaffold --domain component_centermodules use/api/admin/component-center/<name>sand register under 页面模板.
Added
- Shared demo data for the component gallery's page patterns (
docs/roadmap.md"Component gallery redesign", step 2): tabledemo_records(migrations0003_demo_record,0004_demo_record_board_order) and the API/api/admin/component-center/demo-records— list with filters (search, category, status, owner, enabled, parent /root, start-date range) and sorting (sort_field+sort_dir),tree,stats(count, amount / quantity sums, counts per status and category, same filters), CRUD,batch-update,batch-delete,reorder(each entry changes only what it carries:board_order+ status for kanban moves,sort_order+ parent for tree drags, so the two orders never disturb each other; cycle-checked), import / export / template. A record with children can't be deleted (400); a batch delete may take a parent together with all of its children. Demo fixtures: a three-level project tree of 24 rows. - 组件示例中心 → 页面模板 (Page patterns) directory (menu 43,
cc_patterns) with its first page, 标准列表 (Standard list) (menu 4301,/component-center/patterns/standard-list): the scaffold-generated list page on the shared API, the reference implementation of the standard list pattern. The API's buttons (cc_patterns_add/_edit/_delete/_export/_import, menus 431–435) belong to the directory, and any page under it may read. Runpnpm db:migrate && pnpm seed:rbac -- --incrementalafter upgrading. - The other nine page patterns under 页面模板 (menus 4302–4310,
component_center/patterns/*), each the reference implementation of its pattern on the shared demo API: 卡片列表 (card list: card grid, cover upload, tags), 树形列表 (tree list: drag to reorder / reparent), 统计列表 (stats list: stat cards and status bar fromstats), 详情页 (detail with tabs, the record id in the URL), 分步表单 (step form), 动态表单 (dynamic form: extra fields inextra), 看板 (kanban: status columns, drag across columns), 甘特图 (gantt: start / end dates and progress), 高级表格 (advanced table: inline edit, batch update / delete). Their status / category / enabled options and badge tones come from one module (pages/patterns/demo-record-options.ts; status tones: 待办 warning, 进行中 info, 已完成 success, 已归档 neutral). - 组件示例中心 → 组件 (Components) directory (menu 47,
cc_components, right after 页面模板) with 11 pages (4701–4711,/component-center/components/<slug>,component_center/components/*): one page per group of shared components (apps/web/src/shared/components), the usage reference for developers and AI agents — live examples, each example's exact source (syntax-highlighted, copyable) and the key props. 数据表格 (DataTable, RowActions, ConfirmAction), 表单 (FormFields, FormGrid, FormDialog, FormSheet, DetailSheet / DescriptionList), 筛选 (FilterBar, SearchInput, FilterSelect, SegmentedTabs), 选择器 (MultiSelect, TagInput, DatePicker / DateTimePicker, TreeSelect), 树 (TreeView, CheckableTree), 上传 (FileUpload, ImageUpload, AvatarUpload, FileIdUpload, to the real file center), 导入导出 (ImportDialog, ExportDialog on mock handlers), 反馈 (StatusBadge, EmptyState, ConfirmAction, toast, Skeleton), 数据展示 (StatCard with CountUp / Sparkline, Chart, Panel, PageHeader, UserAvatar), Markdown (MarkdownView), 条件构建器 (ConditionBuilder); no buttons, mock data only. The pages share a small showcase kit (modules/component_center/showcase:ShowcasePage,ShowcaseSection,Example,PropsTable,CodeBlock); each example is its own file imported twice, as a component and with Vite?rawfor the source shown, so the two can't drift (test/showcase.test.tsxchecks every example file is wired both ways); props tables are hand-written per page inprops.ts. The code highlighting reuses the AI Elements Shiki setup (tokensFor, now exported) and loads on demand. How to add one: AGENTS.md "Component showcase pages"; overview on the docs site's component gallery guide. Runpnpm seed:rbac -- --incrementalafter upgrading. ConditionBuildershared component (apps/web/src/shared/components/ConditionBuilder.tsx), replacing the old list page's saved-query condition builder: conditions (field / operator / value, operators and value editor by field type — text, number, date, select, boolean) combined with AND / OR, plus one level of condition groups (allowGroups); controlled (value/onChange), typed over the field keys (ConditionBuilder<K>), and its valueConditionTreeis plain JSON to save or send to an API — saving, API parameters or client-side filtering stay with the page.- Which page to copy: AGENTS.md "Page patterns (which page to copy)" maps a requirement (cards, tree, stats, detail, steps, dynamic fields, kanban, gantt, batch editing) to its gallery page and the backend pieces it needs; the shadcn and autopilot skills and the docs site's gallery guide ("Building a feature from a pattern", en / zh / ja) point to it.
- Starting a project guide (docs site, en / zh / ja): create a repository from a release tag with castor-kit as
upstream, name the product, hide the component gallery (one line inseed-rbac.ts; the code stays as the AI reference), go live, and take later releases, including how to merge when both sides added migrations (tried end to end on a scratch copy). APP_NAME(server) andAPP_NAMEinapps/web/src/lib/brand.ts(web) name the product in one place each: authenticator apps, the default mail sender and test mail, the AI assistant's introduction, logs; tab titles, the sidebar wordmark, the sign-in footer, the recovery-code file name.
Removed
-
The old gallery pages (组件示例中心 → 管理系统 / Admin pages: list page with saved queries and the condition builder, stats list, card list, tree list, dynamic form, kanban board, detail tabs, gantt, advanced table), replaced by the page patterns: their backend modules (
/api/admin/component-center/{list-page,stats-list-page,card-list-page,tree-list-page,dynamic-form-page,kanban,detail-tabs,gantt,advanced-table}), pages, API files, tests, demo fixtures, messages and OpenAPI paths. Migration0005_remove_old_gallery_modulesdrops their tables (saved_queries,saved_query_versions,stats_items,card_items,tree_nodes,dynamic_form_records,dynamic_form_fields,kanban_boards,kanban_cards,detail_members,gantt_tasks,advanced_table_rows) and deletes the 管理系统 menu directory (40) with its pages (401–409), their buttons and role grants. The saved-query condition builder comes back as a component showcase page (roadmap step 4). The dashboard's gallery quick link now opens the page patterns. Upgrading:pnpm db:migratedeletes the rows of those tables — demo data only; nothing else reads them. -
The component gallery's 3D / creative pages (particle network, CSS 3D cards, Three.js globe, particle morphing) and the
threedependency: the gallery is being reshaped into reference implementations for developers and AI (docs/roadmap.md"Component gallery redesign"). Migration `0002_remov...
v0.2.0 — English first, TypeScript throughout
English first and TypeScript throughout: the specs, docs and tools speak English, the admin frontend is TypeScript end to end, and the OpenAPI doc is kept in sync with the backend by a check instead of by hand.
Highlights
- English first.
AGENTS.md,CLAUDE.md,docs/, the skills, the MCP tool descriptions and every developer tool (pnpm verify,pnpm scaffold,pnpm openapi:generate, the setup wizard) are in English; the docs site defaults to English (Chinese at/zh/, Japanese at/ja/); English is the fallback UI / API language. - TypeScript frontend.
apps/web(source, tests and configs) is TypeScript with the same strict settings as the API, checked bypnpm typecheckand theverifygate;pnpm scaffoldgenerates typed TSX pages and TS API files. - API types from the OpenAPI doc. The frontend's API types are generated from
docs/apifox-full.openapi.json, and a newbody-syncrule keeps every documented request body in line with the backend's Zod declarations.
Added
routeBody(schema, 'create' | 'patch' | 'array')(@/common/validation): a route declares its JSON body once —.routegoes into the route options (Fastify routeconfig, so nothing runs before the login and permission checks),.parse(request)validates after the permission check. All 79 body-reading routes, the backend template andpnpm scaffolduse it;test/conventions.test.tsrejects a directparseBody/parsePatch/parseArrayBodyin aroutes.ts.body-syncOpenAPI rule (apps/api/scripts/lib/openapi-body-sync.ts): compares each documented JSON request body with the route's declaration — nullability, requiredness, types and enums per property, nested objects and array items included — wherever the doc rules run (pnpm openapi:generate --strict, verify'sopenapi_sync,test/openapi-doc.test.ts). Exportfields[]/file_typeenums are the contract by design; other intentional differences live inBODY_SYNC_ALLOWLISTwith a reason each, and a stale entry fails.- Generated frontend API types:
apps/web/src/shared/api/openapi.d.ts(byapps/web/scripts/api-types.mjs) withApiItem/ApiResponse/ApiQuery/ApiBodyhelpers in@/shared/api/types;pnpm openapi:generateregenerates it andtest/api-types.test.tsfails when it is stale. - Traffic flow in the component gallery (
/component-center/dataviz/traffic-flow, permissioncc_dataviz_traffic_flow): a Sankey diagram of visits (source → landing page → outcome) and a conversion funnel, replacing the map heatmap. Migration0001_traffic_flow_menurenames the existing menu in place, so role grants carry over. docs/shadcn-changes.md: every project change to an upstream shadcn / AI Elements component, to re-apply after re-adding one.- Component layer boundaries enforced by a test: shadcn primitives import only primitives; shared components get data through props instead of calling the API or reading app context.
Changed
- Frontend in TypeScript (plan and details in
docs/roadmap.md"TypeScript frontend"):apps/web/tsconfig.jsonis strict (same options as the API:noUncheckedIndexedAccess,verbatimModuleSyntax);srcis TypeScript only (test/typescript-only.test.ts), and tests and the Vite / Vitest configs are checked bytsconfig.test.json.pnpm lintlints the web app too.- Everything is typed: shadcn primitives (
components.jsontsx: true), shared components (DataTable<Row>with typed columns, FormFields / FormDialog over react-hook-form, generic trees and selects,Chartover echarts'EChartsOption), contexts (useAuth()/useTagsView()return non-null values), hooks (useCrudList<Row>), every module API file and every page. pnpm scaffoldwritesapi/<name>.tstyped from the module's OpenAPI entries and a list pageindex.tsxwithFormValuesandDataTableColumn<Row>[], so a form that doesn't match the documented body failstsc; it regeneratesopenapi.d.tsitself.docs/templates/frontend/is TSX.- Idiomatic cleanup: casts and non-null assertions replaced by narrowing, type guards and precise generics (the few left are commented); naming and export conventions documented in AGENTS.md "TypeScript".
- English first:
- Developer specs, skills and MCP tool descriptions in English; UI copy is still Chinese source text as the i18n key (
t('中文原文')) with English and Japanese translations. - English is the fallback: the UI uses it when neither a saved choice nor the browser language matches; the API answers in English when a request has no supported
Accept-Language(curl, API-token clients). Page title and<html lang>are English. - Tool output in English (
pnpm verify,pnpm scaffoldincl. spec validation anddocs/spec.schema.jsonhints,pnpm openapi:generate,pnpm seed:rbac, setup / seed scripts,scripts/setup.sh). Generated code keeps Chinese UI copy as the i18n key, and generated OpenAPI text stays Chinese. - Docs site: English at the root (
/guide/…), Chinese at/zh/, Japanese at/ja/; old/en/…links redirect.
- Developer specs, skills and MCP tool descriptions in English; UI copy is still Chinese source text as the i18n key (
- Repository root tidied: the Docker setup wizard is
bash scripts/setup.sh(entry pointscripts/docker-entrypoint.sh);README.zh-CN.md;.env.production.example;llms.txtserved at/llms.txt; one sharedAGENTS.md(+CLAUDE.md) instead of per-tool rule copies. - Faster first page opens: ECharts registered on demand (chart pages load about 40% less code); sign-in, reset-password and profile pages lazy-loaded (first download about a fifth smaller); page code prefetched on menu hover / focus and, for light pages, while the browser is idle (skipped in data-saver mode).
- Scaffolded modules document export
ids/fields/file_typeas nullable, and only required fields without a default are non-null and listed inrequired.
Fixed
- OpenAPI request side matches the backend: 332 differences between documented request bodies and the Zod
field.*declarations fixed (nullable fields with their defaults,''= "all" filters,export_mode: all, validated enums on announcements / menus, required webhook fields, descriptions that promised lenient parsing where the API returns 400). - Dashboard network tiles always showed 0.00 (they read fields the API doesn't return); they now show cumulative traffic since boot with a readable unit.
- Card list: a card with no
is_activevalue showed the switch off but was saved as enabled; edits sentid/ timestamps along with the form. - Heatmap dates were a day off before 08:00 in UTC+8; times on the dashboard, perf monitor and WebSocket pages ignored the UI language; the code editor reported success for languages it can't format; the AI SQL schema sheet showed "no tables" after a failed load; the prompt studio kept untrimmed values after saving; kanban sent
board_codeon update; untranslated list-page section titles and image-upload hint; Three.js pages didn't resize with their container; smaller fixes inDataTablekeys, zero page size, the particle canvas and the code highlighter. - Tags view: even spacing between tabs (the close button on inactive tabs no longer leaves an invisible gap).
Upgrading from 0.1.0
- Run
pnpm db:migrate(migration0001_traffic_flow_menu) andpnpm seed:rbac -- --incremental. - Frontend pages must be
index.tsx: page routing no longer findsindex.jsx, andapps/web/srcaccepts no.js/.jsxfiles. Convert custom pages and components to TypeScript (see AGENTS.md "TypeScript" anddocs/templates/frontend/). - Backend routes read JSON bodies through
routeBody(...)instead of callingparseBody/parsePatch/parseArrayBodydirectly (enforced bytest/conventions.test.ts), andpnpm openapi:generate -- --strictnow also checks request bodies against the Zod declarations. - API clients that send no
Accept-Languagenow get English messages; sendAccept-Language: zh-CNfor Chinese. - Docs site links: English pages moved from
/en/…to the root (old links redirect), Chinese pages from the root to/zh/…. - Moved at the repo root:
setup.sh→scripts/setup.sh,docker-entrypoint.sh→scripts/docker-entrypoint.sh,README_CN.md→README.zh-CN.md, the production env reference.env.example→.env.production.example(local development still usesapps/api/.env.example).
castor-kit 0.1.0
First public release: an AI-first admin framework on Node.js + TypeScript (Fastify 5, Zod, Drizzle ORM, PostgreSQL) and React 19 (shadcn/ui, Tailwind CSS v4, Motion).
AI-driven development
pnpm scaffoldgenerates a complete module from a field list or a JSON spec (--spec): table, migration, request-body declaration, repository / service / routes, OpenAPI entries, API tests (including field rules), the list page with form, import and export, menu and button permissions, and translations. Specs are checked againstdocs/spec.schema.json(--validate-only);docs/examples/specs/shows how requirements become specs.pnpm verify -- --module <name>gates a feature: files, registration, migrations applied, OpenAPI in sync, permission checks, data scope, frontend conventions, and the API and web tests.- An MCP server (
apps/mcp) exposes scaffolding, spec validation, RBAC sync and OpenAPI checks to AI agents;AGENTS.md,CLAUDE.mdand skills describe the conventions they follow. - The OpenAPI document (
docs/apifox-full.openapi.json) is written alongside the code and linted in CI (pnpm openapi:generate -- --strict); it can be pushed to Apifox.
Platform
- RBAC with menus and button permissions (
seed-rbac.tsas the single source of truth), a protected super admin role, departments and per-role data scope (all, own department and below, own department, own data, custom departments). - Users with profiles, status, avatars and import / export; roles, menus, data dictionary, announcements, notifications, login and operation logs, scheduled HTTP tasks (cron, with SSRF checks), and a file center (local or S3-compatible storage, type and signature checks, reference tracking).
- Account security: server-side sessions with an online-users page, two-step verification (authenticator app, recovery codes, required per role), password reset by email, password rules, rate limits and sign-in lockout. Passwords are hashed with scrypt.
- System settings as the configuration center: security, mail, file storage and AI, applied without a restart; secrets stored encrypted; changes need a recent identity check and notify super admins.
- Open API: personal API tokens limited to chosen permissions, and signed webhooks with retries and a delivery log.
- Request bodies are declared with Zod (
common/validation.ts) and take JSON types only; input problems are 4xx with readable messages. Times in the API are ISO 8601 in UTC; the web app shows them, and exported files and the dashboard use, the caller's time zone (X-Time-Zone). - Interface and API messages in Chinese, English and Japanese.
AI features
- AI chat, AI data query (read-only SQL on a restricted role) and a prompt workshop, on the Vercel AI SDK with OpenAI-compatible, OpenAI, Anthropic and Google providers.
- A global AI assistant (⌘/Ctrl + J) that answers questions and, after the user approves each call, acts through the API as the signed-in user.
Frontend
- Pages built from shared components: page header, filters, data table, form dialogs, import / export dialogs, confirmations and toasts.
- Tabs that keep page state, three navigation modes, accent colors, light and dark themes, and a component gallery of list, card, tree, kanban, Gantt, dashboard, editor, 3D and data-visualization examples.
Deployment and docs
- Docker image with migrations and RBAC sync on start; a public demo mode (read-only system management, one-click sign-in, data reset on a schedule) and a Render + Neon blueprint.
- Documentation site (VitePress) in Chinese, English and Japanese; MIT license and community files.