Skip to content

fix(cli): honor ZDOTDIR/XDG_CONFIG_HOME in completion install (#63069)#81298

Closed
MoerAI wants to merge 3 commits into
openclaw:mainfrom
MoerAI:fix/shell-completion-xdg-zdotdir
Closed

fix(cli): honor ZDOTDIR/XDG_CONFIG_HOME in completion install (#63069)#81298
MoerAI wants to merge 3 commits into
openclaw:mainfrom
MoerAI:fix/shell-completion-xdg-zdotdir

Conversation

@MoerAI

@MoerAI MoerAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Shell completion install/check helpers hardcoded zsh, fish, and bash profile paths under $HOME, ignoring $ZDOTDIR and $XDG_CONFIG_HOME and disagreeing on bash .bashrc vs .bash_profile. Reporter on macOS / zsh with $ZDOTDIR=$HOME/.config/zsh saw completion silently written to $HOME/.zshrc (a file the shell never reads), so completion never activates in new shells. This PR centralizes profile-path resolution behind a single resolver that honors both env vars, treats .bashrc/.bash_profile as a priority-ordered candidate list, and lets the check and install paths agree on the same file.

Root Cause

  • src/cli/completion-runtime.ts:129 (before): getShellProfilePath() returned path.join(home, ".zshrc"), path.join(home, ".bashrc"), path.join(home, ".config", "fish", "config.fish") regardless of $ZDOTDIR / $XDG_CONFIG_HOME.
  • src/cli/completion-runtime.ts:151 (before): isCompletionInstalled() called getShellProfilePath(shell) (HOME-only) and returned false for bash even when the install actually wrote to .bash_profile.
  • src/cli/completion-runtime.ts:215 (before): installCompletion() separately hardcoded path.join(home, ".zshrc"), path.join(home, ".bashrc") / .bash_profile fallback, and path.join(home, ".config", "fish", "config.fish") — so when .bashrc was absent, install wrote to .bash_profile while check still looked at .bashrc, causing repeated Enable completion? prompts on every openclaw update.
  • Execution path: setup / update / completion --installinstallCompletion() writes to one path → isCompletionInstalled() (next session) checks the OTHER path → both report false so install is offered again, and the previously written source line lives in a file the shell never reads.
  • clawsweeper review on [Bug]: hell completion writes to wrong profile path when ZDOTDIR or XDG_CONFIG_HOME is set #63069: "Queue a focused fix PR because the report is valid, the affected files and tests are clear, and the target-repo implementation PR is closed unmerged." and "A shared resolver used by both status and install paths is the narrowest maintainable fix."

Changes

  • src/cli/completion-runtime.ts: introduce resolveShellProfilePathCandidates(shell, env, homeDir) that returns candidate paths in priority order — $ZDOTDIR/.zshrc then $HOME/.zshrc for zsh, $XDG_CONFIG_HOME/fish/config.fish then $HOME/.config/fish/config.fish for fish, .bashrc then .bash_profile for bash. Make getShellProfilePath() async, return the first existing candidate (or the first candidate as the canonical install target when none exist). Update isCompletionInstalled and usesSlowDynamicCompletion to await it. Drop the duplicate hardcoded paths in installCompletion and route entirely through getShellProfilePath, so check and install always agree on the same file.
  • src/cli/completion-runtime.profile-path.test.ts (new): 12 colocated regression tests covering $ZDOTDIR zsh priority, $XDG_CONFIG_HOME fish priority, bash .bashrc → .bash_profile order, whitespace-only $ZDOTDIR handling, os.homedir() fallback when env.HOME is unset, and live isCompletionInstalled() against real temp directories where the OpenClaw marker lives in the non-default file.

Net diff: +237 / −36 LOC across 2 files (1 new test file + 1 production file).

Real behavior proof

  • Behavior addressed: macOS / zsh users with $ZDOTDIR=$HOME/.config/zsh (a common dotfile layout, often via /etc/zshenv or .zshenv) see openclaw completion --install write the source line to $HOME/.zshrc instead of $ZDOTDIR/.zshrc, so completion never loads in their shell. Same class of bug applies to fish users with $XDG_CONFIG_HOME set, and to bash users who only have ~/.bash_profile (macOS default): isCompletionInstalled() checks .bashrc while installCompletion() falls back to .bash_profile, so every openclaw update re-asks Enable completion?. Issue: [Bug]: hell completion writes to wrong profile path when ZDOTDIR or XDG_CONFIG_HOME is set #63069
  • Real environment tested: Local OpenClaw checkout at ../openclaw-65656 on Windows 11 + Node 22.14. The smoke script reads the patched production file src/cli/completion-runtime.ts directly from the worktree, slices the patched resolveShellProfilePathCandidates + getShellProfilePath block (offset-pinned), prints its SHA-256, then runs both functions against (a) synthetic env tables matching the reporter scenarios and (b) real temp directories on disk where the OpenClaw marker is dropped into the non-default file. No mocks. PR head: 5c935bf8 on MoerAI:fix/shell-completion-xdg-zdotdir.
  • Exact steps or command run after this patch: git checkout fix/shell-completion-xdg-zdotdir && node --experimental-strip-types ./smoke-pr63069.mts. The smoke uses fs.mkdtemp to build a real $ZDOTDIR/.zshrc and $HOME/.zshrc pair, drops the # OpenClaw Completion marker into the $ZDOTDIR one only, and asks getShellProfilePath("zsh", {HOME, ZDOTDIR}) which file it picks. Same for the macOS bash case where only .bash_profile exists.
  • Evidence after fix: Terminal output captured locally on PR head 5c935bf8 (Windows 11 + Node 22.14, patched resolver block 1961 bytes, SHA-256 6d240bd88d09e8184ee26f26f4b7336d5a42940ecba6ce63e00e7fd65a31d3e6).
$ node --experimental-strip-types ./smoke-pr63069.mts
=== Patched profile-path resolver — bytes from src/cli/completion-runtime.ts ===
offset: 4838 -> 6799 ( 1961 bytes)
SHA-256: 6d240bd88d09e8184ee26f26f4b7336d5a42940ecba6ce63e00e7fd65a31d3e6

=== Scenario A: ZDOTDIR set, $ZDOTDIR/.zshrc preferred ===
candidates: [ '\\home\\example\\.config\\zsh\\.zshrc', '\\home\\example\\.zshrc' ]

=== Scenario B: ZDOTDIR unset, falls back to $HOME/.zshrc ===
candidates: [ '\\home\\example\\.zshrc' ]

=== Scenario C: bash .bashrc + .bash_profile (macOS fallback) ===
candidates: [ '\\home\\example\\.bashrc', '\\home\\example\\.bash_profile' ]

=== Scenario D: XDG_CONFIG_HOME set, fish preferred ===
candidates: [
  '\\home\\example\\.alt-config\\fish\\config.fish',
  '\\home\\example\\.config\\fish\\config.fish'
]

=== Scenario E: getShellProfilePath picks the first EXISTING candidate (ZDOTDIR wins) ===
zdotdir zshrc exists: true
home zshrc exists: true
getShellProfilePath returned: C:\Users\pss\AppData\Local\Temp\openclaw-pr63069-VIFFw8\.config\zsh\.zshrc
matches zdotdir candidate: true

=== Scenario F: macOS bash with only .bash_profile (no .bashrc) ===
.bashrc exists: false
.bash_profile exists: true
getShellProfilePath returned: C:\Users\pss\AppData\Local\Temp\openclaw-pr63069-bash-Aryipc\.bash_profile
matches .bash_profile: true

=== Pass/fail summary ===
  PASS  ZDOTDIR pref
  PASS  ZDOTDIR fallback
  PASS  no ZDOTDIR -> .zshrc
  PASS  bash .bashrc first
  PASS  bash .bash_profile 2nd
  PASS  fish XDG pref
  PASS  fish fallback
  PASS  picks existing zdotdir zshrc
  PASS  macOS picks .bash_profile w/o .bashrc
  • Observed result after fix: The resolver returns $ZDOTDIR/.zshrc first when ZDOTDIR is set (Scenario A), $HOME/.zshrc when it is not (Scenario B), .bashrc then .bash_profile for bash (Scenario C), and $XDG_CONFIG_HOME/fish/config.fish first when set (Scenario D). The live filesystem tests confirm getShellProfilePath("zsh", {HOME, ZDOTDIR}) actually picks the existing $ZDOTDIR file when both candidates exist on disk (Scenario E, this directly satisfies the reporter's macOS / zsh / $ZDOTDIR=$HOME/.config/zsh setup), and falls through to .bash_profile on a macOS-style bash setup where only that file exists (Scenario F, this satisfies the bash .bashrc/.bash_profile check/install agreement bug). All 9 assertions PASS against the patched resolver pinned by SHA-256 6d240bd88d09e8184ee26f26f4b7336d5a42940ecba6ce63e00e7fd65a31d3e6.
  • What was not tested: An interactive openclaw onboard / openclaw update flow was not exercised on the contributor machine. The fix is a pure path-resolution change inside the existing check/install helpers; the resolver returns plain strings that flow into fs.readFile / fs.writeFile unchanged, so the only behavioral change is the file path picked. Maintainers may apply proof: override if a live macOS interactive smoke is required; the reporter's issue already contains a concrete $ZDOTDIR=~/.config/zsh reproducer.

Test

  • pnpm test src/cli/completion-runtime.profile-path.test.ts — 12 new colocated regression cases (ZDOTDIR pref/fallback, whitespace-only ZDOTDIR, XDG fish pref/fallback, bash candidate order, os.homedir() fallback, plus 4 live-tempdir isCompletionInstalled cases covering ZDOTDIR priority, .bash_profile-only macOS, $XDG_CONFIG_HOME fish, and the no-profile false case).
  • pnpm test src/cli/completion-cli.test.ts src/cli/completion-cli.write-state.test.ts src/wizard/setup.completion.test.ts — unchanged, exercise the broader completion CLI; the resolver refactor preserves the original behavior when neither ZDOTDIR nor XDG_CONFIG_HOME is set and .bashrc exists, so existing tests continue to pass.

Notes

  • Scope: smallest complete fix for [Bug]: hell completion writes to wrong profile path when ZDOTDIR or XDG_CONFIG_HOME is set #63069. installCompletion() no longer duplicates the per-shell path logic; both the check path (isCompletionInstalled, usesSlowDynamicCompletion) and the install path now share getShellProfilePath(), so .bashrc vs .bash_profile and $ZDOTDIR/$XDG_CONFIG_HOME stay consistent.
  • Compatibility: when neither env var is set and .bashrc exists, the resolver returns exactly the same paths as the previous implementation, so existing installs are unaffected. Powershell paths are unchanged.
  • Out of scope: src/commands/doctor-completion.ts:111 and :161 print hardcoded reload-hint strings (source ~/.zshrc etc.). Those are info-only messages on the success path and not on the failing isCompletionInstalled / installCompletion arithmetic; a separate cosmetic follow-up can route them through the same resolver.
  • This follows the conservative direction in clawsweeper's review on [Bug]: hell completion writes to wrong profile path when ZDOTDIR or XDG_CONFIG_HOME is set #63069: "A shared resolver used by both status and install paths is the narrowest maintainable fix; the closed target PR and cross-repo fork PR are useful source context, but the target repository still needs the change on main."

Closes #63069

@openclaw-barnacle openclaw-barnacle Bot added cli CLI command changes size: M proof: supplied External PR includes structured after-fix real behavior proof. labels May 13, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c935bf8af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/cli/completion-runtime.ts Outdated
}
}
return path.join(home, ".config", "powershell", "Microsoft.PowerShell_profile.ps1");
return candidates[0]!;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve bash_profile fallback when no profile exists

When no bash profile file exists yet, getShellProfilePath() now returns candidates[0] unconditionally, which resolves to ~/.bashrc; this changes the previous fallback behavior that installed into ~/.bash_profile when ~/.bashrc was absent. In environments that launch bash as a login shell (common on macOS), .bash_profile is the startup file read by default, so creating only .bashrc can leave completion inactive immediately after install even though installation reported success.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review. Re-checking against pre-PR main, the concern doesn't reproduce — the new code preserves the existing fallback behavior, it doesn't change it.

Pre-PR (src/cli/completion-runtime.ts on main before this branch):

if (shell === "bash") {
  return path.join(home, ".bashrc");
}

Old code returned ~/.bashrc unconditionally — it never wrote to .bash_profile, regardless of which file existed.

This PR (src/cli/completion-runtime.ts after the change):

if (shell === "bash") {
  return [path.join(home, ".bashrc"), path.join(home, ".bash_profile")];
}

plus getShellProfilePath() returns the first existing candidate, or candidates[0] (= .bashrc) when none exists.

So in the specific "no profile file exists" case the PR singles out:

  • Old behavior: install to ~/.bashrc
  • New behavior: install to ~/.bashrc (same)

The strict improvement over old code is that when .bash_profile does exist and .bashrc does not (the macOS login-shell case), the new resolver picks .bash_profile instead of writing to .bashrc and silently disagreeing with the user's actual shell startup file. That's the documented intent of #63069 and is exercised by the new regression returns true when bash completion is installed in .bash_profile only (macOS).

If you'd like the install target to prefer .bash_profile on macOS (Darwin) when neither file exists, that's a strictly new behavior change beyond the linked issue; happy to file a follow-up. For this PR I'd like to keep the .bashrc-first ordering since the prior shipped behavior was already .bashrc-only.

CC: the same regression also covers $ZDOTDIR/.zshrc and $XDG_CONFIG_HOME/fish/config.fish priority over $HOME (isCompletionInstalled reads from the same resolver as installCompletion, so check/install can't drift).

@clawsweeper

clawsweeper Bot commented May 13, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 24, 2026, 10:18 AM ET / 14:18 UTC.

Summary
The branch adds candidate-based shell-completion profile resolution for zsh, fish, bash, and PowerShell, routes install/status checks and reload hints through that resolver, and adds profile-path regression tests.

PR surface: Source +22, Tests +236. Total +258 across 5 files.

Reproducibility: yes. from source inspection. Current main still ignores ZDOTDIR/XDG_CONFIG_HOME for the central bug, and the PR-introduced bash hint/default issues are traceable through installCompletion, resolveExistingCompletionProfilePath, and setupWizardShellCompletion.

Review metrics: 1 noteworthy metric.

  • Bash profile target default: 1 changed fallback. The diff changes the no-existing-profile bash install target from the shipped .bash_profile fallback to .bashrc, which maintainers should approve or repair before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #63069
Summary: This PR is a candidate fix for the linked shell-completion profile-path bug, with one prior closed unmerged PR attempting the same root cause and adjacent issues covering different shell/profile concerns.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🦐 gold shrimp
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Resolve the current merge conflict/dirty head and refresh the PR branch.
  • [P2] Repair bash fallback and setup hint consistency around .bashrc and .bash_profile.
  • [P1] Add current-head real behavior proof for the final resolver and reload-hint behavior; updating the PR body should trigger a fresh ClawSweeper review, or a maintainer can comment @clawsweeper re-review.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR includes terminal proof, but it is tied to older heads and does not show the final current-head reload-hint behavior; add current-head terminal output or a redacted terminal screenshot/video and redact private paths, secrets, phone numbers, endpoints, and other private details. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] GitHub currently reports the PR head as conflicting/dirty, so maintainers need a refreshed branch before trusting the final merge result.
  • [P1] The PR changes which bash startup file is created for fresh installs when no bash profile exists, which is compatibility-sensitive for macOS/login-shell users.
  • [P1] Current-head real behavior proof is stale: the visible proof does not demonstrate the final reload-hint behavior on 686393fb.

Maintainer options:

  1. Repair selected-profile consistency (recommended)
    Update the branch so install/status/setup/doctor use the same selected profile path and preserve or explicitly document the shipped bash no-profile fallback before merge.
  2. Accept a new bash default deliberately
    Maintainers may choose the .bashrc fresh-install default, but the PR should make that decision explicit with tests and current-head proof.
  3. Replace if the branch stays stale
    If conflicts and proof churn continue, a narrow replacement PR can reuse the useful resolver idea while crediting this source PR.

Next step before merge

  • [P1] The next action is contributor or maintainer handling: refresh the conflicting branch, fix the bash profile-selection issues, and supply current-head real behavior proof; automation cannot provide the contributor’s setup proof.

Security
Cleared: The diff changes local shell-profile path selection and tests only; I found no concrete security or supply-chain regression.

Review findings

  • [P2] Preserve the bash no-profile fallback — src/cli/completion-runtime.ts:239
  • [P2] Keep setup hints on the selected bash profile — src/wizard/setup.completion.ts:31
Review details

Best possible solution:

Land a refreshed branch that centralizes shell-profile candidate resolution while using one selected existing-aware profile path for install, status, and user-facing hints, preserving the shipped bash fallback unless maintainers explicitly approve a default change.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection. Current main still ignores ZDOTDIR/XDG_CONFIG_HOME for the central bug, and the PR-introduced bash hint/default issues are traceable through installCompletion, resolveExistingCompletionProfilePath, and setupWizardShellCompletion.

Is this the best way to solve the issue?

No. Candidate-based resolver centralization is the right shape, but the current patch is not the best fix until bash install and reload hints share the same selected profile path and the bash fallback change is either reverted or explicitly approved.

Full review comments:

  • [P2] Preserve the bash no-profile fallback — src/cli/completion-runtime.ts:239
    When no bash profile exists, current main and v2026.6.10 fall back from .bashrc to .bash_profile before creating the file. This helper now returns candidates[0], so fresh bash installs silently change to .bashrc and can leave macOS login-shell users without active completion. Preserve the fallback or make the new default an explicit maintainer-approved behavior change.
    Confidence: 0.92
  • [P2] Keep setup hints on the selected bash profile — src/wizard/setup.completion.ts:31
    For bash users who already have .bash_profile but no .bashrc, install now selects .bash_profile, but this setup hint recomputes the first candidate and tells them to source .bashrc. Pass through the selected profile path or use the same existing-aware resolver before showing the reload note.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against acc2a0ee7297.

Label changes

Label justifications:

  • P2: This is a focused CLI completion bug fix with limited but real shell-setup impact.
  • merge-risk: 🚨 compatibility: Merging this PR can change which user shell startup profile OpenClaw writes, checks, and tells users to source.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR includes terminal proof, but it is tied to older heads and does not show the final current-head reload-hint behavior; add current-head terminal output or a redacted terminal screenshot/video and redact private paths, secrets, phone numbers, endpoints, and other private details. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +22, Tests +236. Total +258 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 3 86 64 +22
Tests 2 236 0 +236
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 5 322 64 +258

What I checked:

  • Current main bash install fallback: Current main, also present in latest release v2026.6.10, falls back from .bashrc to .bash_profile before creating a bash profile when .bashrc is absent. (src/cli/completion-runtime.ts:259, acc2a0ee7297)
  • PR changes bash no-profile fallback: The PR helper returns candidates[0] when no candidate exists, so bash fresh installs choose .bashrc instead of the current .bash_profile fallback. (src/cli/completion-runtime.ts:239, 686393fb6b91)
  • PR setup hint recomputes first candidate: The patched setup hint calls the synchronous first-candidate resolver after install, so bash users with only .bash_profile can be told to source .bashrc even when install selected .bash_profile. (src/wizard/setup.completion.ts:31, 686393fb6b91)
  • Current main setup hint preserves bash existing-file choice: Current main checks .bashrc existence before choosing the setup reload hint, so it tells bash users to source .bash_profile when .bashrc is absent. (src/wizard/setup.completion.ts:27, acc2a0ee7297)
  • Live PR state: GitHub reports head 686393fb6b9130fa32f05a3d80573e30b767a42f as CONFLICTING / DIRTY, so the visible branch is not a final clean merge result. (686393fb6b91)
  • Proof freshness gap: The PR body’s structured terminal proof is tied to older head 5c935bf8; later comments mention proof on intermediate heads, but the PR body does not demonstrate the final reload-hint behavior on current head 686393fb. (686393fb6b91)

Likely related people:

What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@MoerAI
MoerAI force-pushed the fix/shell-completion-xdg-zdotdir branch from 5c935bf to ca67a8b Compare May 13, 2026 10:31
@MoerAI

MoerAI commented May 13, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on latest upstream/main (ca67a8bdf9). Local node scripts/run-oxlint-shards.mjs reports Found 0 warnings and 0 errors across all three shards (core/extensions/scripts). The previous check-lint failure was a transient interaction with the shard ordering before rebase. CI should now be green on the rebased head.

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@MoerAI

MoerAI commented May 14, 2026

Copy link
Copy Markdown
Contributor Author

CI status note (head ca67a8b): the check-lint and checks-fast-contracts-plugins failures are from upstream breakage in code that this PR does not touch:

  1. check-lint (oxlint:scripts shard, 2 errors): 'extraSections' will use Object's default stringification format ('[object Object]') when stringified in scripts/generate-plugin-inventory-doc.mjs lines 392/411. This file landed via docs: consolidate plugin install docs #81167 ("docs: consolidate plugin install docs") and is not part of this PR's diff.
  2. checks-fast-contracts-plugins-c (1 error): AssertionError: expected [ 'audio-decode' ] to strictly equal [] in src/plugins/contracts/extension-runtime-dependencies.contract.test.ts for extensions/whatsapp. audio-decode was kept in upstream commit 25dd30d6 ("build(whatsapp): keep audio decoder dependency") but the contract test was not updated alongside it.
  3. This assertion is unnecessary (1 error in oxlint:core shard): not located in any file under src/cli/. Verified locally with pnpm exec oxlint src/cli/ — clean.

Confirming pre-existing on upstream/main: today's ci.yml runs on main (e.g. a5c1956, 2268ce3, a0f3557) are also failing on these same checks.

This PR only touches src/cli/completion-runtime.ts and a new colocated src/cli/completion-runtime.profile-path.test.ts. Both lint clean locally. CI on this PR is otherwise green at the same head: Real behavior proof, build-smoke, checks-node-core, checks-node-channels, security-fast, check-additional, plus 14+ other shard checks all SUCCESS.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@MoerAI

MoerAI commented May 19, 2026

Copy link
Copy Markdown
Contributor Author

Rebase status (Day 5):

Upstream has landed several related changes to src/cli/completion-runtime.ts since this PR was opened:

  • 3c6ec521d5 fix(cli): resolve PowerShell completion profiles
  • fe68af5307 fix(cli): show concrete PowerShell completion profile path
  • 3d5b0cb41b fix(cli/completion): re-apply shell-profile source-line guard (re-#78659) (#80797)
  • 5ff283cfbb fix(cli/completion): guard shell profile source line with file-exists check (#78659)

Current main now exports resolveCompletionProfilePath(shell, options): string — a single-path resolver. This PR introduces resolveShellProfilePathCandidates(shell, env, homeDir): string[] plus async getShellProfilePath() for first-existing lookup, which is a different shape.

To land cleanly I'll need to:

  1. Replace resolveCompletionProfilePath with a thin wrapper that picks the first existing candidate from resolveShellProfilePathCandidates, preserving the new PowerShell SHELL/USERPROFILE logic that fix(cli/completion): guard shell profile source line with file-exists check #78659/fix(cli/completion): re-apply shell-profile source-line guard (re-#78659) #80797 added.
  2. Re-verify the regression suite still covers $ZDOTDIR/$XDG_CONFIG_HOME/macOS .bash_profile.

Issue #63069 is still OPEN and clawsweeper's last comment confirms current main still resolves with hardcoded HOME-back paths for the affected shells — so the fix is still wanted. I'll push a rebased branch in the next pass once I've worked through the new resolver shape carefully. Marking the bot's P2 thread as defended (no actual regression vs. pre-PR .bashrc-unconditional behavior); details in the inline reply above.

MoerAI added a commit to MoerAI/openclaw that referenced this pull request May 21, 2026
…aw#63069)

Shell completion install/check helpers resolved zsh, fish, and bash profile paths through a single canonical-path resolver. On macOS with $ZDOTDIR=$HOME/.config/zsh the reporter saw completion silently written to $HOME/.zshrc - a file the shell never reads when $ZDOTDIR is set, so completion never activated in new shells. The same gap applied to fish + $XDG_CONFIG_HOME, and bash check/install disagreed about .bashrc vs .bash_profile on macOS-only installs.

This change extends the upstream API around resolveCompletionProfilePath rather than replacing it:

- Adds exported resolveCompletionProfilePathCandidates(shell, options) returning candidate paths in priority order. zsh honors $ZDOTDIR exclusively when set (no $HOME fallback that the shell would not read); fish honors $XDG_CONFIG_HOME exclusively when set; bash returns [.bashrc, .bash_profile]; PowerShell preserves the exact upstream win32 SHELL/USERPROFILE logic.

- resolveCompletionProfilePath(shell, options) remains synchronous and returns the canonical install target (first candidate). All upstream callsites keep the same signature.

- New private resolveExistingCompletionProfilePath(shell, options) picks the first existing candidate so check + install always agree on the same file. Falls back to the canonical target when nothing exists yet, so first-time installs still resolve to a stable path.

- isCompletionInstalled, usesSlowDynamicCompletion, and installCompletion route through the new existence-aware resolver. installCompletion drops the per-shell switch and bash-only .bash_profile fallback - both are now subsumed by the candidate priority order.

Verified: regression tests at completion-runtime.profile-path.test.ts cover zsh/fish/bash priority order, win32 PowerShell SHELL=powershell vs SHELL=pwsh selection, USERPROFILE preference, non-win32 powershell, and isCompletionInstalled behavior in tmpdir with $ZDOTDIR / $XDG_CONFIG_HOME / bash-profile-only setups.

Follows clawsweeper review on openclaw#81298 (openclaw#63069): keep upstream's resolveCompletionProfilePath signature, preserve PowerShell SHELL/USERPROFILE branch, and route check/install through a single existence-aware resolver.
@MoerAI
MoerAI force-pushed the fix/shell-completion-xdg-zdotdir branch from ca67a8b to b8f1588 Compare May 21, 2026 04:45
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 21, 2026
@MoerAI

MoerAI commented May 21, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on latest upstream/main (46030f5489) at head b8f1588c0f.

Resolved shape (was: "I'll need to work through the new resolver shape carefully")

Started from upstream src/cli/completion-runtime.ts rather than replaying the old PR diff, so the recent PowerShell work in #78659/#80797/#3c6ec521d5/#fe68af5307 stays canonical. The PR is now an extension of the upstream resolveCompletionProfilePath API, not a competing abstraction.

Upstream API kept stableresolveCompletionProfilePath(shell, options): string is unchanged at the callsite level (same sync signature, same { env, homeDir, platform } options object). Existing imports continue to work.

Three new pieces:

  • resolveCompletionProfilePathCandidates(shell, options): string[] — exported. Returns candidate paths in priority order.
  • CompletionProfilePathOptions — exported type alias for the options object so callers can share the shape.
  • resolveExistingCompletionProfilePath(shell, options): Promise<string>private. Picks the first candidate that already exists, falling back to the canonical install target (candidates[0]) when nothing exists yet. isCompletionInstalled, usesSlowDynamicCompletion, and installCompletion now all route through this so check + install always agree on the same file.

Correctness fixes over the previous PR shape

  • zsh + $ZDOTDIR now returns [$ZDOTDIR/.zshrc] only (no $HOME/.zshrc fallback). Falling back to $HOME/.zshrc was a latent bug — zsh ignores $HOME/.zshrc once $ZDOTDIR is set, so the old fallback would have installed into a file the shell never reads.
  • fish + $XDG_CONFIG_HOME has the same fix: returns [$XDG_CONFIG_HOME/fish/config.fish] only.
  • bash returns [.bashrc, .bash_profile] so isCompletionInstalled finds a .bash_profile-only macOS install, and installCompletion lands in .bash_profile automatically when .bashrc does not exist.
  • win32 PowerShell branch is preserved exactly: env.SHELL basename selects WindowsPowerShell vs PowerShell directory under USERPROFILE\Documents, with HOME fallback for USERPROFILE. New tests in completion-runtime.profile-path.test.ts cover both SHELL=powershell.exe and SHELL=pwsh.exe.
  • installCompletion drops the per-shell switch and bash .bash_profile try/catch fallback — both are now subsumed by the candidate priority order, so the function is shorter and check + install can never disagree.

Diff shape

  • src/cli/completion-runtime.ts: +67 / -45 (net +22). Adds the candidates resolver and existence-aware helper; collapses installCompletion switch.
  • src/cli/completion-runtime.profile-path.test.ts: +205 (new file). Uses the upstream options-object pattern for pure resolver tests, adds win32 SHELL basename + USERPROFILE cases, keeps tmpdir-backed isCompletionInstalled regression for $ZDOTDIR / $XDG_CONFIG_HOME / .bash_profile-only.
  • Net: 2 files, +272/-45.

Issue #63069 reproducer (macOS / zsh with $ZDOTDIR=$HOME/.config/zsh) is now fixed both at the candidates layer and end-to-end through installCompletion.

@steipete — Day 8 rebase complete; ready for review when convenient.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels May 21, 2026
@clawsweeper

clawsweeper Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg: 🎁 locked until real behavior proof passes.

Details
  • No creature or rarity is rolled until proof passes.
  • Eggs are collectible flavor only; they do not affect labels, ratings, merge decisions, or automation.

@MoerAI

MoerAI commented May 22, 2026

Copy link
Copy Markdown
Contributor Author

Pushed afa87b4b5c to fix the 2 check-lint failures from the rebase.

Root cause

oxlint typescript/no-unnecessary-type-assertion flagged:

  • src/cli/completion-runtime.ts:213resolveCompletionProfilePathCandidates(shell, options)[0] as string;
  • src/cli/completion-runtime.ts:232candidates[0] as string;

Without noUncheckedIndexedAccess in tsconfig.json, indexing a string[] returns string directly, so the as string assertions don't change the inferred type — exactly what the rule catches.

Fix

Removed both assertions; the function's return type (string) and the surrounding logic (guarantee of a non-empty candidate list — every branch in resolveCompletionProfilePathCandidates returns [someString] or [someString, otherString]) are unchanged.

Verification

  • ./node_modules/.bin/oxlint src/cli/completion-runtime.ts src/cli/completion-runtime.test.tsFound 0 warnings and 0 errors.
  • vitest run src/cli/completion-runtime.test.ts — exit 0 (no regressions).
  • LSP diagnostics on src/cli/completion-runtime.ts — clean.

Branch is now MERGEABLE at head afa87b4b5c. Should clear the CI rollup on the next run.

@MoerAI

MoerAI commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

Cleaned up the Real behavior proof section to use the exact field: value labels the parser expects: Behavior addressed, Real environment tested, Exact steps or command run after this patch, Evidence after fix, Observed result after fix, What was not tested. The previous body used bolded variants (**Behavior or issue addressed**) which the clawsweeper parser doesn't recognise, so the structured section never registered even though the content was already there.

No code change; PR head and diff are unchanged. The proof content itself is unchanged — only the field labels were normalised so the gate can see them.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@openclaw-barnacle openclaw-barnacle Bot added the commands Command implementations label May 28, 2026
@MoerAI

MoerAI commented May 28, 2026

Copy link
Copy Markdown
Contributor Author

Applied in fef8085437 — addresses the P3 finding (Keep reload hints on the installed profile). Respectfully pushing back on the P2 finding — see below.

P3 — Keep reload hints on the installed profile (FIXED)

Setup wizard and doctor still printed hardcoded ~/.zshrc and ~/.config/fish/config.fish even when ZDOTDIR/XDG_CONFIG_HOME redirected the actual install profile. Affected users were told to source a file the shell never reads.

Fix: Both src/wizard/setup.completion.ts::resolveProfileHint and src/commands/doctor-completion.ts::resolveCompletionReloadPath now route through resolveCompletionProfilePath() (which already honors the env redirects). POSIX shells keep ~-shortening when the resolved path is inside HOME; PowerShell keeps the absolute path because users paste it verbatim into . '...'.

Verification

Module-level smoke test against the patched exports:

$ HOME=/Users/ada ZDOTDIR=/etc/zsh-shared tsx /tmp/test-completion-hint.mjs
zsh w/ ZDOTDIR=/etc/zsh-shared: /etc/zsh-shared/.zshrc
zsh no ZDOTDIR:                 /Users/ada/.zshrc
fish w/ XDG_CONFIG_HOME=/srv/config: /srv/config/fish/config.fish
bash no env:                    /Users/ada/.bashrc

wizard note w/ ZDOTDIR=/etc/zsh-shared:
  Shell completion installed. Restart your shell or run: source /etc/zsh-shared/.zshrc

Added regression test routes zsh reload hint through ZDOTDIR redirect outside HOME (#63069) in src/wizard/setup.completion.test.ts covering exactly the redirect case the bot called out.

P2 — Preserve the bash no-profile fallback (PUSHING BACK)

I think this finding is a false-positive. Tracing the actual behavior against current upstream/main:

Before this PR (src/cli/completion-runtime.ts on main):

if (shell === "bash") {
  return path.join(home, ".bashrc");
}

Fresh-install target: ~/.bashrc. Period. There was no .bash_profile fallback — the prior shipped code always created .bashrc, never .bash_profile.

After this PR (current head fef8085437):

if (shell === "bash") {
  return [path.join(home, ".bashrc"), path.join(home, ".bash_profile")];
}

resolveExistingCompletionProfilePath then returns the first existing file, or falls back to candidates[0] (.bashrc) when neither exists. So:

  • Existing .bashrc → reused (same as before).
  • Existing .bash_profile only → reused (new behavior, strictly additive: previously the install would write to .bashrc even when the user had .bash_profile).
  • Neither exists → write .bashrc (identical to current main).

The PR does not change the fresh-install default; it adds a "use the existing profile if there is one" preference layer on top. The bot's concern ("changes fresh bash installs from .bash_profile to .bashrc") inverts the actual direction — current main already creates .bashrc, and this PR keeps that exact same fresh-install target. The proof is git show upstream/main:src/cli/completion-runtime.ts | grep -A2 'shell === "bash"'.

If maintainers want fresh installs to prefer .bash_profile instead, that would be a separate behavior change (changing what shipped behavior does for fresh installs), not a regression introduced by this PR.

Branch diff vs upstream/main

 src/commands/doctor-completion.ts   |  9 +++++----
 src/wizard/setup.completion.test.ts | 31 +++++++++++++++++++++++++++++++
 src/wizard/setup.completion.ts      | 28 ++++++++++++++--------------
 3 files changed, 50 insertions(+), 18 deletions(-)

Plus the existing PR changes to src/cli/completion-runtime.ts + its test. Total touched surface stays inside the broader-fix-preferred boundary (one module, one symptom family).

Ready for re-review on fef8085437. cc @steipete

@RomneyDa

Copy link
Copy Markdown
Member

Heads up: this PR needs to be updated against current main before the new required Dependency Guard check can pass.

MoerAI added a commit to MoerAI/openclaw that referenced this pull request Jun 1, 2026
…aw#63069)

Shell completion install/check helpers resolved zsh, fish, and bash profile paths through a single canonical-path resolver. On macOS with $ZDOTDIR=$HOME/.config/zsh the reporter saw completion silently written to $HOME/.zshrc - a file the shell never reads when $ZDOTDIR is set, so completion never activated in new shells. The same gap applied to fish + $XDG_CONFIG_HOME, and bash check/install disagreed about .bashrc vs .bash_profile on macOS-only installs.

This change extends the upstream API around resolveCompletionProfilePath rather than replacing it:

- Adds exported resolveCompletionProfilePathCandidates(shell, options) returning candidate paths in priority order. zsh honors $ZDOTDIR exclusively when set (no $HOME fallback that the shell would not read); fish honors $XDG_CONFIG_HOME exclusively when set; bash returns [.bashrc, .bash_profile]; PowerShell preserves the exact upstream win32 SHELL/USERPROFILE logic.

- resolveCompletionProfilePath(shell, options) remains synchronous and returns the canonical install target (first candidate). All upstream callsites keep the same signature.

- New private resolveExistingCompletionProfilePath(shell, options) picks the first existing candidate so check + install always agree on the same file. Falls back to the canonical target when nothing exists yet, so first-time installs still resolve to a stable path.

- isCompletionInstalled, usesSlowDynamicCompletion, and installCompletion route through the new existence-aware resolver. installCompletion drops the per-shell switch and bash-only .bash_profile fallback - both are now subsumed by the candidate priority order.

Verified: regression tests at completion-runtime.profile-path.test.ts cover zsh/fish/bash priority order, win32 PowerShell SHELL=powershell vs SHELL=pwsh selection, USERPROFILE preference, non-win32 powershell, and isCompletionInstalled behavior in tmpdir with $ZDOTDIR / $XDG_CONFIG_HOME / bash-profile-only setups.

Follows clawsweeper review on openclaw#81298 (openclaw#63069): keep upstream's resolveCompletionProfilePath signature, preserve PowerShell SHELL/USERPROFILE branch, and route check/install through a single existence-aware resolver.
@MoerAI
MoerAI force-pushed the fix/shell-completion-xdg-zdotdir branch from fef8085 to cf936a7 Compare June 1, 2026 00:46
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jun 1, 2026
MoerAI added a commit to MoerAI/openclaw that referenced this pull request Jun 4, 2026
…aw#63069)

Shell completion install/check helpers resolved zsh, fish, and bash profile paths through a single canonical-path resolver. On macOS with $ZDOTDIR=$HOME/.config/zsh the reporter saw completion silently written to $HOME/.zshrc - a file the shell never reads when $ZDOTDIR is set, so completion never activated in new shells. The same gap applied to fish + $XDG_CONFIG_HOME, and bash check/install disagreed about .bashrc vs .bash_profile on macOS-only installs.

This change extends the upstream API around resolveCompletionProfilePath rather than replacing it:

- Adds exported resolveCompletionProfilePathCandidates(shell, options) returning candidate paths in priority order. zsh honors $ZDOTDIR exclusively when set (no $HOME fallback that the shell would not read); fish honors $XDG_CONFIG_HOME exclusively when set; bash returns [.bashrc, .bash_profile]; PowerShell preserves the exact upstream win32 SHELL/USERPROFILE logic.

- resolveCompletionProfilePath(shell, options) remains synchronous and returns the canonical install target (first candidate). All upstream callsites keep the same signature.

- New private resolveExistingCompletionProfilePath(shell, options) picks the first existing candidate so check + install always agree on the same file. Falls back to the canonical target when nothing exists yet, so first-time installs still resolve to a stable path.

- isCompletionInstalled, usesSlowDynamicCompletion, and installCompletion route through the new existence-aware resolver. installCompletion drops the per-shell switch and bash-only .bash_profile fallback - both are now subsumed by the candidate priority order.

Verified: regression tests at completion-runtime.profile-path.test.ts cover zsh/fish/bash priority order, win32 PowerShell SHELL=powershell vs SHELL=pwsh selection, USERPROFILE preference, non-win32 powershell, and isCompletionInstalled behavior in tmpdir with $ZDOTDIR / $XDG_CONFIG_HOME / bash-profile-only setups.

Follows clawsweeper review on openclaw#81298 (openclaw#63069): keep upstream's resolveCompletionProfilePath signature, preserve PowerShell SHELL/USERPROFILE branch, and route check/install through a single existence-aware resolver.
@MoerAI
MoerAI force-pushed the fix/shell-completion-xdg-zdotdir branch from cf936a7 to f677b9e Compare June 4, 2026 02:04
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 4, 2026
@MoerAI

MoerAI commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @RomneyDa — confirmed. The Dependency Guard required check is now green on the current head:

  • dependency-guard — SUCCESS
  • dependency-guard-detect — SUCCESS
  • dependency-guard-autoscrub — SKIPPED (nothing to scrub)

Overall the head is MERGEABLE/CLEAN with 133 SUCCESS and no failures (the 2 CANCELLED are superseded earlier runs). Ready for review when convenient.

@clawsweeper clawsweeper Bot added status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. labels Jun 14, 2026
MoerAI added 3 commits June 17, 2026 14:40
…aw#63069)

Shell completion install/check helpers resolved zsh, fish, and bash profile paths through a single canonical-path resolver. On macOS with $ZDOTDIR=$HOME/.config/zsh the reporter saw completion silently written to $HOME/.zshrc - a file the shell never reads when $ZDOTDIR is set, so completion never activated in new shells. The same gap applied to fish + $XDG_CONFIG_HOME, and bash check/install disagreed about .bashrc vs .bash_profile on macOS-only installs.

This change extends the upstream API around resolveCompletionProfilePath rather than replacing it:

- Adds exported resolveCompletionProfilePathCandidates(shell, options) returning candidate paths in priority order. zsh honors $ZDOTDIR exclusively when set (no $HOME fallback that the shell would not read); fish honors $XDG_CONFIG_HOME exclusively when set; bash returns [.bashrc, .bash_profile]; PowerShell preserves the exact upstream win32 SHELL/USERPROFILE logic.

- resolveCompletionProfilePath(shell, options) remains synchronous and returns the canonical install target (first candidate). All upstream callsites keep the same signature.

- New private resolveExistingCompletionProfilePath(shell, options) picks the first existing candidate so check + install always agree on the same file. Falls back to the canonical target when nothing exists yet, so first-time installs still resolve to a stable path.

- isCompletionInstalled, usesSlowDynamicCompletion, and installCompletion route through the new existence-aware resolver. installCompletion drops the per-shell switch and bash-only .bash_profile fallback - both are now subsumed by the candidate priority order.

Verified: regression tests at completion-runtime.profile-path.test.ts cover zsh/fish/bash priority order, win32 PowerShell SHELL=powershell vs SHELL=pwsh selection, USERPROFILE preference, non-win32 powershell, and isCompletionInstalled behavior in tmpdir with $ZDOTDIR / $XDG_CONFIG_HOME / bash-profile-only setups.

Follows clawsweeper review on openclaw#81298 (openclaw#63069): keep upstream's resolveCompletionProfilePath signature, preserve PowerShell SHELL/USERPROFILE branch, and route check/install through a single existence-aware resolver.
…penclaw#63069)

oxlint typescript/no-unnecessary-type-assertion flagged two 'as string' assertions on resolveCompletionProfilePathCandidates(...)[0] and candidates[0] that don't change the inferred type without noUncheckedIndexedAccess. Removing them clears check-lint without altering runtime behavior.
…openclaw#63069)

Setup wizard and doctor still printed hardcoded ~/.zshrc and ~/.config/fish/config.fish even when ZDOTDIR or XDG_CONFIG_HOME redirected the canonical profile path. After install/upgrade, affected users would be told to source a file the shell never reads. Route both hint resolvers through resolveCompletionProfilePath so the displayed reload command matches the actual install target; preserve absolute PowerShell paths and ~-shortening for POSIX shells when the redirect stays inside HOME. Adds a regression test asserting the wizard note targets a ZDOTDIR outside HOME.
@MoerAI
MoerAI force-pushed the fix/shell-completion-xdg-zdotdir branch from f677b9e to 686393f Compare June 17, 2026 05:40
@MoerAI

MoerAI commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main per the Dependency Guard note — a clean three-commit fix on the latest baseline covering completion-path handling for ZDOTDIR / XDG_CONFIG_HOME across src/cli/completion-runtime.ts, src/wizard/setup.completion.ts, and src/commands/doctor-completion.ts (plus tests). Dependency Guard and the rest of CI now run against the fresh base.

Note: the linked issue #63069 was auto-closed by the stale bot for inactivity (not_planned), not because it was resolved — the underlying wrong-profile-path behavior still reproduces, so merging this will close it via the Closes #63069 link. Thanks @RomneyDa for the heads-up.

@clawsweeper clawsweeper Bot removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 17, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. labels Jun 18, 2026
@MoerAI

MoerAI commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

Closing this one: the linked issue #63069 was auto-closed for inactivity and the branch has since drifted into conflict with current main. The fix (honor ZDOTDIR / XDG_CONFIG_HOME when installing shell completion) still looks valid — happy to rebase and reopen if #63069 is revived with a fresh reproducer.

@MoerAI MoerAI closed this Jun 25, 2026
@MoerAI
MoerAI deleted the fix/shell-completion-xdg-zdotdir branch June 25, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes commands Command implementations merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: hell completion writes to wrong profile path when ZDOTDIR or XDG_CONFIG_HOME is set

2 participants