@agent-native/dispatch 0.23.3 → 0.23.5

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 (55) hide show
  1. package/dist/actions/provider-api-register.d.ts +11 -11
  2. package/dist/components/app-list-row.d.ts +1 -1
  3. package/dist/components/app-list-row.d.ts.map +1 -1
  4. package/dist/components/app-list-row.js +2 -2
  5. package/dist/components/app-list-row.js.map +1 -1
  6. package/dist/components/create-app-popover.d.ts.map +1 -1
  7. package/dist/components/create-app-popover.js +11 -0
  8. package/dist/components/create-app-popover.js.map +1 -1
  9. package/dist/components/dispatch-control-plane.d.ts.map +1 -1
  10. package/dist/components/dispatch-control-plane.js +3 -2
  11. package/dist/components/dispatch-control-plane.js.map +1 -1
  12. package/dist/components/layout/Layout.d.ts +1 -0
  13. package/dist/components/layout/Layout.d.ts.map +1 -1
  14. package/dist/components/layout/Layout.js +41 -3
  15. package/dist/components/layout/Layout.js.map +1 -1
  16. package/dist/components/layout/workspace-apps-rail.d.ts.map +1 -1
  17. package/dist/components/layout/workspace-apps-rail.js +2 -2
  18. package/dist/components/layout/workspace-apps-rail.js.map +1 -1
  19. package/dist/components/other-apps-section.d.ts.map +1 -1
  20. package/dist/components/other-apps-section.js +5 -1
  21. package/dist/components/other-apps-section.js.map +1 -1
  22. package/dist/config.d.ts +2 -0
  23. package/dist/config.d.ts.map +1 -1
  24. package/dist/config.js.map +1 -1
  25. package/dist/lib/other-apps.d.ts.map +1 -1
  26. package/dist/lib/other-apps.js +2 -0
  27. package/dist/lib/other-apps.js.map +1 -1
  28. package/dist/lib/workspace-apps.d.ts +3 -0
  29. package/dist/lib/workspace-apps.d.ts.map +1 -1
  30. package/dist/lib/workspace-apps.js +10 -0
  31. package/dist/lib/workspace-apps.js.map +1 -1
  32. package/dist/routes/pages/apps.d.ts.map +1 -1
  33. package/dist/routes/pages/apps.js +2 -1
  34. package/dist/routes/pages/apps.js.map +1 -1
  35. package/dist/server/plugins/auth.d.ts.map +1 -1
  36. package/dist/server/plugins/auth.js +1 -0
  37. package/dist/server/plugins/auth.js.map +1 -1
  38. package/package.json +3 -3
  39. package/src/components/app-list-row.tsx +3 -2
  40. package/src/components/create-app-popover.spec.tsx +26 -2
  41. package/src/components/create-app-popover.tsx +10 -0
  42. package/src/components/dispatch-control-plane.spec.tsx +1 -0
  43. package/src/components/dispatch-control-plane.tsx +8 -2
  44. package/src/components/layout/Layout.spec.tsx +9 -0
  45. package/src/components/layout/Layout.tsx +71 -4
  46. package/src/components/layout/workspace-apps-rail.tsx +2 -1
  47. package/src/components/other-apps-section.tsx +8 -1
  48. package/src/config.ts +2 -0
  49. package/src/lib/other-apps.spec.ts +26 -0
  50. package/src/lib/other-apps.ts +3 -0
  51. package/src/lib/workspace-apps.spec.ts +24 -1
  52. package/src/lib/workspace-apps.ts +15 -0
  53. package/src/routes/pages/apps.tsx +5 -2
  54. package/src/server/plugins/auth.spec.ts +45 -0
  55. package/src/server/plugins/auth.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-apps-rail.d.ts","sourceRoot":"","sources":["../../../src/components/layout/workspace-apps-rail.tsx"],"names":[],"mappings":"AAuBA,wBAAgB,iBAAiB,CAAC,EAChC,SAAiB,EACjB,UAAU,GACX,EAAE;IACD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,0DAqGA"}
1
+ {"version":3,"file":"workspace-apps-rail.d.ts","sourceRoot":"","sources":["../../../src/components/layout/workspace-apps-rail.tsx"],"names":[],"mappings":"AAwBA,wBAAgB,iBAAiB,CAAC,EAChC,SAAiB,EACjB,UAAU,GACX,EAAE;IACD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,0DAqGA"}
@@ -4,7 +4,7 @@ import { useT } from "@agent-native/core/client/i18n";
4
4
  import { IconApps } from "@tabler/icons-react";
5
5
  import { Link, useLocation } from "react-router";
6
6
  import { cn } from "../../lib/utils.js";
7
- import { workspaceAppIdFromRoute, workspaceAppRoute, workspaceAppHref, } from "../../lib/workspace-apps.js";
7
+ import { isWorkspaceAppVisibleInDefaultLaunchers, workspaceAppIdFromRoute, workspaceAppRoute, workspaceAppHref, } from "../../lib/workspace-apps.js";
8
8
  import { AppIcon } from "../app-icon.js";
9
9
  import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip.js";
