@ncukondo/reference-manager 0.14.1 → 0.15.1

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 (106) hide show
  1. package/README.md +64 -16
  2. package/bin/reference-manager.js +0 -0
  3. package/dist/chunks/{action-menu-CVSizwXm.js → action-menu-DwCcc6Gt.js} +3 -3
  4. package/dist/chunks/{action-menu-CVSizwXm.js.map → action-menu-DwCcc6Gt.js.map} +1 -1
  5. package/dist/chunks/{file-watcher-D2Y-SlcE.js → file-watcher-B_WpVHSV.js} +18 -18
  6. package/dist/chunks/{file-watcher-D2Y-SlcE.js.map → file-watcher-B_WpVHSV.js.map} +1 -1
  7. package/dist/chunks/{index-CXoDLO8W.js → index-B4RmLBI1.js} +1698 -504
  8. package/dist/chunks/index-B4RmLBI1.js.map +1 -0
  9. package/dist/chunks/index-DEd6F5Rr.js +10 -0
  10. package/dist/chunks/index-DEd6F5Rr.js.map +1 -0
  11. package/dist/chunks/{index-DapYyqAC.js → index-DHgeuWGP.js} +112 -35
  12. package/dist/chunks/index-DHgeuWGP.js.map +1 -0
  13. package/dist/chunks/{loader-C1EpnyPm.js → loader-DStZe-OB.js} +82 -32
  14. package/dist/chunks/loader-DStZe-OB.js.map +1 -0
  15. package/dist/chunks/{reference-select-DSVwE9iu.js → reference-select-B9w9CLa1.js} +3 -3
  16. package/dist/chunks/{reference-select-DSVwE9iu.js.map → reference-select-B9w9CLa1.js.map} +1 -1
  17. package/dist/chunks/{style-select-CYo0O7MZ.js → style-select-BNQHC79W.js} +2 -2
  18. package/dist/chunks/{style-select-CYo0O7MZ.js.map → style-select-BNQHC79W.js.map} +1 -1
  19. package/dist/chunks/{tty-CDBIQraQ.js → tty-BMyaEOhX.js} +2 -2
  20. package/dist/chunks/tty-BMyaEOhX.js.map +1 -0
  21. package/dist/cli/commands/attach.d.ts +204 -0
  22. package/dist/cli/commands/attach.d.ts.map +1 -0
  23. package/dist/cli/commands/cite.d.ts +1 -1
  24. package/dist/cli/commands/cite.d.ts.map +1 -1
  25. package/dist/cli/commands/config.d.ts.map +1 -1
  26. package/dist/cli/commands/edit.d.ts.map +1 -1
  27. package/dist/cli/commands/export.d.ts +1 -1
  28. package/dist/cli/commands/fulltext.d.ts +2 -2
  29. package/dist/cli/commands/fulltext.d.ts.map +1 -1
  30. package/dist/cli/commands/list.d.ts +2 -1
  31. package/dist/cli/commands/list.d.ts.map +1 -1
  32. package/dist/cli/commands/remove.d.ts.map +1 -1
  33. package/dist/cli/commands/search.d.ts +3 -2
  34. package/dist/cli/commands/search.d.ts.map +1 -1
  35. package/dist/cli/commands/server.d.ts.map +1 -1
  36. package/dist/cli/commands/update.d.ts.map +1 -1
  37. package/dist/cli/completion.d.ts.map +1 -1
  38. package/dist/cli/helpers.d.ts +36 -0
  39. package/dist/cli/helpers.d.ts.map +1 -1
  40. package/dist/cli/index.d.ts.map +1 -1
  41. package/dist/cli/server-client.d.ts +37 -1
  42. package/dist/cli/server-client.d.ts.map +1 -1
  43. package/dist/cli.js +2 -2
  44. package/dist/config/defaults.d.ts +7 -1
  45. package/dist/config/defaults.d.ts.map +1 -1
  46. package/dist/config/key-parser.d.ts +1 -1
  47. package/dist/config/loader.d.ts.map +1 -1
  48. package/dist/config/schema.d.ts +22 -8
  49. package/dist/config/schema.d.ts.map +1 -1
  50. package/dist/features/attachments/directory-manager.d.ts +40 -0
  51. package/dist/features/attachments/directory-manager.d.ts.map +1 -0
  52. package/dist/features/attachments/directory.d.ts +36 -0
  53. package/dist/features/attachments/directory.d.ts.map +1 -0
  54. package/dist/features/attachments/filename.d.ts +30 -0
  55. package/dist/features/attachments/filename.d.ts.map +1 -0
  56. package/dist/features/attachments/types.d.ts +38 -0
  57. package/dist/features/attachments/types.d.ts.map +1 -0
  58. package/dist/features/fulltext/manager.d.ts +1 -1
  59. package/dist/features/fulltext/manager.d.ts.map +1 -1
  60. package/dist/features/interactive/tty.d.ts +2 -2
  61. package/dist/features/operations/attachments/add.d.ts +42 -0
  62. package/dist/features/operations/attachments/add.d.ts.map +1 -0
  63. package/dist/features/operations/attachments/detach.d.ts +38 -0
  64. package/dist/features/operations/attachments/detach.d.ts.map +1 -0
  65. package/dist/features/operations/attachments/get.d.ts +35 -0
  66. package/dist/features/operations/attachments/get.d.ts.map +1 -0
  67. package/dist/features/operations/attachments/index.d.ts +16 -0
  68. package/dist/features/operations/attachments/index.d.ts.map +1 -0
  69. package/dist/features/operations/attachments/list.d.ts +32 -0
  70. package/dist/features/operations/attachments/list.d.ts.map +1 -0
  71. package/dist/features/operations/attachments/open.d.ts +39 -0
  72. package/dist/features/operations/attachments/open.d.ts.map +1 -0
  73. package/dist/features/operations/attachments/sync.d.ts +50 -0
  74. package/dist/features/operations/attachments/sync.d.ts.map +1 -0
  75. package/dist/features/operations/fulltext/attach.d.ts +8 -2
  76. package/dist/features/operations/fulltext/attach.d.ts.map +1 -1
  77. package/dist/features/operations/fulltext/detach.d.ts +9 -3
  78. package/dist/features/operations/fulltext/detach.d.ts.map +1 -1
  79. package/dist/features/operations/fulltext/get.d.ts +8 -2
  80. package/dist/features/operations/fulltext/get.d.ts.map +1 -1
  81. package/dist/features/operations/fulltext/open.d.ts +8 -2
  82. package/dist/features/operations/fulltext/open.d.ts.map +1 -1
  83. package/dist/features/operations/fulltext-adapter/fulltext-adapter.d.ts +39 -0
  84. package/dist/features/operations/fulltext-adapter/fulltext-adapter.d.ts.map +1 -0
  85. package/dist/features/operations/fulltext-adapter/index.d.ts +7 -0
  86. package/dist/features/operations/fulltext-adapter/index.d.ts.map +1 -0
  87. package/dist/features/operations/index.d.ts +1 -0
  88. package/dist/features/operations/index.d.ts.map +1 -1
  89. package/dist/features/operations/library-operations.d.ts +43 -0
  90. package/dist/features/operations/library-operations.d.ts.map +1 -1
  91. package/dist/features/operations/operations-library.d.ts +7 -0
  92. package/dist/features/operations/operations-library.d.ts.map +1 -1
  93. package/dist/features/operations/remove.d.ts +1 -0
  94. package/dist/features/operations/remove.d.ts.map +1 -1
  95. package/dist/index.js +15 -15
  96. package/dist/index.js.map +1 -1
  97. package/dist/server.js +3 -3
  98. package/dist/utils/opener.d.ts +6 -1
  99. package/dist/utils/opener.d.ts.map +1 -1
  100. package/dist/utils/path.d.ts +28 -0
  101. package/dist/utils/path.d.ts.map +1 -0
  102. package/package.json +3 -1
  103. package/dist/chunks/index-CXoDLO8W.js.map +0 -1
  104. package/dist/chunks/index-DapYyqAC.js.map +0 -1
  105. package/dist/chunks/loader-C1EpnyPm.js.map +0 -1
  106. package/dist/chunks/tty-CDBIQraQ.js.map +0 -1
