@agent-native/core 0.49.11 → 0.49.13

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 (77) hide show
  1. package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
  2. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  3. package/dist/cli/pr-visual-recap-workflow.js +1 -1
  4. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  5. package/dist/cli/recap.d.ts +37 -0
  6. package/dist/cli/recap.d.ts.map +1 -1
  7. package/dist/cli/recap.js +240 -0
  8. package/dist/cli/recap.js.map +1 -1
  9. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  10. package/dist/client/MultiTabAssistantChat.js +5 -10
  11. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  12. package/dist/client/blocks/library/question-form.js +1 -1
  13. package/dist/client/blocks/library/question-form.js.map +1 -1
  14. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  15. package/dist/client/extensions/EmbeddedExtension.js +4 -0
  16. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  17. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  18. package/dist/client/extensions/ExtensionViewer.js +12 -4
  19. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  20. package/dist/client/extensions/ExtensionsListPage.d.ts.map +1 -1
  21. package/dist/client/extensions/ExtensionsListPage.js +14 -9
  22. package/dist/client/extensions/ExtensionsListPage.js.map +1 -1
  23. package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
  24. package/dist/client/extensions/ExtensionsSidebarSection.js +6 -4
  25. package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
  26. package/dist/client/extensions/iframe-bridge.d.ts +8 -0
  27. package/dist/client/extensions/iframe-bridge.d.ts.map +1 -1
  28. package/dist/client/extensions/iframe-bridge.js +54 -0
  29. package/dist/client/extensions/iframe-bridge.js.map +1 -1
  30. package/dist/client/progress/RunsTray.d.ts.map +1 -1
  31. package/dist/client/progress/RunsTray.js +12 -3
  32. package/dist/client/progress/RunsTray.js.map +1 -1
  33. package/dist/client/resources/ResourceEditor.d.ts +1 -3
  34. package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
  35. package/dist/client/resources/ResourceEditor.js +8 -23
  36. package/dist/client/resources/ResourceEditor.js.map +1 -1
  37. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  38. package/dist/client/resources/ResourcesPanel.js +4 -9
  39. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  40. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  41. package/dist/client/settings/VoiceTranscriptionSection.js +1 -1
  42. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  43. package/dist/client/sharing/ShareButton.d.ts +5 -1
  44. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  45. package/dist/client/sharing/ShareButton.js +15 -7
  46. package/dist/client/sharing/ShareButton.js.map +1 -1
  47. package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
  48. package/dist/client/sharing/ShareDialog.js +6 -2
  49. package/dist/client/sharing/ShareDialog.js.map +1 -1
  50. package/dist/extensions/actions.d.ts.map +1 -1
  51. package/dist/extensions/actions.js +70 -2
  52. package/dist/extensions/actions.js.map +1 -1
  53. package/dist/extensions/html-shell.d.ts +12 -0
  54. package/dist/extensions/html-shell.d.ts.map +1 -1
  55. package/dist/extensions/html-shell.js.map +1 -1
  56. package/dist/extensions/local.d.ts +35 -0
  57. package/dist/extensions/local.d.ts.map +1 -0
  58. package/dist/extensions/local.js +334 -0
  59. package/dist/extensions/local.js.map +1 -0
  60. package/dist/extensions/routes.d.ts.map +1 -1
  61. package/dist/extensions/routes.js +92 -12
  62. package/dist/extensions/routes.js.map +1 -1
  63. package/dist/extensions/slots/store.d.ts.map +1 -1
  64. package/dist/extensions/slots/store.js +72 -4
  65. package/dist/extensions/slots/store.js.map +1 -1
  66. package/dist/local-artifacts/index.d.ts +4 -0
  67. package/dist/local-artifacts/index.d.ts.map +1 -1
  68. package/dist/local-artifacts/index.js +60 -35
  69. package/dist/local-artifacts/index.js.map +1 -1
  70. package/dist/vite/client.d.ts +11 -1
  71. package/dist/vite/client.d.ts.map +1 -1
  72. package/dist/vite/client.js +26 -1
  73. package/dist/vite/client.js.map +1 -1
  74. package/docs/content/extensions.md +65 -0
  75. package/docs/content/local-file-mode.md +378 -0
  76. package/docs/content/template-content.md +53 -4
  77. package/package.json +1 -1
