@evolith/smart-cli 0.0.3-beta → 1.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 (156) hide show
  1. package/README.es.md +51 -15
  2. package/README.md +51 -15
  3. package/dist/app.module.js +2 -0
  4. package/dist/app.module.js.map +1 -1
  5. package/dist/application/ports/webhook-notifier.port.d.ts +4 -0
  6. package/dist/application/ports/webhook-notifier.port.js +3 -0
  7. package/dist/application/ports/webhook-notifier.port.js.map +1 -0
  8. package/dist/application/services/index.d.ts +1 -0
  9. package/dist/application/services/index.js +28 -2
  10. package/dist/application/services/index.js.map +1 -1
  11. package/dist/application/services/initialize-project.spec.d.ts +1 -0
  12. package/dist/application/services/initialize-project.spec.js +211 -0
  13. package/dist/application/services/initialize-project.spec.js.map +1 -0
  14. package/dist/application/use-cases/evaluate-gate.use-case.d.ts +20 -0
  15. package/dist/application/use-cases/evaluate-gate.use-case.js +72 -0
  16. package/dist/application/use-cases/evaluate-gate.use-case.js.map +1 -0
  17. package/dist/application/use-cases/validate-satellite.use-case.d.ts +1 -0
  18. package/dist/application/use-cases/validate-satellite.use-case.js +7 -3
  19. package/dist/application/use-cases/validate-satellite.use-case.js.map +1 -1
  20. package/dist/commands/adr/adr.command.d.ts +2 -0
  21. package/dist/commands/adr/adr.command.js +36 -14
  22. package/dist/commands/adr/adr.command.js.map +1 -1
  23. package/dist/commands/architecture/scaffold.command.d.ts +1 -0
  24. package/dist/commands/architecture/scaffold.command.js +23 -1
  25. package/dist/commands/architecture/scaffold.command.js.map +1 -1
  26. package/dist/commands/gate/gate.command.d.ts +23 -0
  27. package/dist/commands/gate/gate.command.js +210 -0
  28. package/dist/commands/gate/gate.command.js.map +1 -0
  29. package/dist/commands/sdlc/gate-status.command.d.ts +3 -1
  30. package/dist/commands/sdlc/gate-status.command.js +78 -3
  31. package/dist/commands/sdlc/gate-status.command.js.map +1 -1
  32. package/dist/commands/sdlc/gate-status.command.spec.d.ts +1 -0
  33. package/dist/commands/sdlc/gate-status.command.spec.js +302 -0
  34. package/dist/commands/sdlc/gate-status.command.spec.js.map +1 -0
  35. package/dist/commands/sdlc/generate-domain.command.d.ts +2 -0
  36. package/dist/commands/sdlc/generate-domain.command.js +123 -12
  37. package/dist/commands/sdlc/generate-domain.command.js.map +1 -1
  38. package/dist/commands/sdlc/generate-domain.command.spec.js +103 -29
  39. package/dist/commands/sdlc/generate-domain.command.spec.js.map +1 -1
  40. package/dist/commands/sdlc/handoff.command.js +2 -2
  41. package/dist/commands/sdlc/handoff.command.js.map +1 -1
  42. package/dist/commands/sdlc/sdlc.command.js +40 -6
  43. package/dist/commands/sdlc/sdlc.command.js.map +1 -1
  44. package/dist/commands/sdlc/sdlc.command.spec.js +48 -14
  45. package/dist/commands/sdlc/sdlc.command.spec.js.map +1 -1
  46. package/dist/commands/validate/validate.command.d.ts +2 -0
  47. package/dist/commands/validate/validate.command.js +16 -2
  48. package/dist/commands/validate/validate.command.js.map +1 -1
  49. package/dist/core/abstractions/interfaces.d.ts +1 -0
  50. package/dist/core/abstractions/interfaces.js.map +1 -1
  51. package/dist/core/abstractions/providers/config-parser.provider.spec.d.ts +1 -0
  52. package/dist/core/abstractions/providers/config-parser.provider.spec.js +18 -0
  53. package/dist/core/abstractions/providers/config-parser.provider.spec.js.map +1 -0
  54. package/dist/core/abstractions/providers/mock-filesystem.provider.d.ts +1 -0
  55. package/dist/core/abstractions/providers/mock-filesystem.provider.js +4 -0
  56. package/dist/core/abstractions/providers/mock-filesystem.provider.js.map +1 -1
  57. package/dist/core/abstractions/providers/mock-filesystem.provider.spec.d.ts +1 -0
  58. package/dist/core/abstractions/providers/mock-filesystem.provider.spec.js +56 -0
  59. package/dist/core/abstractions/providers/mock-filesystem.provider.spec.js.map +1 -0
  60. package/dist/core/abstractions/providers/node-filesystem.provider.d.ts +1 -0
  61. package/dist/core/abstractions/providers/node-filesystem.provider.js +4 -0
  62. package/dist/core/abstractions/providers/node-filesystem.provider.js.map +1 -1
  63. package/dist/core/architecture/nx-workspace.strategy.d.ts +3 -0
  64. package/dist/core/architecture/nx-workspace.strategy.js +35 -6
  65. package/dist/core/architecture/nx-workspace.strategy.js.map +1 -1
  66. package/dist/core/architecture/nx-workspace.strategy.spec.d.ts +1 -0
  67. package/dist/core/architecture/nx-workspace.strategy.spec.js +187 -0
  68. package/dist/core/architecture/nx-workspace.strategy.spec.js.map +1 -0
  69. package/dist/core/architecture/workspace-manager.strategy.d.ts +1 -0
  70. package/dist/core/generators/hexagonal-scaffolder.d.ts +6 -0
  71. package/dist/core/generators/hexagonal-scaffolder.js +260 -0
  72. package/dist/core/generators/hexagonal-scaffolder.js.map +1 -0
  73. package/dist/core/generators/hexagonal-scaffolder.spec.d.ts +1 -0
  74. package/dist/core/generators/hexagonal-scaffolder.spec.js +164 -0
  75. package/dist/core/generators/hexagonal-scaffolder.spec.js.map +1 -0
  76. package/dist/core/generators/mermaid-class-parser.d.ts +38 -0
  77. package/dist/core/generators/mermaid-class-parser.js +183 -0
  78. package/dist/core/generators/mermaid-class-parser.js.map +1 -0
  79. package/dist/core/generators/mermaid-class-parser.spec.d.ts +1 -0
  80. package/dist/core/generators/mermaid-class-parser.spec.js +148 -0
  81. package/dist/core/generators/mermaid-class-parser.spec.js.map +1 -0
  82. package/dist/core/mcp/server.d.ts +3 -1
  83. package/dist/core/mcp/server.js +82 -108
  84. package/dist/core/mcp/server.js.map +1 -1
  85. package/dist/core/mcp/server.spec.js +20 -4
  86. package/dist/core/mcp/server.spec.js.map +1 -1
  87. package/dist/core/mcp/tools/gate.d.ts +1 -0
  88. package/dist/core/mcp/tools/gate.js +68 -0
  89. package/dist/core/mcp/tools/gate.js.map +1 -0
  90. package/dist/core/metrics/dora-calculator.d.ts +18 -0
  91. package/dist/core/metrics/dora-calculator.js +146 -0
  92. package/dist/core/metrics/dora-calculator.js.map +1 -0
  93. package/dist/core/metrics/dora-calculator.spec.d.ts +1 -0
  94. package/dist/core/metrics/dora-calculator.spec.js +164 -0
  95. package/dist/core/metrics/dora-calculator.spec.js.map +1 -0
  96. package/dist/core/metrics/git-log-reader.d.ts +14 -0
  97. package/dist/core/metrics/git-log-reader.js +39 -0
  98. package/dist/core/metrics/git-log-reader.js.map +1 -0
  99. package/dist/core/metrics/git-log-reader.spec.d.ts +1 -0
  100. package/dist/core/metrics/git-log-reader.spec.js +108 -0
  101. package/dist/core/metrics/git-log-reader.spec.js.map +1 -0
  102. package/dist/core/observability/command-watcher.spec.d.ts +1 -0
  103. package/dist/core/observability/command-watcher.spec.js +123 -0
  104. package/dist/core/observability/command-watcher.spec.js.map +1 -0
  105. package/dist/core/observability/index.d.ts +1 -0
  106. package/dist/core/observability/index.js +3 -1
  107. package/dist/core/observability/index.js.map +1 -1
  108. package/dist/core/observability/tool-usage-telemetry.service.d.ts +46 -0
  109. package/dist/core/observability/tool-usage-telemetry.service.js +181 -0
  110. package/dist/core/observability/tool-usage-telemetry.service.js.map +1 -0
  111. package/dist/core/services/command-history.service.d.ts +1 -0
  112. package/dist/core/services/command-history.service.js +4 -0
  113. package/dist/core/services/command-history.service.js.map +1 -1
  114. package/dist/core/services/command-history.service.spec.js +217 -126
  115. package/dist/core/services/command-history.service.spec.js.map +1 -1
  116. package/dist/core/upgrade/satellite-upgrade.service.spec.js +204 -144
  117. package/dist/core/upgrade/satellite-upgrade.service.spec.js.map +1 -1
  118. package/dist/core/validators/deep-architecture-analyzer.spec.js +27 -57
  119. package/dist/core/validators/deep-architecture-analyzer.spec.js.map +1 -1
  120. package/dist/core/validators/evaluators/evaluator.interface.d.ts +14 -0
  121. package/dist/core/validators/evaluators/evaluator.interface.js +3 -0
  122. package/dist/core/validators/evaluators/evaluator.interface.js.map +1 -0
  123. package/dist/core/validators/evaluators/native-evaluator.d.ts +31 -0
  124. package/dist/core/validators/evaluators/native-evaluator.js +461 -0
  125. package/dist/core/validators/evaluators/native-evaluator.js.map +1 -0
  126. package/dist/core/validators/evaluators/opa-evaluator.d.ts +20 -0
  127. package/dist/core/validators/evaluators/opa-evaluator.js +249 -0
  128. package/dist/core/validators/evaluators/opa-evaluator.js.map +1 -0
  129. package/dist/core/validators/phase-gate-validator.service.d.ts +4 -0
  130. package/dist/core/validators/phase-gate-validator.service.js +74 -9
  131. package/dist/core/validators/phase-gate-validator.service.js.map +1 -1
  132. package/dist/core/validators/rule-evaluation-engine.d.ts +34 -0
  133. package/dist/core/validators/rule-evaluation-engine.js +187 -0
  134. package/dist/core/validators/rule-evaluation-engine.js.map +1 -0
  135. package/dist/core/validators/rule-evaluation-engine.spec.d.ts +1 -0
  136. package/dist/core/validators/rule-evaluation-engine.spec.js +243 -0
  137. package/dist/core/validators/rule-evaluation-engine.spec.js.map +1 -0
  138. package/dist/core/validators/ruleset-validator.service.d.ts +2 -0
  139. package/dist/core/validators/ruleset-validator.service.js +29 -4
  140. package/dist/core/validators/ruleset-validator.service.js.map +1 -1
  141. package/dist/domain/gate-evidence.d.ts +59 -0
  142. package/dist/domain/gate-evidence.js +38 -0
  143. package/dist/domain/gate-evidence.js.map +1 -0
  144. package/dist/domain/services/adr.service.d.ts +2 -2
  145. package/dist/domain/services/adr.service.js +12 -8
  146. package/dist/domain/services/adr.service.js.map +1 -1
  147. package/dist/infrastructure/adapters/webhook.adapter.d.ts +5 -0
  148. package/dist/infrastructure/adapters/webhook.adapter.js +19 -0
  149. package/dist/infrastructure/adapters/webhook.adapter.js.map +1 -0
  150. package/dist/infrastructure/cli/command-executor.spec.d.ts +1 -0
  151. package/dist/infrastructure/cli/command-executor.spec.js +149 -0
  152. package/dist/infrastructure/cli/command-executor.spec.js.map +1 -0
  153. package/dist/infrastructure/cli/providers/providers.spec.d.ts +1 -0
  154. package/dist/infrastructure/cli/providers/providers.spec.js +251 -0
  155. package/dist/infrastructure/cli/providers/providers.spec.js.map +1 -0
  156. package/package.json +23 -5
