Skip to content

Keep setup usable when an optional tool installer fails - #3

Open
bmorelli25 wants to merge 1 commit into
mainfrom
fix/first-run-reliability
Open

Keep setup usable when an optional tool installer fails#3
bmorelli25 wants to merge 1 commit into
mainfrom
fix/first-run-reliability

Conversation

@bmorelli25

Copy link
Copy Markdown
Member

Why

Running elastic-docs-utils install --with-docs-tools on a machine where docs-builder installs to /usr/local/bin hit a sudo prompt it could not answer. The command aborted immediately, so skills and host adapters were never configured, even though nothing was wrong with them.

Investigating that also turned up three smaller reporting problems that made the failure hard to understand.

Changes

Optional tool failures no longer abandon the command. installOptionalTools now returns every failure rather than the first, and install and update warn, finish the rest of the work, then exit non-zero. Vale and docs-builder are explicitly opt-in, so their installers should not be able to prevent the setup those commands exist to perform.

not installed now says what to do about it. updates.Item already carried a Hint, but the only place it rendered was the session-start hook, gated on update available — never the state where a user needs it most. Hints now print beneath any non-current row in status and check-updates, and a component that was never requested points at its install --with-... option instead of an update command. This was the actual source of confusion: missing reads as a broken install rather than an opt-in tool.

--yes does something. It was parsed and immediately discarded (_ = yes) while being advertised in --help and the README. It now closes the installers' stdin so they cannot block on a prompt. It deliberately does not answer prompts, which stays --force's job, so existing configuration is left alone.

Rate limiting is reported instead of hidden. Every lookup returned "" on any error, so an exhausted GitHub quota was indistinguishable from an undetectable version and surfaced as a bare unknown. Lookups now return errors, say when the limit was hit, and send GITHUB_TOKEN or GH_TOKEN when set. The unauthenticated limit is 60 requests per hour per address, and each check spends five.

Version probes are harder to fool. binaryVersion used .Output(), so a tool that reports its version on stderr or logs before printing it read as not installed. It now parses combined output, prefers a line holding only a version over the first version-shaped string anywhere, and times out after 10s so a binary that starts a server cannot hang the command.

Test plan

  • go test ./..., go vet ./..., and gofmt -l . are clean
  • New unit tests cover the failure aggregation, hint rendering, installer input selection, version parsing, rate-limit detection, and token propagation
  • End-to-end against an isolated HOME with a forced docs-builder failure: setup continues, 18 skills install, adapters sync, hints render, and the command exits 1 with the cause
Installing documentation tools
[INFO] Installing docs-builder.
[WARN] install docs-builder: <simulated failure>
[WARN] Continuing with the rest of the setup. Re-run the installer for the tools above once the cause is resolved.
Synchronizing shared skills
[OK] Installed 18 managed skills.
...
[INFO] Vale: Not installed. Run `elastic-docs-utils install --with-vale`
[INFO] Elastic Docs skills: GitHub API rate limit reached; set GITHUB_TOKEN or retry later
[ERROR] 1 optional documentation tool installer(s) failed: install docs-builder: <simulated failure>

Notes for review

  • update passes assumeYes: false because it has no --yes flag; its interactive behavior is unchanged.
  • Item.State values are untouched, so the cached JSON contract and the hook's update available check still work.

Made with Cursor

A failing Vale or docs-builder installer aborted install before skills and
host adapters were configured, so a sudo prompt that could not be answered
left the command with nothing done. Both tools are optional, so report every
failure, finish the rest of the setup, and exit non-zero.

Status output could not distinguish a tool the user never asked for from one
that failed to install. Item hints already existed but only reached the
session-start hook, so print them beneath any row that is not current, and
point a component that was never requested at its install option.

Also make version reporting honest: --yes was parsed and discarded, version
lookups silently reported unknown when the shared 60-per-hour GitHub limit
was reached, and a tool that logged before printing its version was read as
not installed.

Co-authored-by: Cursor <cursoragent@cursor.com>
@bmorelli25
bmorelli25 requested a review from theletterf August 3, 2026 21:51
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