cadr-cli 0.0.1 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/adr.d.ts +50 -0
  2. package/dist/adr.d.ts.map +1 -0
  3. package/dist/adr.js +156 -0
  4. package/dist/adr.js.map +1 -0
  5. package/dist/adr.test.d.ts +8 -0
  6. package/dist/adr.test.d.ts.map +1 -0
  7. package/dist/adr.test.js +256 -0
  8. package/dist/adr.test.js.map +1 -0
  9. package/dist/analysis.d.ts +24 -0
  10. package/dist/analysis.d.ts.map +1 -0
  11. package/dist/analysis.js +281 -0
  12. package/dist/analysis.js.map +1 -0
  13. package/dist/analysis.test.d.ts +8 -0
  14. package/dist/analysis.test.d.ts.map +1 -0
  15. package/dist/analysis.test.js +351 -0
  16. package/dist/analysis.test.js.map +1 -0
  17. package/dist/commands/analyze.d.ts +14 -0
  18. package/dist/commands/analyze.d.ts.map +1 -0
  19. package/dist/commands/analyze.js +56 -0
  20. package/dist/commands/analyze.js.map +1 -0
  21. package/dist/commands/init.d.ts +12 -0
  22. package/dist/commands/init.d.ts.map +1 -0
  23. package/dist/commands/init.js +93 -0
  24. package/dist/commands/init.js.map +1 -0
  25. package/dist/commands/init.test.d.ts +2 -0
  26. package/dist/commands/init.test.d.ts.map +1 -0
  27. package/dist/commands/init.test.js +56 -0
  28. package/dist/commands/init.test.js.map +1 -0
  29. package/dist/config.d.ts +40 -0
  30. package/dist/config.d.ts.map +1 -0
  31. package/dist/config.js +208 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/config.test.d.ts +2 -0
  34. package/dist/config.test.d.ts.map +1 -0
  35. package/dist/config.test.js +97 -0
  36. package/dist/config.test.js.map +1 -0
  37. package/dist/git.d.ts +42 -0
  38. package/dist/git.d.ts.map +1 -1
  39. package/dist/git.js +157 -0
  40. package/dist/git.js.map +1 -1
  41. package/dist/index.d.ts +2 -3
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +78 -62
  44. package/dist/index.js.map +1 -1
  45. package/dist/index.test.d.ts +2 -0
  46. package/dist/index.test.d.ts.map +1 -0
  47. package/dist/index.test.js +51 -0
  48. package/dist/index.test.js.map +1 -0
  49. package/dist/llm.d.ts +73 -0
  50. package/dist/llm.d.ts.map +1 -0
  51. package/dist/llm.js +263 -0
  52. package/dist/llm.js.map +1 -0
  53. package/dist/llm.test.d.ts +2 -0
  54. package/dist/llm.test.d.ts.map +1 -0
  55. package/dist/llm.test.js +592 -0
  56. package/dist/llm.test.js.map +1 -0
  57. package/dist/logger.d.ts.map +1 -1
  58. package/dist/logger.js +5 -3
  59. package/dist/logger.js.map +1 -1
  60. package/dist/logger.test.d.ts +2 -0
  61. package/dist/logger.test.d.ts.map +1 -0
  62. package/dist/logger.test.js +78 -0
  63. package/dist/logger.test.js.map +1 -0
  64. package/dist/prompts.d.ts +49 -0
  65. package/dist/prompts.d.ts.map +1 -0
  66. package/dist/prompts.js +195 -0
  67. package/dist/prompts.js.map +1 -0
  68. package/dist/prompts.test.d.ts +2 -0
  69. package/dist/prompts.test.d.ts.map +1 -0
  70. package/dist/prompts.test.js +427 -0
  71. package/dist/prompts.test.js.map +1 -0
  72. package/dist/providers/gemini.d.ts +3 -0
  73. package/dist/providers/gemini.d.ts.map +1 -0
  74. package/dist/providers/gemini.js +39 -0
  75. package/dist/providers/gemini.js.map +1 -0
  76. package/dist/providers/index.d.ts +2 -0
  77. package/dist/providers/index.d.ts.map +1 -0
  78. package/dist/providers/index.js +6 -0
  79. package/dist/providers/index.js.map +1 -0
  80. package/dist/providers/openai.d.ts +3 -0
  81. package/dist/providers/openai.d.ts.map +1 -0
  82. package/dist/providers/openai.js +25 -0
  83. package/dist/providers/openai.js.map +1 -0
  84. package/dist/providers/registry.d.ts +4 -0
  85. package/dist/providers/registry.d.ts.map +1 -0
  86. package/dist/providers/registry.js +16 -0
  87. package/dist/providers/registry.js.map +1 -0
  88. package/dist/providers/types.d.ts +12 -0
  89. package/dist/providers/types.d.ts.map +1 -0
  90. package/dist/providers/types.js +5 -0
  91. package/dist/providers/types.js.map +1 -0
  92. package/dist/version.test.d.ts +3 -0
  93. package/dist/version.test.d.ts.map +1 -0
  94. package/dist/version.test.js +25 -0
  95. package/dist/version.test.js.map +1 -0
  96. package/package.json +14 -5
  97. package/src/adr.test.ts +278 -0
  98. package/src/adr.ts +136 -0
  99. package/src/analysis.test.ts +396 -0
  100. package/src/analysis.ts +262 -0
  101. package/src/commands/analyze.ts +56 -0
  102. package/src/commands/init.test.ts +27 -0
  103. package/src/commands/init.ts +99 -0
  104. package/src/config.test.ts +79 -0
  105. package/src/config.ts +214 -0
  106. package/src/git.ts +240 -0
  107. package/src/index.test.ts +59 -0
  108. package/src/index.ts +80 -60
  109. package/src/llm.test.ts +701 -0
  110. package/src/llm.ts +344 -0
  111. package/src/logger.test.ts +90 -0
  112. package/src/logger.ts +6 -3
  113. package/src/prompts.test.ts +515 -0
  114. package/src/prompts.ts +174 -0
  115. package/src/providers/gemini.ts +41 -0
  116. package/src/providers/index.ts +1 -0
  117. package/src/providers/openai.ts +22 -0
  118. package/src/providers/registry.ts +16 -0
  119. package/src/providers/types.ts +14 -0
  120. package/src/version.test.ts +29 -0
  121. package/bin/cadr.js +0 -16
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const config_1 = require("./config");
37
+ const fs = __importStar(require("fs"));
38
+ const yaml = __importStar(require("js-yaml"));
39
+ // Mock fs and yaml modules
40
+ jest.mock('fs');
41
+ jest.mock('js-yaml');
42
+ describe('Configuration Module', () => {
43
+ const mockConfig = {
44
+ provider: 'openai',
45
+ analysis_model: 'gpt-4',
46
+ api_key_env: 'OPENAI_API_KEY',
47
+ timeout_seconds: 15
48
+ };
49
+ beforeEach(() => {
50
+ jest.clearAllMocks();
51
+ });
52
+ describe('loadConfig', () => {
53
+ test('loads valid configuration successfully', async () => {
54
+ fs.existsSync.mockReturnValue(true);
55
+ fs.readFileSync.mockReturnValue('provider: openai\nanalysis_model: gpt-4');
56
+ yaml.load.mockReturnValue(mockConfig);
57
+ const result = await (0, config_1.loadConfig)('/test/cadr.yaml');
58
+ expect(result).toEqual(mockConfig);
59
+ expect(fs.existsSync).toHaveBeenCalledWith('/test/cadr.yaml');
60
+ expect(fs.readFileSync).toHaveBeenCalledWith('/test/cadr.yaml', 'utf-8');
61
+ });
62
+ test('returns null when config file does not exist', async () => {
63
+ fs.existsSync.mockReturnValue(false);
64
+ const result = await (0, config_1.loadConfig)('/test/cadr.yaml');
65
+ expect(result).toBeNull();
66
+ });
67
+ test('returns null when config file is invalid', async () => {
68
+ fs.existsSync.mockReturnValue(true);
69
+ fs.readFileSync.mockReturnValue('invalid yaml');
70
+ yaml.load.mockImplementation(() => {
71
+ throw new Error('Invalid YAML');
72
+ });
73
+ const result = await (0, config_1.loadConfig)('/test/cadr.yaml');
74
+ expect(result).toBeNull();
75
+ });
76
+ });
77
+ describe('validateConfig', () => {
78
+ test('validates correct configuration', () => {
79
+ const result = (0, config_1.validateConfig)(mockConfig);
80
+ expect(result.valid).toBe(true);
81
+ expect(result.errors).toHaveLength(0);
82
+ });
83
+ test('rejects invalid provider', () => {
84
+ const invalidConfig = { ...mockConfig, provider: 'invalid' };
85
+ const result = (0, config_1.validateConfig)(invalidConfig);
86
+ expect(result.valid).toBe(false);
87
+ expect(result.errors.join('\n')).toMatch(/provider must be one of the following values: openai, gemini/);
88
+ });
89
+ test('rejects missing required fields', () => {
90
+ const invalidConfig = { provider: 'openai' };
91
+ const result = (0, config_1.validateConfig)(invalidConfig);
92
+ expect(result.valid).toBe(false);
93
+ expect(result.errors.length).toBeGreaterThan(0);
94
+ });
95
+ });
96
+ });
97
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../src/config.test.ts"],"names":[],"mappings":"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"}
package/dist/git.d.ts CHANGED
@@ -3,10 +3,52 @@ export declare class GitError extends Error {
3
3
  readonly originalError?: Error | undefined;
4
4
  constructor(message: string, code: 'NOT_GIT_REPO' | 'GIT_NOT_FOUND' | 'GIT_ERROR', originalError?: Error | undefined);
5
5
  }
