@ncukondo/reference-manager 0.17.1 → 0.18.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/dist/chunks/action-menu-D8gSe1YM.js +87 -0
- package/dist/chunks/action-menu-D8gSe1YM.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-B52BI__9.js} +2 -2
- package/dist/chunks/{format-ByjxlVm5.js.map → format-B52BI__9.js.map} +1 -1
- package/dist/chunks/{index-BigPRCTh.js → index-B5W5srUa.js} +50 -38
- package/dist/chunks/index-B5W5srUa.js.map +1 -0
- package/dist/chunks/{index-wb8zgPJ0.js → index-BPhIwqHO.js} +561 -92
- package/dist/chunks/index-BPhIwqHO.js.map +1 -0
- package/dist/chunks/{index-DWEWWvFO.js → index-iYPq6D80.js} +2 -2
- package/dist/chunks/index-iYPq6D80.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-DcClzkw2.js} +3 -3
- package/dist/chunks/{reference-select-O0PY7CRU.js.map → reference-select-DcClzkw2.js.map} +1 -1
- package/dist/chunks/{style-select-DF5kX4G6.js → style-select-D0bgalgW.js} +2 -2
- package/dist/chunks/{style-select-DF5kX4G6.js.map → style-select-D0bgalgW.js.map} +1 -1
- 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.0";
|
|
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-iYPq6D80.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-iYPq6D80.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-iYPq6D80.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-iYPq6D80.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-iYPq6D80.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-iYPq6D80.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-DcClzkw2.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,27 @@ 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
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
2083
2136
|
async function validateOptions$2(options) {
|
|
2084
2137
|
if (options.output && !["text", "html", "rtf"].includes(options.output)) {
|
|
2085
2138
|
throw new Error(`Invalid output format '${options.output}'. Must be one of: text, html, rtf`);
|
|
@@ -2137,8 +2190,8 @@ function getCiteExitCode(result) {
|
|
|
2137
2190
|
}
|
|
2138
2191
|
async function executeInteractiveCite(options, context, config2) {
|
|
2139
2192
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
2140
|
-
const { runCiteFlow } = await import("./index-
|
|
2141
|
-
const { buildStyleChoices, listCustomStyles } = await import("./style-select-
|
|
2193
|
+
const { runCiteFlow } = await import("./index-B5W5srUa.js");
|
|
2194
|
+
const { buildStyleChoices, listCustomStyles } = await import("./style-select-D0bgalgW.js");
|
|
2142
2195
|
const { search } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.z);
|
|
2143
2196
|
const { tokenize } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.y);
|
|
2144
2197
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
@@ -2180,8 +2233,10 @@ async function handleCiteAction(identifiers, options, globalOpts) {
|
|
|
2180
2233
|
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
2181
2234
|
const context = await createExecutionContext(config2, Library.load);
|
|
2182
2235
|
let result;
|
|
2236
|
+
let isTuiMode = false;
|
|
2183
2237
|
if (identifiers.length === 0) {
|
|
2184
2238
|
if (isTTY()) {
|
|
2239
|
+
isTuiMode = true;
|
|
2185
2240
|
result = await executeInteractiveCite(options, context, config2);
|
|
2186
2241
|
} else {
|
|
2187
2242
|
const stdinIds = await readIdentifiersFromStdin();
|
|
@@ -2199,8 +2254,8 @@ async function handleCiteAction(identifiers, options, globalOpts) {
|
|
|
2199
2254
|
}
|
|
2200
2255
|
const output = formatCiteOutput(result);
|
|
2201
2256
|
if (output) {
|
|
2202
|
-
|
|
2203
|
-
|
|
2257
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, isTuiMode);
|
|
2258
|
+
await writeOutputWithClipboard(output, clipboardEnabled, config2.logLevel === "silent");
|
|
2204
2259
|
}
|
|
2205
2260
|
const errors2 = formatCiteErrors(result);
|
|
2206
2261
|
if (errors2) {
|
|
@@ -2219,6 +2274,7 @@ const ENV_OVERRIDE_MAP = {
|
|
|
2219
2274
|
REFERENCE_MANAGER_ATTACHMENTS_DIR: "attachments.directory",
|
|
2220
2275
|
REFERENCE_MANAGER_CLI_DEFAULT_LIMIT: "cli.default_limit",
|
|
2221
2276
|
REFERENCE_MANAGER_MCP_DEFAULT_LIMIT: "mcp.default_limit",
|
|
2277
|
+
REFERENCE_MANAGER_CLIPBOARD_AUTO_COPY: "cli.tui.clipboard_auto_copy",
|
|
2222
2278
|
PUBMED_EMAIL: "pubmed.email",
|
|
2223
2279
|
PUBMED_API_KEY: "pubmed.api_key"
|
|
2224
2280
|
};
|
|
@@ -2275,6 +2331,12 @@ const CONFIG_KEY_REGISTRY = [
|
|
|
2275
2331
|
description: "Default format",
|
|
2276
2332
|
enumValues: ["text", "html", "rtf"]
|
|
2277
2333
|
},
|
|
2334
|
+
{
|
|
2335
|
+
key: "citation.default_key_format",
|
|
2336
|
+
type: "enum",
|
|
2337
|
+
description: "Default citation key format",
|
|
2338
|
+
enumValues: ["pandoc", "latex"]
|
|
2339
|
+
},
|
|
2278
2340
|
// pubmed section
|
|
2279
2341
|
{ key: "pubmed.email", type: "string", description: "Email for PubMed API", optional: true },
|
|
2280
2342
|
{ key: "pubmed.api_key", type: "string", description: "API key for PubMed", optional: true },
|
|
@@ -2309,6 +2371,11 @@ const CONFIG_KEY_REGISTRY = [
|
|
|
2309
2371
|
type: "integer",
|
|
2310
2372
|
description: "Search debounce delay (ms)"
|
|
2311
2373
|
},
|
|
2374
|
+
{
|
|
2375
|
+
key: "cli.tui.clipboard_auto_copy",
|
|
2376
|
+
type: "boolean",
|
|
2377
|
+
description: "Auto-copy TUI output to clipboard"
|
|
2378
|
+
},
|
|
2312
2379
|
// cli.edit section
|
|
2313
2380
|
{
|
|
2314
2381
|
key: "cli.edit.default_format",
|
|
@@ -6681,7 +6748,7 @@ function formatEditOutput(result) {
|
|
|
6681
6748
|
}
|
|
6682
6749
|
async function executeInteractiveEdit(options, context, config2) {
|
|
6683
6750
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
6684
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
6751
|
+
const { selectReferencesOrExit } = await import("./reference-select-DcClzkw2.js");
|
|
6685
6752
|
const allReferences = await context.library.getAll();
|
|
6686
6753
|
const identifiers = await withAlternateScreen2(
|
|
6687
6754
|
() => selectReferencesOrExit(allReferences, { multiSelect: true }, config2.cli.tui)
|
|
@@ -6747,6 +6814,12 @@ async function handleEditAction(identifiers, options, globalOpts) {
|
|
|
6747
6814
|
setExitCode(ExitCode.INTERNAL_ERROR);
|
|
6748
6815
|
}
|
|
6749
6816
|
}
|
|
6817
|
+
const edit = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
6818
|
+
__proto__: null,
|
|
6819
|
+
executeEditCommand,
|
|
6820
|
+
formatEditOutput,
|
|
6821
|
+
handleEditAction
|
|
6822
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
6750
6823
|
const ALIAS = Symbol.for("yaml.alias");
|
|
6751
6824
|
const DOC = Symbol.for("yaml.document");
|
|
6752
6825
|
const MAP = Symbol.for("yaml.map");
|
|
@@ -10327,9 +10400,9 @@ function formatFulltextOpenOutput(result) {
|
|
|
10327
10400
|
function getFulltextExitCode(result) {
|
|
10328
10401
|
return result.success ? 0 : 1;
|
|
10329
10402
|
}
|
|
10330
|
-
async function executeInteractiveSelect(context, config2) {
|
|
10403
|
+
async function executeInteractiveSelect$1(context, config2) {
|
|
10331
10404
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
10332
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
10405
|
+
const { selectReferencesOrExit } = await import("./reference-select-DcClzkw2.js");
|
|
10333
10406
|
const allReferences = await context.library.getAll();
|
|
10334
10407
|
const identifiers = await withAlternateScreen2(
|
|
10335
10408
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -10366,7 +10439,7 @@ async function handleFulltextAttachAction(identifierArg, filePathArg, options, g
|
|
|
10366
10439
|
setExitCode(ExitCode.ERROR);
|
|
10367
10440
|
return;
|
|
10368
10441
|
}
|
|
10369
|
-
identifier = await executeInteractiveSelect(context, config2);
|
|
10442
|
+
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10370
10443
|
}
|
|
10371
10444
|
const { type: type2, filePath } = parseFulltextAttachTypeAndPath(filePathArg, options);
|
|
10372
10445
|
const stdinContent = !filePath && type2 ? await readStdinBuffer() : void 0;
|
|
@@ -10413,7 +10486,7 @@ async function handleFulltextGetAction(identifierArg, options, globalOpts) {
|
|
|
10413
10486
|
if (identifierArg) {
|
|
10414
10487
|
identifier = identifierArg;
|
|
10415
10488
|
} else if (isTTY()) {
|
|
10416
|
-
identifier = await executeInteractiveSelect(context, config2);
|
|
10489
|
+
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10417
10490
|
} else {
|
|
10418
10491
|
const stdinId = await readIdentifierFromStdin();
|
|
10419
10492
|
if (!stdinId) {
|
|
@@ -10450,7 +10523,7 @@ async function handleFulltextDetachAction(identifierArg, options, globalOpts) {
|
|
|
10450
10523
|
if (identifierArg) {
|
|
10451
10524
|
identifier = identifierArg;
|
|
10452
10525
|
} else if (isTTY()) {
|
|
10453
|
-
identifier = await executeInteractiveSelect(context, config2);
|
|
10526
|
+
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10454
10527
|
} else {
|
|
10455
10528
|
const stdinId = await readIdentifierFromStdin();
|
|
10456
10529
|
if (!stdinId) {
|
|
@@ -10490,7 +10563,7 @@ async function handleFulltextOpenAction(identifierArg, options, globalOpts) {
|
|
|
10490
10563
|
if (identifierArg) {
|
|
10491
10564
|
identifier = identifierArg;
|
|
10492
10565
|
} else if (isTTY()) {
|
|
10493
|
-
identifier = await executeInteractiveSelect(context, config2);
|
|
10566
|
+
identifier = await executeInteractiveSelect$1(context, config2);
|
|
10494
10567
|
} else {
|
|
10495
10568
|
const stdinId = await readIdentifierFromStdin();
|
|
10496
10569
|
if (!stdinId) {
|
|
@@ -10520,6 +10593,22 @@ async function handleFulltextOpenAction(identifierArg, options, globalOpts) {
|
|
|
10520
10593
|
setExitCode(ExitCode.INTERNAL_ERROR);
|
|
10521
10594
|
}
|
|
10522
10595
|
}
|
|
10596
|
+
const fulltext = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
10597
|
+
__proto__: null,
|
|
10598
|
+
executeFulltextAttach,
|
|
10599
|
+
executeFulltextDetach,
|
|
10600
|
+
executeFulltextGet,
|
|
10601
|
+
executeFulltextOpen,
|
|
10602
|
+
formatFulltextAttachOutput,
|
|
10603
|
+
formatFulltextDetachOutput,
|
|
10604
|
+
formatFulltextGetOutput,
|
|
10605
|
+
formatFulltextOpenOutput,
|
|
10606
|
+
getFulltextExitCode,
|
|
10607
|
+
handleFulltextAttachAction,
|
|
10608
|
+
handleFulltextDetachAction,
|
|
10609
|
+
handleFulltextGetAction,
|
|
10610
|
+
handleFulltextOpenAction
|
|
10611
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
10523
10612
|
function formatAuthor(author) {
|
|
10524
10613
|
const family = author.family || "";
|
|
10525
10614
|
const givenInitial = author.given ? `${author.given.charAt(0)}.` : "";
|
|
@@ -10572,6 +10661,10 @@ function formatItems(items2, format2) {
|
|
|
10572
10661
|
return items2.filter(
|
|
10573
10662
|
(item) => Boolean(item.custom?.uuid)
|
|
10574
10663
|
).map((item) => item.custom.uuid);
|
|
10664
|
+
case "pandoc-key":
|
|
10665
|
+
return items2.map((item) => `@${item.id}`);
|
|
10666
|
+
case "latex-key":
|
|
10667
|
+
return items2.map((item) => `\\cite{${item.id}}`);
|
|
10575
10668
|
default:
|
|
10576
10669
|
return items2.map((item) => formatPretty([item]));
|
|
10577
10670
|
}
|
|
@@ -10610,11 +10703,14 @@ const VALID_LIST_SORT_FIELDS = /* @__PURE__ */ new Set([
|
|
|
10610
10703
|
"mod",
|
|
10611
10704
|
"pub"
|
|
10612
10705
|
]);
|
|
10613
|
-
function getOutputFormat$1(options) {
|
|
10706
|
+
function getOutputFormat$1(options, defaultKeyFormat) {
|
|
10614
10707
|
if (options.output) {
|
|
10615
10708
|
if (options.output === "ids") return "ids-only";
|
|
10616
10709
|
return options.output;
|
|
10617
10710
|
}
|
|
10711
|
+
if (options.key) return defaultKeyFormat === "latex" ? "latex-key" : "pandoc-key";
|
|
10712
|
+
if (options.pandocKey) return "pandoc-key";
|
|
10713
|
+
if (options.latexKey) return "latex-key";
|
|
10618
10714
|
if (options.json) return "json";
|
|
10619
10715
|
if (options.idsOnly) return "ids-only";
|
|
10620
10716
|
if (options.uuidOnly) return "uuid";
|
|
@@ -10622,12 +10718,18 @@ function getOutputFormat$1(options) {
|
|
|
10622
10718
|
return "pretty";
|
|
10623
10719
|
}
|
|
10624
10720
|
function validateOptions$1(options) {
|
|
10625
|
-
const outputOptions = [
|
|
10626
|
-
|
|
10627
|
-
|
|
10721
|
+
const outputOptions = [
|
|
10722
|
+
options.json,
|
|
10723
|
+
options.idsOnly,
|
|
10724
|
+
options.uuidOnly,
|
|
10725
|
+
options.bibtex,
|
|
10726
|
+
options.key,
|
|
10727
|
+
options.pandocKey,
|
|
10728
|
+
options.latexKey
|
|
10729
|
+
].filter(Boolean);
|
|
10628
10730
|
if (outputOptions.length > 1) {
|
|
10629
10731
|
throw new Error(
|
|
10630
|
-
"Multiple output formats specified. Only one of --json, --ids-only, --uuid-only, --bibtex can be used."
|
|
10732
|
+
"Multiple output formats specified. Only one of --json, --ids-only, --uuid-only, --bibtex, --key, --pandoc-key, --latex-key can be used."
|
|
10631
10733
|
);
|
|
10632
10734
|
}
|
|
10633
10735
|
if (options.output && outputOptions.length > 0) {
|
|
@@ -10662,8 +10764,8 @@ async function executeList(options, context) {
|
|
|
10662
10764
|
...pickDefined(options, ["order", "limit", "offset"])
|
|
10663
10765
|
});
|
|
10664
10766
|
}
|
|
10665
|
-
function formatListOutput(result, options) {
|
|
10666
|
-
const format2 = getOutputFormat$1(options);
|
|
10767
|
+
function formatListOutput(result, options, defaultKeyFormat) {
|
|
10768
|
+
const format2 = getOutputFormat$1(options, defaultKeyFormat);
|
|
10667
10769
|
if (format2 === "json") {
|
|
10668
10770
|
return JSON.stringify({
|
|
10669
10771
|
items: result.items,
|
|
@@ -15480,10 +15582,10 @@ const $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
15480
15582
|
inst._zod.check = (payload) => {
|
|
15481
15583
|
try {
|
|
15482
15584
|
const trimmed = payload.value.trim();
|
|
15483
|
-
const
|
|
15585
|
+
const url2 = new URL(trimmed);
|
|
15484
15586
|
if (def.hostname) {
|
|
15485
15587
|
def.hostname.lastIndex = 0;
|
|
15486
|
-
if (!def.hostname.test(
|
|
15588
|
+
if (!def.hostname.test(url2.hostname)) {
|
|
15487
15589
|
payload.issues.push({
|
|
15488
15590
|
code: "invalid_format",
|
|
15489
15591
|
format: "url",
|
|
@@ -15497,7 +15599,7 @@ const $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
15497
15599
|
}
|
|
15498
15600
|
if (def.protocol) {
|
|
15499
15601
|
def.protocol.lastIndex = 0;
|
|
15500
|
-
if (!def.protocol.test(
|
|
15602
|
+
if (!def.protocol.test(url2.protocol.endsWith(":") ? url2.protocol.slice(0, -1) : url2.protocol)) {
|
|
15501
15603
|
payload.issues.push({
|
|
15502
15604
|
code: "invalid_format",
|
|
15503
15605
|
format: "url",
|
|
@@ -15510,7 +15612,7 @@ const $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
15510
15612
|
}
|
|
15511
15613
|
}
|
|
15512
15614
|
if (def.normalize) {
|
|
15513
|
-
payload.value =
|
|
15615
|
+
payload.value = url2.href;
|
|
15514
15616
|
} else {
|
|
15515
15617
|
payload.value = trimmed;
|
|
15516
15618
|
}
|
|
@@ -31388,7 +31490,7 @@ Continue?`;
|
|
|
31388
31490
|
}
|
|
31389
31491
|
async function executeInteractiveRemove(context, config2) {
|
|
31390
31492
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
31391
|
-
const { selectReferenceItemsOrExit } = await import("./reference-select-
|
|
31493
|
+
const { selectReferenceItemsOrExit } = await import("./reference-select-DcClzkw2.js");
|
|
31392
31494
|
const allReferences = await context.library.getAll();
|
|
31393
31495
|
const selectedItems = await withAlternateScreen2(
|
|
31394
31496
|
() => selectReferenceItemsOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -31485,6 +31587,15 @@ async function handleRemoveAction(identifierArg, options, globalOpts) {
|
|
|
31485
31587
|
handleRemoveError(error, identifierArg, outputFormat);
|
|
31486
31588
|
}
|
|
31487
31589
|
}
|
|
31590
|
+
const remove = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
31591
|
+
__proto__: null,
|
|
31592
|
+
confirmRemoveIfNeeded,
|
|
31593
|
+
executeRemove,
|
|
31594
|
+
formatFulltextWarning,
|
|
31595
|
+
formatRemoveOutput,
|
|
31596
|
+
getFulltextAttachmentTypes,
|
|
31597
|
+
handleRemoveAction
|
|
31598
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
31488
31599
|
const VALID_SEARCH_SORT_FIELDS = /* @__PURE__ */ new Set([
|
|
31489
31600
|
"created",
|
|
31490
31601
|
"updated",
|
|
@@ -31497,11 +31608,14 @@ const VALID_SEARCH_SORT_FIELDS = /* @__PURE__ */ new Set([
|
|
|
31497
31608
|
"pub",
|
|
31498
31609
|
"rel"
|
|
31499
31610
|
]);
|
|
31500
|
-
function getOutputFormat(options) {
|
|
31611
|
+
function getOutputFormat(options, defaultKeyFormat) {
|
|
31501
31612
|
if (options.output) {
|
|
31502
31613
|
if (options.output === "ids") return "ids-only";
|
|
31503
31614
|
return options.output;
|
|
31504
31615
|
}
|
|
31616
|
+
if (options.key) return defaultKeyFormat === "latex" ? "latex-key" : "pandoc-key";
|
|
31617
|
+
if (options.pandocKey) return "pandoc-key";
|
|
31618
|
+
if (options.latexKey) return "latex-key";
|
|
31505
31619
|
if (options.json) return "json";
|
|
31506
31620
|
if (options.idsOnly) return "ids-only";
|
|
31507
31621
|
if (options.uuidOnly) return "uuid";
|
|
@@ -31509,12 +31623,18 @@ function getOutputFormat(options) {
|
|
|
31509
31623
|
return "pretty";
|
|
31510
31624
|
}
|
|
31511
31625
|
function validateOptions(options) {
|
|
31512
|
-
const outputOptions = [
|
|
31513
|
-
|
|
31514
|
-
|
|
31626
|
+
const outputOptions = [
|
|
31627
|
+
options.json,
|
|
31628
|
+
options.idsOnly,
|
|
31629
|
+
options.uuidOnly,
|
|
31630
|
+
options.bibtex,
|
|
31631
|
+
options.key,
|
|
31632
|
+
options.pandocKey,
|
|
31633
|
+
options.latexKey
|
|
31634
|
+
].filter(Boolean);
|
|
31515
31635
|
if (outputOptions.length > 1) {
|
|
31516
31636
|
throw new Error(
|
|
31517
|
-
"Multiple output formats specified. Only one of --json, --ids-only, --uuid-only, --bibtex can be used."
|
|
31637
|
+
"Multiple output formats specified. Only one of --json, --ids-only, --uuid-only, --bibtex, --key, --pandoc-key, --latex-key can be used."
|
|
31518
31638
|
);
|
|
31519
31639
|
}
|
|
31520
31640
|
if (options.output && outputOptions.length > 0) {
|
|
@@ -31550,8 +31670,8 @@ async function executeSearch(options, context) {
|
|
|
31550
31670
|
...pickDefined(options, ["order", "limit", "offset"])
|
|
31551
31671
|
});
|
|
31552
31672
|
}
|
|
31553
|
-
function formatSearchOutput(result, options) {
|
|
31554
|
-
const format2 = getOutputFormat(options);
|
|
31673
|
+
function formatSearchOutput(result, options, defaultKeyFormat) {
|
|
31674
|
+
const format2 = getOutputFormat(options, defaultKeyFormat);
|
|
31555
31675
|
if (format2 === "json") {
|
|
31556
31676
|
return JSON.stringify({
|
|
31557
31677
|
items: result.items,
|
|
@@ -31580,11 +31700,14 @@ function validateInteractiveOptions(options) {
|
|
|
31580
31700
|
options.json,
|
|
31581
31701
|
options.idsOnly,
|
|
31582
31702
|
options.uuidOnly,
|
|
31583
|
-
options.bibtex
|
|
31703
|
+
options.bibtex,
|
|
31704
|
+
options.key,
|
|
31705
|
+
options.pandocKey,
|
|
31706
|
+
options.latexKey
|
|
31584
31707
|
].filter(Boolean);
|
|
31585
31708
|
if (outputOptions.length > 0) {
|
|
31586
31709
|
throw new Error(
|
|
31587
|
-
"TUI mode cannot be combined with output format options (--output, --json, --ids-only, --uuid-only, --bibtex)"
|
|
31710
|
+
"TUI mode cannot be combined with output format options (--output, --json, --ids-only, --uuid-only, --bibtex, --key, --pandoc-key, --latex-key)"
|
|
31588
31711
|
);
|
|
31589
31712
|
}
|
|
31590
31713
|
}
|
|
@@ -31592,7 +31715,7 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
31592
31715
|
validateInteractiveOptions(options);
|
|
31593
31716
|
const { checkTTY } = await import("./tty-BMyaEOhX.js");
|
|
31594
31717
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
31595
|
-
const { runSearchFlow } = await import("./index-
|
|
31718
|
+
const { runSearchFlow } = await import("./index-B5W5srUa.js");
|
|
31596
31719
|
const { search } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.z);
|
|
31597
31720
|
const { tokenize } = await import("./file-watcher-CrsNHUpz.js").then((n) => n.y);
|
|
31598
31721
|
checkTTY();
|
|
@@ -31605,14 +31728,110 @@ async function executeInteractiveSearch(options, context, config2) {
|
|
|
31605
31728
|
const result = await withAlternateScreen2(
|
|
31606
31729
|
() => runSearchFlow(allReferences, searchFn, {
|
|
31607
31730
|
limit: tuiConfig.limit,
|
|
31608
|
-
debounceMs: tuiConfig.debounceMs
|
|
31731
|
+
debounceMs: tuiConfig.debounceMs,
|
|
31732
|
+
defaultKeyFormat: config2.citation.defaultKeyFormat,
|
|
31733
|
+
defaultStyle: config2.citation.defaultStyle
|
|
31609
31734
|
})
|
|
31610
31735
|
);
|
|
31736
|
+
if (result.selectedItems && !result.cancelled) {
|
|
31737
|
+
const { isSideEffectAction } = await import("./action-menu-D8gSe1YM.js");
|
|
31738
|
+
if (isSideEffectAction(result.action)) {
|
|
31739
|
+
await executeSideEffectAction(result.action, result.selectedItems, context, config2);
|
|
31740
|
+
return { output: "", cancelled: false, action: result.action };
|
|
31741
|
+
}
|
|
31742
|
+
}
|
|
31611
31743
|
return {
|
|
31612
31744
|
output: result.output,
|
|
31613
|
-
cancelled: result.cancelled
|
|
31745
|
+
cancelled: result.cancelled,
|
|
31746
|
+
action: result.action
|
|
31614
31747
|
};
|
|
31615
31748
|
}
|
|
31749
|
+
async function executeSideEffectAction(action, items2, context, config2) {
|
|
31750
|
+
switch (action) {
|
|
31751
|
+
case "open-url": {
|
|
31752
|
+
const { resolveDefaultUrl: resolveDefaultUrl2 } = await Promise.resolve().then(() => url);
|
|
31753
|
+
const { openWithSystemApp: openWithSystemApp2 } = await import("./loader-BtW20O32.js").then((n) => n.j);
|
|
31754
|
+
const item = items2[0];
|
|
31755
|
+
if (!item) return;
|
|
31756
|
+
const url$1 = resolveDefaultUrl2(item);
|
|
31757
|
+
if (url$1) {
|
|
31758
|
+
await openWithSystemApp2(url$1);
|
|
31759
|
+
} else {
|
|
31760
|
+
process.stderr.write(`No URL available for ${item.id}
|
|
31761
|
+
`);
|
|
31762
|
+
}
|
|
31763
|
+
break;
|
|
31764
|
+
}
|
|
31765
|
+
case "open-fulltext": {
|
|
31766
|
+
const { executeFulltextOpen: executeFulltextOpen2 } = await Promise.resolve().then(() => fulltext);
|
|
31767
|
+
const item = items2[0];
|
|
31768
|
+
if (!item) return;
|
|
31769
|
+
const result = await executeFulltextOpen2(
|
|
31770
|
+
{
|
|
31771
|
+
identifier: item.id,
|
|
31772
|
+
fulltextDirectory: config2.attachments.directory
|
|
31773
|
+
},
|
|
31774
|
+
context
|
|
31775
|
+
);
|
|
31776
|
+
if (!result.success) {
|
|
31777
|
+
process.stderr.write(`${result.error}
|
|
31778
|
+
`);
|
|
31779
|
+
}
|
|
31780
|
+
break;
|
|
31781
|
+
}
|
|
31782
|
+
case "manage-attachments": {
|
|
31783
|
+
const { executeAttachOpen: executeAttachOpen2 } = await Promise.resolve().then(() => attach);
|
|
31784
|
+
const item = items2[0];
|
|
31785
|
+
if (!item) return;
|
|
31786
|
+
await executeAttachOpen2(
|
|
31787
|
+
{
|
|
31788
|
+
identifier: item.id,
|
|
31789
|
+
attachmentsDirectory: config2.attachments.directory
|
|
31790
|
+
},
|
|
31791
|
+
context
|
|
31792
|
+
);
|
|
31793
|
+
break;
|
|
31794
|
+
}
|
|
31795
|
+
case "edit": {
|
|
31796
|
+
const { executeEditCommand: executeEditCommand2 } = await Promise.resolve().then(() => edit);
|
|
31797
|
+
await executeEditCommand2(
|
|
31798
|
+
{
|
|
31799
|
+
identifiers: items2.map((i) => i.id),
|
|
31800
|
+
format: config2.cli.edit.defaultFormat
|
|
31801
|
+
},
|
|
31802
|
+
context
|
|
31803
|
+
);
|
|
31804
|
+
break;
|
|
31805
|
+
}
|
|
31806
|
+
case "remove": {
|
|
31807
|
+
const {
|
|
31808
|
+
executeRemove: executeRemove2,
|
|
31809
|
+
confirmRemoveIfNeeded: confirmRemoveIfNeeded2,
|
|
31810
|
+
getFulltextAttachmentTypes: getFulltextAttachmentTypes2,
|
|
31811
|
+
formatRemoveOutput: formatRemoveOutput2
|
|
31812
|
+
} = await Promise.resolve().then(() => remove);
|
|
31813
|
+
for (const item of items2) {
|
|
31814
|
+
const hasFulltext = getFulltextAttachmentTypes2(item).length > 0;
|
|
31815
|
+
const confirmed = await confirmRemoveIfNeeded2(item, hasFulltext, false);
|
|
31816
|
+
if (!confirmed) {
|
|
31817
|
+
process.stderr.write("Cancelled.\n");
|
|
31818
|
+
continue;
|
|
31819
|
+
}
|
|
31820
|
+
const result = await executeRemove2(
|
|
31821
|
+
{
|
|
31822
|
+
identifier: item.id,
|
|
31823
|
+
fulltextDirectory: config2.attachments.directory,
|
|
31824
|
+
deleteFulltext: hasFulltext
|
|
31825
|
+
},
|
|
31826
|
+
context
|
|
31827
|
+
);
|
|
31828
|
+
process.stderr.write(`${formatRemoveOutput2(result, item.id)}
|
|
31829
|
+
`);
|
|
31830
|
+
}
|
|
31831
|
+
break;
|
|
31832
|
+
}
|
|
31833
|
+
}
|
|
31834
|
+
}
|
|
31616
31835
|
async function serverStart(options) {
|
|
31617
31836
|
const existingStatus = await serverStatus(options.portfilePath);
|
|
31618
31837
|
if (existingStatus !== null) {
|
|
@@ -31906,7 +32125,7 @@ function formatUpdateOutput(result, identifier) {
|
|
|
31906
32125
|
}
|
|
31907
32126
|
async function executeInteractiveUpdate(context, config2) {
|
|
31908
32127
|
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
31909
|
-
const { selectReferencesOrExit } = await import("./reference-select-
|
|
32128
|
+
const { selectReferencesOrExit } = await import("./reference-select-DcClzkw2.js");
|
|
31910
32129
|
const allReferences = await context.library.getAll();
|
|
31911
32130
|
const identifiers = await withAlternateScreen2(
|
|
31912
32131
|
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
@@ -32021,6 +32240,231 @@ async function handleUpdateAction(identifierArg, file, options, globalOpts) {
|
|
|
32021
32240
|
function collectSetOption(value, previous) {
|
|
32022
32241
|
return previous.concat([value]);
|
|
32023
32242
|
}
|
|
32243
|
+
function buildDoiUrl(doi) {
|
|
32244
|
+
return `https://doi.org/${doi}`;
|
|
32245
|
+
}
|
|
32246
|
+
function buildPubmedUrl(pmid) {
|
|
32247
|
+
return `https://pubmed.ncbi.nlm.nih.gov/${pmid}/`;
|
|
32248
|
+
}
|
|
32249
|
+
function buildPmcUrl(pmcid) {
|
|
32250
|
+
return `https://www.ncbi.nlm.nih.gov/pmc/articles/${pmcid}/`;
|
|
32251
|
+
}
|
|
32252
|
+
function resolveAllUrls(item) {
|
|
32253
|
+
const urls = [];
|
|
32254
|
+
if (item.DOI) {
|
|
32255
|
+
urls.push(buildDoiUrl(item.DOI));
|
|
32256
|
+
}
|
|
32257
|
+
if (item.URL) {
|
|
32258
|
+
urls.push(item.URL);
|
|
32259
|
+
}
|
|
32260
|
+
if (item.PMID) {
|
|
32261
|
+
urls.push(buildPubmedUrl(item.PMID));
|
|
32262
|
+
}
|
|
32263
|
+
if (item.PMCID) {
|
|
32264
|
+
urls.push(buildPmcUrl(item.PMCID));
|
|
32265
|
+
}
|
|
32266
|
+
const additionalUrls = item.custom?.additional_urls;
|
|
32267
|
+
if (additionalUrls && additionalUrls.length > 0) {
|
|
32268
|
+
urls.push(...additionalUrls);
|
|
32269
|
+
}
|
|
32270
|
+
return urls;
|
|
32271
|
+
}
|
|
32272
|
+
function resolveDefaultUrl(item) {
|
|
32273
|
+
if (item.DOI) {
|
|
32274
|
+
return buildDoiUrl(item.DOI);
|
|
32275
|
+
}
|
|
32276
|
+
if (item.URL) {
|
|
32277
|
+
return item.URL;
|
|
32278
|
+
}
|
|
32279
|
+
if (item.PMID) {
|
|
32280
|
+
return buildPubmedUrl(item.PMID);
|
|
32281
|
+
}
|
|
32282
|
+
if (item.PMCID) {
|
|
32283
|
+
return buildPmcUrl(item.PMCID);
|
|
32284
|
+
}
|
|
32285
|
+
const additionalUrls = item.custom?.additional_urls;
|
|
32286
|
+
if (additionalUrls && additionalUrls.length > 0) {
|
|
32287
|
+
return additionalUrls[0] ?? null;
|
|
32288
|
+
}
|
|
32289
|
+
return null;
|
|
32290
|
+
}
|
|
32291
|
+
function resolveUrlByType(item, type2) {
|
|
32292
|
+
switch (type2) {
|
|
32293
|
+
case "doi":
|
|
32294
|
+
return item.DOI ? buildDoiUrl(item.DOI) : null;
|
|
32295
|
+
case "url":
|
|
32296
|
+
return item.URL ?? null;
|
|
32297
|
+
case "pubmed":
|
|
32298
|
+
return item.PMID ? buildPubmedUrl(item.PMID) : null;
|
|
32299
|
+
case "pmcid":
|
|
32300
|
+
return item.PMCID ? buildPmcUrl(item.PMCID) : null;
|
|
32301
|
+
}
|
|
32302
|
+
}
|
|
32303
|
+
const url = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
32304
|
+
__proto__: null,
|
|
32305
|
+
resolveAllUrls,
|
|
32306
|
+
resolveDefaultUrl,
|
|
32307
|
+
resolveUrlByType
|
|
32308
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
32309
|
+
function getUrlTypeFilter(options) {
|
|
32310
|
+
if (options.doi) return "doi";
|
|
32311
|
+
if (options.pubmed) return "pubmed";
|
|
32312
|
+
if (options.pmcid) return "pmcid";
|
|
32313
|
+
if (options.default) return "default";
|
|
32314
|
+
if (options.open) return "default";
|
|
32315
|
+
return null;
|
|
32316
|
+
}
|
|
32317
|
+
function getFilterLabel(filter) {
|
|
32318
|
+
switch (filter) {
|
|
32319
|
+
case "doi":
|
|
32320
|
+
return "DOI";
|
|
32321
|
+
case "pubmed":
|
|
32322
|
+
return "PubMed";
|
|
32323
|
+
case "pmcid":
|
|
32324
|
+
return "PMC";
|
|
32325
|
+
case "url":
|
|
32326
|
+
return "URL";
|
|
32327
|
+
case "default":
|
|
32328
|
+
return "default";
|
|
32329
|
+
}
|
|
32330
|
+
}
|
|
32331
|
+
function resolveUrlsForItem(item, id2, filter) {
|
|
32332
|
+
if (filter === null) {
|
|
32333
|
+
const urls = resolveAllUrls(item);
|
|
32334
|
+
if (urls.length === 0) {
|
|
32335
|
+
return { id: id2, urls: [], error: `No URLs available for ${id2}` };
|
|
32336
|
+
}
|
|
32337
|
+
return { id: id2, urls };
|
|
32338
|
+
}
|
|
32339
|
+
if (filter === "default") {
|
|
32340
|
+
const url22 = resolveDefaultUrl(item);
|
|
32341
|
+
if (!url22) {
|
|
32342
|
+
return { id: id2, urls: [], error: `No URLs available for ${id2}` };
|
|
32343
|
+
}
|
|
32344
|
+
return { id: id2, urls: [url22] };
|
|
32345
|
+
}
|
|
32346
|
+
const url2 = resolveUrlByType(item, filter);
|
|
32347
|
+
if (!url2) {
|
|
32348
|
+
return { id: id2, urls: [], error: `No ${getFilterLabel(filter)} URL for ${id2}` };
|
|
32349
|
+
}
|
|
32350
|
+
return { id: id2, urls: [url2] };
|
|
32351
|
+
}
|
|
32352
|
+
async function executeUrlCommand(identifiers, options, context) {
|
|
32353
|
+
const filter = getUrlTypeFilter(options);
|
|
32354
|
+
const findOptions = options.uuid ? { idType: "uuid" } : void 0;
|
|
32355
|
+
const results = [];
|
|
32356
|
+
for (const identifier of identifiers) {
|
|
32357
|
+
const item = await context.library.find(identifier, findOptions);
|
|
32358
|
+
if (!item) {
|
|
32359
|
+
results.push({ id: identifier, urls: [], error: `Reference not found: ${identifier}` });
|
|
32360
|
+
continue;
|
|
32361
|
+
}
|
|
32362
|
+
const result = resolveUrlsForItem(item, identifier, filter);
|
|
32363
|
+
results.push(result);
|
|
32364
|
+
}
|
|
32365
|
+
if (options.open) {
|
|
32366
|
+
const firstSuccess = results.find((r) => r.urls.length > 0);
|
|
32367
|
+
if (firstSuccess?.urls[0]) {
|
|
32368
|
+
try {
|
|
32369
|
+
await openWithSystemApp(firstSuccess.urls[0]);
|
|
32370
|
+
} catch (error) {
|
|
32371
|
+
return {
|
|
32372
|
+
results,
|
|
32373
|
+
openError: `Failed to open URL: ${error instanceof Error ? error.message : String(error)}`
|
|
32374
|
+
};
|
|
32375
|
+
}
|
|
32376
|
+
}
|
|
32377
|
+
}
|
|
32378
|
+
return { results };
|
|
32379
|
+
}
|
|
32380
|
+
function hasFilter(options) {
|
|
32381
|
+
return Boolean(options.default || options.doi || options.pubmed || options.pmcid || options.open);
|
|
32382
|
+
}
|
|
32383
|
+
function formatUrlOutput(result, options) {
|
|
32384
|
+
const successResults = result.results.filter((r) => r.urls.length > 0);
|
|
32385
|
+
if (successResults.length === 0) {
|
|
32386
|
+
return "";
|
|
32387
|
+
}
|
|
32388
|
+
const filtered = hasFilter(options);
|
|
32389
|
+
if (filtered || successResults.length === 1) {
|
|
32390
|
+
const lines2 = [];
|
|
32391
|
+
for (const r of successResults) {
|
|
32392
|
+
for (const url2 of r.urls) {
|
|
32393
|
+
lines2.push(url2);
|
|
32394
|
+
}
|
|
32395
|
+
}
|
|
32396
|
+
return lines2.join("\n");
|
|
32397
|
+
}
|
|
32398
|
+
const lines = [];
|
|
32399
|
+
for (const r of successResults) {
|
|
32400
|
+
for (const url2 of r.urls) {
|
|
32401
|
+
lines.push(`${r.id} ${url2}`);
|
|
32402
|
+
}
|
|
32403
|
+
}
|
|
32404
|
+
return lines.join("\n");
|
|
32405
|
+
}
|
|
32406
|
+
function formatUrlErrors(result) {
|
|
32407
|
+
const errorMessages = result.results.filter((r) => r.error).map((r) => `Error: ${r.error}`);
|
|
32408
|
+
if (result.openError) {
|
|
32409
|
+
errorMessages.push(`Error: ${result.openError}`);
|
|
32410
|
+
}
|
|
32411
|
+
return errorMessages.join("\n");
|
|
32412
|
+
}
|
|
32413
|
+
function getUrlExitCode(result) {
|
|
32414
|
+
if (result.openError) return ExitCode.ERROR;
|
|
32415
|
+
const hasSuccess = result.results.some((r) => r.urls.length > 0);
|
|
32416
|
+
const hasError = result.results.some((r) => r.error);
|
|
32417
|
+
if (hasSuccess) return ExitCode.SUCCESS;
|
|
32418
|
+
if (hasError) return ExitCode.ERROR;
|
|
32419
|
+
return ExitCode.SUCCESS;
|
|
32420
|
+
}
|
|
32421
|
+
async function executeInteractiveSelect(context, config2) {
|
|
32422
|
+
const { withAlternateScreen: withAlternateScreen2 } = await Promise.resolve().then(() => alternateScreen);
|
|
32423
|
+
const { selectReferencesOrExit } = await import("./reference-select-DcClzkw2.js");
|
|
32424
|
+
const allReferences = await context.library.getAll();
|
|
32425
|
+
const identifiers = await withAlternateScreen2(
|
|
32426
|
+
() => selectReferencesOrExit(allReferences, { multiSelect: false }, config2.cli.tui)
|
|
32427
|
+
);
|
|
32428
|
+
return identifiers[0] ?? "";
|
|
32429
|
+
}
|
|
32430
|
+
async function handleUrlAction(identifiers, options, globalOpts) {
|
|
32431
|
+
try {
|
|
32432
|
+
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
32433
|
+
const context = await createExecutionContext(config2, Library.load);
|
|
32434
|
+
let resolvedIdentifiers;
|
|
32435
|
+
let isTuiMode = false;
|
|
32436
|
+
if (identifiers && identifiers.length > 0) {
|
|
32437
|
+
resolvedIdentifiers = identifiers;
|
|
32438
|
+
} else if (isTTY()) {
|
|
32439
|
+
isTuiMode = true;
|
|
32440
|
+
const selected = await executeInteractiveSelect(context, config2);
|
|
32441
|
+
resolvedIdentifiers = [selected];
|
|
32442
|
+
} else {
|
|
32443
|
+
const stdinId = await readIdentifierFromStdin();
|
|
32444
|
+
if (!stdinId) {
|
|
32445
|
+
exitWithError("Identifier is required");
|
|
32446
|
+
return;
|
|
32447
|
+
}
|
|
32448
|
+
resolvedIdentifiers = [stdinId];
|
|
32449
|
+
}
|
|
32450
|
+
const result = await executeUrlCommand(resolvedIdentifiers, options, context);
|
|
32451
|
+
const output = formatUrlOutput(result, options);
|
|
32452
|
+
if (output) {
|
|
32453
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, isTuiMode);
|
|
32454
|
+
await writeOutputWithClipboard(output, clipboardEnabled, config2.logLevel === "silent");
|
|
32455
|
+
}
|
|
32456
|
+
const errors2 = formatUrlErrors(result);
|
|
32457
|
+
if (errors2) {
|
|
32458
|
+
process.stderr.write(`${errors2}
|
|
32459
|
+
`);
|
|
32460
|
+
}
|
|
32461
|
+
setExitCode(getUrlExitCode(result));
|
|
32462
|
+
} catch (error) {
|
|
32463
|
+
process.stderr.write(`Error: ${error instanceof Error ? error.message : String(error)}
|
|
32464
|
+
`);
|
|
32465
|
+
setExitCode(ExitCode.INTERNAL_ERROR);
|
|
32466
|
+
}
|
|
32467
|
+
}
|
|
32024
32468
|
const SEARCH_SORT_FIELDS = searchSortFieldSchema.options;
|
|
32025
32469
|
const SORT_ORDERS = sortOrderSchema.options;
|
|
32026
32470
|
const CITATION_OUTPUT_FORMATS = ["text", "html", "rtf"];
|
|
@@ -32305,7 +32749,7 @@ function registerCompletionCommand(program) {
|
|
|
32305
32749
|
function createProgram() {
|
|
32306
32750
|
const program = new Command();
|
|
32307
32751
|
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");
|
|
32752
|
+
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
32753
|
registerListCommand(program);
|
|
32310
32754
|
registerSearchCommand(program);
|
|
32311
32755
|
registerExportCommand(program);
|
|
@@ -32318,6 +32762,7 @@ function createProgram() {
|
|
|
32318
32762
|
registerFulltextCommand(program);
|
|
32319
32763
|
registerAttachCommand(program);
|
|
32320
32764
|
registerMcpCommand(program);
|
|
32765
|
+
registerUrlCommand(program);
|
|
32321
32766
|
registerConfigCommand(program);
|
|
32322
32767
|
registerCompletionCommand(program);
|
|
32323
32768
|
return program;
|
|
@@ -32326,12 +32771,12 @@ async function handleListAction(options, program) {
|
|
|
32326
32771
|
try {
|
|
32327
32772
|
const globalOpts = program.opts();
|
|
32328
32773
|
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
32774
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, false);
|
|
32329
32775
|
const context = await createExecutionContext(config2, Library.load);
|
|
32330
32776
|
const result = await executeList(options, context);
|
|
32331
|
-
const output = formatListOutput(result, options);
|
|
32777
|
+
const output = formatListOutput(result, options, config2.citation.defaultKeyFormat);
|
|
32332
32778
|
if (output) {
|
|
32333
|
-
|
|
32334
|
-
`);
|
|
32779
|
+
await writeOutputWithClipboard(output, clipboardEnabled, config2.logLevel === "silent");
|
|
32335
32780
|
}
|
|
32336
32781
|
setExitCode(ExitCode.SUCCESS);
|
|
32337
32782
|
} catch (error) {
|
|
@@ -32339,7 +32784,10 @@ async function handleListAction(options, program) {
|
|
|
32339
32784
|
}
|
|
32340
32785
|
}
|
|
32341
32786
|
function registerListCommand(program) {
|
|
32342
|
-
program.command("list").description("List all references in the library").option(
|
|
32787
|
+
program.command("list").description("List all references in the library").option(
|
|
32788
|
+
"-o, --output <format>",
|
|
32789
|
+
"Output format: pretty|json|bibtex|ids|uuid|pandoc-key|latex-key"
|
|
32790
|
+
).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
32791
|
await handleListAction(options, program);
|
|
32344
32792
|
});
|
|
32345
32793
|
}
|
|
@@ -32347,12 +32795,12 @@ async function handleExportAction(ids, options, program) {
|
|
|
32347
32795
|
try {
|
|
32348
32796
|
const globalOpts = program.opts();
|
|
32349
32797
|
const config2 = await loadConfigWithOverrides({ ...globalOpts, ...options });
|
|
32798
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, false);
|
|
32350
32799
|
const context = await createExecutionContext(config2, Library.load);
|
|
32351
32800
|
const result = await executeExport({ ...options, ids }, context);
|
|
32352
32801
|
const output = formatExportOutput(result, { ...options, ids });
|
|
32353
32802
|
if (output) {
|
|
32354
|
-
|
|
32355
|
-
`);
|
|
32803
|
+
await writeOutputWithClipboard(output, clipboardEnabled, config2.logLevel === "silent");
|
|
32356
32804
|
}
|
|
32357
32805
|
if (result.notFound.length > 0) {
|
|
32358
32806
|
for (const id2 of result.notFound) {
|
|
@@ -32380,17 +32828,25 @@ async function handleSearchAction(query, options, program) {
|
|
|
32380
32828
|
if (options.tui) {
|
|
32381
32829
|
const result2 = await executeInteractiveSearch({ ...options, query }, context, config2);
|
|
32382
32830
|
if (result2.output) {
|
|
32383
|
-
|
|
32384
|
-
|
|
32831
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, true);
|
|
32832
|
+
await writeOutputWithClipboard(
|
|
32833
|
+
result2.output,
|
|
32834
|
+
clipboardEnabled,
|
|
32835
|
+
config2.logLevel === "silent"
|
|
32836
|
+
);
|
|
32385
32837
|
}
|
|
32386
32838
|
setExitCode(ExitCode.SUCCESS);
|
|
32387
32839
|
return;
|
|
32388
32840
|
}
|
|
32389
32841
|
const result = await executeSearch({ ...options, query }, context);
|
|
32390
|
-
const output = formatSearchOutput(
|
|
32842
|
+
const output = formatSearchOutput(
|
|
32843
|
+
result,
|
|
32844
|
+
{ ...options, query },
|
|
32845
|
+
config2.citation.defaultKeyFormat
|
|
32846
|
+
);
|
|
32391
32847
|
if (output) {
|
|
32392
|
-
|
|
32393
|
-
|
|
32848
|
+
const clipboardEnabled = resolveClipboardEnabled(globalOpts, config2, false);
|
|
32849
|
+
await writeOutputWithClipboard(output, clipboardEnabled, config2.logLevel === "silent");
|
|
32394
32850
|
}
|
|
32395
32851
|
setExitCode(ExitCode.SUCCESS);
|
|
32396
32852
|
} catch (error) {
|
|
@@ -32400,7 +32856,10 @@ async function handleSearchAction(query, options, program) {
|
|
|
32400
32856
|
}
|
|
32401
32857
|
}
|
|
32402
32858
|
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(
|
|
32859
|
+
program.command("search").description("Search references").argument("[query]", "Search query (required unless using --tui)").option("-t, --tui", "Enable TUI (interactive) search mode").option(
|
|
32860
|
+
"-o, --output <format>",
|
|
32861
|
+
"Output format: pretty|json|bibtex|ids|uuid|pandoc-key|latex-key"
|
|
32862
|
+
).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
32863
|
if (!options.tui && !query) {
|
|
32405
32864
|
process.stderr.write("Error: Search query is required unless using --tui\n");
|
|
32406
32865
|
setExitCode(ExitCode.ERROR);
|
|
@@ -32616,6 +33075,9 @@ function registerMcpCommand(program) {
|
|
|
32616
33075
|
}
|
|
32617
33076
|
function registerAttachCommand(program) {
|
|
32618
33077
|
const attachCmd = program.command("attach").description("Manage file attachments for references");
|
|
33078
|
+
attachCmd.argument("[identifier]", "Citation key or UUID (interactive selection if omitted)").option("--uuid", "Interpret identifier as UUID").action(async (identifier, options) => {
|
|
33079
|
+
await handleAttachOpenAction(identifier, void 0, options, program.opts());
|
|
33080
|
+
});
|
|
32619
33081
|
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
33082
|
await handleAttachOpenAction(identifier, filename, options, program.opts());
|
|
32621
33083
|
});
|
|
@@ -32653,6 +33115,12 @@ function registerFulltextCommand(program) {
|
|
|
32653
33115
|
await handleFulltextOpenAction(identifier, options, program.opts());
|
|
32654
33116
|
});
|
|
32655
33117
|
}
|
|
33118
|
+
function registerUrlCommand(program) {
|
|
33119
|
+
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) => {
|
|
33120
|
+
const globalOpts = program.opts();
|
|
33121
|
+
await handleUrlAction(identifiers.length > 0 ? identifiers : void 0, options, globalOpts);
|
|
33122
|
+
});
|
|
33123
|
+
}
|
|
32656
33124
|
async function main(argv) {
|
|
32657
33125
|
const program = createProgram();
|
|
32658
33126
|
if (process.env.COMP_LINE) {
|
|
@@ -32670,6 +33138,7 @@ async function main(argv) {
|
|
|
32670
33138
|
export {
|
|
32671
33139
|
Select as S,
|
|
32672
33140
|
addAttachment as a,
|
|
33141
|
+
stringify as b,
|
|
32673
33142
|
createProgram as c,
|
|
32674
33143
|
detachAttachment as d,
|
|
32675
33144
|
formatBibtex as f,
|
|
@@ -32681,4 +33150,4 @@ export {
|
|
|
32681
33150
|
restoreStdinAfterInk as r,
|
|
32682
33151
|
syncAttachments as s
|
|
32683
33152
|
};
|
|
32684
|
-
//# sourceMappingURL=index-
|
|
33153
|
+
//# sourceMappingURL=index-BPhIwqHO.js.map
|