oh-my-claude-sisyphus 3.8.1 → 3.8.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.
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "name": "oh-my-claudecode",
12
12
  "description": "Claude Code native multi-agent orchestration with intelligent model routing, 28 agent variants, and 30 powerful skills. Zero learning curve. Maximum power.",
13
- "version": "3.8.1",
13
+ "version": "3.8.2",
14
14
  "author": {
15
15
  "name": "Yeachan Heo",
16
16
  "email": "hurrc04@gmail.com"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-claudecode",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Multi-agent orchestration system for Claude Code",
5
5
  "skills": "./skills/",
6
6
  "mcpServers": "./.mcp.json"
package/docs/CLAUDE.md CHANGED
@@ -36,8 +36,29 @@ RULE 1: ALWAYS delegate substantive work to specialized agents
36
36
  RULE 2: ALWAYS invoke appropriate skills for recognized patterns
37
37
  RULE 3: NEVER do code changes directly - delegate to executor
38
38
  RULE 4: NEVER complete without Architect verification
39
+ RULE 5: ALWAYS consult official documentation before implementing with SDKs/frameworks/APIs
39
40
  ```
40
41
 
42
+ ### Documentation-First Development (CRITICAL)
43
+
44
+ **NEVER make assumptions about SDK, framework, or API behavior.**
45
+
46
+ When implementing with any external tool (Claude Code hooks, React, database drivers, etc.):
47
+
48
+ 1. **BEFORE writing code**: Delegate to `researcher` agent to fetch official docs
49
+ 2. **Use Context7 MCP tools**: `resolve-library-id` → `query-docs` for up-to-date documentation
50
+ 3. **Verify API contracts**: Check actual schemas, return types, and field names
51
+ 4. **No guessing**: If docs are unclear, search for examples or ask the user
52
+
53
+ **Why this matters**: Assumptions about undocumented fields (like using `message` instead of `hookSpecificOutput.additionalContext`) lead to silent failures that are hard to debug.
54
+
55
+ | Situation | Action |
56
+ |-----------|--------|
57
+ | Using a new SDK/API | Delegate to `researcher` first |
58
+ | Implementing hooks/plugins | Verify output schema from official docs |
59
+ | Uncertain about field names | Query official documentation |
60
+ | Copying from old code | Verify pattern still valid |
61
+
41
62
  ### What You Do vs. Delegate
42
63
 
43
64
  | Action | YOU Do Directly | DELEGATE to Agent |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-claude-sisyphus",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
4
4
  "description": "Multi-agent orchestration system for Claude Code - Inspired by oh-my-opencode",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -134,6 +134,20 @@ ${originalPrompt}
134
134
  IMPORTANT: Invoke the skill IMMEDIATELY. Do not proceed without loading the skill instructions.`;
135
135
  }
136
136
 
137
+ /**
138
+ * Create proper hook output with additionalContext (Claude Code hooks API)
139
+ * The 'message' field is NOT a valid hook output - use hookSpecificOutput.additionalContext
140
+ */
141
+ function createHookOutput(additionalContext) {
142
+ return {
143
+ continue: true,
144
+ hookSpecificOutput: {
145
+ hookEventName: 'UserPromptSubmit',
146
+ additionalContext
147
+ }
148
+ };
149
+ }
150
+
137
151
  // Main
138
152
  async function main() {
139
153
  try {
@@ -161,10 +175,7 @@ async function main() {
161
175
  if (/\b(stop|cancel|abort)\b/i.test(cleanPrompt)) {
162
176
  // Special: clear state files instead of creating them
163
177
  clearStateFiles(directory, ['ralph', 'autopilot', 'ultrapilot', 'ultrawork', 'ecomode', 'swarm', 'pipeline']);
164
- console.log(JSON.stringify({
165
- continue: true,
166
- message: createSkillInvocation('cancel', prompt)
167
- }));
178
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('cancel', prompt))));
168
179
  return;
169
180
  }
170
181
 
@@ -172,10 +183,7 @@ async function main() {
172
183
  if (/\b(ralph|don't stop|must complete|until done)\b/i.test(cleanPrompt)) {
173
184
  activateState(directory, prompt, 'ralph');
174
185
  activateState(directory, prompt, 'ultrawork');
175
- console.log(JSON.stringify({
176
- continue: true,
177
- message: createSkillInvocation('ralph', prompt)
178
- }));
186
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('ralph', prompt))));
179
187
  return;
180
188
  }
