@outfitter/cli 0.1.0-rc.1 → 0.1.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/actions.d.ts +1 -12
  2. package/dist/actions.js +3 -170
  3. package/dist/cli.d.ts +2 -103
  4. package/dist/cli.js +4 -51
  5. package/dist/command.d.ts +2 -73
  6. package/dist/command.js +4 -42
  7. package/dist/index.d.ts +7 -606
  8. package/dist/index.js +11 -11
  9. package/dist/input.d.ts +2 -277
  10. package/dist/input.js +11 -426
  11. package/dist/output.d.ts +2 -68
  12. package/dist/output.js +4 -150
  13. package/dist/pagination.d.ts +2 -95
  14. package/dist/pagination.js +6 -84
  15. package/dist/render/colors.d.ts +2 -0
  16. package/dist/render/colors.js +17 -0
  17. package/dist/render/date.d.ts +2 -0
  18. package/dist/render/date.js +12 -0
  19. package/dist/render/format-relative.d.ts +2 -0
  20. package/dist/render/format-relative.js +8 -0
  21. package/dist/render/format.d.ts +2 -0
  22. package/dist/render/format.js +10 -0
  23. package/dist/render/index.d.ts +13 -0
  24. package/dist/render/index.js +101 -0
  25. package/dist/render/json.d.ts +2 -0
  26. package/dist/render/json.js +10 -0
  27. package/dist/render/list.d.ts +2 -0
  28. package/dist/render/list.js +8 -0
  29. package/dist/render/markdown.d.ts +2 -0
  30. package/dist/render/markdown.js +10 -0
  31. package/dist/render/progress.d.ts +2 -0
  32. package/dist/render/progress.js +8 -0
  33. package/dist/render/shapes.d.ts +2 -0
  34. package/dist/render/shapes.js +34 -0
  35. package/dist/render/table.d.ts +2 -0
  36. package/dist/render/table.js +11 -0
  37. package/dist/render/text.d.ts +2 -0
  38. package/dist/render/text.js +24 -0
  39. package/dist/render/tree.d.ts +2 -0
  40. package/dist/render/tree.js +8 -0
  41. package/dist/shared/@outfitter/cli-2vs2gxa8.js +429 -0
  42. package/dist/shared/@outfitter/cli-2y3kxew8.d.ts +58 -0
  43. package/dist/shared/@outfitter/cli-2yq94zst.d.ts +39 -0
  44. package/dist/shared/@outfitter/cli-33e97cjs.d.ts +42 -0
  45. package/dist/shared/@outfitter/cli-3hp8qwx3.js +11 -0
  46. package/dist/shared/@outfitter/cli-6xc869x1.js +26 -0
  47. package/dist/shared/@outfitter/cli-72kg550t.d.ts +53 -0
  48. package/dist/shared/@outfitter/cli-7km1e58p.js +85 -0
  49. package/dist/shared/@outfitter/cli-7na6p4fs.d.ts +59 -0
  50. package/dist/shared/@outfitter/cli-8aa1vhdn.d.ts +119 -0
  51. package/dist/shared/@outfitter/cli-8j5k6mr3.js +71 -0
  52. package/dist/shared/@outfitter/cli-8r0bnyyx.js +43 -0
  53. package/dist/shared/@outfitter/cli-a4q87517.d.ts +64 -0
  54. package/dist/shared/@outfitter/cli-afecwfrn.d.ts +13 -0
  55. package/dist/shared/@outfitter/cli-ag0w4pk0.js +89 -0
  56. package/dist/shared/@outfitter/cli-azzk8a1d.js +59 -0
  57. package/dist/shared/@outfitter/cli-bc17qeh2.js +19 -0
  58. package/dist/shared/@outfitter/cli-bt423m6y.js +4 -0
  59. package/dist/shared/@outfitter/cli-c8q4f71g.js +144 -0
  60. package/dist/shared/@outfitter/cli-c9knfqn5.d.ts +30 -0
  61. package/dist/shared/@outfitter/cli-cf2s94s1.d.ts +42 -0
  62. package/dist/shared/@outfitter/cli-d4fegbad.d.ts +66 -0
  63. package/dist/shared/@outfitter/cli-dds0qqvm.d.ts +145 -0
  64. package/dist/shared/@outfitter/cli-e0ecw3x1.js +64 -0
  65. package/dist/shared/@outfitter/cli-efy6jfcj.js +52 -0
  66. package/dist/shared/@outfitter/cli-evx7qcp1.d.ts +300 -0
  67. package/dist/shared/@outfitter/cli-fheaaa6b.js +25 -0
  68. package/dist/shared/@outfitter/cli-j19a91ck.js +30 -0
  69. package/dist/shared/@outfitter/cli-j361wp3g.d.ts +41 -0
  70. package/dist/shared/@outfitter/cli-jbj78ac5.js +70 -0
  71. package/dist/shared/@outfitter/cli-mhamvbty.d.ts +34 -0
  72. package/dist/shared/@outfitter/cli-n51t773m.d.ts +208 -0
  73. package/dist/shared/@outfitter/cli-p0m2fc51.js +172 -0
  74. package/dist/shared/@outfitter/cli-ttt7r0j7.d.ts +253 -0
  75. package/dist/shared/@outfitter/cli-tyajr8qa.d.ts +63 -0
  76. package/dist/shared/@outfitter/cli-v9mjsvjh.js +118 -0
  77. package/dist/shared/@outfitter/cli-wqc652mx.js +135 -0
  78. package/dist/shared/@outfitter/cli-zact3325.js +152 -0
  79. package/dist/shared/@outfitter/cli-zs6jy1am.d.ts +164 -0
  80. package/dist/shared/@outfitter/cli-zx598p8q.d.ts +26 -0
  81. package/dist/terminal/detection.d.ts +2 -0
  82. package/dist/terminal/detection.js +20 -0
  83. package/dist/terminal/index.d.ts +2 -0
  84. package/dist/terminal/index.js +20 -0
  85. package/dist/types.d.ts +1 -252
  86. package/dist/types.js +1 -1
  87. package/package.json +98 -4
  88. package/dist/shared/@outfitter/cli-4yy82cmp.js +0 -20
