dsh-cite 0.1.1 → 0.3.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/LICENSE +21 -0
- package/README.en.md +16 -0
- package/README.md +20 -3
- package/lib/config.d.ts +3 -1
- package/lib/config.js +11 -3
- package/lib/crossref.d.ts +1 -0
- package/lib/crossref.js +2 -1
- package/lib/format.js +25 -4
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/tools.js +71 -6
- package/package.json +63 -64
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 stardustlc
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.en.md
CHANGED
|
@@ -13,6 +13,10 @@ A DeepSeek Harness plugin for bibliographic references: query Crossref and forma
|
|
|
13
13
|
| `cite_bibtex` | Generate a BibTeX entry | `doi`; `key` optional |
|
|
14
14
|
| `cite_check` | Extract DOIs from text and validate them | `text`; `maxChecks` 1-50, default 10 |
|
|
15
15
|
|
|
16
|
+
## Compatibility
|
|
17
|
+
|
|
18
|
+
Verified against `@deepseek-ai/dsh@0.1.1-rc.2` on 2026-08-26. Built for the cordis patch-bundle plugin model (`cordis.patch.yml` + `dsh.bundle.patch`). No runtime imports of `@deepseek-ai/*` internals.
|
|
19
|
+
|
|
16
20
|
## Install
|
|
17
21
|
|
|
18
22
|
```bash
|
|
@@ -20,3 +24,15 @@ dsh plugin --profile web add dsh-cite
|
|
|
20
24
|
```
|
|
21
25
|
|
|
22
26
|
MIT
|
|
27
|
+
|
|
28
|
+
## Uninstall
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
dsh plugin --profile web remove dsh-cite
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Then restart the web service. To clean up fully, also remove the plugin entry from your profile `cordis.patch.yml` if you overrode it.
|
|
35
|
+
|
|
36
|
+
## License
|
|
37
|
+
|
|
38
|
+
MIT (see [LICENSE](LICENSE))
|
package/README.md
CHANGED
|
@@ -11,7 +11,11 @@ DeepSeek Harness 参考文献工具插件:通过 Crossref API 查询文献元
|
|
|
11
11
|
| `cite_lookup` | 查文献元数据(DOI 精确查询 / 题录检索) | `doi` 或 `query` 至少一个;`limit` 1-10 默认 5 |
|
|
12
12
|
| `cite_format` | 生成规范引文 | `doi` 必填;`style`:gb-t-7714 / apa / mla / chicago |
|
|
13
13
|
| `cite_bibtex` | 生成 BibTeX 条目 | `doi` 必填;`key` 可选 |
|
|
14
|
-
| `cite_check` | 从文本提取 DOI
|
|
14
|
+
| `cite_check` | 从文本提取 DOI 并并发校验是否存在(并发 3,保持输入顺序) | `text` 必填;`maxChecks` 1-50 默认 10 |
|
|
15
|
+
|
|
16
|
+
## 兼容性
|
|
17
|
+
|
|
18
|
+
在 `@deepseek-ai/dsh@0.1.1-rc.2` 上验证(2026-08-26)。遵循 cordis 组合包补丁模型(`cordis.patch.yml` + `dsh.bundle.patch`),运行时不 import 任何 `@deepseek-ai/*` 内部模块。
|
|
15
19
|
|
|
16
20
|
## 安装
|
|
17
21
|
|
|
@@ -19,6 +23,15 @@ DeepSeek Harness 参考文献工具插件:通过 Crossref API 查询文献元
|
|
|
19
23
|
dsh plugin --profile web add dsh-cite
|
|
20
24
|
```
|
|
21
25
|
|
|
26
|
+
## 卸载
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
dsh plugin --profile web remove dsh-cite
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
卸载后重启 Web 服务。如需彻底清理,可再手动删除自己 profile `cordis.patch.yml` 中覆盖的插件行。
|
|
33
|
+
|
|
34
|
+
|
|
22
35
|
## 示例
|
|
23
36
|
|
|
24
37
|
```text
|
|
@@ -38,7 +51,8 @@ Agent:
|
|
|
38
51
|
- id: cite
|
|
39
52
|
name: 'dsh-cite'
|
|
40
53
|
config:
|
|
41
|
-
timeoutMs: 15000 # Crossref
|
|
54
|
+
timeoutMs: 15000 # Crossref 请求超时(也可用 DSH_CITE_TIMEOUT_MS)
|
|
55
|
+
# userAgent: ... # 自定义 User-Agent(也可用 DSH_CITE_USER_AGENT)
|
|
42
56
|
userAgent: '' # 自定义 UA(建议带上可联系邮箱)
|
|
43
57
|
```
|
|
44
58
|
|
|
@@ -51,7 +65,10 @@ Agent:
|
|
|
51
65
|
## 开发
|
|
52
66
|
|
|
53
67
|
```bash
|
|
54
|
-
pnpm test # 构建 +
|
|
68
|
+
pnpm test # 构建 + 18 个测试
|
|
55
69
|
```
|
|
56
70
|
|
|
57
71
|
MIT
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
MIT(见 [LICENSE](LICENSE))
|
package/lib/config.d.ts
CHANGED
|
@@ -11,7 +11,9 @@ export interface ResolvedCiteConfig {
|
|
|
11
11
|
timeoutMs: number;
|
|
12
12
|
userAgent: string;
|
|
13
13
|
}
|
|
14
|
-
export declare
|
|
14
|
+
export declare const CITE_TIMEOUT_ENV = "DSH_CITE_TIMEOUT_MS";
|
|
15
|
+
export declare const CITE_USER_AGENT_ENV = "DSH_CITE_USER_AGENT";
|
|
16
|
+
export declare function resolveConfig(config: CiteConfig | undefined | null, env?: NodeJS.ProcessEnv): ResolvedCiteConfig;
|
|
15
17
|
export declare function optionalString(args: Record<string, unknown>, key: string): string | undefined;
|
|
16
18
|
export declare function requiredString(args: Record<string, unknown>, key: string, label: string): string;
|
|
17
19
|
export declare function optionalInteger(args: Record<string, unknown>, key: string, label: string, lo: number, hi: number, fallback: number): number;
|
package/lib/config.js
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
* @module dsh-cite/config
|
|
5
5
|
*/
|
|
6
6
|
const DEFAULT_TIMEOUT_MS = 15000;
|
|
7
|
-
const DEFAULT_USER_AGENT = 'dsh-cite/0.
|
|
8
|
-
export
|
|
7
|
+
const DEFAULT_USER_AGENT = 'dsh-cite/0.2.0 (DeepSeek Harness citation plugin; mailto:STARDUSTLC666@users.noreply.github.com)';
|
|
8
|
+
export const CITE_TIMEOUT_ENV = 'DSH_CITE_TIMEOUT_MS';
|
|
9
|
+
export const CITE_USER_AGENT_ENV = 'DSH_CITE_USER_AGENT';
|
|
10
|
+
export function resolveConfig(config, env = process.env) {
|
|
9
11
|
const cfg = config ?? {};
|
|
10
12
|
let timeoutMs = DEFAULT_TIMEOUT_MS;
|
|
11
13
|
if (cfg.timeoutMs !== undefined) {
|
|
@@ -14,7 +16,13 @@ export function resolveConfig(config) {
|
|
|
14
16
|
}
|
|
15
17
|
timeoutMs = Math.min(120000, Math.max(2000, Math.round(cfg.timeoutMs)));
|
|
16
18
|
}
|
|
17
|
-
|
|
19
|
+
else if (env[CITE_TIMEOUT_ENV]?.trim()) {
|
|
20
|
+
const parsed = Number(env[CITE_TIMEOUT_ENV].trim());
|
|
21
|
+
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
22
|
+
throw new Error(CITE_TIMEOUT_ENV + ' 必须是大于 0 的数字(毫秒)。');
|
|
23
|
+
timeoutMs = Math.min(120000, Math.max(2000, Math.round(parsed)));
|
|
24
|
+
}
|
|
25
|
+
const userAgent = typeof cfg.userAgent === 'string' && cfg.userAgent.trim() !== '' ? cfg.userAgent.trim() : (env[CITE_USER_AGENT_ENV]?.trim() || DEFAULT_USER_AGENT);
|
|
18
26
|
return { timeoutMs, userAgent };
|
|
19
27
|
}
|
|
20
28
|
export function optionalString(args, key) {
|
package/lib/crossref.d.ts
CHANGED
package/lib/crossref.js
CHANGED
|
@@ -52,6 +52,7 @@ function normalizeWork(raw) {
|
|
|
52
52
|
containerTitle: firstText(raw['container-title']),
|
|
53
53
|
publisher: typeof raw.publisher === 'string' ? raw.publisher.trim() : '',
|
|
54
54
|
year: year || 0,
|
|
55
|
+
language: typeof raw.language === 'string' ? raw.language.trim().toLowerCase() : '',
|
|
55
56
|
volume: typeof raw.volume === 'string' ? raw.volume.trim() : '',
|
|
56
57
|
issue: typeof raw.issue === 'string' ? raw.issue.trim() : '',
|
|
57
58
|
page: typeof raw.page === 'string' ? raw.page.trim() : '',
|
|
@@ -134,7 +135,7 @@ export function extractDois(text) {
|
|
|
134
135
|
const seen = new Set();
|
|
135
136
|
const result = [];
|
|
136
137
|
for (const match of text.match(pattern) ?? []) {
|
|
137
|
-
const clean = match.replace(/[
|
|
138
|
+
const clean = match.replace(/[.,;:)\]}'">]+$/, '').trim();
|
|
138
139
|
if (seen.has(clean.toLowerCase()))
|
|
139
140
|
continue;
|
|
140
141
|
seen.add(clean.toLowerCase());
|
package/lib/format.js
CHANGED
|
@@ -26,7 +26,7 @@ function initials(given) {
|
|
|
26
26
|
}
|
|
27
27
|
function apaName(author) {
|
|
28
28
|
const family = author.family !== '' ? author.family : (author.name !== '' ? author.name : author.given);
|
|
29
|
-
const initialsText = author.given !== '' ? initials(author.given) :
|
|
29
|
+
const initialsText = author.given !== '' ? initials(author.given) : '';
|
|
30
30
|
return initialsText !== '' ? family + ', ' + initialsText : family;
|
|
31
31
|
}
|
|
32
32
|
function mlaName(author, first) {
|
|
@@ -52,7 +52,9 @@ function apaAuthors(authors) {
|
|
|
52
52
|
return names[0];
|
|
53
53
|
if (names.length === 2)
|
|
54
54
|
return names[0] + ', & ' + names[1];
|
|
55
|
-
|
|
55
|
+
if (names.length <= 20)
|
|
56
|
+
return names.slice(0, -1).join(', ') + ', & ' + names[names.length - 1];
|
|
57
|
+
return names.slice(0, 19).join(', ') + ', ... ' + names[names.length - 1];
|
|
56
58
|
}
|
|
57
59
|
function mlaAuthors(authors) {
|
|
58
60
|
if (authors.length === 0)
|
|
@@ -201,7 +203,26 @@ export function buildCitation(work, style, lang = 'zh') {
|
|
|
201
203
|
}
|
|
202
204
|
}
|
|
203
205
|
function escapeLatex(value) {
|
|
204
|
-
return value.replace(/
|
|
206
|
+
return value.replace(/[\\{}&%$#_~^]/g, (ch) => {
|
|
207
|
+
switch (ch) {
|
|
208
|
+
case '\\': return '\\textbackslash{}';
|
|
209
|
+
case '{': return '\\{';
|
|
210
|
+
case '}': return '\\}';
|
|
211
|
+
case '&': return '\\&';
|
|
212
|
+
case '%': return '\\%';
|
|
213
|
+
case '$': return '\\$';
|
|
214
|
+
case '#': return '\\#';
|
|
215
|
+
case '_': return '\\_';
|
|
216
|
+
case '~': return '\\textasciitilde{}';
|
|
217
|
+
case '^': return '\\textasciicircum{}';
|
|
218
|
+
default: return ch;
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/** BibTeX 引用键只允许安全字符,空格/逗号/花括号等替换为下划线。 */
|
|
223
|
+
function sanitizeBibtexKey(value) {
|
|
224
|
+
const cleaned = value.replace(/[^A-Za-z0-9_.:\/-]+/g, '_').replace(/^_+|_+$/g, '');
|
|
225
|
+
return cleaned === '' ? 'work' : cleaned;
|
|
205
226
|
}
|
|
206
227
|
function bibtexType(work) {
|
|
207
228
|
switch (work.type) {
|
|
@@ -220,7 +241,7 @@ function bibtexType(work) {
|
|
|
220
241
|
export function buildBibtex(work, key) {
|
|
221
242
|
const first = work.authors[0];
|
|
222
243
|
const firstWord = titleOf(work).split(/[^\p{L}\p{N}]+/u).find((part) => part !== '') ?? 'work';
|
|
223
|
-
const baseKey = key !== undefined && key.trim() !== '' ? key.trim() : ((first?.family ?? first?.name ?? 'author') + yearText(work) + firstWord).toLowerCase();
|
|
244
|
+
const baseKey = key !== undefined && key.trim() !== '' ? sanitizeBibtexKey(key.trim()) : ((first?.family ?? first?.name ?? 'author') + yearText(work) + firstWord).toLowerCase();
|
|
224
245
|
const type = bibtexType(work);
|
|
225
246
|
const fields = [];
|
|
226
247
|
const authors = work.authors.map((author) => fullName(author)).join(' and ');
|
package/lib/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { type CiteConfig } from './config.js';
|
|
11
11
|
import { type CiteToolDefinition } from './tools.js';
|
|
12
12
|
/** cordis 服务注入:apply 里要用 ctx.tools。 */
|
|
13
|
+
export declare const name = "cite";
|
|
13
14
|
export declare const inject: string[];
|
|
14
15
|
export interface CitePluginContext {
|
|
15
16
|
tools: {
|
package/lib/index.js
CHANGED
package/lib/tools.js
CHANGED
|
@@ -39,6 +39,7 @@ const workSchema = {
|
|
|
39
39
|
containerTitle: { type: 'string' },
|
|
40
40
|
publisher: { type: 'string' },
|
|
41
41
|
year: { type: 'integer' },
|
|
42
|
+
language: { type: 'string' },
|
|
42
43
|
volume: { type: 'string' },
|
|
43
44
|
issue: { type: 'string' },
|
|
44
45
|
page: { type: 'string' },
|
|
@@ -72,6 +73,22 @@ const checkSchema = {
|
|
|
72
73
|
properties: { count: { type: 'integer' }, results: { type: 'array', items: checkItemSchema } },
|
|
73
74
|
additionalProperties: true,
|
|
74
75
|
};
|
|
76
|
+
/** 以固定并发度执行异步任务并保持原顺序。 */
|
|
77
|
+
async function mapWithConcurrency(items, concurrency, fn) {
|
|
78
|
+
const results = new Array(items.length);
|
|
79
|
+
let next = 0;
|
|
80
|
+
const workers = Array.from({ length: Math.min(concurrency, items.length) }, async () => {
|
|
81
|
+
while (true) {
|
|
82
|
+
const index = next;
|
|
83
|
+
next += 1;
|
|
84
|
+
if (index >= items.length)
|
|
85
|
+
return;
|
|
86
|
+
results[index] = await fn(items[index], index);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
await Promise.all(workers);
|
|
90
|
+
return results;
|
|
91
|
+
}
|
|
75
92
|
function workLabel(work) {
|
|
76
93
|
const title = work.title !== '' ? work.title : '(无标题)';
|
|
77
94
|
return title + '(' + (work.year > 0 ? work.year + ', ' : '') + (work.containerTitle !== '' ? work.containerTitle : work.publisher) + ')';
|
|
@@ -100,6 +117,11 @@ export function buildCiteTools(cfg, fetchImpl) {
|
|
|
100
117
|
const work = await lookupDoi(doi, cfg, fetchImpl);
|
|
101
118
|
return { count: 1, works: [work] };
|
|
102
119
|
}
|
|
120
|
+
const queryDoi = extractDois(query)[0];
|
|
121
|
+
if (queryDoi !== undefined) {
|
|
122
|
+
const work = await lookupDoi(queryDoi, cfg, fetchImpl);
|
|
123
|
+
return { count: 1, works: [work], matchedDoi: queryDoi };
|
|
124
|
+
}
|
|
103
125
|
const limit = optionalInteger(args, 'limit', '返回条数', 1, 10, 5);
|
|
104
126
|
const works = await searchWorks(query, limit, cfg, fetchImpl);
|
|
105
127
|
if (works.length === 0)
|
|
@@ -172,19 +194,62 @@ export function buildCiteTools(cfg, fetchImpl) {
|
|
|
172
194
|
const text = requiredString(args, 'text', '待检查文本');
|
|
173
195
|
const maxChecks = optionalInteger(args, 'maxChecks', '校验数量', 1, 50, 10);
|
|
174
196
|
const dois = extractDois(text).slice(0, maxChecks);
|
|
175
|
-
const results =
|
|
176
|
-
for (const doi of dois) {
|
|
197
|
+
const results = await mapWithConcurrency(dois, 3, async (doi) => {
|
|
177
198
|
try {
|
|
178
199
|
const work = await lookupDoi(doi, cfg, fetchImpl);
|
|
179
|
-
|
|
200
|
+
return { doi, ok: true, title: work.title, url: work.url };
|
|
180
201
|
}
|
|
181
202
|
catch (error) {
|
|
182
|
-
|
|
203
|
+
return { doi, ok: false, title: '', url: '', error: error instanceof Error ? error.message : String(error) };
|
|
183
204
|
}
|
|
184
|
-
}
|
|
205
|
+
});
|
|
185
206
|
return { count: results.length, results };
|
|
186
207
|
},
|
|
187
208
|
timeoutMs: cfg.timeoutMs * 3 + 5000,
|
|
188
209
|
};
|
|
189
|
-
|
|
210
|
+
const citeHealth = {
|
|
211
|
+
name: 'cite_health',
|
|
212
|
+
description: 'dsh-cite 自检:向 Crossref API 发一个最小请求验证连通性(rows=1),报告延迟。遇到问题时先运行本工具定位。',
|
|
213
|
+
parameters: compileParameters({}),
|
|
214
|
+
output: {
|
|
215
|
+
schema: { type: 'object', additionalProperties: true },
|
|
216
|
+
render: (_args, value) => {
|
|
217
|
+
const rec = (value ?? {});
|
|
218
|
+
const rawChecks = Array.isArray(rec.checks) ? rec.checks : [];
|
|
219
|
+
const checks = rawChecks.map((item) => (item ?? {}));
|
|
220
|
+
const lines = ['dsh-cite 自检' + (rec.ok === true ? ':正常。' : ':发现问题。')];
|
|
221
|
+
for (const c of checks) {
|
|
222
|
+
lines.push('- ' + c.name + ':' + (c.ok === true ? '✅' : '❌ ' + String(c.detail ?? '')));
|
|
223
|
+
}
|
|
224
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
async execute() {
|
|
228
|
+
const checks = [];
|
|
229
|
+
let ok = true;
|
|
230
|
+
const startedAt = Date.now();
|
|
231
|
+
try {
|
|
232
|
+
const fetcher = fetchImpl ?? globalThis.fetch;
|
|
233
|
+
const response = await fetcher('https://api.crossref.org/works?rows=1&select=DOI', {
|
|
234
|
+
headers: { 'user-agent': cfg.userAgent },
|
|
235
|
+
signal: AbortSignal.timeout(Math.min(cfg.timeoutMs, 15000)),
|
|
236
|
+
});
|
|
237
|
+
if (response.ok) {
|
|
238
|
+
checks.push({ name: 'Crossref API', ok: true, detail: 'HTTP ' + response.status + ',' + (Date.now() - startedAt) + 'ms' });
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
ok = false;
|
|
242
|
+
checks.push({ name: 'Crossref API', ok: false, detail: 'HTTP ' + response.status });
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
ok = false;
|
|
247
|
+
checks.push({ name: 'Crossref API', ok: false, detail: (error instanceof Error ? error.message : String(error)) + '(网络需要特殊代理时请配置系统代理后重启)' });
|
|
248
|
+
}
|
|
249
|
+
checks.push({ name: '请求配置', ok: true, detail: 'timeoutMs=' + cfg.timeoutMs + ',UA 已配置' });
|
|
250
|
+
return { ok, plugin: 'dsh-cite', checks };
|
|
251
|
+
},
|
|
252
|
+
timeoutMs: Math.min(cfg.timeoutMs + 5000, 30000),
|
|
253
|
+
};
|
|
254
|
+
return [citeLookup, citeFormat, citeBibtex, citeCheck, citeHealth];
|
|
190
255
|
}
|
package/package.json
CHANGED
|
@@ -1,64 +1,63 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dsh-cite",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "DSH 参考文献工具插件:cite_lookup/cite_format/cite_bibtex/cite_check 四工具,Crossref
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "lib/index.js",
|
|
7
|
-
"types": "lib/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./lib/index.d.ts",
|
|
11
|
-
"default": "./lib/index.js"
|
|
12
|
-
},
|
|
13
|
-
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
14
|
-
"./package.json": "./package.json"
|
|
15
|
-
},
|
|
16
|
-
"files": [
|
|
17
|
-
"lib",
|
|
18
|
-
"cordis.patch.yml",
|
|
19
|
-
"README.md",
|
|
20
|
-
"README.en.md"
|
|
21
|
-
],
|
|
22
|
-
"scripts": {
|
|
23
|
-
"build": "tsc -p tsconfig.json",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-cite",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "DSH 参考文献工具插件:cite_lookup/cite_format/cite_bibtex/cite_check 四工具,Crossref 元数据查询(含 DOI 精确解析与并发校验),GB/T 7714 / APA / MLA / Chicago 格式化,零运行时依赖。",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/index.d.ts",
|
|
11
|
+
"default": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"lib",
|
|
18
|
+
"cordis.patch.yml",
|
|
19
|
+
"README.md",
|
|
20
|
+
"README.en.md"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc -p tsconfig.json",
|
|
24
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
25
|
+
"test": "pnpm run build && node --test \"test/*.test.mjs\"",
|
|
26
|
+
"prepublishOnly": "pnpm run build"
|
|
27
|
+
},
|
|
28
|
+
"dsh": {
|
|
29
|
+
"bundle": {
|
|
30
|
+
"patch": "./cordis.patch.yml"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"dsh",
|
|
35
|
+
"deepseek-harness",
|
|
36
|
+
"plugin",
|
|
37
|
+
"citation",
|
|
38
|
+
"crossref",
|
|
39
|
+
"gb-t-7714",
|
|
40
|
+
"apa",
|
|
41
|
+
"mla",
|
|
42
|
+
"chicago",
|
|
43
|
+
"dsh-plugin"
|
|
44
|
+
],
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=22"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^24.0.0",
|
|
51
|
+
"typescript": "^5.6.0"
|
|
52
|
+
},
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "git+https://github.com/STARDUSTLC666/dsh-cite.git"
|
|
56
|
+
},
|
|
57
|
+
"bugs": {
|
|
58
|
+
"url": "https://github.com/STARDUSTLC666/dsh-cite/issues"
|
|
59
|
+
},
|
|
60
|
+
"homepage": "https://github.com/STARDUSTLC666/dsh-cite#readme",
|
|
61
|
+
"author": "stardustlc",
|
|
62
|
+
"packageManager": "pnpm@11.7.0"
|
|
63
|
+
}
|