oh-my-claude-sisyphus 3.5.8 → 3.6.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 (94) hide show
  1. package/agents/executor-high.md +2 -0
  2. package/agents/executor-low.md +2 -0
  3. package/agents/executor.md +2 -0
  4. package/agents/templates/base-agent.md +9 -0
  5. package/commands/cancel.md +8 -8
  6. package/commands/swarm.md +350 -148
  7. package/dist/__tests__/hooks.test.js +10 -9
  8. package/dist/__tests__/hooks.test.js.map +1 -1
  9. package/dist/agents/codex-agents.d.ts +20 -0
  10. package/dist/agents/codex-agents.d.ts.map +1 -0
  11. package/dist/agents/codex-agents.js +36 -0
  12. package/dist/agents/codex-agents.js.map +1 -0
  13. package/dist/agents/preamble.d.ts +14 -0
  14. package/dist/agents/preamble.d.ts.map +1 -0
  15. package/dist/agents/preamble.js +26 -0
  16. package/dist/agents/preamble.js.map +1 -0
  17. package/dist/hooks/autopilot/__tests__/cancel.test.js +14 -4
  18. package/dist/hooks/autopilot/__tests__/cancel.test.js.map +1 -1
  19. package/dist/hooks/autopilot/__tests__/state.test.js +1 -0
  20. package/dist/hooks/autopilot/__tests__/state.test.js.map +1 -1
  21. package/dist/hooks/autopilot/__tests__/summary.test.js +38 -3
  22. package/dist/hooks/autopilot/__tests__/summary.test.js.map +1 -1
  23. package/dist/hooks/autopilot/state.d.ts +1 -1
  24. package/dist/hooks/autopilot/state.d.ts.map +1 -1
  25. package/dist/hooks/autopilot/state.js +15 -8
  26. package/dist/hooks/autopilot/state.js.map +1 -1
  27. package/dist/hooks/index.d.ts +2 -0
  28. package/dist/hooks/index.d.ts.map +1 -1
  29. package/dist/hooks/index.js +7 -0
  30. package/dist/hooks/index.js.map +1 -1
  31. package/dist/hooks/mode-registry/index.d.ts +135 -0
  32. package/dist/hooks/mode-registry/index.d.ts.map +1 -0
  33. package/dist/hooks/mode-registry/index.js +445 -0
  34. package/dist/hooks/mode-registry/index.js.map +1 -0
  35. package/dist/hooks/mode-registry/types.d.ts +31 -0
  36. package/dist/hooks/mode-registry/types.d.ts.map +1 -0
  37. package/dist/hooks/mode-registry/types.js +7 -0
  38. package/dist/hooks/mode-registry/types.js.map +1 -0
  39. package/dist/hooks/ralph/loop.js +6 -6
  40. package/dist/hooks/ralph/loop.js.map +1 -1
  41. package/dist/hooks/swarm/__tests__/claiming.test.d.ts +2 -0
  42. package/dist/hooks/swarm/__tests__/claiming.test.d.ts.map +1 -0
  43. package/dist/hooks/swarm/__tests__/claiming.test.js +170 -0
  44. package/dist/hooks/swarm/__tests__/claiming.test.js.map +1 -0
  45. package/dist/hooks/swarm/__tests__/index.test.d.ts +2 -0
  46. package/dist/hooks/swarm/__tests__/index.test.d.ts.map +1 -0
  47. package/dist/hooks/swarm/__tests__/index.test.js +157 -0
  48. package/dist/hooks/swarm/__tests__/index.test.js.map +1 -0
  49. package/dist/hooks/swarm/__tests__/mode-registry.test.d.ts +2 -0
  50. package/dist/hooks/swarm/__tests__/mode-registry.test.d.ts.map +1 -0
  51. package/dist/hooks/swarm/__tests__/mode-registry.test.js +177 -0
  52. package/dist/hooks/swarm/__tests__/mode-registry.test.js.map +1 -0
  53. package/dist/hooks/swarm/claiming.d.ts +101 -0
  54. package/dist/hooks/swarm/claiming.d.ts.map +1 -0
  55. package/dist/hooks/swarm/claiming.js +460 -0
  56. package/dist/hooks/swarm/claiming.js.map +1 -0
  57. package/dist/hooks/swarm/index.d.ts +221 -0
  58. package/dist/hooks/swarm/index.d.ts.map +1 -0
  59. package/dist/hooks/swarm/index.js +413 -0
  60. package/dist/hooks/swarm/index.js.map +1 -0
  61. package/dist/hooks/swarm/state.d.ts +94 -0
  62. package/dist/hooks/swarm/state.d.ts.map +1 -0
  63. package/dist/hooks/swarm/state.js +530 -0
  64. package/dist/hooks/swarm/state.js.map +1 -0
  65. package/dist/hooks/swarm/types.d.ts +116 -0
  66. package/dist/hooks/swarm/types.d.ts.map +1 -0
  67. package/dist/hooks/swarm/types.js +22 -0
  68. package/dist/hooks/swarm/types.js.map +1 -0
  69. package/dist/hooks/ultrapilot/decomposer.d.ts +141 -0
  70. package/dist/hooks/ultrapilot/decomposer.d.ts.map +1 -0
  71. package/dist/hooks/ultrapilot/decomposer.js +377 -0
  72. package/dist/hooks/ultrapilot/decomposer.js.map +1 -0
  73. package/dist/hooks/ultrapilot/index.d.ts +31 -0
  74. package/dist/hooks/ultrapilot/index.d.ts.map +1 -1
  75. package/dist/hooks/ultrapilot/index.js +43 -2
  76. package/dist/hooks/ultrapilot/index.js.map +1 -1
  77. package/dist/hooks/ultrapilot/state.d.ts +1 -1
  78. package/dist/hooks/ultrapilot/state.d.ts.map +1 -1
  79. package/dist/hooks/ultrapilot/state.js +7 -0
  80. package/dist/hooks/ultrapilot/state.js.map +1 -1
  81. package/dist/hooks/ultraqa/index.js +5 -5
  82. package/dist/hooks/ultraqa/index.js.map +1 -1
  83. package/dist/hooks/ultrawork/index.js +3 -3
  84. package/dist/hooks/ultrawork/index.js.map +1 -1
  85. package/package.json +3 -1
  86. package/skills/autopilot/SKILL.md +18 -0
  87. package/skills/cancel/SKILL.md +166 -141
  88. package/skills/ecomode/SKILL.md +14 -0
  89. package/skills/pipeline/SKILL.md +13 -0
  90. package/skills/ralph/SKILL.md +22 -1
  91. package/skills/swarm/SKILL.md +521 -197
  92. package/skills/ultrapilot/SKILL.md +82 -13
  93. package/skills/ultraqa/SKILL.md +13 -0
  94. package/skills/ultrawork/SKILL.md +14 -0
