@ncukondo/reference-manager 0.14.0 → 0.15.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.
Files changed (125) hide show
  1. package/README.md +157 -13
  2. package/bin/reference-manager.js +0 -0
  3. package/dist/chunks/{action-menu-DNlpGiwS.js → action-menu-DvwR6nMj.js} +3 -3
  4. package/dist/chunks/{action-menu-DNlpGiwS.js.map → action-menu-DvwR6nMj.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-B_WCu-ZQ.js +10 -0
  8. package/dist/chunks/index-B_WCu-ZQ.js.map +1 -0
  9. package/dist/chunks/{index-UpzsmbyY.js → index-Bv5IgsL-.js} +2453 -497
  10. package/dist/chunks/index-Bv5IgsL-.js.map +1 -0
  11. package/dist/chunks/{index-4KSTJ3rp.js → index-DHgeuWGP.js} +122 -41
  12. package/dist/chunks/index-DHgeuWGP.js.map +1 -0
  13. package/dist/chunks/{loader-C1EpnyPm.js → loader-4FFB4igw.js} +66 -27
  14. package/dist/chunks/loader-4FFB4igw.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-CHjDTyq2.js → style-select-BNQHC79W.js} +2 -2
  18. package/dist/chunks/{style-select-CHjDTyq2.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/config.d.ts +9 -0
  25. package/dist/cli/commands/config.d.ts.map +1 -0
  26. package/dist/cli/commands/export.d.ts +1 -1
  27. package/dist/cli/commands/fulltext.d.ts +2 -2
  28. package/dist/cli/commands/fulltext.d.ts.map +1 -1
  29. package/dist/cli/commands/list.d.ts +2 -1
  30. package/dist/cli/commands/list.d.ts.map +1 -1
  31. package/dist/cli/commands/search.d.ts +3 -2
  32. package/dist/cli/commands/search.d.ts.map +1 -1
  33. package/dist/cli/completion.d.ts +8 -0
  34. package/dist/cli/completion.d.ts.map +1 -1
  35. package/dist/cli/index.d.ts.map +1 -1
  36. package/dist/cli/server-client.d.ts +37 -1
  37. package/dist/cli/server-client.d.ts.map +1 -1
  38. package/dist/cli.js +2 -2
  39. package/dist/config/defaults.d.ts +7 -1
  40. package/dist/config/defaults.d.ts.map +1 -1
  41. package/dist/config/env-override.d.ts +36 -0
  42. package/dist/config/env-override.d.ts.map +1 -0
  43. package/dist/config/key-parser.d.ts +46 -0
  44. package/dist/config/key-parser.d.ts.map +1 -0
  45. package/dist/config/loader.d.ts.map +1 -1
  46. package/dist/config/schema.d.ts +22 -8
  47. package/dist/config/schema.d.ts.map +1 -1
  48. package/dist/config/toml-writer.d.ts +25 -0
  49. package/dist/config/toml-writer.d.ts.map +1 -0
  50. package/dist/config/value-validator.d.ts +21 -0
  51. package/dist/config/value-validator.d.ts.map +1 -0
  52. package/dist/features/attachments/directory-manager.d.ts +40 -0
  53. package/dist/features/attachments/directory-manager.d.ts.map +1 -0
  54. package/dist/features/attachments/directory.d.ts +36 -0
  55. package/dist/features/attachments/directory.d.ts.map +1 -0
  56. package/dist/features/attachments/filename.d.ts +30 -0
  57. package/dist/features/attachments/filename.d.ts.map +1 -0
  58. package/dist/features/attachments/types.d.ts +38 -0
  59. package/dist/features/attachments/types.d.ts.map +1 -0
  60. package/dist/features/config/edit.d.ts +38 -0
  61. package/dist/features/config/edit.d.ts.map +1 -0
  62. package/dist/features/config/get.d.ts +35 -0
  63. package/dist/features/config/get.d.ts.map +1 -0
  64. package/dist/features/config/list-keys.d.ts +16 -0
  65. package/dist/features/config/list-keys.d.ts.map +1 -0
  66. package/dist/features/config/path.d.ts +29 -0
  67. package/dist/features/config/path.d.ts.map +1 -0
  68. package/dist/features/config/set.d.ts +27 -0
  69. package/dist/features/config/set.d.ts.map +1 -0
  70. package/dist/features/config/show.d.ts +20 -0
  71. package/dist/features/config/show.d.ts.map +1 -0
  72. package/dist/features/config/unset.d.ts +17 -0
  73. package/dist/features/config/unset.d.ts.map +1 -0
  74. package/dist/features/config/write-target.d.ts +30 -0
  75. package/dist/features/config/write-target.d.ts.map +1 -0
  76. package/dist/features/fulltext/manager.d.ts +1 -1
  77. package/dist/features/fulltext/manager.d.ts.map +1 -1
  78. package/dist/features/import/importer.d.ts.map +1 -1
  79. package/dist/features/interactive/tty.d.ts +2 -2
  80. package/dist/features/operations/attachments/add.d.ts +42 -0
  81. package/dist/features/operations/attachments/add.d.ts.map +1 -0
  82. package/dist/features/operations/attachments/detach.d.ts +38 -0
  83. package/dist/features/operations/attachments/detach.d.ts.map +1 -0
  84. package/dist/features/operations/attachments/get.d.ts +35 -0
  85. package/dist/features/operations/attachments/get.d.ts.map +1 -0
  86. package/dist/features/operations/attachments/index.d.ts +16 -0
  87. package/dist/features/operations/attachments/index.d.ts.map +1 -0
  88. package/dist/features/operations/attachments/list.d.ts +32 -0
  89. package/dist/features/operations/attachments/list.d.ts.map +1 -0
  90. package/dist/features/operations/attachments/open.d.ts +39 -0
  91. package/dist/features/operations/attachments/open.d.ts.map +1 -0
  92. package/dist/features/operations/attachments/sync.d.ts +50 -0
  93. package/dist/features/operations/attachments/sync.d.ts.map +1 -0
  94. package/dist/features/operations/fulltext/attach.d.ts +8 -2
  95. package/dist/features/operations/fulltext/attach.d.ts.map +1 -1
  96. package/dist/features/operations/fulltext/detach.d.ts +9 -3
  97. package/dist/features/operations/fulltext/detach.d.ts.map +1 -1
  98. package/dist/features/operations/fulltext/get.d.ts +8 -2
  99. package/dist/features/operations/fulltext/get.d.ts.map +1 -1
  100. package/dist/features/operations/fulltext/open.d.ts +8 -2
  101. package/dist/features/operations/fulltext/open.d.ts.map +1 -1
  102. package/dist/features/operations/fulltext-adapter/fulltext-adapter.d.ts +39 -0
  103. package/dist/features/operations/fulltext-adapter/fulltext-adapter.d.ts.map +1 -0
  104. package/dist/features/operations/fulltext-adapter/index.d.ts +7 -0
  105. package/dist/features/operations/fulltext-adapter/index.d.ts.map +1 -0
  106. package/dist/features/operations/index.d.ts +1 -0
  107. package/dist/features/operations/index.d.ts.map +1 -1
  108. package/dist/features/operations/library-operations.d.ts +43 -0
  109. package/dist/features/operations/library-operations.d.ts.map +1 -1
  110. package/dist/features/operations/operations-library.d.ts +7 -0
  111. package/dist/features/operations/operations-library.d.ts.map +1 -1
  112. package/dist/features/operations/remove.d.ts +1 -0
  113. package/dist/features/operations/remove.d.ts.map +1 -1
  114. package/dist/index.js +15 -15
  115. package/dist/index.js.map +1 -1
  116. package/dist/server.js +3 -3
  117. package/dist/utils/opener.d.ts +6 -1
  118. package/dist/utils/opener.d.ts.map +1 -1
  119. package/dist/utils/path.d.ts +28 -0
  120. package/dist/utils/path.d.ts.map +1 -0
  121. package/package.json +2 -1
  122. package/dist/chunks/index-4KSTJ3rp.js.map +0 -1
  123. package/dist/chunks/index-UpzsmbyY.js.map +0 -1
  124. package/dist/chunks/loader-C1EpnyPm.js.map +0 -1
  125. 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,20 +221,38 @@ 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
237
239
 
240
+ ### Interactive ID Selection
241
+
242
+ When you invoke certain commands without specifying IDs in a TTY environment, an interactive search prompt appears:
243
+
244
+ ```bash
245
+ # These commands support interactive selection when ID is omitted
246
+ ref cite # Select references → generate citation
247
+ ref edit # Select references → open in editor
248
+ ref remove # Select reference → confirm deletion
249
+ ref update # Select reference → update flow
250
+ ref fulltext attach # Select reference → attach file
251
+ ref fulltext open # Select reference → open file
252
+ ```
253
+
254
+ This makes it easy to quickly find and act on references without remembering citation keys.
255
+
238
256
  ### Basic Commands
239
257
 
240
258
  ```bash
@@ -255,16 +273,16 @@ ref search "author:jones year:2024"
255
273
  ref search "title:\"deep learning\""
256
274
 
257
275
  # Interactive search (with real-time filtering)
258
- ref search -i # Start interactive mode
259
- ref search -i "machine learning" # Pre-fill query
276
+ ref search -t # Start interactive mode
277
+ ref search -t "machine learning" # Pre-fill query
260
278
 
261
279
  # Export raw CSL-JSON (for pandoc, jq, etc.)
262
280
  ref export smith2024 # Single reference (as object)
263
281
  ref export smith2024 jones2023 # Multiple references (as array)
264
282
  ref export --all # All references
265
283
  ref export --search "author:smith" # Search results
266
- ref export smith2024 --format yaml # YAML format
267
- ref export --all --format bibtex # BibTeX format
284
+ ref export smith2024 -o yaml # YAML format
285
+ ref export --all -o bibtex # BibTeX format
268
286
 
269
287
  # Add references
270
288
  ref add paper.json # From CSL-JSON file
@@ -275,8 +293,8 @@ ref add pmid:25056061 # From PubMed ID
275
293
  ref add "ISBN:978-4-00-000000-0" # From ISBN
276
294
  cat references.json | ref add # From stdin (file content)
277
295
  echo "10.1038/nature12373" | ref add # From stdin (DOI auto-detect)
278
- echo "12345678" | ref add --format pmid # From stdin (PMID)
279
- 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)
280
298
 
281
299
  # Remove a reference
282
300
  ref remove smith2024
@@ -310,7 +328,16 @@ ref update smith2024 --set "abstract="
310
328
  # Generate citations
311
329
  ref cite smith2024
312
330
  ref cite smith2024 jones2023 --style apa
313
- ref cite smith2024 --style chicago-author-date --format html
331
+ ref cite smith2024 --style chicago-author-date -o html
332
+
333
+ # Interactive selection (no ID argument)
334
+ ref cite
335
+ # → Select references interactively → choose style → output citation
336
+
337
+ # Additional options
338
+ ref cite smith2024 --in-text # In-text citation: (Smith, 2024)
339
+ ref cite smith2024 --csl-file ./custom.csl # Use custom CSL file
340
+ ref cite smith2024 --locale ja-JP # Japanese locale
314
341
  ```
315
342
 
316
343
  ### Fulltext Management
@@ -341,6 +368,84 @@ ref fulltext detach smith2024 --pdf
341
368
  ref fulltext detach smith2024 --pdf --delete # Also delete the file
342
369
  ```
343
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
+
417
+ ### Edit Command
418
+
419
+ Edit references interactively using your preferred text editor:
420
+
421
+ ```bash
422
+ # Edit single reference
423
+ ref edit smith2024
424
+
425
+ # Edit multiple references
426
+ ref edit smith2024 jones2023
427
+
428
+ # Edit by UUID
429
+ ref edit --uuid 550e8400-e29b-41d4-a716-446655440000
430
+
431
+ # Edit in JSON format (default is YAML)
432
+ ref edit smith2024 --format json
433
+
434
+ # Interactive selection (no ID argument)
435
+ ref edit
436
+ ```
437
+
438
+ **Editor selection** (same as Git):
439
+ 1. `$VISUAL` environment variable
440
+ 2. `$EDITOR` environment variable
441
+ 3. Platform fallback: `vi` (Linux/macOS) or `notepad` (Windows)
442
+
443
+ **Features:**
444
+ - Opens references in YAML or JSON format
445
+ - Protected fields (uuid, timestamps, fulltext) shown as comments
446
+ - Validation with re-edit option on errors
447
+ - Date fields simplified to ISO format (`"2024-03-15"`)
448
+
344
449
  ### Output Formats
345
450
 
346
451
  | Format | Flag | Description |
@@ -401,8 +506,8 @@ Supported field prefixes: `id:`, `author:`, `title:`, `year:`, `doi:`, `pmid:`,
401
506
  Start an interactive search session with real-time filtering:
402
507
 
403
508
  ```bash
404
- ref search -i # Start with empty query
405
- 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
406
511
  ```
407
512
 
408
513
  **Features:**
@@ -491,7 +596,46 @@ auto_stop_minutes = 60
491
596
  | Variable | Description |
492
597
  |----------|-------------|
493
598
  | `REFERENCE_MANAGER_LIBRARY` | Override library file path |
494
- | `REFERENCE_MANAGER_FULLTEXT_DIR` | Override fulltext directory |
599
+ | `REFERENCE_MANAGER_ATTACHMENTS_DIR` | Override attachments directory |
600
+
601
+ ### Config Command
602
+
603
+ Manage configuration via CLI without manually editing TOML files:
604
+
605
+ ```bash
606
+ # View all configuration
607
+ ref config show
608
+ ref config show -o json # JSON format
609
+ ref config show --sources # Show where each value comes from
610
+
611
+ # Get/set individual values
612
+ ref config get citation.default_style
613
+ ref config set citation.default_style chicago-author-date
614
+ ref config set --local citation.default_style ieee # Project-local config
615
+
616
+ # Reset to default
617
+ ref config unset citation.default_style
618
+
619
+ # List all available keys
620
+ ref config keys
621
+
622
+ # Show config file locations
623
+ ref config path
624
+
625
+ # Open config in editor
626
+ ref config edit
627
+ ref config edit --local # Edit project-local config
628
+ ```
629
+
630
+ **Key categories:**
631
+ - `library`, `log_level` — Core settings
632
+ - `backup.*` — Backup configuration
633
+ - `server.*` — HTTP server settings
634
+ - `citation.*` — Citation defaults (style, locale, format)
635
+ - `pubmed.*` — PubMed API credentials
636
+ - `fulltext.*` — Fulltext storage
637
+ - `cli.*` — CLI behavior (limits, sorting, TUI mode)
638
+ - `mcp.*` — MCP server settings
495
639
 
496
640
  ## Data Format
497
641
 
File without changes
@@ -1,5 +1,5 @@
1
- import { f as formatBibtex } from "./index-UpzsmbyY.js";
2
- import { f as formatBibliographyCSL } from "./index-4KSTJ3rp.js";
1
+ import { f as formatBibtex } from "./index-Bv5IgsL-.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-DNlpGiwS.js.map
119
+ //# sourceMappingURL=action-menu-DvwR6nMj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-menu-DNlpGiwS.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-DvwR6nMj.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