Skip to content

feat(installer): brand the curl|sh run with a mark, table, and card - #1122

Merged
norrietaylor merged 3 commits into
mainfrom
inbox-patch/installer-getting-started-hint-b25f03a06e45dc06
Jul 31, 2026
Merged

feat(installer): brand the curl|sh run with a mark, table, and card#1122
norrietaylor merged 3 commits into
mainfrom
inbox-patch/installer-getting-started-hint-b25f03a06e45dc06

Conversation

@gominimal-aw-bot

@gominimal-aw-bot gominimal-aw-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Routing-Key: inbox-route/I_kwDOSUhdos8AAAABK5q94Q

curl … | sh is the product's first impression, and it read like a bookkeeping log: ragged component: verb lines, a successful run ending on the path of its own install record, and nothing anywhere that looked like Minimal.

This started as a getting-started hint on the last line (the original commit on this branch) and grew into the presentation layer that hint belonged to.

What the run looks like now

A first install opens with the mark — character-for-character the one in the README's session demo (docs/public/loadout-demo.cast) — then an aligned component table, then a closing card:

     ████  ████▄
  ▄▄▄ ▀███▄ ▀███▄
  ▀███  ▀███  ▀███

  minimal · Build Software You Can Trust

▸ target 'stable' → 0.7.3

  minimal            installed    4.0 MB
  minvmd             installed    9.3 MB
  libkrun            current
  git-remote-min     linked       → min
  completions        installed    bash zsh fish
  shell-init         added        ~/.zshrc

  8 installed · 0 current · 6s
  record: ~/.local/state/minimal/installed

  Minimal 0.7.3 is ready.

  ▸ min init                          declare this project's environment
  ▸ min session activate --attach .   build the sandbox and step inside

  docs.minimal.dev   ·   discord.com/invite/qgX8sm6X7G
  • Degradation first. Bold/dim and the in-place row rewrite require stderr to be a terminal, NO_COLOR unset, and TERM != dumb; UTF-8 glyphs require a UTF-8 locale, independently of that. MINIMAL_INSTALL_PLAIN=1 forces both off. A redirected run emits no escape byte at all, which is what keeps CI logs and any future output parsing clean — and the one property here worth a regression test.
  • One row per component, rewritten in place on a terminal so a slow download narrates itself and still leaves exactly one line behind; two ordinary lines in a log. Anything printing mid-row closes it first, so the active-sessions prompt and fatal errors never land mid-line. Uninstall prints the same table (no mark, no card).
  • The mark on a first install only — no prior install record. A mark in a log file, or on the fifth rerun of the week, is litter.
  • The card is the last output of every successful install, superseding this branch's earlier hint. When the bin dir is not yet on PATH it carries that advisory inside the card, above the commands, because those commands would not resolve in this shell otherwise. No card on failure, none in uninstall mode.

Monochrome throughout — attributes, never color — matching the CLI's prompt theme (crates/minimal/src/theme.rs) and the website.

Spec

The layer is recorded as Unit 10 of 07-spec-installer. Its one contract is the degradation rule (R10.1); R10.2–R10.4 record the shape the implementation takes so a rewrite does not have to rediscover it. The terminal-only behaviors are marked not automated — the harness always redirects and cannot reach them, so they are verified by eye against a mock bucket, not by CI.

The same pass drops the R-number citations from install.sh. The spec is where those numbers belong; in code they rot silently, and this PR's own diff is the proof (the old Unit N: section headers no longer matched the units they named).

Verification

  • install_test.sh270 passed / 0 failed, under both sh and dash. Gains: the card closes a fresh install, an up-to-date rerun, and a run whose last note is the AppArmor advisory; no card on a failed install; no ESC byte in redirected output. Four existing assertions were retargeted from the old component: verb wording to the table layout.
  • shellcheck --shell=sh clean on install.sh and install_test.sh; just lint-shell — 26/26.
  • cargo test -p common --locked — 46 passed / 0 failed, including shell_lint::all_scripts_pass_shellcheck and installer_stop_signal.
  • Terminal rendering checked by eye against a mock bucket across seven scenarios: fresh install, upgrade, bin-dir-not-on-PATH, MINIMAL_INSTALL_PLAIN=1, piped-to-cat, an upgrade interrupted by the live-sessions prompt (the mid-row case), and uninstall.

Note

Routing-Key: inbox-route/I_kwDOSUhdos8AAAABK5q94Q

curl … | sh is the product's first impression, and it read like a bookkeeping log: ragged component: verb lines, a successful run ending on the path of its own install record, and nothing anywhere that looked like Minimal.

This started as a getting-started hint on the last line (the original commit on this branch) and grew into the presentation layer that hint belonged to.

What the run looks like now

A first install opens with the mark — character-for-character the one in the README's session demo (docs/public/loadout-demo.cast) — then an aligned component table, then a closing card:

     ████  ████▄
  ▄▄▄ ▀███▄ ▀███▄
  ▀███  ▀███  ▀███

  minimal · Build Software You Can Trust

▸ target 'stable' → 0.7.3

  minimal            installed    4.0 MB
  minvmd             installed    9.3 MB
  libkrun            current
  git-remote-min     linked       → min
  completions        installed    bash zsh fish
  shell-init         added        ~/.zshrc

  8 installed · 0 current · 6s
  record: ~/.local/state/minimal/installed

  Minimal 0.7.3 is ready.

  ▸ min init                          declare this project's environment
  ▸ min session activate --attach .   build the sandbox and step inside

  docs.minimal.dev   ·   discord.com/invite/qgX8sm6X7G
  • Degradation first. Bold/dim and the in-place row rewrite require stderr to be a terminal, NO_COLOR unset, and TERM != dumb; UTF-8 glyphs require a UTF-8 locale, independently of that. MINIMAL_INSTALL_PLAIN=1 forces both off. A redirected run emits no escape byte at all, which is what keeps CI logs and any future output parsing clean — and the one property here worth a regression test.
  • One row per component, rewritten in place on a terminal so a slow download narrates itself and still leaves exactly one line behind; two ordinary lines in a log. Anything printing mid-row closes it first, so the active-sessions prompt and fatal errors never land mid-line. Uninstall prints the same table (no mark, no card).
  • The mark on a first install only — no prior install record. A mark in a log file, or on the fifth rerun of the week, is litter.
  • The card is the last output of every successful install, superseding this branch's earlier hint. When the bin dir is not yet on PATH it carries that advisory inside the card, above the commands, because those commands would not resolve in this shell otherwise. No card on failure, none in uninstall mode.

Monochrome throughout — attributes, never color — matching the CLI's prompt theme (crates/minimal/src/theme.rs) and the website.

Spec

The layer is recorded as Unit 10 of 07-spec-installer. Its one contract is the degradation rule (R10.1); R10.2–R10.4 record the shape the implementation takes so a rewrite does not have to rediscover it. The terminal-only behaviors are marked not automated — the harness always redirects and cannot reach them, so they are verified by eye against a mock bucket, not by CI.

The same pass drops the R-number citations from install.sh. The spec is where those numbers belong; in code they rot silently, and this PR's own diff is the proof (the old Unit N: section headers no longer matched the units they named).

Verification

  • install_test.sh270 passed / 0 failed, under both sh and dash. Gains: the card closes a fresh install, an up-to-date rerun, and a run whose last note is the AppArmor advisory; no card on a failed install; no ESC byte in redirected output. Four existing assertions were retargeted from the old component: verb wording to the table layout.
  • shellcheck --shell=sh clean on install.sh and install_test.sh; just lint-shell — 26/26.
  • cargo test -p common --locked — 46 passed / 0 failed, including shell_lint::all_scripts_pass_shellcheck and installer_stop_signal.
  • Terminal rendering checked by eye against a mock bucket across seven scenarios: fresh install, upgrade, bin-dir-not-on-PATH, MINIMAL_INSTALL_PLAIN=1, piped-to-cat, an upgrade interrupted by the live-sessions prompt (the mid-row case), and uninstall.

