fix(import): support cross-user OpenClaw sources + post-import path check#10
Merged
crisandrews merged 1 commit intocrisandrews:mainfrom Apr 17, 2026
Merged
Conversation
…heck Fixes two related failure modes from crisandrews#4 (item 11), both surfacing when the user runs OpenClaw as one account (typically `root`) and ClawCode as a different one (typically a non-root service user like `claude`). 1. Workspace discovery now scans multiple plausible source roots instead of only `~/.openclaw`: - `$CLAWCODE_OPENCLAW_ROOT` (env override for mounted volumes etc.) - `$HOME/.openclaw` (current user) - `/root/.openclaw` (readable when the new user has access) The union is deduped with `sort -u`. If nothing is found, the skill now asks for an absolute path instead of silently falling back. Each entry surfaces with its full absolute path so later copy steps can't lose it to a wrong `~` re-expansion. 2. New Step G — "Path sanity check" — runs after skills/crons/messaging are done and before the reload prompt. It greps absolute paths out of `~/.claude/settings.json`, `~/.claude/installed_plugins.json`, and `./agent-config.json` and flags any that don't live under `$HOME` (excluding system locations). This catches the concrete failure mode from crisandrews#4: `installed_plugins.json` pointing at `/root/.claude/plugins` after a user switch causes `/agent:doctor` and other skills to fail with silent "unknown skill" errors. ClawCode doesn't own `settings.json` / `installed_plugins.json`, so the step detects and prints a fix-ready `sed` command rather than auto-patching — the user decides whether to apply it. No new arguments; no behavior change for users whose source and runtime accounts match. Pure skill-doc change — no code, no generator changes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
crisandrews
added a commit
that referenced
this pull request
Apr 17, 2026
Summary of changes in this release (full detail in CHANGELOG.md): Added - Resume-on-restart wrapper for service mode (#7) - Service hardening defaults: HOME/TERM env, StartLimitBurst guard, persistent log path (#8) - /agent:update skill + heartbeat version-check with day-gate and per-version dedupe (#12) Fixed - WORKSPACE resolution so memory_search hits user's project dir, not plugin dir (#6, closes #5) - Linux systemd crash loop after Claude Code auto-updates mid-run — PTY wrap in ExecStart + DISABLE_AUTOUPDATER=1 for file-integrity (#9, #17/#18) - macOS launchd PTY wrap parity (#16) - Cross-user /agent:import discovery + post-import path sanity check (#10) Performance - reconcile-crons.sh fast-path on steady-state sessions (#11) Thanks to @JD2005L for the whole batch.
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.
What
Addresses item 11 of #4:
/agent:importonly looks for source workspaces under~/.openclaw, which fails when the user ran OpenClaw as one account (typicallyroot) and now runs ClawCode as a non-root service user (typicallyclaudeinside an LXC or similar). A related half of the same problem is that Claude Code's own config files (settings.json,installed_plugins.json) keep absolute paths written at install time — so switching the runtime user leaves those paths dangling with silent "unknown skill" failures downstream.Two changes, both in
skills/import/SKILL.md:1. Workspace discovery across plausible source roots
The old step was:
Replaced with a loop over every readable root we know about:
CLAWCODE_OPENCLAW_ROOTlets the user point at a mounted volume / non-standard location explicitly.$HOME/.openclawis the existing default./root/.openclawis picked up when the current user happens to be able to read it (common in Docker/LXC setups where the container runs as a non-root user but can still read/root).If the loop returns nothing, the skill now asks for an absolute path rather than silently falling back. The subsequent "determine source path" step uses the absolute path from the chosen workspace directly — no re-expanding
~from an agent-id, which was the root of the cross-user bug.2. New Step G — "Path sanity check"
After the import copies + skills/crons/messaging work, scan these config files for absolute paths that don't live under
$HOME(excluding system dirs):~/.claude/settings.json~/.claude/installed_plugins.json./agent-config.jsonFor every hit, print a fix-ready
sedcommand the user can run. Example output:ClawCode does not own
settings.json/installed_plugins.json, so the step explicitly does not auto-patch. Detect-and-warn only; the user decides whether to apply.Why a skill-doc change, not code
The import flow is driven by the agent reading the SKILL.md procedure, so this is the code. No TS changes, no new binary paths, no generator changes. The existing Step G (Reload) is renumbered to Step H.
Not addressed
Test plan
$HOME/.openclaw/workspace*— discovers workspaces as before, no behavior change/root/.openclaw/but the runtime user has read access — discovers workspaces that used to be invisibleCLAWCODE_OPENCLAW_ROOT=/mnt/backup/openclaw— loop picks up that root first/root/.openclawexists but is not readable — loop quietly skips it (no permission denied spam)"/root/.claude/plugins/foo"entry ininstalled_plugins.jsonwith the correctsedsuggestion🤖 Generated with Claude Code