feat(intelligence): add Graph Export#2967
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (10)
💤 Files with no reviewable changes (6)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughWalkthroughAdds a complete knowledge graph export feature: pure serialization functions (JSON/CSV) with RFC 4180 CSV formatting, an API loader for graph relations, two React components (stateless panel and stateful container), page integration with tab routing, and English localization. ChangesKnowledge Graph Export Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@app/src/components/intelligence/GraphExportTab.tsx`:
- Around line 47-54: The blob URL is revoked immediately after anchor.click(),
which can cancel the download; update the download flow in GraphExportTab to
defer revocation like the pattern used in McpInventoryExportTab: create the URL
(url), set anchor.href and download, append and call anchor.click(), then defer
URL.revokeObjectURL(url) (for example via setTimeout or a short delay/onfocus
handler) and remove the anchor afterwards so the browser has time to start the
download; reference variables/functions: url, anchor, nowSeconds(), format.
- Around line 58-59: Replace the raw relation count with the number of
exportable rows: import toExportRows from ../../lib/memory/graphExport, compute
exportableRows = relations ? toExportRows(relations).length : null, and pass
count={exportableRows} into the GraphExportPanel so the badge reflects the
actual rows serializeGraph() will produce (handle null/undefined relations as
before).
🪄 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: CHILL
Plan: Pro
Run ID: 162f7226-6bf1-48f1-aa87-be65e34b6559
📒 Files selected for processing (23)
app/src/components/intelligence/GraphExportPanel.test.tsxapp/src/components/intelligence/GraphExportPanel.tsxapp/src/components/intelligence/GraphExportTab.test.tsxapp/src/components/intelligence/GraphExportTab.tsxapp/src/lib/i18n/chunks/ar-1.tsapp/src/lib/i18n/chunks/bn-1.tsapp/src/lib/i18n/chunks/de-1.tsapp/src/lib/i18n/chunks/en-1.tsapp/src/lib/i18n/chunks/es-1.tsapp/src/lib/i18n/chunks/fr-1.tsapp/src/lib/i18n/chunks/hi-1.tsapp/src/lib/i18n/chunks/id-1.tsapp/src/lib/i18n/chunks/it-1.tsapp/src/lib/i18n/chunks/ko-1.tsapp/src/lib/i18n/chunks/pt-1.tsapp/src/lib/i18n/chunks/ru-1.tsapp/src/lib/i18n/chunks/zh-CN-1.tsapp/src/lib/i18n/en.tsapp/src/lib/memory/graphExport.test.tsapp/src/lib/memory/graphExport.tsapp/src/pages/Intelligence.tsxapp/src/services/api/graphExportApi.test.tsapp/src/services/api/graphExportApi.ts
…count Address CodeRabbit review on tinyhumansai#2967: - Defer URL.revokeObjectURL to a macrotask so the browser has started reading the Blob before it is freed (synchronous revoke can cancel the download). - Show the EXPORTABLE row count (toExportRows drops malformed relations), not the raw relations.length, so the "N facts ready to export" label is accurate. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…count Address CodeRabbit review on tinyhumansai#2967: - Defer URL.revokeObjectURL to a macrotask so the browser has started reading the Blob before it is freed (synchronous revoke can cancel the download). - Show the EXPORTABLE row count (toExportRows drops malformed relations), not the raw relations.length, so the "N facts ready to export" label is accurate. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
418b6e6 to
2e2fdc5
Compare
A new read-only "Export" tab for data portability: download the entire memory
knowledge graph as JSON or CSV — a different KIND of feature from the analytics
lenses, giving the user ownership of their data.
- Pure deterministic serializers (lib/memory/graphExport.ts): toJsonExport and
toCsvExport over a stable {subject,predicate,object,namespace,evidenceCount,
updatedAt} projection (malformed rows dropped). CSV follows RFC 4180 — fields
containing comma/quote/CR/LF are quoted and embedded quotes doubled, with CRLF
row terminators — so entity names with commas/quotes/newlines round-trip.
- Zero new core surface: reuses ONLY memoryGraphQuery. Read-only — the download
(Blob + anchor) happens in the container's click handler, never during render.
- Container/presentational split; the container guards the load with a request
token; the pure panel renders the count + a JSON/CSV format toggle + download
button. i18n across all 13 locales.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…count Address CodeRabbit review on tinyhumansai#2967: - Defer URL.revokeObjectURL to a macrotask so the browser has started reading the Blob before it is freed (synchronous revoke can cancel the download). - Show the EXPORTABLE row count (toExportRows drops malformed relations), not the raw relations.length, so the "N facts ready to export" label is accurate. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2e2fdc5 to
b3e5324
Compare
Summary
Adds a new read-only "Export" tab for data portability: download the entire memory knowledge graph as JSON or CSV. A different kind of feature from the analytics lenses — it's about giving the user ownership of their data ("your memory, yours to keep").
Design
lib/memory/graphExport.ts):toJsonExportandtoCsvExportover a stable{subject, predicate, object, namespace, evidenceCount, updatedAt}projection (malformed rows dropped). The CSV follows RFC 4180 — a field is quoted when it contains a comma, double-quote, CR, or LF; embedded double-quotes are doubled; rows are CRLF-terminated — so entity names with commas/quotes/newlines round-trip safely.memoryGraphQuery. Read-only — the download itself (Blob + object URL + anchor) happens in the container's click handler, never during render, so the engine stays pure.Test plan
vitest— 19 tests (engine: projection/malformed-drop/null-namespace/non-finite normalization, JSON round-trip, CSV RFC-4180 escaping for commas/quotes/newlines + CRLF + empty-graph header, format dispatch + MIME; api facade; panel states + format toggle/download callbacks; container load + Blob-download trigger + error)tsc --noEmit— cleaneslint— 0 errorsprettier --check— cleangraphExport.*keys🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes