@ncukondo/reference-manager 0.17.1 → 0.18.1
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/dist/chunks/action-menu-DRkjGlCc.js +87 -0
- package/dist/chunks/action-menu-DRkjGlCc.js.map +1 -0
- package/dist/chunks/clipboard-KXwFSJ4w.js +56 -0
- package/dist/chunks/clipboard-KXwFSJ4w.js.map +1 -0
- package/dist/chunks/{format-ByjxlVm5.js → format-DiPpWzBA.js} +2 -2
- package/dist/chunks/{format-ByjxlVm5.js.map → format-DiPpWzBA.js.map} +1 -1
- package/dist/chunks/{index-BigPRCTh.js → index-BB_a8Tm7.js} +50 -38
- package/dist/chunks/index-BB_a8Tm7.js.map +1 -0
- package/dist/chunks/{index-DWEWWvFO.js → index-GQ2KSWiQ.js} +2 -2
- package/dist/chunks/index-GQ2KSWiQ.js.map +1 -0
- package/dist/chunks/{index-wb8zgPJ0.js → index-vInTzmDN.js} +574 -92
- package/dist/chunks/index-vInTzmDN.js.map +1 -0
- package/dist/chunks/{loader-Ds4s8UO0.js → loader-BtW20O32.js} +40 -8
- package/dist/chunks/loader-BtW20O32.js.map +1 -0
- package/dist/chunks/{reference-select-O0PY7CRU.js → reference-select-DCXlkWpk.js} +3 -3
- package/dist/chunks/{reference-select-O0PY7CRU.js.map → reference-select-DCXlkWpk.js.map} +1 -1
- package/dist/chunks/{style-select-DF5kX4G6.js → style-select-BhBHyU3u.js} +2 -2
- package/dist/chunks/{style-select-DF5kX4G6.js.map → style-select-BhBHyU3u.js.map} +1 -1
- package/dist/cli/commands/attach.d.ts +4 -0
- package/dist/cli/commands/attach.d.ts.map +1 -1
- package/dist/cli/commands/cite.d.ts.map +1 -1
- package/dist/cli/commands/list.d.ts +6 -2
- package/dist/cli/commands/list.d.ts.map +1 -1
- package/dist/cli/commands/remove.d.ts +5 -0
- package/dist/cli/commands/remove.d.ts.map +1 -1
- package/dist/cli/commands/search.d.ts +18 -3
- package/dist/cli/commands/search.d.ts.map +1 -1
- package/dist/cli/commands/url.d.ts +58 -0
- package/dist/cli/commands/url.d.ts.map +1 -0
- package/dist/cli/helpers.d.ts +18 -0
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/env-override.d.ts.map +1 -1
- package/dist/config/key-parser.d.ts.map +1 -1
- package/dist/config/loader.d.ts +7 -4
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/schema.d.ts +27 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/features/format/items.d.ts +1 -1
- package/dist/features/format/items.d.ts.map +1 -1
- package/dist/features/interactive/action-menu.d.ts +40 -5
- package/dist/features/interactive/action-menu.d.ts.map +1 -1
- package/dist/features/interactive/apps/SearchFlowApp.d.ts +8 -3
- package/dist/features/interactive/apps/SearchFlowApp.d.ts.map +1 -1
- package/dist/features/interactive/apps/runSearchFlow.d.ts +5 -0
- package/dist/features/interactive/apps/runSearchFlow.d.ts.map +1 -1
- package/dist/features/operations/url.d.ts +24 -0
- package/dist/features/operations/url.d.ts.map +1 -0
- package/dist/index.js +1 -1
- package/dist/utils/clipboard.d.ts +19 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/package.json +2 -2
- package/dist/chunks/index-BigPRCTh.js.map +0 -1
- package/dist/chunks/index-DWEWWvFO.js.map +0 -1
- package/dist/chunks/index-wb8zgPJ0.js.map +0 -1
- package/dist/chunks/loader-Ds4s8UO0.js.map +0 -1
|
@@ -8,7 +8,7 @@ import * as path from "node:path";
|
|
|
8
8
|
import path__default, { extname, join, basename, dirname } from "node:path";
|
|
9
9
|
import fs__default, { stat, rename, copyFile, readFile, unlink, readdir, mkdir, rm } from "node:fs/promises";
|
|
10
10
|
import { g as getExtension, i as isValidFulltextFiles, a as isReservedRole, F as FULLTEXT_ROLE, b as formatToExtension, c as findFulltextFiles, d as findFulltextFile, e as extensionToFormat, B as BUILTIN_STYLES, h as getFulltextAttachmentTypes, s as startServerWithFileWatcher } from "./index-B4gr0P83.js";
|
|
11
|
-
import { o as openWithSystemApp, l as loadConfig, e as getDefaultCurrentDirConfigFilename, h as getDefaultUserConfigPath } from "./loader-
|
|
11
|
+
import { o as openWithSystemApp, l as loadConfig, e as getDefaultCurrentDirConfigFilename, h as getDefaultUserConfigPath } from "./loader-BtW20O32.js";
|
|
12
12
|
import { spawn, spawnSync } from "node:child_process";
|
|
13
13
|
import process$1, { stdin, stdout } from "node:process";
|
|
14
14
|
import * as readline from "node:readline";
|
|
@@ -20,7 +20,7 @@ import "@citation-js/plugin-csl";
|
|
|
20
20
|
import { ZodOptional as ZodOptional$2, z } from "zod";
|
|
21
21
|
import { serve } from "@hono/node-server";
|
|
22
22
|
const name = "@ncukondo/reference-manager";
|
|
23
|
-
const version$1 = "0.
|
|
23
|
+
const version$1 = "0.18.1";
|
|
24
24
|
const description$1 = "A local reference management tool using CSL-JSON as the single source of truth";
|
|
25
25
|
const packageJson = {
|
|
26
26
|
name,
|
|
@@ -1056,27 +1056,27 @@ class OperationsLibrary {
|
|
|
1056
1056
|
}
|
|
1057
1057
|
// Attachment operations
|
|
1058
1058
|
async attachAdd(options) {
|
|
1059
|
-
const { addAttachment: addAttachment2 } = await import("./index-
|
|
1059
|
+
const { addAttachment: addAttachment2 } = await import("./index-GQ2KSWiQ.js");
|
|
1060
1060
|
return addAttachment2(this.library, options);
|
|
1061
1061
|
}
|
|
1062
1062
|
async attachList(options) {
|
|
1063
|
-
const { listAttachments: listAttachments2 } = await import("./index-
|
|
1063
|
+
const { listAttachments: listAttachments2 } = await import("./index-GQ2KSWiQ.js");
|
|
1064
1064
|
return listAttachments2(this.library, options);
|
|
1065
1065
|
}
|
|
1066
1066
|
async attachGet(options) {
|
|
1067
|
-
const { getAttachment: getAttachment2 } = await import("./index-
|
|
1067
|
+
const { getAttachment: getAttachment2 } = await import("./index-GQ2KSWiQ.js");
|
|
1068
1068
|
return getAttachment2(this.library, options);
|
|
1069
1069
|
}
|
|
1070
1070
|
async attachDetach(options) {
|
|
1071
|
-
const { detachAttachment: detachAttachment2 } = await import("./index-
|
|
1071
|
+
const { detachAttachment: detachAttachment2 } = await import("./index-GQ2KSWiQ.js");
|
|
1072
1072
|
return detachAttachment2(this.library, options);
|
|
1073
1073
|
}
|
|
1074
1074
|
async attachSync(options) {
|
|
1075
|
-
const { syncAttachments: syncAttachments2 } = await import("./index-
|
|
1075
|
+
const { syncAttachments: syncAttachments2 } = await import("./index-GQ2KSWiQ.js");
|
|
1076
1076
|
return syncAttachments2(this.library, options);
|
|
1077
1077
|
}
|
|
1078
1078
|
async attachOpen(options) {
|
|
1079
|
-
const { openAttachment: openAttachment2 } = await import("./index-
|
|
1079
|
+
const { openAttachment: openAttachment2 } = await import("./index-GQ2KSWiQ.js");
|
|
1080
1080
|
return openAttachment2(this.library, options);
|
|
1081
1081
|
}
|
|
1082
1082
|
}
|
|
@@ -1092,8 +1092,8 @@ class ServerClient {
|
|
|
1092
1092
|
* @returns Array of CSL items
|
|
1093
1093
|
*/
|
|
1094
1094
|
async getAll() {
|
|
1095
|
-
const
|
|
1096
|
-
const response = await fetch(
|
|
1095
|
+
const url2 = `${this.baseUrl}/api/references`;
|
|
1096
|
+
const response = await fetch(url2);
|
|
1097
1097
|
if (!response.ok) {
|
|
1098
1098
|
throw new Error(await response.text());
|
|
1099
1099
|
}
|
|
@@ -1107,8 +1107,8 @@ class ServerClient {
|
|
|
1107
1107
|
*/
|
|
1108
1108
|
async find(identifier, options = {}) {
|
|
1109
1109
|
const { idType = "id" } = options;
|
|
1110
|
-
const
|
|
1111
|
-
const response = await fetch(
|
|
1110
|
+
const url2 = idType === "uuid" ? `${this.baseUrl}/api/references/uuid/${encodeURIComponent(identifier)}` : `${this.baseUrl}/api/references/id/${encodeURIComponent(identifier)}`;
|
|
1111
|
+
const response = await fetch(url2);
|
|
1112
1112
|
if (response.status === 404) {
|
|
1113
1113
|
return void 0;
|
|
1114
1114
|
}
|
|
@@ -1126,8 +1126,8 @@ class ServerClient {
|
|
|
1126
1126
|
* @returns The added CSL item (with generated ID and UUID)
|
|
1127
1127
|
*/
|
|
1128
1128
|
async add(item) {
|
|
1129
|
-
const
|
|
1130
|
-
const response = await fetch(
|
|
1129
|
+
const url2 = `${this.baseUrl}/api/references`;
|
|
1130
|
+
const response = await fetch(url2, {
|
|
1131
1131
|
method: "POST",
|
|
1132
1132
|
headers: { "Content-Type": "application/json" },
|
|
1133
1133
|
body: JSON.stringify(item)
|
|
@@ -1146,8 +1146,8 @@ class ServerClient {
|
|
|
1146
1146
|
*/
|
|
1147
1147
|
async update(identifier, updates, options) {
|
|
1148
1148
|
const { idType = "id", onIdCollision } = options ?? {};
|
|
1149
|
-
const
|
|
1150
|
-
const response = await fetch(
|
|
1149
|
+
const url2 = idType === "uuid" ? `${this.baseUrl}/api/references/uuid/${encodeURIComponent(identifier)}` : `${this.baseUrl}/api/references/id/${encodeURIComponent(identifier)}`;
|
|
1150
|
+
const response = await fetch(url2, {
|
|
1151
1151
|
method: "PUT",
|
|
1152
1152
|
headers: { "Content-Type": "application/json" },
|
|
1153
1153
|
body: JSON.stringify({ updates, onIdCollision })
|
|
@@ -1171,8 +1171,8 @@ class ServerClient {
|
|
|
1171
1171
|
*/
|
|
1172
1172
|
async remove(identifier, options = {}) {
|
|
1173
1173
|
const { idType = "id" } = options;
|
|
1174
|
-
const
|
|
1175
|
-
const response = await fetch(
|
|
1174
|
+
const url2 = idType === "uuid" ? `${this.baseUrl}/api/references/uuid/${encodeURIComponent(identifier)}` : `${this.baseUrl}/api/references/id/${encodeURIComponent(identifier)}`;
|
|
1175
|
+
const response = await fetch(url2, {
|
|
1176
1176
|
method: "DELETE"
|
|
1177
1177
|
});
|
|
1178
1178
|
if (!response.ok && response.status !== 404) {
|
|
@@ -1203,8 +1203,8 @@ class ServerClient {
|
|
|
1203
1203
|
* @returns Result containing added, failed, and skipped items
|
|
1204
1204
|
*/
|
|
1205
1205
|
async import(inputs, options) {
|
|
1206
|
-
const
|
|
1207
|
-
const response = await fetch(
|
|
1206
|
+
const url2 = `${this.baseUrl}/api/add`;
|
|
1207
|
+
const response = await fetch(url2, {
|
|
1208
1208
|
method: "POST",
|
|
1209
1209
|
headers: { "Content-Type": "application/json" },
|
|
1210
1210
|
body: JSON.stringify({ inputs, options })
|
|
@@ -1220,8 +1220,8 @@ class ServerClient {
|
|
|
1220
1220
|
* @returns Cite result with per-identifier results
|
|
1221
1221
|
*/
|
|
1222
1222
|
async cite(options) {
|
|
1223
|
-
const
|
|
1224
|
-
const response = await fetch(
|
|
1223
|
+
const url2 = `${this.baseUrl}/api/cite`;
|
|
1224
|
+
const response = await fetch(url2, {
|
|
1225
1225
|
method: "POST",
|
|
1226
1226
|
headers: { "Content-Type": "application/json" },
|
|
1227
1227
|
body: JSON.stringify(options)
|
|
@@ -1237,8 +1237,8 @@ class ServerClient {
|
|
|
1237
1237
|
* @returns List result with raw CslItem[]
|
|
1238
1238
|
*/
|
|
1239
1239
|
async list(options) {
|
|
1240
|
-
const
|
|
1241
|
-
const response = await fetch(
|
|
1240
|
+
const url2 = `${this.baseUrl}/api/list`;
|
|
1241
|
+
const response = await fetch(url2, {
|
|
1242
1242
|
method: "POST",
|
|
1243
1243
|
headers: { "Content-Type": "application/json" },
|
|
1244
1244
|
body: JSON.stringify(options ?? {})
|
|
@@ -1254,8 +1254,8 @@ class ServerClient {
|
|
|
1254
1254
|
* @returns Search result with raw CslItem[]
|
|
1255
1255
|
*/
|
|
1256
1256
|
async search(options) {
|
|
1257
|
-
const
|
|
1258
|
-
const response = await fetch(
|
|
1257
|
+
const url2 = `${this.baseUrl}/api/search`;
|
|
1258
|
+
const response = await fetch(url2, {
|
|
1259
1259
|
method: "POST",
|
|
1260
1260
|
headers: { "Content-Type": "application/json" },
|
|
1261
1261
|
body: JSON.stringify(options)
|
|
@@ -1274,8 +1274,8 @@ class ServerClient {
|
|
|
1274
1274
|
* @returns Result of the add operation
|
|
1275
1275
|
*/
|
|
1276
1276
|
async attachAdd(options) {
|
|
1277
|
-
const
|
|
1278
|
-
const response = await fetch(
|
|
1277
|
+
const url2 = `${this.baseUrl}/api/attachments/add`;
|
|
1278
|
+
const response = await fetch(url2, {
|
|
1279
1279
|
method: "POST",
|
|
1280
1280
|
headers: { "Content-Type": "application/json" },
|
|
1281
1281
|
body: JSON.stringify(options)
|
|
@@ -1291,8 +1291,8 @@ class ServerClient {
|
|
|
1291
1291
|
* @returns List of attachments
|
|
1292
1292
|
*/
|
|
1293
1293
|
async attachList(options) {
|
|
1294
|
-
const
|
|
1295
|
-
const response = await fetch(
|
|
1294
|
+
const url2 = `${this.baseUrl}/api/attachments/list`;
|
|
1295
|
+
const response = await fetch(url2, {
|
|
1296
1296
|
method: "POST",
|
|
1297
1297
|
headers: { "Content-Type": "application/json" },
|
|
1298
1298
|
body: JSON.stringify(options)
|
|
@@ -1308,8 +1308,8 @@ class ServerClient {
|
|
|
1308
1308
|
* @returns Attachment file path or content
|
|
1309
1309
|
*/
|
|
1310
1310
|
async attachGet(options) {
|
|
1311
|
-
const
|
|
1312
|
-
const response = await fetch(
|
|
1311
|
+
const url2 = `${this.baseUrl}/api/attachments/get`;
|
|
1312
|
+
const response = await fetch(url2, {
|
|
1313
1313
|
method: "POST",
|
|
1314
1314
|
headers: { "Content-Type": "application/json" },
|
|
1315
1315
|
body: JSON.stringify(options)
|
|
@@ -1325,8 +1325,8 @@ class ServerClient {
|
|
|
1325
1325
|
* @returns Result of the detach operation
|
|
1326
1326
|
*/
|
|
1327
1327
|
async attachDetach(options) {
|
|
1328
|
-
const
|
|
1329
|
-
const response = await fetch(
|
|
1328
|
+
const url2 = `${this.baseUrl}/api/attachments/detach`;
|
|
1329
|
+
const response = await fetch(url2, {
|
|
1330
1330
|
method: "POST",
|
|
1331
1331
|
headers: { "Content-Type": "application/json" },
|
|
1332
1332
|
body: JSON.stringify(options)
|
|
@@ -1342,8 +1342,8 @@ class ServerClient {
|
|
|
1342
1342
|
* @returns Sync result
|
|
1343
1343
|
*/
|
|
1344
1344
|
async attachSync(options) {
|
|
1345
|
-
const
|
|
1346
|
-
const response = await fetch(
|
|
1345
|
+
const url2 = `${this.baseUrl}/api/attachments/sync`;
|
|
1346
|
+
const response = await fetch(url2, {
|
|
1347
1347
|
method: "POST",
|
|
1348
1348
|
headers: { "Content-Type": "application/json" },
|
|
1349
1349
|
body: JSON.stringify(options)
|
|
@@ -1359,8 +1359,8 @@ class ServerClient {
|
|
|
1359
1359
|
* @returns Result of the open operation
|
|
1360
1360
|
*/
|
|
1361
1361
|
async attachOpen(options) {
|
|
1362
|
-
const
|
|
1363
|
-
const response = await fetch(
|
|
1362
|
+
const url2 = `${this.baseUrl}/api/attachments/open`;
|
|
1363
|
+
const response = await fetch(url2, {
|
|
1364
1364
|
method: "POST",
|
|
1365
1365
|
headers: { "Content-Type": "application/json" },
|
|
1366
1366
|
body: JSON.stringify(options)
|
|
@@ -1458,7 +1458,9 @@ function parseJsonInput(input) {
|
|
|
1458
1458
|
}
|
|
1459
1459
|
}
|
|
1460
1460
|
async function loadConfigWithOverrides(options) {
|
|
1461
|
-
const config2 = await loadConfig(
|
|
1461
|
+
const config2 = await loadConfig({
|
|
1462
|
+
...options.config && { configPath: options.config }
|
|
1463
|
+
});
|
|
1462
1464
|
const overrides = {};
|
|
1463
1465
|
if (options.library) {
|
|
1464
1466
|
overrides.library = options.library;
|
|
@@ -1566,6 +1568,35 @@ function exitWithError(message, code2 = ExitCode.ERROR) {
|
|
|
1566
1568
|
`);
|
|
1567
1569
|
setExitCode(code2);
|
|
1568
1570
|
}
|
|
1571
|
+
function resolveClipboardEnabled(options, config2, isTui) {
|
|
1572
|
+
if (options.clipboard !== void 0) {
|
|
1573
|
+
return options.clipboard;
|
|
1574
|
+
}
|
|
1575
|
+
const envVal = process.env.REFERENCE_MANAGER_CLIPBOARD_AUTO_COPY;
|
|
1576
|
+
if (envVal !== void 0) {
|
|
1577
|
+
return envVal === "1" || envVal === "true";
|
|
1578
|
+
}
|
|
1579
|
+
if (isTui) {
|
|
1580
|
+
return config2.cli.tui.clipboardAutoCopy;
|
|
1581
|
+
}
|
|
1582
|
+
return false;
|
|
1583
|
+
}
|
|
1584
|
+
async function writeOutputWithClipboard(output, clipboardEnabled, quiet) {
|
|
1585
|
+
process.stdout.write(`${output}
|
|
1586
|
+
`);
|
|
1587
|
+
if (clipboardEnabled) {
|
|
1588
|
+
const { copyToClipboard } = await import("./clipboard-KXwFSJ4w.js");
|
|
1589
|
+
const result = await copyToClipboard(output);
|
|
1590
|
+
if (!quiet) {
|
|
1591
|
+
if (result.success) {
|
|
1592
|
+
process.stderr.write("Copied to clipboard\n");
|
|
1593
|
+
} else {
|
|
1594
|
+
process.stderr.write(`Warning: Failed to copy to clipboard: ${result.error}
|
|
1595
|
+
`);
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1569
1600
|
async function executeAttachOpen(options, context) {
|
|
1570
1601
|
const operationOptions = {
|
|
1571
1602
|
identifier: options.identifier,
|
|
@@ -1762,9 +1793,9 @@ function formatSyncPreview(result) {
|
|
|
1762
1793
|
function getAttachExitCode(result) {
|
|
1763
1794
|
return result.success ? 0 : 1;
|
|
1764
1795
|
}
|
|
1765
|
-
async function executeInteractiveSelect$
|
|
1796
|
+
async function executeInteractiveSelect$2(context, config2) {
|
|
1766
1797
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
1767
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
1798
|
+
const { selectReferencesOrExit } = await import("./reference-select-DCXlkWpk.js");
|
|
1768
1799
|
const allReferences = await context.library.getAll();
|
|
1769
1800
|
const identifiers = await withAlternateScreen2(
|
|
1770
1801
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -1776,7 +1807,7 @@ async function resolveIdentifier(identifierArg, context, config2) {
|
|
|
1776
1807
|
return identifierArg;
|
|
1777
1808
|
}
|
|
1778
1809
|
if (isTTY()) {
|
|
1779
|
-
return executeInteractiveSelect$
|
|
1810
|
+
return executeInteractiveSelect$2(context, config2);
|
|
1780
1811
|
}
|
|
1781
1812
|
const stdinId = await readIdentifierFromStdin();
|
|
1782
1813
|
if (!stdinId) {
|
|
@@ -1894,6 +1925,7 @@ async function handleAttachOpenAction(identifierArg, filenameArg, options, globa
|
|
|
1894
1925
|
process.stdout.write(`${result.path}
|
|
1895
1926
|
`);
|
|
1896
1927
|
setExitCode(ExitCode.SUCCESS);
|
|
1928
|
+
return;
|
|
1897
1929
|
}
|
|
1898
1930
|
if (shouldUseInteractive) {
|
|
1899
1931
|
await runInteractiveMode(
|
|
@@ -2080,6 +2112,28 @@ async function handleAttachSyncAction(identifierArg, options, globalOpts) {
|
|
|
2080
2112
|
setExitCode(ExitCode.INTERNAL_ERROR);
|
|
2081
2113
|
}
|
|
2082
2114
|
}
|
|
2115
|
+
const attach = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2116
|
+
__proto__: null,
|
|
2117
|
+
executeAttachAdd,
|
|
2118
|
+
executeAttachDetach,
|
|
2119
|
+
executeAttachGet,
|
|
2120
|
+
executeAttachList,
|
|
2121
|
+
executeAttachOpen,
|
|
2122
|
+
executeAttachSync,
|
|
2123
|
+
formatAttachAddOutput,
|
|
2124
|
+
formatAttachDetachOutput,
|
|
2125
|
+
formatAttachListOutput,
|
|
2126
|
+
formatAttachOpenOutput,
|
|
2127
|
+
formatAttachSyncOutput,
|
|
2128
|
+
getAttachExitCode,
|
|
2129
|
+
handleAttachAddAction,
|
|
2130
|
+
handleAttachDetachAction,
|
|
2131
|
+
handleAttachGetAction,
|
|
2132
|
+
handleAttachListAction,
|
|
2133
|
+
handleAttachOpenAction,
|
|
2134
|
+
handleAttachSyncAction,
|
|
2135
|
+
runInteractiveMode
|
|
2136
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
2083
2137
|
async function validateOptions$2(options) {
|
|
2084
2138
|
if (options.output && !["text", "html", "rtf"].includes(options.output)) {
|
|
2085
2139
|
throw new Error(`Invalid output format '${options.output}'. Must be one of: text, html, rtf`);
|
|
@@ -2137,8 +2191,8 @@ function getCiteExitCode(result) {
|
|
|
2137
2191
|
}
|
|
2138
2192
|
async function executeInteractiveCite(options, context, config2) {
|
|
2139
2193
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
2140
|
-
const { runCiteFlow } = await import("./index-
|
|
2141
|
-
const { buildStyleChoices, listCustomStyles } = await import("./style-select-
|
|
2194
|
+
const { runCiteFlow } = await import("./index-BB_a8Tm7.js");
|
|
2195
|
+
const { buildStyleChoices, listCustomStyles } = await import("./style-select-BhBHyU3u.js");
|
|
2142
2196
|
const { search } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.z);
|
|
2143
2197
|
const { tokenize } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.y);
|
|
2144
2198
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
@@ -2180,8 +2234,10 @@ async function handleCiteAction(identifiers, options, globalOpts) {
|
|
|
2180
2234
|
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
2181
2235
|
const context = await createExecutionContext(config2, Library.load);
|
|
2182
2236
|
let result;
|
|
2237
|
+
let isTuiMode = false;
|
|
2183
2238
|
if (identifiers.length === 0) {
|
|
2184
2239
|
if (isTTY()) {
|
|
2240
|
+
isTuiMode = true;
|
|
2185
2241
|
result = await executeInteractiveCite(options, context, config2);
|
|
2186
2242
|
} else {
|
|
2187
2243
|
const stdinIds = await readIdentifiersFromStdin();
|
|
@@ -2199,8 +2255,8 @@ async function handleCiteAction(identifiers, options, globalOpts) {
|
|
|
2199
2255
|
}
|
|
2200
2256
|
const output = formatCiteOutput(result);
|
|
2201
2257
|
if (output) {
|
|
2202
|
-
|
|
2203
|
-
|
|
2258
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, isTuiMode);
|
|
2259
|
+
await writeOutputWithClipboard(output, clipboardEnabled, config2.logLevel === "silent");
|
|
2204
2260
|
}
|
|
2205
2261
|
const errors2 = formatCiteErrors(result);
|
|
2206
2262
|
if (errors2) {
|
|
@@ -2219,6 +2275,7 @@ const ENV_OVERRIDE_MAP = {
|
|
|
2219
2275
|
REFERENCE_MANAGER_ATTACHMENTS_DIR: "attachments.directory",
|
|
2220
2276
|
REFERENCE_MANAGER_CLI_DEFAULT_LIMIT: "cli.default_limit",
|
|
2221
2277
|
REFERENCE_MANAGER_MCP_DEFAULT_LIMIT: "mcp.default_limit",
|
|
2278
|
+
REFERENCE_MANAGER_CLIPBOARD_AUTO_COPY: "cli.tui.clipboard_auto_copy",
|
|
2222
2279
|
PUBMED_EMAIL: "pubmed.email",
|
|
2223
2280
|
PUBMED_API_KEY: "pubmed.api_key"
|
|
2224
2281
|
};
|
|
@@ -2275,6 +2332,12 @@ const CONFIG_KEY_REGISTRY = [
|
|
|
2275
2332
|
description: "Default format",
|
|
2276
2333
|
enumValues: ["text", "html", "rtf"]
|
|
2277
2334
|
},
|
|
2335
|
+
{
|
|
2336
|
+
key: "citation.default_key_format",
|
|
2337
|
+
type: "enum",
|
|
2338
|
+
description: "Default citation key format",
|
|
2339
|
+
enumValues: ["pandoc", "latex"]
|
|
2340
|
+
},
|
|
2278
2341
|
// pubmed section
|
|
2279
2342
|
{ key: "pubmed.email", type: "string", description: "Email for PubMed API", optional: true },
|
|
2280
2343
|
{ key: "pubmed.api_key", type: "string", description: "API key for PubMed", optional: true },
|
|
@@ -2309,6 +2372,11 @@ const CONFIG_KEY_REGISTRY = [
|
|
|
2309
2372
|
type: "integer",
|
|
2310
2373
|
description: "Search debounce delay (ms)"
|
|
2311
2374
|
},
|
|
2375
|
+
{
|
|
2376
|
+
key: "cli.tui.clipboard_auto_copy",
|
|
2377
|
+
type: "boolean",
|
|
2378
|
+
description: "Auto-copy TUI output to clipboard"
|
|
2379
|
+
},
|
|
2312
2380
|
// cli.edit section
|
|
2313
2381
|
{
|
|
2314
2382
|
key: "cli.edit.default_format",
|
|
@@ -6681,7 +6749,7 @@ function formatEditOutput(result) {
|
|
|
6681
6749
|
}
|
|
6682
6750
|
async function executeInteractiveEdit(options, context, config2) {
|
|
6683
6751
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
6684
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
6752
|
+
const { selectReferencesOrExit } = await import("./reference-select-DCXlkWpk.js");
|
|
6685
6753
|
const allReferences = await context.library.getAll();
|
|
6686
6754
|
const identifiers = await withAlternateScreen2(
|
|
6687
6755
|
() => selectReferencesOrExit(allReferences, { multiSelect: true }, config2.cli.tui)
|
|
@@ -6747,6 +6815,12 @@ async function handleEditAction(identifiers, options, globalOpts) {
|
|
|
6747
6815
|
setExitCode(ExitCode.INTERNAL_ERROR);
|
|
6748
6816
|
}
|
|
6749
6817
|
}
|
|
6818
|
+
const edit = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
6819
|
+
__proto__: null,
|
|
6820
|
+
executeEditCommand,
|
|
6821
|
+
formatEditOutput,
|
|
6822
|
+
handleEditAction
|
|
6823
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
6750
6824
|
const ALIAS = Symbol.for("yaml.alias");
|
|
6751
6825
|
const DOC = Symbol.for("yaml.document");
|
|
6752
6826
|
const MAP = Symbol.for("yaml.map");
|
|
@@ -10327,9 +10401,9 @@ function formatFulltextOpenOutput(result) {
|
|
|
10327
10401
|
function getFulltextExitCode(result) {
|
|
10328
10402
|
return result.success ? 0 : 1;
|
|
10329
10403
|
}
|
|
10330
|
-
async function executeInteractiveSelect(context, config2) {
|
|
10404
|
+
async function executeInteractiveSelect$1(context, config2) {
|
|
10331
10405
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
10332
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
10406
|
+
const { selectReferencesOrExit } = await import("./reference-select-DCXlkWpk.js");
|
|
10333
10407
|
const allReferences = await context.library.getAll();
|
|
10334
10408
|
const identifiers = await withAlternateScreen2(
|
|
10335
10409
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -10366,7 +10440,7 @@ async function handleFulltextAttachAction(identifierArg, filePathArg, options, g
|
|
|
10366
10440
|
setExitCode(ExitCode.ERROR);
|
|
10367
10441
|
return;
|
|
10368
10442
|
}
|
|
10369
|
-
identifier = await executeInteractiveSelect(context, config2);
|
|
10443
|
+
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10370
10444
|
}
|
|
10371
10445
|
const { type: type2, filePath } = parseFulltextAttachTypeAndPath(filePathArg, options);
|
|
10372
10446
|
const stdinContent = !filePath && type2 ? await readStdinBuffer() : void 0;
|
|
@@ -10413,7 +10487,7 @@ async function handleFulltextGetAction(identifierArg, options, globalOpts) {
|
|
|
10413
10487
|
if (identifierArg) {
|
|
10414
10488
|
identifier = identifierArg;
|
|
10415
10489
|
} else if (isTTY()) {
|
|
10416
|
-
identifier = await executeInteractiveSelect(context, config2);
|
|
10490
|
+
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10417
10491
|
} else {
|
|
10418
10492
|
const stdinId = await readIdentifierFromStdin();
|
|
10419
10493
|
if (!stdinId) {
|
|
@@ -10450,7 +10524,7 @@ async function handleFulltextDetachAction(identifierArg, options, globalOpts) {
|
|
|
10450
10524
|
if (identifierArg) {
|
|
10451
10525
|
identifier = identifierArg;
|
|
10452
10526
|
} else if (isTTY()) {
|
|
10453
|
-
identifier = await executeInteractiveSelect(context, config2);
|
|
10527
|
+
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10454
10528
|
} else {
|
|
10455
10529
|
const stdinId = await readIdentifierFromStdin();
|
|
10456
10530
|
if (!stdinId) {
|
|
@@ -10490,7 +10564,7 @@ async function handleFulltextOpenAction(identifierArg, options, globalOpts) {
|
|
|
10490
10564
|
if (identifierArg) {
|
|
10491
10565
|
identifier = identifierArg;
|
|
10492
10566
|
} else if (isTTY()) {
|
|
10493
|
-
identifier = await executeInteractiveSelect(context, config2);
|
|
10567
|
+
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10494
10568
|
} else {
|
|
10495
10569
|
const stdinId = await readIdentifierFromStdin();
|
|
10496
10570
|
if (!stdinId) {
|
|
@@ -10520,6 +10594,22 @@ async function handleFulltextOpenAction(identifierArg, options, globalOpts) {
|
|
|
10520
10594
|
setExitCode(ExitCode.INTERNAL_ERROR);
|
|
10521
10595
|
}
|
|
10522
10596
|
}
|
|
10597
|
+
const fulltext = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
10598
|
+
__proto__: null,
|
|
10599
|
+
executeFulltextAttach,
|
|
10600
|
+
executeFulltextDetach,
|
|
10601
|
+
executeFulltextGet,
|
|
10602
|
+
executeFulltextOpen,
|
|
10603
|
+
formatFulltextAttachOutput,
|
|
10604
|
+
formatFulltextDetachOutput,
|
|
10605
|
+
formatFulltextGetOutput,
|
|
10606
|
+
formatFulltextOpenOutput,
|
|
10607
|
+
getFulltextExitCode,
|
|
10608
|
+
handleFulltextAttachAction,
|
|
10609
|
+
handleFulltextDetachAction,
|
|
10610
|
+
handleFulltextGetAction,
|
|
10611
|
+
handleFulltextOpenAction
|
|
10612
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
10523
10613
|
function formatAuthor(author) {
|
|
10524
10614
|
const family = author.family || "";
|
|
10525
10615
|
const givenInitial = author.given ? `${author.given.charAt(0)}.` : "";
|
|
@@ -10572,6 +10662,10 @@ function formatItems(items2, format2) {
|
|
|
10572
10662
|
return items2.filter(
|
|
10573
10663
|
(item) => Boolean(item.custom?.uuid)
|
|
10574
10664
|
).map((item) => item.custom.uuid);
|
|
10665
|
+
case "pandoc-key":
|
|
10666
|
+
return items2.map((item) => `@${item.id}`);
|
|
10667
|
+
case "latex-key":
|
|
10668
|
+
return items2.map((item) => `\\cite{${item.id}}`);
|
|
10575
10669
|
default:
|
|
10576
10670
|
return items2.map((item) => formatPretty([item]));
|
|
10577
10671
|
}
|
|
@@ -10610,11 +10704,14 @@ const VALID_LIST_SORT_FIELDS = /* @__PURE__ */ new Set([
|
|
|
10610
10704
|
"mod",
|
|
10611
10705
|
"pub"
|
|
10612
10706
|
]);
|
|
10613
|
-
function getOutputFormat$1(options) {
|
|
10707
|
+
function getOutputFormat$1(options, defaultKeyFormat) {
|
|
10614
10708
|
if (options.output) {
|
|
10615
10709
|
if (options.output === "ids") return "ids-only";
|
|
10616
10710
|
return options.output;
|
|
10617
10711
|
}
|
|
10712
|
+
if (options.key) return defaultKeyFormat === "latex" ? "latex-key" : "pandoc-key";
|
|
10713
|
+
if (options.pandocKey) return "pandoc-key";
|
|
10714
|
+
if (options.latexKey) return "latex-key";
|
|
10618
10715
|
if (options.json) return "json";
|
|
10619
10716
|
if (options.idsOnly) return "ids-only";
|
|
10620
10717
|
if (options.uuidOnly) return "uuid";
|
|
@@ -10622,12 +10719,18 @@ function getOutputFormat$1(options) {
|
|
|
10622
10719
|
return "pretty";
|
|
10623
10720
|
}
|
|
10624
10721
|
function validateOptions$1(options) {
|
|
10625
|
-
const outputOptions = [
|
|
10626
|
-
|
|
10627
|
-
|
|
10722
|
+
const outputOptions = [
|
|
10723
|
+
options.json,
|
|
10724
|
+
options.idsOnly,
|
|
10725
|
+
options.uuidOnly,
|
|
10726
|
+
options.bibtex,
|
|
10727
|
+
options.key,
|
|
10728
|
+
options.pandocKey,
|
|
10729
|
+
options.latexKey
|
|
10730
|
+
].filter(Boolean);
|
|
10628
10731
|
if (outputOptions.length > 1) {
|
|
10629
10732
|
throw new Error(
|
|
10630
|
-
"Multiple output formats specified. Only one of --json, --ids-only, --uuid-only, --bibtex can be used."
|
|
10733
|
+
"Multiple output formats specified. Only one of --json, --ids-only, --uuid-only, --bibtex, --key, --pandoc-key, --latex-key can be used."
|
|
10631
10734
|
);
|
|
10632
10735
|
}
|
|
10633
10736
|
if (options.output && outputOptions.length > 0) {
|
|
@@ -10662,8 +10765,8 @@ async function executeList(options, context) {
|
|
|
10662
10765
|
...pickDefined(options, ["order", "limit", "offset"])
|
|
10663
10766
|
});
|
|
10664
10767
|
}
|
|
10665
|
-
function formatListOutput(result, options) {
|
|
10666
|
-
const format2 = getOutputFormat$1(options);
|
|
10768
|
+
function formatListOutput(result, options, defaultKeyFormat) {
|
|
10769
|
+
const format2 = getOutputFormat$1(options, defaultKeyFormat);
|
|
10667
10770
|
if (format2 === "json") {
|
|
10668
10771
|
return JSON.stringify({
|
|
10669
10772
|
items: result.items,
|
|
@@ -15480,10 +15583,10 @@ const $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
15480
15583
|
inst._zod.check = (payload) => {
|
|
15481
15584
|
try {
|
|
15482
15585
|
const trimmed = payload.value.trim();
|
|
15483
|
-
const
|
|
15586
|
+
const url2 = new URL(trimmed);
|
|
15484
15587
|
if (def.hostname) {
|
|
15485
15588
|
def.hostname.lastIndex = 0;
|
|
15486
|
-
if (!def.hostname.test(
|
|
15589
|
+
if (!def.hostname.test(url2.hostname)) {
|
|
15487
15590
|
payload.issues.push({
|
|
15488
15591
|
code: "invalid_format",
|
|
15489
15592
|
format: "url",
|
|
@@ -15497,7 +15600,7 @@ const $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
15497
15600
|
}
|
|
15498
15601
|
if (def.protocol) {
|
|
15499
15602
|
def.protocol.lastIndex = 0;
|
|
15500
|
-
if (!def.protocol.test(
|
|
15603
|
+
if (!def.protocol.test(url2.protocol.endsWith(":") ? url2.protocol.slice(0, -1) : url2.protocol)) {
|
|
15501
15604
|
payload.issues.push({
|
|
15502
15605
|
code: "invalid_format",
|
|
15503
15606
|
format: "url",
|
|
@@ -15510,7 +15613,7 @@ const $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
15510
15613
|
}
|
|
15511
15614
|
}
|
|
15512
15615
|
if (def.normalize) {
|
|
15513
|
-
payload.value =
|
|
15616
|
+
payload.value = url2.href;
|
|
15514
15617
|
} else {
|
|
15515
15618
|
payload.value = trimmed;
|
|
15516
15619
|
}
|
|
@@ -31388,7 +31491,7 @@ Continue?`;
|
|
|
31388
31491
|
}
|
|
31389
31492
|
async function executeInteractiveRemove(context, config2) {
|
|
31390
31493
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
31391
|
-
const { selectReferenceItemsOrExit } = await import("./reference-select-
|
|
31494
|
+
const { selectReferenceItemsOrExit } = await import("./reference-select-DCXlkWpk.js");
|
|
31392
31495
|
const allReferences = await context.library.getAll();
|
|
31393
31496
|
const selectedItems = await withAlternateScreen2(
|
|
31394
31497
|
() => selectReferenceItemsOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -31485,6 +31588,15 @@ async function handleRemoveAction(identifierArg, options, globalOpts) {
|
|
|
31485
31588
|
handleRemoveError(error, identifierArg, outputFormat);
|
|
31486
31589
|
}
|
|
31487
31590
|
}
|
|
31591
|
+
const remove = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
31592
|
+
__proto__: null,
|
|
31593
|
+
confirmRemoveIfNeeded,
|
|
31594
|
+
executeRemove,
|
|
31595
|
+
formatFulltextWarning,
|
|
31596
|
+
formatRemoveOutput,
|
|
31597
|
+
getFulltextAttachmentTypes,
|
|
31598
|
+
handleRemoveAction
|
|
31599
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
31488
31600
|
const VALID_SEARCH_SORT_FIELDS = /* @__PURE__ */ new Set([
|
|
31489
31601
|
"created",
|
|
31490
31602
|
"updated",
|
|
@@ -31497,11 +31609,14 @@ const VALID_SEARCH_SORT_FIELDS = /* @__PURE__ */ new Set([
|
|
|
31497
31609
|
"pub",
|
|
31498
31610
|
"rel"
|
|
31499
31611
|
]);
|
|
31500
|
-
function getOutputFormat(options) {
|
|
31612
|
+
function getOutputFormat(options, defaultKeyFormat) {
|
|
31501
31613
|
if (options.output) {
|
|
31502
31614
|
if (options.output === "ids") return "ids-only";
|
|
31503
31615
|
return options.output;
|
|
31504
31616
|
}
|
|
31617
|
+
if (options.key) return defaultKeyFormat === "latex" ? "latex-key" : "pandoc-key";
|
|
31618
|
+
if (options.pandocKey) return "pandoc-key";
|
|
31619
|
+
if (options.latexKey) return "latex-key";
|
|
31505
31620
|
if (options.json) return "json";
|
|
31506
31621
|
if (options.idsOnly) return "ids-only";
|
|
31507
31622
|
if (options.uuidOnly) return "uuid";
|
|
@@ -31509,12 +31624,18 @@ function getOutputFormat(options) {
|
|
|
31509
31624
|
return "pretty";
|
|
31510
31625
|
}
|
|
31511
31626
|
function validateOptions(options) {
|
|
31512
|
-
const outputOptions = [
|
|
31513
|
-
|
|
31514
|
-
|
|
31627
|
+
const outputOptions = [
|
|
31628
|
+
options.json,
|
|
31629
|
+
options.idsOnly,
|
|
31630
|
+
options.uuidOnly,
|
|
31631
|
+
options.bibtex,
|
|
31632
|
+
options.key,
|
|
31633
|
+
options.pandocKey,
|
|
31634
|
+
options.latexKey
|
|
31635
|
+
].filter(Boolean);
|
|
31515
31636
|
if (outputOptions.length > 1) {
|
|
31516
31637
|
throw new Error(
|
|
31517
|
-
"Multiple output formats specified. Only one of --json, --ids-only, --uuid-only, --bibtex can be used."
|
|
31638
|
+
"Multiple output formats specified. Only one of --json, --ids-only, --uuid-only, --bibtex, --key, --pandoc-key, --latex-key can be used."
|
|
31518
31639
|
);
|
|
31519
31640
|
}
|
|
31520
31641
|
if (options.output && outputOptions.length > 0) {
|
|
@@ -31550,8 +31671,8 @@ async function executeSearch(options, context) {
|
|
|
31550
31671
|
...pickDefined(options, ["order", "limit", "offset"])
|
|
31551
31672
|
});
|
|
31552
31673
|
}
|
|
31553
|
-
function formatSearchOutput(result, options) {
|
|
31554
|
-
const format2 = getOutputFormat(options);
|
|
31674
|
+
function formatSearchOutput(result, options, defaultKeyFormat) {
|
|
31675
|
+
const format2 = getOutputFormat(options, defaultKeyFormat);
|
|
31555
31676
|
if (format2 === "json") {
|
|
31556
31677
|
return JSON.stringify({
|
|
31557
31678
|
items: result.items,
|
|
@@ -31580,11 +31701,14 @@ function validateInteractiveOptions(options) {
|
|
|
31580
31701
|
options.json,
|
|
31581
31702
|
options.idsOnly,
|
|
31582
31703
|
options.uuidOnly,
|
|
31583
|
-
options.bibtex
|
|
31704
|
+
options.bibtex,
|
|
31705
|
+
options.key,
|
|
31706
|
+
options.pandocKey,
|
|
31707
|
+
options.latexKey
|
|
31584
31708
|
].filter(Boolean);
|
|
31585
31709
|
if (outputOptions.length > 0) {
|
|
31586
31710
|
throw new Error(
|
|
31587
|
-
"TUI mode cannot be combined with output format options (--output, --json, --ids-only, --uuid-only, --bibtex)"
|
|
31711
|
+
"TUI mode cannot be combined with output format options (--output, --json, --ids-only, --uuid-only, --bibtex, --key, --pandoc-key, --latex-key)"
|
|
31588
31712
|
);
|
|
31589
31713
|
}
|
|
31590
31714
|
}
|
|
@@ -31592,7 +31716,7 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
31592
31716
|
validateInteractiveOptions(options);
|
|
31593
31717
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
31594
31718
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
31595
|
-
const { runSearchFlow } = await import("./index-
|
|
31719
|
+
const { runSearchFlow } = await import("./index-BB_a8Tm7.js");
|
|
31596
31720
|
const { search } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.z);
|
|
31597
31721
|
const { tokenize } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.y);
|
|
31598
31722
|
checkTTY();
|
|
@@ -31605,14 +31729,122 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
31605
31729
|
const result = await withAlternateScreen2(
|
|
31606
31730
|
() => runSearchFlow(allReferences, searchFn, {
|
|
31607
31731
|
limit: tuiConfig.limit,
|
|
31608
|
-
debounceMs: tuiConfig.debounceMs
|
|
31732
|
+
debounceMs: tuiConfig.debounceMs,
|
|
31733
|
+
defaultKeyFormat: config2.citation.defaultKeyFormat,
|
|
31734
|
+
defaultStyle: config2.citation.defaultStyle
|
|
31609
31735
|
})
|
|
31610
31736
|
);
|
|
31737
|
+
if (result.selectedItems && !result.cancelled) {
|
|
31738
|
+
const { isSideEffectAction } = await import("./action-menu-DRkjGlCc.js");
|
|
31739
|
+
if (isSideEffectAction(result.action)) {
|
|
31740
|
+
await executeSideEffectAction(result.action, result.selectedItems, context, config2);
|
|
31741
|
+
return { output: "", cancelled: false, action: result.action };
|
|
31742
|
+
}
|
|
31743
|
+
}
|
|
31611
31744
|
return {
|
|
31612
31745
|
output: result.output,
|
|
31613
|
-
cancelled: result.cancelled
|
|
31746
|
+
cancelled: result.cancelled,
|
|
31747
|
+
action: result.action
|
|
31614
31748
|
};
|
|
31615
31749
|
}
|
|
31750
|
+
async function executeSideEffectAction(action, items2, context, config2) {
|
|
31751
|
+
switch (action) {
|
|
31752
|
+
case "open-url": {
|
|
31753
|
+
const { resolveDefaultUrl: resolveDefaultUrl2 } = await Promise.resolve().then(() => url);
|
|
31754
|
+
const { openWithSystemApp: openWithSystemApp2 } = await import("./loader-BtW20O32.js").then((n) => n.j);
|
|
31755
|
+
const item = items2[0];
|
|
31756
|
+
if (!item) return;
|
|
31757
|
+
const url$1 = resolveDefaultUrl2(item);
|
|
31758
|
+
if (url$1) {
|
|
31759
|
+
await openWithSystemApp2(url$1);
|
|
31760
|
+
} else {
|
|
31761
|
+
process.stderr.write(`No URL available for ${item.id}
|
|
31762
|
+
`);
|
|
31763
|
+
}
|
|
31764
|
+
break;
|
|
31765
|
+
}
|
|
31766
|
+
case "open-fulltext": {
|
|
31767
|
+
const { executeFulltextOpen: executeFulltextOpen2 } = await Promise.resolve().then(() => fulltext);
|
|
31768
|
+
const item = items2[0];
|
|
31769
|
+
if (!item) return;
|
|
31770
|
+
const result = await executeFulltextOpen2(
|
|
31771
|
+
{
|
|
31772
|
+
identifier: item.id,
|
|
31773
|
+
fulltextDirectory: config2.attachments.directory
|
|
31774
|
+
},
|
|
31775
|
+
context
|
|
31776
|
+
);
|
|
31777
|
+
if (!result.success) {
|
|
31778
|
+
process.stderr.write(`${result.error}
|
|
31779
|
+
`);
|
|
31780
|
+
}
|
|
31781
|
+
break;
|
|
31782
|
+
}
|
|
31783
|
+
case "manage-attachments": {
|
|
31784
|
+
const { executeAttachOpen: executeAttachOpen2, runInteractiveMode: runInteractiveMode2 } = await Promise.resolve().then(() => attach);
|
|
31785
|
+
const item = items2[0];
|
|
31786
|
+
if (!item) return;
|
|
31787
|
+
const result = await executeAttachOpen2(
|
|
31788
|
+
{
|
|
31789
|
+
identifier: item.id,
|
|
31790
|
+
attachmentsDirectory: config2.attachments.directory
|
|
31791
|
+
},
|
|
31792
|
+
context
|
|
31793
|
+
);
|
|
31794
|
+
if (!result.success) {
|
|
31795
|
+
process.stderr.write(`Error: ${result.error}
|
|
31796
|
+
`);
|
|
31797
|
+
return;
|
|
31798
|
+
}
|
|
31799
|
+
await runInteractiveMode2(
|
|
31800
|
+
item.id,
|
|
31801
|
+
result.path ?? "",
|
|
31802
|
+
config2.attachments.directory,
|
|
31803
|
+
void 0,
|
|
31804
|
+
context
|
|
31805
|
+
);
|
|
31806
|
+
break;
|
|
31807
|
+
}
|
|
31808
|
+
case "edit": {
|
|
31809
|
+
const { executeEditCommand: executeEditCommand2 } = await Promise.resolve().then(() => edit);
|
|
31810
|
+
await executeEditCommand2(
|
|
31811
|
+
{
|
|
31812
|
+
identifiers: items2.map((i) => i.id),
|
|
31813
|
+
format: config2.cli.edit.defaultFormat
|
|
31814
|
+
},
|
|
31815
|
+
context
|
|
31816
|
+
);
|
|
31817
|
+
break;
|
|
31818
|
+
}
|
|
31819
|
+
case "remove": {
|
|
31820
|
+
const {
|
|
31821
|
+
executeRemove: executeRemove2,
|
|
31822
|
+
confirmRemoveIfNeeded: confirmRemoveIfNeeded2,
|
|
31823
|
+
getFulltextAttachmentTypes: getFulltextAttachmentTypes2,
|
|
31824
|
+
formatRemoveOutput: formatRemoveOutput2
|
|
31825
|
+
} = await Promise.resolve().then(() => remove);
|
|
31826
|
+
for (const item of items2) {
|
|
31827
|
+
const hasFulltext = getFulltextAttachmentTypes2(item).length > 0;
|
|
31828
|
+
const confirmed = await confirmRemoveIfNeeded2(item, hasFulltext, false);
|
|
31829
|
+
if (!confirmed) {
|
|
31830
|
+
process.stderr.write("Cancelled.\n");
|
|
31831
|
+
continue;
|
|
31832
|
+
}
|
|
31833
|
+
const result = await executeRemove2(
|
|
31834
|
+
{
|
|
31835
|
+
identifier: item.id,
|
|
31836
|
+
fulltextDirectory: config2.attachments.directory,
|
|
31837
|
+
deleteFulltext: hasFulltext
|
|
31838
|
+
},
|
|
31839
|
+
context
|
|
31840
|
+
);
|
|
31841
|
+
process.stderr.write(`${formatRemoveOutput2(result, item.id)}
|
|
31842
|
+
`);
|
|
31843
|
+
}
|
|
31844
|
+
break;
|
|
31845
|
+
}
|
|
31846
|
+
}
|
|
31847
|
+
}
|
|
31616
31848
|
async function serverStart(options) {
|
|
31617
31849
|
const existingStatus = await serverStatus(options.portfilePath);
|
|
31618
31850
|
if (existingStatus !== null) {
|
|
@@ -31906,7 +32138,7 @@ function formatUpdateOutput(result, identifier) {
|
|
|
31906
32138
|
}
|
|
31907
32139
|
async function executeInteractiveUpdate(context, config2) {
|
|
31908
32140
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
31909
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
32141
|
+
const { selectReferencesOrExit } = await import("./reference-select-DCXlkWpk.js");
|
|
31910
32142
|
const allReferences = await context.library.getAll();
|
|
31911
32143
|
const identifiers = await withAlternateScreen2(
|
|
31912
32144
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -32021,6 +32253,231 @@ async function handleUpdateAction(identifierArg, file, options, globalOpts) {
|
|
|
32021
32253
|
function collectSetOption(value, previous) {
|
|
32022
32254
|
return previous.concat([value]);
|
|
32023
32255
|
}
|
|
32256
|
+
function buildDoiUrl(doi) {
|
|
32257
|
+
return `https://doi.org/${doi}`;
|
|
32258
|
+
}
|
|
32259
|
+
function buildPubmedUrl(pmid) {
|
|
32260
|
+
return `https://pubmed.ncbi.nlm.nih.gov/${pmid}/`;
|
|
32261
|
+
}
|
|
32262
|
+
function buildPmcUrl(pmcid) {
|
|
32263
|
+
return `https://www.ncbi.nlm.nih.gov/pmc/articles/${pmcid}/`;
|
|
32264
|
+
}
|
|
32265
|
+
function resolveAllUrls(item) {
|
|
32266
|
+
const urls = [];
|
|
32267
|
+
if (item.DOI) {
|
|
32268
|
+
urls.push(buildDoiUrl(item.DOI));
|
|
32269
|
+
}
|
|
32270
|
+
if (item.URL) {
|
|
32271
|
+
urls.push(item.URL);
|
|
32272
|
+
}
|
|
32273
|
+
if (item.PMID) {
|
|
32274
|
+
urls.push(buildPubmedUrl(item.PMID));
|
|
32275
|
+
}
|
|
32276
|
+
if (item.PMCID) {
|
|
32277
|
+
urls.push(buildPmcUrl(item.PMCID));
|
|
32278
|
+
}
|
|
32279
|
+
const additionalUrls = item.custom?.additional_urls;
|
|
32280
|
+
if (additionalUrls && additionalUrls.length > 0) {
|
|
32281
|
+
urls.push(...additionalUrls);
|
|
32282
|
+
}
|
|
32283
|
+
return urls;
|
|
32284
|
+
}
|
|
32285
|
+
function resolveDefaultUrl(item) {
|
|
32286
|
+
if (item.DOI) {
|
|
32287
|
+
return buildDoiUrl(item.DOI);
|
|
32288
|
+
}
|
|
32289
|
+
if (item.URL) {
|
|
32290
|
+
return item.URL;
|
|
32291
|
+
}
|
|
32292
|
+
if (item.PMID) {
|
|
32293
|
+
return buildPubmedUrl(item.PMID);
|
|
32294
|
+
}
|
|
32295
|
+
if (item.PMCID) {
|
|
32296
|
+
return buildPmcUrl(item.PMCID);
|
|
32297
|
+
}
|
|
32298
|
+
const additionalUrls = item.custom?.additional_urls;
|
|
32299
|
+
if (additionalUrls && additionalUrls.length > 0) {
|
|
32300
|
+
return additionalUrls[0] ?? null;
|
|
32301
|
+
}
|
|
32302
|
+
return null;
|
|
32303
|
+
}
|
|
32304
|
+
function resolveUrlByType(item, type2) {
|
|
32305
|
+
switch (type2) {
|
|
32306
|
+
case "doi":
|
|
32307
|
+
return item.DOI ? buildDoiUrl(item.DOI) : null;
|
|
32308
|
+
case "url":
|
|
32309
|
+
return item.URL ?? null;
|
|
32310
|
+
case "pubmed":
|
|
32311
|
+
return item.PMID ? buildPubmedUrl(item.PMID) : null;
|
|
32312
|
+
case "pmcid":
|
|
32313
|
+
return item.PMCID ? buildPmcUrl(item.PMCID) : null;
|
|
32314
|
+
}
|
|
32315
|
+
}
|
|
32316
|
+
const url = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
32317
|
+
__proto__: null,
|
|
32318
|
+
resolveAllUrls,
|
|
32319
|
+
resolveDefaultUrl,
|
|
32320
|
+
resolveUrlByType
|
|
32321
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
32322
|
+
function getUrlTypeFilter(options) {
|
|
32323
|
+
if (options.doi) return "doi";
|
|
32324
|
+
if (options.pubmed) return "pubmed";
|
|
32325
|
+
if (options.pmcid) return "pmcid";
|
|
32326
|
+
if (options.default) return "default";
|
|
32327
|
+
if (options.open) return "default";
|
|
32328
|
+
return null;
|
|
32329
|
+
}
|
|
32330
|
+
function getFilterLabel(filter) {
|
|
32331
|
+
switch (filter) {
|
|
32332
|
+
case "doi":
|
|
32333
|
+
return "DOI";
|
|
32334
|
+
case "pubmed":
|
|
32335
|
+
return "PubMed";
|
|
32336
|
+
case "pmcid":
|
|
32337
|
+
return "PMC";
|
|
32338
|
+
case "url":
|
|
32339
|
+
return "URL";
|
|
32340
|
+
case "default":
|
|
32341
|
+
return "default";
|
|
32342
|
+
}
|
|
32343
|
+
}
|
|
32344
|
+
function resolveUrlsForItem(item, id2, filter) {
|
|
32345
|
+
if (filter === null) {
|
|
32346
|
+
const urls = resolveAllUrls(item);
|
|
32347
|
+
if (urls.length === 0) {
|
|
32348
|
+
return { id: id2, urls: [], error: `No URLs available for ${id2}` };
|
|
32349
|
+
}
|
|
32350
|
+
return { id: id2, urls };
|
|
32351
|
+
}
|
|
32352
|
+
if (filter === "default") {
|
|
32353
|
+
const url22 = resolveDefaultUrl(item);
|
|
32354
|
+
if (!url22) {
|
|
32355
|
+
return { id: id2, urls: [], error: `No URLs available for ${id2}` };
|
|
32356
|
+
}
|
|
32357
|
+
return { id: id2, urls: [url22] };
|
|
32358
|
+
}
|
|
32359
|
+
const url2 = resolveUrlByType(item, filter);
|
|
32360
|
+
if (!url2) {
|
|
32361
|
+
return { id: id2, urls: [], error: `No ${getFilterLabel(filter)} URL for ${id2}` };
|
|
32362
|
+
}
|
|
32363
|
+
return { id: id2, urls: [url2] };
|
|
32364
|
+
}
|
|
32365
|
+
async function executeUrlCommand(identifiers, options, context) {
|
|
32366
|
+
const filter = getUrlTypeFilter(options);
|
|
32367
|
+
const findOptions = options.uuid ? { idType: "uuid" } : void 0;
|
|
32368
|
+
const results = [];
|
|
32369
|
+
for (const identifier of identifiers) {
|
|
32370
|
+
const item = await context.library.find(identifier, findOptions);
|
|
32371
|
+
if (!item) {
|
|
32372
|
+
results.push({ id: identifier, urls: [], error: `Reference not found: ${identifier}` });
|
|
32373
|
+
continue;
|
|
32374
|
+
}
|
|
32375
|
+
const result = resolveUrlsForItem(item, identifier, filter);
|
|
32376
|
+
results.push(result);
|
|
32377
|
+
}
|
|
32378
|
+
if (options.open) {
|
|
32379
|
+
const firstSuccess = results.find((r) => r.urls.length > 0);
|
|
32380
|
+
if (firstSuccess?.urls[0]) {
|
|
32381
|
+
try {
|
|
32382
|
+
await openWithSystemApp(firstSuccess.urls[0]);
|
|
32383
|
+
} catch (error) {
|
|
32384
|
+
return {
|
|
32385
|
+
results,
|
|
32386
|
+
openError: `Failed to open URL: ${error instanceof Error ? error.message : String(error)}`
|
|
32387
|
+
};
|
|
32388
|
+
}
|
|
32389
|
+
}
|
|
32390
|
+
}
|
|
32391
|
+
return { results };
|
|
32392
|
+
}
|
|
32393
|
+
function hasFilter(options) {
|
|
32394
|
+
return Boolean(options.default || options.doi || options.pubmed || options.pmcid || options.open);
|
|
32395
|
+
}
|
|
32396
|
+
function formatUrlOutput(result, options) {
|
|
32397
|
+
const successResults = result.results.filter((r) => r.urls.length > 0);
|
|
32398
|
+
if (successResults.length === 0) {
|
|
32399
|
+
return "";
|
|
32400
|
+
}
|
|
32401
|
+
const filtered = hasFilter(options);
|
|
32402
|
+
if (filtered || successResults.length === 1) {
|
|
32403
|
+
const lines2 = [];
|
|
32404
|
+
for (const r of successResults) {
|
|
32405
|
+
for (const url2 of r.urls) {
|
|
32406
|
+
lines2.push(url2);
|
|
32407
|
+
}
|
|
32408
|
+
}
|
|
32409
|
+
return lines2.join("\n");
|
|
32410
|
+
}
|
|
32411
|
+
const lines = [];
|
|
32412
|
+
for (const r of successResults) {
|
|
32413
|
+
for (const url2 of r.urls) {
|
|
32414
|
+
lines.push(`${r.id} ${url2}`);
|
|
32415
|
+
}
|
|
32416
|
+
}
|
|
32417
|
+
return lines.join("\n");
|
|
32418
|
+
}
|
|
32419
|
+
function formatUrlErrors(result) {
|
|
32420
|
+
const errorMessages = result.results.filter((r) => r.error).map((r) => `Error: ${r.error}`);
|
|
32421
|
+
if (result.openError) {
|
|
32422
|
+
errorMessages.push(`Error: ${result.openError}`);
|
|
32423
|
+
}
|
|
32424
|
+
return errorMessages.join("\n");
|
|
32425
|
+
}
|
|
32426
|
+
function getUrlExitCode(result) {
|
|
32427
|
+
if (result.openError) return ExitCode.ERROR;
|
|
32428
|
+
const hasSuccess = result.results.some((r) => r.urls.length > 0);
|
|
32429
|
+
const hasError = result.results.some((r) => r.error);
|
|
32430
|
+
if (hasSuccess) return ExitCode.SUCCESS;
|
|
32431
|
+
if (hasError) return ExitCode.ERROR;
|
|
32432
|
+
return ExitCode.SUCCESS;
|
|
32433
|
+
}
|
|
32434
|
+
async function executeInteractiveSelect(context, config2) {
|
|
32435
|
+
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32436
|
+
const { selectReferencesOrExit } = await import("./reference-select-DCXlkWpk.js");
|
|
32437
|
+
const allReferences = await context.library.getAll();
|
|
32438
|
+
const identifiers = await withAlternateScreen2(
|
|
32439
|
+
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
32440
|
+
);
|
|
32441
|
+
return identifiers[0] ?? "";
|
|
32442
|
+
}
|
|
32443
|
+
async function handleUrlAction(identifiers, options, globalOpts) {
|
|
32444
|
+
try {
|
|
32445
|
+
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
32446
|
+
const context = await createExecutionContext(config2, Library.load);
|
|
32447
|
+
let resolvedIdentifiers;
|
|
32448
|
+
let isTuiMode = false;
|
|
32449
|
+
if (identifiers && identifiers.length > 0) {
|
|
32450
|
+
resolvedIdentifiers = identifiers;
|
|
32451
|
+
} else if (isTTY()) {
|
|
32452
|
+
isTuiMode = true;
|
|
32453
|
+
const selected = await executeInteractiveSelect(context, config2);
|
|
32454
|
+
resolvedIdentifiers = [selected];
|
|
32455
|
+
} else {
|
|
32456
|
+
const stdinId = await readIdentifierFromStdin();
|
|
32457
|
+
if (!stdinId) {
|
|
32458
|
+
exitWithError("Identifier is required");
|
|
32459
|
+
return;
|
|
32460
|
+
}
|
|
32461
|
+
resolvedIdentifiers = [stdinId];
|
|
32462
|
+
}
|
|
32463
|
+
const result = await executeUrlCommand(resolvedIdentifiers, options, context);
|
|
32464
|
+
const output = formatUrlOutput(result, options);
|
|
32465
|
+
if (output) {
|
|
32466
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, isTuiMode);
|
|
32467
|
+
await writeOutputWithClipboard(output, clipboardEnabled, config2.logLevel === "silent");
|
|
32468
|
+
}
|
|
32469
|
+
const errors2 = formatUrlErrors(result);
|
|
32470
|
+
if (errors2) {
|
|
32471
|
+
process.stderr.write(`${errors2}
|
|
32472
|
+
`);
|
|
32473
|
+
}
|
|
32474
|
+
setExitCode(getUrlExitCode(result));
|
|
32475
|
+
} catch (error) {
|
|
32476
|
+
process.stderr.write(`Error: ${error instanceof Error ? error.message : String(error)}
|
|
32477
|
+
`);
|
|
32478
|
+
setExitCode(ExitCode.INTERNAL_ERROR);
|
|
32479
|
+
}
|
|
32480
|
+
}
|
|
32024
32481
|
const SEARCH_SORT_FIELDS = searchSortFieldSchema.options;
|
|
32025
32482
|
const SORT_ORDERS = sortOrderSchema.options;
|
|
32026
32483
|
const CITATION_OUTPUT_FORMATS = ["text", "html", "rtf"];
|
|
@@ -32305,7 +32762,7 @@ function registerCompletionCommand(program) {
|
|
|
32305
32762
|
function createProgram() {
|
|
32306
32763
|
const program = new Command();
|
|
32307
32764
|
program.name("reference-manager").version(packageJson.version).description(packageJson.description);
|
|
32308
|
-
program.option("--library <path>", "Override library file path").option("--log-level <level>", "Override log level (silent|info|debug)").option("--config <path>", "Use specific config file").option("--quiet", "Suppress all non-error output").option("--verbose", "Enable verbose output").option("--no-backup", "Disable backup creation").option("--backup-dir <path>", "Override backup directory").option("--attachments-dir <path>", "Override attachments directory");
|
|
32765
|
+
program.option("--library <path>", "Override library file path").option("--log-level <level>", "Override log level (silent|info|debug)").option("--config <path>", "Use specific config file").option("--quiet", "Suppress all non-error output").option("--verbose", "Enable verbose output").option("--no-backup", "Disable backup creation").option("--backup-dir <path>", "Override backup directory").option("--attachments-dir <path>", "Override attachments directory").option("--clipboard", "Copy output to system clipboard").option("--no-clipboard", "Disable clipboard copy");
|
|
32309
32766
|
registerListCommand(program);
|
|
32310
32767
|
registerSearchCommand(program);
|
|
32311
32768
|
registerExportCommand(program);
|
|
@@ -32318,6 +32775,7 @@ function createProgram() {
|
|
|
32318
32775
|
registerFulltextCommand(program);
|
|
32319
32776
|
registerAttachCommand(program);
|
|
32320
32777
|
registerMcpCommand(program);
|
|
32778
|
+
registerUrlCommand(program);
|
|
32321
32779
|
registerConfigCommand(program);
|
|
32322
32780
|
registerCompletionCommand(program);
|
|
32323
32781
|
return program;
|
|
@@ -32326,12 +32784,12 @@ async function handleListAction(options, program) {
|
|
|
32326
32784
|
try {
|
|
32327
32785
|
const globalOpts = program.opts();
|
|
32328
32786
|
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
32787
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, false);
|
|
32329
32788
|
const context = await createExecutionContext(config2, Library.load);
|
|
32330
32789
|
const result = await executeList(options, context);
|
|
32331
|
-
const output = formatListOutput(result, options);
|
|
32790
|
+
const output = formatListOutput(result, options, config2.citation.defaultKeyFormat);
|
|
32332
32791
|
if (output) {
|
|
32333
|
-
|
|
32334
|
-
`);
|
|
32792
|
+
await writeOutputWithClipboard(output, clipboardEnabled, config2.logLevel === "silent");
|
|
32335
32793
|
}
|
|
32336
32794
|
setExitCode(ExitCode.SUCCESS);
|
|
32337
32795
|
} catch (error) {
|
|
@@ -32339,7 +32797,10 @@ async function handleListAction(options, program) {
|
|
|
32339
32797
|
}
|
|
32340
32798
|
}
|
|
32341
32799
|
function registerListCommand(program) {
|
|
32342
|
-
program.command("list").description("List all references in the library").option(
|
|
32800
|
+
program.command("list").description("List all references in the library").option(
|
|
32801
|
+
"-o, --output <format>",
|
|
32802
|
+
"Output format: pretty|json|bibtex|ids|uuid|pandoc-key|latex-key"
|
|
32803
|
+
).option("--json", "Alias for --output json").option("--bibtex", "Alias for --output bibtex").option("--ids-only", "Alias for --output ids").option("--uuid-only", "Alias for --output uuid").option("-k, --key", "Output citation keys (uses citation.default_key_format config)").option("--pandoc-key", "Alias for --output pandoc-key").option("--latex-key", "Alias for --output latex-key").option("--sort <field>", "Sort by field: created|updated|published|author|title").option("--order <order>", "Sort order: asc|desc").option("-n, --limit <n>", "Maximum number of results", Number.parseInt).option("--offset <n>", "Number of results to skip", Number.parseInt).action(async (options) => {
|
|
32343
32804
|
await handleListAction(options, program);
|
|
32344
32805
|
});
|
|
32345
32806
|
}
|
|
@@ -32347,12 +32808,12 @@ async function handleExportAction(ids, options, program) {
|
|
|
32347
32808
|
try {
|
|
32348
32809
|
const globalOpts = program.opts();
|
|
32349
32810
|
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
32811
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, false);
|
|
32350
32812
|
const context = await createExecutionContext(config2, Library.load);
|
|
32351
32813
|
const result = await executeExport({ ...options, ids }, context);
|
|
32352
32814
|
const output = formatExportOutput(result, { ...options, ids });
|
|
32353
32815
|
if (output) {
|
|
32354
|
-
|
|
32355
|
-
`);
|
|
32816
|
+
await writeOutputWithClipboard(output, clipboardEnabled, config2.logLevel === "silent");
|
|
32356
32817
|
}
|
|
32357
32818
|
if (result.notFound.length > 0) {
|
|
32358
32819
|
for (const id2 of result.notFound) {
|
|
@@ -32380,17 +32841,25 @@ async function handleSearchAction(query, options, program) {
|
|
|
32380
32841
|
if (options.tui) {
|
|
32381
32842
|
const result2 = await executeInteractiveSearch({ ...options, query }, context, config2);
|
|
32382
32843
|
if (result2.output) {
|
|
32383
|
-
|
|
32384
|
-
|
|
32844
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, true);
|
|
32845
|
+
await writeOutputWithClipboard(
|
|
32846
|
+
result2.output,
|
|
32847
|
+
clipboardEnabled,
|
|
32848
|
+
config2.logLevel === "silent"
|
|
32849
|
+
);
|
|
32385
32850
|
}
|
|
32386
32851
|
setExitCode(ExitCode.SUCCESS);
|
|
32387
32852
|
return;
|
|
32388
32853
|
}
|
|
32389
32854
|
const result = await executeSearch({ ...options, query }, context);
|
|
32390
|
-
const output = formatSearchOutput(
|
|
32855
|
+
const output = formatSearchOutput(
|
|
32856
|
+
result,
|
|
32857
|
+
{ ...options, query },
|
|
32858
|
+
config2.citation.defaultKeyFormat
|
|
32859
|
+
);
|
|
32391
32860
|
if (output) {
|
|
32392
|
-
|
|
32393
|
-
|
|
32861
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, false);
|
|
32862
|
+
await writeOutputWithClipboard(output, clipboardEnabled, config2.logLevel === "silent");
|
|
32394
32863
|
}
|
|
32395
32864
|
setExitCode(ExitCode.SUCCESS);
|
|
32396
32865
|
} catch (error) {
|
|
@@ -32400,7 +32869,10 @@ async function handleSearchAction(query, options, program) {
|
|
|
32400
32869
|
}
|
|
32401
32870
|
}
|
|
32402
32871
|
function registerSearchCommand(program) {
|
|
32403
|
-
program.command("search").description("Search references").argument("[query]", "Search query (required unless using --tui)").option("-t, --tui", "Enable TUI (interactive) search mode").option(
|
|
32872
|
+
program.command("search").description("Search references").argument("[query]", "Search query (required unless using --tui)").option("-t, --tui", "Enable TUI (interactive) search mode").option(
|
|
32873
|
+
"-o, --output <format>",
|
|
32874
|
+
"Output format: pretty|json|bibtex|ids|uuid|pandoc-key|latex-key"
|
|
32875
|
+
).option("--json", "Alias for --output json").option("--bibtex", "Alias for --output bibtex").option("--ids-only", "Alias for --output ids").option("--uuid-only", "Alias for --output uuid").option("-k, --key", "Output citation keys (uses citation.default_key_format config)").option("--pandoc-key", "Alias for --output pandoc-key").option("--latex-key", "Alias for --output latex-key").option("--sort <field>", "Sort by field: created|updated|published|author|title|relevance").option("--order <order>", "Sort order: asc|desc").option("-n, --limit <n>", "Maximum number of results", Number.parseInt).option("--offset <n>", "Number of results to skip", Number.parseInt).action(async (query, options) => {
|
|
32404
32876
|
if (!options.tui && !query) {
|
|
32405
32877
|
process.stderr.write("Error: Search query is required unless using --tui\n");
|
|
32406
32878
|
setExitCode(ExitCode.ERROR);
|
|
@@ -32616,6 +33088,9 @@ function registerMcpCommand(program) {
|
|
|
32616
33088
|
}
|
|
32617
33089
|
function registerAttachCommand(program) {
|
|
32618
33090
|
const attachCmd = program.command("attach").description("Manage file attachments for references");
|
|
33091
|
+
attachCmd.argument("[identifier]", "Citation key or UUID (interactive selection if omitted)").option("--uuid", "Interpret identifier as UUID").action(async (identifier, options) => {
|
|
33092
|
+
await handleAttachOpenAction(identifier, void 0, options, program.opts());
|
|
33093
|
+
});
|
|
32619
33094
|
attachCmd.command("open").description("Open attachments directory or specific file").argument("[identifier]", "Citation key or UUID (interactive selection if omitted)").argument("[filename]", "Specific file to open").option("--role <role>", "Open file by role").option("--print", "Output path instead of opening").option("--no-sync", "Skip interactive sync prompt").option("--uuid", "Interpret identifier as UUID").action(async (identifier, filename, options) => {
|
|
32620
33095
|
await handleAttachOpenAction(identifier, filename, options, program.opts());
|
|
32621
33096
|
});
|
|
@@ -32653,6 +33128,12 @@ function registerFulltextCommand(program) {
|
|
|
32653
33128
|
await handleFulltextOpenAction(identifier, options, program.opts());
|
|
32654
33129
|
});
|
|
32655
33130
|
}
|
|
33131
|
+
function registerUrlCommand(program) {
|
|
33132
|
+
program.command("url").description("Show URLs for references").argument("[identifiers...]", "Reference identifiers").option("--default", "Show only the best URL by priority").option("--doi", "Show only DOI URL").option("--pubmed", "Show only PubMed URL").option("--pmcid", "Show only PMC URL").option("--open", "Open URL in browser").option("--uuid", "Interpret identifiers as UUIDs").action(async (identifiers, options) => {
|
|
33133
|
+
const globalOpts = program.opts();
|
|
33134
|
+
await handleUrlAction(identifiers.length > 0 ? identifiers : void 0, options, globalOpts);
|
|
33135
|
+
});
|
|
33136
|
+
}
|
|
32656
33137
|
async function main(argv) {
|
|
32657
33138
|
const program = createProgram();
|
|
32658
33139
|
if (process.env.COMP_LINE) {
|
|
@@ -32670,6 +33151,7 @@ async function main(argv) {
|
|
|
32670
33151
|
export {
|
|
32671
33152
|
Select as S,
|
|
32672
33153
|
addAttachment as a,
|
|
33154
|
+
stringify as b,
|
|
32673
33155
|
createProgram as c,
|
|
32674
33156
|
detachAttachment as d,
|
|
32675
33157
|
formatBibtex as f,
|
|
@@ -32681,4 +33163,4 @@ export {
|
|
|
32681
33163
|
restoreStdinAfterInk as r,
|
|
32682
33164
|
syncAttachments as s
|
|
32683
33165
|
};
|
|
32684
|
-
//# sourceMappingURL=index-
|
|
33166
|
+
//# sourceMappingURL=index-vInTzmDN.js.map
|