10
10
  function appMatchesPath(app, pathname) {
@@ -22,7 +22,7 @@ export function WorkspaceAppsRail({ collapsed = false, onNavigate, }) {
22
22
  if (appsQuery.isError || !appsQuery.data)
23
23
  return null;
24
24
  const apps = appsQuery.data
25
- .filter((app) => !app.isDispatch &&
25
+ .filter((app) => isWorkspaceAppVisibleInDefaultLaunchers(app) &&
26
26
  !app.archived &&
27
27
  app.status !== "pending" &&
28
28
  !!workspaceAppHref(app))
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-apps-rail.js","sourceRoot":"","sources":["../../../src/components/layout/workspace-apps-rail.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { IconApps } from \"@tabler/icons-react\";\nimport { Link, useLocation } from \"react-router\";\n\nimport { cn } from \"../../lib/utils\";\nimport {\n workspaceAppIdFromRoute,\n workspaceAppRoute,\n workspaceAppHref,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\nimport { AppIcon } from \"../app-icon\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/tooltip\";\n\nfunction appMatchesPath(app: WorkspaceAppSummary, pathname: string): boolean {\n return workspaceAppIdFromRoute(pathname) === app.id;\n}\n\nfunction appLabel(app: WorkspaceAppSummary): string {\n return app.name.trim() || app.id;\n}\n\nexport function WorkspaceAppsRail({\n collapsed = false,\n onNavigate,\n}: {\n collapsed?: boolean;\n onNavigate?: () => void;\n}) {\n const t = useT();\n const location = useLocation();\n const appsQuery = useActionQuery<WorkspaceAppSummary[]>(\n \"list-workspace-apps\",\n {\n includeAgentCards: false,\n },\n );\n if (appsQuery.isError || !appsQuery.data) return null;\n\n const apps = appsQuery.data\n .filter(\n (app) =>\n !app.isDispatch &&\n !app.archived &&\n app.status !== \"pending\" &&\n !!workspaceAppHref(app),\n )\n .sort((a, b) => appLabel(a).localeCompare(appLabel(b)));\n\n if (apps.length === 0) return null;\n\n const renderAppLink = (app: WorkspaceAppSummary) => {\n const href = workspaceAppHref(app);\n if (!href) return null;\n\n const label = appLabel(app);\n const active = appMatchesPath(app, location.pathname);\n const link = (\n <Link\n to={workspaceAppRoute(app.id)}\n aria-current={active ? \"page\" : undefined}\n aria-label={collapsed ? label : undefined}\n onClick={onNavigate}\n className={cn(\n \"flex h-9 items-center rounded-md text-sm transition-colors\",\n collapsed ? \"w-9 justify-center\" : \"w-full gap-2 px-2 text-start\",\n active\n ? \"bg-sidebar-accent font-medium text-sidebar-accent-foreground\"\n : \"text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n )}\n >\n <AppIcon\n id={app.id}\n name={label}\n size=\"sm\"\n monochrome\n className={cn(\"size-5 rounded-md\", active && \"ring-1 ring-ring/30\")}\n />\n {!collapsed ? <span className=\"truncate\">{label}</span> : null}\n </Link>\n );\n\n if (!collapsed) return link;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{link}</TooltipTrigger>\n <TooltipContent side=\"right\">{label}</TooltipContent>\n </Tooltip>\n );\n };\n\n return (\n <div\n className={cn(\n \"mt-4 border-t border-sidebar-border pt-3\",\n collapsed ? \"px-1.5\" : \"px-2\",\n )}\n data-dispatch-apps-rail\n >\n {!collapsed ? (\n <div className=\"mb-1 flex items-center gap-1.5 px-2 text-[11px] font-medium uppercase tracking-wide text-sidebar-foreground/45\">\n <IconApps size={13} />\n <span>\n {t(\"dispatch.pages.workspaceApps\", {\n defaultValue: \"Workspace apps\",\n })}\n </span>\n </div>\n ) : (\n <span className=\"sr-only\">\n {t(\"dispatch.pages.workspaceApps\", {\n defaultValue: \"Workspace apps\",\n })}\n </span>\n )}\n <ul\n className={cn(\n collapsed ? \"flex flex-col items-center gap-1\" : \"space-y-0.5\",\n )}\n >\n {apps.map((app) => {\n const href = workspaceAppHref(app);\n if (!href) return null;\n return <li key={app.id}>{renderAppLink(app)}</li>;\n })}\n </ul>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"workspace-apps-rail.js","sourceRoot":"","sources":["../../../src/components/layout/workspace-apps-rail.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { IconApps } from \"@tabler/icons-react\";\nimport { Link, useLocation } from \"react-router\";\n\nimport { cn } from \"../../lib/utils\";\nimport {\n isWorkspaceAppVisibleInDefaultLaunchers,\n workspaceAppIdFromRoute,\n workspaceAppRoute,\n workspaceAppHref,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\nimport { AppIcon } from \"../app-icon\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/tooltip\";\n\nfunction appMatchesPath(app: WorkspaceAppSummary, pathname: string): boolean {\n return workspaceAppIdFromRoute(pathname) === app.id;\n}\n\nfunction appLabel(app: WorkspaceAppSummary): string {\n return app.name.trim() || app.id;\n}\n\nexport function WorkspaceAppsRail({\n collapsed = false,\n onNavigate,\n}: {\n collapsed?: boolean;\n onNavigate?: () => void;\n}) {\n const t = useT();\n const location = useLocation();\n const appsQuery = useActionQuery<WorkspaceAppSummary[]>(\n \"list-workspace-apps\",\n {\n includeAgentCards: false,\n },\n );\n if (appsQuery.isError || !appsQuery.data) return null;\n\n const apps = appsQuery.data\n .filter(\n (app) =>\n isWorkspaceAppVisibleInDefaultLaunchers(app) &&\n !app.archived &&\n app.status !== \"pending\" &&\n !!workspaceAppHref(app),\n )\n .sort((a, b) => appLabel(a).localeCompare(appLabel(b)));\n\n if (apps.length === 0) return null;\n\n const renderAppLink = (app: WorkspaceAppSummary) => {\n const href = workspaceAppHref(app);\n if (!href) return null;\n\n const label = appLabel(app);\n const active = appMatchesPath(app, location.pathname);\n const link = (\n <Link\n to={workspaceAppRoute(app.id)}\n aria-current={active ? \"page\" : undefined}\n aria-label={collapsed ? label : undefined}\n onClick={onNavigate}\n className={cn(\n \"flex h-9 items-center rounded-md text-sm transition-colors\",\n collapsed ? \"w-9 justify-center\" : \"w-full gap-2 px-2 text-start\",\n active\n ? \"bg-sidebar-accent font-medium text-sidebar-accent-foreground\"\n : \"text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n )}\n >\n <AppIcon\n id={app.id}\n name={label}\n size=\"sm\"\n monochrome\n className={cn(\"size-5 rounded-md\", active && \"ring-1 ring-ring/30\")}\n />\n {!collapsed ? <span className=\"truncate\">{label}</span> : null}\n </Link>\n );\n\n if (!collapsed) return link;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{link}</TooltipTrigger>\n <TooltipContent side=\"right\">{label}</TooltipContent>\n </Tooltip>\n );\n };\n\n return (\n <div\n className={cn(\n \"mt-4 border-t border-sidebar-border pt-3\",\n collapsed ? \"px-1.5\" : \"px-2\",\n )}\n data-dispatch-apps-rail\n >\n {!collapsed ? (\n <div className=\"mb-1 flex items-center gap-1.5 px-2 text-[11px] font-medium uppercase tracking-wide text-sidebar-foreground/45\">\n <IconApps size={13} />\n <span>\n {t(\"dispatch.pages.workspaceApps\", {\n defaultValue: \"Workspace apps\",\n })}\n </span>\n </div>\n ) : (\n <span className=\"sr-only\">\n {t(\"dispatch.pages.workspaceApps\", {\n defaultValue: \"Workspace apps\",\n })}\n </span>\n )}\n <ul\n className={cn(\n collapsed ? \"flex flex-col items-center gap-1\" : \"space-y-0.5\",\n )}\n >\n {apps.map((app) => {\n const href = workspaceAppHref(app);\n if (!href) return null;\n return <li key={app.id}>{renderAppLink(app)}</li>;\n })}\n </ul>\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"other-apps-section.d.ts","sourceRoot":"","sources":["../../src/components/other-apps-section.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAUxD,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,+BAA+B,EACpC,KAAK,uBAAuB,EAC7B,MAAM,2BAA2B,CAAC;AAEnC,KAAK,aAAa,GACd;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,wBAAwB,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAepD,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,aAAa,EACb,aAAa,GACd,EAAE;IACD,SAAS,CAAC,EAAE,+BAA+B,CAAC;IAC5C,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,aAAa,EAAE,cAAc,EAAE,CAAC;CACjC,GAAG,aAAa,EAAE,CAsBlB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,aAAkB,EAClB,aAAa,EACb,gBAAwB,EACxB,oBAA4B,EAC5B,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,cAAc,EACd,OAAsB,EACtB,cAAsB,EACtB,SAAS,GACV,EAAE;IACD,SAAS,CAAC,EAAE,+BAA+B,CAAC;IAC5C,aAAa,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACtC,aAAa,EAAE,cAAc,EAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAC9B,kBAAkB,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAClD,cAAc,CAAC,EAAE,CACf,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,wBAAwB,KAC/B,IAAI,CAAC;IACV,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,0DAmEA"}
1
+ {"version":3,"file":"other-apps-section.d.ts","sourceRoot":"","sources":["../../src/components/other-apps-section.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAWxD,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,+BAA+B,EACpC,KAAK,uBAAuB,EAC7B,MAAM,2BAA2B,CAAC;AAEnC,KAAK,aAAa,GACd;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,wBAAwB,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAepD,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,aAAa,EACb,aAAa,GACd,EAAE;IACD,SAAS,CAAC,EAAE,+BAA+B,CAAC;IAC5C,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,aAAa,EAAE,cAAc,EAAE,CAAC;CACjC,GAAG,aAAa,EAAE,CA4BlB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,aAAkB,EAClB,aAAa,EACb,gBAAwB,EACxB,oBAA4B,EAC5B,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,cAAc,EACd,OAAsB,EACtB,cAAsB,EACtB,SAAS,GACV,EAAE;IACD,SAAS,CAAC,EAAE,+BAA+B,CAAC;IAC5C,aAAa,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACtC,aAAa,EAAE,cAAc,EAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAC9B,kBAAkB,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAClD,cAAc,CAAC,EAAE,CACf,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,wBAAwB,KAC/B,IAAI,CAAC;IACV,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,0DAmEA"}
@@ -2,6 +2,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
2
2
  import { useT } from "@agent-native/core/client/i18n";
3
3
  import { filterOtherApps } from "../lib/other-apps.js";
4
4
  import { cn } from "../lib/utils.js";
5
+ import { isDefaultWorkspaceAppHiddenId } from "../lib/workspace-apps.js";
5
6
  import { ActionQueryError } from "./action-query-error.js";
6
7
  import { APP_LIST_GRID_CLASS, APP_LIST_GRID_ROW_CLASS, AppList, } from "./app-list-row.js";
7
8
  import { ConnectedAppCard } from "./connected-app-card.js";
@@ -23,7 +24,10 @@ export function mergeOtherAppEntries({ templates, connectedApps, workspaceApps,
23
24
  const entries = [];
24
25
  for (const template of getTemplateItems(templates)) {
25
26
  const id = templateKey(template);
26
- if (!id || template.installed || workspaceAppIds.has(id))
27
+ if (!id ||
28
+ isDefaultWorkspaceAppHiddenId(id) ||
29
+ template.installed ||
30
+ workspaceAppIds.has(id))
27
31
  continue;
28
32
  seen.add(id);
29
33
  entries.push({ kind: "template", template });
@@ -1 +1 @@
1
- {"version":3,"file":"other-apps-section.js","sourceRoot":"","sources":["../../src/components/other-apps-section.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\n\nimport { filterOtherApps, type ConnectedAppSummary } from \"../lib/other-apps\";\nimport type { WorkspaceAppId } from \"../lib/other-apps\";\nimport { cn } from \"../lib/utils\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n APP_LIST_GRID_ROW_CLASS,\n AppList,\n} from \"./app-list-row\";\nimport { ConnectedAppCard } from \"./connected-app-card\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport {\n WorkspaceTemplateCard,\n type CuratedWorkspaceTemplate,\n type CuratedWorkspaceTemplatesResult,\n type WorkspaceTemplateLabels,\n} from \"./workspace-template-card\";\n\ntype OtherAppEntry =\n | { kind: \"template\"; template: CuratedWorkspaceTemplate }\n | { kind: \"connected\"; app: ConnectedAppSummary };\n\nfunction templateKey(template: CuratedWorkspaceTemplate): string {\n return (template.templateId || template.id || template.appId || template.name)\n .trim()\n .toLowerCase();\n}\n\nfunction getTemplateItems(\n result: CuratedWorkspaceTemplatesResult | undefined,\n): CuratedWorkspaceTemplate[] {\n if (!result) return [];\n return Array.isArray(result) ? result : result.templates;\n}\n\nexport function mergeOtherAppEntries({\n templates,\n connectedApps,\n workspaceApps,\n}: {\n templates?: CuratedWorkspaceTemplatesResult;\n connectedApps: ConnectedAppSummary[];\n workspaceApps: WorkspaceAppId[];\n}): OtherAppEntry[] {\n const workspaceAppIds = new Set(\n workspaceApps.map((app) => app.id.trim().toLowerCase()),\n );\n const seen = new Set<string>();\n const entries: OtherAppEntry[] = [];\n\n for (const template of getTemplateItems(templates)) {\n const id = templateKey(template);\n if (!id || template.installed || workspaceAppIds.has(id)) continue;\n seen.add(id);\n entries.push({ kind: \"template\", template });\n }\n\n for (const app of filterOtherApps(connectedApps, workspaceApps)) {\n const id = app.id.trim().toLowerCase();\n if (seen.has(id)) continue;\n seen.add(id);\n entries.push({ kind: \"connected\", app });\n }\n\n return entries;\n}\n\nexport function OtherAppsSection({\n templates,\n connectedApps = [],\n workspaceApps,\n templatesLoading = false,\n connectedAppsLoading = false,\n templatesError,\n connectedAppsError,\n onRetryTemplates,\n onRetryConnectedApps,\n templateLabels,\n onRemixSuccess,\n heading = \"Other apps\",\n embeddedInList = false,\n className,\n}: {\n templates?: CuratedWorkspaceTemplatesResult;\n connectedApps?: ConnectedAppSummary[];\n workspaceApps: WorkspaceAppId[];\n templatesLoading?: boolean;\n connectedAppsLoading?: boolean;\n templatesError?: Error | null;\n connectedAppsError?: Error | null;\n onRetryTemplates?: () => void;\n onRetryConnectedApps?: () => void;\n templateLabels?: Partial<WorkspaceTemplateLabels>;\n onRemixSuccess?: (\n result: unknown,\n template: CuratedWorkspaceTemplate,\n ) => void;\n heading?: string | null;\n embeddedInList?: boolean;\n className?: string;\n}) {\n const t = useT();\n const entries = mergeOtherAppEntries({\n templates,\n connectedApps,\n workspaceApps,\n });\n const isLoading = templatesLoading || connectedAppsLoading;\n const hasError = Boolean(templatesError || connectedAppsError);\n\n if (!isLoading && !hasError && entries.length === 0) return null;\n\n const content = (\n <>\n {heading ? (\n <div className=\"flex min-w-0 items-center\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.otherApps\", { defaultValue: heading })}\n </h2>\n </div>\n ) : null}\n\n {templatesError ? (\n <ActionQueryError\n error={templatesError}\n onRetry={() => onRetryTemplates?.()}\n />\n ) : null}\n {connectedAppsError ? (\n <ActionQueryError\n error={connectedAppsError}\n onRetry={() => onRetryConnectedApps?.()}\n />\n ) : null}\n\n {isLoading && entries.length === 0 ? (\n embeddedInList ? (\n <OtherAppsSkeletonRows />\n ) : (\n <OtherAppsSkeletonList />\n )\n ) : entries.length > 0 ? (\n entries.map((entry) =>\n entry.kind === \"template\" ? (\n <WorkspaceTemplateCard\n key={`template:${templateKey(entry.template)}`}\n template={entry.template}\n labels={templateLabels}\n catalog\n className={APP_LIST_GRID_ROW_CLASS}\n onRemixSuccess={onRemixSuccess}\n />\n ) : (\n <ConnectedAppCard\n key={`connected:${entry.app.id}`}\n app={entry.app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ),\n )\n ) : null}\n </>\n );\n\n if (embeddedInList) return content;\n\n return <section className={cn(\"space-y-3\", className)}>{content}</section>;\n}\n\nfunction OtherAppsSkeletonList() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 4 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-xl\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-9 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nfunction OtherAppsSkeletonRows() {\n return (\n <>\n {Array.from({ length: 4 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-xl\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-9 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </>\n );\n}\n"]}
1
+ {"version":3,"file":"other-apps-section.js","sourceRoot":"","sources":["../../src/components/other-apps-section.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useT } from \"@agent-native/core/client/i18n\";\n\nimport { filterOtherApps, type ConnectedAppSummary } from \"../lib/other-apps\";\nimport type { WorkspaceAppId } from \"../lib/other-apps\";\nimport { cn } from \"../lib/utils\";\nimport { isDefaultWorkspaceAppHiddenId } from \"../lib/workspace-apps\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n APP_LIST_GRID_ROW_CLASS,\n AppList,\n} from \"./app-list-row\";\nimport { ConnectedAppCard } from \"./connected-app-card\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport {\n WorkspaceTemplateCard,\n type CuratedWorkspaceTemplate,\n type CuratedWorkspaceTemplatesResult,\n type WorkspaceTemplateLabels,\n} from \"./workspace-template-card\";\n\ntype OtherAppEntry =\n | { kind: \"template\"; template: CuratedWorkspaceTemplate }\n | { kind: \"connected\"; app: ConnectedAppSummary };\n\nfunction templateKey(template: CuratedWorkspaceTemplate): string {\n return (template.templateId || template.id || template.appId || template.name)\n .trim()\n .toLowerCase();\n}\n\nfunction getTemplateItems(\n result: CuratedWorkspaceTemplatesResult | undefined,\n): CuratedWorkspaceTemplate[] {\n if (!result) return [];\n return Array.isArray(result) ? result : result.templates;\n}\n\nexport function mergeOtherAppEntries({\n templates,\n connectedApps,\n workspaceApps,\n}: {\n templates?: CuratedWorkspaceTemplatesResult;\n connectedApps: ConnectedAppSummary[];\n workspaceApps: WorkspaceAppId[];\n}): OtherAppEntry[] {\n const workspaceAppIds = new Set(\n workspaceApps.map((app) => app.id.trim().toLowerCase()),\n );\n const seen = new Set<string>();\n const entries: OtherAppEntry[] = [];\n\n for (const template of getTemplateItems(templates)) {\n const id = templateKey(template);\n if (\n !id ||\n isDefaultWorkspaceAppHiddenId(id) ||\n template.installed ||\n workspaceAppIds.has(id)\n )\n continue;\n seen.add(id);\n entries.push({ kind: \"template\", template });\n }\n\n for (const app of filterOtherApps(connectedApps, workspaceApps)) {\n const id = app.id.trim().toLowerCase();\n if (seen.has(id)) continue;\n seen.add(id);\n entries.push({ kind: \"connected\", app });\n }\n\n return entries;\n}\n\nexport function OtherAppsSection({\n templates,\n connectedApps = [],\n workspaceApps,\n templatesLoading = false,\n connectedAppsLoading = false,\n templatesError,\n connectedAppsError,\n onRetryTemplates,\n onRetryConnectedApps,\n templateLabels,\n onRemixSuccess,\n heading = \"Other apps\",\n embeddedInList = false,\n className,\n}: {\n templates?: CuratedWorkspaceTemplatesResult;\n connectedApps?: ConnectedAppSummary[];\n workspaceApps: WorkspaceAppId[];\n templatesLoading?: boolean;\n connectedAppsLoading?: boolean;\n templatesError?: Error | null;\n connectedAppsError?: Error | null;\n onRetryTemplates?: () => void;\n onRetryConnectedApps?: () => void;\n templateLabels?: Partial<WorkspaceTemplateLabels>;\n onRemixSuccess?: (\n result: unknown,\n template: CuratedWorkspaceTemplate,\n ) => void;\n heading?: string | null;\n embeddedInList?: boolean;\n className?: string;\n}) {\n const t = useT();\n const entries = mergeOtherAppEntries({\n templates,\n connectedApps,\n workspaceApps,\n });\n const isLoading = templatesLoading || connectedAppsLoading;\n const hasError = Boolean(templatesError || connectedAppsError);\n\n if (!isLoading && !hasError && entries.length === 0) return null;\n\n const content = (\n <>\n {heading ? (\n <div className=\"flex min-w-0 items-center\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.otherApps\", { defaultValue: heading })}\n </h2>\n </div>\n ) : null}\n\n {templatesError ? (\n <ActionQueryError\n error={templatesError}\n onRetry={() => onRetryTemplates?.()}\n />\n ) : null}\n {connectedAppsError ? (\n <ActionQueryError\n error={connectedAppsError}\n onRetry={() => onRetryConnectedApps?.()}\n />\n ) : null}\n\n {isLoading && entries.length === 0 ? (\n embeddedInList ? (\n <OtherAppsSkeletonRows />\n ) : (\n <OtherAppsSkeletonList />\n )\n ) : entries.length > 0 ? (\n entries.map((entry) =>\n entry.kind === \"template\" ? (\n <WorkspaceTemplateCard\n key={`template:${templateKey(entry.template)}`}\n template={entry.template}\n labels={templateLabels}\n catalog\n className={APP_LIST_GRID_ROW_CLASS}\n onRemixSuccess={onRemixSuccess}\n />\n ) : (\n <ConnectedAppCard\n key={`connected:${entry.app.id}`}\n app={entry.app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ),\n )\n ) : null}\n </>\n );\n\n if (embeddedInList) return content;\n\n return <section className={cn(\"space-y-3\", className)}>{content}</section>;\n}\n\nfunction OtherAppsSkeletonList() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 4 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-xl\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-9 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nfunction OtherAppsSkeletonRows() {\n return (\n <>\n {Array.from({ length: 4 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-xl\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-9 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </>\n );\n}\n"]}
package/dist/config.d.ts CHANGED
@@ -12,6 +12,8 @@ export interface DispatchAuthConfig {
12
12
  googleOnly?: boolean;
13
13
  /** Marketing/branding copy passed straight through to `createAuthPlugin`. */
14
14
  marketing?: Record<string, unknown>;
15
+ /** Exact framework routes that perform their own authentication checks. */
16
+ publicPaths?: string[];
15
17
  }
16
18
  export interface DispatchIntegrationsConfig {
17
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,0BAA0B,CAAC;CAC3C"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,0BAA0B,CAAC;CAC3C"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG","sourcesContent":["/**\n * Configuration shape for `setupDispatch(config)`. Captures every workspace\n * customization point we identified during the framework→workspace drift\n * audit so consumers can express their environment without forking source.\n */\n\nexport interface DispatchAuthConfig {\n /**\n * When true, only Google OAuth is shown on the login screen and other\n * providers are hidden. Used by Builder's own workspace, which enforces\n * Google SSO for its org.\n */\n googleOnly?: boolean;\n /** Marketing/branding copy passed straight through to `createAuthPlugin`. */\n marketing?: Record<string, unknown>;\n}\n\nexport interface DispatchIntegrationsConfig {\n /**\n * Append or replace the integrations agent's system-prompt guidance.\n * Pass a string to replace the default; pass a function to mutate it.\n */\n systemPrompt?: string | ((defaultPrompt: string) => string);\n}\n\nexport interface DispatchConfig {\n auth?: DispatchAuthConfig;\n /**\n * Exact Chrome Web Store or managed-install extension ids allowed to pair\n * with Dispatch browser chat. Wildcards are not supported.\n */\n browserExtensionIds?: readonly string[];\n /**\n * App IDs to hide from `list-connected-agents` results. Used to filter\n * out first-party Builder apps (calls, issues, macros, …) from the\n * Connected Agents list when those apps aren't shipped to end users.\n */\n hiddenAgentIds?: string[];\n integrations?: DispatchIntegrationsConfig;\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG","sourcesContent":["/**\n * Configuration shape for `setupDispatch(config)`. Captures every workspace\n * customization point we identified during the framework→workspace drift\n * audit so consumers can express their environment without forking source.\n */\n\nexport interface DispatchAuthConfig {\n /**\n * When true, only Google OAuth is shown on the login screen and other\n * providers are hidden. Used by Builder's own workspace, which enforces\n * Google SSO for its org.\n */\n googleOnly?: boolean;\n /** Marketing/branding copy passed straight through to `createAuthPlugin`. */\n marketing?: Record<string, unknown>;\n /** Exact framework routes that perform their own authentication checks. */\n publicPaths?: string[];\n}\n\nexport interface DispatchIntegrationsConfig {\n /**\n * Append or replace the integrations agent's system-prompt guidance.\n * Pass a string to replace the default; pass a function to mutate it.\n */\n systemPrompt?: string | ((defaultPrompt: string) => string);\n}\n\nexport interface DispatchConfig {\n auth?: DispatchAuthConfig;\n /**\n * Exact Chrome Web Store or managed-install extension ids allowed to pair\n * with Dispatch browser chat. Wildcards are not supported.\n */\n browserExtensionIds?: readonly string[];\n /**\n * App IDs to hide from `list-connected-agents` results. Used to filter\n * out first-party Builder apps (calls, issues, macros, …) from the\n * Connected Agents list when those apps aren't shipped to end users.\n */\n hiddenAgentIds?: string[];\n integrations?: DispatchIntegrationsConfig;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"other-apps.d.ts","sourceRoot":"","sources":["../../src/lib/other-apps.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAaD,wBAAgB,eAAe,CAC7B,aAAa,EAAE,mBAAmB,EAAE,EACpC,aAAa,EAAE,cAAc,EAAE,GAC9B,mBAAmB,EAAE,CAuBvB"}
1
+ {"version":3,"file":"other-apps.d.ts","sourceRoot":"","sources":["../../src/lib/other-apps.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAaD,wBAAgB,eAAe,CAC7B,aAAa,EAAE,mBAAmB,EAAE,EACpC,aAAa,EAAE,cAAc,EAAE,GAC9B,mBAAmB,EAAE,CAwBvB"}
@@ -1,3 +1,4 @@
1
+ import { isDefaultWorkspaceAppHiddenId } from "./workspace-apps.js";
1
2
  const HIDDEN_OTHER_APP_IDS = new Set(["crm", "research"]);
2
3
  function isHttpUrl(value) {
3
4
  try {
@@ -18,6 +19,7 @@ export function filterOtherApps(connectedApps, workspaceApps) {
18
19
  .filter((app) => {
19
20
  const id = app.id.trim().toLowerCase();
20
21
  if (!id ||
22
+ isDefaultWorkspaceAppHiddenId(id) ||
21
23
  HIDDEN_OTHER_APP_IDS.has(id) ||
22
24
  workspaceAppIds.has(id) ||
23
25
  seen.has(id))
@@ -1 +1 @@
1
- {"version":3,"file":"other-apps.js","sourceRoot":"","sources":["../../src/lib/other-apps.ts"],"names":[],"mappings":"AAcA,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;AAE1D,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,aAAoC,EACpC,aAA+B;IAE/B,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;QAC9B,UAAU;QACV,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;KAC3D,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,OAAO,aAAa;SACjB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;QACd,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACvC,IACE,CAAC,EAAE;YACH,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAEZ,OAAO,KAAK,CAAC;QACf,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW;YAAE,OAAO,KAAK,CAAC;QAC7C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAClD,CAAC","sourcesContent":["export interface ConnectedAppSummary {\n id: string;\n name: string;\n description?: string;\n url: string;\n color?: string;\n source?: \"builtin\" | \"custom\" | \"workspace\";\n}\n\nexport interface WorkspaceAppId {\n id: string;\n isDispatch?: boolean;\n}\n\nconst HIDDEN_OTHER_APP_IDS = new Set([\"crm\", \"research\"]);\n\nfunction isHttpUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nexport function filterOtherApps(\n connectedApps: ConnectedAppSummary[],\n workspaceApps: WorkspaceAppId[],\n): ConnectedAppSummary[] {\n const workspaceAppIds = new Set([\n \"dispatch\",\n ...workspaceApps.map((app) => app.id.trim().toLowerCase()),\n ]);\n const seen = new Set<string>();\n\n return connectedApps\n .filter((app) => {\n const id = app.id.trim().toLowerCase();\n if (\n !id ||\n HIDDEN_OTHER_APP_IDS.has(id) ||\n workspaceAppIds.has(id) ||\n seen.has(id)\n )\n return false;\n if (app.source === \"workspace\") return false;\n if (!isHttpUrl(app.url)) return false;\n seen.add(id);\n return true;\n })\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n"]}
1
+ {"version":3,"file":"other-apps.js","sourceRoot":"","sources":["../../src/lib/other-apps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAgBjE,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;AAE1D,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,aAAoC,EACpC,aAA+B;IAE/B,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;QAC9B,UAAU;QACV,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;KAC3D,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,OAAO,aAAa;SACjB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;QACd,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACvC,IACE,CAAC,EAAE;YACH,6BAA6B,CAAC,EAAE,CAAC;YACjC,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAEZ,OAAO,KAAK,CAAC;QACf,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW;YAAE,OAAO,KAAK,CAAC;QAC7C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAClD,CAAC","sourcesContent":["import { isDefaultWorkspaceAppHiddenId } from \"./workspace-apps\";\n\nexport interface ConnectedAppSummary {\n id: string;\n name: string;\n description?: string;\n url: string;\n color?: string;\n source?: \"builtin\" | \"custom\" | \"workspace\";\n}\n\nexport interface WorkspaceAppId {\n id: string;\n isDispatch?: boolean;\n}\n\nconst HIDDEN_OTHER_APP_IDS = new Set([\"crm\", \"research\"]);\n\nfunction isHttpUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nexport function filterOtherApps(\n connectedApps: ConnectedAppSummary[],\n workspaceApps: WorkspaceAppId[],\n): ConnectedAppSummary[] {\n const workspaceAppIds = new Set([\n \"dispatch\",\n ...workspaceApps.map((app) => app.id.trim().toLowerCase()),\n ]);\n const seen = new Set<string>();\n\n return connectedApps\n .filter((app) => {\n const id = app.id.trim().toLowerCase();\n if (\n !id ||\n isDefaultWorkspaceAppHiddenId(id) ||\n HIDDEN_OTHER_APP_IDS.has(id) ||\n workspaceAppIds.has(id) ||\n seen.has(id)\n )\n return false;\n if (app.source === \"workspace\") return false;\n if (!isHttpUrl(app.url)) return false;\n seen.add(id);\n return true;\n })\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n"]}
@@ -23,6 +23,9 @@ export interface WorkspaceAppSummary {
23
23
  agentSkillsCount?: number | null;
24
24
  archived?: boolean;
25
25
  }
26
+ export declare function isDispatchWorkspaceAppId(appId: string): boolean;
27
+ export declare function isDefaultWorkspaceAppHiddenId(appId: string): boolean;
28
+ export declare function isWorkspaceAppVisibleInDefaultLaunchers(app: Pick<WorkspaceAppSummary, "id" | "isDispatch">): boolean;
26
29
  export declare function workspaceAppRoute(appId: string): string;
27
30
  export declare function workspaceAppIdFromRoute(pathname: string): string | null;
28
31
  export declare function workspaceAppHref(app: WorkspaceAppSummary): string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-apps.d.ts","sourceRoot":"","sources":["../../src/lib/workspace-apps.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUvE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAUxE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,SAAS,mBAAmB,EAAE,GAAG,SAAS,GAC/C,mBAAmB,EAAE,CAcvB"}
1
+ {"version":3,"file":"workspace-apps.d.ts","sourceRoot":"","sources":["../../src/lib/workspace-apps.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGpE;AAED,wBAAgB,uCAAuC,CACrD,GAAG,EAAE,IAAI,CAAC,mBAAmB,EAAE,IAAI,GAAG,YAAY,CAAC,GAClD,OAAO,CAET;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUvE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAUxE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,SAAS,mBAAmB,EAAE,GAAG,SAAS,GAC/C,mBAAmB,EAAE,CAcvB"}
@@ -1,5 +1,15 @@
1
1
  import { CHAT_FIRST_DEFAULT_APP_IDS } from "@agent-native/core/client/chat-first";
2
2
  import { withBuilderUtmTrackingParams } from "@agent-native/core/shared/builder-link-tracking";
3
+ export function isDispatchWorkspaceAppId(appId) {
4
+ return appId.trim().toLowerCase() === "dispatch";
5
+ }
6
+ export function isDefaultWorkspaceAppHiddenId(appId) {
7
+ const normalized = appId.trim().toLowerCase();
8
+ return normalized === "chat" || isDispatchWorkspaceAppId(normalized);
9
+ }
10
+ export function isWorkspaceAppVisibleInDefaultLaunchers(app) {
11
+ return !app.isDispatch && !isDefaultWorkspaceAppHiddenId(app.id);
12
+ }
3
13
  export function workspaceAppRoute(appId) {
4
14
  return `/apps/${encodeURIComponent(appId)}`;
5
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-apps.js","sourceRoot":"","sources":["../../src/lib/workspace-apps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAClF,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AA4B/F,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,SAAS,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACzD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,OAAO,KAAK,IAAI,IAAI,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,+DAA+D;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAwB;IACvD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC,UAAU;YACnB,CAAC,CAAC,4BAA4B,CAAC,GAAG,CAAC,UAAU,EAAE;gBAC3C,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,iBAAiB;aAC3B,CAAC;YACJ,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAwB;IAC3D,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,IAAgD;IAEhD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA+B,CAAC;IACtD,KAAK,MAAM,EAAE,IAAI,0BAA0B,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE;YACb,EAAE;YACF,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9C,IAAI,EAAE,IAAI,EAAE,EAAE;YACd,GAAG,EAAE,IAAI;YACT,MAAM,EAAE,OAAO;SAChB,CAAC,CAAC;IACL,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE;QAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAEtD,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["import { CHAT_FIRST_DEFAULT_APP_IDS } from \"@agent-native/core/client/chat-first\";\nimport { withBuilderUtmTrackingParams } from \"@agent-native/core/shared/builder-link-tracking\";\n\nexport interface WorkspaceAppSummary {\n id: string;\n name: string;\n description?: string;\n path: string;\n url?: string | null;\n isDispatch?: boolean;\n audience?: \"internal\" | \"public\";\n publicPaths?: string[];\n protectedPaths?: string[];\n status?: \"ready\" | \"pending\";\n statusLabel?: string;\n builderUrl?: string | null;\n branchName?: string | null;\n createdAt?: string | null;\n createdBy?: string | null;\n owner?: string | null;\n teams?: string[];\n agentCardUrl?: string | null;\n agentCardReachable?: boolean;\n a2aEndpointUrl?: string | null;\n agentName?: string | null;\n agentSkillsCount?: number | null;\n archived?: boolean;\n}\n\nexport function workspaceAppRoute(appId: string): string {\n return `/apps/${encodeURIComponent(appId)}`;\n}\n\nexport function workspaceAppIdFromRoute(pathname: string): string | null {\n const match = pathname.match(/^\\/apps\\/([^/]+)(?:\\/|$)/);\n if (!match) return null;\n try {\n const appId = decodeURIComponent(match[1]).trim();\n return appId || null;\n } catch {\n // coercion-ok: malformed app routes are inactive, not app ids.\n return null;\n }\n}\n\nexport function workspaceAppHref(app: WorkspaceAppSummary): string | null {\n if (app.status === \"pending\") {\n return app.builderUrl\n ? withBuilderUtmTrackingParams(app.builderUrl, {\n campaign: \"product\",\n content: \"dispatch_branch\",\n })\n : null;\n }\n return app.path || app.url || null;\n}\n\nexport function isPendingBuilderHref(app: WorkspaceAppSummary): boolean {\n return app.status === \"pending\" && !!app.builderUrl;\n}\n\n/**\n * Keep the chat-first rail useful before a workspace manifest is populated.\n * Mounted workspace rows still win, so custom names and routes remain the\n * source of truth once an app exists in the workspace.\n */\nexport function mergeChatFirstWorkspaceApps(\n apps: readonly WorkspaceAppSummary[] | undefined,\n): WorkspaceAppSummary[] {\n const merged = new Map<string, WorkspaceAppSummary>();\n for (const id of CHAT_FIRST_DEFAULT_APP_IDS) {\n merged.set(id, {\n id,\n name: id.charAt(0).toUpperCase() + id.slice(1),\n path: `/${id}`,\n url: null,\n status: \"ready\",\n });\n }\n for (const app of apps ?? []) merged.set(app.id, app);\n\n return [...merged.values()];\n}\n"]}
1
+ {"version":3,"file":"workspace-apps.js","sourceRoot":"","sources":["../../src/lib/workspace-apps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAClF,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AA4B/F,MAAM,UAAU,wBAAwB,CAAC,KAAa;IACpD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,KAAa;IACzD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,UAAU,KAAK,MAAM,IAAI,wBAAwB,CAAC,UAAU,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,uCAAuC,CACrD,GAAmD;IAEnD,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,6BAA6B,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,SAAS,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACzD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,OAAO,KAAK,IAAI,IAAI,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,+DAA+D;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAwB;IACvD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC,UAAU;YACnB,CAAC,CAAC,4BAA4B,CAAC,GAAG,CAAC,UAAU,EAAE;gBAC3C,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,iBAAiB;aAC3B,CAAC;YACJ,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAwB;IAC3D,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,IAAgD;IAEhD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA+B,CAAC;IACtD,KAAK,MAAM,EAAE,IAAI,0BAA0B,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE;YACb,EAAE;YACF,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9C,IAAI,EAAE,IAAI,EAAE,EAAE;YACd,GAAG,EAAE,IAAI;YACT,MAAM,EAAE,OAAO;SAChB,CAAC,CAAC;IACL,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE;QAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAEtD,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["import { CHAT_FIRST_DEFAULT_APP_IDS } from \"@agent-native/core/client/chat-first\";\nimport { withBuilderUtmTrackingParams } from \"@agent-native/core/shared/builder-link-tracking\";\n\nexport interface WorkspaceAppSummary {\n id: string;\n name: string;\n description?: string;\n path: string;\n url?: string | null;\n isDispatch?: boolean;\n audience?: \"internal\" | \"public\";\n publicPaths?: string[];\n protectedPaths?: string[];\n status?: \"ready\" | \"pending\";\n statusLabel?: string;\n builderUrl?: string | null;\n branchName?: string | null;\n createdAt?: string | null;\n createdBy?: string | null;\n owner?: string | null;\n teams?: string[];\n agentCardUrl?: string | null;\n agentCardReachable?: boolean;\n a2aEndpointUrl?: string | null;\n agentName?: string | null;\n agentSkillsCount?: number | null;\n archived?: boolean;\n}\n\nexport function isDispatchWorkspaceAppId(appId: string): boolean {\n return appId.trim().toLowerCase() === \"dispatch\";\n}\n\nexport function isDefaultWorkspaceAppHiddenId(appId: string): boolean {\n const normalized = appId.trim().toLowerCase();\n return normalized === \"chat\" || isDispatchWorkspaceAppId(normalized);\n}\n\nexport function isWorkspaceAppVisibleInDefaultLaunchers(\n app: Pick<WorkspaceAppSummary, \"id\" | \"isDispatch\">,\n): boolean {\n return !app.isDispatch && !isDefaultWorkspaceAppHiddenId(app.id);\n}\n\nexport function workspaceAppRoute(appId: string): string {\n return `/apps/${encodeURIComponent(appId)}`;\n}\n\nexport function workspaceAppIdFromRoute(pathname: string): string | null {\n const match = pathname.match(/^\\/apps\\/([^/]+)(?:\\/|$)/);\n if (!match) return null;\n try {\n const appId = decodeURIComponent(match[1]).trim();\n return appId || null;\n } catch {\n // coercion-ok: malformed app routes are inactive, not app ids.\n return null;\n }\n}\n\nexport function workspaceAppHref(app: WorkspaceAppSummary): string | null {\n if (app.status === \"pending\") {\n return app.builderUrl\n ? withBuilderUtmTrackingParams(app.builderUrl, {\n campaign: \"product\",\n content: \"dispatch_branch\",\n })\n : null;\n }\n return app.path || app.url || null;\n}\n\nexport function isPendingBuilderHref(app: WorkspaceAppSummary): boolean {\n return app.status === \"pending\" && !!app.builderUrl;\n}\n\n/**\n * Keep the chat-first rail useful before a workspace manifest is populated.\n * Mounted workspace rows still win, so custom names and routes remain the\n * source of truth once an app exists in the workspace.\n */\nexport function mergeChatFirstWorkspaceApps(\n apps: readonly WorkspaceAppSummary[] | undefined,\n): WorkspaceAppSummary[] {\n const merged = new Map<string, WorkspaceAppSummary>();\n for (const id of CHAT_FIRST_DEFAULT_APP_IDS) {\n merged.set(id, {\n id,\n name: id.charAt(0).toUpperCase() + id.slice(1),\n path: `/${id}`,\n url: null,\n status: \"ready\",\n });\n }\n for (const app of apps ?? []) merged.set(app.id, app);\n\n return [...merged.values()];\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"AAqCA,wBAAgB,IAAI;;IAEnB;AAQD,MAAM,CAAC,OAAO,UAAU,cAAc,oDAGrC"}
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"AAwCA,wBAAgB,IAAI;;IAEnB;AAQD,MAAM,CAAC,OAAO,UAAU,cAAc,oDAGrC"}
@@ -14,6 +14,7 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "../../comp
14
14
  import { Skeleton } from "../../components/ui/skeleton.js";
15
15
  import { WorkspaceAppCard } from "../../components/workspace-app-card.js";
16
16
  import { cn } from "../../lib/utils.js";
17
+ import { isWorkspaceAppVisibleInDefaultLaunchers, } from "../../lib/workspace-apps.js";
17
18
  export function meta() {
18
19
  return [{ title: "Apps — Dispatch" }];
19
20
  }
@@ -35,7 +36,7 @@ function AppsRoute() {
35
36
  const { data: workspace } = useActionQuery("get-workspace-info", {}, { staleTime: 60_000 });
36
37
  const ws = workspace;
37
38
  const workspaceLabel = ws?.displayName ?? ws?.name ?? null;
38
- const allApps = apps.filter((app) => !app.isDispatch);
39
+ const allApps = apps.filter(isWorkspaceAppVisibleInDefaultLaunchers);
39
40
  const visibleApps = allApps.filter((app) => !app.archived);
40
41
  const activeApps = visibleApps.filter((app) => app.status !== "pending");
41
42
  const pendingApps = visibleApps.filter((app) => app.status === "pending");
@@ -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/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport {\n IconApps,\n IconChevronDown,\n IconClockHour4,\n IconEyeOff,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { Outlet, useParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n APP_LIST_GRID_ROW_CLASS,\n AppList,\n} from \"../../components/app-list-row\";\nimport { CreateAppPopover } from \"../../components/create-app-popover\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { OtherAppsSection } from \"../../components/other-apps-section\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../components/ui/collapsible\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { WorkspaceAppCard } from \"../../components/workspace-app-card\";\nimport type {\n CuratedWorkspaceTemplatesResult,\n WorkspaceTemplateLabels,\n} from \"../../components/workspace-template-card\";\nimport type { ConnectedAppSummary } from \"../../lib/other-apps\";\nimport { cn } from \"../../lib/utils\";\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 AppsRouteEntry() {\n const { appId } = useParams();\n return appId ? <Outlet /> : <AppsRoute />;\n}\n\nfunction AppsRoute() {\n const t = useT();\n const [showPending, setShowPending] = useState(false);\n const [showHidden, setShowHidden] = useState(false);\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n includeArchived: true,\n });\n const connectedAppsQuery = useActionQuery(\"list-connected-agents\", {});\n const curatedTemplatesQuery = useActionQuery(\n \"list-curated-workspace-templates\",\n {},\n );\n const { data: apps = [], isLoading: appsLoading } = appsQuery;\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 allApps = (apps as WorkspaceAppSummary[]).filter(\n (app) => !app.isDispatch,\n );\n const visibleApps = allApps.filter((app) => !app.archived);\n const activeApps = visibleApps.filter((app) => app.status !== \"pending\");\n const pendingApps = visibleApps.filter((app) => app.status === \"pending\");\n const archivedApps = allApps.filter((app) => app.archived);\n const showAppSkeletons = appsLoading && allApps.length === 0;\n const templateLabels: WorkspaceTemplateLabels = {\n appId: t(\"dispatch.pages.remixAppIdLabel\"),\n appIdDescription: t(\"dispatch.pages.remixAppIdDescription\"),\n cancel: t(\"dispatch.pages.cancel\"),\n integrationSetup: t(\"dispatch.pages.integrationSetup\"),\n installed: t(\"dispatch.pages.alreadyInWorkspace\"),\n remix: t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" }),\n remixing: t(\"dispatch.pages.remixing\"),\n remixSuccess: t(\"dispatch.pages.remixSuccess\"),\n remixError: t(\"dispatch.pages.remixError\"),\n appIdRequired: t(\"dispatch.pages.appIdRequired\"),\n source: t(\"dispatch.pages.source\"),\n openApp: t(\"dispatch.pages.openApp\", { defaultValue: \"Open app\" }),\n viewLiveApp: t(\"dispatch.pages.openApp\", { defaultValue: \"Open\" }),\n };\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.apps\")}\n description={\n workspaceLabel\n ? t(\"dispatch.pages.appsDescriptionWithWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.appsDescription\")\n }\n >\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-end justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2\">\n <IconApps\n size={16}\n className=\"mt-0.5 shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.yourApps\", { defaultValue: \"Your apps\" })}\n </h2>\n <p className=\"mt-0.5 text-xs text-muted-foreground\">\n {t(\"dispatch.pages.activeCount\", {\n count: activeApps.length,\n })}\n {pendingApps.length > 0\n ? ` · ${t(\"dispatch.pages.pendingCount\", {\n count: pendingApps.length,\n })}`\n : \"\"}\n {archivedApps.length > 0\n ? ` · ${t(\"dispatch.pages.hiddenCount\", {\n count: archivedApps.length,\n })}`\n : \"\"}\n </p>\n </div>\n </div>\n {activeApps.length > 0 || pendingApps.length > 0 ? (\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" })}\n </Button>\n }\n />\n ) : null}\n </div>\n\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : showAppSkeletons ? (\n <AppsSkeletonGrid />\n ) : activeApps.length > 0 ? (\n <AppList className={APP_LIST_GRID_CLASS}>\n {activeApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n ) : pendingApps.length > 0 ? (\n <EmptyActiveAppsState />\n ) : (\n <EmptyAppsState />\n )}\n </section>\n\n {pendingApps.length > 0 ? (\n <Collapsible open={showPending} onOpenChange={setShowPending}>\n <section className=\"space-y-3 border-t pt-6\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconClockHour4\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.pendingApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.pendingCount\", {\n count: pendingApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showPending\n ? t(\"dispatch.pages.hidePendingApps\")\n : t(\"dispatch.pages.showPendingApps\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n showPending && \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {pendingApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n\n <OtherAppsSection\n templates={\n curatedTemplatesQuery.data as\n | CuratedWorkspaceTemplatesResult\n | undefined\n }\n connectedApps={\n connectedAppsQuery.data as ConnectedAppSummary[] | undefined\n }\n workspaceApps={allApps}\n templatesLoading={curatedTemplatesQuery.isLoading}\n connectedAppsLoading={connectedAppsQuery.isLoading}\n templatesError={curatedTemplatesQuery.error}\n connectedAppsError={connectedAppsQuery.error}\n onRetryTemplates={() => void curatedTemplatesQuery.refetch()}\n onRetryConnectedApps={() => void connectedAppsQuery.refetch()}\n templateLabels={templateLabels}\n onRemixSuccess={() => {\n void appsQuery.refetch();\n void curatedTemplatesQuery.refetch();\n }}\n />\n\n {archivedApps.length > 0 ? (\n <Collapsible open={showHidden} onOpenChange={setShowHidden}>\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconEyeOff\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.hiddenApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.hiddenAppCount\", {\n count: archivedApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showHidden\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n showHidden && \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {archivedApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n </div>\n </DispatchShell>\n );\n}\n\nfunction AppsSkeletonGrid() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-md\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-8 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nfunction EmptyAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <div className=\"mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <IconApps size={18} />\n </div>\n <h3 className=\"mt-3 text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.noWorkspaceApps\")}\n </h3>\n <p className=\"mx-auto mt-1 max-w-sm text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noWorkspaceAppsDescription\")}\n </p>\n <div className=\"mt-4\">\n <CreateAppPopover\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" })}\n </Button>\n }\n />\n </div>\n </div>\n );\n}\n\nfunction EmptyActiveAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <p className=\"text-sm font-medium text-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceApps\")}\n </p>\n <p className=\"mx-auto mt-1 max-w-md text-xs text-muted-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceAppsDescription\")}\n </p>\n </div>\n );\n}\n"]}
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/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport {\n IconApps,\n IconChevronDown,\n IconClockHour4,\n IconEyeOff,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { Outlet, useParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n APP_LIST_GRID_ROW_CLASS,\n AppList,\n} from \"../../components/app-list-row\";\nimport { CreateAppPopover } from \"../../components/create-app-popover\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { OtherAppsSection } from \"../../components/other-apps-section\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../components/ui/collapsible\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { WorkspaceAppCard } from \"../../components/workspace-app-card\";\nimport type {\n CuratedWorkspaceTemplatesResult,\n WorkspaceTemplateLabels,\n} from \"../../components/workspace-template-card\";\nimport type { ConnectedAppSummary } from \"../../lib/other-apps\";\nimport { cn } from \"../../lib/utils\";\nimport {\n isWorkspaceAppVisibleInDefaultLaunchers,\n type WorkspaceAppSummary,\n} 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 AppsRouteEntry() {\n const { appId } = useParams();\n return appId ? <Outlet /> : <AppsRoute />;\n}\n\nfunction AppsRoute() {\n const t = useT();\n const [showPending, setShowPending] = useState(false);\n const [showHidden, setShowHidden] = useState(false);\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n includeArchived: true,\n });\n const connectedAppsQuery = useActionQuery(\"list-connected-agents\", {});\n const curatedTemplatesQuery = useActionQuery(\n \"list-curated-workspace-templates\",\n {},\n );\n const { data: apps = [], isLoading: appsLoading } = appsQuery;\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 allApps = (apps as WorkspaceAppSummary[]).filter(\n isWorkspaceAppVisibleInDefaultLaunchers,\n );\n const visibleApps = allApps.filter((app) => !app.archived);\n const activeApps = visibleApps.filter((app) => app.status !== \"pending\");\n const pendingApps = visibleApps.filter((app) => app.status === \"pending\");\n const archivedApps = allApps.filter((app) => app.archived);\n const showAppSkeletons = appsLoading && allApps.length === 0;\n const templateLabels: WorkspaceTemplateLabels = {\n appId: t(\"dispatch.pages.remixAppIdLabel\"),\n appIdDescription: t(\"dispatch.pages.remixAppIdDescription\"),\n cancel: t(\"dispatch.pages.cancel\"),\n integrationSetup: t(\"dispatch.pages.integrationSetup\"),\n installed: t(\"dispatch.pages.alreadyInWorkspace\"),\n remix: t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" }),\n remixing: t(\"dispatch.pages.remixing\"),\n remixSuccess: t(\"dispatch.pages.remixSuccess\"),\n remixError: t(\"dispatch.pages.remixError\"),\n appIdRequired: t(\"dispatch.pages.appIdRequired\"),\n source: t(\"dispatch.pages.source\"),\n openApp: t(\"dispatch.pages.openApp\", { defaultValue: \"Open app\" }),\n viewLiveApp: t(\"dispatch.pages.openApp\", { defaultValue: \"Open\" }),\n };\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.apps\")}\n description={\n workspaceLabel\n ? t(\"dispatch.pages.appsDescriptionWithWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.appsDescription\")\n }\n >\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-end justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2\">\n <IconApps\n size={16}\n className=\"mt-0.5 shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.yourApps\", { defaultValue: \"Your apps\" })}\n </h2>\n <p className=\"mt-0.5 text-xs text-muted-foreground\">\n {t(\"dispatch.pages.activeCount\", {\n count: activeApps.length,\n })}\n {pendingApps.length > 0\n ? ` · ${t(\"dispatch.pages.pendingCount\", {\n count: pendingApps.length,\n })}`\n : \"\"}\n {archivedApps.length > 0\n ? ` · ${t(\"dispatch.pages.hiddenCount\", {\n count: archivedApps.length,\n })}`\n : \"\"}\n </p>\n </div>\n </div>\n {activeApps.length > 0 || pendingApps.length > 0 ? (\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" })}\n </Button>\n }\n />\n ) : null}\n </div>\n\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : showAppSkeletons ? (\n <AppsSkeletonGrid />\n ) : activeApps.length > 0 ? (\n <AppList className={APP_LIST_GRID_CLASS}>\n {activeApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n ) : pendingApps.length > 0 ? (\n <EmptyActiveAppsState />\n ) : (\n <EmptyAppsState />\n )}\n </section>\n\n {pendingApps.length > 0 ? (\n <Collapsible open={showPending} onOpenChange={setShowPending}>\n <section className=\"space-y-3 border-t pt-6\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconClockHour4\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.pendingApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.pendingCount\", {\n count: pendingApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showPending\n ? t(\"dispatch.pages.hidePendingApps\")\n : t(\"dispatch.pages.showPendingApps\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n showPending && \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {pendingApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n\n <OtherAppsSection\n templates={\n curatedTemplatesQuery.data as\n | CuratedWorkspaceTemplatesResult\n | undefined\n }\n connectedApps={\n connectedAppsQuery.data as ConnectedAppSummary[] | undefined\n }\n workspaceApps={allApps}\n templatesLoading={curatedTemplatesQuery.isLoading}\n connectedAppsLoading={connectedAppsQuery.isLoading}\n templatesError={curatedTemplatesQuery.error}\n connectedAppsError={connectedAppsQuery.error}\n onRetryTemplates={() => void curatedTemplatesQuery.refetch()}\n onRetryConnectedApps={() => void connectedAppsQuery.refetch()}\n templateLabels={templateLabels}\n onRemixSuccess={() => {\n void appsQuery.refetch();\n void curatedTemplatesQuery.refetch();\n }}\n />\n\n {archivedApps.length > 0 ? (\n <Collapsible open={showHidden} onOpenChange={setShowHidden}>\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconEyeOff\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.hiddenApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.hiddenAppCount\", {\n count: archivedApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showHidden\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n showHidden && \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {archivedApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n </div>\n </DispatchShell>\n );\n}\n\nfunction AppsSkeletonGrid() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-md\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-8 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nfunction EmptyAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <div className=\"mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <IconApps size={18} />\n </div>\n <h3 className=\"mt-3 text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.noWorkspaceApps\")}\n </h3>\n <p className=\"mx-auto mt-1 max-w-sm text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noWorkspaceAppsDescription\")}\n </p>\n <div className=\"mt-4\">\n <CreateAppPopover\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" })}\n </Button>\n }\n />\n </div>\n </div>\n );\n}\n\nfunction EmptyActiveAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <p className=\"text-sm font-medium text-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceApps\")}\n </p>\n <p className=\"mx-auto mt-1 max-w-md text-xs text-muted-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceAppsDescription\")}\n </p>\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/server/plugins/auth.ts"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH,QAAA,MAAM,kBAAkB,aAAoB,GAAG,kBAW9C,CAAC;eAEa,kBAAkB"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/server/plugins/auth.ts"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH,QAAA,MAAM,kBAAkB,aAAoB,GAAG,kBAY9C,CAAC;eAEa,kBAAkB"}
@@ -23,6 +23,7 @@ const dispatchAuthPlugin = async (nitroApp) => {
23
23
  const plugin = createAuthPlugin({
24
24
  googleOnly,
25
25
  marketing: marketing,
26
+ publicPaths: authConfig.publicPaths,
26
27
  });
27
28
  return plugin(nitroApp);
28
29
  };
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/server/plugins/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,iBAAiB,GAAG;IACxB,OAAO,EAAE,UAAU;IACnB,OAAO,EACL,sGAAsG;IACxG,QAAQ,EAAE;QACR,4DAA4D;QAC5D,6DAA6D;QAC7D,oDAAoD;KACrD;CACO,CAAC;AAEX;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,KAAK,EAAE,QAAa,EAAE,EAAE;IACjD,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,iBAAiB,EAAE,CAAC;IACtD,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC;IAClD,MAAM,SAAS,GACZ,UAAU,CAAC,SAAiD;QAC7D,iBAAiB,CAAC;IACpB,MAAM,MAAM,GAAG,gBAAgB,CAAC;QAC9B,UAAU;QACV,SAAS,EAAE,SAAgB;KAC5B,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,eAAe,kBAAkB,CAAC","sourcesContent":["import { createAuthPlugin } from \"@agent-native/core/server\";\n\nimport { getDispatchConfig } from \"../index.js\";\n\nconst DEFAULT_MARKETING = {\n appName: \"Dispatch\",\n tagline:\n \"Your AI agent manages secrets, orchestrates other agents, and routes messages across your workspace.\",\n features: [\n \"Centralized vault for secrets with granular per-app grants\",\n \"Cross-agent orchestration and delegation to specialist apps\",\n \"Slack and Telegram routing with approval workflows\",\n ],\n} as const;\n\n/**\n * Defer config + plugin construction until the Nitro plugin actually fires.\n * This way `setupDispatch(config)` can run after plugin module-load order\n * (Nitro doesn't guarantee load order across plugin files) and still feed\n * `googleOnly` / `marketing` into `createAuthPlugin`.\n */\nconst dispatchAuthPlugin = async (nitroApp: any) => {\n const { auth: authConfig = {} } = getDispatchConfig();\n const googleOnly = authConfig.googleOnly ?? false;\n const marketing =\n (authConfig.marketing as Record<string, unknown> | undefined) ??\n DEFAULT_MARKETING;\n const plugin = createAuthPlugin({\n googleOnly,\n marketing: marketing as any,\n });\n return plugin(nitroApp);\n};\n\nexport default dispatchAuthPlugin;\n"]}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/server/plugins/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,iBAAiB,GAAG;IACxB,OAAO,EAAE,UAAU;IACnB,OAAO,EACL,sGAAsG;IACxG,QAAQ,EAAE;QACR,4DAA4D;QAC5D,6DAA6D;QAC7D,oDAAoD;KACrD;CACO,CAAC;AAEX;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,KAAK,EAAE,QAAa,EAAE,EAAE;IACjD,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,iBAAiB,EAAE,CAAC;IACtD,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC;IAClD,MAAM,SAAS,GACZ,UAAU,CAAC,SAAiD;QAC7D,iBAAiB,CAAC;IACpB,MAAM,MAAM,GAAG,gBAAgB,CAAC;QAC9B,UAAU;QACV,SAAS,EAAE,SAAgB;QAC3B,WAAW,EAAE,UAAU,CAAC,WAAW;KACpC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,eAAe,kBAAkB,CAAC","sourcesContent":["import { createAuthPlugin } from \"@agent-native/core/server\";\n\nimport { getDispatchConfig } from \"../index.js\";\n\nconst DEFAULT_MARKETING = {\n appName: \"Dispatch\",\n tagline:\n \"Your AI agent manages secrets, orchestrates other agents, and routes messages across your workspace.\",\n features: [\n \"Centralized vault for secrets with granular per-app grants\",\n \"Cross-agent orchestration and delegation to specialist apps\",\n \"Slack and Telegram routing with approval workflows\",\n ],\n} as const;\n\n/**\n * Defer config + plugin construction until the Nitro plugin actually fires.\n * This way `setupDispatch(config)` can run after plugin module-load order\n * (Nitro doesn't guarantee load order across plugin files) and still feed\n * `googleOnly` / `marketing` into `createAuthPlugin`.\n */\nconst dispatchAuthPlugin = async (nitroApp: any) => {\n const { auth: authConfig = {} } = getDispatchConfig();\n const googleOnly = authConfig.googleOnly ?? false;\n const marketing =\n (authConfig.marketing as Record<string, unknown> | undefined) ??\n DEFAULT_MARKETING;\n const plugin = createAuthPlugin({\n googleOnly,\n marketing: marketing as any,\n publicPaths: authConfig.publicPaths,\n });\n return plugin(nitroApp);\n};\n\nexport default dispatchAuthPlugin;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/dispatch",
3
- "version": "0.23.3",
3
+ "version": "0.23.5",
4
4
  "description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -84,7 +84,7 @@
