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

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.
@@ -1,182 +0,0 @@
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,84 +0,0 @@
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
- }
@@ -1,261 +0,0 @@
1
- /**
2
- * Utility functions for CLI help generation
3
- *
4
- * Provides intelligent help generation for KOS CLI commands including:
5
- * - Example value generation based on argument types and names
6
- * - Relevant argument filtering for concise examples
7
- * - Command-line example generation with proper formatting
8
- * - Named argument documentation display
9
- *
10
- * @module cli-help-utils
11
- */
12
-
13
- /**
14
- * Generate example values for command-line arguments based on argument names.
15
- *
16
- * Uses heuristics to determine appropriate example values based on the argument
17
- * name and command context. Provides realistic examples for common patterns like
18
- * names, projects, and boolean flags.
19
- *
20
- * @param {string} argName - The argument name (e.g., 'name', 'project', 'singleton')
21
- * @param {string} command - The command name for context (e.g., 'model', 'api:generate')
22
- * @returns {string|boolean} Example value appropriate for the argument type
23
- *
24
- * @example
25
- * generateExampleValue('name', 'model') // Returns 'MyComponent'
26
- * generateExampleValue('singleton', 'model') // Returns true
27
- * generateExampleValue('project', 'api:generate') // Returns 'my-ui-lib'
28
- */
29
- export function generateExampleValue(argName, command) {
30
- switch (argName) {
31
- case "name":
32
- case "componentName":
33
- return command.includes("plugin") ? "MyPlugin" : "MyComponent";
34
- case "modelName":
35
- return "my-model";
36
- case "workspaceName":
37
- return "my-workspace";
38
- case "project":
39
- case "componentProject":
40
- case "modelProject":
41
- return "my-ui-lib";
42
- case "registrationProject":
43
- return "my-lib";
44
- case "companionParent":
45
- return "parent-model";
46
- case "extensionPoint":
47
- return "utility";
48
- case "group":
49
- return "appearance";
50
- case "locale":
51
- return "en";
52
- case "container":
53
- case "singleton":
54
- case "parentAware":
55
- case "dataServices":
56
- return true;
57
- case "dryRun":
58
- return true;
59
- default:
60
- return `my-${argName}`;
61
- }
62
- }
63
-
64
- /**
65
- * Filter and prioritize arguments for concise help examples.
66
- *
67
- * Selects the most relevant arguments to display in help examples by prioritizing:
68
- * 1. Name-type arguments (name, componentName, modelName, workspaceName)
69
- * 2. Project-type arguments (project, componentProject, modelProject)
70
- * 3. Other non-boolean arguments (up to 2 additional)
71
- *
72
- * Boolean flags are excluded from this list and handled separately.
73
- *
74
- * @param {string[]} args - All available argument names from the generator
75
- * @param {string} command - The command name for context
76
- * @returns {string[]} Filtered list of most relevant arguments to show (typically 2-4 items)
77
- *
78
- * @example
79
- * getRelevantArgs(['name', 'project', 'singleton', 'dryRun'], 'model')
80
- * // Returns ['name', 'project']
81
- */
82
- export function getRelevantArgs(args, command) {
83
- const relevantArgs = [];
84
-
85
- const booleanArgs = [
86
- "container",
87
- "singleton",
88
- "parentAware",
89
- "dataServices",
90
- "dryRun",
91
- ];
92
-
93
- // Always prefer name-type arguments first
94
- const nameArgs = [
95
- "name",
96
- "componentName",
97
- "modelName",
98
- "workspaceName",
99
- ].filter((arg) => args.includes(arg));
100
- if (nameArgs.length > 0) {
101
- relevantArgs.push(nameArgs[0]); // Take the first name argument
102
- }
103
-
104
- // Then add project-type arguments
105
- const projectArgs = [
106
- "project",
107
- "componentProject",
108
- "modelProject",
109
- "registrationProject",
110
- ].filter((arg) => args.includes(arg));
111
- if (projectArgs.length > 0) {
112
- relevantArgs.push(projectArgs[0]); // Take the first project argument
113
- }
114
-
115
- // Add other specific arguments
116
- const otherArgs = args.filter(
117
- (arg) =>
118
- !nameArgs.includes(arg) &&
119
- !projectArgs.includes(arg) &&
120
- !booleanArgs.includes(arg) &&
121
- arg !== "interactive"
122
- );
123
-
124
- // Add up to 2 more relevant arguments
125
- relevantArgs.push(...otherArgs.slice(0, 2));
126
-
127
- return relevantArgs;
128
- }
129
-
130
- /**
131
- * Generate command-line examples for a generator with proper formatting.
132
- *
133
- * Creates multiple example commands showing:
134
- * - Basic usage with most relevant arguments
135
- * - Advanced usage with boolean flags
136
- * - Interactive mode invocation (both long and short form)
137
- *
138
- * Examples are formatted ready for terminal display with proper indentation.
139
- *
140
- * @param {string} command - The command name (e.g., 'model', 'api:generate')
141
- * @param {Object} namedArguments - Mapping of CLI argument names to prompt names
142
- * @returns {string[]} Array of formatted example command strings with leading spaces
143
- *
144
- * @example
145
- * generateCommandExamples('api:generate', { project: 'project', host: 'host' })
146
- * // Returns:
147
- * // [
148
- * // ' kosui api:generate --project my-ui-lib --host http://localhost',
149
- * // ' kosui api:generate --interactive # Force interactive mode',
150
- * // ' kosui api:generate -i # Force interactive mode (short form)'
151
- * // ]
152
- */
153
- export function generateCommandExamples(command, namedArguments) {
154
- if (!namedArguments) {
155
- return [` kosui ${command} [options]`];
156
- }
157
-
158
- const args = Object.keys(namedArguments);
159
- const examples = [];
160
-
161
- const booleanArgs = [
162
- "container",
163
- "singleton",
164
- "parentAware",
165
- "dataServices",
166
- "dryRun",
167
- ];
168
-
169
- const relevantArgs = getRelevantArgs(args, command);
170
-
171
- // Build basic example with most important arguments
172
- const basicArgs = [];
173
- relevantArgs.forEach((argName) => {
174
- const value = generateExampleValue(argName, command);
175
- basicArgs.push(`--${argName} ${value}`);
176
- });
177
-
178
- if (basicArgs.length > 0) {
179
- examples.push(` kosui ${command} ${basicArgs.join(" ")}`);
180
- }
181
-
182
- // Create advanced example with boolean flags
183
- const advancedBooleanArgs = [];
184
- booleanArgs.forEach((argName) => {
185
- if (args.includes(argName)) {
186
- advancedBooleanArgs.push(`--${argName}`);
187
- }
188
- });
189
-
190
- // Show advanced example with boolean flags if any exist
191
- if (basicArgs.length > 0 && advancedBooleanArgs.length > 0) {
192
- examples.push(
193
- ` kosui ${command} ${basicArgs
194
- .slice(0, 2)
195
- .join(" ")} ${advancedBooleanArgs.join(" ")}`
196
- );
197
- }
198
-
199
- // If no basic args, show a minimal example
200
- if (basicArgs.length === 0) {
201
- examples.push(` kosui ${command} [options]`);
202
- }
203
-
204
- // Always show interactive mode example
205
- examples.push(` kosui ${command} --interactive # Force interactive mode`);
206
- examples.push(
207
- ` kosui ${command} -i # Force interactive mode (short form)`
208
- );
209
-
210
- return examples;
211
- }
212
-
213
- /**
214
- * Display the named arguments help section to the console.
215
- *
216
- * Outputs a formatted table showing the mapping between CLI argument names
217
- * and their corresponding prompt names in the generator schema. This helps
218
- * users understand which CLI arguments map to which interactive prompts.
219
- *
220
- * @param {Object} namedArguments - Mapping of CLI argument names to prompt names
221
- * (e.g., { 'project': 'project', 'host': 'host' })
222
- *
223
- * @example
224
- * displayNamedArguments({ project: 'project', host: 'host' })
225
- * // Outputs:
226
- * // Named Arguments:
227
- * // --project Maps to prompt: project
228
- * // --host Maps to prompt: host
229
- */
230
- export function displayNamedArguments(namedArguments) {
231
- if (!namedArguments) return;
232
-
233
- console.log("\nNamed Arguments:");
234
- Object.entries(namedArguments).forEach(([cliArg, promptName]) => {
235
- console.log(` --${cliArg} Maps to prompt: ${promptName}`);
236
- });
237
- }
238
-
239
- /**
240
- * Display the examples help section to the console.
241
- *
242
- * Outputs formatted command-line examples showing various ways to invoke the
243
- * command, including basic usage, advanced usage with boolean flags, and
244
- * interactive mode shortcuts.
245
- *
246
- * @param {string} command - The command name (e.g., 'model', 'api:generate')
247
- * @param {Object} namedArguments - Mapping of CLI argument names to prompt names
248
- *
249
- * @example
250
- * displayExamples('api:generate', { project: 'project', host: 'host' })
251
- * // Outputs:
252
- * // Examples:
253
- * // kosui api:generate --project my-ui-lib --host http://localhost
254
- * // kosui api:generate --interactive # Force interactive mode
255
- * // kosui api:generate -i # Force interactive mode (short form)
256
- */
257
- export function displayExamples(command, namedArguments) {
258
- console.log("\nExamples:");
259
- const examples = generateCommandExamples(command, namedArguments);
260
- examples.forEach((example) => console.log(example));
261
- }
@@ -1,94 +0,0 @@
1
- /**
2
- * Builds a non-interactive command string from interactive session answers
3
- * This helps users understand how to run the same command without prompts
4
- */
5
-
6
- /**
7
- * Converts interactive prompt answers back to CLI command arguments
8
- * @param {string} command - The generator command name
9
- * @param {Object} answers - The answers collected from prompts
10
- * @param {Object} meta - Generator metadata including namedArguments mapping
11
- * @returns {string|null} The equivalent CLI command string, or null if cannot be built
12
- */
13
- export function buildNonInteractiveCommand(command, answers, meta) {
14
- if (!meta?.namedArguments) {
15
- return null;
16
- }
17
-
18
- const args = [`kosui ${command}`];
19
- const reverseMap = {};
20
-
21
- // Create reverse mapping from prompt names to CLI arguments
22
- Object.entries(meta.namedArguments).forEach(([cliArg, promptName]) => {
23
- // Skip special flags that don't map to prompts
24
- if (cliArg !== "interactive" && cliArg !== "dryRun") {
25
- reverseMap[promptName] = cliArg;
26
- }
27
- });
28
-
29
- // Build command arguments from answers
30
- Object.entries(answers).forEach(([promptName, value]) => {
31
- const cliArg = reverseMap[promptName];
32
- if (cliArg && value !== undefined && value !== null && value !== "") {
33
- args.push(formatArgument(cliArg, value));
34
- }
35
- });
36
-
37
- // Add dryRun if it was provided
38
- if (answers.dryRun) {
39
- args.push("--dryRun");
40
- }
41
-
42
- return args.join(" ");
43
- }
44
-
45
- /**
46
- * Formats a single CLI argument based on its value type
47
- * @param {string} argName - The CLI argument name
48
- * @param {any} value - The value for the argument
49
- * @returns {string} The formatted CLI argument string
50
- */
51
- function formatArgument(argName, value) {
52
- // Handle boolean values
53
- if (typeof value === "boolean") {
54
- if (value) {
55
- return `--${argName}`;
56
- } else {
57
- // For false booleans, explicitly set to false
58
- // This ensures the command can be replicated exactly
59
- return `--${argName}=false`;
60
- }
61
- }
62
-
63
- // Handle string/number values
64
- const stringValue = String(value);
65
-
66
- // Check if value needs escaping
67
- if (needsEscaping(stringValue)) {
68
- // Use double quotes and escape internal quotes
69
- return `--${argName}="${stringValue.replace(/"/g, '\\"')}"`;
70
- }
71
-
72
- return `--${argName}=${stringValue}`;
73
- }
74
-
75
- /**
76
- * Determines if a string value needs shell escaping
77
- * @param {string} value - The value to check
78
- * @returns {boolean} True if the value needs escaping
79
- */
80
- function needsEscaping(value) {
81
- // Check for characters that need escaping in shell
82
- return /[\s'"$`\\!]/.test(value);
83
- }
84
-
85
- /**
86
- * Determines if the CLI is running in interactive mode
87
- * @param {Object} parsedArgs - Parsed command line arguments
88
- * @param {boolean} hasAnyAnswers - Whether any answers were provided via CLI
89
- * @returns {boolean} True if running in interactive mode
90
- */
91
- export function isRunningInteractively(parsedArgs, hasAnyAnswers) {
92
- const forceInteractive = parsedArgs.interactive || parsedArgs.i;
93
- return forceInteractive || (!hasAnyAnswers && !parsedArgs.help);
94
- }