claude-pro-minmax 1.0.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 (90) hide show
  1. package/.claude/CLAUDE.md +60 -0
  2. package/.claude/agents/README.ko.md +210 -0
  3. package/.claude/agents/README.md +210 -0
  4. package/.claude/agents/builder.md +96 -0
  5. package/.claude/agents/dplanner.md +58 -0
  6. package/.claude/agents/planner.md +52 -0
  7. package/.claude/agents/reviewer.md +69 -0
  8. package/.claude/commands/README.ko.md +381 -0
  9. package/.claude/commands/README.md +381 -0
  10. package/.claude/commands/analyze-failures.md +49 -0
  11. package/.claude/commands/compact-phase.md +75 -0
  12. package/.claude/commands/do-opus.md +43 -0
  13. package/.claude/commands/do-sonnet.md +43 -0
  14. package/.claude/commands/do.md +56 -0
  15. package/.claude/commands/dplan.md +36 -0
  16. package/.claude/commands/learn.md +64 -0
  17. package/.claude/commands/llms-txt.md +50 -0
  18. package/.claude/commands/load-context.md +46 -0
  19. package/.claude/commands/plan.md +62 -0
  20. package/.claude/commands/review.md +55 -0
  21. package/.claude/commands/session-load.md +61 -0
  22. package/.claude/commands/session-save.md +79 -0
  23. package/.claude/commands/watch.md +58 -0
  24. package/.claude/contexts/README.ko.md +94 -0
  25. package/.claude/contexts/README.md +94 -0
  26. package/.claude/contexts/backend-context.md +23 -0
  27. package/.claude/contexts/frontend-context.md +24 -0
  28. package/.claude/rules/README.ko.md +98 -0
  29. package/.claude/rules/README.md +98 -0
  30. package/.claude/rules/code-style.md +21 -0
  31. package/.claude/rules/critical-actions.md +34 -0
  32. package/.claude/rules/security.md +13 -0
  33. package/.claude/sessions/2025-01-27-auth-jwt-refresh.md +32 -0
  34. package/.claude/sessions/README.ko.md +195 -0
  35. package/.claude/sessions/README.md +195 -0
  36. package/.claude/settings.json +167 -0
  37. package/.claude/settings.local.example.json +3 -0
  38. package/.claude/skills/README.ko.md +60 -0
  39. package/.claude/skills/README.md +60 -0
  40. package/.claude/skills/cli-wrappers/SKILL.md +38 -0
  41. package/.claude/skills/cli-wrappers/references/github-cli.md +18 -0
  42. package/.claude/skills/cli-wrappers/references/mgrep.md +18 -0
  43. package/.claude/skills/learned/README.ko.md +64 -0
  44. package/.claude/skills/learned/README.md +64 -0
  45. package/.claude.json +28 -0
  46. package/.claudeignore +17 -0
  47. package/LICENSE +21 -0
  48. package/README.ko.md +441 -0
  49. package/README.md +441 -0
  50. package/bin/cpmm.js +171 -0
  51. package/install.sh +154 -0
  52. package/package.json +59 -0
  53. package/scripts/README.ko.md +150 -0
  54. package/scripts/README.md +150 -0
  55. package/scripts/analyze-failures.sh +145 -0
  56. package/scripts/build.sh +34 -0
  57. package/scripts/claude_command_smoke.sh +116 -0
  58. package/scripts/commit.sh +7 -0
  59. package/scripts/create-branch.sh +14 -0
  60. package/scripts/hooks/README.ko.md +117 -0
  61. package/scripts/hooks/README.md +118 -0
  62. package/scripts/hooks/compact-suggest.sh +52 -0
  63. package/scripts/hooks/critical-action-check.sh +68 -0
  64. package/scripts/hooks/notification.sh +47 -0
  65. package/scripts/hooks/post-edit-format.sh +39 -0
  66. package/scripts/hooks/pre-compact.sh +55 -0
  67. package/scripts/hooks/readonly-check.sh +19 -0
  68. package/scripts/hooks/retry-check.sh +32 -0
  69. package/scripts/hooks/session-cleanup.sh +83 -0
  70. package/scripts/hooks/session-start.sh +70 -0
  71. package/scripts/hooks/stop-collect-context.sh +39 -0
  72. package/scripts/hooks/tool-failure-log.sh +46 -0
  73. package/scripts/lint.sh +34 -0
  74. package/scripts/runtime/README.ko.md +60 -0
  75. package/scripts/runtime/README.md +60 -0
  76. package/scripts/runtime/adapters/README.ko.md +68 -0
  77. package/scripts/runtime/adapters/README.md +68 -0
  78. package/scripts/runtime/adapters/_interface.sh +53 -0
  79. package/scripts/runtime/adapters/_template.sh +67 -0
  80. package/scripts/runtime/adapters/generic.sh +78 -0
  81. package/scripts/runtime/adapters/go.sh +51 -0
  82. package/scripts/runtime/adapters/jvm.sh +97 -0
  83. package/scripts/runtime/adapters/node.sh +104 -0
  84. package/scripts/runtime/adapters/python.sh +116 -0
  85. package/scripts/runtime/adapters/rust.sh +49 -0
  86. package/scripts/runtime/detect.sh +52 -0
  87. package/scripts/scrub-secrets.js +48 -0
  88. package/scripts/snapshot.sh +45 -0
  89. package/scripts/test.sh +34 -0
  90. package/scripts/verify.sh +35 -0
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+ # retry-check.sh - Stop Hook (For Builder Subagent)
3
+ # Enforce 2-Retry Cap (0 tokens, ~50 tokens on block)
4
+ # Hardened Hook
5
+
6
+ set -euo pipefail
7
+
8
+ INPUT=$(cat)
9
+
10
+ # check stop_hook_active - to prevent infinite loops
11
+ STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false')
12
+ if [ "$STOP_HOOK_ACTIVE" = "true" ]; then
13
+ exit 0 # Already continuing from stop hook result - do not intervene
14
+ fi
15
+
16
+ # Get transcript path
17
+ TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty')
18
+
19
+ if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
20
+ # Extract tool_result from last 50 lines (sufficient buffer) and check if last 2 are both errors
21
+ # tail: optimizes performance by not reading the entire file
22
+ # jq: parses JSONL to extract is_error field
23
+ CONSECUTIVE_ERRORS=$(tail -n 50 "$TRANSCRIPT_PATH" | jq -r 'select(.type=="tool_result") | .is_error // false' | tail -n 2 | grep -c "true")
24
+
25
+ # Escalate on 2 consecutive failures
26
+ if [ "$CONSECUTIVE_ERRORS" -ge 2 ]; then
27
+ echo "RETRY_CAP: 2 consecutive failures detected. Escalation to --sonnet, @planner, or @dplanner is recommended." >&2
28
+ exit 2
29
+ fi
30
+ fi
31
+
32
+ exit 0
@@ -0,0 +1,83 @@
1
+ #!/bin/bash
2
+ # session-cleanup.sh - SessionEnd Hook
3
+ # Save session summary + Secret scrubbing on session end (0 tokens)
4
+ # Hardened Hook
5
+
6
+ set -euo pipefail
7
+
8
+ INPUT=$(cat)
9
+
10
+ # Check jq dependency
11
+ if ! command -v jq &> /dev/null; then
12
+ echo "Error: jq is required but not installed." >&2
13
+ exit 1
14
+ fi
15
+
16
+ # Set project directories
17
+ SESSION_DIR="$HOME/.claude/sessions"
18
+ SCRUBBER="$HOME/.claude/scripts/scrub-secrets.js"
19
+
20
+ mkdir -p "$SESSION_DIR"
21
+
22
+ # Save session summary
23
+ SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
24
+ REASON=$(echo "$INPUT" | jq -r '.reason // "other"')
25
+ TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
26
+ SUMMARY_FILE="$SESSION_DIR/${TIMESTAMP}-session-end.md"
27
+
28
+ # Git change summary
29
+ GIT_SUMMARY=""
30
+ if git rev-parse --is-inside-work-tree &>/dev/null; then
31
+ CHANGED_FILES=$(git diff --name-only HEAD 2>/dev/null | wc -l | tr -d ' ')
32
+ STAGED_FILES=$(git diff --cached --name-only 2>/dev/null | wc -l | tr -d ' ')
33
+ BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
34
+ GIT_SUMMARY="Branch: $BRANCH, Changed: $CHANGED_FILES, Staged: $STAGED_FILES"
35
+ else
36
+ GIT_SUMMARY="Not a git repository"
37
+ fi
38
+
39
+ # Create summary file
40
+ cat > "$SUMMARY_FILE" <<EOF
41
+ ---
42
+ type: session-end
43
+ session_id: $SESSION_ID
44
+ reason: $REASON
45
+ timestamp: $(date +"%Y-%m-%d %H:%M:%S")
46
+ ---
47
+
48
+ # Session End Summary
49
+
50
+ ## Session Info
51
+ - ID: $SESSION_ID
52
+ - End Reason: $REASON
53
+ - Time: $(date +"%H:%M:%S")
54
+
55
+ ## Git Status
56
+ $GIT_SUMMARY
57
+
58
+ ## Working Directory
59
+ $(pwd)
60
+
61
+ ## Context for Next Session
62
+ [Reference this file with /session-load in the next session]
63
+ EOF
64
+
65
+ echo "[SessionEnd] Summary saved: $SUMMARY_FILE" >&2
66
+
67
+ # ===== Existing: Secret Scrubbing =====
68
+ # Skip if scrubber does not exist
69
+ [ ! -f "$SCRUBBER" ] && exit 0
70
+
71
+ # Scrub session files modified within last 5 minutes (*.md)
72
+ find "$SESSION_DIR" -name "*.md" -mmin -5 -print0 2>/dev/null | while IFS= read -r -d '' file; do
73
+ if [ -f "$file" ]; then
74
+ temp_file=$(mktemp)
75
+ if node "$SCRUBBER" < "$file" > "$temp_file" 2>/dev/null; then
76
+ mv "$temp_file" "$file"
77
+ else
78
+ rm -f "$temp_file"
79
+ fi
80
+ fi
81
+ done
82
+
83
+ exit 0
@@ -0,0 +1,70 @@
1
+ #!/bin/bash
2
+ # session-start.sh - SessionStart Hook
3
+ # 1. Set environment variables (using CLAUDE_ENV_FILE)
4
+ # 2. Notify previous session context (opt-in: CLAUDE_SESSION_NOTIFY=1)
5
+ # Official Docs: Environment variables can be persisted via CLAUDE_ENV_FILE in SessionStart
6
+ set -euo pipefail
7
+
8
+ # 1. Set environment variables (0 tokens) - Always runs
9
+ if [ -n "${CLAUDE_ENV_FILE:-}" ]; then
10
+ # Example: project-specific environment variables
11
+ # echo 'export NODE_ENV=development' >> "$CLAUDE_ENV_FILE"
12
+ # echo 'export DEBUG=true' >> "$CLAUDE_ENV_FILE"
13
+
14
+ # Load .env.local if exists (Security: values are not exposed)
15
+ ENV_LOCAL="${CLAUDE_PROJECT_DIR:-.}/.env.local"
16
+ if [ -f "$ENV_LOCAL" ]; then
17
+ # Extract only variable names and export (values are loaded at runtime)
18
+ grep -v '^#' "$ENV_LOCAL" | grep '=' | while read -r line; do
19
+ var_name="${line%%=*}"
20
+ echo "export $var_name=\"\${$var_name:-}\"" >> "$CLAUDE_ENV_FILE"
21
+ done
22
+ fi
23
+ fi
24
+
25
+ # 2. Previous session notification (opt-in, ~30 tokens)
26
+ if [ "${CLAUDE_SESSION_NOTIFY:-0}" = "1" ]; then
27
+ SESSION_DIR="$HOME/.claude/sessions"
28
+ RECENT=$(find "$SESSION_DIR" -name "*.md" -mtime -7 2>/dev/null | sort -r | head -1)
29
+
30
+ if [ -n "$RECENT" ] && [ -f "$RECENT" ]; then
31
+ cat <<EOF
32
+ {
33
+ "hookSpecificOutput": {
34
+ "hookEventName": "SessionStart",
35
+ "additionalContext": "📂 Previous session found: $(basename "$RECENT"). To restore: /session-load $(basename "$RECENT" .md)"
36
+ }
37
+ }
38
+ EOF
39
+ fi
40
+ fi
41
+
42
+ # 3. Failure log notification (opt-in, ~30 tokens)
43
+ if [ "${CLAUDE_FAILURE_NOTIFY:-0}" = "1" ]; then
44
+ LOG_FILE="$HOME/.claude/logs/tool-failures.log"
45
+ if [ -f "$LOG_FILE" ]; then
46
+ FAILURE_COUNT=$(wc -l < "$LOG_FILE" 2>/dev/null | tr -d ' ')
47
+ if [ "$FAILURE_COUNT" -gt 10 ]; then
48
+ cat <<EOF
49
+ {
50
+ "hookSpecificOutput": {
51
+ "hookEventName": "SessionStart",
52
+ "additionalContext": "⚠️ ${FAILURE_COUNT} tool failures accumulated. To analyze: /analyze-failures"
53
+ }
54
+ }
55
+ EOF
56
+ fi
57
+ fi
58
+ fi
59
+
60
+ # 4. Message budget reminder (always-on, ~40 tokens)
61
+ cat <<'BUDGET'
62
+ {
63
+ "hookSpecificOutput": {
64
+ "hookEventName": "SessionStart",
65
+ "additionalContext": "📊 Pro Plan Strategy: ~45 msg/5h target (short conversations)\n• Default (/do): 2 msg (Batch plan+build+verify)\n• Complex (/plan): 6+ msg (Use for 4+ files)\n• Cost: Haiku(1x) vs Sonnet(3x) vs Opus(5x) | Out=5x In"
66
+ }
67
+ }
68
+ BUDGET
69
+
70
+ exit 0
@@ -0,0 +1,39 @@
1
+ #!/bin/bash
2
+ # stop-collect-context.sh - Stop Hook
3
+ # Collect additional context on tool failure (0 tokens)
4
+ # Optional: Activated when additional context is needed besides PostToolUseFailure
5
+ # Hardened Hook
6
+
7
+ set -euo pipefail
8
+
9
+ INPUT=$(cat)
10
+
11
+ # Check jq dependency
12
+ if ! command -v jq &> /dev/null; then
13
+ exit 0 # Silently skip if jq is missing
14
+ fi
15
+
16
+ # check stop_hook_active - to prevent infinite loops
17
+ STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false')
18
+ [ "$STOP_HOOK_ACTIVE" = "true" ] && exit 0
19
+
20
+ # Transcript path
21
+ TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty')
22
+ [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ] && exit 0
23
+
24
+ # Check for error in recent tool_result
25
+ LAST_ERROR=$(tail -100 "$TRANSCRIPT_PATH" 2>/dev/null | jq -s '[.[] | select(.type=="tool_result" and .is_error==true)] | last' 2>/dev/null || echo "null")
26
+
27
+ if [ "$LAST_ERROR" != "null" ] && [ "$LAST_ERROR" != "" ]; then
28
+ TOOL_NAME=$(echo "$LAST_ERROR" | jq -r '.tool_name // "unknown"')
29
+ ERROR_MSG=$(echo "$LAST_ERROR" | jq -r '.error // "unknown"')
30
+
31
+ LOG_DIR="$HOME/.claude/logs"
32
+ mkdir -p "$LOG_DIR"
33
+ CONTEXT_FILE="$LOG_DIR/failure-contexts.jsonl"
34
+
35
+ # Save context (JSONL format)
36
+ echo "$LAST_ERROR" >> "$CONTEXT_FILE"
37
+ fi
38
+
39
+ exit 0
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+ # tool-failure-log.sh - PostToolUseFailure Hook
3
+ # Logging and escalation recommendations on tool failure (0 tokens)
4
+ # Hardened Hook
5
+
6
+ set -euo pipefail
7
+
8
+ INPUT=$(cat)
9
+
10
+ # Check jq dependency
11
+ if ! command -v jq &> /dev/null; then
12
+ echo "Error: jq is required but not installed." >&2
13
+ exit 1
14
+ fi
15
+
16
+ # Parsing
17
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // "unknown"')
18
+ ERROR_MSG=$(echo "$INPUT" | jq -r '.error // "unknown error"')
19
+ SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
20
+
21
+ # Log directory
22
+ LOG_DIR="$HOME/.claude/logs"
23
+ mkdir -p "$LOG_DIR"
24
+
25
+ LOG_FILE="$LOG_DIR/tool-failures.log"
26
+ TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
27
+
28
+ # Record log
29
+ echo "[$TIMESTAMP] Tool: $TOOL_NAME | Error: $ERROR_MSG | Session: $SESSION_ID" >> "$LOG_FILE"
30
+
31
+ # Check for identical tool failures within last 5 minutes (from log file)
32
+ if [ -f "$LOG_FILE" ]; then
33
+ FIVE_MIN_AGO=$(date -v-5M +"%Y-%m-%d %H:%M:%S" 2>/dev/null || date -d "5 minutes ago" +"%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "")
34
+ if [ -n "$FIVE_MIN_AGO" ]; then
35
+ RECENT_FAILURES=$(grep "$TOOL_NAME" "$LOG_FILE" 2>/dev/null | tail -10 | wc -l | tr -d ' ')
36
+ else
37
+ RECENT_FAILURES=$(grep -c "$TOOL_NAME" "$LOG_FILE" 2>/dev/null || echo 0)
38
+ fi
39
+ else
40
+ RECENT_FAILURES=1
41
+ fi
42
+
43
+ # Recommend escalation on 3 or more failures
44
+ if [ "$RECENT_FAILURES" -ge 3 ]; then
45
+ echo "[ToolFailure] Tool $TOOL_NAME failed ${RECENT_FAILURES} times. Escalation to @planner or @dplanner recommended." >&2
46
+ fi
@@ -0,0 +1,34 @@
1
+ #!/bin/bash
2
+ # lint.sh - Universal Lint
3
+ # Delegates to runtime-specific adapter
4
+ set -euo pipefail
5
+
6
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ RUNTIME_DIR="$SCRIPT_DIR/runtime"
9
+
10
+ # Detect runtime
11
+ RUNTIME=$("$RUNTIME_DIR/detect.sh" "$@")
12
+
13
+ # Parse JSON - prefer jq, fallback to bash
14
+ parse_json() {
15
+ local key="$1"
16
+ if command -v jq &>/dev/null; then
17
+ echo "$RUNTIME" | jq -r ".$key"
18
+ else
19
+ echo "$RUNTIME" | sed 's/.*"'"$key"'":"\([^"]*\)".*/\1/'
20
+ fi
21
+ }
22
+
23
+ ADAPTER=$(parse_json adapter)
24
+ RUNTIME_NAME=$(parse_json runtime)
25
+ TOOL_NAME=$(parse_json tool)
26
+
27
+ echo "🔍 Detected: $RUNTIME_NAME ($TOOL_NAME)"
28
+
29
+ # Source adapter
30
+ source "$RUNTIME_DIR/adapters/$ADAPTER"
31
+
32
+ # Execute
33
+ echo "🔎 Running linter..."
34
+ adapter_lint
@@ -0,0 +1,60 @@
1
+ > **[English Version](README.md)**
2
+
3
+ # Runtime Detection Layer
4
+
5
+ ## 목적
6
+ 언어 독립적 작업을 위한 OCP 준수 런타임 감지. 코어 스크립트 수정 없이 새 언어 추가 가능.
7
+
8
+ ## 구조
9
+
10
+ ```
11
+ runtime/
12
+ ├── detect.sh # 프로젝트 런타임 자동 감지
13
+ └── adapters/ # 언어별 구현체
14
+ ```
15
+
16
+ ## detect.sh
17
+
18
+ 프로젝트 유형을 자동 감지하고 JSON을 출력합니다.
19
+
20
+ **사용법:**
21
+ ```bash
22
+ # 기본 사용
23
+ ./detect.sh
24
+ # 출력: {"runtime":"node","tool":"npm","adapter":"node.sh"}
25
+
26
+ # 모노레포 지원 (하위 디렉토리)
27
+ ./detect.sh --path backend
28
+ # 출력: {"runtime":"jvm","tool":"gradle","adapter":"jvm.sh"}
29
+ ```
30
+
31
+ **감지 우선순위:**
32
+ 1. JVM: `build.gradle.kts` > `build.gradle` > `pom.xml`
33
+ 2. Node: `package.json` (락 파일로 패키지 매니저 확인)
34
+ 3. Rust: `Cargo.toml`
35
+ 4. Go: `go.mod`
36
+ 5. Python: `pyproject.toml` > `setup.py` > `requirements.txt`
37
+ 6. Generic: Makefile로 폴백
38
+
39
+ ## 통합
40
+
41
+ 유니버설 스크립트가 이 레이어를 사용합니다:
42
+
43
+ ```bash
44
+ # scripts/verify.sh
45
+ RUNTIME=$("$RUNTIME_DIR/detect.sh" "$@")
46
+ ADAPTER=$(echo "$RUNTIME" | jq -r '.adapter')
47
+ source "$RUNTIME_DIR/adapters/$ADAPTER"
48
+ adapter_verify
49
+ ```
50
+
51
+ ## 새 런타임 추가
52
+
53
+ `detect.sh`만 업데이트:
54
+
55
+ ```bash
56
+ # 감지 패턴 추가
57
+ [[ -f "$dir/mix.exs" ]] && echo '{"runtime":"elixir","tool":"mix","adapter":"elixir.sh"}' && return
58
+ ```
59
+
60
+ 그 다음 `adapters/elixir.sh`에 어댑터 생성.
@@ -0,0 +1,60 @@
1
+ > **[한국어 버전](README.ko.md)**
2
+
3
+ # Runtime Detection Layer
4
+
5
+ ## Purpose
6
+ OCP-compliant runtime detection for language-agnostic operations. Add new languages without modifying core scripts.
7
+
8
+ ## Structure
9
+
10
+ ```
11
+ runtime/
12
+ ├── detect.sh # Auto-detect project runtime
13
+ └── adapters/ # Language-specific implementations
14
+ ```
15
+
16
+ ## detect.sh
17
+
18
+ Automatically detects project type and outputs JSON.
19
+
20
+ **Usage:**
21
+ ```bash
22
+ # Basic usage
23
+ ./detect.sh
24
+ # Output: {"runtime":"node","tool":"npm","adapter":"node.sh"}
25
+
26
+ # Monorepo support (subdirectory)
27
+ ./detect.sh --path backend
28
+ # Output: {"runtime":"jvm","tool":"gradle","adapter":"jvm.sh"}
29
+ ```
30
+
31
+ **Detection Priority:**
32
+ 1. JVM: `build.gradle.kts` > `build.gradle` > `pom.xml`
33
+ 2. Node: `package.json` (then check lock files for pm)
34
+ 3. Rust: `Cargo.toml`
35
+ 4. Go: `go.mod`
36
+ 5. Python: `pyproject.toml` > `setup.py` > `requirements.txt`
37
+ 6. Generic: Fallback to Makefile
38
+
39
+ ## Integration
40
+
41
+ Universal scripts use this layer:
42
+
43
+ ```bash
44
+ # scripts/verify.sh
45
+ RUNTIME=$("$RUNTIME_DIR/detect.sh" "$@")
46
+ ADAPTER=$(echo "$RUNTIME" | jq -r '.adapter')
47
+ source "$RUNTIME_DIR/adapters/$ADAPTER"
48
+ adapter_verify
49
+ ```
50
+
51
+ ## Adding New Runtimes
52
+
53
+ Update `detect.sh` only:
54
+
55
+ ```bash
56
+ # Add detection pattern
57
+ [[ -f "$dir/mix.exs" ]] && echo '{"runtime":"elixir","tool":"mix","adapter":"elixir.sh"}' && return
58
+ ```
59
+
60
+ Then create the adapter in `adapters/elixir.sh`.
@@ -0,0 +1,68 @@
1
+ > **[English Version](README.md)**
2
+
3
+ # Adapters Directory
4
+
5
+ ## 목적
6
+ 어댑터 계약을 따르는 언어별 구현체. 각 어댑터는 빌드, 테스트, 린트 작업에 대해 통합 인터페이스를 제공합니다.
7
+
8
+ ## 사용 가능한 어댑터
9
+
10
+ | 어댑터 | 런타임 | 빌드 도구 | 언어 |
11
+ |---------|---------|-------------|-----------|
12
+ | `jvm.sh` | JVM | Gradle, Maven | Java, Kotlin |
13
+ | `node.sh` | Node | npm, pnpm, yarn, bun | TypeScript, JavaScript |
14
+ | `go.sh` | Go | Go 모듈 | Go |
15
+ | `rust.sh` | Rust | Cargo | Rust |
16
+ | `python.sh` | Python | pip, poetry, uv | Python |
17
+ | `generic.sh` | Generic | Makefile | Any |
18
+
19
+ ## 개발 유틸리티
20
+
21
+ | 파일 | 목적 |
22
+ |------|------|
23
+ | `_interface.sh` | 계약 검증기 - 어댑터가 모든 필수 함수를 구현했는지 검증 |
24
+ | `_template.sh` | 어댑터 템플릿 - 새 어댑터 생성 시 복사하여 사용 |
25
+
26
+ ## 어댑터 계약
27
+
28
+ 모든 어댑터는 다음 함수를 구현해야 합니다 (`_interface.sh`에 정의됨):
29
+
30
+ ```bash
31
+ adapter_info() # 어댑터 메타데이터를 JSON으로 반환
32
+ adapter_verify() # 전체 검증 실행 (빌드 + 테스트 + 린트)
33
+ adapter_build() # 프로젝트 빌드
34
+ adapter_test() # 테스트 실행
35
+ adapter_lint() # 린터 실행
36
+ adapter_format() # 코드 포맷
37
+ adapter_clean() # 빌드 산출물 정리
38
+ ```
39
+
40
+ 선택 사항:
41
+ ```bash
42
+ adapter_run() # 개발 서버 실행
43
+ ```
44
+
45
+ ## 새 어댑터 추가
46
+
47
+ **3단계 (OCP - 코어 수정 없음):**
48
+
49
+ 1. 템플릿 복사:
50
+ ```bash
51
+ cp _template.sh elixir.sh
52
+ ```
53
+
54
+ 2. 모든 `adapter_*` 함수 구현
55
+
56
+ 3. `../detect.sh`에 감지 패턴 추가:
57
+ ```bash
58
+ [[ -f "$dir/mix.exs" ]] && echo '{"runtime":"elixir","tool":"mix","adapter":"elixir.sh"}' && return
59
+ ```
60
+
61
+ 완료! Universal scripts가 자동으로 새 어댑터 사용
62
+
63
+ ## 어댑터 준수 검증
64
+
65
+ ```bash
66
+ ./adapters/_interface.sh ./adapters/elixir.sh
67
+ # 출력: ✓ Adapter implements all required functions
68
+ ```
@@ -0,0 +1,68 @@
1
+ > **[한국어 버전](README.ko.md)**
2
+
3
+ # Adapters Directory
4
+
5
+ ## Purpose
6
+ Language-specific implementations following the adapter contract. Each adapter provides a unified interface for build, test, lint operations.
7
+
8
+ ## Available Adapters
9
+
10
+ | Adapter | Runtime | Build Tools | Languages |
11
+ |---------|---------|-------------|-----------|
12
+ | `jvm.sh` | JVM | Gradle, Maven | Java, Kotlin |
13
+ | `node.sh` | Node | npm, pnpm, yarn, bun | TypeScript, JavaScript |
14
+ | `go.sh` | Go | Go modules | Go |
15
+ | `rust.sh` | Rust | Cargo | Rust |
16
+ | `python.sh` | Python | pip, poetry, uv | Python |
17
+ | `generic.sh` | Generic | Makefile | Any |
18
+
19
+ ## Development Utilities
20
+
21
+ | File | Purpose |
22
+ |------|---------|
23
+ | `_interface.sh` | Contract validator - verifies adapter implements all required functions |
24
+ | `_template.sh` | Adapter template - copy this to create new adapters |
25
+
26
+ ## Adapter Contract
27
+
28
+ All adapters MUST implement these functions (defined in `_interface.sh`):
29
+
30
+ ```bash
31
+ adapter_info() # Return adapter metadata as JSON
32
+ adapter_verify() # Run full verification (build + test + lint)
33
+ adapter_build() # Build project
34
+ adapter_test() # Run tests
35
+ adapter_lint() # Run linter
36
+ adapter_format() # Format code
37
+ adapter_clean() # Clean build artifacts
38
+ ```
39
+
40
+ Optional:
41
+ ```bash
42
+ adapter_run() # Run dev server
43
+ ```
44
+
45
+ ## Adding a New Adapter
46
+
47
+ **3 Steps (OCP - no core modifications):**
48
+
49
+ 1. Copy template:
50
+ ```bash
51
+ cp _template.sh elixir.sh
52
+ ```
53
+
54
+ 2. Implement all `adapter_*` functions
55
+
56
+ 3. Add detection pattern to `../detect.sh`:
57
+ ```bash
58
+ [[ -f "$dir/mix.exs" ]] && echo '{"runtime":"elixir","tool":"mix","adapter":"elixir.sh"}' && return
59
+ ```
60
+
61
+ Done! Universal scripts automatically use the new adapter.
62
+
63
+ ## Verify Adapter Compliance
64
+
65
+ ```bash
66
+ ./adapters/_interface.sh ./adapters/elixir.sh
67
+ # Output: ✓ Adapter implements all required functions
68
+ ```
@@ -0,0 +1,53 @@
1
+ #!/bin/bash
2
+ # _interface.sh - Adapter Interface Contract
3
+ # All adapters MUST implement these functions
4
+ #
5
+ # Usage: source this file to verify adapter compliance
6
+ #
7
+ # Required functions:
8
+ # adapter_info() - Return adapter metadata as JSON
9
+ # adapter_verify() - Run full verification (build + test + lint)
10
+ # adapter_build() - Build project
11
+ # adapter_test() - Run tests
12
+ # adapter_lint() - Run linter
13
+ # adapter_format() - Format code
14
+ # adapter_clean() - Clean build artifacts
15
+ #
16
+ # Optional functions:
17
+ # adapter_run() - Run dev server
18
+
19
+ REQUIRED_FUNCTIONS=(
20
+ "adapter_info"
21
+ "adapter_verify"
22
+ "adapter_build"
23
+ "adapter_test"
24
+ "adapter_lint"
25
+ "adapter_format"
26
+ "adapter_clean"
27
+ )
28
+
29
+ verify_adapter() {
30
+ local adapter_file="$1"
31
+ local missing=()
32
+
33
+ source "$adapter_file"
34
+
35
+ for func in "${REQUIRED_FUNCTIONS[@]}"; do
36
+ if ! declare -f "$func" > /dev/null 2>&1; then
37
+ missing+=("$func")
38
+ fi
39
+ done
40
+
41
+ if [ ${#missing[@]} -gt 0 ]; then
42
+ echo "ERROR: Adapter missing functions: ${missing[*]}" >&2
43
+ return 1
44
+ fi
45
+
46
+ echo "✓ Adapter $adapter_file implements all required functions"
47
+ return 0
48
+ }
49
+
50
+ # If called directly with an argument, verify that adapter
51
+ if [ $# -gt 0 ]; then
52
+ verify_adapter "$1"
53
+ fi
@@ -0,0 +1,67 @@
1
+ #!/bin/bash
2
+ # _template.sh - Template for New Adapters
3
+ # Copy this file to create a new adapter
4
+ #
5
+ # Steps to add a new language:
6
+ # 1. cp _template.sh elixir.sh
7
+ # 2. Implement all adapter_* functions
8
+ # 3. Add detection pattern to ../detect.sh
9
+ # Done! Core scripts unchanged (OCP).
10
+ #
11
+ set -euo pipefail
12
+
13
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
14
+
15
+ # Return adapter metadata as JSON
16
+ adapter_info() {
17
+ echo '{"runtime":"RUNTIME_NAME","tool":"TOOL_NAME","languages":["LANGUAGE"]}'
18
+ }
19
+
20
+ # Run full verification (compile + test + lint)
21
+ adapter_verify() {
22
+ echo "TODO: Implement verify for RUNTIME_NAME"
23
+ echo "Example: mix compile && mix test"
24
+ exit 1
25
+ }
26
+
27
+ # Build the project
28
+ adapter_build() {
29
+ echo "TODO: Implement build for RUNTIME_NAME"
30
+ echo "Example: mix release"
31
+ exit 1
32
+ }
33
+
34
+ # Run tests
35
+ adapter_test() {
36
+ echo "TODO: Implement test for RUNTIME_NAME"
37
+ echo "Example: mix test"
38
+ exit 1
39
+ }
40
+
41
+ # Run linter
42
+ adapter_lint() {
43
+ echo "TODO: Implement lint for RUNTIME_NAME"
44
+ echo "Example: mix credo"
45
+ exit 1
46
+ }
47
+
48
+ # Format code
49
+ adapter_format() {
50
+ echo "TODO: Implement format for RUNTIME_NAME"
51
+ echo "Example: mix format"
52
+ exit 1
53
+ }
54
+
55
+ # Clean build artifacts
56
+ adapter_clean() {
57
+ echo "TODO: Implement clean for RUNTIME_NAME"
58
+ echo "Example: mix clean"
59
+ exit 1
60
+ }
61
+
62
+ # Optional: Run dev server
63
+ adapter_run() {
64
+ echo "TODO: Implement run for RUNTIME_NAME"
65
+ echo "Example: mix phx.server"
66
+ exit 1
67
+ }