feat(shell): name the shell after the name it was invoked as
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 0
- Forks
- 3
- Avg merge
- 8h 43m
- Merged PRs (30d)
- 60
Description
Problem Statement
A user who runs the shell under a different name — for example a ws symlink next to the wso2 executable — still gets every next step, recovery, usage line, and hint phrased as wso2 …. The suggested commands are not the ones they type, so copy-pasting a suggestion switches them back to the long name, and a demo or tutorial built around the short name shows output that contradicts itself.
Solution
The shell names itself after the name it was invoked as. Invoked as ws, every piece of shell-rendered prose that names a shell command says ws …; invoked as wso2, output is unchanged. There is no setting to configure: creating a symlink or a copy under another name is the whole configuration. This applies to table and JSON output alike, and to text that product modules return, since the shell renders all of it (ADR 0003).
User Stories
- As a CLI user who invokes the shell through a
wssymlink, I want next-step lines to sayws …, so that I can run the suggestion exactly as printed. - As a CLI user invoking
ws, I want error recoveries to sayws …, so that recovering from an error does not require translating the command. - As a CLI user invoking
ws, I want warning diagnostics' recoveries to namews, so that warnings and errors are consistent. - As a CLI user invoking
ws, I want the root usage line in help to readws <command> [arguments], so that help matches what I typed. - As a CLI user invoking
ws, I wantws doctorrecovery lines to namews, so that the checklist it prints is directly actionable. - As a CLI user invoking
ws, I want the "no contexts are configured" guidance to namews context applyandws context create, so that first-run onboarding uses my command. - As a CLI user invoking
ws, I want next steps returned by product modules (identity, api) to namews, so that product commands and shell commands read the same. - As a CLI user invoking
ws, I want recoveries in problems returned by product modules to namews, so that module failures are as actionable as shell failures. - As a script author running
ws … --output json, I want thenextand recovery members to carry the invoked name, so that the JSON document agrees with the human rendering. - As a CLI user invoking
wso2, I want output to be byte-for-byte what it is today, so that nothing I depend on changes. - As a CLI user invoking
ws, I want command highlighting (color or backticks) to still apply tows …spans, so that commands stand out as before. - As a CLI user invoking
ws, I want words such aswso2-cli,WSO2_HOME,WSO2 CLI, and paths containingwso2left alone, so that the rename touches only command invocations. - As a CLI user invoking
ws, I want result data — row values and field values that are not next steps — left untouched, so that a resource whose actual name containswso2is shown truthfully. - As a CLI user invoking
ws, I want tables to stay aligned, so that renaming does not shift columns. - As a CLI user on Windows invoking
ws.exe, I want output to sayws, notws.exe, so that suggestions are phrased the way commands are typed. - As a CLI user invoking the shell by an absolute or relative path, I want output to use only the base name, so that suggestions are not cluttered with my install location.
- As a CLI user whose terminal renders color, I want color detection to keep working, so that carrying the invoked name does not turn color off.
- As a module author, I want to keep writing
wso2 …in next steps and recoveries, so that modules need no SDK or protocol change to benefit. - As a shell contributor, I want to keep writing
wso2 …in shell messages, so that the source stays greppable and consistent. - As a shell contributor, I want a shell constructed without a name (as every existing test does) to render
wso2, so that existing golden output stays valid. - As a shell contributor, I want the process arguments read only in the executable's entry point, so that the existing boundary rule on process-global reads still holds.
- As a Jupyter notebook author driving the CLI as
ws, I want the printed suggestions to match my notebook cells, so that the demo is self-consistent.
Implementation Decisions
-
Invoked name. The shell gains a name field. The executable's entry point sets it from the base name of the first process argument, with a trailing
.exeremoved. An empty name meanswso2. The entry point stays the only reader of process arguments. -
Canonical source text. All shell and module text keeps saying
wso2. Renaming is a render-time concern, consistent with ADR 0003 (the shell owns output). -
The name travels with the writer. The output package gains a way to attach a name to a writer. The returned writer passes writes through unchanged and still exposes the underlying file descriptor, so terminal and color detection behave as before. The output package gains a way to read the name back from any writer, falling back to
wso2. At the start of a run, the shell attaches its name to both output streams when the name differs fromwso2. Every existing render call already receives those streams, so no call site changes signature. -
Rename rule. One rename function in the output package replaces a whitespace-delimited token that is exactly
wso2with the invoked name, but only when the next token reads as a command word. It reuses the command-span detection the hint renderer already uses. Substrings such aswso2-cli,WSO2_HOME,/wso2/, and uppercaseWSO2never match. A barewso2inside quotes (for example"wso2 help") matches. -
Where the rename applies. It applies to:
- problem and diagnostic rendering (message and recovery);
- the hint renderer, which also highlights
<name> …spans; - the next-step line;
- JSON rendering of result fields, where only the
nextfield's value is renamed; - module diagnostics lines;
- the root command's usage line.
Shell messages written straight to a stream with a literal
wso2 …, bypassing those renderers, are routed through the hint or rename function. -
What never gets renamed: table row values, result field values other than
next, and any other data values. -
Alignment. Any renamed text that ends up in a table cell is renamed before widths are computed.
-
No configuration surface. No preference key and no environment variable.
Testing Decisions
-
A good test drives external behavior only: construct a shell with in-memory streams and a name, run a command, and assert on the rendered output. Tests don't assert on private helpers.
-
Seam 1, shell run. Build the shell with the name
wsand buffer streams, then check:- the no-contexts guidance says
ws context apply; - an unknown command's recovery says
ws help; - the version usage error recovery says
ws version; - a JSON-mode report's
nextmember saysws; - the same scenarios without a name still say
wso2.
Prior art: the existing shell tests in the app package that build a shell with buffer streams.
- the no-contexts guidance says
-
Seam 2, rename function. Table-driven tests cover:
- a plain command;
- trailing punctuation;
- several commands in one sentence;
wso2followed by an English word (no match);wso2-cli,WSO2_HOME, and/dev/wso2/(no match);- the empty and default name, which leave the text unchanged;
- a hint highlight span that starts at the new name.
Prior art: the existing hint renderer tests.
-
The writer that carries the name is checked through seam 1 plus one assertion that it still reports a file descriptor when wrapping a file.
-
The entry point's argument parsing is a one-liner and gets no dedicated test.
Out of Scope
- Renaming the executable, the release artifacts, module executables, or the
cmd/wso2directory. - Documentation, README, and guide prose.
- Environment variable names (
WSO2_HOME,WSO2_NO_INPUT, …) and the state directory layout. - Shell completion script naming.
- A configuration key or environment variable to override the name.
- Any change to the module SDK or protocol.
Further Notes
- Motivation: a notebook demo drives the CLI through a
wssymlink, and the output kept suggestingwso2 …. - JSON output depending on the invoked name was chosen on purpose. Scripts that invoke the canonical
wso2name see no change.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the cmd/wso2 entry point and the output package, then review the existing shell tests in the app package and hint renderer tests. Construct a shell with buffer streams and the invoked name, and verify that rendered guidance, recoveries, hints, usage, JSON next fields, and table output use the base name while default output remains wso2.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 65/100