Changes since #1122 opened

  • Added terminal-aware presentation system with attribute and glyph detection, row-based output formatting, wordmark display, and closing card [6a38bf7]
  • Converted all installer output to row-based table format with human-readable formatting [6a38bf7]
  • Added human_size utility function to format byte counts and tilde utility to display HOME-relative paths [6a38bf7]
  • Added first-run detection and elapsed time tracking [6a38bf7]
  • Updated test assertions to verify closing card presence, position, escape-free redirected output, and new row-formatted messages [6a38bf7]
  • Modified do_uninstall shell function to retain the install record when shell-init blocks cannot be stripped or files remain [bebbfb5]
  • Added tests validating uninstall record retention behavior when shell-init blocks survive [bebbfb5]
  • Added TERM=xterm-256color to test environment in run helper function [bebbfb5]
  • Clarified NO_COLOR environment variable handling to align with no-color.org convention [bebbfb5]
  • Clarified UTF-8 degradation behavior for presentation mark output [bebbfb5]

Summary by CodeRabbit

  • New Features

    • Added a clearer, terminal-aware installer experience with progress rows, status indicators, version details, elapsed time, and improved path display.
    • Added first-install branding and a closing readiness card with the initial min command after successful installation.
    • Improved uninstall reporting, dry-run messaging, completion cleanup, and protection for modified or externally managed files.
  • Bug Fixes

    • Simplified redirected output by removing terminal escape sequences.
    • Improved handling of failed installations and uninstall operations.

A successful install ended on whichever bookkeeping message fired
last — the install-record summary, the shell-init note, the PATH
advisory, or the AppArmor advisory — none of which tells a new user
what to do next.

Emit a getting-started block as the final stderr output of every
successful run, after all existing notes, naming the first command to
run. Failure and uninstall/dry-run paths are unchanged.

Add harness assertions that the hint is the last line on a fresh
install and on an up-to-date rerun, that it follows the AppArmor
advisory, and that it is absent when an install fails.
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5d939e68-d795-4ce6-ac40-fc9935486b2f

📥 Commits

Reviewing files that changed from the base of the PR and between 6a38bf7 and bebbfb5.

📒 Files selected for processing (3)
  • docs/specs/07-spec-installer/07-spec-installer.md
  • scripts/install.sh
  • scripts/install_test.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/specs/07-spec-installer/07-spec-installer.md
  • scripts/install_test.sh

📝 Walkthrough

Walkthrough

The installer now uses terminal-aware progress presentation, structured install and uninstall output, first-install branding, receipts, and a successful-install closing card. Specifications and tests cover redirected output, card placement, failed installs, and uninstall recovery.

Changes

Installer presentation and lifecycle

Layer / File(s) Summary
Presentation contract and terminal output
docs/specs/07-spec-installer/07-spec-installer.md, scripts/install.sh
Unit 10 defines presentation requirements. The installer detects terminal capabilities, selects fallbacks, renders progress rows, formats sizes and paths, prints first-install branding, and records timing state.
Uninstall dispatch and component reporting
scripts/install.sh
Uninstall runs before target and manifest processing. Component outcomes use structured rows. Modified and foreign records remain preserved. Dry-run handling, cache removal, directory pruning, and final summaries are reported.
Install resolution and component processing
scripts/install.sh
Install processing retains validation, daemon handling, atomic replacement, checksum checks, and cleanup. Component stages use progress rows and human-readable file sizes.
Shell integration, receipt, closing card, and tests
scripts/install.sh, scripts/install_test.sh, docs/specs/07-spec-installer/07-spec-installer.md
Completion and shell-hook changes use progress rows. The installer prints a receipt and final readiness card. Tests verify card placement, redirected output without escapes, failure omission, uninstall recovery, and revised wording.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Installer
  participant Terminal
  participant InstallRecord
  participant ShellIntegration
  Installer->>Terminal: render component progress rows
  Installer->>InstallRecord: persist install records
  Installer->>ShellIntegration: generate completions and update shell hooks
  Installer->>Terminal: print receipt and closing card
Loading

Possibly related PRs

  • gominimal/minimal#988: Modifies the same installer and test files for component progress, uninstall handling, and output assertions.
  • gominimal/minimal#1009: Extends completion installation and zsh completion-cache cleanup.

Suggested reviewers: twitchyliquid64, norrietaylor

Poem

The rabbit checks each progress row,

And watches tidy paths below.
A min command rests in sight,
The closing card ends the night.
No escape codes hop in tow.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the installer presentation changes and follows the required Conventional Commit format.
Description check ✅ Passed The description clearly covers the implementation, behavior, specification updates, and verification results, although it omits the template's explicit Checklist section.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch inbox-patch/installer-getting-started-hint-b25f03a06e45dc06

Comment @coderabbitai help to get the list of available commands.

@norrietaylor
norrietaylor marked this pull request as ready for review July 31, 2026 05:38
@norrietaylor
norrietaylor requested a review from a team as a code owner July 31, 2026 05:38
The installer is the product's first impression and read like a
bookkeeping log: ragged `component: verb` lines, a successful run ending
on the path of its own install record, and nothing anywhere that looked
like Minimal.

Add a presentation layer to install.sh:

- Degradation first. Bold/dim and the in-place row rewrite need stderr to
  be a terminal, NO_COLOR unset, and TERM != dumb; UTF-8 glyphs need a
  UTF-8 locale, independently of that. MINIMAL_INSTALL_PLAIN=1 forces
  both off. A redirected run therefore emits no escape byte at all, which
  is what keeps CI logs and any future output parsing clean.
- One aligned row per component (name, verb, size or path), rewritten in
  place on a terminal so a slow download narrates itself and still leaves
  exactly one line behind. Anything printing mid-row closes it first, so
  the active-sessions prompt and fatal errors never land mid-line.
  Uninstall prints the same table.
- The mark, on a first install only: character-for-character the one in
  the README's session demo (docs/public/loadout-demo.cast).
- A closing card as the last output of every successful install,
  superseding this branch's earlier getting-started hint. It names the
  first two commands and carries the PATH advisory inside it when the bin
  dir is not yet on PATH, since those commands would not resolve in this
  shell otherwise.

Monochrome throughout — attributes, never color — like the CLI's prompt
theme and the website.

Record the layer as Unit 10 of 07-spec-installer. Its one contract is the
degradation rule (R10.1); the terminal-only behaviors are marked
not-automated, because the harness always redirects and cannot reach
them. Drop the R-number citations from install.sh in the same pass: the
spec is where those numbers belong, and in code they rot silently.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@norrietaylor norrietaylor changed the title fix: end a successful install with a getting-started hint feat(installer): brand the curl|sh run with a mark, table, and card Jul 31, 2026
@norrietaylor
norrietaylor enabled auto-merge (squash) July 31, 2026 07:09
@norrietaylor
norrietaylor disabled auto-merge July 31, 2026 07:09

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/install.sh (1)

527-547: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Retain the install record until shell teardown completes.

Line 536 removes $record before strip_rc_block runs. If a later rc-file rewrite fails or the process stops, the marker block remains. A later --uninstall exits at lines 441-444 because the record is gone, so it cannot retry cleanup.

Move record deletion after shell teardown. Retain the record when any shell block remains unremoved.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/install.sh` around lines 527 - 547, Move the non-dry-run rm -f
"$record" operation from the pre-teardown conditional to after the
strip_rc_block loop. Track whether any rc-file marker block remains unremoved,
and retain the install record with an appropriate message when teardown fails;
only delete it after all shell cleanup succeeds, while preserving kept-entry and
dry-run behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/install_test.sh`:
- Around line 342-345: Update the redirected-output assertion around want_err to
invoke run with TERM=xterm-256color set, while keeping stderr redirected to OUT
and preserving the requirement that it contains no terminal escape bytes.

In `@scripts/install.sh`:
- Around line 84-90: Update the attribute-enabling condition in the
MINIMAL_INSTALL_PLAIN setup so NO_COLOR must be unset, not merely an empty
string; replace the current -z check with the appropriate variable-presence
check while preserving the existing terminal and TERM guards.
- Around line 165-175: Update wordmark so it returns immediately when glyph is
0, preventing the minimal branding line from rendering without UTF-8 glyph
support; retain the existing attr guard and full branding output when glyph is
enabled.

---

Outside diff comments:
In `@scripts/install.sh`:
- Around line 527-547: Move the non-dry-run rm -f "$record" operation from the
pre-teardown conditional to after the strip_rc_block loop. Track whether any
rc-file marker block remains unremoved, and retain the install record with an
appropriate message when teardown fails; only delete it after all shell cleanup
succeeds, while preserving kept-entry and dry-run behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 24bfc443-49c6-4730-bbb7-d4aad637c635

📥 Commits

Reviewing files that changed from the base of the PR and between f7dc233 and 6a38bf7.

📒 Files selected for processing (3)
  • docs/specs/07-spec-installer/07-spec-installer.md
  • scripts/install.sh
  • scripts/install_test.sh

Comment thread scripts/install_test.sh
Comment thread scripts/install.sh
Comment on lines +84 to +90
if [ -z "${MINIMAL_INSTALL_PLAIN:-}" ]; then
if [ -t 2 ] && [ -z "${NO_COLOR:-}" ] && [ "${TERM:-dumb}" != dumb ]; then
attr=1
fi
case "${LC_ALL:-${LC_CTYPE:-${LANG:-}}}" in
*UTF-8*|*utf-8*|*UTF8*|*utf8*) glyph=1 ;;
esac

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Disable attributes when NO_COLOR is set.

R10.1 requires NO_COLOR to be unset. The current -z check enables SGR attributes when the caller sets NO_COLOR=''.

Proposed fix
-if [ -z "${MINIMAL_INSTALL_PLAIN:-}" ]; then
-    if [ -t 2 ] && [ -z "${NO_COLOR:-}" ] && [ "${TERM:-dumb}" != dumb ]; then
+if [ -z "${MINIMAL_INSTALL_PLAIN:-}" ]; then
+    if [ -t 2 ] && [ "${NO_COLOR+x}" != x ] && [ "${TERM:-dumb}" != dumb ]; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [ -z "${MINIMAL_INSTALL_PLAIN:-}" ]; then
if [ -t 2 ] && [ -z "${NO_COLOR:-}" ] && [ "${TERM:-dumb}" != dumb ]; then
attr=1
fi
case "${LC_ALL:-${LC_CTYPE:-${LANG:-}}}" in
*UTF-8*|*utf-8*|*UTF8*|*utf8*) glyph=1 ;;
esac
if [ -z "${MINIMAL_INSTALL_PLAIN:-}" ]; then
if [ -t 2 ] && [ "${NO_COLOR+x}" != x ] && [ "${TERM:-dumb}" != dumb ]; then
attr=1
fi
case "${LC_ALL:-${LC_CTYPE:-${LANG:-}}}" in
*UTF-8*|*utf-8*|*UTF8*|*utf8*) glyph=1 ;;
esac
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/install.sh` around lines 84 - 90, Update the attribute-enabling
condition in the MINIMAL_INSTALL_PLAIN setup so NO_COLOR must be unset, not
merely an empty string; replace the current -z check with the appropriate
variable-presence check while preserving the existing terminal and TERM guards.

Comment thread scripts/install.sh
Comment on lines +165 to +175
wordmark() {
[ "$attr" -eq 1 ] || return 0
printf '\n' >&2
if [ "$glyph" -eq 1 ]; then
printf '%s%s\n%s\n%s%s\n\n' "$b" \
' ████ ████▄' \
' ▄▄▄ ▀███▄ ▀███▄' \
' ▀███ ▀███ ▀███' "$rst" >&2
fi
printf ' %sminimal%s %s%s Build Software You Can Trust%s\n' \
"$b" "$rst" "$dim" "$sep" "$rst" >&2

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not render first-install branding without UTF-8 glyph support.

R10.3 requires the Minimal mark to be terminal-only and UTF-8-only. In an ASCII locale on a terminal, wordmark skips the block mark but still prints the minimal branding line.

Either return when glyph=0, or change R10.3 to specify this fallback.

Proposed fix
 wordmark() {
-    [ "$attr" -eq 1 ] || return 0
+    [ "$attr" -eq 1 ] && [ "$glyph" -eq 1 ] || return 0
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
wordmark() {
[ "$attr" -eq 1 ] || return 0
printf '\n' >&2
if [ "$glyph" -eq 1 ]; then
printf '%s%s\n%s\n%s%s\n\n' "$b" \
' ████ ████▄' \
' ▄▄▄ ▀███▄ ▀███▄' \
' ▀███ ▀███ ▀███' "$rst" >&2
fi
printf ' %sminimal%s %s%s Build Software You Can Trust%s\n' \
"$b" "$rst" "$dim" "$sep" "$rst" >&2
wordmark() {
[ "$attr" -eq 1 ] && [ "$glyph" -eq 1 ] || return 0
printf '\n' >&2
if [ "$glyph" -eq 1 ]; then
printf '%s%s\n%s\n%s%s\n\n' "$b" \
' ████ ████▄' \
' ▄▄▄ ▀███▄ ▀███▄' \
' ▀███ ▀███ ▀███' "$rst" >&2
fi
printf ' %sminimal%s %s%s Build Software You Can Trust%s\n' \
"$b" "$rst" "$dim" "$sep" "$rst" >&2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/install.sh` around lines 165 - 175, Update wordmark so it returns
immediately when glyph is 0, preventing the minimal branding line from rendering
without UTF-8 glyph support; retain the existing attr guard and full branding
output when glyph is enabled.

Uninstall deleted the install record before stripping the marker-fenced
shell-init block from the rc files. `strip_rc_block` returns non-zero on an
unterminated block (the file is kept, block and all), and `do_uninstall`
treats a missing record as "nothing to undo" and returns 0 — so a run that
failed to strip the block left it uninstallable by any later run, with the
inventory needed to retry already gone.

Move the record teardown after the rc walk and the compinit-dump drop, and
track a surviving block in `kept_rc` so retention is announced the same way a
kept component already is.

Also from review:

- Set a terminal-like TERM in the test harness's `env -i`. The R10.1
  redirected-output assertion ran with TERM unset, so it passed on the TERM
  guard alone and would not have caught a regression that dropped the
  `[ -t 2 ]` check.
- Record the two presentation behaviours the spec stated more strictly than
  the implementation, both deliberate: NO_COLOR suppresses only when non-empty
  (no-color.org), and the mark's glyph block and its wordmark line degrade
  separately, so an ASCII-locale terminal opens on the wordmark alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@norrietaylor
norrietaylor enabled auto-merge (squash) July 31, 2026 07:34
@norrietaylor
norrietaylor merged commit fe391af into main Jul 31, 2026
32 checks passed
@norrietaylor
norrietaylor deleted the inbox-patch/installer-getting-started-hint-b25f03a06e45dc06 branch July 31, 2026 07:48
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