Prompts
Define prompts once, infer types automatically, and read values from cli.storage.
oscli prompt builders are the center of the framework. You define the input
shape once, resolve prompts with cli.prompt.<name>(), then read typed values
from cli.storage.
Canonical chain order
Use the same chain order for every prompt builder so definitions stay easy to scan.
.<type>()
.label()
.describe()
.placeholder()
.default()
.optional()
.validate()
.transform()
.color()Shared methods
These methods exist on every prompt builder.
Prop
Type
Prompt builders
These are the available prompt factories.
Prop
Type
Text
Plain string input with placeholder, default, validation, and transform support.
export const cli = createCLI((b) => ({
title: "text prompt",
prompts: {
project: b
.text()
.label("Project")
.placeholder("my-app")
.default("my-app")
.validate((value) =>
value.length >= 2 ? true : "Use at least 2 characters.",
)
.transform((value) => value.trim()),
},
}));# Prompting
Project
› my-app_
# Submitted
✓ Project: my-appPassword
Masked text input for secrets such as API tokens or passwords.
export const cli = createCLI((b) => ({
title: "password prompt",
prompts: {
token: b.password().label("API token"),
},
}));# Prompting
API token
› ********_
# Submitted
✓ API token: ********Number
Numeric input with optional min, max, and prefix formatting.
export const cli = createCLI((b) => ({
title: "number prompt",
prompts: {
retries: b.number().label("Retries").min(0).max(5),
budget: b.number().label("Budget").prefix("$").min(0),
},
}));# Prompting
Budget
› $500_
# Submitted
✓ Budget: $500Select
Choose one value from a fixed list.
export const cli = createCLI((b) => ({
title: "select prompt",
prompts: {
mode: b
.select({ choices: ["personal", "team"] as const })
.label("Mode")
.rule("personal", "single-user setup")
.rule("team", "shared project"),
},
}));# Prompting
Mode
› ● personal single-user setup
○ team shared project
↑↓ navigate enter select
# Submitted
✓ Mode: personalMultiselect
Choose multiple values from a fixed list.
export const cli = createCLI((b) => ({
title: "multiselect prompt",
prompts: {
features: b
.multiselect({ choices: ["api", "ui", "docs", "tests"] as const })
.label("Features")
.min(1)
.max(3),
},
}));# Prompting
Features (1–3)
› ◉ api
○ ui
◉ docs
○ tests
↑↓ navigate space toggle enter confirm
# Submitted
✓ Features: api, docsConfirm
Boolean input. Toggle is the default. Simple keeps the
older typed y/n flow.
Toggle (default):
approved: b.confirm().label("Continue?").default(true)Simple:
approved: b.confirm("simple").label("Continue?").default(false)# Toggle
Continue?
● Yes / ○ No
# Toggle submitted
✓ Continue?: yes
# Simple
Continue?
› (y/N) _
# Simple submitted
✓ Continue?: noToggle: inlineYes / Noselector, arrow keys ory/n, then EnterSimple: typedy/ninput
Search
Filter a fixed choice list while typing.
export const cli = createCLI((b) => ({
title: "search prompt",
prompts: {
framework: b
.search({ choices: ["react", "vue", "svelte", "solid"] as const })
.label("Framework")
.rule("react", "large ecosystem")
.rule("svelte", "minimal runtime"),
},
}));# Prompting
Framework
› sv_
› ● svelte minimal runtime
○ solid
↑↓ navigate enter select
# Submitted
✓ Framework: svelteList
Collect repeated free-form values. The prompt ends on an empty Enter.
export const cli = createCLI((b) => ({
title: "list prompt",
prompts: {
tags: b.list().label("Tags").min(1).max(5),
},
}));# Prompting
Tags 1 / 5
› api_
# Accepted items
✓ Tags: api
✓ Tags: docs
✓ Tags: tests
# Submitted
✓ Tags: api, docs, testsDate
Validated date input stored as Date.
export const cli = createCLI((b) => ({
title: "date prompt",
prompts: {
deadline: b.date().label("Deadline").format("YYYY-MM-DD"),
},
}));# Prompting
Deadline
› 2026-03-31_
# Submitted
✓ Deadline: 2026-03-31
# Validation error
Deadline
› tomorrow_
✗ Use a valid date in YYYY-MM-DD format.If you do not set a placeholder for .date(), oscli uses the configured
format as the placeholder.
Resolution behavior
Prompt builders share the same runtime rules once a value is submitted.