Skip to content

Commit d54be28

Browse files
os-zhuangclaude
andauthored
docs(site): mermaid rendering, stat removal, and full-corpus persona-review fixes (#2601)
* docs(site): render mermaid code fences as diagrams Fumadocs was showing ```mermaid blocks (used on 7 pages: protocol diagram, kernel architecture, data-flow, permissions matrix, field-type decision tree, contracts, metadata-service) as plain code. Add a client-side Mermaid component (theme-aware, falls back to the source block on bad syntax) and a remark plugin that rewrites mermaid fences into <Mermaid chart=.../> — no content changes required. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018r9mjpF7jr9BKdzEmUE4uZ * docs(site): drop numeric stats; first round of persona-review fixes Per review feedback, remove count-style statistics from module overviews and landing (field type counts, hook event counts, namespace tallies) in favor of qualitative descriptions — counts drift from the implementation and don't help readers. Also lands the first fixes from the reader-persona review pass: - ai/actions-as-tools: remove walkthrough of HITL demo tests that do not exist in examples/app-todo (only mcp-actions/seed tests exist); point at the real delete_completed danger action instead - ai/agents, ai/natural-language-queries: fix orphaned 'see above' references and same-page anchors that now live on sibling pages Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018r9mjpF7jr9BKdzEmUE4uZ * docs(site): full-corpus persona review — fix what real readers would hit Seven reader-persona passes (first-time developer, schema modeler, logic author + API integrator, security admin, UI builder + AI admin, plugin developer, production SRE) read every hand-written page and verified claims against source before fixing. Highlights: - hooks: ctx.input is flat (installFlatInput) — the documented ctx.input.doc pattern never worked; fixed across hooks, events, error-handling-server, and the plugin tutorial - plugin tutorial: manifest example was missing required id (threw at parse) and registered a kernel hook name that never fires — a reader shipped a silently dead plugin; rewritten against engine.registerHook - permissions: removed the false implicit manager-visibility claim (role hierarchy grants nothing by itself); owner-type sharing rules and group/guest recipients marked declared-but-unenforced; FLS semantics corrected to default-visible for undeclared fields; no-sharingModel = no record filter warning added - data modeling: removed invented cdc/partitioning/recordTypes object config (schema hard-rejects), phantom field props (pruned 2026-06), wrong autonumber key; new expand (related records) query section - api: removed ADR-0019-deleted workflow approve/reject endpoints, invented webhook rate-limiting; realtime status stated honestly (in-process pub/sub; WS/SSE transport plugin-provided); error handling documents the two real wire formats - protocol: maskingRule/encryptionConfig sections re-scoped to their real status (System schemas exist; field wiring pruned, channel is type:'secret' + FLS) - deployment: env-var table repaired and completed (OS_SECRET_KEY, cluster vars), stale CLI paths and ten dead links fixed - onboarding: REST route /api/v1/data/:object, send_email→notify node, npx os pointers, nine dead ADR links - runtime-services: binding note — services.* is the contract surface; open-framework hooks use ctx.api / ctx.getService Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018r9mjpF7jr9BKdzEmUE4uZ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 93e6d02 commit d54be28

76 files changed

Lines changed: 1478 additions & 608 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/docs/components/mermaid.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use client';
2+
3+
import { useEffect, useId, useState } from 'react';
4+
import { useTheme } from 'next-themes';
5+
6+
/**
7+
* Client-side Mermaid renderer. Code fences with the `mermaid` language are
8+
* rewritten to <Mermaid chart="..."/> by the remark plugin in source.config.ts,
9+
* so authors keep writing standard ```mermaid blocks.
10+
*/
11+
export function Mermaid({ chart }: { chart: string }) {
12+
const id = useId();
13+
const [svg, setSvg] = useState('');
14+
const { resolvedTheme } = useTheme();
15+
16+
useEffect(() => {
17+
let cancelled = false;
18+
19+
async function render() {
20+
const { default: mermaid } = await import('mermaid');
21+
mermaid.initialize({
22+
startOnLoad: false,
23+
securityLevel: 'strict',
24+
fontFamily: 'inherit',
25+
theme: resolvedTheme === 'dark' ? 'dark' : 'default',
26+
});
27+
try {
28+
const rendered = await mermaid.render(
29+
// mermaid requires a DOM-safe element id
30+
`mermaid-${id.replace(/[^a-zA-Z0-9]/g, '')}`,
31+
chart,
32+
);
33+
if (!cancelled) setSvg(rendered.svg);
34+
} catch {
35+
// Leave the diagram source visible instead of a blank hole on bad syntax.
36+
if (!cancelled) setSvg('');
37+
}
38+
}
39+
40+
void render();
41+
return () => {
42+
cancelled = true;
43+
};
44+
}, [chart, id, resolvedTheme]);
45+
46+
if (!svg) {
47+
return (
48+
<pre className="overflow-x-auto rounded-lg border p-4 text-sm">
49+
<code>{chart}</code>
50+
</pre>
51+
);
52+
}
53+
54+
return (
55+
<div
56+
className="my-6 flex justify-center overflow-x-auto [&_svg]:max-w-full"
57+
dangerouslySetInnerHTML={{ __html: svg }}
58+
/>
59+
);
60+
}

apps/docs/mdx-components.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import defaultMdxComponents from 'fumadocs-ui/mdx';
22
import type { MDXComponents } from 'mdx/types';
3+
import { Mermaid } from '@/components/mermaid';
34

45
export function getMDXComponents(components?: MDXComponents): MDXComponents {
56
return {
67
...defaultMdxComponents,
8+
Mermaid,
79
...components,
810
};
911
}

apps/docs/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
"fumadocs-mdx": "15.0.12",
1818
"fumadocs-ui": "16.10.5",
1919
"lucide-react": "^1.22.0",
20+
"mermaid": "^11.16.0",
2021
"next": "16.2.9",
22+
"next-themes": "^0.4.6",
2123
"react": "^19.2.7",
2224
"react-dom": "^19.2.7",
23-
"tailwind-merge": "^3.6.0"
25+
"tailwind-merge": "^3.6.0",
26+
"unist-util-visit": "^5.1.0"
2427
},
2528
"devDependencies": {
2629
"@objectstack/spec": "workspace:*",

apps/docs/source.config.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@ import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
22
import { metaSchema, pageSchema } from 'fumadocs-core/source/schema';
33
import { z } from 'zod';
44
import path from 'node:path';
5+
import { visit } from 'unist-util-visit';
6+
7+
/**
8+
* Rewrite ```mermaid code fences into <Mermaid chart="..."/> elements so
9+
* diagrams render as SVG (components/mermaid.tsx) instead of code blocks.
10+
*/
11+
function remarkMermaid() {
12+
return (tree: any) => {
13+
visit(tree, 'code', (node: any, index: number | undefined, parent: any) => {
14+
if (node.lang !== 'mermaid' || !parent || index === undefined) return;
15+
parent.children[index] = {
16+
type: 'mdxJsxFlowElement',
17+
name: 'Mermaid',
18+
attributes: [{ type: 'mdxJsxAttribute', name: 'chart', value: node.value }],
19+
children: [],
20+
};
21+
});
22+
};
23+
}
524

625
export const docs = defineDocs({
726
dir: path.resolve(process.cwd(), '../../content/docs'),
@@ -31,6 +50,6 @@ export const blog = defineDocs({
3150

3251
export default defineConfig({
3352
mdxOptions: {
34-
// MDX options
53+
remarkPlugins: (v) => [...v, remarkMermaid],
3554
},
3655
});

content/docs/ai/actions-as-tools.mdx

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -116,21 +116,13 @@ The queue is exposed via four REST endpoints (`GET`, `GET/:id`, `POST/:id/approv
116116

117117
### End-to-end example
118118

119-
Two runnable demos live in `examples/app-todo/test/`:
120-
121-
- **`ai-hitl.test.ts`** — drives the tool registry directly (no LLM dependency). Asserts the full lifecycle: `variant:'danger'` action registered as a tool → invocation returns `pending_approval` without executing → row persisted → `approvePendingAction(id, actor)` re-runs the handler → row transitions to `executed`. Reject path is also covered.
122-
123-
```bash
124-
pnpm --filter @example/app-todo test:hitl
125-
```
126-
127-
- **`ai-hitl-llm.test.ts`** — same scenario but with a real model behind Vercel AI Gateway. The LLM is given the auto-generated tool description and asked to "delete all completed tasks"; the framework returns `pending_approval` so the model summarises the wait instead of retrying. After we call approve from the test, the deletion completes.
128-
129-
```bash
130-
AI_GATEWAY_API_KEY=vck_... pnpm --filter @example/app-todo test:hitl:llm
131-
```
132-
133-
Gated on `AI_GATEWAY_API_KEY` (or `OPENAI_API_KEY`); exits 0 with a notice if no key is provided, so it can be wired into CI without leaking spend.
119+
The full lifecycle: a `variant:'danger'` action registered as a tool →
120+
invocation returns `pending_approval` without executing → row persisted →
121+
`approvePendingAction(id, actor)` re-runs the handler → row transitions to
122+
`executed` (the reject path mirrors it). The todo example's
123+
`delete_completed` action (`examples/app-todo/src/actions/task.actions.ts`)
124+
is authored exactly for this: `variant: 'danger'` + `confirmText` route it
125+
through the approval queue.
134126

135127
A trimmed view of the integration path:
136128

content/docs/ai/agents.mdx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ is in — the user never picks from a roster:
1818

1919
Both agents are part of the **cloud / Enterprise** in-UI AI runtime (cloud ADR-0025).
2020
The **open edition** ships neither — it uses `@objectstack/mcp` (BYO-AI) for data
21-
query and source-mode authoring instead (see the note above).
21+
query and source-mode authoring instead (see the callout in the
22+
[AI Overview](/docs/ai)).
2223

2324
Within the cloud / EE runtime there is no per-turn intent classifier and no agent
2425
dropdown: the surface binds the agent (data console → `ask`, Studio → `build`). A
@@ -64,7 +65,7 @@ them via the chat endpoint.
6465
<Callout type="info">
6566
Agent tools are **references** to existing Actions, Flows, or queries — you do
6667
not define ad-hoc tool names with inline parameter schemas here. See
67-
[Actions as Tools](#actions-as-tools-explicit-opt-in) for how an Action becomes
68+
[Actions as Tools](/docs/ai/actions-as-tools) for how an Action becomes
6869
LLM-callable.
6970
</Callout>
7071

@@ -219,7 +220,7 @@ Use the data tools to query records and aggregate metrics.`,
219220
},
220221

221222
// Built-in data tools (query_records / get_record / aggregate_data) are
222-
// available to agents automatically once registered — see "Actions as Tools".
223+
// available to agents automatically once registered — see "Natural Language Queries".
223224
tools: [
224225
{ type: 'flow', name: 'analyze_pipeline', description: 'Analyze sales pipeline health' },
225226
],

content/docs/ai/chatbot-integration.mdx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ This guide maps every chatbot configuration knob to its framework endpoint
2626
so you can drop the plugin into an app without reverse-engineering the
2727
contract.
2828

29-
## 1. Enable the AI tier on the framework side
29+
## 1. Enable the AI tier on the backend
3030

31-
The `default` and `full` plugin tier presets both include the `ai`
32-
capability, so `objectstack dev` boots the AI services unless you opt out
33-
with `--preset minimal`. Provide a Vercel AI Gateway model and key via env
34-
vars:
31+
On a cloud / EE dev host (where `@objectstack/service-ai` is available —
32+
see the callout above), the `default` and `full` plugin tier presets both
33+
include the `ai` capability, so `objectstack dev` boots the AI services
34+
unless you opt out with `--preset minimal`. Provide a Vercel AI Gateway
35+
model and key via env vars:
3536

3637
```bash
3738
AI_GATEWAY_API_KEY=vck_*** \

content/docs/ai/knowledge-rag.mdx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ kernel.use(new KnowledgeMemoryPlugin());
4040
// kernel.use(new KnowledgeRagflowPlugin({ endpoint, apiKey }));
4141
```
4242

43-
Then register the AI tool so agents can call it:
43+
Then register the AI tool so agents can call it. (This step uses
44+
`@objectstack/service-ai`, i.e. the **cloud / Enterprise** in-UI AI runtime —
45+
see the callout in the [AI Overview](/docs/ai). The Knowledge Protocol itself
46+
and the adapter plugins above ship in the open framework.)
4447

4548
```ts
4649
import { registerKnowledgeTools } from '@objectstack/service-ai';

content/docs/ai/natural-language-queries.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ description: How agents query live data through the built-in data tools (query_r
77

88
Part of the [AI module](/docs/ai) — how natural-language questions become ObjectQL queries at runtime.
99

10+
The data tools described here ship with `@objectstack/service-ai`, i.e. the
11+
**cloud / Enterprise** in-UI AI runtime (see the callout in the
12+
[AI Overview](/docs/ai)). On the open edition, point your own AI at the same
13+
objects and queries through `@objectstack/mcp` instead.
14+
1015
Agents query your data through the built-in **data tools**
1116
`query_records`, `get_record`, and `aggregate_data` — which the LLM calls with
1217
structured arguments. These run as ordinary [ObjectQL](/docs/protocol/objectql) queries over

content/docs/api/client-sdk.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ The `@objectstack/client` SDK aims to implement the ObjectStack API protocol spe
122122
| **storage** || 2 | File upload & download |
123123
| **i18n** || 3 | Internationalization |
124124
| **notifications** | 🟡 | 7 | Legacy notification helpers; receipt/inbox cut-over pending |
125-
| **realtime** || 6 | WebSocket subscriptions |
125+
| **realtime** || 6 | Connection/subscription/presence calls (server transport is plugin-provided) |
126126
| **ai** || 3 | AI services (NLQ, suggest, insights) |
127127

128128
<Callout type="info">
@@ -553,18 +553,18 @@ For detailed information about the client's protocol implementation:
553553

554554
<Cards>
555555
<Card
556-
href="./api-reference"
557-
title="API Reference"
556+
href="/docs/api/data-api"
557+
title="Data API"
558558
description="Complete REST endpoint documentation"
559559
/>
560560
<Card
561-
href="./kernel-services"
561+
href="/docs/kernel/services-checklist"
562562
title="Kernel Services"
563563
description="Service checklist and plugin development guide"
564564
/>
565565
<Card
566-
href="../references/api/protocol"
566+
href="/docs/references/api/protocol"
567567
title="Protocol Types"
568-
description="All 57 Zod protocol schemas"
568+
description="The Zod protocol schemas"
569569
/>
570570
</Cards>

0 commit comments

Comments
 (0)