181
189
 
@@ -190,10 +198,7 @@ async function main() {
190
198
  /\bend\s+to\s+end\b/i.test(cleanPrompt) ||
191
199
  /\be2e\s+this\b/i.test(cleanPrompt)) {
192
200
  activateState(directory, prompt, 'autopilot');
193
- console.log(JSON.stringify({
194
- continue: true,
195
- message: createSkillInvocation('autopilot', prompt)
196
- }));
201
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('autopilot', prompt))));
197
202
  return;
198
203
  }
199
204
 
@@ -202,30 +207,21 @@ async function main() {
202
207
  /\bparallel\s+build\b/i.test(cleanPrompt) ||
203
208
  /\bswarm\s+build\b/i.test(cleanPrompt)) {
204
209
  activateState(directory, prompt, 'ultrapilot');
205
- console.log(JSON.stringify({
206
- continue: true,
207
- message: createSkillInvocation('ultrapilot', prompt)
208
- }));
210
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('ultrapilot', prompt))));
209
211
  return;
210
212
  }
211
213
 
212
214
  // Priority 5: Ultrawork keywords
213
215
  if (/\b(ultrawork|ulw|uw)\b/i.test(cleanPrompt)) {
214
216
  activateState(directory, prompt, 'ultrawork');
215
- console.log(JSON.stringify({
216
- continue: true,
217
- message: createSkillInvocation('ultrawork', prompt)
218
- }));
217
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('ultrawork', prompt))));
219
218
  return;
220
219
  }
221
220
 
222
221
  // Priority 6: Ecomode keywords (includes "efficient")
223
222
  if (/\b(eco|ecomode|eco-mode|efficient|save-tokens|budget)\b/i.test(cleanPrompt)) {
224
223
  activateState(directory, prompt, 'ecomode');
225
- console.log(JSON.stringify({
226
- continue: true,
227
- message: createSkillInvocation('ecomode', prompt)
228
- }));
224
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('ecomode', prompt))));
229
225
  return;
230
226
  }
231
227
 
@@ -233,37 +229,25 @@ async function main() {
233
229
  const swarmMatch = cleanPrompt.match(/\bswarm\s+(\d+)\s+agents?\b/i);
234
230
  if (swarmMatch || /\bcoordinated\s+agents\b/i.test(cleanPrompt)) {
235
231
  const agentCount = swarmMatch ? swarmMatch[1] : '3'; // default 3
236
- console.log(JSON.stringify({
237
- continue: true,
238
- message: createSkillInvocation('swarm', prompt, agentCount)
239
- }));
232
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('swarm', prompt, agentCount))));
240
233
  return;
241
234
  }
242
235
 
243
236
  // Priority 8: Pipeline
244
237
  if (/\b(pipeline)\b/i.test(cleanPrompt) || /\bchain\s+agents\b/i.test(cleanPrompt)) {
245
- console.log(JSON.stringify({
246
- continue: true,
247
- message: createSkillInvocation('pipeline', prompt)
248
- }));
238
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('pipeline', prompt))));
249
239
  return;
250
240
  }
251
241
 
252
242
  // Priority 9: Ralplan keyword (before plan to avoid false match)
253
243
  if (/\b(ralplan)\b/i.test(cleanPrompt)) {
254
- console.log(JSON.stringify({
255
- continue: true,
256
- message: createSkillInvocation('ralplan', prompt)
257
- }));
244
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('ralplan', prompt))));
258
245
  return;
259
246
  }
260
247
 
261
248
  // Priority 10: Plan keywords
262
249
  if (/\b(plan this|plan the)\b/i.test(cleanPrompt)) {
263
- console.log(JSON.stringify({
264
- continue: true,
265
- message: createSkillInvocation('plan', prompt)
266
- }));
250
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('plan', prompt))));
267
251
  return;
268
252
  }
269
253
 
@@ -271,10 +255,7 @@ async function main() {
271
255
  if (/\b(tdd)\b/i.test(cleanPrompt) ||
272
256
  /\btest\s+first\b/i.test(cleanPrompt) ||
273
257
  /\bred\s+green\b/i.test(cleanPrompt)) {
274
- console.log(JSON.stringify({
275
- continue: true,
276
- message: createSkillInvocation('tdd', prompt)
277
- }));
258
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('tdd', prompt))));
278
259
  return;
279
260
  }
280
261
 