package/dist/actions.d.ts CHANGED
@@ -1,13 +1,2 @@
1
- import { ActionRegistry, ActionSurface, AnyActionSpec, HandlerContext } from "@outfitter/contracts";
2
- import { Command } from "commander";
3
- interface BuildCliCommandsOptions {
4
- readonly createContext?: (input: {
5
- action: AnyActionSpec;
6
- args: readonly string[];
7
- flags: Record<string, unknown>;
8
- }) => HandlerContext;
9
- readonly includeSurfaces?: readonly ActionSurface[];
10
- }
11
- type ActionSource = ActionRegistry | readonly AnyActionSpec[];
12
- declare function buildCliCommands(source: ActionSource, options?: BuildCliCommandsOptions): Command[];
1
+ import { BuildCliCommandsOptions, buildCliCommands } from "./shared/@outfitter/cli-afecwfrn";
13
2
  export { buildCliCommands, BuildCliCommandsOptions };
package/dist/actions.js CHANGED
@@ -1,175 +1,8 @@
1
1
  // @bun
2
- import"./shared/@outfitter/cli-4yy82cmp.js";
3
-
4
- // packages/cli/src/actions.ts
5
2
  import {
6
- createContext as createHandlerContext,
7
- DEFAULT_REGISTRY_SURFACES,
8
- validateInput
9
- } from "@outfitter/contracts";
10
- import { Command } from "commander";
11
- var ARGUMENT_PREFIXES = ["<", "["];
12
- function isArgumentToken(token) {
13
- if (!token) {
14
- return false;
15
- }
16
- return ARGUMENT_PREFIXES.some((prefix) => token.startsWith(prefix));
17
- }
18
- function splitCommandSpec(spec) {
19
- const parts = spec.trim().split(/\s+/).filter(Boolean);
20
- if (parts.length === 0) {
21
- return { name: undefined, args: [] };
22
- }
23
- return { name: parts[0], args: parts.slice(1) };
24
- }
25
- function applyArguments(command, args) {
26
- for (const arg of args) {
27
- command.argument(arg);
28
- }
29
- }
30
- function applyCliOptions(command, action) {
31
- const options = action.cli?.options ?? [];
32
- for (const option of options) {
33
- if (option.required) {
34
- command.requiredOption(option.flags, option.description, option.defaultValue);
35
- } else {
36
- command.option(option.flags, option.description, option.defaultValue);
37
- }
38
- }
39
- }
40
- function resolveDescription(action) {
41
- return action.cli?.description ?? action.description ?? action.id;
42
- }
43
- function resolveAliases(action) {
44
- return action.cli?.aliases ?? [];
45
- }
46
- function resolveCommandSpec(action) {
47
- return action.cli?.command ?? action.id;
48
- }
49
- function resolveFlags(command) {
50
- return command.optsWithGlobals?.() ?? command.opts();
51
- }
52
- function resolveInput(action, context) {
53
- if (action.cli?.mapInput) {
54
- return action.cli.mapInput(context);
55
- }
56
- const hasFlags = Object.keys(context.flags).length > 0;
57
- if (!hasFlags && context.args.length === 0) {
58
- return {};
59
- }
60
- return {
61
- ...context.flags,
62
- ...context.args.length > 0 ? { args: context.args } : {}
63
- };
64
- }
65
- async function runAction(action, command, createContext) {
66
- const flags = resolveFlags(command);
67
- const args = command.args;
68
- const inputContext = { args, flags };
69
- const input = resolveInput(action, inputContext);
70
- const validation = validateInput(action.input, input);
71
- if (validation.isErr()) {
72
- throw validation.error;
73
- }
74
- const ctx = createContext({ action, args, flags });
75
- const result = await action.handler(validation.value, ctx);
76
- if (result.isErr()) {
77
- throw result.error;
78
- }
79
- }
80
- function createCommand(action, createContext, spec) {
81
- const commandSpec = spec ?? resolveCommandSpec(action);
82
- const { name, args } = splitCommandSpec(commandSpec);
83
- if (!name) {
84
- throw new Error(`Missing CLI command name for action ${action.id}`);
85
- }
86
- const command = new Command(name);
87
- command.description(resolveDescription(action));
88
- applyCliOptions(command, action);
89
- applyArguments(command, args);
90
- for (const alias of resolveAliases(action)) {
91
- command.alias(alias);
92
- }
93
- command.action(async (...argsList) => {
94
- const commandInstance = argsList.at(-1);
95
- await runAction(action, commandInstance, createContext);
96
- });
97
- return command;
98
- }
99
- function buildCliCommands(source, options = {}) {
100
- const actions = isActionRegistry(source) ? source.list() : source;
101
- const includeSurfaces = options.includeSurfaces ?? [
102
- "cli"
103
- ];
104
- const commands = [];
105
- const createContext = options.createContext ?? ((_input) => createHandlerContext({
106
- cwd: process.cwd(),
107
- env: process.env
108
- }));
109
- const grouped = new Map;
110
- const ungrouped = [];
111
- for (const action of actions) {
112
- const surfaces = action.surfaces ?? DEFAULT_REGISTRY_SURFACES;
113
- if (!surfaces.some((surface) => includeSurfaces.includes(surface))) {
114
- continue;
115
- }
116
- const group = action.cli?.group;
117
- if (group) {
118
- const groupActions = grouped.get(group) ?? [];
119
- groupActions.push(action);
120
- grouped.set(group, groupActions);
121
- } else {
122
- ungrouped.push(action);
123
- }
124
- }
125
- for (const action of ungrouped) {
126
- commands.push(createCommand(action, createContext));
127
- }
128
- for (const [groupName, groupActions] of grouped.entries()) {
129
- const groupCommand = new Command(groupName);
130
- let baseAction;
131
- const subcommands = [];
132
- for (const action of groupActions) {
133
- const spec = action.cli?.command?.trim() ?? "";
134
- const { name, args } = splitCommandSpec(spec);
135
- if (!name || isArgumentToken(name)) {
136
- if (baseAction) {
137
- throw new Error(`Group '${groupName}' defines multiple base actions: '${baseAction.id}' and '${action.id}'.`);
138
- }
139
- baseAction = action;
140
- groupCommand.description(resolveDescription(action));
141
- applyCliOptions(groupCommand, action);
142
- applyArguments(groupCommand, name ? [name, ...args] : args);
143
- for (const alias of resolveAliases(action)) {
144
- groupCommand.alias(alias);
145
- }
146
- groupCommand.action(async (...argsList) => {
147
- const commandInstance = argsList.at(-1);
148
- await runAction(action, commandInstance, createContext);
149
- });
150
- } else {
151
- subcommands.push(action);
152
- }
153
- }
154
- for (const action of subcommands) {
155
- const spec = resolveCommandSpec(action);
156
- const { name, args } = splitCommandSpec(spec);
157
- if (!name) {
158
- continue;
159
- }
160
- const subcommand = createCommand(action, createContext, [name, ...args].join(" "));
161
- groupCommand.addCommand(subcommand);
162
- }
163
- if (!baseAction) {
164
- groupCommand.description(groupName);
165
- }
166
- commands.push(groupCommand);
167
- }
168
- return commands;
169
- }
170
- function isActionRegistry(source) {
171
- return "list" in source;
172
- }
3
+ buildCliCommands
4
+ } from "./shared/@outfitter/cli-p0m2fc51.js";
5
+ import"./shared/@outfitter/cli-bt423m6y.js";
173
6
  export {
174
7
  buildCliCommands
175
8
  };
