@contractspec/bundle.marketing 3.8.8 → 3.8.10

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 (96) hide show
  1. package/.turbo/turbo-build.log +73 -29
  2. package/CHANGELOG.md +63 -0
  3. package/dist/browser/components/templates/TemplateCard.js +83 -0
  4. package/dist/browser/components/templates/TemplateCommandDialog.js +110 -0
  5. package/dist/browser/components/templates/TemplatePreviewContent.js +96 -0
  6. package/dist/browser/components/templates/TemplatesBrowseControls.js +130 -0
  7. package/dist/browser/components/templates/TemplatesCatalogSection.js +307 -0
  8. package/dist/browser/components/templates/TemplatesClientPage.js +1020 -917
  9. package/dist/browser/components/templates/TemplatesHeroSection.js +87 -0
  10. package/dist/browser/components/templates/TemplatesNextStepsSection.js +126 -0
  11. package/dist/browser/components/templates/TemplatesOverlays.js +2874 -0
  12. package/dist/browser/components/templates/TemplatesPreviewModal.js +136 -126
  13. package/dist/browser/components/templates/index.js +1055 -952
  14. package/dist/browser/components/templates/template-catalog.js +83 -0
  15. package/dist/browser/components/templates/template-filters.js +99 -0
  16. package/dist/browser/components/templates/template-new.js +23 -0
  17. package/dist/browser/components/templates/template-preview.js +43 -0
  18. package/dist/browser/components/templates/template-source.js +19 -0
  19. package/dist/browser/components/templates/template-tag-visibility.js +40 -0
  20. package/dist/browser/components/templates/useTemplateBrowseState.js +191 -0
  21. package/dist/browser/index.js +1055 -952
  22. package/dist/components/templates/TemplateCard.d.ts +12 -0
  23. package/dist/components/templates/TemplateCard.js +78 -0
  24. package/dist/components/templates/TemplateCommandDialog.d.ts +6 -0
  25. package/dist/components/templates/TemplateCommandDialog.js +105 -0
  26. package/dist/components/templates/TemplatePreviewContent.d.ts +5 -0
  27. package/dist/components/templates/TemplatePreviewContent.js +91 -0
  28. package/dist/components/templates/TemplatesBrowseControls.d.ts +18 -0
  29. package/dist/components/templates/TemplatesBrowseControls.js +125 -0
  30. package/dist/components/templates/TemplatesCatalogSection.d.ts +17 -0
  31. package/dist/components/templates/TemplatesCatalogSection.js +302 -0
  32. package/dist/components/templates/TemplatesClientPage.js +1020 -917
  33. package/dist/components/templates/TemplatesHeroSection.d.ts +5 -0
  34. package/dist/components/templates/TemplatesHeroSection.js +82 -0
  35. package/dist/components/templates/TemplatesNextStepsSection.d.ts +1 -0
  36. package/dist/components/templates/TemplatesNextStepsSection.js +121 -0
  37. package/dist/components/templates/TemplatesOverlays.d.ts +10 -0
  38. package/dist/components/templates/TemplatesOverlays.js +2869 -0
  39. package/dist/components/templates/TemplatesPreviewModal.d.ts +3 -4
  40. package/dist/components/templates/TemplatesPreviewModal.js +136 -126
  41. package/dist/components/templates/index.js +1055 -952
  42. package/dist/components/templates/template-catalog.d.ts +28 -0
  43. package/dist/components/templates/template-catalog.js +78 -0
  44. package/dist/components/templates/template-catalog.test.d.ts +1 -0
  45. package/dist/components/templates/template-filters.d.ts +12 -0
  46. package/dist/components/templates/template-filters.js +94 -0
  47. package/dist/components/templates/template-new.d.ts +2 -0
  48. package/dist/components/templates/template-new.js +18 -0
  49. package/dist/components/templates/template-preview.d.ts +18 -0
  50. package/dist/components/templates/template-preview.js +38 -0
  51. package/dist/components/templates/template-source.d.ts +3 -0
  52. package/dist/components/templates/template-source.js +14 -0
  53. package/dist/components/templates/template-tag-visibility.d.ts +10 -0
  54. package/dist/components/templates/template-tag-visibility.js +35 -0
  55. package/dist/components/templates/useTemplateBrowseState.d.ts +22 -0
  56. package/dist/components/templates/useTemplateBrowseState.js +186 -0
  57. package/dist/index.js +1055 -952
  58. package/dist/node/components/templates/TemplateCard.js +78 -0
  59. package/dist/node/components/templates/TemplateCommandDialog.js +105 -0
  60. package/dist/node/components/templates/TemplatePreviewContent.js +91 -0
  61. package/dist/node/components/templates/TemplatesBrowseControls.js +125 -0
  62. package/dist/node/components/templates/TemplatesCatalogSection.js +302 -0
  63. package/dist/node/components/templates/TemplatesClientPage.js +1020 -917
  64. package/dist/node/components/templates/TemplatesHeroSection.js +82 -0
  65. package/dist/node/components/templates/TemplatesNextStepsSection.js +121 -0
  66. package/dist/node/components/templates/TemplatesOverlays.js +2869 -0
  67. package/dist/node/components/templates/TemplatesPreviewModal.js +136 -126
  68. package/dist/node/components/templates/index.js +1055 -952
  69. package/dist/node/components/templates/template-catalog.js +78 -0
  70. package/dist/node/components/templates/template-filters.js +94 -0
  71. package/dist/node/components/templates/template-new.js +18 -0
  72. package/dist/node/components/templates/template-preview.js +38 -0
  73. package/dist/node/components/templates/template-source.js +14 -0
  74. package/dist/node/components/templates/template-tag-visibility.js +35 -0
  75. package/dist/node/components/templates/useTemplateBrowseState.js +186 -0
  76. package/dist/node/index.js +1055 -952
  77. package/package.json +237 -26
  78. package/src/components/templates/TemplateCard.tsx +74 -0
  79. package/src/components/templates/TemplateCommandDialog.tsx +92 -0
  80. package/src/components/templates/TemplatePreviewContent.tsx +182 -0
  81. package/src/components/templates/TemplatesBrowseControls.tsx +144 -0
  82. package/src/components/templates/TemplatesCatalogSection.tsx +191 -0
  83. package/src/components/templates/TemplatesClientPage.tsx +85 -773
  84. package/src/components/templates/TemplatesHeroSection.tsx +41 -0
  85. package/src/components/templates/TemplatesNextStepsSection.tsx +80 -0
  86. package/src/components/templates/TemplatesOverlays.tsx +65 -0
  87. package/src/components/templates/TemplatesPreviewModal.tsx +19 -294
  88. package/src/components/templates/template-catalog.test.ts +162 -0
  89. package/src/components/templates/template-catalog.ts +140 -0
  90. package/src/components/templates/template-filters.ts +57 -0
  91. package/src/components/templates/template-new.ts +12 -0
  92. package/src/components/templates/template-preview.ts +57 -0
  93. package/src/components/templates/template-source.ts +13 -0
  94. package/src/components/templates/template-tag-visibility.ts +58 -0
  95. package/src/components/templates/useTemplateBrowseState.ts +101 -0
  96. package/.turbo/turbo-prebuild.log +0 -1
@@ -2566,989 +2566,1092 @@ function PricingThinkingModal({
2566
2566
  }, undefined, true, undefined, this)
2567
2567
  }, undefined, false, undefined, this);
2568
2568
  }
2569
- // src/components/templates/TemplatesPreviewModal.tsx
2570
- import { LoadingSpinner } from "@contractspec/lib.ui-kit-web/ui/atoms/LoadingSpinner";
2571
- import { Dialog as Dialog2, DialogContent as DialogContent2 } from "@contractspec/lib.ui-kit-web/ui/dialog";
2572
- import { ScrollArea } from "@contractspec/lib.ui-kit-web/ui/scroll-area";
2573
- import dynamic from "next/dynamic";
2574
- import { useMemo } from "react";
2569
+ // src/components/templates/TemplateCard.tsx
2575
2570
  import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
2576
2571
  "use client";
2577
- var TemplateShell = dynamic(() => import("@contractspec/lib.example-shared-ui").then((mod) => mod.TemplateShell), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2578
- var TodosTaskList = dynamic(() => import("@contractspec/bundle.library/components/templates/todos/TaskList").then((mod) => mod.TaskList), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2579
- var MessagingWorkspace = dynamic(() => import("@contractspec/bundle.library/components/templates/messaging/MessagingWorkspace").then((mod) => mod.MessagingWorkspace), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2580
- var RecipesExperience = dynamic(() => import("@contractspec/bundle.library/components/templates/recipes/RecipeList").then((mod) => mod.RecipeList), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2581
- var SaasDashboard = dynamic(() => import("@contractspec/example.saas-boilerplate").then((mod) => mod.SaasDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2582
- var CrmDashboard = dynamic(() => import("@contractspec/example.crm-pipeline").then((mod) => mod.CrmDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2583
- var DataGridShowcase = dynamic(() => import("@contractspec/example.data-grid-showcase/ui").then((mod) => mod.DataGridShowcase), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2584
- var VisualizationShowcase = dynamic(() => import("@contractspec/example.visualization-showcase/ui").then((mod) => mod.VisualizationShowcase), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2585
- var AgentDashboard = dynamic(() => import("@contractspec/example.agent-console/ui").then((mod) => mod.AgentDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2586
- var WorkflowDashboard = dynamic(() => import("@contractspec/example.workflow-system/ui").then((mod) => mod.WorkflowDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2587
- var MarketplaceDashboard = dynamic(() => import("@contractspec/example.marketplace/ui").then((mod) => mod.MarketplaceDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2588
- var IntegrationDashboard = dynamic(() => import("@contractspec/example.integration-hub/ui").then((mod) => mod.IntegrationDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2589
- var AnalyticsDashboard = dynamic(() => import("@contractspec/example.analytics-dashboard").then((mod) => mod.AnalyticsDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2590
- var AiChatAssistantDashboard = dynamic(() => import("@contractspec/example.ai-chat-assistant").then((mod) => mod.AiChatAssistantDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2591
- var TemplatePreviewModal = ({
2592
- templateId,
2593
- onClose
2594
- }) => {
2595
- const previewComponent = useMemo(() => {
2596
- switch (templateId) {
2597
- case "todos-app":
2598
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2599
- title: "Starter tasks",
2600
- description: "Track work items with filters, priorities, and per-tenant data isolation.",
2601
- showSaveAction: false,
2602
- children: /* @__PURE__ */ jsxDEV11(TodosTaskList, {}, undefined, false, undefined, this)
2603
- }, undefined, false, undefined, this);
2604
- case "messaging-app":
2605
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2606
- title: "Messaging workspace",
2607
- description: "Realtime-ready messaging surface with optimistic delivery.",
2608
- showSaveAction: false,
2609
- children: /* @__PURE__ */ jsxDEV11(MessagingWorkspace, {}, undefined, false, undefined, this)
2610
- }, undefined, false, undefined, this);
2611
- case "recipe-app-i18n":
2612
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2613
- title: "Ceremony recipes",
2614
- description: "Switch locales and preview how rituals translate across teams.",
2615
- showSaveAction: false,
2616
- children: /* @__PURE__ */ jsxDEV11(RecipesExperience, {}, undefined, false, undefined, this)
2617
- }, undefined, false, undefined, this);
2618
- case "saas-boilerplate":
2619
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2620
- title: "SaaS Boilerplate",
2621
- description: "Multi-tenant organizations, projects, settings, and billing usage tracking.",
2622
- showSaveAction: false,
2623
- children: /* @__PURE__ */ jsxDEV11(SaasDashboard, {}, undefined, false, undefined, this)
2624
- }, undefined, false, undefined, this);
2625
- case "crm-pipeline":
2626
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2627
- title: "CRM Pipeline",
2628
- description: "Sales CRM with contacts, companies, deals, and pipeline stages.",
2629
- showSaveAction: false,
2630
- children: /* @__PURE__ */ jsxDEV11(CrmDashboard, {}, undefined, false, undefined, this)
2631
- }, undefined, false, undefined, this);
2632
- case "data-grid-showcase":
2633
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2634
- title: "Data Grid Showcase",
2635
- description: "Shared ContractSpec table primitives with client, server, and DataView-driven lanes.",
2636
- showSaveAction: false,
2637
- children: /* @__PURE__ */ jsxDEV11(DataGridShowcase, {}, undefined, false, undefined, this)
2638
- }, undefined, false, undefined, this);
2639
- case "visualization-showcase":
2640
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2641
- title: "Visualization Showcase",
2642
- description: "ContractSpec-owned chart primitives rendered through shared visualization contracts and design-system wrappers.",
2643
- showSaveAction: false,
2644
- children: /* @__PURE__ */ jsxDEV11(VisualizationShowcase, {}, undefined, false, undefined, this)
2645
- }, undefined, false, undefined, this);
2646
- case "agent-console":
2647
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2648
- title: "AI Agent Console",
2649
- description: "AI agent orchestration with tools, agents, runs, and execution logs.",
2650
- showSaveAction: false,
2651
- children: /* @__PURE__ */ jsxDEV11(AgentDashboard, {}, undefined, false, undefined, this)
2652
- }, undefined, false, undefined, this);
2653
- case "ai-chat-assistant":
2654
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2655
- title: "AI Chat Assistant",
2656
- description: "Focused assistant surface with reasoning, sources, suggestions, and MCP-aware tools.",
2657
- showSaveAction: false,
2658
- children: /* @__PURE__ */ jsxDEV11(AiChatAssistantDashboard, {}, undefined, false, undefined, this)
2659
- }, undefined, false, undefined, this);
2660
- case "workflow-system":
2661
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2662
- title: "Workflow System",
2663
- description: "Multi-step workflows with role-based approvals.",
2664
- showSaveAction: false,
2665
- children: /* @__PURE__ */ jsxDEV11(WorkflowDashboard, {}, undefined, false, undefined, this)
2666
- }, undefined, false, undefined, this);
2667
- case "marketplace":
2668
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2669
- title: "Marketplace",
2670
- description: "Two-sided marketplace with stores, products, and orders.",
2671
- showSaveAction: false,
2672
- children: /* @__PURE__ */ jsxDEV11(MarketplaceDashboard, {}, undefined, false, undefined, this)
2673
- }, undefined, false, undefined, this);
2674
- case "integration-hub":
2675
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2676
- title: "Integration Hub",
2677
- description: "Third-party integrations with sync and field mapping.",
2678
- showSaveAction: false,
2679
- children: /* @__PURE__ */ jsxDEV11(IntegrationDashboard, {}, undefined, false, undefined, this)
2680
- }, undefined, false, undefined, this);
2681
- case "analytics-dashboard":
2682
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2683
- title: "Analytics Dashboard",
2684
- description: "Custom dashboards with widgets and queries.",
2685
- showSaveAction: false,
2686
- children: /* @__PURE__ */ jsxDEV11(AnalyticsDashboard, {}, undefined, false, undefined, this)
2687
- }, undefined, false, undefined, this);
2688
- case null:
2689
- return null;
2690
- default:
2691
- return null;
2692
- }
2693
- }, [templateId]);
2694
- return /* @__PURE__ */ jsxDEV11(Dialog2, {
2695
- open: !!previewComponent,
2696
- onOpenChange: onClose,
2697
- children: /* @__PURE__ */ jsxDEV11(DialogContent2, {
2698
- className: "mb-8 flex h-[calc(100vh-2rem)] min-w-[calc(100vw-2rem)] flex-col justify-between gap-0 p-0",
2699
- children: /* @__PURE__ */ jsxDEV11(ScrollArea, {
2700
- className: "flex flex-col justify-between overflow-hidden",
2701
- children: previewComponent
2702
- }, undefined, false, undefined, this)
2703
- }, undefined, false, undefined, this)
2704
- }, undefined, false, undefined, this);
2705
- };
2572
+ function TemplateCard({
2573
+ title,
2574
+ description,
2575
+ metaBadges,
2576
+ tags,
2577
+ featureList = [],
2578
+ isNew = false,
2579
+ previewAction,
2580
+ useAction
2581
+ }) {
2582
+ return /* @__PURE__ */ jsxDEV11("div", {
2583
+ className: "editorial-panel relative flex flex-col space-y-4 transition-colors hover:border-[color:rgb(162_79_42_/_0.55)]",
2584
+ children: [
2585
+ isNew ? /* @__PURE__ */ jsxDEV11("span", {
2586
+ className: "absolute top-4 right-4 rounded-full bg-[color:var(--success)] px-2.5 py-1 font-medium text-[11px] text-white uppercase",
2587
+ children: "New"
2588
+ }, undefined, false, undefined, this) : null,
2589
+ /* @__PURE__ */ jsxDEV11("div", {
2590
+ children: [
2591
+ /* @__PURE__ */ jsxDEV11("h3", {
2592
+ className: "font-serif text-2xl tracking-[-0.03em]",
2593
+ children: title
2594
+ }, undefined, false, undefined, this),
2595
+ /* @__PURE__ */ jsxDEV11("p", {
2596
+ className: "mt-1 text-muted-foreground text-sm",
2597
+ children: description
2598
+ }, undefined, false, undefined, this)
2599
+ ]
2600
+ }, undefined, true, undefined, this),
2601
+ /* @__PURE__ */ jsxDEV11("div", {
2602
+ className: "flex-1 space-y-3",
2603
+ children: [
2604
+ /* @__PURE__ */ jsxDEV11("div", {
2605
+ className: "flex flex-wrap gap-2",
2606
+ children: metaBadges.map((badge) => /* @__PURE__ */ jsxDEV11("span", {
2607
+ className: "rounded-full border border-border bg-background px-3 py-1 text-[11px] text-foreground",
2608
+ children: badge
2609
+ }, badge, false, undefined, this))
2610
+ }, undefined, false, undefined, this),
2611
+ featureList.length > 0 ? /* @__PURE__ */ jsxDEV11("p", {
2612
+ className: "text-muted-foreground text-xs",
2613
+ children: [
2614
+ /* @__PURE__ */ jsxDEV11("span", {
2615
+ className: "font-medium text-foreground",
2616
+ children: "Features:"
2617
+ }, undefined, false, undefined, this),
2618
+ " ",
2619
+ featureList.join(", ")
2620
+ ]
2621
+ }, undefined, true, undefined, this) : null,
2622
+ /* @__PURE__ */ jsxDEV11("div", {
2623
+ className: "flex flex-wrap gap-1",
2624
+ children: tags.map((tag) => /* @__PURE__ */ jsxDEV11("span", {
2625
+ className: "rounded-full border border-border bg-muted px-3 py-1 text-[11px] text-muted-foreground",
2626
+ children: tag
2627
+ }, tag, false, undefined, this))
2628
+ }, undefined, false, undefined, this)
2629
+ ]
2630
+ }, undefined, true, undefined, this),
2631
+ /* @__PURE__ */ jsxDEV11("div", {
2632
+ className: "flex gap-2 pt-4",
2633
+ children: [
2634
+ previewAction,
2635
+ useAction
2636
+ ]
2637
+ }, undefined, true, undefined, this)
2638
+ ]
2639
+ }, undefined, true, undefined, this);
2640
+ }
2706
2641
 
