@agent-native/dispatch 0.23.2 → 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 (86) 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/app-open-actions.d.ts.map +1 -1
  7. package/dist/components/app-open-actions.js +3 -2
  8. package/dist/components/app-open-actions.js.map +1 -1
  9. package/dist/components/create-app-popover.d.ts.map +1 -1
  10. package/dist/components/create-app-popover.js +11 -0
  11. package/dist/components/create-app-popover.js.map +1 -1
  12. package/dist/components/dispatch-control-plane.d.ts.map +1 -1
  13. package/dist/components/dispatch-control-plane.js +3 -2
  14. package/dist/components/dispatch-control-plane.js.map +1 -1
  15. package/dist/components/layout/Layout.d.ts +5 -2
  16. package/dist/components/layout/Layout.d.ts.map +1 -1
  17. package/dist/components/layout/Layout.js +122 -13
  18. package/dist/components/layout/Layout.js.map +1 -1
  19. package/dist/components/layout/workspace-apps-rail.d.ts.map +1 -1
  20. package/dist/components/layout/workspace-apps-rail.js +3 -23
  21. package/dist/components/layout/workspace-apps-rail.js.map +1 -1
  22. package/dist/components/other-apps-section.d.ts.map +1 -1
  23. package/dist/components/other-apps-section.js +5 -1
  24. package/dist/components/other-apps-section.js.map +1 -1
  25. package/dist/components/workspace-app-card.d.ts.map +1 -1
  26. package/dist/components/workspace-app-card.js +3 -4
  27. package/dist/components/workspace-app-card.js.map +1 -1
  28. package/dist/components/workspace-template-card.d.ts.map +1 -1
  29. package/dist/components/workspace-template-card.js +1 -1
  30. package/dist/components/workspace-template-card.js.map +1 -1
  31. package/dist/config.d.ts +2 -0
  32. package/dist/config.d.ts.map +1 -1
  33. package/dist/config.js.map +1 -1
  34. package/dist/lib/other-apps.d.ts.map +1 -1
  35. package/dist/lib/other-apps.js +2 -0
  36. package/dist/lib/other-apps.js.map +1 -1
  37. package/dist/lib/workspace-apps.d.ts +4 -0
  38. package/dist/lib/workspace-apps.d.ts.map +1 -1
  39. package/dist/lib/workspace-apps.js +23 -0
  40. package/dist/lib/workspace-apps.js.map +1 -1
  41. package/dist/routes/index.js +1 -1
  42. package/dist/routes/index.js.map +1 -1
  43. package/dist/routes/pages/agent-integrations.d.ts +5 -0
  44. package/dist/routes/pages/agent-integrations.d.ts.map +1 -0
  45. package/dist/routes/pages/agent-integrations.js +15 -0
  46. package/dist/routes/pages/agent-integrations.js.map +1 -0
  47. package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
  48. package/dist/routes/pages/apps.$appId.js +14 -2
  49. package/dist/routes/pages/apps.$appId.js.map +1 -1
  50. package/dist/routes/pages/apps.d.ts.map +1 -1
  51. package/dist/routes/pages/apps.js +2 -1
  52. package/dist/routes/pages/apps.js.map +1 -1
  53. package/dist/routes/pages/overview.d.ts +2 -2
  54. package/dist/routes/pages/settings.d.ts.map +1 -1
  55. package/dist/routes/pages/settings.js +1 -1
  56. package/dist/routes/pages/settings.js.map +1 -1
  57. package/dist/server/plugins/auth.d.ts.map +1 -1
  58. package/dist/server/plugins/auth.js +1 -0
  59. package/dist/server/plugins/auth.js.map +1 -1
  60. package/package.json +3 -3
  61. package/src/components/app-list-row.tsx +3 -2
  62. package/src/components/app-open-actions.tsx +3 -2
  63. package/src/components/create-app-popover.spec.tsx +26 -2
  64. package/src/components/create-app-popover.tsx +10 -0
  65. package/src/components/dispatch-control-plane.spec.tsx +1 -0
  66. package/src/components/dispatch-control-plane.tsx +8 -2
  67. package/src/components/layout/Layout.spec.tsx +9 -0
  68. package/src/components/layout/Layout.tsx +181 -19
  69. package/src/components/layout/workspace-apps-rail.tsx +4 -26
  70. package/src/components/other-apps-section.tsx +8 -1
  71. package/src/components/workspace-app-card.spec.tsx +6 -6
  72. package/src/components/workspace-app-card.tsx +4 -7
  73. package/src/components/workspace-template-card.spec.tsx +4 -16
  74. package/src/components/workspace-template-card.tsx +0 -1
  75. package/src/config.ts +2 -0
  76. package/src/lib/other-apps.spec.ts +26 -0
  77. package/src/lib/other-apps.ts +3 -0
  78. package/src/lib/workspace-apps.spec.ts +44 -0
  79. package/src/lib/workspace-apps.ts +27 -0
  80. package/src/routes/index.ts +1 -1
  81. package/src/routes/pages/agent-integrations.tsx +24 -0
  82. package/src/routes/pages/apps.$appId.tsx +19 -1
  83. package/src/routes/pages/apps.tsx +5 -2
  84. package/src/routes/pages/settings.tsx +1 -19
  85. package/src/server/plugins/auth.spec.ts +45 -0
  86. package/src/server/plugins/auth.ts +1 -0
@@ -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,7 +23,11 @@ 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;
30
+ export declare function workspaceAppIdFromRoute(pathname: string): string | null;
27
31
  export declare function workspaceAppHref(app: WorkspaceAppSummary): string | null;
28
32
  export declare function isPendingBuilderHref(app: WorkspaceAppSummary): boolean;