84
84
  "tailwind-merge": "^3.5.0",
85
85
  "vaul": "^1.1.2",
86
86
  "zod": "^4.3.6",
87
- "@agent-native/toolkit": "0.13.9"
87
+ "@agent-native/toolkit": "0.13.10"
88
88
  },
89
89
  "devDependencies": {
90
90
  "@react-router/dev": "^8.1.0",
@@ -98,7 +98,7 @@
98
98
  "typescript-7": "npm:typescript@^7.0.2",
99
99
  "vite": "8.1.0",
100
100
  "vitest": "^4.1.5",
101
- "@agent-native/core": "0.149.5"
101
+ "@agent-native/core": "0.151.0"
102
102
  },
103
103
  "peerDependencies": {
104
104
  "@agent-native/core": ">=0.8.0",
@@ -4,7 +4,8 @@ import { cn } from "../lib/utils";
4
4
 
5
5
  export const APP_LIST_GRID_CLASS =
6
6
  "mx-auto w-full max-w-[1000px] xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none xl:bg-transparent";
7
- export const APP_LIST_GRID_ROW_CLASS = "xl:rounded-2xl xl:border-0 xl:bg-card";
7
+ export const APP_LIST_GRID_ROW_CLASS =
8
+ "xl:rounded-2xl xl:border xl:border-transparent xl:bg-card xl:transition-[background-color,border-color] xl:hover:border-border xl:focus-within:border-ring/50";
8
9
 
9
10
  export function AppList({
10
11
  children,
@@ -30,7 +31,7 @@ export function AppListRow({
30
31
  return (
31
32
  <div
32
33
  className={cn(
33
- "group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color] hover:bg-muted/30 focus-within:bg-muted/30",
34
+ "group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color,border-color] hover:bg-muted/30 focus-within:bg-muted/30",
34
35
  className,
35
36
  )}
36
37
  >
@@ -152,9 +152,12 @@ describe("CreateAppFlow", () => {
152
152
  vi.unstubAllGlobals();
153
153
  });
154
154
 
155
- async function renderAndSubmit(prompt: string) {
155
+ async function renderAndSubmit(
156
+ prompt: string,
157
+ props: { onClose?: () => void } = {},
158
+ ) {
156
159
  await act(async () => {
157
- root.render(React.createElement(CreateAppFlow, {}));
160
+ root.render(React.createElement(CreateAppFlow, props));
158
161
  });
159
162
 
160
163
  changeValue(
@@ -213,6 +216,27 @@ describe("CreateAppFlow", () => {
213
216
  ).toBe(false);
214
217
  });
215
218
 
219
+ it("opens a fresh local chat when the server hands off app creation", async () => {
220
+ startWorkspaceAppCreationResponse.result = {
221
+ mode: "local-agent",
222
+ appId: "quality-dashboard",
223
+ prompt: "Create the quality dashboard in the new workspace app.",
224
+ message: "Starting the local coding chat.",
225
+ };
226
+ const onClose = vi.fn();
227
+
228
+ await renderAndSubmit("Build a quality dashboard", { onClose });
229
+
230
+ expect(sendToAgentChatMock).toHaveBeenCalledWith({
231
+ message: "Create the quality dashboard in the new workspace app.",
232
+ submit: true,
233
+ type: "code",
234
+ newTab: true,
235
+ reuseEmptyTab: true,
236
+ });
237
+ expect(onClose).toHaveBeenCalledTimes(1);
238
+ });
239
+
216
240
  it("renders the error affordance and a Try again control for builder-error, without a Connect Builder control", async () => {
217
241
  startWorkspaceAppCreationResponse.result = {
218
242
  mode: "builder-unavailable",
@@ -269,6 +269,16 @@ export function CreateAppFlow({
269
269
  if (result?.mode === "builder") {
270
270
  setBranchUrl(result?.url || null);
271
271
  setStatusMessage("Builder branch created.");
272
+ } else if (result?.mode === "local-agent") {
273
+ sendToAgentChat({
274
+ message: result.prompt ?? message,
275
+ submit: true,
276
+ type: "code",
277
+ newTab: true,
278
+ reuseEmptyTab: true,
279
+ });
280
+ setStatusMessage("Sent to the local agent.");
281
+ onClose?.();
272
282
  } else {
273
283
  setStatusMessage(
274
284
  result?.message ||
@@ -142,6 +142,7 @@ describe("DispatchControlPlane", () => {
142
142
  selectedEffort: "medium",
143
143
  selectedEngine: "",
144
144
  selectedModel: "auto",
145
+ rootClassName: "bg-card",
145
146
  });
146
147
 
147
148
  await act(async () => {
@@ -12,7 +12,10 @@ import { Link, useNavigate } from "react-router";
12
12
 
13
13
  import type { ConnectedAppSummary } from "../lib/other-apps";
14
14
  import { cn } from "../lib/utils";
15
- import type { WorkspaceAppSummary } from "../lib/workspace-apps";
15
+ import {
16
+ isWorkspaceAppVisibleInDefaultLaunchers,
17
+ type WorkspaceAppSummary,
18
+ } from "../lib/workspace-apps";
16
19
  import { ActionQueryError } from "./action-query-error";
17
20
  import {
18
21
  APP_LIST_GRID_CLASS,
@@ -115,6 +118,7 @@ function CommandPanel() {
115
118
  selectedEffort={selectedEffort}
116
119
  selectedEngine={selectedEngine}
117
120
  selectedModel={selectedModel}
121
+ rootClassName="bg-card"
118
122
  onEffortChange={onEffortChange}
119
123
  onModelChange={onModelChange}
120
124
  onSubmit={(text) => send(text)}
@@ -161,7 +165,9 @@ function AppsPanel({
161
165
  }) {
162
166
  const t = useT();
163
167
  const [showPending, setShowPending] = useState(false);
164
- const visibleApps = apps.filter((app) => !app.isDispatch && !app.archived);
168
+ const visibleApps = apps.filter(
169
+ (app) => isWorkspaceAppVisibleInDefaultLaunchers(app) && !app.archived,
170
+ );
165
171
  const activeApps = visibleApps.filter((app) => app.status !== "pending");
166
172
  const pendingApps = visibleApps.filter((app) => app.status === "pending");
167
173
  const otherAppEntries = mergeOtherAppEntries({