@@ -0,0 +1,378 @@
1
+ ---
2
+ title: "Local File Mode"
3
+ description: "Run agent-native apps with local Markdown, MDX, and other repo files as the source of truth instead of SQL-backed records."
4
+ ---
5
+
6
+ # Local File Mode
7
+
8
+ Local File Mode lets an agent-native app attach its normal UI and action surface
9
+ directly to files in a repo or workspace. The app still feels like the hosted
10
+ product, but its list views, editor, and agent tools read and write local files
11
+ instead of SQL-backed app records.
12
+
13
+ The first implementation is in the Content template: the left sidebar is
14
+ populated from local `.md` and `.mdx` files, selecting a page opens the standard
15
+ Content editor, and saving writes back to the selected file. The same files can
16
+ also be edited by Codex, Claude Code, the Agent-Native sidebar agent, or a normal
17
+ editor.
18
+
19
+ Use Local File Mode when you want a repo-first workflow:
20
+
21
+ - a docs repo with `docs/*.mdx`
22
+ - a blog with `blog/*.mdx`
23
+ - resources such as positioning, messaging, or team notes in `resources/*.md`
24
+ - a personal Obsidian-style knowledge base with a richer MDX editor
25
+ - app artifacts that should be easy for coding agents to inspect and patch
26
+
27
+ Use database mode when you want the hosted collaborative app experience:
28
+ multi-user sharing, SQL-backed permissions, comments, version history, and
29
+ production hosting without local filesystem access.
30
+
31
+ ## The Mental Model
32
+
33
+ There are two source-of-truth modes:
34
+
35
+ | Mode | Source of truth | Best for |
36
+ | --------------- | ------------------------------------------ | ------------------------------------------------------------------------ |
37
+ | Database mode | SQL rows through Drizzle | Hosted apps, collaboration, sharing, comments, version history |
38
+ | Local File Mode | Repo files declared by `agent-native.json` | Local/dev workflows, Git review, coding-agent edits, file-native content |
39
+
40
+ The UI and agent actions should stay the same shape in both modes. A Content
41
+ editor still edits documents; the difference is whether those documents resolve
42
+ to SQL rows or local files.
43
+
44
+ ## Example Repo
45
+
46
+ A Content workspace can be as small as this:
47
+
48
+ ```txt
49
+ my-content-repo/
50
+ agent-native.json
51
+ docs/
52
+ getting-started.mdx
53
+ guides/
54
+ custom-components.mdx
55
+ blog/
56
+ launch-post.mdx
57
+ resources/
58
+ messaging/
59
+ positioning.md
60
+ components/
61
+ FrameworkTabs.tsx
62
+ Callout.tsx
63
+ extensions/
64
+ doc-status/
65
+ extension.json
66
+ index.html
67
+ ```
68
+
69
+ In Local File Mode, the Content sidebar shows the `docs/`, `blog/`, and
70
+ `resources/` trees as pages. Selecting `docs/getting-started.mdx` opens that
71
+ file in the standard Content editor; editing in the UI writes back to
72
+ `docs/getting-started.mdx`.
73
+
74
+ `components/` is not a content root. It is a preview component library that MDX
75
+ files can import or reference. The editor can render simple local MDX components
76
+ without requiring you to clone or fork the entire Content app.
77
+
78
+ `extensions/` is also not a content root. It is a local extension library:
79
+ small sandboxed widgets that can render in app slots while their source stays in
80
+ the repo.
81
+
82
+ ## Configuration
83
+
84
+ Add `agent-native.json` to the repo or workspace root:
85
+
86
+ ```json
87
+ {
88
+ "version": 1,
89
+ "apps": {
90
+ "content": {
91
+ "mode": "local-files",
92
+ "roots": [
93
+ {
94
+ "name": "Docs",
95
+ "path": "docs",
96
+ "kind": "docs",
97
+ "extensions": [".md", ".mdx"]
98
+ },
99
+ {
100
+ "name": "Blog",
101
+ "path": "blog",
102
+ "kind": "blog",
103
+ "extensions": [".md", ".mdx"]
104
+ },
105
+ {
106
+ "name": "Resources",
107
+ "path": "resources",
108
+ "kind": "resources",
109
+ "extensions": [".md", ".mdx"]
110
+ }
111
+ ],
112
+ "components": "components",
113
+ "extensions": "extensions",
114
+ "hide": ["**/_*.md", "**/_*.mdx"]
115
+ }
116
+ }
117
+ }
118
+ ```
119
+
120
+ You can also enable local files with `AGENT_NATIVE_MODE=local-files` or
121
+ `AGENT_NATIVE_DATA_MODE=local-files`; the manifest is preferred because it
122
+ documents the folder contract in the repo itself.
123
+
124
+ ## Content File Format
125
+
126
+ Content reads Markdown and MDX. Frontmatter holds page metadata, and the body is
127
+ the editable document:
128
+
129
+ ```mdx
130
+ ---
131
+ title: "Getting Started"
132
+ icon: "sparkles"
133
+ isFavorite: true
134
+ updatedAt: "2026-06-12T20:00:00.000Z"
135
+ ---
136
+
137
+ # Getting Started
138
+
139
+ Use <FrameworkTabs value="react" /> to show framework-specific code.
140
+ ```
141
+
142
+ The title comes from `title` frontmatter when present, otherwise from the
143
+ filename. The editor preserves MDX source that it cannot visually edit yet, so
144
+ coding agents and normal text editors remain safe escape hatches.
145
+
146
+ ## Custom MDX Components
147
+
148
+ Content can preview local components from the configured `components` folder.
149
+ This is meant for docs-style MDX components such as tabs, callouts, package
150
+ install snippets, or framework-specific code blocks.
151
+
152
+ For example, add an interactive component next to your content:
153
+
154
+ ```tsx
155
+ // components/ImpactCounter.tsx
156
+ import { useState } from "react";
157
+
158
+ export function ImpactCounter({
159
+ label = "points",
160
+ accent = "blue",
161
+ featured = false,
162
+ }: {
163
+ label?: string;
164
+ accent?: "blue" | "green" | "purple";
165
+ featured?: boolean;
166
+ }) {
167
+ const [count, setCount] = useState(3);
168
+ const accentClass =
169
+ accent === "green"
170
+ ? "border-green-300 bg-green-50"
171
+ : accent === "purple"
172
+ ? "border-purple-300 bg-purple-50"
173
+ : "border-blue-300 bg-blue-50";
174
+
175
+ return (
176
+ <div className={`rounded-md border p-4 ${accentClass}`}>
177
+ <div className="text-sm text-muted-foreground">Launch impact</div>
178
+ <div className="mt-1 text-3xl font-semibold">
179
+ {count} {label}
180
+ </div>
181
+ {featured ? <div className="mt-1 text-sm">Featured metric</div> : null}
182
+ <button
183
+ type="button"
184
+ className="mt-3 rounded border px-3 py-1 text-sm"
185
+ onClick={() => setCount((value) => value + 1)}
186
+ >
187
+ Add point
188
+ </button>
189
+ </div>
190
+ );
191
+ }
192
+
193
+ export const ImpactCounterInputs = {
194
+ label: {
195
+ type: "string",
196
+ label: "Metric label",
197
+ default: "points",
198
+ },
199
+ accent: {
200
+ type: "select",
201
+ label: "Accent",
202
+ options: ["blue", "green", "purple"],
203
+ default: "blue",
204
+ },
205
+ featured: {
206
+ type: "boolean",
207
+ label: "Featured",
208
+ default: false,
209
+ },
210
+ };
211
+ ```
212
+
213
+ Then use it from any local MDX file:
214
+
215
+ ```mdx
216
+ ---
217
+ title: "Launch Notes"
218
+ ---
219
+
220
+ # Launch Notes
221
+
222
+ <ImpactCounter label="wins" />
223
+ ```
224
+
225
+ The Content dev server discovers PascalCase named exports and PascalCase default
226
+ exports from `.tsx`, `.jsx`, `.ts`, and `.js` files under `components/`. Those
227
+ components render inside the editor and appear in the slash menu under
228
+ **Local components**. Slash insertion creates a minimal tag such as
229
+ `<ImpactCounter />`; add props in the MDX source when needed.
230
+
231
+ If a component exports input metadata, selecting the component in the editor
232
+ shows an edit button in the component's top-right corner. Supported input types
233
+ are `string`, `textarea`, `number`, `boolean`, and `select`. The form writes
234
+ changes back to the MDX tag, so local files remain the source of truth. The
235
+ metadata can be exported as `ComponentNameInputs`, `ComponentNameConfig.inputs`,
236
+ `Component.inputs`, or `agentNative.inputs`.
237
+
238
+ Simple component tags with literal props can preview inline:
239
+
240
+ ```mdx
241
+ <FrameworkTabs value="react" />
242
+
243
+ <Callout type="warning">This setting affects production deploys.</Callout>
244
+ ```
245
+
246
+ Complex JSX expressions are preserved in source. If the editor cannot safely
247
+ preview a component prop yet, it shows a warning placeholder rather than
248
+ silently dropping data.
249
+
250
+ ## Sharing Local Files
251
+
252
+ Local files are not shared directly because other users cannot read a path on
253
+ your machine. The Content toolbar's Share button creates or refreshes a
254
+ database-backed copy of the selected file, navigates to that copy, and opens the
255
+ normal share popover. The original local file remains under Local files; the
256
+ database copy appears under Shared copies in Local File Mode and uses the
257
+ standard document sharing model.
258
+
259
+ ## Local Extensions
260
+
261
+ Local File Mode can also load repo-backed extensions from the configured
262
+ `extensions` folder. Each extension is one directory with an `extension.json`
263
+ manifest and an HTML entry file:
264
+
265
+ ```txt
266
+ extensions/
267
+ doc-status/
268
+ extension.json
269
+ index.html
270
+ ```
271
+
272
+ ```json
273
+ {
274
+ "id": "doc-status",
275
+ "name": "Doc Status",
276
+ "description": "Shows metadata for the selected Content file.",
277
+ "entry": "index.html",
278
+ "slots": ["content.sidebar.bottom"],
279
+ "permissions": {
280
+ "appActions": ["list-documents"],
281
+ "extensionData": true
282
+ }
283
+ }
284
+ ```
285
+
286
+ `index.html` is the same Alpine/Tailwind extension body format used by normal
287
+ database-backed extensions. When the Content app sees a local extension that
288
+ declares `content.sidebar.bottom`, it renders that extension at the bottom of
289
+ the Content sidebar. The host passes `window.slotContext` with the selected
290
+ document id, title, source metadata, and whether Content is in Local File Mode.
291
+
292
+ Local extensions are previewed by the app but edited as files. The Extensions
293
+ list shows them with a Local File badge, and the full-page viewer points back to
294
+ the entry file. SQL-backed extension actions such as update, delete, share, and
295
+ history do not apply; use your editor, Codex, Claude Code, or Git history for
296
+ source changes.
297
+
298
+ For v1, local extensions are intentionally conservative:
299
+
300
+ - they can use `extensionData` for their own small runtime state
301
+ - they can call only the `appAction`s listed in `extension.json`
302
+ - raw SQL helpers and external `extensionFetch` are disabled
303
+ - slot targets are declared in `extension.json`, not installed through SQL
304
+
305
+ This gives local workspaces an Obsidian-like plugin surface without letting an
306
+ arbitrary repo file inherit every capability of a database-backed extension.
307
+
308
+ ## How Apps Use It
309
+
310
+ Local File Mode is implemented through the framework's local artifact helpers.
311
+ An app declares roots for the artifact types it owns, then reads and writes
312
+ through the same action surface its UI and agent already use.
313
+
314
+ For Content, that means:
315
+
316
+ - `list-documents` lists configured `.md` and `.mdx` files.
317
+ - `get-document` reads a selected local file.
318
+ - `update-document` writes the selected local file.
319
+ - `create-document` creates a new local `.mdx` file in the selected folder.
320
+ - `delete-document` deletes the local file.
321
+ - search runs across the configured local files.
322
+
323
+ Moving, renaming, and reordering local-file pages from the Content UI is not
324
+ supported yet. Do those operations in the workspace or with a coding agent; the
325
+ Content sidebar will reflect the resulting file tree.
326
+
327
+ This keeps the agent contract simple: the agent can keep using Content actions,
328
+ and those actions decide whether the target is SQL-backed or file-backed.
329
+
330
+ Other apps can adopt the same pattern over time. A Slides app can map
331
+ `slides/*.mdx` to decks, a Plans app can map `plans/*` to plan documents, and a
332
+ Dashboards app can map `dashboards/*.mdx` to dashboards. Those app-specific
333
+ folders are conventions layered on top of the same local artifact contract.
334
+
335
+ ## Local Files vs. Export/Import
336
+
337
+ Content has two different file workflows:
338
+
339
+ | Workflow | What happens |
340
+ | ---------------------------- | -------------------------------------------------------------------------------------------------------------------- |
341
+ | `/local-files` export/import | Database mode remains the source of truth. Files are an explicit sync surface you export, edit, preview, and import. |
342
+ | Local File Mode | Files are the source of truth. The Content sidebar and editor operate directly on local files. |
343
+
344
+ Use export/import when you want occasional file review around a hosted workspace.
345
+ Use Local File Mode when the repo itself is the workspace.
346
+
347
+ ## History And Collaboration
348
+
349
+ Local File Mode leans on file-native history:
350
+
351
+ - commit important changes to Git
352
+ - use pull requests for review
353
+ - let coding agents edit the same files directly
354
+ - use normal file diffs to understand changes
355
+
356
+ Database mode remains the better fit for hosted collaboration features such as
357
+ sharing, comments, SQL-backed version history, and live multi-user editing.
358
+
359
+ Provider sync can be layered on top of either mode. For example, a docs repo can
360
+ add actions that pull content from a CMS into local MDX files or push selected
361
+ local files back to that CMS.
362
+
363
+ ## Production Safety
364
+
365
+ Local File Mode gives app actions direct write access to configured workspace
366
+ files. That is appropriate for local development and trusted single-tenant file
367
+ bridges, but it is not the default production security model.
368
+
369
+ When `NODE_ENV=production`, the framework refuses `local-files` mode unless you
370
+ set:
371
+
372
+ ```bash
373
+ AGENT_NATIVE_ALLOW_LOCAL_FILES_IN_PRODUCTION=true
374
+ ```
375
+
376
+ Only set that for a trusted single-tenant deployment where everyone who can use
377
+ the app is allowed to read and write the configured files. For normal hosted,
378
+ multi-user apps, use database mode and SQL-backed sharing.
@@ -71,7 +71,10 @@ truth instead of SQL documents. Add `agent-native.json` to a repo, set
71
71
  left sidebar from those local `.md`/`.mdx` files and writes edits back to the