29
33
  /**
@@ -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,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,8 +1,31 @@
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
  }
16
+ export function workspaceAppIdFromRoute(pathname) {
17
+ const match = pathname.match(/^\/apps\/([^/]+)(?:\/|$)/);
18
+ if (!match)
19
+ return null;
20
+ try {
21
+ const appId = decodeURIComponent(match[1]).trim();
22
+ return appId || null;
23
+ }
24
+ catch {
25
+ // coercion-ok: malformed app routes are inactive, not app ids.
26
+ return null;
27
+ }
28
+ }
6
29
  export function workspaceAppHref(app) {
7
30
  if (app.status === "pending") {
8
31
  return app.builderUrl
@@ -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,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 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"]}
@@ -43,7 +43,7 @@ export const dispatchRoutes = [
43
43
  route("automations", "./pages/automations.js"),
44
44
  route("approvals", "./pages/approvals.js"),
45
45
  route("destinations", "./pages/destinations.js"),
46
- route("integrations", "./pages/integrations.js"),
46
+ route("integrations", "./pages/agent-integrations.js"),
47
47
  route("transactional-email", "./pages/transactional-email.js"),
48
48
  route("transactional-email/:appId/:id", "./pages/transactional-email.$appId.$id.js"),
49
49
  route("vault", "./pages/vault.js"),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteConfig, route, index } from \"@react-router/dev/routes\";\n\n/**\n * Dispatch's routes as a programmatic `RouteConfig[]`. Splat into the\n * consumer's `app/routes.ts`:\n *\n * ```ts\n * import { type RouteConfig } from \"@react-router/dev/routes\";\n * import { dispatchRoutes } from \"@agent-native/dispatch/routes\";\n *\n * export default [\n * ...localRoutes, // consumer's own routes win on collision\n * ...dispatchRoutes, // dispatch fills in everything else\n * ] satisfies RouteConfig;\n * ```\n *\n * Route precedence: React Router 7 matches in declaration order, so\n * placing `dispatchRoutes` LAST means consumer-defined routes with the\n * same path take precedence. To override a single dispatch route, define\n * it in your local routes; to keep it, omit it.\n *\n * The `file` paths below resolve relative to this file at runtime — they\n * point into `packages/dispatch/dist/routes/pages/*.js` after build.\n *\n * Naming maps the original flatRoutes file conventions:\n * `_index.tsx` → `index(...)`\n * `<name>.tsx` → `route(\"<name>\", ...)`\n * `<a>.$<param>.tsx` → `route(\"<a>/:<param>\", ...)`\n * `<a>._index.tsx` → flattened as `route(\"<a>\", ...)` (workspace\n * versions are bare and don't wrap a parent layout)\n */\nexport const dispatchRoutes: RouteConfig = [\n index(\"./pages/_index.js\"),\n route(\"browser-connect\", \"./pages/browser-connect.js\"),\n route(\"browser-chat\", \"./pages/browser-chat.js\"),\n route(\"chat\", \"./pages/chat.js\"),\n route(\"chat/:threadId\", \"./pages/chat.js\"),\n route(\"overview\", \"./pages/overview.js\"),\n route(\"admin\", \"./pages/admin.js\", [\n index(\"./pages/admin._index.js\"),\n route(\"new-app\", \"./pages/new-app.js\"),\n route(\"operations\", \"./pages/operations.js\"),\n route(\"metrics\", \"./pages/metrics.js\"),\n route(\"automations\", \"./pages/automations.js\"),\n route(\"approvals\", \"./pages/approvals.js\"),\n route(\"destinations\", \"./pages/destinations.js\"),\n route(\"integrations\", \"./pages/integrations.js\"),\n route(\"transactional-email\", \"./pages/transactional-email.js\"),\n route(\n \"transactional-email/:appId/:id\",\n \"./pages/transactional-email.$appId.$id.js\",\n ),\n route(\"vault\", \"./pages/vault.js\"),\n route(\"agents\", \"./pages/agents.js\"),\n route(\"workspace\", \"./pages/workspace.js\"),\n route(\"messaging\", \"./pages/messaging.js\"),\n route(\"identities\", \"./pages/identities.js\"),\n route(\"audit\", \"./pages/audit.js\"),\n route(\"dreams\", \"./pages/dreams.js\"),\n route(\"thread-debug\", \"./pages/thread-debug.js\"),\n ]),\n route(\"metrics\", \"./pages/metrics.js\"),\n route(\"operations\", \"./pages/operations.js\"),\n route(\"apps\", \"./pages/apps.js\"),\n route(\"apps/:appId\", \"./pages/apps.$appId.js\"),\n route(\"new-app\", \"./pages/new-app.js\"),\n route(\"vault\", \"./pages/vault.js\"),\n route(\"integrations\", \"./pages/integrations.js\"),\n route(\"agents\", \"./pages/agents.js\"),\n route(\"workspace\", \"./pages/workspace.js\"),\n route(\"messaging\", \"./pages/messaging.js\"),\n route(\"destinations\", \"./pages/destinations.js\"),\n route(\"transactional-email\", \"./pages/transactional-email.js\"),\n route(\n \"transactional-email/:appId/:id\",\n \"./pages/transactional-email.$appId.$id.js\",\n ),\n route(\"identities\", \"./pages/identities.js\"),\n route(\"approval\", \"./pages/approval.js\"),\n route(\"approvals\", \"./pages/approvals.js\"),\n route(\"automations\", \"./pages/automations.js\"),\n route(\"audit\", \"./pages/audit.js\"),\n route(\"settings\", \"./pages/settings.js\"),\n route(\"dreams\", \"./pages/dreams.js\"),\n route(\"thread-debug\", \"./pages/thread-debug.js\"),\n route(\"team\", \"./pages/team.js\"),\n route(\"extensions\", \"./pages/extensions._index.js\"),\n route(\"extensions/:id\", \"./pages/extensions.$id.js\"),\n route(\"extensions/:id/:slug\", \"./pages/extensions.$id.js\"),\n // Catch-all for /:appId — bounces /dispatch/<appId> to /<appId> when the\n // segment names a workspace app sibling (e.g. Builder.io routing a \"go to\n // /todo\" call through Dispatch's mount). Declared last so React Router 7's\n // specificity ranking still matches explicit static routes above first.\n route(\":appId\", \"./pages/$appId.js\"),\n];\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteConfig, route, index } from \"@react-router/dev/routes\";\n\n/**\n * Dispatch's routes as a programmatic `RouteConfig[]`. Splat into the\n * consumer's `app/routes.ts`:\n *\n * ```ts\n * import { type RouteConfig } from \"@react-router/dev/routes\";\n * import { dispatchRoutes } from \"@agent-native/dispatch/routes\";\n *\n * export default [\n * ...localRoutes, // consumer's own routes win on collision\n * ...dispatchRoutes, // dispatch fills in everything else\n * ] satisfies RouteConfig;\n * ```\n *\n * Route precedence: React Router 7 matches in declaration order, so\n * placing `dispatchRoutes` LAST means consumer-defined routes with the\n * same path take precedence. To override a single dispatch route, define\n * it in your local routes; to keep it, omit it.\n *\n * The `file` paths below resolve relative to this file at runtime — they\n * point into `packages/dispatch/dist/routes/pages/*.js` after build.\n *\n * Naming maps the original flatRoutes file conventions:\n * `_index.tsx` → `index(...)`\n * `<name>.tsx` → `route(\"<name>\", ...)`\n * `<a>.$<param>.tsx` → `route(\"<a>/:<param>\", ...)`\n * `<a>._index.tsx` → flattened as `route(\"<a>\", ...)` (workspace\n * versions are bare and don't wrap a parent layout)\n */\nexport const dispatchRoutes: RouteConfig = [\n index(\"./pages/_index.js\"),\n route(\"browser-connect\", \"./pages/browser-connect.js\"),\n route(\"browser-chat\", \"./pages/browser-chat.js\"),\n route(\"chat\", \"./pages/chat.js\"),\n route(\"chat/:threadId\", \"./pages/chat.js\"),\n route(\"overview\", \"./pages/overview.js\"),\n route(\"admin\", \"./pages/admin.js\", [\n index(\"./pages/admin._index.js\"),\n route(\"new-app\", \"./pages/new-app.js\"),\n route(\"operations\", \"./pages/operations.js\"),\n route(\"metrics\", \"./pages/metrics.js\"),\n route(\"automations\", \"./pages/automations.js\"),\n route(\"approvals\", \"./pages/approvals.js\"),\n route(\"destinations\", \"./pages/destinations.js\"),\n route(\"integrations\", \"./pages/agent-integrations.js\"),\n route(\"transactional-email\", \"./pages/transactional-email.js\"),\n route(\n \"transactional-email/:appId/:id\",\n \"./pages/transactional-email.$appId.$id.js\",\n ),\n route(\"vault\", \"./pages/vault.js\"),\n route(\"agents\", \"./pages/agents.js\"),\n route(\"workspace\", \"./pages/workspace.js\"),\n route(\"messaging\", \"./pages/messaging.js\"),\n route(\"identities\", \"./pages/identities.js\"),\n route(\"audit\", \"./pages/audit.js\"),\n route(\"dreams\", \"./pages/dreams.js\"),\n route(\"thread-debug\", \"./pages/thread-debug.js\"),\n ]),\n route(\"metrics\", \"./pages/metrics.js\"),\n route(\"operations\", \"./pages/operations.js\"),\n route(\"apps\", \"./pages/apps.js\"),\n route(\"apps/:appId\", \"./pages/apps.$appId.js\"),\n route(\"new-app\", \"./pages/new-app.js\"),\n route(\"vault\", \"./pages/vault.js\"),\n route(\"integrations\", \"./pages/integrations.js\"),\n route(\"agents\", \"./pages/agents.js\"),\n route(\"workspace\", \"./pages/workspace.js\"),\n route(\"messaging\", \"./pages/messaging.js\"),\n route(\"destinations\", \"./pages/destinations.js\"),\n route(\"transactional-email\", \"./pages/transactional-email.js\"),\n route(\n \"transactional-email/:appId/:id\",\n \"./pages/transactional-email.$appId.$id.js\",\n ),\n route(\"identities\", \"./pages/identities.js\"),\n route(\"approval\", \"./pages/approval.js\"),\n route(\"approvals\", \"./pages/approvals.js\"),\n route(\"automations\", \"./pages/automations.js\"),\n route(\"audit\", \"./pages/audit.js\"),\n route(\"settings\", \"./pages/settings.js\"),\n route(\"dreams\", \"./pages/dreams.js\"),\n route(\"thread-debug\", \"./pages/thread-debug.js\"),\n route(\"team\", \"./pages/team.js\"),\n route(\"extensions\", \"./pages/extensions._index.js\"),\n route(\"extensions/:id\", \"./pages/extensions.$id.js\"),\n route(\"extensions/:id/:slug\", \"./pages/extensions.$id.js\"),\n // Catch-all for /:appId — bounces /dispatch/<appId> to /<appId> when the\n // segment names a workspace app sibling (e.g. Builder.io routing a \"go to\n // /todo\" call through Dispatch's mount). Declared last so React Router 7's\n // specificity ranking still matches explicit static routes above first.\n route(\":appId\", \"./pages/$appId.js\"),\n];\n"]}