package/dist/cli.d.ts CHANGED
@@ -1,104 +1,3 @@
1
- import { Command } from "commander";
2
- /**
3
- * Configuration for creating a CLI instance.
4
- *
5
- * @example
6
- * ```typescript
7
- * const config: CLIConfig = {
8
- * name: "waymark",
9
- * version: "1.0.0",
10
- * description: "A note management CLI",
11
- * };
12
- * ```
13
- */
14
- interface CLIConfig {
15
- /** CLI name (used in help output and error messages) */
16
- readonly name: string;
17
- /** CLI version (displayed with --version) */
18
- readonly version: string;
19
- /** CLI description (displayed in help output) */
20
- readonly description?: string;
21
- /** Custom error handler */
22
- readonly onError?: (error: Error) => void;
23
- /** Custom exit handler (defaults to process.exit) */
24
- readonly onExit?: (code: number) => never;
25
- }
26
- /**
27
- * CLI instance returned by createCLI.
28
- */
29
- interface CLI {
30
- /** Register a command with the CLI */
31
- register(command: CommandBuilder | Command): this;
32
- /** Parse arguments and execute the matched command */
33
- parse(argv?: readonly string[]): Promise<void>;
34
- /** Get the underlying Commander program */
35
- readonly program: Command;
36
- }
37
- /**
38
- * Action function executed when a command is invoked.
39
- *
40
- * @typeParam TFlags - Type of parsed command flags
41
- */
42
- type CommandAction<TFlags extends CommandFlags = CommandFlags> = (context: {
43
- /** Parsed command-line arguments */
44
- readonly args: readonly string[];
45
- /** Parsed command flags */
46
- readonly flags: TFlags;
47
- /** Raw Commander command instance */
48
- readonly command: Command;
49
- }) => Promise<void> | void;
50
- /**
51
- * Base type for command flags.
52
- * All flag types must extend this.
53
- */
54
- type CommandFlags = Record<string, unknown>;
55
- /**
56
- * Builder interface for constructing commands fluently.
57
- */
58
- interface CommandBuilder {
59
- /** Set command description */
60
- description(text: string): this;
61
- /** Add a command option/flag */
62
- option(flags: string, description: string, defaultValue?: unknown): this;
63
- /** Add a required option */
64
- requiredOption(flags: string, description: string, defaultValue?: unknown): this;
65
- /** Add command aliases */
66
- alias(alias: string): this;
67
- /** Set the action handler */
68
- action<TFlags extends CommandFlags = CommandFlags>(handler: CommandAction<TFlags>): this;
69
- /** Build the underlying Commander command */
70
- build(): Command;
71
- }
72
- /**
73
- * Create a new CLI instance with the given configuration.
74
- *
75
- * The CLI wraps Commander.js with typed helpers, output contract enforcement,
76
- * and pagination state management.
77
- *
78
- * @param config - CLI configuration options
79
- * @returns A CLI instance ready for command registration
80
- *
81
- * @example
82
- * ```typescript
83
- * import { createCLI, command, output } from "@outfitter/cli";
84
- *
85
- * const cli = createCLI({
86
- * name: "waymark",
87
- * version: "1.0.0",
88
- * description: "A note management CLI",
89
- * });
90
- *
91
- * cli.register(
92
- * command("list")
93
- * .description("List all notes")
94
- * .action(async () => {
95
- * const notes = await getNotes();
96
- * output(notes);
97
- * })
98
- * );
99
- *
100
- * await cli.parse();
101
- * ```
102
- */
103
- declare function createCLI(config: CLIConfig): CLI;
1
+ import { createCLI } from "./shared/@outfitter/cli-mhamvbty";
2
+ import "./shared/@outfitter/cli-ttt7r0j7";
104
3
  export { createCLI };
