@uzysjung/agent-harness 26.83.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.
- package/LICENSE +21 -0
- package/README.ko.md +279 -0
- package/README.md +306 -0
- package/dist/chunk-SDVAM5JZ.js +775 -0
- package/dist/chunk-SDVAM5JZ.js.map +1 -0
- package/dist/index.js +5412 -0
- package/dist/index.js.map +1 -0
- package/dist/trust-tier-drift.js +67 -0
- package/dist/trust-tier-drift.js.map +1 -0
- package/package.json +53 -0
- package/scripts/prune-ecc.sh +310 -0
- package/templates/CLAUDE.md +86 -0
- package/templates/agents/build-error-resolver.md +114 -0
- package/templates/agents/code-reviewer.md +237 -0
- package/templates/agents/data-analyst.md +69 -0
- package/templates/agents/plan-checker.md +118 -0
- package/templates/agents/reviewer.md +128 -0
- package/templates/agents/security-reviewer.md +108 -0
- package/templates/agents/silent-failure-hunter.md +50 -0
- package/templates/agents/strategist.md +86 -0
- package/templates/antigravity/AGENTS.md.template +58 -0
- package/templates/codex/AGENTS.md.template +94 -0
- package/templates/codex/README.md +69 -0
- package/templates/codex/config.toml.template +108 -0
- package/templates/codex/hooks/README.md +40 -0
- package/templates/codex/hooks/gate-check.sh +7 -0
- package/templates/codex/hooks/hito-counter.sh +7 -0
- package/templates/codex/hooks/session-start.sh +7 -0
- package/templates/codex/hooks/uncommitted-check.sh +7 -0
- package/templates/codex/skills/uzys-build/SKILL.md +24 -0
- package/templates/codex/skills/uzys-plan/SKILL.md +24 -0
- package/templates/codex/skills/uzys-review/SKILL.md +24 -0
- package/templates/codex/skills/uzys-ship/SKILL.md +24 -0
- package/templates/codex/skills/uzys-spec/SKILL.md +28 -0
- package/templates/codex/skills/uzys-test/SKILL.md +24 -0
- package/templates/commands/ecc/checkpoint.md +32 -0
- package/templates/commands/ecc/e2e.md +105 -0
- package/templates/commands/ecc/eval.md +88 -0
- package/templates/commands/ecc/evolve.md +7 -0
- package/templates/commands/ecc/harness-audit.md +73 -0
- package/templates/commands/ecc/instinct-status.md +8 -0
- package/templates/commands/ecc/promote.md +10 -0
- package/templates/commands/ecc/security-scan.md +10 -0
- package/templates/commands/uzys/auto.md +190 -0
- package/templates/commands/uzys/build.md +42 -0
- package/templates/commands/uzys/plan.md +55 -0
- package/templates/commands/uzys/review.md +44 -0
- package/templates/commands/uzys/ship.md +49 -0
- package/templates/commands/uzys/spec.md +93 -0
- package/templates/commands/uzys/test.md +58 -0
- package/templates/docs/PLAN.template.md +102 -0
- package/templates/hooks/agentshield-gate.sh +101 -0
- package/templates/hooks/checkpoint-snapshot.sh +115 -0
- package/templates/hooks/gate-check.sh +138 -0
- package/templates/hooks/hito-counter.sh +26 -0
- package/templates/hooks/karpathy-gate.sh +59 -0
- package/templates/hooks/mcp-pre-exec.sh +104 -0
- package/templates/hooks/protect-files.sh +41 -0
- package/templates/hooks/session-start.sh +40 -0
- package/templates/hooks/spec-drift-check.sh +86 -0
- package/templates/mcp-allowlist.example +24 -0
- package/templates/mcp.json +20 -0
- package/templates/opencode/.opencode/commands/uzys-build.md +22 -0
- package/templates/opencode/.opencode/commands/uzys-plan.md +22 -0
- package/templates/opencode/.opencode/commands/uzys-review.md +22 -0
- package/templates/opencode/.opencode/commands/uzys-ship.md +22 -0
- package/templates/opencode/.opencode/commands/uzys-spec.md +28 -0
- package/templates/opencode/.opencode/commands/uzys-test.md +22 -0
- package/templates/opencode/.opencode/plugins/uzys-harness.ts +146 -0
- package/templates/opencode/AGENTS.md.template +98 -0
- package/templates/opencode/README.md +34 -0
- package/templates/opencode/opencode.json.template +42 -0
- package/templates/project-claude/_base.md +23 -0
- package/templates/project-claude/fragments/csr-fastapi/active-rules.md +13 -0
- package/templates/project-claude/fragments/csr-fastapi/agents.md +5 -0
- package/templates/project-claude/fragments/csr-fastapi/boundaries.md +18 -0
- package/templates/project-claude/fragments/csr-fastapi/commands.md +6 -0
- package/templates/project-claude/fragments/csr-fastapi/plugins.md +2 -0
- package/templates/project-claude/fragments/csr-fastapi/skills.md +5 -0
- package/templates/project-claude/fragments/csr-fastapi/stack.md +6 -0
- package/templates/project-claude/fragments/csr-fastapi/tagline.md +1 -0
- package/templates/project-claude/fragments/csr-fastapi/workflow.md +8 -0
- package/templates/project-claude/fragments/csr-fastify/active-rules.md +13 -0
- package/templates/project-claude/fragments/csr-fastify/agents.md +5 -0
- package/templates/project-claude/fragments/csr-fastify/boundaries.md +18 -0
- package/templates/project-claude/fragments/csr-fastify/commands.md +6 -0
- package/templates/project-claude/fragments/csr-fastify/plugins.md +2 -0
- package/templates/project-claude/fragments/csr-fastify/skills.md +5 -0
- package/templates/project-claude/fragments/csr-fastify/stack.md +6 -0
- package/templates/project-claude/fragments/csr-fastify/tagline.md +1 -0
- package/templates/project-claude/fragments/csr-fastify/workflow.md +8 -0
- package/templates/project-claude/fragments/csr-supabase/active-rules.md +12 -0
- package/templates/project-claude/fragments/csr-supabase/agents.md +5 -0
- package/templates/project-claude/fragments/csr-supabase/boundaries.md +19 -0
- package/templates/project-claude/fragments/csr-supabase/commands.md +6 -0
- package/templates/project-claude/fragments/csr-supabase/plugins.md +4 -0
- package/templates/project-claude/fragments/csr-supabase/skills.md +7 -0
- package/templates/project-claude/fragments/csr-supabase/stack.md +6 -0
- package/templates/project-claude/fragments/csr-supabase/supabase-auth.md +21 -0
- package/templates/project-claude/fragments/csr-supabase/tagline.md +1 -0
- package/templates/project-claude/fragments/csr-supabase/workflow.md +8 -0
- package/templates/project-claude/fragments/data/active-rules.md +10 -0
- package/templates/project-claude/fragments/data/agents.md +6 -0
- package/templates/project-claude/fragments/data/boundaries.md +20 -0
- package/templates/project-claude/fragments/data/commands.md +6 -0
- package/templates/project-claude/fragments/data/plugins.md +2 -0
- package/templates/project-claude/fragments/data/skills.md +3 -0
- package/templates/project-claude/fragments/data/stack.md +7 -0
- package/templates/project-claude/fragments/data/tagline.md +1 -0
- package/templates/project-claude/fragments/data/workflow.md +9 -0
- package/templates/project-claude/fragments/executive/active-rules.md +6 -0
- package/templates/project-claude/fragments/executive/agents.md +6 -0
- package/templates/project-claude/fragments/executive/boundaries.md +17 -0
- package/templates/project-claude/fragments/executive/commands.md +11 -0
- package/templates/project-claude/fragments/executive/plugins.md +1 -0
- package/templates/project-claude/fragments/executive/skills.md +7 -0
- package/templates/project-claude/fragments/executive/stack.md +4 -0
- package/templates/project-claude/fragments/executive/tagline.md +1 -0
- package/templates/project-claude/fragments/executive/workflow.md +10 -0
- package/templates/project-claude/fragments/growth-marketing/active-rules.md +7 -0
- package/templates/project-claude/fragments/growth-marketing/agents.md +6 -0
- package/templates/project-claude/fragments/growth-marketing/boundaries.md +17 -0
- package/templates/project-claude/fragments/growth-marketing/commands.md +11 -0
- package/templates/project-claude/fragments/growth-marketing/plugins.md +9 -0
- package/templates/project-claude/fragments/growth-marketing/skills.md +8 -0
- package/templates/project-claude/fragments/growth-marketing/stack.md +7 -0
- package/templates/project-claude/fragments/growth-marketing/tagline.md +1 -0
- package/templates/project-claude/fragments/growth-marketing/workflow.md +11 -0
- package/templates/project-claude/fragments/project-management/active-rules.md +7 -0
- package/templates/project-claude/fragments/project-management/agents.md +6 -0
- package/templates/project-claude/fragments/project-management/boundaries.md +16 -0
- package/templates/project-claude/fragments/project-management/commands.md +10 -0
- package/templates/project-claude/fragments/project-management/plugins.md +6 -0
- package/templates/project-claude/fragments/project-management/skills.md +5 -0
- package/templates/project-claude/fragments/project-management/stack.md +4 -0
- package/templates/project-claude/fragments/project-management/tagline.md +1 -0
- package/templates/project-claude/fragments/project-management/workflow.md +12 -0
- package/templates/project-claude/fragments/ssr-htmx/active-rules.md +11 -0
- package/templates/project-claude/fragments/ssr-htmx/agents.md +5 -0
- package/templates/project-claude/fragments/ssr-htmx/boundaries.md +20 -0
- package/templates/project-claude/fragments/ssr-htmx/commands.md +6 -0
- package/templates/project-claude/fragments/ssr-htmx/plugins.md +2 -0
- package/templates/project-claude/fragments/ssr-htmx/skills.md +3 -0
- package/templates/project-claude/fragments/ssr-htmx/stack.md +6 -0
- package/templates/project-claude/fragments/ssr-htmx/tagline.md +1 -0
- package/templates/project-claude/fragments/ssr-htmx/workflow.md +8 -0
- package/templates/project-claude/fragments/ssr-nextjs/active-rules.md +12 -0
- package/templates/project-claude/fragments/ssr-nextjs/agents.md +5 -0
- package/templates/project-claude/fragments/ssr-nextjs/boundaries.md +20 -0
- package/templates/project-claude/fragments/ssr-nextjs/commands.md +6 -0
- package/templates/project-claude/fragments/ssr-nextjs/plugins.md +2 -0
- package/templates/project-claude/fragments/ssr-nextjs/skills.md +5 -0
- package/templates/project-claude/fragments/ssr-nextjs/stack.md +5 -0
- package/templates/project-claude/fragments/ssr-nextjs/tagline.md +1 -0
- package/templates/project-claude/fragments/ssr-nextjs/workflow.md +8 -0
- package/templates/project-claude/fragments/tooling/active-rules.md +11 -0
- package/templates/project-claude/fragments/tooling/agents.md +5 -0
- package/templates/project-claude/fragments/tooling/boundaries.md +17 -0
- package/templates/project-claude/fragments/tooling/commands.md +4 -0
- package/templates/project-claude/fragments/tooling/skills.md +4 -0
- package/templates/project-claude/fragments/tooling/stack.md +5 -0
- package/templates/project-claude/fragments/tooling/tagline.md +1 -0
- package/templates/project-claude/fragments/tooling/workflow.md +5 -0
- package/templates/rules/api-contract.md +33 -0
- package/templates/rules/change-management.md +80 -0
- package/templates/rules/cli-development.md +39 -0
- package/templates/rules/code-style.md +23 -0
- package/templates/rules/data-analysis.md +61 -0
- package/templates/rules/database.md +29 -0
- package/templates/rules/design-workflow.md +17 -0
- package/templates/rules/error-handling.md +23 -0
- package/templates/rules/gates-taxonomy.md +21 -0
- package/templates/rules/git-policy.md +102 -0
- package/templates/rules/htmx.md +42 -0
- package/templates/rules/nextjs.md +35 -0
- package/templates/rules/playwright-launch.md +66 -0
- package/templates/rules/pyside6.md +59 -0
- package/templates/rules/shadcn.md +33 -0
- package/templates/rules/ship-checklist.md +24 -0
- package/templates/rules/tauri.md +40 -0
- package/templates/rules/test-policy.md +62 -0
- package/templates/settings.json +71 -0
- package/templates/skills/agent-introspection-debugging/SKILL.md +153 -0
- package/templates/skills/continuous-learning-v2/SKILL.md +365 -0
- package/templates/skills/continuous-learning-v2/config.json +8 -0
- package/templates/skills/continuous-learning-v2/hooks/observe.sh +428 -0
- package/templates/skills/continuous-learning-v2/scripts/detect-project.sh +228 -0
- package/templates/skills/continuous-learning-v2/scripts/instinct-cli.py +1426 -0
- package/templates/skills/deep-research/SKILL.md +155 -0
- package/templates/skills/deep-research/agents/openai.yaml +7 -0
- package/templates/skills/e2e-testing/SKILL.md +326 -0
- package/templates/skills/e2e-testing/agents/openai.yaml +7 -0
- package/templates/skills/eval-harness/SKILL.md +279 -0
- package/templates/skills/eval-harness/agents/openai.yaml +7 -0
- package/templates/skills/gh-issue-workflow/ISSUE.template.md +58 -0
- package/templates/skills/gh-issue-workflow/SKILL.md +184 -0
- package/templates/skills/investor-materials/SKILL.md +96 -0
- package/templates/skills/investor-outreach/SKILL.md +91 -0
- package/templates/skills/market-research/SKILL.md +75 -0
- package/templates/skills/market-research/agents/openai.yaml +7 -0
- package/templates/skills/nextjs-turbopack/SKILL.md +44 -0
- package/templates/skills/north-star/NORTH_STAR.template.md +114 -0
- package/templates/skills/north-star/SKILL.md +103 -0
- package/templates/skills/python-patterns/SKILL.md +750 -0
- package/templates/skills/python-testing/SKILL.md +816 -0
- package/templates/skills/spec-scaling/SKILL.md +89 -0
- package/templates/skills/strategic-compact/SKILL.md +131 -0
- package/templates/skills/strategic-compact/suggest-compact.sh +54 -0
- package/templates/skills/ui-visual-review/SKILL.md +154 -0
- package/templates/skills/verification-loop/SKILL.md +126 -0
- package/templates/skills/verification-loop/agents/openai.yaml +7 -0
- package/templates/track-mcp-map.tsv +15 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# PreToolUse Hook: 워크플로우 게이트 강제
|
|
3
|
+
# Skill 도구 호출 시 이전 게이트 완료 여부 확인
|
|
4
|
+
# 미완료 시 exit code 2로 차단
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
GATE_FILE=".claude/gate-status.json"
|
|
8
|
+
INPUT_JSON=$(cat)
|
|
9
|
+
|
|
10
|
+
# tool_input에서 skill 이름 추출 (jq 우선, bash 폴백)
|
|
11
|
+
if command -v jq &> /dev/null; then
|
|
12
|
+
SKILL_NAME=$(echo "$INPUT_JSON" | jq -r '.tool_input.skill // .tool_input.args // ""' 2>/dev/null || echo "")
|
|
13
|
+
else
|
|
14
|
+
# jq 없을 때 bash 폴백
|
|
15
|
+
SKILL_NAME=$(echo "$INPUT_JSON" | grep -o '"skill"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"//')
|
|
16
|
+
if [ -z "$SKILL_NAME" ]; then
|
|
17
|
+
SKILL_NAME=$(echo "$INPUT_JSON" | grep -o '"args"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"//')
|
|
18
|
+
fi
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# uzys: 커맨드가 아니면 통과
|
|
22
|
+
# uzys:auto는 게이트 체크 제외 (auto 커맨드가 내부에서 gate-status 직접 관리)
|
|
23
|
+
case "$SKILL_NAME" in
|
|
24
|
+
uzys:spec|uzys:plan|uzys:build|uzys:test|uzys:review|uzys:ship) ;;
|
|
25
|
+
uzys:auto) exit 0 ;;
|
|
26
|
+
*) exit 0 ;;
|
|
27
|
+
esac
|
|
28
|
+
|
|
29
|
+
# gate-status.json 없으면 초기 상태 생성 (모두 미완료)
|
|
30
|
+
if [ ! -f "$GATE_FILE" ]; then
|
|
31
|
+
mkdir -p "$(dirname "$GATE_FILE")"
|
|
32
|
+
cat > "$GATE_FILE" << 'INIT'
|
|
33
|
+
{
|
|
34
|
+
"define": { "completed": false },
|
|
35
|
+
"plan": { "completed": false },
|
|
36
|
+
"build": { "completed": false },
|
|
37
|
+
"verify": { "completed": false },
|
|
38
|
+
"review": { "completed": false },
|
|
39
|
+
"ship": { "completed": false },
|
|
40
|
+
"hotfix": false
|
|
41
|
+
}
|
|
42
|
+
INIT
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# v26.11.2 — 게이트 상태 읽기. jq 실패/손상된 JSON 시 안전한 default "false"로 fail-secure.
|
|
46
|
+
# (이전: jq 실패 시 빈 출력 가능 → 호출자에서 일관성 없는 처리. C2 수정)
|
|
47
|
+
is_completed() {
|
|
48
|
+
local result=""
|
|
49
|
+
if command -v jq &> /dev/null; then
|
|
50
|
+
result=$(jq -r ".$1.completed // false" "$GATE_FILE" 2>/dev/null) || result="false"
|
|
51
|
+
else
|
|
52
|
+
grep -A1 "\"$1\"" "$GATE_FILE" 2>/dev/null | grep -o '"completed"[[:space:]]*:[[:space:]]*true' | head -1 | grep -q 'true' && result="true" || result="false"
|
|
53
|
+
fi
|
|
54
|
+
case "$result" in
|
|
55
|
+
true|false) echo "$result" ;;
|
|
56
|
+
*) echo "false" ;;
|
|
57
|
+
esac
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
is_hotfix() {
|
|
61
|
+
local result=""
|
|
62
|
+
if command -v jq &> /dev/null; then
|
|
63
|
+
result=$(jq -r ".hotfix // false" "$GATE_FILE" 2>/dev/null) || result="false"
|
|
64
|
+
else
|
|
65
|
+
grep -o '"hotfix"[[:space:]]*:[[:space:]]*true' "$GATE_FILE" 2>/dev/null | head -1 | grep -q 'true' && result="true" || result="false"
|
|
66
|
+
fi
|
|
67
|
+
case "$result" in
|
|
68
|
+
true|false) echo "$result" ;;
|
|
69
|
+
*) echo "false" ;;
|
|
70
|
+
esac
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
HOTFIX=$(is_hotfix)
|
|
74
|
+
|
|
75
|
+
# 게이트 순서 검증
|
|
76
|
+
case "$SKILL_NAME" in
|
|
77
|
+
uzys:spec)
|
|
78
|
+
# Define은 항상 허용 (첫 단계). 새 사이클 시작이므로 모든 게이트 리셋
|
|
79
|
+
cat > "$GATE_FILE" << 'RESET'
|
|
80
|
+
{
|
|
81
|
+
"define": { "completed": false },
|
|
82
|
+
"plan": { "completed": false },
|
|
83
|
+
"build": { "completed": false },
|
|
84
|
+
"verify": { "completed": false },
|
|
85
|
+
"review": { "completed": false },
|
|
86
|
+
"ship": { "completed": false },
|
|
87
|
+
"hotfix": false
|
|
88
|
+
}
|
|
89
|
+
RESET
|
|
90
|
+
exit 0
|
|
91
|
+
;;
|
|
92
|
+
uzys:plan)
|
|
93
|
+
if [ "$(is_completed define)" != "true" ]; then
|
|
94
|
+
echo "BLOCKED: Define 단계가 완료되지 않았습니다. /uzys:spec을 먼저 실행하세요. (docs/SPEC.md 필요)" >&2
|
|
95
|
+
exit 2
|
|
96
|
+
fi
|
|
97
|
+
;;
|
|
98
|
+
uzys:build)
|
|
99
|
+
if [ "$HOTFIX" = "true" ]; then
|
|
100
|
+
exit 0 # hotfix 모드: plan 건너뛰기 허용
|
|
101
|
+
fi
|
|
102
|
+
if [ "$(is_completed plan)" != "true" ]; then
|
|
103
|
+
echo "BLOCKED: Plan 단계가 완료되지 않았습니다. /uzys:plan을 먼저 실행하세요. (docs/todo.md 필요)" >&2
|
|
104
|
+
exit 2
|
|
105
|
+
fi
|
|
106
|
+
;;
|
|
107
|
+
uzys:test)
|
|
108
|
+
if [ "$(is_completed build)" != "true" ]; then
|
|
109
|
+
echo "BLOCKED: Build 단계가 완료되지 않았습니다. /uzys:build를 먼저 실행하세요." >&2
|
|
110
|
+
exit 2
|
|
111
|
+
fi
|
|
112
|
+
;;
|
|
113
|
+
uzys:review)
|
|
114
|
+
if [ "$HOTFIX" = "true" ]; then
|
|
115
|
+
exit 0 # hotfix 모드: review 건너뛰기 허용
|
|
116
|
+
fi
|
|
117
|
+
if [ "$(is_completed verify)" != "true" ]; then
|
|
118
|
+
echo "BLOCKED: Verify 단계가 완료되지 않았습니다. /uzys:test를 먼저 실행하세요." >&2
|
|
119
|
+
exit 2
|
|
120
|
+
fi
|
|
121
|
+
;;
|
|
122
|
+
uzys:ship)
|
|
123
|
+
if [ "$HOTFIX" = "true" ]; then
|
|
124
|
+
# hotfix: verify만 필수
|
|
125
|
+
if [ "$(is_completed verify)" != "true" ]; then
|
|
126
|
+
echo "BLOCKED: Hotfix 모드에서도 Verify는 필수입니다. /uzys:test를 먼저 실행하세요." >&2
|
|
127
|
+
exit 2
|
|
128
|
+
fi
|
|
129
|
+
exit 0
|
|
130
|
+
fi
|
|
131
|
+
if [ "$(is_completed review)" != "true" ]; then
|
|
132
|
+
echo "BLOCKED: Review 단계가 완료되지 않았습니다. /uzys:review를 먼저 실행하세요." >&2
|
|
133
|
+
exit 2
|
|
134
|
+
fi
|
|
135
|
+
;;
|
|
136
|
+
esac
|
|
137
|
+
|
|
138
|
+
exit 0
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ============================================================
|
|
3
|
+
# hito-counter.sh (v26.32.0)
|
|
4
|
+
# UserPromptSubmit hook — HITO (Human-In-The-Loop Occurrences) 측정용.
|
|
5
|
+
#
|
|
6
|
+
# NORTH_STAR.md NSM 추적을 위한 Phase 2 baseline 수집 인프라.
|
|
7
|
+
# 사용자 prompt submit 시마다 타임스탬프 1줄 추가.
|
|
8
|
+
# 프롬프트 내용은 기록하지 않음 (프라이버시).
|
|
9
|
+
#
|
|
10
|
+
# 로그 위치: .claude/evals/hito-YYYY-MM-DD.log
|
|
11
|
+
# 집계: `wc -l .claude/evals/hito-*.log` 로 일일 카운트
|
|
12
|
+
# 더 정밀한 분류(명시적 지시 vs 승인 vs 확인)는 수동 eval에서.
|
|
13
|
+
#
|
|
14
|
+
# Exit: 항상 0 (hook 차단 금지)
|
|
15
|
+
# ============================================================
|
|
16
|
+
|
|
17
|
+
DATE=$(date +%Y-%m-%d 2>/dev/null || echo "unknown")
|
|
18
|
+
LOG_DIR="${CLAUDE_PROJECT_DIR:-.}/.claude/evals"
|
|
19
|
+
LOG_FILE="$LOG_DIR/hito-$DATE.log"
|
|
20
|
+
|
|
21
|
+
mkdir -p "$LOG_DIR" 2>/dev/null || exit 0
|
|
22
|
+
|
|
23
|
+
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo "?")
|
|
24
|
+
echo "$TS prompt_submit" >> "$LOG_FILE" 2>/dev/null
|
|
25
|
+
|
|
26
|
+
exit 0
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# karpathy Gate — Claude Code PreToolUse hook (Write|Edit matcher, non-blocking warn).
|
|
3
|
+
#
|
|
4
|
+
# v0.6.0 cherry-pick from alirezarezvani/claude-skills@f567c61
|
|
5
|
+
# src: engineering/karpathy-coder/hooks/karpathy-gate.sh
|
|
6
|
+
# License: MIT (alirezarezvani/claude-skills)
|
|
7
|
+
#
|
|
8
|
+
# Adapt for Claude Code PreToolUse context:
|
|
9
|
+
# - upstream은 git pre-commit (staged files) context 가정
|
|
10
|
+
# - 본 스크립트는 PreToolUse Write|Edit — Claude가 코드 작성 직전 발동
|
|
11
|
+
# - stdin으로 tool_input JSON 받음 (Claude Code hook spec)
|
|
12
|
+
# - file_path 추출 → Python 도구로 complexity 검사 (best-effort)
|
|
13
|
+
# - 비차단 (exit 0 항상) — upstream "warn, doesn't reject" 정신 유지
|
|
14
|
+
#
|
|
15
|
+
# Python 3 + plugin scripts 부재 시 graceful exit (commit/edit 차단 X).
|
|
16
|
+
|
|
17
|
+
# 어떤 실패도 차단 안 함
|
|
18
|
+
set +e
|
|
19
|
+
|
|
20
|
+
# stdin tool_input JSON 읽기 (Claude Code hook spec: PreToolUse 시 자동 주입)
|
|
21
|
+
INPUT=$(cat 2>/dev/null || echo "")
|
|
22
|
+
|
|
23
|
+
# file_path 추출 — jq 우선, grep 폴백 (cli-development.md hook 컨벤션)
|
|
24
|
+
# jq 가용 시: escape 처리 정확. 미설치 시: grep+sed (단순 케이스만)
|
|
25
|
+
if command -v jq >/dev/null 2>&1; then
|
|
26
|
+
FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null || echo "")
|
|
27
|
+
else
|
|
28
|
+
FILE_PATH=$(printf '%s' "$INPUT" | grep -o '"file_path":"[^"]*"' | head -1 | sed 's/"file_path":"//; s/"$//')
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# 짧은 reminder — 모든 Write|Edit 시점에 출력 (4 원칙 환기)
|
|
32
|
+
printf '[karpathy] Think Before / Simplicity / Surgical / Goal-Driven\n' >&2
|
|
33
|
+
|
|
34
|
+
# Python 3 + plugin scripts 가용 시만 complexity 검사
|
|
35
|
+
SCRIPT_DIR="${CLAUDE_PLUGIN_ROOT:-}/scripts"
|
|
36
|
+
if ! command -v python3 >/dev/null 2>&1; then
|
|
37
|
+
# Python 3 부재 — reminder만 출력하고 종료
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
if [ ! -d "$SCRIPT_DIR" ]; then
|
|
41
|
+
# plugin 미설치 또는 ${CLAUDE_PLUGIN_ROOT} 미세팅
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
if [ -z "$FILE_PATH" ]; then
|
|
45
|
+
# tool_input 파싱 실패 또는 file_path 없음
|
|
46
|
+
exit 0
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# 코드 파일 한정
|
|
50
|
+
case "$FILE_PATH" in
|
|
51
|
+
*.py|*.ts|*.tsx|*.js|*.jsx)
|
|
52
|
+
# complexity_checker 실행, WARN만 stderr로
|
|
53
|
+
python3 "$SCRIPT_DIR/complexity_checker.py" "$FILE_PATH" --threshold medium 2>/dev/null \
|
|
54
|
+
| grep -E "^[[:space:]]+\[WARN\]" >&2 \
|
|
55
|
+
|| true
|
|
56
|
+
;;
|
|
57
|
+
esac
|
|
58
|
+
|
|
59
|
+
exit 0
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ============================================================
|
|
3
|
+
# mcp-pre-exec.sh — PreToolUse hook (mcp__.* matcher)
|
|
4
|
+
#
|
|
5
|
+
# 목적: MCP tool 호출을 화이트리스트 + 위험 패턴으로 차단.
|
|
6
|
+
# CVE-2025-59536, CVE-2026-21852 (hooks/MCP RCE) 대응.
|
|
7
|
+
#
|
|
8
|
+
# 호출: templates/settings.json의 PreToolUse 매처 "mcp__.*" 에서 실행.
|
|
9
|
+
# 입력: stdin JSON (tool_name, tool_input, cwd, session_id, ...)
|
|
10
|
+
# 출력: stderr 경고 + exit 2 차단 또는 exit 0 통과
|
|
11
|
+
#
|
|
12
|
+
# 화이트리스트: $CLAUDE_PROJECT_DIR/.mcp-allowlist
|
|
13
|
+
# - 한 줄에 하나의 서버 이름 (예: context7, github, chrome-devtools)
|
|
14
|
+
# - '#' 주석, 빈 줄 허용
|
|
15
|
+
# - 파일 없으면 모든 MCP 호출 통과 (opt-in 구조 — 사용자가 의도적으로 활성)
|
|
16
|
+
#
|
|
17
|
+
# 위험 파라미터 패턴: stdin의 tool_input에 다음 패턴 감지 시 차단
|
|
18
|
+
# - rm -rf, curl | sh, wget | bash, eval, base64 decode + exec
|
|
19
|
+
#
|
|
20
|
+
# Exit codes:
|
|
21
|
+
# 0: 통과 (MCP 아님, 화이트리스트 매칭, 또는 allowlist 없음)
|
|
22
|
+
# 2: 차단 (서버 비매칭 또는 위험 패턴 감지)
|
|
23
|
+
# ============================================================
|
|
24
|
+
set -u
|
|
25
|
+
|
|
26
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
27
|
+
ALLOWLIST="$PROJECT_DIR/.mcp-allowlist"
|
|
28
|
+
|
|
29
|
+
# stdin JSON 파싱
|
|
30
|
+
INPUT=$(cat 2>/dev/null || echo "{}")
|
|
31
|
+
|
|
32
|
+
TOOL_NAME=""
|
|
33
|
+
if command -v jq &>/dev/null; then
|
|
34
|
+
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null || echo "")
|
|
35
|
+
else
|
|
36
|
+
# jq 없을 때 bash 폴백
|
|
37
|
+
TOOL_NAME=$(echo "$INPUT" | grep -oE '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' | sed -E 's/.*"([^"]*)"$/\1/')
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# MCP tool 이 아니면 즉시 통과
|
|
41
|
+
case "$TOOL_NAME" in
|
|
42
|
+
mcp__*__*) ;;
|
|
43
|
+
*) exit 0 ;;
|
|
44
|
+
esac
|
|
45
|
+
|
|
46
|
+
# 서버 이름 추출: mcp__<server>__<tool> → <server>
|
|
47
|
+
SERVER_NAME=$(echo "$TOOL_NAME" | awk -F'__' '{print $2}')
|
|
48
|
+
|
|
49
|
+
if [ -z "$SERVER_NAME" ]; then
|
|
50
|
+
echo "[mcp-pre-exec] WARN: cannot extract server name from '$TOOL_NAME'" >&2
|
|
51
|
+
exit 0
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# 화이트리스트 대조 (파일 없으면 opt-in 미활성 — 통과)
|
|
55
|
+
if [ ! -f "$ALLOWLIST" ]; then
|
|
56
|
+
exit 0
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# 화이트리스트에 서버 있는지 확인 (주석/빈 줄 제외)
|
|
60
|
+
MATCHED=false
|
|
61
|
+
while IFS= read -r line; do
|
|
62
|
+
# 주석과 빈 줄 skip
|
|
63
|
+
case "$line" in
|
|
64
|
+
""|"#"*) continue ;;
|
|
65
|
+
esac
|
|
66
|
+
# trim whitespace
|
|
67
|
+
clean=$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
68
|
+
if [ "$clean" = "$SERVER_NAME" ]; then
|
|
69
|
+
MATCHED=true
|
|
70
|
+
break
|
|
71
|
+
fi
|
|
72
|
+
done < "$ALLOWLIST"
|
|
73
|
+
|
|
74
|
+
if [ "$MATCHED" = false ]; then
|
|
75
|
+
echo "[mcp-pre-exec] BLOCKED: MCP server '$SERVER_NAME' not in allowlist" >&2
|
|
76
|
+
echo "" >&2
|
|
77
|
+
echo "Tool: $TOOL_NAME" >&2
|
|
78
|
+
echo "Allowlist: $ALLOWLIST" >&2
|
|
79
|
+
echo "" >&2
|
|
80
|
+
echo "이 서버를 허용하려면 '$SERVER_NAME'을 $ALLOWLIST 에 한 줄로 추가." >&2
|
|
81
|
+
exit 2
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# 위험 파라미터 패턴 검사 (tool_input 전체를 문자열로)
|
|
85
|
+
TOOL_INPUT_JSON=""
|
|
86
|
+
if command -v jq &>/dev/null; then
|
|
87
|
+
TOOL_INPUT_JSON=$(echo "$INPUT" | jq -r '.tool_input // empty' 2>/dev/null || echo "")
|
|
88
|
+
else
|
|
89
|
+
TOOL_INPUT_JSON=$(echo "$INPUT" | grep -oE '"tool_input"[[:space:]]*:[[:space:]]*\{[^}]*\}')
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
if [ -n "$TOOL_INPUT_JSON" ]; then
|
|
93
|
+
if echo "$TOOL_INPUT_JSON" | grep -qE "rm -rf|curl[^|]*\| *sh|wget[^|]*\| *bash|\beval\b.*\\\$|base64[[:space:]]+-d.*\| *sh"; then
|
|
94
|
+
echo "[mcp-pre-exec] BLOCKED: suspicious parameter pattern in tool_input" >&2
|
|
95
|
+
echo "" >&2
|
|
96
|
+
echo "Tool: $TOOL_NAME" >&2
|
|
97
|
+
echo "위험 패턴 감지: rm -rf / curl|sh / wget|bash / eval \$... / base64-d|sh" >&2
|
|
98
|
+
echo "" >&2
|
|
99
|
+
echo "의도된 사용이면 .mcp-allowlist 대신 이 서버의 다른 호출 경로 검토 필요." >&2
|
|
100
|
+
exit 2
|
|
101
|
+
fi
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
exit 0
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# PreToolUse Hook: Write/Edit 대상이 보호 파일이면 차단
|
|
3
|
+
# Python 의존 없음 — jq 또는 순수 bash로 동작
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
INPUT_JSON=$(cat)
|
|
7
|
+
|
|
8
|
+
# jq가 있으면 사용, 없으면 grep 폴백
|
|
9
|
+
if command -v jq &> /dev/null; then
|
|
10
|
+
FILE_PATH=$(echo "$INPUT_JSON" | jq -r '.tool_input.file_path // .tool_input.path // ""' 2>/dev/null)
|
|
11
|
+
else
|
|
12
|
+
# 순수 bash 폴백: file_path 추출
|
|
13
|
+
FILE_PATH=$(echo "$INPUT_JSON" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"//')
|
|
14
|
+
if [ -z "$FILE_PATH" ]; then
|
|
15
|
+
FILE_PATH=$(echo "$INPUT_JSON" | grep -o '"path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"//')
|
|
16
|
+
fi
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
if [ -z "$FILE_PATH" ]; then
|
|
20
|
+
exit 0
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
BASENAME=$(basename "$FILE_PATH")
|
|
24
|
+
|
|
25
|
+
# 보호 패턴 확인
|
|
26
|
+
case "$BASENAME" in
|
|
27
|
+
.env|.env.*)
|
|
28
|
+
echo "BLOCKED: Protected file: $BASENAME. Environment files must be edited manually." >&2
|
|
29
|
+
exit 2
|
|
30
|
+
;;
|
|
31
|
+
package-lock.json|yarn.lock|pnpm-lock.yaml|Cargo.lock|poetry.lock|uv.lock)
|
|
32
|
+
echo "BLOCKED: Protected file: $BASENAME. Lock files should not be edited directly." >&2
|
|
33
|
+
exit 2
|
|
34
|
+
;;
|
|
35
|
+
*.pem|*.key|*.p12|*.pfx)
|
|
36
|
+
echo "BLOCKED: Protected file: $BASENAME. Certificate/key files must not be modified by agents." >&2
|
|
37
|
+
exit 2
|
|
38
|
+
;;
|
|
39
|
+
esac
|
|
40
|
+
|
|
41
|
+
exit 0
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Session Start Hook
|
|
3
|
+
# git pull + 세션 컨텍스트 출력 + compact-warning.flag 감지
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
|
|
7
|
+
|
|
8
|
+
# 1. git pull (branch가 있고 detached HEAD가 아닐 때)
|
|
9
|
+
if [ -n "$BRANCH" ] && [ "$BRANCH" != "HEAD" ]; then
|
|
10
|
+
git pull --rebase 2>/dev/null || true
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
# 2. SPEC 존재 여부 확인
|
|
14
|
+
SPEC_EXISTS="false"
|
|
15
|
+
if [ -f "docs/SPEC.md" ] || [ -f "SPEC.md" ]; then
|
|
16
|
+
SPEC_EXISTS="true"
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# 3. compact-warning.flag 감지 (이전 세션에서 checkpoint-snapshot이 생성)
|
|
20
|
+
COMPACT_WARNING=""
|
|
21
|
+
WARNING_FLAG=".claude/compact-warning.flag"
|
|
22
|
+
if [ -f "$WARNING_FLAG" ]; then
|
|
23
|
+
LAST_CHECKPOINT=$(cat "$WARNING_FLAG" 2>/dev/null || echo "unknown")
|
|
24
|
+
COMPACT_WARNING=" Checkpoint saved at $LAST_CHECKPOINT — run /compact soon to reclaim context."
|
|
25
|
+
rm -f "$WARNING_FLAG"
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# 4. 세션 컨텍스트 출력
|
|
29
|
+
if [ "$SPEC_EXISTS" = "true" ]; then
|
|
30
|
+
MSG="Session started. Branch: ${BRANCH:-detached}. SPEC exists — read docs/SPEC.md first (Persistent Anchor). Check Change Log and current Phase before starting work.${COMPACT_WARNING}"
|
|
31
|
+
else
|
|
32
|
+
MSG="Session started. Branch: ${BRANCH:-detached}. No SPEC found. Use /uzys:spec to begin workflow.${COMPACT_WARNING}"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
cat <<EOF
|
|
36
|
+
{
|
|
37
|
+
"priority": "INFO",
|
|
38
|
+
"message": "$MSG"
|
|
39
|
+
}
|
|
40
|
+
EOF
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# spec-drift-check.sh
|
|
3
|
+
# SPEC.md/todo.md/PRD.md의 drift를 검출한다.
|
|
4
|
+
# Verify 또는 Ship 단계에서 호출 가능.
|
|
5
|
+
#
|
|
6
|
+
# 검출 항목:
|
|
7
|
+
# 1. SPEC.md의 Verification Checklist에 unchecked 항목 존재
|
|
8
|
+
# 2. todo.md의 unchecked 항목 존재
|
|
9
|
+
# 3. SPEC.md Status가 "Define"인데 build/verify gate가 완료된 경우
|
|
10
|
+
# 4. PRD.md Status가 In Progress인데 모든 Phase가 Complete인 경우
|
|
11
|
+
#
|
|
12
|
+
# Exit codes:
|
|
13
|
+
# 0: drift 없음
|
|
14
|
+
# 1: drift 발견 (경고 출력)
|
|
15
|
+
# 2: 차단 수준 drift (Ship 게이트에서 차단)
|
|
16
|
+
set -e
|
|
17
|
+
|
|
18
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
19
|
+
DOCS_DIR="$PROJECT_DIR/docs"
|
|
20
|
+
[ ! -d "$DOCS_DIR" ] && DOCS_DIR="$PROJECT_DIR/Docs"
|
|
21
|
+
|
|
22
|
+
DRIFT=0
|
|
23
|
+
BLOCK=0
|
|
24
|
+
|
|
25
|
+
count_unchecked() {
|
|
26
|
+
local file="$1"
|
|
27
|
+
grep -c "^- \[ \]\|^ - \[ \]" "$file" 2>/dev/null | tail -1 | tr -d ' \n'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# 1. SPEC.md unchecked 검사
|
|
31
|
+
if [ -f "$DOCS_DIR/SPEC.md" ]; then
|
|
32
|
+
UNCHECKED=$(count_unchecked "$DOCS_DIR/SPEC.md")
|
|
33
|
+
UNCHECKED=${UNCHECKED:-0}
|
|
34
|
+
if [ "$UNCHECKED" -gt 0 ] 2>/dev/null; then
|
|
35
|
+
echo "DRIFT: SPEC.md에 unchecked 항목 ${UNCHECKED}건" >&2
|
|
36
|
+
DRIFT=$((DRIFT + 1))
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# 2. todo.md unchecked 검사
|
|
41
|
+
if [ -f "$DOCS_DIR/todo.md" ]; then
|
|
42
|
+
UNCHECKED=$(count_unchecked "$DOCS_DIR/todo.md")
|
|
43
|
+
UNCHECKED=${UNCHECKED:-0}
|
|
44
|
+
if [ "$UNCHECKED" -gt 0 ] 2>/dev/null; then
|
|
45
|
+
echo "DRIFT: todo.md에 unchecked 항목 ${UNCHECKED}건" >&2
|
|
46
|
+
DRIFT=$((DRIFT + 1))
|
|
47
|
+
fi
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# 3. SPEC.md Status 일관성 — gate-status.json과 대조
|
|
51
|
+
GATE_FILE="$PROJECT_DIR/.claude/gate-status.json"
|
|
52
|
+
if [ -f "$GATE_FILE" ] && [ -f "$DOCS_DIR/SPEC.md" ] && command -v jq &> /dev/null; then
|
|
53
|
+
BUILD_DONE=$(jq -r '.build.completed // false' "$GATE_FILE")
|
|
54
|
+
VERIFY_DONE=$(jq -r '.verify.completed // false' "$GATE_FILE")
|
|
55
|
+
|
|
56
|
+
# SPEC Status가 "Define"인지 확인 (frontmatter 형식만, 본문 파이프라인 설명 제외)
|
|
57
|
+
if grep -qE "^> \*\*Status\*\*:.*Define" "$DOCS_DIR/SPEC.md"; then
|
|
58
|
+
if [ "$BUILD_DONE" = "true" ] || [ "$VERIFY_DONE" = "true" ]; then
|
|
59
|
+
echo "DRIFT: SPEC.md Status='Define'인데 Build/Verify gate가 완료됨" >&2
|
|
60
|
+
DRIFT=$((DRIFT + 1))
|
|
61
|
+
# Ship 게이트에서는 차단 (Build 이후에도 SPEC이 Define이면 안 됨)
|
|
62
|
+
[ "$1" = "ship" ] && BLOCK=1
|
|
63
|
+
fi
|
|
64
|
+
fi
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# 4. Ship 단계에서는 모든 unchecked가 차단
|
|
68
|
+
if [ "$1" = "ship" ] && [ "$DRIFT" -gt 0 ]; then
|
|
69
|
+
BLOCK=1
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Summary
|
|
73
|
+
if [ "$DRIFT" -eq 0 ]; then
|
|
74
|
+
echo "OK: SPEC/todo/PRD 동기화 상태 정상"
|
|
75
|
+
exit 0
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
if [ "$BLOCK" -eq 1 ]; then
|
|
79
|
+
echo "" >&2
|
|
80
|
+
echo "BLOCKED (ship gate): SPEC drift 발견 — SPEC.md, todo.md, PRD.md 동기화 후 재시도" >&2
|
|
81
|
+
exit 2
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
echo "" >&2
|
|
85
|
+
echo "WARNING: SPEC drift ${DRIFT}건. 동기화 권장." >&2
|
|
86
|
+
exit 1
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# MCP Server Allowlist — opt-in security gate
|
|
2
|
+
#
|
|
3
|
+
# mcp-pre-exec.sh hook이 이 파일을 참조해 MCP 서버 호출을 화이트리스트
|
|
4
|
+
# 방식으로 차단한다. 파일이 없으면 opt-in 미활성 (모든 MCP 호출 통과).
|
|
5
|
+
#
|
|
6
|
+
# 사용법:
|
|
7
|
+
# 1. 이 파일을 프로젝트 루트에 `.mcp-allowlist` 이름으로 복사
|
|
8
|
+
# 2. 허용할 MCP 서버 이름을 한 줄에 하나씩 작성
|
|
9
|
+
# 3. '#' 주석과 빈 줄 허용
|
|
10
|
+
#
|
|
11
|
+
# 서버 이름 확인 방법:
|
|
12
|
+
# - .mcp.json의 `mcpServers` 필드 키 이름
|
|
13
|
+
# - 또는 PreToolUse에서 tool_name `mcp__<server>__<tool>` 의 <server>
|
|
14
|
+
#
|
|
15
|
+
# 기본 프로젝트 서버 (templates/mcp.json):
|
|
16
|
+
context7
|
|
17
|
+
github
|
|
18
|
+
chrome-devtools
|
|
19
|
+
|
|
20
|
+
# Track별 추가 서버 예시 (주석 해제 후 사용):
|
|
21
|
+
# supabase # csr-supabase Track
|
|
22
|
+
# railway # 배포 Track
|
|
23
|
+
# notion # executive Track
|
|
24
|
+
# playwright # UI Track
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "프로젝트 .mcp.json 템플릿. setup-harness.sh가 Track별로 조건부 항목을 동적 추가한다. 글로벌 ~/.claude/는 절대 건드리지 않음.",
|
|
3
|
+
"mcpServers": {
|
|
4
|
+
"context7": {
|
|
5
|
+
"type": "stdio",
|
|
6
|
+
"command": "npx",
|
|
7
|
+
"args": ["-y", "@upstash/context7-mcp@latest"]
|
|
8
|
+
},
|
|
9
|
+
"github": {
|
|
10
|
+
"type": "stdio",
|
|
11
|
+
"command": "npx",
|
|
12
|
+
"args": ["-y", "@modelcontextprotocol/server-github"]
|
|
13
|
+
},
|
|
14
|
+
"chrome-devtools": {
|
|
15
|
+
"type": "stdio",
|
|
16
|
+
"command": "npx",
|
|
17
|
+
"args": ["-y", "chrome-devtools-mcp@latest"]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Build phase — TDD로 점진적 구현한다."
|
|
3
|
+
agent: build
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /uzys-build — OpenCode
|
|
7
|
+
|
|
8
|
+
> **Generated from**: `.claude/commands/uzys/build.md` via TS CLI `src/opencode/skills.ts` (Phase C)
|
|
9
|
+
> **Slash**: `/uzys-build` (OpenCode namespace 미사용 — Phase B2 결정, hyphen 채택)
|
|
10
|
+
|
|
11
|
+
## Goal
|
|
12
|
+
|
|
13
|
+
{COMMAND_BODY_PLACEHOLDER}
|
|
14
|
+
|
|
15
|
+
## OpenCode 제약 참고
|
|
16
|
+
|
|
17
|
+
- Slash 콜론 namespace 미사용 — 파일명 = 커맨드명 (`uzys-build.md` → `/uzys-build`)
|
|
18
|
+
- Plugin lifecycle (`.opencode/plugins/uzys-harness.ts`)이 gate-check / spec-drift / HITO 처리
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
*Phase C에서 본 command 본문이 `.claude/commands/uzys/build.md`로부터 포팅됨.*
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Plan phase — 작업을 검증 가능한 작은 단위로 분해한다."
|
|
3
|
+
agent: plan
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /uzys-plan — OpenCode
|
|
7
|
+
|
|
8
|
+
> **Generated from**: `.claude/commands/uzys/plan.md` via TS CLI `src/opencode/skills.ts` (Phase C)
|
|
9
|
+
> **Slash**: `/uzys-plan` (OpenCode namespace 미사용 — Phase B2 결정, hyphen 채택)
|
|
10
|
+
|
|
11
|
+
## Goal
|
|
12
|
+
|
|
13
|
+
{COMMAND_BODY_PLACEHOLDER}
|
|
14
|
+
|
|
15
|
+
## OpenCode 제약 참고
|
|
16
|
+
|
|
17
|
+
- Slash 콜론 namespace 미사용 — 파일명 = 커맨드명 (`uzys-plan.md` → `/uzys-plan`)
|
|
18
|
+
- Plugin lifecycle (`.opencode/plugins/uzys-harness.ts`)이 gate-check / spec-drift / HITO 처리
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
*Phase C에서 본 command 본문이 `.claude/commands/uzys/plan.md`로부터 포팅됨.*
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Review phase — 다중 관점 리뷰로 품질을 검증한다."
|
|
3
|
+
agent: plan
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /uzys-review — OpenCode
|
|
7
|
+
|
|
8
|
+
> **Generated from**: `.claude/commands/uzys/review.md` via TS CLI `src/opencode/skills.ts` (Phase C)
|
|
9
|
+
> **Slash**: `/uzys-review` (OpenCode namespace 미사용 — Phase B2 결정, hyphen 채택)
|
|
10
|
+
|
|
11
|
+
## Goal
|
|
12
|
+
|
|
13
|
+
{COMMAND_BODY_PLACEHOLDER}
|
|
14
|
+
|
|
15
|
+
## OpenCode 제약 참고
|
|
16
|
+
|
|
17
|
+
- Slash 콜론 namespace 미사용 — 파일명 = 커맨드명 (`uzys-review.md` → `/uzys-review`)
|
|
18
|
+
- Plugin lifecycle (`.opencode/plugins/uzys-harness.ts`)이 gate-check / spec-drift / HITO 처리
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
*Phase C에서 본 command 본문이 `.claude/commands/uzys/review.md`로부터 포팅됨.*
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Ship phase — 프리런치 체크리스트 실행 후 배포한다."
|
|
3
|
+
agent: build
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /uzys-ship — OpenCode
|
|
7
|
+
|
|
8
|
+
> **Generated from**: `.claude/commands/uzys/ship.md` via TS CLI `src/opencode/skills.ts` (Phase C)
|
|
9
|
+
> **Slash**: `/uzys-ship` (OpenCode namespace 미사용 — Phase B2 결정, hyphen 채택)
|
|
10
|
+
|
|
11
|
+
## Goal
|
|
12
|
+
|
|
13
|
+
{COMMAND_BODY_PLACEHOLDER}
|
|
14
|
+
|
|
15
|
+
## OpenCode 제약 참고
|
|
16
|
+
|
|
17
|
+
- Slash 콜론 namespace 미사용 — 파일명 = 커맨드명 (`uzys-ship.md` → `/uzys-ship`)
|
|
18
|
+
- Plugin lifecycle (`.opencode/plugins/uzys-harness.ts`)이 gate-check / spec-drift / HITO 처리
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
*Phase C에서 본 command 본문이 `.claude/commands/uzys/ship.md`로부터 포팅됨.*
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Define phase — 구조화된 스펙을 코드 작성 전에 작성한다."
|
|
3
|
+
agent: plan
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /uzys-spec — Define Phase (OpenCode)
|
|
7
|
+
|
|
8
|
+
> **Generated from**: `.claude/commands/uzys/spec.md` via TS CLI `src/opencode/skills.ts` (Phase C)
|
|
9
|
+
> **Slash**: `/uzys-spec` (OpenCode namespace 미사용 — Phase B2 결정, hyphen 채택)
|
|
10
|
+
|
|
11
|
+
## Pre-flight
|
|
12
|
+
|
|
13
|
+
이 command 호출 전 확인:
|
|
14
|
+
- 직전 단계 없음 (최초 진입점)
|
|
15
|
+
- `docs/SPEC.md` 또는 `docs/specs/<feature>.md`가 아직 없거나 갱신 필요한 상황
|
|
16
|
+
|
|
17
|
+
## Goal
|
|
18
|
+
|
|
19
|
+
{COMMAND_BODY_PLACEHOLDER}
|
|
20
|
+
|
|
21
|
+
## OpenCode 제약 참고
|
|
22
|
+
|
|
23
|
+
- Slash 콜론 namespace 미사용 — 파일명 = 커맨드명 (`uzys-spec.md` → `/uzys-spec`)
|
|
24
|
+
- Plugin lifecycle (`.opencode/plugins/uzys-harness.ts`)이 gate-check / spec-drift / HITO 처리
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
*Phase C에서 본 command 본문이 `.claude/commands/uzys/spec.md`로부터 포팅됨.*
|