or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

arguments.mdconfiguration-sources.mdcore-commands.mdexceptions.mdindex.mdoptions.mdparameter-groups.mdparameter-types.mdshell-completion.mdtesting-utilities.md

core-commands.mddocs/

0

# Core Commands

1

2

Foundation command classes and execution framework for building CLI applications. The CliktCommand class provides the base functionality for parameter registration, parsing, and execution.

3

4

## Capabilities

5

6

### CliktCommand

7

8

Abstract base class for all CLI commands. Provides parameter registration, parsing lifecycle, and execution framework.

9

10

```kotlin { .api }

11

/**

12

* Abstract base class for all CLI commands

13

* @param help Help text for the command

14

* @param epilog Text displayed at end of help output

15

* @param name Command name (inferred from class name if null)

16

* @param invokeWithoutSubcommand Allow execution without subcommands

17

* @param printHelpOnEmptyArgs Print help when no arguments given

18

* @param helpTags Extra help formatter information

19

*/

20

abstract class CliktCommand(

21

help: String = "",

22

epilog: String = "",

23

name: String? = null,

24

invokeWithoutSubcommand: Boolean = false,

25

printHelpOnEmptyArgs: Boolean = false,

26

helpTags: Map<String, String> = emptyMap()

27

) {

28

/** Main execution method - must be implemented by subclasses */

29

abstract fun run()

30

31

/** Parse and execute command with error handling */

32

fun main(argv: List<String>)

33

34

/** Parse command without error handling */

35

fun parse(argv: List<String>, parentContext: Context? = null)

36

37

/** Print output to terminal */

38

fun echo(message: Any?, trailingNewline: Boolean = true, err: Boolean = false)

39

40

/** Add message for later printing */

41

fun issueMessage(message: String)

42

43

/** Get formatted help text */

44

fun getFormattedHelp(error: CliktError? = null): String?

45

46

/** Print formatted help text */

47

fun echoFormattedHelp(error: CliktError? = null)

48

49

/** Get command aliases map */

50

fun aliases(): Map<String, List<String>>

51

52

/** Get all help parameters */

53

fun allHelpParams(): List<ParameterHelp>

54

55

/** Get registered subcommands */

56

fun registeredSubcommands(): List<CliktCommand>

57

58

/** Get registered options */

59

fun registeredOptions(): List<Option>

60

61

/** Get registered arguments */

62

fun registeredArguments(): List<Argument>

63

64

/** Get registered parameter groups */

65

fun registeredParameterGroups(): List<ParameterGroup>

66

67

/** Register an option */

68

fun registerOption(option: Option)

69

70

/** Register an argument */

71

fun registerArgument(argument: Argument)

72

73

/** Register a parameter group */

74

fun registerOptionGroup(group: ParameterGroup)

75

76

/** Get command help text */

77

fun commandHelp(context: Context): String

78

79

/** Get epilog text */

80

fun commandHelpEpilog(context: Context): String

81

82

/** The name of this command, used in help output */

83

val commandName: String

84

85

/** All messages issued during parsing */

86

val messages: List<String>

87

88

/** The names of all direct children of this command */

89

fun registeredSubcommandNames(): List<String>

90

91

/** Parse command line and throw exception if parsing fails */

92

fun parse(argv: Array<String>, parentContext: Context? = null)

93

94

/** Parse command line and print helpful output on errors */

95

fun main(argv: Array<out String>)

96

97

/** The help displayed in commands list when used as subcommand */

98

protected fun shortHelp(context: Context): String

99

}

100

```

101

102

**Usage Examples:**

103

104

