@ncukondo/reference-manager 0.1.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/README.md +278 -80
  2. package/dist/chunks/{detector-BF8Mcc72.js → file-watcher-B-SiUw5f.js} +469 -327
  3. package/dist/chunks/file-watcher-B-SiUw5f.js.map +1 -0
  4. package/dist/chunks/index-DLIGxQaB.js +29851 -0
  5. package/dist/chunks/index-DLIGxQaB.js.map +1 -0
  6. package/dist/chunks/loader-DuzyKV70.js +394 -0
  7. package/dist/chunks/loader-DuzyKV70.js.map +1 -0
  8. package/dist/cli/commands/add.d.ts +44 -16
  9. package/dist/cli/commands/add.d.ts.map +1 -1
  10. package/dist/cli/commands/cite.d.ts +49 -0
  11. package/dist/cli/commands/cite.d.ts.map +1 -0
  12. package/dist/cli/commands/fulltext.d.ts +72 -0
  13. package/dist/cli/commands/fulltext.d.ts.map +1 -0
  14. package/dist/cli/commands/index.d.ts +14 -10
  15. package/dist/cli/commands/index.d.ts.map +1 -1
  16. package/dist/cli/commands/list.d.ts +23 -6
  17. package/dist/cli/commands/list.d.ts.map +1 -1
  18. package/dist/cli/commands/mcp.d.ts +16 -0
  19. package/dist/cli/commands/mcp.d.ts.map +1 -0
  20. package/dist/cli/commands/remove.d.ts +47 -12
  21. package/dist/cli/commands/remove.d.ts.map +1 -1
  22. package/dist/cli/commands/search.d.ts +24 -7
  23. package/dist/cli/commands/search.d.ts.map +1 -1
  24. package/dist/cli/commands/server.d.ts +2 -0
  25. package/dist/cli/commands/server.d.ts.map +1 -1
  26. package/dist/cli/commands/update.d.ts +26 -13
  27. package/dist/cli/commands/update.d.ts.map +1 -1
  28. package/dist/cli/execution-context.d.ts +47 -0
  29. package/dist/cli/execution-context.d.ts.map +1 -0
  30. package/dist/cli/helpers.d.ts +18 -0
  31. package/dist/cli/helpers.d.ts.map +1 -1
  32. package/dist/cli/index.d.ts.map +1 -1
  33. package/dist/cli/server-client.d.ts +61 -14
  34. package/dist/cli/server-client.d.ts.map +1 -1
  35. package/dist/cli/server-detection.d.ts +1 -0
  36. package/dist/cli/server-detection.d.ts.map +1 -1
  37. package/dist/cli.js +21979 -564
  38. package/dist/cli.js.map +1 -1
  39. package/dist/config/csl-styles.d.ts +83 -0
  40. package/dist/config/csl-styles.d.ts.map +1 -0
  41. package/dist/config/defaults.d.ts +10 -0
  42. package/dist/config/defaults.d.ts.map +1 -1
  43. package/dist/config/loader.d.ts.map +1 -1
  44. package/dist/config/schema.d.ts +86 -3
  45. package/dist/config/schema.d.ts.map +1 -1
  46. package/dist/core/csl-json/types.d.ts +18 -3
  47. package/dist/core/csl-json/types.d.ts.map +1 -1
  48. package/dist/core/library-interface.d.ts +100 -0
  49. package/dist/core/library-interface.d.ts.map +1 -0
  50. package/dist/core/library.d.ts +56 -13
  51. package/dist/core/library.d.ts.map +1 -1
  52. package/dist/features/format/bibtex.d.ts +6 -0
  53. package/dist/features/format/bibtex.d.ts.map +1 -0
  54. package/dist/features/format/citation-csl.d.ts +41 -0
  55. package/dist/features/format/citation-csl.d.ts.map +1 -0
  56. package/dist/features/format/citation-fallback.d.ts +24 -0
  57. package/dist/features/format/citation-fallback.d.ts.map +1 -0
  58. package/dist/features/format/index.d.ts +10 -0
  59. package/dist/features/format/index.d.ts.map +1 -0
  60. package/dist/features/format/json.d.ts +6 -0
  61. package/dist/features/format/json.d.ts.map +1 -0
  62. package/dist/features/format/pretty.d.ts +6 -0
  63. package/dist/features/format/pretty.d.ts.map +1 -0
  64. package/dist/features/fulltext/filename.d.ts +17 -0
  65. package/dist/features/fulltext/filename.d.ts.map +1 -0
  66. package/dist/features/fulltext/index.d.ts +7 -0
  67. package/dist/features/fulltext/index.d.ts.map +1 -0
  68. package/dist/features/fulltext/manager.d.ts +109 -0
  69. package/dist/features/fulltext/manager.d.ts.map +1 -0
  70. package/dist/features/fulltext/types.d.ts +12 -0
  71. package/dist/features/fulltext/types.d.ts.map +1 -0
  72. package/dist/features/import/cache.d.ts +37 -0
  73. package/dist/features/import/cache.d.ts.map +1 -0
  74. package/dist/features/import/detector.d.ts +42 -0
  75. package/dist/features/import/detector.d.ts.map +1 -0
  76. package/dist/features/import/fetcher.d.ts +49 -0
  77. package/dist/features/import/fetcher.d.ts.map +1 -0
  78. package/dist/features/import/importer.d.ts +61 -0
  79. package/dist/features/import/importer.d.ts.map +1 -0
  80. package/dist/features/import/index.d.ts +8 -0
  81. package/dist/features/import/index.d.ts.map +1 -0
  82. package/dist/features/import/normalizer.d.ts +15 -0
  83. package/dist/features/import/normalizer.d.ts.map +1 -0
  84. package/dist/features/import/parser.d.ts +33 -0
  85. package/dist/features/import/parser.d.ts.map +1 -0
  86. package/dist/features/import/rate-limiter.d.ts +45 -0
  87. package/dist/features/import/rate-limiter.d.ts.map +1 -0
  88. package/dist/features/operations/add.d.ts +65 -0
  89. package/dist/features/operations/add.d.ts.map +1 -0
  90. package/dist/features/operations/cite.d.ts +48 -0
  91. package/dist/features/operations/cite.d.ts.map +1 -0
  92. package/dist/features/operations/fulltext/attach.d.ts +47 -0
  93. package/dist/features/operations/fulltext/attach.d.ts.map +1 -0
  94. package/dist/features/operations/fulltext/detach.d.ts +38 -0
  95. package/dist/features/operations/fulltext/detach.d.ts.map +1 -0
  96. package/dist/features/operations/fulltext/get.d.ts +41 -0
  97. package/dist/features/operations/fulltext/get.d.ts.map +1 -0
  98. package/dist/features/operations/fulltext/index.d.ts +9 -0
  99. package/dist/features/operations/fulltext/index.d.ts.map +1 -0
  100. package/dist/features/operations/index.d.ts +15 -0
  101. package/dist/features/operations/index.d.ts.map +1 -0
  102. package/dist/features/operations/library-operations.d.ts +64 -0
  103. package/dist/features/operations/library-operations.d.ts.map +1 -0
  104. package/dist/features/operations/list.d.ts +28 -0
  105. package/dist/features/operations/list.d.ts.map +1 -0
  106. package/dist/features/operations/operations-library.d.ts +36 -0
  107. package/dist/features/operations/operations-library.d.ts.map +1 -0
  108. package/dist/features/operations/remove.d.ts +29 -0
  109. package/dist/features/operations/remove.d.ts.map +1 -0
  110. package/dist/features/operations/search.d.ts +30 -0
  111. package/dist/features/operations/search.d.ts.map +1 -0
  112. package/dist/features/operations/update.d.ts +39 -0
  113. package/dist/features/operations/update.d.ts.map +1 -0
  114. package/dist/features/search/matcher.d.ts.map +1 -1
  115. package/dist/features/search/normalizer.d.ts +12 -0
  116. package/dist/features/search/normalizer.d.ts.map +1 -1
  117. package/dist/features/search/tokenizer.d.ts.map +1 -1
  118. package/dist/features/search/types.d.ts +1 -1
  119. package/dist/features/search/types.d.ts.map +1 -1
  120. package/dist/features/search/uppercase.d.ts +41 -0
  121. package/dist/features/search/uppercase.d.ts.map +1 -0
  122. package/dist/index.js +21 -187
  123. package/dist/index.js.map +1 -1
  124. package/dist/mcp/context.d.ts +19 -0
  125. package/dist/mcp/context.d.ts.map +1 -0
  126. package/dist/mcp/index.d.ts +20 -0
  127. package/dist/mcp/index.d.ts.map +1 -0
  128. package/dist/mcp/resources/index.d.ts +10 -0
  129. package/dist/mcp/resources/index.d.ts.map +1 -0
  130. package/dist/mcp/resources/library.d.ts +26 -0
  131. package/dist/mcp/resources/library.d.ts.map +1 -0
  132. package/dist/mcp/tools/add.d.ts +17 -0
  133. package/dist/mcp/tools/add.d.ts.map +1 -0
  134. package/dist/mcp/tools/cite.d.ts +15 -0
  135. package/dist/mcp/tools/cite.d.ts.map +1 -0
  136. package/dist/mcp/tools/fulltext.d.ts +51 -0
  137. package/dist/mcp/tools/fulltext.d.ts.map +1 -0
  138. package/dist/mcp/tools/index.d.ts +12 -0
  139. package/dist/mcp/tools/index.d.ts.map +1 -0
  140. package/dist/mcp/tools/list.d.ts +13 -0
  141. package/dist/mcp/tools/list.d.ts.map +1 -0
  142. package/dist/mcp/tools/remove.d.ts +19 -0
  143. package/dist/mcp/tools/remove.d.ts.map +1 -0
  144. package/dist/mcp/tools/search.d.ts +13 -0
  145. package/dist/mcp/tools/search.d.ts.map +1 -0
  146. package/dist/server/index.d.ts +26 -2
  147. package/dist/server/index.d.ts.map +1 -1
  148. package/dist/server/routes/add.d.ts +11 -0
  149. package/dist/server/routes/add.d.ts.map +1 -0
  150. package/dist/server/routes/cite.d.ts +9 -0
  151. package/dist/server/routes/cite.d.ts.map +1 -0
  152. package/dist/server/routes/list.d.ts +25 -0
  153. package/dist/server/routes/list.d.ts.map +1 -0
  154. package/dist/server/routes/references.d.ts.map +1 -1
  155. package/dist/server/routes/search.d.ts +26 -0
  156. package/dist/server/routes/search.d.ts.map +1 -0
  157. package/dist/server.js +5 -88
  158. package/dist/server.js.map +1 -1
  159. package/package.json +16 -4
  160. package/dist/chunks/detector-BF8Mcc72.js.map +0 -1
  161. package/dist/cli/output/bibtex.d.ts +0 -6
  162. package/dist/cli/output/bibtex.d.ts.map +0 -1
  163. package/dist/cli/output/index.d.ts +0 -7
  164. package/dist/cli/output/index.d.ts.map +0 -1
  165. package/dist/cli/output/json.d.ts +0 -6
  166. package/dist/cli/output/json.d.ts.map +0 -1
  167. package/dist/cli/output/pretty.d.ts +0 -6
  168. package/dist/cli/output/pretty.d.ts.map +0 -1
