Skip to content

install.sh --update silently updates whichever install sorts first, and reports success #599

Description

@fujibee

./install.sh --update without --cmd picks the first skill directory the glob yields, and reports success either way. On a machine with more than one agmsg install, that is not the one you meant, and nothing in the output says so.

What happened

Updating a live install from 1.1.12 to 1.1.13:

$ ./install.sh --update
  Updating agmsg-dfr...
  + refreshed Codex monitor shim (~/.agents/bin/codex)
  + updated scripts, templates, and SKILL.md (version v1.1.13)
  ✓ Update complete

$ cat ~/.agents/skills/agmsg/VERSION
1.1.12

The intended install was untouched. The command exited 0 and printed Update complete.

Why

SKILL_DIR=""
for d in "$AGENTS_DIR"/skills/*/; do
  if [ -f "${d}.agmsg" ]; then
    SKILL_DIR="${d%/}"
    break
  fi
done

The comment above it reads "otherwise preserve the historical 'first installed agmsg skill' behavior" — but a glob is expanded in collation order, not installation order, and nothing records which install came first. With agmsg/ and agmsg-dfr/ both present, the paths compare at the sixth character: - (0x2D) sorts before / (0x2F), so agmsg-dfr/ wins. Rename the second install to agmsg-zz and the same command would update the other one.

So the selection is neither "first installed" nor stable — it depends on the names.

Why it is worth fixing rather than documenting

The failure is silent in both directions. The skill you meant to update stays on the old version, and a different install is modified without being asked. --update also refreshes the shared ~/.agents/bin/codex shim (see #553), so a run aimed at one install can move a resource the other one shares.

An operator who does not check VERSION afterwards has no signal at all — the output names the directory it chose, but reads as confirmation rather than as a decision the caller might disagree with.

Suggested shape

Two options, either of which closes it:

  • Refuse to guess when there is more than one. If the loop finds a second .agmsg directory, stop and list them: several agmsg installs found (agmsg, agmsg-dfr) — pass --cmd <name>. A single install keeps working exactly as today, which is the common case.
  • Update all of them, printing each. Also unambiguous, though it makes one command touch installs the caller may not have had in mind.

The first is the smaller change and keeps the blast radius where the caller put it. Whichever is chosen, the "historical first installed" comment should go — it describes an ordering the code cannot observe.

Workaround

./install.sh --update --cmd <name> targets exactly one install and errors if it is not there. That path is already correct.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions