@ncukondo/reference-manager 0.13.5 → 0.14.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 (66) hide show
  1. package/README.md +96 -0
  2. package/dist/chunks/{action-menu-svBJmZdi.js → action-menu-CVSizwXm.js} +3 -3
  3. package/dist/chunks/{action-menu-svBJmZdi.js.map → action-menu-CVSizwXm.js.map} +1 -1
  4. package/dist/chunks/{index-CaAOawzv.js → index-CXoDLO8W.js} +27966 -26914
  5. package/dist/chunks/index-CXoDLO8W.js.map +1 -0
  6. package/dist/chunks/{index-4KSTJ3rp.js → index-DapYyqAC.js} +11 -7
  7. package/dist/chunks/index-DapYyqAC.js.map +1 -0
  8. package/dist/chunks/reference-select-DSVwE9iu.js +52 -0
  9. package/dist/chunks/reference-select-DSVwE9iu.js.map +1 -0
  10. package/dist/chunks/{search-prompt-Bg9usf8f.js → search-prompt-BrWpOcij.js} +34 -1
  11. package/dist/chunks/{search-prompt-Bg9usf8f.js.map → search-prompt-BrWpOcij.js.map} +1 -1
  12. package/dist/chunks/style-select-CYo0O7MZ.js +86 -0
  13. package/dist/chunks/style-select-CYo0O7MZ.js.map +1 -0
  14. package/dist/cli/commands/cite.d.ts +5 -1
  15. package/dist/cli/commands/cite.d.ts.map +1 -1
  16. package/dist/cli/commands/config.d.ts +9 -0
  17. package/dist/cli/commands/config.d.ts.map +1 -0
  18. package/dist/cli/commands/edit.d.ts +13 -1
  19. package/dist/cli/commands/edit.d.ts.map +1 -1
  20. package/dist/cli/commands/fulltext.d.ts +54 -1
  21. package/dist/cli/commands/fulltext.d.ts.map +1 -1
  22. package/dist/cli/commands/remove.d.ts +14 -1
  23. package/dist/cli/commands/remove.d.ts.map +1 -1
  24. package/dist/cli/commands/update.d.ts +18 -1
  25. package/dist/cli/commands/update.d.ts.map +1 -1
  26. package/dist/cli/completion.d.ts +8 -0
  27. package/dist/cli/completion.d.ts.map +1 -1
  28. package/dist/cli/helpers.d.ts +11 -0
  29. package/dist/cli/helpers.d.ts.map +1 -1
  30. package/dist/cli/index.d.ts.map +1 -1
  31. package/dist/cli.js +1 -3
  32. package/dist/cli.js.map +1 -1
  33. package/dist/config/env-override.d.ts +36 -0
  34. package/dist/config/env-override.d.ts.map +1 -0
  35. package/dist/config/key-parser.d.ts +46 -0
  36. package/dist/config/key-parser.d.ts.map +1 -0
  37. package/dist/config/toml-writer.d.ts +25 -0
  38. package/dist/config/toml-writer.d.ts.map +1 -0
  39. package/dist/config/value-validator.d.ts +21 -0
  40. package/dist/config/value-validator.d.ts.map +1 -0
  41. package/dist/features/config/edit.d.ts +38 -0
  42. package/dist/features/config/edit.d.ts.map +1 -0
  43. package/dist/features/config/get.d.ts +35 -0
  44. package/dist/features/config/get.d.ts.map +1 -0
  45. package/dist/features/config/list-keys.d.ts +16 -0
  46. package/dist/features/config/list-keys.d.ts.map +1 -0
  47. package/dist/features/config/path.d.ts +29 -0
  48. package/dist/features/config/path.d.ts.map +1 -0
  49. package/dist/features/config/set.d.ts +27 -0
  50. package/dist/features/config/set.d.ts.map +1 -0
  51. package/dist/features/config/show.d.ts +20 -0
  52. package/dist/features/config/show.d.ts.map +1 -0
  53. package/dist/features/config/unset.d.ts +17 -0
  54. package/dist/features/config/unset.d.ts.map +1 -0
  55. package/dist/features/config/write-target.d.ts +30 -0
  56. package/dist/features/config/write-target.d.ts.map +1 -0
  57. package/dist/features/import/importer.d.ts.map +1 -1
  58. package/dist/features/interactive/reference-select.d.ts +79 -0
  59. package/dist/features/interactive/reference-select.d.ts.map +1 -0
  60. package/dist/features/interactive/search-prompt.d.ts.map +1 -1
  61. package/dist/features/interactive/style-select.d.ts +56 -0
  62. package/dist/features/interactive/style-select.d.ts.map +1 -0
  63. package/dist/server.js +1 -1
  64. package/package.json +1 -1
  65. package/dist/chunks/index-4KSTJ3rp.js.map +0 -1
  66. package/dist/chunks/index-CaAOawzv.js.map +0 -1
package/README.md CHANGED
@@ -235,6 +235,22 @@ Completion includes:
235
235
 
236
236
  ## CLI Reference
237
237
 
