@agent-native/dispatch 0.2.11 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/actions/create-workspace-resource.js +4 -4
  2. package/dist/actions/create-workspace-resource.js.map +1 -1
  3. package/dist/actions/grant-workspace-resources-to-app.d.ts +3 -0
  4. package/dist/actions/grant-workspace-resources-to-app.d.ts.map +1 -0
  5. package/dist/actions/grant-workspace-resources-to-app.js +15 -0
  6. package/dist/actions/grant-workspace-resources-to-app.js.map +1 -0
  7. package/dist/actions/index.d.ts.map +1 -1
  8. package/dist/actions/index.js +4 -0
  9. package/dist/actions/index.js.map +1 -1
  10. package/dist/actions/list-workspace-resource-options.d.ts +3 -0
  11. package/dist/actions/list-workspace-resource-options.d.ts.map +1 -0
  12. package/dist/actions/list-workspace-resource-options.js +15 -0
  13. package/dist/actions/list-workspace-resource-options.js.map +1 -0
  14. package/dist/actions/list-workspace-resources.js +2 -2
  15. package/dist/actions/list-workspace-resources.js.map +1 -1
  16. package/dist/actions/start-workspace-app-creation.d.ts.map +1 -1
  17. package/dist/actions/start-workspace-app-creation.js +6 -1
  18. package/dist/actions/start-workspace-app-creation.js.map +1 -1
  19. package/dist/actions/view-screen.d.ts.map +1 -1
  20. package/dist/actions/view-screen.js +4 -0
  21. package/dist/actions/view-screen.js.map +1 -1
  22. package/dist/components/app-keys-popover.js +3 -3
  23. package/dist/components/app-keys-popover.js.map +1 -1
  24. package/dist/components/create-app-popover.d.ts +1 -1
  25. package/dist/components/create-app-popover.d.ts.map +1 -1
  26. package/dist/components/create-app-popover.js +66 -21
  27. package/dist/components/create-app-popover.js.map +1 -1
  28. package/dist/components/workspace-app-card.d.ts +6 -0
  29. package/dist/components/workspace-app-card.d.ts.map +1 -0
  30. package/dist/components/workspace-app-card.js +12 -0
  31. package/dist/components/workspace-app-card.js.map +1 -0
  32. package/dist/db/schema.js +2 -2
  33. package/dist/db/schema.js.map +1 -1
  34. package/dist/lib/workspace-apps.d.ts +15 -0
  35. package/dist/lib/workspace-apps.d.ts.map +1 -0
  36. package/dist/lib/workspace-apps.js +9 -0
  37. package/dist/lib/workspace-apps.js.map +1 -0
  38. package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
  39. package/dist/routes/pages/apps.$appId.js +1 -5
  40. package/dist/routes/pages/apps.$appId.js.map +1 -1
  41. package/dist/routes/pages/apps.d.ts.map +1 -1
  42. package/dist/routes/pages/apps.js +3 -20
  43. package/dist/routes/pages/apps.js.map +1 -1
  44. package/dist/routes/pages/overview.d.ts.map +1 -1
  45. package/dist/routes/pages/overview.js +2 -20
  46. package/dist/routes/pages/overview.js.map +1 -1
  47. package/dist/routes/pages/workspace.d.ts.map +1 -1
  48. package/dist/routes/pages/workspace.js +17 -6
  49. package/dist/routes/pages/workspace.js.map +1 -1
  50. package/dist/server/lib/app-creation-store.d.ts +1 -0
  51. package/dist/server/lib/app-creation-store.d.ts.map +1 -1
  52. package/dist/server/lib/app-creation-store.js +36 -0
  53. package/dist/server/lib/app-creation-store.js.map +1 -1
  54. package/dist/server/lib/workspace-resources-store.d.ts +29 -1
  55. package/dist/server/lib/workspace-resources-store.d.ts.map +1 -1
  56. package/dist/server/lib/workspace-resources-store.js +46 -0
  57. package/dist/server/lib/workspace-resources-store.js.map +1 -1
  58. package/dist/server/plugins/agent-chat.d.ts.map +1 -1
  59. package/dist/server/plugins/agent-chat.js +1 -0
  60. package/dist/server/plugins/agent-chat.js.map +1 -1
  61. package/dist/server/plugins/integrations.d.ts.map +1 -1
  62. package/dist/server/plugins/integrations.js +2 -0
  63. package/dist/server/plugins/integrations.js.map +1 -1
  64. package/package.json +2 -2
  65. package/src/actions/create-workspace-resource.ts +4 -4
  66. package/src/actions/grant-workspace-resources-to-app.ts +16 -0
  67. package/src/actions/index.ts +4 -0
  68. package/src/actions/list-workspace-resource-options.ts +16 -0
  69. package/src/actions/list-workspace-resources.ts +2 -2
  70. package/src/actions/start-workspace-app-creation.ts +8 -1
  71. package/src/actions/view-screen.ts +4 -0
  72. package/src/components/app-keys-popover.tsx +3 -3
  73. package/src/components/create-app-popover.tsx +155 -22
  74. package/src/components/workspace-app-card.tsx +85 -0
  75. package/src/db/schema.ts +2 -2
  76. package/src/lib/workspace-apps.ts +21 -0
  77. package/src/routes/pages/apps.$appId.tsx +4 -17
  78. package/src/routes/pages/apps.tsx +6 -89
  79. package/src/routes/pages/overview.tsx +5 -84
  80. package/src/routes/pages/workspace.tsx +31 -5
  81. package/src/server/lib/app-creation-store.ts +52 -0
  82. package/src/server/lib/workspace-resources-store.ts +75 -1
  83. package/src/server/plugins/agent-chat.ts +1 -0
  84. package/src/server/plugins/integrations.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"apps.$appId.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.$appId.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo } from \"react\";\nimport { Link, useParams } from \"react-router\";\nimport { useActionQuery } from \"@agent-native/core/client\";\nimport {\n IconArrowLeft,\n IconArrowUpRight,\n IconClockHour4,\n} from \"@tabler/icons-react\";\nimport { DispatchShell } from \"@/components/dispatch-shell\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface WorkspaceAppSummary {\n id: string;\n name: string;\n description?: string;\n path: string;\n url?: string | null;\n status?: \"ready\" | \"pending\";\n statusLabel?: string;\n builderUrl?: string | null;\n branchName?: string | null;\n}\n\nfunction workspaceAppHref(app: WorkspaceAppSummary): string | null {\n if (app.status === \"pending\") return app.builderUrl || null;\n return app.path || app.url || null;\n}\n\nexport function meta() {\n return [{ title: \"Workspace app - Dispatch\" }];\n}\n\nexport default function WorkspaceAppRoute() {\n const { appId } = useParams();\n const { data: apps = [], isLoading } = useActionQuery(\n \"list-workspace-apps\",\n { includeAgentCards: false },\n {\n refetchInterval: 2_000,\n },\n );\n const app = useMemo(\n () =>\n (apps as WorkspaceAppSummary[]).find((item) => item.id === appId) ?? null,\n [appId, apps],\n );\n const href = app ? workspaceAppHref(app) : null;\n\n useEffect(() => {\n if (!app || app.status === \"pending\" || !href) return;\n window.location.assign(href);\n }, [app, href]);\n\n return (\n <DispatchShell\n title={app?.name || \"Workspace App\"}\n description=\"Open a deployed app or check the status of an app being created.\"\n >\n <div className=\"max-w-2xl rounded-lg border bg-card p-5\">\n <Button asChild size=\"sm\" variant=\"ghost\" className=\"-ml-2 mb-4\">\n <Link to=\"/apps\">\n <IconArrowLeft size={15} className=\"mr-1.5\" />\n Apps\n </Link>\n </Button>\n\n {isLoading && !app ? (\n <p className=\"text-sm text-muted-foreground\">Loading app status...</p>\n ) : !app ? (\n <div className=\"space-y-3\">\n <h2 className=\"text-base font-semibold text-foreground\">\n App not found\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n This route is not in the workspace app list yet.\n </p>\n </div>\n ) : app.status === \"pending\" ? (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-base font-semibold text-foreground\">\n {app.name}\n </h2>\n <Badge\n variant=\"outline\"\n className=\"gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n <IconClockHour4 size={12} />\n Building\n </Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n This app is being created. It will be available at{\" \"}\n <span className=\"font-mono text-foreground\">{app.path}</span>{\" \"}\n after its branch is merged and the workspace deploy finishes.\n </p>\n {app.branchName ? (\n <p className=\"text-xs text-muted-foreground\">\n Branch: {app.branchName}\n </p>\n ) : null}\n {app.builderUrl ? (\n <Button asChild>\n <a href={app.builderUrl} target=\"_blank\" rel=\"noreferrer\">\n Open Builder branch\n <IconArrowUpRight size={15} className=\"ml-1.5\" />\n </a>\n </Button>\n ) : null}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <h2 className=\"text-base font-semibold text-foreground\">\n Opening {app.name}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n Redirecting to{\" \"}\n <span className=\"font-mono text-foreground\">{app.path}</span>.\n </p>\n {href ? (\n <Button asChild>\n <a href={href}>\n Open app\n <IconArrowUpRight size={15} className=\"ml-1.5\" />\n </a>\n </Button>\n ) : null}\n </div>\n )}\n </div>\n </DispatchShell>\n );\n}\n"]}
