Skip to content

[FIX] bare origin claude syncs workspace symlinks (plugins, sessions, …)#19

Merged
gradyzhuo merged 1 commit into
mainfrom
fix/origin-bare-launch-workspace-links
Jul 7, 2026
Merged

[FIX] bare origin claude syncs workspace symlinks (plugins, sessions, …)#19
gradyzhuo merged 1 commit into
mainfrom
fix/origin-bare-launch-workspace-links

Conversation

@gradyzhuo

Copy link
Copy Markdown
Member

Summary

Bare claude on origin (CLAUDE_CONFIG_DIR unset) never ran the workspace linker, so ~/.claude's shareable dirs (plugins, sessions, shell-snapshots, session-env, …) stayed per-account real dirs instead of being shared into the workspace — only the legacy base-5 (projects/memory/agents/commands/todos) were linked. Named/pinned accounts (CLAUDE_CONFIG_DIR set) already worked; origin bare launches did not. This is why plugins never became a symlink on a second machine that launches origin directly.

  • _prepare-claude-launch --links-only — runs the workspace linker but skips the .claude.json merge. Bare origin reads ~/.claude.json (home), not <accountDir>/.claude.json, so merging there would target the wrong file.
  • Resolve the account-dir symlink up front~/.claude is a symlink to the origin account dir, and FileManager.contentsOfDirectory(at:) does not traverse a symlinked directory (POSIX EINVAL/ENOTDIR), which would otherwise silently link nothing.
  • claude() wrapper — when CLAUDE_CONFIG_DIR is unset and ~/.claude/metadata.json exists, run _prepare-claude-launch --account-dir "$HOME/.claude" --links-only (best-effort; no _capture-claude-exit, since nothing is merged to reconcile).

Result: bare origin launches now share the same dirs as orrery use origin.

Test Plan

  • --links-only syncs workspace symlinks without merging .claude.json
  • --account-dir follows a symlinked account dir (the ~/.claude origin case)
  • claude() wrapper links workspace for bare origin launch (CLAUDE_CONFIG_DIR unset)
  • Full suite green (368/368); generated wrapper valid in bash -n and zsh -n
  • End-to-end: links plugins (incl. nested content) through a ~/.claude-style symlink; idempotent on re-run
  • Adversarial review found no launch-blocking issues

🤖 Generated with Claude Code

…sions, …)

Launching bare `claude` on origin (CLAUDE_CONFIG_DIR unset) fell through to
`command claude` with no _prepare-claude-launch, so ~/.claude's shareable
dirs were never migrated into the workspace and symlinked — only the legacy
base-5 (projects/memory/agents/commands/todos) were linked. Named/pinned
accounts (CLAUDE_CONFIG_DIR set) worked; origin bare launches did not.

- _prepare-claude-launch: add --links-only (runs the workspace linker, skips
  the .claude.json merge). Bare origin reads ~/.claude.json (home), not
  <accountDir>/.claude.json, so merging there would target the wrong file.
- Resolve the account-dir symlink up front: ~/.claude is a symlink and
  FileManager.contentsOfDirectory(at:) does not traverse a symlinked dir
  (POSIX EINVAL/ENOTDIR), which would otherwise skip all linking.
- claude() wrapper: when CLAUDE_CONFIG_DIR is unset and ~/.claude/metadata.json
  exists, run `_prepare-claude-launch --account-dir "$HOME/.claude" --links-only`
  (best-effort, no capture — nothing to reconcile without a .claude.json merge).

Tests: --links-only skips the merge; --account-dir follows a symlinked dir;
wrapper links workspace for bare origin. Full suite green.
@gradyzhuo
gradyzhuo merged commit 1b184ac into main Jul 7, 2026
1 check passed
@gradyzhuo
gradyzhuo deleted the fix/origin-bare-launch-workspace-links branch July 7, 2026 04:07
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