oh-my-customcode 0.24.2 → 0.30.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 +3 -3
- package/dist/cli/index.js +518 -245
- package/dist/index.js +327 -37
- package/package.json +1 -1
- package/templates/.claude/agents/be-django-expert.md +45 -0
- package/templates/.claude/hooks/hooks.json +10 -0
- package/templates/.claude/hooks/scripts/context-budget-advisor.sh +86 -0
- package/templates/.claude/hooks/scripts/session-env-check.sh +58 -0
- package/templates/.claude/rules/SHOULD-ecomode.md +39 -0
- package/templates/.claude/rules/SHOULD-memory-integration.md +99 -9
- package/templates/.claude/skills/dev-lead-routing/SKILL.md +2 -1
- package/templates/.claude/skills/django-best-practices/SKILL.md +440 -0
- package/templates/CLAUDE.md.en +5 -5
- package/templates/CLAUDE.md.ko +5 -5
- package/templates/guides/django-best-practices/README.md +476 -0
- package/templates/manifest.json +4 -4
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Context Budget Advisor Hook
|
|
5
|
+
# Trigger: PostToolUse (Edit/Write/Agent/Task/Read/Glob/Grep/Bash)
|
|
6
|
+
# Purpose: Monitor context usage and advise ecomode activation based on task type
|
|
7
|
+
# Protocol: stdin JSON -> stdout pass-through, exit 0 always
|
|
8
|
+
|
|
9
|
+
input=$(cat)
|
|
10
|
+
|
|
11
|
+
# Read context info from status file if available
|
|
12
|
+
STATUS_FILE="/tmp/.claude-env-status-${PPID}"
|
|
13
|
+
BUDGET_FILE="/tmp/.claude-context-budget-${PPID}"
|
|
14
|
+
|
|
15
|
+
# Initialize budget tracking file
|
|
16
|
+
if [ ! -f "$BUDGET_FILE" ]; then
|
|
17
|
+
echo "task_type=general" > "$BUDGET_FILE"
|
|
18
|
+
echo "tool_count=0" >> "$BUDGET_FILE"
|
|
19
|
+
echo "write_count=0" >> "$BUDGET_FILE"
|
|
20
|
+
echo "read_count=0" >> "$BUDGET_FILE"
|
|
21
|
+
echo "agent_count=0" >> "$BUDGET_FILE"
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Read current counts
|
|
25
|
+
source "$BUDGET_FILE" 2>/dev/null || true
|
|
26
|
+
tool_count=${tool_count:-0}
|
|
27
|
+
write_count=${write_count:-0}
|
|
28
|
+
read_count=${read_count:-0}
|
|
29
|
+
agent_count=${agent_count:-0}
|
|
30
|
+
|
|
31
|
+
# Determine tool type from input
|
|
32
|
+
TOOL=$(echo "$input" | jq -r '.tool // ""' 2>/dev/null || echo "")
|
|
33
|
+
tool_count=$((tool_count + 1))
|
|
34
|
+
|
|
35
|
+
case "$TOOL" in
|
|
36
|
+
Write|Edit)
|
|
37
|
+
write_count=$((write_count + 1))
|
|
38
|
+
;;
|
|
39
|
+
Read|Glob|Grep)
|
|
40
|
+
read_count=$((read_count + 1))
|
|
41
|
+
;;
|
|
42
|
+
Task|Agent)
|
|
43
|
+
agent_count=$((agent_count + 1))
|
|
44
|
+
;;
|
|
45
|
+
esac
|
|
46
|
+
|
|
47
|
+
# Infer task type based on tool usage pattern
|
|
48
|
+
if [ "$agent_count" -ge 4 ]; then
|
|
49
|
+
task_type="research"
|
|
50
|
+
elif [ "$write_count" -gt "$read_count" ] && [ "$write_count" -ge 5 ]; then
|
|
51
|
+
task_type="implementation"
|
|
52
|
+
elif [ "$read_count" -gt "$write_count" ] && [ "$read_count" -ge 10 ]; then
|
|
53
|
+
task_type="review"
|
|
54
|
+
else
|
|
55
|
+
task_type="general"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Update budget file
|
|
59
|
+
cat > "$BUDGET_FILE" << EOF
|
|
60
|
+
task_type=${task_type}
|
|
61
|
+
tool_count=${tool_count}
|
|
62
|
+
write_count=${write_count}
|
|
63
|
+
read_count=${read_count}
|
|
64
|
+
agent_count=${agent_count}
|
|
65
|
+
EOF
|
|
66
|
+
|
|
67
|
+
# Determine threshold for current task type
|
|
68
|
+
case "$task_type" in
|
|
69
|
+
research) THRESHOLD=40 ;;
|
|
70
|
+
implementation) THRESHOLD=50 ;;
|
|
71
|
+
review) THRESHOLD=60 ;;
|
|
72
|
+
management) THRESHOLD=70 ;;
|
|
73
|
+
*) THRESHOLD=80 ;;
|
|
74
|
+
esac
|
|
75
|
+
|
|
76
|
+
# Emit advisory at milestones (every 25 tool calls)
|
|
77
|
+
if [ "$tool_count" -gt 0 ] && [ $((tool_count % 25)) -eq 0 ]; then
|
|
78
|
+
echo "[Context Budget] Task: ${task_type} | Threshold: ${THRESHOLD}% | Tools used: ${tool_count}" >&2
|
|
79
|
+
if [ "$tool_count" -ge 75 ]; then
|
|
80
|
+
echo "[Context Budget] ⚠ High tool usage — consider /compact or ecomode" >&2
|
|
81
|
+
fi
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Pass through
|
|
85
|
+
echo "$input"
|
|
86
|
+
exit 0
|
|
@@ -50,6 +50,38 @@ if command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/n
|
|
|
50
50
|
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
|
|
51
51
|
fi
|
|
52
52
|
|
|
53
|
+
# Drift Detection: compare git HEAD between sessions
|
|
54
|
+
DRIFT_STATUS="not-git"
|
|
55
|
+
if command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
56
|
+
SESSION_STATE_DIR="$HOME/.claude/session-state"
|
|
57
|
+
mkdir -p "$SESSION_STATE_DIR"
|
|
58
|
+
|
|
59
|
+
PROJECT_HASH=$(echo "$(pwd)" | md5 2>/dev/null || echo "$(pwd)" | md5sum 2>/dev/null | cut -c1-8)
|
|
60
|
+
# md5 on macOS outputs "MD5 (stdin) = <hash>", extract just the hash
|
|
61
|
+
PROJECT_HASH=$(echo "$PROJECT_HASH" | grep -oE '[a-f0-9]{32}' | cut -c1-8)
|
|
62
|
+
STATE_FILE="${SESSION_STATE_DIR}/${PROJECT_HASH}.last-head"
|
|
63
|
+
|
|
64
|
+
CURRENT_HEAD=$(git log -1 --format="%H" 2>/dev/null || echo "")
|
|
65
|
+
|
|
66
|
+
if [ -n "$CURRENT_HEAD" ]; then
|
|
67
|
+
if [ -f "$STATE_FILE" ]; then
|
|
68
|
+
LAST_HEAD=$(cat "$STATE_FILE" 2>/dev/null || echo "")
|
|
69
|
+
if [ -n "$LAST_HEAD" ] && [ "$LAST_HEAD" != "$CURRENT_HEAD" ]; then
|
|
70
|
+
DRIFT_STATUS="drifted"
|
|
71
|
+
NEW_COMMITS=$(git rev-list --count "${LAST_HEAD}..${CURRENT_HEAD}" 2>/dev/null || echo "?")
|
|
72
|
+
CHANGED_FILES=$(git diff --name-only "${LAST_HEAD}..${CURRENT_HEAD}" 2>/dev/null | head -10)
|
|
73
|
+
else
|
|
74
|
+
DRIFT_STATUS="clean"
|
|
75
|
+
fi
|
|
76
|
+
else
|
|
77
|
+
DRIFT_STATUS="first-session"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Save current HEAD for next session
|
|
81
|
+
echo "$CURRENT_HEAD" > "$STATE_FILE"
|
|
82
|
+
fi
|
|
83
|
+
fi
|
|
84
|
+
|
|
53
85
|
# Write status to file for other hooks to reference
|
|
54
86
|
STATUS_FILE="/tmp/.claude-env-status-${PPID}"
|
|
55
87
|
cat > "$STATUS_FILE" << ENVEOF
|
|
@@ -58,6 +90,7 @@ agent_teams=${AGENT_TEAMS_STATUS}
|
|
|
58
90
|
git_branch=${CURRENT_BRANCH}
|
|
59
91
|
claude_version=${CLAUDE_VERSION}
|
|
60
92
|
compat_status=${COMPAT_STATUS}
|
|
93
|
+
drift_status=${DRIFT_STATUS}
|
|
61
94
|
ENVEOF
|
|
62
95
|
|
|
63
96
|
# Report to stderr (visible in conversation)
|
|
@@ -78,6 +111,31 @@ else
|
|
|
78
111
|
echo " ✓ Feature branch detected" >&2
|
|
79
112
|
fi
|
|
80
113
|
echo " Rules: feature branch → commit → push → PR → merge" >&2
|
|
114
|
+
echo "" >&2
|
|
115
|
+
|
|
116
|
+
# Drift Detection report
|
|
117
|
+
echo " [Drift Detection]" >&2
|
|
118
|
+
case "$DRIFT_STATUS" in
|
|
119
|
+
drifted)
|
|
120
|
+
echo " ⚠ Repository changed since last session" >&2
|
|
121
|
+
echo " New commits: ${NEW_COMMITS}" >&2
|
|
122
|
+
if [ -n "${CHANGED_FILES:-}" ]; then
|
|
123
|
+
echo " Changed files:" >&2
|
|
124
|
+
echo "$CHANGED_FILES" | while IFS= read -r file; do
|
|
125
|
+
echo " - ${file}" >&2
|
|
126
|
+
done
|
|
127
|
+
fi
|
|
128
|
+
;;
|
|
129
|
+
clean)
|
|
130
|
+
echo " ✓ No changes since last session" >&2
|
|
131
|
+
;;
|
|
132
|
+
first-session)
|
|
133
|
+
echo " First session for this project" >&2
|
|
134
|
+
;;
|
|
135
|
+
not-git)
|
|
136
|
+
echo " Skipped (not a git repository)" >&2
|
|
137
|
+
;;
|
|
138
|
+
esac
|
|
81
139
|
echo "------------------------------------" >&2
|
|
82
140
|
|
|
83
141
|
# Pass through
|
|
@@ -35,3 +35,42 @@ Ecomode: `[lang-golang-expert] ✓ src/main.go reviewed: 1 naming issue (handle_
|
|
|
35
35
|
## Override
|
|
36
36
|
|
|
37
37
|
Disable with: "ecomode off", "verbose mode", or "show full details".
|
|
38
|
+
|
|
39
|
+
## Context Budget Management
|
|
40
|
+
|
|
41
|
+
Task-type-aware context thresholds that trigger ecomode earlier for context-heavy operations.
|
|
42
|
+
|
|
43
|
+
### Task Type Thresholds
|
|
44
|
+
|
|
45
|
+
| Task Type | Context Trigger | Rationale |
|
|
46
|
+
|-----------|----------------|-----------|
|
|
47
|
+
| Research (/research, multi-team) | 40% | High context consumption from parallel team results |
|
|
48
|
+
| Implementation (code generation) | 50% | Moderate context for code + test output |
|
|
49
|
+
| Review (code review, audit) | 60% | Moderate context for diff analysis |
|
|
50
|
+
| Management (git, deploy, CI) | 70% | Lower context needs |
|
|
51
|
+
| General (default) | 80% | Standard threshold |
|
|
52
|
+
|
|
53
|
+
### Detection
|
|
54
|
+
|
|
55
|
+
Task type is inferred from active context:
|
|
56
|
+
- **Research**: `/research` skill active, 4+ parallel agents
|
|
57
|
+
- **Implementation**: Write/Edit tools dominant, code files targeted
|
|
58
|
+
- **Review**: Read/Grep dominant, review/audit skill active
|
|
59
|
+
- **Management**: git/gh commands, CI/CD operations
|
|
60
|
+
- **General**: No specific pattern detected
|
|
61
|
+
|
|
62
|
+
### Budget Advisor Hook
|
|
63
|
+
|
|
64
|
+
The `context-budget-advisor.sh` hook monitors context usage and emits warnings when task-specific thresholds are approached:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
[Context Budget] Task: research | Threshold: 40% | Current: 38%
|
|
68
|
+
[Context Budget] ⚠ Approaching budget limit — consider /compact or ecomode
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Integration
|
|
72
|
+
|
|
73
|
+
- Works with existing ecomode activation (R013)
|
|
74
|
+
- Does NOT override explicit user settings
|
|
75
|
+
- Advisory only — never blocks operations
|
|
76
|
+
- Context percentage from statusline data when available
|
|
@@ -38,6 +38,56 @@ Agent frontmatter `memory: project|user|local` enables persistent memory:
|
|
|
38
38
|
- Do not store sensitive data or duplicate CLAUDE.md content
|
|
39
39
|
- Memory write failures should not block main task
|
|
40
40
|
|
|
41
|
+
## Confidence-Tracked Memory
|
|
42
|
+
|
|
43
|
+
Memory entries in MEMORY.md should include confidence annotations to distinguish verified facts from hypotheses.
|
|
44
|
+
|
|
45
|
+
### Confidence Levels
|
|
46
|
+
|
|
47
|
+
| Level | Tag | Meaning | Example |
|
|
48
|
+
|-------|-----|---------|---------|
|
|
49
|
+
| High | `[confidence: high]` | Verified across multiple sessions or confirmed by user | Architecture decisions, confirmed patterns |
|
|
50
|
+
| Medium | `[confidence: medium]` | Observed pattern, not yet fully verified | Code conventions seen in 2-3 files |
|
|
51
|
+
| Low | `[confidence: low]` | Single observation or hypothesis | First-time discovery, untested assumption |
|
|
52
|
+
|
|
53
|
+
### Format in MEMORY.md
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
### Key Patterns [confidence: high]
|
|
57
|
+
- `.claude/` files are gitignored → always use `git add -f`
|
|
58
|
+
- pre-commit hooks auto-detect README/manifest count mismatches
|
|
59
|
+
|
|
60
|
+
### Hypotheses [confidence: medium]
|
|
61
|
+
- Template sync might need CI enforcement (seen in 2 PRs)
|
|
62
|
+
|
|
63
|
+
### Unverified [confidence: low]
|
|
64
|
+
- Possible race condition in parallel hook execution (observed once)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Confidence Lifecycle
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
[low] → observed again → [medium] → confirmed by user/testing → [high]
|
|
71
|
+
[any] → contradicted by evidence → demoted or removed
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Rules
|
|
75
|
+
|
|
76
|
+
| Rule | Detail |
|
|
77
|
+
|------|--------|
|
|
78
|
+
| New discoveries | Start at `[confidence: low]` unless user explicitly confirms |
|
|
79
|
+
| Cross-session verification | Promote to `[confidence: medium]` when seen in 2+ sessions |
|
|
80
|
+
| User confirmation | Promote to `[confidence: high]` when user confirms or tests pass |
|
|
81
|
+
| Contradiction | Demote or remove when contradicted by new evidence |
|
|
82
|
+
| Default | Entries without tags are treated as `[confidence: high]` (backward compatibility) |
|
|
83
|
+
|
|
84
|
+
### Integration with Session-End
|
|
85
|
+
|
|
86
|
+
When sys-memory-keeper updates MEMORY.md at session end:
|
|
87
|
+
1. New findings from this session → `[confidence: low]`
|
|
88
|
+
2. Findings that match existing entries → promote confidence
|
|
89
|
+
3. Findings that contradict existing entries → flag for review
|
|
90
|
+
|
|
41
91
|
## Session-End Auto-Save
|
|
42
92
|
|
|
43
93
|
### Trigger
|
|
@@ -49,23 +99,63 @@ Session-end detected when user says: "끝", "종료", "마무리", "done", "wrap
|
|
|
49
99
|
```
|
|
50
100
|
User signals session end
|
|
51
101
|
→ Orchestrator delegates to sys-memory-keeper
|
|
52
|
-
→ sys-memory-keeper performs
|
|
53
|
-
1.
|
|
54
|
-
2.
|
|
55
|
-
|
|
102
|
+
→ sys-memory-keeper performs:
|
|
103
|
+
1. Collect session summary (tasks, decisions, open items)
|
|
104
|
+
2. Update native auto-memory (MEMORY.md)
|
|
105
|
+
3. Return formatted summary to orchestrator
|
|
106
|
+
→ Orchestrator performs MCP saves directly:
|
|
107
|
+
1. claude-mem save (if available via ToolSearch)
|
|
108
|
+
2. episodic-memory verification (if available via ToolSearch)
|
|
56
109
|
→ Orchestrator confirms to user
|
|
57
110
|
```
|
|
58
111
|
|
|
112
|
+
### Responsibility Split
|
|
113
|
+
|
|
114
|
+
MCP tools (claude-mem, episodic-memory) are **orchestrator-scoped** and not inherited by subagents. Therefore:
|
|
115
|
+
|
|
116
|
+
| Responsibility | Owner | Reason |
|
|
117
|
+
|----------------|-------|--------|
|
|
118
|
+
| Session summary collection | sys-memory-keeper | Domain expertise in memory formatting |
|
|
119
|
+
| Native auto-memory (MEMORY.md) | sys-memory-keeper | Has Write access to memory directory |
|
|
120
|
+
| claude-mem MCP save | Orchestrator | MCP tools only available at orchestrator level |
|
|
121
|
+
| episodic-memory MCP verification | Orchestrator | MCP tools only available at orchestrator level |
|
|
122
|
+
|
|
59
123
|
### Dual-System Save
|
|
60
124
|
|
|
61
|
-
| System | Tool | Action | Required |
|
|
62
|
-
|
|
63
|
-
|
|
|
64
|
-
|
|
|
125
|
+
| System | Owner | Tool | Action | Required |
|
|
126
|
+
|--------|-------|------|--------|----------|
|
|
127
|
+
| Native auto-memory | sys-memory-keeper | Write | Update MEMORY.md with session learnings | Yes |
|
|
128
|
+
| claude-mem | Orchestrator | `mcp__plugin_claude-mem_mcp-search__save_memory` | Save session summary with project, tasks, decisions | No (best-effort) |
|
|
129
|
+
| episodic-memory | Orchestrator | `mcp__plugin_episodic-memory_episodic-memory__search` | Verify session is indexed for future retrieval | No (best-effort) |
|
|
130
|
+
|
|
131
|
+
### Session-End Self-Check (MANDATORY)
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
╔══════════════════════════════════════════════════════════════════╗
|
|
135
|
+
║ BEFORE CONFIRMING SESSION-END TO USER: ║
|
|
136
|
+
║ ║
|
|
137
|
+
║ 1. Did sys-memory-keeper update MEMORY.md? ║
|
|
138
|
+
║ YES → Continue ║
|
|
139
|
+
║ NO → Delegate to sys-memory-keeper first ║
|
|
140
|
+
║ ║
|
|
141
|
+
║ 2. Did I attempt claude-mem save? ║
|
|
142
|
+
║ YES → Continue (even if it failed) ║
|
|
143
|
+
║ NO → ToolSearch + save now ║
|
|
144
|
+
║ ║
|
|
145
|
+
║ 3. Did I attempt episodic-memory verification? ║
|
|
146
|
+
║ YES → Continue (even if it failed) ║
|
|
147
|
+
║ NO → ToolSearch + verify now ← THIS IS THE COMMONLY ║
|
|
148
|
+
║ SKIPPED STEP. DO NOT SKIP IT. ║
|
|
149
|
+
║ ║
|
|
150
|
+
║ ALL THREE must be attempted before confirming to user. ║
|
|
151
|
+
║ "Attempted" means called the tool — failure is OK, skipping ║
|
|
152
|
+
║ is NOT. ║
|
|
153
|
+
╚══════════════════════════════════════════════════════════════════╝
|
|
154
|
+
```
|
|
65
155
|
|
|
66
156
|
### Failure Policy
|
|
67
157
|
|
|
68
|
-
-
|
|
158
|
+
- MCP saves are **non-blocking**: memory failure MUST NOT prevent session from ending
|
|
69
159
|
- If claude-mem unavailable: skip, log warning
|
|
70
160
|
- If episodic-memory unavailable: skip, log warning
|
|
71
161
|
- If both unavailable: warn user, proceed with session end
|
|
@@ -13,7 +13,7 @@ context: fork
|
|
|
13
13
|
|------|--------|
|
|
14
14
|
| Language | lang-golang-expert, lang-python-expert, lang-rust-expert, lang-kotlin-expert, lang-typescript-expert, lang-java21-expert |
|
|
15
15
|
| Frontend | fe-vercel-agent, fe-vuejs-agent, fe-svelte-agent |
|
|
16
|
-
| Backend | be-fastapi-expert, be-springboot-expert, be-go-backend-expert, be-nestjs-expert, be-express-expert |
|
|
16
|
+
| Backend | be-fastapi-expert, be-springboot-expert, be-go-backend-expert, be-nestjs-expert, be-express-expert, be-django-expert |
|
|
17
17
|
| Tooling | tool-npm-expert, tool-optimizer, tool-bun-expert |
|
|
18
18
|
| Database | db-supabase-expert, db-postgres-expert, db-redis-expert |
|
|
19
19
|
| Architect | arch-documenter, arch-speckit-agent |
|
|
@@ -52,6 +52,7 @@ context: fork
|
|
|
52
52
|
| vue | fe-vuejs-agent |
|
|
53
53
|
| svelte | fe-svelte-agent |
|
|
54
54
|
| fastapi | be-fastapi-expert |
|
|
55
|
+
| django | be-django-expert |
|
|
55
56
|
| spring, springboot | be-springboot-expert |
|
|
56
57
|
| nestjs | be-nestjs-expert |
|
|
57
58
|
| express | be-express-expert |
|