1
+ {"version":3,"file":"apps.$appId.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.$appId.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo } from \"react\";\nimport { Link, useParams } from \"react-router\";\nimport { useActionQuery } from \"@agent-native/core/client\";\nimport {\n IconArrowLeft,\n IconArrowUpRight,\n IconClockHour4,\n} from \"@tabler/icons-react\";\nimport { DispatchShell } from \"@/components/dispatch-shell\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n workspaceAppHref,\n type WorkspaceAppSummary,\n} from \"@/lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Workspace app - Dispatch\" }];\n}\n\nexport default function WorkspaceAppRoute() {\n const { appId } = useParams();\n const { data: apps = [], isLoading } = useActionQuery(\n \"list-workspace-apps\",\n { includeAgentCards: false },\n {\n refetchInterval: 2_000,\n },\n );\n const app = useMemo(\n () =>\n (apps as WorkspaceAppSummary[]).find((item) => item.id === appId) ?? null,\n [appId, apps],\n );\n const href = app ? workspaceAppHref(app) : null;\n\n useEffect(() => {\n if (!app || app.status === \"pending\" || !href) return;\n window.location.assign(href);\n }, [app, href]);\n\n return (\n <DispatchShell\n title={app?.name || \"Workspace App\"}\n description=\"Open a deployed app or check the status of an app being created.\"\n >\n <div className=\"max-w-2xl rounded-lg border bg-card p-5\">\n <Button asChild size=\"sm\" variant=\"ghost\" className=\"-ml-2 mb-4\">\n <Link to=\"/apps\">\n <IconArrowLeft size={15} className=\"mr-1.5\" />\n Apps\n </Link>\n </Button>\n\n {isLoading && !app ? (\n <p className=\"text-sm text-muted-foreground\">Loading app status...</p>\n ) : !app ? (\n <div className=\"space-y-3\">\n <h2 className=\"text-base font-semibold text-foreground\">\n App not found\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n This route is not in the workspace app list yet.\n </p>\n </div>\n ) : app.status === \"pending\" ? (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-base font-semibold text-foreground\">\n {app.name}\n </h2>\n <Badge\n variant=\"outline\"\n className=\"gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n <IconClockHour4 size={12} />\n Building\n </Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n This app is being created. It will be available at{\" \"}\n <span className=\"font-mono text-foreground\">{app.path}</span>{\" \"}\n after its branch is merged and the workspace deploy finishes.\n </p>\n {app.branchName ? (\n <p className=\"text-xs text-muted-foreground\">\n Branch: {app.branchName}\n </p>\n ) : null}\n {app.builderUrl ? (\n <Button asChild>\n <a href={app.builderUrl} target=\"_blank\" rel=\"noreferrer\">\n Open Builder branch\n <IconArrowUpRight size={15} className=\"ml-1.5\" />\n </a>\n </Button>\n ) : null}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <h2 className=\"text-base font-semibold text-foreground\">\n Opening {app.name}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n Redirecting to{\" \"}\n <span className=\"font-mono text-foreground\">{app.path}</span>.\n </p>\n {href ? (\n <Button asChild>\n <a href={href}>\n Open app\n <IconArrowUpRight size={15} className=\"ml-1.5\" />\n </a>\n </Button>\n ) : null}\n </div>\n )}\n </div>\n </DispatchShell>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"AAmCA,wBAAgB,IAAI;;IAEnB;AAQD,MAAM,CAAC,OAAO,UAAU,SAAS,4CAqHhC"}
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"AAQA,wBAAgB,IAAI;;IAEnB;AAQD,MAAM,CAAC,OAAO,UAAU,SAAS,4CA6DhC"}
@@ -1,19 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useActionQuery } from "@agent-native/core/client";
3
- import { IconArrowUpRight, IconApps, IconClockHour4, IconPlus, } from "@tabler/icons-react";
4
- import { AppKeysPopover } from "../../components/app-keys-popover.js";
3
+ import { IconApps, IconPlus } from "@tabler/icons-react";
5
4
  import { CreateAppPopover } from "../../components/create-app-popover.js";
6
5
  import { DispatchShell } from "../../components/dispatch-shell.js";
7
- import { Badge } from "../../components/ui/badge.js";
6
+ import { WorkspaceAppCard } from "../../components/workspace-app-card.js";
8
7
  import { Button } from "../../components/ui/button.js";
9
- function workspaceAppHref(app) {
10
- if (app.status === "pending")
11
- return app.builderUrl || null;
12
- return app.path || app.url || null;
13
- }
14
- function isPendingBuilderHref(app) {
15
- return app.status === "pending" && !!app.builderUrl;
16
- }
17
8
  export function meta() {
18
9
  return [{ title: "Apps — Dispatch" }];
19
10
  }
@@ -29,14 +20,6 @@ export default function AppsRoute() {
29
20
  ? `Apps in the "${workspaceLabel}" workspace. Each app gets its own route under this workspace and shares its database, auth, and agent chat.`
30
21
  : "Open workspace apps and start new app creation from Dispatch.", children: _jsx("div", { className: "space-y-4", children: _jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(IconApps, { size: 16, className: "text-muted-foreground" }), _jsx("h2", { className: "text-sm font-semibold text-foreground", children: workspaceLabel
31
22
  ? `Apps in ${workspaceLabel}`
32
- : "Workspace apps" })] }), _jsx(CreateAppPopover, { align: "end", trigger: _jsxs(Button, { size: "sm", variant: "outline", children: [_jsx(IconPlus, { size: 15, className: "mr-1.5" }), "App"] }) })] }), _jsxs("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-3", children: [typedApps.map((app) => {
33
- const href = workspaceAppHref(app);
34
- // Pending Builder branches live on a different host; open
35
- // those in a new tab. Ready workspace apps stay in-window
36
- // so the cards work inside the Builder webview, where new
37
- // tabs would escape to the host browser.
38
- const openInNewTab = isPendingBuilderHref(app);
39
- return (_jsx("a", { href: href ?? undefined, target: openInNewTab ? "_blank" : undefined, rel: openInNewTab ? "noreferrer" : undefined, "aria-disabled": !href, className: "group rounded-lg border bg-card p-4 transition hover:border-foreground/30 aria-disabled:pointer-events-none aria-disabled:opacity-60", children: _jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("h3", { className: "truncate text-sm font-semibold text-foreground", children: app.name }), app.status === "pending" ? (_jsxs(Badge, { variant: "outline", className: "shrink-0 gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300", children: [_jsx(IconClockHour4, { size: 12 }), "Building"] })) : null] }), _jsx("p", { className: "mt-1 truncate font-mono text-xs text-muted-foreground", children: app.path }), app.status === "pending" && app.branchName ? (_jsxs("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: ["Branch: ", app.branchName] })) : null, app.description ? (_jsx("p", { className: "mt-2 line-clamp-2 text-xs leading-relaxed text-muted-foreground", children: app.description })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [app.status === "ready" ? (_jsx(AppKeysPopover, { appId: app.id, appName: app.name })) : null, _jsx(IconArrowUpRight, { size: 16, className: "text-muted-foreground transition group-hover:text-foreground" })] })] }) }, app.id));
40
- }), _jsx(CreateAppPopover, {})] })] }) }) }));
23
+ : "Workspace apps" })] }), _jsx(CreateAppPopover, { align: "end", trigger: _jsxs(Button, { size: "sm", variant: "outline", children: [_jsx(IconPlus, { size: 15, className: "mr-1.5" }), "App"] }) })] }), _jsxs("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-3", children: [typedApps.map((app) => (_jsx(WorkspaceAppCard, { app: app }, app.id))), _jsx(CreateAppPopover, {})] })] }) }) }));
41
24
  }
42
25
  //# sourceMappingURL=apps.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client\";\nimport {\n IconArrowUpRight,\n IconApps,\n IconClockHour4,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { AppKeysPopover } from \"@/components/app-keys-popover\";\nimport { CreateAppPopover } from \"@/components/create-app-popover\";\nimport { DispatchShell } from \"@/components/dispatch-shell\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface WorkspaceAppSummary {\n id: string;\n name: string;\n description?: string;\n path: string;\n url?: string | null;\n isDispatch: boolean;\n status?: \"ready\" | \"pending\";\n statusLabel?: string;\n builderUrl?: string | null;\n branchName?: string | null;\n}\n\nfunction workspaceAppHref(app: WorkspaceAppSummary): string | null {\n if (app.status === \"pending\") return app.builderUrl || null;\n return app.path || app.url || null;\n}\n\nfunction isPendingBuilderHref(app: WorkspaceAppSummary): boolean {\n return app.status === \"pending\" && !!app.builderUrl;\n}\n\nexport function meta() {\n return [{ title: \"Apps — Dispatch\" }];\n}\n\ninterface WorkspaceInfo {\n name: string | null;\n displayName: string | null;\n appCount: number;\n}\n\nexport default function AppsRoute() {\n const { data: apps = [] } = useActionQuery(\n \"list-workspace-apps\",\n { includeAgentCards: false },\n {\n refetchInterval: 2_000,\n },\n );\n const { data: workspace } = useActionQuery(\n \"get-workspace-info\",\n {},\n { staleTime: 60_000 },\n );\n const ws = workspace as WorkspaceInfo | undefined;\n const workspaceLabel = ws?.displayName ?? ws?.name ?? null;\n const typedApps = (apps as WorkspaceAppSummary[]).filter(\n (app) => !app.isDispatch,\n );\n\n return (\n <DispatchShell\n title=\"Apps\"\n description={\n workspaceLabel\n ? `Apps in the \"${workspaceLabel}\" workspace. Each app gets its own route under this workspace and shares its database, auth, and agent chat.`\n : \"Open workspace apps and start new app creation from Dispatch.\"\n }\n >\n <div className=\"space-y-4\">\n <section className=\"space-y-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <IconApps size={16} className=\"text-muted-foreground\" />\n <h2 className=\"text-sm font-semibold text-foreground\">\n {workspaceLabel\n ? `Apps in ${workspaceLabel}`\n : \"Workspace apps\"}\n </h2>\n </div>\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n App\n </Button>\n }\n />\n </div>\n\n <div className=\"grid gap-3 md:grid-cols-2 xl:grid-cols-3\">\n {typedApps.map((app) => {\n const href = workspaceAppHref(app);\n // Pending Builder branches live on a different host; open\n // those in a new tab. Ready workspace apps stay in-window\n // so the cards work inside the Builder webview, where new\n // tabs would escape to the host browser.\n const openInNewTab = isPendingBuilderHref(app);\n return (\n <a\n key={app.id}\n href={href ?? undefined}\n target={openInNewTab ? \"_blank\" : undefined}\n rel={openInNewTab ? \"noreferrer\" : undefined}\n aria-disabled={!href}\n className=\"group rounded-lg border bg-card p-4 transition hover:border-foreground/30 aria-disabled:pointer-events-none aria-disabled:opacity-60\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <h3 className=\"truncate text-sm font-semibold text-foreground\">\n {app.name}\n </h3>\n {app.status === \"pending\" ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n <IconClockHour4 size={12} />\n Building\n </Badge>\n ) : null}\n </div>\n <p className=\"mt-1 truncate font-mono text-xs text-muted-foreground\">\n {app.path}\n </p>\n {app.status === \"pending\" && app.branchName ? (\n <p className=\"mt-1 truncate text-xs text-muted-foreground\">\n Branch: {app.branchName}\n </p>\n ) : null}\n {app.description ? (\n <p className=\"mt-2 line-clamp-2 text-xs leading-relaxed text-muted-foreground\">\n {app.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {app.status === \"ready\" ? (\n <AppKeysPopover appId={app.id} appName={app.name} />\n ) : null}\n <IconArrowUpRight\n size={16}\n className=\"text-muted-foreground transition group-hover:text-foreground\"\n />\n </div>\n </div>\n </a>\n );\n })}\n\n <CreateAppPopover />\n </div>\n </section>\n </div>\n </DispatchShell>\n );\n}\n"]}
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGhD,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;AACxC,CAAC;AAQD,MAAM,CAAC,OAAO,UAAU,SAAS;IAC/B,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,GAAG,cAAc,CACxC,qBAAqB,EACrB,EAAE,iBAAiB,EAAE,KAAK,EAAE,EAC5B;QACE,eAAe,EAAE,KAAK;KACvB,CACF,CAAC;IACF,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,cAAc,CACxC,oBAAoB,EACpB,EAAE,EACF,EAAE,SAAS,EAAE,MAAM,EAAE,CACtB,CAAC;IACF,MAAM,EAAE,GAAG,SAAsC,CAAC;IAClD,MAAM,cAAc,GAAG,EAAE,EAAE,WAAW,IAAI,EAAE,EAAE,IAAI,IAAI,IAAI,CAAC;IAC3D,MAAM,SAAS,GAAI,IAA8B,CAAC,MAAM,CACtD,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CACzB,CAAC;IAEF,OAAO,CACL,KAAC,aAAa,IACZ,KAAK,EAAC,MAAM,EACZ,WAAW,EACT,cAAc;YACZ,CAAC,CAAC,gBAAgB,cAAc,8GAA8G;YAC9I,CAAC,CAAC,+DAA+D,YAGrE,cAAK,SAAS,EAAC,WAAW,YACxB,mBAAS,SAAS,EAAC,WAAW,aAC5B,eAAK,SAAS,EAAC,yCAAyC,aACtD,eAAK,SAAS,EAAC,yBAAyB,aACtC,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAC,uBAAuB,GAAG,EACxD,aAAI,SAAS,EAAC,uCAAuC,YAClD,cAAc;4CACb,CAAC,CAAC,WAAW,cAAc,EAAE;4CAC7B,CAAC,CAAC,gBAAgB,GACjB,IACD,EACN,KAAC,gBAAgB,IACf,KAAK,EAAC,KAAK,EACX,OAAO,EACL,MAAC,MAAM,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAC,SAAS,aACjC,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAC,QAAQ,GAAG,WAElC,GAEX,IACE,EAEN,eAAK,SAAS,EAAC,0CAA0C,aACtD,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACtB,KAAC,gBAAgB,IAAc,GAAG,EAAE,GAAG,IAAhB,GAAG,CAAC,EAAE,CAAc,CAC5C,CAAC,EAEF,KAAC,gBAAgB,KAAG,IAChB,IACE,GACN,GACQ,CACjB,CAAC;AACJ,CAAC","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client\";\nimport { IconApps, IconPlus } from \"@tabler/icons-react\";\nimport { CreateAppPopover } from \"@/components/create-app-popover\";\nimport { DispatchShell } from \"@/components/dispatch-shell\";\nimport { WorkspaceAppCard } from \"@/components/workspace-app-card\";\nimport { Button } from \"@/components/ui/button\";\nimport type { WorkspaceAppSummary } from \"@/lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Apps — Dispatch\" }];\n}\n\ninterface WorkspaceInfo {\n name: string | null;\n displayName: string | null;\n appCount: number;\n}\n\nexport default function AppsRoute() {\n const { data: apps = [] } = useActionQuery(\n \"list-workspace-apps\",\n { includeAgentCards: false },\n {\n refetchInterval: 2_000,\n },\n );\n const { data: workspace } = useActionQuery(\n \"get-workspace-info\",\n {},\n { staleTime: 60_000 },\n );\n const ws = workspace as WorkspaceInfo | undefined;\n const workspaceLabel = ws?.displayName ?? ws?.name ?? null;\n const typedApps = (apps as WorkspaceAppSummary[]).filter(\n (app) => !app.isDispatch,\n );\n\n return (\n <DispatchShell\n title=\"Apps\"\n description={\n workspaceLabel\n ? `Apps in the \"${workspaceLabel}\" workspace. Each app gets its own route under this workspace and shares its database, auth, and agent chat.`\n : \"Open workspace apps and start new app creation from Dispatch.\"\n }\n >\n <div className=\"space-y-4\">\n <section className=\"space-y-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <IconApps size={16} className=\"text-muted-foreground\" />\n <h2 className=\"text-sm font-semibold text-foreground\">\n {workspaceLabel\n ? `Apps in ${workspaceLabel}`\n : \"Workspace apps\"}\n </h2>\n </div>\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n App\n </Button>\n }\n />\n </div>\n\n <div className=\"grid gap-3 md:grid-cols-2 xl:grid-cols-3\">\n {typedApps.map((app) => (\n <WorkspaceAppCard key={app.id} app={app} />\n ))}\n\n <CreateAppPopover />\n </div>\n </section>\n </div>\n </DispatchShell>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"overview.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/overview.tsx"],"names":[],"mappings":"AA4dA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,4CA0SpC"}
1
+ {"version":3,"file":"overview.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/overview.tsx"],"names":[],"mappings":"AA6YA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,4CA0SpC"}
@@ -3,11 +3,10 @@ import { useEffect, useMemo, useState } from "react";
3
3
  import { Link } from "react-router";
4
4
  import { PromptComposer, useActionQuery, useChatModels, agentNativePath, } from "@agent-native/core/client";
5
5
  import { IconActivity, IconAlertTriangle, IconApps, IconArrowUpRight, IconCheck, IconClockHour4, IconInfoCircle, IconKey, IconListCheck, IconRocket, IconPlugConnected, IconShieldCheck, } from "@tabler/icons-react";
6
- import { AppKeysPopover } from "../../components/app-keys-popover.js";
7
6
  import { CreateAppPopover } from "../../components/create-app-popover.js";
8
7
  import { DispatchShell } from "../../components/dispatch-shell.js";
8
+ import { WorkspaceAppCard } from "../../components/workspace-app-card.js";
9
9
  import { Alert, AlertDescription, AlertTitle } from "../../components/ui/alert.js";
10
- import { Badge } from "../../components/ui/badge.js";
11
10
  import { Button } from "../../components/ui/button.js";
12
11
  import { Skeleton } from "../../components/ui/skeleton.js";
13
12
  import { Tooltip, TooltipContent, TooltipTrigger, } from "../../components/ui/tooltip.js";
@@ -20,14 +19,6 @@ const ZERO_TASK_QUEUE_STATS = {
20
19
  oldest_pending_age_seconds: 0,
21
20
  recent_failures: [],
22
21
  };
23
- function workspaceAppHref(app) {
24
- if (app.status === "pending")
25
- return app.builderUrl || null;
26
- return app.path || app.url || null;
27
- }
28
- function isPendingBuilderHref(app) {
29
- return app.status === "pending" && !!app.builderUrl;
30
- }
31
22
  const HOME_CHAT_SUGGESTIONS = [
32
23
  "Create a lightweight customer onboarding app",
33
24
  "Ask Slides to draft a board update from our latest metrics",
@@ -54,16 +45,7 @@ function WorkspaceAppsSection({ apps, isLoading, }) {
54
45
  const showSkeletons = isLoading && visibleApps.length === 0;
55
46
  return (_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(IconApps, { size: 16, className: "text-muted-foreground" }), _jsx("h2", { className: "text-sm font-semibold text-foreground", children: "Workspace apps" })] }), _jsx(Button, { asChild: true, variant: "outline", size: "sm", children: _jsxs(Link, { to: "/apps", children: ["View all", _jsx(IconArrowUpRight, { size: 15, className: "ml-1.5" })] }) })] }), _jsxs("div", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3", children: [showSkeletons
56
47
  ? Array.from({ length: 6 }).map((_, index) => (_jsx(AppCardSkeleton, {}, index)))
57
- : visibleApps.map((app) => {
58
- const href = workspaceAppHref(app);
59
- // Pending Builder branches live on a different host (Builder
60
- // editor URL); open those in a new tab. Ready workspace apps
61
- // navigate the current window so this works inside the
62
- // Builder webview, where new tabs would try to open in the
63
- // host browser and break the embedded session.
64
- const openInNewTab = isPendingBuilderHref(app);
65
- return (_jsx("a", { href: href ?? undefined, target: openInNewTab ? "_blank" : undefined, rel: openInNewTab ? "noreferrer" : undefined, "aria-disabled": !href, className: "group min-h-32 rounded-lg border bg-card p-4 transition hover:border-foreground/30 aria-disabled:pointer-events-none aria-disabled:opacity-60", children: _jsxs("div", { className: "flex h-full items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("h3", { className: "truncate text-sm font-semibold text-foreground", children: app.name }), app.status === "pending" ? (_jsxs(Badge, { variant: "outline", className: "shrink-0 gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300", children: [_jsx(IconClockHour4, { size: 12 }), "Building"] })) : null] }), _jsx("p", { className: "mt-1 truncate font-mono text-xs text-muted-foreground", children: app.path }), app.status === "pending" && app.branchName ? (_jsxs("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: ["Branch: ", app.branchName] })) : null, app.description ? (_jsx("p", { className: "mt-2 line-clamp-2 text-xs leading-relaxed text-muted-foreground", children: app.description })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [app.status === "ready" ? (_jsx(AppKeysPopover, { appId: app.id, appName: app.name })) : null, _jsx(IconArrowUpRight, { size: 16, className: "text-muted-foreground transition group-hover:text-foreground" })] })] }) }, app.id));
66
- }), !showSkeletons ? _jsx(CreateAppPopover, {}) : null] })] }));
48
+ : visibleApps.map((app) => (_jsx(WorkspaceAppCard, { app: app, className: "min-h-32" }, app.id))), !showSkeletons ? _jsx(CreateAppPopover, {}) : null] })] }));
67
49
  }
