@agent-native/core 0.12.15 → 0.12.17

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 (85) hide show
  1. package/dist/agent/production-agent.d.ts +1 -1
  2. package/dist/agent/production-agent.d.ts.map +1 -1
  3. package/dist/agent/production-agent.js +1 -1
  4. package/dist/agent/production-agent.js.map +1 -1
  5. package/dist/agent/run-manager.d.ts.map +1 -1
  6. package/dist/agent/run-manager.js +56 -42
  7. package/dist/agent/run-manager.js.map +1 -1
  8. package/dist/cli/create.js +1 -1
  9. package/dist/cli/create.js.map +1 -1
  10. package/dist/cli/index.js +13 -2
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/workspace-dev.d.ts +40 -1
  13. package/dist/cli/workspace-dev.d.ts.map +1 -1
  14. package/dist/cli/workspace-dev.js +506 -363
  15. package/dist/cli/workspace-dev.js.map +1 -1
  16. package/dist/client/AgentPanel.d.ts +16 -0
  17. package/dist/client/AgentPanel.d.ts.map +1 -1
  18. package/dist/client/AgentPanel.js +30 -9
  19. package/dist/client/AgentPanel.js.map +1 -1
  20. package/dist/client/AssistantChat.d.ts +4 -0
  21. package/dist/client/AssistantChat.d.ts.map +1 -1
  22. package/dist/client/AssistantChat.js +49 -14
  23. package/dist/client/AssistantChat.js.map +1 -1
  24. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  25. package/dist/client/MultiTabAssistantChat.js +17 -3
  26. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  27. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
  28. package/dist/client/NewWorkspaceAppFlow.js +4 -1
  29. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  30. package/dist/client/agent-chat.d.ts +1 -1
  31. package/dist/client/agent-chat.js.map +1 -1
  32. package/dist/client/components/CodeRequiredDialog.d.ts +3 -2
  33. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  34. package/dist/client/components/CodeRequiredDialog.js +4 -3
  35. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  36. package/dist/client/composer/PromptComposer.d.ts +2 -0
  37. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  38. package/dist/client/composer/PromptComposer.js +2 -2
  39. package/dist/client/composer/PromptComposer.js.map +1 -1
  40. package/dist/client/composer/TiptapComposer.d.ts +6 -1
  41. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  42. package/dist/client/composer/TiptapComposer.js +21 -12
  43. package/dist/client/composer/TiptapComposer.js.map +1 -1
  44. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  45. package/dist/client/settings/SettingsPanel.js +3 -0
  46. package/dist/client/settings/SettingsPanel.js.map +1 -1
  47. package/dist/client/sharing/ShareButton.js +6 -1
  48. package/dist/client/sharing/ShareButton.js.map +1 -1
  49. package/dist/client/sharing/ShareButton.spec.d.ts +2 -0
  50. package/dist/client/sharing/ShareButton.spec.d.ts.map +1 -0
  51. package/dist/client/sharing/ShareButton.spec.js +90 -0
  52. package/dist/client/sharing/ShareButton.spec.js.map +1 -0
  53. package/dist/client/sse-event-processor.d.ts.map +1 -1
  54. package/dist/client/sse-event-processor.js +10 -2
  55. package/dist/client/sse-event-processor.js.map +1 -1
  56. package/dist/client/use-chat-threads.d.ts.map +1 -1
  57. package/dist/client/use-chat-threads.js +19 -2
  58. package/dist/client/use-chat-threads.js.map +1 -1
  59. package/dist/client/use-send-to-agent-chat.d.ts +3 -3
  60. package/dist/client/use-send-to-agent-chat.js +3 -3
  61. package/dist/client/use-send-to-agent-chat.js.map +1 -1
  62. package/dist/deploy/workspace-deploy.js +4 -1
  63. package/dist/deploy/workspace-deploy.js.map +1 -1
  64. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  65. package/dist/server/agent-chat-plugin.js +11 -7
  66. package/dist/server/agent-chat-plugin.js.map +1 -1
  67. package/dist/templates/default/AGENTS.md +7 -1
  68. package/dist/templates/default/DEVELOPING.md +12 -0
  69. package/dist/templates/default/app/hooks/use-navigation-state.ts +81 -0
  70. package/dist/templates/default/app/root.tsx +11 -5
  71. package/dist/templates/workspace-root/AGENTS.md +3 -1
  72. package/dist/templates/workspace-root/README.md +4 -4
  73. package/dist/vite/client.d.ts.map +1 -1
  74. package/dist/vite/client.js +34 -6
  75. package/dist/vite/client.js.map +1 -1
  76. package/docs/content/multi-app-workspace.md +1 -1
  77. package/package.json +1 -1
  78. package/src/templates/default/AGENTS.md +7 -1
  79. package/src/templates/default/DEVELOPING.md +12 -0
  80. package/src/templates/default/app/hooks/use-navigation-state.ts +81 -0
  81. package/src/templates/default/app/root.tsx +11 -5
  82. package/src/templates/workspace-root/AGENTS.md +3 -1
  83. package/src/templates/workspace-root/README.md +4 -4
  84. package/dist/templates/workspace-root/netlify.toml +0 -11
  85. package/src/templates/workspace-root/netlify.toml +0 -11
