or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

action-execution.mdcommand-definition.mdhelp-system.mdindex.mdoptions-configuration.mdprogram-creation.md

action-execution.mddocs/

0

# Action Execution

1

2

Action handler system for command execution, argument parsing, and lazy evaluation support.

3

4

## Capabilities

5

6

### Action Method

7

8

Attach callback handlers to commands that execute when the command is invoked.

9

10

```javascript { .api }

11

/**

12

* Attach callback handler to current command

13

* @param {function} handler - Command handler function

14

* @returns {Sade} Chainable instance

15

*/

16

action(handler);

17

18

/**

19

* Command handler function signature

20

* @param {...*} args - Positional arguments based on command usage pattern

21

* @param {object} opts - Parsed options and flags

22

*/

23

type Handler = (...args: any[], opts: object) => any;

24

```

25

26

**Parameters:**

27

28

- `handler` (function, required): Callback function executed when command runs

29

- Receives positional arguments based on command usage pattern

30

- Final parameter is always an options object with parsed flags

31

- Optional arguments may be `undefined` if not provided

32

33

**Usage Examples:**

34

35

```javascript

36

// Basic command handler

37

prog.command('greet <name>')

38

.action((name, opts) => {

39

console.log(`Hello, ${name}!`);

40

});

41

42

// Handler with optional arguments

43

prog.command('serve [dir] [port]')

44

.option('-w, --watch', 'Watch for changes')

45

.action((dir = '.', port = 3000, opts) => {

46

console.log(`Serving ${dir} on port ${port}`);

47

if (opts.watch) console.log('Watching for changes...');

48

});

49

50

// Handler with multiple required arguments

51

prog.command('copy <src> <dest>')

52

.option('-f, --force', 'Overwrite existing files')

53

.action((src, dest, opts) => {

54

console.log(`Copying ${src} to ${dest}`);

55

console.log('Options:', opts);

56

// opts = { _: [], force: true/false, f: true/false }

57

});

58

```

59

60

### Parse Method

61

62

Parse command line arguments and execute the appropriate command handler.

63

64

```javascript { .api }

65

/**

66

* Parse command line arguments and execute appropriate handler

67

* @param {string[]} arr - Command line arguments (typically process.argv)

68

* @param {object} [opts] - Parsing configuration options

69

* @returns {void|LazyOutput} Void (executes handler) or LazyOutput if opts.lazy = true

70

*/

71

parse(arr, opts);

72

73

interface ParseOptions {

74

/** Return execution info instead of running handler */

75

lazy?: boolean;

76

/** Additional flag aliases */

77

alias?: Record<string, string | string[]>;

78

/** Additional default values */

79

default?: Record<string, any>;

80

/** Handler for unknown flags */

81

unknown?: (flag: string) => string | void;

82

}

83

84

interface LazyOutput {

85

/** Command name that was matched */

86

name: string;

87

/** Handler function to execute */

88

handler: Handler;

89

/** Arguments array to pass to handler */

90

args: any[];

91

}

92

```

93

94

**Parameters:**

95

96

- `arr` (string[], required): Command line arguments array (usually `process.argv`)

97

- `opts` (object, optional): Parsing configuration options

98

99

**Basic Usage:**

100

101

```javascript

102

// Standard usage - executes handler immediately

103

prog.parse(process.argv);

104

105

// With custom arguments (for testing)

106

prog.parse(['node', 'script.js', 'build', 'src', 'dist', '--watch']);

107

```

108

109

### Lazy Execution

110

111

Use lazy parsing to defer command execution and gain control over when handlers run.

112

113

**Usage Examples:**

114

115

```javascript

116

// Get execution information without running

117

const result = prog.parse(process.argv, { lazy: true });

118

119

console.log('Command:', result.name);

120

console.log('Arguments:', result.args);

121

122

// Execute later (optionally modify args first)

123

result.handler.apply(null, result.args);

124

125

// Or with modified arguments

126

const modifiedArgs = result.args.map(arg =>

127

typeof arg === 'string' ? arg.toUpperCase() : arg

128

);

129

result.handler.apply(null, modifiedArgs);

130

```