@@ -0,0 +1,5 @@
1
+ export declare function meta(): {
2
+ title: string;
3
+ }[];
4
+ export default function AgentIntegrationsRoute(): import("node_modules/@types/react").JSX.Element;
5
+ //# sourceMappingURL=agent-integrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-integrations.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/agent-integrations.tsx"],"names":[],"mappings":"AAIA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,sBAAsB,oDAe7C"}
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useAgentSettingsTabs } from "@agent-native/core/client/settings";
3
+ import { DispatchShell } from "../../components/dispatch-shell.js";
4
+ export function meta() {
5
+ return [{ title: "Integrations — Dispatch" }];
6
+ }
7
+ export default function AgentIntegrationsRoute() {
8
+ const settingsTabs = useAgentSettingsTabs();
9
+ const integrationsTab = settingsTabs.find((tab) => tab.id === "integrations");
10
+ if (!integrationsTab) {
11
+ throw new Error("The shared Integrations settings view is unavailable.");
12
+ }
13
+ return (_jsx(DispatchShell, { title: "Integrations", description: "Connect the tools and services available to your agent.", children: _jsx("div", { className: "mx-auto w-full max-w-5xl", children: integrationsTab.content }) }));
14
+ }
15
+ //# sourceMappingURL=agent-integrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-integrations.js","sourceRoot":"","sources":["../../../src/routes/pages/agent-integrations.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,sBAAsB;IAC5C,MAAM,YAAY,GAAG,oBAAoB,EAAE,CAAC;IAC5C,MAAM,eAAe,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,cAAc,CAAC,CAAC;IAC9E,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,CACL,KAAC,aAAa,IACZ,KAAK,EAAC,cAAc,EACpB,WAAW,EAAC,yDAAyD,YAErE,cAAK,SAAS,EAAC,0BAA0B,YAAE,eAAe,CAAC,OAAO,GAAO,GAC3D,CACjB,CAAC;AACJ,CAAC","sourcesContent":["import { useAgentSettingsTabs } from \"@agent-native/core/client/settings\";\n\nimport { DispatchShell } from \"../../components/dispatch-shell\";\n\nexport function meta() {\n return [{ title: \"Integrations — Dispatch\" }];\n}\n\nexport default function AgentIntegrationsRoute() {\n const settingsTabs = useAgentSettingsTabs();\n const integrationsTab = settingsTabs.find((tab) => tab.id === \"integrations\");\n if (!integrationsTab) {\n throw new Error(\"The shared Integrations settings view is unavailable.\");\n }\n\n return (\n <DispatchShell\n title=\"Integrations\"\n description=\"Connect the tools and services available to your agent.\"\n >\n <div className=\"mx-auto w-full max-w-5xl\">{integrationsTab.content}</div>\n </DispatchShell>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"apps.$appId.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/apps.$appId.tsx"],"names":[],"mappings":"AAkCA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,oDAiMxC"}
1
+ {"version":3,"file":"apps.$appId.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/apps.$appId.tsx"],"names":[],"mappings":"AAkCA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,oDAmNxC"}
@@ -3,7 +3,7 @@ import { useActionMutation, useActionQuery, } from "@agent-native/core/client/ho
3
3
  import { useT } from "@agent-native/core/client/i18n";
4
4
  import { withBuilderUtmTrackingParams } from "@agent-native/core/shared/builder-link-tracking";
5
5
  import { IconArrowLeft, IconClockHour4 } from "@tabler/icons-react";
6
- import { useEffect, useMemo, useState } from "react";
6
+ import { useEffect, useMemo, useRef, useState } from "react";
7
7
  import { Link, useParams } from "react-router";
8
8
  import { ActionQueryError } from "../../components/action-query-error.js";
9
9
  import { Badge } from "../../components/ui/badge.js";
@@ -26,6 +26,7 @@ export default function WorkspaceAppRoute() {
26
26
  const [embedUrl, setEmbedUrl] = useState(null);
27
27
  const [embedError, setEmbedError] = useState(null);
28
28
  const [embedAttempt, setEmbedAttempt] = useState(0);
29
+ const embedFrameRef = useRef(null);
29
30
  const createEmbedSession = useActionMutation("create_embed_session", {
30
31
  skipActionQueryInvalidation: true,
31
32
  });
@@ -66,6 +67,17 @@ export default function WorkspaceAppRoute() {
66
67
  embedAttempt,
67
68
  embedInput,
68
69
  ]);
70
+ useEffect(() => {
71
+ const handleEmbedSessionExpired = (event) => {
72
+ if (event.data?.type !== "agentNative.embedSessionExpired" ||
73
+ event.source !== embedFrameRef.current?.contentWindow) {
74
+ return;
75
+ }
76
+ setEmbedAttempt((attempt) => attempt + 1);
77
+ };
78
+ window.addEventListener("message", handleEmbedSessionExpired);
79
+ return () => window.removeEventListener("message", handleEmbedSessionExpired);
80
+ }, []);
69
81
  if (appsQuery.isError) {
70
82
  return (_jsx("div", { className: "flex h-full min-h-0 items-center justify-center p-6", children: _jsx("div", { className: "w-full max-w-2xl", children: _jsx(ActionQueryError, { error: appsQuery.error, onRetry: () => void appsQuery.refetch() }) }) }));
71
83
  }
@@ -81,6 +93,6 @@ export default function WorkspaceAppRoute() {
81
93
  content: "dispatch_branch",
82
94
  }), target: "_blank", rel: "noreferrer", children: t("dispatch.pages.openBuilderBranch") }) })) : null] })] }) }));
83
95
  }
84
- return (_jsx("div", { "data-dispatch-workspace-app-host": true, className: "flex h-full min-h-0 flex-col bg-background", children: _jsx("div", { className: "min-h-0 flex-1 bg-muted/20", children: embedUrl ? (_jsx("iframe", { "data-dispatch-workspace-app-frame": true, src: embedUrl, title: app.name, referrerPolicy: "no-referrer", className: "h-full w-full border-0 bg-background" })) : embedError ? (_jsx("div", { className: "flex h-full items-center justify-center p-6", children: _jsx("div", { className: "w-full max-w-2xl", children: _jsx(ActionQueryError, { error: embedError, onRetry: () => setEmbedAttempt((attempt) => attempt + 1) }) }) })) : (_jsxs("div", { className: "flex h-full items-center justify-center", children: [_jsx(Spinner, { className: "size-5 text-muted-foreground" }), _jsx("span", { className: "sr-only", children: t("dispatch.pages.loading") })] })) }) }));
96
+ return (_jsx("div", { "data-dispatch-workspace-app-host": true, className: "flex h-full min-h-0 flex-col bg-background", children: _jsx("div", { className: "min-h-0 flex-1 bg-muted/20", children: embedUrl ? (_jsx("iframe", { "data-dispatch-workspace-app-frame": true, src: embedUrl, title: app.name, ref: embedFrameRef, referrerPolicy: "no-referrer", className: "h-full w-full border-0 bg-background" })) : embedError ? (_jsx("div", { className: "flex h-full items-center justify-center p-6", children: _jsx("div", { className: "w-full max-w-2xl", children: _jsx(ActionQueryError, { error: embedError, onRetry: () => setEmbedAttempt((attempt) => attempt + 1) }) }) })) : (_jsxs("div", { className: "flex h-full items-center justify-center", children: [_jsx(Spinner, { className: "size-5 text-muted-foreground" }), _jsx("span", { className: "sr-only", children: t("dispatch.pages.loading") })] })) }) }));
85
97
  }
