Skip to content

Add Mintlify analytics fetch scripts for assistant insights - #1222

Merged
comfyui-wiki merged 4 commits into
mainfrom
feat/mintlify-analytics-cache
Jul 4, 2026
Merged

Add Mintlify analytics fetch scripts for assistant insights#1222
comfyui-wiki merged 4 commits into
mainfrom
feat/mintlify-analytics-cache

Conversation

@comfyui-wiki

Copy link
Copy Markdown
Member

Summary

  • Add a Bun CLI under .github/scripts/analytics/ to pull Mintlify AI assistant conversations, search terms, and user feedback into a local gitignored cache (tmp/analytics-cache/).
  • Support incremental updates, 1-year full history (analytics:fetch:all), checkpoint resume after 504/429/interrupt, rate limiting, custom date ranges, and --assistant-only for AI Q&A-first workflows.
  • Wire npm scripts, document setup in README/AGENTS.md, and add MINTLIFY_PROJECT_ID + optional throttle env vars to .env.local.example.

Test plan

  • Copy .env.local.example.env.local and set MINTLIFY_API_KEY + MINTLIFY_PROJECT_ID
  • Run pnpm analytics:fetch:dry-run and confirm date range / mode logging
  • Run pnpm analytics:fetch:assistant -- --days 7 and verify tmp/analytics-cache/assistant-summary.md + by-day/ output
  • Interrupt mid-run and confirm pnpm analytics:fetch -- --resume continues from checkpoint
  • Confirm tmp/analytics-cache/ stays gitignored

@mintlify

mintlify Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
comfy 🟢 Ready View Preview Jul 4, 2026, 5:02 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@comfyui-wiki, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f970c986-59e9-4eda-a03b-08958d3ae913

📥 Commits

Reviewing files that changed from the base of the PR and between 58d2231 and 9f6f855.

📒 Files selected for processing (11)
  • .env.local.example
  • .github/scripts/analytics/README.md
  • .github/scripts/analytics/analytics-checkpoint.ts
  • .github/scripts/analytics/analytics-writers.ts
  • .github/scripts/analytics/fetch-assistant-insights.ts
  • .github/scripts/analytics/mintlify-analytics.ts
  • .github/scripts/cms/README.md
  • .github/scripts/i18n/README.md
  • .gitignore
  • AGENTS.md
  • package.json
📝 Walkthrough

Walkthrough

This PR adds a Mintlify analytics cache pipeline: API fetching with pagination and retries, checkpointed local persistence, per-day Markdown/JSON outputs, a CLI to run assistant/search/feedback exports, and updated environment/docs/script wiring.

Changes

Mintlify Analytics Cache Fetch Pipeline

Layer / File(s) Summary
Mintlify API client and pagination
.github/scripts/analytics/mintlify-analytics.ts
Adds typed analytics models, authenticated fetching with retry/backoff, cursor pagination with 414 bisecting, chunked range fetches, and date-range utilities.
Checkpoint and store persistence
.github/scripts/analytics/analytics-checkpoint.ts
Adds checkpoint/store JSON shapes, atomic read/write helpers, checkpoint lifecycle operations, merge/dedupe logic, and incremental range computation.
Markdown/JSON report writers
.github/scripts/analytics/analytics-writers.ts
Converts conversations to slim records, groups by day, computes stats, and writes per-day partitions plus range-level index artifacts.
CLI orchestration script
.github/scripts/analytics/fetch-assistant-insights.ts
Implements the Bun CLI flow for parsing flags, resolving run modes, fetching in phases, persisting progress, and handling resume/failure behavior.
Env, docs, and package.json wiring
.env.local.example, .github/scripts/analytics/README.md, AGENTS.md, .gitignore, package.json
Updates analytics env vars, adds workflow docs, refreshes agent guidance, adjusts the cache comment, and adds analytics:fetch* scripts.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant fetch-assistant-insights
  participant analytics-checkpoint
  participant mintlify-analytics
  participant analytics-writers

  User->>fetch-assistant-insights: pnpm analytics:fetch
  fetch-assistant-insights->>analytics-checkpoint: loadCheckpoint / createCheckpoint
  fetch-assistant-insights->>mintlify-analytics: fetch assistant conversations chunked
  mintlify-analytics-->>fetch-assistant-insights: conversation batch
  fetch-assistant-insights->>analytics-checkpoint: markChunkComplete, saveConversationStore
  fetch-assistant-insights->>mintlify-analytics: fetch search queries chunked
  fetch-assistant-insights->>mintlify-analytics: fetch feedback chunked
  fetch-assistant-insights->>analytics-writers: writeSplitSummaries(range, data)
  analytics-writers-->>fetch-assistant-insights: dayFiles, dayStats
  fetch-assistant-insights->>analytics-checkpoint: clearCheckpoint
  fetch-assistant-insights-->>User: manifest.json + summary report
