monol-plugin-scout 2.1.3 → 4.1.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 (87) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +244 -0
  3. package/monol-plugin-scout-pkg/CLAUDE.md +125 -8
  4. package/monol-plugin-scout-pkg/api/mock/categories.json +81 -0
  5. package/monol-plugin-scout-pkg/api/mock/insights.json +111 -0
  6. package/monol-plugin-scout-pkg/api/mock/marketplace.json +501 -0
  7. package/monol-plugin-scout-pkg/api/mock/trending.json +96 -0
  8. package/monol-plugin-scout-pkg/commands/console.md +79 -0
  9. package/monol-plugin-scout-pkg/commands/frequency.md +32 -0
  10. package/monol-plugin-scout-pkg/commands/install.md +32 -0
  11. package/monol-plugin-scout-pkg/commands/priority.md +30 -0
  12. package/monol-plugin-scout-pkg/commands/quiet.md +32 -0
  13. package/monol-plugin-scout-pkg/commands/schedule.md +32 -0
  14. package/monol-plugin-scout-pkg/commands/scout.md +8 -5
  15. package/monol-plugin-scout-pkg/commands/skills.md +160 -0
  16. package/monol-plugin-scout-pkg/commands/team.md +32 -0
  17. package/monol-plugin-scout-pkg/commands/timing.md +32 -0
  18. package/monol-plugin-scout-pkg/commands/trust.md +85 -0
  19. package/monol-plugin-scout-pkg/commands/trusted-install.md +98 -0
  20. package/monol-plugin-scout-pkg/commands/uninstall.md +31 -0
  21. package/monol-plugin-scout-pkg/config.yaml +57 -0
  22. package/monol-plugin-scout-pkg/data/.cache/676d5ab664292155e5f509c69d4edae1 +10 -0
  23. package/monol-plugin-scout-pkg/data/.session +8 -0
  24. package/monol-plugin-scout-pkg/data/analytics.json +102 -0
  25. package/monol-plugin-scout-pkg/data/history.json +67 -11
  26. package/monol-plugin-scout-pkg/data/logs/scout.log +1 -0
  27. package/monol-plugin-scout-pkg/data/schedules.json +17 -0
  28. package/monol-plugin-scout-pkg/data/team.json +53 -0
  29. package/monol-plugin-scout-pkg/data/usage.json +100 -7
  30. package/monol-plugin-scout-pkg/docs/ARCHITECTURE.md +201 -0
  31. package/monol-plugin-scout-pkg/hooks/generate-insights.sh +102 -0
  32. package/monol-plugin-scout-pkg/hooks/hooks.json +36 -1
  33. package/monol-plugin-scout-pkg/hooks/on-session-end.sh +136 -0
  34. package/monol-plugin-scout-pkg/hooks/on-session-start.sh +43 -0
  35. package/monol-plugin-scout-pkg/hooks/on-stop.md +79 -0
  36. package/monol-plugin-scout-pkg/hooks/open-console.sh +111 -0
  37. package/monol-plugin-scout-pkg/hooks/open-dashboard.sh +61 -0
  38. package/monol-plugin-scout-pkg/hooks/track-usage.sh +59 -0
  39. package/monol-plugin-scout-pkg/lib/ai-recommender.sh +505 -0
  40. package/monol-plugin-scout-pkg/lib/cache.sh +194 -0
  41. package/monol-plugin-scout-pkg/lib/data-validator.sh +360 -0
  42. package/monol-plugin-scout-pkg/lib/error-handler.sh +296 -0
  43. package/monol-plugin-scout-pkg/lib/logger.sh +263 -0
  44. package/monol-plugin-scout-pkg/lib/plugin-manager.sh +239 -0
  45. package/monol-plugin-scout-pkg/lib/priority-scorer.sh +262 -0
  46. package/monol-plugin-scout-pkg/lib/profile-learner.sh +339 -0
  47. package/monol-plugin-scout-pkg/lib/project-analyzer.sh +281 -0
  48. package/monol-plugin-scout-pkg/lib/recommendation-controller.sh +290 -0
  49. package/monol-plugin-scout-pkg/lib/rejection-learner.sh +232 -0
  50. package/monol-plugin-scout-pkg/lib/scheduler.sh +275 -0
  51. package/monol-plugin-scout-pkg/lib/skill-scout.sh +729 -0
  52. package/monol-plugin-scout-pkg/lib/sync.sh +221 -0
  53. package/monol-plugin-scout-pkg/lib/team-learner.sh +450 -0
  54. package/monol-plugin-scout-pkg/lib/team-manager.sh +369 -0
  55. package/monol-plugin-scout-pkg/lib/trend-learner.sh +428 -0
  56. package/monol-plugin-scout-pkg/lib/trust-manager.sh +261 -0
  57. package/monol-plugin-scout-pkg/lib/trusted-installer.sh +738 -0
  58. package/monol-plugin-scout-pkg/plugin.json +3 -2
  59. package/monol-plugin-scout-pkg/skills/audit.md +6 -0
  60. package/monol-plugin-scout-pkg/skills/cleanup.md +6 -0
  61. package/monol-plugin-scout-pkg/skills/compare.md +6 -0
  62. package/monol-plugin-scout-pkg/skills/console.md +315 -0
  63. package/monol-plugin-scout-pkg/skills/explore.md +6 -0
  64. package/monol-plugin-scout-pkg/skills/fork.md +6 -0
  65. package/monol-plugin-scout-pkg/skills/frequency.md +93 -0
  66. package/monol-plugin-scout-pkg/skills/install.md +127 -0
  67. package/monol-plugin-scout-pkg/skills/priority.md +77 -0
  68. package/monol-plugin-scout-pkg/skills/quiet.md +73 -0
  69. package/monol-plugin-scout-pkg/skills/schedule.md +95 -0
  70. package/monol-plugin-scout-pkg/skills/scout.md +27 -17
  71. package/monol-plugin-scout-pkg/skills/skills.md +230 -0
  72. package/monol-plugin-scout-pkg/skills/team.md +117 -0
  73. package/monol-plugin-scout-pkg/skills/timing.md +97 -0
  74. package/monol-plugin-scout-pkg/skills/trust.md +120 -0
  75. package/monol-plugin-scout-pkg/skills/trusted-install.md +264 -0
  76. package/monol-plugin-scout-pkg/skills/uninstall.md +100 -0
  77. package/monol-plugin-scout-pkg/web/components/activity-chart.js +208 -0
  78. package/monol-plugin-scout-pkg/web/components/index.js +27 -0
  79. package/monol-plugin-scout-pkg/web/components/insight-card.js +365 -0
  80. package/monol-plugin-scout-pkg/web/components/overview.js +154 -0
  81. package/monol-plugin-scout-pkg/web/components/plugin-list.js +242 -0
  82. package/monol-plugin-scout-pkg/web/components/stats-card.js +126 -0
  83. package/monol-plugin-scout-pkg/web/components/team-list.js +346 -0
  84. package/monol-plugin-scout-pkg/web/console.html +2098 -0
  85. package/monol-plugin-scout-pkg/web/dashboard.html +2106 -0
  86. package/monol-plugin-scout-pkg/web/manifest.json +29 -0
  87. package/package.json +1 -1
