oh-my-claude-sisyphus 2.2.0 → 2.2.1
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.
- package/README.md +20 -4
- package/package.json +1 -1
- package/scripts/persistent-mode.mjs +31 -2
- package/scripts/pre-tool-enforcer.mjs +48 -21
package/README.md
CHANGED
|
@@ -2,11 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
-
# 🚀 v2.
|
|
6
|
-
|
|
7
|
-
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus/releases)
|
|
8
|
+
[](https://www.npmjs.com/package/oh-my-claude-sisyphus)
|
|
9
|
+
[](https://www.npmjs.com/package/oh-my-claude-sisyphus)
|
|
10
|
+
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus/stargazers)
|
|
11
|
+
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus/network/members)
|
|
12
|
+
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus/issues)
|
|
13
|
+
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus/commits)
|
|
8
14
|
[](https://opensource.org/licenses/MIT)
|
|
15
|
+
|
|
16
|
+
[](https://nodejs.org/)
|
|
17
|
+
[](https://www.typescriptlang.org/)
|
|
18
|
+
[](https://docs.anthropic.com/claude-code)
|
|
19
|
+
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus/pulls)
|
|
20
|
+
|
|
9
21
|
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus)
|
|
22
|
+
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus)
|
|
23
|
+
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus)
|
|
10
24
|
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus)
|
|
11
25
|
[](https://github.com/Yeachan-Heo/oh-my-claude-sisyphus)
|
|
12
26
|
|
|
@@ -225,6 +239,7 @@ claude
|
|
|
225
239
|
| `/orchestrator <task>` | Complex multi-step task coordination |
|
|
226
240
|
| `/ralph-loop <task>` | Self-referential loop until task completion |
|
|
227
241
|
| `/cancel-ralph` | Cancel active Ralph Loop |
|
|
242
|
+
| `/doctor` | Diagnose and fix installation issues |
|
|
228
243
|
|
|
229
244
|
### Examples
|
|
230
245
|
|
|
@@ -326,7 +341,7 @@ Oh-my-claude-sisyphus includes 18 lifecycle hooks that enhance Claude Code's beh
|
|
|
326
341
|
|
|
327
342
|
## Builtin Skills
|
|
328
343
|
|
|
329
|
-
|
|
344
|
+
Eight builtin skills provide specialized capabilities:
|
|
330
345
|
|
|
331
346
|
| Skill | Description |
|
|
332
347
|
|-------|-------------|
|
|
@@ -337,6 +352,7 @@ Seven builtin skills provide specialized capabilities:
|
|
|
337
352
|
| **ralph-loop** | Self-referential development until completion |
|
|
338
353
|
| **frontend-ui-ux** | Designer-turned-developer UI/UX expertise |
|
|
339
354
|
| **git-master** | Git expert for atomic commits and history |
|
|
355
|
+
| **doctor** | Diagnose and fix installation issues |
|
|
340
356
|
|
|
341
357
|
Skills are automatically activated via slash commands or magic keywords.
|
|
342
358
|
|
package/package.json
CHANGED
|
@@ -177,6 +177,17 @@ ${ralphState.prompt ? `Original task: ${ralphState.prompt}` : ''}
|
|
|
177
177
|
// Priority 2: Ultrawork with incomplete todos
|
|
178
178
|
if (ultraworkState?.active && incompleteCount > 0) {
|
|
179
179
|
const newCount = (ultraworkState.reinforcement_count || 0) + 1;
|
|
180
|
+
const maxReinforcements = ultraworkState.max_reinforcements || 10;
|
|
181
|
+
|
|
182
|
+
// Escape mechanism: after max reinforcements, allow stopping
|
|
183
|
+
if (newCount > maxReinforcements) {
|
|
184
|
+
console.log(JSON.stringify({
|
|
185
|
+
continue: true,
|
|
186
|
+
reason: `[ULTRAWORK ESCAPE] Maximum reinforcements (${maxReinforcements}) reached. Allowing stop despite ${incompleteCount} incomplete todos. If tasks are genuinely stuck, consider cancelling them or asking the user for help.`
|
|
187
|
+
}));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
180
191
|
ultraworkState.reinforcement_count = newCount;
|
|
181
192
|
ultraworkState.last_checked_at = new Date().toISOString();
|
|
182
193
|
|
|
@@ -209,13 +220,31 @@ ${ultraworkState.original_prompt ? `Original task: ${ultraworkState.original_pro
|
|
|
209
220
|
return;
|
|
210
221
|
}
|
|
211
222
|
|
|
212
|
-
// Priority 3: Todo Continuation
|
|
223
|
+
// Priority 3: Todo Continuation (with escape mechanism)
|
|
213
224
|
if (incompleteCount > 0) {
|
|
225
|
+
// Track continuation attempts in a lightweight way
|
|
226
|
+
const contFile = join(directory, '.sisyphus', 'continuation-count.json');
|
|
227
|
+
let contState = readJsonFile(contFile) || { count: 0 };
|
|
228
|
+
contState.count = (contState.count || 0) + 1;
|
|
229
|
+
contState.last_checked_at = new Date().toISOString();
|
|
230
|
+
writeJsonFile(contFile, contState);
|
|
231
|
+
|
|
232
|
+
const maxContinuations = 15;
|
|
233
|
+
|
|
234
|
+
// Escape mechanism: after max continuations, allow stopping
|
|
235
|
+
if (contState.count > maxContinuations) {
|
|
236
|
+
console.log(JSON.stringify({
|
|
237
|
+
continue: true,
|
|
238
|
+
reason: `[TODO ESCAPE] Maximum continuation attempts (${maxContinuations}) reached. Allowing stop despite ${incompleteCount} incomplete todos. Tasks may be stuck - consider reviewing and clearing them.`
|
|
239
|
+
}));
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
214
243
|
console.log(JSON.stringify({
|
|
215
244
|
continue: false,
|
|
216
245
|
reason: `<todo-continuation>
|
|
217
246
|
|
|
218
|
-
[SYSTEM REMINDER - TODO CONTINUATION]
|
|
247
|
+
[SYSTEM REMINDER - TODO CONTINUATION ${contState.count}/${maxContinuations}]
|
|
219
248
|
|
|
220
249
|
Incomplete tasks remain in your todo list (${incompleteCount} remaining). Continue working on the next pending task.
|
|
221
250
|
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* Cross-platform: Windows, macOS, Linux
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { existsSync, readFileSync } from 'fs';
|
|
9
|
+
import { existsSync, readFileSync, readdirSync } from 'fs';
|
|
10
10
|
import { join } from 'path';
|
|
11
|
+
import { homedir } from 'os';
|
|
11
12
|
|
|
12
13
|
// Read all stdin
|
|
13
14
|
async function readStdin() {
|
|
@@ -30,31 +31,57 @@ function extractJsonField(input, field, defaultValue = '') {
|
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
// Get todo status from project
|
|
34
|
+
// Get todo status from project and global todos
|
|
34
35
|
function getTodoStatus(directory) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
let pending = 0;
|
|
37
|
+
let inProgress = 0;
|
|
38
|
+
|
|
39
|
+
// Check project-local todos
|
|
40
|
+
const localPaths = [
|
|
41
|
+
join(directory, '.sisyphus', 'todos.json'),
|
|
42
|
+
join(directory, '.claude', 'todos.json')
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
for (const todoFile of localPaths) {
|
|
46
|
+
if (existsSync(todoFile)) {
|
|
47
|
+
try {
|
|
48
|
+
const content = readFileSync(todoFile, 'utf-8');
|
|
49
|
+
const data = JSON.parse(content);
|
|
50
|
+
const todos = data.todos || data;
|
|
51
|
+
if (Array.isArray(todos)) {
|
|
52
|
+
pending += todos.filter(t => t.status === 'pending').length;
|
|
53
|
+
inProgress += todos.filter(t => t.status === 'in_progress').length;
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
// Ignore errors
|
|
57
|
+
}
|
|
58
|
+
}
|
|
39
59
|
}
|
|
40
60
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
// Check global Claude Code todos directory
|
|
62
|
+
const globalTodosDir = join(homedir(), '.claude', 'todos');
|
|
63
|
+
if (existsSync(globalTodosDir)) {
|
|
64
|
+
try {
|
|
65
|
+
const files = readdirSync(globalTodosDir).filter(f => f.endsWith('.json'));
|
|
66
|
+
for (const file of files) {
|
|
67
|
+
try {
|
|
68
|
+
const content = readFileSync(join(globalTodosDir, file), 'utf-8');
|
|
69
|
+
const todos = JSON.parse(content);
|
|
70
|
+
if (Array.isArray(todos)) {
|
|
71
|
+
pending += todos.filter(t => t.status === 'pending').length;
|
|
72
|
+
inProgress += todos.filter(t => t.status === 'in_progress').length;
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
// Ignore individual file errors
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} catch {
|
|
79
|
+
// Ignore directory read errors
|
|
48
80
|
}
|
|
81
|
+
}
|
|
49
82
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (pending + inProgress > 0) {
|
|
54
|
-
return `[${inProgress} active, ${pending} pending] `;
|
|
55
|
-
}
|
|
56
|
-
} catch {
|
|
57
|
-
// Ignore errors
|
|
83
|
+
if (pending + inProgress > 0) {
|
|
84
|
+
return `[${inProgress} active, ${pending} pending] `;
|
|
58
85
|
}
|
|
59
86
|
|
|
60
87
|
return '';
|