@agent-native/core 0.135.0 → 0.135.2
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.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +12 -0
- package/corpus/core/docs/content/getting-started-actions.mdx +235 -0
- package/corpus/core/docs/content/getting-started-database.mdx +253 -0
- package/corpus/core/docs/content/getting-started-pages.mdx +190 -0
- package/corpus/core/docs/content/getting-started.mdx +57 -613
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/sharing/access.ts +44 -2
- package/corpus/templates/clips/actions/add-comment.ts +6 -2
- package/corpus/templates/clips/app/components/player/comments-panel.tsx +9 -2
- package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +44 -27
- package/corpus/templates/clips/app/components/player/scrubber.tsx +10 -2
- package/corpus/templates/clips/app/components/player/video-player.tsx +4 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +22 -15
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +1 -0
- package/corpus/templates/content/actions/_database-utils.ts +113 -4
- package/corpus/templates/content/actions/get-document.ts +84 -3
- package/corpus/templates/content/app/components/editor/BuilderBodySyncingNotice.tsx +9 -2
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +29 -13
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +5 -12
- package/corpus/templates/content/app/components/editor/body-hydration.ts +12 -6
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +2 -3
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -12
- package/corpus/templates/content/app/hooks/use-content-database.ts +16 -27
- package/corpus/templates/content/app/hooks/use-create-page.ts +3 -6
- package/corpus/templates/content/app/hooks/use-document-properties.ts +9 -16
- package/corpus/templates/content/app/hooks/use-document-versions.ts +3 -3
- package/corpus/templates/content/app/hooks/use-documents.ts +85 -29
- package/corpus/templates/content/app/hooks/use-notion.ts +15 -13
- package/corpus/templates/content/app/i18n-data.ts +32 -1
- package/corpus/templates/content/app/lib/document-query.ts +36 -0
- package/corpus/templates/content/changelog/2026-08-02-pages-opened-from-a-database-now-keep-that-database-s-fields.md +6 -0
- package/corpus/templates/content/server/lib/document-context.ts +11 -6
- package/corpus/templates/content/shared/api.ts +8 -0
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +6 -6
- package/dist/provider-api/actions/provider-api.d.ts +4 -4
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +32 -2
- package/dist/sharing/access.js.map +1 -1
- package/docs/content/getting-started-actions.mdx +235 -0
- package/docs/content/getting-started-database.mdx +253 -0
- package/docs/content/getting-started-pages.mdx +190 -0
- package/docs/content/getting-started.mdx +57 -613
- package/package.json +1 -1
- package/src/sharing/access.ts +44 -2
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Add a Page"
|
|
3
|
+
description: "Build a React route that displays your saved data and wire it into the sidebar so the agent can navigate to it."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Add a Page
|
|
7
|
+
|
|
8
|
+
This is part four of the Getting Started series. In [Persist Data in SQL](/docs/getting-started-database) you saved action results to a database. Here you'll build a page that displays that data and connect it to the sidebar.
|
|
9
|
+
|
|
10
|
+
## Add a page the agent can open {#add-a-page}
|
|
11
|
+
|
|
12
|
+
Chat is great for conversational interaction, but some data is better inspected
|
|
13
|
+
in a dedicated UI: a table you can scan, sort, or delete rows from. This step
|
|
14
|
+
adds a React route that displays everything saved in `text_analyses`, using the
|
|
15
|
+
same `list-text-analyses` and `delete-text-analysis` actions you already wrote.
|
|
16
|
+
There's no second data layer. The page is just a view over the same SQL state
|
|
17
|
+
the agent reads and writes.
|
|
18
|
+
|
|
19
|
+
Create the route file at `app/routes/text-analyses.tsx`. Route files in
|
|
20
|
+
`app/routes/` are automatically picked up by the framework. The filename
|
|
21
|
+
becomes the URL path, so this page will be available at
|
|
22
|
+
`http://localhost:8080/text-analyses`.
|
|
23
|
+
|
|
24
|
+
```tsx filename="app/routes/text-analyses.tsx"
|
|
25
|
+
import {
|
|
26
|
+
useActionMutation,
|
|
27
|
+
useActionQuery,
|
|
28
|
+
} from "@agent-native/core/client/hooks";
|
|
29
|
+
|
|
30
|
+
export default function TextAnalysesRoute() {
|
|
31
|
+
const analyses = useActionQuery("list-text-analyses", {});
|
|
32
|
+
const deleteAnalysis = useActionMutation("delete-text-analysis");
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<main className="mx-auto flex max-w-3xl flex-col gap-6 p-6">
|
|
36
|
+
<header>
|
|
37
|
+
<h1 className="text-2xl font-semibold">Text analyses</h1>
|
|
38
|
+
<p className="text-muted-foreground">
|
|
39
|
+
Results saved by the agent or triggered manually.
|
|
40
|
+
</p>
|
|
41
|
+
</header>
|
|
42
|
+
<section className="flex flex-col gap-3">
|
|
43
|
+
{analyses.data?.length === 0 && (
|
|
44
|
+
<p className="text-muted-foreground">No analyses saved yet.</p>
|
|
45
|
+
)}
|
|
46
|
+
{analyses.data?.map((row: any) => (
|
|
47
|
+
<article
|
|
48
|
+
key={row.id}
|
|
49
|
+
className="flex items-start justify-between rounded-lg border p-4"
|
|
50
|
+
>
|
|
51
|
+
<div className="flex flex-col gap-1">
|
|
52
|
+
<p className="text-sm font-medium">{row.input}</p>
|
|
53
|
+
<p className="text-xs text-muted-foreground">
|
|
54
|
+
{row.word_count} words · {row.char_count} characters ·{" "}
|
|
55
|
+
{row.sentence_count} sentences
|
|
56
|
+
</p>
|
|
57
|
+
</div>
|
|
58
|
+
<button
|
|
59
|
+
className="text-xs text-destructive hover:underline"
|
|
60
|
+
onClick={() => deleteAnalysis.mutate({ id: row.id })}
|
|
61
|
+
>
|
|
62
|
+
Delete
|
|
63
|
+
</button>
|
|
64
|
+
</article>
|
|
65
|
+
))}
|
|
66
|
+
</section>
|
|
67
|
+
</main>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`useActionQuery` calls `list-text-analyses` and keeps the result live. If the
|
|
73
|
+
agent saves a new row while the page is open, it appears automatically.
|
|
74
|
+
`useActionMutation` calls `delete-text-analysis` when the user clicks Delete,
|
|
75
|
+
then invalidates the query so the list refreshes.
|
|
76
|
+
|
|
77
|
+
Open `http://localhost:8080/text-analyses` in your browser. If you saved an
|
|
78
|
+
analysis in the previous step you'll see it listed. Then ask the agent in chat:
|
|
79
|
+
|
|
80
|
+
> Open the text analyses page.
|
|
81
|
+
|
|
82
|
+
If you get a 404, try restarting your dev server.
|
|
83
|
+
|
|
84
|
+
The agent calls the `navigate` action (already included in the Chat
|
|
85
|
+
template) to send the browser to `/text-analyses`. This is what it looks like
|
|
86
|
+
with a few saved rows:
|
|
87
|
+
|
|
88
|
+
<WireframeBlock id="doc-block-response-insights-page-wireframe">
|
|
89
|
+
<Screen
|
|
90
|
+
surface="desktop"
|
|
91
|
+
html={
|
|
92
|
+
"<main style='min-height:400px;box-sizing:border-box;padding:28px;background:var(--wf-bg)'><div style='max-width:720px;margin:0 auto;display:flex;flex-direction:column;gap:20px'><header><h2 style='margin:0 0 4px;font-size:24px;font-weight:600'>Text analyses</h2><p class='wf-muted' style='margin:0;font-size:14px'>Results saved by the agent or triggered manually.</p></header><section style='display:flex;flex-direction:column;gap:10px'><article class='wf-card' data-rough style='display:flex;align-items:center;justify-content:space-between;padding:14px 16px'><div><p style='margin:0 0 4px;font-size:14px;font-weight:500'>Hello world</p><p class='wf-muted' style='margin:0;font-size:12px'>2 words · 11 characters · 1 sentence</p></div><span class='wf-muted' style='font-size:12px'>Delete</span></article><article class='wf-card' data-rough style='display:flex;align-items:center;justify-content:space-between;padding:14px 16px'><div><p style='margin:0 0 4px;font-size:14px;font-weight:500'>The quick brown fox jumps over the lazy dog.</p><p class='wf-muted' style='margin:0;font-size:12px'>9 words · 44 characters · 1 sentence</p></div><span class='wf-muted' style='font-size:12px'>Delete</span></article><article class='wf-card' data-rough style='display:flex;align-items:center;justify-content:space-between;padding:14px 16px'><div><p style='margin:0 0 4px;font-size:14px;font-weight:500'>Pack my box with five dozen liquor jugs.</p><p class='wf-muted' style='margin:0;font-size:12px'>8 words · 40 characters · 1 sentence</p></div><span class='wf-muted' style='font-size:12px'>Delete</span></article></section></div></main>"
|
|
93
|
+
}
|
|
94
|
+
/>
|
|
95
|
+
</WireframeBlock>
|
|
96
|
+
|
|
97
|
+
## Extend the navigation {#extend-navigation}
|
|
98
|
+
|
|
99
|
+
The sidebar's links are a plain array in `app/components/layout/Sidebar.tsx`,
|
|
100
|
+
not a separate config file. Open it and add an entry for the Text analyses
|
|
101
|
+
page next to the existing Chat entry:
|
|
102
|
+
|
|
103
|
+
```tsx filename="app/components/layout/Sidebar.tsx"
|
|
104
|
+
import { IconList, IconMessageCircle } from "@tabler/icons-react";
|
|
105
|
+
|
|
106
|
+
const navItems = [
|
|
107
|
+
{
|
|
108
|
+
icon: IconMessageCircle,
|
|
109
|
+
labelKey: "navigation.chat",
|
|
110
|
+
href: "/",
|
|
111
|
+
view: "chat",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
icon: IconList,
|
|
115
|
+
labelKey: "navigation.textAnalyses",
|
|
116
|
+
href: "/text-analyses",
|
|
117
|
+
view: "text-analyses",
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`icon` takes an imported Tabler icon component, not a string name. `labelKey`
|
|
123
|
+
looks up a string in the i18n catalog (`app/i18n/en-US.ts` and the other
|
|
124
|
+
locale files); an unregistered key still renders — it falls back to a
|
|
125
|
+
humanized version of the key (`navigation.textAnalyses` becomes "Text
|
|
126
|
+
analyses") — but add it to the catalogs if you want the label translated. See
|
|
127
|
+
[Internationalization](/docs/internationalization).
|
|
128
|
+
|
|
129
|
+
Save the file. The dev server picks up the change automatically and the sidebar
|
|
130
|
+
updates without a restart.
|
|
131
|
+
|
|
132
|
+
### Agent navigation
|
|
133
|
+
|
|
134
|
+
The sidebar link lets users navigate manually. The agent can also open pages on
|
|
135
|
+
its own using two built-in actions that ship with the Chat template:
|
|
136
|
+
|
|
137
|
+
- **`view-screen`** reads the current route and returns a compact summary of
|
|
138
|
+
what the user is looking at.
|
|
139
|
+
- **`navigate`** writes a same-origin path to the browser's history.
|
|
140
|
+
|
|
141
|
+
As you add more pages, keep `navigate` updated so the agent knows what
|
|
142
|
+
destinations exist. Document available paths in `AGENTS.md` so the model can
|
|
143
|
+
reason about them.
|
|
144
|
+
|
|
145
|
+
When the app has both a full-page chat route and an app page, use the shared chat
|
|
146
|
+
handoff helpers described in [Agent Surfaces](/docs/agent-surfaces#rich-chat):
|
|
147
|
+
`AgentChatSurface`, `AgentSidebar`, `useAgentChatHomeHandoff`,
|
|
148
|
+
`useAgentChatHomeHandoffLinks`, and `chatViewTransition`. That lets the full
|
|
149
|
+
chat slide into the side panel as the page opens, keeping the same thread while
|
|
150
|
+
the user inspects durable data.
|
|
151
|
+
|
|
152
|
+
## Project structure {#project-structure}
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
my-app/
|
|
156
|
+
actions/ # Agent-callable and UI-callable operations
|
|
157
|
+
app/ # React routes, pages, and chat surfaces
|
|
158
|
+
server/ # Nitro server and SQL schema
|
|
159
|
+
AGENTS.md # Always-on instructions for the app agent
|
|
160
|
+
.agents/ # Skills the agent loads when relevant
|
|
161
|
+
data/app.db # Local SQLite state when DATABASE_URL is unset
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## What's next {#next}
|
|
165
|
+
|
|
166
|
+
You've built a complete agentic app: a working chat interface, an action, inline
|
|
167
|
+
rendering, a database, and a page the agent can navigate to. From here:
|
|
168
|
+
|
|
169
|
+
<Cards>
|
|
170
|
+
|
|
171
|
+
### [Key Concepts](/docs/key-concepts)
|
|
172
|
+
|
|
173
|
+
The architecture underneath this tutorial: SQL, actions, live sync, and context
|
|
174
|
+
awareness.
|
|
175
|
+
|
|
176
|
+
### [Agent Surfaces](/docs/agent-surfaces)
|
|
177
|
+
|
|
178
|
+
Chat, inline UI, app pages, embedded sidecars, automation, and external agents —
|
|
179
|
+
all the ways your app can surface the agent.
|
|
180
|
+
|
|
181
|
+
### [Context Awareness](/docs/context-awareness)
|
|
182
|
+
|
|
183
|
+
`view-screen`, `navigate`, route state, and selected objects — how the agent
|
|
184
|
+
knows what the user is looking at.
|
|
185
|
+
|
|
186
|
+
### [Deployment](/docs/deployment)
|
|
187
|
+
|
|
188
|
+
Put your app on your own domain.
|
|
189
|
+
|
|
190
|
+
</Cards>
|