Add alias command for creating extra CLI names - #33
Conversation
- Add `commit alias` with an interactive hub for listing, creating, and deleting aliases, plus scriptable `list`, `add <name> <target>`, and `remove <name>` subcommands. - Bind each alias to a subcommand and install it as a POSIX shim under `~/.commit-tools/bin`, so reinstalling or removing the npm package never touches user aliases. - Introduce a branded `AliasName` in `src/domain/alias/alias.ts` whose private constructor makes an unsafe filesystem path unrepresentable in `shimPath` and `removeShim`. - Keep the registry in `aliases.json` separate from `config.json` so aliases work before `commit setup` has run, validating names and rejecting duplicates at the load boundary. - Offer a one-time managed `PATH` block in `.zshrc`, `.bashrc`, or `config.fish`, written only after an explicit confirmation and idempotent on repeat runs. - Warn before an alias shadows an existing binary on `PATH`, since the alias bin dir is prepended. - Quote interpreter and entry-script paths with POSIX single-quote escaping so a `$` or `'` in the path cannot break the generated shim. - Reject `commit alias` on Windows with a clear message rather than writing an unusable `sh` shim. - Cover the domain, storage, shim, `PATH` setup, CLI, and parser behavior with unit tests.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a37f85e385
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Store the lowercased form from `AliasName.parse` so registry keys and shim paths share one identity. - Reject reserved names case-insensitively after normalization. - Cover case-folded duplicates and reserved variants in unit tests.
- Attach `mapRej` logging on `AliasCommand.create` so malformed `aliases.json` prints recovery text before exit 1. - Cover the load-failure path in CLI unit tests.
- Call `mkdir(dirname(profile.file), { recursive: true })` in `ensureBinDirOnPath` so fish can create `~/.config/fish/config.fish` on first run.
- Cover nested missing parents in path-setup unit tests.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3104c3a87d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Chain `reconcileShims` before the scripted `commit alias add` mutation so existing shims pick up the current Node and entry paths. - Assert direct add reconciles the registry in CLI unit tests.
- Dual-write the managed PATH block to `.bashrc` and the first existing bash login file (`.bash_profile`, `.bash_login`, or `.profile`), creating `.bash_profile` when none exist. - Return `added` when any target file is written so partial prior setup still completes. - Cover dual-write and idempotency in path-setup unit tests. - Document bash login profile handling in the README.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 175611b101
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .chain((name) => this.createAlias(this.initial, name, action.target)) | ||
| .map(() => undefined); | ||
| case "remove": | ||
| return parseName(action.name) |
There was a problem hiding this comment.
Reconcile shims before removing an alias
When commit-tools is reinstalled under a different nvm-managed Node version, registered shims still embed the removed process.execPath; if the user's first mutation is commit alias remove cb, this branch deletes cb and saves the registry without rewriting the remaining shims, so those aliases continue failing despite the command succeeding. This is a P1 availability regression. The fresh evidence beyond the prior add-path comment is that the remove branch still bypasses reconcileShims after the add branch was fixed; prepend reconcileShims(this.initial) here before parsing and deleting the alias.
AGENTS.md reference: AGENTS.md:L9-L10
Useful? React with 👍 / 👎.
| const candidate = resolve(dir, name.value); | ||
| if (await isExecutable(candidate)) return candidate; |
There was a problem hiding this comment.
Reject alias names masked by shell builtins
For commit alias add cd branch, this scan normally finds no executable named cd, so creation succeeds and reports a usable alias, but Bash resolves its cd builtin before searching PATH; help type confirms that command interpretation distinguishes builtins from disk files. Typing cd therefore never executes the generated shim, breaking the alias contract for an accepted input and making this a P1 production correctness bug. Reject builtin/keyword names for the supported shells, or extend conflict detection beyond executable files before writing the alias.
AGENTS.md reference: AGENTS.md:L10-L12
Useful? React with 👍 / 👎.
Motivation
This is something helpful; everyone likes aliases for their favorite tools.
What's New
CLI Alias Command
commit aliasinteractive hub (list / create / delete / done) plus scriptablelist,add <name> <target>, andremove <name>.src/cli/parser.tsandindex.ts; document usage inREADME.md.Domain & Storage
AliasNamewith private constructor so unsafe path names cannot reachshimPath/removeShim.aliases.json(notconfig.json) so aliases work beforecommit setup.Shims & PATH Setup
~/.commit-tools/binso npm reinstall/remove never touches user aliases.PATHblock in.zshrc/.bashrc/config.fishonly after confirmation; idempotent on repeat.PATHbinary; quote interpreter/entry paths with POSIX single-quote escaping.commit aliason Windows with a clear message instead of writing unusableshshims.Tests
Testing & Feedback
pnpm typecheck,pnpm lint,pnpm exec prettier . --check, andpnpm test.0755, bound subcommand execution, and error exits for duplicate / unsafe / reserved / invalid target / unknown remove.removeis non-silent.If you find any bugs or have recommendations for improvements, please open an issue and assign it to me.