@walwal-harness/cli 6.0.4 → 6.0.5
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/CHANGELOG.md +21 -0
- package/bin/init.js +121 -4
- package/package.json +1 -1
- package/scripts/harness-archive.sh +0 -109
- package/scripts/harness-dashboard-up.sh +0 -72
- package/scripts/harness-dashboard.sh +0 -509
- package/scripts/harness-goal-init.sh +0 -72
- package/scripts/harness-goal-show.sh +0 -37
- package/scripts/harness-gotcha-memory.sh +0 -348
- package/scripts/harness-gotcha-register.sh +0 -393
- package/scripts/harness-monitor.sh +0 -398
- package/scripts/harness-next.sh +0 -546
- package/scripts/harness-progress-set.sh +0 -41
- package/scripts/harness-prompt-history.sh +0 -164
- package/scripts/harness-queue-manager.sh +0 -694
- package/scripts/harness-session-start.sh +0 -129
- package/scripts/harness-statusline.sh +0 -139
- package/scripts/harness-tmux.sh +0 -372
- package/scripts/harness-user-prompt-submit.sh +0 -105
- package/scripts/init-agents-md.sh +0 -337
- package/scripts/init-ref-docs.sh +0 -262
- package/scripts/lib/harness-audit.sh +0 -113
- package/scripts/lib/harness-guardrail.sh +0 -148
- package/scripts/lib/harness-keywait.sh +0 -57
- package/scripts/lib/harness-render-progress.sh +0 -346
- package/scripts/scan-project.sh +0 -367
|
@@ -1,393 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# harness-gotcha-register.sh — Evaluator → Gotcha 자동 등록 파이프라인
|
|
3
|
-
#
|
|
4
|
-
# 사용법:
|
|
5
|
-
# 1) 단일 항목 등록 (수동/스크립트):
|
|
6
|
-
# bash harness-gotcha-register.sh <project-root> \
|
|
7
|
-
# --target <agent> \
|
|
8
|
-
# --rule-id <rule-id> \
|
|
9
|
-
# --title "제목" \
|
|
10
|
-
# --wrong "잘못된 행동" \
|
|
11
|
-
# --right "올바른 행동" \
|
|
12
|
-
# --why "근거" \
|
|
13
|
-
# --scope "적용 범위" \
|
|
14
|
-
# --source "evaluator-functional:F-003"
|
|
15
|
-
#
|
|
16
|
-
# 2) 일괄 등록 (JSON stdin/파일):
|
|
17
|
-
# bash harness-gotcha-register.sh <project-root> --from-json <path>
|
|
18
|
-
# bash harness-gotcha-register.sh <project-root> --scan-evaluations
|
|
19
|
-
# └ .harness/actions/evaluation-*.md 의 ```gotcha_candidates``` 블록 전부 스캔
|
|
20
|
-
#
|
|
21
|
-
# 동작:
|
|
22
|
-
# - 대상 파일: .harness/gotchas/<target>.md (없으면 생성)
|
|
23
|
-
# - 중복 감지: 동일 rule_id 가 있으면 Occurrences +1, last_seen 갱신 (본문 수정 없음)
|
|
24
|
-
# - 신규: 다음 G-NNN 할당, Status: unverified 로 기록
|
|
25
|
-
# - 등록 성공 로그: .harness/progress.log 에 한 줄 append
|
|
26
|
-
#
|
|
27
|
-
# 등록 형식:
|
|
28
|
-
# ### [G-NNN] <title> <!-- rule_id: <rule-id> -->
|
|
29
|
-
# - **Status**: unverified
|
|
30
|
-
# - **Date**: YYYY-MM-DD
|
|
31
|
-
# - **Source**: <source> (예: "evaluator-functional:F-003")
|
|
32
|
-
# - **Trigger**: Eval 자동 감지
|
|
33
|
-
# - **Wrong**: <wrong>
|
|
34
|
-
# - **Right**: <right>
|
|
35
|
-
# - **Why**: <why>
|
|
36
|
-
# - **Scope**: <scope>
|
|
37
|
-
# - **Occurrences**: 1
|
|
38
|
-
# - **Last-Seen**: YYYY-MM-DD
|
|
39
|
-
|
|
40
|
-
set -euo pipefail
|
|
41
|
-
|
|
42
|
-
if [ $# -lt 1 ]; then
|
|
43
|
-
echo "usage: harness-gotcha-register.sh <project-root> [options]" >&2
|
|
44
|
-
exit 1
|
|
45
|
-
fi
|
|
46
|
-
|
|
47
|
-
PROJECT_ROOT="$1"
|
|
48
|
-
shift
|
|
49
|
-
PROJECT_ROOT="$(cd "$PROJECT_ROOT" && pwd)"
|
|
50
|
-
|
|
51
|
-
command -v jq >/dev/null 2>&1 || { echo "[gotcha-register] ERROR: jq required" >&2; exit 1; }
|
|
52
|
-
|
|
53
|
-
GOTCHAS_DIR="$PROJECT_ROOT/.harness/gotchas"
|
|
54
|
-
ACTIONS_DIR="$PROJECT_ROOT/.harness/actions"
|
|
55
|
-
mkdir -p "$GOTCHAS_DIR"
|
|
56
|
-
|
|
57
|
-
TODAY="$(date +%Y-%m-%d)"
|
|
58
|
-
|
|
59
|
-
# ─────────────────────────────────────────
|
|
60
|
-
# 단일 항목을 .harness/gotchas/<target>.md 에 append
|
|
61
|
-
# $1: target agent (generator-backend, generator-frontend, evaluator-functional, ...)
|
|
62
|
-
# $2: rule_id (dedup key)
|
|
63
|
-
# $3: title
|
|
64
|
-
# $4: wrong
|
|
65
|
-
# $5: right
|
|
66
|
-
# $6: why
|
|
67
|
-
# $7: scope
|
|
68
|
-
# $8: source
|
|
69
|
-
# ─────────────────────────────────────────
|
|
70
|
-
register_one() {
|
|
71
|
-
local target="$1" rule_id="$2" title="$3" wrong="$4" right="$5" why="$6" scope="$7" source="$8"
|
|
72
|
-
local file="$GOTCHAS_DIR/${target}.md"
|
|
73
|
-
|
|
74
|
-
# Ensure file exists with header
|
|
75
|
-
if [ ! -f "$file" ]; then
|
|
76
|
-
cat > "$file" <<EOF
|
|
77
|
-
# Gotchas — $target
|
|
78
|
-
|
|
79
|
-
> Dispatcher + Evaluator 가 관리. $target 은 세션 시작 시 이 파일을 읽고 같은 실수를 반복하지 않습니다.
|
|
80
|
-
> 신규 항목은 \`Status: unverified\` 로 기록되고, Planner 리뷰 후 \`verified\` 로 승격됩니다.
|
|
81
|
-
|
|
82
|
-
EOF
|
|
83
|
-
fi
|
|
84
|
-
|
|
85
|
-
# Dedup by rule_id marker comment
|
|
86
|
-
if grep -qE "<!-- rule_id: ${rule_id} -->" "$file" 2>/dev/null; then
|
|
87
|
-
# Bump Occurrences + Last-Seen for matching block
|
|
88
|
-
awk -v rid="$rule_id" -v today="$TODAY" '
|
|
89
|
-
BEGIN { in_block = 0 }
|
|
90
|
-
/^### \[G-[0-9]+\].*<!-- rule_id: / {
|
|
91
|
-
in_block = (index($0, "rule_id: " rid " ") > 0 || index($0, "rule_id: " rid "\n") > 0 || $0 ~ ("rule_id: " rid " -->"))
|
|
92
|
-
}
|
|
93
|
-
in_block && /^- \*\*Occurrences\*\*:/ {
|
|
94
|
-
n = $NF + 0
|
|
95
|
-
print "- **Occurrences**: " (n + 1)
|
|
96
|
-
next
|
|
97
|
-
}
|
|
98
|
-
in_block && /^- \*\*Last-Seen\*\*:/ {
|
|
99
|
-
print "- **Last-Seen**: " today
|
|
100
|
-
next
|
|
101
|
-
}
|
|
102
|
-
/^### / && !/<!-- rule_id: / { in_block = 0 }
|
|
103
|
-
{ print }
|
|
104
|
-
' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
|
|
105
|
-
echo "[gotcha-register] $target: dedup $rule_id (occurrence bumped)"
|
|
106
|
-
return 0
|
|
107
|
-
fi
|
|
108
|
-
|
|
109
|
-
# Allocate next G-NNN (|| true — pipefail-safe when no existing entries)
|
|
110
|
-
local next_num=""
|
|
111
|
-
next_num=$(grep -oE '^### \[G-[0-9]+\]' "$file" 2>/dev/null | grep -oE '[0-9]+' | sort -n | tail -1 || true)
|
|
112
|
-
next_num=$((${next_num:-0} + 1))
|
|
113
|
-
local g_id
|
|
114
|
-
g_id=$(printf 'G-%03d' "$next_num")
|
|
115
|
-
|
|
116
|
-
# Append new block
|
|
117
|
-
{
|
|
118
|
-
echo ""
|
|
119
|
-
echo "### [$g_id] $title <!-- rule_id: $rule_id -->"
|
|
120
|
-
echo "- **Status**: unverified"
|
|
121
|
-
echo "- **Date**: $TODAY"
|
|
122
|
-
echo "- **Source**: $source"
|
|
123
|
-
echo "- **Trigger**: Eval 자동 감지"
|
|
124
|
-
echo "- **Wrong**: $wrong"
|
|
125
|
-
echo "- **Right**: $right"
|
|
126
|
-
echo "- **Why**: $why"
|
|
127
|
-
echo "- **Scope**: $scope"
|
|
128
|
-
echo "- **Occurrences**: 1"
|
|
129
|
-
echo "- **Last-Seen**: $TODAY"
|
|
130
|
-
} >> "$file"
|
|
131
|
-
|
|
132
|
-
echo "[gotcha-register] $target: registered $g_id ($rule_id) — unverified"
|
|
133
|
-
|
|
134
|
-
# Log to progress.log if present
|
|
135
|
-
local progress_log="$PROJECT_ROOT/.harness/progress.log"
|
|
136
|
-
if [ -f "$progress_log" ]; then
|
|
137
|
-
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) [gotcha] $target $g_id unverified — $title (source: $source)" >> "$progress_log"
|
|
138
|
-
fi
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
# ─────────────────────────────────────────
|
|
142
|
-
# JSON 배열에서 일괄 등록
|
|
143
|
-
# schema: [{ target, rule_id, title, wrong, right, why, scope, source }]
|
|
144
|
-
# ─────────────────────────────────────────
|
|
145
|
-
register_from_json() {
|
|
146
|
-
local json="$1"
|
|
147
|
-
local count
|
|
148
|
-
count=$(echo "$json" | jq 'length' 2>/dev/null || echo 0)
|
|
149
|
-
if [ "$count" -eq 0 ]; then
|
|
150
|
-
return 0
|
|
151
|
-
fi
|
|
152
|
-
|
|
153
|
-
local i
|
|
154
|
-
for ((i=0; i<count; i++)); do
|
|
155
|
-
local t r ti w ri wh sc so
|
|
156
|
-
t=$(echo "$json" | jq -r ".[$i].target // empty")
|
|
157
|
-
r=$(echo "$json" | jq -r ".[$i].rule_id // empty")
|
|
158
|
-
ti=$(echo "$json" | jq -r ".[$i].title // empty")
|
|
159
|
-
w=$(echo "$json" | jq -r ".[$i].wrong // empty")
|
|
160
|
-
ri=$(echo "$json" | jq -r ".[$i].right // empty")
|
|
161
|
-
wh=$(echo "$json" | jq -r ".[$i].why // empty")
|
|
162
|
-
sc=$(echo "$json" | jq -r ".[$i].scope // \"항상\"")
|
|
163
|
-
so=$(echo "$json" | jq -r ".[$i].source // \"evaluator:auto\"")
|
|
164
|
-
|
|
165
|
-
if [ -z "$t" ] || [ -z "$r" ] || [ -z "$ti" ]; then
|
|
166
|
-
echo "[gotcha-register] skip: missing target/rule_id/title at index $i" >&2
|
|
167
|
-
continue
|
|
168
|
-
fi
|
|
169
|
-
register_one "$t" "$r" "$ti" "$w" "$ri" "$wh" "$sc" "$so"
|
|
170
|
-
done
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
# ─────────────────────────────────────────
|
|
174
|
-
# Convention 등록 — .harness/conventions/<scope>.md 에 [C-NNN] entry append
|
|
175
|
-
# $1: scope (shared, generator-backend, generator-frontend, ... — 파일명 base)
|
|
176
|
-
# $2: rule_id (dedup key)
|
|
177
|
-
# $3: title
|
|
178
|
-
# $4: rule (긍정 가이드 본문 — "X 는 항상 Y 로")
|
|
179
|
-
# $5: why
|
|
180
|
-
# $6: source
|
|
181
|
-
# ─────────────────────────────────────────
|
|
182
|
-
CONVENTIONS_DIR="$PROJECT_ROOT/.harness/conventions"
|
|
183
|
-
register_convention_one() {
|
|
184
|
-
local scope="$1" rule_id="$2" title="$3" rule="$4" why="$5" source="$6"
|
|
185
|
-
mkdir -p "$CONVENTIONS_DIR"
|
|
186
|
-
local file="$CONVENTIONS_DIR/${scope}.md"
|
|
187
|
-
|
|
188
|
-
if [ ! -f "$file" ]; then
|
|
189
|
-
cat > "$file" <<EOF
|
|
190
|
-
# Conventions — ${scope}
|
|
191
|
-
|
|
192
|
-
> Dispatcher가 관리. 긍정 가이드("~를 사용해", "항상 ~") 자동 등록.
|
|
193
|
-
|
|
194
|
-
EOF
|
|
195
|
-
fi
|
|
196
|
-
|
|
197
|
-
# dedup: 같은 rule_id 가 있으면 해당 [C-NNN] 블록의 Occurrences +1, Last-Seen 갱신
|
|
198
|
-
if grep -qE "<!-- rule_id: ${rule_id} -->" "$file" 2>/dev/null; then
|
|
199
|
-
awk -v rid="$rule_id" -v today="$TODAY" '
|
|
200
|
-
BEGIN { in_block = 0 }
|
|
201
|
-
/^### \[C-[0-9]+\].*<!-- rule_id: / {
|
|
202
|
-
in_block = ($0 ~ ("rule_id: " rid " -->"))
|
|
203
|
-
}
|
|
204
|
-
in_block && /^- \*\*Occurrences\*\*:/ {
|
|
205
|
-
n = $NF + 0
|
|
206
|
-
print "- **Occurrences**: " (n + 1)
|
|
207
|
-
next
|
|
208
|
-
}
|
|
209
|
-
in_block && /^- \*\*Last-Seen\*\*:/ {
|
|
210
|
-
print "- **Last-Seen**: " today
|
|
211
|
-
next
|
|
212
|
-
}
|
|
213
|
-
/^### / && !/<!-- rule_id: / { in_block = 0 }
|
|
214
|
-
{ print }
|
|
215
|
-
' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
|
|
216
|
-
echo "[gotcha-register] convention/${scope}: dedup ${rule_id} (occurrence bumped)"
|
|
217
|
-
return 0
|
|
218
|
-
fi
|
|
219
|
-
|
|
220
|
-
# 신규 — 다음 [C-NNN] 번호 할당 (set -e 회피: || true)
|
|
221
|
-
local last_n
|
|
222
|
-
last_n=$(grep -oE '\[C-[0-9]+\]' "$file" 2>/dev/null | grep -oE '[0-9]+' | sort -n | tail -1 || true)
|
|
223
|
-
last_n=${last_n:-0}
|
|
224
|
-
local next_n=$(printf "%03d" $((last_n + 1)))
|
|
225
|
-
|
|
226
|
-
cat >> "$file" <<EOF
|
|
227
|
-
|
|
228
|
-
### [C-${next_n}] ${title} <!-- rule_id: ${rule_id} -->
|
|
229
|
-
- **Status**: unverified
|
|
230
|
-
- **Date**: ${TODAY}
|
|
231
|
-
- **Source**: ${source}
|
|
232
|
-
- **Rule**: ${rule}
|
|
233
|
-
- **Why**: ${why}
|
|
234
|
-
- **Occurrences**: 1
|
|
235
|
-
- **Last-Seen**: ${TODAY}
|
|
236
|
-
EOF
|
|
237
|
-
|
|
238
|
-
echo "[gotcha-register] convention/${scope}: registered C-${next_n} (${rule_id}) — unverified"
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
register_conventions_from_json() {
|
|
242
|
-
local json="$1"
|
|
243
|
-
local count
|
|
244
|
-
count=$(echo "$json" | jq 'length' 2>/dev/null || echo 0)
|
|
245
|
-
[ "$count" -eq 0 ] && return 0
|
|
246
|
-
local i
|
|
247
|
-
for ((i=0; i<count; i++)); do
|
|
248
|
-
local sc r ti ru wh so
|
|
249
|
-
sc=$(echo "$json" | jq -r ".[$i].scope // \"shared\"")
|
|
250
|
-
r=$(echo "$json" | jq -r ".[$i].rule_id // empty")
|
|
251
|
-
ti=$(echo "$json" | jq -r ".[$i].title // empty")
|
|
252
|
-
ru=$(echo "$json" | jq -r ".[$i].rule // empty")
|
|
253
|
-
wh=$(echo "$json" | jq -r ".[$i].why // empty")
|
|
254
|
-
so=$(echo "$json" | jq -r ".[$i].source // \"agent:auto\"")
|
|
255
|
-
if [ -z "$r" ] || [ -z "$ti" ] || [ -z "$ru" ]; then
|
|
256
|
-
echo "[gotcha-register] convention skip: missing rule_id/title/rule at index $i" >&2
|
|
257
|
-
continue
|
|
258
|
-
fi
|
|
259
|
-
register_convention_one "$sc" "$r" "$ti" "$ru" "$wh" "$so"
|
|
260
|
-
done
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
# ─────────────────────────────────────────
|
|
264
|
-
# 단일 파일에서 fenced block 추출 (block_tag 인자로 종류 지정)
|
|
265
|
-
# $1: file path · $2: block tag (gotcha_candidates 또는 convention_candidates)
|
|
266
|
-
# stdout 으로 각 block JSON 을 한 줄씩 출력 (\0 구분자)
|
|
267
|
-
# ─────────────────────────────────────────
|
|
268
|
-
extract_blocks() {
|
|
269
|
-
local file="$1" tag="$2"
|
|
270
|
-
local blocks_prefix
|
|
271
|
-
blocks_prefix=$(mktemp -d)
|
|
272
|
-
awk -v dir="$blocks_prefix" -v tag="$tag" '
|
|
273
|
-
BEGIN { idx=0; flag=0; buf="" }
|
|
274
|
-
$0 ~ ("^```" tag "[[:space:]]*$") { flag=1; buf=""; next }
|
|
275
|
-
/^```[[:space:]]*$/ && flag {
|
|
276
|
-
flag=0
|
|
277
|
-
idx++
|
|
278
|
-
outfile = sprintf("%s/block-%03d.json", dir, idx)
|
|
279
|
-
print buf > outfile
|
|
280
|
-
close(outfile)
|
|
281
|
-
buf=""
|
|
282
|
-
next
|
|
283
|
-
}
|
|
284
|
-
flag { buf = buf $0 "\n" }
|
|
285
|
-
' "$file"
|
|
286
|
-
echo "$blocks_prefix"
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
process_blocks_in_file() {
|
|
290
|
-
local file="$1"
|
|
291
|
-
# gotcha_candidates
|
|
292
|
-
local g_dir
|
|
293
|
-
g_dir=$(extract_blocks "$file" "gotcha_candidates")
|
|
294
|
-
local b
|
|
295
|
-
for b in "$g_dir"/block-*.json; do
|
|
296
|
-
[ -f "$b" ] || continue
|
|
297
|
-
if jq empty "$b" 2>/dev/null; then
|
|
298
|
-
register_from_json "$(cat "$b")"
|
|
299
|
-
else
|
|
300
|
-
echo "[gotcha-register] skip: invalid gotcha_candidates JSON in $(basename "$file")" >&2
|
|
301
|
-
fi
|
|
302
|
-
done
|
|
303
|
-
rm -rf "$g_dir"
|
|
304
|
-
|
|
305
|
-
# convention_candidates
|
|
306
|
-
local c_dir
|
|
307
|
-
c_dir=$(extract_blocks "$file" "convention_candidates")
|
|
308
|
-
for b in "$c_dir"/block-*.json; do
|
|
309
|
-
[ -f "$b" ] || continue
|
|
310
|
-
if jq empty "$b" 2>/dev/null; then
|
|
311
|
-
register_conventions_from_json "$(cat "$b")"
|
|
312
|
-
else
|
|
313
|
-
echo "[gotcha-register] skip: invalid convention_candidates JSON in $(basename "$file")" >&2
|
|
314
|
-
fi
|
|
315
|
-
done
|
|
316
|
-
rm -rf "$c_dir"
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
# ─────────────────────────────────────────
|
|
320
|
-
# evaluation-*.md 스캔 — ```gotcha_candidates``` + ```convention_candidates``` 둘 다
|
|
321
|
-
# ─────────────────────────────────────────
|
|
322
|
-
scan_evaluations() {
|
|
323
|
-
[ -d "$ACTIONS_DIR" ] || return 0
|
|
324
|
-
local f
|
|
325
|
-
for f in "$ACTIONS_DIR"/evaluation-*.md; do
|
|
326
|
-
[ -f "$f" ] || continue
|
|
327
|
-
process_blocks_in_file "$f"
|
|
328
|
-
done
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
# ─────────────────────────────────────────
|
|
332
|
-
# 모든 worker report 스캔 — evaluation-*.md + gen-report-*.md + lead-report-*.md
|
|
333
|
-
# Generator 는 gen-report-{F-ID}.md 작성, Lead 는 lead-report-{date}.md 작성 가능
|
|
334
|
-
# ─────────────────────────────────────────
|
|
335
|
-
scan_all() {
|
|
336
|
-
[ -d "$ACTIONS_DIR" ] || return 0
|
|
337
|
-
local f
|
|
338
|
-
for f in "$ACTIONS_DIR"/evaluation-*.md "$ACTIONS_DIR"/gen-report-*.md "$ACTIONS_DIR"/lead-report-*.md; do
|
|
339
|
-
[ -f "$f" ] || continue
|
|
340
|
-
process_blocks_in_file "$f"
|
|
341
|
-
done
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
# ─────────────────────────────────────────
|
|
345
|
-
# Parse CLI
|
|
346
|
-
# ─────────────────────────────────────────
|
|
347
|
-
TARGET=""
|
|
348
|
-
RULE_ID=""
|
|
349
|
-
TITLE=""
|
|
350
|
-
WRONG=""
|
|
351
|
-
RIGHT=""
|
|
352
|
-
WHY=""
|
|
353
|
-
SCOPE="항상"
|
|
354
|
-
SOURCE="evaluator:auto"
|
|
355
|
-
MODE="single"
|
|
356
|
-
FROM_JSON=""
|
|
357
|
-
|
|
358
|
-
while [ $# -gt 0 ]; do
|
|
359
|
-
case "$1" in
|
|
360
|
-
--target) TARGET="$2"; shift 2 ;;
|
|
361
|
-
--rule-id) RULE_ID="$2"; shift 2 ;;
|
|
362
|
-
--title) TITLE="$2"; shift 2 ;;
|
|
363
|
-
--wrong) WRONG="$2"; shift 2 ;;
|
|
364
|
-
--right) RIGHT="$2"; shift 2 ;;
|
|
365
|
-
--why) WHY="$2"; shift 2 ;;
|
|
366
|
-
--scope) SCOPE="$2"; shift 2 ;;
|
|
367
|
-
--source) SOURCE="$2"; shift 2 ;;
|
|
368
|
-
--from-json) MODE="json"; FROM_JSON="$2"; shift 2 ;;
|
|
369
|
-
--scan-evaluations) MODE="scan"; shift ;;
|
|
370
|
-
--scan-all) MODE="scan-all"; shift ;;
|
|
371
|
-
*) echo "[gotcha-register] unknown arg: $1" >&2; exit 1 ;;
|
|
372
|
-
esac
|
|
373
|
-
done
|
|
374
|
-
|
|
375
|
-
case "$MODE" in
|
|
376
|
-
single)
|
|
377
|
-
if [ -z "$TARGET" ] || [ -z "$RULE_ID" ] || [ -z "$TITLE" ]; then
|
|
378
|
-
echo "[gotcha-register] usage: --target X --rule-id Y --title Z [...]" >&2
|
|
379
|
-
exit 1
|
|
380
|
-
fi
|
|
381
|
-
register_one "$TARGET" "$RULE_ID" "$TITLE" "$WRONG" "$RIGHT" "$WHY" "$SCOPE" "$SOURCE"
|
|
382
|
-
;;
|
|
383
|
-
json)
|
|
384
|
-
if [ ! -f "$FROM_JSON" ]; then echo "[gotcha-register] file not found: $FROM_JSON" >&2; exit 1; fi
|
|
385
|
-
register_from_json "$(cat "$FROM_JSON")"
|
|
386
|
-
;;
|
|
387
|
-
scan)
|
|
388
|
-
scan_evaluations
|
|
389
|
-
;;
|
|
390
|
-
scan-all)
|
|
391
|
-
scan_all
|
|
392
|
-
;;
|
|
393
|
-
esac
|