@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,392 @@
1
+ /**
2
+ * Status Command Tests
3
+ */
4
+
5
+ import { promises as fs } from 'fs';
6
+ import { join } from 'path';
7
+ import { tmpdir } from 'os';
8
+ import { status, formatStatusResult, formatStatusSummary } from './status.js';
9
+ import {
10
+ initKnowledgeLibrary,
11
+ initAgentKnowledgeLibrary,
12
+ writeInboxMessage,
13
+ updateAgentContext,
14
+ } from '../../knowledge-library/index.js';
15
+
16
+ describe('Status Command', () => {
17
+ let testDir: string;
18
+
19
+ beforeEach(async () => {
20
+ testDir = join(
21
+ tmpdir(),
22
+ `status-cmd-test-${Date.now()}-${Math.random().toString(36).slice(2)}`
23
+ );
24
+ await fs.mkdir(testDir, { recursive: true });
25
+ });
26
+
27
+ afterEach(async () => {
28
+ try {
29
+ await fs.rm(testDir, { recursive: true, force: true });
30
+ } catch {
31
+ // Ignore cleanup errors
32
+ }
33
+ });
34
+
35
+ describe('status', () => {
36
+ it('should warn when KnowledgeLibrary not initialized', () => {
37
+ const result = status({ projectRoot: testDir });
38
+
39
+ expect(result.success).toBe(true);
40
+ expect(result.agents).toEqual([]);
41
+ expect(result.warnings).toBeDefined();
42
+ expect(result.warnings?.some((w) => w.includes('not initialized'))).toBe(true);
43
+ });
44
+
45
+ it('should initialize KnowledgeLibrary with init option', () => {
46
+ const result = status({ projectRoot: testDir, init: true });
47
+
48
+ expect(result.success).toBe(true);
49
+ expect(result.knowledgeLibrary).toBeDefined();
50
+ });
51
+
52
+ it('should show agents from KnowledgeLibrary', () => {
53
+ initKnowledgeLibrary({ projectRoot: testDir });
54
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
55
+ initAgentKnowledgeLibrary('frontend-engineer', { projectRoot: testDir });
56
+
57
+ const result = status({ projectRoot: testDir });
58
+
59
+ expect(result.success).toBe(true);
60
+ expect(result.agents.length).toBe(2);
61
+ expect(result.agents.map((a) => a.name)).toContain('backend-engineer');
62
+ expect(result.agents.map((a) => a.name)).toContain('frontend-engineer');
63
+ });
64
+
65
+ it('should show agents from config', async () => {
66
+ // Create config with agents
67
+ const configContent = `
68
+ version: "1.0"
69
+ project:
70
+ name: test-project
71
+ team:
72
+ agents:
73
+ - backend-engineer
74
+ - qa-engineer
75
+ `;
76
+ await fs.writeFile(join(testDir, 'coreai.config.yaml'), configContent);
77
+
78
+ initKnowledgeLibrary({ projectRoot: testDir });
79
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
80
+
81
+ const result = status({ projectRoot: testDir });
82
+
83
+ expect(result.success).toBe(true);
84
+ // Should include both configured and initialized agents
85
+ expect(result.agents.map((a) => a.name)).toContain('backend-engineer');
86
+ expect(result.agents.map((a) => a.name)).toContain('qa-engineer');
87
+ });
88
+
89
+ it('should show status for specific agent', () => {
90
+ initKnowledgeLibrary({ projectRoot: testDir });
91
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
92
+ initAgentKnowledgeLibrary('frontend-engineer', { projectRoot: testDir });
93
+
94
+ const result = status({ projectRoot: testDir, agent: 'backend-engineer' });
95
+
96
+ expect(result.success).toBe(true);
97
+ expect(result.agents.length).toBe(1);
98
+ expect(result.agents[0]?.name).toBe('backend-engineer');
99
+ });
100
+
101
+ it('should show pending message count', () => {
102
+ initKnowledgeLibrary({ projectRoot: testDir });
103
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
104
+ initAgentKnowledgeLibrary('em', { projectRoot: testDir });
105
+
106
+ writeInboxMessage({
107
+ projectRoot: testDir,
108
+ type: 'task-assignment',
109
+ from: 'em',
110
+ to: 'backend-engineer',
111
+ subject: 'Task 1',
112
+ body: 'Body 1',
113
+ });
114
+
115
+ writeInboxMessage({
116
+ projectRoot: testDir,
117
+ type: 'task-assignment',
118
+ from: 'em',
119
+ to: 'backend-engineer',
120
+ subject: 'Task 2',
121
+ body: 'Body 2',
122
+ });
123
+
124
+ const result = status({ projectRoot: testDir });
125
+
126
+ expect(result.success).toBe(true);
127
+ const beAgent = result.agents.find((a) => a.name === 'backend-engineer');
128
+ expect(beAgent?.pendingMessages).toBe(2);
129
+ });
130
+
131
+ it('should show agent context', () => {
132
+ initKnowledgeLibrary({ projectRoot: testDir });
133
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
134
+
135
+ updateAgentContext(
136
+ 'backend-engineer',
137
+ {
138
+ status: 'working',
139
+ currentTask: 'Implementing feature X',
140
+ currentTicket: 'PROJ-123',
141
+ },
142
+ { projectRoot: testDir }
143
+ );
144
+
145
+ const result = status({ projectRoot: testDir });
146
+
147
+ expect(result.success).toBe(true);
148
+ const beAgent = result.agents.find((a) => a.name === 'backend-engineer');
149
+ expect(beAgent?.status).toBe('working');
150
+ expect(beAgent?.currentTask).toBe('Implementing feature X');
151
+ expect(beAgent?.currentTicket).toBe('PROJ-123');
152
+ });
153
+
154
+ it('should include message details in detailed mode', () => {
155
+ initKnowledgeLibrary({ projectRoot: testDir });
156
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
157
+ initAgentKnowledgeLibrary('em', { projectRoot: testDir });
158
+
159
+ writeInboxMessage({
160
+ projectRoot: testDir,
161
+ type: 'task-assignment',
162
+ from: 'em',
163
+ to: 'backend-engineer',
164
+ subject: 'Implement Feature X',
165
+ body: 'Details',
166
+ });
167
+
168
+ const result = status({ projectRoot: testDir, detailed: true });
169
+
170
+ expect(result.success).toBe(true);
171
+ const beAgent = result.agents.find((a) => a.name === 'backend-engineer');
172
+ expect(beAgent?.messageDetails).toBeDefined();
173
+ expect(beAgent?.messageDetails?.length).toBe(1);
174
+ expect(beAgent?.messageDetails?.[0]?.type).toBe('task-assignment');
175
+ expect(beAgent?.messageDetails?.[0]?.from).toBe('em');
176
+ });
177
+
178
+ it('should sort agents by pending messages', () => {
179
+ initKnowledgeLibrary({ projectRoot: testDir });
180
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
181
+ initAgentKnowledgeLibrary('frontend-engineer', { projectRoot: testDir });
182
+ initAgentKnowledgeLibrary('em', { projectRoot: testDir });
183
+
184
+ // frontend-engineer gets more messages
185
+ writeInboxMessage({
186
+ projectRoot: testDir,
187
+ type: 'task-assignment',
188
+ from: 'em',
189
+ to: 'frontend-engineer',
190
+ subject: 'Task 1',
191
+ body: 'Body',
192
+ });
193
+ writeInboxMessage({
194
+ projectRoot: testDir,
195
+ type: 'task-assignment',
196
+ from: 'em',
197
+ to: 'frontend-engineer',
198
+ subject: 'Task 2',
199
+ body: 'Body',
200
+ });
201
+
202
+ // backend-engineer gets one message
203
+ writeInboxMessage({
204
+ projectRoot: testDir,
205
+ type: 'task-assignment',
206
+ from: 'em',
207
+ to: 'backend-engineer',
208
+ subject: 'Task 1',
209
+ body: 'Body',
210
+ });
211
+
212
+ const result = status({ projectRoot: testDir });
213
+
214
+ expect(result.success).toBe(true);
215
+ // frontend-engineer should be first (2 messages)
216
+ expect(result.agents[0]?.name).toBe('frontend-engineer');
217
+ expect(result.agents[0]?.pendingMessages).toBe(2);
218
+ });
219
+
220
+ it('should show uninitialized agents from config', async () => {
221
+ const configContent = `
222
+ version: "1.0"
223
+ project:
224
+ name: test-project
225
+ team:
226
+ agents:
227
+ - backend-engineer
228
+ - qa-engineer
229
+ `;
230
+ await fs.writeFile(join(testDir, 'coreai.config.yaml'), configContent);
231
+
232
+ initKnowledgeLibrary({ projectRoot: testDir });
233
+ // Don't initialize any agents
234
+
235
+ const result = status({ projectRoot: testDir });
236
+
237
+ expect(result.success).toBe(true);
238
+ expect(result.agents.length).toBe(2);
239
+ expect(result.agents.every((a) => !a.initialized)).toBe(true);
240
+ });
241
+ });
242
+
243
+ describe('formatStatusResult', () => {
244
+ it('should format empty result', () => {
245
+ const result = status({ projectRoot: testDir, init: true });
246
+ const output = formatStatusResult(result);
247
+
248
+ expect(output).toContain('No agents found');
249
+ });
250
+
251
+ it('should format agents with pending messages', () => {
252
+ initKnowledgeLibrary({ projectRoot: testDir });
253
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
254
+ initAgentKnowledgeLibrary('em', { projectRoot: testDir });
255
+
256
+ writeInboxMessage({
257
+ projectRoot: testDir,
258
+ type: 'task-assignment',
259
+ from: 'em',
260
+ to: 'backend-engineer',
261
+ subject: 'Test Task',
262
+ body: 'Body',
263
+ });
264
+
265
+ const result = status({ projectRoot: testDir });
266
+ const output = formatStatusResult(result);
267
+
268
+ expect(output).toContain('backend-engineer');
269
+ expect(output).toContain('Pending messages: 1');
270
+ });
271
+
272
+ it('should format agents with current task', () => {
273
+ initKnowledgeLibrary({ projectRoot: testDir });
274
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
275
+
276
+ updateAgentContext(
277
+ 'backend-engineer',
278
+ {
279
+ status: 'working',
280
+ currentTask: 'Implementing feature X',
281
+ },
282
+ { projectRoot: testDir }
283
+ );
284
+
285
+ const result = status({ projectRoot: testDir });
286
+ const output = formatStatusResult(result);
287
+
288
+ expect(output).toContain('backend-engineer');
289
+ expect(output).toContain('Status: working');
290
+ expect(output).toContain('Implementing feature X');
291
+ });
292
+
293
+ it('should show error result', () => {
294
+ const result = {
295
+ success: false,
296
+ agents: [],
297
+ error: 'Something went wrong',
298
+ };
299
+
300
+ const output = formatStatusResult(result);
301
+ expect(output).toContain('Error');
302
+ expect(output).toContain('Something went wrong');
303
+ });
304
+
305
+ it('should show warnings', () => {
306
+ const result = {
307
+ success: true,
308
+ agents: [],
309
+ warnings: ['Warning 1', 'Warning 2'],
310
+ };
311
+
312
+ const output = formatStatusResult(result);
313
+ expect(output).toContain('Warning 1');
314
+ expect(output).toContain('Warning 2');
315
+ });
316
+
317
+ it('should show summary counts', () => {
318
+ initKnowledgeLibrary({ projectRoot: testDir });
319
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
320
+ initAgentKnowledgeLibrary('frontend-engineer', { projectRoot: testDir });
321
+
322
+ updateAgentContext('backend-engineer', { status: 'working' }, { projectRoot: testDir });
323
+
324
+ const result = status({ projectRoot: testDir });
325
+ const output = formatStatusResult(result);
326
+
327
+ expect(output).toContain('Total agents: 2');
328
+ expect(output).toContain('Active: 1');
329
+ });
330
+
331
+ it('should show message details in detailed mode', () => {
332
+ initKnowledgeLibrary({ projectRoot: testDir });
333
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
334
+ initAgentKnowledgeLibrary('em', { projectRoot: testDir });
335
+
336
+ writeInboxMessage({
337
+ projectRoot: testDir,
338
+ type: 'task-assignment',
339
+ from: 'em',
340
+ to: 'backend-engineer',
341
+ subject: 'Implement Feature X',
342
+ body: 'Details',
343
+ });
344
+
345
+ const result = status({ projectRoot: testDir, detailed: true });
346
+ const output = formatStatusResult(result);
347
+
348
+ expect(output).toContain('task-assignment');
349
+ expect(output).toContain('from em');
350
+ expect(output).toContain('Implement Feature X');
351
+ });
352
+ });
353
+
354
+ describe('formatStatusSummary', () => {
355
+ it('should format compact summary', () => {
356
+ initKnowledgeLibrary({ projectRoot: testDir });
357
+ initAgentKnowledgeLibrary('backend-engineer', { projectRoot: testDir });
358
+ initAgentKnowledgeLibrary('frontend-engineer', { projectRoot: testDir });
359
+ initAgentKnowledgeLibrary('em', { projectRoot: testDir });
360
+
361
+ updateAgentContext('backend-engineer', { status: 'working' }, { projectRoot: testDir });
362
+
363
+ writeInboxMessage({
364
+ projectRoot: testDir,
365
+ type: 'task-assignment',
366
+ from: 'em',
367
+ to: 'frontend-engineer',
368
+ subject: 'Task',
369
+ body: 'Body',
370
+ });
371
+
372
+ const result = status({ projectRoot: testDir });
373
+ const summary = formatStatusSummary(result);
374
+
375
+ expect(summary).toContain('3 agents');
376
+ expect(summary).toContain('1 active');
377
+ expect(summary).toContain('1 pending messages');
378
+ });
379
+
380
+ it('should format error', () => {
381
+ const result = {
382
+ success: false,
383
+ agents: [],
384
+ error: 'Something went wrong',
385
+ };
386
+
387
+ const summary = formatStatusSummary(result);
388
+ expect(summary).toContain('Error');
389
+ expect(summary).toContain('Something went wrong');
390
+ });
391
+ });
392
+ });