@@ -0,0 +1,170 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { mkdtempSync, rmSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { tmpdir } from 'os';
5
+ import { initDb, closeDb, initSession, addTasks, getHeartbeats } from '../state.js';
6
+ import { claimTask, cleanupStaleClaims, heartbeat } from '../claiming.js';
7
+ describe('Swarm Claiming', () => {
8
+ let testDir;
9
+ beforeEach(async () => {
10
+ testDir = mkdtempSync(join(tmpdir(), 'swarm-claiming-test-'));
11
+ await initDb(testDir);
12
+ });
13
+ afterEach(() => {
14
+ closeDb();
15
+ rmSync(testDir, { recursive: true, force: true });
16
+ });
17
+ describe('claimTask', () => {
18
+ it('should successfully claim a pending task', () => {
19
+ initSession('test-session', 3);
20
+ addTasks([
21
+ { id: 'task-1', description: 'First task' }
22
+ ]);
23
+ const result = claimTask('agent-1');
24
+ expect(result.success).toBe(true);
25
+ expect(result.taskId).toBe('task-1');
26
+ expect(result.description).toBe('First task');
27
+ });
28
+ it('should allow sequential claims for different tasks', () => {
29
+ initSession('test-session', 3);
30
+ addTasks([
31
+ { id: 'task-1', description: 'First task' },
32
+ { id: 'task-2', description: 'Second task' },
33
+ { id: 'task-3', description: 'Third task' }
34
+ ]);
35
+ const result1 = claimTask('agent-1');
36
+ const result2 = claimTask('agent-2');
37
+ const result3 = claimTask('agent-3');
38
+ expect(result1.success).toBe(true);
39
+ expect(result1.taskId).toBe('task-1');
40
+ expect(result2.success).toBe(true);
41
+ expect(result2.taskId).toBe('task-2');
42
+ expect(result3.success).toBe(true);
43
+ expect(result3.taskId).toBe('task-3');
44
+ });
45
+ it('should handle duplicate claims correctly when only one task available', () => {
46
+ initSession('test-session', 2);
47
+ addTasks([
48
+ { id: 'task-1', description: 'Only task' }
49
+ ]);
50
+ const result1 = claimTask('agent-1');
51
+ const result2 = claimTask('agent-2');
52
+ expect(result1.success).toBe(true);
53
+ expect(result1.taskId).toBe('task-1');
54
+ expect(result2.success).toBe(false);
55
+ expect(result2.taskId).toBeNull();
56
+ });
57
+ it('should fail with appropriate message when no pending tasks available', () => {
58
+ initSession('test-session', 2);
59
+ // No tasks added
60
+ const result = claimTask('agent-1');
61
+ expect(result.success).toBe(false);
62
+ expect(result.taskId).toBeNull();
63
+ expect(result.reason).toBe('No pending tasks available');
64
+ });
65
+ it('should update heartbeat when claiming a task', () => {
66
+ initSession('test-session', 1);
67
+ addTasks([
68
+ { id: 'task-1', description: 'First task' }
69
+ ]);
70
+ claimTask('agent-1');
71
+ const heartbeats = getHeartbeats();
72
+ expect(heartbeats).toHaveLength(1);
73
+ expect(heartbeats[0].agentId).toBe('agent-1');
74
+ expect(heartbeats[0].currentTaskId).toBe('task-1');
75
+ expect(heartbeats[0].lastHeartbeat).toBeGreaterThan(Date.now() - 1000);
76
+ });
77
+ });
78
+ describe('cleanupStaleClaims', () => {
79
+ it('should return 0 when no stale claims exist', () => {
80
+ initSession('test-session', 1);
81
+ addTasks([
82
+ { id: 'task-1', description: 'First task' }
83
+ ]);
84
+ const released = cleanupStaleClaims(5 * 60 * 1000); // 5 minutes
85
+ expect(released).toBe(0);
86
+ });
87
+ it('should release stale claim without heartbeat', () => {
88
+ vi.useFakeTimers();
89
+ const now = Date.now();
90
+ vi.setSystemTime(now);
91
+ initSession('test-session', 1);
92
+ addTasks([
93
+ { id: 'task-1', description: 'First task' }
94
+ ]);
95
+ // Claim task
96
+ claimTask('agent-1');
97
+ // Advance time by 6 minutes
98
+ vi.setSystemTime(now + 6 * 60 * 1000);
99
+ // Cleanup stale claims
100
+ const released = cleanupStaleClaims(5 * 60 * 1000);
101
+ expect(released).toBe(1);
102
+ vi.useRealTimers();
103
+ });
104
+ it('should not release claim with fresh heartbeat', () => {
105
+ vi.useFakeTimers();
106
+ const now = Date.now();
107
+ vi.setSystemTime(now);
108
+ initSession('test-session', 1);
109
+ addTasks([
110
+ { id: 'task-1', description: 'First task' }
111
+ ]);
112
+ // Claim task
113
+ claimTask('agent-1');
114
+ // Advance time by 3 minutes
115
+ vi.setSystemTime(now + 3 * 60 * 1000);
116
+ // Send heartbeat
117
+ heartbeat('agent-1');
118
+ // Advance time by another 3 minutes (6 minutes total, but heartbeat is only 3 minutes old)
119
+ vi.setSystemTime(now + 6 * 60 * 1000);
120
+ // Cleanup stale claims
121
+ const released = cleanupStaleClaims(5 * 60 * 1000);
122
+ expect(released).toBe(0);
123
+ vi.useRealTimers();
124
+ });
125
+ it('should release multiple stale claims', () => {
126
+ vi.useFakeTimers();
127
+ const now = Date.now();
128
+ vi.setSystemTime(now);
129
+ initSession('test-session', 3);
130
+ addTasks([
131
+ { id: 'task-1', description: 'First task' },
132
+ { id: 'task-2', description: 'Second task' },
133
+ { id: 'task-3', description: 'Third task' }
134
+ ]);
135
+ // All agents claim tasks
136
+ claimTask('agent-1');
137
+ claimTask('agent-2');
138
+ claimTask('agent-3');
139
+ // Advance time by 6 minutes
140
+ vi.setSystemTime(now + 6 * 60 * 1000);
141
+ // Cleanup stale claims
142
+ const released = cleanupStaleClaims(5 * 60 * 1000);
143
+ expect(released).toBe(3);
144
+ vi.useRealTimers();
145
+ });
146
+ it('should remove stale heartbeat records during cleanup', () => {
147
+ vi.useFakeTimers();
148
+ const now = Date.now();
149
+ vi.setSystemTime(now);
150
+ initSession('test-session', 1);
151
+ addTasks([
152
+ { id: 'task-1', description: 'First task' }
153
+ ]);
154
+ // Claim task
155
+ claimTask('agent-1');
156
+ // Verify heartbeat exists
157
+ let heartbeats = getHeartbeats();
158
+ expect(heartbeats).toHaveLength(1);
159
+ // Advance time by 6 minutes
160
+ vi.setSystemTime(now + 6 * 60 * 1000);
161
+ // Cleanup stale claims
162
+ cleanupStaleClaims(5 * 60 * 1000);
163
+ // Verify heartbeat was removed
164
+ heartbeats = getHeartbeats();
165
+ expect(heartbeats).toHaveLength(0);
166
+ vi.useRealTimers();
167
+ });
168
+ });
169
+ });
170
+ //# sourceMappingURL=claiming.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claiming.test.js","sourceRoot":"","sources":["../../../../src/hooks/swarm/__tests__/claiming.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../../src/hooks/swarm/__tests__/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,157 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { mkdtempSync, rmSync, existsSync, writeFileSync, mkdirSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { tmpdir } from 'os';
5
+ import { startSwarm, stopSwarm, getSwarmStatus, isSwarmActive } from '../index.js';
6
+ describe('Swarm Lifecycle', () => {
7
+ let testDir;
8
+ beforeEach(() => {
9
+ testDir = mkdtempSync(join(tmpdir(), 'swarm-test-'));
10
+ });
11
+ afterEach(() => {
12
+ // Clean up any active swarm before removing directory
13
+ try {
14
+ stopSwarm(true);
15
+ }
16
+ catch {
17
+ // Ignore errors if swarm was not active
18
+ }
19
+ rmSync(testDir, { recursive: true, force: true });
20
+ });
21
+ describe('startSwarm', () => {
22
+ it('should start swarm with valid config and create db and marker', async () => {
23
+ const success = await startSwarm({
24
+ agentCount: 3,
25
+ tasks: ['task 1', 'task 2', 'task 3'],
26
+ cwd: testDir
27
+ });
28
+ expect(success).toBe(true);
29
+ // Verify database exists
30
+ const dbPath = join(testDir, '.omc', 'state', 'swarm.db');
31
+ expect(existsSync(dbPath)).toBe(true);
32
+ // Verify marker file exists
33
+ const markerPath = join(testDir, '.omc', 'state', 'swarm-active.marker');
34
+ expect(existsSync(markerPath)).toBe(true);
35
+ // Verify state is active
36
+ const status = getSwarmStatus();
37
+ expect(status).not.toBeNull();
38
+ expect(status?.active).toBe(true);
39
+ });
40
+ it('should fail with empty tasks array', async () => {
41
+ const success = await startSwarm({
42
+ agentCount: 3,
43
+ tasks: [],
44
+ cwd: testDir
45
+ });
46
+ expect(success).toBe(false);
47
+ });
48
+ it('should fail with agentCount less than 1', async () => {
49
+ const success = await startSwarm({
50
+ agentCount: 0,
51
+ tasks: ['task 1'],
52
+ cwd: testDir
53
+ });
54
+ expect(success).toBe(false);
55
+ });
56
+ it('should fail when another exclusive mode is active', async () => {
57
+ // Create autopilot state file to simulate active autopilot
58
+ const stateDir = join(testDir, '.omc', 'state');
59
+ mkdirSync(stateDir, { recursive: true });
60
+ const autopilotStatePath = join(stateDir, 'autopilot-state.json');
61
+ writeFileSync(autopilotStatePath, JSON.stringify({
62
+ active: true,
63
+ phase: 'execution',
64
+ originalIdea: 'test',
65
+ created_at: Date.now()
66
+ }));
67
+ // Attempt to start swarm should fail
68
+ const success = await startSwarm({
69
+ agentCount: 3,
70
+ tasks: ['task 1'],
71
+ cwd: testDir
72
+ });
73
+ expect(success).toBe(false);
74
+ });
75
+ });
76
+ describe('stopSwarm', () => {
77
+ it('should clean up properly and remove marker', async () => {
78
+ // Start swarm
79
+ await startSwarm({
80
+ agentCount: 2,
81
+ tasks: ['task 1', 'task 2'],
82
+ cwd: testDir
83
+ });
84
+ const markerPath = join(testDir, '.omc', 'state', 'swarm-active.marker');
85
+ expect(existsSync(markerPath)).toBe(true);
86
+ // Stop swarm without deleting database
87
+ const success = stopSwarm(false);
88
+ expect(success).toBe(true);
89
+ // Marker should be removed
90
+ expect(existsSync(markerPath)).toBe(false);
91
+ // Database should still exist
92
+ const dbPath = join(testDir, '.omc', 'state', 'swarm.db');
93
+ expect(existsSync(dbPath)).toBe(true);
94
+ });
95
+ it('should remove database when deleteDatabase=true', async () => {
96
+ await startSwarm({
97
+ agentCount: 2,
98
+ tasks: ['task 1'],
99
+ cwd: testDir
100
+ });
101
+ const dbPath = join(testDir, '.omc', 'state', 'swarm.db');
102
+ expect(existsSync(dbPath)).toBe(true);
103
+ // Stop with deleteDatabase flag
104
+ stopSwarm(true);
105
+ // Database should be deleted
106
+ expect(existsSync(dbPath)).toBe(false);
107
+ });
108
+ });
109
+ describe('getSwarmStatus', () => {
110
+ it('should return null when swarm is not active', () => {
111
+ const status = getSwarmStatus();
112
+ expect(status).toBeNull();
113
+ });
114
+ it('should return correct state when swarm is active', async () => {
115
+ await startSwarm({
116
+ agentCount: 5,
117
+ tasks: ['task 1', 'task 2'],
118
+ cwd: testDir
119
+ });
120
+ const status = getSwarmStatus();
121
+ expect(status).not.toBeNull();
122
+ expect(status?.active).toBe(true);
123
+ expect(status?.agentCount).toBe(5);
124
+ });
125
+ });
126
+ describe('isSwarmActive', () => {
127
+ it('should detect running swarm', async () => {
128
+ await startSwarm({
129
+ agentCount: 3,
130
+ tasks: ['task 1'],
131
+ cwd: testDir
132
+ });
133
+ expect(isSwarmActive(testDir)).toBe(true);
134
+ });
135
+ it('should return false when swarm is not running', () => {
136
+ expect(isSwarmActive(testDir)).toBe(false);
137
+ });
138
+ it('should detect inactive state after swarm is stopped with database preserved', async () => {
139
+ await startSwarm({
140
+ agentCount: 2,
141
+ tasks: ['task 1'],
142
+ cwd: testDir
143
+ });
144
+ expect(isSwarmActive(testDir)).toBe(true);
145
+ stopSwarm(false);
146
+ // After stopSwarm(false), database file still exists
147
+ const dbPath = join(testDir, '.omc', 'state', 'swarm.db');
148
+ expect(existsSync(dbPath)).toBe(true);
149
+ // isSwarmActive checks if db file exists (not if it's truly active)
150
+ // This is expected behavior - database is preserved for analysis
151
+ // For true active detection, use marker file (removed by stopSwarm)
152
+ const markerPath = join(testDir, '.omc', 'state', 'swarm-active.marker');
153
+ expect(existsSync(markerPath)).toBe(false);
154
+ });
155
+ });
156
+ });
157
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../../src/hooks/swarm/__tests__/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mode-registry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-registry.test.d.ts","sourceRoot":"","sources":["../../../../src/hooks/swarm/__tests__/mode-registry.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,177 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { mkdtempSync, rmSync, existsSync, writeFileSync, mkdirSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { tmpdir } from 'os';
5
+ import { canStartMode, createModeMarker, removeModeMarker, isModeActive, readModeMarker } from '../../mode-registry/index.js';
6
+ describe('Mode Registry Integration', () => {
7
+ let testDir;
8
+ beforeEach(() => {
9
+ testDir = mkdtempSync(join(tmpdir(), 'mode-registry-test-'));
10
+ });
11
+ afterEach(() => {
12
+ rmSync(testDir, { recursive: true, force: true });
13
+ });
14
+ describe('canStartMode', () => {
15
+ it('should allow mode when no conflicts exist', () => {
16
+ const result = canStartMode('swarm', testDir);
17
+ expect(result.allowed).toBe(true);
18
+ expect(result.blockedBy).toBeUndefined();
19
+ expect(result.message).toBeUndefined();
20
+ });
21
+ it('should block when exclusive mode is active', () => {
22
+ // Create autopilot state to simulate active mode
23
+ const stateDir = join(testDir, '.omc', 'state');
24
+ mkdirSync(stateDir, { recursive: true });
25
+ const autopilotStatePath = join(stateDir, 'autopilot-state.json');
26
+ writeFileSync(autopilotStatePath, JSON.stringify({
27
+ active: true,
28
+ phase: 'execution',
29
+ originalIdea: 'test',
30
+ created_at: Date.now()
31
+ }));
32
+ const result = canStartMode('swarm', testDir);
33
+ expect(result.allowed).toBe(false);
34
+ expect(result.blockedBy).toBe('autopilot');
35
+ expect(result.message).toContain('Cannot start Swarm');
36
+ expect(result.message).toContain('Autopilot is active');
37
+ });
38
+ it('should block when ultrapilot is active', () => {
39
+ // Create ultrapilot state
40
+ const stateDir = join(testDir, '.omc', 'state');
41
+ mkdirSync(stateDir, { recursive: true });
42
+ const ultrapilotStatePath = join(stateDir, 'ultrapilot-state.json');
43
+ writeFileSync(ultrapilotStatePath, JSON.stringify({
44
+ active: true,
45
+ created_at: Date.now()
46
+ }));
47
+ const result = canStartMode('swarm', testDir);
48
+ expect(result.allowed).toBe(false);
49
+ expect(result.blockedBy).toBe('ultrapilot');
50
+ });
51
+ it('should allow non-exclusive modes when swarm is active', () => {
52
+ // Create swarm marker
53
+ const stateDir = join(testDir, '.omc', 'state');
54
+ mkdirSync(stateDir, { recursive: true });
55
+ createModeMarker('swarm', testDir, { agentCount: 3 });
56
+ // Ralph is not exclusive, so it should be allowed
57
+ const result = canStartMode('ralph', testDir);
58
+ expect(result.allowed).toBe(true);
59
+ });
60
+ });
61
+ describe('createModeMarker', () => {
62
+ it('should create marker file with metadata', () => {
63
+ const markerPath = join(testDir, '.omc', 'state', 'swarm-active.marker');
64
+ const success = createModeMarker('swarm', testDir, {
65
+ agentCount: 5,
66
+ taskCount: 10
67
+ });
68
+ expect(success).toBe(true);
69
+ expect(existsSync(markerPath)).toBe(true);
70
+ const marker = readModeMarker('swarm', testDir);
71
+ expect(marker).not.toBeNull();
72
+ expect(marker?.mode).toBe('swarm');
73
+ expect(marker?.agentCount).toBe(5);
74
+ expect(marker?.taskCount).toBe(10);
75
+ expect(marker?.startedAt).toBeDefined();
76
+ });
77
+ it('should create directory if it does not exist', () => {
78
+ const markerPath = join(testDir, '.omc', 'state', 'swarm-active.marker');
79
+ // Ensure directory doesn't exist
80
+ expect(existsSync(join(testDir, '.omc'))).toBe(false);
81
+ const success = createModeMarker('swarm', testDir, {});
82
+ expect(success).toBe(true);
83
+ expect(existsSync(markerPath)).toBe(true);
84
+ });
85
+ it('should fail for modes without marker file', () => {
86
+ // autopilot uses JSON state file, not marker
87
+ const success = createModeMarker('autopilot', testDir, {});
88
+ expect(success).toBe(false);
89
+ });
90
+ });
91
+ describe('removeModeMarker', () => {
92
+ it('should delete marker file', () => {
93
+ const markerPath = join(testDir, '.omc', 'state', 'swarm-active.marker');
94
+ createModeMarker('swarm', testDir, {});
95
+ expect(existsSync(markerPath)).toBe(true);
96
+ const success = removeModeMarker('swarm', testDir);
97
+ expect(success).toBe(true);
98
+ expect(existsSync(markerPath)).toBe(false);
99
+ });
100
+ it('should succeed if marker does not exist', () => {
101
+ const success = removeModeMarker('swarm', testDir);
102
+ expect(success).toBe(true);
103
+ });
104
+ it('should succeed for modes without marker file', () => {
105
+ const success = removeModeMarker('autopilot', testDir);
106
+ expect(success).toBe(true);
107
+ });
108
+ });
109
+ describe('isModeActive', () => {
110
+ it('should detect active marker-based mode', () => {
111
+ createModeMarker('swarm', testDir, {});
112
+ expect(isModeActive('swarm', testDir)).toBe(true);
113
+ });
114
+ it('should detect active JSON-based mode', () => {
115
+ const stateDir = join(testDir, '.omc', 'state');
116
+ mkdirSync(stateDir, { recursive: true });
117
+ writeFileSync(join(stateDir, 'autopilot-state.json'), JSON.stringify({
118
+ active: true,
119
+ phase: 'execution',
120
+ originalIdea: 'test',
121
+ created_at: Date.now()
122
+ }));
123
+ expect(isModeActive('autopilot', testDir)).toBe(true);
124
+ });
125
+ it('should return false when mode is not active', () => {
126
+ expect(isModeActive('swarm', testDir)).toBe(false);
127
+ expect(isModeActive('autopilot', testDir)).toBe(false);
128
+ });
129
+ it('should return false when JSON mode is inactive', () => {
130
+ const stateDir = join(testDir, '.omc', 'state');
131
+ mkdirSync(stateDir, { recursive: true });
132
+ writeFileSync(join(stateDir, 'autopilot-state.json'), JSON.stringify({
133
+ active: false,
134
+ phase: 'complete',
135
+ originalIdea: 'test',
136
+ created_at: Date.now(),
137
+ completed_at: Date.now()
138
+ }));
139
+ expect(isModeActive('autopilot', testDir)).toBe(false);
140
+ });
141
+ });
142
+ describe('Stale marker detection', () => {
143
+ it('should auto-remove stale markers older than 1 hour', () => {
144
+ // Create marker with old timestamp (simulating stale marker)
145
+ const stateDir = join(testDir, '.omc', 'state');
146
+ mkdirSync(stateDir, { recursive: true });
147
+ const markerPath = join(stateDir, 'swarm-active.marker');
148
+ // Create marker with timestamp from 2 hours ago (exceeds 1-hour threshold)
149
+ const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString();
150
+ writeFileSync(markerPath, JSON.stringify({
151
+ mode: 'swarm',
152
+ startedAt: twoHoursAgo,
153
+ agentCount: 3
154
+ }));
155
+ // Verify marker file exists
156
+ expect(existsSync(markerPath)).toBe(true);
157
+ // isModeActive should detect stale marker and auto-remove it
158
+ expect(isModeActive('swarm', testDir)).toBe(false);
159
+ // Marker should be deleted after staleness check
160
+ expect(existsSync(markerPath)).toBe(false);
161
+ });
162
+ it('should handle marker files without timestamp', () => {
163
+ const stateDir = join(testDir, '.omc', 'state');
164
+ mkdirSync(stateDir, { recursive: true });
165
+ const markerPath = join(stateDir, 'swarm-active.marker');
166
+ // Create marker without startedAt
167
+ writeFileSync(markerPath, JSON.stringify({
168
+ mode: 'swarm',
169
+ agentCount: 3
170
+ }));
171
+ expect(isModeActive('swarm', testDir)).toBe(true);
172
+ const marker = readModeMarker('swarm', testDir);
173
+ expect(marker?.startedAt).toBeUndefined();
174
+ });
175
+ });
176
+ });
177
+ //# sourceMappingURL=mode-registry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-registry.test.js","sourceRoot":"","sources":["../../../../src/hooks/swarm/__tests__/mode-registry.test.ts"],"names":[],"mappings":"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"}