@@ -34,133 +34,224 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const command_history_service_1 = require("./command-history.service");
37
+ jest.mock('fs-extra');
37
38
  const fs = __importStar(require("fs-extra"));
38
- jest.mock('fs-extra', () => ({
39
- ensureDir: jest.fn().mockResolvedValue(undefined),
40
- pathExists: jest.fn().mockResolvedValue(false),
41
- readFile: jest.fn().mockResolvedValue(''),
42
- appendFile: jest.fn().mockResolvedValue(undefined),
43
- writeFile: jest.fn().mockResolvedValue(undefined),
44
- remove: jest.fn().mockResolvedValue(undefined),
45
- }));
46
- const mockedFs = fs;
47
- describe('CommandHistoryService', () => {
48
- let service;
49
- let counter = 0;
50
- beforeEach(() => {
51
- jest.clearAllMocks();
52
- mockedFs.pathExists.mockResolvedValue(false);
53
- mockedFs.readFile.mockResolvedValue('');
54
- mockedFs.appendFile.mockResolvedValue(undefined);
55
- mockedFs.remove.mockResolvedValue(undefined);
56
- service = new command_history_service_1.CommandHistoryService(`/tmp/test-repo-${Date.now()}-${++counter}`);
57
- });
58
- describe('initialize', () => {
59
- it('should create history directory', async () => {
60
- await service.initialize();
61
- expect(mockedFs.ensureDir).toHaveBeenCalled();
62
- });
63
- it('should load existing history from file', async () => {
64
- const mockHistory = [
65
- JSON.stringify({ id: 'h-000001', timestamp: '2026-01-01', command: 'validate', args: [], exitCode: 0, durationMs: 100, success: true }),
66
- JSON.stringify({ id: 'h-000002', timestamp: '2026-01-02', command: 'init', args: ['--name', 'test'], exitCode: 0, durationMs: 200, success: true }),
67
- ].join('\n');
68
- let readCount = 0;
69
- mockedFs.pathExists.mockImplementation(async () => true);
70
- mockedFs.readFile.mockImplementation(async () => {
71
- readCount++;
72
- return readCount === 1 ? mockHistory : '';
73
- });
74
- const newService = new command_history_service_1.CommandHistoryService(`/tmp/test-repo-load-${Date.now()}-${++counter}`);
75
- await newService.initialize();
76
- const entries = await newService.list();
77
- expect(entries.length).toBeGreaterThanOrEqual(2);
78
- });
79
- it('should skip malformed lines', async () => {
80
- const mockContent = 'invalid json\n{"id":"h-000001","timestamp":"2026-01-01","command":"test","args":[],"exitCode":0,"durationMs":100,"success":true}\n';
81
- let readCount = 0;
82
- mockedFs.pathExists.mockImplementation(async () => true);
83
- mockedFs.readFile.mockImplementation(async () => {
84
- readCount++;
85
- return readCount === 1 ? mockContent : '';
86
- });
87
- const newService = new command_history_service_1.CommandHistoryService(`/tmp/test-repo-malformed-${Date.now()}-${++counter}`);
88
- await newService.initialize();
89
- const entries = await newService.list();
90
- expect(entries.length).toBeGreaterThanOrEqual(1);
91
- });
92
- });
93
- describe('record', () => {
94
- it('should record a successful command', async () => {
95
- const id = await service.record('validate', [], 0, 150);
96
- expect(id).toMatch(/^h-\d{6}$/);
97
- expect(mockedFs.appendFile).toHaveBeenCalled();
98
- });
99
- it('should record a failed command', async () => {
100
- const id = await service.record('validate', ['--arch'], 1, 50);
101
- expect(id).toMatch(/^h-\d{6}$/);
102
- });
103
- it('should increment entry counter', async () => {
104
- const id1 = await service.record('cmd1', [], 0, 100);
105
- const id2 = await service.record('cmd2', [], 0, 100);
106
- expect(id2).not.toBe(id1);
107
- });
108
- });
109
- describe('list', () => {
110
- it('should return all history entries', async () => {
111
- await service.record('cmd1', [], 0, 100);
112
- await service.record('cmd2', ['--flag'], 0, 200);
113
- const entries = await service.list();
114
- expect(entries.length).toBe(2);
115
- });
116
- it('should limit results when limit provided', async () => {
117
- await service.record('cmd1', [], 0, 100);
118
- await service.record('cmd2', [], 0, 100);
119
- await service.record('cmd3', [], 0, 100);
120
- const entries = await service.list(2);
121
- expect(entries.length).toBe(2);
122
- });
123
- });
124
- describe('search', () => {
125
- it('should search by command name', async () => {
126
- await service.record('validate', [], 0, 100);
127
- await service.record('init', ['--name', 'test'], 0, 200);
128
- await service.record('validate', ['--arch'], 0, 150);
129
- const results = await service.search('validate');
130
- expect(results.length).toBe(2);
131
- });
132
- it('should return empty array for no matches', async () => {
133
- await service.record('validate', [], 0, 100);
134
- const results = await service.search('nonexistent');
135
- expect(results.length).toBe(0);
136
- });
137
- });
138
- describe('stats', () => {
139
- it('should return command statistics', async () => {
140
- await service.record('validate', [], 0, 100);
141
- await service.record('validate', [], 0, 200);
142
- await service.record('init', [], 1, 50);
143
- const stats = await service.stats();
144
- expect(stats.totalCommands).toBe(3);
145
- expect(stats.successRate).toContain('66.7');
146
- });
147
- it('should return 0 success rate with no commands', async () => {
148
- const newService = new command_history_service_1.CommandHistoryService(`/tmp/test-repo-empty-${Date.now()}-${++counter}`);
149
- const stats = await newService.stats();
150
- expect(stats.totalCommands).toBe(0);
151
- expect(stats.successRate).toBe('0%');
152
- });
153
- });
154
- describe('clear', () => {
155
- it('should clear all history', async () => {
156
- await service.record('cmd1', [], 0, 100);
157
- mockedFs.pathExists.mockResolvedValue(true);
158
- mockedFs.readFile.mockResolvedValue('');
159
- await service.clear();
160
- mockedFs.pathExists.mockResolvedValue(false);
161
- const entries = await service.list();
162
- expect(entries.length).toBe(0);
163
- });
39
+ const mockFs = fs;
40
+ function makeEntry(overrides = {}) {
41
+ return {
42
+ id: 'h-000001',
43
+ timestamp: new Date(Date.now() - 60_000).toISOString(),
44
+ command: 'validate',
45
+ args: ['--satellite', '.'],
46
+ exitCode: 0,
47
+ durationMs: 120,
48
+ success: true,
49
+ ...overrides,
50
+ };
51
+ }
52
+ function makeService() {
53
+ return new command_history_service_1.CommandHistoryService('/tmp/test-repo');
54
+ }
55
+ beforeEach(() => {
56
+ jest.clearAllMocks();
57
+ mockFs.ensureDir.mockResolvedValue(undefined);
58
+ mockFs.pathExists.mockResolvedValue(false);
59
+ mockFs.appendFile.mockResolvedValue(undefined);
60
+ mockFs.remove.mockResolvedValue(undefined);
61
+ });
62
+ describe('initialize', () => {
63
+ it('creates the .evolith directory', async () => {
64
+ const svc = makeService();
65
+ await svc.initialize();
66
+ expect(mockFs.ensureDir).toHaveBeenCalledWith(expect.stringContaining('.evolith'));
67
+ });
68
+ it('starts empty when history file does not exist', async () => {
69
+ const svc = makeService();
70
+ await svc.initialize();
71
+ expect(await svc.list()).toEqual([]);
72
+ });
73
+ it('parses existing JSONL history file', async () => {
74
+ const entry = makeEntry();
75
+ mockFs.pathExists.mockResolvedValue(true);
76
+ mockFs.readFile.mockResolvedValue(JSON.stringify(entry) + '\n');
77
+ const svc = makeService();
78
+ await svc.initialize();
79
+ const entries = await svc.list();
80
+ expect(entries).toHaveLength(1);
81
+ expect(entries[0].id).toBe('h-000001');
82
+ });
83
+ it('skips malformed lines in history file', async () => {
84
+ mockFs.pathExists.mockResolvedValue(true);
85
+ mockFs.readFile.mockResolvedValue('bad json\n' + JSON.stringify(makeEntry()) + '\n');
86
+ const svc = makeService();
87
+ await svc.initialize();
88
+ expect(await svc.list()).toHaveLength(1);
89
+ });
90
+ it('keeps only the last 1000 entries', async () => {
91
+ const lines = Array.from({ length: 1100 }, (_, i) => JSON.stringify(makeEntry({ id: `h-${String(i + 1).padStart(6, '0')}` }))).join('\n');
92
+ mockFs.pathExists.mockResolvedValue(true);
93
+ mockFs.readFile.mockResolvedValue(lines);
94
+ const svc = makeService();
95
+ await svc.initialize();
96
+ expect((await svc.list(2000)).length).toBe(1000);
97
+ });
98
+ it('is idempotent — calling twice does not double entries', async () => {
99
+ const entry = makeEntry();
100
+ mockFs.pathExists.mockResolvedValue(true);
101
+ mockFs.readFile.mockResolvedValue(JSON.stringify(entry) + '\n');
102
+ const svc = makeService();
103
+ await svc.initialize();
104
+ await svc.initialize();
105
+ expect((await svc.list()).length).toBe(1);
106
+ });
107
+ });
108
+ describe('record', () => {
109
+ it('returns an id in h-NNNNNN format', async () => {
110
+ const id = await makeService().record('validate', [], 0, 100);
111
+ expect(id).toMatch(/^h-\d{6}$/);
112
+ });
113
+ it('appends JSON line to the history file', async () => {
114
+ await makeService().record('validate', ['--satellite', '.'], 0, 50);
115
+ expect(mockFs.appendFile).toHaveBeenCalledWith(expect.any(String), expect.stringContaining('"validate"'));
116
+ });
117
+ it('marks success=true when exitCode=0', async () => {
118
+ const svc = makeService();
119
+ await svc.record('validate', [], 0, 10);
120
+ const [entry] = await svc.list();
121
+ expect(entry.success).toBe(true);
122
+ });
123
+ it('marks success=false when exitCode≠0', async () => {
124
+ const svc = makeService();
125
+ await svc.record('validate', [], 1, 10);
126
+ const [entry] = await svc.list();
127
+ expect(entry.success).toBe(false);
128
+ });
129
+ it('increments id counter across multiple records', async () => {
130
+ const svc = makeService();
131
+ const id1 = await svc.record('cmd', [], 0, 1);
132
+ const id2 = await svc.record('cmd', [], 0, 1);
133
+ expect(id1).not.toBe(id2);
134
+ });
135
+ });
136
+ describe('list', () => {
137
+ it('returns entries in reverse chronological order (newest first)', async () => {
138
+ const svc = makeService();
139
+ await svc.record('first', [], 0, 1);
140
+ await svc.record('second', [], 0, 1);
141
+ const entries = await svc.list();
142
+ expect(entries[0].command).toBe('second');
143
+ expect(entries[1].command).toBe('first');
144
+ });
145
+ it('respects limit parameter', async () => {
146
+ const svc = makeService();
147
+ for (let i = 0; i < 5; i++)
148
+ await svc.record(`cmd${i}`, [], 0, 1);
149
+ expect(await svc.list(3)).toHaveLength(3);
150
+ });
151
+ it('returns all entries when limit > total', async () => {
152
+ const svc = makeService();
153
+ await svc.record('only', [], 0, 1);
154
+ expect(await svc.list(100)).toHaveLength(1);
155
+ });
156
+ });
157
+ describe('get', () => {
158
+ it('returns the entry with the matching id', async () => {
159
+ const svc = makeService();
160
+ const id = await svc.record('validate', ['--satellite', '.'], 0, 42);
161
+ const entry = await svc.get(id);
162
+ expect(entry).toBeDefined();
163
+ expect(entry.command).toBe('validate');
164
+ expect(entry.durationMs).toBe(42);
165
+ });
166
+ it('returns undefined for unknown id', async () => {
167
+ expect(await makeService().get('h-999999')).toBeUndefined();
168
+ });
169
+ });
170
+ describe('search', () => {
171
+ it('finds entries by command name', async () => {
172
+ const svc = makeService();
173
+ await svc.record('validate', [], 0, 1);
174
+ await svc.record('gate-status', [], 0, 1);
175
+ const results = await svc.search('validate');
176
+ expect(results).toHaveLength(1);
177
+ expect(results[0].command).toBe('validate');
178
+ });
179
+ it('finds entries by args substring', async () => {
180
+ const svc = makeService();
181
+ await svc.record('validate', ['--satellite', '/my/repo'], 0, 1);
182
+ const results = await svc.search('my/repo');
183
+ expect(results).toHaveLength(1);
184
+ });
185
+ it('is case-insensitive', async () => {
186
+ const svc = makeService();
187
+ await svc.record('Validate', [], 0, 1);
188
+ expect(await svc.search('validate')).toHaveLength(1);
189
+ expect(await svc.search('VALIDATE')).toHaveLength(1);
190
+ });
191
+ it('returns empty array when no match', async () => {
192
+ const svc = makeService();
193
+ await svc.record('gate-status', [], 0, 1);
194
+ expect(await svc.search('nonexistent')).toHaveLength(0);
195
+ });
196
+ });
197
+ describe('clear', () => {
198
+ it('empties the in-memory entries', async () => {
199
+ const svc = makeService();
200
+ await svc.record('validate', [], 0, 1);
201
+ await svc.clear();
202
+ expect(await svc.list()).toHaveLength(0);
203
+ });
204
+ it('removes the history file when it exists', async () => {
205
+ mockFs.pathExists.mockResolvedValue(true);
206
+ await makeService().clear();
207
+ expect(mockFs.remove).toHaveBeenCalled();
208
+ });
209
+ it('does not call remove when file does not exist', async () => {
210
+ mockFs.pathExists.mockResolvedValue(false);
211
+ await makeService().clear();
212
+ expect(mockFs.remove).not.toHaveBeenCalled();
213
+ });
214
+ });
215
+ describe('stats', () => {
216
+ it('returns zero stats when history is empty', async () => {
217
+ const result = await makeService().stats();
218
+ expect(result.totalCommands).toBe(0);
219
+ expect(result.successRate).toBe('0%');
220
+ expect(result.mostUsed).toHaveLength(0);
221
+ });
222
+ it('calculates success rate correctly', async () => {
223
+ const svc = makeService();
224
+ await svc.record('cmd', [], 0, 1);
225
+ await svc.record('cmd', [], 0, 1);
226
+ await svc.record('cmd', [], 1, 1);
227
+ const { successRate } = await svc.stats();
228
+ expect(successRate).toBe('66.7%');
229
+ });
230
+ it('returns mostUsed sorted by frequency', async () => {
231
+ const svc = makeService();
232
+ await svc.record('validate', [], 0, 1);
233
+ await svc.record('validate', [], 0, 1);
234
+ await svc.record('gate-status', [], 0, 1);
235
+ const { mostUsed } = await svc.stats();
236
+ expect(mostUsed[0].command).toBe('validate');
237
+ expect(mostUsed[0].count).toBe(2);
238
+ });
239
+ it('counts recentCommands in last 24h', async () => {
240
+ const svc = makeService();
241
+ await svc.record('recent', [], 0, 1);
242
+ const { recentCommands } = await svc.stats();
243
+ expect(recentCommands).toBe(1);
244
+ });
245
+ });
246
+ describe('replay', () => {
247
+ it('returns command and args for a valid id', async () => {
248
+ const svc = makeService();
249
+ const id = await svc.record('gate-status', ['--since', '30'], 0, 1);
250
+ const result = await svc.replay(id);
251
+ expect(result).toEqual({ command: 'gate-status', args: ['--since', '30'] });
252
+ });
253
+ it('returns undefined for unknown id', async () => {
254
+ expect(await makeService().replay('h-999999')).toBeUndefined();
164
255
  });
165
256
  });
166
257
  //# sourceMappingURL=command-history.service.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"command-history.service.spec.js","sourceRoot":"","sources":["../../../src/core/services/command-history.service.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command-history.service.spec.js","sourceRoot":"","sources":["../../../src/core/services/command-history.service.spec.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uEAAgF;AAEhF,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACtB,6CAA+B;AAC/B,MAAM,MAAM,GAAG,EAA4B,CAAC;AAI5C,SAAS,SAAS,CAAC,YAAmC,EAAE;IACtD,OAAO;QACL,EAAE,EAAE,UAAU;QACd,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,WAAW,EAAE;QACtD,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE,CAAC,aAAa,EAAE,GAAG,CAAC;QAC1B,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,GAAG;QACf,OAAO,EAAE,IAAI;QACb,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,SAAS,WAAW;IAClB,OAAO,IAAI,+CAAqB,CAAC,gBAAgB,CAAC,CAAC;AACrD,CAAC;AAED,UAAU,CAAC,GAAG,EAAE;IACd,IAAI,CAAC,aAAa,EAAE,CAAC;IACrB,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,SAAgB,CAAC,CAAC;IACrD,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAY,CAAC,CAAC;IAClD,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,SAAgB,CAAC,CAAC;IACtD,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,SAAgB,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAIH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CAC3C,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,CACpC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAW,CAAC,CAAC;QAChD,MAAM,CAAC,QAAsB,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QAC/E,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAW,CAAC,CAAC;QAChD,MAAM,CAAC,QAAsB,CAAC,iBAAiB,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACpG,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAClD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CACzE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAW,CAAC,CAAC;QAChD,MAAM,CAAC,QAAsB,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAW,CAAC,CAAC;QAChD,MAAM,CAAC,QAAsB,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QAC/E,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAIH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9D,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAC5C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAClB,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,CACtC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAIH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACpC,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAIH,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;IACnB,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5B,MAAM,CAAC,KAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,CAAC,KAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,CAAC,MAAM,WAAW,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAIH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,MAAM,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAIH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAW,CAAC,CAAC;QACjD,MAAM,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;QAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAY,CAAC,CAAC;QAClD,MAAM,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;QAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAIH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,MAAM,GAAG,MAAM,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;QAC1C,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,MAAM,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;QACvC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACrC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;QAC7C,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAIH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,CAAC,MAAM,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}