86
98
  //# sourceMappingURL=apps.$appId.js.map
@@ -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 {\n useActionMutation,\n useActionQuery,\n} from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { withBuilderUtmTrackingParams } from \"@agent-native/core/shared/builder-link-tracking\";\nimport { IconArrowLeft, IconClockHour4 } from \"@tabler/icons-react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { Link, useParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { Spinner } from \"../../components/ui/spinner\";\nimport {\n workspaceAppHref,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\n\ninterface EmbedSessionResult {\n startUrl: string;\n targetPath?: string;\n expiresAt?: number;\n app: string;\n}\n\ninterface EmbedSessionInput {\n app: string;\n path?: string;\n url?: string;\n chrome: \"minimal\";\n}\n\nexport function meta() {\n return [{ title: \"Workspace app - Dispatch\" }];\n}\n\nexport default function WorkspaceAppRoute() {\n const t = useT();\n const { appId } = useParams();\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n });\n const { data: apps = [], isLoading } = appsQuery;\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 const [embedUrl, setEmbedUrl] = useState<string | null>(null);\n const [embedError, setEmbedError] = useState<Error | null>(null);\n const [embedAttempt, setEmbedAttempt] = useState(0);\n const createEmbedSession = useActionMutation<\n EmbedSessionResult,\n EmbedSessionInput\n >(\"create_embed_session\", {\n skipActionQueryInvalidation: true,\n });\n const embedInput = useMemo<EmbedSessionInput | null>(() => {\n if (!app || !href) return null;\n const path = app.path.trim();\n if (path.startsWith(\"/\")) {\n return { app: app.id, path, chrome: \"minimal\" };\n }\n return { app: app.id, url: href, chrome: \"minimal\" };\n }, [app?.id, app?.path, href]);\n\n useEffect(() => {\n if (!app || app.status === \"pending\" || !embedInput) return;\n let cancelled = false;\n setEmbedUrl(null);\n setEmbedError(null);\n void createEmbedSession\n .mutateAsync(embedInput)\n .then((result) => {\n if (!cancelled) setEmbedUrl(result.startUrl);\n })\n .catch((cause: unknown) => {\n if (!cancelled) {\n setEmbedError(\n cause instanceof Error ? cause : new Error(String(cause)),\n );\n }\n });\n return () => {\n cancelled = true;\n };\n }, [\n app?.id,\n app?.path,\n app?.status,\n createEmbedSession.mutateAsync,\n embedAttempt,\n embedInput,\n ]);\n\n if (appsQuery.isError) {\n return (\n <div className=\"flex h-full min-h-0 items-center justify-center p-6\">\n <div className=\"w-full max-w-2xl\">\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n </div>\n </div>\n );\n }\n\n if (isLoading && !app) {\n return (\n <div className=\"flex h-full min-h-0 items-center justify-center p-6\">\n <div className=\"w-full max-w-2xl space-y-3 rounded-xl border bg-card p-6\">\n <Skeleton className=\"h-5 w-48\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-2/3\" />\n </div>\n </div>\n );\n }\n\n if (!app) {\n return (\n <div className=\"flex h-full min-h-0 items-center justify-center p-6\">\n <div className=\"w-full max-w-2xl rounded-xl border bg-card p-6\">\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 {t(\"dispatch.nav.apps\")}\n </Link>\n </Button>\n <div className=\"space-y-3\">\n <h2 className=\"text-base font-semibold text-foreground\">\n {t(\"dispatch.pages.appNotFound\")}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {t(\"dispatch.pages.pageNotFoundDescription\")}\n </p>\n </div>\n </div>\n </div>\n );\n }\n\n if (app.status === \"pending\") {\n return (\n <div className=\"flex h-full min-h-0 items-center justify-center p-6\">\n <div className=\"w-full max-w-2xl rounded-xl border bg-card p-6\">\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 {t(\"dispatch.nav.apps\")}\n </Link>\n </Button>\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 {t(\"dispatch.pages.building\")}\n </Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {t(\"dispatch.pages.appBuildingPrefix\")}{\" \"}\n <span className=\"font-mono text-foreground\">{app.path}</span>{\" \"}\n {t(\"dispatch.pages.appBuildingSuffix\")}\n </p>\n {app.branchName ? (\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.branch\", { branch: app.branchName })}\n </p>\n ) : null}\n {app.builderUrl ? (\n <Button asChild>\n <a\n href={withBuilderUtmTrackingParams(app.builderUrl, {\n campaign: \"product\",\n content: \"dispatch_branch\",\n })}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {t(\"dispatch.pages.openBuilderBranch\")}\n </a>\n </Button>\n ) : null}\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div\n data-dispatch-workspace-app-host\n className=\"flex h-full min-h-0 flex-col bg-background\"\n >\n <div className=\"min-h-0 flex-1 bg-muted/20\">\n {embedUrl ? (\n <iframe\n data-dispatch-workspace-app-frame\n src={embedUrl}\n title={app.name}\n referrerPolicy=\"no-referrer\"\n className=\"h-full w-full border-0 bg-background\"\n />\n ) : embedError ? (\n <div className=\"flex h-full items-center justify-center p-6\">\n <div className=\"w-full max-w-2xl\">\n <ActionQueryError\n error={embedError}\n onRetry={() => setEmbedAttempt((attempt) => attempt + 1)}\n />\n </div>\n </div>\n ) : (\n <div className=\"flex h-full items-center justify-center\">\n <Spinner className=\"size-5 text-muted-foreground\" />\n <span className=\"sr-only\">{t(\"dispatch.pages.loading\")}</span>\n </div>\n )}\n </div>\n </div>\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 {\n useActionMutation,\n useActionQuery,\n} from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { withBuilderUtmTrackingParams } from \"@agent-native/core/shared/builder-link-tracking\";\nimport { IconArrowLeft, IconClockHour4 } from \"@tabler/icons-react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Link, useParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { Spinner } from \"../../components/ui/spinner\";\nimport {\n workspaceAppHref,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\n\ninterface EmbedSessionResult {\n startUrl: string;\n targetPath?: string;\n expiresAt?: number;\n app: string;\n}\n\ninterface EmbedSessionInput {\n app: string;\n path?: string;\n url?: string;\n chrome: \"minimal\";\n}\n\nexport function meta() {\n return [{ title: \"Workspace app - Dispatch\" }];\n}\n\nexport default function WorkspaceAppRoute() {\n const t = useT();\n const { appId } = useParams();\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n });\n const { data: apps = [], isLoading } = appsQuery;\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 const [embedUrl, setEmbedUrl] = useState<string | null>(null);\n const [embedError, setEmbedError] = useState<Error | null>(null);\n const [embedAttempt, setEmbedAttempt] = useState(0);\n const embedFrameRef = useRef<HTMLIFrameElement>(null);\n const createEmbedSession = useActionMutation<\n EmbedSessionResult,\n EmbedSessionInput\n >(\"create_embed_session\", {\n skipActionQueryInvalidation: true,\n });\n const embedInput = useMemo<EmbedSessionInput | null>(() => {\n if (!app || !href) return null;\n const path = app.path.trim();\n if (path.startsWith(\"/\")) {\n return { app: app.id, path, chrome: \"minimal\" };\n }\n return { app: app.id, url: href, chrome: \"minimal\" };\n }, [app?.id, app?.path, href]);\n\n useEffect(() => {\n if (!app || app.status === \"pending\" || !embedInput) return;\n let cancelled = false;\n setEmbedUrl(null);\n setEmbedError(null);\n void createEmbedSession\n .mutateAsync(embedInput)\n .then((result) => {\n if (!cancelled) setEmbedUrl(result.startUrl);\n })\n .catch((cause: unknown) => {\n if (!cancelled) {\n setEmbedError(\n cause instanceof Error ? cause : new Error(String(cause)),\n );\n }\n });\n return () => {\n cancelled = true;\n };\n }, [\n app?.id,\n app?.path,\n app?.status,\n createEmbedSession.mutateAsync,\n embedAttempt,\n embedInput,\n ]);\n\n useEffect(() => {\n const handleEmbedSessionExpired = (event: MessageEvent) => {\n if (\n event.data?.type !== \"agentNative.embedSessionExpired\" ||\n event.source !== embedFrameRef.current?.contentWindow\n ) {\n return;\n }\n setEmbedAttempt((attempt) => attempt + 1);\n };\n\n window.addEventListener(\"message\", handleEmbedSessionExpired);\n return () =>\n window.removeEventListener(\"message\", handleEmbedSessionExpired);\n }, []);\n\n if (appsQuery.isError) {\n return (\n <div className=\"flex h-full min-h-0 items-center justify-center p-6\">\n <div className=\"w-full max-w-2xl\">\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n </div>\n </div>\n );\n }\n\n if (isLoading && !app) {\n return (\n <div className=\"flex h-full min-h-0 items-center justify-center p-6\">\n <div className=\"w-full max-w-2xl space-y-3 rounded-xl border bg-card p-6\">\n <Skeleton className=\"h-5 w-48\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-2/3\" />\n </div>\n </div>\n );\n }\n\n if (!app) {\n return (\n <div className=\"flex h-full min-h-0 items-center justify-center p-6\">\n <div className=\"w-full max-w-2xl rounded-xl border bg-card p-6\">\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 {t(\"dispatch.nav.apps\")}\n </Link>\n </Button>\n <div className=\"space-y-3\">\n <h2 className=\"text-base font-semibold text-foreground\">\n {t(\"dispatch.pages.appNotFound\")}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {t(\"dispatch.pages.pageNotFoundDescription\")}\n </p>\n </div>\n </div>\n </div>\n );\n }\n\n if (app.status === \"pending\") {\n return (\n <div className=\"flex h-full min-h-0 items-center justify-center p-6\">\n <div className=\"w-full max-w-2xl rounded-xl border bg-card p-6\">\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 {t(\"dispatch.nav.apps\")}\n </Link>\n </Button>\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 {t(\"dispatch.pages.building\")}\n </Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {t(\"dispatch.pages.appBuildingPrefix\")}{\" \"}\n <span className=\"font-mono text-foreground\">{app.path}</span>{\" \"}\n {t(\"dispatch.pages.appBuildingSuffix\")}\n </p>\n {app.branchName ? (\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.branch\", { branch: app.branchName })}\n </p>\n ) : null}\n {app.builderUrl ? (\n <Button asChild>\n <a\n href={withBuilderUtmTrackingParams(app.builderUrl, {\n campaign: \"product\",\n content: \"dispatch_branch\",\n })}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {t(\"dispatch.pages.openBuilderBranch\")}\n </a>\n </Button>\n ) : null}\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div\n data-dispatch-workspace-app-host\n className=\"flex h-full min-h-0 flex-col bg-background\"\n >\n <div className=\"min-h-0 flex-1 bg-muted/20\">\n {embedUrl ? (\n <iframe\n data-dispatch-workspace-app-frame\n src={embedUrl}\n title={app.name}\n ref={embedFrameRef}\n referrerPolicy=\"no-referrer\"\n className=\"h-full w-full border-0 bg-background\"\n />\n ) : embedError ? (\n <div className=\"flex h-full items-center justify-center p-6\">\n <div className=\"w-full max-w-2xl\">\n <ActionQueryError\n error={embedError}\n onRetry={() => setEmbedAttempt((attempt) => attempt + 1)}\n />\n </div>\n </div>\n ) : (\n <div className=\"flex h-full items-center justify-center\">\n <Spinner className=\"size-5 text-muted-foreground\" />\n <span className=\"sr-only\">{t(\"dispatch.pages.loading\")}</span>\n </div>\n )}\n </div>\n </div>\n );\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":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EACL,QAAQ,EACR,eAAe,EACf,cAAc,EACd,UAAU,EACV,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,OAAO,GACR,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAMvE,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAGrC,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;AACxC,CAAC;AAQD,MAAM,CAAC,OAAO,UAAU,cAAc;IACpC,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,EAAE,CAAC;IAC9B,OAAO,KAAK,CAAC,CAAC,CAAC,KAAC,MAAM,KAAG,CAAC,CAAC,CAAC,KAAC,SAAS,KAAG,CAAC;AAC5C,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,cAAc,CAAC,qBAAqB,EAAE;QACtD,iBAAiB,EAAE,KAAK;QACxB,eAAe,EAAE,IAAI;KACtB,CAAC,CAAC;IACH,MAAM,kBAAkB,GAAG,cAAc,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;IACvE,MAAM,qBAAqB,GAAG,cAAc,CAC1C,kCAAkC,EAClC,EAAE,CACH,CAAC;IACF,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;IAC9D,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,OAAO,GAAI,IAA8B,CAAC,MAAM,CACpD,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CACzB,CAAC;IACF,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3D,MAAM,gBAAgB,GAAG,WAAW,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;IAC7D,MAAM,cAAc,GAA4B;QAC9C,KAAK,EAAE,CAAC,CAAC,gCAAgC,CAAC;QAC1C,gBAAgB,EAAE,CAAC,CAAC,sCAAsC,CAAC;QAC3D,MAAM,EAAE,CAAC,CAAC,uBAAuB,CAAC;QAClC,gBAAgB,EAAE,CAAC,CAAC,iCAAiC,CAAC;QACtD,SAAS,EAAE,CAAC,CAAC,mCAAmC,CAAC;QACjD,KAAK,EAAE,CAAC,CAAC,uBAAuB,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;QAC9D,QAAQ,EAAE,CAAC,CAAC,yBAAyB,CAAC;QACtC,YAAY,EAAE,CAAC,CAAC,6BAA6B,CAAC;QAC9C,UAAU,EAAE,CAAC,CAAC,2BAA2B,CAAC;QAC1C,aAAa,EAAE,CAAC,CAAC,8BAA8B,CAAC;QAChD,MAAM,EAAE,CAAC,CAAC,uBAAuB,CAAC;QAClC,OAAO,EAAE,CAAC,CAAC,wBAAwB,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;QAClE,WAAW,EAAE,CAAC,CAAC,wBAAwB,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;KACnE,CAAC;IAEF,OAAO,CACL,KAAC,aAAa,IACZ,KAAK,EAAE,CAAC,CAAC,mBAAmB,CAAC,EAC7B,WAAW,EACT,cAAc;YACZ,CAAC,CAAC,CAAC,CAAC,6CAA6C,EAAE;gBAC/C,SAAS,EAAE,cAAc;aAC1B,CAAC;YACJ,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC,YAGzC,eAAK,SAAS,EAAC,WAAW,aACxB,mBAAS,SAAS,EAAC,WAAW,aAC5B,eAAK,SAAS,EAAC,gDAAgD,aAC7D,eAAK,SAAS,EAAC,gCAAgC,aAC7C,KAAC,QAAQ,IACP,IAAI,EAAE,EAAE,EACR,SAAS,EAAC,uCAAuC,GACjD,EACF,eAAK,SAAS,EAAC,SAAS,aACtB,aAAI,SAAS,EAAC,gDAAgD,YAC3D,CAAC,CAAC,yBAAyB,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,GACzD,EACL,aAAG,SAAS,EAAC,sCAAsC,aAChD,CAAC,CAAC,4BAA4B,EAAE;4DAC/B,KAAK,EAAE,UAAU,CAAC,MAAM;yDACzB,CAAC,EACD,WAAW,CAAC,MAAM,GAAG,CAAC;4DACrB,CAAC,CAAC,MAAM,CAAC,CAAC,6BAA6B,EAAE;gEACrC,KAAK,EAAE,WAAW,CAAC,MAAM;6DAC1B,CAAC,EAAE;4DACN,CAAC,CAAC,EAAE,EACL,YAAY,CAAC,MAAM,GAAG,CAAC;4DACtB,CAAC,CAAC,MAAM,CAAC,CAAC,4BAA4B,EAAE;gEACpC,KAAK,EAAE,YAAY,CAAC,MAAM;6DAC3B,CAAC,EAAE;4DACN,CAAC,CAAC,EAAE,IACJ,IACA,IACF,EACL,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACjD,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,EACxC,CAAC,CAAC,uBAAuB,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,IACjD,GAEX,CACH,CAAC,CAAC,CAAC,IAAI,IACJ,EAEL,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CACnB,KAAC,gBAAgB,IACf,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC,OAAO,EAAE,GACvC,CACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CACrB,KAAC,gBAAgB,KAAG,CACrB,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC1B,KAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,YACpC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACvB,KAAC,gBAAgB,IAEf,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,uBAAuB,IAF7B,GAAG,CAAC,EAAE,CAGX,CACH,CAAC,GACM,CACX,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC3B,KAAC,oBAAoB,KAAG,CACzB,CAAC,CAAC,CAAC,CACF,KAAC,cAAc,KAAG,CACnB,IACO,EAET,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACxB,KAAC,WAAW,IAAC,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,YAC1D,mBAAS,SAAS,EAAC,yBAAyB,aAC1C,eAAK,SAAS,EAAC,mDAAmD,aAChE,eAAK,SAAS,EAAC,iCAAiC,aAC9C,KAAC,cAAc,IACb,IAAI,EAAE,EAAE,EACR,SAAS,EAAC,gCAAgC,GAC1C,EACF,eAAK,SAAS,EAAC,SAAS,aACtB,aAAI,SAAS,EAAC,uCAAuC,YAClD,CAAC,CAAC,4BAA4B,CAAC,GAC7B,EACL,YAAG,SAAS,EAAC,+BAA+B,YACzC,CAAC,CAAC,6BAA6B,EAAE;4DAChC,KAAK,EAAE,WAAW,CAAC,MAAM;yDAC1B,CAAC,GACA,IACA,IACF,EACN,KAAC,kBAAkB,IAAC,OAAO,kBACzB,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,SAAS,aAElB,WAAW;oDACV,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC;oDACrC,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC,EACvC,KAAC,eAAe,IACd,IAAI,EAAE,EAAE,EACR,SAAS,EAAE,EAAE,CACX,sBAAsB,EACtB,WAAW,IAAI,YAAY,CAC5B,GACD,IACK,GACU,IACjB,EACN,KAAC,kBAAkB,cACjB,KAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,YACpC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACxB,KAAC,gBAAgB,IAEf,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,uBAAuB,IAF7B,GAAG,CAAC,EAAE,CAGX,CACH,CAAC,GACM,GACS,IACb,GACE,CACf,CAAC,CAAC,CAAC,IAAI,EAER,KAAC,gBAAgB,IACf,SAAS,EACP,qBAAqB,CAAC,IAET,EAEf,aAAa,EACX,kBAAkB,CAAC,IAAyC,EAE9D,aAAa,EAAE,OAAO,EACtB,gBAAgB,EAAE,qBAAqB,CAAC,SAAS,EACjD,oBAAoB,EAAE,kBAAkB,CAAC,SAAS,EAClD,cAAc,EAAE,qBAAqB,CAAC,KAAK,EAC3C,kBAAkB,EAAE,kBAAkB,CAAC,KAAK,EAC5C,gBAAgB,EAAE,GAAG,EAAE,CAAC,KAAK,qBAAqB,CAAC,OAAO,EAAE,EAC5D,oBAAoB,EAAE,GAAG,EAAE,CAAC,KAAK,kBAAkB,CAAC,OAAO,EAAE,EAC7D,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,GAAG,EAAE;wBACnB,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;wBACzB,KAAK,qBAAqB,CAAC,OAAO,EAAE,CAAC;oBACvC,CAAC,GACD,EAED,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACzB,KAAC,WAAW,IAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,YACxD,mBAAS,SAAS,EAAC,WAAW,aAC5B,eAAK,SAAS,EAAC,iEAAiE,aAC9E,eAAK,SAAS,EAAC,iCAAiC,aAC9C,KAAC,UAAU,IACT,IAAI,EAAE,EAAE,EACR,SAAS,EAAC,gCAAgC,GAC1C,EACF,eAAK,SAAS,EAAC,SAAS,aACtB,aAAI,SAAS,EAAC,uCAAuC,YAClD,CAAC,CAAC,2BAA2B,CAAC,GAC5B,EACL,YAAG,SAAS,EAAC,+BAA+B,YACzC,CAAC,CAAC,+BAA+B,EAAE;4DAClC,KAAK,EAAE,YAAY,CAAC,MAAM;yDAC3B,CAAC,GACA,IACA,IACF,EACN,KAAC,kBAAkB,IAAC,OAAO,kBACzB,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,SAAS,EAAC,SAAS,aAElB,UAAU;oDACT,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC;oDAC1B,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,EAC5B,KAAC,eAAe,IACd,IAAI,EAAE,EAAE,EACR,SAAS,EAAE,EAAE,CACX,sBAAsB,EACtB,UAAU,IAAI,YAAY,CAC3B,GACD,IACK,GACU,IACjB,EACN,KAAC,kBAAkB,cACjB,KAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,YACpC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACzB,KAAC,gBAAgB,IAEf,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,uBAAuB,IAF7B,GAAG,CAAC,EAAE,CAGX,CACH,CAAC,GACM,GACS,IACb,GACE,CACf,CAAC,CAAC,CAAC,IAAI,IACJ,GACQ,CACjB,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,CACL,KAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,YACpC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAC3C,eAEE,SAAS,EAAE,EAAE,CACX,sEAAsE,EACtE,uBAAuB,CACxB,aAED,KAAC,QAAQ,IAAC,SAAS,EAAC,4BAA4B,GAAG,EACnD,eAAK,SAAS,EAAC,0BAA0B,aACvC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,IAC9B,EACN,KAAC,QAAQ,IAAC,SAAS,EAAC,8BAA8B,GAAG,KAXhD,KAAK,CAYN,CACP,CAAC,GACM,CACX,CAAC;AACJ,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,OAAO,CACL,eAAK,SAAS,EAAC,gEAAgE,aAC7E,cAAK,SAAS,EAAC,4FAA4F,YACzG,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,GAAI,GAClB,EACN,aAAI,SAAS,EAAC,4CAA4C,YACvD,CAAC,CAAC,gCAAgC,CAAC,GACjC,EACL,YAAG,SAAS,EAAC,qDAAqD,YAC/D,CAAC,CAAC,2CAA2C,CAAC,GAC7C,EACJ,cAAK,SAAS,EAAC,MAAM,YACnB,KAAC,gBAAgB,IACf,OAAO,EACL,MAAC,MAAM,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAC,SAAS,aACjC,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAC,QAAQ,GAAG,EACxC,CAAC,CAAC,uBAAuB,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,IACjD,GAEX,GACE,IACF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB;IAC3B,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,OAAO,CACL,eAAK,SAAS,EAAC,gEAAgE,aAC7E,YAAG,SAAS,EAAC,qCAAqC,YAC/C,CAAC,CAAC,sCAAsC,CAAC,GACxC,EACJ,YAAG,SAAS,EAAC,qDAAqD,YAC/D,CAAC,CAAC,iDAAiD,CAAC,GACnD,IACA,CACP,CAAC;AACJ,CAAC","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,13 +1,13 @@
1
1
  export declare function meta(): ({
2
+ title: string;
2
3
  name?: undefined;
3
4
  property?: undefined;
4
5
  content?: undefined;
5
- title: string;
6
6
  } | {
7
7
  title?: undefined;
8
- property?: undefined;
9
8
  name: string;
10
9
  content: string;
10
+ property?: undefined;
11
11
  } | {
12
12
  title?: undefined;
13
13
  name?: undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/settings.tsx"],"names":[],"mappings":"AA4BA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,oDAoKpC"}
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/settings.tsx"],"names":[],"mappings":"AA4BA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,oDAkJpC"}
@@ -35,6 +35,6 @@ export default function SettingsRoute() {
35
35
  detail: { enabled },
36
36
  }));
