@ncukondo/reference-manager 0.30.1 → 0.32.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 +20 -0
- package/dist/chunks/{SearchableMultiSelect-SOvTpKAU.js → SearchableMultiSelect-jAKQd_B0.js} +2 -2
- package/dist/chunks/{SearchableMultiSelect-SOvTpKAU.js.map → SearchableMultiSelect-jAKQd_B0.js.map} +1 -1
- package/dist/chunks/{action-menu-DCZcb0HB.js → action-menu-DLEwSKrj.js} +3 -3
- package/dist/chunks/{action-menu-DCZcb0HB.js.map → action-menu-DLEwSKrj.js.map} +1 -1
- package/dist/chunks/{checker-CxSG7cdw.js → checker-kVM4S67y.js} +4 -4
- package/dist/chunks/{checker-CxSG7cdw.js.map → checker-kVM4S67y.js.map} +1 -1
- package/dist/chunks/{crossref-client-CN2pRi3R.js → crossref-client-DcJ42Qt6.js} +2 -2
- package/dist/chunks/{crossref-client-CN2pRi3R.js.map → crossref-client-DcJ42Qt6.js.map} +1 -1
- package/dist/chunks/{fix-interaction-C3OrF3yU.js → fix-interaction-DWUzp9Ri.js} +5 -5
- package/dist/chunks/{fix-interaction-C3OrF3yU.js.map → fix-interaction-DWUzp9Ri.js.map} +1 -1
- package/dist/chunks/{index-C_mW5LMY.js → index-B4-i4PrU.js} +3 -3
- package/dist/chunks/{index-C_mW5LMY.js.map → index-B4-i4PrU.js.map} +1 -1
- package/dist/chunks/{index-BZMfDG4M.js → index-B8iEozpf.js} +3 -3
- package/dist/chunks/index-B8iEozpf.js.map +1 -0
- package/dist/chunks/{index-CA9y5wSm.js → index-BuQm8A5F.js} +4 -4
- package/dist/chunks/{index-CA9y5wSm.js.map → index-BuQm8A5F.js.map} +1 -1
- package/dist/chunks/{index-4w0pu_0o.js → index-CmkN2-2A.js} +438 -85
- package/dist/chunks/index-CmkN2-2A.js.map +1 -0
- package/dist/chunks/{pubmed-client-MF5gA6Os.js → pubmed-client-Bhzz4Gg5.js} +2 -2
- package/dist/chunks/{pubmed-client-MF5gA6Os.js.map → pubmed-client-Bhzz4Gg5.js.map} +1 -1
- package/dist/chunks/{reference-select-Bm-05R0u.js → reference-select-B9b9Ez7Q.js} +3 -3
- package/dist/chunks/{reference-select-Bm-05R0u.js.map → reference-select-B9b9Ez7Q.js.map} +1 -1
- package/dist/chunks/{style-select-kfWjEg1X.js → style-select-aXByJLOo.js} +3 -3
- package/dist/chunks/{style-select-kfWjEg1X.js.map → style-select-aXByJLOo.js.map} +1 -1
- package/dist/cli/commands/install/install.d.ts +11 -0
- package/dist/cli/commands/install/install.d.ts.map +1 -0
- package/dist/cli/commands/show.d.ts +16 -0
- package/dist/cli/commands/show.d.ts.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/features/format/show-normalizer.d.ts +43 -0
- package/dist/features/format/show-normalizer.d.ts.map +1 -0
- package/dist/features/format/show-pretty.d.ts +8 -0
- package/dist/features/format/show-pretty.d.ts.map +1 -0
- package/dist/features/install/index.d.ts +6 -0
- package/dist/features/install/index.d.ts.map +1 -0
- package/dist/features/install/write-skills.d.ts +21 -0
- package/dist/features/install/write-skills.d.ts.map +1 -0
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/show.d.ts +23 -0
- package/dist/mcp/tools/show.d.ts.map +1 -0
- package/dist/server.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/index-4w0pu_0o.js.map +0 -1
- package/dist/chunks/index-BZMfDG4M.js.map +0 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Command, Option } from "commander";
|
|
2
|
-
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 packageJson, u as getFulltextAttachmentTypes, v as startServerWithFileWatcher, w as BUILTIN_CONVERTER_NAMES, x as BUILTIN_CONVERTER_INFO } from "./index-
|
|
2
|
+
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 packageJson, u as getFulltextAttachmentTypes, v as startServerWithFileWatcher, w as BUILTIN_CONVERTER_NAMES, x as BUILTIN_CONVERTER_INFO } from "./index-B4-i4PrU.js";
|
|
3
3
|
import { i as isEqual, M as MANAGED_CUSTOM_FIELDS, w as writeFileAtomic, L as Library, h as CslItemSchema, p as pickDefined, a as sortOrderSchema, z as paginationOptionsSchema, F as FileWatcher, b as sortFieldSchema, y as searchSortFieldSchema } from "./file-watcher-CWHg1yol.js";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
|
-
import { promises, readFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { promises, readFileSync, existsSync, mkdirSync, writeFileSync, lstatSync, unlinkSync, rmSync, symlinkSync } from "node:fs";
|
|
6
6
|
import * as os from "node:os";
|
|
7
|
+
import { homedir } from "node:os";
|
|
7
8
|
import * as path from "node:path";
|
|
8
|
-
import path__default, { join, basename, dirname } from "node:path";
|
|
9
|
+
import path__default, { join, basename, dirname, relative } from "node:path";
|
|
9
10
|
import { readFile, unlink, stat, readdir, rename } from "node:fs/promises";
|
|
10
11
|
import { o as openWithSystemApp, l as loadConfig, e as getDefaultCurrentDirConfigFilename, h as getDefaultUserConfigPath } from "./loader-BG2eomDC.js";
|
|
11
12
|
import { spawn, spawnSync } from "node:child_process";
|
|
@@ -613,11 +614,11 @@ function inferFromFilename(filename) {
|
|
|
613
614
|
if (!parsed) {
|
|
614
615
|
return { filename, role: "other", label: filename };
|
|
615
616
|
}
|
|
616
|
-
const { role, label } = parsed;
|
|
617
|
+
const { role, label: label2 } = parsed;
|
|
617
618
|
if (isReservedRole(role)) {
|
|
618
|
-
return
|
|
619
|
+
return label2 ? { filename, role, label: label2 } : { filename, role };
|
|
619
620
|
}
|
|
620
|
-
const basename2 =
|
|
621
|
+
const basename2 = label2 ? `${role}-${label2}` : role;
|
|
621
622
|
return { filename, role: "other", label: basename2 };
|
|
622
623
|
}
|
|
623
624
|
async function getFilesOnDisk(dirPath) {
|
|
@@ -656,11 +657,11 @@ function buildUpdatedFiles(metadataFiles, newFiles, missingFiles, shouldApplyNew
|
|
|
656
657
|
for (const newFile of newFiles) {
|
|
657
658
|
const override = roleOverrides?.[newFile.filename];
|
|
658
659
|
const role = override?.role ?? newFile.role;
|
|
659
|
-
const
|
|
660
|
+
const label2 = override ? override.label : newFile.label;
|
|
660
661
|
const attachmentFile = {
|
|
661
662
|
filename: newFile.filename,
|
|
662
663
|
role,
|
|
663
|
-
...
|
|
664
|
+
...label2 && { label: label2 }
|
|
664
665
|
};
|
|
665
666
|
updatedFiles.push(attachmentFile);
|
|
666
667
|
}
|
|
@@ -893,15 +894,15 @@ class OperationsLibrary {
|
|
|
893
894
|
}
|
|
894
895
|
// High-level operations
|
|
895
896
|
async search(options) {
|
|
896
|
-
const { searchReferences } = await import("./index-
|
|
897
|
+
const { searchReferences } = await import("./index-B4-i4PrU.js").then((n) => n.H);
|
|
897
898
|
return searchReferences(this.library, options);
|
|
898
899
|
}
|
|
899
900
|
async list(options) {
|
|
900
|
-
const { listReferences } = await import("./index-
|
|
901
|
+
const { listReferences } = await import("./index-B4-i4PrU.js").then((n) => n.G);
|
|
901
902
|
return listReferences(this.library, options ?? {});
|
|
902
903
|
}
|
|
903
904
|
async cite(options) {
|
|
904
|
-
const { citeReferences } = await import("./index-
|
|
905
|
+
const { citeReferences } = await import("./index-B4-i4PrU.js").then((n) => n.F);
|
|
905
906
|
const defaultStyle = options.defaultStyle ?? this.citationConfig?.defaultStyle;
|
|
906
907
|
const cslDirectory = options.cslDirectory ?? this.citationConfig?.cslDirectory;
|
|
907
908
|
const mergedOptions = {
|
|
@@ -912,36 +913,36 @@ class OperationsLibrary {
|
|
|
912
913
|
return citeReferences(this.library, mergedOptions);
|
|
913
914
|
}
|
|
914
915
|
async import(inputs, options) {
|
|
915
|
-
const { addReferences } = await import("./index-
|
|
916
|
+
const { addReferences } = await import("./index-B4-i4PrU.js").then((n) => n.D);
|
|
916
917
|
return addReferences(inputs, this.library, options ?? {});
|
|
917
918
|
}
|
|
918
919
|
async check(options) {
|
|
919
|
-
const { checkReferences } = await import("./index-
|
|
920
|
+
const { checkReferences } = await import("./index-B4-i4PrU.js").then((n) => n.E);
|
|
920
921
|
return checkReferences(this.library, options);
|
|
921
922
|
}
|
|
922
923
|
// Attachment operations
|
|
923
924
|
async attachAdd(options) {
|
|
924
|
-
const { addAttachment: addAttachment2 } = await import("./index-
|
|
925
|
+
const { addAttachment: addAttachment2 } = await import("./index-B8iEozpf.js");
|
|
925
926
|
return addAttachment2(this.library, options);
|
|
926
927
|
}
|
|
927
928
|
async attachList(options) {
|
|
928
|
-
const { listAttachments: listAttachments2 } = await import("./index-
|
|
929
|
+
const { listAttachments: listAttachments2 } = await import("./index-B8iEozpf.js");
|
|
929
930
|
return listAttachments2(this.library, options);
|
|
930
931
|
}
|
|
931
932
|
async attachGet(options) {
|
|
932
|
-
const { getAttachment: getAttachment2 } = await import("./index-
|
|
933
|
+
const { getAttachment: getAttachment2 } = await import("./index-B8iEozpf.js");
|
|
933
934
|
return getAttachment2(this.library, options);
|
|
934
935
|
}
|
|
935
936
|
async attachDetach(options) {
|
|
936
|
-
const { detachAttachment: detachAttachment2 } = await import("./index-
|
|
937
|
+
const { detachAttachment: detachAttachment2 } = await import("./index-B8iEozpf.js");
|
|
937
938
|
return detachAttachment2(this.library, options);
|
|
938
939
|
}
|
|
939
940
|
async attachSync(options) {
|
|
940
|
-
const { syncAttachments: syncAttachments2 } = await import("./index-
|
|
941
|
+
const { syncAttachments: syncAttachments2 } = await import("./index-B8iEozpf.js");
|
|
941
942
|
return syncAttachments2(this.library, options);
|
|
942
943
|
}
|
|
943
944
|
async attachOpen(options) {
|
|
944
|
-
const { openAttachment: openAttachment2 } = await import("./index-
|
|
945
|
+
const { openAttachment: openAttachment2 } = await import("./index-B8iEozpf.js");
|
|
945
946
|
return openAttachment2(this.library, options);
|
|
946
947
|
}
|
|
947
948
|
}
|
|
@@ -1804,9 +1805,9 @@ function formatSyncPreview(result) {
|
|
|
1804
1805
|
function getAttachExitCode(result) {
|
|
1805
1806
|
return result.success ? 0 : 1;
|
|
1806
1807
|
}
|
|
1807
|
-
async function executeInteractiveSelect$
|
|
1808
|
+
async function executeInteractiveSelect$3(context, config2) {
|
|
1808
1809
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
1809
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
1810
|
+
const { selectReferencesOrExit } = await import("./reference-select-B9b9Ez7Q.js");
|
|
1810
1811
|
const allReferences = await context.library.getAll();
|
|
1811
1812
|
const identifiers = await withAlternateScreen2(
|
|
1812
1813
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -1818,7 +1819,7 @@ async function resolveIdentifier(identifierArg, context, config2) {
|
|
|
1818
1819
|
return identifierArg;
|
|
1819
1820
|
}
|
|
1820
1821
|
if (isTTY()) {
|
|
1821
|
-
return executeInteractiveSelect$
|
|
1822
|
+
return executeInteractiveSelect$3(context, config2);
|
|
1822
1823
|
}
|
|
1823
1824
|
const stdinId = await readIdentifierFromStdin();
|
|
1824
1825
|
if (!stdinId) {
|
|
@@ -2413,8 +2414,8 @@ function countFindingTypes(result) {
|
|
|
2413
2414
|
function formatCheckTextOutput(result) {
|
|
2414
2415
|
const lines = [];
|
|
2415
2416
|
for (const r of result.results) {
|
|
2416
|
-
const
|
|
2417
|
-
lines.push(`${
|
|
2417
|
+
const label2 = getStatusLabel(r);
|
|
2418
|
+
lines.push(`${label2} ${r.id}`);
|
|
2418
2419
|
for (const finding of r.findings) {
|
|
2419
2420
|
lines.push(...formatFindingDetails(finding, r.id));
|
|
2420
2421
|
}
|
|
@@ -2431,9 +2432,9 @@ function formatCheckTextOutput(result) {
|
|
|
2431
2432
|
["versionChanged", "version changed"]
|
|
2432
2433
|
];
|
|
2433
2434
|
const knownKeys = new Set(summaryItems.map(([key]) => key));
|
|
2434
|
-
for (const [key,
|
|
2435
|
+
for (const [key, label2] of summaryItems) {
|
|
2435
2436
|
const count = fc[key] ?? 0;
|
|
2436
|
-
if (count > 0) parts.push(`${count} ${
|
|
2437
|
+
if (count > 0) parts.push(`${count} ${label2}`);
|
|
2437
2438
|
}
|
|
2438
2439
|
for (const [key, count] of Object.entries(fc)) {
|
|
2439
2440
|
if (!knownKeys.has(key) && count > 0) parts.push(`${count} ${key}`);
|
|
@@ -2471,7 +2472,7 @@ async function handleCheckAction(identifiers, options, globalOpts) {
|
|
|
2471
2472
|
const jsonOptions = buildJsonOptionsFromRefs(options, outputFormat, result, allRefs);
|
|
2472
2473
|
outputCheckResult(result, outputFormat, jsonOptions);
|
|
2473
2474
|
if (options.fix && result.summary.warnings > 0 && allRefs) {
|
|
2474
|
-
const { runFixInteraction } = await import("./fix-interaction-
|
|
2475
|
+
const { runFixInteraction } = await import("./fix-interaction-DWUzp9Ri.js");
|
|
2475
2476
|
const findItem = (id2) => allRefs.find((item) => item.id === id2);
|
|
2476
2477
|
const fixResult = await runFixInteraction(result.results, context.library, findItem);
|
|
2477
2478
|
const removedSuffix = fixResult.removed.length > 0 ? `, ${fixResult.removed.length} removed` : "";
|
|
@@ -2539,7 +2540,7 @@ function outputCheckError(error, format2) {
|
|
|
2539
2540
|
}
|
|
2540
2541
|
async function selectReferencesInteractively(context, config2) {
|
|
2541
2542
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
2542
|
-
const { selectReferenceItemsOrExit } = await import("./reference-select-
|
|
2543
|
+
const { selectReferenceItemsOrExit } = await import("./reference-select-B9b9Ez7Q.js");
|
|
2543
2544
|
const allReferences = await context.library.getAll();
|
|
2544
2545
|
if (allReferences.length === 0) {
|
|
2545
2546
|
process.stderr.write("No references in library.\n");
|
|
@@ -2607,8 +2608,8 @@ function getCiteExitCode(result) {
|
|
|
2607
2608
|
}
|
|
2608
2609
|
async function executeInteractiveCite(options, context, config2) {
|
|
2609
2610
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
2610
|
-
const { runCiteFlow } = await import("./index-
|
|
2611
|
-
const { buildStyleChoices, listCustomStyles } = await import("./style-select-
|
|
2611
|
+
const { runCiteFlow } = await import("./index-BuQm8A5F.js");
|
|
2612
|
+
const { buildStyleChoices, listCustomStyles } = await import("./style-select-aXByJLOo.js");
|
|
2612
2613
|
const { search } = await import("./file-watcher-CWHg1yol.js").then((n) => n.B);
|
|
2613
2614
|
const { tokenize } = await import("./file-watcher-CWHg1yol.js").then((n) => n.A);
|
|
2614
2615
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
@@ -7291,7 +7292,7 @@ function formatEditOutput(result) {
|
|
|
7291
7292
|
}
|
|
7292
7293
|
async function executeInteractiveEdit(options, context, config2) {
|
|
7293
7294
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
7294
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
7295
|
+
const { selectReferencesOrExit } = await import("./reference-select-B9b9Ez7Q.js");
|
|
7295
7296
|
const allReferences = await context.library.getAll();
|
|
7296
7297
|
const identifiers = await withAlternateScreen2(
|
|
7297
7298
|
() => selectReferencesOrExit(allReferences, { multiSelect: true }, config2.cli.tui)
|
|
@@ -10865,9 +10866,9 @@ function formatFulltextConvertOutput(result) {
|
|
|
10865
10866
|
function getFulltextExitCode(result) {
|
|
10866
10867
|
return result.success ? 0 : 1;
|
|
10867
10868
|
}
|
|
10868
|
-
async function executeInteractiveSelect$
|
|
10869
|
+
async function executeInteractiveSelect$2(context, config2, multiSelect = false) {
|
|
10869
10870
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
10870
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
10871
|
+
const { selectReferencesOrExit } = await import("./reference-select-B9b9Ez7Q.js");
|
|
10871
10872
|
const allReferences = await context.library.getAll();
|
|
10872
10873
|
const identifiers = await withAlternateScreen2(
|
|
10873
10874
|
() => selectReferencesOrExit(allReferences, { multiSelect }, config2.cli.tui)
|
|
@@ -10904,7 +10905,7 @@ async function handleFulltextAttachAction(identifierArg, filePathArg, options, g
|
|
|
10904
10905
|
setExitCode(ExitCode.ERROR);
|
|
10905
10906
|
return;
|
|
10906
10907
|
}
|
|
10907
|
-
identifier = (await executeInteractiveSelect$
|
|
10908
|
+
identifier = (await executeInteractiveSelect$2(context, config2))[0];
|
|
10908
10909
|
}
|
|
10909
10910
|
const { type: type2, filePath } = parseFulltextAttachTypeAndPath(filePathArg, options);
|
|
10910
10911
|
const stdinContent = !filePath && type2 ? await readStdinBuffer() : void 0;
|
|
@@ -10990,7 +10991,7 @@ async function resolveGetIdentifiers(identifierArgs, context, config2) {
|
|
|
10990
10991
|
return identifierArgs;
|
|
10991
10992
|
}
|
|
10992
10993
|
if (isTTY()) {
|
|
10993
|
-
return executeInteractiveSelect$
|
|
10994
|
+
return executeInteractiveSelect$2(context, config2, true);
|
|
10994
10995
|
}
|
|
10995
10996
|
const stdinIds = await readIdentifiersFromStdin();
|
|
10996
10997
|
if (stdinIds.length === 0) {
|
|
@@ -11071,7 +11072,7 @@ async function handleFulltextDetachAction(identifierArg, options, globalOpts) {
|
|
|
11071
11072
|
if (identifierArg) {
|
|
11072
11073
|
identifier = identifierArg;
|
|
11073
11074
|
} else if (isTTY()) {
|
|
11074
|
-
identifier = (await executeInteractiveSelect$
|
|
11075
|
+
identifier = (await executeInteractiveSelect$2(context, config2))[0];
|
|
11075
11076
|
} else {
|
|
11076
11077
|
const stdinId = await readIdentifierFromStdin();
|
|
11077
11078
|
if (!stdinId) {
|
|
@@ -11111,7 +11112,7 @@ async function handleFulltextOpenAction(identifierArg, options, globalOpts) {
|
|
|
11111
11112
|
if (identifierArg) {
|
|
11112
11113
|
identifier = identifierArg;
|
|
11113
11114
|
} else if (isTTY()) {
|
|
11114
|
-
identifier = (await executeInteractiveSelect$
|
|
11115
|
+
identifier = (await executeInteractiveSelect$2(context, config2))[0];
|
|
11115
11116
|
} else {
|
|
11116
11117
|
const stdinId = await readIdentifierFromStdin();
|
|
11117
11118
|
if (!stdinId) {
|
|
@@ -11151,7 +11152,7 @@ async function handleFulltextDiscoverAction(identifierArg, options, globalOpts)
|
|
|
11151
11152
|
if (identifierArg) {
|
|
11152
11153
|
identifier = identifierArg;
|
|
11153
11154
|
} else if (isTTY()) {
|
|
11154
|
-
identifier = (await executeInteractiveSelect$
|
|
11155
|
+
identifier = (await executeInteractiveSelect$2(context, config2))[0];
|
|
11155
11156
|
} else {
|
|
11156
11157
|
const stdinId = await readIdentifierFromStdin();
|
|
11157
11158
|
if (!stdinId) {
|
|
@@ -11191,7 +11192,7 @@ async function handleFulltextFetchAction(identifierArg, options, globalOpts) {
|
|
|
11191
11192
|
if (identifierArg) {
|
|
11192
11193
|
identifier = identifierArg;
|
|
11193
11194
|
} else if (isTTY()) {
|
|
11194
|
-
identifier = (await executeInteractiveSelect$
|
|
11195
|
+
identifier = (await executeInteractiveSelect$2(context, config2))[0];
|
|
11195
11196
|
} else {
|
|
11196
11197
|
const stdinId = await readIdentifierFromStdin();
|
|
11197
11198
|
if (!stdinId) {
|
|
@@ -11231,7 +11232,7 @@ async function handleFulltextConvertAction(identifierArg, options, globalOpts) {
|
|
|
11231
11232
|
if (identifierArg) {
|
|
11232
11233
|
identifier = identifierArg;
|
|
11233
11234
|
} else if (isTTY()) {
|
|
11234
|
-
identifier = (await executeInteractiveSelect$
|
|
11235
|
+
identifier = (await executeInteractiveSelect$2(context, config2))[0];
|
|
11235
11236
|
} else {
|
|
11236
11237
|
const stdinId = await readIdentifierFromStdin();
|
|
11237
11238
|
if (!stdinId) {
|
|
@@ -11290,6 +11291,79 @@ const fulltext = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
11290
11291
|
handleFulltextGetAction,
|
|
11291
11292
|
handleFulltextOpenAction
|
|
11292
11293
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
11294
|
+
const skillMd = '---\nname: ref\ndescription: Manage academic references in CSL-JSON format. Add papers by DOI/PMID/ISBN/arXiv, search and list references, generate citations, manage full-text PDFs, and check for retractions.\nallowed-tools:\n - Bash\n - Read\n - Write\n - Edit\n - Glob\n - Grep\n---\n\n# ref — Reference Manager\n\nA CLI tool for managing academic references using CSL-JSON as the single source of truth.\n\n## Quick Reference\n\n| Task | Command |\n|------|---------|\n| Add by DOI | `ref add 10.1234/example` |\n| Add by PMID | `ref add 12345678` |\n| Add by ISBN | `ref add 978-0-123456-78-9` |\n| Add by arXiv | `ref add 2301.12345` |\n| Add from BibTeX | `ref add references.bib` |\n| Add from RIS | `ref add references.ris` |\n| Search | `ref search "query"` |\n| List all | `ref list` |\n| Show details | `ref show <id>` |\n| Generate citation | `ref cite <id>` |\n| Export | `ref export <id> --output bibtex` |\n| Attach full-text | `ref fulltext attach <id> paper.pdf` |\n| Fetch full-text | `ref fulltext fetch <id>` |\n| Check retractions | `ref check <id>` |\n| Remove | `ref remove <id>` |\n| Update fields | `ref update <id> --set "title=New Title"` |\n| Configure | `ref config set <key> <value>` |\n\n## Search Syntax\n\n- Simple text: `ref search "machine learning"`\n- By author: `ref search "author:Smith"`\n- By year: `ref search "year:2024"`\n- By type: `ref search "type:article-journal"`\n- By tag: `ref search "tag:review"`\n- Combined: `ref search "author:Smith year:2024"`\n- Case-sensitive: prefix with `C/` (e.g., `ref search "C/RNA"`)\n\n## Output Formats\n\nMost commands support `--output` or `--json` flags:\n\n- `--json` — JSON output for programmatic use\n- `--output bibtex` — BibTeX format\n- `--output yaml` — YAML format\n\n## Full Help\n\nRun `ref --help` for all commands and options.\nRun `ref <command> --help` for command-specific help.\n';
|
|
11295
|
+
const fulltextMd = '---\nname: ref/fulltext\ndescription: Guide for managing full-text PDFs and Markdown files. Covers fetching, attaching, converting, and organizing full-text content.\n---\n\n# Full-Text Management\n\nGuide for working with full-text files (PDFs and Markdown) using `ref`.\n\n## Attach Files\n\n```bash\n# Attach a PDF\nref fulltext attach <id> paper.pdf\n\n# Attach Markdown\nref fulltext attach <id> paper.md\n```\n\n## Fetch Open Access\n\n```bash\n# Auto-discover and download OA full text\nref fulltext fetch <id>\n\n# Fetch with auto-attach on add\nref add 10.1234/example --fetch-fulltext\n```\n\n## Convert Formats\n\n```bash\n# Convert PDF to Markdown (requires external converter)\nref fulltext convert <id>\n\n# Supported converters: marker, docling, mineru, pymupdf\n# Configure custom converter:\nref config set fulltext.pdfConverter.command "marker"\nref config set fulltext.pdfConverter.args "{input} --output {output_dir}"\n```\n\n## Retrieve Full Text\n\n```bash\n# Get file path\nref fulltext get <id>\n\n# Get Markdown content to stdout\nref fulltext get <id> --stdout\n\n# Prefer specific format\nref fulltext get <id> --markdown\nref fulltext get <id> --pdf\n\n# Open in default system viewer\nref fulltext open <id>\n```\n\n## Check Availability\n\n```bash\n# Discover OA sources without downloading\nref fulltext discover <id>\n```\n\n## Detach\n\n```bash\n# Remove full-text association (file remains on disk)\nref fulltext detach <id>\n```\n\n## Tips\n\n- Use `ref fulltext get <id> --stdout` to pipe content to other tools\n- Full-text files are stored in the attachments directory (see `ref config get attachments.directory`)\n- Use `ref show <id>` to see full-text status alongside metadata\n- Markdown is preferred for AI-readable content; use `ref fulltext convert` after attaching PDF\n';
|
|
11296
|
+
const manuscriptWritingMd = "---\nname: ref/manuscript-writing\ndescription: Workflow for managing references while writing academic manuscripts. Covers citation generation, bibliography export, and reference verification.\n---\n\n# Manuscript Writing Workflow\n\nGuide for managing references during academic manuscript writing with `ref`.\n\n## 1. Find and Cite\n\n```bash\n# Search your library\nref search \"Smith 2024\"\n\n# Generate an inline citation\nref cite <id>\n\n# Generate citation in specific style\nref cite <id> --style apa\nref cite <id> --style vancouver\n\n# Get Pandoc/LaTeX citation key\nref cite <id> --key\n```\n\n## 2. Build Bibliography\n\n```bash\n# Export all cited references as BibTeX\nref export <id1> <id2> <id3> --output bibtex > references.bib\n\n# Export by search query\nref search \"tag:cited\" --output bibtex > references.bib\n\n# Export all references\nref export --all --output bibtex > library.bib\n```\n\n## 3. Add New References During Writing\n\n```bash\n# Quick add by DOI from a paper you're reading\nref add 10.1234/example\n\n# Add from clipboard BibTeX (pipe from stdin)\necho '<bibtex>' | ref add -\n\n# Add and immediately get citation key\nref add 10.1234/example --json | jq -r '.added[0].id'\n```\n\n## 4. Verify Before Submission\n\n```bash\n# Check all cited references for retractions\nref check <id1> <id2> <id3>\n\n# Verify metadata accuracy\nref check <id> --metadata\n\n# Show full details for final review\nref show <id>\n```\n\n## 5. Full-Text Management\n\n```bash\n# Attach supplementary files\nref fulltext attach <id> paper.pdf\nref fulltext attach <id> supplement.pdf\n\n# Get full-text path for reading\nref fulltext get <id>\n\n# Open in default viewer\nref fulltext open <id>\n```\n\n## Tips\n\n- Use `ref cite <id> --key` to get `@AuthorYear` keys for Pandoc\n- Use `ref show <id> --output yaml` for quick metadata overview\n- Use `ref url <id>` to get DOI/PubMed URLs for linking\n- Tag references with `ref update <id> --set \"tags=cited\"` to track what's in the manuscript\n";
|
|
11297
|
+
const systematicReviewMd = '---\nname: ref/systematic-review\ndescription: Workflow for conducting systematic literature reviews using reference-manager. Covers search strategy, screening, and evidence synthesis.\n---\n\n# Systematic Review Workflow\n\nGuide for conducting systematic literature reviews with `ref`.\n\n## 1. Build Search Set\n\nAdd references from multiple sources:\n\n```bash\n# From DOIs (e.g., exported from database search)\nref add 10.1234/study1 10.1234/study2 10.1234/study3\n\n# From BibTeX exported by PubMed/Scopus/Web of Science\nref add pubmed-results.bib\nref add scopus-results.ris\n\n# By PMID list\nref add 12345678 23456789 34567890\n```\n\n## 2. Tag and Organize\n\nUse tags to track screening stages:\n\n```bash\n# Tag references for screening\nref update <id> --set "tags=screening"\n\n# After title/abstract screening\nref update <id> --set "tags=included"\nref update <id> --set "tags=excluded"\n\n# After full-text review\nref update <id> --set "tags=final-included"\n```\n\n## 3. Full-Text Collection\n\n```bash\n# Auto-fetch open access full texts\nref fulltext fetch <id>\n\n# Attach manually obtained PDFs\nref fulltext attach <id> path/to/paper.pdf\n\n# Convert PDF to Markdown for text analysis\nref fulltext convert <id>\n```\n\n## 4. Quality Check\n\n```bash\n# Check for retractions or corrections\nref check <id>\n\n# Verify metadata against upstream sources\nref check <id> --metadata\n```\n\n## 5. Export for Analysis\n\n```bash\n# Export included studies as BibTeX\nref search "tag:final-included" --output bibtex > included.bib\n\n# Export as JSON for custom analysis\nref search "tag:final-included" --json > included.json\n```\n\n## Tips\n\n- Use `ref list --sort date-desc` to review chronologically\n- Use `ref search "tag:screening"` to find unprocessed references\n- Use `ref show <id>` to inspect full metadata before decisions\n- Duplicates are auto-detected on `ref add` — review skip messages\n';
|
|
11298
|
+
const SKILL_FILES = [
|
|
11299
|
+
["SKILL.md", skillMd],
|
|
11300
|
+
["references/systematic-review.md", systematicReviewMd],
|
|
11301
|
+
["references/manuscript-writing.md", manuscriptWritingMd],
|
|
11302
|
+
["references/fulltext.md", fulltextMd]
|
|
11303
|
+
];
|
|
11304
|
+
async function writeSkills(options) {
|
|
11305
|
+
const { targetDir, force = false, user = false } = options;
|
|
11306
|
+
const baseDir = user ? homedir() : targetDir;
|
|
11307
|
+
const agentsDir = join(baseDir, ".agents", "skills", "ref");
|
|
11308
|
+
const claudeDir = join(baseDir, ".claude", "skills");
|
|
11309
|
+
const claudeLink = join(claudeDir, "ref");
|
|
11310
|
+
const written = [];
|
|
11311
|
+
const skipped = [];
|
|
11312
|
+
mkdirSync(join(agentsDir, "references"), { recursive: true });
|
|
11313
|
+
for (const [relativePath, content] of SKILL_FILES) {
|
|
11314
|
+
const filePath = join(agentsDir, relativePath);
|
|
11315
|
+
if (existsSync(filePath) && !force) {
|
|
11316
|
+
skipped.push(relativePath);
|
|
11317
|
+
continue;
|
|
11318
|
+
}
|
|
11319
|
+
writeFileSync(filePath, content, "utf-8");
|
|
11320
|
+
written.push(relativePath);
|
|
11321
|
+
}
|
|
11322
|
+
let linkCreated = false;
|
|
11323
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
11324
|
+
if (force && existsSync(claudeLink)) {
|
|
11325
|
+
const stat2 = lstatSync(claudeLink);
|
|
11326
|
+
if (stat2.isSymbolicLink()) {
|
|
11327
|
+
unlinkSync(claudeLink);
|
|
11328
|
+
} else if (stat2.isDirectory()) {
|
|
11329
|
+
rmSync(claudeLink, { recursive: true, force: true });
|
|
11330
|
+
}
|
|
11331
|
+
}
|
|
11332
|
+
if (!existsSync(claudeLink)) {
|
|
11333
|
+
const linkTarget = relative(claudeDir, agentsDir);
|
|
11334
|
+
symlinkSync(linkTarget, claudeLink, "junction");
|
|
11335
|
+
linkCreated = true;
|
|
11336
|
+
}
|
|
11337
|
+
return { written, skipped, linkCreated };
|
|
11338
|
+
}
|
|
11339
|
+
async function executeInstallSkills(options) {
|
|
11340
|
+
return writeSkills({
|
|
11341
|
+
targetDir: process.cwd(),
|
|
11342
|
+
force: options.force,
|
|
11343
|
+
...options.user != null && { user: options.user }
|
|
11344
|
+
});
|
|
11345
|
+
}
|
|
11346
|
+
function formatInstallSkillsOutput(result) {
|
|
11347
|
+
const lines = [];
|
|
11348
|
+
if (result.written.length === 0 && result.skipped.length > 0) {
|
|
11349
|
+
lines.push("Skills already up-to-date. Use --force to overwrite.");
|
|
11350
|
+
lines.push(` ${result.skipped.length} files skipped`);
|
|
11351
|
+
return lines.join("\n");
|
|
11352
|
+
}
|
|
11353
|
+
if (result.written.length > 0) {
|
|
11354
|
+
lines.push(`Installed ${result.written.length} skill files to .agents/skills/ref/`);
|
|
11355
|
+
for (const file of result.written) {
|
|
11356
|
+
lines.push(` + ${file}`);
|
|
11357
|
+
}
|
|
11358
|
+
}
|
|
11359
|
+
if (result.skipped.length > 0) {
|
|
11360
|
+
lines.push(` ${result.skipped.length} files skipped (already exist)`);
|
|
11361
|
+
}
|
|
11362
|
+
if (result.linkCreated) {
|
|
11363
|
+
lines.push("Created symlink: .claude/skills/ref -> .agents/skills/ref");
|
|
11364
|
+
}
|
|
11365
|
+
return lines.join("\n");
|
|
11366
|
+
}
|
|
11293
11367
|
function buildResourceIndicators(item) {
|
|
11294
11368
|
const labels = [];
|
|
11295
11369
|
const attachments = item.custom?.attachments;
|
|
@@ -11310,14 +11384,14 @@ function buildResourceIndicators(item) {
|
|
|
11310
11384
|
if (Array.isArray(tags) && tags.length > 0) labels.push("tag");
|
|
11311
11385
|
return labels.join(" ");
|
|
11312
11386
|
}
|
|
11313
|
-
function formatAuthor(author) {
|
|
11387
|
+
function formatAuthor$1(author) {
|
|
11314
11388
|
if (author.literal) return author.literal;
|
|
11315
11389
|
const family = author.family || "";
|
|
11316
11390
|
const givenInitial = author.given ? `${author.given.charAt(0)}.` : "";
|
|
11317
11391
|
return givenInitial ? `${family}, ${givenInitial}` : family;
|
|
11318
11392
|
}
|
|
11319
11393
|
function formatAuthors(authors) {
|
|
11320
|
-
return authors.map(formatAuthor).join("; ");
|
|
11394
|
+
return authors.map(formatAuthor$1).join("; ");
|
|
11321
11395
|
}
|
|
11322
11396
|
function formatSingleReference(item) {
|
|
11323
11397
|
const lines = [];
|
|
@@ -23701,9 +23775,9 @@ function requireCodegen() {
|
|
|
23701
23775
|
}
|
|
23702
23776
|
}
|
|
23703
23777
|
class Label extends Node {
|
|
23704
|
-
constructor(
|
|
23778
|
+
constructor(label2) {
|
|
23705
23779
|
super();
|
|
23706
|
-
this.label =
|
|
23780
|
+
this.label = label2;
|
|
23707
23781
|
this.names = {};
|
|
23708
23782
|
}
|
|
23709
23783
|
render({ _n }) {
|
|
@@ -23711,14 +23785,14 @@ function requireCodegen() {
|
|
|
23711
23785
|
}
|
|
23712
23786
|
}
|
|
23713
23787
|
class Break extends Node {
|
|
23714
|
-
constructor(
|
|
23788
|
+
constructor(label2) {
|
|
23715
23789
|
super();
|
|
23716
|
-
this.label =
|
|
23790
|
+
this.label = label2;
|
|
23717
23791
|
this.names = {};
|
|
23718
23792
|
}
|
|
23719
23793
|
render({ _n }) {
|
|
23720
|
-
const
|
|
23721
|
-
return `break${
|
|
23794
|
+
const label2 = this.label ? ` ${this.label}` : "";
|
|
23795
|
+
return `break${label2};` + _n;
|
|
23722
23796
|
}
|
|
23723
23797
|
}
|
|
23724
23798
|
class Throw extends Node {
|
|
@@ -24130,12 +24204,12 @@ function requireCodegen() {
|
|
|
24130
24204
|
return this._endBlockNode(For);
|
|
24131
24205
|
}
|
|
24132
24206
|
// `label` statement
|
|
24133
|
-
label(
|
|
24134
|
-
return this._leafNode(new Label(
|
|
24207
|
+
label(label2) {
|
|
24208
|
+
return this._leafNode(new Label(label2));
|
|
24135
24209
|
}
|
|
24136
24210
|
// `break` statement
|
|
24137
|
-
break(
|
|
24138
|
-
return this._leafNode(new Break(
|
|
24211
|
+
break(label2) {
|
|
24212
|
+
return this._leafNode(new Break(label2));
|
|
24139
24213
|
}
|
|
24140
24214
|
// `return` statement
|
|
24141
24215
|
return(value) {
|
|
@@ -26836,49 +26910,49 @@ function requireFastUri() {
|
|
|
26836
26910
|
schemelessOptions.skipEscape = true;
|
|
26837
26911
|
return serialize2(resolved, schemelessOptions);
|
|
26838
26912
|
}
|
|
26839
|
-
function resolveComponent(base,
|
|
26913
|
+
function resolveComponent(base, relative2, options, skipNormalization) {
|
|
26840
26914
|
const target = {};
|
|
26841
26915
|
if (!skipNormalization) {
|
|
26842
26916
|
base = parse2(serialize2(base, options), options);
|
|
26843
|
-
|
|
26917
|
+
relative2 = parse2(serialize2(relative2, options), options);
|
|
26844
26918
|
}
|
|
26845
26919
|
options = options || {};
|
|
26846
|
-
if (!options.tolerant &&
|
|
26847
|
-
target.scheme =
|
|
26848
|
-
target.userinfo =
|
|
26849
|
-
target.host =
|
|
26850
|
-
target.port =
|
|
26851
|
-
target.path = removeDotSegments(
|
|
26852
|
-
target.query =
|
|
26920
|
+
if (!options.tolerant && relative2.scheme) {
|
|
26921
|
+
target.scheme = relative2.scheme;
|
|
26922
|
+
target.userinfo = relative2.userinfo;
|
|
26923
|
+
target.host = relative2.host;
|
|
26924
|
+
target.port = relative2.port;
|
|
26925
|
+
target.path = removeDotSegments(relative2.path || "");
|
|
26926
|
+
target.query = relative2.query;
|
|
26853
26927
|
} else {
|
|
26854
|
-
if (
|
|
26855
|
-
target.userinfo =
|
|
26856
|
-
target.host =
|
|
26857
|
-
target.port =
|
|
26858
|
-
target.path = removeDotSegments(
|
|
26859
|
-
target.query =
|
|
26928
|
+
if (relative2.userinfo !== void 0 || relative2.host !== void 0 || relative2.port !== void 0) {
|
|
26929
|
+
target.userinfo = relative2.userinfo;
|
|
26930
|
+
target.host = relative2.host;
|
|
26931
|
+
target.port = relative2.port;
|
|
26932
|
+
target.path = removeDotSegments(relative2.path || "");
|
|
26933
|
+
target.query = relative2.query;
|
|
26860
26934
|
} else {
|
|
26861
|
-
if (!
|
|
26935
|
+
if (!relative2.path) {
|
|
26862
26936
|
target.path = base.path;
|
|
26863
|
-
if (
|
|
26864
|
-
target.query =
|
|
26937
|
+
if (relative2.query !== void 0) {
|
|
26938
|
+
target.query = relative2.query;
|
|
26865
26939
|
} else {
|
|
26866
26940
|
target.query = base.query;
|
|
26867
26941
|
}
|
|
26868
26942
|
} else {
|
|
26869
|
-
if (
|
|
26870
|
-
target.path = removeDotSegments(
|
|
26943
|
+
if (relative2.path[0] === "/") {
|
|
26944
|
+
target.path = removeDotSegments(relative2.path);
|
|
26871
26945
|
} else {
|
|
26872
26946
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
26873
|
-
target.path = "/" +
|
|
26947
|
+
target.path = "/" + relative2.path;
|
|
26874
26948
|
} else if (!base.path) {
|
|
26875
|
-
target.path =
|
|
26949
|
+
target.path = relative2.path;
|
|
26876
26950
|
} else {
|
|
26877
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
26951
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative2.path;
|
|
26878
26952
|
}
|
|
26879
26953
|
target.path = removeDotSegments(target.path);
|
|
26880
26954
|
}
|
|
26881
|
-
target.query =
|
|
26955
|
+
target.query = relative2.query;
|
|
26882
26956
|
}
|
|
26883
26957
|
target.userinfo = base.userinfo;
|
|
26884
26958
|
target.host = base.host;
|
|
@@ -26886,7 +26960,7 @@ function requireFastUri() {
|
|
|
26886
26960
|
}
|
|
26887
26961
|
target.scheme = base.scheme;
|
|
26888
26962
|
}
|
|
26889
|
-
target.fragment =
|
|
26963
|
+
target.fragment = relative2.fragment;
|
|
26890
26964
|
return target;
|
|
26891
26965
|
}
|
|
26892
26966
|
function equal2(uriA, uriB, options) {
|
|
@@ -32269,6 +32343,121 @@ function registerSearchTool(server, getLibraryOperations, getConfig) {
|
|
|
32269
32343
|
}
|
|
32270
32344
|
);
|
|
32271
32345
|
}
|
|
32346
|
+
function toPosixPath(p) {
|
|
32347
|
+
return p.split(path__default.sep).join("/");
|
|
32348
|
+
}
|
|
32349
|
+
function formatAuthor(author) {
|
|
32350
|
+
if (author.literal) return author.literal;
|
|
32351
|
+
const family = author.family || "";
|
|
32352
|
+
const givenInitial = author.given ? `${author.given.charAt(0)}.` : "";
|
|
32353
|
+
return givenInitial ? `${family}, ${givenInitial}` : family;
|
|
32354
|
+
}
|
|
32355
|
+
function resolveFulltextAndAttachments(item, attachmentsDirectory) {
|
|
32356
|
+
const attachments = item.custom?.attachments;
|
|
32357
|
+
if (!attachments) {
|
|
32358
|
+
return {
|
|
32359
|
+
fulltext: { pdf: null, markdown: null },
|
|
32360
|
+
attachments: []
|
|
32361
|
+
};
|
|
32362
|
+
}
|
|
32363
|
+
const dir = path__default.join(attachmentsDirectory, attachments.directory);
|
|
32364
|
+
const files = attachments.files ?? [];
|
|
32365
|
+
let pdfPath = null;
|
|
32366
|
+
let markdownPath = null;
|
|
32367
|
+
const nonFulltext = [];
|
|
32368
|
+
for (const file of files) {
|
|
32369
|
+
if (file.role === "fulltext") {
|
|
32370
|
+
if (file.filename.endsWith(".pdf")) {
|
|
32371
|
+
pdfPath = toPosixPath(path__default.join(dir, file.filename));
|
|
32372
|
+
} else if (file.filename.endsWith(".md")) {
|
|
32373
|
+
markdownPath = toPosixPath(path__default.join(dir, file.filename));
|
|
32374
|
+
}
|
|
32375
|
+
} else {
|
|
32376
|
+
nonFulltext.push({ filename: file.filename, role: file.role });
|
|
32377
|
+
}
|
|
32378
|
+
}
|
|
32379
|
+
return {
|
|
32380
|
+
fulltext: { pdf: pdfPath, markdown: markdownPath },
|
|
32381
|
+
attachments: nonFulltext
|
|
32382
|
+
};
|
|
32383
|
+
}
|
|
32384
|
+
function normalizeAuthors(item) {
|
|
32385
|
+
return item.author && item.author.length > 0 ? item.author.map(formatAuthor) : null;
|
|
32386
|
+
}
|
|
32387
|
+
function normalizeFileInfo(item, options) {
|
|
32388
|
+
if (!options?.attachmentsDirectory) {
|
|
32389
|
+
return { fulltext: null, attachments: null };
|
|
32390
|
+
}
|
|
32391
|
+
return resolveFulltextAndAttachments(item, options.attachmentsDirectory);
|
|
32392
|
+
}
|
|
32393
|
+
function normalizeReference(item, options) {
|
|
32394
|
+
const custom2 = item.custom;
|
|
32395
|
+
const { fulltext: fulltext2, attachments } = normalizeFileInfo(item, options);
|
|
32396
|
+
return {
|
|
32397
|
+
id: item.id,
|
|
32398
|
+
uuid: custom2?.uuid ?? null,
|
|
32399
|
+
type: item.type,
|
|
32400
|
+
title: item.title ?? null,
|
|
32401
|
+
authors: normalizeAuthors(item),
|
|
32402
|
+
year: item.issued?.["date-parts"]?.[0]?.[0] ?? null,
|
|
32403
|
+
journal: item["container-title"] ?? null,
|
|
32404
|
+
volume: item.volume ?? null,
|
|
32405
|
+
issue: item.issue ?? null,
|
|
32406
|
+
page: item.page ?? null,
|
|
32407
|
+
doi: item.DOI ?? null,
|
|
32408
|
+
pmid: item.PMID ?? null,
|
|
32409
|
+
pmcid: item.PMCID ?? null,
|
|
32410
|
+
url: item.URL ?? null,
|
|
32411
|
+
abstract: item.abstract ?? null,
|
|
32412
|
+
tags: custom2?.tags ?? null,
|
|
32413
|
+
created: custom2?.created_at ?? null,
|
|
32414
|
+
modified: custom2?.timestamp ?? null,
|
|
32415
|
+
fulltext: fulltext2,
|
|
32416
|
+
attachments,
|
|
32417
|
+
raw: item
|
|
32418
|
+
};
|
|
32419
|
+
}
|
|
32420
|
+
function createShowToolHandler(getLibraryOperations, getConfig) {
|
|
32421
|
+
return async (args) => {
|
|
32422
|
+
const libraryOps = getLibraryOperations();
|
|
32423
|
+
const config2 = getConfig();
|
|
32424
|
+
const id2 = args.uuid ?? args.identifier;
|
|
32425
|
+
const idType = args.uuid ? "uuid" : "id";
|
|
32426
|
+
if (!id2) {
|
|
32427
|
+
return {
|
|
32428
|
+
content: [{ type: "text", text: "Error: identifier or uuid is required" }],
|
|
32429
|
+
isError: true
|
|
32430
|
+
};
|
|
32431
|
+
}
|
|
32432
|
+
const item = await libraryOps.find(id2, { idType });
|
|
32433
|
+
if (!item) {
|
|
32434
|
+
return {
|
|
32435
|
+
content: [{ type: "text", text: `Reference not found: ${id2}` }],
|
|
32436
|
+
isError: true
|
|
32437
|
+
};
|
|
32438
|
+
}
|
|
32439
|
+
const attachmentsDir = config2.attachments?.directory;
|
|
32440
|
+
const normalizeOpts = attachmentsDir ? { attachmentsDirectory: attachmentsDir } : void 0;
|
|
32441
|
+
const normalized = normalizeReference(item, normalizeOpts);
|
|
32442
|
+
return {
|
|
32443
|
+
content: [{ type: "text", text: JSON.stringify(normalized, null, 2) }]
|
|
32444
|
+
};
|
|
32445
|
+
};
|
|
32446
|
+
}
|
|
32447
|
+
function registerShowTool(server, getLibraryOperations, getConfig) {
|
|
32448
|
+
const handler = createShowToolHandler(getLibraryOperations, getConfig);
|
|
32449
|
+
server.registerTool(
|
|
32450
|
+
"show",
|
|
32451
|
+
{
|
|
32452
|
+
description: "Show detailed information about a single reference. Returns normalized JSON with all metadata, fulltext paths, and attachments. Use identifier (citation key) or uuid to look up.",
|
|
32453
|
+
inputSchema: {
|
|
32454
|
+
identifier: z.string().optional().describe("Reference citation key (e.g., Smith2020)"),
|
|
32455
|
+
uuid: z.string().optional().describe("Reference UUID (alternative to identifier)")
|
|
32456
|
+
}
|
|
32457
|
+
},
|
|
32458
|
+
async (args) => handler(args)
|
|
32459
|
+
);
|
|
32460
|
+
}
|
|
32272
32461
|
function registerAllTools(server, getLibraryOperations, getConfig) {
|
|
32273
32462
|
registerSearchTool(server, getLibraryOperations, getConfig);
|
|
32274
32463
|
registerListTool(server, getLibraryOperations, getConfig);
|
|
@@ -32276,6 +32465,7 @@ function registerAllTools(server, getLibraryOperations, getConfig) {
|
|
|
32276
32465
|
registerCheckTool(server, getLibraryOperations);
|
|
32277
32466
|
registerAddTool(server, getLibraryOperations);
|
|
32278
32467
|
registerRemoveTool(server, getLibraryOperations);
|
|
32468
|
+
registerShowTool(server, getLibraryOperations, getConfig);
|
|
32279
32469
|
registerFulltextAttachTool(server, getLibraryOperations, getConfig);
|
|
32280
32470
|
registerFulltextGetTool(server, getLibraryOperations, getConfig);
|
|
32281
32471
|
registerFulltextDetachTool(server, getLibraryOperations, getConfig);
|
|
@@ -32335,7 +32525,7 @@ async function mcpStart(options) {
|
|
|
32335
32525
|
async function executeRemove(options, context) {
|
|
32336
32526
|
const { identifier, idType = "id", fulltextDirectory, deleteFulltext = false } = options;
|
|
32337
32527
|
if (context.mode === "local" && deleteFulltext && fulltextDirectory) {
|
|
32338
|
-
const { removeReference } = await import("./index-
|
|
32528
|
+
const { removeReference } = await import("./index-B4-i4PrU.js").then((n) => n.A);
|
|
32339
32529
|
return removeReference(context.library, {
|
|
32340
32530
|
identifier,
|
|
32341
32531
|
idType,
|
|
@@ -32390,7 +32580,7 @@ Continue?`;
|
|
|
32390
32580
|
}
|
|
32391
32581
|
async function executeInteractiveRemove(context, config2) {
|
|
32392
32582
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32393
|
-
const { selectReferenceItemsOrExit } = await import("./reference-select-
|
|
32583
|
+
const { selectReferenceItemsOrExit } = await import("./reference-select-B9b9Ez7Q.js");
|
|
32394
32584
|
const allReferences = await context.library.getAll();
|
|
32395
32585
|
const selectedItems = await withAlternateScreen2(
|
|
32396
32586
|
() => selectReferenceItemsOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -32615,7 +32805,7 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
32615
32805
|
validateInteractiveOptions(options);
|
|
32616
32806
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
32617
32807
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32618
|
-
const { runSearchFlow } = await import("./index-
|
|
32808
|
+
const { runSearchFlow } = await import("./index-BuQm8A5F.js");
|
|
32619
32809
|
const { search } = await import("./file-watcher-CWHg1yol.js").then((n) => n.B);
|
|
32620
32810
|
const { tokenize } = await import("./file-watcher-CWHg1yol.js").then((n) => n.A);
|
|
32621
32811
|
checkTTY();
|
|
@@ -32634,7 +32824,7 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
32634
32824
|
})
|
|
32635
32825
|
);
|
|
32636
32826
|
if (result.selectedItems && !result.cancelled) {
|
|
32637
|
-
const { isSideEffectAction } = await import("./action-menu-
|
|
32827
|
+
const { isSideEffectAction } = await import("./action-menu-DLEwSKrj.js");
|
|
32638
32828
|
if (isSideEffectAction(result.action)) {
|
|
32639
32829
|
await executeSideEffectAction(result.action, result.selectedItems, context, config2);
|
|
32640
32830
|
return { output: "", cancelled: false, action: result.action };
|
|
@@ -32836,6 +33026,142 @@ async function serverStatus(portfilePath) {
|
|
|
32836
33026
|
}
|
|
32837
33027
|
return result;
|
|
32838
33028
|
}
|
|
33029
|
+
const LABEL_WIDTH = 11;
|
|
33030
|
+
function label(name) {
|
|
33031
|
+
return ` ${name.padEnd(LABEL_WIDTH)}`;
|
|
33032
|
+
}
|
|
33033
|
+
function formatJournalLine(ref2) {
|
|
33034
|
+
let line = ref2.journal ?? "";
|
|
33035
|
+
if (ref2.volume) {
|
|
33036
|
+
line += ref2.issue ? `, ${ref2.volume}(${ref2.issue})` : `, ${ref2.volume}`;
|
|
33037
|
+
}
|
|
33038
|
+
if (ref2.page) {
|
|
33039
|
+
line += `, ${ref2.page}`;
|
|
33040
|
+
}
|
|
33041
|
+
return line;
|
|
33042
|
+
}
|
|
33043
|
+
function formatDate(iso) {
|
|
33044
|
+
return iso.slice(0, 10);
|
|
33045
|
+
}
|
|
33046
|
+
function formatFulltext(lines, ref2) {
|
|
33047
|
+
if (!ref2.fulltext) return;
|
|
33048
|
+
if (!ref2.fulltext.pdf && !ref2.fulltext.markdown) {
|
|
33049
|
+
lines.push(`${label("Fulltext:")}-`);
|
|
33050
|
+
return;
|
|
33051
|
+
}
|
|
33052
|
+
lines.push(`${label("Fulltext:")}`);
|
|
33053
|
+
lines.push(` pdf: ${ref2.fulltext.pdf ?? "-"}`);
|
|
33054
|
+
lines.push(` markdown: ${ref2.fulltext.markdown ?? "-"}`);
|
|
33055
|
+
}
|
|
33056
|
+
function formatAttachments(lines, ref2) {
|
|
33057
|
+
if (!ref2.attachments || ref2.attachments.length === 0) return;
|
|
33058
|
+
const roles = /* @__PURE__ */ new Map();
|
|
33059
|
+
for (const a of ref2.attachments) {
|
|
33060
|
+
roles.set(a.role, (roles.get(a.role) ?? 0) + 1);
|
|
33061
|
+
}
|
|
33062
|
+
const parts = [...roles.entries()].map(([role, count]) => `${role} (${count} files)`);
|
|
33063
|
+
lines.push(`${label("Files:")}${parts.join(", ")}`);
|
|
33064
|
+
}
|
|
33065
|
+
function formatAbstract(lines, ref2) {
|
|
33066
|
+
if (!ref2.abstract) return;
|
|
33067
|
+
lines.push("");
|
|
33068
|
+
lines.push(`${label("Abstract:")}`);
|
|
33069
|
+
for (const line of ref2.abstract.split("\n")) {
|
|
33070
|
+
lines.push(` ${line}`);
|
|
33071
|
+
}
|
|
33072
|
+
}
|
|
33073
|
+
function formatShowPretty(ref2) {
|
|
33074
|
+
const lines = [];
|
|
33075
|
+
const header = ref2.title ? `[${ref2.id}] ${ref2.title}` : `[${ref2.id}]`;
|
|
33076
|
+
lines.push(header);
|
|
33077
|
+
lines.push(`${label("Type:")}${ref2.type}`);
|
|
33078
|
+
if (ref2.authors) {
|
|
33079
|
+
lines.push(`${label("Authors:")}${ref2.authors.join("; ")}`);
|
|
33080
|
+
}
|
|
33081
|
+
if (ref2.year != null) {
|
|
33082
|
+
lines.push(`${label("Year:")}${ref2.year}`);
|
|
33083
|
+
}
|
|
33084
|
+
if (ref2.journal) {
|
|
33085
|
+
lines.push(`${label("Journal:")}${formatJournalLine(ref2)}`);
|
|
33086
|
+
}
|
|
33087
|
+
if (ref2.doi) lines.push(`${label("DOI:")}${ref2.doi}`);
|
|
33088
|
+
if (ref2.pmid) lines.push(`${label("PMID:")}${ref2.pmid}`);
|
|
33089
|
+
if (ref2.pmcid) lines.push(`${label("PMCID:")}${ref2.pmcid}`);
|
|
33090
|
+
if (ref2.url) lines.push(`${label("URL:")}${ref2.url}`);
|
|
33091
|
+
lines.push(`${label("UUID:")}${ref2.uuid ?? "(no uuid)"}`);
|
|
33092
|
+
if (ref2.tags && ref2.tags.length > 0) {
|
|
33093
|
+
lines.push(`${label("Tags:")}${ref2.tags.join(", ")}`);
|
|
33094
|
+
}
|
|
33095
|
+
if (ref2.created) lines.push(`${label("Added:")}${formatDate(ref2.created)}`);
|
|
33096
|
+
if (ref2.modified) lines.push(`${label("Modified:")}${formatDate(ref2.modified)}`);
|
|
33097
|
+
formatFulltext(lines, ref2);
|
|
33098
|
+
formatAttachments(lines, ref2);
|
|
33099
|
+
formatAbstract(lines, ref2);
|
|
33100
|
+
return lines.join("\n");
|
|
33101
|
+
}
|
|
33102
|
+
async function executeShow(identifier, options, context) {
|
|
33103
|
+
const idType = options.uuid ? "uuid" : "id";
|
|
33104
|
+
return context.library.find(identifier, { idType });
|
|
33105
|
+
}
|
|
33106
|
+
function formatShowOutput(item, options, attachmentsDirectory) {
|
|
33107
|
+
const format2 = options.json ? "json" : options.output ?? "pretty";
|
|
33108
|
+
const normalizeOpts = attachmentsDirectory ? { attachmentsDirectory } : void 0;
|
|
33109
|
+
if (format2 === "json") {
|
|
33110
|
+
const normalized2 = normalizeReference(item, normalizeOpts);
|
|
33111
|
+
return JSON.stringify(normalized2, null, 2);
|
|
33112
|
+
}
|
|
33113
|
+
if (format2 === "yaml") {
|
|
33114
|
+
const normalized2 = normalizeReference(item, normalizeOpts);
|
|
33115
|
+
return stringify(normalized2);
|
|
33116
|
+
}
|
|
33117
|
+
if (format2 === "bibtex") {
|
|
33118
|
+
return formatBibtex([item]);
|
|
33119
|
+
}
|
|
33120
|
+
const normalized = normalizeReference(item, normalizeOpts);
|
|
33121
|
+
return formatShowPretty(normalized);
|
|
33122
|
+
}
|
|
33123
|
+
async function executeInteractiveSelect$1(context, config2) {
|
|
33124
|
+
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
33125
|
+
const { selectReferencesOrExit } = await import("./reference-select-B9b9Ez7Q.js");
|
|
33126
|
+
const allReferences = await context.library.getAll();
|
|
33127
|
+
const identifiers = await withAlternateScreen2(
|
|
33128
|
+
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
33129
|
+
);
|
|
33130
|
+
return identifiers[0] ?? "";
|
|
33131
|
+
}
|
|
33132
|
+
async function handleShowAction(identifier, options, globalOpts) {
|
|
33133
|
+
try {
|
|
33134
|
+
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
33135
|
+
const context = await createExecutionContext(config2, Library.load);
|
|
33136
|
+
let resolvedIdentifier;
|
|
33137
|
+
if (identifier) {
|
|
33138
|
+
resolvedIdentifier = identifier;
|
|
33139
|
+
} else if (isTTY()) {
|
|
33140
|
+
resolvedIdentifier = await executeInteractiveSelect$1(context, config2);
|
|
33141
|
+
} else {
|
|
33142
|
+
const stdinId = await readIdentifierFromStdin();
|
|
33143
|
+
if (!stdinId) {
|
|
33144
|
+
exitWithError("Identifier required (non-interactive mode)");
|
|
33145
|
+
return;
|
|
33146
|
+
}
|
|
33147
|
+
resolvedIdentifier = stdinId;
|
|
33148
|
+
}
|
|
33149
|
+
const item = await executeShow(resolvedIdentifier, options, context);
|
|
33150
|
+
if (!item) {
|
|
33151
|
+
exitWithError(`Reference not found: ${resolvedIdentifier}`);
|
|
33152
|
+
return;
|
|
33153
|
+
}
|
|
33154
|
+
const output = formatShowOutput(item, options, config2.attachments.directory);
|
|
33155
|
+
if (output) {
|
|
33156
|
+
await writeOutputWithClipboard(output, false, config2.logLevel === "silent");
|
|
33157
|
+
}
|
|
33158
|
+
setExitCode(ExitCode.SUCCESS);
|
|
33159
|
+
} catch (error) {
|
|
33160
|
+
process.stderr.write(`Error: ${error instanceof Error ? error.message : String(error)}
|
|
33161
|
+
`);
|
|
33162
|
+
setExitCode(ExitCode.INTERNAL_ERROR);
|
|
33163
|
+
}
|
|
33164
|
+
}
|
|
32839
33165
|
function parseSetOption(input) {
|
|
32840
33166
|
const match = input.match(/^([a-zA-Z][a-zA-Z0-9_.]*)([\+\-]?=)(.*)$/);
|
|
32841
33167
|
if (!match) {
|
|
@@ -33045,7 +33371,7 @@ function formatUpdateOutput(result, identifier) {
|
|
|
33045
33371
|
}
|
|
33046
33372
|
async function executeInteractiveUpdate(context, config2) {
|
|
33047
33373
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
33048
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
33374
|
+
const { selectReferencesOrExit } = await import("./reference-select-B9b9Ez7Q.js");
|
|
33049
33375
|
const allReferences = await context.library.getAll();
|
|
33050
33376
|
const identifiers = await withAlternateScreen2(
|
|
33051
33377
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -33340,7 +33666,7 @@ function getUrlExitCode(result) {
|
|
|
33340
33666
|
}
|
|
33341
33667
|
async function executeInteractiveSelect(context, config2) {
|
|
33342
33668
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
33343
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
33669
|
+
const { selectReferencesOrExit } = await import("./reference-select-B9b9Ez7Q.js");
|
|
33344
33670
|
const allReferences = await context.library.getAll();
|
|
33345
33671
|
const identifiers = await withAlternateScreen2(
|
|
33346
33672
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -33774,6 +34100,7 @@ function createProgram() {
|
|
|
33774
34100
|
}
|
|
33775
34101
|
});
|
|
33776
34102
|
registerListCommand(program);
|
|
34103
|
+
registerShowCommand(program);
|
|
33777
34104
|
registerSearchCommand(program);
|
|
33778
34105
|
registerExportCommand(program);
|
|
33779
34106
|
registerAddCommand(program);
|
|
@@ -33787,6 +34114,7 @@ function createProgram() {
|
|
|
33787
34114
|
registerAttachCommand(program);
|
|
33788
34115
|
registerMcpCommand(program);
|
|
33789
34116
|
registerUrlCommand(program);
|
|
34117
|
+
registerInstallCommand(program);
|
|
33790
34118
|
registerConfigCommand(program);
|
|
33791
34119
|
registerCompletionCommand(program);
|
|
33792
34120
|
return program;
|
|
@@ -33815,6 +34143,12 @@ function registerListCommand(program) {
|
|
|
33815
34143
|
await handleListAction(options, program);
|
|
33816
34144
|
});
|
|
33817
34145
|
}
|
|
34146
|
+
function registerShowCommand(program) {
|
|
34147
|
+
program.command("show [identifier]").description("Show detailed information about a single reference").option("--uuid", "Interpret identifier as UUID").option("-o, --output <format>", "Output format: pretty (default), json, yaml, bibtex").option("--json", "Alias for --output json").action(async (identifier, options) => {
|
|
34148
|
+
const globalOpts = program.opts();
|
|
34149
|
+
await handleShowAction(identifier, options, globalOpts);
|
|
34150
|
+
});
|
|
34151
|
+
}
|
|
33818
34152
|
async function handleExportAction(ids, options, program) {
|
|
33819
34153
|
try {
|
|
33820
34154
|
const globalOpts = program.opts();
|
|
@@ -33945,7 +34279,7 @@ function shouldAutoFetch(cliFlag, configEnabled) {
|
|
|
33945
34279
|
return configEnabled;
|
|
33946
34280
|
}
|
|
33947
34281
|
async function performAutoFetch(addedItems, context, config2) {
|
|
33948
|
-
const { fulltextFetch: fulltextFetch2 } = await import("./index-
|
|
34282
|
+
const { fulltextFetch: fulltextFetch2 } = await import("./index-B4-i4PrU.js").then((n) => n.z);
|
|
33949
34283
|
const fetchResults = await autoFetchFulltext(addedItems, context, {
|
|
33950
34284
|
fulltextConfig: config2.fulltext,
|
|
33951
34285
|
fulltextDirectory: config2.attachments.directory,
|
|
@@ -34211,6 +34545,25 @@ function registerUrlCommand(program) {
|
|
|
34211
34545
|
await handleUrlAction(identifiers.length > 0 ? identifiers : void 0, options, globalOpts);
|
|
34212
34546
|
});
|
|
34213
34547
|
}
|
|
34548
|
+
function registerInstallCommand(program) {
|
|
34549
|
+
const installCmd = program.command("install").description("Install tools and integrations");
|
|
34550
|
+
installCmd.command("skills").description("Install Agent Skills (SKILL.md) for AI coding agents").option("-f, --force", "Overwrite existing files").option("-u, --user", "Install to user-level directory (~/.agents/skills/)").action(async (options) => {
|
|
34551
|
+
try {
|
|
34552
|
+
const result = await executeInstallSkills({
|
|
34553
|
+
force: options.force ?? false,
|
|
34554
|
+
...options.user != null && { user: options.user }
|
|
34555
|
+
});
|
|
34556
|
+
const output = formatInstallSkillsOutput(result);
|
|
34557
|
+
process.stdout.write(`${output}
|
|
34558
|
+
`);
|
|
34559
|
+
setExitCode(ExitCode.SUCCESS);
|
|
34560
|
+
} catch (error) {
|
|
34561
|
+
process.stderr.write(`Error: ${error instanceof Error ? error.message : String(error)}
|
|
34562
|
+
`);
|
|
34563
|
+
setExitCode(ExitCode.INTERNAL_ERROR);
|
|
34564
|
+
}
|
|
34565
|
+
});
|
|
34566
|
+
}
|
|
34214
34567
|
async function main(argv) {
|
|
34215
34568
|
const program = createProgram();
|
|
34216
34569
|
if (process.env.COMP_LINE) {
|
|
@@ -34240,4 +34593,4 @@ export {
|
|
|
34240
34593
|
restoreStdinAfterInk as r,
|
|
34241
34594
|
syncAttachments as s
|
|
34242
34595
|
};
|
|
34243
|
-
//# sourceMappingURL=index-
|
|
34596
|
+
//# sourceMappingURL=index-CmkN2-2A.js.map
|