2707
- // src/components/templates/TemplatesClientPage.tsx
2642
+ // src/components/templates/TemplateCommandDialog.tsx
2708
2643
  import {
2709
2644
  analyticsEventNames as analyticsEventNames2,
2710
2645
  captureAnalyticsEvent as captureAnalyticsEvent2
2711
2646
  } from "@contractspec/bundle.library/libs/posthog/client";
2712
- import { useRegistryTemplates } from "@contractspec/lib.example-shared-ui";
2713
- import { cn } from "@contractspec/lib.ui-kit-core/utils";
2714
2647
  import {
2715
- Dialog as Dialog3,
2716
- DialogContent as DialogContent3,
2648
+ Dialog as Dialog2,
2649
+ DialogContent as DialogContent2,
2717
2650
  DialogDescription as DialogDescription2,
2718
2651
  DialogHeader as DialogHeader2,
2719
2652
  DialogTitle as DialogTitle2
2720
2653
  } from "@contractspec/lib.ui-kit-web/ui/dialog";
2721
- import {
2722
- Tooltip,
2723
- TooltipContent,
2724
- TooltipProvider,
2725
- TooltipTrigger
2726
- } from "@contractspec/lib.ui-kit-web/ui/tooltip";
2727
- import { getTemplate } from "@contractspec/module.examples";
2728
- import { Search } from "lucide-react";
2729
- import Link8 from "next/link";
2730
- import { useState as useState2 } from "react";
2731
2654
  import { jsxDEV as jsxDEV12 } from "react/jsx-dev-runtime";
2732
2655
  "use client";
