@agent-native/dispatch 0.8.9 → 0.8.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/use-navigation-state.d.ts +3 -0
- package/dist/hooks/use-navigation-state.d.ts.map +1 -1
- package/dist/hooks/use-navigation-state.js +50 -18
- package/dist/hooks/use-navigation-state.js.map +1 -1
- package/dist/server/lib/mcp-gateway.d.ts.map +1 -1
- package/dist/server/lib/mcp-gateway.js +6 -1
- package/dist/server/lib/mcp-gateway.js.map +1 -1
- package/package.json +1 -1
- package/src/hooks/use-navigation-state.spec.ts +30 -0
- package/src/hooks/use-navigation-state.ts +59 -14
- package/src/server/lib/mcp-gateway.spec.ts +54 -0
- package/src/server/lib/mcp-gateway.ts +5 -1
|
@@ -2,9 +2,12 @@ import type { DispatchExtensionConfig } from "../components/index.js";
|
|
|
2
2
|
export interface NavigationState {
|
|
3
3
|
view: string;
|
|
4
4
|
path?: string;
|
|
5
|
+
extensionId?: string;
|
|
6
|
+
extensionSlug?: string;
|
|
5
7
|
dreamId?: string;
|
|
6
8
|
sourceId?: string;
|
|
7
9
|
query?: string;
|
|
8
10
|
}
|
|
9
11
|
export declare function useNavigationState(extensions?: DispatchExtensionConfig): void;
|
|
12
|
+
export declare function buildDispatchNavigationState(pathname: string, search?: string, extensions?: DispatchExtensionConfig): NavigationState;
|
|
10
13
|
//# sourceMappingURL=use-navigation-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-navigation-state.d.ts","sourceRoot":"","sources":["../../src/hooks/use-navigation-state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-navigation-state.d.ts","sourceRoot":"","sources":["../../src/hooks/use-navigation-state.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,uBAAuB,EAExB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAAC,UAAU,CAAC,EAAE,uBAAuB,QA6DtE;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,MAAM,SAAK,EACX,UAAU,CAAC,EAAE,uBAAuB,GACnC,eAAe,CA0BjB"}
|
|
@@ -2,6 +2,7 @@ import { useEffect } from "react";
|
|
|
2
2
|
import { useLocation, useNavigate } from "react-router";
|
|
3
3
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
4
4
|
import { agentNativePath, appBasePath, appPath, } from "@agent-native/core/client";
|
|
5
|
+
import { extensionIdFromPathname } from "@agent-native/core/client/extensions";
|
|
5
6
|
export function useNavigationState(extensions) {
|
|
6
7
|
const location = useLocation();
|
|
7
8
|
const navigate = useNavigate();
|
|
@@ -9,22 +10,7 @@ export function useNavigationState(extensions) {
|
|
|
9
10
|
// Sync current route to application state
|
|
10
11
|
useEffect(() => {
|
|
11
12
|
const localPathname = routerPath(location.pathname);
|
|
12
|
-
const
|
|
13
|
-
const state = {
|
|
14
|
-
view: resolveView(localPathname, extensions),
|
|
15
|
-
path: appPath(localPathname),
|
|
16
|
-
};
|
|
17
|
-
if (state.view === "dreams") {
|
|
18
|
-
const dreamId = params.get("dreamId");
|
|
19
|
-
const sourceId = params.get("sourceId");
|
|
20
|
-
const query = params.get("query");
|
|
21
|
-
if (dreamId)
|
|
22
|
-
state.dreamId = dreamId;
|
|
23
|
-
if (sourceId)
|
|
24
|
-
state.sourceId = sourceId;
|
|
25
|
-
if (query)
|
|
26
|
-
state.query = query;
|
|
27
|
-
}
|
|
13
|
+
const state = buildDispatchNavigationState(localPathname, location.search, extensions);
|
|
28
14
|
fetch(agentNativePath("/_agent-native/application-state/navigation"), {
|
|
29
15
|
method: "PUT",
|
|
30
16
|
keepalive: true,
|
|
@@ -59,7 +45,7 @@ export function useNavigationState(extensions) {
|
|
|
59
45
|
}).catch(() => { });
|
|
60
46
|
const cmd = navCommand;
|
|
61
47
|
// Navigate to a specific path or resolve view name to path
|
|
62
|
-
const resolvedPath = cmd.path || resolvePath(cmd.view, extensions) || "/overview";
|
|
48
|
+
const resolvedPath = cmd.path || resolvePath(cmd.view, extensions, cmd) || "/overview";
|
|
63
49
|
const path = cmd.view === "dreams" && cmd.dreamId && !resolvedPath.includes("?")
|
|
64
50
|
? `${resolvedPath}?dreamId=${encodeURIComponent(cmd.dreamId)}`
|
|
65
51
|
: resolvedPath;
|
|
@@ -68,6 +54,34 @@ export function useNavigationState(extensions) {
|
|
|
68
54
|
qc.setQueryData(["navigate-command"], null);
|
|
69
55
|
}, [extensions, navCommand, navigate, qc]);
|
|
70
56
|
}
|
|
57
|
+
export function buildDispatchNavigationState(pathname, search = "", extensions) {
|
|
58
|
+
const state = {
|
|
59
|
+
view: resolveView(pathname, extensions),
|
|
60
|
+
path: appPath(pathname),
|
|
61
|
+
};
|
|
62
|
+
const extensionId = extensionIdFromPathname(pathname);
|
|
63
|
+
if (extensionId) {
|
|
64
|
+
state.view = "extensions";
|
|
65
|
+
state.extensionId = extensionId;
|
|
66
|
+
const slug = extensionSlugFromPathname(pathname);
|
|
67
|
+
if (slug)
|
|
68
|
+
state.extensionSlug = slug;
|
|
69
|
+
return state;
|
|
70
|
+
}
|
|
71
|
+
if (state.view === "dreams") {
|
|
72
|
+
const params = new URLSearchParams(search);
|
|
73
|
+
const dreamId = params.get("dreamId");
|
|
74
|
+
const sourceId = params.get("sourceId");
|
|
75
|
+
const query = params.get("query");
|
|
76
|
+
if (dreamId)
|
|
77
|
+
state.dreamId = dreamId;
|
|
78
|
+
if (sourceId)
|
|
79
|
+
state.sourceId = sourceId;
|
|
80
|
+
if (query)
|
|
81
|
+
state.query = query;
|
|
82
|
+
}
|
|
83
|
+
return state;
|
|
84
|
+
}
|
|
71
85
|
function routerPath(path) {
|
|
72
86
|
const basePath = appBasePath();
|
|
73
87
|
if (!basePath)
|
|
@@ -110,6 +124,9 @@ function resolveView(pathname, extensions) {
|
|
|
110
124
|
const extensionView = resolveExtensionView(pathname, extensions);
|
|
111
125
|
if (extensionView)
|
|
112
126
|
return extensionView;
|
|
127
|
+
if (pathname === "/extensions" || pathname.startsWith("/extensions/")) {
|
|
128
|
+
return "extensions";
|
|
129
|
+
}
|
|
113
130
|
if (pathname.startsWith("/apps"))
|
|
114
131
|
return "apps";
|
|
115
132
|
if (pathname.startsWith("/metrics"))
|
|
@@ -142,7 +159,7 @@ function resolveView(pathname, extensions) {
|
|
|
142
159
|
return "team";
|
|
143
160
|
return "overview";
|
|
144
161
|
}
|
|
145
|
-
function resolvePath(view, extensions) {
|
|
162
|
+
function resolvePath(view, extensions, command) {
|
|
146
163
|
switch (view) {
|
|
147
164
|
case "overview":
|
|
148
165
|
return "/overview";
|
|
@@ -182,8 +199,23 @@ function resolvePath(view, extensions) {
|
|
|
182
199
|
return "/thread-debug";
|
|
183
200
|
case "team":
|
|
184
201
|
return "/team";
|
|
202
|
+
case "extensions":
|
|
203
|
+
return command?.extensionId
|
|
204
|
+
? `/extensions/${encodeURIComponent(command.extensionId)}`
|
|
205
|
+
: "/extensions";
|
|
185
206
|
default:
|
|
186
207
|
return resolveExtensionPath(view, extensions);
|
|
187
208
|
}
|
|
188
209
|
}
|
|
210
|
+
function extensionSlugFromPathname(pathname) {
|
|
211
|
+
const match = pathname.match(/^\/extensions\/[^/]+\/([^/?#]+)/);
|
|
212
|
+
if (!match?.[1])
|
|
213
|
+
return undefined;
|
|
214
|
+
try {
|
|
215
|
+
return decodeURIComponent(match[1]);
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return match[1];
|
|
219
|
+
}
|
|
220
|
+
}
|
|
189
221
|
//# sourceMappingURL=use-navigation-state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-navigation-state.js","sourceRoot":"","sources":["../../src/hooks/use-navigation-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEffect } from \"react\";\nimport { useLocation, useNavigate } from \"react-router\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport {\n agentNativePath,\n appBasePath,\n appPath,\n} from \"@agent-native/core/client\";\nimport type {\n DispatchExtensionConfig,\n DispatchNavItem,\n} from \"../components/index.js\";\n\nexport interface NavigationState {\n view: string;\n path?: string;\n dreamId?: string;\n sourceId?: string;\n query?: string;\n}\n\nexport function useNavigationState(extensions?: DispatchExtensionConfig) {\n const location = useLocation();\n const navigate = useNavigate();\n const qc = useQueryClient();\n\n // Sync current route to application state\n useEffect(() => {\n const localPathname = routerPath(location.pathname);\n const params = new URLSearchParams(location.search);\n const state: NavigationState = {\n view: resolveView(localPathname, extensions),\n path: appPath(localPathname),\n };\n if (state.view === \"dreams\") {\n const dreamId = params.get(\"dreamId\");\n const sourceId = params.get(\"sourceId\");\n const query = params.get(\"query\");\n if (dreamId) state.dreamId = dreamId;\n if (sourceId) state.sourceId = sourceId;\n if (query) state.query = query;\n }\n\n fetch(agentNativePath(\"/_agent-native/application-state/navigation\"), {\n method: \"PUT\",\n keepalive: true,\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(state),\n }).catch(() => {});\n }, [extensions, location.pathname, location.search]);\n\n // Listen for navigate commands from agent\n const { data: navCommand } = useQuery({\n queryKey: [\"navigate-command\"],\n queryFn: async () => {\n const res = await fetch(\n agentNativePath(\"/_agent-native/application-state/navigate\"),\n );\n if (!res.ok) return null;\n const data = await res.json();\n if (data) {\n // Return with a timestamp to ensure uniqueness\n return { ...data, _ts: Date.now() };\n }\n return null;\n },\n refetchInterval: 2_000,\n structuralSharing: false,\n });\n\n useEffect(() => {\n if (!navCommand) return;\n // Delete the one-shot command AFTER reading it\n fetch(agentNativePath(\"/_agent-native/application-state/navigate\"), {\n method: \"DELETE\",\n headers: { \"X-Agent-Native-CSRF\": \"1\" },\n }).catch(() => {});\n const cmd = navCommand as NavigationState;\n\n // Navigate to a specific path or resolve view name to path\n const resolvedPath =\n cmd.path || resolvePath(cmd.view, extensions) || \"/overview\";\n const path =\n cmd.view === \"dreams\" && cmd.dreamId && !resolvedPath.includes(\"?\")\n ? `${resolvedPath}?dreamId=${encodeURIComponent(cmd.dreamId)}`\n : resolvedPath;\n const nextPath = routerPath(path);\n navigate(nextPath);\n qc.setQueryData([\"navigate-command\"], null);\n }, [extensions, navCommand, navigate, qc]);\n}\n\nfunction routerPath(path: string): string {\n const basePath = appBasePath();\n if (!basePath) return path;\n let result = path;\n // Iteratively strip basename. A path that arrives doubly-prefixed\n // (e.g. \"/dispatch/dispatch/overview\", possibly from a stale link or a\n // prior bug) would otherwise get partially stripped here and then\n // re-prefixed by react-router's basename, restoring the bad URL.\n for (let i = 0; i < 4; i += 1) {\n if (result === basePath) return \"/\";\n if (!result.startsWith(`${basePath}/`)) break;\n result = result.slice(basePath.length) || \"/\";\n }\n return result;\n}\n\nfunction extensionItemMatchesPath(\n item: DispatchNavItem,\n pathname: string,\n): boolean {\n if (item.match) {\n try {\n if (item.match(pathname)) return true;\n } catch {\n return false;\n }\n }\n return pathname === item.to || pathname.startsWith(`${item.to}/`);\n}\n\nfunction resolveExtensionView(\n pathname: string,\n extensions?: DispatchExtensionConfig,\n): string | undefined {\n return extensions?.navItems?.find((item) =>\n extensionItemMatchesPath(item, pathname),\n )?.id;\n}\n\nfunction resolveExtensionPath(\n view: string | undefined,\n extensions?: DispatchExtensionConfig,\n): string | undefined {\n if (!view) return undefined;\n return extensions?.navItems?.find((item) => item.id === view)?.to;\n}\n\nfunction resolveView(\n pathname: string,\n extensions?: DispatchExtensionConfig,\n): string {\n const extensionView = resolveExtensionView(pathname, extensions);\n if (extensionView) return extensionView;\n if (pathname.startsWith(\"/apps\")) return \"apps\";\n if (pathname.startsWith(\"/metrics\")) return \"metrics\";\n if (pathname.startsWith(\"/new-app\")) return \"new-app\";\n if (pathname.startsWith(\"/vault\")) return \"vault\";\n if (pathname.startsWith(\"/integrations\")) return \"integrations\";\n if (pathname.startsWith(\"/workspace\")) return \"workspace\";\n if (pathname.startsWith(\"/agents\")) return \"agents\";\n if (pathname.startsWith(\"/messaging\")) return \"messaging\";\n if (pathname.startsWith(\"/destinations\")) return \"destinations\";\n if (pathname.startsWith(\"/identities\")) return \"identities\";\n if (pathname.startsWith(\"/approvals\")) return \"approvals\";\n if (pathname.startsWith(\"/audit\")) return \"audit\";\n if (pathname.startsWith(\"/dreams\")) return \"dreams\";\n if (pathname.startsWith(\"/thread-debug\")) return \"thread-debug\";\n if (pathname.startsWith(\"/team\")) return \"team\";\n return \"overview\";\n}\n\nfunction resolvePath(\n view?: string,\n extensions?: DispatchExtensionConfig,\n): string | undefined {\n switch (view) {\n case \"overview\":\n return \"/overview\";\n case \"apps\":\n return \"/apps\";\n case \"metrics\":\n case \"usage\":\n return \"/metrics\";\n case \"new-app\":\n case \"create-app\":\n return \"/new-app\";\n case \"vault\":\n case \"secrets\":\n return \"/vault\";\n case \"integrations\":\n return \"/integrations\";\n case \"workspace\":\n case \"resources\":\n return \"/workspace\";\n case \"agents\":\n return \"/agents\";\n case \"messaging\":\n return \"/messaging\";\n case \"destinations\":\n case \"routes\":\n return \"/destinations\";\n case \"identities\":\n return \"/identities\";\n case \"approvals\":\n return \"/approvals\";\n case \"audit\":\n return \"/audit\";\n case \"dreams\":\n return \"/dreams\";\n case \"thread-debug\":\n case \"threads\":\n return \"/thread-debug\";\n case \"team\":\n return \"/team\";\n default:\n return resolveExtensionPath(view, extensions);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-navigation-state.js","sourceRoot":"","sources":["../../src/hooks/use-navigation-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EACL,eAAe,EACf,WAAW,EACX,OAAO,GACR,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAgB/E,MAAM,UAAU,kBAAkB,CAAC,UAAoC;IACrE,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAE5B,0CAA0C;IAC1C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,aAAa,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,4BAA4B,CACxC,aAAa,EACb,QAAQ,CAAC,MAAM,EACf,UAAU,CACX,CAAC;QAEF,KAAK,CAAC,eAAe,CAAC,6CAA6C,CAAC,EAAE;YACpE,MAAM,EAAE,KAAK;YACb,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SAC5B,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACrB,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAErD,0CAA0C;IAC1C,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;QACpC,QAAQ,EAAE,CAAC,kBAAkB,CAAC;QAC9B,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,eAAe,CAAC,2CAA2C,CAAC,CAC7D,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,IAAI,IAAI,EAAE,CAAC;gBACT,+CAA+C;gBAC/C,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACtC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,eAAe,EAAE,KAAK;QACtB,iBAAiB,EAAE,KAAK;KACzB,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,+CAA+C;QAC/C,KAAK,CAAC,eAAe,CAAC,2CAA2C,CAAC,EAAE;YAClE,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,EAAE,qBAAqB,EAAE,GAAG,EAAE;SACxC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACnB,MAAM,GAAG,GAAG,UAA6B,CAAC;QAE1C,2DAA2D;QAC3D,MAAM,YAAY,GAChB,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,WAAW,CAAC;QACpE,MAAM,IAAI,GACR,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC;YACjE,CAAC,CAAC,GAAG,YAAY,YAAY,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAC9D,CAAC,CAAC,YAAY,CAAC;QACnB,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAClC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnB,EAAE,CAAC,YAAY,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,QAAgB,EAChB,MAAM,GAAG,EAAE,EACX,UAAoC;IAEpC,MAAM,KAAK,GAAoB;QAC7B,IAAI,EAAE,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC;QACvC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC;KACxB,CAAC;IAEF,MAAM,WAAW,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC;QAC1B,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;QAChC,MAAM,IAAI,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,IAAI;YAAE,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,OAAO;YAAE,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;QACrC,IAAI,QAAQ;YAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxC,IAAI,KAAK;YAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IACjC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,kEAAkE;IAClE,uEAAuE;IACvE,kEAAkE;IAClE,iEAAiE;IACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,IAAI,MAAM,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC;YAAE,MAAM;QAC9C,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,wBAAwB,CAC/B,IAAqB,EACrB,QAAgB;IAEhB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;gBAAE,OAAO,IAAI,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,KAAK,IAAI,CAAC,EAAE,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,oBAAoB,CAC3B,QAAgB,EAChB,UAAoC;IAEpC,OAAO,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACzC,wBAAwB,CAAC,IAAI,EAAE,QAAQ,CAAC,CACzC,EAAE,EAAE,CAAC;AACR,CAAC;AAED,SAAS,oBAAoB,CAC3B,IAAwB,EACxB,UAAoC;IAEpC,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;AACpE,CAAC;AAED,SAAS,WAAW,CAClB,QAAgB,EAChB,UAAoC;IAEpC,MAAM,aAAa,GAAG,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACjE,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IACxC,IAAI,QAAQ,KAAK,aAAa,IAAI,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACtE,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IACtD,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IACtD,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAC;IAClD,IAAI,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,cAAc,CAAC;IAChE,IAAI,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,WAAW,CAAC;IAC1D,IAAI,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,QAAQ,CAAC;IACpD,IAAI,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,WAAW,CAAC;IAC1D,IAAI,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,cAAc,CAAC;IAChE,IAAI,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,YAAY,CAAC;IAC5D,IAAI,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,WAAW,CAAC;IAC1D,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAC;IAClD,IAAI,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,QAAQ,CAAC;IACpD,IAAI,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,cAAc,CAAC;IAChE,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,WAAW,CAClB,IAAa,EACb,UAAoC,EACpC,OAA8C;IAE9C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,UAAU;YACb,OAAO,WAAW,CAAC;QACrB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC;QACjB,KAAK,SAAS,CAAC;QACf,KAAK,OAAO;YACV,OAAO,UAAU,CAAC;QACpB,KAAK,SAAS,CAAC;QACf,KAAK,YAAY;YACf,OAAO,UAAU,CAAC;QACpB,KAAK,OAAO,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,QAAQ,CAAC;QAClB,KAAK,cAAc;YACjB,OAAO,eAAe,CAAC;QACzB,KAAK,WAAW,CAAC;QACjB,KAAK,WAAW;YACd,OAAO,YAAY,CAAC;QACtB,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,YAAY,CAAC;QACtB,KAAK,cAAc,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,eAAe,CAAC;QACzB,KAAK,YAAY;YACf,OAAO,aAAa,CAAC;QACvB,KAAK,WAAW;YACd,OAAO,YAAY,CAAC;QACtB,KAAK,OAAO;YACV,OAAO,QAAQ,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC;QACnB,KAAK,cAAc,CAAC;QACpB,KAAK,SAAS;YACZ,OAAO,eAAe,CAAC;QACzB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC;QACjB,KAAK,YAAY;YACf,OAAO,OAAO,EAAE,WAAW;gBACzB,CAAC,CAAC,eAAe,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;gBAC1D,CAAC,CAAC,aAAa,CAAC;QACpB;YACE,OAAO,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,SAAS,yBAAyB,CAAC,QAAgB;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAChE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAClC,IAAI,CAAC;QACH,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC","sourcesContent":["import { useEffect } from \"react\";\nimport { useLocation, useNavigate } from \"react-router\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport {\n agentNativePath,\n appBasePath,\n appPath,\n} from \"@agent-native/core/client\";\nimport { extensionIdFromPathname } from \"@agent-native/core/client/extensions\";\nimport type {\n DispatchExtensionConfig,\n DispatchNavItem,\n} from \"../components/index.js\";\n\nexport interface NavigationState {\n view: string;\n path?: string;\n extensionId?: string;\n extensionSlug?: string;\n dreamId?: string;\n sourceId?: string;\n query?: string;\n}\n\nexport function useNavigationState(extensions?: DispatchExtensionConfig) {\n const location = useLocation();\n const navigate = useNavigate();\n const qc = useQueryClient();\n\n // Sync current route to application state\n useEffect(() => {\n const localPathname = routerPath(location.pathname);\n const state = buildDispatchNavigationState(\n localPathname,\n location.search,\n extensions,\n );\n\n fetch(agentNativePath(\"/_agent-native/application-state/navigation\"), {\n method: \"PUT\",\n keepalive: true,\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(state),\n }).catch(() => {});\n }, [extensions, location.pathname, location.search]);\n\n // Listen for navigate commands from agent\n const { data: navCommand } = useQuery({\n queryKey: [\"navigate-command\"],\n queryFn: async () => {\n const res = await fetch(\n agentNativePath(\"/_agent-native/application-state/navigate\"),\n );\n if (!res.ok) return null;\n const data = await res.json();\n if (data) {\n // Return with a timestamp to ensure uniqueness\n return { ...data, _ts: Date.now() };\n }\n return null;\n },\n refetchInterval: 2_000,\n structuralSharing: false,\n });\n\n useEffect(() => {\n if (!navCommand) return;\n // Delete the one-shot command AFTER reading it\n fetch(agentNativePath(\"/_agent-native/application-state/navigate\"), {\n method: \"DELETE\",\n headers: { \"X-Agent-Native-CSRF\": \"1\" },\n }).catch(() => {});\n const cmd = navCommand as NavigationState;\n\n // Navigate to a specific path or resolve view name to path\n const resolvedPath =\n cmd.path || resolvePath(cmd.view, extensions, cmd) || \"/overview\";\n const path =\n cmd.view === \"dreams\" && cmd.dreamId && !resolvedPath.includes(\"?\")\n ? `${resolvedPath}?dreamId=${encodeURIComponent(cmd.dreamId)}`\n : resolvedPath;\n const nextPath = routerPath(path);\n navigate(nextPath);\n qc.setQueryData([\"navigate-command\"], null);\n }, [extensions, navCommand, navigate, qc]);\n}\n\nexport function buildDispatchNavigationState(\n pathname: string,\n search = \"\",\n extensions?: DispatchExtensionConfig,\n): NavigationState {\n const state: NavigationState = {\n view: resolveView(pathname, extensions),\n path: appPath(pathname),\n };\n\n const extensionId = extensionIdFromPathname(pathname);\n if (extensionId) {\n state.view = \"extensions\";\n state.extensionId = extensionId;\n const slug = extensionSlugFromPathname(pathname);\n if (slug) state.extensionSlug = slug;\n return state;\n }\n\n if (state.view === \"dreams\") {\n const params = new URLSearchParams(search);\n const dreamId = params.get(\"dreamId\");\n const sourceId = params.get(\"sourceId\");\n const query = params.get(\"query\");\n if (dreamId) state.dreamId = dreamId;\n if (sourceId) state.sourceId = sourceId;\n if (query) state.query = query;\n }\n\n return state;\n}\n\nfunction routerPath(path: string): string {\n const basePath = appBasePath();\n if (!basePath) return path;\n let result = path;\n // Iteratively strip basename. A path that arrives doubly-prefixed\n // (e.g. \"/dispatch/dispatch/overview\", possibly from a stale link or a\n // prior bug) would otherwise get partially stripped here and then\n // re-prefixed by react-router's basename, restoring the bad URL.\n for (let i = 0; i < 4; i += 1) {\n if (result === basePath) return \"/\";\n if (!result.startsWith(`${basePath}/`)) break;\n result = result.slice(basePath.length) || \"/\";\n }\n return result;\n}\n\nfunction extensionItemMatchesPath(\n item: DispatchNavItem,\n pathname: string,\n): boolean {\n if (item.match) {\n try {\n if (item.match(pathname)) return true;\n } catch {\n return false;\n }\n }\n return pathname === item.to || pathname.startsWith(`${item.to}/`);\n}\n\nfunction resolveExtensionView(\n pathname: string,\n extensions?: DispatchExtensionConfig,\n): string | undefined {\n return extensions?.navItems?.find((item) =>\n extensionItemMatchesPath(item, pathname),\n )?.id;\n}\n\nfunction resolveExtensionPath(\n view: string | undefined,\n extensions?: DispatchExtensionConfig,\n): string | undefined {\n if (!view) return undefined;\n return extensions?.navItems?.find((item) => item.id === view)?.to;\n}\n\nfunction resolveView(\n pathname: string,\n extensions?: DispatchExtensionConfig,\n): string {\n const extensionView = resolveExtensionView(pathname, extensions);\n if (extensionView) return extensionView;\n if (pathname === \"/extensions\" || pathname.startsWith(\"/extensions/\")) {\n return \"extensions\";\n }\n if (pathname.startsWith(\"/apps\")) return \"apps\";\n if (pathname.startsWith(\"/metrics\")) return \"metrics\";\n if (pathname.startsWith(\"/new-app\")) return \"new-app\";\n if (pathname.startsWith(\"/vault\")) return \"vault\";\n if (pathname.startsWith(\"/integrations\")) return \"integrations\";\n if (pathname.startsWith(\"/workspace\")) return \"workspace\";\n if (pathname.startsWith(\"/agents\")) return \"agents\";\n if (pathname.startsWith(\"/messaging\")) return \"messaging\";\n if (pathname.startsWith(\"/destinations\")) return \"destinations\";\n if (pathname.startsWith(\"/identities\")) return \"identities\";\n if (pathname.startsWith(\"/approvals\")) return \"approvals\";\n if (pathname.startsWith(\"/audit\")) return \"audit\";\n if (pathname.startsWith(\"/dreams\")) return \"dreams\";\n if (pathname.startsWith(\"/thread-debug\")) return \"thread-debug\";\n if (pathname.startsWith(\"/team\")) return \"team\";\n return \"overview\";\n}\n\nfunction resolvePath(\n view?: string,\n extensions?: DispatchExtensionConfig,\n command?: Pick<NavigationState, \"extensionId\">,\n): string | undefined {\n switch (view) {\n case \"overview\":\n return \"/overview\";\n case \"apps\":\n return \"/apps\";\n case \"metrics\":\n case \"usage\":\n return \"/metrics\";\n case \"new-app\":\n case \"create-app\":\n return \"/new-app\";\n case \"vault\":\n case \"secrets\":\n return \"/vault\";\n case \"integrations\":\n return \"/integrations\";\n case \"workspace\":\n case \"resources\":\n return \"/workspace\";\n case \"agents\":\n return \"/agents\";\n case \"messaging\":\n return \"/messaging\";\n case \"destinations\":\n case \"routes\":\n return \"/destinations\";\n case \"identities\":\n return \"/identities\";\n case \"approvals\":\n return \"/approvals\";\n case \"audit\":\n return \"/audit\";\n case \"dreams\":\n return \"/dreams\";\n case \"thread-debug\":\n case \"threads\":\n return \"/thread-debug\";\n case \"team\":\n return \"/team\";\n case \"extensions\":\n return command?.extensionId\n ? `/extensions/${encodeURIComponent(command.extensionId)}`\n : \"/extensions\";\n default:\n return resolveExtensionPath(view, extensions);\n }\n}\n\nfunction extensionSlugFromPathname(pathname: string): string | undefined {\n const match = pathname.match(/^\\/extensions\\/[^/]+\\/([^/?#]+)/);\n if (!match?.[1]) return undefined;\n try {\n return decodeURIComponent(match[1]);\n } catch {\n return match[1];\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-gateway.d.ts","sourceRoot":"","sources":["../../../src/server/lib/mcp-gateway.ts"],"names":[],"mappings":"AAoBA,OAAO,EAGL,KAAK,4BAA4B,EAClC,MAAM,uBAAuB,CAAC;AAQ/B,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AA6KD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC;IACnD,QAAQ,EAAE,4BAA4B,CAAC;IACvC,IAAI,EAAE,wBAAwB,EAAE,CAAC;CAClC,CAAC,CAcD;AAED,wBAAsB,0BAA0B,IAAI,OAAO,CACzD,wBAAwB,EAAE,CAC3B,CAGA;AAED,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,wBAAwB,CAAC,CAmBnC;AAED,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB9D;AAED,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACrD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,OAAO,CAAC;IACV,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC,CAyBD;
|
|
1
|
+
{"version":3,"file":"mcp-gateway.d.ts","sourceRoot":"","sources":["../../../src/server/lib/mcp-gateway.ts"],"names":[],"mappings":"AAoBA,OAAO,EAGL,KAAK,4BAA4B,EAClC,MAAM,uBAAuB,CAAC;AAQ/B,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AA6KD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC;IACnD,QAAQ,EAAE,4BAA4B,CAAC;IACvC,IAAI,EAAE,wBAAwB,EAAE,CAAC;CAClC,CAAC,CAcD;AAED,wBAAsB,0BAA0B,IAAI,OAAO,CACzD,wBAAwB,EAAE,CAC3B,CAGA;AAED,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,wBAAwB,CAAC,CAmBnC;AAED,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB9D;AAED,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACrD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,OAAO,CAAC;IACV,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC,CAyBD;AAsGD,wBAAsB,oCAAoC,CAAC,KAAK,EAAE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,OAAO,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC,CAgFD"}
|
|
@@ -259,6 +259,8 @@ function parseMcpToolTextResult(result) {
|
|
|
259
259
|
: [];
|
|
260
260
|
const text = parts.find((part) => part?.type === "text" && typeof part.text === "string")?.text;
|
|
261
261
|
if (typeof text === "string" && text.trim()) {
|
|
262
|
+
if (result.isError)
|
|
263
|
+
throw new Error(text.trim());
|
|
262
264
|
const parsed = JSON.parse(text);
|
|
263
265
|
if (parsed && typeof parsed === "object")
|
|
264
266
|
return parsed;
|
|
@@ -352,7 +354,10 @@ export async function createGrantedDispatchMcpEmbedSession(input) {
|
|
|
352
354
|
: [null, null];
|
|
353
355
|
const token = await signA2AToken(userEmail, orgDomain ?? undefined, orgSecret ?? undefined, {
|
|
354
356
|
expiresIn: "5m",
|
|
355
|
-
|
|
357
|
+
// Target MCP endpoints verify A2A JWTs with the deployment-wide
|
|
358
|
+
// A2A_SECRET. Prefer it for hosted cross-app embeds even when Dispatch
|
|
359
|
+
// also has an org-level secret available.
|
|
360
|
+
preferGlobalSecret: true,
|
|
356
361
|
});
|
|
357
362
|
const serverId = "target";
|
|
358
363
|
const manager = new McpClientManager({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-gateway.js","sourceRoot":"","sources":["../../../src/server/lib/mcp-gateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,cAAc,GAEf,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,eAAe,EACf,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EACL,+BAA+B,EAC/B,uBAAuB,GAExB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,eAAe,GAAG,UAAU,CAAC;AACnC,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAC9C,MAAM,oBAAoB,GACxB,kGAAkG,CAAC;AACrG,MAAM,cAAc,GAAG,SAAS,CAAC;AAWjC,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AACpC,CAAC;AAED,SAAS,gBAAgB,CAAC,GAA8B;IACtD,MAAM,KAAK,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACvE,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAyB;IAClD,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC;IAC3C,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACnE,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAe;IAC7C,MAAM,QAAQ,GAAG,iBAAiB,CAChC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAC5D,CAAC;IACF,IAAI,CAAC,QAAQ;QAAE,OAAO,OAAO,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC;YACzD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,GAAG,CAAC,QAAQ,GAAG,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC;QAC5E,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,aAAa,GAAG,gBAAgB,CAAC,iBAAiB,EAAE,EAAE,aAAa,CAAC,CAAC;IAC3E,IAAI,aAAa;QAAE,OAAO,sBAAsB,CAAC,aAAa,CAAC,CAAC;IAEhE,MAAM,UAAU,GACd,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QACnD,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QACrC,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;QACjC,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QACxC,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAChD,IAAI,UAAU;QAAE,OAAO,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAE1D,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;QAC1C,CAAC,CAAC,mCAAmC;QACrC,CAAC,CAAC,uBAAuB,CAAC;AAC9B,CAAC;AAED,SAAS,eAAe,CACtB,QAAsC;IAEtC,OAAO;QACL,EAAE,EAAE,eAAe;QACnB,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,oBAAoB;QACjC,GAAG,EAAE,mBAAmB,EAAE;QAC1B,KAAK,EAAE,cAAc;QACrB,OAAO,EAAE,uBAAuB,CAAC,eAAe,EAAE,QAAQ,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAE7D,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IACxD,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACzB,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnE,IAAI,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;IACnD,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,6BAA6B,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC7C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB,CACzB,IAAY,EACZ,MAA6D;IAE7D,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,6BAA6B,CAAC,CAAC;IACzD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;AACnD,CAAC;AAED,SAAS,SAAS,CAAC,GAA6B;IAC9C,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;AACjC,CAAC;AAED,SAAS,UAAU,CAAC,GAA6B;IAC/C,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,GAA6B;IAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACvE,OAAO,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC1C,CAAC;AAED,SAAS,iBAAiB,CAAC,GAA6B,EAAE,GAAQ;IAChE,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAChD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,kBAAkB,CAAC,GAA6B;IACvD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;AACjC,CAAC;AAED,SAAS,eAAe,CAAC,GAA6B,EAAE,GAAQ;IAC9D,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,QAAQ;QACnB,CAAC,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ;YACzB,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QACvC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;IACjB,OAAO,GAAG,IAAI,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;AAClD,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAmB;IAChD,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAC/C,OAAO,CACL,KAAK,KAAK,aAAa;QACvB,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC;QAChC,KAAK,KAAK,QAAQ;QAClB,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,GAA6B,EAAE,IAAY;IACvE,IAAI,GAAG,CAAC,EAAE,KAAK,eAAe,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CACb,SAAS,IAAI,oFAAoF,CAClG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CACtB,KAAsB,EACtB,QAAsC;IAEtC,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,uBAAuB,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC;KACrD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB;IAIvC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC3C,+BAA+B,EAAE;QACjC,cAAc,CAAC,UAAU,CAAC;KAC3B,CAAC,CAAC;IACH,OAAO;QACL,QAAQ;QACR,IAAI,EAAE;YACJ,eAAe,CAAC,QAAQ,CAAC;YACzB,GAAG,MAAM;iBACN,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,eAAe,CAAC;iBAC/D,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;SACpD;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B;IAG9C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC7C,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,GAAW;IAEX,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAChD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CACrB,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,EAAE,KAAK,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CACrE,CAAC;IACF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,gBAAgB,GAAG,+DAA+D,CACnF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,2BAA2B,KAAK,CAAC,EAAE,oEAAoE,CACxG,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,GAAW,EACX,OAAe;IAEf,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,CAAC,cAAc;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC,GAAG,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,mBAAmB,EAAE,CAAC;IACxC,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAEzD,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,KAAK;QAClC,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;YACrC,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;SACzC,CAAC;QACJ,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAEjB,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE;QAC3D,SAAS;QACT,SAAS,EAAE,SAAS,IAAI,SAAS;QACjC,SAAS,EAAE,SAAS,IAAI,SAAS;QACjC,SAAS,EAAE,CAAC,GAAG,MAAM;KACtB,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,KAO/C;IAQC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACtC,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC;IACxC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7D,IAAI,IAAI;QAAE,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI;QACjB,CAAC,CAAC,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;QACxC,CAAC,CAAC,aAAa,CAAC;YACZ,GAAG,EAAE,MAAM,CAAC,EAAE;YACd,IAAI;YACJ,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC;IACP,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,EAAE;QACd,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,GAAG,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;QACrC,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClD,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAe;IAC7C,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACzC,MAAM,UAAU,GAAI,MAAc,CAAC,iBAAiB,CAAC;QACrD,IAAI,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ;YAAE,OAAO,UAAU,CAAC;QACpE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAE,MAAc,CAAC,OAAO,CAAC;YAClD,CAAC,CAAG,MAAc,CAAC,OAA0C;YAC7D,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CACrB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CACjE,EAAE,IAAI,CAAC;QACR,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;gBAAE,OAAO,MAAM,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;AACjE,CAAC;AAED,KAAK,UAAU,0BAA0B,CAAC,KAIzC;IACC,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;QACnC,CAAC,CAAC,MAAM,4BAA4B,CAAC,KAAK,CAAC,GAAG,CAAC;QAC/C,CAAC,CAAC,IAAI,CAAC;IACT,IAAI,WAAW,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACrE,oBAAoB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACxC,OAAO;YACL,GAAG,EAAE,WAAW;YAChB,IAAI;YACJ,GAAG,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,IAAI,EAAE;SACzC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC5D,OAAO;YACL,GAAG,EAAE,WAAW;YAChB,IAAI;YACJ,GAAG,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,IAAI,EAAE;SACzC,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,0BAA0B,EAAE,CAAC;IAC9E,MAAM,MAAM,GAAG,IAAI;SAChB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;SAC/C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC1D,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACnC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC;AACpE,CAAC;AAED,KAAK,UAAU,8BAA8B,CAAC,KAM7C;IAMC,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAAC;QAC5C,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,UAAU,EAAE,KAAK,CAAC,IAAI;QACtB,KAAK,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;KAC5B,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrD,OAAO;QACL,QAAQ,EAAE,IAAI,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE;QACtD,UAAU,EAAE,KAAK,CAAC,IAAI;QACtB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,GAAG,EAAE,eAAe;KACrB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAK1D;IAMC,MAAM,SAAS,GAAG,mBAAmB,EAAE,CAAC;IACxC,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,MAAM,0BAA0B,CAAC,KAAK,CAAC,CAAC;IAEvD,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,eAAe,EAAE,CAAC;QACtC,OAAO,8BAA8B,CAAC;YACpC,UAAU,EAAE,SAAS;YACrB,KAAK;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC;YAC/B,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,KAAK;QAClC,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;YACrC,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;SACzC,CAAC;QACJ,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjB,MAAM,KAAK,GAAG,MAAM,YAAY,CAC9B,SAAS,EACT,SAAS,IAAI,SAAS,EACtB,SAAS,IAAI,SAAS,EACtB;QACE,SAAS,EAAE,IAAI;QACf,kBAAkB,EAAE,CAAC,SAAS;KAC/B,CACF,CAAC;IAEF,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC1B,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC;QACnC,OAAO,EAAE;YACP,CAAC,QAAQ,CAAC,EAAE;gBACV,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,oBAAoB;gBAClD,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,KAAK,EAAE;iBACjC;aACF;SACF;KACF,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CACnC,gBAAgB,CAAC,QAAQ,EAAE,sBAAsB,CAAC,EAClD;YACE,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,MAAM;SAC/B,CACF,CAAC;QACF,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAI3C,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,MAAM,GAKR;YACF,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE;SACnB,CAAC;QACF,IAAI,MAAM,CAAC,UAAU;YAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAC7D,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;YACtC,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QACtC,OAAO,MAAM,CAAC;IAChB,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;AACH,CAAC","sourcesContent":["import { callAgent, signA2AToken } from \"@agent-native/core/a2a\";\nimport {\n buildMcpToolName,\n McpClientManager,\n} from \"@agent-native/core/mcp-client\";\nimport {\n buildDeepLink,\n buildEmbedStartPath,\n createEmbedSessionTicket,\n getRequestContext,\n} from \"@agent-native/core/server\";\nimport {\n discoverAgents,\n type DiscoveredAgent,\n} from \"@agent-native/core/server/agent-discovery\";\nimport {\n getRequestOrgId,\n getRequestUserEmail,\n} from \"@agent-native/core/server\";\nimport { getOrgA2ASecret, getOrgDomain } from \"@agent-native/core/org\";\nimport {\n getDispatchMcpAppAccessSettings,\n isAppAllowedByMcpAccess,\n type DispatchMcpAppAccessSettings,\n} from \"./mcp-access-store.js\";\n\nconst DISPATCH_APP_ID = \"dispatch\";\nconst DISPATCH_NAME = \"Agent-Native Dispatch\";\nconst DISPATCH_DESCRIPTION =\n \"Workspace control plane for extensions, agents, vault, integrations, approvals, and app routing.\";\nconst DISPATCH_COLOR = \"#14B8A6\";\n\nexport interface DispatchMcpAccessibleApp {\n id: string;\n name: string;\n description: string;\n url: string;\n color: string;\n granted: boolean;\n}\n\nfunction normalizeAppId(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction normalizeBaseUrl(raw: string | undefined | null): string | null {\n const value = raw?.trim();\n if (!value) return null;\n try {\n const url = new URL(value);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return null;\n return url.toString().replace(/\\/+$/, \"\");\n } catch {\n return null;\n }\n}\n\nfunction normalizeBasePath(value: string | undefined): string {\n const trimmed = value?.trim();\n if (!trimmed || trimmed === \"/\") return \"\";\n const normalized = trimmed.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n return normalized ? `/${normalized}` : \"\";\n}\n\nfunction withConfiguredBasePath(baseUrl: string): string {\n const basePath = normalizeBasePath(\n process.env.VITE_APP_BASE_PATH || process.env.APP_BASE_PATH,\n );\n if (!basePath) return baseUrl;\n try {\n const url = new URL(baseUrl);\n const path = normalizeBasePath(url.pathname);\n if (path === basePath || path.startsWith(`${basePath}/`)) {\n return baseUrl;\n }\n url.pathname = path && path !== \"/\" ? `${basePath}${path}` : `${basePath}/`;\n return url.toString().replace(/\\/+$/, \"\");\n } catch {\n return baseUrl;\n }\n}\n\nfunction dispatchSelfBaseUrl(): string {\n const requestOrigin = normalizeBaseUrl(getRequestContext()?.requestOrigin);\n if (requestOrigin) return withConfiguredBasePath(requestOrigin);\n\n const configured =\n normalizeBaseUrl(process.env.WORKSPACE_GATEWAY_URL) ??\n normalizeBaseUrl(process.env.APP_URL) ??\n normalizeBaseUrl(process.env.URL) ??\n normalizeBaseUrl(process.env.DEPLOY_URL) ??\n normalizeBaseUrl(process.env.BETTER_AUTH_URL);\n if (configured) return withConfiguredBasePath(configured);\n\n return process.env.NODE_ENV === \"production\"\n ? \"https://dispatch.agent-native.com\"\n : \"http://localhost:8092\";\n}\n\nfunction dispatchSelfApp(\n settings: DispatchMcpAppAccessSettings,\n): DispatchMcpAccessibleApp {\n return {\n id: DISPATCH_APP_ID,\n name: DISPATCH_NAME,\n description: DISPATCH_DESCRIPTION,\n url: dispatchSelfBaseUrl(),\n color: DISPATCH_COLOR,\n granted: isAppAllowedByMcpAccess(DISPATCH_APP_ID, settings),\n };\n}\n\nconst CONTROL_CHARS = new RegExp(\"[\\\\u0000-\\\\u001f\\\\u007f]\");\n\nfunction safeAppPath(raw: unknown): string | null {\n if (typeof raw !== \"string\" || !raw.trim()) return null;\n const value = raw.trim();\n if (CONTROL_CHARS.test(value)) return null;\n if (!value.startsWith(\"/\")) return null;\n if (value.startsWith(\"//\") || value.startsWith(\"/\\\\\")) return null;\n if (/^\\/[a-z][a-z0-9+.-]*:/i.test(value)) return null;\n if (/%(?:2f|5c)/i.test(value)) return null;\n const rawPath = value.split(/[?#]/, 1)[0] ?? value;\n let parsed: URL;\n try {\n parsed = new URL(value, \"http://agent-native.invalid\");\n } catch {\n return null;\n }\n if (parsed.pathname !== rawPath) return null;\n return value;\n}\n\nfunction appendParamsToPath(\n path: string,\n params: Record<string, string | number | boolean> | undefined,\n): string {\n if (!params || Object.keys(params).length === 0) return path;\n const url = new URL(path, \"http://agent-native.invalid\");\n for (const [key, value] of Object.entries(params)) {\n url.searchParams.set(key, String(value));\n }\n return `${url.pathname}${url.search}${url.hash}`;\n}\n\nfunction appOrigin(app: DispatchMcpAccessibleApp): string {\n return new URL(app.url).origin;\n}\n\nfunction appBaseUrl(app: DispatchMcpAccessibleApp): string {\n return app.url.replace(/\\/+$/, \"\");\n}\n\nfunction appBasePath(app: DispatchMcpAccessibleApp): string {\n const pathname = new URL(appBaseUrl(app)).pathname.replace(/\\/+$/, \"\");\n return pathname === \"/\" ? \"\" : pathname;\n}\n\nfunction appMatchesUrlPath(app: DispatchMcpAccessibleApp, url: URL): boolean {\n if (url.origin !== appOrigin(app)) return false;\n const basePath = appBasePath(app);\n if (!basePath) return true;\n return url.pathname === basePath || url.pathname.startsWith(`${basePath}/`);\n}\n\nfunction appPathSpecificity(app: DispatchMcpAccessibleApp): number {\n return appBasePath(app).length;\n}\n\nfunction appRelativePath(app: DispatchMcpAccessibleApp, url: URL): string {\n const basePath = appBasePath(app);\n const path = basePath\n ? url.pathname === basePath\n ? \"/\"\n : url.pathname.slice(basePath.length)\n : url.pathname;\n return `${path || \"/\"}${url.search}${url.hash}`;\n}\n\nfunction isDispatchControlPath(path: string | null): boolean {\n if (!path) return false;\n const route = path.split(/[?#]/, 1)[0] ?? path;\n return (\n route === \"/extensions\" ||\n route.startsWith(\"/extensions/\") ||\n route === \"/tools\" ||\n route.startsWith(\"/tools/\")\n );\n}\n\nfunction assertAppCanOpenPath(app: DispatchMcpAccessibleApp, path: string) {\n if (app.id !== DISPATCH_APP_ID && isDispatchControlPath(path)) {\n throw new Error(\n `Path \"${path}\" belongs to Dispatch. Use app: \"dispatch\" for Dispatch extension and tool routes.`,\n );\n }\n}\n\nfunction toAccessibleApp(\n agent: DiscoveredAgent,\n settings: DispatchMcpAppAccessSettings,\n): DispatchMcpAccessibleApp {\n return {\n id: agent.id,\n name: agent.name,\n description: agent.description,\n url: agent.url,\n color: agent.color,\n granted: isAppAllowedByMcpAccess(agent.id, settings),\n };\n}\n\nexport async function listDispatchMcpApps(): Promise<{\n settings: DispatchMcpAppAccessSettings;\n apps: DispatchMcpAccessibleApp[];\n}> {\n const [settings, agents] = await Promise.all([\n getDispatchMcpAppAccessSettings(),\n discoverAgents(\"dispatch\"),\n ]);\n return {\n settings,\n apps: [\n dispatchSelfApp(settings),\n ...agents\n .filter((agent) => normalizeAppId(agent.id) !== DISPATCH_APP_ID)\n .map((agent) => toAccessibleApp(agent, settings)),\n ],\n };\n}\n\nexport async function listGrantedDispatchMcpApps(): Promise<\n DispatchMcpAccessibleApp[]\n> {\n const { apps } = await listDispatchMcpApps();\n return apps.filter((app) => app.granted);\n}\n\nexport async function resolveGrantedDispatchMcpApp(\n app: string,\n): Promise<DispatchMcpAccessibleApp> {\n const target = normalizeAppId(app);\n if (!target) throw new Error(\"app is required\");\n const { apps } = await listDispatchMcpApps();\n const match = apps.find(\n (candidate) =>\n candidate.id === target || candidate.name.toLowerCase() === target,\n );\n if (!match) {\n throw new Error(\n `Unknown app \"${app}\". Call list_apps to see apps available through Dispatch MCP.`,\n );\n }\n if (!match.granted) {\n throw new Error(\n `Dispatch MCP access to \"${match.id}\" is not granted. Open Dispatch > Agents to change MCP app access.`,\n );\n }\n return match;\n}\n\nexport async function askGrantedDispatchMcpApp(\n app: string,\n message: string,\n): Promise<{ app: string; routedVia: \"a2a\"; response: string }> {\n const trimmedMessage = message.trim();\n if (!trimmedMessage) throw new Error(\"message is required\");\n const target = await resolveGrantedDispatchMcpApp(app);\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n\n const orgId = getRequestOrgId();\n const [orgDomain, orgSecret] = orgId\n ? await Promise.all([\n getOrgDomain(orgId).catch(() => null),\n getOrgA2ASecret(orgId).catch(() => null),\n ])\n : [null, null];\n\n const response = await callAgent(target.url, trimmedMessage, {\n userEmail,\n orgDomain: orgDomain ?? undefined,\n orgSecret: orgSecret ?? undefined,\n timeoutMs: 5 * 60_000,\n });\n return { app: target.id, routedVia: \"a2a\", response };\n}\n\nexport async function openGrantedDispatchMcpApp(input: {\n app: string;\n view?: string;\n path?: string;\n params?: Record<string, string | number | boolean>;\n embed?: boolean;\n chrome?: \"full\" | \"minimal\";\n}): Promise<{\n app: string;\n view?: string;\n path?: string;\n url: string;\n embed?: boolean;\n chrome?: \"full\" | \"minimal\";\n}> {\n const view = input.view?.trim() ?? \"\";\n const hasPathInput = input.path != null;\n const path = safeAppPath(input.path);\n if (hasPathInput && !path) {\n throw new Error(\"path must be a safe app-relative route\");\n }\n if (!view && !path) throw new Error(\"open_app requires view or path\");\n const target = await resolveGrantedDispatchMcpApp(input.app);\n if (path) assertAppCanOpenPath(target, path);\n const relUrl = path\n ? appendParamsToPath(path, input.params)\n : buildDeepLink({\n app: target.id,\n view,\n params: input.params,\n });\n return {\n app: target.id,\n ...(view ? { view } : {}),\n ...(path ? { path } : {}),\n url: `${appBaseUrl(target)}${relUrl}`,\n ...(input.embed === true ? { embed: true } : {}),\n ...(input.chrome ? { chrome: input.chrome } : {}),\n };\n}\n\nfunction parseMcpToolTextResult(result: unknown): Record<string, unknown> {\n if (result && typeof result === \"object\") {\n const structured = (result as any).structuredContent;\n if (structured && typeof structured === \"object\") return structured;\n const parts = Array.isArray((result as any).content)\n ? ((result as any).content as Array<Record<string, unknown>>)\n : [];\n const text = parts.find(\n (part) => part?.type === \"text\" && typeof part.text === \"string\",\n )?.text;\n if (typeof text === \"string\" && text.trim()) {\n const parsed = JSON.parse(text);\n if (parsed && typeof parsed === \"object\") return parsed;\n }\n }\n throw new Error(\"Target app did not return an embed session.\");\n}\n\nasync function resolveDispatchEmbedTarget(input: {\n app?: string;\n url?: string;\n path?: string;\n}): Promise<{ app: DispatchMcpAccessibleApp; path: string; url: string }> {\n const explicitApp = input.app?.trim()\n ? await resolveGrantedDispatchMcpApp(input.app)\n : null;\n if (explicitApp && input.path) {\n const path = safeAppPath(input.path);\n if (!path) throw new Error(\"path must be a safe app-relative route\");\n assertAppCanOpenPath(explicitApp, path);\n return {\n app: explicitApp,\n path,\n url: `${appBaseUrl(explicitApp)}${path}`,\n };\n }\n\n if (!input.url) {\n throw new Error(\"create_embed_session requires a url or app + path.\");\n }\n\n let parsed: URL;\n try {\n parsed = new URL(input.url);\n } catch {\n if (!explicitApp) {\n throw new Error(\"Relative embed paths require an app id.\");\n }\n const path = safeAppPath(input.url);\n if (!path) throw new Error(\"url must be a safe app route.\");\n return {\n app: explicitApp,\n path,\n url: `${appBaseUrl(explicitApp)}${path}`,\n };\n }\n\n const apps = explicitApp ? [explicitApp] : await listGrantedDispatchMcpApps();\n const target = apps\n .filter((app) => appMatchesUrlPath(app, parsed))\n .sort((a, b) => appPathSpecificity(b) - appPathSpecificity(a))[0];\n if (!target) {\n throw new Error(\n \"Embed URL must belong to an app granted through Dispatch.\",\n );\n }\n const path = safeAppPath(appRelativePath(target, parsed));\n if (!path) throw new Error(\"Embed URL path is not safe.\");\n assertAppCanOpenPath(target, path);\n return { app: target, path, url: `${appBaseUrl(target)}${path}` };\n}\n\nasync function createDispatchSelfEmbedSession(input: {\n ownerEmail: string;\n orgId?: string;\n path: string;\n baseUrl: string;\n chrome?: \"full\" | \"minimal\";\n}): Promise<{\n startUrl: string;\n targetPath?: string;\n expiresAt?: number;\n app: string;\n}> {\n const ticket = await createEmbedSessionTicket({\n ownerEmail: input.ownerEmail,\n orgId: input.orgId,\n targetPath: input.path,\n scope: input.chrome ?? null,\n });\n const startPath = buildEmbedStartPath(ticket.ticket);\n return {\n startUrl: new URL(startPath, input.baseUrl).toString(),\n targetPath: input.path,\n expiresAt: ticket.expiresAt,\n app: DISPATCH_APP_ID,\n };\n}\n\nexport async function createGrantedDispatchMcpEmbedSession(input: {\n app?: string;\n url?: string;\n path?: string;\n chrome?: \"full\" | \"minimal\";\n}): Promise<{\n startUrl: string;\n targetPath?: string;\n expiresAt?: number;\n app: string;\n}> {\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n const target = await resolveDispatchEmbedTarget(input);\n\n const orgId = getRequestOrgId();\n if (target.app.id === DISPATCH_APP_ID) {\n return createDispatchSelfEmbedSession({\n ownerEmail: userEmail,\n orgId,\n path: target.path,\n baseUrl: appBaseUrl(target.app),\n chrome: input.chrome,\n });\n }\n\n const [orgDomain, orgSecret] = orgId\n ? await Promise.all([\n getOrgDomain(orgId).catch(() => null),\n getOrgA2ASecret(orgId).catch(() => null),\n ])\n : [null, null];\n const token = await signA2AToken(\n userEmail,\n orgDomain ?? undefined,\n orgSecret ?? undefined,\n {\n expiresIn: \"5m\",\n preferGlobalSecret: !orgSecret,\n },\n );\n\n const serverId = \"target\";\n const manager = new McpClientManager({\n servers: {\n [serverId]: {\n type: \"http\",\n url: `${appBaseUrl(target.app)}/_agent-native/mcp`,\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n },\n });\n await manager.start();\n try {\n const result = await manager.callTool(\n buildMcpToolName(serverId, \"create_embed_session\"),\n {\n url: target.url,\n chrome: input.chrome ?? \"full\",\n },\n );\n const parsed = parseMcpToolTextResult(result) as {\n startUrl?: string;\n targetPath?: string;\n expiresAt?: number;\n };\n if (!parsed.startUrl) {\n throw new Error(\"Target app did not return an embed start URL.\");\n }\n const output: {\n startUrl: string;\n targetPath?: string;\n expiresAt?: number;\n app: string;\n } = {\n startUrl: parsed.startUrl,\n app: target.app.id,\n };\n if (parsed.targetPath) output.targetPath = parsed.targetPath;\n if (typeof parsed.expiresAt === \"number\")\n output.expiresAt = parsed.expiresAt;\n return output;\n } finally {\n await manager.stop();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mcp-gateway.js","sourceRoot":"","sources":["../../../src/server/lib/mcp-gateway.ts"],"names":[],"mappings":"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","sourcesContent":["import { callAgent, signA2AToken } from \"@agent-native/core/a2a\";\nimport {\n buildMcpToolName,\n McpClientManager,\n} from \"@agent-native/core/mcp-client\";\nimport {\n buildDeepLink,\n buildEmbedStartPath,\n createEmbedSessionTicket,\n getRequestContext,\n} from \"@agent-native/core/server\";\nimport {\n discoverAgents,\n type DiscoveredAgent,\n} from \"@agent-native/core/server/agent-discovery\";\nimport {\n getRequestOrgId,\n getRequestUserEmail,\n} from \"@agent-native/core/server\";\nimport { getOrgA2ASecret, getOrgDomain } from \"@agent-native/core/org\";\nimport {\n getDispatchMcpAppAccessSettings,\n isAppAllowedByMcpAccess,\n type DispatchMcpAppAccessSettings,\n} from \"./mcp-access-store.js\";\n\nconst DISPATCH_APP_ID = \"dispatch\";\nconst DISPATCH_NAME = \"Agent-Native Dispatch\";\nconst DISPATCH_DESCRIPTION =\n \"Workspace control plane for extensions, agents, vault, integrations, approvals, and app routing.\";\nconst DISPATCH_COLOR = \"#14B8A6\";\n\nexport interface DispatchMcpAccessibleApp {\n id: string;\n name: string;\n description: string;\n url: string;\n color: string;\n granted: boolean;\n}\n\nfunction normalizeAppId(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction normalizeBaseUrl(raw: string | undefined | null): string | null {\n const value = raw?.trim();\n if (!value) return null;\n try {\n const url = new URL(value);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return null;\n return url.toString().replace(/\\/+$/, \"\");\n } catch {\n return null;\n }\n}\n\nfunction normalizeBasePath(value: string | undefined): string {\n const trimmed = value?.trim();\n if (!trimmed || trimmed === \"/\") return \"\";\n const normalized = trimmed.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n return normalized ? `/${normalized}` : \"\";\n}\n\nfunction withConfiguredBasePath(baseUrl: string): string {\n const basePath = normalizeBasePath(\n process.env.VITE_APP_BASE_PATH || process.env.APP_BASE_PATH,\n );\n if (!basePath) return baseUrl;\n try {\n const url = new URL(baseUrl);\n const path = normalizeBasePath(url.pathname);\n if (path === basePath || path.startsWith(`${basePath}/`)) {\n return baseUrl;\n }\n url.pathname = path && path !== \"/\" ? `${basePath}${path}` : `${basePath}/`;\n return url.toString().replace(/\\/+$/, \"\");\n } catch {\n return baseUrl;\n }\n}\n\nfunction dispatchSelfBaseUrl(): string {\n const requestOrigin = normalizeBaseUrl(getRequestContext()?.requestOrigin);\n if (requestOrigin) return withConfiguredBasePath(requestOrigin);\n\n const configured =\n normalizeBaseUrl(process.env.WORKSPACE_GATEWAY_URL) ??\n normalizeBaseUrl(process.env.APP_URL) ??\n normalizeBaseUrl(process.env.URL) ??\n normalizeBaseUrl(process.env.DEPLOY_URL) ??\n normalizeBaseUrl(process.env.BETTER_AUTH_URL);\n if (configured) return withConfiguredBasePath(configured);\n\n return process.env.NODE_ENV === \"production\"\n ? \"https://dispatch.agent-native.com\"\n : \"http://localhost:8092\";\n}\n\nfunction dispatchSelfApp(\n settings: DispatchMcpAppAccessSettings,\n): DispatchMcpAccessibleApp {\n return {\n id: DISPATCH_APP_ID,\n name: DISPATCH_NAME,\n description: DISPATCH_DESCRIPTION,\n url: dispatchSelfBaseUrl(),\n color: DISPATCH_COLOR,\n granted: isAppAllowedByMcpAccess(DISPATCH_APP_ID, settings),\n };\n}\n\nconst CONTROL_CHARS = new RegExp(\"[\\\\u0000-\\\\u001f\\\\u007f]\");\n\nfunction safeAppPath(raw: unknown): string | null {\n if (typeof raw !== \"string\" || !raw.trim()) return null;\n const value = raw.trim();\n if (CONTROL_CHARS.test(value)) return null;\n if (!value.startsWith(\"/\")) return null;\n if (value.startsWith(\"//\") || value.startsWith(\"/\\\\\")) return null;\n if (/^\\/[a-z][a-z0-9+.-]*:/i.test(value)) return null;\n if (/%(?:2f|5c)/i.test(value)) return null;\n const rawPath = value.split(/[?#]/, 1)[0] ?? value;\n let parsed: URL;\n try {\n parsed = new URL(value, \"http://agent-native.invalid\");\n } catch {\n return null;\n }\n if (parsed.pathname !== rawPath) return null;\n return value;\n}\n\nfunction appendParamsToPath(\n path: string,\n params: Record<string, string | number | boolean> | undefined,\n): string {\n if (!params || Object.keys(params).length === 0) return path;\n const url = new URL(path, \"http://agent-native.invalid\");\n for (const [key, value] of Object.entries(params)) {\n url.searchParams.set(key, String(value));\n }\n return `${url.pathname}${url.search}${url.hash}`;\n}\n\nfunction appOrigin(app: DispatchMcpAccessibleApp): string {\n return new URL(app.url).origin;\n}\n\nfunction appBaseUrl(app: DispatchMcpAccessibleApp): string {\n return app.url.replace(/\\/+$/, \"\");\n}\n\nfunction appBasePath(app: DispatchMcpAccessibleApp): string {\n const pathname = new URL(appBaseUrl(app)).pathname.replace(/\\/+$/, \"\");\n return pathname === \"/\" ? \"\" : pathname;\n}\n\nfunction appMatchesUrlPath(app: DispatchMcpAccessibleApp, url: URL): boolean {\n if (url.origin !== appOrigin(app)) return false;\n const basePath = appBasePath(app);\n if (!basePath) return true;\n return url.pathname === basePath || url.pathname.startsWith(`${basePath}/`);\n}\n\nfunction appPathSpecificity(app: DispatchMcpAccessibleApp): number {\n return appBasePath(app).length;\n}\n\nfunction appRelativePath(app: DispatchMcpAccessibleApp, url: URL): string {\n const basePath = appBasePath(app);\n const path = basePath\n ? url.pathname === basePath\n ? \"/\"\n : url.pathname.slice(basePath.length)\n : url.pathname;\n return `${path || \"/\"}${url.search}${url.hash}`;\n}\n\nfunction isDispatchControlPath(path: string | null): boolean {\n if (!path) return false;\n const route = path.split(/[?#]/, 1)[0] ?? path;\n return (\n route === \"/extensions\" ||\n route.startsWith(\"/extensions/\") ||\n route === \"/tools\" ||\n route.startsWith(\"/tools/\")\n );\n}\n\nfunction assertAppCanOpenPath(app: DispatchMcpAccessibleApp, path: string) {\n if (app.id !== DISPATCH_APP_ID && isDispatchControlPath(path)) {\n throw new Error(\n `Path \"${path}\" belongs to Dispatch. Use app: \"dispatch\" for Dispatch extension and tool routes.`,\n );\n }\n}\n\nfunction toAccessibleApp(\n agent: DiscoveredAgent,\n settings: DispatchMcpAppAccessSettings,\n): DispatchMcpAccessibleApp {\n return {\n id: agent.id,\n name: agent.name,\n description: agent.description,\n url: agent.url,\n color: agent.color,\n granted: isAppAllowedByMcpAccess(agent.id, settings),\n };\n}\n\nexport async function listDispatchMcpApps(): Promise<{\n settings: DispatchMcpAppAccessSettings;\n apps: DispatchMcpAccessibleApp[];\n}> {\n const [settings, agents] = await Promise.all([\n getDispatchMcpAppAccessSettings(),\n discoverAgents(\"dispatch\"),\n ]);\n return {\n settings,\n apps: [\n dispatchSelfApp(settings),\n ...agents\n .filter((agent) => normalizeAppId(agent.id) !== DISPATCH_APP_ID)\n .map((agent) => toAccessibleApp(agent, settings)),\n ],\n };\n}\n\nexport async function listGrantedDispatchMcpApps(): Promise<\n DispatchMcpAccessibleApp[]\n> {\n const { apps } = await listDispatchMcpApps();\n return apps.filter((app) => app.granted);\n}\n\nexport async function resolveGrantedDispatchMcpApp(\n app: string,\n): Promise<DispatchMcpAccessibleApp> {\n const target = normalizeAppId(app);\n if (!target) throw new Error(\"app is required\");\n const { apps } = await listDispatchMcpApps();\n const match = apps.find(\n (candidate) =>\n candidate.id === target || candidate.name.toLowerCase() === target,\n );\n if (!match) {\n throw new Error(\n `Unknown app \"${app}\". Call list_apps to see apps available through Dispatch MCP.`,\n );\n }\n if (!match.granted) {\n throw new Error(\n `Dispatch MCP access to \"${match.id}\" is not granted. Open Dispatch > Agents to change MCP app access.`,\n );\n }\n return match;\n}\n\nexport async function askGrantedDispatchMcpApp(\n app: string,\n message: string,\n): Promise<{ app: string; routedVia: \"a2a\"; response: string }> {\n const trimmedMessage = message.trim();\n if (!trimmedMessage) throw new Error(\"message is required\");\n const target = await resolveGrantedDispatchMcpApp(app);\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n\n const orgId = getRequestOrgId();\n const [orgDomain, orgSecret] = orgId\n ? await Promise.all([\n getOrgDomain(orgId).catch(() => null),\n getOrgA2ASecret(orgId).catch(() => null),\n ])\n : [null, null];\n\n const response = await callAgent(target.url, trimmedMessage, {\n userEmail,\n orgDomain: orgDomain ?? undefined,\n orgSecret: orgSecret ?? undefined,\n timeoutMs: 5 * 60_000,\n });\n return { app: target.id, routedVia: \"a2a\", response };\n}\n\nexport async function openGrantedDispatchMcpApp(input: {\n app: string;\n view?: string;\n path?: string;\n params?: Record<string, string | number | boolean>;\n embed?: boolean;\n chrome?: \"full\" | \"minimal\";\n}): Promise<{\n app: string;\n view?: string;\n path?: string;\n url: string;\n embed?: boolean;\n chrome?: \"full\" | \"minimal\";\n}> {\n const view = input.view?.trim() ?? \"\";\n const hasPathInput = input.path != null;\n const path = safeAppPath(input.path);\n if (hasPathInput && !path) {\n throw new Error(\"path must be a safe app-relative route\");\n }\n if (!view && !path) throw new Error(\"open_app requires view or path\");\n const target = await resolveGrantedDispatchMcpApp(input.app);\n if (path) assertAppCanOpenPath(target, path);\n const relUrl = path\n ? appendParamsToPath(path, input.params)\n : buildDeepLink({\n app: target.id,\n view,\n params: input.params,\n });\n return {\n app: target.id,\n ...(view ? { view } : {}),\n ...(path ? { path } : {}),\n url: `${appBaseUrl(target)}${relUrl}`,\n ...(input.embed === true ? { embed: true } : {}),\n ...(input.chrome ? { chrome: input.chrome } : {}),\n };\n}\n\nfunction parseMcpToolTextResult(result: unknown): Record<string, unknown> {\n if (result && typeof result === \"object\") {\n const structured = (result as any).structuredContent;\n if (structured && typeof structured === \"object\") return structured;\n const parts = Array.isArray((result as any).content)\n ? ((result as any).content as Array<Record<string, unknown>>)\n : [];\n const text = parts.find(\n (part) => part?.type === \"text\" && typeof part.text === \"string\",\n )?.text;\n if (typeof text === \"string\" && text.trim()) {\n if ((result as any).isError) throw new Error(text.trim());\n const parsed = JSON.parse(text);\n if (parsed && typeof parsed === \"object\") return parsed;\n }\n }\n throw new Error(\"Target app did not return an embed session.\");\n}\n\nasync function resolveDispatchEmbedTarget(input: {\n app?: string;\n url?: string;\n path?: string;\n}): Promise<{ app: DispatchMcpAccessibleApp; path: string; url: string }> {\n const explicitApp = input.app?.trim()\n ? await resolveGrantedDispatchMcpApp(input.app)\n : null;\n if (explicitApp && input.path) {\n const path = safeAppPath(input.path);\n if (!path) throw new Error(\"path must be a safe app-relative route\");\n assertAppCanOpenPath(explicitApp, path);\n return {\n app: explicitApp,\n path,\n url: `${appBaseUrl(explicitApp)}${path}`,\n };\n }\n\n if (!input.url) {\n throw new Error(\"create_embed_session requires a url or app + path.\");\n }\n\n let parsed: URL;\n try {\n parsed = new URL(input.url);\n } catch {\n if (!explicitApp) {\n throw new Error(\"Relative embed paths require an app id.\");\n }\n const path = safeAppPath(input.url);\n if (!path) throw new Error(\"url must be a safe app route.\");\n return {\n app: explicitApp,\n path,\n url: `${appBaseUrl(explicitApp)}${path}`,\n };\n }\n\n const apps = explicitApp ? [explicitApp] : await listGrantedDispatchMcpApps();\n const target = apps\n .filter((app) => appMatchesUrlPath(app, parsed))\n .sort((a, b) => appPathSpecificity(b) - appPathSpecificity(a))[0];\n if (!target) {\n throw new Error(\n \"Embed URL must belong to an app granted through Dispatch.\",\n );\n }\n const path = safeAppPath(appRelativePath(target, parsed));\n if (!path) throw new Error(\"Embed URL path is not safe.\");\n assertAppCanOpenPath(target, path);\n return { app: target, path, url: `${appBaseUrl(target)}${path}` };\n}\n\nasync function createDispatchSelfEmbedSession(input: {\n ownerEmail: string;\n orgId?: string;\n path: string;\n baseUrl: string;\n chrome?: \"full\" | \"minimal\";\n}): Promise<{\n startUrl: string;\n targetPath?: string;\n expiresAt?: number;\n app: string;\n}> {\n const ticket = await createEmbedSessionTicket({\n ownerEmail: input.ownerEmail,\n orgId: input.orgId,\n targetPath: input.path,\n scope: input.chrome ?? null,\n });\n const startPath = buildEmbedStartPath(ticket.ticket);\n return {\n startUrl: new URL(startPath, input.baseUrl).toString(),\n targetPath: input.path,\n expiresAt: ticket.expiresAt,\n app: DISPATCH_APP_ID,\n };\n}\n\nexport async function createGrantedDispatchMcpEmbedSession(input: {\n app?: string;\n url?: string;\n path?: string;\n chrome?: \"full\" | \"minimal\";\n}): Promise<{\n startUrl: string;\n targetPath?: string;\n expiresAt?: number;\n app: string;\n}> {\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n const target = await resolveDispatchEmbedTarget(input);\n\n const orgId = getRequestOrgId();\n if (target.app.id === DISPATCH_APP_ID) {\n return createDispatchSelfEmbedSession({\n ownerEmail: userEmail,\n orgId,\n path: target.path,\n baseUrl: appBaseUrl(target.app),\n chrome: input.chrome,\n });\n }\n\n const [orgDomain, orgSecret] = orgId\n ? await Promise.all([\n getOrgDomain(orgId).catch(() => null),\n getOrgA2ASecret(orgId).catch(() => null),\n ])\n : [null, null];\n const token = await signA2AToken(\n userEmail,\n orgDomain ?? undefined,\n orgSecret ?? undefined,\n {\n expiresIn: \"5m\",\n // Target MCP endpoints verify A2A JWTs with the deployment-wide\n // A2A_SECRET. Prefer it for hosted cross-app embeds even when Dispatch\n // also has an org-level secret available.\n preferGlobalSecret: true,\n },\n );\n\n const serverId = \"target\";\n const manager = new McpClientManager({\n servers: {\n [serverId]: {\n type: \"http\",\n url: `${appBaseUrl(target.app)}/_agent-native/mcp`,\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n },\n });\n await manager.start();\n try {\n const result = await manager.callTool(\n buildMcpToolName(serverId, \"create_embed_session\"),\n {\n url: target.url,\n chrome: input.chrome ?? \"full\",\n },\n );\n const parsed = parseMcpToolTextResult(result) as {\n startUrl?: string;\n targetPath?: string;\n expiresAt?: number;\n };\n if (!parsed.startUrl) {\n throw new Error(\"Target app did not return an embed start URL.\");\n }\n const output: {\n startUrl: string;\n targetPath?: string;\n expiresAt?: number;\n app: string;\n } = {\n startUrl: parsed.startUrl,\n app: target.app.id,\n };\n if (parsed.targetPath) output.targetPath = parsed.targetPath;\n if (typeof parsed.expiresAt === \"number\")\n output.expiresAt = parsed.expiresAt;\n return output;\n } finally {\n await manager.stop();\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/dispatch",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { buildDispatchNavigationState } from "./use-navigation-state.js";
|
|
3
|
+
|
|
4
|
+
describe("buildDispatchNavigationState", () => {
|
|
5
|
+
it("exposes the current extension id from extension routes", () => {
|
|
6
|
+
expect(
|
|
7
|
+
buildDispatchNavigationState("/extensions/ext-1/github-stars-over-time"),
|
|
8
|
+
).toEqual({
|
|
9
|
+
view: "extensions",
|
|
10
|
+
path: "/extensions/ext-1/github-stars-over-time",
|
|
11
|
+
extensionId: "ext-1",
|
|
12
|
+
extensionSlug: "github-stars-over-time",
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("preserves dreams query context", () => {
|
|
17
|
+
expect(
|
|
18
|
+
buildDispatchNavigationState(
|
|
19
|
+
"/dreams",
|
|
20
|
+
"?dreamId=dream-1&sourceId=src-1&query=focus",
|
|
21
|
+
),
|
|
22
|
+
).toEqual({
|
|
23
|
+
view: "dreams",
|
|
24
|
+
path: "/dreams",
|
|
25
|
+
dreamId: "dream-1",
|
|
26
|
+
sourceId: "src-1",
|
|
27
|
+
query: "focus",
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
appBasePath,
|
|
7
7
|
appPath,
|
|
8
8
|
} from "@agent-native/core/client";
|
|
9
|
+
import { extensionIdFromPathname } from "@agent-native/core/client/extensions";
|
|
9
10
|
import type {
|
|
10
11
|
DispatchExtensionConfig,
|
|
11
12
|
DispatchNavItem,
|
|
@@ -14,6 +15,8 @@ import type {
|
|
|
14
15
|
export interface NavigationState {
|
|
15
16
|
view: string;
|
|
16
17
|
path?: string;
|
|
18
|
+
extensionId?: string;
|
|
19
|
+
extensionSlug?: string;
|
|
17
20
|
dreamId?: string;
|
|
18
21
|
sourceId?: string;
|
|
19
22
|
query?: string;
|
|
@@ -27,19 +30,11 @@ export function useNavigationState(extensions?: DispatchExtensionConfig) {
|
|
|
27
30
|
// Sync current route to application state
|
|
28
31
|
useEffect(() => {
|
|
29
32
|
const localPathname = routerPath(location.pathname);
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (state.view === "dreams") {
|
|
36
|
-
const dreamId = params.get("dreamId");
|
|
37
|
-
const sourceId = params.get("sourceId");
|
|
38
|
-
const query = params.get("query");
|
|
39
|
-
if (dreamId) state.dreamId = dreamId;
|
|
40
|
-
if (sourceId) state.sourceId = sourceId;
|
|
41
|
-
if (query) state.query = query;
|
|
42
|
-
}
|
|
33
|
+
const state = buildDispatchNavigationState(
|
|
34
|
+
localPathname,
|
|
35
|
+
location.search,
|
|
36
|
+
extensions,
|
|
37
|
+
);
|
|
43
38
|
|
|
44
39
|
fetch(agentNativePath("/_agent-native/application-state/navigation"), {
|
|
45
40
|
method: "PUT",
|
|
@@ -79,7 +74,7 @@ export function useNavigationState(extensions?: DispatchExtensionConfig) {
|
|
|
79
74
|
|
|
80
75
|
// Navigate to a specific path or resolve view name to path
|
|
81
76
|
const resolvedPath =
|
|
82
|
-
cmd.path || resolvePath(cmd.view, extensions) || "/overview";
|
|
77
|
+
cmd.path || resolvePath(cmd.view, extensions, cmd) || "/overview";
|
|
83
78
|
const path =
|
|
84
79
|
cmd.view === "dreams" && cmd.dreamId && !resolvedPath.includes("?")
|
|
85
80
|
? `${resolvedPath}?dreamId=${encodeURIComponent(cmd.dreamId)}`
|
|
@@ -90,6 +85,38 @@ export function useNavigationState(extensions?: DispatchExtensionConfig) {
|
|
|
90
85
|
}, [extensions, navCommand, navigate, qc]);
|
|
91
86
|
}
|
|
92
87
|
|
|
88
|
+
export function buildDispatchNavigationState(
|
|
89
|
+
pathname: string,
|
|
90
|
+
search = "",
|
|
91
|
+
extensions?: DispatchExtensionConfig,
|
|
92
|
+
): NavigationState {
|
|
93
|
+
const state: NavigationState = {
|
|
94
|
+
view: resolveView(pathname, extensions),
|
|
95
|
+
path: appPath(pathname),
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const extensionId = extensionIdFromPathname(pathname);
|
|
99
|
+
if (extensionId) {
|
|
100
|
+
state.view = "extensions";
|
|
101
|
+
state.extensionId = extensionId;
|
|
102
|
+
const slug = extensionSlugFromPathname(pathname);
|
|
103
|
+
if (slug) state.extensionSlug = slug;
|
|
104
|
+
return state;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (state.view === "dreams") {
|
|
108
|
+
const params = new URLSearchParams(search);
|
|
109
|
+
const dreamId = params.get("dreamId");
|
|
110
|
+
const sourceId = params.get("sourceId");
|
|
111
|
+
const query = params.get("query");
|
|
112
|
+
if (dreamId) state.dreamId = dreamId;
|
|
113
|
+
if (sourceId) state.sourceId = sourceId;
|
|
114
|
+
if (query) state.query = query;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return state;
|
|
118
|
+
}
|
|
119
|
+
|
|
93
120
|
function routerPath(path: string): string {
|
|
94
121
|
const basePath = appBasePath();
|
|
95
122
|
if (!basePath) return path;
|
|
@@ -143,6 +170,9 @@ function resolveView(
|
|
|
143
170
|
): string {
|
|
144
171
|
const extensionView = resolveExtensionView(pathname, extensions);
|
|
145
172
|
if (extensionView) return extensionView;
|
|
173
|
+
if (pathname === "/extensions" || pathname.startsWith("/extensions/")) {
|
|
174
|
+
return "extensions";
|
|
175
|
+
}
|
|
146
176
|
if (pathname.startsWith("/apps")) return "apps";
|
|
147
177
|
if (pathname.startsWith("/metrics")) return "metrics";
|
|
148
178
|
if (pathname.startsWith("/new-app")) return "new-app";
|
|
@@ -164,6 +194,7 @@ function resolveView(
|
|
|
164
194
|
function resolvePath(
|
|
165
195
|
view?: string,
|
|
166
196
|
extensions?: DispatchExtensionConfig,
|
|
197
|
+
command?: Pick<NavigationState, "extensionId">,
|
|
167
198
|
): string | undefined {
|
|
168
199
|
switch (view) {
|
|
169
200
|
case "overview":
|
|
@@ -204,7 +235,21 @@ function resolvePath(
|
|
|
204
235
|
return "/thread-debug";
|
|
205
236
|
case "team":
|
|
206
237
|
return "/team";
|
|
238
|
+
case "extensions":
|
|
239
|
+
return command?.extensionId
|
|
240
|
+
? `/extensions/${encodeURIComponent(command.extensionId)}`
|
|
241
|
+
: "/extensions";
|
|
207
242
|
default:
|
|
208
243
|
return resolveExtensionPath(view, extensions);
|
|
209
244
|
}
|
|
210
245
|
}
|
|
246
|
+
|
|
247
|
+
function extensionSlugFromPathname(pathname: string): string | undefined {
|
|
248
|
+
const match = pathname.match(/^\/extensions\/[^/]+\/([^/?#]+)/);
|
|
249
|
+
if (!match?.[1]) return undefined;
|
|
250
|
+
try {
|
|
251
|
+
return decodeURIComponent(match[1]);
|
|
252
|
+
} catch {
|
|
253
|
+
return match[1];
|
|
254
|
+
}
|
|
255
|
+
}
|
|
@@ -292,4 +292,58 @@ describe("createGrantedDispatchMcpEmbedSession", () => {
|
|
|
292
292
|
startUrl: "http://localhost:8086/_agent-native/embed/start?ticket=remote",
|
|
293
293
|
});
|
|
294
294
|
});
|
|
295
|
+
|
|
296
|
+
it("prefers the shared A2A secret when minting cross-app MCP embed tokens", async () => {
|
|
297
|
+
mocks.getOrgDomain.mockResolvedValue("builder.io");
|
|
298
|
+
mocks.getOrgA2ASecret.mockResolvedValue("org-specific-secret");
|
|
299
|
+
|
|
300
|
+
await runWithRequestContext(
|
|
301
|
+
{
|
|
302
|
+
userEmail: "owner@example.test",
|
|
303
|
+
orgId: "org-1",
|
|
304
|
+
requestOrigin: "http://localhost:8092",
|
|
305
|
+
},
|
|
306
|
+
() =>
|
|
307
|
+
createGrantedDispatchMcpEmbedSession({
|
|
308
|
+
app: "analytics",
|
|
309
|
+
path: "/dashboards",
|
|
310
|
+
}),
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
expect(mocks.signA2AToken).toHaveBeenCalledWith(
|
|
314
|
+
"owner@example.test",
|
|
315
|
+
"builder.io",
|
|
316
|
+
"org-specific-secret",
|
|
317
|
+
{
|
|
318
|
+
expiresIn: "5m",
|
|
319
|
+
preferGlobalSecret: true,
|
|
320
|
+
},
|
|
321
|
+
);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it("surfaces target MCP embed-session errors", async () => {
|
|
325
|
+
mocks.managerCallTool.mockResolvedValueOnce({
|
|
326
|
+
isError: true,
|
|
327
|
+
content: [
|
|
328
|
+
{
|
|
329
|
+
type: "text",
|
|
330
|
+
text: "Error: create_embed_session requires an authenticated MCP caller.",
|
|
331
|
+
},
|
|
332
|
+
],
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
await expect(
|
|
336
|
+
runWithRequestContext(
|
|
337
|
+
{
|
|
338
|
+
userEmail: "owner@example.test",
|
|
339
|
+
requestOrigin: "http://localhost:8092",
|
|
340
|
+
},
|
|
341
|
+
() =>
|
|
342
|
+
createGrantedDispatchMcpEmbedSession({
|
|
343
|
+
app: "analytics",
|
|
344
|
+
path: "/dashboards",
|
|
345
|
+
}),
|
|
346
|
+
),
|
|
347
|
+
).rejects.toThrow(/authenticated MCP caller/);
|
|
348
|
+
});
|
|
295
349
|
});
|
|
@@ -338,6 +338,7 @@ function parseMcpToolTextResult(result: unknown): Record<string, unknown> {
|
|
|
338
338
|
(part) => part?.type === "text" && typeof part.text === "string",
|
|
339
339
|
)?.text;
|
|
340
340
|
if (typeof text === "string" && text.trim()) {
|
|
341
|
+
if ((result as any).isError) throw new Error(text.trim());
|
|
341
342
|
const parsed = JSON.parse(text);
|
|
342
343
|
if (parsed && typeof parsed === "object") return parsed;
|
|
343
344
|
}
|
|
@@ -464,7 +465,10 @@ export async function createGrantedDispatchMcpEmbedSession(input: {
|
|
|
464
465
|
orgSecret ?? undefined,
|
|
465
466
|
{
|
|
466
467
|
expiresIn: "5m",
|
|
467
|
-
|
|
468
|
+
// Target MCP endpoints verify A2A JWTs with the deployment-wide
|
|
469
|
+
// A2A_SECRET. Prefer it for hosted cross-app embeds even when Dispatch
|
|
470
|
+
// also has an org-level secret available.
|
|
471
|
+
preferGlobalSecret: true,
|
|
468
472
|
},
|
|
469
473
|
);
|
|
470
474
|
|