@agent-native/core 0.178.1 → 0.178.2-nightly-20260910214741

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 (50) hide show
  1. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +108 -121
  2. package/corpus/templates/assets/actions/create-generation-session.ts +2 -6
  3. package/corpus/templates/assets/actions/generate-image.ts +3 -12
  4. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +87 -220
  5. package/corpus/templates/assets/server/lib/library-access.ts +23 -0
  6. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +83 -221
  7. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +324 -460
  8. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +57 -247
  9. package/corpus/templates/clips/app/components/library/library-layout.tsx +15 -48
  10. package/corpus/templates/clips/changelog/2026-09-10-open-mcp-connections-in-new-tabs.md +1 -0
  11. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +84 -94
  12. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +1 -1
  13. package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +108 -296
  14. package/corpus/templates/design/app/components/layout/Sidebar.tsx +55 -212
  15. package/corpus/templates/factory/app/components/layout/Sidebar.tsx +72 -260
  16. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +143 -362
  17. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +64 -159
  18. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +152 -165
  19. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +82 -207
  20. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +61 -234
  21. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +73 -225
  22. package/dist/client/EnvironmentBadge.d.ts +7 -4
  23. package/dist/client/EnvironmentBadge.js +26 -18
  24. package/dist/client/FeedbackButton.js +23 -8
  25. package/dist/client/app-providers.js +1 -1
  26. package/dist/client/auth/AuthPage.js +0 -38
  27. package/dist/client/components/icons/AgentNativeIcon.js +1 -1
  28. package/dist/client/index.d.ts +1 -0
  29. package/dist/client/index.js +1 -0
  30. package/dist/client/ui/AppSidebar.d.ts +15 -0
  31. package/dist/client/ui/AppSidebar.js +34 -0
  32. package/dist/client/ui/index.d.ts +1 -0
  33. package/dist/client/ui/index.js +1 -0
  34. package/dist/collab/routes.d.ts +1 -1
  35. package/dist/config.d.ts +4 -0
  36. package/dist/config.js +19 -3
  37. package/dist/file-upload/actions/upload-image.d.ts +3 -3
  38. package/dist/notifications/routes.d.ts +2 -2
  39. package/dist/observability/routes.d.ts +5 -5
  40. package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
  41. package/dist/provider-api/actions/provider-api.d.ts +15 -15
  42. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  43. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  44. package/dist/server/beta-opt-out-html.js +2 -2
  45. package/dist/templates/chat/app/components/layout/Sidebar.tsx +57 -247
  46. package/dist/vite/client.js +4 -1
  47. package/docs/content/template-clips-anonymous-intake.mdx +7 -5
  48. package/docs/content/template-clips-developers.mdx +1 -1
  49. package/package.json +2 -2
  50. package/src/templates/chat/app/components/layout/Sidebar.tsx +57 -247
@@ -9,16 +9,18 @@ import { useActionQuery } from "@agent-native/core/client/hooks";
9
9
  import { useT } from "@agent-native/core/client/i18n";
10
10
  import { openCommandMenu } from "@agent-native/core/client/navigation";
11
11
  import { OrgSwitcher } from "@agent-native/core/client/org";
12
- import { AgentNativeIcon, FeedbackButton } from "@agent-native/core/client/ui";
13
- import { SidebarFooterActions } from "@agent-native/toolkit/app-shell";
12
+ import {
13
+ AppSidebar,
14
+ AppSidebarNavItem,
15
+ FeedbackButton,
16
+ type AppSidebarItemDefinition,
17
+ } from "@agent-native/core/client/ui";
14
18
  import {
15
19
  ChatHistoryRail,
16
20
  type ChatHistoryItem,
17
21
  } from "@agent-native/toolkit/chat-history";
