@agent-native/core 0.153.8 → 0.153.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/corpus/templates/analytics/app/pages/DataSources.tsx +2 -1
  2. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueList.tsx +4 -2
  3. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +4 -2
  4. package/corpus/templates/clips/app/root.tsx +4 -1
  5. package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -2
  6. package/corpus/templates/clips/desktop/src/app.tsx +1 -1
  7. package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +2 -1
  8. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +2 -1
  9. package/corpus/templates/plan/app/pages/PlansPage.tsx +5 -2
  10. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +5 -3
  11. package/dist/cli/skills-content/help.d.ts +1 -1
  12. package/dist/cli/skills-content/help.js +2 -1
  13. package/dist/cli/skills.js +2 -1
  14. package/dist/client/NewWorkspaceAppFlow.js +4 -1
  15. package/dist/client/agent-page/AgentTabsPage.d.ts +2 -2
  16. package/dist/client/agent-page/AgentTabsPage.js +12 -9
  17. package/dist/client/extensions/ExtensionsSidebarSection.js +2 -1
  18. package/dist/client/hooks/index.d.ts +1 -1
  19. package/dist/client/hooks/index.js +1 -1
  20. package/dist/client/onboarding/FirstRunOnboarding.js +2 -1
  21. package/dist/client/org/TeamPage.js +14 -3
  22. package/dist/client/settings/SettingsPanel.js +26 -1
  23. package/dist/collab/routes.d.ts +1 -1
  24. package/dist/integrations/catalog.js +9 -8
  25. package/dist/notifications/routes.d.ts +1 -1
  26. package/dist/observability/routes.d.ts +3 -3
  27. package/dist/progress/routes.d.ts +1 -1
  28. package/dist/server/agent-chat-plugin.js +2 -2
  29. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  30. package/dist/server/onboarding-html.js +2 -1
  31. package/dist/server/realtime-token.d.ts +1 -1
  32. package/dist/shared/docs-url.d.ts +24 -0
  33. package/dist/shared/docs-url.js +39 -0
  34. package/dist/shared/index.d.ts +1 -0
  35. package/dist/shared/index.js +1 -0
  36. package/dist/templates/default/app/routes/_index.tsx +2 -1
  37. package/docs/content/client-advanced.mdx +200 -0
  38. package/docs/content/client-agent-chat.mdx +313 -0
  39. package/docs/content/client-data.mdx +432 -0
  40. package/docs/content/client-entry-points.mdx +27 -0
  41. package/docs/content/client-overview.mdx +206 -0
  42. package/docs/content/client-routing.mdx +121 -0
  43. package/docs/content/client-sync-internals.mdx +124 -0
  44. package/docs/content/context-awareness.mdx +1 -1
  45. package/docs/content/docs-components.mdx +201 -0
  46. package/docs/content/drop-in-agent.mdx +1 -1
  47. package/docs/content/internationalization.mdx +1 -1
  48. package/docs/content/key-concepts.mdx +4 -0
  49. package/docs/content/notifications.mdx +1 -1
  50. package/docs/content/progress.mdx +2 -2
  51. package/docs/content/real-time-collaboration.mdx +2 -2
  52. package/docs/content/template-chat-developers.mdx +1 -1
  53. package/docs/content/toolkit-command-navigation.mdx +1 -1
  54. package/package.json +3 -3
  55. package/src/templates/default/app/routes/_index.tsx +2 -1
  56. package/docs/content/client.mdx +0 -486
  57. package/docs/content/routing.mdx +0 -119