131

132

### Parse Options Override

133

134

Override or extend option parsing behavior with custom configuration.

135

136

**Alias Override:**

137

138

```javascript

139

prog.command('build')

140

.option('-f, --force', 'Force build');

141

142

// Override aliases at parse time

143

prog.parse(process.argv, {

144

alias: {

145

f: ['foo', 'fizz'], // -f now maps to --foo and --fizz instead of --force

146

v: ['verbose'] // Add new -v -> --verbose alias

147

}

148

});

149

```

150

151

**Default Value Override:**

152

153

```javascript

154

prog.command('start')

155

.option('-p, --port', 'Server port', 3000);

156

157

// Override defaults at parse time

158

prog.parse(process.argv, {

159

default: {

160

port: 8080, // Override default port

161

env: 'development' // Add new default value

162

}

163

});

164

```

165

166

**Unknown Flag Handling:**

167

168

```javascript

169

prog.parse(process.argv, {

170

unknown: (flag) => {

171

if (flag.startsWith('--experimental-')) {

172

return; // Allow experimental flags without error

173

}

174

return `Unknown flag: ${flag}. Did you mean --help?`;

175

}

176

});

177

178

// Example output:

179

// $ my-cli build --typo

180

// ERROR: Unknown flag: --typo. Did you mean --help?

181

```

182

183

### Argument Parsing Behavior

184

185

Sade follows specific rules for parsing arguments and options.

186

187

**Argument Order and Types:**

188

189

```javascript

190

prog.command('deploy <env> [version] [region]')

191

.option('-f, --force', 'Force deployment')

192

.option('--timeout', 'Deployment timeout', 300)

193

.action((env, version, region, opts) => {

194

// env: always provided (required)

195

// version: string or undefined (optional)

196

// region: string or undefined (optional)

197

// opts: { force: boolean, timeout: number, ... }

198

});

199

200

// Examples:

201

// $ my-cli deploy prod

202

// → env='prod', version=undefined, region=undefined

203

// $ my-cli deploy prod v1.2.0

204

// → env='prod', version='v1.2.0', region=undefined

205

// $ my-cli deploy prod v1.2.0 us-east-1 --force

206

// → env='prod', version='v1.2.0', region='us-east-1', opts.force=true

207

```

208

209

**Options Object Structure:**

210

211

```javascript

212

prog.command('build')

213

.option('-w, --watch', 'Watch mode')

214

.option('-o, --output', 'Output file', 'dist.js')

215

.action((opts) => {

216

console.log(opts);

217

// {

218

// _: [], // Remaining arguments

219

// w: true, // Short flag alias

220

// watch: true, // Long flag name

221

// o: 'custom.js', // Short flag alias with value

222

// output: 'custom.js' // Long flag name with value

223

// }

224

});

225

```

226

227

### Error Handling

228

229

Parse method handles various error conditions and provides helpful error messages.

230

231

**Common Errors:**

232

233

- **Insufficient arguments**: Required arguments not provided

234

- **Invalid command**: Command name not found

235

- **Unknown options**: Unrecognized flags (unless handled by `unknown` option)

236

- **No command specified**: Multi-command CLI called without a command

237

238

**Error Examples:**

239

240

```javascript

241

// Insufficient arguments

242

// $ my-cli copy file1

243

// ERROR: Insufficient arguments!

244

// Run `$ my-cli copy --help` for more info.

245

246

// Invalid command

247

// $ my-cli invalid-command

248

// ERROR: Invalid command: invalid-command

249

// Run `$ my-cli --help` for more info.

250

251

// No command (multi-command mode)

252

// $ my-cli

253

// ERROR: No command specified.

254

// Run `$ my-cli --help` for more info.

255

```

256

257

### Execution Flow

258

259

The parse method follows a specific execution flow:

260

261

1. **Parse arguments** using mri library

262

2. **Detect command** from positional arguments

263

3. **Resolve aliases** to actual command names

264

4. **Validate arguments** against command usage pattern

265

5. **Merge options** (global + command + parse-time)

266

6. **Execute action** or return lazy output

267

7. **Handle help/version** flags automatically