codex-session-insights 0.1.0 → 0.2.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/README.md CHANGED
@@ -108,8 +108,8 @@ npx codex-session-insights --provider openai --api-key $OPENAI_API_KEY
108
108
  Current default analysis plan:
109
109
 
110
110
  - `days`: `30`
111
- - `limit`: `50`
112
- - `facet-limit`: `20`
111
+ - `limit`: `200`
112
+ - `facet-limit`: `50`
113
113
  - `provider`: `codex-cli`
114
114
  - `facet-model`: `gpt-5.4-mini`
115
115
  - `fast-section-model`: `gpt-5.4-mini`
@@ -120,6 +120,8 @@ Current default analysis plan:
120
120
 
121
121
  Important behavior defaults:
122
122
 
123
+ - `limit` means the target number of substantive threads to include in the report, not just the first 50 indexed threads
124
+ - `facet-limit` means the max number of uncached per-thread facet analyses to run in a single report
123
125
  - Report language follows a best-effort system locale check
124
126
  - Main-thread analysis is the default; sub-agent threads are excluded unless you pass `--include-subagents`
125
127
  - The CLI shows an estimate before running in interactive terminals
package/lib/cli.js CHANGED
@@ -141,7 +141,7 @@ function parseArgs(argv) {
141
141
  jsonPath: null,
142
142
  htmlPath: null,
143
143
  days: 30,
144
- limit: 50,
144
+ limit: 200,
145
145
  preview: 50,
146
146
  provider: 'codex-cli',
147
147
  codexBin: null,
@@ -154,7 +154,7 @@ function parseArgs(argv) {
154
154
  insightModel: null,
155
155
  insightEffort: null,
156
156
  cacheDir: null,
157
- facetLimit: 20,
157
+ facetLimit: 50,
158
158
  lang: detectSystemLanguage(),
159
159
  includeArchived: false,
160
160
  includeSubagents: false,
@@ -330,7 +330,7 @@ Options:
330
330
  --json-path <path> Exact path for report.json
331
331
  --html-path <path> Exact path for report.html
332
332
  --days <n> Only include threads updated in the last N days (default: 30)
333
- --limit <n> Max threads to scan from the thread registry (default: 50)
333
+ --limit <n> Target number of substantive threads to include (default: 200)
334
334
  --preview <n> Number of threads to embed in the HTML report (default: 50)
335
335
  --provider <name> Model provider: codex-cli or openai (default: codex-cli)
336
336
  --codex-bin <path> Override the Codex CLI binary path for provider=codex-cli
@@ -344,7 +344,7 @@ Options:
344
344
  Reasoning effort for lower-risk sections
345
345
  --insight-model <name> Model for final report generation
346
346
  --insight-effort <level> Reasoning effort for higher-risk sections
347
- --facet-limit <n> Max uncached substantive threads to analyze (default: 20)
347
+ --facet-limit <n> Max uncached thread facets to analyze (default: 50)
348
348
  --cache-dir <path> Cache directory for session-meta and facet caches
349
349
  --lang <code> Report language: en or zh-CN (default: system language)
350
350
  --include-archived Include archived threads
@@ -657,8 +657,8 @@ function inferScopePreset(days) {
657
657
 
658
658
  function inferDepthPreset(options) {
659
659
  if (options.limit === 20 && options.facetLimit === 8) return 'conservative'
660
- if (options.limit === 50 && options.facetLimit === 20) return 'standard'
661
- if (options.limit === 200 && options.facetLimit === 50) return 'deep'
660
+ if (options.limit === 200 && options.facetLimit === 50) return 'standard'
661
+ if (options.limit === 400 && options.facetLimit === 50) return 'deep'
662
662
  return 'custom'
663
663
  }
664
664
 
@@ -682,8 +682,8 @@ function inferQualityPreset(options) {
682
682
 
683
683
  function applyScopePreset(options, preset) {
684
684
  if (preset === 'conservative') return { ...options, limit: 20, facetLimit: 8 }
685
- if (preset === 'deep') return { ...options, limit: 200, facetLimit: 50 }
686
- return { ...options, limit: 50, facetLimit: 20 }
685
+ if (preset === 'deep') return { ...options, limit: 400, facetLimit: 50 }
686
+ return { ...options, limit: 200, facetLimit: 50 }
687
687
  }
688
688
 
689
689
  function applyQualityPreset(options, preset) {
@@ -833,17 +833,17 @@ function getUiText(lang) {
833
833
  scopeCustom: '自定义天数',
834
834
  customDaysQuestion: '输入要分析的天数',
835
835
  depthQuestion: '选择分析深度:',
836
- depthConservative: '保守(20 threads / 8 facets)',
837
- depthStandard: '标准(50 threads / 20 facets)',
838
- depthDeep: '深度(200 threads / 50 facets)',
836
+ depthConservative: '保守(20 个有效线程 / 8 facets)',
837
+ depthStandard: '标准(200 个有效线程 / 50 facets)',
838
+ depthDeep: '深度(400 个有效线程 / 50 facets)',
839
839
  depthCustom: '自定义',
840
- limitQuestion: '输入最大 thread 数',
841
- facetLimitQuestion: '输入最大 facet 提取数',
840
+ limitQuestion: '输入目标有效线程数',
841
+ facetLimitQuestion: '输入最大新增 facet ',
842
842
  languageQuestion: '选择报告语言:',
843
843
  outputDirQuestion: '输出目录',
844
844
  openBrowserQuestion: '生成后自动打开浏览器?',
845
845
  qualityQuestion: '选择分析质量预设:',
846
- qualityCheaper: '更省(尽量用 spark)',
846
+ qualityCheaper: '更省(尽量用 gpt-5.4-mini)',
847
847
  qualityBalanced: '平衡',
848
848
  qualityHigher: '更高质量(更多使用 gpt-5.4)',
849
849
  yesDefault: '[Y/n]',
@@ -860,7 +860,7 @@ function getUiText(lang) {
860
860
  toWord: '到',
861
861
  likelyWord: '左右',
862
862
  plannedCallsLabel: '预计调用数',
863
- substantiveThreadsLabel: '有效线程',
863
+ substantiveThreadsLabel: '纳入报告线程',
864
864
  uncachedFacetsLabel: '未缓存 facets',
865
865
  longTranscriptsLabel: '长 transcript',
866
866
  inputEstimateLabel: '输入',
@@ -891,17 +891,17 @@ function getUiText(lang) {
891
891
  scopeCustom: 'Custom days',
892
892
  customDaysQuestion: 'Enter number of days to analyze',
893
893
  depthQuestion: 'Choose analysis depth:',
894
- depthConservative: 'Conservative (20 threads / 8 facets)',
895
- depthStandard: 'Standard (50 threads / 20 facets)',
896
- depthDeep: 'Deep (200 threads / 50 facets)',
894
+ depthConservative: 'Conservative (20 substantive threads / 8 facets)',
895
+ depthStandard: 'Standard (200 substantive threads / 50 facets)',
896
+ depthDeep: 'Deep (400 substantive threads / 50 facets)',
897
897
  depthCustom: 'Custom',
898
- limitQuestion: 'Enter max thread count',
899
- facetLimitQuestion: 'Enter max facet extraction count',
898
+ limitQuestion: 'Enter target substantive thread count',
899
+ facetLimitQuestion: 'Enter max new facet extraction count',
900
900
  languageQuestion: 'Choose report language:',
901
901
  outputDirQuestion: 'Output directory',
902
902
  openBrowserQuestion: 'Open the report in your browser after generation?',
903
903
  qualityQuestion: 'Choose quality preset:',
904
- qualityCheaper: 'Cheaper (more spark)',
904
+ qualityCheaper: 'Cheaper (more gpt-5.4-mini)',
905
905
  qualityBalanced: 'Balanced',
906
906
  qualityHigher: 'Higher quality (more gpt-5.4)',
907
907
  yesDefault: '[Y/n]',
@@ -918,7 +918,7 @@ function getUiText(lang) {
918
918
  toWord: 'to',
919
919
  likelyWord: 'likely',
920
920
  plannedCallsLabel: 'planned calls',
921
- substantiveThreadsLabel: 'substantive threads',
921
+ substantiveThreadsLabel: 'threads in report',
922
922
  uncachedFacetsLabel: 'uncached facets',
923
923
  longTranscriptsLabel: 'long transcripts',
924
924
  inputEstimateLabel: 'input',
package/lib/codex-data.js CHANGED
@@ -44,6 +44,7 @@ export async function loadThreads({
44
44
  codexHome,
45
45
  sinceEpochSeconds,
46
46
  limit,
47
+ offset,
47
48
  includeArchived,
48
49
  includeSubagents,
49
50
  }) {
@@ -66,6 +67,7 @@ export async function loadThreads({
66
67
  where.length ? `where ${where.join(' and ')}` : '',
67
68
  'order by updated_at desc',
68
69
  limit ? `limit ${Number(limit)}` : '',
70
+ offset ? `offset ${Number(offset)}` : '',
69
71
  ';',
70
72
  ]
71
73
  .filter(Boolean)
@@ -115,11 +117,15 @@ export async function loadRolloutEvents(rolloutPath) {
115
117
  return events
116
118
  }
117
119
 
120
+ export function isSubstantiveThread(thread) {
121
+ if (thread.userMessages < 2) return false
122
+ if (thread.durationMinutes < 1) return false
123
+ return Boolean(String(thread.transcriptForAnalysis || '').trim())
124
+ }
125
+
118
126
  export function filterSubstantiveThreads(threadSummaries) {
119
127
  return [...threadSummaries]
120
- .filter(thread => thread.userMessages >= 2)
121
- .filter(thread => thread.durationMinutes >= 1)
122
- .filter(thread => Boolean(String(thread.transcriptForAnalysis || '').trim()))
128
+ .filter(isSubstantiveThread)
123
129
  .sort((a, b) => Date.parse(b.updatedAt) - Date.parse(a.updatedAt))
124
130
  }
125
131
 
@@ -440,14 +446,43 @@ export function summarizeThread(thread, events) {
440
446
  }
441
447
 
442
448
  export async function collectThreadSummaries(options) {
443
- const threads = await loadThreads(options)
444
449
  const cacheDir = resolveSessionMetaCacheDir(options.cacheDir)
445
450
  await fs.mkdir(cacheDir, { recursive: true })
446
451
 
452
+ const substantiveTarget = Number(options.limit ?? 0)
453
+ const pageSize = substantiveTarget > 0 ? substantiveTarget : 200
447
454
  const summaries = []
448
- for (const thread of threads) {
449
- const summary = await loadCachedOrFreshSummary(thread, cacheDir)
450
- summaries.push(summary)
455
+ let offset = 0
456
+ let substantiveCount = 0
457
+
458
+ while (true) {
459
+ const threads = await loadThreads({
460
+ ...options,
461
+ limit: pageSize,
462
+ offset,
463
+ })
464
+ if (!threads.length) break
465
+
466
+ for (const thread of threads) {
467
+ const summary = await loadCachedOrFreshSummary(thread, cacheDir)
468
+ summaries.push(summary)
469
+ if (isSubstantiveThread(summary)) {
470
+ substantiveCount += 1
471
+ }
472
+ }
473
+
474
+ if (substantiveTarget > 0 && substantiveCount >= substantiveTarget) {
475
+ break
476
+ }
477
+ if (threads.length < pageSize) {
478
+ break
479
+ }
480
+
481
+ offset += threads.length
482
+ }
483
+
484
+ if (substantiveTarget > 0) {
485
+ return filterSubstantiveThreads(summaries).slice(0, substantiveTarget)
451
486
  }
452
487
  return summaries
453
488
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-session-insights",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Generate a report analyzing your Codex sessions.",
5
5
  "type": "module",
6
6
  "bin": {