@@ -0,0 +1,102 @@
1
+ #!/bin/bash
2
+ # Plugin Scout - 인사이트 생성 스크립트
3
+ # 세션 시작 시 또는 콘솔 실행 시 호출
4
+
5
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$0")/..}"
6
+ DATA_DIR="$PLUGIN_ROOT/data"
7
+ USAGE_FILE="$DATA_DIR/usage.json"
8
+ ANALYTICS_FILE="$DATA_DIR/analytics.json"
9
+
10
+ # jq가 없으면 종료
11
+ if ! command -v jq &> /dev/null; then
12
+ exit 0
13
+ fi
14
+
15
+ # 파일 존재 확인
16
+ if [ ! -f "$USAGE_FILE" ] || [ ! -f "$ANALYTICS_FILE" ]; then
17
+ exit 0
18
+ fi
19
+
20
+ NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
21
+ TODAY=$(date +"%Y-%m-%d")
22
+ THIRTY_DAYS_AGO=$(date -v-30d +"%Y-%m-%d" 2>/dev/null || date -d "30 days ago" +"%Y-%m-%d" 2>/dev/null)
23
+
24
+ # 인사이트 배열 초기화
25
+ INSIGHTS="[]"
26
+
27
+ # 1. 미사용 플러그인 체크 (30일 이상)
28
+ UNUSED_PLUGINS=$(jq -r --arg threshold "$THIRTY_DAYS_AGO" '
29
+ .plugins | to_entries |
30
+ map(select(.value.lastUsed < $threshold or .value.lastUsed == null)) |
31
+ .[].key
32
+ ' "$USAGE_FILE" 2>/dev/null)
33
+
34
+ for plugin in $UNUSED_PLUGINS; do
35
+ if [ -n "$plugin" ]; then
36
+ DAYS_AGO=$(jq -r --arg p "$plugin" '.plugins[$p].lastUsed // "never"' "$USAGE_FILE")
37
+ INSIGHT=$(jq -n --arg plugin "$plugin" --arg days "$DAYS_AGO" --arg now "$NOW" '{
38
+ "type": "cleanup",
39
+ "severity": "warning",
40
+ "message": "\($plugin)이 오래 미사용 상태입니다 (마지막: \($days))",
41
+ "action": "/scout cleanup",
42
+ "generated": $now
43
+ }')
44
+ INSIGHTS=$(echo "$INSIGHTS" | jq --argjson insight "$INSIGHT" '. + [$insight]')
45
+ fi
46
+ done
47
+
48
+ # 2. 가장 많이 사용된 플러그인 분석
49
+ TOP_PLUGIN=$(jq -r '.plugins | to_entries | sort_by(.value.usageCount) | reverse | .[0].key // ""' "$USAGE_FILE" 2>/dev/null)
50
+ if [ -n "$TOP_PLUGIN" ]; then
51
+ TOP_COUNT=$(jq -r --arg p "$TOP_PLUGIN" '.plugins[$p].usageCount // 0' "$USAGE_FILE")
52
+ INSIGHT=$(jq -n --arg plugin "$TOP_PLUGIN" --arg count "$TOP_COUNT" --arg now "$NOW" '{
53
+ "type": "trend-up",
54
+ "severity": "info",
55
+ "message": "\($plugin)이 가장 활발히 사용됩니다 (\($count)회)",
56
+ "action": "",
57
+ "generated": $now
58
+ }')
59
+ INSIGHTS=$(echo "$INSIGHTS" | jq --argjson insight "$INSIGHT" '. + [$insight]')
60
+ fi
61
+
62
+ # 3. 사용량 없는 플러그인 체크
63
+ ZERO_USAGE=$(jq -r '.plugins | to_entries | map(select(.value.usageCount == 0)) | .[].key' "$USAGE_FILE" 2>/dev/null)
64
+ for plugin in $ZERO_USAGE; do
65
+ if [ -n "$plugin" ]; then
66
+ INSIGHT=$(jq -n --arg plugin "$plugin" --arg now "$NOW" '{
67
+ "type": "cleanup",
68
+ "severity": "warning",
69
+ "message": "\($plugin)이 설치 후 한 번도 사용되지 않았습니다",
70
+ "action": "/scout cleanup",
71
+ "generated": $now
72
+ }')
73
+ INSIGHTS=$(echo "$INSIGHTS" | jq --argjson insight "$INSIGHT" '. + [$insight]')
74
+ fi
75
+ done
76
+
77
+ # 4. 전체 통계 업데이트
78
+ TOTAL_PLUGINS=$(jq '.plugins | length' "$USAGE_FILE" 2>/dev/null || echo 0)
79
+ TOTAL_USAGE=$(jq '[.plugins[].usageCount] | add // 0' "$USAGE_FILE" 2>/dev/null || echo 0)
80
+ ACTIVE_PLUGINS=$(jq --arg threshold "$THIRTY_DAYS_AGO" '
81
+ [.plugins | to_entries[] | select(.value.lastUsed >= $threshold)] | length
82
+ ' "$USAGE_FILE" 2>/dev/null || echo 0)
83
+ DORMANT_PLUGINS=$((TOTAL_PLUGINS - ACTIVE_PLUGINS))
84
+
85
+ # analytics.json 업데이트
86
+ TEMP_FILE=$(mktemp)
87
+ jq --arg now "$NOW" \
88
+ --argjson total "$TOTAL_PLUGINS" \
89
+ --argjson active "$ACTIVE_PLUGINS" \
90
+ --argjson dormant "$DORMANT_PLUGINS" \
91
+ --argjson usage "$TOTAL_USAGE" \
92
+ --argjson insights "$INSIGHTS" '
93
+ .lastUpdated = $now |
94
+ .summary.totalPlugins = $total |
95
+ .summary.activePlugins = $active |
96
+ .summary.dormantPlugins = $dormant |
97
+ .summary.totalUsageCount = $usage |
98
+ .insights = $insights
99
+ ' "$ANALYTICS_FILE" > "$TEMP_FILE" && mv "$TEMP_FILE" "$ANALYTICS_FILE"
100
+
101
+ # 결과 출력 (디버그용, 필요시 주석 처리)
102
+ # echo "Insights generated: $(echo "$INSIGHTS" | jq length)"
@@ -1,3 +1,38 @@
1
1
  {
2
- "hooks": {}
2
+ "hooks": {
3
+ "Stop": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "cat ${CLAUDE_PLUGIN_ROOT}/hooks/on-stop.md",
9
+ "timeout": 5
10
+ }
11
+ ]
12
+ }
13
+ ],
14
+ "SessionStart": [
15
+ {
16
+ "matcher": "startup",
17
+ "hooks": [
18
+ {
19
+ "type": "command",
20
+ "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/on-session-start.sh",
21
+ "timeout": 10
22
+ }
23
+ ]
24
+ }
25
+ ],
26
+ "SessionEnd": [
27
+ {
28
+ "hooks": [
29
+ {
30
+ "type": "command",
31
+ "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/on-session-end.sh",
32
+ "timeout": 10
33
+ }
34
+ ]
35
+ }
36
+ ]
37
+ }
3
38
  }
