@ncukondo/reference-manager 0.25.0 → 0.27.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 +14 -2
- package/dist/chunks/{SearchableMultiSelect-B7qEWPDT.js → SearchableMultiSelect-D6-pj_XI.js} +2 -2
- package/dist/chunks/{SearchableMultiSelect-B7qEWPDT.js.map → SearchableMultiSelect-D6-pj_XI.js.map} +1 -1
- package/dist/chunks/{action-menu-DD0RtNVD.js → action-menu-DP1rmCkH.js} +3 -3
- package/dist/chunks/{action-menu-DD0RtNVD.js.map → action-menu-DP1rmCkH.js.map} +1 -1
- package/dist/chunks/checker-B-SL7krG.js +170 -0
- package/dist/chunks/checker-B-SL7krG.js.map +1 -0
- package/dist/chunks/crossref-client-D6g3pLUI.js +94 -0
- package/dist/chunks/crossref-client-D6g3pLUI.js.map +1 -0
- package/dist/chunks/{fix-interaction-BpfMLRNY.js → fix-interaction-CTIvq9t4.js} +79 -20
- package/dist/chunks/fix-interaction-CTIvq9t4.js.map +1 -0
- package/dist/chunks/{index-QTYx5RaF.js → index-B8ST0WLa.js} +235 -79
- package/dist/chunks/index-B8ST0WLa.js.map +1 -0
- package/dist/chunks/{index-CYEise6v.js → index-Bo1JIDmF.js} +4 -4
- package/dist/chunks/{index-CYEise6v.js.map → index-Bo1JIDmF.js.map} +1 -1
- package/dist/chunks/{index-D2HsxXnK.js → index-DUpYvm-W.js} +43 -25
- package/dist/chunks/index-DUpYvm-W.js.map +1 -0
- package/dist/chunks/{index-PQkbePWV.js → index-F4gbDFWf.js} +3 -3
- package/dist/chunks/index-F4gbDFWf.js.map +1 -0
- package/dist/chunks/metadata-comparator-C5zfoYdK.js +137 -0
- package/dist/chunks/metadata-comparator-C5zfoYdK.js.map +1 -0
- package/dist/chunks/{pubmed-client-J18fg3fG.js → pubmed-client-mGn5jDIc.js} +2 -2
- package/dist/chunks/{pubmed-client-J18fg3fG.js.map → pubmed-client-mGn5jDIc.js.map} +1 -1
- package/dist/chunks/{reference-select-Qpgt9cbN.js → reference-select-DtzpiOvp.js} +3 -3
- package/dist/chunks/{reference-select-Qpgt9cbN.js.map → reference-select-DtzpiOvp.js.map} +1 -1
- package/dist/chunks/{style-select-mEMoWbM2.js → style-select-BT-HOyFf.js} +3 -3
- package/dist/chunks/{style-select-mEMoWbM2.js.map → style-select-BT-HOyFf.js.map} +1 -1
- package/dist/cli/commands/check.d.ts +2 -1
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/fulltext.d.ts +12 -7
- package/dist/cli/commands/fulltext.d.ts.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/features/check/checker.d.ts +1 -0
- package/dist/features/check/checker.d.ts.map +1 -1
- package/dist/features/check/crossref-client.d.ts +16 -0
- package/dist/features/check/crossref-client.d.ts.map +1 -1
- package/dist/features/check/fix-actions.d.ts +1 -1
- package/dist/features/check/fix-actions.d.ts.map +1 -1
- package/dist/features/check/fix-interaction.d.ts.map +1 -1
- package/dist/features/check/metadata-comparator.d.ts +37 -0
- package/dist/features/check/metadata-comparator.d.ts.map +1 -0
- package/dist/features/check/metadata-similarity.d.ts +22 -0
- package/dist/features/check/metadata-similarity.d.ts.map +1 -0
- package/dist/features/check/types.d.ts +6 -1
- package/dist/features/check/types.d.ts.map +1 -1
- package/dist/features/operations/check.d.ts +1 -0
- package/dist/features/operations/check.d.ts.map +1 -1
- package/dist/mcp/tools/check.d.ts +1 -0
- package/dist/mcp/tools/check.d.ts.map +1 -1
- package/dist/server/routes/check.d.ts.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/checker-7pzK2XSC.js +0 -92
- package/dist/chunks/checker-7pzK2XSC.js.map +0 -1
- package/dist/chunks/crossref-client-DGNz4PNW.js +0 -52
- package/dist/chunks/crossref-client-DGNz4PNW.js.map +0 -1
- package/dist/chunks/fix-interaction-BpfMLRNY.js.map +0 -1
- package/dist/chunks/index-D2HsxXnK.js.map +0 -1
- package/dist/chunks/index-PQkbePWV.js.map +0 -1
- package/dist/chunks/index-QTYx5RaF.js.map +0 -1
|
@@ -5,7 +5,7 @@ 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, b as generateFilename, c as findFulltextFiles, h as findFulltextFile, j as extensionToFormat, k as fulltextAttach, l as
|
|
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 fulltextDiscover, m as fulltextFetch, o as fulltextConvert, q as fulltextGet, r as getExtension, s as getDefaultExportFromCjs, B as BUILTIN_STYLES, t as getFulltextAttachmentTypes, u as startServerWithFileWatcher } from "./index-DUpYvm-W.js";
|
|
9
9
|
import { readFile, unlink, stat, readdir, rename } from "node:fs/promises";
|
|
10
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";
|
|
@@ -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.27.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-DUpYvm-W.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-DUpYvm-W.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-DUpYvm-W.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,36 +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-DUpYvm-W.js").then((n) => n.z);
|
|
925
925
|
return addReferences(inputs, this.library, options ?? {});
|
|
926
926
|
}
|
|
927
927
|
async check(options) {
|
|
928
|
-
const { checkReferences } = await import("./index-
|
|
928
|
+
const { checkReferences } = await import("./index-DUpYvm-W.js").then((n) => n.A);
|
|
929
929
|
return checkReferences(this.library, options);
|
|
930
930
|
}
|
|
931
931
|
// Attachment operations
|
|
932
932
|
async attachAdd(options) {
|
|
933
|
-
const { addAttachment: addAttachment2 } = await import("./index-
|
|
933
|
+
const { addAttachment: addAttachment2 } = await import("./index-F4gbDFWf.js");
|
|
934
934
|
return addAttachment2(this.library, options);
|
|
935
935
|
}
|
|
936
936
|
async attachList(options) {
|
|
937
|
-
const { listAttachments: listAttachments2 } = await import("./index-
|
|
937
|
+
const { listAttachments: listAttachments2 } = await import("./index-F4gbDFWf.js");
|
|
938
938
|
return listAttachments2(this.library, options);
|
|
939
939
|
}
|
|
940
940
|
async attachGet(options) {
|
|
941
|
-
const { getAttachment: getAttachment2 } = await import("./index-
|
|
941
|
+
const { getAttachment: getAttachment2 } = await import("./index-F4gbDFWf.js");
|
|
942
942
|
return getAttachment2(this.library, options);
|
|
943
943
|
}
|
|
944
944
|
async attachDetach(options) {
|
|
945
|
-
const { detachAttachment: detachAttachment2 } = await import("./index-
|
|
945
|
+
const { detachAttachment: detachAttachment2 } = await import("./index-F4gbDFWf.js");
|
|
946
946
|
return detachAttachment2(this.library, options);
|
|
947
947
|
}
|
|
948
948
|
async attachSync(options) {
|
|
949
|
-
const { syncAttachments: syncAttachments2 } = await import("./index-
|
|
949
|
+
const { syncAttachments: syncAttachments2 } = await import("./index-F4gbDFWf.js");
|
|
950
950
|
return syncAttachments2(this.library, options);
|
|
951
951
|
}
|
|
952
952
|
async attachOpen(options) {
|
|
953
|
-
const { openAttachment: openAttachment2 } = await import("./index-
|
|
953
|
+
const { openAttachment: openAttachment2 } = await import("./index-F4gbDFWf.js");
|
|
954
954
|
return openAttachment2(this.library, options);
|
|
955
955
|
}
|
|
956
956
|
}
|
|
@@ -1806,7 +1806,7 @@ function getAttachExitCode(result) {
|
|
|
1806
1806
|
}
|
|
1807
1807
|
async function executeInteractiveSelect$2(context, config2) {
|
|
1808
1808
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
1809
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
1809
|
+
const { selectReferencesOrExit } = await import("./reference-select-DtzpiOvp.js");
|
|
1810
1810
|
const allReferences = await context.library.getAll();
|
|
1811
1811
|
const identifiers = await withAlternateScreen2(
|
|
1812
1812
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -2312,9 +2312,12 @@ function buildCheckOptions(options, appConfig) {
|
|
|
2312
2312
|
if (options.days !== void 0) {
|
|
2313
2313
|
opOptions.skipDays = options.days;
|
|
2314
2314
|
}
|
|
2315
|
-
if (options.
|
|
2315
|
+
if (options.save === false) {
|
|
2316
2316
|
opOptions.save = false;
|
|
2317
2317
|
}
|
|
2318
|
+
if (options.metadata === false) {
|
|
2319
|
+
opOptions.metadata = false;
|
|
2320
|
+
}
|
|
2318
2321
|
if (appConfig) {
|
|
2319
2322
|
const pubmed = {};
|
|
2320
2323
|
if (appConfig.pubmed.email) pubmed.email = appConfig.pubmed.email;
|
|
@@ -2332,45 +2335,109 @@ async function executeCheck(options, context, appConfig) {
|
|
|
2332
2335
|
function getStatusLabel(result) {
|
|
2333
2336
|
if (result.status === "skipped") return "[SKIPPED]";
|
|
2334
2337
|
if (result.status === "ok") return "[OK]";
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
+
if (result.findings.length === 0) return "[WARNING]";
|
|
2339
|
+
const priorityOrder = {
|
|
2340
|
+
retracted: 0,
|
|
2341
|
+
concern: 1,
|
|
2342
|
+
version_changed: 2,
|
|
2343
|
+
metadata_mismatch: 3,
|
|
2344
|
+
metadata_outdated: 4
|
|
2345
|
+
};
|
|
2346
|
+
let highestPriority = Number.MAX_SAFE_INTEGER;
|
|
2347
|
+
let highestType = "unknown";
|
|
2348
|
+
for (const finding of result.findings) {
|
|
2349
|
+
const priority = priorityOrder[finding.type] ?? 99;
|
|
2350
|
+
if (priority < highestPriority) {
|
|
2351
|
+
highestPriority = priority;
|
|
2352
|
+
highestType = finding.type;
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
switch (highestType) {
|
|
2338
2356
|
case "retracted":
|
|
2339
2357
|
return "[RETRACTED]";
|
|
2340
2358
|
case "concern":
|
|
2341
2359
|
return "[CONCERN]";
|
|
2342
2360
|
case "version_changed":
|
|
2343
2361
|
return "[VERSION]";
|
|
2344
|
-
case "
|
|
2345
|
-
return "[
|
|
2362
|
+
case "metadata_mismatch":
|
|
2363
|
+
return "[MISMATCH]";
|
|
2364
|
+
case "metadata_outdated":
|
|
2365
|
+
return "[OUTDATED]";
|
|
2346
2366
|
default:
|
|
2347
2367
|
return "[WARNING]";
|
|
2348
2368
|
}
|
|
2349
2369
|
}
|
|
2350
|
-
function
|
|
2370
|
+
function formatFieldDiff(diff) {
|
|
2371
|
+
const local = diff.local ?? "(none)";
|
|
2372
|
+
const remote = diff.remote ?? "(none)";
|
|
2373
|
+
return ` ${diff.field}: "${local}" → "${remote}"`;
|
|
2374
|
+
}
|
|
2375
|
+
function formatFindingDetails(finding, refId) {
|
|
2351
2376
|
const lines = [];
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2377
|
+
if (finding.details?.fieldDiffs && finding.details.fieldDiffs.length > 0) {
|
|
2378
|
+
for (const diff of finding.details.fieldDiffs) {
|
|
2379
|
+
lines.push(formatFieldDiff(diff));
|
|
2380
|
+
}
|
|
2355
2381
|
}
|
|
2356
|
-
if (finding.
|
|
2357
|
-
|
|
2382
|
+
if (finding.type === "metadata_mismatch" || finding.type === "metadata_outdated") {
|
|
2383
|
+
const icon = finding.type === "metadata_mismatch" ? "⚠" : "ℹ";
|
|
2384
|
+
lines.push(` ${icon} ${finding.message}`);
|
|
2385
|
+
lines.push(` → Run: ref update ${refId}`);
|
|
2386
|
+
} else {
|
|
2387
|
+
lines.push(` ${finding.message}`);
|
|
2388
|
+
if (finding.details?.retractionDoi) {
|
|
2389
|
+
lines.push(` Retraction notice: https://doi.org/${finding.details.retractionDoi}`);
|
|
2390
|
+
}
|
|
2391
|
+
if (finding.details?.newDoi) {
|
|
2392
|
+
lines.push(` New DOI: https://doi.org/${finding.details.newDoi}`);
|
|
2393
|
+
}
|
|
2358
2394
|
}
|
|
2359
2395
|
return lines;
|
|
2360
2396
|
}
|
|
2397
|
+
const FINDING_TYPE_KEYS = {
|
|
2398
|
+
retracted: "retracted",
|
|
2399
|
+
concern: "concern",
|
|
2400
|
+
metadata_mismatch: "mismatch",
|
|
2401
|
+
metadata_outdated: "outdated",
|
|
2402
|
+
version_changed: "versionChanged"
|
|
2403
|
+
};
|
|
2404
|
+
function countFindingTypes(result) {
|
|
2405
|
+
const counts = {};
|
|
2406
|
+
const allFindings = result.results.flatMap((r) => r.findings);
|
|
2407
|
+
for (const f of allFindings) {
|
|
2408
|
+
const key = FINDING_TYPE_KEYS[f.type] ?? f.type;
|
|
2409
|
+
counts[key] = (counts[key] ?? 0) + 1;
|
|
2410
|
+
}
|
|
2411
|
+
return counts;
|
|
2412
|
+
}
|
|
2361
2413
|
function formatCheckTextOutput(result) {
|
|
2362
2414
|
const lines = [];
|
|
2363
2415
|
for (const r of result.results) {
|
|
2364
2416
|
const label = getStatusLabel(r);
|
|
2365
2417
|
lines.push(`${label} ${r.id}`);
|
|
2366
2418
|
for (const finding of r.findings) {
|
|
2367
|
-
lines.push(...formatFindingDetails(finding));
|
|
2419
|
+
lines.push(...formatFindingDetails(finding, r.id));
|
|
2368
2420
|
}
|
|
2369
2421
|
lines.push("");
|
|
2370
2422
|
}
|
|
2371
2423
|
const { summary } = result;
|
|
2372
2424
|
const parts = [`${summary.total} checked`];
|
|
2373
|
-
|
|
2425
|
+
const fc = countFindingTypes(result);
|
|
2426
|
+
const summaryItems = [
|
|
2427
|
+
["retracted", "retracted"],
|
|
2428
|
+
["concern", "concern"],
|
|
2429
|
+
["mismatch", "mismatch"],
|
|
2430
|
+
["outdated", "outdated"],
|
|
2431
|
+
["versionChanged", "version changed"]
|
|
2432
|
+
];
|
|
2433
|
+
const knownKeys = new Set(summaryItems.map(([key]) => key));
|
|
2434
|
+
for (const [key, label] of summaryItems) {
|
|
2435
|
+
const count = fc[key] ?? 0;
|
|
2436
|
+
if (count > 0) parts.push(`${count} ${label}`);
|
|
2437
|
+
}
|
|
2438
|
+
for (const [key, count] of Object.entries(fc)) {
|
|
2439
|
+
if (!knownKeys.has(key) && count > 0) parts.push(`${count} ${key}`);
|
|
2440
|
+
}
|
|
2374
2441
|
if (summary.ok > 0) parts.push(`${summary.ok} ok`);
|
|
2375
2442
|
if (summary.skipped > 0) parts.push(`${summary.skipped} skipped`);
|
|
2376
2443
|
lines.push(`Summary: ${parts.join(", ")}`);
|
|
@@ -2404,7 +2471,7 @@ async function handleCheckAction(identifiers, options, globalOpts) {
|
|
|
2404
2471
|
const jsonOptions = buildJsonOptionsFromRefs(options, outputFormat, result, allRefs);
|
|
2405
2472
|
outputCheckResult(result, outputFormat, jsonOptions);
|
|
2406
2473
|
if (options.fix && result.summary.warnings > 0 && allRefs) {
|
|
2407
|
-
const { runFixInteraction } = await import("./fix-interaction-
|
|
2474
|
+
const { runFixInteraction } = await import("./fix-interaction-CTIvq9t4.js");
|
|
2408
2475
|
const findItem = (id2) => allRefs.find((item) => item.id === id2);
|
|
2409
2476
|
const fixResult = await runFixInteraction(result.results, context.library, findItem);
|
|
2410
2477
|
const removedSuffix = fixResult.removed.length > 0 ? `, ${fixResult.removed.length} removed` : "";
|
|
@@ -2472,7 +2539,7 @@ function outputCheckError(error, format2) {
|
|
|
2472
2539
|
}
|
|
2473
2540
|
async function selectReferencesInteractively(context, config2) {
|
|
2474
2541
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
2475
|
-
const { selectReferenceItemsOrExit } = await import("./reference-select-
|
|
2542
|
+
const { selectReferenceItemsOrExit } = await import("./reference-select-DtzpiOvp.js");
|
|
2476
2543
|
const allReferences = await context.library.getAll();
|
|
2477
2544
|
if (allReferences.length === 0) {
|
|
2478
2545
|
process.stderr.write("No references in library.\n");
|
|
@@ -2540,8 +2607,8 @@ function getCiteExitCode(result) {
|
|
|
2540
2607
|
}
|
|
2541
2608
|
async function executeInteractiveCite(options, context, config2) {
|
|
2542
2609
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
2543
|
-
const { runCiteFlow } = await import("./index-
|
|
2544
|
-
const { buildStyleChoices, listCustomStyles } = await import("./style-select-
|
|
2610
|
+
const { runCiteFlow } = await import("./index-Bo1JIDmF.js");
|
|
2611
|
+
const { buildStyleChoices, listCustomStyles } = await import("./style-select-BT-HOyFf.js");
|
|
2545
2612
|
const { search } = await import("./file-watcher-Dlx0PolG.js").then((n) => n.B);
|
|
2546
2613
|
const { tokenize } = await import("./file-watcher-Dlx0PolG.js").then((n) => n.A);
|
|
2547
2614
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
@@ -7142,7 +7209,7 @@ function formatEditOutput(result) {
|
|
|
7142
7209
|
}
|
|
7143
7210
|
async function executeInteractiveEdit(options, context, config2) {
|
|
7144
7211
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
7145
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
7212
|
+
const { selectReferencesOrExit } = await import("./reference-select-DtzpiOvp.js");
|
|
7146
7213
|
const allReferences = await context.library.getAll();
|
|
7147
7214
|
const identifiers = await withAlternateScreen2(
|
|
7148
7215
|
() => selectReferencesOrExit(allReferences, { multiSelect: true }, config2.cli.tui)
|
|
@@ -10681,14 +10748,14 @@ function formatFulltextConvertOutput(result) {
|
|
|
10681
10748
|
function getFulltextExitCode(result) {
|
|
10682
10749
|
return result.success ? 0 : 1;
|
|
10683
10750
|
}
|
|
10684
|
-
async function executeInteractiveSelect$1(context, config2) {
|
|
10751
|
+
async function executeInteractiveSelect$1(context, config2, multiSelect = false) {
|
|
10685
10752
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
10686
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
10753
|
+
const { selectReferencesOrExit } = await import("./reference-select-DtzpiOvp.js");
|
|
10687
10754
|
const allReferences = await context.library.getAll();
|
|
10688
10755
|
const identifiers = await withAlternateScreen2(
|
|
10689
|
-
() => selectReferencesOrExit(allReferences, { multiSelect
|
|
10756
|
+
() => selectReferencesOrExit(allReferences, { multiSelect }, config2.cli.tui)
|
|
10690
10757
|
);
|
|
10691
|
-
return identifiers
|
|
10758
|
+
return identifiers;
|
|
10692
10759
|
}
|
|
10693
10760
|
function isValidFilePath(value) {
|
|
10694
10761
|
return typeof value === "string" && value !== "" && value !== "true";
|
|
@@ -10720,7 +10787,7 @@ async function handleFulltextAttachAction(identifierArg, filePathArg, options, g
|
|
|
10720
10787
|
setExitCode(ExitCode.ERROR);
|
|
10721
10788
|
return;
|
|
10722
10789
|
}
|
|
10723
|
-
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10790
|
+
identifier = (await executeInteractiveSelect$1(context, config2))[0];
|
|
10724
10791
|
}
|
|
10725
10792
|
const { type: type2, filePath } = parseFulltextAttachTypeAndPath(filePathArg, options);
|
|
10726
10793
|
const stdinContent = !filePath && type2 ? await readStdinBuffer() : void 0;
|
|
@@ -10745,6 +10812,48 @@ async function handleFulltextAttachAction(identifierArg, filePathArg, options, g
|
|
|
10745
10812
|
setExitCode(ExitCode.INTERNAL_ERROR);
|
|
10746
10813
|
}
|
|
10747
10814
|
}
|
|
10815
|
+
function formatMultiFulltextGetOutput(results) {
|
|
10816
|
+
const isSingle = results.length === 1;
|
|
10817
|
+
if (isSingle) {
|
|
10818
|
+
const { result } = results[0];
|
|
10819
|
+
const formatted = formatFulltextGetOutput(result);
|
|
10820
|
+
return {
|
|
10821
|
+
stdout: result.success ? formatted : "",
|
|
10822
|
+
stderr: result.success ? "" : formatted
|
|
10823
|
+
};
|
|
10824
|
+
}
|
|
10825
|
+
const stdoutLines = [];
|
|
10826
|
+
const stderrLines = [];
|
|
10827
|
+
for (const { id: id2, result } of results) {
|
|
10828
|
+
if (result.success) {
|
|
10829
|
+
stdoutLines.push(`${id2}:`);
|
|
10830
|
+
if (result.paths?.pdf) {
|
|
10831
|
+
stdoutLines.push(` pdf: ${result.paths.pdf}`);
|
|
10832
|
+
}
|
|
10833
|
+
if (result.paths?.markdown) {
|
|
10834
|
+
stdoutLines.push(` markdown: ${result.paths.markdown}`);
|
|
10835
|
+
}
|
|
10836
|
+
} else {
|
|
10837
|
+
stderrLines.push(`Error: ${result.error}`);
|
|
10838
|
+
}
|
|
10839
|
+
}
|
|
10840
|
+
return {
|
|
10841
|
+
stdout: stdoutLines.join("\n"),
|
|
10842
|
+
stderr: stderrLines.join("\n")
|
|
10843
|
+
};
|
|
10844
|
+
}
|
|
10845
|
+
function formatFulltextGetJsonOutput(results) {
|
|
10846
|
+
const toJsonItem = ({ id: id2, result }) => {
|
|
10847
|
+
if (result.success) {
|
|
10848
|
+
return { id: id2, success: true, paths: result.paths };
|
|
10849
|
+
}
|
|
10850
|
+
return { id: id2, success: false, error: result.error };
|
|
10851
|
+
};
|
|
10852
|
+
if (results.length === 1) {
|
|
10853
|
+
return JSON.stringify(toJsonItem(results[0]), null, 2);
|
|
10854
|
+
}
|
|
10855
|
+
return JSON.stringify(results.map(toJsonItem), null, 2);
|
|
10856
|
+
}
|
|
10748
10857
|
function outputFulltextGetResult(result, useStdout) {
|
|
10749
10858
|
if (result.success && result.content && useStdout) {
|
|
10750
10859
|
process.stdout.write(result.content);
|
|
@@ -10759,27 +10868,26 @@ function outputFulltextGetResult(result, useStdout) {
|
|
|
10759
10868
|
`);
|
|
10760
10869
|
}
|
|
10761
10870
|
}
|
|
10762
|
-
async function
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
const preferValue = options.prefer ?? config2.fulltext.preferredType;
|
|
10871
|
+
async function resolveGetIdentifiers(identifierArgs, context, config2) {
|
|
10872
|
+
if (identifierArgs.length > 0) {
|
|
10873
|
+
return identifierArgs;
|
|
10874
|
+
}
|
|
10875
|
+
if (isTTY()) {
|
|
10876
|
+
return executeInteractiveSelect$1(context, config2, true);
|
|
10877
|
+
}
|
|
10878
|
+
const stdinIds = await readIdentifiersFromStdin();
|
|
10879
|
+
if (stdinIds.length === 0) {
|
|
10880
|
+
process.stderr.write(
|
|
10881
|
+
"Error: No identifier provided. Provide an ID, pipe one via stdin, or run interactively in a TTY.\n"
|
|
10882
|
+
);
|
|
10883
|
+
return null;
|
|
10884
|
+
}
|
|
10885
|
+
return stdinIds;
|
|
10886
|
+
}
|
|
10887
|
+
async function collectFulltextGetResults(identifiers, options, config2, context) {
|
|
10888
|
+
const preferValue = options.prefer ?? config2.fulltext.preferredType;
|
|
10889
|
+
const results = [];
|
|
10890
|
+
for (const identifier of identifiers) {
|
|
10783
10891
|
const getOptions = {
|
|
10784
10892
|
identifier,
|
|
10785
10893
|
fulltextDirectory: config2.attachments.directory,
|
|
@@ -10790,8 +10898,48 @@ async function handleFulltextGetAction(identifierArg, options, globalOpts) {
|
|
|
10790
10898
|
...preferValue && { preferredType: preferValue }
|
|
10791
10899
|
};
|
|
10792
10900
|
const result = await executeFulltextGet(getOptions, context);
|
|
10793
|
-
|
|
10794
|
-
|
|
10901
|
+
results.push({ id: identifier, result });
|
|
10902
|
+
}
|
|
10903
|
+
return results;
|
|
10904
|
+
}
|
|
10905
|
+
function outputFulltextGetResults(results, options) {
|
|
10906
|
+
if (options.output === "json") {
|
|
10907
|
+
process.stdout.write(`${formatFulltextGetJsonOutput(results)}
|
|
10908
|
+
`);
|
|
10909
|
+
return;
|
|
10910
|
+
}
|
|
10911
|
+
if (results.length === 1) {
|
|
10912
|
+
outputFulltextGetResult(results[0].result, Boolean(options.stdout));
|
|
10913
|
+
return;
|
|
10914
|
+
}
|
|
10915
|
+
const output = formatMultiFulltextGetOutput(results);
|
|
10916
|
+
if (output.stdout) {
|
|
10917
|
+
process.stdout.write(`${output.stdout}
|
|
10918
|
+
`);
|
|
10919
|
+
}
|
|
10920
|
+
if (output.stderr) {
|
|
10921
|
+
process.stderr.write(`${output.stderr}
|
|
10922
|
+
`);
|
|
10923
|
+
}
|
|
10924
|
+
}
|
|
10925
|
+
async function handleFulltextGetAction(identifierArgs, options, globalOpts) {
|
|
10926
|
+
try {
|
|
10927
|
+
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
10928
|
+
const context = await createExecutionContext(config2, Library.load);
|
|
10929
|
+
const identifiers = await resolveGetIdentifiers(identifierArgs, context, config2);
|
|
10930
|
+
if (!identifiers) {
|
|
10931
|
+
setExitCode(ExitCode.ERROR);
|
|
10932
|
+
return;
|
|
10933
|
+
}
|
|
10934
|
+
if (options.stdout && identifiers.length > 1) {
|
|
10935
|
+
process.stderr.write("Error: --stdout cannot be used with multiple identifiers\n");
|
|
10936
|
+
setExitCode(ExitCode.ERROR);
|
|
10937
|
+
return;
|
|
10938
|
+
}
|
|
10939
|
+
const results = await collectFulltextGetResults(identifiers, options, config2, context);
|
|
10940
|
+
outputFulltextGetResults(results, options);
|
|
10941
|
+
const hasFailure = results.some((r) => !r.result.success);
|
|
10942
|
+
setExitCode(hasFailure ? ExitCode.ERROR : ExitCode.SUCCESS);
|
|
10795
10943
|
} catch (error) {
|
|
10796
10944
|
process.stderr.write(`Error: ${error instanceof Error ? error.message : String(error)}
|
|
10797
10945
|
`);
|
|
@@ -10806,7 +10954,7 @@ async function handleFulltextDetachAction(identifierArg, options, globalOpts) {
|
|
|
10806
10954
|
if (identifierArg) {
|
|
10807
10955
|
identifier = identifierArg;
|
|
10808
10956
|
} else if (isTTY()) {
|
|
10809
|
-
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10957
|
+
identifier = (await executeInteractiveSelect$1(context, config2))[0];
|
|
10810
10958
|
} else {
|
|
10811
10959
|
const stdinId = await readIdentifierFromStdin();
|
|
10812
10960
|
if (!stdinId) {
|
|
@@ -10846,7 +10994,7 @@ async function handleFulltextOpenAction(identifierArg, options, globalOpts) {
|
|
|
10846
10994
|
if (identifierArg) {
|
|
10847
10995
|
identifier = identifierArg;
|
|
10848
10996
|
} else if (isTTY()) {
|
|
10849
|
-
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10997
|
+
identifier = (await executeInteractiveSelect$1(context, config2))[0];
|
|
10850
10998
|
} else {
|
|
10851
10999
|
const stdinId = await readIdentifierFromStdin();
|
|
10852
11000
|
if (!stdinId) {
|
|
@@ -10886,7 +11034,7 @@ async function handleFulltextDiscoverAction(identifierArg, options, globalOpts)
|
|
|
10886
11034
|
if (identifierArg) {
|
|
10887
11035
|
identifier = identifierArg;
|
|
10888
11036
|
} else if (isTTY()) {
|
|
10889
|
-
identifier = await executeInteractiveSelect$1(context, config2);
|
|
11037
|
+
identifier = (await executeInteractiveSelect$1(context, config2))[0];
|
|
10890
11038
|
} else {
|
|
10891
11039
|
const stdinId = await readIdentifierFromStdin();
|
|
10892
11040
|
if (!stdinId) {
|
|
@@ -10926,7 +11074,7 @@ async function handleFulltextFetchAction(identifierArg, options, globalOpts) {
|
|
|
10926
11074
|
if (identifierArg) {
|
|
10927
11075
|
identifier = identifierArg;
|
|
10928
11076
|
} else if (isTTY()) {
|
|
10929
|
-
identifier = await executeInteractiveSelect$1(context, config2);
|
|
11077
|
+
identifier = (await executeInteractiveSelect$1(context, config2))[0];
|
|
10930
11078
|
} else {
|
|
10931
11079
|
const stdinId = await readIdentifierFromStdin();
|
|
10932
11080
|
if (!stdinId) {
|
|
@@ -10966,7 +11114,7 @@ async function handleFulltextConvertAction(identifierArg, options, globalOpts) {
|
|
|
10966
11114
|
if (identifierArg) {
|
|
10967
11115
|
identifier = identifierArg;
|
|
10968
11116
|
} else if (isTTY()) {
|
|
10969
|
-
identifier = await executeInteractiveSelect$1(context, config2);
|
|
11117
|
+
identifier = (await executeInteractiveSelect$1(context, config2))[0];
|
|
10970
11118
|
} else {
|
|
10971
11119
|
const stdinId = await readIdentifierFromStdin();
|
|
10972
11120
|
if (!stdinId) {
|
|
@@ -11008,8 +11156,10 @@ const fulltext = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
11008
11156
|
formatFulltextDetachOutput,
|
|
11009
11157
|
formatFulltextDiscoverOutput,
|
|
11010
11158
|
formatFulltextFetchOutput,
|
|
11159
|
+
formatFulltextGetJsonOutput,
|
|
11011
11160
|
formatFulltextGetOutput,
|
|
11012
11161
|
formatFulltextOpenOutput,
|
|
11162
|
+
formatMultiFulltextGetOutput,
|
|
11013
11163
|
getFulltextExitCode,
|
|
11014
11164
|
handleFulltextAttachAction,
|
|
11015
11165
|
handleFulltextConvertAction,
|
|
@@ -31561,7 +31711,8 @@ function registerCheckTool(server, getLibraryOperations) {
|
|
|
31561
31711
|
ids: z.array(z.string()).optional().describe("Array of reference IDs to check. Omit if using 'all'."),
|
|
31562
31712
|
all: z.boolean().optional().describe("Check all references in library"),
|
|
31563
31713
|
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)")
|
|
31714
|
+
save: z.boolean().optional().describe("Whether to save results to library (default: true)"),
|
|
31715
|
+
metadata: z.boolean().optional().describe("Compare metadata against remote sources (default: true)")
|
|
31565
31716
|
}
|
|
31566
31717
|
},
|
|
31567
31718
|
async (args) => {
|
|
@@ -31571,6 +31722,7 @@ function registerCheckTool(server, getLibraryOperations) {
|
|
|
31571
31722
|
if (args.all) options.all = true;
|
|
31572
31723
|
if (args.skipDays !== void 0) options.skipDays = args.skipDays;
|
|
31573
31724
|
if (args.save !== void 0) options.save = args.save;
|
|
31725
|
+
if (args.metadata !== void 0) options.metadata = args.metadata;
|
|
31574
31726
|
const result = await libraryOps.check(options);
|
|
31575
31727
|
const text = formatCheckResult(result);
|
|
31576
31728
|
return {
|
|
@@ -32031,7 +32183,7 @@ async function mcpStart(options) {
|
|
|
32031
32183
|
async function executeRemove(options, context) {
|
|
32032
32184
|
const { identifier, idType = "id", fulltextDirectory, deleteFulltext = false } = options;
|
|
32033
32185
|
if (context.mode === "local" && deleteFulltext && fulltextDirectory) {
|
|
32034
|
-
const { removeReference } = await import("./index-
|
|
32186
|
+
const { removeReference } = await import("./index-DUpYvm-W.js").then((n) => n.x);
|
|
32035
32187
|
return removeReference(context.library, {
|
|
32036
32188
|
identifier,
|
|
32037
32189
|
idType,
|
|
@@ -32086,7 +32238,7 @@ Continue?`;
|
|
|
32086
32238
|
}
|
|
32087
32239
|
async function executeInteractiveRemove(context, config2) {
|
|
32088
32240
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32089
|
-
const { selectReferenceItemsOrExit } = await import("./reference-select-
|
|
32241
|
+
const { selectReferenceItemsOrExit } = await import("./reference-select-DtzpiOvp.js");
|
|
32090
32242
|
const allReferences = await context.library.getAll();
|
|
32091
32243
|
const selectedItems = await withAlternateScreen2(
|
|
32092
32244
|
() => selectReferenceItemsOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -32311,7 +32463,7 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
32311
32463
|
validateInteractiveOptions(options);
|
|
32312
32464
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
32313
32465
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32314
|
-
const { runSearchFlow } = await import("./index-
|
|
32466
|
+
const { runSearchFlow } = await import("./index-Bo1JIDmF.js");
|
|
32315
32467
|
const { search } = await import("./file-watcher-Dlx0PolG.js").then((n) => n.B);
|
|
32316
32468
|
const { tokenize } = await import("./file-watcher-Dlx0PolG.js").then((n) => n.A);
|
|
32317
32469
|
checkTTY();
|
|
@@ -32330,7 +32482,7 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
32330
32482
|
})
|
|
32331
32483
|
);
|
|
32332
32484
|
if (result.selectedItems && !result.cancelled) {
|
|
32333
|
-
const { isSideEffectAction } = await import("./action-menu-
|
|
32485
|
+
const { isSideEffectAction } = await import("./action-menu-DP1rmCkH.js");
|
|
32334
32486
|
if (isSideEffectAction(result.action)) {
|
|
32335
32487
|
await executeSideEffectAction(result.action, result.selectedItems, context, config2);
|
|
32336
32488
|
return { output: "", cancelled: false, action: result.action };
|
|
@@ -32733,7 +32885,7 @@ function formatUpdateOutput(result, identifier) {
|
|
|
32733
32885
|
}
|
|
32734
32886
|
async function executeInteractiveUpdate(context, config2) {
|
|
32735
32887
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32736
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
32888
|
+
const { selectReferencesOrExit } = await import("./reference-select-DtzpiOvp.js");
|
|
32737
32889
|
const allReferences = await context.library.getAll();
|
|
32738
32890
|
const identifiers = await withAlternateScreen2(
|
|
32739
32891
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -33028,7 +33180,7 @@ function getUrlExitCode(result) {
|
|
|
33028
33180
|
}
|
|
33029
33181
|
async function executeInteractiveSelect(context, config2) {
|
|
33030
33182
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
33031
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
33183
|
+
const { selectReferencesOrExit } = await import("./reference-select-DtzpiOvp.js");
|
|
33032
33184
|
const allReferences = await context.library.getAll();
|
|
33033
33185
|
const identifiers = await withAlternateScreen2(
|
|
33034
33186
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -33561,7 +33713,7 @@ function shouldAutoFetch(cliFlag, configEnabled) {
|
|
|
33561
33713
|
return configEnabled;
|
|
33562
33714
|
}
|
|
33563
33715
|
async function performAutoFetch(addedItems, context, config2) {
|
|
33564
|
-
const { fulltextFetch: fulltextFetch2 } = await import("./index-
|
|
33716
|
+
const { fulltextFetch: fulltextFetch2 } = await import("./index-DUpYvm-W.js").then((n) => n.w);
|
|
33565
33717
|
const fetchResults = await autoFetchFulltext(addedItems, context, {
|
|
33566
33718
|
fulltextConfig: config2.fulltext,
|
|
33567
33719
|
fulltextDirectory: config2.attachments.directory,
|
|
@@ -33642,7 +33794,9 @@ function registerEditCommand(program) {
|
|
|
33642
33794
|
});
|
|
33643
33795
|
}
|
|
33644
33796
|
function registerCheckCommand(program) {
|
|
33645
|
-
program.command("check").description(
|
|
33797
|
+
program.command("check").description(
|
|
33798
|
+
"Check references for retractions, expressions of concern, version changes, and metadata drift"
|
|
33799
|
+
).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)").option("--no-metadata", "Skip metadata comparison against remote sources").action(async (ids, options) => {
|
|
33646
33800
|
await handleCheckAction(ids, options, program.opts());
|
|
33647
33801
|
});
|
|
33648
33802
|
}
|
|
@@ -33787,10 +33941,12 @@ function registerFulltextCommand(program) {
|
|
|
33787
33941
|
fulltextCmd.command("attach").description("Attach a full-text file to a reference").argument("[identifier]", "Citation key or UUID (interactive selection if omitted)").argument("[file-path]", "Path to the file to attach").option("--pdf [path]", "Attach as PDF (path optional if provided as argument)").option("--markdown [path]", "Attach as Markdown (path optional if provided as argument)").option("--move", "Move file instead of copy").option("-f, --force", "Overwrite existing attachment").option("--uuid", "Interpret identifier as UUID").action(async (identifier, filePath, options) => {
|
|
33788
33942
|
await handleFulltextAttachAction(identifier, filePath, options, program.opts());
|
|
33789
33943
|
});
|
|
33790
|
-
fulltextCmd.command("get").description("Get full-text file path or content").argument("[
|
|
33944
|
+
fulltextCmd.command("get").description("Get full-text file path or content").argument("[identifiers...]", "Citation keys or UUIDs (interactive selection if omitted)").option("--pdf", "Get PDF file only").option("--markdown", "Get Markdown file only").addOption(
|
|
33791
33945
|
new Option("--prefer <type>", "Preferred fulltext type").choices(["pdf", "markdown"])
|
|
33792
|
-
).option("--stdout", "Output file content to stdout").option("--uuid", "Interpret
|
|
33793
|
-
|
|
33946
|
+
).option("--stdout", "Output file content to stdout").option("--uuid", "Interpret identifiers as UUIDs").addOption(
|
|
33947
|
+
new Option("-o, --output <format>", "Output format: json|text").choices(["json", "text"]).default("text")
|
|
33948
|
+
).action(async (identifiers, options) => {
|
|
33949
|
+
await handleFulltextGetAction(identifiers, options, program.opts());
|
|
33794
33950
|
});
|
|
33795
33951
|
fulltextCmd.command("detach").description("Detach full-text file from a reference").argument("[identifier]", "Citation key or UUID (interactive selection if omitted)").option("--pdf", "Detach PDF only").option("--markdown", "Detach Markdown only").option("--remove-files", "Also delete the file from disk").option("-f, --force", "Skip confirmation for file removal").option("--uuid", "Interpret identifier as UUID").action(async (identifier, options) => {
|
|
33796
33952
|
await handleFulltextDetachAction(identifier, options, program.opts());
|
|
@@ -33845,4 +34001,4 @@ export {
|
|
|
33845
34001
|
restoreStdinAfterInk as r,
|
|
33846
34002
|
syncAttachments as s
|
|
33847
34003
|
};
|
|
33848
|
-
//# sourceMappingURL=index-
|
|
34004
|
+
//# sourceMappingURL=index-B8ST0WLa.js.map
|