@akanjs/devkit 1.0.7-canary.5 → 1.0.8

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.
@@ -38,6 +38,7 @@ var import_fs = __toESM(require("fs"));
38
38
  var import__ = require("..");
39
39
  var import_executors = require("../executors");
40
40
  var import_argMeta = require("./argMeta");
41
+ var import_helpFormatter = require("./helpFormatter");
41
42
  var import_targetMeta = require("./targetMeta");
42
43
  const import_meta = {};
43
44
  const camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
@@ -221,7 +222,17 @@ const runCommands = async (...commands) => {
221
222
  const __dirname = (0, import__.getDirname)(import_meta.url);
222
223
  const hasPackageJson = import_fs.default.existsSync(`${__dirname}/../package.json`);
223
224
  process.env.AKAN_VERSION = hasPackageJson ? JSON.parse(import_fs.default.readFileSync(`${__dirname}/../package.json`, "utf8")).version : "0.0.1";
224
- import_commander.program.version(process.env.AKAN_VERSION).description("Akan CLI");
225
+ const hasHelpFlag = process.argv.includes("--help") || process.argv.includes("-h");
226
+ const hasCommand = process.argv.length > 2 && !process.argv[2].startsWith("-");
227
+ if (hasHelpFlag || !hasCommand) {
228
+ if (process.argv.length === 2 || process.argv.length === 3 && hasHelpFlag) {
229
+ import_common.Logger.rawLog((0, import_helpFormatter.formatHelp)(commands, process.env.AKAN_VERSION));
230
+ process.exit(0);
231
+ }
232
+ }
233
+ import_commander.program.version(process.env.AKAN_VERSION).description("Akan CLI").configureHelp({
234
+ helpWidth: 100
235
+ });
225
236
  const akanBasePackageJson = import_fs.default.existsSync("./node_modules/@akanjs/base/package.json") ? JSON.parse(import_fs.default.readFileSync("./node_modules/@akanjs/base/package.json", "utf8")) : null;
226
237
  if (akanBasePackageJson && akanBasePackageJson.version !== process.env.AKAN_VERSION) {
227
238
  import_common.Logger.rawLog(
@@ -266,6 +277,9 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`
266
277
  }
267
278
  }
268
279
  programCommand = programCommand.option(`-v, --verbose [boolean]`, `verbose output`);
280
+ programCommand.helpInformation = () => {
281
+ return (0, import_helpFormatter.formatCommandHelp)(command, targetMeta.key);
282
+ };
269
283
  programCommand.action(async (...args) => {
270
284
  import_common.Logger.rawLog();
271
285
  const cmdArgs = args.slice(0, args.length - 2);
@@ -0,0 +1,211 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var helpFormatter_exports = {};
29
+ __export(helpFormatter_exports, {
30
+ formatCommandHelp: () => formatCommandHelp,
31
+ formatHelp: () => formatHelp
32
+ });
33
+ module.exports = __toCommonJS(helpFormatter_exports);
34
+ var import_chalk = __toESM(require("chalk"));
35
+ var import_argMeta = require("./argMeta");
36
+ var import_targetMeta = require("./targetMeta");
37
+ const camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
38
+ const groupCommands = (commands) => {
39
+ const groups = /* @__PURE__ */ new Map();
40
+ for (const command of commands) {
41
+ const className = command.name.replace("Command", "");
42
+ const groupName = className;
43
+ if (!groups.has(groupName)) {
44
+ groups.set(groupName, { name: groupName, commands: [] });
45
+ }
46
+ const targetMetas = (0, import_targetMeta.getTargetMetas)(command);
47
+ for (const targetMeta of targetMetas) {
48
+ if (targetMeta.targetOption.devOnly)
49
+ continue;
50
+ const [allArgMetas] = (0, import_argMeta.getArgMetas)(command, targetMeta.key);
51
+ const args = allArgMetas.filter((arg) => arg.type !== "Option").map((arg) => {
52
+ if (arg.type === "Workspace")
53
+ return "";
54
+ if (arg.type === "Module")
55
+ return "[sys:module]";
56
+ if (arg.type === "Argument") {
57
+ return `[${arg.name}]`;
58
+ }
59
+ return `[${arg.type.toLowerCase()}]`;
60
+ }).filter(Boolean);
61
+ const group = groups.get(groupName);
62
+ if (group) {
63
+ group.commands.push({
64
+ key: camelToKebabCase(targetMeta.key),
65
+ args,
66
+ desc: targetMeta.targetOption.desc
67
+ });
68
+ }
69
+ }
70
+ }
71
+ return groups;
72
+ };
73
+ const formatHelp = (commands, version) => {
74
+ const groups = groupCommands(commands);
75
+ const lines = [];
76
+ lines.push("");
77
+ lines.push(import_chalk.default.bold.cyan(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
78
+ lines.push(
79
+ import_chalk.default.bold.cyan(" \u2551") + import_chalk.default.bold.white(" Akan.js Framework CLI ") + import_chalk.default.bold.cyan(" \u2551")
80
+ );
81
+ lines.push(import_chalk.default.bold.cyan(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
82
+ lines.push("");
83
+ lines.push(import_chalk.default.gray(` Version: ${version}`));
84
+ lines.push("");
85
+ lines.push(import_chalk.default.bold.yellow(" USAGE"));
86
+ lines.push("");
87
+ lines.push(import_chalk.default.gray(" $ ") + import_chalk.default.white("akan") + import_chalk.default.gray(" <command> [options]"));
88
+ lines.push("");
89
+ lines.push(import_chalk.default.bold.yellow(" COMMANDS"));
90
+ lines.push("");
91
+ for (const [groupName, group] of groups) {
92
+ if (group.commands.length === 0)
93
+ continue;
94
+ lines.push(import_chalk.default.bold.magenta(` ${groupName}`));
95
+ lines.push("");
96
+ for (const cmd of group.commands) {
97
+ const cmdName = import_chalk.default.green(cmd.key);
98
+ const cmdArgs = cmd.args.length > 0 ? import_chalk.default.gray(` ${cmd.args.join(" ")}`) : "";
99
+ if (cmd.desc) {
100
+ const maxLineLength = 70;
101
+ const cmdPrefix = ` ${cmdName}${cmdArgs}`;
102
+ const indent = " ";
103
+ if (cmdPrefix.length + cmd.desc.length + 3 < maxLineLength) {
104
+ lines.push(`${cmdPrefix} ${import_chalk.default.gray(cmd.desc)}`);
105
+ } else {
106
+ lines.push(cmdPrefix);
107
+ lines.push(`${indent}${import_chalk.default.gray(cmd.desc)}`);
108
+ }
109
+ } else {
110
+ lines.push(` ${cmdName}${cmdArgs}`);
111
+ }
112
+ }
113
+ lines.push("");
114
+ }
115
+ lines.push(import_chalk.default.bold.yellow(" OPTIONS"));
116
+ lines.push("");
117
+ lines.push(` ${import_chalk.default.green("-v, --verbose")} ${import_chalk.default.gray("Enable verbose output")}`);
118
+ lines.push(` ${import_chalk.default.green("-h, --help")} ${import_chalk.default.gray("Display this help message")}`);
119
+ lines.push(` ${import_chalk.default.green("-V, --version")} ${import_chalk.default.gray("Output version number")}`);
120
+ lines.push("");
121
+ lines.push(import_chalk.default.bold.yellow(" EXAMPLES"));
122
+ lines.push("");
123
+ lines.push(import_chalk.default.gray(" # Create a new workspace"));
124
+ lines.push(import_chalk.default.white(" $ akan create-workspace myproject"));
125
+ lines.push("");
126
+ lines.push(import_chalk.default.gray(" # Start development server"));
127
+ lines.push(import_chalk.default.white(" $ akan start myapp"));
128
+ lines.push("");
129
+ lines.push(import_chalk.default.gray(" # Create a new module"));
130
+ lines.push(import_chalk.default.white(" $ akan create-module userProfile"));
131
+ lines.push("");
132
+ lines.push(import_chalk.default.gray(" Documentation: ") + import_chalk.default.cyan("https://akanjs.com/docs"));
133
+ lines.push(import_chalk.default.gray(" Report issues: ") + import_chalk.default.cyan("https://github.com/akan-team/akanjs/issues"));
134
+ lines.push("");
135
+ return lines.join("\n");
136
+ };
137
+ const formatCommandHelp = (command, key) => {
138
+ const [allArgMetas, argMetas] = (0, import_argMeta.getArgMetas)(command, key);
139
+ const kebabKey = camelToKebabCase(key);
140
+ const lines = [];
141
+ const targetMetas = (0, import_targetMeta.getTargetMetas)(command);
142
+ const targetMeta = targetMetas.find((t) => t.key === key);
143
+ const commandDesc = targetMeta?.targetOption.desc;
144
+ lines.push("");
145
+ lines.push(import_chalk.default.bold.cyan(` Command: ${kebabKey}`));
146
+ if (commandDesc) {
147
+ lines.push(import_chalk.default.gray(` ${commandDesc}`));
148
+ }
149
+ lines.push("");
150
+ const args = allArgMetas.filter((arg) => arg.type !== "Option").map((arg) => {
151
+ if (arg.type === "Workspace")
152
+ return "";
153
+ if (arg.type === "Module")
154
+ return "[sys:module]";
155
+ if (arg.type === "Argument") {
156
+ return `[${camelToKebabCase(arg.name)}]`;
157
+ }
158
+ return `[${arg.type.toLowerCase()}]`;
159
+ }).filter(Boolean).join(" ");
160
+ lines.push(import_chalk.default.bold.yellow(" USAGE"));
161
+ lines.push("");
162
+ lines.push(import_chalk.default.gray(" $ ") + import_chalk.default.white(`akan ${kebabKey}`) + (args ? import_chalk.default.gray(` ${args}`) : ""));
163
+ lines.push("");
164
+ const nonOptionArgs = allArgMetas.filter((arg) => arg.type !== "Option");
165
+ if (nonOptionArgs.length > 0) {
166
+ lines.push(import_chalk.default.bold.yellow(" ARGUMENTS"));
167
+ lines.push("");
168
+ for (const arg of nonOptionArgs) {
169
+ if (arg.type === "Workspace")
170
+ continue;
171
+ let argName;
172
+ let argDesc;
173
+ let example = "";
174
+ if (arg.type === "Argument") {
175
+ argName = camelToKebabCase(arg.name);
176
+ argDesc = arg.argsOption.desc ?? "";
177
+ example = arg.argsOption.example ? import_chalk.default.gray(` (e.g., ${String(arg.argsOption.example)})`) : "";
178
+ } else if (arg.type === "Module") {
179
+ argName = "sys:module";
180
+ argDesc = "Module in format: app-name:module-name or lib-name:module-name";
181
+ } else {
182
+ argName = arg.type.toLowerCase();
183
+ argDesc = `${arg.type} name in this workspace`;
184
+ }
185
+ lines.push(` ${import_chalk.default.green(argName)} ${import_chalk.default.gray(argDesc)}${example}`);
186
+ }
187
+ lines.push("");
188
+ }
189
+ const optionArgs = argMetas.filter((a) => a.type === "Option");
190
+ if (optionArgs.length > 0) {
191
+ lines.push(import_chalk.default.bold.yellow(" OPTIONS"));
192
+ lines.push("");
193
+ for (const arg of optionArgs) {
194
+ const opt = arg.argsOption;
195
+ const flag = opt.flag ? `-${opt.flag}, ` : "";
196
+ const kebabName = camelToKebabCase(arg.name);
197
+ const optName = `${flag}--${kebabName}`;
198
+ const optDesc = opt.desc ?? "";
199
+ const defaultVal = opt.default !== void 0 ? import_chalk.default.gray(` [default: ${String(opt.default)}]`) : "";
200
+ const choices = opt.enum ? import_chalk.default.gray(` (${opt.enum.join(", ")})`) : "";
201
+ lines.push(` ${import_chalk.default.green(optName)} ${import_chalk.default.gray(optDesc)}${defaultVal}${choices}`);
202
+ }
203
+ lines.push("");
204
+ }
205
+ return lines.join("\n");
206
+ };
207
+ // Annotate the CommonJS export names for ESM import in node:
208
+ 0 && (module.exports = {
209
+ formatCommandHelp,
210
+ formatHelp
211
+ });
@@ -18,6 +18,7 @@ __reExport(commandDecorators_exports, require("./argMeta"), module.exports);
18
18
  __reExport(commandDecorators_exports, require("./commandMeta"), module.exports);
19
19
  __reExport(commandDecorators_exports, require("./targetMeta"), module.exports);
20
20
  __reExport(commandDecorators_exports, require("./types"), module.exports);
21
+ __reExport(commandDecorators_exports, require("./helpFormatter"), module.exports);
21
22
  __reExport(commandDecorators_exports, require("./command"), module.exports);
22
23
  // Annotate the CommonJS export names for ESM import in node:
23
24
  0 && (module.exports = {
@@ -25,5 +26,6 @@ __reExport(commandDecorators_exports, require("./command"), module.exports);
25
26
  ...require("./commandMeta"),
26
27
  ...require("./targetMeta"),
27
28
  ...require("./types"),
29
+ ...require("./helpFormatter"),
28
30
  ...require("./command")
29
31
  });
@@ -6,6 +6,7 @@ import fs from "fs";
6
6
  import { getDirname } from "..";
7
7
  import { AppExecutor, Executor, LibExecutor, ModuleExecutor, PkgExecutor, WorkspaceExecutor } from "../executors";
8
8
  import { getArgMetas } from "./argMeta";
9
+ import { formatCommandHelp, formatHelp } from "./helpFormatter";
9
10
  import { getTargetMetas } from "./targetMeta";
10
11
  const camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
11
12
  const handleOption = (programCommand, argMeta) => {
@@ -188,7 +189,17 @@ const runCommands = async (...commands) => {
188
189
  const __dirname = getDirname(import.meta.url);
189
190
  const hasPackageJson = fs.existsSync(`${__dirname}/../package.json`);
190
191
  process.env.AKAN_VERSION = hasPackageJson ? JSON.parse(fs.readFileSync(`${__dirname}/../package.json`, "utf8")).version : "0.0.1";
191
- program.version(process.env.AKAN_VERSION).description("Akan CLI");
192
+ const hasHelpFlag = process.argv.includes("--help") || process.argv.includes("-h");
193
+ const hasCommand = process.argv.length > 2 && !process.argv[2].startsWith("-");
194
+ if (hasHelpFlag || !hasCommand) {
195
+ if (process.argv.length === 2 || process.argv.length === 3 && hasHelpFlag) {
196
+ Logger.rawLog(formatHelp(commands, process.env.AKAN_VERSION));
197
+ process.exit(0);
198
+ }
199
+ }
200
+ program.version(process.env.AKAN_VERSION).description("Akan CLI").configureHelp({
201
+ helpWidth: 100
202
+ });
192
203
  const akanBasePackageJson = fs.existsSync("./node_modules/@akanjs/base/package.json") ? JSON.parse(fs.readFileSync("./node_modules/@akanjs/base/package.json", "utf8")) : null;
193
204
  if (akanBasePackageJson && akanBasePackageJson.version !== process.env.AKAN_VERSION) {
194
205
  Logger.rawLog(
@@ -233,6 +244,9 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`
233
244
  }
234
245
  }
235
246
  programCommand = programCommand.option(`-v, --verbose [boolean]`, `verbose output`);
247
+ programCommand.helpInformation = () => {
248
+ return formatCommandHelp(command, targetMeta.key);
249
+ };
236
250
  programCommand.action(async (...args) => {
237
251
  Logger.rawLog();
238
252
  const cmdArgs = args.slice(0, args.length - 2);
@@ -0,0 +1,177 @@
1
+ import chalk from "chalk";
2
+ import { getArgMetas } from "./argMeta";
3
+ import { getTargetMetas } from "./targetMeta";
4
+ const camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
5
+ const groupCommands = (commands) => {
6
+ const groups = /* @__PURE__ */ new Map();
7
+ for (const command of commands) {
8
+ const className = command.name.replace("Command", "");
9
+ const groupName = className;
10
+ if (!groups.has(groupName)) {
11
+ groups.set(groupName, { name: groupName, commands: [] });
12
+ }
13
+ const targetMetas = getTargetMetas(command);
14
+ for (const targetMeta of targetMetas) {
15
+ if (targetMeta.targetOption.devOnly)
16
+ continue;
17
+ const [allArgMetas] = getArgMetas(command, targetMeta.key);
18
+ const args = allArgMetas.filter((arg) => arg.type !== "Option").map((arg) => {
19
+ if (arg.type === "Workspace")
20
+ return "";
21
+ if (arg.type === "Module")
22
+ return "[sys:module]";
23
+ if (arg.type === "Argument") {
24
+ return `[${arg.name}]`;
25
+ }
26
+ return `[${arg.type.toLowerCase()}]`;
27
+ }).filter(Boolean);
28
+ const group = groups.get(groupName);
29
+ if (group) {
30
+ group.commands.push({
31
+ key: camelToKebabCase(targetMeta.key),
32
+ args,
33
+ desc: targetMeta.targetOption.desc
34
+ });
35
+ }
36
+ }
37
+ }
38
+ return groups;
39
+ };
40
+ const formatHelp = (commands, version) => {
41
+ const groups = groupCommands(commands);
42
+ const lines = [];
43
+ lines.push("");
44
+ lines.push(chalk.bold.cyan(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
45
+ lines.push(
46
+ chalk.bold.cyan(" \u2551") + chalk.bold.white(" Akan.js Framework CLI ") + chalk.bold.cyan(" \u2551")
47
+ );
48
+ lines.push(chalk.bold.cyan(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
49
+ lines.push("");
50
+ lines.push(chalk.gray(` Version: ${version}`));
51
+ lines.push("");
52
+ lines.push(chalk.bold.yellow(" USAGE"));
53
+ lines.push("");
54
+ lines.push(chalk.gray(" $ ") + chalk.white("akan") + chalk.gray(" <command> [options]"));
55
+ lines.push("");
56
+ lines.push(chalk.bold.yellow(" COMMANDS"));
57
+ lines.push("");
58
+ for (const [groupName, group] of groups) {
59
+ if (group.commands.length === 0)
60
+ continue;
61
+ lines.push(chalk.bold.magenta(` ${groupName}`));
62
+ lines.push("");
63
+ for (const cmd of group.commands) {
64
+ const cmdName = chalk.green(cmd.key);
65
+ const cmdArgs = cmd.args.length > 0 ? chalk.gray(` ${cmd.args.join(" ")}`) : "";
66
+ if (cmd.desc) {
67
+ const maxLineLength = 70;
68
+ const cmdPrefix = ` ${cmdName}${cmdArgs}`;
69
+ const indent = " ";
70
+ if (cmdPrefix.length + cmd.desc.length + 3 < maxLineLength) {
71
+ lines.push(`${cmdPrefix} ${chalk.gray(cmd.desc)}`);
72
+ } else {
73
+ lines.push(cmdPrefix);
74
+ lines.push(`${indent}${chalk.gray(cmd.desc)}`);
75
+ }
76
+ } else {
77
+ lines.push(` ${cmdName}${cmdArgs}`);
78
+ }
79
+ }
80
+ lines.push("");
81
+ }
82
+ lines.push(chalk.bold.yellow(" OPTIONS"));
83
+ lines.push("");
84
+ lines.push(` ${chalk.green("-v, --verbose")} ${chalk.gray("Enable verbose output")}`);
85
+ lines.push(` ${chalk.green("-h, --help")} ${chalk.gray("Display this help message")}`);
86
+ lines.push(` ${chalk.green("-V, --version")} ${chalk.gray("Output version number")}`);
87
+ lines.push("");
88
+ lines.push(chalk.bold.yellow(" EXAMPLES"));
89
+ lines.push("");
90
+ lines.push(chalk.gray(" # Create a new workspace"));
91
+ lines.push(chalk.white(" $ akan create-workspace myproject"));
92
+ lines.push("");
93
+ lines.push(chalk.gray(" # Start development server"));
94
+ lines.push(chalk.white(" $ akan start myapp"));
95
+ lines.push("");
96
+ lines.push(chalk.gray(" # Create a new module"));
97
+ lines.push(chalk.white(" $ akan create-module userProfile"));
98
+ lines.push("");
99
+ lines.push(chalk.gray(" Documentation: ") + chalk.cyan("https://akanjs.com/docs"));
100
+ lines.push(chalk.gray(" Report issues: ") + chalk.cyan("https://github.com/akan-team/akanjs/issues"));
101
+ lines.push("");
102
+ return lines.join("\n");
103
+ };
104
+ const formatCommandHelp = (command, key) => {
105
+ const [allArgMetas, argMetas] = getArgMetas(command, key);
106
+ const kebabKey = camelToKebabCase(key);
107
+ const lines = [];
108
+ const targetMetas = getTargetMetas(command);
109
+ const targetMeta = targetMetas.find((t) => t.key === key);
110
+ const commandDesc = targetMeta?.targetOption.desc;
111
+ lines.push("");
112
+ lines.push(chalk.bold.cyan(` Command: ${kebabKey}`));
113
+ if (commandDesc) {
114
+ lines.push(chalk.gray(` ${commandDesc}`));
115
+ }
116
+ lines.push("");
117
+ const args = allArgMetas.filter((arg) => arg.type !== "Option").map((arg) => {
118
+ if (arg.type === "Workspace")
119
+ return "";
120
+ if (arg.type === "Module")
121
+ return "[sys:module]";
122
+ if (arg.type === "Argument") {
123
+ return `[${camelToKebabCase(arg.name)}]`;
124
+ }
125
+ return `[${arg.type.toLowerCase()}]`;
126
+ }).filter(Boolean).join(" ");
127
+ lines.push(chalk.bold.yellow(" USAGE"));
128
+ lines.push("");
129
+ lines.push(chalk.gray(" $ ") + chalk.white(`akan ${kebabKey}`) + (args ? chalk.gray(` ${args}`) : ""));
130
+ lines.push("");
131
+ const nonOptionArgs = allArgMetas.filter((arg) => arg.type !== "Option");
132
+ if (nonOptionArgs.length > 0) {
133
+ lines.push(chalk.bold.yellow(" ARGUMENTS"));
134
+ lines.push("");
135
+ for (const arg of nonOptionArgs) {
136
+ if (arg.type === "Workspace")
137
+ continue;
138
+ let argName;
139
+ let argDesc;
140
+ let example = "";
141
+ if (arg.type === "Argument") {
142
+ argName = camelToKebabCase(arg.name);
143
+ argDesc = arg.argsOption.desc ?? "";
144
+ example = arg.argsOption.example ? chalk.gray(` (e.g., ${String(arg.argsOption.example)})`) : "";
145
+ } else if (arg.type === "Module") {
146
+ argName = "sys:module";
147
+ argDesc = "Module in format: app-name:module-name or lib-name:module-name";
148
+ } else {
149
+ argName = arg.type.toLowerCase();
150
+ argDesc = `${arg.type} name in this workspace`;
151
+ }
152
+ lines.push(` ${chalk.green(argName)} ${chalk.gray(argDesc)}${example}`);
153
+ }
154
+ lines.push("");
155
+ }
156
+ const optionArgs = argMetas.filter((a) => a.type === "Option");
157
+ if (optionArgs.length > 0) {
158
+ lines.push(chalk.bold.yellow(" OPTIONS"));
159
+ lines.push("");
160
+ for (const arg of optionArgs) {
161
+ const opt = arg.argsOption;
162
+ const flag = opt.flag ? `-${opt.flag}, ` : "";
163
+ const kebabName = camelToKebabCase(arg.name);
164
+ const optName = `${flag}--${kebabName}`;
165
+ const optDesc = opt.desc ?? "";
166
+ const defaultVal = opt.default !== void 0 ? chalk.gray(` [default: ${String(opt.default)}]`) : "";
167
+ const choices = opt.enum ? chalk.gray(` (${opt.enum.join(", ")})`) : "";
168
+ lines.push(` ${chalk.green(optName)} ${chalk.gray(optDesc)}${defaultVal}${choices}`);
169
+ }
170
+ lines.push("");
171
+ }
172
+ return lines.join("\n");
173
+ };
174
+ export {
175
+ formatCommandHelp,
176
+ formatHelp
177
+ };
@@ -2,4 +2,5 @@ export * from "./argMeta";
2
2
  export * from "./commandMeta";
3
3
  export * from "./targetMeta";
4
4
  export * from "./types";
5
+ export * from "./helpFormatter";
5
6
  export * from "./command";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/devkit",
3
- "version": "1.0.7-canary.5",
3
+ "version": "1.0.8",
4
4
  "sourceType": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -28,7 +28,7 @@
28
28
  "dotenv": "^16.4.7",
29
29
  "esbuild": "^0.19.2",
30
30
  "esbuild-plugin-d.ts": "^1.3.1",
31
- "eslint": "^9.19.0",
31
+ "eslint": "^9.0.0",
32
32
  "form-data": "^4.0.1",
33
33
  "ignore": "^7.0.5",
34
34
  "ink": "^6.1.0",
@@ -0,0 +1,3 @@
1
+ import type { Type } from "./types";
2
+ export declare const formatHelp: (commands: Type[], version: string) => string;
3
+ export declare const formatCommandHelp: (command: Type, key: string) => string;
@@ -2,4 +2,5 @@ export * from "./argMeta";
2
2
  export * from "./commandMeta";
3
3
  export * from "./targetMeta";
4
4
  export * from "./types";
5
+ export * from "./helpFormatter";
5
6
  export * from "./command";
@@ -9,6 +9,7 @@ interface TargetOption {
9
9
  type: "public" | "cloud" | "dev";
10
10
  short?: string | true;
11
11
  devOnly?: boolean;
12
+ desc?: string;
12
13
  }
13
14
  export declare const Target: {
14
15
  Public: (targetOption?: Omit<TargetOption, "type">) => (prototype: object, key: string, descriptor: PropertyDescriptor) => void;