@@ -0,0 +1,121 @@
1
+ ---
2
+ title: "Routing"
3
+ description: "File-based routing for agent-native apps with React Router v8: pages, dynamic params, and navigation."
4
+ ---
5
+
6
+ # Routing
7
+
8
+ Agent-native apps use **React Router v8** with file-based routing via `flatRoutes()` from `@react-router/fs-routes`. Every file in `app/routes/` becomes a URL. Templates use the dot-notation convention. Dots separate URL segments inside a single filename.
9
+
10
+ This page covers client routes, the pages rendered in the browser from `app/routes/`. Server routes are a separate system: Nitro file routes under `server/routes/`, plus the framework's own `/_agent-native/*` endpoints. Those live on the [Routes](/docs/server-routes) page. The two don't share a directory, a naming convention, or a router, so a `server/routes/` file never becomes a page here and an `app/routes/` file never becomes a server endpoint.
11
+
12
+ <Diagram id="doc-block-client-routing-1" title="File name → URL" summary="Each file in app/routes/ becomes a URL. Dots become slashes, and a $ segment becomes a dynamic param.">
13
+
14
+ ```html
15
+ <div class="diagram-filemap">
16
+ <div class="diagram-filemap-row">
17
+ <span class="diagram-node">_index.tsx</span>
18
+ <span class="diagram-arrow diagram-muted" aria-hidden="true">&rarr;</span>
19
+ <span class="diagram-pill accent">/</span>
20
+ </div>
21
+ <div class="diagram-filemap-row">
22
+ <span class="diagram-node">dashboard.tsx</span>
23
+ <span class="diagram-arrow diagram-muted" aria-hidden="true">&rarr;</span>
24
+ <span class="diagram-pill accent">/dashboard</span>
25
+ </div>
26
+ <div class="diagram-filemap-row">
27
+ <span class="diagram-node">dashboard_.$ticketId.tsx</span>
28
+ <span class="diagram-arrow diagram-muted" aria-hidden="true">&rarr;</span>
29
+ <span class="diagram-pill accent">/dashboard/:ticketId</span>
30
+ </div>
31
+ </div>
32
+ ```
33
+
34
+ ```css
35
+ .diagram-filemap {
36
+ display: flex;
37
+ flex-direction: column;
38
+ gap: 10px;
39
+ }
40
+ .diagram-filemap-row {
41
+ display: flex;
42
+ align-items: center;
43
+ gap: 10px;
44
+ flex-wrap: wrap;
45
+ }
46
+ .diagram-filemap-row .diagram-arrow {
47
+ font-size: 18px;
48
+ line-height: 1;
49
+ }
50
+ ```
51
+
52
+ </Diagram>
53
+
54
+ ## File-based routing {#file-based-routing}
55
+
56
+ ### File → URL mapping
57
+
58
+ | File | URL | Notes |
59
+ | -------------------------- | ---------------------- | ------------------------------------------------------------------------- |
60
+ | `_index.tsx` | `/` | Index route |
61
+ | `dashboard.tsx` | `/dashboard` | Simple page |
62
+ | `extensions.$id.tsx` | `/extensions/:id` | Nests inside `extensions.tsx`'s `<Outlet/>`. `$` is a dynamic param |
63
+ | `dashboard_.$ticketId.tsx` | `/dashboard/:ticketId` | Trailing `_` skips nesting under `dashboard.tsx`, so this is its own page |
64
+ | `_app.tsx` | (no URL segment) | Pathless layout. Prefix with `_` |
65
+ | `inbox/route.tsx` | `/inbox` | Folder form. `route.tsx` is the index |
66
+
67
+ Prefix a segment with `$` for a dynamic param. Prefix with `_` to make it a pathless layout route (no URL segment), or add a trailing `_` before a dot to opt a nested-looking path out of nesting under its parent's layout. Templates use `flatRoutes()`. The dot-notation file above is primary. The nested-folder form `inbox/route.tsx` also works.
68
+
69
+ ## Adding a new page {#adding-a-page}
70
+
71
+ Create the file and export a default component:
72
+
73
+ ```tsx filename="app/routes/settings.tsx"
74
+ export function meta() {
75
+ return [{ title: "Settings" }];
76
+ }
77
+
78
+ export default function SettingsPage() {
79
+ return <div>Settings</div>;
80
+ }
81
+ ```
82
+
83
+ That's it. The dev server reads route files at startup. If `pnpm dev` is already running, restart it after adding the file. No registration is needed.
84
+
85
+ ## Dynamic params {#dynamic-params}
86
+
87
+ ```tsx filename="app/routes/dashboard_.$ticketId.tsx"
88
+ import { useParams } from "react-router";
89
+
90
+ export default function TicketDetailPage() {
91
+ const { ticketId } = useParams();
92
+ return <div>Ticket: {ticketId}</div>;
93
+ }
94
+ ```
95
+
96
+ The trailing `_` before the dot keeps this page from nesting inside `dashboard.tsx`'s `<Outlet/>`, so it renders as its own full page at `/dashboard/:ticketId` instead of appearing inside the ticket queue's layout.
97
+
98
+ ## Navigation {#navigation}
99
+
100
+ Use `<Link>` for client-side navigation and `useNavigate()` for programmatic navigation:
101
+
102
+ ```tsx
103
+ import { Link, useNavigate } from "react-router";
104
+
105
+ // In JSX
106
+ <Link to="/dashboard">Dashboard</Link>;
107
+
108
+ // Programmatic
109
+ const navigate = useNavigate();
110
+ navigate(`/dashboard/${ticketId}`);
111
+ ```
112
+
113
+ Neither of these tells the agent what the user is looking at on their own. That's a separate concern, handled by `useAgentRouteState()` writing the current route into application state. See [Context Awareness](/docs/context-awareness).
114
+
115
+ ## What's next
116
+
117
+ - [**Overview**](/docs/client-overview) — where `app/routes/` fits among the rest of `app/` and `public/`
118
+ - [**Data & Sync**](/docs/client-data) — reading and writing data from inside a route
119
+ - [**Agent Chat**](/docs/client-agent-chat) — sending prompts and staging context from a route
120
+ - [**Routes**](/docs/server-routes) — the separate server-routing system: file routes under `server/routes/` and the framework's `/_agent-native/` namespace
121
+ - [**Context Awareness**](/docs/context-awareness) — how the agent learns the current route and selection
@@ -0,0 +1,124 @@
1
+ ---
2
+ title: "Sync Internals"
3
+ description: "The change-version mechanism behind useDbSync: useChangeVersion/useChangeVersions for syncing a raw useQuery, and the two latency paths a refetch can take."
4
+ ---
5
+
6
+ # Sync Internals
7
+
8
+ [Live Sync](/docs/key-concepts#polling-sync) covers the mental model: an agent write becomes a change event, `useDbSync()` picks it up, and affected queries refetch. This page covers the mechanism underneath that most apps never touch directly: the change-version counters `useDbSync()` bumps, and how to fold them into a raw `useQuery()` call that isn't going through `useActionQuery()`.
9
+
10
+ `useActionQuery()` already refetches automatically when a mutating action completes (see [Data & Sync](/docs/client-data#fetching-mutating)). Reach for `useChangeVersion()`/`useChangeVersions()` only when you're syncing a raw `useQuery()` call outside that path, such as a low-level client helper reading integration status.
11
+
12
+ ## How change versions work {#how-it-works}
13
+
14
+ When a server-side database mutation occurs, the server records a change event tagged with a `source` key. `useDbSync()` receives that event and bumps a local counter for that source. Folding the counter into a React Query key makes the query refetch automatically whenever the backend reports new activity for that source.
15
+
16
+ ## useChangeVersion / useChangeVersions {#use-change-version}
17
+
18
+ <Signature
19
+ id="doc-block-client-sync-internals-1"
20
+ name="useChangeVersion"
21
+ params={[
22
+ {
23
+ name: "source",
24
+ type: "string",
25
+ description: 'The change-event source to watch, e.g. `"dashboards"`.',
26
+ },
27
+ ]}
28
+ returns={{
29
+ type: "number",
30
+ description:
31
+ "A counter that increments whenever the given source is mutated.",
32
+ }}
33
+ />
34
+
35
+ <Signature
36
+ id="doc-block-client-sync-internals-2"
37
+ name="useChangeVersions"
38
+ params={[
39
+ {
40
+ name: "sources",
41
+ type: "readonly string[]",
42
+ description: "Multiple change-event sources to watch at once.",
43
+ },
44
+ ]}
45
+ returns={{
46
+ type: "number",
47
+ description: "The sum of the version counters for every given source.",
48
+ }}
49
+ />
50
+
51
+ In the example below, a raw `useQuery()` call reads a dashboard directly, folding the `"dashboards"` source's version counter into its query key so it refetches whenever that source changes:
52
+
53
+ ```tsx
54
+ import { useQuery } from "@tanstack/react-query";
55
+ import { useChangeVersion } from "@agent-native/core/client/hooks";
56
+
57
+ function DashboardView({ id }) {
58
+ const version = useChangeVersion("dashboards");
59
+
60
+ const { data } = useQuery({
61
+ queryKey: ["dashboard", id, version],
62
+ queryFn: () => fetchDashboard(id),
63
+ placeholderData: (prev) => prev,
64
+ });
65
+
66
+ return <div>{data?.title}</div>;
67
+ }
68
+ ```
69
+
70
+ `placeholderData: (prev) => prev` keeps the previous data on screen during the refetch, so the view doesn't flicker to a loading state.
71
+
72
+ ## Two paths to a refetch {#latency-models}
73
+
74
+ A mutation reaches the UI one of two ways, and they have different latency.
75
+
76
+ A local mutation, one your own `useActionMutation()` call just made, fires a `source: "action"` event as soon as it succeeds. Every query depending on that action refetches immediately. There's no round-trip delay, since the tab that made the write already knows about it.
77
+
78
+ A remote mutation, from the agent, a webhook, another tab, or another user, has to reach this tab first. `useDbSync()` picks it up over SSE almost immediately, or over the polling fallback within about two seconds if SSE isn't available. Only once that event arrives does the relevant version counter bump and the query refetch in the background.
79
+
80
+ <Diagram id="doc-block-client-sync-internals-3" title="Two paths to a refetch" summary="A local mutation invalidates its own caches instantly. A remote write reaches this tab over SSE, or the polling tick as a fallback.">
81
+
82
+ ```html
83
+ <div class="diagram-latency">
84
+ <div class="diagram-col">
85
+ <div class="diagram-card" data-rough>
86
+ <span class="diagram-pill ok">This tab</span
87
+ ><strong>useActionMutation</strong
88
+ ><small class="diagram-muted"
89
+ >fires source: "action" on success &rarr; instant local refetch</small
90
+ >
91
+ </div>
92
+ <div class="diagram-card" data-rough>
93
+ <span class="diagram-pill accent">Agent · webhook · other tab</span
94
+ ><strong>Remote write</strong
95
+ ><small class="diagram-muted"
96
+ >SSE push, or the ~2s polling tick as fallback &rarr; version bumps
97
+ &rarr; background refetch</small
98
+ >
99
+ </div>
100
+ </div>
101
+ </div>
102
+ ```
103
+
104
+ ```css
105
+ .diagram-latency .diagram-col {
106
+ display: flex;
107
+ flex-direction: column;
108
+ gap: 12px;
109
+ }
110
+ .diagram-latency .diagram-card {
111
+ display: flex;
112
+ flex-direction: column;
113
+ gap: 4px;
114
+ padding: 14px 16px;
115
+ }
116
+ ```
117
+
118
+ </Diagram>
119
+
120
+ ## What's next
121
+
122
+ - [**Live Sync**](/docs/key-concepts#polling-sync) — the conceptual mental model this page goes underneath
123
+ - [**Data & Sync**](/docs/client-data) — `useActionQuery`/`useDbSync`, which most pages should use instead of these primitives
124
+ - [**Advanced**](/docs/client-advanced) — the other lower-level client primitives and escape hatches
@@ -486,5 +486,5 @@ How it works:
486
486
  - [**Agent Mentions**](/docs/agent-mentions) — `@`-mention files and agents into a turn instead of relying on ambient context
487
487
  - [**Drop-in Agent**](/docs/drop-in-agent) — mount the panel that reads and writes this state
488
488
  - [**Real-Time Collaboration**](/docs/real-time-collaboration) — keep app state in sync when the agent and users edit together
489
- - [**Client Methods**](/docs/client) — the full `application-state` and client helper reference
489
+ - [**Application State**](/docs/client-advanced#application-state) — the full `application-state` and client helper reference
490
490
  - [**Toolkit piece: Context & Knowledge**](/docs/toolkit-context-knowledge) — the Context X-Ray presentation built on this state
@@ -330,6 +330,204 @@ Add more `###` sections to get 3 or 4 columns (max 4). The red/green label accen
330
330
 
331
331
  ---
332
332
 
333
+ ## Image
334
+
335
+ <Image
336
+ src="/screenshots/dispatch.png"
337
+ alt="Dispatch app screenshot showing the run history sidebar"
338
+ align="left"
339
+ width={320}
340
+ caption="Dispatch's run history sidebar."
341
+ >
342
+
343
+ Aligning an image left or right turns it into a two-column row. The image sits on that side, and this markdown is the paired text on the other side. Leave `align` unset, or set it to `"full"`, for a normal full-width image with no paired text.
344
+
345
+ </Image>
346
+
347
+ ```mdx
348
+ <Image
349
+ src="/screenshots/dispatch.png"
350
+ alt="Dispatch app screenshot showing the run history sidebar"
351
+ align="left"
352
+ width={320}
353
+ caption="Dispatch's run history sidebar."
354
+ >
355
+
356
+ Aligning an image left or right turns it into a two-column row. The image sits on that side, and this markdown is the paired text on the other side. Leave `align` unset, or set it to `"full"`, for a normal full-width image with no paired text.
357
+
358
+ </Image>
359
+ ```
360
+
361
+ `alt` is required. `align` is `"full"` (the default), `"left"`, or `"right"`. `width` is an optional pixel hint for the image column when aligned, and has no effect on `"full"`. `caption` renders in small muted text under the image. Anything between the open and close tags is markdown, and becomes the paired text next to the image when aligned, or plain content below it when full width. Omit the children entirely for a self-closing `<Image ... />` with no paired text.
362
+
363
+ Hovering the image reveals a top-right expand button that opens it in a larger popup. If the image has paired text (or a caption), the popup stacks it below the image instead of beside it, since the two-column layout only makes sense at the inline aligned size.
364
+
365
+ For a plain full-width image with no paired text, omit `align` (or set it to `"full"`) and skip the children entirely:
366
+
367
+ <Image
368
+ src="/screenshots/mail.png"
369
+ alt="Mail app screenshot showing the inbox and reading pane"
370
+ caption="The default inbox view."
371
+ />
372
+
373
+ ```mdx
374
+ <Image
375
+ src="/screenshots/mail.png"
376
+ alt="Mail app screenshot showing the inbox and reading pane"
377
+ caption="The default inbox view."
378
+ />
379
+ ```
380
+
381
+ ---
382
+
383
+ ## Video
384
+
385
+ No sample video ships in this repo, so this section shows syntax only rather than a live-rendered example. Swap `src` for a real `.mp4`/`.webm` file under `public/` to see it rendered.
386
+
387
+ ```mdx
388
+ <Video
389
+ src="/videos/product-tour.mp4"
390
+ alt="A short screen recording of creating a new action from the CLI"
391
+ align="right"
392
+ width={320}
393
+ caption="Creating an action from the CLI."
394
+ >
395
+
396
+ Same shape as `Image`, aligned the other way this time. The video sits on the right, and this text sits on the left. `src` must be a direct video file, mp4 or webm. Third-party embed links like YouTube or Loom aren't supported, since that would need an `<iframe>`, which the docs system doesn't allow for security reasons.
397
+
398
+ </Video>
399
+ ```
400
+
401
+ Identical attributes to `Image` (`src`, `alt`, `align`, `width`, `caption`, and paired markdown children), except `src` must point to a direct video file rather than an embed link. `alt` becomes the video's `aria-label`, since `<video>` has no native `alt` attribute.
402
+
403
+ Pass `autoplay` to play the video automatically once it's visible. It always forces `muted` alongside it, since browsers block autoplay with sound regardless of the attribute. It also never autoplays for a viewer with `prefers-reduced-motion: reduce` set. That viewer instead gets a normal paused player, and pressing play themselves gives them full, unmuted playback rather than a silently-muted one.
404
+
405
+ Pass `loop` to restart the video from the beginning once it ends. It's independent of `autoplay`, so a looping video that isn't set to autoplay just loops once the viewer presses play themselves.
406
+
407
+ The same full-width form applies here too, omit `align` and the children for a plain full-width video:
408
+
409
+ ```mdx
410
+ <Video
411
+ src="/videos/product-tour.mp4"
412
+ alt="A full walkthrough recording of building an action end to end"
413
+ caption="Building an action end to end."
414
+ />
415
+ ```
416
+
417
+ ---
418
+
419
+ ## Signature
420
+
421
+ <Signature
422
+ id="docs-components-signature"
423
+ name="askUserQuestion"
424
+ params={[
425
+ {
426
+ name: "input",
427
+ type: "AskUserQuestionInput",
428
+ description: "The question, its options, and how it should behave.",
429
+ fields: [
430
+ {
431
+ name: "question",
432
+ type: "string",
433
+ description:
434
+ "The complete question. Clear, specific, ends with a question mark.",
435
+ },
436
+ {
437
+ name: "header",
438
+ type: "string",
439
+ optional: true,
440
+ description:
441
+ 'Very short chip/heading, about 12 characters, e.g. `"Date range"`.',
442
+ },
443
+ {
444
+ name: "options",
445
+ type: "AskUserQuestionOption[]",
446
+ description: "2-4 distinct options.",
447
+ },
448
+ {
449
+ name: "allowFreeText",
450
+ type: "boolean",
451
+ optional: true,
452
+ default: "true",
453
+ description: 'Adds a free-text "Other" option.',
454
+ },
455
+ {
456
+ name: "allowMultiple",
457
+ type: "boolean",
458
+ optional: true,
459
+ default: "false",
460
+ description: "Multi-select instead of single-select.",
461
+ },
462
+ ],
463
+ },
464
+ ]}
465
+ returns={{
466
+ type: "Promise<AskUserQuestionResult>",
467
+ description:
468
+ 'The picked value, `value[]` when `allowMultiple`, the typed "Other" text, or `null` if skipped.',
469
+ }}
470
+ />
471
+
472
+ ```mdx
473
+ <Signature
474
+ id="docs-components-signature"
475
+ name="askUserQuestion"
476
+ params={[
477
+ {
478
+ name: "input",
479
+ type: "AskUserQuestionInput",
480
+ description: "The question, its options, and how it should behave.",
481
+ fields: [
482
+ {
483
+ name: "question",
484
+ type: "string",
485
+ description:
486
+ "The complete question. Clear, specific, ends with a question mark.",
487
+ },
488
+ {
489
+ name: "header",
490
+ type: "string",
491
+ optional: true,
492
+ description:
493
+ 'Very short chip/heading, about 12 characters, e.g. `"Date range"`.',
494
+ },
495
+ {
496
+ name: "options",
497
+ type: "AskUserQuestionOption[]",
498
+ description: "2-4 distinct options.",
499
+ },
500
+ {
501
+ name: "allowFreeText",
502
+ type: "boolean",
503
+ optional: true,
504
+ default: "true",
505
+ description: 'Adds a free-text "Other" option.',
506
+ },
507
+ {
508
+ name: "allowMultiple",
509
+ type: "boolean",
510
+ optional: true,
511
+ default: "false",
512
+ description: "Multi-select instead of single-select.",
513
+ },
514
+ ],
515
+ },
516
+ ]}
517
+ returns={{
518
+ type: "Promise<AskUserQuestionResult>",
519
+ description:
520
+ 'The picked value, `value[]` when `allowMultiple`, the typed "Other" text, or `null` if skipped.',
521
+ }}
522
+ />
523
+ ```
524
+
525
+ `Signature` is self-closing. `name` plus `params` build the code-style call line shown at the top (an optional param renders as `name?: type`). Each param is `{ name, type, optional?, default?, description }`, matching a plain field. An object-shaped param (like `input` above) can add a nested `fields` array of the same shape to break down its properties, so one block replaces both a hand-written signature line and a separate options table. `returns` is optional and takes the same `{ type, description? }` shape. Descriptions render through the normal markdown pipeline, so backticks and bold work.
526
+
527
+ Use this over a hand-written `ts` fence plus a prose bullet list whenever a reference page documents a specific function, hook, or action's call shape, per the `writing-reference-docs` skill.
528
+
529
+ ---
530
+
333
531
  ## kbd — keyboard shortcut
334
532
 
335
533
  Press [[⌘K]] to open the command palette. Save with [[Ctrl+S]] before running the dev server. Navigate fields with [[Tab]] and [[Shift+Tab]].
@@ -606,5 +804,8 @@ Like `TabsBlock`, `Columns` is self-closing with a single JSON `columns` attribu
606
804
  | Same task in multiple tools or frameworks | `Tabs` |
607
805
  | Side-by-side code (labeled columns) | `Columns` |
608
806
  | Project directory structure | `FileTree` |
807
+ | A function/hook/action's call shape | `Signature` |
808
+ | An image, full width or with paired text | `Image` |
809
+ | A video, full width or with paired text | `Video` |
609
810
  | Inline keyboard shortcut | `[[Key]]` |
610
811
  | Architecture or flow diagram | Mermaid fence |
@@ -237,7 +237,7 @@ conversation itself belongs in the AgentSidebar composer.
237
237
 
238
238
  When the same route is embedded as an MCP App, submitted
239
239
  `sendToAgentChat()` calls are forwarded to the host chat where supported; see
240
- [Client](/docs/client#sendtoagentchat) for the MCP App bridge behavior.
240
+ [Agent Chat](/docs/client-agent-chat#sendtoagentchat) for the MCP App bridge behavior.
241
241
 
242
242
  If you want a loading state, use the `useSendToAgentChat()` hook — it returns both `send` and `isGenerating`:
243
243
 
@@ -148,6 +148,6 @@ names.
148
148
 
149
149
  ## What's next
150
150
 
151
- - [**Client**](/docs/client) — the `AppProviders` wrapper and other browser hooks i18n builds on
151
+ - [**Overview**](/docs/client-overview#app-shell) — the `AppProviders` wrapper and other browser hooks i18n builds on
152
152
  - [**Toolkit: Settings**](/docs/toolkit-settings) — put `<LanguagePicker>` on the standard settings page
153
153
  - [**Getting Started**](/docs/getting-started) — build your first app on a template that already ships localized catalogs
@@ -511,6 +511,10 @@ The vision and philosophy behind these rules.
511
511
 
512
512
  Navigation state, view-screen, and navigate commands in depth.
513
513
 
514
+ ### [Sync Internals](/docs/client-sync-internals)
515
+
516
+ The change-version mechanism behind live sync, for syncing a raw `useQuery`.
517
+
514
518
  ### [Skills Guide](/docs/skills-guide)
515
519
 
516
520
  Framework skills, domain skills, and creating custom skills.
@@ -366,7 +366,7 @@ Automations can chain off this — e.g. _"if a critical notification fires, also
366
366
  ## How it works {#internals}
367
367
 
368
368
  - **Owner scoping** — every row has an `owner` column; every query filters on it; every route uses the authenticated session's email. Users never see each other's notifications.
369
- - **Poll integration** — every mutation calls `recordChange()` so templates using [`useDbSync`](/docs/client) auto-invalidate without any extra wiring.
369
+ - **Poll integration** — every mutation calls `recordChange()` so templates using [`useDbSync`](/docs/client-data#usedbsync) auto-invalidate without any extra wiring.
370
370
  - **Best-effort fan-out** — channel errors are caught and logged; one failing channel does not block others or the inbox write.
371
371
  - **Fire-and-forget** — `notify()` returns after the inbox write completes; custom channels run in the background.
372
372
 
@@ -244,7 +244,7 @@ Notify me that run {{runId}} has failed.
244
244
  ## How it works {#internals}
245
245
 
246
246
  - **Owner scoping** — every row has an `owner` column; every query filters on it. Users see only their own runs.
247
- - **Poll integration** — every mutation calls `recordChange()` so templates using [`useDbSync`](/docs/client) auto-invalidate without any extra wiring.
247
+ - **Poll integration** — every mutation calls `recordChange()` so templates using [`useDbSync`](/docs/client-data#usedbsync) auto-invalidate without any extra wiring.
248
248
  - **Table name** — the framework also has an `agent_runs` table for internal agent-chat turn lifecycle tracking. The progress primitive uses `progress_runs` to keep the two concerns separate.
249
249
  - **Percent clamping** — values are clamped to `[0, 100]` and rounded to an integer on write.
250
250
 
@@ -252,4 +252,4 @@ Notify me that run {{runId}} has failed.
252
252
 
253
253
  - [**Notifications**](/docs/notifications) — pair with `manage-progress` (`action=complete`) to tell the user when work finishes
254
254
  - [**Automations**](/docs/automations) — watchdog slow runs via `run.progress.updated`
255
- - [**Client**](/docs/client) — `useDbSync` for real-time cache invalidation
255
+ - [**Data & Sync**](/docs/client-data) — `useDbSync` for real-time cache invalidation
@@ -39,7 +39,7 @@ deployment environments including serverless and edge).
39
39
 
40
40
  <Callout tone="info">
41
41
 
42
- **Just need the UI to refresh, not character-level co-editing?** Use [`useDbSync`](/docs/client#usedbsync) instead — it's for reacting to SQL writes from the agent or other users. This page covers real-time character-level co-editing of a single rich-text document (shared cursors, conflict-free merging). Both ride the same `/_agent-native/poll` channel.
42
+ **Just need the UI to refresh, not character-level co-editing?** Use [`useDbSync`](/docs/client-data#usedbsync) instead — it's for reacting to SQL writes from the agent or other users. This page covers real-time character-level co-editing of a single rich-text document (shared cursors, conflict-free merging). Both ride the same `/_agent-native/poll` channel.
43
43
 
44
44
  </Callout>
45
45
 
@@ -780,7 +780,7 @@ Key properties:
780
780
 
781
781
  ## What's next {#whats-next}
782
782
 
783
- - [Real-Time Sync](/docs/client#usedbsync) — the `useDbSync` + `useChangeVersion`
783
+ - [Sync Internals](/docs/client-sync-internals) — the `useDbSync` + `useChangeVersion`
784
784
  system that delivers the `updatedAt` bump driving editor reconciliation.
785
785
  - [Security](/docs/security) — `registerShareableResource`, `resolveAccess`,
786
786
  and `assertAccess` for resource-scoped collaboration.
@@ -11,7 +11,7 @@ This page is for developers who need to know what runs under the hood in [Chat](
11
11
 
12
12
  Chat adds no domain tables of its own (see [What's not in it](/docs/template-chat#not-in-it)). It runs entirely on the framework's core tables: chat threads and messages, `application_state`, `settings`, sessions, resources, and run history.
13
13
 
14
- `useDbSync()` is already wired into the app shell: when the agent (or anyone else) writes to SQL, the client receives the change over SSE, or the 2-second polling fallback, and invalidates the matching React Query caches — no manual refresh, no websocket you have to manage yourself. See [`useDbSync`](/docs/client#usedbsync) for the full hook API.
14
+ `useDbSync()` is already wired into the app shell: when the agent (or anyone else) writes to SQL, the client receives the change over SSE, or the 2-second polling fallback, and invalidates the matching React Query caches — no manual refresh, no websocket you have to manage yourself. See [`useDbSync`](/docs/client-data#usedbsync) for the full hook API.
15
15
 
16
16
  `server/plugins/agent-chat.ts` is where the chat runtime itself is configured: it registers every action in `actions/` as a callable tool (`loadActionsFromStaticRegistry`), resolves the current org for scoping (`resolveOrgId`), sets the system prompt, and declares which tools the model sees on the very first turn (`initialToolNames`) — see [Your first feature in Chat](/docs/template-chat-first-edits#first-edits) for what that last part means when you add a new action.
17
17
 
@@ -104,7 +104,7 @@ Use a small predictable route set:
104
104
 
105
105
  ## What's next
106
106
 
107
- - [**Routing**](/docs/routing) — the file-route conventions the route standard
107
+ - [**Routing**](/docs/client-routing) — the file-route conventions the route standard
108
108
  builds on.
109
109
  - [**Context Awareness**](/docs/context-awareness) — how `view-screen` and
110
110
  navigation state stay in sync.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.153.8",
3
+ "version": "0.153.10",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -421,8 +421,8 @@
421
421
  "y-protocols": "^1.0.7",
422
422
  "yjs": "^13.6.31",
423
423
  "zod": "^4.3.6",
424
- "@agent-native/recap-cli": "0.5.4",
425
- "@agent-native/toolkit": "^0.14.1"
424
+ "@agent-native/toolkit": "^0.14.1",
425
+ "@agent-native/recap-cli": "0.5.4"
426
426
  },
427
427
  "devDependencies": {
428
428
  "@ai-sdk/anthropic": "^3.0.71",
@@ -1,5 +1,6 @@
1
1
  import { useActionQuery } from "@agent-native/core/client/hooks";
2
2
  import { useT } from "@agent-native/core/client/i18n";
3
+ import { docsUrl } from "@agent-native/core/shared";
3
4
  import { useTheme } from "next-themes";
4
5
  import { Link } from "react-router";
5
6
 
@@ -41,7 +42,7 @@ export default function IndexPage() {
41
42
 
42
43
  <div className="grid grid-cols-2 gap-3 text-left">
43
44
  <a
44
- href="https://agent-native.com/docs"
45
+ href={docsUrl("getting-started")}
45
46
  target="_blank"
46
47
  rel="noopener noreferrer"
47
48
  className="group rounded-lg border border-border/50 px-4 py-3 hover:bg-accent/50 transition-colors"