@kosdev-code/kos-ui-cli 2.0.43 → 2.0.45

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.
@@ -27,21 +27,39 @@ export const metadata = {
27
27
  parentAware: "parentAware",
28
28
  singleton: "singleton",
29
29
  dataServices: "dataServices",
30
+ autoRegister: "autoRegister",
30
31
  dryRun: "dryRun",
31
32
  interactive: "interactive",
32
33
  },
33
34
  };
34
35
 
35
36
  export default async function (plop) {
36
- const allModels = await getAllModels();
37
37
  const libraryProjects = await getModelProjectsWithFallback();
38
- const modelChoices = allModels.map((m) => ({
39
- name: `${m.model} (${m.project})`,
40
- value: m.model,
41
- }));
38
+
39
+ // Check if we're in interactive mode by looking at process args
40
+ const isInteractive = process.argv.includes('-i') || process.argv.includes('--interactive');
41
+
42
+ // For interactive mode, use lazy loading. For non-interactive, load immediately.
43
+ let modelChoices;
44
+ if (isInteractive) {
45
+ modelChoices = async () => {
46
+ const allModels = await getAllModels();
47
+ return allModels.map((m) => ({
48
+ name: `${m.model} (${m.project})`,
49
+ value: m.model,
50
+ }));
51
+ };
52
+ } else {
53
+ const allModels = await getAllModels();
54
+ modelChoices = allModels.map((m) => ({
55
+ name: `${m.model} (${m.project})`,
56
+ value: m.model,
57
+ }));
58
+ }
42
59
 
43
60
  plop.setActionType("createCompanionModel", async function (answers) {
44
61
  const modelProject = await getProjectDetails(answers.modelProject);
62
+ const allModels = await getAllModels();
45
63
  const companionProject = allModels.find(
46
64
  (m) => m.model === answers.companionParent
47
65
  )?.project;
@@ -54,6 +72,7 @@ export default async function (plop) {
54
72
  --dataServices=${!!answers.dataServices} \
55
73
  --singleton=${!!answers.singleton} \
56
74
  --parentAware=${!!answers.parentAware} \
75
+ --autoRegister=${!!answers.autoRegister} \
57
76
  --companion=true \
58
77
  --companionModel=${answers.companionParent} \
59
78
  --companionModelProject=${companionProject} \
@@ -18,20 +18,38 @@ export const metadata = {
18
18
  parentAware: "parentAware",
19
19
  singleton: "singleton",
20
20
  dataServices: "dataServices",
21
+ autoRegister: "autoRegister",
21
22
  dryRun: "dryRun",
22
23
  interactive: "interactive",
23
24
  },
24
25
  };
25
26
 
26
27
  export default async function (plop) {
27
- const allModels = await getAllModels();
28
28
  const allProjects = await getAllProjects();
29
- const modelChoices = allModels.map((m) => ({
30
- name: `${m.model} (${m.project})`,
31
- value: m.model,
32
- }));
29
+
30
+ // Check if we're in interactive mode by looking at process args
31
+ const isInteractive = process.argv.includes('-i') || process.argv.includes('--interactive');
32
+
33
+ // For interactive mode, use lazy loading. For non-interactive, load immediately.
34
+ let modelChoices;
35
+ if (isInteractive) {
36
+ modelChoices = async () => {
37
+ const allModels = await getAllModels();
38
+ return allModels.map((m) => ({
39
+ name: `${m.model} (${m.project})`,
40
+ value: m.model,
41
+ }));
42
+ };
43
+ } else {
44
+ const allModels = await getAllModels();
45
+ modelChoices = allModels.map((m) => ({
46
+ name: `${m.model} (${m.project})`,
47
+ value: m.model,
48
+ }));
49
+ }
33
50
 
34
51
  plop.setActionType("createContainer", async function (answers) {
52
+ const allModels = await getAllModels();
35
53
  const modelProject = allModels.find(
36
54
  (m) => m.model === answers.modelName
37
55
  )?.project;
@@ -43,6 +61,7 @@ export default async function (plop) {
43
61
  --skipRegistration=true \
44
62
  --dataServices=${!!answers.dataServices} \
45
63
  --singleton=${!!answers.singleton} \
64
+ --autoRegister=${!!answers.autoRegister} \
46
65
  --no-interactive ${answers.dryRun ? "--dryRun" : ""} --verbose`;
47
66
 
48
67
  try {
@@ -14,13 +14,30 @@ export const metadata = {
14
14
 
15
15
  export default async function (plop) {
16
16
  const allProjects = await getAllProjects();
17
- const allModels = await getAllModels();
18
- const modelChoices = allModels.map((m) => ({
19
- name: `${m.model} (${m.project})`,
20
- value: m.model,
21
- }));
17
+
18
+ // Check if we're in interactive mode by looking at process args
19
+ const isInteractive = process.argv.includes('-i') || process.argv.includes('--interactive');
20
+
21
+ // For interactive mode, use lazy loading. For non-interactive, load immediately.
22
+ let modelChoices;
23
+ if (isInteractive) {
24
+ modelChoices = async () => {
25
+ const allModels = await getAllModels();
26
+ return allModels.map((m) => ({
27
+ name: `${m.model} (${m.project})`,
28
+ value: m.model,
29
+ }));
30
+ };
31
+ } else {
32
+ const allModels = await getAllModels();
33
+ modelChoices = allModels.map((m) => ({
34
+ name: `${m.model} (${m.project})`,
35
+ value: m.model,
36
+ }));
37
+ }
22
38
 
23
39
  plop.setActionType("createContext", async function (answers) {
40
+ const allModels = await getAllModels();
24
41
  const modelProject = allModels.find(
25
42
  (m) => m.model === answers.modelName
26
43
  )?.project;
@@ -14,13 +14,30 @@ export const metadata = {
14
14
 
15
15
  export default async function (plop) {
16
16
  const allProjects = await getAllProjects();
17
- const allModels = await getAllModels();
18
- const modelChoices = allModels.map((m) => ({
19
- name: `${m.model} (${m.project})`,
20
- value: m.model,
21
- }));
17
+
18
+ // Check if we're in interactive mode by looking at process args
19
+ const isInteractive = process.argv.includes('-i') || process.argv.includes('--interactive');
20
+
21
+ // For interactive mode, use lazy loading. For non-interactive, load immediately.
22
+ let modelChoices;
23
+ if (isInteractive) {
24
+ modelChoices = async () => {
25
+ const allModels = await getAllModels();
26
+ return allModels.map((m) => ({
27
+ name: `${m.model} (${m.project})`,
28
+ value: m.model,
29
+ }));
30
+ };
31
+ } else {
32
+ const allModels = await getAllModels();
33
+ modelChoices = allModels.map((m) => ({
34
+ name: `${m.model} (${m.project})`,
35
+ value: m.model,
36
+ }));
37
+ }
22
38
 
23
39
  plop.setActionType("createHook", async function (answers) {
40
+ const allModels = await getAllModels();
24
41
  const modelProject = allModels.find(
25
42
  (m) => m.model === answers.modelName
26
43
  )?.project;
@@ -15,13 +15,14 @@ export const metadata = {
15
15
  namedArguments: {
16
16
  name: "modelName",
17
17
  modelName: "modelName",
18
- project: "modelProject",
18
+ project: "modelProject",
19
19
  modelProject: "modelProject",
20
20
  container: "container",
21
21
  parentAware: "parentAware",
22
22
  singleton: "singleton",
23
23
  dataServices: "dataServices",
24
24
  futureAware: "futureAware",
25
+ autoRegister: "autoRegister",
25
26
  dryRun: "dryRun",
26
27
  interactive: "interactive"
27
28
  }
@@ -41,6 +42,7 @@ export default async function (plop) {
41
42
  --singleton=${!!answers.singleton} \
42
43
  --parentAware=${!!answers.parentAware} \
43
44
  --futureAware=${answers.futureAware || 'none'} \
45
+ --autoRegister=${!!answers.autoRegister} \
44
46
  --no-interactive ${answers.dryRun ? "--dryRun" : ""} --verbose`;
45
47
 
46
48
  try {
@@ -66,8 +66,8 @@ export const metadata = [
66
66
  componentProject: "componentProject"
67
67
  }
68
68
  },
69
- {
70
- key: "plugin:cp",
69
+ {
70
+ key: "plugin:cp",
71
71
  name: "KOS UI Plugin Control Pour",
72
72
  namedArguments: {
73
73
  name: "componentName",
@@ -76,6 +76,17 @@ export const metadata = [
76
76
  componentProject: "componentProject"
77
77
  }
78
78
  },
79
+ {
80
+ key: "plugin:custom",
81
+ name: "KOS UI Plugin Custom (User-Specified Contribution)",
82
+ namedArguments: {
83
+ name: "componentName",
84
+ componentName: "componentName",
85
+ project: "componentProject",
86
+ componentProject: "componentProject",
87
+ contributionKey: "contributionKey"
88
+ }
89
+ },
79
90
  ];
80
91
 
81
92
  export default async function (plop) {
@@ -84,7 +95,12 @@ export default async function (plop) {
84
95
  plop.setActionType("createPluginComponent", async function (answers) {
85
96
  const pluginType = answers.extensionPoint;
86
97
 
87
- const command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-component --name=${answers.componentName} --group=${answers.group} --appProject=${answers.componentProject} --pluginType=${pluginType} --type=components --no-interactive`;
98
+ let command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-component --name=${answers.componentName} --group=${answers.group} --appProject=${answers.componentProject} --pluginType=${pluginType} --type=components --no-interactive`;
99
+
100
+ // Add contributionKey for custom plugin types
101
+ if (pluginType === 'custom' && answers.contributionKey) {
102
+ command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-component --name=${answers.componentName} --contributionKey=${answers.contributionKey} --appProject=${answers.componentProject} --pluginType=${pluginType} --type=components --no-interactive`;
103
+ }
88
104
 
89
105
  try {
90
106
  await execute(command);
@@ -116,6 +132,7 @@ export default async function (plop) {
116
132
  { key: "plugin:setting", name: "setting" },
117
133
  { key: "plugin:nav", name: "nav" },
118
134
  { key: "plugin:cp", name: "controlPour" },
135
+ { key: "plugin:custom", name: "custom" },
119
136
  ];
120
137
 
121
138
  // Generic plugin component
@@ -146,6 +163,16 @@ export default async function (plop) {
146
163
  },
147
164
  ]
148
165
  : []),
166
+ ...(name === "custom"
167
+ ? [
168
+ {
169
+ type: "input",
170
+ name: "contributionKey",
171
+ message: "What contribution key should be used in .kos.json? (e.g., 'menus', 'panels', 'commands', etc.)",
172
+ validate: required,
173
+ },
174
+ ]
175
+ : []),
149
176
  {
150
177
  type: "input",
151
178
  name: "extensionPoint",
@@ -0,0 +1,74 @@
1
+ // generators/serve/index.mjs
2
+ import { execSync } from "child_process";
3
+ import { detectWorkspace } from "../../utils/nx-context.mjs";
4
+
5
+ export const metadata = {
6
+ key: "serve",
7
+ name: "Run Serve Target",
8
+ namedArguments: {
9
+ project: "project",
10
+ interactive: "interactive"
11
+ },
12
+ };
13
+
14
+ async function getProjectsWithTarget(target) {
15
+ try {
16
+ const output = execSync(`npx nx show projects --with-target ${target} --json`, {
17
+ encoding: "utf-8",
18
+ stdio: ["pipe", "pipe", "ignore"]
19
+ });
20
+ return JSON.parse(output);
21
+ } catch (error) {
22
+ return [];
23
+ }
24
+ }
25
+
26
+ export default async function (plop) {
27
+ const projects = await getProjectsWithTarget("serve");
28
+
29
+ if (projects.length === 0) {
30
+ console.warn("[kos-cli] No projects found with serve target");
31
+ // Still register the generator but it will fail gracefully
32
+ }
33
+
34
+ plop.setActionType("runServe", async function (answers) {
35
+ const isWorkspace = await detectWorkspace();
36
+
37
+ if (!isWorkspace) {
38
+ console.warn(
39
+ "[kos-cli] Not inside an Nx workspace. Cannot run serve target."
40
+ );
41
+ return "Skipped: Not a workspace";
42
+ }
43
+
44
+ const { project } = answers;
45
+
46
+ console.log(`[kos-cli] Running serve on ${project}...`);
47
+ try {
48
+ // Run serve in foreground with stdio inherited so it stays alive
49
+ execSync(`npx nx run ${project}:serve`, {
50
+ stdio: "inherit",
51
+ });
52
+ return `Serve completed for ${project}`;
53
+ } catch (error) {
54
+ // Don't throw error for Ctrl+C or normal termination
55
+ if (error.signal === "SIGINT") {
56
+ return `Serve terminated for ${project}`;
57
+ }
58
+ throw new Error(`Failed to run serve on ${project}: ${error.message}`);
59
+ }
60
+ });
61
+
62
+ plop.setGenerator("serve", {
63
+ description: "Run the serve target on a project",
64
+ prompts: [
65
+ {
66
+ type: "list",
67
+ name: "project",
68
+ message: "Select a project to serve:",
69
+ choices: projects,
70
+ },
71
+ ],
72
+ actions: () => [{ type: "runServe" }],
73
+ });
74
+ }
@@ -0,0 +1,182 @@
1
+ // generators/version/index.mjs
2
+ import { execSync } from "child_process";
3
+ import { existsSync, readFileSync } from "fs";
4
+ import path from "path";
5
+ import { detectWorkspace } from "../../utils/nx-context.mjs";
6
+
7
+ export const metadata = {
8
+ key: "version",
9
+ name: "Display CLI and SDK Version Information",
10
+ namedArguments: { interactive: "interactive" },
11
+ };
12
+
13
+ function getPackageVersion(packagePath) {
14
+ try {
15
+ const packageJsonPath = path.join(packagePath, "package.json");
16
+ if (existsSync(packageJsonPath)) {
17
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
18
+ return packageJson.version || "unknown";
19
+ }
20
+ } catch (error) {
21
+ // Package not found
22
+ }
23
+ return null;
24
+ }
25
+
26
+ function findWorkspaceRoot(startDir = process.cwd()) {
27
+ let dir = startDir;
28
+ while (dir !== path.dirname(dir)) {
29
+ if (existsSync(path.join(dir, "nx.json"))) {
30
+ return dir;
31
+ }
32
+ dir = path.dirname(dir);
33
+ }
34
+ return null;
35
+ }
36
+
37
+ function getCliVersion() {
38
+ let version = null;
39
+
40
+ // Option 1: Check workspace root package.json for installed CLI
41
+ const workspaceRoot = findWorkspaceRoot();
42
+ if (workspaceRoot) {
43
+ try {
44
+ const output = execSync(
45
+ "npm list @kosdev-code/kos-ui-cli --depth=0 --json",
46
+ {
47
+ cwd: workspaceRoot,
48
+ encoding: "utf-8",
49
+ stdio: ["pipe", "pipe", "ignore"],
50
+ }
51
+ );
52
+ const data = JSON.parse(output);
53
+ version = data?.dependencies?.["@kosdev-code/kos-ui-cli"]?.version;
54
+ } catch (error) {
55
+ // Not in workspace dependencies
56
+ }
57
+ }
58
+
59
+ // Option 2: Check global installation
60
+ if (!version) {
61
+ try {
62
+ const output = execSync(
63
+ "npm list -g @kosdev-code/kos-ui-cli --depth=0 --json",
64
+ {
65
+ encoding: "utf-8",
66
+ stdio: ["pipe", "pipe", "ignore"],
67
+ }
68
+ );
69
+ const data = JSON.parse(output);
70
+ version = data?.dependencies?.["@kosdev-code/kos-ui-cli"]?.version;
71
+ } catch (error) {
72
+ // Not installed globally
73
+ }
74
+ }
75
+
76
+ return version || "unknown";
77
+ }
78
+
79
+ export default async function (plop) {
80
+ plop.setActionType("showVersions", async function () {
81
+ console.log("[kos-cli] Discovering version information...\n");
82
+
83
+ const isWorkspace = await detectWorkspace();
84
+ const workspaceRoot = findWorkspaceRoot();
85
+
86
+ const versions = {};
87
+
88
+ // Get CLI version
89
+ versions.cli = getCliVersion();
90
+
91
+ if (isWorkspace && workspaceRoot) {
92
+ // Get SDK versions from workspace dependencies
93
+ const sdkPackages = {
94
+ sdk: ["@kosdev-code/kos-ui-sdk", "@kosdev-code/kos-dispense-sdk"],
95
+ ddk: [
96
+ "@kosdev-code/kos-ddk-components",
97
+ "@kosdev-code/kos-ddk-model-components",
98
+ ],
99
+ };
100
+
101
+ for (const [type, packages] of Object.entries(sdkPackages)) {
102
+ for (const pkgName of packages) {
103
+ try {
104
+ const output = execSync(`npm list ${pkgName} --depth=0 --json`, {
105
+ cwd: workspaceRoot,
106
+ encoding: "utf-8",
107
+ stdio: ["pipe", "pipe", "ignore"],
108
+ });
109
+ const data = JSON.parse(output);
110
+ const version = data?.dependencies?.[pkgName]?.version;
111
+ if (version) {
112
+ // Store with short name (without @kosdev-code/ prefix)
113
+ const shortName = pkgName.replace("@kosdev-code/", "");
114
+ versions[shortName] = version;
115
+ }
116
+ } catch (error) {
117
+ // Package not installed in workspace
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ // Display results
124
+ console.log("Version Information:");
125
+ console.log("===================\n");
126
+
127
+ if (versions.cli) {
128
+ console.log(`kos-ui-cli: ${versions.cli}`);
129
+ } else {
130
+ console.log("kos-ui-cli: unknown");
131
+ }
132
+
133
+ if (isWorkspace) {
134
+ console.log("");
135
+ console.log("SDK Packages:");
136
+ console.log("-------------");
137
+
138
+ if (versions["kos-ui-sdk"]) {
139
+ console.log(`kos-ui-sdk: ${versions["kos-ui-sdk"]}`);
140
+ }
141
+
142
+ if (versions["kos-dispense-sdk"]) {
143
+ console.log(`kos-dispense-sdk: ${versions["kos-dispense-sdk"]}`);
144
+ }
145
+
146
+ console.log("");
147
+ console.log("DDK Packages:");
148
+ console.log("-------------");
149
+
150
+ if (versions["kos-ddk-components"]) {
151
+ console.log(`kos-ddk-components: ${versions["kos-ddk-components"]}`);
152
+ }
153
+
154
+ if (versions["kos-ddk-model-components"]) {
155
+ console.log(
156
+ `kos-ddk-model-components: ${versions["kos-ddk-model-components"]}`
157
+ );
158
+ }
159
+
160
+ if (!versions["kos-ui-sdk"] && !versions["kos-dispense-sdk"]) {
161
+ console.log("(No SDK packages found in workspace)");
162
+ }
163
+
164
+ if (
165
+ !versions["kos-ddk-components"] &&
166
+ !versions["kos-ddk-model-components"]
167
+ ) {
168
+ console.log("(No DDK packages found in workspace)");
169
+ }
170
+ } else {
171
+ console.log("\n(Not in workspace - SDK versions unavailable)");
172
+ }
173
+
174
+ return "\n";
175
+ });
176
+
177
+ plop.setGenerator("version", {
178
+ description: "Display CLI and SDK version information",
179
+ prompts: [],
180
+ actions: () => [{ type: "showVersions" }],
181
+ });
182
+ }
@@ -1,5 +1,5 @@
1
1
  // generators/workspace/index.mjs
2
- import { createWorkspace } from "create-nx-workspace";
2
+ // Note: create-nx-workspace is imported lazily to avoid dependency errors
3
3
  import { required } from "../../utils/validators.mjs";
4
4
  import registerListModels from "./list-models.mjs";
5
5
  import registerListProjects from "./list-projects.mjs";
@@ -9,14 +9,18 @@ export const metadata = {
9
9
  name: "Create a new KOS UI Workspace",
10
10
  namedArguments: {
11
11
  name: "workspaceName",
12
- workspaceName: "workspaceName"
12
+ workspaceName: "workspaceName",
13
+ enablePlugins: "enablePlugins"
13
14
  }
14
15
  };
15
16
  export default async function (plop) {
16
17
  plop.setActionType("createWorkspace", async function (answers) {
18
+ // Lazy import to avoid dependency errors when not using workspace generator
19
+ const { createWorkspace } = await import("create-nx-workspace");
17
20
  await createWorkspace("@kosdev-code/kos-nx-plugin", {
18
21
  nxCloud: "skip",
19
22
  name: answers.workspaceName,
23
+ enablePlugins: answers.enablePlugins,
20
24
  });
21
25
  return `Workspace ${answers.workspaceName} created.`;
22
26
  });
@@ -30,10 +34,16 @@ export default async function (plop) {
30
34
  message: "Enter the workspace name",
31
35
  validate: required,
32
36
  },
37
+ {
38
+ type: "confirm",
39
+ name: "enablePlugins",
40
+ message: "Do you want to enable plugin support?",
41
+ default: true,
42
+ },
33
43
  ],
34
44
  actions: () => [{ type: "createWorkspace" }],
35
45
  });
36
-
46
+
37
47
  // Register additional workspace generators
38
48
  await registerListModels(plop);
39
49
  await registerListProjects(plop);
@@ -12,8 +12,14 @@ import registerKosModel from "./generators/model/model.mjs";
12
12
  import registerComponent from "./generators/component/index.mjs";
13
13
  import registerPluginComponent from "./generators/plugin/index.mjs";
14
14
 
15
+ import registerApiGenerate from "./generators/api/generate.mjs";
16
+ import registerApiCompare from "./generators/api/compare.mjs";
15
17
  import registerCacheGenerators from "./generators/cache/index.mjs";
18
+ import registerDev from "./generators/dev/index.mjs";
16
19
  import registerEnv from "./generators/env/index.mjs";
20
+ import registerKab from "./generators/kab/index.mjs";
21
+ import registerServe from "./generators/serve/index.mjs";
22
+ import registerVersion from "./generators/version/index.mjs";
17
23
  import registerI18nNamespace from "./generators/i18n/namespace.mjs";
18
24
  import registerUiProject from "./generators/project/app.mjs";
19
25
  import registerContentProject from "./generators/project/content.mjs";
@@ -56,6 +62,12 @@ export default async function (plop) {
56
62
  await registerSplashProject(plop);
57
63
  await registerI18n(plop);
58
64
  await registerI18nNamespace(plop);
65
+ await registerApiGenerate(plop);
66
+ await registerApiCompare(plop);
67
+ await registerDev(plop);
59
68
  await registerEnv(plop);
69
+ await registerKab(plop);
70
+ await registerServe(plop);
71
+ await registerVersion(plop);
60
72
  await registerCacheGenerators(plop);
61
73
  }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * CLI help display utilities
3
+ *
4
+ * High-level help display functions for the KOS CLI. Coordinates the display
5
+ * of generator-specific help and general CLI help using utilities from
6
+ * cli-help-utils.mjs.
7
+ *
8
+ * @module cli-help-display
9
+ */
10
+ import { displayExamples, displayNamedArguments } from "./cli-help-utils.mjs";
11
+
12
+ /**
13
+ * Display comprehensive help information for a specific generator.
14
+ *
15
+ * Shows the generator's name, description, named arguments mapping, and
16
+ * usage examples. This provides users with all the information needed to
17
+ * use a specific CLI command effectively.
18
+ *
19
+ * @param {string} command - The command name (e.g., 'model', 'api:generate')
20
+ * @param {Object} meta - Generator metadata from the generator's export
21
+ * @param {string} meta.name - Display name for the generator
22
+ * @param {string} meta.description - Brief description of what the generator does
23
+ * @param {Object} meta.namedArguments - Mapping of CLI args to prompt names
24
+ * @param {Object} [generator=null] - Optional plop generator object (fallback for metadata)
25
+ *
26
+ * @example
27
+ * displayGeneratorHelp('api:generate', {
28
+ * name: 'Generate OpenAPI service types',
29
+ * description: 'Generate typed service helpers from OpenAPI specifications',
30
+ * namedArguments: { project: 'project', host: 'host' }
31
+ * })
32
+ */
33
+ export function displayGeneratorHelp(command, meta, generator = null) {
34
+ console.log(`--- ${meta?.name || command} Help ---`);
35
+ console.log(
36
+ meta?.description || generator?.description || "No description available"
37
+ );
38
+
39
+ displayNamedArguments(meta?.namedArguments);
40
+ displayExamples(command, meta?.namedArguments);
41
+ }
42
+
43
+ /**
44
+ * Display general CLI help showing all available generators and global options.
45
+ *
46
+ * Outputs a comprehensive overview of the KOS CLI including:
47
+ * - List of all available generators with descriptions
48
+ * - General usage pattern
49
+ * - Global options that apply to all commands
50
+ * - Help invocation instructions
51
+ *
52
+ * This is displayed when users run `kosui --help` or `kosui` with no command.
53
+ *
54
+ * @param {Object} plop - The plop instance containing registered generators
55
+ *
56
+ * @example
57
+ * displayGeneralHelp(plopInstance)
58
+ * // Outputs:
59
+ * // --- KOS CLI Help ---
60
+ * //
61
+ * // Available Generators:
62
+ * // - model: Generate KOS models
63
+ * // - api:generate: Generate OpenAPI service types
64
+ * // ...
65
+ */
66
+ export function displayGeneralHelp(plop) {
67
+ console.warn("--- KOS CLI Help ---");
68
+ console.log("\nAvailable Generators:");
69
+ plop.getGeneratorList().forEach((g) => {
70
+ console.log(`- ${g.name}: ${g.description}`);
71
+ });
72
+
73
+ console.log("\nUsage:");
74
+ console.log(" kosui <generator> [options]");
75
+ console.log(" kosui <generator> --help # Show generator-specific help");
76
+ console.log("\nGlobal Options:");
77
+ console.log(" --no-cache Disable cache");
78
+ console.log(" --refresh Clear cache and refresh");
79
+ console.log(" --quiet Suppress banner and debug output");
80
+ console.log(
81
+ " --interactive, -i Force interactive mode (ignore provided arguments)"
82
+ );
83
+ console.log(" --help Show this help");
84
+ }