@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.
Files changed (78) hide show
  1. package/README.md +484 -0
  2. package/dist/cli/commands/list.command.d.ts +48 -0
  3. package/dist/cli/commands/list.command.d.ts.map +1 -0
  4. package/dist/cli/commands/list.command.js +87 -0
  5. package/dist/cli/commands/list.command.js.map +1 -0
  6. package/dist/cli/commands/mcp-manifest.command.d.ts +14 -0
  7. package/dist/cli/commands/mcp-manifest.command.d.ts.map +1 -0
  8. package/dist/cli/commands/mcp-manifest.command.js +87 -0
  9. package/dist/cli/commands/mcp-manifest.command.js.map +1 -0
  10. package/dist/cli/index.d.ts +9 -0
  11. package/dist/cli/index.d.ts.map +1 -0
  12. package/dist/cli/index.js +112 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/command/dynamic-command.factory.d.ts +16 -0
  15. package/dist/command/dynamic-command.factory.d.ts.map +1 -0
  16. package/dist/command/dynamic-command.factory.js +153 -0
  17. package/dist/command/dynamic-command.factory.js.map +1 -0
  18. package/dist/config/config-loader.d.ts +24 -0
  19. package/dist/config/config-loader.d.ts.map +1 -0
  20. package/dist/config/config-loader.js +95 -0
  21. package/dist/config/config-loader.js.map +1 -0
  22. package/dist/config/config-schema.d.ts +73 -0
  23. package/dist/config/config-schema.d.ts.map +1 -0
  24. package/dist/config/config-schema.js +7 -0
  25. package/dist/config/config-schema.js.map +1 -0
  26. package/dist/config/config-validator.d.ts +20 -0
  27. package/dist/config/config-validator.d.ts.map +1 -0
  28. package/dist/config/config-validator.js +162 -0
  29. package/dist/config/config-validator.js.map +1 -0
  30. package/dist/executor/js-executor.d.ts +29 -0
  31. package/dist/executor/js-executor.d.ts.map +1 -0
  32. package/dist/executor/js-executor.js +77 -0
  33. package/dist/executor/js-executor.js.map +1 -0
  34. package/dist/executor/script-executor.d.ts +33 -0
  35. package/dist/executor/script-executor.d.ts.map +1 -0
  36. package/dist/executor/script-executor.js +45 -0
  37. package/dist/executor/script-executor.js.map +1 -0
  38. package/dist/executor/shell-executor.d.ts +33 -0
  39. package/dist/executor/shell-executor.d.ts.map +1 -0
  40. package/dist/executor/shell-executor.js +126 -0
  41. package/dist/executor/shell-executor.js.map +1 -0
  42. package/dist/executor/ts-executor.d.ts +33 -0
  43. package/dist/executor/ts-executor.d.ts.map +1 -0
  44. package/dist/executor/ts-executor.js +134 -0
  45. package/dist/executor/ts-executor.js.map +1 -0
  46. package/dist/index.d.ts +14 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +15 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/infra/logger.d.ts +42 -0
  51. package/dist/infra/logger.d.ts.map +1 -0
  52. package/dist/infra/logger.js +96 -0
  53. package/dist/infra/logger.js.map +1 -0
  54. package/dist/infra/output.d.ts +11 -0
  55. package/dist/infra/output.d.ts.map +1 -0
  56. package/dist/infra/output.js +70 -0
  57. package/dist/infra/output.js.map +1 -0
  58. package/dist/mcp/manifest-generator.d.ts +51 -0
  59. package/dist/mcp/manifest-generator.d.ts.map +1 -0
  60. package/dist/mcp/manifest-generator.js +130 -0
  61. package/dist/mcp/manifest-generator.js.map +1 -0
  62. package/dist/services/file-system.service.d.ts +53 -0
  63. package/dist/services/file-system.service.d.ts.map +1 -0
  64. package/dist/services/file-system.service.js +100 -0
  65. package/dist/services/file-system.service.js.map +1 -0
  66. package/dist/services/naming.service.d.ts +40 -0
  67. package/dist/services/naming.service.d.ts.map +1 -0
  68. package/dist/services/naming.service.js +86 -0
  69. package/dist/services/naming.service.js.map +1 -0
  70. package/dist/services/naming.service.test.d.ts +2 -0
  71. package/dist/services/naming.service.test.d.ts.map +1 -0
  72. package/dist/services/naming.service.test.js +99 -0
  73. package/dist/services/naming.service.test.js.map +1 -0
  74. package/dist/types/index.d.ts +51 -0
  75. package/dist/types/index.d.ts.map +1 -0
  76. package/dist/types/index.js +14 -0
  77. package/dist/types/index.js.map +1 -0
  78. package/package.json +70 -0