72
72
  selected file through the normal document actions. Use this for repo-first docs,
73
73
  blogs, resource libraries, or Obsidian-style personal content; switch back to
74
- database mode when you want hosted collaboration and SQL-backed sharing.
74
+ database mode when you want hosted collaboration and SQL-backed sharing. See
75
+ [Local File Mode](/docs/local-file-mode) for the standalone repo layout,
76
+ configuration, custom MDX components, local `extensions/` widgets, and
77
+ production safety guide.
75
78
 
76
79
  ## Why it's interesting
77
80
 
@@ -143,9 +146,18 @@ Sync state is tracked in the `document_sync_links` table (last synced time, conf
143
146
 
144
147
  ### Local file sync
145
148
 
146
- The protected `/local-files` route uses the browser File System Access API (or
147
- the same Chromium capability inside Agent Native Desktop) to read and write
148
- Markdown/MDX files from a user-chosen folder. It calls:
149
+ The protected `/local-files` route uses the browser File System Access API, or a
150
+ guarded native folder bridge inside Agent Native Desktop, to read and write
151
+ Markdown/MDX files from a user-chosen folder. After the folder is linked and
152
+ imported, the selected file is treated as the authority: opening the page reads
153
+ the file, and normal editor saves write the file first. SQL is then updated as a
154
+ cache/history layer for the existing document UI, search, and version panel, not
155
+ as the source of truth. The top-right page menu exposes the local source path:
156
+ relative path is always available, absolute path is available in true local-file
157
+ mode and Agent Native Desktop, and Reveal in Finder is available through the
158
+ desktop bridge or server-backed local-file mode.
159
+
160
+ The bulk sync route calls:
149
161
 
150
162
  - `export-content-source` — reads the accessible document tree and returns a
151
163
  deterministic `content/` file bundle.
@@ -156,6 +168,43 @@ Markdown/MDX files from a user-chosen folder. It calls:
156
168
  The source format lives in `shared/content-source.ts`. Keep that file as the
157
169
  single contract for filenames, frontmatter, parsing, and serialization.
158
170
 
171
+ Local file workspaces can also provide repo-local React components through the
172
+ configured `components` folder. The Content dev server imports PascalCase
173
+ exports from those files, renders matching MDX tags such as `<ImpactCounter />`
174
+ inside the editor, and exposes them in the slash menu under Local components.
175
+ This keeps custom MDX blocks local to the workspace without cloning the Content
176
+ app. A minimal workspace component can be:
177
+
178
+ ```tsx
179
+ // components/ImpactCounter.tsx
180
+ import { useState } from "react";
181
+
182
+ export function ImpactCounter({
183
+ label = "points",
184
+ start = 3,
185
+ }: {
186
+ label?: string;
187
+ start?: number;
188
+ }) {
189
+ const [count, setCount] = useState(start);
190
+ return (
191
+ <button type="button" onClick={() => setCount(count + 1)}>
192
+ Impact: {count} {label}
193
+ </button>
194
+ );
195
+ }
196
+
197
+ export const ImpactCounterInputs = {
198
+ label: { type: "string", label: "Label", default: "points" },
199
+ start: { type: "number", label: "Starting count", default: 3 },
200
+ };
201
+ ```
202
+
203
+ Use it in local MDX as `<ImpactCounter />`, or insert it from the editor slash
204
+ menu under Local components. When input metadata is exported, selecting the
205
+ component in the editor shows a corner edit button that rewrites the MDX props
206
+ in the local file.
207
+
159
208
  ### Comments
160
209
 
161
210
  Threaded comments on documents with quoted-text anchors, replies, and resolve state. Backed by the `document_comments` table and `app/components/editor/CommentsSidebar.tsx`. Actions: `list-comments`, `add-comment`. Notion comments can sync both ways via `sync-notion-comments`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.49.11",
3
+ "version": "0.49.13",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22"