@pipe0/react 0.0.2 → 0.0.3

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 (25) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/components/defaults/adapters/key-value-list-input.mjs +3 -1
  3. package/dist/components/defaults/adapters/key-value-list-input.mjs.map +1 -1
  4. package/dist/components/defaults/adapters/prompt-input.mjs +1 -0
  5. package/dist/components/defaults/adapters/prompt-input.mjs.map +1 -1
  6. package/dist/components/defaults/adapters/tagged-text-input.mjs +1 -0
  7. package/dist/components/defaults/adapters/tagged-text-input.mjs.map +1 -1
  8. package/dist/components/defaults/adapters/template-input.mjs +1 -0
  9. package/dist/components/defaults/adapters/template-input.mjs.map +1 -1
  10. package/dist/components/internal/LiquidEditor/LiquidEditor.mjs +61 -37
  11. package/dist/components/internal/LiquidEditor/LiquidEditor.mjs.map +1 -1
  12. package/dist/components/internal/LiquidEditor/UnifiedReferencePicker.mjs +45 -31
  13. package/dist/components/internal/LiquidEditor/UnifiedReferencePicker.mjs.map +1 -1
  14. package/dist/components/internal/suggestion-menu/suggestion-menu.mjs +17 -9
  15. package/dist/components/internal/suggestion-menu/suggestion-menu.mjs.map +1 -1
  16. package/dist/components/ui/button.d.mts +2 -2
  17. package/dist/hooks/use-async-remote-source.mjs +93 -0
  18. package/dist/hooks/use-async-remote-source.mjs.map +1 -0
  19. package/dist/hooks/use-pipe-catalog-table.d.mts +8 -8
  20. package/dist/styles/pipe0-form.css +0 -48
  21. package/dist/types/field-props.d.mts +26 -2
  22. package/dist/types/field-props.d.mts.map +1 -1
  23. package/dist/utils/build-section-handlers.mjs +8 -3
  24. package/dist/utils/build-section-handlers.mjs.map +1 -1
  25. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"UnifiedReferencePicker.mjs","names":[],"sources":["../../../../src/components/internal/LiquidEditor/UnifiedReferencePicker.tsx"],"sourcesContent":["import type { PipesFieldDefinitionWithName } from \"@pipe0/base\";\nimport { Hash, Key } from \"lucide-react\";\nimport type { ConstantSuggestion, SecretSuggestion } from \"../../../types/field-props.js\";\nimport type {\n SuggestionItem,\n SuggestionMenuRenderProps,\n} from \"../suggestion-menu/suggestion-menu-types.js\";\n\nexport type ReferenceKind = \"field\" | \"secret\" | \"constant\";\n\nexport interface ReferenceContext {\n kind: ReferenceKind;\n}\n\nexport interface ReferenceSources {\n inputFields: PipesFieldDefinitionWithName[];\n secretSuggestions: SecretSuggestion[];\n constantSuggestions: ConstantSuggestion[];\n}\n\nconst PREFIX_RE = /^([fsc])\\/(.*)$/;\n\n/**\n * Parses a typed query into `(prefix, residual)`. Lets users filter\n * directly to a single source: `f/email`, `s/STRIPE`, `c/REGION`.\n * Without a prefix, all sources are searched.\n */\nexport function parseQuery(query: string): {\n prefix: ReferenceKind | null;\n residual: string;\n} {\n const m = query.match(PREFIX_RE);\n if (!m) return { prefix: null, residual: query };\n const map = { f: \"field\", s: \"secret\", c: \"constant\" } as const;\n return { prefix: map[m[1] as \"f\" | \"s\" | \"c\"], residual: m[2] };\n}\n\nfunction score(haystack: string, needle: string): number {\n if (!needle) return 1;\n const h = haystack.toLowerCase();\n const n = needle.toLowerCase();\n if (h === n) return 100;\n if (h.startsWith(n)) return 50;\n if (h.includes(n)) return 10;\n return 0;\n}\n\nfunction buildFieldItem(\n f: PipesFieldDefinitionWithName,\n insertField: (name: string) => string,\n): SuggestionItem<ReferenceContext> {\n return {\n title: f.resolvedName,\n subtext: f.type,\n keywords: [f.type],\n context: { kind: \"field\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, insertField(f.resolvedName)).run();\n },\n };\n}\n\nfunction buildSecretItem(s: SecretSuggestion): SuggestionItem<ReferenceContext> {\n return {\n title: s.label,\n subtext: `${s.mask} · ${s.ownershipLevel}${s.providerHint ? ` · ${s.providerHint}` : \"\"}`,\n keywords: [s.publicId, s.providerHint ?? \"\"],\n context: { kind: \"secret\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, `{{ SECRETS.${s.publicId} }}`).run();\n },\n };\n}\n\nfunction buildConstantItem(c: ConstantSuggestion): SuggestionItem<ReferenceContext> {\n return {\n title: c.label,\n subtext: c.ownershipLevel,\n keywords: [c.publicId],\n context: { kind: \"constant\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, `{{ CONSTANTS.${c.publicId} }}`).run();\n },\n };\n}\n\n/**\n * Builds the suggestion list for a given query against the three sources.\n * Behavior:\n * - empty query → returns all items in source order (Fields, then\n * Secrets, then Constants). Header rows are rendered separately by\n * the picker UI — this function returns a flat list of items only.\n * - non-empty query → ranks across all sources with a simple\n * starts-with > includes scoring. Items with a zero score are\n * dropped.\n * - prefix syntax `f/`, `s/`, `c/` filters to a single source before\n * scoring with the residual.\n */\nexport function buildReferenceItems(\n query: string,\n sources: ReferenceSources,\n expectedFieldType: string | undefined,\n insertField: (name: string) => string,\n): SuggestionItem<ReferenceContext>[] {\n const { prefix, residual } = parseQuery(query);\n\n const fieldsAll = expectedFieldType\n ? sources.inputFields.filter((f) => f.type === expectedFieldType)\n : sources.inputFields;\n\n const fieldItems = fieldsAll.map((f) => buildFieldItem(f, insertField));\n const secretItems = sources.secretSuggestions.map(buildSecretItem);\n const constantItems = sources.constantSuggestions.map(buildConstantItem);\n\n const pool: SuggestionItem<ReferenceContext>[] =\n prefix === \"field\"\n ? fieldItems\n : prefix === \"secret\"\n ? secretItems\n : prefix === \"constant\"\n ? constantItems\n : [...fieldItems, ...secretItems, ...constantItems];\n\n if (!residual.trim()) return pool;\n\n return pool\n .map((item) => {\n const titleScore = score(item.title, residual);\n const keywordScore = (item.keywords ?? []).reduce(\n (best, kw) => Math.max(best, score(kw, residual)),\n 0,\n );\n const subtextScore = item.subtext ? score(item.subtext, residual) * 0.5 : 0;\n const total = Math.max(titleScore, keywordScore, subtextScore);\n return { item, total };\n })\n .filter(({ total }) => total > 0)\n .sort((a, b) => b.total - a.total)\n .map(({ item }) => item);\n}\n\nfunction KindIcon({ kind }: { kind: ReferenceKind }) {\n // Fields are the default category and don't need a marker — the section\n // header and the type column on the right convey the kind.\n if (kind === \"field\") return null;\n if (kind === \"secret\") return <Key className=\"pz:size-3.5 pz:text-amber-700\" aria-hidden />;\n return <Hash className=\"pz:size-3.5 pz:text-violet-700\" aria-hidden />;\n}\n\nfunction SectionHeader({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"pz:px-2 pz:pt-1.5 pz:pb-0.5 pz:text-[10px] pz:font-medium pz:uppercase pz:tracking-wide pz:text-muted-foreground\">\n {children}\n </div>\n );\n}\n\nfunction ItemRow({\n item,\n active,\n onSelect,\n}: {\n item: SuggestionItem<ReferenceContext>;\n active: boolean;\n onSelect: (item: SuggestionItem<ReferenceContext>) => void;\n}) {\n return (\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={active}\n onClick={() => onSelect(item)}\n className={[\n \"pz:flex pz:w-full pz:items-center pz:gap-2 pz:rounded-sm pz:px-2 pz:py-1 pz:text-sm pz:text-left pz:cursor-pointer\",\n active\n ? \"pz:bg-accent pz:text-accent-foreground\"\n : \"pz:hover:bg-accent pz:hover:text-accent-foreground\",\n ].join(\" \")}\n >\n <KindIcon kind={item.context?.kind ?? \"field\"} />\n <span className=\"pz:truncate\">{item.title}</span>\n {item.subtext && (\n <span className=\"pz:ml-auto pz:shrink-0 pz:truncate pz:text-xs pz:text-muted-foreground\">\n {item.subtext}\n </span>\n )}\n </button>\n );\n}\n\n/**\n * Picker UI rendered inside the SuggestionMenu's children render-prop.\n *\n * - Empty query → sectioned view (Fields, Secrets, Constants).\n * - Non-empty query → flat ranked list.\n *\n * The selected-index pointer from `SuggestionMenuRenderProps` always maps\n * to the flat `items` order. Sectioned mode uses the same flat order but\n * inserts headers between the boundaries, so highlight tracking still\n * works without bespoke navigation.\n */\nexport function UnifiedReferencePicker({\n items,\n selectedIndex,\n onSelect,\n query,\n hasSecretsResolver,\n inputFieldsCount,\n constantsCount,\n}: SuggestionMenuRenderProps<ReferenceContext> & {\n query: string;\n hasSecretsResolver: boolean;\n inputFieldsCount: number;\n constantsCount: number;\n}) {\n const { prefix, residual } = parseQuery(query);\n const isFlat = !!residual.trim() || prefix !== null;\n\n if (isFlat) {\n if (items.length === 0) {\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n {prefix && (\n <SectionHeader>\n {prefix === \"field\" ? \"Fields\" : prefix === \"secret\" ? \"Secrets\" : \"Constants\"}\n </SectionHeader>\n )}\n <div className=\"pz:px-2 pz:py-1.5 pz:text-sm pz:text-muted-foreground\">\n {describeEmpty(prefix)}\n </div>\n </div>\n );\n }\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n {prefix && (\n <SectionHeader>\n {prefix === \"field\" ? \"Fields\" : prefix === \"secret\" ? \"Secrets\" : \"Constants\"}\n </SectionHeader>\n )}\n {items.map((item, index) => (\n <ItemRow\n key={`${item.context?.kind}-${item.title}`}\n item={item}\n active={selectedIndex === index}\n onSelect={onSelect}\n />\n ))}\n </div>\n );\n }\n\n // Sectioned view — always render Fields and Secrets headers in fixed\n // order, with empty-state hints when a section has no items. Constants\n // only appear when there are any to show.\n //\n // The selectedIndex still maps to the flat `items` order returned by\n // `buildReferenceItems` (Fields → Secrets → Constants).\n const fieldItems = items.filter((it) => it.context?.kind === \"field\");\n const secretItems = items.filter((it) => it.context?.kind === \"secret\");\n const constantItems = items.filter((it) => it.context?.kind === \"constant\");\n\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n <Section\n label=\"Fields\"\n kind=\"field\"\n items={fieldItems}\n startIndex={0}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint={\n inputFieldsCount === 0\n ? \"No input fields available.\"\n : \"No matching input fields.\"\n }\n />\n {hasSecretsResolver && (\n <Section\n label=\"Secrets\"\n kind=\"secret\"\n items={secretItems}\n startIndex={fieldItems.length}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint=\"No matching secrets.\"\n helperHint=\"Type /s/ to filter to secrets only.\"\n />\n )}\n {constantsCount > 0 && (\n <Section\n label=\"Constants\"\n kind=\"constant\"\n items={constantItems}\n startIndex={fieldItems.length + secretItems.length}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint=\"No matching constants.\"\n />\n )}\n </div>\n );\n}\n\nfunction Section({\n label,\n kind,\n items,\n startIndex,\n selectedIndex,\n onSelect,\n emptyHint,\n helperHint,\n}: {\n label: string;\n kind: ReferenceKind;\n items: SuggestionItem<ReferenceContext>[];\n startIndex: number;\n selectedIndex?: number;\n onSelect: (item: SuggestionItem<ReferenceContext>) => void;\n emptyHint: string;\n helperHint?: string;\n}) {\n return (\n <div className=\"pz:flex pz:flex-col\">\n <SectionHeader>\n {label}\n {items.length > 0 && (\n <span className=\"pz:ml-1 pz:normal-case pz:tracking-normal\">({items.length})</span>\n )}\n </SectionHeader>\n {items.length === 0 ? (\n <div className=\"pz:px-2 pz:py-1 pz:text-xs pz:text-muted-foreground\">\n {emptyHint}\n {helperHint && <span className=\"pz:block pz:opacity-70\">{helperHint}</span>}\n </div>\n ) : (\n items.map((item, i) => (\n <ItemRow\n key={`${kind}-${item.title}`}\n item={item}\n active={selectedIndex === startIndex + i}\n onSelect={onSelect}\n />\n ))\n )}\n </div>\n );\n}\n\nfunction describeEmpty(prefix: ReferenceKind | null): string {\n if (prefix === \"secret\") return \"No matching secrets.\";\n if (prefix === \"constant\") return \"No matching constants.\";\n if (prefix === \"field\") return \"No matching fields.\";\n return \"No matches.\";\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"UnifiedReferencePicker.mjs","names":[],"sources":["../../../../src/components/internal/LiquidEditor/UnifiedReferencePicker.tsx"],"sourcesContent":["import type { PipesFieldDefinitionWithName } from \"@pipe0/base\";\nimport { Hash, Key } from \"lucide-react\";\nimport type { ConstantSuggestion, SecretSuggestion } from \"../../../types/field-props.js\";\nimport type {\n SuggestionItem,\n SuggestionMenuRenderProps,\n} from \"../suggestion-menu/suggestion-menu-types.js\";\n\nexport const SECTION_CAP = 5;\n\nexport type ReferenceKind = \"field\" | \"secret\" | \"constant\";\n\nexport interface ReferenceContext {\n kind: ReferenceKind;\n}\n\nexport interface ReferenceSources {\n inputFields: PipesFieldDefinitionWithName[];\n secretSuggestions: SecretSuggestion[];\n constantSuggestions: ConstantSuggestion[];\n}\n\nconst PREFIX_RE = /^([fsc])\\/(.*)$/;\n\n/**\n * Parses a typed query into `(prefix, residual)`. Lets users filter\n * directly to a single source: `f/email`, `s/STRIPE`, `c/REGION`.\n * Without a prefix, all sources are searched.\n */\nexport function parseQuery(query: string): {\n prefix: ReferenceKind | null;\n residual: string;\n} {\n const m = query.match(PREFIX_RE);\n if (!m) return { prefix: null, residual: query };\n const map = { f: \"field\", s: \"secret\", c: \"constant\" } as const;\n return { prefix: map[m[1] as \"f\" | \"s\" | \"c\"], residual: m[2] };\n}\n\nfunction score(haystack: string, needle: string): number {\n if (!needle) return 1;\n const h = haystack.toLowerCase();\n const n = needle.toLowerCase();\n if (h === n) return 100;\n if (h.startsWith(n)) return 50;\n if (h.includes(n)) return 10;\n return 0;\n}\n\nfunction buildFieldItem(\n f: PipesFieldDefinitionWithName,\n insertField: (name: string) => string,\n): SuggestionItem<ReferenceContext> {\n return {\n title: f.resolvedName,\n subtext: f.type,\n keywords: [f.type],\n context: { kind: \"field\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, insertField(f.resolvedName)).run();\n },\n };\n}\n\nfunction buildSecretItem(s: SecretSuggestion): SuggestionItem<ReferenceContext> {\n return {\n title: s.label,\n subtext: `${s.mask} · ${s.ownershipLevel}${s.providerHint ? ` · ${s.providerHint}` : \"\"}`,\n keywords: [s.publicId, s.providerHint ?? \"\"],\n context: { kind: \"secret\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, `{{ SECRETS.${s.publicId} }}`).run();\n },\n };\n}\n\nfunction buildConstantItem(c: ConstantSuggestion): SuggestionItem<ReferenceContext> {\n return {\n title: c.label,\n subtext: c.ownershipLevel,\n keywords: [c.publicId],\n context: { kind: \"constant\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, `{{ CONSTANTS.${c.publicId} }}`).run();\n },\n };\n}\n\n/**\n * Builds the suggestion list for a given query against the three sources.\n * Behavior:\n * - empty query → returns all items in source order (Fields, then\n * Secrets, then Constants). Header rows are rendered separately by\n * the picker UI — this function returns a flat list of items only.\n * - non-empty query → ranks across all sources with a simple\n * starts-with > includes scoring. Items with a zero score are\n * dropped.\n * - prefix syntax `f/`, `s/`, `c/` filters to a single source before\n * scoring with the residual.\n */\nexport function buildReferenceItems(\n query: string,\n sources: ReferenceSources,\n expectedFieldType: string | undefined,\n insertField: (name: string) => string,\n): SuggestionItem<ReferenceContext>[] {\n const { prefix, residual } = parseQuery(query);\n\n const fieldsAll = expectedFieldType\n ? sources.inputFields.filter((f) => f.type === expectedFieldType)\n : sources.inputFields;\n\n const fieldItems = fieldsAll.map((f) => buildFieldItem(f, insertField));\n const secretItems = sources.secretSuggestions.map(buildSecretItem);\n const constantItems = sources.constantSuggestions.map(buildConstantItem);\n\n const pool: SuggestionItem<ReferenceContext>[] =\n prefix === \"field\"\n ? fieldItems\n : prefix === \"secret\"\n ? secretItems\n : prefix === \"constant\"\n ? constantItems\n : [...fieldItems, ...secretItems, ...constantItems];\n\n if (!residual.trim()) return pool;\n\n return pool\n .map((item) => {\n const titleScore = score(item.title, residual);\n const keywordScore = (item.keywords ?? []).reduce(\n (best, kw) => Math.max(best, score(kw, residual)),\n 0,\n );\n const subtextScore = item.subtext ? score(item.subtext, residual) * 0.5 : 0;\n const total = Math.max(titleScore, keywordScore, subtextScore);\n return { item, total };\n })\n .filter(({ total }) => total > 0)\n .sort((a, b) => b.total - a.total)\n .map(({ item }) => item);\n}\n\nfunction KindIcon({ kind }: { kind: ReferenceKind }) {\n // Fields are the default category and don't need a marker — the section\n // header and the type column on the right convey the kind.\n if (kind === \"field\") return null;\n if (kind === \"secret\") return <Key className=\"pz:size-3.5 pz:text-amber-700\" aria-hidden />;\n return <Hash className=\"pz:size-3.5 pz:text-violet-700\" aria-hidden />;\n}\n\nfunction SectionHeader({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"pz:px-2 pz:pt-1.5 pz:pb-0.5 pz:text-[10px] pz:font-medium pz:uppercase pz:tracking-wide pz:text-muted-foreground\">\n {children}\n </div>\n );\n}\n\nfunction ItemRow({\n item,\n active,\n onSelect,\n}: {\n item: SuggestionItem<ReferenceContext>;\n active: boolean;\n onSelect: (item: SuggestionItem<ReferenceContext>) => void;\n}) {\n return (\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={active}\n onClick={() => onSelect(item)}\n className={[\n \"pz:flex pz:w-full pz:items-center pz:gap-2 pz:rounded-sm pz:px-2 pz:py-1 pz:text-sm pz:text-left pz:cursor-pointer\",\n active\n ? \"pz:bg-accent pz:text-accent-foreground\"\n : \"pz:hover:bg-accent pz:hover:text-accent-foreground\",\n ].join(\" \")}\n >\n <KindIcon kind={item.context?.kind ?? \"field\"} />\n <span className=\"pz:truncate\">{item.title}</span>\n {item.subtext && (\n <span className=\"pz:ml-auto pz:shrink-0 pz:truncate pz:text-xs pz:text-muted-foreground\">\n {item.subtext}\n </span>\n )}\n </button>\n );\n}\n\n/**\n * Picker UI rendered inside the SuggestionMenu's children render-prop.\n *\n * - Empty query → sectioned view (Fields, Secrets, Constants).\n * - Non-empty query → flat ranked list.\n *\n * The selected-index pointer from `SuggestionMenuRenderProps` always maps\n * to the flat `items` order. Sectioned mode uses the same flat order but\n * inserts headers between the boundaries, so highlight tracking still\n * works without bespoke navigation.\n */\nexport interface OverflowCounts {\n field: number;\n secret: number;\n constant: number;\n}\n\nexport function UnifiedReferencePicker({\n items,\n selectedIndex,\n onSelect,\n query,\n hasSecretsResolver,\n hasConstantsResolver,\n inputFieldsCount,\n secretsPending,\n constantsPending,\n overflow,\n}: SuggestionMenuRenderProps<ReferenceContext> & {\n query: string;\n hasSecretsResolver: boolean;\n hasConstantsResolver: boolean;\n inputFieldsCount: number;\n secretsPending: boolean;\n constantsPending: boolean;\n overflow: OverflowCounts;\n}) {\n const { prefix, residual } = parseQuery(query);\n const isFlat = !!residual.trim() || prefix !== null;\n\n if (isFlat) {\n if (items.length === 0) {\n const isPendingForPrefix =\n (prefix === \"secret\" && secretsPending) ||\n (prefix === \"constant\" && constantsPending) ||\n (prefix === null && (secretsPending || constantsPending));\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n {prefix && (\n <SectionHeader>\n {prefix === \"field\" ? \"Fields\" : prefix === \"secret\" ? \"Secrets\" : \"Constants\"}\n </SectionHeader>\n )}\n <div className=\"pz:px-2 pz:py-1.5 pz:text-sm pz:text-muted-foreground\">\n {isPendingForPrefix ? \"Searching…\" : describeEmpty(prefix)}\n </div>\n </div>\n );\n }\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n {prefix && (\n <SectionHeader>\n {prefix === \"field\" ? \"Fields\" : prefix === \"secret\" ? \"Secrets\" : \"Constants\"}\n </SectionHeader>\n )}\n {items.map((item, index) => (\n <ItemRow\n key={`${item.context?.kind}-${item.title}`}\n item={item}\n active={selectedIndex === index}\n onSelect={onSelect}\n />\n ))}\n </div>\n );\n }\n\n // Sectioned view — always render Fields and Secrets headers in fixed\n // order, with empty-state hints when a section has no items. Constants\n // only appear when there are any to show.\n //\n // Items here are pre-capped per kind (LiquidEditor applies SECTION_CAP).\n // The selectedIndex maps to this capped flat order — no hidden rows.\n const fieldItems = items.filter((it) => it.context?.kind === \"field\");\n const secretItems = items.filter((it) => it.context?.kind === \"secret\");\n const constantItems = items.filter((it) => it.context?.kind === \"constant\");\n\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n <Section\n label=\"Fields\"\n kind=\"field\"\n items={fieldItems}\n startIndex={0}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint={\n inputFieldsCount === 0 ? \"No input fields available.\" : \"No matching input fields.\"\n }\n overflow={overflow.field}\n overflowHelper=\"Type to filter.\"\n />\n {hasSecretsResolver && (\n <Section\n label=\"Secrets\"\n kind=\"secret\"\n items={secretItems}\n startIndex={fieldItems.length}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint={secretsPending ? \"Searching…\" : \"No matching secrets.\"}\n helperHint=\"Type /s/ to filter to secrets only.\"\n pending={secretsPending}\n overflow={overflow.secret}\n overflowHelper=\"Type to filter, or /s/ for secrets only.\"\n />\n )}\n {hasConstantsResolver && (\n <Section\n label=\"Constants\"\n kind=\"constant\"\n items={constantItems}\n startIndex={fieldItems.length + secretItems.length}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint={constantsPending ? \"Searching…\" : \"No matching constants.\"}\n helperHint=\"Type /c/ to filter to constants only.\"\n pending={constantsPending}\n overflow={overflow.constant}\n overflowHelper=\"Type to filter, or /c/ for constants only.\"\n />\n )}\n </div>\n );\n}\n\nfunction Section({\n label,\n kind,\n items,\n startIndex,\n selectedIndex,\n onSelect,\n emptyHint,\n helperHint,\n pending,\n overflow = 0,\n overflowHelper,\n}: {\n label: string;\n kind: ReferenceKind;\n items: SuggestionItem<ReferenceContext>[];\n startIndex: number;\n selectedIndex?: number;\n onSelect: (item: SuggestionItem<ReferenceContext>) => void;\n emptyHint: string;\n helperHint?: string;\n pending?: boolean;\n overflow?: number;\n overflowHelper?: string;\n}) {\n return (\n <div className=\"pz:flex pz:flex-col\">\n <SectionHeader>\n {label}\n {items.length > 0 && (\n <span className=\"pz:ml-1 pz:normal-case pz:tracking-normal\">\n ({items.length}\n {overflow > 0 && ` of ${items.length + overflow}`})\n </span>\n )}\n {pending && (\n <span className=\"pz:ml-1 pz:normal-case pz:tracking-normal pz:opacity-70\">\n · Searching…\n </span>\n )}\n </SectionHeader>\n {items.length === 0 ? (\n <div className=\"pz:px-2 pz:py-1 pz:text-xs pz:text-muted-foreground\">\n {emptyHint}\n {helperHint && <span className=\"pz:block pz:opacity-70\">{helperHint}</span>}\n </div>\n ) : (\n <>\n {items.map((item, i) => (\n <ItemRow\n key={`${kind}-${item.title}`}\n item={item}\n active={selectedIndex === startIndex + i}\n onSelect={onSelect}\n />\n ))}\n {overflow > 0 && overflowHelper && (\n <div className=\"pz:px-2 pz:py-0.5 pz:text-[11px] pz:text-muted-foreground pz:opacity-70\">\n +{overflow} more — {overflowHelper}\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\nfunction describeEmpty(prefix: ReferenceKind | null): string {\n if (prefix === \"secret\") return \"No matching secrets.\";\n if (prefix === \"constant\") return \"No matching constants.\";\n if (prefix === \"field\") return \"No matching fields.\";\n return \"No matches.\";\n}\n"],"mappings":"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"}