Loading

Compact metadata

  • Type: Feature addition
  • Estimated review effort: High

Related issues: None referenced.

Related PRs: None referenced.

Suggested labels: enhancement, tooling, documentation

Suggested reviewers: Reviewer familiar with Bun/TypeScript CLI scripts and Mintlify API integration

A cache for chats, a cache for clues,
with checkpoints, retries, and daily views.
If the fetch gets grumpy and throws a fit,
resume right where it left off — neat.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/mintlify-analytics-cache
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/mintlify-analytics-cache

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/scripts/analytics/analytics-checkpoint.ts:
- Around line 76-79: The writeJsonFile helper is doing a direct overwrite of the
target checkpoint/store file, which can leave a truncated or invalid JSON file
if the run is interrupted. Update writeJsonFile in analytics-checkpoint.ts to
write the JSON to a temporary file first and then atomically replace the
destination with a same-filesystem rename, so readJsonFile, saveCheckpoint, and
markChunkComplete never observe partial writes.
- Around line 91-97: clearCheckpoint currently depends on readJsonFile failing
JSON.parse of an empty file instead of actually clearing state. Update
clearCheckpoint to remove the checkpoint file directly (or otherwise write an
explicit sentinel value) using checkpointPath and the filesystem API, and keep
the existing error swallowing behavior so callers still treat missing/cleared
checkpoints as non-fatal.
- Around line 150-167: The mergeSearches function is double-counting hits during
incremental refreshes because overlapping ranges re-fetch the same query window.
Update mergeSearches to avoid adding row.hits to an existing SearchRow; instead
preserve the latest row’s hits (or otherwise dedupe overlapping range data)
while still keeping the newer lastSearchedAt, topClickedPage, and ctr in
mergeSearches. Use the existing mergeSearches and incrementalRangeFromManifest
behavior as the key places to adjust the aggregation logic.

In @.github/scripts/analytics/analytics-writers.ts:
- Around line 26-38: The day-report writer is persisting raw user queries
without any truncation or redaction, so sensitive input can leak into shareable
analytics artifacts. Update toSlim and the downstream buildDayMarkdown flow to
scrub or redact the query before it is written to Markdown/JSON, similar to how
responsePreview is handled. Keep the fix localized to the analytics-writers.ts
helpers so all report generation paths use the same sanitized value.

In @.github/scripts/analytics/fetch-assistant-insights.ts:
- Around line 430-433: The search store is being loaded twice in the same block,
causing redundant disk and JSON parsing work. Update the logic around
loadSearchStore(CACHE_DIR) to read it once, store the result in a single local
variable, and destructure both searches and totalSearches from that object
alongside the existing loadConversationStore and loadFeedbackStore reads.
- Around line 122-129: The env-derived paging values in
fetch-assistant-insights.ts are not using the same bounds as the CLI flags, so
ANALYTICS_PAGE_LIMIT can exceed the allowed maximum and get passed through to
fetchOpts.limit. Update the options construction in the fetch-assistant-insights
logic to apply the same 1..1000 clamp used by the CLI page-limit parsing, while
keeping ANALYTICS_PAGE_DELAY_MS validated with the existing non-negative check,
so both env and CLI paths share consistent paging limits.
- Around line 461-464: The chunkDays guard in fetch-assistant-insights.ts is
using fetchRange.dateFrom !== fetchRange.dateTo, which is always true and makes
the DEFAULT_DAYS cap unreachable. Update the condition in the chunkDays
assignment to check the actual date range span instead of comparing endpoints,
so the Math.min(options.chunkDays, DEFAULT_DAYS) branch only applies for small
windows.