package/dist/cli.js CHANGED
@@ -1,55 +1,8 @@
1
1
  // @bun
2
- import"./shared/@outfitter/cli-4yy82cmp.js";
3
-
4
- // packages/cli/src/cli.ts
5
- import { Command } from "commander";
6
- function isCommanderHelp(error) {
7
- return error.code === "commander.helpDisplayed" || error.code === "commander.version" || error.code === "commander.help";
8
- }
9
- function createCLI(config) {
10
- const program = new Command;
11
- program.name(config.name).version(config.version);
12
- if (config.description) {
13
- program.description(config.description);
14
- }
15
- const exit = config.onExit ?? ((code) => process.exit(code));
16
- program.exitOverride((error) => {
17
- if (isCommanderHelp(error)) {
18
- exit(0);
19
- }
20
- if (config.onError) {
21
- config.onError(error);
22
- }
23
- const exitCode = typeof error.exitCode === "number" && Number.isFinite(error.exitCode) ? error.exitCode : 1;
24
- exit(exitCode);
25
- });
26
- const parse = async (argv) => {
27
- try {
28
- await program.parseAsync(argv ?? process.argv);
29
- } catch (error) {
30
- const err = error instanceof Error ? error : new Error(String(error));
31
- if (config.onError) {
32
- config.onError(err);
33
- }
34
- const errorExitCode = error.exitCode;
35
- const exitCode = typeof errorExitCode === "number" ? errorExitCode : 1;
36
- exit(exitCode);
37
- }
38
- };
39
- const cli = {
40
- program,
41
- register: (builderOrCommand) => {
42
- if ("build" in builderOrCommand) {
43
- program.addCommand(builderOrCommand.build());
44
- } else {
45
- program.addCommand(builderOrCommand);
46
- }
47
- return cli;
48
- },
49
- parse
50
- };
51
- return cli;
52
- }
2
+ import {
3
+ createCLI
4
+ } from "./shared/@outfitter/cli-efy6jfcj.js";
5
+ import"./shared/@outfitter/cli-bt423m6y.js";
53
6
  export {
54
7
  createCLI
55
8
  };
