@ncukondo/search-hub 0.10.0 → 0.12.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.
Files changed (36) hide show
  1. package/dist/cli/commands/merge.d.ts +82 -0
  2. package/dist/cli/commands/merge.d.ts.map +1 -0
  3. package/dist/cli/commands/merge.js +221 -0
  4. package/dist/cli/commands/merge.js.map +1 -0
  5. package/dist/cli/commands/resume.d.ts.map +1 -1
  6. package/dist/cli/commands/resume.js +7 -0
  7. package/dist/cli/commands/resume.js.map +1 -1
  8. package/dist/cli/commands/review/extract.d.ts +3 -1
  9. package/dist/cli/commands/review/extract.d.ts.map +1 -1
  10. package/dist/cli/commands/review/extract.js +75 -45
  11. package/dist/cli/commands/review/extract.js.map +1 -1
  12. package/dist/cli/commands/review/mark.d.ts.map +1 -1
  13. package/dist/cli/commands/review/mark.js +69 -22
  14. package/dist/cli/commands/review/mark.js.map +1 -1
  15. package/dist/cli/commands/review/merge.d.ts.map +1 -1
  16. package/dist/cli/commands/review/merge.js +8 -2
  17. package/dist/cli/commands/review/merge.js.map +1 -1
  18. package/dist/cli/commands/review/types.d.ts +4 -0
  19. package/dist/cli/commands/review/types.d.ts.map +1 -1
  20. package/dist/cli/commands/review/types.js +10 -3
  21. package/dist/cli/commands/review/types.js.map +1 -1
  22. package/dist/cli/commands/status.js +1 -1
  23. package/dist/cli/commands/status.js.map +1 -1
  24. package/dist/cli/index.d.ts.map +1 -1
  25. package/dist/cli/index.js +143 -4
  26. package/dist/cli/index.js.map +1 -1
  27. package/dist/cli/suggestions/rules.d.ts.map +1 -1
  28. package/dist/cli/suggestions/rules.js +20 -2
  29. package/dist/cli/suggestions/rules.js.map +1 -1
  30. package/dist/cli/suggestions/types.d.ts +6 -0
  31. package/dist/cli/suggestions/types.d.ts.map +1 -1
  32. package/dist/session/types.d.ts +14 -1
  33. package/dist/session/types.d.ts.map +1 -1
  34. package/dist/session/types.js +7 -0
  35. package/dist/session/types.js.map +1 -0
  36. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/cli/suggestions/rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAkB,MAAM,YAAY,CAAC;AAsZtF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,IAAI,CAM7E"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/cli/suggestions/rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAkB,MAAM,YAAY,CAAC;AA8atF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,IAAI,CAM7E"}
