@ncukondo/search-hub 0.1.1 → 0.1.2

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 (84) hide show
  1. package/dist/cli/index.js +9 -5
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/cli/utils/progress.js +3 -3
  4. package/dist/cli/utils/progress.js.map +1 -1
  5. package/dist/config/paths.js +1 -1
  6. package/dist/providers/arxiv/parser.js +1 -1
  7. package/dist/providers/pubmed/parser.js +1 -1
  8. package/package.json +1 -1
  9. package/dist/_virtual/___vite-browser-external.js +0 -7
  10. package/dist/_virtual/___vite-browser-external.js.map +0 -1
  11. package/dist/_virtual/__vite-browser-external.js +0 -5
  12. package/dist/_virtual/__vite-browser-external.js.map +0 -1
  13. package/dist/_virtual/_commonjsHelpers.js +0 -28
  14. package/dist/_virtual/_commonjsHelpers.js.map +0 -1
  15. package/dist/_virtual/cli-progress.js +0 -6
  16. package/dist/_virtual/cli-progress.js.map +0 -1
  17. package/dist/_virtual/index.js +0 -5
  18. package/dist/_virtual/index.js.map +0 -1
  19. package/dist/_virtual/index2.js +0 -5
  20. package/dist/_virtual/index2.js.map +0 -1
  21. package/dist/node_modules/cli-progress/cli-progress.js +0 -37
  22. package/dist/node_modules/cli-progress/cli-progress.js.map +0 -1
  23. package/dist/node_modules/cli-progress/lib/eta.js +0 -52
  24. package/dist/node_modules/cli-progress/lib/eta.js.map +0 -1
  25. package/dist/node_modules/cli-progress/lib/format-bar.js +0 -16
  26. package/dist/node_modules/cli-progress/lib/format-bar.js.map +0 -1
  27. package/dist/node_modules/cli-progress/lib/format-time.js +0 -32
  28. package/dist/node_modules/cli-progress/lib/format-time.js.map +0 -1
  29. package/dist/node_modules/cli-progress/lib/format-value.js +0 -25
  30. package/dist/node_modules/cli-progress/lib/format-value.js.map +0 -1
  31. package/dist/node_modules/cli-progress/lib/formatter.js +0 -57
  32. package/dist/node_modules/cli-progress/lib/formatter.js.map +0 -1
  33. package/dist/node_modules/cli-progress/lib/generic-bar.js +0 -137
  34. package/dist/node_modules/cli-progress/lib/generic-bar.js.map +0 -1
  35. package/dist/node_modules/cli-progress/lib/multi-bar.js +0 -147
  36. package/dist/node_modules/cli-progress/lib/multi-bar.js.map +0 -1
  37. package/dist/node_modules/cli-progress/lib/options.js +0 -59
  38. package/dist/node_modules/cli-progress/lib/options.js.map +0 -1
  39. package/dist/node_modules/cli-progress/lib/single-bar.js +0 -95
  40. package/dist/node_modules/cli-progress/lib/single-bar.js.map +0 -1
  41. package/dist/node_modules/cli-progress/lib/terminal.js +0 -125
  42. package/dist/node_modules/cli-progress/lib/terminal.js.map +0 -1
  43. package/dist/node_modules/cli-progress/node_modules/ansi-regex/index.js +0 -18
  44. package/dist/node_modules/cli-progress/node_modules/ansi-regex/index.js.map +0 -1
  45. package/dist/node_modules/cli-progress/node_modules/emoji-regex/index.js +0 -14
  46. package/dist/node_modules/cli-progress/node_modules/emoji-regex/index.js.map +0 -1
  47. package/dist/node_modules/cli-progress/node_modules/string-width/index.js +0 -44
  48. package/dist/node_modules/cli-progress/node_modules/string-width/index.js.map +0 -1
  49. package/dist/node_modules/cli-progress/node_modules/strip-ansi/index.js +0 -14
  50. package/dist/node_modules/cli-progress/node_modules/strip-ansi/index.js.map +0 -1
  51. package/dist/node_modules/cli-progress/presets/index.js +0 -25
  52. package/dist/node_modules/cli-progress/presets/index.js.map +0 -1
  53. package/dist/node_modules/cli-progress/presets/legacy.js +0 -16
  54. package/dist/node_modules/cli-progress/presets/legacy.js.map +0 -1
  55. package/dist/node_modules/cli-progress/presets/rect.js +0 -16
  56. package/dist/node_modules/cli-progress/presets/rect.js.map +0 -1
  57. package/dist/node_modules/cli-progress/presets/shades-classic.js +0 -16
  58. package/dist/node_modules/cli-progress/presets/shades-classic.js.map +0 -1
  59. package/dist/node_modules/cli-progress/presets/shades-grey.js +0 -16
  60. package/dist/node_modules/cli-progress/presets/shades-grey.js.map +0 -1
  61. package/dist/node_modules/env-paths/index.js +0 -58
  62. package/dist/node_modules/env-paths/index.js.map +0 -1
  63. package/dist/node_modules/fast-xml-parser/src/ignoreAttributes.js +0 -22
  64. package/dist/node_modules/fast-xml-parser/src/ignoreAttributes.js.map +0 -1
  65. package/dist/node_modules/fast-xml-parser/src/util.js +0 -33
  66. package/dist/node_modules/fast-xml-parser/src/util.js.map +0 -1
  67. package/dist/node_modules/fast-xml-parser/src/validator.js +0 -309
  68. package/dist/node_modules/fast-xml-parser/src/validator.js.map +0 -1
  69. package/dist/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js +0 -265
  70. package/dist/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js.map +0 -1
  71. package/dist/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js +0 -53
  72. package/dist/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js.map +0 -1
  73. package/dist/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js +0 -515
  74. package/dist/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js.map +0 -1
  75. package/dist/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js +0 -68
  76. package/dist/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js.map +0 -1
  77. package/dist/node_modules/fast-xml-parser/src/xmlparser/node2json.js +0 -88
  78. package/dist/node_modules/fast-xml-parser/src/xmlparser/node2json.js.map +0 -1
  79. package/dist/node_modules/fast-xml-parser/src/xmlparser/xmlNode.js +0 -36
  80. package/dist/node_modules/fast-xml-parser/src/xmlparser/xmlNode.js.map +0 -1
  81. package/dist/node_modules/is-fullwidth-code-point/index.js +0 -37
  82. package/dist/node_modules/is-fullwidth-code-point/index.js.map +0 -1
  83. package/dist/node_modules/strnum/strnum.js +0 -100
  84. package/dist/node_modules/strnum/strnum.js.map +0 -1
package/dist/cli/index.js CHANGED
@@ -625,11 +625,15 @@ async function main() {
625
625
  await program.parseAsync(process.argv);
626
626
  }
627
627
  const currentFile = fileURLToPath(import.meta.url);
