feat: add basic-memory watch CLI command by phernandez · Pull Request #559 · basicmachines-co/basic-memory · GitHub
Skip to content

feat: add basic-memory watch CLI command - #559

Merged
phernandez merged 2 commits into
mainfrom
feat/watch-command
Feb 13, 2026
Merged

phernandez merged 2 commits into
mainfrom
feat/watch-command

Conversation

@phernandez

Copy link
Copy Markdown
Member

Summary

  • Adds basic-memory watch command that runs the file watcher as a standalone long-running process without starting the MCP server
  • Threads a quiet parameter through SyncCoordinator → initialize_file_sync → WatchService so the watch command shows Rich console output while MCP keeps quiet
  • Supports --project flag to constrain watching to a single project
  • Motivated by openclaw-basic-memory needing file sync without MCP

Test plan

  • 5 new tests in tests/cli/test_watch.py (init, coordinator args, project env var, invalid project exit, shutdown cleanup)
  • 3 new tests in tests/sync/test_coordinator.py (quiet defaults, quiet override, quiet passthrough)
  • All 16 tests pass, lint and typecheck clean
  • Manual: basic-memory watch starts and shows file changes, stops on Ctrl+C
  • Manual: basic-memory watch --project my-project constrains to single project

🤖 Generated with Claude Code

Standalone long-running file watcher that reuses SyncCoordinator without
starting the MCP server. Useful for running Basic Memory sync alongside
external tools like openclaw-basic-memory.

- Add `quiet` field to SyncCoordinator, threaded through to WatchService
- Add `quiet` param to `initialize_file_sync()` (defaults True for MCP)
- New `watch.py` command: init → sync coordinator → block until signal → clean shutdown
- Supports `--project` flag to constrain to a single project

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
@github-actions

github-actions Bot commented Feb 12, 2026 •

Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 44570a0736

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/basic_memory/cli/commands/watch.py Outdated

loop = asyncio.get_running_loop()
for sig in (signal.SIGINT, signal.SIGTERM):
loop.add_signal_handler(sig, _signal_handler)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Handle Windows where add_signal_handler is unsupported

run_watch registers SIGINT/SIGTERM with loop.add_signal_handler(...) unconditionally, but that API is not implemented on Windows event loops, so basic-memory watch fails with NotImplementedError before the watcher starts. This impacts all win32 users of the new command even though the command explicitly tries to support Windows via selector policy setup.

Useful? React with 👍 / 👎.

Comment thread src/basic_memory/cli/commands/watch.py Outdated
project_name, _ = config_manager.get_project(project)
if not project_name:
typer.echo(f"No project found named: {project}", err=True)
raise typer.Exit(1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Ensure DB cleanup on invalid --project exit path

When --project is invalid, run_watch raises typer.Exit(1) after initialize_app(config) has already run, but before entering the try/finally block that calls db.shutdown_db(). That leaves initialization-opened DB resources unclosed on this error path and can cause noisy or hanging event-loop teardown for users who mistype the project name.

Useful? React with 👍 / 👎.

- Resolve merge conflicts in app.py (add both "reindex" and "watch" to skip_init_commands)
  and rclone_commands.py (use --header for Tigris consistency)
- Address Codex P1: handle Windows where add_signal_handler is unsupported by falling
  back to signal.signal()
- Address Codex P2: ensure DB cleanup on all exit paths (including invalid --project)
  by wrapping post-init code in try/finally
- Add test for Windows signal handler fallback
- Apply ruff formatting to files from main

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
@github-actions

github-actions Bot commented Feb 12, 2026 •

Copy link
Copy Markdown
Contributor

@phernandez
phernandez merged commit 8df88e4 into main Feb 13, 2026
37 of 38 checks passed
@phernandez
phernandez deleted the feat/watch-command branch February 13, 2026 02:10
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