crewly 1.0.0 → 1.0.2

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 (185) hide show
  1. package/config/constants.ts +40 -2
  2. package/config/skills/_common/lib.sh +2 -1
  3. package/config/skills/orchestrator/schedule-check/execute.sh +1 -1
  4. package/config/skills/orchestrator/send-pdf-to-slack/execute.sh +28 -5
  5. package/config/skills/orchestrator/send-pdf-to-slack/instructions.md +49 -10
  6. package/config/skills/orchestrator/send-pdf-to-slack/skill.json +1 -1
  7. package/config/skills/orchestrator/subscribe-event/execute.sh +2 -2
  8. package/dist/backend/backend/src/constants.d.ts +24 -2
  9. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  10. package/dist/backend/backend/src/constants.js +13 -3
  11. package/dist/backend/backend/src/constants.js.map +1 -1
  12. package/dist/backend/backend/src/controllers/session/session.controller.d.ts.map +1 -1
  13. package/dist/backend/backend/src/controllers/session/session.controller.js +16 -7
  14. package/dist/backend/backend/src/controllers/session/session.controller.js.map +1 -1
  15. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  16. package/dist/backend/backend/src/controllers/team/team.controller.js +27 -0
  17. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  18. package/dist/backend/backend/src/index.d.ts +7 -0
  19. package/dist/backend/backend/src/index.d.ts.map +1 -1
  20. package/dist/backend/backend/src/index.js +131 -0
  21. package/dist/backend/backend/src/index.js.map +1 -1
  22. package/dist/backend/backend/src/middleware/agent-heartbeat.middleware.d.ts +3 -2
  23. package/dist/backend/backend/src/middleware/agent-heartbeat.middleware.d.ts.map +1 -1
  24. package/dist/backend/backend/src/middleware/agent-heartbeat.middleware.js +8 -2
  25. package/dist/backend/backend/src/middleware/agent-heartbeat.middleware.js.map +1 -1
  26. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.d.ts +185 -0
  27. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.d.ts.map +1 -0
  28. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.js +508 -0
  29. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.js.map +1 -0
  30. package/dist/backend/backend/src/services/agent/agent-heartbeat.service.d.ts +5 -5
  31. package/dist/backend/backend/src/services/agent/agent-heartbeat.service.d.ts.map +1 -1
  32. package/dist/backend/backend/src/services/agent/agent-heartbeat.service.js +3 -3
  33. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  34. package/dist/backend/backend/src/services/agent/agent-registration.service.js +39 -13
  35. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  36. package/dist/backend/backend/src/services/agent/disk-cleanup.service.d.ts +24 -3
  37. package/dist/backend/backend/src/services/agent/disk-cleanup.service.d.ts.map +1 -1
  38. package/dist/backend/backend/src/services/agent/disk-cleanup.service.js +15 -3
  39. package/dist/backend/backend/src/services/agent/disk-cleanup.service.js.map +1 -1
  40. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  41. package/dist/backend/backend/src/services/agent/idle-detection.service.js +18 -0
  42. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  43. package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.d.ts +7 -2
  44. package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.d.ts.map +1 -1
  45. package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.js +11 -3
  46. package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.js.map +1 -1
  47. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts +42 -0
  48. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
  49. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +190 -1
  50. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
  51. package/dist/backend/backend/src/services/agent/tmux.service.js +2 -2
  52. package/dist/backend/backend/src/services/agent/tmux.service.js.map +1 -1
  53. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.d.ts +28 -4
  54. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.d.ts.map +1 -1
  55. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js +74 -7
  56. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js.map +1 -1
  57. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  58. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +13 -19
  59. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  60. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts +129 -0
  61. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts.map +1 -0
  62. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js +253 -0
  63. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js.map +1 -0
  64. package/dist/backend/backend/src/services/session/pty/pty-session-backend.d.ts.map +1 -1
  65. package/dist/backend/backend/src/services/session/pty/pty-session-backend.js +5 -1
  66. package/dist/backend/backend/src/services/session/pty/pty-session-backend.js.map +1 -1
  67. package/dist/backend/backend/src/services/session/pty/pty-terminal-buffer.d.ts.map +1 -1
  68. package/dist/backend/backend/src/services/session/pty/pty-terminal-buffer.js +2 -1
  69. package/dist/backend/backend/src/services/session/pty/pty-terminal-buffer.js.map +1 -1
  70. package/dist/backend/backend/src/services/session/session-state-persistence.d.ts +4 -1
  71. package/dist/backend/backend/src/services/session/session-state-persistence.d.ts.map +1 -1
  72. package/dist/backend/backend/src/services/session/session-state-persistence.js +3 -1
  73. package/dist/backend/backend/src/services/session/session-state-persistence.js.map +1 -1
  74. package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts +11 -0
  75. package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts.map +1 -1
  76. package/dist/backend/backend/src/services/skill/skill-catalog.service.js +46 -3
  77. package/dist/backend/backend/src/services/skill/skill-catalog.service.js.map +1 -1
  78. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +1 -0
  79. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  80. package/dist/backend/backend/src/services/workflow/scheduler.service.js +1 -0
  81. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  82. package/dist/backend/backend/src/types/index.d.ts +2 -0
  83. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  84. package/dist/backend/backend/src/types/index.js.map +1 -1
  85. package/dist/backend/backend/src/types/scheduler.types.d.ts +17 -0
  86. package/dist/backend/backend/src/types/scheduler.types.d.ts.map +1 -1
  87. package/dist/backend/backend/src/types/scheduler.types.js.map +1 -1
  88. package/dist/backend/config/constants.d.ts +36 -2
  89. package/dist/backend/config/constants.d.ts.map +1 -1
  90. package/dist/backend/config/constants.js +37 -2
  91. package/dist/backend/config/constants.js.map +1 -1
  92. package/dist/backend/config/index.d.ts +1 -1
  93. package/dist/cli/cli/src/commands/install.d.ts +23 -0
  94. package/dist/cli/cli/src/commands/install.d.ts.map +1 -0
  95. package/dist/cli/cli/src/commands/install.js +113 -0
  96. package/dist/cli/cli/src/commands/install.js.map +1 -0
  97. package/dist/cli/cli/src/commands/search.d.ts +23 -0
  98. package/dist/cli/cli/src/commands/search.d.ts.map +1 -0
  99. package/dist/cli/cli/src/commands/search.js +85 -0
  100. package/dist/cli/cli/src/commands/search.js.map +1 -0
  101. package/dist/cli/cli/src/commands/start.d.ts.map +1 -1
  102. package/dist/cli/cli/src/commands/start.js +11 -0
  103. package/dist/cli/cli/src/commands/start.js.map +1 -1
  104. package/dist/cli/cli/src/constants.d.ts +1 -1
  105. package/dist/cli/cli/src/index.js +13 -1
  106. package/dist/cli/cli/src/index.js.map +1 -1
  107. package/dist/cli/cli/src/utils/marketplace.d.ts +111 -0
  108. package/dist/cli/cli/src/utils/marketplace.d.ts.map +1 -0
  109. package/dist/cli/cli/src/utils/marketplace.js +209 -0
  110. package/dist/cli/cli/src/utils/marketplace.js.map +1 -0
  111. package/dist/cli/config/constants.d.ts +36 -2
  112. package/dist/cli/config/constants.d.ts.map +1 -1
  113. package/dist/cli/config/constants.js +37 -2
  114. package/dist/cli/config/constants.js.map +1 -1
  115. package/dist/cli/config/index.d.ts +1 -1
  116. package/frontend/dist/assets/{index-77b6a2a0.js → index-4c56763b.js} +31 -31
  117. package/frontend/dist/assets/{index-5ddf71c8.css → index-c1dd0b10.css} +1 -1
  118. package/frontend/dist/index.html +2 -2
  119. package/package.json +11 -4
  120. package/config/constants.test.ts +0 -469
  121. package/config/quality-gates/default-gates.test.ts +0 -246
  122. package/config/skills/agent/_common/lib.sh +0 -4
  123. package/config/skills/agent/accept-task/execute.sh +0 -21
  124. package/config/skills/agent/accept-task/instructions.md +0 -20
  125. package/config/skills/agent/accept-task/skill.json +0 -20
  126. package/config/skills/agent/block-task/execute.sh +0 -26
  127. package/config/skills/agent/block-task/instructions.md +0 -22
  128. package/config/skills/agent/block-task/skill.json +0 -20
  129. package/config/skills/agent/check-quality-gates/execute.sh +0 -20
  130. package/config/skills/agent/check-quality-gates/instructions.md +0 -23
  131. package/config/skills/agent/check-quality-gates/skill.json +0 -20
  132. package/config/skills/agent/complete-task/execute.sh +0 -26
  133. package/config/skills/agent/complete-task/instructions.md +0 -22
  134. package/config/skills/agent/complete-task/skill.json +0 -20
  135. package/config/skills/agent/get-my-context/execute.sh +0 -23
  136. package/config/skills/agent/get-my-context/instructions.md +0 -21
  137. package/config/skills/agent/get-my-context/skill.json +0 -20
  138. package/config/skills/agent/get-sops/execute.sh +0 -24
  139. package/config/skills/agent/get-sops/instructions.md +0 -21
  140. package/config/skills/agent/get-sops/skill.json +0 -20
  141. package/config/skills/agent/get-team-status/execute.sh +0 -8
  142. package/config/skills/agent/get-team-status/instructions.md +0 -17
  143. package/config/skills/agent/get-team-status/skill.json +0 -20
  144. package/config/skills/agent/manage-knowledge/execute.sh +0 -60
  145. package/config/skills/agent/manage-knowledge/instructions.md +0 -46
  146. package/config/skills/agent/nano-banana-image/.env +0 -2
  147. package/config/skills/agent/nano-banana-image/.env.example +0 -6
  148. package/config/skills/agent/nano-banana-image/generate.sh +0 -73
  149. package/config/skills/agent/nano-banana-image/instructions.md +0 -50
  150. package/config/skills/agent/nano-banana-image/skill.json +0 -39
  151. package/config/skills/agent/query-knowledge/execute.sh +0 -30
  152. package/config/skills/agent/query-knowledge/instructions.md +0 -47
  153. package/config/skills/agent/query-knowledge/skill.json +0 -20
  154. package/config/skills/agent/read-task/execute.sh +0 -15
  155. package/config/skills/agent/read-task/instructions.md +0 -19
  156. package/config/skills/agent/read-task/skill.json +0 -20
  157. package/config/skills/agent/recall/execute.sh +0 -24
  158. package/config/skills/agent/recall/instructions.md +0 -23
  159. package/config/skills/agent/recall/skill.json +0 -20
  160. package/config/skills/agent/record-learning/execute.sh +0 -29
  161. package/config/skills/agent/record-learning/instructions.md +0 -24
  162. package/config/skills/agent/record-learning/skill.json +0 -20
  163. package/config/skills/agent/register-self/execute.sh +0 -28
  164. package/config/skills/agent/register-self/instructions.md +0 -18
  165. package/config/skills/agent/register-self/skill.json +0 -20
  166. package/config/skills/agent/remember/execute.sh +0 -29
  167. package/config/skills/agent/remember/instructions.md +0 -24
  168. package/config/skills/agent/remember/skill.json +0 -20
  169. package/config/skills/agent/report-progress/execute.sh +0 -28
  170. package/config/skills/agent/report-progress/instructions.md +0 -25
  171. package/config/skills/agent/report-progress/skill.json +0 -20
  172. package/config/skills/agent/report-status/execute.sh +0 -35
  173. package/config/skills/agent/report-status/instructions.md +0 -36
  174. package/config/skills/agent/report-status/skill.json +0 -20
  175. package/config/skills/agent/send-chat-response/execute.sh +0 -26
  176. package/config/skills/agent/send-chat-response/instructions.md +0 -22
  177. package/config/skills/agent/send-chat-response/skill.json +0 -20
  178. package/config/skills/agent/send-message/execute.sh +0 -17
  179. package/config/skills/agent/send-message/instructions.md +0 -20
  180. package/config/skills/agent/send-message/skill.json +0 -20
  181. package/config/skills/agent/send-pdf-to-slack/execute.sh +0 -182
  182. package/config/skills/agent/send-pdf-to-slack/instructions.md +0 -49
  183. package/config/skills/agent/send-pdf-to-slack/skill.json +0 -20
  184. package/config/skills/nano-banana-image/.env +0 -2
  185. package/config/skills/nano-banana-image/.env.example +0 -6
@@ -1,469 +0,0 @@
1
- /**
2
- * Unit tests for Crewly cross-domain constants
3
- *
4
- * This test file validates the centralized constants that are shared
5
- * across all Crewly domains (backend, frontend, CLI).
6
- */
7
-
8
- import {
9
- CREWLY_CONSTANTS,
10
- AGENT_IDENTITY_CONSTANTS,
11
- WEB_CONSTANTS,
12
- TIMING_CONSTANTS,
13
- MESSAGE_CONSTANTS,
14
- ENV_CONSTANTS,
15
- type AgentStatus,
16
- type WorkingStatus,
17
- type AgentRole,
18
- type AgentId,
19
- type MessageType,
20
- } from './constants.js';
21
-
22
- describe('Crewly Cross-Domain Constants', () => {
23
- describe('CREWLY_CONSTANTS', () => {
24
- describe('SESSIONS', () => {
25
- test('should have valid orchestrator name', () => {
26
- expect(CREWLY_CONSTANTS.SESSIONS.ORCHESTRATOR_NAME).toBe('crewly-orc');
27
- expect(typeof CREWLY_CONSTANTS.SESSIONS.ORCHESTRATOR_NAME).toBe('string');
28
- });
29
-
30
- test('should have valid timeout values', () => {
31
- expect(CREWLY_CONSTANTS.SESSIONS.DEFAULT_TIMEOUT).toBe(120000);
32
- expect(CREWLY_CONSTANTS.SESSIONS.REGISTRATION_CHECK_INTERVAL).toBe(5000);
33
- expect(CREWLY_CONSTANTS.SESSIONS.CLAUDE_DETECTION_CACHE_TIMEOUT).toBe(30000);
34
- });
35
-
36
- test('timeout values should be positive numbers', () => {
37
- const timeouts = [
38
- CREWLY_CONSTANTS.SESSIONS.DEFAULT_TIMEOUT,
39
- CREWLY_CONSTANTS.SESSIONS.REGISTRATION_CHECK_INTERVAL,
40
- CREWLY_CONSTANTS.SESSIONS.CLAUDE_DETECTION_CACHE_TIMEOUT,
41
- ];
42
-
43
- timeouts.forEach((timeout) => {
44
- expect(typeof timeout).toBe('number');
45
- expect(timeout).toBeGreaterThan(0);
46
- });
47
- });
48
- });
49
-
50
- describe('PATHS', () => {
51
- test('should have all required paths', () => {
52
- expect(CREWLY_CONSTANTS.PATHS.CREWLY_HOME).toBe('.crewly');
53
- expect(CREWLY_CONSTANTS.PATHS.TEAMS_FILE).toBe('teams.json');
54
- expect(CREWLY_CONSTANTS.PATHS.PROJECTS_FILE).toBe('projects.json');
55
- expect(CREWLY_CONSTANTS.PATHS.CONFIG_DIR).toBe('config');
56
- expect(CREWLY_CONSTANTS.PATHS.PROMPTS_DIR).toBe('prompts');
57
- expect(CREWLY_CONSTANTS.PATHS.TASKS_DIR).toBe('tasks');
58
- expect(CREWLY_CONSTANTS.PATHS.SPECS_DIR).toBe('specs');
59
- expect(CREWLY_CONSTANTS.PATHS.MEMORY_DIR).toBe('memory');
60
- });
61
-
62
- test('file paths should have proper extensions', () => {
63
- expect(CREWLY_CONSTANTS.PATHS.TEAMS_FILE).toMatch(/\.json$/);
64
- expect(CREWLY_CONSTANTS.PATHS.PROJECTS_FILE).toMatch(/\.json$/);
65
- expect(CREWLY_CONSTANTS.PATHS.RUNTIME_FILE).toMatch(/\.json$/);
66
- expect(CREWLY_CONSTANTS.PATHS.SCHEDULED_MESSAGES_FILE).toMatch(/\.json$/);
67
- expect(CREWLY_CONSTANTS.PATHS.MESSAGE_DELIVERY_LOGS_FILE).toMatch(/\.json$/);
68
- });
69
-
70
- test('directory names should not contain slashes', () => {
71
- const dirs = [
72
- CREWLY_CONSTANTS.PATHS.CONFIG_DIR,
73
- CREWLY_CONSTANTS.PATHS.PROMPTS_DIR,
74
- CREWLY_CONSTANTS.PATHS.TASKS_DIR,
75
- CREWLY_CONSTANTS.PATHS.SPECS_DIR,
76
- CREWLY_CONSTANTS.PATHS.MEMORY_DIR,
77
- ];
78
-
79
- dirs.forEach((dir) => {
80
- expect(dir).not.toMatch(/\//);
81
- expect(dir.length).toBeGreaterThan(0);
82
- });
83
- });
84
- });
85
-
86
- describe('AGENT_STATUSES', () => {
87
- test('should have all required statuses', () => {
88
- expect(CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE).toBe('inactive');
89
- expect(CREWLY_CONSTANTS.AGENT_STATUSES.ACTIVATING).toBe('activating');
90
- expect(CREWLY_CONSTANTS.AGENT_STATUSES.ACTIVE).toBe('active');
91
- });
92
-
93
- test('all statuses should be lowercase strings', () => {
94
- Object.values(CREWLY_CONSTANTS.AGENT_STATUSES).forEach((status) => {
95
- expect(typeof status).toBe('string');
96
- expect(status).toBe(status.toLowerCase());
97
- });
98
- });
99
- });
100
-
101
- describe('WORKING_STATUSES', () => {
102
- test('should have all required working statuses', () => {
103
- expect(CREWLY_CONSTANTS.WORKING_STATUSES.IDLE).toBe('idle');
104
- expect(CREWLY_CONSTANTS.WORKING_STATUSES.IN_PROGRESS).toBe('in_progress');
105
- });
106
-
107
- test('all working statuses should be lowercase strings', () => {
108
- Object.values(CREWLY_CONSTANTS.WORKING_STATUSES).forEach((status) => {
109
- expect(typeof status).toBe('string');
110
- expect(status).toBe(status.toLowerCase());
111
- });
112
- });
113
- });
114
-
115
- describe('ROLES', () => {
116
- test('should have all required roles', () => {
117
- expect(CREWLY_CONSTANTS.ROLES.ORCHESTRATOR).toBe('orchestrator');
118
- expect(CREWLY_CONSTANTS.ROLES.PROJECT_MANAGER).toBe('pm');
119
- expect(CREWLY_CONSTANTS.ROLES.TECH_LEAD).toBe('tpm');
120
- expect(CREWLY_CONSTANTS.ROLES.DEVELOPER).toBe('developer');
121
- expect(CREWLY_CONSTANTS.ROLES.QA).toBe('qa');
122
- expect(CREWLY_CONSTANTS.ROLES.DEVOPS).toBe('devops');
123
- });
124
-
125
- test('should have display names for all roles', () => {
126
- Object.values(CREWLY_CONSTANTS.ROLES).forEach((role) => {
127
- expect(CREWLY_CONSTANTS.ROLE_DISPLAY_NAMES).toHaveProperty(role);
128
- expect(typeof CREWLY_CONSTANTS.ROLE_DISPLAY_NAMES[role as keyof typeof CREWLY_CONSTANTS.ROLE_DISPLAY_NAMES]).toBe('string');
129
- });
130
- });
131
-
132
- test('display names should be properly formatted', () => {
133
- Object.values(CREWLY_CONSTANTS.ROLE_DISPLAY_NAMES).forEach((displayName) => {
134
- expect(displayName.charAt(0)).toMatch(/[A-Z]/);
135
- expect(displayName.length).toBeGreaterThan(0);
136
- });
137
- });
138
- });
139
-
140
- describe('AGENT_IDS', () => {
141
- test('should have orchestrator ID defined', () => {
142
- expect(CREWLY_CONSTANTS.AGENT_IDS.ORCHESTRATOR_ID).toBe('orchestrator');
143
- });
144
-
145
- test('should be a valid string constant', () => {
146
- const orchestratorId: AgentId = CREWLY_CONSTANTS.AGENT_IDS.ORCHESTRATOR_ID;
147
- expect(typeof orchestratorId).toBe('string');
148
- expect(orchestratorId.length).toBeGreaterThan(0);
149
- expect(orchestratorId).toBe('orchestrator');
150
- });
151
-
152
- test('orchestrator ID should match role constant', () => {
153
- expect(CREWLY_CONSTANTS.AGENT_IDS.ORCHESTRATOR_ID).toBe(CREWLY_CONSTANTS.ROLES.ORCHESTRATOR);
154
- });
155
- });
156
- });
157
-
158
- describe('AGENT_IDENTITY_CONSTANTS', () => {
159
- describe('ORCHESTRATOR', () => {
160
- test('should have complete orchestrator identity', () => {
161
- const orch = AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR;
162
-
163
- expect(orch.ID).toBe('orchestrator');
164
- expect(orch.SESSION_NAME).toBe('crewly-orc');
165
- expect(orch.ROLE).toBe('orchestrator');
166
- });
167
-
168
- test('should reference existing constants consistently', () => {
169
- const orch = AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR;
170
-
171
- // Verify references point to correct source constants
172
- expect(orch.ID).toBe(CREWLY_CONSTANTS.AGENT_IDS.ORCHESTRATOR_ID);
173
- expect(orch.SESSION_NAME).toBe(CREWLY_CONSTANTS.SESSIONS.ORCHESTRATOR_NAME);
174
- expect(orch.ROLE).toBe(CREWLY_CONSTANTS.ROLES.ORCHESTRATOR);
175
- });
176
-
177
- test('should maintain type safety', () => {
178
- const orchestratorId: AgentId = AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR.ID;
179
- const orchestratorRole: AgentRole = AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR.ROLE;
180
-
181
- expect(orchestratorId).toBe('orchestrator');
182
- expect(orchestratorRole).toBe('orchestrator');
183
- });
184
-
185
- test('should provide constants for agent heartbeat system', () => {
186
- // These constants are essential for the new agent heartbeat architecture
187
- expect(typeof AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR.ID).toBe('string');
188
- expect(typeof AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR.SESSION_NAME).toBe('string');
189
- expect(typeof AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR.ROLE).toBe('string');
190
-
191
- // All should be non-empty
192
- expect(AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR.ID.length).toBeGreaterThan(0);
193
- expect(AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR.SESSION_NAME.length).toBeGreaterThan(0);
194
- expect(AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR.ROLE.length).toBeGreaterThan(0);
195
- });
196
- });
197
-
198
- test('should maintain consistency across all orchestrator references', () => {
199
- // All orchestrator constants should be consistent
200
- expect(CREWLY_CONSTANTS.AGENT_IDS.ORCHESTRATOR_ID).toBe('orchestrator');
201
- expect(CREWLY_CONSTANTS.ROLES.ORCHESTRATOR).toBe('orchestrator');
202
- expect(CREWLY_CONSTANTS.SESSIONS.ORCHESTRATOR_NAME).toBe('crewly-orc');
203
-
204
- // Identity helper should match
205
- const orch = AGENT_IDENTITY_CONSTANTS.ORCHESTRATOR;
206
- expect(orch.ID).toBe('orchestrator');
207
- expect(orch.ROLE).toBe('orchestrator');
208
- expect(orch.SESSION_NAME).toBe('crewly-orc');
209
- });
210
- });
211
-
212
- describe('WEB_CONSTANTS', () => {
213
- describe('PORTS', () => {
214
- test('should have valid port numbers', () => {
215
- expect(WEB_CONSTANTS.PORTS.BACKEND).toBe(8787);
216
- expect(WEB_CONSTANTS.PORTS.FRONTEND).toBe(8788);
217
- });
218
-
219
- test('ports should be in valid range', () => {
220
- [WEB_CONSTANTS.PORTS.BACKEND, WEB_CONSTANTS.PORTS.FRONTEND].forEach((port) => {
221
- expect(port).toBeGreaterThan(1023);
222
- expect(port).toBeLessThan(65536);
223
- });
224
- });
225
-
226
- test('frontend and backend ports should be different', () => {
227
- expect(WEB_CONSTANTS.PORTS.FRONTEND).not.toBe(WEB_CONSTANTS.PORTS.BACKEND);
228
- });
229
- });
230
-
231
- describe('ENDPOINTS', () => {
232
- test('should have all required endpoints', () => {
233
- expect(WEB_CONSTANTS.ENDPOINTS.HEALTH).toBe('/health');
234
- expect(WEB_CONSTANTS.ENDPOINTS.API_BASE).toBe('/api');
235
- expect(WEB_CONSTANTS.ENDPOINTS.TEAMS).toBe('/api/teams');
236
- expect(WEB_CONSTANTS.ENDPOINTS.PROJECTS).toBe('/api/projects');
237
- expect(WEB_CONSTANTS.ENDPOINTS.ORCHESTRATOR).toBe('/api/orchestrator');
238
- expect(WEB_CONSTANTS.ENDPOINTS.TERMINAL).toBe('/api/terminal');
239
- expect(WEB_CONSTANTS.ENDPOINTS.TASKS).toBe('/api/tasks');
240
- });
241
-
242
- test('all endpoints should start with forward slash', () => {
243
- Object.values(WEB_CONSTANTS.ENDPOINTS).forEach((endpoint) => {
244
- expect(endpoint).toMatch(/^\/[a-z]/);
245
- });
246
- });
247
-
248
- test('API endpoints should start with /api', () => {
249
- const apiEndpoints = [
250
- WEB_CONSTANTS.ENDPOINTS.TEAMS,
251
- WEB_CONSTANTS.ENDPOINTS.PROJECTS,
252
- WEB_CONSTANTS.ENDPOINTS.ORCHESTRATOR,
253
- WEB_CONSTANTS.ENDPOINTS.TERMINAL,
254
- WEB_CONSTANTS.ENDPOINTS.TASKS,
255
- ];
256
-
257
- apiEndpoints.forEach((endpoint) => {
258
- expect(endpoint).toMatch(/^\/api\//);
259
- });
260
- });
261
- });
262
- });
263
-
264
- describe('TIMING_CONSTANTS', () => {
265
- describe('RETRIES', () => {
266
- test('should have valid retry configuration', () => {
267
- expect(TIMING_CONSTANTS.RETRIES.MAX_ATTEMPTS).toBe(3);
268
- expect(TIMING_CONSTANTS.RETRIES.BASE_DELAY).toBe(1000);
269
- expect(TIMING_CONSTANTS.RETRIES.MAX_DELAY).toBe(10000);
270
- });
271
-
272
- test('retry values should be positive', () => {
273
- Object.values(TIMING_CONSTANTS.RETRIES).forEach((value) => {
274
- expect(typeof value).toBe('number');
275
- expect(value).toBeGreaterThan(0);
276
- });
277
- });
278
-
279
- test('max delay should be greater than base delay', () => {
280
- expect(TIMING_CONSTANTS.RETRIES.MAX_DELAY).toBeGreaterThan(TIMING_CONSTANTS.RETRIES.BASE_DELAY);
281
- });
282
- });
283
-
284
- describe('INTERVALS', () => {
285
- test('should have valid interval values', () => {
286
- expect(TIMING_CONSTANTS.INTERVALS.HEALTH_CHECK).toBe(30000);
287
- expect(TIMING_CONSTANTS.INTERVALS.MEMORY_CLEANUP).toBe(300000);
288
- expect(TIMING_CONSTANTS.INTERVALS.STATUS_UPDATE).toBe(10000);
289
- expect(TIMING_CONSTANTS.INTERVALS.ACTIVITY_MONITOR).toBe(15000);
290
- expect(TIMING_CONSTANTS.INTERVALS.CLEANUP).toBe(60000);
291
- expect(TIMING_CONSTANTS.INTERVALS.BATCH_DELAY).toBe(500);
292
- expect(TIMING_CONSTANTS.INTERVALS.RATE_LIMIT_WINDOW).toBe(1000);
293
- expect(TIMING_CONSTANTS.INTERVALS.TASK_CLEANUP).toBe(300000);
294
- });
295
-
296
- test('all intervals should be positive numbers', () => {
297
- Object.values(TIMING_CONSTANTS.INTERVALS).forEach((interval) => {
298
- expect(typeof interval).toBe('number');
299
- expect(interval).toBeGreaterThan(0);
300
- });
301
- });
302
-
303
- test('cleanup interval should be greater than batch delay', () => {
304
- expect(TIMING_CONSTANTS.INTERVALS.CLEANUP).toBeGreaterThan(
305
- TIMING_CONSTANTS.INTERVALS.BATCH_DELAY
306
- );
307
- });
308
-
309
- test('task cleanup should be greater than rate limit window', () => {
310
- expect(TIMING_CONSTANTS.INTERVALS.TASK_CLEANUP).toBeGreaterThan(
311
- TIMING_CONSTANTS.INTERVALS.RATE_LIMIT_WINDOW
312
- );
313
- });
314
- });
315
-
316
- describe('TIMEOUTS', () => {
317
- test('should have valid timeout values', () => {
318
- expect(TIMING_CONSTANTS.TIMEOUTS.CLAUDE_INIT).toBe(45000);
319
- expect(TIMING_CONSTANTS.TIMEOUTS.AGENT_SETUP).toBe(90000);
320
- expect(TIMING_CONSTANTS.TIMEOUTS.TASK_COMPLETION).toBe(300000);
321
- expect(TIMING_CONSTANTS.TIMEOUTS.WEBSOCKET).toBe(30000);
322
- expect(TIMING_CONSTANTS.TIMEOUTS.HTTP_HEALTH_CHECK).toBe(3000);
323
- expect(TIMING_CONSTANTS.TIMEOUTS.API_REQUEST_QUICK).toBe(2000);
324
- expect(TIMING_CONSTANTS.TIMEOUTS.SHUTDOWN).toBe(2000);
325
- expect(TIMING_CONSTANTS.TIMEOUTS.CONNECTION).toBe(10000);
326
- });
327
-
328
- test('all timeouts should be positive numbers', () => {
329
- Object.values(TIMING_CONSTANTS.TIMEOUTS).forEach((timeout) => {
330
- expect(typeof timeout).toBe('number');
331
- expect(timeout).toBeGreaterThan(0);
332
- });
333
- });
334
-
335
- test('http health check timeout should be reasonable', () => {
336
- expect(TIMING_CONSTANTS.TIMEOUTS.HTTP_HEALTH_CHECK).toBeLessThanOrEqual(10000);
337
- expect(TIMING_CONSTANTS.TIMEOUTS.HTTP_HEALTH_CHECK).toBeGreaterThanOrEqual(1000);
338
- });
339
-
340
- test('connection timeout should be reasonable', () => {
341
- expect(TIMING_CONSTANTS.TIMEOUTS.CONNECTION).toBeGreaterThanOrEqual(5000);
342
- expect(TIMING_CONSTANTS.TIMEOUTS.CONNECTION).toBeLessThanOrEqual(30000);
343
- });
344
- });
345
- });
346
-
347
- describe('MESSAGE_CONSTANTS', () => {
348
- describe('LIMITS', () => {
349
- test('should have valid message limits', () => {
350
- expect(MESSAGE_CONSTANTS.LIMITS.CHUNK_SIZE).toBe(1500);
351
- expect(MESSAGE_CONSTANTS.LIMITS.SMALL_CHUNK_SIZE).toBe(200);
352
- expect(MESSAGE_CONSTANTS.LIMITS.MAX_BUFFER_SIZE).toBe(100);
353
- });
354
-
355
- test('chunk size should be larger than small chunk size', () => {
356
- expect(MESSAGE_CONSTANTS.LIMITS.CHUNK_SIZE).toBeGreaterThan(MESSAGE_CONSTANTS.LIMITS.SMALL_CHUNK_SIZE);
357
- });
358
-
359
- test('all limits should be positive numbers', () => {
360
- Object.values(MESSAGE_CONSTANTS.LIMITS).forEach((limit) => {
361
- expect(typeof limit).toBe('number');
362
- expect(limit).toBeGreaterThan(0);
363
- });
364
- });
365
- });
366
-
367
- describe('TYPES', () => {
368
- test('should have all required message types', () => {
369
- const expectedTypes = ['system', 'user', 'agent', 'error', 'broadcast'];
370
- expectedTypes.forEach((type) => {
371
- expect(Object.values(MESSAGE_CONSTANTS.TYPES)).toContain(type);
372
- });
373
- });
374
-
375
- test('message types should be lowercase strings', () => {
376
- Object.values(MESSAGE_CONSTANTS.TYPES).forEach((type) => {
377
- expect(typeof type).toBe('string');
378
- expect(type).toBe(type.toLowerCase());
379
- });
380
- });
381
- });
382
- });
383
-
384
- describe('ENV_CONSTANTS', () => {
385
- test('should have all required environment variables', () => {
386
- const expectedEnvVars = [
387
- 'TMUX_SESSION_NAME',
388
- 'CREWLY_ROLE',
389
- 'API_PORT',
390
- 'CREWLY_MCP_PORT',
391
- 'PROJECT_PATH',
392
- 'AGENT_ROLE',
393
- 'NODE_ENV',
394
- 'DEV_MODE',
395
- ];
396
-
397
- expectedEnvVars.forEach((envVar) => {
398
- expect(Object.values(ENV_CONSTANTS)).toContain(envVar);
399
- });
400
- });
401
-
402
- test('all env var names should be uppercase with underscores', () => {
403
- Object.values(ENV_CONSTANTS).forEach((envVar) => {
404
- expect(envVar).toMatch(/^[A-Z_]+$/);
405
- });
406
- });
407
-
408
- test('env var names should not be empty', () => {
409
- Object.values(ENV_CONSTANTS).forEach((envVar) => {
410
- expect(envVar.length).toBeGreaterThan(0);
411
- });
412
- });
413
- });
414
-
415
- describe('Type Helpers', () => {
416
- test('AgentStatus type should include all status values', () => {
417
- const testStatus: AgentStatus = 'active';
418
- expect(['active', 'inactive', 'activating']).toContain(testStatus);
419
- });
420
-
421
- test('WorkingStatus type should include all working status values', () => {
422
- const testWorkingStatus: WorkingStatus = 'idle';
423
- expect(['idle', 'in_progress']).toContain(testWorkingStatus);
424
- });
425
-
426
- test('AgentRole type should include all role values', () => {
427
- const testRole: AgentRole = 'developer';
428
- expect(['orchestrator', 'pm', 'tpm', 'developer', 'qa', 'devops']).toContain(testRole);
429
- });
430
-
431
- test('MessageType type should include all message type values', () => {
432
- const testMessageType: MessageType = 'system';
433
- expect(Object.values(MESSAGE_CONSTANTS.TYPES)).toContain(testMessageType);
434
- });
435
- });
436
-
437
- describe('Constants Structure', () => {
438
- test('all main constant objects should be defined', () => {
439
- expect(CREWLY_CONSTANTS).toBeDefined();
440
- expect(WEB_CONSTANTS).toBeDefined();
441
- expect(TIMING_CONSTANTS).toBeDefined();
442
- expect(MESSAGE_CONSTANTS).toBeDefined();
443
- expect(ENV_CONSTANTS).toBeDefined();
444
- });
445
-
446
- test('constants should be immutable (const assertions)', () => {
447
- // These tests verify that const assertions are working
448
- expect(typeof CREWLY_CONSTANTS).toBe('object');
449
- expect(typeof WEB_CONSTANTS).toBe('object');
450
- expect(typeof TIMING_CONSTANTS).toBe('object');
451
- expect(typeof MESSAGE_CONSTANTS).toBe('object');
452
- expect(typeof ENV_CONSTANTS).toBe('object');
453
- });
454
- });
455
-
456
- describe('Cross-Domain Consistency', () => {
457
- test('orchestrator session name should be consistent', () => {
458
- expect(CREWLY_CONSTANTS.SESSIONS.ORCHESTRATOR_NAME).toBe('crewly-orc');
459
- });
460
-
461
- test('timeout values should be reasonable', () => {
462
- // Agent setup timeout should be longer than Claude init timeout
463
- expect(TIMING_CONSTANTS.TIMEOUTS.AGENT_SETUP).toBeGreaterThan(TIMING_CONSTANTS.TIMEOUTS.CLAUDE_INIT);
464
-
465
- // Task completion timeout should be longest
466
- expect(TIMING_CONSTANTS.TIMEOUTS.TASK_COMPLETION).toBeGreaterThan(TIMING_CONSTANTS.TIMEOUTS.AGENT_SETUP);
467
- });
468
- });
469
- });