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
Description
When
opencode-plugin-mempalaceruns against a palace-daemon hosted on a different machine (PALACE_DAEMON_URL=http://remote-host:8085), live capture cannot work because of howmempalace mineis invoked.The plugin's
mineSync(dir, 'convos', wing)callsmempalace mine <dir> --mode convos --wing <wing>. In daemon-routed mode the CLI forwards that toPOST /minewith{dir, mode, wing}. The daemon then walks<dir>on its own filesystem — not the client's. So:dir = /home/jp/Projects/foo(or/tmp/opencode-test)./tmp/opencode-test(different host).{\"detail\": \"Directory does not exist: /tmp/opencode-test\"}→ HTTP 400./home/jphappens 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),
mineSyncreturns 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-saveendpoint ({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-contentthat 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
Workaround (today)
For daemon-routed setups, run
mempalace mine --source opencodefrom cron / shell rc — this reads opencode.db client-side via MemPalace'sOpenCodeSourceAdapterand POSTs drawers individually. Loses sub-day granularity vs. live capture, but it actually works.Environment
Related