feat(desktop): add a coding agent once Codeman is installed

The agent chooser only appeared during the install, and only on a Mac with
no agent. After "Skip for now", or with Codeman already installed, there was
no screen for it.

The same chooser now works after the install: "Add a coding agent" on the
This Mac tab, "Add a Coding Agent to This Mac..." in the app menu (it also
works from a Codeman page), and after a Skip the app says Codeman has no
agent yet before it opens Codeman.

`install.sh agent <id>` installs one agent and nothing else. It checks that
THAT agent landed: install_offered_cli is fatal only when no CLI is left, so
with another one present a failed install would have reported success.

The app runs it as a run of its own (`gui_install::Run::Agent`), in its own
temporary folder, so `ps` never reads it as "Codeman is being installed". It
may run next to a live server, which an install must refuse, and stops only
for another run. `--no-admin` goes to both `preflight` and `agent`: it decides
what counts as installable, so the two must agree.

CI: the bash 3.2 preflight check never tested anything. Its child run
inherited CODEMAN_INSTALL_SH_LIB and stopped at the sourcing guard, and a
false [[ ]] does not trip set -e on bash 3.2. Both are fixed for that check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-11-06 13:23:56 +01:00
1 parent b51632e54b
commit dd07126dd8
12 files changed
+1016 -124

No files matched your search

+14 -4
View File
@@ -93,12 +93,22 @@ jobs:
done
offer_ai_cli_install >/dev/null 2>&1
echo "bash $BASH_VERSION: --ai-cli answers the menu, also with nothing to offer"
# What the desktop app runs: preflight on stdout, and only JSON there.
out=$(bash /w/install.sh preflight --no-admin)
[[ "$out" == "{\"schema\":1,"* && "$out" == *"]}" ]]
# What the desktop app runs: preflight on stdout, and only JSON there. These
# child runs must not inherit CODEMAN_INSTALL_SH_LIB, or they stop at the
# sourcing guard and print nothing. Each check ends in `|| exit 1`, because
# bash 3.2 does not let a false [[ ]] trip set -e.
out=$(env -u CODEMAN_INSTALL_SH_LIB bash /w/install.sh preflight --no-admin)
[[ "$out" == "{\"schema\":1,"* && "$out" == *"]}" ]] || { echo "preflight printed: $out"; exit 1; }
json_string "a\"b\\c" >/tmp/json-out
[[ "$(cat /tmp/json-out)" == "\"a\\\"b\\\\c\"" ]]
[[ "$(cat /tmp/json-out)" == "\"a\\\"b\\\\c\"" ]] || { echo "json_string printed: $(cat /tmp/json-out)"; exit 1; }
echo "bash $BASH_VERSION: preflight prints JSON"
# How the desktop app adds an agent: a real run of the subcommand, which stops
# on the missing npm before it could install anything.
if out=$(env -u CODEMAN_INSTALL_SH_LIB bash /w/install.sh agent codex --no-admin --progress 2>&1); then
echo "agent ran with no npm to run"; exit 1
fi
[[ "$out" == *"@@codeman phase agent"* && "$out" != *"@@codeman phase done"* ]] || { echo "agent printed: $out"; exit 1; }
echo "bash $BASH_VERSION: agent stops without saying done"
'
# Issue #382: the dsh identity probe builds an OPTIONAL `timeout` prefix as an
# array, and on stock macOS there is no `timeout`, so the array is empty and the