docrev 0.8.1 → 0.8.5
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/.claude/settings.local.json +9 -0
- package/PLAN-tables-and-postprocess.md +850 -0
- package/README.md +33 -0
- package/bin/rev.js +12 -131
- package/bin/rev.ts +145 -0
- package/dist/bin/rev.d.ts +9 -0
- package/dist/bin/rev.d.ts.map +1 -0
- package/dist/bin/rev.js +118 -0
- package/dist/bin/rev.js.map +1 -0
- package/dist/lib/annotations.d.ts +91 -0
- package/dist/lib/annotations.d.ts.map +1 -0
- package/dist/lib/annotations.js +554 -0
- package/dist/lib/annotations.js.map +1 -0
- package/dist/lib/build.d.ts +171 -0
- package/dist/lib/build.d.ts.map +1 -0
- package/dist/lib/build.js +755 -0
- package/dist/lib/build.js.map +1 -0
- package/dist/lib/citations.d.ts +34 -0
- package/dist/lib/citations.d.ts.map +1 -0
- package/dist/lib/citations.js +140 -0
- package/dist/lib/citations.js.map +1 -0
- package/dist/lib/commands/build.d.ts +13 -0
- package/dist/lib/commands/build.d.ts.map +1 -0
- package/dist/lib/commands/build.js +678 -0
- package/dist/lib/commands/build.js.map +1 -0
- package/dist/lib/commands/citations.d.ts +11 -0
- package/dist/lib/commands/citations.d.ts.map +1 -0
- package/dist/lib/commands/citations.js +428 -0
- package/dist/lib/commands/citations.js.map +1 -0
- package/dist/lib/commands/comments.d.ts +11 -0
- package/dist/lib/commands/comments.d.ts.map +1 -0
- package/dist/lib/commands/comments.js +883 -0
- package/dist/lib/commands/comments.js.map +1 -0
- package/dist/lib/commands/context.d.ts +35 -0
- package/dist/lib/commands/context.d.ts.map +1 -0
- package/dist/lib/commands/context.js +59 -0
- package/dist/lib/commands/context.js.map +1 -0
- package/dist/lib/commands/core.d.ts +11 -0
- package/dist/lib/commands/core.d.ts.map +1 -0
- package/dist/lib/commands/core.js +246 -0
- package/dist/lib/commands/core.js.map +1 -0
- package/dist/lib/commands/doi.d.ts +11 -0
- package/dist/lib/commands/doi.d.ts.map +1 -0
- package/dist/lib/commands/doi.js +373 -0
- package/dist/lib/commands/doi.js.map +1 -0
- package/dist/lib/commands/history.d.ts +11 -0
- package/dist/lib/commands/history.d.ts.map +1 -0
- package/dist/lib/commands/history.js +245 -0
- package/dist/lib/commands/history.js.map +1 -0
- package/dist/lib/commands/index.d.ts +28 -0
- package/dist/lib/commands/index.d.ts.map +1 -0
- package/dist/lib/commands/index.js +35 -0
- package/dist/lib/commands/index.js.map +1 -0
- package/dist/lib/commands/init.d.ts +11 -0
- package/dist/lib/commands/init.d.ts.map +1 -0
- package/dist/lib/commands/init.js +209 -0
- package/dist/lib/commands/init.js.map +1 -0
- package/dist/lib/commands/response.d.ts +11 -0
- package/dist/lib/commands/response.d.ts.map +1 -0
- package/dist/lib/commands/response.js +317 -0
- package/dist/lib/commands/response.js.map +1 -0
- package/dist/lib/commands/sections.d.ts +11 -0
- package/dist/lib/commands/sections.d.ts.map +1 -0
- package/dist/lib/commands/sections.js +1071 -0
- package/dist/lib/commands/sections.js.map +1 -0
- package/dist/lib/commands/utilities.d.ts +19 -0
- package/dist/lib/commands/utilities.d.ts.map +1 -0
- package/dist/lib/commands/utilities.js +2009 -0
- package/dist/lib/commands/utilities.js.map +1 -0
- package/dist/lib/comment-realign.d.ts +50 -0
- package/dist/lib/comment-realign.d.ts.map +1 -0
- package/dist/lib/comment-realign.js +372 -0
- package/dist/lib/comment-realign.js.map +1 -0
- package/dist/lib/config.d.ts +41 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +76 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/crossref.d.ts +108 -0
- package/dist/lib/crossref.d.ts.map +1 -0
- package/dist/lib/crossref.js +597 -0
- package/dist/lib/crossref.js.map +1 -0
- package/dist/lib/dependencies.d.ts +30 -0
- package/dist/lib/dependencies.d.ts.map +1 -0
- package/dist/lib/dependencies.js +95 -0
- package/dist/lib/dependencies.js.map +1 -0
- package/dist/lib/doi-cache.d.ts +29 -0
- package/dist/lib/doi-cache.d.ts.map +1 -0
- package/dist/lib/doi-cache.js +104 -0
- package/dist/lib/doi-cache.js.map +1 -0
- package/dist/lib/doi.d.ts +65 -0
- package/dist/lib/doi.d.ts.map +1 -0
- package/dist/lib/doi.js +710 -0
- package/dist/lib/doi.js.map +1 -0
- package/dist/lib/equations.d.ts +61 -0
- package/dist/lib/equations.d.ts.map +1 -0
- package/dist/lib/equations.js +445 -0
- package/dist/lib/equations.js.map +1 -0
- package/dist/lib/errors.d.ts +60 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +303 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/format.d.ts +104 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +416 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/git.d.ts +88 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +304 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/grammar.d.ts +62 -0
- package/dist/lib/grammar.d.ts.map +1 -0
- package/dist/lib/grammar.js +244 -0
- package/dist/lib/grammar.js.map +1 -0
- package/dist/lib/image-registry.d.ts +68 -0
- package/dist/lib/image-registry.d.ts.map +1 -0
- package/dist/lib/image-registry.js +112 -0
- package/dist/lib/image-registry.js.map +1 -0
- package/dist/lib/import.d.ts +184 -0
- package/dist/lib/import.d.ts.map +1 -0
- package/dist/lib/import.js +1581 -0
- package/dist/lib/import.js.map +1 -0
- package/dist/lib/journals.d.ts +55 -0
- package/dist/lib/journals.d.ts.map +1 -0
- package/dist/lib/journals.js +417 -0
- package/dist/lib/journals.js.map +1 -0
- package/dist/lib/merge.d.ts +138 -0
- package/dist/lib/merge.d.ts.map +1 -0
- package/dist/lib/merge.js +603 -0
- package/dist/lib/merge.js.map +1 -0
- package/dist/lib/orcid.d.ts +36 -0
- package/dist/lib/orcid.d.ts.map +1 -0
- package/dist/lib/orcid.js +117 -0
- package/dist/lib/orcid.js.map +1 -0
- package/dist/lib/pdf-comments.d.ts +95 -0
- package/dist/lib/pdf-comments.d.ts.map +1 -0
- package/dist/lib/pdf-comments.js +192 -0
- package/dist/lib/pdf-comments.js.map +1 -0
- package/dist/lib/pdf-import.d.ts +118 -0
- package/dist/lib/pdf-import.d.ts.map +1 -0
- package/dist/lib/pdf-import.js +397 -0
- package/dist/lib/pdf-import.js.map +1 -0
- package/dist/lib/plugins.d.ts +76 -0
- package/dist/lib/plugins.d.ts.map +1 -0
- package/dist/lib/plugins.js +235 -0
- package/dist/lib/plugins.js.map +1 -0
- package/dist/lib/postprocess.d.ts +42 -0
- package/dist/lib/postprocess.d.ts.map +1 -0
- package/dist/lib/postprocess.js +138 -0
- package/dist/lib/postprocess.js.map +1 -0
- package/dist/lib/pptx-template.d.ts +59 -0
- package/dist/lib/pptx-template.d.ts.map +1 -0
- package/dist/lib/pptx-template.js +613 -0
- package/dist/lib/pptx-template.js.map +1 -0
- package/dist/lib/pptx-themes.d.ts +80 -0
- package/dist/lib/pptx-themes.d.ts.map +1 -0
- package/dist/lib/pptx-themes.js +818 -0
- package/dist/lib/pptx-themes.js.map +1 -0
- package/dist/lib/protect-restore.d.ts +137 -0
- package/dist/lib/protect-restore.d.ts.map +1 -0
- package/dist/lib/protect-restore.js +394 -0
- package/dist/lib/protect-restore.js.map +1 -0
- package/dist/lib/rate-limiter.d.ts +27 -0
- package/dist/lib/rate-limiter.d.ts.map +1 -0
- package/dist/lib/rate-limiter.js +79 -0
- package/dist/lib/rate-limiter.js.map +1 -0
- package/dist/lib/response.d.ts +41 -0
- package/dist/lib/response.d.ts.map +1 -0
- package/dist/lib/response.js +150 -0
- package/dist/lib/response.js.map +1 -0
- package/dist/lib/review.d.ts +35 -0
- package/dist/lib/review.d.ts.map +1 -0
- package/dist/lib/review.js +263 -0
- package/dist/lib/review.js.map +1 -0
- package/dist/lib/schema.d.ts +66 -0
- package/dist/lib/schema.d.ts.map +1 -0
- package/dist/lib/schema.js +339 -0
- package/dist/lib/schema.js.map +1 -0
- package/dist/lib/scientific-words.d.ts +6 -0
- package/dist/lib/scientific-words.d.ts.map +1 -0
- package/dist/lib/scientific-words.js +66 -0
- package/dist/lib/scientific-words.js.map +1 -0
- package/dist/lib/sections.d.ts +40 -0
- package/dist/lib/sections.d.ts.map +1 -0
- package/dist/lib/sections.js +288 -0
- package/dist/lib/sections.js.map +1 -0
- package/dist/lib/slides.d.ts +86 -0
- package/dist/lib/slides.d.ts.map +1 -0
- package/dist/lib/slides.js +676 -0
- package/dist/lib/slides.js.map +1 -0
- package/dist/lib/spelling.d.ts +76 -0
- package/dist/lib/spelling.d.ts.map +1 -0
- package/dist/lib/spelling.js +272 -0
- package/dist/lib/spelling.js.map +1 -0
- package/dist/lib/templates.d.ts +30 -0
- package/dist/lib/templates.d.ts.map +1 -0
- package/dist/lib/templates.js +504 -0
- package/dist/lib/templates.js.map +1 -0
- package/dist/lib/themes.d.ts +85 -0
- package/dist/lib/themes.d.ts.map +1 -0
- package/dist/lib/themes.js +652 -0
- package/dist/lib/themes.js.map +1 -0
- package/dist/lib/trackchanges.d.ts +51 -0
- package/dist/lib/trackchanges.d.ts.map +1 -0
- package/dist/lib/trackchanges.js +202 -0
- package/dist/lib/trackchanges.js.map +1 -0
- package/dist/lib/tui.d.ts +76 -0
- package/dist/lib/tui.d.ts.map +1 -0
- package/dist/lib/tui.js +377 -0
- package/dist/lib/tui.js.map +1 -0
- package/dist/lib/types.d.ts +447 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +6 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/undo.d.ts +57 -0
- package/dist/lib/undo.d.ts.map +1 -0
- package/dist/lib/undo.js +185 -0
- package/dist/lib/undo.js.map +1 -0
- package/dist/lib/utils.d.ts +16 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +40 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/variables.d.ts +42 -0
- package/dist/lib/variables.d.ts.map +1 -0
- package/dist/lib/variables.js +141 -0
- package/dist/lib/variables.js.map +1 -0
- package/dist/lib/word.d.ts +80 -0
- package/dist/lib/word.d.ts.map +1 -0
- package/dist/lib/word.js +360 -0
- package/dist/lib/word.js.map +1 -0
- package/dist/lib/wordcomments.d.ts +51 -0
- package/dist/lib/wordcomments.d.ts.map +1 -0
- package/dist/lib/wordcomments.js +587 -0
- package/dist/lib/wordcomments.js.map +1 -0
- package/eslint.config.js +27 -0
- package/lib/annotations.ts +622 -0
- package/lib/apply-buildup-colors.py +88 -0
- package/lib/build.ts +1013 -0
- package/lib/{citations.js → citations.ts} +38 -27
- package/lib/commands/{build.js → build.ts} +80 -27
- package/lib/commands/{citations.js → citations.ts} +36 -18
- package/lib/commands/{comments.js → comments.ts} +187 -54
- package/lib/commands/{context.js → context.ts} +18 -8
- package/lib/commands/{core.js → core.ts} +34 -20
- package/lib/commands/{doi.js → doi.ts} +32 -16
- package/lib/commands/{history.js → history.ts} +25 -12
- package/lib/commands/{index.js → index.ts} +9 -5
- package/lib/commands/{init.js → init.ts} +20 -8
- package/lib/commands/{response.js → response.ts} +47 -20
- package/lib/commands/{sections.js → sections.ts} +273 -68
- package/lib/commands/{utilities.js → utilities.ts} +338 -158
- package/lib/{comment-realign.js → comment-realign.ts} +117 -45
- package/lib/config.ts +84 -0
- package/lib/{crossref.js → crossref.ts} +213 -138
- package/lib/dependencies.ts +106 -0
- package/lib/doi-cache.ts +115 -0
- package/lib/{doi.js → doi.ts} +115 -281
- package/lib/{equations.js → equations.ts} +60 -64
- package/lib/{errors.js → errors.ts} +56 -48
- package/lib/{format.js → format.ts} +137 -63
- package/lib/{git.js → git.ts} +66 -63
- package/lib/{grammar.js → grammar.ts} +45 -32
- package/lib/image-registry.ts +180 -0
- package/lib/import.ts +2060 -0
- package/lib/journals.ts +505 -0
- package/lib/{merge.js → merge.ts} +185 -135
- package/lib/{orcid.js → orcid.ts} +17 -22
- package/lib/{pdf-comments.js → pdf-comments.ts} +76 -18
- package/lib/{pdf-import.js → pdf-import.ts} +148 -70
- package/lib/{plugins.js → plugins.ts} +82 -39
- package/lib/postprocess.ts +188 -0
- package/lib/pptx-color-filter.lua +37 -0
- package/lib/pptx-template.ts +625 -0
- package/lib/pptx-themes/academic.pptx +0 -0
- package/lib/pptx-themes/corporate.pptx +0 -0
- package/lib/pptx-themes/dark.pptx +0 -0
- package/lib/pptx-themes/default.pptx +0 -0
- package/lib/pptx-themes/minimal.pptx +0 -0
- package/lib/pptx-themes/plant.pptx +0 -0
- package/lib/pptx-themes.ts +896 -0
- package/lib/protect-restore.ts +516 -0
- package/lib/rate-limiter.ts +94 -0
- package/lib/{response.js → response.ts} +36 -21
- package/lib/{review.js → review.ts} +53 -43
- package/lib/{schema.js → schema.ts} +70 -25
- package/lib/{sections.js → sections.ts} +71 -76
- package/lib/slides.ts +793 -0
- package/lib/{spelling.js → spelling.ts} +43 -59
- package/lib/{templates.js → templates.ts} +20 -17
- package/lib/themes.ts +742 -0
- package/lib/{trackchanges.js → trackchanges.ts} +52 -23
- package/lib/types.ts +509 -0
- package/lib/{undo.js → undo.ts} +75 -52
- package/lib/utils.ts +41 -0
- package/lib/{variables.js → variables.ts} +60 -54
- package/lib/word.ts +428 -0
- package/lib/{wordcomments.js → wordcomments.ts} +94 -40
- package/package.json +15 -5
- package/skill/REFERENCE.md +67 -0
- package/tsconfig.json +26 -0
- package/lib/annotations.js +0 -414
- package/lib/build.js +0 -639
- package/lib/config.js +0 -79
- package/lib/import.js +0 -1145
- package/lib/journals.js +0 -629
- package/lib/word.js +0 -225
- /package/lib/{scientific-words.js → scientific-words.ts} +0 -0
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Basic annotation operations for track changes workflow.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { Command } from 'commander';
|
|
8
|
+
import type { Comment } from '../types.js';
|
|
7
9
|
import {
|
|
8
10
|
chalk,
|
|
9
11
|
fs,
|
|
@@ -23,11 +25,15 @@ import {
|
|
|
23
25
|
requireFile,
|
|
24
26
|
} from './context.js';
|
|
25
27
|
|
|
28
|
+
interface StripOptions {
|
|
29
|
+
output?: string;
|
|
30
|
+
keepComments?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
/**
|
|
27
34
|
* Register core commands with the program
|
|
28
|
-
* @param {import('commander').Command} program
|
|
29
35
|
*/
|
|
30
|
-
export function register(program) {
|
|
36
|
+
export function register(program: Command): void {
|
|
31
37
|
// ==========================================================================
|
|
32
38
|
// REVIEW command - Interactive track change review
|
|
33
39
|
// ==========================================================================
|
|
@@ -36,7 +42,7 @@ export function register(program) {
|
|
|
36
42
|
.command('review')
|
|
37
43
|
.description('Interactively review and accept/reject track changes')
|
|
38
44
|
.argument('<file>', 'Markdown file to review')
|
|
39
|
-
.action(async (file) => {
|
|
45
|
+
.action(async (file: string) => {
|
|
40
46
|
requireFile(file, 'Markdown file');
|
|
41
47
|
|
|
42
48
|
const text = fs.readFileSync(file, 'utf-8');
|
|
@@ -72,7 +78,7 @@ export function register(program) {
|
|
|
72
78
|
.argument('<file>', 'Markdown file to strip')
|
|
73
79
|
.option('-o, --output <file>', 'Output file (default: stdout)')
|
|
74
80
|
.option('-c, --keep-comments', 'Keep comment annotations')
|
|
75
|
-
.action((file, options) => {
|
|
81
|
+
.action((file: string, options: StripOptions) => {
|
|
76
82
|
requireFile(file, 'Markdown file');
|
|
77
83
|
|
|
78
84
|
const text = fs.readFileSync(file, 'utf-8');
|
|
@@ -95,7 +101,7 @@ export function register(program) {
|
|
|
95
101
|
.alias('s')
|
|
96
102
|
.description('Show project overview or file annotation statistics')
|
|
97
103
|
.argument('[file]', 'Markdown file to analyze (default: project overview)')
|
|
98
|
-
.action(async (file) => {
|
|
104
|
+
.action(async (file?: string) => {
|
|
99
105
|
// If a specific file is given, show its annotations
|
|
100
106
|
if (file) {
|
|
101
107
|
if (!fs.existsSync(file)) {
|
|
@@ -114,7 +120,7 @@ export function register(program) {
|
|
|
114
120
|
jsonOutput({
|
|
115
121
|
file: path.basename(file),
|
|
116
122
|
annotations: counts,
|
|
117
|
-
comments: comments.map(c => ({
|
|
123
|
+
comments: comments.map((c) => ({
|
|
118
124
|
author: c.author || null,
|
|
119
125
|
content: c.content,
|
|
120
126
|
line: c.line,
|
|
@@ -133,12 +139,12 @@ export function register(program) {
|
|
|
133
139
|
console.log();
|
|
134
140
|
|
|
135
141
|
// Build stats table
|
|
136
|
-
const rows = [];
|
|
137
|
-
if (counts.inserts > 0) rows.push([chalk.green('+'), 'Insertions', chalk.green(counts.inserts)]);
|
|
138
|
-
if (counts.deletes > 0) rows.push([chalk.red('-'), 'Deletions', chalk.red(counts.deletes)]);
|
|
139
|
-
if (counts.substitutes > 0) rows.push([chalk.yellow('~'), 'Substitutions', chalk.yellow(counts.substitutes)]);
|
|
140
|
-
if (counts.comments > 0) rows.push([chalk.blue('#'), 'Comments', chalk.blue(counts.comments)]);
|
|
141
|
-
rows.push([chalk.dim('Σ'), chalk.dim('Total'), chalk.dim(counts.total)]);
|
|
142
|
+
const rows: string[][] = [];
|
|
143
|
+
if (counts.inserts > 0) rows.push([chalk.green('+'), 'Insertions', chalk.green(counts.inserts.toString())]);
|
|
144
|
+
if (counts.deletes > 0) rows.push([chalk.red('-'), 'Deletions', chalk.red(counts.deletes.toString())]);
|
|
145
|
+
if (counts.substitutes > 0) rows.push([chalk.yellow('~'), 'Substitutions', chalk.yellow(counts.substitutes.toString())]);
|
|
146
|
+
if (counts.comments > 0) rows.push([chalk.blue('#'), 'Comments', chalk.blue(counts.comments.toString())]);
|
|
147
|
+
rows.push([chalk.dim('Σ'), chalk.dim('Total'), chalk.dim(counts.total.toString())]);
|
|
142
148
|
|
|
143
149
|
console.log(fmt.table(['', 'Type', 'Count'], rows, { align: ['center', 'left', 'right'] }));
|
|
144
150
|
|
|
@@ -148,8 +154,8 @@ export function register(program) {
|
|
|
148
154
|
console.log(fmt.header('Comments'));
|
|
149
155
|
console.log();
|
|
150
156
|
|
|
151
|
-
const commentRows = comments.map((c, i) => [
|
|
152
|
-
chalk.dim(i + 1),
|
|
157
|
+
const commentRows = comments.map((c, i: number) => [
|
|
158
|
+
chalk.dim((i + 1).toString()),
|
|
153
159
|
c.author ? chalk.blue(c.author) : chalk.dim('Anonymous'),
|
|
154
160
|
c.content.length > 45 ? c.content.slice(0, 45) + '...' : c.content,
|
|
155
161
|
chalk.dim(`L${c.line}`),
|
|
@@ -181,13 +187,21 @@ export function register(program) {
|
|
|
181
187
|
let totalInserts = 0;
|
|
182
188
|
let totalDeletes = 0;
|
|
183
189
|
let totalSubstitutes = 0;
|
|
184
|
-
const fileStats
|
|
190
|
+
const fileStats: Array<{
|
|
191
|
+
file: string;
|
|
192
|
+
words: number;
|
|
193
|
+
inserts: number;
|
|
194
|
+
deletes: number;
|
|
195
|
+
substitutions: number;
|
|
196
|
+
comments: number;
|
|
197
|
+
pending: number;
|
|
198
|
+
}> = [];
|
|
185
199
|
|
|
186
200
|
for (const f of mdFiles) {
|
|
187
201
|
const text = fs.readFileSync(f, 'utf-8');
|
|
188
202
|
const counts = countAnnotations(text);
|
|
189
203
|
const comments = getComments(text);
|
|
190
|
-
const pending = comments.filter(c =>
|
|
204
|
+
const pending = comments.filter((c) => c.resolved === false).length;
|
|
191
205
|
|
|
192
206
|
// Simple word count (excluding annotations)
|
|
193
207
|
const stripped = stripAnnotations(text);
|
|
@@ -219,7 +233,7 @@ export function register(program) {
|
|
|
219
233
|
const latestDocx = docxFiles.length > 0
|
|
220
234
|
? docxFiles
|
|
221
235
|
.map(f => ({ name: f, mtime: fs.statSync(f).mtime }))
|
|
222
|
-
.sort((a, b) => b.mtime - a.mtime)[0]
|
|
236
|
+
.sort((a, b) => b.mtime.getTime() - a.mtime.getTime())[0]
|
|
223
237
|
: null;
|
|
224
238
|
|
|
225
239
|
jsonOutput({
|
|
@@ -246,7 +260,7 @@ export function register(program) {
|
|
|
246
260
|
console.log(` ${chalk.bold(totalWords.toLocaleString())} words across ${mdFiles.length} files`);
|
|
247
261
|
|
|
248
262
|
if (totalComments > 0) {
|
|
249
|
-
console.log(` ${chalk.blue(totalComments)} comments (${chalk.yellow(pendingComments)} pending)`);
|
|
263
|
+
console.log(` ${chalk.blue(totalComments.toString())} comments (${chalk.yellow(pendingComments.toString())} pending)`);
|
|
250
264
|
}
|
|
251
265
|
|
|
252
266
|
const totalChanges = totalInserts + totalDeletes + totalSubstitutes;
|
|
@@ -265,7 +279,7 @@ export function register(program) {
|
|
|
265
279
|
f.inserts > 0 ? chalk.green(`+${f.inserts}`) : chalk.dim('-'),
|
|
266
280
|
f.deletes > 0 ? chalk.red(`-${f.deletes}`) : chalk.dim('-'),
|
|
267
281
|
f.substitutions > 0 ? chalk.yellow(`~${f.substitutions}`) : chalk.dim('-'),
|
|
268
|
-
f.pending > 0 ? chalk.yellow(f.pending) : (f.comments > 0 ? chalk.dim(f.comments) : chalk.dim('-')),
|
|
282
|
+
f.pending > 0 ? chalk.yellow(f.pending.toString()) : (f.comments > 0 ? chalk.dim(f.comments.toString()) : chalk.dim('-')),
|
|
269
283
|
]);
|
|
270
284
|
|
|
271
285
|
if (rows.length > 0) {
|
|
@@ -282,7 +296,7 @@ export function register(program) {
|
|
|
282
296
|
if (docxFiles.length > 0) {
|
|
283
297
|
const sorted = docxFiles
|
|
284
298
|
.map(f => ({ name: f, mtime: fs.statSync(f).mtime }))
|
|
285
|
-
.sort((a, b) => b.mtime - a.mtime);
|
|
299
|
+
.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
286
300
|
const latest = sorted[0];
|
|
287
301
|
const age = Date.now() - latest.mtime.getTime();
|
|
288
302
|
const ageStr = age < 3600000 ? `${Math.round(age / 60000)}m ago` :
|
|
@@ -10,12 +10,24 @@ import {
|
|
|
10
10
|
path,
|
|
11
11
|
fmt,
|
|
12
12
|
} from './context.js';
|
|
13
|
+
import type { Command } from 'commander';
|
|
14
|
+
|
|
15
|
+
interface DoiOptions {
|
|
16
|
+
bib: string;
|
|
17
|
+
strict?: boolean;
|
|
18
|
+
resolve?: boolean;
|
|
19
|
+
confidence: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface OrcidOptions {
|
|
23
|
+
yaml?: boolean;
|
|
24
|
+
badge?: boolean;
|
|
25
|
+
}
|
|
13
26
|
|
|
14
27
|
/**
|
|
15
28
|
* Register DOI commands with the program
|
|
16
|
-
* @param {import('commander').Command} program
|
|
17
29
|
*/
|
|
18
|
-
export function register(program) {
|
|
30
|
+
export function register(program: Command): void {
|
|
19
31
|
// ==========================================================================
|
|
20
32
|
// DOI command - Validate and fetch DOIs
|
|
21
33
|
// ==========================================================================
|
|
@@ -29,7 +41,7 @@ export function register(program) {
|
|
|
29
41
|
.option('--strict', 'Fail on missing DOIs for articles')
|
|
30
42
|
.option('--no-resolve', 'Only check format, skip resolution check')
|
|
31
43
|
.option('--confidence <level>', 'Minimum confidence: high, medium, low (default: medium)', 'medium')
|
|
32
|
-
.action(async (action, input, options) => {
|
|
44
|
+
.action(async (action: string, input: string | undefined, options: DoiOptions) => {
|
|
33
45
|
const { parseBibEntries, checkBibDois, fetchBibtex, addToBib, isValidDoiFormat, lookupDoi, lookupMissingDois } = await import('../doi.js');
|
|
34
46
|
|
|
35
47
|
if (action === 'check') {
|
|
@@ -59,7 +71,7 @@ export function register(program) {
|
|
|
59
71
|
const skipped = results.entries.filter(e => e.status === 'skipped');
|
|
60
72
|
|
|
61
73
|
// Summary table
|
|
62
|
-
const summaryRows = [
|
|
74
|
+
const summaryRows: string[][] = [
|
|
63
75
|
[chalk.green('Valid'), chalk.green(valid.length.toString())],
|
|
64
76
|
[invalid.length > 0 ? chalk.red('Invalid') : 'Invalid', invalid.length > 0 ? chalk.red(invalid.length.toString()) : '0'],
|
|
65
77
|
[missing.length > 0 ? chalk.yellow('Missing (articles)') : 'Missing', missing.length > 0 ? chalk.yellow(missing.length.toString()) : '0'],
|
|
@@ -126,7 +138,8 @@ export function register(program) {
|
|
|
126
138
|
|
|
127
139
|
} catch (err) {
|
|
128
140
|
spin.stop();
|
|
129
|
-
|
|
141
|
+
const error = err as Error;
|
|
142
|
+
console.error(fmt.status('error', error.message));
|
|
130
143
|
process.exit(1);
|
|
131
144
|
}
|
|
132
145
|
|
|
@@ -147,11 +160,12 @@ export function register(program) {
|
|
|
147
160
|
console.log();
|
|
148
161
|
console.log(result.bibtex);
|
|
149
162
|
} else {
|
|
150
|
-
spin.error(result.error);
|
|
163
|
+
spin.error(result.error!);
|
|
151
164
|
process.exit(1);
|
|
152
165
|
}
|
|
153
166
|
} catch (err) {
|
|
154
|
-
|
|
167
|
+
const error = err as Error;
|
|
168
|
+
spin.error(error.message);
|
|
155
169
|
process.exit(1);
|
|
156
170
|
}
|
|
157
171
|
|
|
@@ -169,20 +183,21 @@ export function register(program) {
|
|
|
169
183
|
const fetchResult = await fetchBibtex(input);
|
|
170
184
|
|
|
171
185
|
if (!fetchResult.success) {
|
|
172
|
-
spin.error(fetchResult.error);
|
|
186
|
+
spin.error(fetchResult.error!);
|
|
173
187
|
process.exit(1);
|
|
174
188
|
}
|
|
175
189
|
|
|
176
|
-
const addResult = addToBib(bibPath, fetchResult.bibtex);
|
|
190
|
+
const addResult = addToBib(bibPath, fetchResult.bibtex!);
|
|
177
191
|
|
|
178
192
|
if (addResult.success) {
|
|
179
193
|
spin.success(`Added @${addResult.key} to ${bibPath}`);
|
|
180
194
|
} else {
|
|
181
|
-
spin.error(addResult.error);
|
|
195
|
+
spin.error(addResult.error!);
|
|
182
196
|
process.exit(1);
|
|
183
197
|
}
|
|
184
198
|
} catch (err) {
|
|
185
|
-
|
|
199
|
+
const error = err as Error;
|
|
200
|
+
spin.error(error.message);
|
|
186
201
|
process.exit(1);
|
|
187
202
|
}
|
|
188
203
|
|
|
@@ -210,7 +225,7 @@ export function register(program) {
|
|
|
210
225
|
let found = 0;
|
|
211
226
|
let notFound = 0;
|
|
212
227
|
let lowConfidence = 0;
|
|
213
|
-
const results = [];
|
|
228
|
+
const results: Array<{ entry: any; result: any; status: string }> = [];
|
|
214
229
|
|
|
215
230
|
for (let i = 0; i < missing.length; i++) {
|
|
216
231
|
const entry = missing[i];
|
|
@@ -268,7 +283,7 @@ export function register(program) {
|
|
|
268
283
|
|
|
269
284
|
// Filter by confidence level
|
|
270
285
|
const confLevel = options.confidence || 'medium';
|
|
271
|
-
const confLevels = { high: 3, medium: 2, low: 1 };
|
|
286
|
+
const confLevels: Record<string, number> = { high: 3, medium: 2, low: 1 };
|
|
272
287
|
const minConf = confLevels[confLevel] || 2;
|
|
273
288
|
|
|
274
289
|
const filteredResults = results.filter(r => {
|
|
@@ -304,7 +319,7 @@ export function register(program) {
|
|
|
304
319
|
console.log(chalk.cyan(` DOI: ${result.doi}`));
|
|
305
320
|
|
|
306
321
|
if (result.metadata?.journal) {
|
|
307
|
-
let yearDisplay;
|
|
322
|
+
let yearDisplay: string;
|
|
308
323
|
if (yearExact) {
|
|
309
324
|
yearDisplay = chalk.green(`(${foundYear})`);
|
|
310
325
|
} else if (yearClose) {
|
|
@@ -368,7 +383,7 @@ export function register(program) {
|
|
|
368
383
|
.argument('<orcid>', 'ORCID iD (e.g., 0000-0002-1825-0097)')
|
|
369
384
|
.option('--yaml', 'Output as YAML for rev.yaml authors section')
|
|
370
385
|
.option('--badge', 'Output markdown badge')
|
|
371
|
-
.action(async (orcidInput, options) => {
|
|
386
|
+
.action(async (orcidInput: string, options: OrcidOptions) => {
|
|
372
387
|
const { fetchOrcidProfile, fetchOrcidWorkCount, formatAuthorYaml, getOrcidBadge, cleanOrcid, isValidOrcid } = await import('../orcid.js');
|
|
373
388
|
|
|
374
389
|
const orcid = cleanOrcid(orcidInput);
|
|
@@ -412,7 +427,8 @@ export function register(program) {
|
|
|
412
427
|
console.log(chalk.dim(' Use --yaml to output for rev.yaml authors section'));
|
|
413
428
|
console.log(chalk.dim(' Use --badge to get markdown badge'));
|
|
414
429
|
} catch (err) {
|
|
415
|
-
|
|
430
|
+
const error = err as Error;
|
|
431
|
+
console.error(fmt.status('error', error.message));
|
|
416
432
|
process.exit(1);
|
|
417
433
|
}
|
|
418
434
|
});
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Commands for git-based revision tracking and author statistics.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { Command } from 'commander';
|
|
7
8
|
import {
|
|
8
9
|
chalk,
|
|
9
10
|
fs,
|
|
@@ -12,11 +13,23 @@ import {
|
|
|
12
13
|
loadBuildConfig,
|
|
13
14
|
} from './context.js';
|
|
14
15
|
|
|
16
|
+
interface DiffOptions {
|
|
17
|
+
files?: string;
|
|
18
|
+
stat?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface HistoryOptions {
|
|
22
|
+
limit: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface ContributorsOptions {
|
|
26
|
+
blame?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
15
29
|
/**
|
|
16
30
|
* Register history commands with the program
|
|
17
|
-
* @param {import('commander').Command} program
|
|
18
31
|
*/
|
|
19
|
-
export function register(program) {
|
|
32
|
+
export function register(program: Command): void {
|
|
20
33
|
// ==========================================================================
|
|
21
34
|
// DIFF command - Compare sections against git history
|
|
22
35
|
// ==========================================================================
|
|
@@ -27,7 +40,7 @@ export function register(program) {
|
|
|
27
40
|
.argument('[ref]', 'Git reference to compare against (default: main/master)')
|
|
28
41
|
.option('-f, --files <files>', 'Specific files to compare (comma-separated)')
|
|
29
42
|
.option('--stat', 'Show only statistics, not full diff')
|
|
30
|
-
.action(async (ref, options) => {
|
|
43
|
+
.action(async (ref: string | undefined, options: DiffOptions) => {
|
|
31
44
|
const {
|
|
32
45
|
isGitRepo,
|
|
33
46
|
getDefaultBranch,
|
|
@@ -50,7 +63,7 @@ export function register(program) {
|
|
|
50
63
|
console.log();
|
|
51
64
|
|
|
52
65
|
// Get files to compare
|
|
53
|
-
let filesToCompare;
|
|
66
|
+
let filesToCompare: string[];
|
|
54
67
|
if (options.files) {
|
|
55
68
|
filesToCompare = options.files.split(',').map(f => f.trim());
|
|
56
69
|
} else {
|
|
@@ -73,7 +86,7 @@ export function register(program) {
|
|
|
73
86
|
const { total, byFile } = getWordCountDiff(filesToCompare, compareRef);
|
|
74
87
|
|
|
75
88
|
// Show results
|
|
76
|
-
const rows = [];
|
|
89
|
+
const rows: string[][] = [];
|
|
77
90
|
for (const file of filesToCompare) {
|
|
78
91
|
const stats = byFile[file];
|
|
79
92
|
if (stats && (stats.added > 0 || stats.removed > 0)) {
|
|
@@ -115,10 +128,10 @@ export function register(program) {
|
|
|
115
128
|
console.log(chalk.dim(' ...'));
|
|
116
129
|
break;
|
|
117
130
|
}
|
|
118
|
-
const preview = change.
|
|
119
|
-
if (change.
|
|
131
|
+
const preview = change.value.slice(0, 60).replace(/\n/g, ' ');
|
|
132
|
+
if (change.added) {
|
|
120
133
|
console.log(chalk.green(` + "${preview}..."`));
|
|
121
|
-
} else {
|
|
134
|
+
} else if (change.removed) {
|
|
122
135
|
console.log(chalk.red(` - "${preview}..."`));
|
|
123
136
|
}
|
|
124
137
|
shown++;
|
|
@@ -137,7 +150,7 @@ export function register(program) {
|
|
|
137
150
|
.description('Show revision history for section files')
|
|
138
151
|
.argument('[file]', 'Specific file (default: all sections)')
|
|
139
152
|
.option('-n, --limit <count>', 'Number of commits to show', '10')
|
|
140
|
-
.action(async (file, options) => {
|
|
153
|
+
.action(async (file: string | undefined, options: HistoryOptions) => {
|
|
141
154
|
const {
|
|
142
155
|
isGitRepo,
|
|
143
156
|
getFileHistory,
|
|
@@ -209,7 +222,7 @@ export function register(program) {
|
|
|
209
222
|
.description('Show author contributions across section files')
|
|
210
223
|
.argument('[file]', 'Specific file (default: all sections)')
|
|
211
224
|
.option('--blame', 'Show detailed line-by-line blame for a file')
|
|
212
|
-
.action(async (file, options) => {
|
|
225
|
+
.action(async (file: string | undefined, options: ContributorsOptions) => {
|
|
213
226
|
const { isGitRepo, getAuthorStats, getContributors, getFileBlame } = await import('../git.js');
|
|
214
227
|
|
|
215
228
|
if (!isGitRepo()) {
|
|
@@ -262,9 +275,9 @@ export function register(program) {
|
|
|
262
275
|
}
|
|
263
276
|
} else {
|
|
264
277
|
// Show contributors across all sections
|
|
265
|
-
let config = {};
|
|
278
|
+
let config: { sections?: string[] } = {};
|
|
266
279
|
try {
|
|
267
|
-
config = loadBuildConfig() || {};
|
|
280
|
+
config = loadBuildConfig(process.cwd()) || {};
|
|
268
281
|
} catch {
|
|
269
282
|
// Not in a rev project
|
|
270
283
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Each module's register() function adds commands to the Commander program.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import type { Command } from 'commander';
|
|
8
9
|
import { register as registerCoreCommands } from './core.js';
|
|
9
10
|
import { register as registerCommentCommands } from './comments.js';
|
|
10
11
|
import { register as registerInitCommands } from './init.js';
|
|
@@ -37,20 +38,23 @@ export {
|
|
|
37
38
|
jsonMode,
|
|
38
39
|
} from './context.js';
|
|
39
40
|
|
|
41
|
+
interface PackageJson {
|
|
42
|
+
version?: string;
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
|
|
40
46
|
/**
|
|
41
47
|
* Register all command modules with the program.
|
|
42
|
-
* @param {import('commander').Command} program
|
|
43
|
-
* @param {object} [pkg] - Package.json object for version info (optional)
|
|
44
48
|
*/
|
|
45
|
-
export function registerAllCommands(program, pkg) {
|
|
49
|
+
export function registerAllCommands(program: Command, pkg?: PackageJson): void {
|
|
46
50
|
registerCoreCommands(program);
|
|
47
51
|
registerCommentCommands(program);
|
|
48
52
|
registerInitCommands(program);
|
|
49
53
|
registerSectionCommands(program);
|
|
50
|
-
registerBuildCommands(program, pkg);
|
|
54
|
+
registerBuildCommands(program, pkg || {});
|
|
51
55
|
registerResponseCommands(program);
|
|
52
56
|
registerCitationCommands(program);
|
|
53
57
|
registerDoiCommands(program);
|
|
54
58
|
registerHistoryCommands(program);
|
|
55
|
-
registerUtilityCommands(program, pkg);
|
|
59
|
+
registerUtilityCommands(program, pkg || {});
|
|
56
60
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Project initialization and configuration commands.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { Command } from 'commander';
|
|
7
8
|
import {
|
|
8
9
|
chalk,
|
|
9
10
|
fs,
|
|
@@ -22,11 +23,22 @@ import {
|
|
|
22
23
|
setDefaultSections,
|
|
23
24
|
} from './context.js';
|
|
24
25
|
|
|
26
|
+
interface InitOptions {
|
|
27
|
+
dir: string;
|
|
28
|
+
output: string;
|
|
29
|
+
force?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface NewOptions {
|
|
33
|
+
template: string;
|
|
34
|
+
sections?: string;
|
|
35
|
+
list?: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
/**
|
|
26
39
|
* Register init commands with the program
|
|
27
|
-
* @param {import('commander').Command} program
|
|
28
40
|
*/
|
|
29
|
-
export function register(program) {
|
|
41
|
+
export function register(program: Command): void {
|
|
30
42
|
// ==========================================================================
|
|
31
43
|
// INIT command - Generate sections.yaml config
|
|
32
44
|
// ==========================================================================
|
|
@@ -37,7 +49,7 @@ export function register(program) {
|
|
|
37
49
|
.option('-d, --dir <directory>', 'Directory to scan', '.')
|
|
38
50
|
.option('-o, --output <file>', 'Output config file', 'sections.yaml')
|
|
39
51
|
.option('--force', 'Overwrite existing config')
|
|
40
|
-
.action((options) => {
|
|
52
|
+
.action((options: InitOptions) => {
|
|
41
53
|
const dir = path.resolve(options.dir);
|
|
42
54
|
|
|
43
55
|
if (!fs.existsSync(dir)) {
|
|
@@ -70,7 +82,7 @@ export function register(program) {
|
|
|
70
82
|
for (const [file, section] of Object.entries(config.sections)) {
|
|
71
83
|
console.log(` ${chalk.bold(file)}`);
|
|
72
84
|
console.log(chalk.dim(` header: "${section.header}"`));
|
|
73
|
-
if (section.aliases
|
|
85
|
+
if (section.aliases && section.aliases.length > 0) {
|
|
74
86
|
console.log(chalk.dim(` aliases: ${JSON.stringify(section.aliases)}`));
|
|
75
87
|
}
|
|
76
88
|
}
|
|
@@ -92,7 +104,7 @@ export function register(program) {
|
|
|
92
104
|
.option('-t, --template <name>', 'Template: paper, minimal, thesis, review', 'paper')
|
|
93
105
|
.option('-s, --sections <sections>', 'Comma-separated section names (e.g., intro,methods,results)')
|
|
94
106
|
.option('--list', 'List available templates')
|
|
95
|
-
.action(async (name, options) => {
|
|
107
|
+
.action(async (name: string | undefined, options: NewOptions) => {
|
|
96
108
|
if (options.list) {
|
|
97
109
|
console.log(chalk.cyan('Available templates:\n'));
|
|
98
110
|
for (const t of listTemplates()) {
|
|
@@ -115,7 +127,7 @@ export function register(program) {
|
|
|
115
127
|
}
|
|
116
128
|
|
|
117
129
|
let template;
|
|
118
|
-
let sections = null;
|
|
130
|
+
let sections: string[] | null = null;
|
|
119
131
|
|
|
120
132
|
// Determine sections: CLI option > user config > prompt
|
|
121
133
|
if (options.sections) {
|
|
@@ -138,7 +150,7 @@ export function register(program) {
|
|
|
138
150
|
output: process.stdout,
|
|
139
151
|
});
|
|
140
152
|
|
|
141
|
-
const ask = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
|
|
153
|
+
const ask = (prompt: string): Promise<string> => new Promise((resolve) => rl.question(prompt, resolve));
|
|
142
154
|
|
|
143
155
|
console.log(chalk.cyan('Enter your document sections (comma-separated):'));
|
|
144
156
|
console.log(chalk.dim(' Example: introduction,methods,results,discussion'));
|
|
@@ -207,7 +219,7 @@ export function register(program) {
|
|
|
207
219
|
.description('Set user preferences')
|
|
208
220
|
.argument('<key>', 'Config key: user, sections')
|
|
209
221
|
.argument('[value]', 'Value to set')
|
|
210
|
-
.action((key, value) => {
|
|
222
|
+
.action((key: string, value?: string) => {
|
|
211
223
|
if (key === 'user') {
|
|
212
224
|
if (value) {
|
|
213
225
|
setUserName(value);
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Commands for generating reviewer responses and validating manuscripts.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { Command } from 'commander';
|
|
7
8
|
import {
|
|
8
9
|
chalk,
|
|
9
10
|
fs,
|
|
@@ -15,11 +16,35 @@ import {
|
|
|
15
16
|
getUserName,
|
|
16
17
|
} from './context.js';
|
|
17
18
|
|
|
19
|
+
interface ResponseOptions {
|
|
20
|
+
output?: string;
|
|
21
|
+
author?: string;
|
|
22
|
+
context?: boolean;
|
|
23
|
+
location?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface ValidateOptions {
|
|
27
|
+
journal?: string;
|
|
28
|
+
list?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface ProfilesOptions {
|
|
32
|
+
list?: boolean;
|
|
33
|
+
new?: string;
|
|
34
|
+
project?: boolean;
|
|
35
|
+
dirs?: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface AnonymizeOptions {
|
|
39
|
+
output?: string;
|
|
40
|
+
authors?: string;
|
|
41
|
+
dryRun?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
18
44
|
/**
|
|
19
45
|
* Register response commands with the program
|
|
20
|
-
* @param {import('commander').Command} program
|
|
21
46
|
*/
|
|
22
|
-
export function register(program) {
|
|
47
|
+
export function register(program: Command): void {
|
|
23
48
|
// ==========================================================================
|
|
24
49
|
// RESPONSE command - Generate response letter for reviewers
|
|
25
50
|
// ==========================================================================
|
|
@@ -32,7 +57,7 @@ export function register(program) {
|
|
|
32
57
|
.option('-a, --author <name>', 'Author name for identifying replies')
|
|
33
58
|
.option('--no-context', 'Omit context snippets')
|
|
34
59
|
.option('--no-location', 'Omit file:line references')
|
|
35
|
-
.action(async (files, options) => {
|
|
60
|
+
.action(async (files: string[] | undefined, options: ResponseOptions) => {
|
|
36
61
|
let mdFiles = files;
|
|
37
62
|
if (!mdFiles || mdFiles.length === 0) {
|
|
38
63
|
const allFiles = fs.readdirSync('.').filter(f =>
|
|
@@ -74,7 +99,7 @@ export function register(program) {
|
|
|
74
99
|
console.log(fmt.header('Response Letter Generated'));
|
|
75
100
|
console.log();
|
|
76
101
|
|
|
77
|
-
const rows = reviewers.map(r => [r, grouped.get(r)
|
|
102
|
+
const rows = reviewers.map(r => [r, grouped.get(r)!.length.toString()]);
|
|
78
103
|
console.log(fmt.table(['Reviewer', 'Comments'], rows));
|
|
79
104
|
console.log();
|
|
80
105
|
console.log(fmt.status('success', `Created ${outputPath}`));
|
|
@@ -90,7 +115,7 @@ export function register(program) {
|
|
|
90
115
|
.argument('[files...]', 'Markdown files to validate (default: all section files)')
|
|
91
116
|
.option('-j, --journal <name>', 'Journal profile (e.g., nature, plos-one, science)')
|
|
92
117
|
.option('--list', 'List available journal profiles')
|
|
93
|
-
.action(async (files, options) => {
|
|
118
|
+
.action(async (files: string[] | undefined, options: ValidateOptions) => {
|
|
94
119
|
const { listJournals, validateProject, getJournalProfile } = await import('../journals.js');
|
|
95
120
|
|
|
96
121
|
if (options.list) {
|
|
@@ -151,16 +176,18 @@ export function register(program) {
|
|
|
151
176
|
|
|
152
177
|
const result = validateProject(mdFiles, options.journal);
|
|
153
178
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
['
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
179
|
+
if (result.stats) {
|
|
180
|
+
console.log(chalk.cyan('Manuscript Stats:'));
|
|
181
|
+
console.log(fmt.table(['Metric', 'Value'], [
|
|
182
|
+
['Word count', result.stats.wordCount.toString()],
|
|
183
|
+
['Abstract', `${result.stats.abstractWords} words`],
|
|
184
|
+
['Title', `${result.stats.titleChars} chars`],
|
|
185
|
+
['Figures', result.stats.figures.toString()],
|
|
186
|
+
['Tables', result.stats.tables.toString()],
|
|
187
|
+
['References', result.stats.references.toString()],
|
|
188
|
+
]));
|
|
189
|
+
console.log();
|
|
190
|
+
}
|
|
164
191
|
|
|
165
192
|
if (result.errors.length > 0) {
|
|
166
193
|
console.log(chalk.red('Errors:'));
|
|
@@ -197,7 +224,7 @@ export function register(program) {
|
|
|
197
224
|
.option('--new <name>', 'Create a new profile template')
|
|
198
225
|
.option('--project', 'Create profile in project directory (with --new)')
|
|
199
226
|
.option('--dirs', 'Show profile directory locations')
|
|
200
|
-
.action(async (options) => {
|
|
227
|
+
.action(async (options: ProfilesOptions) => {
|
|
201
228
|
const {
|
|
202
229
|
listCustomProfiles,
|
|
203
230
|
saveProfileTemplate,
|
|
@@ -225,7 +252,7 @@ export function register(program) {
|
|
|
225
252
|
console.log(fmt.status('success', `Created profile template: ${filePath}`));
|
|
226
253
|
console.log(chalk.dim('Edit the file to customize journal requirements'));
|
|
227
254
|
} catch (err) {
|
|
228
|
-
console.error(fmt.status('error', err.message));
|
|
255
|
+
console.error(fmt.status('error', (err as Error).message));
|
|
229
256
|
process.exit(1);
|
|
230
257
|
}
|
|
231
258
|
return;
|
|
@@ -272,7 +299,7 @@ export function register(program) {
|
|
|
272
299
|
.option('-o, --output <file>', 'Output file (default: input-anonymous.md)')
|
|
273
300
|
.option('--authors <names>', 'Author names to redact (comma-separated)')
|
|
274
301
|
.option('--dry-run', 'Show what would be changed without writing')
|
|
275
|
-
.action(async (input, options) => {
|
|
302
|
+
.action(async (input: string, options: AnonymizeOptions) => {
|
|
276
303
|
const { default: YAML } = await import('yaml');
|
|
277
304
|
|
|
278
305
|
const isDir = fs.existsSync(input) && fs.statSync(input).isDirectory();
|
|
@@ -287,7 +314,7 @@ export function register(program) {
|
|
|
287
314
|
process.exit(1);
|
|
288
315
|
}
|
|
289
316
|
|
|
290
|
-
let authorNames = [];
|
|
317
|
+
let authorNames: string[] = [];
|
|
291
318
|
if (options.authors) {
|
|
292
319
|
authorNames = options.authors.split(',').map(n => n.trim());
|
|
293
320
|
} else {
|
|
@@ -296,7 +323,7 @@ export function register(program) {
|
|
|
296
323
|
try {
|
|
297
324
|
const config = YAML.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
298
325
|
if (config.authors) {
|
|
299
|
-
authorNames = config.authors.map(a => typeof a === 'string' ? a : a.name).filter(Boolean);
|
|
326
|
+
authorNames = config.authors.map((a: string | { name: string }) => typeof a === 'string' ? a : a.name).filter(Boolean);
|
|
300
327
|
}
|
|
301
328
|
} catch { /* ignore */ }
|
|
302
329
|
}
|