628
- if (process.argv[1] === currentFile) {
629
- main().catch((error) => {
630
- console.error("Fatal error:", error);
631
- process.exit(EXIT_CODES.GENERAL_ERROR);
632
- });
628
+ const executedFile = process.argv[1];
629
+ if (executedFile) {
630
+ const { realpathSync } = await import("node:fs");
631
+ if (realpathSync(executedFile) === realpathSync(currentFile)) {
632
+ main().catch((error) => {
633
+ console.error("Fatal error:", error);
634
+ process.exit(EXIT_CODES.GENERAL_ERROR);
635
+ });
636
+ }
633
637
  }
634
638
  export {
635
639
  createProgram,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for search-hub.\n */\nimport { Command } from 'commander';\nimport { init } from './commands/init.js';\nimport { EXIT_CODES } from './exit-codes.js';\nimport { loadConfig, saveConfig, getDefaultConfig } from '../config/index.js';\nimport { getDefaultConfigPath } from '../config/paths.js';\nimport {\n viewConfig,\n viewConfigKey,\n setConfigKey,\n} from './commands/config.js';\nimport {\n validateQueryCommand,\n formatValidateResult,\n} from './commands/query/validate.js';\nimport {\n translateQueryCommand,\n formatTranslateResult,\n} from './commands/query/translate.js';\nimport type { ProviderName } from '../providers/base/types.js';\nimport {\n listSessionsForDisplay,\n getSessionDetails,\n formatSessionList,\n formatSessionDetails,\n} from './commands/status.js';\nimport {\n parseSearchOptions,\n validateSearchInput,\n formatDryRunOutput,\n} from './commands/search.js';\nimport { executeSearch } from './commands/search-executor.js';\nimport {\n parseResumeOptions,\n validateResumeInput,\n getResumableProvidersForCommand,\n} from './commands/resume.js';\nimport { executeResume } from './commands/resume-executor.js';\nimport {\n parseExportOptions,\n validateExportInput,\n formatIds,\n formatJson,\n formatJsonl,\n} from './commands/export.js';\nimport {\n parseRegisterOptions,\n validateRegisterInput,\n formatRegistrationSummary,\n formatDryRunOutput as formatRegisterDryRunOutput,\n} from './commands/register.js';\nimport { registerArticles, saveRegistrationRecord } from '../integration/register.js';\nimport { checkRefAvailable, checkNpmAvailable, installRefManager } from '../integration/ref-cli.js';\nimport { loadSession } from '../session/manager.js';\nimport { writeFile } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\nimport { getSessionsDir } from './utils/sessions-dir.js';\nimport { expandPath } from '../utils/path.js';\n\n/**\n * Global CLI options available to all commands.\n */\nexport interface GlobalOptions {\n /** Path to config file */\n config?: string;\n /** Path to session directory */\n sessionDir?: string;\n /** Enable verbose output */\n verbose: boolean;\n /** Suppress all output except errors */\n quiet: boolean;\n /** Enable color output (default: true, use --no-color to disable) */\n color: boolean;\n}\n\n/**\n * Create and configure the CLI program.\n */\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name('search-hub')\n .version('0.1.0')\n .description(\n 'CLI tool for systematic literature searching across multiple academic databases'\n )\n .option('-c, --config <path>', 'path to config file')\n .option('--session-dir <path>', 'path to session directory')\n .option('-v, --verbose', 'enable verbose output', false)\n .option('-q, --quiet', 'suppress all output except errors', false)\n .option('--no-color', 'disable color output');\n\n // Register init command\n program\n .command('init')\n .description('Initialize configuration directory')\n .option('-f, --force', 'overwrite existing configuration', false)\n .addHelpText('after', `\nExamples:\n $ search-hub init # Initialize with default settings\n $ search-hub init --force # Overwrite existing configuration`)\n .action(async (options: { force: boolean }) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n const result = await init({ force: options.force });\n if (!globalOpts.quiet) {\n if (result.success) {\n console.log(result.message);\n } else {\n console.error(result.message);\n }\n }\n process.exitCode = result.success ? EXIT_CODES.SUCCESS : EXIT_CODES.CONFIG_ERROR;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.GENERAL_ERROR;\n }\n });\n\n // Register config command\n program\n .command('config')\n .description('View and edit configuration')\n .argument('[key]', 'configuration key to view or set')\n .argument('[value]', 'value to set for the key')\n .addHelpText('after', `\nExamples:\n $ search-hub config # Show all config\n $ search-hub config providers.pubmed # Show PubMed config\n $ search-hub config providers.pubmed.api_key KEY # Set API key`)\n .action(async (key?: string, value?: string) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n // Load config - use default if no config file exists\n let config;\n try {\n config = await loadConfig(\n globalOpts.config ? { globalConfigPath: globalOpts.config } : {}\n );\n } catch {\n config = getDefaultConfig();\n }\n\n if (!key) {\n // View all config\n if (!globalOpts.quiet) {\n console.log(viewConfig(config));\n }\n } else if (!value) {\n // View specific key\n const result = viewConfigKey(config, key);\n if (result.success) {\n if (!globalOpts.quiet) {\n console.log(result.value);\n }\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.CONFIG_ERROR;\n return;\n }\n } else {\n // Set key value\n const result = setConfigKey(config, key, value);\n if (result.success) {\n // Save the modified config to file\n const configPath = globalOpts.config ? expandPath(globalOpts.config) : getDefaultConfigPath();\n try {\n await saveConfig(config, { path: configPath });\n if (!globalOpts.quiet) {\n console.log(`Set ${key} = ${result.value}`);\n console.log(`Saved to ${configPath}`);\n }\n } catch (saveError) {\n if (!globalOpts.quiet) {\n console.error(\n `Error saving config: ${saveError instanceof Error ? saveError.message : saveError}`\n );\n }\n process.exitCode = EXIT_CODES.CONFIG_ERROR;\n return;\n }\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.CONFIG_ERROR;\n return;\n }\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.CONFIG_ERROR;\n }\n });\n\n // Register query command group\n const queryCommand = program\n .command('query')\n .description('Query file utilities');\n\n queryCommand\n .command('validate')\n .description('Validate query YAML file')\n .argument('<file>', 'path to query YAML file')\n .addHelpText('after', `\nExamples:\n $ search-hub query validate ./diabetes-ai.yaml`)\n .action(async (file: string) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n const result = await validateQueryCommand(file);\n if (!globalOpts.quiet) {\n console.log(formatValidateResult(result, file));\n }\n process.exitCode = result.success\n ? EXIT_CODES.SUCCESS\n : EXIT_CODES.QUERY_ERROR;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.QUERY_ERROR;\n }\n });\n\n queryCommand\n .command('translate')\n .description('Show translated queries for each database')\n .argument('<file>', 'path to query YAML file')\n .option('--db <provider>', 'show translation for specific provider only')\n .addHelpText('after', `\nExamples:\n $ search-hub query translate ./diabetes-ai.yaml # All databases\n $ search-hub query translate ./diabetes-ai.yaml --db pubmed # PubMed only`)\n .action(async (file: string, options: { db?: string }) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n const translateOptions = options.db\n ? { providers: [options.db as ProviderName] }\n : {};\n const result = await translateQueryCommand(file, translateOptions);\n if (!globalOpts.quiet) {\n console.log(formatTranslateResult(result, file));\n }\n process.exitCode = result.success\n ? EXIT_CODES.SUCCESS\n : EXIT_CODES.QUERY_ERROR;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.QUERY_ERROR;\n }\n });\n\n // Register status command\n program\n .command('status')\n .description('Show session status and statistics')\n .argument('[session-id]', 'session ID to show details for')\n .option('--json', 'output as JSON')\n .option('--all', 'include completed sessions')\n .addHelpText('after', `\nExamples:\n $ search-hub status # List recent sessions\n $ search-hub status 20240115_diabetes-ai_a3f2 # Show session details\n $ search-hub status --json # JSON output for scripting`)\n .action(async (sessionId?: string, options?: { json?: boolean; all?: boolean }) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n const sessionsDir = await getSessionsDir(globalOpts);\n const formatOpts = { json: options?.json ?? false };\n\n if (sessionId) {\n // Show specific session details\n const result = await getSessionDetails(sessionId, sessionsDir);\n if (result.success && result.session) {\n if (!globalOpts.quiet) {\n console.log(formatSessionDetails(result.session, formatOpts));\n }\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n } else {\n // List sessions\n const listOpts = { all: options?.all ?? false };\n const sessions = await listSessionsForDisplay(sessionsDir, listOpts);\n if (!globalOpts.quiet) {\n console.log(formatSessionList(sessions, formatOpts));\n }\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n }\n });\n\n // Register search command\n program\n .command('search')\n .description('Execute search across databases')\n .argument('[query-file]', 'path to query YAML file')\n .option('--db <providers>', 'target specific database(s), comma-separated')\n .option('--query <string>', 'direct query string (requires --db)')\n .option('--name <string>', 'session name')\n .option('--max-results <n>', 'limit results per database')\n .option('--dry-run', 'show translated queries without executing')\n .option('--no-resume', 'start fresh even if session exists')\n .addHelpText('after', `\nExamples:\n $ search-hub search ./diabetes-ai.yaml # Search all databases\n $ search-hub search ./query.yaml --db pubmed,eric # Specific databases\n $ search-hub search --db pubmed --query \"diabetes[tiab]\" # Direct query\n $ search-hub search ./query.yaml --dry-run # Preview translations\n $ search-hub search ./query.yaml --max-results 100 # Limit results`)\n .action(\n async (\n queryFile?: string,\n options?: {\n db?: string;\n query?: string;\n name?: string;\n maxResults?: string;\n dryRun?: boolean;\n resume?: boolean;\n }\n ) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n // Parse and validate options\n const searchOpts = parseSearchOptions(queryFile, {\n db: options?.db,\n query: options?.query,\n name: options?.name,\n maxResults: options?.maxResults,\n dryRun: options?.dryRun,\n noResume: options?.resume === false,\n });\n\n const validation = validateSearchInput(searchOpts);\n if (!validation.valid) {\n if (!globalOpts.quiet) {\n console.error(`Error: ${validation.error}`);\n }\n process.exitCode = EXIT_CODES.GENERAL_ERROR;\n return;\n }\n\n // Handle dry-run mode\n if (searchOpts.dryRun) {\n if (searchOpts.queryFile) {\n // Translate from file\n const translateOpts = searchOpts.providers\n ? { providers: searchOpts.providers }\n : {};\n const result = await translateQueryCommand(\n searchOpts.queryFile,\n translateOpts\n );\n if (result.success && result.translations) {\n const translations = Object.entries(result.translations).map(\n ([provider, t]) => ({ provider, query: t.native })\n );\n if (!globalOpts.quiet) {\n console.log(formatDryRunOutput(translations));\n }\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.QUERY_ERROR;\n return;\n }\n } else if (searchOpts.directQuery && searchOpts.providers) {\n // Direct query\n const translations = [\n {\n provider: searchOpts.providers[0]!,\n query: searchOpts.directQuery,\n },\n ];\n if (!globalOpts.quiet) {\n console.log(formatDryRunOutput(translations));\n }\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n return;\n }\n\n // Non-dry-run: actual search execution\n const sessionsDir = await getSessionsDir(globalOpts);\n let config;\n try {\n config = await loadConfig(\n globalOpts.config ? { globalConfigPath: globalOpts.config } : {}\n );\n } catch {\n config = getDefaultConfig();\n }\n\n const showProgress = !globalOpts.quiet && process.stdout.isTTY;\n const result = await executeSearch(\n searchOpts,\n sessionsDir,\n config,\n showProgress\n );\n\n if (result.success) {\n if (!globalOpts.quiet) {\n console.log(`\\nSearch completed. Session: ${result.sessionId}`);\n if (result.results) {\n for (const [provider, stats] of Object.entries(result.results)) {\n console.log(` ${provider}: ${stats.retrieved} results`);\n }\n }\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.NETWORK_ERROR;\n }\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.GENERAL_ERROR;\n }\n }\n );\n\n // Register resume command\n program\n .command('resume')\n .description('Resume an interrupted search session')\n .argument('<session-id>', 'session ID to resume')\n .option('--db <providers>', 'resume only specific database(s)')\n .option('--retry-failed', 'retry failed databases')\n .addHelpText('after', `\nExamples:\n $ search-hub resume 20240115_diabetes-ai_a3f2 # Resume session\n $ search-hub resume SESSION_ID --retry-failed # Retry failed databases\n $ search-hub resume SESSION_ID --db scopus # Resume specific database`)\n .action(\n async (\n sessionId: string,\n options?: { db?: string; retryFailed?: boolean }\n ) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n // Parse and validate options\n const resumeOpts = parseResumeOptions(sessionId, {\n db: options?.db,\n retryFailed: options?.retryFailed,\n });\n\n const validation = validateResumeInput(resumeOpts);\n if (!validation.valid) {\n if (!globalOpts.quiet) {\n console.error(`Error: ${validation.error}`);\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n const sessionsDir = await getSessionsDir(globalOpts);\n\n // Get resumable providers\n const result = await getResumableProvidersForCommand(\n sessionId,\n sessionsDir,\n {\n providers: resumeOpts.providers,\n retryFailed: resumeOpts.retryFailed,\n }\n );\n\n if (!result.success) {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n if (!result.providers || result.providers.length === 0) {\n if (!globalOpts.quiet) {\n console.log('No providers need resuming for this session.');\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n return;\n }\n\n // Show resumable providers\n if (!globalOpts.quiet) {\n console.log(`Resuming session ${sessionId} with ${result.providers.length} provider(s):`);\n for (const p of result.providers) {\n const details = p.cursor\n ? `cursor: ${p.cursor}`\n : p.pageNumber\n ? `page: ${p.pageNumber}`\n : '';\n console.log(` - ${p.provider}: ${p.strategy}${details ? ` (${details})` : ''}`);\n }\n console.log('');\n }\n\n // Execute resume\n let config;\n try {\n config = await loadConfig(\n globalOpts.config ? { globalConfigPath: globalOpts.config } : {}\n );\n } catch {\n config = getDefaultConfig();\n }\n\n const showProgress = !globalOpts.quiet && process.stdout.isTTY;\n const execResult = await executeResume(\n resumeOpts,\n sessionsDir,\n config,\n showProgress\n );\n\n if (execResult.success) {\n if (!globalOpts.quiet) {\n console.log(`\\nResume completed. ${execResult.resumed} provider(s) resumed.`);\n if (execResult.results) {\n for (const [provider, stats] of Object.entries(execResult.results)) {\n console.log(` ${provider}: ${stats.retrieved} results`);\n }\n }\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${execResult.error}`);\n }\n process.exitCode = EXIT_CODES.NETWORK_ERROR;\n }\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n }\n }\n );\n\n // Register export command\n program\n .command('export')\n .description('Export session results to various formats')\n .argument('<session-id>', 'session ID to export')\n .option('--format <fmt>', 'output format: ids, json, jsonl', 'jsonl')\n .option('-o, --output <path>', 'output file path')\n .option('--db <providers>', 'export only specific database(s)')\n .option('--id-type <type>', 'for ids format: doi, pmid, all')\n .addHelpText('after', `\nExamples:\n $ search-hub export SESSION_ID --format ids --id-type doi # Export DOIs\n $ search-hub export SESSION_ID --format json -o results.json\n $ search-hub export SESSION_ID --db pubmed --format jsonl`)\n .action(\n async (\n sessionId: string,\n options?: {\n format?: string;\n output?: string;\n db?: string;\n idType?: string;\n }\n ) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n // Parse and validate options\n const exportOpts = parseExportOptions(sessionId, {\n format: options?.format,\n output: options?.output,\n db: options?.db,\n idType: options?.idType,\n });\n\n const validation = validateExportInput(exportOpts);\n if (!validation.valid) {\n if (!globalOpts.quiet) {\n console.error(`Error: ${validation.error}`);\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n const sessionsDir = await getSessionsDir(globalOpts);\n\n // Load session\n let session;\n try {\n session = await loadSession(sessionId, sessionsDir);\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n `Error: ${error instanceof Error ? error.message : 'Failed to load session'}`\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n // Collect articles from result files\n const { readFile } = await import('node:fs/promises');\n const { join } = await import('node:path');\n const articles: import('../providers/base/types.js').Article[] = [];\n\n // Determine which providers to export\n const providersToExport = exportOpts.providers\n ? exportOpts.providers\n : (Object.keys(session.databases) as ProviderName[]);\n\n for (const provider of providersToExport) {\n const dbStatus = session.databases[provider];\n if (!dbStatus || !dbStatus.files?.results) continue;\n\n const resultsPath = join(sessionsDir, sessionId, dbStatus.files.results);\n try {\n const content = await readFile(resultsPath, 'utf-8');\n const lines = content.trim().split('\\n').filter((line) => line);\n for (const line of lines) {\n try {\n articles.push(JSON.parse(line));\n } catch {\n // Skip invalid JSON lines\n }\n }\n } catch {\n // Results file may not exist yet\n }\n }\n\n // Format output\n let output: string;\n if (exportOpts.format === 'ids') {\n output = formatIds(articles, exportOpts.idType ?? 'all');\n } else if (exportOpts.format === 'json') {\n output = formatJson(articles);\n } else {\n output = formatJsonl(articles);\n }\n\n // Write to file or stdout\n if (exportOpts.outputPath) {\n await writeFile(exportOpts.outputPath, output, 'utf-8');\n if (!globalOpts.quiet) {\n console.log(`Exported ${articles.length} articles to ${exportOpts.outputPath}`);\n }\n } else {\n console.log(output);\n }\n\n process.exitCode = EXIT_CODES.SUCCESS;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n }\n }\n );\n\n // Register register command\n program\n .command('register')\n .description('Register results with reference-manager')\n .argument('<session-id>', 'session ID to register')\n .option('--db <providers>', 'register only specific database(s)')\n .option('--dry-run', 'show what would be registered without executing', false)\n .option('--with-abstracts', 'also update abstracts via ref update', false)\n .addHelpText('after', `\nExamples:\n $ search-hub register SESSION_ID # Register all results\n $ search-hub register SESSION_ID --with-abstracts\n $ search-hub register SESSION_ID --dry-run # Preview only`)\n .action(\n async (\n sessionId: string,\n options?: {\n db?: string;\n dryRun?: boolean;\n withAbstracts?: boolean;\n }\n ) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n // Parse and validate options\n const registerOpts = parseRegisterOptions(sessionId, {\n db: options?.db,\n dryRun: options?.dryRun,\n withAbstracts: options?.withAbstracts,\n });\n\n const validation = validateRegisterInput(registerOpts);\n if (!validation.valid) {\n if (!globalOpts.quiet) {\n console.error(`Error: ${validation.error}`);\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n // Check if ref command is available\n const refAvailable = await checkRefAvailable();\n if (!refAvailable && !registerOpts.dryRun) {\n if (!globalOpts.quiet) {\n console.error('Error: reference-manager (ref) command not found.\\n');\n console.error('reference-manager is required to register search results.');\n console.error('Would you like to install it now? (npm i -g @ncukondo/reference-manager) [Y/n]: ');\n }\n\n // For non-interactive mode, suggest installation\n const npmAvailable = await checkNpmAvailable();\n if (!npmAvailable) {\n if (!globalOpts.quiet) {\n console.error('\\nError: npm command not found.');\n console.error('Please install Node.js first: https://nodejs.org/');\n }\n process.exitCode = EXIT_CODES.GENERAL_ERROR;\n return;\n }\n\n // Try to install\n try {\n if (!globalOpts.quiet) {\n console.log('\\nInstalling reference-manager...');\n }\n await installRefManager();\n if (!globalOpts.quiet) {\n console.log('✓ reference-manager installed successfully.\\n');\n }\n } catch (installError) {\n if (!globalOpts.quiet) {\n console.error(\n `\\nFailed to install reference-manager: ${installError instanceof Error ? installError.message : 'Unknown error'}`\n );\n }\n process.exitCode = EXIT_CODES.GENERAL_ERROR;\n return;\n }\n }\n\n const sessionsDir = await getSessionsDir(globalOpts);\n\n // Load session\n let session;\n try {\n session = await loadSession(sessionId, sessionsDir);\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n `Error: ${error instanceof Error ? error.message : 'Failed to load session'}`\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n // Collect articles from result files\n const { readFile } = await import('node:fs/promises');\n const { join } = await import('node:path');\n const articles: import('../providers/base/types.js').Article[] = [];\n\n // Determine which providers to register\n const providersToRegister = registerOpts.providers\n ? registerOpts.providers\n : (Object.keys(session.databases) as ProviderName[]);\n\n for (const provider of providersToRegister) {\n const dbStatus = session.databases[provider];\n if (!dbStatus || !dbStatus.files?.results) continue;\n\n const resultsPath = join(sessionsDir, sessionId, dbStatus.files.results);\n try {\n const content = await readFile(resultsPath, 'utf-8');\n const lines = content.trim().split('\\n').filter((line) => line);\n for (const line of lines) {\n try {\n articles.push(JSON.parse(line));\n } catch {\n // Skip invalid JSON lines\n }\n }\n } catch {\n // Results file may not exist yet\n }\n }\n\n // Dry run mode\n if (registerOpts.dryRun) {\n if (!globalOpts.quiet) {\n console.log(formatRegisterDryRunOutput(articles));\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n return;\n }\n\n // Register articles\n if (!globalOpts.quiet) {\n console.log(`Registering ${articles.length} references to reference-manager...`);\n }\n\n const sessionDir = join(sessionsDir, sessionId);\n const registerOptions: import('../integration/register.js').RegisterOptions = {\n sessionId,\n sessionDir,\n withAbstracts: registerOpts.withAbstracts,\n };\n if (!globalOpts.quiet) {\n registerOptions.onProgress = (current, total) => {\n process.stdout.write(`\\rProgress: ${current}/${total}`);\n };\n }\n const record = await registerArticles(articles, registerOptions);\n\n // Save registration record\n await saveRegistrationRecord(sessionDir, record);\n\n if (!globalOpts.quiet) {\n console.log('\\n');\n console.log(formatRegistrationSummary(record.summary));\n console.log(`\\nResults saved to: ${join(sessionDir, 'registration.json')}`);\n }\n\n process.exitCode = EXIT_CODES.SUCCESS;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n }\n }\n );\n\n return program;\n}\n\n/**\n * Main entry point for CLI execution.\n */\nexport async function main(): Promise<void> {\n const program = createProgram();\n await program.parseAsync(process.argv);\n}\n\n// Run main if executed directly\nconst currentFile = fileURLToPath(import.meta.url);\nif (process.argv[1] === currentFile) {\n main().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(EXIT_CODES.GENERAL_ERROR);\n });\n}\n"],"names":["result","formatRegisterDryRunOutput"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for search-hub.\n */\nimport { Command } from 'commander';\nimport { init } from './commands/init.js';\nimport { EXIT_CODES } from './exit-codes.js';\nimport { loadConfig, saveConfig, getDefaultConfig } from '../config/index.js';\nimport { getDefaultConfigPath } from '../config/paths.js';\nimport {\n viewConfig,\n viewConfigKey,\n setConfigKey,\n} from './commands/config.js';\nimport {\n validateQueryCommand,\n formatValidateResult,\n} from './commands/query/validate.js';\nimport {\n translateQueryCommand,\n formatTranslateResult,\n} from './commands/query/translate.js';\nimport type { ProviderName } from '../providers/base/types.js';\nimport {\n listSessionsForDisplay,\n getSessionDetails,\n formatSessionList,\n formatSessionDetails,\n} from './commands/status.js';\nimport {\n parseSearchOptions,\n validateSearchInput,\n formatDryRunOutput,\n} from './commands/search.js';\nimport { executeSearch } from './commands/search-executor.js';\nimport {\n parseResumeOptions,\n validateResumeInput,\n getResumableProvidersForCommand,\n} from './commands/resume.js';\nimport { executeResume } from './commands/resume-executor.js';\nimport {\n parseExportOptions,\n validateExportInput,\n formatIds,\n formatJson,\n formatJsonl,\n} from './commands/export.js';\nimport {\n parseRegisterOptions,\n validateRegisterInput,\n formatRegistrationSummary,\n formatDryRunOutput as formatRegisterDryRunOutput,\n} from './commands/register.js';\nimport { registerArticles, saveRegistrationRecord } from '../integration/register.js';\nimport { checkRefAvailable, checkNpmAvailable, installRefManager } from '../integration/ref-cli.js';\nimport { loadSession } from '../session/manager.js';\nimport { writeFile } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\nimport { getSessionsDir } from './utils/sessions-dir.js';\nimport { expandPath } from '../utils/path.js';\n\n/**\n * Global CLI options available to all commands.\n */\nexport interface GlobalOptions {\n /** Path to config file */\n config?: string;\n /** Path to session directory */\n sessionDir?: string;\n /** Enable verbose output */\n verbose: boolean;\n /** Suppress all output except errors */\n quiet: boolean;\n /** Enable color output (default: true, use --no-color to disable) */\n color: boolean;\n}\n\n/**\n * Create and configure the CLI program.\n */\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name('search-hub')\n .version('0.1.0')\n .description(\n 'CLI tool for systematic literature searching across multiple academic databases'\n )\n .option('-c, --config <path>', 'path to config file')\n .option('--session-dir <path>', 'path to session directory')\n .option('-v, --verbose', 'enable verbose output', false)\n .option('-q, --quiet', 'suppress all output except errors', false)\n .option('--no-color', 'disable color output');\n\n // Register init command\n program\n .command('init')\n .description('Initialize configuration directory')\n .option('-f, --force', 'overwrite existing configuration', false)\n .addHelpText('after', `\nExamples:\n $ search-hub init # Initialize with default settings\n $ search-hub init --force # Overwrite existing configuration`)\n .action(async (options: { force: boolean }) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n const result = await init({ force: options.force });\n if (!globalOpts.quiet) {\n if (result.success) {\n console.log(result.message);\n } else {\n console.error(result.message);\n }\n }\n process.exitCode = result.success ? EXIT_CODES.SUCCESS : EXIT_CODES.CONFIG_ERROR;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.GENERAL_ERROR;\n }\n });\n\n // Register config command\n program\n .command('config')\n .description('View and edit configuration')\n .argument('[key]', 'configuration key to view or set')\n .argument('[value]', 'value to set for the key')\n .addHelpText('after', `\nExamples:\n $ search-hub config # Show all config\n $ search-hub config providers.pubmed # Show PubMed config\n $ search-hub config providers.pubmed.api_key KEY # Set API key`)\n .action(async (key?: string, value?: string) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n // Load config - use default if no config file exists\n let config;\n try {\n config = await loadConfig(\n globalOpts.config ? { globalConfigPath: globalOpts.config } : {}\n );\n } catch {\n config = getDefaultConfig();\n }\n\n if (!key) {\n // View all config\n if (!globalOpts.quiet) {\n console.log(viewConfig(config));\n }\n } else if (!value) {\n // View specific key\n const result = viewConfigKey(config, key);\n if (result.success) {\n if (!globalOpts.quiet) {\n console.log(result.value);\n }\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.CONFIG_ERROR;\n return;\n }\n } else {\n // Set key value\n const result = setConfigKey(config, key, value);\n if (result.success) {\n // Save the modified config to file\n const configPath = globalOpts.config ? expandPath(globalOpts.config) : getDefaultConfigPath();\n try {\n await saveConfig(config, { path: configPath });\n if (!globalOpts.quiet) {\n console.log(`Set ${key} = ${result.value}`);\n console.log(`Saved to ${configPath}`);\n }\n } catch (saveError) {\n if (!globalOpts.quiet) {\n console.error(\n `Error saving config: ${saveError instanceof Error ? saveError.message : saveError}`\n );\n }\n process.exitCode = EXIT_CODES.CONFIG_ERROR;\n return;\n }\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.CONFIG_ERROR;\n return;\n }\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.CONFIG_ERROR;\n }\n });\n\n // Register query command group\n const queryCommand = program\n .command('query')\n .description('Query file utilities');\n\n queryCommand\n .command('validate')\n .description('Validate query YAML file')\n .argument('<file>', 'path to query YAML file')\n .addHelpText('after', `\nExamples:\n $ search-hub query validate ./diabetes-ai.yaml`)\n .action(async (file: string) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n const result = await validateQueryCommand(file);\n if (!globalOpts.quiet) {\n console.log(formatValidateResult(result, file));\n }\n process.exitCode = result.success\n ? EXIT_CODES.SUCCESS\n : EXIT_CODES.QUERY_ERROR;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.QUERY_ERROR;\n }\n });\n\n queryCommand\n .command('translate')\n .description('Show translated queries for each database')\n .argument('<file>', 'path to query YAML file')\n .option('--db <provider>', 'show translation for specific provider only')\n .addHelpText('after', `\nExamples:\n $ search-hub query translate ./diabetes-ai.yaml # All databases\n $ search-hub query translate ./diabetes-ai.yaml --db pubmed # PubMed only`)\n .action(async (file: string, options: { db?: string }) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n const translateOptions = options.db\n ? { providers: [options.db as ProviderName] }\n : {};\n const result = await translateQueryCommand(file, translateOptions);\n if (!globalOpts.quiet) {\n console.log(formatTranslateResult(result, file));\n }\n process.exitCode = result.success\n ? EXIT_CODES.SUCCESS\n : EXIT_CODES.QUERY_ERROR;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.QUERY_ERROR;\n }\n });\n\n // Register status command\n program\n .command('status')\n .description('Show session status and statistics')\n .argument('[session-id]', 'session ID to show details for')\n .option('--json', 'output as JSON')\n .option('--all', 'include completed sessions')\n .addHelpText('after', `\nExamples:\n $ search-hub status # List recent sessions\n $ search-hub status 20240115_diabetes-ai_a3f2 # Show session details\n $ search-hub status --json # JSON output for scripting`)\n .action(async (sessionId?: string, options?: { json?: boolean; all?: boolean }) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n const sessionsDir = await getSessionsDir(globalOpts);\n const formatOpts = { json: options?.json ?? false };\n\n if (sessionId) {\n // Show specific session details\n const result = await getSessionDetails(sessionId, sessionsDir);\n if (result.success && result.session) {\n if (!globalOpts.quiet) {\n console.log(formatSessionDetails(result.session, formatOpts));\n }\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n } else {\n // List sessions\n const listOpts = { all: options?.all ?? false };\n const sessions = await listSessionsForDisplay(sessionsDir, listOpts);\n if (!globalOpts.quiet) {\n console.log(formatSessionList(sessions, formatOpts));\n }\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n }\n });\n\n // Register search command\n program\n .command('search')\n .description('Execute search across databases')\n .argument('[query-file]', 'path to query YAML file')\n .option('--db <providers>', 'target specific database(s), comma-separated')\n .option('--query <string>', 'direct query string (requires --db)')\n .option('--name <string>', 'session name')\n .option('--max-results <n>', 'limit results per database')\n .option('--dry-run', 'show translated queries without executing')\n .option('--no-resume', 'start fresh even if session exists')\n .addHelpText('after', `\nExamples:\n $ search-hub search ./diabetes-ai.yaml # Search all databases\n $ search-hub search ./query.yaml --db pubmed,eric # Specific databases\n $ search-hub search --db pubmed --query \"diabetes[tiab]\" # Direct query\n $ search-hub search ./query.yaml --dry-run # Preview translations\n $ search-hub search ./query.yaml --max-results 100 # Limit results`)\n .action(\n async (\n queryFile?: string,\n options?: {\n db?: string;\n query?: string;\n name?: string;\n maxResults?: string;\n dryRun?: boolean;\n resume?: boolean;\n }\n ) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n // Parse and validate options\n const searchOpts = parseSearchOptions(queryFile, {\n db: options?.db,\n query: options?.query,\n name: options?.name,\n maxResults: options?.maxResults,\n dryRun: options?.dryRun,\n noResume: options?.resume === false,\n });\n\n const validation = validateSearchInput(searchOpts);\n if (!validation.valid) {\n if (!globalOpts.quiet) {\n console.error(`Error: ${validation.error}`);\n }\n process.exitCode = EXIT_CODES.GENERAL_ERROR;\n return;\n }\n\n // Handle dry-run mode\n if (searchOpts.dryRun) {\n if (searchOpts.queryFile) {\n // Translate from file\n const translateOpts = searchOpts.providers\n ? { providers: searchOpts.providers }\n : {};\n const result = await translateQueryCommand(\n searchOpts.queryFile,\n translateOpts\n );\n if (result.success && result.translations) {\n const translations = Object.entries(result.translations).map(\n ([provider, t]) => ({ provider, query: t.native })\n );\n if (!globalOpts.quiet) {\n console.log(formatDryRunOutput(translations));\n }\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.QUERY_ERROR;\n return;\n }\n } else if (searchOpts.directQuery && searchOpts.providers) {\n // Direct query\n const translations = [\n {\n provider: searchOpts.providers[0]!,\n query: searchOpts.directQuery,\n },\n ];\n if (!globalOpts.quiet) {\n console.log(formatDryRunOutput(translations));\n }\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n return;\n }\n\n // Non-dry-run: actual search execution\n const sessionsDir = await getSessionsDir(globalOpts);\n let config;\n try {\n config = await loadConfig(\n globalOpts.config ? { globalConfigPath: globalOpts.config } : {}\n );\n } catch {\n config = getDefaultConfig();\n }\n\n const showProgress = !globalOpts.quiet && process.stdout.isTTY;\n const result = await executeSearch(\n searchOpts,\n sessionsDir,\n config,\n showProgress\n );\n\n if (result.success) {\n if (!globalOpts.quiet) {\n console.log(`\\nSearch completed. Session: ${result.sessionId}`);\n if (result.results) {\n for (const [provider, stats] of Object.entries(result.results)) {\n console.log(` ${provider}: ${stats.retrieved} results`);\n }\n }\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.NETWORK_ERROR;\n }\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.GENERAL_ERROR;\n }\n }\n );\n\n // Register resume command\n program\n .command('resume')\n .description('Resume an interrupted search session')\n .argument('<session-id>', 'session ID to resume')\n .option('--db <providers>', 'resume only specific database(s)')\n .option('--retry-failed', 'retry failed databases')\n .addHelpText('after', `\nExamples:\n $ search-hub resume 20240115_diabetes-ai_a3f2 # Resume session\n $ search-hub resume SESSION_ID --retry-failed # Retry failed databases\n $ search-hub resume SESSION_ID --db scopus # Resume specific database`)\n .action(\n async (\n sessionId: string,\n options?: { db?: string; retryFailed?: boolean }\n ) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n // Parse and validate options\n const resumeOpts = parseResumeOptions(sessionId, {\n db: options?.db,\n retryFailed: options?.retryFailed,\n });\n\n const validation = validateResumeInput(resumeOpts);\n if (!validation.valid) {\n if (!globalOpts.quiet) {\n console.error(`Error: ${validation.error}`);\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n const sessionsDir = await getSessionsDir(globalOpts);\n\n // Get resumable providers\n const result = await getResumableProvidersForCommand(\n sessionId,\n sessionsDir,\n {\n providers: resumeOpts.providers,\n retryFailed: resumeOpts.retryFailed,\n }\n );\n\n if (!result.success) {\n if (!globalOpts.quiet) {\n console.error(`Error: ${result.error}`);\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n if (!result.providers || result.providers.length === 0) {\n if (!globalOpts.quiet) {\n console.log('No providers need resuming for this session.');\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n return;\n }\n\n // Show resumable providers\n if (!globalOpts.quiet) {\n console.log(`Resuming session ${sessionId} with ${result.providers.length} provider(s):`);\n for (const p of result.providers) {\n const details = p.cursor\n ? `cursor: ${p.cursor}`\n : p.pageNumber\n ? `page: ${p.pageNumber}`\n : '';\n console.log(` - ${p.provider}: ${p.strategy}${details ? ` (${details})` : ''}`);\n }\n console.log('');\n }\n\n // Execute resume\n let config;\n try {\n config = await loadConfig(\n globalOpts.config ? { globalConfigPath: globalOpts.config } : {}\n );\n } catch {\n config = getDefaultConfig();\n }\n\n const showProgress = !globalOpts.quiet && process.stdout.isTTY;\n const execResult = await executeResume(\n resumeOpts,\n sessionsDir,\n config,\n showProgress\n );\n\n if (execResult.success) {\n if (!globalOpts.quiet) {\n console.log(`\\nResume completed. ${execResult.resumed} provider(s) resumed.`);\n if (execResult.results) {\n for (const [provider, stats] of Object.entries(execResult.results)) {\n console.log(` ${provider}: ${stats.retrieved} results`);\n }\n }\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n } else {\n if (!globalOpts.quiet) {\n console.error(`Error: ${execResult.error}`);\n }\n process.exitCode = EXIT_CODES.NETWORK_ERROR;\n }\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n }\n }\n );\n\n // Register export command\n program\n .command('export')\n .description('Export session results to various formats')\n .argument('<session-id>', 'session ID to export')\n .option('--format <fmt>', 'output format: ids, json, jsonl', 'jsonl')\n .option('-o, --output <path>', 'output file path')\n .option('--db <providers>', 'export only specific database(s)')\n .option('--id-type <type>', 'for ids format: doi, pmid, all')\n .addHelpText('after', `\nExamples:\n $ search-hub export SESSION_ID --format ids --id-type doi # Export DOIs\n $ search-hub export SESSION_ID --format json -o results.json\n $ search-hub export SESSION_ID --db pubmed --format jsonl`)\n .action(\n async (\n sessionId: string,\n options?: {\n format?: string;\n output?: string;\n db?: string;\n idType?: string;\n }\n ) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n // Parse and validate options\n const exportOpts = parseExportOptions(sessionId, {\n format: options?.format,\n output: options?.output,\n db: options?.db,\n idType: options?.idType,\n });\n\n const validation = validateExportInput(exportOpts);\n if (!validation.valid) {\n if (!globalOpts.quiet) {\n console.error(`Error: ${validation.error}`);\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n const sessionsDir = await getSessionsDir(globalOpts);\n\n // Load session\n let session;\n try {\n session = await loadSession(sessionId, sessionsDir);\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n `Error: ${error instanceof Error ? error.message : 'Failed to load session'}`\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n // Collect articles from result files\n const { readFile } = await import('node:fs/promises');\n const { join } = await import('node:path');\n const articles: import('../providers/base/types.js').Article[] = [];\n\n // Determine which providers to export\n const providersToExport = exportOpts.providers\n ? exportOpts.providers\n : (Object.keys(session.databases) as ProviderName[]);\n\n for (const provider of providersToExport) {\n const dbStatus = session.databases[provider];\n if (!dbStatus || !dbStatus.files?.results) continue;\n\n const resultsPath = join(sessionsDir, sessionId, dbStatus.files.results);\n try {\n const content = await readFile(resultsPath, 'utf-8');\n const lines = content.trim().split('\\n').filter((line) => line);\n for (const line of lines) {\n try {\n articles.push(JSON.parse(line));\n } catch {\n // Skip invalid JSON lines\n }\n }\n } catch {\n // Results file may not exist yet\n }\n }\n\n // Format output\n let output: string;\n if (exportOpts.format === 'ids') {\n output = formatIds(articles, exportOpts.idType ?? 'all');\n } else if (exportOpts.format === 'json') {\n output = formatJson(articles);\n } else {\n output = formatJsonl(articles);\n }\n\n // Write to file or stdout\n if (exportOpts.outputPath) {\n await writeFile(exportOpts.outputPath, output, 'utf-8');\n if (!globalOpts.quiet) {\n console.log(`Exported ${articles.length} articles to ${exportOpts.outputPath}`);\n }\n } else {\n console.log(output);\n }\n\n process.exitCode = EXIT_CODES.SUCCESS;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n }\n }\n );\n\n // Register register command\n program\n .command('register')\n .description('Register results with reference-manager')\n .argument('<session-id>', 'session ID to register')\n .option('--db <providers>', 'register only specific database(s)')\n .option('--dry-run', 'show what would be registered without executing', false)\n .option('--with-abstracts', 'also update abstracts via ref update', false)\n .addHelpText('after', `\nExamples:\n $ search-hub register SESSION_ID # Register all results\n $ search-hub register SESSION_ID --with-abstracts\n $ search-hub register SESSION_ID --dry-run # Preview only`)\n .action(\n async (\n sessionId: string,\n options?: {\n db?: string;\n dryRun?: boolean;\n withAbstracts?: boolean;\n }\n ) => {\n const globalOpts = program.opts() as GlobalOptions;\n try {\n // Parse and validate options\n const registerOpts = parseRegisterOptions(sessionId, {\n db: options?.db,\n dryRun: options?.dryRun,\n withAbstracts: options?.withAbstracts,\n });\n\n const validation = validateRegisterInput(registerOpts);\n if (!validation.valid) {\n if (!globalOpts.quiet) {\n console.error(`Error: ${validation.error}`);\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n // Check if ref command is available\n const refAvailable = await checkRefAvailable();\n if (!refAvailable && !registerOpts.dryRun) {\n if (!globalOpts.quiet) {\n console.error('Error: reference-manager (ref) command not found.\\n');\n console.error('reference-manager is required to register search results.');\n console.error('Would you like to install it now? (npm i -g @ncukondo/reference-manager) [Y/n]: ');\n }\n\n // For non-interactive mode, suggest installation\n const npmAvailable = await checkNpmAvailable();\n if (!npmAvailable) {\n if (!globalOpts.quiet) {\n console.error('\\nError: npm command not found.');\n console.error('Please install Node.js first: https://nodejs.org/');\n }\n process.exitCode = EXIT_CODES.GENERAL_ERROR;\n return;\n }\n\n // Try to install\n try {\n if (!globalOpts.quiet) {\n console.log('\\nInstalling reference-manager...');\n }\n await installRefManager();\n if (!globalOpts.quiet) {\n console.log('✓ reference-manager installed successfully.\\n');\n }\n } catch (installError) {\n if (!globalOpts.quiet) {\n console.error(\n `\\nFailed to install reference-manager: ${installError instanceof Error ? installError.message : 'Unknown error'}`\n );\n }\n process.exitCode = EXIT_CODES.GENERAL_ERROR;\n return;\n }\n }\n\n const sessionsDir = await getSessionsDir(globalOpts);\n\n // Load session\n let session;\n try {\n session = await loadSession(sessionId, sessionsDir);\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n `Error: ${error instanceof Error ? error.message : 'Failed to load session'}`\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n return;\n }\n\n // Collect articles from result files\n const { readFile } = await import('node:fs/promises');\n const { join } = await import('node:path');\n const articles: import('../providers/base/types.js').Article[] = [];\n\n // Determine which providers to register\n const providersToRegister = registerOpts.providers\n ? registerOpts.providers\n : (Object.keys(session.databases) as ProviderName[]);\n\n for (const provider of providersToRegister) {\n const dbStatus = session.databases[provider];\n if (!dbStatus || !dbStatus.files?.results) continue;\n\n const resultsPath = join(sessionsDir, sessionId, dbStatus.files.results);\n try {\n const content = await readFile(resultsPath, 'utf-8');\n const lines = content.trim().split('\\n').filter((line) => line);\n for (const line of lines) {\n try {\n articles.push(JSON.parse(line));\n } catch {\n // Skip invalid JSON lines\n }\n }\n } catch {\n // Results file may not exist yet\n }\n }\n\n // Dry run mode\n if (registerOpts.dryRun) {\n if (!globalOpts.quiet) {\n console.log(formatRegisterDryRunOutput(articles));\n }\n process.exitCode = EXIT_CODES.SUCCESS;\n return;\n }\n\n // Register articles\n if (!globalOpts.quiet) {\n console.log(`Registering ${articles.length} references to reference-manager...`);\n }\n\n const sessionDir = join(sessionsDir, sessionId);\n const registerOptions: import('../integration/register.js').RegisterOptions = {\n sessionId,\n sessionDir,\n withAbstracts: registerOpts.withAbstracts,\n };\n if (!globalOpts.quiet) {\n registerOptions.onProgress = (current, total) => {\n process.stdout.write(`\\rProgress: ${current}/${total}`);\n };\n }\n const record = await registerArticles(articles, registerOptions);\n\n // Save registration record\n await saveRegistrationRecord(sessionDir, record);\n\n if (!globalOpts.quiet) {\n console.log('\\n');\n console.log(formatRegistrationSummary(record.summary));\n console.log(`\\nResults saved to: ${join(sessionDir, 'registration.json')}`);\n }\n\n process.exitCode = EXIT_CODES.SUCCESS;\n } catch (error) {\n if (!globalOpts.quiet) {\n console.error(\n 'Error:',\n error instanceof Error ? error.message : error\n );\n }\n process.exitCode = EXIT_CODES.SESSION_ERROR;\n }\n }\n );\n\n return program;\n}\n\n/**\n * Main entry point for CLI execution.\n */\nexport async function main(): Promise<void> {\n const program = createProgram();\n await program.parseAsync(process.argv);\n}\n\n// Run main if executed directly\nconst currentFile = fileURLToPath(import.meta.url);\nconst executedFile = process.argv[1];\nif (executedFile) {\n const { realpathSync } = await import('node:fs');\n if (realpathSync(executedFile) === realpathSync(currentFile)) {\n main().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(EXIT_CODES.GENERAL_ERROR);\n });\n }\n}\n"],"names":["result","formatRegisterDryRunOutput"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { c as cliProgressExports } from "../../_virtual/cli-progress.js";
1
+ import { MultiBar, Presets } from "cli-progress";
2
2
  const STATUS_ICONS = {
3
3
  completed: "✓",
4
4
  // ✓
@@ -16,7 +16,7 @@ class MultiProviderProgress {
16
16
  bars;
17
17
  states;
18
18
  constructor(providers) {
19
- this.multibar = new cliProgressExports.MultiBar(
19
+ this.multibar = new MultiBar(
20
20
  {
21
21
  clearOnComplete: false,
22
22
  hideCursor: true,
@@ -26,7 +26,7 @@ class MultiProviderProgress {
26
26
  barIncompleteChar: "░"
27
27
  // ░
28
28
  },
29
- cliProgressExports.Presets.shades_classic
29
+ Presets.shades_classic
30
30
  );
31
31
  this.bars = /* @__PURE__ */ new Map();
32
32
  this.states = /* @__PURE__ */ new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"progress.js","sources":["../../../src/cli/utils/progress.ts"],"sourcesContent":["import { MultiBar, SingleBar, Presets } from 'cli-progress';\n\nexport type ProgressStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'partial';\n\nexport interface ProviderState {\n provider: string;\n current: number;\n total: number;\n status: ProgressStatus;\n error?: string;\n}\n\nconst STATUS_ICONS: Record<ProgressStatus, string> = {\n completed: '\\u2713', // ✓\n failed: '\\u2717', // ✗\n in_progress: '\\u280B', // ⠋\n pending: '\\u25FC', // ◼\n partial: '\\u26A0', // ⚠\n};\n\nexport class MultiProviderProgress {\n private multibar: MultiBar;\n private bars: Map<string, SingleBar>;\n private states: Map<string, ProviderState>;\n\n constructor(providers: string[]) {\n this.multibar = new MultiBar(\n {\n clearOnComplete: false,\n hideCursor: true,\n format: '{icon} {provider} [{bar}] {value}/{total} {statusText}',\n barCompleteChar: '\\u2588', // █\n barIncompleteChar: '\\u2591', // ░\n },\n Presets.shades_classic\n );\n\n this.bars = new Map();\n this.states = new Map();\n\n for (const provider of providers) {\n const bar = this.multibar.create(0, 0, {\n icon: STATUS_ICONS.pending,\n provider: provider.padEnd(10),\n statusText: 'waiting...',\n });\n this.bars.set(provider, bar);\n this.states.set(provider, {\n provider,\n current: 0,\n total: 0,\n status: 'pending',\n });\n }\n }\n\n update(provider: string, current: number, total: number, status: ProgressStatus): void {\n const bar = this.bars.get(provider);\n const state = this.states.get(provider);\n if (!bar || !state) return;\n\n state.current = current;\n state.total = total;\n state.status = status;\n\n bar.setTotal(total);\n bar.update(current, {\n icon: STATUS_ICONS[status],\n provider: provider.padEnd(10),\n statusText: this.getStatusText(status),\n });\n }\n\n complete(provider: string): void {\n const bar = this.bars.get(provider);\n const state = this.states.get(provider);\n if (!bar || !state) return;\n\n state.status = 'completed';\n bar.update(state.current, {\n icon: STATUS_ICONS.completed,\n provider: provider.padEnd(10),\n statusText: 'completed',\n });\n }\n\n fail(provider: string, error: string): void {\n const bar = this.bars.get(provider);\n const state = this.states.get(provider);\n if (!bar || !state) return;\n\n state.status = 'failed';\n state.error = error;\n bar.update(state.current, {\n icon: STATUS_ICONS.failed,\n provider: provider.padEnd(10),\n statusText: `failed: ${error}`,\n });\n }\n\n partial(provider: string): void {\n const bar = this.bars.get(provider);\n const state = this.states.get(provider);\n if (!bar || !state) return;\n\n state.status = 'partial';\n bar.update(state.current, {\n icon: STATUS_ICONS.partial,\n provider: provider.padEnd(10),\n statusText: 'partial',\n });\n }\n\n stop(): void {\n this.multibar.stop();\n }\n\n getState(provider: string): ProviderState | undefined {\n return this.states.get(provider);\n }\n\n getAllStates(): ProviderState[] {\n return Array.from(this.states.values());\n }\n\n static getIcon(status: ProgressStatus): string {\n return STATUS_ICONS[status];\n }\n\n private getStatusText(status: ProgressStatus): string {\n switch (status) {\n case 'completed':\n return 'completed';\n case 'failed':\n return 'failed';\n case 'in_progress':\n return '';\n case 'pending':\n return 'waiting...';\n case 'partial':\n return 'partial';\n default:\n return '';\n }\n }\n}\n"],"names":["MultiBar","Presets"],"mappings":"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"}
1
+ {"version":3,"file":"progress.js","sources":["../../../src/cli/utils/progress.ts"],"sourcesContent":["import { MultiBar, SingleBar, Presets } from 'cli-progress';\n\nexport type ProgressStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'partial';\n\nexport interface ProviderState {\n provider: string;\n current: number;\n total: number;\n status: ProgressStatus;\n error?: string;\n}\n\nconst STATUS_ICONS: Record<ProgressStatus, string> = {\n completed: '\\u2713', // ✓\n failed: '\\u2717', // ✗\n in_progress: '\\u280B', // ⠋\n pending: '\\u25FC', // ◼\n partial: '\\u26A0', // ⚠\n};\n\nexport class MultiProviderProgress {\n private multibar: MultiBar;\n private bars: Map<string, SingleBar>;\n private states: Map<string, ProviderState>;\n\n constructor(providers: string[]) {\n this.multibar = new MultiBar(\n {\n clearOnComplete: false,\n hideCursor: true,\n format: '{icon} {provider} [{bar}] {value}/{total} {statusText}',\n barCompleteChar: '\\u2588', // █\n barIncompleteChar: '\\u2591', // ░\n },\n Presets.shades_classic\n );\n\n this.bars = new Map();\n this.states = new Map();\n\n for (const provider of providers) {\n const bar = this.multibar.create(0, 0, {\n icon: STATUS_ICONS.pending,\n provider: provider.padEnd(10),\n statusText: 'waiting...',\n });\n this.bars.set(provider, bar);\n this.states.set(provider, {\n provider,\n current: 0,\n total: 0,\n status: 'pending',\n });\n }\n }\n\n update(provider: string, current: number, total: number, status: ProgressStatus): void {\n const bar = this.bars.get(provider);\n const state = this.states.get(provider);\n if (!bar || !state) return;\n\n state.current = current;\n state.total = total;\n state.status = status;\n\n bar.setTotal(total);\n bar.update(current, {\n icon: STATUS_ICONS[status],\n provider: provider.padEnd(10),\n statusText: this.getStatusText(status),\n });\n }\n\n complete(provider: string): void {\n const bar = this.bars.get(provider);\n const state = this.states.get(provider);\n if (!bar || !state) return;\n\n state.status = 'completed';\n bar.update(state.current, {\n icon: STATUS_ICONS.completed,\n provider: provider.padEnd(10),\n statusText: 'completed',\n });\n }\n\n fail(provider: string, error: string): void {\n const bar = this.bars.get(provider);\n const state = this.states.get(provider);\n if (!bar || !state) return;\n\n state.status = 'failed';\n state.error = error;\n bar.update(state.current, {\n icon: STATUS_ICONS.failed,\n provider: provider.padEnd(10),\n statusText: `failed: ${error}`,\n });\n }\n\n partial(provider: string): void {\n const bar = this.bars.get(provider);\n const state = this.states.get(provider);\n if (!bar || !state) return;\n\n state.status = 'partial';\n bar.update(state.current, {\n icon: STATUS_ICONS.partial,\n provider: provider.padEnd(10),\n statusText: 'partial',\n });\n }\n\n stop(): void {\n this.multibar.stop();\n }\n\n getState(provider: string): ProviderState | undefined {\n return this.states.get(provider);\n }\n\n getAllStates(): ProviderState[] {\n return Array.from(this.states.values());\n }\n\n static getIcon(status: ProgressStatus): string {\n return STATUS_ICONS[status];\n }\n\n private getStatusText(status: ProgressStatus): string {\n switch (status) {\n case 'completed':\n return 'completed';\n case 'failed':\n return 'failed';\n case 'in_progress':\n return '';\n case 'pending':\n return 'waiting...';\n case 'partial':\n return 'partial';\n default:\n return '';\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import envPaths from "../node_modules/env-paths/index.js";
1
+ import envPaths from "env-paths";
2
2
  import { join } from "node:path";
3
3
  const paths = envPaths("search-hub", { suffix: "" });
4
4
  function getConfigDir() {
@@ -1,4 +1,4 @@
1
- import XMLParser from "../../node_modules/fast-xml-parser/src/xmlparser/XMLParser.js";
1
+ import { XMLParser } from "fast-xml-parser";
2
2
  const parserOptions = {
3
3
  ignoreAttributes: false,
4
4
  attributeNamePrefix: "@_",
@@ -1,4 +1,4 @@
1
- import XMLParser from "../../node_modules/fast-xml-parser/src/xmlparser/XMLParser.js";
1
+ import { XMLParser } from "fast-xml-parser";
2
2
  const parser = new XMLParser({
3
3
  ignoreAttributes: false,
4
4
  attributeNamePrefix: "@_",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ncukondo/search-hub",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A CLI tool for systematic literature searching across multiple academic databases",
5
5
  "type": "module",
6
6
  "engines": {
@@ -1,7 +0,0 @@
1
- import * as __viteBrowserExternal from "./__vite-browser-external.js";
2
- import { getAugmentedNamespace } from "./_commonjsHelpers.js";
3
- const require$$3 = /* @__PURE__ */ getAugmentedNamespace(__viteBrowserExternal);
4
- export {
5
- require$$3 as default
6
- };
7
- //# sourceMappingURL=___vite-browser-external.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"___vite-browser-external.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
@@ -1,5 +0,0 @@
1
- const __viteBrowserExternal = {};
2
- export {
3
- __viteBrowserExternal as default
4
- };
5
- //# sourceMappingURL=__vite-browser-external.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"__vite-browser-external.js","sources":["../../__vite-browser-external"],"sourcesContent":["export default {}"],"names":[],"mappings":"AAAA,MAAA,wBAAe,CAAA;"}
@@ -1,28 +0,0 @@
1
- function getAugmentedNamespace(n) {
2
- if (Object.prototype.hasOwnProperty.call(n, "__esModule")) return n;
3
- var f = n.default;
4
- if (typeof f == "function") {
5
- var a = function a2() {
6
- if (this instanceof a2) {
7
- return Reflect.construct(f, arguments, this.constructor);
8
- }
9
- return f.apply(this, arguments);
10
- };
11
- a.prototype = f.prototype;
12
- } else a = {};
13
- Object.defineProperty(a, "__esModule", { value: true });
14
- Object.keys(n).forEach(function(k) {
15
- var d = Object.getOwnPropertyDescriptor(n, k);
16
- Object.defineProperty(a, k, d.get ? d : {
17
- enumerable: true,
18
- get: function() {
19
- return n[k];
20
- }
21
- });
22
- });
23
- return a;
24
- }
25
- export {
26
- getAugmentedNamespace
27
- };
28
- //# sourceMappingURL=_commonjsHelpers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_commonjsHelpers.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,6 +0,0 @@
1
- import { __require as requireCliProgress } from "../node_modules/cli-progress/cli-progress.js";
2
- var cliProgressExports = requireCliProgress();
3
- export {
4
- cliProgressExports as c
5
- };
6
- //# sourceMappingURL=cli-progress.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli-progress.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,5 +0,0 @@
1
- var stringWidth = { exports: {} };
2
- export {
3
- stringWidth as __module
4
- };
5
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,5 +0,0 @@
1
- var isFullwidthCodePoint = { exports: {} };
2
- export {
3
- isFullwidthCodePoint as __module
4
- };
5
- //# sourceMappingURL=index2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,37 +0,0 @@
1
- import { __require as requireSingleBar } from "./lib/single-bar.js";
2
- import { __require as requireMultiBar } from "./lib/multi-bar.js";
3
- import { __require as requirePresets } from "./presets/index.js";
4
- import { __require as requireFormatter } from "./lib/formatter.js";
5
- import { __require as requireFormatValue } from "./lib/format-value.js";
6
- import { __require as requireFormatBar } from "./lib/format-bar.js";
7
- import { __require as requireFormatTime } from "./lib/format-time.js";
8
- var cliProgress;
9
- var hasRequiredCliProgress;
10
- function requireCliProgress() {
11
- if (hasRequiredCliProgress) return cliProgress;
12
- hasRequiredCliProgress = 1;
13
- const _SingleBar = requireSingleBar();
14
- const _MultiBar = requireMultiBar();
15
- const _Presets = requirePresets();
16
- const _Formatter = requireFormatter();
17
- const _defaultFormatValue = requireFormatValue();
18
- const _defaultFormatBar = requireFormatBar();
19
- const _defaultFormatTime = requireFormatTime();
20
- cliProgress = {
21
- Bar: _SingleBar,
22
- SingleBar: _SingleBar,
23
- MultiBar: _MultiBar,
24
- Presets: _Presets,
25
- Format: {
26
- Formatter: _Formatter,
27
- BarFormat: _defaultFormatBar,
28
- ValueFormat: _defaultFormatValue,
29
- TimeFormat: _defaultFormatTime
30
- }
31
- };
32
- return cliProgress;
33
- }
34
- export {
35
- requireCliProgress as __require
36
- };
37
- //# sourceMappingURL=cli-progress.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli-progress.js","sources":["../../../node_modules/cli-progress/cli-progress.js"],"sourcesContent":["const _SingleBar = require('./lib/single-bar');\nconst _MultiBar = require('./lib/multi-bar');\nconst _Presets = require('./presets/index');\nconst _Formatter = require('./lib/formatter');\nconst _defaultFormatValue = require('./lib/format-value');\nconst _defaultFormatBar = require('./lib/format-bar');\nconst _defaultFormatTime = require('./lib/format-time');\n\n// sub-module access\nmodule.exports = {\n Bar: _SingleBar,\n SingleBar: _SingleBar,\n MultiBar: _MultiBar,\n Presets: _Presets,\n Format: {\n Formatter: _Formatter,\n BarFormat: _defaultFormatBar,\n ValueFormat: _defaultFormatValue,\n TimeFormat: _defaultFormatTime\n }\n};"],"names":["require$$0","require$$1","require$$2","require$$3","require$$4","require$$5","require$$6"],"mappings":";;;;;;;;;;;;AAAA,QAAM,aAAaA,iBAAA;AACnB,QAAM,YAAYC,gBAAA;AAClB,QAAM,WAAWC,eAAA;AACjB,QAAM,aAAaC,iBAAA;AACnB,QAAM,sBAAsBC,mBAAA;AAC5B,QAAM,oBAAoBC,iBAAA;AAC1B,QAAM,qBAAqBC,kBAAA;AAG3B,gBAAiB;AAAA,IACb,KAAK;AAAA,IACL,WAAW;AAAA,IACX,UAAU;AAAA,IACV,SAAS;AAAA,IACT,QAAQ;AAAA,MACJ,WAAW;AAAA,MACX,WAAW;AAAA,MACX,aAAa;AAAA,MACb,YAAY;AAAA,IACpB;AAAA;;;","x_google_ignoreList":[0]}
@@ -1,52 +0,0 @@
1
- var eta;
2
- var hasRequiredEta;
3
- function requireEta() {
4
- if (hasRequiredEta) return eta;
5
- hasRequiredEta = 1;
6
- class ETA {
7
- constructor(length, initTime, initValue) {
8
- this.etaBufferLength = length || 100;
9
- this.valueBuffer = [initValue];
10
- this.timeBuffer = [initTime];
11
- this.eta = "0";
12
- }
13
- // add new values to calculation buffer
14
- update(time, value, total) {
15
- this.valueBuffer.push(value);
16
- this.timeBuffer.push(time);
17
- this.calculate(total - value);
18
- }
19
- // fetch estimated time
20
- getTime() {
21
- return this.eta;
22
- }
23
- // eta calculation - request number of remaining events
24
- calculate(remaining) {
25
- const currentBufferSize = this.valueBuffer.length;
26
- const buffer = Math.min(this.etaBufferLength, currentBufferSize);
27
- const v_diff = this.valueBuffer[currentBufferSize - 1] - this.valueBuffer[currentBufferSize - buffer];
28
- const t_diff = this.timeBuffer[currentBufferSize - 1] - this.timeBuffer[currentBufferSize - buffer];
29
- const vt_rate = v_diff / t_diff;
30
- this.valueBuffer = this.valueBuffer.slice(-this.etaBufferLength);
31
- this.timeBuffer = this.timeBuffer.slice(-this.etaBufferLength);
32
- const eta2 = Math.ceil(remaining / vt_rate / 1e3);
33
- if (isNaN(eta2)) {
34
- this.eta = "NULL";
35
- } else if (!isFinite(eta2)) {
36
- this.eta = "INF";
37
- } else if (eta2 > 1e7) {
38
- this.eta = "INF";
39
- } else if (eta2 < 0) {
40
- this.eta = 0;
41
- } else {
42
- this.eta = eta2;
43
- }
44
- }
45
- }
46
- eta = ETA;
47
- return eta;
48
- }
49
- export {
50
- requireEta as __require
51
- };
52
- //# sourceMappingURL=eta.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eta.js","sources":["../../../../node_modules/cli-progress/lib/eta.js"],"sourcesContent":["\n// ETA calculation\nclass ETA{\n\n constructor(length, initTime, initValue){\n // size of eta buffer\n this.etaBufferLength = length || 100;\n\n // eta buffer with initial values\n this.valueBuffer = [initValue];\n this.timeBuffer = [initTime];\n\n // eta time value\n this.eta = '0';\n }\n\n // add new values to calculation buffer\n update(time, value, total){\n this.valueBuffer.push(value);\n this.timeBuffer.push(time);\n\n // trigger recalculation\n this.calculate(total-value);\n }\n\n // fetch estimated time\n getTime(){\n return this.eta;\n }\n\n // eta calculation - request number of remaining events\n calculate(remaining){\n // get number of samples in eta buffer\n const currentBufferSize = this.valueBuffer.length;\n const buffer = Math.min(this.etaBufferLength, currentBufferSize);\n\n const v_diff = this.valueBuffer[currentBufferSize - 1] - this.valueBuffer[currentBufferSize - buffer];\n const t_diff = this.timeBuffer[currentBufferSize - 1] - this.timeBuffer[currentBufferSize - buffer];\n\n // get progress per ms\n const vt_rate = v_diff/t_diff;\n\n // strip past elements\n this.valueBuffer = this.valueBuffer.slice(-this.etaBufferLength);\n this.timeBuffer = this.timeBuffer.slice(-this.etaBufferLength);\n\n // eq: vt_rate *x = total\n const eta = Math.ceil(remaining/vt_rate/1000);\n\n // check values\n if (isNaN(eta)){\n this.eta = 'NULL';\n\n // +/- Infinity --- NaN already handled\n }else if (!isFinite(eta)){\n this.eta = 'INF';\n\n // > 10M s ? - set upper display limit ~115days (1e7/60/60/24)\n }else if (eta > 1e7){\n this.eta = 'INF';\n\n // negative ?\n }else if (eta < 0){\n this.eta = 0;\n\n }else{\n // assign\n this.eta = eta;\n }\n }\n}\n\nmodule.exports = ETA;"],"names":["eta"],"mappings":";;;;;EAEA,MAAM,IAAG;AAAA,IAEL,YAAY,QAAQ,UAAU,WAAU;AAEpC,WAAK,kBAAkB,UAAU;AAGjC,WAAK,cAAc,CAAC,SAAS;AAC7B,WAAK,aAAa,CAAC,QAAQ;AAG3B,WAAK,MAAM;AAAA,IACnB;AAAA;AAAA,IAGI,OAAO,MAAM,OAAO,OAAM;AACtB,WAAK,YAAY,KAAK,KAAK;AAC3B,WAAK,WAAW,KAAK,IAAI;AAGzB,WAAK,UAAU,QAAM,KAAK;AAAA,IAClC;AAAA;AAAA,IAGI,UAAS;AACL,aAAO,KAAK;AAAA,IACpB;AAAA;AAAA,IAGI,UAAU,WAAU;AAEhB,YAAM,oBAAoB,KAAK,YAAY;AAC3C,YAAM,SAAS,KAAK,IAAI,KAAK,iBAAiB,iBAAiB;AAE/D,YAAM,SAAS,KAAK,YAAY,oBAAoB,CAAC,IAAI,KAAK,YAAY,oBAAoB,MAAM;AACpG,YAAM,SAAS,KAAK,WAAW,oBAAoB,CAAC,IAAI,KAAK,WAAW,oBAAoB,MAAM;AAGlG,YAAM,UAAU,SAAO;AAGvB,WAAK,cAAc,KAAK,YAAY,MAAM,CAAC,KAAK,eAAe;AAC/D,WAAK,aAAc,KAAK,WAAW,MAAM,CAAC,KAAK,eAAe;AAG9D,YAAMA,OAAM,KAAK,KAAK,YAAU,UAAQ,GAAI;AAG5C,UAAI,MAAMA,IAAG,GAAE;AACX,aAAK,MAAM;AAAA,MAGvB,WAAkB,CAAC,SAASA,IAAG,GAAE;AACrB,aAAK,MAAM;AAAA,MAGvB,WAAkBA,OAAM,KAAI;AAChB,aAAK,MAAM;AAAA,MAGvB,WAAkBA,OAAM,GAAE;AACd,aAAK,MAAM;AAAA,MAEvB,OAAa;AAED,aAAK,MAAMA;AAAA,MACvB;AAAA,IACA;AAAA,EACA;AAEA,QAAiB;;;","x_google_ignoreList":[0]}
@@ -1,16 +0,0 @@
1
- var formatBar;
2
- var hasRequiredFormatBar;
3
- function requireFormatBar() {
4
- if (hasRequiredFormatBar) return formatBar;
5
- hasRequiredFormatBar = 1;
6
- formatBar = function formatBar2(progress, options) {
7
- const completeSize = Math.round(progress * options.barsize);
8
- const incompleteSize = options.barsize - completeSize;
9
- return options.barCompleteString.substr(0, completeSize) + options.barGlue + options.barIncompleteString.substr(0, incompleteSize);
10
- };
11
- return formatBar;
12
- }
13
- export {
14
- requireFormatBar as __require
15
- };
16
- //# sourceMappingURL=format-bar.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"format-bar.js","sources":["../../../../node_modules/cli-progress/lib/format-bar.js"],"sourcesContent":["// format bar\nmodule.exports = function formatBar(progress, options){\n // calculate barsize\n const completeSize = Math.round(progress*options.barsize);\n const incompleteSize = options.barsize-completeSize;\n\n // generate bar string by stripping the pre-rendered strings\n return options.barCompleteString.substr(0, completeSize) +\n options.barGlue +\n options.barIncompleteString.substr(0, incompleteSize);\n}"],"names":["formatBar"],"mappings":";;;;;AACA,cAAiB,SAASA,WAAU,UAAU,SAAQ;AAElD,UAAM,eAAe,KAAK,MAAM,WAAS,QAAQ,OAAO;AACxD,UAAM,iBAAiB,QAAQ,UAAQ;AAGxC,WAAS,QAAQ,kBAAkB,OAAO,GAAG,YAAY,IAChD,QAAQ,UACR,QAAQ,oBAAoB,OAAO,GAAG,cAAc;AAAA,EAChE;;;","x_google_ignoreList":[0]}
@@ -1,32 +0,0 @@
1
- var formatTime;
2
- var hasRequiredFormatTime;
3
- function requireFormatTime() {
4
- if (hasRequiredFormatTime) return formatTime;
5
- hasRequiredFormatTime = 1;
6
- formatTime = function formatTime2(t, options, roundToMultipleOf) {
7
- function round(input) {
8
- if (roundToMultipleOf) {
9
- return roundToMultipleOf * Math.round(input / roundToMultipleOf);
10
- } else {
11
- return input;
12
- }
13
- }
14
- function autopadding(v) {
15
- return (options.autopaddingChar + v).slice(-2);
16
- }
17
- if (t > 3600) {
18
- return autopadding(Math.floor(t / 3600)) + "h" + autopadding(round(t % 3600 / 60)) + "m";
19
- } else if (t > 60) {
20
- return autopadding(Math.floor(t / 60)) + "m" + autopadding(round(t % 60)) + "s";
21
- } else if (t > 10) {
22
- return autopadding(round(t)) + "s";
23
- } else {
24
- return autopadding(t) + "s";
25
- }
26
- };
27
- return formatTime;
28
- }
29
- export {
30
- requireFormatTime as __require
31
- };
32
- //# sourceMappingURL=format-time.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"format-time.js","sources":["../../../../node_modules/cli-progress/lib/format-time.js"],"sourcesContent":["// default time format\n\n// format a number of seconds into hours and minutes as appropriate\nmodule.exports = function formatTime(t, options, roundToMultipleOf){\n function round(input) {\n if (roundToMultipleOf) {\n return roundToMultipleOf * Math.round(input / roundToMultipleOf);\n } else {\n return input\n }\n }\n\n // leading zero padding\n function autopadding(v){\n return (options.autopaddingChar + v).slice(-2);\n }\n\n // > 1h ?\n if (t > 3600) {\n return autopadding(Math.floor(t / 3600)) + 'h' + autopadding(round((t % 3600) / 60)) + 'm';\n\n // > 60s ?\n } else if (t > 60) {\n return autopadding(Math.floor(t / 60)) + 'm' + autopadding(round((t % 60))) + 's';\n\n // > 10s ?\n } else if (t > 10) {\n return autopadding(round(t)) + 's';\n\n // default: don't apply round to multiple\n }else{\n return autopadding(t) + 's';\n }\n}"],"names":["formatTime"],"mappings":";;;;;AAGA,eAAiB,SAASA,YAAW,GAAG,SAAS,mBAAkB;AAC/D,aAAS,MAAM,OAAO;AAClB,UAAI,mBAAmB;AACnB,eAAO,oBAAoB,KAAK,MAAM,QAAQ,iBAAiB;AAAA,MAC3E,OAAe;AACH,eAAO;AAAA,MACnB;AAAA,IACA;AAGI,aAAS,YAAY,GAAE;AACnB,cAAQ,QAAQ,kBAAkB,GAAG,MAAM,EAAE;AAAA,IACrD;AAGI,QAAI,IAAI,MAAM;AACV,aAAO,YAAY,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,MAAM,YAAY,MAAO,IAAI,OAAQ,EAAE,CAAC,IAAI;AAAA,IAG/F,WAAe,IAAI,IAAI;AACf,aAAO,YAAY,KAAK,MAAM,IAAI,EAAE,CAAC,IAAI,MAAM,YAAY,MAAO,IAAI,EAAE,CAAE,IAAI;AAAA,IAGtF,WAAe,IAAI,IAAI;AACf,aAAO,YAAY,MAAM,CAAC,CAAC,IAAI;AAAA,IAGvC,OAAS;AACD,aAAO,YAAY,CAAC,IAAI;AAAA,IAChC;AAAA,EACA;;;","x_google_ignoreList":[0]}