@@ -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"}
@@ -0,0 +1,86 @@
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 function toKebabCase(input) {
11
+ return input
12
+ // Insert hyphen before uppercase letters
13
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
14
+ // Replace underscores and spaces with hyphens
15
+ .replace(/[_\s]+/g, '-')
16
+ // Convert to lowercase
17
+ .toLowerCase()
18
+ // Remove any non-alphanumeric characters except hyphens
19
+ .replace(/[^a-z0-9-]/g, '')
20
+ // Remove consecutive hyphens
21
+ .replace(/-+/g, '-')
22
+ // Remove leading/trailing hyphens
23
+ .replace(/^-|-$/g, '');
24
+ }
25
+ /**
26
+ * Convert a string to PascalCase
27
+ * @example "user-profile" -> "UserProfile"
28
+ * @example "user_profile" -> "UserProfile"
29
+ */
30
+ export function toPascalCase(input) {
31
+ return toKebabCase(input)
32
+ .split('-')
33
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
34
+ .join('');
35
+ }
36
+ /**
37
+ * Convert a string to camelCase
38
+ * @example "user-profile" -> "userProfile"
39
+ * @example "user_profile" -> "userProfile"
40
+ */
41
+ export function toCamelCase(input) {
42
+ const pascal = toPascalCase(input);
43
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
44
+ }
45
+ /**
46
+ * Convert a string to SCREAMING_SNAKE_CASE
47
+ * @example "user-profile" -> "USER_PROFILE"
48
+ * @example "UserProfile" -> "USER_PROFILE"
49
+ */
50
+ export function toScreamingSnakeCase(input) {
51
+ return toKebabCase(input).replace(/-/g, '_').toUpperCase();
52
+ }
53
+ /**
54
+ * Validate that a name is a valid feature name
55
+ * - Must not be empty
56
+ * - Must contain only alphanumeric characters, hyphens, or underscores
57
+ * - Must start with a letter
58
+ */
59
+ export function isValidFeatureName(name) {
60
+ if (!name || name.trim().length === 0) {
61
+ return false;
62
+ }
63
+ // After converting to kebab-case, check if it's valid
64
+ const kebab = toKebabCase(name);
65
+ return /^[a-z][a-z0-9-]*$/.test(kebab);
66
+ }
67
+ /**
68
+ * Get validation error message for an invalid feature name
69
+ */
70
+ export function getFeatureNameError(name) {
71
+ if (!name || name.trim().length === 0) {
72
+ return 'Feature name cannot be empty';
73
+ }
74
+ const kebab = toKebabCase(name);
75
+ if (kebab.length === 0) {
76
+ return 'Feature name must contain at least one alphanumeric character';
77
+ }
78
+ if (!/^[a-z]/.test(kebab)) {
79
+ return 'Feature name must start with a letter';
80
+ }
81
+ if (!/^[a-z][a-z0-9-]*$/.test(kebab)) {
82
+ return 'Feature name can only contain letters, numbers, and hyphens';
83
+ }
84
+ return null;
85
+ }
86
+ //# sourceMappingURL=naming.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.service.js","sourceRoot":"","sources":["../../src/services/naming.service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,KAAK;QACV,yCAAyC;SACxC,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;QACpC,8CAA8C;SAC7C,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;QACxB,uBAAuB;SACtB,WAAW,EAAE;QACd,wDAAwD;SACvD,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;QAC3B,6BAA6B;SAC5B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QACpB,kCAAkC;SACjC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,WAAW,CAAC,KAAK,CAAC;SACtB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,sDAAsD;IACtD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,8BAA8B,CAAC;IACxC,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAEhC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,+DAA+D,CAAC;IACzE,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,uCAAuC,CAAC;IACjD,CAAC;IAED,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,6DAA6D,CAAC;IACvE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=naming.service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.service.test.d.ts","sourceRoot":"","sources":["../../src/services/naming.service.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,99 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { toKebabCase, toPascalCase, toCamelCase, toScreamingSnakeCase, isValidFeatureName, getFeatureNameError, } from './naming.service.js';
3
+ describe('Naming Service', () => {
4
+ describe('toKebabCase', () => {
5
+ it('should convert PascalCase to kebab-case', () => {
6
+ expect(toKebabCase('UserProfile')).toBe('user-profile');
7
+ expect(toKebabCase('MyAwesomeFeature')).toBe('my-awesome-feature');
8
+ });
9
+ it('should convert camelCase to kebab-case', () => {
10
+ expect(toKebabCase('userProfile')).toBe('user-profile');
11
+ expect(toKebabCase('myAwesomeFeature')).toBe('my-awesome-feature');
12
+ });
13
+ it('should convert snake_case to kebab-case', () => {
14
+ expect(toKebabCase('user_profile')).toBe('user-profile');
15
+ expect(toKebabCase('my_awesome_feature')).toBe('my-awesome-feature');
16
+ });
17
+ it('should convert spaces to hyphens', () => {
18
+ expect(toKebabCase('user profile')).toBe('user-profile');
19
+ expect(toKebabCase('my awesome feature')).toBe('my-awesome-feature');
20
+ });
21
+ it('should handle already kebab-case strings', () => {
22
+ expect(toKebabCase('user-profile')).toBe('user-profile');
23
+ });
24
+ it('should remove non-alphanumeric characters', () => {
25
+ expect(toKebabCase('user@profile!')).toBe('userprofile');
26
+ });
27
+ it('should handle consecutive hyphens', () => {
28
+ expect(toKebabCase('user--profile')).toBe('user-profile');
29
+ });
30
+ it('should remove leading/trailing hyphens', () => {
31
+ expect(toKebabCase('-user-profile-')).toBe('user-profile');
32
+ });
33
+ });
34
+ describe('toPascalCase', () => {
35
+ it('should convert kebab-case to PascalCase', () => {
36
+ expect(toPascalCase('user-profile')).toBe('UserProfile');
37
+ expect(toPascalCase('my-awesome-feature')).toBe('MyAwesomeFeature');
38
+ });
39
+ it('should convert snake_case to PascalCase', () => {
40
+ expect(toPascalCase('user_profile')).toBe('UserProfile');
41
+ });
42
+ it('should handle single word', () => {
43
+ expect(toPascalCase('user')).toBe('User');
44
+ });
45
+ });
46
+ describe('toCamelCase', () => {
47
+ it('should convert kebab-case to camelCase', () => {
48
+ expect(toCamelCase('user-profile')).toBe('userProfile');
49
+ expect(toCamelCase('my-awesome-feature')).toBe('myAwesomeFeature');
50
+ });
51
+ it('should handle single word', () => {
52
+ expect(toCamelCase('user')).toBe('user');
53
+ });
54
+ });
55
+ describe('toScreamingSnakeCase', () => {
56
+ it('should convert kebab-case to SCREAMING_SNAKE_CASE', () => {
57
+ expect(toScreamingSnakeCase('user-profile')).toBe('USER_PROFILE');
58
+ expect(toScreamingSnakeCase('my-awesome-feature')).toBe('MY_AWESOME_FEATURE');
59
+ });
60
+ it('should convert PascalCase to SCREAMING_SNAKE_CASE', () => {
61
+ expect(toScreamingSnakeCase('UserProfile')).toBe('USER_PROFILE');
62
+ });
63
+ });
64
+ describe('isValidFeatureName', () => {
65
+ it('should return true for valid names', () => {
66
+ expect(isValidFeatureName('user-profile')).toBe(true);
67
+ expect(isValidFeatureName('UserProfile')).toBe(true);
68
+ expect(isValidFeatureName('user123')).toBe(true);
69
+ expect(isValidFeatureName('a')).toBe(true);
70
+ });
71
+ it('should return false for empty names', () => {
72
+ expect(isValidFeatureName('')).toBe(false);
73
+ expect(isValidFeatureName(' ')).toBe(false);
74
+ });
75
+ it('should return false for names starting with number', () => {
76
+ expect(isValidFeatureName('123user')).toBe(false);
77
+ });
78
+ it('should return false for names with only special characters', () => {
79
+ expect(isValidFeatureName('@#$%')).toBe(false);
80
+ });
81
+ });
82
+ describe('getFeatureNameError', () => {
83
+ it('should return null for valid names', () => {
84
+ expect(getFeatureNameError('user-profile')).toBeNull();
85
+ expect(getFeatureNameError('UserProfile')).toBeNull();
86
+ });
87
+ it('should return error for empty names', () => {
88
+ expect(getFeatureNameError('')).toBe('Feature name cannot be empty');
89
+ expect(getFeatureNameError(' ')).toBe('Feature name cannot be empty');
90
+ });
91
+ it('should return error for names with only special characters', () => {
92
+ expect(getFeatureNameError('@#$%')).toBe('Feature name must contain at least one alphanumeric character');
93
+ });
94
+ it('should return error for names starting with number', () => {
95
+ expect(getFeatureNameError('123user')).toBe('Feature name must start with a letter');
96
+ });
97
+ });
98
+ });
99
+ //# sourceMappingURL=naming.service.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.service.test.js","sourceRoot":"","sources":["../../src/services/naming.service.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Shared types for the CLI wrapper
3
+ */
4
+ /**
5
+ * Output format for CLI commands
6
+ */
7
+ export type OutputFormat = "human" | "json";
8
+ /**
9
+ * Log level for verbosity control
10
+ */
11
+ export type LogLevel = "quiet" | "normal" | "verbose" | "debug";
12
+ /**
13
+ * Result of a CLI command execution
14
+ *
15
+ * Scripts must return this structure for proper handling.
16
+ */
17
+ export interface CommandResult<T = unknown> {
18
+ /** Whether the command succeeded */
19
+ success: boolean;
20
+ /** Result data (type depends on the command) */
21
+ data?: T;
22
+ /** Error message if success is false */
23
+ error?: string;
24
+ /** Human-readable message */
25
+ message?: string;
26
+ }
27
+ /**
28
+ * Context passed to scripts during execution
29
+ */
30
+ export interface ScriptContext {
31
+ /** Parsed positional arguments */
32
+ args: Record<string, unknown>;
33
+ /** Parsed options */
34
+ options: Record<string, unknown>;
35
+ /** Current working directory */
36
+ cwd: string;
37
+ /** Output format requested */
38
+ format: OutputFormat;
39
+ }
40
+ /**
41
+ * Exit codes for the CLI
42
+ */
43
+ export declare const ExitCode: {
44
+ readonly SUCCESS: 0;
45
+ readonly GENERAL_ERROR: 1;
46
+ readonly INVALID_ARGUMENT: 2;
47
+ readonly CONFIG_ERROR: 3;
48
+ readonly SCRIPT_ERROR: 4;
49
+ };
50
+ export type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode];
51
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAEhE;;;;GAIG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACxC,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;CAMX,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared types for the CLI wrapper
3
+ */
4
+ /**
5
+ * Exit codes for the CLI
6
+ */
7
+ export const ExitCode = {
8
+ SUCCESS: 0,
9
+ GENERAL_ERROR: 1,
10
+ INVALID_ARGUMENT: 2,
11
+ CONFIG_ERROR: 3,
12
+ SCRIPT_ERROR: 4,
13
+ };
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AA0CH;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,CAAC;IAChB,gBAAgB,EAAE,CAAC;IACnB,YAAY,EAAE,CAAC;IACf,YAAY,EAAE,CAAC;CACP,CAAC"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@nicolasmondain/cli-agent",
3
+ "version": "2.1.0",
4
+ "description": "Generic CLI wrapper for executing external scripts, designed for both human developers and AI agents (MCP compatible)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "cli-agent": "./dist/cli/index.js"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/nicolasmondain/cli-agent.git"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "dev": "tsc --watch",
24
+ "start": "node ./dist/cli/index.js",
25
+ "test": "vitest run",
26
+ "test:watch": "vitest",
27
+ "test:coverage": "vitest run --coverage",
28
+ "lint": "eslint src --ext .ts",
29
+ "typecheck": "tsc --noEmit",
30
+ "clean": "rm -rf dist",
31
+ "prepublishOnly": "npm run clean && npm run build",
32
+ "release": "release-it",
33
+ "release:dry": "release-it --dry-run"
34
+ },
35
+ "keywords": [
36
+ "cli",
37
+ "cli-wrapper",
38
+ "command-line",
39
+ "commander",
40
+ "ai",
41
+ "ai-agent",
42
+ "llm",
43
+ "mcp",
44
+ "model-context-protocol",
45
+ "claude",
46
+ "automation",
47
+ "scripts",
48
+ "natural-language",
49
+ "nlp",
50
+ "tool-use",
51
+ "function-calling"
52
+ ],
53
+ "author": "Nicolas Mondain",
54
+ "license": "MIT",
55
+ "engines": {
56
+ "node": ">=20.0.0"
57
+ },
58
+ "dependencies": {
59
+ "commander": "^12.1.0",
60
+ "consola": "^3.2.3"
61
+ },
62
+ "devDependencies": {
63
+ "@release-it/conventional-changelog": "^10.0.4",
64
+ "@types/node": "^20.11.0",
65
+ "release-it": "^19.2.4",
66
+ "tsx": "^4.21.0",
67
+ "typescript": "^5.3.3",
68
+ "vitest": "^2.1.8"
69
+ }
70
+ }