@agent-native/dispatch 0.11.5 → 0.11.7

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/README.md CHANGED
@@ -1,33 +1,8 @@
1
1
  # Agent-Native
2
2
 
3
- ### Open-source framework for agentic applications you own.
4
-
5
- Don't choose between rich user interfaces and autonomous agents. Every Agent-Native app is both.
6
-
7
- ## Agents and UIs — Fully Connected
8
-
9
- The agent and the UI are equal citizens of the same system. Every action works both ways — click it or ask for it.
10
-
11
- ![Agents and UIs fully connected](https://cdn.builder.io/api/v1/file/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fadc1e9e9368e4a8cb1b4dbb5aae5aaa2)
12
-
13
- - **Everything syncs** — Agent and UI share one database and one state. Changes from either side show up instantly on the other.
14
- - **Real-time multiplayer** — Humans and agents collaborate in the same document simultaneously: CRDT merging, live presence (cursors, selection rings, who's on which slide), and the agent as a first-class peer editor. Works on any SQL database and any host, including serverless.
15
- - **Context-aware** — The agent knows what you're looking at. Select text, hit Cmd+I, and tell it what to do.
16
- - **Per-user workspace** — Skills, memory, instructions, sub-agents, and MCP servers — SQL-backed, customizable per user. Claude-Code-level flexibility, SaaS-grade economics.
17
- - **Agents call agents** — Tag another agent from any app. They discover each other over A2A and take action across your stack.
18
- - **Reusable integrations** — Connect a provider once in Dispatch, keep secret values in the vault, then grant apps like Brain, Analytics, Mail, and Dispatch access to the shared account metadata and credential refs.
19
- - **Three shapes** — Build the same agent as a headless API, a rich chat experience, or a full application where agent and UI stay in sync.
20
- - **Apps that improve themselves** — Your apps get better on their own. The agent can add features, fix bugs, and refine the UI over time.
21
- - **Any database, any host** — Any SQL database Drizzle supports. Any hosting target Nitro supports. No lock-in.
22
- - **Bring the agent surface you need** — MCP-compatible hosts can call your apps, coding agents can install skills, native chat renders reusable app outputs, and BYO agent runtimes can stream into the Agent-Native chat shell.
23
-
24
3
  ## The framework for agent-native apps
25
4
 
26
- Agent-Native is an open-source framework for building robust agents that can act inside real apps, not just chat next to them.
27
-
28
- It gives you primitives for product-grade agentic software: shared actions, SQL-backed state, identity, tools, skills, jobs, observability, and UI surfaces that all work together.
29
-
30
- Backend agnostic: bring your own database, hosting provider, model stack, and app code.
5
+ Agent-Native is an open-source framework for building robust agents that act inside real apps, not just chat next to them. It gives you primitives for product-grade agentic software: shared actions, SQL-backed state, identity, tools, skills, jobs, observability, and UI surfaces that all work together. Bring your own database, hosting provider, model stack, and app code.
31
6
 
32
7
  ```ts
33
8
  // One action powers UI, agent, HTTP, MCP, A2A, and CLI.
@@ -42,58 +17,51 @@ export default defineAction({
42
17
  });
43
18
  ```
44
19
 
45
- - **Actions** Define work once. Use it from UI, agent, API, MCP, A2A, and CLI.
46
- - **Agent runtime** Chat, tools, skills, memory, jobs, observability, and handoffs ship together.
47
- - **Backend agnostic** Plug in any Drizzle-supported SQL database and Nitro-compatible host.
20
+ - **Actions**: Define work once. Use it from UI, agent, API, MCP, A2A, and CLI.
21
+ - **Agent runtime**: Chat, tools, skills, memory, jobs, observability, and handoffs ship together.
22
+ - **Backend agnostic**: Plug in any Drizzle-supported SQL database and Nitro-compatible host.
48
23
 
49
- ## One agent, three product shapes
50
-
51
- Agent-Native primitives let you choose how much UI to put around an agent without rebuilding the agent contract:
52
-
53
- | Shape | What you ship | Same primitives underneath |
54
- | ------------- | --------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
55
- | **Headless** | Call the agent and actions from code, CLI, HTTP, MCP, or A2A. | `defineAction`, auth, skills, memory, jobs, observability |
56
- | **Rich chat** | A standalone or embedded chat with native tables, charts, approvals, setup flows, and tool results. | Shared chat runtime, BYO runtime adapters, action-declared native renderers |
57
- | **Whole app** | A full SaaS/product UI where chat can start central, move to the sidebar, and stay synced with app state. | SQL state, actions, context awareness, deep links, live sync |
24
+ ## Templates
58
25
 
59
- Protocols come with the framework instead of becoming separate integrations per feature. Today that means A2A, MCP, MCP Apps, standard remote MCP OAuth, MCP clients, HTTP/CLI action calls, native chat widgets, `AgentChatRuntime` adapters, standard OpenAI, AG-UI, Claude Agent SDK, and Vercel AI SDK chat runtime connectors, and deep links all hang off the same action surface. ACP is best understood as the coding-agent/editor interoperability protocol, not the general BYO app-chat runtime.
26
+ Start with a full featured template. Each one is a complete, 100% free and open-source SaaS app: cloneable, not scaffolded, except you own the code and can customize everything.
60
27
 
61
- For the full decision guide — headless, rich chat on the built-in agent, rich chat on your own agent, embedded sidecar, or full app — see [Agent Surfaces](https://agent-native.com/docs/agent-surfaces).
28
+ <table>
29
+ <tr>
30
+ <td width="33%" align="center" valign="top">
62
31
 
63
- To connect Claude, ChatGPT, Codex, Cursor, OpenCode, GitHub Copilot / VS Code, or another MCP host to your hosted app, see the [External Agents guide](https://agent-native.com/docs/external-agents).
32
+ **Clips**
64
33
 
65
- ## Try it with a skill
34
+ <a href="https://agent-native.com/templates/clips"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F189ebd9b2f2b4f0ead3b33138d4e4c10?format=webp&width=800" alt="Clips template" width="100%" /></a>
66
35
 
67
- Don't want to scaffold a whole app yet? Add visual planning and PR recaps to Claude Code, Codex, Cursor, Pi, OpenCode, GitHub Copilot / VS Code, and similar agents with one command:
36
+ **Agent-Native Loom + Jam**
68
37
 
69
- ```bash
70
- npx @agent-native/core@latest skills add visual-plan
71
- ```
38
+ Record your screen with auto-transcripts and captured browser debug logs, share a link, and let an agent read the transcript, see timestamped frames, and fix the bug.
72
39
 
73
- You get two slash commands that upgrade how your agent plans and reports its work:
40
+ </td>
41
+ <td width="33%" align="center" valign="top">
74
42
 
75
- - **`/visual-plan`** — before the agent writes code, it opens a structured, reviewable plan document instead of a wall of text: inline diagrams, UI wireframes and prototypes, file-by-file implementation maps, and annotations you can comment on and approve.
76
- - **`/visual-recap`** — after changes land, it turns a PR or git diff into a high-altitude visual recap: schema, API, and file changes rendered as grounded before/after blocks with a shareable review link, instead of scrolling a raw diff.
43
+ **Plans**
77
44
 
78
- See the **[Skills Guide](https://agent-native.com/docs/skills-guide#app-backed-skills)** for more skills and local installs.
45
+ <a href="https://agent-native.com/templates/plan"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fb6f4213ac7cc42eeb10c12e8ccda8936?format=webp&width=800" alt="Plans template" width="100%" /></a>
79
46
 
80
- ## Templates
47
+ **Visual plan mode for coding agents**
81
48
 
82
- Start with a full featured template. Each one is a complete, 100% free and open-source SaaS app cloneable, not scaffolded except you own the code and can customize everything.
49
+ Install `/visual-plan` and `/visual-recap` so your coding agent can plan before it builds and recap changes after they land. High-level code reviews with diagrams, wireframes, annotations, and review links.
83
50
 
84
- <table>
85
- <tr>
51
+ </td>
86
52
  <td width="33%" align="center" valign="top">
87
53
 
88
- **Calendar**
54
+ **Design**
89
55
 
90
- <a href="https://agent-native.com/templates/calendar"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Ffb6c3b483ca24ab3b6c3a758aeceef4c?format=webp&width=800" alt="Calendar template" width="100%" /></a>
56
+ <a href="https://agent-native.com/templates/design"><img src="https://cdn.builder.io/api/v1/image/assets%2F348da13fcd8b414c87de9066196f7266%2F961bedb713a94463b834c1f2f4643bcf?format=webp&width=800" alt="Design template" width="100%" /></a>
91
57
 
92
- **Agent-Native Google Calendar, Calendly**
58
+ **Agent-Native design prototyping**
93
59
 
94
- Manage events, sync with Google Calendar, and share a public booking page with AI scheduling.
60
+ Generate interactive HTML prototypes, compare variants, refine controls, and export the result.
95
61
 
96
62
  </td>
63
+ </tr>
64
+ <tr>
97
65
  <td width="33%" align="center" valign="top">
98
66
 
99
67
  **Content**
@@ -107,19 +75,6 @@ Edit local Markdown/MDX files, generate rich interactive custom blocks, and draf
107
75
  </td>
108
76
  <td width="33%" align="center" valign="top">
109
77
 
110
- **Plans**
111
-
112
- <a href="https://agent-native.com/templates/plan"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fb6f4213ac7cc42eeb10c12e8ccda8936?format=webp&width=800" alt="Plans template" width="100%" /></a>
113
-
114
- **Visual plan mode for coding agents**
115
-
116
- Install `/visual-plan` and `/visual-recap` so your coding agent can plan before it builds and recap changes after they land — high-level code reviews with diagrams, wireframes, annotations, and review links.
117
-
118
- </td>
119
- </tr>
120
- <tr>
121
- <td width="33%" align="center" valign="top">
122
-
123
78
  **Slides**
124
79
 
125
80
  <a href="https://agent-native.com/templates/slides"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F2c09b451d40c4a74a89a38d69170c2d8?format=webp&width=800" alt="Slides template" width="100%" /></a>
@@ -137,79 +92,61 @@ Generate and edit React-based presentations via prompt or point-and-click.
137
92
 
138
93
  **Agent-Native Amplitude, Mixpanel**
139
94
 
140
- Connect analytics data sources, prompt for real charts, and build reusable dashboards. Shared workspace connections can provide provider credentials, while Analytics still owns metrics, source-of-truth choices, and saved analyses.
141
-
142
- </td>
143
- <td width="33%" align="center" valign="top">
144
-
145
- **Clips**
146
-
147
- <a href="https://agent-native.com/templates/clips"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F678be5a501a14ab8a508e5f7bc92c468?format=webp&width=800" alt="Clips template" width="100%" /></a>
148
-
149
- **Agent-Native Loom**
150
-
151
- Record your screen with auto-transcripts, shareable links, and an agent that summarizes, captions, and edits clips on demand.
95
+ Connect analytics data sources, prompt for real charts, and build reusable dashboards.
152
96
 
153
97
  </td>
154
98
  </tr>
155
99
  </table>
156
100
 
157
- Every template is a complete cloneable SaaS — fork it, customize it with the agent, own it. Try them with example data before connecting your own sources.
158
-
159
101
  View the full template gallery at **[agent-native.com/templates](https://agent-native.com/templates)**.
160
102
 
161
- ## Quick Start
103
+ ## Agents and UIs, Fully Connected
162
104
 
163
- One command to fork a template and start building locally.
105
+ The agent and the UI are equal citizens of one system. Every action works both ways: click it or ask for it.
164
106
 
165
- ```bash
166
- npx @agent-native/core@latest create my-platform
167
- cd my-platform
168
- pnpm install
169
- pnpm dev
170
- ```
107
+ ![Agents and UIs fully connected](https://cdn.builder.io/api/v1/file/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fadc1e9e9368e4a8cb1b4dbb5aae5aaa2)
171
108
 
172
- The CLI shows a multi-select picker so you can include as many templates as you want in one workspace. Pick Mail + Calendar + Forms and you get all three apps wired up and sharing auth in one go. Or browse the **[template gallery](https://agent-native.com/templates)** for live demos.
109
+ - **Everything syncs**: One database, one state. Changes from either side show up instantly on the other.
110
+ - **Real-time multiplayer**: Humans and agents edit the same document together, with the agent as a first-class peer.
111
+ - **Context-aware**: The agent knows what you're looking at. Select text, hit Cmd+I, and tell it what to do.
112
+ - **Agents call agents**: Tag another agent from any app and they coordinate over A2A.
113
+ - **Self-improving**: The agent can add features, fix bugs, and refine the UI over time.
173
114
 
174
- Want a single app, no monorepo? Use `--standalone`:
115
+ ## Try it with a skill
116
+
117
+ Don't want to scaffold a whole app yet? Add visual planning and PR recaps to Claude Code, Codex, Cursor, Pi, OpenCode, GitHub Copilot / VS Code, and similar agents with one command:
175
118
 
176
119
  ```bash
177
- npx @agent-native/core@latest create my-app --standalone --template mail
120
+ npx @agent-native/core@latest skills add visual-plan
178
121
  ```
179
122
 
180
- ## Workspaces (Monorepo)
123
+ ![Visual plan and recap in action](https://raw.githubusercontent.com/builderio/skills/main/media/visual-recap.gif)
181
124
 
182
- A workspace is the default shape of an agent-native project. Every app sits under `apps/`, and `packages/shared/` is available for the small amount of code, instructions, skills, or branding that should truly apply to every app.
125
+ You get two slash commands:
183
126
 
184
- ```
185
- my-platform/
186
- ├── package.json # declares `agent-native.workspaceCore`
187
- ├── pnpm-workspace.yaml
188
- ├── .env # shared secrets: ANTHROPIC_API_KEY, BUILDER_PRIVATE_KEY, A2A_SECRET, ...
189
- ├── packages/
190
- │ └── shared/ # optional shared custom code
191
- └── apps/
192
- ├── mail/
193
- ├── calendar/
194
- └── forms/
195
- ```
127
+ - **`/visual-plan`**: before the agent writes code, it opens a structured, reviewable plan with inline diagrams, UI wireframes, file-by-file implementation maps, and annotations you can comment on and approve.
128
+ - **`/visual-recap`**: after changes land, it turns a PR or git diff into a high-altitude visual recap with a shareable review link instead of a raw diff.
196
129
 
197
- Add another app later:
130
+ See the **[Skills Guide](https://agent-native.com/docs/skills-guide#app-backed-skills)** for more.
198
131
 
199
- ```bash
200
- npx @agent-native/core@latest add-app notes --template content
201
- ```
132
+ ## Quick Start
202
133
 
203
- Deploy every app behind one origin:
134
+ One command to start a new project locally.
204
135
 
205
136
  ```bash
206
- npx @agent-native/core@latest deploy
207
- # https://your-agents.com/mail/* → mail
208
- # https://your-agents.com/calendar/* → calendar
209
- # https://your-agents.com/forms/* → forms
137
+ npx @agent-native/core@latest create my-app
138
+ cd my-app
139
+ pnpm install
140
+ pnpm dev
210
141
  ```
211
142
 
212
- Same-origin deploy means a **shared login session** across every app and **zero-config cross-app A2A** — tag `@mail` from the calendar's agent chat and it just works (no JWT signing, no CORS). Full details at **[agent-native.com/docs/multi-app-workspace](https://agent-native.com/docs/multi-app-workspace)**.
143
+ `create` first asks how you want to start:
144
+
145
+ - **Full template(s)**: clone one or more complete apps into a workspace. Pick Mail + Calendar + Forms and you get all three wired up and sharing auth.
146
+ - **Chat**: a single app with a minimal chat UI and the browser shell already wired, the simplest way to get a UI.
147
+ - **Headless**: a single action-first app with no UI shell. The CLI walks you through calling your first action and agent, and you can add a UI later.
148
+
149
+ Prefer flags? `create my-app --template mail`, `--headless`, or `--standalone` skip the prompt.
213
150
 
214
151
  ## The Best of Both Worlds
215
152
 
@@ -1 +1 @@
1
- {"version":3,"file":"create-vault-secret.d.ts","sourceRoot":"","sources":["../../src/actions/create-vault-secret.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAIA,wBAiBG"}
1
+ {"version":3,"file":"create-vault-secret.d.ts","sourceRoot":"","sources":["../../src/actions/create-vault-secret.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAIA,wBAsBG"}
@@ -16,6 +16,11 @@ export default defineAction({
16
16
  .describe("Provider grouping tag, e.g. google, sendgrid, slack"),
17
17
  description: z.string().optional().describe("Optional description"),
18
18
  }),
19
+ // This action's whole purpose is to carry a secret `value`. The vault owns
20
+ // secret storage; the audit log must record THAT a secret was created — never
21
+ // the value. Opt out of input capture so the trail can't become a second
22
+ // durable credential store.
23
+ audit: { recordInputs: false },
19
24
  run: async (args) => createSecret(args),
20
25
  });
21
26
  //# sourceMappingURL=create-vault-secret.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-vault-secret.js","sourceRoot":"","sources":["../../src/actions/create-vault-secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,8LAA8L;IAChM,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,aAAa,EAAE,CAAC;aACb,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CAAC,kDAAkD,CAAC;QAC/D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QACrD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC;QACxE,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,qDAAqD,CAAC;QAClE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACpE,CAAC;IACF,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;CACxC,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport { createSecret } from \"../server/lib/vault-store.js\";\n\nexport default defineAction({\n description:\n \"Store a secret in the workspace vault. Admin only. Existing credential keys are updated. By default, saved vault keys are available to every workspace app; manual mode uses per-app grants.\",\n schema: z.object({\n credentialKey: z\n .string()\n .min(1)\n .describe(\"Environment variable name, e.g. GOOGLE_CLIENT_ID\"),\n value: z.string().min(1).describe(\"The secret value\"),\n name: z.string().min(1).describe(\"Human-readable label for this secret\"),\n provider: z\n .string()\n .optional()\n .describe(\"Provider grouping tag, e.g. google, sendgrid, slack\"),\n description: z.string().optional().describe(\"Optional description\"),\n }),\n run: async (args) => createSecret(args),\n});\n"]}
1
+ {"version":3,"file":"create-vault-secret.js","sourceRoot":"","sources":["../../src/actions/create-vault-secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,8LAA8L;IAChM,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,aAAa,EAAE,CAAC;aACb,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CAAC,kDAAkD,CAAC;QAC/D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QACrD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC;QACxE,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,qDAAqD,CAAC;QAClE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACpE,CAAC;IACF,2EAA2E;IAC3E,8EAA8E;IAC9E,yEAAyE;IACzE,4BAA4B;IAC5B,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE;IAC9B,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;CACxC,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport { createSecret } from \"../server/lib/vault-store.js\";\n\nexport default defineAction({\n description:\n \"Store a secret in the workspace vault. Admin only. Existing credential keys are updated. By default, saved vault keys are available to every workspace app; manual mode uses per-app grants.\",\n schema: z.object({\n credentialKey: z\n .string()\n .min(1)\n .describe(\"Environment variable name, e.g. GOOGLE_CLIENT_ID\"),\n value: z.string().min(1).describe(\"The secret value\"),\n name: z.string().min(1).describe(\"Human-readable label for this secret\"),\n provider: z\n .string()\n .optional()\n .describe(\"Provider grouping tag, e.g. google, sendgrid, slack\"),\n description: z.string().optional().describe(\"Optional description\"),\n }),\n // This action's whole purpose is to carry a secret `value`. The vault owns\n // secret storage; the audit log must record THAT a secret was created — never\n // the value. Opt out of input capture so the trail can't become a second\n // durable credential store.\n audit: { recordInputs: false },\n run: async (args) => createSecret(args),\n});\n"]}
@@ -12,10 +12,12 @@
12
12
  * Options:
13
13
  * --view View name to navigate to
14
14
  * --path URL path to navigate to
15
+ * --threadId Chat thread ID to open on the chat route
15
16
  */
16
17
  declare const _default: import("@agent-native/core").ActionDefinition<{
17
18
  view?: string | undefined;
18
19
  path?: string | undefined;
20
+ threadId?: string | undefined;
19
21
  }, string>;
20
22
  export default _default;
21
23
  //# sourceMappingURL=navigate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../../src/actions/navigate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;;;;;AAMH,wBAuBG"}
1
+ {"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../../src/actions/navigate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;;;;;;AAMH,wBA+BG"}
@@ -12,31 +12,42 @@
12
12
  * Options:
13
13
  * --view View name to navigate to
14
14
  * --path URL path to navigate to
15
+ * --threadId Chat thread ID to open on the chat route
15
16
  */
16
17
  import { defineAction } from "@agent-native/core";
17
18
  import { z } from "zod";
18
19
  import { writeAppState } from "@agent-native/core/application-state";
19
20
  export default defineAction({
20
- description: "Navigate the UI to a specific view or path. Writes a navigate command to application state which the UI reads and auto-deletes.",
21
+ description: "Navigate the UI to a specific view or path. Use threadId to open a specific chat thread on the chat route. Writes a navigate command to application state which the UI reads and auto-deletes.",
21
22
  schema: z.object({
22
23
  view: z
23
24
  .string()
24
25
  .optional()
25
26
  .describe("Named dispatch view to navigate to. Built-in views include chat, overview, apps, metrics, new-app, vault, integrations, messaging, workspace, agents, destinations, identities, approvals, audit, thread-debug, dreams, and team. Generated Dispatch extension tabs can also use their nav item id."),
26
27
  path: z.string().optional().describe("URL path to navigate to"),
28
+ threadId: z
29
+ .string()
30
+ .optional()
31
+ .describe("Chat thread ID to open on the chat route"),
27
32
  }),
28
33
  http: false,
29
34
  run: async (args) => {
30
- if (!args.view && !args.path) {
31
- return "Error: At least --view or --path is required.";
35
+ const threadId = args.threadId?.trim();
36
+ if (!args.view && !args.path && !threadId) {
37
+ return "Error: At least --view, --path, or --threadId is required.";
32
38
  }
33
39
  const nav = {};
40
+ // A thread id without an explicit view implies the chat surface.
34
41
  if (args.view)
35
42
  nav.view = args.view;
43
+ else if (threadId)
44
+ nav.view = "chat";
36
45
  if (args.path)
37
46
  nav.path = args.path;
47
+ if (threadId)
48
+ nav.threadId = threadId;
38
49
  await writeAppState("navigate", nav);
39
- return `Navigating to ${args.view || args.path}`;
50
+ return `Navigating to ${args.view || args.path || `chat thread ${threadId}`}`;
40
51
  },
41
52
  });
42
53
  //# sourceMappingURL=navigate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../src/actions/navigate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,iIAAiI;IACnI,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,qSAAqS,CACtS;QACH,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;KAChE,CAAC;IACF,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAClB,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7B,OAAO,+CAA+C,CAAC;QACzD,CAAC;QACD,MAAM,GAAG,GAA2B,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACpC,IAAI,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACpC,MAAM,aAAa,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACrC,OAAO,iBAAiB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IACnD,CAAC;CACF,CAAC,CAAC","sourcesContent":["/**\n * Navigate the UI to a view.\n *\n * Writes a navigate command to application state which the UI reads and auto-deletes.\n *\n * Usage:\n * pnpm action navigate --view=overview\n * pnpm action navigate --view=dreams\n * pnpm action navigate --view=<custom-dispatch-extension-id>\n * pnpm action navigate --path=/some/route\n *\n * Options:\n * --view View name to navigate to\n * --path URL path to navigate to\n */\n\nimport { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport { writeAppState } from \"@agent-native/core/application-state\";\n\nexport default defineAction({\n description:\n \"Navigate the UI to a specific view or path. Writes a navigate command to application state which the UI reads and auto-deletes.\",\n schema: z.object({\n view: z\n .string()\n .optional()\n .describe(\n \"Named dispatch view to navigate to. Built-in views include chat, overview, apps, metrics, new-app, vault, integrations, messaging, workspace, agents, destinations, identities, approvals, audit, thread-debug, dreams, and team. Generated Dispatch extension tabs can also use their nav item id.\",\n ),\n path: z.string().optional().describe(\"URL path to navigate to\"),\n }),\n http: false,\n run: async (args) => {\n if (!args.view && !args.path) {\n return \"Error: At least --view or --path is required.\";\n }\n const nav: Record<string, string> = {};\n if (args.view) nav.view = args.view;\n if (args.path) nav.path = args.path;\n await writeAppState(\"navigate\", nav);\n return `Navigating to ${args.view || args.path}`;\n },\n});\n"]}
1
+ {"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../src/actions/navigate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,gMAAgM;IAClM,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,qSAAqS,CACtS;QACH,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QAC/D,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,0CAA0C,CAAC;KACxD,CAAC;IACF,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1C,OAAO,4DAA4D,CAAC;QACtE,CAAC;QACD,MAAM,GAAG,GAA2B,EAAE,CAAC;QACvC,iEAAiE;QACjE,IAAI,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;aAC/B,IAAI,QAAQ;YAAE,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC;QACrC,IAAI,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACpC,IAAI,QAAQ;YAAE,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACtC,MAAM,aAAa,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACrC,OAAO,iBAAiB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,eAAe,QAAQ,EAAE,EAAE,CAAC;IAChF,CAAC;CACF,CAAC,CAAC","sourcesContent":["/**\n * Navigate the UI to a view.\n *\n * Writes a navigate command to application state which the UI reads and auto-deletes.\n *\n * Usage:\n * pnpm action navigate --view=overview\n * pnpm action navigate --view=dreams\n * pnpm action navigate --view=<custom-dispatch-extension-id>\n * pnpm action navigate --path=/some/route\n *\n * Options:\n * --view View name to navigate to\n * --path URL path to navigate to\n * --threadId Chat thread ID to open on the chat route\n */\n\nimport { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport { writeAppState } from \"@agent-native/core/application-state\";\n\nexport default defineAction({\n description:\n \"Navigate the UI to a specific view or path. Use threadId to open a specific chat thread on the chat route. Writes a navigate command to application state which the UI reads and auto-deletes.\",\n schema: z.object({\n view: z\n .string()\n .optional()\n .describe(\n \"Named dispatch view to navigate to. Built-in views include chat, overview, apps, metrics, new-app, vault, integrations, messaging, workspace, agents, destinations, identities, approvals, audit, thread-debug, dreams, and team. Generated Dispatch extension tabs can also use their nav item id.\",\n ),\n path: z.string().optional().describe(\"URL path to navigate to\"),\n threadId: z\n .string()\n .optional()\n .describe(\"Chat thread ID to open on the chat route\"),\n }),\n http: false,\n run: async (args) => {\n const threadId = args.threadId?.trim();\n if (!args.view && !args.path && !threadId) {\n return \"Error: At least --view, --path, or --threadId is required.\";\n }\n const nav: Record<string, string> = {};\n // A thread id without an explicit view implies the chat surface.\n if (args.view) nav.view = args.view;\n else if (threadId) nav.view = \"chat\";\n if (args.path) nav.path = args.path;\n if (threadId) nav.threadId = threadId;\n await writeAppState(\"navigate\", nav);\n return `Navigating to ${args.view || args.path || `chat thread ${threadId}`}`;\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"update-vault-secret.d.ts","sourceRoot":"","sources":["../../src/actions/update-vault-secret.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAIA,wBAwCG"}
1
+ {"version":3,"file":"update-vault-secret.d.ts","sourceRoot":"","sources":["../../src/actions/update-vault-secret.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAIA,wBA2CG"}
@@ -35,6 +35,9 @@ export default defineAction({
35
35
  name !== undefined ||
36
36
  provider !== undefined ||
37
37
  description !== undefined, "At least one secret field must be updated"),
38
+ // Carries a secret `value`. Record THAT the secret changed, never the value —
39
+ // keep the audit trail from becoming a second credential store.
40
+ audit: { recordInputs: false },
38
41
  run: async (args) => updateSecret(args.id, args),
39
42
  });
40
43
  //# sourceMappingURL=update-vault-secret.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"update-vault-secret.js","sourceRoot":"","sources":["../../src/actions/update-vault-secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,uGAAuG;IACzG,MAAM,EAAE,CAAC;SACN,MAAM,CAAC;QACN,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC3C,aAAa,EAAE,CAAC;aACb,MAAM,EAAE;aACR,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,kDAAkD,CAAC;QAC/D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAChE,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,sCAAsC,CAAC;QACnD,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,qDAAqD,CAAC;QAClE,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,sBAAsB,CAAC;KACpC,CAAC;SACD,MAAM,CACL,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE,CACxD,aAAa,KAAK,SAAS;QAC3B,KAAK,KAAK,SAAS;QACnB,IAAI,KAAK,SAAS;QAClB,QAAQ,KAAK,SAAS;QACtB,WAAW,KAAK,SAAS,EAC3B,2CAA2C,CAC5C;IACH,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC;CACjD,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport { updateSecret } from \"../server/lib/vault-store.js\";\n\nexport default defineAction({\n description:\n \"Update an existing vault secret's label, credential key, value, provider, or description. Admin only.\",\n schema: z\n .object({\n id: z.string().min(1).describe(\"Secret ID\"),\n credentialKey: z\n .string()\n .trim()\n .min(1)\n .optional()\n .describe(\"Environment variable name, e.g. GOOGLE_CLIENT_ID\"),\n value: z.string().min(1).optional().describe(\"New secret value\"),\n name: z\n .string()\n .trim()\n .min(1)\n .optional()\n .describe(\"Human-readable label for this secret\"),\n provider: z\n .string()\n .nullable()\n .optional()\n .describe(\"Provider grouping tag, e.g. google, sendgrid, slack\"),\n description: z\n .string()\n .nullable()\n .optional()\n .describe(\"Optional description\"),\n })\n .refine(\n ({ credentialKey, value, name, provider, description }) =>\n credentialKey !== undefined ||\n value !== undefined ||\n name !== undefined ||\n provider !== undefined ||\n description !== undefined,\n \"At least one secret field must be updated\",\n ),\n run: async (args) => updateSecret(args.id, args),\n});\n"]}
1
+ {"version":3,"file":"update-vault-secret.js","sourceRoot":"","sources":["../../src/actions/update-vault-secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,uGAAuG;IACzG,MAAM,EAAE,CAAC;SACN,MAAM,CAAC;QACN,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC3C,aAAa,EAAE,CAAC;aACb,MAAM,EAAE;aACR,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,kDAAkD,CAAC;QAC/D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAChE,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,sCAAsC,CAAC;QACnD,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,qDAAqD,CAAC;QAClE,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,sBAAsB,CAAC;KACpC,CAAC;SACD,MAAM,CACL,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE,CACxD,aAAa,KAAK,SAAS;QAC3B,KAAK,KAAK,SAAS;QACnB,IAAI,KAAK,SAAS;QAClB,QAAQ,KAAK,SAAS;QACtB,WAAW,KAAK,SAAS,EAC3B,2CAA2C,CAC5C;IACH,8EAA8E;IAC9E,gEAAgE;IAChE,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE;IAC9B,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC;CACjD,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport { updateSecret } from \"../server/lib/vault-store.js\";\n\nexport default defineAction({\n description:\n \"Update an existing vault secret's label, credential key, value, provider, or description. Admin only.\",\n schema: z\n .object({\n id: z.string().min(1).describe(\"Secret ID\"),\n credentialKey: z\n .string()\n .trim()\n .min(1)\n .optional()\n .describe(\"Environment variable name, e.g. GOOGLE_CLIENT_ID\"),\n value: z.string().min(1).optional().describe(\"New secret value\"),\n name: z\n .string()\n .trim()\n .min(1)\n .optional()\n .describe(\"Human-readable label for this secret\"),\n provider: z\n .string()\n .nullable()\n .optional()\n .describe(\"Provider grouping tag, e.g. google, sendgrid, slack\"),\n description: z\n .string()\n .nullable()\n .optional()\n .describe(\"Optional description\"),\n })\n .refine(\n ({ credentialKey, value, name, provider, description }) =>\n credentialKey !== undefined ||\n value !== undefined ||\n name !== undefined ||\n provider !== undefined ||\n description !== undefined,\n \"At least one secret field must be updated\",\n ),\n // Carries a secret `value`. Record THAT the secret changed, never the value —\n // keep the audit trail from becoming a second credential store.\n audit: { recordInputs: false },\n run: async (args) => updateSecret(args.id, args),\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EAElB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AA6Df,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,YAAY,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC;IAC1C,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,mFAAmF;IACnF,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CACvC;AAED,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,kFAAkF;IAClF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AAwbD,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,UAAU,GACX,EAAE;IACD,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,UAAU,CAAC,EAAE,uBAAuB,CAAC;CACtC,2CA6IA;AAED,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,UAAU,GACX,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,uBAAuB,CAAC;CACtC,2CA2FA"}
1
+ {"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EAElB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AA6Df,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,YAAY,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC;IAC1C,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,mFAAmF;IACnF,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CACvC;AAED,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,kFAAkF;IAClF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AA8cD,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,UAAU,GACX,EAAE;IACD,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,UAAU,CAAC,EAAE,uBAAuB,CAAC;CACtC,2CA6IA;AAED,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,UAAU,GACX,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,uBAAuB,CAAC;CACtC,2CAgGA"}
@@ -190,6 +190,21 @@ function dispatchNavLinkTarget(path) {
190
190
  const routerHasBasename = pathname === basePath || pathname.startsWith(`${basePath}/`);
191
191
  return routerHasBasename ? path : appPath(path);
192
192
  }
193
+ function chatThreadPath(threadId) {
194
+ return `/chat/${encodeURIComponent(threadId)}`;
195
+ }
196
+ function threadIdFromPath(pathname) {
197
+ const match = pathname.match(/^\/chat\/([^/]+)/);
198
+ if (!match)
199
+ return null;
200
+ try {
201
+ const value = decodeURIComponent(match[1]).trim();
202
+ return value || null;
203
+ }
204
+ catch {
205
+ return null;
206
+ }
207
+ }
193
208
  function formatThreadAge(updatedAt) {
194
209
  const diffMs = Math.max(0, Date.now() - updatedAt);
195
210
  const minutes = Math.floor(diffMs / 60_000);
@@ -220,6 +235,7 @@ function threadUpdatedAt(thread) {
220
235
  }
221
236
  function DispatchChatsSection({ onNavigate }) {
222
237
  const navigate = useNavigate();
238
+ const location = useLocation();
223
239
  const { threads, activeThreadId, createThread, switchThread, renameThread, refreshThreads, } = useChatThreads(undefined, "dispatch", undefined, { autoCreate: false });
224
240
  const [renamingThreadId, setRenamingThreadId] = useState(null);
225
241
  const [renameDraft, setRenameDraft] = useState("");
@@ -255,7 +271,7 @@ function DispatchChatsSection({ onNavigate }) {
255
271
  }, [renamingThreadId]);
256
272
  function openThread(threadId, options) {
257
273
  switchThread(threadId);
258
- navigateWithAgentChatViewTransition(navigate, dispatchNavLinkTarget("/chat"));
274
+ navigateWithAgentChatViewTransition(navigate, dispatchNavLinkTarget(options?.isNew ? "/chat" : chatThreadPath(threadId)));
259
275
  onNavigate?.();
260
276
  window.requestAnimationFrame(() => {
261
277
  window.dispatchEvent(new CustomEvent("agent-chat:open-thread", {
@@ -297,7 +313,10 @@ function DispatchChatsSection({ onNavigate }) {
297
313
  void commitRenameThread();
298
314
  }
299
315
  return (_jsxs("div", { className: "mt-2 border-l border-sidebar-border/70 pl-3", children: [_jsxs("div", { className: "mb-1 flex h-7 items-center gap-2 pr-1", children: [_jsx("div", { className: "min-w-0 flex-1 text-xs font-medium text-sidebar-foreground/70", children: "Chats" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: handleNewChat, className: "flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-md text-sidebar-foreground/65 transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground", "aria-label": "New Dispatch chat", children: _jsx(IconPlus, { className: "size-3.5" }) }) }), _jsx(TooltipContent, { children: "New chat" })] })] }), _jsx("div", { className: "grid gap-0.5", children: visibleThreads.length > 0 ? (visibleThreads.map((thread) => {
300
- const isActive = thread.id === activeThreadId;
316
+ const localPathname = localDispatchPath(location.pathname);
317
+ const isActive = thread.id ===
318
+ (threadIdFromPath(localPathname) ??
319
+ (localPathname === "/chat" ? null : activeThreadId));
301
320
  const isRenaming = thread.id === renamingThreadId;
302
321
  return (_jsx("div", { className: cn("group flex h-8 min-w-0 items-center rounded-md text-sm transition-colors", isActive
303
322
  ? "bg-sidebar-accent text-sidebar-accent-foreground"
@@ -360,13 +379,16 @@ export function Layout({ children, extensions, }) {
360
379
  const navigate = useNavigate();
361
380
  const [mobileOpen, setMobileOpen] = useState(false);
362
381
  const localPathname = localDispatchPath(location.pathname);
363
- const isChatRoute = localPathname === "/chat";
382
+ const isChatRoute = localPathname === "/chat" || localPathname.startsWith("/chat/");
364
383
  const chatHomeHandoffActive = useAgentChatHomeHandoff({
365
384
  storageKey: "dispatch",
366
385
  activePath: localPathname,
367
386
  enabled: !isChatRoute,
368
387
  });
369
- useAgentChatHomeHandoffLinks({ storageKey: "dispatch", chatPath: "/chat" });
388
+ useAgentChatHomeHandoffLinks({
389
+ storageKey: "dispatch",
390
+ isChatPath: (pathname) => pathname === "/chat" || pathname.startsWith("/chat/"),
391
+ });
370
392
  if (CHROMELESS_PATHS.some((path) => localPathname === path)) {
371
393
  return _jsx(_Fragment, { children: children });
372
394
  }