6
+ /**
7
+ * Options for specifying what diff to analyze
8
+ */
9
+ export interface DiffOptions {
10
+ mode: 'staged' | 'all' | 'branch-diff';
11
+ base?: string;
12
+ head?: string;
13
+ }
6
14
  /**
7
15
  * Retrieves the list of staged files in the current Git repository
8
16
  * @returns Promise<string[]> Array of staged file paths
9
17
  * @throws GitError When Git is not available or repository is invalid
10
18
  */
11
19
  export declare function getStagedFiles(): Promise<string[]>;
20
+ /**
21
+ * Retrieves the full diff content for staged files
22
+ * Uses minimal context to reduce token usage
23
+ * @returns Promise<string> Full diff content of staged changes
24
+ * @throws GitError When Git is not available or repository is invalid
25
+ */
26
+ export declare function getStagedDiff(): Promise<string>;
27
+ /**
28
+ * Retrieves the list of all uncommitted files (staged + unstaged) in the current Git repository
29
+ * @returns Promise<string[]> Array of uncommitted file paths
30
+ * @throws GitError When Git is not available or repository is invalid
31
+ */
32
+ export declare function getUncommittedFiles(): Promise<string[]>;
33
+ /**
34
+ * Retrieves the full diff content for all uncommitted files (staged + unstaged)
35
+ * Uses minimal context to reduce token usage
36
+ * @returns Promise<string> Full diff content of uncommitted changes
37
+ * @throws GitError When Git is not available or repository is invalid
38
+ */
39
+ export declare function getUncommittedDiff(): Promise<string>;
40
+ /**
41
+ * Generic function to get changed files based on diff options
42
+ * @param options - Diff options specifying which changes to analyze
43
+ * @returns Promise<string[]> Array of changed file paths
44
+ * @throws GitError When Git is not available or repository is invalid
45
+ */
46
+ export declare function getChangedFiles(options?: DiffOptions): Promise<string[]>;
47
+ /**
48
+ * Generic function to get diff content based on diff options
49
+ * @param options - Diff options specifying which changes to analyze
50
+ * @returns Promise<string> Full diff content
51
+ * @throws GitError When Git is not available or repository is invalid
52
+ */
53
+ export declare function getDiff(options?: DiffOptions): Promise<string>;
12
54
  //# sourceMappingURL=git.d.ts.map