package/README.md CHANGED
@@ -43,7 +43,7 @@ Streamline your writing workflow:
43
43
 
44
44
  ```bash
45
45
  # Find and select references interactively
46
- ref search -i "machine learning"
46
+ ref search -t "machine learning"
47
47
  # → Select references with Space, then export as BibTeX or generate citations
48
48
 
49
49
  # Generate citations
@@ -221,16 +221,18 @@ ref completion uninstall
221
221
  After installation, restart your shell or source the config file. Then:
222
222
 
223
223
  ```bash
224
- ref <TAB> # Shows: list search add remove ...
224
+ ref <TAB> # Shows: list search add remove attach ...
225
225
  ref list --<TAB> # Shows: --json --sort --limit ...
226
226
  ref list --sort <TAB> # Shows: created updated published ...
227
227
  ref cite <TAB> # Shows: smith2023 jones2024 ...
228
228
  ref cite smith<TAB> # Shows: smith2023 smith2024-review
229
+ ref attach <TAB> # Shows: open add list get detach sync
230
+ ref attach add <ID> --role <TAB> # Shows: fulltext supplement notes draft
229
231
  ```
230
232
 
231
233
  Completion includes:
232
234
  - Subcommands and options
233
- - Option values (sort fields, citation styles, etc.)
235
+ - Option values (sort fields, citation styles, attachment roles, etc.)
234
236
  - Dynamic reference IDs from your library
235
237
 
236
238
  ## CLI Reference
@@ -271,16 +273,16 @@ ref search "author:jones year:2024"
271
273
  ref search "title:\"deep learning\""
272
274
 
273
275
  # Interactive search (with real-time filtering)
274
- ref search -i # Start interactive mode
275
- ref search -i "machine learning" # Pre-fill query
276
+ ref search -t # Start interactive mode
277
+ ref search -t "machine learning" # Pre-fill query
276
278
 
277
279
  # Export raw CSL-JSON (for pandoc, jq, etc.)
278
280
  ref export smith2024 # Single reference (as object)
279
281
  ref export smith2024 jones2023 # Multiple references (as array)
280
282
  ref export --all # All references
281
283
  ref export --search "author:smith" # Search results
282
- ref export smith2024 --format yaml # YAML format
283
- ref export --all --format bibtex # BibTeX format
284
+ ref export smith2024 -o yaml # YAML format
285
+ ref export --all -o bibtex # BibTeX format
284
286
 
285
287
  # Add references
286
288
  ref add paper.json # From CSL-JSON file
@@ -291,8 +293,8 @@ ref add pmid:25056061 # From PubMed ID
291
293
  ref add "ISBN:978-4-00-000000-0" # From ISBN
292
294
  cat references.json | ref add # From stdin (file content)
293
295
  echo "10.1038/nature12373" | ref add # From stdin (DOI auto-detect)
294
- echo "12345678" | ref add --format pmid # From stdin (PMID)
295
- echo "ISBN:978-4-00-000000-0" | ref add --format isbn # From stdin (ISBN)
296
+ echo "12345678" | ref add -i pmid # From stdin (PMID)
297
+ echo "ISBN:978-4-00-000000-0" | ref add -i isbn # From stdin (ISBN)
296
298
 
297
299
  # Remove a reference
298
300
  ref remove smith2024
@@ -326,7 +328,7 @@ ref update smith2024 --set "abstract="
326
328
  # Generate citations
327
329
  ref cite smith2024
328
330
  ref cite smith2024 jones2023 --style apa
329
- ref cite smith2024 --style chicago-author-date --format html
331
+ ref cite smith2024 --style chicago-author-date -o html
330
332
 
331
333
  # Interactive selection (no ID argument)
332
334
  ref cite
@@ -366,6 +368,52 @@ ref fulltext detach smith2024 --pdf
366
368
  ref fulltext detach smith2024 --pdf --delete # Also delete the file
367
369
  ```
