@deimoscloud/coreai 0.1.9 → 0.1.11

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 (196) hide show
  1. package/dist/cli/index.js +7 -0
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/index.js +7 -0
  4. package/dist/index.js.map +1 -1
  5. package/package.json +6 -1
  6. package/.prettierrc +0 -9
  7. package/AGENT_SPEC.md +0 -347
  8. package/ARCHITECTURE.md +0 -547
  9. package/DRAFT_PRD.md +0 -1440
  10. package/IMPLEMENTATION_PLAN.md +0 -256
  11. package/PRODUCT.md +0 -473
  12. package/WORKFLOWS.md +0 -295
  13. package/commands/core/check-inbox.md +0 -34
  14. package/commands/core/delegate.md +0 -30
  15. package/commands/core/git-commit.md +0 -144
  16. package/commands/core/pr-create.md +0 -193
  17. package/commands/core/review.md +0 -56
  18. package/commands/core/sprint-status.md +0 -65
  19. package/commands/optional/docs-update.md +0 -200
  20. package/commands/optional/jira-create.md +0 -200
  21. package/commands/optional/jira-transition.md +0 -184
  22. package/commands/optional/worktree-cleanup.md +0 -167
  23. package/commands/optional/worktree-setup.md +0 -110
  24. package/eslint.config.js +0 -29
  25. package/jest.config.js +0 -22
  26. package/knowledge-library/README.md +0 -118
  27. package/knowledge-library/android-engineer/context/current.txt +0 -42
  28. package/knowledge-library/android-engineer/control/decisions.txt +0 -9
  29. package/knowledge-library/android-engineer/control/dependencies.txt +0 -19
  30. package/knowledge-library/android-engineer/control/objectives.txt +0 -26
  31. package/knowledge-library/android-engineer/history/.gitkeep +0 -0
  32. package/knowledge-library/android-engineer/inbox/processed/.gitkeep +0 -0
  33. package/knowledge-library/android-engineer/outbox/.gitkeep +0 -0
  34. package/knowledge-library/android-engineer/tech/.gitkeep +0 -0
  35. package/knowledge-library/architecture.txt +0 -61
  36. package/knowledge-library/backend-engineer/context/current.txt +0 -42
  37. package/knowledge-library/backend-engineer/control/decisions.txt +0 -9
  38. package/knowledge-library/backend-engineer/control/dependencies.txt +0 -19
  39. package/knowledge-library/backend-engineer/control/objectives.txt +0 -26
  40. package/knowledge-library/backend-engineer/history/.gitkeep +0 -0
  41. package/knowledge-library/backend-engineer/inbox/processed/.gitkeep +0 -0
  42. package/knowledge-library/backend-engineer/outbox/.gitkeep +0 -0
  43. package/knowledge-library/backend-engineer/tech/.gitkeep +0 -0
  44. package/knowledge-library/context.txt +0 -52
  45. package/knowledge-library/devops-engineer/context/current.txt +0 -42
  46. package/knowledge-library/devops-engineer/control/decisions.txt +0 -9
  47. package/knowledge-library/devops-engineer/control/dependencies.txt +0 -19
  48. package/knowledge-library/devops-engineer/control/objectives.txt +0 -26
  49. package/knowledge-library/devops-engineer/history/.gitkeep +0 -0
  50. package/knowledge-library/devops-engineer/inbox/processed/.gitkeep +0 -0
  51. package/knowledge-library/devops-engineer/outbox/.gitkeep +0 -0
  52. package/knowledge-library/devops-engineer/tech/.gitkeep +0 -0
  53. package/knowledge-library/engineering-manager/context/current.txt +0 -40
  54. package/knowledge-library/engineering-manager/control/decisions.txt +0 -9
  55. package/knowledge-library/engineering-manager/control/objectives.txt +0 -27
  56. package/knowledge-library/engineering-manager/history/.gitkeep +0 -0
  57. package/knowledge-library/engineering-manager/inbox/processed/.gitkeep +0 -0
  58. package/knowledge-library/engineering-manager/outbox/.gitkeep +0 -0
  59. package/knowledge-library/engineering-manager/tech/.gitkeep +0 -0
  60. package/knowledge-library/prd.txt +0 -81
  61. package/knowledge-library/product-manager/context/current.txt +0 -42
  62. package/knowledge-library/product-manager/control/decisions.txt +0 -9
  63. package/knowledge-library/product-manager/control/dependencies.txt +0 -19
  64. package/knowledge-library/product-manager/control/objectives.txt +0 -26
  65. package/knowledge-library/product-manager/history/.gitkeep +0 -0
  66. package/knowledge-library/product-manager/inbox/processed/.gitkeep +0 -0
  67. package/knowledge-library/product-manager/outbox/.gitkeep +0 -0
  68. package/knowledge-library/product-manager/tech/.gitkeep +0 -0
  69. package/knowledge-library/qa-engineer/context/current.txt +0 -42
  70. package/knowledge-library/qa-engineer/control/decisions.txt +0 -9
  71. package/knowledge-library/qa-engineer/control/dependencies.txt +0 -19
  72. package/knowledge-library/qa-engineer/control/objectives.txt +0 -26
  73. package/knowledge-library/qa-engineer/history/.gitkeep +0 -0
  74. package/knowledge-library/qa-engineer/inbox/processed/.gitkeep +0 -0
  75. package/knowledge-library/qa-engineer/outbox/.gitkeep +0 -0
  76. package/knowledge-library/qa-engineer/tech/.gitkeep +0 -0
  77. package/knowledge-library/security-engineer/context/current.txt +0 -42
  78. package/knowledge-library/security-engineer/control/decisions.txt +0 -9
  79. package/knowledge-library/security-engineer/control/dependencies.txt +0 -19
  80. package/knowledge-library/security-engineer/control/objectives.txt +0 -26
  81. package/knowledge-library/security-engineer/history/.gitkeep +0 -0
  82. package/knowledge-library/security-engineer/inbox/processed/.gitkeep +0 -0
  83. package/knowledge-library/security-engineer/outbox/.gitkeep +0 -0
  84. package/knowledge-library/security-engineer/tech/.gitkeep +0 -0
  85. package/knowledge-library/solutions-architect/context/current.txt +0 -42
  86. package/knowledge-library/solutions-architect/control/decisions.txt +0 -9
  87. package/knowledge-library/solutions-architect/control/dependencies.txt +0 -19
  88. package/knowledge-library/solutions-architect/control/objectives.txt +0 -26
  89. package/knowledge-library/solutions-architect/history/.gitkeep +0 -0
  90. package/knowledge-library/solutions-architect/inbox/processed/.gitkeep +0 -0
  91. package/knowledge-library/solutions-architect/outbox/.gitkeep +0 -0
  92. package/knowledge-library/solutions-architect/tech/.gitkeep +0 -0
  93. package/knowledge-library/wearos-engineer/context/current.txt +0 -42
  94. package/knowledge-library/wearos-engineer/control/decisions.txt +0 -9
  95. package/knowledge-library/wearos-engineer/control/dependencies.txt +0 -19
  96. package/knowledge-library/wearos-engineer/control/objectives.txt +0 -26
  97. package/knowledge-library/wearos-engineer/history/.gitkeep +0 -0
  98. package/knowledge-library/wearos-engineer/inbox/processed/.gitkeep +0 -0
  99. package/knowledge-library/wearos-engineer/outbox/.gitkeep +0 -0
  100. package/knowledge-library/wearos-engineer/tech/.gitkeep +0 -0
  101. package/scripts/add-agent.sh +0 -323
  102. package/scripts/install.sh +0 -354
  103. package/src/adapters/factory.test.ts +0 -386
  104. package/src/adapters/factory.ts +0 -305
  105. package/src/adapters/index.ts +0 -113
  106. package/src/adapters/interfaces.ts +0 -268
  107. package/src/adapters/mcp/client.test.ts +0 -130
  108. package/src/adapters/mcp/client.ts +0 -451
  109. package/src/adapters/mcp/discovery.test.ts +0 -315
  110. package/src/adapters/mcp/discovery.ts +0 -340
  111. package/src/adapters/mcp/index.ts +0 -66
  112. package/src/adapters/mcp/mapper.test.ts +0 -218
  113. package/src/adapters/mcp/mapper.ts +0 -536
  114. package/src/adapters/mcp/registry.test.ts +0 -433
  115. package/src/adapters/mcp/registry.ts +0 -550
  116. package/src/adapters/mcp/types.ts +0 -258
  117. package/src/adapters/native/filesystem.test.ts +0 -350
  118. package/src/adapters/native/filesystem.ts +0 -393
  119. package/src/adapters/native/github.test.ts +0 -173
  120. package/src/adapters/native/github.ts +0 -627
  121. package/src/adapters/native/index.ts +0 -22
  122. package/src/adapters/native/selector.test.ts +0 -224
  123. package/src/adapters/native/selector.ts +0 -150
  124. package/src/adapters/types.ts +0 -270
  125. package/src/agents/compiler.test.ts +0 -410
  126. package/src/agents/compiler.ts +0 -424
  127. package/src/agents/index.ts +0 -37
  128. package/src/agents/loader.test.ts +0 -319
  129. package/src/agents/loader.ts +0 -143
  130. package/src/agents/resolver.test.ts +0 -282
  131. package/src/agents/resolver.ts +0 -262
  132. package/src/agents/types.ts +0 -97
  133. package/src/cache/index.ts +0 -38
  134. package/src/cache/interfaces.ts +0 -283
  135. package/src/cache/manager.test.ts +0 -266
  136. package/src/cache/manager.ts +0 -388
  137. package/src/cache/provider.test.ts +0 -485
  138. package/src/cache/provider.ts +0 -745
  139. package/src/cache/types.test.ts +0 -192
  140. package/src/cache/types.ts +0 -313
  141. package/src/cli/commands/build.test.ts +0 -248
  142. package/src/cli/commands/build.ts +0 -284
  143. package/src/cli/commands/cache.test.ts +0 -221
  144. package/src/cli/commands/cache.ts +0 -229
  145. package/src/cli/commands/index.ts +0 -63
  146. package/src/cli/commands/init.test.ts +0 -173
  147. package/src/cli/commands/init.ts +0 -296
  148. package/src/cli/commands/skills.test.ts +0 -272
  149. package/src/cli/commands/skills.ts +0 -348
  150. package/src/cli/commands/status.test.ts +0 -392
  151. package/src/cli/commands/status.ts +0 -332
  152. package/src/cli/commands/sync.test.ts +0 -213
  153. package/src/cli/commands/sync.ts +0 -251
  154. package/src/cli/commands/validate.test.ts +0 -216
  155. package/src/cli/commands/validate.ts +0 -340
  156. package/src/cli/index.test.ts +0 -190
  157. package/src/cli/index.ts +0 -493
  158. package/src/commands/context.test.ts +0 -163
  159. package/src/commands/context.ts +0 -111
  160. package/src/commands/index.ts +0 -56
  161. package/src/commands/loader.test.ts +0 -273
  162. package/src/commands/loader.ts +0 -355
  163. package/src/commands/registry.test.ts +0 -384
  164. package/src/commands/registry.ts +0 -248
  165. package/src/commands/runner.test.ts +0 -297
  166. package/src/commands/runner.ts +0 -222
  167. package/src/commands/types.ts +0 -361
  168. package/src/config/index.ts +0 -19
  169. package/src/config/loader.test.ts +0 -262
  170. package/src/config/loader.ts +0 -188
  171. package/src/config/types.ts +0 -154
  172. package/src/context/index.ts +0 -14
  173. package/src/context/loader.test.ts +0 -334
  174. package/src/context/loader.ts +0 -357
  175. package/src/index.test.ts +0 -13
  176. package/src/index.ts +0 -268
  177. package/src/knowledge-library/index.ts +0 -44
  178. package/src/knowledge-library/manager.test.ts +0 -536
  179. package/src/knowledge-library/manager.ts +0 -804
  180. package/src/knowledge-library/types.ts +0 -432
  181. package/src/skills/generator.test.ts +0 -602
  182. package/src/skills/generator.ts +0 -491
  183. package/src/skills/index.ts +0 -27
  184. package/src/skills/templates.ts +0 -520
  185. package/src/skills/types.ts +0 -251
  186. package/templates/completion-report.md +0 -72
  187. package/templates/feedback.md +0 -56
  188. package/templates/project-files/CLAUDE.md.template +0 -109
  189. package/templates/project-files/coreai.json.example +0 -47
  190. package/templates/project-files/mcp.json.template +0 -20
  191. package/templates/review-complete.md +0 -64
  192. package/templates/review-request.md +0 -67
  193. package/templates/task-assignment.md +0 -51
  194. package/tsconfig.build.json +0 -4
  195. package/tsconfig.json +0 -26
  196. package/tsup.config.ts +0 -23
@@ -1,361 +0,0 @@
1
- /**
2
- * Command Framework Types
3
- *
4
- * Type definitions for the CoreAI command registration and execution system.
5
- */
6
-
7
- import type { ResolvedCoreAIConfig } from '../config/types.js';
8
- import type { AdapterFactory, AdapterType } from '../adapters/index.js';
9
-
10
- /**
11
- * Command category for organization
12
- */
13
- export type CommandCategory = 'core' | 'optional' | 'custom';
14
-
15
- /**
16
- * Integration dependency for a command
17
- */
18
- export interface IntegrationDependency {
19
- /**
20
- * Adapter type required
21
- */
22
- type: AdapterType;
23
-
24
- /**
25
- * Whether this integration is required or optional
26
- * If required and missing, command won't be registered
27
- * If optional and missing, command degrades gracefully
28
- */
29
- required: boolean;
30
-
31
- /**
32
- * Description of what this integration is used for
33
- */
34
- description?: string;
35
- }
36
-
37
- /**
38
- * Command metadata parsed from markdown frontmatter
39
- */
40
- export interface CommandMetadata {
41
- /**
42
- * Command name (derived from filename)
43
- */
44
- name: string;
45
-
46
- /**
47
- * Human-readable description
48
- */
49
- description: string;
50
-
51
- /**
52
- * Hint for command arguments
53
- */
54
- argumentHint?: string;
55
-
56
- /**
57
- * Command category
58
- */
59
- category: CommandCategory;
60
-
61
- /**
62
- * Integration dependencies
63
- */
64
- dependencies: IntegrationDependency[];
65
-
66
- /**
67
- * Path to the source markdown file
68
- */
69
- sourcePath: string;
70
-
71
- /**
72
- * Whether command is available (all required deps satisfied)
73
- */
74
- available: boolean;
75
-
76
- /**
77
- * Reason command is unavailable (if not available)
78
- */
79
- unavailableReason?: string;
80
- }
81
-
82
- /**
83
- * Runtime context available during command execution
84
- */
85
- export interface CommandContext {
86
- /**
87
- * Loaded configuration (may be null if no config file)
88
- */
89
- config: ResolvedCoreAIConfig | null;
90
-
91
- /**
92
- * Adapter factory for accessing integrations
93
- */
94
- adapterFactory: AdapterFactory | null;
95
-
96
- /**
97
- * Project root directory
98
- */
99
- projectRoot: string;
100
-
101
- /**
102
- * Check if an integration is available
103
- */
104
- hasIntegration(type: AdapterType): boolean;
105
-
106
- /**
107
- * Get adapter with graceful handling
108
- * Returns null if not available instead of throwing
109
- */
110
- getAdapterSafe<T>(type: AdapterType): Promise<T | null>;
111
- }
112
-
113
- /**
114
- * Base options available to all commands
115
- */
116
- export interface BaseCommandOptions {
117
- /**
118
- * Output format
119
- */
120
- format?: 'text' | 'json';
121
-
122
- /**
123
- * Verbose output
124
- */
125
- verbose?: boolean;
126
-
127
- /**
128
- * Project root directory override
129
- */
130
- projectRoot?: string;
131
- }
132
-
133
- /**
134
- * Result of command execution
135
- */
136
- export interface CommandResult<T = unknown> {
137
- /**
138
- * Whether command completed successfully
139
- */
140
- success: boolean;
141
-
142
- /**
143
- * Result data (command-specific)
144
- */
145
- data?: T;
146
-
147
- /**
148
- * Error message if failed
149
- */
150
- error?: string;
151
-
152
- /**
153
- * Warnings that occurred during execution
154
- */
155
- warnings?: string[];
156
-
157
- /**
158
- * Steps that were skipped due to missing integrations
159
- */
160
- skippedSteps?: {
161
- step: string;
162
- reason: string;
163
- }[];
164
- }
165
-
166
- /**
167
- * Command handler function signature
168
- */
169
- export type CommandHandler<TOptions = BaseCommandOptions, TResult = unknown> = (
170
- args: string[],
171
- options: TOptions,
172
- context: CommandContext
173
- ) => Promise<CommandResult<TResult>>;
174
-
175
- /**
176
- * Command definition for programmatic commands
177
- */
178
- export interface CommandDefinition<TOptions = BaseCommandOptions, TResult = unknown> {
179
- /**
180
- * Command name
181
- */
182
- name: string;
183
-
184
- /**
185
- * Human-readable description
186
- */
187
- description: string;
188
-
189
- /**
190
- * Command category
191
- */
192
- category: CommandCategory;
193
-
194
- /**
195
- * Integration dependencies
196
- */
197
- dependencies?: IntegrationDependency[];
198
-
199
- /**
200
- * Option definitions for Commander.js
201
- */
202
- options?: CommandOptionDefinition[];
203
-
204
- /**
205
- * Positional argument definitions
206
- */
207
- arguments?: CommandArgumentDefinition[];
208
-
209
- /**
210
- * Command handler
211
- */
212
- handler: CommandHandler<TOptions, TResult>;
213
-
214
- /**
215
- * Subcommands (for command groups like 'agents list', 'agents show')
216
- */
217
- subcommands?: CommandDefinition[];
218
- }
219
-
220
- /**
221
- * Command option definition
222
- */
223
- export interface CommandOptionDefinition {
224
- /**
225
- * Option flags (e.g., '-f, --force')
226
- */
227
- flags: string;
228
-
229
- /**
230
- * Description
231
- */
232
- description: string;
233
-
234
- /**
235
- * Default value
236
- */
237
- defaultValue?: unknown;
238
-
239
- /**
240
- * Whether option is required
241
- */
242
- required?: boolean;
243
- }
244
-
245
- /**
246
- * Command argument definition
247
- */
248
- export interface CommandArgumentDefinition {
249
- /**
250
- * Argument name
251
- */
252
- name: string;
253
-
254
- /**
255
- * Description
256
- */
257
- description: string;
258
-
259
- /**
260
- * Whether argument is required
261
- */
262
- required?: boolean;
263
-
264
- /**
265
- * Default value
266
- */
267
- defaultValue?: unknown;
268
- }
269
-
270
- /**
271
- * Markdown command definition (parsed from file)
272
- */
273
- export interface MarkdownCommand {
274
- /**
275
- * Command metadata
276
- */
277
- metadata: CommandMetadata;
278
-
279
- /**
280
- * Raw markdown content (instructions for agents)
281
- */
282
- content: string;
283
-
284
- /**
285
- * Parsed sections from markdown
286
- */
287
- sections: {
288
- title?: string;
289
- instructions?: string;
290
- fallbacks?: string;
291
- outputFormat?: string;
292
- };
293
- }
294
-
295
- /**
296
- * Command registry entry
297
- */
298
- export interface RegistryEntry {
299
- /**
300
- * Command metadata
301
- */
302
- metadata: CommandMetadata;
303
-
304
- /**
305
- * Command definition (for programmatic commands)
306
- */
307
- definition?: CommandDefinition;
308
-
309
- /**
310
- * Markdown command (for agent commands)
311
- */
312
- markdownCommand?: MarkdownCommand;
313
-
314
- /**
315
- * Source type
316
- */
317
- source: 'programmatic' | 'markdown';
318
- }
319
-
320
- /**
321
- * Options for loading commands from directory
322
- */
323
- export interface CommandLoaderOptions {
324
- /**
325
- * Directory to load commands from
326
- */
327
- directory: string;
328
-
329
- /**
330
- * Category to assign to loaded commands
331
- */
332
- category: CommandCategory;
333
-
334
- /**
335
- * Recursively search subdirectories
336
- */
337
- recursive?: boolean;
338
-
339
- /**
340
- * Filter function to include/exclude commands
341
- */
342
- filter?: (metadata: CommandMetadata) => boolean;
343
- }
344
-
345
- /**
346
- * Result of loading commands
347
- */
348
- export interface CommandLoadResult {
349
- /**
350
- * Successfully loaded commands
351
- */
352
- loaded: MarkdownCommand[];
353
-
354
- /**
355
- * Failed to load
356
- */
357
- errors: {
358
- path: string;
359
- error: string;
360
- }[];
361
- }
@@ -1,19 +0,0 @@
1
- /**
2
- * Configuration Module
3
- *
4
- * Provides configuration loading, validation, and management for CoreAI.
5
- */
6
-
7
- export * from './types.js';
8
- export {
9
- loadConfig,
10
- loadConfigFromFile,
11
- findConfigFile,
12
- parseConfig,
13
- validateConfig,
14
- applyDefaults,
15
- configExists,
16
- getConfigPath,
17
- ConfigError,
18
- type ConfigErrorCode,
19
- } from './loader.js';
@@ -1,262 +0,0 @@
1
- import { mkdtempSync, writeFileSync, mkdirSync, rmSync } from 'fs';
2
- import { join } from 'path';
3
- import { tmpdir } from 'os';
4
- import {
5
- findConfigFile,
6
- parseConfig,
7
- validateConfig,
8
- applyDefaults,
9
- loadConfigFromFile,
10
- configExists,
11
- getConfigPath,
12
- ConfigError,
13
- } from './loader.js';
14
- import type { CoreAIConfig } from './types.js';
15
-
16
- /**
17
- * Helper to check ConfigError with specific code
18
- */
19
- function expectConfigError(fn: () => unknown, code: string): void {
20
- try {
21
- fn();
22
- fail('Expected ConfigError to be thrown');
23
- } catch (error) {
24
- expect(error).toBeInstanceOf(ConfigError);
25
- expect((error as ConfigError).code).toBe(code);
26
- }
27
- }
28
-
29
- describe('Config Loader', () => {
30
- let tempDir: string;
31
-
32
- beforeEach(() => {
33
- tempDir = mkdtempSync(join(tmpdir(), 'coreai-test-'));
34
- });
35
-
36
- afterEach(() => {
37
- rmSync(tempDir, { recursive: true, force: true });
38
- });
39
-
40
- describe('findConfigFile', () => {
41
- it('should find config file in current directory', () => {
42
- const configPath = join(tempDir, 'coreai.config.yaml');
43
- writeFileSync(configPath, 'version: "1.0"\nproject:\n name: test');
44
-
45
- const result = findConfigFile(tempDir);
46
- expect(result).toBe(configPath);
47
- });
48
-
49
- it('should find config file with .yml extension', () => {
50
- const configPath = join(tempDir, 'coreai.config.yml');
51
- writeFileSync(configPath, 'version: "1.0"\nproject:\n name: test');
52
-
53
- const result = findConfigFile(tempDir);
54
- expect(result).toBe(configPath);
55
- });
56
-
57
- it('should find config file in parent directory', () => {
58
- const subDir = join(tempDir, 'subdir');
59
- mkdirSync(subDir);
60
- const configPath = join(tempDir, 'coreai.config.yaml');
61
- writeFileSync(configPath, 'version: "1.0"\nproject:\n name: test');
62
-
63
- const result = findConfigFile(subDir);
64
- expect(result).toBe(configPath);
65
- });
66
-
67
- it('should return null when no config file exists in temp dir', () => {
68
- // Create an isolated deep directory structure to avoid finding project root config
69
- const deepDir = join(tempDir, 'a', 'b', 'c', 'd', 'e');
70
- mkdirSync(deepDir, { recursive: true });
71
-
72
- // findConfigFile walks up, so we test from within tempDir where we control the env
73
- const result = findConfigFile(deepDir);
74
- // It might find the project root config, so we just check it doesn't find one in tempDir
75
- if (result !== null) {
76
- expect(result.startsWith(tempDir)).toBe(false);
77
- }
78
- });
79
- });
80
-
81
- describe('parseConfig', () => {
82
- it('should parse valid YAML', () => {
83
- const yaml = `
84
- version: "1.0"
85
- project:
86
- name: "Test Project"
87
- type: software
88
- `;
89
- const result = parseConfig(yaml);
90
- expect(result).toEqual({
91
- version: '1.0',
92
- project: {
93
- name: 'Test Project',
94
- type: 'software',
95
- },
96
- });
97
- });
98
-
99
- it('should throw ConfigError for invalid YAML', () => {
100
- const invalidYaml = `
101
- version: "1.0"
102
- project:
103
- name: "Test
104
- invalid: yaml
105
- `;
106
- expectConfigError(() => parseConfig(invalidYaml), 'PARSE_ERROR');
107
- });
108
- });
109
-
110
- describe('validateConfig', () => {
111
- it('should validate a minimal valid config', () => {
112
- const config = {
113
- version: '1.0',
114
- project: { name: 'Test' },
115
- };
116
-
117
- const result = validateConfig(config);
118
- expect(result).toEqual(config);
119
- });
120
-
121
- it('should validate a full config', () => {
122
- const config: CoreAIConfig = {
123
- version: '1.0',
124
- project: { name: 'Test', type: 'software' },
125
- team: { agents: ['backend-engineer'] },
126
- integrations: {
127
- git: { provider: 'github', config: { repo: 'org/repo' } },
128
- issue_tracker: { provider: 'jira', config: { project_key: 'TEST' } },
129
- },
130
- quality_gates: {
131
- lint: { command: 'npm run lint', required: true },
132
- },
133
- tech_stack: { primary_language: 'typescript' },
134
- };
135
-
136
- const result = validateConfig(config);
137
- expect(result).toEqual(config);
138
- });
139
-
140
- it('should throw for missing required fields', () => {
141
- const config = { version: '1.0' }; // missing project
142
- expectConfigError(() => validateConfig(config), 'VALIDATION_ERROR');
143
- });
144
-
145
- it('should throw for invalid version', () => {
146
- const config = {
147
- version: '2.0', // invalid version
148
- project: { name: 'Test' },
149
- };
150
- expectConfigError(() => validateConfig(config), 'VALIDATION_ERROR');
151
- });
152
-
153
- it('should throw for invalid provider', () => {
154
- const config = {
155
- version: '1.0',
156
- project: { name: 'Test' },
157
- integrations: {
158
- git: { provider: 'invalid-provider' },
159
- },
160
- };
161
- expectConfigError(() => validateConfig(config), 'VALIDATION_ERROR');
162
- });
163
- });
164
-
165
- describe('applyDefaults', () => {
166
- it('should apply default project type', () => {
167
- const config: CoreAIConfig = {
168
- version: '1.0',
169
- project: { name: 'Test' },
170
- };
171
-
172
- const result = applyDefaults(config);
173
- expect(result.project.type).toBe('software');
174
- });
175
-
176
- it('should apply default agents', () => {
177
- const config: CoreAIConfig = {
178
- version: '1.0',
179
- project: { name: 'Test' },
180
- };
181
-
182
- const result = applyDefaults(config);
183
- expect(result.team.agents).toEqual([
184
- 'backend-engineer',
185
- 'frontend-engineer',
186
- 'devops-engineer',
187
- 'engineering-manager',
188
- ]);
189
- });
190
-
191
- it('should preserve explicit values', () => {
192
- const config: CoreAIConfig = {
193
- version: '1.0',
194
- project: { name: 'Test', type: 'infrastructure' },
195
- team: { agents: ['devops-engineer'] },
196
- };
197
-
198
- const result = applyDefaults(config);
199
- expect(result.project.type).toBe('infrastructure');
200
- expect(result.team.agents).toEqual(['devops-engineer']);
201
- });
202
- });
203
-
204
- describe('loadConfigFromFile', () => {
205
- it('should load and validate a config file', () => {
206
- const configPath = join(tempDir, 'coreai.config.yaml');
207
- writeFileSync(
208
- configPath,
209
- `
210
- version: "1.0"
211
- project:
212
- name: "Test Project"
213
- `
214
- );
215
-
216
- const result = loadConfigFromFile(configPath);
217
- expect(result.project.name).toBe('Test Project');
218
- expect(result.project.type).toBe('software'); // default applied
219
- });
220
-
221
- it('should throw for non-existent file', () => {
222
- const configPath = join(tempDir, 'nonexistent.yaml');
223
- expectConfigError(() => loadConfigFromFile(configPath), 'READ_ERROR');
224
- });
225
-
226
- it('should throw for invalid config', () => {
227
- const configPath = join(tempDir, 'coreai.config.yaml');
228
- writeFileSync(configPath, 'invalid: config');
229
- expectConfigError(() => loadConfigFromFile(configPath), 'VALIDATION_ERROR');
230
- });
231
- });
232
-
233
- describe('configExists', () => {
234
- it('should return true when config exists', () => {
235
- const configPath = join(tempDir, 'coreai.config.yaml');
236
- writeFileSync(configPath, 'version: "1.0"\nproject:\n name: test');
237
-
238
- expect(configExists(tempDir)).toBe(true);
239
- });
240
-
241
- it('should return false when no config in temp directory tree', () => {
242
- // We can't truly test "no config exists" because findConfigFile walks up
243
- // to the filesystem root. Instead, test that configExists returns a boolean.
244
- const result = configExists(tempDir);
245
- expect(typeof result).toBe('boolean');
246
- });
247
- });
248
-
249
- describe('getConfigPath', () => {
250
- it('should return path when config exists', () => {
251
- const configPath = join(tempDir, 'coreai.config.yaml');
252
- writeFileSync(configPath, 'version: "1.0"\nproject:\n name: test');
253
-
254
- expect(getConfigPath(tempDir)).toBe(configPath);
255
- });
256
-
257
- it('should return string or null', () => {
258
- const result = getConfigPath(tempDir);
259
- expect(result === null || typeof result === 'string').toBe(true);
260
- });
261
- });
262
- });