package/dist/command.d.ts CHANGED
@@ -1,74 +1,3 @@
1
- import { Command } from "commander";
2
- /**
3
- * Action function executed when a command is invoked.
4
- *
5
- * @typeParam TFlags - Type of parsed command flags
6
- */
7
- type CommandAction<TFlags extends CommandFlags = CommandFlags> = (context: {
8
- /** Parsed command-line arguments */
9
- readonly args: readonly string[];
10
- /** Parsed command flags */
11
- readonly flags: TFlags;
12
- /** Raw Commander command instance */
13
- readonly command: Command;
14
- }) => Promise<void> | void;
15
- /**
16
- * Base type for command flags.
17
- * All flag types must extend this.
18
- */
19
- type CommandFlags = Record<string, unknown>;
20
- /**
21
- * Builder interface for constructing commands fluently.
22
- */
23
- interface CommandBuilder {
24
- /** Set command description */
25
- description(text: string): this;
26
- /** Add a command option/flag */
27
- option(flags: string, description: string, defaultValue?: unknown): this;
28
- /** Add a required option */
29
- requiredOption(flags: string, description: string, defaultValue?: unknown): this;
30
- /** Add command aliases */
31
- alias(alias: string): this;
32
- /** Set the action handler */
33
- action<TFlags extends CommandFlags = CommandFlags>(handler: CommandAction<TFlags>): this;
34
- /** Build the underlying Commander command */
35
- build(): Command;
36
- }
37
- /**
38
- * Create a new command builder with the given name.
39
- *
40
- * The command builder provides a fluent API for defining CLI commands
41
- * with typed flags, arguments, and actions.
42
- *
43
- * @param name - Command name and optional argument syntax (e.g., "list" or "get <id>")
44
- * @returns A CommandBuilder instance for fluent configuration
45
- *
46
- * @example
47
- * ```typescript
48
- * import { command, output } from "@outfitter/cli";
49
- *
50
- * const list = command("list")
51
- * .description("List all notes")
52
- * .option("--limit <n>", "Max results", "20")
53
- * .option("--json", "Output as JSON")
54
- * .option("--next", "Continue from last position")
55
- * .action(async ({ flags }) => {
56
- * const results = await listNotes(flags);
57
- * output(results);
58
- * });
59
- * ```
60
- *
61
- * @example
62
- * ```typescript
63
- * // Command with required argument
64
- * const get = command("get <id>")
65
- * .description("Get a note by ID")
66
- * .action(async ({ args }) => {
67
- * const [id] = args;
68
- * const note = await getNote(id);
69
- * output(note);
70
- * });
71
- * ```
72
- */
73
- declare function command(name: string): CommandBuilder;
1
+ import { command } from "./shared/@outfitter/cli-2yq94zst";
2
+ import "./shared/@outfitter/cli-ttt7r0j7";
74
3
  export { command };
