@agent-native/dispatch 0.14.3 → 0.14.4

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 (127) hide show
  1. package/README.md +114 -128
  2. package/dist/actions/list_apps.d.ts +1 -0
  3. package/dist/actions/list_apps.js +16 -8
  4. package/dist/actions/list_apps.js.map +1 -1
  5. package/dist/actions/set-mcp-app-access.js +1 -4
  6. package/dist/actions/set-mcp-app-access.js.map +1 -1
  7. package/dist/components/action-query-error.d.ts +8 -0
  8. package/dist/components/action-query-error.d.ts.map +1 -0
  9. package/dist/components/action-query-error.js +10 -0
  10. package/dist/components/action-query-error.js.map +1 -0
  11. package/dist/components/app-keys-popover.d.ts +4 -0
  12. package/dist/components/app-keys-popover.d.ts.map +1 -1
  13. package/dist/components/app-keys-popover.js +26 -14
  14. package/dist/components/app-keys-popover.js.map +1 -1
  15. package/dist/components/dispatch-control-plane.d.ts.map +1 -1
  16. package/dist/components/dispatch-control-plane.js +31 -27
  17. package/dist/components/dispatch-control-plane.js.map +1 -1
  18. package/dist/components/index.d.ts +1 -0
  19. package/dist/components/index.d.ts.map +1 -1
  20. package/dist/components/index.js +1 -0
  21. package/dist/components/index.js.map +1 -1
  22. package/dist/components/layout/Layout.d.ts +1 -0
  23. package/dist/components/layout/Layout.d.ts.map +1 -1
  24. package/dist/components/layout/Layout.js +19 -21
  25. package/dist/components/layout/Layout.js.map +1 -1
  26. package/dist/components/ui/sheet.js +1 -1
  27. package/dist/components/ui/sheet.js.map +1 -1
  28. package/dist/components/ui/toast.js +1 -1
  29. package/dist/components/ui/toast.js.map +1 -1
  30. package/dist/components/workspace-app-card.d.ts.map +1 -1
  31. package/dist/components/workspace-app-card.js +8 -5
  32. package/dist/components/workspace-app-card.js.map +1 -1
  33. package/dist/components/workspace-resource-effective-stack.d.ts.map +1 -1
  34. package/dist/components/workspace-resource-effective-stack.js +6 -1
  35. package/dist/components/workspace-resource-effective-stack.js.map +1 -1
  36. package/dist/components/workspace-resource-impact-preview.d.ts.map +1 -1
  37. package/dist/components/workspace-resource-impact-preview.js +6 -1
  38. package/dist/components/workspace-resource-impact-preview.js.map +1 -1
  39. package/dist/routes/pages/$appId.d.ts.map +1 -1
  40. package/dist/routes/pages/$appId.js +6 -1
  41. package/dist/routes/pages/$appId.js.map +1 -1
  42. package/dist/routes/pages/agents.d.ts.map +1 -1
  43. package/dist/routes/pages/agents.js +5 -8
  44. package/dist/routes/pages/agents.js.map +1 -1
  45. package/dist/routes/pages/approval.d.ts.map +1 -1
  46. package/dist/routes/pages/approval.js +6 -1
  47. package/dist/routes/pages/approval.js.map +1 -1
  48. package/dist/routes/pages/approvals.d.ts.map +1 -1
  49. package/dist/routes/pages/approvals.js +8 -5
  50. package/dist/routes/pages/approvals.js.map +1 -1
  51. package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
  52. package/dist/routes/pages/apps.$appId.js +4 -2
  53. package/dist/routes/pages/apps.$appId.js.map +1 -1
  54. package/dist/routes/pages/apps.d.ts.map +1 -1
  55. package/dist/routes/pages/apps.js +9 -3
  56. package/dist/routes/pages/apps.js.map +1 -1
  57. package/dist/routes/pages/audit.d.ts.map +1 -1
  58. package/dist/routes/pages/audit.js +4 -2
  59. package/dist/routes/pages/audit.js.map +1 -1
  60. package/dist/routes/pages/chat.d.ts.map +1 -1
  61. package/dist/routes/pages/chat.js +16 -2
  62. package/dist/routes/pages/chat.js.map +1 -1
  63. package/dist/routes/pages/destinations.d.ts.map +1 -1
  64. package/dist/routes/pages/destinations.js +5 -3
  65. package/dist/routes/pages/destinations.js.map +1 -1
  66. package/dist/routes/pages/identities.d.ts.map +1 -1
  67. package/dist/routes/pages/identities.js +5 -3
  68. package/dist/routes/pages/identities.js.map +1 -1
  69. package/dist/routes/pages/integrations.d.ts.map +1 -1
  70. package/dist/routes/pages/integrations.js +9 -3
  71. package/dist/routes/pages/integrations.js.map +1 -1
  72. package/dist/routes/pages/thread-debug.d.ts.map +1 -1
  73. package/dist/routes/pages/thread-debug.js +7 -6
  74. package/dist/routes/pages/thread-debug.js.map +1 -1
  75. package/dist/routes/pages/vault.d.ts.map +1 -1
  76. package/dist/routes/pages/vault.js +23 -7
  77. package/dist/routes/pages/vault.js.map +1 -1
  78. package/dist/routes/pages/workspace.d.ts.map +1 -1
  79. package/dist/routes/pages/workspace.js +9 -3
  80. package/dist/routes/pages/workspace.js.map +1 -1
  81. package/dist/server/lib/dispatch-store.d.ts.map +1 -1
  82. package/dist/server/lib/dispatch-store.js +2 -2
  83. package/dist/server/lib/dispatch-store.js.map +1 -1
  84. package/dist/server/lib/mcp-access-store.d.ts.map +1 -1
  85. package/dist/server/lib/mcp-access-store.js +30 -2
  86. package/dist/server/lib/mcp-access-store.js.map +1 -1
  87. package/dist/server/plugins/agent-chat.d.ts +1 -1
  88. package/package.json +2 -2
  89. package/src/actions/list_apps.spec.ts +52 -0
  90. package/src/actions/list_apps.ts +16 -8
  91. package/src/actions/set-mcp-app-access.spec.ts +73 -0
  92. package/src/actions/set-mcp-app-access.ts +1 -5
  93. package/src/components/action-query-error.spec.tsx +56 -0
  94. package/src/components/action-query-error.tsx +32 -0
  95. package/src/components/app-keys-popover.spec.tsx +85 -0
  96. package/src/components/app-keys-popover.tsx +76 -50
  97. package/src/components/dispatch-control-plane.spec.tsx +106 -0
  98. package/src/components/dispatch-control-plane.tsx +71 -115
  99. package/src/components/index.ts +1 -0
  100. package/src/components/layout/Layout.spec.tsx +42 -2
  101. package/src/components/layout/Layout.tsx +22 -27
  102. package/src/components/ui/sheet.tsx +1 -1
  103. package/src/components/ui/toast.tsx +1 -1
  104. package/src/components/workspace-app-card.spec.tsx +80 -0
  105. package/src/components/workspace-app-card.tsx +36 -25
  106. package/src/components/workspace-resource-effective-stack.tsx +13 -1
  107. package/src/components/workspace-resource-impact-preview.tsx +12 -1
  108. package/src/routes/pages/$appId.tsx +17 -1
  109. package/src/routes/pages/agents.tsx +24 -11
  110. package/src/routes/pages/approval.tsx +16 -4
  111. package/src/routes/pages/approvals.tsx +108 -89
  112. package/src/routes/pages/apps.$appId.tsx +9 -2
  113. package/src/routes/pages/apps.tsx +20 -7
  114. package/src/routes/pages/audit.tsx +29 -20
  115. package/src/routes/pages/chat.spec.tsx +94 -0
  116. package/src/routes/pages/chat.tsx +30 -10
  117. package/src/routes/pages/destinations.tsx +75 -62
  118. package/src/routes/pages/identities.tsx +74 -63
  119. package/src/routes/pages/integrations.tsx +17 -10
  120. package/src/routes/pages/thread-debug.tsx +18 -12
  121. package/src/routes/pages/vault.tsx +59 -26
  122. package/src/routes/pages/workspace.tsx +69 -55
  123. package/src/server/lib/approval-fencing.spec.ts +113 -2
  124. package/src/server/lib/dispatch-store.ts +2 -0
  125. package/src/server/lib/mcp-access-store.spec.ts +116 -4
  126. package/src/server/lib/mcp-access-store.ts +37 -2
  127. package/src/server/lib/mcp-gateway.spec.ts +79 -3
