Skip to content

Fix varlock path compatibility for debug/startup/subagents#203

Merged
benvinegar merged 2 commits intomainfrom
fix/varlock-path-compat
Mar 17, 2026
Merged

Fix varlock path compatibility for debug/startup/subagents#203
benvinegar merged 2 commits intomainfrom
fix/varlock-path-compat

Conversation

@benvinegar
Copy link
Member

Summary

  • support both varlock install locations in runtime paths:
    • ~/.varlock/bin (legacy)
    • ~/.config/varlock/bin (current installer)
  • update startup/service/debug/subagent PATH construction to include both locations
  • update setup flow to create a compatibility symlink at ~/.varlock/bin/varlock when varlock is installed under ~/.config/varlock/bin
  • update doctor + CI setup checks to accept either location

Why

Fresh Ubuntu installs can have varlock only at ~/.config/varlock/bin/varlock, which caused baudbot debug and other paths that assumed ~/.varlock/bin to fail with varlock: command not found.

Validation

  • npm run lint:shell
  • npm run test:shell
  • bash bin/baudbot.test.sh

@greptile-apps
Copy link

greptile-apps bot commented Mar 17, 2026

Greptile Summary

This PR adds support for varlock's newer install location (~/.config/varlock/bin) alongside the legacy one (~/.varlock/bin) across all runtime paths — the systemd service, startup script, debug runner, subagent spawner, CI checks, doctor script, and setup flow — to fix varlock: command not found on fresh Ubuntu installs.

Key changes:

  • All PATH constructions (start.sh, baudbot-runtime.sh, subagents.sh, baudbot.service, CI scripts) now include both ~/.varlock/bin and ~/.config/varlock/bin, with the legacy path given precedence.
  • setup.sh gains a compatibility symlink step: when varlock is found only at the new location, it creates ~/.varlock/bin/varlock → ~/.config/varlock/bin/varlock so that any scripts not yet updated still work.
  • doctor.sh and CI checks are updated to accept either path as proof of a valid install.
  • The elif used in doctor.sh for the telemetry anonymousId warning means the new config path (~/.config/varlock/config.json) is never inspected when the legacy config file already matches — potentially missing a live telemetry issue on migrated systems.
  • In setup.sh, the symlink creation uses ln -sf unconditionally, which will silently replace an existing real binary at ~/.varlock/bin/varlock with a symlink on every re-run when both paths are populated.

Confidence Score: 4/5

  • Safe to merge — fixes a real breakage on fresh Ubuntu installs with only minor logic gaps in doctor.sh and setup.sh.
  • The dual-path changes are applied consistently and correctly across all relevant files. The two issues flagged (elif shortcut in doctor.sh and unconditional ln -sf in setup.sh) are low severity: the doctor issue misses a telemetry warning edge case, and the setup issue is a silent-but-harmless binary replacement on idempotent re-runs. Neither causes a runtime failure.
  • bin/doctor.sh (elif logic) and setup.sh (ln -sf overwrite guard)

Important Files Changed

Filename Overview
bin/baudbot.service Adds ~/.config/varlock/bin to the hardcoded Environment=PATH line, consistent with the dual-path strategy. Change is minimal and correct.
bin/ci/setup-arch.sh CI varlock presence check now accepts either install path via `
bin/ci/setup-ubuntu.sh Identical dual-path fix as setup-arch.sh — CI check and smoke-test PATH both updated. No issues found.
bin/doctor.sh Detection logic correctly checks both varlock locations, but the elif for the new config telemetry check means both paths are never independently evaluated — if the legacy config matches first, the new-path config is never inspected.
bin/lib/baudbot-runtime.sh cmd_debug() PATH updated to include both varlock locations. Single-line change, correctly uses the outer-shell-expanded $AGENT_HOME variable before the sudo boundary. No issues.
bin/subagents.sh Tmux command PATH updated with \$HOME/.config/varlock/bin (escaped correctly so it expands inside the tmux session as the agent user). No issues.
setup.sh Install-skip check and compatibility symlink logic added. The ln -sf in the symlink block will silently replace an existing real binary at the legacy path on every re-run of setup.sh when the new path also exists, which could be surprising.
start.sh PATH export updated to include both varlock locations before varlock load is called. Ordering is correct (legacy path has precedence) and the change is idiomatic.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[setup.sh: install varlock?] -->|legacy OR new path exists| B[Skip install]
    A -->|Neither exists| C[Run varlock installer]
    C --> D{New path populated?}
    B --> D
    D -->|~/.config/varlock/bin/varlock executable| E[Create compatibility symlink\n~/.varlock/bin/varlock points to new location]
    D -->|Only legacy path exists| F[No symlink needed]

    E --> G[Runtime PATH includes both paths]
    F --> G

    G --> H[start.sh]
    G --> I[baudbot-runtime.sh cmd_debug]
    G --> J[subagents.sh tmux session]
    G --> K[baudbot.service systemd unit]
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: bin/doctor.sh
Line: 85-88

Comment:
**`elif` silences telemetry warning for new config path when legacy config also matches**

Because the new config-path check is behind an `elif`, if `~/.varlock/config.json` exists **and** contains `anonymousId`, the check for `~/.config/varlock/config.json` is never reached — even if that file also contains `anonymousId`. On systems where both config files are present (e.g., migrated installs), the new-path telemetry issue would go undetected.

Use two independent `if` blocks so both paths are always checked:

```suggestion
  if [ -f "$BAUDBOT_HOME/.varlock/config.json" ] && grep -q '"anonymousId"' "$BAUDBOT_HOME/.varlock/config.json"; then
    warn "$BAUDBOT_HOME/.varlock/config.json includes anonymousId (export VARLOCK_TELEMETRY_DISABLED=1 or remove this field)"
  fi
  if [ -f "$BAUDBOT_HOME/.config/varlock/config.json" ] && grep -q '"anonymousId"' "$BAUDBOT_HOME/.config/varlock/config.json"; then
    warn "$BAUDBOT_HOME/.config/varlock/config.json includes anonymousId (export VARLOCK_TELEMETRY_DISABLED=1 or remove this field)"
  fi
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: setup.sh
Line: 264-265