```kotlin

105

import com.github.ajalt.clikt.core.CliktCommand

106

import com.github.ajalt.clikt.parameters.options.*

107

import com.github.ajalt.clikt.parameters.arguments.*

108

109

// Basic command

110

class GreetCommand : CliktCommand(name = "greet", help = "Greet a person") {

111

private val name by argument(help = "Name of person to greet")

112

private val greeting by option("-g", "--greeting", help = "Greeting to use").default("Hello")

113

114

override fun run() {

115

echo("$greeting $name!")

116

}

117

}

118

119

// Command with subcommands

120

class GitCommand : CliktCommand(name = "git") {

121

override fun run() = Unit

122

}

123

124

class CommitCommand : CliktCommand(name = "commit", help = "Record changes") {

125

private val message by option("-m", "--message", help = "Commit message").required()

126

127

override fun run() {

128

echo("Committing with message: $message")

129

}

130

}

131

132

fun main() {

133

GitCommand().subcommands(CommitCommand()).main()

134

}

135

```

136

137

### NoOpCliktCommand

138

139

Convenience base class with empty `run()` implementation for commands that only contain subcommands.

140

141

```kotlin { .api }

142

/**

143

* Convenience base class with empty run() implementation

144

* Useful for commands that only contain subcommands

145

*/

146

open class NoOpCliktCommand(

147

help: String = "",

148

epilog: String = "",

149

name: String? = null,

150

invokeWithoutSubcommand: Boolean = false,

151

printHelpOnEmptyArgs: Boolean = false,

152

helpTags: Map<String, String> = emptyMap()

153

) : CliktCommand(

154

help, epilog, name, invokeWithoutSubcommand, printHelpOnEmptyArgs, helpTags

155

) {

156

override fun run() = Unit

157

}

158

```

159

160

### Context

161

162

Manages parsing configuration and execution state. Provides context-aware error handling and configuration management.

163

164

```kotlin { .api }

165

/**

166

* Manages parsing configuration and execution state

167

* Context instances are created internally and configured via Context.Builder

168

*/

169

class Context private constructor(

170

val parent: Context?,

171

val command: CliktCommand,

172

val allowInterspersedArgs: Boolean,

173

val allowGroupedShortOptions: Boolean,

174

val autoEnvvarPrefix: String?,

175

val printExtraMessages: Boolean,

176

val helpOptionNames: Set<String>,

177

val helpFormatter: (Context) -> HelpFormatter,

178

val tokenTransformer: Context.(String) -> String,

179

val terminal: Terminal,

180

val argumentFileReader: ((filename: String) -> String)?,

181

val readEnvvarBeforeValueSource: Boolean,

182

val valueSource: ValueSource?,

183

val correctionSuggestor: TypoSuggestor,

184

val localization: Localization,

185

val readEnvvar: (String) -> String?,

186

var obj: Any?,

187

val originalArgv: List<String>

188

) {

189

/** If this command has subcommands and one was invoked, this is the subcommand */

190

var invokedSubcommand: CliktCommand?

191

192

/** If true, an error was encountered while parsing but parsing continues */

193

var errorEncountered: Boolean

194

195

/** Find context object by type */

196

inline fun <reified T : Any> findObject(): T?

197

198

/** Find or set context object */

199

inline fun <reified T : Any> findOrSetObject(defaultValue: () -> T): T

200

201

/** Get root context */

202

fun findRoot(): Context

203

204

/** Get parent command names */

205

fun parentNames(): List<String>

206

207

/** Get full command path */

208

fun commandNameWithParents(): List<String>

209

210

/** Throw UsageError */

211

fun fail(message: String = ""): Nothing

212

213

/** Register cleanup callback */

214

fun callOnClose(closeable: () -> Unit)

215

216

/** Execute cleanup callbacks */

217

fun close()

218

219

/** If true, arguments starting with @ will be expanded as argument files */

220

val expandArgumentFiles: Boolean

221

222

class Builder(command: CliktCommand, val parent: Context? = null) {

223

var allowInterspersedArgs: Boolean

224

var allowGroupedShortOptions: Boolean

225

var printExtraMessages: Boolean

226

var helpOptionNames: Iterable<String>

227

var helpFormatter: ((Context) -> HelpFormatter)?

228

var tokenTransformer: Context.(String) -> String

229

var autoEnvvarPrefix: String?

230

var terminal: Terminal

231

var expandArgumentFiles: Boolean

232

var argumentFileReader: ((filename: String) -> String)?

233

var readEnvvarBeforeValueSource: Boolean

234

var valueSource: ValueSource?

235

fun valueSources(vararg sources: ValueSource)

236

var correctionSuggestor: TypoSuggestor

237

var localization: Localization

238

var envvarReader: (key: String) -> String?

239

var obj: Any?

240

}

241

}

242

```

243

244

### Extension Functions

245

246

```kotlin { .api }

247

/**

248

* Add subcommands to a command

249

*/

250

fun <T : CliktCommand> T.subcommands(commands: Iterable<CliktCommand>): T

251

252

fun <T : CliktCommand> T.subcommands(vararg commands: CliktCommand): T

253

254

/**

255

* Configure command context

256

*/

257

fun <T : CliktCommand> T.context(block: Context.Builder.() -> Unit): T

258

259

/**

260

* Register an AutoCloseable to be closed when command finishes

261

*/

262

fun <T: AutoCloseable> Context.registerCloseable(closeable: T): T

263

264

/**

265

* Find the closest object of type T, or throw NullPointerException

266

*/

267

inline fun <reified T : Any> CliktCommand.requireObject(): ReadOnlyProperty<CliktCommand, T>

268

269

/**

270

* Find the closest object of type T, or null

271

*/

272

inline fun <reified T : Any> CliktCommand.findObject(): ReadOnlyProperty<CliktCommand, T?>

273

274

/**

275

* Find the closest object of type T, setting context.obj if not found

276

*/

277

inline fun <reified T : Any> CliktCommand.findOrSetObject(crossinline default: () -> T): ReadOnlyProperty<CliktCommand, T>

278

279

/**

280

* The current terminal's theme

281

*/

282

val Context.theme : Theme

283

284

/**

285

* Short for accessing the terminal from the currentContext

286

*/

287

val CliktCommand.terminal: Terminal

288

```

289

290

**Usage Examples:**

291

292

```kotlin

293

// Configure context

294

class MyCommand : CliktCommand() {

295

init {

296

context {

297

allowInterspersedArgs = false

298

helpOptionNames = setOf("--help")

299

}

300

}

301

302

override fun run() {

303

// Access context

304

val ctx = currentContext

305

echo("Command name: ${ctx.command.commandName}")

306

307

// Store data in context

308

ctx.obj = "shared data"

309

}

310

}

311

312

// Add subcommands

313

class MainCommand : NoOpCliktCommand() {

314

override fun run() = Unit

315

}

316

317

fun main() {

318

MainCommand()

319

.subcommands(

320

SubCommand1(),

321

SubCommand2(),

322

SubCommand3()

323

)

324

.main()

325

}

326

```

327

328

## Core Interfaces

329

330

```kotlin { .api }

331

/**

332

* DSL marker annotation for parameter holder interfaces

333

*/

334

@DslMarker

335

annotation class ParameterHolderDsl

336

337

/**

338

* Base interface for classes that hold parameters

339

*/

340

@ParameterHolderDsl

341

interface ParameterHolder {

342

/** Register an option with this command or group */

343

fun registerOption(option: GroupableOption)

344

}

345

346

/**

347

* Base interface for options with static group names

348

*/

349

interface StaticallyGroupedOption : Option {

350

/** The name of the group, or null if this option should not be grouped */

351

val groupName: String?

352

}

353

354

/**

355

* An option that can be added to a ParameterGroup

356

*/

357

interface GroupableOption : StaticallyGroupedOption {

358

/** The group that this option belongs to, or null. Set by the group */

359

var parameterGroup: ParameterGroup?

360

361

/** The name of the group, or null if this option should not be grouped */

362

override var groupName: String?

363

}

364

365

/**

366

* Marker interface for context-aware errors

367

*/

368

interface ContextCliktError {

369

/** The context of the command that raised this error */

370

var context: Context?

371

}

372

373

/**

374

* Type alias for typo correction functions

375

*/

376

typealias TypoSuggestor = (enteredValue: String, possibleValues: List<String>) -> List<String>

377

```