368
370
 
371
+ ### Attachment Management
372
+
373
+ A more flexible attachment system supporting multiple files per reference with role-based categorization:
374
+
375
+ ```bash
376
+ # Open reference's attachment folder (for drag-and-drop file management)
377
+ ref attach open smith2024 # Opens folder in file manager
378
+ ref attach open smith2024 --print # Print path only (for scripting)
379
+
380
+ # Add attachments programmatically
381
+ ref attach add smith2024 supplement.xlsx --role supplement
382
+ ref attach add smith2024 notes.md --role notes
383
+ ref attach add smith2024 draft-v1.docx --role draft --label v1
384
+ ref attach add smith2024 file.pdf --move # Move instead of copy
385
+ ref attach add smith2024 file.pdf --force # Overwrite existing
386
+
387
+ # List attachments
388
+ ref attach list smith2024 # List all attachments
389
+ ref attach list smith2024 --role supplement # Filter by role
390
+
391
+ # Get attachment path
392
+ ref attach get smith2024 supplement-data.xlsx
393
+
394
+ # Sync metadata with filesystem (after manual file operations)
395
+ ref attach sync smith2024 # Show pending changes (dry-run)
396
+ ref attach sync smith2024 --yes # Apply changes
397
+ ref attach sync smith2024 --fix # Also remove missing files from metadata
398
+
399
+ # Detach files
400
+ ref attach detach smith2024 supplement-data.xlsx
401
+ ref attach detach smith2024 supplement-data.xlsx --delete # Also delete file
402
+ ```
403
+
404
+ **Available Roles:**
405
+ - `fulltext` — Primary document (PDF or Markdown)
406
+ - `supplement` — Supplementary materials, datasets
407
+ - `notes` — Research notes
408
+ - `draft` — Draft versions
409
+
410
+ **Manual Workflow:**
411
+ 1. `ref attach open smith2024` — Opens folder in your file manager
412
+ 2. Drag and drop files into the folder
413
+ 3. `ref attach sync smith2024 --yes` — Updates metadata to include new files
414
+
415
+ Files are organized by reference in directories named `Author-Year-ID-UUID` under the attachments directory.
416
+
369
417
  ### Edit Command