In @.github/scripts/analytics/mintlify-analytics.ts:
- Around line 101-103: The chunkKey implementation is duplicated in
analytics-checkpoint, so keep a single source of truth by importing the exported
chunkKey from mintlify-analytics.ts instead of redefining it. Update the
analytics-checkpoint module to reuse chunkKey directly and remove the verbatim
copy so both callers stay in sync if the DateRange key format changes.
- Around line 479-531: The chunked fetch helpers are overriding caller progress
callbacks instead of forwarding them, so `fetchSearchQueriesChunked` (and the
matching `fetchFeedbackChunked`) drop `options.onProgress` entirely while
printing progress. Update the inline `onProgress` wrapper in
`fetchSearchQueriesChunked` to invoke `options.onProgress?.(progress)` before or
alongside the console write, and apply the same change in `fetchFeedbackChunked`
so it matches `fetchAssistantConversationsChunked` behavior and preserves
`PaginatedFetchOptions` hooks.
- Around line 236-279: The pagination loop in fetchPaginated can repeat forever
if the API keeps returning the same cursor or a cursor that normalizes to an
already-seen value. Update fetchPaginated to track the previous cursor before
assigning cursor and break with a warning when the next cursor does not advance,
or add a sane max-pages safety cap. Use the existing fetchPaginated, hasMore,
normalizeCursor, and cursor handling logic to keep the fix localized.
- Around line 326-349: fetchAllSearchQueries is overwriting totalSearches for
each fetched page, so bisected fetches only keep the last branch’s count. Update
the logic inside fetchAllSearchQueries (and the fetchPaginatedWithBisect
callback path it uses) so totalSearches is accumulated per page/recursive branch
instead of reassigned, while still returning the merged searches array and
correct overall total.
- Line 7: The default page delay is still too low and can exceed Mintlify’s
request limit when parseArgs() falls back to DEFAULT_PAGE_DELAY_MS and the fetch
flow uses it unchanged. Update the DEFAULT_PAGE_DELAY_MS constant in
mintlify-analytics.ts to match the 100 req/hour cap (about 36 seconds) or
compute it from that limit, so the default run throttles correctly without
requiring callers to override pageDelayMs. Ensure the new default is used
consistently by the parseArgs() fallback and the downstream fetch path.

In @.github/scripts/analytics/README.md:
- Around line 131-140: The README text in the analytics output section
hard-codes a 14-day chunk, but the batching is configurable and chunk-based.
Update the description under the gitignored output for the fetcher/docs so it
refers generically to chunk/window-based updates instead of a fixed 14-day
period, keeping the wording aligned with the analytics fetcher behavior and the
output paths like assistant-summary.md and by-day/YYYY-MM-DD.md.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b4b1efc3-3317-471b-adfd-08c4d10f43b3

📥 Commits

Reviewing files that changed from the base of the PR and between 5b8f020 and 0a8ef05.

📒 Files selected for processing (9)
  • .env.local.example
  • .github/scripts/analytics/README.md
  • .github/scripts/analytics/analytics-checkpoint.ts
  • .github/scripts/analytics/analytics-writers.ts
  • .github/scripts/analytics/fetch-assistant-insights.ts
  • .github/scripts/analytics/mintlify-analytics.ts
  • .gitignore
  • AGENTS.md
  • package.json