package/dist/git.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAKA,qBAAa,QAAS,SAAQ,KAAK;aAGf,IAAI,EAAE,cAAc,GAAG,eAAe,GAAG,WAAW;aACpD,aAAa,CAAC,EAAE,KAAK;gBAFrC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,cAAc,GAAG,eAAe,GAAG,WAAW,EACpD,aAAa,CAAC,EAAE,KAAK,YAAA;CAKxC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAsCxD"}
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAKA,qBAAa,QAAS,SAAQ,KAAK;aAGf,IAAI,EAAE,cAAc,GAAG,eAAe,GAAG,WAAW;aACpD,aAAa,CAAC,EAAE,KAAK;gBAFrC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,cAAc,GAAG,eAAe,GAAG,WAAW,EACpD,aAAa,CAAC,EAAE,KAAK,YAAA;CAKxC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,GAAG,KAAK,GAAG,aAAa,CAAC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAsCxD;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAiCrD;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAsC7D;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAiC1D;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,WAA6B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA+C/F;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,OAAO,GAAE,WAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAyCrF"}
package/dist/git.js CHANGED
@@ -2,6 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GitError = void 0;
4
4
  exports.getStagedFiles = getStagedFiles;
5
+ exports.getStagedDiff = getStagedDiff;
6
+ exports.getUncommittedFiles = getUncommittedFiles;
7
+ exports.getUncommittedDiff = getUncommittedDiff;
8
+ exports.getChangedFiles = getChangedFiles;
9
+ exports.getDiff = getDiff;
5
10
  const child_process_1 = require("child_process");
