diff --git a/docs/roadmap/aliases.md b/docs/roadmap/aliases.md new file mode 100644 index 0000000..5136d34 --- /dev/null +++ b/docs/roadmap/aliases.md @@ -0,0 +1,192 @@ +# Application-owned aliases + +Status: command-alias direction accepted; implementation has not started. +Public API and remaining routing details are open. Flag aliasing is under +discussion. This roadmap records the target and work needed before implementation. + +## Purpose and ownership + +Make alternate command spellings and shorter paths simple for consuming +applications to declare. CommandKit core owns alias registration, resolution, +and integration with routing and help. Applications choose their aliases. +Integrated libraries continue to own their canonical command behavior. + +Aliases occupy a separate application routing layer above installed canonical +commands: + +```text +CLI argument tokens + → command-path alias resolution + → canonical command routing and parsing + → ordinary invocation lifecycle +``` + +Alias declarations do not install new handlers or modify the canonical command +tree. An alias spelled inside `promptkit` therefore does not add an +application-owned operation to the integration's namespace. The ownership and +placement rules in [ADR 0011](../adr/0011-captured-declarations-and-installation.md) +and the [architecture policy](../policy/architecture.md) continue to govern +canonical command installation. + +## Current baseline + +Core captures reusable `Command` declarations and installs them through `New` +and `App.Register`. Installation validates a batch before registry mutation. +Optional standard families own their installed root namespaces. Core routing +and the internal backend coordinate parsing, help, and execution through one +invocation lifecycle. + +The current public model has no application alias layer. PromptKit already +exposes the collection catalog and smoke-test commands used in the examples +below. These examples illustrate alternate routes to existing capabilities; +they do not introduce new PromptKit operations. + +The [CLI reference](../cli.md) owns current grammar. Options follow the complete +command path, can be interspersed with operands, and use `--` to terminate +option parsing. Aliasing preserves the target's grammar and typed binding +contracts. + +## Selected command-alias behavior + +### Paths and resolution + +Declare mappings between command paths relative to the application root. The +executable name is not part of either path: + +| Alias path | Target path | +| --- | --- | +| `list collections` | `promptkit list collections` | +| `promptkit test full` | `promptkit test all` | +| `list` | `promptkit list` | + +Aliases can target individual commands or groups. A group alias preserves +remaining subcommand tokens. For example, `list collections` can reach +`promptkit list collections` through the `list` group alias. + +Match complete argument tokens at the beginning of the command path. Resolve +overlapping alias paths using the longest match. Preserve trailing arguments, +including flags, operands, explicit empty values, and `--`, for canonical +parsing. Values and operands are not searched for alias text. + +Support alias chains and resolve them to their canonical target. Validate +targets and reject cycles during installation. Resolution must terminate; +the treatment of group-prefix composition is part of the remaining detailed +design. + +The initial command-alias feature maps command paths. Preset flags, operand +transformation, and arbitrary argument rewriting are outside this delivery. + +### Installation and collisions + +Provide a small core API for aliases that composes with installation of +application and integration commands. The public declaration and registration +shape remains open; earlier illustrative `Alias` calls are not a settled Go API. + +An alias target may already be installed or be supplied in the same installation +batch. Declaration order within that batch does not affect resolution. Missing +targets, collisions, and cycles produce installation errors with useful path +context. Failed installation preserves the existing application registry and +alias mappings under the existing batch-atomicity model. + +Reject aliases that shadow existing canonical command paths. Preserve that +protection when later registration adds commands. Detailed prefix interactions +remain open below. Aliases do not create canonical parent groups, merge +integration trees, or replace handlers. + +### Execution and help + +An invocation through an alias uses the canonical target's flags, operands, +defaults, typed bindings, input preparation, providers, diagnostics, and +outcomes. Execute the ordinary lifecycle once. Alias registration, resolution, +and help do not invoke application input/state factories or acquisition callbacks. + +Retain the entered alias path and resolved canonical path for routing and +presentation. Whether this identity is exposed through the public invocation +API remains open. + +Support both help forms: + +```text +scriptorium help list collections +scriptorium list collections --help +``` + +Alias help describes the canonical target's inputs using the alias invocation +path and identifies the canonical command. Root help presents aliases separately +from canonical commands. Group help and discovery details remain to be specified. + +## Work needed from the baseline + +1. Settle the public alias API and the open routing details with consumer examples + covering a command shortcut, a synonym inside an integration namespace, and + a group shortcut. +2. Capture the durable separation between application alias routing and canonical + namespace ownership in an ADR. Keep exact API, matching, and presentation + details in their appropriate contracts. No relaxation of canonical namespace + ownership is selected. +3. Extend installation to validate aliases and commands against the complete + candidate batch, preserving retained errors and atomicity. Keep aliases + independent of optional-library dependencies and backend-specific exports. +4. Integrate alias resolution with canonical routing, help, and invocation + identity. Reuse the existing parser and typed execution machinery. +5. Add focused behavioral evidence for both example mappings, group aliases, + longest matches, chains and cycles, collisions, missing targets, same-batch + resolution, later registration, argument preservation, help without + acquisition, and a single execution lifecycle. +6. Add maintained consumer examples and update GoDoc, the CLI reference, consumer + guidance, and internal documentation when implementation lands. Validate the + affected modules under the [developer guide](../development.md). + +Completion means consumers can declare alternate paths with minimal wiring, +receive installation-time feedback, and invoke canonical behavior and help +through those paths while canonical namespace ownership stays intact. + +## Flag aliasing under discussion + +The same application routing concept may support alternate flag spellings, +such as `--hlep` mapping to `--help`, while leaving canonical flags and bindings +unchanged. The user-facing API should be comparably simple to command aliases. +Scope, token handling, registration, and help behavior need further discussion; +no specific flag-alias API or resolution policy is selected here. + +## Open Decisions + +### OD-1: Public declaration and registration API + +What are the exact alias declaration, path representation, and installation +signatures? How do alias declarations compose with groups, reusable declarations, +and later `App.Register` calls? What are the duplicate-declaration semantics? + +### OD-2: Prefix interactions and canonical reachability + +How are collisions determined when alias sources or targets overlap canonical +groups or runnable commands with children? How does longest matching interact +with operand boundaries? Which later registrations conflict with existing +aliases? How are ambiguous paths reported? + +### OD-3: Chains and group aliases + +How do group aliases compose with more specific aliases and with aliases inside +their target paths? At what boundaries is resolution repeated? How are cycles +and nonterminating prefix expansion detected without confusing operands with +command-path tokens? + +### OD-4: Help and discovery + +How are aliases listed, grouped, and described in help? What happens when an +operator requests a parent of an alias path that has no canonical group? How +does group-alias help present descendants? How are entered and canonical paths +shown in usage errors? + +### OD-5: Invocation identity + +Does the public invocation API expose entered and canonical command paths? +What identity is retained through a chain, and how is it represented for help +and diagnostic presentation? + +### OD-6: Flag alias scope and composition + +What is the flag-alias API and its installation scope? How does it compose with +command aliases, canonical local flags, and built-in help? Which long and short +flag forms are supported? How are values, `--`, chains, collisions, missing +targets, help, and diagnostic spelling handled?