Comment thread .github/scripts/analytics/analytics-checkpoint.ts
Comment thread .github/scripts/analytics/analytics-checkpoint.ts
Comment thread .github/scripts/analytics/analytics-checkpoint.ts
Comment thread .github/scripts/analytics/analytics-writers.ts
Comment thread .github/scripts/analytics/fetch-assistant-insights.ts
Comment on lines +101 to +103
export function chunkKey(range: DateRange): string {
return `${range.dateFrom}_${range.dateTo}`;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

chunkKey duplicated verbatim in analytics-checkpoint.ts.

Same implementation exists at analytics-checkpoint.ts Lines 56-58. Since this file already exports chunkKey, the checkpoint module should import it instead of redefining, avoiding future drift between the two copies.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/analytics/mintlify-analytics.ts around lines 101 - 103, The
chunkKey implementation is duplicated in analytics-checkpoint, so keep a single
source of truth by importing the exported chunkKey from mintlify-analytics.ts
instead of redefining it. Update the analytics-checkpoint module to reuse
chunkKey directly and remove the verbatim copy so both callers stay in sync if
the DateRange key format changes.

Comment thread .github/scripts/analytics/mintlify-analytics.ts
Comment thread .github/scripts/analytics/mintlify-analytics.ts
Comment thread .github/scripts/analytics/mintlify-analytics.ts
Comment thread .github/scripts/analytics/README.md Outdated
comfyui-wiki added a commit that referenced this pull request Jul 4, 2026
Atomic JSON writes, fix search merge double-counting, pagination guards, rate-limit defaults, and other robustness improvements from PR #1222 review.
Introduce a local analytics cache CLI (assistant, searches, feedback) with checkpoint resume and rate limiting. Centralize env var documentation in .github/ENV.local.md and keep AGENTS.md to brief references only.
@comfyui-wiki
comfyui-wiki force-pushed the feat/mintlify-analytics-cache branch from db9e782 to 7ba1235 Compare July 4, 2026 17:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/scripts/analytics/fetch-assistant-insights.ts (1)

629-651: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Persist totalSearches before writing outputs
fetchSearchQueriesChunked returns an aggregated totalSearches, but this call site drops it and never writes back to searchStore.totalSearches. Fresh runs will pass 0 into writeOutputs(...), so the total-searches summary can come out empty even when rows exist.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/analytics/fetch-assistant-insights.ts around lines 629 -
651, The search-query fetch flow is ignoring the aggregated totalSearches
returned by fetchSearchQueriesChunked, so searchStore.totalSearches never gets
updated before later output writing. Update the fetchSearchQueriesChunked call
site in fetch-assistant-insights.ts to capture the returned totalSearches and
assign it back onto searchStore.totalSearches before moving on to checkpointing
or writeOutputs, using the existing searchStore and fetchSearchQueriesChunked
symbols to locate the change.
.github/scripts/analytics/analytics-checkpoint.ts (1)

155-173: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Don’t reuse mergeSearches for per-chunk search aggregation
splitDateRange creates non-overlapping windows, and fetchSearchQueriesChunked already sums hits across them. The onChunkComplete path still merges each raw chunk with mergeSearches, so the “keep the fresher row” branch can overwrite hits and drop earlier chunks for the same query. Keep that freshness-based merge for overlapping incremental re-fetches only, and use the chunked function’s merged return value for the intra-run store.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/analytics/analytics-checkpoint.ts around lines 155 - 173,
The current use of mergeSearches in onChunkComplete is mixing overlapping
incremental re-fetch logic with non-overlapping chunk aggregation, which can
overwrite summed hits for the same query. Keep mergeSearches reserved for
freshness-based incremental updates only, and switch the chunked path to use the
merged return value from fetchSearchQueriesChunked for the intra-run store.
Ensure splitDateRange-based chunks are accumulated by summing their results
rather than applying the “keep the fresher row” branch in mergeSearches.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/scripts/analytics/analytics-checkpoint.ts:
- Around line 155-173: The current use of mergeSearches in onChunkComplete is
mixing overlapping incremental re-fetch logic with non-overlapping chunk
aggregation, which can overwrite summed hits for the same query. Keep
mergeSearches reserved for freshness-based incremental updates only, and switch
the chunked path to use the merged return value from fetchSearchQueriesChunked
for the intra-run store. Ensure splitDateRange-based chunks are accumulated by
summing their results rather than applying the “keep the fresher row” branch in
mergeSearches.

In @.github/scripts/analytics/fetch-assistant-insights.ts:
- Around line 629-651: The search-query fetch flow is ignoring the aggregated
totalSearches returned by fetchSearchQueriesChunked, so
searchStore.totalSearches never gets updated before later output writing. Update
the fetchSearchQueriesChunked call site in fetch-assistant-insights.ts to
capture the returned totalSearches and assign it back onto
searchStore.totalSearches before moving on to checkpointing or writeOutputs,
using the existing searchStore and fetchSearchQueriesChunked symbols to locate
the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 79486107-c4d0-4657-807c-fef8c719e323

📥 Commits

Reviewing files that changed from the base of the PR and between 0a8ef05 and 58d2231.

📒 Files selected for processing (5)
  • .github/scripts/analytics/README.md
  • .github/scripts/analytics/analytics-checkpoint.ts
  • .github/scripts/analytics/analytics-writers.ts
  • .github/scripts/analytics/fetch-assistant-insights.ts
  • .github/scripts/analytics/mintlify-analytics.ts

Drop the redundant env doc and restore inline comments in the example file; update cross-references in AGENTS.md and script READMEs.
Keep AGENTS.md to skills plus doc links; document changelog fork, commands, and agent rules in i18n and cms READMEs.
Keep English MDX editing rules in the agent entrypoint; i18n README links back instead of duplicating them.
@comfyui-wiki
comfyui-wiki merged commit 6148181 into main Jul 4, 2026
8 checks passed
@github-actions
github-actions Bot deleted the feat/mintlify-analytics-cache branch July 4, 2026 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant