@agent-native/dispatch 0.23.3 → 0.24.0

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 (139) hide show
  1. package/dist/actions/list-connected-agents.d.ts +1 -0
  2. package/dist/actions/list-connected-agents.js +5 -1
  3. package/dist/actions/list-connected-agents.js.map +1 -1
  4. package/dist/actions/list-dispatch-usage-metrics.d.ts +2 -0
  5. package/dist/actions/list-dispatch-usage-metrics.js +11 -1
  6. package/dist/actions/list-dispatch-usage-metrics.js.map +1 -1
  7. package/dist/actions/provider-api-register.d.ts +11 -11
  8. package/dist/actions/remix-workspace-template.js +4 -3
  9. package/dist/actions/remix-workspace-template.js.map +1 -1
  10. package/dist/actions/scaffold-workspace-app.js +3 -2
  11. package/dist/actions/scaffold-workspace-app.js.map +1 -1
  12. package/dist/actions/start-workspace-app-creation.js +3 -2
  13. package/dist/actions/start-workspace-app-creation.js.map +1 -1
  14. package/dist/actions/view-screen.js +11 -1
  15. package/dist/actions/view-screen.js.map +1 -1
  16. package/dist/components/app-icon.js +1 -1
  17. package/dist/components/app-icon.js.map +1 -1
  18. package/dist/components/app-list-row.d.ts +1 -1
  19. package/dist/components/app-list-row.d.ts.map +1 -1
  20. package/dist/components/app-list-row.js +2 -2
  21. package/dist/components/app-list-row.js.map +1 -1
  22. package/dist/components/connected-app-card.d.ts.map +1 -1
  23. package/dist/components/connected-app-card.js +2 -1
  24. package/dist/components/connected-app-card.js.map +1 -1
  25. package/dist/components/create-app-popover.d.ts.map +1 -1
  26. package/dist/components/create-app-popover.js +11 -0
  27. package/dist/components/create-app-popover.js.map +1 -1
  28. package/dist/components/dispatch-control-plane.d.ts.map +1 -1
  29. package/dist/components/dispatch-control-plane.js +3 -2
  30. package/dist/components/dispatch-control-plane.js.map +1 -1
  31. package/dist/components/layout/Layout.d.ts +1 -0
  32. package/dist/components/layout/Layout.d.ts.map +1 -1
  33. package/dist/components/layout/Layout.js +47 -10
  34. package/dist/components/layout/Layout.js.map +1 -1
  35. package/dist/components/layout/workspace-apps-rail.d.ts.map +1 -1
  36. package/dist/components/layout/workspace-apps-rail.js +2 -2
  37. package/dist/components/layout/workspace-apps-rail.js.map +1 -1
  38. package/dist/components/other-apps-section.d.ts.map +1 -1
  39. package/dist/components/other-apps-section.js +5 -1
  40. package/dist/components/other-apps-section.js.map +1 -1
  41. package/dist/components/workspace-template-card.d.ts.map +1 -1
  42. package/dist/components/workspace-template-card.js +8 -14
  43. package/dist/components/workspace-template-card.js.map +1 -1
  44. package/dist/config.d.ts +2 -0
  45. package/dist/config.d.ts.map +1 -1
  46. package/dist/config.js.map +1 -1
  47. package/dist/hooks/use-navigation-state.d.ts +2 -0
  48. package/dist/hooks/use-navigation-state.d.ts.map +1 -1
  49. package/dist/hooks/use-navigation-state.js +10 -0
  50. package/dist/hooks/use-navigation-state.js.map +1 -1
  51. package/dist/lib/embed-session-recovery.d.ts +3 -0
  52. package/dist/lib/embed-session-recovery.d.ts.map +1 -0
  53. package/dist/lib/embed-session-recovery.js +18 -0
  54. package/dist/lib/embed-session-recovery.js.map +1 -0
  55. package/dist/lib/other-apps.d.ts +2 -0
  56. package/dist/lib/other-apps.d.ts.map +1 -1
  57. package/dist/lib/other-apps.js +2 -0
  58. package/dist/lib/other-apps.js.map +1 -1
  59. package/dist/lib/workspace-apps.d.ts +7 -0
  60. package/dist/lib/workspace-apps.d.ts.map +1 -1
  61. package/dist/lib/workspace-apps.js +17 -0
  62. package/dist/lib/workspace-apps.js.map +1 -1
  63. package/dist/lib/workspace-apps.test.d.ts +2 -0
  64. package/dist/lib/workspace-apps.test.d.ts.map +1 -0
  65. package/dist/lib/workspace-apps.test.js +16 -0
  66. package/dist/lib/workspace-apps.test.js.map +1 -0
  67. package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
  68. package/dist/routes/pages/apps.$appId.js +10 -11
  69. package/dist/routes/pages/apps.$appId.js.map +1 -1
  70. package/dist/routes/pages/apps.d.ts.map +1 -1
  71. package/dist/routes/pages/apps.js +2 -1
  72. package/dist/routes/pages/apps.js.map +1 -1
  73. package/dist/routes/pages/chat.d.ts.map +1 -1
  74. package/dist/routes/pages/chat.js +7 -2
  75. package/dist/routes/pages/chat.js.map +1 -1
  76. package/dist/routes/pages/metrics.d.ts.map +1 -1
  77. package/dist/routes/pages/metrics.js +143 -17
  78. package/dist/routes/pages/metrics.js.map +1 -1
  79. package/dist/routes/pages/settings.d.ts.map +1 -1
  80. package/dist/routes/pages/settings.js +13 -1
  81. package/dist/routes/pages/settings.js.map +1 -1
  82. package/dist/server/lib/usage-metrics-store.d.ts +17 -0
  83. package/dist/server/lib/usage-metrics-store.d.ts.map +1 -1
  84. package/dist/server/lib/usage-metrics-store.js +187 -30
  85. package/dist/server/lib/usage-metrics-store.js.map +1 -1
  86. package/dist/server/plugins/agent-chat.js +2 -0
  87. package/dist/server/plugins/agent-chat.js.map +1 -1
  88. package/dist/server/plugins/auth.d.ts.map +1 -1
  89. package/dist/server/plugins/auth.js +1 -0
  90. package/dist/server/plugins/auth.js.map +1 -1
  91. package/dist/server/plugins/integrations.d.ts.map +1 -1
  92. package/dist/server/plugins/integrations.js +1 -0
  93. package/dist/server/plugins/integrations.js.map +1 -1
  94. package/package.json +3 -3
  95. package/src/actions/list-connected-agents.spec.ts +73 -0
  96. package/src/actions/list-connected-agents.ts +6 -2
  97. package/src/actions/list-dispatch-usage-metrics.ts +11 -1
  98. package/src/actions/remix-workspace-template.spec.ts +29 -0
  99. package/src/actions/remix-workspace-template.ts +13 -6
  100. package/src/actions/scaffold-workspace-app.ts +12 -5
  101. package/src/actions/start-workspace-app-creation.ts +8 -2
  102. package/src/actions/view-screen.ts +13 -1
  103. package/src/components/app-icon.spec.tsx +34 -0
  104. package/src/components/app-icon.tsx +1 -1
  105. package/src/components/app-list-row.tsx +3 -2
  106. package/src/components/connected-app-card.tsx +3 -1
  107. package/src/components/create-app-popover.spec.tsx +26 -2
  108. package/src/components/create-app-popover.tsx +10 -0
  109. package/src/components/dispatch-control-plane.spec.tsx +9 -1
  110. package/src/components/dispatch-control-plane.tsx +8 -2
  111. package/src/components/layout/Layout.spec.tsx +12 -0
  112. package/src/components/layout/Layout.tsx +84 -13
  113. package/src/components/layout/workspace-apps-rail.tsx +2 -1
  114. package/src/components/other-apps-section.tsx +8 -1
  115. package/src/components/workspace-template-card.spec.tsx +1 -1
  116. package/src/components/workspace-template-card.tsx +9 -16
  117. package/src/config.ts +2 -0
  118. package/src/hooks/use-navigation-state.ts +12 -0
  119. package/src/lib/embed-session-recovery.spec.ts +63 -0
  120. package/src/lib/embed-session-recovery.ts +26 -0
  121. package/src/lib/other-apps.spec.ts +26 -0
  122. package/src/lib/other-apps.ts +5 -0
  123. package/src/lib/workspace-apps.spec.ts +24 -1
  124. package/src/lib/workspace-apps.test.ts +20 -0
  125. package/src/lib/workspace-apps.ts +25 -0
  126. package/src/routes/pages/apps.$appId.tsx +10 -11
  127. package/src/routes/pages/apps.tsx +5 -2
  128. package/src/routes/pages/chat.spec.tsx +10 -0
  129. package/src/routes/pages/chat.tsx +8 -0
  130. package/src/routes/pages/metrics.tsx +452 -102
  131. package/src/routes/pages/settings.tsx +13 -1
  132. package/src/server/lib/usage-metrics-store.spec.ts +117 -0
  133. package/src/server/lib/usage-metrics-store.ts +249 -30
  134. package/src/server/plugins/agent-chat.spec.ts +4 -0
  135. package/src/server/plugins/agent-chat.ts +2 -0
  136. package/src/server/plugins/auth.spec.ts +45 -0
  137. package/src/server/plugins/auth.ts +1 -0
  138. package/src/server/plugins/integrations.ts +1 -0
  139. package/src/styles/dispatch.css +9 -0
@@ -4,6 +4,7 @@ declare const _default: import("@agent-native/core").ActionDefinition<Record<str
4
4
  description: string;
5
5
  url: string;
6
6
  color: string;
7
+ homeUrl?: string | undefined;
7
8
  source: string;
8
9
  resourceId: string | undefined;
9
10
  path: string | undefined;