18
22
  import {
19
23
  IconClipboardList,
20
- IconLayoutSidebarLeftCollapse,
21
- IconLayoutSidebarLeftExpand,
22
24
  IconLayoutGrid,
23
25
  IconPhotoPlus,
24
26
  IconSearch,
@@ -27,16 +29,16 @@ import {
27
29
  IconTemplate,
28
30
  } from "@tabler/icons-react";
29
31
  import { useEffect, useMemo, useState } from "react";
30
- import { Link, useLocation, useNavigate } from "react-router";
32
+ import { useLocation, useNavigate } from "react-router";
31
33
  import { toast } from "sonner";
32
34
 
35
+ import { Button } from "@/components/ui/button";
33
36
  import {
34
37
  Tooltip,
35
38
  TooltipContent,
36
39
  TooltipTrigger,
37
40
  } from "@/components/ui/tooltip";
38
41
  import { ASSETS_CHAT_STORAGE_KEY } from "@/lib/chat";
39
- import { cn } from "@/lib/utils";
40
42
 
41
43
  const baseNavItems = [
42
44
  { icon: IconPhotoPlus, labelKey: "navigation.create", href: "/home" },
@@ -44,10 +46,6 @@ const baseNavItems = [
44
46
  { icon: IconTemplate, labelKey: "navigation.templates", href: "/templates" },
45
47
  ];
46
48
 
47
- const bottomNavItems = [
48
- { icon: IconSettings, labelKey: "navigation.settings", href: "/settings" },
49
- ];
50
-
51
49
  const auditNavItem = {
52
50
  icon: IconClipboardList,
53
51
  labelKey: "navigation.auditLog",
@@ -329,230 +327,99 @@ export function Sidebar() {
329
327
  }
330
328
  }, [collapsed]);
331
329
 
332
- const collapseButton = (
333
- <Tooltip delayDuration={0}>
334
- <TooltipTrigger asChild>
335
- <button
336
- type="button"
337
- onClick={() => setCollapsed((value) => !value)}
338
- className="flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-sidebar-accent/50 hover:text-foreground"
339
- aria-label={
340
- collapsed
341
- ? t("navigation.expandSidebar")
342
- : t("navigation.collapseSidebar")
343
- }
344
- >
345
- {collapsed ? (
346
- <IconLayoutSidebarLeftExpand className="h-4 w-4 rtl:-scale-x-100" />
347
- ) : (
348
- <IconLayoutSidebarLeftCollapse className="h-4 w-4 rtl:-scale-x-100" />
349
- )}
350
- </button>
351
- </TooltipTrigger>
352
- <TooltipContent side="right">
353
- {collapsed
354
- ? t("navigation.expandSidebar")
355
- : t("navigation.collapseSidebar")}
356
- </TooltipContent>
357
- </Tooltip>
330
+ const secondaryItems: AppSidebarItemDefinition[] = [
331
+ {
332
+ to: "/settings",
333
+ label: t("navigation.settings"),
334
+ icon: IconSettings,
335
+ active: location.pathname.startsWith("/settings"),
336
+ },
337
+ ];
338
+
339
+ const feedbackButton = (
340
+ <FeedbackButton variant={collapsed ? "icon" : "sidebar"} side="right" />
358
341
  );
342
+
343
+ const orgSwitcher = <OrgSwitcher compact={collapsed} />;
344
+
359
345
  const searchButton = (
360
- <Tooltip delayDuration={0}>
346
+ <Tooltip>
361
347
  <TooltipTrigger asChild>
362
- <button
348
+ <Button
363
349
  type="button"
350
+ variant="ghost"
351
+ size="icon"
352
+ className="size-9 shrink-0 text-primary hover:bg-accent/60 hover:text-primary"
364
353
  onClick={openCommandMenu}
365
- className="flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-sidebar-accent/50 hover:text-foreground"
366
354
  aria-label={t("root.commandSearch")}
367
355
  >
368
- <IconSearch className="h-4 w-4" />
369
- </button>
356
+ <IconSearch className="size-4" />
357
+ </Button>
370
358
  </TooltipTrigger>
371
359
  <TooltipContent side="right">{t("root.commandSearch")}</TooltipContent>
372
360
  </Tooltip>
373
361
  );
374
- const feedbackButton = (
375
- <FeedbackButton
376
- variant={collapsed ? "icon" : "sidebar"}
377
- side="right"
378
- className={collapsed ? "h-8 w-8" : "min-w-0"}
379
- />
380
- );
381
- const brandControl = (
382
- <button
383
- type="button"
384
- onClick={() => setCollapsed((value) => !value)}
385
- aria-label={
386
- collapsed
387
- ? t("navigation.expandSidebar")
388
- : t("navigation.collapseSidebar")
389
- }
390
- className={cn(
391
- "flex items-center gap-2 rounded outline-none transition-colors hover:bg-sidebar-accent/50 focus-visible:ring-2 focus-visible:ring-ring",
392
- collapsed ? "size-8 justify-center" : "text-start",
393
- )}
394
- data-sidebar-brand-toggle
395
- >
396
- <AgentNativeIcon
397
- aria-hidden="true"
398
- className="h-3.5 w-6 shrink-0 text-sidebar-foreground"
399
- />
400
- {!collapsed && (
401
- <span className="text-sm font-semibold tracking-tight">
402
- {t("navigation.brand")}
403
- </span>
404
- )}
405
- </button>
406
- );
407
362
 
408
363
  return (
409
- <aside
410
- className={cn(
411
- "flex h-full min-w-0 shrink-0 flex-col overflow-hidden border-e border-border bg-sidebar text-sidebar-foreground transition-[width] duration-200 ease-out",
412
- collapsed ? "w-14" : "w-56",
413
- )}
364
+ <AppSidebar
365
+ collapsed={collapsed}
366
+ onCollapsedChange={setCollapsed}
367
+ brandName={t("navigation.brand")}
368
+ brandHref="/home"
369
+ secondaryItems={secondaryItems}
370
+ feedback={feedbackButton}
371
+ orgSwitcher={orgSwitcher}
372
+ footerExtras={
373
+ <>
374
+ {searchButton}
375
+ <DevDatabaseLink />
376
+ </>
377
+ }
414
378
  >
415
- <div
416
- className={cn(
417
- "flex h-12 shrink-0 items-center border-b border-border",
418
- collapsed ? "justify-center px-2" : "justify-between px-4",
419
- )}
420
- >
421
- {brandControl}
422
- </div>
423
-
424
- <div className="flex min-h-0 flex-1 flex-col overflow-y-auto">
425
- <nav
426
- className={cn(
427
- "space-y-1 py-2",
428
- collapsed ? "flex flex-col items-center px-1.5" : "px-2",
429
- )}
430
- >
431
- {navItems.map((item) => {
432
- const Icon = item.icon;
433
- const isActive =
434
- item.href === "/home"
435
- ? isCreateRoute
436
- : item.href === "/library"
437
- ? location.pathname === "/library" ||
438
- location.pathname.startsWith("/library/") ||
439
- location.pathname.startsWith("/brand-kits/") ||
440
- location.pathname.startsWith("/image/") ||
441
- location.pathname.startsWith("/asset/")
442
- : item.href === "/templates"
443
- ? location.pathname === "/templates" ||
444
- location.pathname.startsWith("/templates/")
445
- : location.pathname.startsWith(item.href);
446
- const link = (
447
- <Link
448
- key={item.href}
449
- to={item.href}
450
- onClick={(event) => {
451
- if (
452
- item.href === "/home" &&
453
- !event.metaKey &&
454
- !event.ctrlKey &&
455
- !event.shiftKey &&
456
- !event.altKey
457
- ) {
458
- event.preventDefault();
459
- focusAgentChat();
460
- if (!isCreateRoute || location.pathname !== "/home") {
461
- navigateWithAgentChatViewTransition(navigate, "/home");
462
- }
379
+ {navItems.map((item) => {
380
+ const isActive =
381
+ item.href === "/home"
382
+ ? isCreateRoute
383
+ : item.href === "/library"
384
+ ? location.pathname === "/library" ||
385
+ location.pathname.startsWith("/library/") ||
386
+ location.pathname.startsWith("/brand-kits/") ||
387
+ location.pathname.startsWith("/image/") ||
388
+ location.pathname.startsWith("/asset/")
389
+ : item.href === "/templates"
390
+ ? location.pathname === "/templates" ||
391
+ location.pathname.startsWith("/templates/")
392
+ : location.pathname.startsWith(item.href);
393
+
394
+ return (
395
+ <div key={item.href}>
396
+ <AppSidebarNavItem
397
+ to={item.href}
398
+ label={t(item.labelKey)}
399
+ icon={item.icon}
400
+ active={isActive}
401
+ onClick={(event) => {
402
+ if (
403
+ item.href === "/home" &&
404
+ !event.metaKey &&
405
+ !event.ctrlKey &&
406
+ !event.shiftKey &&
407
+ !event.altKey
408
+ ) {
409
+ event.preventDefault();
410
+ focusAgentChat();
411
+ if (!isCreateRoute || location.pathname !== "/home") {
412
+ navigateWithAgentChatViewTransition(navigate, "/home");
463
413
  }
464
- }}
465
- className={cn(
466
- "flex items-center rounded-lg text-sm",
467
- collapsed ? "h-9 w-9 justify-center" : "gap-3 px-3 py-2",
468
- isActive
469
- ? "bg-sidebar-accent text-sidebar-accent-foreground"
470
- : "text-muted-foreground hover:bg-sidebar-accent/50 hover:text-foreground",
471
- )}
472
- >
473
- <Icon className="h-4 w-4 shrink-0" />
474
- {!collapsed && t(item.labelKey)}
475
- </Link>
476
- );
477
- if (collapsed) {
478
- return (
479
- <Tooltip key={item.href} delayDuration={0}>
480
- <TooltipTrigger asChild>{link}</TooltipTrigger>
481
- <TooltipContent side="right">
482
- {t(item.labelKey)}
483
- </TooltipContent>
484
- </Tooltip>
485
- );
486
- }
487
- return (
488
- <div key={item.href}>
489
- {link}
490
- {item.href === "/home" ? (
491
- <AssetsChatsSection open={isCreateRoute} />
492
- ) : null}
493
- </div>
494
- );
495
- })}
496
- </nav>
497
-
498
- <div className="mt-auto shrink-0">
499
- <nav
500
- className={cn(
501
- "grid gap-1",
502
- collapsed ? "justify-items-center px-1.5 py-1" : "px-2 py-1",
503
- )}
504
- >
505
- {bottomNavItems.map((item) => {
506
- const Icon = item.icon;
507
- const isActive = location.pathname.startsWith(item.href);
508
- const link = (
509
- <Link
510
- to={item.href}
511
- className={cn(
512
- "flex items-center rounded-lg text-sm",
513
- collapsed ? "h-9 w-9 justify-center" : "gap-3 px-3 py-2",
514
- isActive
515
- ? "bg-sidebar-accent text-sidebar-accent-foreground"
516
- : "text-muted-foreground hover:bg-sidebar-accent/50 hover:text-foreground",
517
- )}
518
- aria-label={collapsed ? t(item.labelKey) : undefined}
519
- >
520
- <Icon className="h-4 w-4 shrink-0" />
521
- {!collapsed && t(item.labelKey)}
522
- </Link>
523
- );
524
- return collapsed ? (
525
- <Tooltip key={item.href} delayDuration={0}>
526
- <TooltipTrigger asChild>{link}</TooltipTrigger>
527
- <TooltipContent side="right">
528
- {t(item.labelKey)}
529
- </TooltipContent>
530
- </Tooltip>
531
- ) : (
532
- <div key={item.href}>{link}</div>
533
- );
534
- })}
535
- </nav>
536
-
537
- {!collapsed && (
538
- <div className="px-3 py-2 empty:hidden">
539
- <OrgSwitcher />
540
- </div>
541
- )}
542
-
543
- {!collapsed && (
544
- <div className="px-3 py-2 empty:hidden">
545
- <DevDatabaseLink />
546
- </div>
547
- )}
548
- </div>
549
- </div>
550
- <SidebarFooterActions
551
- collapsed={collapsed}
552
- feedback={feedbackButton}
553
- search={searchButton}
554
- collapse={collapseButton}
555
- />
556
- </aside>
414
+ }
415
+ }}
416
+ />
417
+ {!collapsed && item.href === "/home" ? (
418
+ <AssetsChatsSection open={isCreateRoute} />
419
+ ) : null}
420
+ </div>
421
+ );
422
+ })}
423
+ </AppSidebar>
557
424
  );
558
425
  }
@@ -37,6 +37,29 @@ import { getDb, schema } from "../db/index.js";
37
37
  export const DRAFT_ROLE: ShareRole = "viewer";
38
38
  export const APPROVE_ROLE: ShareRole = "editor";
39
39
 
40
+ /**
41
+ * The creative-context access target for provenance on a draft this caller
42
+ * just created in `libraryId`.
43
+ *
44
+ * Recording it needs only `DRAFT_ROLE`, because the artifact is the caller's
45
+ * own candidate run/asset/session rather than kit content. Defaulting to
46
+ * `editor` there is what made every viewer generation die mid-turn with a bare
47
+ * `Requires editor role on asset-library <id> (have viewer)` — the kit gate had
48
+ * already passed, so the refusal arrived with no remedy and read as a
49
+ * permanent precondition the caller could not act on.
50
+ */
51
+ export function draftProvenanceAccess(libraryId: string): {
52
+ resourceType: "asset-library";
53
+ resourceId: string;
54
+ recordMinRole: "viewer";
55
+ } {
56
+ return {
57
+ resourceType: "asset-library",
58
+ resourceId: libraryId,
59
+ recordMinRole: "viewer",
60
+ };
61
+ }
62
+
40
63
  export interface LibraryWriteAccess {
41
64
  role: ShareRole | "owner";
42
65
  /** True when this caller may save and organize, not only draft. */