@agent-native/core 0.15.11 → 0.15.12
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/a2a/server.d.ts +1 -0
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +25 -13
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/types.d.ts +8 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js +0 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/action.d.ts +15 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +6 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +3 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent-web/config.d.ts +41 -0
- package/dist/agent-web/config.d.ts.map +1 -0
- package/dist/agent-web/config.js +162 -0
- package/dist/agent-web/config.js.map +1 -0
- package/dist/agent-web/generator.d.ts +95 -0
- package/dist/agent-web/generator.d.ts.map +1 -0
- package/dist/agent-web/generator.js +270 -0
- package/dist/agent-web/generator.js.map +1 -0
- package/dist/agent-web/index.d.ts +3 -0
- package/dist/agent-web/index.d.ts.map +1 -0
- package/dist/agent-web/index.js +3 -0
- package/dist/agent-web/index.js.map +1 -0
- package/dist/cli/audit-agent-web.d.ts +2 -0
- package/dist/cli/audit-agent-web.d.ts.map +1 -0
- package/dist/cli/audit-agent-web.js +201 -0
- package/dist/cli/audit-agent-web.js.map +1 -0
- package/dist/cli/index.js +17 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/migrate.d.ts +10 -0
- package/dist/cli/migrate.d.ts.map +1 -0
- package/dist/cli/migrate.js +78 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +12 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +6 -5
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +74 -9
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.spec.js +73 -0
- package/dist/client/settings/useBuilderStatus.spec.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +2 -0
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/vite/agent-web-plugin.d.ts +17 -0
- package/dist/vite/agent-web-plugin.d.ts.map +1 -0
- package/dist/vite/agent-web-plugin.js +48 -0
- package/dist/vite/agent-web-plugin.js.map +1 -0
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +1 -0
- package/dist/vite/index.js.map +1 -1
- package/docs/content/agent-web-surfaces.md +143 -0
- package/docs/content/migration-workbench.md +110 -0
- package/package.json +2 -1
- package/dist/client/dev-mode.d.ts +0 -14
- package/dist/client/dev-mode.d.ts.map +0 -1
- package/dist/client/dev-mode.js +0 -14
- package/dist/client/dev-mode.js.map +0 -1
- package/dist/client/extensions/EmbeddedTool.d.ts +0 -20
- package/dist/client/extensions/EmbeddedTool.d.ts.map +0 -1
- package/dist/client/extensions/EmbeddedTool.js +0 -199
- package/dist/client/extensions/EmbeddedTool.js.map +0 -1
- package/dist/client/extensions/ToolEditor.d.ts +0 -5
- package/dist/client/extensions/ToolEditor.d.ts.map +0 -1
- package/dist/client/extensions/ToolEditor.js +0 -129
- package/dist/client/extensions/ToolEditor.js.map +0 -1
- package/dist/client/extensions/ToolViewer.d.ts +0 -5
- package/dist/client/extensions/ToolViewer.d.ts.map +0 -1
- package/dist/client/extensions/ToolViewer.js +0 -400
- package/dist/client/extensions/ToolViewer.js.map +0 -1
- package/dist/client/extensions/ToolViewerPage.d.ts +0 -2
- package/dist/client/extensions/ToolViewerPage.d.ts.map +0 -1
- package/dist/client/extensions/ToolViewerPage.js +0 -24
- package/dist/client/extensions/ToolViewerPage.js.map +0 -1
- package/dist/client/extensions/ToolsListPage.d.ts +0 -2
- package/dist/client/extensions/ToolsListPage.d.ts.map +0 -1
- package/dist/client/extensions/ToolsListPage.js +0 -67
- package/dist/client/extensions/ToolsListPage.js.map +0 -1
- package/dist/client/extensions/ToolsSidebarSection.d.ts +0 -2
- package/dist/client/extensions/ToolsSidebarSection.d.ts.map +0 -1
- package/dist/client/extensions/ToolsSidebarSection.js +0 -236
- package/dist/client/extensions/ToolsSidebarSection.js.map +0 -1
- package/dist/client/extensions/tool-order.d.ts +0 -7
- package/dist/client/extensions/tool-order.d.ts.map +0 -1
- package/dist/client/extensions/tool-order.js +0 -47
- package/dist/client/extensions/tool-order.js.map +0 -1
- package/dist/client/tools/EmbeddedTool.d.ts +0 -20
- package/dist/client/tools/EmbeddedTool.d.ts.map +0 -1
- package/dist/client/tools/EmbeddedTool.js +0 -199
- package/dist/client/tools/EmbeddedTool.js.map +0 -1
- package/dist/client/tools/ExtensionSlot.d.ts +0 -27
- package/dist/client/tools/ExtensionSlot.d.ts.map +0 -1
- package/dist/client/tools/ExtensionSlot.js +0 -96
- package/dist/client/tools/ExtensionSlot.js.map +0 -1
- package/dist/client/tools/ToolEditor.d.ts +0 -5
- package/dist/client/tools/ToolEditor.d.ts.map +0 -1
- package/dist/client/tools/ToolEditor.js +0 -129
- package/dist/client/tools/ToolEditor.js.map +0 -1
- package/dist/client/tools/ToolViewer.d.ts +0 -5
- package/dist/client/tools/ToolViewer.d.ts.map +0 -1
- package/dist/client/tools/ToolViewer.js +0 -400
- package/dist/client/tools/ToolViewer.js.map +0 -1
- package/dist/client/tools/ToolViewerPage.d.ts +0 -2
- package/dist/client/tools/ToolViewerPage.d.ts.map +0 -1
- package/dist/client/tools/ToolViewerPage.js +0 -24
- package/dist/client/tools/ToolViewerPage.js.map +0 -1
- package/dist/client/tools/ToolsListPage.d.ts +0 -2
- package/dist/client/tools/ToolsListPage.d.ts.map +0 -1
- package/dist/client/tools/ToolsListPage.js +0 -67
- package/dist/client/tools/ToolsListPage.js.map +0 -1
- package/dist/client/tools/ToolsSidebarSection.d.ts +0 -2
- package/dist/client/tools/ToolsSidebarSection.d.ts.map +0 -1
- package/dist/client/tools/ToolsSidebarSection.js +0 -236
- package/dist/client/tools/ToolsSidebarSection.js.map +0 -1
- package/dist/client/tools/iframe-bridge.d.ts +0 -38
- package/dist/client/tools/iframe-bridge.d.ts.map +0 -1
- package/dist/client/tools/iframe-bridge.js +0 -207
- package/dist/client/tools/iframe-bridge.js.map +0 -1
- package/dist/client/tools/index.d.ts +0 -8
- package/dist/client/tools/index.d.ts.map +0 -1
- package/dist/client/tools/index.js +0 -8
- package/dist/client/tools/index.js.map +0 -1
- package/dist/client/tools/tool-order.d.ts +0 -7
- package/dist/client/tools/tool-order.d.ts.map +0 -1
- package/dist/client/tools/tool-order.js +0 -47
- package/dist/client/tools/tool-order.js.map +0 -1
- package/dist/server/local-migration.d.ts +0 -41
- package/dist/server/local-migration.d.ts.map +0 -1
- package/dist/server/local-migration.js +0 -235
- package/dist/server/local-migration.js.map +0 -1
- package/dist/tools/actions.d.ts +0 -3
- package/dist/tools/actions.d.ts.map +0 -1
- package/dist/tools/actions.js +0 -272
- package/dist/tools/actions.js.map +0 -1
- package/dist/tools/fetch-tool.d.ts +0 -23
- package/dist/tools/fetch-tool.d.ts.map +0 -1
- package/dist/tools/fetch-tool.js +0 -178
- package/dist/tools/fetch-tool.js.map +0 -1
- package/dist/tools/html-shell.d.ts +0 -45
- package/dist/tools/html-shell.d.ts.map +0 -1
- package/dist/tools/html-shell.js +0 -514
- package/dist/tools/html-shell.js.map +0 -1
- package/dist/tools/proxy-security.d.ts +0 -12
- package/dist/tools/proxy-security.d.ts.map +0 -1
- package/dist/tools/proxy-security.js +0 -158
- package/dist/tools/proxy-security.js.map +0 -1
- package/dist/tools/routes.d.ts +0 -2
- package/dist/tools/routes.d.ts.map +0 -1
- package/dist/tools/routes.js +0 -627
- package/dist/tools/routes.js.map +0 -1
- package/dist/tools/schema.d.ts +0 -664
- package/dist/tools/schema.d.ts.map +0 -1
- package/dist/tools/schema.js +0 -146
- package/dist/tools/schema.js.map +0 -1
- package/dist/tools/slots/routes.d.ts +0 -15
- package/dist/tools/slots/routes.d.ts.map +0 -1
- package/dist/tools/slots/routes.js +0 -94
- package/dist/tools/slots/routes.js.map +0 -1
- package/dist/tools/slots/schema.d.ts +0 -303
- package/dist/tools/slots/schema.d.ts.map +0 -1
- package/dist/tools/slots/schema.js +0 -76
- package/dist/tools/slots/schema.js.map +0 -1
- package/dist/tools/slots/store.d.ts +0 -66
- package/dist/tools/slots/store.d.ts.map +0 -1
- package/dist/tools/slots/store.js +0 -227
- package/dist/tools/slots/store.js.map +0 -1
- package/dist/tools/store.d.ts +0 -40
- package/dist/tools/store.d.ts.map +0 -1
- package/dist/tools/store.js +0 -193
- package/dist/tools/store.js.map +0 -1
- package/dist/tools/theme.d.ts +0 -2
- package/dist/tools/theme.d.ts.map +0 -1
- package/dist/tools/theme.js +0 -67
- package/dist/tools/theme.js.map +0 -1
- package/dist/tools/url-safety.d.ts +0 -24
- package/dist/tools/url-safety.d.ts.map +0 -1
- package/dist/tools/url-safety.js +0 -224
- package/dist/tools/url-safety.js.map +0 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import { type AgentWebInputConfig, type AgentWebPage } from "../agent-web/index.js";
|
|
3
|
+
export interface AgentWebVitePluginOptions {
|
|
4
|
+
siteName: string;
|
|
5
|
+
siteUrl: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
pages: AgentWebPage[] | (() => AgentWebPage[]);
|
|
8
|
+
agentWeb?: AgentWebInputConfig | boolean;
|
|
9
|
+
outputDirs?: string[];
|
|
10
|
+
organization?: {
|
|
11
|
+
name: string;
|
|
12
|
+
url?: string;
|
|
13
|
+
sameAs?: string[];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare function createAgentWebVitePlugin(options: AgentWebVitePluginOptions): Plugin;
|
|
17
|
+
//# sourceMappingURL=agent-web-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-web-plugin.d.ts","sourceRoot":"","sources":["../../src/vite/agent-web-plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,YAAY,EAAE,CAAC,CAAC;IAC/C,QAAQ,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,yBAAyB,GACjC,MAAM,CAiDR"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { buildAgentWebStaticFiles, normalizeAgentWebConfig, } from "../agent-web/index.js";
|
|
4
|
+
export function createAgentWebVitePlugin(options) {
|
|
5
|
+
let rootDir = process.cwd();
|
|
6
|
+
return {
|
|
7
|
+
name: "agent-web-surfaces",
|
|
8
|
+
apply: "build",
|
|
9
|
+
configResolved(config) {
|
|
10
|
+
rootDir = config.root;
|
|
11
|
+
},
|
|
12
|
+
closeBundle() {
|
|
13
|
+
const pages = typeof options.pages === "function" ? options.pages() : options.pages;
|
|
14
|
+
const config = normalizeAgentWebConfig(options.agentWeb ?? {}, {
|
|
15
|
+
hasPublicRoutes: pages.length > 0,
|
|
16
|
+
});
|
|
17
|
+
if (!config.discoverable)
|
|
18
|
+
return;
|
|
19
|
+
const files = buildAgentWebStaticFiles({
|
|
20
|
+
siteName: options.siteName,
|
|
21
|
+
siteUrl: options.siteUrl,
|
|
22
|
+
description: options.description,
|
|
23
|
+
pages,
|
|
24
|
+
config,
|
|
25
|
+
organization: options.organization,
|
|
26
|
+
});
|
|
27
|
+
const outputDirs = options.outputDirs ?? [
|
|
28
|
+
"public",
|
|
29
|
+
"dist",
|
|
30
|
+
"dist/client",
|
|
31
|
+
"dist/server/public",
|
|
32
|
+
"build/client",
|
|
33
|
+
];
|
|
34
|
+
for (const dir of outputDirs) {
|
|
35
|
+
const outDir = path.resolve(rootDir, dir);
|
|
36
|
+
if (!fs.existsSync(outDir))
|
|
37
|
+
continue;
|
|
38
|
+
for (const file of files) {
|
|
39
|
+
const outPath = path.resolve(outDir, file.path);
|
|
40
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
41
|
+
fs.writeFileSync(outPath, file.content);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
this.info(`[agent-web] Generated ${files.length} files for ${pages.length} public routes`);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=agent-web-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-web-plugin.js","sourceRoot":"","sources":["../../src/vite/agent-web-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EACL,wBAAwB,EACxB,uBAAuB,GAGxB,MAAM,uBAAuB,CAAC;AAgB/B,MAAM,UAAU,wBAAwB,CACtC,OAAkC;IAElC,IAAI,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE5B,OAAO;QACL,IAAI,EAAE,oBAAoB;QAC1B,KAAK,EAAE,OAAO;QACd,cAAc,CAAC,MAAM;YACnB,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC;QACxB,CAAC;QACD,WAAW;YACT,MAAM,KAAK,GACT,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;YACxE,MAAM,MAAM,GAAG,uBAAuB,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,EAAE;gBAC7D,eAAe,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC;aAClC,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,YAAY;gBAAE,OAAO;YAEjC,MAAM,KAAK,GAAG,wBAAwB,CAAC;gBACrC,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,KAAK;gBACL,MAAM;gBACN,YAAY,EAAE,OAAO,CAAC,YAAY;aACnC,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI;gBACvC,QAAQ;gBACR,MAAM;gBACN,aAAa;gBACb,oBAAoB;gBACpB,cAAc;aACf,CAAC;YAEF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBAC1C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;oBAAE,SAAS;gBACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;oBAChD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBACzD,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;YAED,IAAI,CAAC,IAAI,CACP,yBAAyB,KAAK,CAAC,MAAM,cAAc,KAAK,CAAC,MAAM,gBAAgB,CAChF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport type { Plugin } from \"vite\";\nimport {\n buildAgentWebStaticFiles,\n normalizeAgentWebConfig,\n type AgentWebInputConfig,\n type AgentWebPage,\n} from \"../agent-web/index.js\";\n\nexport interface AgentWebVitePluginOptions {\n siteName: string;\n siteUrl: string;\n description?: string;\n pages: AgentWebPage[] | (() => AgentWebPage[]);\n agentWeb?: AgentWebInputConfig | boolean;\n outputDirs?: string[];\n organization?: {\n name: string;\n url?: string;\n sameAs?: string[];\n };\n}\n\nexport function createAgentWebVitePlugin(\n options: AgentWebVitePluginOptions,\n): Plugin {\n let rootDir = process.cwd();\n\n return {\n name: \"agent-web-surfaces\",\n apply: \"build\",\n configResolved(config) {\n rootDir = config.root;\n },\n closeBundle() {\n const pages =\n typeof options.pages === \"function\" ? options.pages() : options.pages;\n const config = normalizeAgentWebConfig(options.agentWeb ?? {}, {\n hasPublicRoutes: pages.length > 0,\n });\n if (!config.discoverable) return;\n\n const files = buildAgentWebStaticFiles({\n siteName: options.siteName,\n siteUrl: options.siteUrl,\n description: options.description,\n pages,\n config,\n organization: options.organization,\n });\n\n const outputDirs = options.outputDirs ?? [\n \"public\",\n \"dist\",\n \"dist/client\",\n \"dist/server/public\",\n \"build/client\",\n ];\n\n for (const dir of outputDirs) {\n const outDir = path.resolve(rootDir, dir);\n if (!fs.existsSync(outDir)) continue;\n for (const file of files) {\n const outPath = path.resolve(outDir, file.path);\n fs.mkdirSync(path.dirname(outPath), { recursive: true });\n fs.writeFileSync(outPath, file.content);\n }\n }\n\n this.info(\n `[agent-web] Generated ${files.length} files for ${pages.length} public routes`,\n );\n },\n };\n}\n"]}
|
package/dist/vite/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { defineConfig, type ClientConfigOptions, type NitroOptions, } from "./client.js";
|
|
2
2
|
export { actionTypesPlugin, generateActionRegistryForProject, } from "./action-types-plugin.js";
|
|
3
3
|
export { agentsBundlePlugin } from "./agents-bundle-plugin.js";
|
|
4
|
+
export { createAgentWebVitePlugin, type AgentWebVitePluginOptions, } from "./agent-web-plugin.js";
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/vite/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,KAAK,yBAAyB,GAC/B,MAAM,uBAAuB,CAAC"}
|
package/dist/vite/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { defineConfig, } from "./client.js";
|
|
2
2
|
export { actionTypesPlugin, generateActionRegistryForProject, } from "./action-types-plugin.js";
|
|
3
3
|
export { agentsBundlePlugin } from "./agents-bundle-plugin.js";
|
|
4
|
+
export { createAgentWebVitePlugin, } from "./agent-web-plugin.js";
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/vite/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,GAGb,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["export {\n defineConfig,\n type ClientConfigOptions,\n type NitroOptions,\n} from \"./client.js\";\nexport {\n actionTypesPlugin,\n generateActionRegistryForProject,\n} from \"./action-types-plugin.js\";\nexport { agentsBundlePlugin } from \"./agents-bundle-plugin.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,GAGb,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,GAEzB,MAAM,uBAAuB,CAAC","sourcesContent":["export {\n defineConfig,\n type ClientConfigOptions,\n type NitroOptions,\n} from \"./client.js\";\nexport {\n actionTypesPlugin,\n generateActionRegistryForProject,\n} from \"./action-types-plugin.js\";\nexport { agentsBundlePlugin } from \"./agents-bundle-plugin.js\";\nexport {\n createAgentWebVitePlugin,\n type AgentWebVitePluginOptions,\n} from \"./agent-web-plugin.js\";\n"]}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Agent Web Surfaces"
|
|
3
|
+
description: "Make public routes crawlable, readable, citable, and optionally callable by agents."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent Web Surfaces
|
|
7
|
+
|
|
8
|
+
Agent Web surfaces make public Agent-Native routes easy for agents to crawl, read, cite, and eventually call. The goal is not to make every app endpoint public. The goal is to publish a clean public surface for pages that are already public, while keeping private data and tool access behind explicit controls.
|
|
9
|
+
|
|
10
|
+
The docs site is the reference implementation. It publishes:
|
|
11
|
+
|
|
12
|
+
- `/robots.txt` with a crawler policy that allows retrieval but disallows training by default.
|
|
13
|
+
- `/sitemap.xml` with absolute canonical URLs and `lastmod` when the source file exposes it.
|
|
14
|
+
- `/llms.txt` and `/llms-full.txt` for agent-friendly content discovery.
|
|
15
|
+
- Markdown mirrors such as `/docs/getting-started.md`.
|
|
16
|
+
- `Accept: text/markdown` responses for public docs pages after a production build.
|
|
17
|
+
- JSON-LD for base organization, website, and page metadata.
|
|
18
|
+
|
|
19
|
+
## Configuration
|
|
20
|
+
|
|
21
|
+
Add `agentWeb` under the existing workspace app config. The public route list is still derived from the app's route access settings; `agentWeb` controls how that public surface is represented to agents.
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"agent-native": {
|
|
26
|
+
"workspaceApp": {
|
|
27
|
+
"audience": "public",
|
|
28
|
+
"protectedPaths": ["/admin/*"],
|
|
29
|
+
"agentWeb": {
|
|
30
|
+
"discoverable": true,
|
|
31
|
+
"markdownTwins": true,
|
|
32
|
+
"llmsTxt": true,
|
|
33
|
+
"jsonLd": true,
|
|
34
|
+
"publicAgentCard": true,
|
|
35
|
+
"publicMcp": false,
|
|
36
|
+
"crawlerPolicy": "discoverable-no-training",
|
|
37
|
+
"crawlers": {
|
|
38
|
+
"training": "disallow",
|
|
39
|
+
"search": "allow",
|
|
40
|
+
"userTriggered": "allow",
|
|
41
|
+
"codingAgents": "allow",
|
|
42
|
+
"autonomousAgents": "allow"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
For most apps, leave the defaults alone. If an app has any public route, `discoverable` defaults on. The default crawler policy is "discoverable, not trainable": search, user-triggered retrieval, coding agents, and autonomous browsing agents are allowed; training crawlers are disallowed.
|
|
51
|
+
|
|
52
|
+
## Route Source Of Truth
|
|
53
|
+
|
|
54
|
+
Agent Web discovery follows the route access model:
|
|
55
|
+
|
|
56
|
+
- Public apps expose every route except `protectedPaths`.
|
|
57
|
+
- Internal apps expose only `publicPaths`.
|
|
58
|
+
- Public share and form pages can be readable by agents.
|
|
59
|
+
- Submitted private data, authenticated dashboards, and user/org state are never included just because a nearby page is public.
|
|
60
|
+
|
|
61
|
+
This keeps mixed apps natural. A forms app can expose a public form page and keep submissions private. A content app can expose published posts and keep the editor private. A docs site can expose everything except admin tools.
|
|
62
|
+
|
|
63
|
+
## Public Pages Are Not Public Tools
|
|
64
|
+
|
|
65
|
+
Public page access and public tool access are separate. A route being public only means agents can read that route as HTML, Markdown, sitemap entries, llms entries, and structured data.
|
|
66
|
+
|
|
67
|
+
To expose an action through a public agent protocol later, the action must opt in:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
export default defineAction({
|
|
71
|
+
description: "Search published docs",
|
|
72
|
+
readOnly: true,
|
|
73
|
+
publicAgent: {
|
|
74
|
+
expose: true,
|
|
75
|
+
readOnly: true,
|
|
76
|
+
requiresAuth: false,
|
|
77
|
+
isConsequential: false,
|
|
78
|
+
title: "Search published docs",
|
|
79
|
+
},
|
|
80
|
+
run: async (args) => {
|
|
81
|
+
// ...
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`agentWeb.publicMcp` stays `false` by default. When public MCP is enabled, the server should expose only actions with `publicAgent.expose === true`, and should still exclude consequential or write actions unless the action and auth policy explicitly allow them.
|
|
87
|
+
|
|
88
|
+
## Build-Time Files
|
|
89
|
+
|
|
90
|
+
Framework utilities in `@agent-native/core/agent-web` generate the common files from one page list:
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import {
|
|
94
|
+
buildAgentWebStaticFiles,
|
|
95
|
+
normalizeAgentWebConfig,
|
|
96
|
+
} from "@agent-native/core/agent-web";
|
|
97
|
+
|
|
98
|
+
const config = normalizeAgentWebConfig(
|
|
99
|
+
{ crawlerPolicy: "discoverable-no-training" },
|
|
100
|
+
{ hasPublicRoutes: true },
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const files = buildAgentWebStaticFiles({
|
|
104
|
+
siteName: "My Agent-Native App",
|
|
105
|
+
siteUrl: "https://example.com",
|
|
106
|
+
description: "Public docs for my app.",
|
|
107
|
+
config,
|
|
108
|
+
pages: [
|
|
109
|
+
{
|
|
110
|
+
path: "/docs",
|
|
111
|
+
title: "Docs",
|
|
112
|
+
description: "Start here.",
|
|
113
|
+
markdown: "# Docs\n\nStart here.\n",
|
|
114
|
+
markdownPath: "/docs/getting-started.md",
|
|
115
|
+
lastmod: new Date(),
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Vite apps can use `createAgentWebVitePlugin` from `@agent-native/core/vite` to write those files into `public`, `dist`, `dist/client`, `dist/server/public`, or `build/client` during production builds.
|
|
122
|
+
|
|
123
|
+
## Audit A Site
|
|
124
|
+
|
|
125
|
+
Use the CLI audit against a deployed site or a local production server:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
agent-native audit-agent-web --url https://www.agent-native.com
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The audit checks for:
|
|
132
|
+
|
|
133
|
+
- SSR-visible HTML.
|
|
134
|
+
- Canonical URLs.
|
|
135
|
+
- JSON-LD.
|
|
136
|
+
- `robots.txt` policy and absolute sitemap URL.
|
|
137
|
+
- Absolute sitemap entries.
|
|
138
|
+
- `/llms.txt` and `/llms-full.txt`.
|
|
139
|
+
- Markdown mirrors.
|
|
140
|
+
- `Accept: text/markdown`.
|
|
141
|
+
- No accidental 401/403 blocks for common agent retrieval user agents.
|
|
142
|
+
|
|
143
|
+
The audit exits non-zero if a required public surface is missing.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Migration Workbench"
|
|
3
|
+
description: "Use a local agent-native Workbench to migrate existing apps into agent-native with assessment, approval, generated output, and verification."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Migration Workbench
|
|
7
|
+
|
|
8
|
+
Migration Workbench is a local agent-native app for moving existing applications into the agent-native framework. It is designed for migrations where an agent can do useful work, but every important step should be auditable and verified.
|
|
9
|
+
|
|
10
|
+
The product promise is: **let the agent run, but prove it**.
|
|
11
|
+
|
|
12
|
+
V1 focuses on **Next.js to standalone agent-native**. Builder.io Publish and AEM exits are designed into the adapter interfaces, but are intended as follow-on enterprise adapters rather than the first shipped path.
|
|
13
|
+
|
|
14
|
+
## How It Works
|
|
15
|
+
|
|
16
|
+
Run:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
agent-native migrate ./my-next-app --out ../migrated-app
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The command scaffolds the hidden `migration` template and writes a seed file with the source and output paths. The Workbench UI then guides the run:
|
|
23
|
+
|
|
24
|
+
1. **Discover** reads the source project and creates `01-assessment.md`.
|
|
25
|
+
2. **Plan** creates recipe tasks and writes `02-plan.md` plus `03-tasks.md`.
|
|
26
|
+
3. **Approve** unlocks generated output writes.
|
|
27
|
+
4. **Sweep** runs migration tasks against the generated output project.
|
|
28
|
+
5. **Verify** runs deterministic checks and writes `04-report.md`.
|
|
29
|
+
|
|
30
|
+
The source project is read-only. Generated output is written to a separate `outputRoot`.
|
|
31
|
+
|
|
32
|
+
## Agent-Native Mapping
|
|
33
|
+
|
|
34
|
+
The V1 recipes are named after the framework contracts they enforce:
|
|
35
|
+
|
|
36
|
+
| Source pattern | Agent-native target |
|
|
37
|
+
| --------------------------- | ----------------------------------------------------------------- |
|
|
38
|
+
| API routes / server actions | `actions/`, except uploads, webhooks, OAuth, and streaming routes |
|
|
39
|
+
| app-owned data | Drizzle SQL tables plus actions |
|
|
40
|
+
| direct LLM calls | agent chat delegation |
|
|
41
|
+
| important client state | `application_state` navigation and selection |
|
|
42
|
+
| UI mutations | optimistic action mutations |
|
|
43
|
+
| shared resources | ownership, sharing, and access helpers |
|
|
44
|
+
| public pages | server rendering |
|
|
45
|
+
| logged-in workflows | persistent client app shell |
|
|
46
|
+
|
|
47
|
+
This is the difference between porting React code and actually migrating to agent-native.
|
|
48
|
+
|
|
49
|
+
## Adapter Model
|
|
50
|
+
|
|
51
|
+
`@agent-native/migrate` exposes a reusable engine:
|
|
52
|
+
|
|
53
|
+
- `SourceAdapter` detects and inventories existing projects.
|
|
54
|
+
- `TargetAdapter` scaffolds and verifies output.
|
|
55
|
+
- `MigrationRecipe` turns IR graph inventory into tasks.
|
|
56
|
+
- `Verifier` returns structured migration evidence.
|
|
57
|
+
|
|
58
|
+
The intermediate representation is split into four graphs:
|
|
59
|
+
|
|
60
|
+
- `SiteGraph`: routes, redirects, public/private classification, metadata.
|
|
61
|
+
- `ComponentGraph`: reusable UI components and design tokens.
|
|
62
|
+
- `ContentGraph`: CMS models, static content, and assets.
|
|
63
|
+
- `BehaviorGraph`: API endpoints, data stores, auth, jobs, client state, and LLM calls.
|
|
64
|
+
|
|
65
|
+
## Builder.io And AEM
|
|
66
|
+
|
|
67
|
+
Builder.io is a target decision, not a source assumption. Builder Publish should be used for marketing, docs, landing, and content surfaces. Transactional SaaS state, dashboards, app-owned data, and workflows stay in agent-native SQL/actions.
|
|
68
|
+
|
|
69
|
+
AEM support should be implemented as a source adapter family:
|
|
70
|
+
|
|
71
|
+
- `crawl`: URLs, sitemap, screenshots, SEO, redirects.
|
|
72
|
+
- `api`: AEM GraphQL Content Fragments and DAM metadata.
|
|
73
|
+
- `package`: Vault/JCR package parsing.
|
|
74
|
+
- `code`: HTL components, dialogs, templates, and policies.
|
|
75
|
+
- `enterprise`: combines available modes and emits confidence/gap reports.
|
|
76
|
+
|
|
77
|
+
AEM output is two-pipeline: content extraction into Builder or SQL, plus frontend regeneration and component mapping into agent-native UI.
|
|
78
|
+
|
|
79
|
+
## Verification
|
|
80
|
+
|
|
81
|
+
The default verifier path is deterministic:
|
|
82
|
+
|
|
83
|
+
- output file smoke checks
|
|
84
|
+
- route inventory parity artifacts
|
|
85
|
+
- agent-native conformance checks
|
|
86
|
+
- future Playwright smoke tests
|
|
87
|
+
- future visual, a11y, Lighthouse, SEO, and redirect checks
|
|
88
|
+
|
|
89
|
+
AI browser tools can help generate or repair flows, but deterministic Playwright-style checks should remain the truth oracle.
|
|
90
|
+
|
|
91
|
+
## Package Exports
|
|
92
|
+
|
|
93
|
+
Use the engine directly when building adapters or custom migration workflows:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import {
|
|
97
|
+
createMigrationRun,
|
|
98
|
+
discoverMigration,
|
|
99
|
+
planMigration,
|
|
100
|
+
nextjsSourceAdapter,
|
|
101
|
+
agentNativeTargetAdapter,
|
|
102
|
+
} from "@agent-native/migrate";
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Subpath exports are available for first-party V1 adapters:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { nextjsSourceAdapter } from "@agent-native/migrate/source-nextjs";
|
|
109
|
+
import { agentNativeTargetAdapter } from "@agent-native/migrate/target-agent-native";
|
|
110
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Framework for agent-native application development — where AI agents and UI share state via files",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"./server/agent-discovery": "./dist/server/agent-discovery.js",
|
|
32
32
|
"./server/request-context": "./dist/server/request-context.js",
|
|
33
33
|
"./server/design-token-utils": "./dist/server/design-token-utils.js",
|
|
34
|
+
"./agent-web": "./dist/agent-web/index.js",
|
|
34
35
|
"./db": "./dist/db/index.js",
|
|
35
36
|
"./db/schema": "./dist/db/schema.js",
|
|
36
37
|
"./db/drizzle-config": "./dist/db/drizzle-config.js",
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client-side mirror of the framework's dev-mode bypass identity.
|
|
3
|
-
*
|
|
4
|
-
* Mirrors `DEV_MODE_USER_EMAIL` from `packages/core/src/server/auth.ts`
|
|
5
|
-
* (the source of truth) so that React components and other client code
|
|
6
|
-
* can compare against it without importing from server-only modules.
|
|
7
|
-
*
|
|
8
|
-
* Use this when a client component needs to show / hide UI that is only
|
|
9
|
-
* meaningful when the user is running in local/dev mode (e.g. the
|
|
10
|
-
* "Migrate local data" prompt, the dev-only sign-in card, or hiding the
|
|
11
|
-
* org switcher when there is no real account yet).
|
|
12
|
-
*/
|
|
13
|
-
export declare const DEV_MODE_USER_EMAIL = "local@localhost";
|
|
14
|
-
//# sourceMappingURL=dev-mode.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-mode.d.ts","sourceRoot":"","sources":["../../src/client/dev-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,oBAAoB,CAAC"}
|
package/dist/client/dev-mode.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client-side mirror of the framework's dev-mode bypass identity.
|
|
3
|
-
*
|
|
4
|
-
* Mirrors `DEV_MODE_USER_EMAIL` from `packages/core/src/server/auth.ts`
|
|
5
|
-
* (the source of truth) so that React components and other client code
|
|
6
|
-
* can compare against it without importing from server-only modules.
|
|
7
|
-
*
|
|
8
|
-
* Use this when a client component needs to show / hide UI that is only
|
|
9
|
-
* meaningful when the user is running in local/dev mode (e.g. the
|
|
10
|
-
* "Migrate local data" prompt, the dev-only sign-in card, or hiding the
|
|
11
|
-
* org switcher when there is no real account yet).
|
|
12
|
-
*/
|
|
13
|
-
export const DEV_MODE_USER_EMAIL = "local@localhost"; // guard:allow-localhost-fallback — client-side mirror of the framework dev-mode identity defined in server/auth.ts; not a session-pooling fallback
|
|
14
|
-
//# sourceMappingURL=dev-mode.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-mode.js","sourceRoot":"","sources":["../../src/client/dev-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,CAAC,mJAAmJ","sourcesContent":["/**\n * Client-side mirror of the framework's dev-mode bypass identity.\n *\n * Mirrors `DEV_MODE_USER_EMAIL` from `packages/core/src/server/auth.ts`\n * (the source of truth) so that React components and other client code\n * can compare against it without importing from server-only modules.\n *\n * Use this when a client component needs to show / hide UI that is only\n * meaningful when the user is running in local/dev mode (e.g. the\n * \"Migrate local data\" prompt, the dev-only sign-in card, or hiding the\n * org switcher when there is no real account yet).\n */\nexport const DEV_MODE_USER_EMAIL = \"local@localhost\"; // guard:allow-localhost-fallback — client-side mirror of the framework dev-mode identity defined in server/auth.ts; not a session-pooling fallback\n"]}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export interface EmbeddedToolProps {
|
|
2
|
-
toolId: string;
|
|
3
|
-
/** Slot identifier passed via the iframe URL so the tool runtime knows it's
|
|
4
|
-
* embedded and enables auto-resize. */
|
|
5
|
-
slotId: string;
|
|
6
|
-
/** Object pushed into the tool as `window.slotContext`. Re-posted whenever
|
|
7
|
-
* the host re-renders with a new context. */
|
|
8
|
-
context?: Record<string, unknown> | null;
|
|
9
|
-
/** Optional className applied to the iframe container. */
|
|
10
|
-
className?: string;
|
|
11
|
-
/** Initial iframe height before content reports a real height. */
|
|
12
|
-
initialHeight?: number;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Renders a tool inline as a small auto-sized iframe — for use inside an
|
|
16
|
-
* `<ExtensionSlot>`. Different from `<ToolViewer>` (which is full-page with a
|
|
17
|
-
* toolbar): no header, sized to content, receives a `slotContext`.
|
|
18
|
-
*/
|
|
19
|
-
export declare function EmbeddedTool({ toolId, slotId, context, className, initialHeight, }: EmbeddedToolProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
-
//# sourceMappingURL=EmbeddedTool.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EmbeddedTool.d.ts","sourceRoot":"","sources":["../../../src/client/extensions/EmbeddedTool.tsx"],"names":[],"mappings":"AA8BA,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf;2CACuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf;iDAC6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,MAAM,EACN,OAAO,EACP,SAAS,EACT,aAAkB,GACnB,EAAE,iBAAiB,2CA6LnB"}
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { agentNativePath } from "../api-path.js";
|
|
3
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
5
|
-
import { useNavigate } from "react-router";
|
|
6
|
-
import { IconDots, IconExternalLink, IconLayoutSidebarRightCollapse, IconTrash, } from "@tabler/icons-react";
|
|
7
|
-
import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
|
|
8
|
-
import { isAllowedToolPath, sanitizeToolRequestOptions, checkBridgePolicy, } from "./iframe-bridge.js";
|
|
9
|
-
/**
|
|
10
|
-
* Renders a tool inline as a small auto-sized iframe — for use inside an
|
|
11
|
-
* `<ExtensionSlot>`. Different from `<ToolViewer>` (which is full-page with a
|
|
12
|
-
* toolbar): no header, sized to content, receives a `slotContext`.
|
|
13
|
-
*/
|
|
14
|
-
export function EmbeddedTool({ toolId, slotId, context, className, initialHeight = 80, }) {
|
|
15
|
-
const iframeRef = useRef(null);
|
|
16
|
-
const [height, setHeight] = useState(initialHeight);
|
|
17
|
-
const [isDark, setIsDark] = useState(false);
|
|
18
|
-
// (audit H4) Mirror ToolViewer's role-aware gating; deny-by-default until
|
|
19
|
-
// the iframe's render binding announcement arrives.
|
|
20
|
-
const bridgeContextRef = useRef({
|
|
21
|
-
role: "viewer",
|
|
22
|
-
isAuthor: false,
|
|
23
|
-
});
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
setIsDark(document.documentElement.classList.contains("dark"));
|
|
26
|
-
const observer = new MutationObserver(() => {
|
|
27
|
-
setIsDark(document.documentElement.classList.contains("dark"));
|
|
28
|
-
});
|
|
29
|
-
observer.observe(document.documentElement, {
|
|
30
|
-
attributes: true,
|
|
31
|
-
attributeFilter: ["class"],
|
|
32
|
-
});
|
|
33
|
-
return () => observer.disconnect();
|
|
34
|
-
}, []);
|
|
35
|
-
const { data: tool } = useQuery({
|
|
36
|
-
queryKey: ["tool", toolId],
|
|
37
|
-
queryFn: async () => {
|
|
38
|
-
const res = await fetch(agentNativePath(`/_agent-native/tools/${toolId}`));
|
|
39
|
-
if (!res.ok)
|
|
40
|
-
throw new Error("Failed to fetch tool");
|
|
41
|
-
return res.json();
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
const iframeSrc = useMemo(() => {
|
|
45
|
-
const v = encodeURIComponent(tool?.updatedAt ?? "");
|
|
46
|
-
return agentNativePath(`/_agent-native/tools/${toolId}/render?slot=${encodeURIComponent(slotId)}&dark=${isDark}&v=${v}`);
|
|
47
|
-
}, [toolId, slotId, isDark, tool?.updatedAt]);
|
|
48
|
-
// Forward slot context whenever it changes. The iframe's own load handler
|
|
49
|
-
// posts the initial value once it's ready; this effect handles updates.
|
|
50
|
-
const contextJson = JSON.stringify(context ?? {});
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
const win = iframeRef.current?.contentWindow;
|
|
53
|
-
if (!win)
|
|
54
|
-
return;
|
|
55
|
-
win.postMessage({ type: "agent-native-slot-context", context: context ?? {} }, "*");
|
|
56
|
-
}, [contextJson]);
|
|
57
|
-
// Bridge tool requests + height reports.
|
|
58
|
-
useEffect(() => {
|
|
59
|
-
const handleMessage = async (event) => {
|
|
60
|
-
if (event.source !== iframeRef.current?.contentWindow)
|
|
61
|
-
return;
|
|
62
|
-
const message = event.data;
|
|
63
|
-
if (!message || typeof message !== "object")
|
|
64
|
-
return;
|
|
65
|
-
if (message.type === "agent-native-tool-binding") {
|
|
66
|
-
const binding = message.binding ?? {};
|
|
67
|
-
const role = binding.role === "owner" ||
|
|
68
|
-
binding.role === "admin" ||
|
|
69
|
-
binding.role === "editor" ||
|
|
70
|
-
binding.role === "viewer"
|
|
71
|
-
? binding.role
|
|
72
|
-
: "viewer";
|
|
73
|
-
bridgeContextRef.current = {
|
|
74
|
-
role,
|
|
75
|
-
isAuthor: !!binding.isAuthor,
|
|
76
|
-
};
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
if (message.type === "agent-native-tool-resize") {
|
|
80
|
-
const h = Number(message.height);
|
|
81
|
-
if (Number.isFinite(h) && h > 0) {
|
|
82
|
-
setHeight(Math.ceil(h));
|
|
83
|
-
}
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
if (message.type !== "agent-native-tool-request")
|
|
87
|
-
return;
|
|
88
|
-
const requestId = String(message.requestId ?? "");
|
|
89
|
-
const path = String(message.path ?? "");
|
|
90
|
-
const respond = (payload) => {
|
|
91
|
-
iframeRef.current?.contentWindow?.postMessage({ type: "agent-native-tool-response", requestId, ...payload }, "*");
|
|
92
|
-
};
|
|
93
|
-
if (!requestId || !isAllowedToolPath(path, toolId)) {
|
|
94
|
-
respond({ error: "Tool request path is not allowed" });
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
try {
|
|
98
|
-
const options = sanitizeToolRequestOptions(message.options);
|
|
99
|
-
// (audit H4) Role-aware gating: viewer-shared tools can read but not
|
|
100
|
-
// write. The bridge policy is decided here in the parent before the
|
|
101
|
-
// request leaves; the server enforces a second layer.
|
|
102
|
-
const policy = checkBridgePolicy(path, options.method ?? "GET", bridgeContextRef.current);
|
|
103
|
-
if (!policy.ok) {
|
|
104
|
-
respond({
|
|
105
|
-
response: {
|
|
106
|
-
ok: false,
|
|
107
|
-
status: 403,
|
|
108
|
-
statusText: "Forbidden",
|
|
109
|
-
body: { error: policy.error },
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
// (audit H5) Same tool-bridge tagging as <ToolViewer>. action-routes
|
|
115
|
-
// uses these headers to enforce per-action `toolCallable` opt-in.
|
|
116
|
-
const finalHeaders = new Headers(options.headers ?? undefined);
|
|
117
|
-
finalHeaders.set("X-Agent-Native-Tool-Bridge", "1");
|
|
118
|
-
finalHeaders.set("X-Agent-Native-Tool-Id", toolId);
|
|
119
|
-
const res = await fetch(agentNativePath(path), {
|
|
120
|
-
...options,
|
|
121
|
-
headers: finalHeaders,
|
|
122
|
-
credentials: "same-origin",
|
|
123
|
-
});
|
|
124
|
-
const text = await res.text();
|
|
125
|
-
let body = text;
|
|
126
|
-
if (text) {
|
|
127
|
-
try {
|
|
128
|
-
body = JSON.parse(text);
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
body = text;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
respond({
|
|
135
|
-
response: {
|
|
136
|
-
ok: res.ok,
|
|
137
|
-
status: res.status,
|
|
138
|
-
statusText: res.statusText,
|
|
139
|
-
body,
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
catch (err) {
|
|
144
|
-
respond({ error: err?.message ?? "Tool host request failed" });
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
window.addEventListener("message", handleMessage);
|
|
148
|
-
return () => window.removeEventListener("message", handleMessage);
|
|
149
|
-
}, [toolId]);
|
|
150
|
-
if (!tool) {
|
|
151
|
-
return (_jsx("div", { className: className, style: { height: initialHeight }, "aria-busy": "true" }));
|
|
152
|
-
}
|
|
153
|
-
return (_jsxs("div", { className: `relative group/embedded-tool ${className ?? ""}`, children: [_jsx("iframe", { ref: iframeRef, src: iframeSrc, title: tool.name, sandbox: "allow-scripts allow-forms", style: { width: "100%", border: 0, height, display: "block" }, onLoad: () => {
|
|
154
|
-
iframeRef.current?.contentWindow?.postMessage({ type: "agent-native-slot-context", context: context ?? {} }, "*");
|
|
155
|
-
} }, `${toolId}-${tool.updatedAt ?? ""}`), _jsx(EmbeddedToolMenu, { toolId: toolId, slotId: slotId, toolName: tool.name })] }));
|
|
156
|
-
}
|
|
157
|
-
function EmbeddedToolMenu({ toolId, slotId, toolName, }) {
|
|
158
|
-
const [open, setOpen] = useState(false);
|
|
159
|
-
const [confirmingDelete, setConfirmingDelete] = useState(false);
|
|
160
|
-
const queryClient = useQueryClient();
|
|
161
|
-
const navigate = useNavigate();
|
|
162
|
-
const closeMenu = () => {
|
|
163
|
-
setOpen(false);
|
|
164
|
-
setConfirmingDelete(false);
|
|
165
|
-
};
|
|
166
|
-
const removeFromSlot = async () => {
|
|
167
|
-
closeMenu();
|
|
168
|
-
queryClient.setQueryData(["slot-installs", slotId], (old) => (old ?? []).filter((i) => i.toolId !== toolId));
|
|
169
|
-
try {
|
|
170
|
-
await fetch(agentNativePath(`/_agent-native/slots/${encodeURIComponent(slotId)}/install/${encodeURIComponent(toolId)}`), { method: "DELETE" });
|
|
171
|
-
}
|
|
172
|
-
finally {
|
|
173
|
-
queryClient.invalidateQueries({ queryKey: ["slot-installs", slotId] });
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
const deleteTool = async () => {
|
|
177
|
-
closeMenu();
|
|
178
|
-
queryClient.setQueryData(["slot-installs", slotId], (old) => (old ?? []).filter((i) => i.toolId !== toolId));
|
|
179
|
-
try {
|
|
180
|
-
await fetch(agentNativePath(`/_agent-native/tools/${toolId}`), {
|
|
181
|
-
method: "DELETE",
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
finally {
|
|
185
|
-
queryClient.invalidateQueries({ queryKey: ["slot-installs", slotId] });
|
|
186
|
-
queryClient.invalidateQueries({ queryKey: ["tool", toolId] });
|
|
187
|
-
queryClient.invalidateQueries({ queryKey: ["tools"] });
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
return (_jsxs(Popover, { open: open, onOpenChange: (o) => {
|
|
191
|
-
setOpen(o);
|
|
192
|
-
if (!o)
|
|
193
|
-
setConfirmingDelete(false);
|
|
194
|
-
}, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "absolute top-1 right-1 flex h-6 w-6 items-center justify-center rounded-md bg-background/60 text-muted-foreground/60 opacity-0 hover:bg-accent hover:text-foreground hover:opacity-100 group-hover/embedded-tool:opacity-100 cursor-pointer transition-opacity", title: `${toolName} options`, "aria-label": `${toolName} options`, children: _jsx(IconDots, { className: "h-3.5 w-3.5" }) }) }), _jsx(PopoverContent, { align: "end", sideOffset: 4, className: "w-56 p-1", children: !confirmingDelete ? (_jsxs("div", { className: "flex flex-col", children: [_jsxs("button", { type: "button", onClick: () => {
|
|
195
|
-
closeMenu();
|
|
196
|
-
navigate(`/tools/${toolId}`);
|
|
197
|
-
}, className: "flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] hover:bg-accent cursor-pointer text-left", children: [_jsx(IconExternalLink, { className: "h-3.5 w-3.5" }), _jsx("span", { children: "Open full view" })] }), _jsxs("button", { type: "button", onClick: removeFromSlot, className: "flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] hover:bg-accent cursor-pointer text-left", children: [_jsx(IconLayoutSidebarRightCollapse, { className: "h-3.5 w-3.5" }), _jsx("span", { children: "Remove from this widget area" })] }), _jsx("div", { className: "my-1 h-px bg-border/40" }), _jsxs("button", { type: "button", onClick: () => setConfirmingDelete(true), className: "flex items-center gap-2 rounded-sm px-2 py-1.5 text-[12px] text-destructive hover:bg-destructive/10 cursor-pointer text-left", children: [_jsx(IconTrash, { className: "h-3.5 w-3.5" }), _jsx("span", { children: "Delete tool\u2026" })] })] })) : (_jsxs("div", { className: "flex flex-col gap-2 p-2", children: [_jsxs("p", { className: "text-[12px]", children: ["Delete ", _jsx("span", { className: "font-medium", children: toolName }), "? This removes the tool everywhere, for everyone it's shared with."] }), _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx("button", { type: "button", onClick: () => setConfirmingDelete(false), className: "rounded-md px-2 py-1 text-[12px] hover:bg-accent cursor-pointer", children: "Cancel" }), _jsx("button", { type: "button", onClick: deleteTool, className: "rounded-md bg-destructive px-2 py-1 text-[12px] text-destructive-foreground hover:bg-destructive/90 cursor-pointer", children: "Delete" })] })] })) })] }));
|
|
198
|
-
}
|
|
199
|
-
//# sourceMappingURL=EmbeddedTool.js.map
|