Skip to content

feat(migration): OpenClaw import surface + unblock unified-core Apply#2087

Merged
senamakel merged 6 commits into
tinyhumansai:mainfrom
obchain:feat/1440-migration-panel
May 19, 2026
Merged

feat(migration): OpenClaw import surface + unblock unified-core Apply#2087
senamakel merged 6 commits into
tinyhumansai:mainfrom
obchain:feat/1440-migration-panel

Conversation

@obchain
Copy link
Copy Markdown
Contributor

@obchain obchain commented May 18, 2026

Summary

  • Re-enable the disabled create_memory_for_migration factory so the Apply path of openhuman.migrate_openclaw actually moves data instead of bailing with "memory migration is disabled for the unified namespace memory core."
  • Add a Settings → Account → "Import from another assistant" panel that wraps the RPC with a preview-then-apply flow — the discoverability surface called out as the Feat/gitbooks #1 gap in Simplify migration from OpenClaw and Hermes Agent into OpenHuman #1440.
  • Hermes lands as "on the roadmap" with a context link to Simplify migration from OpenClaw and Hermes Agent into OpenHuman #1440 (per the acceptance criteria: "do not leave Hermes unmentioned in UX; coming soon is acceptable").
  • 13 new tests (6 Rust: 5 pre-existing + 1 new fresh-import integration test; 7 Vitest: panel UX matrix).
  • New coverage matrix row 13.5.4 Migration from another assistant (OpenClaw).

Problem

#1440 (raised by @senamakel) flagged three things:

  1. Discoverability — migration RPC has lived under src/openhuman/migration/ for a while with zero UI surface.
  2. Dry-run vs apply must be obvious — the RPC defaults dry_run to true, which surprises CLI/RPC callers who expect "I clicked Import, my data should move."
  3. Hermes — no in-tree importer; either ship one or honestly track it.

Discovered while smoke-testing the UI: even with the panel wired, Apply was dead at the backend. src/openhuman/memory/store/factories.rs:442 had create_memory_for_migration permanently bail!ed with "memory migration is disabled for the unified namespace memory core" — left over from the unified namespace memory landing. Without unblocking that, the UI would have shipped half-broken: users would discover the migration surface, run Preview, click Apply, and watch it fail with a backend error nobody could action without reading Rust source.

Solution

Three layers, sized to scope:

1. Backend re-enable (src/openhuman/memory/store/factories.rs, src/openhuman/migration/core.rs)

Under the unified namespace memory core there is no separate "migration backend" — the importer just needs a writable Box<dyn Memory> rooted at the active workspace, which is exactly what create_memory(config, workspace_dir) already produces.

  • create_memory_for_migration now delegates to create_memory. Old behavior was unconditional bail.
  • Signature changes from (&str, &Path) to (&MemoryConfig, &Path) so we can pass the full memory config; the sole caller (target_memory_backend) already has &Config in scope.
  • The "always errors" regression test in factories.rs is replaced with a positive create_memory_for_migration_returns_writable_memory_on_unified_core that pins the new contract.
  • New integration test migrate_openclaw_apply_imports_markdown_entries_into_target_workspace exercises the full Apply path against a temp OpenClaw workspace and asserts imported >= 1.

2. Settings panel (app/src/components/settings/panels/MigrationPanel.tsx)

  • Vendor <select> — OpenClaw active, Hermes disabled with an honest "on the roadmap" callout that links to Simplify migration from OpenClaw and Hermes Agent into OpenHuman #1440 for context.
  • Optional source path input (blank → backend auto-resolves ~/.openclaw/workspace).
  • Preview button hits the RPC with dry_run=true and renders the returned MigrationReport — source/target paths, per-source counts (from_sqlite, from_markdown), imported, skipped_unchanged, renamed_conflicts, warnings.
  • Apply button — disabled until a successful Preview lands, fires window.confirm with the planned counts, then calls the RPC with dry_run=false and shows the post-apply report.
  • Inline error surface survives the form so the user can edit + retry without losing context.
  • Wired into Settings via a new migration route + sidebar item under the Account section.
  • English i18n keys under migration.* and pages.settings.account.migration*. Other locales fall back to English via the existing t() fallback chain.

3. Coverage matrix (docs/TEST-COVERAGE-MATRIX.md)

New row 13.5.4 Migration from another assistant (OpenClaw) — was ❌, now ✅, layer VU+RU.

Why preview-then-apply (not single Import button)?

