max / alloy
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+183 insertions,
-108 deletions
| @@ -1,129 +1,70 @@ | |||
| 1 | 1 | @{! variants = default, night } | |
| 2 | 2 | # Alloy starship configuration | |
| 3 | 3 | # | |
| 4 | - | # Cross-shell prompt per docs/STACK.md#shell. Two-line prompt: line | |
| 5 | - | # one for context (cwd + git + language versions), line two for the | |
| 6 | - | # entry glyph. Color reserved for state (git dirty, non-zero exit, | |
| 7 | - | # insert/normal mode) per DESIGN-LANGUAGE.md. | |
| 4 | + | # Cross-shell prompt per docs/STACK.md#shell. Two lines: context on the first, | |
| 5 | + | # the entry glyph alone on the second, so a typed command always starts at the | |
| 6 | + | # same column no matter how long the branch name or the path is. | |
| 8 | 7 | # | |
| 9 | - | # Palette drawn from docs/TOKENS.md hex values, mapped to starship's | |
| 10 | - | # color slots by function, not by name. | |
| 8 | + | # Palette drawn from docs/TOKENS.md, mapped to starship's color slots by | |
| 9 | + | # function rather than by name. Color is reserved for state per | |
| 10 | + | # DESIGN-LANGUAGE.md, which is why almost everything here is muted: the only | |
| 11 | + | # things that take a color are the ones saying something went wrong. | |
| 12 | + | # | |
| 13 | + | # THE RULE THIS FILE IS BUILT ON, stated 2026-08-14: every segment is a fact | |
| 14 | + | # somebody acts on, written as words rather than as pictures. | |
| 15 | + | # | |
| 16 | + | # What that ruled out, and why: | |
| 17 | + | # | |
| 18 | + | # - Nerd-font icons. A branch glyph in front of a branch name is the same fact | |
| 19 | + | # drawn twice, and it costs a font dependency to say it: shop has no font | |
| 20 | + | # fallback, so a glyph the font lacks draws as tofu rather than as nothing. | |
| 21 | + | # A prompt of words and ASCII cannot break that way. | |
| 22 | + | # - Language versions (rust, python, nodejs). Information, not useful | |
| 23 | + | # information. Inside a Rust repo it printed the toolchain version on every | |
| 24 | + | # line for a question nobody asks at the prompt, and `rustc -V` answers it | |
| 25 | + | # the moment they do. | |
| 26 | + | # | |
| 27 | + | # What it ruled in, all of them invisible until they are true: | |
| 28 | + | # | |
| 29 | + | # - The exit code as a number. A red glyph says a command failed; 1, 127, 130 | |
| 30 | + | # and 137 are four different next actions, and the glyph cannot tell them | |
| 31 | + | # apart. | |
| 32 | + | # - The container name. `alloy pkg` puts people inside distrobox, and a box | |
| 33 | + | # prompt was indistinguishable from the host. | |
| 34 | + | # - git_state. Mid-rebase is the most important thing on screen while it lasts. | |
| 11 | 35 | ||
| 12 | 36 | format = """ | |
| 13 | 37 | $username\ | |
| 14 | 38 | $hostname\ | |
| 39 | + | $container\ | |
| 15 | 40 | $directory\ | |
| 16 | 41 | $git_branch\ | |
| 42 | + | $git_state\ | |
| 17 | 43 | $git_status\ | |
| 18 | - | $python\ | |
| 19 | - | $rust\ | |
| 20 | - | $nodejs\ | |
| 21 | - | $cmd_duration\ | |
| 22 | 44 | $line_break\ | |
| 23 | 45 | $character""" | |
| 24 | 46 | ||
| 25 | - | right_format = """$time""" | |
| 47 | + | # The right prompt is a different subject from the left, and that is the whole | |
| 48 | + | # grouping mechanism: the left says where you are, the right says what just | |
| 49 | + | # happened. Exit code, duration and the time all belong to the command that | |
| 50 | + | # finished, so they sit together at the far end and nothing on the left has to | |
| 51 | + | # be separated from anything else by punctuation. | |
| 52 | + | right_format = """$status$cmd_duration$time""" | |
| 26 | 53 | ||
| 27 | - | add_newline = true | |
| 28 | - | ||
| 29 | - | # ------------------------------------------------------------------- | |
| 30 | - | # Entry glyph — the prompt character itself | |
| 31 | - | # ------------------------------------------------------------------- | |
| 32 | - | [character] | |
| 33 | - | success_symbol = "[▸](@{content.secondary})" # text-secondary | |
| 34 | - | error_symbol = "[▸](@{status.danger})" # accent-error on non-zero exit | |
| 35 | - | vimcmd_symbol = "[◂](@{status.success})" # accent-ok (normal mode) | |
| 36 | - | ||
| 37 | - | # ------------------------------------------------------------------- | |
| 38 | - | # Directory — truncated, primary text | |
| 39 | - | # ------------------------------------------------------------------- | |
| 40 | - | [directory] | |
| 41 | - | style = "bold @{content.primary}" # text-primary | |
| 42 | - | format = "[$path]($style)[$read_only]($read_only_style) " | |
| 43 | - | truncation_length = 4 | |
| 44 | - | truncation_symbol = "…/" | |
| 45 | - | truncate_to_repo = true | |
| 46 | - | read_only = " " | |
| 47 | - | read_only_style = "@{status.danger}" | |
| 54 | + | # No blank line between prompts. The second line is already the separator, and | |
| 55 | + | # a blank one on top of it spends a third of a three-line prompt on nothing. | |
| 56 | + | add_newline = false | |
| 48 | 57 | ||
| 49 | 58 | # ------------------------------------------------------------------- | |
| 50 | - | # Git — branch (secondary), status (accent-warn if dirty) | |
| 51 | - | # ------------------------------------------------------------------- | |
| 52 | - | [git_branch] | |
| 53 | - | symbol = " " | |
| 54 | - | style = "@{content.secondary}" # text-secondary | |
| 55 | - | format = "[$symbol$branch]($style) " | |
| 56 | - | ||
| 57 | - | [git_status] | |
| 58 | - | style = "@{status.warning}" # accent-warn | |
| 59 | - | format = "[$all_status$ahead_behind]($style) " | |
| 60 | - | conflicted = "=" | |
| 61 | - | ahead = "↑${count}" | |
| 62 | - | behind = "↓${count}" | |
| 63 | - | diverged = "↕${ahead_count}↓${behind_count}" | |
| 64 | - | untracked = "?" | |
| 65 | - | stashed = "$" | |
| 66 | - | modified = "!" | |
| 67 | - | staged = "+" | |
| 68 | - | renamed = "»" | |
| 69 | - | deleted = "✘" | |
| 70 | - | ||
| 71 | - | # ------------------------------------------------------------------- | |
| 72 | - | # Language versions — dim, only shown when relevant to cwd | |
| 73 | - | # ------------------------------------------------------------------- | |
| 74 | - | [python] | |
| 75 | - | symbol = " " | |
| 76 | - | style = "@{content.muted}" # text-muted | |
| 77 | - | format = "[$symbol$version]($style) " | |
| 78 | - | detect_extensions = ["py"] | |
| 79 | - | detect_files = ["pyproject.toml", "requirements.txt", "setup.py"] | |
| 80 | - | ||
| 81 | - | [rust] | |
| 82 | - | symbol = " " | |
| 83 | - | style = "@{content.muted}" | |
| 84 | - | format = "[$symbol$version]($style) " | |
| 85 | - | ||
| 86 | - | [nodejs] | |
| 87 | - | symbol = " " | |
| 88 | - | style = "@{content.muted}" | |
| 89 | - | format = "[$symbol$version]($style) " | |
| 90 | - | ||
| 91 | - | # ------------------------------------------------------------------- | |
| 92 | - | # Command duration — only for commands >2s | |
| 93 | - | # ------------------------------------------------------------------- | |
| 94 | - | [cmd_duration] | |
| 95 | - | min_time = 2000 | |
| 96 | - | style = "@{content.secondary}" | |
| 97 | - | format = "[$duration]($style) " | |
| 98 | - | show_milliseconds = false | |
| 99 | - | ||
| 100 | - | # ------------------------------------------------------------------- | |
| 101 | - | # Right-aligned clock — a readout, styled in text-muted so it reads as | |
| 102 | - | # metadata. Mono throughout: the two-font working/display split was | |
| 103 | - | # dropped in the 2026-07-17 pivot (docs/DESIGN-LANGUAGE.md#typography), | |
| 104 | - | # so a terminal segment in IosevkaTerm is the rule now, not a deviation. | |
| 105 | - | # ------------------------------------------------------------------- | |
| 106 | - | [time] | |
| 107 | - | disabled = false | |
| 108 | - | format = "[$time]($style)" | |
| 109 | - | time_format = "%H:%M" | |
| 110 | - | style = "@{content.muted}" | |
| 111 | - | ||
| 112 | - | # ------------------------------------------------------------------- | |
| 113 | - | # Who and where — the two facts a prompt is for | |
| 59 | + | # Who and where | |
| 114 | 60 | # ------------------------------------------------------------------- | |
| 115 | 61 | # Both were disabled here as "noise for Alloy's audience", on the reading that | |
| 116 | - | # a laptop user knows which machine they are sitting at. That reading did not | |
| 117 | - | # survive an installed test machine: fw12 and fw13 both show a bare `▸`, an | |
| 118 | - | # ssh session looks identical to a local one, and the first thing anyone needs | |
| 119 | - | # from a console on a box they just installed is which box it is. | |
| 62 | + | # a laptop user knows which machine they are sitting at. That did not survive | |
| 63 | + | # an installed test machine: two boxes gave the identical prompt and an ssh | |
| 64 | + | # session was indistinguishable from a local one. | |
| 120 | 65 | # | |
| 121 | - | # ssh_only stays off deliberately. Showing the host only over ssh means the | |
| 122 | - | # prompt is silent in exactly the case where a machine is new and unfamiliar, | |
| 123 | - | # and it makes two sessions that behave differently look the same. | |
| 124 | - | # | |
| 125 | - | # Muted, so they read as context rather than as the line's subject. The | |
| 126 | - | # directory stays the only bold thing here. | |
| 66 | + | # ssh_only stays off deliberately. Showing the host only over ssh keeps the | |
| 67 | + | # prompt silent in exactly the case where a machine is new and unfamiliar. | |
| 127 | 68 | [hostname] | |
| 128 | 69 | disabled = false | |
| 129 | 70 | ssh_only = false | |
| @@ -137,19 +78,153 @@ | |||
| 137 | 78 | # Not `style`. This module resolves `$style` to one of these two by who you | |
| 138 | 79 | # are, and a plain `style` key is silently ignored: starship warns and falls | |
| 139 | 80 | # back to its own bold yellow, which is off-palette and reads as a warning | |
| 140 | - | # about nothing. Caught by rendering the config and running `starship prompt` | |
| 141 | - | # against it, not by reading it. | |
| 81 | + | # about nothing. | |
| 142 | 82 | style_user = "@{content.muted}" | |
| 143 | 83 | # Root gets the danger color rather than the muted one. This is the one time | |
| 144 | 84 | # the prompt should be saying something about who you are. | |
| 145 | 85 | style_root = "@{status.danger}" | |
| 146 | 86 | ||
| 87 | + | # Which distrobox, blank on the host. No symbol: the name is the fact, and the | |
| 88 | + | # brackets are what make it read as an enclosure rather than as a word in the | |
| 89 | + | # path. | |
| 90 | + | [container] | |
| 91 | + | disabled = false | |
| 92 | + | format = "[\\[$name\\]]($style) " | |
| 93 | + | style = "@{status.warning}" | |
| 94 | + | ||
| 95 | + | # ------------------------------------------------------------------- | |
| 96 | + | # Directory — the one bold thing on the line | |
| 97 | + | # ------------------------------------------------------------------- | |
| 98 | + | [directory] | |
| 99 | + | style = "bold @{content.primary}" | |
| 100 | + | format = "[$path]($style)[$read_only]($read_only_style) " | |
| 101 | + | truncation_length = 4 | |
| 102 | + | truncation_symbol = "…/" | |
| 103 | + | truncate_to_repo = true | |
| 104 | + | # Was a nerd-font padlock. Two letters that are always in the font say it as | |
| 105 | + | # well and cannot arrive as tofu. | |
| 106 | + | read_only = " [ro]" | |
| 107 | + | read_only_style = "@{status.danger}" | |
| 108 | + | ||
| 109 | + | # ------------------------------------------------------------------- | |
| 110 | + | # Git — branch, then any operation in flight, then the working tree | |
| 111 | + | # ------------------------------------------------------------------- | |
| 112 | + | [git_branch] | |
| 113 | + | symbol = "" | |
| 114 | + | style = "@{content.secondary}" | |
| 115 | + | format = "[$branch]($style) " | |
| 116 | + | ||
| 117 | + | # Only ever on screen mid-operation, and then it is the thing that matters: | |
| 118 | + | # what you are in the middle of, and how far through. The parenthesised | |
| 119 | + | # progress is starship's optional syntax and collapses when there is none, so | |
| 120 | + | # a merge reads `merge` and a rebase reads `rebase 3/7`. | |
| 121 | + | [git_state] | |
| 122 | + | style = "@{status.warning}" | |
| 123 | + | format = "[$state( $progress_current/$progress_total)]($style) " | |
| 124 | + | ||
| 125 | + | # Count first, then a letter for what was counted: `2m 1u 3s 3a`. Reads as a | |
| 126 | + | # quantity with a unit, which is what it is. | |
| 127 | + | # | |
| 128 | + | # This replaced `!?+` with arrows, where the count was missing on the working | |
| 129 | + | # tree markers and present on the remote ones, nothing separated one marker | |
| 130 | + | # from the next, and `!` and `↑3` sat adjacent while being different kinds of | |
| 131 | + | # fact: one is your working tree, the other is your relationship to the remote. | |
| 132 | + | # `!↑3` was three characters that had to be learned rather than read. | |
| 133 | + | # | |
| 134 | + | # Each marker carries its own trailing space, because starship concatenates | |
| 135 | + | # these with no separator and `2m1u3s` is the run-together problem again. | |
| 136 | + | # | |
| 137 | + | # `st` for stashed rather than a second `s`, which staged already has. It is | |
| 138 | + | # the one marker here that is not about the working tree, and the extra letter | |
| 139 | + | # is cheaper than the collision. | |
| 140 | + | [git_status] | |
| 141 | + | style = "@{status.warning}" | |
| 142 | + | format = "[$all_status$ahead_behind]($style)" | |
| 143 | + | conflicted = "${count}c " | |
| 144 | + | ahead = "${count}a " | |
| 145 | + | behind = "${count}b " | |
| 146 | + | # Diverged needs no symbol of its own now: ahead and behind already have | |
| 147 | + | # letters, so it is just both of them. | |
| 148 | + | diverged = "${ahead_count}a ${behind_count}b " | |
| 149 | + | untracked = "${count}u " | |
| 150 | + | stashed = "${count}st " | |
| 151 | + | modified = "${count}m " | |
| 152 | + | staged = "${count}s " | |
| 153 | + | renamed = "${count}r " | |
| 154 | + | deleted = "${count}d " | |
| 155 | + | ||
| 156 | + | # ------------------------------------------------------------------- | |
| 157 | + | # The exit code, as a number | |
| 158 | + | # ------------------------------------------------------------------- | |
| 159 | + | # Disabled by default in starship, and the reason to turn it on is that the | |
| 160 | + | # entry glyph already carries this state as a color and a color cannot count. | |
| 161 | + | # 127 is a typo'd command, 130 is you pressing ctrl-c, 137 is the OOM killer. | |
| 162 | + | # Same red glyph, three unrelated problems. | |
| 163 | + | # | |
| 164 | + | # Silent on success: a prompt that printed 0 after every command would be | |
| 165 | + | # saying nothing, loudly. | |
| 166 | + | [status] | |
| 167 | + | disabled = false | |
| 168 | + | # Labelled. On the right-hand side, away from anything that gives it context, | |
| 169 | + | # a bare `130` is a number with no noun. `exit 130` costs five characters and | |
| 170 | + | # needs nothing learned. | |
| 171 | + | format = "[exit $status]($style) " | |
| 172 | + | style = "@{status.danger}" | |
| 173 | + | # The number, not a name for it. `map_symbol` would turn 130 into an interrupt | |
| 174 | + | # glyph, which is the picture-for-a-word trade this file exists to refuse. | |
| 175 | + | map_symbol = false | |
| 176 | + | pipestatus = false | |
| 177 | + | ||
| 178 | + | # ------------------------------------------------------------------- | |
| 179 | + | # Command duration — only for commands slow enough to have been noticed | |
| 180 | + | # ------------------------------------------------------------------- | |
| 181 | + | [cmd_duration] | |
| 182 | + | min_time = 2000 | |
| 183 | + | style = "@{content.secondary}" | |
| 184 | + | format = "[$duration]($style) " | |
| 185 | + | show_milliseconds = false | |
| 186 | + | ||
| 187 | + | # ------------------------------------------------------------------- | |
| 188 | + | # Entry glyph — the prompt character itself | |
| 189 | + | # ------------------------------------------------------------------- | |
| 190 | + | # Geometric shapes rather than nerd-font icons, so this survives a font with | |
| 191 | + | # no icon coverage. It keeps its color state even though the exit code is now | |
| 192 | + | # spelled out: the color is what you catch without reading. | |
| 193 | + | [character] | |
| 194 | + | success_symbol = "[▸](@{content.secondary})" | |
| 195 | + | error_symbol = "[▸](@{status.danger})" | |
| 196 | + | vimcmd_symbol = "[◂](@{status.success})" | |
| 197 | + | ||
| 198 | + | # ------------------------------------------------------------------- | |
| 199 | + | # Right-aligned clock — when the command in front of it ran | |
| 200 | + | # ------------------------------------------------------------------- | |
| 201 | + | # Kept even though the status bar is also a clock. The bar says what time it | |
| 202 | + | # is now; this says what time each command in the scrollback happened, which | |
| 203 | + | # is a different question and the only place it gets answered. | |
| 204 | + | [time] | |
| 205 | + | disabled = false | |
| 206 | + | format = "[$time]($style)" | |
| 207 | + | time_format = "%H:%M" | |
| 208 | + | style = "@{content.muted}" | |
| 209 | + | ||
| 147 | 210 | # ------------------------------------------------------------------- | |
| 148 | 211 | # Disabled modules — noise for Alloy's audience | |
| 149 | 212 | # ------------------------------------------------------------------- | |
| 213 | + | # The language modules are not merely absent from `format`; they are off, so | |
| 214 | + | # that adding a segment later is a deliberate act rather than something that | |
| 215 | + | # starts rendering because a module's default changed. | |
| 150 | 216 | [package] | |
| 151 | 217 | disabled = true | |
| 152 | 218 | ||
| 219 | + | [python] | |
| 220 | + | disabled = true | |
| 221 | + | ||
| 222 | + | [rust] | |
| 223 | + | disabled = true | |
| 224 | + | ||
| 225 | + | [nodejs] | |
| 226 | + | disabled = true | |
| 227 | + | ||
| 153 | 228 | [aws] | |
| 154 | 229 | disabled = true | |
| 155 | 230 |