feat(memos-local-openclaw): add hub sharing, dual-instance isolation, and viewer/docs improvements#1320
Closed
tangbotony wants to merge 92 commits intoMemTensor:mainfrom
Closed
feat(memos-local-openclaw): add hub sharing, dual-instance isolation, and viewer/docs improvements#1320tangbotony wants to merge 92 commits intoMemTensor:mainfrom
tangbotony wants to merge 92 commits intoMemTensor:mainfrom
Conversation
added 30 commits
March 8, 2026 12:01
# Conflicts: # apps/memos-local-openclaw/tests/integration.test.ts
…licitly - createMemorySearchTool now accepts optional store and ctx parameters instead of accessing private members via (engine as any) - Add missing worker.flush() call in root index.ts stop handler - Fix shutdown-lifecycle test mocks for new module dependencies Made-with: Cursor
Prevents memory exhaustion from oversized request bodies. Returns 413 status code when the limit is exceeded. Made-with: Cursor
Centralized auth + rate limit check for all authenticated endpoints. - 60 req/min default, 30 req/min for search endpoints - Returns 429 with retryAfterMs when exceeded - Refactored handle() to authenticate once at the top Made-with: Cursor
Add getHubGroupById, deleteHubGroup, and listHubGroupMembers to support the existing Hub server group management API endpoints. Made-with: Cursor
- Viewer server: add proxy endpoints for group CRUD, member management, and user listing (all forwarded to Hub API) - Hub server: add GET /admin/users endpoint for listing active users - Viewer UI: wire up "Manage Groups" button with group/member panel (already had the JS functions, now connected via server routes) Made-with: Cursor
- Add local_shared_tasks table to track which tasks have been shared - task_share/task_unshare now mark/unmark tasks in local tracking table - After each agent_end, automatically sync new chunks for shared tasks to the Hub without requiring manual re-share Made-with: Cursor
- Add upsertHubEmbedding/getHubEmbedding/getAllHubEmbeddings to SqliteStore - Hub server accepts optional embedder; embeds shared chunks async on receive - Hub search now merges FTS and vector results via RRF (k=60) when embedder is available, falling back to FTS-only otherwise - Pass embedder instance to HubServer from root index.ts Made-with: Cursor
- config.ts: inject provider:"openclaw" when hostEmbedding/hostCompletion capabilities are enabled but no explicit provider is configured, so the fallback priority chain (user config → openclaw → local/rule) works correctly - openclaw-api.ts: rename class to OpenClawAPIClient and add explicit `implements OpenClawAPI` to avoid confusion with the interface in types.ts - ingest/providers/index.ts: rewrite all 5 openclaw summarizer methods with high-quality prompts aligned with openai.ts (language preservation, structured JSON output for filter/dedup), reuse parseFilterResult/parseDedupResult - viewer/server.ts: pass openclawAPI to Summarizer in migration code path - openai.ts: export parseFilterResult for reuse Made-with: Cursor
- memory_search/skill_search: read agentId from context (3rd arg) instead of params, matching the OpenClaw Plugin SDK calling convention - memory_timeline: add owner filtering so agents cannot access other agents' private chunks via timeline traversal - memory_get: add owner filtering so agents cannot read other agents' private chunks directly - memory_search: include ref and summary in details.hits for downstream tools (timeline/get) that need the full ChunkRef - service.stop(): reorder to flush worker before telemetry shutdown, ensuring data persistence completes before auxiliary services stop Made-with: Cursor
…credentials externalization - Fix owner filter in serveMemories/serveStats: shared memories (owner='public') were excluded because session_key LIKE 'agent:main:%' never matched. Changed to simply include all public memories alongside agent-owned ones. - Add toast notifications for retry-connection in all states (loading/fail/error) so sidebar clicks also get user feedback. - Remove hardcoded ARMS telemetry credentials from source code. Credentials are now loaded at runtime from telemetry.credentials.json (generated by CI from GitHub Secrets) or MEMOS_ARMS_* env vars. If neither is available, telemetry is silently disabled. Made-with: Cursor
…re atomicity Disable "team" scope option in the sharing modal when hub connection is not active, preventing users from triggering a doomed request. On the backend, reorder scope handlers (memory, task, skill) so the hub remote call executes before any local state mutation — if the hub request fails, local data stays unchanged, avoiding inconsistency. Made-with: Cursor
The migrate/scan endpoint only counted sessions under agents/main/, while the actual import traverses agents/*/sessions/ for all configured agents. This caused a mismatch between the previewed message count and the import progress total. Made-with: Cursor
Show the number of distinct agents instead of time span in the overview stat cards. The data is already available from the owners array returned by the stats API. Made-with: Cursor
…ltering for Hub results, and skill embedding - Add SearchHit.origin field (local/local-shared/hub-memory/hub-remote) to track result source - RecallEngine sets origin based on chunk owner and hubmem: prefix - memory_search: Hub remote results now pass through summarizer.filterRelevant LLM filtering - Hub skill publish generates embedding async via embedSkillAsync for vector search - Hub /api/v1/hub/skills search endpoint adds vector search + RRF fusion - Add getVisibleHubSkillEmbeddings() to sqlite storage layer - rawCandidates and auto-recall logs include origin field - Viewer log recall-items display origin badges (本机共享/团队缓存/团队) - AI output annotates each result with origin label - Handle removed user re-join on Hub (reset to pending) - Detect 401 in getHubStatus for deleted user cleanup Made-with: Cursor
…serve client hub connection on disable - Check both hostname and port when detecting self-join to avoid blocking different-port Hub on same machine - Preserve client hub connection when sharing is disabled (instead of clearing it) for seamless re-enable - Trigger auto-join when re-enabling sharing as client, not only on initial role switch Made-with: Cursor
… sharing UX - Fix embedding model consistency: Client mode no longer stores hub_memories locally or searches them with local embedder. Remote data stays remote, searched via Hub API only. Hub mode retains local hub_memories search since embeddings are generated by the same model. - Add user notifications for approve/reject: Hub server now creates notifications for users when their membership is approved or rejected. - Fix sharing UI onboarding: Settings page auto-switches to Hub tab when sharing is unconfigured, showing the setup guide card. - Fix scope selector visibility: Memory/task/skill scope selectors now appear when hub is connected, auto-refresh data on first connection. - Fix hub group management: Add hub_groups/hub_group_members tables and CRUD methods, enforce group-based search permissions. - Fix chunker type system: Support code_block, error_stack, list, command chunk kinds beyond paragraph. - Fix test stability: Mock LLM in task-processor test, adapt viewer-sharing tests to pending-approval flow, fix viewer-ui function call. Made-with: Cursor
Made-with: Cursor
…ove notification and admin panel refresh - Fix 401 misdiagnosis: token expiry was incorrectly treated as "removed" status. Now queries registration-status for real state and auto-renews token if active. - Add membership_approved/rejected notification types with i18n support - Reconnect SSE and load notifications immediately on pending→active transition - Shorten client pending poll interval from 10s to 5s - Add user.status to admin fingerprint to catch status changes - Force admin data refresh on view switch and after approve/reject/remove/role-change - Add notifPollImmediate for instant notification check on new SSE connections Made-with: Cursor
Made-with: Cursor
…uto-upgrade, and sharing UX fixes - Auto-recall: add hubFallback() to search remote Hub when local yields no/insufficient results (3-layer fallback) - memory_search: auto-upgrade scope from "local" to "all" when sharing is enabled - config: parse client nickname field for join requests - hub/server: sync userManager.approveUser on registration-status token renewal - storage: tasks query includes shared public tasks for original owner visibility - viewer: role switch clears stale panels, rejected/removed show retry button, admin tab visibility control, adminToggleRole refreshes all panels, memory scope persists in localStorage Made-with: Cursor
…ment, and admin notifications - Hub port auto-derivation (gatewayPort + 11) to avoid port conflicts in multi-instance setups - Hub port retry on EADDRINUSE (up to 3 retries) - Role change notifications (role_promoted / role_demoted) sent to affected users - Withdraw-pending API for canceling pending join requests when switching roles - Complete client connection cleanup (clearClientHubConnection) on role switch - Frontend toast guards: pending→connected/rejected only fire for client role - Resource notification display: localized titles with resource name as detail - Self-removal prevention in admin user management panel - Faster restart overlay (waitDown max 8 attempts instead of 60) - Config path resolution via OPENCLAW_CONFIG_PATH / OPENCLAW_STATE_DIR Made-with: Cursor
…s all docs and landing pages - README: expand Team Sharing section with capabilities table, multi-instance deployment, Viewer panel details - HUB-SHARING-GUIDE: add admin features, notifications table, multi-instance deployment, port auto-derivation - www/index.html: add Team Sharing section with Hub-Client architecture demo, admin controls, nav link, update tool count to 17 - docs/index.html: add Team Sharing sidebar group, feature card, full setup/admin/multi-instance/notification docs - openclaw.plugin.json: update description to include team sharing and collaboration tools Made-with: Cursor
…platform tabs & one-liner install - www/index.html: add macOS/Linux + Windows tab switcher for hero terminal and Quick Start install section; update install description to match openmem.net - README.md: simplify install to one-liner curl/powershell commands matching openmem.net; add Windows PowerShell install; update homepage links Made-with: Cursor
…to Team Sharing section Replace text-only code blocks with a full SVG architecture diagram showing: - Hub server with team members (online/offline/pending states) - Three Client instances (Alice connected, Bob pending, Charlie offline) - Data flow arrows (task_share, skill_pull) between instances - Shared data badges (tasks, memories, skills counts) - Per-client views (local private vs team shared data) - Port auto-derivation info box - OpenClaw mascot icons on each instance Made-with: Cursor
…ction - Add animated SVG showing Hub + 3 Client instances with data flow particles - Each instance has OpenClaw mascot, role label, memory counts, and operations - Animated connection lines and flowing data particles between instances - "...N" indicator showing unlimited scalability - Update Hero tagline to emphasize multi-instance collaboration Made-with: Cursor
…inal & add architecture SVG to docs pages - Move multi-OpenClaw collaboration SVG from below install terminal to above it in Hero section - Add Hub-Client architecture diagram to docs/index.html and www/docs/index.html team sharing section - Use distinct gradient ID namespaces (hg*/ts*/dg*) to avoid SVG ID conflicts across pages Made-with: Cursor
…t hub_memories recall - Add team_shared_chunks table + upsert/get/delete; clear in deleteAll - Client: after Hub memories/share, persist metadata only; Hub role keeps upsertHubMemory - Viewer: merge team_shared_chunks into memory list sharing map; getHubMemoryForChunk reads both - Unshare paths delete team_shared_chunks; shareMemoryToHub/unshareMemoryFromHub aligned in index.ts - capture: strip MiniMax <final> tags from captured text - hub: sync bootstrapAdminToken on rename (self + admin) - viewer html: admin preview/collapsed message fade mask 88% - chore: version 1.0.4-beta.19 Made-with: Cursor
…mory on Hub - Hub: resource_removed notification includes JSON message with memoryId + sourceChunkId - Viewer: POST /api/sharing/sync-hub-removal clears team_shared_chunks + local hub_memories row - html: sync from notifications before non-silent loadMemories Made-with: Cursor
…s view Made-with: Cursor
…dge), never hub_memories/recall Made-with: Cursor
When a memory is re-shared to team after an admin removal, old resource_removed notifications would incorrectly clear the new team_shared_chunks badge on every page refresh. Now handleSyncHubRemoval compares the notification's memoryId against the current hub_memory_id and skips deletion when they differ (stale notification). Bump to 1.0.4-beta.21. Made-with: Cursor
macos-13 runner is deprecated. Use macos-15 (ARM64) and rebuild better-sqlite3 under Rosetta 2 via arch -x86_64 to produce the x64 native binary. Made-with: Cursor
The plugin runs as ESM (type: module) but telemetry.ts relied on __dirname which is undefined in ESM. Credentials file existed on disk but was never found, silently disabling all telemetry since day one. Now accepts pluginDir from index.ts (resolved via import.meta.url) and uses it as primary search path for telemetry.credentials.json. Made-with: Cursor
17 tasks
CaralHsi
added a commit
that referenced
this pull request
Mar 23, 2026
… isolation, and viewer improvements (#1321) ## Description This PR brings the `native_memos` branch into `main` with a major upgrade to the `memos-local-openclaw` plugin, focused on team sharing, dual-instance isolation, viewer usability, recall quality, and documentation completeness. It solves several practical issues that appeared during real-world local OpenClaw usage, especially when running multiple instances on the same machine: - team sharing state transitions were fragile across join/leave/role-switch flows - Hub/Viewer ports and session state could conflict in dual-instance setups - admin and member notifications were incomplete or unclear - Viewer polling and sharing UX had refresh/state consistency issues - documentation and landing pages did not fully explain the Hub/Client architecture, multi-instance deployment, and collaboration workflow Implementation approach: - added and hardened the Hub/Client sharing architecture, including Hub auth, client connector flow, server-side status management, admin operations, and notification handling - improved dual-instance isolation by refining runtime/config behavior around gateway-derived ports, sharing state cleanup, and local-vs-hub behavior boundaries - enhanced recall quality with origin tracking, Hub result filtering, and local/hybrid search improvements - improved Viewer UX and stability across sharing setup, admin workflows, polling, notifications, and collaboration-related UI - added and updated automated test coverage for hub server, viewer sharing, connector logic, storage, integration, and skill runtime flows - expanded README, Team Sharing guide, docs site, troubleshooting docs, and landing pages to better document collaboration workflows and multi-OpenClaw capabilities Relevant dependencies / requirements: - no new mandatory external product dependency for end users beyond existing model/provider configuration - local runtime still depends on `better-sqlite3` native bindings being built for the active Node.js version - optional telemetry and model-provider related configuration continue to follow the existing plugin setup Related Issue (Required): Fixes #1320 ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [x] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Refactor (does not change functionality, e.g. code style improvements, linting) - [x] Documentation update ## How Has This Been Tested? The change was validated through a combination of targeted automated coverage added in this branch and manual end-to-end verification of multi-instance local OpenClaw scenarios. Test areas covered in this branch include: - Hub server and authentication behavior - viewer sharing flows and config handling - client connector and sharing state transitions - storage and integration flows - skill runtime and sharing-related scenarios Manual reproduction / verification steps: 1. Start two local OpenClaw instances with isolated `OPENCLAW_CONFIG_PATH`, `OPENCLAW_STATE_DIR`, and workspace directories. 2. Install and enable `memos-local-openclaw` in both instances. 3. Configure one instance as Hub and another as Client. 4. Verify gateway, viewer, and Hub startup behavior, including port isolation and no cross-instance conflict. 5. Submit a join request from the Client, approve it from the Hub, and verify status updates and notifications. 6. Test admin operations including promote, demote, remove member, and self-removal prevention. 7. Test client leave / disable / role-switch behavior and verify state cleanup and reconnect behavior. 8. Verify Viewer live updates do not cause unnecessary full refreshes or scroll-position loss. 9. Open the updated docs / landing pages and confirm installation instructions, Team Sharing content, and collaboration visuals are displayed correctly. Suggested test environment: - OS: macOS - Runtime: local OpenClaw dual-instance setup - Plugin: `memos-local-openclaw` - Database: SQLite / `better-sqlite3` - [ ] Unit Test - [x] Test Script Or Test Steps (please provide) - [ ] Pipeline Automated API Test (please provide) ## Checklist - [x] I have performed a self-review of my own code | 我已自行检查了自己的代码 - [x] I have commented my code in hard-to-understand areas | 我已在难以理解的地方对代码进行了注释 - [x] I have added tests that prove my fix is effective or that my feature works | 我已添加测试以证明我的修复有效或功能正常 - [x] I have created related documentation issue/PR in [MemOS-Docs](https://github.com/MemTensor/MemOS-Docs) (if applicable) | 我已在 [MemOS-Docs](https://github.com/MemTensor/MemOS-Docs) 中创建了相关的文档 issue/PR(如果适用) - [x] I have linked the issue to this PR (if applicable) | 我已将 issue 链接到此 PR(如果适用) - [x] I have mentioned the person who will review this PR | 我已提及将审查此 PR 的人 ## Reviewer Checklist - [x] closes #1320 - [x] Made sure Checks passed - [x] Tests have been provided
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR brings the
native_memosbranch intomainwith a major upgrade to thememos-local-openclawplugin, focused on team sharing, dual-instance isolation, viewer usability, recall quality, and documentation completeness.It solves several practical issues that appeared during real-world local OpenClaw usage, especially when running multiple instances on the same machine:
Implementation approach:
Relevant dependencies / requirements:
better-sqlite3native bindings being built for the active Node.js versionRelated Issue (Required): Fixes #1319
Type of change
How Has This Been Tested?
The change was validated through a combination of targeted automated coverage added in this branch and manual end-to-end verification of multi-instance local OpenClaw scenarios.
Test areas covered in this branch include:
Manual reproduction / verification steps:
OPENCLAW_CONFIG_PATH,OPENCLAW_STATE_DIR, and workspace directories.memos-local-openclawin both instances.Suggested test environment:
OS: macOS
Runtime: local OpenClaw dual-instance setup
Plugin:
memos-local-openclawDatabase: SQLite /
better-sqlite3Unit Test
Test Script Or Test Steps (please provide)
Pipeline Automated API Test (please provide)
Checklist
Reviewer Checklist