68
50
  function formatAgeSeconds(seconds) {
69
51
  if (!seconds || seconds < 0)
@@ -1 +1 @@
1
- {"version":3,"file":"overview.js","sourceRoot":"","sources":["../../../src/routes/pages/overview.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport { Link } from \"react-router\";\nimport {\n PromptComposer,\n useActionQuery,\n useChatModels,\n agentNativePath,\n} from \"@agent-native/core/client\";\nimport {\n IconActivity,\n IconAlertTriangle,\n IconApps,\n IconArrowUpRight,\n IconCheck,\n IconClockHour4,\n IconInfoCircle,\n IconKey,\n IconListCheck,\n IconRocket,\n IconPlugConnected,\n IconShieldCheck,\n type IconProps,\n} from \"@tabler/icons-react\";\nimport { AppKeysPopover } from \"@/components/app-keys-popover\";\nimport { CreateAppPopover } from \"@/components/create-app-popover\";\nimport { DispatchShell } from \"@/components/dispatch-shell\";\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { submitOverviewPrompt } from \"@/lib/overview-chat\";\n\ninterface IntegrationStatus {\n platform: string;\n label: string;\n enabled: boolean;\n configured: boolean;\n}\n\ninterface TaskQueueRecentFailure {\n id: string;\n platform: string;\n error: string;\n attempts: number;\n}\n\ninterface TaskQueueStats {\n pending: number;\n processing: number;\n completed_last_hour: number;\n failed_last_hour: number;\n oldest_pending_age_seconds: number;\n recent_failures: TaskQueueRecentFailure[];\n}\n\nconst ZERO_TASK_QUEUE_STATS: TaskQueueStats = {\n pending: 0,\n processing: 0,\n completed_last_hour: 0,\n failed_last_hour: 0,\n oldest_pending_age_seconds: 0,\n recent_failures: [],\n};\n\ninterface WorkspaceAppSummary {\n id: string;\n name: string;\n description?: string;\n path: string;\n url?: string | null;\n isDispatch: boolean;\n status?: \"ready\" | \"pending\";\n statusLabel?: string;\n builderUrl?: string | null;\n branchName?: string | null;\n}\n\nfunction workspaceAppHref(app: WorkspaceAppSummary): string | null {\n if (app.status === \"pending\") return app.builderUrl || null;\n return app.path || app.url || null;\n}\n\nfunction isPendingBuilderHref(app: WorkspaceAppSummary): boolean {\n return app.status === \"pending\" && !!app.builderUrl;\n}\n\nconst HOME_CHAT_SUGGESTIONS = [\n \"Create a lightweight customer onboarding app\",\n \"Ask Slides to draft a board update from our latest metrics\",\n \"Schedule a Monday morning analytics digest\",\n];\n\nfunction HomeChatPanel() {\n const { selectedModel } = useChatModels();\n\n const send = (message: string) => {\n submitOverviewPrompt(message, selectedModel);\n };\n\n return (\n <section className=\"px-2 py-6 sm:py-10\">\n <div className=\"mx-auto w-full max-w-2xl space-y-8\">\n <h1 className=\"text-center text-2xl font-semibold tracking-tight text-foreground sm:text-3xl\">\n What should we do next?\n </h1>\n <div className=\"flex flex-col gap-4\">\n <PromptComposer\n placeholder=\"Message agent…\"\n onSubmit={(text) => {\n const trimmed = text.trim();\n if (!trimmed) return;\n send(trimmed);\n }}\n />\n <div className=\"flex flex-wrap justify-center gap-2\">\n {HOME_CHAT_SUGGESTIONS.map((suggestion) => (\n <button\n key={suggestion}\n type=\"button\"\n onClick={() => send(suggestion)}\n className=\"cursor-pointer rounded-full border border-border bg-card px-3 py-1.5 text-xs text-muted-foreground transition hover:border-foreground/30 hover:text-foreground\"\n >\n {suggestion}\n </button>\n ))}\n </div>\n </div>\n </div>\n </section>\n );\n}\n\nfunction AppCardSkeleton() {\n return (\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1 space-y-3\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-24\" />\n <div className=\"space-y-2 pt-1\">\n <Skeleton className=\"h-3 w-full\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n </div>\n <Skeleton className=\"h-5 w-5 rounded-md\" />\n </div>\n </div>\n );\n}\n\nfunction WorkspaceAppsSection({\n apps,\n isLoading,\n}: {\n apps: WorkspaceAppSummary[];\n isLoading: boolean;\n}) {\n const filteredApps = apps.filter((app) => !app.isDispatch);\n const visibleApps = filteredApps.slice(0, 6);\n const showSkeletons = isLoading && visibleApps.length === 0;\n\n return (\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <IconApps size={16} className=\"text-muted-foreground\" />\n <h2 className=\"text-sm font-semibold text-foreground\">\n Workspace apps\n </h2>\n </div>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link to=\"/apps\">\n View all\n <IconArrowUpRight size={15} className=\"ml-1.5\" />\n </Link>\n </Button>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {showSkeletons\n ? Array.from({ length: 6 }).map((_, index) => (\n <AppCardSkeleton key={index} />\n ))\n : visibleApps.map((app) => {\n const href = workspaceAppHref(app);\n // Pending Builder branches live on a different host (Builder\n // editor URL); open those in a new tab. Ready workspace apps\n // navigate the current window so this works inside the\n // Builder webview, where new tabs would try to open in the\n // host browser and break the embedded session.\n const openInNewTab = isPendingBuilderHref(app);\n return (\n <a\n key={app.id}\n href={href ?? undefined}\n target={openInNewTab ? \"_blank\" : undefined}\n rel={openInNewTab ? \"noreferrer\" : undefined}\n aria-disabled={!href}\n className=\"group min-h-32 rounded-lg border bg-card p-4 transition hover:border-foreground/30 aria-disabled:pointer-events-none aria-disabled:opacity-60\"\n >\n <div className=\"flex h-full items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <h3 className=\"truncate text-sm font-semibold text-foreground\">\n {app.name}\n </h3>\n {app.status === \"pending\" ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n <IconClockHour4 size={12} />\n Building\n </Badge>\n ) : null}\n </div>\n <p className=\"mt-1 truncate font-mono text-xs text-muted-foreground\">\n {app.path}\n </p>\n {app.status === \"pending\" && app.branchName ? (\n <p className=\"mt-1 truncate text-xs text-muted-foreground\">\n Branch: {app.branchName}\n </p>\n ) : null}\n {app.description ? (\n <p className=\"mt-2 line-clamp-2 text-xs leading-relaxed text-muted-foreground\">\n {app.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {app.status === \"ready\" ? (\n <AppKeysPopover appId={app.id} appName={app.name} />\n ) : null}\n <IconArrowUpRight\n size={16}\n className=\"text-muted-foreground transition group-hover:text-foreground\"\n />\n </div>\n </div>\n </a>\n );\n })}\n\n {!showSkeletons ? <CreateAppPopover /> : null}\n </div>\n </section>\n );\n}\n\nfunction formatAgeSeconds(seconds: number): string {\n if (!seconds || seconds < 0) return \"0s\";\n if (seconds < 60) return `${seconds}s`;\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;\n return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`;\n}\n\nfunction TaskQueueMetric({\n label,\n value,\n tone,\n icon: Icon,\n}: {\n label: string;\n value: string | number;\n tone?: \"default\" | \"warning\" | \"danger\";\n icon?: React.ComponentType<IconProps>;\n}) {\n const toneClass =\n tone === \"danger\"\n ? \"text-red-600 dark:text-red-400\"\n : tone === \"warning\"\n ? \"text-amber-600 dark:text-amber-400\"\n : \"text-foreground\";\n return (\n <div className=\"rounded-xl border bg-card px-4 py-3\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-muted-foreground\">\n {Icon ? <Icon size={14} /> : null}\n <span>{label}</span>\n </div>\n <div className={`mt-1 text-2xl font-semibold ${toneClass}`}>{value}</div>\n </div>\n );\n}\n\nfunction TaskQueueSection({ stats }: { stats: TaskQueueStats }) {\n const showAlert = stats.pending > 5 || stats.failed_last_hour > 0;\n return (\n <section className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <IconListCheck size={16} className=\"text-muted-foreground\" />\n <h2 className=\"text-sm font-semibold text-foreground\">Task queue</h2>\n </div>\n {showAlert && (\n <Alert variant={stats.failed_last_hour > 0 ? \"destructive\" : \"default\"}>\n <IconAlertTriangle className=\"h-4 w-4\" />\n <AlertTitle>\n {stats.failed_last_hour > 0\n ? `${stats.failed_last_hour} integration task${stats.failed_last_hour === 1 ? \"\" : \"s\"} failed in the last hour`\n : `${stats.pending} pending integration task${stats.pending === 1 ? \"\" : \"s\"} queued`}\n </AlertTitle>\n <AlertDescription>\n {stats.failed_last_hour > 0\n ? \"Recent failures are listed below. Check platform credentials and retry.\"\n : \"Tasks are waiting to be processed. The queue may be backed up.\"}\n </AlertDescription>\n </Alert>\n )}\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-5\">\n <TaskQueueMetric\n label=\"Pending\"\n value={stats.pending}\n tone={stats.pending > 5 ? \"warning\" : \"default\"}\n />\n <TaskQueueMetric label=\"Processing\" value={stats.processing} />\n <TaskQueueMetric\n label=\"Completed (1h)\"\n value={stats.completed_last_hour}\n />\n <TaskQueueMetric\n label=\"Failed (1h)\"\n value={stats.failed_last_hour}\n tone={stats.failed_last_hour > 0 ? \"danger\" : \"default\"}\n />\n <TaskQueueMetric\n label=\"Oldest pending\"\n value={formatAgeSeconds(stats.oldest_pending_age_seconds)}\n icon={IconClockHour4}\n tone={stats.oldest_pending_age_seconds > 300 ? \"warning\" : \"default\"}\n />\n </div>\n {stats.recent_failures.length > 0 && (\n <div className=\"rounded-2xl border bg-card p-4\">\n <div className=\"text-sm font-semibold text-foreground\">\n Recent failures\n </div>\n <div className=\"mt-3 space-y-2\">\n {stats.recent_failures.map((failure) => (\n <div\n key={failure.id}\n className=\"rounded-xl border bg-muted/30 px-3 py-2\"\n >\n <div className=\"flex items-center justify-between gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">\n {failure.platform}\n </span>\n <span>\n {failure.attempts} attempt\n {failure.attempts === 1 ? \"\" : \"s\"}\n </span>\n </div>\n <div className=\"mt-1 truncate text-sm text-foreground\">\n {failure.error || \"(no error message)\"}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </section>\n );\n}\n\nfunction HelpTooltip({ content }: { content: string }) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className=\"text-muted-foreground/60 hover:text-foreground cursor-pointer\"\n >\n <IconInfoCircle className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-64 text-xs leading-relaxed\">\n {content}\n </TooltipContent>\n </Tooltip>\n );\n}\n\nfunction StatCard({\n label,\n help,\n value,\n icon: Icon,\n cta,\n}: {\n label: string;\n help: string;\n value: number;\n icon: React.ComponentType<IconProps>;\n cta?: React.ReactNode;\n}) {\n return (\n <div className=\"rounded-2xl border bg-card p-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-1.5 text-sm font-medium text-foreground\">\n <span>{label}</span>\n <HelpTooltip content={help} />\n </div>\n <div className=\"mt-3 text-3xl font-semibold text-foreground\">\n {value}\n </div>\n </div>\n <div className=\"rounded-xl border bg-muted/30 p-3 text-muted-foreground\">\n <Icon size={18} />\n </div>\n </div>\n {cta ? <div className=\"mt-4\">{cta}</div> : null}\n </div>\n );\n}\n\ninterface ChecklistStep {\n number: number;\n title: string;\n description: string;\n complete: boolean;\n /** If set, renders a link button to this path */\n to?: string;\n actionLabel?: string;\n /** If true, this step is always shown as informational (never \"complete\") */\n informational?: boolean;\n}\n\nfunction StepRow({ step }: { step: ChecklistStep }) {\n const done = step.complete && !step.informational;\n\n return (\n <div\n className={`flex items-start gap-4 rounded-xl border px-5 py-4 ${done ? \"border-border/50 bg-muted/20\" : \"bg-card\"}`}\n >\n {/* Status marker */}\n <div className=\"flex-none pt-0.5\">\n {done ? (\n <div className=\"flex h-7 w-7 items-center justify-center rounded-full bg-emerald-500/15 text-emerald-600 dark:text-emerald-400\">\n <IconCheck size={16} strokeWidth={2.5} />\n </div>\n ) : (\n <div className=\"flex h-7 w-7 items-center justify-center rounded-full border border-muted-foreground/30 text-muted-foreground\">\n <IconListCheck size={15} />\n </div>\n )}\n </div>\n\n {/* Text */}\n <div className={`min-w-0 flex-1 ${done ? \"opacity-50\" : \"\"}`}>\n <div\n className={`text-sm font-semibold ${done ? \"line-through decoration-muted-foreground/40\" : \"text-foreground\"}`}\n >\n {step.title}\n </div>\n <p className=\"mt-0.5 text-sm leading-relaxed text-muted-foreground\">\n {step.description}\n </p>\n </div>\n\n {/* Action */}\n {step.to && !done && (\n <div className=\"flex-none pt-0.5\">\n <Button variant=\"outline\" size=\"sm\" asChild>\n <Link to={step.to}>{step.actionLabel || \"Set up\"}</Link>\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nexport function meta() {\n return [{ title: \"Overview — Dispatch\" }];\n}\n\nexport default function OverviewRoute() {\n const { data, isLoading } = useActionQuery(\"list-dispatch-overview\", {});\n const { data: connectedAgents } = useActionQuery(\"list-connected-agents\", {});\n const { data: workspaceApps = [], isLoading: appsLoading } = useActionQuery(\n \"list-workspace-apps\",\n { includeAgentCards: false },\n {\n refetchInterval: 2_000,\n },\n );\n const [integrationStatuses, setIntegrationStatuses] = useState<\n IntegrationStatus[]\n >([]);\n const [taskQueueStats, setTaskQueueStats] = useState<TaskQueueStats>(\n ZERO_TASK_QUEUE_STATS,\n );\n\n useEffect(() => {\n let active = true;\n fetch(agentNativePath(\"/_agent-native/integrations/status\"))\n .then((res) => (res.ok ? res.json() : []))\n .then((rows) => {\n if (active) {\n setIntegrationStatuses(Array.isArray(rows) ? rows : []);\n }\n })\n .catch(() => {\n if (active) setIntegrationStatuses([]);\n });\n return () => {\n active = false;\n };\n }, []);\n\n useEffect(() => {\n let active = true;\n const load = () => {\n fetch(agentNativePath(\"/_agent-native/integrations/task-queue/status\"))\n .then((res) => (res.ok ? res.json() : null))\n .then((stats) => {\n if (!active || !stats || typeof stats !== \"object\") return;\n setTaskQueueStats({\n pending: Number(stats.pending ?? 0),\n processing: Number(stats.processing ?? 0),\n completed_last_hour: Number(stats.completed_last_hour ?? 0),\n failed_last_hour: Number(stats.failed_last_hour ?? 0),\n oldest_pending_age_seconds: Number(\n stats.oldest_pending_age_seconds ?? 0,\n ),\n recent_failures: Array.isArray(stats.recent_failures)\n ? stats.recent_failures\n : [],\n });\n })\n .catch(() => {\n // Endpoint may not exist on older deploys — ignore.\n });\n };\n load();\n const id = window.setInterval(load, 15000);\n return () => {\n active = false;\n window.clearInterval(id);\n };\n }, []);\n\n const counts = data?.counts || {\n destinations: 0,\n pendingApprovals: 0,\n linkedIdentities: 0,\n activeTokens: 0,\n };\n\n const messagingStatuses = useMemo(\n () =>\n integrationStatuses.filter(\n (row) => row.platform === \"slack\" || row.platform === \"telegram\",\n ),\n [integrationStatuses],\n );\n\n const connectedMessagingCount = messagingStatuses.filter(\n (row) => row.enabled || row.configured,\n ).length;\n const connectedAgentCount = connectedAgents?.length || 0;\n const vaultSecretCount = data?.vault?.secretCount || 0;\n const typedWorkspaceApps = workspaceApps as WorkspaceAppSummary[];\n\n const messagingDone = connectedMessagingCount > 0;\n const agentsDone = connectedAgentCount > 0;\n const vaultDone = vaultSecretCount > 0;\n\n const steps: ChecklistStep[] = [\n {\n number: 1,\n title: \"Connect Slack\",\n description:\n \"Add @agent-native to your Slack workspace so your team can ask questions, create decks, pull analytics, and more — right from Slack.\",\n complete: messagingDone,\n to: \"/messaging\",\n actionLabel: \"Connect\",\n },\n {\n number: 2,\n title: \"Review connected agents\",\n description:\n \"Dispatch delegates work to specialized apps. The built-in suite (Slides, Analytics, Content, Video, and more) is available automatically.\",\n complete: agentsDone,\n to: \"/agents\",\n actionLabel: \"Review\",\n },\n {\n number: 3,\n title: \"Set up your vault\",\n description:\n \"Store API keys centrally and sync them to apps that need them.\",\n complete: vaultDone,\n to: \"/vault\",\n actionLabel: \"Open vault\",\n },\n {\n number: 4,\n title: \"Try it out\",\n description: \"Mention @agent-native in any Slack channel to get started.\",\n complete: false,\n informational: true,\n },\n ];\n\n const hasIncompleteSteps = steps.some((s) => !s.complete && !s.informational);\n\n return (\n <DispatchShell\n title=\"Overview\"\n description=\"Create apps, manage shared keys, and route work across your workspace.\"\n >\n <HomeChatPanel />\n\n <WorkspaceAppsSection apps={typedWorkspaceApps} isLoading={appsLoading} />\n\n {hasIncompleteSteps && (\n <section className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <IconRocket size={16} className=\"text-muted-foreground\" />\n <h2 className=\"text-sm font-semibold text-foreground\">\n Getting started\n </h2>\n </div>\n <div className=\"space-y-2\">\n {steps.map((step) => (\n <StepRow key={step.number} step={step} />\n ))}\n </div>\n </section>\n )}\n\n <section className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <IconActivity size={16} className=\"text-muted-foreground\" />\n <h2 className=\"text-sm font-semibold text-foreground\">At a glance</h2>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <StatCard\n label=\"Vault secrets\"\n help=\"Credentials stored in the workspace vault. Grant them to apps from the Vault page.\"\n value={data?.vault?.secretCount || 0}\n icon={IconKey}\n cta={\n (data?.vault?.secretCount || 0) === 0 ? (\n <Button variant=\"outline\" size=\"sm\" asChild>\n <Link to=\"/vault\">Set up vault</Link>\n </Button>\n ) : undefined\n }\n />\n <StatCard\n label=\"Active grants\"\n help=\"Secrets currently granted to apps. Sync them to push credentials.\"\n value={data?.vault?.activeGrantCount || 0}\n icon={IconShieldCheck}\n />\n <StatCard\n label=\"Destinations\"\n help=\"Saved outbound targets used for proactive sends and scheduled jobs.\"\n value={counts.destinations}\n icon={IconArrowUpRight}\n cta={\n counts.destinations === 0 ? (\n <Button variant=\"outline\" size=\"sm\" asChild>\n <Link to=\"/destinations\">Set up destinations</Link>\n </Button>\n ) : undefined\n }\n />\n <StatCard\n label=\"Agents\"\n help=\"Agents available to dispatch for delegation over A2A. This includes the built-in app suite plus any additional agents you add.\"\n value={connectedAgentCount}\n icon={IconPlugConnected}\n cta={\n connectedAgentCount === 0 ? (\n <Button variant=\"outline\" size=\"sm\" asChild>\n <Link to=\"/agents\">Open agents</Link>\n </Button>\n ) : undefined\n }\n />\n </div>\n </section>\n\n <details className=\"rounded-xl border\">\n <summary className=\"flex cursor-pointer list-none items-center justify-between gap-3 px-5 py-4 text-sm font-semibold text-foreground hover:bg-muted/30 [&::-webkit-details-marker]:hidden\">\n <span>Operations detail</span>\n <span className=\"text-xs font-normal text-muted-foreground\">\n Queue, audit, and approvals\n </span>\n </summary>\n <div className=\"space-y-5 border-t px-5 py-5\">\n <TaskQueueSection stats={taskQueueStats} />\n\n <div className=\"grid gap-4 xl:grid-cols-3\">\n <section className=\"rounded-2xl border bg-card p-5 xl:col-span-2\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n Recent activity\n </h2>\n {isLoading && (\n <span className=\"text-xs text-muted-foreground\">\n Loading...\n </span>\n )}\n </div>\n <div className=\"mt-4 space-y-3\">\n {(data?.recentAudit || []).map((event) => (\n <div\n key={event.id}\n className=\"rounded-xl border bg-muted/30 px-4 py-3\"\n >\n <div className=\"text-sm font-medium text-foreground\">\n {event.summary}\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {event.actor} ·{\" \"}\n {new Date(event.createdAt).toLocaleString()}\n </div>\n </div>\n ))}\n {!isLoading && (data?.recentAudit?.length || 0) === 0 && (\n <div className=\"rounded-xl border border-dashed px-4 py-6 text-sm text-muted-foreground\">\n No activity yet.\n </div>\n )}\n </div>\n </section>\n\n <section className=\"rounded-2xl border bg-card p-5\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n Approval mode\n </h2>\n <div className=\"mt-4 rounded-xl border bg-muted/30 p-4\">\n <div className=\"text-sm font-medium text-muted-foreground\">\n Current policy\n </div>\n <div className=\"mt-2 text-2xl font-semibold text-foreground\">\n {data?.settings?.enabled ? \"Reviewed\" : \"Immediate\"}\n </div>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {data?.settings?.enabled\n ? \"Changes wait for approval before they apply.\"\n : \"Changes apply immediately and are recorded in audit.\"}\n </p>\n </div>\n <div className=\"mt-4 space-y-2\">\n {(data?.recentApprovals || []).map((approval) => (\n <div\n key={approval.id}\n className=\"rounded-xl border px-4 py-3\"\n >\n <div className=\"text-sm font-medium text-foreground\">\n {approval.summary}\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {approval.status} · requested by {approval.requestedBy}\n </div>\n </div>\n ))}\n {(data?.recentApprovals?.length || 0) === 0 && (\n <div className=\"rounded-xl border border-dashed px-4 py-6 text-sm text-muted-foreground\">\n No approval requests.\n </div>\n )}\n </div>\n </section>\n </div>\n </div>\n </details>\n </DispatchShell>\n );\n}\n"]}
1
+ {"version":3,"file":"overview.js","sourceRoot":"","sources":["../../../src/routes/pages/overview.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport { Link } from \"react-router\";\nimport {\n PromptComposer,\n useActionQuery,\n useChatModels,\n agentNativePath,\n} from \"@agent-native/core/client\";\nimport {\n IconActivity,\n IconAlertTriangle,\n IconApps,\n IconArrowUpRight,\n IconCheck,\n IconClockHour4,\n IconInfoCircle,\n IconKey,\n IconListCheck,\n IconRocket,\n IconPlugConnected,\n IconShieldCheck,\n type IconProps,\n} from \"@tabler/icons-react\";\nimport { CreateAppPopover } from \"@/components/create-app-popover\";\nimport { DispatchShell } from \"@/components/dispatch-shell\";\nimport { WorkspaceAppCard } from \"@/components/workspace-app-card\";\nimport { Alert, AlertDescription, AlertTitle } from \"@/components/ui/alert\";\nimport { Button } from \"@/components/ui/button\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { submitOverviewPrompt } from \"@/lib/overview-chat\";\nimport type { WorkspaceAppSummary } from \"@/lib/workspace-apps\";\n\ninterface IntegrationStatus {\n platform: string;\n label: string;\n enabled: boolean;\n configured: boolean;\n}\n\ninterface TaskQueueRecentFailure {\n id: string;\n platform: string;\n error: string;\n attempts: number;\n}\n\ninterface TaskQueueStats {\n pending: number;\n processing: number;\n completed_last_hour: number;\n failed_last_hour: number;\n oldest_pending_age_seconds: number;\n recent_failures: TaskQueueRecentFailure[];\n}\n\nconst ZERO_TASK_QUEUE_STATS: TaskQueueStats = {\n pending: 0,\n processing: 0,\n completed_last_hour: 0,\n failed_last_hour: 0,\n oldest_pending_age_seconds: 0,\n recent_failures: [],\n};\n\nconst HOME_CHAT_SUGGESTIONS = [\n \"Create a lightweight customer onboarding app\",\n \"Ask Slides to draft a board update from our latest metrics\",\n \"Schedule a Monday morning analytics digest\",\n];\n\nfunction HomeChatPanel() {\n const { selectedModel } = useChatModels();\n\n const send = (message: string) => {\n submitOverviewPrompt(message, selectedModel);\n };\n\n return (\n <section className=\"px-2 py-6 sm:py-10\">\n <div className=\"mx-auto w-full max-w-2xl space-y-8\">\n <h1 className=\"text-center text-2xl font-semibold tracking-tight text-foreground sm:text-3xl\">\n What should we do next?\n </h1>\n <div className=\"flex flex-col gap-4\">\n <PromptComposer\n placeholder=\"Message agent…\"\n onSubmit={(text) => {\n const trimmed = text.trim();\n if (!trimmed) return;\n send(trimmed);\n }}\n />\n <div className=\"flex flex-wrap justify-center gap-2\">\n {HOME_CHAT_SUGGESTIONS.map((suggestion) => (\n <button\n key={suggestion}\n type=\"button\"\n onClick={() => send(suggestion)}\n className=\"cursor-pointer rounded-full border border-border bg-card px-3 py-1.5 text-xs text-muted-foreground transition hover:border-foreground/30 hover:text-foreground\"\n >\n {suggestion}\n </button>\n ))}\n </div>\n </div>\n </div>\n </section>\n );\n}\n\nfunction AppCardSkeleton() {\n return (\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1 space-y-3\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-24\" />\n <div className=\"space-y-2 pt-1\">\n <Skeleton className=\"h-3 w-full\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n </div>\n <Skeleton className=\"h-5 w-5 rounded-md\" />\n </div>\n </div>\n );\n}\n\nfunction WorkspaceAppsSection({\n apps,\n isLoading,\n}: {\n apps: WorkspaceAppSummary[];\n isLoading: boolean;\n}) {\n const filteredApps = apps.filter((app) => !app.isDispatch);\n const visibleApps = filteredApps.slice(0, 6);\n const showSkeletons = isLoading && visibleApps.length === 0;\n\n return (\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <IconApps size={16} className=\"text-muted-foreground\" />\n <h2 className=\"text-sm font-semibold text-foreground\">\n Workspace apps\n </h2>\n </div>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link to=\"/apps\">\n View all\n <IconArrowUpRight size={15} className=\"ml-1.5\" />\n </Link>\n </Button>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {showSkeletons\n ? Array.from({ length: 6 }).map((_, index) => (\n <AppCardSkeleton key={index} />\n ))\n : visibleApps.map((app) => (\n <WorkspaceAppCard key={app.id} app={app} className=\"min-h-32\" />\n ))}\n\n {!showSkeletons ? <CreateAppPopover /> : null}\n </div>\n </section>\n );\n}\n\nfunction formatAgeSeconds(seconds: number): string {\n if (!seconds || seconds < 0) return \"0s\";\n if (seconds < 60) return `${seconds}s`;\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;\n return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`;\n}\n\nfunction TaskQueueMetric({\n label,\n value,\n tone,\n icon: Icon,\n}: {\n label: string;\n value: string | number;\n tone?: \"default\" | \"warning\" | \"danger\";\n icon?: React.ComponentType<IconProps>;\n}) {\n const toneClass =\n tone === \"danger\"\n ? \"text-red-600 dark:text-red-400\"\n : tone === \"warning\"\n ? \"text-amber-600 dark:text-amber-400\"\n : \"text-foreground\";\n return (\n <div className=\"rounded-xl border bg-card px-4 py-3\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-muted-foreground\">\n {Icon ? <Icon size={14} /> : null}\n <span>{label}</span>\n </div>\n <div className={`mt-1 text-2xl font-semibold ${toneClass}`}>{value}</div>\n </div>\n );\n}\n\nfunction TaskQueueSection({ stats }: { stats: TaskQueueStats }) {\n const showAlert = stats.pending > 5 || stats.failed_last_hour > 0;\n return (\n <section className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <IconListCheck size={16} className=\"text-muted-foreground\" />\n <h2 className=\"text-sm font-semibold text-foreground\">Task queue</h2>\n </div>\n {showAlert && (\n <Alert variant={stats.failed_last_hour > 0 ? \"destructive\" : \"default\"}>\n <IconAlertTriangle className=\"h-4 w-4\" />\n <AlertTitle>\n {stats.failed_last_hour > 0\n ? `${stats.failed_last_hour} integration task${stats.failed_last_hour === 1 ? \"\" : \"s\"} failed in the last hour`\n : `${stats.pending} pending integration task${stats.pending === 1 ? \"\" : \"s\"} queued`}\n </AlertTitle>\n <AlertDescription>\n {stats.failed_last_hour > 0\n ? \"Recent failures are listed below. Check platform credentials and retry.\"\n : \"Tasks are waiting to be processed. The queue may be backed up.\"}\n </AlertDescription>\n </Alert>\n )}\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-5\">\n <TaskQueueMetric\n label=\"Pending\"\n value={stats.pending}\n tone={stats.pending > 5 ? \"warning\" : \"default\"}\n />\n <TaskQueueMetric label=\"Processing\" value={stats.processing} />\n <TaskQueueMetric\n label=\"Completed (1h)\"\n value={stats.completed_last_hour}\n />\n <TaskQueueMetric\n label=\"Failed (1h)\"\n value={stats.failed_last_hour}\n tone={stats.failed_last_hour > 0 ? \"danger\" : \"default\"}\n />\n <TaskQueueMetric\n label=\"Oldest pending\"\n value={formatAgeSeconds(stats.oldest_pending_age_seconds)}\n icon={IconClockHour4}\n tone={stats.oldest_pending_age_seconds > 300 ? \"warning\" : \"default\"}\n />\n </div>\n {stats.recent_failures.length > 0 && (\n <div className=\"rounded-2xl border bg-card p-4\">\n <div className=\"text-sm font-semibold text-foreground\">\n Recent failures\n </div>\n <div className=\"mt-3 space-y-2\">\n {stats.recent_failures.map((failure) => (\n <div\n key={failure.id}\n className=\"rounded-xl border bg-muted/30 px-3 py-2\"\n >\n <div className=\"flex items-center justify-between gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">\n {failure.platform}\n </span>\n <span>\n {failure.attempts} attempt\n {failure.attempts === 1 ? \"\" : \"s\"}\n </span>\n </div>\n <div className=\"mt-1 truncate text-sm text-foreground\">\n {failure.error || \"(no error message)\"}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </section>\n );\n}\n\nfunction HelpTooltip({ content }: { content: string }) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className=\"text-muted-foreground/60 hover:text-foreground cursor-pointer\"\n >\n <IconInfoCircle className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-64 text-xs leading-relaxed\">\n {content}\n </TooltipContent>\n </Tooltip>\n );\n}\n\nfunction StatCard({\n label,\n help,\n value,\n icon: Icon,\n cta,\n}: {\n label: string;\n help: string;\n value: number;\n icon: React.ComponentType<IconProps>;\n cta?: React.ReactNode;\n}) {\n return (\n <div className=\"rounded-2xl border bg-card p-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-1.5 text-sm font-medium text-foreground\">\n <span>{label}</span>\n <HelpTooltip content={help} />\n </div>\n <div className=\"mt-3 text-3xl font-semibold text-foreground\">\n {value}\n </div>\n </div>\n <div className=\"rounded-xl border bg-muted/30 p-3 text-muted-foreground\">\n <Icon size={18} />\n </div>\n </div>\n {cta ? <div className=\"mt-4\">{cta}</div> : null}\n </div>\n );\n}\n\ninterface ChecklistStep {\n number: number;\n title: string;\n description: string;\n complete: boolean;\n /** If set, renders a link button to this path */\n to?: string;\n actionLabel?: string;\n /** If true, this step is always shown as informational (never \"complete\") */\n informational?: boolean;\n}\n\nfunction StepRow({ step }: { step: ChecklistStep }) {\n const done = step.complete && !step.informational;\n\n return (\n <div\n className={`flex items-start gap-4 rounded-xl border px-5 py-4 ${done ? \"border-border/50 bg-muted/20\" : \"bg-card\"}`}\n >\n {/* Status marker */}\n <div className=\"flex-none pt-0.5\">\n {done ? (\n <div className=\"flex h-7 w-7 items-center justify-center rounded-full bg-emerald-500/15 text-emerald-600 dark:text-emerald-400\">\n <IconCheck size={16} strokeWidth={2.5} />\n </div>\n ) : (\n <div className=\"flex h-7 w-7 items-center justify-center rounded-full border border-muted-foreground/30 text-muted-foreground\">\n <IconListCheck size={15} />\n </div>\n )}\n </div>\n\n {/* Text */}\n <div className={`min-w-0 flex-1 ${done ? \"opacity-50\" : \"\"}`}>\n <div\n className={`text-sm font-semibold ${done ? \"line-through decoration-muted-foreground/40\" : \"text-foreground\"}`}\n >\n {step.title}\n </div>\n <p className=\"mt-0.5 text-sm leading-relaxed text-muted-foreground\">\n {step.description}\n </p>\n </div>\n\n {/* Action */}\n {step.to && !done && (\n <div className=\"flex-none pt-0.5\">\n <Button variant=\"outline\" size=\"sm\" asChild>\n <Link to={step.to}>{step.actionLabel || \"Set up\"}</Link>\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nexport function meta() {\n return [{ title: \"Overview — Dispatch\" }];\n}\n\nexport default function OverviewRoute() {\n const { data, isLoading } = useActionQuery(\"list-dispatch-overview\", {});\n const { data: connectedAgents } = useActionQuery(\"list-connected-agents\", {});\n const { data: workspaceApps = [], isLoading: appsLoading } = useActionQuery(\n \"list-workspace-apps\",\n { includeAgentCards: false },\n {\n refetchInterval: 2_000,\n },\n );\n const [integrationStatuses, setIntegrationStatuses] = useState<\n IntegrationStatus[]\n >([]);\n const [taskQueueStats, setTaskQueueStats] = useState<TaskQueueStats>(\n ZERO_TASK_QUEUE_STATS,\n );\n\n useEffect(() => {\n let active = true;\n fetch(agentNativePath(\"/_agent-native/integrations/status\"))\n .then((res) => (res.ok ? res.json() : []))\n .then((rows) => {\n if (active) {\n setIntegrationStatuses(Array.isArray(rows) ? rows : []);\n }\n })\n .catch(() => {\n if (active) setIntegrationStatuses([]);\n });\n return () => {\n active = false;\n };\n }, []);\n\n useEffect(() => {\n let active = true;\n const load = () => {\n fetch(agentNativePath(\"/_agent-native/integrations/task-queue/status\"))\n .then((res) => (res.ok ? res.json() : null))\n .then((stats) => {\n if (!active || !stats || typeof stats !== \"object\") return;\n setTaskQueueStats({\n pending: Number(stats.pending ?? 0),\n processing: Number(stats.processing ?? 0),\n completed_last_hour: Number(stats.completed_last_hour ?? 0),\n failed_last_hour: Number(stats.failed_last_hour ?? 0),\n oldest_pending_age_seconds: Number(\n stats.oldest_pending_age_seconds ?? 0,\n ),\n recent_failures: Array.isArray(stats.recent_failures)\n ? stats.recent_failures\n : [],\n });\n })\n .catch(() => {\n // Endpoint may not exist on older deploys — ignore.\n });\n };\n load();\n const id = window.setInterval(load, 15000);\n return () => {\n active = false;\n window.clearInterval(id);\n };\n }, []);\n\n const counts = data?.counts || {\n destinations: 0,\n pendingApprovals: 0,\n linkedIdentities: 0,\n activeTokens: 0,\n };\n\n const messagingStatuses = useMemo(\n () =>\n integrationStatuses.filter(\n (row) => row.platform === \"slack\" || row.platform === \"telegram\",\n ),\n [integrationStatuses],\n );\n\n const connectedMessagingCount = messagingStatuses.filter(\n (row) => row.enabled || row.configured,\n ).length;\n const connectedAgentCount = connectedAgents?.length || 0;\n const vaultSecretCount = data?.vault?.secretCount || 0;\n const typedWorkspaceApps = workspaceApps as WorkspaceAppSummary[];\n\n const messagingDone = connectedMessagingCount > 0;\n const agentsDone = connectedAgentCount > 0;\n const vaultDone = vaultSecretCount > 0;\n\n const steps: ChecklistStep[] = [\n {\n number: 1,\n title: \"Connect Slack\",\n description:\n \"Add @agent-native to your Slack workspace so your team can ask questions, create decks, pull analytics, and more — right from Slack.\",\n complete: messagingDone,\n to: \"/messaging\",\n actionLabel: \"Connect\",\n },\n {\n number: 2,\n title: \"Review connected agents\",\n description:\n \"Dispatch delegates work to specialized apps. The built-in suite (Slides, Analytics, Content, Video, and more) is available automatically.\",\n complete: agentsDone,\n to: \"/agents\",\n actionLabel: \"Review\",\n },\n {\n number: 3,\n title: \"Set up your vault\",\n description:\n \"Store API keys centrally and sync them to apps that need them.\",\n complete: vaultDone,\n to: \"/vault\",\n actionLabel: \"Open vault\",\n },\n {\n number: 4,\n title: \"Try it out\",\n description: \"Mention @agent-native in any Slack channel to get started.\",\n complete: false,\n informational: true,\n },\n ];\n\n const hasIncompleteSteps = steps.some((s) => !s.complete && !s.informational);\n\n return (\n <DispatchShell\n title=\"Overview\"\n description=\"Create apps, manage shared keys, and route work across your workspace.\"\n >\n <HomeChatPanel />\n\n <WorkspaceAppsSection apps={typedWorkspaceApps} isLoading={appsLoading} />\n\n {hasIncompleteSteps && (\n <section className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <IconRocket size={16} className=\"text-muted-foreground\" />\n <h2 className=\"text-sm font-semibold text-foreground\">\n Getting started\n </h2>\n </div>\n <div className=\"space-y-2\">\n {steps.map((step) => (\n <StepRow key={step.number} step={step} />\n ))}\n </div>\n </section>\n )}\n\n <section className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <IconActivity size={16} className=\"text-muted-foreground\" />\n <h2 className=\"text-sm font-semibold text-foreground\">At a glance</h2>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <StatCard\n label=\"Vault secrets\"\n help=\"Credentials stored in the workspace vault. Grant them to apps from the Vault page.\"\n value={data?.vault?.secretCount || 0}\n icon={IconKey}\n cta={\n (data?.vault?.secretCount || 0) === 0 ? (\n <Button variant=\"outline\" size=\"sm\" asChild>\n <Link to=\"/vault\">Set up vault</Link>\n </Button>\n ) : undefined\n }\n />\n <StatCard\n label=\"Active grants\"\n help=\"Secrets currently granted to apps. Sync them to push credentials.\"\n value={data?.vault?.activeGrantCount || 0}\n icon={IconShieldCheck}\n />\n <StatCard\n label=\"Destinations\"\n help=\"Saved outbound targets used for proactive sends and scheduled jobs.\"\n value={counts.destinations}\n icon={IconArrowUpRight}\n cta={\n counts.destinations === 0 ? (\n <Button variant=\"outline\" size=\"sm\" asChild>\n <Link to=\"/destinations\">Set up destinations</Link>\n </Button>\n ) : undefined\n }\n />\n <StatCard\n label=\"Agents\"\n help=\"Agents available to dispatch for delegation over A2A. This includes the built-in app suite plus any additional agents you add.\"\n value={connectedAgentCount}\n icon={IconPlugConnected}\n cta={\n connectedAgentCount === 0 ? (\n <Button variant=\"outline\" size=\"sm\" asChild>\n <Link to=\"/agents\">Open agents</Link>\n </Button>\n ) : undefined\n }\n />\n </div>\n </section>\n\n <details className=\"rounded-xl border\">\n <summary className=\"flex cursor-pointer list-none items-center justify-between gap-3 px-5 py-4 text-sm font-semibold text-foreground hover:bg-muted/30 [&::-webkit-details-marker]:hidden\">\n <span>Operations detail</span>\n <span className=\"text-xs font-normal text-muted-foreground\">\n Queue, audit, and approvals\n </span>\n </summary>\n <div className=\"space-y-5 border-t px-5 py-5\">\n <TaskQueueSection stats={taskQueueStats} />\n\n <div className=\"grid gap-4 xl:grid-cols-3\">\n <section className=\"rounded-2xl border bg-card p-5 xl:col-span-2\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n Recent activity\n </h2>\n {isLoading && (\n <span className=\"text-xs text-muted-foreground\">\n Loading...\n </span>\n )}\n </div>\n <div className=\"mt-4 space-y-3\">\n {(data?.recentAudit || []).map((event) => (\n <div\n key={event.id}\n className=\"rounded-xl border bg-muted/30 px-4 py-3\"\n >\n <div className=\"text-sm font-medium text-foreground\">\n {event.summary}\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {event.actor} ·{\" \"}\n {new Date(event.createdAt).toLocaleString()}\n </div>\n </div>\n ))}\n {!isLoading && (data?.recentAudit?.length || 0) === 0 && (\n <div className=\"rounded-xl border border-dashed px-4 py-6 text-sm text-muted-foreground\">\n No activity yet.\n </div>\n )}\n </div>\n </section>\n\n <section className=\"rounded-2xl border bg-card p-5\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n Approval mode\n </h2>\n <div className=\"mt-4 rounded-xl border bg-muted/30 p-4\">\n <div className=\"text-sm font-medium text-muted-foreground\">\n Current policy\n </div>\n <div className=\"mt-2 text-2xl font-semibold text-foreground\">\n {data?.settings?.enabled ? \"Reviewed\" : \"Immediate\"}\n </div>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {data?.settings?.enabled\n ? \"Changes wait for approval before they apply.\"\n : \"Changes apply immediately and are recorded in audit.\"}\n </p>\n </div>\n <div className=\"mt-4 space-y-2\">\n {(data?.recentApprovals || []).map((approval) => (\n <div\n key={approval.id}\n className=\"rounded-xl border px-4 py-3\"\n >\n <div className=\"text-sm font-medium text-foreground\">\n {approval.summary}\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {approval.status} · requested by {approval.requestedBy}\n </div>\n </div>\n ))}\n {(data?.recentApprovals?.length || 0) === 0 && (\n <div className=\"rounded-xl border border-dashed px-4 py-6 text-sm text-muted-foreground\">\n No approval requests.\n </div>\n )}\n </div>\n </section>\n </div>\n </div>\n </details>\n </DispatchShell>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/workspace.tsx"],"names":[],"mappings":"AAiDA,wBAAgB,IAAI;;IAEnB;AAqaD,MAAM,CAAC,OAAO,UAAU,cAAc,4CA6HrC"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/workspace.tsx"],"names":[],"mappings":"AAkDA,wBAAgB,IAAI;;IAEnB;AAibD,MAAM,CAAC,OAAO,UAAU,cAAc,4CA0IrC"}
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
3
  import { useActionMutation, useActionQuery } from "@agent-native/core/client";
4
4
  import { toast } from "sonner";
5
- import { IconBook, IconChevronDown, IconChevronRight, IconCode, IconPlus, IconRefresh, IconTrash, IconUser, IconX, } from "@tabler/icons-react";
5
+ import { IconBook, IconChevronDown, IconChevronRight, IconCode, IconFileText, IconPlus, IconRefresh, IconTrash, IconUser, IconX, } from "@tabler/icons-react";
6
6
  import { DispatchShell } from "../../components/dispatch-shell.js";
7
7
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "../../components/ui/alert-dialog.js";
8
8
  import { Badge } from "../../components/ui/badge.js";
@@ -35,6 +35,12 @@ const KIND_CONFIG = {
35
35
  pathPrefix: "agents/",
36
36
  description: "Reusable agent profiles — specialist agents shared across apps",
37
37
  },
38
+ knowledge: {
39
+ label: "Knowledge",
40
+ icon: IconFileText,
41
+ pathPrefix: "context/",
42
+ description: "Knowledge packs — reusable GTM, product, and domain context for apps",
43
+ },
38
44
  };
39
45
  function AddResourceDialog() {
40
46
  const [open, setOpen] = useState(false);
@@ -58,15 +64,19 @@ function AddResourceDialog() {
58
64
  onError: (err) => toast.error(String(err)),
59
65
  });
60
66
  const kindInfo = KIND_CONFIG[kind];
61
- return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { children: [_jsx(IconPlus, { size: 16, className: "mr-1.5" }), "Add resource"] }) }), _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Add workspace resource" }), _jsx(DialogDescription, { children: "Create a skill, instruction, or agent profile that can be shared across workspace apps." })] }), _jsxs("div", { className: "space-y-4 py-2", children: [_jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Kind" }), _jsxs(Select, { value: kind, onValueChange: setKind, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "skill", children: "Skill" }), _jsx(SelectItem, { value: "instruction", children: "Instruction" }), _jsx(SelectItem, { value: "agent", children: "Agent" })] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Scope" }), _jsxs(Select, { value: scope, onValueChange: setScope, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All apps" }), _jsx(SelectItem, { value: "selected", children: "Selected apps only" })] })] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Name" }), _jsx(Input, { placeholder: kind === "skill"
67
+ return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { children: [_jsx(IconPlus, { size: 16, className: "mr-1.5" }), "Add resource"] }) }), _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Add workspace resource" }), _jsx(DialogDescription, { children: "Create a skill, instruction, or agent profile that can be shared across workspace apps." })] }), _jsxs("div", { className: "space-y-4 py-2", children: [_jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Kind" }), _jsxs(Select, { value: kind, onValueChange: setKind, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "skill", children: "Skill" }), _jsx(SelectItem, { value: "instruction", children: "Instruction" }), _jsx(SelectItem, { value: "agent", children: "Agent" }), _jsx(SelectItem, { value: "knowledge", children: "Knowledge pack" })] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Scope" }), _jsxs(Select, { value: scope, onValueChange: setScope, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All apps" }), _jsx(SelectItem, { value: "selected", children: "Selected apps only" })] })] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Name" }), _jsx(Input, { placeholder: kind === "skill"
62
68
  ? "Frontend Designer"