370
418
 
371
419
  Edit references interactively using your preferred text editor:
@@ -458,8 +506,8 @@ Supported field prefixes: `id:`, `author:`, `title:`, `year:`, `doi:`, `pmid:`,
458
506
  Start an interactive search session with real-time filtering:
459
507
 
460
508
  ```bash
461
- ref search -i # Start with empty query
462
- ref search -i "machine learning" # Pre-fill the search query
509
+ ref search -t # Start with empty query
510
+ ref search -t "machine learning" # Pre-fill the search query
463
511
  ```
464
512
 
465
513
  **Features:**
@@ -548,7 +596,7 @@ auto_stop_minutes = 60
548
596
  | Variable | Description |
549
597
  |----------|-------------|
550
598
  | `REFERENCE_MANAGER_LIBRARY` | Override library file path |
551
- | `REFERENCE_MANAGER_FULLTEXT_DIR` | Override fulltext directory |
599
+ | `REFERENCE_MANAGER_ATTACHMENTS_DIR` | Override attachments directory |
552
600
 
553
601
  ### Config Command
554
602
 
@@ -557,7 +605,7 @@ Manage configuration via CLI without manually editing TOML files:
557
605
  ```bash
558
606
  # View all configuration
559
607
  ref config show
560
- ref config show --json # JSON format
608
+ ref config show -o json # JSON format
561
609
  ref config show --sources # Show where each value comes from
562
610
 
563
611
  # Get/set individual values
@@ -569,7 +617,7 @@ ref config set --local citation.default_style ieee # Project-local config
569
617
  ref config unset citation.default_style
570
618
 
571
619
  # List all available keys
572
- ref config list-keys
620
+ ref config keys
573
621
 
574
622
  # Show config file locations
575
623
  ref config path
@@ -586,7 +634,7 @@ ref config edit --local # Edit project-local config
586
634
  - `citation.*` — Citation defaults (style, locale, format)
587
635
  - `pubmed.*` — PubMed API credentials
588
636
  - `fulltext.*` — Fulltext storage
589
- - `cli.*` — CLI behavior (limits, sorting, interactive mode)
637
+ - `cli.*` — CLI behavior (limits, sorting, TUI mode)
590
638
  - `mcp.*` — MCP server settings
591
639
 
592
640
  ## Data Format
File without changes
@@ -1,5 +1,5 @@
1
- import { f as formatBibtex } from "./index-CXoDLO8W.js";
2
- import { f as formatBibliographyCSL } from "./index-DapYyqAC.js";
1
+ import { f as formatBibtex } from "./index-B4RmLBI1.js";
2
+ import { f as formatBibliographyCSL } from "./index-DHgeuWGP.js";
3
3
  const ACTION_CHOICES = [
4
4
  { name: "output-ids", message: "Output IDs (citation keys)", value: "output-ids" },
5
5
  { name: "output-csl-json", message: "Output as CSL-JSON", value: "output-csl-json" },
@@ -116,4 +116,4 @@ export {
116
116
  runActionMenu,
117
117
  runStyleSelectPrompt
118
118
  };
119
- //# sourceMappingURL=action-menu-CVSizwXm.js.map
119
+ //# sourceMappingURL=action-menu-DwCcc6Gt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-menu-CVSizwXm.js","sources":["../../src/features/interactive/action-menu.ts"],"sourcesContent":["/**\n * Action menu for interactive search mode.\n * Allows users to perform actions on selected references.\n */\n\nimport type { CslItem } from \"../../core/csl-json/types.js\";\nimport { formatBibliographyCSL, formatBibtex } from \"../format/index.js\";\n\n/**\n * Action types available in the action menu.\n */\nexport type ActionType =\n | \"output-ids\"\n | \"output-csl-json\"\n | \"output-bibtex\"\n | \"cite-apa\"\n | \"cite-choose\"\n | \"cancel\";\n\n/**\n * Result from action menu selection.\n */\nexport interface ActionMenuResult {\n /** Selected action type */\n action: ActionType;\n /** Generated output (empty for cancel) */\n output: string;\n /** Whether the prompt was cancelled */\n cancelled: boolean;\n}\n\n/**\n * Result from style selection prompt.\n */\nexport interface StyleSelectResult {\n /** Selected style (undefined if cancelled) */\n style?: string;\n /** Whether the prompt was cancelled */\n cancelled: boolean;\n}\n\n/**\n * Choice definition for Enquirer Select prompt.\n */\ninterface SelectChoice {\n name: string;\n message: string;\n value: ActionType | string;\n}\n\n/**\n * Available action choices for the action menu.\n */\nexport const ACTION_CHOICES: SelectChoice[] = [\n { name: \"output-ids\", message: \"Output IDs (citation keys)\", value: \"output-ids\" },\n { name: \"output-csl-json\", message: \"Output as CSL-JSON\", value: \"output-csl-json\" },\n { name: \"output-bibtex\", message: \"Output as BibTeX\", value: \"output-bibtex\" },\n { name: \"cite-apa\", message: \"Generate citation (APA)\", value: \"cite-apa\" },\n { name: \"cite-choose\", message: \"Generate citation (choose style)\", value: \"cite-choose\" },\n { name: \"cancel\", message: \"Cancel\", value: \"cancel\" },\n];\n\n/**\n * Available style choices for citation style selection.\n * Uses BUILTIN_STYLES from config/csl-styles.ts\n */\nexport const STYLE_CHOICES: SelectChoice[] = [\n { name: \"apa\", message: \"APA\", value: \"apa\" },\n { name: \"vancouver\", message: \"Vancouver\", value: \"vancouver\" },\n { name: \"harvard\", message: \"Harvard\", value: \"harvard\" },\n];\n\n/**\n * Run the style selection prompt.\n */\n\n/**\n * Generate output for the given action and items.\n */\nfunction generateOutput(action: ActionType, items: CslItem[], style = \"apa\"): string {\n switch (action) {\n case \"output-ids\":\n return items.map((item) => item.id).join(\"\\n\");\n\n case \"output-csl-json\":\n return JSON.stringify(items, null, 2);\n\n case \"output-bibtex\":\n return formatBibtex(items);\n\n case \"cite-apa\":\n return formatBibliographyCSL(items, { style: \"apa\" });\n\n case \"cite-choose\":\n return formatBibliographyCSL(items, { style });\n\n case \"cancel\":\n return \"\";\n\n default:\n return \"\";\n }\n}\n\n/**\n * Process the selected action and generate result.\n */\nasync function processAction(action: ActionType, items: CslItem[]): Promise<ActionMenuResult> {\n // Handle cite-choose: prompt for style first\n if (action === \"cite-choose\") {\n const styleResult = await runStyleSelectPrompt();\n if (styleResult.cancelled) {\n return {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n }\n return {\n action,\n output: generateOutput(action, items, styleResult.style),\n cancelled: false,\n };\n }\n\n // Handle cancel\n if (action === \"cancel\") {\n return {\n action,\n output: \"\",\n cancelled: true,\n };\n }\n\n // Handle other actions\n return {\n action,\n output: generateOutput(action, items),\n cancelled: false,\n };\n}\n\nexport async function runStyleSelectPrompt(): Promise<StyleSelectResult> {\n // Dynamic import to allow mocking in tests\n // enquirer is a CommonJS module, so we must use default import\n const enquirer = await import(\"enquirer\");\n const Select = (enquirer.default as unknown as Record<string, unknown>).Select as new (\n options: Record<string, unknown>\n ) => { run(): Promise<string> };\n\n const promptOptions = {\n name: \"style\",\n message: \"Select citation style:\",\n choices: STYLE_CHOICES,\n };\n\n try {\n const prompt = new Select(promptOptions);\n const result = (await prompt.run()) as string;\n\n return {\n style: result,\n cancelled: false,\n };\n } catch (error) {\n // Enquirer throws an empty string when cancelled\n if (error === \"\" || (error instanceof Error && error.message === \"\")) {\n return {\n cancelled: true,\n };\n }\n throw error;\n }\n}\n\n/**\n * Run the action menu for selected references.\n *\n * @param items - Selected references\n * @returns Action result with output\n */\nexport async function runActionMenu(items: CslItem[]): Promise<ActionMenuResult> {\n // Dynamic import to allow mocking in tests\n // enquirer is a CommonJS module, so we must use default import\n const enquirer = await import(\"enquirer\");\n const Select = (enquirer.default as unknown as Record<string, unknown>).Select as new (\n options: Record<string, unknown>\n ) => { run(): Promise<string> };\n\n const count = items.length;\n const refWord = count === 1 ? \"reference\" : \"references\";\n const message = `Action for ${count} selected ${refWord}:`;\n\n const promptOptions = {\n name: \"action\",\n message,\n choices: ACTION_CHOICES,\n };\n\n try {\n const prompt = new Select(promptOptions);\n const action = (await prompt.run()) as ActionType;\n\n return processAction(action, items);\n } catch (error) {\n // Enquirer throws an empty string when cancelled\n if (error === \"\" || (error instanceof Error && error.message === \"\")) {\n return {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n }\n throw error;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"action-menu-DwCcc6Gt.js","sources":["../../src/features/interactive/action-menu.ts"],"sourcesContent":["/**\n * Action menu for interactive search mode.\n * Allows users to perform actions on selected references.\n */\n\nimport type { CslItem } from \"../../core/csl-json/types.js\";\nimport { formatBibliographyCSL, formatBibtex } from \"../format/index.js\";\n\n/**\n * Action types available in the action menu.\n */\nexport type ActionType =\n | \"output-ids\"\n | \"output-csl-json\"\n | \"output-bibtex\"\n | \"cite-apa\"\n | \"cite-choose\"\n | \"cancel\";\n\n/**\n * Result from action menu selection.\n */\nexport interface ActionMenuResult {\n /** Selected action type */\n action: ActionType;\n /** Generated output (empty for cancel) */\n output: string;\n /** Whether the prompt was cancelled */\n cancelled: boolean;\n}\n\n/**\n * Result from style selection prompt.\n */\nexport interface StyleSelectResult {\n /** Selected style (undefined if cancelled) */\n style?: string;\n /** Whether the prompt was cancelled */\n cancelled: boolean;\n}\n\n/**\n * Choice definition for Enquirer Select prompt.\n */\ninterface SelectChoice {\n name: string;\n message: string;\n value: ActionType | string;\n}\n\n/**\n * Available action choices for the action menu.\n */\nexport const ACTION_CHOICES: SelectChoice[] = [\n { name: \"output-ids\", message: \"Output IDs (citation keys)\", value: \"output-ids\" },\n { name: \"output-csl-json\", message: \"Output as CSL-JSON\", value: \"output-csl-json\" },\n { name: \"output-bibtex\", message: \"Output as BibTeX\", value: \"output-bibtex\" },\n { name: \"cite-apa\", message: \"Generate citation (APA)\", value: \"cite-apa\" },\n { name: \"cite-choose\", message: \"Generate citation (choose style)\", value: \"cite-choose\" },\n { name: \"cancel\", message: \"Cancel\", value: \"cancel\" },\n];\n\n/**\n * Available style choices for citation style selection.\n * Uses BUILTIN_STYLES from config/csl-styles.ts\n */\nexport const STYLE_CHOICES: SelectChoice[] = [\n { name: \"apa\", message: \"APA\", value: \"apa\" },\n { name: \"vancouver\", message: \"Vancouver\", value: \"vancouver\" },\n { name: \"harvard\", message: \"Harvard\", value: \"harvard\" },\n];\n\n/**\n * Run the style selection prompt.\n */\n\n/**\n * Generate output for the given action and items.\n */\nfunction generateOutput(action: ActionType, items: CslItem[], style = \"apa\"): string {\n switch (action) {\n case \"output-ids\":\n return items.map((item) => item.id).join(\"\\n\");\n\n case \"output-csl-json\":\n return JSON.stringify(items, null, 2);\n\n case \"output-bibtex\":\n return formatBibtex(items);\n\n case \"cite-apa\":\n return formatBibliographyCSL(items, { style: \"apa\" });\n\n case \"cite-choose\":\n return formatBibliographyCSL(items, { style });\n\n case \"cancel\":\n return \"\";\n\n default:\n return \"\";\n }\n}\n\n/**\n * Process the selected action and generate result.\n */\nasync function processAction(action: ActionType, items: CslItem[]): Promise<ActionMenuResult> {\n // Handle cite-choose: prompt for style first\n if (action === \"cite-choose\") {\n const styleResult = await runStyleSelectPrompt();\n if (styleResult.cancelled) {\n return {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n }\n return {\n action,\n output: generateOutput(action, items, styleResult.style),\n cancelled: false,\n };\n }\n\n // Handle cancel\n if (action === \"cancel\") {\n return {\n action,\n output: \"\",\n cancelled: true,\n };\n }\n\n // Handle other actions\n return {\n action,\n output: generateOutput(action, items),\n cancelled: false,\n };\n}\n\nexport async function runStyleSelectPrompt(): Promise<StyleSelectResult> {\n // Dynamic import to allow mocking in tests\n // enquirer is a CommonJS module, so we must use default import\n const enquirer = await import(\"enquirer\");\n const Select = (enquirer.default as unknown as Record<string, unknown>).Select as new (\n options: Record<string, unknown>\n ) => { run(): Promise<string> };\n\n const promptOptions = {\n name: \"style\",\n message: \"Select citation style:\",\n choices: STYLE_CHOICES,\n };\n\n try {\n const prompt = new Select(promptOptions);\n const result = (await prompt.run()) as string;\n\n return {\n style: result,\n cancelled: false,\n };\n } catch (error) {\n // Enquirer throws an empty string when cancelled\n if (error === \"\" || (error instanceof Error && error.message === \"\")) {\n return {\n cancelled: true,\n };\n }\n throw error;\n }\n}\n\n/**\n * Run the action menu for selected references.\n *\n * @param items - Selected references\n * @returns Action result with output\n */\nexport async function runActionMenu(items: CslItem[]): Promise<ActionMenuResult> {\n // Dynamic import to allow mocking in tests\n // enquirer is a CommonJS module, so we must use default import\n const enquirer = await import(\"enquirer\");\n const Select = (enquirer.default as unknown as Record<string, unknown>).Select as new (\n options: Record<string, unknown>\n ) => { run(): Promise<string> };\n\n const count = items.length;\n const refWord = count === 1 ? \"reference\" : \"references\";\n const message = `Action for ${count} selected ${refWord}:`;\n\n const promptOptions = {\n name: \"action\",\n message,\n choices: ACTION_CHOICES,\n };\n\n try {\n const prompt = new Select(promptOptions);\n const action = (await prompt.run()) as ActionType;\n\n return processAction(action, items);\n } catch (error) {\n // Enquirer throws an empty string when cancelled\n if (error === \"\" || (error instanceof Error && error.message === \"\")) {\n return {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n }\n throw error;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1684,30 +1684,30 @@ export {
1684
1684
  FileWatcher as F,
1685
1685
  Library as L,
1686
1686
  Reference as R,
1687
- computeHash as a,
1688
- sortResults as b,
1687
+ sortOrderSchema as a,
1688
+ sortFieldSchema as b,
1689
1689
  computeFileHash as c,
1690
- detectDuplicate as d,
1691
- CslItemSchema as e,
1692
- parseCslJson as f,
1693
- serializeCslJson as g,
1694
- generateId as h,
1695
- generateIdWithCollisionCheck as i,
1696
- normalizeText as j,
1697
- generateUuid as k,
1698
- isValidUuid as l,
1699
- ensureCustomMetadata as m,
1690
+ computeHash as d,
1691
+ sortResults as e,
1692
+ detectDuplicate as f,
1693
+ CslItemSchema as g,
1694
+ parseCslJson as h,
1695
+ serializeCslJson as i,
1696
+ generateId as j,
1697
+ generateIdWithCollisionCheck as k,
1698
+ normalizeText as l,
1699
+ generateUuid as m,
1700
1700
  normalize as n,
1701
- extractUuidFromCustom as o,
1701
+ isValidUuid as o,
1702
1702
  pickDefined as p,
1703
- sortOrderSchema as q,
1704
- paginationOptionsSchema as r,
1703
+ ensureCustomMetadata as q,
1704
+ extractUuidFromCustom as r,
1705
1705
  search as s,
1706
1706
  tokenize as t,
1707
- sortFieldSchema as u,
1708
- searchSortFieldSchema as v,
1707
+ searchSortFieldSchema as u,
1708
+ paginationOptionsSchema as v,
1709
1709
  writeCslJson as w,
1710
1710
  tokenizer as x,
1711
1711
  matcher as y
1712
1712
  };
1713
- //# sourceMappingURL=file-watcher-D2Y-SlcE.js.map
1713
+ //# sourceMappingURL=file-watcher-B_WpVHSV.js.map