@@ -0,0 +1,394 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { homedir, tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { parse } from "@iarna/toml";
5
+ import { z } from "zod";
6
+ const logLevelSchema = z.enum(["silent", "info", "debug"]);
7
+ const backupConfigSchema = z.object({
8
+ maxGenerations: z.number().int().positive(),
9
+ maxAgeDays: z.number().int().positive(),
10
+ directory: z.string().min(1)
11
+ });
12
+ const watchConfigSchema = z.object({
13
+ debounceMs: z.number().int().nonnegative(),
14
+ pollIntervalMs: z.number().int().positive(),
15
+ retryIntervalMs: z.number().int().positive(),
16
+ maxRetries: z.number().int().nonnegative()
17
+ });
18
+ const serverConfigSchema = z.object({
19
+ autoStart: z.boolean(),
20
+ autoStopMinutes: z.number().int().nonnegative()
21
+ });
22
+ const citationFormatSchema = z.enum(["text", "html", "rtf"]);
23
+ const citationConfigSchema = z.object({
24
+ defaultStyle: z.string(),
25
+ cslDirectory: z.array(z.string()),
26
+ defaultLocale: z.string(),
27
+ defaultFormat: citationFormatSchema
28
+ });
29
+ const pubmedConfigSchema = z.object({
30
+ email: z.string().optional(),
31
+ apiKey: z.string().optional()
32
+ });
33
+ const fulltextConfigSchema = z.object({
34
+ directory: z.string().min(1)
35
+ });
36
+ const configSchema = z.object({
37
+ library: z.string().min(1),
38
+ logLevel: logLevelSchema,
39
+ backup: backupConfigSchema,
40
+ watch: watchConfigSchema,
41
+ server: serverConfigSchema,
42
+ citation: citationConfigSchema,
43
+ pubmed: pubmedConfigSchema,
44
+ fulltext: fulltextConfigSchema
45
+ });
46
+ const partialConfigSchema = z.object({
47
+ library: z.string().min(1).optional(),
48
+ logLevel: logLevelSchema.optional(),
49
+ log_level: logLevelSchema.optional(),
50
+ // snake_case support
51
+ backup: z.object({
52
+ maxGenerations: z.number().int().positive().optional(),
53
+ max_generations: z.number().int().positive().optional(),
54
+ maxAgeDays: z.number().int().positive().optional(),
55
+ max_age_days: z.number().int().positive().optional(),
56
+ directory: z.string().min(1).optional()
57
+ }).optional(),
58
+ watch: z.object({
59
+ debounceMs: z.number().int().nonnegative().optional(),
60
+ debounce_ms: z.number().int().nonnegative().optional(),
61
+ pollIntervalMs: z.number().int().positive().optional(),
62
+ poll_interval_ms: z.number().int().positive().optional(),
63
+ retryIntervalMs: z.number().int().positive().optional(),
64
+ retry_interval_ms: z.number().int().positive().optional(),
65
+ maxRetries: z.number().int().nonnegative().optional(),
66
+ max_retries: z.number().int().nonnegative().optional()
67
+ }).optional(),
68
+ server: z.object({
69
+ autoStart: z.boolean().optional(),
70
+ auto_start: z.boolean().optional(),
71
+ autoStopMinutes: z.number().int().nonnegative().optional(),
72
+ auto_stop_minutes: z.number().int().nonnegative().optional()
73
+ }).optional(),
74
+ citation: z.object({
75
+ defaultStyle: z.string().optional(),
76
+ default_style: z.string().optional(),
77
+ cslDirectory: z.union([z.string(), z.array(z.string())]).optional(),
78
+ csl_directory: z.union([z.string(), z.array(z.string())]).optional(),
79
+ defaultLocale: z.string().optional(),
80
+ default_locale: z.string().optional(),
81
+ defaultFormat: citationFormatSchema.optional(),
82
+ default_format: citationFormatSchema.optional()
83
+ }).optional(),
84
+ pubmed: z.object({
85
+ email: z.string().optional(),
86
+ apiKey: z.string().optional(),
87
+ api_key: z.string().optional()
88
+ }).optional(),
89
+ fulltext: z.object({
90
+ directory: z.string().min(1).optional()
91
+ }).optional()
92
+ }).passthrough();
93
+ function normalizeBackupConfig(backup) {
94
+ const normalized = {};
95
+ const maxGenerations = backup.maxGenerations ?? backup.max_generations;
96
+ if (maxGenerations !== void 0) {
97
+ normalized.maxGenerations = maxGenerations;
98
+ }
99
+ const maxAgeDays = backup.maxAgeDays ?? backup.max_age_days;
100
+ if (maxAgeDays !== void 0) {
101
+ normalized.maxAgeDays = maxAgeDays;
102
+ }
103
+ if (backup.directory !== void 0) {
104
+ normalized.directory = backup.directory;
105
+ }
106
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
107
+ }
108
+ function normalizeWatchConfig(watch) {
109
+ const normalized = {};
110
+ const debounceMs = watch.debounceMs ?? watch.debounce_ms;
111
+ if (debounceMs !== void 0) {
112
+ normalized.debounceMs = debounceMs;
113
+ }
114
+ const pollIntervalMs = watch.pollIntervalMs ?? watch.poll_interval_ms;
115
+ if (pollIntervalMs !== void 0) {
116
+ normalized.pollIntervalMs = pollIntervalMs;
117
+ }
118
+ const retryIntervalMs = watch.retryIntervalMs ?? watch.retry_interval_ms;
119
+ if (retryIntervalMs !== void 0) {
120
+ normalized.retryIntervalMs = retryIntervalMs;
121
+ }
122
+ const maxRetries = watch.maxRetries ?? watch.max_retries;
123
+ if (maxRetries !== void 0) {
124
+ normalized.maxRetries = maxRetries;
125
+ }
126
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
127
+ }
128
+ function normalizeServerConfig(server) {
129
+ const normalized = {};
130
+ const autoStart = server.autoStart ?? server.auto_start;
131
+ if (autoStart !== void 0) {
132
+ normalized.autoStart = autoStart;
133
+ }
134
+ const autoStopMinutes = server.autoStopMinutes ?? server.auto_stop_minutes;
135
+ if (autoStopMinutes !== void 0) {
136
+ normalized.autoStopMinutes = autoStopMinutes;
137
+ }
138
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
139
+ }
140
+ function normalizeCitationConfig(citation) {
141
+ const normalized = {};
142
+ const defaultStyle = citation.defaultStyle ?? citation.default_style;
143
+ if (defaultStyle !== void 0) {
144
+ normalized.defaultStyle = defaultStyle;
145
+ }
146
+ const cslDirectory = citation.cslDirectory ?? citation.csl_directory;
147
+ if (cslDirectory !== void 0) {
148
+ normalized.cslDirectory = Array.isArray(cslDirectory) ? cslDirectory : [cslDirectory];
149
+ }
150
+ const defaultLocale = citation.defaultLocale ?? citation.default_locale;
151
+ if (defaultLocale !== void 0) {
152
+ normalized.defaultLocale = defaultLocale;
153
+ }
154
+ const defaultFormat = citation.defaultFormat ?? citation.default_format;
155
+ if (defaultFormat !== void 0) {
156
+ normalized.defaultFormat = defaultFormat;
157
+ }
158
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
159
+ }
160
+ function normalizePubmedConfig(pubmed) {
161
+ const normalized = {};
162
+ if (pubmed.email !== void 0) {
163
+ normalized.email = pubmed.email;
164
+ }
165
+ const apiKey = pubmed.apiKey ?? pubmed.api_key;
166
+ if (apiKey !== void 0) {
167
+ normalized.apiKey = apiKey;
168
+ }
169
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
170
+ }
171
+ function normalizePartialConfig(partial) {
172
+ const normalized = {};
173
+ if (partial.library !== void 0) {
174
+ normalized.library = partial.library;
175
+ }
176
+ const logLevel = partial.logLevel ?? partial.log_level;
177
+ if (logLevel !== void 0) {
178
+ normalized.logLevel = logLevel;
179
+ }
180
+ const backup = partial.backup !== void 0 ? normalizeBackupConfig(partial.backup) : void 0;
181
+ if (backup) {
182
+ normalized.backup = backup;
183
+ }
184
+ const watch = partial.watch !== void 0 ? normalizeWatchConfig(partial.watch) : void 0;
185
+ if (watch) {
186
+ normalized.watch = watch;
187
+ }
188
+ const server = partial.server !== void 0 ? normalizeServerConfig(partial.server) : void 0;
189
+ if (server) {
190
+ normalized.server = server;
191
+ }
192
+ const citation = partial.citation !== void 0 ? normalizeCitationConfig(partial.citation) : void 0;
193
+ if (citation) {
194
+ normalized.citation = citation;
195
+ }
196
+ const pubmed = partial.pubmed !== void 0 ? normalizePubmedConfig(partial.pubmed) : void 0;
197
+ if (pubmed) {
198
+ normalized.pubmed = pubmed;
199
+ }
200
+ const fulltext = partial.fulltext !== void 0 ? normalizeFulltextConfig(partial.fulltext) : void 0;
201
+ if (fulltext) {
202
+ normalized.fulltext = fulltext;
203
+ }
204
+ return normalized;
205
+ }
206
+ function normalizeFulltextConfig(fulltext) {
207
+ const normalized = {};
208
+ if (fulltext.directory !== void 0) {
209
+ normalized.directory = fulltext.directory;
210
+ }
211
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
212
+ }
213
+ function getDefaultBackupDirectory() {
214
+ return join(tmpdir(), "reference-manager", "backups");
215
+ }
216
+ function getDefaultLibraryPath() {
217
+ return join(homedir(), ".reference-manager", "csl.library.json");
218
+ }
219
+ function getDefaultUserConfigPath() {
220
+ return join(homedir(), ".reference-manager", "config.toml");
221
+ }
222
+ function getDefaultCurrentDirConfigFilename() {
223
+ return ".reference-manager.config.toml";
224
+ }
225
+ function getDefaultCslDirectory() {
226
+ return join(homedir(), ".reference-manager", "csl");
227
+ }
228
+ function getDefaultFulltextDirectory() {
229
+ return join(homedir(), ".reference-manager", "fulltext");
230
+ }
231
+ const defaultConfig = {
232
+ library: getDefaultLibraryPath(),
233
+ logLevel: "info",
234
+ backup: {
235
+ maxGenerations: 50,
236
+ maxAgeDays: 365,
237
+ directory: getDefaultBackupDirectory()
238
+ },
239
+ watch: {
240
+ debounceMs: 500,
241
+ pollIntervalMs: 5e3,
242
+ retryIntervalMs: 200,
243
+ maxRetries: 10
244
+ },
245
+ server: {
246
+ autoStart: false,
247
+ autoStopMinutes: 0
248
+ },
249
+ citation: {
250
+ defaultStyle: "apa",
251
+ cslDirectory: [getDefaultCslDirectory()],
252
+ defaultLocale: "en-US",
253
+ defaultFormat: "text"
254
+ },
255
+ pubmed: {
256
+ email: void 0,
257
+ apiKey: void 0
258
+ },
259
+ fulltext: {
260
+ directory: getDefaultFulltextDirectory()
261
+ }
262
+ };
263
+ function loadTOMLFile(path) {
264
+ if (!existsSync(path)) {
265
+ return null;
266
+ }
267
+ try {
268
+ const content = readFileSync(path, "utf-8");
269
+ const parsed = parse(content);
270
+ const validated = partialConfigSchema.parse(parsed);
271
+ return validated;
272
+ } catch (error) {
273
+ throw new Error(
274
+ `Failed to load config from ${path}: ${error instanceof Error ? error.message : String(error)}`
275
+ );
276
+ }
277
+ }
278
+ function mergeConfigs(base, ...overrides) {
279
+ const result = { ...base };
280
+ const sectionKeys = ["backup", "watch", "server", "citation", "pubmed", "fulltext"];
281
+ for (const override of overrides) {
282
+ if (!override) continue;
283
+ if (override.library !== void 0) {
284
+ result.library = override.library;
285
+ }
286
+ if (override.logLevel !== void 0) {
287
+ result.logLevel = override.logLevel;
288
+ }
289
+ for (const key of sectionKeys) {
290
+ if (override[key] !== void 0) {
291
+ result[key] = {
292
+ ...result[key],
293
+ ...override[key]
294
+ };
295
+ }
296
+ }
297
+ }
298
+ return result;
299
+ }
300
+ function fillDefaults(partial) {
301
+ return {
302
+ library: partial.library ?? defaultConfig.library,
303
+ logLevel: partial.logLevel ?? defaultConfig.logLevel,
304
+ backup: {
305
+ maxGenerations: partial.backup?.maxGenerations ?? defaultConfig.backup.maxGenerations,
306
+ maxAgeDays: partial.backup?.maxAgeDays ?? defaultConfig.backup.maxAgeDays,
307
+ directory: partial.backup?.directory ?? defaultConfig.backup.directory
308
+ },
309
+ watch: {
310
+ debounceMs: partial.watch?.debounceMs ?? defaultConfig.watch.debounceMs,
311
+ pollIntervalMs: partial.watch?.pollIntervalMs ?? defaultConfig.watch.pollIntervalMs,
312
+ retryIntervalMs: partial.watch?.retryIntervalMs ?? defaultConfig.watch.retryIntervalMs,
313
+ maxRetries: partial.watch?.maxRetries ?? defaultConfig.watch.maxRetries
314
+ },
315
+ server: {
316
+ autoStart: partial.server?.autoStart ?? defaultConfig.server.autoStart,
317
+ autoStopMinutes: partial.server?.autoStopMinutes ?? defaultConfig.server.autoStopMinutes
318
+ },
319
+ citation: fillCitationDefaults(partial.citation),
320
+ pubmed: fillPubmedDefaults(partial.pubmed),
321
+ fulltext: fillFulltextDefaults(partial.fulltext)
322
+ };
323
+ }
324
+ function fillCitationDefaults(partial) {
325
+ return {
326
+ defaultStyle: partial?.defaultStyle ?? defaultConfig.citation.defaultStyle,
327
+ cslDirectory: partial?.cslDirectory ?? defaultConfig.citation.cslDirectory,
328
+ defaultLocale: partial?.defaultLocale ?? defaultConfig.citation.defaultLocale,
329
+ defaultFormat: partial?.defaultFormat ?? defaultConfig.citation.defaultFormat
330
+ };
331
+ }
332
+ function fillPubmedDefaults(partial) {
333
+ const email = process.env.PUBMED_EMAIL ?? partial?.email ?? defaultConfig.pubmed.email;
334
+ const apiKey = process.env.PUBMED_API_KEY ?? partial?.apiKey ?? defaultConfig.pubmed.apiKey;
335
+ return {
336
+ email,
337
+ apiKey
338
+ };
339
+ }
340
+ function expandTilde(path) {
341
+ if (path.startsWith("~/")) {
342
+ return join(homedir(), path.slice(2));
343
+ }
344
+ return path;
345
+ }
346
+ function fillFulltextDefaults(partial) {
347
+ const envDir = process.env.REFERENCE_MANAGER_FULLTEXT_DIR;
348
+ const directory = envDir ?? partial?.directory ?? defaultConfig.fulltext.directory;
349
+ return {
350
+ directory: expandTilde(directory)
351
+ };
352
+ }
353
+ function loadConfig(options = {}) {
354
+ const cwd = options.cwd ?? process.cwd();
355
+ const userConfigPath = options.userConfigPath ?? getDefaultUserConfigPath();
356
+ const userConfig = loadTOMLFile(userConfigPath);
357
+ const envConfigPath = process.env.REFERENCE_MANAGER_CONFIG;
358
+ const envConfig = envConfigPath ? loadTOMLFile(envConfigPath) : null;
359
+ const currentConfigPath = join(cwd, getDefaultCurrentDirConfigFilename());
360
+ const currentConfig = loadTOMLFile(currentConfigPath);
361
+ const normalizedUser = userConfig ? normalizePartialConfig(userConfig) : null;
362
+ const normalizedEnv = envConfig ? normalizePartialConfig(envConfig) : null;
363
+ const normalizedCurrent = currentConfig ? normalizePartialConfig(currentConfig) : null;
364
+ const merged = mergeConfigs(
365
+ {},
366
+ normalizedUser,
367
+ normalizedEnv,
368
+ normalizedCurrent,
369
+ options.overrides
370
+ );
371
+ const config = fillDefaults(merged);
372
+ try {
373
+ return configSchema.parse(config);
374
+ } catch (error) {
375
+ throw new Error(
376
+ `Invalid configuration: ${error instanceof Error ? error.message : String(error)}`
377
+ );
378
+ }
379
+ }
380
+ export {
381
+ getDefaultCurrentDirConfigFilename as a,
382
+ backupConfigSchema as b,
383
+ configSchema as c,
384
+ defaultConfig as d,
385
+ getDefaultLibraryPath as e,
386
+ getDefaultUserConfigPath as f,
387
+ getDefaultBackupDirectory as g,
388
+ logLevelSchema as h,
389
+ loadConfig as l,
390
+ normalizePartialConfig as n,
391
+ partialConfigSchema as p,
392
+ watchConfigSchema as w
393
+ };
394
+ //# sourceMappingURL=loader-DuzyKV70.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-DuzyKV70.js","sources":["../../src/config/schema.ts","../../src/config/defaults.ts","../../src/config/loader.ts"],"sourcesContent":["/**\n * Configuration schema using Zod\n */\n\nimport { z } from \"zod\";\n\n/**\n * Log level schema\n */\nexport const logLevelSchema = z.enum([\"silent\", \"info\", \"debug\"]);\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});\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 })\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 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};\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 * Normalize snake_case fields to camelCase\n */\nexport function normalizePartialConfig(partial: PartialConfig): DeepPartialConfig {\n const normalized: DeepPartialConfig = {};\n\n // Library\n if (partial.library !== undefined) {\n normalized.library = partial.library;\n }\n\n // Log level (prefer camelCase, fallback to snake_case)\n const logLevel = partial.logLevel ?? partial.log_level;\n if (logLevel !== undefined) {\n normalized.logLevel = logLevel;\n }\n\n // Backup\n const backup =\n partial.backup !== undefined\n ? normalizeBackupConfig(partial.backup as Parameters<typeof normalizeBackupConfig>[0])\n : undefined;\n if (backup) {\n normalized.backup = backup;\n }\n\n // Watch\n const watch =\n partial.watch !== undefined\n ? normalizeWatchConfig(partial.watch as Parameters<typeof normalizeWatchConfig>[0])\n : undefined;\n if (watch) {\n normalized.watch = watch;\n }\n\n // Server\n const server =\n partial.server !== undefined\n ? normalizeServerConfig(partial.server as Parameters<typeof normalizeServerConfig>[0])\n : undefined;\n if (server) {\n normalized.server = server;\n }\n\n // Citation\n const citation =\n partial.citation !== undefined\n ? normalizeCitationConfig(partial.citation as Parameters<typeof normalizeCitationConfig>[0])\n : undefined;\n if (citation) {\n normalized.citation = citation;\n }\n\n // PubMed\n const pubmed =\n partial.pubmed !== undefined\n ? normalizePubmedConfig(partial.pubmed as Parameters<typeof normalizePubmedConfig>[0])\n : undefined;\n if (pubmed) {\n normalized.pubmed = pubmed;\n }\n\n // Fulltext\n const fulltext =\n partial.fulltext !== undefined ? normalizeFulltextConfig(partial.fulltext) : undefined;\n if (fulltext) {\n normalized.fulltext = fulltext;\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 * 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};\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 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 = [\"backup\", \"watch\", \"server\", \"citation\", \"pubmed\", \"fulltext\"] 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\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 };\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 * 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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"}
@@ -1,22 +1,50 @@
1
- import type { CslItem } from "../../core/csl-json/types.js";
2
- import type { DuplicateMatch } from "../../features/duplicate/types.js";
3
- export interface AddOptions {
1
+ import type { PubmedConfig } from "../../features/import/fetcher.js";
2
+ import type { AddReferencesResult, AddedItem, FailedItem, SkippedItem } from "../../features/operations/add.js";
3
+ import type { ExecutionContext } from "../execution-context.js";
4
+ /**
5
+ * Options for the add command.
6
+ */
7
+ export interface AddCommandOptions {
8
+ /** Input strings (file paths, PMIDs, DOIs) */
9
+ inputs: string[];
10
+ /** Skip duplicate detection */
4
11
  force: boolean;
12
+ /** Explicit input format */
13
+ format?: string;
14
+ /** PubMed API configuration */
15
+ pubmedConfig?: PubmedConfig;
16
+ /** Show verbose error output */
17
+ verbose?: boolean;
18
+ /** Content from stdin */
19
+ stdinContent?: string;
5
20
  }
6
- export interface AddResult {
7
- added: boolean;
8
- item: CslItem;
9
- idChanged: boolean;
10
- originalId?: string | undefined;
11
- duplicate?: DuplicateMatch | undefined;
12
- }
13
21
  /**
14
- * Add a new reference to the library.
22
+ * Result from add command execution.
23
+ */
24
+ export type AddCommandResult = AddReferencesResult;
25
+ export type { AddedItem, FailedItem, SkippedItem };
26
+ /**
27
+ * Execute add command.
28
+ * Uses context.library.import() which works for both local and server modes.
29
+ *
30
+ * @param options - Add command options
31
+ * @param context - Execution context
32
+ * @returns Add result containing added, failed, and skipped items
33
+ */
34
+ export declare function executeAdd(options: AddCommandOptions, context: ExecutionContext): Promise<AddCommandResult>;
35
+ /**
36
+ * Format add result for CLI output.
37
+ *
38
+ * @param result - Add result
39
+ * @param verbose - Show verbose error output
40
+ * @returns Formatted output string
41
+ */
42
+ export declare function formatAddOutput(result: AddCommandResult, verbose: boolean): string;
43
+ /**
44
+ * Determine exit code based on result.
15
45
  *
16
- * @param existing - Existing library items
17
- * @param newItem - New item to add
18
- * @param options - Add options
19
- * @returns Add result
46
+ * @param result - Add result
47
+ * @returns Exit code (0 for success/partial success, 1 for complete failure)
20
48
  */
21
- export declare function add(existing: CslItem[], newItem: CslItem, options: AddOptions): Promise<AddResult>;
49
+ export declare function getExitCode(result: AddCommandResult): number;
22
50
  //# sourceMappingURL=add.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAExE,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CACxC;AAyCD;;;;;;;GAOG;AACH,wBAAsB,GAAG,CACvB,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,SAAS,CAAC,CA+BpB"}
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/add.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,WAAW,EACZ,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,8CAA8C;IAC9C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,+BAA+B;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gCAAgC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAGnD,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AAKnD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAgB3B;AAiCD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAgClF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAa5D"}
@@ -0,0 +1,49 @@
1
+ import type { CiteResult } from "../../features/operations/cite.js";
2
+ import type { ExecutionContext } from "../execution-context.js";
3
+ /**
4
+ * Options for the cite command.
5
+ */
6
+ export interface CiteCommandOptions {
7
+ identifiers: string[];
8
+ uuid?: boolean;
9
+ style?: string;
10
+ cslFile?: string;
11
+ locale?: string;
12
+ format?: "text" | "html" | "rtf";
13
+ inText?: boolean;
14
+ }
15
+ /**
16
+ * Result from cite command execution.
17
+ */
18
+ export type CiteCommandResult = CiteResult;
19
+ /**
20
+ * Execute cite command.
21
+ * Uses context.library.cite() which works for both local and server modes.
22
+ *
23
+ * @param options - Cite command options
24
+ * @param context - Execution context
25
+ * @returns Cite result containing per-identifier results
26
+ */
27
+ export declare function executeCite(options: CiteCommandOptions, context: ExecutionContext): Promise<CiteCommandResult>;
28
+ /**
29
+ * Format cite result for CLI output.
30
+ *
31
+ * @param result - Cite result
32
+ * @returns Formatted output string (for stdout)
33
+ */
34
+ export declare function formatCiteOutput(result: CiteCommandResult): string;
35
+ /**
36
+ * Format cite errors for stderr.
37
+ *
38
+ * @param result - Cite result
39
+ * @returns Error messages to write to stderr
40
+ */
41
+ export declare function formatCiteErrors(result: CiteCommandResult): string;
42
+ /**
43
+ * Determine exit code based on result.
44
+ *
45
+ * @param result - Cite result
46
+ * @returns Exit code (0 for success/partial success, 1 for complete failure)
47
+ */
48
+ export declare function getCiteExitCode(result: CiteCommandResult): number;
49
+ //# sourceMappingURL=cite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cite.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/cite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAwB,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC1F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAiC3C;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAI5B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAQlE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAQlE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAWjE"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Fulltext CLI commands: attach, get, detach
3
+ *
4
+ * Uses ILibrary interface for unified operations across local and server modes.
5
+ */
6
+ import type { FulltextType } from "../../features/fulltext/index.js";
7
+ import { type FulltextAttachResult, type FulltextDetachResult, type FulltextGetResult } from "../../features/operations/fulltext/index.js";
8
+ import type { ExecutionContext } from "../execution-context.js";
9
+ /**
10
+ * Options for fulltext attach command
11
+ */
12
+ export interface FulltextAttachOptions {
13
+ identifier: string;
14
+ filePath?: string;
15
+ type?: FulltextType;
16
+ move?: boolean;
17
+ force?: boolean;
18
+ byUuid?: boolean;
19
+ fulltextDirectory: string;
20
+ stdinContent?: Buffer;
21
+ }
22
+ /**
23
+ * Options for fulltext get command
24
+ */
25
+ export interface FulltextGetOptions {
26
+ identifier: string;
27
+ type?: FulltextType;
28
+ stdout?: boolean;
29
+ byUuid?: boolean;
30
+ fulltextDirectory: string;
31
+ }
32
+ /**
33
+ * Options for fulltext detach command
34
+ */
35
+ export interface FulltextDetachOptions {
36
+ identifier: string;
37
+ type?: FulltextType;
38
+ delete?: boolean;
39
+ force?: boolean;
40
+ byUuid?: boolean;
41
+ fulltextDirectory: string;
42
+ }
43
+ export type { FulltextAttachResult, FulltextGetResult, FulltextDetachResult };
44
+ /**
45
+ * Execute fulltext attach command
46
+ */
47
+ export declare function executeFulltextAttach(options: FulltextAttachOptions, context: ExecutionContext): Promise<FulltextAttachResult>;
48
+ /**
49
+ * Execute fulltext get command
50
+ */
51
+ export declare function executeFulltextGet(options: FulltextGetOptions, context: ExecutionContext): Promise<FulltextGetResult>;
52
+ /**
53
+ * Execute fulltext detach command
54
+ */
55
+ export declare function executeFulltextDetach(options: FulltextDetachOptions, context: ExecutionContext): Promise<FulltextDetachResult>;
56
+ /**
57
+ * Format fulltext attach output
58
+ */
59
+ export declare function formatFulltextAttachOutput(result: FulltextAttachResult): string;
60
+ /**
61
+ * Format fulltext get output
62
+ */
63
+ export declare function formatFulltextGetOutput(result: FulltextGetResult): string;
64
+ /**
65
+ * Format fulltext detach output
66
+ */
67
+ export declare function formatFulltextDetachOutput(result: FulltextDetachResult): string;
68
+ /**
69
+ * Get exit code for fulltext command result
70
+ */
71
+ export declare function getFulltextExitCode(result: FulltextAttachResult | FulltextGetResult | FulltextDetachResult): number;
72
+ //# sourceMappingURL=fulltext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fulltext.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/fulltext.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EAOvB,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,OAAO,CAAC;IACjB,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,OAAO,CAAC;IACjB,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,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAGD,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,CAAC;AAE9E;;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;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,mBAAmB,CACjC,MAAM,EAAE,oBAAoB,GAAG,iBAAiB,GAAG,oBAAoB,GACtE,MAAM,CAER"}