@agent-native/dispatch 0.6.0 → 0.7.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 (159) hide show
  1. package/README.md +1 -1
  2. package/dist/actions/create-pylon-ticket.d.ts +3 -0
  3. package/dist/actions/create-pylon-ticket.d.ts.map +1 -0
  4. package/dist/actions/create-pylon-ticket.js +94 -0
  5. package/dist/actions/create-pylon-ticket.js.map +1 -0
  6. package/dist/actions/create-vault-grant.js +1 -1
  7. package/dist/actions/create-vault-grant.js.map +1 -1
  8. package/dist/actions/create-vault-secret.d.ts.map +1 -1
  9. package/dist/actions/create-vault-secret.js +4 -3
  10. package/dist/actions/create-vault-secret.js.map +1 -1
  11. package/dist/actions/get-vault-access-settings.d.ts +3 -0
  12. package/dist/actions/get-vault-access-settings.d.ts.map +1 -0
  13. package/dist/actions/get-vault-access-settings.js +10 -0
  14. package/dist/actions/get-vault-access-settings.js.map +1 -0
  15. package/dist/actions/grant-vault-secrets-to-app.js +1 -1
  16. package/dist/actions/grant-vault-secrets-to-app.js.map +1 -1
  17. package/dist/actions/index.d.ts.map +1 -1
  18. package/dist/actions/index.js +8 -0
  19. package/dist/actions/index.js.map +1 -1
  20. package/dist/actions/list-integrations-catalog.js +1 -1
  21. package/dist/actions/list-integrations-catalog.js.map +1 -1
  22. package/dist/actions/list-vault-grants.js +1 -1
  23. package/dist/actions/list-vault-grants.js.map +1 -1
  24. package/dist/actions/list-workspace-apps.d.ts.map +1 -1
  25. package/dist/actions/list-workspace-apps.js +5 -1
  26. package/dist/actions/list-workspace-apps.js.map +1 -1
  27. package/dist/actions/set-vault-access-settings.d.ts +3 -0
  28. package/dist/actions/set-vault-access-settings.d.ts.map +1 -0
  29. package/dist/actions/set-vault-access-settings.js +13 -0
  30. package/dist/actions/set-vault-access-settings.js.map +1 -0
  31. package/dist/actions/start-workspace-app-creation.d.ts.map +1 -1
  32. package/dist/actions/start-workspace-app-creation.js +6 -0
  33. package/dist/actions/start-workspace-app-creation.js.map +1 -1
  34. package/dist/actions/sync-vault-to-app.js +1 -1
  35. package/dist/actions/sync-vault-to-app.js.map +1 -1
  36. package/dist/actions/update-workspace-app-metadata.d.ts +3 -0
  37. package/dist/actions/update-workspace-app-metadata.d.ts.map +1 -0
  38. package/dist/actions/update-workspace-app-metadata.js +30 -0
  39. package/dist/actions/update-workspace-app-metadata.js.map +1 -0
  40. package/dist/actions/view-screen.d.ts.map +1 -1
  41. package/dist/actions/view-screen.js +4 -2
  42. package/dist/actions/view-screen.js.map +1 -1
  43. package/dist/components/app-keys-popover.d.ts.map +1 -1
  44. package/dist/components/app-keys-popover.js +17 -5
  45. package/dist/components/app-keys-popover.js.map +1 -1
  46. package/dist/components/create-app-popover.d.ts.map +1 -1
  47. package/dist/components/create-app-popover.js +38 -14
  48. package/dist/components/create-app-popover.js.map +1 -1
  49. package/dist/components/dispatch-shell.d.ts +4 -4
  50. package/dist/components/dispatch-shell.d.ts.map +1 -1
  51. package/dist/components/dispatch-shell.js +6 -6
  52. package/dist/components/dispatch-shell.js.map +1 -1
  53. package/dist/components/layout/Layout.d.ts.map +1 -1
  54. package/dist/components/layout/Layout.js +10 -3
  55. package/dist/components/layout/Layout.js.map +1 -1
  56. package/dist/components/messaging-setup-panel.d.ts.map +1 -1
  57. package/dist/components/messaging-setup-panel.js +2 -2
  58. package/dist/components/messaging-setup-panel.js.map +1 -1
  59. package/dist/components/workspace-app-card.d.ts.map +1 -1
  60. package/dist/components/workspace-app-card.js +41 -2
  61. package/dist/components/workspace-app-card.js.map +1 -1
  62. package/dist/hooks/use-navigation-state.js +12 -5
  63. package/dist/hooks/use-navigation-state.js.map +1 -1
  64. package/dist/lib/catch-all-target.d.ts +2 -0
  65. package/dist/lib/catch-all-target.d.ts.map +1 -0
  66. package/dist/lib/catch-all-target.js +95 -0
  67. package/dist/lib/catch-all-target.js.map +1 -0
  68. package/dist/lib/workspace-apps.d.ts +9 -0
  69. package/dist/lib/workspace-apps.d.ts.map +1 -1
  70. package/dist/lib/workspace-apps.js.map +1 -1
  71. package/dist/routes/pages/$appId.d.ts +2 -24
  72. package/dist/routes/pages/$appId.d.ts.map +1 -1
  73. package/dist/routes/pages/$appId.js +42 -8
  74. package/dist/routes/pages/$appId.js.map +1 -1
  75. package/dist/routes/pages/approval.d.ts.map +1 -1
  76. package/dist/routes/pages/approval.js +2 -1
  77. package/dist/routes/pages/approval.js.map +1 -1
  78. package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
  79. package/dist/routes/pages/apps.$appId.js +2 -1
  80. package/dist/routes/pages/apps.$appId.js.map +1 -1
  81. package/dist/routes/pages/integrations.d.ts.map +1 -1
  82. package/dist/routes/pages/integrations.js +20 -15
  83. package/dist/routes/pages/integrations.js.map +1 -1
  84. package/dist/routes/pages/new-app.js +1 -1
  85. package/dist/routes/pages/new-app.js.map +1 -1
  86. package/dist/routes/pages/overview.d.ts.map +1 -1
  87. package/dist/routes/pages/overview.js +14 -1
  88. package/dist/routes/pages/overview.js.map +1 -1
  89. package/dist/routes/pages/vault.d.ts.map +1 -1
  90. package/dist/routes/pages/vault.js +25 -6
  91. package/dist/routes/pages/vault.js.map +1 -1
  92. package/dist/routes/pages/workspace.d.ts.map +1 -1
  93. package/dist/routes/pages/workspace.js +5 -3
  94. package/dist/routes/pages/workspace.js.map +1 -1
  95. package/dist/server/lib/app-creation-store.d.ts +13 -0
  96. package/dist/server/lib/app-creation-store.d.ts.map +1 -1
  97. package/dist/server/lib/app-creation-store.js +295 -9
  98. package/dist/server/lib/app-creation-store.js.map +1 -1
  99. package/dist/server/lib/env-config.d.ts.map +1 -1
  100. package/dist/server/lib/env-config.js +5 -0
  101. package/dist/server/lib/env-config.js.map +1 -1
  102. package/dist/server/lib/onboarding-steps.d.ts +12 -0
  103. package/dist/server/lib/onboarding-steps.d.ts.map +1 -0
  104. package/dist/server/lib/onboarding-steps.js +47 -0
  105. package/dist/server/lib/onboarding-steps.js.map +1 -0
  106. package/dist/server/lib/vault-store.d.ts +55 -0
  107. package/dist/server/lib/vault-store.d.ts.map +1 -1
  108. package/dist/server/lib/vault-store.js +210 -41
  109. package/dist/server/lib/vault-store.js.map +1 -1
  110. package/dist/server/plugins/agent-chat.d.ts.map +1 -1
  111. package/dist/server/plugins/agent-chat.js +2 -1
  112. package/dist/server/plugins/agent-chat.js.map +1 -1
  113. package/dist/server/plugins/core-routes.d.ts.map +1 -1
  114. package/dist/server/plugins/core-routes.js +4 -0
  115. package/dist/server/plugins/core-routes.js.map +1 -1
  116. package/dist/server/plugins/integrations.js +2 -2
  117. package/dist/server/plugins/integrations.js.map +1 -1
  118. package/package.json +13 -11
  119. package/src/actions/create-pylon-ticket.ts +109 -0
  120. package/src/actions/create-vault-grant.ts +1 -1
  121. package/src/actions/create-vault-secret.ts +4 -3
  122. package/src/actions/get-vault-access-settings.ts +11 -0
  123. package/src/actions/grant-vault-secrets-to-app.ts +1 -1
  124. package/src/actions/index.ts +8 -0
  125. package/src/actions/list-integrations-catalog.ts +1 -1
  126. package/src/actions/list-vault-grants.ts +1 -1
  127. package/src/actions/list-workspace-apps.ts +5 -1
  128. package/src/actions/set-vault-access-settings.ts +16 -0
  129. package/src/actions/start-workspace-app-creation.ts +8 -0
  130. package/src/actions/sync-vault-to-app.ts +1 -1
  131. package/src/actions/update-workspace-app-metadata.ts +32 -0
  132. package/src/actions/view-screen.ts +4 -1
  133. package/src/components/app-keys-popover.tsx +38 -8
  134. package/src/components/create-app-popover.tsx +47 -14
  135. package/src/components/dispatch-shell.tsx +16 -15
  136. package/src/components/layout/Layout.tsx +11 -5
  137. package/src/components/messaging-setup-panel.tsx +54 -39
  138. package/src/components/workspace-app-card.tsx +102 -0
  139. package/src/hooks/use-navigation-state.ts +10 -4
  140. package/src/lib/catch-all-target.spec.ts +218 -0
  141. package/src/lib/catch-all-target.ts +99 -0
  142. package/src/lib/workspace-apps.ts +9 -0
  143. package/src/routes/pages/$appId.tsx +45 -7
  144. package/src/routes/pages/approval.tsx +33 -3
  145. package/src/routes/pages/apps.$appId.tsx +6 -1
  146. package/src/routes/pages/integrations.tsx +57 -18
  147. package/src/routes/pages/new-app.tsx +1 -1
  148. package/src/routes/pages/overview.tsx +69 -29
  149. package/src/routes/pages/vault.tsx +101 -21
  150. package/src/routes/pages/workspace.tsx +21 -3
  151. package/src/server/lib/app-creation-store.spec.ts +61 -2
  152. package/src/server/lib/app-creation-store.ts +386 -11
  153. package/src/server/lib/env-config.ts +5 -0
  154. package/src/server/lib/onboarding-steps.ts +49 -0
  155. package/src/server/lib/vault-store.spec.ts +69 -0
  156. package/src/server/lib/vault-store.ts +266 -49
  157. package/src/server/plugins/agent-chat.ts +2 -1
  158. package/src/server/plugins/core-routes.ts +5 -0
  159. package/src/server/plugins/integrations.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/vault.tsx"],"names":[],"mappings":"AA8DA,wBAAgB,IAAI;;IAEnB;AAqbD,MAAM,CAAC,OAAO,UAAU,UAAU,4CAmHjC"}
1
+ {"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/vault.tsx"],"names":[],"mappings":"AAkEA,wBAAgB,IAAI;;IAEnB;AA4eD,MAAM,CAAC,OAAO,UAAU,UAAU,4CAwIjC"}
@@ -10,9 +10,11 @@ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, D
10
10
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "../../components/ui/alert-dialog.js";
11
11
  import { Input } from "../../components/ui/input.js";
12
12
  import { Label } from "../../components/ui/label.js";
13
+ import { Switch } from "../../components/ui/switch.js";
13
14
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "../../components/ui/select.js";
14
15
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../components/ui/tabs.js";
15
16
  import { Textarea } from "../../components/ui/textarea.js";
17
+ import { Skeleton } from "../../components/ui/skeleton.js";
16
18
  const PROVIDERS = [
17
19
  "google",
18
20
  "slack",
@@ -73,7 +75,19 @@ function GrantDialog({ secretId, secretName, }) {
73
75
  }));
