oh-my-claude-sisyphus 2.4.1 → 2.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 (85) hide show
  1. package/README.md +56 -29
  2. package/dist/__tests__/hooks.test.js +255 -1
  3. package/dist/__tests__/hooks.test.js.map +1 -1
  4. package/dist/__tests__/installer.test.js +3 -1
  5. package/dist/__tests__/installer.test.js.map +1 -1
  6. package/dist/__tests__/notepad.test.d.ts +2 -0
  7. package/dist/__tests__/notepad.test.d.ts.map +1 -0
  8. package/dist/__tests__/notepad.test.js +374 -0
  9. package/dist/__tests__/notepad.test.js.map +1 -0
  10. package/dist/__tests__/ralph-prd.test.d.ts +2 -0
  11. package/dist/__tests__/ralph-prd.test.d.ts.map +1 -0
  12. package/dist/__tests__/ralph-prd.test.js +308 -0
  13. package/dist/__tests__/ralph-prd.test.js.map +1 -0
  14. package/dist/__tests__/ralph-progress.test.d.ts +2 -0
  15. package/dist/__tests__/ralph-progress.test.d.ts.map +1 -0
  16. package/dist/__tests__/ralph-progress.test.js +312 -0
  17. package/dist/__tests__/ralph-progress.test.js.map +1 -0
  18. package/dist/__tests__/skills.test.js +5 -3
  19. package/dist/__tests__/skills.test.js.map +1 -1
  20. package/dist/agents/definitions.d.ts +4 -0
  21. package/dist/agents/definitions.d.ts.map +1 -1
  22. package/dist/agents/definitions.js +147 -3
  23. package/dist/agents/definitions.js.map +1 -1
  24. package/dist/agents/index.d.ts +1 -0
  25. package/dist/agents/index.d.ts.map +1 -1
  26. package/dist/agents/index.js +2 -0
  27. package/dist/agents/index.js.map +1 -1
  28. package/dist/agents/prometheus.js +2 -2
  29. package/dist/agents/prometheus.js.map +1 -1
  30. package/dist/cli/index.js +6 -4
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/features/builtin-skills/skills.d.ts.map +1 -1
  33. package/dist/features/builtin-skills/skills.js +61 -0
  34. package/dist/features/builtin-skills/skills.js.map +1 -1
  35. package/dist/features/magic-keywords.js +1 -1
  36. package/dist/hooks/index.d.ts +5 -1
  37. package/dist/hooks/index.d.ts.map +1 -1
  38. package/dist/hooks/index.js +15 -1
  39. package/dist/hooks/index.js.map +1 -1
  40. package/dist/hooks/notepad/index.d.ts +114 -0
  41. package/dist/hooks/notepad/index.d.ts.map +1 -0
  42. package/dist/hooks/notepad/index.js +372 -0
  43. package/dist/hooks/notepad/index.js.map +1 -0
  44. package/dist/hooks/persistent-mode/index.d.ts +5 -0
  45. package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
  46. package/dist/hooks/persistent-mode/index.js +71 -5
  47. package/dist/hooks/persistent-mode/index.js.map +1 -1
  48. package/dist/hooks/ralph-loop/index.d.ts +48 -0
  49. package/dist/hooks/ralph-loop/index.d.ts.map +1 -1
  50. package/dist/hooks/ralph-loop/index.js +127 -0
  51. package/dist/hooks/ralph-loop/index.js.map +1 -1
  52. package/dist/hooks/ralph-prd/index.d.ts +130 -0
  53. package/dist/hooks/ralph-prd/index.d.ts.map +1 -0
  54. package/dist/hooks/ralph-prd/index.js +310 -0
  55. package/dist/hooks/ralph-prd/index.js.map +1 -0
  56. package/dist/hooks/ralph-progress/index.d.ts +102 -0
  57. package/dist/hooks/ralph-progress/index.d.ts.map +1 -0
  58. package/dist/hooks/ralph-progress/index.js +408 -0
  59. package/dist/hooks/ralph-progress/index.js.map +1 -0
  60. package/dist/hooks/sisyphus-orchestrator/index.d.ts.map +1 -1
  61. package/dist/hooks/sisyphus-orchestrator/index.js +26 -0
  62. package/dist/hooks/sisyphus-orchestrator/index.js.map +1 -1
  63. package/dist/hooks/ultraqa-loop/index.d.ts +94 -0
  64. package/dist/hooks/ultraqa-loop/index.d.ts.map +1 -0
  65. package/dist/hooks/ultraqa-loop/index.js +216 -0
  66. package/dist/hooks/ultraqa-loop/index.js.map +1 -0
  67. package/dist/installer/hooks.d.ts +28 -0
  68. package/dist/installer/hooks.d.ts.map +1 -1
  69. package/dist/installer/hooks.js +262 -2
  70. package/dist/installer/hooks.js.map +1 -1
  71. package/dist/installer/index.d.ts +1 -1
  72. package/dist/installer/index.d.ts.map +1 -1
  73. package/dist/installer/index.js +533 -23
  74. package/dist/installer/index.js.map +1 -1
  75. package/package.json +1 -1
  76. package/scripts/install.sh +119 -16
  77. package/scripts/persistent-mode.mjs +167 -6
  78. package/scripts/post-tool-verifier.mjs +62 -1
  79. package/scripts/session-start.mjs +22 -0
  80. package/scripts/test-max-attempts.ts +94 -0
  81. package/scripts/test-mutual-exclusion.ts +152 -0
  82. package/scripts/test-notepad-integration.ts +495 -0
  83. package/scripts/test-remember-tags.ts +121 -0
  84. package/scripts/test-session-injection.ts +41 -0
  85. package/scripts/uninstall.sh +1 -0
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Test script for max-attempts counter in todo-continuation
4
+ *
5
+ * Tests the resetTodoContinuationAttempts functionality to verify
6
+ * that the counter tracking mechanism works correctly.
7
+ */
8
+
9
+ import { resetTodoContinuationAttempts, checkPersistentModes } from '../src/hooks/persistent-mode/index.js';
10
+
11
+ async function runTests() {
12
+ console.log('Testing max-attempts counter...\n');
13
+
14
+ let testsPassed = 0;
15
+ let testsFailed = 0;
16
+
17
+ // Test 1: Basic reset functionality
18
+ try {
19
+ console.log('Test 1: Basic reset (should not throw)');
20
+ resetTodoContinuationAttempts('test-session-1');
21
+ console.log('✓ PASS: resetTodoContinuationAttempts executed without error\n');
22
+ testsPassed++;
23
+ } catch (error) {
24
+ console.error('✗ FAIL: resetTodoContinuationAttempts threw error:', error);
25
+ testsFailed++;
26
+ }
27
+
28
+ // Test 2: Multiple resets on same session
29
+ try {
30
+ console.log('Test 2: Multiple resets on same session');
31
+ resetTodoContinuationAttempts('test-session-2');
32
+ resetTodoContinuationAttempts('test-session-2');
33
+ resetTodoContinuationAttempts('test-session-2');
34
+ console.log('✓ PASS: Multiple resets work correctly\n');
35
+ testsPassed++;
36
+ } catch (error) {
37
+ console.error('✗ FAIL: Multiple resets failed:', error);
38
+ testsFailed++;
39
+ }
40
+
41
+ // Test 3: Reset different sessions
42
+ try {
43
+ console.log('Test 3: Reset different sessions');
44
+ resetTodoContinuationAttempts('session-a');
45
+ resetTodoContinuationAttempts('session-b');
46
+ resetTodoContinuationAttempts('session-c');
47
+ console.log('✓ PASS: Can reset different sessions independently\n');
48
+ testsPassed++;
49
+ } catch (error) {
50
+ console.error('✗ FAIL: Different session resets failed:', error);
51
+ testsFailed++;
52
+ }
53
+
54
+ // Test 4: Indirect test via checkPersistentModes (no todos should not throw)
55
+ try {
56
+ console.log('Test 4: Indirect test via checkPersistentModes');
57
+ const result = await checkPersistentModes('test-session-indirect');
58
+ console.log(`✓ PASS: checkPersistentModes executed (shouldBlock=${result.shouldBlock}, mode=${result.mode})\n`);
59
+ testsPassed++;
60
+ } catch (error) {
61
+ console.error('✗ FAIL: checkPersistentModes threw error:', error);
62
+ testsFailed++;
63
+ }
64
+
65
+ // Test 5: Reset with empty string session ID
66
+ try {
67
+ console.log('Test 5: Reset with empty string session ID');
68
+ resetTodoContinuationAttempts('');
69
+ console.log('✓ PASS: Empty session ID handled correctly\n');
70
+ testsPassed++;
71
+ } catch (error) {
72
+ console.error('✗ FAIL: Empty session ID failed:', error);
73
+ testsFailed++;
74
+ }
75
+
76
+ // Summary
77
+ console.log('═══════════════════════════════════════');
78
+ console.log('SUMMARY');
79
+ console.log('═══════════════════════════════════════');
80
+ console.log(`Total tests: ${testsPassed + testsFailed}`);
81
+ console.log(`Passed: ${testsPassed}`);
82
+ console.log(`Failed: ${testsFailed}`);
83
+ console.log('═══════════════════════════════════════\n');
84
+
85
+ if (testsFailed === 0) {
86
+ console.log('✓ ALL TESTS PASSED');
87
+ process.exit(0);
88
+ } else {
89
+ console.log('✗ SOME TESTS FAILED');
90
+ process.exit(1);
91
+ }
92
+ }
93
+
94
+ runTests();
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ import { mkdtempSync, rmSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { tmpdir } from 'os';
6
+ import { mkdirSync } from 'fs';
7
+
8
+ // Import the hooks
9
+ import { startUltraQA, clearUltraQAState, isRalphLoopActive } from '../src/hooks/ultraqa-loop/index.js';
10
+ import { createRalphLoopHook, clearRalphState, isUltraQAActive } from '../src/hooks/ralph-loop/index.js';
11
+
12
+ // Test utilities
13
+ function printTest(testName: string, passed: boolean) {
14
+ const status = passed ? '\x1b[32m✓ PASS\x1b[0m' : '\x1b[31m✗ FAIL\x1b[0m';
15
+ console.log(`${status} - ${testName}`);
16
+ }
17
+
18
+ async function runTests() {
19
+ console.log('\n=== Testing Mutual Exclusion Between UltraQA and Ralph Loop ===\n');
20
+
21
+ // Create temp directory with .sisyphus subfolder
22
+ const tempDir = mkdtempSync(join(tmpdir(), 'sisyphus-test-'));
23
+ const sisyphusDir = join(tempDir, '.sisyphus');
24
+ mkdirSync(sisyphusDir, { recursive: true });
25
+
26
+ console.log(`Using temp directory: ${tempDir}\n`);
27
+
28
+ let allTestsPassed = true;
29
+
30
+ try {
31
+ // Test 1: Start Ralph Loop, try to start UltraQA - should fail
32
+ console.log('Test 1: Ralph Loop blocks UltraQA');
33
+ console.log(' - Starting Ralph Loop...');
34
+
35
+ const ralphHook = createRalphLoopHook(tempDir);
36
+ const ralphStarted = ralphHook.startLoop(
37
+ 'test-session-1',
38
+ 'test task',
39
+ { maxIterations: 5, completionPromise: 'TASK_COMPLETE' }
40
+ );
41
+
42
+ if (!ralphStarted) {
43
+ console.log(' Failed to start Ralph Loop');
44
+ allTestsPassed = false;
45
+ }
46
+
47
+ console.log(' - Attempting to start UltraQA (should fail)...');
48
+ const ultraQAResult1 = startUltraQA(
49
+ tempDir,
50
+ 'all-tests-pass',
51
+ 'test-session-2'
52
+ );
53
+
54
+ if (ultraQAResult1.success) {
55
+ printTest('Test 1: UltraQA should be blocked by Ralph Loop', false);
56
+ allTestsPassed = false;
57
+ } else if (ultraQAResult1.error?.includes('Ralph Loop is active')) {
58
+ printTest('Test 1: UltraQA correctly blocked by Ralph Loop', true);
59
+ } else {
60
+ printTest('Test 1: UltraQA correctly blocked by Ralph Loop', false);
61
+ console.log(` Unexpected error: ${ultraQAResult1.error}`);
62
+ allTestsPassed = false;
63
+ }
64
+
65
+ // Clear Ralph state
66
+ console.log(' - Clearing Ralph state...\n');
67
+ clearRalphState(tempDir);
68
+
69
+ // Test 2: Start UltraQA, try to start Ralph Loop - should fail
70
+ console.log('Test 2: UltraQA blocks Ralph Loop');
71
+ console.log(' - Starting UltraQA...');
72
+
73
+ const ultraQAResult2 = startUltraQA(
74
+ tempDir,
75
+ 'all-tests-pass',
76
+ 'test-session-3'
77
+ );
78
+
79
+ if (!ultraQAResult2.success) {
80
+ console.log(` Failed to start UltraQA: ${ultraQAResult2.error}`);
81
+ allTestsPassed = false;
82
+ }
83
+
84
+ console.log(' - Attempting to start Ralph Loop (should fail)...');
85
+ const ralphHook2 = createRalphLoopHook(tempDir);
86
+ const ralphStarted2 = ralphHook2.startLoop(
87
+ 'test-session-4',
88
+ 'test task',
89
+ { maxIterations: 5, completionPromise: 'TASK_COMPLETE' }
90
+ );
91
+
92
+ if (ralphStarted2) {
93
+ printTest('Test 2: Ralph Loop should be blocked by UltraQA', false);
94
+ allTestsPassed = false;
95
+ } else {
96
+ // Check if it was blocked due to UltraQA
97
+ if (isUltraQAActive(tempDir)) {
98
+ printTest('Test 2: Ralph Loop correctly blocked by UltraQA', true);
99
+ } else {
100
+ printTest('Test 2: Ralph Loop correctly blocked by UltraQA', false);
101
+ console.log(` Ralph Loop failed but UltraQA is not active`);
102
+ allTestsPassed = false;
103
+ }
104
+ }
105
+
106
+ // Clear UltraQA state
107
+ console.log(' - Clearing UltraQA state...\n');
108
+ clearUltraQAState(tempDir);
109
+
110
+ // Test 3: Start UltraQA without any blockers - should succeed
111
+ console.log('Test 3: UltraQA starts without blockers');
112
+ console.log(' - Attempting to start UltraQA (should succeed)...');
113
+ const ultraQAResult3 = startUltraQA(
114
+ tempDir,
115
+ 'all-tests-pass',
116
+ 'test-session-5'
117
+ );
118
+
119
+ if (ultraQAResult3.success) {
120
+ printTest('Test 3: UltraQA starts successfully without blockers', true);
121
+ } else {
122
+ printTest('Test 3: UltraQA should start without blockers', false);
123
+ console.log(` Unexpected error: ${ultraQAResult3.error}`);
124
+ allTestsPassed = false;
125
+ }
126
+
127
+ // Final cleanup
128
+ console.log(' - Clearing UltraQA state...\n');
129
+ clearUltraQAState(tempDir);
130
+
131
+ } finally {
132
+ // Clean up temp directory
133
+ console.log(`Cleaning up temp directory: ${tempDir}`);
134
+ rmSync(tempDir, { recursive: true, force: true });
135
+ }
136
+
137
+ // Summary
138
+ console.log('\n=== Test Summary ===');
139
+ if (allTestsPassed) {
140
+ console.log('\x1b[32m✓ All tests passed!\x1b[0m\n');
141
+ process.exit(0);
142
+ } else {
143
+ console.log('\x1b[31m✗ Some tests failed\x1b[0m\n');
144
+ process.exit(1);
145
+ }
146
+ }
147
+
148
+ // Run tests
149
+ runTests().catch(error => {
150
+ console.error('\x1b[31mTest execution failed:\x1b[0m', error);
151
+ process.exit(1);
152
+ });