@ncukondo/search-hub 0.17.0 → 0.19.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/cli/commands/query/assess.d.ts +15 -0
- package/dist/cli/commands/query/assess.d.ts.map +1 -0
- package/dist/cli/commands/query/assess.js +38 -0
- package/dist/cli/commands/query/assess.js.map +1 -0
- package/dist/cli/commands/query/iteration-log.d.ts +58 -0
- package/dist/cli/commands/query/iteration-log.d.ts.map +1 -0
- package/dist/cli/commands/query/iteration-log.js +115 -0
- package/dist/cli/commands/query/iteration-log.js.map +1 -0
- package/dist/cli/commands/query/log.d.ts +9 -0
- package/dist/cli/commands/query/log.d.ts.map +1 -0
- package/dist/cli/commands/query/log.js +64 -0
- package/dist/cli/commands/query/log.js.map +1 -0
- package/dist/cli/commands/register.d.ts +1 -1
- package/dist/cli/commands/register.js.map +1 -1
- package/dist/cli/commands/review/finalize.js +6 -6
- package/dist/cli/commands/review/finalize.js.map +1 -1
- package/dist/cli/commands/review/init.d.ts.map +1 -1
- package/dist/cli/commands/review/init.js +5 -21
- package/dist/cli/commands/review/init.js.map +1 -1
- package/dist/cli/commands/review/list.d.ts +1 -1
- package/dist/cli/commands/review/list.d.ts.map +1 -1
- package/dist/cli/commands/review/list.js.map +1 -1
- package/dist/cli/commands/review/next-steps.d.ts +1 -1
- package/dist/cli/commands/review/next-steps.js +3 -3
- package/dist/cli/commands/review/next-steps.js.map +1 -1
- package/dist/cli/commands/review/schema.d.ts +199 -0
- package/dist/cli/commands/review/schema.d.ts.map +1 -0
- package/dist/cli/commands/review/schema.js +77 -0
- package/dist/cli/commands/review/schema.js.map +1 -0
- package/dist/cli/commands/review/status.d.ts +2 -2
- package/dist/cli/commands/review/status.d.ts.map +1 -1
- package/dist/cli/commands/review/status.js +13 -13
- package/dist/cli/commands/review/status.js.map +1 -1
- package/dist/cli/commands/review/types.d.ts +20 -75
- package/dist/cli/commands/review/types.d.ts.map +1 -1
- package/dist/cli/commands/review/types.js +8 -9
- package/dist/cli/commands/review/types.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +78 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/suggestions/rules.d.ts.map +1 -1
- package/dist/cli/suggestions/rules.js +22 -2
- package/dist/cli/suggestions/rules.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/review/list.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAmC,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhF,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,YAAY,GACZ,
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/review/list.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAmC,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhF,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,YAAY,GACZ,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,SAAS,GACT,WAAW,GACX,KAAK,CAAC;AAEV,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAWD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,iBAAiB,EAC1B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAuC3B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAkBjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sources":["../../../../src/cli/commands/review/list.ts"],"sourcesContent":["/**\n * review list command - List articles with optional filtering\n */\n\nimport { join } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport { classifyStatus, type ReviewFile, type ReviewStatus } from './types.js';\n\nexport type ListFilter =\n | 'pending'\n | 'incomplete'\n | 'uncertain'\n | 'agreed-include'\n | 'agreed-exclude'\n | '
|
|
1
|
+
{"version":3,"file":"list.js","sources":["../../../../src/cli/commands/review/list.ts"],"sourcesContent":["/**\n * review list command - List articles with optional filtering\n */\n\nimport { join } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport { classifyStatus, type ReviewFile, type ReviewStatus } from './types.js';\n\nexport type ListFilter =\n | 'pending'\n | 'incomplete'\n | 'all-uncertain'\n | 'agreed-include'\n | 'agreed-exclude'\n | 'divided'\n | 'finalized'\n | 'all';\n\nexport interface ReviewListOptions {\n sessionId: string;\n filter?: ListFilter;\n}\n\nexport interface ArticleListItem {\n title: string;\n pmid?: string;\n doi?: string;\n scopusId?: string;\n arxivId?: string;\n ericId?: string;\n year?: string;\n status: ReviewStatus;\n reviewCount: number;\n finalDecision?: 'include' | 'exclude';\n}\n\nexport interface ReviewListResult {\n sessionId: string;\n filter: ListFilter;\n articles: ArticleListItem[];\n}\n\n/**\n * Load review file from session directory\n */\nasync function loadReviewFile(sessionDir: string): Promise<ReviewFile> {\n const reviewsPath = join(sessionDir, '.internal', 'reviews.yaml');\n const content = await readFile(reviewsPath, 'utf-8');\n return parseYaml(content) as ReviewFile;\n}\n\n/**\n * Execute review list command\n */\nexport async function executeReviewList(\n options: ReviewListOptions,\n sessionsDir: string\n): Promise<ReviewListResult> {\n const sessionDir = join(sessionsDir, options.sessionId);\n const reviewFile = await loadReviewFile(sessionDir);\n const filter = options.filter ?? 'all';\n\n const articles: ArticleListItem[] = [];\n\n const reviewers = reviewFile.reviewers;\n for (const article of reviewFile.articles) {\n const status = classifyStatus(article, reviewers);\n\n // Apply filter\n if (filter !== 'all' && status !== filter) {\n continue;\n }\n\n const item: ArticleListItem = {\n title: article.title,\n status,\n reviewCount: (article.reviews ?? []).length,\n };\n\n // Add optional identifiers\n if (article.pmid) item.pmid = article.pmid;\n if (article.doi) item.doi = article.doi;\n if (article.scopusId) item.scopusId = article.scopusId;\n if (article.arxivId) item.arxivId = article.arxivId;\n if (article.ericId) item.ericId = article.ericId;\n if (article.year) item.year = article.year;\n if (article.finalDecision) item.finalDecision = article.finalDecision;\n\n articles.push(item);\n }\n\n return {\n sessionId: options.sessionId,\n filter,\n articles,\n };\n}\n\n/**\n * Format list result as human-readable string\n */\nexport function formatListOutput(result: ReviewListResult): string {\n if (result.articles.length === 0) {\n return `No articles found matching filter: ${result.filter}`;\n }\n\n const lines: string[] = [];\n lines.push(`${result.articles.length} articles (filter: ${result.filter})`);\n lines.push('');\n\n for (const article of result.articles) {\n const id = article.pmid ?? article.doi ?? article.scopusId ?? article.arxivId ?? article.ericId ?? '-';\n const year = article.year ?? '-';\n const decision = article.finalDecision ? ` [${article.finalDecision}]` : '';\n lines.push(`[${article.status}] ${article.title}`);\n lines.push(` ID: ${id} | Year: ${year} | Reviews: ${article.reviewCount}${decision}`);\n }\n\n return lines.join('\\n');\n}\n"],"names":["parseYaml"],"mappings":";;;;AA8CA,eAAe,eAAe,YAAyC;AACrE,QAAM,cAAc,KAAK,YAAY,aAAa,cAAc;AAChE,QAAM,UAAU,MAAM,SAAS,aAAa,OAAO;AACnD,SAAOA,MAAU,OAAO;AAC1B;AAKA,eAAsB,kBACpB,SACA,aAC2B;AAC3B,QAAM,aAAa,KAAK,aAAa,QAAQ,SAAS;AACtD,QAAM,aAAa,MAAM,eAAe,UAAU;AAClD,QAAM,SAAS,QAAQ,UAAU;AAEjC,QAAM,WAA8B,CAAA;AAEpC,QAAM,YAAY,WAAW;AAC7B,aAAW,WAAW,WAAW,UAAU;AACzC,UAAM,SAAS,eAAe,SAAS,SAAS;AAGhD,QAAI,WAAW,SAAS,WAAW,QAAQ;AACzC;AAAA,IACF;AAEA,UAAM,OAAwB;AAAA,MAC5B,OAAO,QAAQ;AAAA,MACf;AAAA,MACA,cAAc,QAAQ,WAAW,IAAI;AAAA,IAAA;AAIvC,QAAI,QAAQ,KAAM,MAAK,OAAO,QAAQ;AACtC,QAAI,QAAQ,IAAK,MAAK,MAAM,QAAQ;AACpC,QAAI,QAAQ,SAAU,MAAK,WAAW,QAAQ;AAC9C,QAAI,QAAQ,QAAS,MAAK,UAAU,QAAQ;AAC5C,QAAI,QAAQ,OAAQ,MAAK,SAAS,QAAQ;AAC1C,QAAI,QAAQ,KAAM,MAAK,OAAO,QAAQ;AACtC,QAAI,QAAQ,cAAe,MAAK,gBAAgB,QAAQ;AAExD,aAAS,KAAK,IAAI;AAAA,EACpB;AAEA,SAAO;AAAA,IACL,WAAW,QAAQ;AAAA,IACnB;AAAA,IACA;AAAA,EAAA;AAEJ;AAKO,SAAS,iBAAiB,QAAkC;AACjE,MAAI,OAAO,SAAS,WAAW,GAAG;AAChC,WAAO,sCAAsC,OAAO,MAAM;AAAA,EAC5D;AAEA,QAAM,QAAkB,CAAA;AACxB,QAAM,KAAK,GAAG,OAAO,SAAS,MAAM,sBAAsB,OAAO,MAAM,GAAG;AAC1E,QAAM,KAAK,EAAE;AAEb,aAAW,WAAW,OAAO,UAAU;AACrC,UAAM,KAAK,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,YAAY,QAAQ,WAAW,QAAQ,UAAU;AACnG,UAAM,OAAO,QAAQ,QAAQ;AAC7B,UAAM,WAAW,QAAQ,gBAAgB,KAAK,QAAQ,aAAa,MAAM;AACzE,UAAM,KAAK,IAAI,QAAQ,MAAM,KAAK,QAAQ,KAAK,EAAE;AACjD,UAAM,KAAK,SAAS,EAAE,YAAY,IAAI,eAAe,QAAQ,WAAW,GAAG,QAAQ,EAAE;AAAA,EACvF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;"}
|
|
@@ -33,7 +33,7 @@ export declare function computeBatchContinuation(params: BatchContinuationParams
|
|
|
33
33
|
* Evaluation order (top-to-bottom, first match wins for primary suggestion):
|
|
34
34
|
* 1. pending > 0 → extract for title screening
|
|
35
35
|
* 2. agreed > 0 → finalize consensus articles
|
|
36
|
-
* 3. (
|
|
36
|
+
* 3. (divided + allUncertain + incomplete) > 0 → extract for next basis level
|
|
37
37
|
* 4. all finalized → register accepted articles
|
|
38
38
|
*
|
|
39
39
|
* Batch continuation is appended to seeAlso when applicable.
|
|
@@ -30,11 +30,11 @@ function generateReviewNextSteps(ctx) {
|
|
|
30
30
|
command: `search-hub review finalize --session ${sessionId}`,
|
|
31
31
|
description: `Finalize ${agreed} articles with consensus`
|
|
32
32
|
});
|
|
33
|
-
} else if (rs.
|
|
34
|
-
const unresolved = rs.
|
|
33
|
+
} else if (rs.divided > 0 || rs.allUncertain > 0 || rs.incomplete > 0) {
|
|
34
|
+
const unresolved = rs.divided + rs.allUncertain + rs.incomplete;
|
|
35
35
|
const nextBasis = detectNextBasis(rs.reviewers);
|
|
36
36
|
result.next.push({
|
|
37
|
-
command: `search-hub review extract --session ${sessionId} --filter
|
|
37
|
+
command: `search-hub review extract --session ${sessionId} --filter divided,all-uncertain,incomplete --basis ${nextBasis} --reviewer "<name>" --name ${nextBasis}-screening`,
|
|
38
38
|
description: `${unresolved} articles need ${nextBasis}-level review`
|
|
39
39
|
});
|
|
40
40
|
} else if (rs.finalized > 0 && rs.finalized === rs.total) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"next-steps.js","sources":["../../../../src/cli/commands/review/next-steps.ts"],"sourcesContent":["/**\n * Dynamic next steps generation for review workflow.\n * Generates context-aware suggestions based on current article status distribution.\n */\n\nimport type { ReviewStatusResult } from './status.js';\nimport type { ReviewBasis } from './types.js';\nimport type { Suggestion, SuggestionResult } from '../../suggestions/types.js';\n\nexport interface ReviewNextStepsContext {\n sessionId: string;\n statusResult: ReviewStatusResult;\n /** Extract name for batch continuation */\n extractName?: string;\n /** Number of articles extracted in current batch */\n extractedCount?: number;\n /** Total articles matching the filter */\n totalMatching?: number;\n /** Limit used in extract */\n limit?: number;\n /** Offset used in extract */\n offset?: number;\n}\n\nexport interface BatchContinuationParams {\n sessionId: string;\n extractName?: string | undefined;\n extractedCount: number;\n totalMatching: number;\n limit: number;\n offset?: number | undefined;\n}\n\n/**\n * Compute a batch continuation suggestion when --limit was used with remaining articles.\n * Returns null if no remaining articles.\n */\nexport function computeBatchContinuation(params: BatchContinuationParams): Suggestion | null {\n const nextOffset = (params.offset ?? 0) + params.extractedCount;\n const remaining = params.totalMatching - nextOffset;\n if (remaining <= 0) return null;\n\n const nextName = params.extractName ? `${params.extractName}-next` : 'next-batch';\n return {\n command: `search-hub review extract --session ${params.sessionId} --offset ${nextOffset} --limit ${params.limit} --name ${nextName}`,\n description: `${remaining} articles remaining — extract next batch`,\n };\n}\n\n/**\n * Detect the next review basis level from reviewer registry.\n * Progression: title → abstract → fulltext\n */\nfunction detectNextBasis(reviewers: ReviewStatusResult['reviewers']): ReviewBasis {\n const bases = new Set(reviewers.map((r) => r.basis));\n if (!bases.has('title')) return 'title';\n if (!bases.has('abstract')) return 'abstract';\n return 'fulltext';\n}\n\n/**\n * Generate dynamic next steps based on review status distribution.\n *\n * Evaluation order (top-to-bottom, first match wins for primary suggestion):\n * 1. pending > 0 → extract for title screening\n * 2. agreed > 0 → finalize consensus articles\n * 3. (
|
|
1
|
+
{"version":3,"file":"next-steps.js","sources":["../../../../src/cli/commands/review/next-steps.ts"],"sourcesContent":["/**\n * Dynamic next steps generation for review workflow.\n * Generates context-aware suggestions based on current article status distribution.\n */\n\nimport type { ReviewStatusResult } from './status.js';\nimport type { ReviewBasis } from './types.js';\nimport type { Suggestion, SuggestionResult } from '../../suggestions/types.js';\n\nexport interface ReviewNextStepsContext {\n sessionId: string;\n statusResult: ReviewStatusResult;\n /** Extract name for batch continuation */\n extractName?: string;\n /** Number of articles extracted in current batch */\n extractedCount?: number;\n /** Total articles matching the filter */\n totalMatching?: number;\n /** Limit used in extract */\n limit?: number;\n /** Offset used in extract */\n offset?: number;\n}\n\nexport interface BatchContinuationParams {\n sessionId: string;\n extractName?: string | undefined;\n extractedCount: number;\n totalMatching: number;\n limit: number;\n offset?: number | undefined;\n}\n\n/**\n * Compute a batch continuation suggestion when --limit was used with remaining articles.\n * Returns null if no remaining articles.\n */\nexport function computeBatchContinuation(params: BatchContinuationParams): Suggestion | null {\n const nextOffset = (params.offset ?? 0) + params.extractedCount;\n const remaining = params.totalMatching - nextOffset;\n if (remaining <= 0) return null;\n\n const nextName = params.extractName ? `${params.extractName}-next` : 'next-batch';\n return {\n command: `search-hub review extract --session ${params.sessionId} --offset ${nextOffset} --limit ${params.limit} --name ${nextName}`,\n description: `${remaining} articles remaining — extract next batch`,\n };\n}\n\n/**\n * Detect the next review basis level from reviewer registry.\n * Progression: title → abstract → fulltext\n */\nfunction detectNextBasis(reviewers: ReviewStatusResult['reviewers']): ReviewBasis {\n const bases = new Set(reviewers.map((r) => r.basis));\n if (!bases.has('title')) return 'title';\n if (!bases.has('abstract')) return 'abstract';\n return 'fulltext';\n}\n\n/**\n * Generate dynamic next steps based on review status distribution.\n *\n * Evaluation order (top-to-bottom, first match wins for primary suggestion):\n * 1. pending > 0 → extract for title screening\n * 2. agreed > 0 → finalize consensus articles\n * 3. (divided + allUncertain + incomplete) > 0 → extract for next basis level\n * 4. all finalized → register accepted articles\n *\n * Batch continuation is appended to seeAlso when applicable.\n */\nexport function generateReviewNextSteps(ctx: ReviewNextStepsContext): SuggestionResult | null {\n const { sessionId, statusResult: rs } = ctx;\n\n if (rs.total === 0) return null;\n\n const result: SuggestionResult = { next: [], seeAlso: [] };\n\n // 1. pending > 0: title screening incomplete\n if (rs.pending > 0) {\n result.next.push({\n command: `search-hub review extract --session ${sessionId} --basis title --filter pending --reviewer \"<name>\" --name title-screening`,\n description: `Extract ${rs.pending} pending articles for title screening`,\n });\n }\n // 2. agreed > 0: suggest finalization\n else {\n const agreed = rs.agreedInclude + rs.agreedExclude;\n if (agreed > 0) {\n result.next.push({\n command: `search-hub review finalize --session ${sessionId}`,\n description: `Finalize ${agreed} articles with consensus`,\n });\n }\n // 3. divided, all-uncertain, or incomplete > 0: suggest further review\n else if (rs.divided > 0 || rs.allUncertain > 0 || rs.incomplete > 0) {\n const unresolved = rs.divided + rs.allUncertain + rs.incomplete;\n const nextBasis = detectNextBasis(rs.reviewers);\n result.next.push({\n command: `search-hub review extract --session ${sessionId} --filter divided,all-uncertain,incomplete --basis ${nextBasis} --reviewer \"<name>\" --name ${nextBasis}-screening`,\n description: `${unresolved} articles need ${nextBasis}-level review`,\n });\n }\n // 4. All finalized\n else if (rs.finalized > 0 && rs.finalized === rs.total) {\n result.next.push({\n command: `search-hub register ${sessionId} --reviewed`,\n description: 'Register accepted articles',\n });\n }\n // No actionable state\n else {\n return null;\n }\n }\n\n // 5. Batch continuation (appended to seeAlso when applicable)\n if (\n ctx.limit !== undefined &&\n ctx.extractedCount !== undefined &&\n ctx.totalMatching !== undefined\n ) {\n const batch = computeBatchContinuation({\n sessionId,\n extractName: ctx.extractName,\n extractedCount: ctx.extractedCount,\n totalMatching: ctx.totalMatching,\n limit: ctx.limit,\n offset: ctx.offset,\n });\n if (batch) result.seeAlso.push(batch);\n }\n\n return result;\n}\n"],"names":[],"mappings":"AAqCO,SAAS,yBAAyB,QAAoD;AAC3F,QAAM,cAAc,OAAO,UAAU,KAAK,OAAO;AACjD,QAAM,YAAY,OAAO,gBAAgB;AACzC,MAAI,aAAa,EAAG,QAAO;AAE3B,QAAM,WAAW,OAAO,cAAc,GAAG,OAAO,WAAW,UAAU;AACrE,SAAO;AAAA,IACL,SAAS,uCAAuC,OAAO,SAAS,aAAa,UAAU,YAAY,OAAO,KAAK,WAAW,QAAQ;AAAA,IAClI,aAAa,GAAG,SAAS;AAAA,EAAA;AAE7B;AAMA,SAAS,gBAAgB,WAAyD;AAChF,QAAM,QAAQ,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACnD,MAAI,CAAC,MAAM,IAAI,OAAO,EAAG,QAAO;AAChC,MAAI,CAAC,MAAM,IAAI,UAAU,EAAG,QAAO;AACnC,SAAO;AACT;AAaO,SAAS,wBAAwB,KAAsD;AAC5F,QAAM,EAAE,WAAW,cAAc,GAAA,IAAO;AAExC,MAAI,GAAG,UAAU,EAAG,QAAO;AAE3B,QAAM,SAA2B,EAAE,MAAM,CAAA,GAAI,SAAS,CAAA,EAAC;AAGvD,MAAI,GAAG,UAAU,GAAG;AAClB,WAAO,KAAK,KAAK;AAAA,MACf,SAAS,uCAAuC,SAAS;AAAA,MACzD,aAAa,WAAW,GAAG,OAAO;AAAA,IAAA,CACnC;AAAA,EACH,OAEK;AACH,UAAM,SAAS,GAAG,gBAAgB,GAAG;AACrC,QAAI,SAAS,GAAG;AACd,aAAO,KAAK,KAAK;AAAA,QACf,SAAS,wCAAwC,SAAS;AAAA,QAC1D,aAAa,YAAY,MAAM;AAAA,MAAA,CAChC;AAAA,IACH,WAES,GAAG,UAAU,KAAK,GAAG,eAAe,KAAK,GAAG,aAAa,GAAG;AACnE,YAAM,aAAa,GAAG,UAAU,GAAG,eAAe,GAAG;AACrD,YAAM,YAAY,gBAAgB,GAAG,SAAS;AAC9C,aAAO,KAAK,KAAK;AAAA,QACf,SAAS,uCAAuC,SAAS,sDAAsD,SAAS,+BAA+B,SAAS;AAAA,QAChK,aAAa,GAAG,UAAU,kBAAkB,SAAS;AAAA,MAAA,CACtD;AAAA,IACH,WAES,GAAG,YAAY,KAAK,GAAG,cAAc,GAAG,OAAO;AACtD,aAAO,KAAK,KAAK;AAAA,QACf,SAAS,uBAAuB,SAAS;AAAA,QACzC,aAAa;AAAA,MAAA,CACd;AAAA,IACH,OAEK;AACH,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MACE,IAAI,UAAU,UACd,IAAI,mBAAmB,UACvB,IAAI,kBAAkB,QACtB;AACA,UAAM,QAAQ,yBAAyB;AAAA,MACrC;AAAA,MACA,aAAa,IAAI;AAAA,MACjB,gBAAgB,IAAI;AAAA,MACpB,eAAe,IAAI;AAAA,MACnB,OAAO,IAAI;AAAA,MACX,QAAQ,IAAI;AAAA,IAAA,CACb;AACD,QAAI,MAAO,QAAO,QAAQ,KAAK,KAAK;AAAA,EACtC;AAEA,SAAO;AACT;"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schemas for review workflow types.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for:
|
|
5
|
+
* - TypeScript types (via z.infer<>)
|
|
6
|
+
* - JSON Schema for IDE autocompletion (via z.toJSONSchema())
|
|
7
|
+
*
|
|
8
|
+
* Follows the pattern established in src/query/json-schema.ts.
|
|
9
|
+
*/
|
|
10
|
+
import * as z from 'zod';
|
|
11
|
+
export declare const reviewDecisionSchema: z.ZodEnum<{
|
|
12
|
+
exclude: "exclude";
|
|
13
|
+
include: "include";
|
|
14
|
+
uncertain: "uncertain";
|
|
15
|
+
}>;
|
|
16
|
+
export declare const reviewBasisSchema: z.ZodEnum<{
|
|
17
|
+
title: "title";
|
|
18
|
+
abstract: "abstract";
|
|
19
|
+
fulltext: "fulltext";
|
|
20
|
+
}>;
|
|
21
|
+
export declare const reviewSchema: z.ZodObject<{
|
|
22
|
+
reviewer: z.ZodString;
|
|
23
|
+
decision: z.ZodOptional<z.ZodEnum<{
|
|
24
|
+
exclude: "exclude";
|
|
25
|
+
include: "include";
|
|
26
|
+
uncertain: "uncertain";
|
|
27
|
+
}>>;
|
|
28
|
+
basis: z.ZodOptional<z.ZodEnum<{
|
|
29
|
+
title: "title";
|
|
30
|
+
abstract: "abstract";
|
|
31
|
+
fulltext: "fulltext";
|
|
32
|
+
}>>;
|
|
33
|
+
comment: z.ZodOptional<z.ZodString>;
|
|
34
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
35
|
+
}, z.core.$strict>;
|
|
36
|
+
export declare const mergedSourceSchema: z.ZodObject<{
|
|
37
|
+
source: z.ZodString;
|
|
38
|
+
pmid: z.ZodOptional<z.ZodString>;
|
|
39
|
+
doi: z.ZodOptional<z.ZodString>;
|
|
40
|
+
scopusId: z.ZodOptional<z.ZodString>;
|
|
41
|
+
arxivId: z.ZodOptional<z.ZodString>;
|
|
42
|
+
ericId: z.ZodOptional<z.ZodString>;
|
|
43
|
+
}, z.core.$strict>;
|
|
44
|
+
export declare const articleFulltextRefSchema: z.ZodObject<{
|
|
45
|
+
dirName: z.ZodString;
|
|
46
|
+
hasFiles: z.ZodObject<{
|
|
47
|
+
pdf: z.ZodBoolean;
|
|
48
|
+
xml: z.ZodBoolean;
|
|
49
|
+
html: z.ZodBoolean;
|
|
50
|
+
markdown: z.ZodBoolean;
|
|
51
|
+
}, z.core.$strict>;
|
|
52
|
+
}, z.core.$strict>;
|
|
53
|
+
export declare const articleEntrySchema: z.ZodObject<{
|
|
54
|
+
doi: z.ZodOptional<z.ZodString>;
|
|
55
|
+
pmid: z.ZodOptional<z.ZodString>;
|
|
56
|
+
scopusId: z.ZodOptional<z.ZodString>;
|
|
57
|
+
arxivId: z.ZodOptional<z.ZodString>;
|
|
58
|
+
ericId: z.ZodOptional<z.ZodString>;
|
|
59
|
+
title: z.ZodString;
|
|
60
|
+
authors: z.ZodOptional<z.ZodString>;
|
|
61
|
+
year: z.ZodOptional<z.ZodString>;
|
|
62
|
+
abstract: z.ZodOptional<z.ZodString>;
|
|
63
|
+
mergedFrom: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
64
|
+
source: z.ZodString;
|
|
65
|
+
pmid: z.ZodOptional<z.ZodString>;
|
|
66
|
+
doi: z.ZodOptional<z.ZodString>;
|
|
67
|
+
scopusId: z.ZodOptional<z.ZodString>;
|
|
68
|
+
arxivId: z.ZodOptional<z.ZodString>;
|
|
69
|
+
ericId: z.ZodOptional<z.ZodString>;
|
|
70
|
+
}, z.core.$strict>>>;
|
|
71
|
+
reviews: z.ZodArray<z.ZodObject<{
|
|
72
|
+
reviewer: z.ZodString;
|
|
73
|
+
decision: z.ZodOptional<z.ZodEnum<{
|
|
74
|
+
exclude: "exclude";
|
|
75
|
+
include: "include";
|
|
76
|
+
uncertain: "uncertain";
|
|
77
|
+
}>>;
|
|
78
|
+
basis: z.ZodOptional<z.ZodEnum<{
|
|
79
|
+
title: "title";
|
|
80
|
+
abstract: "abstract";
|
|
81
|
+
fulltext: "fulltext";
|
|
82
|
+
}>>;
|
|
83
|
+
comment: z.ZodOptional<z.ZodString>;
|
|
84
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
85
|
+
}, z.core.$strict>>;
|
|
86
|
+
reviewHistory: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
87
|
+
reviewer: z.ZodString;
|
|
88
|
+
decision: z.ZodOptional<z.ZodEnum<{
|
|
89
|
+
exclude: "exclude";
|
|
90
|
+
include: "include";
|
|
91
|
+
uncertain: "uncertain";
|
|
92
|
+
}>>;
|
|
93
|
+
basis: z.ZodOptional<z.ZodEnum<{
|
|
94
|
+
title: "title";
|
|
95
|
+
abstract: "abstract";
|
|
96
|
+
fulltext: "fulltext";
|
|
97
|
+
}>>;
|
|
98
|
+
comment: z.ZodOptional<z.ZodString>;
|
|
99
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
100
|
+
}, z.core.$strict>>>;
|
|
101
|
+
finalDecision: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"include">, z.ZodLiteral<"exclude">, z.ZodNull]>>;
|
|
102
|
+
fulltext: z.ZodOptional<z.ZodObject<{
|
|
103
|
+
dirName: z.ZodString;
|
|
104
|
+
hasFiles: z.ZodObject<{
|
|
105
|
+
pdf: z.ZodBoolean;
|
|
106
|
+
xml: z.ZodBoolean;
|
|
107
|
+
html: z.ZodBoolean;
|
|
108
|
+
markdown: z.ZodBoolean;
|
|
109
|
+
}, z.core.$strict>;
|
|
110
|
+
}, z.core.$strict>>;
|
|
111
|
+
}, z.core.$strict>;
|
|
112
|
+
export declare const reviewerRecordSchema: z.ZodObject<{
|
|
113
|
+
name: z.ZodString;
|
|
114
|
+
basis: z.ZodEnum<{
|
|
115
|
+
title: "title";
|
|
116
|
+
abstract: "abstract";
|
|
117
|
+
fulltext: "fulltext";
|
|
118
|
+
}>;
|
|
119
|
+
}, z.core.$strict>;
|
|
120
|
+
export declare const reviewFileSchema: z.ZodObject<{
|
|
121
|
+
sessionId: z.ZodString;
|
|
122
|
+
criteria: z.ZodOptional<z.ZodString>;
|
|
123
|
+
reviewer: z.ZodOptional<z.ZodString>;
|
|
124
|
+
basis: z.ZodOptional<z.ZodEnum<{
|
|
125
|
+
title: "title";
|
|
126
|
+
abstract: "abstract";
|
|
127
|
+
fulltext: "fulltext";
|
|
128
|
+
}>>;
|
|
129
|
+
articles: z.ZodArray<z.ZodObject<{
|
|
130
|
+
doi: z.ZodOptional<z.ZodString>;
|
|
131
|
+
pmid: z.ZodOptional<z.ZodString>;
|
|
132
|
+
scopusId: z.ZodOptional<z.ZodString>;
|
|
133
|
+
arxivId: z.ZodOptional<z.ZodString>;
|
|
134
|
+
ericId: z.ZodOptional<z.ZodString>;
|
|
135
|
+
title: z.ZodString;
|
|
136
|
+
authors: z.ZodOptional<z.ZodString>;
|
|
137
|
+
year: z.ZodOptional<z.ZodString>;
|
|
138
|
+
abstract: z.ZodOptional<z.ZodString>;
|
|
139
|
+
mergedFrom: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
140
|
+
source: z.ZodString;
|
|
141
|
+
pmid: z.ZodOptional<z.ZodString>;
|
|
142
|
+
doi: z.ZodOptional<z.ZodString>;
|
|
143
|
+
scopusId: z.ZodOptional<z.ZodString>;
|
|
144
|
+
arxivId: z.ZodOptional<z.ZodString>;
|
|
145
|
+
ericId: z.ZodOptional<z.ZodString>;
|
|
146
|
+
}, z.core.$strict>>>;
|
|
147
|
+
reviews: z.ZodArray<z.ZodObject<{
|
|
148
|
+
reviewer: z.ZodString;
|
|
149
|
+
decision: z.ZodOptional<z.ZodEnum<{
|
|
150
|
+
exclude: "exclude";
|
|
151
|
+
include: "include";
|
|
152
|
+
uncertain: "uncertain";
|
|
153
|
+
}>>;
|
|
154
|
+
basis: z.ZodOptional<z.ZodEnum<{
|
|
155
|
+
title: "title";
|
|
156
|
+
abstract: "abstract";
|
|
157
|
+
fulltext: "fulltext";
|
|
158
|
+
}>>;
|
|
159
|
+
comment: z.ZodOptional<z.ZodString>;
|
|
160
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
161
|
+
}, z.core.$strict>>;
|
|
162
|
+
reviewHistory: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
163
|
+
reviewer: z.ZodString;
|
|
164
|
+
decision: z.ZodOptional<z.ZodEnum<{
|
|
165
|
+
exclude: "exclude";
|
|
166
|
+
include: "include";
|
|
167
|
+
uncertain: "uncertain";
|
|
168
|
+
}>>;
|
|
169
|
+
basis: z.ZodOptional<z.ZodEnum<{
|
|
170
|
+
title: "title";
|
|
171
|
+
abstract: "abstract";
|
|
172
|
+
fulltext: "fulltext";
|
|
173
|
+
}>>;
|
|
174
|
+
comment: z.ZodOptional<z.ZodString>;
|
|
175
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
176
|
+
}, z.core.$strict>>>;
|
|
177
|
+
finalDecision: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"include">, z.ZodLiteral<"exclude">, z.ZodNull]>>;
|
|
178
|
+
fulltext: z.ZodOptional<z.ZodObject<{
|
|
179
|
+
dirName: z.ZodString;
|
|
180
|
+
hasFiles: z.ZodObject<{
|
|
181
|
+
pdf: z.ZodBoolean;
|
|
182
|
+
xml: z.ZodBoolean;
|
|
183
|
+
html: z.ZodBoolean;
|
|
184
|
+
markdown: z.ZodBoolean;
|
|
185
|
+
}, z.core.$strict>;
|
|
186
|
+
}, z.core.$strict>>;
|
|
187
|
+
}, z.core.$strict>>;
|
|
188
|
+
reviewers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
189
|
+
name: z.ZodString;
|
|
190
|
+
basis: z.ZodEnum<{
|
|
191
|
+
title: "title";
|
|
192
|
+
abstract: "abstract";
|
|
193
|
+
fulltext: "fulltext";
|
|
194
|
+
}>;
|
|
195
|
+
}, z.core.$strict>>>;
|
|
196
|
+
}, z.core.$strict>;
|
|
197
|
+
/** Generate a JSON Schema from the review file Zod schema. */
|
|
198
|
+
export declare function generateReviewJSONSchema(): Record<string, unknown>;
|
|
199
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/review/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,eAAO,MAAM,oBAAoB;;;;EAA8C,CAAC;AAEhF,eAAO,MAAM,iBAAiB;;;;EAA4C,CAAC;AAE3E,eAAO,MAAM,YAAY;;;;;;;;;;;;;;kBASyB,CAAC;AAEnD,eAAO,MAAM,kBAAkB;;;;;;;kBAUwB,CAAC;AAExD,eAAO,MAAM,wBAAwB;;;;;;;;kBAY1B,CAAC;AAEZ,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA0ByC,CAAC;AAEzE,eAAO,MAAM,oBAAoB;;;;;;;kBAM6C,CAAC;AAE/E,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAU6B,CAAC;AAE3D,8DAA8D;AAC9D,wBAAgB,wBAAwB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIlE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
const reviewDecisionSchema = z.enum(["include", "exclude", "uncertain"]);
|
|
3
|
+
const reviewBasisSchema = z.enum(["title", "abstract", "fulltext"]);
|
|
4
|
+
const reviewSchema = z.object({
|
|
5
|
+
reviewer: z.string().describe("Reviewer identifier (e.g., 'gpt-4o', 'claude-sonnet', 'human:tanaka')"),
|
|
6
|
+
decision: reviewDecisionSchema.describe("Assessment decision").optional(),
|
|
7
|
+
basis: reviewBasisSchema.describe("Basis of the decision (what information was used)").optional(),
|
|
8
|
+
comment: z.string().describe("Optional comment or reason").optional(),
|
|
9
|
+
timestamp: z.string().datetime().describe("ISO 8601 timestamp").optional()
|
|
10
|
+
}).strict().describe("Individual assessment of an article");
|
|
11
|
+
const mergedSourceSchema = z.object({
|
|
12
|
+
source: z.string().describe("Database source (e.g., 'pubmed', 'scopus')"),
|
|
13
|
+
pmid: z.string().optional(),
|
|
14
|
+
doi: z.string().optional(),
|
|
15
|
+
scopusId: z.string().optional(),
|
|
16
|
+
arxivId: z.string().optional(),
|
|
17
|
+
ericId: z.string().optional()
|
|
18
|
+
}).strict().describe("Source information for merged duplicates");
|
|
19
|
+
const articleFulltextRefSchema = z.object({
|
|
20
|
+
dirName: z.string(),
|
|
21
|
+
hasFiles: z.object({
|
|
22
|
+
pdf: z.boolean(),
|
|
23
|
+
xml: z.boolean(),
|
|
24
|
+
html: z.boolean(),
|
|
25
|
+
markdown: z.boolean()
|
|
26
|
+
}).strict()
|
|
27
|
+
}).strict();
|
|
28
|
+
const articleEntrySchema = z.object({
|
|
29
|
+
// Identifiers
|
|
30
|
+
doi: z.string().describe("Digital Object Identifier").optional(),
|
|
31
|
+
pmid: z.string().describe("PubMed ID").optional(),
|
|
32
|
+
scopusId: z.string().describe("Scopus ID").optional(),
|
|
33
|
+
arxivId: z.string().describe("arXiv ID").optional(),
|
|
34
|
+
ericId: z.string().describe("ERIC ID").optional(),
|
|
35
|
+
// Bibliographic info
|
|
36
|
+
title: z.string().describe("Article title"),
|
|
37
|
+
authors: z.string().describe("Authors (formatted string)").optional(),
|
|
38
|
+
year: z.string().describe("Publication year").optional(),
|
|
39
|
+
abstract: z.string().describe("Article abstract").optional(),
|
|
40
|
+
// Deduplication tracking
|
|
41
|
+
mergedFrom: z.array(mergedSourceSchema).describe("Sources this article was merged from during deduplication").optional(),
|
|
42
|
+
// Review data
|
|
43
|
+
reviews: z.array(reviewSchema).describe("List of assessments"),
|
|
44
|
+
reviewHistory: z.array(reviewSchema).describe("Historical reviews (only in extracted ReviewFiles, never in master file)").optional(),
|
|
45
|
+
finalDecision: z.union([z.literal("include"), z.literal("exclude"), z.null()]).describe("Final inclusion/exclusion decision (null in extracted files)").optional(),
|
|
46
|
+
// Fulltext reference
|
|
47
|
+
fulltext: articleFulltextRefSchema.optional()
|
|
48
|
+
}).strict().describe("Article with identifiers, bibliographic info, and reviews");
|
|
49
|
+
const reviewerRecordSchema = z.object({
|
|
50
|
+
name: z.string().describe("Reviewer identifier"),
|
|
51
|
+
basis: reviewBasisSchema.describe("Basis level at which the reviewer participated")
|
|
52
|
+
}).strict().describe("Record of a reviewer's participation at a specific basis level");
|
|
53
|
+
const reviewFileSchema = z.object({
|
|
54
|
+
sessionId: z.string().describe("Session identifier"),
|
|
55
|
+
criteria: z.string().describe("Path to inclusion criteria file").optional(),
|
|
56
|
+
reviewer: z.string().describe("Reviewer identifier (only in extracted ReviewFiles)").optional(),
|
|
57
|
+
basis: reviewBasisSchema.describe("Basis level for screening (only in extracted ReviewFiles)").optional(),
|
|
58
|
+
articles: z.array(articleEntrySchema).describe("List of articles with review data"),
|
|
59
|
+
reviewers: z.array(reviewerRecordSchema).describe("Registry of reviewers who participated at each basis level").optional()
|
|
60
|
+
}).strict().describe("Schema for article review workflow tracking");
|
|
61
|
+
function generateReviewJSONSchema() {
|
|
62
|
+
return z.toJSONSchema(reviewFileSchema, {
|
|
63
|
+
target: "draft-7"
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
articleEntrySchema,
|
|
68
|
+
articleFulltextRefSchema,
|
|
69
|
+
generateReviewJSONSchema,
|
|
70
|
+
mergedSourceSchema,
|
|
71
|
+
reviewBasisSchema,
|
|
72
|
+
reviewDecisionSchema,
|
|
73
|
+
reviewFileSchema,
|
|
74
|
+
reviewSchema,
|
|
75
|
+
reviewerRecordSchema
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sources":["../../../../src/cli/commands/review/schema.ts"],"sourcesContent":["/**\n * Zod schemas for review workflow types.\n *\n * Single source of truth for:\n * - TypeScript types (via z.infer<>)\n * - JSON Schema for IDE autocompletion (via z.toJSONSchema())\n *\n * Follows the pattern established in src/query/json-schema.ts.\n */\nimport * as z from 'zod';\n\nexport const reviewDecisionSchema = z.enum(['include', 'exclude', 'uncertain']);\n\nexport const reviewBasisSchema = z.enum(['title', 'abstract', 'fulltext']);\n\nexport const reviewSchema = z\n .object({\n reviewer: z.string().describe(\"Reviewer identifier (e.g., 'gpt-4o', 'claude-sonnet', 'human:tanaka')\"),\n decision: reviewDecisionSchema.describe('Assessment decision').optional(),\n basis: reviewBasisSchema.describe('Basis of the decision (what information was used)').optional(),\n comment: z.string().describe('Optional comment or reason').optional(),\n timestamp: z.string().datetime().describe('ISO 8601 timestamp').optional(),\n })\n .strict()\n .describe('Individual assessment of an article');\n\nexport const mergedSourceSchema = z\n .object({\n source: z.string().describe(\"Database source (e.g., 'pubmed', 'scopus')\"),\n pmid: z.string().optional(),\n doi: z.string().optional(),\n scopusId: z.string().optional(),\n arxivId: z.string().optional(),\n ericId: z.string().optional(),\n })\n .strict()\n .describe('Source information for merged duplicates');\n\nexport const articleFulltextRefSchema = z\n .object({\n dirName: z.string(),\n hasFiles: z\n .object({\n pdf: z.boolean(),\n xml: z.boolean(),\n html: z.boolean(),\n markdown: z.boolean(),\n })\n .strict(),\n })\n .strict();\n\nexport const articleEntrySchema = z\n .object({\n // Identifiers\n doi: z.string().describe('Digital Object Identifier').optional(),\n pmid: z.string().describe('PubMed ID').optional(),\n scopusId: z.string().describe('Scopus ID').optional(),\n arxivId: z.string().describe('arXiv ID').optional(),\n ericId: z.string().describe('ERIC ID').optional(),\n // Bibliographic info\n title: z.string().describe('Article title'),\n authors: z.string().describe('Authors (formatted string)').optional(),\n year: z.string().describe('Publication year').optional(),\n abstract: z.string().describe('Article abstract').optional(),\n // Deduplication tracking\n mergedFrom: z.array(mergedSourceSchema).describe('Sources this article was merged from during deduplication').optional(),\n // Review data\n reviews: z.array(reviewSchema).describe('List of assessments'),\n reviewHistory: z.array(reviewSchema).describe('Historical reviews (only in extracted ReviewFiles, never in master file)').optional(),\n finalDecision: z\n .union([z.literal('include'), z.literal('exclude'), z.null()])\n .describe('Final inclusion/exclusion decision (null in extracted files)')\n .optional(),\n // Fulltext reference\n fulltext: articleFulltextRefSchema.optional(),\n })\n .strict()\n .describe('Article with identifiers, bibliographic info, and reviews');\n\nexport const reviewerRecordSchema = z\n .object({\n name: z.string().describe('Reviewer identifier'),\n basis: reviewBasisSchema.describe('Basis level at which the reviewer participated'),\n })\n .strict()\n .describe('Record of a reviewer\\'s participation at a specific basis level');\n\nexport const reviewFileSchema = z\n .object({\n sessionId: z.string().describe('Session identifier'),\n criteria: z.string().describe('Path to inclusion criteria file').optional(),\n reviewer: z.string().describe('Reviewer identifier (only in extracted ReviewFiles)').optional(),\n basis: reviewBasisSchema.describe('Basis level for screening (only in extracted ReviewFiles)').optional(),\n articles: z.array(articleEntrySchema).describe('List of articles with review data'),\n reviewers: z.array(reviewerRecordSchema).describe('Registry of reviewers who participated at each basis level').optional(),\n })\n .strict()\n .describe('Schema for article review workflow tracking');\n\n/** Generate a JSON Schema from the review file Zod schema. */\nexport function generateReviewJSONSchema(): Record<string, unknown> {\n return z.toJSONSchema(reviewFileSchema, {\n target: 'draft-7',\n });\n}\n"],"names":[],"mappings":";AAWO,MAAM,uBAAuB,EAAE,KAAK,CAAC,WAAW,WAAW,WAAW,CAAC;AAEvE,MAAM,oBAAoB,EAAE,KAAK,CAAC,SAAS,YAAY,UAAU,CAAC;AAElE,MAAM,eAAe,EACzB,OAAO;AAAA,EACN,UAAU,EAAE,SAAS,SAAS,uEAAuE;AAAA,EACrG,UAAU,qBAAqB,SAAS,qBAAqB,EAAE,SAAA;AAAA,EAC/D,OAAO,kBAAkB,SAAS,mDAAmD,EAAE,SAAA;AAAA,EACvF,SAAS,EAAE,OAAA,EAAS,SAAS,4BAA4B,EAAE,SAAA;AAAA,EAC3D,WAAW,EAAE,OAAA,EAAS,WAAW,SAAS,oBAAoB,EAAE,SAAA;AAClE,CAAC,EACA,SACA,SAAS,qCAAqC;AAE1C,MAAM,qBAAqB,EAC/B,OAAO;AAAA,EACN,QAAQ,EAAE,SAAS,SAAS,4CAA4C;AAAA,EACxE,MAAM,EAAE,OAAA,EAAS,SAAA;AAAA,EACjB,KAAK,EAAE,OAAA,EAAS,SAAA;AAAA,EAChB,UAAU,EAAE,OAAA,EAAS,SAAA;AAAA,EACrB,SAAS,EAAE,OAAA,EAAS,SAAA;AAAA,EACpB,QAAQ,EAAE,OAAA,EAAS,SAAA;AACrB,CAAC,EACA,SACA,SAAS,0CAA0C;AAE/C,MAAM,2BAA2B,EACrC,OAAO;AAAA,EACN,SAAS,EAAE,OAAA;AAAA,EACX,UAAU,EACP,OAAO;AAAA,IACN,KAAK,EAAE,QAAA;AAAA,IACP,KAAK,EAAE,QAAA;AAAA,IACP,MAAM,EAAE,QAAA;AAAA,IACR,UAAU,EAAE,QAAA;AAAA,EAAQ,CACrB,EACA,OAAA;AACL,CAAC,EACA,OAAA;AAEI,MAAM,qBAAqB,EAC/B,OAAO;AAAA;AAAA,EAEN,KAAK,EAAE,OAAA,EAAS,SAAS,2BAA2B,EAAE,SAAA;AAAA,EACtD,MAAM,EAAE,OAAA,EAAS,SAAS,WAAW,EAAE,SAAA;AAAA,EACvC,UAAU,EAAE,OAAA,EAAS,SAAS,WAAW,EAAE,SAAA;AAAA,EAC3C,SAAS,EAAE,OAAA,EAAS,SAAS,UAAU,EAAE,SAAA;AAAA,EACzC,QAAQ,EAAE,OAAA,EAAS,SAAS,SAAS,EAAE,SAAA;AAAA;AAAA,EAEvC,OAAO,EAAE,SAAS,SAAS,eAAe;AAAA,EAC1C,SAAS,EAAE,OAAA,EAAS,SAAS,4BAA4B,EAAE,SAAA;AAAA,EAC3D,MAAM,EAAE,OAAA,EAAS,SAAS,kBAAkB,EAAE,SAAA;AAAA,EAC9C,UAAU,EAAE,OAAA,EAAS,SAAS,kBAAkB,EAAE,SAAA;AAAA;AAAA,EAElD,YAAY,EAAE,MAAM,kBAAkB,EAAE,SAAS,2DAA2D,EAAE,SAAA;AAAA;AAAA,EAE9G,SAAS,EAAE,MAAM,YAAY,EAAE,SAAS,qBAAqB;AAAA,EAC7D,eAAe,EAAE,MAAM,YAAY,EAAE,SAAS,0EAA0E,EAAE,SAAA;AAAA,EAC1H,eAAe,EACZ,MAAM,CAAC,EAAE,QAAQ,SAAS,GAAG,EAAE,QAAQ,SAAS,GAAG,EAAE,MAAM,CAAC,EAC5D,SAAS,8DAA8D,EACvE,SAAA;AAAA;AAAA,EAEH,UAAU,yBAAyB,SAAA;AACrC,CAAC,EACA,SACA,SAAS,2DAA2D;AAEhE,MAAM,uBAAuB,EACjC,OAAO;AAAA,EACN,MAAM,EAAE,SAAS,SAAS,qBAAqB;AAAA,EAC/C,OAAO,kBAAkB,SAAS,gDAAgD;AACpF,CAAC,EACA,SACA,SAAS,gEAAiE;AAEtE,MAAM,mBAAmB,EAC7B,OAAO;AAAA,EACN,WAAW,EAAE,SAAS,SAAS,oBAAoB;AAAA,EACnD,UAAU,EAAE,OAAA,EAAS,SAAS,iCAAiC,EAAE,SAAA;AAAA,EACjE,UAAU,EAAE,OAAA,EAAS,SAAS,qDAAqD,EAAE,SAAA;AAAA,EACrF,OAAO,kBAAkB,SAAS,2DAA2D,EAAE,SAAA;AAAA,EAC/F,UAAU,EAAE,MAAM,kBAAkB,EAAE,SAAS,mCAAmC;AAAA,EAClF,WAAW,EAAE,MAAM,oBAAoB,EAAE,SAAS,4DAA4D,EAAE,SAAA;AAClH,CAAC,EACA,SACA,SAAS,6CAA6C;AAGlD,SAAS,2BAAoD;AAClE,SAAO,EAAE,aAAa,kBAAkB;AAAA,IACtC,QAAQ;AAAA,EAAA,CACT;AACH;"}
|
|
@@ -7,10 +7,10 @@ export interface ReviewStatusResult {
|
|
|
7
7
|
total: number;
|
|
8
8
|
pending: number;
|
|
9
9
|
incomplete: number;
|
|
10
|
-
|
|
10
|
+
allUncertain: number;
|
|
11
11
|
agreedInclude: number;
|
|
12
12
|
agreedExclude: number;
|
|
13
|
-
|
|
13
|
+
divided: number;
|
|
14
14
|
finalized: number;
|
|
15
15
|
included: number;
|
|
16
16
|
excluded: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/review/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAElF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/review/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAElF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B;AAWD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,mBAAmB,EAC5B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC,CAwD7B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAuBrE"}
|
|
@@ -14,10 +14,10 @@ async function executeReviewStatus(options, sessionsDir) {
|
|
|
14
14
|
const counts = {
|
|
15
15
|
pending: 0,
|
|
16
16
|
incomplete: 0,
|
|
17
|
-
|
|
17
|
+
allUncertain: 0,
|
|
18
18
|
agreedInclude: 0,
|
|
19
19
|
agreedExclude: 0,
|
|
20
|
-
|
|
20
|
+
divided: 0,
|
|
21
21
|
finalized: 0,
|
|
22
22
|
included: 0,
|
|
23
23
|
excluded: 0
|
|
@@ -31,8 +31,8 @@ async function executeReviewStatus(options, sessionsDir) {
|
|
|
31
31
|
case "incomplete":
|
|
32
32
|
counts.incomplete++;
|
|
33
33
|
break;
|
|
34
|
-
case "uncertain":
|
|
35
|
-
counts.
|
|
34
|
+
case "all-uncertain":
|
|
35
|
+
counts.allUncertain++;
|
|
36
36
|
break;
|
|
37
37
|
case "agreed-include":
|
|
38
38
|
counts.agreedInclude++;
|
|
@@ -40,8 +40,8 @@ async function executeReviewStatus(options, sessionsDir) {
|
|
|
40
40
|
case "agreed-exclude":
|
|
41
41
|
counts.agreedExclude++;
|
|
42
42
|
break;
|
|
43
|
-
case "
|
|
44
|
-
counts.
|
|
43
|
+
case "divided":
|
|
44
|
+
counts.divided++;
|
|
45
45
|
break;
|
|
46
46
|
case "finalized":
|
|
47
47
|
counts.finalized++;
|
|
@@ -65,13 +65,13 @@ function formatStatusOutput(result) {
|
|
|
65
65
|
const agreed = result.agreedInclude + result.agreedExclude;
|
|
66
66
|
const lines = [
|
|
67
67
|
`Review Progress: ${id}`,
|
|
68
|
-
` Total:
|
|
69
|
-
` Pending:
|
|
70
|
-
` Incomplete:
|
|
71
|
-
`
|
|
72
|
-
` Agreed:
|
|
73
|
-
`
|
|
74
|
-
` Finalized:
|
|
68
|
+
` Total: ${result.total}`,
|
|
69
|
+
` Pending: ${result.pending}`,
|
|
70
|
+
` Incomplete: ${result.incomplete}`,
|
|
71
|
+
` All-uncertain: ${result.allUncertain}`,
|
|
72
|
+
` Agreed: ${agreed} (include: ${result.agreedInclude}, exclude: ${result.agreedExclude})`,
|
|
73
|
+
` Divided: ${result.divided}`,
|
|
74
|
+
` Finalized: ${result.finalized} (include: ${result.included}, exclude: ${result.excluded})`
|
|
75
75
|
];
|
|
76
76
|
if (result.reviewers.length > 0) {
|
|
77
77
|
lines.push("");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sources":["../../../../src/cli/commands/review/status.ts"],"sourcesContent":["/**\n * review status command - Show review progress summary\n */\n\nimport { join } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport { classifyStatus, type ReviewFile, type ReviewerRecord } from './types.js';\n\nexport interface ReviewStatusOptions {\n sessionId: string;\n}\n\nexport interface ReviewStatusResult {\n sessionId: string;\n total: number;\n pending: number;\n incomplete: number;\n
|
|
1
|
+
{"version":3,"file":"status.js","sources":["../../../../src/cli/commands/review/status.ts"],"sourcesContent":["/**\n * review status command - Show review progress summary\n */\n\nimport { join } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport { classifyStatus, type ReviewFile, type ReviewerRecord } from './types.js';\n\nexport interface ReviewStatusOptions {\n sessionId: string;\n}\n\nexport interface ReviewStatusResult {\n sessionId: string;\n total: number;\n pending: number;\n incomplete: number;\n allUncertain: number;\n agreedInclude: number;\n agreedExclude: number;\n divided: number;\n finalized: number;\n included: number;\n excluded: number;\n /** Registered reviewers from the review file */\n reviewers: ReviewerRecord[];\n}\n\n/**\n * Load review file from session directory\n */\nasync function loadReviewFile(sessionDir: string): Promise<ReviewFile> {\n const reviewsPath = join(sessionDir, '.internal', 'reviews.yaml');\n const content = await readFile(reviewsPath, 'utf-8');\n return parseYaml(content) as ReviewFile;\n}\n\n/**\n * Execute review status command\n */\nexport async function executeReviewStatus(\n options: ReviewStatusOptions,\n sessionsDir: string\n): Promise<ReviewStatusResult> {\n const sessionDir = join(sessionsDir, options.sessionId);\n const reviewFile = await loadReviewFile(sessionDir);\n\n const reviewers = reviewFile.reviewers ?? [];\n const counts = {\n pending: 0,\n incomplete: 0,\n allUncertain: 0,\n agreedInclude: 0,\n agreedExclude: 0,\n divided: 0,\n finalized: 0,\n included: 0,\n excluded: 0,\n };\n\n for (const article of reviewFile.articles) {\n const status = classifyStatus(article, reviewers);\n\n switch (status) {\n case 'pending':\n counts.pending++;\n break;\n case 'incomplete':\n counts.incomplete++;\n break;\n case 'all-uncertain':\n counts.allUncertain++;\n break;\n case 'agreed-include':\n counts.agreedInclude++;\n break;\n case 'agreed-exclude':\n counts.agreedExclude++;\n break;\n case 'divided':\n counts.divided++;\n break;\n case 'finalized':\n counts.finalized++;\n if (article.finalDecision === 'include') {\n counts.included++;\n } else {\n counts.excluded++;\n }\n break;\n }\n }\n\n return {\n sessionId: options.sessionId,\n total: reviewFile.articles.length,\n reviewers,\n ...counts,\n };\n}\n\n/**\n * Format status result as human-readable string\n */\nexport function formatStatusOutput(result: ReviewStatusResult): string {\n const id = result.sessionId;\n const agreed = result.agreedInclude + result.agreedExclude;\n const lines = [\n `Review Progress: ${id}`,\n ` Total: ${result.total}`,\n ` Pending: ${result.pending}`,\n ` Incomplete: ${result.incomplete}`,\n ` All-uncertain: ${result.allUncertain}`,\n ` Agreed: ${agreed} (include: ${result.agreedInclude}, exclude: ${result.agreedExclude})`,\n ` Divided: ${result.divided}`,\n ` Finalized: ${result.finalized} (include: ${result.included}, exclude: ${result.excluded})`,\n ];\n\n if (result.reviewers.length > 0) {\n lines.push('');\n lines.push('Reviewers:');\n for (const r of result.reviewers) {\n lines.push(` ${r.name} (${r.basis})`);\n }\n }\n\n return lines.join('\\n');\n}\n"],"names":["parseYaml"],"mappings":";;;;AAgCA,eAAe,eAAe,YAAyC;AACrE,QAAM,cAAc,KAAK,YAAY,aAAa,cAAc;AAChE,QAAM,UAAU,MAAM,SAAS,aAAa,OAAO;AACnD,SAAOA,MAAU,OAAO;AAC1B;AAKA,eAAsB,oBACpB,SACA,aAC6B;AAC7B,QAAM,aAAa,KAAK,aAAa,QAAQ,SAAS;AACtD,QAAM,aAAa,MAAM,eAAe,UAAU;AAElD,QAAM,YAAY,WAAW,aAAa,CAAA;AAC1C,QAAM,SAAS;AAAA,IACb,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,eAAe;AAAA,IACf,eAAe;AAAA,IACf,SAAS;AAAA,IACT,WAAW;AAAA,IACX,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAGZ,aAAW,WAAW,WAAW,UAAU;AACzC,UAAM,SAAS,eAAe,SAAS,SAAS;AAEhD,YAAQ,QAAA;AAAA,MACN,KAAK;AACH,eAAO;AACP;AAAA,MACF,KAAK;AACH,eAAO;AACP;AAAA,MACF,KAAK;AACH,eAAO;AACP;AAAA,MACF,KAAK;AACH,eAAO;AACP;AAAA,MACF,KAAK;AACH,eAAO;AACP;AAAA,MACF,KAAK;AACH,eAAO;AACP;AAAA,MACF,KAAK;AACH,eAAO;AACP,YAAI,QAAQ,kBAAkB,WAAW;AACvC,iBAAO;AAAA,QACT,OAAO;AACL,iBAAO;AAAA,QACT;AACA;AAAA,IAAA;AAAA,EAEN;AAEA,SAAO;AAAA,IACL,WAAW,QAAQ;AAAA,IACnB,OAAO,WAAW,SAAS;AAAA,IAC3B;AAAA,IACA,GAAG;AAAA,EAAA;AAEP;AAKO,SAAS,mBAAmB,QAAoC;AACrE,QAAM,KAAK,OAAO;AAClB,QAAM,SAAS,OAAO,gBAAgB,OAAO;AAC7C,QAAM,QAAQ;AAAA,IACZ,oBAAoB,EAAE;AAAA,IACtB,sBAAsB,OAAO,KAAK;AAAA,IAClC,sBAAsB,OAAO,OAAO;AAAA,IACpC,sBAAsB,OAAO,UAAU;AAAA,IACvC,sBAAsB,OAAO,YAAY;AAAA,IACzC,sBAAsB,MAAM,eAAe,OAAO,aAAa,cAAc,OAAO,aAAa;AAAA,IACjG,sBAAsB,OAAO,OAAO;AAAA,IACpC,sBAAsB,OAAO,SAAS,eAAe,OAAO,QAAQ,cAAc,OAAO,QAAQ;AAAA,EAAA;AAGnG,MAAI,OAAO,UAAU,SAAS,GAAG;AAC/B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,YAAY;AACvB,eAAW,KAAK,OAAO,WAAW;AAChC,YAAM,KAAK,KAAK,EAAE,IAAI,MAAM,EAAE,KAAK,GAAG;AAAA,IACxC;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;"}
|
|
@@ -1,74 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type ReviewDecision = 'include' | 'exclude' | 'uncertain';
|
|
1
|
+
import { reviewDecisionSchema, reviewBasisSchema, reviewSchema, mergedSourceSchema, articleEntrySchema, reviewerRecordSchema, reviewFileSchema } from './schema.js';
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
comment?: string;
|
|
19
|
-
/** ISO 8601 timestamp (optional - auto-assigned on merge if not provided) */
|
|
20
|
-
timestamp?: string;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Source information for merged duplicates
|
|
24
|
-
*/
|
|
25
|
-
export interface MergedSource {
|
|
26
|
-
source: string;
|
|
27
|
-
pmid?: string;
|
|
28
|
-
doi?: string;
|
|
29
|
-
scopusId?: string;
|
|
30
|
-
arxivId?: string;
|
|
31
|
-
ericId?: string;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Article entry with identifiers, bibliographic info, and reviews
|
|
35
|
-
*/
|
|
36
|
-
export interface ArticleEntry {
|
|
37
|
-
doi?: string;
|
|
38
|
-
pmid?: string;
|
|
39
|
-
scopusId?: string;
|
|
40
|
-
arxivId?: string;
|
|
41
|
-
ericId?: string;
|
|
42
|
-
title: string;
|
|
43
|
-
authors?: string;
|
|
44
|
-
year?: string;
|
|
45
|
-
abstract?: string;
|
|
46
|
-
mergedFrom?: MergedSource[];
|
|
47
|
-
reviews: Review[];
|
|
48
|
-
/** Historical reviews (only in extracted ReviewFiles, never in master file) */
|
|
49
|
-
reviewHistory?: Review[];
|
|
50
|
-
finalDecision?: 'include' | 'exclude' | null;
|
|
51
|
-
fulltext?: ArticleFulltextRef;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Top-level structure of the reviews.yaml file
|
|
55
|
-
*/
|
|
56
|
-
export interface ReviewerRecord {
|
|
57
|
-
name: string;
|
|
58
|
-
basis: ReviewBasis;
|
|
59
|
-
}
|
|
60
|
-
export interface ReviewFile {
|
|
61
|
-
sessionId: string;
|
|
62
|
-
/** Path to inclusion criteria file */
|
|
63
|
-
criteria?: string;
|
|
64
|
-
/** Reviewer identifier (only in extracted ReviewFiles) */
|
|
65
|
-
reviewer?: string;
|
|
66
|
-
/** Basis level for screening (only in extracted ReviewFiles) */
|
|
67
|
-
basis?: ReviewBasis;
|
|
68
|
-
articles: ArticleEntry[];
|
|
69
|
-
/** Registry of reviewers who participated at each basis level */
|
|
70
|
-
reviewers?: ReviewerRecord[];
|
|
71
|
-
}
|
|
3
|
+
* Review workflow types for article assessment tracking.
|
|
4
|
+
*
|
|
5
|
+
* Core data types (ReviewDecision, ReviewBasis, Review, MergedSource,
|
|
6
|
+
* ArticleEntry, ReviewerRecord, ReviewFile) are derived from Zod schemas
|
|
7
|
+
* in schema.ts — single source of truth for types and JSON Schema.
|
|
8
|
+
*/
|
|
9
|
+
import * as z from 'zod';
|
|
10
|
+
export type ReviewDecision = z.infer<typeof reviewDecisionSchema>;
|
|
11
|
+
export type ReviewBasis = z.infer<typeof reviewBasisSchema>;
|
|
12
|
+
export type Review = z.infer<typeof reviewSchema>;
|
|
13
|
+
export type MergedSource = z.infer<typeof mergedSourceSchema>;
|
|
14
|
+
export type ArticleEntry = z.infer<typeof articleEntrySchema>;
|
|
15
|
+
export type ReviewerRecord = z.infer<typeof reviewerRecordSchema>;
|
|
16
|
+
export type ReviewFile = z.infer<typeof reviewFileSchema>;
|
|
72
17
|
/**
|
|
73
18
|
* Work file article entry for AI agent workflow
|
|
74
19
|
*/
|
|
@@ -96,7 +41,7 @@ export declare function basisRank(basis: ReviewBasis | undefined): number;
|
|
|
96
41
|
/**
|
|
97
42
|
* Review status classification (7-state model)
|
|
98
43
|
*/
|
|
99
|
-
export type ReviewStatus = 'pending' | 'incomplete' | 'uncertain' | 'agreed-include' | 'agreed-exclude' | '
|
|
44
|
+
export type ReviewStatus = 'pending' | 'incomplete' | 'all-uncertain' | 'agreed-include' | 'agreed-exclude' | 'divided' | 'finalized';
|
|
100
45
|
/**
|
|
101
46
|
* Classify the review status of an article entry
|
|
102
47
|
*
|
|
@@ -104,10 +49,10 @@ export type ReviewStatus = 'pending' | 'incomplete' | 'uncertain' | 'agreed-incl
|
|
|
104
49
|
* 1. finalDecision set? → finalized
|
|
105
50
|
* 2. No reviews? → pending
|
|
106
51
|
* 3. Registered reviewer missing? → incomplete
|
|
107
|
-
* 4.
|
|
108
|
-
* 5.
|
|
109
|
-
* 6. All
|
|
110
|
-
* 7.
|
|
52
|
+
* 4. All uncertain? → all-uncertain
|
|
53
|
+
* 5. All include? → agreed-include
|
|
54
|
+
* 6. All exclude? → agreed-exclude
|
|
55
|
+
* 7. Any mix of decisions? → divided
|
|
111
56
|
*/
|
|
112
57
|
export declare function classifyStatus(entry: ArticleEntry, registeredReviewers?: ReviewerRecord[]): ReviewStatus;
|
|
113
58
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/review/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/review/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;GAEG;AACH,iGAAiG;AACjG,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,mGAAmG;AACnG,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAWD,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAGhE;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,YAAY,GACZ,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,SAAS,GACT,WAAW,CAAC;AAEhB;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,YAAY,EACnB,mBAAmB,CAAC,EAAE,cAAc,EAAE,GACrC,YAAY,CAmHd"}
|