@nicolasmondain/cli-agent 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +183 -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-serve.command.d.ts +13 -0
- package/dist/cli/commands/mcp-serve.command.d.ts.map +1 -0
- package/dist/cli/commands/mcp-serve.command.js +42 -0
- package/dist/cli/commands/mcp-serve.command.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +111 -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 +161 -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 +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -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/mcp-server.d.ts +21 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -0
- package/dist/mcp/mcp-server.js +183 -0
- package/dist/mcp/mcp-server.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 +72 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { createConsola } from 'consola';
|
|
2
|
+
/**
|
|
3
|
+
* Logger instance configured for CLI usage
|
|
4
|
+
* - All logs go to stderr (keeps stdout clean for results)
|
|
5
|
+
* - Supports different verbosity levels
|
|
6
|
+
*/
|
|
7
|
+
let loggerInstance = null;
|
|
8
|
+
let currentLogLevel = 'normal';
|
|
9
|
+
/**
|
|
10
|
+
* Map our log levels to consola log levels
|
|
11
|
+
*/
|
|
12
|
+
const LOG_LEVEL_MAP = {
|
|
13
|
+
quiet: -1, // Only errors
|
|
14
|
+
normal: 3, // Info and above
|
|
15
|
+
verbose: 4, // Debug and above
|
|
16
|
+
debug: 5, // Trace and above
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Create or get the logger instance
|
|
20
|
+
*/
|
|
21
|
+
function getLogger() {
|
|
22
|
+
if (!loggerInstance) {
|
|
23
|
+
loggerInstance = createConsola({
|
|
24
|
+
level: LOG_LEVEL_MAP[currentLogLevel],
|
|
25
|
+
// Force output to stderr
|
|
26
|
+
stderr: process.stderr,
|
|
27
|
+
stdout: process.stderr,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return loggerInstance;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Set the log level for the logger
|
|
34
|
+
*/
|
|
35
|
+
export function setLogLevel(level) {
|
|
36
|
+
currentLogLevel = level;
|
|
37
|
+
if (loggerInstance) {
|
|
38
|
+
loggerInstance.level = LOG_LEVEL_MAP[level];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the current log level
|
|
43
|
+
*/
|
|
44
|
+
export function getLogLevel() {
|
|
45
|
+
return currentLogLevel;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Log an error message (always shown unless quiet)
|
|
49
|
+
*/
|
|
50
|
+
export function logError(message, ...args) {
|
|
51
|
+
getLogger().error(message, ...args);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Log a warning message
|
|
55
|
+
*/
|
|
56
|
+
export function logWarn(message, ...args) {
|
|
57
|
+
getLogger().warn(message, ...args);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Log an info message
|
|
61
|
+
*/
|
|
62
|
+
export function logInfo(message, ...args) {
|
|
63
|
+
getLogger().info(message, ...args);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Log a success message
|
|
67
|
+
*/
|
|
68
|
+
export function logSuccess(message, ...args) {
|
|
69
|
+
getLogger().success(message, ...args);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Log a debug message (only in verbose/debug mode)
|
|
73
|
+
*/
|
|
74
|
+
export function logDebug(message, ...args) {
|
|
75
|
+
getLogger().debug(message, ...args);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Log a trace message (only in debug mode)
|
|
79
|
+
*/
|
|
80
|
+
export function logTrace(message, ...args) {
|
|
81
|
+
getLogger().trace(message, ...args);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Create a boxed message for important outputs
|
|
85
|
+
*/
|
|
86
|
+
export function logBox(message) {
|
|
87
|
+
getLogger().box(message);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Reset logger instance (useful for testing)
|
|
91
|
+
*/
|
|
92
|
+
export function resetLogger() {
|
|
93
|
+
loggerInstance = null;
|
|
94
|
+
currentLogLevel = 'normal';
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/infra/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAwB,MAAM,SAAS,CAAC;AAG9D;;;;GAIG;AAEH,IAAI,cAAc,GAA2B,IAAI,CAAC;AAClD,IAAI,eAAe,GAAa,QAAQ,CAAC;AAEzC;;GAEG;AACH,MAAM,aAAa,GAA6B;IAC9C,KAAK,EAAE,CAAC,CAAC,EAAK,cAAc;IAC5B,MAAM,EAAE,CAAC,EAAK,iBAAiB;IAC/B,OAAO,EAAE,CAAC,EAAI,kBAAkB;IAChC,KAAK,EAAE,CAAC,EAAM,kBAAkB;CACjC,CAAC;AAEF;;GAEG;AACH,SAAS,SAAS;IAChB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,aAAa,CAAC;YAC7B,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC;YACrC,yBAAyB;YACzB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAe;IACzC,eAAe,GAAG,KAAK,CAAC;IACxB,IAAI,cAAc,EAAE,CAAC;QACnB,cAAc,CAAC,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,GAAG,IAAe;IAC1D,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe,EAAE,GAAG,IAAe;IACzD,SAAS,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe,EAAE,GAAG,IAAe;IACzD,SAAS,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,GAAG,IAAe;IAC5D,SAAS,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,GAAG,IAAe;IAC1D,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,GAAG,IAAe;IAC1D,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,OAAe;IACpC,SAAS,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,cAAc,GAAG,IAAI,CAAC;IACtB,eAAe,GAAG,QAAQ,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CommandResult, OutputFormat } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Output utilities for CLI commands
|
|
4
|
+
* - Results go to stdout (for piping/parsing)
|
|
5
|
+
* - Supports human-readable and JSON formats
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Output a result to stdout in the specified format
|
|
9
|
+
*/
|
|
10
|
+
export declare function outputResult<T>(result: CommandResult<T>, format: OutputFormat): void;
|
|
11
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/infra/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAErE;;;;GAIG;AAEH;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,MAAM,EAAE,YAAY,GACnB,IAAI,CAMN"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output utilities for CLI commands
|
|
3
|
+
* - Results go to stdout (for piping/parsing)
|
|
4
|
+
* - Supports human-readable and JSON formats
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Output a result to stdout in the specified format
|
|
8
|
+
*/
|
|
9
|
+
export function outputResult(result, format) {
|
|
10
|
+
if (format === "json") {
|
|
11
|
+
outputJson(result);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
outputHuman(result);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Output result as JSON to stdout
|
|
19
|
+
*/
|
|
20
|
+
function outputJson(result) {
|
|
21
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Output result in human-readable format to stdout
|
|
25
|
+
*/
|
|
26
|
+
function outputHuman(result) {
|
|
27
|
+
if (result.success) {
|
|
28
|
+
if (result.message) {
|
|
29
|
+
console.log(result.message);
|
|
30
|
+
}
|
|
31
|
+
if (result.data !== undefined) {
|
|
32
|
+
formatData(result.data);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.error(`Error: ${result.error ?? "Unknown error"}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Format data for human-readable output
|
|
41
|
+
*/
|
|
42
|
+
function formatData(data) {
|
|
43
|
+
if (data === null || data === undefined) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (typeof data === "string") {
|
|
47
|
+
// String data - output directly
|
|
48
|
+
console.log(data);
|
|
49
|
+
}
|
|
50
|
+
else if (typeof data === "number" || typeof data === "boolean") {
|
|
51
|
+
// Primitive data - output directly
|
|
52
|
+
console.log(String(data));
|
|
53
|
+
}
|
|
54
|
+
else if (Array.isArray(data)) {
|
|
55
|
+
// Array data - output each item
|
|
56
|
+
for (const item of data) {
|
|
57
|
+
if (typeof item === "object" && item !== null) {
|
|
58
|
+
console.log(JSON.stringify(item, null, 2));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.log(String(item));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (typeof data === "object") {
|
|
66
|
+
// Object data - pretty print JSON
|
|
67
|
+
console.log(JSON.stringify(data, null, 2));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/infra/output.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAwB,EACxB,MAAoB;IAEpB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,UAAU,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,WAAW,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAI,MAAwB;IAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAC/D,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAI,MAAwB;IAC9C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAI,IAAO;IAC5B,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO;IACT,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,gCAAgC;QAChC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;SAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,SAAS,EAAE,CAAC;QACjE,mCAAmC;QACnC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5B,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,gCAAgC;QAChC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC9C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpC,kCAAkC;QAClC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server Implementation
|
|
3
|
+
*
|
|
4
|
+
* Creates an MCP server that exposes cli-agent commands as tools.
|
|
5
|
+
* Enables native integration with Claude Code and other MCP-compatible clients.
|
|
6
|
+
*/
|
|
7
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
|
+
import type { CliConfig } from "../config/config-schema.js";
|
|
9
|
+
export interface McpServerOptions {
|
|
10
|
+
config: CliConfig;
|
|
11
|
+
configDir: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create and configure an MCP server from cli-agent configuration
|
|
15
|
+
*/
|
|
16
|
+
export declare function createMcpServer(options: McpServerOptions): McpServer;
|
|
17
|
+
/**
|
|
18
|
+
* Start the MCP server with stdio transport
|
|
19
|
+
*/
|
|
20
|
+
export declare function startMcpServer(options: McpServerOptions): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=mcp-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,4BAA4B,CAAC;AAO3E,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AA8KD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CA2BpE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAU7E"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server Implementation
|
|
3
|
+
*
|
|
4
|
+
* Creates an MCP server that exposes cli-agent commands as tools.
|
|
5
|
+
* Enables native integration with Claude Code and other MCP-compatible clients.
|
|
6
|
+
*/
|
|
7
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
import { executeScript, } from "../executor/script-executor.js";
|
|
11
|
+
/**
|
|
12
|
+
* Parse option flags to extract the option name
|
|
13
|
+
* Examples:
|
|
14
|
+
* "-n, --name <value>" -> "name"
|
|
15
|
+
* "--verbose" -> "verbose"
|
|
16
|
+
* "-f, --force" -> "force"
|
|
17
|
+
*/
|
|
18
|
+
function parseOptionName(flags) {
|
|
19
|
+
const match = flags.match(/--([a-zA-Z][\w-]*)/);
|
|
20
|
+
if (match && match[1]) {
|
|
21
|
+
return match[1];
|
|
22
|
+
}
|
|
23
|
+
return flags.replace(/[^a-zA-Z0-9-]/g, "");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Determine if option takes a value based on flags
|
|
27
|
+
* Examples:
|
|
28
|
+
* "-n, --name <value>" -> true (required value)
|
|
29
|
+
* "--count [num]" -> true (optional value)
|
|
30
|
+
* "--verbose" -> false (boolean flag)
|
|
31
|
+
*/
|
|
32
|
+
function optionTakesValue(flags) {
|
|
33
|
+
return flags.includes("<") || flags.includes("[");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build Zod schema from command configuration
|
|
37
|
+
*/
|
|
38
|
+
function buildZodSchema(command) {
|
|
39
|
+
const shape = {};
|
|
40
|
+
// Add arguments to schema
|
|
41
|
+
if (command.arguments) {
|
|
42
|
+
for (const arg of command.arguments) {
|
|
43
|
+
if (arg.variadic) {
|
|
44
|
+
shape[arg.name] = z
|
|
45
|
+
.array(z.string())
|
|
46
|
+
.describe(arg.description ?? "")
|
|
47
|
+
.optional();
|
|
48
|
+
}
|
|
49
|
+
else if (arg.required === false) {
|
|
50
|
+
shape[arg.name] = z
|
|
51
|
+
.string()
|
|
52
|
+
.describe(arg.description ?? "")
|
|
53
|
+
.optional();
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
shape[arg.name] = z.string().describe(arg.description ?? "");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Add options to schema
|
|
61
|
+
if (command.options) {
|
|
62
|
+
for (const opt of command.options) {
|
|
63
|
+
const optName = parseOptionName(opt.flags);
|
|
64
|
+
const takesValue = optionTakesValue(opt.flags);
|
|
65
|
+
let field;
|
|
66
|
+
if (!takesValue) {
|
|
67
|
+
// Boolean flag
|
|
68
|
+
field = z
|
|
69
|
+
.boolean()
|
|
70
|
+
.describe(opt.description ?? "")
|
|
71
|
+
.optional();
|
|
72
|
+
}
|
|
73
|
+
else if (opt.choices && opt.choices.length > 0) {
|
|
74
|
+
// Enum type
|
|
75
|
+
field = z
|
|
76
|
+
.enum(opt.choices)
|
|
77
|
+
.describe(opt.description ?? "");
|
|
78
|
+
if (!opt.required) {
|
|
79
|
+
field = field.optional();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else if (typeof opt.default === "number") {
|
|
83
|
+
field = z
|
|
84
|
+
.number()
|
|
85
|
+
.describe(opt.description ?? "")
|
|
86
|
+
.optional();
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
field = z
|
|
90
|
+
.string()
|
|
91
|
+
.describe(opt.description ?? "")
|
|
92
|
+
.optional();
|
|
93
|
+
}
|
|
94
|
+
if (opt.default !== undefined && "default" in field) {
|
|
95
|
+
field = field.default(opt.default);
|
|
96
|
+
}
|
|
97
|
+
shape[optName] = field;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return z.object(shape);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Separate MCP params into args and options based on command config
|
|
104
|
+
*/
|
|
105
|
+
function separateArgsAndOptions(command, params) {
|
|
106
|
+
const args = {};
|
|
107
|
+
const options = {};
|
|
108
|
+
const argumentNames = new Set((command.arguments ?? []).map((a) => a.name));
|
|
109
|
+
for (const [key, value] of Object.entries(params)) {
|
|
110
|
+
if (argumentNames.has(key)) {
|
|
111
|
+
args[key] = value;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
options[key] = value;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return { args, options };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Execute a tool call by routing to the script executor
|
|
121
|
+
*/
|
|
122
|
+
async function executeToolCall(command, params, configDir) {
|
|
123
|
+
const { args, options } = separateArgsAndOptions(command, params);
|
|
124
|
+
const context = {
|
|
125
|
+
args,
|
|
126
|
+
options,
|
|
127
|
+
cwd: process.cwd(),
|
|
128
|
+
format: "json",
|
|
129
|
+
};
|
|
130
|
+
try {
|
|
131
|
+
const result = await executeScript(command.script, context, configDir);
|
|
132
|
+
return {
|
|
133
|
+
content: [
|
|
134
|
+
{
|
|
135
|
+
type: "text",
|
|
136
|
+
text: JSON.stringify(result, null, 2),
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
return {
|
|
143
|
+
content: [
|
|
144
|
+
{
|
|
145
|
+
type: "text",
|
|
146
|
+
text: JSON.stringify({
|
|
147
|
+
success: false,
|
|
148
|
+
error: error instanceof Error ? error.message : String(error),
|
|
149
|
+
}, null, 2),
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Create and configure an MCP server from cli-agent configuration
|
|
157
|
+
*/
|
|
158
|
+
export function createMcpServer(options) {
|
|
159
|
+
const { config, configDir } = options;
|
|
160
|
+
const server = new McpServer({
|
|
161
|
+
name: config.name ?? "cli-agent",
|
|
162
|
+
version: config.version ?? "1.0.0",
|
|
163
|
+
});
|
|
164
|
+
// Register each command as an MCP tool
|
|
165
|
+
for (const command of config.commands) {
|
|
166
|
+
const inputSchema = buildZodSchema(command);
|
|
167
|
+
server.tool(command.name, command.description ?? `Execute ${command.name} command`, inputSchema.shape, async (params) => {
|
|
168
|
+
return executeToolCall(command, params, configDir);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return server;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Start the MCP server with stdio transport
|
|
175
|
+
*/
|
|
176
|
+
export async function startMcpServer(options) {
|
|
177
|
+
const server = createMcpServer(options);
|
|
178
|
+
const transport = new StdioServerTransport();
|
|
179
|
+
await server.connect(transport);
|
|
180
|
+
// Log to stderr (not stdout - would corrupt MCP messages)
|
|
181
|
+
console.error(`MCP Server "${options.config.name ?? "cli-agent"}" running on stdio`);
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../../src/mcp/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a file or directory to be created
|
|
3
|
+
*/
|
|
4
|
+
export interface FileEntry {
|
|
5
|
+
/** Relative path from the base directory */
|
|
6
|
+
path: string;
|
|
7
|
+
/** Type of entry */
|
|
8
|
+
type: "file" | "directory";
|
|
9
|
+
/** Content for files (undefined for directories) */
|
|
10
|
+
content?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* File system service for creating files and directories
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Check if a path exists
|
|
17
|
+
*/
|
|
18
|
+
export declare function pathExists(path: string): Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* Check if a path is a directory
|
|
21
|
+
*/
|
|
22
|
+
export declare function isDirectory(path: string): Promise<boolean>;
|
|
23
|
+
/**
|
|
24
|
+
* Create a directory (and parent directories if needed)
|
|
25
|
+
*/
|
|
26
|
+
export declare function createDirectory(path: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Create a file with content
|
|
29
|
+
* Creates parent directories if they don't exist
|
|
30
|
+
*/
|
|
31
|
+
export declare function createFile(path: string, content: string): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Resolve a path relative to a base path
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolvePath(basePath: string, relativePath: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Join path segments
|
|
38
|
+
*/
|
|
39
|
+
export declare function joinPath(...segments: string[]): string;
|
|
40
|
+
/**
|
|
41
|
+
* Create all entries (files and directories) for a feature
|
|
42
|
+
* Returns the list of created paths
|
|
43
|
+
*/
|
|
44
|
+
export declare function createEntries(basePath: string, entries: FileEntry[]): Promise<{
|
|
45
|
+
files: string[];
|
|
46
|
+
directories: string[];
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* Check if any of the given paths already exist
|
|
50
|
+
* Returns the list of existing paths
|
|
51
|
+
*/
|
|
52
|
+
export declare function checkExistingPaths(basePath: string, paths: string[]): Promise<string[]>;
|
|
53
|
+
//# sourceMappingURL=file-system.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-system.service.d.ts","sourceRoot":"","sources":["../../src/services/file-system.service.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AAEH;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOhE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAEtD;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,SAAS,EAAE,GACnB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAyBrD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CAWnB"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { mkdir, writeFile, access, stat } from "node:fs/promises";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* File system service for creating files and directories
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Check if a path exists
|
|
8
|
+
*/
|
|
9
|
+
export async function pathExists(path) {
|
|
10
|
+
try {
|
|
11
|
+
await access(path);
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check if a path is a directory
|
|
20
|
+
*/
|
|
21
|
+
export async function isDirectory(path) {
|
|
22
|
+
try {
|
|
23
|
+
const stats = await stat(path);
|
|
24
|
+
return stats.isDirectory();
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create a directory (and parent directories if needed)
|
|
32
|
+
*/
|
|
33
|
+
export async function createDirectory(path) {
|
|
34
|
+
await mkdir(path, { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create a file with content
|
|
38
|
+
* Creates parent directories if they don't exist
|
|
39
|
+
*/
|
|
40
|
+
export async function createFile(path, content) {
|
|
41
|
+
const dir = dirname(path);
|
|
42
|
+
await mkdir(dir, { recursive: true });
|
|
43
|
+
await writeFile(path, content, "utf-8");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolve a path relative to a base path
|
|
47
|
+
*/
|
|
48
|
+
export function resolvePath(basePath, relativePath) {
|
|
49
|
+
return resolve(basePath, relativePath);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Join path segments
|
|
53
|
+
*/
|
|
54
|
+
export function joinPath(...segments) {
|
|
55
|
+
return join(...segments);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create all entries (files and directories) for a feature
|
|
59
|
+
* Returns the list of created paths
|
|
60
|
+
*/
|
|
61
|
+
export async function createEntries(basePath, entries) {
|
|
62
|
+
const files = [];
|
|
63
|
+
const directories = [];
|
|
64
|
+
// Sort entries: directories first, then files
|
|
65
|
+
// This ensures parent directories are created before files
|
|
66
|
+
const sortedEntries = [...entries].sort((a, b) => {
|
|
67
|
+
if (a.type === "directory" && b.type === "file")
|
|
68
|
+
return -1;
|
|
69
|
+
if (a.type === "file" && b.type === "directory")
|
|
70
|
+
return 1;
|
|
71
|
+
return a.path.localeCompare(b.path);
|
|
72
|
+
});
|
|
73
|
+
for (const entry of sortedEntries) {
|
|
74
|
+
const fullPath = resolvePath(basePath, entry.path);
|
|
75
|
+
if (entry.type === "directory") {
|
|
76
|
+
await createDirectory(fullPath);
|
|
77
|
+
directories.push(entry.path);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
await createFile(fullPath, entry.content ?? "");
|
|
81
|
+
files.push(entry.path);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { files, directories };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Check if any of the given paths already exist
|
|
88
|
+
* Returns the list of existing paths
|
|
89
|
+
*/
|
|
90
|
+
export async function checkExistingPaths(basePath, paths) {
|
|
91
|
+
const existing = [];
|
|
92
|
+
for (const path of paths) {
|
|
93
|
+
const fullPath = resolvePath(basePath, path);
|
|
94
|
+
if (await pathExists(fullPath)) {
|
|
95
|
+
existing.push(path);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return existing;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=file-system.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-system.service.js","sourceRoot":"","sources":["../../src/services/file-system.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Naming service for converting between different case conventions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Convert a string to kebab-case
|
|
6
|
+
* @example "UserProfile" -> "user-profile"
|
|
7
|
+
* @example "user_profile" -> "user-profile"
|
|
8
|
+
* @example "user profile" -> "user-profile"
|
|
9
|
+
*/
|
|
10
|
+
export declare function toKebabCase(input: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Convert a string to PascalCase
|
|
13
|
+
* @example "user-profile" -> "UserProfile"
|
|
14
|
+
* @example "user_profile" -> "UserProfile"
|
|
15
|
+
*/
|
|
16
|
+
export declare function toPascalCase(input: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Convert a string to camelCase
|
|
19
|
+
* @example "user-profile" -> "userProfile"
|
|
20
|
+
* @example "user_profile" -> "userProfile"
|
|
21
|
+
*/
|
|
22
|
+
export declare function toCamelCase(input: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Convert a string to SCREAMING_SNAKE_CASE
|
|
25
|
+
* @example "user-profile" -> "USER_PROFILE"
|
|
26
|
+
* @example "UserProfile" -> "USER_PROFILE"
|
|
27
|
+
*/
|
|
28
|
+
export declare function toScreamingSnakeCase(input: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Validate that a name is a valid feature name
|
|
31
|
+
* - Must not be empty
|
|
32
|
+
* - Must contain only alphanumeric characters, hyphens, or underscores
|
|
33
|
+
* - Must start with a letter
|
|
34
|
+
*/
|
|
35
|
+
export declare function isValidFeatureName(name: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Get validation error message for an invalid feature name
|
|
38
|
+
*/
|
|
39
|
+
export declare function getFeatureNameError(name: string): string | null;
|
|
40
|
+
//# sourceMappingURL=naming.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.service.d.ts","sourceRoot":"","sources":["../../src/services/naming.service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAcjD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoB/D"}
|