74
76
  return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "sm", children: [_jsx(IconPlus, { size: 14, className: "mr-1" }), "Grant"] }) }), _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: ["Grant \"", secretName, "\" to an app"] }), _jsx(DialogDescription, { children: "Choose which app should receive this secret." })] }), _jsx("div", { className: "py-2", children: _jsxs(Select, { value: appId, onValueChange: setAppId, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Select an app..." }) }), _jsx(SelectContent, { children: apps.map((app) => (_jsx(SelectItem, { value: app.id, children: app.name }, app.id))) })] }) }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: () => grant.mutate({ secretId, appId }), disabled: !appId || grant.isPending, children: grant.isPending ? "Granting..." : "Grant access" }) })] })] }));
75
77
  }
76
- function SecretRow({ secret, grants }) {
78
+ function VaultAccessSettingsCard({ mode }) {
79
+ const update = useActionMutation("set-vault-access-settings", {
80
+ onSuccess: (next) => toast.success(next?.mode === "manual"
81
+ ? "Manual vault access enabled"
82
+ : "All apps can use vault keys"),
83
+ onError: (err) => toast.error(String(err)),
84
+ });
85
+ const allApps = mode !== "manual";
86
+ return (_jsx("div", { className: "rounded-xl border bg-card px-4 py-3", children: _jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx(Label, { className: "text-sm font-medium", children: "All apps can use vault keys" }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: allApps
87
+ ? "Every workspace app can receive every saved key."
88
+ : "Only apps with explicit grants can receive saved keys." })] }), _jsx(Switch, { checked: allApps, disabled: update.isPending, onCheckedChange: (checked) => update.mutate({ mode: checked ? "all-apps" : "manual" }), "aria-label": "Allow all workspace apps to use vault keys" })] }) }));
89
+ }
90
+ function SecretRow({ secret, grants, accessMode, }) {
77
91
  const [expanded, setExpanded] = useState(false);
78
92
  const [showValue, setShowValue] = useState(false);
79
93
  const deleteSecret = useActionMutation("delete-vault-secret", {
@@ -89,9 +103,12 @@ function SecretRow({ secret, grants }) {
89
103
  onError: (err) => toast.error(String(err)),
90
104
  });
91
105
  const activeGrants = grants.filter((g) => g.status === "active");
92
- return (_jsxs("div", { className: "rounded-xl border bg-card", children: [_jsxs("button", { type: "button", className: "flex w-full items-center gap-3 px-4 py-3 text-left cursor-pointer", onClick: () => setExpanded(!expanded), children: [expanded ? (_jsx(IconChevronDown, { size: 16, className: "text-muted-foreground" })) : (_jsx(IconChevronRight, { size: 16, className: "text-muted-foreground" })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: secret.name }), secret.provider && (_jsx(Badge, { variant: "secondary", className: "text-xs", children: secret.provider }))] }), _jsx("div", { className: "mt-0.5 font-mono text-xs text-muted-foreground", children: secret.credentialKey })] }), _jsx("div", { className: "flex items-center gap-2", children: _jsxs(Badge, { variant: "outline", className: "text-xs", children: [activeGrants.length, " grant", activeGrants.length !== 1 ? "s" : ""] }) })] }), expanded && (_jsxs("div", { className: "border-t px-4 py-3 space-y-3", children: [secret.description && (_jsx("p", { className: "text-sm text-muted-foreground", children: secret.description })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: "Value:" }), _jsx("code", { className: "text-xs font-mono text-foreground", children: showValue ? secret.value : `••••${secret.value.slice(-4)}` }), _jsx("button", { type: "button", onClick: () => setShowValue(!showValue), className: "text-muted-foreground hover:text-foreground cursor-pointer", children: showValue ? _jsx(IconEyeOff, { size: 14 }) : _jsx(IconEye, { size: 14 }) })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-medium text-foreground", children: "Grants" }), _jsx(GrantDialog, { secretId: secret.id, secretName: secret.name })] }), activeGrants.length > 0 ? (_jsx("div", { className: "space-y-1.5", children: activeGrants.map((grant) => (_jsxs("div", { className: "flex items-center justify-between rounded-lg border px-3 py-2", children: [_jsxs("div", { children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: grant.appId }), _jsx("span", { className: "ml-2 text-xs text-muted-foreground", children: grant.syncedAt
106
+ const allApps = accessMode !== "manual";
107
+ return (_jsxs("div", { className: "rounded-xl border bg-card", children: [_jsxs("button", { type: "button", className: "flex w-full items-center gap-3 px-4 py-3 text-left cursor-pointer", onClick: () => setExpanded(!expanded), children: [expanded ? (_jsx(IconChevronDown, { size: 16, className: "text-muted-foreground" })) : (_jsx(IconChevronRight, { size: 16, className: "text-muted-foreground" })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: secret.name }), secret.provider && (_jsx(Badge, { variant: "secondary", className: "text-xs", children: secret.provider }))] }), _jsx("div", { className: "mt-0.5 font-mono text-xs text-muted-foreground", children: secret.credentialKey })] }), _jsx("div", { className: "flex items-center gap-2", children: _jsx(Badge, { variant: "outline", className: "text-xs", children: allApps
108
+ ? "All apps"
109
+ : `${activeGrants.length} grant${activeGrants.length !== 1 ? "s" : ""}` }) })] }), expanded && (_jsxs("div", { className: "border-t px-4 py-3 space-y-3", children: [secret.description && (_jsx("p", { className: "text-sm text-muted-foreground", children: secret.description })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: "Value:" }), _jsx("code", { className: "text-xs font-mono text-foreground", children: showValue ? secret.value : `••••${secret.value.slice(-4)}` }), _jsx("button", { type: "button", onClick: () => setShowValue(!showValue), className: "text-muted-foreground hover:text-foreground cursor-pointer", children: showValue ? _jsx(IconEyeOff, { size: 14 }) : _jsx(IconEye, { size: 14 }) })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-medium text-foreground", children: allApps ? "Access" : "Grants" }), !allApps && (_jsx(GrantDialog, { secretId: secret.id, secretName: secret.name }))] }), allApps ? (_jsx("div", { className: "rounded-lg border border-dashed px-3 py-4 text-center text-xs text-muted-foreground", children: "Available to every workspace app." })) : activeGrants.length > 0 ? (_jsx("div", { className: "space-y-1.5", children: activeGrants.map((grant) => (_jsxs("div", { className: "flex items-center justify-between rounded-lg border px-3 py-2", children: [_jsxs("div", { children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: grant.appId }), _jsx("span", { className: "ml-2 text-xs text-muted-foreground", children: grant.syncedAt
93
110
  ? `synced ${new Date(grant.syncedAt).toLocaleString()}`
94
- : "not synced" })] }), _jsxs("div", { className: "flex gap-1.5", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => syncToApp.mutate({ appId: grant.appId }), disabled: syncToApp.isPending, children: _jsx(IconRefresh, { size: 14 }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => revokeGrant.mutate({ grantId: grant.id }), disabled: revokeGrant.isPending, children: _jsx(IconX, { size: 14 }) })] })] }, grant.id))) })) : (_jsx("div", { className: "rounded-lg border border-dashed px-3 py-4 text-center text-xs text-muted-foreground", children: "No grants yet. Grant this secret to an app to share it." }))] }), _jsx("div", { className: "flex justify-end border-t pt-3", children: _jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "destructive", size: "sm", disabled: deleteSecret.isPending, children: [_jsx(IconTrash, { size: 14, className: "mr-1" }), "Delete secret"] }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete this secret?" }), _jsxs(AlertDialogDescription, { children: ["Removing \u201C", secret.name, "\u201D revokes all of its grants. Apps that depended on this credential will lose access on the next sync. This cannot be undone."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancel" }), _jsx(AlertDialogAction, { onClick: () => deleteSecret.mutate({ id: secret.id }), children: "Delete secret" })] })] })] }) })] }))] }));
111
+ : "not synced" })] }), _jsxs("div", { className: "flex gap-1.5", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => syncToApp.mutate({ appId: grant.appId }), disabled: syncToApp.isPending, children: _jsx(IconRefresh, { size: 14 }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => revokeGrant.mutate({ grantId: grant.id }), disabled: revokeGrant.isPending, children: _jsx(IconX, { size: 14 }) })] })] }, grant.id))) })) : (_jsx("div", { className: "rounded-lg border border-dashed px-3 py-4 text-center text-xs text-muted-foreground", children: "No grants yet." }))] }), _jsx("div", { className: "flex justify-end border-t pt-3", children: _jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "destructive", size: "sm", disabled: deleteSecret.isPending, children: [_jsx(IconTrash, { size: 14, className: "mr-1" }), "Delete secret"] }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete this secret?" }), _jsxs(AlertDialogDescription, { children: ["Removing \u201C", secret.name, "\u201D revokes all of its grants. Apps that depended on this credential can lose access on the next sync. This cannot be undone."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancel" }), _jsx(AlertDialogAction, { onClick: () => deleteSecret.mutate({ id: secret.id }), children: "Delete secret" })] })] })] }) })] }))] }));
95
112
  }
96
113
  function RequestRow({ request }) {
97
114
  const [secretValue, setSecretValue] = useState("");
@@ -117,6 +134,8 @@ export default function VaultRoute() {
117
134
  const { data: grants } = useActionQuery("list-vault-grants", {});
118
135
  const { data: requests } = useActionQuery("list-vault-requests", {});
119
136
  const { data: audit } = useActionQuery("list-vault-audit", { limit: 20 });
137
+ const { data: accessSettings } = useActionQuery("get-vault-access-settings", {});
138
+ const accessMode = accessSettings?.mode === "manual" ? "manual" : "all-apps";
120
139
  const grantsBySecret = (grants || []).reduce((acc, g) => {
121
140
  if (!acc[g.secretId])
122
141
  acc[g.secretId] = [];
@@ -124,8 +143,8 @@ export default function VaultRoute() {
124
143
  return acc;
125
144
  }, {});
126
145
  const pendingRequests = (requests || []).filter((r) => r.status === "pending");
127
- return (_jsx(DispatchShell, { title: "Vault", description: "Centralized secret management for your workspace. Store credentials once, grant them to apps.", children: _jsxs(Tabs, { defaultValue: "secrets", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "secrets", children: ["Secrets ", (secrets?.length || 0) > 0 && `(${secrets?.length})`] }), _jsxs(TabsTrigger, { value: "requests", children: ["Requests", " ", pendingRequests.length > 0 && (_jsx(Badge, { variant: "secondary", className: "ml-1.5 h-5 px-1.5 text-xs bg-amber-500/10 text-amber-700 dark:text-amber-400", children: pendingRequests.length }))] }), _jsx(TabsTrigger, { value: "audit", children: "Audit" })] }), _jsxs(TabsContent, { value: "secrets", className: "mt-4 space-y-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(IconKey, { size: 16 }), _jsx("span", { children: secretsLoading
128
- ? "Loading..."
129
- : `${secrets?.length || 0} secret${(secrets?.length || 0) !== 1 ? "s" : ""}` })] }), _jsx(AddSecretDialog, {})] }), (secrets || []).map((secret) => (_jsx(SecretRow, { secret: secret, grants: grantsBySecret[secret.id] || [] }, secret.id))), !secretsLoading && (secrets?.length || 0) === 0 && (_jsxs("div", { className: "rounded-2xl border border-dashed px-6 py-12 text-center", children: [_jsx(IconKey, { size: 32, className: "mx-auto text-muted-foreground/50" }), _jsx("h3", { className: "mt-3 text-sm font-medium text-foreground", children: "No secrets yet" }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: "Add your first secret to start sharing credentials across workspace apps." })] }))] }), _jsxs(TabsContent, { value: "requests", className: "mt-4 space-y-3", children: [(requests || []).map((request) => (_jsx(RequestRow, { request: request }, request.id))), (requests?.length || 0) === 0 && (_jsx("div", { className: "rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground", children: "No secret requests yet." }))] }), _jsxs(TabsContent, { value: "audit", className: "mt-4 space-y-2", children: [(audit || []).map((event) => (_jsxs("div", { className: "rounded-xl border bg-muted/30 px-4 py-3", children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: event.summary }), _jsxs("div", { className: "mt-1 text-xs text-muted-foreground", children: [event.actor, " \u00B7 ", new Date(event.createdAt).toLocaleString()] })] }, event.id))), (audit?.length || 0) === 0 && (_jsx("div", { className: "rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground", children: "No vault activity yet." }))] })] }) }));
146
+ return (_jsx(DispatchShell, { title: "Vault", description: "Centralized secret management for your workspace. Store credentials once and sync them to apps.", children: _jsxs(Tabs, { defaultValue: "secrets", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "secrets", children: ["Secrets ", (secrets?.length || 0) > 0 && `(${secrets?.length})`] }), _jsxs(TabsTrigger, { value: "requests", children: ["Requests", " ", pendingRequests.length > 0 && (_jsx(Badge, { variant: "secondary", className: "ml-1.5 h-5 px-1.5 text-xs bg-amber-500/10 text-amber-700 dark:text-amber-400", children: pendingRequests.length }))] }), _jsx(TabsTrigger, { value: "audit", children: "Audit" })] }), _jsxs(TabsContent, { value: "secrets", className: "mt-4 space-y-3", children: [_jsx(VaultAccessSettingsCard, { mode: accessMode }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(IconKey, { size: 16 }), secretsLoading ? (_jsx(Skeleton, { className: "h-4 w-20" })) : (_jsx("span", { children: `${secrets?.length || 0} secret${(secrets?.length || 0) !== 1 ? "s" : ""}` }))] }), _jsx(AddSecretDialog, {})] }), secretsLoading && (secrets ?? []).length === 0
147
+ ? Array.from({ length: 3 }).map((_, index) => (_jsxs("div", { className: "rounded-2xl border bg-card px-5 py-4 space-y-2", children: [_jsx(Skeleton, { className: "h-4 w-1/3" }), _jsx(Skeleton, { className: "h-3 w-2/3" })] }, index)))
148
+ : (secrets || []).map((secret) => (_jsx(SecretRow, { secret: secret, grants: grantsBySecret[secret.id] || [], accessMode: accessMode }, secret.id))), !secretsLoading && (secrets?.length || 0) === 0 && (_jsxs("div", { className: "rounded-2xl border border-dashed px-6 py-12 text-center", children: [_jsx(IconKey, { size: 32, className: "mx-auto text-muted-foreground/50" }), _jsx("h3", { className: "mt-3 text-sm font-medium text-foreground", children: "No secrets yet" }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: "Add your first secret to start sharing credentials across workspace apps." })] }))] }), _jsxs(TabsContent, { value: "requests", className: "mt-4 space-y-3", children: [(requests || []).map((request) => (_jsx(RequestRow, { request: request }, request.id))), (requests?.length || 0) === 0 && (_jsx("div", { className: "rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground", children: "No secret requests yet." }))] }), _jsxs(TabsContent, { value: "audit", className: "mt-4 space-y-2", children: [(audit || []).map((event) => (_jsxs("div", { className: "rounded-xl border bg-muted/30 px-4 py-3", children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: event.summary }), _jsxs("div", { className: "mt-1 text-xs text-muted-foreground", children: [event.actor, " \u00B7 ", new Date(event.createdAt).toLocaleString()] })] }, event.id))), (audit?.length || 0) === 0 && (_jsx("div", { className: "rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground", children: "No vault activity yet." }))] })] }) }));
130
149
  }
131
150
  //# sourceMappingURL=vault.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vault.js","sourceRoot":"","sources":["../../../src/routes/pages/vault.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport { useActionMutation, useActionQuery } from \"@agent-native/core/client\";\nimport { toast } from \"sonner\";\nimport {\n IconChevronDown,\n IconChevronRight,\n IconEye,\n IconEyeOff,\n IconKey,\n IconPlus,\n IconRefresh,\n IconTrash,\n IconX,\n} from \"@tabler/icons-react\";\nimport { DispatchShell } from \"@/components/dispatch-shell\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { Textarea } from \"@/components/ui/textarea\";\n\nconst PROVIDERS = [\n \"google\",\n \"slack\",\n \"sendgrid\",\n \"github\",\n \"stripe\",\n \"hubspot\",\n \"jira\",\n \"bigquery\",\n \"anthropic\",\n \"other\",\n];\n\nexport function meta() {\n return [{ title: \"Vault — Dispatch\" }];\n}\n\nfunction AddSecretDialog() {\n const [open, setOpen] = useState(false);\n const [credentialKey, setCredentialKey] = useState(\"\");\n const [name, setName] = useState(\"\");\n const [value, setValue] = useState(\"\");\n const [provider, setProvider] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n\n const create = useActionMutation(\"create-vault-secret\", {\n onSuccess: () => {\n toast.success(\"Secret created\");\n setOpen(false);\n setCredentialKey(\"\");\n setName(\"\");\n setValue(\"\");\n setProvider(\"\");\n setDescription(\"\");\n },\n onError: (err) => toast.error(String(err)),\n });\n\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild>\n <Button>\n <IconPlus size={16} className=\"mr-1.5\" />\n Add secret\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Add vault secret</DialogTitle>\n <DialogDescription>\n Store a credential that can be granted to workspace apps.\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4 py-2\">\n <div className=\"space-y-2\">\n <Label>Name</Label>\n <Input\n placeholder=\"Google OAuth Client ID\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Credential key (env var name)</Label>\n <Input\n placeholder=\"GOOGLE_CLIENT_ID\"\n value={credentialKey}\n onChange={(e) => setCredentialKey(e.target.value)}\n className=\"font-mono text-sm\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Value</Label>\n <Input\n type=\"password\"\n placeholder=\"The secret value\"\n value={value}\n onChange={(e) => setValue(e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Provider</Label>\n <Select value={provider} onValueChange={setProvider}>\n <SelectTrigger>\n <SelectValue placeholder=\"Select a provider...\" />\n </SelectTrigger>\n <SelectContent>\n {PROVIDERS.map((p) => (\n <SelectItem key={p} value={p}>\n {p.charAt(0).toUpperCase() + p.slice(1)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Description (optional)</Label>\n <Textarea\n placeholder=\"What is this secret used for?\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n />\n </div>\n </div>\n <DialogFooter>\n <Button\n onClick={() =>\n create.mutate({\n credentialKey,\n name,\n value,\n provider: provider || undefined,\n description: description || undefined,\n })\n }\n disabled={!credentialKey || !name || !value || create.isPending}\n >\n {create.isPending ? \"Creating...\" : \"Create secret\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction GrantDialog({\n secretId,\n secretName,\n}: {\n secretId: string;\n secretName: string;\n}) {\n const [open, setOpen] = useState(false);\n const [appId, setAppId] = useState(\"\");\n const { data: catalog } = useActionQuery(\"list-integrations-catalog\", {});\n\n const grant = useActionMutation(\"create-vault-grant\", {\n onSuccess: () => {\n toast.success(`Granted to ${appId}`);\n setOpen(false);\n setAppId(\"\");\n },\n onError: (err) => toast.error(String(err)),\n });\n\n const apps = (catalog || []).map((a: any) => ({\n id: a.appId,\n name: a.appName,\n }));\n\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <IconPlus size={14} className=\"mr-1\" />\n Grant\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Grant \"{secretName}\" to an app</DialogTitle>\n <DialogDescription>\n Choose which app should receive this secret.\n </DialogDescription>\n </DialogHeader>\n <div className=\"py-2\">\n <Select value={appId} onValueChange={setAppId}>\n <SelectTrigger>\n <SelectValue placeholder=\"Select an app...\" />\n </SelectTrigger>\n <SelectContent>\n {apps.map((app: any) => (\n <SelectItem key={app.id} value={app.id}>\n {app.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <DialogFooter>\n <Button\n onClick={() => grant.mutate({ secretId, appId })}\n disabled={!appId || grant.isPending}\n >\n {grant.isPending ? \"Granting...\" : \"Grant access\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction SecretRow({ secret, grants }: { secret: any; grants: any[] }) {\n const [expanded, setExpanded] = useState(false);\n const [showValue, setShowValue] = useState(false);\n\n const deleteSecret = useActionMutation(\"delete-vault-secret\", {\n onSuccess: () => toast.success(\"Secret deleted\"),\n onError: (err) => toast.error(String(err)),\n });\n const revokeGrant = useActionMutation(\"revoke-vault-grant\", {\n onSuccess: () => toast.success(\"Grant revoked\"),\n onError: (err) => toast.error(String(err)),\n });\n const syncToApp = useActionMutation(\"sync-vault-to-app\", {\n onSuccess: (data: any) =>\n toast.success(`Synced ${data.synced} key(s) to ${data.appId}`),\n onError: (err) => toast.error(String(err)),\n });\n\n const activeGrants = grants.filter((g) => g.status === \"active\");\n\n return (\n <div className=\"rounded-xl border bg-card\">\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left cursor-pointer\"\n onClick={() => setExpanded(!expanded)}\n >\n {expanded ? (\n <IconChevronDown size={16} className=\"text-muted-foreground\" />\n ) : (\n <IconChevronRight size={16} className=\"text-muted-foreground\" />\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {secret.name}\n </span>\n {secret.provider && (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {secret.provider}\n </Badge>\n )}\n </div>\n <div className=\"mt-0.5 font-mono text-xs text-muted-foreground\">\n {secret.credentialKey}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"outline\" className=\"text-xs\">\n {activeGrants.length} grant{activeGrants.length !== 1 ? \"s\" : \"\"}\n </Badge>\n </div>\n </button>\n\n {expanded && (\n <div className=\"border-t px-4 py-3 space-y-3\">\n {secret.description && (\n <p className=\"text-sm text-muted-foreground\">\n {secret.description}\n </p>\n )}\n\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">Value:</span>\n <code className=\"text-xs font-mono text-foreground\">\n {showValue ? secret.value : `••••${secret.value.slice(-4)}`}\n </code>\n <button\n type=\"button\"\n onClick={() => setShowValue(!showValue)}\n className=\"text-muted-foreground hover:text-foreground cursor-pointer\"\n >\n {showValue ? <IconEyeOff size={14} /> : <IconEye size={14} />}\n </button>\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-medium text-foreground\">\n Grants\n </span>\n <GrantDialog secretId={secret.id} secretName={secret.name} />\n </div>\n {activeGrants.length > 0 ? (\n <div className=\"space-y-1.5\">\n {activeGrants.map((grant: any) => (\n <div\n key={grant.id}\n className=\"flex items-center justify-between rounded-lg border px-3 py-2\"\n >\n <div>\n <span className=\"text-sm font-medium text-foreground\">\n {grant.appId}\n </span>\n <span className=\"ml-2 text-xs text-muted-foreground\">\n {grant.syncedAt\n ? `synced ${new Date(grant.syncedAt).toLocaleString()}`\n : \"not synced\"}\n </span>\n </div>\n <div className=\"flex gap-1.5\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => syncToApp.mutate({ appId: grant.appId })}\n disabled={syncToApp.isPending}\n >\n <IconRefresh size={14} />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() =>\n revokeGrant.mutate({ grantId: grant.id })\n }\n disabled={revokeGrant.isPending}\n >\n <IconX size={14} />\n </Button>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"rounded-lg border border-dashed px-3 py-4 text-center text-xs text-muted-foreground\">\n No grants yet. Grant this secret to an app to share it.\n </div>\n )}\n </div>\n\n <div className=\"flex justify-end border-t pt-3\">\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n disabled={deleteSecret.isPending}\n >\n <IconTrash size={14} className=\"mr-1\" />\n Delete secret\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete this secret?</AlertDialogTitle>\n <AlertDialogDescription>\n Removing “{secret.name}” revokes all of its grants. Apps\n that depended on this credential will lose access on the\n next sync. This cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => deleteSecret.mutate({ id: secret.id })}\n >\n Delete secret\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction RequestRow({ request }: { request: any }) {\n const [secretValue, setSecretValue] = useState(\"\");\n\n const approve = useActionMutation(\"approve-vault-request\", {\n onSuccess: () => {\n toast.success(\"Request approved\");\n setSecretValue(\"\");\n },\n onError: (err) => toast.error(String(err)),\n });\n const deny = useActionMutation(\"deny-vault-request\", {\n onSuccess: () => toast.success(\"Request denied\"),\n onError: (err) => toast.error(String(err)),\n });\n\n return (\n <div className=\"rounded-xl border bg-muted/30 px-4 py-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <div className=\"text-sm font-medium text-foreground\">\n <span className=\"font-mono\">{request.credentialKey}</span> for{\" \"}\n <span className=\"font-semibold\">{request.appId}</span>\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n Requested by {request.requestedBy}\n {request.reason && ` — \"${request.reason}\"`}\n </div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">\n {request.status === \"pending\"\n ? \"Pending\"\n : request.status === \"approved\"\n ? `Approved by ${request.reviewedBy}`\n : `Denied by ${request.reviewedBy}`}{\" \"}\n · {new Date(request.createdAt).toLocaleString()}\n </div>\n </div>\n {request.status === \"pending\" && (\n <Badge variant=\"outline\" className=\"whitespace-nowrap\">\n Pending\n </Badge>\n )}\n {request.status === \"approved\" && (\n <Badge\n variant=\"secondary\"\n className=\"whitespace-nowrap bg-green-500/10 text-green-700 dark:text-green-400\"\n >\n Approved\n </Badge>\n )}\n {request.status === \"denied\" && (\n <Badge\n variant=\"secondary\"\n className=\"whitespace-nowrap bg-red-500/10 text-red-700 dark:text-red-400\"\n >\n Denied\n </Badge>\n )}\n </div>\n {request.status === \"pending\" && (\n <div className=\"mt-3 flex items-end gap-2 border-t pt-3\">\n <div className=\"flex-1 space-y-1\">\n <Label className=\"text-xs\">Secret value to provision</Label>\n <Input\n type=\"password\"\n placeholder=\"Enter the secret value\"\n value={secretValue}\n onChange={(e) => setSecretValue(e.target.value)}\n className=\"h-8 text-sm\"\n />\n </div>\n <Button\n size=\"sm\"\n onClick={() => approve.mutate({ id: request.id, secretValue })}\n disabled={!secretValue || approve.isPending}\n >\n Approve\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => deny.mutate({ id: request.id })}\n disabled={deny.isPending}\n >\n Deny\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nexport default function VaultRoute() {\n const { data: secrets, isLoading: secretsLoading } = useActionQuery(\n \"list-vault-secrets\",\n {},\n );\n const { data: grants } = useActionQuery(\"list-vault-grants\", {});\n const { data: requests } = useActionQuery(\"list-vault-requests\", {});\n const { data: audit } = useActionQuery(\"list-vault-audit\", { limit: 20 });\n\n const grantsBySecret = (grants || []).reduce(\n (acc: Record<string, any[]>, g: any) => {\n if (!acc[g.secretId]) acc[g.secretId] = [];\n acc[g.secretId].push(g);\n return acc;\n },\n {} as Record<string, any[]>,\n );\n\n const pendingRequests = (requests || []).filter(\n (r: any) => r.status === \"pending\",\n );\n\n return (\n <DispatchShell\n title=\"Vault\"\n description=\"Centralized secret management for your workspace. Store credentials once, grant them to apps.\"\n >\n <Tabs defaultValue=\"secrets\">\n <TabsList>\n <TabsTrigger value=\"secrets\">\n Secrets {(secrets?.length || 0) > 0 && `(${secrets?.length})`}\n </TabsTrigger>\n <TabsTrigger value=\"requests\">\n Requests{\" \"}\n {pendingRequests.length > 0 && (\n <Badge\n variant=\"secondary\"\n className=\"ml-1.5 h-5 px-1.5 text-xs bg-amber-500/10 text-amber-700 dark:text-amber-400\"\n >\n {pendingRequests.length}\n </Badge>\n )}\n </TabsTrigger>\n <TabsTrigger value=\"audit\">Audit</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"secrets\" className=\"mt-4 space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <IconKey size={16} />\n <span>\n {secretsLoading\n ? \"Loading...\"\n : `${secrets?.length || 0} secret${(secrets?.length || 0) !== 1 ? \"s\" : \"\"}`}\n </span>\n </div>\n <AddSecretDialog />\n </div>\n\n {(secrets || []).map((secret: any) => (\n <SecretRow\n key={secret.id}\n secret={secret}\n grants={grantsBySecret[secret.id] || []}\n />\n ))}\n\n {!secretsLoading && (secrets?.length || 0) === 0 && (\n <div className=\"rounded-2xl border border-dashed px-6 py-12 text-center\">\n <IconKey size={32} className=\"mx-auto text-muted-foreground/50\" />\n <h3 className=\"mt-3 text-sm font-medium text-foreground\">\n No secrets yet\n </h3>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n Add your first secret to start sharing credentials across\n workspace apps.\n </p>\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"requests\" className=\"mt-4 space-y-3\">\n {(requests || []).map((request: any) => (\n <RequestRow key={request.id} request={request} />\n ))}\n {(requests?.length || 0) === 0 && (\n <div className=\"rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground\">\n No secret requests yet.\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"audit\" className=\"mt-4 space-y-2\">\n {(audit || []).map((event: any) => (\n <div\n key={event.id}\n className=\"rounded-xl border bg-muted/30 px-4 py-3\"\n >\n <div className=\"text-sm font-medium text-foreground\">\n {event.summary}\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {event.actor} · {new Date(event.createdAt).toLocaleString()}\n </div>\n </div>\n ))}\n {(audit?.length || 0) === 0 && (\n <div className=\"rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground\">\n No vault activity yet.\n </div>\n )}\n </TabsContent>\n </Tabs>\n </DispatchShell>\n );\n}\n"]}