@@ -69,7 +69,7 @@ Then boot it:
69
69
  cd my-company-platform
70
70
  cp .env.example .env # fill in ANTHROPIC_API_KEY, BETTER_AUTH_SECRET, ...
71
71
  pnpm install
72
- pnpm dev # runs every app
72
+ pnpm dev # opens Dispatch; other apps start on first visit
73
73
  ```
74
74
 
75
75
  Every app already knows how to log in, share the same database, and load the workspace `AGENTS.md`. You didn't wire any of that up — the framework auto-discovered the shared package via the `agent-native.workspaceCore` field in the root `package.json`:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.12.15",
3
+ "version": "0.12.17",
4
4
  "type": "module",
5
5
  "description": "Framework for agent-native application development — where AI agents and UI share state via files",
6
6
  "license": "MIT",
@@ -50,6 +50,12 @@ Ephemeral UI state is stored in the SQL `application_state` table, accessed via
50
50
 
51
51
  The `navigation` key is written by the UI whenever the route changes. The `navigate` key is a one-shot command: the agent writes it, the UI reads and executes the navigation, then deletes it.
52
52
 
53
+ ## Mounted Workspace Routing
54
+
55
+ This app may be mounted under `/<app-id>` in a workspace. Inside app source, React Router paths are app-local: use `<Link to="/review">` and `navigate("/review")`, not `/<app-id>/review`. The workspace gateway and `APP_BASE_PATH` add the mounted prefix in the browser; hardcoding it inside React Router links causes doubled URLs such as `/<app-id>/<app-id>/review`.
56
+
57
+ For raw paths outside React Router, use the core helpers: `appPath()` for static assets or normal hrefs, `appApiPath()` for `/api/*`, and `agentNativePath()` for `/_agent-native/*`.
58
+
53
59
  ## Agent Operations
54
60
 
55
61
  **Always know what the user is currently viewing before you edit anything.** The user's view can change mid-conversation. Stale IDs lead to editing the wrong record.
@@ -101,7 +107,7 @@ Skills in `.agents/skills/` provide detailed guidance for each architectural rul
101
107
 
102
108
  As you build out this app, follow this checklist for each new feature:
103
109
 
104
- 1. **Add navigation state entries** -- create or extend `app/hooks/use-navigation-state.ts` to track new routes
110
+ 1. **Add navigation state entries** -- extend `app/hooks/use-navigation-state.ts` to track new routes
105
111
  2. **Enhance view-screen** -- make the view-screen script return relevant context for the new view
106
112
  3. **Create domain actions** -- add scripts for CRUD operations on new data models
107
113
  4. **Create domain skills** -- add `.agents/skills/<feature>/SKILL.md` documenting the data model, storage patterns, and agent operations
@@ -20,6 +20,18 @@ app/routes/inbox.$threadId.tsx → /inbox/:threadId
20
20
  app/routes/$id.tsx → /:id (dynamic param)
21
21
  ```
22
22
 
23
+ ## Mounted Workspace Routing
24
+
25
+ In a workspace, this app can be mounted under `/<app-id>`. React Router already receives `APP_BASE_PATH`/`VITE_APP_BASE_PATH` through `appBasePath()`, so route code stays app-local:
26
+
27
+ | Route file | App-internal route | Mounted browser URL |
28
+ | ----------------------- | ------------------ | ------------------- |
29
+ | `app/routes/_index.tsx` | `/` | `/<app-id>` |
30
+ | `app/routes/review.tsx` | `/review` | `/<app-id>/review` |
31
+ | `app/routes/$id.tsx` | `/:id` | `/<app-id>/:id` |
32
+
33
+ Use `<Link to="/review">` and `navigate("/review")` inside this app. Do not prefix React Router paths with `/<app-id>` or the URL can double-prefix, e.g. `/<app-id>/<app-id>/review`. Use `appPath()` for raw `href`s/static assets, `appApiPath()` for `/api/*`, and `agentNativePath()` for `/_agent-native/*`.
34
+
23
35
  Each route file exports a default component and optional `meta()`:
24
36
 
25
37
  ```tsx
@@ -0,0 +1,81 @@
1
+ import { useEffect } from "react";
2
+ import { useLocation, useNavigate } from "react-router";
3
+ import { useQuery, useQueryClient } from "@tanstack/react-query";
4
+ import {
5
+ agentNativePath,
6
+ appBasePath,
7
+ appPath,
8
+ } from "@agent-native/core/client";
9
+
10
+ export interface NavigationState {
11
+ view: string;
12
+ path?: string;
13
+ }
14
+
15
+ export function useNavigationState() {
16
+ const location = useLocation();
17
+ const navigate = useNavigate();
18
+ const qc = useQueryClient();
19
+
20
+ useEffect(() => {
21
+ const state: NavigationState = {
22
+ view: viewFromPath(location.pathname),
23
+ path: appPath(location.pathname),
24
+ };
25
+
26
+ fetch(agentNativePath("/_agent-native/application-state/navigation"), {
27
+ method: "PUT",
28
+ keepalive: true,
29
+ headers: { "Content-Type": "application/json" },
30
+ body: JSON.stringify(state),
31
+ }).catch(() => {});
32
+ }, [location.pathname]);
33
+
34
+ const { data: navCommand } = useQuery({
35
+ queryKey: ["navigate-command"],
36
+ queryFn: async () => {
37
+ const res = await fetch(
38
+ agentNativePath("/_agent-native/application-state/navigate"),
39
+ );
40
+ if (!res.ok) return null;
41
+ const data = await res.json();
42
+ return data ? { ...data, _ts: Date.now() } : null;
43
+ },
44
+ refetchInterval: 2_000,
45
+ refetchIntervalInBackground: true,
46
+ structuralSharing: false,
47
+ });
48
+
49
+ useEffect(() => {
50
+ if (!navCommand) return;
51
+ fetch(agentNativePath("/_agent-native/application-state/navigate"), {
52
+ method: "DELETE",
53
+ headers: { "X-Agent-Native-CSRF": "1" },
54
+ }).catch(() => {});
55
+ const cmd = navCommand as NavigationState;
56
+
57
+ const path = routerPath(cmd.path || pathFromView(cmd.view));
58
+ navigate(path);
59
+ qc.setQueryData(["navigate-command"], null);
60
+ }, [navCommand, navigate, qc]);
61
+ }
62
+
63
+ function viewFromPath(pathname: string): string {
64
+ if (!pathname || pathname === "/") return "home";
65
+ return pathname.replace(/^\/+/, "") || "home";
66
+ }
67
+
68
+ function pathFromView(view: string | undefined): string {
69
+ if (!view || view === "home") return "/";
70
+ return `/${view.replace(/^\/+/, "")}`;
71
+ }
72
+
73
+ function routerPath(path: string): string {
74
+ const basePath = appBasePath();
75
+ if (!basePath) return path;
76
+ if (path === basePath) return "/";
77
+ if (path.startsWith(`${basePath}/`)) {
78
+ return path.slice(basePath.length) || "/";
79
+ }
80
+ return path;
81
+ }
@@ -16,10 +16,15 @@ import {
16
16
  } from "@tanstack/react-query";
17
17
  import { ThemeProvider } from "next-themes";
18
18
  import { useDbSync } from "@agent-native/core";
19
- import { ClientOnly, DefaultSpinner } from "@agent-native/core/client";
20
- import { getThemeInitScript } from "@agent-native/core/client";
19
+ import {
20
+ ClientOnly,
21
+ DefaultSpinner,
22
+ appPath,
23
+ getThemeInitScript,
24
+ } from "@agent-native/core/client";
21
25
  import { Toaster } from "sonner";
22
26
  import { configureTracking } from "@agent-native/core/client";
27
+ import { useNavigationState } from "./hooks/use-navigation-state";
23
28
  configureTracking({
24
29
  getDefaultProps: (_name, properties) => ({
25
30
  ...properties,
@@ -56,8 +61,8 @@ export function Layout({ children }: { children: React.ReactNode }) {
56
61
  suppressHydrationWarning
57
62
  dangerouslySetInnerHTML={{ __html: THEME_INIT_SCRIPT }}
58
63
  />
59
- <link rel="manifest" href="/manifest.json" />
60
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
64
+ <link rel="manifest" href={appPath("/manifest.json")} />
65
+ <link rel="icon" type="image/svg+xml" href={appPath("/favicon.svg")} />
61
66
  <meta name="theme-color" content="#111111" />
62
67
  <meta name="mobile-web-app-capable" content="yes" />
63
68
  <meta
@@ -65,7 +70,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
65
70
  content="black-translucent"
66
71
  />
67
72
  <meta name="apple-mobile-web-app-title" content="App" />
68
- <link rel="apple-touch-icon" href="/icon-180.svg" />
73
+ <link rel="apple-touch-icon" href={appPath("/icon-180.svg")} />
69
74
  <Meta />
70
75
  <Links />
71
76
  </head>
@@ -80,6 +85,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
80
85
 
81
86
  function DbSyncSetup() {
82
87
  const qc = useQueryClient();
88
+ useNavigationState();
83
89
  useDbSync({ queryClient: qc, queryKeys: ["files", "data"] });
84
90
  return null;
85
91
  }
@@ -56,7 +56,9 @@ in `apps/<app>/AGENTS.md`; shared cross-app behavior belongs in
56
56
  - In local development, scaffold the app from the workspace root with
57
57
  `pnpm exec agent-native create <app-id> --template=<template>`. In production
58
58
  Dispatch posts the request to Builder branch creation; the Builder branch
59
- should still create the separate workspace app, not patch starter.
59
+ should still create the separate workspace app, not patch starter. The local
60
+ workspace gateway detects new app directories automatically and starts each
61
+ app server lazily on first visit.
60
62
 
61
63
  ## Workspace Identity
62
64
 
@@ -44,10 +44,10 @@ pnpm dev # starts the workspace gateway; opens Dispatch when prese
44
44
 
45
45
  The dev gateway serves Dispatch at `/dispatch` when you keep the recommended
46
46
  Dispatch app selected, and every app at its own path such as `/starter`. It
47
- watches `apps/`, so newly-created apps are detected and started without
48
- restarting `pnpm dev`. App links should stay relative, such as `/starter` or
49
- `/<app-id>`; do not hardcode localhost or dev ports because the active gateway
50
- origin owns the port.
47
+ watches `apps/`, so newly-created apps are detected without restarting
48
+ `pnpm dev`. App servers start lazily the first time you visit their path. App
49
+ links should stay relative, such as `/starter` or `/<app-id>`; do not hardcode
50
+ localhost or dev ports because the active gateway origin owns the port.
51
51
 
52
52
  ## Workspace org identity
53
53
 
@@ -1,11 +0,0 @@
1
- [build]
2
- command = "export DATABASE_URL=\"${NETLIFY_DATABASE_URL:-$DATABASE_URL}\" && pnpm install && pnpm exec agent-native deploy --preset netlify --build-only"
3
- publish = "dist"
4
- functions = ".netlify/functions-internal"
5
-
6
- [build.environment]
7
- NITRO_PRESET = "netlify"
8
- NPM_CONFIG_PRODUCTION = "false"
9
-
10
- [functions."*"]
11
- timeout = 60
@@ -1,11 +0,0 @@
1
- [build]
2
- command = "export DATABASE_URL=\"${NETLIFY_DATABASE_URL:-$DATABASE_URL}\" && pnpm install && pnpm exec agent-native deploy --preset netlify --build-only"
3
- publish = "dist"
4
- functions = ".netlify/functions-internal"
5
-
6
- [build.environment]
7
- NITRO_PRESET = "netlify"
8
- NPM_CONFIG_PRODUCTION = "false"
9
-
10
- [functions."*"]
11
- timeout = 60