@@ -0,0 +1,136 @@
1
+ #!/bin/bash
2
+ # Plugin Scout - 세션 종료 시 사용 이력 기록
3
+
4
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$0")/..}"
5
+ DATA_DIR="$PLUGIN_ROOT/data"
6
+ USAGE_FILE="$DATA_DIR/usage.json"
7
+ ANALYTICS_FILE="$DATA_DIR/analytics.json"
8
+ SESSION_FILE="$DATA_DIR/.session"
9
+
10
+ # usage.json이 없으면 초기화 (users 섹션 포함)
11
+ if [ ! -f "$USAGE_FILE" ]; then
12
+ cat > "$USAGE_FILE" << 'EOF'
13
+ {
14
+ "lastUpdated": "",
15
+ "config": {
16
+ "unusedThresholdDays": 30,
17
+ "lowUsageThreshold": 3
18
+ },
19
+ "plugins": {},
20
+ "users": {},
21
+ "sessions": {
22
+ "total": 0,
23
+ "thisWeek": 0
24
+ }
25
+ }
26
+ EOF
27
+ fi
28
+
29
+ # analytics.json이 없으면 초기화
30
+ if [ ! -f "$ANALYTICS_FILE" ]; then
31
+ cat > "$ANALYTICS_FILE" << 'EOF'
32
+ {
33
+ "version": "1.0.0",
34
+ "lastUpdated": "",
35
+ "summary": {
36
+ "totalPlugins": 0,
37
+ "activePlugins": 0,
38
+ "totalUsageCount": 0
39
+ },
40
+ "trends": {
41
+ "weekly": [],
42
+ "monthly": []
43
+ },
44
+ "pluginStats": {},
45
+ "userStats": {},
46
+ "insights": []
47
+ }
48
+ EOF
49
+ fi
50
+
51
+ # 세션 파일에서 데이터 읽기
52
+ if [ -f "$SESSION_FILE" ] && command -v jq &> /dev/null; then
53
+ TODAY=$(date +"%Y-%m-%d")
54
+ NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
55
+
56
+ # 세션에서 사용자 및 스킬 추출
57
+ SESSION_USER=$(jq -r '.user // "unknown"' "$SESSION_FILE" 2>/dev/null)
58
+ SKILLS=$(jq -r '.skills_used[]' "$SESSION_FILE" 2>/dev/null)
59
+
60
+ # 세션 카운트 증가
61
+ TEMP_FILE=$(mktemp)
62
+ jq --arg now "$NOW" '
63
+ .lastUpdated = $now |
64
+ .sessions.total += 1
65
+ ' "$USAGE_FILE" > "$TEMP_FILE" && mv "$TEMP_FILE" "$USAGE_FILE"
66
+
67
+ # 사용자별 세션 카운트
68
+ if [ -n "$SESSION_USER" ] && [ "$SESSION_USER" != "unknown" ]; then
69
+ TEMP_FILE=$(mktemp)
70
+ jq --arg user "$SESSION_USER" --arg today "$TODAY" --arg now "$NOW" '
71
+ .lastUpdated = $now |
72
+ if .users[$user] then
73
+ .users[$user].sessions += 1 |
74
+ .users[$user].lastActive = $today
75
+ else
76
+ .users[$user] = {
77
+ "plugins": {},
78
+ "sessions": 1,
79
+ "lastActive": $today,
80
+ "firstSeen": $today
81
+ }
82
+ end
83
+ ' "$USAGE_FILE" > "$TEMP_FILE" && mv "$TEMP_FILE" "$USAGE_FILE"
84
+ fi
85
+
86
+ # 스킬별 사용량 업데이트
87
+ if [ -n "$SKILLS" ]; then
88
+ for skill in $SKILLS; do
89
+ if [ -n "$skill" ]; then
90
+ # 플러그인 전체 사용량 업데이트
91
+ TEMP_FILE=$(mktemp)
92
+ jq --arg skill "$skill" --arg today "$TODAY" --arg now "$NOW" '
93
+ .lastUpdated = $now |
94
+ if .plugins[$skill] then
95
+ .plugins[$skill].usageCount += 1 |
96
+ .plugins[$skill].lastUsed = $today
97
+ else
98
+ .plugins[$skill] = {
99
+ "installed": $today,
100
+ "usageCount": 1,
101
+ "lastUsed": $today
102
+ }
103
+ end
104
+ ' "$USAGE_FILE" > "$TEMP_FILE" && mv "$TEMP_FILE" "$USAGE_FILE"
105
+
106
+ # 사용자별 플러그인 사용량 업데이트
107
+ if [ -n "$SESSION_USER" ] && [ "$SESSION_USER" != "unknown" ]; then
108
+ TEMP_FILE=$(mktemp)
109
+ jq --arg user "$SESSION_USER" --arg skill "$skill" --arg today "$TODAY" '
110
+ if .users[$user].plugins[$skill] then
111
+ .users[$user].plugins[$skill].usageCount += 1 |
112
+ .users[$user].plugins[$skill].lastUsed = $today
113
+ else
114
+ .users[$user].plugins[$skill] = {
115
+ "usageCount": 1,
116
+ "lastUsed": $today
117
+ }
118
+ end
119
+ ' "$USAGE_FILE" > "$TEMP_FILE" && mv "$TEMP_FILE" "$USAGE_FILE"
120
+ fi
121
+
122
+ # analytics.json 총 사용량 업데이트
123
+ TEMP_FILE=$(mktemp)
124
+ jq --arg now "$NOW" '
125
+ .lastUpdated = $now |
126
+ .summary.totalUsageCount += 1
127
+ ' "$ANALYTICS_FILE" > "$TEMP_FILE" && mv "$TEMP_FILE" "$ANALYTICS_FILE"
128
+ fi
129
+ done
130
+ fi
131
+
132
+ # 세션 파일 정리
133
+ rm -f "$SESSION_FILE"
134
+ fi
135
+
136
+ # 조용히 종료 (출력 없음)
@@ -0,0 +1,43 @@
1
+ #!/bin/bash
2
+ # Plugin Scout - 세션 시작 시 초기화
3
+
4
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$0")/..}"
5
+ DATA_DIR="$PLUGIN_ROOT/data"
6
+ SESSION_FILE="$DATA_DIR/.session"
7
+
8
+ # 데이터 디렉토리 확인
9
+ mkdir -p "$DATA_DIR"
10
+
11
+ # 사용자 정보 캡처
12
+ CURRENT_USER="${USER:-unknown}"
13
+ GIT_USER=$(git config user.name 2>/dev/null || echo "")
14
+ if [ -n "$GIT_USER" ]; then
15
+ CURRENT_USER="$GIT_USER"
16
+ fi
17
+
18
+ # 세션 정보 초기화 (사용자 정보 포함)
19
+ cat > "$SESSION_FILE" << EOF
20
+ {
21
+ "started": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
22
+ "user": "$CURRENT_USER",
23
+ "recommended": false,
24
+ "skills_used": []
25
+ }
26
+ EOF
27
+
28
+ # 팀에 사용자 등록 (조용히)
29
+ if [ -f "$PLUGIN_ROOT/lib/team-manager.sh" ]; then
30
+ bash "$PLUGIN_ROOT/lib/team-manager.sh" register "$CURRENT_USER" >/dev/null 2>&1
31
+ fi
32
+
33
+ # Trusted auto-install (silent, background)
34
+ if [ -f "$PLUGIN_ROOT/lib/trusted-installer.sh" ]; then
35
+ bash "$PLUGIN_ROOT/lib/trusted-installer.sh" run >/dev/null 2>&1 &
36
+ fi
37
+
38
+ # Skill scout auto-install (silent, background)
39
+ if [ -f "$PLUGIN_ROOT/lib/skill-scout.sh" ]; then
40
+ bash "$PLUGIN_ROOT/lib/skill-scout.sh" auto >/dev/null 2>&1 &
41
+ fi
42
+
43
+ # 조용히 시작 (출력 없음)
@@ -0,0 +1,79 @@
1
+ # Plugin Scout - 작업 완료 후 추천 체크 (v2.1)
2
+
3
+ 작업이 완료되었습니다. 아래 절차에 따라 플러그인 추천 여부를 결정하세요.
4
+
5
+ ## 1단계: 추천 제한 확인 (필수)
6
+
7
+ 먼저 recommendation-controller를 통해 추천 가능 여부를 확인합니다:
8
+
9
+ ```bash
10
+ bash ${CLAUDE_PLUGIN_ROOT}/lib/recommendation-controller.sh can-recommend session
11
+ ```
12
+
13
+ 결과 해석:
14
+ - `true` → 추천 가능, 2단계로 진행
15
+ - `blocked:quiet_mode` → 무음 모드 활성화됨, 추천 중단
16
+ - `blocked:session_limit` → 세션 추천 한도 도달, 추천 중단
17
+ - `blocked:daily_limit` → 일일 추천 한도 도달, 추천 중단
18
+
19
+ **중요**: `blocked:`로 시작하면 즉시 중단하고 아무것도 출력하지 마세요.
20
+
21
+ ## 2단계: 스마트 타이밍 확인
22
+
23
+ 이벤트 기반 추천이 설정된 경우:
24
+
25
+ ```bash
26
+ bash ${CLAUDE_PLUGIN_ROOT}/lib/recommendation-controller.sh timing task-complete
27
+ ```
28
+
29
+ 결과 해석:
30
+ - `true` → 타이밍 조건 충족, 3단계로 진행
31
+ - `blocked:not_after_commit` → 커밋 후에만 추천 설정됨, 추천 중단
32
+ - `blocked:not_after_pr` → PR 후에만 추천 설정됨, 추천 중단
33
+
34
+ ## 3단계: 추천 조건 검증
35
+
36
+ 다음 조건이 모두 충족되어야 추천:
37
+
38
+ 1. **의미 있는 작업 완료** - 단순 질문/답변이 아닌 코드 작성, 파일 수정 등
39
+ 2. **프로젝트 컨텍스트 존재** - package.json, pyproject.toml 등 감지됨
40
+ 3. **플러그인 관련 작업 중이 아님** - `/scout`, 플러그인 설치 등 진행 중이 아님
41
+
42
+ ## 4단계: 추천 실행
43
+
44
+ 조건 충족 시 간단히 제안:
45
+
46
+ ```
47
+ 💡 이 프로젝트에 [plugin-name] 플러그인이 도움될 수 있어요.
48
+ [한 줄 설명]
49
+ 관심있으시면 `/scout`로 더 알아보세요.
50
+ ```
51
+
52
+ ## 5단계: 추천 기록
53
+
54
+ 추천 후 반드시 기록:
55
+
56
+ ```bash
57
+ bash ${CLAUDE_PLUGIN_ROOT}/lib/recommendation-controller.sh record 1 post-task
58
+ ```
59
+
60
+ ## 설정 변경 안내
61
+
62
+ 사용자가 추천 빈도에 불만을 표시하면:
63
+
64
+ - **완전 중단**: `/scout quiet on`
65
+ - **빈도 조절**: `/scout frequency session 2` 또는 `/scout frequency daily 5`
66
+ - **타이밍 변경**: `/scout timing after-commit on`
67
+
68
+ ## 현재 상태 확인
69
+
70
+ ```bash
71
+ bash ${CLAUDE_PLUGIN_ROOT}/lib/recommendation-controller.sh status
72
+ ```
73
+
74
+ ## 추천 안 하는 경우
75
+
76
+ - recommendation-controller가 `blocked:*` 반환
77
+ - 단순 질문/답변 세션
78
+ - 프로젝트 파일이 없음
79
+ - 사용자가 플러그인 관련 작업 중
@@ -0,0 +1,111 @@
1
+ #!/bin/bash
2
+ # Plugin Scout - 웹 콘솔 열기
3
+ # 로컬 데이터를 HTML에 주입하고 브라우저에서 열기
4
+
5
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$0")/..}"
6
+ DATA_DIR="$PLUGIN_ROOT/data"
7
+ WEB_DIR="$PLUGIN_ROOT/web"
8
+ API_DIR="$PLUGIN_ROOT/api/mock"
9
+ TEMPLATE="$WEB_DIR/console.html"
10
+ OUTPUT="/tmp/plugin-scout-console.html"
11
+
12
+ # 데이터 파일 확인
13
+ USAGE_FILE="$DATA_DIR/usage.json"
14
+ ANALYTICS_FILE="$DATA_DIR/analytics.json"
15
+
16
+ if [ ! -f "$USAGE_FILE" ]; then
17
+ echo "Error: usage.json not found"
18
+ exit 1
19
+ fi
20
+
21
+ if [ ! -f "$ANALYTICS_FILE" ]; then
22
+ echo "Error: analytics.json not found"
23
+ exit 1
24
+ fi
25
+
26
+ if [ ! -f "$TEMPLATE" ]; then
27
+ echo "Error: console.html template not found"
28
+ exit 1
29
+ fi
30
+
31
+ # JSON 데이터 읽기
32
+ if command -v jq &> /dev/null; then
33
+ USAGE_JSON=$(jq -c '.' "$USAGE_FILE")
34
+ ANALYTICS_JSON=$(jq -c '.' "$ANALYTICS_FILE")
35
+
36
+ # Mock API 데이터 읽기
37
+ if [ -f "$API_DIR/marketplace.json" ]; then
38
+ MARKETPLACE_JSON=$(jq -c '.' "$API_DIR/marketplace.json")
39
+ else
40
+ MARKETPLACE_JSON='{"plugins":[],"total":0}'
41
+ fi
42
+
43
+ if [ -f "$API_DIR/categories.json" ]; then
44
+ CATEGORIES_JSON=$(jq -c '.' "$API_DIR/categories.json")
45
+ else
46
+ CATEGORIES_JSON='{"categories":[]}'
47
+ fi
48
+
49
+ if [ -f "$API_DIR/trending.json" ]; then
50
+ TRENDING_JSON=$(jq -c '.' "$API_DIR/trending.json")
51
+ else
52
+ TRENDING_JSON='{"plugins":[]}'
53
+ fi
54
+
55
+ if [ -f "$API_DIR/insights.json" ]; then
56
+ INSIGHTS_JSON=$(jq -c '.' "$API_DIR/insights.json")
57
+ else
58
+ INSIGHTS_JSON='{"insights":[]}'
59
+ fi
60
+ else
61
+ USAGE_JSON=$(cat "$USAGE_FILE" | tr -d '\n')
62
+ ANALYTICS_JSON=$(cat "$ANALYTICS_FILE" | tr -d '\n')
63
+
64
+ # Mock API 데이터 읽기 (jq 없이)
65
+ if [ -f "$API_DIR/marketplace.json" ]; then
66
+ MARKETPLACE_JSON=$(cat "$API_DIR/marketplace.json" | tr -d '\n')
67
+ else
68
+ MARKETPLACE_JSON='{"plugins":[],"total":0}'
69
+ fi
70
+
71
+ if [ -f "$API_DIR/categories.json" ]; then
72
+ CATEGORIES_JSON=$(cat "$API_DIR/categories.json" | tr -d '\n')
73
+ else
74
+ CATEGORIES_JSON='{"categories":[]}'
75
+ fi
76
+
77
+ if [ -f "$API_DIR/trending.json" ]; then
78
+ TRENDING_JSON=$(cat "$API_DIR/trending.json" | tr -d '\n')
79
+ else
80
+ TRENDING_JSON='{"plugins":[]}'
81
+ fi
82
+
83
+ if [ -f "$API_DIR/insights.json" ]; then
84
+ INSIGHTS_JSON=$(cat "$API_DIR/insights.json" | tr -d '\n')
85
+ else
86
+ INSIGHTS_JSON='{"insights":[]}'
87
+ fi
88
+ fi
89
+
90
+ # HTML 생성 (데이터 주입)
91
+ sed -e "s|__USAGE_DATA__|$USAGE_JSON|g" \
92
+ -e "s|__ANALYTICS_DATA__|$ANALYTICS_JSON|g" \
93
+ -e "s|__MARKETPLACE_DATA__|$MARKETPLACE_JSON|g" \
94
+ -e "s|__CATEGORIES_DATA__|$CATEGORIES_JSON|g" \
95
+ -e "s|__TRENDING_DATA__|$TRENDING_JSON|g" \
96
+ -e "s|__INSIGHTS_DATA__|$INSIGHTS_JSON|g" \
97
+ "$TEMPLATE" > "$OUTPUT"
98
+
99
+ # 브라우저에서 열기
100
+ if [[ "$OSTYPE" == "darwin"* ]]; then
101
+ open "$OUTPUT"
102
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
103
+ xdg-open "$OUTPUT" 2>/dev/null || sensible-browser "$OUTPUT" 2>/dev/null
104
+ elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]]; then
105
+ start "$OUTPUT"
106
+ else
107
+ echo "Console generated: $OUTPUT"
108
+ echo "Please open this file in your browser."
109
+ fi
110
+
111
+ echo "Console opened: $OUTPUT"
@@ -0,0 +1,61 @@
1
+ #!/bin/bash
2
+ # Plugin Scout - 웹 대시보드 열기
3
+ # 데이터를 HTML에 주입하고 브라우저에서 열기
4
+
5
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$0")/..}"
6
+ DATA_DIR="$PLUGIN_ROOT/data"
7
+ WEB_DIR="$PLUGIN_ROOT/web"
8
+ TEMPLATE="$WEB_DIR/dashboard.html"
9
+ OUTPUT="/tmp/plugin-scout-dashboard.html"
10
+
11
+ # 데이터 파일 확인
12
+ USAGE_FILE="$DATA_DIR/usage.json"
13
+ ANALYTICS_FILE="$DATA_DIR/analytics.json"
14
+
15
+ if [ ! -f "$USAGE_FILE" ]; then
16
+ echo "Error: usage.json not found"
17
+ exit 1
18
+ fi
19
+
20
+ if [ ! -f "$ANALYTICS_FILE" ]; then
21
+ echo "Error: analytics.json not found"
22
+ exit 1
23
+ fi
24
+
25
+ if [ ! -f "$TEMPLATE" ]; then
26
+ echo "Error: dashboard.html template not found"
27
+ exit 1
28
+ fi
29
+
30
+ # JSON 데이터 읽기 (한 줄로 압축)
31
+ USAGE_DATA=$(cat "$USAGE_FILE" | tr -d '\n' | sed 's/"/\\"/g' | sed "s/'/\\'/g")
32
+ ANALYTICS_DATA=$(cat "$ANALYTICS_FILE" | tr -d '\n' | sed 's/"/\\"/g' | sed "s/'/\\'/g")
33
+
34
+ # 템플릿에 데이터 주입
35
+ # jq가 있으면 사용, 없으면 cat 사용
36
+ if command -v jq &> /dev/null; then
37
+ USAGE_JSON=$(jq -c '.' "$USAGE_FILE")
38
+ ANALYTICS_JSON=$(jq -c '.' "$ANALYTICS_FILE")
39
+ else
40
+ USAGE_JSON=$(cat "$USAGE_FILE" | tr -d '\n')
41
+ ANALYTICS_JSON=$(cat "$ANALYTICS_FILE" | tr -d '\n')
42
+ fi
43
+
44
+ # HTML 생성 (데이터 주입)
45
+ sed -e "s|__USAGE_DATA__|$USAGE_JSON|g" \
46
+ -e "s|__ANALYTICS_DATA__|$ANALYTICS_JSON|g" \
47
+ "$TEMPLATE" > "$OUTPUT"
48
+
49
+ # 브라우저에서 열기
50
+ if [[ "$OSTYPE" == "darwin"* ]]; then
51
+ open "$OUTPUT"
52
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
53
+ xdg-open "$OUTPUT" 2>/dev/null || sensible-browser "$OUTPUT" 2>/dev/null
54
+ elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]]; then
55
+ start "$OUTPUT"
56
+ else
57
+ echo "Dashboard generated: $OUTPUT"
58
+ echo "Please open this file in your browser."
59
+ fi
60
+
61
+ echo "Dashboard opened: $OUTPUT"
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+ # Plugin Scout - 스킬 사용 추적
3
+ # 사용법: track-usage.sh <skill-name>
4
+
5
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$0")/..}"
6
+ DATA_DIR="$PLUGIN_ROOT/data"
7
+ SESSION_FILE="$DATA_DIR/.session"
8
+ SKILL_NAME="${1:-unknown}"
9
+
10
+ # sync 모듈 로드
11
+ if [ -f "$PLUGIN_ROOT/lib/sync.sh" ]; then
12
+ source "$PLUGIN_ROOT/lib/sync.sh"
13
+ fi
14
+
15
+ # 데이터 디렉토리 확인
16
+ mkdir -p "$DATA_DIR"
17
+
18
+ # 세션 파일이 없으면 생성
19
+ if [ ! -f "$SESSION_FILE" ]; then
20
+ cat > "$SESSION_FILE" << EOF
21
+ {
22
+ "started": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
23
+ "recommended": false,
24
+ "skills_used": []
25
+ }
26
+ EOF
27
+ fi
28
+
29
+ # jq가 있으면 사용, 없으면 sed로 대체
30
+ if command -v jq &> /dev/null; then
31
+ TEMP_FILE=$(mktemp)
32
+ jq --arg skill "$SKILL_NAME" '
33
+ if (.skills_used | index($skill)) then .
34
+ else .skills_used += [$skill]
35
+ end
36
+ ' "$SESSION_FILE" > "$TEMP_FILE" && mv "$TEMP_FILE" "$SESSION_FILE"
37
+ else
38
+ # jq 없이 간단한 추가 (중복 체크 없음)
39
+ if grep -q '"skills_used": \[\]' "$SESSION_FILE"; then
40
+ sed -i.bak "s/\"skills_used\": \[\]/\"skills_used\": [\"$SKILL_NAME\"]/" "$SESSION_FILE"
41
+ elif ! grep -q "\"$SKILL_NAME\"" "$SESSION_FILE"; then
42
+ sed -i.bak "s/\"skills_used\": \[/\"skills_used\": [\"$SKILL_NAME\", /" "$SESSION_FILE"
43
+ fi
44
+ rm -f "$SESSION_FILE.bak"
45
+ fi
46
+
47
+ # 서버에 스킬 사용 이벤트 전송
48
+ if type sync_skill_used &>/dev/null; then
49
+ sync_skill_used "$SKILL_NAME"
50
+ fi
51
+
52
+ # 팀 통계에 플러그인 사용 기록
53
+ if [ -f "$PLUGIN_ROOT/lib/team-manager.sh" ]; then
54
+ CURRENT_USER="${USER:-unknown}"
55
+ if command -v jq &> /dev/null && [ -f "$SESSION_FILE" ]; then
56
+ CURRENT_USER=$(jq -r '.user // "unknown"' "$SESSION_FILE")
57
+ fi
58
+ bash "$PLUGIN_ROOT/lib/team-manager.sh" record "$CURRENT_USER" "$SKILL_NAME" >/dev/null 2>&1
59
+ fi