238
+ ### Interactive ID Selection
239
+
240
+ When you invoke certain commands without specifying IDs in a TTY environment, an interactive search prompt appears:
241
+
242
+ ```bash
243
+ # These commands support interactive selection when ID is omitted
244
+ ref cite # Select references → generate citation
245
+ ref edit # Select references → open in editor
246
+ ref remove # Select reference → confirm deletion
247
+ ref update # Select reference → update flow
248
+ ref fulltext attach # Select reference → attach file
249
+ ref fulltext open # Select reference → open file
250
+ ```
251
+
252
+ This makes it easy to quickly find and act on references without remembering citation keys.
253
+
238
254
  ### Basic Commands
239
255
 
240
256
  ```bash
@@ -311,6 +327,15 @@ ref update smith2024 --set "abstract="
311
327
  ref cite smith2024
312
328
  ref cite smith2024 jones2023 --style apa
313
329
  ref cite smith2024 --style chicago-author-date --format html
330
+
331
+ # Interactive selection (no ID argument)
332
+ ref cite
333
+ # → Select references interactively → choose style → output citation
334
+
335
+ # Additional options
336
+ ref cite smith2024 --in-text # In-text citation: (Smith, 2024)
337
+ ref cite smith2024 --csl-file ./custom.csl # Use custom CSL file
338
+ ref cite smith2024 --locale ja-JP # Japanese locale
314
339
  ```
315
340
 
316
341
  ### Fulltext Management
@@ -341,6 +366,38 @@ ref fulltext detach smith2024 --pdf
341
366
  ref fulltext detach smith2024 --pdf --delete # Also delete the file
342
367
  ```
343
368
 
369
+ ### Edit Command
370
+
371
+ Edit references interactively using your preferred text editor:
372
+
373
+ ```bash
374
+ # Edit single reference
375
+ ref edit smith2024
376
+
377
+ # Edit multiple references
378
+ ref edit smith2024 jones2023
379
+
380
+ # Edit by UUID
381
+ ref edit --uuid 550e8400-e29b-41d4-a716-446655440000
382
+
383
+ # Edit in JSON format (default is YAML)
384
+ ref edit smith2024 --format json
385
+
386
+ # Interactive selection (no ID argument)
387
+ ref edit
388
+ ```
389
+
390
+ **Editor selection** (same as Git):
391
+ 1. `$VISUAL` environment variable
392
+ 2. `$EDITOR` environment variable
393
+ 3. Platform fallback: `vi` (Linux/macOS) or `notepad` (Windows)
394
+
395
+ **Features:**
396
+ - Opens references in YAML or JSON format
397
+ - Protected fields (uuid, timestamps, fulltext) shown as comments
398
+ - Validation with re-edit option on errors
399
+ - Date fields simplified to ISO format (`"2024-03-15"`)
400
+
344
401
  ### Output Formats
345
402
 
346
403
  | Format | Flag | Description |
@@ -493,6 +550,45 @@ auto_stop_minutes = 60
493
550
  | `REFERENCE_MANAGER_LIBRARY` | Override library file path |
494
551
  | `REFERENCE_MANAGER_FULLTEXT_DIR` | Override fulltext directory |
495
552
 
553
+ ### Config Command
554
+
555
+ Manage configuration via CLI without manually editing TOML files:
556
+
557
+ ```bash
558
+ # View all configuration
559
+ ref config show
560
+ ref config show --json # JSON format
561
+ ref config show --sources # Show where each value comes from
562
+
563
+ # Get/set individual values
564
+ ref config get citation.default_style
565
+ ref config set citation.default_style chicago-author-date
566
+ ref config set --local citation.default_style ieee # Project-local config
567
+
568
+ # Reset to default
569
+ ref config unset citation.default_style
570
+
571
+ # List all available keys
572
+ ref config list-keys
573
+
574
+ # Show config file locations
575
+ ref config path
576
+
577
+ # Open config in editor
578
+ ref config edit
579
+ ref config edit --local # Edit project-local config
580
+ ```
581
+
582
+ **Key categories:**
583
+ - `library`, `log_level` — Core settings
584
+ - `backup.*` — Backup configuration
585
+ - `server.*` — HTTP server settings
586
+ - `citation.*` — Citation defaults (style, locale, format)
587
+ - `pubmed.*` — PubMed API credentials
588
+ - `fulltext.*` — Fulltext storage
589
+ - `cli.*` — CLI behavior (limits, sorting, interactive mode)
590
+ - `mcp.*` — MCP server settings
591
+
496
592
  ## Data Format
497
593
 
498
594
  reference-manager uses [CSL-JSON](https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html) as its native format — the same format used by Pandoc, Zotero, and other academic tools.
@@ -1,5 +1,5 @@
1
- import { f as formatBibtex } from "./index-CaAOawzv.js";
2
- import { f as formatBibliographyCSL } from "./index-4KSTJ3rp.js";
1
+ import { f as formatBibtex } from "./index-CXoDLO8W.js";
2
+ import { f as formatBibliographyCSL } from "./index-DapYyqAC.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-svBJmZdi.js.map
119
+ //# sourceMappingURL=action-menu-CVSizwXm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-menu-svBJmZdi.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-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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"}