@@ -1 +1 @@
1
- {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../../../src/components/ui/sheet.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst Sheet = SheetPrimitive.Root;\n\nconst SheetTrigger = SheetPrimitive.Trigger;\n\nconst SheetClose = SheetPrimitive.Close;\n\nconst SheetPortal = SheetPrimitive.Portal;\n\nconst SheetOverlay = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Overlay\n className={cn(\n \"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n ref={ref}\n />\n));\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName;\n\nconst sheetVariants = cva(\n \"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n {\n variants: {\n side: {\n top: \"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n bottom:\n \"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n left: \"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm\",\n right:\n \"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm\",\n },\n },\n defaultVariants: {\n side: \"right\",\n },\n },\n);\n\ninterface SheetContentProps\n extends\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,\n VariantProps<typeof sheetVariants> {}\n\nconst SheetContent = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Content>,\n SheetContentProps\n>(({ side = \"right\", className, children, ...props }, ref) => (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n ref={ref}\n className={cn(sheetVariants({ side }), className)}\n {...props}\n >\n {children}\n <SheetPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\">\n <IconX className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </SheetPrimitive.Content>\n </SheetPortal>\n));\nSheetContent.displayName = SheetPrimitive.Content.displayName;\n\nconst SheetHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col space-y-2 text-center sm:text-left\",\n className,\n )}\n {...props}\n />\n);\nSheetHeader.displayName = \"SheetHeader\";\n\nconst SheetFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className,\n )}\n {...props}\n />\n);\nSheetFooter.displayName = \"SheetFooter\";\n\nconst SheetTitle = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Title\n ref={ref}\n className={cn(\"text-lg font-semibold text-foreground\", className)}\n {...props}\n />\n));\nSheetTitle.displayName = SheetPrimitive.Title.displayName;\n\nconst SheetDescription = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n));\nSheetDescription.displayName = SheetPrimitive.Description.displayName;\n\nexport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetOverlay,\n SheetPortal,\n SheetTitle,\n SheetTrigger,\n};\n"]}
1
+ {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../../../src/components/ui/sheet.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst Sheet = SheetPrimitive.Root;\n\nconst SheetTrigger = SheetPrimitive.Trigger;\n\nconst SheetClose = SheetPrimitive.Close;\n\nconst SheetPortal = SheetPrimitive.Portal;\n\nconst SheetOverlay = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Overlay\n className={cn(\n \"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n ref={ref}\n />\n));\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName;\n\nconst sheetVariants = cva(\n \"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-150 data-[state=open]:duration-200\",\n {\n variants: {\n side: {\n top: \"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n bottom:\n \"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n left: \"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm\",\n right:\n \"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm\",\n },\n },\n defaultVariants: {\n side: \"right\",\n },\n },\n);\n\ninterface SheetContentProps\n extends\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,\n VariantProps<typeof sheetVariants> {}\n\nconst SheetContent = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Content>,\n SheetContentProps\n>(({ side = \"right\", className, children, ...props }, ref) => (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n ref={ref}\n className={cn(sheetVariants({ side }), className)}\n {...props}\n >\n {children}\n <SheetPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\">\n <IconX className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </SheetPrimitive.Content>\n </SheetPortal>\n));\nSheetContent.displayName = SheetPrimitive.Content.displayName;\n\nconst SheetHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col space-y-2 text-center sm:text-left\",\n className,\n )}\n {...props}\n />\n);\nSheetHeader.displayName = \"SheetHeader\";\n\nconst SheetFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className,\n )}\n {...props}\n />\n);\nSheetFooter.displayName = \"SheetFooter\";\n\nconst SheetTitle = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Title\n ref={ref}\n className={cn(\"text-lg font-semibold text-foreground\", className)}\n {...props}\n />\n));\nSheetTitle.displayName = SheetPrimitive.Title.displayName;\n\nconst SheetDescription = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n));\nSheetDescription.displayName = SheetPrimitive.Description.displayName;\n\nexport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetOverlay,\n SheetPortal,\n SheetTitle,\n SheetTrigger,\n};\n"]}
@@ -7,7 +7,7 @@ import { cn } from "../../lib/utils.js";
7
7
  const ToastProvider = ToastPrimitives.Provider;
8
8
  const ToastViewport = React.forwardRef(({ className, ...props }, ref) => (_jsx(ToastPrimitives.Viewport, { ref: ref, className: cn("fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col sm:max-w-[36rem]", className), ...props })));
9
9
  ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
10
- const toastVariants = cva("group pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", {
10
+ const toastVariants = cva("group pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-transform motion-reduce:animate-none motion-reduce:transition-none data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", {
11
11
  variants: {
12
12
  variant: {
13
13
  default: "border bg-background text-foreground",
@@ -1 +1 @@
1
- {"version":3,"file":"toast.js","sourceRoot":"","sources":["../../../src/components/ui/toast.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst ToastProvider = ToastPrimitives.Provider;\n\nconst ToastViewport = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Viewport>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>\n>(({ className, ...props }, ref) => (\n <ToastPrimitives.Viewport\n ref={ref}\n className={cn(\n \"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col sm:max-w-[36rem]\",\n className,\n )}\n {...props}\n />\n));\nToastViewport.displayName = ToastPrimitives.Viewport.displayName;\n\nconst toastVariants = cva(\n \"group pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full\",\n {\n variants: {\n variant: {\n default: \"border bg-background text-foreground\",\n destructive:\n \"destructive group border-destructive bg-destructive text-destructive-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n },\n);\n\nconst Toast = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Root>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &\n VariantProps<typeof toastVariants>\n>(({ className, variant, ...props }, ref) => {\n return (\n <ToastPrimitives.Root\n ref={ref}\n className={cn(toastVariants({ variant }), className)}\n {...props}\n />\n );\n});\nToast.displayName = ToastPrimitives.Root.displayName;\n\nconst ToastAction = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Action>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>\n>(({ className, ...props }, ref) => (\n <ToastPrimitives.Action\n ref={ref}\n className={cn(\n \"inline-flex h-8 shrink-0 items-center whitespace-nowrap justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive\",\n className,\n )}\n {...props}\n />\n));\nToastAction.displayName = ToastPrimitives.Action.displayName;\n\nconst ToastClose = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Close>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>\n>(({ className, ...props }, ref) => (\n <ToastPrimitives.Close\n ref={ref}\n className={cn(\n \"absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600\",\n className,\n )}\n toast-close=\"\"\n {...props}\n >\n <IconX className=\"h-4 w-4\" />\n </ToastPrimitives.Close>\n));\nToastClose.displayName = ToastPrimitives.Close.displayName;\n\nconst ToastTitle = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Title>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>\n>(({ className, ...props }, ref) => (\n <ToastPrimitives.Title\n ref={ref}\n className={cn(\"break-words text-sm font-semibold\", className)}\n {...props}\n />\n));\nToastTitle.displayName = ToastPrimitives.Title.displayName;\n\nconst ToastDescription = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Description>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>\n>(({ className, ...props }, ref) => (\n <ToastPrimitives.Description\n ref={ref}\n className={cn(\"break-words text-sm opacity-90\", className)}\n {...props}\n />\n));\nToastDescription.displayName = ToastPrimitives.Description.displayName;\n\ntype ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;\n\ntype ToastActionElement = React.ReactElement<typeof ToastAction>;\n\nexport {\n type ToastProps,\n type ToastActionElement,\n ToastProvider,\n ToastViewport,\n Toast,\n ToastTitle,\n ToastDescription,\n ToastClose,\n ToastAction,\n};\n"]}
1
+ {"version":3,"file":"toast.js","sourceRoot":"","sources":["../../../src/components/ui/toast.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst ToastProvider = ToastPrimitives.Provider;\n\nconst ToastViewport = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Viewport>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>\n>(({ className, ...props }, ref) => (\n <ToastPrimitives.Viewport\n ref={ref}\n className={cn(\n \"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col sm:max-w-[36rem]\",\n className,\n )}\n {...props}\n />\n));\nToastViewport.displayName = ToastPrimitives.Viewport.displayName;\n\nconst toastVariants = cva(\n \"group pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-transform motion-reduce:animate-none motion-reduce:transition-none data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full\",\n {\n variants: {\n variant: {\n default: \"border bg-background text-foreground\",\n destructive:\n \"destructive group border-destructive bg-destructive text-destructive-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n },\n);\n\nconst Toast = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Root>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &\n VariantProps<typeof toastVariants>\n>(({ className, variant, ...props }, ref) => {\n return (\n <ToastPrimitives.Root\n ref={ref}\n className={cn(toastVariants({ variant }), className)}\n {...props}\n />\n );\n});\nToast.displayName = ToastPrimitives.Root.displayName;\n\nconst ToastAction = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Action>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>\n>(({ className, ...props }, ref) => (\n <ToastPrimitives.Action\n ref={ref}\n className={cn(\n \"inline-flex h-8 shrink-0 items-center whitespace-nowrap justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive\",\n className,\n )}\n {...props}\n />\n));\nToastAction.displayName = ToastPrimitives.Action.displayName;\n\nconst ToastClose = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Close>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>\n>(({ className, ...props }, ref) => (\n <ToastPrimitives.Close\n ref={ref}\n className={cn(\n \"absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600\",\n className,\n )}\n toast-close=\"\"\n {...props}\n >\n <IconX className=\"h-4 w-4\" />\n </ToastPrimitives.Close>\n));\nToastClose.displayName = ToastPrimitives.Close.displayName;\n\nconst ToastTitle = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Title>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>\n>(({ className, ...props }, ref) => (\n <ToastPrimitives.Title\n ref={ref}\n className={cn(\"break-words text-sm font-semibold\", className)}\n {...props}\n />\n));\nToastTitle.displayName = ToastPrimitives.Title.displayName;\n\nconst ToastDescription = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Description>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>\n>(({ className, ...props }, ref) => (\n <ToastPrimitives.Description\n ref={ref}\n className={cn(\"break-words text-sm opacity-90\", className)}\n {...props}\n />\n));\nToastDescription.displayName = ToastPrimitives.Description.displayName;\n\ntype ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;\n\ntype ToastActionElement = React.ReactElement<typeof ToastAction>;\n\nexport {\n type ToastProps,\n type ToastActionElement,\n ToastProvider,\n ToastViewport,\n Toast,\n ToastTitle,\n ToastDescription,\n ToastClose,\n ToastAction,\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-app-card.d.ts","sourceRoot":"","sources":["../../src/components/workspace-app-card.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,uBAAuB,CAAC;AAyB/B,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GACV,EAAE;IACD,GAAG,EAAE,mBAAmB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDAwOA"}
1
+ {"version":3,"file":"workspace-app-card.d.ts","sourceRoot":"","sources":["../../src/components/workspace-app-card.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,uBAAuB,CAAC;AA6B/B,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,GACV,EAAE;IACD,GAAG,EAAE,mBAAmB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,mDA0OA"}
@@ -1,10 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useActionMutation, useActionQuery } from "@agent-native/core/client";
3
- import { IconArrowUpRight, IconChevronDown, IconChevronRight, IconClockHour4, IconDots, IconEdit, IconEye, IconEyeOff, IconFileText, IconWorld, IconTrash, } from "@tabler/icons-react";
3
+ import { IconChevronDown, IconChevronRight, IconClockHour4, IconDots, IconEdit, IconEye, IconEyeOff, IconFileText, IconWorld, IconTrash, } from "@tabler/icons-react";
4
4
  import { useEffect, useState } from "react";
5
5
  import { toast } from "sonner";
6
6
  import { cn } from "../lib/utils.js";
7
7
  import { isPendingBuilderHref, workspaceAppHref, } from "../lib/workspace-apps.js";
8
+ import { ActionQueryError } from "./action-query-error.js";
8
9
  import { AppKeysPopover } from "./app-keys-popover.js";
9
10
  import { Badge } from "./ui/badge.js";
10
11
  import { Button } from "./ui/button.js";
@@ -15,6 +16,7 @@ import { Label } from "./ui/label.js";
15
16
  import { Textarea } from "./ui/textarea.js";
16
17
  import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip.js";
17
18
  import { AppResourceEffectiveStack } from "./workspace-resource-effective-stack.js";
19
+ const APP_CARD_ACTION_CLASS = "size-7 rounded-md p-0 text-muted-foreground transition-[background-color,color] hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:bg-accent data-[state=open]:text-foreground";
18
20
  export function WorkspaceAppCard({ app, className, }) {
19
21
  const href = workspaceAppHref(app);
20
22
  const openInNewTab = isPendingBuilderHref(app);
@@ -72,22 +74,23 @@ export function WorkspaceAppCard({ app, className, }) {
72
74
  description: draftDescription.trim(),
73
75
  });
74
76
  };
75
- return (_jsxs("div", { "aria-disabled": !href, className: cn("group relative rounded-lg border bg-card p-4 transition hover:border-foreground/30 aria-disabled:opacity-60", isArchived && "opacity-70", className), children: [href ? (_jsx("a", { href: href, target: openInNewTab ? "_blank" : undefined, rel: openInNewTab ? "noreferrer" : undefined, "aria-label": `Open ${app.name}`, className: "absolute inset-0 z-0 rounded-lg" })) : null, _jsxs("div", { className: "pointer-events-none relative z-10 flex h-full min-w-0 items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [_jsx("h3", { className: "min-w-0 flex-1 truncate text-sm font-semibold text-foreground", children: app.name }), isPending ? (_jsxs(Badge, { variant: "outline", className: "shrink-0 gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300", children: [_jsx(IconClockHour4, { size: 12 }), pendingLabel] })) : null, isArchived ? (_jsxs(Badge, { variant: "outline", className: "shrink-0 gap-1", children: [_jsx(IconEyeOff, { size: 12 }), "Hidden"] })) : null, audience === "public" ? (_jsxs(Badge, { variant: "outline", className: "shrink-0 gap-1", children: [_jsx(IconWorld, { size: 12 }), "Public"] })) : null] }), _jsx("p", { className: "mt-1 truncate font-mono text-xs text-muted-foreground", children: app.path }), isPending && app.branchName ? (_jsxs("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: ["Builder branch: ", app.branchName] })) : null, app.description ? (_jsx("p", { className: "mt-2 line-clamp-2 text-xs leading-relaxed text-muted-foreground", children: app.description })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [!isPending && !isArchived ? (_jsx("div", { className: "pointer-events-auto", children: _jsx(AppResourcesDialog, { app: app }) })) : null, !isPending && !isArchived ? (_jsx("div", { className: "pointer-events-auto", children: _jsx(AppKeysPopover, { appId: app.id, appName: app.name }) })) : null, _jsx("div", { className: "pointer-events-auto", children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": `More actions for ${app.name}`, className: "inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-md text-muted-foreground opacity-0 transition hover:bg-accent hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100 data-[state=open]:opacity-100", onClick: (e) => e.stopPropagation(), children: _jsx(IconDots, { size: 15 }) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-44", children: [_jsxs(DropdownMenuItem, { onSelect: (event) => {
77
+ return (_jsxs("div", { "aria-disabled": !href, className: cn("group relative rounded-xl border border-border/60 bg-card/40 p-4 transition-[background-color,border-color] hover:border-foreground/20 hover:bg-accent/15 focus-within:border-foreground/20 focus-within:bg-accent/15 aria-disabled:opacity-60", isArchived && "opacity-70", className), children: [href ? (_jsx("a", { href: href, target: openInNewTab ? "_blank" : undefined, rel: openInNewTab ? "noreferrer" : undefined, "aria-label": `Open ${app.name}`, className: "absolute inset-0 z-0 rounded-xl outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background" })) : null, _jsxs("div", { className: "pointer-events-none relative z-10 flex h-full min-w-0 items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [_jsx("h3", { className: "min-w-0 flex-1 truncate text-sm font-semibold text-foreground", children: app.name }), isPending ? (_jsxs(Badge, { variant: "outline", className: "shrink-0 gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300", children: [_jsx(IconClockHour4, { size: 12 }), pendingLabel] })) : null, isArchived ? (_jsxs(Badge, { variant: "outline", className: "shrink-0 gap-1", children: [_jsx(IconEyeOff, { size: 12 }), "Hidden"] })) : null, audience === "public" ? (_jsxs(Badge, { variant: "outline", className: "shrink-0 gap-1", children: [_jsx(IconWorld, { size: 12 }), "Public"] })) : null] }), _jsx("p", { className: "mt-1 truncate font-mono text-[11px] text-muted-foreground", children: app.path }), isPending && app.branchName ? (_jsxs("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: ["Builder branch: ", app.branchName] })) : null, app.description ? (_jsx("p", { className: "mt-2 min-h-10 line-clamp-2 text-[13px] leading-5 text-muted-foreground", children: app.description })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [!isPending && !isArchived ? (_jsx("div", { className: "pointer-events-auto", children: _jsx(AppResourcesDialog, { app: app }) })) : null, !isPending && !isArchived ? (_jsx("div", { className: "pointer-events-auto", children: _jsx(AppKeysPopover, { appId: app.id, appName: app.name }) })) : null, _jsx("div", { className: "pointer-events-auto", children: _jsxs(DropdownMenu, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": `More actions for ${app.name}`, className: cn(APP_CARD_ACTION_CLASS, "inline-flex cursor-pointer items-center justify-center"), onClick: (e) => e.stopPropagation(), children: _jsx(IconDots, { size: 15 }) }) }) }), _jsx(TooltipContent, { children: "More actions" })] }), _jsxs(DropdownMenuContent, { align: "end", className: "w-44", children: [_jsxs(DropdownMenuItem, { onSelect: (event) => {
76
78
  event.preventDefault();
77
79
  setEditOpen(true);
78
- }, children: [_jsx(IconEdit, { size: 14, className: "mr-2" }), "Edit details"] }), isPending ? (_jsxs(DropdownMenuItem, { onSelect: handleRemovePending, className: "text-red-600 focus:text-red-600 dark:text-red-400 dark:focus:text-red-400", children: [_jsx(IconTrash, { size: 14, className: "mr-2" }), "Remove from list"] })) : isArchived ? (_jsxs(DropdownMenuItem, { onSelect: handleUnarchive, children: [_jsx(IconEye, { size: 14, className: "mr-2" }), "Restore to list"] })) : (_jsxs(DropdownMenuItem, { onSelect: handleArchive, children: [_jsx(IconEyeOff, { size: 14, className: "mr-2" }), "Hide from list"] }))] })] }) }), href && !isArchived ? (_jsx(IconArrowUpRight, { size: 16, className: "text-muted-foreground transition group-hover:text-foreground" })) : null] })] }), _jsx(Dialog, { open: editOpen, onOpenChange: setEditOpen, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Edit app details" }) }), _jsxs("form", { className: "space-y-4", onSubmit: handleMetadataSubmit, children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `app-name-${app.id}`, children: "Name" }), _jsx(Input, { id: `app-name-${app.id}`, value: draftName, maxLength: 120, onChange: (event) => setDraftName(event.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `app-description-${app.id}`, children: "Description" }), _jsx(Textarea, { id: `app-description-${app.id}`, value: draftDescription, maxLength: 500, rows: 4, onChange: (event) => setDraftDescription(event.target.value) })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "outline", onClick: () => setEditOpen(false), children: "Cancel" }), _jsx(Button, { type: "submit", disabled: updateMetadata.isPending, children: updateMetadata.isPending ? "Saving..." : "Save" })] })] })] }) })] }));
80
+ }, children: [_jsx(IconEdit, { size: 14, className: "mr-2" }), "Edit details"] }), isPending ? (_jsxs(DropdownMenuItem, { onSelect: handleRemovePending, className: "text-red-600 focus:text-red-600 dark:text-red-400 dark:focus:text-red-400", children: [_jsx(IconTrash, { size: 14, className: "mr-2" }), "Remove from list"] })) : isArchived ? (_jsxs(DropdownMenuItem, { onSelect: handleUnarchive, children: [_jsx(IconEye, { size: 14, className: "mr-2" }), "Restore to list"] })) : (_jsxs(DropdownMenuItem, { onSelect: handleArchive, children: [_jsx(IconEyeOff, { size: 14, className: "mr-2" }), "Hide from list"] }))] })] }) })] })] }), _jsx(Dialog, { open: editOpen, onOpenChange: setEditOpen, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Edit app details" }) }), _jsxs("form", { className: "space-y-4", onSubmit: handleMetadataSubmit, children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `app-name-${app.id}`, children: "Name" }), _jsx(Input, { id: `app-name-${app.id}`, value: draftName, maxLength: 120, onChange: (event) => setDraftName(event.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `app-description-${app.id}`, children: "Description" }), _jsx(Textarea, { id: `app-description-${app.id}`, value: draftDescription, maxLength: 500, rows: 4, onChange: (event) => setDraftDescription(event.target.value) })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "outline", onClick: () => setEditOpen(false), children: "Cancel" }), _jsx(Button, { type: "submit", disabled: updateMetadata.isPending, children: updateMetadata.isPending ? "Saving..." : "Save" })] })] })] }) })] }));
79
81
  }
80
82
  function AppResourcesDialog({ app }) {
81
83
  const [open, setOpen] = useState(false);
82
84
  const [inspectedResourceId, setInspectedResourceId] = useState(null);
83
- const { data, isLoading } = useActionQuery("list-workspace-resources-for-app", { appId: app.id }, { enabled: open });
85
+ const query = useActionQuery("list-workspace-resources-for-app", { appId: app.id }, { enabled: open });
86
+ const { data, isLoading } = query;
84
87
  const resources = (data?.resources ?? []);
85
88
  const counts = data?.counts;
86
89
  return (_jsxs(Dialog, { open: open, onOpenChange: (nextOpen) => {
87
90
  setOpen(nextOpen);
88
91
  if (!nextOpen)
89
92
  setInspectedResourceId(null);
90
- }, children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(DialogTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": `View context resources for ${app.name}`, className: "h-7 w-7 p-0", onClick: (e) => e.stopPropagation(), children: _jsx(IconFileText, { size: 14 }) }) }) }), _jsx(TooltipContent, { children: "Context" })] }), _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: [app.name, " workspace resources"] }), _jsx(DialogDescription, { children: "Workspace-level resources are inherited at runtime. App shared and personal resources can override them locally." })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "rounded-lg border bg-muted/30 px-3 py-2 text-xs leading-relaxed text-muted-foreground", children: "All-app resources live once at workspace scope and are read by each app agent when it builds context. Nothing is copied into this app." }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs(Badge, { variant: "secondary", children: [counts?.total ?? 0, " total"] }), _jsxs(Badge, { variant: "outline", children: [counts?.workspace ?? counts?.global ?? 0, " workspace"] }), _jsxs(Badge, { variant: "outline", children: [counts?.granted ?? 0, " granted"] }), _jsxs(Badge, { variant: "outline", children: [counts?.autoLoaded ?? 0, " auto-loaded"] })] }), isLoading ? (_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "h-14 rounded-lg border bg-muted/30" }), _jsx("div", { className: "h-14 rounded-lg border bg-muted/30" }), _jsx("div", { className: "h-14 rounded-lg border bg-muted/30" })] })) : resources.length === 0 ? (_jsx("div", { className: "rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground", children: "No workspace or granted resources are visible to this app yet." })) : (_jsx("div", { className: "max-h-[420px] space-y-2 overflow-y-auto pr-1", children: resources.map((resource) => {
93
+ }, children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(DialogTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": `View context resources for ${app.name}`, className: APP_CARD_ACTION_CLASS, onClick: (e) => e.stopPropagation(), children: _jsx(IconFileText, { size: 14 }) }) }) }), _jsx(TooltipContent, { children: "View context" })] }), _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: [app.name, " workspace resources"] }), _jsx(DialogDescription, { children: "Workspace-level resources are inherited at runtime. App shared and personal resources can override them locally." })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "rounded-lg border bg-muted/30 px-3 py-2 text-xs leading-relaxed text-muted-foreground", children: "All-app resources live once at workspace scope and are read by each app agent when it builds context. Nothing is copied into this app." }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs(Badge, { variant: "secondary", children: [counts?.total ?? 0, " total"] }), _jsxs(Badge, { variant: "outline", children: [counts?.workspace ?? counts?.global ?? 0, " workspace"] }), _jsxs(Badge, { variant: "outline", children: [counts?.granted ?? 0, " granted"] }), _jsxs(Badge, { variant: "outline", children: [counts?.autoLoaded ?? 0, " auto-loaded"] })] }), query.isError ? (_jsx(ActionQueryError, { error: query.error, onRetry: () => void query.refetch() })) : isLoading ? (_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "h-14 rounded-lg border bg-muted/30" }), _jsx("div", { className: "h-14 rounded-lg border bg-muted/30" }), _jsx("div", { className: "h-14 rounded-lg border bg-muted/30" })] })) : resources.length === 0 ? (_jsx("div", { className: "rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground", children: "No workspace or granted resources are visible to this app yet." })) : (_jsx("div", { className: "max-h-[420px] space-y-2 overflow-y-auto pr-1", children: resources.map((resource) => {
91
94
  const inspected = inspectedResourceId === resource.id;
92
95
  return (_jsxs("div", { className: "rounded-lg border px-3 py-3", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: resource.name }), _jsx(Badge, { variant: "secondary", children: resource.kind }), _jsx(Badge, { variant: "outline", children: resource.source === "workspace"
93
96
  ? "All apps"
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-app-card.js","sourceRoot":"","sources":["../../src/components/workspace-app-card.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionMutation, useActionQuery } from \"@agent-native/core/client\";\nimport {\n IconArrowUpRight,\n IconChevronDown,\n IconChevronRight,\n IconClockHour4,\n IconDots,\n IconEdit,\n IconEye,\n IconEyeOff,\n IconFileText,\n IconWorld,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { useEffect, useState, type FormEvent } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { cn } from \"../lib/utils\";\nimport {\n isPendingBuilderHref,\n workspaceAppHref,\n type WorkspaceAppSummary,\n} from \"../lib/workspace-apps\";\nimport { AppKeysPopover } from \"./app-keys-popover\";\nimport { Badge } from \"./ui/badge\";\nimport { Button } from \"./ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"./ui/dialog\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"./ui/dropdown-menu\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport { Textarea } from \"./ui/textarea\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"./ui/tooltip\";\nimport { AppResourceEffectiveStack } from \"./workspace-resource-effective-stack\";\n\nexport function WorkspaceAppCard({\n app,\n className,\n}: {\n app: WorkspaceAppSummary;\n className?: string;\n}) {\n const href = workspaceAppHref(app);\n const openInNewTab = isPendingBuilderHref(app);\n const isPending = app.status === \"pending\";\n const pendingLabel = app.statusLabel || \"Builder branch\";\n const isArchived = !!app.archived;\n const audience = app.audience ?? \"internal\";\n const [editOpen, setEditOpen] = useState(false);\n const [draftName, setDraftName] = useState(app.name);\n const [draftDescription, setDraftDescription] = useState(\n app.description || \"\",\n );\n\n useEffect(() => {\n if (editOpen) return;\n setDraftName(app.name);\n setDraftDescription(app.description || \"\");\n }, [app.description, app.name, editOpen]);\n\n const archive = useActionMutation(\"archive-workspace-app\", {\n onError: (err) =>\n toast.error(`Could not hide ${app.name}: ${stringifyError(err)}`),\n });\n const unarchive = useActionMutation(\"unarchive-workspace-app\", {\n onError: (err) =>\n toast.error(`Could not restore ${app.name}: ${stringifyError(err)}`),\n });\n const removePending = useActionMutation(\"remove-pending-workspace-app\", {\n onError: (err) =>\n toast.error(`Could not remove ${app.name}: ${stringifyError(err)}`),\n });\n const updateMetadata = useActionMutation(\"update-workspace-app-metadata\", {\n onSuccess: () => {\n toast.success(`Updated ${draftName.trim() || app.name}`);\n setEditOpen(false);\n },\n onError: (err) =>\n toast.error(`Could not update ${app.name}: ${stringifyError(err)}`),\n });\n\n const handleArchive = () => {\n archive.mutate({ appId: app.id });\n toast.success(`Hid ${app.name} from the Apps list`);\n };\n const handleUnarchive = () => {\n unarchive.mutate({ appId: app.id });\n toast.success(`Restored ${app.name} to the Apps list`);\n };\n const handleRemovePending = () => {\n removePending.mutate({ appId: app.id });\n toast.success(`Removed pending ${app.name}`);\n };\n const handleMetadataSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const name = draftName.trim();\n if (!name) {\n toast.error(\"App name is required.\");\n return;\n }\n updateMetadata.mutate({\n appId: app.id,\n name,\n description: draftDescription.trim(),\n });\n };\n\n return (\n <div\n aria-disabled={!href}\n className={cn(\n \"group relative rounded-lg border bg-card p-4 transition hover:border-foreground/30 aria-disabled:opacity-60\",\n isArchived && \"opacity-70\",\n className,\n )}\n >\n {href ? (\n <a\n href={href}\n target={openInNewTab ? \"_blank\" : undefined}\n rel={openInNewTab ? \"noreferrer\" : undefined}\n aria-label={`Open ${app.name}`}\n className=\"absolute inset-0 z-0 rounded-lg\"\n />\n ) : null}\n\n <div className=\"pointer-events-none relative z-10 flex h-full min-w-0 items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex min-w-0 flex-wrap items-center gap-1.5\">\n <h3 className=\"min-w-0 flex-1 truncate text-sm font-semibold text-foreground\">\n {app.name}\n </h3>\n {isPending ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n <IconClockHour4 size={12} />\n {pendingLabel}\n </Badge>\n ) : null}\n {isArchived ? (\n <Badge variant=\"outline\" className=\"shrink-0 gap-1\">\n <IconEyeOff size={12} />\n Hidden\n </Badge>\n ) : null}\n {audience === \"public\" ? (\n <Badge variant=\"outline\" className=\"shrink-0 gap-1\">\n <IconWorld size={12} />\n Public\n </Badge>\n ) : null}\n </div>\n <p className=\"mt-1 truncate font-mono text-xs text-muted-foreground\">\n {app.path}\n </p>\n {isPending && app.branchName ? (\n <p className=\"mt-1 truncate text-xs text-muted-foreground\">\n Builder branch: {app.branchName}\n </p>\n ) : null}\n {app.description ? (\n <p className=\"mt-2 line-clamp-2 text-xs leading-relaxed text-muted-foreground\">\n {app.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {!isPending && !isArchived ? (\n <div className=\"pointer-events-auto\">\n <AppResourcesDialog app={app} />\n </div>\n ) : null}\n {!isPending && !isArchived ? (\n <div className=\"pointer-events-auto\">\n <AppKeysPopover appId={app.id} appName={app.name} />\n </div>\n ) : null}\n <div className=\"pointer-events-auto\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label={`More actions for ${app.name}`}\n className=\"inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-md text-muted-foreground opacity-0 transition hover:bg-accent hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100 data-[state=open]:opacity-100\"\n onClick={(e) => e.stopPropagation()}\n >\n <IconDots size={15} />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-44\">\n <DropdownMenuItem\n onSelect={(event) => {\n event.preventDefault();\n setEditOpen(true);\n }}\n >\n <IconEdit size={14} className=\"mr-2\" />\n Edit details\n </DropdownMenuItem>\n {isPending ? (\n <DropdownMenuItem\n onSelect={handleRemovePending}\n className=\"text-red-600 focus:text-red-600 dark:text-red-400 dark:focus:text-red-400\"\n >\n <IconTrash size={14} className=\"mr-2\" />\n Remove from list\n </DropdownMenuItem>\n ) : isArchived ? (\n <DropdownMenuItem onSelect={handleUnarchive}>\n <IconEye size={14} className=\"mr-2\" />\n Restore to list\n </DropdownMenuItem>\n ) : (\n <DropdownMenuItem onSelect={handleArchive}>\n <IconEyeOff size={14} className=\"mr-2\" />\n Hide from list\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n {href && !isArchived ? (\n <IconArrowUpRight\n size={16}\n className=\"text-muted-foreground transition group-hover:text-foreground\"\n />\n ) : null}\n </div>\n </div>\n <Dialog open={editOpen} onOpenChange={setEditOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Edit app details</DialogTitle>\n </DialogHeader>\n <form className=\"space-y-4\" onSubmit={handleMetadataSubmit}>\n <div className=\"space-y-2\">\n <Label htmlFor={`app-name-${app.id}`}>Name</Label>\n <Input\n id={`app-name-${app.id}`}\n value={draftName}\n maxLength={120}\n onChange={(event) => setDraftName(event.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor={`app-description-${app.id}`}>Description</Label>\n <Textarea\n id={`app-description-${app.id}`}\n value={draftDescription}\n maxLength={500}\n rows={4}\n onChange={(event) => setDraftDescription(event.target.value)}\n />\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setEditOpen(false)}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={updateMetadata.isPending}>\n {updateMetadata.isPending ? \"Saving...\" : \"Save\"}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n </div>\n );\n}\n\nfunction AppResourcesDialog({ app }: { app: WorkspaceAppSummary }) {\n const [open, setOpen] = useState(false);\n const [inspectedResourceId, setInspectedResourceId] = useState<string | null>(\n null,\n );\n const { data, isLoading } = useActionQuery(\n \"list-workspace-resources-for-app\",\n { appId: app.id },\n { enabled: open },\n );\n\n const resources = ((data as any)?.resources ?? []) as any[];\n const counts = (data as any)?.counts;\n\n return (\n <Dialog\n open={open}\n onOpenChange={(nextOpen) => {\n setOpen(nextOpen);\n if (!nextOpen) setInspectedResourceId(null);\n }}\n >\n <Tooltip>\n <TooltipTrigger asChild>\n <DialogTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n aria-label={`View context resources for ${app.name}`}\n className=\"h-7 w-7 p-0\"\n onClick={(e) => e.stopPropagation()}\n >\n <IconFileText size={14} />\n </Button>\n </DialogTrigger>\n </TooltipTrigger>\n <TooltipContent>Context</TooltipContent>\n </Tooltip>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{app.name} workspace resources</DialogTitle>\n <DialogDescription>\n Workspace-level resources are inherited at runtime. App shared and\n personal resources can override them locally.\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4\">\n <div className=\"rounded-lg border bg-muted/30 px-3 py-2 text-xs leading-relaxed text-muted-foreground\">\n All-app resources live once at workspace scope and are read by each\n app agent when it builds context. Nothing is copied into this app.\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"secondary\">{counts?.total ?? 0} total</Badge>\n <Badge variant=\"outline\">\n {counts?.workspace ?? counts?.global ?? 0} workspace\n </Badge>\n <Badge variant=\"outline\">{counts?.granted ?? 0} granted</Badge>\n <Badge variant=\"outline\">\n {counts?.autoLoaded ?? 0} auto-loaded\n </Badge>\n </div>\n\n {isLoading ? (\n <div className=\"space-y-2\">\n <div className=\"h-14 rounded-lg border bg-muted/30\" />\n <div className=\"h-14 rounded-lg border bg-muted/30\" />\n <div className=\"h-14 rounded-lg border bg-muted/30\" />\n </div>\n ) : resources.length === 0 ? (\n <div className=\"rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground\">\n No workspace or granted resources are visible to this app yet.\n </div>\n ) : (\n <div className=\"max-h-[420px] space-y-2 overflow-y-auto pr-1\">\n {resources.map((resource) => {\n const inspected = inspectedResourceId === resource.id;\n return (\n <div\n key={resource.id}\n className=\"rounded-lg border px-3 py-3\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {resource.name}\n </span>\n <Badge variant=\"secondary\">{resource.kind}</Badge>\n <Badge variant=\"outline\">\n {resource.source === \"workspace\"\n ? \"All apps\"\n : \"Granted\"}\n </Badge>\n {resource.autoLoaded ? (\n <Badge variant=\"outline\">Auto-loaded</Badge>\n ) : null}\n </div>\n <div className=\"mt-1 truncate font-mono text-xs text-muted-foreground\">\n {resource.path}\n </div>\n </div>\n <div className=\"flex shrink-0 flex-col items-end gap-2\">\n {resource.source === \"grant\" ? (\n <div className=\"text-right text-[11px] text-muted-foreground\">\n Selected grant\n </div>\n ) : null}\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2 text-xs\"\n onClick={(event) => {\n event.stopPropagation();\n setInspectedResourceId(\n inspected ? null : resource.id,\n );\n }}\n >\n {inspected ? (\n <IconChevronDown size={14} className=\"mr-1\" />\n ) : (\n <IconChevronRight size={14} className=\"mr-1\" />\n )}\n Stack\n </Button>\n </div>\n </div>\n\n {resource.description ? (\n <p className=\"mt-2 line-clamp-2 text-xs text-muted-foreground\">\n {resource.description}\n </p>\n ) : null}\n\n {inspected ? (\n <AppResourceEffectiveStack\n appId={app.id}\n resource={resource}\n />\n ) : null}\n </div>\n );\n })}\n </div>\n )}\n </div>\n <DialogFooter>\n <Button type=\"button\" onClick={() => setOpen(false)}>\n Done\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction stringifyError(err: unknown): string {\n if (err instanceof Error) return err.message;\n return String(err);\n}\n"]}
1
+ {"version":3,"file":"workspace-app-card.js","sourceRoot":"","sources":["../../src/components/workspace-app-card.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionMutation, useActionQuery } from \"@agent-native/core/client\";\nimport {\n IconChevronDown,\n IconChevronRight,\n IconClockHour4,\n IconDots,\n IconEdit,\n IconEye,\n IconEyeOff,\n IconFileText,\n IconWorld,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { useEffect, useState, type FormEvent } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { cn } from \"../lib/utils\";\nimport {\n isPendingBuilderHref,\n workspaceAppHref,\n type WorkspaceAppSummary,\n} from \"../lib/workspace-apps\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport { AppKeysPopover } from \"./app-keys-popover\";\nimport { Badge } from \"./ui/badge\";\nimport { Button } from \"./ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"./ui/dialog\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"./ui/dropdown-menu\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport { Textarea } from \"./ui/textarea\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"./ui/tooltip\";\nimport { AppResourceEffectiveStack } from \"./workspace-resource-effective-stack\";\n\nconst APP_CARD_ACTION_CLASS =\n \"size-7 rounded-md p-0 text-muted-foreground transition-[background-color,color] hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:bg-accent data-[state=open]:text-foreground\";\n\nexport function WorkspaceAppCard({\n app,\n className,\n}: {\n app: WorkspaceAppSummary;\n className?: string;\n}) {\n const href = workspaceAppHref(app);\n const openInNewTab = isPendingBuilderHref(app);\n const isPending = app.status === \"pending\";\n const pendingLabel = app.statusLabel || \"Builder branch\";\n const isArchived = !!app.archived;\n const audience = app.audience ?? \"internal\";\n const [editOpen, setEditOpen] = useState(false);\n const [draftName, setDraftName] = useState(app.name);\n const [draftDescription, setDraftDescription] = useState(\n app.description || \"\",\n );\n\n useEffect(() => {\n if (editOpen) return;\n setDraftName(app.name);\n setDraftDescription(app.description || \"\");\n }, [app.description, app.name, editOpen]);\n\n const archive = useActionMutation(\"archive-workspace-app\", {\n onError: (err) =>\n toast.error(`Could not hide ${app.name}: ${stringifyError(err)}`),\n });\n const unarchive = useActionMutation(\"unarchive-workspace-app\", {\n onError: (err) =>\n toast.error(`Could not restore ${app.name}: ${stringifyError(err)}`),\n });\n const removePending = useActionMutation(\"remove-pending-workspace-app\", {\n onError: (err) =>\n toast.error(`Could not remove ${app.name}: ${stringifyError(err)}`),\n });\n const updateMetadata = useActionMutation(\"update-workspace-app-metadata\", {\n onSuccess: () => {\n toast.success(`Updated ${draftName.trim() || app.name}`);\n setEditOpen(false);\n },\n onError: (err) =>\n toast.error(`Could not update ${app.name}: ${stringifyError(err)}`),\n });\n\n const handleArchive = () => {\n archive.mutate({ appId: app.id });\n toast.success(`Hid ${app.name} from the Apps list`);\n };\n const handleUnarchive = () => {\n unarchive.mutate({ appId: app.id });\n toast.success(`Restored ${app.name} to the Apps list`);\n };\n const handleRemovePending = () => {\n removePending.mutate({ appId: app.id });\n toast.success(`Removed pending ${app.name}`);\n };\n const handleMetadataSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const name = draftName.trim();\n if (!name) {\n toast.error(\"App name is required.\");\n return;\n }\n updateMetadata.mutate({\n appId: app.id,\n name,\n description: draftDescription.trim(),\n });\n };\n\n return (\n <div\n aria-disabled={!href}\n className={cn(\n \"group relative rounded-xl border border-border/60 bg-card/40 p-4 transition-[background-color,border-color] hover:border-foreground/20 hover:bg-accent/15 focus-within:border-foreground/20 focus-within:bg-accent/15 aria-disabled:opacity-60\",\n isArchived && \"opacity-70\",\n className,\n )}\n >\n {href ? (\n <a\n href={href}\n target={openInNewTab ? \"_blank\" : undefined}\n rel={openInNewTab ? \"noreferrer\" : undefined}\n aria-label={`Open ${app.name}`}\n className=\"absolute inset-0 z-0 rounded-xl outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n />\n ) : null}\n\n <div className=\"pointer-events-none relative z-10 flex h-full min-w-0 items-start justify-between gap-3\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex min-w-0 flex-wrap items-center gap-1.5\">\n <h3 className=\"min-w-0 flex-1 truncate text-sm font-semibold text-foreground\">\n {app.name}\n </h3>\n {isPending ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n <IconClockHour4 size={12} />\n {pendingLabel}\n </Badge>\n ) : null}\n {isArchived ? (\n <Badge variant=\"outline\" className=\"shrink-0 gap-1\">\n <IconEyeOff size={12} />\n Hidden\n </Badge>\n ) : null}\n {audience === \"public\" ? (\n <Badge variant=\"outline\" className=\"shrink-0 gap-1\">\n <IconWorld size={12} />\n Public\n </Badge>\n ) : null}\n </div>\n <p className=\"mt-1 truncate font-mono text-[11px] text-muted-foreground\">\n {app.path}\n </p>\n {isPending && app.branchName ? (\n <p className=\"mt-1 truncate text-xs text-muted-foreground\">\n Builder branch: {app.branchName}\n </p>\n ) : null}\n {app.description ? (\n <p className=\"mt-2 min-h-10 line-clamp-2 text-[13px] leading-5 text-muted-foreground\">\n {app.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {!isPending && !isArchived ? (\n <div className=\"pointer-events-auto\">\n <AppResourcesDialog app={app} />\n </div>\n ) : null}\n {!isPending && !isArchived ? (\n <div className=\"pointer-events-auto\">\n <AppKeysPopover appId={app.id} appName={app.name} />\n </div>\n ) : null}\n <div className=\"pointer-events-auto\">\n <DropdownMenu>\n <Tooltip>\n <TooltipTrigger asChild>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label={`More actions for ${app.name}`}\n className={cn(\n APP_CARD_ACTION_CLASS,\n \"inline-flex cursor-pointer items-center justify-center\",\n )}\n onClick={(e) => e.stopPropagation()}\n >\n <IconDots size={15} />\n </button>\n </DropdownMenuTrigger>\n </TooltipTrigger>\n <TooltipContent>More actions</TooltipContent>\n </Tooltip>\n <DropdownMenuContent align=\"end\" className=\"w-44\">\n <DropdownMenuItem\n onSelect={(event) => {\n event.preventDefault();\n setEditOpen(true);\n }}\n >\n <IconEdit size={14} className=\"mr-2\" />\n Edit details\n </DropdownMenuItem>\n {isPending ? (\n <DropdownMenuItem\n onSelect={handleRemovePending}\n className=\"text-red-600 focus:text-red-600 dark:text-red-400 dark:focus:text-red-400\"\n >\n <IconTrash size={14} className=\"mr-2\" />\n Remove from list\n </DropdownMenuItem>\n ) : isArchived ? (\n <DropdownMenuItem onSelect={handleUnarchive}>\n <IconEye size={14} className=\"mr-2\" />\n Restore to list\n </DropdownMenuItem>\n ) : (\n <DropdownMenuItem onSelect={handleArchive}>\n <IconEyeOff size={14} className=\"mr-2\" />\n Hide from list\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n </div>\n <Dialog open={editOpen} onOpenChange={setEditOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Edit app details</DialogTitle>\n </DialogHeader>\n <form className=\"space-y-4\" onSubmit={handleMetadataSubmit}>\n <div className=\"space-y-2\">\n <Label htmlFor={`app-name-${app.id}`}>Name</Label>\n <Input\n id={`app-name-${app.id}`}\n value={draftName}\n maxLength={120}\n onChange={(event) => setDraftName(event.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor={`app-description-${app.id}`}>Description</Label>\n <Textarea\n id={`app-description-${app.id}`}\n value={draftDescription}\n maxLength={500}\n rows={4}\n onChange={(event) => setDraftDescription(event.target.value)}\n />\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setEditOpen(false)}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={updateMetadata.isPending}>\n {updateMetadata.isPending ? \"Saving...\" : \"Save\"}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n </div>\n );\n}\n\nfunction AppResourcesDialog({ app }: { app: WorkspaceAppSummary }) {\n const [open, setOpen] = useState(false);\n const [inspectedResourceId, setInspectedResourceId] = useState<string | null>(\n null,\n );\n const query = useActionQuery(\n \"list-workspace-resources-for-app\",\n { appId: app.id },\n { enabled: open },\n );\n const { data, isLoading } = query;\n\n const resources = ((data as any)?.resources ?? []) as any[];\n const counts = (data as any)?.counts;\n\n return (\n <Dialog\n open={open}\n onOpenChange={(nextOpen) => {\n setOpen(nextOpen);\n if (!nextOpen) setInspectedResourceId(null);\n }}\n >\n <Tooltip>\n <TooltipTrigger asChild>\n <DialogTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n aria-label={`View context resources for ${app.name}`}\n className={APP_CARD_ACTION_CLASS}\n onClick={(e) => e.stopPropagation()}\n >\n <IconFileText size={14} />\n </Button>\n </DialogTrigger>\n </TooltipTrigger>\n <TooltipContent>View context</TooltipContent>\n </Tooltip>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{app.name} workspace resources</DialogTitle>\n <DialogDescription>\n Workspace-level resources are inherited at runtime. App shared and\n personal resources can override them locally.\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4\">\n <div className=\"rounded-lg border bg-muted/30 px-3 py-2 text-xs leading-relaxed text-muted-foreground\">\n All-app resources live once at workspace scope and are read by each\n app agent when it builds context. Nothing is copied into this app.\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"secondary\">{counts?.total ?? 0} total</Badge>\n <Badge variant=\"outline\">\n {counts?.workspace ?? counts?.global ?? 0} workspace\n </Badge>\n <Badge variant=\"outline\">{counts?.granted ?? 0} granted</Badge>\n <Badge variant=\"outline\">\n {counts?.autoLoaded ?? 0} auto-loaded\n </Badge>\n </div>\n\n {query.isError ? (\n <ActionQueryError\n error={query.error}\n onRetry={() => void query.refetch()}\n />\n ) : isLoading ? (\n <div className=\"space-y-2\">\n <div className=\"h-14 rounded-lg border bg-muted/30\" />\n <div className=\"h-14 rounded-lg border bg-muted/30\" />\n <div className=\"h-14 rounded-lg border bg-muted/30\" />\n </div>\n ) : resources.length === 0 ? (\n <div className=\"rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground\">\n No workspace or granted resources are visible to this app yet.\n </div>\n ) : (\n <div className=\"max-h-[420px] space-y-2 overflow-y-auto pr-1\">\n {resources.map((resource) => {\n const inspected = inspectedResourceId === resource.id;\n return (\n <div\n key={resource.id}\n className=\"rounded-lg border px-3 py-3\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {resource.name}\n </span>\n <Badge variant=\"secondary\">{resource.kind}</Badge>\n <Badge variant=\"outline\">\n {resource.source === \"workspace\"\n ? \"All apps\"\n : \"Granted\"}\n </Badge>\n {resource.autoLoaded ? (\n <Badge variant=\"outline\">Auto-loaded</Badge>\n ) : null}\n </div>\n <div className=\"mt-1 truncate font-mono text-xs text-muted-foreground\">\n {resource.path}\n </div>\n </div>\n <div className=\"flex shrink-0 flex-col items-end gap-2\">\n {resource.source === \"grant\" ? (\n <div className=\"text-right text-[11px] text-muted-foreground\">\n Selected grant\n </div>\n ) : null}\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2 text-xs\"\n onClick={(event) => {\n event.stopPropagation();\n setInspectedResourceId(\n inspected ? null : resource.id,\n );\n }}\n >\n {inspected ? (\n <IconChevronDown size={14} className=\"mr-1\" />\n ) : (\n <IconChevronRight size={14} className=\"mr-1\" />\n )}\n Stack\n </Button>\n </div>\n </div>\n\n {resource.description ? (\n <p className=\"mt-2 line-clamp-2 text-xs text-muted-foreground\">\n {resource.description}\n </p>\n ) : null}\n\n {inspected ? (\n <AppResourceEffectiveStack\n appId={app.id}\n resource={resource}\n />\n ) : null}\n </div>\n );\n })}\n </div>\n )}\n </div>\n <DialogFooter>\n <Button type=\"button\" onClick={() => setOpen(false)}>\n Done\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction stringifyError(err: unknown): string {\n if (err instanceof Error) return err.message;\n return String(err);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-resource-effective-stack.d.ts","sourceRoot":"","sources":["../../src/components/workspace-resource-effective-stack.tsx"],"names":[],"mappings":"AAKA,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,+GAelD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAiBA;AAED,wBAAgB,uBAAuB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGrE;AAED,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,GAAG,CAAC;CACf,mDAsFA"}
1
+ {"version":3,"file":"workspace-resource-effective-stack.d.ts","sourceRoot":"","sources":["../../src/components/workspace-resource-effective-stack.tsx"],"names":[],"mappings":"AAMA,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,+GAelD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAiBA;AAED,wBAAgB,uBAAuB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGrE;AAED,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,GAAG,CAAC;CACf,mDAiGA"}
@@ -1,6 +1,7 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useActionQuery } from "@agent-native/core/client";
3
3
  import { cn } from "../lib/utils.js";
4
+ import { ActionQueryError } from "./action-query-error.js";
4
5
  import { Badge } from "./ui/badge.js";
5
6
  export function appAvailabilityLabel(value) {
6
7
  switch (value) {
@@ -42,13 +43,17 @@ export function formatResourceTimestamp(value) {
42
43
  return new Date(value).toLocaleString();
43
44
  }
44
45
  export function AppResourceEffectiveStack({ appId, resource, }) {
45
- const { data: context, isLoading } = useActionQuery("get-workspace-resource-effective-context", { resourceId: resource.id, appId }, { enabled: !!resource.id });
46
+ const query = useActionQuery("get-workspace-resource-effective-context", { resourceId: resource.id, appId }, { enabled: !!resource.id });
47
+ const { data: context, isLoading } = query;
46
48
  const layers = (context?.layers ?? []);
47
49
  const active = context?.effectiveResource;
48
50
  const availability = context?.availability;
49
51
  if (isLoading && !context) {
50
52
  return (_jsxs("div", { className: "mt-3 rounded-lg border bg-muted/20 p-3", children: [_jsx("div", { className: "h-3 w-44 animate-pulse rounded bg-muted-foreground/10" }), _jsxs("div", { className: "mt-3 grid gap-2 sm:grid-cols-3", children: [_jsx("div", { className: "h-20 animate-pulse rounded-md bg-muted-foreground/10" }), _jsx("div", { className: "h-20 animate-pulse rounded-md bg-muted-foreground/10" }), _jsx("div", { className: "h-20 animate-pulse rounded-md bg-muted-foreground/10" })] })] }));
51
53
  }
54
+ if (query.isError) {
55
+ return (_jsx(ActionQueryError, { className: "mt-3", error: query.error, onRetry: () => void query.refetch() }));
56
+ }
52
57
  return (_jsxs("div", { className: "mt-3 rounded-lg border bg-muted/20 p-3", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-xs font-semibold uppercase text-muted-foreground", children: "Effective context stack" }), _jsx("div", { className: "mt-1 truncate font-mono text-[11px] text-muted-foreground", children: resource.path })] }), _jsx(Badge, { variant: "outline", children: appAvailabilityLabel(availability) })] }), _jsx("div", { className: "mt-3 grid gap-2 sm:grid-cols-3", children: layers.map((layer) => {
53
58
  const state = appLayerState(layer);
54
59
  return (_jsxs("div", { className: cn("rounded-md border bg-background/70 p-2", {
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-resource-effective-stack.js","sourceRoot":"","sources":["../../src/components/workspace-resource-effective-stack.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client\";\n\nimport { cn } from \"../lib/utils\";\nimport { Badge } from \"./ui/badge\";\n\nexport function appAvailabilityLabel(value?: string) {\n switch (value) {\n case \"all-apps\":\n return \"Inherited by all apps\";\n case \"selected-granted\":\n return \"Granted to this app\";\n case \"selected-not-granted\":\n return \"Not granted\";\n case \"selected-no-app\":\n return \"Select app\";\n case \"path-not-managed\":\n return \"Not managed\";\n default:\n return \"Checking\";\n }\n}\n\nexport function appLayerState(layer: any): {\n label: string;\n className: string;\n} {\n if (layer.effective) {\n return {\n label: \"Wins\",\n className: \"border-green-500/30 bg-green-500/10 text-green-700\",\n };\n }\n if (layer.overridden) {\n return {\n label: \"Overridden\",\n className: \"border-amber-500/30 bg-amber-500/10 text-amber-700\",\n };\n }\n return {\n label: \"Missing\",\n className: \"text-muted-foreground\",\n };\n}\n\nexport function formatResourceTimestamp(value?: number | null): string {\n if (!value) return \"not present\";\n return new Date(value).toLocaleString();\n}\n\nexport function AppResourceEffectiveStack({\n appId,\n resource,\n}: {\n appId: string;\n resource: any;\n}) {\n const { data: context, isLoading } = useActionQuery(\n \"get-workspace-resource-effective-context\",\n { resourceId: resource.id, appId },\n { enabled: !!resource.id },\n );\n const layers = ((context as any)?.layers ?? []) as any[];\n const active = (context as any)?.effectiveResource;\n const availability = (context as any)?.availability;\n\n if (isLoading && !context) {\n return (\n <div className=\"mt-3 rounded-lg border bg-muted/20 p-3\">\n <div className=\"h-3 w-44 animate-pulse rounded bg-muted-foreground/10\" />\n <div className=\"mt-3 grid gap-2 sm:grid-cols-3\">\n <div className=\"h-20 animate-pulse rounded-md bg-muted-foreground/10\" />\n <div className=\"h-20 animate-pulse rounded-md bg-muted-foreground/10\" />\n <div className=\"h-20 animate-pulse rounded-md bg-muted-foreground/10\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"mt-3 rounded-lg border bg-muted/20 p-3\">\n <div className=\"flex flex-wrap items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"text-xs font-semibold uppercase text-muted-foreground\">\n Effective context stack\n </div>\n <div className=\"mt-1 truncate font-mono text-[11px] text-muted-foreground\">\n {resource.path}\n </div>\n </div>\n <Badge variant=\"outline\">{appAvailabilityLabel(availability)}</Badge>\n </div>\n\n <div className=\"mt-3 grid gap-2 sm:grid-cols-3\">\n {layers.map((layer) => {\n const state = appLayerState(layer);\n return (\n <div\n key={layer.scope}\n className={cn(\"rounded-md border bg-background/70 p-2\", {\n \"border-green-500/30 bg-green-500/10\": layer.effective,\n })}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"text-xs font-medium text-foreground\">\n {layer.label}\n </span>\n <Badge variant=\"outline\" className={state.className}>\n {state.label}\n </Badge>\n </div>\n <div className=\"mt-1 truncate font-mono text-[10px] text-muted-foreground\">\n {layer.owner}\n </div>\n {layer.resource ? (\n <div className=\"mt-2 text-[11px] text-muted-foreground\">\n Updated {formatResourceTimestamp(layer.resource.updatedAt)}\n </div>\n ) : (\n <div className=\"mt-2 text-[11px] text-muted-foreground\">\n No file at this layer\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n <div className=\"mt-3 rounded-md bg-background/70 px-3 py-2 text-xs text-muted-foreground\">\n {active ? (\n <>\n Winning layer:{\" \"}\n <span className=\"font-mono text-foreground\">\n {active.owner}/{active.path}\n </span>\n </>\n ) : (\n \"No active resource exists for this path yet.\"\n )}\n </div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"workspace-resource-effective-stack.js","sourceRoot":"","sources":["../../src/components/workspace-resource-effective-stack.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,UAAU;YACb,OAAO,uBAAuB,CAAC;QACjC,KAAK,kBAAkB;YACrB,OAAO,qBAAqB,CAAC;QAC/B,KAAK,sBAAsB;YACzB,OAAO,aAAa,CAAC;QACvB,KAAK,iBAAiB;YACpB,OAAO,YAAY,CAAC;QACtB,KAAK,kBAAkB;YACrB,OAAO,aAAa,CAAC;QACvB;YACE,OAAO,UAAU,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAU;IAItC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,OAAO;YACL,KAAK,EAAE,MAAM;YACb,SAAS,EAAE,oDAAoD;SAChE,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,SAAS,EAAE,oDAAoD;SAChE,CAAC;IACJ,CAAC;IACD,OAAO;QACL,KAAK,EAAE,SAAS;QAChB,SAAS,EAAE,uBAAuB;KACnC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAqB;IAC3D,IAAI,CAAC,KAAK;QAAE,OAAO,aAAa,CAAC;IACjC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,EACxC,KAAK,EACL,QAAQ,GAIT;IACC,MAAM,KAAK,GAAG,cAAc,CAC1B,0CAA0C,EAC1C,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,EAClC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,CAC3B,CAAC;IACF,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC3C,MAAM,MAAM,GAAG,CAAE,OAAe,EAAE,MAAM,IAAI,EAAE,CAAU,CAAC;IACzD,MAAM,MAAM,GAAI,OAAe,EAAE,iBAAiB,CAAC;IACnD,MAAM,YAAY,GAAI,OAAe,EAAE,YAAY,CAAC;IAEpD,IAAI,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,CACL,eAAK,SAAS,EAAC,wCAAwC,aACrD,cAAK,SAAS,EAAC,uDAAuD,GAAG,EACzE,eAAK,SAAS,EAAC,gCAAgC,aAC7C,cAAK,SAAS,EAAC,sDAAsD,GAAG,EACxE,cAAK,SAAS,EAAC,sDAAsD,GAAG,EACxE,cAAK,SAAS,EAAC,sDAAsD,GAAG,IACpE,IACF,CACP,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,CACL,KAAC,gBAAgB,IACf,SAAS,EAAC,MAAM,EAChB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,GACnC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,wCAAwC,aACrD,eAAK,SAAS,EAAC,kDAAkD,aAC/D,eAAK,SAAS,EAAC,SAAS,aACtB,cAAK,SAAS,EAAC,uDAAuD,wCAEhE,EACN,cAAK,SAAS,EAAC,2DAA2D,YACvE,QAAQ,CAAC,IAAI,GACV,IACF,EACN,KAAC,KAAK,IAAC,OAAO,EAAC,SAAS,YAAE,oBAAoB,CAAC,YAAY,CAAC,GAAS,IACjE,EAEN,cAAK,SAAS,EAAC,gCAAgC,YAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;oBACpB,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;oBACnC,OAAO,CACL,eAEE,SAAS,EAAE,EAAE,CAAC,wCAAwC,EAAE;4BACtD,qCAAqC,EAAE,KAAK,CAAC,SAAS;yBACvD,CAAC,aAEF,eAAK,SAAS,EAAC,wCAAwC,aACrD,eAAM,SAAS,EAAC,qCAAqC,YAClD,KAAK,CAAC,KAAK,GACP,EACP,KAAC,KAAK,IAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAE,KAAK,CAAC,SAAS,YAChD,KAAK,CAAC,KAAK,GACN,IACJ,EACN,cAAK,SAAS,EAAC,2DAA2D,YACvE,KAAK,CAAC,KAAK,GACR,EACL,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAChB,eAAK,SAAS,EAAC,wCAAwC,yBAC5C,uBAAuB,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IACtD,CACP,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,wCAAwC,sCAEjD,CACP,KAxBI,KAAK,CAAC,KAAK,CAyBZ,CACP,CAAC;gBACJ,CAAC,CAAC,GACE,EAEN,cAAK,SAAS,EAAC,0EAA0E,YACtF,MAAM,CAAC,CAAC,CAAC,CACR,gDACiB,GAAG,EAClB,gBAAM,SAAS,EAAC,2BAA2B,aACxC,MAAM,CAAC,KAAK,OAAG,MAAM,CAAC,IAAI,IACtB,IACN,CACJ,CAAC,CAAC,CAAC,CACF,8CAA8C,CAC/C,GACG,IACF,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client\";\n\nimport { cn } from \"../lib/utils\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport { Badge } from \"./ui/badge\";\n\nexport function appAvailabilityLabel(value?: string) {\n switch (value) {\n case \"all-apps\":\n return \"Inherited by all apps\";\n case \"selected-granted\":\n return \"Granted to this app\";\n case \"selected-not-granted\":\n return \"Not granted\";\n case \"selected-no-app\":\n return \"Select app\";\n case \"path-not-managed\":\n return \"Not managed\";\n default:\n return \"Checking\";\n }\n}\n\nexport function appLayerState(layer: any): {\n label: string;\n className: string;\n} {\n if (layer.effective) {\n return {\n label: \"Wins\",\n className: \"border-green-500/30 bg-green-500/10 text-green-700\",\n };\n }\n if (layer.overridden) {\n return {\n label: \"Overridden\",\n className: \"border-amber-500/30 bg-amber-500/10 text-amber-700\",\n };\n }\n return {\n label: \"Missing\",\n className: \"text-muted-foreground\",\n };\n}\n\nexport function formatResourceTimestamp(value?: number | null): string {\n if (!value) return \"not present\";\n return new Date(value).toLocaleString();\n}\n\nexport function AppResourceEffectiveStack({\n appId,\n resource,\n}: {\n appId: string;\n resource: any;\n}) {\n const query = useActionQuery(\n \"get-workspace-resource-effective-context\",\n { resourceId: resource.id, appId },\n { enabled: !!resource.id },\n );\n const { data: context, isLoading } = query;\n const layers = ((context as any)?.layers ?? []) as any[];\n const active = (context as any)?.effectiveResource;\n const availability = (context as any)?.availability;\n\n if (isLoading && !context) {\n return (\n <div className=\"mt-3 rounded-lg border bg-muted/20 p-3\">\n <div className=\"h-3 w-44 animate-pulse rounded bg-muted-foreground/10\" />\n <div className=\"mt-3 grid gap-2 sm:grid-cols-3\">\n <div className=\"h-20 animate-pulse rounded-md bg-muted-foreground/10\" />\n <div className=\"h-20 animate-pulse rounded-md bg-muted-foreground/10\" />\n <div className=\"h-20 animate-pulse rounded-md bg-muted-foreground/10\" />\n </div>\n </div>\n );\n }\n\n if (query.isError) {\n return (\n <ActionQueryError\n className=\"mt-3\"\n error={query.error}\n onRetry={() => void query.refetch()}\n />\n );\n }\n\n return (\n <div className=\"mt-3 rounded-lg border bg-muted/20 p-3\">\n <div className=\"flex flex-wrap items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"text-xs font-semibold uppercase text-muted-foreground\">\n Effective context stack\n </div>\n <div className=\"mt-1 truncate font-mono text-[11px] text-muted-foreground\">\n {resource.path}\n </div>\n </div>\n <Badge variant=\"outline\">{appAvailabilityLabel(availability)}</Badge>\n </div>\n\n <div className=\"mt-3 grid gap-2 sm:grid-cols-3\">\n {layers.map((layer) => {\n const state = appLayerState(layer);\n return (\n <div\n key={layer.scope}\n className={cn(\"rounded-md border bg-background/70 p-2\", {\n \"border-green-500/30 bg-green-500/10\": layer.effective,\n })}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"text-xs font-medium text-foreground\">\n {layer.label}\n </span>\n <Badge variant=\"outline\" className={state.className}>\n {state.label}\n </Badge>\n </div>\n <div className=\"mt-1 truncate font-mono text-[10px] text-muted-foreground\">\n {layer.owner}\n </div>\n {layer.resource ? (\n <div className=\"mt-2 text-[11px] text-muted-foreground\">\n Updated {formatResourceTimestamp(layer.resource.updatedAt)}\n </div>\n ) : (\n <div className=\"mt-2 text-[11px] text-muted-foreground\">\n No file at this layer\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n <div className=\"mt-3 rounded-md bg-background/70 px-3 py-2 text-xs text-muted-foreground\">\n {active ? (\n <>\n Winning layer:{\" \"}\n <span className=\"font-mono text-foreground\">\n {active.owner}/{active.path}\n </span>\n </>\n ) : (\n \"No active resource exists for this path yet.\"\n )}\n </div>\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-resource-impact-preview.d.ts","sourceRoot":"","sources":["../../src/components/workspace-resource-impact-preview.tsx"],"names":[],"mappings":"AAcA,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,MAAM,GACf,MAAM,CAER;AAED,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,UAAU,EACV,IAAI,EACJ,KAAK,EACL,OAAc,GACf,EAAE;IACD,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,0DAmFA"}
1
+ {"version":3,"file":"workspace-resource-impact-preview.d.ts","sourceRoot":"","sources":["../../src/components/workspace-resource-impact-preview.tsx"],"names":[],"mappings":"AAeA,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,MAAM,GACf,MAAM,CAER;AAED,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,UAAU,EACV,IAAI,EACJ,KAAK,EACL,OAAc,GACf,EAAE;IACD,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,0DA6FA"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useActionQuery } from "@agent-native/core/client";
3
+ import { ActionQueryError } from "./action-query-error.js";
3
4
  import { Badge } from "./ui/badge.js";
4
5
  import { Skeleton } from "./ui/skeleton.js";
5
6
  import { formatResourceTimestamp } from "./workspace-resource-effective-stack.js";
@@ -12,17 +13,21 @@ export function workspaceResourceMutationMessage(result, fallback) {
12
13
  return isApprovalRequest(result) ? "Approval requested" : fallback;
13
14
  }
14
15
  export function ImpactPreview({ operation, resourceId, path, scope, enabled = true, }) {
15
- const { data: impact, isLoading } = useActionQuery("preview-workspace-resource-change", {
16
+ const query = useActionQuery("preview-workspace-resource-change", {
16
17
  operation,
17
18
  resourceId,
18
19
  path,
19
20
  scope,
20
21
  }, { enabled: enabled && Boolean(resourceId || path) });
22
+ const { data: impact, isLoading } = query;
21
23
  if (!enabled || (!resourceId && !path))
22
24
  return null;
23
25
  if (isLoading) {
24
26
  return (_jsxs("div", { className: "rounded-lg border bg-muted/30 p-3", children: [_jsx(Skeleton, { className: "h-4 w-40" }), _jsx(Skeleton, { className: "mt-2 h-3 w-72" })] }));
25
27
  }
28
+ if (query.isError) {
29
+ return (_jsx(ActionQueryError, { error: query.error, onRetry: () => void query.refetch() }));
30
+ }
26
31
  const data = impact;
27
32
  if (!data)
28
33
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-resource-impact-preview.js","sourceRoot":"","sources":["../../src/components/workspace-resource-impact-preview.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client\";\n\nimport { Badge } from \"./ui/badge\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport { formatResourceTimestamp } from \"./workspace-resource-effective-stack\";\n\nfunction isApprovalRequest(result: any): boolean {\n return (\n result?.status === \"pending\" &&\n typeof result?.changeType === \"string\" &&\n result.changeType.startsWith(\"workspace-resource.\")\n );\n}\n\nexport function workspaceResourceMutationMessage(\n result: any,\n fallback: string,\n): string {\n return isApprovalRequest(result) ? \"Approval requested\" : fallback;\n}\n\nexport function ImpactPreview({\n operation,\n resourceId,\n path,\n scope,\n enabled = true,\n}: {\n operation: \"create\" | \"update\" | \"delete\";\n resourceId?: string;\n path?: string;\n scope?: \"all\" | \"selected\";\n enabled?: boolean;\n}) {\n const { data: impact, isLoading } = useActionQuery(\n \"preview-workspace-resource-change\",\n {\n operation,\n resourceId,\n path,\n scope,\n },\n { enabled: enabled && Boolean(resourceId || path) },\n );\n\n if (!enabled || (!resourceId && !path)) return null;\n\n if (isLoading) {\n return (\n <div className=\"rounded-lg border bg-muted/30 p-3\">\n <Skeleton className=\"h-4 w-40\" />\n <Skeleton className=\"mt-2 h-3 w-72\" />\n </div>\n );\n }\n\n const data = impact as any;\n if (!data) return null;\n const affectsAllApps = data.affectsAllApps === true;\n const appCount = data.affectedApps?.count;\n const overrides = data.overrides ?? { count: 0, items: [] };\n const willRequestApproval = data.approval?.willRequestApproval === true;\n\n return (\n <div className=\"rounded-lg border bg-muted/30 p-3 text-xs\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant={affectsAllApps ? \"secondary\" : \"outline\"}>\n {affectsAllApps ? \"All apps impact\" : \"Selected only\"}\n </Badge>\n {willRequestApproval ? (\n <Badge\n variant=\"outline\"\n className=\"border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n Approval required\n </Badge>\n ) : null}\n {overrides.count > 0 ? (\n <Badge variant=\"outline\">\n {overrides.count} override{overrides.count === 1 ? \"\" : \"s\"}\n </Badge>\n ) : null}\n </div>\n <p className=\"mt-2 leading-relaxed text-muted-foreground\">\n {affectsAllApps\n ? `This change applies to every workspace app${typeof appCount === \"number\" ? ` (${appCount} discovered)` : \"\"}.`\n : \"This change only applies to explicitly granted apps.\"}{\" \"}\n {willRequestApproval\n ? \"It will be queued for approval before it takes effect.\"\n : \"It will take effect immediately when saved.\"}\n </p>\n {overrides.count > 0 ? (\n <div className=\"mt-2 space-y-1\">\n {overrides.items.slice(0, 4).map((override: any) => (\n <div\n key={`${override.scope}:${override.owner}`}\n className=\"flex items-center justify-between gap-3 rounded-md border bg-background px-2 py-1.5\"\n >\n <span className=\"min-w-0 truncate text-muted-foreground\">\n {override.label}\n </span>\n <span className=\"shrink-0 font-mono text-[11px] text-muted-foreground\">\n {formatResourceTimestamp(override.updatedAt)}\n </span>\n </div>\n ))}\n {overrides.count > 4 ? (\n <div className=\"text-muted-foreground\">\n +{overrides.count - 4} more override\n {overrides.count - 4 === 1 ? \"\" : \"s\"}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"workspace-resource-impact-preview.js","sourceRoot":"","sources":["../../src/components/workspace-resource-impact-preview.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client\";\n\nimport { ActionQueryError } from \"./action-query-error\";\nimport { Badge } from \"./ui/badge\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport { formatResourceTimestamp } from \"./workspace-resource-effective-stack\";\n\nfunction isApprovalRequest(result: any): boolean {\n return (\n result?.status === \"pending\" &&\n typeof result?.changeType === \"string\" &&\n result.changeType.startsWith(\"workspace-resource.\")\n );\n}\n\nexport function workspaceResourceMutationMessage(\n result: any,\n fallback: string,\n): string {\n return isApprovalRequest(result) ? \"Approval requested\" : fallback;\n}\n\nexport function ImpactPreview({\n operation,\n resourceId,\n path,\n scope,\n enabled = true,\n}: {\n operation: \"create\" | \"update\" | \"delete\";\n resourceId?: string;\n path?: string;\n scope?: \"all\" | \"selected\";\n enabled?: boolean;\n}) {\n const query = useActionQuery(\n \"preview-workspace-resource-change\",\n {\n operation,\n resourceId,\n path,\n scope,\n },\n { enabled: enabled && Boolean(resourceId || path) },\n );\n const { data: impact, isLoading } = query;\n\n if (!enabled || (!resourceId && !path)) return null;\n\n if (isLoading) {\n return (\n <div className=\"rounded-lg border bg-muted/30 p-3\">\n <Skeleton className=\"h-4 w-40\" />\n <Skeleton className=\"mt-2 h-3 w-72\" />\n </div>\n );\n }\n\n if (query.isError) {\n return (\n <ActionQueryError\n error={query.error}\n onRetry={() => void query.refetch()}\n />\n );\n }\n\n const data = impact as any;\n if (!data) return null;\n const affectsAllApps = data.affectsAllApps === true;\n const appCount = data.affectedApps?.count;\n const overrides = data.overrides ?? { count: 0, items: [] };\n const willRequestApproval = data.approval?.willRequestApproval === true;\n\n return (\n <div className=\"rounded-lg border bg-muted/30 p-3 text-xs\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant={affectsAllApps ? \"secondary\" : \"outline\"}>\n {affectsAllApps ? \"All apps impact\" : \"Selected only\"}\n </Badge>\n {willRequestApproval ? (\n <Badge\n variant=\"outline\"\n className=\"border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n Approval required\n </Badge>\n ) : null}\n {overrides.count > 0 ? (\n <Badge variant=\"outline\">\n {overrides.count} override{overrides.count === 1 ? \"\" : \"s\"}\n </Badge>\n ) : null}\n </div>\n <p className=\"mt-2 leading-relaxed text-muted-foreground\">\n {affectsAllApps\n ? `This change applies to every workspace app${typeof appCount === \"number\" ? ` (${appCount} discovered)` : \"\"}.`\n : \"This change only applies to explicitly granted apps.\"}{\" \"}\n {willRequestApproval\n ? \"It will be queued for approval before it takes effect.\"\n : \"It will take effect immediately when saved.\"}\n </p>\n {overrides.count > 0 ? (\n <div className=\"mt-2 space-y-1\">\n {overrides.items.slice(0, 4).map((override: any) => (\n <div\n key={`${override.scope}:${override.owner}`}\n className=\"flex items-center justify-between gap-3 rounded-md border bg-background px-2 py-1.5\"\n >\n <span className=\"min-w-0 truncate text-muted-foreground\">\n {override.label}\n </span>\n <span className=\"shrink-0 font-mono text-[11px] text-muted-foreground\">\n {formatResourceTimestamp(override.updatedAt)}\n </span>\n </div>\n ))}\n {overrides.count > 4 ? (\n <div className=\"text-muted-foreground\">\n +{overrides.count - 4} more override\n {overrides.count - 4 === 1 ? \"\" : \"s\"}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"$appId.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/$appId.tsx"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACxB,MAAM,cAAc,CAAC;AAYtB,wBAAgB,IAAI;;IAEnB;AA2CD,wBAAsB,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,kBAAkB,iBAQ1D;AAED,wBAAsB,YAAY,CAAC,EACjC,MAAM,EACN,YAAY,GACb,EAAE,wBAAwB,oBAS1B;AAED,MAAM,CAAC,OAAO,UAAU,yBAAyB,oDAiGhD"}
1
+ {"version":3,"file":"$appId.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/$appId.tsx"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACxB,MAAM,cAAc,CAAC;AAatB,wBAAgB,IAAI;;IAEnB;AA2CD,wBAAsB,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,kBAAkB,iBAQ1D;AAED,wBAAsB,YAAY,CAAC,EACjC,MAAM,EACN,YAAY,GACb,EAAE,wBAAwB,oBAS1B;AAED,MAAM,CAAC,OAAO,UAAU,yBAAyB,oDAgHhD"}
@@ -3,6 +3,7 @@ import { useActionQuery, appPath, useT } from "@agent-native/core/client";
3
3
  import { IconArrowLeft, IconArrowUpRight, IconClockHour4, } from "@tabler/icons-react";
4
4
  import { useEffect, useMemo } from "react";
5
5
  import { Link, Navigate, redirect, useParams, } from "react-router";
6
+ import { ActionQueryError } from "../../components/action-query-error.js";
6
7
  import { DispatchShell } from "../../components/dispatch-shell.js";
7
8
  import { Badge } from "../../components/ui/badge.js";
8
9
  import { Button } from "../../components/ui/button.js";
@@ -79,9 +80,10 @@ export async function clientLoader({ params, serverLoader, }) {
79
80
  export default function WorkspaceAppCatchAllRoute() {
80
81
  const t = useT();
81
82
  const { appId } = useParams();
82
- const { data: apps = [], isLoading } = useActionQuery("list-workspace-apps", {
83
+ const appsQuery = useActionQuery("list-workspace-apps", {
83
84
  includeAgentCards: false,
84
85
  });
86
+ const { data: apps = [], isLoading } = appsQuery;
85
87
  const app = useMemo(() => apps.find((item) => item.id === appId) ?? null, [appId, apps]);
86
88
  const href = app ? workspaceAppHref(app) : null;
87
89
  const isSelfReference = appId === "dispatch";
@@ -95,6 +97,9 @@ export default function WorkspaceAppCatchAllRoute() {
95
97
  if (isSelfReference) {
96
98
  return _jsx(Navigate, { to: appPath("/overview"), replace: true });
97
99
  }
100
+ if (appsQuery.isError) {
101
+ return (_jsx(DispatchShell, { title: t("dispatch.pages.dataLoadFailed"), description: t("dispatch.pages.pageNotFoundDescription"), children: _jsx(ActionQueryError, { error: appsQuery.error, onRetry: () => void appsQuery.refetch() }) }));
102
+ }
98
103
  if ((isLoading && !app) || (app && app.status !== "pending" && href)) {
99
104
  return (_jsx("div", { className: "flex h-screen w-full items-center justify-center", children: _jsx(Spinner, { className: "size-8" }) }));
100
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"$appId.js","sourceRoot":"","sources":["../../../src/routes/pages/$appId.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery, appPath, useT } from \"@agent-native/core/client\";\nimport {\n IconArrowLeft,\n IconArrowUpRight,\n IconClockHour4,\n} from \"@tabler/icons-react\";\nimport { useEffect, useMemo } from \"react\";\nimport {\n Link,\n Navigate,\n redirect,\n useParams,\n type ClientLoaderFunctionArgs,\n type LoaderFunctionArgs,\n} from \"react-router\";\n\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Spinner } from \"../../components/ui/spinner\";\nimport { resolveServerCatchAllTarget } from \"../../lib/catch-all-target\";\nimport {\n workspaceAppHref,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Workspace app - Dispatch\" }];\n}\n\n/**\n * Catch-all for `/dispatch/<segment>` paths that don't match an explicit\n * Dispatch route. When `<segment>` is the id of a workspace app sibling\n * (e.g. `/dispatch/todo` after Builder.io routes a \"navigate to /todo\"\n * call through Dispatch's mount point), bounce to the absolute `/<appId>`\n * so the user lands on the actual app instead of a 404 inside Dispatch.\n *\n * Server-side redirect: we resolve the workspace app manifest via the\n * shared `loadWorkspaceAppsManifest()` helper, which checks the\n * `AGENT_NATIVE_WORKSPACE_APPS_JSON` env var, then the\n * `.agent-native/workspace-apps.json` file written by `workspace-deploy.ts`,\n * then a live filesystem scan of `apps/` for local dev. We then throw\n * `redirect(\"/<appId>\")`. React Router 7 does not prepend the basename to\n * absolute paths returned from a loader, so the redirect escapes Dispatch's\n * `/dispatch` mount cleanly.\n *\n * Why a catch-all instead of fixing the agent prompt: Builder.io currently\n * resolves \"navigate to /todo\" relative to Dispatch's mount, sending the\n * user to /dispatch/todo. The same wrong path then gets captured as the\n * OAuth callbackURL, so Google sign-in completes back at /dispatch/todo\n * and looks broken. This route fixes both the post-creation navigation\n * and the OAuth round-trip from a single place.\n *\n * Built-in template fallback: when no workspace manifest is available\n * (framework dev with each template on its own port, hosted dispatch with\n * no sibling apps), redirect to the matching first-party template's deploy\n * URL — `http://localhost:<devPort>` in dev, `https://<id>.agent-native.com`\n * in production. Without this, a user visiting `/forms` on dispatch is\n * forced to sign in (auth guard) and then lands on this route's \"Page not\n * found\" pane after the post-login reload.\n *\n * `appId === \"dispatch\"` short-circuit: when the segment matches Dispatch\n * itself (e.g. `/dispatch/dispatch`), we go straight to the overview rather\n * than chaining through `/dispatch` (which polled `useActionQuery` re-fired\n * `window.location.assign` against and looped forever in production).\n */\nfunction dispatchSelfRedirect(appId: string | undefined): string | null {\n if (appId === \"dispatch\") return appPath(\"/overview\");\n return null;\n}\n\nexport async function loader({ params }: LoaderFunctionArgs) {\n const appId = params.appId;\n if (!appId) return null;\n const selfTarget = dispatchSelfRedirect(appId);\n if (selfTarget) throw redirect(selfTarget);\n const target = await resolveServerCatchAllTarget(appId);\n if (target) throw redirect(target);\n return null;\n}\n\nexport async function clientLoader({\n params,\n serverLoader,\n}: ClientLoaderFunctionArgs) {\n const selfTarget = dispatchSelfRedirect(params.appId);\n if (selfTarget) throw redirect(selfTarget);\n // Defer to the server loader so the built-in template fallback runs on\n // SPA navigations too (e.g. clicking a `/<template-id>` link inside\n // dispatch). Without this the client side would only check the workspace\n // apps query, which never lists the static first-party templates and so\n // the user would land on the \"Page not found\" pane.\n return serverLoader();\n}\n\nexport default function WorkspaceAppCatchAllRoute() {\n const t = useT();\n const { appId } = useParams();\n const { data: apps = [], isLoading } = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n });\n const app = useMemo(\n () =>\n (apps as WorkspaceAppSummary[]).find((item) => item.id === appId) ?? null,\n [appId, apps],\n );\n const href = app ? workspaceAppHref(app) : null;\n const isSelfReference = appId === \"dispatch\";\n\n useEffect(() => {\n if (isSelfReference) return;\n if (!app || app.status === \"pending\" || !href) return;\n window.location.assign(href);\n }, [app, href, isSelfReference]);\n\n if (isSelfReference) {\n return <Navigate to={appPath(\"/overview\")} replace />;\n }\n\n if ((isLoading && !app) || (app && app.status !== \"pending\" && href)) {\n return (\n <div className=\"flex h-screen w-full items-center justify-center\">\n <Spinner className=\"size-8\" />\n </div>\n );\n }\n\n return (\n <DispatchShell\n title={app?.name || t(\"dispatch.pages.pageNotFound\")}\n description={t(\"dispatch.pages.pageNotFoundDescription\")}\n >\n <div className=\"max-w-2xl rounded-lg border bg-card p-5\">\n <Button asChild size=\"sm\" variant=\"ghost\" className=\"-ml-2 mb-4\">\n <Link to={appPath(\"/overview\")}>\n <IconArrowLeft size={15} className=\"mr-1.5\" />\n {t(\"dispatch.nav.overview\")}\n </Link>\n </Button>\n\n {app?.status === \"pending\" ? (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-base font-semibold text-foreground\">\n {app.name}\n </h2>\n <Badge\n variant=\"outline\"\n className=\"gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n <IconClockHour4 size={12} />\n {t(\"dispatch.pages.building\")}\n </Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {t(\"dispatch.pages.appBuildingPrefix\")}{\" \"}\n <span className=\"font-mono text-foreground\">{app.path}</span>{\" \"}\n {t(\"dispatch.pages.appBuildingSuffix\")}\n </p>\n {app.branchName ? (\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.branch\", { branch: app.branchName })}\n </p>\n ) : null}\n {app.builderUrl ? (\n <Button asChild>\n <a href={app.builderUrl} target=\"_blank\" rel=\"noreferrer\">\n {t(\"dispatch.pages.openBuilderBranch\")}\n <IconArrowUpRight size={15} className=\"ml-1.5\" />\n </a>\n </Button>\n ) : null}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <h2 className=\"text-base font-semibold text-foreground\">\n {t(\"dispatch.pages.pageNotFound\")}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n <span className=\"font-mono text-foreground\">/{appId}</span> isn't\n {t(\"dispatch.pages.notDispatchOrWorkspaceApp\")}\n </p>\n <Button asChild>\n <Link to={appPath(\"/apps\")}>\n {t(\"dispatch.pages.browseApps\")}\n </Link>\n </Button>\n </div>\n )}\n </div>\n </DispatchShell>\n );\n}\n"]}
1
+ {"version":3,"file":"$appId.js","sourceRoot":"","sources":["../../../src/routes/pages/$appId.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery, appPath, useT } from \"@agent-native/core/client\";\nimport {\n IconArrowLeft,\n IconArrowUpRight,\n IconClockHour4,\n} from \"@tabler/icons-react\";\nimport { useEffect, useMemo } from \"react\";\nimport {\n Link,\n Navigate,\n redirect,\n useParams,\n type ClientLoaderFunctionArgs,\n type LoaderFunctionArgs,\n} from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Spinner } from \"../../components/ui/spinner\";\nimport { resolveServerCatchAllTarget } from \"../../lib/catch-all-target\";\nimport {\n workspaceAppHref,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Workspace app - Dispatch\" }];\n}\n\n/**\n * Catch-all for `/dispatch/<segment>` paths that don't match an explicit\n * Dispatch route. When `<segment>` is the id of a workspace app sibling\n * (e.g. `/dispatch/todo` after Builder.io routes a \"navigate to /todo\"\n * call through Dispatch's mount point), bounce to the absolute `/<appId>`\n * so the user lands on the actual app instead of a 404 inside Dispatch.\n *\n * Server-side redirect: we resolve the workspace app manifest via the\n * shared `loadWorkspaceAppsManifest()` helper, which checks the\n * `AGENT_NATIVE_WORKSPACE_APPS_JSON` env var, then the\n * `.agent-native/workspace-apps.json` file written by `workspace-deploy.ts`,\n * then a live filesystem scan of `apps/` for local dev. We then throw\n * `redirect(\"/<appId>\")`. React Router 7 does not prepend the basename to\n * absolute paths returned from a loader, so the redirect escapes Dispatch's\n * `/dispatch` mount cleanly.\n *\n * Why a catch-all instead of fixing the agent prompt: Builder.io currently\n * resolves \"navigate to /todo\" relative to Dispatch's mount, sending the\n * user to /dispatch/todo. The same wrong path then gets captured as the\n * OAuth callbackURL, so Google sign-in completes back at /dispatch/todo\n * and looks broken. This route fixes both the post-creation navigation\n * and the OAuth round-trip from a single place.\n *\n * Built-in template fallback: when no workspace manifest is available\n * (framework dev with each template on its own port, hosted dispatch with\n * no sibling apps), redirect to the matching first-party template's deploy\n * URL — `http://localhost:<devPort>` in dev, `https://<id>.agent-native.com`\n * in production. Without this, a user visiting `/forms` on dispatch is\n * forced to sign in (auth guard) and then lands on this route's \"Page not\n * found\" pane after the post-login reload.\n *\n * `appId === \"dispatch\"` short-circuit: when the segment matches Dispatch\n * itself (e.g. `/dispatch/dispatch`), we go straight to the overview rather\n * than chaining through `/dispatch` (which polled `useActionQuery` re-fired\n * `window.location.assign` against and looped forever in production).\n */\nfunction dispatchSelfRedirect(appId: string | undefined): string | null {\n if (appId === \"dispatch\") return appPath(\"/overview\");\n return null;\n}\n\nexport async function loader({ params }: LoaderFunctionArgs) {\n const appId = params.appId;\n if (!appId) return null;\n const selfTarget = dispatchSelfRedirect(appId);\n if (selfTarget) throw redirect(selfTarget);\n const target = await resolveServerCatchAllTarget(appId);\n if (target) throw redirect(target);\n return null;\n}\n\nexport async function clientLoader({\n params,\n serverLoader,\n}: ClientLoaderFunctionArgs) {\n const selfTarget = dispatchSelfRedirect(params.appId);\n if (selfTarget) throw redirect(selfTarget);\n // Defer to the server loader so the built-in template fallback runs on\n // SPA navigations too (e.g. clicking a `/<template-id>` link inside\n // dispatch). Without this the client side would only check the workspace\n // apps query, which never lists the static first-party templates and so\n // the user would land on the \"Page not found\" pane.\n return serverLoader();\n}\n\nexport default function WorkspaceAppCatchAllRoute() {\n const t = useT();\n const { appId } = useParams();\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n });\n const { data: apps = [], isLoading } = appsQuery;\n const app = useMemo(\n () =>\n (apps as WorkspaceAppSummary[]).find((item) => item.id === appId) ?? null,\n [appId, apps],\n );\n const href = app ? workspaceAppHref(app) : null;\n const isSelfReference = appId === \"dispatch\";\n\n useEffect(() => {\n if (isSelfReference) return;\n if (!app || app.status === \"pending\" || !href) return;\n window.location.assign(href);\n }, [app, href, isSelfReference]);\n\n if (isSelfReference) {\n return <Navigate to={appPath(\"/overview\")} replace />;\n }\n\n if (appsQuery.isError) {\n return (\n <DispatchShell\n title={t(\"dispatch.pages.dataLoadFailed\")}\n description={t(\"dispatch.pages.pageNotFoundDescription\")}\n >\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n </DispatchShell>\n );\n }\n\n if ((isLoading && !app) || (app && app.status !== \"pending\" && href)) {\n return (\n <div className=\"flex h-screen w-full items-center justify-center\">\n <Spinner className=\"size-8\" />\n </div>\n );\n }\n\n return (\n <DispatchShell\n title={app?.name || t(\"dispatch.pages.pageNotFound\")}\n description={t(\"dispatch.pages.pageNotFoundDescription\")}\n >\n <div className=\"max-w-2xl rounded-lg border bg-card p-5\">\n <Button asChild size=\"sm\" variant=\"ghost\" className=\"-ml-2 mb-4\">\n <Link to={appPath(\"/overview\")}>\n <IconArrowLeft size={15} className=\"mr-1.5\" />\n {t(\"dispatch.nav.overview\")}\n </Link>\n </Button>\n\n {app?.status === \"pending\" ? (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-base font-semibold text-foreground\">\n {app.name}\n </h2>\n <Badge\n variant=\"outline\"\n className=\"gap-1 border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300\"\n >\n <IconClockHour4 size={12} />\n {t(\"dispatch.pages.building\")}\n </Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {t(\"dispatch.pages.appBuildingPrefix\")}{\" \"}\n <span className=\"font-mono text-foreground\">{app.path}</span>{\" \"}\n {t(\"dispatch.pages.appBuildingSuffix\")}\n </p>\n {app.branchName ? (\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.branch\", { branch: app.branchName })}\n </p>\n ) : null}\n {app.builderUrl ? (\n <Button asChild>\n <a href={app.builderUrl} target=\"_blank\" rel=\"noreferrer\">\n {t(\"dispatch.pages.openBuilderBranch\")}\n <IconArrowUpRight size={15} className=\"ml-1.5\" />\n </a>\n </Button>\n ) : null}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <h2 className=\"text-base font-semibold text-foreground\">\n {t(\"dispatch.pages.pageNotFound\")}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n <span className=\"font-mono text-foreground\">/{appId}</span> isn't\n {t(\"dispatch.pages.notDispatchOrWorkspaceApp\")}\n </p>\n <Button asChild>\n <Link to={appPath(\"/apps\")}>\n {t(\"dispatch.pages.browseApps\")}\n </Link>\n </Button>\n </div>\n )}\n </div>\n </DispatchShell>\n );\n}\n"]}