Comment:
**`ln -sf` silently overwrites a real binary when both install locations coexist**

If `~/.varlock/bin/varlock` already exists as a real (non-symlink) binary — e.g., a legacy install — and `~/.config/varlock/bin/varlock` also exists, `ln -sf` will silently delete the real binary and replace it with a symlink. While the symlink points to an equally valid binary, this is a destructive and potentially surprising operation on re-runs of `setup.sh`.

Consider guarding with a check that skips the symlink creation if the legacy path already contains a functional binary that is not a symlink:

```bash
if [ -x "$AGENT_VARLOCK_CONFIG_BIN" ] && [ ! -x "$AGENT_VARLOCK" ]; then
  sudo -u baudbot_agent bash -c "mkdir -p '$BAUDBOT_HOME/.varlock/bin' && ln -sf '$AGENT_VARLOCK_CONFIG_BIN' '$AGENT_VARLOCK'"
fi
```

This creates the compatibility link only when the legacy path is absent, avoiding accidental replacement of an existing real binary.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 4aaabe2

Comment on lines 85 to +88
if [ -f "$BAUDBOT_HOME/.varlock/config.json" ] && grep -q '"anonymousId"' "$BAUDBOT_HOME/.varlock/config.json"; then
warn "$BAUDBOT_HOME/.varlock/config.json includes anonymousId (export VARLOCK_TELEMETRY_DISABLED=1 or remove this field)"
elif [ -f "$BAUDBOT_HOME/.config/varlock/config.json" ] && grep -q '"anonymousId"' "$BAUDBOT_HOME/.config/varlock/config.json"; then
warn "$BAUDBOT_HOME/.config/varlock/config.json includes anonymousId (export VARLOCK_TELEMETRY_DISABLED=1 or remove this field)"
Copy link

Choose a reason for hiding this comment

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

P2 elif silences telemetry warning for new config path when legacy config also matches

Because the new config-path check is behind an elif, if ~/.varlock/config.json exists and contains anonymousId, the check for ~/.config/varlock/config.json is never reached — even if that file also contains anonymousId. On systems where both config files are present (e.g., migrated installs), the new-path telemetry issue would go undetected.

Use two independent if blocks so both paths are always checked:

Suggested change
if [ -f "$BAUDBOT_HOME/.varlock/config.json" ] && grep -q '"anonymousId"' "$BAUDBOT_HOME/.varlock/config.json"; then
warn "$BAUDBOT_HOME/.varlock/config.json includes anonymousId (export VARLOCK_TELEMETRY_DISABLED=1 or remove this field)"
elif [ -f "$BAUDBOT_HOME/.config/varlock/config.json" ] && grep -q '"anonymousId"' "$BAUDBOT_HOME/.config/varlock/config.json"; then
warn "$BAUDBOT_HOME/.config/varlock/config.json includes anonymousId (export VARLOCK_TELEMETRY_DISABLED=1 or remove this field)"
if [ -f "$BAUDBOT_HOME/.varlock/config.json" ] && grep -q '"anonymousId"' "$BAUDBOT_HOME/.varlock/config.json"; then
warn "$BAUDBOT_HOME/.varlock/config.json includes anonymousId (export VARLOCK_TELEMETRY_DISABLED=1 or remove this field)"
fi
if [ -f "$BAUDBOT_HOME/.config/varlock/config.json" ] && grep -q '"anonymousId"' "$BAUDBOT_HOME/.config/varlock/config.json"; then
warn "$BAUDBOT_HOME/.config/varlock/config.json includes anonymousId (export VARLOCK_TELEMETRY_DISABLED=1 or remove this field)"
fi
Prompt To Fix With AI
This is a comment left during a code review.
Path: bin/doctor.sh
Line: 85-88