package/dist/command.js CHANGED
@@ -1,46 +1,8 @@
1
1
  // @bun
2
- import"./shared/@outfitter/cli-4yy82cmp.js";
3
-
4
- // packages/cli/src/command.ts
5
- import { Command } from "commander";
6
-
7
- class CommandBuilderImpl {
8
- command;
9
- constructor(name) {
10
- this.command = new Command(name);
11
- }
12
- description(text) {
13
- this.command.description(text);
14
- return this;
15
- }
16
- option(flags, description, defaultValue) {
17
- this.command.option(flags, description, defaultValue);
18
- return this;
19
- }
20
- requiredOption(flags, description, defaultValue) {
21
- this.command.requiredOption(flags, description, defaultValue);
22
- return this;
23
- }
24
- alias(alias) {
25
- this.command.alias(alias);
26
- return this;
27
- }
28
- action(handler) {
29
- this.command.action(async (...args) => {
30
- const command = args.at(-1);
31
- const flags = command.optsWithGlobals?.() ?? command.opts();
32
- const positional = command.args;
33
- await handler({ args: positional, flags, command });
34
- });
35
- return this;
36
- }
37
- build() {
38
- return this.command;
39
- }
40
- }
41
- function command(name) {
42
- return new CommandBuilderImpl(name);
43
- }
2
+ import {
3
+ command
4
+ } from "./shared/@outfitter/cli-8r0bnyyx.js";
5
+ import"./shared/@outfitter/cli-bt423m6y.js";
44
6
  export {
45
7
  command
46
8
  };