oh-my-customcode 1.1.67 → 1.1.68
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/dist/cli/index.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -298,6 +298,10 @@ split("\n")
|
|
|
298
298
|
# 미announce Read — 은 새로 발화한다(의도된 동작, v1.1.62 적대적 리뷰 재현 C1/C2).
|
|
299
299
|
| ($an_tool + (if $an_spawn > $an_tool_agent then $an_spawn - $an_tool_agent else 0 end)) as $announce
|
|
300
300
|
| ([ $blocks[] | select((.type? == "tool_use") and ((.name? // "") != "Skill")) ] | length) as $ntools
|
|
301
|
+
# 미접두 도구 이름 (#1687): $ntools와 동일한 필터(non-Skill tool_use)로 순서를 보존한 이름
|
|
302
|
+
# 목록을 뽑는다. $r008(누락 건수)이 어떤 도구인지 shell에서 드러내기 위한 부가 필드 —
|
|
303
|
+
# 판정식($r008 산출) 자체는 건드리지 않는다.
|
|
304
|
+
| ([ $blocks[] | select((.type? == "tool_use") and ((.name? // "") != "Skill")) | (.name? // "") ]) as $tool_names_list
|
|
301
305
|
# 전체 tool_use(Skill 포함)가 0건인 턴은 forward 판정을 무조건 0으로 고정한다(#1625
|
|
302
306
|
# 찐빠 #3, 이슈 제안 그대로). $ntools(Skill 제외) 기반 산식은 정상 입력에서는 이미
|
|
303
307
|
# 0을 내지만, 명시 가드로 불변식을 코드에 못박아 향후 산식 변경이 이 보장을 조용히
|
|
@@ -322,7 +326,7 @@ split("\n")
|
|
|
322
326
|
| ([ $lines[] | select(test("^\\[[^\\]]+\\]\\[[^\\]]+\\] ?(→|->|—>) ?Tool:")) ] | length) as $an_anchored
|
|
323
327
|
# $nall_tools는 위 forward r008 가드에서 이미 바인딩됨 — 재바인딩하지 않고 재사용한다.
|
|
324
328
|
| (if $nall_tools == 0 and $an_anchored > 0 then $an_anchored else 0 end) as $r008rev
|
|
325
|
-
| [$tuuid, ($r007 | tostring), ($r008 | tostring), ($r008rev | tostring)] | @tsv
|
|
329
|
+
| [$tuuid, ($r007 | tostring), ($r008 | tostring), ($r008rev | tostring), ($tool_names_list | join(","))] | @tsv
|
|
326
330
|
)
|
|
327
331
|
end
|
|
328
332
|
end
|
|
@@ -346,6 +350,8 @@ turn_uuid=$(printf '%s' "$result" | cut -f1)
|
|
|
346
350
|
r007_violations=$(printf '%s' "$result" | cut -f2)
|
|
347
351
|
r008_violations=$(printf '%s' "$result" | cut -f3)
|
|
348
352
|
r008_reverse=$(printf '%s' "$result" | cut -f4)
|
|
353
|
+
# 미접두 도구 이름 목록 (#1687) — $ntools와 동일 필터의 순서 보존 목록, "," join.
|
|
354
|
+
tool_names=$(printf '%s' "$result" | cut -f5)
|
|
349
355
|
|
|
350
356
|
: "${r007_violations:=0}"
|
|
351
357
|
: "${r008_violations:=0}"
|
|
@@ -397,6 +403,26 @@ if [ "$r008_violations" -gt 0 ]; then
|
|
|
397
403
|
violation_desc="R008 도구 식별 접두사 누락 ${r008_violations}건"
|
|
398
404
|
instruction="모든 도구 호출에 [agent][model] → Tool: 접두사를 포함하십시오."
|
|
399
405
|
fi
|
|
406
|
+
# 미접두 도구 이름 귀속 (#1687): announce는 턴 단위로 매칭되므로, $tool_names(순서 보존,
|
|
407
|
+
# non-Skill tool_use)의 마지막 r008_violations개를 부족분으로 귀속한다. 카운트 문구
|
|
408
|
+
# "R008 도구 식별 접두사 누락 N건"은 위에서 이미 확정되어 바이트 동일 유지 — 이 접미사는
|
|
409
|
+
# 항상 그 뒤에 이어붙인다(scripts/count-r007-r008.sh의 grep -oE 앵커와 무관).
|
|
410
|
+
if [ -n "$tool_names" ]; then
|
|
411
|
+
r008_missing_tools=$(printf '%s' "$tool_names" | awk -F',' -v n="$r008_violations" '{
|
|
412
|
+
total = NF
|
|
413
|
+
start = total - n + 1
|
|
414
|
+
if (start < 1) start = 1
|
|
415
|
+
out = ""
|
|
416
|
+
for (i = start; i <= total; i++) {
|
|
417
|
+
if (out != "") out = out ", "
|
|
418
|
+
out = out $i
|
|
419
|
+
}
|
|
420
|
+
print out
|
|
421
|
+
}')
|
|
422
|
+
if [ -n "$r008_missing_tools" ]; then
|
|
423
|
+
violation_desc="${violation_desc} (미접두 도구: ${r008_missing_tools})"
|
|
424
|
+
fi
|
|
425
|
+
fi
|
|
400
426
|
fi
|
|
401
427
|
|
|
402
428
|
if [ -n "$violation_desc" ]; then
|
|
@@ -597,13 +597,34 @@ raw_command=$(printf '%s' "$input" | jq -r '.tool_input.command // ""')
|
|
|
597
597
|
# Distinguish "the same file edited 3 times with DIFFERENT content" (a normal
|
|
598
598
|
# incremental-edit workflow — the #1641 false positive) from "the same edit
|
|
599
599
|
# repeated 3 times" (a genuine stuck loop). Only the latter should hard-block.
|
|
600
|
-
#
|
|
601
|
-
#
|
|
600
|
+
# #1649: the original alphanumerics-only + 120-char-cut key had two defects —
|
|
601
|
+
# (M-1) edits differing only in punctuation/whitespace (e.g. re-aligning a
|
|
602
|
+
# markdown table) collapsed to the SAME key and were falsely blocked as
|
|
603
|
+
# "identical", and (M-2) Write calls sharing a long identical prefix (e.g.
|
|
604
|
+
# frontmatter) collided after the 120-char cut even when the body differed.
|
|
605
|
+
# New spec: collapse whitespace runs to one space (still deterministic,
|
|
606
|
+
# platform-independent, no md5sum) but PRESERVE punctuation, then key on
|
|
607
|
+
# "<len>#<full>" when the normalized string is <=120 chars (short strings fit
|
|
608
|
+
# whole, so no sum is needed), else "<len>#<codepoint sum>#<first 80 chars>
|
|
609
|
+
# #<last 40 chars>" — length + codepoint sum + head/tail. Adversarial review
|
|
610
|
+
# found the length+head+tail-only key (no sum) still collides when a
|
|
611
|
+
# same-length middle-only substitution falls entirely outside both the head
|
|
612
|
+
# and tail windows (e.g. this repo's own count/version-bump Writes: 80 "A"s +
|
|
613
|
+
# "version-115-count" + 40 "Z"s vs "...-116-..." vs "...-117-..." — all 137
|
|
614
|
+
# chars, identical head/tail). The codepoint sum changes whenever the changed
|
|
615
|
+
# substring's characters change, so a substitution is now caught by the sum;
|
|
616
|
+
# a same-sum transposition of the middle segment can still collide — an
|
|
617
|
+
# accepted residual risk, not fully eliminated.
|
|
602
618
|
edit_hash=""
|
|
603
619
|
if [ "$tool_name" = "Edit" ] || [ "$tool_name" = "Write" ]; then
|
|
604
620
|
edit_hash=$(printf '%s' "$input" \
|
|
605
621
|
| jq -r '(.tool_input.old_string // .tool_input.content // .tool_input.new_string // "")
|
|
606
|
-
| gsub("[
|
|
622
|
+
| gsub("[[:space:]]+"; " ") | ltrimstr(" ") | rtrimstr(" ")
|
|
623
|
+
| (length as $l
|
|
624
|
+
| if $l <= 120 then "\($l)#\(.)"
|
|
625
|
+
else ((explode | add // 0) as $sum
|
|
626
|
+
| "\($l)#\($sum)#\(.[0:80])#\(.[-40:])")
|
|
627
|
+
end)')
|
|
607
628
|
fi
|
|
608
629
|
|
|
609
630
|
# History entries are written by jq, so their "path" values are JSON-ENCODED.
|
|
@@ -615,6 +636,15 @@ fi
|
|
|
615
636
|
target_key_json=$(jq -n --arg v "$target_key" '$v')
|
|
616
637
|
path_match="\"path\":${target_key_json}"
|
|
617
638
|
|
|
639
|
+
# #1649 follow-up: edit_hash now preserves punctuation (see the edit_hash
|
|
640
|
+
# comment above), so it can contain quotes/backslashes just like a Bash
|
|
641
|
+
# command can. It is written to history the same JSON-encoded way "path" is
|
|
642
|
+
# (--arg ehash "$edit_hash" -> jq serializes it), so Check 1 / Check 3 below
|
|
643
|
+
# must match it with the SAME JSON-encoded literal, not the raw string — same
|
|
644
|
+
# fix as path_match above, applied to edit_hash.
|
|
645
|
+
edit_hash_json=$(jq -n --arg v "$edit_hash" '$v')
|
|
646
|
+
edit_hash_match="\"edit_hash\":${edit_hash_json}"
|
|
647
|
+
|
|
618
648
|
is_readonly="false"
|
|
619
649
|
if [ "$tool_name" = "Bash" ]; then
|
|
620
650
|
is_readonly=$(is_readonly_bash_command "$raw_command")
|
|
@@ -761,7 +791,7 @@ if [ -f "$HISTORY_FILE" ]; then
|
|
|
761
791
|
if [ "$is_readonly" != "true" ] && [ -n "$file_path" ]; then
|
|
762
792
|
consecutive_file=$(printf '%s\n' "$last_n" \
|
|
763
793
|
| grep -F -e "$path_match" \
|
|
764
|
-
| grep -cF -e "
|
|
794
|
+
| grep -cF -e "$edit_hash_match" 2>/dev/null || true)
|
|
765
795
|
[ -n "$consecutive_file" ] || consecutive_file=0
|
|
766
796
|
if [ "$consecutive_file" -ge "$HARD_BLOCK_THRESHOLD" ]; then
|
|
767
797
|
hard_block=true
|
|
@@ -791,7 +821,7 @@ if [ -f "$HISTORY_FILE" ]; then
|
|
|
791
821
|
consecutive_tool_target=$(printf '%s\n' "$last_n" \
|
|
792
822
|
| grep -F -e "\"tool\":\"${tool_name}\"" \
|
|
793
823
|
| grep -F -e "$path_match" \
|
|
794
|
-
| grep -cF -e "
|
|
824
|
+
| grep -cF -e "$edit_hash_match" 2>/dev/null || true)
|
|
795
825
|
[ -n "$consecutive_tool_target" ] || consecutive_tool_target=0
|
|
796
826
|
if [ "$consecutive_tool_target" -ge "$HARD_BLOCK_THRESHOLD" ]; then
|
|
797
827
|
hard_block=true
|
package/templates/manifest.json
CHANGED