Rename the public CyberOS CLI bin from `cyberos` to `cs`
TASK-IMP-130: Rename the public CyberOS CLI bin from cyberos to cs
Summary
The npm-published CyberOS CLI exposes itself as the bin command cyberos, which collides on $PATH with an unrelated internal tool that happens to already claim that name. This task renames the public bin to cs, updates every place the CLI describes its own invocation, and folds in a stale-domain fix discovered in the same files.
Problem
brew install --cask cyberos followed by brew trust installs the Homebrew-packaged CLI correctly, but running cyberos -h afterward showed an unrelated 39-subcommand BRAIN-store CLI instead of the Homebrew-installed one. Root cause, confirmed by direct repo inspection (docs/plans/PLAN-cli-module-namespacing-2026-07-22/plan.md §2): the npm-published @cyberskill/cyberos package (tools/install/build.sh:341-347) declares its bin as cyberos (tools/install/cli/bin/cli.mjs), and a completely separate, PyPI-unpublished internal package (modules/memory, cyberos-memory) independently declares a console-script entry also named cyberos (modules/memory/pyproject.toml:29). Whichever one lands later on $PATH (in the reported case, a local/dev pyenv install of modules/memory) wins, and there is no error — just the wrong tool answering to the name, silently.
cyberos-memory is confirmed internal-only with no plan to publish (plan §2), so it was never actually the thing that needed to change to solve the founder's goal, which is "the only public command is cs" (plan §4). Renaming the public bin directly delivers that and needs no coordination with the internal package's own naming.
Proposed Solution
Change the npm package's bin field (generated by build.sh:341-347) from { "cyberos": "cli/bin/cli.mjs" } to { "cs": "cli/bin/cli.mjs" }, keeping the package name @cyberskill/cyberos unchanged (see Alternatives Considered). Update every place the CLI's own text describes its invocation — cli.mjs's top comment and usage() output, help.sh's "Channels" section, the plugin's help.md, docs/index.md's "same eight commands" line, and the npx cyberos ... examples in tools/install/README.md — to read cs instead of cyberos. Add a CHANGELOG entry calling out the rename as breaking, per the plan's explicit instruction not to ship it as a silent swap (plan §7). While editing cli.mjs, help.sh, and help.md for the rename, also correct the stale domain string https://cyberos.cyberskill.world/docs found in all three to the canonical https://os.cyberskill.world/docs already in use elsewhere in the repo (e.g. README.md:7) since PR #107.
Alternatives Considered
- Rename the npm package name (
@cyberskill/cyberos→@cyberskill/csor similar) along with the bin. Rejected: npm allows a package's name to differ from the command(s) it installs (many published CLIs do this), and the package name is what appears innpm install <name>/ the registry URL /repository/homepagemetadata already tied to the OIDC trusted-publishing pipeline (plan §7 flags that pipeline as fragile — pinned to org+repo+workflow-filename trust). Renaming the package name changes more surface for zero user-facing benefit, since the thing a user types day to day is the bin command, not the package name. - Keep
cyberosas an alias alongsidecsduring a transition window. Rejected per the plan (§7): the founder explicitly rejected keepingcyberosas an alias, since an alias would leave the exact collision this task exists to remove. - Rename
modules/memory's console-script entry instead of the public bin (the original, since-superseded plan revision). Rejected: superseded same day by the founder directly (plan §9 revision log) once it was confirmedcyberos-memorywas never going to be published — renaming an internal-only tool to protect a name the public CLI was going to leave anyway solves nothing. - Leave the stale domain fix for a separate task. Rejected: all three instances are single-line strings inside files this task already opens for the rename; deferring them means a sixth reviewer touching the same three lines for an unrelated one-word change.
Success Metrics
- Primary: by the next CyberOS release after 1.0.9,
npx cs install,npx cs -h, and every subcommand incli.mjs'sSCRIPTStable resolve correctly, with zero remainingnpx cyberosor barecyberos <verb>references intools/install/{cli/bin/cli.mjs,help.sh,plugin/commands/help.md,docs/index.md,README.md}. Baseline today: all five files instruct the reader to typecyberos. - Guardrail: in that same release, the payload's
package.jsonnamefield remains@cyberskill/cyberos(unchanged), sonpm install @cyberskill/cyberoscontinues to resolve to the same package post-rename — only the invoked command changes, not the install target.
Scope
In scope: build.sh's package.json generation (bin field only — name stays), cli.mjs's dispatch/usage text, help.sh, the plugin's help.md, docs/index.md, the npx cyberos ... examples in tools/install/README.md, a CHANGELOG entry, and the three stale-domain instances found in the same files touched for the rename.
Out of scope / Non-Goals
- Renaming
modules/memory's own console-script entry (modules/memory/pyproject.toml:29) — confirmed internal-only, never needed for this collision, left untouched per the plan. - Renaming the npm package name
@cyberskill/cyberos— decided against; see Alternatives Considered. - Adding a
memoryorcuoverb to the renamed dispatch table — that is TASK-IMP-131 / TASK-IMP-132. - Updating
Formula/cyberos-cli.rbin the separatehomebrew-taprepo — that is TASK-IMP-133. - The end-to-end regression proving the rename works on a clean machine — that is TASK-IMP-134.
- Any pre-existing inconsistency in
tools/install/README.mdunrelated to thecyberos→csrename itself (e.g. lines 186-188 describenpx cyberos-gates/npx cyberos-mcpas if they were separate bin names, which does not matchcli.mjs's actual single-bin dispatch design) — flagged as a pre-existing documentation inconsistency, not introduced or fixed by this task.
Dependencies
None blocking — this is the root task the other four in this batch depend on. Touches the OIDC trusted-publishing pipeline in release.yml (plan §7): a bin-name change should go through the normal release flow and be re-tested end to end by TASK-IMP-134, not verified in isolation here.
Relationship to TASK-IMP-076 (done). That task shipped the original install/uninstall/version/status/help root CLI surface and the mcp/gates verbs inside cli.mjs — the exact dispatch table and usage text this task renames. It established the "three channels cannot drift" design (plugin slash commands, help.sh, cli.mjs mirror the same command set 1:1) that this task's doc sweep must preserve under the new name, not just the bin field itself.
AI Authorship Disclosure
- Tools used: Claude (Fable 5) running the CyberOS
task-authorskill inside Cowork. - Scope: every
source_pagesline above was read at HEAD in this checkout during authoring; the stale-domain finding inhelp.shandplugin/commands/help.md(beyond the singlecli.mjsinstance already surfaced to the operator in conversation) was discovered while gathering these citations, not asserted from memory. - Human review: task decomposition and scope approved at the 2026-07-22 PLAN gate (create-tasks). The package-name decision and the domain-fix scope addition are recorded above as authoring-time calls, not yet independently reviewed beyond that PLAN approval — flagged for the operator to revisit if either call is unwanted.
1. Description (normative)
- 1.1 The payload's generated
package.jsonMUST declare itsbinfield as{ "cs": "cli/bin/cli.mjs" }and MUST NOT change thenamefield from@cyberskill/cyberos. - 1.2
cli.mjs's top comment andusage()output MUST refer to the invocation ascs <command>(ornpx cs <command>), notcyberos <command>. - 1.3
help.sh's "Channels" section MUST describe the npm channel asnpx cs <command>, notnpx cyberos <command>. - 1.4 The plugin's
help.md,docs/index.md's "same eight commands" line, and everynpx cyberos ...example intools/install/README.mdMUST readcsin place ofcyberos. - 1.5 The domain string
https://cyberos.cyberskill.world/docsMUST be corrected tohttps://os.cyberskill.world/docsin every file this task modifies that contains it (cli.mjs,help.sh,plugin/commands/help.md). - 1.6
CHANGELOG.mdMUST gain an entry documenting the rename as a breaking change, naming the old (cyberos) and new (cs) command explicitly. - 1.7 This task MUST NOT modify
modules/memory/pyproject.toml's console-script entry.
2. Acceptance criteria
- [ ] AC 1 (traces_to: #1.1) - a scratch build's
dist/*/package.jsonhasbin: {"cs": "cli/bin/cli.mjs"}andname: "@cyberskill/cyberos"- test:tools/install/tests/test_cli_rename.sh::t01_bin_renamed_to_cs - [ ] AC 2 (traces_to: #1.2) -
node dist/*/cli/bin/cli.mjs --helpprints usage text containingcs <command>and contains no substringcyberos <command>- test:tools/install/tests/test_cli_rename.sh::t02_usage_text_says_cs - [ ] AC 3 (traces_to: #1.3) -
bash dist/*/help.shoutput containsnpx cs <command>and does not containnpx cyberos- test:tools/install/tests/test_cli_rename.sh::t03_help_sh_says_cs - [ ] AC 4 (traces_to: #1.4) - for each of
tools/install/plugin/commands/help.md,tools/install/docs/index.md, andtools/install/README.md'snpx cyberos install [dir]example line: the file now contains the replacementcs-based text (/help→ mentionscs;docs/index.md→npx cs <command>;README.md→npx cs install [dir]) AND a grep for the literal stringcyberos <command>across the three returns zero matches - test:tools/install/tests/test_cli_rename.sh::t04_docs_sweep_replaced_not_just_removed - [ ] AC 5 (traces_to: #1.5) - a grep of
cli.mjs,help.sh, andplugin/commands/help.mdforcyberos.cyberskill.worldreturns zero matches, and each now containsos.cyberskill.world/docs- test:tools/install/tests/test_cli_rename.sh::t05_stale_domain_fixed - [ ] AC 6 (traces_to: #1.6) -
CHANGELOG.md's top entry mentions bothcyberosandcsand the word "breaking" - test:tools/install/tests/test_cli_rename.sh::t06_changelog_entry_present - [ ] AC 7 (traces_to: #1.7) -
git difffor this change touches no file undermodules/memory/- test:tools/install/tests/test_cli_rename.sh::t07_memory_module_untouched
3. Edge cases
- A consumer repo that already ran
npx cyberos installbefore this ships has an installed.cyberos/machine with no dependency on the bin name (the machine itself never shells out tocyberos/csinternally) - re-running install under the new bin name MUST behave identically to a fresh install. bash dist/*/help.shandbash dist/*/install.sh(invoked directly, not through the npm bin) are unaffected by the bin rename - only the npm-published entry point's name changes, not the underlying shell scripts' own invocation.- A user who globally installed an earlier version of
@cyberskill/cyberos(bincyberos) and upgrades to the version carrying this rename: whether npm cleanly removes the now-undeclaredcyberosbin symlink or leaves it dangling is version/install-method dependent and NOT independently verified by this task - this is exactly the gap TASK-IMP-134's clean-machine end-to-end regression exists to observe directly, rather than this task asserting a specific npm bin-symlink behaviour it has not verified. Either outcome is the accepted breaking-change cost the plan (§7) already recorded; only the precise mechanics are unverified here. - The Grok/Claude plugin channel (
grok plugin install,claude plugin install cyberos@cyberos) is a separate name from the npm bin - the plugin identifiercyberos@cyberos(tools/install/README.md:121,123,136) is the Claude/Grok marketplace+plugin name, unaffected by this task; renaming it is out of scope and not implied by 1.1-1.6. - Security-class: this task only changes which string a package.json/shell script prints and which key an object uses; it grants no new filesystem or network capability and narrows nothing that needs a security review beyond the standard release-pipeline retest called out in Dependencies.
Audit
§1 — Verdict summary
Seven §1 clauses, seven ACs, five edge cases including one security-class row. All seven clauses trace 1:1 to an AC via traces_to; TRACE-006 (verb-vs-assertion) review found one real gap (AC 4) which is now fixed. The most consequential finding was a test-file convention mismatch that would have pointed the implementer at a file structured the wrong way to receive these tests.
§2 — Findings (all resolved)
ISS-001 — AC 4 tested only the absence of the old string, not the presence of the new one (TRACE-006)
Clause 1.4 demands the doc files "read cs in place of cyberos" — a positive replacement. The original AC 4 asserted only that a grep for cyberos <command> returned zero matches. A test asserting the negative alone would pass on an implementation that deleted the CLI examples from the docs entirely rather than updating them, which satisfies "zero matches" while failing the clause's actual demand that the reader now sees cs. Material: would have passed a test that didn't prove the clause. Resolved: AC 4 now requires both the positive replacement text be present in each of the three files AND the old pattern be absent.
ISS-002 — the cited test file uses the wrong convention for a file::test_name citation
All seven ACs originally pointed at tools/install/tests/test_channels.sh using ::t_name citations. Reading that file showed it is a flat sequential script (ok()/bad() calls with string labels), not a file of named test functions — the citation convention this contract requires (per test_install_hygiene.sh's actual t01_gitignore_managed_block()-style functions, which is what TASK-IMP-129 cited correctly). Citing test_channels.sh::t_bin_renamed_to_cs would have pointed an implementer at a file that cannot host a function by that name without restructuring it first, and conflated this task's rename-specific assertions with test_channels.sh's actual purpose (proving every manifest-declared delivery channel works, per its own header comment). Resolved: introduced a new dedicated file, tools/install/tests/test_cli_rename.sh, using the named-function convention, and all seven ACs now cite it.
ISS-003 — new_files omitted the test file entirely
Following directly from ISS-002: the original frontmatter's new_files: [(none)] was wrong on its own terms even before the file-choice fix — every AC required a new test, so at least one new file was always going to be needed, and the frontmatter didn't say so. Resolved: new_files now lists tools/install/tests/test_cli_rename.sh.
ISS-004 — related_tasks named TASK-IMP-076 but the body never said why
related_tasks: [TASK-IMP-076] was present in the first draft, but nothing in Problem, Proposed Solution, or Dependencies explained the relationship — the same class of gap TASK-IMP-129's own audit (ISS-004 there) flagged as material when a related task is listed but unexplained. TASK-IMP-076 shipped the exact dispatch table and usage text this task renames, and established the "three channels cannot drift" design this task's doc sweep must preserve. Resolved: added an explanatory paragraph to Dependencies.
ISS-005 — Success Metrics lacked a timeframe (QA-004-adjacent)
Both metrics had a baseline and a target but no deadline, which QA-004 treats as a vanity-metric risk even when the target itself is concrete. Resolved: both metrics now anchor to "the next CyberOS release after 1.0.9."
ISS-006 — an edge case asserted a specific npm bin-symlink behaviour that was not actually verified
The original edge-case bullet stated a user's old cyberos invocation "will silently stop resolving" after the package upgrades to the new bin name — presented as settled fact, but npm's handling of a changed bin field on an existing global install (clean removal vs. a dangling stale symlink) was never independently checked in this authoring session; it is version- and install-method-dependent. Asserting a specific mechanism without having verified it is exactly the kind of unsourced technical claim the anti-fabrication discipline exists to catch. Resolved: reframed as an open question that TASK-IMP-134's clean-machine regression test must observe directly, rather than a claim this task asserts as already known.
§3 — TRACE-006 semantic sufficiency (per clause)
| Clause | Verb demand | Cited test asserts | Verdict |
|---|---|---|---|
| 1.1 MUST declare bin+name | generated config literally contains both fields | AC 1: scratch-build package.json has bin.cs and unchanged name | sufficient |
1.2 MUST refer to invocation as cs | positive text present AND old text absent in --help output | AC 2: asserts both halves against actual stdout | sufficient |
1.3 MUST describe npm channel as npx cs | same shape as 1.2, against help.sh output | AC 3: asserts both halves against actual stdout | sufficient |
1.4 MUST read cs in docs | positive replacement present, not just old string absent | AC 4 (revised): asserts both halves per file | sufficient after revision (was insufficient pre-revision — ISS-001) |
| 1.5 MUST correct domain string | positive new domain present AND old domain absent | AC 5: asserts both halves | sufficient |
| 1.6 MUST gain CHANGELOG entry | positive content present in top entry | AC 6: asserts three required substrings | sufficient |
1.7 MUST NOT modify modules/memory | diff scope excludes the path — a "preserve" style check | AC 7: asserts git diff touches no file under modules/memory/ | sufficient |
§4 — Resolution
Six findings, all material or TRACE-006-material, all resolved in the audited revision. Score = 10/10.
Status transition draft -> ready_to_implement is authorised by this verdict per STATUS-REFERENCE.md §1.1. The two human-acceptance gates in /ship-tasks (review acceptance, final acceptance) are unchanged and remain recorded human verdicts — this audit clears the spec-correctness gate only.
End of TASK-IMP-130 audit.