Skip to content

A tab still slugs the branch: branch_123 reads branch-123, and the case goes too #628

Description

@blooop

dl blooop/devlaunch@test/branc-title_123 names the tab
devlaunch@test/branc-title-123. The underscore is now a dash. feat/ABC_123
reads feat/abc-123, so the case goes as well. Measured against main at
0.50.0, by calling WorkspaceId::label directly:

test/branc-title_123 -> id devlaunch-test-branc-title-123-hx1w  label devlaunch@test/branc-title-123
        feat/ABC_123 -> id devlaunch-feat-abc-123-ktsk          label devlaunch@feat/abc-123

Why it happens

Nothing is filtering the title for safety. sanitize_title
(rust/devlaunch-core/src/flows/launch.rs) drops control characters, $, a
backtick and a backslash, and finds nothing to do on this path: a derived name
never holds any of them.

The reshaping is slug
(rust/devlaunch-core/src/domain/workspace_id.rs), which lowercases and
collapses every run of non-alphanumerics to one dash. That rule belongs to the
id, and the id has to obey it: it names a devpod workspace and it is the
container's hostname, so it has to be a DNS label. WorkspaceId::label is
defined as a rendering of the id rather than a second reading of the spec,
which is what keeps a tab matchable by eye against a dl --ls row, so it
inherits the id's alphabet wholesale.

Why that is worth revisiting

A tab is not a DNS label and not a devpod name. #626 made exactly this argument
for the / and put the branch's slashes back, and the same argument covers _,
. and the case: all of them are inert in every sink the label reaches. The OSC
2 escape is BEL-terminated, herdr tab rename takes the label as argv with no
shell, and the container's PS1 line is shell-quoted and re-expanded rather
than re-parsed, so only $, a backtick and a backslash would ever act, and
sanitize_title already drops those.

So #626 was a half-step. It restored one of the four things the id's alphabet
takes off a branch name and left the other three, on no principle that
distinguishes them.

The decision this needs

Not "stop filtering" but what a tab is a rendering of, decided once:

  1. The id, as today. The tab and a dl --ls row stay matchable character for
    character apart from the separators. feature/auth and Feature_auth keep
    reading alike, which is the same ambiguity Spell the branch's slashes in the name a tab reads #626 removed for slashes.
  2. The branch as typed, cut to the id's budget with the id's
    segment-dropping. A tab then says what you typed, and the price is that the
    readable half of a tab no longer matches the readable half of the id: a
    reader matching devlaunch@Feature_auth against
    devlaunch-feature-auth-3j1t has to know the slug rule to see they are one
    workspace.

Whichever wins, docs/workspaces.md's renderings table is where it is written
down, and the length budget, the dropped middle segments and the four-character
suffix are not in question either way.

Worth pinning in the same change: the label's alphabet is currently asserted in
a_label_holds_one_at_and_nothing_else_a_shell_or_a_terminal_reads
(workspace_id.rs), which would have to move with the decision, and
the_prompt_that_repaints_the_title_renders_it_as_text
(flows/provision.rs) is where a new character earns its keep by being rendered
through a real bash prompt.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions