or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdcommands-and-routing.mdconfiguration-and-context.mddocumentation-and-help.mderror-handling.mdexit-codes.mdflag-parameters.mdindex.mdparameter-parsers.mdpositional-parameters.mdtext-and-localization.md

commands-and-routing.mddocs/

0

# Commands and Routing

1

2

Define commands and organize them into nested route maps.

3

4

## Quick Reference

5

6

```typescript

7

// Simple command

8

const cmd = buildCommand({

9

func: async function(flags, arg1, arg2) { /* ... */ },

10

parameters: { flags: { /* ... */ }, positional: { /* ... */ } },

11

docs: { brief: "Description" }

12

})

13

14

// Lazy-loaded command

15

const cmd = buildCommand({

16

loader: () => import("./commands/deploy.js"),

17

parameters: { /* ... */ },

18

docs: { brief: "Description" }

19

})

20

21

// Route map

22

const routes = buildRouteMap({

23

routes: { cmd1, cmd2, nested: nestedRouteMap },

24

defaultCommand: "cmd1", // optional

25

docs: { brief: "Description" },

26

aliases: { c: "cmd1" } // optional

27

})

28

```

29

30

## buildCommand

31

32

Builds a command from a function or loader with parameters and documentation.

33

34

```typescript { .api }

35

function buildCommand<FLAGS, ARGS, CONTEXT>(

36

builderArgs: CommandBuilderArguments<FLAGS, ARGS, CONTEXT>

37

): Command<CONTEXT>

38

```

39

40

**Local Function:**

41

42

```typescript

43

buildCommand({

44

func: async function(flags, ...args) {

45

this.process.stdout.write("Hello\n");

46

},

47

parameters: {

48

flags: { /* FlagParametersForType<FLAGS> */ },

49

positional: { /* TypedPositionalParameters<ARGS> */ },

50

aliases: { /* single-char to flag name mapping */ }

51

},

52

docs: {

53

brief: "Short description",

54

fullDescription: "Optional longer description"

55

}

56

})

57

```

58

59

**Lazy-Loaded Function:**

60

61

```typescript

62

buildCommand({

63

loader: async () => import("./commands/deploy.js"), // or () => CommandFunction

64

parameters: { /* ... */ },

65

docs: { /* ... */ }

66

})

67

68

// In commands/deploy.ts:

69

export default async function(flags, ...args) {

70

// Command implementation

71

}

72

```

73

74

**CommandFunction Signature:**

75

76

```typescript { .api }

77

type CommandFunction<FLAGS, ARGS, CONTEXT> = (

78

this: CONTEXT,

79

flags: FLAGS,

80

...args: ARGS

81

) => void | Error | Promise<void | Error>

82

```

83

84

**Validation:** Checks for reserved flags (`--help`, `--helpAll`, `-h`, `-H`), negation collisions, and variadic separators.

85

86

## buildRouteMap

87

88

Organizes commands into nested structures with optional default command and aliases.

89

90

```typescript { .api }

91

function buildRouteMap<R extends string, CONTEXT>(

92

args: RouteMapBuilderArguments<R, CONTEXT>

93

): RouteMap<CONTEXT>

94

```

95

96

**Example:**

97

98

```typescript

99

const dbRoutes = buildRouteMap({

100

routes: {

101

connect: connectCmd,

102

migrate: migrateCmd,

103

backup: backupCmd

104

},

105

defaultCommand: "connect", // Optional: runs when user types "myapp db"

106

docs: { brief: "Database commands" },

107

aliases: { c: "connect", m: "migrate", b: "backup" } // Optional

108

});

109

110

const app = buildApplication(

111

buildRouteMap({

112

routes: {

113

db: dbRoutes,

114

server: serverCmd

115

},

116

docs: { brief: "Application CLI" }

117

}),

118

{ name: "myapp" }

119

);

120

121

// Usage:

122

// myapp db connect --host localhost

123

// myapp db c --host localhost (using alias)

124

// myapp db (runs default connect command)

125

// myapp server --port 8080

126

```

127

128

**Validation:** Route map must contain at least one route, aliases can't conflict with route names, default command must be a Command (not another RouteMap).

129

130

## Complete Example

131

132

```typescript

133

import { buildApplication, buildRouteMap, buildCommand, numberParser } from "@stricli/core";

134

135

// Commands

136

const deployCmd = buildCommand({

137

func: async function(flags, service) {

138

this.process.stdout.write(`Deploying ${service} to ${flags.env}\n`);

139

},

140

parameters: {

141

flags: {

142

env: { kind: "enum", values: ["dev", "staging", "prod"], brief: "Environment", default: "dev" },

143

force: { kind: "boolean", brief: "Force deployment" }

144

},

145

positional: {

146

kind: "tuple",

147

parameters: [{ brief: "Service name", parse: String }]

148

},

149

aliases: { e: "env", f: "force" }

150

},

151

docs: { brief: "Deploy service" }

152

});

153

154

const statusCmd = buildCommand({

155

func: async function(flags) {

156

this.process.stdout.write(`Checking status (verbose: ${flags.verbose})\n`);

157

},

158

parameters: {

159

flags: {

160

verbose: { kind: "boolean", brief: "Verbose output", default: false }

161

},

162

aliases: { v: "verbose" }

163

},

164

docs: { brief: "Check status" }

165

});

166

167

// Route map

168

const app = buildApplication(

169

buildRouteMap({

170

routes: {

171

deploy: deployCmd,

172

status: statusCmd

173

},

174

docs: { brief: "Deployment CLI" }

175

}),

176

{

177

name: "myapp",

178

scanner: { caseStyle: "allow-kebab-for-camel" }

179

}

180

);

181

182

// Usage:

183

// myapp deploy api --env prod --force

184

// myapp deploy api -e prod -f

185

// myapp status --verbose

186

// myapp status -v

187

```

188

189

## Related

190

191

- [Flag Parameters](./flag-parameters.md)

192

- [Positional Parameters](./positional-parameters.md)

193

- [Configuration and Context](./configuration-and-context.md)

194