oh-my-claude-sisyphus 3.7.16 → 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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +8 -6
- package/agents/AGENTS.md +8 -8
- package/agents/architect.md +32 -0
- package/agents/build-fixer.md +35 -0
- package/agents/code-reviewer.md +51 -0
- package/agents/executor-high.md +49 -0
- package/agents/explore-high.md +39 -0
- package/agents/explore-medium.md +33 -0
- package/dist/__tests__/hooks/learner/bridge.test.js +13 -7
- package/dist/__tests__/hooks/learner/bridge.test.js.map +1 -1
- package/dist/__tests__/hooks.test.js +306 -67
- package/dist/__tests__/hooks.test.js.map +1 -1
- package/dist/__tests__/installer.test.js +31 -15
- package/dist/__tests__/installer.test.js.map +1 -1
- package/dist/hooks/bridge.js +3 -3
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/clear-suggestions/constants.d.ts +54 -0
- package/dist/hooks/clear-suggestions/constants.d.ts.map +1 -0
- package/dist/hooks/clear-suggestions/constants.js +102 -0
- package/dist/hooks/clear-suggestions/constants.js.map +1 -0
- package/dist/hooks/clear-suggestions/index.d.ts +61 -0
- package/dist/hooks/clear-suggestions/index.d.ts.map +1 -0
- package/dist/hooks/clear-suggestions/index.js +276 -0
- package/dist/hooks/clear-suggestions/index.js.map +1 -0
- package/dist/hooks/clear-suggestions/triggers.d.ts +65 -0
- package/dist/hooks/clear-suggestions/triggers.d.ts.map +1 -0
- package/dist/hooks/clear-suggestions/triggers.js +222 -0
- package/dist/hooks/clear-suggestions/triggers.js.map +1 -0
- package/dist/hooks/clear-suggestions/types.d.ts +92 -0
- package/dist/hooks/clear-suggestions/types.d.ts.map +1 -0
- package/dist/hooks/clear-suggestions/types.js +9 -0
- package/dist/hooks/clear-suggestions/types.js.map +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/keyword-detector/__tests__/index.test.js +51 -51
- package/dist/hooks/keyword-detector/__tests__/index.test.js.map +1 -1
- package/dist/hooks/keyword-detector/index.d.ts +1 -1
- package/dist/hooks/keyword-detector/index.d.ts.map +1 -1
- package/dist/hooks/keyword-detector/index.js +18 -5
- package/dist/hooks/keyword-detector/index.js.map +1 -1
- package/docs/CLAUDE.md +104 -0
- package/package.json +1 -1
- package/scripts/keyword-detector.mjs +176 -84
- package/scripts/post-tool-verifier.mjs +42 -3
- package/scripts/pre-tool-enforcer.mjs +4 -1
- package/scripts/session-start.mjs +7 -1
- package/scripts/skill-injector.mjs +4 -1
- package/templates/hooks/keyword-detector.sh +197 -31
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 |
|
|
@@ -309,6 +330,89 @@ Always use `oh-my-claudecode:` prefix when calling via Task tool.
|
|
|
309
330
|
| Data analysis/stats | `scientist` | sonnet |
|
|
310
331
|
| Quick data inspection | `scientist-low` | haiku |
|
|
311
332
|
| Complex ML/hypothesis | `scientist-high` | opus |
|
|
333
|
+
| Find symbol references | `explore-high` | opus |
|
|
334
|
+
| Get file/workspace symbol outline | `explore` | haiku |
|
|
335
|
+
| Structural code pattern search | `explore` | haiku |
|
|
336
|
+
| Structural code transformation | `executor-high` | opus |
|
|
337
|
+
| Project-wide type checking | `build-fixer` | sonnet |
|
|
338
|
+
| Check single file for errors | `executor-low` | haiku |
|
|
339
|
+
| Data analysis / computation | `scientist` | sonnet |
|
|
340
|
+
|
|
341
|
+
### MCP Tools & Agent Capabilities
|
|
342
|
+
|
|
343
|
+
*Source of truth: `src/agents/definitions.ts`*
|
|
344
|
+
|
|
345
|
+
#### Tool Inventory
|
|
346
|
+
|
|
347
|
+
| Tool | Category | Purpose | Assigned to Agents? |
|
|
348
|
+
|------|----------|---------|---------------------|
|
|
349
|
+
| `lsp_hover` | LSP | Get type info and documentation at a code position | NO (orchestrator-direct) |
|
|
350
|
+
| `lsp_goto_definition` | LSP | Jump to where a symbol is defined | NO (orchestrator-direct) |
|
|
351
|
+
| `lsp_find_references` | LSP | Find all usages of a symbol across the codebase | YES (`explore-high` only) |
|
|
352
|
+
| `lsp_document_symbols` | LSP | Get outline of all symbols in a file | YES |
|
|
353
|
+
| `lsp_workspace_symbols` | LSP | Search for symbols by name across the workspace | YES |
|
|
354
|
+
| `lsp_diagnostics` | LSP | Get errors, warnings, and hints for a file | YES |
|
|
355
|
+
| `lsp_diagnostics_directory` | LSP | Project-level type checking (tsc --noEmit or LSP) | YES |
|
|
356
|
+
| `lsp_prepare_rename` | LSP | Check if a symbol can be renamed | NO (orchestrator-direct) |
|
|
357
|
+
| `lsp_rename` | LSP | Rename a symbol across the entire project | NO (orchestrator-direct) |
|
|
358
|
+
| `lsp_code_actions` | LSP | Get available refactorings and quick fixes | NO (orchestrator-direct) |
|
|
359
|
+
| `lsp_code_action_resolve` | LSP | Get full edit details for a code action | NO (orchestrator-direct) |
|
|
360
|
+
| `lsp_servers` | LSP | List available language servers and install status | NO (orchestrator-direct) |
|
|
361
|
+
| `ast_grep_search` | AST | Pattern-based structural code search using AST | YES |
|
|
362
|
+
| `ast_grep_replace` | AST | Pattern-based structural code transformation | YES (`executor-high` only) |
|
|
363
|
+
| `python_repl` | Data | Persistent Python REPL for data analysis and computation | YES |
|
|
364
|
+
|
|
365
|
+
#### Agent Tool Matrix (MCP Tools Only)
|
|
366
|
+
|
|
367
|
+
| Agent | LSP Diagnostics | LSP Dir Diagnostics | LSP Symbols | LSP References | AST Search | AST Replace | Python REPL |
|
|
368
|
+
|-------|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|
|
369
|
+
| `explore` | - | - | doc + workspace | - | yes | - | - |
|
|
370
|
+
| `explore-medium` | - | - | doc + workspace | - | yes | - | - |
|
|
371
|
+
| `explore-high` | - | - | doc + workspace | yes | yes | - | - |
|
|
372
|
+
| `architect-low` | yes | - | - | - | - | - | - |
|
|
373
|
+
| `architect-medium` | yes | yes | - | - | yes | - | - |
|
|
374
|
+
| `architect` | yes | yes | - | - | yes | - | - |
|
|
375
|
+
| `executor-low` | yes | - | - | - | - | - | - |
|
|
376
|
+
| `executor` | yes | yes | - | - | - | - | - |
|
|
377
|
+
| `executor-high` | yes | yes | - | - | yes | yes | - |
|
|
378
|
+
| `build-fixer` | yes | yes | - | - | - | - | - |
|
|
379
|
+
| `build-fixer-low` | yes | yes | - | - | - | - | - |
|
|
380
|
+
| `tdd-guide` | yes | - | - | - | - | - | - |
|
|
381
|
+
| `tdd-guide-low` | yes | - | - | - | - | - | - |
|
|
382
|
+
| `code-reviewer` | yes | - | - | - | yes | - | - |
|
|
383
|
+
| `code-reviewer-low` | yes | - | - | - | - | - | - |
|
|
384
|
+
| `qa-tester` | yes | - | - | - | - | - | - |
|
|
385
|
+
| `qa-tester-high` | yes | - | - | - | - | - | - |
|
|
386
|
+
| `scientist-low` | - | - | - | - | - | - | yes |
|
|
387
|
+
| `scientist` | - | - | - | - | - | - | yes |
|
|
388
|
+
| `scientist-high` | - | - | - | - | - | - | yes |
|
|
389
|
+
|
|
390
|
+
#### Unassigned Tools (Orchestrator-Direct)
|
|
391
|
+
|
|
392
|
+
The following 7 MCP tools are NOT assigned to any agent. Use directly when needed:
|
|
393
|
+
|
|
394
|
+
| Tool | When to Use Directly |
|
|
395
|
+
|------|---------------------|
|
|
396
|
+
| `lsp_hover` | Quick type lookups during conversation |
|
|
397
|
+
| `lsp_goto_definition` | Navigating to symbol definitions during analysis |
|
|
398
|
+
| `lsp_prepare_rename` | Checking rename feasibility before deciding on approach |
|
|
399
|
+
| `lsp_rename` | Safe rename operations (returns edit preview, does not auto-apply) |
|
|
400
|
+
| `lsp_code_actions` | Discovering available refactorings |
|
|
401
|
+
| `lsp_code_action_resolve` | Getting details of a specific code action |
|
|
402
|
+
| `lsp_servers` | Checking language server availability |
|
|
403
|
+
|
|
404
|
+
For complex rename or refactoring tasks requiring implementation, delegate to `executor-high` which can use `ast_grep_replace` for structural transformations.
|
|
405
|
+
|
|
406
|
+
#### Tool Selection Guidance
|
|
407
|
+
|
|
408
|
+
- **Need file symbol outline or workspace search?** Use `lsp_document_symbols`/`lsp_workspace_symbols` via `explore`, `explore-medium`, or `explore-high`
|
|
409
|
+
- **Need to find all usages of a symbol?** Use `lsp_find_references` via `explore-high` (only agent with it)
|
|
410
|
+
- **Need structural code patterns?** (e.g., "find all functions matching X shape") Use `ast_grep_search` via `explore` family, `architect`/`architect-medium`, or `code-reviewer`
|
|
411
|
+
- **Need to transform code structurally?** Use `ast_grep_replace` via `executor-high` (only agent with it)
|
|
412
|
+
- **Need project-wide type checking?** Use `lsp_diagnostics_directory` via `architect`/`architect-medium`, `executor`/`executor-high`, or `build-fixer` family
|
|
413
|
+
- **Need single-file error checking?** Use `lsp_diagnostics` via many agents (see matrix)
|
|
414
|
+
- **Need data analysis / computation?** Use `python_repl` via `scientist` agents (all tiers)
|
|
415
|
+
- **Need quick type info or definition lookup?** Use `lsp_hover`/`lsp_goto_definition` directly (orchestrator-direct tools)
|
|
312
416
|
|
|
313
417
|
---
|
|
314
418
|
|
package/package.json
CHANGED
|
@@ -1,51 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* Detects
|
|
4
|
+
* OMC Keyword Detector Hook (Node.js)
|
|
5
|
+
* Detects magic keywords and invokes skill tools
|
|
6
6
|
* Cross-platform: Windows, macOS, Linux
|
|
7
|
+
*
|
|
8
|
+
* Supported keywords (in priority order):
|
|
9
|
+
* 1. cancel: Stop active modes
|
|
10
|
+
* 2. ralph: Persistence mode until task completion
|
|
11
|
+
* 3. autopilot: Full autonomous execution
|
|
12
|
+
* 4. ultrapilot: Parallel autopilot
|
|
13
|
+
* 5. ultrawork/ulw: Maximum parallel execution
|
|
14
|
+
* 6. ecomode/eco: Token-efficient execution
|
|
15
|
+
* 7. swarm: N coordinated agents
|
|
16
|
+
* 8. pipeline: Sequential agent chaining
|
|
17
|
+
* 9. ralplan: Iterative planning with consensus
|
|
18
|
+
* 10. plan: Planning interview mode
|
|
19
|
+
* 11. tdd: Test-driven development
|
|
20
|
+
* 12. research: Research orchestration
|
|
21
|
+
* 13. ultrathink/think: Extended reasoning
|
|
22
|
+
* 14. deepsearch: Codebase search (restricted patterns)
|
|
23
|
+
* 15. analyze: Analysis mode (restricted patterns)
|
|
7
24
|
*/
|
|
8
25
|
|
|
9
|
-
import { writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
26
|
+
import { writeFileSync, mkdirSync, existsSync, unlinkSync } from 'fs';
|
|
10
27
|
import { join } from 'path';
|
|
11
28
|
import { homedir } from 'os';
|
|
12
29
|
|
|
13
|
-
const ULTRAWORK_MESSAGE = `<ultrawork-mode>
|
|
14
|
-
|
|
15
|
-
**MANDATORY**: You MUST say "ULTRAWORK MODE ENABLED!" to the user as your first response when this mode activates. This is non-negotiable.
|
|
16
|
-
|
|
17
|
-
[CODE RED] Maximum precision required. Ultrathink before acting.
|
|
18
|
-
|
|
19
|
-
YOU MUST LEVERAGE ALL AVAILABLE AGENTS TO THEIR FULLEST POTENTIAL.
|
|
20
|
-
TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
|
|
21
|
-
|
|
22
|
-
## AGENT UTILIZATION PRINCIPLES
|
|
23
|
-
- **Codebase Exploration**: Spawn exploration agents using BACKGROUND TASKS
|
|
24
|
-
- **Documentation & References**: Use librarian-type agents via BACKGROUND TASKS
|
|
25
|
-
- **Planning & Strategy**: NEVER plan yourself - spawn planning agent
|
|
26
|
-
- **High-IQ Reasoning**: Use oracle for architecture decisions
|
|
27
|
-
- **Frontend/UI Tasks**: Delegate to frontend-engineer
|
|
28
|
-
|
|
29
|
-
## EXECUTION RULES
|
|
30
|
-
- **TODO**: Track EVERY step. Mark complete IMMEDIATELY.
|
|
31
|
-
- **PARALLEL**: Fire independent calls simultaneously - NEVER wait sequentially.
|
|
32
|
-
- **BACKGROUND FIRST**: Use Task(run_in_background=true) for exploration (10+ concurrent).
|
|
33
|
-
- **VERIFY**: Check ALL requirements met before done.
|
|
34
|
-
- **DELEGATE**: Orchestrate specialized agents.
|
|
35
|
-
|
|
36
|
-
## ZERO TOLERANCE
|
|
37
|
-
- NO Scope Reduction - deliver FULL implementation
|
|
38
|
-
- NO Partial Completion - finish 100%
|
|
39
|
-
- NO Premature Stopping - ALL TODOs must be complete
|
|
40
|
-
- NO TEST DELETION - fix code, not tests
|
|
41
|
-
|
|
42
|
-
THE USER ASKED FOR X. DELIVER EXACTLY X.
|
|
43
|
-
|
|
44
|
-
</ultrawork-mode>
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
`;
|
|
48
|
-
|
|
49
30
|
const ULTRATHINK_MESSAGE = `<think-mode>
|
|
50
31
|
|
|
51
32
|
**ULTRATHINK MODE ENABLED** - Extended reasoning activated.
|
|
@@ -63,34 +44,6 @@ Use your extended thinking capabilities to provide the most thorough and well-re
|
|
|
63
44
|
---
|
|
64
45
|
`;
|
|
65
46
|
|
|
66
|
-
const SEARCH_MESSAGE = `<search-mode>
|
|
67
|
-
MAXIMIZE SEARCH EFFORT. Launch multiple background agents IN PARALLEL:
|
|
68
|
-
- explore agents (codebase patterns, file structures)
|
|
69
|
-
- librarian agents (remote repos, official docs, GitHub examples)
|
|
70
|
-
Plus direct tools: Grep, Glob
|
|
71
|
-
NEVER stop at first result - be exhaustive.
|
|
72
|
-
</search-mode>
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
`;
|
|
76
|
-
|
|
77
|
-
const ANALYZE_MESSAGE = `<analyze-mode>
|
|
78
|
-
ANALYSIS MODE. Gather context before diving deep:
|
|
79
|
-
|
|
80
|
-
CONTEXT GATHERING (parallel):
|
|
81
|
-
- 1-2 explore agents (codebase patterns, implementations)
|
|
82
|
-
- 1-2 librarian agents (if external library involved)
|
|
83
|
-
- Direct tools: Grep, Glob, LSP for targeted searches
|
|
84
|
-
|
|
85
|
-
IF COMPLEX (architecture, multi-system, debugging after 2+ failures):
|
|
86
|
-
- Consult oracle agent for strategic guidance
|
|
87
|
-
|
|
88
|
-
SYNTHESIZE findings before proceeding.
|
|
89
|
-
</analyze-mode>
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
`;
|
|
93
|
-
|
|
94
47
|
// Read all stdin
|
|
95
48
|
async function readStdin() {
|
|
96
49
|
const chunks = [];
|
|
@@ -127,8 +80,8 @@ function removeCodeBlocks(text) {
|
|
|
127
80
|
.replace(/`[^`]+`/g, '');
|
|
128
81
|
}
|
|
129
82
|
|
|
130
|
-
// Create
|
|
131
|
-
function
|
|
83
|
+
// Create state file for a mode
|
|
84
|
+
function activateState(directory, prompt, stateName) {
|
|
132
85
|
const state = {
|
|
133
86
|
active: true,
|
|
134
87
|
started_at: new Date().toISOString(),
|
|
@@ -142,14 +95,57 @@ function activateUltraworkState(directory, prompt) {
|
|
|
142
95
|
if (!existsSync(localDir)) {
|
|
143
96
|
try { mkdirSync(localDir, { recursive: true }); } catch {}
|
|
144
97
|
}
|
|
145
|
-
try { writeFileSync(join(localDir,
|
|
98
|
+
try { writeFileSync(join(localDir, `${stateName}-state.json`), JSON.stringify(state, null, 2)); } catch {}
|
|
146
99
|
|
|
147
100
|
// Write to global .omc/state directory
|
|
148
101
|
const globalDir = join(homedir(), '.omc', 'state');
|
|
149
102
|
if (!existsSync(globalDir)) {
|
|
150
103
|
try { mkdirSync(globalDir, { recursive: true }); } catch {}
|
|
151
104
|
}
|
|
152
|
-
try { writeFileSync(join(globalDir,
|
|
105
|
+
try { writeFileSync(join(globalDir, `${stateName}-state.json`), JSON.stringify(state, null, 2)); } catch {}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Clear state files for cancel operation
|
|
110
|
+
*/
|
|
111
|
+
function clearStateFiles(directory, modeNames) {
|
|
112
|
+
for (const name of modeNames) {
|
|
113
|
+
const localPath = join(directory, '.omc', 'state', `${name}-state.json`);
|
|
114
|
+
const globalPath = join(homedir(), '.omc', 'state', `${name}-state.json`);
|
|
115
|
+
try { if (existsSync(localPath)) unlinkSync(localPath); } catch {}
|
|
116
|
+
try { if (existsSync(globalPath)) unlinkSync(globalPath); } catch {}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Create a skill invocation message that tells Claude to use the Skill tool
|
|
122
|
+
*/
|
|
123
|
+
function createSkillInvocation(skillName, originalPrompt, args = '') {
|
|
124
|
+
const argsSection = args ? `\nArguments: ${args}` : '';
|
|
125
|
+
return `[MAGIC KEYWORD: ${skillName.toUpperCase()}]
|
|
126
|
+
|
|
127
|
+
You MUST invoke the skill using the Skill tool:
|
|
128
|
+
|
|
129
|
+
Skill: oh-my-claudecode:${skillName}${argsSection}
|
|
130
|
+
|
|
131
|
+
User request:
|
|
132
|
+
${originalPrompt}
|
|
133
|
+
|
|
134
|
+
IMPORTANT: Invoke the skill IMMEDIATELY. Do not proceed without loading the skill instructions.`;
|
|
135
|
+
}
|
|
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
|
+
};
|
|
153
149
|
}
|
|
154
150
|
|
|
155
151
|
// Main
|
|
@@ -173,28 +169,124 @@ async function main() {
|
|
|
173
169
|
|
|
174
170
|
const cleanPrompt = removeCodeBlocks(prompt).toLowerCase();
|
|
175
171
|
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
172
|
+
// Priority order: cancel > ralph > autopilot > ultrapilot > ultrawork > ecomode > swarm > pipeline > ralplan > plan > tdd > research > ultrathink > deepsearch > analyze
|
|
173
|
+
|
|
174
|
+
// Priority 1: Cancel (BEFORE other modes - clears states)
|
|
175
|
+
if (/\b(stop|cancel|abort)\b/i.test(cleanPrompt)) {
|
|
176
|
+
// Special: clear state files instead of creating them
|
|
177
|
+
clearStateFiles(directory, ['ralph', 'autopilot', 'ultrapilot', 'ultrawork', 'ecomode', 'swarm', 'pipeline']);
|
|
178
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('cancel', prompt))));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Priority 2: Ralph keywords
|
|
183
|
+
if (/\b(ralph|don't stop|must complete|until done)\b/i.test(cleanPrompt)) {
|
|
184
|
+
activateState(directory, prompt, 'ralph');
|
|
185
|
+
activateState(directory, prompt, 'ultrawork');
|
|
186
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('ralph', prompt))));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Priority 3: Autopilot keywords
|
|
191
|
+
if (/\b(autopilot|auto pilot|auto-pilot|autonomous|full auto|fullsend)\b/i.test(cleanPrompt) ||
|
|
192
|
+
/\bbuild\s+me\s+/i.test(cleanPrompt) ||
|
|
193
|
+
/\bcreate\s+me\s+/i.test(cleanPrompt) ||
|
|
194
|
+
/\bmake\s+me\s+/i.test(cleanPrompt) ||
|
|
195
|
+
/\bi\s+want\s+a\s+/i.test(cleanPrompt) ||
|
|
196
|
+
/\bi\s+want\s+an\s+/i.test(cleanPrompt) ||
|
|
197
|
+
/\bhandle\s+it\s+all\b/i.test(cleanPrompt) ||
|
|
198
|
+
/\bend\s+to\s+end\b/i.test(cleanPrompt) ||
|
|
199
|
+
/\be2e\s+this\b/i.test(cleanPrompt)) {
|
|
200
|
+
activateState(directory, prompt, 'autopilot');
|
|
201
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('autopilot', prompt))));
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Priority 4: Ultrapilot
|
|
206
|
+
if (/\b(ultrapilot|ultra-pilot)\b/i.test(cleanPrompt) ||
|
|
207
|
+
/\bparallel\s+build\b/i.test(cleanPrompt) ||
|
|
208
|
+
/\bswarm\s+build\b/i.test(cleanPrompt)) {
|
|
209
|
+
activateState(directory, prompt, 'ultrapilot');
|
|
210
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('ultrapilot', prompt))));
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Priority 5: Ultrawork keywords
|
|
215
|
+
if (/\b(ultrawork|ulw|uw)\b/i.test(cleanPrompt)) {
|
|
216
|
+
activateState(directory, prompt, 'ultrawork');
|
|
217
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('ultrawork', prompt))));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Priority 6: Ecomode keywords (includes "efficient")
|
|
222
|
+
if (/\b(eco|ecomode|eco-mode|efficient|save-tokens|budget)\b/i.test(cleanPrompt)) {
|
|
223
|
+
activateState(directory, prompt, 'ecomode');
|
|
224
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('ecomode', prompt))));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Priority 7: Swarm - parse N from "swarm N agents"
|
|
229
|
+
const swarmMatch = cleanPrompt.match(/\bswarm\s+(\d+)\s+agents?\b/i);
|
|
230
|
+
if (swarmMatch || /\bcoordinated\s+agents\b/i.test(cleanPrompt)) {
|
|
231
|
+
const agentCount = swarmMatch ? swarmMatch[1] : '3'; // default 3
|
|
232
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('swarm', prompt, agentCount))));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Priority 8: Pipeline
|
|
237
|
+
if (/\b(pipeline)\b/i.test(cleanPrompt) || /\bchain\s+agents\b/i.test(cleanPrompt)) {
|
|
238
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('pipeline', prompt))));
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Priority 9: Ralplan keyword (before plan to avoid false match)
|
|
243
|
+
if (/\b(ralplan)\b/i.test(cleanPrompt)) {
|
|
244
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('ralplan', prompt))));
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Priority 10: Plan keywords
|
|
249
|
+
if (/\b(plan this|plan the)\b/i.test(cleanPrompt)) {
|
|
250
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('plan', prompt))));
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Priority 11: TDD
|
|
255
|
+
if (/\b(tdd)\b/i.test(cleanPrompt) ||
|
|
256
|
+
/\btest\s+first\b/i.test(cleanPrompt) ||
|
|
257
|
+
/\bred\s+green\b/i.test(cleanPrompt)) {
|
|
258
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('tdd', prompt))));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Priority 12: Research
|
|
263
|
+
// "research" alone OR "analyze data" OR "statistics" trigger research skill
|
|
264
|
+
if (/\b(research)\b/i.test(cleanPrompt) ||
|
|
265
|
+
/\banalyze\s+data\b/i.test(cleanPrompt) ||
|
|
266
|
+
/\bstatistics\b/i.test(cleanPrompt)) {
|
|
267
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('research', prompt))));
|
|
180
268
|
return;
|
|
181
269
|
}
|
|
182
270
|
|
|
183
|
-
//
|
|
184
|
-
if (/\b(ultrathink|think)\b
|
|
185
|
-
console.log(JSON.stringify(
|
|
271
|
+
// Priority 13: Ultrathink/think keywords (keep inline message)
|
|
272
|
+
if (/\b(ultrathink|think hard|think deeply)\b/i.test(cleanPrompt)) {
|
|
273
|
+
console.log(JSON.stringify(createHookOutput(ULTRATHINK_MESSAGE)));
|
|
186
274
|
return;
|
|
187
275
|
}
|
|
188
276
|
|
|
189
|
-
//
|
|
190
|
-
if (/\b(
|
|
191
|
-
|
|
277
|
+
// Priority 14: Deepsearch (RESTRICTED patterns)
|
|
278
|
+
if (/\b(deepsearch)\b/i.test(cleanPrompt) ||
|
|
279
|
+
/\bsearch\s+(the\s+)?(codebase|code|files?|project)\b/i.test(cleanPrompt) ||
|
|
280
|
+
/\bfind\s+(in\s+)?(codebase|code|all\s+files?)\b/i.test(cleanPrompt)) {
|
|
281
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('deepsearch', prompt))));
|
|
192
282
|
return;
|
|
193
283
|
}
|
|
194
284
|
|
|
195
|
-
//
|
|
196
|
-
if (/\b(analyze
|
|
197
|
-
|
|
285
|
+
// Priority 15: Analyze (RESTRICTED patterns)
|
|
286
|
+
if (/\b(deep\s*analyze)\b/i.test(cleanPrompt) ||
|
|
287
|
+
/\binvestigate\s+(the|this|why)\b/i.test(cleanPrompt) ||
|
|
288
|
+
/\bdebug\s+(the|this|why)\b/i.test(cleanPrompt)) {
|
|
289
|
+
console.log(JSON.stringify(createHookOutput(createSkillInvocation('analyze', prompt))));
|
|
198
290
|
return;
|
|
199
291
|
}
|
|
200
292
|
|
|
@@ -15,6 +15,7 @@ import { fileURLToPath } from 'url';
|
|
|
15
15
|
const __filename = fileURLToPath(import.meta.url);
|
|
16
16
|
const __dirname = dirname(__filename);
|
|
17
17
|
const distDir = join(__dirname, '..', 'dist', 'hooks', 'notepad');
|
|
18
|
+
const clearSuggestionsDistDir = join(__dirname, '..', 'dist', 'hooks', 'clear-suggestions');
|
|
18
19
|
|
|
19
20
|
// Try to import notepad functions (may fail if not built)
|
|
20
21
|
let setPriorityContext = null;
|
|
@@ -27,6 +28,15 @@ try {
|
|
|
27
28
|
// Notepad module not available - remember tags will be silently ignored
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
// Try to import clear suggestions functions (may fail if not built)
|
|
32
|
+
let checkClearSuggestion = null;
|
|
33
|
+
try {
|
|
34
|
+
const clearSuggestionsModule = await import(join(clearSuggestionsDistDir, 'index.js'));
|
|
35
|
+
checkClearSuggestion = clearSuggestionsModule.checkClearSuggestion;
|
|
36
|
+
} catch {
|
|
37
|
+
// Clear suggestions module not available - will be silently skipped
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
// State file for session tracking
|
|
31
41
|
const STATE_FILE = join(homedir(), '.claude', '.session-stats.json');
|
|
32
42
|
|
|
@@ -262,10 +272,39 @@ async function main() {
|
|
|
262
272
|
// Generate contextual message
|
|
263
273
|
const message = generateMessage(toolName, toolOutput, sessionId, toolCount);
|
|
264
274
|
|
|
265
|
-
//
|
|
275
|
+
// Check for clear suggestions (complements /compact suggestions)
|
|
276
|
+
let clearSuggestionMessage = null;
|
|
277
|
+
if (checkClearSuggestion) {
|
|
278
|
+
try {
|
|
279
|
+
const stats = loadStats();
|
|
280
|
+
const session = stats.sessions[sessionId];
|
|
281
|
+
// Estimate context usage from total tool calls (rough heuristic)
|
|
282
|
+
const estimatedContextRatio = session ? Math.min(session.total_calls / 200, 1.0) : 0;
|
|
283
|
+
|
|
284
|
+
const clearResult = checkClearSuggestion({
|
|
285
|
+
sessionId,
|
|
286
|
+
directory,
|
|
287
|
+
toolName,
|
|
288
|
+
toolOutput,
|
|
289
|
+
contextUsageRatio: estimatedContextRatio,
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
if (clearResult.shouldSuggest && clearResult.message) {
|
|
293
|
+
clearSuggestionMessage = clearResult.message;
|
|
294
|
+
}
|
|
295
|
+
} catch {
|
|
296
|
+
// Clear suggestion check failed - continue without it
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Build response - use hookSpecificOutput.additionalContext for PostToolUse
|
|
266
301
|
const response = { continue: true };
|
|
267
|
-
|
|
268
|
-
|
|
302
|
+
const contextMessage = clearSuggestionMessage || message;
|
|
303
|
+
if (contextMessage) {
|
|
304
|
+
response.hookSpecificOutput = {
|
|
305
|
+
hookEventName: 'PostToolUse',
|
|
306
|
+
additionalContext: contextMessage
|
|
307
|
+
};
|
|
269
308
|
}
|
|
270
309
|
|
|
271
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
|
-
|
|
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({
|
|
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
|
-
|
|
271
|
+
hookSpecificOutput: {
|
|
272
|
+
hookEventName: 'UserPromptSubmit',
|
|
273
|
+
additionalContext: formatSkillsMessage(matchingSkills)
|
|
274
|
+
}
|
|
272
275
|
}));
|
|
273
276
|
} else {
|
|
274
277
|
console.log(JSON.stringify({ continue: true }));
|