@nicolasmondain/cli-agent 2.1.0
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.
Potentially problematic release.
This version of @nicolasmondain/cli-agent might be problematic. Click here for more details.
- package/README.md +484 -0
- package/dist/cli/commands/list.command.d.ts +48 -0
- package/dist/cli/commands/list.command.d.ts.map +1 -0
- package/dist/cli/commands/list.command.js +87 -0
- package/dist/cli/commands/list.command.js.map +1 -0
- package/dist/cli/commands/mcp-manifest.command.d.ts +14 -0
- package/dist/cli/commands/mcp-manifest.command.d.ts.map +1 -0
- package/dist/cli/commands/mcp-manifest.command.js +87 -0
- package/dist/cli/commands/mcp-manifest.command.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +112 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/command/dynamic-command.factory.d.ts +16 -0
- package/dist/command/dynamic-command.factory.d.ts.map +1 -0
- package/dist/command/dynamic-command.factory.js +153 -0
- package/dist/command/dynamic-command.factory.js.map +1 -0
- package/dist/config/config-loader.d.ts +24 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +95 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config/config-schema.d.ts +73 -0
- package/dist/config/config-schema.d.ts.map +1 -0
- package/dist/config/config-schema.js +7 -0
- package/dist/config/config-schema.js.map +1 -0
- package/dist/config/config-validator.d.ts +20 -0
- package/dist/config/config-validator.d.ts.map +1 -0
- package/dist/config/config-validator.js +162 -0
- package/dist/config/config-validator.js.map +1 -0
- package/dist/executor/js-executor.d.ts +29 -0
- package/dist/executor/js-executor.d.ts.map +1 -0
- package/dist/executor/js-executor.js +77 -0
- package/dist/executor/js-executor.js.map +1 -0
- package/dist/executor/script-executor.d.ts +33 -0
- package/dist/executor/script-executor.d.ts.map +1 -0
- package/dist/executor/script-executor.js +45 -0
- package/dist/executor/script-executor.js.map +1 -0
- package/dist/executor/shell-executor.d.ts +33 -0
- package/dist/executor/shell-executor.d.ts.map +1 -0
- package/dist/executor/shell-executor.js +126 -0
- package/dist/executor/shell-executor.js.map +1 -0
- package/dist/executor/ts-executor.d.ts +33 -0
- package/dist/executor/ts-executor.d.ts.map +1 -0
- package/dist/executor/ts-executor.js +134 -0
- package/dist/executor/ts-executor.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/infra/logger.d.ts +42 -0
- package/dist/infra/logger.d.ts.map +1 -0
- package/dist/infra/logger.js +96 -0
- package/dist/infra/logger.js.map +1 -0
- package/dist/infra/output.d.ts +11 -0
- package/dist/infra/output.d.ts.map +1 -0
- package/dist/infra/output.js +70 -0
- package/dist/infra/output.js.map +1 -0
- package/dist/mcp/manifest-generator.d.ts +51 -0
- package/dist/mcp/manifest-generator.d.ts.map +1 -0
- package/dist/mcp/manifest-generator.js +130 -0
- package/dist/mcp/manifest-generator.js.map +1 -0
- package/dist/services/file-system.service.d.ts +53 -0
- package/dist/services/file-system.service.d.ts.map +1 -0
- package/dist/services/file-system.service.js +100 -0
- package/dist/services/file-system.service.js.map +1 -0
- package/dist/services/naming.service.d.ts +40 -0
- package/dist/services/naming.service.d.ts.map +1 -0
- package/dist/services/naming.service.js +86 -0
- package/dist/services/naming.service.js.map +1 -0
- package/dist/services/naming.service.test.d.ts +2 -0
- package/dist/services/naming.service.test.d.ts.map +1 -0
- package/dist/services/naming.service.test.js +99 -0
- package/dist/services/naming.service.test.js.map +1 -0
- package/dist/types/index.d.ts +51 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +14 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Manifest Command
|
|
3
|
+
*
|
|
4
|
+
* Built-in command that generates an MCP (Model Context Protocol) tool manifest
|
|
5
|
+
* from the cli-agent configuration. This enables native integration with
|
|
6
|
+
* Claude Code and other MCP-compatible clients.
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
import { writeFile } from 'node:fs/promises';
|
|
10
|
+
import { generateMcpManifestJson, generateMcpManifest } from '../../mcp/manifest-generator.js';
|
|
11
|
+
import { outputResult } from '../../infra/output.js';
|
|
12
|
+
/**
|
|
13
|
+
* Create the mcp:manifest command
|
|
14
|
+
*/
|
|
15
|
+
export function createMcpManifestCommand(config) {
|
|
16
|
+
const command = new Command('mcp:manifest');
|
|
17
|
+
command
|
|
18
|
+
.description('Generate MCP (Model Context Protocol) tool manifest from configuration')
|
|
19
|
+
.option('-o, --output <path>', 'Write manifest to file instead of stdout')
|
|
20
|
+
.option('--format <format>', 'Output format: human or json', 'human')
|
|
21
|
+
.action(async (options) => {
|
|
22
|
+
const format = options.format === 'json' ? 'json' : 'human';
|
|
23
|
+
if (!config) {
|
|
24
|
+
outputResult({
|
|
25
|
+
success: false,
|
|
26
|
+
error: 'No configuration found. Create a .cli-agent.json file to define commands.',
|
|
27
|
+
}, format);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (config.commands.length === 0) {
|
|
32
|
+
outputResult({
|
|
33
|
+
success: false,
|
|
34
|
+
error: 'No commands defined in configuration.',
|
|
35
|
+
}, format);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const manifestJson = generateMcpManifestJson(config);
|
|
41
|
+
if (options.output) {
|
|
42
|
+
// Write to file
|
|
43
|
+
await writeFile(options.output, manifestJson + '\n', 'utf-8');
|
|
44
|
+
if (format === 'json') {
|
|
45
|
+
const manifest = generateMcpManifest(config);
|
|
46
|
+
outputResult({
|
|
47
|
+
success: true,
|
|
48
|
+
message: `MCP manifest written to ${options.output}`,
|
|
49
|
+
data: {
|
|
50
|
+
path: options.output,
|
|
51
|
+
toolCount: manifest.tools.length,
|
|
52
|
+
},
|
|
53
|
+
}, format);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
console.log(`MCP manifest written to ${options.output}`);
|
|
57
|
+
console.log(`Contains ${config.commands.length} tool(s).`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// Output to stdout
|
|
62
|
+
if (format === 'json') {
|
|
63
|
+
// Wrap manifest in CommandResult for consistent JSON output
|
|
64
|
+
const manifest = generateMcpManifest(config);
|
|
65
|
+
outputResult({
|
|
66
|
+
success: true,
|
|
67
|
+
message: `Generated MCP manifest with ${manifest.tools.length} tool(s)`,
|
|
68
|
+
data: manifest,
|
|
69
|
+
}, format);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// Human format: just output the manifest JSON directly
|
|
73
|
+
console.log(manifestJson);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
outputResult({
|
|
79
|
+
success: false,
|
|
80
|
+
error: `Failed to generate manifest: ${error instanceof Error ? error.message : String(error)}`,
|
|
81
|
+
}, format);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return command;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=mcp-manifest.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-manifest.command.js","sourceRoot":"","sources":["../../../src/cli/commands/mcp-manifest.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Generic CLI wrapper that loads commands from external configuration.
|
|
6
|
+
* Designed for both human developers and AI agents (MCP compatible).
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from "commander";
|
|
9
|
+
import { loadConfig, getExplicitConfigPath } from "../config/config-loader.js";
|
|
10
|
+
import { createDynamicCommand } from "../command/dynamic-command.factory.js";
|
|
11
|
+
import { createListCommand } from "./commands/list.command.js";
|
|
12
|
+
import { createMcpManifestCommand } from "./commands/mcp-manifest.command.js";
|
|
13
|
+
import { logError, logDebug } from "../infra/logger.js";
|
|
14
|
+
// Package info
|
|
15
|
+
const VERSION = "2.0.0";
|
|
16
|
+
const DEFAULT_NAME = "cli-agent";
|
|
17
|
+
const DEFAULT_DESCRIPTION = "Generic CLI wrapper for executing external scripts";
|
|
18
|
+
/**
|
|
19
|
+
* Create and configure the main CLI program
|
|
20
|
+
*/
|
|
21
|
+
async function createProgram() {
|
|
22
|
+
const program = new Command();
|
|
23
|
+
// Try to load configuration
|
|
24
|
+
const explicitPath = getExplicitConfigPath();
|
|
25
|
+
const configResult = await loadConfig(explicitPath);
|
|
26
|
+
const config = configResult?.config ?? null;
|
|
27
|
+
if (configResult) {
|
|
28
|
+
const { config, configDir, configPath } = configResult;
|
|
29
|
+
program
|
|
30
|
+
.name(config.name ?? DEFAULT_NAME)
|
|
31
|
+
.description(config.description ?? DEFAULT_DESCRIPTION)
|
|
32
|
+
.version(config.version ?? VERSION, "-v, --version", "Output the current version");
|
|
33
|
+
// Register all commands from configuration
|
|
34
|
+
for (const commandConfig of config.commands) {
|
|
35
|
+
const command = createDynamicCommand(commandConfig, configDir);
|
|
36
|
+
program.addCommand(command);
|
|
37
|
+
}
|
|
38
|
+
logDebug("Loaded configuration", {
|
|
39
|
+
path: configPath,
|
|
40
|
+
commandCount: config.commands.length,
|
|
41
|
+
commands: config.commands.map((c) => c.name),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// No configuration found - show helpful message
|
|
46
|
+
program
|
|
47
|
+
.name(DEFAULT_NAME)
|
|
48
|
+
.description(DEFAULT_DESCRIPTION)
|
|
49
|
+
.version(VERSION, "-v, --version", "Output the current version");
|
|
50
|
+
program.addHelpText("after", `
|
|
51
|
+
No configuration file found. Create one of:
|
|
52
|
+
- .cli-agent.json in your project
|
|
53
|
+
- "cli-agent" field in package.json
|
|
54
|
+
- ~/.cli-agent.json for global commands
|
|
55
|
+
|
|
56
|
+
Example .cli-agent.json:
|
|
57
|
+
{
|
|
58
|
+
"name": "my-cli",
|
|
59
|
+
"commands": [
|
|
60
|
+
{
|
|
61
|
+
"name": "hello",
|
|
62
|
+
"description": "Say hello",
|
|
63
|
+
"script": "./scripts/hello.js",
|
|
64
|
+
"options": [
|
|
65
|
+
{ "flags": "-n, --name <name>", "description": "Name to greet" }
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
Example script (./scripts/hello.js):
|
|
72
|
+
export default async function(context) {
|
|
73
|
+
const name = context.options.name || 'World';
|
|
74
|
+
return {
|
|
75
|
+
success: true,
|
|
76
|
+
message: \`Hello, \${name}!\`
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
`);
|
|
80
|
+
}
|
|
81
|
+
// Add built-in commands (always available)
|
|
82
|
+
program.addCommand(createListCommand(config));
|
|
83
|
+
program.addCommand(createMcpManifestCommand(config));
|
|
84
|
+
// Add global options
|
|
85
|
+
program
|
|
86
|
+
.option("-c, --config <path>", "Path to configuration file")
|
|
87
|
+
.helpOption("-h, --help", "Display help for command");
|
|
88
|
+
return program;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Main entry point
|
|
92
|
+
*/
|
|
93
|
+
async function main() {
|
|
94
|
+
try {
|
|
95
|
+
const program = await createProgram();
|
|
96
|
+
await program.parseAsync(process.argv);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
logError("Unexpected error:", error);
|
|
100
|
+
// Output error in JSON format if possible
|
|
101
|
+
if (process.argv.includes("--format") && process.argv.includes("json")) {
|
|
102
|
+
console.log(JSON.stringify({
|
|
103
|
+
success: false,
|
|
104
|
+
error: error instanceof Error ? error.message : String(error),
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Run the CLI
|
|
111
|
+
main();
|
|
112
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic Command Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates Commander.js commands from configuration.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import type { CommandConfig } from "../config/config-schema.js";
|
|
8
|
+
/**
|
|
9
|
+
* Create a Commander command from configuration
|
|
10
|
+
*
|
|
11
|
+
* @param config - Command configuration from CLI config file
|
|
12
|
+
* @param configDir - Directory containing the configuration file
|
|
13
|
+
* @returns Configured Commander command
|
|
14
|
+
*/
|
|
15
|
+
export declare function createDynamicCommand(config: CommandConfig, configDir: string): Command;
|
|
16
|
+
//# sourceMappingURL=dynamic-command.factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-command.factory.d.ts","sourceRoot":"","sources":["../../src/command/dynamic-command.factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,4BAA4B,CAAC;AAShF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,MAAM,GAChB,OAAO,CAgGT"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic Command Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates Commander.js commands from configuration.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { executeScript, } from "../executor/script-executor.js";
|
|
8
|
+
import { outputResult } from "../infra/output.js";
|
|
9
|
+
import { setLogLevel, logDebug, logError } from "../infra/logger.js";
|
|
10
|
+
/**
|
|
11
|
+
* Create a Commander command from configuration
|
|
12
|
+
*
|
|
13
|
+
* @param config - Command configuration from CLI config file
|
|
14
|
+
* @param configDir - Directory containing the configuration file
|
|
15
|
+
* @returns Configured Commander command
|
|
16
|
+
*/
|
|
17
|
+
export function createDynamicCommand(config, configDir) {
|
|
18
|
+
const command = new Command(config.name);
|
|
19
|
+
// Set description
|
|
20
|
+
if (config.description) {
|
|
21
|
+
command.description(config.description);
|
|
22
|
+
}
|
|
23
|
+
// Add positional arguments
|
|
24
|
+
if (config.arguments) {
|
|
25
|
+
for (const arg of config.arguments) {
|
|
26
|
+
const argSyntax = buildArgumentSyntax(arg);
|
|
27
|
+
command.argument(argSyntax, arg.description ?? "");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Add options
|
|
31
|
+
if (config.options) {
|
|
32
|
+
for (const opt of config.options) {
|
|
33
|
+
if (opt.required) {
|
|
34
|
+
command.requiredOption(opt.flags, opt.description ?? "", opt.default);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
const option = command.createOption(opt.flags, opt.description ?? "");
|
|
38
|
+
if (opt.default !== undefined) {
|
|
39
|
+
option.default(opt.default);
|
|
40
|
+
}
|
|
41
|
+
if (opt.choices) {
|
|
42
|
+
option.choices(opt.choices);
|
|
43
|
+
}
|
|
44
|
+
command.addOption(option);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Add standard options (always available for all commands)
|
|
49
|
+
command
|
|
50
|
+
.option("--format <format>", "Output format: human or json", "human")
|
|
51
|
+
.option("--quiet", "Suppress all output except errors")
|
|
52
|
+
.option("--verbose", "Show detailed output")
|
|
53
|
+
.option("--debug", "Show debug information");
|
|
54
|
+
// Add action handler
|
|
55
|
+
command.action(async (...actionArgs) => {
|
|
56
|
+
try {
|
|
57
|
+
// Parse arguments and options from Commander
|
|
58
|
+
const { args, options } = parseActionArgs(config, actionArgs);
|
|
59
|
+
// Set log level based on options
|
|
60
|
+
const logLevel = resolveLogLevel(options);
|
|
61
|
+
setLogLevel(logLevel);
|
|
62
|
+
logDebug("Executing command", {
|
|
63
|
+
name: config.name,
|
|
64
|
+
script: config.script,
|
|
65
|
+
args,
|
|
66
|
+
options: { ...options, format: options.format },
|
|
67
|
+
});
|
|
68
|
+
// Build script context
|
|
69
|
+
const context = {
|
|
70
|
+
args,
|
|
71
|
+
options,
|
|
72
|
+
cwd: process.cwd(),
|
|
73
|
+
format: validateFormat(options.format),
|
|
74
|
+
};
|
|
75
|
+
// Execute the script
|
|
76
|
+
const result = await executeScript(config.script, context, configDir);
|
|
77
|
+
logDebug("Script result", result);
|
|
78
|
+
// Output result
|
|
79
|
+
outputResult(result, context.format);
|
|
80
|
+
// Exit with appropriate code
|
|
81
|
+
if (!result.success) {
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logError("Command execution failed", error);
|
|
87
|
+
outputResult({
|
|
88
|
+
success: false,
|
|
89
|
+
error: error instanceof Error ? error.message : String(error),
|
|
90
|
+
}, "human");
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
return command;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Build Commander argument syntax from configuration
|
|
98
|
+
*/
|
|
99
|
+
function buildArgumentSyntax(arg) {
|
|
100
|
+
const name = arg.name;
|
|
101
|
+
const required = arg.required !== false; // Default to required
|
|
102
|
+
if (arg.variadic) {
|
|
103
|
+
return required ? `<${name}...>` : `[${name}...]`;
|
|
104
|
+
}
|
|
105
|
+
return required ? `<${name}>` : `[${name}]`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Parse action arguments from Commander callback
|
|
109
|
+
*
|
|
110
|
+
* Commander.js passes arguments to action handlers in this order:
|
|
111
|
+
* 1. Positional arguments (in order)
|
|
112
|
+
* 2. Options object (from command.opts())
|
|
113
|
+
* 3. Command instance itself
|
|
114
|
+
*
|
|
115
|
+
* However, when using .action(), the last argument is always the Command instance.
|
|
116
|
+
* Options must be retrieved via command.opts() method.
|
|
117
|
+
*/
|
|
118
|
+
function parseActionArgs(config, actionArgs) {
|
|
119
|
+
const args = {};
|
|
120
|
+
// The last argument is always the Command instance
|
|
121
|
+
const commandInstance = actionArgs[actionArgs.length - 1];
|
|
122
|
+
// Get options from the Command instance
|
|
123
|
+
const options = commandInstance.opts();
|
|
124
|
+
// Positional arguments are all items except the last one (Command instance)
|
|
125
|
+
const positionalArgs = actionArgs.slice(0, -1);
|
|
126
|
+
if (config.arguments) {
|
|
127
|
+
config.arguments.forEach((argConfig, index) => {
|
|
128
|
+
if (index < positionalArgs.length) {
|
|
129
|
+
args[argConfig.name] = positionalArgs[index];
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return { args, options };
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Resolve log level from command options
|
|
137
|
+
*/
|
|
138
|
+
function resolveLogLevel(options) {
|
|
139
|
+
if (options.debug)
|
|
140
|
+
return "debug";
|
|
141
|
+
if (options.verbose)
|
|
142
|
+
return "verbose";
|
|
143
|
+
if (options.quiet)
|
|
144
|
+
return "quiet";
|
|
145
|
+
return "normal";
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Validate and normalize output format
|
|
149
|
+
*/
|
|
150
|
+
function validateFormat(format) {
|
|
151
|
+
return format === "json" ? "json" : "human";
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=dynamic-command.factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-command.factory.js","sourceRoot":"","sources":["../../src/command/dynamic-command.factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Loader
|
|
3
|
+
*
|
|
4
|
+
* Finds and loads CLI configuration from multiple sources.
|
|
5
|
+
*/
|
|
6
|
+
import type { LoadConfigResult } from "./config-schema.js";
|
|
7
|
+
/**
|
|
8
|
+
* Load configuration from multiple sources (in order of precedence)
|
|
9
|
+
*
|
|
10
|
+
* 1. Explicit path via --config flag
|
|
11
|
+
* 2. .cli-agent.json in current working directory
|
|
12
|
+
* 3. cli-agent field in package.json
|
|
13
|
+
* 4. ~/.cli-agent.json for global commands
|
|
14
|
+
*
|
|
15
|
+
* @param explicitPath - Optional explicit path to configuration file
|
|
16
|
+
* @returns Configuration result or null if no configuration found
|
|
17
|
+
*/
|
|
18
|
+
export declare function loadConfig(explicitPath?: string): Promise<LoadConfigResult | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the configuration file path from command line args
|
|
21
|
+
* Looks for -c or --config flags
|
|
22
|
+
*/
|
|
23
|
+
export declare function getExplicitConfigPath(): string | undefined;
|
|
24
|
+
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/config/config-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAI3D;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC9B,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAuBlC;AAgDD;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,SAAS,CAe1D"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Loader
|
|
3
|
+
*
|
|
4
|
+
* Finds and loads CLI configuration from multiple sources.
|
|
5
|
+
*/
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import { resolve, dirname } from "node:path";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { validateConfig, ConfigValidationError } from "./config-validator.js";
|
|
10
|
+
import { pathExists } from "../services/file-system.service.js";
|
|
11
|
+
/**
|
|
12
|
+
* Load configuration from multiple sources (in order of precedence)
|
|
13
|
+
*
|
|
14
|
+
* 1. Explicit path via --config flag
|
|
15
|
+
* 2. .cli-agent.json in current working directory
|
|
16
|
+
* 3. cli-agent field in package.json
|
|
17
|
+
* 4. ~/.cli-agent.json for global commands
|
|
18
|
+
*
|
|
19
|
+
* @param explicitPath - Optional explicit path to configuration file
|
|
20
|
+
* @returns Configuration result or null if no configuration found
|
|
21
|
+
*/
|
|
22
|
+
export async function loadConfig(explicitPath) {
|
|
23
|
+
const sources = [];
|
|
24
|
+
// Add explicit path first if provided
|
|
25
|
+
if (explicitPath) {
|
|
26
|
+
sources.push(resolve(process.cwd(), explicitPath));
|
|
27
|
+
}
|
|
28
|
+
// Add standard configuration locations
|
|
29
|
+
sources.push(resolve(process.cwd(), ".cli-agent.json"), resolve(process.cwd(), "package.json"), resolve(homedir(), ".cli-agent.json"));
|
|
30
|
+
for (const source of sources) {
|
|
31
|
+
const result = await tryLoadConfig(source);
|
|
32
|
+
if (result) {
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Try to load configuration from a specific file
|
|
40
|
+
*/
|
|
41
|
+
async function tryLoadConfig(filePath) {
|
|
42
|
+
if (!(await pathExists(filePath))) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const content = await readFile(filePath, "utf-8");
|
|
47
|
+
const parsed = JSON.parse(content);
|
|
48
|
+
// Handle package.json case
|
|
49
|
+
if (filePath.endsWith("package.json")) {
|
|
50
|
+
if (!parsed["cli-agent"]) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const config = validateConfig(parsed["cli-agent"]);
|
|
54
|
+
return {
|
|
55
|
+
config,
|
|
56
|
+
configPath: filePath,
|
|
57
|
+
configDir: dirname(filePath),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Handle .cli-agent.json
|
|
61
|
+
const config = validateConfig(parsed);
|
|
62
|
+
return {
|
|
63
|
+
config,
|
|
64
|
+
configPath: filePath,
|
|
65
|
+
configDir: dirname(filePath),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error instanceof ConfigValidationError) {
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
if (error instanceof SyntaxError) {
|
|
73
|
+
throw new Error(`Invalid JSON in ${filePath}: ${error.message}`);
|
|
74
|
+
}
|
|
75
|
+
// File read errors or other issues - skip this source
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the configuration file path from command line args
|
|
81
|
+
* Looks for -c or --config flags
|
|
82
|
+
*/
|
|
83
|
+
export function getExplicitConfigPath() {
|
|
84
|
+
const args = process.argv;
|
|
85
|
+
const configIndex = args.findIndex((arg) => arg === "-c" || arg === "--config");
|
|
86
|
+
if (configIndex !== -1) {
|
|
87
|
+
// Make sure the next arg is not another flag
|
|
88
|
+
const nextArg = args[configIndex + 1];
|
|
89
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
90
|
+
return nextArg;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=config-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/config/config-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Schema
|
|
3
|
+
*
|
|
4
|
+
* TypeScript types for CLI configuration.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Root configuration for cli-agent
|
|
8
|
+
*/
|
|
9
|
+
export interface CliConfig {
|
|
10
|
+
/** CLI name (defaults to 'cli-agent') */
|
|
11
|
+
name?: string;
|
|
12
|
+
/** CLI version (defaults to package.json version) */
|
|
13
|
+
version?: string;
|
|
14
|
+
/** CLI description */
|
|
15
|
+
description?: string;
|
|
16
|
+
/** List of commands */
|
|
17
|
+
commands: CommandConfig[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Configuration for a single command
|
|
21
|
+
*/
|
|
22
|
+
export interface CommandConfig {
|
|
23
|
+
/** Command name (e.g., 'feature-folder') */
|
|
24
|
+
name: string;
|
|
25
|
+
/** Command description for help text */
|
|
26
|
+
description?: string;
|
|
27
|
+
/** Path to script file (.js, .ts, or .sh) relative to config file */
|
|
28
|
+
script: string;
|
|
29
|
+
/** Positional arguments */
|
|
30
|
+
arguments?: ArgumentConfig[];
|
|
31
|
+
/** Command options */
|
|
32
|
+
options?: OptionConfig[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Configuration for a positional argument
|
|
36
|
+
*/
|
|
37
|
+
export interface ArgumentConfig {
|
|
38
|
+
/** Argument name */
|
|
39
|
+
name: string;
|
|
40
|
+
/** Argument description */
|
|
41
|
+
description?: string;
|
|
42
|
+
/** Whether the argument is required (default: true) */
|
|
43
|
+
required?: boolean;
|
|
44
|
+
/** Whether the argument accepts multiple values (e.g., <files...>) */
|
|
45
|
+
variadic?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Configuration for a command option
|
|
49
|
+
*/
|
|
50
|
+
export interface OptionConfig {
|
|
51
|
+
/** Option flags (e.g., '-n, --name <name>') */
|
|
52
|
+
flags: string;
|
|
53
|
+
/** Option description */
|
|
54
|
+
description?: string;
|
|
55
|
+
/** Default value */
|
|
56
|
+
default?: unknown;
|
|
57
|
+
/** Whether the option is required */
|
|
58
|
+
required?: boolean;
|
|
59
|
+
/** Allowed values */
|
|
60
|
+
choices?: string[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Result of loading configuration
|
|
64
|
+
*/
|
|
65
|
+
export interface LoadConfigResult {
|
|
66
|
+
/** Parsed and validated configuration */
|
|
67
|
+
config: CliConfig;
|
|
68
|
+
/** Absolute path to the configuration file */
|
|
69
|
+
configPath: string;
|
|
70
|
+
/** Directory containing the configuration file */
|
|
71
|
+
configDir: string;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=config-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../../src/config/config-schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB;IACvB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,sBAAsB;IACtB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,MAAM,EAAE,SAAS,CAAC;IAClB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-schema.js","sourceRoot":"","sources":["../../src/config/config-schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates CLI configuration structure.
|
|
5
|
+
*/
|
|
6
|
+
import type { CliConfig } from './config-schema.js';
|
|
7
|
+
/**
|
|
8
|
+
* Validation error with details
|
|
9
|
+
*/
|
|
10
|
+
export declare class ConfigValidationError extends Error {
|
|
11
|
+
readonly path: string;
|
|
12
|
+
readonly value?: unknown | undefined;
|
|
13
|
+
constructor(message: string, path: string, value?: unknown | undefined);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Validate a configuration object
|
|
17
|
+
* @throws ConfigValidationError if validation fails
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateConfig(config: unknown): CliConfig;
|
|
20
|
+
//# sourceMappingURL=config-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-validator.d.ts","sourceRoot":"","sources":["../../src/config/config-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAA+C,MAAM,oBAAoB,CAAC;AAEjG;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;aAG5B,IAAI,EAAE,MAAM;aACZ,KAAK,CAAC,EAAE,OAAO;gBAF/B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,YAAA;CAKlC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAiCzD"}
|