6
11
  const util_1 = require("util");
7
12
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
@@ -44,4 +49,156 @@ async function getStagedFiles() {
44
49
  throw new GitError('Unable to read Git repository. Please check repository permissions.', 'GIT_ERROR', error instanceof Error ? error : new Error(String(error)));
45
50
  }
46
51
  }
52
+ /**
53
+ * Retrieves the full diff content for staged files
54
+ * Uses minimal context to reduce token usage
55
+ * @returns Promise<string> Full diff content of staged changes
56
+ * @throws GitError When Git is not available or repository is invalid
57
+ */
58
+ async function getStagedDiff() {
59
+ try {
60
+ // Use --unified=1 for minimal context (1 line before/after instead of 3)
61
+ // This significantly reduces token usage while maintaining readability
62
+ const { stdout } = await execAsync('git diff --cached --unified=1');
63
+ return stdout;
64
+ }
65
+ catch (error) {
66
+ // Handle different Git error scenarios (same as getStagedFiles)
67
+ const errorWithCode = error;
68
+ if (errorWithCode.code === 128) {
69
+ throw new GitError('Not in a Git repository. Please run \'cadr\' from within a Git repository.', 'NOT_GIT_REPO', error instanceof Error ? error : new Error(String(error)));
70
+ }
71
+ if (errorWithCode.code === 127) {
72
+ throw new GitError('Git is not installed. Please install Git and try again.', 'GIT_NOT_FOUND', error instanceof Error ? error : new Error(String(error)));
73
+ }
74
+ // Handle other Git errors (permissions, corruption, etc.)
75
+ throw new GitError('Unable to read Git repository. Please check repository permissions.', 'GIT_ERROR', error instanceof Error ? error : new Error(String(error)));
76
+ }
77
+ }
78
+ /**
79
+ * Retrieves the list of all uncommitted files (staged + unstaged) in the current Git repository
80
+ * @returns Promise<string[]> Array of uncommitted file paths
81
+ * @throws GitError When Git is not available or repository is invalid
82
+ */
83
+ async function getUncommittedFiles() {
84
+ try {
85
+ const { stdout } = await execAsync('git diff HEAD --name-only');
86
+ // Split by newlines and filter out empty strings
87
+ const uncommittedFiles = stdout
88
+ .split('\n')
89
+ .map(file => file.trim())
90
+ .filter(file => file.length > 0);
91
+ return uncommittedFiles;
92
+ }
93
+ catch (error) {
94
+ // Handle different Git error scenarios
95
+ const errorWithCode = error;
96
+ if (errorWithCode.code === 128) {
97
+ throw new GitError('Not in a Git repository. Please run \'cadr\' from within a Git repository.', 'NOT_GIT_REPO', error instanceof Error ? error : new Error(String(error)));
98
+ }
99
+ if (errorWithCode.code === 127) {
100
+ throw new GitError('Git is not installed. Please install Git and try again.', 'GIT_NOT_FOUND', error instanceof Error ? error : new Error(String(error)));
101
+ }
102
+ // Handle other Git errors (permissions, corruption, etc.)
103
+ throw new GitError('Unable to read Git repository. Please check repository permissions.', 'GIT_ERROR', error instanceof Error ? error : new Error(String(error)));
104
+ }
105
+ }
106
+ /**
107
+ * Retrieves the full diff content for all uncommitted files (staged + unstaged)
108
+ * Uses minimal context to reduce token usage
109
+ * @returns Promise<string> Full diff content of uncommitted changes
110
+ * @throws GitError When Git is not available or repository is invalid
111
+ */
112
+ async function getUncommittedDiff() {
113
+ try {
114
+ // Use --unified=1 for minimal context (1 line before/after instead of 3)
115
+ // This significantly reduces token usage while maintaining readability
116
+ const { stdout } = await execAsync('git diff HEAD --unified=1');
117
+ return stdout;
118
+ }
119
+ catch (error) {
120
+ // Handle different Git error scenarios (same as getUncommittedFiles)
121
+ const errorWithCode = error;
122
+ if (errorWithCode.code === 128) {
123
+ throw new GitError('Not in a Git repository. Please run \'cadr\' from within a Git repository.', 'NOT_GIT_REPO', error instanceof Error ? error : new Error(String(error)));
124
+ }
125
+ if (errorWithCode.code === 127) {
126
+ throw new GitError('Git is not installed. Please install Git and try again.', 'GIT_NOT_FOUND', error instanceof Error ? error : new Error(String(error)));
127
+ }
128
+ // Handle other Git errors (permissions, corruption, etc.)
129
+ throw new GitError('Unable to read Git repository. Please check repository permissions.', 'GIT_ERROR', error instanceof Error ? error : new Error(String(error)));
130
+ }
131
+ }
132
+ /**
133
+ * Generic function to get changed files based on diff options
134
+ * @param options - Diff options specifying which changes to analyze
135
+ * @returns Promise<string[]> Array of changed file paths
136
+ * @throws GitError When Git is not available or repository is invalid
137
+ */
138
+ async function getChangedFiles(options = { mode: 'all' }) {
139
+ switch (options.mode) {
140
+ case 'staged':
141
+ return getStagedFiles();
142
+ case 'all':
143
+ return getUncommittedFiles();
144
+ case 'branch-diff': {
145
+ const base = options.base || 'origin/main';
146
+ const head = options.head || 'HEAD';
147
+ try {
148
+ // Use triple-dot syntax for merge-base diff (standard in CI/CD)
149
+ const { stdout } = await execAsync(`git diff ${base}...${head} --name-only`);
150
+ const files = stdout
151
+ .split('\n')
152
+ .map(file => file.trim())
153
+ .filter(file => file.length > 0);
154
+ return files;
155
+ }
156
+ catch (error) {
157
+ // Handle different Git error scenarios
158
+ const errorWithCode = error;
159
+ if (errorWithCode.code === 128) {
160
+ throw new GitError(`Invalid git references: ${base}...${head}. Please ensure both references exist.`, 'GIT_ERROR', error instanceof Error ? error : new Error(String(error)));
161
+ }
162
+ if (errorWithCode.code === 127) {
163
+ throw new GitError('Git is not installed. Please install Git and try again.', 'GIT_NOT_FOUND', error instanceof Error ? error : new Error(String(error)));
164
+ }
165
+ throw new GitError('Unable to read Git repository. Please check repository permissions.', 'GIT_ERROR', error instanceof Error ? error : new Error(String(error)));
166
+ }
167
+ }
168
+ }
169
+ }
170
+ /**
171
+ * Generic function to get diff content based on diff options
172
+ * @param options - Diff options specifying which changes to analyze
173
+ * @returns Promise<string> Full diff content
174
+ * @throws GitError When Git is not available or repository is invalid
175
+ */
176
+ async function getDiff(options = { mode: 'all' }) {
177
+ switch (options.mode) {
178
+ case 'staged':
179
+ return getStagedDiff();
180
+ case 'all':
181
+ return getUncommittedDiff();
182
+ case 'branch-diff': {
183
+ const base = options.base || 'origin/main';
184
+ const head = options.head || 'HEAD';
185
+ try {
186
+ // Use triple-dot syntax for merge-base diff with minimal context
187
+ const { stdout } = await execAsync(`git diff ${base}...${head} --unified=1`);
188
+ return stdout;
189
+ }
190
+ catch (error) {
191
+ // Handle different Git error scenarios
192
+ const errorWithCode = error;
193
+ if (errorWithCode.code === 128) {
194
+ throw new GitError(`Invalid git references: ${base}...${head}. Please ensure both references exist.`, 'GIT_ERROR', error instanceof Error ? error : new Error(String(error)));
195
+ }
196
+ if (errorWithCode.code === 127) {
197
+ throw new GitError('Git is not installed. Please install Git and try again.', 'GIT_NOT_FOUND', error instanceof Error ? error : new Error(String(error)));
198
+ }
199
+ throw new GitError('Unable to read Git repository. Please check repository permissions.', 'GIT_ERROR', error instanceof Error ? error : new Error(String(error)));
200
+ }
201
+ }
202
+ }
203
+ }
47
204
  //# sourceMappingURL=git.js.map