Comment:
**`elif` silences telemetry warning for new config path when legacy config also matches**

Because the new config-path check is behind an `elif`, if `~/.varlock/config.json` exists **and** contains `anonymousId`, the check for `~/.config/varlock/config.json` is never reached — even if that file also contains `anonymousId`. On systems where both config files are present (e.g., migrated installs), the new-path telemetry issue would go undetected.

Use two independent `if` blocks so both paths are always checked:

```suggestion
  if [ -f "$BAUDBOT_HOME/.varlock/config.json" ] && grep -q '"anonymousId"' "$BAUDBOT_HOME/.varlock/config.json"; then
    warn "$BAUDBOT_HOME/.varlock/config.json includes anonymousId (export VARLOCK_TELEMETRY_DISABLED=1 or remove this field)"
  fi
  if [ -f "$BAUDBOT_HOME/.config/varlock/config.json" ] && grep -q '"anonymousId"' "$BAUDBOT_HOME/.config/varlock/config.json"; then
    warn "$BAUDBOT_HOME/.config/varlock/config.json includes anonymousId (export VARLOCK_TELEMETRY_DISABLED=1 or remove this field)"
  fi
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch. Fixed in d666663.

I changed the telemetry checks in bin/doctor.sh to use two independent if blocks, so both legacy (~/.varlock/config.json) and current (~/.config/varlock/config.json) paths are checked even when both exist.

Responded by baudbot-dev-agent using openai/gpt-5.

setup.sh Outdated
Comment on lines +264 to +265
if [ -x "$AGENT_VARLOCK_CONFIG_BIN" ]; then
sudo -u baudbot_agent bash -c "mkdir -p '$BAUDBOT_HOME/.varlock/bin' && ln -sf '$AGENT_VARLOCK_CONFIG_BIN' '$AGENT_VARLOCK'"
Copy link

Choose a reason for hiding this comment

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

P2 ln -sf silently overwrites a real binary when both install locations coexist

If ~/.varlock/bin/varlock already exists as a real (non-symlink) binary — e.g., a legacy install — and ~/.config/varlock/bin/varlock also exists, ln -sf will silently delete the real binary and replace it with a symlink. While the symlink points to an equally valid binary, this is a destructive and potentially surprising operation on re-runs of setup.sh.

Consider guarding with a check that skips the symlink creation if the legacy path already contains a functional binary that is not a symlink:

if [ -x "$AGENT_VARLOCK_CONFIG_BIN" ] && [ ! -x "$AGENT_VARLOCK" ]; then
  sudo -u baudbot_agent bash -c "mkdir -p '$BAUDBOT_HOME/.varlock/bin' && ln -sf '$AGENT_VARLOCK_CONFIG_BIN' '$AGENT_VARLOCK'"
fi

This creates the compatibility link only when the legacy path is absent, avoiding accidental replacement of an existing real binary.

Prompt To Fix With AI
This is a comment left during a code review.
Path: setup.sh
Line: 264-265

Comment:
**`ln -sf` silently overwrites a real binary when both install locations coexist**

If `~/.varlock/bin/varlock` already exists as a real (non-symlink) binary — e.g., a legacy install — and `~/.config/varlock/bin/varlock` also exists, `ln -sf` will silently delete the real binary and replace it with a symlink. While the symlink points to an equally valid binary, this is a destructive and potentially surprising operation on re-runs of `setup.sh`.

Consider guarding with a check that skips the symlink creation if the legacy path already contains a functional binary that is not a symlink:

```bash
if [ -x "$AGENT_VARLOCK_CONFIG_BIN" ] && [ ! -x "$AGENT_VARLOCK" ]; then
  sudo -u baudbot_agent bash -c "mkdir -p '$BAUDBOT_HOME/.varlock/bin' && ln -sf '$AGENT_VARLOCK_CONFIG_BIN' '$AGENT_VARLOCK'"
fi
```

This creates the compatibility link only when the legacy path is absent, avoiding accidental replacement of an existing real binary.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. Fixed in d666663.

setup.sh now preserves an existing real legacy binary at ~/.varlock/bin/varlock and only creates/updates the compatibility symlink when the legacy path is absent or already a symlink.

Responded by baudbot-dev-agent using openai/gpt-5.

@benvinegar benvinegar merged commit f4c316c into main Mar 17, 2026
9 checks passed
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