37
37
  }
38
- return (_jsx(DispatchShell, { title: t("settings.title"), description: t("settings.description"), children: _jsx(SettingsTabsPage, { extraTabs: agentSettingsTabs, general: _jsxs("div", { className: "mx-auto w-full max-w-3xl space-y-6", children: [_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: t("settings.languageTitle") }), _jsx(CardDescription, { children: t("settings.languageDescription") })] }), _jsxs(CardContent, { className: "max-w-xs space-y-1.5", children: [_jsx(Label, { children: t("settings.languageLabel") }), _jsx(LanguagePicker, { label: t("settings.languageLabel") })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: "Chat-first workspace" }), _jsx(CardDescription, { children: "Keep chats at the center and open workspace apps in a contextual pane beside them." })] }), _jsxs(CardContent, { className: "flex items-center justify-between gap-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { htmlFor: "dispatch-chat-first-mode", children: "Use chat-first navigation" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "This preference only changes your local Dispatch shell." }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Session watch and follow-up messaging work in this browser pane too. Local CLI subscription detection stays in the Electron app; Dispatch uses workspace/provider credentials." })] }), _jsx(Switch, { id: "dispatch-chat-first-mode", checked: chatFirstMode, onCheckedChange: updateChatFirstMode })] }), chatFirstStorageNotice ? (_jsx("p", { className: "px-6 pb-4 text-sm text-destructive", role: "alert", children: chatFirstStorageNotice })) : null] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: t("settings.workspaceTitle") }), _jsx(CardDescription, { children: t("settings.workspaceDescription") })] }), _jsx(CardContent, { children: _jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/admin/workspace", children: t("settings.openResourceSettings") }) }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: t("settings.automationsTitle") }), _jsx(CardDescription, { children: t("settings.automationsDescription") })] }), _jsx(CardContent, { children: _jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/admin/automations", children: t("settings.openAutomations") }) }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: t("settings.deliveryTitle") }), _jsx(CardDescription, { children: t("settings.deliveryDescription") })] }), _jsx(CardContent, { children: _jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/admin/destinations", children: t("settings.openDelivery") }) }) })] })] }), team: _jsx("div", { className: "mx-auto w-full max-w-3xl", children: _jsx(TeamPage, { showTitle: false, createOrgDescription: "Set up a team to share dispatch destinations and approvals with your colleagues." }) }), whatsNew: _jsx("div", { className: "mx-auto w-full max-w-3xl", children: _jsx(ChangelogSettingsCard, { markdown: changelog }) }) }) }));
38
+ return (_jsx(DispatchShell, { title: t("settings.title"), description: t("settings.description"), children: _jsx(SettingsTabsPage, { extraTabs: agentSettingsTabs.filter((tab) => tab.id !== "integrations"), general: _jsxs("div", { className: "mx-auto w-full max-w-3xl space-y-6", children: [_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: t("settings.languageTitle") }), _jsx(CardDescription, { children: t("settings.languageDescription") })] }), _jsxs(CardContent, { className: "max-w-xs space-y-1.5", children: [_jsx(Label, { children: t("settings.languageLabel") }), _jsx(LanguagePicker, { label: t("settings.languageLabel") })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: "Chat-first workspace" }), _jsx(CardDescription, { children: "Keep chats at the center and open workspace apps in a contextual pane beside them." })] }), _jsxs(CardContent, { className: "flex items-center justify-between gap-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { htmlFor: "dispatch-chat-first-mode", children: "Use chat-first navigation" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "This preference only changes your local Dispatch shell." }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Session watch and follow-up messaging work in this browser pane too. Local CLI subscription detection stays in the Electron app; Dispatch uses workspace/provider credentials." })] }), _jsx(Switch, { id: "dispatch-chat-first-mode", checked: chatFirstMode, onCheckedChange: updateChatFirstMode })] }), chatFirstStorageNotice ? (_jsx("p", { className: "px-6 pb-4 text-sm text-destructive", role: "alert", children: chatFirstStorageNotice })) : null] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: t("settings.workspaceTitle") }), _jsx(CardDescription, { children: t("settings.workspaceDescription") })] }), _jsx(CardContent, { children: _jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/admin/workspace", children: t("settings.openResourceSettings") }) }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: t("settings.deliveryTitle") }), _jsx(CardDescription, { children: t("settings.deliveryDescription") })] }), _jsx(CardContent, { children: _jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/admin/destinations", children: t("settings.openDelivery") }) }) })] })] }), team: _jsx("div", { className: "mx-auto w-full max-w-3xl", children: _jsx(TeamPage, { showTitle: false, createOrgDescription: "Set up a team to share dispatch destinations and approvals with your colleagues." }) }), whatsNew: _jsx("div", { className: "mx-auto w-full max-w-3xl", children: _jsx(ChangelogSettingsCard, { markdown: changelog }) }) }) }));
39
39
  }