The instinct is to flip dry_run's default. The downside: the existing RPC contract is load-bearing for any external script that's been calling it with the dry-run default. A safer UX-side fix: keep the RPC contract as-is, but make the UI explicit — Preview = dry_run=true, Apply = dry_run=false + confirm. The user always knows which mode they're in.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy — 7 new Vitest tests + 1 new Rust integration test + 1 positive Rust factories test (replacing the "always errors" regression).
  • Diff coverage ≥ 80% — every visible code path in the new panel is exercised by a test (preview, apply, error, vendor switch, confirm cancel, source path); backend re-enable is exercised by both unit + integration tests.
  • Coverage matrix updated — new row 13.5.4 in docs/TEST-COVERAGE-MATRIX.md.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related.
  • No new external network dependencies introduced — reuses the existing openhuman.migrate_openclaw RPC + create_memory factory; no new deps.
  • Manual smoke checklist — verified end-to-end against a real OpenClaw-shaped workspace (~/.openclaw/workspace with MEMORY.md + 2 memory/*.md files): Preview returns from_markdown=3, imported=0; Apply succeeds (no more bail), backup directory created, report renders inline; idempotent re-Apply reports skipped_unchanged=3.
  • N/A: Linked issue is not auto-closed by this PR — see ## Related. Simplify migration from OpenClaw and Hermes Agent into OpenHuman #1440 covers OpenClaw + Hermes; this PR ships OpenClaw end-to-end and leaves Simplify migration from OpenClaw and Hermes Agent into OpenHuman #1440 open for the Hermes companion (per acceptance criterion 2: "do not leave Hermes unmentioned in UX; 'coming soon' is acceptable only with linked tracking issue").

Impact

  • Runtime: desktop only. No new IPC commands. No new RPC method. RPC contract for openhuman.migrate_openclaw unchanged (dry_run still defaults to true at the handler level — old CLI/RPC callers continue to behave identically).
  • Performance: Apply now actually does work where it previously failed fast. The work itself is bounded by the OpenClaw source size; backup is one-time before the writes.
  • Security: positive — moves migration off the "you have to know the RPC name" surface and onto an explicit confirm flow.
  • Migration: backward compatible. Existing memory is backed up before any import runs (the backup_target_memory helper was already in place; only the bail in front of it was the blocker).
  • Compatibility: cloud-independent. Works in fully-local mode since both halves are local-only.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A — human-authored, GitHub issue only.
  • URL: N/A

Commit & Branch

  • Branch: N/A
  • Commit SHA: N/A

Validation Run

  • pnpm --filter openhuman-app format:check
  • pnpm typecheck
  • Focused tests:
    • pnpm exec vitest run --config test/vitest.config.ts src/components/settings/panels/__tests__/MigrationPanel.test.tsx — 7 passed
    • pnpm debug rust migrate_openclaw — 6 passed (including the new Apply integration test)
    • pnpm debug rust create_memory_for_migration — 1 passed (positive replacement of the always-errors regression)
  • Rust fmt/check (via cargo check --manifest-path Cargo.toml) — clean.
  • N/A: Tauri fmt/check (no Tauri shell changes).

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: OpenClaw migration is now discoverable from Settings AND the Apply path actually writes data instead of bailing.
  • User-visible effect: new "Import from another assistant" item under Settings → Account; Preview shows planned counts, Apply imports markdown + brain.db entries into the workspace memory with a backup created first.

Parity Contract

  • Legacy behavior preserved: openhuman.migrate_openclaw RPC contract unchanged (dry_run defaults to true at the handler level). CLI / RPC callers continue to behave identically.
  • Guard/fallback/dispatch parity checks: backup is still created before any write; idempotency check (existing entry with same content → skipped_unchanged) untouched; rename-on-conflict behavior untouched. Only the bail in front of all that is replaced.

Duplicate / Superseded PR Handling

Summary by CodeRabbit

  • New Features

    • Added a Migration settings panel: choose vendor, optional source path, Preview (dry-run) then Apply (import) after a successful preview; Apply disabled until preview and requires confirmation; shows preview/applied reports, inline errors, and Hermes marked “coming soon” with a tracker link. Registered Migration in Settings navigation.
  • Localization

    • Added migration UI translations across many languages.
  • Tests

    • Added UI tests covering the preview→apply workflow.
  • Documentation

    • Updated test-coverage matrix for migration.

Review Change Stack

@obchain obchain requested a review from a team May 18, 2026 10:35
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a65bc236-2cd9-44f2-b6d6-69703d8921d6

📥 Commits

Reviewing files that changed from the base of the PR and between ebb6bda and a350509.

📒 Files selected for processing (30)
  • app/src/components/settings/panels/MigrationPanel.tsx
  • app/src/components/settings/panels/__tests__/MigrationPanel.test.tsx
  • app/src/lib/i18n/chunks/ar-1.ts
  • app/src/lib/i18n/chunks/ar-4.ts
  • app/src/lib/i18n/chunks/bn-1.ts
  • app/src/lib/i18n/chunks/bn-4.ts
  • app/src/lib/i18n/chunks/en-1.ts
  • app/src/lib/i18n/chunks/en-4.ts
  • app/src/lib/i18n/chunks/es-1.ts
  • app/src/lib/i18n/chunks/es-4.ts
  • app/src/lib/i18n/chunks/fr-1.ts
  • app/src/lib/i18n/chunks/fr-4.ts
  • app/src/lib/i18n/chunks/hi-1.ts
  • app/src/lib/i18n/chunks/hi-4.ts
  • app/src/lib/i18n/chunks/id-1.ts
  • app/src/lib/i18n/chunks/id-4.ts
  • app/src/lib/i18n/chunks/it-1.ts
  • app/src/lib/i18n/chunks/it-4.ts
  • app/src/lib/i18n/chunks/pt-1.ts
  • app/src/lib/i18n/chunks/pt-4.ts
  • app/src/lib/i18n/chunks/ru-1.ts
  • app/src/lib/i18n/chunks/ru-4.ts
  • app/src/lib/i18n/chunks/zh-CN-1.ts
  • app/src/lib/i18n/chunks/zh-CN-4.ts
  • app/src/lib/i18n/en.ts
  • app/src/pages/Settings.tsx
  • docs/TEST-COVERAGE-MATRIX.md
  • src/openhuman/memory/store/factories.rs
  • src/openhuman/migration/core.rs
  • src/openhuman/migration/ops.rs
✅ Files skipped from review due to trivial changes (11)
  • app/src/lib/i18n/chunks/en-1.ts
  • app/src/lib/i18n/chunks/bn-1.ts
  • app/src/lib/i18n/chunks/bn-4.ts
  • app/src/lib/i18n/chunks/pt-4.ts
  • app/src/lib/i18n/chunks/en-4.ts
  • app/src/lib/i18n/chunks/pt-1.ts
  • app/src/lib/i18n/chunks/it-1.ts
  • app/src/lib/i18n/chunks/es-4.ts
  • app/src/lib/i18n/chunks/ar-1.ts
  • docs/TEST-COVERAGE-MATRIX.md
  • app/src/lib/i18n/chunks/es-1.ts
🚧 Files skipped from review as they are similar to previous changes (18)
  • app/src/lib/i18n/chunks/zh-CN-4.ts
  • src/openhuman/migration/core.rs
  • app/src/lib/i18n/chunks/it-4.ts
  • app/src/lib/i18n/chunks/ru-1.ts
  • app/src/lib/i18n/chunks/fr-4.ts
  • app/src/lib/i18n/chunks/fr-1.ts
  • app/src/lib/i18n/chunks/zh-CN-1.ts
  • app/src/lib/i18n/chunks/ar-4.ts
  • app/src/lib/i18n/chunks/hi-4.ts
  • app/src/pages/Settings.tsx
  • src/openhuman/memory/store/factories.rs
  • app/src/lib/i18n/chunks/id-1.ts
  • app/src/lib/i18n/chunks/ru-4.ts
  • app/src/components/settings/panels/tests/MigrationPanel.test.tsx
  • src/openhuman/migration/ops.rs
  • app/src/lib/i18n/chunks/hi-1.ts
  • app/src/lib/i18n/en.ts
  • app/src/components/settings/panels/MigrationPanel.tsx

📝 Walkthrough

Walkthrough

Adds a MigrationPanel UI for previewing and applying OpenClaw imports, i18n and settings routing, frontend tests, and backend changes to enable writable migration memory and an integration apply test.

Changes

OpenClaw Migration Feature

Layer / File(s) Summary
Migration memory factory and backend infrastructure
src/openhuman/memory/store/factories.rs, src/openhuman/migration/core.rs, src/openhuman/migration/ops.rs
create_memory_for_migration now accepts &MemoryConfig and delegates to create_memory, enabling writable UnifiedMemory for migrations. Caller updated to pass config.memory. Adds integration test verifying non-dry-run apply imports markdown entries.
MigrationPanel React component implementation
app/src/components/settings/panels/MigrationPanel.tsx
New default-exported MigrationPanel component: vendor dropdown (OpenClaw enabled, Hermes disabled/coming soon), source workspace input, Preview (dry-run) and Apply (confirm-gated) flows, loading/error state handling, and migration report rendering.
Component tests
app/src/components/settings/panels/__tests__/MigrationPanel.test.tsx
Vitest + React Testing Library suite covering vendor defaults, Hermes callout, Preview RPC (dry_run=true) and rendering, source path trimming, Apply gating/confirmation (dry_run=false), cancel behavior, re-disable on edit, and RPC error rendering.
Settings routing, i18n and docs
app/src/pages/Settings.tsx, app/src/lib/i18n/*, docs/TEST-COVERAGE-MATRIX.md
Registers /settings/.../migration route rendering MigrationPanel, adds MigrationIcon and account menu item, inserts migration.* translation keys across locales including English account labels, and updates TEST-COVERAGE-MATRIX.md to mark migration covered.

Sequence Diagram

sequenceDiagram
  participant User
  participant MigrationPanel
  participant TauriRPC
  User->>MigrationPanel: Select vendor & enter source path
  User->>MigrationPanel: Click Preview
  MigrationPanel->>TauriRPC: openhumanMigrateOpenclaw(dry_run=true, source)
  TauriRPC-->>MigrationPanel: MigrationReport (preview)
  MigrationPanel->>User: Display preview report
  User->>MigrationPanel: Click Apply
  MigrationPanel->>User: window.confirm()
  alt User confirms
    MigrationPanel->>TauriRPC: openhumanMigrateOpenclaw(dry_run=false, source)
    TauriRPC-->>MigrationPanel: MigrationReport (applied)
    MigrationPanel->>User: Display applied report
  else User cancels
    MigrationPanel->>User: Keep preview report
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • graycyrus

Poem

🐰 I sniff the codepath, soft and keen,
A preview first—no change unseen,
Then confirm the hop to import true,
From OpenClaw fields into your view,
A rabbit's cheer for migrations new!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a user-facing OpenClaw migration UI panel and unblocking the unified-core memory factory for Apply operations. It is concise, specific, and directly related to the primary changes across both frontend and backend.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ 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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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 and usage tips.

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. working A PR that is being worked on by the team. labels May 18, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
app/src/components/settings/panels/__tests__/MigrationPanel.test.tsx (1)

102-111: ⚡ Quick win

Add a regression test for stale preview invalidation.

Please add a case that edits sourcePath after a successful preview and asserts Apply is disabled until re-preview succeeds for the new input.

Also applies to: 113-148

🤖 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 `@app/src/components/settings/panels/__tests__/MigrationPanel.test.tsx` around
lines 102 - 111, Add a new test in MigrationPanel.test.tsx that verifies stale
preview invalidation: render <MigrationPanel />, mock openhumanMigrateOpenclaw
to resolve for the initial input and click the 'migration-preview-button' (using
the 'migration-source-input' test id) and assert the Apply control (e.g. test id
'migration-apply-button' or the Apply button text) becomes enabled; then change
the source input value to a different path, assert that Apply becomes disabled
immediately (stale preview), then mock openhumanMigrateOpenclaw to resolve for
the new trimmed path, click the preview button again and finally assert Apply is
enabled again. Reference openhumanMigrateOpenclaw, MigrationPanel,
'migration-source-input', 'migration-preview-button', and the Apply button test
id/name when implementing the test.
🤖 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/settings/panels/MigrationPanel.tsx`:
- Around line 38-39: The Apply button is enabled by any existing previewReport
even if the user has changed sourcePath afterward; update the gating logic so
Apply is only allowed when the previewReport corresponds to the current
sourcePath and no apply is in progress. Concretely, track and compare the
previewed path (e.g., add/derive a previewedSourcePath from previewReport or
store lastPreviewedSourcePath when preview completes) and change canApply (and
the checks around runApply, preview button handlers, and any uses at the apply
call sites) to require previewedSourcePath === sourcePath && !isApplying
(instead of just previewReport != null). Ensure runApply uses the validated
sourcePath that matches the previewed path.
- Around line 70-75: The confirmation dialog in MigrationPanel (the
window.confirm call that builds the message using totalPlanned and
previewReport.source_workspace/target_workspace) and the Hermes roadmap copy
later (around the other hardcoded strings noted) are hardcoded and must be
localized; replace the inline strings with calls to the translation function (t)
from your i18n hook (useTranslation/t) and create descriptive translation keys,
use pluralization/interpolation for totalPlanned (e.g.,
t('migration.confirmImport', {count: totalPlanned})) and interpolate
previewReport.source_workspace and previewReport.target_workspace into the
translated string, and update the Hermes roadmap text similarly so all
user-facing text in MigrationPanel uses t(...) with appropriate keys and
variables.

In `@docs/TEST-COVERAGE-MATRIX.md`:
- Line 473: The coverage summary totals need updating because the "Migration
from another assistant (OpenClaw)" row changed from ❌ to ✅; update the summary
row(s) that aggregate Covered and Missing counts to increment Covered by 1 and
decrement Missing by 1 (and recompute any dependent totals/percentages) so the
overall totals reflect this PR's change; look for the summary totals section
that references the matrix totals and adjust the numeric values accordingly.

---

Nitpick comments:
In `@app/src/components/settings/panels/__tests__/MigrationPanel.test.tsx`:
- Around line 102-111: Add a new test in MigrationPanel.test.tsx that verifies
stale preview invalidation: render <MigrationPanel />, mock
openhumanMigrateOpenclaw to resolve for the initial input and click the
'migration-preview-button' (using the 'migration-source-input' test id) and
assert the Apply control (e.g. test id 'migration-apply-button' or the Apply
button text) becomes enabled; then change the source input value to a different
path, assert that Apply becomes disabled immediately (stale preview), then mock
openhumanMigrateOpenclaw to resolve for the new trimmed path, click the preview
button again and finally assert Apply is enabled again. Reference
openhumanMigrateOpenclaw, MigrationPanel, 'migration-source-input',
'migration-preview-button', and the Apply button test id/name when implementing
the test.
🪄 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: 5e9d9364-d4d6-47e0-b028-9124cc8b089a

📥 Commits

Reviewing files that changed from the base of the PR and between d5cef57 and 1f04fac.

📒 Files selected for processing (8)
  • app/src/components/settings/panels/MigrationPanel.tsx
  • app/src/components/settings/panels/__tests__/MigrationPanel.test.tsx
  • app/src/lib/i18n/en.ts
  • app/src/pages/Settings.tsx
  • docs/TEST-COVERAGE-MATRIX.md
  • src/openhuman/memory/store/factories.rs
  • src/openhuman/migration/core.rs
  • src/openhuman/migration/ops.rs

Comment thread app/src/components/settings/panels/MigrationPanel.tsx Outdated
Comment thread app/src/components/settings/panels/MigrationPanel.tsx
Comment thread docs/TEST-COVERAGE-MATRIX.md
obchain added a commit to obchain/openhuman that referenced this pull request May 18, 2026
Address CodeRabbit review on PR tinyhumansai#2087:

1. `MigrationPanel.tsx` — track `{ vendor, source }` snapshot of the
   last successful preview. Apply now requires that snapshot to match
   the currently-typed input, so editing the path after a preview
   re-locks Apply until the user previews the new value. Previously
   Apply unlocked on any prior preview, letting the user mutate a
   workspace they had never seen the diff for.
2. `MigrationPanel.tsx` — localize the Hermes "coming soon" callout
   and the Apply confirm() body via `t(...)` with three new keys
   (`hermesComingSoonPrefix/Suffix/LinkText`, `confirmImport.singular`,
   `confirmImport.plural`). Tests cover the new gate behavior.
3. `docs/TEST-COVERAGE-MATRIX.md` — rebalance Covered/Missing totals
   to reflect the OpenClaw migration row moving ❌ → ✅
   (Covered 65→66, Missing 27→26).
obchain added a commit to obchain/openhuman that referenced this pull request May 18, 2026
CI `i18n:check` failed on PR tinyhumansai#2087 because the migration.* keys (added
to en.ts) had no presence in the chunks/ source-of-truth that the
coverage tool uses for drift + per-locale checks. Add the 28 new
`migration.*` keys to chunks/en-1.ts plus
`pages.settings.account.migration{Desc}` to chunks/en-4.ts, then seed
English fallbacks into all 10 non-en locale chunks so per-locale
"missing" passes. Translators can replace the English placeholders in
a follow-up.
@obchain obchain force-pushed the feat/1440-migration-panel branch from 1f04fac to 65b42cc Compare May 18, 2026 13:06
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 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/lib/i18n/chunks/ar-1.ts`:
- Around line 375-410: The Arabic locale chunk includes new migration.* keys in
English; translate each migration.* string (e.g., migration.title,
migration.description, migration.vendorLabel, migration.sourceLabel,
migration.sourcePlaceholder, migration.sourceHint, migration.previewAction,
migration.previewRunning, migration.applyAction, migration.applyRunning,
migration.applyDisclaimer, migration.reportTitlePreview,
migration.reportTitleApplied, migration.report.source, migration.report.target,
migration.report.fromSqlite, migration.report.fromMarkdown,
migration.report.imported, migration.report.skippedUnchanged,
migration.report.renamedConflicts, migration.report.warnings,
migration.report.previewHint, migration.report.appliedHint,
migration.hermesComingSoonPrefix, migration.hermesComingSoonSuffix,
migration.hermesLinkText, migration.confirmImport.singular,
migration.confirmImport.plural) into Arabic so users of the ar chunk see
localized text; preserve formatting/escapes (e.g., "\\n\\n") and placeholders
({count}, {source}, {target}) exactly when replacing the English strings.

In `@app/src/lib/i18n/chunks/bn-1.ts`:
- Around line 383-418: The Bengali locale chunk still contains English strings
for all migration.* keys; update each migration.* entry (e.g.,
'migration.title', 'migration.description', 'migration.vendorLabel',
'migration.sourceLabel', 'migration.sourcePlaceholder', 'migration.sourceHint',
'migration.previewAction', 'migration.previewRunning', 'migration.applyAction',
'migration.applyRunning', 'migration.applyDisclaimer',
'migration.reportTitlePreview', 'migration.reportTitleApplied',
'migration.report.source', 'migration.report.target',
'migration.report.fromSqlite', 'migration.report.fromMarkdown',
'migration.report.imported', 'migration.report.skippedUnchanged',
'migration.report.renamedConflicts', 'migration.report.warnings',
'migration.report.previewHint', 'migration.report.appliedHint',
'migration.hermesComingSoonPrefix', 'migration.hermesComingSoonSuffix',
'migration.hermesLinkText', 'migration.confirmImport.singular',
'migration.confirmImport.plural') with proper Bengali translations so the UI
shows localized text; preserve placeholders like {count}, {source}, {target} and
the escaped newline sequences (\\n\\n) and ensure punctuation/grammar match
Bengali usage.

In `@app/src/lib/i18n/chunks/hi-4.ts`:
- Around line 366-368: The Hindi localization is missing translations for the
keys 'pages.settings.account.migration' and
'pages.settings.account.migrationDesc'; update the hi-4.ts chunk by replacing
the English strings for those symbols with proper Hindi translations that convey
"Import from another assistant" and "Migrate memory and notes from OpenClaw (or,
soon, Hermes) into this workspace." respectively, preserving the existing key
names and string formatting (quotes, trailing comma).

In `@app/src/lib/i18n/chunks/id-1.ts`:
- Around line 383-418: The migration.* entries are still in English so the
Indonesian locale lacks translations; update each key (e.g., migration.title,
migration.description, migration.vendorLabel, migration.sourceLabel,
migration.sourcePlaceholder, migration.sourceHint, migration.previewAction,
migration.previewRunning, migration.applyAction, migration.applyRunning,
migration.applyDisclaimer, migration.reportTitlePreview,
migration.reportTitleApplied, migration.report.source, migration.report.target,
migration.report.fromSqlite, migration.report.fromMarkdown,
migration.report.imported, migration.report.skippedUnchanged,
migration.report.renamedConflicts, migration.report.warnings,
migration.report.previewHint, migration.report.appliedHint,
migration.hermesComingSoonPrefix, migration.hermesComingSoonSuffix,
migration.hermesLinkText, migration.confirmImport.singular,
migration.confirmImport.plural) with proper Indonesian translations consistent
with existing style and tone, ensuring escaped newlines (\\n) remain where
present and keeping placeholders like {count}, {source}, {target} intact.

In `@app/src/lib/i18n/chunks/it-1.ts`:
- Around line 388-423: Replace the English strings for all migration.* keys in
this file (e.g., 'migration.title', 'migration.description',
'migration.vendorLabel', 'migration.sourceLabel', 'migration.sourcePlaceholder',
'migration.sourceHint', 'migration.previewAction', 'migration.previewRunning',
'migration.applyAction', 'migration.applyRunning', 'migration.applyDisclaimer',
'migration.reportTitlePreview', 'migration.reportTitleApplied',
'migration.report.source', 'migration.report.target',
'migration.report.fromSqlite', 'migration.report.fromMarkdown',
'migration.report.imported', 'migration.report.skippedUnchanged',
'migration.report.renamedConflicts', 'migration.report.warnings',
'migration.report.previewHint', 'migration.report.appliedHint',
'migration.hermesComingSoonPrefix', 'migration.hermesComingSoonSuffix',
'migration.hermesLinkText', 'migration.confirmImport.singular',
'migration.confirmImport.plural') with accurate Italian translations so the UI
shows Italian text consistently; keep placeholders like {count}, {source},
{target} and escaped newlines (\\n) unchanged and preserve punctuation and
intent of each message.

In `@app/src/lib/i18n/chunks/it-4.ts`:
- Around line 368-370: Translate the two English keys into Italian in
app/src/lib/i18n/chunks/it-4.ts: replace 'pages.settings.account.migration'
value with an Italian label (e.g., "Importa da un altro assistente") and update
'pages.settings.account.migrationDesc' to an Italian sentence (e.g., "Migra
memorie e note da OpenClaw (o, presto, Hermes) in questo spazio di lavoro.") so
both keys (pages.settings.account.migration and
pages.settings.account.migrationDesc) are localized consistently.

In `@app/src/lib/i18n/chunks/pt-4.ts`:
- Around line 368-370: The two new keys 'pages.settings.account.migration' and
'pages.settings.account.migrationDesc' in the pt-4 translation chunk are still
in English; replace their English strings with Portuguese translations (e.g.,
'Importar de outro assistente' for 'pages.settings.account.migration' and a
natural Portuguese sentence for 'pages.settings.account.migrationDesc' such as
'Migrar memórias e notas do OpenClaw (ou, em breve, Hermes) para este espaço de
trabalho.') so Portuguese users see localized account menu content.

In `@app/src/lib/i18n/chunks/zh-CN-1.ts`:
- Around line 365-400: The migration.* entries in zh-CN-1.ts are still in
English (e.g. 'migration.title', 'migration.vendorLabel',
'migration.previewAction', 'migration.confirmImport.singular' etc.), so replace
the English values with proper Simplified Chinese translations for all 36
migration.* keys in that file; preserve formatting and escape sequences (e.g.
"\\n\\n") and keep the same keys and punctuation, only changing the string
values to Chinese (for example 'migration.title' → '从其他助手导入',
'migration.vendorLabel' → '源供应商', 'migration.previewAction' → '预览').

In `@app/src/lib/i18n/chunks/zh-CN-4.ts`:
- Around line 362-364: The two i18n keys pages.settings.account.migration and
pages.settings.account.migrationDesc contain English text in the Simplified
Chinese chunk; replace their values with the provided Chinese translations so
Chinese users see localized text — set pages.settings.account.migration to
"从其他助手导入" and pages.settings.account.migrationDesc to "将来自 OpenClaw(或即将支持的
Hermes)的记忆和笔记迁移到此工作区。".
🪄 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: 196ca957-9e4a-4e6d-b286-370b6f80e90e

📥 Commits

Reviewing files that changed from the base of the PR and between 1f04fac and 65b42cc.

📒 Files selected for processing (30)
  • app/src/components/settings/panels/MigrationPanel.tsx
  • app/src/components/settings/panels/__tests__/MigrationPanel.test.tsx
  • app/src/lib/i18n/chunks/ar-1.ts
  • app/src/lib/i18n/chunks/ar-4.ts
  • app/src/lib/i18n/chunks/bn-1.ts
  • app/src/lib/i18n/chunks/bn-4.ts
  • app/src/lib/i18n/chunks/en-1.ts
  • app/src/lib/i18n/chunks/en-4.ts
  • app/src/lib/i18n/chunks/es-1.ts
  • app/src/lib/i18n/chunks/es-4.ts
  • app/src/lib/i18n/chunks/fr-1.ts
  • app/src/lib/i18n/chunks/fr-4.ts
  • app/src/lib/i18n/chunks/hi-1.ts
  • app/src/lib/i18n/chunks/hi-4.ts
  • app/src/lib/i18n/chunks/id-1.ts
  • app/src/lib/i18n/chunks/id-4.ts
  • app/src/lib/i18n/chunks/it-1.ts
  • app/src/lib/i18n/chunks/it-4.ts
  • app/src/lib/i18n/chunks/pt-1.ts
  • app/src/lib/i18n/chunks/pt-4.ts
  • app/src/lib/i18n/chunks/ru-1.ts
  • app/src/lib/i18n/chunks/ru-4.ts
  • app/src/lib/i18n/chunks/zh-CN-1.ts
  • app/src/lib/i18n/chunks/zh-CN-4.ts
  • app/src/lib/i18n/en.ts
  • app/src/pages/Settings.tsx
  • docs/TEST-COVERAGE-MATRIX.md
  • src/openhuman/memory/store/factories.rs
  • src/openhuman/migration/core.rs
  • src/openhuman/migration/ops.rs
✅ Files skipped from review due to trivial changes (13)
  • app/src/lib/i18n/chunks/es-1.ts
  • app/src/lib/i18n/chunks/hi-1.ts
  • app/src/lib/i18n/chunks/id-4.ts
  • app/src/lib/i18n/chunks/en-4.ts
  • app/src/lib/i18n/chunks/fr-4.ts
  • app/src/lib/i18n/chunks/es-4.ts
  • app/src/lib/i18n/chunks/ru-4.ts
  • app/src/lib/i18n/chunks/ru-1.ts
  • app/src/lib/i18n/chunks/fr-1.ts
  • app/src/lib/i18n/chunks/ar-4.ts
  • app/src/lib/i18n/chunks/bn-4.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/chunks/pt-1.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/openhuman/migration/core.rs
  • src/openhuman/memory/store/factories.rs
  • app/src/components/settings/panels/tests/MigrationPanel.test.tsx
  • app/src/pages/Settings.tsx
  • src/openhuman/migration/ops.rs
  • app/src/components/settings/panels/MigrationPanel.tsx

Comment thread app/src/lib/i18n/chunks/ar-1.ts Outdated
Comment thread app/src/lib/i18n/chunks/bn-1.ts Outdated
Comment thread app/src/lib/i18n/chunks/hi-4.ts Outdated
Comment thread app/src/lib/i18n/chunks/id-1.ts Outdated
Comment thread app/src/lib/i18n/chunks/it-1.ts Outdated
Comment thread app/src/lib/i18n/chunks/it-4.ts Outdated
Comment thread app/src/lib/i18n/chunks/pt-4.ts Outdated
Comment thread app/src/lib/i18n/chunks/zh-CN-1.ts Outdated
Comment thread app/src/lib/i18n/chunks/zh-CN-4.ts Outdated
obchain added a commit to obchain/openhuman that referenced this pull request May 18, 2026
CodeRabbit follow-up on PR tinyhumansai#2087: replace English fallback placeholders
in all 10 non-en locale chunks (zh-CN, hi, es, ar, fr, bn, pt, ru, id,
it) with real translations for the 28 `migration.*` keys plus the 2
`pages.settings.account.migration{Desc}` labels. Placeholder tokens
(`{count}`, `{source}`, `{target}`) and the `tinyhumansai#1440` link text are kept
verbatim. Newlines in the confirm-import bodies preserved via `\n`.
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 18, 2026
obchain added a commit to obchain/openhuman that referenced this pull request May 18, 2026
Address CodeRabbit review on PR tinyhumansai#2087:

1. `MigrationPanel.tsx` — track `{ vendor, source }` snapshot of the
   last successful preview. Apply now requires that snapshot to match
   the currently-typed input, so editing the path after a preview
   re-locks Apply until the user previews the new value. Previously
   Apply unlocked on any prior preview, letting the user mutate a
   workspace they had never seen the diff for.
2. `MigrationPanel.tsx` — localize the Hermes "coming soon" callout
   and the Apply confirm() body via `t(...)` with three new keys
   (`hermesComingSoonPrefix/Suffix/LinkText`, `confirmImport.singular`,
   `confirmImport.plural`). Tests cover the new gate behavior.
3. `docs/TEST-COVERAGE-MATRIX.md` — rebalance Covered/Missing totals
   to reflect the OpenClaw migration row moving ❌ → ✅
   (Covered 65→66, Missing 27→26).
obchain added a commit to obchain/openhuman that referenced this pull request May 18, 2026
CI `i18n:check` failed on PR tinyhumansai#2087 because the migration.* keys (added
to en.ts) had no presence in the chunks/ source-of-truth that the
coverage tool uses for drift + per-locale checks. Add the 28 new
`migration.*` keys to chunks/en-1.ts plus
`pages.settings.account.migration{Desc}` to chunks/en-4.ts, then seed
English fallbacks into all 10 non-en locale chunks so per-locale
"missing" passes. Translators can replace the English placeholders in
a follow-up.
obchain added a commit to obchain/openhuman that referenced this pull request May 18, 2026
CodeRabbit follow-up on PR tinyhumansai#2087: replace English fallback placeholders
in all 10 non-en locale chunks (zh-CN, hi, es, ar, fr, bn, pt, ru, id,
it) with real translations for the 28 `migration.*` keys plus the 2
`pages.settings.account.migration{Desc}` labels. Placeholder tokens
(`{count}`, `{source}`, `{target}`) and the `tinyhumansai#1440` link text are kept
verbatim. Newlines in the confirm-import bodies preserved via `\n`.
@obchain obchain force-pushed the feat/1440-migration-panel branch from 20ef55c to ebb6bda Compare May 18, 2026 14:20
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 18, 2026
obchain added 6 commits May 19, 2026 11:25
`create_memory_for_migration` had been left as an unconditional
`anyhow::bail!("memory migration is disabled for the unified namespace
memory core")` since the unified namespace memory landing. Every code
path that goes through it (today: the Apply phase of
`openhuman.migrate_openclaw` via `migrate_openclaw_memory`) failed
closed — Preview worked, Apply was dead.

The fix is small: under the unified core there is no separate
"migration backend", just the same workspace-scoped store the rest of
the app reads from. Delegate to `create_memory(config, workspace_dir)`
so migration writes into a real `Box<dyn Memory>`.

Signature changes from `(&str, &Path)` to `(&MemoryConfig, &Path)`
since the workspace-aware factory needs the full memory config. The
sole caller (`migration::core::target_memory_backend`) already has
`&Config` in scope, so the call site is a one-line change.

Tests: replaced the always-errors regression with a positive
`create_memory_for_migration_returns_writable_memory_on_unified_core`,
and added `migrate_openclaw_apply_imports_markdown_entries_into_target_workspace`
to exercise the full Apply path end-to-end against a temp OpenClaw
workspace.

Refs tinyhumansai#1440
Adds a Settings → Account → "Import from another assistant" panel
that wraps the existing `openhuman.migrate_openclaw` RPC with a
preview-then-apply flow:

- Vendor dropdown (OpenClaw active; Hermes disabled with a "coming
  soon" callout linking back to the tracking issue).
- Preview button hits the RPC with `dry_run=true` and renders the
  returned `MigrationReport` (source/target paths, per-source counts,
  warnings).
- Apply is locked until a successful Preview lands and fires
  `window.confirm` with the planned counts before calling the RPC
  with `dry_run=false`.
- Inline error surface survives the form so the user can edit + retry
  without losing context.

The Rust core RPC + TS wrapper already existed; this PR ships the
discoverability surface called out as the tinyhumansai#1 gap in the issue. The
Apply path is unblocked by the sibling backend fix in the previous
commit.

Closes tinyhumansai#1440
Address CodeRabbit review on PR tinyhumansai#2087:

1. `MigrationPanel.tsx` — track `{ vendor, source }` snapshot of the
   last successful preview. Apply now requires that snapshot to match
   the currently-typed input, so editing the path after a preview
   re-locks Apply until the user previews the new value. Previously
   Apply unlocked on any prior preview, letting the user mutate a
   workspace they had never seen the diff for.
2. `MigrationPanel.tsx` — localize the Hermes "coming soon" callout
   and the Apply confirm() body via `t(...)` with three new keys
   (`hermesComingSoonPrefix/Suffix/LinkText`, `confirmImport.singular`,
   `confirmImport.plural`). Tests cover the new gate behavior.
3. `docs/TEST-COVERAGE-MATRIX.md` — rebalance Covered/Missing totals
   to reflect the OpenClaw migration row moving ❌ → ✅
   (Covered 65→66, Missing 27→26).
CI `i18n:check` failed on PR tinyhumansai#2087 because the migration.* keys (added
to en.ts) had no presence in the chunks/ source-of-truth that the
coverage tool uses for drift + per-locale checks. Add the 28 new
`migration.*` keys to chunks/en-1.ts plus
`pages.settings.account.migration{Desc}` to chunks/en-4.ts, then seed
English fallbacks into all 10 non-en locale chunks so per-locale
"missing" passes. Translators can replace the English placeholders in
a follow-up.
CodeRabbit follow-up on PR tinyhumansai#2087: replace English fallback placeholders
in all 10 non-en locale chunks (zh-CN, hi, es, ar, fr, bn, pt, ru, id,
it) with real translations for the 28 `migration.*` keys plus the 2
`pages.settings.account.migration{Desc}` labels. Placeholder tokens
(`{count}`, `{source}`, `{target}`) and the `tinyhumansai#1440` link text are kept
verbatim. Newlines in the confirm-import bodies preserved via `\n`.
@CodeGhost21
Copy link
Copy Markdown
Contributor

@obchain Could you add Closes #1440 to the PR description so the issue auto-closes on merge? Happy to spin out a separate Hermes tracker after this lands.

@senamakel senamakel merged commit 6a83409 into tinyhumansai:main May 19, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Net-new user-facing capability or product behavior. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants