@deimoscloud/coreai 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/.prettierrc +9 -0
  2. package/AGENT_SPEC.md +347 -0
  3. package/ARCHITECTURE.md +547 -0
  4. package/DRAFT_PRD.md +1440 -0
  5. package/IMPLEMENTATION_PLAN.md +256 -0
  6. package/PRODUCT.md +473 -0
  7. package/README.md +303 -0
  8. package/WORKFLOWS.md +295 -0
  9. package/agents/_templates/ic-engineer.md +185 -0
  10. package/agents/_templates/reviewer.md +182 -0
  11. package/agents/backend-engineer.yaml +72 -0
  12. package/agents/devops-engineer.yaml +72 -0
  13. package/agents/engineering-manager.yaml +70 -0
  14. package/agents/examples/android-engineer.md +302 -0
  15. package/agents/examples/backend-engineer.md +320 -0
  16. package/agents/examples/devops-engineer.md +742 -0
  17. package/agents/examples/engineering-manager.md +469 -0
  18. package/agents/examples/frontend-engineer.md +58 -0
  19. package/agents/examples/product-manager.md +315 -0
  20. package/agents/examples/qa-engineer.md +371 -0
  21. package/agents/examples/security-engineer.md +525 -0
  22. package/agents/examples/solutions-architect.md +351 -0
  23. package/agents/examples/wearos-engineer.md +359 -0
  24. package/agents/frontend-engineer.yaml +72 -0
  25. package/commands/core/check-inbox.md +34 -0
  26. package/commands/core/delegate.md +30 -0
  27. package/commands/core/git-commit.md +144 -0
  28. package/commands/core/pr-create.md +193 -0
  29. package/commands/core/review.md +56 -0
  30. package/commands/core/sprint-status.md +65 -0
  31. package/commands/optional/docs-update.md +200 -0
  32. package/commands/optional/jira-create.md +200 -0
  33. package/commands/optional/jira-transition.md +184 -0
  34. package/commands/optional/worktree-cleanup.md +167 -0
  35. package/commands/optional/worktree-setup.md +110 -0
  36. package/dist/cli/index.js +4037 -0
  37. package/dist/cli/index.js.map +1 -0
  38. package/dist/index.d.ts +2978 -0
  39. package/dist/index.js +3867 -0
  40. package/dist/index.js.map +1 -0
  41. package/eslint.config.js +29 -0
  42. package/jest.config.js +22 -0
  43. package/knowledge-library/README.md +118 -0
  44. package/knowledge-library/android-engineer/context/current.txt +42 -0
  45. package/knowledge-library/android-engineer/control/decisions.txt +9 -0
  46. package/knowledge-library/android-engineer/control/dependencies.txt +19 -0
  47. package/knowledge-library/android-engineer/control/objectives.txt +26 -0
  48. package/knowledge-library/android-engineer/history/.gitkeep +0 -0
  49. package/knowledge-library/android-engineer/inbox/processed/.gitkeep +0 -0
  50. package/knowledge-library/android-engineer/outbox/.gitkeep +0 -0
  51. package/knowledge-library/android-engineer/tech/.gitkeep +0 -0
  52. package/knowledge-library/architecture.txt +61 -0
  53. package/knowledge-library/backend-engineer/context/current.txt +42 -0
  54. package/knowledge-library/backend-engineer/control/decisions.txt +9 -0
  55. package/knowledge-library/backend-engineer/control/dependencies.txt +19 -0
  56. package/knowledge-library/backend-engineer/control/objectives.txt +26 -0
  57. package/knowledge-library/backend-engineer/history/.gitkeep +0 -0
  58. package/knowledge-library/backend-engineer/inbox/processed/.gitkeep +0 -0
  59. package/knowledge-library/backend-engineer/outbox/.gitkeep +0 -0
  60. package/knowledge-library/backend-engineer/tech/.gitkeep +0 -0
  61. package/knowledge-library/context.txt +52 -0
  62. package/knowledge-library/devops-engineer/context/current.txt +42 -0
  63. package/knowledge-library/devops-engineer/control/decisions.txt +9 -0
  64. package/knowledge-library/devops-engineer/control/dependencies.txt +19 -0
  65. package/knowledge-library/devops-engineer/control/objectives.txt +26 -0
  66. package/knowledge-library/devops-engineer/history/.gitkeep +0 -0
  67. package/knowledge-library/devops-engineer/inbox/processed/.gitkeep +0 -0
  68. package/knowledge-library/devops-engineer/outbox/.gitkeep +0 -0
  69. package/knowledge-library/devops-engineer/tech/.gitkeep +0 -0
  70. package/knowledge-library/engineering-manager/context/current.txt +40 -0
  71. package/knowledge-library/engineering-manager/control/decisions.txt +9 -0
  72. package/knowledge-library/engineering-manager/control/objectives.txt +27 -0
  73. package/knowledge-library/engineering-manager/history/.gitkeep +0 -0
  74. package/knowledge-library/engineering-manager/inbox/processed/.gitkeep +0 -0
  75. package/knowledge-library/engineering-manager/outbox/.gitkeep +0 -0
  76. package/knowledge-library/engineering-manager/tech/.gitkeep +0 -0
  77. package/knowledge-library/prd.txt +81 -0
  78. package/knowledge-library/product-manager/context/current.txt +42 -0
  79. package/knowledge-library/product-manager/control/decisions.txt +9 -0
  80. package/knowledge-library/product-manager/control/dependencies.txt +19 -0
  81. package/knowledge-library/product-manager/control/objectives.txt +26 -0
  82. package/knowledge-library/product-manager/history/.gitkeep +0 -0
  83. package/knowledge-library/product-manager/inbox/processed/.gitkeep +0 -0
  84. package/knowledge-library/product-manager/outbox/.gitkeep +0 -0
  85. package/knowledge-library/product-manager/tech/.gitkeep +0 -0
  86. package/knowledge-library/qa-engineer/context/current.txt +42 -0
  87. package/knowledge-library/qa-engineer/control/decisions.txt +9 -0
  88. package/knowledge-library/qa-engineer/control/dependencies.txt +19 -0
  89. package/knowledge-library/qa-engineer/control/objectives.txt +26 -0
  90. package/knowledge-library/qa-engineer/history/.gitkeep +0 -0
  91. package/knowledge-library/qa-engineer/inbox/processed/.gitkeep +0 -0
  92. package/knowledge-library/qa-engineer/outbox/.gitkeep +0 -0
  93. package/knowledge-library/qa-engineer/tech/.gitkeep +0 -0
  94. package/knowledge-library/security-engineer/context/current.txt +42 -0
  95. package/knowledge-library/security-engineer/control/decisions.txt +9 -0
  96. package/knowledge-library/security-engineer/control/dependencies.txt +19 -0
  97. package/knowledge-library/security-engineer/control/objectives.txt +26 -0
  98. package/knowledge-library/security-engineer/history/.gitkeep +0 -0
  99. package/knowledge-library/security-engineer/inbox/processed/.gitkeep +0 -0
  100. package/knowledge-library/security-engineer/outbox/.gitkeep +0 -0
  101. package/knowledge-library/security-engineer/tech/.gitkeep +0 -0
  102. package/knowledge-library/solutions-architect/context/current.txt +42 -0
  103. package/knowledge-library/solutions-architect/control/decisions.txt +9 -0
  104. package/knowledge-library/solutions-architect/control/dependencies.txt +19 -0
  105. package/knowledge-library/solutions-architect/control/objectives.txt +26 -0
  106. package/knowledge-library/solutions-architect/history/.gitkeep +0 -0
  107. package/knowledge-library/solutions-architect/inbox/processed/.gitkeep +0 -0
  108. package/knowledge-library/solutions-architect/outbox/.gitkeep +0 -0
  109. package/knowledge-library/solutions-architect/tech/.gitkeep +0 -0
  110. package/knowledge-library/wearos-engineer/context/current.txt +42 -0
  111. package/knowledge-library/wearos-engineer/control/decisions.txt +9 -0
  112. package/knowledge-library/wearos-engineer/control/dependencies.txt +19 -0
  113. package/knowledge-library/wearos-engineer/control/objectives.txt +26 -0
  114. package/knowledge-library/wearos-engineer/history/.gitkeep +0 -0
  115. package/knowledge-library/wearos-engineer/inbox/processed/.gitkeep +0 -0
  116. package/knowledge-library/wearos-engineer/outbox/.gitkeep +0 -0
  117. package/knowledge-library/wearos-engineer/tech/.gitkeep +0 -0
  118. package/package.json +66 -0
  119. package/schemas/agent.schema.json +171 -0
  120. package/schemas/coreai.config.schema.json +257 -0
  121. package/scripts/add-agent.sh +323 -0
  122. package/scripts/install.sh +354 -0
  123. package/src/adapters/factory.test.ts +386 -0
  124. package/src/adapters/factory.ts +305 -0
  125. package/src/adapters/index.ts +113 -0
  126. package/src/adapters/interfaces.ts +268 -0
  127. package/src/adapters/mcp/client.test.ts +130 -0
  128. package/src/adapters/mcp/client.ts +451 -0
  129. package/src/adapters/mcp/discovery.test.ts +315 -0
  130. package/src/adapters/mcp/discovery.ts +340 -0
  131. package/src/adapters/mcp/index.ts +66 -0
  132. package/src/adapters/mcp/mapper.test.ts +218 -0
  133. package/src/adapters/mcp/mapper.ts +536 -0
  134. package/src/adapters/mcp/registry.test.ts +433 -0
  135. package/src/adapters/mcp/registry.ts +550 -0
  136. package/src/adapters/mcp/types.ts +258 -0
  137. package/src/adapters/native/filesystem.test.ts +350 -0
  138. package/src/adapters/native/filesystem.ts +393 -0
  139. package/src/adapters/native/github.test.ts +173 -0
  140. package/src/adapters/native/github.ts +627 -0
  141. package/src/adapters/native/index.ts +22 -0
  142. package/src/adapters/native/selector.test.ts +224 -0
  143. package/src/adapters/native/selector.ts +150 -0
  144. package/src/adapters/types.ts +270 -0
  145. package/src/agents/compiler.test.ts +399 -0
  146. package/src/agents/compiler.ts +359 -0
  147. package/src/agents/index.ts +36 -0
  148. package/src/agents/loader.test.ts +319 -0
  149. package/src/agents/loader.ts +143 -0
  150. package/src/agents/resolver.test.ts +282 -0
  151. package/src/agents/resolver.ts +262 -0
  152. package/src/agents/types.ts +87 -0
  153. package/src/cache/index.ts +38 -0
  154. package/src/cache/interfaces.ts +283 -0
  155. package/src/cache/manager.test.ts +266 -0
  156. package/src/cache/manager.ts +388 -0
  157. package/src/cache/provider.test.ts +485 -0
  158. package/src/cache/provider.ts +745 -0
  159. package/src/cache/types.test.ts +192 -0
  160. package/src/cache/types.ts +313 -0
  161. package/src/cli/commands/build.test.ts +248 -0
  162. package/src/cli/commands/build.ts +244 -0
  163. package/src/cli/commands/cache.test.ts +221 -0
  164. package/src/cli/commands/cache.ts +229 -0
  165. package/src/cli/commands/index.ts +63 -0
  166. package/src/cli/commands/init.test.ts +173 -0
  167. package/src/cli/commands/init.ts +296 -0
  168. package/src/cli/commands/skills.test.ts +272 -0
  169. package/src/cli/commands/skills.ts +348 -0
  170. package/src/cli/commands/status.test.ts +392 -0
  171. package/src/cli/commands/status.ts +332 -0
  172. package/src/cli/commands/sync.test.ts +213 -0
  173. package/src/cli/commands/sync.ts +251 -0
  174. package/src/cli/commands/validate.test.ts +216 -0
  175. package/src/cli/commands/validate.ts +340 -0
  176. package/src/cli/index.test.ts +190 -0
  177. package/src/cli/index.ts +493 -0
  178. package/src/commands/context.test.ts +163 -0
  179. package/src/commands/context.ts +111 -0
  180. package/src/commands/index.ts +56 -0
  181. package/src/commands/loader.test.ts +273 -0
  182. package/src/commands/loader.ts +355 -0
  183. package/src/commands/registry.test.ts +384 -0
  184. package/src/commands/registry.ts +248 -0
  185. package/src/commands/runner.test.ts +297 -0
  186. package/src/commands/runner.ts +222 -0
  187. package/src/commands/types.ts +361 -0
  188. package/src/config/index.ts +19 -0
  189. package/src/config/loader.test.ts +262 -0
  190. package/src/config/loader.ts +188 -0
  191. package/src/config/types.ts +154 -0
  192. package/src/context/index.ts +14 -0
  193. package/src/context/loader.test.ts +334 -0
  194. package/src/context/loader.ts +357 -0
  195. package/src/index.test.ts +13 -0
  196. package/src/index.ts +244 -0
  197. package/src/knowledge-library/index.ts +44 -0
  198. package/src/knowledge-library/manager.test.ts +536 -0
  199. package/src/knowledge-library/manager.ts +804 -0
  200. package/src/knowledge-library/types.ts +432 -0
  201. package/src/skills/generator.test.ts +602 -0
  202. package/src/skills/generator.ts +491 -0
  203. package/src/skills/index.ts +27 -0
  204. package/src/skills/templates.ts +520 -0
  205. package/src/skills/types.ts +251 -0
  206. package/templates/completion-report.md +72 -0
  207. package/templates/feedback.md +56 -0
  208. package/templates/project-files/CLAUDE.md.template +109 -0
  209. package/templates/project-files/coreai.json.example +47 -0
  210. package/templates/project-files/mcp.json.template +20 -0
  211. package/templates/review-complete.md +64 -0
  212. package/templates/review-request.md +67 -0
  213. package/templates/task-assignment.md +51 -0
  214. package/tsconfig.build.json +4 -0
  215. package/tsconfig.json +26 -0
  216. package/tsup.config.ts +23 -0
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Cache Types Tests
3
+ */
4
+
5
+ import { CacheError, CACHE_PATHS, DEFAULT_CACHE_CONFIG } from './types.js';
6
+ import type {
7
+ CacheSource,
8
+ CacheStatus,
9
+ CacheMetadata,
10
+ CacheEntry,
11
+ CacheOptions,
12
+ CacheListOptions,
13
+ CacheStats,
14
+ SyncResult,
15
+ } from './types.js';
16
+
17
+ describe('CacheError', () => {
18
+ it('should create error with message and code', () => {
19
+ const error = new CacheError('Entry not found', 'not_found');
20
+ expect(error.message).toBe('Entry not found');
21
+ expect(error.code).toBe('not_found');
22
+ expect(error.name).toBe('CacheError');
23
+ });
24
+
25
+ it('should create error with key', () => {
26
+ const error = new CacheError('Entry not found', 'not_found', 'test-key');
27
+ expect(error.key).toBe('test-key');
28
+ });
29
+
30
+ it('should create error with cause', () => {
31
+ const cause = new Error('Original error');
32
+ const error = new CacheError('Wrapped error', 'read_failed', undefined, cause);
33
+ expect(error.cause).toBe(cause);
34
+ });
35
+
36
+ it('should be instanceof Error', () => {
37
+ const error = new CacheError('Test', 'not_found');
38
+ expect(error).toBeInstanceOf(Error);
39
+ expect(error).toBeInstanceOf(CacheError);
40
+ });
41
+ });
42
+
43
+ describe('CACHE_PATHS', () => {
44
+ it('should define root path', () => {
45
+ expect(CACHE_PATHS.ROOT).toBe('.coreai/cache');
46
+ });
47
+
48
+ it('should define content path', () => {
49
+ expect(CACHE_PATHS.CONTENT).toBe('.coreai/cache/content');
50
+ });
51
+
52
+ it('should define metadata path', () => {
53
+ expect(CACHE_PATHS.METADATA).toBe('.coreai/cache/metadata');
54
+ });
55
+
56
+ it('should define index path', () => {
57
+ expect(CACHE_PATHS.INDEX).toBe('.coreai/cache/index.json');
58
+ });
59
+
60
+ it('should define lock path', () => {
61
+ expect(CACHE_PATHS.LOCK).toBe('.coreai/cache/.lock');
62
+ });
63
+ });
64
+
65
+ describe('DEFAULT_CACHE_CONFIG', () => {
66
+ it('should have default TTL of 1 hour', () => {
67
+ expect(DEFAULT_CACHE_CONFIG.ttl).toBe(3600);
68
+ });
69
+
70
+ it('should have default max size of 100MB', () => {
71
+ expect(DEFAULT_CACHE_CONFIG.maxSize).toBe(100 * 1024 * 1024);
72
+ });
73
+
74
+ it('should have default max entries of 1000', () => {
75
+ expect(DEFAULT_CACHE_CONFIG.maxEntries).toBe(1000);
76
+ });
77
+
78
+ it('should enable auto cleanup by default', () => {
79
+ expect(DEFAULT_CACHE_CONFIG.autoCleanup).toBe(true);
80
+ });
81
+
82
+ it('should have cleanup interval of 1 hour', () => {
83
+ expect(DEFAULT_CACHE_CONFIG.cleanupInterval).toBe(3600);
84
+ });
85
+ });
86
+
87
+ describe('Type shapes', () => {
88
+ it('should accept valid CacheSource values', () => {
89
+ const sources: CacheSource[] = ['confluence', 'github', 'notion', 'local', 'custom'];
90
+ expect(sources).toHaveLength(5);
91
+ });
92
+
93
+ it('should accept valid CacheStatus values', () => {
94
+ const statuses: CacheStatus[] = ['valid', 'stale', 'expired', 'error'];
95
+ expect(statuses).toHaveLength(4);
96
+ });
97
+
98
+ it('should create valid CacheMetadata', () => {
99
+ const metadata: CacheMetadata = {
100
+ key: 'test-key',
101
+ source: 'confluence',
102
+ sourceUrl: 'https://example.com/page',
103
+ cachedAt: new Date().toISOString(),
104
+ expiresAt: new Date(Date.now() + 3600000).toISOString(),
105
+ contentHash: 'abc123',
106
+ size: 1024,
107
+ contentType: 'text/markdown',
108
+ };
109
+
110
+ expect(metadata.key).toBe('test-key');
111
+ expect(metadata.source).toBe('confluence');
112
+ });
113
+
114
+ it('should create valid CacheEntry', () => {
115
+ const entry: CacheEntry = {
116
+ metadata: {
117
+ key: 'test-key',
118
+ source: 'github',
119
+ sourceUrl: 'https://github.com/owner/repo',
120
+ cachedAt: new Date().toISOString(),
121
+ expiresAt: new Date(Date.now() + 3600000).toISOString(),
122
+ contentHash: 'def456',
123
+ size: 2048,
124
+ contentType: 'text/markdown',
125
+ },
126
+ content: '# Test Content',
127
+ };
128
+
129
+ expect(entry.metadata.key).toBe('test-key');
130
+ expect(entry.content).toBe('# Test Content');
131
+ });
132
+
133
+ it('should create valid CacheOptions', () => {
134
+ const options: CacheOptions = {
135
+ ttl: 7200,
136
+ forceRefresh: false,
137
+ skipCache: false,
138
+ tags: ['docs', 'architecture'],
139
+ };
140
+
141
+ expect(options.ttl).toBe(7200);
142
+ expect(options.tags).toHaveLength(2);
143
+ });
144
+
145
+ it('should create valid CacheListOptions', () => {
146
+ const options: CacheListOptions = {
147
+ source: 'confluence',
148
+ tag: 'docs',
149
+ status: 'valid',
150
+ limit: 10,
151
+ };
152
+
153
+ expect(options.source).toBe('confluence');
154
+ expect(options.limit).toBe(10);
155
+ });
156
+
157
+ it('should create valid CacheStats', () => {
158
+ const stats: CacheStats = {
159
+ totalEntries: 100,
160
+ totalSize: 1024 * 1024,
161
+ validEntries: 80,
162
+ staleEntries: 15,
163
+ expiredEntries: 5,
164
+ bySource: {
165
+ confluence: 50,
166
+ github: 30,
167
+ notion: 10,
168
+ local: 10,
169
+ custom: 0,
170
+ },
171
+ oldestEntry: new Date(Date.now() - 86400000).toISOString(),
172
+ newestEntry: new Date().toISOString(),
173
+ };
174
+
175
+ expect(stats.totalEntries).toBe(100);
176
+ expect(stats.bySource.confluence).toBe(50);
177
+ });
178
+
179
+ it('should create valid SyncResult', () => {
180
+ const result: SyncResult = {
181
+ added: 5,
182
+ updated: 10,
183
+ removed: 2,
184
+ failed: 1,
185
+ errors: [{ key: 'failed-key', error: 'Network error' }],
186
+ duration: 5000,
187
+ };
188
+
189
+ expect(result.added).toBe(5);
190
+ expect(result.errors).toHaveLength(1);
191
+ });
192
+ });
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Cache Types
3
+ *
4
+ * Type definitions for the shared context cache system.
5
+ */
6
+
7
+ /**
8
+ * Source type for cached content
9
+ */
10
+ export type CacheSource = 'confluence' | 'github' | 'notion' | 'local' | 'custom';
11
+
12
+ /**
13
+ * Cache entry status
14
+ */
15
+ export type CacheStatus = 'valid' | 'stale' | 'expired' | 'error';
16
+
17
+ /**
18
+ * Metadata for a cached entry
19
+ */
20
+ export interface CacheMetadata {
21
+ /**
22
+ * Unique key for this cache entry
23
+ */
24
+ key: string;
25
+
26
+ /**
27
+ * Source provider (e.g., 'confluence', 'github')
28
+ */
29
+ source: CacheSource;
30
+
31
+ /**
32
+ * Original source URL or identifier
33
+ */
34
+ sourceUrl: string;
35
+
36
+ /**
37
+ * When the content was cached
38
+ */
39
+ cachedAt: string;
40
+
41
+ /**
42
+ * When the content expires (ISO date string)
43
+ */
44
+ expiresAt: string;
45
+
46
+ /**
47
+ * ETag or version hash from source (for conditional fetching)
48
+ */
49
+ etag?: string;
50
+
51
+ /**
52
+ * Content hash for integrity checking
53
+ */
54
+ contentHash: string;
55
+
56
+ /**
57
+ * Size in bytes
58
+ */
59
+ size: number;
60
+
61
+ /**
62
+ * Content type (e.g., 'text/markdown', 'application/json')
63
+ */
64
+ contentType: string;
65
+
66
+ /**
67
+ * Original title or name
68
+ */
69
+ title?: string;
70
+
71
+ /**
72
+ * Last modified timestamp from source
73
+ */
74
+ lastModified?: string;
75
+
76
+ /**
77
+ * Custom tags for categorization
78
+ */
79
+ tags?: string[];
80
+ }
81
+
82
+ /**
83
+ * A cached content entry
84
+ */
85
+ export interface CacheEntry<T = string> {
86
+ /**
87
+ * Entry metadata
88
+ */
89
+ metadata: CacheMetadata;
90
+
91
+ /**
92
+ * The cached content
93
+ */
94
+ content: T;
95
+ }
96
+
97
+ /**
98
+ * Options for cache operations
99
+ */
100
+ export interface CacheOptions {
101
+ /**
102
+ * Time-to-live in seconds (default: 3600 = 1 hour)
103
+ */
104
+ ttl?: number;
105
+
106
+ /**
107
+ * Force refresh even if cached
108
+ */
109
+ forceRefresh?: boolean;
110
+
111
+ /**
112
+ * Skip cache and fetch directly
113
+ */
114
+ skipCache?: boolean;
115
+
116
+ /**
117
+ * Custom tags to apply
118
+ */
119
+ tags?: string[];
120
+ }
121
+
122
+ /**
123
+ * Options for listing cache entries
124
+ */
125
+ export interface CacheListOptions {
126
+ /**
127
+ * Filter by source
128
+ */
129
+ source?: CacheSource;
130
+
131
+ /**
132
+ * Filter by tag
133
+ */
134
+ tag?: string;
135
+
136
+ /**
137
+ * Filter by status
138
+ */
139
+ status?: CacheStatus;
140
+
141
+ /**
142
+ * Maximum entries to return
143
+ */
144
+ limit?: number;
145
+ }
146
+
147
+ /**
148
+ * Cache statistics
149
+ */
150
+ export interface CacheStats {
151
+ /**
152
+ * Total number of entries
153
+ */
154
+ totalEntries: number;
155
+
156
+ /**
157
+ * Total size in bytes
158
+ */
159
+ totalSize: number;
160
+
161
+ /**
162
+ * Number of valid entries
163
+ */
164
+ validEntries: number;
165
+
166
+ /**
167
+ * Number of stale entries
168
+ */
169
+ staleEntries: number;
170
+
171
+ /**
172
+ * Number of expired entries
173
+ */
174
+ expiredEntries: number;
175
+
176
+ /**
177
+ * Entries by source
178
+ */
179
+ bySource: Record<CacheSource, number>;
180
+
181
+ /**
182
+ * Oldest entry timestamp
183
+ */
184
+ oldestEntry?: string;
185
+
186
+ /**
187
+ * Newest entry timestamp
188
+ */
189
+ newestEntry?: string;
190
+ }
191
+
192
+ /**
193
+ * Result of a sync operation
194
+ */
195
+ export interface SyncResult {
196
+ /**
197
+ * Number of entries added
198
+ */
199
+ added: number;
200
+
201
+ /**
202
+ * Number of entries updated
203
+ */
204
+ updated: number;
205
+
206
+ /**
207
+ * Number of entries removed
208
+ */
209
+ removed: number;
210
+
211
+ /**
212
+ * Number of entries that failed to sync
213
+ */
214
+ failed: number;
215
+
216
+ /**
217
+ * Error messages for failed entries
218
+ */
219
+ errors: { key: string; error: string }[];
220
+
221
+ /**
222
+ * Duration of sync in milliseconds
223
+ */
224
+ duration: number;
225
+ }
226
+
227
+ /**
228
+ * Cache error codes
229
+ */
230
+ export type CacheErrorCode =
231
+ | 'not_found'
232
+ | 'expired'
233
+ | 'invalid_key'
234
+ | 'write_failed'
235
+ | 'read_failed'
236
+ | 'fetch_failed'
237
+ | 'invalid_config'
238
+ | 'storage_full';
239
+
240
+ /**
241
+ * Cache-specific error
242
+ */
243
+ export class CacheError extends Error {
244
+ constructor(
245
+ message: string,
246
+ public readonly code: CacheErrorCode,
247
+ public readonly key?: string,
248
+ public override readonly cause?: Error
249
+ ) {
250
+ super(message);
251
+ this.name = 'CacheError';
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Default cache directory paths
257
+ */
258
+ export const CACHE_PATHS = {
259
+ /**
260
+ * Root cache directory (relative to project root)
261
+ */
262
+ ROOT: '.coreai/cache',
263
+
264
+ /**
265
+ * Content storage directory
266
+ */
267
+ CONTENT: '.coreai/cache/content',
268
+
269
+ /**
270
+ * Metadata storage directory
271
+ */
272
+ METADATA: '.coreai/cache/metadata',
273
+
274
+ /**
275
+ * Index file for fast lookups
276
+ */
277
+ INDEX: '.coreai/cache/index.json',
278
+
279
+ /**
280
+ * Lock file for concurrent access
281
+ */
282
+ LOCK: '.coreai/cache/.lock',
283
+ } as const;
284
+
285
+ /**
286
+ * Default cache configuration
287
+ */
288
+ export const DEFAULT_CACHE_CONFIG = {
289
+ /**
290
+ * Default TTL in seconds (1 hour)
291
+ */
292
+ ttl: 3600,
293
+
294
+ /**
295
+ * Maximum cache size in bytes (100MB)
296
+ */
297
+ maxSize: 100 * 1024 * 1024,
298
+
299
+ /**
300
+ * Maximum number of entries
301
+ */
302
+ maxEntries: 1000,
303
+
304
+ /**
305
+ * Enable automatic cleanup of expired entries
306
+ */
307
+ autoCleanup: true,
308
+
309
+ /**
310
+ * Cleanup interval in seconds (1 hour)
311
+ */
312
+ cleanupInterval: 3600,
313
+ } as const;