package/dist/git.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":";;;AAqBA,wCAsCC;AA3DD,iDAAqC;AACrC,+BAAiC;AAEjC,MAAM,SAAS,GAAG,IAAA,gBAAS,EAAC,oBAAI,CAAC,CAAC;AAElC,MAAa,QAAS,SAAQ,KAAK;IAGf;IACA;IAHlB,YACE,OAAe,EACC,IAAoD,EACpD,aAAqB;QAErC,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAgD;QACpD,kBAAa,GAAb,aAAa,CAAQ;QAGrC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AATD,4BASC;AAED;;;;GAIG;AACI,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,+BAA+B,CAAC,CAAC;QAEpE,iDAAiD;QACjD,MAAM,WAAW,GAAG,MAAM;aACvB,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEnC,OAAO,WAAW,CAAC;IACrB,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,uCAAuC;QACvC,MAAM,aAAa,GAAG,KAA0B,CAAC;QAEjD,IAAI,aAAa,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;YAC/B,MAAM,IAAI,QAAQ,CAChB,4EAA4E,EAC5E,cAAc,EACd,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;QACJ,CAAC;QAED,IAAI,aAAa,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;YAC/B,MAAM,IAAI,QAAQ,CAChB,yDAAyD,EACzD,eAAe,EACf,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;QACJ,CAAC;QAED,0DAA0D;QAC1D,MAAM,IAAI,QAAQ,CAChB,qEAAqE,EACrE,WAAW,EACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- export declare function getWelcomeMessage(): string;
2
- export declare function displayWelcome(): void;
3
- export declare function processStagedFiles(): Promise<void>;
1
+ export declare function showHelp(): void;
2
+ export declare function showVersion(): void;
4
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,wBAAgB,iBAAiB,IAAI,MAAM,CAY1C;AAED,wBAAgB,cAAc,IAAI,IAAI,CAGrC;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAmCxD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,wBAAgB,QAAQ,IAAI,IAAI,CA6C/B;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
package/dist/index.js CHANGED
@@ -1,79 +1,95 @@
1
+ #!/usr/bin/env node
1
2
  "use strict";
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getWelcomeMessage = getWelcomeMessage;
4
- exports.displayWelcome = displayWelcome;
5
- exports.processStagedFiles = processStagedFiles;
6
- const git_1 = require("./git");
7
- const logger_1 = require("./logger");
4
+ exports.showHelp = showHelp;
5
+ exports.showVersion = showVersion;
6
+ const init_1 = require("./commands/init");
7
+ const analyze_1 = require("./commands/analyze");
8
8
  // Version constants
9
9
  const CORE_VERSION = '0.0.1';
10
10
  const CLI_VERSION = '0.0.1';
11
- // Parse command line arguments
12
- const args = process.argv.slice(2);
13
- const isVerbose = args.includes('--verbose') || args.includes('-v');
14
- function getWelcomeMessage() {
15
- return `🎉 Hello, cADR!
11
+ function showHelp() {
12
+ const help = `
13
+ cADR - Continuous Architectural Decision Records
14
+ Version: ${CLI_VERSION}
16
15
 
17
- cADR (Continuous Architectural Decision Records) helps you automatically
18
- capture and document architectural decisions as you code.
16
+ USAGE
17
+ cadr [command] [options]
19
18
 
20
- Version: ${CLI_VERSION}
21
- Core: ${CORE_VERSION}
22
- Learn more: https://github.com/YotpoLtd/cADR
19
+ COMMANDS
20
+ init Create a cadr.yaml configuration file
21
+ analyze Analyze code changes and generate ADRs (default)
22
+ help Show this help message
23
+
24
+ ANALYZE OPTIONS
25
+ --all Analyze all uncommitted changes (staged + unstaged) [default]
26
+ --staged Analyze only staged changes
27
+ --base <ref> Base git reference for CI/CD (e.g., origin/main)
28
+ --head <ref> Head git reference for CI/CD (default: HEAD)
23
29
 
24
- Get started by running 'cadr --verbose' to see detailed logs
30
+ GLOBAL OPTIONS
31
+ -h, --help Show help message
32
+ -v, --version Show version information
33
+ --verbose Enable verbose logging
34
+
35
+ EXAMPLES
36
+ # Local development
37
+ cadr # Analyze all uncommitted files (default)
38
+ cadr analyze # Analyze all uncommitted files
39
+ cadr analyze --staged # Analyze only staged files
40
+ cadr analyze --all # Analyze all uncommitted files (explicit)
41
+
42
+ # CI/CD (Pull Requests)
43
+ cadr analyze --base origin/main # Compare current HEAD to main
44
+ cadr analyze --base origin/main --head feature-branch
45
+ cadr analyze --base HEAD~1 # Compare to previous commit
46
+
47
+ # Other commands
48
+ cadr init # Initialize configuration
49
+ cadr --verbose analyze # Analyze with debug logs
50
+
51
+ LEARN MORE
52
+ GitHub: https://github.com/YotpoLtd/cADR
53
+ Docs: https://github.com/YotpoLtd/cADR#readme
25
54
  `;
55
+ process.stdout.write(help);
26
56
  }
27
- function displayWelcome() {
28
- // Use process.stdout.write instead of console.log (Constitution: no console.log)
29
- process.stdout.write(getWelcomeMessage());
57
+ function showVersion() {
58
+ process.stdout.write(`cADR version ${CLI_VERSION} (core: ${CORE_VERSION})\n`);
30
59
  }
31
- async function processStagedFiles() {
32
- try {
33
- const stagedFiles = await (0, git_1.getStagedFiles)();
34
- // Display staged files to user
35
- if (stagedFiles.length > 0) {
36
- process.stdout.write(`\n📁 Found ${stagedFiles.length} staged file${stagedFiles.length === 1 ? '' : 's'}:\n`);
37
- stagedFiles.forEach((file) => {
38
- process.stdout.write(` • ${file}\n`);
39
- });
40
- }
41
- else {
42
- process.stdout.write(`\n📁 No staged files found.\n`);
43
- }
44
- // Only log for debugging when verbose mode is enabled
45
- if (isVerbose) {
46
- logger_1.loggerInstance.info('Retrieved staged files', {
47
- staged_files: stagedFiles,
48
- count: stagedFiles.length
49
- });
60
+ // Main execution block - run when module is executed directly
61
+ if (require.main === module) {
62
+ const args = process.argv.slice(2);
63
+ const command = args[0];
64
+ // Handle commands
65
+ (async () => {
66
+ // Help flags
67
+ if (!command || command === 'help' || args.includes('--help') || args.includes('-h')) {
68
+ showHelp();
69
+ return;
50
70
  }
51
- }
52
- catch (error) {
53
- if (error instanceof git_1.GitError) {
54
- // Display helpful error message to stdout
55
- process.stdout.write(`\n❌ ${error.message}\n`);
56
- process.exit(1);
71
+ // Version flag
72
+ if (args.includes('--version')) {
73
+ showVersion();
74
+ return;
57
75
  }
58
- else {
59
- // Log unexpected errors (always show errors)
60
- const errorMessage = error instanceof Error ? error.message : String(error);
61
- logger_1.loggerInstance.error('Unexpected error occurred', {
62
- error: errorMessage
63
- });
64
- process.exit(1);
76
+ // Commands
77
+ switch (command) {
78
+ case 'init':
79
+ await (0, init_1.initCommand)();
80
+ break;
81
+ case 'analyze':
82
+ await (0, analyze_1.analyzeCommand)(args);
83
+ break;
84
+ default:
85
+ // Unknown command - show error and help
86
+ process.stdout.write(`\n❌ Unknown command: ${command}\n`);
87
+ showHelp();
88
+ process.exit(1);
65
89
  }
66
- }
67
- }
68
- // Main execution block - run when module is executed directly
69
- if (require.main === module) {
70
- // Display welcome message first
71
- displayWelcome();
72
- // Then process staged files
73
- processStagedFiles().catch((error) => {
74
- logger_1.loggerInstance.error('Failed to process staged files', {
75
- error: error instanceof Error ? error.message : String(error)
76
- });
90
+ })().catch((error) => {
91
+ // eslint-disable-next-line no-console
92
+ console.error('Error:', error.message || error);
77
93
  process.exit(1);
78
94
  });
79
95
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAWA,8CAYC;AAED,wCAGC;AAED,gDAmCC;AAjED,+BAAiD;AACjD,qCAA0C;AAE1C,oBAAoB;AACpB,MAAM,YAAY,GAAG,OAAO,CAAC;AAC7B,MAAM,WAAW,GAAG,OAAO,CAAC;AAE5B,+BAA+B;AAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAEpE,SAAgB,iBAAiB;IAC/B,OAAO;;;;;WAKE,WAAW;QACd,YAAY;;;;CAInB,CAAC;AACF,CAAC;AAED,SAAgB,cAAc;IAC5B,iFAAiF;IACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAC5C,CAAC;AAEM,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,IAAA,oBAAc,GAAE,CAAC;QAE3C,+BAA+B;QAC/B,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,WAAW,CAAC,MAAM,eAAe,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;YAC9G,WAAW,CAAC,OAAO,CAAC,CAAC,IAAY,EAAE,EAAE;gBACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACxD,CAAC;QAED,sDAAsD;QACtD,IAAI,SAAS,EAAE,CAAC;YACd,uBAAc,CAAC,IAAI,CAAC,wBAAwB,EAAE;gBAC5C,YAAY,EAAE,WAAW;gBACzB,KAAK,EAAE,WAAW,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,cAAQ,EAAE,CAAC;YAC9B,0CAA0C;YAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,6CAA6C;YAC7C,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,uBAAc,CAAC,KAAK,CAAC,2BAA2B,EAAE;gBAChD,KAAK,EAAE,YAAY;aACpB,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,gCAAgC;IAChC,cAAc,EAAE,CAAC;IAEjB,4BAA4B;IAC5B,kBAAkB,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACnC,uBAAc,CAAC,KAAK,CAAC,gCAAgC,EAAE;YACrD,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAOA,4BA6CC;AAED,kCAEC;AAxDD,0CAA8C;AAC9C,gDAAoD;AAEpD,oBAAoB;AACpB,MAAM,YAAY,GAAG,OAAO,CAAC;AAC7B,MAAM,WAAW,GAAG,OAAO,CAAC;AAE5B,SAAgB,QAAQ;IACtB,MAAM,IAAI,GAAG;;WAEJ,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCrB,CAAC;IACA,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,WAAW;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,WAAW,WAAW,YAAY,KAAK,CAAC,CAAC;AAChF,CAAC;AAGD,8DAA8D;AAC9D,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAExB,kBAAkB;IAClB,CAAC,KAAK,IAAI,EAAE;QACV,aAAa;QACb,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACrF,QAAQ,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QAED,eAAe;QACf,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,WAAW,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QAED,WAAW;QACX,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,MAAM;gBACT,MAAM,IAAA,kBAAW,GAAE,CAAC;gBACpB,MAAM;YAER,KAAK,SAAS;gBACZ,MAAM,IAAA,wBAAc,EAAC,IAAI,CAAC,CAAC;gBAC3B,MAAM;YAER;gBACE,wCAAwC;gBACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,OAAO,IAAI,CAAC,CAAC;gBAC1D,QAAQ,EAAE,CAAC;gBACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACnB,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("./index");
4
+ describe('CLI Help', () => {
5
+ let stdoutSpy;
6
+ beforeEach(() => {
7
+ stdoutSpy = jest.spyOn(process.stdout, 'write').mockImplementation();
8
+ });
9
+ afterEach(() => {
10
+ stdoutSpy.mockRestore();
11
+ });
12
+ test('showHelp displays product name', () => {
13
+ (0, index_1.showHelp)();
14
+ expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('cADR'));
15
+ });
16
+ test('showHelp displays available commands', () => {
17
+ (0, index_1.showHelp)();
18
+ const output = stdoutSpy.mock.calls[0][0];
19
+ expect(output).toContain('init');
20
+ expect(output).toContain('analyze');
21
+ expect(output).toContain('help');
22
+ });
23
+ test('showHelp displays usage examples', () => {
24
+ (0, index_1.showHelp)();
25
+ const output = stdoutSpy.mock.calls[0][0];
26
+ expect(output).toContain('USAGE');
27
+ expect(output).toContain('COMMANDS');
28
+ expect(output).toContain('OPTIONS');
29
+ expect(output).toContain('EXAMPLES');
30
+ });
31
+ test('showHelp displays version info', () => {
32
+ (0, index_1.showHelp)();
33
+ const output = stdoutSpy.mock.calls[0][0];
34
+ expect(output).toContain('0.0.1');
35
+ });
36
+ });
37
+ describe('CLI Version', () => {
38
+ let stdoutSpy;
39
+ beforeEach(() => {
40
+ stdoutSpy = jest.spyOn(process.stdout, 'write').mockImplementation();
41
+ });
42
+ afterEach(() => {
43
+ stdoutSpy.mockRestore();
44
+ });
45
+ test('showVersion displays version information', () => {
46
+ (0, index_1.showVersion)();
47
+ expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('cADR version'));
48
+ expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('0.0.1'));
49
+ });
50
+ });
51
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":";;AAAA,mCAAgD;AAEhD,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,IAAI,SAA2B,CAAC;IAEhC,UAAU,CAAC,GAAG,EAAE;QACd,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,kBAAkB,EAAE,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE;QAC1C,IAAA,gBAAQ,GAAE,CAAC;QACX,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAChD,IAAA,gBAAQ,GAAE,CAAC;QACX,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC5C,IAAA,gBAAQ,GAAE,CAAC;QACX,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE;QAC1C,IAAA,gBAAQ,GAAE,CAAC;QACX,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,SAA2B,CAAC;IAEhC,UAAU,CAAC,GAAG,EAAE;QACd,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,kBAAkB,EAAE,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,0CAA0C,EAAE,GAAG,EAAE;QACpD,IAAA,mBAAW,GAAE,CAAC;QACd,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC;QAChF,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}