@deimoscloud/coreai 0.1.8 → 0.1.10

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 +5 -0
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/index.js +3 -1
  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 -399
  126. package/src/agents/compiler.ts +0 -422
  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,251 +0,0 @@
1
- /**
2
- * Sync Command
3
- *
4
- * Syncs shared context from remote sources.
5
- */
6
-
7
- import { join } from 'path';
8
- import {
9
- FileCacheProvider,
10
- CACHE_PATHS,
11
- type SyncResult,
12
- type CacheSource,
13
- } from '../../cache/index.js';
14
- import { CacheManager } from '../../cache/manager.js';
15
- import type { RemoteFetcher } from '../../cache/interfaces.js';
16
-
17
- /**
18
- * Options for sync command
19
- */
20
- export interface SyncCommandOptions {
21
- /**
22
- * Project root directory
23
- */
24
- projectRoot?: string;
25
-
26
- /**
27
- * Custom cache path
28
- */
29
- cachePath?: string;
30
-
31
- /**
32
- * Force refresh all entries
33
- */
34
- force?: boolean;
35
-
36
- /**
37
- * Filter by source type
38
- */
39
- source?: CacheSource;
40
-
41
- /**
42
- * Continue on error
43
- */
44
- continueOnError?: boolean;
45
-
46
- /**
47
- * Maximum concurrent fetches
48
- */
49
- concurrency?: number;
50
-
51
- /**
52
- * Progress callback
53
- */
54
- onProgress?: (completed: number, total: number, message: string) => void;
55
- }
56
-
57
- /**
58
- * Result of sync command
59
- */
60
- export interface SyncCommandResult {
61
- success: boolean;
62
- result: SyncResult | null;
63
- error?: string;
64
- sources: string[];
65
- }
66
-
67
- /**
68
- * Create a mock fetcher for a source (placeholder until real fetchers are implemented)
69
- *
70
- * In a real implementation, these would be replaced with actual fetchers
71
- * that use the documentation adapter interfaces.
72
- */
73
- function createPlaceholderFetcher(source: string): RemoteFetcher {
74
- return {
75
- async fetch(url: string) {
76
- // This is a placeholder - real implementation would use adapters
77
- throw new Error(
78
- `No fetcher implementation for source "${source}". ` +
79
- `URL: ${url}. Configure a documentation provider in coreai.config.yaml.`
80
- );
81
- },
82
- async hasChanged(_url: string, _etag?: string) {
83
- // Always return true for placeholder
84
- return true;
85
- },
86
- };
87
- }
88
-
89
- /**
90
- * Get the cache path for a project
91
- */
92
- function getCachePath(options: SyncCommandOptions): string {
93
- if (options.cachePath) {
94
- return options.cachePath;
95
- }
96
- const root = options.projectRoot ?? process.cwd();
97
- return join(root, CACHE_PATHS.base);
98
- }
99
-
100
- /**
101
- * Sync cached entries from remote sources
102
- *
103
- * This command refreshes cached content by re-fetching from remote sources.
104
- * If --force is specified, it clears stale/expired status and fetches fresh content.
105
- */
106
- export async function sync(options: SyncCommandOptions = {}): Promise<SyncCommandResult> {
107
- const cachePath = getCachePath(options);
108
-
109
- const provider = new FileCacheProvider({ basePath: cachePath });
110
-
111
- try {
112
- await provider.initialize();
113
- } catch (error) {
114
- return {
115
- success: false,
116
- result: null,
117
- error: `Failed to initialize cache: ${error instanceof Error ? error.message : String(error)}`,
118
- sources: [],
119
- };
120
- }
121
-
122
- // Get all cached entries
123
- const entries = await provider.list({ source: options.source });
124
-
125
- if (entries.length === 0) {
126
- return {
127
- success: true,
128
- result: {
129
- added: 0,
130
- updated: 0,
131
- removed: 0,
132
- failed: 0,
133
- errors: [],
134
- duration: 0,
135
- },
136
- sources: [],
137
- };
138
- }
139
-
140
- // Create cache manager
141
- const manager = new CacheManager({
142
- cache: provider,
143
- defaultTtl: 3600,
144
- });
145
-
146
- // Collect unique sources and register placeholder fetchers
147
- const sources = new Set<string>();
148
- for (const entry of entries) {
149
- sources.add(entry.source);
150
- }
151
-
152
- // Register fetchers for each source
153
- // In a real implementation, these would be actual fetcher implementations
154
- for (const source of sources) {
155
- if (!manager.hasFetcher(source)) {
156
- manager.registerFetcher(source, createPlaceholderFetcher(source));
157
- }
158
- }
159
-
160
- // Get keys to sync
161
- const keys = entries.map((e) => e.key);
162
-
163
- // Report progress
164
- if (options.onProgress) {
165
- options.onProgress(0, keys.length, 'Starting sync...');
166
- }
167
-
168
- // Sync entries
169
- try {
170
- const result = await manager.syncEntries(keys, {
171
- force: options.force,
172
- continueOnError: options.continueOnError ?? true,
173
- concurrency: options.concurrency ?? 5,
174
- onProgress: (completed, total) => {
175
- if (options.onProgress) {
176
- options.onProgress(completed, total, `Syncing ${completed}/${total} entries...`);
177
- }
178
- },
179
- });
180
-
181
- return {
182
- success: result.failed === 0 || options.continueOnError === true,
183
- result,
184
- sources: Array.from(sources),
185
- };
186
- } catch (error) {
187
- return {
188
- success: false,
189
- result: null,
190
- error: error instanceof Error ? error.message : String(error),
191
- sources: Array.from(sources),
192
- };
193
- }
194
- }
195
-
196
- /**
197
- * Format sync result for terminal output
198
- */
199
- export function formatSyncResult(result: SyncCommandResult): string {
200
- const lines: string[] = [];
201
-
202
- lines.push('Sync Results');
203
- lines.push('============');
204
- lines.push('');
205
-
206
- if (!result.success && result.error) {
207
- lines.push(`Error: ${result.error}`);
208
- return lines.join('\n');
209
- }
210
-
211
- if (!result.result) {
212
- lines.push('No sync operation performed.');
213
- return lines.join('\n');
214
- }
215
-
216
- const r = result.result;
217
-
218
- if (r.added === 0 && r.updated === 0 && r.removed === 0 && r.failed === 0) {
219
- lines.push('Cache is empty. Nothing to sync.');
220
- lines.push('');
221
- lines.push('Tip: Add context sources to your coreai.config.yaml to fetch remote content.');
222
- return lines.join('\n');
223
- }
224
-
225
- lines.push(`Duration: ${r.duration}ms`);
226
- lines.push('');
227
-
228
- if (result.sources.length > 0) {
229
- lines.push(`Sources: ${result.sources.join(', ')}`);
230
- lines.push('');
231
- }
232
-
233
- lines.push('Summary:');
234
- if (r.added > 0) lines.push(` ✓ Added: ${r.added}`);
235
- if (r.updated > 0) lines.push(` ✓ Updated: ${r.updated}`);
236
- if (r.removed > 0) lines.push(` ○ Removed: ${r.removed}`);
237
- if (r.failed > 0) lines.push(` ✗ Failed: ${r.failed}`);
238
-
239
- if (r.errors.length > 0) {
240
- lines.push('');
241
- lines.push('Errors:');
242
- for (const err of r.errors.slice(0, 10)) {
243
- lines.push(` - ${err.key}: ${err.error}`);
244
- }
245
- if (r.errors.length > 10) {
246
- lines.push(` ... and ${r.errors.length - 10} more errors`);
247
- }
248
- }
249
-
250
- return lines.join('\n');
251
- }
@@ -1,216 +0,0 @@
1
- /**
2
- * Validate Command Tests
3
- */
4
-
5
- import { promises as fs } from 'fs';
6
- import { join } from 'path';
7
- import { tmpdir } from 'os';
8
- import { validate, formatValidateResult } from './validate.js';
9
-
10
- describe('Validate Command', () => {
11
- let testDir: string;
12
-
13
- beforeEach(async () => {
14
- testDir = join(
15
- tmpdir(),
16
- `validate-cmd-test-${Date.now()}-${Math.random().toString(36).slice(2)}`
17
- );
18
- await fs.mkdir(testDir, { recursive: true });
19
- });
20
-
21
- afterEach(async () => {
22
- try {
23
- await fs.rm(testDir, { recursive: true, force: true });
24
- } catch {
25
- // Ignore cleanup errors
26
- }
27
- });
28
-
29
- describe('validate', () => {
30
- it('should report error if no config exists', () => {
31
- const result = validate({
32
- projectRoot: testDir,
33
- checkAgents: false,
34
- checkDirs: false,
35
- });
36
-
37
- expect(result.success).toBe(true);
38
- expect(result.valid).toBe(false);
39
- expect(result.summary.errors).toBeGreaterThan(0);
40
- expect(result.issues.some((i) => i.message.includes('No CoreAI configuration'))).toBe(true);
41
- });
42
-
43
- it('should validate valid config', async () => {
44
- const configPath = join(testDir, 'coreai.config.yaml');
45
- await fs.writeFile(
46
- configPath,
47
- `version: "1.0"
48
- project:
49
- name: test-project
50
- type: software
51
- team:
52
- agents:
53
- - backend-engineer
54
- `
55
- );
56
-
57
- const result = validate({
58
- projectRoot: testDir,
59
- checkAgents: false,
60
- checkDirs: false,
61
- });
62
-
63
- expect(result.success).toBe(true);
64
- expect(result.config).toBeDefined();
65
- expect(result.config?.project.name).toBe('test-project');
66
- });
67
-
68
- it('should report config syntax errors', async () => {
69
- const configPath = join(testDir, 'coreai.config.yaml');
70
- await fs.writeFile(configPath, 'invalid: yaml: content: [');
71
-
72
- const result = validate({
73
- projectRoot: testDir,
74
- checkAgents: false,
75
- checkDirs: false,
76
- });
77
-
78
- expect(result.valid).toBe(false);
79
- expect(result.issues.some((i) => i.category === 'config' && i.level === 'error')).toBe(true);
80
- });
81
-
82
- it('should check for missing directories', async () => {
83
- const configPath = join(testDir, 'coreai.config.yaml');
84
- await fs.writeFile(
85
- configPath,
86
- `version: "1.0"
87
- project:
88
- name: test-project
89
- `
90
- );
91
-
92
- const result = validate({
93
- projectRoot: testDir,
94
- checkAgents: false,
95
- checkDirs: true,
96
- });
97
-
98
- expect(result.issues.some((i) => i.category === 'directories')).toBe(true);
99
- });
100
-
101
- it('should report info for unconfigured integrations', async () => {
102
- const configPath = join(testDir, 'coreai.config.yaml');
103
- await fs.writeFile(
104
- configPath,
105
- `version: "1.0"
106
- project:
107
- name: test-project
108
- `
109
- );
110
-
111
- const result = validate({
112
- projectRoot: testDir,
113
- checkAgents: false,
114
- checkDirs: false,
115
- });
116
-
117
- expect(result.issues.some((i) => i.category === 'integrations' && i.level === 'info')).toBe(
118
- true
119
- );
120
- });
121
-
122
- it('should warn about incomplete git integration', async () => {
123
- const configPath = join(testDir, 'coreai.config.yaml');
124
- await fs.writeFile(
125
- configPath,
126
- `version: "1.0"
127
- project:
128
- name: test-project
129
- integrations:
130
- git:
131
- provider: github
132
- `
133
- );
134
-
135
- const result = validate({
136
- projectRoot: testDir,
137
- checkAgents: false,
138
- checkDirs: false,
139
- });
140
-
141
- expect(
142
- result.issues.some((i) => i.category === 'integrations' && i.level === 'warning')
143
- ).toBe(true);
144
- });
145
-
146
- it('should calculate correct summary', async () => {
147
- const result = validate({
148
- projectRoot: testDir,
149
- checkAgents: false,
150
- checkDirs: true,
151
- });
152
-
153
- expect(result.summary.errors + result.summary.warnings + result.summary.info).toBe(
154
- result.issues.length
155
- );
156
- });
157
- });
158
-
159
- describe('formatValidateResult', () => {
160
- it('should format valid result', () => {
161
- const result = {
162
- success: true,
163
- valid: true,
164
- issues: [],
165
- summary: { errors: 0, warnings: 0, info: 0 },
166
- };
167
-
168
- const output = formatValidateResult(result);
169
-
170
- expect(output).toContain('✓');
171
- expect(output).toContain('valid');
172
- });
173
-
174
- it('should format invalid result', () => {
175
- const result = {
176
- success: true,
177
- valid: false,
178
- issues: [
179
- {
180
- level: 'error' as const,
181
- category: 'config' as const,
182
- message: 'Config missing',
183
- fix: 'Run coreai init',
184
- },
185
- ],
186
- summary: { errors: 1, warnings: 0, info: 0 },
187
- };
188
-
189
- const output = formatValidateResult(result);
190
-
191
- expect(output).toContain('✗');
192
- expect(output).toContain('errors');
193
- expect(output).toContain('Config missing');
194
- expect(output).toContain('Run coreai init');
195
- });
196
-
197
- it('should group issues by category', () => {
198
- const result = {
199
- success: true,
200
- valid: false,
201
- issues: [
202
- { level: 'error' as const, category: 'config' as const, message: 'Config error' },
203
- { level: 'warning' as const, category: 'directories' as const, message: 'Dir warning' },
204
- { level: 'info' as const, category: 'integrations' as const, message: 'Int info' },
205
- ],
206
- summary: { errors: 1, warnings: 1, info: 1 },
207
- };
208
-
209
- const output = formatValidateResult(result);
210
-
211
- expect(output).toContain('Config');
212
- expect(output).toContain('Directories');
213
- expect(output).toContain('Integrations');
214
- });
215
- });
216
- });