1
+ {"version":3,"file":"vault.js","sourceRoot":"","sources":["../../../src/routes/pages/vault.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport { useActionMutation, useActionQuery } from \"@agent-native/core/client\";\nimport { toast } from \"sonner\";\nimport {\n IconChevronDown,\n IconChevronRight,\n IconEye,\n IconEyeOff,\n IconKey,\n IconPlus,\n IconRefresh,\n IconTrash,\n IconX,\n} from \"@tabler/icons-react\";\nimport { DispatchShell } from \"@/components/dispatch-shell\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Switch } from \"@/components/ui/switch\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\n\nconst PROVIDERS = [\n \"google\",\n \"slack\",\n \"sendgrid\",\n \"github\",\n \"stripe\",\n \"hubspot\",\n \"jira\",\n \"bigquery\",\n \"anthropic\",\n \"other\",\n];\n\ntype VaultAccessMode = \"all-apps\" | \"manual\";\n\nexport function meta() {\n return [{ title: \"Vault — Dispatch\" }];\n}\n\nfunction AddSecretDialog() {\n const [open, setOpen] = useState(false);\n const [credentialKey, setCredentialKey] = useState(\"\");\n const [name, setName] = useState(\"\");\n const [value, setValue] = useState(\"\");\n const [provider, setProvider] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n\n const create = useActionMutation(\"create-vault-secret\", {\n onSuccess: () => {\n toast.success(\"Secret created\");\n setOpen(false);\n setCredentialKey(\"\");\n setName(\"\");\n setValue(\"\");\n setProvider(\"\");\n setDescription(\"\");\n },\n onError: (err) => toast.error(String(err)),\n });\n\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild>\n <Button>\n <IconPlus size={16} className=\"mr-1.5\" />\n Add secret\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Add vault secret</DialogTitle>\n <DialogDescription>\n Store a credential that can be granted to workspace apps.\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4 py-2\">\n <div className=\"space-y-2\">\n <Label>Name</Label>\n <Input\n placeholder=\"Google OAuth Client ID\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Credential key (env var name)</Label>\n <Input\n placeholder=\"GOOGLE_CLIENT_ID\"\n value={credentialKey}\n onChange={(e) => setCredentialKey(e.target.value)}\n className=\"font-mono text-sm\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Value</Label>\n <Input\n type=\"password\"\n placeholder=\"The secret value\"\n value={value}\n onChange={(e) => setValue(e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Provider</Label>\n <Select value={provider} onValueChange={setProvider}>\n <SelectTrigger>\n <SelectValue placeholder=\"Select a provider...\" />\n </SelectTrigger>\n <SelectContent>\n {PROVIDERS.map((p) => (\n <SelectItem key={p} value={p}>\n {p.charAt(0).toUpperCase() + p.slice(1)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Description (optional)</Label>\n <Textarea\n placeholder=\"What is this secret used for?\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n />\n </div>\n </div>\n <DialogFooter>\n <Button\n onClick={() =>\n create.mutate({\n credentialKey,\n name,\n value,\n provider: provider || undefined,\n description: description || undefined,\n })\n }\n disabled={!credentialKey || !name || !value || create.isPending}\n >\n {create.isPending ? \"Creating...\" : \"Create secret\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction GrantDialog({\n secretId,\n secretName,\n}: {\n secretId: string;\n secretName: string;\n}) {\n const [open, setOpen] = useState(false);\n const [appId, setAppId] = useState(\"\");\n const { data: catalog } = useActionQuery(\"list-integrations-catalog\", {});\n\n const grant = useActionMutation(\"create-vault-grant\", {\n onSuccess: () => {\n toast.success(`Granted to ${appId}`);\n setOpen(false);\n setAppId(\"\");\n },\n onError: (err) => toast.error(String(err)),\n });\n\n const apps = (catalog || []).map((a: any) => ({\n id: a.appId,\n name: a.appName,\n }));\n\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <IconPlus size={14} className=\"mr-1\" />\n Grant\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Grant \"{secretName}\" to an app</DialogTitle>\n <DialogDescription>\n Choose which app should receive this secret.\n </DialogDescription>\n </DialogHeader>\n <div className=\"py-2\">\n <Select value={appId} onValueChange={setAppId}>\n <SelectTrigger>\n <SelectValue placeholder=\"Select an app...\" />\n </SelectTrigger>\n <SelectContent>\n {apps.map((app: any) => (\n <SelectItem key={app.id} value={app.id}>\n {app.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <DialogFooter>\n <Button\n onClick={() => grant.mutate({ secretId, appId })}\n disabled={!appId || grant.isPending}\n >\n {grant.isPending ? \"Granting...\" : \"Grant access\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction VaultAccessSettingsCard({ mode }: { mode: VaultAccessMode }) {\n const update = useActionMutation(\"set-vault-access-settings\", {\n onSuccess: (next: any) =>\n toast.success(\n next?.mode === \"manual\"\n ? \"Manual vault access enabled\"\n : \"All apps can use vault keys\",\n ),\n onError: (err) => toast.error(String(err)),\n });\n const allApps = mode !== \"manual\";\n\n return (\n <div className=\"rounded-xl border bg-card px-4 py-3\">\n <div className=\"flex items-center justify-between gap-4\">\n <div className=\"min-w-0\">\n <Label className=\"text-sm font-medium\">\n All apps can use vault keys\n </Label>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {allApps\n ? \"Every workspace app can receive every saved key.\"\n : \"Only apps with explicit grants can receive saved keys.\"}\n </p>\n </div>\n <Switch\n checked={allApps}\n disabled={update.isPending}\n onCheckedChange={(checked) =>\n update.mutate({ mode: checked ? \"all-apps\" : \"manual\" })\n }\n aria-label=\"Allow all workspace apps to use vault keys\"\n />\n </div>\n </div>\n );\n}\n\nfunction SecretRow({\n secret,\n grants,\n accessMode,\n}: {\n secret: any;\n grants: any[];\n accessMode: VaultAccessMode;\n}) {\n const [expanded, setExpanded] = useState(false);\n const [showValue, setShowValue] = useState(false);\n\n const deleteSecret = useActionMutation(\"delete-vault-secret\", {\n onSuccess: () => toast.success(\"Secret deleted\"),\n onError: (err) => toast.error(String(err)),\n });\n const revokeGrant = useActionMutation(\"revoke-vault-grant\", {\n onSuccess: () => toast.success(\"Grant revoked\"),\n onError: (err) => toast.error(String(err)),\n });\n const syncToApp = useActionMutation(\"sync-vault-to-app\", {\n onSuccess: (data: any) =>\n toast.success(`Synced ${data.synced} key(s) to ${data.appId}`),\n onError: (err) => toast.error(String(err)),\n });\n\n const activeGrants = grants.filter((g) => g.status === \"active\");\n const allApps = accessMode !== \"manual\";\n\n return (\n <div className=\"rounded-xl border bg-card\">\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left cursor-pointer\"\n onClick={() => setExpanded(!expanded)}\n >\n {expanded ? (\n <IconChevronDown size={16} className=\"text-muted-foreground\" />\n ) : (\n <IconChevronRight size={16} className=\"text-muted-foreground\" />\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {secret.name}\n </span>\n {secret.provider && (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {secret.provider}\n </Badge>\n )}\n </div>\n <div className=\"mt-0.5 font-mono text-xs text-muted-foreground\">\n {secret.credentialKey}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"outline\" className=\"text-xs\">\n {allApps\n ? \"All apps\"\n : `${activeGrants.length} grant${activeGrants.length !== 1 ? \"s\" : \"\"}`}\n </Badge>\n </div>\n </button>\n\n {expanded && (\n <div className=\"border-t px-4 py-3 space-y-3\">\n {secret.description && (\n <p className=\"text-sm text-muted-foreground\">\n {secret.description}\n </p>\n )}\n\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">Value:</span>\n <code className=\"text-xs font-mono text-foreground\">\n {showValue ? secret.value : `••••${secret.value.slice(-4)}`}\n </code>\n <button\n type=\"button\"\n onClick={() => setShowValue(!showValue)}\n className=\"text-muted-foreground hover:text-foreground cursor-pointer\"\n >\n {showValue ? <IconEyeOff size={14} /> : <IconEye size={14} />}\n </button>\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-medium text-foreground\">\n {allApps ? \"Access\" : \"Grants\"}\n </span>\n {!allApps && (\n <GrantDialog secretId={secret.id} secretName={secret.name} />\n )}\n </div>\n {allApps ? (\n <div className=\"rounded-lg border border-dashed px-3 py-4 text-center text-xs text-muted-foreground\">\n Available to every workspace app.\n </div>\n ) : activeGrants.length > 0 ? (\n <div className=\"space-y-1.5\">\n {activeGrants.map((grant: any) => (\n <div\n key={grant.id}\n className=\"flex items-center justify-between rounded-lg border px-3 py-2\"\n >\n <div>\n <span className=\"text-sm font-medium text-foreground\">\n {grant.appId}\n </span>\n <span className=\"ml-2 text-xs text-muted-foreground\">\n {grant.syncedAt\n ? `synced ${new Date(grant.syncedAt).toLocaleString()}`\n : \"not synced\"}\n </span>\n </div>\n <div className=\"flex gap-1.5\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => syncToApp.mutate({ appId: grant.appId })}\n disabled={syncToApp.isPending}\n >\n <IconRefresh size={14} />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() =>\n revokeGrant.mutate({ grantId: grant.id })\n }\n disabled={revokeGrant.isPending}\n >\n <IconX size={14} />\n </Button>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"rounded-lg border border-dashed px-3 py-4 text-center text-xs text-muted-foreground\">\n No grants yet.\n </div>\n )}\n </div>\n\n <div className=\"flex justify-end border-t pt-3\">\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n disabled={deleteSecret.isPending}\n >\n <IconTrash size={14} className=\"mr-1\" />\n Delete secret\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete this secret?</AlertDialogTitle>\n <AlertDialogDescription>\n Removing “{secret.name}” revokes all of its grants. Apps\n that depended on this credential can lose access on the next\n sync. This cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => deleteSecret.mutate({ id: secret.id })}\n >\n Delete secret\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction RequestRow({ request }: { request: any }) {\n const [secretValue, setSecretValue] = useState(\"\");\n\n const approve = useActionMutation(\"approve-vault-request\", {\n onSuccess: () => {\n toast.success(\"Request approved\");\n setSecretValue(\"\");\n },\n onError: (err) => toast.error(String(err)),\n });\n const deny = useActionMutation(\"deny-vault-request\", {\n onSuccess: () => toast.success(\"Request denied\"),\n onError: (err) => toast.error(String(err)),\n });\n\n return (\n <div className=\"rounded-xl border bg-muted/30 px-4 py-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <div className=\"text-sm font-medium text-foreground\">\n <span className=\"font-mono\">{request.credentialKey}</span> for{\" \"}\n <span className=\"font-semibold\">{request.appId}</span>\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n Requested by {request.requestedBy}\n {request.reason && ` — \"${request.reason}\"`}\n </div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">\n {request.status === \"pending\"\n ? \"Pending\"\n : request.status === \"approved\"\n ? `Approved by ${request.reviewedBy}`\n : `Denied by ${request.reviewedBy}`}{\" \"}\n · {new Date(request.createdAt).toLocaleString()}\n </div>\n </div>\n {request.status === \"pending\" && (\n <Badge variant=\"outline\" className=\"whitespace-nowrap\">\n Pending\n </Badge>\n )}\n {request.status === \"approved\" && (\n <Badge\n variant=\"secondary\"\n className=\"whitespace-nowrap bg-green-500/10 text-green-700 dark:text-green-400\"\n >\n Approved\n </Badge>\n )}\n {request.status === \"denied\" && (\n <Badge\n variant=\"secondary\"\n className=\"whitespace-nowrap bg-red-500/10 text-red-700 dark:text-red-400\"\n >\n Denied\n </Badge>\n )}\n </div>\n {request.status === \"pending\" && (\n <div className=\"mt-3 flex items-end gap-2 border-t pt-3\">\n <div className=\"flex-1 space-y-1\">\n <Label className=\"text-xs\">Secret value to provision</Label>\n <Input\n type=\"password\"\n placeholder=\"Enter the secret value\"\n value={secretValue}\n onChange={(e) => setSecretValue(e.target.value)}\n className=\"h-8 text-sm\"\n />\n </div>\n <Button\n size=\"sm\"\n onClick={() => approve.mutate({ id: request.id, secretValue })}\n disabled={!secretValue || approve.isPending}\n >\n Approve\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => deny.mutate({ id: request.id })}\n disabled={deny.isPending}\n >\n Deny\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nexport default function VaultRoute() {\n const { data: secrets, isLoading: secretsLoading } = useActionQuery(\n \"list-vault-secrets\",\n {},\n );\n const { data: grants } = useActionQuery(\"list-vault-grants\", {});\n const { data: requests } = useActionQuery(\"list-vault-requests\", {});\n const { data: audit } = useActionQuery(\"list-vault-audit\", { limit: 20 });\n const { data: accessSettings } = useActionQuery(\n \"get-vault-access-settings\",\n {},\n );\n const accessMode: VaultAccessMode =\n (accessSettings as any)?.mode === \"manual\" ? \"manual\" : \"all-apps\";\n\n const grantsBySecret = (grants || []).reduce(\n (acc: Record<string, any[]>, g: any) => {\n if (!acc[g.secretId]) acc[g.secretId] = [];\n acc[g.secretId].push(g);\n return acc;\n },\n {} as Record<string, any[]>,\n );\n\n const pendingRequests = (requests || []).filter(\n (r: any) => r.status === \"pending\",\n );\n\n return (\n <DispatchShell\n title=\"Vault\"\n description=\"Centralized secret management for your workspace. Store credentials once and sync them to apps.\"\n >\n <Tabs defaultValue=\"secrets\">\n <TabsList>\n <TabsTrigger value=\"secrets\">\n Secrets {(secrets?.length || 0) > 0 && `(${secrets?.length})`}\n </TabsTrigger>\n <TabsTrigger value=\"requests\">\n Requests{\" \"}\n {pendingRequests.length > 0 && (\n <Badge\n variant=\"secondary\"\n className=\"ml-1.5 h-5 px-1.5 text-xs bg-amber-500/10 text-amber-700 dark:text-amber-400\"\n >\n {pendingRequests.length}\n </Badge>\n )}\n </TabsTrigger>\n <TabsTrigger value=\"audit\">Audit</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"secrets\" className=\"mt-4 space-y-3\">\n <VaultAccessSettingsCard mode={accessMode} />\n\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <IconKey size={16} />\n {secretsLoading ? (\n <Skeleton className=\"h-4 w-20\" />\n ) : (\n <span>\n {`${secrets?.length || 0} secret${(secrets?.length || 0) !== 1 ? \"s\" : \"\"}`}\n </span>\n )}\n </div>\n <AddSecretDialog />\n </div>\n\n {secretsLoading && (secrets ?? []).length === 0\n ? Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className=\"rounded-2xl border bg-card px-5 py-4 space-y-2\"\n >\n <Skeleton className=\"h-4 w-1/3\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n ))\n : (secrets || []).map((secret: any) => (\n <SecretRow\n key={secret.id}\n secret={secret}\n grants={grantsBySecret[secret.id] || []}\n accessMode={accessMode}\n />\n ))}\n\n {!secretsLoading && (secrets?.length || 0) === 0 && (\n <div className=\"rounded-2xl border border-dashed px-6 py-12 text-center\">\n <IconKey size={32} className=\"mx-auto text-muted-foreground/50\" />\n <h3 className=\"mt-3 text-sm font-medium text-foreground\">\n No secrets yet\n </h3>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n Add your first secret to start sharing credentials across\n workspace apps.\n </p>\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"requests\" className=\"mt-4 space-y-3\">\n {(requests || []).map((request: any) => (\n <RequestRow key={request.id} request={request} />\n ))}\n {(requests?.length || 0) === 0 && (\n <div className=\"rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground\">\n No secret requests yet.\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"audit\" className=\"mt-4 space-y-2\">\n {(audit || []).map((event: any) => (\n <div\n key={event.id}\n className=\"rounded-xl border bg-muted/30 px-4 py-3\"\n >\n <div className=\"text-sm font-medium text-foreground\">\n {event.summary}\n </div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {event.actor} · {new Date(event.createdAt).toLocaleString()}\n </div>\n </div>\n ))}\n {(audit?.length || 0) === 0 && (\n <div className=\"rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground\">\n No vault activity yet.\n </div>\n )}\n </TabsContent>\n </Tabs>\n </DispatchShell>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/workspace.tsx"],"names":[],"mappings":"AAkDA,wBAAgB,IAAI;;IAEnB;AAibD,MAAM,CAAC,OAAO,UAAU,cAAc,4CA0IrC"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/workspace.tsx"],"names":[],"mappings":"AAmDA,wBAAgB,IAAI;;IAEnB;AAibD,MAAM,CAAC,OAAO,UAAU,cAAc,4CA2JrC"}
@@ -13,6 +13,7 @@ import { Label } from "../../components/ui/label.js";
13
13
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "../../components/ui/select.js";
14
14
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../components/ui/tabs.js";
15
15
  import { Textarea } from "../../components/ui/textarea.js";
16
+ import { Skeleton } from "../../components/ui/skeleton.js";
16
17
  export function meta() {
17
18
  return [{ title: "Workspace Resources — Dispatch" }];
18
19
  }
@@ -148,13 +149,14 @@ export default function WorkspaceRoute() {
148
149
  const agents = (resources || []).filter((r) => r.kind === "agent");
149
150
  const knowledge = (resources || []).filter((r) => r.kind === "knowledge");
150
151
  function ResourceList({ items, emptyText, }) {
152
+ if (isLoading && (resources ?? []).length === 0) {
153
+ return (_jsx("div", { className: "space-y-3", children: Array.from({ length: 3 }).map((_, index) => (_jsxs("div", { className: "rounded-2xl border bg-card px-5 py-4 space-y-2", children: [_jsx(Skeleton, { className: "h-4 w-1/3" }), _jsx(Skeleton, { className: "h-3 w-2/3" })] }, index))) }));
154
+ }
151
155
  if (items.length === 0) {
152
156
  return (_jsx("div", { className: "rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground", children: emptyText }));
153
157
  }
154
158
  return (_jsx("div", { className: "space-y-3", children: items.map((resource) => (_jsx(ResourceRow, { resource: resource, grants: grantsByResource[resource.id] || [] }, resource.id))) }));
155
159
  }
156
- return (_jsxs(DispatchShell, { title: "Workspace Resources", description: "Share skills, instructions, agent profiles, and knowledge packs across workspace apps. Scope to all apps or grant per-app.", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-sm text-muted-foreground", children: isLoading
157
- ? "Loading..."
158
- : `${resources?.length || 0} resource${(resources?.length || 0) !== 1 ? "s" : ""}` }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", onClick: () => syncAll.mutate({}), disabled: syncAll.isPending || (resources?.length || 0) === 0, children: [_jsx(IconRefresh, { size: 16, className: syncAll.isPending ? "mr-1.5 animate-spin" : "mr-1.5" }), "Sync all"] }), _jsx(AddResourceDialog, {})] })] }), _jsxs(Tabs, { defaultValue: "skills", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "skills", children: ["Skills ", skills.length > 0 && `(${skills.length})`] }), _jsxs(TabsTrigger, { value: "instructions", children: ["Instructions ", instructions.length > 0 && `(${instructions.length})`] }), _jsxs(TabsTrigger, { value: "agents", children: ["Agents ", agents.length > 0 && `(${agents.length})`] }), _jsxs(TabsTrigger, { value: "knowledge", children: ["Knowledge ", knowledge.length > 0 && `(${knowledge.length})`] })] }), _jsx(TabsContent, { value: "skills", className: "mt-4", children: _jsx(ResourceList, { items: skills, emptyText: "No workspace skills yet. Add a skill to share agent guidance across apps." }) }), _jsx(TabsContent, { value: "instructions", className: "mt-4", children: _jsx(ResourceList, { items: instructions, emptyText: "No workspace instructions yet. Add instructions to set behavioral rules across apps." }) }), _jsx(TabsContent, { value: "agents", className: "mt-4", children: _jsx(ResourceList, { items: agents, emptyText: "No workspace agents yet. Add a reusable agent profile to share specialist agents across apps." }) }), _jsx(TabsContent, { value: "knowledge", className: "mt-4", children: _jsx(ResourceList, { items: knowledge, emptyText: "No knowledge packs yet. Add GTM, product, or domain context that apps can reuse." }) })] })] }));
160
+ return (_jsxs(DispatchShell, { title: "Workspace Resources", description: "Share skills, instructions, agent profiles, and knowledge packs across workspace apps. Scope to all apps or grant per-app.", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-sm text-muted-foreground", children: isLoading ? (_jsx(Skeleton, { className: "h-4 w-24" })) : (`${resources?.length || 0} resource${(resources?.length || 0) !== 1 ? "s" : ""}`) }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", onClick: () => syncAll.mutate({}), disabled: syncAll.isPending || (resources?.length || 0) === 0, children: [_jsx(IconRefresh, { size: 16, className: syncAll.isPending ? "mr-1.5 animate-spin" : "mr-1.5" }), "Sync all"] }), _jsx(AddResourceDialog, {})] })] }), _jsxs(Tabs, { defaultValue: "skills", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "skills", children: ["Skills ", skills.length > 0 && `(${skills.length})`] }), _jsxs(TabsTrigger, { value: "instructions", children: ["Instructions ", instructions.length > 0 && `(${instructions.length})`] }), _jsxs(TabsTrigger, { value: "agents", children: ["Agents ", agents.length > 0 && `(${agents.length})`] }), _jsxs(TabsTrigger, { value: "knowledge", children: ["Knowledge ", knowledge.length > 0 && `(${knowledge.length})`] })] }), _jsx(TabsContent, { value: "skills", className: "mt-4", children: _jsx(ResourceList, { items: skills, emptyText: "No workspace skills yet. Add a skill to share agent guidance across apps." }) }), _jsx(TabsContent, { value: "instructions", className: "mt-4", children: _jsx(ResourceList, { items: instructions, emptyText: "No workspace instructions yet. Add instructions to set behavioral rules across apps." }) }), _jsx(TabsContent, { value: "agents", className: "mt-4", children: _jsx(ResourceList, { items: agents, emptyText: "No workspace agents yet. Add a reusable agent profile to share specialist agents across apps." }) }), _jsx(TabsContent, { value: "knowledge", className: "mt-4", children: _jsx(ResourceList, { items: knowledge, emptyText: "No knowledge packs yet. Add GTM, product, or domain context that apps can reuse." }) })] })] }));
159
161
  }
