@ncukondo/reference-manager 0.24.0 → 0.25.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 +44 -1
- package/dist/chunks/{SearchableMultiSelect-BigM9xv_.js → SearchableMultiSelect-B7qEWPDT.js} +2 -2
- package/dist/chunks/{SearchableMultiSelect-BigM9xv_.js.map → SearchableMultiSelect-B7qEWPDT.js.map} +1 -1
- package/dist/chunks/{action-menu-ByDpq-KF.js → action-menu-DD0RtNVD.js} +3 -3
- package/dist/chunks/{action-menu-ByDpq-KF.js.map → action-menu-DD0RtNVD.js.map} +1 -1
- package/dist/chunks/checker-7pzK2XSC.js +92 -0
- package/dist/chunks/checker-7pzK2XSC.js.map +1 -0
- package/dist/chunks/crossref-client-DGNz4PNW.js +52 -0
- package/dist/chunks/crossref-client-DGNz4PNW.js.map +1 -0
- package/dist/chunks/fix-interaction-BpfMLRNY.js +203 -0
- package/dist/chunks/fix-interaction-BpfMLRNY.js.map +1 -0
- package/dist/chunks/{index-CKY11DzK.js → index-CYEise6v.js} +4 -4
- package/dist/chunks/{index-CKY11DzK.js.map → index-CYEise6v.js.map} +1 -1
- package/dist/chunks/{index-DWAtvFtp.js → index-D2HsxXnK.js} +203 -21
- package/dist/chunks/index-D2HsxXnK.js.map +1 -0
- package/dist/chunks/{index-DVsuPpMS.js → index-PQkbePWV.js} +3 -3
- package/dist/chunks/index-PQkbePWV.js.map +1 -0
- package/dist/chunks/{index-ChvsE9WF.js → index-QTYx5RaF.js} +315 -28
- package/dist/chunks/index-QTYx5RaF.js.map +1 -0
- package/dist/chunks/{loader-CV71qNY2.js → loader-B-fte1uv.js} +19 -8
- package/dist/chunks/loader-B-fte1uv.js.map +1 -0
- package/dist/chunks/pubmed-client-J18fg3fG.js +51 -0
- package/dist/chunks/pubmed-client-J18fg3fG.js.map +1 -0
- package/dist/chunks/{reference-select-CrOVXP7v.js → reference-select-Qpgt9cbN.js} +3 -3
- package/dist/chunks/{reference-select-CrOVXP7v.js.map → reference-select-Qpgt9cbN.js.map} +1 -1
- package/dist/chunks/{style-select-BVP0KQz4.js → style-select-mEMoWbM2.js} +3 -3
- package/dist/chunks/{style-select-BVP0KQz4.js.map → style-select-mEMoWbM2.js.map} +1 -1
- package/dist/cli/commands/check.d.ts +42 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/index.d.ts +2 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/help/search-help.d.ts +6 -0
- package/dist/cli/help/search-help.d.ts.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/server-client.d.ts +2 -1
- package/dist/cli/server-client.d.ts.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/env-override.d.ts.map +1 -1
- package/dist/config/key-parser.d.ts.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/schema.d.ts +3 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/features/check/checker.d.ts +18 -0
- package/dist/features/check/checker.d.ts.map +1 -0
- package/dist/features/check/crossref-client.d.ts +24 -0
- package/dist/features/check/crossref-client.d.ts.map +1 -0
- package/dist/features/check/fix-actions.d.ts +16 -0
- package/dist/features/check/fix-actions.d.ts.map +1 -0
- package/dist/features/check/fix-interaction.d.ts +11 -0
- package/dist/features/check/fix-interaction.d.ts.map +1 -0
- package/dist/features/check/pubmed-client.d.ts +20 -0
- package/dist/features/check/pubmed-client.d.ts.map +1 -0
- package/dist/features/check/types.d.ts +23 -0
- package/dist/features/check/types.d.ts.map +1 -0
- package/dist/features/operations/check.d.ts +28 -0
- package/dist/features/operations/check.d.ts.map +1 -0
- package/dist/features/operations/index.d.ts +1 -0
- package/dist/features/operations/index.d.ts.map +1 -1
- package/dist/features/operations/library-operations.d.ts +8 -0
- package/dist/features/operations/library-operations.d.ts.map +1 -1
- package/dist/features/operations/operations-library.d.ts +2 -0
- package/dist/features/operations/operations-library.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/tools/check.d.ts +10 -0
- package/dist/mcp/tools/check.d.ts.map +1 -0
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/routes/check.d.ts +4 -0
- package/dist/server/routes/check.d.ts.map +1 -0
- package/dist/server.js +3 -3
- package/package.json +1 -1
- package/dist/chunks/index-ChvsE9WF.js.map +0 -1
- package/dist/chunks/index-DVsuPpMS.js.map +0 -1
- package/dist/chunks/index-DWAtvFtp.js.map +0 -1
- package/dist/chunks/loader-CV71qNY2.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a } from "./index-
|
|
2
|
-
import { d, g, l, o, s } from "./index-
|
|
1
|
+
import { a } from "./index-D2HsxXnK.js";
|
|
2
|
+
import { d, g, l, o, s } from "./index-QTYx5RaF.js";
|
|
3
3
|
export {
|
|
4
4
|
a as addAttachment,
|
|
5
5
|
d as detachAttachment,
|
|
@@ -8,4 +8,4 @@ export {
|
|
|
8
8
|
o as openAttachment,
|
|
9
9
|
s as syncAttachments
|
|
10
10
|
};
|
|
11
|
-
//# sourceMappingURL=index-
|
|
11
|
+
//# sourceMappingURL=index-PQkbePWV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-PQkbePWV.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
|
@@ -5,9 +5,9 @@ import { promises, readFileSync, existsSync, mkdirSync, writeFileSync } from "no
|
|
|
5
5
|
import * as os from "node:os";
|
|
6
6
|
import * as path from "node:path";
|
|
7
7
|
import path__default, { join, basename, dirname } from "node:path";
|
|
8
|
-
import { n as normalizePathForOutput, d as deleteDirectoryIfEmpty, p as parseFilename, i as isReservedRole, e as ensureDirectory, a as addAttachment, R as RESERVED_ROLES,
|
|
8
|
+
import { n as normalizePathForOutput, d as deleteDirectoryIfEmpty, p as parseFilename, i as isReservedRole, e as ensureDirectory, a as addAttachment, R as RESERVED_ROLES, b as generateFilename, c as findFulltextFiles, h as findFulltextFile, j as extensionToFormat, k as fulltextAttach, l as fulltextGet, m as fulltextDiscover, o as fulltextFetch, q as fulltextConvert, r as getExtension, s as getDefaultExportFromCjs, B as BUILTIN_STYLES, t as getFulltextAttachmentTypes, u as startServerWithFileWatcher } from "./index-D2HsxXnK.js";
|
|
9
9
|
import { readFile, unlink, stat, readdir, rename } from "node:fs/promises";
|
|
10
|
-
import { o as openWithSystemApp, l as loadConfig, e as getDefaultCurrentDirConfigFilename, h as getDefaultUserConfigPath } from "./loader-
|
|
10
|
+
import { o as openWithSystemApp, l as loadConfig, e as getDefaultCurrentDirConfigFilename, h as getDefaultUserConfigPath } from "./loader-B-fte1uv.js";
|
|
11
11
|
import { spawn, spawnSync } from "node:child_process";
|
|
12
12
|
import process$1, { stdin, stdout } from "node:process";
|
|
13
13
|
import * as readline from "node:readline";
|
|
@@ -19,7 +19,7 @@ import "@citation-js/plugin-csl";
|
|
|
19
19
|
import { ZodOptional as ZodOptional$2, z } from "zod";
|
|
20
20
|
import { serve } from "@hono/node-server";
|
|
21
21
|
const name = "@ncukondo/reference-manager";
|
|
22
|
-
const version$1 = "0.
|
|
22
|
+
const version$1 = "0.25.0";
|
|
23
23
|
const description$1 = "A local reference management tool using CSL-JSON as the single source of truth";
|
|
24
24
|
const packageJson = {
|
|
25
25
|
name,
|
|
@@ -902,15 +902,15 @@ class OperationsLibrary {
|
|
|
902
902
|
}
|
|
903
903
|
// High-level operations
|
|
904
904
|
async search(options) {
|
|
905
|
-
const { searchReferences } = await import("./index-
|
|
905
|
+
const { searchReferences } = await import("./index-D2HsxXnK.js").then((n) => n.E);
|
|
906
906
|
return searchReferences(this.library, options);
|
|
907
907
|
}
|
|
908
908
|
async list(options) {
|
|
909
|
-
const { listReferences } = await import("./index-
|
|
909
|
+
const { listReferences } = await import("./index-D2HsxXnK.js").then((n) => n.D);
|
|
910
910
|
return listReferences(this.library, options ?? {});
|
|
911
911
|
}
|
|
912
912
|
async cite(options) {
|
|
913
|
-
const { citeReferences } = await import("./index-
|
|
913
|
+
const { citeReferences } = await import("./index-D2HsxXnK.js").then((n) => n.C);
|
|
914
914
|
const defaultStyle = options.defaultStyle ?? this.citationConfig?.defaultStyle;
|
|
915
915
|
const cslDirectory = options.cslDirectory ?? this.citationConfig?.cslDirectory;
|
|
916
916
|
const mergedOptions = {
|
|
@@ -921,32 +921,36 @@ class OperationsLibrary {
|
|
|
921
921
|
return citeReferences(this.library, mergedOptions);
|
|
922
922
|
}
|
|
923
923
|
async import(inputs, options) {
|
|
924
|
-
const { addReferences } = await import("./index-
|
|
924
|
+
const { addReferences } = await import("./index-D2HsxXnK.js").then((n) => n.z);
|
|
925
925
|
return addReferences(inputs, this.library, options ?? {});
|
|
926
926
|
}
|
|
927
|
+
async check(options) {
|
|
928
|
+
const { checkReferences } = await import("./index-D2HsxXnK.js").then((n) => n.A);
|
|
929
|
+
return checkReferences(this.library, options);
|
|
930
|
+
}
|
|
927
931
|
// Attachment operations
|
|
928
932
|
async attachAdd(options) {
|
|
929
|
-
const { addAttachment: addAttachment2 } = await import("./index-
|
|
933
|
+
const { addAttachment: addAttachment2 } = await import("./index-PQkbePWV.js");
|
|
930
934
|
return addAttachment2(this.library, options);
|
|
931
935
|
}
|
|
932
936
|
async attachList(options) {
|
|
933
|
-
const { listAttachments: listAttachments2 } = await import("./index-
|
|
937
|
+
const { listAttachments: listAttachments2 } = await import("./index-PQkbePWV.js");
|
|
934
938
|
return listAttachments2(this.library, options);
|
|
935
939
|
}
|
|
936
940
|
async attachGet(options) {
|
|
937
|
-
const { getAttachment: getAttachment2 } = await import("./index-
|
|
941
|
+
const { getAttachment: getAttachment2 } = await import("./index-PQkbePWV.js");
|
|
938
942
|
return getAttachment2(this.library, options);
|
|
939
943
|
}
|
|
940
944
|
async attachDetach(options) {
|
|
941
|
-
const { detachAttachment: detachAttachment2 } = await import("./index-
|
|
945
|
+
const { detachAttachment: detachAttachment2 } = await import("./index-PQkbePWV.js");
|
|
942
946
|
return detachAttachment2(this.library, options);
|
|
943
947
|
}
|
|
944
948
|
async attachSync(options) {
|
|
945
|
-
const { syncAttachments: syncAttachments2 } = await import("./index-
|
|
949
|
+
const { syncAttachments: syncAttachments2 } = await import("./index-PQkbePWV.js");
|
|
946
950
|
return syncAttachments2(this.library, options);
|
|
947
951
|
}
|
|
948
952
|
async attachOpen(options) {
|
|
949
|
-
const { openAttachment: openAttachment2 } = await import("./index-
|
|
953
|
+
const { openAttachment: openAttachment2 } = await import("./index-PQkbePWV.js");
|
|
950
954
|
return openAttachment2(this.library, options);
|
|
951
955
|
}
|
|
952
956
|
}
|
|
@@ -1084,6 +1088,18 @@ class ServerClient {
|
|
|
1084
1088
|
}
|
|
1085
1089
|
return await response.json();
|
|
1086
1090
|
}
|
|
1091
|
+
async check(options) {
|
|
1092
|
+
const url2 = `${this.baseUrl}/api/check`;
|
|
1093
|
+
const response = await fetch(url2, {
|
|
1094
|
+
method: "POST",
|
|
1095
|
+
headers: { "Content-Type": "application/json" },
|
|
1096
|
+
body: JSON.stringify(options)
|
|
1097
|
+
});
|
|
1098
|
+
if (!response.ok) {
|
|
1099
|
+
throw new Error(await response.text());
|
|
1100
|
+
}
|
|
1101
|
+
return await response.json();
|
|
1102
|
+
}
|
|
1087
1103
|
/**
|
|
1088
1104
|
* Generate citations for references.
|
|
1089
1105
|
* @param options - Cite options including identifiers and formatting
|
|
@@ -1790,7 +1806,7 @@ function getAttachExitCode(result) {
|
|
|
1790
1806
|
}
|
|
1791
1807
|
async function executeInteractiveSelect$2(context, config2) {
|
|
1792
1808
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
1793
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
1809
|
+
const { selectReferencesOrExit } = await import("./reference-select-Qpgt9cbN.js");
|
|
1794
1810
|
const allReferences = await context.library.getAll();
|
|
1795
1811
|
const identifiers = await withAlternateScreen2(
|
|
1796
1812
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -2281,6 +2297,192 @@ const attach = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
|
|
|
2281
2297
|
runInteractiveMode,
|
|
2282
2298
|
syncNewFilesWithRolePrompt
|
|
2283
2299
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2300
|
+
function buildCheckOptions(options, appConfig) {
|
|
2301
|
+
const opOptions = {};
|
|
2302
|
+
if (options.all) {
|
|
2303
|
+
opOptions.all = true;
|
|
2304
|
+
} else if (options.search) {
|
|
2305
|
+
opOptions.searchQuery = options.search;
|
|
2306
|
+
} else if (options.identifiers.length > 0) {
|
|
2307
|
+
opOptions.identifiers = options.identifiers;
|
|
2308
|
+
}
|
|
2309
|
+
if (options.uuid) {
|
|
2310
|
+
opOptions.idType = "uuid";
|
|
2311
|
+
}
|
|
2312
|
+
if (options.days !== void 0) {
|
|
2313
|
+
opOptions.skipDays = options.days;
|
|
2314
|
+
}
|
|
2315
|
+
if (options.noSave) {
|
|
2316
|
+
opOptions.save = false;
|
|
2317
|
+
}
|
|
2318
|
+
if (appConfig) {
|
|
2319
|
+
const pubmed = {};
|
|
2320
|
+
if (appConfig.pubmed.email) pubmed.email = appConfig.pubmed.email;
|
|
2321
|
+
if (appConfig.pubmed.apiKey) pubmed.apiKey = appConfig.pubmed.apiKey;
|
|
2322
|
+
opOptions.config = {
|
|
2323
|
+
...appConfig.email ? { email: appConfig.email } : {},
|
|
2324
|
+
pubmed
|
|
2325
|
+
};
|
|
2326
|
+
}
|
|
2327
|
+
return opOptions;
|
|
2328
|
+
}
|
|
2329
|
+
async function executeCheck(options, context, appConfig) {
|
|
2330
|
+
return context.library.check(buildCheckOptions(options, appConfig));
|
|
2331
|
+
}
|
|
2332
|
+
function getStatusLabel(result) {
|
|
2333
|
+
if (result.status === "skipped") return "[SKIPPED]";
|
|
2334
|
+
if (result.status === "ok") return "[OK]";
|
|
2335
|
+
const finding = result.findings[0];
|
|
2336
|
+
if (!finding) return "[WARNING]";
|
|
2337
|
+
switch (finding.type) {
|
|
2338
|
+
case "retracted":
|
|
2339
|
+
return "[RETRACTED]";
|
|
2340
|
+
case "concern":
|
|
2341
|
+
return "[CONCERN]";
|
|
2342
|
+
case "version_changed":
|
|
2343
|
+
return "[VERSION]";
|
|
2344
|
+
case "metadata_changed":
|
|
2345
|
+
return "[METADATA]";
|
|
2346
|
+
default:
|
|
2347
|
+
return "[WARNING]";
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
function formatFindingDetails(finding) {
|
|
2351
|
+
const lines = [];
|
|
2352
|
+
lines.push(` ${finding.message}`);
|
|
2353
|
+
if (finding.details?.retractionDoi) {
|
|
2354
|
+
lines.push(` Retraction notice: https://doi.org/${finding.details.retractionDoi}`);
|
|
2355
|
+
}
|
|
2356
|
+
if (finding.details?.newDoi) {
|
|
2357
|
+
lines.push(` New DOI: https://doi.org/${finding.details.newDoi}`);
|
|
2358
|
+
}
|
|
2359
|
+
return lines;
|
|
2360
|
+
}
|
|
2361
|
+
function formatCheckTextOutput(result) {
|
|
2362
|
+
const lines = [];
|
|
2363
|
+
for (const r of result.results) {
|
|
2364
|
+
const label = getStatusLabel(r);
|
|
2365
|
+
lines.push(`${label} ${r.id}`);
|
|
2366
|
+
for (const finding of r.findings) {
|
|
2367
|
+
lines.push(...formatFindingDetails(finding));
|
|
2368
|
+
}
|
|
2369
|
+
lines.push("");
|
|
2370
|
+
}
|
|
2371
|
+
const { summary } = result;
|
|
2372
|
+
const parts = [`${summary.total} checked`];
|
|
2373
|
+
if (summary.warnings > 0) parts.push(`${summary.warnings} warning(s)`);
|
|
2374
|
+
if (summary.ok > 0) parts.push(`${summary.ok} ok`);
|
|
2375
|
+
if (summary.skipped > 0) parts.push(`${summary.skipped} skipped`);
|
|
2376
|
+
lines.push(`Summary: ${parts.join(", ")}`);
|
|
2377
|
+
return lines.join("\n");
|
|
2378
|
+
}
|
|
2379
|
+
function formatCheckJsonOutput(result, options) {
|
|
2380
|
+
if (!options?.full || !options.items) {
|
|
2381
|
+
return result;
|
|
2382
|
+
}
|
|
2383
|
+
const results = result.results.map((r) => {
|
|
2384
|
+
const item = options.items?.get(r.id);
|
|
2385
|
+
return item ? { ...r, item } : r;
|
|
2386
|
+
});
|
|
2387
|
+
return { ...result, results };
|
|
2388
|
+
}
|
|
2389
|
+
async function handleCheckAction(identifiers, options, globalOpts) {
|
|
2390
|
+
const outputFormat = options.output ?? "text";
|
|
2391
|
+
if (options.fix && !isTTY()) {
|
|
2392
|
+
outputCheckError(new Error("--fix requires an interactive terminal (TTY)"), outputFormat);
|
|
2393
|
+
setExitCode(ExitCode.ERROR);
|
|
2394
|
+
return;
|
|
2395
|
+
}
|
|
2396
|
+
try {
|
|
2397
|
+
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
2398
|
+
const context = await createExecutionContext(config2, Library.load);
|
|
2399
|
+
const ids = await resolveIdentifiers$1(identifiers, options, context, config2);
|
|
2400
|
+
if (ids === null) return;
|
|
2401
|
+
const result = await executeCheck({ ...options, identifiers: ids }, context, config2);
|
|
2402
|
+
const needAllRefs = options.full && outputFormat === "json" || options.fix;
|
|
2403
|
+
const allRefs = needAllRefs ? await context.library.getAll() : void 0;
|
|
2404
|
+
const jsonOptions = buildJsonOptionsFromRefs(options, outputFormat, result, allRefs);
|
|
2405
|
+
outputCheckResult(result, outputFormat, jsonOptions);
|
|
2406
|
+
if (options.fix && result.summary.warnings > 0 && allRefs) {
|
|
2407
|
+
const { runFixInteraction } = await import("./fix-interaction-BpfMLRNY.js");
|
|
2408
|
+
const findItem = (id2) => allRefs.find((item) => item.id === id2);
|
|
2409
|
+
const fixResult = await runFixInteraction(result.results, context.library, findItem);
|
|
2410
|
+
const removedSuffix = fixResult.removed.length > 0 ? `, ${fixResult.removed.length} removed` : "";
|
|
2411
|
+
process.stderr.write(
|
|
2412
|
+
`
|
|
2413
|
+
Fix summary: ${fixResult.applied} applied, ${fixResult.skipped} skipped${removedSuffix}
|
|
2414
|
+
`
|
|
2415
|
+
);
|
|
2416
|
+
}
|
|
2417
|
+
setExitCode(ExitCode.SUCCESS);
|
|
2418
|
+
} catch (error) {
|
|
2419
|
+
outputCheckError(error, outputFormat);
|
|
2420
|
+
setExitCode(ExitCode.ERROR);
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
function buildJsonOptionsFromRefs(options, outputFormat, result, allRefs) {
|
|
2424
|
+
if (!options.full || outputFormat !== "json" || !allRefs) return void 0;
|
|
2425
|
+
const items2 = /* @__PURE__ */ new Map();
|
|
2426
|
+
for (const r of result.results) {
|
|
2427
|
+
const item = allRefs.find((ref2) => ref2.id === r.id);
|
|
2428
|
+
if (item) items2.set(r.id, item);
|
|
2429
|
+
}
|
|
2430
|
+
return { full: true, items: items2 };
|
|
2431
|
+
}
|
|
2432
|
+
async function resolveIdentifiers$1(identifiers, options, context, config2) {
|
|
2433
|
+
if (identifiers.length > 0 || options.all || options.search) {
|
|
2434
|
+
return identifiers;
|
|
2435
|
+
}
|
|
2436
|
+
if (isTTY()) {
|
|
2437
|
+
const ids = await selectReferencesInteractively(context, config2);
|
|
2438
|
+
if (ids.length === 0) {
|
|
2439
|
+
setExitCode(ExitCode.SUCCESS);
|
|
2440
|
+
return null;
|
|
2441
|
+
}
|
|
2442
|
+
return ids;
|
|
2443
|
+
}
|
|
2444
|
+
const stdinIds = await readIdentifiersFromStdin();
|
|
2445
|
+
if (stdinIds.length === 0) {
|
|
2446
|
+
process.stderr.write(
|
|
2447
|
+
"Error: No identifiers provided. Provide IDs, use --all, --search, or run interactively.\n"
|
|
2448
|
+
);
|
|
2449
|
+
setExitCode(ExitCode.ERROR);
|
|
2450
|
+
return null;
|
|
2451
|
+
}
|
|
2452
|
+
return stdinIds;
|
|
2453
|
+
}
|
|
2454
|
+
function outputCheckResult(result, format2, jsonOptions) {
|
|
2455
|
+
if (format2 === "json") {
|
|
2456
|
+
process.stdout.write(`${JSON.stringify(formatCheckJsonOutput(result, jsonOptions))}
|
|
2457
|
+
`);
|
|
2458
|
+
} else {
|
|
2459
|
+
process.stderr.write(`${formatCheckTextOutput(result)}
|
|
2460
|
+
`);
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
function outputCheckError(error, format2) {
|
|
2464
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2465
|
+
if (format2 === "json") {
|
|
2466
|
+
process.stdout.write(`${JSON.stringify({ error: message })}
|
|
2467
|
+
`);
|
|
2468
|
+
} else {
|
|
2469
|
+
process.stderr.write(`Error: ${message}
|
|
2470
|
+
`);
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
async function selectReferencesInteractively(context, config2) {
|
|
2474
|
+
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
2475
|
+
const { selectReferenceItemsOrExit } = await import("./reference-select-Qpgt9cbN.js");
|
|
2476
|
+
const allReferences = await context.library.getAll();
|
|
2477
|
+
if (allReferences.length === 0) {
|
|
2478
|
+
process.stderr.write("No references in library.\n");
|
|
2479
|
+
return [];
|
|
2480
|
+
}
|
|
2481
|
+
const selectedItems = await withAlternateScreen2(
|
|
2482
|
+
() => selectReferenceItemsOrExit(allReferences, { multiSelect: true }, config2.cli.tui)
|
|
2483
|
+
);
|
|
2484
|
+
return selectedItems.map((item) => item.id);
|
|
2485
|
+
}
|
|
2284
2486
|
async function validateOptions$2(options) {
|
|
2285
2487
|
if (options.output && !["text", "html", "rtf"].includes(options.output)) {
|
|
2286
2488
|
throw new Error(`Invalid output format '${options.output}'. Must be one of: text, html, rtf`);
|
|
@@ -2338,8 +2540,8 @@ function getCiteExitCode(result) {
|
|
|
2338
2540
|
}
|
|
2339
2541
|
async function executeInteractiveCite(options, context, config2) {
|
|
2340
2542
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
2341
|
-
const { runCiteFlow } = await import("./index-
|
|
2342
|
-
const { buildStyleChoices, listCustomStyles } = await import("./style-select-
|
|
2543
|
+
const { runCiteFlow } = await import("./index-CYEise6v.js");
|
|
2544
|
+
const { buildStyleChoices, listCustomStyles } = await import("./style-select-mEMoWbM2.js");
|
|
2343
2545
|
const { search } = await import("./file-watcher-Dlx0PolG.js").then((n) => n.B);
|
|
2344
2546
|
const { tokenize } = await import("./file-watcher-Dlx0PolG.js").then((n) => n.A);
|
|
2345
2547
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
@@ -2419,6 +2621,7 @@ async function handleCiteAction(identifiers, options, globalOpts) {
|
|
|
2419
2621
|
}
|
|
2420
2622
|
const ENV_OVERRIDE_MAP = {
|
|
2421
2623
|
REFERENCE_MANAGER_LIBRARY: "library",
|
|
2624
|
+
EMAIL: "email",
|
|
2422
2625
|
REFERENCE_MANAGER_ATTACHMENTS_DIR: "attachments.directory",
|
|
2423
2626
|
REFERENCE_MANAGER_CLI_DEFAULT_LIMIT: "cli.default_limit",
|
|
2424
2627
|
REFERENCE_MANAGER_MCP_DEFAULT_LIMIT: "mcp.default_limit",
|
|
@@ -2454,6 +2657,7 @@ const CONFIG_KEY_REGISTRY = [
|
|
|
2454
2657
|
description: "Log level",
|
|
2455
2658
|
enumValues: ["silent", "info", "debug"]
|
|
2456
2659
|
},
|
|
2660
|
+
{ key: "email", type: "string", description: "Fallback email for API services", optional: true },
|
|
2457
2661
|
// backup section
|
|
2458
2662
|
{ key: "backup.max_generations", type: "integer", description: "Maximum backup generations" },
|
|
2459
2663
|
{ key: "backup.max_age_days", type: "integer", description: "Maximum backup age in days" },
|
|
@@ -6938,7 +7142,7 @@ function formatEditOutput(result) {
|
|
|
6938
7142
|
}
|
|
6939
7143
|
async function executeInteractiveEdit(options, context, config2) {
|
|
6940
7144
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
6941
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
7145
|
+
const { selectReferencesOrExit } = await import("./reference-select-Qpgt9cbN.js");
|
|
6942
7146
|
const allReferences = await context.library.getAll();
|
|
6943
7147
|
const identifiers = await withAlternateScreen2(
|
|
6944
7148
|
() => selectReferencesOrExit(allReferences, { multiSelect: true }, config2.cli.tui)
|
|
@@ -10479,7 +10683,7 @@ function getFulltextExitCode(result) {
|
|
|
10479
10683
|
}
|
|
10480
10684
|
async function executeInteractiveSelect$1(context, config2) {
|
|
10481
10685
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
10482
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
10686
|
+
const { selectReferencesOrExit } = await import("./reference-select-Qpgt9cbN.js");
|
|
10483
10687
|
const allReferences = await context.library.getAll();
|
|
10484
10688
|
const identifiers = await withAlternateScreen2(
|
|
10485
10689
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -31328,6 +31532,53 @@ function registerAddTool(server, getLibraryOperations) {
|
|
|
31328
31532
|
}
|
|
31329
31533
|
);
|
|
31330
31534
|
}
|
|
31535
|
+
function formatCheckResult(result) {
|
|
31536
|
+
const lines = [];
|
|
31537
|
+
for (const r of result.results) {
|
|
31538
|
+
if (r.status === "ok") {
|
|
31539
|
+
lines.push(`[OK] ${r.id}`);
|
|
31540
|
+
} else if (r.status === "skipped") {
|
|
31541
|
+
lines.push(`[SKIPPED] ${r.id}`);
|
|
31542
|
+
} else {
|
|
31543
|
+
for (const f of r.findings) {
|
|
31544
|
+
lines.push(`[${f.type.toUpperCase()}] ${r.id}: ${f.message}`);
|
|
31545
|
+
}
|
|
31546
|
+
}
|
|
31547
|
+
}
|
|
31548
|
+
const { summary } = result;
|
|
31549
|
+
lines.push(
|
|
31550
|
+
`
|
|
31551
|
+
Summary: ${summary.total} checked, ${summary.ok} ok, ${summary.warnings} warnings, ${summary.skipped} skipped`
|
|
31552
|
+
);
|
|
31553
|
+
return lines.join("\n");
|
|
31554
|
+
}
|
|
31555
|
+
function registerCheckTool(server, getLibraryOperations) {
|
|
31556
|
+
server.registerTool(
|
|
31557
|
+
"check",
|
|
31558
|
+
{
|
|
31559
|
+
description: "Check references for retractions, expressions of concern, and version changes by querying Crossref and PubMed APIs.",
|
|
31560
|
+
inputSchema: {
|
|
31561
|
+
ids: z.array(z.string()).optional().describe("Array of reference IDs to check. Omit if using 'all'."),
|
|
31562
|
+
all: z.boolean().optional().describe("Check all references in library"),
|
|
31563
|
+
skipDays: z.number().optional().describe("Skip references checked within n days (default: 7)"),
|
|
31564
|
+
save: z.boolean().optional().describe("Whether to save results to library (default: true)")
|
|
31565
|
+
}
|
|
31566
|
+
},
|
|
31567
|
+
async (args) => {
|
|
31568
|
+
const libraryOps = getLibraryOperations();
|
|
31569
|
+
const options = {};
|
|
31570
|
+
if (args.ids?.length) options.identifiers = args.ids;
|
|
31571
|
+
if (args.all) options.all = true;
|
|
31572
|
+
if (args.skipDays !== void 0) options.skipDays = args.skipDays;
|
|
31573
|
+
if (args.save !== void 0) options.save = args.save;
|
|
31574
|
+
const result = await libraryOps.check(options);
|
|
31575
|
+
const text = formatCheckResult(result);
|
|
31576
|
+
return {
|
|
31577
|
+
content: [{ type: "text", text }]
|
|
31578
|
+
};
|
|
31579
|
+
}
|
|
31580
|
+
);
|
|
31581
|
+
}
|
|
31331
31582
|
function registerCiteTool(server, getLibraryOperations) {
|
|
31332
31583
|
server.registerTool(
|
|
31333
31584
|
"cite",
|
|
@@ -31718,6 +31969,7 @@ function registerAllTools(server, getLibraryOperations, getConfig) {
|
|
|
31718
31969
|
registerSearchTool(server, getLibraryOperations, getConfig);
|
|
31719
31970
|
registerListTool(server, getLibraryOperations, getConfig);
|
|
31720
31971
|
registerCiteTool(server, getLibraryOperations);
|
|
31972
|
+
registerCheckTool(server, getLibraryOperations);
|
|
31721
31973
|
registerAddTool(server, getLibraryOperations);
|
|
31722
31974
|
registerRemoveTool(server, getLibraryOperations);
|
|
31723
31975
|
registerFulltextAttachTool(server, getLibraryOperations, getConfig);
|
|
@@ -31779,7 +32031,7 @@ async function mcpStart(options) {
|
|
|
31779
32031
|
async function executeRemove(options, context) {
|
|
31780
32032
|
const { identifier, idType = "id", fulltextDirectory, deleteFulltext = false } = options;
|
|
31781
32033
|
if (context.mode === "local" && deleteFulltext && fulltextDirectory) {
|
|
31782
|
-
const { removeReference } = await import("./index-
|
|
32034
|
+
const { removeReference } = await import("./index-D2HsxXnK.js").then((n) => n.x);
|
|
31783
32035
|
return removeReference(context.library, {
|
|
31784
32036
|
identifier,
|
|
31785
32037
|
idType,
|
|
@@ -31834,7 +32086,7 @@ Continue?`;
|
|
|
31834
32086
|
}
|
|
31835
32087
|
async function executeInteractiveRemove(context, config2) {
|
|
31836
32088
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
31837
|
-
const { selectReferenceItemsOrExit } = await import("./reference-select-
|
|
32089
|
+
const { selectReferenceItemsOrExit } = await import("./reference-select-Qpgt9cbN.js");
|
|
31838
32090
|
const allReferences = await context.library.getAll();
|
|
31839
32091
|
const selectedItems = await withAlternateScreen2(
|
|
31840
32092
|
() => selectReferenceItemsOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -32059,7 +32311,7 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
32059
32311
|
validateInteractiveOptions(options);
|
|
32060
32312
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
32061
32313
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32062
|
-
const { runSearchFlow } = await import("./index-
|
|
32314
|
+
const { runSearchFlow } = await import("./index-CYEise6v.js");
|
|
32063
32315
|
const { search } = await import("./file-watcher-Dlx0PolG.js").then((n) => n.B);
|
|
32064
32316
|
const { tokenize } = await import("./file-watcher-Dlx0PolG.js").then((n) => n.A);
|
|
32065
32317
|
checkTTY();
|
|
@@ -32078,7 +32330,7 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
32078
32330
|
})
|
|
32079
32331
|
);
|
|
32080
32332
|
if (result.selectedItems && !result.cancelled) {
|
|
32081
|
-
const { isSideEffectAction } = await import("./action-menu-
|
|
32333
|
+
const { isSideEffectAction } = await import("./action-menu-DD0RtNVD.js");
|
|
32082
32334
|
if (isSideEffectAction(result.action)) {
|
|
32083
32335
|
await executeSideEffectAction(result.action, result.selectedItems, context, config2);
|
|
32084
32336
|
return { output: "", cancelled: false, action: result.action };
|
|
@@ -32094,7 +32346,7 @@ async function executeSideEffectAction(action, items2, context, config2) {
|
|
|
32094
32346
|
switch (action) {
|
|
32095
32347
|
case "open-url": {
|
|
32096
32348
|
const { resolveDefaultUrl: resolveDefaultUrl2 } = await Promise.resolve().then(() => url);
|
|
32097
|
-
const { openWithSystemApp: openWithSystemApp2 } = await import("./loader-
|
|
32349
|
+
const { openWithSystemApp: openWithSystemApp2 } = await import("./loader-B-fte1uv.js").then((n) => n.j);
|
|
32098
32350
|
const item = items2[0];
|
|
32099
32351
|
if (!item) return;
|
|
32100
32352
|
const url$1 = resolveDefaultUrl2(item);
|
|
@@ -32481,7 +32733,7 @@ function formatUpdateOutput(result, identifier) {
|
|
|
32481
32733
|
}
|
|
32482
32734
|
async function executeInteractiveUpdate(context, config2) {
|
|
32483
32735
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32484
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
32736
|
+
const { selectReferencesOrExit } = await import("./reference-select-Qpgt9cbN.js");
|
|
32485
32737
|
const allReferences = await context.library.getAll();
|
|
32486
32738
|
const identifiers = await withAlternateScreen2(
|
|
32487
32739
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -32776,7 +33028,7 @@ function getUrlExitCode(result) {
|
|
|
32776
33028
|
}
|
|
32777
33029
|
async function executeInteractiveSelect(context, config2) {
|
|
32778
33030
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32779
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
33031
|
+
const { selectReferencesOrExit } = await import("./reference-select-Qpgt9cbN.js");
|
|
32780
33032
|
const allReferences = await context.library.getAll();
|
|
32781
33033
|
const identifiers = await withAlternateScreen2(
|
|
32782
33034
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -33102,6 +33354,33 @@ function registerCompletionCommand(program) {
|
|
|
33102
33354
|
}
|
|
33103
33355
|
});
|
|
33104
33356
|
}
|
|
33357
|
+
function buildSearchHelpText() {
|
|
33358
|
+
return `
|
|
33359
|
+
QUERY SYNTAX
|
|
33360
|
+
Free text machine learning Search all fields (AND logic)
|
|
33361
|
+
Phrase "machine learning" Exact phrase match
|
|
33362
|
+
Field author:Smith Search specific field
|
|
33363
|
+
Field+Phrase author:"John Smith" Field with phrase
|
|
33364
|
+
|
|
33365
|
+
FIELDS
|
|
33366
|
+
author, title, year, doi, pmid, pmcid, isbn, url, keyword, tag, id
|
|
33367
|
+
|
|
33368
|
+
CASE SENSITIVITY
|
|
33369
|
+
Consecutive uppercase (2+ letters) is case-sensitive:
|
|
33370
|
+
AI → matches "AI therapy", not "ai therapy"
|
|
33371
|
+
RNA → matches "mRNA synthesis", not "mrna synthesis"
|
|
33372
|
+
Other text is case-insensitive:
|
|
33373
|
+
api → matches "API", "api", "Api"
|
|
33374
|
+
|
|
33375
|
+
EXAMPLES
|
|
33376
|
+
$ ref search "machine learning"
|
|
33377
|
+
$ ref search author:Smith year:2020
|
|
33378
|
+
$ ref search author:"John Smith" title:introduction
|
|
33379
|
+
$ ref search tag:review --sort published --order desc
|
|
33380
|
+
$ ref search AI therapy # AI is case-sensitive
|
|
33381
|
+
$ ref search id:smith2023 --output json
|
|
33382
|
+
$ ref search --tui # Interactive mode`;
|
|
33383
|
+
}
|
|
33105
33384
|
function createProgram() {
|
|
33106
33385
|
const program = new Command();
|
|
33107
33386
|
program.name("reference-manager").version(packageJson.version).description(packageJson.description);
|
|
@@ -33120,6 +33399,7 @@ function createProgram() {
|
|
|
33120
33399
|
registerRemoveCommand(program);
|
|
33121
33400
|
registerUpdateCommand(program);
|
|
33122
33401
|
registerEditCommand(program);
|
|
33402
|
+
registerCheckCommand(program);
|
|
33123
33403
|
registerCiteCommand(program);
|
|
33124
33404
|
registerServerCommand(program);
|
|
33125
33405
|
registerFulltextCommand(program);
|
|
@@ -33219,7 +33499,9 @@ async function handleSearchAction(query, options, program) {
|
|
|
33219
33499
|
}
|
|
33220
33500
|
}
|
|
33221
33501
|
function registerSearchCommand(program) {
|
|
33222
|
-
program.command("search").description(
|
|
33502
|
+
program.command("search").description(
|
|
33503
|
+
"Search references in the library.\n\nSupports field-specific search with field:value syntax and phrase search\nwith quoted strings. Consecutive uppercase letters (AI, RNA) are matched\ncase-sensitively; other text is matched case-insensitively."
|
|
33504
|
+
).argument("[query]", "Search query (required unless using --tui)").addHelpText("after", buildSearchHelpText()).option("-t, --tui", "Enable TUI (interactive) search mode").option(
|
|
33223
33505
|
"-o, --output <format>",
|
|
33224
33506
|
"Output format: pretty|json|bibtex|ids|uuid|pandoc-key|latex-key"
|
|
33225
33507
|
).option("--json", "Alias for --output json").option("--bibtex", "Alias for --output bibtex").option("--ids-only", "Alias for --output ids").option("--uuid-only", "Alias for --output uuid").option("-k, --key", "Output citation keys (uses citation.default_key_format config)").option("--pandoc-key", "Alias for --output pandoc-key").option("--latex-key", "Alias for --output latex-key").option("--sort <field>", "Sort by field: created|updated|published|author|title|relevance").option("--order <order>", "Sort order: asc|desc").option("-n, --limit <n>", "Maximum number of results", Number.parseInt).option("--offset <n>", "Number of results to skip", Number.parseInt).action(async (query, options) => {
|
|
@@ -33279,7 +33561,7 @@ function shouldAutoFetch(cliFlag, configEnabled) {
|
|
|
33279
33561
|
return configEnabled;
|
|
33280
33562
|
}
|
|
33281
33563
|
async function performAutoFetch(addedItems, context, config2) {
|
|
33282
|
-
const { fulltextFetch: fulltextFetch2 } = await import("./index-
|
|
33564
|
+
const { fulltextFetch: fulltextFetch2 } = await import("./index-D2HsxXnK.js").then((n) => n.w);
|
|
33283
33565
|
const fetchResults = await autoFetchFulltext(addedItems, context, {
|
|
33284
33566
|
fulltextConfig: config2.fulltext,
|
|
33285
33567
|
fulltextDirectory: config2.attachments.directory,
|
|
@@ -33359,6 +33641,11 @@ function registerEditCommand(program) {
|
|
|
33359
33641
|
await handleEditAction(identifiers, options, program.opts());
|
|
33360
33642
|
});
|
|
33361
33643
|
}
|
|
33644
|
+
function registerCheckCommand(program) {
|
|
33645
|
+
program.command("check").description("Check references for retractions, expressions of concern, and version changes").argument("[ids...]", "Citation keys or UUIDs to check (interactive selection if omitted)").option("--all", "Check all references in library").option("--search <query>", "Check references matching search query").option("--uuid", "Interpret identifiers as UUIDs").option("-o, --output <format>", "Output format: text|json", "text").option("--full", "Include full details in JSON output").option("--no-save", "Report only, do not save results to library").option("--days <n>", "Skip references checked within n days (default: 7)", Number.parseInt).option("--fix", "Interactive repair for findings (TTY only)").action(async (ids, options) => {
|
|
33646
|
+
await handleCheckAction(ids, options, program.opts());
|
|
33647
|
+
});
|
|
33648
|
+
}
|
|
33362
33649
|
function registerCiteCommand(program) {
|
|
33363
33650
|
program.command("cite").description("Generate formatted citations for references").argument(
|
|
33364
33651
|
"[id-or-uuid...]",
|
|
@@ -33558,4 +33845,4 @@ export {
|
|
|
33558
33845
|
restoreStdinAfterInk as r,
|
|
33559
33846
|
syncAttachments as s
|
|
33560
33847
|
};
|
|
33561
|
-
//# sourceMappingURL=index-
|
|
33848
|
+
//# sourceMappingURL=index-QTYx5RaF.js.map
|