@@ -283,16 +264,13 @@ async function main() {
283
264
  if (/\b(research)\b/i.test(cleanPrompt) ||
284
265
  /\banalyze\s+data\b/i.test(cleanPrompt) ||
285
266
  /\bstatistics\b/i.test(cleanPrompt)) {
286
- console.log(JSON.stringify({
287
- continue: true,
288
- message: createSkillInvocation('research', prompt)
289
- }));
267
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('research', prompt))));
290
268
  return;
291
269
  }
292
270
 
293
271
  // Priority 13: Ultrathink/think keywords (keep inline message)
294
272
  if (/\b(ultrathink|think hard|think deeply)\b/i.test(cleanPrompt)) {
295
- console.log(JSON.stringify({ continue: true, message: ULTRATHINK_MESSAGE }));
273
+ console.log(JSON.stringify(createHookOutput(ULTRATHINK_MESSAGE)));
296
274
  return;
297
275
  }
298
276
 
@@ -300,10 +278,7 @@ async function main() {
300
278
  if (/\b(deepsearch)\b/i.test(cleanPrompt) ||
301
279
  /\bsearch\s+(the\s+)?(codebase|code|files?|project)\b/i.test(cleanPrompt) ||
302
280
  /\bfind\s+(in\s+)?(codebase|code|all\s+files?)\b/i.test(cleanPrompt)) {
303
- console.log(JSON.stringify({
304
- continue: true,
305
- message: createSkillInvocation('deepsearch', prompt)
306
- }));
281
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('deepsearch', prompt))));
307
282
  return;
308
283
  }
309
284
 
@@ -311,10 +286,7 @@ async function main() {
311
286
  if (/\b(deep\s*analyze)\b/i.test(cleanPrompt) ||
312
287
  /\binvestigate\s+(the|this|why)\b/i.test(cleanPrompt) ||
313
288
  /\bdebug\s+(the|this|why)\b/i.test(cleanPrompt)) {
314
- console.log(JSON.stringify({
315
- continue: true,
316
- message: createSkillInvocation('analyze', prompt)
317
- }));
289
+ console.log(JSON.stringify(createHookOutput(createSkillInvocation('analyze', prompt))));
318
290
  return;
319
291
  }
320
292
 
@@ -297,13 +297,14 @@ async function main() {
297
297
  }
298
298
  }
299
299
 
300
- // Build response
300
+ // Build response - use hookSpecificOutput.additionalContext for PostToolUse
301
301
  const response = { continue: true };
302
- // Prefer clear suggestion over contextual message (more impactful)
303
- if (clearSuggestionMessage) {
304
- response.message = clearSuggestionMessage;
305
- } else if (message) {
306
- response.message = message;
302
+ const contextMessage = clearSuggestionMessage || message;
303
+ if (contextMessage) {
304
+ response.hookSpecificOutput = {
305
+ hookEventName: 'PostToolUse',
306
+ additionalContext: contextMessage
307
+ };
307
308
  }
308
309
 
309
310
  console.log(JSON.stringify(response, null, 2));
@@ -115,7 +115,10 @@ async function main() {
115
115
 
116
116
  console.log(JSON.stringify({
117
117
  continue: true,
118
- message: message
118
+ hookSpecificOutput: {
119
+ hookEventName: 'PreToolUse',
120
+ additionalContext: message
121
+ }
119
122
  }, null, 2));
120
123
  } catch (error) {
121
124
  // On error, always continue
@@ -171,7 +171,13 @@ ${cleanContent}
171
171
  }
172
172
 
173
173
  if (messages.length > 0) {
174
- console.log(JSON.stringify({ continue: true, message: messages.join('\n') }));
174
+ console.log(JSON.stringify({
175
+ continue: true,
176
+ hookSpecificOutput: {
177
+ hookEventName: 'SessionStart',
178
+ additionalContext: messages.join('\n')
179
+ }
180
+ }));
175
181
  } else {
176
182
  console.log(JSON.stringify({ continue: true }));
177
183
  }
@@ -268,7 +268,10 @@ async function main() {
268
268
  if (matchingSkills.length > 0) {
269
269
  console.log(JSON.stringify({
270
270
  continue: true,
271
- message: formatSkillsMessage(matchingSkills)
271
+ hookSpecificOutput: {
272
+ hookEventName: 'UserPromptSubmit',
273
+ additionalContext: formatSkillsMessage(matchingSkills)
274
+ }
272
275
  }));
273
276
  } else {
274
277
  console.log(JSON.stringify({ continue: true }));