@ncukondo/reference-manager 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/chunks/{action-menu-D8gSe1YM.js → action-menu-BoJkH1yr.js} +2 -2
- package/dist/chunks/{action-menu-D8gSe1YM.js.map → action-menu-BoJkH1yr.js.map} +1 -1
- package/dist/chunks/{format-B52BI__9.js → format-QgF4pmp6.js} +2 -2
- package/dist/chunks/{format-B52BI__9.js.map → format-QgF4pmp6.js.map} +1 -1
- package/dist/chunks/{index-iYPq6D80.js → index-BJf01yMW.js} +2 -2
- package/dist/chunks/index-BJf01yMW.js.map +1 -0
- package/dist/chunks/{index-B5W5srUa.js → index-C49EfSAl.js} +4 -4
- package/dist/chunks/{index-B5W5srUa.js.map → index-C49EfSAl.js.map} +1 -1
- package/dist/chunks/{index-BPhIwqHO.js → index-Di6yhlFH.js} +41 -21
- package/dist/chunks/index-Di6yhlFH.js.map +1 -0
- package/dist/chunks/{reference-select-DcClzkw2.js → reference-select-D4iGJ4kA.js} +3 -3
- package/dist/chunks/{reference-select-DcClzkw2.js.map → reference-select-D4iGJ4kA.js.map} +1 -1
- package/dist/chunks/{style-select-D0bgalgW.js → style-select-UWYScO8e.js} +2 -2
- package/dist/chunks/{style-select-D0bgalgW.js.map → style-select-UWYScO8e.js.map} +1 -1
- package/dist/cli/commands/attach.d.ts +4 -0
- package/dist/cli/commands/attach.d.ts.map +1 -1
- package/dist/cli/commands/search.d.ts.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/index-BPhIwqHO.js.map +0 -1
- package/dist/chunks/index-iYPq6D80.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-B5W5srUa.js","sources":["../../src/features/interactive/apps/SearchFlowApp.tsx","../../src/features/interactive/apps/runSearchFlow.ts","../../src/features/interactive/apps/CiteFlowApp.tsx","../../src/features/interactive/apps/runCiteFlow.ts"],"sourcesContent":["/**\n * SearchFlowApp - Single App for search -t flow\n *\n * Manages state transitions: search → action → (style/output-format if needed)\n * Following React Ink Single App Pattern (ADR-015)\n */\n\nimport { Box, useApp } from \"ink\";\nimport type React from \"react\";\nimport { createElement, useEffect, useState } from \"react\";\nimport type { CitationKeyFormat } from \"../../../config/schema.js\";\nimport type { CslItem } from \"../../../core/csl-json/types.js\";\nimport {\n type ActionMenuResult,\n type ActionType,\n OUTPUT_FORMAT_CHOICES,\n type OutputFormatType,\n STYLE_CHOICES,\n generateOutput,\n getActionChoices,\n isSideEffectAction,\n} from \"../action-menu.js\";\nimport {\n type Choice,\n SearchableMultiSelect,\n Select,\n type SortOption,\n} from \"../components/index.js\";\n\n/**\n * Flow states for the search flow\n */\ntype FlowState = \"search\" | \"action\" | \"style\" | \"output-format\" | \"exiting\";\n\n/**\n * Props for SearchFlowApp\n */\nexport interface SearchFlowAppProps {\n /** Choices for the search prompt */\n choices: Choice<CslItem>[];\n /** Filter function for search */\n filterFn: (query: string, choices: Choice<CslItem>[]) => Choice<CslItem>[];\n /** Number of visible items */\n visibleCount: number;\n /** Default sort option */\n defaultSort: SortOption;\n /** Default citation key format */\n defaultKeyFormat: CitationKeyFormat;\n /** Default citation style */\n defaultStyle: string;\n /** Callback when flow completes */\n onComplete: (result: ActionMenuResult) => void;\n /** Callback when flow is cancelled */\n onCancel: () => void;\n}\n\n/**\n * SearchFlowApp component\n *\n * Single App that manages search → action → style/output-format flow\n */\nexport function SearchFlowApp({\n choices,\n filterFn,\n visibleCount,\n defaultSort,\n defaultKeyFormat,\n defaultStyle,\n onComplete,\n onCancel,\n}: SearchFlowAppProps): React.ReactElement {\n const { exit } = useApp();\n const [state, setState] = useState<FlowState>(\"search\");\n const [selectedItems, setSelectedItems] = useState<CslItem[]>([]);\n const [pendingResult, setPendingResult] = useState<ActionMenuResult | null>(null);\n\n // Exit when entering \"exiting\" state (after rendering empty component)\n useEffect(() => {\n if (state === \"exiting\" && pendingResult) {\n exit();\n if (pendingResult.cancelled) {\n onCancel();\n } else {\n onComplete(pendingResult);\n }\n }\n }, [state, pendingResult, exit, onCancel, onComplete]);\n\n // Transition to exiting state with result\n const exitWith = (result: ActionMenuResult) => {\n setPendingResult(result);\n setState(\"exiting\");\n };\n\n // Handle search submission\n const handleSearchSubmit = (selected: Choice<CslItem>[]) => {\n if (selected.length === 0) {\n exitWith({ action: \"cancel\", output: \"\", cancelled: true });\n return;\n }\n setSelectedItems(selected.map((c) => c.value));\n setState(\"action\");\n };\n\n // Handle search cancel\n const handleSearchCancel = () => {\n exitWith({ action: \"cancel\", output: \"\", cancelled: true });\n };\n\n // Handle action selection\n const handleActionSelect = (action: ActionType) => {\n if (action === \"cancel\") {\n exitWith({ action: \"cancel\", output: \"\", cancelled: true });\n return;\n }\n\n // If cite-choose, go to style selection\n if (action === \"cite-choose\") {\n setState(\"style\");\n return;\n }\n\n // If output-format, go to output format submenu\n if (action === \"output-format\") {\n setState(\"output-format\");\n return;\n }\n\n // Handle side-effect actions\n if (isSideEffectAction(action)) {\n exitWith({ action, output: \"\", cancelled: false, selectedItems });\n return;\n }\n\n // Generate output and complete\n const output = generateOutput(action, selectedItems, {\n defaultKeyFormat,\n defaultStyle,\n });\n exitWith({ action, output, cancelled: false });\n };\n\n // Handle action cancel (go back to search)\n const handleActionCancel = () => {\n setState(\"search\");\n };\n\n // Handle style selection\n const handleStyleSelect = (style: string) => {\n const output = generateOutput(\"cite-choose\", selectedItems, {\n defaultKeyFormat,\n defaultStyle: style,\n });\n exitWith({ action: \"cite-choose\", output, cancelled: false });\n };\n\n // Handle style cancel (go back to action)\n const handleStyleCancel = () => {\n setState(\"action\");\n };\n\n // Handle output format selection\n const handleOutputFormatSelect = (format: OutputFormatType) => {\n if (format === \"cancel\") {\n setState(\"action\");\n return;\n }\n\n const output = generateOutput(format, selectedItems, {\n defaultKeyFormat,\n defaultStyle,\n });\n exitWith({ action: \"output-format\", output, cancelled: false });\n };\n\n // Handle output format cancel (go back to action)\n const handleOutputFormatCancel = () => {\n setState(\"action\");\n };\n\n // Render based on current state\n if (state === \"exiting\") {\n // Empty component - Ink will clear the previous content\n return createElement(Box);\n }\n\n if (state === \"search\") {\n return createElement(SearchableMultiSelect<CslItem>, {\n choices,\n filterFn,\n visibleCount,\n onSubmit: handleSearchSubmit,\n onCancel: handleSearchCancel,\n header: \"Search references\",\n placeholder: \"Type to search...\",\n defaultSort,\n });\n }\n\n if (state === \"action\") {\n const count = selectedItems.length;\n const refWord = count === 1 ? \"reference\" : \"references\";\n return createElement(Select<ActionType>, {\n key: \"action\",\n options: getActionChoices(count, { defaultKeyFormat }),\n message: `Action for ${count} selected ${refWord}:`,\n onSelect: handleActionSelect,\n onCancel: handleActionCancel,\n });\n }\n\n if (state === \"output-format\") {\n return createElement(Select<OutputFormatType>, {\n key: \"output-format\",\n options: OUTPUT_FORMAT_CHOICES,\n message: \"Select output format:\",\n onSelect: handleOutputFormatSelect,\n onCancel: handleOutputFormatCancel,\n });\n }\n\n // state === \"style\"\n return createElement(Select<string>, {\n key: \"style\",\n options: STYLE_CHOICES,\n message: \"Select citation style:\",\n onSelect: handleStyleSelect,\n onCancel: handleStyleCancel,\n });\n}\n","/**\n * Runner for SearchFlowApp\n *\n * Provides the public API for running the search flow.\n */\n\nimport { render } from \"ink\";\nimport { createElement } from \"react\";\nimport type { CitationKeyFormat } from \"../../../config/schema.js\";\nimport type { CslItem } from \"../../../core/csl-json/types.js\";\nimport type { SearchResult } from \"../../search/types.js\";\nimport type { ActionMenuResult } from \"../action-menu.js\";\nimport { restoreStdinAfterInk } from \"../alternate-screen.js\";\nimport { type Choice, type SortOption, calculateEffectiveLimit } from \"../components/index.js\";\nimport { formatAuthors } from \"../format.js\";\nimport { SearchFlowApp } from \"./SearchFlowApp.js\";\n\n/**\n * Configuration for the search flow\n */\nexport interface SearchFlowConfig {\n /** Maximum number of results to display */\n limit: number;\n /** Debounce delay in milliseconds (not used, kept for API compatibility) */\n debounceMs: number;\n /** Default citation key format */\n defaultKeyFormat?: CitationKeyFormat;\n /** Default citation style */\n defaultStyle?: string;\n}\n\n/**\n * Search function type for filtering references\n */\nexport type SearchFunction = (query: string) => SearchResult[];\n\n/**\n * Extract year from CSL item\n */\nfunction extractYear(item: CslItem): number | undefined {\n const dateParts = item.issued?.[\"date-parts\"];\n if (!dateParts || dateParts.length === 0) return undefined;\n const firstDatePart = dateParts[0];\n if (!firstDatePart || firstDatePart.length === 0) return undefined;\n return firstDatePart[0];\n}\n\n/**\n * Extract published date from CSL item\n */\nfunction extractPublishedDate(item: CslItem): Date | undefined {\n const dateParts = item.issued?.[\"date-parts\"];\n if (!dateParts || dateParts.length === 0) return undefined;\n const firstDatePart = dateParts[0];\n if (!firstDatePart || firstDatePart.length === 0) return undefined;\n const [year, month = 1, day = 1] = firstDatePart;\n if (year === undefined) return undefined;\n return new Date(year, month - 1, day);\n}\n\n/**\n * Extract updated date from CSL item (from custom.timestamp)\n */\nfunction extractUpdatedDate(item: CslItem): Date | undefined {\n const dateStr = item.custom?.timestamp;\n if (!dateStr || typeof dateStr !== \"string\") return undefined;\n const date = new Date(dateStr);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\n/**\n * Extract created date from CSL item (from custom.created_at)\n */\nfunction extractCreatedDate(item: CslItem): Date | undefined {\n const dateStr = item.custom?.created_at;\n if (!dateStr || typeof dateStr !== \"string\") return undefined;\n const date = new Date(dateStr);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\n/**\n * Format identifiers for meta line\n */\nfunction formatIdentifiers(item: CslItem): string {\n const parts: string[] = [];\n if (item.DOI) parts.push(`DOI: ${item.DOI}`);\n if (item.PMID) parts.push(`PMID: ${item.PMID}`);\n if (item.PMCID) parts.push(`PMCID: ${item.PMCID}`);\n if (item.ISBN) parts.push(`ISBN: ${item.ISBN}`);\n return parts.join(\" · \");\n}\n\n/**\n * Format item type for display\n */\nfunction formatType(type: string): string {\n const typeMap: Record<string, string> = {\n \"article-journal\": \"Journal article\",\n \"article-magazine\": \"Magazine article\",\n \"article-newspaper\": \"Newspaper article\",\n book: \"Book\",\n chapter: \"Book chapter\",\n \"paper-conference\": \"Conference paper\",\n thesis: \"Thesis\",\n report: \"Report\",\n webpage: \"Web page\",\n };\n return typeMap[type] ?? type;\n}\n\n/**\n * Convert CslItem to Choice for SearchableMultiSelect\n */\nfunction toChoice(item: CslItem): Choice<CslItem> {\n const authors = formatAuthors(item.author);\n const year = extractYear(item);\n const identifiers = formatIdentifiers(item);\n const itemType = formatType(item.type);\n\n // Build meta line: Year · Type · Identifiers\n const metaParts: string[] = [];\n if (year) metaParts.push(String(year));\n metaParts.push(itemType);\n if (identifiers) metaParts.push(identifiers);\n\n const updatedDate = extractUpdatedDate(item);\n const createdDate = extractCreatedDate(item);\n const publishedDate = extractPublishedDate(item);\n\n return {\n id: item.id,\n title: item.title ?? \"(No title)\",\n subtitle: authors || \"(No authors)\",\n meta: metaParts.join(\" · \"),\n value: item,\n ...(updatedDate && { updatedDate }),\n ...(createdDate && { createdDate }),\n ...(publishedDate && { publishedDate }),\n };\n}\n\n/**\n * Run the search flow (search → action → style if needed)\n *\n * This is the main entry point for the `search -t` command.\n */\nexport async function runSearchFlow(\n allReferences: CslItem[],\n searchFn: SearchFunction,\n config: SearchFlowConfig\n): Promise<ActionMenuResult> {\n // Convert references to choices\n const choices = allReferences.map(toChoice);\n\n // Calculate effective visible count\n const effectiveLimit = calculateEffectiveLimit(config.limit);\n\n // Create filter function using the provided search function\n const filterFn = (query: string, choices: Choice<CslItem>[]): Choice<CslItem>[] => {\n if (!query.trim()) return choices;\n\n const results = searchFn(query);\n return results.map((r) => toChoice(r.reference));\n };\n\n // Default sort option\n const defaultSort: SortOption = \"updated-desc\";\n\n // Create a promise to capture the result\n return new Promise<ActionMenuResult>((resolve) => {\n let flowResult: ActionMenuResult = {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n\n const handleComplete = (result: ActionMenuResult): void => {\n flowResult = result;\n };\n\n const handleCancel = (): void => {\n flowResult = {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n };\n\n // Render the Ink app (single render for entire flow)\n const { waitUntilExit } = render(\n createElement(SearchFlowApp, {\n choices,\n filterFn,\n visibleCount: effectiveLimit,\n defaultSort,\n defaultKeyFormat: config.defaultKeyFormat ?? \"pandoc\",\n defaultStyle: config.defaultStyle ?? \"apa\",\n onComplete: handleComplete,\n onCancel: handleCancel,\n })\n );\n\n // Wait for the app to exit, then resolve\n waitUntilExit()\n .then(() => {\n restoreStdinAfterInk();\n resolve(flowResult);\n })\n .catch(() => {\n restoreStdinAfterInk();\n resolve({\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n });\n });\n });\n}\n","/**\n * CiteFlowApp - Single App for cite command flow\n *\n * Implements the Single App Pattern (ADR-015) for the cite command.\n * Manages state transitions: reference selection → style selection → exiting\n */\n\nimport { Box, useApp } from \"ink\";\nimport type React from \"react\";\nimport { createElement, useEffect, useState } from \"react\";\nimport type { CslItem } from \"../../../core/csl-json/types.js\";\nimport { SearchableMultiSelect } from \"../components/SearchableMultiSelect.js\";\nimport { Select, type SelectOption } from \"../components/Select.js\";\nimport type { Choice, SortOption } from \"../components/index.js\";\n\n// Flow states\ntype FlowState = \"search\" | \"style\" | \"exiting\";\n\n/**\n * Result from the cite flow\n */\nexport interface CiteFlowResult {\n /** Selected reference IDs */\n identifiers: string[];\n /** Selected style (if style selection was shown) */\n style?: string;\n /** Whether the flow was cancelled */\n cancelled: boolean;\n}\n\n/**\n * Props for CiteFlowApp\n */\nexport interface CiteFlowAppProps {\n /** All reference choices */\n choices: Choice<CslItem>[];\n /** Filter function for search */\n filterFn: (query: string, choices: Choice<CslItem>[]) => Choice<CslItem>[];\n /** Number of visible items */\n visibleCount: number;\n /** Default sort option */\n defaultSort: SortOption;\n /** Style options for style selection */\n styleOptions: SelectOption<string>[];\n /** Whether to show style selection (false if style already specified) */\n showStyleSelect: boolean;\n /** Callback when flow completes */\n onComplete: (result: CiteFlowResult) => void;\n /** Callback when flow is cancelled */\n onCancel: () => void;\n}\n\n/**\n * CiteFlowApp component\n *\n * Single Ink app that handles the entire cite flow:\n * 1. Reference selection (SearchableMultiSelect)\n * 2. Style selection (Select) - optional\n * 3. Exit\n */\nexport function CiteFlowApp({\n choices,\n filterFn,\n visibleCount,\n defaultSort,\n styleOptions,\n showStyleSelect,\n onComplete,\n onCancel,\n}: CiteFlowAppProps): React.ReactElement {\n const { exit } = useApp();\n const [state, setState] = useState<FlowState>(\"search\");\n const [selectedItems, setSelectedItems] = useState<CslItem[]>([]);\n const [pendingResult, setPendingResult] = useState<CiteFlowResult | null>(null);\n\n // Exit when entering \"exiting\" state\n useEffect(() => {\n if (state === \"exiting\" && pendingResult) {\n exit();\n if (pendingResult.cancelled) {\n onCancel();\n } else {\n onComplete(pendingResult);\n }\n }\n }, [state, pendingResult, exit, onCancel, onComplete]);\n\n // Transition to exiting state with result\n const exitWith = (result: CiteFlowResult) => {\n setPendingResult(result);\n setState(\"exiting\");\n };\n\n // Handle search submission\n const handleSearchSubmit = (selected: Choice<CslItem>[]) => {\n if (selected.length === 0) {\n exitWith({ identifiers: [], cancelled: true });\n return;\n }\n const items = selected.map((c) => c.value);\n setSelectedItems(items);\n\n if (showStyleSelect) {\n setState(\"style\");\n } else {\n // No style selection needed, complete immediately\n exitWith({\n identifiers: items.map((item) => item.id),\n cancelled: false,\n });\n }\n };\n\n // Handle search cancel\n const handleSearchCancel = () => {\n exitWith({ identifiers: [], cancelled: true });\n };\n\n // Handle style selection\n const handleStyleSelect = (style: string) => {\n exitWith({\n identifiers: selectedItems.map((item) => item.id),\n style,\n cancelled: false,\n });\n };\n\n // Handle style cancel (go back to search)\n const handleStyleCancel = () => {\n setState(\"search\");\n };\n\n // Render based on current state\n if (state === \"exiting\") {\n return createElement(Box);\n }\n\n if (state === \"search\") {\n return createElement(SearchableMultiSelect<CslItem>, {\n choices,\n filterFn,\n visibleCount,\n onSubmit: handleSearchSubmit,\n onCancel: handleSearchCancel,\n header: \"Select references to cite\",\n placeholder: \"Type to search...\",\n defaultSort,\n });\n }\n\n // state === \"style\"\n const count = selectedItems.length;\n const refWord = count === 1 ? \"reference\" : \"references\";\n return createElement(Select<string>, {\n options: styleOptions,\n message: `Select citation style for ${count} ${refWord}:`,\n onSelect: handleStyleSelect,\n onCancel: handleStyleCancel,\n });\n}\n","/**\n * Runner for CiteFlowApp\n *\n * Provides the public API for running the cite flow.\n */\n\nimport { render } from \"ink\";\nimport { createElement } from \"react\";\nimport type { CslItem } from \"../../../core/csl-json/types.js\";\nimport type { SearchResult } from \"../../search/types.js\";\nimport { restoreStdinAfterInk } from \"../alternate-screen.js\";\nimport {\n type Choice,\n type SelectOption,\n type SortOption,\n calculateEffectiveLimit,\n} from \"../components/index.js\";\nimport { formatAuthors } from \"../format.js\";\nimport { CiteFlowApp, type CiteFlowResult } from \"./CiteFlowApp.js\";\n\n/**\n * Configuration for the cite flow\n */\nexport interface CiteFlowConfig {\n /** Maximum number of results to display */\n limit: number;\n}\n\n/**\n * Search function type for filtering references\n */\nexport type SearchFunction = (query: string) => SearchResult[];\n\n/**\n * Extract year from CSL item\n */\nfunction extractYear(item: CslItem): number | undefined {\n const dateParts = item.issued?.[\"date-parts\"];\n if (!dateParts || dateParts.length === 0) return undefined;\n const firstDatePart = dateParts[0];\n if (!firstDatePart || firstDatePart.length === 0) return undefined;\n return firstDatePart[0];\n}\n\n/**\n * Extract published date from CSL item\n */\nfunction extractPublishedDate(item: CslItem): Date | undefined {\n const dateParts = item.issued?.[\"date-parts\"];\n if (!dateParts || dateParts.length === 0) return undefined;\n const firstDatePart = dateParts[0];\n if (!firstDatePart || firstDatePart.length === 0) return undefined;\n const [year, month = 1, day = 1] = firstDatePart;\n if (year === undefined) return undefined;\n return new Date(year, month - 1, day);\n}\n\n/**\n * Extract updated date from CSL item (from custom.timestamp)\n */\nfunction extractUpdatedDate(item: CslItem): Date | undefined {\n const dateStr = item.custom?.timestamp;\n if (!dateStr || typeof dateStr !== \"string\") return undefined;\n const date = new Date(dateStr);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\n/**\n * Extract created date from CSL item (from custom.created_at)\n */\nfunction extractCreatedDate(item: CslItem): Date | undefined {\n const dateStr = item.custom?.created_at;\n if (!dateStr || typeof dateStr !== \"string\") return undefined;\n const date = new Date(dateStr);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\n/**\n * Format identifiers for meta line\n */\nfunction formatIdentifiers(item: CslItem): string {\n const parts: string[] = [];\n if (item.DOI) parts.push(`DOI: ${item.DOI}`);\n if (item.PMID) parts.push(`PMID: ${item.PMID}`);\n if (item.PMCID) parts.push(`PMCID: ${item.PMCID}`);\n if (item.ISBN) parts.push(`ISBN: ${item.ISBN}`);\n return parts.join(\" · \");\n}\n\n/**\n * Format item type for display\n */\nfunction formatType(type: string): string {\n const typeMap: Record<string, string> = {\n \"article-journal\": \"Journal article\",\n \"article-magazine\": \"Magazine article\",\n \"article-newspaper\": \"Newspaper article\",\n book: \"Book\",\n chapter: \"Book chapter\",\n \"paper-conference\": \"Conference paper\",\n thesis: \"Thesis\",\n report: \"Report\",\n webpage: \"Web page\",\n };\n return typeMap[type] ?? type;\n}\n\n/**\n * Convert CslItem to Choice for SearchableMultiSelect\n */\nfunction toChoice(item: CslItem): Choice<CslItem> {\n const authors = formatAuthors(item.author);\n const year = extractYear(item);\n const identifiers = formatIdentifiers(item);\n const itemType = formatType(item.type);\n\n // Build meta line: Year · Type · Identifiers\n const metaParts: string[] = [];\n if (year) metaParts.push(String(year));\n metaParts.push(itemType);\n if (identifiers) metaParts.push(identifiers);\n\n const updatedDate = extractUpdatedDate(item);\n const createdDate = extractCreatedDate(item);\n const publishedDate = extractPublishedDate(item);\n\n return {\n id: item.id,\n title: item.title ?? \"(No title)\",\n subtitle: authors || \"(No authors)\",\n meta: metaParts.join(\" · \"),\n value: item,\n ...(updatedDate && { updatedDate }),\n ...(createdDate && { createdDate }),\n ...(publishedDate && { publishedDate }),\n };\n}\n\n/**\n * Options for running the cite flow\n */\nexport interface RunCiteFlowOptions {\n /** All references available for selection */\n allReferences: CslItem[];\n /** Search function for filtering */\n searchFn: SearchFunction;\n /** Flow configuration */\n config: CiteFlowConfig;\n /** Style options for style selection */\n styleOptions: SelectOption<string>[];\n /** Whether to show style selection */\n showStyleSelect: boolean;\n}\n\n/**\n * Run the cite flow (reference selection → style selection if needed)\n *\n * This is the main entry point for interactive cite command.\n */\nexport async function runCiteFlow(options: RunCiteFlowOptions): Promise<CiteFlowResult> {\n const { allReferences, searchFn, config, styleOptions, showStyleSelect } = options;\n\n // Convert references to choices\n const choices = allReferences.map(toChoice);\n\n // Calculate effective visible count\n const effectiveLimit = calculateEffectiveLimit(config.limit);\n\n // Create filter function using the provided search function\n const filterFn = (query: string, choices: Choice<CslItem>[]): Choice<CslItem>[] => {\n if (!query.trim()) return choices;\n\n const results = searchFn(query);\n return results.map((r) => toChoice(r.reference));\n };\n\n // Default sort option\n const defaultSort: SortOption = \"updated-desc\";\n\n // Create a promise to capture the result\n return new Promise<CiteFlowResult>((resolve) => {\n let flowResult: CiteFlowResult = {\n identifiers: [],\n cancelled: true,\n };\n\n const handleComplete = (result: CiteFlowResult): void => {\n flowResult = result;\n };\n\n const handleCancel = (): void => {\n flowResult = {\n identifiers: [],\n cancelled: true,\n };\n };\n\n // Render the Ink app (single render for entire flow)\n const { waitUntilExit } = render(\n createElement(CiteFlowApp, {\n choices,\n filterFn,\n visibleCount: effectiveLimit,\n defaultSort,\n styleOptions,\n showStyleSelect,\n onComplete: handleComplete,\n onCancel: handleCancel,\n })\n );\n\n // Wait for the app to exit, then resolve\n waitUntilExit()\n .then(() => {\n restoreStdinAfterInk();\n resolve(flowResult);\n })\n .catch(() => {\n restoreStdinAfterInk();\n resolve({\n identifiers: [],\n cancelled: true,\n });\n });\n });\n}\n"],"names":["extractYear","extractPublishedDate","extractUpdatedDate","extractCreatedDate","formatIdentifiers","formatType","toChoice","choices"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-C49EfSAl.js","sources":["../../src/features/interactive/apps/SearchFlowApp.tsx","../../src/features/interactive/apps/runSearchFlow.ts","../../src/features/interactive/apps/CiteFlowApp.tsx","../../src/features/interactive/apps/runCiteFlow.ts"],"sourcesContent":["/**\n * SearchFlowApp - Single App for search -t flow\n *\n * Manages state transitions: search → action → (style/output-format if needed)\n * Following React Ink Single App Pattern (ADR-015)\n */\n\nimport { Box, useApp } from \"ink\";\nimport type React from \"react\";\nimport { createElement, useEffect, useState } from \"react\";\nimport type { CitationKeyFormat } from \"../../../config/schema.js\";\nimport type { CslItem } from \"../../../core/csl-json/types.js\";\nimport {\n type ActionMenuResult,\n type ActionType,\n OUTPUT_FORMAT_CHOICES,\n type OutputFormatType,\n STYLE_CHOICES,\n generateOutput,\n getActionChoices,\n isSideEffectAction,\n} from \"../action-menu.js\";\nimport {\n type Choice,\n SearchableMultiSelect,\n Select,\n type SortOption,\n} from \"../components/index.js\";\n\n/**\n * Flow states for the search flow\n */\ntype FlowState = \"search\" | \"action\" | \"style\" | \"output-format\" | \"exiting\";\n\n/**\n * Props for SearchFlowApp\n */\nexport interface SearchFlowAppProps {\n /** Choices for the search prompt */\n choices: Choice<CslItem>[];\n /** Filter function for search */\n filterFn: (query: string, choices: Choice<CslItem>[]) => Choice<CslItem>[];\n /** Number of visible items */\n visibleCount: number;\n /** Default sort option */\n defaultSort: SortOption;\n /** Default citation key format */\n defaultKeyFormat: CitationKeyFormat;\n /** Default citation style */\n defaultStyle: string;\n /** Callback when flow completes */\n onComplete: (result: ActionMenuResult) => void;\n /** Callback when flow is cancelled */\n onCancel: () => void;\n}\n\n/**\n * SearchFlowApp component\n *\n * Single App that manages search → action → style/output-format flow\n */\nexport function SearchFlowApp({\n choices,\n filterFn,\n visibleCount,\n defaultSort,\n defaultKeyFormat,\n defaultStyle,\n onComplete,\n onCancel,\n}: SearchFlowAppProps): React.ReactElement {\n const { exit } = useApp();\n const [state, setState] = useState<FlowState>(\"search\");\n const [selectedItems, setSelectedItems] = useState<CslItem[]>([]);\n const [pendingResult, setPendingResult] = useState<ActionMenuResult | null>(null);\n\n // Exit when entering \"exiting\" state (after rendering empty component)\n useEffect(() => {\n if (state === \"exiting\" && pendingResult) {\n exit();\n if (pendingResult.cancelled) {\n onCancel();\n } else {\n onComplete(pendingResult);\n }\n }\n }, [state, pendingResult, exit, onCancel, onComplete]);\n\n // Transition to exiting state with result\n const exitWith = (result: ActionMenuResult) => {\n setPendingResult(result);\n setState(\"exiting\");\n };\n\n // Handle search submission\n const handleSearchSubmit = (selected: Choice<CslItem>[]) => {\n if (selected.length === 0) {\n exitWith({ action: \"cancel\", output: \"\", cancelled: true });\n return;\n }\n setSelectedItems(selected.map((c) => c.value));\n setState(\"action\");\n };\n\n // Handle search cancel\n const handleSearchCancel = () => {\n exitWith({ action: \"cancel\", output: \"\", cancelled: true });\n };\n\n // Handle action selection\n const handleActionSelect = (action: ActionType) => {\n if (action === \"cancel\") {\n exitWith({ action: \"cancel\", output: \"\", cancelled: true });\n return;\n }\n\n // If cite-choose, go to style selection\n if (action === \"cite-choose\") {\n setState(\"style\");\n return;\n }\n\n // If output-format, go to output format submenu\n if (action === \"output-format\") {\n setState(\"output-format\");\n return;\n }\n\n // Handle side-effect actions\n if (isSideEffectAction(action)) {\n exitWith({ action, output: \"\", cancelled: false, selectedItems });\n return;\n }\n\n // Generate output and complete\n const output = generateOutput(action, selectedItems, {\n defaultKeyFormat,\n defaultStyle,\n });\n exitWith({ action, output, cancelled: false });\n };\n\n // Handle action cancel (go back to search)\n const handleActionCancel = () => {\n setState(\"search\");\n };\n\n // Handle style selection\n const handleStyleSelect = (style: string) => {\n const output = generateOutput(\"cite-choose\", selectedItems, {\n defaultKeyFormat,\n defaultStyle: style,\n });\n exitWith({ action: \"cite-choose\", output, cancelled: false });\n };\n\n // Handle style cancel (go back to action)\n const handleStyleCancel = () => {\n setState(\"action\");\n };\n\n // Handle output format selection\n const handleOutputFormatSelect = (format: OutputFormatType) => {\n if (format === \"cancel\") {\n setState(\"action\");\n return;\n }\n\n const output = generateOutput(format, selectedItems, {\n defaultKeyFormat,\n defaultStyle,\n });\n exitWith({ action: \"output-format\", output, cancelled: false });\n };\n\n // Handle output format cancel (go back to action)\n const handleOutputFormatCancel = () => {\n setState(\"action\");\n };\n\n // Render based on current state\n if (state === \"exiting\") {\n // Empty component - Ink will clear the previous content\n return createElement(Box);\n }\n\n if (state === \"search\") {\n return createElement(SearchableMultiSelect<CslItem>, {\n choices,\n filterFn,\n visibleCount,\n onSubmit: handleSearchSubmit,\n onCancel: handleSearchCancel,\n header: \"Search references\",\n placeholder: \"Type to search...\",\n defaultSort,\n });\n }\n\n if (state === \"action\") {\n const count = selectedItems.length;\n const refWord = count === 1 ? \"reference\" : \"references\";\n return createElement(Select<ActionType>, {\n key: \"action\",\n options: getActionChoices(count, { defaultKeyFormat }),\n message: `Action for ${count} selected ${refWord}:`,\n onSelect: handleActionSelect,\n onCancel: handleActionCancel,\n });\n }\n\n if (state === \"output-format\") {\n return createElement(Select<OutputFormatType>, {\n key: \"output-format\",\n options: OUTPUT_FORMAT_CHOICES,\n message: \"Select output format:\",\n onSelect: handleOutputFormatSelect,\n onCancel: handleOutputFormatCancel,\n });\n }\n\n // state === \"style\"\n return createElement(Select<string>, {\n key: \"style\",\n options: STYLE_CHOICES,\n message: \"Select citation style:\",\n onSelect: handleStyleSelect,\n onCancel: handleStyleCancel,\n });\n}\n","/**\n * Runner for SearchFlowApp\n *\n * Provides the public API for running the search flow.\n */\n\nimport { render } from \"ink\";\nimport { createElement } from \"react\";\nimport type { CitationKeyFormat } from \"../../../config/schema.js\";\nimport type { CslItem } from \"../../../core/csl-json/types.js\";\nimport type { SearchResult } from \"../../search/types.js\";\nimport type { ActionMenuResult } from \"../action-menu.js\";\nimport { restoreStdinAfterInk } from \"../alternate-screen.js\";\nimport { type Choice, type SortOption, calculateEffectiveLimit } from \"../components/index.js\";\nimport { formatAuthors } from \"../format.js\";\nimport { SearchFlowApp } from \"./SearchFlowApp.js\";\n\n/**\n * Configuration for the search flow\n */\nexport interface SearchFlowConfig {\n /** Maximum number of results to display */\n limit: number;\n /** Debounce delay in milliseconds (not used, kept for API compatibility) */\n debounceMs: number;\n /** Default citation key format */\n defaultKeyFormat?: CitationKeyFormat;\n /** Default citation style */\n defaultStyle?: string;\n}\n\n/**\n * Search function type for filtering references\n */\nexport type SearchFunction = (query: string) => SearchResult[];\n\n/**\n * Extract year from CSL item\n */\nfunction extractYear(item: CslItem): number | undefined {\n const dateParts = item.issued?.[\"date-parts\"];\n if (!dateParts || dateParts.length === 0) return undefined;\n const firstDatePart = dateParts[0];\n if (!firstDatePart || firstDatePart.length === 0) return undefined;\n return firstDatePart[0];\n}\n\n/**\n * Extract published date from CSL item\n */\nfunction extractPublishedDate(item: CslItem): Date | undefined {\n const dateParts = item.issued?.[\"date-parts\"];\n if (!dateParts || dateParts.length === 0) return undefined;\n const firstDatePart = dateParts[0];\n if (!firstDatePart || firstDatePart.length === 0) return undefined;\n const [year, month = 1, day = 1] = firstDatePart;\n if (year === undefined) return undefined;\n return new Date(year, month - 1, day);\n}\n\n/**\n * Extract updated date from CSL item (from custom.timestamp)\n */\nfunction extractUpdatedDate(item: CslItem): Date | undefined {\n const dateStr = item.custom?.timestamp;\n if (!dateStr || typeof dateStr !== \"string\") return undefined;\n const date = new Date(dateStr);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\n/**\n * Extract created date from CSL item (from custom.created_at)\n */\nfunction extractCreatedDate(item: CslItem): Date | undefined {\n const dateStr = item.custom?.created_at;\n if (!dateStr || typeof dateStr !== \"string\") return undefined;\n const date = new Date(dateStr);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\n/**\n * Format identifiers for meta line\n */\nfunction formatIdentifiers(item: CslItem): string {\n const parts: string[] = [];\n if (item.DOI) parts.push(`DOI: ${item.DOI}`);\n if (item.PMID) parts.push(`PMID: ${item.PMID}`);\n if (item.PMCID) parts.push(`PMCID: ${item.PMCID}`);\n if (item.ISBN) parts.push(`ISBN: ${item.ISBN}`);\n return parts.join(\" · \");\n}\n\n/**\n * Format item type for display\n */\nfunction formatType(type: string): string {\n const typeMap: Record<string, string> = {\n \"article-journal\": \"Journal article\",\n \"article-magazine\": \"Magazine article\",\n \"article-newspaper\": \"Newspaper article\",\n book: \"Book\",\n chapter: \"Book chapter\",\n \"paper-conference\": \"Conference paper\",\n thesis: \"Thesis\",\n report: \"Report\",\n webpage: \"Web page\",\n };\n return typeMap[type] ?? type;\n}\n\n/**\n * Convert CslItem to Choice for SearchableMultiSelect\n */\nfunction toChoice(item: CslItem): Choice<CslItem> {\n const authors = formatAuthors(item.author);\n const year = extractYear(item);\n const identifiers = formatIdentifiers(item);\n const itemType = formatType(item.type);\n\n // Build meta line: Year · Type · Identifiers\n const metaParts: string[] = [];\n if (year) metaParts.push(String(year));\n metaParts.push(itemType);\n if (identifiers) metaParts.push(identifiers);\n\n const updatedDate = extractUpdatedDate(item);\n const createdDate = extractCreatedDate(item);\n const publishedDate = extractPublishedDate(item);\n\n return {\n id: item.id,\n title: item.title ?? \"(No title)\",\n subtitle: authors || \"(No authors)\",\n meta: metaParts.join(\" · \"),\n value: item,\n ...(updatedDate && { updatedDate }),\n ...(createdDate && { createdDate }),\n ...(publishedDate && { publishedDate }),\n };\n}\n\n/**\n * Run the search flow (search → action → style if needed)\n *\n * This is the main entry point for the `search -t` command.\n */\nexport async function runSearchFlow(\n allReferences: CslItem[],\n searchFn: SearchFunction,\n config: SearchFlowConfig\n): Promise<ActionMenuResult> {\n // Convert references to choices\n const choices = allReferences.map(toChoice);\n\n // Calculate effective visible count\n const effectiveLimit = calculateEffectiveLimit(config.limit);\n\n // Create filter function using the provided search function\n const filterFn = (query: string, choices: Choice<CslItem>[]): Choice<CslItem>[] => {\n if (!query.trim()) return choices;\n\n const results = searchFn(query);\n return results.map((r) => toChoice(r.reference));\n };\n\n // Default sort option\n const defaultSort: SortOption = \"updated-desc\";\n\n // Create a promise to capture the result\n return new Promise<ActionMenuResult>((resolve) => {\n let flowResult: ActionMenuResult = {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n\n const handleComplete = (result: ActionMenuResult): void => {\n flowResult = result;\n };\n\n const handleCancel = (): void => {\n flowResult = {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n };\n\n // Render the Ink app (single render for entire flow)\n const { waitUntilExit } = render(\n createElement(SearchFlowApp, {\n choices,\n filterFn,\n visibleCount: effectiveLimit,\n defaultSort,\n defaultKeyFormat: config.defaultKeyFormat ?? \"pandoc\",\n defaultStyle: config.defaultStyle ?? \"apa\",\n onComplete: handleComplete,\n onCancel: handleCancel,\n })\n );\n\n // Wait for the app to exit, then resolve\n waitUntilExit()\n .then(() => {\n restoreStdinAfterInk();\n resolve(flowResult);\n })\n .catch(() => {\n restoreStdinAfterInk();\n resolve({\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n });\n });\n });\n}\n","/**\n * CiteFlowApp - Single App for cite command flow\n *\n * Implements the Single App Pattern (ADR-015) for the cite command.\n * Manages state transitions: reference selection → style selection → exiting\n */\n\nimport { Box, useApp } from \"ink\";\nimport type React from \"react\";\nimport { createElement, useEffect, useState } from \"react\";\nimport type { CslItem } from \"../../../core/csl-json/types.js\";\nimport { SearchableMultiSelect } from \"../components/SearchableMultiSelect.js\";\nimport { Select, type SelectOption } from \"../components/Select.js\";\nimport type { Choice, SortOption } from \"../components/index.js\";\n\n// Flow states\ntype FlowState = \"search\" | \"style\" | \"exiting\";\n\n/**\n * Result from the cite flow\n */\nexport interface CiteFlowResult {\n /** Selected reference IDs */\n identifiers: string[];\n /** Selected style (if style selection was shown) */\n style?: string;\n /** Whether the flow was cancelled */\n cancelled: boolean;\n}\n\n/**\n * Props for CiteFlowApp\n */\nexport interface CiteFlowAppProps {\n /** All reference choices */\n choices: Choice<CslItem>[];\n /** Filter function for search */\n filterFn: (query: string, choices: Choice<CslItem>[]) => Choice<CslItem>[];\n /** Number of visible items */\n visibleCount: number;\n /** Default sort option */\n defaultSort: SortOption;\n /** Style options for style selection */\n styleOptions: SelectOption<string>[];\n /** Whether to show style selection (false if style already specified) */\n showStyleSelect: boolean;\n /** Callback when flow completes */\n onComplete: (result: CiteFlowResult) => void;\n /** Callback when flow is cancelled */\n onCancel: () => void;\n}\n\n/**\n * CiteFlowApp component\n *\n * Single Ink app that handles the entire cite flow:\n * 1. Reference selection (SearchableMultiSelect)\n * 2. Style selection (Select) - optional\n * 3. Exit\n */\nexport function CiteFlowApp({\n choices,\n filterFn,\n visibleCount,\n defaultSort,\n styleOptions,\n showStyleSelect,\n onComplete,\n onCancel,\n}: CiteFlowAppProps): React.ReactElement {\n const { exit } = useApp();\n const [state, setState] = useState<FlowState>(\"search\");\n const [selectedItems, setSelectedItems] = useState<CslItem[]>([]);\n const [pendingResult, setPendingResult] = useState<CiteFlowResult | null>(null);\n\n // Exit when entering \"exiting\" state\n useEffect(() => {\n if (state === \"exiting\" && pendingResult) {\n exit();\n if (pendingResult.cancelled) {\n onCancel();\n } else {\n onComplete(pendingResult);\n }\n }\n }, [state, pendingResult, exit, onCancel, onComplete]);\n\n // Transition to exiting state with result\n const exitWith = (result: CiteFlowResult) => {\n setPendingResult(result);\n setState(\"exiting\");\n };\n\n // Handle search submission\n const handleSearchSubmit = (selected: Choice<CslItem>[]) => {\n if (selected.length === 0) {\n exitWith({ identifiers: [], cancelled: true });\n return;\n }\n const items = selected.map((c) => c.value);\n setSelectedItems(items);\n\n if (showStyleSelect) {\n setState(\"style\");\n } else {\n // No style selection needed, complete immediately\n exitWith({\n identifiers: items.map((item) => item.id),\n cancelled: false,\n });\n }\n };\n\n // Handle search cancel\n const handleSearchCancel = () => {\n exitWith({ identifiers: [], cancelled: true });\n };\n\n // Handle style selection\n const handleStyleSelect = (style: string) => {\n exitWith({\n identifiers: selectedItems.map((item) => item.id),\n style,\n cancelled: false,\n });\n };\n\n // Handle style cancel (go back to search)\n const handleStyleCancel = () => {\n setState(\"search\");\n };\n\n // Render based on current state\n if (state === \"exiting\") {\n return createElement(Box);\n }\n\n if (state === \"search\") {\n return createElement(SearchableMultiSelect<CslItem>, {\n choices,\n filterFn,\n visibleCount,\n onSubmit: handleSearchSubmit,\n onCancel: handleSearchCancel,\n header: \"Select references to cite\",\n placeholder: \"Type to search...\",\n defaultSort,\n });\n }\n\n // state === \"style\"\n const count = selectedItems.length;\n const refWord = count === 1 ? \"reference\" : \"references\";\n return createElement(Select<string>, {\n options: styleOptions,\n message: `Select citation style for ${count} ${refWord}:`,\n onSelect: handleStyleSelect,\n onCancel: handleStyleCancel,\n });\n}\n","/**\n * Runner for CiteFlowApp\n *\n * Provides the public API for running the cite flow.\n */\n\nimport { render } from \"ink\";\nimport { createElement } from \"react\";\nimport type { CslItem } from \"../../../core/csl-json/types.js\";\nimport type { SearchResult } from \"../../search/types.js\";\nimport { restoreStdinAfterInk } from \"../alternate-screen.js\";\nimport {\n type Choice,\n type SelectOption,\n type SortOption,\n calculateEffectiveLimit,\n} from \"../components/index.js\";\nimport { formatAuthors } from \"../format.js\";\nimport { CiteFlowApp, type CiteFlowResult } from \"./CiteFlowApp.js\";\n\n/**\n * Configuration for the cite flow\n */\nexport interface CiteFlowConfig {\n /** Maximum number of results to display */\n limit: number;\n}\n\n/**\n * Search function type for filtering references\n */\nexport type SearchFunction = (query: string) => SearchResult[];\n\n/**\n * Extract year from CSL item\n */\nfunction extractYear(item: CslItem): number | undefined {\n const dateParts = item.issued?.[\"date-parts\"];\n if (!dateParts || dateParts.length === 0) return undefined;\n const firstDatePart = dateParts[0];\n if (!firstDatePart || firstDatePart.length === 0) return undefined;\n return firstDatePart[0];\n}\n\n/**\n * Extract published date from CSL item\n */\nfunction extractPublishedDate(item: CslItem): Date | undefined {\n const dateParts = item.issued?.[\"date-parts\"];\n if (!dateParts || dateParts.length === 0) return undefined;\n const firstDatePart = dateParts[0];\n if (!firstDatePart || firstDatePart.length === 0) return undefined;\n const [year, month = 1, day = 1] = firstDatePart;\n if (year === undefined) return undefined;\n return new Date(year, month - 1, day);\n}\n\n/**\n * Extract updated date from CSL item (from custom.timestamp)\n */\nfunction extractUpdatedDate(item: CslItem): Date | undefined {\n const dateStr = item.custom?.timestamp;\n if (!dateStr || typeof dateStr !== \"string\") return undefined;\n const date = new Date(dateStr);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\n/**\n * Extract created date from CSL item (from custom.created_at)\n */\nfunction extractCreatedDate(item: CslItem): Date | undefined {\n const dateStr = item.custom?.created_at;\n if (!dateStr || typeof dateStr !== \"string\") return undefined;\n const date = new Date(dateStr);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\n/**\n * Format identifiers for meta line\n */\nfunction formatIdentifiers(item: CslItem): string {\n const parts: string[] = [];\n if (item.DOI) parts.push(`DOI: ${item.DOI}`);\n if (item.PMID) parts.push(`PMID: ${item.PMID}`);\n if (item.PMCID) parts.push(`PMCID: ${item.PMCID}`);\n if (item.ISBN) parts.push(`ISBN: ${item.ISBN}`);\n return parts.join(\" · \");\n}\n\n/**\n * Format item type for display\n */\nfunction formatType(type: string): string {\n const typeMap: Record<string, string> = {\n \"article-journal\": \"Journal article\",\n \"article-magazine\": \"Magazine article\",\n \"article-newspaper\": \"Newspaper article\",\n book: \"Book\",\n chapter: \"Book chapter\",\n \"paper-conference\": \"Conference paper\",\n thesis: \"Thesis\",\n report: \"Report\",\n webpage: \"Web page\",\n };\n return typeMap[type] ?? type;\n}\n\n/**\n * Convert CslItem to Choice for SearchableMultiSelect\n */\nfunction toChoice(item: CslItem): Choice<CslItem> {\n const authors = formatAuthors(item.author);\n const year = extractYear(item);\n const identifiers = formatIdentifiers(item);\n const itemType = formatType(item.type);\n\n // Build meta line: Year · Type · Identifiers\n const metaParts: string[] = [];\n if (year) metaParts.push(String(year));\n metaParts.push(itemType);\n if (identifiers) metaParts.push(identifiers);\n\n const updatedDate = extractUpdatedDate(item);\n const createdDate = extractCreatedDate(item);\n const publishedDate = extractPublishedDate(item);\n\n return {\n id: item.id,\n title: item.title ?? \"(No title)\",\n subtitle: authors || \"(No authors)\",\n meta: metaParts.join(\" · \"),\n value: item,\n ...(updatedDate && { updatedDate }),\n ...(createdDate && { createdDate }),\n ...(publishedDate && { publishedDate }),\n };\n}\n\n/**\n * Options for running the cite flow\n */\nexport interface RunCiteFlowOptions {\n /** All references available for selection */\n allReferences: CslItem[];\n /** Search function for filtering */\n searchFn: SearchFunction;\n /** Flow configuration */\n config: CiteFlowConfig;\n /** Style options for style selection */\n styleOptions: SelectOption<string>[];\n /** Whether to show style selection */\n showStyleSelect: boolean;\n}\n\n/**\n * Run the cite flow (reference selection → style selection if needed)\n *\n * This is the main entry point for interactive cite command.\n */\nexport async function runCiteFlow(options: RunCiteFlowOptions): Promise<CiteFlowResult> {\n const { allReferences, searchFn, config, styleOptions, showStyleSelect } = options;\n\n // Convert references to choices\n const choices = allReferences.map(toChoice);\n\n // Calculate effective visible count\n const effectiveLimit = calculateEffectiveLimit(config.limit);\n\n // Create filter function using the provided search function\n const filterFn = (query: string, choices: Choice<CslItem>[]): Choice<CslItem>[] => {\n if (!query.trim()) return choices;\n\n const results = searchFn(query);\n return results.map((r) => toChoice(r.reference));\n };\n\n // Default sort option\n const defaultSort: SortOption = \"updated-desc\";\n\n // Create a promise to capture the result\n return new Promise<CiteFlowResult>((resolve) => {\n let flowResult: CiteFlowResult = {\n identifiers: [],\n cancelled: true,\n };\n\n const handleComplete = (result: CiteFlowResult): void => {\n flowResult = result;\n };\n\n const handleCancel = (): void => {\n flowResult = {\n identifiers: [],\n cancelled: true,\n };\n };\n\n // Render the Ink app (single render for entire flow)\n const { waitUntilExit } = render(\n createElement(CiteFlowApp, {\n choices,\n filterFn,\n visibleCount: effectiveLimit,\n defaultSort,\n styleOptions,\n showStyleSelect,\n onComplete: handleComplete,\n onCancel: handleCancel,\n })\n );\n\n // Wait for the app to exit, then resolve\n waitUntilExit()\n .then(() => {\n restoreStdinAfterInk();\n resolve(flowResult);\n })\n .catch(() => {\n restoreStdinAfterInk();\n resolve({\n identifiers: [],\n cancelled: true,\n });\n });\n });\n}\n"],"names":["extractYear","extractPublishedDate","extractUpdatedDate","extractCreatedDate","formatIdentifiers","formatType","toChoice","choices"],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ import "@citation-js/plugin-csl";
|
|
|
20
20
|
import { ZodOptional as ZodOptional$2, z } from "zod";
|
|
21
21
|
import { serve } from "@hono/node-server";
|
|
22
22
|
const name = "@ncukondo/reference-manager";
|
|
23
|
-
const version$1 = "0.
|
|
23
|
+
const version$1 = "0.19.0";
|
|
24
24
|
const description$1 = "A local reference management tool using CSL-JSON as the single source of truth";
|
|
25
25
|
const packageJson = {
|
|
26
26
|
name,
|
|
@@ -1056,27 +1056,27 @@ class OperationsLibrary {
|
|
|
1056
1056
|
}
|
|
1057
1057
|
// Attachment operations
|
|
1058
1058
|
async attachAdd(options) {
|
|
1059
|
-
const { addAttachment: addAttachment2 } = await import("./index-
|
|
1059
|
+
const { addAttachment: addAttachment2 } = await import("./index-BJf01yMW.js");
|
|
1060
1060
|
return addAttachment2(this.library, options);
|
|
1061
1061
|
}
|
|
1062
1062
|
async attachList(options) {
|
|
1063
|
-
const { listAttachments: listAttachments2 } = await import("./index-
|
|
1063
|
+
const { listAttachments: listAttachments2 } = await import("./index-BJf01yMW.js");
|
|
1064
1064
|
return listAttachments2(this.library, options);
|
|
1065
1065
|
}
|
|
1066
1066
|
async attachGet(options) {
|
|
1067
|
-
const { getAttachment: getAttachment2 } = await import("./index-
|
|
1067
|
+
const { getAttachment: getAttachment2 } = await import("./index-BJf01yMW.js");
|
|
1068
1068
|
return getAttachment2(this.library, options);
|
|
1069
1069
|
}
|
|
1070
1070
|
async attachDetach(options) {
|
|
1071
|
-
const { detachAttachment: detachAttachment2 } = await import("./index-
|
|
1071
|
+
const { detachAttachment: detachAttachment2 } = await import("./index-BJf01yMW.js");
|
|
1072
1072
|
return detachAttachment2(this.library, options);
|
|
1073
1073
|
}
|
|
1074
1074
|
async attachSync(options) {
|
|
1075
|
-
const { syncAttachments: syncAttachments2 } = await import("./index-
|
|
1075
|
+
const { syncAttachments: syncAttachments2 } = await import("./index-BJf01yMW.js");
|
|
1076
1076
|
return syncAttachments2(this.library, options);
|
|
1077
1077
|
}
|
|
1078
1078
|
async attachOpen(options) {
|
|
1079
|
-
const { openAttachment: openAttachment2 } = await import("./index-
|
|
1079
|
+
const { openAttachment: openAttachment2 } = await import("./index-BJf01yMW.js");
|
|
1080
1080
|
return openAttachment2(this.library, options);
|
|
1081
1081
|
}
|
|
1082
1082
|
}
|
|
@@ -1795,7 +1795,7 @@ function getAttachExitCode(result) {
|
|
|
1795
1795
|
}
|
|
1796
1796
|
async function executeInteractiveSelect$2(context, config2) {
|
|
1797
1797
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
1798
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
1798
|
+
const { selectReferencesOrExit } = await import("./reference-select-D4iGJ4kA.js");
|
|
1799
1799
|
const allReferences = await context.library.getAll();
|
|
1800
1800
|
const identifiers = await withAlternateScreen2(
|
|
1801
1801
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -2131,7 +2131,8 @@ const attach = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
|
|
|
2131
2131
|
handleAttachGetAction,
|
|
2132
2132
|
handleAttachListAction,
|
|
2133
2133
|
handleAttachOpenAction,
|
|
2134
|
-
handleAttachSyncAction
|
|
2134
|
+
handleAttachSyncAction,
|
|
2135
|
+
runInteractiveMode
|
|
2135
2136
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2136
2137
|
async function validateOptions$2(options) {
|
|
2137
2138
|
if (options.output && !["text", "html", "rtf"].includes(options.output)) {
|
|
@@ -2190,8 +2191,8 @@ function getCiteExitCode(result) {
|
|
|
2190
2191
|
}
|
|
2191
2192
|
async function executeInteractiveCite(options, context, config2) {
|
|
2192
2193
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
2193
|
-
const { runCiteFlow } = await import("./index-
|
|
2194
|
-
const { buildStyleChoices, listCustomStyles } = await import("./style-select-
|
|
2194
|
+
const { runCiteFlow } = await import("./index-C49EfSAl.js");
|
|
2195
|
+
const { buildStyleChoices, listCustomStyles } = await import("./style-select-UWYScO8e.js");
|
|
2195
2196
|
const { search } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.z);
|
|
2196
2197
|
const { tokenize } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.y);
|
|
2197
2198
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
@@ -6748,7 +6749,7 @@ function formatEditOutput(result) {
|
|
|
6748
6749
|
}
|
|
6749
6750
|
async function executeInteractiveEdit(options, context, config2) {
|
|
6750
6751
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
6751
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
6752
|
+
const { selectReferencesOrExit } = await import("./reference-select-D4iGJ4kA.js");
|
|
6752
6753
|
const allReferences = await context.library.getAll();
|
|
6753
6754
|
const identifiers = await withAlternateScreen2(
|
|
6754
6755
|
() => selectReferencesOrExit(allReferences, { multiSelect: true }, config2.cli.tui)
|
|
@@ -10402,7 +10403,7 @@ function getFulltextExitCode(result) {
|
|
|
10402
10403
|
}
|
|
10403
10404
|
async function executeInteractiveSelect$1(context, config2) {
|
|
10404
10405
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
10405
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
10406
|
+
const { selectReferencesOrExit } = await import("./reference-select-D4iGJ4kA.js");
|
|
10406
10407
|
const allReferences = await context.library.getAll();
|
|
10407
10408
|
const identifiers = await withAlternateScreen2(
|
|
10408
10409
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -31490,7 +31491,7 @@ Continue?`;
|
|
|
31490
31491
|
}
|
|
31491
31492
|
async function executeInteractiveRemove(context, config2) {
|
|
31492
31493
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
31493
|
-
const { selectReferenceItemsOrExit } = await import("./reference-select-
|
|
31494
|
+
const { selectReferenceItemsOrExit } = await import("./reference-select-D4iGJ4kA.js");
|
|
31494
31495
|
const allReferences = await context.library.getAll();
|
|
31495
31496
|
const selectedItems = await withAlternateScreen2(
|
|
31496
31497
|
() => selectReferenceItemsOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -31715,7 +31716,7 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
31715
31716
|
validateInteractiveOptions(options);
|
|
31716
31717
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
31717
31718
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
31718
|
-
const { runSearchFlow } = await import("./index-
|
|
31719
|
+
const { runSearchFlow } = await import("./index-C49EfSAl.js");
|
|
31719
31720
|
const { search } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.z);
|
|
31720
31721
|
const { tokenize } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.y);
|
|
31721
31722
|
checkTTY();
|
|
@@ -31734,7 +31735,7 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
31734
31735
|
})
|
|
31735
31736
|
);
|
|
31736
31737
|
if (result.selectedItems && !result.cancelled) {
|
|
31737
|
-
const { isSideEffectAction } = await import("./action-menu-
|
|
31738
|
+
const { isSideEffectAction } = await import("./action-menu-BoJkH1yr.js");
|
|
31738
31739
|
if (isSideEffectAction(result.action)) {
|
|
31739
31740
|
await executeSideEffectAction(result.action, result.selectedItems, context, config2);
|
|
31740
31741
|
return { output: "", cancelled: false, action: result.action };
|
|
@@ -31780,16 +31781,28 @@ async function executeSideEffectAction(action, items2, context, config2) {
|
|
|
31780
31781
|
break;
|
|
31781
31782
|
}
|
|
31782
31783
|
case "manage-attachments": {
|
|
31783
|
-
const { executeAttachOpen: executeAttachOpen2 } = await Promise.resolve().then(() => attach);
|
|
31784
|
+
const { executeAttachOpen: executeAttachOpen2, runInteractiveMode: runInteractiveMode2 } = await Promise.resolve().then(() => attach);
|
|
31784
31785
|
const item = items2[0];
|
|
31785
31786
|
if (!item) return;
|
|
31786
|
-
await executeAttachOpen2(
|
|
31787
|
+
const result = await executeAttachOpen2(
|
|
31787
31788
|
{
|
|
31788
31789
|
identifier: item.id,
|
|
31789
31790
|
attachmentsDirectory: config2.attachments.directory
|
|
31790
31791
|
},
|
|
31791
31792
|
context
|
|
31792
31793
|
);
|
|
31794
|
+
if (!result.success) {
|
|
31795
|
+
process.stderr.write(`Error: ${result.error}
|
|
31796
|
+
`);
|
|
31797
|
+
return;
|
|
31798
|
+
}
|
|
31799
|
+
await runInteractiveMode2(
|
|
31800
|
+
item.id,
|
|
31801
|
+
result.path ?? "",
|
|
31802
|
+
config2.attachments.directory,
|
|
31803
|
+
void 0,
|
|
31804
|
+
context
|
|
31805
|
+
);
|
|
31793
31806
|
break;
|
|
31794
31807
|
}
|
|
31795
31808
|
case "edit": {
|
|
@@ -32125,7 +32138,7 @@ function formatUpdateOutput(result, identifier) {
|
|
|
32125
32138
|
}
|
|
32126
32139
|
async function executeInteractiveUpdate(context, config2) {
|
|
32127
32140
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32128
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
32141
|
+
const { selectReferencesOrExit } = await import("./reference-select-D4iGJ4kA.js");
|
|
32129
32142
|
const allReferences = await context.library.getAll();
|
|
32130
32143
|
const identifiers = await withAlternateScreen2(
|
|
32131
32144
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -32420,7 +32433,7 @@ function getUrlExitCode(result) {
|
|
|
32420
32433
|
}
|
|
32421
32434
|
async function executeInteractiveSelect(context, config2) {
|
|
32422
32435
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32423
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
32436
|
+
const { selectReferencesOrExit } = await import("./reference-select-D4iGJ4kA.js");
|
|
32424
32437
|
const allReferences = await context.library.getAll();
|
|
32425
32438
|
const identifiers = await withAlternateScreen2(
|
|
32426
32439
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -32750,6 +32763,13 @@ function createProgram() {
|
|
|
32750
32763
|
const program = new Command();
|
|
32751
32764
|
program.name("reference-manager").version(packageJson.version).description(packageJson.description);
|
|
32752
32765
|
program.option("--library <path>", "Override library file path").option("--log-level <level>", "Override log level (silent|info|debug)").option("--config <path>", "Use specific config file").option("--quiet", "Suppress all non-error output").option("--verbose", "Enable verbose output").option("--no-backup", "Disable backup creation").option("--backup-dir <path>", "Override backup directory").option("--attachments-dir <path>", "Override attachments directory").option("--clipboard", "Copy output to system clipboard").option("--no-clipboard", "Disable clipboard copy");
|
|
32766
|
+
program.action(async () => {
|
|
32767
|
+
if (process.stdin.isTTY && process.stdout.isTTY) {
|
|
32768
|
+
await handleSearchAction("", { tui: true }, program);
|
|
32769
|
+
} else {
|
|
32770
|
+
program.help();
|
|
32771
|
+
}
|
|
32772
|
+
});
|
|
32753
32773
|
registerListCommand(program);
|
|
32754
32774
|
registerSearchCommand(program);
|
|
32755
32775
|
registerExportCommand(program);
|
|
@@ -33150,4 +33170,4 @@ export {
|
|
|
33150
33170
|
restoreStdinAfterInk as r,
|
|
33151
33171
|
syncAttachments as s
|
|
33152
33172
|
};
|
|
33153
|
-
//# sourceMappingURL=index-
|
|
33173
|
+
//# sourceMappingURL=index-Di6yhlFH.js.map
|