160
162
  //# sourceMappingURL=workspace.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/routes/pages/workspace.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport { useActionMutation, useActionQuery } from \"@agent-native/core/client\";\nimport { toast } from \"sonner\";\nimport {\n IconBook,\n IconChevronDown,\n IconChevronRight,\n IconCode,\n IconFileText,\n IconPlus,\n IconRefresh,\n IconTrash,\n IconUser,\n IconX,\n} from \"@tabler/icons-react\";\nimport { DispatchShell } from \"@/components/dispatch-shell\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { Textarea } from \"@/components/ui/textarea\";\n\nexport function meta() {\n return [{ title: \"Workspace Resources — Dispatch\" }];\n}\n\nconst KIND_CONFIG = {\n skill: {\n label: \"Skill\",\n icon: IconCode,\n pathPrefix: \"skills/\",\n description: \"Agent skills — detailed guidance for patterns and workflows\",\n },\n instruction: {\n label: \"Instruction\",\n icon: IconBook,\n pathPrefix: \"\",\n description:\n \"Agent instructions — operational rules and behavioral guidance\",\n },\n agent: {\n label: \"Agent\",\n icon: IconUser,\n pathPrefix: \"agents/\",\n description:\n \"Reusable agent profiles — specialist agents shared across apps\",\n },\n knowledge: {\n label: \"Knowledge\",\n icon: IconFileText,\n pathPrefix: \"context/\",\n description:\n \"Knowledge packs — reusable GTM, product, and domain context for apps\",\n },\n} as const;\n\nfunction AddResourceDialog() {\n const [open, setOpen] = useState(false);\n const [kind, setKind] = useState<string>(\"skill\");\n const [name, setName] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [path, setPath] = useState(\"\");\n const [content, setContent] = useState(\"\");\n const [scope, setScope] = useState<string>(\"all\");\n\n const create = useActionMutation(\"create-workspace-resource\", {\n onSuccess: () => {\n toast.success(\"Resource created\");\n setOpen(false);\n setKind(\"skill\");\n setName(\"\");\n setDescription(\"\");\n setPath(\"\");\n setContent(\"\");\n setScope(\"all\");\n },\n onError: (err) => toast.error(String(err)),\n });\n\n const kindInfo = KIND_CONFIG[kind as keyof typeof KIND_CONFIG];\n\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild>\n <Button>\n <IconPlus size={16} className=\"mr-1.5\" />\n Add resource\n </Button>\n </DialogTrigger>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>Add workspace resource</DialogTitle>\n <DialogDescription>\n Create a skill, instruction, or agent profile that can be shared\n across workspace apps.\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4 py-2\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label>Kind</Label>\n <Select value={kind} onValueChange={setKind}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"skill\">Skill</SelectItem>\n <SelectItem value=\"instruction\">Instruction</SelectItem>\n <SelectItem value=\"agent\">Agent</SelectItem>\n <SelectItem value=\"knowledge\">Knowledge pack</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Scope</Label>\n <Select value={scope} onValueChange={setScope}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All apps</SelectItem>\n <SelectItem value=\"selected\">Selected apps only</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label>Name</Label>\n <Input\n placeholder={\n kind === \"skill\"\n ? \"Frontend Designer\"\n : kind === \"agent\"\n ? \"Research Specialist\"\n : kind === \"knowledge\"\n ? \"Core GTM Messaging\"\n : \"Code Style Guide\"\n }\n value={name}\n onChange={(e) => setName(e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Path</Label>\n <Input\n placeholder={`${kindInfo?.pathPrefix || \"\"}${name.toLowerCase().replace(/\\s+/g, \"-\") || \"example\"}.md`}\n value={path}\n onChange={(e) => setPath(e.target.value)}\n className=\"font-mono text-sm\"\n />\n <p className=\"text-xs text-muted-foreground\">\n Resource path in target apps. Skills go in skills/, agents in\n agents/, knowledge packs in context/.\n </p>\n </div>\n <div className=\"space-y-2\">\n <Label>Description (optional)</Label>\n <Input\n placeholder=\"Short description of what this resource does\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Content</Label>\n <Textarea\n placeholder={\n kind === \"skill\"\n ? \"---\\nname: my-skill\\ndescription: What this skill teaches\\n---\\n\\n# My Skill\\n\\n...\"\n : kind === \"agent\"\n ? \"---\\nname: Research Specialist\\ndescription: Handles research tasks\\n---\\n\\n# Instructions\\n\\n...\"\n : kind === \"knowledge\"\n ? \"# Core GTM Messaging\\n\\n## Positioning\\n\\n## ICP\\n\\n## Proof points\\n\\n## Source\\n\\n\"\n : \"# Instructions\\n\\nBehavioral rules and guidance for agents across apps...\"\n }\n value={content}\n onChange={(e) => setContent(e.target.value)}\n rows={12}\n className=\"font-mono text-sm\"\n />\n </div>\n </div>\n <DialogFooter>\n <Button\n onClick={() =>\n create.mutate({\n kind: kind as \"skill\" | \"instruction\" | \"agent\" | \"knowledge\",\n name,\n description: description || undefined,\n path:\n path ||\n `${kindInfo?.pathPrefix || \"\"}${name.toLowerCase().replace(/\\s+/g, \"-\")}.md`,\n content,\n scope: scope as \"all\" | \"selected\",\n })\n }\n disabled={!name || !content || create.isPending}\n >\n {create.isPending ? \"Creating...\" : \"Create resource\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction GrantDialog({\n resourceId,\n resourceName,\n}: {\n resourceId: string;\n resourceName: string;\n}) {\n const [open, setOpen] = useState(false);\n const [appId, setAppId] = useState(\"\");\n const { data: catalog } = useActionQuery(\"list-integrations-catalog\", {});\n\n const grant = useActionMutation(\"create-workspace-resource-grant\", {\n onSuccess: () => {\n toast.success(`Granted to ${appId}`);\n setOpen(false);\n setAppId(\"\");\n },\n onError: (err) => toast.error(String(err)),\n });\n\n const apps = (catalog || []).map((a: any) => ({\n id: a.appId,\n name: a.appName,\n }));\n\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <IconPlus size={14} className=\"mr-1\" />\n Grant\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Grant \"{resourceName}\" to an app</DialogTitle>\n <DialogDescription>\n Choose which app should receive this resource.\n </DialogDescription>\n </DialogHeader>\n <div className=\"py-2\">\n <Select value={appId} onValueChange={setAppId}>\n <SelectTrigger>\n <SelectValue placeholder=\"Select an app...\" />\n </SelectTrigger>\n <SelectContent>\n {apps.map((app: any) => (\n <SelectItem key={app.id} value={app.id}>\n {app.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <DialogFooter>\n <Button\n onClick={() => grant.mutate({ resourceId, appId })}\n disabled={!appId || grant.isPending}\n >\n {grant.isPending ? \"Granting...\" : \"Grant access\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction ResourceRow({ resource, grants }: { resource: any; grants: any[] }) {\n const [expanded, setExpanded] = useState(false);\n\n const deleteResource = useActionMutation(\"delete-workspace-resource\", {\n onSuccess: () => toast.success(\"Resource deleted\"),\n onError: (err) => toast.error(String(err)),\n });\n const revokeGrant = useActionMutation(\"revoke-workspace-resource-grant\", {\n onSuccess: () => toast.success(\"Grant revoked\"),\n onError: (err) => toast.error(String(err)),\n });\n const syncToApp = useActionMutation(\"sync-workspace-resources-to-app\", {\n onSuccess: (data: any) =>\n toast.success(`Synced ${data.synced} resource(s) to ${data.appId}`),\n onError: (err) => toast.error(String(err)),\n });\n\n const kindInfo = KIND_CONFIG[resource.kind as keyof typeof KIND_CONFIG];\n const KindIcon = kindInfo?.icon || IconCode;\n const activeGrants = grants.filter((g) => g.status === \"active\");\n\n return (\n <div className=\"rounded-xl border bg-card\">\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left cursor-pointer\"\n onClick={() => setExpanded(!expanded)}\n >\n {expanded ? (\n <IconChevronDown size={16} className=\"text-muted-foreground\" />\n ) : (\n <IconChevronRight size={16} className=\"text-muted-foreground\" />\n )}\n <KindIcon size={16} className=\"text-muted-foreground\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {resource.name}\n </span>\n <Badge variant=\"secondary\" className=\"text-xs\">\n {kindInfo?.label || resource.kind}\n </Badge>\n <Badge\n variant=\"outline\"\n className={\n resource.scope === \"all\"\n ? \"text-xs bg-green-500/10 text-green-700 dark:text-green-400\"\n : \"text-xs\"\n }\n >\n {resource.scope === \"all\" ? \"All apps\" : \"Selected\"}\n </Badge>\n </div>\n <div className=\"mt-0.5 font-mono text-xs text-muted-foreground\">\n {resource.path}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {resource.scope === \"selected\" && (\n <Badge variant=\"outline\" className=\"text-xs\">\n {activeGrants.length} grant\n {activeGrants.length !== 1 ? \"s\" : \"\"}\n </Badge>\n )}\n </div>\n </button>\n\n {expanded && (\n <div className=\"border-t px-4 py-3 space-y-3\">\n {resource.description && (\n <p className=\"text-sm text-muted-foreground\">\n {resource.description}\n </p>\n )}\n\n <div className=\"rounded-lg border bg-muted/30 p-3\">\n <pre className=\"whitespace-pre-wrap text-xs font-mono text-foreground max-h-64 overflow-y-auto\">\n {resource.content}\n </pre>\n </div>\n\n {resource.scope === \"selected\" && (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-medium text-foreground\">\n Grants\n </span>\n <GrantDialog\n resourceId={resource.id}\n resourceName={resource.name}\n />\n </div>\n {activeGrants.length > 0 ? (\n <div className=\"space-y-1.5\">\n {activeGrants.map((grant: any) => (\n <div\n key={grant.id}\n className=\"flex items-center justify-between rounded-lg border px-3 py-2\"\n >\n <div>\n <span className=\"text-sm font-medium text-foreground\">\n {grant.appId}\n </span>\n <span className=\"ml-2 text-xs text-muted-foreground\">\n {grant.syncedAt\n ? `synced ${new Date(grant.syncedAt).toLocaleString()}`\n : \"not synced\"}\n </span>\n </div>\n <div className=\"flex gap-1.5\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() =>\n syncToApp.mutate({ appId: grant.appId })\n }\n disabled={syncToApp.isPending}\n >\n <IconRefresh size={14} />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() =>\n revokeGrant.mutate({ grantId: grant.id })\n }\n disabled={revokeGrant.isPending}\n >\n <IconX size={14} />\n </Button>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"rounded-lg border border-dashed px-3 py-4 text-center text-xs text-muted-foreground\">\n No grants yet. Grant this resource to specific apps.\n </div>\n )}\n </div>\n )}\n\n <div className=\"flex justify-between border-t pt-3\">\n <div className=\"text-xs text-muted-foreground\">\n Created by {resource.createdBy} ·{\" \"}\n {new Date(resource.createdAt).toLocaleString()}\n </div>\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n disabled={deleteResource.isPending}\n >\n <IconTrash size={14} className=\"mr-1\" />\n Delete\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete this resource?</AlertDialogTitle>\n <AlertDialogDescription>\n Removing \"{resource.name}\" revokes all of its grants. Apps\n that depended on this resource will lose access on the next\n sync. This cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => deleteResource.mutate({ id: resource.id })}\n >\n Delete resource\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport default function WorkspaceRoute() {\n const { data: resources, isLoading } = useActionQuery(\n \"list-workspace-resources\",\n {},\n );\n const { data: grants } = useActionQuery(\"list-workspace-resource-grants\", {});\n\n const syncAll = useActionMutation(\"sync-workspace-resources-to-all\", {\n onSuccess: (data: any) => {\n const total = (data || []).reduce(\n (sum: number, r: any) => sum + r.synced,\n 0,\n );\n toast.success(\n `Synced resources to ${data?.length || 0} apps (${total} total pushes)`,\n );\n },\n onError: (err) => toast.error(String(err)),\n });\n\n const grantsByResource = (grants || []).reduce(\n (acc: Record<string, any[]>, g: any) => {\n if (!acc[g.resourceId]) acc[g.resourceId] = [];\n acc[g.resourceId].push(g);\n return acc;\n },\n {} as Record<string, any[]>,\n );\n\n const skills = (resources || []).filter((r: any) => r.kind === \"skill\");\n const instructions = (resources || []).filter(\n (r: any) => r.kind === \"instruction\",\n );\n const agents = (resources || []).filter((r: any) => r.kind === \"agent\");\n const knowledge = (resources || []).filter(\n (r: any) => r.kind === \"knowledge\",\n );\n\n function ResourceList({\n items,\n emptyText,\n }: {\n items: any[];\n emptyText: string;\n }) {\n if (items.length === 0) {\n return (\n <div className=\"rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground\">\n {emptyText}\n </div>\n );\n }\n return (\n <div className=\"space-y-3\">\n {items.map((resource: any) => (\n <ResourceRow\n key={resource.id}\n resource={resource}\n grants={grantsByResource[resource.id] || []}\n />\n ))}\n </div>\n );\n }\n\n return (\n <DispatchShell\n title=\"Workspace Resources\"\n description=\"Share skills, instructions, agent profiles, and knowledge packs across workspace apps. Scope to all apps or grant per-app.\"\n >\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm text-muted-foreground\">\n {isLoading\n ? \"Loading...\"\n : `${resources?.length || 0} resource${(resources?.length || 0) !== 1 ? \"s\" : \"\"}`}\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n onClick={() => syncAll.mutate({})}\n disabled={syncAll.isPending || (resources?.length || 0) === 0}\n >\n <IconRefresh\n size={16}\n className={syncAll.isPending ? \"mr-1.5 animate-spin\" : \"mr-1.5\"}\n />\n Sync all\n </Button>\n <AddResourceDialog />\n </div>\n </div>\n\n <Tabs defaultValue=\"skills\">\n <TabsList>\n <TabsTrigger value=\"skills\">\n Skills {skills.length > 0 && `(${skills.length})`}\n </TabsTrigger>\n <TabsTrigger value=\"instructions\">\n Instructions {instructions.length > 0 && `(${instructions.length})`}\n </TabsTrigger>\n <TabsTrigger value=\"agents\">\n Agents {agents.length > 0 && `(${agents.length})`}\n </TabsTrigger>\n <TabsTrigger value=\"knowledge\">\n Knowledge {knowledge.length > 0 && `(${knowledge.length})`}\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"skills\" className=\"mt-4\">\n <ResourceList\n items={skills}\n emptyText=\"No workspace skills yet. Add a skill to share agent guidance across apps.\"\n />\n </TabsContent>\n\n <TabsContent value=\"instructions\" className=\"mt-4\">\n <ResourceList\n items={instructions}\n emptyText=\"No workspace instructions yet. Add instructions to set behavioral rules across apps.\"\n />\n </TabsContent>\n\n <TabsContent value=\"agents\" className=\"mt-4\">\n <ResourceList\n items={agents}\n emptyText=\"No workspace agents yet. Add a reusable agent profile to share specialist agents across apps.\"\n />\n </TabsContent>\n\n <TabsContent value=\"knowledge\" className=\"mt-4\">\n <ResourceList\n items={knowledge}\n emptyText=\"No knowledge packs yet. Add GTM, product, or domain context that apps can reuse.\"\n />\n </TabsContent>\n </Tabs>\n </DispatchShell>\n );\n}\n"]}
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/routes/pages/workspace.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport { useActionMutation, useActionQuery } from \"@agent-native/core/client\";\nimport { toast } from \"sonner\";\nimport {\n IconBook,\n IconChevronDown,\n IconChevronRight,\n IconCode,\n IconFileText,\n IconPlus,\n IconRefresh,\n IconTrash,\n IconUser,\n IconX,\n} from \"@tabler/icons-react\";\nimport { DispatchShell } from \"@/components/dispatch-shell\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\n\nexport function meta() {\n return [{ title: \"Workspace Resources — Dispatch\" }];\n}\n\nconst KIND_CONFIG = {\n skill: {\n label: \"Skill\",\n icon: IconCode,\n pathPrefix: \"skills/\",\n description: \"Agent skills — detailed guidance for patterns and workflows\",\n },\n instruction: {\n label: \"Instruction\",\n icon: IconBook,\n pathPrefix: \"\",\n description:\n \"Agent instructions — operational rules and behavioral guidance\",\n },\n agent: {\n label: \"Agent\",\n icon: IconUser,\n pathPrefix: \"agents/\",\n description:\n \"Reusable agent profiles — specialist agents shared across apps\",\n },\n knowledge: {\n label: \"Knowledge\",\n icon: IconFileText,\n pathPrefix: \"context/\",\n description:\n \"Knowledge packs — reusable GTM, product, and domain context for apps\",\n },\n} as const;\n\nfunction AddResourceDialog() {\n const [open, setOpen] = useState(false);\n const [kind, setKind] = useState<string>(\"skill\");\n const [name, setName] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [path, setPath] = useState(\"\");\n const [content, setContent] = useState(\"\");\n const [scope, setScope] = useState<string>(\"all\");\n\n const create = useActionMutation(\"create-workspace-resource\", {\n onSuccess: () => {\n toast.success(\"Resource created\");\n setOpen(false);\n setKind(\"skill\");\n setName(\"\");\n setDescription(\"\");\n setPath(\"\");\n setContent(\"\");\n setScope(\"all\");\n },\n onError: (err) => toast.error(String(err)),\n });\n\n const kindInfo = KIND_CONFIG[kind as keyof typeof KIND_CONFIG];\n\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild>\n <Button>\n <IconPlus size={16} className=\"mr-1.5\" />\n Add resource\n </Button>\n </DialogTrigger>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>Add workspace resource</DialogTitle>\n <DialogDescription>\n Create a skill, instruction, or agent profile that can be shared\n across workspace apps.\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4 py-2\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label>Kind</Label>\n <Select value={kind} onValueChange={setKind}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"skill\">Skill</SelectItem>\n <SelectItem value=\"instruction\">Instruction</SelectItem>\n <SelectItem value=\"agent\">Agent</SelectItem>\n <SelectItem value=\"knowledge\">Knowledge pack</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label>Scope</Label>\n <Select value={scope} onValueChange={setScope}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All apps</SelectItem>\n <SelectItem value=\"selected\">Selected apps only</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label>Name</Label>\n <Input\n placeholder={\n kind === \"skill\"\n ? \"Frontend Designer\"\n : kind === \"agent\"\n ? \"Research Specialist\"\n : kind === \"knowledge\"\n ? \"Core GTM Messaging\"\n : \"Code Style Guide\"\n }\n value={name}\n onChange={(e) => setName(e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Path</Label>\n <Input\n placeholder={`${kindInfo?.pathPrefix || \"\"}${name.toLowerCase().replace(/\\s+/g, \"-\") || \"example\"}.md`}\n value={path}\n onChange={(e) => setPath(e.target.value)}\n className=\"font-mono text-sm\"\n />\n <p className=\"text-xs text-muted-foreground\">\n Resource path in target apps. Skills go in skills/, agents in\n agents/, knowledge packs in context/.\n </p>\n </div>\n <div className=\"space-y-2\">\n <Label>Description (optional)</Label>\n <Input\n placeholder=\"Short description of what this resource does\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>Content</Label>\n <Textarea\n placeholder={\n kind === \"skill\"\n ? \"---\\nname: my-skill\\ndescription: What this skill teaches\\n---\\n\\n# My Skill\\n\\n...\"\n : kind === \"agent\"\n ? \"---\\nname: Research Specialist\\ndescription: Handles research tasks\\n---\\n\\n# Instructions\\n\\n...\"\n : kind === \"knowledge\"\n ? \"# Core GTM Messaging\\n\\n## Positioning\\n\\n## ICP\\n\\n## Proof points\\n\\n## Source\\n\\n\"\n : \"# Instructions\\n\\nBehavioral rules and guidance for agents across apps...\"\n }\n value={content}\n onChange={(e) => setContent(e.target.value)}\n rows={12}\n className=\"font-mono text-sm\"\n />\n </div>\n </div>\n <DialogFooter>\n <Button\n onClick={() =>\n create.mutate({\n kind: kind as \"skill\" | \"instruction\" | \"agent\" | \"knowledge\",\n name,\n description: description || undefined,\n path:\n path ||\n `${kindInfo?.pathPrefix || \"\"}${name.toLowerCase().replace(/\\s+/g, \"-\")}.md`,\n content,\n scope: scope as \"all\" | \"selected\",\n })\n }\n disabled={!name || !content || create.isPending}\n >\n {create.isPending ? \"Creating...\" : \"Create resource\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction GrantDialog({\n resourceId,\n resourceName,\n}: {\n resourceId: string;\n resourceName: string;\n}) {\n const [open, setOpen] = useState(false);\n const [appId, setAppId] = useState(\"\");\n const { data: catalog } = useActionQuery(\"list-integrations-catalog\", {});\n\n const grant = useActionMutation(\"create-workspace-resource-grant\", {\n onSuccess: () => {\n toast.success(`Granted to ${appId}`);\n setOpen(false);\n setAppId(\"\");\n },\n onError: (err) => toast.error(String(err)),\n });\n\n const apps = (catalog || []).map((a: any) => ({\n id: a.appId,\n name: a.appName,\n }));\n\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <IconPlus size={14} className=\"mr-1\" />\n Grant\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Grant \"{resourceName}\" to an app</DialogTitle>\n <DialogDescription>\n Choose which app should receive this resource.\n </DialogDescription>\n </DialogHeader>\n <div className=\"py-2\">\n <Select value={appId} onValueChange={setAppId}>\n <SelectTrigger>\n <SelectValue placeholder=\"Select an app...\" />\n </SelectTrigger>\n <SelectContent>\n {apps.map((app: any) => (\n <SelectItem key={app.id} value={app.id}>\n {app.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <DialogFooter>\n <Button\n onClick={() => grant.mutate({ resourceId, appId })}\n disabled={!appId || grant.isPending}\n >\n {grant.isPending ? \"Granting...\" : \"Grant access\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction ResourceRow({ resource, grants }: { resource: any; grants: any[] }) {\n const [expanded, setExpanded] = useState(false);\n\n const deleteResource = useActionMutation(\"delete-workspace-resource\", {\n onSuccess: () => toast.success(\"Resource deleted\"),\n onError: (err) => toast.error(String(err)),\n });\n const revokeGrant = useActionMutation(\"revoke-workspace-resource-grant\", {\n onSuccess: () => toast.success(\"Grant revoked\"),\n onError: (err) => toast.error(String(err)),\n });\n const syncToApp = useActionMutation(\"sync-workspace-resources-to-app\", {\n onSuccess: (data: any) =>\n toast.success(`Synced ${data.synced} resource(s) to ${data.appId}`),\n onError: (err) => toast.error(String(err)),\n });\n\n const kindInfo = KIND_CONFIG[resource.kind as keyof typeof KIND_CONFIG];\n const KindIcon = kindInfo?.icon || IconCode;\n const activeGrants = grants.filter((g) => g.status === \"active\");\n\n return (\n <div className=\"rounded-xl border bg-card\">\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left cursor-pointer\"\n onClick={() => setExpanded(!expanded)}\n >\n {expanded ? (\n <IconChevronDown size={16} className=\"text-muted-foreground\" />\n ) : (\n <IconChevronRight size={16} className=\"text-muted-foreground\" />\n )}\n <KindIcon size={16} className=\"text-muted-foreground\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {resource.name}\n </span>\n <Badge variant=\"secondary\" className=\"text-xs\">\n {kindInfo?.label || resource.kind}\n </Badge>\n <Badge\n variant=\"outline\"\n className={\n resource.scope === \"all\"\n ? \"text-xs bg-green-500/10 text-green-700 dark:text-green-400\"\n : \"text-xs\"\n }\n >\n {resource.scope === \"all\" ? \"All apps\" : \"Selected\"}\n </Badge>\n </div>\n <div className=\"mt-0.5 font-mono text-xs text-muted-foreground\">\n {resource.path}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {resource.scope === \"selected\" && (\n <Badge variant=\"outline\" className=\"text-xs\">\n {activeGrants.length} grant\n {activeGrants.length !== 1 ? \"s\" : \"\"}\n </Badge>\n )}\n </div>\n </button>\n\n {expanded && (\n <div className=\"border-t px-4 py-3 space-y-3\">\n {resource.description && (\n <p className=\"text-sm text-muted-foreground\">\n {resource.description}\n </p>\n )}\n\n <div className=\"rounded-lg border bg-muted/30 p-3\">\n <pre className=\"whitespace-pre-wrap text-xs font-mono text-foreground max-h-64 overflow-y-auto\">\n {resource.content}\n </pre>\n </div>\n\n {resource.scope === \"selected\" && (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-medium text-foreground\">\n Grants\n </span>\n <GrantDialog\n resourceId={resource.id}\n resourceName={resource.name}\n />\n </div>\n {activeGrants.length > 0 ? (\n <div className=\"space-y-1.5\">\n {activeGrants.map((grant: any) => (\n <div\n key={grant.id}\n className=\"flex items-center justify-between rounded-lg border px-3 py-2\"\n >\n <div>\n <span className=\"text-sm font-medium text-foreground\">\n {grant.appId}\n </span>\n <span className=\"ml-2 text-xs text-muted-foreground\">\n {grant.syncedAt\n ? `synced ${new Date(grant.syncedAt).toLocaleString()}`\n : \"not synced\"}\n </span>\n </div>\n <div className=\"flex gap-1.5\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() =>\n syncToApp.mutate({ appId: grant.appId })\n }\n disabled={syncToApp.isPending}\n >\n <IconRefresh size={14} />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() =>\n revokeGrant.mutate({ grantId: grant.id })\n }\n disabled={revokeGrant.isPending}\n >\n <IconX size={14} />\n </Button>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"rounded-lg border border-dashed px-3 py-4 text-center text-xs text-muted-foreground\">\n No grants yet. Grant this resource to specific apps.\n </div>\n )}\n </div>\n )}\n\n <div className=\"flex justify-between border-t pt-3\">\n <div className=\"text-xs text-muted-foreground\">\n Created by {resource.createdBy} ·{\" \"}\n {new Date(resource.createdAt).toLocaleString()}\n </div>\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n disabled={deleteResource.isPending}\n >\n <IconTrash size={14} className=\"mr-1\" />\n Delete\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete this resource?</AlertDialogTitle>\n <AlertDialogDescription>\n Removing \"{resource.name}\" revokes all of its grants. Apps\n that depended on this resource will lose access on the next\n sync. This cannot be undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => deleteResource.mutate({ id: resource.id })}\n >\n Delete resource\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport default function WorkspaceRoute() {\n const { data: resources, isLoading } = useActionQuery(\n \"list-workspace-resources\",\n {},\n );\n const { data: grants } = useActionQuery(\"list-workspace-resource-grants\", {});\n\n const syncAll = useActionMutation(\"sync-workspace-resources-to-all\", {\n onSuccess: (data: any) => {\n const total = (data || []).reduce(\n (sum: number, r: any) => sum + r.synced,\n 0,\n );\n toast.success(\n `Synced resources to ${data?.length || 0} apps (${total} total pushes)`,\n );\n },\n onError: (err) => toast.error(String(err)),\n });\n\n const grantsByResource = (grants || []).reduce(\n (acc: Record<string, any[]>, g: any) => {\n if (!acc[g.resourceId]) acc[g.resourceId] = [];\n acc[g.resourceId].push(g);\n return acc;\n },\n {} as Record<string, any[]>,\n );\n\n const skills = (resources || []).filter((r: any) => r.kind === \"skill\");\n const instructions = (resources || []).filter(\n (r: any) => r.kind === \"instruction\",\n );\n const agents = (resources || []).filter((r: any) => r.kind === \"agent\");\n const knowledge = (resources || []).filter(\n (r: any) => r.kind === \"knowledge\",\n );\n\n function ResourceList({\n items,\n emptyText,\n }: {\n items: any[];\n emptyText: string;\n }) {\n if (isLoading && (resources ?? []).length === 0) {\n return (\n <div className=\"space-y-3\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className=\"rounded-2xl border bg-card px-5 py-4 space-y-2\"\n >\n <Skeleton className=\"h-4 w-1/3\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n ))}\n </div>\n );\n }\n if (items.length === 0) {\n return (\n <div className=\"rounded-2xl border border-dashed px-6 py-12 text-center text-sm text-muted-foreground\">\n {emptyText}\n </div>\n );\n }\n return (\n <div className=\"space-y-3\">\n {items.map((resource: any) => (\n <ResourceRow\n key={resource.id}\n resource={resource}\n grants={grantsByResource[resource.id] || []}\n />\n ))}\n </div>\n );\n }\n\n return (\n <DispatchShell\n title=\"Workspace Resources\"\n description=\"Share skills, instructions, agent profiles, and knowledge packs across workspace apps. Scope to all apps or grant per-app.\"\n >\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm text-muted-foreground\">\n {isLoading ? (\n <Skeleton className=\"h-4 w-24\" />\n ) : (\n `${resources?.length || 0} resource${(resources?.length || 0) !== 1 ? \"s\" : \"\"}`\n )}\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n onClick={() => syncAll.mutate({})}\n disabled={syncAll.isPending || (resources?.length || 0) === 0}\n >\n <IconRefresh\n size={16}\n className={syncAll.isPending ? \"mr-1.5 animate-spin\" : \"mr-1.5\"}\n />\n Sync all\n </Button>\n <AddResourceDialog />\n </div>\n </div>\n\n <Tabs defaultValue=\"skills\">\n <TabsList>\n <TabsTrigger value=\"skills\">\n Skills {skills.length > 0 && `(${skills.length})`}\n </TabsTrigger>\n <TabsTrigger value=\"instructions\">\n Instructions {instructions.length > 0 && `(${instructions.length})`}\n </TabsTrigger>\n <TabsTrigger value=\"agents\">\n Agents {agents.length > 0 && `(${agents.length})`}\n </TabsTrigger>\n <TabsTrigger value=\"knowledge\">\n Knowledge {knowledge.length > 0 && `(${knowledge.length})`}\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"skills\" className=\"mt-4\">\n <ResourceList\n items={skills}\n emptyText=\"No workspace skills yet. Add a skill to share agent guidance across apps.\"\n />\n </TabsContent>\n\n <TabsContent value=\"instructions\" className=\"mt-4\">\n <ResourceList\n items={instructions}\n emptyText=\"No workspace instructions yet. Add instructions to set behavioral rules across apps.\"\n />\n </TabsContent>\n\n <TabsContent value=\"agents\" className=\"mt-4\">\n <ResourceList\n items={agents}\n emptyText=\"No workspace agents yet. Add a reusable agent profile to share specialist agents across apps.\"\n />\n </TabsContent>\n\n <TabsContent value=\"knowledge\" className=\"mt-4\">\n <ResourceList\n items={knowledge}\n emptyText=\"No knowledge packs yet. Add GTM, product, or domain context that apps can reuse.\"\n />\n </TabsContent>\n </Tabs>\n </DispatchShell>\n );\n}\n"]}