@nxuss/lemma 1.1.1 → 1.2.1

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 (143) hide show
  1. package/README.md +148 -9
  2. package/bin/init.js +135 -84
  3. package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
  4. package/dist/cjs/cli/lemma-proxy.js +2 -0
  5. package/dist/cjs/cli/lemma-proxy.js.map +1 -1
  6. package/dist/cjs/infra/analyzers/DriftDetector.d.ts +4 -0
  7. package/dist/cjs/infra/analyzers/DriftDetector.d.ts.map +1 -0
  8. package/dist/cjs/infra/analyzers/DriftDetector.js +88 -0
  9. package/dist/cjs/infra/analyzers/DriftDetector.js.map +1 -0
  10. package/dist/cjs/infra/analyzers/InfraAnalyzer.d.ts +3 -0
  11. package/dist/cjs/infra/analyzers/InfraAnalyzer.d.ts.map +1 -0
  12. package/dist/cjs/infra/analyzers/InfraAnalyzer.js +73 -0
  13. package/dist/cjs/infra/analyzers/InfraAnalyzer.js.map +1 -0
  14. package/dist/cjs/infra/analyzers/MonolithAnalyzer.d.ts +3 -0
  15. package/dist/cjs/infra/analyzers/MonolithAnalyzer.d.ts.map +1 -0
  16. package/dist/cjs/infra/analyzers/MonolithAnalyzer.js +180 -0
  17. package/dist/cjs/infra/analyzers/MonolithAnalyzer.js.map +1 -0
  18. package/dist/cjs/infra/analyzers/index.d.ts +4 -0
  19. package/dist/cjs/infra/analyzers/index.d.ts.map +1 -0
  20. package/dist/cjs/infra/analyzers/index.js +11 -0
  21. package/dist/cjs/infra/analyzers/index.js.map +1 -0
  22. package/dist/cjs/infra/cli.d.ts +2 -0
  23. package/dist/cjs/infra/cli.d.ts.map +1 -0
  24. package/dist/cjs/infra/cli.js +221 -0
  25. package/dist/cjs/infra/cli.js.map +1 -0
  26. package/dist/cjs/infra/config.d.ts +17 -0
  27. package/dist/cjs/infra/config.d.ts.map +1 -0
  28. package/dist/cjs/infra/config.js +111 -0
  29. package/dist/cjs/infra/config.js.map +1 -0
  30. package/dist/cjs/infra/index.d.ts +8 -0
  31. package/dist/cjs/infra/index.d.ts.map +1 -0
  32. package/dist/cjs/infra/index.js +28 -0
  33. package/dist/cjs/infra/index.js.map +1 -0
  34. package/dist/cjs/infra/mcp-tools.d.ts +16 -0
  35. package/dist/cjs/infra/mcp-tools.d.ts.map +1 -0
  36. package/dist/cjs/infra/mcp-tools.js +456 -0
  37. package/dist/cjs/infra/mcp-tools.js.map +1 -0
  38. package/dist/cjs/infra/providers/InfraProvider.d.ts +9 -0
  39. package/dist/cjs/infra/providers/InfraProvider.d.ts.map +1 -0
  40. package/dist/cjs/infra/providers/InfraProvider.js +3 -0
  41. package/dist/cjs/infra/providers/InfraProvider.js.map +1 -0
  42. package/dist/cjs/infra/providers/JenkinsProvider.d.ts +16 -0
  43. package/dist/cjs/infra/providers/JenkinsProvider.d.ts.map +1 -0
  44. package/dist/cjs/infra/providers/JenkinsProvider.js +188 -0
  45. package/dist/cjs/infra/providers/JenkinsProvider.js.map +1 -0
  46. package/dist/cjs/infra/providers/OKDProvider.d.ts +24 -0
  47. package/dist/cjs/infra/providers/OKDProvider.d.ts.map +1 -0
  48. package/dist/cjs/infra/providers/OKDProvider.js +292 -0
  49. package/dist/cjs/infra/providers/OKDProvider.js.map +1 -0
  50. package/dist/cjs/infra/providers/TerraformProvider.d.ts +17 -0
  51. package/dist/cjs/infra/providers/TerraformProvider.d.ts.map +1 -0
  52. package/dist/cjs/infra/providers/TerraformProvider.js +109 -0
  53. package/dist/cjs/infra/providers/TerraformProvider.js.map +1 -0
  54. package/dist/cjs/infra/providers/index.d.ts +9 -0
  55. package/dist/cjs/infra/providers/index.d.ts.map +1 -0
  56. package/dist/cjs/infra/providers/index.js +34 -0
  57. package/dist/cjs/infra/providers/index.js.map +1 -0
  58. package/dist/cjs/infra/templates/jenkins/index.d.ts +15 -0
  59. package/dist/cjs/infra/templates/jenkins/index.d.ts.map +1 -0
  60. package/dist/cjs/infra/templates/jenkins/index.js +124 -0
  61. package/dist/cjs/infra/templates/jenkins/index.js.map +1 -0
  62. package/dist/cjs/infra/templates/okd/index.d.ts +31 -0
  63. package/dist/cjs/infra/templates/okd/index.d.ts.map +1 -0
  64. package/dist/cjs/infra/templates/okd/index.js +149 -0
  65. package/dist/cjs/infra/templates/okd/index.js.map +1 -0
  66. package/dist/cjs/infra/types.d.ts +128 -0
  67. package/dist/cjs/infra/types.d.ts.map +1 -0
  68. package/dist/cjs/infra/types.js +4 -0
  69. package/dist/cjs/infra/types.js.map +1 -0
  70. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  71. package/dist/cjs/mcp/tools.js +9 -1
  72. package/dist/cjs/mcp/tools.js.map +1 -1
  73. package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
  74. package/dist/esm/cli/lemma-proxy.js +2 -0
  75. package/dist/esm/cli/lemma-proxy.js.map +1 -1
  76. package/dist/esm/infra/analyzers/DriftDetector.d.ts +4 -0
  77. package/dist/esm/infra/analyzers/DriftDetector.d.ts.map +1 -0
  78. package/dist/esm/infra/analyzers/DriftDetector.js +84 -0
  79. package/dist/esm/infra/analyzers/DriftDetector.js.map +1 -0
  80. package/dist/esm/infra/analyzers/InfraAnalyzer.d.ts +3 -0
  81. package/dist/esm/infra/analyzers/InfraAnalyzer.d.ts.map +1 -0
  82. package/dist/esm/infra/analyzers/InfraAnalyzer.js +70 -0
  83. package/dist/esm/infra/analyzers/InfraAnalyzer.js.map +1 -0
  84. package/dist/esm/infra/analyzers/MonolithAnalyzer.d.ts +3 -0
  85. package/dist/esm/infra/analyzers/MonolithAnalyzer.d.ts.map +1 -0
  86. package/dist/esm/infra/analyzers/MonolithAnalyzer.js +174 -0
  87. package/dist/esm/infra/analyzers/MonolithAnalyzer.js.map +1 -0
  88. package/dist/esm/infra/analyzers/index.d.ts +4 -0
  89. package/dist/esm/infra/analyzers/index.d.ts.map +1 -0
  90. package/dist/esm/infra/analyzers/index.js +4 -0
  91. package/dist/esm/infra/analyzers/index.js.map +1 -0
  92. package/dist/esm/infra/cli.d.ts +2 -0
  93. package/dist/esm/infra/cli.d.ts.map +1 -0
  94. package/dist/esm/infra/cli.js +218 -0
  95. package/dist/esm/infra/cli.js.map +1 -0
  96. package/dist/esm/infra/config.d.ts +17 -0
  97. package/dist/esm/infra/config.d.ts.map +1 -0
  98. package/dist/esm/infra/config.js +101 -0
  99. package/dist/esm/infra/config.js.map +1 -0
  100. package/dist/esm/infra/index.d.ts +8 -0
  101. package/dist/esm/infra/index.d.ts.map +1 -0
  102. package/dist/esm/infra/index.js +9 -0
  103. package/dist/esm/infra/index.js.map +1 -0
  104. package/dist/esm/infra/mcp-tools.d.ts +16 -0
  105. package/dist/esm/infra/mcp-tools.d.ts.map +1 -0
  106. package/dist/esm/infra/mcp-tools.js +451 -0
  107. package/dist/esm/infra/mcp-tools.js.map +1 -0
  108. package/dist/esm/infra/providers/InfraProvider.d.ts +9 -0
  109. package/dist/esm/infra/providers/InfraProvider.d.ts.map +1 -0
  110. package/dist/esm/infra/providers/InfraProvider.js +2 -0
  111. package/dist/esm/infra/providers/InfraProvider.js.map +1 -0
  112. package/dist/esm/infra/providers/JenkinsProvider.d.ts +16 -0
  113. package/dist/esm/infra/providers/JenkinsProvider.d.ts.map +1 -0
  114. package/dist/esm/infra/providers/JenkinsProvider.js +181 -0
  115. package/dist/esm/infra/providers/JenkinsProvider.js.map +1 -0
  116. package/dist/esm/infra/providers/OKDProvider.d.ts +24 -0
  117. package/dist/esm/infra/providers/OKDProvider.d.ts.map +1 -0
  118. package/dist/esm/infra/providers/OKDProvider.js +288 -0
  119. package/dist/esm/infra/providers/OKDProvider.js.map +1 -0
  120. package/dist/esm/infra/providers/TerraformProvider.d.ts +17 -0
  121. package/dist/esm/infra/providers/TerraformProvider.d.ts.map +1 -0
  122. package/dist/esm/infra/providers/TerraformProvider.js +105 -0
  123. package/dist/esm/infra/providers/TerraformProvider.js.map +1 -0
  124. package/dist/esm/infra/providers/index.d.ts +9 -0
  125. package/dist/esm/infra/providers/index.d.ts.map +1 -0
  126. package/dist/esm/infra/providers/index.js +27 -0
  127. package/dist/esm/infra/providers/index.js.map +1 -0
  128. package/dist/esm/infra/templates/jenkins/index.d.ts +15 -0
  129. package/dist/esm/infra/templates/jenkins/index.d.ts.map +1 -0
  130. package/dist/esm/infra/templates/jenkins/index.js +120 -0
  131. package/dist/esm/infra/templates/jenkins/index.js.map +1 -0
  132. package/dist/esm/infra/templates/okd/index.d.ts +31 -0
  133. package/dist/esm/infra/templates/okd/index.d.ts.map +1 -0
  134. package/dist/esm/infra/templates/okd/index.js +142 -0
  135. package/dist/esm/infra/templates/okd/index.js.map +1 -0
  136. package/dist/esm/infra/types.d.ts +128 -0
  137. package/dist/esm/infra/types.d.ts.map +1 -0
  138. package/dist/esm/infra/types.js +3 -0
  139. package/dist/esm/infra/types.js.map +1 -0
  140. package/dist/esm/mcp/tools.d.ts.map +1 -1
  141. package/dist/esm/mcp/tools.js +9 -1
  142. package/dist/esm/mcp/tools.js.map +1 -1
  143. package/package.json +3 -2
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectTerraformDrift = detectTerraformDrift;
4
+ exports.detectOKDDrift = detectOKDDrift;
5
+ const child_process_1 = require("child_process");
6
+ function detectTerraformDrift(workDir) {
7
+ try {
8
+ const output = (0, child_process_1.execSync)('terraform plan -detailed-exitcode -no-color', {
9
+ encoding: 'utf8',
10
+ timeout: 60000,
11
+ cwd: workDir,
12
+ stdio: ['pipe', 'pipe', 'pipe'],
13
+ });
14
+ return [];
15
+ }
16
+ catch (err) {
17
+ if (err.status === 2) {
18
+ return parsePlanOutput(err.stdout || '');
19
+ }
20
+ return [];
21
+ }
22
+ }
23
+ function parsePlanOutput(output) {
24
+ const drifts = [];
25
+ const lines = output.split('\n');
26
+ for (const line of lines) {
27
+ const modifiedMatch = line.match(/^\s+~\s+(\S+)/);
28
+ if (modifiedMatch) {
29
+ drifts.push({
30
+ resource: modifiedMatch[1],
31
+ type: 'config',
32
+ expected: 'current state',
33
+ actual: 'will be modified',
34
+ severity: 'MEDIUM',
35
+ });
36
+ continue;
37
+ }
38
+ const removedMatch = line.match(/^\s+-\s+(\S+)/);
39
+ if (removedMatch) {
40
+ drifts.push({
41
+ resource: removedMatch[1],
42
+ type: 'state',
43
+ expected: 'exists',
44
+ actual: 'will be destroyed',
45
+ severity: 'HIGH',
46
+ });
47
+ continue;
48
+ }
49
+ const addedMatch = line.match(/^\s+\+\s+(\S+)/);
50
+ if (addedMatch) {
51
+ drifts.push({
52
+ resource: addedMatch[1],
53
+ type: 'config',
54
+ expected: 'does not exist',
55
+ actual: 'will be created',
56
+ severity: 'LOW',
57
+ });
58
+ }
59
+ }
60
+ return drifts;
61
+ }
62
+ function detectOKDDrift(project) {
63
+ try {
64
+ const raw = (0, child_process_1.execSync)(`oc get all -n ${project} -o json`, {
65
+ encoding: 'utf8',
66
+ timeout: 15000,
67
+ });
68
+ const data = JSON.parse(raw);
69
+ const drifts = [];
70
+ for (const item of data.items || []) {
71
+ const status = item.status;
72
+ if (status?.phase === 'Failed' || status?.phase === 'Error') {
73
+ drifts.push({
74
+ resource: `${item.kind}/${item.metadata.name}`,
75
+ type: 'config',
76
+ expected: 'Running',
77
+ actual: status.phase,
78
+ severity: 'HIGH',
79
+ });
80
+ }
81
+ }
82
+ return drifts;
83
+ }
84
+ catch {
85
+ return [];
86
+ }
87
+ }
88
+ //# sourceMappingURL=DriftDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DriftDetector.js","sourceRoot":"","sources":["../../../../src/infra/analyzers/DriftDetector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { InfraAnalysisResult } from '../types';
2
+ export declare function analyzeInfra(provider: string, status: Record<string, any>): InfraAnalysisResult;
3
+ //# sourceMappingURL=InfraAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InfraAnalyzer.d.ts","sourceRoot":"","sources":["../../../../src/infra/analyzers/InfraAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAElE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,mBAAmB,CAwE/F"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.analyzeInfra = analyzeInfra;
4
+ function analyzeInfra(provider, status) {
5
+ const findings = [];
6
+ if (provider === 'okd') {
7
+ const podList = status.podList || [];
8
+ for (const pod of podList) {
9
+ if (pod.status !== 'Running') {
10
+ findings.push({
11
+ ruleId: 'okd-pod-not-running',
12
+ severity: pod.status === 'CrashLoopBackOff' ? 'CRITICAL' : 'HIGH',
13
+ category: 'reliability',
14
+ resource: pod.name,
15
+ message: `Pod ${pod.name} is in ${pod.status}`,
16
+ suggestion: 'Check pod logs: oc logs ' + pod.name,
17
+ autoFixAvailable: false,
18
+ });
19
+ }
20
+ if (pod.restarts > 3) {
21
+ findings.push({
22
+ ruleId: 'okd-high-restarts',
23
+ severity: 'MEDIUM',
24
+ category: 'reliability',
25
+ resource: pod.name,
26
+ message: `Pod ${pod.name} has ${pod.restarts} restarts`,
27
+ suggestion: 'Investigate crash reason in pod logs',
28
+ autoFixAvailable: false,
29
+ });
30
+ }
31
+ }
32
+ }
33
+ if (provider === 'jenkins') {
34
+ const jobs = status.jobs || [];
35
+ for (const job of jobs) {
36
+ if (job.color === 'red') {
37
+ findings.push({
38
+ ruleId: 'jenkins-failed-build',
39
+ severity: 'HIGH',
40
+ category: 'reliability',
41
+ resource: job.name,
42
+ message: `Jenkins job ${job.name} last build failed`,
43
+ suggestion: 'Check build logs and fix the failure',
44
+ autoFixAvailable: false,
45
+ });
46
+ }
47
+ if (job.building) {
48
+ findings.push({
49
+ ruleId: 'jenkins-active-build',
50
+ severity: 'LOW',
51
+ category: 'performance',
52
+ resource: job.name,
53
+ message: `Jenkins job ${job.name} is currently building`,
54
+ suggestion: 'No action needed, build in progress',
55
+ autoFixAvailable: false,
56
+ });
57
+ }
58
+ }
59
+ }
60
+ const score = Math.max(0, 100 - findings.reduce((sum, f) => {
61
+ const deduction = f.severity === 'CRITICAL' ? 25 : f.severity === 'HIGH' ? 15 : f.severity === 'MEDIUM' ? 8 : 3;
62
+ return sum + deduction;
63
+ }, 0));
64
+ return {
65
+ findings,
66
+ score,
67
+ provider,
68
+ summary: findings.length === 0
69
+ ? `All ${provider} resources are healthy.`
70
+ : `Found ${findings.length} issue(s) in ${provider} (score: ${score}/100)`,
71
+ };
72
+ }
73
+ //# sourceMappingURL=InfraAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InfraAnalyzer.js","sourceRoot":"","sources":["../../../../src/infra/analyzers/InfraAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { MonolithAnalysis } from '../types';
2
+ export declare function analyzeMonolith(workspaceRoot: string): MonolithAnalysis;
3
+ //# sourceMappingURL=MonolithAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MonolithAnalyzer.d.ts","sourceRoot":"","sources":["../../../../src/infra/analyzers/MonolithAnalyzer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAA6C,MAAM,UAAU,CAAC;AAE5F,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,gBAAgB,CAOvE"}
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.analyzeMonolith = analyzeMonolith;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ function analyzeMonolith(workspaceRoot) {
10
+ const modules = discoverModules(workspaceRoot);
11
+ const couplingScore = calculateCoupling(modules);
12
+ const suggestedSplits = suggestSplits(modules);
13
+ const migrationPlan = generateMigrationPlan(suggestedSplits);
14
+ return { modules, couplingScore, suggestedSplits, migrationPlan };
15
+ }
16
+ function discoverModules(root) {
17
+ const modules = [];
18
+ const srcDir = path_1.default.join(root, 'src');
19
+ if (!fs_1.default.existsSync(srcDir))
20
+ return modules;
21
+ const entries = fs_1.default.readdirSync(srcDir, { withFileTypes: true });
22
+ for (const entry of entries) {
23
+ if (!entry.isDirectory())
24
+ continue;
25
+ const modulePath = path_1.default.join(srcDir, entry.name);
26
+ const files = countTsFiles(modulePath);
27
+ const deps = extractImports(modulePath);
28
+ const entryPoints = findEntryPoints(modulePath);
29
+ modules.push({
30
+ name: entry.name,
31
+ files,
32
+ dependencies: deps,
33
+ entryPoints,
34
+ complexity: estimateComplexity(modulePath),
35
+ });
36
+ }
37
+ return modules;
38
+ }
39
+ function countTsFiles(dir) {
40
+ let count = 0;
41
+ try {
42
+ const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
43
+ for (const e of entries) {
44
+ if (e.isFile() && /\.(ts|tsx|js|jsx)$/.test(e.name))
45
+ count++;
46
+ else if (e.isDirectory())
47
+ count += countTsFiles(path_1.default.join(dir, e.name));
48
+ }
49
+ }
50
+ catch { }
51
+ return count;
52
+ }
53
+ function extractImports(dir) {
54
+ const imports = new Set();
55
+ try {
56
+ const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
57
+ for (const e of entries) {
58
+ if (e.isFile() && /\.(ts|tsx)$/.test(e.name)) {
59
+ const content = fs_1.default.readFileSync(path_1.default.join(dir, e.name), 'utf8');
60
+ const importMatches = content.matchAll(/from\s+['"]\.\.\/(\w+)/g);
61
+ for (const m of importMatches)
62
+ imports.add(m[1]);
63
+ }
64
+ else if (e.isDirectory()) {
65
+ extractImports(path_1.default.join(dir, e.name)).forEach((i) => imports.add(i));
66
+ }
67
+ }
68
+ }
69
+ catch { }
70
+ return Array.from(imports);
71
+ }
72
+ function findEntryPoints(dir) {
73
+ const points = [];
74
+ try {
75
+ const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
76
+ for (const e of entries) {
77
+ if (e.isFile() && /^(index|main|app|server|server)\.(ts|tsx|js)$/.test(e.name)) {
78
+ points.push(e.name);
79
+ }
80
+ }
81
+ }
82
+ catch { }
83
+ return points;
84
+ }
85
+ function estimateComplexity(dir) {
86
+ let totalLines = 0;
87
+ try {
88
+ const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
89
+ for (const e of entries) {
90
+ if (e.isFile() && /\.(ts|tsx)$/.test(e.name)) {
91
+ totalLines += fs_1.default.readFileSync(path_1.default.join(dir, e.name), 'utf8').split('\n').length;
92
+ }
93
+ else if (e.isDirectory()) {
94
+ totalLines += estimateComplexity(path_1.default.join(dir, e.name));
95
+ }
96
+ }
97
+ }
98
+ catch { }
99
+ return totalLines;
100
+ }
101
+ function calculateCoupling(modules) {
102
+ if (modules.length === 0)
103
+ return 0;
104
+ let crossDeps = 0;
105
+ const moduleNames = new Set(modules.map((m) => m.name));
106
+ for (const m of modules) {
107
+ for (const dep of m.dependencies) {
108
+ if (moduleNames.has(dep) && dep !== m.name)
109
+ crossDeps++;
110
+ }
111
+ }
112
+ const maxDeps = modules.length * (modules.length - 1);
113
+ return maxDeps > 0 ? Math.round((crossDeps / maxDeps) * 100) : 0;
114
+ }
115
+ function suggestSplits(modules) {
116
+ const suggestions = [];
117
+ const highCoupling = modules.filter((m) => m.dependencies.length > 2);
118
+ if (highCoupling.length > 0) {
119
+ suggestions.push({
120
+ name: 'Core Services',
121
+ includes: highCoupling.map((m) => m.name),
122
+ rationale: 'High inter-dependency suggests these should stay together initially',
123
+ estimatedEffort: 'high',
124
+ });
125
+ }
126
+ const standalone = modules.filter((m) => m.dependencies.length <= 1 && m.files > 5);
127
+ for (const m of standalone) {
128
+ suggestions.push({
129
+ name: `${m.name}-service`,
130
+ includes: [m.name],
131
+ rationale: `Low coupling (${m.dependencies.length} deps) makes this a good candidate for extraction`,
132
+ estimatedEffort: m.files < 20 ? 'low' : 'medium',
133
+ });
134
+ }
135
+ return suggestions;
136
+ }
137
+ function generateMigrationPlan(splits) {
138
+ const steps = [];
139
+ let order = 1;
140
+ steps.push({
141
+ order: order++,
142
+ action: 'Audit current dependencies',
143
+ detail: 'Run lemma infra analyze monolith to get full dependency graph',
144
+ risk: 'LOW',
145
+ });
146
+ for (const split of splits) {
147
+ if (split.estimatedEffort === 'low') {
148
+ steps.push({
149
+ order: order++,
150
+ action: `Extract ${split.name}`,
151
+ detail: `Move ${split.includes.join(', ')} to separate service. ${split.rationale}`,
152
+ risk: 'LOW',
153
+ });
154
+ }
155
+ }
156
+ for (const split of splits) {
157
+ if (split.estimatedEffort === 'medium' || split.estimatedEffort === 'high') {
158
+ steps.push({
159
+ order: order++,
160
+ action: `Refactor ${split.name}`,
161
+ detail: `${split.rationale}. Estimated effort: ${split.estimatedEffort}`,
162
+ risk: 'MEDIUM',
163
+ });
164
+ }
165
+ }
166
+ steps.push({
167
+ order: order++,
168
+ action: 'Set up inter-service communication',
169
+ detail: 'Implement API gateway, service discovery, and shared contracts',
170
+ risk: 'HIGH',
171
+ });
172
+ steps.push({
173
+ order: order++,
174
+ action: 'Deploy and monitor',
175
+ detail: 'Gradual rollout with feature flags and canary deployments',
176
+ risk: 'HIGH',
177
+ });
178
+ return steps;
179
+ }
180
+ //# sourceMappingURL=MonolithAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MonolithAnalyzer.js","sourceRoot":"","sources":["../../../../src/infra/analyzers/MonolithAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { analyzeInfra } from './InfraAnalyzer';
2
+ export { detectTerraformDrift, detectOKDDrift } from './DriftDetector';
3
+ export { analyzeMonolith } from './MonolithAnalyzer';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/infra/analyzers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.analyzeMonolith = exports.detectOKDDrift = exports.detectTerraformDrift = exports.analyzeInfra = void 0;
4
+ var InfraAnalyzer_1 = require("./InfraAnalyzer");
5
+ Object.defineProperty(exports, "analyzeInfra", { enumerable: true, get: function () { return InfraAnalyzer_1.analyzeInfra; } });
6
+ var DriftDetector_1 = require("./DriftDetector");
7
+ Object.defineProperty(exports, "detectTerraformDrift", { enumerable: true, get: function () { return DriftDetector_1.detectTerraformDrift; } });
8
+ Object.defineProperty(exports, "detectOKDDrift", { enumerable: true, get: function () { return DriftDetector_1.detectOKDDrift; } });
9
+ var MonolithAnalyzer_1 = require("./MonolithAnalyzer");
10
+ Object.defineProperty(exports, "analyzeMonolith", { enumerable: true, get: function () { return MonolithAnalyzer_1.analyzeMonolith; } });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/infra/analyzers/index.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AACrB,iDAAuE;AAA9D,qHAAA,oBAAoB,OAAA;AAAE,+GAAA,cAAc,OAAA;AAC7C,uDAAqD;AAA5C,mHAAA,eAAe,OAAA"}
@@ -0,0 +1,2 @@
1
+ export declare function registerInfraCommands(): void;
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/infra/cli.ts"],"names":[],"mappings":"AAIA,wBAAgB,qBAAqB,IAAI,IAAI,CA0M5C"}
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerInfraCommands = registerInfraCommands;
4
+ const commander_1 = require("commander");
5
+ const config_1 = require("./config");
6
+ const providers_1 = require("./providers");
7
+ function registerInfraCommands() {
8
+ const infra = commander_1.program.command('infra').description('Infrastructure Command Center — manage Jenkins, OKD, and Terraform');
9
+ infra.command('discover')
10
+ .description('Auto-detect infrastructure providers')
11
+ .action(async () => {
12
+ const cfg = (0, config_1.getInfraConfig)();
13
+ console.log('Infrastructure Discovery:');
14
+ if (cfg.jenkins?.url)
15
+ console.log(` Jenkins: ${cfg.jenkins.url}`);
16
+ if (cfg.okd?.server)
17
+ console.log(` OKD: ${cfg.okd.server} (project: ${cfg.okd.project})`);
18
+ if (cfg.terraform?.backend)
19
+ console.log(` Terraform: ${cfg.terraform.backend} backend`);
20
+ console.log('\nUse `lemma infra connect <provider>` to connect.');
21
+ });
22
+ infra.command('connect <provider>')
23
+ .description('Connect to an infrastructure provider')
24
+ .option('-u, --url <url>', 'Provider URL')
25
+ .option('-t, --token <token>', 'Auth token')
26
+ .option('-p, --project <project>', 'OKD project')
27
+ .action(async (provider, opts) => {
28
+ try {
29
+ const p = (0, providers_1.getProvider)(provider);
30
+ const config = {};
31
+ if (provider === 'jenkins') {
32
+ config.url = opts.url;
33
+ }
34
+ else if (provider === 'okd') {
35
+ config.server = opts.url;
36
+ config.token = opts.token;
37
+ config.project = opts.project;
38
+ }
39
+ else if (provider === 'terraform') {
40
+ config.backend = 's3';
41
+ config.workDir = process.cwd();
42
+ }
43
+ const ok = await p.connect(config);
44
+ console.log(ok ? `Connected to ${provider}.` : `Failed to connect to ${provider}.`);
45
+ }
46
+ catch (err) {
47
+ console.error(`Error: ${err.message}`);
48
+ }
49
+ });
50
+ infra.command('status')
51
+ .description('Show status of all connected providers')
52
+ .action(async () => {
53
+ const cfg = (0, config_1.getInfraConfig)();
54
+ const providers = ['jenkins', 'okd', 'terraform'].filter((p) => {
55
+ if (p === 'jenkins')
56
+ return !!cfg.jenkins?.url;
57
+ if (p === 'okd')
58
+ return !!cfg.okd?.server;
59
+ if (p === 'terraform')
60
+ return !!cfg.terraform?.backend;
61
+ return false;
62
+ });
63
+ if (providers.length === 0) {
64
+ console.log('No providers configured. Add config to lemma.config.json under "infra".');
65
+ return;
66
+ }
67
+ for (const name of providers) {
68
+ try {
69
+ const p = (0, providers_1.getProvider)(name);
70
+ const health = await p.healthCheck();
71
+ const icon = health.status === 'healthy' ? '\x1b[32mOK\x1b[0m' : health.status === 'degraded' ? '\x1b[33mWARN\x1b[0m' : '\x1b[31mDOWN\x1b[0m';
72
+ console.log(` [${icon}] ${name}: ${health.status} (${health.latency}ms)`);
73
+ }
74
+ catch {
75
+ console.log(` [\x1b[31mDOWN\x1b[0m] ${name}: unreachable`);
76
+ }
77
+ }
78
+ });
79
+ infra.command('deploy jenkins')
80
+ .description('Generate and trigger Jenkins pipeline')
81
+ .option('-n, --name <name>', 'Project name')
82
+ .option('-j, --job <job>', 'Jenkins job name to trigger')
83
+ .action(async (opts) => {
84
+ const cfg = (0, config_1.getInfraConfig)();
85
+ if (!cfg.jenkins?.url) {
86
+ console.error('Jenkins not configured in lemma.config.json');
87
+ return;
88
+ }
89
+ if (opts.name) {
90
+ const { jenkinsfileTemplate } = require('./templates/jenkins');
91
+ console.log(jenkinsfileTemplate({ name: opts.name }));
92
+ }
93
+ if (opts.job) {
94
+ const p = (0, providers_1.getProvider)('jenkins');
95
+ const result = await p.triggerBuild(opts.job);
96
+ console.log(result.success ? `Build triggered: ${result.logs[0]}` : `Failed: ${result.logs[0]}`);
97
+ }
98
+ });
99
+ infra.command('deploy okd')
100
+ .description('Generate and apply OKD manifests')
101
+ .option('-n, --name <name>', 'Application name')
102
+ .option('-i, --image <image>', 'Container image')
103
+ .option('--dry-run', 'Only generate, do not apply')
104
+ .action(async (opts) => {
105
+ const cfg = (0, config_1.getInfraConfig)();
106
+ if (!cfg.okd?.server) {
107
+ console.error('OKD not configured in lemma.config.json');
108
+ return;
109
+ }
110
+ const p = (0, providers_1.getProvider)('okd');
111
+ const manifests = p.generateManifests({
112
+ name: opts.name,
113
+ image: opts.image,
114
+ port: 8080,
115
+ replicas: 2,
116
+ });
117
+ if (opts.dryRun) {
118
+ console.log(Object.entries(manifests).map(([k, v]) => `--- ${k} ---\n${v}`).join('\n\n'));
119
+ }
120
+ else {
121
+ const result = await p.apply(manifests, false);
122
+ console.log(result.logs.join('\n'));
123
+ console.log(`\nNext steps:\n${result.nextSteps.join('\n')}`);
124
+ }
125
+ });
126
+ infra.command('logs <provider>')
127
+ .description('Get logs from Jenkins or OKD')
128
+ .argument('[target]', 'Job name (Jenkins) or pod name (OKD)')
129
+ .option('-n, --number <n>', 'Build number (Jenkins) or lines (OKD)', '50')
130
+ .action(async (provider, target, opts) => {
131
+ try {
132
+ const p = (0, providers_1.getProvider)(provider);
133
+ if (provider === 'jenkins') {
134
+ const logs = await p.getBuildLogs(target, parseInt(opts.number, 10));
135
+ console.log(logs);
136
+ }
137
+ else if (provider === 'okd') {
138
+ const logs = await p.getLogs(target, parseInt(opts.number, 10));
139
+ console.log(logs);
140
+ }
141
+ }
142
+ catch (err) {
143
+ console.error(`Error: ${err.message}`);
144
+ }
145
+ });
146
+ infra.command('diagnose [provider]')
147
+ .description('Diagnose infrastructure issues')
148
+ .action(async (provider) => {
149
+ const providers = provider ? [provider] : ['jenkins', 'okd', 'terraform'];
150
+ for (const name of providers) {
151
+ try {
152
+ const p = (0, providers_1.getProvider)(name);
153
+ const status = await p.getStatus();
154
+ const { analyzeInfra } = require('./analyzers');
155
+ const analysis = analyzeInfra(name, status);
156
+ console.log(`\n[${name.toUpperCase()}] Score: ${analysis.score}/100`);
157
+ for (const f of analysis.findings) {
158
+ console.log(` [${f.severity}] ${f.resource}: ${f.message}`);
159
+ console.log(` Fix: ${f.suggestion}`);
160
+ }
161
+ }
162
+ catch (err) {
163
+ console.log(`[${name}] Skipped: ${err.message}`);
164
+ }
165
+ }
166
+ });
167
+ infra.command('terraform plan')
168
+ .description('Run terraform plan')
169
+ .action(async () => {
170
+ const p = (0, providers_1.getProvider)('terraform');
171
+ const plan = await p.plan();
172
+ console.log(plan);
173
+ });
174
+ infra.command('terraform apply')
175
+ .description('Run terraform apply')
176
+ .option('--auto-approve', 'Skip confirmation')
177
+ .action(async (opts) => {
178
+ const p = (0, providers_1.getProvider)('terraform');
179
+ const result = await p.apply(opts.autoApprove);
180
+ console.log(result);
181
+ });
182
+ infra.command('terraform state')
183
+ .description('List resources in Terraform state')
184
+ .action(async () => {
185
+ const p = (0, providers_1.getProvider)('terraform');
186
+ const resources = await p.stateList();
187
+ resources.forEach((r) => console.log(` ${r}`));
188
+ });
189
+ infra.command('terraform drift')
190
+ .description('Detect configuration drift')
191
+ .action(async () => {
192
+ const p = (0, providers_1.getProvider)('terraform');
193
+ const drifts = await p.detectDrift();
194
+ if (drifts.length === 0) {
195
+ console.log('No drift detected.');
196
+ return;
197
+ }
198
+ for (const d of drifts) {
199
+ console.log(` [${d.severity}] ${d.resource}: ${d.actual}`);
200
+ }
201
+ });
202
+ infra.command('analyze monolith')
203
+ .description('Analyze codebase for microservice migration')
204
+ .action(async () => {
205
+ const { analyzeMonolith } = require('./analyzers');
206
+ const analysis = analyzeMonolith(process.cwd());
207
+ console.log(`Modules: ${analysis.modules.length} | Coupling: ${analysis.couplingScore}%`);
208
+ for (const m of analysis.modules) {
209
+ console.log(` ${m.name}: ${m.files} files, ${m.complexity} LOC`);
210
+ }
211
+ console.log('\nSuggested Splits:');
212
+ for (const s of analysis.suggestedSplits) {
213
+ console.log(` ${s.name}: ${s.rationale} (effort: ${s.estimatedEffort})`);
214
+ }
215
+ console.log('\nMigration Plan:');
216
+ for (const step of analysis.migrationPlan) {
217
+ console.log(` ${step.order}. [${step.risk}] ${step.action}: ${step.detail}`);
218
+ }
219
+ });
220
+ }
221
+ //# sourceMappingURL=cli.js.map