40
40
  //# sourceMappingURL=settings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/routes/pages/settings.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n CHAT_FIRST_MODE_CHANGED_EVENT,\n readChatFirstModeState,\n writeChatFirstMode,\n} from \"@agent-native/core/client/agent-chat\";\nimport { ChangelogSettingsCard } from \"@agent-native/core/client/changelog\";\nimport { LanguagePicker, useT } from \"@agent-native/core/client/i18n\";\nimport { TeamPage } from \"@agent-native/core/client/org\";\nimport {\n SettingsTabsPage,\n useAgentSettingsTabs,\n} from \"@agent-native/core/client/settings\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router\";\n\nimport changelog from \"../../../CHANGELOG.md?raw\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"../../components/ui/card\";\nimport { Label } from \"../../components/ui/label\";\nimport { Switch } from \"../../components/ui/switch\";\n\nexport function meta() {\n return [{ title: \"Settings - Dispatch\" }];\n}\n\nexport default function SettingsRoute() {\n const t = useT();\n const agentSettingsTabs = useAgentSettingsTabs();\n const [chatFirstModeState] = useState(() => readChatFirstModeState());\n const [chatFirstMode, setChatFirstMode] = useState(\n () => chatFirstModeState.enabled,\n );\n const [chatFirstStorageNotice, setChatFirstStorageNotice] = useState<\n string | null\n >(\n chatFirstModeState.availability === \"unavailable\"\n ? \"This browser is not allowing local preferences, so Chat-first mode cannot be persisted.\"\n : null,\n );\n\n function updateChatFirstMode(enabled: boolean) {\n const result = writeChatFirstMode(enabled);\n if (!result.ok) {\n setChatFirstStorageNotice(\n \"This browser blocked local preferences, so Chat-first mode was not changed.\",\n );\n return;\n }\n setChatFirstStorageNotice(null);\n setChatFirstMode(enabled);\n window.dispatchEvent(\n new CustomEvent(CHAT_FIRST_MODE_CHANGED_EVENT, {\n detail: { enabled },\n }),\n );\n }\n\n return (\n <DispatchShell\n title={t(\"settings.title\")}\n description={t(\"settings.description\")}\n >\n <SettingsTabsPage\n extraTabs={agentSettingsTabs}\n general={\n <div className=\"mx-auto w-full max-w-3xl space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t(\"settings.languageTitle\")}\n </CardTitle>\n <CardDescription>\n {t(\"settings.languageDescription\")}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"max-w-xs space-y-1.5\">\n <Label>{t(\"settings.languageLabel\")}</Label>\n <LanguagePicker label={t(\"settings.languageLabel\")} />\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n Chat-first workspace\n </CardTitle>\n <CardDescription>\n Keep chats at the center and open workspace apps in a\n contextual pane beside them.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"flex items-center justify-between gap-4\">\n <div className=\"space-y-1\">\n <Label htmlFor=\"dispatch-chat-first-mode\">\n Use chat-first navigation\n </Label>\n <p className=\"text-sm text-muted-foreground\">\n This preference only changes your local Dispatch shell.\n </p>\n <p className=\"text-sm text-muted-foreground\">\n Session watch and follow-up messaging work in this browser\n pane too. Local CLI subscription detection stays in the\n Electron app; Dispatch uses workspace/provider credentials.\n </p>\n </div>\n <Switch\n id=\"dispatch-chat-first-mode\"\n checked={chatFirstMode}\n onCheckedChange={updateChatFirstMode}\n />\n </CardContent>\n {chatFirstStorageNotice ? (\n <p className=\"px-6 pb-4 text-sm text-destructive\" role=\"alert\">\n {chatFirstStorageNotice}\n </p>\n ) : null}\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t(\"settings.workspaceTitle\")}\n </CardTitle>\n <CardDescription>\n {t(\"settings.workspaceDescription\")}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Button variant=\"outline\" asChild>\n <Link to=\"/admin/workspace\">\n {t(\"settings.openResourceSettings\")}\n </Link>\n </Button>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t(\"settings.automationsTitle\")}\n </CardTitle>\n <CardDescription>\n {t(\"settings.automationsDescription\")}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Button variant=\"outline\" asChild>\n <Link to=\"/admin/automations\">\n {t(\"settings.openAutomations\")}\n </Link>\n </Button>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t(\"settings.deliveryTitle\")}\n </CardTitle>\n <CardDescription>\n {t(\"settings.deliveryDescription\")}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Button variant=\"outline\" asChild>\n <Link to=\"/admin/destinations\">\n {t(\"settings.openDelivery\")}\n </Link>\n </Button>\n </CardContent>\n </Card>\n </div>\n }\n team={\n <div className=\"mx-auto w-full max-w-3xl\">\n <TeamPage\n showTitle={false}\n createOrgDescription=\"Set up a team to share dispatch destinations and approvals with your colleagues.\"\n />\n </div>\n }\n whatsNew={\n <div className=\"mx-auto w-full max-w-3xl\">\n <ChangelogSettingsCard markdown={changelog} />\n </div>\n }\n />\n </DispatchShell>\n );\n}\n"]}
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/routes/pages/settings.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n CHAT_FIRST_MODE_CHANGED_EVENT,\n readChatFirstModeState,\n writeChatFirstMode,\n} from \"@agent-native/core/client/agent-chat\";\nimport { ChangelogSettingsCard } from \"@agent-native/core/client/changelog\";\nimport { LanguagePicker, useT } from \"@agent-native/core/client/i18n\";\nimport { TeamPage } from \"@agent-native/core/client/org\";\nimport {\n SettingsTabsPage,\n useAgentSettingsTabs,\n} from \"@agent-native/core/client/settings\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router\";\n\nimport changelog from \"../../../CHANGELOG.md?raw\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"../../components/ui/card\";\nimport { Label } from \"../../components/ui/label\";\nimport { Switch } from \"../../components/ui/switch\";\n\nexport function meta() {\n return [{ title: \"Settings - Dispatch\" }];\n}\n\nexport default function SettingsRoute() {\n const t = useT();\n const agentSettingsTabs = useAgentSettingsTabs();\n const [chatFirstModeState] = useState(() => readChatFirstModeState());\n const [chatFirstMode, setChatFirstMode] = useState(\n () => chatFirstModeState.enabled,\n );\n const [chatFirstStorageNotice, setChatFirstStorageNotice] = useState<\n string | null\n >(\n chatFirstModeState.availability === \"unavailable\"\n ? \"This browser is not allowing local preferences, so Chat-first mode cannot be persisted.\"\n : null,\n );\n\n function updateChatFirstMode(enabled: boolean) {\n const result = writeChatFirstMode(enabled);\n if (!result.ok) {\n setChatFirstStorageNotice(\n \"This browser blocked local preferences, so Chat-first mode was not changed.\",\n );\n return;\n }\n setChatFirstStorageNotice(null);\n setChatFirstMode(enabled);\n window.dispatchEvent(\n new CustomEvent(CHAT_FIRST_MODE_CHANGED_EVENT, {\n detail: { enabled },\n }),\n );\n }\n\n return (\n <DispatchShell\n title={t(\"settings.title\")}\n description={t(\"settings.description\")}\n >\n <SettingsTabsPage\n extraTabs={agentSettingsTabs.filter((tab) => tab.id !== \"integrations\")}\n general={\n <div className=\"mx-auto w-full max-w-3xl space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t(\"settings.languageTitle\")}\n </CardTitle>\n <CardDescription>\n {t(\"settings.languageDescription\")}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"max-w-xs space-y-1.5\">\n <Label>{t(\"settings.languageLabel\")}</Label>\n <LanguagePicker label={t(\"settings.languageLabel\")} />\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n Chat-first workspace\n </CardTitle>\n <CardDescription>\n Keep chats at the center and open workspace apps in a\n contextual pane beside them.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"flex items-center justify-between gap-4\">\n <div className=\"space-y-1\">\n <Label htmlFor=\"dispatch-chat-first-mode\">\n Use chat-first navigation\n </Label>\n <p className=\"text-sm text-muted-foreground\">\n This preference only changes your local Dispatch shell.\n </p>\n <p className=\"text-sm text-muted-foreground\">\n Session watch and follow-up messaging work in this browser\n pane too. Local CLI subscription detection stays in the\n Electron app; Dispatch uses workspace/provider credentials.\n </p>\n </div>\n <Switch\n id=\"dispatch-chat-first-mode\"\n checked={chatFirstMode}\n onCheckedChange={updateChatFirstMode}\n />\n </CardContent>\n {chatFirstStorageNotice ? (\n <p className=\"px-6 pb-4 text-sm text-destructive\" role=\"alert\">\n {chatFirstStorageNotice}\n </p>\n ) : null}\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t(\"settings.workspaceTitle\")}\n </CardTitle>\n <CardDescription>\n {t(\"settings.workspaceDescription\")}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Button variant=\"outline\" asChild>\n <Link to=\"/admin/workspace\">\n {t(\"settings.openResourceSettings\")}\n </Link>\n </Button>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t(\"settings.deliveryTitle\")}\n </CardTitle>\n <CardDescription>\n {t(\"settings.deliveryDescription\")}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Button variant=\"outline\" asChild>\n <Link to=\"/admin/destinations\">\n {t(\"settings.openDelivery\")}\n </Link>\n </Button>\n </CardContent>\n </Card>\n </div>\n }\n team={\n <div className=\"mx-auto w-full max-w-3xl\">\n <TeamPage\n showTitle={false}\n createOrgDescription=\"Set up a team to share dispatch destinations and approvals with your colleagues.\"\n />\n </div>\n }\n whatsNew={\n <div className=\"mx-auto w-full max-w-3xl\">\n <ChangelogSettingsCard markdown={changelog} />\n </div>\n }\n />\n </DispatchShell>\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"]}