Skip to content

fix(import): support cross-user OpenClaw sources + post-import path check#10

Merged
crisandrews merged 1 commit intocrisandrews:mainfrom
JD2005L:fix/import-path-discovery
Apr 17, 2026
Merged

fix(import): support cross-user OpenClaw sources + post-import path check#10
crisandrews merged 1 commit intocrisandrews:mainfrom
JD2005L:fix/import-path-discovery

Conversation

@JD2005L
Copy link
Copy Markdown
Contributor

@JD2005L JD2005L commented Apr 15, 2026

What

Addresses item 11 of #4: /agent:import only looks for source workspaces under ~/.openclaw, which fails when the user ran OpenClaw as one account (typically root) and now runs ClawCode as a non-root service user (typically claude inside 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:

ls -d ~/.openclaw/workspace* 2>/dev/null

Replaced with a loop over every readable root we know about:

for root in \
  "${CLAWCODE_OPENCLAW_ROOT:-}" \
  "$HOME/.openclaw" \
  "/root/.openclaw"; do
  [[ -z "$root" ]] && continue
  [[ -r "$root" ]] || continue
  ls -d "$root"/workspace* 2>/dev/null
done | sort -u
  • CLAWCODE_OPENCLAW_ROOT lets the user point at a mounted volume / non-standard location explicitly.
  • $HOME/.openclaw is the existing default.
  • /root/.openclaw is 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.json

For every hit, print a fix-ready sed command the user can run. Example output:

⚠️ ~/.claude/installed_plugins.json references /root/.claude/plugins/...
   but this agent runs as claude ($HOME = /home/claude). Skills from those
   plugins will fail with "unknown skill". Fix with:

   sed -i "s|/root/.claude|$HOME/.claude|g" ~/.claude/installed_plugins.json

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

  • Item 11 also called out that installed_plugins.json can be invalid after a user switch. This PR surfaces it with a fix command but doesn't auto-repair. Auto-repairing Claude Code's own config from a ClawCode skill felt out of scope — happy to follow up with a separate PR if you'd prefer we take that step too.

Test plan

  • Fresh import on a system with only $HOME/.openclaw/workspace* — discovers workspaces as before, no behavior change
  • Import on a system where OpenClaw lives only in /root/.openclaw/ but the runtime user has read access — discovers workspaces that used to be invisible
  • CLAWCODE_OPENCLAW_ROOT=/mnt/backup/openclaw — loop picks up that root first
  • /root/.openclaw exists but is not readable — loop quietly skips it (no permission denied spam)
  • Step G flags a seeded "/root/.claude/plugins/foo" entry in installed_plugins.json with the correct sed suggestion
  • Step G prints the all-clear line when no stale paths exist

🤖 Generated with Claude Code

…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 crisandrews merged commit 98b62d1 into crisandrews:main Apr 17, 2026
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.
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.

2 participants