Skip to content

Plugin's mine path doesn't work with remote palace-daemon: daemon evaluates 'dir' on its own filesystem #5

@jphein

Description

@jphein

Description

When opencode-plugin-mempalace runs against a palace-daemon hosted on a different machine (PALACE_DAEMON_URL=http://remote-host:8085), live capture cannot work because of how mempalace mine is invoked.

The plugin's mineSync(dir, 'convos', wing) calls mempalace mine <dir> --mode convos --wing <wing>. In daemon-routed mode the CLI forwards that to POST /mine with {dir, mode, wing}. The daemon then walks <dir> on its own filesystem — not the client's. So:

  • Plugin runs on katana, dir = /home/jp/Projects/foo (or /tmp/opencode-test).
  • Daemon runs on disks; it doesn't have /tmp/opencode-test (different host).
  • Daemon returns {\"detail\": \"Directory does not exist: /tmp/opencode-test\"} → HTTP 400.
  • Even when the path nominally exists on the daemon's filesystem (/home/jp happens to share, or doesn't), the daemon walks a different file tree than the user's actual session.

Impact

For users running palace-daemon on a remote server (the canonical multi-client deployment), live capture is silently broken regardless of issues #1 and #4. Even after fixing the counter (#4) and the daemon-detection (#1), mineSync returns 400 and no drawer lands.

Suggested fix (architectural)

The plugin needs a path that doesn't rely on the daemon walking the client's filesystem. Two options:

Option A: read OpenCode's session DB and POST drawers directly

OpenCode persists sessions to ~/.local/share/opencode/opencode.db (SQLite). The plugin already runs on the same machine as opencode, so it can read this DB and extract per-turn content client-side. Then POST drawers individually via the daemon's /silent-save endpoint ({session_id, wing, entry, message_count, agent_name, themes?}).

This is the exact pattern MemPalace's Claude Code stop-hook uses for verbatim conversation capture. It also matches MemPalace's OpenCodeSourceAdapter (mempalace mine --source opencode), which is what the upstream PR #1484 implements for retrospective backfill.

Option B: pipe content to the daemon via stdin

A new daemon endpoint /mine-content that takes the conversation text directly in the request body, no filesystem walk required.

Option C: document the limitation

If the maintainer wants to keep the current architecture, the README should document that live-capture only works when palace-daemon and opencode run on the same host (or with a shared filesystem).

Reproduction

# On katana, with PALACE_DAEMON_URL=http://disks:8085
export PATH=\"\$HOME/path-to-mempalace-venv/bin:\$PATH\"
mempalace mine /tmp/some-katana-only-dir --mode convos --wing wing_test
# → ERROR: daemon mine failed: HTTP Error 400: Bad Request

# Verify by hitting the daemon directly:
curl -s -X POST -H \"X-API-Key: \$PALACE_API_KEY\" -H \"Content-Type: application/json\" \\
  -d '{\"dir\": \"/tmp/some-katana-only-dir\", \"mode\": \"convos\", \"wing\": \"wing_test\"}' \\
  http://disks:8085/mine
# → {\"detail\":\"Directory does not exist: /tmp/some-katana-only-dir\"}

Workaround (today)

For daemon-routed setups, run mempalace mine --source opencode from cron / shell rc — this reads opencode.db client-side via MemPalace's OpenCodeSourceAdapter and POSTs drawers individually. Loses sub-day granularity vs. live capture, but it actually works.

Environment

  • opencode-plugin-mempalace 1.2.1
  • opencode-ai 1.15.7
  • mempalace 3.3.5 with palace-daemon @ disks.jphe.in:8085

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions