@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,221 +0,0 @@
1
- /**
2
- * Cache Commands Tests
3
- */
4
-
5
- import { promises as fs } from 'fs';
6
- import { join } from 'path';
7
- import { tmpdir } from 'os';
8
- import { FileCacheProvider } from '../../cache/provider.js';
9
- import {
10
- cacheStatus,
11
- cacheClear,
12
- cacheClearExpired,
13
- formatCacheStatus,
14
- formatBytes,
15
- } from './cache.js';
16
-
17
- describe('Cache Commands', () => {
18
- let testDir: string;
19
-
20
- beforeEach(async () => {
21
- testDir = join(tmpdir(), `cache-cmd-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
22
- await fs.mkdir(testDir, { recursive: true });
23
- });
24
-
25
- afterEach(async () => {
26
- try {
27
- await fs.rm(testDir, { recursive: true, force: true });
28
- } catch {
29
- // Ignore cleanup errors
30
- }
31
- });
32
-
33
- describe('cacheStatus', () => {
34
- it('should return initialized for new directory', async () => {
35
- // Cache auto-initializes when called
36
- const result = await cacheStatus({ cachePath: join(testDir, 'new-cache') });
37
-
38
- expect(result.initialized).toBe(true);
39
- expect(result.stats).not.toBeNull();
40
- expect(result.entries).toHaveLength(0);
41
- });
42
-
43
- it('should return status for initialized cache', async () => {
44
- // Initialize cache with some entries
45
- const provider = new FileCacheProvider({ basePath: testDir });
46
- await provider.initialize();
47
- await provider.set('test-key', 'test content', {
48
- source: 'github',
49
- sourceUrl: 'https://github.com/test',
50
- });
51
-
52
- const result = await cacheStatus({ cachePath: testDir });
53
-
54
- expect(result.initialized).toBe(true);
55
- expect(result.stats).not.toBeNull();
56
- expect(result.stats?.totalEntries).toBe(1);
57
- expect(result.entries).toHaveLength(1);
58
- expect(result.entries[0].key).toBe('test-key');
59
- expect(result.entries[0].source).toBe('github');
60
- });
61
-
62
- it('should include entry status', async () => {
63
- const provider = new FileCacheProvider({ basePath: testDir });
64
- await provider.initialize();
65
- await provider.set(
66
- 'valid-entry',
67
- 'content',
68
- { source: 'local', sourceUrl: '' },
69
- { ttl: 3600 }
70
- );
71
-
72
- const result = await cacheStatus({ cachePath: testDir });
73
-
74
- expect(result.entries[0].status).toBe('valid');
75
- });
76
- });
77
-
78
- describe('cacheClear', () => {
79
- it('should clear all cache entries', async () => {
80
- const provider = new FileCacheProvider({ basePath: testDir });
81
- await provider.initialize();
82
- await provider.set('key1', 'content1', { source: 'local', sourceUrl: '' });
83
- await provider.set('key2', 'content2', { source: 'local', sourceUrl: '' });
84
-
85
- const result = await cacheClear({ cachePath: testDir });
86
-
87
- expect(result.success).toBe(true);
88
- expect(result.cleared).toBe(2);
89
-
90
- // Verify cache is empty
91
- const status = await cacheStatus({ cachePath: testDir });
92
- expect(status.entries).toHaveLength(0);
93
- });
94
-
95
- it('should handle empty cache', async () => {
96
- const provider = new FileCacheProvider({ basePath: testDir });
97
- await provider.initialize();
98
-
99
- const result = await cacheClear({ cachePath: testDir });
100
-
101
- expect(result.success).toBe(true);
102
- expect(result.cleared).toBe(0);
103
- });
104
-
105
- it('should handle uninitialized cache directory', async () => {
106
- const result = await cacheClear({ cachePath: join(testDir, 'new-cache') });
107
-
108
- expect(result.success).toBe(true);
109
- expect(result.cleared).toBe(0);
110
- });
111
- });
112
-
113
- describe('cacheClearExpired', () => {
114
- it('should only clear expired entries', async () => {
115
- const provider = new FileCacheProvider({ basePath: testDir });
116
- await provider.initialize();
117
-
118
- // Add a valid entry
119
- await provider.set('valid', 'content', { source: 'local', sourceUrl: '' }, { ttl: 3600 });
120
-
121
- // Add an "expired" entry by manipulating the metadata
122
- await provider.set('expired', 'content', { source: 'local', sourceUrl: '' }, { ttl: 1 });
123
-
124
- // Wait for expiration
125
- await new Promise((resolve) => setTimeout(resolve, 1100));
126
-
127
- const result = await cacheClearExpired({ cachePath: testDir });
128
-
129
- expect(result.success).toBe(true);
130
- expect(result.cleared).toBe(1);
131
-
132
- // Valid entry should still exist
133
- const status = await cacheStatus({ cachePath: testDir });
134
- expect(status.entries.map((e) => e.key)).toContain('valid');
135
- });
136
- });
137
-
138
- describe('formatBytes', () => {
139
- it('should format bytes correctly', () => {
140
- expect(formatBytes(0)).toBe('0 B');
141
- expect(formatBytes(100)).toBe('100 B');
142
- expect(formatBytes(1024)).toBe('1 KB');
143
- expect(formatBytes(1536)).toBe('1.5 KB');
144
- expect(formatBytes(1048576)).toBe('1 MB');
145
- expect(formatBytes(1073741824)).toBe('1 GB');
146
- });
147
- });
148
-
149
- describe('formatCacheStatus', () => {
150
- it('should format uninitialized cache', () => {
151
- const result = formatCacheStatus({
152
- initialized: false,
153
- path: '/test/cache',
154
- stats: null,
155
- entries: [],
156
- });
157
-
158
- expect(result).toContain('Not initialized');
159
- expect(result).toContain('/test/cache');
160
- });
161
-
162
- it('should format initialized cache with entries', () => {
163
- const result = formatCacheStatus({
164
- initialized: true,
165
- path: '/test/cache',
166
- stats: {
167
- totalEntries: 2,
168
- totalSize: 1024,
169
- validEntries: 1,
170
- staleEntries: 1,
171
- expiredEntries: 0,
172
- bySource: { github: 2, confluence: 0, notion: 0, local: 0, custom: 0 },
173
- newestEntry: '2024-01-01T00:00:00Z',
174
- },
175
- entries: [
176
- {
177
- key: 'entry1',
178
- source: 'github',
179
- status: 'valid',
180
- size: 512,
181
- cachedAt: '2024-01-01T00:00:00Z',
182
- expiresAt: '2024-01-02T00:00:00Z',
183
- },
184
- {
185
- key: 'entry2',
186
- source: 'github',
187
- status: 'stale',
188
- size: 512,
189
- cachedAt: '2024-01-01T00:00:00Z',
190
- expiresAt: '2024-01-02T00:00:00Z',
191
- },
192
- ],
193
- });
194
-
195
- expect(result).toContain('Initialized');
196
- expect(result).toContain('Entries: 2');
197
- expect(result).toContain('1 KB');
198
- expect(result).toContain('github');
199
- expect(result).toContain('entry1');
200
- expect(result).toContain('entry2');
201
- });
202
-
203
- it('should format empty cache', () => {
204
- const result = formatCacheStatus({
205
- initialized: true,
206
- path: '/test/cache',
207
- stats: {
208
- totalEntries: 0,
209
- totalSize: 0,
210
- validEntries: 0,
211
- staleEntries: 0,
212
- expiredEntries: 0,
213
- bySource: { github: 0, confluence: 0, notion: 0, local: 0, custom: 0 },
214
- },
215
- entries: [],
216
- });
217
-
218
- expect(result).toContain('No entries in cache');
219
- });
220
- });
221
- });
@@ -1,229 +0,0 @@
1
- /**
2
- * Cache Commands
3
- *
4
- * Commands for managing the local cache.
5
- */
6
-
7
- import { join } from 'path';
8
- import { FileCacheProvider, CACHE_PATHS, type CacheStats } from '../../cache/index.js';
9
-
10
- /**
11
- * Options for cache commands
12
- */
13
- export interface CacheCommandOptions {
14
- /**
15
- * Project root directory
16
- */
17
- projectRoot?: string;
18
-
19
- /**
20
- * Custom cache path (overrides default)
21
- */
22
- cachePath?: string;
23
-
24
- /**
25
- * Output format
26
- */
27
- format?: 'text' | 'json';
28
- }
29
-
30
- /**
31
- * Result of cache status command
32
- */
33
- export interface CacheStatusResult {
34
- initialized: boolean;
35
- path: string;
36
- stats: CacheStats | null;
37
- entries: {
38
- key: string;
39
- source: string;
40
- status: string;
41
- size: number;
42
- cachedAt: string;
43
- expiresAt: string;
44
- }[];
45
- }
46
-
47
- /**
48
- * Result of cache clear command
49
- */
50
- export interface CacheClearResult {
51
- cleared: number;
52
- success: boolean;
53
- error?: string;
54
- }
55
-
56
- /**
57
- * Get the cache path for a project
58
- */
59
- function getCachePath(options: CacheCommandOptions): string {
60
- if (options.cachePath) {
61
- return options.cachePath;
62
- }
63
- const root = options.projectRoot ?? process.cwd();
64
- return join(root, CACHE_PATHS.ROOT);
65
- }
66
-
67
- /**
68
- * Get cache status
69
- */
70
- export async function cacheStatus(options: CacheCommandOptions = {}): Promise<CacheStatusResult> {
71
- const cachePath = getCachePath(options);
72
-
73
- const provider = new FileCacheProvider({ basePath: cachePath });
74
-
75
- try {
76
- await provider.initialize();
77
- } catch {
78
- return {
79
- initialized: false,
80
- path: cachePath,
81
- stats: null,
82
- entries: [],
83
- };
84
- }
85
-
86
- const stats = await provider.getStats();
87
- const metadataList = await provider.list();
88
-
89
- const entries = await Promise.all(
90
- metadataList.map(async (metadata) => {
91
- const status = await provider.getStatus(metadata.key);
92
- return {
93
- key: metadata.key,
94
- source: metadata.source,
95
- status: status ?? 'unknown',
96
- size: metadata.size,
97
- cachedAt: metadata.cachedAt,
98
- expiresAt: metadata.expiresAt,
99
- };
100
- })
101
- );
102
-
103
- return {
104
- initialized: true,
105
- path: cachePath,
106
- stats,
107
- entries,
108
- };
109
- }
110
-
111
- /**
112
- * Clear all cache entries
113
- */
114
- export async function cacheClear(options: CacheCommandOptions = {}): Promise<CacheClearResult> {
115
- const cachePath = getCachePath(options);
116
-
117
- const provider = new FileCacheProvider({ basePath: cachePath });
118
-
119
- try {
120
- await provider.initialize();
121
- const cleared = await provider.clear();
122
- return { cleared, success: true };
123
- } catch (error) {
124
- return {
125
- cleared: 0,
126
- success: false,
127
- error: error instanceof Error ? error.message : String(error),
128
- };
129
- }
130
- }
131
-
132
- /**
133
- * Clear expired cache entries
134
- */
135
- export async function cacheClearExpired(
136
- options: CacheCommandOptions = {}
137
- ): Promise<CacheClearResult> {
138
- const cachePath = getCachePath(options);
139
-
140
- const provider = new FileCacheProvider({ basePath: cachePath });
141
-
142
- try {
143
- await provider.initialize();
144
- const cleared = await provider.clearExpired();
145
- return { cleared, success: true };
146
- } catch (error) {
147
- return {
148
- cleared: 0,
149
- success: false,
150
- error: error instanceof Error ? error.message : String(error),
151
- };
152
- }
153
- }
154
-
155
- /**
156
- * Format bytes to human-readable string
157
- */
158
- export function formatBytes(bytes: number): string {
159
- if (bytes === 0) return '0 B';
160
- const k = 1024;
161
- const sizes = ['B', 'KB', 'MB', 'GB'];
162
- const i = Math.floor(Math.log(bytes) / Math.log(k));
163
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
164
- }
165
-
166
- /**
167
- * Format cache status for terminal output
168
- */
169
- export function formatCacheStatus(result: CacheStatusResult): string {
170
- const lines: string[] = [];
171
-
172
- lines.push('Cache Status');
173
- lines.push('============');
174
- lines.push('');
175
-
176
- if (!result.initialized) {
177
- lines.push(`Path: ${result.path}`);
178
- lines.push('Status: Not initialized (no cache found)');
179
- return lines.join('\n');
180
- }
181
-
182
- lines.push(`Path: ${result.path}`);
183
- lines.push('Status: Initialized');
184
- lines.push('');
185
-
186
- if (result.stats) {
187
- lines.push('Statistics:');
188
- lines.push(` Entries: ${result.stats.totalEntries}`);
189
- lines.push(` Total size: ${formatBytes(result.stats.totalSize)}`);
190
- lines.push(
191
- ` Valid: ${result.stats.validEntries}, Stale: ${result.stats.staleEntries}, Expired: ${result.stats.expiredEntries}`
192
- );
193
- if (result.stats.newestEntry) {
194
- lines.push(` Last updated: ${result.stats.newestEntry}`);
195
- }
196
- }
197
-
198
- if (result.entries.length > 0) {
199
- lines.push('');
200
- lines.push('Entries:');
201
- lines.push('');
202
-
203
- // Group by source
204
- const bySource = new Map<string, typeof result.entries>();
205
- for (const entry of result.entries) {
206
- const source = entry.source;
207
- if (!bySource.has(source)) {
208
- bySource.set(source, []);
209
- }
210
- const entries = bySource.get(source);
211
- if (entries) {
212
- entries.push(entry);
213
- }
214
- }
215
-
216
- for (const [source, entries] of bySource) {
217
- lines.push(` ${source}:`);
218
- for (const entry of entries) {
219
- const statusIcon = entry.status === 'valid' ? '✓' : entry.status === 'stale' ? '○' : '✗';
220
- lines.push(` ${statusIcon} ${entry.key} (${formatBytes(entry.size)})`);
221
- }
222
- }
223
- } else {
224
- lines.push('');
225
- lines.push('No entries in cache.');
226
- }
227
-
228
- return lines.join('\n');
229
- }
@@ -1,63 +0,0 @@
1
- /**
2
- * CLI Commands
3
- *
4
- * Command implementations for the CoreAI CLI.
5
- */
6
-
7
- // Cache commands
8
- export {
9
- cacheStatus,
10
- cacheClear,
11
- cacheClearExpired,
12
- formatCacheStatus,
13
- formatBytes,
14
- type CacheCommandOptions,
15
- type CacheStatusResult,
16
- type CacheClearResult,
17
- } from './cache.js';
18
-
19
- // Sync commands
20
- export { sync, formatSyncResult, type SyncCommandOptions, type SyncCommandResult } from './sync.js';
21
-
22
- // Init command
23
- export { init, formatInitResult, type InitCommandOptions, type InitCommandResult } from './init.js';
24
-
25
- // Build command
26
- export {
27
- build,
28
- formatBuildResult,
29
- type BuildCommandOptions,
30
- type BuildCommandResult,
31
- } from './build.js';
32
-
33
- // Validate command
34
- export {
35
- validate,
36
- formatValidateResult,
37
- type ValidateCommandOptions,
38
- type ValidateCommandResult,
39
- type ValidationIssue,
40
- } from './validate.js';
41
-
42
- // Skills commands
43
- export {
44
- skillsGenerate,
45
- formatSkillsGenerateResult,
46
- skillsList,
47
- formatSkillsListResult,
48
- type SkillsGenerateOptions,
49
- type SkillsGenerateResult,
50
- type SkillsListOptions,
51
- type SkillsListResult,
52
- type SkillInfo,
53
- } from './skills.js';
54
-
55
- // Status command
56
- export {
57
- status,
58
- formatStatusResult,
59
- formatStatusSummary,
60
- type StatusCommandOptions,
61
- type StatusCommandResult,
62
- type AgentStatus,
63
- } from './status.js';
@@ -1,173 +0,0 @@
1
- /**
2
- * Init Command Tests
3
- */
4
-
5
- import { promises as fs } from 'fs';
6
- import { join } from 'path';
7
- import { tmpdir } from 'os';
8
- import { init, formatInitResult } from './init.js';
9
-
10
- describe('Init Command', () => {
11
- let testDir: string;
12
-
13
- beforeEach(async () => {
14
- testDir = join(tmpdir(), `init-cmd-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
15
- await fs.mkdir(testDir, { recursive: true });
16
- });
17
-
18
- afterEach(async () => {
19
- try {
20
- await fs.rm(testDir, { recursive: true, force: true });
21
- } catch {
22
- // Ignore cleanup errors
23
- }
24
- });
25
-
26
- describe('init', () => {
27
- it('should create config file with defaults', async () => {
28
- const result = init({
29
- projectRoot: testDir,
30
- name: 'test-project',
31
- });
32
-
33
- expect(result.success).toBe(true);
34
- expect(result.configPath).toBe(join(testDir, 'coreai.config.yaml'));
35
-
36
- // Verify file exists
37
- const configPath = result.configPath ?? '';
38
- const content = await fs.readFile(configPath, 'utf-8');
39
- expect(content).toContain('name: "test-project"');
40
- expect(content).toContain('type: software');
41
- });
42
-
43
- it('should create directory structure', async () => {
44
- const result = init({
45
- projectRoot: testDir,
46
- name: 'test-project',
47
- });
48
-
49
- expect(result.success).toBe(true);
50
- expect(result.createdDirs).toBeDefined();
51
- expect(result.createdDirs?.length).toBeGreaterThan(0);
52
-
53
- // Verify directories exist
54
- const coreaiDir = join(testDir, 'coreai', 'agents');
55
- const stat = await fs.stat(coreaiDir);
56
- expect(stat.isDirectory()).toBe(true);
57
- });
58
-
59
- it('should skip directory creation when skipDirs is true', async () => {
60
- const result = init({
61
- projectRoot: testDir,
62
- name: 'test-project',
63
- skipDirs: true,
64
- });
65
-
66
- expect(result.success).toBe(true);
67
- expect(result.createdDirs).toEqual([]);
68
- });
69
-
70
- it('should fail if config already exists without force', async () => {
71
- // Create existing config
72
- await fs.writeFile(join(testDir, 'coreai.config.yaml'), 'version: "1.0"');
73
-
74
- const result = init({
75
- projectRoot: testDir,
76
- name: 'test-project',
77
- });
78
-
79
- expect(result.success).toBe(false);
80
- expect(result.error).toContain('already exists');
81
- });
82
-
83
- it('should overwrite config with force option', async () => {
84
- // Create existing config
85
- await fs.writeFile(join(testDir, 'coreai.config.yaml'), 'version: "1.0"');
86
-
87
- const result = init({
88
- projectRoot: testDir,
89
- name: 'new-project',
90
- force: true,
91
- });
92
-
93
- expect(result.success).toBe(true);
94
-
95
- const configPath2 = result.configPath ?? '';
96
- const content = await fs.readFile(configPath2, 'utf-8');
97
- expect(content).toContain('name: "new-project"');
98
- });
99
-
100
- it('should use custom project type', async () => {
101
- const result = init({
102
- projectRoot: testDir,
103
- name: 'mobile-app',
104
- type: 'mobile',
105
- });
106
-
107
- expect(result.success).toBe(true);
108
-
109
- const configPath3 = result.configPath ?? '';
110
- const content = await fs.readFile(configPath3, 'utf-8');
111
- expect(content).toContain('type: mobile');
112
- });
113
-
114
- it('should detect project name from directory', async () => {
115
- const result = init({
116
- projectRoot: testDir,
117
- });
118
-
119
- expect(result.success).toBe(true);
120
-
121
- // Should use directory name as project name
122
- const configPath4 = result.configPath ?? '';
123
- const content = await fs.readFile(configPath4, 'utf-8');
124
- expect(content).toContain('name:');
125
- });
126
- });
127
-
128
- describe('formatInitResult', () => {
129
- it('should format success result', () => {
130
- const result = {
131
- success: true,
132
- configPath: '/path/to/coreai.config.yaml',
133
- createdDirs: ['/path/to/coreai/agents'],
134
- };
135
-
136
- const output = formatInitResult(result);
137
-
138
- expect(output).toContain('initialized successfully');
139
- expect(output).toContain('coreai.config.yaml');
140
- expect(output).toContain('Next steps');
141
- });
142
-
143
- it('should format error result', () => {
144
- const result = {
145
- success: false,
146
- error: 'Config already exists',
147
- };
148
-
149
- const output = formatInitResult(result);
150
-
151
- expect(output).toContain('Error');
152
- expect(output).toContain('Config already exists');
153
- });
154
-
155
- it('should show detected git info', () => {
156
- const result = {
157
- success: true,
158
- configPath: '/path/to/config.yaml',
159
- createdDirs: [],
160
- gitInfo: {
161
- provider: 'github' as const,
162
- owner: 'test-owner',
163
- repo: 'test-repo',
164
- },
165
- };
166
-
167
- const output = formatInitResult(result);
168
-
169
- expect(output).toContain('github');
170
- expect(output).toContain('test-owner/test-repo');
171
- });
172
- });
173
- });