63
69
  : kind === "agent"
64
70
  ? "Research Specialist"
65
- : "Code Style Guide", value: name, onChange: (e) => setName(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Path" }), _jsx(Input, { placeholder: `${kindInfo?.pathPrefix || ""}${name.toLowerCase().replace(/\s+/g, "-") || "example"}.md`, value: path, onChange: (e) => setPath(e.target.value), className: "font-mono text-sm" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Resource path in target apps. Skills go in skills/, agents in agents/." })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Description (optional)" }), _jsx(Input, { placeholder: "Short description of what this resource does", value: description, onChange: (e) => setDescription(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Content" }), _jsx(Textarea, { placeholder: kind === "skill"
71
+ : kind === "knowledge"
72
+ ? "Core GTM Messaging"
73
+ : "Code Style Guide", value: name, onChange: (e) => setName(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Path" }), _jsx(Input, { placeholder: `${kindInfo?.pathPrefix || ""}${name.toLowerCase().replace(/\s+/g, "-") || "example"}.md`, value: path, onChange: (e) => setPath(e.target.value), className: "font-mono text-sm" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Resource path in target apps. Skills go in skills/, agents in agents/, knowledge packs in context/." })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Description (optional)" }), _jsx(Input, { placeholder: "Short description of what this resource does", value: description, onChange: (e) => setDescription(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Content" }), _jsx(Textarea, { placeholder: kind === "skill"
66
74
  ? "---\nname: my-skill\ndescription: What this skill teaches\n---\n\n# My Skill\n\n..."
67
75
  : kind === "agent"
68
76
  ? "---\nname: Research Specialist\ndescription: Handles research tasks\n---\n\n# Instructions\n\n..."
69
- : "# Instructions\n\nBehavioral rules and guidance for agents across apps...", value: content, onChange: (e) => setContent(e.target.value), rows: 12, className: "font-mono text-sm" })] })] }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: () => create.mutate({
77
+ : kind === "knowledge"
78
+ ? "# Core GTM Messaging\n\n## Positioning\n\n## ICP\n\n## Proof points\n\n## Source\n\n"
79
+ : "# Instructions\n\nBehavioral rules and guidance for agents across apps...", value: content, onChange: (e) => setContent(e.target.value), rows: 12, className: "font-mono text-sm" })] })] }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: () => create.mutate({
70
80
  kind: kind,
71
81
  name,
72
82
  description: description || undefined,
@@ -136,14 +146,15 @@ export default function WorkspaceRoute() {
136
146
  const skills = (resources || []).filter((r) => r.kind === "skill");
137
147
  const instructions = (resources || []).filter((r) => r.kind === "instruction");
138
148
  const agents = (resources || []).filter((r) => r.kind === "agent");
149
+ const knowledge = (resources || []).filter((r) => r.kind === "knowledge");
139
150
  function ResourceList({ items, emptyText, }) {
140
151
  if (items.length === 0) {
141
152
  return (_jsx("div", { className: "rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground", children: emptyText }));
142
153
  }
143
154
  return (_jsx("div", { className: "space-y-3", children: items.map((resource) => (_jsx(ResourceRow, { resource: resource, grants: grantsByResource[resource.id] || [] }, resource.id))) }));
144
155
  }
145
- return (_jsxs(DispatchShell, { title: "Workspace Resources", description: "Share skills, instructions, and agent profiles across workspace apps. Scope to all apps or grant per-app.", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-sm text-muted-foreground", children: isLoading
156
+ return (_jsxs(DispatchShell, { title: "Workspace Resources", description: "Share skills, instructions, agent profiles, and knowledge packs across workspace apps. Scope to all apps or grant per-app.", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-sm text-muted-foreground", children: isLoading
146
157
  ? "Loading..."
147
- : `${resources?.length || 0} resource${(resources?.length || 0) !== 1 ? "s" : ""}` }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", onClick: () => syncAll.mutate({}), disabled: syncAll.isPending || (resources?.length || 0) === 0, children: [_jsx(IconRefresh, { size: 16, className: syncAll.isPending ? "mr-1.5 animate-spin" : "mr-1.5" }), "Sync all"] }), _jsx(AddResourceDialog, {})] })] }), _jsxs(Tabs, { defaultValue: "skills", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "skills", children: ["Skills ", skills.length > 0 && `(${skills.length})`] }), _jsxs(TabsTrigger, { value: "instructions", children: ["Instructions ", instructions.length > 0 && `(${instructions.length})`] }), _jsxs(TabsTrigger, { value: "agents", children: ["Agents ", agents.length > 0 && `(${agents.length})`] })] }), _jsx(TabsContent, { value: "skills", className: "mt-4", children: _jsx(ResourceList, { items: skills, emptyText: "No workspace skills yet. Add a skill to share agent guidance across apps." }) }), _jsx(TabsContent, { value: "instructions", className: "mt-4", children: _jsx(ResourceList, { items: instructions, emptyText: "No workspace instructions yet. Add instructions to set behavioral rules across apps." }) }), _jsx(TabsContent, { value: "agents", className: "mt-4", children: _jsx(ResourceList, { items: agents, emptyText: "No workspace agents yet. Add a reusable agent profile to share specialist agents across apps." }) })] })] }));
158
+ : `${resources?.length || 0} resource${(resources?.length || 0) !== 1 ? "s" : ""}` }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", onClick: () => syncAll.mutate({}), disabled: syncAll.isPending || (resources?.length || 0) === 0, children: [_jsx(IconRefresh, { size: 16, className: syncAll.isPending ? "mr-1.5 animate-spin" : "mr-1.5" }), "Sync all"] }), _jsx(AddResourceDialog, {})] })] }), _jsxs(Tabs, { defaultValue: "skills", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "skills", children: ["Skills ", skills.length > 0 && `(${skills.length})`] }), _jsxs(TabsTrigger, { value: "instructions", children: ["Instructions ", instructions.length > 0 && `(${instructions.length})`] }), _jsxs(TabsTrigger, { value: "agents", children: ["Agents ", agents.length > 0 && `(${agents.length})`] }), _jsxs(TabsTrigger, { value: "knowledge", children: ["Knowledge ", knowledge.length > 0 && `(${knowledge.length})`] })] }), _jsx(TabsContent, { value: "skills", className: "mt-4", children: _jsx(ResourceList, { items: skills, emptyText: "No workspace skills yet. Add a skill to share agent guidance across apps." }) }), _jsx(TabsContent, { value: "instructions", className: "mt-4", children: _jsx(ResourceList, { items: instructions, emptyText: "No workspace instructions yet. Add instructions to set behavioral rules across apps." }) }), _jsx(TabsContent, { value: "agents", className: "mt-4", children: _jsx(ResourceList, { items: agents, emptyText: "No workspace agents yet. Add a reusable agent profile to share specialist agents across apps." }) }), _jsx(TabsContent, { value: "knowledge", className: "mt-4", children: _jsx(ResourceList, { items: knowledge, emptyText: "No knowledge packs yet. Add GTM, product, or domain context that apps can reuse." }) })] })] }));
148
159
  }
149
160
  //# sourceMappingURL=workspace.js.map