@@ -11,7 +11,9 @@ export default defineAction({
11
11
  run: async () => {
12
12
  const { hiddenAgentIds = [] } = await import("../server/index.js").then((m) => m.getDispatchConfig());
13
13
  const discovered = await discoverAgents("dispatch");
14
- const builtinIds = new Set(getBuiltinAgents("dispatch").map((agent) => agent.id));
14
+ const builtins = getBuiltinAgents("dispatch");
15
+ const builtinIds = new Set(builtins.map((agent) => agent.id));
16
+ const builtinHomeUrls = new Map(builtins.map((agent) => [agent.id, agent.url]));
15
17
  const ownerEmail = getRequestUserEmail();
16
18
  if (!ownerEmail)
17
19
  throw new Error("no authenticated user");
@@ -53,8 +55,10 @@ export default defineAction({
53
55
  const connected = discovered.map((agent) => {
54
56
  const custom = customById.get(agent.id);
55
57
  const isBuiltin = builtinIds.has(agent.id);
58
+ const homeUrl = isBuiltin ? builtinHomeUrls.get(agent.id) : undefined;
56
59
  return {
57
60
  ...agent,
61
+ ...(homeUrl ? { homeUrl } : {}),
58
62
  source: isBuiltin ? "builtin" : custom ? "custom" : "workspace",
59
63
  resourceId: custom?.resourceId,
60
64
  path: custom?.path,
@@ -1 +1 @@
1
- {"version":3,"file":"list-connected-agents.js","sourceRoot":"","sources":["../../src/actions/list-connected-agents.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport {\n REMOTE_AGENT_RESOURCE_PREFIXES,\n parseRemoteAgentManifest,\n} from \"@agent-native/core/resources/metadata\";\nimport {\n resourceGet,\n resourceListAccessible,\n SHARED_OWNER,\n} from \"@agent-native/core/resources/store\";\nimport { getRequestUserEmail } from \"@agent-native/core/server\";\nimport {\n discoverAgents,\n getBuiltinAgents,\n normalizeAgentId,\n shouldIncludeRemoteAgentManifest,\n} from \"@agent-native/core/server/agent-discovery\";\nimport { z } from \"zod\";\n\nexport default defineAction({\n description:\n \"List agents available to dispatch for A2A delegation, including built-in apps and connected remote agents.\",\n schema: z.object({}),\n http: { method: \"GET\" },\n run: async () => {\n const { hiddenAgentIds = [] } = await import(\"../server/index.js\").then(\n (m) => m.getDispatchConfig(),\n );\n const discovered = await discoverAgents(\"dispatch\");\n const builtinIds = new Set(\n getBuiltinAgents(\"dispatch\").map((agent) => agent.id),\n );\n const ownerEmail = getRequestUserEmail();\n if (!ownerEmail) throw new Error(\"no authenticated user\");\n const resources: Array<{ id: string; path: string; owner: string }> = [];\n for (const prefix of [...REMOTE_AGENT_RESOURCE_PREFIXES].reverse()) {\n resources.push(...(await resourceListAccessible(ownerEmail, prefix)));\n }\n const customById = new Map<\n string,\n {\n resourceId: string;\n path: string;\n scope: \"shared\" | \"personal\";\n name: string;\n description: string;\n url: string;\n color: string;\n }\n >();\n\n // Only treat a resource as a \"custom\" agent if its id is not a builtin.\n // Built-in agents may also be seeded as shared resources so the agent-chat\n // plugin can overlay them — those should still be reported as builtin.\n for (const resource of resources) {\n if (!resource.path.endsWith(\".json\")) continue;\n const full = await resourceGet(resource.id);\n if (!full) continue;\n const manifest = parseRemoteAgentManifest(full.content, resource.path);\n if (!manifest) continue;\n if (!shouldIncludeRemoteAgentManifest(manifest, \"dispatch\")) continue;\n // discoverAgents keys agents by the normalized id (image/images/asset\n // all collapse to assets). Keying this map by the raw manifest id makes\n // the id lookups below miss, so the same agent lands in the list twice.\n const manifestId = normalizeAgentId(manifest.id);\n if (builtinIds.has(manifestId)) continue;\n customById.set(manifestId, {\n resourceId: resource.id,\n path: resource.path,\n scope: resource.owner === SHARED_OWNER ? \"shared\" : \"personal\",\n name: manifest.name,\n description: manifest.description || \"\",\n url: manifest.url,\n color: manifest.color || \"#6B7280\",\n });\n }\n\n const connected = discovered.map((agent) => {\n const custom = customById.get(agent.id);\n const isBuiltin = builtinIds.has(agent.id);\n return {\n ...agent,\n source: isBuiltin ? \"builtin\" : custom ? \"custom\" : \"workspace\",\n resourceId: custom?.resourceId,\n path: custom?.path,\n scope: custom?.scope,\n };\n });\n\n const discoveredIds = new Set(connected.map((agent) => agent.id));\n for (const [id, custom] of customById) {\n if (discoveredIds.has(id)) continue;\n connected.push({\n id,\n name: custom.name,\n description: custom.description,\n url: custom.url,\n color: custom.color,\n source: \"custom\",\n resourceId: custom.resourceId,\n path: custom.path,\n scope: custom.scope,\n });\n }\n\n return connected.filter((a) => !hiddenAgentIds.includes(a.id));\n },\n});\n"]}
1
+ {"version":3,"file":"list-connected-agents.js","sourceRoot":"","sources":["../../src/actions/list-connected-agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,8BAA8B,EAC9B,wBAAwB,GACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,WAAW,EACX,sBAAsB,EACtB,YAAY,GACb,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,gCAAgC,GACjC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,4GAA4G;IAC9G,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;IACpB,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;IACvB,GAAG,EAAE,KAAK,IAAI,EAAE;QACd,MAAM,EAAE,cAAc,GAAG,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CACrE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAC7B,CAAC;QACF,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAC/C,CAAC;QACF,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;QACzC,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAuD,EAAE,CAAC;QACzE,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,8BAA8B,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YACnE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,sBAAsB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,GAAG,EAWvB,CAAC;QAEJ,wEAAwE;QACxE,2EAA2E;QAC3E,uEAAuE;QACvE,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;YAC/C,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YACvE,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACxB,IAAI,CAAC,gCAAgC,CAAC,QAAQ,EAAE,UAAU,CAAC;gBAAE,SAAS;YACtE,sEAAsE;YACtE,wEAAwE;YACxE,wEAAwE;YACxE,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACjD,IAAI,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC;gBAAE,SAAS;YACzC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE;gBACzB,UAAU,EAAE,QAAQ,CAAC,EAAE;gBACvB,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU;gBAC9D,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,EAAE;gBACvC,GAAG,EAAE,QAAQ,CAAC,GAAG;gBACjB,KAAK,EAAE,QAAQ,CAAC,KAAK,IAAI,SAAS;aACnC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACzC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACxC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACtE,OAAO;gBACL,GAAG,KAAK;gBACR,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/B,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW;gBAC/D,UAAU,EAAE,MAAM,EAAE,UAAU;gBAC9B,IAAI,EAAE,MAAM,EAAE,IAAI;gBAClB,KAAK,EAAE,MAAM,EAAE,KAAK;aACrB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAClE,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YACtC,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,SAAS;YACpC,SAAS,CAAC,IAAI,CAAC;gBACb,EAAE;gBACF,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM,EAAE,QAAQ;gBAChB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport {\n REMOTE_AGENT_RESOURCE_PREFIXES,\n parseRemoteAgentManifest,\n} from \"@agent-native/core/resources/metadata\";\nimport {\n resourceGet,\n resourceListAccessible,\n SHARED_OWNER,\n} from \"@agent-native/core/resources/store\";\nimport { getRequestUserEmail } from \"@agent-native/core/server\";\nimport {\n discoverAgents,\n getBuiltinAgents,\n normalizeAgentId,\n shouldIncludeRemoteAgentManifest,\n} from \"@agent-native/core/server/agent-discovery\";\nimport { z } from \"zod\";\n\nexport default defineAction({\n description:\n \"List agents available to dispatch for A2A delegation, including built-in apps and connected remote agents.\",\n schema: z.object({}),\n http: { method: \"GET\" },\n run: async () => {\n const { hiddenAgentIds = [] } = await import(\"../server/index.js\").then(\n (m) => m.getDispatchConfig(),\n );\n const discovered = await discoverAgents(\"dispatch\");\n const builtins = getBuiltinAgents(\"dispatch\");\n const builtinIds = new Set(builtins.map((agent) => agent.id));\n const builtinHomeUrls = new Map(\n builtins.map((agent) => [agent.id, agent.url]),\n );\n const ownerEmail = getRequestUserEmail();\n if (!ownerEmail) throw new Error(\"no authenticated user\");\n const resources: Array<{ id: string; path: string; owner: string }> = [];\n for (const prefix of [...REMOTE_AGENT_RESOURCE_PREFIXES].reverse()) {\n resources.push(...(await resourceListAccessible(ownerEmail, prefix)));\n }\n const customById = new Map<\n string,\n {\n resourceId: string;\n path: string;\n scope: \"shared\" | \"personal\";\n name: string;\n description: string;\n url: string;\n color: string;\n }\n >();\n\n // Only treat a resource as a \"custom\" agent if its id is not a builtin.\n // Built-in agents may also be seeded as shared resources so the agent-chat\n // plugin can overlay them — those should still be reported as builtin.\n for (const resource of resources) {\n if (!resource.path.endsWith(\".json\")) continue;\n const full = await resourceGet(resource.id);\n if (!full) continue;\n const manifest = parseRemoteAgentManifest(full.content, resource.path);\n if (!manifest) continue;\n if (!shouldIncludeRemoteAgentManifest(manifest, \"dispatch\")) continue;\n // discoverAgents keys agents by the normalized id (image/images/asset\n // all collapse to assets). Keying this map by the raw manifest id makes\n // the id lookups below miss, so the same agent lands in the list twice.\n const manifestId = normalizeAgentId(manifest.id);\n if (builtinIds.has(manifestId)) continue;\n customById.set(manifestId, {\n resourceId: resource.id,\n path: resource.path,\n scope: resource.owner === SHARED_OWNER ? \"shared\" : \"personal\",\n name: manifest.name,\n description: manifest.description || \"\",\n url: manifest.url,\n color: manifest.color || \"#6B7280\",\n });\n }\n\n const connected = discovered.map((agent) => {\n const custom = customById.get(agent.id);\n const isBuiltin = builtinIds.has(agent.id);\n const homeUrl = isBuiltin ? builtinHomeUrls.get(agent.id) : undefined;\n return {\n ...agent,\n ...(homeUrl ? { homeUrl } : {}),\n source: isBuiltin ? \"builtin\" : custom ? \"custom\" : \"workspace\",\n resourceId: custom?.resourceId,\n path: custom?.path,\n scope: custom?.scope,\n };\n });\n\n const discoveredIds = new Set(connected.map((agent) => agent.id));\n for (const [id, custom] of customById) {\n if (discoveredIds.has(id)) continue;\n connected.push({\n id,\n name: custom.name,\n description: custom.description,\n url: custom.url,\n color: custom.color,\n source: \"custom\",\n resourceId: custom.resourceId,\n path: custom.path,\n scope: custom.scope,\n });\n }\n\n return connected.filter((a) => !hiddenAgentIds.includes(a.id));\n },\n});\n"]}
@@ -1,5 +1,7 @@
1
1
  declare const _default: import("@agent-native/core").ActionDefinition<{
2
2
  sinceDays?: unknown;
3
+ scope?: "me" | "workspace" | undefined;
4
+ userEmail?: string | undefined;
3
5
  }, import("../server/lib/usage-metrics-store.js").DispatchUsageMetrics>;
4
6
  export default _default;
5
7
  //# sourceMappingURL=list-dispatch-usage-metrics.d.ts.map
@@ -2,7 +2,7 @@ import { defineAction } from "@agent-native/core";
2
2
  import { z } from "zod";
3
3
  import { listDispatchUsageMetrics } from "../server/lib/usage-metrics-store.js";
4
4
  export default defineAction({
5
- description: "Get workspace-level LLM usage, spend or Builder.io credit spend, users, app access, and recent activity metrics for Dispatch admins.",
5
+ description: "Get personal or workspace LLM usage, spend or Builder.io credit spend, app attribution, prompt previews, and recent activity metrics for Dispatch.",
6
6
  schema: z.object({
7
7
  sinceDays: z.coerce
8
8
  .number()
@@ -11,6 +11,16 @@ export default defineAction({
11
11
  .max(365)
12
12
  .default(30)
13
13
  .describe("Lookback window in days. Defaults to 30."),
14
+ scope: z
15
+ .enum(["me", "workspace"])
16
+ .default("workspace")
17
+ .describe("Whether to inspect your account or the whole workspace."),
18
+ userEmail: z
19
+ .string()
20
+ .trim()
21
+ .min(1)
22
+ .optional()
23
+ .describe("Optional workspace member email to filter all usage to."),
14
24
  }),
15
25
  http: { method: "GET" },
16
26
  run: async (args) => listDispatchUsageMetrics(args),
@@ -1 +1 @@
1
- {"version":3,"file":"list-dispatch-usage-metrics.js","sourceRoot":"","sources":["../../src/actions/list-dispatch-usage-metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAEhF,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,sIAAsI;IACxI,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,SAAS,EAAE,CAAC,CAAC,MAAM;aAChB,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,GAAG,CAAC;aACR,OAAO,CAAC,EAAE,CAAC;aACX,QAAQ,CAAC,0CAA0C,CAAC;KACxD,CAAC;IACF,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;IACvB,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC;CACpD,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\n\nimport { listDispatchUsageMetrics } from \"../server/lib/usage-metrics-store.js\";\n\nexport default defineAction({\n description:\n \"Get workspace-level LLM usage, spend or Builder.io credit spend, users, app access, and recent activity metrics for Dispatch admins.\",\n schema: z.object({\n sinceDays: z.coerce\n .number()\n .int()\n .min(1)\n .max(365)\n .default(30)\n .describe(\"Lookback window in days. Defaults to 30.\"),\n }),\n http: { method: \"GET\" },\n run: async (args) => listDispatchUsageMetrics(args),\n});\n"]}
1
+ {"version":3,"file":"list-dispatch-usage-metrics.js","sourceRoot":"","sources":["../../src/actions/list-dispatch-usage-metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAEhF,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,oJAAoJ;IACtJ,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,SAAS,EAAE,CAAC,CAAC,MAAM;aAChB,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,GAAG,CAAC;aACR,OAAO,CAAC,EAAE,CAAC;aACX,QAAQ,CAAC,0CAA0C,CAAC;QACvD,KAAK,EAAE,CAAC;aACL,IAAI,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;aACzB,OAAO,CAAC,WAAW,CAAC;aACpB,QAAQ,CAAC,yDAAyD,CAAC;QACtE,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,yDAAyD,CAAC;KACvE,CAAC;IACF,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;IACvB,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC;CACpD,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\n\nimport { listDispatchUsageMetrics } from \"../server/lib/usage-metrics-store.js\";\n\nexport default defineAction({\n description:\n \"Get personal or workspace LLM usage, spend or Builder.io credit spend, app attribution, prompt previews, and recent activity metrics for Dispatch.\",\n schema: z.object({\n sinceDays: z.coerce\n .number()\n .int()\n .min(1)\n .max(365)\n .default(30)\n .describe(\"Lookback window in days. Defaults to 30.\"),\n scope: z\n .enum([\"me\", \"workspace\"])\n .default(\"workspace\")\n .describe(\"Whether to inspect your account or the whole workspace.\"),\n userEmail: z\n .string()\n .trim()\n .min(1)\n .optional()\n .describe(\"Optional workspace member email to filter all usage to.\"),\n }),\n http: { method: \"GET\" },\n run: async (args) => listDispatchUsageMetrics(args),\n});\n"]}
@@ -49,7 +49,7 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
49
49
  }, {
50
50
  id?: undefined;
51
51
  deleted?: undefined;
52
- provider?: undefined;
52
+ message?: undefined;
53
53
  providers: {
54
54
  id: string;
55
55
  label: string;
@@ -60,45 +60,45 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
60
60
  updatedAt: number;
61
61
  }[];
62
62
  count: number;
63
+ provider?: undefined;
63
64
  found?: undefined;
64
65
  registered?: undefined;
65
66
  label?: undefined;
66
- message?: undefined;
67
67
  } | {
68
+ count?: undefined;
68
69
  id?: undefined;
69
70
  deleted?: undefined;
70
- count?: undefined;
71
+ message?: undefined;
71
72
  providers?: undefined;
72
73
  found: boolean;
73
74
  provider: import("node_modules/@agent-native/core/dist/provider-api").CustomProviderConfig;
74
75
  registered?: undefined;
75
76
  label?: undefined;
76
- message?: undefined;
77
77
  } | {
78
- deleted?: undefined;
79
78
  count?: undefined;
80
- provider?: undefined;
79
+ deleted?: undefined;
80
+ message?: undefined;
81
81
  providers?: undefined;
82
+ provider?: undefined;
82
83
  found: boolean;
83
84
  id: string;
84
85
  registered?: undefined;
85
86
  label?: undefined;
86
- message?: undefined;
87
87
  } | {
88
88
  count?: undefined;
89
- provider?: undefined;
89
+ message?: undefined;
90
90
  providers?: undefined;
91
+ provider?: undefined;
91
92
  found?: undefined;
92
93
  deleted: boolean;
93
94
  id: string;
94
95
  registered?: undefined;
95
96
  label?: undefined;
96
- message?: undefined;
97
97
  } | {
98
- deleted?: undefined;
99
98
  count?: undefined;
100
- provider?: undefined;
99
+ deleted?: undefined;
101
100
  providers?: undefined;
101
+ provider?: undefined;
102
102
  found?: undefined;
103
103
  registered: boolean;
104
104
  id: string;
@@ -1,5 +1,5 @@
1
1
  import { defineAction } from "@agent-native/core";
2
- import { getWorkspaceAppIdValidationError } from "@agent-native/core/shared";
2
+ import { getWorkspaceAppIdValidationError, normalizeWorkspaceAppId, } from "@agent-native/core/shared";
3
3
  import { z } from "zod";
4
4
  import { isLocalAppCreationRuntime, scaffoldWorkspaceAppFromTemplate, startWorkspaceAppCreation, } from "../server/lib/app-creation-store.js";
5
5
  import { getCuratedWorkspaceTemplate } from "../server/lib/curated-workspace-templates.js";
@@ -27,12 +27,13 @@ export default defineAction({
27
27
  appId: z
28
28
  .string()
29
29
  .max(64)
30
+ .transform(normalizeWorkspaceAppId)
30
31
  .optional()
31
32
  .nullable()
32
- .refine((appId) => !appId || !getWorkspaceAppIdValidationError(appId), {
33
+ .refine((appId) => appId == null || !getWorkspaceAppIdValidationError(appId), {
33
34
  message: "Use a non-reserved app id with lowercase letters, numbers, and hyphens.",
34
35
  })
35
- .describe("Optional target workspace app id. Defaults to <template>-remix so the source app remains independent."),
36
+ .describe("Optional target workspace app id or human-friendly name. Names are converted to lowercase, hyphenated ids. Defaults to <template>-remix so the source app remains independent."),
36
37
  description: z
37
38
  .string()
38
39
  .max(500)
@@ -1 +1 @@
1
- {"version":3,"file":"remix-workspace-template.js","sourceRoot":"","sources":["../../src/actions/remix-workspace-template.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { getWorkspaceAppIdValidationError } from \"@agent-native/core/shared\";\nimport { z } from \"zod\";\n\nimport {\n isLocalAppCreationRuntime,\n scaffoldWorkspaceAppFromTemplate,\n startWorkspaceAppCreation,\n} from \"../server/lib/app-creation-store.js\";\nimport { getCuratedWorkspaceTemplate } from \"../server/lib/curated-workspace-templates.js\";\nimport { recordAudit } from \"../server/lib/dispatch-store.js\";\n\nfunction buildRemixPrompt(input: {\n templateName: string;\n templateId: string;\n setupNote: string;\n description?: string | null;\n}): string {\n return [\n \"Create a private workspace app from a curated first-party template.\",\n `Source template: ${input.templateName} (${input.templateId}).`,\n \"Recreate the source template's product shape and capabilities as an independent workspace app.\",\n \"Never copy source-app data, records, user content, secrets, credentials, tokens, API keys, or private configuration.\",\n \"Use empty or synthetic seed data only, keep the new app private to the current workspace, and do not create a public demo.\",\n `Setup note: ${input.setupNote}`,\n input.description?.trim()\n ? `Requested customization: ${input.description.trim()}`\n : \"Keep the first version close to the curated source template while preserving independent ownership.\",\n ].join(\" \");\n}\n\nexport default defineAction({\n description:\n \"Create a private, independent app from one of Dispatch's curated first-party workspace templates. Valid templates are mail, calendar, analytics, slides, content, clips, brain, assets, forms, and design. The new app must not copy source-app data, secrets, credentials, or private configuration; local workspaces scaffold the template, while hosted workspaces start a Builder app-creation branch.\",\n schema: z.object({\n templateId: z\n .string()\n .min(1)\n .describe(\n \"Curated source template id: mail, calendar, analytics, slides, content, clips, brain, assets, forms, or design.\",\n ),\n appId: z\n .string()\n .max(64)\n .optional()\n .nullable()\n .refine((appId) => !appId || !getWorkspaceAppIdValidationError(appId), {\n message:\n \"Use a non-reserved app id with lowercase letters, numbers, and hyphens.\",\n })\n .describe(\n \"Optional target workspace app id. Defaults to <template>-remix so the source app remains independent.\",\n ),\n description: z\n .string()\n .max(500)\n .optional()\n .nullable()\n .describe(\"Optional customization or purpose for the private app.\"),\n }),\n run: async (input) => {\n const sourceTemplate = getCuratedWorkspaceTemplate(input.templateId);\n const appId = input.appId?.trim() || `${sourceTemplate.template}-remix`;\n\n const result = isLocalAppCreationRuntime()\n ? await scaffoldWorkspaceAppFromTemplate({\n template: sourceTemplate.template,\n appId,\n })\n : await startWorkspaceAppCreation({\n prompt: buildRemixPrompt({\n templateName: sourceTemplate.name,\n templateId: sourceTemplate.template,\n setupNote: sourceTemplate.setupNote,\n description: input.description,\n }),\n appId,\n description: input.description,\n template: sourceTemplate.template,\n });\n\n await recordAudit({\n action: \"workspace-app.remix-requested\",\n targetType: \"workspace-app\",\n targetId: appId,\n summary: `Requested private app from ${sourceTemplate.name}`,\n metadata: {\n sourceTemplate: sourceTemplate.template,\n mode:\n result && typeof result === \"object\" && \"mode\" in result\n ? result.mode\n : \"local\",\n descriptionConfigured: !!input.description?.trim(),\n },\n });\n\n return { ...result, sourceTemplate };\n },\n});\n"]}
1
+ {"version":3,"file":"remix-workspace-template.js","sourceRoot":"","sources":["../../src/actions/remix-workspace-template.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport {\n getWorkspaceAppIdValidationError,\n normalizeWorkspaceAppId,\n} from \"@agent-native/core/shared\";\nimport { z } from \"zod\";\n\nimport {\n isLocalAppCreationRuntime,\n scaffoldWorkspaceAppFromTemplate,\n startWorkspaceAppCreation,\n} from \"../server/lib/app-creation-store.js\";\nimport { getCuratedWorkspaceTemplate } from \"../server/lib/curated-workspace-templates.js\";\nimport { recordAudit } from \"../server/lib/dispatch-store.js\";\n\nfunction buildRemixPrompt(input: {\n templateName: string;\n templateId: string;\n setupNote: string;\n description?: string | null;\n}): string {\n return [\n \"Create a private workspace app from a curated first-party template.\",\n `Source template: ${input.templateName} (${input.templateId}).`,\n \"Recreate the source template's product shape and capabilities as an independent workspace app.\",\n \"Never copy source-app data, records, user content, secrets, credentials, tokens, API keys, or private configuration.\",\n \"Use empty or synthetic seed data only, keep the new app private to the current workspace, and do not create a public demo.\",\n `Setup note: ${input.setupNote}`,\n input.description?.trim()\n ? `Requested customization: ${input.description.trim()}`\n : \"Keep the first version close to the curated source template while preserving independent ownership.\",\n ].join(\" \");\n}\n\nexport default defineAction({\n description:\n \"Create a private, independent app from one of Dispatch's curated first-party workspace templates. Valid templates are mail, calendar, analytics, slides, content, clips, brain, assets, forms, and design. The new app must not copy source-app data, secrets, credentials, or private configuration; local workspaces scaffold the template, while hosted workspaces start a Builder app-creation branch.\",\n schema: z.object({\n templateId: z\n .string()\n .min(1)\n .describe(\n \"Curated source template id: mail, calendar, analytics, slides, content, clips, brain, assets, forms, or design.\",\n ),\n appId: z\n .string()\n .max(64)\n .transform(normalizeWorkspaceAppId)\n .optional()\n .nullable()\n .refine(\n (appId) => appId == null || !getWorkspaceAppIdValidationError(appId),\n {\n message:\n \"Use a non-reserved app id with lowercase letters, numbers, and hyphens.\",\n },\n )\n .describe(\n \"Optional target workspace app id or human-friendly name. Names are converted to lowercase, hyphenated ids. Defaults to <template>-remix so the source app remains independent.\",\n ),\n description: z\n .string()\n .max(500)\n .optional()\n .nullable()\n .describe(\"Optional customization or purpose for the private app.\"),\n }),\n run: async (input) => {\n const sourceTemplate = getCuratedWorkspaceTemplate(input.templateId);\n const appId = input.appId?.trim() || `${sourceTemplate.template}-remix`;\n\n const result = isLocalAppCreationRuntime()\n ? await scaffoldWorkspaceAppFromTemplate({\n template: sourceTemplate.template,\n appId,\n })\n : await startWorkspaceAppCreation({\n prompt: buildRemixPrompt({\n templateName: sourceTemplate.name,\n templateId: sourceTemplate.template,\n setupNote: sourceTemplate.setupNote,\n description: input.description,\n }),\n appId,\n description: input.description,\n template: sourceTemplate.template,\n });\n\n await recordAudit({\n action: \"workspace-app.remix-requested\",\n targetType: \"workspace-app\",\n targetId: appId,\n summary: `Requested private app from ${sourceTemplate.name}`,\n metadata: {\n sourceTemplate: sourceTemplate.template,\n mode:\n result && typeof result === \"object\" && \"mode\" in result\n ? result.mode\n : \"local\",\n descriptionConfigured: !!input.description?.trim(),\n },\n });\n\n return { ...result, sourceTemplate };\n },\n});\n"]}
@@ -1,5 +1,5 @@
1
1
  import { defineAction } from "@agent-native/core";
2
- import { getWorkspaceAppIdValidationError } from "@agent-native/core/shared";
2
+ import { getWorkspaceAppIdValidationError, normalizeWorkspaceAppId, } from "@agent-native/core/shared";
3
3
  import { z } from "zod";
4
4
  import { scaffoldWorkspaceAppFromTemplate } from "../server/lib/app-creation-store.js";
5
5
  function userFacingActionError(err) {
@@ -18,9 +18,10 @@ export default defineAction({
18
18
  appId: z
19
19
  .string()
20
20
  .max(64)
21
+ .transform(normalizeWorkspaceAppId)
21
22
  .optional()
22
23
  .nullable()
23
- .refine((appId) => !appId || !getWorkspaceAppIdValidationError(appId), {
24
+ .refine((appId) => appId == null || !getWorkspaceAppIdValidationError(appId), {
24
25
  message: "Use a non-reserved app id with lowercase letters, numbers, and hyphens.",
25
26
  })
26
27
  .describe("Optional override for the apps/<id>/ directory name; defaults to the template name"),
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold-workspace-app.js","sourceRoot":"","sources":["../../src/actions/scaffold-workspace-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gCAAgC,EAAE,MAAM,qCAAqC,CAAC;AAEvF,SAAS,qBAAqB,CAAC,GAAY;IACzC,MAAM,OAAO,GACX,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,OAAO,IAAI,mCAAmC,CACb,CAAC;IACpC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,uUAAuU;IACzU,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CACP,0FAA0F,CAC3F;QACH,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,CAAC,EAAE,CAAC;aACP,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,gCAAgC,CAAC,KAAK,CAAC,EAAE;YACrE,OAAO,EACL,yEAAyE;SAC5E,CAAC;aACD,QAAQ,CACP,oFAAoF,CACrF;KACJ,CAAC;IACF,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QACnB,IAAI,CAAC;YACH,OAAO,MAAM,gCAAgC,CAAC;gBAC5C,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI;aAC3B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { getWorkspaceAppIdValidationError } from \"@agent-native/core/shared\";\nimport { z } from \"zod\";\n\nimport { scaffoldWorkspaceAppFromTemplate } from \"../server/lib/app-creation-store.js\";\n\nfunction userFacingActionError(err: unknown): Error & { statusCode: number } {\n const message =\n err instanceof Error && err.message ? err.message : String(err);\n const error = new Error(\n message || \"Could not scaffold workspace app.\",\n ) as Error & { statusCode: number };\n error.statusCode = 400;\n return error;\n}\n\nexport default defineAction({\n description:\n \"Scaffold a first-party template (mail, calendar, slides, etc.) into apps/<id>/ in the current workspace. Local-dev only — runs `agent-native add-app` as a subprocess. The workspace gateway picks the new app up automatically and serves it at /<id>. For natural-language app creation, call start-workspace-app-creation instead.\",\n schema: z.object({\n template: z\n .string()\n .min(1)\n .describe(\n \"Template name (mail, calendar, slides, content, clips, analytics, forms, design, assets)\",\n ),\n appId: z\n .string()\n .max(64)\n .optional()\n .nullable()\n .refine((appId) => !appId || !getWorkspaceAppIdValidationError(appId), {\n message:\n \"Use a non-reserved app id with lowercase letters, numbers, and hyphens.\",\n })\n .describe(\n \"Optional override for the apps/<id>/ directory name; defaults to the template name\",\n ),\n }),\n run: async (input) => {\n try {\n return await scaffoldWorkspaceAppFromTemplate({\n template: input.template,\n appId: input.appId ?? null,\n });\n } catch (err) {\n throw userFacingActionError(err);\n }\n },\n});\n"]}
1
+ {"version":3,"file":"scaffold-workspace-app.js","sourceRoot":"","sources":["../../src/actions/scaffold-workspace-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,gCAAgC,EAChC,uBAAuB,GACxB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gCAAgC,EAAE,MAAM,qCAAqC,CAAC;AAEvF,SAAS,qBAAqB,CAAC,GAAY;IACzC,MAAM,OAAO,GACX,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,OAAO,IAAI,mCAAmC,CACb,CAAC;IACpC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,uUAAuU;IACzU,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CACP,0FAA0F,CAC3F;QACH,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,CAAC,EAAE,CAAC;aACP,SAAS,CAAC,uBAAuB,CAAC;aAClC,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,MAAM,CACL,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,gCAAgC,CAAC,KAAK,CAAC,EACpE;YACE,OAAO,EACL,yEAAyE;SAC5E,CACF;aACA,QAAQ,CACP,oFAAoF,CACrF;KACJ,CAAC;IACF,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QACnB,IAAI,CAAC;YACH,OAAO,MAAM,gCAAgC,CAAC;gBAC5C,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI;aAC3B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport {\n getWorkspaceAppIdValidationError,\n normalizeWorkspaceAppId,\n} from \"@agent-native/core/shared\";\nimport { z } from \"zod\";\n\nimport { scaffoldWorkspaceAppFromTemplate } from \"../server/lib/app-creation-store.js\";\n\nfunction userFacingActionError(err: unknown): Error & { statusCode: number } {\n const message =\n err instanceof Error && err.message ? err.message : String(err);\n const error = new Error(\n message || \"Could not scaffold workspace app.\",\n ) as Error & { statusCode: number };\n error.statusCode = 400;\n return error;\n}\n\nexport default defineAction({\n description:\n \"Scaffold a first-party template (mail, calendar, slides, etc.) into apps/<id>/ in the current workspace. Local-dev only — runs `agent-native add-app` as a subprocess. The workspace gateway picks the new app up automatically and serves it at /<id>. For natural-language app creation, call start-workspace-app-creation instead.\",\n schema: z.object({\n template: z\n .string()\n .min(1)\n .describe(\n \"Template name (mail, calendar, slides, content, clips, analytics, forms, design, assets)\",\n ),\n appId: z\n .string()\n .max(64)\n .transform(normalizeWorkspaceAppId)\n .optional()\n .nullable()\n .refine(\n (appId) => appId == null || !getWorkspaceAppIdValidationError(appId),\n {\n message:\n \"Use a non-reserved app id with lowercase letters, numbers, and hyphens.\",\n },\n )\n .describe(\n \"Optional override for the apps/<id>/ directory name; defaults to the template name\",\n ),\n }),\n run: async (input) => {\n try {\n return await scaffoldWorkspaceAppFromTemplate({\n template: input.template,\n appId: input.appId ?? null,\n });\n } catch (err) {\n throw userFacingActionError(err);\n }\n },\n});\n"]}
@@ -1,5 +1,5 @@
1
1
  import { defineAction } from "@agent-native/core";
2
- import { getWorkspaceAppIdValidationError } from "@agent-native/core/shared";
2
+ import { getWorkspaceAppIdValidationError, normalizeWorkspaceAppId, } from "@agent-native/core/shared";
3
3
  import { z } from "zod";
4
4
  import { startWorkspaceAppCreation } from "../server/lib/app-creation-store.js";
5
5
  export default defineAction({
@@ -9,12 +9,13 @@ export default defineAction({
9
9
  appId: z
10
10
  .string()
11
11
  .max(64)
12
+ .transform(normalizeWorkspaceAppId)
12
13
  .refine((appId) => !getWorkspaceAppIdValidationError(appId), {
13
14
  message: "Use a non-reserved app id with lowercase letters, numbers, and hyphens.",
14
15
  })
15
16
  .optional()
16
17
  .nullable()
17
- .describe("Desired workspace app id/path"),
18
+ .describe("Desired workspace app id/path or human-friendly name. Names are converted to lowercase, hyphenated ids."),
18
19
  template: z
19
20
  .string()
20
21
  .optional()
@@ -1 +1 @@
1
- {"version":3,"file":"start-workspace-app-creation.js","sourceRoot":"","sources":["../../src/actions/start-workspace-app-creation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAEhF,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,y9CAAy9C;IAC39C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QACrE,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,CAAC,EAAE,CAAC;aACP,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,gCAAgC,CAAC,KAAK,CAAC,EAAE;YAC3D,OAAO,EACL,yEAAyE;SAC5E,CAAC;aACD,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,+BAA+B,CAAC;QAC5C,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,wBAAwB,CAAC;QACrC,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CACP,6HAA6H,CAC9H;QACH,SAAS,EAAE,CAAC;aACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,+CAA+C,CAAC;QAC5D,WAAW,EAAE,CAAC;aACX,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,wEAAwE,CACzE;KACJ,CAAC;IACF,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC;CACrD,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { getWorkspaceAppIdValidationError } from \"@agent-native/core/shared\";\nimport { z } from \"zod\";\n\nimport { startWorkspaceAppCreation } from \"../server/lib/app-creation-store.js\";\n\nexport default defineAction({\n description:\n 'Start creating a new workspace app from Dispatch when the request truly needs its own app. For Claude Web, ChatGPT Web, or either host\\'s web Project, this action is the Builder handoff: call it after forming a bounded source brief and do not scaffold or edit files in the host sandbox. This handoff is autonomous once the brief exists: do not ask the user for non-blocking product or UX choices; choose recommended defaults and let Builder record assumptions while it implements. Callers should include a concise generated description by default; Dispatch generates one from the prompt when omitted. In local dev this returns a code-agent prompt; in production it reuses the connected Agent-Native workspace project or, for an organization owner/admin, provisions it through the Builder Projects API before starting the Builder Cloud Agent branch. If no project is configured, organization members must ask an owner/admin to configure it first. The result must be a separate workspace app under apps/<app-id>, not a new route or file in apps/chat. If chat is used as the source template, the finished app must be branded as the requested app and must not leave visible \"Chat\", \"Starter\", \"Blank app\", or \"New app\" UI behind. If the request needs Mail, Calendar, Analytics, Brain, Assets, or another first-party app, use the existing hosted/connected app via links or A2A; do not wrap or nest those apps inside the new app unless the user explicitly asks for a customized app from that template.',\n schema: z.object({\n prompt: z.string().min(1).describe(\"The user's app creation request\"),\n appId: z\n .string()\n .max(64)\n .refine((appId) => !getWorkspaceAppIdValidationError(appId), {\n message:\n \"Use a non-reserved app id with lowercase letters, numbers, and hyphens.\",\n })\n .optional()\n .nullable()\n .describe(\"Desired workspace app id/path\"),\n template: z\n .string()\n .optional()\n .nullable()\n .describe(\"Template to start from\"),\n description: z\n .string()\n .max(500)\n .optional()\n .nullable()\n .describe(\n \"Concise AI-generated description of the app based on the user's prompt. Dispatch saves this while the app is being created.\",\n ),\n secretIds: z\n .array(z.string())\n .max(100)\n .optional()\n .describe(\"Dispatch vault secret IDs to grant to the app\"),\n resourceIds: z\n .array(z.string())\n .max(100)\n .optional()\n .describe(\n \"Dispatch workspace resource IDs or knowledge packs to grant to the app\",\n ),\n }),\n run: async (args) => startWorkspaceAppCreation(args),\n});\n"]}
1
+ {"version":3,"file":"start-workspace-app-creation.js","sourceRoot":"","sources":["../../src/actions/start-workspace-app-creation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,gCAAgC,EAChC,uBAAuB,GACxB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAEhF,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,y9CAAy9C;IAC39C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QACrE,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,CAAC,EAAE,CAAC;aACP,SAAS,CAAC,uBAAuB,CAAC;aAClC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,gCAAgC,CAAC,KAAK,CAAC,EAAE;YAC3D,OAAO,EACL,yEAAyE;SAC5E,CAAC;aACD,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CACP,yGAAyG,CAC1G;QACH,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,wBAAwB,CAAC;QACrC,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CACP,6HAA6H,CAC9H;QACH,SAAS,EAAE,CAAC;aACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,+CAA+C,CAAC;QAC5D,WAAW,EAAE,CAAC;aACX,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,wEAAwE,CACzE;KACJ,CAAC;IACF,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC;CACrD,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport {\n getWorkspaceAppIdValidationError,\n normalizeWorkspaceAppId,\n} from \"@agent-native/core/shared\";\nimport { z } from \"zod\";\n\nimport { startWorkspaceAppCreation } from \"../server/lib/app-creation-store.js\";\n\nexport default defineAction({\n description:\n 'Start creating a new workspace app from Dispatch when the request truly needs its own app. For Claude Web, ChatGPT Web, or either host\\'s web Project, this action is the Builder handoff: call it after forming a bounded source brief and do not scaffold or edit files in the host sandbox. This handoff is autonomous once the brief exists: do not ask the user for non-blocking product or UX choices; choose recommended defaults and let Builder record assumptions while it implements. Callers should include a concise generated description by default; Dispatch generates one from the prompt when omitted. In local dev this returns a code-agent prompt; in production it reuses the connected Agent-Native workspace project or, for an organization owner/admin, provisions it through the Builder Projects API before starting the Builder Cloud Agent branch. If no project is configured, organization members must ask an owner/admin to configure it first. The result must be a separate workspace app under apps/<app-id>, not a new route or file in apps/chat. If chat is used as the source template, the finished app must be branded as the requested app and must not leave visible \"Chat\", \"Starter\", \"Blank app\", or \"New app\" UI behind. If the request needs Mail, Calendar, Analytics, Brain, Assets, or another first-party app, use the existing hosted/connected app via links or A2A; do not wrap or nest those apps inside the new app unless the user explicitly asks for a customized app from that template.',\n schema: z.object({\n prompt: z.string().min(1).describe(\"The user's app creation request\"),\n appId: z\n .string()\n .max(64)\n .transform(normalizeWorkspaceAppId)\n .refine((appId) => !getWorkspaceAppIdValidationError(appId), {\n message:\n \"Use a non-reserved app id with lowercase letters, numbers, and hyphens.\",\n })\n .optional()\n .nullable()\n .describe(\n \"Desired workspace app id/path or human-friendly name. Names are converted to lowercase, hyphenated ids.\",\n ),\n template: z\n .string()\n .optional()\n .nullable()\n .describe(\"Template to start from\"),\n description: z\n .string()\n .max(500)\n .optional()\n .nullable()\n .describe(\n \"Concise AI-generated description of the app based on the user's prompt. Dispatch saves this while the app is being created.\",\n ),\n secretIds: z\n .array(z.string())\n .max(100)\n .optional()\n .describe(\"Dispatch vault secret IDs to grant to the app\"),\n resourceIds: z\n .array(z.string())\n .max(100)\n .optional()\n .describe(\n \"Dispatch workspace resource IDs or knowledge packs to grant to the app\",\n ),\n }),\n run: async (args) => startWorkspaceAppCreation(args),\n});\n"]}
@@ -116,9 +116,19 @@ export default defineAction({
116
116
  }
117
117
  if (navigation?.view === "metrics") {
118
118
  try {
119
- const metrics = await listDispatchUsageMetrics({ sinceDays: 30 });
119
+ const usageScope = navigation.usageScope === "workspace" ? "workspace" : "me";
120
+ const usageUserEmail = typeof navigation.usageUserEmail === "string"
121
+ ? navigation.usageUserEmail
122
+ : undefined;
123
+ const metrics = await listDispatchUsageMetrics({
124
+ sinceDays: 30,
125
+ scope: usageScope,
126
+ userEmail: usageUserEmail,
127
+ });
120
128
  screen.usageMetrics = {
121
129
  billing: metrics.billing,
130
+ viewScope: metrics.viewScope,
131
+ selectedUserEmail: metrics.selectedUserEmail,
122
132
  totals: metrics.totals,
123
133
  byApp: metrics.byApp.slice(0, 8),
124
134
  byUser: metrics.byUser.slice(0, 8),
@@ -1 +1 @@
1
- {"version":3,"file":"view-screen.js","sourceRoot":"","sources":["../../src/actions/view-screen.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * See what the user is currently looking at on screen.\n *\n * Reads and returns the current navigation state from application state.\n *\n * Usage:\n * pnpm action view-screen\n */\n\nimport { defineAction } from \"@agent-native/core\";\nimport { readAppState } from \"@agent-native/core/application-state\";\nimport { z } from \"zod\";\n\nimport { listWorkspaceApps } from \"../server/lib/app-creation-store.js\";\nimport { listOverview } from \"../server/lib/dispatch-store.js\";\nimport {\n getAgentThreadDebug,\n listAgentRunFailures,\n listThreadDebugSources,\n searchAgentThreads,\n} from \"../server/lib/thread-debug-store.js\";\nimport { listDispatchUsageMetrics } from \"../server/lib/usage-metrics-store.js\";\nimport {\n listVaultOverview,\n listSecretOptions,\n listGrants,\n listRequests,\n getVaultAccessSettings,\n canManageVault,\n} from \"../server/lib/vault-store.js\";\nimport {\n listWorkspaceResourceOptions,\n listWorkspaceResourcesForApp,\n} from \"../server/lib/workspace-resources-store.js\";\n\nasync function runLocalDispatchAction(\n name: string,\n args: Record<string, unknown>,\n) {\n const modulePath = `./${name}.js`;\n const module = (await import(/* @vite-ignore */ modulePath)) as {\n default?: {\n run: (args: Record<string, unknown>) => unknown | Promise<unknown>;\n };\n };\n if (!module.default) throw new Error(`Dispatch action not found: ${name}`);\n return module.default.run(stripUndefined(args));\n}\n\nfunction stripUndefined(args: Record<string, unknown>) {\n return Object.fromEntries(\n Object.entries(args).filter(([, value]) => value !== undefined),\n );\n}\n\nfunction threadDebugLookbackHours(value: unknown): number {\n if (value === \"7d\") return 168;\n if (value === \"30d\") return 720;\n return 24;\n}\n\nfunction threadDebugFailureStatus(\n value: unknown,\n): \"all\" | \"errored\" | \"aborted\" | \"truncated\" {\n return value === \"errored\" || value === \"aborted\" || value === \"truncated\"\n ? value\n : \"all\";\n}\n\nexport default defineAction({\n description:\n \"See what the user is currently looking at in the dispatch UI, including navigation state and a compact operational summary.\",\n schema: z.object({}),\n http: false,\n run: async () => {\n const [navigation, overview, vaultOverview] = await Promise.all([\n readAppState(\"navigation\"),\n listOverview(),\n listVaultOverview(),\n ]);\n\n const screen: Record<string, unknown> = {\n counts: { ...overview.counts, ...vaultOverview },\n approvalPolicy: overview.settings,\n };\n if (navigation) screen.navigation = navigation;\n if (navigation?.view === \"chat\" || navigation?.view === \"browser-chat\") {\n screen.chatSurface = {\n view:\n navigation.view === \"browser-chat\"\n ? \"embedded browser chat\"\n : \"full-page Dispatch chat\",\n purpose:\n \"Create apps, manage workspace resources, route work to connected agents, and continue Dispatch conversations.\",\n };\n }\n if (navigation?.view === \"overview\") {\n screen.recentAudit = overview.recentAudit.slice(0, 5);\n screen.recentApprovals = overview.recentApprovals.slice(0, 5);\n }\n if (navigation?.view === \"destinations\") {\n screen.recentDestinations = overview.recentDestinations;\n }\n if (navigation?.view === \"agents\") {\n const [connectedAgents, mcpAccess] = await Promise.all([\n runLocalDispatchAction(\"list-connected-agents\", {}),\n runLocalDispatchAction(\"list-mcp-app-access\", {}),\n ]);\n screen.connectedAgents = connectedAgents;\n screen.mcpAppAccess = mcpAccess;\n }\n if (navigation?.view === \"operations\") {\n const nav = navigation as { operationsView?: string };\n screen.operatorConsole = {\n view: nav.operationsView === \"database\" ? \"database\" : \"monitoring\",\n monitoring:\n \"The shared observability dashboard provides traces, conversations, evaluations, experiments, and feedback.\",\n database:\n \"The shared database admin is available in Code mode for table browsing and SQL inspection.\",\n relatedTools: [\"thread-debug\", \"audit\", \"destinations\", \"automations\"],\n };\n }\n if (\n navigation?.view === \"overview\" ||\n navigation?.view === \"metrics\" ||\n navigation?.view === \"apps\" ||\n navigation?.view === \"new-app\"\n ) {\n const workspaceApps = await listWorkspaceApps({\n includeAgentCards: true,\n });\n screen.workspaceApps = workspaceApps;\n if (navigation?.view === \"apps\") {\n screen.workspaceAppResources = await Promise.all(\n workspaceApps\n .filter((app) => !app.isDispatch)\n .slice(0, 12)\n .map(async (app) => {\n const result = await listWorkspaceResourcesForApp(app.id);\n return {\n appId: app.id,\n appName: app.name,\n counts: result.counts,\n resources: result.resources.map((resource) => ({\n name: resource.name,\n path: resource.path,\n kind: resource.kind,\n source: resource.source,\n autoLoaded: resource.autoLoaded,\n })),\n };\n }),\n );\n }\n }\n if (navigation?.view === \"metrics\") {\n try {\n const metrics = await listDispatchUsageMetrics({ sinceDays: 30 });\n screen.usageMetrics = {\n billing: metrics.billing,\n totals: metrics.totals,\n byApp: metrics.byApp.slice(0, 8),\n byUser: metrics.byUser.slice(0, 8),\n appAccess: metrics.appAccess\n .filter((app) => !app.isDispatch)\n .slice(0, 8),\n };\n } catch (error) {\n screen.usageMetricsError =\n error instanceof Error ? error.message : String(error);\n }\n }\n if (navigation?.view === \"vault\" || navigation?.view === \"new-app\") {\n const isVaultAdmin = await canManageVault();\n const [secrets, grants, requests, access] = await Promise.all([\n listSecretOptions(),\n isVaultAdmin ? listGrants() : Promise.resolve([]),\n listRequests({ status: \"pending\" }),\n getVaultAccessSettings(),\n ]);\n screen.vaultAccessMode = access.mode;\n screen.vaultSecrets = secrets.map((s) => ({\n id: s.id,\n name: s.name,\n credentialKey: s.credentialKey,\n provider: s.provider,\n }));\n screen.vaultActiveGrants = grants\n .filter((g) => g.status === \"active\")\n .map((g) => ({ secretId: g.secretId, appId: g.appId }));\n screen.vaultPendingRequests = requests;\n }\n if (navigation?.view === \"workspace\" || navigation?.view === \"new-app\") {\n screen.workspaceResources = await listWorkspaceResourceOptions();\n screen.workspaceResourceEffectiveContext = {\n action: \"get-workspace-resource-effective-context\",\n description:\n \"Preview workspace -> organization/app -> personal precedence for a resource path and optional app/user. All-app resources are inherited at runtime; selected resources are app-specific exceptions.\",\n };\n screen.workspaceResourceImpactPreview = {\n action: \"preview-workspace-resource-change\",\n description:\n \"Preview All-app reach, overrides, and approval behavior before creating, updating, or deleting a workspace resource.\",\n };\n }\n if (navigation?.view === \"thread-debug\") {\n try {\n const nav = navigation as Record<string, any>;\n screen.threadDebugSources = await listThreadDebugSources();\n if (nav.threadDebugMode !== \"threads\") {\n screen.agentRunFailures = await listAgentRunFailures({\n sourceId: nav.sourceId ?? \"all\",\n ownerEmail: nav.ownerEmail,\n status: threadDebugFailureStatus(nav.failureStatus),\n lookbackHours: threadDebugLookbackHours(nav.range),\n limit: 10,\n });\n } else if (nav.query) {\n screen.threadDebugResults = await searchAgentThreads({\n sourceId: nav.sourceId,\n query: nav.query,\n ownerEmail: nav.ownerEmail,\n limit: 10,\n });\n }\n if (nav.threadId || nav.runId) {\n const detail = await getAgentThreadDebug({\n sourceId:\n nav.runId && nav.inspectSourceId\n ? nav.inspectSourceId\n : nav.sourceId,\n threadId: nav.runId ? undefined : nav.threadId,\n runId: nav.runId,\n ownerEmail: nav.ownerEmail,\n maxRuns: 5,\n maxEvents: 80,\n maxTraceSpans: 50,\n });\n screen.threadDebugSelection = {\n source: detail.source,\n thread: detail.thread,\n messageCount: detail.messages.length,\n runCount: detail.runs.length,\n debug: detail.debug,\n debugRuns: (detail as any).debugRuns?.slice(-5) ?? [],\n messages: detail.messages.slice(-6),\n runs: detail.runs\n .slice(0, 5)\n .map(({ events: _events, ...run }) => run),\n };\n }\n } catch (error) {\n screen.threadDebugError =\n error instanceof Error ? error.message : String(error);\n }\n }\n if (navigation?.view === \"dreams\") {\n try {\n const nav = navigation as Record<string, any>;\n const [sources, candidates, dreams, settings] = await Promise.all([\n listThreadDebugSources(),\n runLocalDispatchAction(\"list-dream-candidates\", {\n sourceId: nav.sourceId,\n ownerEmail: nav.ownerEmail,\n limit: 10,\n }),\n runLocalDispatchAction(\"list-dreams\", {\n status: nav.status,\n limit: 10,\n }),\n runLocalDispatchAction(\"get-dream-settings\", {}),\n ]);\n screen.dreamSources = sources;\n screen.dreamCandidates = candidates;\n screen.latestDreams = dreams;\n screen.dreamSettings = settings;\n\n const dreamId = nav.dreamId ?? nav.id;\n if (dreamId) {\n screen.dreamDetail = await runLocalDispatchAction(\"get-dream\", {\n id: dreamId,\n });\n }\n } catch (error) {\n screen.dreamsError =\n error instanceof Error ? error.message : String(error);\n }\n }\n\n if (Object.keys(screen).length === 0) {\n return \"No application state found. Is the app running?\";\n }\n return JSON.stringify(screen, null, 2);\n },\n});\n"]}
1
+ {"version":3,"file":"view-screen.js","sourceRoot":"","sources":["../../src/actions/view-screen.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * See what the user is currently looking at on screen.\n *\n * Reads and returns the current navigation state from application state.\n *\n * Usage:\n * pnpm action view-screen\n */\n\nimport { defineAction } from \"@agent-native/core\";\nimport { readAppState } from \"@agent-native/core/application-state\";\nimport { z } from \"zod\";\n\nimport { listWorkspaceApps } from \"../server/lib/app-creation-store.js\";\nimport { listOverview } from \"../server/lib/dispatch-store.js\";\nimport {\n getAgentThreadDebug,\n listAgentRunFailures,\n listThreadDebugSources,\n searchAgentThreads,\n} from \"../server/lib/thread-debug-store.js\";\nimport { listDispatchUsageMetrics } from \"../server/lib/usage-metrics-store.js\";\nimport {\n listVaultOverview,\n listSecretOptions,\n listGrants,\n listRequests,\n getVaultAccessSettings,\n canManageVault,\n} from \"../server/lib/vault-store.js\";\nimport {\n listWorkspaceResourceOptions,\n listWorkspaceResourcesForApp,\n} from \"../server/lib/workspace-resources-store.js\";\n\nasync function runLocalDispatchAction(\n name: string,\n args: Record<string, unknown>,\n) {\n const modulePath = `./${name}.js`;\n const module = (await import(/* @vite-ignore */ modulePath)) as {\n default?: {\n run: (args: Record<string, unknown>) => unknown | Promise<unknown>;\n };\n };\n if (!module.default) throw new Error(`Dispatch action not found: ${name}`);\n return module.default.run(stripUndefined(args));\n}\n\nfunction stripUndefined(args: Record<string, unknown>) {\n return Object.fromEntries(\n Object.entries(args).filter(([, value]) => value !== undefined),\n );\n}\n\nfunction threadDebugLookbackHours(value: unknown): number {\n if (value === \"7d\") return 168;\n if (value === \"30d\") return 720;\n return 24;\n}\n\nfunction threadDebugFailureStatus(\n value: unknown,\n): \"all\" | \"errored\" | \"aborted\" | \"truncated\" {\n return value === \"errored\" || value === \"aborted\" || value === \"truncated\"\n ? value\n : \"all\";\n}\n\nexport default defineAction({\n description:\n \"See what the user is currently looking at in the dispatch UI, including navigation state and a compact operational summary.\",\n schema: z.object({}),\n http: false,\n run: async () => {\n const [navigation, overview, vaultOverview] = await Promise.all([\n readAppState(\"navigation\"),\n listOverview(),\n listVaultOverview(),\n ]);\n\n const screen: Record<string, unknown> = {\n counts: { ...overview.counts, ...vaultOverview },\n approvalPolicy: overview.settings,\n };\n if (navigation) screen.navigation = navigation;\n if (navigation?.view === \"chat\" || navigation?.view === \"browser-chat\") {\n screen.chatSurface = {\n view:\n navigation.view === \"browser-chat\"\n ? \"embedded browser chat\"\n : \"full-page Dispatch chat\",\n purpose:\n \"Create apps, manage workspace resources, route work to connected agents, and continue Dispatch conversations.\",\n };\n }\n if (navigation?.view === \"overview\") {\n screen.recentAudit = overview.recentAudit.slice(0, 5);\n screen.recentApprovals = overview.recentApprovals.slice(0, 5);\n }\n if (navigation?.view === \"destinations\") {\n screen.recentDestinations = overview.recentDestinations;\n }\n if (navigation?.view === \"agents\") {\n const [connectedAgents, mcpAccess] = await Promise.all([\n runLocalDispatchAction(\"list-connected-agents\", {}),\n runLocalDispatchAction(\"list-mcp-app-access\", {}),\n ]);\n screen.connectedAgents = connectedAgents;\n screen.mcpAppAccess = mcpAccess;\n }\n if (navigation?.view === \"operations\") {\n const nav = navigation as { operationsView?: string };\n screen.operatorConsole = {\n view: nav.operationsView === \"database\" ? \"database\" : \"monitoring\",\n monitoring:\n \"The shared observability dashboard provides traces, conversations, evaluations, experiments, and feedback.\",\n database:\n \"The shared database admin is available in Code mode for table browsing and SQL inspection.\",\n relatedTools: [\"thread-debug\", \"audit\", \"destinations\", \"automations\"],\n };\n }\n if (\n navigation?.view === \"overview\" ||\n navigation?.view === \"metrics\" ||\n navigation?.view === \"apps\" ||\n navigation?.view === \"new-app\"\n ) {\n const workspaceApps = await listWorkspaceApps({\n includeAgentCards: true,\n });\n screen.workspaceApps = workspaceApps;\n if (navigation?.view === \"apps\") {\n screen.workspaceAppResources = await Promise.all(\n workspaceApps\n .filter((app) => !app.isDispatch)\n .slice(0, 12)\n .map(async (app) => {\n const result = await listWorkspaceResourcesForApp(app.id);\n return {\n appId: app.id,\n appName: app.name,\n counts: result.counts,\n resources: result.resources.map((resource) => ({\n name: resource.name,\n path: resource.path,\n kind: resource.kind,\n source: resource.source,\n autoLoaded: resource.autoLoaded,\n })),\n };\n }),\n );\n }\n }\n if (navigation?.view === \"metrics\") {\n try {\n const usageScope =\n navigation.usageScope === \"workspace\" ? \"workspace\" : \"me\";\n const usageUserEmail =\n typeof navigation.usageUserEmail === \"string\"\n ? navigation.usageUserEmail\n : undefined;\n const metrics = await listDispatchUsageMetrics({\n sinceDays: 30,\n scope: usageScope,\n userEmail: usageUserEmail,\n });\n screen.usageMetrics = {\n billing: metrics.billing,\n viewScope: metrics.viewScope,\n selectedUserEmail: metrics.selectedUserEmail,\n totals: metrics.totals,\n byApp: metrics.byApp.slice(0, 8),\n byUser: metrics.byUser.slice(0, 8),\n appAccess: metrics.appAccess\n .filter((app) => !app.isDispatch)\n .slice(0, 8),\n };\n } catch (error) {\n screen.usageMetricsError =\n error instanceof Error ? error.message : String(error);\n }\n }\n if (navigation?.view === \"vault\" || navigation?.view === \"new-app\") {\n const isVaultAdmin = await canManageVault();\n const [secrets, grants, requests, access] = await Promise.all([\n listSecretOptions(),\n isVaultAdmin ? listGrants() : Promise.resolve([]),\n listRequests({ status: \"pending\" }),\n getVaultAccessSettings(),\n ]);\n screen.vaultAccessMode = access.mode;\n screen.vaultSecrets = secrets.map((s) => ({\n id: s.id,\n name: s.name,\n credentialKey: s.credentialKey,\n provider: s.provider,\n }));\n screen.vaultActiveGrants = grants\n .filter((g) => g.status === \"active\")\n .map((g) => ({ secretId: g.secretId, appId: g.appId }));\n screen.vaultPendingRequests = requests;\n }\n if (navigation?.view === \"workspace\" || navigation?.view === \"new-app\") {\n screen.workspaceResources = await listWorkspaceResourceOptions();\n screen.workspaceResourceEffectiveContext = {\n action: \"get-workspace-resource-effective-context\",\n description:\n \"Preview workspace -> organization/app -> personal precedence for a resource path and optional app/user. All-app resources are inherited at runtime; selected resources are app-specific exceptions.\",\n };\n screen.workspaceResourceImpactPreview = {\n action: \"preview-workspace-resource-change\",\n description:\n \"Preview All-app reach, overrides, and approval behavior before creating, updating, or deleting a workspace resource.\",\n };\n }\n if (navigation?.view === \"thread-debug\") {\n try {\n const nav = navigation as Record<string, any>;\n screen.threadDebugSources = await listThreadDebugSources();\n if (nav.threadDebugMode !== \"threads\") {\n screen.agentRunFailures = await listAgentRunFailures({\n sourceId: nav.sourceId ?? \"all\",\n ownerEmail: nav.ownerEmail,\n status: threadDebugFailureStatus(nav.failureStatus),\n lookbackHours: threadDebugLookbackHours(nav.range),\n limit: 10,\n });\n } else if (nav.query) {\n screen.threadDebugResults = await searchAgentThreads({\n sourceId: nav.sourceId,\n query: nav.query,\n ownerEmail: nav.ownerEmail,\n limit: 10,\n });\n }\n if (nav.threadId || nav.runId) {\n const detail = await getAgentThreadDebug({\n sourceId:\n nav.runId && nav.inspectSourceId\n ? nav.inspectSourceId\n : nav.sourceId,\n threadId: nav.runId ? undefined : nav.threadId,\n runId: nav.runId,\n ownerEmail: nav.ownerEmail,\n maxRuns: 5,\n maxEvents: 80,\n maxTraceSpans: 50,\n });\n screen.threadDebugSelection = {\n source: detail.source,\n thread: detail.thread,\n messageCount: detail.messages.length,\n runCount: detail.runs.length,\n debug: detail.debug,\n debugRuns: (detail as any).debugRuns?.slice(-5) ?? [],\n messages: detail.messages.slice(-6),\n runs: detail.runs\n .slice(0, 5)\n .map(({ events: _events, ...run }) => run),\n };\n }\n } catch (error) {\n screen.threadDebugError =\n error instanceof Error ? error.message : String(error);\n }\n }\n if (navigation?.view === \"dreams\") {\n try {\n const nav = navigation as Record<string, any>;\n const [sources, candidates, dreams, settings] = await Promise.all([\n listThreadDebugSources(),\n runLocalDispatchAction(\"list-dream-candidates\", {\n sourceId: nav.sourceId,\n ownerEmail: nav.ownerEmail,\n limit: 10,\n }),\n runLocalDispatchAction(\"list-dreams\", {\n status: nav.status,\n limit: 10,\n }),\n runLocalDispatchAction(\"get-dream-settings\", {}),\n ]);\n screen.dreamSources = sources;\n screen.dreamCandidates = candidates;\n screen.latestDreams = dreams;\n screen.dreamSettings = settings;\n\n const dreamId = nav.dreamId ?? nav.id;\n if (dreamId) {\n screen.dreamDetail = await runLocalDispatchAction(\"get-dream\", {\n id: dreamId,\n });\n }\n } catch (error) {\n screen.dreamsError =\n error instanceof Error ? error.message : String(error);\n }\n }\n\n if (Object.keys(screen).length === 0) {\n return \"No application state found. Is the app running?\";\n }\n return JSON.stringify(screen, null, 2);\n },\n});\n"]}
@@ -40,7 +40,7 @@ const APP_VISUALS_BY_ID = {
40
40
  forms: { icon: IconStack2, colorRgb: "6 182 212" },
41
41
  macros: { icon: IconCode, colorRgb: "113 113 122" },
42
42
  mail: { icon: IconMail, colorRgb: "59 130 246" },
43
- plan: { icon: IconLayoutBoard, colorRgb: "82 82 91" },
43
+ plan: { icon: IconLayoutBoard, colorRgb: "47 111 237" },
44
44
  slides: { icon: IconPresentation, colorRgb: "236 72 153" },
45
45
  tasks: { icon: IconListCheck, colorRgb: "99 102 241" },
46
46
  };
@@ -1 +1 @@
1
- {"version":3,"file":"app-icon.js","sourceRoot":"","sources":["../../src/components/app-icon.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconBrain,\n IconBrandChrome,\n IconBrandJira,\n IconCalendar,\n IconChartBar,\n IconCode,\n IconFileText,\n IconFolder,\n IconLayoutBoard,\n IconListCheck,\n IconMail,\n IconMessageCircle,\n IconPhoto,\n IconPresentation,\n IconRoute,\n IconSettings,\n IconStack2,\n IconUsers,\n} from \"@tabler/icons-react\";\nimport type { CSSProperties } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\ntype AppIconComponent = typeof IconStack2;\n\nconst ICONS_BY_KEY: Record<string, AppIconComponent> = {\n barchart2: IconChartBar,\n brandjira: IconBrandJira,\n brain: IconBrain,\n calendardays: IconCalendar,\n calendarmonth: IconCalendar,\n chartbar: IconChartBar,\n code: IconCode,\n filetext: IconFileText,\n folder: IconFolder,\n galleryhorizontal: IconPresentation,\n globe: IconBrandChrome,\n layoutboard: IconLayoutBoard,\n listcheck: IconListCheck,\n mail: IconMail,\n messagecircle: IconMessageCircle,\n photo: IconPhoto,\n presentation: IconPresentation,\n route: IconRoute,\n settings: IconSettings,\n stack2: IconStack2,\n users: IconUsers,\n};\n\n/** Keep the Dispatch rail visually identical to the desktop app for first-party apps. */\nconst APP_VISUALS_BY_ID: Record<\n string,\n { icon: AppIconComponent; colorRgb: string }\n> = {\n analytics: { icon: IconChartBar, colorRgb: \"245 158 11\" },\n assets: { icon: IconPhoto, colorRgb: \"15 118 110\" },\n brain: { icon: IconBrain, colorRgb: \"139 92 246\" },\n calendar: { icon: IconCalendar, colorRgb: \"0 181 255\" },\n chat: { icon: IconMessageCircle, colorRgb: \"24 24 27\" },\n clips: { icon: IconStack2, colorRgb: \"14 165 233\" },\n content: { icon: IconFileText, colorRgb: \"16 185 129\" },\n crm: { icon: IconUsers, colorRgb: \"37 99 235\" },\n design: { icon: IconStack2, colorRgb: \"244 114 182\" },\n dispatch: { icon: IconRoute, colorRgb: \"20 184 166\" },\n factory: { icon: IconUsers, colorRgb: \"124 58 237\" },\n forms: { icon: IconStack2, colorRgb: \"6 182 212\" },\n macros: { icon: IconCode, colorRgb: \"113 113 122\" },\n mail: { icon: IconMail, colorRgb: \"59 130 246\" },\n plan: { icon: IconLayoutBoard, colorRgb: \"82 82 91\" },\n slides: { icon: IconPresentation, colorRgb: \"236 72 153\" },\n tasks: { icon: IconListCheck, colorRgb: \"99 102 241\" },\n};\n\nfunction appIconComponent(\n id: string,\n name: string,\n iconKey?: string,\n): AppIconComponent {\n const normalizedIconKey = iconKey?.trim().toLowerCase();\n if (normalizedIconKey && ICONS_BY_KEY[normalizedIconKey]) {\n return ICONS_BY_KEY[normalizedIconKey];\n }\n\n const standardVisuals = APP_VISUALS_BY_ID[id.trim().toLowerCase()];\n if (standardVisuals) return standardVisuals.icon;\n\n const haystack = `${id} ${name}`.toLowerCase();\n\n if (haystack.includes(\"mail\") || haystack.includes(\"email\")) {\n return IconMail;\n }\n if (\n haystack.includes(\"analytics\") ||\n haystack.includes(\"metric\") ||\n haystack.includes(\"indicator\") ||\n haystack.includes(\"gtm\")\n ) {\n return IconChartBar;\n }\n if (haystack.includes(\"coach\") || haystack.includes(\"agent\")) {\n return IconBrain;\n }\n return IconStack2;\n}\n\nfunction safeHexColor(color: string | undefined): string | null {\n const normalized = color?.trim();\n return normalized && /^#[0-9a-f]{6}$/i.test(normalized) ? normalized : null;\n}\n\nexport function AppIcon({\n id,\n name,\n icon,\n color,\n className,\n size = \"md\",\n monochrome = false,\n}: {\n id: string;\n name: string;\n icon?: string;\n color?: string;\n className?: string;\n size?: \"sm\" | \"md\";\n monochrome?: boolean;\n}) {\n const Icon = appIconComponent(id, name, icon);\n const customColor = safeHexColor(color);\n const standardColorRgb = APP_VISUALS_BY_ID[id.trim().toLowerCase()]?.colorRgb;\n const style = customColor\n ? ({\n \"--dispatch-app-icon-color\": customColor,\n backgroundColor:\n \"color-mix(in srgb, var(--dispatch-app-icon-color) 14%, transparent)\",\n color: \"var(--dispatch-app-icon-color)\",\n } as CSSProperties)\n : standardColorRgb\n ? ({\n \"--dispatch-app-icon-color-rgb\": standardColorRgb,\n backgroundColor: \"rgb(var(--dispatch-app-icon-color-rgb) / 0.14)\",\n color: \"rgb(var(--dispatch-app-icon-color-rgb))\",\n } as CSSProperties)\n : ({\n \"--dispatch-app-icon-hue\": `${appHue(id, name)} 72% 44%`,\n backgroundColor: \"hsl(var(--dispatch-app-icon-hue) / 0.14)\",\n color: \"hsl(var(--dispatch-app-icon-hue))\",\n } as CSSProperties);\n\n return (\n <span\n aria-hidden=\"true\"\n className={cn(\n \"flex shrink-0 items-center justify-center rounded-lg\",\n size === \"sm\" ? \"size-7\" : \"size-10\",\n monochrome && \"bg-transparent text-sidebar-foreground/70\",\n className,\n )}\n style={monochrome ? undefined : style}\n >\n <Icon size={size === \"sm\" ? 15 : 19} strokeWidth={1.8} />\n </span>\n );\n}\n\nfunction hashForApp(id: string, name: string): number {\n let hash = 0;\n for (const character of `${id}:${name}`) {\n hash = (hash * 31 + character.charCodeAt(0)) | 0;\n }\n return hash;\n}\n\nfunction appHue(id: string, name: string): number {\n return 20 + (Math.abs(hashForApp(id, name)) % 320);\n}\n"]}
1
+ {"version":3,"file":"app-icon.js","sourceRoot":"","sources":["../../src/components/app-icon.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconBrain,\n IconBrandChrome,\n IconBrandJira,\n IconCalendar,\n IconChartBar,\n IconCode,\n IconFileText,\n IconFolder,\n IconLayoutBoard,\n IconListCheck,\n IconMail,\n IconMessageCircle,\n IconPhoto,\n IconPresentation,\n IconRoute,\n IconSettings,\n IconStack2,\n IconUsers,\n} from \"@tabler/icons-react\";\nimport type { CSSProperties } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\ntype AppIconComponent = typeof IconStack2;\n\nconst ICONS_BY_KEY: Record<string, AppIconComponent> = {\n barchart2: IconChartBar,\n brandjira: IconBrandJira,\n brain: IconBrain,\n calendardays: IconCalendar,\n calendarmonth: IconCalendar,\n chartbar: IconChartBar,\n code: IconCode,\n filetext: IconFileText,\n folder: IconFolder,\n galleryhorizontal: IconPresentation,\n globe: IconBrandChrome,\n layoutboard: IconLayoutBoard,\n listcheck: IconListCheck,\n mail: IconMail,\n messagecircle: IconMessageCircle,\n photo: IconPhoto,\n presentation: IconPresentation,\n route: IconRoute,\n settings: IconSettings,\n stack2: IconStack2,\n users: IconUsers,\n};\n\n/** Keep the Dispatch rail visually identical to the desktop app for first-party apps. */\nconst APP_VISUALS_BY_ID: Record<\n string,\n { icon: AppIconComponent; colorRgb: string }\n> = {\n analytics: { icon: IconChartBar, colorRgb: \"245 158 11\" },\n assets: { icon: IconPhoto, colorRgb: \"15 118 110\" },\n brain: { icon: IconBrain, colorRgb: \"139 92 246\" },\n calendar: { icon: IconCalendar, colorRgb: \"0 181 255\" },\n chat: { icon: IconMessageCircle, colorRgb: \"24 24 27\" },\n clips: { icon: IconStack2, colorRgb: \"14 165 233\" },\n content: { icon: IconFileText, colorRgb: \"16 185 129\" },\n crm: { icon: IconUsers, colorRgb: \"37 99 235\" },\n design: { icon: IconStack2, colorRgb: \"244 114 182\" },\n dispatch: { icon: IconRoute, colorRgb: \"20 184 166\" },\n factory: { icon: IconUsers, colorRgb: \"124 58 237\" },\n forms: { icon: IconStack2, colorRgb: \"6 182 212\" },\n macros: { icon: IconCode, colorRgb: \"113 113 122\" },\n mail: { icon: IconMail, colorRgb: \"59 130 246\" },\n plan: { icon: IconLayoutBoard, colorRgb: \"47 111 237\" },\n slides: { icon: IconPresentation, colorRgb: \"236 72 153\" },\n tasks: { icon: IconListCheck, colorRgb: \"99 102 241\" },\n};\n\nfunction appIconComponent(\n id: string,\n name: string,\n iconKey?: string,\n): AppIconComponent {\n const normalizedIconKey = iconKey?.trim().toLowerCase();\n if (normalizedIconKey && ICONS_BY_KEY[normalizedIconKey]) {\n return ICONS_BY_KEY[normalizedIconKey];\n }\n\n const standardVisuals = APP_VISUALS_BY_ID[id.trim().toLowerCase()];\n if (standardVisuals) return standardVisuals.icon;\n\n const haystack = `${id} ${name}`.toLowerCase();\n\n if (haystack.includes(\"mail\") || haystack.includes(\"email\")) {\n return IconMail;\n }\n if (\n haystack.includes(\"analytics\") ||\n haystack.includes(\"metric\") ||\n haystack.includes(\"indicator\") ||\n haystack.includes(\"gtm\")\n ) {\n return IconChartBar;\n }\n if (haystack.includes(\"coach\") || haystack.includes(\"agent\")) {\n return IconBrain;\n }\n return IconStack2;\n}\n\nfunction safeHexColor(color: string | undefined): string | null {\n const normalized = color?.trim();\n return normalized && /^#[0-9a-f]{6}$/i.test(normalized) ? normalized : null;\n}\n\nexport function AppIcon({\n id,\n name,\n icon,\n color,\n className,\n size = \"md\",\n monochrome = false,\n}: {\n id: string;\n name: string;\n icon?: string;\n color?: string;\n className?: string;\n size?: \"sm\" | \"md\";\n monochrome?: boolean;\n}) {\n const Icon = appIconComponent(id, name, icon);\n const customColor = safeHexColor(color);\n const standardColorRgb = APP_VISUALS_BY_ID[id.trim().toLowerCase()]?.colorRgb;\n const style = customColor\n ? ({\n \"--dispatch-app-icon-color\": customColor,\n backgroundColor:\n \"color-mix(in srgb, var(--dispatch-app-icon-color) 14%, transparent)\",\n color: \"var(--dispatch-app-icon-color)\",\n } as CSSProperties)\n : standardColorRgb\n ? ({\n \"--dispatch-app-icon-color-rgb\": standardColorRgb,\n backgroundColor: \"rgb(var(--dispatch-app-icon-color-rgb) / 0.14)\",\n color: \"rgb(var(--dispatch-app-icon-color-rgb))\",\n } as CSSProperties)\n : ({\n \"--dispatch-app-icon-hue\": `${appHue(id, name)} 72% 44%`,\n backgroundColor: \"hsl(var(--dispatch-app-icon-hue) / 0.14)\",\n color: \"hsl(var(--dispatch-app-icon-hue))\",\n } as CSSProperties);\n\n return (\n <span\n aria-hidden=\"true\"\n className={cn(\n \"flex shrink-0 items-center justify-center rounded-lg\",\n size === \"sm\" ? \"size-7\" : \"size-10\",\n monochrome && \"bg-transparent text-sidebar-foreground/70\",\n className,\n )}\n style={monochrome ? undefined : style}\n >\n <Icon size={size === \"sm\" ? 15 : 19} strokeWidth={1.8} />\n </span>\n );\n}\n\nfunction hashForApp(id: string, name: string): number {\n let hash = 0;\n for (const character of `${id}:${name}`) {\n hash = (hash * 31 + character.charCodeAt(0)) | 0;\n }\n return hash;\n}\n\nfunction appHue(id: string, name: string): number {\n return 20 + (Math.abs(hashForApp(id, name)) % 320);\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { ReactNode } from "react";
2
2
  export declare const APP_LIST_GRID_CLASS = "mx-auto w-full max-w-[1000px] xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none xl:bg-transparent";
3
- export declare const APP_LIST_GRID_ROW_CLASS = "xl:rounded-2xl xl:border-0 xl:bg-card";
3
+ export declare const APP_LIST_GRID_ROW_CLASS = "xl:rounded-2xl xl:border xl:border-transparent xl:bg-card xl:transition-[background-color,border-color] xl:hover:border-border xl:focus-within:border-ring/50";
4
4
  export declare function AppList({ children, className, }: {
5
5
  children: ReactNode;
6
6
  className?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"app-list-row.d.ts","sourceRoot":"","sources":["../../src/components/app-list-row.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,eAAO,MAAM,mBAAmB,wHACuF,CAAC;AACxH,eAAO,MAAM,uBAAuB,0CAA0C,CAAC;AAE/E,wBAAgB,OAAO,CAAC,EACtB,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAMA;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAWA"}
1
+ {"version":3,"file":"app-list-row.d.ts","sourceRoot":"","sources":["../../src/components/app-list-row.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,eAAO,MAAM,mBAAmB,wHACuF,CAAC;AACxH,eAAO,MAAM,uBAAuB,kKAC6H,CAAC;AAElK,wBAAgB,OAAO,CAAC,EACtB,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAMA;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAWA"}
@@ -1,11 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cn } from "../lib/utils.js";
3
3
  export const APP_LIST_GRID_CLASS = "mx-auto w-full max-w-[1000px] xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none xl:bg-transparent";
4
- export const APP_LIST_GRID_ROW_CLASS = "xl:rounded-2xl xl:border-0 xl:bg-card";
4
+ export const APP_LIST_GRID_ROW_CLASS = "xl:rounded-2xl xl:border xl:border-transparent xl:bg-card xl:transition-[background-color,border-color] xl:hover:border-border xl:focus-within:border-ring/50";
5
5
  export function AppList({ children, className, }) {
6
6
  return (_jsx("div", { className: cn("overflow-hidden rounded-2xl bg-card", className), children: children }));
7
7
  }
8
8
  export function AppListRow({ children, className, }) {
9
- return (_jsx("div", { className: cn("group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color] hover:bg-muted/30 focus-within:bg-muted/30", className), children: children }));
9
+ return (_jsx("div", { className: cn("group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color,border-color] hover:bg-muted/30 focus-within:bg-muted/30", className), children: children }));
10
10
  }
11
11
  //# sourceMappingURL=app-list-row.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-list-row.js","sourceRoot":"","sources":["../../src/components/app-list-row.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC,MAAM,CAAC,MAAM,mBAAmB,GAC9B,qHAAqH,CAAC;AACxH,MAAM,CAAC,MAAM,uBAAuB,GAAG,uCAAuC,CAAC;AAE/E,MAAM,UAAU,OAAO,CAAC,EACtB,QAAQ,EACR,SAAS,GAIV;IACC,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,qCAAqC,EAAE,SAAS,CAAC,YACjE,QAAQ,GACL,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,GAIV;IACC,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,qJAAqJ,EACrJ,SAAS,CACV,YAEA,QAAQ,GACL,CACP,CAAC;AACJ,CAAC","sourcesContent":["import type { ReactNode } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\nexport const APP_LIST_GRID_CLASS =\n \"mx-auto w-full max-w-[1000px] xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none xl:bg-transparent\";\nexport const APP_LIST_GRID_ROW_CLASS = \"xl:rounded-2xl xl:border-0 xl:bg-card\";\n\nexport function AppList({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn(\"overflow-hidden rounded-2xl bg-card\", className)}>\n {children}\n </div>\n );\n}\n\nexport function AppListRow({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={cn(\n \"group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color] hover:bg-muted/30 focus-within:bg-muted/30\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"app-list-row.js","sourceRoot":"","sources":["../../src/components/app-list-row.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC,MAAM,CAAC,MAAM,mBAAmB,GAC9B,qHAAqH,CAAC;AACxH,MAAM,CAAC,MAAM,uBAAuB,GAClC,+JAA+J,CAAC;AAElK,MAAM,UAAU,OAAO,CAAC,EACtB,QAAQ,EACR,SAAS,GAIV;IACC,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,qCAAqC,EAAE,SAAS,CAAC,YACjE,QAAQ,GACL,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,GAIV;IACC,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,kKAAkK,EAClK,SAAS,CACV,YAEA,QAAQ,GACL,CACP,CAAC;AACJ,CAAC","sourcesContent":["import type { ReactNode } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\nexport const APP_LIST_GRID_CLASS =\n \"mx-auto w-full max-w-[1000px] xl:grid xl:grid-cols-2 xl:gap-3 xl:overflow-visible xl:rounded-none xl:bg-transparent\";\nexport const APP_LIST_GRID_ROW_CLASS =\n \"xl:rounded-2xl xl:border xl:border-transparent xl:bg-card xl:transition-[background-color,border-color] xl:hover:border-border xl:focus-within:border-ring/50\";\n\nexport function AppList({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn(\"overflow-hidden rounded-2xl bg-card\", className)}>\n {children}\n </div>\n );\n}\n\nexport function AppListRow({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={cn(\n \"group flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0 transition-[background-color,border-color] hover:bg-muted/30 focus-within:bg-muted/30\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"connected-app-card.d.ts","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAK7D,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GACV,EAAE;IACD,GAAG,EAAE,mBAAmB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAwBA"}
1
+ {"version":3,"file":"connected-app-card.d.ts","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAK7D,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GACV,EAAE;IACD,GAAG,EAAE,mBAAmB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDA0BA"}
@@ -4,7 +4,8 @@ import { AppIcon } from "./app-icon.js";
4
4
  import { AppListRow } from "./app-list-row.js";
5
5
  import { AppOpenActions } from "./app-open-actions.js";
6
6
  export function ConnectedAppCard({ app, className, }) {
7
- return (_jsxs(AppListRow, { className: className, children: [_jsx(AppIcon, { id: app.id, name: app.name, color: app.color, size: "sm" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: app.name }), _jsx("div", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: app.description || app.url })] }), _jsx(AppOpenActions, { name: app.name, href: withBuilderUtmTrackingParams(app.url, {
7
+ const launchUrl = app.homeUrl ?? app.url;
8
+ return (_jsxs(AppListRow, { className: className, children: [_jsx(AppIcon, { id: app.id, name: app.name, color: app.color, size: "sm" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: app.name }), _jsx("div", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: app.description || app.url })] }), _jsx(AppOpenActions, { name: app.name, href: withBuilderUtmTrackingParams(launchUrl, {
8
9
  campaign: "product",
9
10
  content: "dispatch_app",
10
11
  }), target: "_blank", rel: "noopener noreferrer", showNewTabOption: true })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"connected-app-card.js","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAG/F,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GAIV;IACC,OAAO,CACL,MAAC,UAAU,IAAC,SAAS,EAAE,SAAS,aAC9B,KAAC,OAAO,IAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAC,IAAI,GAAG,EACnE,eAAK,SAAS,EAAC,gBAAgB,aAC7B,cAAK,SAAS,EAAC,gDAAgD,YAC5D,GAAG,CAAC,IAAI,GACL,EACN,cAAK,SAAS,EAAC,+CAA+C,YAC3D,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,GAAG,GACvB,IACF,EACN,KAAC,cAAc,IACb,IAAI,EAAE,GAAG,CAAC,IAAI,EACd,IAAI,EAAE,4BAA4B,CAAC,GAAG,CAAC,GAAG,EAAE;oBAC1C,QAAQ,EAAE,SAAS;oBACnB,OAAO,EAAE,cAAc;iBACxB,CAAC,EACF,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,gBAAgB,SAChB,IACS,CACd,CAAC;AACJ,CAAC","sourcesContent":["import { withBuilderUtmTrackingParams } from \"@agent-native/core/shared/builder-link-tracking\";\n\nimport type { ConnectedAppSummary } from \"../lib/other-apps\";\nimport { AppIcon } from \"./app-icon\";\nimport { AppListRow } from \"./app-list-row\";\nimport { AppOpenActions } from \"./app-open-actions\";\n\nexport function ConnectedAppCard({\n app,\n className,\n}: {\n app: ConnectedAppSummary;\n className?: string;\n}) {\n return (\n <AppListRow className={className}>\n <AppIcon id={app.id} name={app.name} color={app.color} size=\"sm\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold text-foreground\">\n {app.name}\n </div>\n <div className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {app.description || app.url}\n </div>\n </div>\n <AppOpenActions\n name={app.name}\n href={withBuilderUtmTrackingParams(app.url, {\n campaign: \"product\",\n content: \"dispatch_app\",\n })}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n showNewTabOption\n />\n </AppListRow>\n );\n}\n"]}
1
+ {"version":3,"file":"connected-app-card.js","sourceRoot":"","sources":["../../src/components/connected-app-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAG/F,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GAIV;IACC,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC;IAEzC,OAAO,CACL,MAAC,UAAU,IAAC,SAAS,EAAE,SAAS,aAC9B,KAAC,OAAO,IAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAC,IAAI,GAAG,EACnE,eAAK,SAAS,EAAC,gBAAgB,aAC7B,cAAK,SAAS,EAAC,gDAAgD,YAC5D,GAAG,CAAC,IAAI,GACL,EACN,cAAK,SAAS,EAAC,+CAA+C,YAC3D,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,GAAG,GACvB,IACF,EACN,KAAC,cAAc,IACb,IAAI,EAAE,GAAG,CAAC,IAAI,EACd,IAAI,EAAE,4BAA4B,CAAC,SAAS,EAAE;oBAC5C,QAAQ,EAAE,SAAS;oBACnB,OAAO,EAAE,cAAc;iBACxB,CAAC,EACF,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,gBAAgB,SAChB,IACS,CACd,CAAC;AACJ,CAAC","sourcesContent":["import { withBuilderUtmTrackingParams } from \"@agent-native/core/shared/builder-link-tracking\";\n\nimport type { ConnectedAppSummary } from \"../lib/other-apps\";\nimport { AppIcon } from \"./app-icon\";\nimport { AppListRow } from \"./app-list-row\";\nimport { AppOpenActions } from \"./app-open-actions\";\n\nexport function ConnectedAppCard({\n app,\n className,\n}: {\n app: ConnectedAppSummary;\n className?: string;\n}) {\n const launchUrl = app.homeUrl ?? app.url;\n\n return (\n <AppListRow className={className}>\n <AppIcon id={app.id} name={app.name} color={app.color} size=\"sm\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold text-foreground\">\n {app.name}\n </div>\n <div className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {app.description || app.url}\n </div>\n </div>\n <AppOpenActions\n name={app.name}\n href={withBuilderUtmTrackingParams(launchUrl, {\n campaign: \"product\",\n content: \"dispatch_app\",\n })}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n showNewTabOption\n />\n </AppListRow>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"create-app-popover.d.ts","sourceRoot":"","sources":["../../src/components/create-app-popover.tsx"],"names":[],"mappings":"AA0BA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAyBrE,UAAU,qBAAqB;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CACpC;AAuCD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,SAAc,GACf,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDA4fA;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,KAAgB,GACjB,EAAE,qBAAqB,mDA0BvB"}
1
+ {"version":3,"file":"create-app-popover.d.ts","sourceRoot":"","sources":["../../src/components/create-app-popover.tsx"],"names":[],"mappings":"AA0BA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAyBrE,UAAU,qBAAqB;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CACpC;AAuCD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,SAAc,GACf,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAsgBA;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,KAAgB,GACjB,EAAE,qBAAqB,mDA0BvB"}