@@ -162,9 +162,26 @@ const summaryRule = (ctx) => {
162
162
  const diffRule = (ctx) => {
163
163
  if (ctx.command !== "diff") return null;
164
164
  const sid = ctx.sessionId ?? "<session-id>";
165
+ const seeAlso = [];
166
+ if (ctx.diffAddedCount !== void 0 && ctx.diffAddedCount > 0 && ctx.diffRemovedCount !== void 0 && ctx.diffRemovedCount > 0) {
167
+ const sid1 = ctx.diffSession1Id ?? "<session-id-1>";
168
+ seeAlso.push({
169
+ command: `search-hub merge ${sid1} ${sid}`,
170
+ description: "Combine results from both sessions"
171
+ });
172
+ }
173
+ seeAlso.push({ command: `search-hub results ${sid}`, description: "View detailed results" });
174
+ return { next: [], seeAlso };
175
+ };
176
+ const mergeRule = (ctx) => {
177
+ if (ctx.command !== "merge") return null;
178
+ const sid = ctx.sessionId ?? "<session-id>";
165
179
  return {
166
- next: [],
167
- seeAlso: [{ command: `search-hub results ${sid}`, description: "View detailed results" }]
180
+ next: [
181
+ { command: `search-hub results ${sid}`, description: "View merged results" },
182
+ { command: `search-hub summary ${sid}`, description: "View merge statistics" }
183
+ ],
184
+ seeAlso: []
168
185
  };
169
186
  };
170
187
  const reviewInitRule = (ctx) => {
@@ -327,6 +344,7 @@ const rules = [
327
344
  resultsRule,
328
345
  summaryRule,
329
346
  diffRule,
347
+ mergeRule,
330
348
  // Phase 4
331
349
  reviewInitRule,
332
350
  reviewStatusRule,
@@ -1 +1 @@
1
- {"version":3,"file":"rules.js","sources":["../../../src/cli/suggestions/rules.ts"],"sourcesContent":["import type { SuggestionContext, SuggestionResult, SuggestionRule } from './types.js';\nimport { computeBatchContinuation, generateReviewNextSteps } from '../commands/review/next-steps.js';\n\n// Phase 1: Query Preparation rules\n\nconst queryInitRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'query init') return null;\n const file = ctx.outputFile ?? 'query.yaml';\n return {\n next: [{ command: `$EDITOR ${file}`, description: 'Edit your query' }],\n seeAlso: [],\n };\n};\n\nconst queryValidateRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'query validate') return null;\n const file = ctx.queryFile ?? '<query-file>';\n\n if (ctx.validationSuccess === false) {\n return {\n next: [{ command: `$EDITOR ${file}`, description: 'Fix errors and re-validate' }],\n seeAlso: [],\n };\n }\n\n return {\n next: [\n { command: `search-hub search ${file} --dry-run`, description: 'Check DB translations' },\n { command: `search-hub search ${file} --preview`, description: 'Preview hit counts + sample titles' },\n ],\n seeAlso: [],\n };\n};\n\nconst queryTranslateRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'query translate') return null;\n const file = ctx.queryFile ?? '<query-file>';\n return {\n next: [\n { command: `search-hub search ${file} --preview`, description: 'Preview hit counts + sample titles' },\n { command: `search-hub search ${file}`, description: 'Execute search' },\n ],\n seeAlso: [],\n };\n};\n\n// Phase 2: Search Execution rules\n\n/**\n * Build search completion suggestions based on session status.\n * Shared by search, search --query, and resume commands.\n */\nfunction searchCompletionSuggestion(ctx: SuggestionContext): SuggestionResult | null {\n const sid = ctx.sessionId ?? '<session-id>';\n\n switch (ctx.sessionStatus) {\n case 'completed': {\n const seeAlso: SuggestionResult['seeAlso'] = [];\n if (ctx.sessionCount !== undefined && ctx.sessionCount > 1) {\n seeAlso.push({\n command: `search-hub diff <other-session> ${sid}`,\n description: 'Compare with another query version',\n });\n }\n return {\n next: [{ command: `search-hub results ${sid}`, description: 'View results' }],\n seeAlso,\n };\n }\n case 'partial':\n return {\n next: [{ command: `search-hub resume ${sid}`, description: 'Retry failed databases' }],\n seeAlso: [],\n };\n case 'failed':\n return {\n next: [\n { command: `search-hub resume ${sid} --retry-failed`, description: 'Retry all databases' },\n { command: `search-hub status ${sid}`, description: 'View error details' },\n ],\n seeAlso: [],\n };\n default:\n return null;\n }\n}\n\nconst searchDryRunRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'search --dry-run') return null;\n const file = ctx.queryFile ?? '<query-file>';\n return {\n next: [\n { command: `search-hub search ${file} --preview`, description: 'Preview hit counts + sample titles' },\n { command: `search-hub search ${file}`, description: 'Execute search' },\n ],\n seeAlso: [],\n };\n};\n\nconst searchPreviewRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'search --preview') return null;\n const file = ctx.queryFile ?? '<query-file>';\n return {\n next: [{ command: `search-hub search ${file}`, description: 'Execute full search' }],\n seeAlso: [],\n };\n};\n\nconst searchCountOnlyRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'search --count-only') return null;\n const file = ctx.queryFile ?? '<query-file>';\n return {\n next: [{ command: `search-hub search ${file}`, description: 'Execute full search' }],\n seeAlso: [],\n };\n};\n\nconst searchDirectQueryRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'search --query') return null;\n const base = searchCompletionSuggestion(ctx);\n if (base === null) return null;\n return {\n next: base.next,\n seeAlso: [\n ...base.seeAlso,\n { command: 'search-hub query init -o my-search.yaml', description: 'Save as YAML for reproducibility' },\n ],\n };\n};\n\nconst searchRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'search') return null;\n return searchCompletionSuggestion(ctx);\n};\n\nconst resumeRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'resume') return null;\n return searchCompletionSuggestion(ctx);\n};\n\n// Phase 3: Result Analysis rules\n\nconst statusRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'status') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n\n switch (ctx.sessionStatus) {\n case 'completed':\n return {\n next: [{ command: `search-hub results ${sid}`, description: 'View results' }],\n seeAlso: [],\n };\n case 'partial':\n return {\n next: [{ command: `search-hub resume ${sid}`, description: 'Resume search' }],\n seeAlso: [],\n };\n case 'failed':\n return {\n next: [{ command: `search-hub resume ${sid} --retry-failed`, description: 'Retry all databases' }],\n seeAlso: [],\n };\n default:\n return null;\n }\n};\n\n/**\n * Suggestion for results/summary commands - conditional based on reviews.yaml existence.\n */\nfunction resultReviewSuggestion(ctx: SuggestionContext): SuggestionResult {\n const sid = ctx.sessionId ?? '<session-id>';\n if (ctx.hasReviews === true) {\n return {\n next: [{ command: `search-hub review status --session ${sid}`, description: 'Check review progress' }],\n seeAlso: [],\n };\n }\n return {\n next: [{ command: `search-hub review init --session ${sid}`, description: 'Start systematic review' }],\n seeAlso: [],\n };\n}\n\nconst resultsRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'results') return null;\n return resultReviewSuggestion(ctx);\n};\n\nconst summaryRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'summary') return null;\n return resultReviewSuggestion(ctx);\n};\n\nconst diffRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'diff') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [],\n seeAlso: [{ command: `search-hub results ${sid}`, description: 'View detailed results' }],\n };\n};\n\n// Phase 4: Review Workflow rules\n\nconst reviewInitRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review init') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [\n {\n command: `search-hub review extract --session ${sid} --basis title --name title-screening`,\n description: 'Start title screening',\n },\n ],\n seeAlso: [],\n };\n};\n\nconst reviewStatusRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review status') return null;\n const rs = ctx.reviewStatus;\n if (!rs) return null;\n\n return generateReviewNextSteps({\n sessionId: ctx.sessionId ?? '<session-id>',\n statusResult: rs,\n });\n};\n\nconst reviewListRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review list') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [],\n seeAlso: [\n {\n command: `search-hub review extract --session ${sid} --name <name>`,\n description: 'Extract subset for review',\n },\n ],\n };\n};\n\nconst reviewExtractRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review extract') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n const name = ctx.extractName ?? '<name>';\n const result: SuggestionResult = {\n next: [\n {\n command: `search-hub review merge --session ${sid} --name ${name}`,\n description: 'Merge review results',\n },\n ],\n seeAlso: [],\n };\n\n // Batch continuation: suggest next batch if --limit was used with remaining articles\n if (\n ctx.extractLimit !== undefined &&\n ctx.extractedCount !== undefined &&\n ctx.totalMatching !== undefined\n ) {\n const batch = computeBatchContinuation({\n sessionId: sid,\n extractName: name !== '<name>' ? name : undefined,\n extractedCount: ctx.extractedCount,\n totalMatching: ctx.totalMatching,\n limit: ctx.extractLimit,\n offset: ctx.extractOffset,\n });\n if (batch) result.seeAlso.push(batch);\n }\n\n return result;\n};\n\nconst reviewMergeRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review merge') return null;\n const rs = ctx.reviewStatus;\n if (!rs) {\n // Fallback: suggest status check when reviewStatus not available\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [\n {\n command: `search-hub review status --session ${sid}`,\n description: 'Check progress',\n },\n ],\n seeAlso: [],\n };\n }\n\n return generateReviewNextSteps({\n sessionId: ctx.sessionId ?? '<session-id>',\n statusResult: rs,\n });\n};\n\nconst reviewFinalizeRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review finalize') return null;\n const rs = ctx.reviewStatus;\n if (!rs) return null;\n\n return generateReviewNextSteps({\n sessionId: ctx.sessionId ?? '<session-id>',\n statusResult: rs,\n });\n};\n\nconst reviewExportRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review export') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [],\n seeAlso: [\n {\n command: `search-hub register ${sid} --reviewed`,\n description: 'Register with reference-manager',\n },\n ],\n };\n};\n\n// Phase 5: Registration & Export rules\n\nconst exportRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'export') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n if (ctx.hasReviews === false) {\n return {\n next: [],\n seeAlso: [\n {\n command: `search-hub review init --session ${sid}`,\n description: 'Start review workflow',\n },\n ],\n };\n }\n return { next: [], seeAlso: [] };\n};\n\nconst registerRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'register') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n if (ctx.hasReviews === false) {\n return {\n next: [],\n seeAlso: [\n {\n command: `search-hub review init --session ${sid}`,\n description: 'Start systematic review',\n },\n ],\n };\n }\n // Terminal state: no suggestions\n return null;\n};\n\nconst notesRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'notes add' && ctx.command !== 'notes assess') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [],\n seeAlso: [{ command: `search-hub notes list ${sid}`, description: 'View notes' }],\n };\n};\n\n/**\n * All suggestion rules in evaluation order.\n */\nconst rules: SuggestionRule[] = [\n // Phase 1\n queryInitRule,\n queryValidateRule,\n queryTranslateRule,\n // Phase 2\n searchDryRunRule,\n searchPreviewRule,\n searchCountOnlyRule,\n searchDirectQueryRule,\n searchRule,\n resumeRule,\n // Phase 3\n statusRule,\n resultsRule,\n summaryRule,\n diffRule,\n // Phase 4\n reviewInitRule,\n reviewStatusRule,\n reviewListRule,\n reviewExtractRule,\n reviewMergeRule,\n reviewFinalizeRule,\n reviewExportRule,\n // Phase 5\n exportRule,\n registerRule,\n notesRule,\n];\n\n/**\n * Evaluate suggestion rules for the given context.\n * Returns the first matching rule's result, or null if no rules match.\n */\nexport function getSuggestion(ctx: SuggestionContext): SuggestionResult | null {\n for (const rule of rules) {\n const result = rule(ctx);\n if (result !== null) return result;\n }\n return null;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rules.js","sources":["../../../src/cli/suggestions/rules.ts"],"sourcesContent":["import type { SuggestionContext, SuggestionResult, SuggestionRule } from './types.js';\nimport { computeBatchContinuation, generateReviewNextSteps } from '../commands/review/next-steps.js';\n\n// Phase 1: Query Preparation rules\n\nconst queryInitRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'query init') return null;\n const file = ctx.outputFile ?? 'query.yaml';\n return {\n next: [{ command: `$EDITOR ${file}`, description: 'Edit your query' }],\n seeAlso: [],\n };\n};\n\nconst queryValidateRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'query validate') return null;\n const file = ctx.queryFile ?? '<query-file>';\n\n if (ctx.validationSuccess === false) {\n return {\n next: [{ command: `$EDITOR ${file}`, description: 'Fix errors and re-validate' }],\n seeAlso: [],\n };\n }\n\n return {\n next: [\n { command: `search-hub search ${file} --dry-run`, description: 'Check DB translations' },\n { command: `search-hub search ${file} --preview`, description: 'Preview hit counts + sample titles' },\n ],\n seeAlso: [],\n };\n};\n\nconst queryTranslateRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'query translate') return null;\n const file = ctx.queryFile ?? '<query-file>';\n return {\n next: [\n { command: `search-hub search ${file} --preview`, description: 'Preview hit counts + sample titles' },\n { command: `search-hub search ${file}`, description: 'Execute search' },\n ],\n seeAlso: [],\n };\n};\n\n// Phase 2: Search Execution rules\n\n/**\n * Build search completion suggestions based on session status.\n * Shared by search, search --query, and resume commands.\n */\nfunction searchCompletionSuggestion(ctx: SuggestionContext): SuggestionResult | null {\n const sid = ctx.sessionId ?? '<session-id>';\n\n switch (ctx.sessionStatus) {\n case 'completed': {\n const seeAlso: SuggestionResult['seeAlso'] = [];\n if (ctx.sessionCount !== undefined && ctx.sessionCount > 1) {\n seeAlso.push({\n command: `search-hub diff <other-session> ${sid}`,\n description: 'Compare with another query version',\n });\n }\n return {\n next: [{ command: `search-hub results ${sid}`, description: 'View results' }],\n seeAlso,\n };\n }\n case 'partial':\n return {\n next: [{ command: `search-hub resume ${sid}`, description: 'Retry failed databases' }],\n seeAlso: [],\n };\n case 'failed':\n return {\n next: [\n { command: `search-hub resume ${sid} --retry-failed`, description: 'Retry all databases' },\n { command: `search-hub status ${sid}`, description: 'View error details' },\n ],\n seeAlso: [],\n };\n default:\n return null;\n }\n}\n\nconst searchDryRunRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'search --dry-run') return null;\n const file = ctx.queryFile ?? '<query-file>';\n return {\n next: [\n { command: `search-hub search ${file} --preview`, description: 'Preview hit counts + sample titles' },\n { command: `search-hub search ${file}`, description: 'Execute search' },\n ],\n seeAlso: [],\n };\n};\n\nconst searchPreviewRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'search --preview') return null;\n const file = ctx.queryFile ?? '<query-file>';\n return {\n next: [{ command: `search-hub search ${file}`, description: 'Execute full search' }],\n seeAlso: [],\n };\n};\n\nconst searchCountOnlyRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'search --count-only') return null;\n const file = ctx.queryFile ?? '<query-file>';\n return {\n next: [{ command: `search-hub search ${file}`, description: 'Execute full search' }],\n seeAlso: [],\n };\n};\n\nconst searchDirectQueryRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'search --query') return null;\n const base = searchCompletionSuggestion(ctx);\n if (base === null) return null;\n return {\n next: base.next,\n seeAlso: [\n ...base.seeAlso,\n { command: 'search-hub query init -o my-search.yaml', description: 'Save as YAML for reproducibility' },\n ],\n };\n};\n\nconst searchRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'search') return null;\n return searchCompletionSuggestion(ctx);\n};\n\nconst resumeRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'resume') return null;\n return searchCompletionSuggestion(ctx);\n};\n\n// Phase 3: Result Analysis rules\n\nconst statusRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'status') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n\n switch (ctx.sessionStatus) {\n case 'completed':\n return {\n next: [{ command: `search-hub results ${sid}`, description: 'View results' }],\n seeAlso: [],\n };\n case 'partial':\n return {\n next: [{ command: `search-hub resume ${sid}`, description: 'Resume search' }],\n seeAlso: [],\n };\n case 'failed':\n return {\n next: [{ command: `search-hub resume ${sid} --retry-failed`, description: 'Retry all databases' }],\n seeAlso: [],\n };\n default:\n return null;\n }\n};\n\n/**\n * Suggestion for results/summary commands - conditional based on reviews.yaml existence.\n */\nfunction resultReviewSuggestion(ctx: SuggestionContext): SuggestionResult {\n const sid = ctx.sessionId ?? '<session-id>';\n if (ctx.hasReviews === true) {\n return {\n next: [{ command: `search-hub review status --session ${sid}`, description: 'Check review progress' }],\n seeAlso: [],\n };\n }\n return {\n next: [{ command: `search-hub review init --session ${sid}`, description: 'Start systematic review' }],\n seeAlso: [],\n };\n}\n\nconst resultsRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'results') return null;\n return resultReviewSuggestion(ctx);\n};\n\nconst summaryRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'summary') return null;\n return resultReviewSuggestion(ctx);\n};\n\nconst diffRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'diff') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n const seeAlso: SuggestionResult['seeAlso'] = [];\n\n // Suggest merge when both sessions have unique articles\n if (ctx.diffAddedCount !== undefined && ctx.diffAddedCount > 0 &&\n ctx.diffRemovedCount !== undefined && ctx.diffRemovedCount > 0) {\n const sid1 = ctx.diffSession1Id ?? '<session-id-1>';\n seeAlso.push({\n command: `search-hub merge ${sid1} ${sid}`,\n description: 'Combine results from both sessions',\n });\n }\n\n seeAlso.push({ command: `search-hub results ${sid}`, description: 'View detailed results' });\n\n return { next: [], seeAlso };\n};\n\nconst mergeRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'merge') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [\n { command: `search-hub results ${sid}`, description: 'View merged results' },\n { command: `search-hub summary ${sid}`, description: 'View merge statistics' },\n ],\n seeAlso: [],\n };\n};\n\n// Phase 4: Review Workflow rules\n\nconst reviewInitRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review init') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [\n {\n command: `search-hub review extract --session ${sid} --basis title --name title-screening`,\n description: 'Start title screening',\n },\n ],\n seeAlso: [],\n };\n};\n\nconst reviewStatusRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review status') return null;\n const rs = ctx.reviewStatus;\n if (!rs) return null;\n\n return generateReviewNextSteps({\n sessionId: ctx.sessionId ?? '<session-id>',\n statusResult: rs,\n });\n};\n\nconst reviewListRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review list') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [],\n seeAlso: [\n {\n command: `search-hub review extract --session ${sid} --name <name>`,\n description: 'Extract subset for review',\n },\n ],\n };\n};\n\nconst reviewExtractRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review extract') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n const name = ctx.extractName ?? '<name>';\n const result: SuggestionResult = {\n next: [\n {\n command: `search-hub review merge --session ${sid} --name ${name}`,\n description: 'Merge review results',\n },\n ],\n seeAlso: [],\n };\n\n // Batch continuation: suggest next batch if --limit was used with remaining articles\n if (\n ctx.extractLimit !== undefined &&\n ctx.extractedCount !== undefined &&\n ctx.totalMatching !== undefined\n ) {\n const batch = computeBatchContinuation({\n sessionId: sid,\n extractName: name !== '<name>' ? name : undefined,\n extractedCount: ctx.extractedCount,\n totalMatching: ctx.totalMatching,\n limit: ctx.extractLimit,\n offset: ctx.extractOffset,\n });\n if (batch) result.seeAlso.push(batch);\n }\n\n return result;\n};\n\nconst reviewMergeRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review merge') return null;\n const rs = ctx.reviewStatus;\n if (!rs) {\n // Fallback: suggest status check when reviewStatus not available\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [\n {\n command: `search-hub review status --session ${sid}`,\n description: 'Check progress',\n },\n ],\n seeAlso: [],\n };\n }\n\n return generateReviewNextSteps({\n sessionId: ctx.sessionId ?? '<session-id>',\n statusResult: rs,\n });\n};\n\nconst reviewFinalizeRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review finalize') return null;\n const rs = ctx.reviewStatus;\n if (!rs) return null;\n\n return generateReviewNextSteps({\n sessionId: ctx.sessionId ?? '<session-id>',\n statusResult: rs,\n });\n};\n\nconst reviewExportRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'review export') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [],\n seeAlso: [\n {\n command: `search-hub register ${sid} --reviewed`,\n description: 'Register with reference-manager',\n },\n ],\n };\n};\n\n// Phase 5: Registration & Export rules\n\nconst exportRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'export') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n if (ctx.hasReviews === false) {\n return {\n next: [],\n seeAlso: [\n {\n command: `search-hub review init --session ${sid}`,\n description: 'Start review workflow',\n },\n ],\n };\n }\n return { next: [], seeAlso: [] };\n};\n\nconst registerRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'register') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n if (ctx.hasReviews === false) {\n return {\n next: [],\n seeAlso: [\n {\n command: `search-hub review init --session ${sid}`,\n description: 'Start systematic review',\n },\n ],\n };\n }\n // Terminal state: no suggestions\n return null;\n};\n\nconst notesRule: SuggestionRule = (ctx) => {\n if (ctx.command !== 'notes add' && ctx.command !== 'notes assess') return null;\n const sid = ctx.sessionId ?? '<session-id>';\n return {\n next: [],\n seeAlso: [{ command: `search-hub notes list ${sid}`, description: 'View notes' }],\n };\n};\n\n/**\n * All suggestion rules in evaluation order.\n */\nconst rules: SuggestionRule[] = [\n // Phase 1\n queryInitRule,\n queryValidateRule,\n queryTranslateRule,\n // Phase 2\n searchDryRunRule,\n searchPreviewRule,\n searchCountOnlyRule,\n searchDirectQueryRule,\n searchRule,\n resumeRule,\n // Phase 3\n statusRule,\n resultsRule,\n summaryRule,\n diffRule,\n mergeRule,\n // Phase 4\n reviewInitRule,\n reviewStatusRule,\n reviewListRule,\n reviewExtractRule,\n reviewMergeRule,\n reviewFinalizeRule,\n reviewExportRule,\n // Phase 5\n exportRule,\n registerRule,\n notesRule,\n];\n\n/**\n * Evaluate suggestion rules for the given context.\n * Returns the first matching rule's result, or null if no rules match.\n */\nexport function getSuggestion(ctx: SuggestionContext): SuggestionResult | null {\n for (const rule of rules) {\n const result = rule(ctx);\n if (result !== null) return result;\n }\n return null;\n}\n"],"names":[],"mappings":"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"}
@@ -50,6 +50,12 @@ export interface SuggestionContext {
50
50
  outputFile?: string | undefined;
51
51
  /** Whether validation succeeded (for query validate) */
52
52
  validationSuccess?: boolean | undefined;
53
+ /** Number of added articles in diff result */
54
+ diffAddedCount?: number | undefined;
55
+ /** Number of removed articles in diff result */
56
+ diffRemovedCount?: number | undefined;
57
+ /** Session 1 ID for diff command */
58
+ diffSession1Id?: string | undefined;
53
59
  }
54
60
  /**
55
61
  * A suggestion rule function that evaluates context and returns suggestions.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/suggestions/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,oCAAoC;IACpC,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,qBAAqB;IACrB,aAAa,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC1C,iDAAiD;IACjD,YAAY,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC9C,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,kCAAkC;IAClC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,4BAA4B;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,6BAA6B;IAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,gBAAgB,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/suggestions/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,oCAAoC;IACpC,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,qBAAqB;IACrB,aAAa,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC1C,iDAAiD;IACjD,YAAY,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC9C,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,kCAAkC;IAClC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,4BAA4B;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,6BAA6B;IAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,oCAAoC;IACpC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,gBAAgB,GAAG,IAAI,CAAC"}
@@ -42,6 +42,13 @@ export interface DatabaseStatus {
42
42
  resultsYaml?: string;
43
43
  };
44
44
  }
45
+ /**
46
+ * Source session reference for merged sessions.
47
+ */
48
+ export interface SessionSource {
49
+ id: string;
50
+ name: string;
51
+ }
45
52
  /**
46
53
  * Session file structure (session.yaml).
47
54
  */
@@ -50,13 +57,15 @@ export interface SessionFile {
50
57
  id: string;
51
58
  name: string;
52
59
  description?: string;
60
+ type?: 'search' | 'merge';
53
61
  createdAt: string;
54
62
  updatedAt: string;
55
- query: {
63
+ query?: {
56
64
  file: string;
57
65
  hash: string;
58
66
  targets: ProviderName[];
59
67
  };
68
+ sources?: SessionSource[];
60
69
  databases: Partial<Record<ProviderName, DatabaseStatus>>;
61
70
  summary: {
62
71
  totalHits: number;
@@ -64,6 +73,10 @@ export interface SessionFile {
64
73
  status: SessionStatus;
65
74
  };
66
75
  }
76
+ /**
77
+ * Check if a session is a merged session.
78
+ */
79
+ export declare function isMergedSession(session: SessionFile): boolean;
67
80
  /**
68
81
  * Session summary for listing.
69
82
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/session/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/session/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ function isMergedSession(session) {
2
+ return session.type === "merge";
3
+ }
4
+ export {
5
+ isMergedSession
6
+ };
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":["../../src/session/types.ts"],"sourcesContent":["/**\n * Session types for search-hub.\n *\n * These types define the structure of session data, including:\n * - Session status and lifecycle\n * - Database-specific status and pagination\n * - Event logging\n */\n\n// Import and re-export ProviderName from the authoritative source\nimport type { ProviderName } from '../providers/base/types.js';\nexport type { ProviderName };\n\n/**\n * Overall session status.\n */\nexport type SessionStatus =\n | 'created'\n | 'running'\n | 'completed'\n | 'partial'\n | 'failed';\n\n/**\n * Status for individual database searches.\n */\nexport type DatabaseStatusType =\n | 'pending'\n | 'in_progress'\n | 'completed'\n | 'failed'\n | 'skipped';\n\n/**\n * Pagination state for resumable searches.\n */\nexport interface PaginationState {\n cursor: string | null;\n pageNumber: number;\n isComplete: boolean;\n}\n\n/**\n * Error information for failed searches.\n */\nexport interface DatabaseError {\n code: string;\n message: string;\n retryable: boolean;\n}\n\n/**\n * Status of a database search within a session.\n */\nexport interface DatabaseStatus {\n status: DatabaseStatusType;\n startedAt?: string;\n completedAt?: string;\n totalHits?: number;\n retrievedCount?: number;\n pagination?: PaginationState;\n error?: DatabaseError;\n files: {\n query: string;\n results: string;\n /** Human-readable YAML results file (present when search is completed) */\n resultsYaml?: string;\n };\n}\n\n/**\n * Source session reference for merged sessions.\n */\nexport interface SessionSource {\n id: string;\n name: string;\n}\n\n/**\n * Session file structure (session.yaml).\n */\nexport interface SessionFile {\n version: 1;\n id: string;\n name: string;\n description?: string;\n type?: 'search' | 'merge';\n createdAt: string;\n updatedAt: string;\n query?: {\n file: string;\n hash: string;\n targets: ProviderName[];\n };\n sources?: SessionSource[];\n databases: Partial<Record<ProviderName, DatabaseStatus>>;\n summary: {\n totalHits: number;\n totalRetrieved: number;\n status: SessionStatus;\n };\n}\n\n/**\n * Check if a session is a merged session.\n */\nexport function isMergedSession(session: SessionFile): boolean {\n return session.type === 'merge';\n}\n\n/**\n * Session summary for listing.\n */\nexport interface SessionSummary {\n id: string;\n name: string;\n status: SessionStatus;\n createdAt: string;\n totalHits: number;\n totalRetrieved: number;\n}\n\n/**\n * Log event types.\n */\nexport type LogEventType =\n | 'session_created'\n | 'search_started'\n | 'page_fetched'\n | 'rate_limited'\n | 'retry'\n | 'search_completed'\n | 'search_failed'\n | 'session_completed'\n | 'session_resumed';\n\n/**\n * Base log event structure.\n */\ninterface BaseLogEvent {\n ts: string;\n}\n\n/**\n * Session created event.\n */\ninterface SessionCreatedEvent extends BaseLogEvent {\n event: 'session_created';\n data: { id: string; query: string };\n}\n\n/**\n * Search started event.\n */\ninterface SearchStartedEvent extends BaseLogEvent {\n event: 'search_started';\n provider: ProviderName;\n}\n\n/**\n * Page fetched event.\n */\ninterface PageFetchedEvent extends BaseLogEvent {\n event: 'page_fetched';\n provider: ProviderName;\n page: number;\n count: number;\n cursor?: string;\n}\n\n/**\n * Rate limited event.\n */\ninterface RateLimitedEvent extends BaseLogEvent {\n event: 'rate_limited';\n provider: ProviderName;\n waitMs: number;\n}\n\n/**\n * Retry event.\n */\ninterface RetryEvent extends BaseLogEvent {\n event: 'retry';\n provider: ProviderName;\n attempt: number;\n reason: string;\n}\n\n/**\n * Search completed event.\n */\ninterface SearchCompletedEvent extends BaseLogEvent {\n event: 'search_completed';\n provider: ProviderName;\n total: number;\n duration: number;\n}\n\n/**\n * Search failed event.\n */\ninterface SearchFailedEvent extends BaseLogEvent {\n event: 'search_failed';\n provider: ProviderName;\n error: string;\n}\n\n/**\n * Session completed event.\n */\ninterface SessionCompletedEvent extends BaseLogEvent {\n event: 'session_completed';\n summary: { totalHits: number; totalRetrieved: number };\n}\n\n/**\n * Session resumed event.\n */\ninterface SessionResumedEvent extends BaseLogEvent {\n event: 'session_resumed';\n fromProvider: ProviderName;\n fromPage: number;\n}\n\n/**\n * Union of all log event types.\n */\nexport type LogEvent =\n | SessionCreatedEvent\n | SearchStartedEvent\n | PageFetchedEvent\n | RateLimitedEvent\n | RetryEvent\n | SearchCompletedEvent\n | SearchFailedEvent\n | SessionCompletedEvent\n | SessionResumedEvent;\n\n/**\n * Resume strategy for a provider.\n */\nexport type ResumeStrategy = 'fresh' | 'retry' | 'continue';\n\n/**\n * Information about a provider that can be resumed.\n */\nexport interface ResumableProvider {\n provider: ProviderName;\n strategy: ResumeStrategy;\n cursor?: string | null;\n pageNumber?: number;\n}\n"],"names":[],"mappings":"AA0GO,SAAS,gBAAgB,SAA+B;AAC7D,SAAO,QAAQ,SAAS;AAC1B;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ncukondo/search-hub",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "A CLI tool for systematic literature searching across multiple academic databases",
5
5
  "type": "module",
6
6
  "engines": {