@@ -8,7 +8,7 @@ import { PluginKey } from "@tiptap/pm/state";
8
8
  import { Suggestion, SuggestionPluginKey } from "@tiptap/suggestion";
9
9
 
10
10
  //#region src/components/internal/suggestion-menu/suggestion-menu.tsx
11
- const SuggestionMenu = ({ editor: providedEditor, floatingOptions, selector = "tiptap-suggestion-menu", children, maxHeight = 384, pluginKey = SuggestionPluginKey, ...internalSuggestionProps }) => {
11
+ const SuggestionMenu = ({ editor: providedEditor, floatingOptions, selector = "tiptap-suggestion-menu", children, maxHeight = 384, pluginKey = SuggestionPluginKey, liveItems, ...internalSuggestionProps }) => {
12
12
  const editor = providedEditor ?? null;
13
13
  const [show, setShow] = useState(false);
14
14
  const [internalClientRect, setInternalClientRect] = useState(null);
@@ -54,19 +54,26 @@ const SuggestionMenu = ({ editor: providedEditor, floatingOptions, selector = "t
54
54
  if (!range) return;
55
55
  const { view, state } = editor;
56
56
  const { selection } = state;
57
- if (!editor.extensionManager.extensions.some((extension) => extension.name === "mention" && extension.options?.suggestion?.char === internalSuggestionPropsRef.current.char)) {
57
+ const isMention = editor.extensionManager.extensions.some((extension) => extension.name === "mention" && extension.options?.suggestion?.char === internalSuggestionPropsRef.current.char);
58
+ let insertRange;
59
+ if (!isMention) {
58
60
  const cursorPosition = selection.$from.pos;
59
61
  const previousNode = selection.$head?.nodeBefore;
60
62
  const startPosition = previousNode ? calculateStartPosition(cursorPosition, previousNode, internalSuggestionPropsRef.current.char) : selection.$from.start();
61
63
  const transaction = state.tr.deleteRange(startPosition, cursorPosition);
62
64
  view.dispatch(transaction);
63
- }
64
- const overrideSpace = view.state.selection.$to.nodeAfter?.text?.startsWith(" ");
65
- const rangeToUse = { ...range };
66
- if (overrideSpace) rangeToUse.to += 1;
65
+ insertRange = {
66
+ from: startPosition,
67
+ to: startPosition
68
+ };
69
+ } else insertRange = {
70
+ from: range.from,
71
+ to: range.to
72
+ };
73
+ if (view.state.selection.$to.nodeAfter?.text?.startsWith(" ")) insertRange.to += 1;
67
74
  props.onSelect({
68
75
  editor,
69
- range: rangeToUse,
76
+ range: insertRange,
70
77
  context: props.context
71
78
  });
72
79
  },
@@ -121,10 +128,11 @@ const SuggestionMenu = ({ editor: providedEditor, floatingOptions, selector = "t
121
128
  closePopup();
122
129
  if (internalCommand) internalCommand(item);
123
130
  }, [closePopup, internalCommand]);
131
+ const renderedItems = liveItems ?? internalItems;
124
132
  const { selectedIndex } = useMenuNavigation({
125
133
  editor,
126
134
  query: internalQuery,
127
- items: internalItems,
135
+ items: renderedItems,
128
136
  onSelect
129
137
  });
130
138
  if (!isMounted || !show || !editor) return null;
@@ -138,7 +146,7 @@ const SuggestionMenu = ({ editor: providedEditor, floatingOptions, selector = "t
138
146
  "aria-label": "Suggestions",
139
147
  onPointerDown: (e) => e.preventDefault(),
140
148
  children: children({
141
- items: internalItems,
149
+ items: renderedItems,
142
150
  selectedIndex,
143
151
  onSelect,
144
152
  query: internalQuery
@@ -1 +1 @@
1
- {"version":3,"file":"suggestion-menu.mjs","names":[],"sources":["../../../../src/components/internal/suggestion-menu/suggestion-menu.tsx"],"sourcesContent":["import { flip, offset, shift, size } from \"@floating-ui/react\";\nimport { PluginKey } from \"@tiptap/pm/state\";\nimport type { Range } from \"@tiptap/react\";\nimport {\n Suggestion,\n type SuggestionKeyDownProps,\n SuggestionPluginKey,\n type SuggestionProps,\n} from \"@tiptap/suggestion\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useFloatingElement } from \"../../../hooks/use-floating-element.js\";\nimport { useMenuNavigation } from \"../../../hooks/use-menu-navigation.js\";\nimport type { SuggestionItem, SuggestionMenuProps } from \"./suggestion-menu-types.js\";\nimport { calculateStartPosition } from \"./suggestion-menu-utils.js\";\n\nexport const SuggestionMenu = ({\n editor: providedEditor,\n floatingOptions,\n selector = \"tiptap-suggestion-menu\",\n children,\n maxHeight = 384,\n pluginKey = SuggestionPluginKey,\n ...internalSuggestionProps\n}: SuggestionMenuProps) => {\n const editor = providedEditor ?? null;\n\n const [show, setShow] = useState<boolean>(false);\n const [internalClientRect, setInternalClientRect] = useState<DOMRect | null>(null);\n const [internalCommand, setInternalCommand] = useState<((item: SuggestionItem) => void) | null>(\n null,\n );\n const [internalItems, setInternalItems] = useState<SuggestionItem[]>([]);\n const [internalQuery, setInternalQuery] = useState<string>(\"\");\n const [, setInternalRange] = useState<Range | null>(null);\n\n const { ref, style, getFloatingProps, isMounted } = useFloatingElement(\n show,\n internalClientRect,\n 1000,\n {\n placement: \"bottom-start\",\n middleware: [\n offset(10),\n flip({ mainAxis: true, crossAxis: false }),\n shift(),\n size({\n apply({ availableHeight, elements }) {\n if (elements.floating) {\n const maxHeightValue = maxHeight\n ? Math.min(maxHeight, availableHeight)\n : availableHeight;\n elements.floating.style.setProperty(\n \"--suggestion-menu-max-height\",\n `${maxHeightValue}px`,\n );\n }\n },\n }),\n ],\n onOpenChange(open) {\n if (!open) setShow(false);\n },\n ...floatingOptions,\n },\n );\n\n const internalSuggestionPropsRef = useRef(internalSuggestionProps);\n\n useEffect(() => {\n internalSuggestionPropsRef.current = internalSuggestionProps;\n }, [internalSuggestionProps]);\n\n const closePopup = useCallback(() => {\n setShow(false);\n }, []);\n\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n\n const existingPlugin = editor.state.plugins.find((plugin) => plugin.spec.key === pluginKey);\n if (existingPlugin) {\n editor.unregisterPlugin(pluginKey);\n }\n\n type ItemsFn = NonNullable<typeof internalSuggestionPropsRef.current.items>;\n type ItemsArgs = Parameters<ItemsFn>[0];\n type ItemsReturn = ReturnType<ItemsFn>;\n\n const suggestion = Suggestion({\n pluginKey: pluginKey instanceof PluginKey ? pluginKey : new PluginKey(pluginKey),\n editor,\n\n command({ editor, range, props }) {\n if (!range) return;\n\n const { view, state } = editor;\n const { selection } = state;\n\n const isMention = editor.extensionManager.extensions.some(\n (extension) =>\n extension.name === \"mention\" &&\n extension.options?.suggestion?.char === internalSuggestionPropsRef.current.char,\n );\n\n if (!isMention) {\n const cursorPosition = selection.$from.pos;\n const previousNode = selection.$head?.nodeBefore;\n\n const startPosition = previousNode\n ? calculateStartPosition(\n cursorPosition,\n previousNode,\n internalSuggestionPropsRef.current.char,\n )\n : selection.$from.start();\n\n const transaction = state.tr.deleteRange(startPosition, cursorPosition);\n view.dispatch(transaction);\n }\n\n const nodeAfter = view.state.selection.$to.nodeAfter;\n const overrideSpace = nodeAfter?.text?.startsWith(\" \");\n const rangeToUse = { ...range };\n if (overrideSpace) rangeToUse.to += 1;\n\n props.onSelect({ editor, range: rangeToUse, context: props.context });\n },\n\n render: () => ({\n onStart: (props: SuggestionProps<SuggestionItem>) => {\n setInternalCommand(() => props.command);\n setInternalItems(props.items);\n setInternalQuery(props.query);\n setInternalRange(props.range);\n setInternalClientRect(props.clientRect?.() ?? null);\n setShow(true);\n },\n onUpdate: (props: SuggestionProps<SuggestionItem>) => {\n setInternalCommand(() => props.command);\n setInternalItems(props.items);\n setInternalQuery(props.query);\n setInternalRange(props.range);\n setInternalClientRect(props.clientRect?.() ?? null);\n },\n onKeyDown: (props: SuggestionKeyDownProps) => {\n if (props.event.key === \"Escape\") {\n closePopup();\n return true;\n }\n return false;\n },\n onExit: () => {\n setInternalCommand(null);\n setInternalItems([]);\n setInternalQuery(\"\");\n setInternalRange(null);\n setInternalClientRect(null);\n setShow(false);\n },\n }),\n ...internalSuggestionPropsRef.current,\n // Override `items` to always read from the live ref. The Suggestion\n // plugin captures its options once at registration, but parents update\n // `items` asynchronously (e.g. when `getSecrets` resolves). Without\n // this delegation, items computed after registration never reach the\n // menu and the user sees an empty list.\n items: ((args: ItemsArgs): ItemsReturn => {\n const fn = internalSuggestionPropsRef.current.items;\n return (fn ? fn(args) : ([] as unknown as ItemsReturn)) as ItemsReturn;\n }) as ItemsFn,\n });\n\n editor.registerPlugin(suggestion);\n\n return () => {\n if (!editor.isDestroyed) {\n editor.unregisterPlugin(pluginKey);\n }\n };\n }, [editor, pluginKey, closePopup]);\n\n const onSelect = useCallback(\n (item: SuggestionItem) => {\n closePopup();\n if (internalCommand) internalCommand(item);\n },\n [closePopup, internalCommand],\n );\n\n const { selectedIndex } = useMenuNavigation({\n editor,\n query: internalQuery,\n items: internalItems,\n onSelect,\n });\n\n if (!isMounted || !show || !editor) return null;\n\n return (\n <div\n ref={ref}\n style={style}\n {...getFloatingProps()}\n data-selector={selector}\n className=\"pz:z-50 pz:overflow-hidden pz:rounded-md pz:border pz:border-input pz:bg-popover pz:text-popover-foreground pz:shadow-md\"\n role=\"listbox\"\n aria-label=\"Suggestions\"\n onPointerDown={(e) => e.preventDefault()}\n >\n {children({ items: internalItems, selectedIndex, onSelect, query: internalQuery })}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AAgBA,MAAa,kBAAkB,EAC7B,QAAQ,gBACR,iBACA,WAAW,0BACX,UACA,YAAY,KACZ,YAAY,qBACZ,GAAG,8BACsB;CACzB,MAAM,SAAS,kBAAkB;CAEjC,MAAM,CAAC,MAAM,WAAW,SAAkB,MAAM;CAChD,MAAM,CAAC,oBAAoB,yBAAyB,SAAyB,KAAK;CAClF,MAAM,CAAC,iBAAiB,sBAAsB,SAC5C,KACD;CACD,MAAM,CAAC,eAAe,oBAAoB,SAA2B,EAAE,CAAC;CACxE,MAAM,CAAC,eAAe,oBAAoB,SAAiB,GAAG;CAC9D,MAAM,GAAG,oBAAoB,SAAuB,KAAK;CAEzD,MAAM,EAAE,KAAK,OAAO,kBAAkB,cAAc,mBAClD,MACA,oBACA,KACA;EACE,WAAW;EACX,YAAY;GACV,OAAO,GAAG;GACV,KAAK;IAAE,UAAU;IAAM,WAAW;IAAO,CAAC;GAC1C,OAAO;GACP,KAAK,EACH,MAAM,EAAE,iBAAiB,YAAY;AACnC,QAAI,SAAS,UAAU;KACrB,MAAM,iBAAiB,YACnB,KAAK,IAAI,WAAW,gBAAgB,GACpC;AACJ,cAAS,SAAS,MAAM,YACtB,gCACA,GAAG,eAAe,IACnB;;MAGN,CAAC;GACH;EACD,aAAa,MAAM;AACjB,OAAI,CAAC,KAAM,SAAQ,MAAM;;EAE3B,GAAG;EACJ,CACF;CAED,MAAM,6BAA6B,OAAO,wBAAwB;AAElE,iBAAgB;AACd,6BAA2B,UAAU;IACpC,CAAC,wBAAwB,CAAC;CAE7B,MAAM,aAAa,kBAAkB;AACnC,UAAQ,MAAM;IACb,EAAE,CAAC;AAEN,iBAAgB;AACd,MAAI,CAAC,UAAU,OAAO,YAAa;AAGnC,MADuB,OAAO,MAAM,QAAQ,MAAM,WAAW,OAAO,KAAK,QAAQ,UAAU,CAEzF,QAAO,iBAAiB,UAAU;EAOpC,MAAM,aAAa,WAAW;GAC5B,WAAW,qBAAqB,YAAY,YAAY,IAAI,UAAU,UAAU;GAChF;GAEA,QAAQ,EAAE,QAAQ,OAAO,SAAS;AAChC,QAAI,CAAC,MAAO;IAEZ,MAAM,EAAE,MAAM,UAAU;IACxB,MAAM,EAAE,cAAc;AAQtB,QAAI,CANc,OAAO,iBAAiB,WAAW,MAClD,cACC,UAAU,SAAS,aACnB,UAAU,SAAS,YAAY,SAAS,2BAA2B,QAAQ,KAC9E,EAEe;KACd,MAAM,iBAAiB,UAAU,MAAM;KACvC,MAAM,eAAe,UAAU,OAAO;KAEtC,MAAM,gBAAgB,eAClB,uBACE,gBACA,cACA,2BAA2B,QAAQ,KACpC,GACD,UAAU,MAAM,OAAO;KAE3B,MAAM,cAAc,MAAM,GAAG,YAAY,eAAe,eAAe;AACvE,UAAK,SAAS,YAAY;;IAI5B,MAAM,gBADY,KAAK,MAAM,UAAU,IAAI,WACV,MAAM,WAAW,IAAI;IACtD,MAAM,aAAa,EAAE,GAAG,OAAO;AAC/B,QAAI,cAAe,YAAW,MAAM;AAEpC,UAAM,SAAS;KAAE;KAAQ,OAAO;KAAY,SAAS,MAAM;KAAS,CAAC;;GAGvE,eAAe;IACb,UAAU,UAA2C;AACnD,8BAAyB,MAAM,QAAQ;AACvC,sBAAiB,MAAM,MAAM;AAC7B,sBAAiB,MAAM,MAAM;AAC7B,sBAAiB,MAAM,MAAM;AAC7B,2BAAsB,MAAM,cAAc,IAAI,KAAK;AACnD,aAAQ,KAAK;;IAEf,WAAW,UAA2C;AACpD,8BAAyB,MAAM,QAAQ;AACvC,sBAAiB,MAAM,MAAM;AAC7B,sBAAiB,MAAM,MAAM;AAC7B,sBAAiB,MAAM,MAAM;AAC7B,2BAAsB,MAAM,cAAc,IAAI,KAAK;;IAErD,YAAY,UAAkC;AAC5C,SAAI,MAAM,MAAM,QAAQ,UAAU;AAChC,kBAAY;AACZ,aAAO;;AAET,YAAO;;IAET,cAAc;AACZ,wBAAmB,KAAK;AACxB,sBAAiB,EAAE,CAAC;AACpB,sBAAiB,GAAG;AACpB,sBAAiB,KAAK;AACtB,2BAAsB,KAAK;AAC3B,aAAQ,MAAM;;IAEjB;GACD,GAAG,2BAA2B;GAM9B,SAAS,SAAiC;IACxC,MAAM,KAAK,2BAA2B,QAAQ;AAC9C,WAAQ,KAAK,GAAG,KAAK,GAAI,EAAE;;GAE9B,CAAC;AAEF,SAAO,eAAe,WAAW;AAEjC,eAAa;AACX,OAAI,CAAC,OAAO,YACV,QAAO,iBAAiB,UAAU;;IAGrC;EAAC;EAAQ;EAAW;EAAW,CAAC;CAEnC,MAAM,WAAW,aACd,SAAyB;AACxB,cAAY;AACZ,MAAI,gBAAiB,iBAAgB,KAAK;IAE5C,CAAC,YAAY,gBAAgB,CAC9B;CAED,MAAM,EAAE,kBAAkB,kBAAkB;EAC1C;EACA,OAAO;EACP,OAAO;EACP;EACD,CAAC;AAEF,KAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAQ,QAAO;AAE3C,QACE,oBAAC,OAAD;EACO;EACE;EACP,GAAI,kBAAkB;EACtB,iBAAe;EACf,WAAU;EACV,MAAK;EACL,cAAW;EACX,gBAAgB,MAAM,EAAE,gBAAgB;YAEvC,SAAS;GAAE,OAAO;GAAe;GAAe;GAAU,OAAO;GAAe,CAAC;EAC9E"}
1
+ {"version":3,"file":"suggestion-menu.mjs","names":[],"sources":["../../../../src/components/internal/suggestion-menu/suggestion-menu.tsx"],"sourcesContent":["import { flip, offset, shift, size } from \"@floating-ui/react\";\nimport { PluginKey } from \"@tiptap/pm/state\";\nimport type { Range } from \"@tiptap/react\";\nimport {\n Suggestion,\n type SuggestionKeyDownProps,\n SuggestionPluginKey,\n type SuggestionProps,\n} from \"@tiptap/suggestion\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useFloatingElement } from \"../../../hooks/use-floating-element.js\";\nimport { useMenuNavigation } from \"../../../hooks/use-menu-navigation.js\";\nimport type { SuggestionItem, SuggestionMenuProps } from \"./suggestion-menu-types.js\";\nimport { calculateStartPosition } from \"./suggestion-menu-utils.js\";\n\nexport const SuggestionMenu = ({\n editor: providedEditor,\n floatingOptions,\n selector = \"tiptap-suggestion-menu\",\n children,\n maxHeight = 384,\n pluginKey = SuggestionPluginKey,\n liveItems,\n ...internalSuggestionProps\n}: SuggestionMenuProps) => {\n const editor = providedEditor ?? null;\n\n const [show, setShow] = useState<boolean>(false);\n const [internalClientRect, setInternalClientRect] = useState<DOMRect | null>(null);\n const [internalCommand, setInternalCommand] = useState<((item: SuggestionItem) => void) | null>(\n null,\n );\n const [internalItems, setInternalItems] = useState<SuggestionItem[]>([]);\n const [internalQuery, setInternalQuery] = useState<string>(\"\");\n const [, setInternalRange] = useState<Range | null>(null);\n\n const { ref, style, getFloatingProps, isMounted } = useFloatingElement(\n show,\n internalClientRect,\n 1000,\n {\n placement: \"bottom-start\",\n middleware: [\n offset(10),\n flip({ mainAxis: true, crossAxis: false }),\n shift(),\n size({\n apply({ availableHeight, elements }) {\n if (elements.floating) {\n const maxHeightValue = maxHeight\n ? Math.min(maxHeight, availableHeight)\n : availableHeight;\n elements.floating.style.setProperty(\n \"--suggestion-menu-max-height\",\n `${maxHeightValue}px`,\n );\n }\n },\n }),\n ],\n onOpenChange(open) {\n if (!open) setShow(false);\n },\n ...floatingOptions,\n },\n );\n\n const internalSuggestionPropsRef = useRef(internalSuggestionProps);\n\n useEffect(() => {\n internalSuggestionPropsRef.current = internalSuggestionProps;\n }, [internalSuggestionProps]);\n\n const closePopup = useCallback(() => {\n setShow(false);\n }, []);\n\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n\n const existingPlugin = editor.state.plugins.find((plugin) => plugin.spec.key === pluginKey);\n if (existingPlugin) {\n editor.unregisterPlugin(pluginKey);\n }\n\n type ItemsFn = NonNullable<typeof internalSuggestionPropsRef.current.items>;\n type ItemsArgs = Parameters<ItemsFn>[0];\n type ItemsReturn = ReturnType<ItemsFn>;\n\n const suggestion = Suggestion({\n pluginKey: pluginKey instanceof PluginKey ? pluginKey : new PluginKey(pluginKey),\n editor,\n\n command({ editor, range, props }) {\n if (!range) return;\n\n const { view, state } = editor;\n const { selection } = state;\n\n const isMention = editor.extensionManager.extensions.some(\n (extension) =>\n extension.name === \"mention\" &&\n extension.options?.suggestion?.char === internalSuggestionPropsRef.current.char,\n );\n\n // Track the position where the inserted content should land. For the\n // non-mention path we delete the typed query first; after that, the\n // suggestion's original `range` is stale (its `to` may now point past\n // the doc end), so we collapse to the deletion start. For mentions\n // the typed text is preserved and we keep the original range.\n let insertRange: { from: number; to: number };\n\n if (!isMention) {\n const cursorPosition = selection.$from.pos;\n const previousNode = selection.$head?.nodeBefore;\n\n const startPosition = previousNode\n ? calculateStartPosition(\n cursorPosition,\n previousNode,\n internalSuggestionPropsRef.current.char,\n )\n : selection.$from.start();\n\n const transaction = state.tr.deleteRange(startPosition, cursorPosition);\n view.dispatch(transaction);\n\n insertRange = { from: startPosition, to: startPosition };\n } else {\n insertRange = { from: range.from, to: range.to };\n }\n\n const nodeAfter = view.state.selection.$to.nodeAfter;\n const overrideSpace = nodeAfter?.text?.startsWith(\" \");\n if (overrideSpace) insertRange.to += 1;\n\n props.onSelect({ editor, range: insertRange, context: props.context });\n },\n\n render: () => ({\n onStart: (props: SuggestionProps<SuggestionItem>) => {\n setInternalCommand(() => props.command);\n setInternalItems(props.items);\n setInternalQuery(props.query);\n setInternalRange(props.range);\n setInternalClientRect(props.clientRect?.() ?? null);\n setShow(true);\n },\n onUpdate: (props: SuggestionProps<SuggestionItem>) => {\n setInternalCommand(() => props.command);\n setInternalItems(props.items);\n setInternalQuery(props.query);\n setInternalRange(props.range);\n setInternalClientRect(props.clientRect?.() ?? null);\n },\n onKeyDown: (props: SuggestionKeyDownProps) => {\n if (props.event.key === \"Escape\") {\n closePopup();\n return true;\n }\n return false;\n },\n onExit: () => {\n setInternalCommand(null);\n setInternalItems([]);\n setInternalQuery(\"\");\n setInternalRange(null);\n setInternalClientRect(null);\n setShow(false);\n },\n }),\n ...internalSuggestionPropsRef.current,\n // Override `items` to always read from the live ref. The Suggestion\n // plugin captures its options once at registration, but parents update\n // `items` asynchronously (e.g. when `getSecrets` resolves). Without\n // this delegation, items computed after registration never reach the\n // menu and the user sees an empty list.\n items: ((args: ItemsArgs): ItemsReturn => {\n const fn = internalSuggestionPropsRef.current.items;\n return (fn ? fn(args) : ([] as unknown as ItemsReturn)) as ItemsReturn;\n }) as ItemsFn,\n });\n\n editor.registerPlugin(suggestion);\n\n return () => {\n if (!editor.isDestroyed) {\n editor.unregisterPlugin(pluginKey);\n }\n };\n }, [editor, pluginKey, closePopup]);\n\n const onSelect = useCallback(\n (item: SuggestionItem) => {\n closePopup();\n if (internalCommand) internalCommand(item);\n },\n [closePopup, internalCommand],\n );\n\n // `liveItems` (when provided) takes precedence over `internalItems` for\n // both rendering and keyboard navigation. This lets parents push fresh\n // items into the open popup as async sources resolve — without waiting on\n // the Tiptap suggestion plugin to re-call items() (it only does so on\n // query change).\n const renderedItems = liveItems ?? internalItems;\n\n const { selectedIndex } = useMenuNavigation({\n editor,\n query: internalQuery,\n items: renderedItems,\n onSelect,\n });\n\n if (!isMounted || !show || !editor) return null;\n\n return (\n <div\n ref={ref}\n style={style}\n {...getFloatingProps()}\n data-selector={selector}\n className=\"pz:z-50 pz:overflow-hidden pz:rounded-md pz:border pz:border-input pz:bg-popover pz:text-popover-foreground pz:shadow-md\"\n role=\"listbox\"\n aria-label=\"Suggestions\"\n onPointerDown={(e) => e.preventDefault()}\n >\n {children({ items: renderedItems, selectedIndex, onSelect, query: internalQuery })}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -5,8 +5,8 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
5
5
 
6
6
  //#region src/components/ui/button.d.ts
7
7
  declare const buttonVariants: (props?: ({
8
- variant?: "default" | "link" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
9
- size?: "default" | "sm" | "lg" | "icon" | "xs" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
8
+ variant?: "link" | "default" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
9
+ size?: "default" | "icon" | "sm" | "lg" | "xs" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
10
10
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
11
11
  declare function Button$1({
12
12
  className,
@@ -0,0 +1,93 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+
3
+ //#region src/hooks/use-async-remote-source.ts
4
+ /**
5
+ * Async remote source with cache, debounce, and race-guarded resolves.
6
+ * Used by `LiquidEditor` for secrets and constants — both follow the same
7
+ * "fetch-as-you-type, render last good batch while pending" pattern.
8
+ *
9
+ * Decoupling note: callers should NOT await this. The hook updates React
10
+ * state via `setState` and re-renders consumers when results arrive. Pickers
11
+ * built on top of this read `items` synchronously and rely on the React
12
+ * render to deliver fresh results.
13
+ */
14
+ function useAsyncRemoteSource({ search, debounceMs = 120, cacheSize = 32 }) {
15
+ const [items, setItems] = useState([]);
16
+ const [pending, setPending] = useState(false);
17
+ const cacheRef = useRef(/* @__PURE__ */ new Map());
18
+ const latestQueryRef = useRef("");
19
+ const debounceTimerRef = useRef(null);
20
+ const searchRef = useRef(search);
21
+ useEffect(() => {
22
+ searchRef.current = search;
23
+ }, [search]);
24
+ useEffect(() => {
25
+ cacheRef.current = /* @__PURE__ */ new Map();
26
+ setItems([]);
27
+ setPending(false);
28
+ latestQueryRef.current = "";
29
+ if (debounceTimerRef.current) {
30
+ clearTimeout(debounceTimerRef.current);
31
+ debounceTimerRef.current = null;
32
+ }
33
+ }, [search]);
34
+ useEffect(() => {
35
+ return () => {
36
+ if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
37
+ };
38
+ }, []);
39
+ const commit = useCallback((query, results) => {
40
+ const cache = cacheRef.current;
41
+ cache.set(query, results);
42
+ if (cache.size > cacheSize) {
43
+ const firstKey = cache.keys().next().value;
44
+ if (firstKey !== void 0) cache.delete(firstKey);
45
+ }
46
+ if (latestQueryRef.current === query) {
47
+ setItems(results);
48
+ setPending(false);
49
+ }
50
+ }, [cacheSize]);
51
+ const ensure = useCallback((query) => {
52
+ latestQueryRef.current = query;
53
+ const fn = searchRef.current;
54
+ if (!fn) return;
55
+ const cached = cacheRef.current.get(query);
56
+ if (cached) {
57
+ setItems(cached);
58
+ setPending(false);
59
+ return;
60
+ }
61
+ setPending(true);
62
+ if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
63
+ debounceTimerRef.current = setTimeout(async () => {
64
+ debounceTimerRef.current = null;
65
+ if (latestQueryRef.current !== query) return;
66
+ try {
67
+ commit(query, await fn(query));
68
+ } catch {
69
+ if (latestQueryRef.current === query) setPending(false);
70
+ }
71
+ }, debounceMs);
72
+ }, [commit, debounceMs]);
73
+ const prefetch = useCallback(() => {
74
+ if (!searchRef.current) return;
75
+ if (cacheRef.current.has("")) return;
76
+ ensure("");
77
+ }, [ensure]);
78
+ return useMemo(() => ({
79
+ items,
80
+ pending,
81
+ ensure,
82
+ prefetch
83
+ }), [
84
+ items,
85
+ pending,
86
+ ensure,
87
+ prefetch
88
+ ]);
89
+ }
90
+
91
+ //#endregion
92
+ export { useAsyncRemoteSource };
93
+ //# sourceMappingURL=use-async-remote-source.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-async-remote-source.mjs","names":[],"sources":["../../src/hooks/use-async-remote-source.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\ninterface UseAsyncRemoteSourceOptions<T> {\n search: ((query: string) => Promise<T[]>) | undefined;\n debounceMs?: number;\n cacheSize?: number;\n}\n\nexport interface AsyncRemoteSource<T> {\n /** Items for the current query — last successfully fetched batch (may be stale during pending). */\n items: T[];\n /** True while the in-flight query for the current input doesn't yet have a cached result. */\n pending: boolean;\n /** Imperative ensure-fetched call. Safe to invoke on every keystroke. */\n ensure: (query: string) => void;\n /** Warm the cache for the empty query. Call once on mount. */\n prefetch: () => void;\n}\n\n/**\n * Async remote source with cache, debounce, and race-guarded resolves.\n * Used by `LiquidEditor` for secrets and constants — both follow the same\n * \"fetch-as-you-type, render last good batch while pending\" pattern.\n *\n * Decoupling note: callers should NOT await this. The hook updates React\n * state via `setState` and re-renders consumers when results arrive. Pickers\n * built on top of this read `items` synchronously and rely on the React\n * render to deliver fresh results.\n */\nexport function useAsyncRemoteSource<T>({\n search,\n debounceMs = 120,\n cacheSize = 32,\n}: UseAsyncRemoteSourceOptions<T>): AsyncRemoteSource<T> {\n const [items, setItems] = useState<T[]>([]);\n const [pending, setPending] = useState(false);\n\n const cacheRef = useRef<Map<string, T[]>>(new Map());\n const latestQueryRef = useRef<string>(\"\");\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const searchRef = useRef(search);\n\n useEffect(() => {\n searchRef.current = search;\n }, [search]);\n\n // Reset cache when the resolver identity changes — different resolver\n // implies different data source, so cached entries are no longer valid.\n useEffect(() => {\n cacheRef.current = new Map();\n setItems([]);\n setPending(false);\n latestQueryRef.current = \"\";\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = null;\n }\n }, [search]);\n\n useEffect(() => {\n return () => {\n if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);\n };\n }, []);\n\n const commit = useCallback(\n (query: string, results: T[]) => {\n const cache = cacheRef.current;\n cache.set(query, results);\n if (cache.size > cacheSize) {\n const firstKey = cache.keys().next().value;\n if (firstKey !== undefined) cache.delete(firstKey);\n }\n if (latestQueryRef.current === query) {\n setItems(results);\n setPending(false);\n }\n },\n [cacheSize],\n );\n\n const ensure = useCallback(\n (query: string) => {\n latestQueryRef.current = query;\n const fn = searchRef.current;\n if (!fn) return;\n\n const cached = cacheRef.current.get(query);\n if (cached) {\n setItems(cached);\n setPending(false);\n return;\n }\n\n setPending(true);\n\n if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = setTimeout(async () => {\n debounceTimerRef.current = null;\n if (latestQueryRef.current !== query) return;\n try {\n const results = await fn(query);\n commit(query, results);\n } catch {\n if (latestQueryRef.current === query) setPending(false);\n }\n }, debounceMs);\n },\n [commit, debounceMs],\n );\n\n const prefetch = useCallback(() => {\n if (!searchRef.current) return;\n if (cacheRef.current.has(\"\")) return;\n ensure(\"\");\n }, [ensure]);\n\n return useMemo(() => ({ items, pending, ensure, prefetch }), [items, pending, ensure, prefetch]);\n}\n"],"mappings":";;;;;;;;;;;;;AA6BA,SAAgB,qBAAwB,EACtC,QACA,aAAa,KACb,YAAY,MAC2C;CACvD,MAAM,CAAC,OAAO,YAAY,SAAc,EAAE,CAAC;CAC3C,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;CAE7C,MAAM,WAAW,uBAAyB,IAAI,KAAK,CAAC;CACpD,MAAM,iBAAiB,OAAe,GAAG;CACzC,MAAM,mBAAmB,OAA6C,KAAK;CAC3E,MAAM,YAAY,OAAO,OAAO;AAEhC,iBAAgB;AACd,YAAU,UAAU;IACnB,CAAC,OAAO,CAAC;AAIZ,iBAAgB;AACd,WAAS,0BAAU,IAAI,KAAK;AAC5B,WAAS,EAAE,CAAC;AACZ,aAAW,MAAM;AACjB,iBAAe,UAAU;AACzB,MAAI,iBAAiB,SAAS;AAC5B,gBAAa,iBAAiB,QAAQ;AACtC,oBAAiB,UAAU;;IAE5B,CAAC,OAAO,CAAC;AAEZ,iBAAgB;AACd,eAAa;AACX,OAAI,iBAAiB,QAAS,cAAa,iBAAiB,QAAQ;;IAErE,EAAE,CAAC;CAEN,MAAM,SAAS,aACZ,OAAe,YAAiB;EAC/B,MAAM,QAAQ,SAAS;AACvB,QAAM,IAAI,OAAO,QAAQ;AACzB,MAAI,MAAM,OAAO,WAAW;GAC1B,MAAM,WAAW,MAAM,MAAM,CAAC,MAAM,CAAC;AACrC,OAAI,aAAa,OAAW,OAAM,OAAO,SAAS;;AAEpD,MAAI,eAAe,YAAY,OAAO;AACpC,YAAS,QAAQ;AACjB,cAAW,MAAM;;IAGrB,CAAC,UAAU,CACZ;CAED,MAAM,SAAS,aACZ,UAAkB;AACjB,iBAAe,UAAU;EACzB,MAAM,KAAK,UAAU;AACrB,MAAI,CAAC,GAAI;EAET,MAAM,SAAS,SAAS,QAAQ,IAAI,MAAM;AAC1C,MAAI,QAAQ;AACV,YAAS,OAAO;AAChB,cAAW,MAAM;AACjB;;AAGF,aAAW,KAAK;AAEhB,MAAI,iBAAiB,QAAS,cAAa,iBAAiB,QAAQ;AACpE,mBAAiB,UAAU,WAAW,YAAY;AAChD,oBAAiB,UAAU;AAC3B,OAAI,eAAe,YAAY,MAAO;AACtC,OAAI;AAEF,WAAO,OADS,MAAM,GAAG,MAAM,CACT;WAChB;AACN,QAAI,eAAe,YAAY,MAAO,YAAW,MAAM;;KAExD,WAAW;IAEhB,CAAC,QAAQ,WAAW,CACrB;CAED,MAAM,WAAW,kBAAkB;AACjC,MAAI,CAAC,UAAU,QAAS;AACxB,MAAI,SAAS,QAAQ,IAAI,GAAG,CAAE;AAC9B,SAAO,GAAG;IACT,CAAC,OAAO,CAAC;AAEZ,QAAO,eAAe;EAAE;EAAO;EAAS;EAAQ;EAAU,GAAG;EAAC;EAAO;EAAS;EAAQ;EAAS,CAAC"}
@@ -32,14 +32,14 @@ declare function usePipeCatalogTable(config?: {
32
32
  removeColumnFilter: (id: "inputFields" | "outputFields" | "tags" | "providers") => void;
33
33
  resetFilters: () => void;
34
34
  getColumnFilterValue: (id: "inputFields" | "outputFields" | "tags" | "providers") => string;
35
- sortedInputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "people:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "people:identity:amplemarket@1" | "company:identity@2" | "people:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "people:profileurl:name@1" | "people:email:validate:zerobounce@1" | "people:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "people:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
36
- sortedOutputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "people:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "people:identity:amplemarket@1" | "company:identity@2" | "people:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "people:profileurl:name@1" | "people:email:validate:zerobounce@1" | "people:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "people:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
37
- sortedTagEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "people:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "people:identity:amplemarket@1" | "company:identity@2" | "people:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "people:profileurl:name@1" | "people:email:validate:zerobounce@1" | "people:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "people:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
38
- sortedProviderEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "people:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "people:identity:amplemarket@1" | "company:identity@2" | "people:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "people:profileurl:name@1" | "people:email:validate:zerobounce@1" | "people:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "people:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
39
- pipeIdsByInputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "people:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "people:identity:amplemarket@1" | "company:identity@2" | "people:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "people:profileurl:name@1" | "people:email:validate:zerobounce@1" | "people:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "people:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
40
- pipeIdsByOutputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "people:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "people:identity:amplemarket@1" | "company:identity@2" | "people:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "people:profileurl:name@1" | "people:email:validate:zerobounce@1" | "people:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "people:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
41
- pipeIdsByProvider: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "people:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "people:identity:amplemarket@1" | "company:identity@2" | "people:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "people:profileurl:name@1" | "people:email:validate:zerobounce@1" | "people:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "people:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
42
- pipeIdsByTag: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "people:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "people:identity:amplemarket@1" | "company:identity@2" | "people:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "people:profileurl:name@1" | "people:email:validate:zerobounce@1" | "people:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "people:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
35
+ sortedInputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
36
+ sortedOutputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
37
+ sortedTagEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
38
+ sortedProviderEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
39
+ pipeIdsByInputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
40
+ pipeIdsByOutputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
41
+ pipeIdsByProvider: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
42
+ pipeIdsByTag: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:techstack:builtwith@1" | "company:websiteurl:email@1" | "company:funding:leadmagic@1" | "people:workemail:waterfall@1" | "people:email:iswork@1" | "people:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "json:extract@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "people:personalemail:profile:waterfall@1" | "people:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:match:logodev@1" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "people:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
43
43
  };
44
44
  type UsePipeCatalogTableReturn = ReturnType<typeof usePipeCatalogTable>;
45
45
  //#endregion
@@ -44,8 +44,6 @@
44
44
  --pz-text-sm--line-height: calc(1.25 / 0.875);
45
45
  --pz-text-base: 1rem;
46
46
  --pz-text-base--line-height: calc(1.5 / 1);
47
- --pz-text-lg: 1.125rem;
48
- --pz-text-lg--line-height: calc(1.75 / 1.125);
49
47
  --pz-font-weight-thin: 100;
50
48
  --pz-font-weight-normal: 400;
51
49
  --pz-font-weight-medium: 500;
@@ -290,9 +288,6 @@
290
288
  .pz\:h-12 {
291
289
  height: calc(var(--pz-spacing) * 12);
292
290
  }
293
- .pz\:h-60 {
294
- height: calc(var(--pz-spacing) * 60);
295
- }
296
291
  .pz\:h-\[200px\] {
297
292
  height: 200px;
298
293
  }
@@ -576,13 +571,6 @@
576
571
  .pz\:gap-\[2px\] {
577
572
  gap: 2px;
578
573
  }
579
- .pz\:-space-x-1\.5 {
580
- :where(& > :not(:last-child)) {
581
- --tw-space-x-reverse: 0;
582
- margin-inline-start: calc(calc(var(--pz-spacing) * -1.5) * var(--tw-space-x-reverse));
583
- margin-inline-end: calc(calc(var(--pz-spacing) * -1.5) * calc(1 - var(--tw-space-x-reverse)));
584
- }
585
- }
586
574
  .pz\:gap-y-1 {
587
575
  row-gap: calc(var(--pz-spacing) * 1);
588
576
  }
@@ -864,9 +852,6 @@
864
852
  .pz\:fill-foreground {
865
853
  fill: var(--p0-foreground);
866
854
  }
867
- .pz\:stroke-1 {
868
- stroke-width: 1;
869
- }
870
855
  .pz\:object-contain {
871
856
  object-fit: contain;
872
857
  }
@@ -1019,10 +1004,6 @@
1019
1004
  font-size: var(--pz-text-base);
1020
1005
  line-height: var(--tw-leading, var(--pz-text-base--line-height));
1021
1006
  }
1022
- .pz\:text-lg {
1023
- font-size: var(--pz-text-lg);
1024
- line-height: var(--tw-leading, var(--pz-text-lg--line-height));
1025
- }
1026
1007
  .pz\:text-sm {
1027
1008
  font-size: var(--pz-text-sm);
1028
1009
  line-height: var(--tw-leading, var(--pz-text-sm--line-height));
@@ -1093,9 +1074,6 @@
1093
1074
  .pz\:break-words {
1094
1075
  overflow-wrap: break-word;
1095
1076
  }
1096
- .pz\:break-all {
1097
- word-break: break-all;
1098
- }
1099
1077
  .pz\:whitespace-nowrap {
1100
1078
  white-space: nowrap;
1101
1079
  }
@@ -1499,16 +1477,6 @@
1499
1477
  }
1500
1478
  }
1501
1479
  }
1502
- .pz\:hover\:border-primary\/50 {
1503
- &:hover {
1504
- @media (hover: hover) {
1505
- border-color: var(--p0-primary);
1506
- @supports (color: color-mix(in lab, red, red)) {
1507
- border-color: color-mix(in oklab, var(--p0-primary) 50%, transparent);
1508
- }
1509
- }
1510
- }
1511
- }
1512
1480
  .pz\:hover\:bg-accent {
1513
1481
  &:hover {
1514
1482
  @media (hover: hover) {
@@ -2437,16 +2405,6 @@
2437
2405
  }
2438
2406
  }
2439
2407
  }
2440
- .pz\:data-\[state\=active\]\:bg-accent {
2441
- &[data-state="active"] {
2442
- background-color: var(--p0-accent);
2443
- }
2444
- }
2445
- .pz\:data-\[state\=active\]\:text-accent-foreground {
2446
- &[data-state="active"] {
2447
- color: var(--p0-accent-foreground);
2448
- }
2449
- }
2450
2408
  .pz\:data-\[state\=delayed-open\]\:animate-in {
2451
2409
  &[data-state="delayed-open"] {
2452
2410
  animation: enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);
@@ -3558,11 +3516,6 @@
3558
3516
  inherits: false;
3559
3517
  initial-value: 0;
3560
3518
  }
3561
- @property --tw-space-x-reverse {
3562
- syntax: "*";
3563
- inherits: false;
3564
- initial-value: 0;
3565
- }
3566
3519
  @property --tw-border-style {
3567
3520
  syntax: "*";
3568
3521
  inherits: false;
@@ -3732,7 +3685,6 @@
3732
3685
  --tw-translate-x: 0;
3733
3686
  --tw-translate-y: 0;
3734
3687
  --tw-translate-z: 0;
3735
- --tw-space-x-reverse: 0;
3736
3688
  --tw-border-style: solid;
3737
3689
  --tw-leading: initial;
3738
3690
  --tw-font-weight: initial;
@@ -219,6 +219,11 @@ interface FieldExtras {
219
219
  * Absent when no `getSecrets` resolver is wired.
220
220
  */
221
221
  searchSecrets?: (query: string) => Promise<SecretSuggestion[]>;
222
+ /**
223
+ * Per-keystroke constants searcher for the per-cell reference picker.
224
+ * Absent when no `getConstants` resolver is wired.
225
+ */
226
+ searchConstants?: (query: string) => Promise<ConstantSuggestion[]>;
222
227
  };
223
228
  providers_input: {
224
229
  options: Array<{
@@ -231,17 +236,19 @@ interface FieldExtras {
231
236
  /**
232
237
  * Prompt template editor. Calls `searchSecrets(query)` per keystroke so
233
238
  * the unified reference picker (`/`) can list secrets alongside input
234
- * fields.
239
+ * fields. Same async pattern for `searchConstants`.
235
240
  */
236
241
  prompt_input: {
237
242
  searchSecrets?: (query: string) => Promise<SecretSuggestion[]>;
243
+ searchConstants?: (query: string) => Promise<ConstantSuggestion[]>;
238
244
  };
239
245
  /**
240
- * Liquid template editor. Same per-keystroke secret search as
246
+ * Liquid template editor. Same per-keystroke secret/constant search as
241
247
  * `prompt_input`.
242
248
  */
243
249
  template_input: {
244
250
  searchSecrets?: (query: string) => Promise<SecretSuggestion[]>;
251
+ searchConstants?: (query: string) => Promise<ConstantSuggestion[]>;
245
252
  };
246
253
  /**
247
254
  * Hybrid tagged-text input. The editor accepts `/` to open a unified
@@ -269,6 +276,11 @@ interface FieldExtras {
269
276
  * Absent when no `getSecrets` resolver is wired.
270
277
  */
271
278
  searchSecrets?: (query: string) => Promise<SecretSuggestion[]>;
279
+ /**
280
+ * Per-keystroke constants searcher for the unified reference picker.
281
+ * Absent when no `getConstants` resolver is wired.
282
+ */
283
+ searchConstants?: (query: string) => Promise<ConstantSuggestion[]>;
272
284
  };
273
285
  json_extraction_input: {};
274
286
  pipes_trigger_input: {};
@@ -277,6 +289,18 @@ interface FieldExtras {
277
289
  json_schema_input: {};
278
290
  cursor_pagination_metadata: {};
279
291
  }
292
+ /**
293
+ * Forward-compat type for non-secret org-level constants. Mirrors
294
+ * `SecretSuggestion` but without the masking concern. No runtime surface
295
+ * exposes these yet — `LiquidEditor` accepts an empty array and the
296
+ * unified `/` picker treats Constants as a third section once data lands.
297
+ */
298
+ interface ConstantSuggestion {
299
+ publicId: string;
300
+ label: string;
301
+ ownershipLevel: "organization" | "team" | "user";
302
+ description: string | null;
303
+ }
280
304
  type GeneratedFieldProps<K extends GeneratedFormInputType> = BaseFieldProps<K> & FieldExtras[K];
281
305
  /** Union of all possible field props — used when the kind is not yet known. */
282
306
  type AnyFieldProps = { [K in GeneratedFormInputType]: GeneratedFieldProps<K> }[GeneratedFormInputType];
@@ -1 +1 @@
1
- {"version":3,"file":"field-props.d.mts","names":[],"sources":["../../src/types/field-props.ts"],"mappings":";;;;;;;AA0BA;;;;;;;;;;;;;KAAY,SAAA,WAAoB,sBAAA,IAA0B,qBAAA,CAAsB,CAAA;AAAA,UAM/D,cAAA,WAAyB,sBAAA;EACxC,IAAA,EAAM,CAAA;EACN,IAAA,EAAM,qBAAA,CAAsB,CAAA;EAC5B,IAAA,EAAM,aAAA,CAAc,WAAA;EACpB,IAAA;EACA,EAAA;EAH4B;;;;EAQ5B,KAAA;EAec;;;;EAVd,WAAA;EAfwC;;;;EAoBxC,IAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA;EACA,KAAA,EAAO,aAAA,CAAc,CAAA;EACrB,QAAA,GAAW,CAAA,EAAG,aAAA,CAAc,CAAA;EAC5B,KAAA;EAhBA;EAkBA,QAAA;EARA;EAUA,cAAA;AAAA;AAAA,UAOQ,oBAAA;EACR,OAAA;IACE,KAAA;IACA,GAAA,GAAM,CAAA;IACN,MAAA,GAAS,CAAA;EAAA;EAEX,OAAA;IACE,KAAA;IACA,GAAA,GAAM,CAAA;IACN,MAAA,GAAS,CAAA;EAAA;EAhBG;EAmBd,OAAA,GAAU,KAAA;IACR,KAAA;IACA,KAAA;IACA,OAAA,GAf0B,cAAA,CAeM,aAAA;EAAA;EAHxB;EAMV,WAAA,IAAe,KAAA,aAAkB,OAAA,CAC/B,KAAA;IACE,KAAA;IACA,KAAA;IACA,OAAA,GAVW,cAAA,CAUqB,aAAA;EAAA;AAAA;AAAA,UAK5B,UAAA;EACR,KAAA;EACA,GAAA,GAAM,CAAA;EACN,MAAA,GAAS,CAAA;EA1BE;EA4BX,OAAA,GAAU,KAAA;IACR,KAAA;IACA,KAAA;IACA,OAAA,GARgB,cAAA,CAQgB,aAAA;EAAA;EA1BvB;EA6BX,WAAA,IAAe,KAAA,aAAkB,OAAA,CAC/B,KAAA;IACE,KAAA;IACA,KAAA;IACA,OAAA,GAVW,cAAA,CAUqB,aAAA;EAAA;AAAA;AAAA,UAK5B,cAAA;EACR,IAAA;IAAQ,KAAA,EAAO,CAAA;IAAG,GAAA,GAAM,CAAA,EAAG,CAAA;EAAA;EAC3B,EAAA;IAAM,KAAA,EAAO,CAAA;IAAG,GAAA,GAAM,CAAA,EAAG,CAAA;EAAA;AAAA;AAAA,UAGjB,mBAAA;EACR,WAAA;IACE,QAAA;IACA,KAAA;IACA,WAAA,GAAc,EAAA;IACd,QAAA,GAAW,CAAA;EAAA;EAEb,QAAA;IACE,QAAA;IACA,KAAA;IACA,WAAA,GAAc,EAAA;IACd,QAAA,GAAW,CAAA;EAAA;AAAA;;;;;;;UAcE,WAAA;EAEf,UAAA;IACE,UAAA,EAAY,KAAA,CAAM,mBAAA,CAAoB,gBAAA;EAAA;EAExC,cAAA;IACE,aAAA,EAAe,KAAA,CAAM,sBAAA,CAAuB,mBAAA;EAAA;EAE9C,SAAA;IACE,UAAA,EAAY,KAAA,CAAM,mBAAA,CAAoB,gBAAA;EAAA;EAExC,YAAA;IACE,UAAA,EAAY,KAAA,CAAM,mBAAA,CAAoB,gBAAA;EAAA;EAIxC,YAAA;IACE,OAAA,EAAS,KAAA;MACP,KAAA;MACA,KAAA;MACA,OAAA,GARmC,cAAA,CAQH,aAAA;IAAA;IAElC,aAAA;IACA,QAAA,GAAW,CAAA;EAAA;EAEb,oBAAA;IACE,OAAA,EAAS,KAAA;MACP,KAAA;MACA,KAAA;MACA,OAAA,GAZY,cAAA,CAYoB,aAAA;IAAA;IAElC,aAAA;IACA,QAAA,GAAW,CAAA,mBA5DG;IA8Dd,OAAA,WA9DoB;IAgEpB,mBAAA,WAhEwB;IAkExB,yBAAA;EAAA;EAEF,kBAAA;IACE,OAAA,EAAS,KAAA;MAAQ,KAAA;MAAe,KAAA;IAAA;IAChC,QAAA;IACA,QAAA,GAAW,CAAA;IACX,OAAA;EAAA;EAEF,wBAAA;IACE,WAAA,GAAc,KAAA,aAAkB,OAAA,CAC9B,KAAA;MACE,KAAA;MACA,KAAA;MACA,OAAA,GAVU,cAAA,CAUsB,aAAA;IAAA;IAGpC,QAAA;IACA,QAAA,GAAW,CAAA;IACX,OAAA;EAAA;EAIF,aAAA;IACE,OAAA;IACA,MAAA;IACA,MAAA;IACA,KAAA;EAAA;EAEF,sBAAA;IACE,OAAA;IACA,MAAA;IACA,MAAA;IACA,KAAA;EAAA;EAIF,qBAAA,EAAuB,oBAAA;EACvB,4BAAA,EAA8B,oBAAA;EAC9B,kCAAA,EAAoC,oBAAA;IAClC,WAAA,GAAc,KAAA,aAAkB,OAAA,CAC9B,KAAA;MACE,KAAA;MACA,KAAA;MACA,OAAA,GALkD,cAAA,CAKlB,aAAA;IAAA;EAAA;EAMtC,WAAA,EAAa,cAAA;EACb,gBAAA,EAAkB,cAAA;EAClB,iBAAA,EAAmB,mBAAA;EACnB,iBAAA,EAAmB,cAAA;EAGnB,kBAAA,EAAoB,UAAA;EACpB,0BAAA,EAA4B,UAAA;IAC1B,OAAA,GAAU,IAAA,UAAc,EAAA;EAAA;EAE1B,oBAAA;IACE,IAAA,EAAM,KAAA;MAAQ,GAAA;MAAa,KAAA;IAAA;IAC3B,MAAA;IACA,SAAA,GAAY,KAAA;IACZ,MAAA,GAAS,KAAA,UAAe,GAAA;IACxB,QAAA,GAAW,KAAA,UAAe,KAAA;IAgCS;;;;;IA1BnC,aAAA,IAAiB,KAAA,aAAkB,OAAA,CAAQ,gBAAA;EAAA;EAG7C,eAAA;IACE,OAAA,EAAS,KAAA;MACP,KAAA;MACA,KAAA;MACA,OAAA,GAPwC,cAAA,CAOR,aAAA;IAAA;EAAA;EAKpC,kBAAA;EAlHuB;;;;;EAwHvB,YAAA;IACE,aAAA,IAAiB,KAAA,aAAkB,OAAA,CAAQ,gBAAA;EAAA;EAnH3C;;;;EAyHF,cAAA;IACE,aAAA,IAAiB,KAAA,aAAkB,OAAA,CAAQ,gBAAA;EAAA;EApHzC;;;;;;;;;;;;EAkIJ,iBAAA;IAvHW,sFAyHT,OAAA,EAAS,KAAA;MACP,KAAA;MACA,KAAA;MACA,OAAA,GAnBwC,cAAA,CAmBR,aAAA;IAAA,IAnHlC;IAsHA,OAAA,WAnHA;IAqHA,mBAAA;IACA,yBAAA;IAtHgC;;;;IA2HhC,aAAA,IAAiB,KAAA,aAAkB,OAAA,CAAQ,gBAAA;EAAA;EAE7C,qBAAA;EACA,mBAAA;EACA,eAAA;EACA,mBAAA;EACA,iBAAA;EACA,0BAAA;AAAA;AAAA,KAyBU,mBAAA,WAA8B,sBAAA,IAA0B,cAAA,CAAe,CAAA,IACjF,WAAA,CAAY,CAAA;;KAGF,aAAA,WACJ,sBAAA,GAAyB,mBAAA,CAAoB,CAAA,IACnD,sBAAA"}
1
+ {"version":3,"file":"field-props.d.mts","names":[],"sources":["../../src/types/field-props.ts"],"mappings":"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"}