@ncukondo/reference-manager 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/chunks/{loader-BItrdVWG.js → loader-CLCZRS4m.js} +43 -6
- package/dist/chunks/loader-CLCZRS4m.js.map +1 -0
- package/dist/cli/commands/fulltext.d.ts +20 -3
- package/dist/cli/commands/fulltext.d.ts.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli.js +111 -3
- package/dist/cli.js.map +1 -1
- package/dist/features/operations/fulltext/index.d.ts +1 -0
- package/dist/features/operations/fulltext/index.d.ts.map +1 -1
- package/dist/features/operations/fulltext/open.d.ts +36 -0
- package/dist/features/operations/fulltext/open.d.ts.map +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/opener.d.ts +13 -0
- package/dist/utils/opener.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/chunks/loader-BItrdVWG.js.map +0 -1
package/README.md
CHANGED
|
@@ -442,7 +442,7 @@ reference-manager extends CSL-JSON with a `custom` object for additional metadat
|
|
|
442
442
|
|
|
443
443
|
**Alpha** — This project is under active development. APIs and commands may change between versions.
|
|
444
444
|
|
|
445
|
-
See [ROADMAP.md](./ROADMAP.md) for development progress and planned features.
|
|
445
|
+
See [spec/tasks/ROADMAP.md](./spec/tasks/ROADMAP.md) for development progress and planned features.
|
|
446
446
|
|
|
447
447
|
## Development
|
|
448
448
|
|
|
@@ -1,9 +1,44 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
1
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
3
|
import { homedir, tmpdir } from "node:os";
|
|
3
4
|
import { join } from "node:path";
|
|
4
5
|
import { parse } from "@iarna/toml";
|
|
5
6
|
import { z } from "zod";
|
|
6
7
|
import { q as sortOrderSchema, u as sortFieldSchema } from "./file-watcher-D7oyc-9z.js";
|
|
8
|
+
function getOpenerCommand(platform) {
|
|
9
|
+
switch (platform) {
|
|
10
|
+
case "darwin":
|
|
11
|
+
return ["open"];
|
|
12
|
+
case "linux":
|
|
13
|
+
return ["xdg-open"];
|
|
14
|
+
case "win32":
|
|
15
|
+
return ["cmd", "/c", "start", ""];
|
|
16
|
+
default:
|
|
17
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function openWithSystemApp(filePath, platform = process.platform) {
|
|
21
|
+
const commandParts = getOpenerCommand(platform);
|
|
22
|
+
const [command, ...baseArgs] = commandParts;
|
|
23
|
+
const args = [...baseArgs, filePath];
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
const proc = spawn(command, args, {
|
|
26
|
+
detached: true,
|
|
27
|
+
stdio: "ignore"
|
|
28
|
+
});
|
|
29
|
+
proc.on("error", () => {
|
|
30
|
+
reject(new Error(`Failed to open file: ${filePath}`));
|
|
31
|
+
});
|
|
32
|
+
proc.on("close", (code) => {
|
|
33
|
+
if (code === 0) {
|
|
34
|
+
resolve();
|
|
35
|
+
} else {
|
|
36
|
+
reject(new Error(`Failed to open file: ${filePath}`));
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
proc.unref();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
7
42
|
const logLevelSchema = z.enum(["silent", "info", "debug"]);
|
|
8
43
|
const interactiveConfigSchema = z.object({
|
|
9
44
|
limit: z.number().int().nonnegative(),
|
|
@@ -501,17 +536,19 @@ function loadConfig(options = {}) {
|
|
|
501
536
|
}
|
|
502
537
|
}
|
|
503
538
|
export {
|
|
504
|
-
|
|
539
|
+
getDefaultBackupDirectory as a,
|
|
505
540
|
backupConfigSchema as b,
|
|
506
541
|
configSchema as c,
|
|
507
542
|
defaultConfig as d,
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
543
|
+
getDefaultCurrentDirConfigFilename as e,
|
|
544
|
+
getDefaultLibraryPath as f,
|
|
545
|
+
getOpenerCommand as g,
|
|
546
|
+
getDefaultUserConfigPath as h,
|
|
547
|
+
logLevelSchema as i,
|
|
512
548
|
loadConfig as l,
|
|
513
549
|
normalizePartialConfig as n,
|
|
550
|
+
openWithSystemApp as o,
|
|
514
551
|
partialConfigSchema as p,
|
|
515
552
|
watchConfigSchema as w
|
|
516
553
|
};
|
|
517
|
-
//# sourceMappingURL=loader-
|
|
554
|
+
//# sourceMappingURL=loader-CLCZRS4m.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader-CLCZRS4m.js","sources":["../../src/utils/opener.ts","../../src/config/schema.ts","../../src/config/defaults.ts","../../src/config/loader.ts"],"sourcesContent":["import { type ChildProcess, spawn } from \"node:child_process\";\n\n/**\n * Get the system opener command for the specified platform.\n * @param platform - The platform (darwin, linux, win32)\n * @returns The command array to execute\n */\nexport function getOpenerCommand(platform: string): string[] {\n switch (platform) {\n case \"darwin\":\n return [\"open\"];\n case \"linux\":\n return [\"xdg-open\"];\n case \"win32\":\n return [\"cmd\", \"/c\", \"start\", \"\"];\n default:\n throw new Error(`Unsupported platform: ${platform}`);\n }\n}\n\n/**\n * Open a file with the system's default application.\n * @param filePath - The path to the file to open\n * @param platform - The platform (defaults to process.platform)\n */\nexport async function openWithSystemApp(\n filePath: string,\n platform: string = process.platform\n): Promise<void> {\n const commandParts = getOpenerCommand(platform);\n const [command, ...baseArgs] = commandParts;\n const args = [...baseArgs, filePath];\n\n return new Promise((resolve, reject) => {\n const proc: ChildProcess = spawn(command as string, args, {\n detached: true,\n stdio: \"ignore\",\n });\n\n proc.on(\"error\", () => {\n reject(new Error(`Failed to open file: ${filePath}`));\n });\n\n proc.on(\"close\", (code: number | null) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`Failed to open file: ${filePath}`));\n }\n });\n\n proc.unref();\n });\n}\n","/**\n * Configuration schema using Zod\n */\n\nimport { z } from \"zod\";\nimport { sortFieldSchema, sortOrderSchema } from \"../features/pagination/types.js\";\n\n/**\n * Log level schema\n */\nexport const logLevelSchema = z.enum([\"silent\", \"info\", \"debug\"]);\n\n/**\n * Interactive search configuration schema\n */\nexport const interactiveConfigSchema = z.object({\n limit: z.number().int().nonnegative(),\n debounceMs: z.number().int().nonnegative(),\n});\n\n/**\n * CLI configuration schema\n */\nexport const cliConfigSchema = z.object({\n defaultLimit: z.number().int().nonnegative(),\n defaultSort: sortFieldSchema,\n defaultOrder: sortOrderSchema,\n interactive: interactiveConfigSchema,\n});\n\n/**\n * MCP configuration schema\n */\nexport const mcpConfigSchema = z.object({\n defaultLimit: z.number().int().nonnegative(),\n});\n\n/**\n * Backup configuration schema\n */\nexport const backupConfigSchema = z.object({\n maxGenerations: z.number().int().positive(),\n maxAgeDays: z.number().int().positive(),\n directory: z.string().min(1),\n});\n\n/**\n * File watching configuration schema\n * Note: File watching is always enabled in server mode (HTTP/MCP).\n * CLI mode does not use file watching.\n */\nexport const watchConfigSchema = z.object({\n debounceMs: z.number().int().nonnegative(),\n pollIntervalMs: z.number().int().positive(),\n retryIntervalMs: z.number().int().positive(),\n maxRetries: z.number().int().nonnegative(),\n});\n\n/**\n * Server configuration schema\n */\nexport const serverConfigSchema = z.object({\n autoStart: z.boolean(),\n autoStopMinutes: z.number().int().nonnegative(),\n});\n\n/**\n * Citation format schema\n */\nexport const citationFormatSchema = z.enum([\"text\", \"html\", \"rtf\"]);\n\n/**\n * Citation configuration schema\n */\nexport const citationConfigSchema = z.object({\n defaultStyle: z.string(),\n cslDirectory: z.array(z.string()),\n defaultLocale: z.string(),\n defaultFormat: citationFormatSchema,\n});\n\n/**\n * PubMed API configuration schema\n */\nexport const pubmedConfigSchema = z.object({\n email: z.string().optional(),\n apiKey: z.string().optional(),\n});\n\n/**\n * Fulltext storage configuration schema\n */\nexport const fulltextConfigSchema = z.object({\n directory: z.string().min(1),\n});\n\n/**\n * Complete configuration schema\n */\nexport const configSchema = z.object({\n library: z.string().min(1),\n logLevel: logLevelSchema,\n backup: backupConfigSchema,\n watch: watchConfigSchema,\n server: serverConfigSchema,\n citation: citationConfigSchema,\n pubmed: pubmedConfigSchema,\n fulltext: fulltextConfigSchema,\n cli: cliConfigSchema,\n mcp: mcpConfigSchema,\n});\n\n/**\n * Partial configuration schema (for TOML files)\n * Supports both camelCase and snake_case field names\n */\nexport const partialConfigSchema = z\n .object({\n library: z.string().min(1).optional(),\n logLevel: logLevelSchema.optional(),\n log_level: logLevelSchema.optional(), // snake_case support\n backup: z\n .object({\n maxGenerations: z.number().int().positive().optional(),\n max_generations: z.number().int().positive().optional(),\n maxAgeDays: z.number().int().positive().optional(),\n max_age_days: z.number().int().positive().optional(),\n directory: z.string().min(1).optional(),\n })\n .optional(),\n watch: z\n .object({\n debounceMs: z.number().int().nonnegative().optional(),\n debounce_ms: z.number().int().nonnegative().optional(),\n pollIntervalMs: z.number().int().positive().optional(),\n poll_interval_ms: z.number().int().positive().optional(),\n retryIntervalMs: z.number().int().positive().optional(),\n retry_interval_ms: z.number().int().positive().optional(),\n maxRetries: z.number().int().nonnegative().optional(),\n max_retries: z.number().int().nonnegative().optional(),\n })\n .optional(),\n server: z\n .object({\n autoStart: z.boolean().optional(),\n auto_start: z.boolean().optional(),\n autoStopMinutes: z.number().int().nonnegative().optional(),\n auto_stop_minutes: z.number().int().nonnegative().optional(),\n })\n .optional(),\n citation: z\n .object({\n defaultStyle: z.string().optional(),\n default_style: z.string().optional(),\n cslDirectory: z.union([z.string(), z.array(z.string())]).optional(),\n csl_directory: z.union([z.string(), z.array(z.string())]).optional(),\n defaultLocale: z.string().optional(),\n default_locale: z.string().optional(),\n defaultFormat: citationFormatSchema.optional(),\n default_format: citationFormatSchema.optional(),\n })\n .optional(),\n pubmed: z\n .object({\n email: z.string().optional(),\n apiKey: z.string().optional(),\n api_key: z.string().optional(),\n })\n .optional(),\n fulltext: z\n .object({\n directory: z.string().min(1).optional(),\n })\n .optional(),\n cli: z\n .object({\n defaultLimit: z.number().int().nonnegative().optional(),\n default_limit: z.number().int().nonnegative().optional(),\n defaultSort: sortFieldSchema.optional(),\n default_sort: sortFieldSchema.optional(),\n defaultOrder: sortOrderSchema.optional(),\n default_order: sortOrderSchema.optional(),\n interactive: z\n .object({\n limit: z.number().int().nonnegative().optional(),\n debounceMs: z.number().int().nonnegative().optional(),\n debounce_ms: z.number().int().nonnegative().optional(),\n })\n .optional(),\n })\n .optional(),\n mcp: z\n .object({\n defaultLimit: z.number().int().nonnegative().optional(),\n default_limit: z.number().int().nonnegative().optional(),\n })\n .optional(),\n })\n .passthrough(); // Allow unknown fields in TOML files\n\n/**\n * Inferred types from schemas\n */\nexport type LogLevel = z.infer<typeof logLevelSchema>;\nexport type BackupConfig = z.infer<typeof backupConfigSchema>;\nexport type WatchConfig = z.infer<typeof watchConfigSchema>;\nexport type ServerConfig = z.infer<typeof serverConfigSchema>;\nexport type CitationFormat = z.infer<typeof citationFormatSchema>;\nexport type CitationConfig = z.infer<typeof citationConfigSchema>;\nexport type PubmedConfig = z.infer<typeof pubmedConfigSchema>;\nexport type FulltextConfig = z.infer<typeof fulltextConfigSchema>;\nexport type InteractiveConfig = z.infer<typeof interactiveConfigSchema>;\nexport type CliConfig = z.infer<typeof cliConfigSchema>;\nexport type McpConfig = z.infer<typeof mcpConfigSchema>;\nexport type Config = z.infer<typeof configSchema>;\nexport type PartialConfig = z.infer<typeof partialConfigSchema>;\n\n/**\n * Deep partial type for Config\n */\nexport type DeepPartialConfig = {\n library?: string;\n logLevel?: LogLevel;\n backup?: Partial<BackupConfig>;\n watch?: Partial<WatchConfig>;\n server?: Partial<ServerConfig>;\n citation?: Partial<CitationConfig>;\n pubmed?: Partial<PubmedConfig>;\n fulltext?: Partial<FulltextConfig>;\n cli?: Partial<Omit<CliConfig, \"interactive\">> & {\n interactive?: Partial<InteractiveConfig>;\n };\n mcp?: Partial<McpConfig>;\n};\n\n/**\n * Normalize backup configuration from snake_case to camelCase\n */\nfunction normalizeBackupConfig(\n backup: Partial<{\n maxGenerations?: number;\n max_generations?: number;\n maxAgeDays?: number;\n max_age_days?: number;\n directory?: string;\n }>\n): Partial<BackupConfig> | undefined {\n const normalized: Partial<BackupConfig> = {};\n\n const maxGenerations = backup.maxGenerations ?? backup.max_generations;\n if (maxGenerations !== undefined) {\n normalized.maxGenerations = maxGenerations;\n }\n\n const maxAgeDays = backup.maxAgeDays ?? backup.max_age_days;\n if (maxAgeDays !== undefined) {\n normalized.maxAgeDays = maxAgeDays;\n }\n\n if (backup.directory !== undefined) {\n normalized.directory = backup.directory;\n }\n\n return Object.keys(normalized).length > 0 ? normalized : undefined;\n}\n\n/**\n * Normalize watch configuration from snake_case to camelCase\n */\nfunction normalizeWatchConfig(\n watch: Partial<{\n debounceMs?: number;\n debounce_ms?: number;\n pollIntervalMs?: number;\n poll_interval_ms?: number;\n retryIntervalMs?: number;\n retry_interval_ms?: number;\n maxRetries?: number;\n max_retries?: number;\n }>\n): Partial<WatchConfig> | undefined {\n const normalized: Partial<WatchConfig> = {};\n\n const debounceMs = watch.debounceMs ?? watch.debounce_ms;\n if (debounceMs !== undefined) {\n normalized.debounceMs = debounceMs;\n }\n\n const pollIntervalMs = watch.pollIntervalMs ?? watch.poll_interval_ms;\n if (pollIntervalMs !== undefined) {\n normalized.pollIntervalMs = pollIntervalMs;\n }\n\n const retryIntervalMs = watch.retryIntervalMs ?? watch.retry_interval_ms;\n if (retryIntervalMs !== undefined) {\n normalized.retryIntervalMs = retryIntervalMs;\n }\n\n const maxRetries = watch.maxRetries ?? watch.max_retries;\n if (maxRetries !== undefined) {\n normalized.maxRetries = maxRetries;\n }\n\n return Object.keys(normalized).length > 0 ? normalized : undefined;\n}\n\n/**\n * Normalize server configuration from snake_case to camelCase\n */\nfunction normalizeServerConfig(\n server: Partial<{\n autoStart?: boolean;\n auto_start?: boolean;\n autoStopMinutes?: number;\n auto_stop_minutes?: number;\n }>\n): Partial<ServerConfig> | undefined {\n const normalized: Partial<ServerConfig> = {};\n\n const autoStart = server.autoStart ?? server.auto_start;\n if (autoStart !== undefined) {\n normalized.autoStart = autoStart;\n }\n\n const autoStopMinutes = server.autoStopMinutes ?? server.auto_stop_minutes;\n if (autoStopMinutes !== undefined) {\n normalized.autoStopMinutes = autoStopMinutes;\n }\n\n return Object.keys(normalized).length > 0 ? normalized : undefined;\n}\n\n/**\n * Normalize citation configuration from snake_case to camelCase\n */\nfunction normalizeCitationConfig(\n citation: Partial<{\n defaultStyle?: string;\n default_style?: string;\n cslDirectory?: string | string[];\n csl_directory?: string | string[];\n defaultLocale?: string;\n default_locale?: string;\n defaultFormat?: CitationFormat;\n default_format?: CitationFormat;\n }>\n): Partial<CitationConfig> | undefined {\n const normalized: Partial<CitationConfig> = {};\n\n const defaultStyle = citation.defaultStyle ?? citation.default_style;\n if (defaultStyle !== undefined) {\n normalized.defaultStyle = defaultStyle;\n }\n\n const cslDirectory = citation.cslDirectory ?? citation.csl_directory;\n if (cslDirectory !== undefined) {\n // Normalize to array: string -> [string]\n normalized.cslDirectory = Array.isArray(cslDirectory) ? cslDirectory : [cslDirectory];\n }\n\n const defaultLocale = citation.defaultLocale ?? citation.default_locale;\n if (defaultLocale !== undefined) {\n normalized.defaultLocale = defaultLocale;\n }\n\n const defaultFormat = citation.defaultFormat ?? citation.default_format;\n if (defaultFormat !== undefined) {\n normalized.defaultFormat = defaultFormat;\n }\n\n return Object.keys(normalized).length > 0 ? normalized : undefined;\n}\n\n/**\n * Normalize pubmed configuration from snake_case to camelCase\n */\nfunction normalizePubmedConfig(\n pubmed: Partial<{\n email?: string;\n apiKey?: string;\n api_key?: string;\n }>\n): Partial<PubmedConfig> | undefined {\n const normalized: Partial<PubmedConfig> = {};\n\n if (pubmed.email !== undefined) {\n normalized.email = pubmed.email;\n }\n\n const apiKey = pubmed.apiKey ?? pubmed.api_key;\n if (apiKey !== undefined) {\n normalized.apiKey = apiKey;\n }\n\n return Object.keys(normalized).length > 0 ? normalized : undefined;\n}\n\n/**\n * Section normalizers mapping\n */\nconst sectionNormalizers = {\n backup: normalizeBackupConfig,\n watch: normalizeWatchConfig,\n server: normalizeServerConfig,\n citation: normalizeCitationConfig,\n pubmed: normalizePubmedConfig,\n fulltext: normalizeFulltextConfig,\n cli: normalizeCliConfig,\n mcp: normalizeMcpConfig,\n} as const;\n\ntype SectionKey = keyof typeof sectionNormalizers;\n\n/**\n * Helper to apply a normalizer function to a config section\n */\nfunction applyNormalizer<K extends SectionKey>(\n normalized: DeepPartialConfig,\n partial: PartialConfig,\n key: K,\n normalizer: (typeof sectionNormalizers)[K]\n): void {\n const value = partial[key];\n if (value !== undefined) {\n const result = (normalizer as (input: unknown) => DeepPartialConfig[K] | undefined)(value);\n if (result) {\n normalized[key] = result;\n }\n }\n}\n\n/**\n * Normalize snake_case fields to camelCase\n */\nexport function normalizePartialConfig(partial: PartialConfig): DeepPartialConfig {\n const normalized: DeepPartialConfig = {};\n\n // Simple fields\n if (partial.library !== undefined) {\n normalized.library = partial.library;\n }\n const logLevel = partial.logLevel ?? partial.log_level;\n if (logLevel !== undefined) {\n normalized.logLevel = logLevel;\n }\n\n // Section fields\n for (const key of Object.keys(sectionNormalizers) as SectionKey[]) {\n applyNormalizer(normalized, partial, key, sectionNormalizers[key]);\n }\n\n return normalized;\n}\n\n/**\n * Normalize fulltext configuration\n */\nfunction normalizeFulltextConfig(fulltext: {\n directory?: string | undefined;\n}): Partial<FulltextConfig> | undefined {\n const normalized: Partial<FulltextConfig> = {};\n\n if (fulltext.directory !== undefined) {\n normalized.directory = fulltext.directory;\n }\n\n return Object.keys(normalized).length > 0 ? normalized : undefined;\n}\n\n/**\n * Normalize CLI configuration from snake_case to camelCase\n */\nfunction normalizeCliConfig(\n cli: Partial<{\n defaultLimit?: number;\n default_limit?: number;\n defaultSort?: CliConfig[\"defaultSort\"];\n default_sort?: CliConfig[\"defaultSort\"];\n defaultOrder?: CliConfig[\"defaultOrder\"];\n default_order?: CliConfig[\"defaultOrder\"];\n interactive?: Partial<{\n limit?: number;\n debounceMs?: number;\n debounce_ms?: number;\n }>;\n }>\n): Partial<CliConfig> | undefined {\n const normalized: Partial<CliConfig> = {};\n\n const defaultLimit = cli.defaultLimit ?? cli.default_limit;\n if (defaultLimit !== undefined) {\n normalized.defaultLimit = defaultLimit;\n }\n\n const defaultSort = cli.defaultSort ?? cli.default_sort;\n if (defaultSort !== undefined) {\n normalized.defaultSort = defaultSort;\n }\n\n const defaultOrder = cli.defaultOrder ?? cli.default_order;\n if (defaultOrder !== undefined) {\n normalized.defaultOrder = defaultOrder;\n }\n\n if (cli.interactive !== undefined) {\n const interactive: Partial<InteractiveConfig> = {};\n if (cli.interactive.limit !== undefined) {\n interactive.limit = cli.interactive.limit;\n }\n const debounceMs = cli.interactive.debounceMs ?? cli.interactive.debounce_ms;\n if (debounceMs !== undefined) {\n interactive.debounceMs = debounceMs;\n }\n if (Object.keys(interactive).length > 0) {\n normalized.interactive = interactive as InteractiveConfig;\n }\n }\n\n return Object.keys(normalized).length > 0 ? normalized : undefined;\n}\n\n/**\n * Normalize MCP configuration from snake_case to camelCase\n */\nfunction normalizeMcpConfig(\n mcp: Partial<{\n defaultLimit?: number;\n default_limit?: number;\n }>\n): Partial<McpConfig> | undefined {\n const normalized: Partial<McpConfig> = {};\n\n const defaultLimit = mcp.defaultLimit ?? mcp.default_limit;\n if (defaultLimit !== undefined) {\n normalized.defaultLimit = defaultLimit;\n }\n\n return Object.keys(normalized).length > 0 ? normalized : undefined;\n}\n","/**\n * Default configuration values\n */\n\nimport { tmpdir } from \"node:os\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Config } from \"./schema.js\";\n\n/**\n * Get the default backup directory\n * Uses $TMPDIR/reference-manager/backups/\n */\nexport function getDefaultBackupDirectory(): string {\n return join(tmpdir(), \"reference-manager\", \"backups\");\n}\n\n/**\n * Get the default library path\n * Uses ~/.reference-manager/csl.library.json\n */\nexport function getDefaultLibraryPath(): string {\n return join(homedir(), \".reference-manager\", \"csl.library.json\");\n}\n\n/**\n * Get the default user config path\n * Uses ~/.reference-manager/config.toml\n */\nexport function getDefaultUserConfigPath(): string {\n return join(homedir(), \".reference-manager\", \"config.toml\");\n}\n\n/**\n * Get the default current directory config filename\n * Uses .reference-manager.config.toml\n */\nexport function getDefaultCurrentDirConfigFilename(): string {\n return \".reference-manager.config.toml\";\n}\n\n/**\n * Get the default CSL directory\n * Uses ~/.reference-manager/csl/\n */\nexport function getDefaultCslDirectory(): string {\n return join(homedir(), \".reference-manager\", \"csl\");\n}\n\n/**\n * Get the default fulltext directory\n * Uses ~/.reference-manager/fulltext/\n */\nexport function getDefaultFulltextDirectory(): string {\n return join(homedir(), \".reference-manager\", \"fulltext\");\n}\n\n/**\n * Default configuration\n */\nexport const defaultConfig: Config = {\n library: getDefaultLibraryPath(),\n logLevel: \"info\",\n backup: {\n maxGenerations: 50,\n maxAgeDays: 365,\n directory: getDefaultBackupDirectory(),\n },\n watch: {\n debounceMs: 500,\n pollIntervalMs: 5000,\n retryIntervalMs: 200,\n maxRetries: 10,\n },\n server: {\n autoStart: false,\n autoStopMinutes: 0,\n },\n citation: {\n defaultStyle: \"apa\",\n cslDirectory: [getDefaultCslDirectory()],\n defaultLocale: \"en-US\",\n defaultFormat: \"text\",\n },\n pubmed: {\n email: undefined,\n apiKey: undefined,\n },\n fulltext: {\n directory: getDefaultFulltextDirectory(),\n },\n cli: {\n defaultLimit: 0,\n defaultSort: \"updated\",\n defaultOrder: \"desc\",\n interactive: {\n limit: 20,\n debounceMs: 200,\n },\n },\n mcp: {\n defaultLimit: 20,\n },\n};\n","/**\n * Configuration loader\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { parse as parseTOML } from \"@iarna/toml\";\nimport {\n defaultConfig,\n getDefaultCurrentDirConfigFilename,\n getDefaultUserConfigPath,\n} from \"./defaults.js\";\nimport {\n type Config,\n type DeepPartialConfig,\n type PartialConfig,\n configSchema,\n normalizePartialConfig,\n partialConfigSchema,\n} from \"./schema.js\";\n\n/**\n * Options for loading configuration\n */\nexport interface LoadConfigOptions {\n /** Current working directory (default: process.cwd()) */\n cwd?: string;\n /** User config path (default: ~/.reference-manager/config.toml) */\n userConfigPath?: string;\n /** CLI argument overrides */\n overrides?: Partial<Config>;\n}\n\n/**\n * Load and parse a TOML config file\n */\nfunction loadTOMLFile(path: string): PartialConfig | null {\n if (!existsSync(path)) {\n return null;\n }\n\n try {\n const content = readFileSync(path, \"utf-8\");\n const parsed = parseTOML(content);\n\n // Validate with partial schema\n const validated = partialConfigSchema.parse(parsed);\n return validated;\n } catch (error) {\n throw new Error(\n `Failed to load config from ${path}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Merge CLI config with nested interactive section\n */\nfunction mergeCliConfig(\n base: DeepPartialConfig[\"cli\"],\n override: NonNullable<DeepPartialConfig[\"cli\"]>\n): NonNullable<DeepPartialConfig[\"cli\"]> {\n const { interactive: overrideInteractive, ...overrideCliRest } = override;\n const { interactive: baseInteractive, ...baseCliRest } = base ?? {};\n const mergedInteractive =\n overrideInteractive !== undefined\n ? { ...baseInteractive, ...overrideInteractive }\n : baseInteractive;\n return {\n ...baseCliRest,\n ...overrideCliRest,\n ...(mergedInteractive !== undefined ? { interactive: mergedInteractive } : {}),\n };\n}\n\n/**\n * Merge partial configurations\n * Later configs override earlier ones\n */\nfunction mergeConfigs(\n base: DeepPartialConfig,\n ...overrides: (DeepPartialConfig | null | undefined)[]\n): DeepPartialConfig {\n const result: DeepPartialConfig = { ...base };\n\n const sectionKeys = [\n \"backup\",\n \"watch\",\n \"server\",\n \"citation\",\n \"pubmed\",\n \"fulltext\",\n \"mcp\",\n ] as const;\n\n for (const override of overrides) {\n if (!override) continue;\n\n // Merge top-level primitive fields\n if (override.library !== undefined) {\n result.library = override.library;\n }\n if (override.logLevel !== undefined) {\n result.logLevel = override.logLevel;\n }\n\n // Merge section configs\n for (const key of sectionKeys) {\n if (override[key] !== undefined) {\n result[key] = {\n ...result[key],\n ...override[key],\n };\n }\n }\n\n // Merge cli config with nested interactive\n if (override.cli !== undefined) {\n result.cli = mergeCliConfig(result.cli, override.cli);\n }\n }\n\n return result;\n}\n\n/**\n * Fill missing fields with defaults\n */\nfunction fillDefaults(partial: DeepPartialConfig): Config {\n return {\n library: partial.library ?? defaultConfig.library,\n logLevel: partial.logLevel ?? defaultConfig.logLevel,\n backup: {\n maxGenerations: partial.backup?.maxGenerations ?? defaultConfig.backup.maxGenerations,\n maxAgeDays: partial.backup?.maxAgeDays ?? defaultConfig.backup.maxAgeDays,\n directory: partial.backup?.directory ?? defaultConfig.backup.directory,\n },\n watch: {\n debounceMs: partial.watch?.debounceMs ?? defaultConfig.watch.debounceMs,\n pollIntervalMs: partial.watch?.pollIntervalMs ?? defaultConfig.watch.pollIntervalMs,\n retryIntervalMs: partial.watch?.retryIntervalMs ?? defaultConfig.watch.retryIntervalMs,\n maxRetries: partial.watch?.maxRetries ?? defaultConfig.watch.maxRetries,\n },\n server: {\n autoStart: partial.server?.autoStart ?? defaultConfig.server.autoStart,\n autoStopMinutes: partial.server?.autoStopMinutes ?? defaultConfig.server.autoStopMinutes,\n },\n citation: fillCitationDefaults(partial.citation),\n pubmed: fillPubmedDefaults(partial.pubmed),\n fulltext: fillFulltextDefaults(partial.fulltext),\n cli: fillCliDefaults(partial.cli),\n mcp: fillMcpDefaults(partial.mcp),\n };\n}\n\n/**\n * Fill citation config with defaults\n */\nfunction fillCitationDefaults(partial: DeepPartialConfig[\"citation\"]): Config[\"citation\"] {\n return {\n defaultStyle: partial?.defaultStyle ?? defaultConfig.citation.defaultStyle,\n cslDirectory: partial?.cslDirectory ?? defaultConfig.citation.cslDirectory,\n defaultLocale: partial?.defaultLocale ?? defaultConfig.citation.defaultLocale,\n defaultFormat: partial?.defaultFormat ?? defaultConfig.citation.defaultFormat,\n };\n}\n\n/**\n * Fill pubmed config with defaults\n * Environment variables take priority over config file values\n */\nfunction fillPubmedDefaults(partial: DeepPartialConfig[\"pubmed\"]): Config[\"pubmed\"] {\n // Environment variables take priority\n const email = process.env.PUBMED_EMAIL ?? partial?.email ?? defaultConfig.pubmed.email;\n const apiKey = process.env.PUBMED_API_KEY ?? partial?.apiKey ?? defaultConfig.pubmed.apiKey;\n\n return {\n email,\n apiKey,\n };\n}\n\n/**\n * Expand ~ to home directory\n */\nfunction expandTilde(path: string): string {\n if (path.startsWith(\"~/\")) {\n return join(homedir(), path.slice(2));\n }\n return path;\n}\n\n/**\n * Fill fulltext config with defaults\n *\n * Priority:\n * 1. Environment variable REFERENCE_MANAGER_FULLTEXT_DIR\n * 2. Config file setting\n * 3. Default value\n */\nfunction fillFulltextDefaults(partial: DeepPartialConfig[\"fulltext\"]): Config[\"fulltext\"] {\n const envDir = process.env.REFERENCE_MANAGER_FULLTEXT_DIR;\n const directory = envDir ?? partial?.directory ?? defaultConfig.fulltext.directory;\n return {\n directory: expandTilde(directory),\n };\n}\n\n/**\n * Fill CLI config with defaults\n *\n * Priority:\n * 1. Environment variable REFERENCE_MANAGER_CLI_DEFAULT_LIMIT\n * 2. Config file setting\n * 3. Default value\n */\nfunction fillCliDefaults(partial: DeepPartialConfig[\"cli\"]): Config[\"cli\"] {\n const envLimit = process.env.REFERENCE_MANAGER_CLI_DEFAULT_LIMIT;\n const defaultLimit =\n envLimit !== undefined\n ? Number(envLimit)\n : (partial?.defaultLimit ?? defaultConfig.cli.defaultLimit);\n return {\n defaultLimit,\n defaultSort: partial?.defaultSort ?? defaultConfig.cli.defaultSort,\n defaultOrder: partial?.defaultOrder ?? defaultConfig.cli.defaultOrder,\n interactive: {\n limit: partial?.interactive?.limit ?? defaultConfig.cli.interactive.limit,\n debounceMs: partial?.interactive?.debounceMs ?? defaultConfig.cli.interactive.debounceMs,\n },\n };\n}\n\n/**\n * Fill MCP config with defaults\n *\n * Priority:\n * 1. Environment variable REFERENCE_MANAGER_MCP_DEFAULT_LIMIT\n * 2. Config file setting\n * 3. Default value\n */\nfunction fillMcpDefaults(partial: DeepPartialConfig[\"mcp\"]): Config[\"mcp\"] {\n const envLimit = process.env.REFERENCE_MANAGER_MCP_DEFAULT_LIMIT;\n const defaultLimit =\n envLimit !== undefined\n ? Number(envLimit)\n : (partial?.defaultLimit ?? defaultConfig.mcp.defaultLimit);\n return {\n defaultLimit,\n };\n}\n\n/**\n * Load configuration from multiple sources\n *\n * Priority (highest to lowest):\n * 1. CLI argument overrides\n * 2. Current directory config (.reference-manager.config.toml)\n * 3. Environment variable (REFERENCE_MANAGER_CONFIG)\n * 4. User config (~/.reference-manager/config.toml)\n * 5. Default values\n */\nexport function loadConfig(options: LoadConfigOptions = {}): Config {\n const cwd = options.cwd ?? process.cwd();\n const userConfigPath = options.userConfigPath ?? getDefaultUserConfigPath();\n\n // 1. Load user config (lowest priority)\n const userConfig = loadTOMLFile(userConfigPath);\n\n // 2. Load environment variable config\n const envConfigPath = process.env.REFERENCE_MANAGER_CONFIG;\n const envConfig = envConfigPath ? loadTOMLFile(envConfigPath) : null;\n\n // 3. Load current directory config (highest priority)\n const currentConfigPath = join(cwd, getDefaultCurrentDirConfigFilename());\n const currentConfig = loadTOMLFile(currentConfigPath);\n\n // Normalize snake_case to camelCase\n const normalizedUser = userConfig ? normalizePartialConfig(userConfig) : null;\n const normalizedEnv = envConfig ? normalizePartialConfig(envConfig) : null;\n const normalizedCurrent = currentConfig ? normalizePartialConfig(currentConfig) : null;\n\n // Merge configs (priority: current > env > user > defaults)\n const merged = mergeConfigs(\n {},\n normalizedUser,\n normalizedEnv,\n normalizedCurrent,\n options.overrides\n );\n\n // Fill missing fields with defaults\n const config = fillDefaults(merged);\n\n // Validate final config\n try {\n return configSchema.parse(config);\n } catch (error) {\n throw new Error(\n `Invalid configuration: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n"],"names":["parseTOML"],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { IdentifierType } from "../../core/library-interface.js";
|
|
7
7
|
import type { FulltextType } from "../../features/fulltext/index.js";
|
|
8
|
-
import { type FulltextAttachResult, type FulltextDetachResult, type FulltextGetResult } from "../../features/operations/fulltext/index.js";
|
|
8
|
+
import { type FulltextAttachResult, type FulltextDetachResult, type FulltextGetResult, type FulltextOpenResult } from "../../features/operations/fulltext/index.js";
|
|
9
9
|
import type { ExecutionContext } from "../execution-context.js";
|
|
10
10
|
/**
|
|
11
11
|
* Options for fulltext attach command
|
|
@@ -41,7 +41,16 @@ export interface FulltextDetachOptions {
|
|
|
41
41
|
idType?: IdentifierType;
|
|
42
42
|
fulltextDirectory: string;
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Options for fulltext open command
|
|
46
|
+
*/
|
|
47
|
+
export interface FulltextOpenOptions {
|
|
48
|
+
identifier: string;
|
|
49
|
+
type?: FulltextType;
|
|
50
|
+
idType?: IdentifierType;
|
|
51
|
+
fulltextDirectory: string;
|
|
52
|
+
}
|
|
53
|
+
export type { FulltextAttachResult, FulltextGetResult, FulltextDetachResult, FulltextOpenResult };
|
|
45
54
|
/**
|
|
46
55
|
* Execute fulltext attach command
|
|
47
56
|
*/
|
|
@@ -54,6 +63,10 @@ export declare function executeFulltextGet(options: FulltextGetOptions, context:
|
|
|
54
63
|
* Execute fulltext detach command
|
|
55
64
|
*/
|
|
56
65
|
export declare function executeFulltextDetach(options: FulltextDetachOptions, context: ExecutionContext): Promise<FulltextDetachResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Execute fulltext open command
|
|
68
|
+
*/
|
|
69
|
+
export declare function executeFulltextOpen(options: FulltextOpenOptions, context: ExecutionContext): Promise<FulltextOpenResult>;
|
|
57
70
|
/**
|
|
58
71
|
* Format fulltext attach output
|
|
59
72
|
*/
|
|
@@ -66,8 +79,12 @@ export declare function formatFulltextGetOutput(result: FulltextGetResult): stri
|
|
|
66
79
|
* Format fulltext detach output
|
|
67
80
|
*/
|
|
68
81
|
export declare function formatFulltextDetachOutput(result: FulltextDetachResult): string;
|
|
82
|
+
/**
|
|
83
|
+
* Format fulltext open output
|
|
84
|
+
*/
|
|
85
|
+
export declare function formatFulltextOpenOutput(result: FulltextOpenResult): string;
|
|
69
86
|
/**
|
|
70
87
|
* Get exit code for fulltext command result
|
|
71
88
|
*/
|
|
72
|
-
export declare function getFulltextExitCode(result: FulltextAttachResult | FulltextGetResult | FulltextDetachResult): number;
|
|
89
|
+
export declare function getFulltextExitCode(result: FulltextAttachResult | FulltextGetResult | FulltextDetachResult | FulltextOpenResult): number;
|
|
73
90
|
//# sourceMappingURL=fulltext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fulltext.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/fulltext.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"fulltext.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/fulltext.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EASxB,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAGD,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,CAAC;AAElG;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,oBAAoB,CAAC,CAa/B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAU5B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,oBAAoB,CAAC,CAU/B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CAS7B;AAMD;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAiB/E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAkBzE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAe/E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAM3E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,oBAAoB,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,kBAAkB,GAC3F,MAAM,CAER"}
|
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6DpC;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CA+BvC;AAm2BD;;GAEG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBxD"}
|
package/dist/cli.js
CHANGED
|
@@ -8,12 +8,12 @@ import * as path from "node:path";
|
|
|
8
8
|
import { join, extname } from "node:path";
|
|
9
9
|
import { mkdir, unlink, rename, copyFile, rm, readFile } from "node:fs/promises";
|
|
10
10
|
import { u as updateReference, B as BUILTIN_STYLES, s as startServerWithFileWatcher } from "./chunks/index-_7NEUoS7.js";
|
|
11
|
+
import { o as openWithSystemApp, l as loadConfig } from "./chunks/loader-CLCZRS4m.js";
|
|
11
12
|
import process$1, { stdin, stdout } from "node:process";
|
|
12
|
-
import { l as loadConfig } from "./chunks/loader-BItrdVWG.js";
|
|
13
13
|
import { spawn } from "node:child_process";
|
|
14
14
|
import { serve } from "@hono/node-server";
|
|
15
15
|
const name = "@ncukondo/reference-manager";
|
|
16
|
-
const version$1 = "0.
|
|
16
|
+
const version$1 = "0.8.0";
|
|
17
17
|
const description$1 = "A local reference management tool using CSL-JSON as the single source of truth";
|
|
18
18
|
const packageJson = {
|
|
19
19
|
name,
|
|
@@ -607,6 +607,54 @@ async function fulltextDetach(library, options) {
|
|
|
607
607
|
return handleDetachError(error);
|
|
608
608
|
}
|
|
609
609
|
}
|
|
610
|
+
function getFulltextPath(item, type2, fulltextDirectory) {
|
|
611
|
+
const fulltext = item.custom?.fulltext;
|
|
612
|
+
if (!fulltext) return void 0;
|
|
613
|
+
const filename = type2 === "pdf" ? fulltext.pdf : fulltext.markdown;
|
|
614
|
+
if (!filename) return void 0;
|
|
615
|
+
return join(fulltextDirectory, filename);
|
|
616
|
+
}
|
|
617
|
+
function determineTypeToOpen(item) {
|
|
618
|
+
const fulltext = item.custom?.fulltext;
|
|
619
|
+
if (!fulltext) return void 0;
|
|
620
|
+
if (fulltext.pdf) return "pdf";
|
|
621
|
+
if (fulltext.markdown) return "markdown";
|
|
622
|
+
return void 0;
|
|
623
|
+
}
|
|
624
|
+
async function fulltextOpen(library, options) {
|
|
625
|
+
const { identifier, type: type2, idType = "id", fulltextDirectory } = options;
|
|
626
|
+
const item = await library.find(identifier, { idType });
|
|
627
|
+
if (!item) {
|
|
628
|
+
return { success: false, error: `Reference not found: ${identifier}` };
|
|
629
|
+
}
|
|
630
|
+
const typeToOpen = type2 ?? determineTypeToOpen(item);
|
|
631
|
+
if (!typeToOpen) {
|
|
632
|
+
return { success: false, error: `No fulltext attached to reference: ${identifier}` };
|
|
633
|
+
}
|
|
634
|
+
const filePath = getFulltextPath(item, typeToOpen, fulltextDirectory);
|
|
635
|
+
if (!filePath) {
|
|
636
|
+
return { success: false, error: `No ${typeToOpen} attached to reference: ${identifier}` };
|
|
637
|
+
}
|
|
638
|
+
if (!existsSync(filePath)) {
|
|
639
|
+
return {
|
|
640
|
+
success: false,
|
|
641
|
+
error: `Fulltext file not found: ${filePath} (metadata exists but file is missing)`
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
try {
|
|
645
|
+
await openWithSystemApp(filePath);
|
|
646
|
+
return {
|
|
647
|
+
success: true,
|
|
648
|
+
openedType: typeToOpen,
|
|
649
|
+
openedPath: filePath
|
|
650
|
+
};
|
|
651
|
+
} catch (_error) {
|
|
652
|
+
return {
|
|
653
|
+
success: false,
|
|
654
|
+
error: `Failed to open file: ${filePath}`
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
}
|
|
610
658
|
async function executeFulltextAttach(options, context) {
|
|
611
659
|
const operationOptions = {
|
|
612
660
|
identifier: options.identifier,
|
|
@@ -640,6 +688,15 @@ async function executeFulltextDetach(options, context) {
|
|
|
640
688
|
};
|
|
641
689
|
return fulltextDetach(context.library, operationOptions);
|
|
642
690
|
}
|
|
691
|
+
async function executeFulltextOpen(options, context) {
|
|
692
|
+
const operationOptions = {
|
|
693
|
+
identifier: options.identifier,
|
|
694
|
+
type: options.type,
|
|
695
|
+
idType: options.idType,
|
|
696
|
+
fulltextDirectory: options.fulltextDirectory
|
|
697
|
+
};
|
|
698
|
+
return fulltextOpen(context.library, operationOptions);
|
|
699
|
+
}
|
|
643
700
|
function formatFulltextAttachOutput(result) {
|
|
644
701
|
if (result.requiresConfirmation) {
|
|
645
702
|
return `File already attached: ${result.existingFile}
|
|
@@ -686,6 +743,12 @@ function formatFulltextDetachOutput(result) {
|
|
|
686
743
|
}
|
|
687
744
|
return lines.join("\n");
|
|
688
745
|
}
|
|
746
|
+
function formatFulltextOpenOutput(result) {
|
|
747
|
+
if (!result.success) {
|
|
748
|
+
return `Error: ${result.error}`;
|
|
749
|
+
}
|
|
750
|
+
return `Opened ${result.openedType}: ${result.openedPath}`;
|
|
751
|
+
}
|
|
689
752
|
function getFulltextExitCode(result) {
|
|
690
753
|
return result.success ? 0 : 1;
|
|
691
754
|
}
|
|
@@ -22005,7 +22068,7 @@ const OPTION_VALUES = {
|
|
|
22005
22068
|
"--log-level": LOG_LEVELS
|
|
22006
22069
|
};
|
|
22007
22070
|
const ID_COMPLETION_COMMANDS = /* @__PURE__ */ new Set(["cite", "remove", "update"]);
|
|
22008
|
-
const ID_COMPLETION_FULLTEXT_SUBCOMMANDS = /* @__PURE__ */ new Set(["attach", "get", "detach"]);
|
|
22071
|
+
const ID_COMPLETION_FULLTEXT_SUBCOMMANDS = /* @__PURE__ */ new Set(["attach", "get", "detach", "open"]);
|
|
22009
22072
|
function toCompletionItems(values) {
|
|
22010
22073
|
return values.map((name2) => ({ name: name2 }));
|
|
22011
22074
|
}
|
|
@@ -22787,6 +22850,48 @@ async function handleFulltextDetachAction(identifier, options, program) {
|
|
|
22787
22850
|
process.exit(4);
|
|
22788
22851
|
}
|
|
22789
22852
|
}
|
|
22853
|
+
async function handleFulltextOpenAction(identifierArg, options, program) {
|
|
22854
|
+
try {
|
|
22855
|
+
const config2 = await loadConfigWithOverrides(program.opts());
|
|
22856
|
+
let identifier;
|
|
22857
|
+
if (identifierArg) {
|
|
22858
|
+
identifier = identifierArg;
|
|
22859
|
+
} else {
|
|
22860
|
+
if (isTTY()) {
|
|
22861
|
+
process.stderr.write("Error: Identifier is required when running interactively.\n");
|
|
22862
|
+
process.exit(1);
|
|
22863
|
+
}
|
|
22864
|
+
const stdinId = (await readStdinContent()).split("\n")[0]?.trim() ?? "";
|
|
22865
|
+
if (!stdinId) {
|
|
22866
|
+
process.stderr.write("Error: No identifier provided from stdin.\n");
|
|
22867
|
+
process.exit(1);
|
|
22868
|
+
}
|
|
22869
|
+
identifier = stdinId;
|
|
22870
|
+
}
|
|
22871
|
+
const context = await createExecutionContext(config2, Library.load);
|
|
22872
|
+
const openOptions = {
|
|
22873
|
+
identifier,
|
|
22874
|
+
fulltextDirectory: config2.fulltext.directory,
|
|
22875
|
+
...options.pdf && { type: "pdf" },
|
|
22876
|
+
...options.markdown && { type: "markdown" },
|
|
22877
|
+
...options.uuid && { idType: "uuid" }
|
|
22878
|
+
};
|
|
22879
|
+
const result = await executeFulltextOpen(openOptions, context);
|
|
22880
|
+
const output = formatFulltextOpenOutput(result);
|
|
22881
|
+
if (result.success) {
|
|
22882
|
+
process.stderr.write(`${output}
|
|
22883
|
+
`);
|
|
22884
|
+
} else {
|
|
22885
|
+
process.stderr.write(`${output}
|
|
22886
|
+
`);
|
|
22887
|
+
}
|
|
22888
|
+
process.exit(getFulltextExitCode(result));
|
|
22889
|
+
} catch (error) {
|
|
22890
|
+
process.stderr.write(`Error: ${error instanceof Error ? error.message : String(error)}
|
|
22891
|
+
`);
|
|
22892
|
+
process.exit(4);
|
|
22893
|
+
}
|
|
22894
|
+
}
|
|
22790
22895
|
function registerFulltextCommand(program) {
|
|
22791
22896
|
const fulltextCmd = program.command("fulltext").description("Manage full-text files attached to references");
|
|
22792
22897
|
fulltextCmd.command("attach").description("Attach a full-text file to a reference").argument("<identifier>", "Citation key or UUID").argument("[file-path]", "Path to the file to attach").option("--pdf [path]", "Attach as PDF (path optional if provided as argument)").option("--markdown [path]", "Attach as Markdown (path optional if provided as argument)").option("--move", "Move file instead of copy").option("-f, --force", "Overwrite existing attachment").option("--uuid", "Interpret identifier as UUID").action(async (identifier, filePath, options) => {
|
|
@@ -22798,6 +22903,9 @@ function registerFulltextCommand(program) {
|
|
|
22798
22903
|
fulltextCmd.command("detach").description("Detach full-text file from a reference").argument("<identifier>", "Citation key or UUID").option("--pdf", "Detach PDF only").option("--markdown", "Detach Markdown only").option("--delete", "Also delete the file from disk").option("-f, --force", "Skip confirmation for delete").option("--uuid", "Interpret identifier as UUID").action(async (identifier, options) => {
|
|
22799
22904
|
await handleFulltextDetachAction(identifier, options, program);
|
|
22800
22905
|
});
|
|
22906
|
+
fulltextCmd.command("open").description("Open full-text file with system default application").argument("[identifier]", "Citation key or UUID (reads from stdin if not provided)").option("--pdf", "Open PDF file").option("--markdown", "Open Markdown file").option("--uuid", "Interpret identifier as UUID").action(async (identifier, options) => {
|
|
22907
|
+
await handleFulltextOpenAction(identifier, options, program);
|
|
22908
|
+
});
|
|
22801
22909
|
}
|
|
22802
22910
|
async function main(argv) {
|
|
22803
22911
|
const program = createProgram();
|