Prerequisites: Before using any API command, authentication and configuration must be completed (see below). Must do before execution: Before executing any command, you must first read the reference documentation for the corresponding command, then invoke the command. Naming convention: Uniformly use the
rabetbase <service> <command> [flags]format. Output format: When an AI Agent needs structured output,prefer--format compress(same asjsonenvelope, single-line compact, token-saving); when human-readable indentation is needed, use--format json. You can layerjson/compresson top of--jq '<expr>'(run jq on the entire final printed JSON; binary lookup order isJQ_PATH→ CLI built-in sidecar jq →PATHjq, usually no need to install system jq separately). When unsure what subcommands or flags the current CLI has, first runrabetbase schema(a machine-readable contract from the same source as--help, no login required).
Prerequisites
- Connection configuration and authentication are separate: on first use, first execute
rabetbase config init. In interactive mode, chooseMainland China (cn)orIndonesia (id); in non-interactive mode, explicitly pass--region cn|id, defaulting tocnwhen not passed. For enterprise standalone deployment, use--domain-config <file>or six--*-domainflags。config initto fixedly rebuild the global node/Domain configuration, retaining Cookie, AccessKey, format, locale, and application bindings, but without logging in or binding a project; then executerabetbase auth login - AppCode: ensure that
.rabetbase.jsonhasappsset (single application is automatically selected; for multiple applications, also configuredefaultApp), or the compatibly read top-levelappcode, or pass it via--appcode <code>/--app <name>. Legacy.lovrabet.jsonwill not be read automatically - Configuration file:
rabetbase config initis fixed to write to the global~/.rabetbase.json, does not accept project scope; by defaultcndoes not write redundantregion. Official node mode cleans up explicit and legacy Domain; standalone deployment mode cleans up oldregion/Domain and then writes the provided override values. For complete field descriptions, see.rabetbase.jsonconfiguration reference. Current directory application binding uses theworkspace initbelow; do not mix the two - Working directory application binding: when the current directory needs to be fixed to a certain application, use
rabetbase workspace init --appcode <code>orrabetbase workspace use --app <name>(for selection, see "app vs workspace responsibility boundaries") - Multi-application scenarios: when a project has multiple applications, first
rabetbase workspace add <name> --appcode …register each application, then use--app <name>to temporarily switch, orworkspace use --app <name>to modify the default application for the current working directory - Platform discovery: when you do not know which applications the currently logged-in account can access, first
rabetbase app list --remote; it queries the platform directory and does not modify local configuration - Local configuration view: when you want to confirm which applications have been registered for the current project or globally, and which is the default application, use
rabetbase app list。rabetbase appitself only displays help and is not equivalent toapp list - Personnel directory query: to query the personnel of a tenant, use
rabetbase tenant members-list --tenant-code <code>; to query the personnel of an application and their role affiliations, userabetbase app members-list --appcode <code>. Both are read-only full queries and do not provide pagination, fuzzy search, or write capabilities. - Local SQL / Backend Function directory: newly created or long-term maintained source files should land in a path consistent with the CLI and
bff status/sql pull, to avoid writing insrc/、queries/and other arbitrary directories and then migrating later.- SQL: project root
.rabetbase/sql/<appCode>/<dbName|db-<id>>/<sqlCode>_<sqlName>.sql|xml; drafts or manual fallbacks can be placed in.draft.sql。sql create/sql pull/sql push/sql statusby default works around this set of directories and.rabetbase/sql.lock.json. - Backend Function:
.rabetbase/bff/<appCode>/...(created bybff createor synced bybff pull; consistent with thebff status/bff pushscan scope). Seeguides/sql-creation-workflow.md、guides/bff-creation-workflow.md。
- SQL: project root
- Explicit handoff for runtime data queries —
rabetbaseis only responsible for Dataset structure and R&D publishing. When real row data is not needed, thelovrabetCLI can be left uninstalled. Once real business row data needs to be verified, it must be handed off tolovrabet data filter/getOne; when unavailable, report the blocker and prompt to install thelovrabetSkill and CLI. Do not call the removedrabetbase data filter/getOne, and do not have this Skill silently install or repair the runtime CLI.rabetbase sql execonly validates published SQL, and is not a general substitute for row data queries. Seeguides/data-api-guidelines.md。
Skill Freshness
- Local repo and CLI contract take precedence — if the installed global skill description is inconsistent with the current repository
skills/rabetbase/、rabetbase --help、rabetbase schema, takethe current repository content and the CLI's actual outputas authoritative. - Proactively refresh when a skill is found to be outdated — CLI installation and upgrade automatically install the same version of the Skill; if the inconsistency has already affected the judgment of the current task, execute
rabetbase cli-skill install, to reinstall from the local source within the current npm package via the latest official Skills CLI. - Must re-read after refreshing — after the refresh is complete, reopen the current
SKILL.mdand the required reference, then continue executing the task, to avoid following old memory. - Refresh failure must not fall back to old conclusions — if installation fails, clearly tell the user that "the local global skill may be outdated", and continue to use the repository's
skills/rabetbase/andrabetbase schemaas the source of truth.
Agent quick execution order
- Determine the requirement type
- Instant API standard data record operations → SDK filter/getOne/create/batchCreate/update/delete; for batch updates use
update({ id: [...] }), there is nobatchUpdate() - Simple aggregation and the dataset is DB_TABLE → SDK aggregate; for aggregate columns use
aggregate[].column, do not use the old aliasfield - Complex JOIN / database functions and the dataset is DB_TABLE → Custom SQL
- Charts, statistic cards, or data dashboards → custom page + ECharts; for the data layer, choose Dataset or Custom SQL based on query complexity
- Current user, role, data scope, external systems, cross-table transactions, or complex business orchestration → Backend Function; Backend Function HOOK can be attached to DB_TABLE or METADATA, and the specific operation is subject to what the backend returns
- Instant API standard data record operations → SDK filter/getOne/create/batchCreate/update/delete; for batch updates use
- Get metadata first, then write code
- At minimum first query
rabetbase dataset detail --code xxx --format compress(orjson) to obtain the table structure - For cross-table scenarios, also query the structure of the target table
- Before writing, use
data.fields[]to confirm the real fields, required fields, and enum options; for enum/select fields writeoptions[].value, not the displaylabel - Use when you need to understand dataset association relationships
rabetbase dataset relations --format compress(orjson); use when you need to audit relationship fact errors and manual review itemsrabetbase dataset relation-audit --format compress - When you need to create a new
METADATAdataset from text requirements, first readdataset generate-start/status, run preview to write the design file, and after review usegenerate-start --apply --design-fileto submit the task, then usegenerate-statusto query until success - Manage physical database connections / test connections / synchronize table structure analysisuse
rabetbase db …(firstdb list, see trace/plan id indatabase-connection-workflow.md) - DBAgent incremental analysis by default first performs one asynchronous difference refresh: call
db diff-refresh-start, save the traceId, and usedb diff-refresh-statusto query the same task to a terminal state; after success, execute according to the original intentdb diff --all(difference tables) ordb tables(all tables). Regardless of the size oftableCount, perform the refresh; only skip the asynchronous refresh when the user explicitly states "no analysis needed", "no refresh", or "only look at existing results", and explain that the results may not be the latest facts - When you need to view all tables (including tables with no differences) or proactively re-analyze existing tables, use
db tables; it fixedly aggregates all-table pagination.db diff --allonly aggregates all difference pagination - DB incremental analysis first performs
toAnalyzeTableson the completedb analyze-batch-plan; what it generates is a local batch plan, not a server-sideplanId, and it does not create a task. Then start strictly in batch order; each batch independently savesplanId(i.e., the return value ofanalyze-start), and the next batch must not be started before the current batch reaches a known terminal state - After all batches end, perform the asynchronous difference refresh again and re-fetch the complete differences; if still not converged, according to
database-connection-workflow.md, retry the remainingtoAnalyzeTablesserially table by table, and resume each table only once. Only when the user explicitly requests to skip analysis/refresh, directly read the existing differences. If status query fails, continue using the originalplanId, and do not start the task repeatedly - When the output is very large and only a subset is needed, add
compress/jsonon--jq '.data…'to narrow the results - When real business row data is needed, it must be handed over to
lovrabet data filter/getOne;lovrabet. When unavailable, report the blocker and prompt to install the Skill and CLI; do not silently install or repair, and do not userabetbase sql execas a substitute for row data, seeguides/data-api-guidelines.md - When
src/api/api.ts/client.tsis needed: firstrabetbase api pull --format compressto getdata.models、data.files、data.needsAgentMerge, then update TypeScript according tosdk-client-generation.md.api pullwill not overwrite existingapi.ts/client.ts
- At minimum first query
- SQL workflow is strictly step-by-step
- Recommended path: query existing (
sql list/detail) or create new (sql create) → pull/save locally (sql pull/sql create) → edit the synchronized directory files → optional validation (sql validate) → check status (sql status) → preview first (sql push --dry-run/sql delete --dry-run) → thensql push/sql delete→sql detail/sql execverify - First use
sql list/detailto find reusable Custom SQL; when there is no resource that meets the requirement, followsql-creation-workflow.mdandsql-mybatis.mdto create, validate, publish, and verify - When the page executes published Custom SQL, use
sqlCode+params; Backend Function uses by defaultcontext.client.sql.byName(sqlName).execute({ params }),sql.execute({ sqlCode, params })Compatibility path only
- Recommended path: query existing (
- Backend Function workflow is strictly step-by-step
- Check existing → confirm fields or notification configuration → check public functions → create locally (
bff create) → check status (bff status) → preview first (--dry-run) → then pull/push/delete - When creating a Backend Function that sends message notifications, first read the "Message Notification Extension" contract of
backend-function.md, then executerabetbase notification config-list --type EMAILto get the current app'sconfigCode; do not guess the channel or recipients, or write keys into the script - Push completion only means the script configuration has been synced to the platform; if the user wants to confirm the final runtime effect, explicitly hand off to runtime verification (such as an available
lovrabet bff exec), and do not disguise runtime verification asrabetbasebeing completed
- Check existing → confirm fields or notification configuration → check public functions → create locally (
- Page system selection
- A Data List Page is a structured page group driven by datasets, used for data viewing, maintenance, and model validation; it is not equivalent to the final business workbench
- A Custom Page is an independent page driven by complete code files, used for workbenches, dashboards, portals, and complex business interactions; currently React JSX is only a rendering implementation, not a page product type
- Charts, statistic cards, and data dashboards use custom pages and ECharts within the allowlist
- When the page system is unclear, confirm with the user first; do not create both a data list page and a custom page for the same goal
- Data List Page (page) workflow
- The workflow judgment first looks at
guides/page-development-workflow.md pagecommand responsibility separation:page generate-startis responsible for submitting or reusing tasks,page generate-statusis responsible for querying task status,page data-list-statusis responsible for querying data list page facts- After dataset field changes, sync existing data list pages:
page sync - Page relationship binding audit: first read
rabetbase-page-relation-binding.md, then executepage relation-audit - When encountering issues such as "related data cannot be brought out / the data list page did not generate a relationship / abnormal page relationship binding", the fixed order is:
dataset relationsread-only confirm relationship facts →dataset relation-auditaudit relationship fact risks →page data-list-statusdetermine whether the page exists →page relation-auditaudit page binding; if the relationship facts themselves are incorrect, first followdataset relation-create/update/deleteto do the--dry-runplan and wait for user confirmation; if a page already exists, thenpage sync --dry-run; if there is no page, go throughpage generate-start --dry-run page syncis only responsible for syncing existing data list pages, not a dataset relationship repair command, and cannot promise to automatically repair allwrong_code/wrong_label/missing- Local schema development:
page pull→ IDE editing →page push - Restore a deleted page: first read
page restore, the CLI product type only usesDATA_LIST|CUSTOM; by default it is automatically identified by ID, and when the same ID exists across types, explicitly pass--page-type - When it is necessary to understand the semantics of formal schema components, then read on demand the PageSchema component materials under
knowledge/page-schema/; do not confuse it with therabetbase pagecommand reference
- The workflow judgment first looks at
- Custom Page workflow
- Custom pages and data list pages are two independent page capabilities; do not mix commands from the two page types
- Before creating, modifying, or publishing, you must first read
custom-page-workflow.md, then read the corresponding atomic command reference according to the orchestration within it - Before writing JSX, CSS, or word packages, you must read
generation-standards.md; when selecting UI components, readcomponents.md
- Legacy modernization / Application Blueprint workflow
- When the user wants to modernize a legacy project without handover, an outsourced takeover project, or a legacy system into the Lovrabet system, first read
guides/legacy-application-blueprint-workflow.md - The main artifact is
.rabetbase/blueprint/<appCode>/application-blueprint.md, not directly generating or pushing SQL/Backend Function - The legacy code Logic Graph must be bound to the Dataset / Relations already generated by dbagent, then determine the placement of Instant API, Custom SQL, Backend Function, Hook, COMMON, or Java Service
- When the user wants to modernize a legacy project without handover, an outsourced takeover project, or a legacy system into the Lovrabet system, first read
Application decision guidance
-
appcode already specified
- The user directly provided
app-xxxx - or the current command already explicitly passed
--appcode - Directly execute the target command; no need to first query
rabetbase app list --remote
- The user directly provided
-
Local application name already specified
- Current project
.rabetbase.jsonalready has a unique app, or multiple apps have already configureddefaultApp - or the user provided
--app <name> - First use
rabetbase app listto verify the local configuration, then execute the target command
- Current project
-
Only the business name is known, and it is unknown which application can be accessed
- First
rabetbase app list --remote --format compress - Confirm from the platform directory the applications accessible to the currently logged-in account
- Then decide whether
rabetbase workspace add/rabetbase workspace useis needed, or temporarily pass--appcode
- First
-
Do not confuse the two views
rabetbase app list: local configuration view, answering "which applications are registered in the current project/globally"rabetbase app list --remote: platform directory view, answering "which applications the currently logged-in account can access"
-
When the two sides are inconsistent
- Exists on the platform but not locally: this means it has not yet been registered in the local configuration, and you can use
rabetbase workspace add - Exists locally but cannot be found on the platform: this means the current account may not have permission, or the local configuration is outdated; first verify permissions and appcode
- Exists on the platform but not locally: this means it has not yet been registered in the local configuration, and you can use
Menu asynchronous regrouping (menu regroup-start)
Before execution, first read menu regroup-start and task status. The completion criterion of this workflow is not "task submitted", but that the asynchronous regrouping task reaches a definite terminal state:
- First use
menu listto obtain the precise non-folder leaf menu ID, then executemenu regroup-start --dry-run。 - Formal execution submits only once and saves
data.task.taskId. On the first readback,data.verification.groupingAppliedmay betrueor"unconfirmed"; failure to confirm by readback does not mean the task submission failed. - If
data.task.statusisPENDING / PROCESSING, the execution returnsdata.query.command; if it remains non-terminal afterward, continue querying the same taskId and do not submit againregroup-start。 - Retain the initial response's
data.verification.lookupCommand. Whether the initial response is alreadySUCCESS, or a subsequenttask statusreachesSUCCESS, this command must be used to read back the final menu facts; if the readback still cannot confirm, only retry the read-only query and do not resubmitregroup-start。 FAILEDreporterrorMessageand do not automatically resubmit; unknown states (knownStatus=false) enter manual review, and do not infer success or failure.
Database connection (db)
and dataset(dataset model) division of responsibilities:db * manages platform-registered physical database connections (dblink)、test connection、schema analysis task、physical table list and differences; table fields and enums are based on dataset detail , dataset associations are preferentially based on dataset relations , relationship fact risks use dataset relation-audit。
- Entry: first
db listfetchidandlatestAnalysisTraceId(if any). - Read-only common:
db detail、db test、db tables、db diff。db tablesfixedly aggregates all tables and analysis status;db diffread-only difference results,--allaggregates all difference pages only. - Difference refresh:
db diff-refresh-start/status. When the CLI initiates a DBAgent incremental analysis, regardless of how muchtableCountis or whether it is missing, by default refresh first and then read differences; only when the user explicitly requests to skip analysis/refresh should existing results be read directly. Refresh and schemaanalyze-*are two types of tasks and must not be mixed. - Analysis task:
db analyze-batch-plan/analyze-start/analyze-cancel/analyze-status(server-side plan/trace sources see below). - Status diagnosis boundary:
analyze-statusofrequestedAnalysisonly restores the original submission scope;hasMultipleAttempts=trueonly indicates that multiple execution attempts were observed. It must not be used to infer continuity between attempts, actual execution scope, or automatic restart. - Incremental batching: first use the local read-only
db analyze-batch-plan --id <id> --tables <清单>to obtain deterministic batches andplanningEstimate; what is generated here is a local batch plan, not a server-sideplanId, and will not create or reserve tasks. Then callanalyze-startonce per batch, read the realplanIdand the current task'sserverEstimate; each batch independently saves theplanIdit returns, and the same dblink is strictly serial. Neither type of estimate may drive timeout, cancellation, retry, automatic restart, or status determination, andPENDING / RUNNING / RETRYING / CANCELINGmust not advance to the next batch. - Cancel existing task: only use the original
planIdbeing tracked to executeanalyze-cancel --plan <原 planId>; the cancellation branch must not callanalyze-start, nor replace the known target with a possibly changinglatestAnalysisTraceId. - Failure recovery: after all batches end, by default refresh asynchronously again, then read the complete
db diff --allto obtain unconverged tables; only when the user explicitly requests to skip analysis/refresh should it be read directly. Then executeanalyze-start --tables <单表>serially table by table, restoring each table only once; cumulative reason counts are only displayed as a possibly incomplete reference. The Agent may semantically understand the originalerrorMsgto assist explanation and suggestions, but neither drives task status, task resubmission, or convergence determination. - ER diagram guidance:
db analyze-statusafter terminal success, check and relaydata.links.erPage; if there is nodata.links, supplement--appcodeor enter the project context of the configured app and query again. - Write:
db create/db updateby default test unsaved configuration first, only explicit--skip-connection-testskips it;db deletemust first dry-run, and before execution recheck DB_TABLE Dataset dependencies; if there are dependencies, block and there is no force. All three support--dry-run。 - Cross-cutting process and trace/plan:
database-connection-workflow.md。Single-command detailsseereferences/rabetbase-db-*.md(corresponds one-to-one with repositorysrc/commands/db/).
Development roles and collaborators (role)
rabetbase role only manages development roles and development collaborator relationships, and the output explicitly includes scope: "dev". Business personnel roles, user group members, and page, menu, and dataset permissions belong to lovrabet. If lovrabet the current Help/Schema does not yet provide the corresponding command, you should clearly state that the capability is temporarily unavailable; you must not substitute rabetbase, nor perform cross-platform dual writes.
- Role type:
ADMIN/DEV/OWNER(built-in) and existingCUSTOM;update/deleteonlyCUSTOM. Currently not providedrole create。 - Read-only personnel directory: for querying all tenant members use
tenant members-list; for querying app members and role assignments useapp members-list. When only viewing facts, do not callrole user-add/user-remove。 - Add/remove people: first
role user-resolveget the userId, thenrole user-add/user-remove(high-risk-write, only change the target developer role; OWNER is directly rejected). - View/modify/delete existing groups:
role list/detail/update/delete。 - Iron rule: before writing, first read the current role/member facts →
--dry-runcheckdata.before/after→ for high-risk writes explicitly--yes; do not use rabetbase to modify runtime permissions.
Configuration scope principles (--global)
- Normal write operations default to the current project(
workspace add、config set、project create, etc.), unless the userexplicitlypasses--global;config initis the first-connection configuration entry point, and always writes global configuration. - Do notadd
--global** to commands when the user has not requested it — the default behavior is already "project first"; use it only when the user explicitly wants to change global configuration or is not inside a project and intends to write globally. config set: whenthere is noproject configuration file (the current directory does not resolve to.rabetbase.json) andnotpassing--global, the CLI refuses to executeand prompts to use--globalor firstrabetbase workspace init --appcode <code>,will notsilently write to global.project createnewly generated project.rabetbase.jsononly inheritsa small number of global preferences (such ascookie/locale/format/riskLevel, etc.),will notbring the globalapps/defaultAppinto the new project file; at the same time it generates a browser-safesrc/api/sdk-config.ts: by default mainland China nodes do not write routes, ID writesregion: "id", non-default enterprise Runtime writesruntimeDomainand takes precedence over region, and does not deliver authentication configuration. The template's Vite local development and preview addresses also select the corresponding HTTPS domain and certificate according to the project region: ID useshttps://dev.lovrabet.id, mainland China useshttps://dev.lovrabet.com。api pull/api list: by default only targetsprojectapps; when you need to merge globally registered apps, add--global(see each command reference).app list: by default displaysmergedfull set;--globalglobal only,--projectproject only (seerabetbase app list)。
app vs workspace responsibility boundaries
Division axis = "Is this an objective fact about the app, or configuration about my current working environment?"
app= objective fact queries about the app: answers "which apps do I have/can I access" and "which people and role assignments does an app have", regardless of where the code is written.Read-only, does not carry additions or deletions.app list(local registration view) /app list --remote(platform accessible directory) /app members-list(app personnel).
workspace= configure which apps the current working environment uses: All write operations that "modify my configuration" are here.workspace init(bind the current directory for the first time) /workspace use --app <name>(switch the default app for the current directory).workspace add <name> --appcode <code>(register an app profile) /workspace remove <name>(remove a local profile).- By default, write to the current project
.rabetbase.json;--globalwrite globally (the global scope is treated as one large workspace).init/useDo not copy cookie/accessKey from the global scope.
Three-entry selection (do not mix them):
| Scenario | Command |
|---|---|
| Global guidance after first installation | rabetbase config init |
| The current directory is not yet bound to an app | rabetbase workspace init --appcode <code>(single app does not write defaultApp) |
| The directory already has configuration, just register one more profile | rabetbase workspace add <name> --appcode <code>(when changing from single app to multiple apps, keep the original app as default;--global write globally) |
| Switch the default app for the current directory | rabetbase workspace use --app <name> |
Entry determination:
- "See which apps / what can be accessed on the platform" →
app list(--remotequery the platform). - "See which people and their roles an app has" →
app members-list --appcode <code>。 - "See which people a tenant has" →
tenant members-list --tenant-code <code>。 - "Register/delete an app profile" →
workspace add/workspace remove(when you need to modify the global list, add--global)。 - "Make the current directory use a certain app / switch the default app" →
workspace init/workspace use。
Prohibited Agent behaviors
- Do not guess field names — you must obtain the real field names, types, and enum values from the
dataset detailreturn value - Do not skip validate and dry-run — before modifying existing SQL and preparing
sql push, you must first runsql validate; before creating SQL or executing a high-risk sync, at least confirm the preview ofsql create --dry-run、sql push --dry-runorsql delete --dry-runpreview of - Do not manually assemble API URLs — complete all operations through CLI commands; do not call HTTP interfaces directly
- Do not expose development implementation to product users — when answering role permission operations, do not output engineering repositories, Controllers, database tables, interface paths, MR troubleshooting, or migration processes; only explain CLI commands, role boundaries, risks, and verifiable results
- Do not speculate about sqlCode / id — obtain the real identifier from
sql listorbff listget the real identifier - Do not speculate about dblink id or analyze trace/plan id — obtain it from the return fields of
db list/db detail/db analyze-start(see database-connection-workflow.md) - Only use visible commands — commands appearing in this skill,
rabetbase schema、rabetbase --helpshall prevail; do not call old aliases that do not appear based on training memory - Do not handle failures vaguely —
sql create/sql push/sql delete/bff push/bff deleteWhen a failure is returned, you must clearly tell the user which resource failed and why it failed - Do not write SQL without confirming the table structure — first
dataset detail, then write SQL, Backend Function, pages... - Do not treat case fields as general rules — field names, enum values, and table names in any Demo, historical project, or example must not be copied directly; the current
dataset detailshall prevail - Do not loop single queries — use the SDK
filter + $infor batch queries, do not do N+1 - Do not rely on CLI output text fragments to determine write results — for
dataset rename --dry-run/ formal execution, only read thedata.*stable fields of the structured envelope - Do not skip the final online re-check after Dataset rename — after consecutive renames, you must re-query the online name by code; do not trust only the local plan or dry-run
- Do not treat MCP tool names as CLI commands — use
rabetbase sql list, notlist_sql_queries - Do not add
--global— see "Configuration Scope Principles" above; by default write to the project and read the merged result; use--global。
Interface selection priority
When encountering a new requirement, choose the implementation method by priority:
- Standard SDK interfaces(filter/getOne/create, etc.) — if they can be used, do not write SQL
- aggregate interface — simple grouped summaries for DB_TABLE; METADATA does not support aggregate by default; aggregate definitions use
columnto specify columns,fieldis only a historical compatibility alias - Custom SQL — complex JOINs, database functions, and cross-table statistics for DB_TABLE; METADATA does not support the SQL path
- Backend Function — external system calls, cross-table transactions, complex business orchestration
SDK core rules
Initialization
import { createClient } from "@lovrabet/sdk";
const client = createClient({
appCode: "your-app-code",
authMode: "client-ak", // 传 accessKey 时必须显式声明;缺省 authMode 一律走 cookie 模式,accessKey 会被忽略
accessKey: process.env.RABETBASE_ACCESS_KEY,
models: [{ tableName: "users", datasetCode: "abc123", alias: "users" }],
});
The authentication mode must be explicitly declared:
accessKey(accessKey only) useauthMode: "client-ak";accessKey + secretKeyortokenfor signing scenarios useauthMode: "openapi"; omit in browser Cookie environmentsauthMode(defaults to cookie).
filter query (most commonly used)
const result = await client.models.users.filter({
where: { status: { $eq: "active" } },
select: ["id", "name"],
orderBy: [{ createTime: "desc" }],
currentPage: 1,
pageSize: 20,
});
Parameter names are strictly constrained:select(not fields),orderBy(not sort),currentPage/pageSize(not page/limit)
where conditions must use operators:$eq $ne $gt $lt $gte(or alias $gteq)$lte(or alias $lteq)$in $contain $startWith $endWith $notNull($gteq/$lteq is a backend compatibility alias, mapping to the same SQL; new code should use $gte/$lte)
SQL invocation
The page SDK executes queries through the sqlCode + params of a published Custom SQL; Backend Function by default executes queries through the sqlName of the unique context.client.sql.byName(sqlName).execute({ params }) within the current application,sql.execute({ sqlCode, params }) as a compatible invocation method.
const data = await client.sql.execute<MyRow>({
sqlCode: "xxx",
params: { key: "val" },
});
if (data.execSuccess && data.execResult) {
console.log(data.execResult);
}
When a custom page needs charts, use ECharts in its React JSX implementation; for read-only queries when the platform's sqlCode permissions are already satisfied, you can directly call the Custom SQL published above. When additional control based on the current user, role, data scope, or business rules is needed, the page should instead call a Backend Function, and the Backend Function performs validation before executing that Custom SQL. On execution failure, preserve and report the original error, and locate the issue based on the SQL resource status, parameters, and permissions.
Backend Function invocation
const result = await client.bff.execute<DashboardData>({
scriptName: "getUserDashboard",
params: { userId: "123" },
});
Key differences between frontend and Backend Function
| Frontend SDK | Backend Function (context.client) | |
|---|---|---|
| SQL return value | { execSuccess, execResult } |
directly returns an array T[] |
| single query | getOne({ id }) |
getOne({ id }) |
| dataset access | alias can be used through initialization/generated code | DB_TABLE by default uses models.byTable(tableName, { dblinkId? });METADATA uses "dataset_" + 数据集 code,DB_TABLE also supports this compatible invocation method |
filter() returns |
tableData is list data |
tableData is list data, not list |
create() returns |
Subject to the SDK documentation/types | New record ID, not a complete object |
| SDK initialization capability | createClient / registerModels |
Unavailable;context.client injected by the platform |
| Call Backend Function | client.bff.execute({ scriptName, params }) |
— |
Intent → Command Index
| Intent | Recommended Command | Notes |
|---|---|---|
| Initialize connection configuration | rabetbase config init |
Select an official node or import a standalone deployment Domain |
| Create new project | rabetbase project create |
Supports --name + --appcode non-interactive |
| Migrate from lovrabet-cli | rabetbase project upgrade |
6-step automatic migration,--yes skip confirmation |
| Legacy Application Blueprint / Legacy Application Blueprint | guides/legacy-application-blueprint-workflow.md |
First output .rabetbase/blueprint/<appCode>/application-blueprint.md, bind the legacy code logic to Dataset / Relations, then generate the migration Backlog |
| Run package.json script | rabetbase run <script> |
write; review the script command body first, embedded tools are not yet available |
| Install / reinstall / refresh CLI Built-in Skill | rabetbase cli-skill install |
The latest official Skills CLI reinstalls the same-version Skill from the local source within the current npm package; run this first when the local skill is found to be outdated |
| Log out | rabetbase auth logout |
Delete local authentication cookie |
| Bind the current user's DingTalk sandbox account | rabetbase user-account dingding-sandbox-bind |
write; first --dry-run verify the ID, formal execution does not require --yes; appCode not needed |
| Diagnose configuration issues | rabetbase doctor |
Built-in Skill consistency, merged configuration, JSON syntax on each side, domain, authentication status |
| Report platform issues | rabetbase issue report |
The Skill organizes complete objective facts; it is forbidden to make root-cause judgments or design solutions on behalf of the platform side |
| Upload application files | rabetbase file upload |
Returns a persistently savable filePath |
| Get file access link | rabetbase file query-url |
Short-lived by default; Markdown/HTML URL-only content explicitly adds --long-term |
| Extract text and structured fields from ticket-type business materials | rabetbase ocr recognize |
Invoices, receipts, certificates, etc.; not for general image understanding |
| Export command contract (flags/risk, etc.) | rabetbase schema |
Same source as --help ;No login required; for large results use --format compress |
| Update CLI version | rabetbase update |
Automatically detect the latest version, upgrade CLI and Built-in Skill together |
| Initialize/switch the application for the current working directory | rabetbase workspace |
Write to the current directory .rabetbase.json; do not copy cookie/accessKey from the global scope |
| Modify configuration file | rabetbase config set <key> <value> |
Writes to the project by default; if there is no project configuration and --global was not specified, it will refuse;--global writes ~/.rabetbase.json |
| List configuration | rabetbase config list |
View the currently effective configuration |
| Manage runtime app-config | rabetbase app-config list/get/set/delete |
Runtime app-config management plane; does not output plaintext value by default;set is write,delete keeps high-risk-write |
| Manage and search the enterprise knowledge base of the current R&D application | rabetbase kb list/detail/search/create/update/delete |
Management is company scope only; search is COMPANY/PUBLIC only;create/update is write,delete keeps high-risk-write |
| Query or manage application-level notification configuration | rabetbase notification config-list / rabetbase notification config-create / rabetbase notification config-update / rabetbase notification config-delete |
list retrieves the Backend Function required configCode; writes accept only a single sensitive JSON source, dry-run first; update/delete must --yes |
| View online menu facts / menu anomaly audit | rabetbase menu list |
Return DFS facts, children/page, URL, last updater/time and snapshotHash; for anomaly governance first read menu-anomaly-manual-cleanup |
| Batch show or hide menus | rabetbase menu visibility-update |
Select targets with exact ID/path; dry-run first, use --expect-visible / --expected-count to prevent drift, formal execution must --yes |
| Create external website link menu | rabetbase menu external-link-create |
write; explicitly select embedded or new-window, only HTTPS is accepted; dry-run is recommended first, formal execution does not require --yes |
| Update an existing external link URL in place | rabetbase menu external-link-update |
write; exact single ID, URL-only; must carry old URL and parent assertion, dry-run first, then reuse parameters for formal execution |
| Modify the name of any type of menu | rabetbase menu rename |
exact single ID, label-only; use --expect-label to prevent drift, dry-run first and check before/after |
| Sync local micro-frontend routes to the platform | rabetbase menu sync |
Scan src/pages to create missing procode menus; do not upload build artifacts; before formal execution first --dry-run |
| Modify micro-frontend menu resource URL | rabetbase menu asset-update |
write; use ID/path to precisely select the target or explicitly --all, default patch and preserve load mode, dry-run first then reuse parameters for formal execution |
| View/manage development roles | rabetbase role list/detail/update/delete |
role types are ADMIN/DEV/OWNER/CUSTOM; only CUSTOM can be modified/deleted; create is currently not provided; output scope: dev |
| Resolve nickname/username to userId | rabetbase role user-resolve |
based on the tenant member directory; when names are duplicated, list candidate IDs, then pass the selected ID to role user-add/user-remove --user <id> |
| Query tenant personnel list | rabetbase tenant members-list --tenant-code <code> |
first verify the tenant of the current account, then return all personnel; no pagination, do not output email/phone/avatar |
| Query application personnel and role list | rabetbase app members-list --appcode <code> |
deduplicate by userId and aggregate roles[]; also preserve ACTIVE/PENDING role affiliations |
| Add/remove development collaborators to/from roles | rabetbase role user-add / user-remove |
only modify the target development role; OWNER is directly rejected;high-risk-write, first --dry-run |
| Delete menu or directory tree by ID | rabetbase menu delete |
precisely delete empty folder/non-folder leaves; non-empty folder explicitly --recursive, the plan submits in batches with leaves first and reads back |
| Create empty menu group | rabetbase menu group-create |
group is persisted as type=folder, preserve the platform-generated non-empty path; dry-run first and check creation position and ordering |
| Modify menu group ordering | rabetbase menu group-update |
the target must be folder; to modify the name of any menu type uniformly use menu rename; dry-run first and check before/after |
| Move an existing leaf menu | rabetbase menu move |
use exact source ID, target parent ID and current parent assertion; dry-run item by item and check read-back after writing |
| Asynchronously create root group | rabetbase menu regroup-start |
write; accepts only exact non-folder leaf IDs; returns taskId, non-idempotent requests are not automatically resubmitted |
| Query general asynchronous task | rabetbase task status |
query by taskId + appCode PENDING / PROCESSING / SUCCESS / FAILED; read-only, does not restart business operations |
| Find datasets | rabetbase dataset list --name "xxx" |
Returns supported DB_TABLE and METADATA datasets by default; to query a specified source use --source DB_TABLE / --source METADATA; you can also --code for exact lookup |
| View table structure and fields | rabetbase dataset detail --code xxx |
includes field definitions and operation list |
| Deprecate dataset | rabetbase dataset delete |
high-risk-write; non-cascading by default, explicit --cascade --confirm only then deletes associated pages; must first --dry-run, batch recommended --expected-count |
| Restore deleted dataset | rabetbase dataset restore |
high-risk-write; restores only the Dataset by unique recycle bin log, pages use page restore to explicitly restore; must first --dry-run |
| Modify Dataset display name | rabetbase dataset rename |
Only updates the Dataset display name; must first --dry-run, use --expect-name to prevent drift; for consecutive renames read the corresponding section first |
| Generate a new METADATA dataset from text | rabetbase dataset generate-start / generate-status |
Three steps: preview; submit after review; then execute data.query.command, prefer querying by the same taskId.PENDING/PROCESSING is not terminal, unknown or lost responses must not be automatically resubmitted; only after returning createdDataset.code then use the Dataset |
| Safely update the Dataset raw field object | rabetbase dataset field-update |
Use --code to locate the Dataset, only known mutable business configuration fields may be patched; must first --dry-run, use --expect-json to prevent drift |
| Dataset top-level extend update command | rabetbase dataset extend-update |
currently no writable fields; must not be used for businessGroup. Business scenario grouping can only use rabetbase dataset business-group-update |
| Discover existing business groups | rabetbase dataset business-groups |
read; aggregate DB_TABLE Datasets by --dbid , excluding METADATA; an empty string bucket means ungrouped |
| Update business scenario grouping | rabetbase dataset business-group-update |
the only entry point; use --code to locate the Dataset; must first --dry-run, recommended to use --expect-business-group to prevent drift |
| View Dataset operation definitions | rabetbase dataset operations --code xxx |
Get parameter definitions for filter/getOne/create etc. |
| View dataset association relations | rabetbase dataset relations |
standard read-only entry point, outputs datasetCode + field relation facts; supports DB_TABLE -> DB_TABLE、DB_TABLE -> METADATA、METADATA -> METADATA |
| Audit dataset association relations | rabetbase dataset relation-audit |
read-only audit of relation fact structure errors, risks, and manual review items |
| Manage a single dataset association relation | rabetbase dataset relation-create/update/delete |
single relation write; before writing use relations to confirm datasetCode + field relation facts, the table name required for DB_TABLE write comes from explicit parameters or physical table facts |
| Generate a data list page for the first time | rabetbase page generate-start --datasetcode <code> |
Submit or reuse a server-side asynchronous task |
| Create custom page | rabetbase page create --page-pattern BLANK --name "客户看板" |
currently only publishes BLANK mode; creates JSX/CSS/word package and menu; dry-run first |
| Query custom page | rabetbase page custom-list |
Returns page ID, page name,pageUrl(view latest saved content) and editPageUrl(open editor) |
| View custom page details | rabetbase page custom-detail --id <pageId> |
Query page details,codeContent Includes the complete page file that can be modified and then submitted as a whole |
| Update custom page | rabetbase page custom-update --id <pageId> --page-content <json> |
Save the complete page file and create a new version; dry-run first |
| Publish custom page | rabetbase page custom-publish --id <pageId> |
write; publish the currently saved content, dry-run and review the preview first |
| Query the data list page generation task status | rabetbase page generate-status --datasetcode <code> --operation-id <id> |
Query the job status, supports operationId / clientOperationId |
| Query the data list page generation task status | rabetbase page generate-status --datasetcode <code> --task-id <id> |
Query the job status; taskId is preferred, operationId/clientOperationId are compatible. After success, still read the data list page facts; unknown statuses must not be resubmitted automatically |
| Query the data list page fact snapshot | rabetbase page data-list-status --datasetcode <code> |
Query the data list page four-piece set, residual pages, and menu facts |
| Audit data list page relationship bindings | rabetbase page relation-audit --datasetcode <code> |
Read-only check whether the data list page options bindings match dataset relations |
| Sync existing data list pages | rabetbase page sync --datasetcode <code> |
After dataset field changes, sync to associated data list pages |
| Pull the data list page schema to local | rabetbase page pull --id <pageId> |
Write .rabetbase/page/<appCode>/, and enter the local editing workflow |
| Push the local data list page schema | rabetbase page push --id <pageId> |
After pushing, automatically pull back the canonical schema to overwrite local |
| Restore a deleted page | rabetbase page restore --id <pageId> |
Supports `DATA_LIST |
| Database connection (dblink) / connection test / structure analysis | rabetbase db list starting from |
id、trace/plan id and the completion criteria of "terminal state + rerun diff" are described in database-connection-workflow.md; for each subcommand, see references/rabetbase-db-*.md |
| Generate / update API client code | rabetbase api pull → sdk-client-generation.md |
api pull Pull Dataset facts and refresh sdk-config.ts; existing api.ts/client.ts merge and update according to the guide |
| View generated API models | rabetbase api list |
List generated data models |
| View existing SQL | rabetbase sql list --name "xxx" |
Paginate, filter by name; by default query the single application resolved currently |
| View SQL details | rabetbase sql detail --sqlcode xxx |
Includes the complete SQL content and parameter definitions |
| Create local sync SQL | rabetbase sql create --name xxx --db-id 10001 --mode sql |
Create it remotely first, then write it to the local file and sql.lock.json |
| View local sync status | rabetbase sql status |
Check added / modified / missing / unchanged / remoteOnly |
| Pull remote SQL to local | rabetbase sql pull |
Write `.rabetbase/sql//<dbName |
| Push local SQL to remote | rabetbase sql push --sqlcode xxx |
write; using sql.lock.json as the baseline, upload local files in the sync directory |
| Delete SQL | rabetbase sql delete --sqlcode xxx --yes |
Delete remotely and move the local file into .rabetbase/sql-trash/ |
| Validate SQL content | rabetbase sql validate --file xxx |
Type detection, dangerous statement checks, parameter extraction |
| Execute SQL query | rabetbase sql exec --sqlcode xxx |
Supports --params JSON parameters |
| View existing Backend Function | rabetbase bff list |
Filter by type and name, supports --app to restrict the application |
| View Backend Function details | rabetbase bff detail --id n |
Includes the complete script content |
| Create local Backend Function | rabetbase bff create --type ENDPOINT --name xxx |
Under .rabetbase/bff/<appCode>/... create a scaffold |
| View Backend Function local status | rabetbase bff status |
Check added / modified / unchanged / remoteOnly |
| Pull remote Backend Function | rabetbase bff pull |
Sync from remote to local |
| Push local Backend Function | rabetbase bff push |
write; dry-run is recommended first; formal execution does not require --yes |
| Delete Backend Function | rabetbase bff delete --yes --target xxx |
high-risk-write, delete remote and clean up local |
| Generate SDK code | rabetbase codegen sdk --code xxx |
Generate TypeScript by operation |
| Generate SQL call code | rabetbase codegen sql --sqlcode xxx |
Two targets: sdk/bff |
| List configured applications | rabetbase app list |
Default merged view;--global / --project limit to a single layer;items[].named、meta see reference |
| Discover applications accessible on the platform | rabetbase app list --remote |
Query the current logged-in account's application directory on the platform without modifying local configuration |
| Query application personnel and role assignments | rabetbase app members-list --appcode <code> |
Fully read-only; deduplicate by userId, aggregate role assignments to roles[] |
| Query tenant personnel | rabetbase tenant members-list --tenant-code <code> |
Fully read-only; the tenant must belong to the current account |
| View app service help | rabetbase app |
Only show app subcommand help, not equivalent to app list |
| Bind the current directory to an application | rabetbase workspace init --appcode <code> |
First-time binding; a single application is automatically selected and defaultAppis not written; different from config init(global onboarding) |
| Switch the default application for the current working directory | rabetbase workspace use --app <name> |
Persistently modify the current directory's defaultApp |
| Register application | rabetbase workspace add <name> --appcode <code> |
A single application does not write default; when adding a second application, keep the original application as default;--global write global |
| Remove application | rabetbase workspace remove <name> |
Only remove the local profile; automatically switch default after removal |
| Temporarily switch application for execution | Add to any command --app <name> or --appcode <code> |
Do not modify the configuration file |
| View configuration file format | .rabetbase.json configuration reference |
Complete fields, priority, environment variables |
Command groups
Must do before execution: After locating the command from the table below, be sure to read the reference documentation for the corresponding command before invoking the command.
Risk control
All declarative commands have risk level:
| Level | Meaning | Usage |
|---|---|---|
read |
Does not create, update, or delete business data; allows remote reads followed by generation of reconstructable local files or maintenance of the local CLI | Can be executed directly |
write |
Create or modify data and local configuration within a controllable scope | When the command supports dry-run, check the preview first |
high-risk-write |
Overwrite, delete, or significantly affect online runtime behavior | Complete dry-run, plan, or explicit confirmation according to the command reference |
The risk, flags, and confirmation requirements for a specific command are subject to rabetbase schema is the single source of truth; reference only describes stable execution inputs, outputs, and security prerequisites.
sql validate is the entry point for SQL content validation; SQL writes go uniformly through sql create or execute after editing the sync file sql push。
Configuring riskLevel can limit the maximum risk level allowed for execution; the default value is write(see Configuration Reference). When permissions are insufficient, the Agent can only remind the user to manually edit .rabetbase.json;Agents or automation scripts are prohibited from modifying riskLevelon their own, writing environment variables, or attempting privilege escalation by other means。
Output format
Declarative commands uniformly use standard envelope:ok、command、risk, optional data(on failure it may have error , etc.; refer to actual output).
| Format | Purpose | Description |
|---|---|---|
--format compress |
AI / script preferred | and json semantically identical,Single-line compact, no indentation or line breaks, significantly saves tokens |
--format json |
Program parsing, debugging | Same envelope as above,indented, convenient for manual reading |
--format pretty |
Human reading (common default when format is not specified) | Non-JSON colored text |
--format table |
List data | Table |
--jq '<expr>'(global): only works with json or compress; forthe final printed entire JSON segmentexecute jq (the expression acts on the envelope, for example to get data fields in data use .data.xxx)。jq executableaccording to JQ_PATH → CLI built-in sidecar jq → PATH jq on resolution order. If JQ_PATHis explicitly set, it must point to a real executable file; otherwise the command will directly error and will not silently fall back.
Unsure about subcommands, flags, risk, or whether appcode is needed: execute rabetbase schema(i.e. schema export,no authentication required), outputs machine-readable metadata from the same source as rabetbase --help ; see references/rabetbase-schema.md and repository docs/user-guide/12-schema命令.md。
Common Errors Quick Reference
| Error type | Meaning | Solution |
|---|---|---|
auth_required |
Not logged in | Execute rabetbase auth |
config_missing |
appcode not configured | rabetbase workspace init --appcode <code> or pass --appcode |
flag_missing |
Missing required parameter | Check the reference documentation to confirm required flags |
validation_error |
Input validation failed (including SQL type blocking) | Check SQL content or parameter format |
api_error |
Backend API error | Check appcode, network, and permissions |
cancelled |
User canceled a high-risk operation | Use --yes to skip confirmation, or modify riskLevel |
blocked |
Platform conflict detection or resource status conflict (common in legacy save paths or platform-side restrictions) | Clearly state that the remote write was not completed, and guide the user to handle it on the platform or switch to a sync workflow |
Conflict handling
Whenever blocked: true、action: "blocked"appears, or other explicit indication ofremote write not successfulreturn: must directly state that "the platform did not save/did not sync successfully"; when necessary, guide the user to handle it on the platform or return to create + 本地编辑 + push workflow;retrying to bypass is prohibited, and whitewashing as saved is prohibited. For the complete branch table, response JSON examples, and communication requirements, see guides/conflict-detection.md。
front-end page rules
- the top comments generated by the CLI for the page must be retained; append explanations using
@modified - page component settings
displayName - before writing a page, you must
dataset detailconfirm the fields and relationships - emoji, AI-sounding copy, exclamation marks, and flashy colors are prohibited; copy should be concise and professional
- use
@ant-design/iconsfor icons, and AntD tokens for colors
in-depth guide
document layering:references/ by single CLI command(read the corresponding page before execution);guides/ by cross-cutting topic(workflow, data access, front-end/back-end specifications). The two work together for progressive disclosure in the SKILL body.
The following guides provide detailed explanations, examples, and edge cases:
| Topic | Use when | Guide |
|---|---|---|
| Complete SDK parameters and return values | initialize client, filter/create, sql.execute, bff.execute, error handling | typescript-sdk.md |
| generate / update api.ts and client.ts | api pull after, model expiration, missing scaffold, or the user requests SDK client repair |
sdk-client-generation.md |
| SQL MyBatis and dynamic SQL | write custom SQL,<if>/<foreach>, parameter binding |
sql-mybatis.md |
| Front-end page development constraints | React pages, forms, lists, and dataset binding | frontend-development.md |
| Troubleshooting | troubleshooting for CLI/login/dataset/save failures | troubleshooting.md |
| Backend Function script specifications | HOOK/ENDPOINT/COMMON、context.client, message notification extensions, directories, and comment templates |
backend-function.md |
| Data interface access | detail first, then code; foreign keys/enums; N+1 prohibited; batch and related queries; hand over when validating real row data lovrabet data(lovrabet CLI ≥ 2.0) |
data-api-guidelines.md |
| SQL creation workflow | full chain: list/detail → pull/create → edit → validate → status → push/delete → exec | sql-creation-workflow.md |
| Backend Function creation workflow | new → status → dry-run → pull/push | bff-creation-workflow.md |
| Conflict detection and saving | blocked, user communication when unsaved, response structure |
conflict-detection.md |
| Quality and best practices | review SQL/Backend Function, naming, high-risk boundaries, description fields | best-practices.md |
| Database connection and analysis | connect/change connection/test connection,traceId sources,db analyze-* division of labor with dataset; for the subcommand quick reference, see above "Database connection (db)" |
database-connection-workflow.md |
| Menu anomaly audit and security repair | duplicate path, root-level menu name duplication, empty folder deletion plan, and recheck after platform handling | menu-anomaly-manual-cleanup.md |