2733
- var templates = [
2734
- {
2735
- id: "minimal-example",
2736
- templateId: "todos-app",
2737
- title: "Minimal Example",
2738
- description: "A minimal template to get you running in minutes. Perfect for exploring the engine.",
2739
- tags: ["Getting Started"],
2740
- capabilities: "Basic Forms, Auth",
2741
- isStarter: true,
2742
- previewUrl: "/sandbox?template=minimal-example",
2743
- docsUrl: "/docs/getting-started/hello-world"
2744
- },
2745
- {
2746
- id: "saas-boilerplate",
2747
- templateId: "saas-boilerplate",
2656
+ function TemplateCommandDialog({
2657
+ templateId,
2658
+ onClose,
2659
+ onDeployStudio
2660
+ }) {
2661
+ const command = templateId ? `npx contractspec init --template ${templateId}` : "";
2662
+ return /* @__PURE__ */ jsxDEV12(Dialog2, {
2663
+ open: !!templateId,
2664
+ onOpenChange: (open) => !open && onClose(),
2665
+ children: /* @__PURE__ */ jsxDEV12(DialogContent2, {
2666
+ className: "max-w-md",
2667
+ children: [
2668
+ /* @__PURE__ */ jsxDEV12(DialogHeader2, {
2669
+ children: [
2670
+ /* @__PURE__ */ jsxDEV12(DialogTitle2, {
2671
+ children: "Use this template"
2672
+ }, undefined, false, undefined, this),
2673
+ /* @__PURE__ */ jsxDEV12(DialogDescription2, {
2674
+ children: "Initialize a new project with this template using the CLI."
2675
+ }, undefined, false, undefined, this)
2676
+ ]
2677
+ }, undefined, true, undefined, this),
2678
+ /* @__PURE__ */ jsxDEV12("div", {
2679
+ className: "space-y-4 pt-4",
2680
+ children: [
2681
+ /* @__PURE__ */ jsxDEV12("div", {
2682
+ className: "rounded-md border border-zinc-800 bg-zinc-950 p-4 font-mono text-sm text-zinc-50",
2683
+ children: command
2684
+ }, undefined, false, undefined, this),
2685
+ /* @__PURE__ */ jsxDEV12("div", {
2686
+ className: "flex gap-2",
2687
+ children: /* @__PURE__ */ jsxDEV12("button", {
2688
+ className: "btn-secondary w-full",
2689
+ onClick: () => {
2690
+ if (!templateId) {
2691
+ return;
2692
+ }
2693
+ navigator.clipboard.writeText(command);
2694
+ captureAnalyticsEvent2(analyticsEventNames2.COPY_COMMAND_CLICK, {
2695
+ surface: "templates",
2696
+ templateId,
2697
+ filename: "templates-cli"
2698
+ });
2699
+ },
2700
+ children: "Copy Command"
2701
+ }, undefined, false, undefined, this)
2702
+ }, undefined, false, undefined, this),
2703
+ /* @__PURE__ */ jsxDEV12("div", {
2704
+ className: "relative",
2705
+ children: [
2706
+ /* @__PURE__ */ jsxDEV12("div", {
2707
+ className: "absolute inset-0 flex items-center",
2708
+ children: /* @__PURE__ */ jsxDEV12("span", {
2709
+ className: "w-full border-border border-t"
2710
+ }, undefined, false, undefined, this)
2711
+ }, undefined, false, undefined, this),
2712
+ /* @__PURE__ */ jsxDEV12("div", {
2713
+ className: "relative flex justify-center text-xs uppercase",
2714
+ children: /* @__PURE__ */ jsxDEV12("span", {
2715
+ className: "bg-background px-2 text-muted-foreground",
2716
+ children: "Or"
2717
+ }, undefined, false, undefined, this)
2718
+ }, undefined, false, undefined, this)
2719
+ ]
2720
+ }, undefined, true, undefined, this),
2721
+ /* @__PURE__ */ jsxDEV12("button", {
2722
+ className: "btn-ghost w-full text-sm",
2723
+ onClick: () => {
2724
+ if (!templateId) {
2725
+ return;
2726
+ }
2727
+ captureAnalyticsEvent2(analyticsEventNames2.CTA_STUDIO_CLICK, {
2728
+ surface: "templates",
2729
+ templateId
2730
+ });
2731
+ onDeployStudio();
2732
+ },
2733
+ children: "Deploy to Studio"
2734
+ }, undefined, false, undefined, this)
2735
+ ]
2736
+ }, undefined, true, undefined, this)
2737
+ ]
2738
+ }, undefined, true, undefined, this)
2739
+ }, undefined, false, undefined, this);
2740
+ }
2741
+
2742
+ // src/components/templates/TemplatePreviewContent.tsx
2743
+ import {
2744
+ TemplateShell
2745
+ } from "@contractspec/lib.example-shared-ui";
2746
+ import { LoadingSpinner } from "@contractspec/lib.ui-kit-web/ui/atoms/LoadingSpinner";
2747
+ import dynamic from "next/dynamic";
2748
+ import { jsxDEV as jsxDEV13 } from "react/jsx-dev-runtime";
2749
+ "use client";
2750
+ var SaasDashboard = dynamic(() => import("@contractspec/example.saas-boilerplate").then((module) => module.SaasDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2751
+ var CrmDashboard = dynamic(() => import("@contractspec/example.crm-pipeline").then((module) => module.CrmDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2752
+ var DataGridShowcase = dynamic(() => import("@contractspec/example.data-grid-showcase/ui").then((module) => module.DataGridShowcase), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2753
+ var VisualizationShowcase = dynamic(() => import("@contractspec/example.visualization-showcase/ui").then((module) => module.VisualizationShowcase), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2754
+ var AgentDashboard = dynamic(() => import("@contractspec/example.agent-console/ui").then((module) => module.AgentDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2755
+ var AiChatAssistantDashboard = dynamic(() => import("@contractspec/example.ai-chat-assistant").then((module) => module.AiChatAssistantDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2756
+ var WorkflowDashboard = dynamic(() => import("@contractspec/example.workflow-system/ui").then((module) => module.WorkflowDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2757
+ var MarketplaceDashboard = dynamic(() => import("@contractspec/example.marketplace/ui").then((module) => module.MarketplaceDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2758
+ var IntegrationDashboard = dynamic(() => import("@contractspec/example.integration-hub/ui").then((module) => module.IntegrationDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2759
+ var AnalyticsDashboard = dynamic(() => import("@contractspec/example.analytics-dashboard").then((module) => module.AnalyticsDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2760
+ var PREVIEW_DEFINITIONS = {
2761
+ "saas-boilerplate": {
2748
2762
  title: "SaaS Boilerplate",
2749
- description: "Complete SaaS foundation with multi-tenant orgs, projects, settings, and billing usage.",
2750
- tags: ["Getting Started", "SaaS", "Business"],
2751
- capabilities: "Multi-tenancy, RBAC, Projects, Billing",
2752
- isNew: true,
2753
- previewUrl: "/sandbox?template=saas-boilerplate",
2754
- docsUrl: "/docs/templates/saas-boilerplate"
2763
+ description: "Multi-tenant organizations, projects, settings, and billing usage tracking.",
2764
+ component: SaasDashboard
2755
2765
  },
2756
- {
2757
- id: "crm-pipeline",
2758
- templateId: "crm-pipeline",
2766
+ "crm-pipeline": {
2759
2767
  title: "CRM Pipeline",
2760
- description: "Sales CRM with contacts, companies, deals, pipeline stages, and task management.",
2761
- tags: ["CRM", "Business"],
2762
- capabilities: "Contacts, Deals, Pipelines, Tasks",
2763
- isNew: true,
2764
- previewUrl: "/sandbox?template=crm-pipeline",
2765
- docsUrl: "/docs/templates/crm-pipeline"
2768
+ description: "Sales CRM with contacts, companies, deals, and pipeline stages.",
2769
+ component: CrmDashboard
2766
2770
  },
2767
- {
2768
- id: "data-grid-showcase",
2769
- templateId: "data-grid-showcase",
2771
+ "data-grid-showcase": {
2770
2772
  title: "Data Grid Showcase",
2771
- description: "Focused example for ContractSpec headless tables across client, server, and DataView-driven lanes.",
2772
- tags: ["Ops", "Business"],
2773
- capabilities: "Tables, Sorting, Pagination, Column Controls",
2774
- isNew: true,
2775
- previewUrl: "/sandbox?template=data-grid-showcase",
2776
- docsUrl: "/docs/examples/data-grid-showcase"
2773
+ description: "Shared ContractSpec table primitives with client, server, and DataView-driven lanes.",
2774
+ component: DataGridShowcase
2777
2775
  },
2778
- {
2779
- id: "visualization-showcase",
2780
- templateId: "visualization-showcase",
2776
+ "visualization-showcase": {
2781
2777
  title: "Visualization Showcase",
2782
- description: "Canonical ContractSpec example for chart primitives, shared visualization contracts, and opinionated dashboard blocks.",
2783
- tags: ["Ops", "Visualization"],
2784
- capabilities: "Metrics, Charts, Timelines, Comparisons",
2785
- isNew: true,
2786
- previewUrl: "/sandbox?template=visualization-showcase",
2787
- docsUrl: "/docs/examples/visualization-showcase"
2778
+ description: "ContractSpec-owned chart primitives rendered through shared visualization contracts and design-system wrappers.",
2779
+ component: VisualizationShowcase
2788
2780
  },
2789
- {
2790
- id: "agent-console",
2791
- templateId: "agent-console",
2781
+ "agent-console": {
2792
2782
  title: "AI Agent Console",
2793
- description: "AI agent orchestration platform with tools, agents, runs, and execution logs.",
2794
- tags: ["AI", "Ops"],
2795
- capabilities: "Tools, Agents, Runs, Metrics",
2796
- isNew: true,
2797
- previewUrl: "/sandbox?template=agent-console",
2798
- docsUrl: "/docs/examples/agent-console"
2783
+ description: "AI agent orchestration with tools, agents, runs, and execution logs.",
2784
+ component: AgentDashboard
2799
2785
  },
2800
- {
2801
- id: "ai-chat-assistant",
2802
- templateId: "ai-chat-assistant",
2786
+ "ai-chat-assistant": {
2803
2787
  title: "AI Chat Assistant",
2804
- description: "Focused assistant template with reasoning, sources, suggestions, and MCP-aware tooling.",
2805
- tags: ["AI", "Ops"],
2806
- capabilities: "Chat UX, Sources, Suggestions, MCP",
2807
- isNew: true,
2808
- previewUrl: "/sandbox?template=ai-chat-assistant",
2809
- docsUrl: "/docs/examples/ai-chat-assistant"
2788
+ description: "Focused assistant surface with reasoning, sources, suggestions, and MCP-aware tools.",
2789
+ component: AiChatAssistantDashboard
2810
2790
  },
2811
- {
2812
- id: "workflow-system",
2813
- templateId: "workflow-system",
2814
- title: "Workflow / Approval System",
2815
- description: "Multi-step workflows with role-based approvals and state transitions.",
2816
- tags: ["Business", "Ops"],
2817
- capabilities: "Workflows, Approvals, State Machine",
2818
- isNew: true,
2819
- previewUrl: "/sandbox?template=workflow-system",
2820
- docsUrl: "/docs/examples/workflow-system"
2791
+ "workflow-system": {
2792
+ title: "Workflow System",
2793
+ description: "Multi-step workflows with role-based approvals.",
2794
+ component: WorkflowDashboard
2821
2795
  },
2822
- {
2823
- id: "marketplace",
2824
- templateId: "marketplace",
2796
+ marketplace: {
2825
2797
  title: "Marketplace",
2826
2798
  description: "Two-sided marketplace with stores, products, orders, and payouts.",
2827
- tags: ["Business", "Payments"],
2828
- capabilities: "Stores, Products, Orders, Payouts",
2829
- isNew: true,
2830
- previewUrl: "/sandbox?template=marketplace",
2831
- docsUrl: "/docs/templates/marketplace"
2799
+ component: MarketplaceDashboard
2832
2800
  },
2833
- {
2834
- id: "integration-hub",
2835
- templateId: "integration-hub",
2801
+ "integration-hub": {
2836
2802
  title: "Integration Hub",
2837
2803
  description: "Third-party integrations with connections, sync configs, and field mapping.",
2838
- tags: ["Ops", "AI"],
2839
- capabilities: "Integrations, Connections, Sync",
2840
- isNew: true,
2841
- previewUrl: "/sandbox?template=integration-hub",
2842
- docsUrl: "/docs/templates/integration-hub"
2843
- },
2844
- {
2845
- id: "learning-journey-studio-onboarding",
2846
- templateId: "learning-journey-studio-onboarding",
2847
- title: "Learning Journey — Studio Getting Started",
2848
- description: "First 30 minutes in Studio: choose template, edit spec, regenerate, playground, evolution.",
2849
- tags: ["Learning", "Onboarding"],
2850
- capabilities: "Spec-first onboarding, XP/streak, progress widget",
2851
- isNew: true,
2852
- previewUrl: "/sandbox?template=learning-journey-studio-onboarding",
2853
- docsUrl: "/docs/templates/learning-journey-studio-onboarding"
2854
- },
2855
- {
2856
- id: "learning-journey-platform-tour",
2857
- templateId: "learning-journey-platform-tour",
2858
- title: "Learning Journey — Platform Primitives Tour",
2859
- description: "Touch identity, audit, notifications, jobs, flags, files, metering once with guided steps.",
2860
- tags: ["Learning", "Platform"],
2861
- capabilities: "Cross-module tour with event-driven completion",
2862
- isNew: true,
2863
- previewUrl: "/sandbox?template=learning-journey-platform-tour",
2864
- docsUrl: "/docs/templates/learning-journey-platform-tour"
2865
- },
2866
- {
2867
- id: "learning-journey-crm-onboarding",
2868
- templateId: "learning-journey-crm-onboarding",
2869
- title: "Learning Journey — CRM First Win",
2870
- description: "Get to first closed-won deal: pipeline, contact/company, deal, stages, follow-up.",
2871
- tags: ["Learning", "CRM"],
2872
- capabilities: "CRM onboarding with XP/streak/badge",
2873
- isNew: true,
2874
- previewUrl: "/sandbox?template=learning-journey-crm-onboarding",
2875
- docsUrl: "/docs/templates/learning-journey-crm-onboarding"
2804
+ component: IntegrationDashboard
2876
2805
  },
2877
- {
2878
- id: "analytics-dashboard",
2879
- templateId: "analytics-dashboard",
2806
+ "analytics-dashboard": {
2880
2807
  title: "Analytics Dashboard",
2881
- description: "Custom dashboards with widgets, saved queries, and real-time visualization.",
2882
- tags: ["Business", "Ops"],
2883
- capabilities: "Dashboards, Widgets, Queries",
2884
- isNew: true,
2885
- previewUrl: "/sandbox?template=analytics-dashboard",
2886
- docsUrl: "/docs/templates/analytics-dashboard"
2887
- },
2888
- {
2889
- id: "plumber-ops",
2890
- templateId: "messaging-app",
2891
- title: "Plumber Ops",
2892
- description: "Complete workflow: Quotes → Deposit → Job → Invoice → Payment. Policy-enforced approvals.",
2893
- tags: ["Trades", "Payments"],
2894
- capabilities: "Quotes, Jobs, Invoicing, Payments",
2895
- previewUrl: "/sandbox?template=plumber-ops",
2896
- docsUrl: "/docs/specs/workflows"
2897
- },
2898
- {
2899
- id: "coliving-management",
2900
- templateId: "recipe-app-i18n",
2901
- title: "Coliving Management",
2902
- description: "Coliving management: Onboarding, chores, shared wallet. Multi-party approvals built-in.",
2903
- tags: ["Coliving", "Finance"],
2904
- capabilities: "Tasks, Approvals, Payments",
2905
- previewUrl: "/sandbox?template=coliving-management",
2906
- docsUrl: "/docs/specs/workflows"
2907
- },
2908
- {
2909
- id: "chores-allowance",
2910
- templateId: "todos-app",
2911
- title: "Chores & Allowance",
2912
- description: "Family task management with approval workflows. Teach financial accountability safely.",
2913
- tags: ["Family", "Ops"],
2914
- capabilities: "Tasks, Approvals, Notifications",
2915
- previewUrl: "/sandbox?template=chores-allowance",
2916
- docsUrl: "/docs/specs/workflows"
2917
- },
2918
- {
2919
- id: "service-dispatch",
2920
- templateId: "messaging-app",
2921
- title: "Service Dispatch",
2922
- description: "Field service scheduling, routing, and invoicing. Real-time coordination with policy gates.",
2923
- tags: ["Ops", "Trades"],
2924
- capabilities: "Scheduling, Maps, Invoicing",
2925
- previewUrl: "/sandbox?template=service-dispatch",
2926
- docsUrl: "/docs/specs/workflows"
2927
- },
2928
- {
2929
- id: "content-review",
2930
- templateId: "todos-app",
2931
- title: "Content Review",
2932
- description: "Multi-stage approval workflow for content. Audit trail for every decision.",
2933
- tags: ["Ops"],
2934
- capabilities: "Workflows, Approvals, Comments",
2935
- previewUrl: "/sandbox?template=content-review",
2936
- docsUrl: "/docs/specs/workflows"
2808
+ description: "Custom dashboards with widgets and queries.",
2809
+ component: AnalyticsDashboard
2937
2810
  }
2938
- ];
2939
- var allTags = [
2940
- "Getting Started",
2941
- "SaaS",
2942
- "Business",
2943
- "CRM",
2944
- "AI",
2945
- "Trades",
2946
- "Coliving",
2947
- "Family",
2948
- "Ops",
2949
- "Payments",
2950
- "Learning",
2951
- "Platform"
2952
- ];
2953
- var TemplatesPage = () => {
2954
- const [selectedTag, setSelectedTag] = useState2(null);
2955
- const [search, setSearch] = useState2("");
2956
- const [preview, setPreview] = useState2(null);
2957
- const [studioSignupModalOpen, setStudioSignupModalOpen] = useState2(false);
2958
- const [source, setSource] = useState2("local");
2959
- const [selectedTemplateForCommand, setSelectedTemplateForCommand] = useState2(null);
2960
- const { data: registryTemplates = [], isLoading: registryLoading } = useRegistryTemplates();
2961
- const filtered = templates.filter((t) => {
2962
- const matchTag = !selectedTag || t.tags.includes(selectedTag);
2963
- const matchSearch = !search || t.title.toLowerCase().includes(search.toLowerCase()) || t.description.toLowerCase().includes(search.toLowerCase());
2964
- return matchTag && matchSearch;
2965
- });
2966
- const commandId = selectedTemplateForCommand ? "templateId" in selectedTemplateForCommand ? selectedTemplateForCommand.templateId : selectedTemplateForCommand.id : "";
2967
- return /* @__PURE__ */ jsxDEV12(TooltipProvider, {
2968
- children: [
2969
- /* @__PURE__ */ jsxDEV12("main", {
2970
- children: [
2971
- /* @__PURE__ */ jsxDEV12("section", {
2972
- className: "section-padding hero-gradient border-border/70 border-b",
2973
- children: /* @__PURE__ */ jsxDEV12("div", {
2974
- className: "editorial-shell space-y-8",
2811
+ };
2812
+ function TemplatePreviewContent({
2813
+ templateId
2814
+ }) {
2815
+ const preview = PREVIEW_DEFINITIONS[templateId];
2816
+ if (!preview) {
2817
+ return null;
2818
+ }
2819
+ const PreviewComponent = preview.component;
2820
+ return /* @__PURE__ */ jsxDEV13(TemplateShell, {
2821
+ title: preview.title,
2822
+ description: preview.description,
2823
+ showSaveAction: false,
2824
+ children: /* @__PURE__ */ jsxDEV13(PreviewComponent, {}, undefined, false, undefined, this)
2825
+ }, undefined, false, undefined, this);
2826
+ }
2827
+
2828
+ // src/components/templates/TemplatesBrowseControls.tsx
2829
+ import { cn } from "@contractspec/lib.ui-kit-core/utils";
2830
+ import { Search } from "lucide-react";
2831
+ import { jsxDEV as jsxDEV14 } from "react/jsx-dev-runtime";
2832
+ "use client";
2833
+ function TemplatesBrowseControls({
2834
+ registryConfigured,
2835
+ availableSources,
2836
+ source,
2837
+ onSourceChange,
2838
+ search,
2839
+ onSearchChange,
2840
+ selectedTag,
2841
+ onTagChange,
2842
+ showTagFilters,
2843
+ visibleTagFacets,
2844
+ hiddenTagFacets,
2845
+ showAllTags,
2846
+ onShowAllTagsChange
2847
+ }) {
2848
+ return /* @__PURE__ */ jsxDEV14("section", {
2849
+ className: "editorial-section",
2850
+ children: /* @__PURE__ */ jsxDEV14("div", {
2851
+ className: "editorial-shell space-y-6",
2852
+ children: [
2853
+ /* @__PURE__ */ jsxDEV14("div", {
2854
+ className: "flex flex-col gap-6 lg:flex-row lg:items-end lg:justify-between",
2855
+ children: [
2856
+ /* @__PURE__ */ jsxDEV14("div", {
2857
+ className: "max-w-3xl space-y-3",
2975
2858
  children: [
2976
- /* @__PURE__ */ jsxDEV12("div", {
2977
- className: "max-w-4xl space-y-5",
2978
- children: [
2979
- /* @__PURE__ */ jsxDEV12("p", {
2980
- className: "editorial-kicker",
2981
- children: "Proof through real scenarios"
2982
- }, undefined, false, undefined, this),
2983
- /* @__PURE__ */ jsxDEV12("h1", {
2984
- className: "editorial-title",
2985
- children: "Templates that show the open system in practice."
2986
- }, undefined, false, undefined, this),
2987
- /* @__PURE__ */ jsxDEV12("p", {
2988
- className: "editorial-subtitle",
2989
- children: "These scenarios are the fastest way to understand ContractSpec: explicit contracts, aligned surfaces, and an adoption path from OSS exploration into Studio deployment."
2990
- }, undefined, false, undefined, this)
2991
- ]
2992
- }, undefined, true, undefined, this),
2993
- /* @__PURE__ */ jsxDEV12("div", {
2994
- className: "editorial-proof-strip",
2995
- children: [
2996
- /* @__PURE__ */ jsxDEV12("div", {
2997
- className: "editorial-stat",
2998
- children: [
2999
- /* @__PURE__ */ jsxDEV12("span", {
3000
- className: "editorial-stat-value",
3001
- children: templates.length
3002
- }, undefined, false, undefined, this),
3003
- /* @__PURE__ */ jsxDEV12("span", {
3004
- className: "editorial-label",
3005
- children: "curated scenarios"
3006
- }, undefined, false, undefined, this)
3007
- ]
3008
- }, undefined, true, undefined, this),
3009
- /* @__PURE__ */ jsxDEV12("div", {
3010
- className: "editorial-stat",
3011
- children: [
3012
- /* @__PURE__ */ jsxDEV12("span", {
3013
- className: "editorial-stat-value",
3014
- children: "2"
3015
- }, undefined, false, undefined, this),
3016
- /* @__PURE__ */ jsxDEV12("span", {
3017
- className: "editorial-label",
3018
- children: "entry paths"
3019
- }, undefined, false, undefined, this)
3020
- ]
3021
- }, undefined, true, undefined, this),
3022
- /* @__PURE__ */ jsxDEV12("div", {
3023
- className: "editorial-stat",
3024
- children: [
3025
- /* @__PURE__ */ jsxDEV12("span", {
3026
- className: "editorial-stat-value",
3027
- children: "OSS"
3028
- }, undefined, false, undefined, this),
3029
- /* @__PURE__ */ jsxDEV12("span", {
3030
- className: "editorial-label",
3031
- children: "first, Studio second"
3032
- }, undefined, false, undefined, this)
3033
- ]
3034
- }, undefined, true, undefined, this)
3035
- ]
3036
- }, undefined, true, undefined, this)
2859
+ /* @__PURE__ */ jsxDEV14("p", {
2860
+ className: "editorial-kicker",
2861
+ children: "Browse by source"
2862
+ }, undefined, false, undefined, this),
2863
+ /* @__PURE__ */ jsxDEV14("h2", {
2864
+ className: "font-serif text-4xl tracking-[-0.04em]",
2865
+ children: "Use local scenarios for core proof, then scan the community."
2866
+ }, undefined, false, undefined, this),
2867
+ /* @__PURE__ */ jsxDEV14("p", {
2868
+ className: "text-muted-foreground text-sm leading-7",
2869
+ children: registryConfigured ? "Local templates show the official adoption path. Community templates show where the ecosystem is pushing the system next." : "Local templates show the official adoption path. Community browsing appears automatically when a registry URL is configured."
2870
+ }, undefined, false, undefined, this)
3037
2871
  ]
3038
- }, undefined, true, undefined, this)
3039
- }, undefined, false, undefined, this),
3040
- /* @__PURE__ */ jsxDEV12("section", {
3041
- className: "editorial-section",
3042
- children: /* @__PURE__ */ jsxDEV12("div", {
3043
- className: "editorial-shell space-y-6",
2872
+ }, undefined, true, undefined, this),
2873
+ registryConfigured ? /* @__PURE__ */ jsxDEV14("div", {
2874
+ className: "flex gap-2",
2875
+ children: availableSources.map((option) => /* @__PURE__ */ jsxDEV14("button", {
2876
+ onClick: () => onSourceChange(option),
2877
+ className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
2878
+ "bg-primary text-primary-foreground": source === option,
2879
+ "border border-border bg-card hover:bg-card/80": source !== option
2880
+ }),
2881
+ "aria-pressed": source === option,
2882
+ children: option === "local" ? "Local" : "Community"
2883
+ }, option, false, undefined, this))
2884
+ }, undefined, false, undefined, this) : null
2885
+ ]
2886
+ }, undefined, true, undefined, this),
2887
+ /* @__PURE__ */ jsxDEV14("div", {
2888
+ className: "editorial-panel space-y-5",
2889
+ children: [
2890
+ /* @__PURE__ */ jsxDEV14("div", {
2891
+ className: "relative",
3044
2892
  children: [
3045
- /* @__PURE__ */ jsxDEV12("div", {
3046
- className: "flex flex-col gap-6 lg:flex-row lg:items-end lg:justify-between",
3047
- children: [
3048
- /* @__PURE__ */ jsxDEV12("div", {
3049
- className: "max-w-3xl space-y-3",
3050
- children: [
3051
- /* @__PURE__ */ jsxDEV12("p", {
3052
- className: "editorial-kicker",
3053
- children: "Browse by source"
3054
- }, undefined, false, undefined, this),
3055
- /* @__PURE__ */ jsxDEV12("h2", {
3056
- className: "font-serif text-4xl tracking-[-0.04em]",
3057
- children: "Use local scenarios for core proof, then scan the community."
3058
- }, undefined, false, undefined, this),
3059
- /* @__PURE__ */ jsxDEV12("p", {
3060
- className: "text-muted-foreground text-sm leading-7",
3061
- children: "Local templates show the official adoption path. Community templates show where the ecosystem is pushing the system next."
3062
- }, undefined, false, undefined, this)
3063
- ]
3064
- }, undefined, true, undefined, this),
3065
- /* @__PURE__ */ jsxDEV12("div", {
3066
- className: "flex gap-2",
3067
- children: [
3068
- /* @__PURE__ */ jsxDEV12("button", {
3069
- onClick: () => setSource("local"),
3070
- className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
3071
- "bg-primary text-primary-foreground": source === "local",
3072
- "border border-border bg-card hover:bg-card/80": source !== "local"
3073
- }),
3074
- "aria-pressed": source === "local",
3075
- children: "Local"
3076
- }, undefined, false, undefined, this),
3077
- /* @__PURE__ */ jsxDEV12("button", {
3078
- onClick: () => setSource("registry"),
3079
- className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
3080
- "bg-primary text-primary-foreground": source === "registry",
3081
- "border border-border bg-card hover:bg-card/80": source !== "registry"
3082
- }),
3083
- "aria-pressed": source === "registry",
3084
- children: "Community"
3085
- }, undefined, false, undefined, this)
3086
- ]
3087
- }, undefined, true, undefined, this)
3088
- ]
3089
- }, undefined, true, undefined, this),
3090
- /* @__PURE__ */ jsxDEV12("div", {
3091
- className: "editorial-panel space-y-5",
3092
- children: [
3093
- /* @__PURE__ */ jsxDEV12("div", {
3094
- className: "relative",
3095
- children: [
3096
- /* @__PURE__ */ jsxDEV12(Search, {
3097
- className: "absolute top-3.5 left-4 text-muted-foreground",
3098
- size: 18
3099
- }, undefined, false, undefined, this),
3100
- /* @__PURE__ */ jsxDEV12("input", {
3101
- type: "text",
3102
- placeholder: "Search scenarios, industries, or capabilities",
3103
- value: search,
3104
- onChange: (e) => setSearch(e.target.value),
3105
- className: "w-full rounded-full border border-border bg-background px-12 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring",
3106
- "aria-label": "Search templates"
3107
- }, undefined, false, undefined, this)
3108
- ]
3109
- }, undefined, true, undefined, this),
3110
- /* @__PURE__ */ jsxDEV12("div", {
3111
- className: "flex flex-wrap gap-2",
3112
- children: [
3113
- /* @__PURE__ */ jsxDEV12("button", {
3114
- onClick: () => setSelectedTag(null),
3115
- className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
3116
- "bg-primary text-primary-foreground": selectedTag === null,
3117
- "border border-border bg-card hover:bg-card/80": selectedTag !== null
3118
- }),
3119
- "aria-pressed": selectedTag === null,
3120
- children: "All"
3121
- }, undefined, false, undefined, this),
3122
- allTags.map((tag) => /* @__PURE__ */ jsxDEV12("button", {
3123
- onClick: () => setSelectedTag(tag),
3124
- className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
3125
- "bg-primary text-primary-foreground": selectedTag === tag,
3126
- "border border-border bg-card hover:bg-card/80": selectedTag !== tag
3127
- }),
3128
- "aria-pressed": selectedTag === tag,
3129
- children: tag
3130
- }, tag, false, undefined, this))
3131
- ]
3132
- }, undefined, true, undefined, this)
3133
- ]
3134
- }, undefined, true, undefined, this)
3135
- ]
3136
- }, undefined, true, undefined, this)
3137
- }, undefined, false, undefined, this),
3138
- /* @__PURE__ */ jsxDEV12("section", {
3139
- className: "section-padding",
3140
- children: /* @__PURE__ */ jsxDEV12("div", {
3141
- className: "editorial-shell",
3142
- children: source === "registry" ? registryLoading ? /* @__PURE__ */ jsxDEV12("div", {
3143
- className: "py-12 text-center",
3144
- children: /* @__PURE__ */ jsxDEV12("p", {
3145
- className: "text-muted-foreground",
3146
- children: "Loading community templates…"
3147
- }, undefined, false, undefined, this)
3148
- }, undefined, false, undefined, this) : registryTemplates.length === 0 ? /* @__PURE__ */ jsxDEV12("div", {
3149
- className: "py-12 text-center",
3150
- children: /* @__PURE__ */ jsxDEV12("p", {
3151
- className: "text-muted-foreground",
3152
- children: "No community templates found (configure `NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL`)."
3153
- }, undefined, false, undefined, this)
3154
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV12("div", {
3155
- className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
3156
- children: registryTemplates.map((t) => /* @__PURE__ */ jsxDEV12("div", {
3157
- className: "editorial-panel relative flex flex-col space-y-4 transition-colors hover:border-[color:rgb(162_79_42_/_0.55)]",
3158
- children: [
3159
- /* @__PURE__ */ jsxDEV12("div", {
3160
- children: [
3161
- /* @__PURE__ */ jsxDEV12("h3", {
3162
- className: "font-serif text-2xl tracking-[-0.03em]",
3163
- children: t.name
3164
- }, undefined, false, undefined, this),
3165
- /* @__PURE__ */ jsxDEV12("p", {
3166
- className: "mt-1 text-muted-foreground text-sm",
3167
- children: t.description
3168
- }, undefined, false, undefined, this)
3169
- ]
3170
- }, undefined, true, undefined, this),
3171
- /* @__PURE__ */ jsxDEV12("div", {
3172
- className: "flex-1 space-y-2",
3173
- children: /* @__PURE__ */ jsxDEV12("div", {
3174
- className: "flex flex-wrap gap-1",
3175
- children: t.tags.map((tag) => /* @__PURE__ */ jsxDEV12("span", {
3176
- className: "rounded-full border border-border bg-muted px-3 py-1 text-[11px] text-muted-foreground",
3177
- children: tag
3178
- }, tag, false, undefined, this))
3179
- }, undefined, false, undefined, this)
3180
- }, undefined, false, undefined, this),
3181
- /* @__PURE__ */ jsxDEV12("div", {
3182
- className: "flex gap-2 pt-4",
3183
- children: [
3184
- /* @__PURE__ */ jsxDEV12(Tooltip, {
3185
- children: [
3186
- /* @__PURE__ */ jsxDEV12(TooltipTrigger, {
3187
- asChild: true,
3188
- children: /* @__PURE__ */ jsxDEV12("button", {
3189
- className: "btn-ghost flex-1 text-center text-xs",
3190
- onClick: () => {
3191
- const local = getTemplate(t.id);
3192
- if (!local) {
3193
- setSelectedTemplateForCommand(t);
3194
- return;
3195
- }
3196
- setPreview(t.id);
3197
- },
3198
- children: "Preview"
3199
- }, undefined, false, undefined, this)
3200
- }, undefined, false, undefined, this),
3201
- /* @__PURE__ */ jsxDEV12(TooltipContent, {
3202
- children: /* @__PURE__ */ jsxDEV12("p", {
3203
- children: "Preview this template (if available locally)"
3204
- }, undefined, false, undefined, this)
3205
- }, undefined, false, undefined, this)
3206
- ]
3207
- }, undefined, true, undefined, this),
3208
- /* @__PURE__ */ jsxDEV12(Tooltip, {
3209
- children: [
3210
- /* @__PURE__ */ jsxDEV12(TooltipTrigger, {
3211
- asChild: true,
3212
- children: /* @__PURE__ */ jsxDEV12("button", {
3213
- className: "btn-primary flex-1 text-center text-xs",
3214
- onClick: () => {
3215
- captureAnalyticsEvent2(analyticsEventNames2.EXAMPLE_REPO_OPEN, {
3216
- surface: "templates",
3217
- templateId: t.id,
3218
- source: "registry"
3219
- });
3220
- setSelectedTemplateForCommand(t);
3221
- },
3222
- children: "Use Template"
3223
- }, undefined, false, undefined, this)
3224
- }, undefined, false, undefined, this),
3225
- /* @__PURE__ */ jsxDEV12(TooltipContent, {
3226
- children: /* @__PURE__ */ jsxDEV12("p", {
3227
- children: "Get CLI command"
3228
- }, undefined, false, undefined, this)
3229
- }, undefined, false, undefined, this)
3230
- ]
3231
- }, undefined, true, undefined, this)
3232
- ]
3233
- }, undefined, true, undefined, this)
3234
- ]
3235
- }, t.id, true, undefined, this))
3236
- }, undefined, false, undefined, this) : filtered.length === 0 ? /* @__PURE__ */ jsxDEV12("div", {
3237
- className: "py-12 text-center",
3238
- children: /* @__PURE__ */ jsxDEV12("p", {
3239
- className: "text-muted-foreground",
3240
- children: "No templates match your filters. Try a different search."
2893
+ /* @__PURE__ */ jsxDEV14(Search, {
2894
+ className: "absolute top-3.5 left-4 text-muted-foreground",
2895
+ size: 18
2896
+ }, undefined, false, undefined, this),
2897
+ /* @__PURE__ */ jsxDEV14("input", {
2898
+ type: "text",
2899
+ placeholder: "Search scenarios, industries, or tags",
2900
+ value: search,
2901
+ onChange: (event) => onSearchChange(event.target.value),
2902
+ className: "w-full rounded-full border border-border bg-background px-12 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring",
2903
+ "aria-label": "Search templates"
3241
2904
  }, undefined, false, undefined, this)
3242
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV12("div", {
3243
- className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
3244
- children: filtered.map((template, i) => /* @__PURE__ */ jsxDEV12("div", {
3245
- className: "editorial-panel relative flex flex-col space-y-4 transition-colors hover:border-[color:rgb(162_79_42_/_0.55)]",
3246
- children: [
3247
- "isNew" in template && template.isNew && /* @__PURE__ */ jsxDEV12("span", {
3248
- className: "absolute top-4 right-4 rounded-full bg-[color:var(--success)] px-2.5 py-1 font-medium text-[11px] text-white uppercase",
3249
- children: "New"
3250
- }, undefined, false, undefined, this),
3251
- /* @__PURE__ */ jsxDEV12("div", {
3252
- children: [
3253
- /* @__PURE__ */ jsxDEV12("h3", {
3254
- className: "font-serif text-2xl tracking-[-0.03em]",
3255
- children: template.title
3256
- }, undefined, false, undefined, this),
3257
- /* @__PURE__ */ jsxDEV12("p", {
3258
- className: "mt-1 text-muted-foreground text-sm",
3259
- children: template.description
3260
- }, undefined, false, undefined, this)
3261
- ]
3262
- }, undefined, true, undefined, this),
3263
- /* @__PURE__ */ jsxDEV12("div", {
3264
- className: "flex-1 space-y-2",
3265
- children: [
3266
- /* @__PURE__ */ jsxDEV12("p", {
3267
- className: "text-muted-foreground text-xs",
3268
- children: [
3269
- /* @__PURE__ */ jsxDEV12("span", {
3270
- className: "font-medium text-foreground",
3271
- children: "Capabilities:"
3272
- }, undefined, false, undefined, this),
3273
- " ",
3274
- template.capabilities
3275
- ]
3276
- }, undefined, true, undefined, this),
3277
- /* @__PURE__ */ jsxDEV12("div", {
3278
- className: "flex flex-wrap gap-1",
3279
- children: template.tags.map((tag) => /* @__PURE__ */ jsxDEV12("span", {
3280
- className: "rounded-full border border-border bg-muted px-3 py-1 text-[11px] text-muted-foreground",
3281
- children: tag
3282
- }, tag, false, undefined, this))
3283
- }, undefined, false, undefined, this)
3284
- ]
3285
- }, undefined, true, undefined, this),
3286
- /* @__PURE__ */ jsxDEV12("div", {
3287
- className: "flex gap-2 pt-4",
3288
- children: [
3289
- /* @__PURE__ */ jsxDEV12(Tooltip, {
3290
- children: [
3291
- /* @__PURE__ */ jsxDEV12(TooltipTrigger, {
3292
- asChild: true,
3293
- children: /* @__PURE__ */ jsxDEV12("button", {
3294
- className: "btn-ghost flex-1 text-center text-xs",
3295
- onClick: () => setPreview(template.templateId),
3296
- children: "Preview"
3297
- }, undefined, false, undefined, this)
3298
- }, undefined, false, undefined, this),
3299
- /* @__PURE__ */ jsxDEV12(TooltipContent, {
3300
- children: /* @__PURE__ */ jsxDEV12("p", {
3301
- children: "Preview this template in a modal"
3302
- }, undefined, false, undefined, this)
3303
- }, undefined, false, undefined, this)
3304
- ]
3305
- }, undefined, true, undefined, this),
3306
- /* @__PURE__ */ jsxDEV12(Tooltip, {
3307
- children: [
3308
- /* @__PURE__ */ jsxDEV12(TooltipTrigger, {
3309
- asChild: true,
3310
- children: /* @__PURE__ */ jsxDEV12("button", {
3311
- className: "btn-primary flex-1 text-center text-xs",
3312
- onClick: () => {
3313
- captureAnalyticsEvent2(analyticsEventNames2.EXAMPLE_REPO_OPEN, {
3314
- surface: "templates",
3315
- templateId: template.templateId,
3316
- source: "local"
3317
- });
3318
- setSelectedTemplateForCommand(template);
3319
- },
3320
- children: "Use Template"
3321
- }, undefined, false, undefined, this)
3322
- }, undefined, false, undefined, this),
3323
- /* @__PURE__ */ jsxDEV12(TooltipContent, {
3324
- children: /* @__PURE__ */ jsxDEV12("p", {
3325
- children: "Get CLI command"
3326
- }, undefined, false, undefined, this)
3327
- }, undefined, false, undefined, this)
3328
- ]
3329
- }, undefined, true, undefined, this)
3330
- ]
3331
- }, undefined, true, undefined, this)
3332
- ]
3333
- }, i, true, undefined, this))
3334
- }, undefined, false, undefined, this)
3335
- }, undefined, false, undefined, this)
3336
- }, undefined, false, undefined, this),
3337
- /* @__PURE__ */ jsxDEV12("section", {
3338
- className: "editorial-section bg-striped",
3339
- children: /* @__PURE__ */ jsxDEV12("div", {
3340
- className: "editorial-shell space-y-8",
2905
+ ]
2906
+ }, undefined, true, undefined, this),
2907
+ showTagFilters ? /* @__PURE__ */ jsxDEV14("div", {
2908
+ className: "space-y-3",
3341
2909
  children: [
3342
- /* @__PURE__ */ jsxDEV12("div", {
3343
- className: "max-w-3xl space-y-4",
2910
+ /* @__PURE__ */ jsxDEV14("div", {
2911
+ className: "flex flex-wrap gap-2",
3344
2912
  children: [
3345
- /* @__PURE__ */ jsxDEV12("p", {
3346
- className: "editorial-kicker",
3347
- children: "From template to real system"
2913
+ /* @__PURE__ */ jsxDEV14("button", {
2914
+ onClick: () => onTagChange(null),
2915
+ className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
2916
+ "bg-primary text-primary-foreground": selectedTag === null,
2917
+ "border border-border bg-card hover:bg-card/80": selectedTag !== null
2918
+ }),
2919
+ "aria-pressed": selectedTag === null,
2920
+ children: "All"
3348
2921
  }, undefined, false, undefined, this),
3349
- /* @__PURE__ */ jsxDEV12("h2", {
3350
- className: "font-serif text-4xl tracking-[-0.04em] md:text-5xl",
3351
- children: "Templates become useful when the system can absorb more context."
3352
- }, undefined, false, undefined, this),
3353
- /* @__PURE__ */ jsxDEV12("p", {
3354
- className: "editorial-copy",
3355
- children: "Use templates to prove the base flow, then layer integrations, knowledge, and runtime behavior on top without losing the same contract source."
3356
- }, undefined, false, undefined, this)
2922
+ visibleTagFacets.map((facet) => /* @__PURE__ */ jsxDEV14("button", {
2923
+ onClick: () => onTagChange(facet.tag),
2924
+ className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
2925
+ "bg-primary text-primary-foreground": selectedTag === facet.tag,
2926
+ "border border-border bg-card hover:bg-card/80": selectedTag !== facet.tag
2927
+ }),
2928
+ "aria-pressed": selectedTag === facet.tag,
2929
+ children: facet.tag
2930
+ }, facet.tag, false, undefined, this))
3357
2931
  ]
3358
2932
  }, undefined, true, undefined, this),
3359
- /* @__PURE__ */ jsxDEV12("div", {
3360
- className: "grid gap-6 md:grid-cols-3",
3361
- children: [
3362
- /* @__PURE__ */ jsxDEV12("div", {
3363
- className: "editorial-panel space-y-4",
3364
- children: [
3365
- /* @__PURE__ */ jsxDEV12("div", {
3366
- className: "text-3xl",
3367
- children: "\uD83D\uDCB3"
3368
- }, undefined, false, undefined, this),
3369
- /* @__PURE__ */ jsxDEV12("h3", {
3370
- className: "font-serif text-2xl tracking-[-0.03em]",
3371
- children: "Add payments"
3372
- }, undefined, false, undefined, this),
3373
- /* @__PURE__ */ jsxDEV12("p", {
3374
- className: "text-muted-foreground text-sm",
3375
- children: "Connect Stripe to any template for payment processing, subscriptions, and invoicing. Type-safe and policy-enforced."
3376
- }, undefined, false, undefined, this),
3377
- /* @__PURE__ */ jsxDEV12(Link8, {
3378
- href: "/docs/integrations/stripe",
3379
- className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3380
- children: "Learn more →"
3381
- }, undefined, false, undefined, this)
3382
- ]
3383
- }, undefined, true, undefined, this),
3384
- /* @__PURE__ */ jsxDEV12("div", {
3385
- className: "editorial-panel space-y-4",
3386
- children: [
3387
- /* @__PURE__ */ jsxDEV12("div", {
3388
- className: "text-3xl",
3389
- children: "\uD83D\uDCE7"
3390
- }, undefined, false, undefined, this),
3391
- /* @__PURE__ */ jsxDEV12("h3", {
3392
- className: "font-serif text-2xl tracking-[-0.03em]",
3393
- children: "Add notifications"
3394
- }, undefined, false, undefined, this),
3395
- /* @__PURE__ */ jsxDEV12("p", {
3396
- className: "text-muted-foreground text-sm",
3397
- children: "Send transactional emails via Postmark or Resend. Process inbound emails with Gmail API. SMS via Twilio."
3398
- }, undefined, false, undefined, this),
3399
- /* @__PURE__ */ jsxDEV12(Link8, {
3400
- href: "/docs/integrations",
3401
- className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3402
- children: "View integrations →"
3403
- }, undefined, false, undefined, this)
3404
- ]
3405
- }, undefined, true, undefined, this),
3406
- /* @__PURE__ */ jsxDEV12("div", {
3407
- className: "editorial-panel space-y-4",
3408
- children: [
3409
- /* @__PURE__ */ jsxDEV12("div", {
3410
- className: "text-3xl",
3411
- children: "\uD83E\uDDE0"
3412
- }, undefined, false, undefined, this),
3413
- /* @__PURE__ */ jsxDEV12("h3", {
3414
- className: "font-serif text-2xl tracking-[-0.03em]",
3415
- children: "Add AI and knowledge"
3416
- }, undefined, false, undefined, this),
3417
- /* @__PURE__ */ jsxDEV12("p", {
3418
- className: "text-muted-foreground text-sm",
3419
- children: "Power templates with OpenAI, vector search via Qdrant, and structured knowledge spaces for context-aware workflows."
3420
- }, undefined, false, undefined, this),
3421
- /* @__PURE__ */ jsxDEV12(Link8, {
3422
- href: "/docs/knowledge",
3423
- className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3424
- children: "Learn about knowledge →"
3425
- }, undefined, false, undefined, this)
3426
- ]
3427
- }, undefined, true, undefined, this)
3428
- ]
3429
- }, undefined, true, undefined, this),
3430
- /* @__PURE__ */ jsxDEV12("div", {
3431
- className: "pt-4 text-center",
3432
- children: [
3433
- /* @__PURE__ */ jsxDEV12("p", {
3434
- className: "mb-4 text-muted-foreground text-sm",
3435
- children: "All integrations are configured per-tenant with automatic health checks and credential rotation."
3436
- }, undefined, false, undefined, this),
3437
- /* @__PURE__ */ jsxDEV12(Link8, {
3438
- href: "/docs/architecture",
3439
- className: "btn-primary",
3440
- children: "View Architecture"
3441
- }, undefined, false, undefined, this)
3442
- ]
3443
- }, undefined, true, undefined, this)
2933
+ hiddenTagFacets.length > 0 || showAllTags ? /* @__PURE__ */ jsxDEV14("button", {
2934
+ type: "button",
2935
+ onClick: () => onShowAllTagsChange(!showAllTags),
2936
+ className: "text-muted-foreground text-sm transition-colors hover:text-foreground",
2937
+ children: showAllTags ? "Show fewer" : "More tags"
2938
+ }, undefined, false, undefined, this) : null
3444
2939
  ]
3445
- }, undefined, true, undefined, this)
3446
- }, undefined, false, undefined, this)
3447
- ]
3448
- }, undefined, true, undefined, this),
3449
- /* @__PURE__ */ jsxDEV12(TemplatePreviewModal, {
3450
- templateId: preview,
3451
- onClose: () => {
3452
- setPreview(null);
3453
- }
3454
- }, undefined, false, undefined, this),
3455
- /* @__PURE__ */ jsxDEV12(Dialog3, {
3456
- open: studioSignupModalOpen,
3457
- onOpenChange: setStudioSignupModalOpen,
3458
- children: /* @__PURE__ */ jsxDEV12(DialogContent3, {
3459
- className: "max-h-[90vh] max-w-2xl overflow-y-auto",
2940
+ }, undefined, true, undefined, this) : null
2941
+ ]
2942
+ }, undefined, true, undefined, this)
2943
+ ]
2944
+ }, undefined, true, undefined, this)
2945
+ }, undefined, false, undefined, this);
2946
+ }
2947
+
2948
+ // src/components/templates/template-new.ts
2949
+ var NEW_TEMPLATE_IDS = [
2950
+ "minimal",
2951
+ "messaging-agent-actions",
2952
+ "policy-safe-knowledge-assistant",
2953
+ "visualization-showcase"
2954
+ ];
2955
+ var NEW_TEMPLATE_ID_SET = new Set(NEW_TEMPLATE_IDS);
2956
+ function isNewTemplateId(templateId) {
2957
+ return NEW_TEMPLATE_ID_SET.has(templateId);
2958
+ }
2959
+
2960
+ // src/components/templates/template-catalog.ts
2961
+ import { listExamples, listTemplates } from "@contractspec/module.examples";
2962
+ var NEW_TEMPLATE_INDEX = new Map(NEW_TEMPLATE_IDS.map((templateId, index) => [templateId, index]));
2963
+ function buildLocalTemplateCatalog(examples = listExamples(), templates = listTemplates()) {
2964
+ const templatesById = new Map(templates.map((template) => [template.id, template]));
2965
+ return examples.filter((example) => example.meta.visibility === "public" && example.surfaces.templates).map((example) => {
2966
+ const template = templatesById.get(example.meta.key);
2967
+ const tags = Array.from(new Set(example.meta.tags.map((tag) => tag.trim()).filter(Boolean))).sort((left, right) => left.localeCompare(right));
2968
+ return {
2969
+ id: example.meta.key,
2970
+ title: example.meta.title ?? template?.name ?? example.meta.key,
2971
+ description: example.meta.summary ?? example.meta.description,
2972
+ tags,
2973
+ kind: example.meta.kind,
2974
+ stability: example.meta.stability,
2975
+ previewUrl: template?.preview?.demoUrl ?? `/sandbox?template=${encodeURIComponent(example.meta.key)}`,
2976
+ featureList: [...template?.features ?? []],
2977
+ sandboxModes: example.surfaces.sandbox.modes,
2978
+ renderTargets: [...template?.renderTargets ?? []],
2979
+ isNew: isNewTemplateId(example.meta.key),
2980
+ packageName: example.entrypoints.packageName
2981
+ };
2982
+ }).sort(compareLocalTemplateCatalogItems);
2983
+ }
2984
+ function matchesTemplateFilters(template, search, selectedTag) {
2985
+ return matchesTemplateSearch(template, search) && (selectedTag === null || template.tags.includes(selectedTag));
2986
+ }
2987
+ function matchesTemplateSearch(template, search) {
2988
+ const haystack = [
2989
+ template.title,
2990
+ template.description,
2991
+ template.tags.join(" ")
2992
+ ].join(" ").toLowerCase();
2993
+ const searchTokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
2994
+ return searchTokens.length === 0 || searchTokens.every((token) => haystack.includes(token));
2995
+ }
2996
+ function formatExampleKindLabel(kind) {
2997
+ return kind.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
2998
+ }
2999
+ function formatStabilityLabel(stability) {
3000
+ return stability.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
3001
+ }
3002
+ function compareLocalTemplateCatalogItems(left, right) {
3003
+ const leftNewIndex = NEW_TEMPLATE_INDEX.get(left.id);
3004
+ const rightNewIndex = NEW_TEMPLATE_INDEX.get(right.id);
3005
+ if (leftNewIndex !== undefined || rightNewIndex !== undefined) {
3006
+ if (leftNewIndex === undefined) {
3007
+ return 1;
3008
+ }
3009
+ if (rightNewIndex === undefined) {
3010
+ return -1;
3011
+ }
3012
+ return leftNewIndex - rightNewIndex;
3013
+ }
3014
+ return left.title.localeCompare(right.title);
3015
+ }
3016
+
3017
+ // src/components/templates/template-preview.ts
3018
+ var INLINE_TEMPLATE_PREVIEW_IDS = [
3019
+ "agent-console",
3020
+ "ai-chat-assistant",
3021
+ "analytics-dashboard",
3022
+ "crm-pipeline",
3023
+ "data-grid-showcase",
3024
+ "integration-hub",
3025
+ "marketplace",
3026
+ "saas-boilerplate",
3027
+ "visualization-showcase",
3028
+ "workflow-system"
3029
+ ];
3030
+ var INLINE_TEMPLATE_PREVIEW_SET = new Set(INLINE_TEMPLATE_PREVIEW_IDS);
3031
+ function supportsInlineTemplatePreview(templateId) {
3032
+ return INLINE_TEMPLATE_PREVIEW_SET.has(templateId);
3033
+ }
3034
+ function getLocalTemplatePreviewAction(template) {
3035
+ if (supportsInlineTemplatePreview(template.id)) {
3036
+ return { kind: "modal", templateId: template.id };
3037
+ }
3038
+ return { kind: "sandbox", href: template.previewUrl };
3039
+ }
3040
+ function getRegistryTemplatePreviewAction(template, localTemplate) {
3041
+ if (!localTemplate) {
3042
+ return { kind: "disabled" };
3043
+ }
3044
+ return getLocalTemplatePreviewAction(localTemplate);
3045
+ }
3046
+
3047
+ // src/components/templates/TemplatesCatalogSection.tsx
3048
+ import Link8 from "next/link";
3049
+ import { jsxDEV as jsxDEV15 } from "react/jsx-dev-runtime";
3050
+ "use client";
3051
+ function TemplatesCatalogSection({
3052
+ source,
3053
+ registryConfigured,
3054
+ registryLoading,
3055
+ registryHasTemplates,
3056
+ localTemplates,
3057
+ registryTemplates,
3058
+ localTemplateById,
3059
+ onPreview,
3060
+ onUseTemplate,
3061
+ hasSearch,
3062
+ selectedTag
3063
+ }) {
3064
+ const showRegistry = source === "registry" && registryConfigured;
3065
+ const emptyStateMessage = getEmptyStateMessage(hasSearch, selectedTag);
3066
+ return /* @__PURE__ */ jsxDEV15("section", {
3067
+ className: "section-padding",
3068
+ children: /* @__PURE__ */ jsxDEV15("div", {
3069
+ className: "editorial-shell",
3070
+ children: showRegistry ? registryLoading ? /* @__PURE__ */ jsxDEV15("div", {
3071
+ className: "py-12 text-center",
3072
+ children: /* @__PURE__ */ jsxDEV15("p", {
3073
+ className: "text-muted-foreground",
3074
+ children: "Loading community templates…"
3075
+ }, undefined, false, undefined, this)
3076
+ }, undefined, false, undefined, this) : !registryHasTemplates ? /* @__PURE__ */ jsxDEV15("div", {
3077
+ className: "py-12 text-center",
3078
+ children: /* @__PURE__ */ jsxDEV15("p", {
3079
+ className: "text-muted-foreground",
3080
+ children: "No community templates found."
3081
+ }, undefined, false, undefined, this)
3082
+ }, undefined, false, undefined, this) : registryTemplates.length === 0 ? /* @__PURE__ */ jsxDEV15("div", {
3083
+ className: "py-12 text-center",
3084
+ children: /* @__PURE__ */ jsxDEV15("p", {
3085
+ className: "text-muted-foreground",
3086
+ children: emptyStateMessage
3087
+ }, undefined, false, undefined, this)
3088
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
3089
+ className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
3090
+ children: registryTemplates.map((template) => {
3091
+ const localTemplate = localTemplateById.get(template.id);
3092
+ const previewAction = getRegistryTemplatePreviewAction(template, localTemplate);
3093
+ return /* @__PURE__ */ jsxDEV15(TemplateCard, {
3094
+ title: template.name,
3095
+ description: template.description,
3096
+ metaBadges: ["Community"],
3097
+ tags: template.tags,
3098
+ previewAction: previewAction.kind === "modal" ? /* @__PURE__ */ jsxDEV15("button", {
3099
+ className: "btn-ghost flex-1 text-center text-xs",
3100
+ onClick: () => onPreview(template.id),
3101
+ children: "Preview"
3102
+ }, undefined, false, undefined, this) : previewAction.kind === "sandbox" ? /* @__PURE__ */ jsxDEV15(Link8, {
3103
+ href: previewAction.href,
3104
+ className: "btn-ghost flex-1 text-center text-xs",
3105
+ children: "Open Sandbox"
3106
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("button", {
3107
+ className: "btn-ghost flex-1 cursor-not-allowed text-center text-xs opacity-60",
3108
+ type: "button",
3109
+ disabled: true,
3110
+ children: "Preview Unavailable"
3111
+ }, undefined, false, undefined, this),
3112
+ useAction: /* @__PURE__ */ jsxDEV15("button", {
3113
+ className: "btn-primary flex-1 text-center text-xs",
3114
+ onClick: () => onUseTemplate(template.id, "registry"),
3115
+ children: "Use Template"
3116
+ }, undefined, false, undefined, this)
3117
+ }, template.id, false, undefined, this);
3118
+ })
3119
+ }, undefined, false, undefined, this) : localTemplates.length === 0 ? /* @__PURE__ */ jsxDEV15("div", {
3120
+ className: "py-12 text-center",
3121
+ children: /* @__PURE__ */ jsxDEV15("p", {
3122
+ className: "text-muted-foreground",
3123
+ children: emptyStateMessage
3124
+ }, undefined, false, undefined, this)
3125
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
3126
+ className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
3127
+ children: localTemplates.map((template) => {
3128
+ const previewAction = getLocalTemplatePreviewAction(template);
3129
+ return /* @__PURE__ */ jsxDEV15(TemplateCard, {
3130
+ title: template.title,
3131
+ description: template.description,
3132
+ isNew: template.isNew,
3133
+ metaBadges: [
3134
+ formatExampleKindLabel(template.kind),
3135
+ formatStabilityLabel(template.stability)
3136
+ ],
3137
+ tags: template.tags,
3138
+ featureList: template.featureList,
3139
+ previewAction: previewAction.kind === "modal" ? /* @__PURE__ */ jsxDEV15("button", {
3140
+ className: "btn-ghost flex-1 text-center text-xs",
3141
+ onClick: () => onPreview(template.id),
3142
+ children: "Preview"
3143
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15(Link8, {
3144
+ href: previewAction.href,
3145
+ className: "btn-ghost flex-1 text-center text-xs",
3146
+ children: "Open Sandbox"
3147
+ }, undefined, false, undefined, this),
3148
+ useAction: /* @__PURE__ */ jsxDEV15("button", {
3149
+ className: "btn-primary flex-1 text-center text-xs",
3150
+ onClick: () => onUseTemplate(template.id, "local"),
3151
+ children: "Use Template"
3152
+ }, undefined, false, undefined, this)
3153
+ }, template.id, false, undefined, this);
3154
+ })
3155
+ }, undefined, false, undefined, this)
3156
+ }, undefined, false, undefined, this)
3157
+ }, undefined, false, undefined, this);
3158
+ }
3159
+ function getEmptyStateMessage(hasSearch, selectedTag) {
3160
+ if (selectedTag !== null && hasSearch) {
3161
+ return "No templates match this tag for the current search.";
3162
+ }
3163
+ if (selectedTag !== null) {
3164
+ return "No templates match this tag. Try another tag or reset filters.";
3165
+ }
3166
+ if (hasSearch) {
3167
+ return "No templates match your search. Try a different keyword.";
3168
+ }
3169
+ return "No templates match your filters. Try a different search.";
3170
+ }
3171
+
3172
+ // src/components/templates/TemplatesHeroSection.tsx
3173
+ import { jsxDEV as jsxDEV16 } from "react/jsx-dev-runtime";
3174
+ function TemplatesHeroSection({
3175
+ localTemplateCount,
3176
+ sourceCount
3177
+ }) {
3178
+ return /* @__PURE__ */ jsxDEV16("section", {
3179
+ className: "section-padding hero-gradient border-border/70 border-b",
3180
+ children: /* @__PURE__ */ jsxDEV16("div", {
3181
+ className: "editorial-shell space-y-8",
3182
+ children: [
3183
+ /* @__PURE__ */ jsxDEV16("div", {
3184
+ className: "max-w-4xl space-y-5",
3460
3185
  children: [
3461
- /* @__PURE__ */ jsxDEV12(DialogHeader2, {
3186
+ /* @__PURE__ */ jsxDEV16("p", {
3187
+ className: "editorial-kicker",
3188
+ children: "Proof through real scenarios"
3189
+ }, undefined, false, undefined, this),
3190
+ /* @__PURE__ */ jsxDEV16("h1", {
3191
+ className: "editorial-title",
3192
+ children: "Templates that show the open system in practice."
3193
+ }, undefined, false, undefined, this),
3194
+ /* @__PURE__ */ jsxDEV16("p", {
3195
+ className: "editorial-subtitle",
3196
+ children: "These scenarios are the fastest way to understand ContractSpec: explicit contracts, aligned surfaces, and an adoption path from OSS exploration into Studio deployment."
3197
+ }, undefined, false, undefined, this)
3198
+ ]
3199
+ }, undefined, true, undefined, this),
3200
+ /* @__PURE__ */ jsxDEV16("div", {
3201
+ className: "editorial-proof-strip",
3202
+ children: [
3203
+ /* @__PURE__ */ jsxDEV16("div", {
3204
+ className: "editorial-stat",
3462
3205
  children: [
3463
- /* @__PURE__ */ jsxDEV12(DialogTitle2, {
3464
- children: "Deploy in Studio"
3206
+ /* @__PURE__ */ jsxDEV16("span", {
3207
+ className: "editorial-stat-value",
3208
+ children: localTemplateCount
3465
3209
  }, undefined, false, undefined, this),
3466
- /* @__PURE__ */ jsxDEV12(DialogDescription2, {
3467
- children: "Deploy templates in ContractSpec Studio and run the full evidence-to-spec loop with your team."
3210
+ /* @__PURE__ */ jsxDEV16("span", {
3211
+ className: "editorial-label",
3212
+ children: "curated scenarios"
3468
3213
  }, undefined, false, undefined, this)
3469
3214
  ]
3470
3215
  }, undefined, true, undefined, this),
3471
- /* @__PURE__ */ jsxDEV12(StudioSignupSection, {
3472
- variant: "compact"
3473
- }, undefined, false, undefined, this)
3216
+ /* @__PURE__ */ jsxDEV16("div", {
3217
+ className: "editorial-stat",
3218
+ children: [
3219
+ /* @__PURE__ */ jsxDEV16("span", {
3220
+ className: "editorial-stat-value",
3221
+ children: sourceCount
3222
+ }, undefined, false, undefined, this),
3223
+ /* @__PURE__ */ jsxDEV16("span", {
3224
+ className: "editorial-label",
3225
+ children: "entry paths"
3226
+ }, undefined, false, undefined, this)
3227
+ ]
3228
+ }, undefined, true, undefined, this),
3229
+ /* @__PURE__ */ jsxDEV16("div", {
3230
+ className: "editorial-stat",
3231
+ children: [
3232
+ /* @__PURE__ */ jsxDEV16("span", {
3233
+ className: "editorial-stat-value",
3234
+ children: "OSS"
3235
+ }, undefined, false, undefined, this),
3236
+ /* @__PURE__ */ jsxDEV16("span", {
3237
+ className: "editorial-label",
3238
+ children: "first, Studio second"
3239
+ }, undefined, false, undefined, this)
3240
+ ]
3241
+ }, undefined, true, undefined, this)
3474
3242
  ]
3475
3243
  }, undefined, true, undefined, this)
3476
- }, undefined, false, undefined, this),
3477
- /* @__PURE__ */ jsxDEV12(Dialog3, {
3478
- open: !!selectedTemplateForCommand,
3479
- onOpenChange: () => setSelectedTemplateForCommand(null),
3480
- children: /* @__PURE__ */ jsxDEV12(DialogContent3, {
3481
- className: "max-w-md",
3244
+ ]
3245
+ }, undefined, true, undefined, this)
3246
+ }, undefined, false, undefined, this);
3247
+ }
3248
+
3249
+ // src/components/templates/TemplatesNextStepsSection.tsx
3250
+ import Link9 from "next/link";
3251
+ import { jsxDEV as jsxDEV17 } from "react/jsx-dev-runtime";
3252
+ function TemplatesNextStepsSection() {
3253
+ return /* @__PURE__ */ jsxDEV17("section", {
3254
+ className: "editorial-section bg-striped",
3255
+ children: /* @__PURE__ */ jsxDEV17("div", {
3256
+ className: "editorial-shell space-y-8",
3257
+ children: [
3258
+ /* @__PURE__ */ jsxDEV17("div", {
3259
+ className: "max-w-3xl space-y-4",
3260
+ children: [
3261
+ /* @__PURE__ */ jsxDEV17("p", {
3262
+ className: "editorial-kicker",
3263
+ children: "From template to real system"
3264
+ }, undefined, false, undefined, this),
3265
+ /* @__PURE__ */ jsxDEV17("h2", {
3266
+ className: "font-serif text-4xl tracking-[-0.04em] md:text-5xl",
3267
+ children: "Templates become useful when the system can absorb more context."
3268
+ }, undefined, false, undefined, this),
3269
+ /* @__PURE__ */ jsxDEV17("p", {
3270
+ className: "editorial-copy",
3271
+ children: "Use templates to prove the base flow, then layer integrations, knowledge, and runtime behavior on top without losing the same contract source."
3272
+ }, undefined, false, undefined, this)
3273
+ ]
3274
+ }, undefined, true, undefined, this),
3275
+ /* @__PURE__ */ jsxDEV17("div", {
3276
+ className: "grid gap-6 md:grid-cols-3",
3482
3277
  children: [
3483
- /* @__PURE__ */ jsxDEV12(DialogHeader2, {
3278
+ /* @__PURE__ */ jsxDEV17("div", {
3279
+ className: "editorial-panel space-y-4",
3484
3280
  children: [
3485
- /* @__PURE__ */ jsxDEV12(DialogTitle2, {
3486
- children: "Use this template"
3281
+ /* @__PURE__ */ jsxDEV17("div", {
3282
+ className: "text-3xl",
3283
+ children: "\uD83D\uDCB3"
3284
+ }, undefined, false, undefined, this),
3285
+ /* @__PURE__ */ jsxDEV17("h3", {
3286
+ className: "font-serif text-2xl tracking-[-0.03em]",
3287
+ children: "Add payments"
3487
3288
  }, undefined, false, undefined, this),
3488
- /* @__PURE__ */ jsxDEV12(DialogDescription2, {
3489
- children: "Initialize a new project with this template using the CLI."
3289
+ /* @__PURE__ */ jsxDEV17("p", {
3290
+ className: "text-muted-foreground text-sm",
3291
+ children: "Connect Stripe to any template for payment processing, subscriptions, and invoicing. Type-safe and policy-enforced."
3292
+ }, undefined, false, undefined, this),
3293
+ /* @__PURE__ */ jsxDEV17(Link9, {
3294
+ href: "/docs/integrations/stripe",
3295
+ className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3296
+ children: "Learn more →"
3490
3297
  }, undefined, false, undefined, this)
3491
3298
  ]
3492
3299
  }, undefined, true, undefined, this),
3493
- /* @__PURE__ */ jsxDEV12("div", {
3494
- className: "space-y-4 pt-4",
3300
+ /* @__PURE__ */ jsxDEV17("div", {
3301
+ className: "editorial-panel space-y-4",
3495
3302
  children: [
3496
- /* @__PURE__ */ jsxDEV12("div", {
3497
- className: "rounded-md border border-zinc-800 bg-zinc-950 p-4 font-mono text-sm text-zinc-50",
3498
- children: [
3499
- "npx contractspec init --template ",
3500
- commandId
3501
- ]
3502
- }, undefined, true, undefined, this),
3503
- /* @__PURE__ */ jsxDEV12("div", {
3504
- className: "flex gap-2",
3505
- children: /* @__PURE__ */ jsxDEV12("button", {
3506
- className: "btn-secondary w-full",
3507
- onClick: () => {
3508
- navigator.clipboard.writeText(`npx contractspec init --template ${commandId}`);
3509
- captureAnalyticsEvent2(analyticsEventNames2.COPY_COMMAND_CLICK, {
3510
- surface: "templates",
3511
- templateId: commandId,
3512
- filename: "templates-cli"
3513
- });
3514
- },
3515
- children: "Copy Command"
3516
- }, undefined, false, undefined, this)
3303
+ /* @__PURE__ */ jsxDEV17("div", {
3304
+ className: "text-3xl",
3305
+ children: "\uD83D\uDCE7"
3517
3306
  }, undefined, false, undefined, this),
3518
- /* @__PURE__ */ jsxDEV12("div", {
3519
- className: "relative",
3520
- children: [
3521
- /* @__PURE__ */ jsxDEV12("div", {
3522
- className: "absolute inset-0 flex items-center",
3523
- children: /* @__PURE__ */ jsxDEV12("span", {
3524
- className: "w-full border-border border-t"
3525
- }, undefined, false, undefined, this)
3526
- }, undefined, false, undefined, this),
3527
- /* @__PURE__ */ jsxDEV12("div", {
3528
- className: "relative flex justify-center text-xs uppercase",
3529
- children: /* @__PURE__ */ jsxDEV12("span", {
3530
- className: "bg-background px-2 text-muted-foreground",
3531
- children: "Or"
3532
- }, undefined, false, undefined, this)
3533
- }, undefined, false, undefined, this)
3534
- ]
3535
- }, undefined, true, undefined, this),
3536
- /* @__PURE__ */ jsxDEV12("button", {
3537
- className: "btn-ghost w-full text-sm",
3538
- onClick: () => {
3539
- captureAnalyticsEvent2(analyticsEventNames2.CTA_STUDIO_CLICK, {
3540
- surface: "templates",
3541
- templateId: commandId
3542
- });
3543
- setSelectedTemplateForCommand(null);
3544
- setStudioSignupModalOpen(true);
3545
- },
3546
- children: "Deploy to Studio"
3307
+ /* @__PURE__ */ jsxDEV17("h3", {
3308
+ className: "font-serif text-2xl tracking-[-0.03em]",
3309
+ children: "Add notifications"
3310
+ }, undefined, false, undefined, this),
3311
+ /* @__PURE__ */ jsxDEV17("p", {
3312
+ className: "text-muted-foreground text-sm",
3313
+ children: "Send transactional emails via Postmark or Resend. Process inbound emails with Gmail API. SMS via Twilio."
3314
+ }, undefined, false, undefined, this),
3315
+ /* @__PURE__ */ jsxDEV17(Link9, {
3316
+ href: "/docs/integrations",
3317
+ className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3318
+ children: "View integrations "
3319
+ }, undefined, false, undefined, this)
3320
+ ]
3321
+ }, undefined, true, undefined, this),
3322
+ /* @__PURE__ */ jsxDEV17("div", {
3323
+ className: "editorial-panel space-y-4",
3324
+ children: [
3325
+ /* @__PURE__ */ jsxDEV17("div", {
3326
+ className: "text-3xl",
3327
+ children: "\uD83E\uDDE0"
3328
+ }, undefined, false, undefined, this),
3329
+ /* @__PURE__ */ jsxDEV17("h3", {
3330
+ className: "font-serif text-2xl tracking-[-0.03em]",
3331
+ children: "Add AI and knowledge"
3332
+ }, undefined, false, undefined, this),
3333
+ /* @__PURE__ */ jsxDEV17("p", {
3334
+ className: "text-muted-foreground text-sm",
3335
+ children: "Power templates with OpenAI, vector search via Qdrant, and structured knowledge spaces for context-aware workflows."
3336
+ }, undefined, false, undefined, this),
3337
+ /* @__PURE__ */ jsxDEV17(Link9, {
3338
+ href: "/docs/knowledge",
3339
+ className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3340
+ children: "Learn about knowledge →"
3547
3341
  }, undefined, false, undefined, this)
3548
3342
  ]
3549
3343
  }, undefined, true, undefined, this)
3550
3344
  ]
3345
+ }, undefined, true, undefined, this),
3346
+ /* @__PURE__ */ jsxDEV17("div", {
3347
+ className: "pt-4 text-center",
3348
+ children: [
3349
+ /* @__PURE__ */ jsxDEV17("p", {
3350
+ className: "mb-4 text-muted-foreground text-sm",
3351
+ children: "All integrations are configured per-tenant with automatic health checks and credential rotation."
3352
+ }, undefined, false, undefined, this),
3353
+ /* @__PURE__ */ jsxDEV17(Link9, {
3354
+ href: "/docs/architecture",
3355
+ className: "btn-primary",
3356
+ children: "View Architecture"
3357
+ }, undefined, false, undefined, this)
3358
+ ]
3551
3359
  }, undefined, true, undefined, this)
3360
+ ]
3361
+ }, undefined, true, undefined, this)
3362
+ }, undefined, false, undefined, this);
3363
+ }
3364
+
3365
+ // src/components/templates/TemplatesPreviewModal.tsx
3366
+ import { Dialog as Dialog3, DialogContent as DialogContent3 } from "@contractspec/lib.ui-kit-web/ui/dialog";
3367
+ import { ScrollArea } from "@contractspec/lib.ui-kit-web/ui/scroll-area";
3368
+ import { TemplateRuntimeProvider } from "@contractspec/module.examples";
3369
+ import { jsxDEV as jsxDEV18 } from "react/jsx-dev-runtime";
3370
+ "use client";
3371
+ function TemplatePreviewModal({
3372
+ templateId,
3373
+ onClose
3374
+ }) {
3375
+ if (!supportsInlineTemplatePreview(templateId)) {
3376
+ return null;
3377
+ }
3378
+ return /* @__PURE__ */ jsxDEV18(Dialog3, {
3379
+ open: true,
3380
+ onOpenChange: (open) => !open && onClose(),
3381
+ children: /* @__PURE__ */ jsxDEV18(DialogContent3, {
3382
+ className: "mb-8 flex h-[calc(100vh-2rem)] min-w-[calc(100vw-2rem)] flex-col justify-between gap-0 p-0",
3383
+ children: /* @__PURE__ */ jsxDEV18(ScrollArea, {
3384
+ className: "flex flex-col justify-between overflow-hidden",
3385
+ children: /* @__PURE__ */ jsxDEV18(TemplateRuntimeProvider, {
3386
+ templateId,
3387
+ projectId: `marketing-preview-${templateId}`,
3388
+ children: /* @__PURE__ */ jsxDEV18(TemplatePreviewContent, {
3389
+ templateId
3390
+ }, undefined, false, undefined, this)
3391
+ }, templateId, false, undefined, this)
3392
+ }, undefined, false, undefined, this)
3393
+ }, undefined, false, undefined, this)
3394
+ }, undefined, false, undefined, this);
3395
+ }
3396
+
3397
+ // src/components/templates/TemplatesOverlays.tsx
3398
+ import {
3399
+ Dialog as Dialog4,
3400
+ DialogContent as DialogContent4,
3401
+ DialogDescription as DialogDescription3,
3402
+ DialogHeader as DialogHeader3,
3403
+ DialogTitle as DialogTitle3
3404
+ } from "@contractspec/lib.ui-kit-web/ui/dialog";
3405
+ import { jsxDEV as jsxDEV19, Fragment } from "react/jsx-dev-runtime";
3406
+ "use client";
3407
+ function TemplatesOverlays({
3408
+ previewTemplateId,
3409
+ onPreviewClose,
3410
+ studioSignupModalOpen,
3411
+ onStudioSignupModalOpenChange,
3412
+ selectedTemplateId,
3413
+ onTemplateCommandClose,
3414
+ onDeployStudio
3415
+ }) {
3416
+ return /* @__PURE__ */ jsxDEV19(Fragment, {
3417
+ children: [
3418
+ previewTemplateId ? /* @__PURE__ */ jsxDEV19(TemplatePreviewModal, {
3419
+ templateId: previewTemplateId,
3420
+ onClose: onPreviewClose
3421
+ }, undefined, false, undefined, this) : null,
3422
+ /* @__PURE__ */ jsxDEV19(Dialog4, {
3423
+ open: studioSignupModalOpen,
3424
+ onOpenChange: onStudioSignupModalOpenChange,
3425
+ children: /* @__PURE__ */ jsxDEV19(DialogContent4, {
3426
+ className: "max-h-[90vh] max-w-2xl overflow-y-auto",
3427
+ children: [
3428
+ /* @__PURE__ */ jsxDEV19(DialogHeader3, {
3429
+ children: [
3430
+ /* @__PURE__ */ jsxDEV19(DialogTitle3, {
3431
+ children: "Deploy in Studio"
3432
+ }, undefined, false, undefined, this),
3433
+ /* @__PURE__ */ jsxDEV19(DialogDescription3, {
3434
+ children: "Deploy templates in ContractSpec Studio and run the full evidence-to-spec loop with your team."
3435
+ }, undefined, false, undefined, this)
3436
+ ]
3437
+ }, undefined, true, undefined, this),
3438
+ /* @__PURE__ */ jsxDEV19(StudioSignupSection, {
3439
+ variant: "compact"
3440
+ }, undefined, false, undefined, this)
3441
+ ]
3442
+ }, undefined, true, undefined, this)
3443
+ }, undefined, false, undefined, this),
3444
+ /* @__PURE__ */ jsxDEV19(TemplateCommandDialog, {
3445
+ templateId: selectedTemplateId,
3446
+ onClose: onTemplateCommandClose,
3447
+ onDeployStudio
3448
+ }, undefined, false, undefined, this)
3449
+ ]
3450
+ }, undefined, true, undefined, this);
3451
+ }
3452
+
3453
+ // src/components/templates/template-filters.ts
3454
+ function buildTemplateFilterState(templates, search, selectedTag, getCandidate) {
3455
+ const searchScopedTemplates = templates.filter((template) => matchesTemplateSearch(getCandidate(template), search));
3456
+ const finalTemplates = selectedTag === null ? searchScopedTemplates : searchScopedTemplates.filter((template) => getCandidate(template).tags.includes(selectedTag));
3457
+ return {
3458
+ searchScopedTemplates,
3459
+ finalTemplates,
3460
+ tagFacets: buildTemplateTagFacets(searchScopedTemplates, getCandidate)
3461
+ };
3462
+ }
3463
+ function buildTemplateTagFacets(templates, getCandidate) {
3464
+ const counts = new Map;
3465
+ for (const template of templates) {
3466
+ for (const tag of new Set(getCandidate(template).tags)) {
3467
+ counts.set(tag, (counts.get(tag) ?? 0) + 1);
3468
+ }
3469
+ }
3470
+ return [...counts.entries()].map(([tag, count]) => ({ tag, count })).sort((left, right) => right.count - left.count || left.tag.localeCompare(right.tag));
3471
+ }
3472
+
3473
+ // src/components/templates/template-source.ts
3474
+ function isRegistryConfigured(registryUrl) {
3475
+ return Boolean(registryUrl?.trim());
3476
+ }
3477
+ function getAvailableTemplateSources(registryUrl) {
3478
+ return isRegistryConfigured(registryUrl) ? ["local", "registry"] : ["local"];
3479
+ }
3480
+
3481
+ // src/components/templates/template-tag-visibility.ts
3482
+ var DEFAULT_VISIBLE_TEMPLATE_TAGS = 10;
3483
+ function getVisibleTemplateTagFacets(tagFacets, selectedTag, expanded, visibleCount = DEFAULT_VISIBLE_TEMPLATE_TAGS) {
3484
+ if (expanded) {
3485
+ return {
3486
+ visibleTagFacets: pinSelectedTagFacet(tagFacets, selectedTag),
3487
+ hiddenTagFacets: []
3488
+ };
3489
+ }
3490
+ const visibleTagFacets = pinSelectedTagFacet(tagFacets.slice(0, visibleCount), selectedTag, tagFacets);
3491
+ const visibleTags = new Set(visibleTagFacets.map((facet) => facet.tag));
3492
+ return {
3493
+ visibleTagFacets,
3494
+ hiddenTagFacets: tagFacets.filter((facet) => !visibleTags.has(facet.tag))
3495
+ };
3496
+ }
3497
+ function pinSelectedTagFacet(tagFacets, selectedTag, fallbackTagFacets = tagFacets) {
3498
+ if (selectedTag === null || tagFacets.some((facet) => facet.tag === selectedTag)) {
3499
+ return [...tagFacets];
3500
+ }
3501
+ return [
3502
+ ...tagFacets,
3503
+ fallbackTagFacets.find((facet) => facet.tag === selectedTag) ?? {
3504
+ tag: selectedTag,
3505
+ count: 0
3506
+ }
3507
+ ];
3508
+ }
3509
+
3510
+ // src/components/templates/useTemplateBrowseState.ts
3511
+ import { useRegistryTemplates } from "@contractspec/lib.example-shared-ui";
3512
+ import { useEffect, useMemo, useState as useState2 } from "react";
3513
+ "use client";
3514
+ var REGISTRY_URL = process.env.NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL;
3515
+ function useTemplateBrowseState() {
3516
+ const [selectedTag, setSelectedTag] = useState2(null);
3517
+ const [search, setSearch] = useState2("");
3518
+ const [source, setSource] = useState2("local");
3519
+ const [showAllTags, setShowAllTags] = useState2(false);
3520
+ const registryConfigured = isRegistryConfigured(REGISTRY_URL);
3521
+ const availableSources = getAvailableTemplateSources(REGISTRY_URL);
3522
+ const localTemplates = useMemo(() => buildLocalTemplateCatalog(), []);
3523
+ const localTemplateById = useMemo(() => new Map(localTemplates.map((template) => [template.id, template])), [localTemplates]);
3524
+ const { data: registryTemplates = [], isLoading: registryLoading } = useRegistryTemplates();
3525
+ const localFilterState = useMemo(() => buildTemplateFilterState(localTemplates, search, selectedTag, (template) => ({
3526
+ title: template.title,
3527
+ description: template.description,
3528
+ tags: template.tags
3529
+ })), [localTemplates, search, selectedTag]);
3530
+ const registryFilterState = useMemo(() => buildTemplateFilterState(registryTemplates, search, selectedTag, (template) => ({
3531
+ title: template.name,
3532
+ description: template.description,
3533
+ tags: template.tags
3534
+ })), [registryTemplates, search, selectedTag]);
3535
+ const activeFilterState = source === "registry" ? registryFilterState : localFilterState;
3536
+ const suppressTagRail = source === "registry" && (registryLoading || registryTemplates.length === 0);
3537
+ const { visibleTagFacets, hiddenTagFacets } = useMemo(() => getVisibleTemplateTagFacets(activeFilterState.tagFacets, selectedTag, showAllTags), [activeFilterState.tagFacets, selectedTag, showAllTags]);
3538
+ const showTagFilters = !suppressTagRail && (visibleTagFacets.length > 0 || hiddenTagFacets.length > 0);
3539
+ useEffect(() => {
3540
+ setShowAllTags(false);
3541
+ }, [search, showTagFilters, source]);
3542
+ return {
3543
+ selectedTag,
3544
+ setSelectedTag,
3545
+ search,
3546
+ setSearch,
3547
+ source,
3548
+ setSource,
3549
+ showAllTags,
3550
+ setShowAllTags,
3551
+ registryConfigured,
3552
+ availableSources,
3553
+ localTemplates,
3554
+ localTemplateById,
3555
+ registryTemplates,
3556
+ registryLoading,
3557
+ localFilterState,
3558
+ registryFilterState,
3559
+ visibleTagFacets,
3560
+ hiddenTagFacets,
3561
+ showTagFilters
3562
+ };
3563
+ }
3564
+
3565
+ // src/components/templates/TemplatesClientPage.tsx
3566
+ import {
3567
+ analyticsEventNames as analyticsEventNames3,
3568
+ captureAnalyticsEvent as captureAnalyticsEvent3
3569
+ } from "@contractspec/bundle.library/libs/posthog/client";
3570
+ import { useState as useState3 } from "react";
3571
+ import { jsxDEV as jsxDEV20, Fragment as Fragment2 } from "react/jsx-dev-runtime";
3572
+ "use client";
3573
+ var TemplatesPage = () => {
3574
+ const [previewTemplateId, setPreviewTemplateId] = useState3(null);
3575
+ const [studioSignupModalOpen, setStudioSignupModalOpen] = useState3(false);
3576
+ const [selectedTemplateId, setSelectedTemplateId] = useState3(null);
3577
+ const {
3578
+ selectedTag,
3579
+ setSelectedTag,
3580
+ search,
3581
+ setSearch,
3582
+ source,
3583
+ setSource,
3584
+ showAllTags,
3585
+ setShowAllTags,
3586
+ registryConfigured,
3587
+ availableSources,
3588
+ localTemplates,
3589
+ localTemplateById,
3590
+ registryTemplates,
3591
+ registryLoading,
3592
+ localFilterState,
3593
+ registryFilterState,
3594
+ visibleTagFacets,
3595
+ hiddenTagFacets,
3596
+ showTagFilters
3597
+ } = useTemplateBrowseState();
3598
+ return /* @__PURE__ */ jsxDEV20(Fragment2, {
3599
+ children: [
3600
+ /* @__PURE__ */ jsxDEV20("main", {
3601
+ children: [
3602
+ /* @__PURE__ */ jsxDEV20(TemplatesHeroSection, {
3603
+ localTemplateCount: localTemplates.length,
3604
+ sourceCount: availableSources.length
3605
+ }, undefined, false, undefined, this),
3606
+ /* @__PURE__ */ jsxDEV20(TemplatesBrowseControls, {
3607
+ registryConfigured,
3608
+ availableSources,
3609
+ source,
3610
+ onSourceChange: setSource,
3611
+ search,
3612
+ onSearchChange: setSearch,
3613
+ selectedTag,
3614
+ onTagChange: setSelectedTag,
3615
+ showTagFilters,
3616
+ visibleTagFacets,
3617
+ hiddenTagFacets,
3618
+ showAllTags,
3619
+ onShowAllTagsChange: setShowAllTags
3620
+ }, undefined, false, undefined, this),
3621
+ /* @__PURE__ */ jsxDEV20(TemplatesCatalogSection, {
3622
+ source,
3623
+ registryConfigured,
3624
+ registryLoading,
3625
+ registryHasTemplates: registryTemplates.length > 0,
3626
+ localTemplates: localFilterState.finalTemplates,
3627
+ registryTemplates: registryFilterState.finalTemplates,
3628
+ localTemplateById,
3629
+ onPreview: setPreviewTemplateId,
3630
+ onUseTemplate: (templateId, templateSource) => {
3631
+ captureAnalyticsEvent3(analyticsEventNames3.EXAMPLE_REPO_OPEN, {
3632
+ surface: "templates",
3633
+ templateId,
3634
+ source: templateSource
3635
+ });
3636
+ setSelectedTemplateId(templateId);
3637
+ },
3638
+ hasSearch: search.trim().length > 0,
3639
+ selectedTag
3640
+ }, undefined, false, undefined, this),
3641
+ /* @__PURE__ */ jsxDEV20(TemplatesNextStepsSection, {}, undefined, false, undefined, this)
3642
+ ]
3643
+ }, undefined, true, undefined, this),
3644
+ /* @__PURE__ */ jsxDEV20(TemplatesOverlays, {
3645
+ previewTemplateId,
3646
+ onPreviewClose: () => setPreviewTemplateId(null),
3647
+ studioSignupModalOpen,
3648
+ onStudioSignupModalOpenChange: setStudioSignupModalOpen,
3649
+ selectedTemplateId,
3650
+ onTemplateCommandClose: () => setSelectedTemplateId(null),
3651
+ onDeployStudio: () => {
3652
+ setSelectedTemplateId(null);
3653
+ setStudioSignupModalOpen(true);
3654
+ }
3552
3655
  }, undefined, false, undefined, this)
3553
3656
  ]
3554
3657
  }, undefined, true, undefined, this);