@x12i/ask-cli
v1.2.1
Published
Deterministic natural-language-like command resolver for CLIs
Maintainers
Readme
@x12i/ask-cli
Deterministic natural-language-like command resolver for CLIs.
@x12i/ask-cli lets CLI tools accept friendly phrases such as install, build and test all @x12i packages and resolve them to structured command plans without an LLM.
It does not execute shell commands. Host CLIs remain responsible for validation, approval, and execution.
Install
npm install @x12i/ask-cliQuick start
import { createAskCli } from "@x12i/ask-cli";
const askCli = createAskCli({
catalog: [
{
id: "xnpm.install.all",
intent: "install",
phrases: ["install all packages", "install everything"],
command: { base: "xnpm", args: [] },
explanation: ["Run npm install in dependency-aware order."],
approval: "never",
},
],
});
const result = await askCli.resolve({
input: "install all packages in the right order",
context: { commandName: "xnpm" },
});
if (result.matched && result.command) {
// Host CLI validates, prompts for approval if needed, then executes.
}Features
- Input normalization (lowercase, punctuation,
&→and,then→and,everything→all packages, action reordering) - Harmless modifier stripping (
in the right order,safely, …) with structuredmodifiersmetadata on results - Modifier-tolerant matching when only known adjunct phrases differ from catalog entries
- Exact phrase matching
- Pattern matching with typed slots
- Optional deterministic alias expansion
- Built-in slot types:
scope,packageName,repoName,enum,string - Optional explanation enrichment hook for host-rendered “This will:” blocks
- Configurable output modifier → flag mapping (
outputFlags) - Suggestions when no match is found
- Approval metadata for host-rendered prompts
- Host validation hooks
Modifier stripping
User input often restates default CLI behavior with harmless adjuncts such as in the right order or safely. ask-cli strips these before matching and returns what was removed on the resolve result:
const result = await askCli.resolve({
input: "publish everything in the right order",
});
// result.matched === true
// result.recordId === "publish.all" (when catalog includes that record)
// result.modifiers?.orderRequested === true
// result.matchType === "phrase" | "pattern" | "alias" | "modifier-tolerant"Built-in operation and safety modifiers ship by default. Consumers can extend them:
createAskCli({
catalog,
modifiers: {
operation: ["using our custom order"],
output: ["without version bump"],
},
outputFlags: {
"without version bump": ["--no-version-bump"],
},
});Only flags not already present on the matched record are appended.
Explanation enrichment
Hosts can opt into richer explanations without changing resolved commands:
import { createAskCli, enrichMonorepoExplanation } from "@x12i/ask-cli";
const askCli = createAskCli({
catalog,
enrichExplanation: enrichMonorepoExplanation,
});Or provide a custom hook:
createAskCli({
catalog,
enrichExplanation(explanation, result) {
if (result.modifiers?.orderRequested) {
return ["Order packages by dependency graph.", ...explanation];
}
return explanation;
},
});Catalog shape
Each catalog record defines phrases, optional slot patterns, resolved command args, explanations, risks, and approval policy.
See the project spec for the full AskCliCatalogRecord and AskCliResolveResult types.
Consumers
Designed for CLIs such as:
@x12i/npm(xnpm ask)@x12i/doctor-x(doctor-x ask)@x12i/funcx(funcx ask)
License
MIT
