@routinecrew/routinecode 2.31.35 → 2.31.39
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/bin/prompt-vault.js +1 -1
- package/bin/setup.js +1 -1
- package/hooks/lib/block_message.py +15 -50
- package/hooks/lib/rdpe_maturity.py +128 -0
- package/hooks/lib/rdpe_report.py +47 -0
- package/hooks/lib/rdpe_sanitize.py +90 -0
- package/hooks/lib/sync_manager.py +5 -1
- package/hooks/post-agent-return.sh +118 -4
- package/hooks/pre-agent-spawn.mjs +1 -1
- package/hooks/pre-credit-guard.sh +3 -1
- package/hooks/pre-mark-complete.sh +19 -0
- package/hooks/session-start.sh +3 -0
- package/hooks/stop-usage-metrics.sh +211 -74
- package/hooks/tests/gate-integration.test.sh +106 -0
- package/hooks/user-prompt-submit.sh +0 -12
- package/mcp-db-manager/dist/analyzers/duplicate-detector.js +1 -1
- package/mcp-db-manager/dist/core/model-parser.js +1 -1
- package/mcp-db-manager/dist/core/schema-reader.js +1 -1
- package/mcp-db-manager/dist/executors/migration-executor.js +1 -1
- package/mcp-db-manager/dist/generators/migration-generator.js +1 -1
- package/mcp-db-manager/dist/index.js +1 -1
- package/mcp-db-manager/dist/validators/schema-validator.js +1 -1
- package/mcp-dev-tester/dist/analyzers/auth-diagnoser.js +1 -1
- package/mcp-dev-tester/dist/analyzers/backend-analyzer.js +1 -1
- package/mcp-dev-tester/dist/analyzers/endpoint-diagnoser.js +1 -1
- package/mcp-dev-tester/dist/analyzers/frontend-analyzer.js +1 -1
- package/mcp-dev-tester/dist/analyzers/runtime-diagnoser.js +1 -1
- package/mcp-dev-tester/dist/analyzers/type-comparator.js +1 -1
- package/mcp-dev-tester/dist/analyzers/validation-diagnoser.js +1 -1
- package/mcp-dev-tester/dist/browser/playwright-manager.js +1 -1
- package/mcp-dev-tester/dist/browser/ui-tester.js +1 -1
- package/mcp-dev-tester/dist/config/project-config.js +1 -1
- package/mcp-dev-tester/dist/index.js +1 -1
- package/mcp-dev-tester/dist/testers/api-tester.js +1 -1
- package/mcp-doc-fetcher/dist/index.js +1 -1
- package/mcp-html-renderer/dist/index.js +1 -1
- package/mcp-html-renderer/dist/preview.js +1 -1
- package/mcp-html-renderer/dist/template-engine.js +1 -1
- package/mcp-intelligence/dist/concept-catalog.js +1 -1
- package/mcp-intelligence/dist/concept-server-proxy.js +1 -1
- package/mcp-intelligence/dist/config-auth.js +1 -1
- package/mcp-intelligence/dist/contracts.generated.js +1 -1
- package/mcp-intelligence/dist/domain-templates.js +1 -1
- package/mcp-intelligence/dist/grounding.js +1 -1
- package/mcp-intelligence/dist/handlers.js +1 -1
- package/mcp-intelligence/dist/index.js +1 -1
- package/mcp-intelligence/dist/intelligence-file.js +1 -1
- package/mcp-intelligence/dist/knowledge-critic.js +1 -1
- package/mcp-intelligence/dist/knowledge-handlers.js +1 -1
- package/mcp-intelligence/dist/mention-extractor.js +1 -1
- package/mcp-intelligence/dist/provenance.js +1 -1
- package/mcp-intelligence/dist/semantic-embedder.js +1 -1
- package/mcp-log-watcher/dist/config-auth.js +1 -1
- package/mcp-log-watcher/dist/file-watcher.js +1 -1
- package/mcp-log-watcher/dist/index.js +1 -1
- package/mcp-log-watcher/dist/known-solutions.js +1 -1
- package/mcp-log-watcher/dist/log-store.js +1 -1
- package/mcp-log-watcher/dist/websocket-server.js +1 -1
- package/mcp-plan-manager/dist/__tests__/plan-parser.test.js +1 -1
- package/mcp-plan-manager/dist/file-ops.js +1 -1
- package/mcp-plan-manager/dist/index.js +1 -1
- package/mcp-plan-manager/dist/plan-parser.js +1 -1
- package/mcp-project-context/dist/git-ops.js +1 -1
- package/mcp-project-context/dist/index.js +1 -1
- package/mcp-project-context/dist/project-analysis.js +1 -1
- package/mcp-routinecode/dist/agent-tracker.js +1 -1
- package/mcp-routinecode/dist/blast-radius.js +1 -1
- package/mcp-routinecode/dist/config-auth.js +1 -1
- package/mcp-routinecode/dist/contracts.generated.js +1 -1
- package/mcp-routinecode/dist/explorer-advisor.js +1 -1
- package/mcp-routinecode/dist/failure-tracker.js +1 -1
- package/mcp-routinecode/dist/file-lock-registry.js +1 -1
- package/mcp-routinecode/dist/file-risk-scorer.js +1 -1
- package/mcp-routinecode/dist/index.js +1 -1
- package/mcp-routinecode/dist/known-solutions.js +1 -1
- package/mcp-routinecode/dist/ledger-miner.js +1 -1
- package/mcp-routinecode/dist/observed-draft.js +1 -1
- package/mcp-routinecode/dist/pattern-matcher.js +1 -1
- package/mcp-routinecode/dist/routines.js +1 -1
- package/mcp-routinecode/dist/rule-engine.js +1 -1
- package/mcp-routinecode/dist/rule-promoter.js +1 -1
- package/mcp-routinecode/dist/telemetry-analyzer.js +1 -1
- package/mcp-routinecode/dist/verification.js +0 -0
- package/mcp-routinecode/dist/viral-loop.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""RDPE 로컬 maturity — daily.json.task_sigs → routines.json 성숙 판정.
|
|
3
|
+
|
|
4
|
+
설계 §5 임계를 **로컬에 재구현**한다(서버 maturity.engine 은 Postgres·error_fix 하드코딩이라
|
|
5
|
+
재사용 불가). 로컬 완결: 서버 왕복 없음. fail-open(에러 시 조용히 종료 — 세션 영향 0).
|
|
6
|
+
|
|
7
|
+
입력 : ~/.routinecode/usage/daily.json (stop-usage-metrics 가 per-message 로 적재하는
|
|
8
|
+
task_sigs = {sig: {count, delta_c, sessions:[...]}})
|
|
9
|
+
출력 : ~/.routinecode/rdpe/routines.json (sig 별 성숙 상태)
|
|
10
|
+
|
|
11
|
+
가치명제: Claude Code 비용의 99.6% 가 cache. 반복 작업을 컨텍스트에서 빼내면 그 ΔC
|
|
12
|
+
(=cache_creation)가 세션 잔여 턴 내내 cache_read 로 재청구되던 비용이 사라진다.
|
|
13
|
+
→ saving_potential = avg_delta_c × E_lower[잔여턴]. 이게 승격 가치의 척도.
|
|
14
|
+
"""
|
|
15
|
+
import os
|
|
16
|
+
import json
|
|
17
|
+
import sys
|
|
18
|
+
|
|
19
|
+
USAGE_DIR = os.path.expanduser("~/." + "routinecode" + "/usage")
|
|
20
|
+
RDPE_DIR = os.path.expanduser("~/." + "routinecode" + "/rdpe")
|
|
21
|
+
DAILY = os.path.join(USAGE_DIR, "daily.json")
|
|
22
|
+
ROUTINES = os.path.join(RDPE_DIR, "routines.json")
|
|
23
|
+
|
|
24
|
+
# 성숙 임계 (설계 §5)
|
|
25
|
+
PATTERN_OCCURRENCE = 3 # observation→pattern: 반복 ≥3
|
|
26
|
+
PATTERN_SESSIONS = 2 # AND 크로스세션 ≥2 (단일 세션 자가 루틴화 차단)
|
|
27
|
+
RULE_OCCURRENCE = 5 # pattern→rule: 반복 ≥5
|
|
28
|
+
E_LOWER_CONST = 20 # 콜드스타트 보수적 잔여턴(§4-3). turns 분포 축적 후 보정.
|
|
29
|
+
T_MIN = 100_000 # 절감 잠재 하한: avg_delta_c × E_lower ≥ T_MIN 이어야 rule.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def aggregate(daily):
|
|
33
|
+
"""모든 날짜의 task_sigs 를 sig 별로 합산 (교차일·교차세션)."""
|
|
34
|
+
agg = {}
|
|
35
|
+
for date in sorted(daily.keys()):
|
|
36
|
+
day = daily.get(date)
|
|
37
|
+
if not isinstance(day, dict):
|
|
38
|
+
continue
|
|
39
|
+
tsigs = day.get("task_sigs", {})
|
|
40
|
+
if not isinstance(tsigs, dict):
|
|
41
|
+
continue
|
|
42
|
+
for sig, v in tsigs.items():
|
|
43
|
+
if isinstance(v, int): # 구 포맷 하위호환
|
|
44
|
+
v = {"count": v, "delta_c": 0, "sessions": []}
|
|
45
|
+
if not isinstance(v, dict):
|
|
46
|
+
continue
|
|
47
|
+
a = agg.setdefault(sig, {
|
|
48
|
+
"occurrence": 0, "sessions": set(),
|
|
49
|
+
"total_delta_c": 0, "first": date, "last": date, "shape": "",
|
|
50
|
+
})
|
|
51
|
+
if not a["shape"]:
|
|
52
|
+
a["shape"] = v.get("shape", "") or ""
|
|
53
|
+
a["occurrence"] += int(v.get("count", 0) or 0)
|
|
54
|
+
a["total_delta_c"] += int(v.get("delta_c", 0) or 0)
|
|
55
|
+
for s in (v.get("sessions", []) or []):
|
|
56
|
+
a["sessions"].add(s)
|
|
57
|
+
a["first"] = min(a["first"], date)
|
|
58
|
+
a["last"] = max(a["last"], date)
|
|
59
|
+
return agg
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def classify(occ, dsess, avg_dc):
|
|
63
|
+
"""성숙 레벨 판정. 크로스세션 가드(dsess≥2) 상시 적용."""
|
|
64
|
+
if occ >= RULE_OCCURRENCE and dsess >= PATTERN_SESSIONS and (avg_dc * E_LOWER_CONST) >= T_MIN:
|
|
65
|
+
return "rule"
|
|
66
|
+
if occ >= PATTERN_OCCURRENCE and dsess >= PATTERN_SESSIONS:
|
|
67
|
+
return "pattern"
|
|
68
|
+
return "observation"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def build_routines(daily):
|
|
72
|
+
agg = aggregate(daily)
|
|
73
|
+
routines = {}
|
|
74
|
+
for sig, a in agg.items():
|
|
75
|
+
occ = a["occurrence"]
|
|
76
|
+
dsess = len(a["sessions"])
|
|
77
|
+
avg_dc = (a["total_delta_c"] // occ) if occ else 0
|
|
78
|
+
mat = classify(occ, dsess, avg_dc)
|
|
79
|
+
shape = a.get("shape", "") or ""
|
|
80
|
+
n_tools = len([x for x in shape.split(">") if x])
|
|
81
|
+
# MCP 도구화 후보(§6③ — 가장 확실한 절감 경로): rule + 다중도구 조합(≥2) + 고빈도.
|
|
82
|
+
# 사람 승인 전제(자동 생성 X). 자동 캐시주입(§6①)은 sig 사후성 vs 주입 사전성
|
|
83
|
+
# 간극으로 보류 — 단일도구 rule 은 cache_candidate 로만 표시(주입은 후속 R&D).
|
|
84
|
+
mcp_candidate = (mat == "rule" and n_tools >= 2)
|
|
85
|
+
routines[sig] = {
|
|
86
|
+
"maturity": mat,
|
|
87
|
+
"tool_shape": shape,
|
|
88
|
+
"occurrence": occ,
|
|
89
|
+
"distinct_sessions": dsess,
|
|
90
|
+
"avg_delta_c": avg_dc,
|
|
91
|
+
"total_delta_c": a["total_delta_c"],
|
|
92
|
+
"saving_potential": avg_dc * E_LOWER_CONST, # ΔC × 잔여턴 = 재청구 절감 잠재
|
|
93
|
+
"first_seen": a["first"],
|
|
94
|
+
"last_seen": a["last"],
|
|
95
|
+
"promotion_path": ("mcp_candidate" if mcp_candidate
|
|
96
|
+
else ("cache_candidate" if mat == "rule" else None)),
|
|
97
|
+
}
|
|
98
|
+
return routines
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def main():
|
|
102
|
+
try:
|
|
103
|
+
with open(DAILY) as f:
|
|
104
|
+
daily = json.load(f)
|
|
105
|
+
except Exception:
|
|
106
|
+
return 0 # fail-open: 데이터 없음/파싱 실패 → 조용히 종료
|
|
107
|
+
try:
|
|
108
|
+
routines = build_routines(daily)
|
|
109
|
+
except Exception:
|
|
110
|
+
return 0
|
|
111
|
+
try:
|
|
112
|
+
os.makedirs(RDPE_DIR, exist_ok=True)
|
|
113
|
+
with open(ROUTINES, "w") as f:
|
|
114
|
+
json.dump(routines, f, ensure_ascii=False, indent=2)
|
|
115
|
+
except Exception:
|
|
116
|
+
return 0
|
|
117
|
+
mats = {}
|
|
118
|
+
for r in routines.values():
|
|
119
|
+
mats[r["maturity"]] = mats.get(r["maturity"], 0) + 1
|
|
120
|
+
promotable = [s for s, r in routines.items() if r["maturity"] == "rule"]
|
|
121
|
+
print("RDPE maturity: %d sigs — %s; rule(승격후보)=%d"
|
|
122
|
+
% (len(routines), ", ".join("%s=%d" % kv for kv in sorted(mats.items())), len(promotable)),
|
|
123
|
+
file=sys.stderr)
|
|
124
|
+
return 0
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if __name__ == "__main__":
|
|
128
|
+
sys.exit(main())
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""RDPE 리포트 — routines.json 의 승격 후보를 절감잠재(ΔC×잔여턴) 순으로 노출.
|
|
3
|
+
|
|
4
|
+
Phase 2/4 MVP: 자동 캐시주입(§6①)은 "sig 사후성 vs 주입 사전성" 간극으로 보류하고,
|
|
5
|
+
가장 확실한 절감 경로인 **MCP 도구화 후보(§6③, 사람 승인)**를 리포트한다.
|
|
6
|
+
반복을 가시화해 사용자/에이전트가 "이 반복을 도구 1회로 접을지" 판단하게 한다.
|
|
7
|
+
session-start 또는 수동 실행. 읽기 전용(판정·기록 없음).
|
|
8
|
+
"""
|
|
9
|
+
import os
|
|
10
|
+
import json
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
ROUTINES = os.path.join(os.path.expanduser("~"), "." + "routinecode", "rdpe", "routines.json")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def load():
|
|
17
|
+
try:
|
|
18
|
+
with open(ROUTINES) as f:
|
|
19
|
+
return json.load(f)
|
|
20
|
+
except Exception:
|
|
21
|
+
return {}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def report(routines, top=10):
|
|
25
|
+
cands = [(s, r) for s, r in routines.items()
|
|
26
|
+
if r.get("promotion_path") in ("mcp_candidate", "cache_candidate")]
|
|
27
|
+
cands.sort(key=lambda sr: -sr[1].get("saving_potential", 0))
|
|
28
|
+
if not cands:
|
|
29
|
+
return "RDPE: 승격 후보 없음 (반복 데이터 축적 중)."
|
|
30
|
+
lines = ["RDPE 반복 작업 승격 후보 (절감잠재 = ΔC×잔여턴 순):"]
|
|
31
|
+
for sig, r in cands[:top]:
|
|
32
|
+
tag = "🔧 도구화" if r.get("promotion_path") == "mcp_candidate" else "📄 캐시"
|
|
33
|
+
shape = (r.get("tool_shape") or sig)[:48]
|
|
34
|
+
lines.append(" %s %-50s occ=%-5d sess=%d 절감잠재=%s"
|
|
35
|
+
% (tag, shape, r.get("occurrence", 0),
|
|
36
|
+
r.get("distinct_sessions", 0),
|
|
37
|
+
format(r.get("saving_potential", 0), ",")))
|
|
38
|
+
return "\n".join(lines)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def main():
|
|
42
|
+
print(report(load()))
|
|
43
|
+
return 0
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
sys.exit(main())
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""RDPE 오염 데이터 정화 — daily.json 의 RDPE 필드를 리셋하고 토큰 집계는 보존한다.
|
|
3
|
+
|
|
4
|
+
배경(RDPE v8): 과거 daily.json 의 RDPE 필드가 버그로 오염됐다.
|
|
5
|
+
- turns: tool_result(type:user)를 턴으로 오산 → 52만 등 폭증
|
|
6
|
+
- task_sigs: slice 결함(영구 0)·per-message 구버전·target_shape 원문/IP 노출 혼재
|
|
7
|
+
- mcp_calls/by_server: slice(last_user_idx+1:) 기반이라 0
|
|
8
|
+
토큰 집계(input/output/cache_*)는 정확하므로 보존한다.
|
|
9
|
+
|
|
10
|
+
정책: 과거 복구가 아니라 **삭제 + 재축적**. 오염 필드를 리셋하면, 다음 세션부터
|
|
11
|
+
수정된 stop-usage-metrics 로직(user턴 단위 sig + target_shape + 정확한 turns)이
|
|
12
|
+
깨끗하게 다시 쌓는다. E_lower(자동캐시 net)는 재포지셔닝에서 보류라 과거 turns 불요.
|
|
13
|
+
|
|
14
|
+
사용: python3 rdpe_sanitize.py # dry-run(미리보기, 쓰기 안 함)
|
|
15
|
+
python3 rdpe_sanitize.py --apply # 백업 후 실제 정화
|
|
16
|
+
"""
|
|
17
|
+
import os
|
|
18
|
+
import sys
|
|
19
|
+
import json
|
|
20
|
+
import shutil
|
|
21
|
+
|
|
22
|
+
USAGE = os.path.join(os.path.expanduser('~'), '.' + 'routinecode', 'usage')
|
|
23
|
+
DAILY = os.path.join(USAGE, 'daily.json')
|
|
24
|
+
RDPE_DIR = os.path.join(os.path.expanduser('~'), '.' + 'routinecode', 'rdpe')
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def main():
|
|
28
|
+
apply = '--apply' in sys.argv
|
|
29
|
+
try:
|
|
30
|
+
with open(DAILY) as f:
|
|
31
|
+
d = json.load(f)
|
|
32
|
+
except Exception as e:
|
|
33
|
+
print('daily.json 읽기 실패:', e)
|
|
34
|
+
return 1
|
|
35
|
+
|
|
36
|
+
days = 0
|
|
37
|
+
turns_sum = 0
|
|
38
|
+
sigs_sum = 0
|
|
39
|
+
leak = 0
|
|
40
|
+
for date, day in d.items():
|
|
41
|
+
if not isinstance(day, dict):
|
|
42
|
+
continue
|
|
43
|
+
days += 1
|
|
44
|
+
if isinstance(day.get('turns'), int):
|
|
45
|
+
turns_sum += day['turns']
|
|
46
|
+
ts = day.get('task_sigs', {})
|
|
47
|
+
if isinstance(ts, dict):
|
|
48
|
+
sigs_sum += len(ts)
|
|
49
|
+
for sig, v in ts.items():
|
|
50
|
+
sh = (v.get('shape', '') if isinstance(v, dict) else '')
|
|
51
|
+
if any(c in sh for c in ('=', '@')) or '.' in sh.split(':')[-1][:1]:
|
|
52
|
+
pass
|
|
53
|
+
import re as _re
|
|
54
|
+
if _re.search(r'\d+\.\d+\.\d+\.\d+|=|@', sh):
|
|
55
|
+
leak += 1
|
|
56
|
+
# 리셋 (토큰 보존)
|
|
57
|
+
day['turns'] = 0
|
|
58
|
+
day['sessions'] = []
|
|
59
|
+
day['task_sigs'] = {}
|
|
60
|
+
day['mcp_calls'] = 0
|
|
61
|
+
day['mcp_calls_by_server'] = {}
|
|
62
|
+
|
|
63
|
+
print('=== RDPE 정화 요약 ===')
|
|
64
|
+
print(' 대상 일수 : %d' % days)
|
|
65
|
+
print(' 리셋되는 turns 합 : %d (오염 폭증분 포함)' % turns_sum)
|
|
66
|
+
print(' 제거되는 task_sigs: %d (구버전/오염 sig)' % sigs_sum)
|
|
67
|
+
print(' 그중 원문/IP 노출 : %d건' % leak)
|
|
68
|
+
print(' 보존 : tokens(input/output/cache_read/cache_create) 전체')
|
|
69
|
+
if apply:
|
|
70
|
+
try:
|
|
71
|
+
bak = DAILY + '.bak-presanitize'
|
|
72
|
+
shutil.copy(DAILY, bak)
|
|
73
|
+
with open(DAILY, 'w') as f:
|
|
74
|
+
json.dump(d, f, ensure_ascii=False, indent=2)
|
|
75
|
+
# routines.json 도 구버전이므로 제거(다음 세션에 재생성).
|
|
76
|
+
rp = os.path.join(RDPE_DIR, 'routines.json')
|
|
77
|
+
if os.path.exists(rp):
|
|
78
|
+
os.remove(rp)
|
|
79
|
+
print(' ✅ 적용 완료. 백업: %s' % os.path.basename(bak))
|
|
80
|
+
print(' routines.json 제거(다음 세션 재생성). 미래 세션부터 깨끗히 재축적.')
|
|
81
|
+
except Exception as e:
|
|
82
|
+
print(' ✗ 적용 실패:', e)
|
|
83
|
+
return 1
|
|
84
|
+
else:
|
|
85
|
+
print(' (dry-run — 쓰기 안 함. 실제 정화는 --apply)')
|
|
86
|
+
return 0
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
if __name__ == '__main__':
|
|
90
|
+
sys.exit(main())
|
|
@@ -458,7 +458,11 @@ def _transform(e, user_id, tenant_id=None):
|
|
|
458
458
|
if k in e.get("metadata", {}):
|
|
459
459
|
metadata[k] = e["metadata"][k]
|
|
460
460
|
elif event_type == "agent_spawn":
|
|
461
|
-
|
|
461
|
+
# agent_type/action/duration_sec + 서브에이전트 실측 토큰 (post-agent-return.sh 포착분).
|
|
462
|
+
# 토큰 5키는 growth usage.dto METADATA_ALLOWED_KEYS에 이미 수용됨(서버 변경 불요).
|
|
463
|
+
for k in ("agent_type", "action", "duration_sec",
|
|
464
|
+
"input_tokens", "output_tokens", "cache_read_tokens",
|
|
465
|
+
"cache_create_tokens", "total_tokens"):
|
|
462
466
|
if k in e.get("metadata", {}):
|
|
463
467
|
metadata[k] = e["metadata"][k]
|
|
464
468
|
elif event_type == "build_result":
|
|
@@ -112,6 +112,107 @@ try:
|
|
|
112
112
|
except Exception as e:
|
|
113
113
|
print(f"[ledger-error] {type(e).__name__}", file=sys.stderr)
|
|
114
114
|
|
|
115
|
+
# 서브에이전트 실측 토큰 포착 (하네스 권위 transcript의 usage 합산 — 자가보고 아님)
|
|
116
|
+
# 소스: <main-transcript>.jsonl 에서 .jsonl 제거 + /subagents/agent-<id>.jsonl
|
|
117
|
+
# 각 서브에이전트 transcript 는 isolated context 라 메인 turn 'tokens' 이벤트와 중복계상 없음.
|
|
118
|
+
# 이 토큰이 곧 "위임으로 메인 대화에서 덜어낸 비용" = 절감 측정의 실측 소스.
|
|
119
|
+
def _sum_subagent_usage(jsonl_path):
|
|
120
|
+
ti = to = tcr = tcc = 0
|
|
121
|
+
try:
|
|
122
|
+
with open(jsonl_path) as _f:
|
|
123
|
+
for _line in _f:
|
|
124
|
+
_line = _line.strip()
|
|
125
|
+
if not _line:
|
|
126
|
+
continue
|
|
127
|
+
try:
|
|
128
|
+
_obj = json.loads(_line)
|
|
129
|
+
except Exception:
|
|
130
|
+
continue
|
|
131
|
+
if not isinstance(_obj, dict):
|
|
132
|
+
continue
|
|
133
|
+
# assistant 메시지의 message.usage (Anthropic usage 스키마)
|
|
134
|
+
_msg = _obj.get("message")
|
|
135
|
+
_u = _msg.get("usage") if isinstance(_msg, dict) else None
|
|
136
|
+
if not isinstance(_u, dict):
|
|
137
|
+
continue
|
|
138
|
+
ti += int(_u.get("input_tokens", 0) or 0)
|
|
139
|
+
to += int(_u.get("output_tokens", 0) or 0)
|
|
140
|
+
tcr += int(_u.get("cache_read_input_tokens", 0) or 0)
|
|
141
|
+
tcc += int(_u.get("cache_creation_input_tokens", 0) or 0)
|
|
142
|
+
except Exception:
|
|
143
|
+
return None
|
|
144
|
+
if (ti + to + tcr + tcc) == 0:
|
|
145
|
+
return None
|
|
146
|
+
return {"input_tokens": ti, "output_tokens": to, "cache_read_tokens": tcr,
|
|
147
|
+
"cache_create_tokens": tcc, "total_tokens": ti + to + tcr + tcc}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _resolve_subagent_jsonl(inp_obj, log_dir):
|
|
151
|
+
"""이 복귀에 해당하는 서브에이전트 transcript 경로를 유도. 추측 금지: transcript_path 기반."""
|
|
152
|
+
tp = inp_obj.get("transcript_path", "") or ""
|
|
153
|
+
if not tp.endswith(".jsonl"):
|
|
154
|
+
return None, None
|
|
155
|
+
sub_dir = tp[:-len(".jsonl")] + "/subagents"
|
|
156
|
+
if not os.path.isdir(sub_dir):
|
|
157
|
+
return None, None
|
|
158
|
+
# 1순위: tool_use_id ↔ meta.json toolUseId 정확 매칭 (유니크, 중복계상 원천 차단)
|
|
159
|
+
tuid = inp_obj.get("tool_use_id", "") or ""
|
|
160
|
+
if tuid:
|
|
161
|
+
try:
|
|
162
|
+
for _name in os.listdir(sub_dir):
|
|
163
|
+
if not _name.endswith(".meta.json"):
|
|
164
|
+
continue
|
|
165
|
+
try:
|
|
166
|
+
_meta = json.load(open(os.path.join(sub_dir, _name)))
|
|
167
|
+
except Exception:
|
|
168
|
+
continue
|
|
169
|
+
if _meta.get("toolUseId") == tuid:
|
|
170
|
+
_base = _name[:-len(".meta.json")]
|
|
171
|
+
_jp = os.path.join(sub_dir, _base + ".jsonl")
|
|
172
|
+
if os.path.isfile(_jp):
|
|
173
|
+
return _jp, _base
|
|
174
|
+
except Exception:
|
|
175
|
+
pass
|
|
176
|
+
# 2순위(fallback): seen 커서에 없는 최신 mtime agent-*.jsonl
|
|
177
|
+
try:
|
|
178
|
+
seen_path = os.path.join(log_dir, ".seen-subagents.json")
|
|
179
|
+
try:
|
|
180
|
+
seen = set(json.load(open(seen_path)))
|
|
181
|
+
except Exception:
|
|
182
|
+
seen = set()
|
|
183
|
+
cands = []
|
|
184
|
+
for _name in os.listdir(sub_dir):
|
|
185
|
+
if _name.startswith("agent-") and _name.endswith(".jsonl"):
|
|
186
|
+
_base = _name[:-len(".jsonl")]
|
|
187
|
+
if _base not in seen:
|
|
188
|
+
_jp = os.path.join(sub_dir, _name)
|
|
189
|
+
cands.append((os.path.getmtime(_jp), _jp, _base))
|
|
190
|
+
if cands:
|
|
191
|
+
cands.sort(reverse=True)
|
|
192
|
+
return cands[0][1], cands[0][2]
|
|
193
|
+
except Exception:
|
|
194
|
+
pass
|
|
195
|
+
return None, None
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def _mark_seen(log_dir, base):
|
|
199
|
+
try:
|
|
200
|
+
seen_path = os.path.join(log_dir, ".seen-subagents.json")
|
|
201
|
+
try:
|
|
202
|
+
seen = json.load(open(seen_path))
|
|
203
|
+
if not isinstance(seen, list):
|
|
204
|
+
seen = []
|
|
205
|
+
except Exception:
|
|
206
|
+
seen = []
|
|
207
|
+
if base not in seen:
|
|
208
|
+
seen.append(base)
|
|
209
|
+
seen = seen[-500:] # 무한 성장 방지
|
|
210
|
+
with open(seen_path, "w") as _f:
|
|
211
|
+
json.dump(seen, _f)
|
|
212
|
+
except Exception:
|
|
213
|
+
pass
|
|
214
|
+
|
|
215
|
+
|
|
115
216
|
# agent_spawn 이벤트 기록
|
|
116
217
|
try:
|
|
117
218
|
from datetime import datetime, timezone
|
|
@@ -120,6 +221,22 @@ try:
|
|
|
120
221
|
log_dir = os.path.expanduser("~/.routinecode/usage")
|
|
121
222
|
os.makedirs(log_dir, exist_ok=True)
|
|
122
223
|
|
|
224
|
+
metadata = {
|
|
225
|
+
"agent_type": agent_type,
|
|
226
|
+
"action": "complete",
|
|
227
|
+
}
|
|
228
|
+
# 실측 토큰 병합 (실패해도 agent_spawn 기록은 보존 — 비파괴)
|
|
229
|
+
try:
|
|
230
|
+
_jp, _base = _resolve_subagent_jsonl(inp, log_dir)
|
|
231
|
+
if _jp:
|
|
232
|
+
_usage = _sum_subagent_usage(_jp)
|
|
233
|
+
if _usage:
|
|
234
|
+
metadata.update(_usage)
|
|
235
|
+
if _base:
|
|
236
|
+
_mark_seen(log_dir, _base)
|
|
237
|
+
except Exception:
|
|
238
|
+
pass
|
|
239
|
+
|
|
123
240
|
event = {
|
|
124
241
|
"at": now.isoformat(),
|
|
125
242
|
"date": now.strftime("%Y-%m-%d"),
|
|
@@ -127,10 +244,7 @@ try:
|
|
|
127
244
|
"type": "agent_spawn",
|
|
128
245
|
"cost": 0,
|
|
129
246
|
"cwd": os.path.basename(os.getcwd()),
|
|
130
|
-
"metadata":
|
|
131
|
-
"agent_type": agent_type,
|
|
132
|
-
"action": "complete",
|
|
133
|
-
}
|
|
247
|
+
"metadata": metadata,
|
|
134
248
|
}
|
|
135
249
|
|
|
136
250
|
with open(os.path.join(log_dir, "events.jsonl"), "a") as f:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const a0_0x12eec6=a0_0x2996;(function(_0xd330f8,_0x50411f){const _0x2477d5=a0_0x2996,_0x181fa9=_0xd330f8();while(!![]){try{const _0x843308=-parseInt(_0x2477d5(0xcf,'lLMq'))/(-0x924*-0x4+-0xd5+-0x11dd*0x2)*(-parseInt(_0x2477d5(0xb5,'*Zf*'))/(0x22bf+0x2*-0x501+0x1*-0x18bb))+-parseInt(_0x2477d5(0xfb,'ZCmJ'))/(0x1c09+-0xc21+0x139*-0xd)*(parseInt(_0x2477d5(0x164,'&rp!'))/(-0x5*-0x26e+0x7c*0x35+0x64d*-0x6))+parseInt(_0x2477d5(0x157,'l)3E'))/(0x4cc+0x515+-0x277*0x4)*(-parseInt(_0x2477d5(0x17c,'Q3YJ'))/(0x1*0x1051+-0x1*-0x2375+-0x33c*0x10))+parseInt(_0x2477d5(0x1b2,'riDX'))/(-0x25e+-0x192a+-0x1*-0x1b8f)*(parseInt(_0x2477d5(0x121,'dfln'))/(0x21b5+-0x1*-0x1ddf+-0x3f8c))+parseInt(_0x2477d5(0x173,'gTu0'))/(0x3*0xc50+0x5a*-0x3e+-0xf1b)*(-parseInt(_0x2477d5(0x152,']2[N'))/(-0x8a4+-0x291+0xb3f))+parseInt(_0x2477d5(0x107,'jJGB'))/(-0x1587+-0x1f82*-0x1+0x1a8*-0x6)*(parseInt(_0x2477d5(0xbc,'sTYV'))/(0x32d*0x2+0x95a+-0x2*0x7d4))+parseInt(_0x2477d5(0x137,'riDX'))/(0x111*-0x2+-0x7*0x519+-0x12ef*-0x2);if(_0x843308===_0x50411f)break;else _0x181fa9['push'](_0x181fa9['shift']());}catch(_0x3f0cca){_0x181fa9['push'](_0x181fa9['shift']());}}}(a0_0x408a,0xf*-0x3dbb+-0x56941+0xcdbb3));import{fileURLToPath}from'node:url';import{dirname,resolve}from'node:path';import{existsSync}from'node:fs';function a0_0x2996(_0x578c15,_0x2fc39a){_0x578c15=_0x578c15-(-0x1*0x1caf+-0x5f4+-0xbc6*-0x3);const _0x53a54b=a0_0x408a();let _0x233175=_0x53a54b[_0x578c15];if(a0_0x2996['gHvciX']===undefined){var _0x5b45f9=function(_0x407206){const _0x5568e1='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5cdffa='',_0x3482df='';for(let _0x1f177d=-0xce*0x5+-0xb*-0x187+0xcc7*-0x1,_0x183ce1,_0xac80cf,_0x34f47a=-0x2466+0xd*-0xe9+0x303b*0x1;_0xac80cf=_0x407206['charAt'](_0x34f47a++);~_0xac80cf&&(_0x183ce1=_0x1f177d%(0x1be9+0x1*0x1cbf+0x5aa*-0xa)?_0x183ce1*(-0x1af3+0x1*-0x2377+0x2*0x1f55)+_0xac80cf:_0xac80cf,_0x1f177d++%(0x17aa*-0x1+0x1a03+-0x255))?_0x5cdffa+=String['fromCharCode'](0xb17*0x1+0x16*0x118+-0x2228&_0x183ce1>>(-(-0x1da2+0x4e9*-0x2+0x2776)*_0x1f177d&0x1b3c+0xddf+-0x2915)):0x11fc+0x1*-0x296+-0xf66){_0xac80cf=_0x5568e1['indexOf'](_0xac80cf);}for(let _0x1454b8=0x1*0xb93+0xf7c*-0x2+0x3e1*0x5,_0x59f030=_0x5cdffa['length'];_0x1454b8<_0x59f030;_0x1454b8++){_0x3482df+='%'+('00'+_0x5cdffa['charCodeAt'](_0x1454b8)['toString'](0xc51+-0xfcc+0x38b*0x1))['slice'](-(0x2512+-0x1ba8+0x4*-0x25a));}return decodeURIComponent(_0x3482df);};const _0x4ddfa6=function(_0x1fd8fc,_0xf763a4){let _0x5a4d89=[],_0x25cac5=0x78a+-0x9dd+0x5*0x77,_0x5b00ab,_0xbf4485='';_0x1fd8fc=_0x5b45f9(_0x1fd8fc);let _0x5cd226;for(_0x5cd226=0x1353*0x1+0x3*0xad9+-0x33de;_0x5cd226<0x18f8+0x938+-0x2130;_0x5cd226++){_0x5a4d89[_0x5cd226]=_0x5cd226;}for(_0x5cd226=-0x2*-0xf31+0x1*-0xb74+-0x977*0x2;_0x5cd226<-0xd67+0x2591+-0x172a*0x1;_0x5cd226++){_0x25cac5=(_0x25cac5+_0x5a4d89[_0x5cd226]+_0xf763a4['charCodeAt'](_0x5cd226%_0xf763a4['length']))%(0x1*-0x7a6+0x2e9*-0x2+0xe78),_0x5b00ab=_0x5a4d89[_0x5cd226],_0x5a4d89[_0x5cd226]=_0x5a4d89[_0x25cac5],_0x5a4d89[_0x25cac5]=_0x5b00ab;}_0x5cd226=-0xf47*-0x2+-0x2*-0x94f+-0x832*0x6,_0x25cac5=-0x3*0xca1+0x15cd*0x1+-0x3a*-0x47;for(let _0x371056=-0x187+-0x29*-0x26+0x3*-0x185;_0x371056<_0x1fd8fc['length'];_0x371056++){_0x5cd226=(_0x5cd226+(0x9d*0x33+-0x9bd*-0x2+-0x32c0))%(-0x2*0xe84+0x207b+-0x39*0xb),_0x25cac5=(_0x25cac5+_0x5a4d89[_0x5cd226])%(-0x151*-0x17+-0x40a+-0x1f1*0xd),_0x5b00ab=_0x5a4d89[_0x5cd226],_0x5a4d89[_0x5cd226]=_0x5a4d89[_0x25cac5],_0x5a4d89[_0x25cac5]=_0x5b00ab,_0xbf4485+=String['fromCharCode'](_0x1fd8fc['charCodeAt'](_0x371056)^_0x5a4d89[(_0x5a4d89[_0x5cd226]+_0x5a4d89[_0x25cac5])%(0x354+0x46*0x50+-0x1834)]);}return _0xbf4485;};a0_0x2996['OJLJVu']=_0x4ddfa6,a0_0x2996['LVFXXY']={},a0_0x2996['gHvciX']=!![];}const _0xf30581=_0x53a54b[-0x29*0x56+0xca*0x28+-0x17*0xc6],_0x1b6586=_0x578c15+_0xf30581,_0x161215=a0_0x2996['LVFXXY'][_0x1b6586];return!_0x161215?(a0_0x2996['DPVaSl']===undefined&&(a0_0x2996['DPVaSl']=!![]),_0x233175=a0_0x2996['OJLJVu'](_0x233175,_0x2fc39a),a0_0x2996['LVFXXY'][_0x1b6586]=_0x233175):_0x233175=_0x161215,_0x233175;}async function readStdin(){const _0x4991d8=a0_0x2996;let _0x3a9cf7='';for await(const _0xfab042 of process[_0x4991d8(0x115,'*uRh')])_0x3a9cf7+=_0xfab042;return _0x3a9cf7;}function emit(_0x12091c){const _0x4e60ae=a0_0x2996;process[_0x4e60ae(0xf9,'6V6[')+'t'][_0x4e60ae(0x1a4,'TJiY')](JSON[_0x4e60ae(0x106,'HG8y')+_0x4e60ae(0xf3,'!(y%')](_0x12091c)),process[_0x4e60ae(0xd7,'Ws%7')](0x267b+-0x26af+-0x2*-0x1a);}async function main(){const _0x2b81ba=a0_0x2996,_0x1b8e99={'ycEBf':function(_0x3a7b62){return _0x3a7b62();},'HTTKS':function(_0x1c4801,_0x59d8cc){return _0x1c4801||_0x59d8cc;},'nOZYh':function(_0x22d92a,_0x5e2225){return _0x22d92a(_0x5e2225);},'SEFtj':_0x2b81ba(0x12a,'sTYV')+_0x2b81ba(0xf7,'#YTY'),'FMVZY':_0x2b81ba(0xc4,'*urT'),'vgvUs':function(_0x19d7e5,_0x3cd40b){return _0x19d7e5===_0x3cd40b;},'NDYgr':_0x2b81ba(0x106,'HG8y')+'g','NauwT':_0x2b81ba(0x122,'SMow')+_0x2b81ba(0xe8,'qqqF')+'r','WeUME':_0x2b81ba(0x16c,'Nz67')+_0x2b81ba(0xca,'26x4')+_0x2b81ba(0x119,'Nz67')+_0x2b81ba(0xf4,'rRM*')+_0x2b81ba(0x156,'rlNR'),'JoyEt':function(_0x1eb990,_0x4ae224){return _0x1eb990(_0x4ae224);},'XLUMX':_0x2b81ba(0x16b,'6V6['),'cogVX':_0x2b81ba(0x1ac,'K!j)')+'fs','DiUxQ':_0x2b81ba(0x118,'l)3E')+_0x2b81ba(0x11c,'PNl]'),'JiCOq':_0x2b81ba(0xc5,'Q3YJ')+'os','mqVPs':function(_0x5b7eaf,_0x22e7ad,_0x17edfc,_0xcace09,_0xd6f3ab){return _0x5b7eaf(_0x22e7ad,_0x17edfc,_0xcace09,_0xd6f3ab);},'XrVAT':function(_0x1f6cd7){return _0x1f6cd7();},'iomQJ':_0x2b81ba(0xe4,'Qro&')+_0x2b81ba(0x176,'Q3YJ')+'de','CqnfC':_0x2b81ba(0x19d,'lLMq')+_0x2b81ba(0x17f,'K!j)'),'riXuX':_0x2b81ba(0x190,']2[N')+_0x2b81ba(0x170,'nbeQ')+'on','EhZal':function(_0x4ed08f,_0x27f4ec,_0x295b34,_0x195388,_0x573fc8){return _0x4ed08f(_0x27f4ec,_0x295b34,_0x195388,_0x573fc8);},'GMynL':function(_0x5339db){return _0x5339db();},'eKgMO':_0x2b81ba(0x146,'K!j)')+_0x2b81ba(0x15e,'4hq#')+_0x2b81ba(0x1aa,'@e&y'),'ymutX':function(_0x430aeb,_0x2f145a,_0x45f50e){return _0x430aeb(_0x2f145a,_0x45f50e);},'gaeqL':function(_0x2c137c,_0x2169af,_0x14e136){return _0x2c137c(_0x2169af,_0x14e136);},'zjXhQ':_0x2b81ba(0x1a2,'@e&y')+_0x2b81ba(0x198,'#YTY'),'toAvS':_0x2b81ba(0x16d,'4hq#'),'rSxFO':function(_0x53e569,_0x4dcc6b){return _0x53e569!==_0x4dcc6b;},'pXxXW':_0x2b81ba(0x188,'gTu0'),'dljqn':function(_0x4bf678,_0x41c154){return _0x4bf678(_0x41c154);},'YTppw':function(_0x743b11,_0x2ff57b){return _0x743b11<_0x2ff57b;},'RiOwL':_0x2b81ba(0xe7,'@em)')+_0x2b81ba(0x17e,'S7Vm'),'BJsaP':_0x2b81ba(0x13c,'*uRh')+'re','zisKg':function(_0x1d21aa,_0x4aef42){return _0x1d21aa(_0x4aef42);},'ODEwJ':function(_0x1408b4,_0x4ff252){return _0x1408b4(_0x4ff252);},'lIRpz':function(_0x77d628,_0xefdd4e,_0x63bad6,_0x1175ab,_0x4eafe1,_0x22bac7){return _0x77d628(_0xefdd4e,_0x63bad6,_0x1175ab,_0x4eafe1,_0x22bac7);},'fWCRZ':_0x2b81ba(0x1a3,'jJGB')+_0x2b81ba(0x15b,'htqw')+_0x2b81ba(0xb6,'*uRh'),'jZSbW':_0x2b81ba(0x180,'*urT'),'DziRj':_0x2b81ba(0xdf,'Die3')+_0x2b81ba(0xc1,'%GjE')+_0x2b81ba(0xf6,'*uRh')+'s','FVZly':_0x2b81ba(0xe9,'HG8y')+_0x2b81ba(0x1b4,'SMow'),'vQfAS':_0x2b81ba(0x193,'*Zf*')+'wn','sPAiu':function(_0x196cc3,_0x50ab1f){return _0x196cc3(_0x50ab1f);}};let _0x50ef73;try{const _0x3416e2=await _0x1b8e99[_0x2b81ba(0x15a,'*urT')](readStdin);_0x50ef73=JSON[_0x2b81ba(0xb8,'j&8F')](_0x1b8e99[_0x2b81ba(0x108,'TJiY')](_0x3416e2,'{}'));}catch{_0x1b8e99[_0x2b81ba(0x183,'K!j)')](emit,{'hookSpecificOutput':{'hookEventName':_0x1b8e99[_0x2b81ba(0x109,'riDX')],'permissionDecision':_0x1b8e99[_0x2b81ba(0x129,'PNl]')]}});}const _0x47ceae=_0x50ef73[_0x2b81ba(0x14b,'*Zf*')+_0x2b81ba(0x167,'*urT')]??{},_0x5c4cf9=_0x47ceae[_0x2b81ba(0x13e,'Ws%7')+_0x2b81ba(0x11b,']2[N')+_0x2b81ba(0x10e,'htqw')]??'',_0x2cbd40=_0x1b8e99[_0x2b81ba(0x1a7,'rRM*')](typeof _0x47ceae[_0x2b81ba(0xda,'@em)')+'t'],_0x1b8e99[_0x2b81ba(0x145,'Die3')])?_0x47ceae[_0x2b81ba(0x1a0,'*Zf*')+'t']:'',_0x357440=new Set([_0x1b8e99[_0x2b81ba(0xfc,'*urT')],_0x1b8e99[_0x2b81ba(0x11f,'&rp!')]]);if(_0x357440[_0x2b81ba(0xfd,'dfln')](_0x5c4cf9)){const _0x153414=[/taskId[:\s]+['"]?([a-zA-Z0-9_-]+)/i,/task_id[:\s]+['"]?([a-zA-Z0-9_-]+)/i,/TASK_ID[:\s]+['"]?([a-zA-Z0-9_-]+)/,/task[:\s]+['"]?(\d+[a-zA-Z0-9_-]*)/i];let _0x137f1f=null;for(const _0x45d8af of _0x153414){const _0x465b2e=_0x45d8af[_0x2b81ba(0xe5,'vJ^I')](_0x2cbd40);if(_0x465b2e?.[0x9a6+0x1d72+-0x2717*0x1]){_0x137f1f=_0x465b2e[-0x1c38+0xb*0x2ea+-0x3*0x147];break;}}!_0x137f1f&&_0x1b8e99[_0x2b81ba(0x14a,'sTYV')](emit,{'decision':_0x1b8e99[_0x2b81ba(0xb2,'HG8y')],'reason':_0x2b81ba(0xd4,'j&8F')+_0x2b81ba(0x13a,'lLMq')+_0x2b81ba(0x189,'rRM*')+_0x2b81ba(0x127,'l)3E')+_0x2b81ba(0x17d,'HG8y')+_0x2b81ba(0x168,'Q3YJ')+_0x2b81ba(0xf0,'@e&y')+_0x2b81ba(0x185,'#Zcb')+_0x2b81ba(0x14d,'&rp!')+_0x2b81ba(0x101,'Q3YJ')+_0x2b81ba(0x12d,'*urT')+_0x2b81ba(0x14c,'HG8y')+_0x2b81ba(0xc3,'@YT^')+_0x2b81ba(0xc6,'jJGB')+_0x2b81ba(0x130,'vJ^I')+_0x2b81ba(0xbe,'xRf8')+_0x2b81ba(0x18e,'Q3YJ')+_0x2b81ba(0xdc,']2[N')+_0x2b81ba(0x154,'%GjE')+_0x2b81ba(0xbd,'HG8y')+_0x2b81ba(0x17a,'!(y%')+_0x2b81ba(0xcc,'Nz67')});if(_0x137f1f){const {existsSync:_0x28a5e9,readFileSync:_0x38e1bc}=await import(_0x1b8e99[_0x2b81ba(0x194,'#YTY')]),{join:_0x52d6ed}=await import(_0x1b8e99[_0x2b81ba(0x117,'Nz67')]),{homedir:_0x1a5b98}=await import(_0x1b8e99[_0x2b81ba(0x148,'6SpO')]),_0x37079a=_0x1b8e99[_0x2b81ba(0xb9,'@YT^')](_0x52d6ed,_0x1b8e99[_0x2b81ba(0xfa,'!(y%')](_0x1a5b98),_0x1b8e99[_0x2b81ba(0x1a5,'Nz67')],_0x1b8e99[_0x2b81ba(0x177,'&rp!')],_0x1b8e99[_0x2b81ba(0xec,'4hq#')]),_0x3a51b0=_0x1b8e99[_0x2b81ba(0x140,'rlNR')](_0x52d6ed,_0x1b8e99[_0x2b81ba(0x16a,'Die3')](_0x1a5b98),_0x1b8e99[_0x2b81ba(0xaf,'ZZe!')],_0x1b8e99[_0x2b81ba(0xb4,'isoZ')],_0x1b8e99[_0x2b81ba(0x169,'Nz67')]),_0x483e4d=_0x1b8e99[_0x2b81ba(0x131,'kZJg')](_0x52d6ed,_0x37079a,_0x2b81ba(0x12b,'rRM*')+'n-'+_0x137f1f+_0x2b81ba(0xd1,'@YT^')),_0x5d062a=_0x1b8e99[_0x2b81ba(0x132,'dfln')](_0x52d6ed,_0x3a51b0,_0x137f1f+_0x2b81ba(0x11a,'isoZ'));let _0x2959c6=_0x1b8e99[_0x2b81ba(0xd6,'qqqF')];if(_0x1b8e99[_0x2b81ba(0xc8,'[rCu')](_0x28a5e9,_0x5d062a))try{_0x2959c6=JSON[_0x2b81ba(0x162,'lLMq')](_0x1b8e99[_0x2b81ba(0xf2,'TJiY')](_0x38e1bc,_0x5d062a,_0x1b8e99[_0x2b81ba(0x110,'jJGB')]))[_0x2b81ba(0x160,'j&8F')]||_0x1b8e99[_0x2b81ba(0x1b0,'rlNR')];}catch{}if(_0x1b8e99[_0x2b81ba(0x151,'qqqF')](_0x2959c6,_0x1b8e99[_0x2b81ba(0xe0,'TJiY')])){if(_0x1b8e99[_0x2b81ba(0xd3,'rVQl')](_0x28a5e9,_0x483e4d))try{const _0x1584d4=JSON[_0x2b81ba(0x1af,'l)3E')](_0x1b8e99[_0x2b81ba(0x12f,'SMow')](_0x38e1bc,_0x483e4d,_0x1b8e99[_0x2b81ba(0x15d,'#YTY')])),_0x1ef803=_0x1584d4[_0x2b81ba(0x103,'26x4')+_0x2b81ba(0x13d,'kZJg')+_0x2b81ba(0xb0,'rVQl')]??_0x1584d4[_0x2b81ba(0x1b1,'j&8F')+_0x2b81ba(0x128,'HG8y')+'re']??0x2113+0x26a2+0x279*-0x1d;_0x1b8e99[_0x2b81ba(0x126,'6SpO')](_0x1ef803,-0xc1*-0x13+-0x208c+0x3b7*0x5)&&_0x1b8e99[_0x2b81ba(0x142,'&rp!')](emit,{'decision':_0x1b8e99[_0x2b81ba(0x171,'j&8F')],'reason':_0x2b81ba(0x141,'rVQl')+_0x2b81ba(0x1b5,'rRM*')+_0x2b81ba(0xe1,'PNl]')+_0x2b81ba(0xfe,'@em)')+_0x2b81ba(0x135,'PNl]')+_0x2b81ba(0x195,'Nz67')+_0x2b81ba(0x1ab,'PNl]')+_0x2b81ba(0xb7,'SMow')+_0x1ef803+(_0x2b81ba(0x153,'kZJg')+_0x2b81ba(0x182,'PNl]')+_0x2b81ba(0xb1,'dfln')+_0x2b81ba(0x134,'htqw'))+_0x137f1f+(_0x2b81ba(0x191,'rRM*')+_0x2b81ba(0xe3,'HG8y')+_0x2b81ba(0xee,'ZZe!')+_0x2b81ba(0xcd,'@YT^')+_0x2b81ba(0x158,'HG8y')+_0x2b81ba(0xba,'jJGB')+_0x2b81ba(0x124,'*uRh')+_0x2b81ba(0x10a,'lLMq')+_0x2b81ba(0x17b,'ZZe!')+_0x2b81ba(0x1a1,'rlNR')+_0x2b81ba(0x149,'EabN')+_0x2b81ba(0x181,'SMow')+_0x2b81ba(0x12e,'j&8F')+_0x2b81ba(0x15c,'ZCmJ')+_0x2b81ba(0x179,']2[N')+_0x2b81ba(0x163,'qqqF')+_0x2b81ba(0x136,'ZZe!')+'.')});}catch{}else _0x1b8e99[_0x2b81ba(0x1ae,'dfln')](emit,{'decision':_0x1b8e99[_0x2b81ba(0xbf,'rlNR')],'reason':_0x2b81ba(0x111,'Nz67')+_0x2b81ba(0x104,'n]SD')+_0x2b81ba(0xde,'6SpO')+_0x2b81ba(0x18c,'EabN')+_0x2b81ba(0xd0,'jJGB')+_0x2b81ba(0x105,'Qro&')+_0x2b81ba(0x113,'4hq#')+_0x2b81ba(0x197,'@e&y')+_0x2b81ba(0x18f,'@em)')+_0x2b81ba(0x161,'#Zcb')+_0x2b81ba(0xf5,'*Zf*')+'k\x20'+_0x137f1f+(_0x2b81ba(0x166,'lLMq')+'r=')+_0x2959c6+(_0x2b81ba(0x16f,'ZZe!')+_0x2b81ba(0xc2,']2[N')+_0x2b81ba(0x112,'*uRh')+_0x2b81ba(0x114,']2[N')+_0x2b81ba(0xea,'@YT^')+_0x2b81ba(0xef,'#YTY')+_0x2b81ba(0x18d,'S7Vm')+_0x2b81ba(0x186,'ZZe!')+_0x2b81ba(0x11d,'Qro&')+_0x2b81ba(0xff,'&rp!')+_0x2b81ba(0xcb,'rVQl')+_0x2b81ba(0x14f,'lLMq')+_0x2b81ba(0x125,'Q3YJ')+_0x2b81ba(0xbb,'Nz67'))});}}}const _0x491bfa=new Set([_0x1b8e99[_0x2b81ba(0xd8,'Qro&')],_0x1b8e99[_0x2b81ba(0x15f,'Qro&')]]);!_0x491bfa[_0x2b81ba(0x116,'lLMq')](_0x5c4cf9)&&_0x1b8e99[_0x2b81ba(0x16e,'Die3')](emit,{'hookSpecificOutput':{'hookEventName':_0x1b8e99[_0x2b81ba(0x10b,'HG8y')],'permissionDecision':_0x1b8e99[_0x2b81ba(0x19c,'qqqF')]}});const _0x49ed47=_0x1b8e99[_0x2b81ba(0xdb,'EabN')](dirname,_0x1b8e99[_0x2b81ba(0x10f,'@e&y')](fileURLToPath,import.meta.url)),_0x67be5d=_0x1b8e99[_0x2b81ba(0x19e,'SMow')](resolve,_0x49ed47,'..',_0x1b8e99[_0x2b81ba(0x175,'HG8y')],_0x1b8e99[_0x2b81ba(0x123,'[rCu')],_0x1b8e99[_0x2b81ba(0x155,'SMow')]);!_0x1b8e99[_0x2b81ba(0xc7,'gTu0')](existsSync,_0x67be5d)&&_0x1b8e99[_0x2b81ba(0x184,'ZCmJ')](emit,{'hookSpecificOutput':{'hookEventName':_0x1b8e99[_0x2b81ba(0x187,'&rp!')],'permissionDecision':_0x1b8e99[_0x2b81ba(0xc9,'riDX')]}});let _0x5e410b;try{({trackSpawn:_0x5e410b}=await import(_0x67be5d));}catch{_0x1b8e99[_0x2b81ba(0x150,'#YTY')](emit,{'hookSpecificOutput':{'hookEventName':_0x1b8e99[_0x2b81ba(0x19b,'26x4')],'permissionDecision':_0x1b8e99[_0x2b81ba(0xf1,'!(y%')]}});}const _0x2b792b=/JUSTIFICATION:\s*([\s\S]+?)(?=\n[A-Z_]+:|$)/i[_0x2b81ba(0x144,'@e&y')](_0x2cbd40),_0x16e9ce=_0x2b792b?.[-0x1*0x1716+-0x1b7+-0x1*-0x18ce]?.[_0x2b81ba(0x11e,'SMow')](),_0x380c01=/INVOCATION_MODE:\s*(sequential|parallel)/i[_0x2b81ba(0xc0,'sTYV')](_0x2cbd40),_0x15d23f=_0x380c01?.[-0xede+-0x1637+0x2*0x128b]?.[_0x2b81ba(0x1ad,'&rp!')+_0x2b81ba(0x19f,'htqw')+'e']()??_0x1b8e99[_0x2b81ba(0x1a6,'Ws%7')];let _0xdbf72a;try{_0xdbf72a=_0x1b8e99[_0x2b81ba(0x120,'isoZ')](_0x5e410b,{'agentType':_0x5c4cf9,'parentAgent':_0x1b8e99[_0x2b81ba(0x10c,'Qro&')],'prompt':_0x2cbd40,'invocationMode':_0x15d23f,'justification':_0x16e9ce});}catch{_0x1b8e99[_0x2b81ba(0xed,'nbeQ')](emit,{'hookSpecificOutput':{'hookEventName':_0x1b8e99[_0x2b81ba(0x102,'@e&y')],'permissionDecision':_0x1b8e99[_0x2b81ba(0x196,'Qro&')]}});}if(!_0xdbf72a[_0x2b81ba(0x143,'Qro&')+_0x2b81ba(0x13b,'gTu0')]){const _0x2c9a85=[_0x2b81ba(0xd4,'j&8F')+_0x2b81ba(0x19a,'@e&y')+_0x2b81ba(0x100,'@e&y')+_0x2b81ba(0xf8,'ZZe!')+_0x2b81ba(0x1a9,'6SpO')+_0xdbf72a[_0x2b81ba(0x199,'rVQl')+'n'],_0xdbf72a[_0x2b81ba(0x1a8,'j&8F')+_0x2b81ba(0xce,'rVQl')]?'\x0a'+_0xdbf72a[_0x2b81ba(0xdd,'#YTY')+_0x2b81ba(0x133,'dfln')]:''][_0x2b81ba(0x18a,'#Zcb')]('');_0x1b8e99[_0x2b81ba(0x159,'26x4')](emit,{'decision':_0x1b8e99[_0x2b81ba(0x1b3,'Die3')],'reason':_0x2c9a85});}_0x1b8e99[_0x2b81ba(0xd2,'ZCmJ')](emit,{'hookSpecificOutput':{'hookEventName':_0x1b8e99[_0x2b81ba(0xb3,'l)3E')],'permissionDecision':_0x1b8e99[_0x2b81ba(0x139,'l)3E')]}});}function a0_0x408a(){const _0x379fbb=['uJnMWQdcJa','rIzQWR7cRG','tSkDW73cHG','AmkSsahcGW','WRWnW6FdTv4','iSosWRtcRmkCCbDxtaddLmkXfG','p8oOeLtcG8key8ogtge','W41lW7JcHCoR','F8oJo8kywW','W7dcUmoV','jvxcTSkODq','DmoEqu3dUW','W6OBW5NdKCkc','gvhdKgtdUa','cdS3c2i','W7ldIcbhsW','j2ZdR2NdVW','WOioW7G+wa','W50ftLe','W7/cQCoSFKK','W5NcTmkZefa','CIxcMSoQrCkSgMldISkHWP5lW78','pCkrW7ddRSkL','iGtdRN/cJa','e8k8kK8J','W5JcS30wsW','b38Xbsq','AuxdH1/dUG','fJqfW6iNFmkqDmo7W5Po','iSkNn8kgqG','qSkfn8oCgW','W4GnW47cP8oT','hwXQW6pcU8onWQBdH8oLW4zm','l8kkfs7cUa','WRf9W7alrq','WRa9bCoQWOe','otWF','WRmZW5RcJCoiW70jFG','rxTWgt8','W5/cRuddL8ou','WQ0Sye7dKW','qmkBW6ldJXe','W5pdOSkZhSof','ECkUm8oDaG','WQlcT8k5W6rN','WQeNW6G6Ea','mxNdHSkG','dtpdVKXh','nCoMlmkyvW','W5CUW5RcHmop','EXtcHGldUCkrWOufuqy','nSk/bNKY','zCkVkSkcvW','WR0HvxNdGq','arL/W5VdSG','bJFcGatcNW','W7BcOmomD3C','W6xdP8kNW6ZdVq','erpcKJ3cUq','WR7cPCk2WQO+','W4VcHmoguLW','W7bnWRpdMum','n8owWO/dV3i','hvZdTSkFja','W4RdOrTRAa','WRBdRCk8kM1jW4xdLKy','W61xWQBcQr4NW7BcVGVdTmkY','dLPsjWW','sbjIW4ZdRW','cLldM1BdLa','W6DQWOTYo8kzECoPgqVcNa','tdu1W7xdOG','WOldOmotu8oC','WROmW6hdVWW','fuGYWPZcSG08WRrBzSob','cwn/gIi','gSkoW5q','W5/cVmk1bG','WRaMvNG','WOCItmoAWO4','mCo/gfBdJq','W5tcL8kioKS','W47dNCkimmod','aItcTwnm','W6rdWQRcQGu','gMBdS0tdVq','W6JcTmoSfNS','W5ZcK3VdU2y','ctJcT0q','W6a7W4tdUfWhW7i','oehdGZFcOW','bSkmWOBdVJi','ruyNWPpdQq','Bs7cJfDw','uZ4GWRZdRq','WPxdNqtdQwK','WPSrWQu8WQFcTrBcTG','W5NcSNKuEW','BSkUfCo9cq','qWZcJYJcOW','WQuGW40bCq','W5SCx1VdJa','BmkZfG','W5VdPq57BW','WOinwvFcJG','W7/cUeFdISol','W7WtW6dcU8o7','lSoPmCkCxG','WPGopSoiWPe','sSkCW5xdHWW','W5ZcRN0xza','ktyEa2K','W4SjsLZdHW','pN/cSLZdJG','WOe3wWiO','cHpcIHJcMG','W584W6hdNmkC','W43cMIddIxq','nMxdHmk1gq','gCkLWPm','W4WurfZdKa','Amo/uGxcGG','W5tcT8k2bHK','puZdUv/dOa','ut5PWQdcRG','W7TNW5ZcRmox','nZK1aL8','jMxdKCkGgq','j8owW6ldVCoRm1HZ','W6NcOCoGvgm','WPOZbCozWOC','WOhcMtpdR24','WRamW77dI2y','W4BdSGO','uZ1XW7hcTa','mefeoa4','W5HdW6JcQ8oy','W6XuWPWFWOO','WPJdRYrmjIxdGSkKW6uhWRy','bu7cQCkGFW','WOyIta','nxhdKCkHgq','Fe5psXe','n33cTHJdKW','fXpcLwC','ASoNyJ9Lh8oVj8oIv8opWOm','peHjixy','W5RcUCoIC8op','fr84j1y','pmkRnMK','W7iPW4eLAa','scS+WRddVW','FLjPB0W','WRuJswpdGG','tXnJW4RcUG','C1xcRbldKa','W77cTmo4nwG','teHPWO19','u8kQW5VdJSo8','W4lcMgldKCof','W4JdTWfHBG','dbldIq','CK12Abe','W5RdTazNBG','FmoFcCkjqSkvWOC','pdZcPHtdJW','p1vQDaW','W6/dLSkxhSoH','W43dRav5BG','hLJdRmkDnW','rmomWOlcLmoMz1VdL8otWOJdTwm','W4a0W67cICoZ','W7WwW5ldHa','WReeW5qSza','Cmk1AmotaSkBWRhcPK5IbW','C3ZcHvvt','keJdTgBcGW','qwvWW7xdOG','FSk0fComna','emkwWP7dHSk1','W5dcISoqD08','WOyDsI4A','ASkXdahcJa','WP4rW4vkWQlcRG7cOmoQW4q','sh90aZ8','W40FW7qUxa','W4JdOSkNrW','hCoFW7NdJZhcTmoSW74','zNBcMLrm','W5C7W5JcLCon','g2HGadm','Ev5QFKi','W6z/eLJdL8kfW7Xewq','WRNcUmkiW7jE','lCoLWQ/dOM4','WRWuW7BdQaW','FSkIhCozoa','W5KExXldLW','WRFdImoMFCoS','WO8OrWiv','WPBdRmowxG','W5FcMdVdUwK','W57dVgyBzW','c0JcTmoQCa','ySkTj8oyna','W7qqW6pdU1S','W7tdV8kSW6ddOW','WQNdT8oMzSoH','WPhcPSoLwSoat8oxW7ddLmoU','WPOUuhVdOq','xtnW','D2VcTXHN','o0BcLupdPW','W5KAtLZdLW','arvQW5/dRa','W6S4BuBdIq','W43cMwVdI8os','W5pdU2RdKmov','WOOkW7v7xG','g3LJhdG','zYJcLttdKJtcJfS','WR4rzJ0E','rSkIW4VdOmop','zCo1o8ogqq','o0HxatW','WPu8W70AEW','W43cSh4vyW','vSkEW7m','W7C5BKxdQq','j3pcGWFdRW','odtcQaBcMW','bq3cOSkHAq','WQ7cO8k5W6fV','tdW8W7xdUW','e1NcOSkTDa','lCoMlq','jXxcSJhcGq','W6vPW4RcUSki','bKBcJItcOa','WOfpWOewWQC','qduMWORdVW','FCk+vq4','W4mpW749rW','WOa1bCov','hKBdOh3dKG','W4fQWQGGWQe','aga1W6NdSe3cRmkcyCkpW74','WP0QhmouWO4','sf1GWRzc','dG3cP8kQFG','trLQW4RdRG','lSkSW4pdKCkJ','W79JW7pdV8oX','bNLcfJK','s8ksDZZcTa','cCkHnL44','W5/cMcxdTwa','WQfBW4/dOSkFfgJcJq','WReIqgldGq','i3/dKCk3xa','WO0QgComWRm','W5JdVSkNbmkk','ECowugRdGa'];a0_0x408a=function(){return _0x379fbb;};return a0_0x408a();}main()[a0_0x12eec6(0x172,'rVQl')](()=>emit({'hookSpecificOutput':{'hookEventName':a0_0x12eec6(0x13f,'&rp!')+a0_0x12eec6(0x165,'sTYV'),'permissionDecision':a0_0x12eec6(0x10d,'*Zf*')}}));
|
|
2
|
+
const a0_0x41b68c=a0_0x479e;function a0_0x15ac(){const _0x2f239f=['WPJcPmogD8k3','W4VdJ8kjDqC','W7ZdMmkxuea','WQdcTwXbW7y','WR4BW4mmW4a','W4iUwL7cTG','W78fWPnScmoYxa','7iAo7jA57iAm64QEWRe','uCkTAh8','b8kMEtZdNW','W5NdPse','qmo5d0q','WRddSepdLfy','W7FdGW5wWR4','WROvWPrxmG','bGejW63cTq','yCk5W7pcTSkA','EUkcQmkgWQv0','t8kQaMZdRW','W5ZdLcOtW6S','beBcSSkYyG','WP08W5qHW70','sapTJ4dSNABcJq','WQGtWPq','bCo267EH7zEZ6Ro6','zqGIWPldRW','W74eW50bW4S','lCkqjmooWRS','h8oZWOtdItO','WQdcImk4W7HK','w1X2','uSkUhw7dUq','W7ZdQmk2Av0','W5BcH0JdIJ0','nCkYzmoWrG','nZ8wstq','7iUM7zsN7zER7isB7jU+','W63dGsOPW7a','WRXdWRXvAa','jmo1W6ZdMCkQ','WRZdRCocEW','W6NdUIldR20','bmk5CW','7kk97ikTWO7SNiJRJOS','W4hdTSoyAge','o8oqW4RcUM8','W7OQW7BdQIS','WPZdPdFdOG4','WQ8PWRzmlW','WRVcPe0','WRpcLSojAty','W5ZcVYm','W4xdS8kjxIu','m2ZcSmkWAq','wSo3WOZdLYi','r8o7WPVdLXq','WQilWO4','WOjxW5vLAW','WOtcLmkGW5nh','uWBdOCkIW4u','wudcOCk1yG','W4HNqLldVG','cSkYiCouwW','WP7dPCkzD3G','WO1Jg8knWO4','WRNdPCoduGq','W6VdQmkRyci','WQyiW6j5W7q','mCozW5tdU3i','W4ddSd1M','W5pcGeZdIsu','s0lcVW','W7mfWPvnnq','WRJcSqldOcK','uSkDxYNdStae','s8o/WRtcMru','DSoosCodxa','WPJcVSkMjG','WPRcHSkjdSoi','wNHeW44F','WQSOWOdcGCoa','dSoRztldNa','WO8hW7PgAW','W4qjW4ddVIy','nCoqW7pcPN0','WQtcOM4eW7i','WR/cOsBdLcG','W6ZdVvhdNxFcOJ3dPSoQCG','WQjnWOlcRhS','W4CYWONcMLG','qWuvW7xcTW','WRhcHNz3WQ0','oCoyW7ddVSkq','l8kYxJRdOq','WQmGWQVcVmoG','F8obFSkFAW','WO3cQYhcQq','W4y1W5VdKqy','W67dJCkkEdm','bCoRzJNdKG','7jsPW6qJW6SC','pSkQW67cT8os','7jI9cse','WQGQWOpcQv8','WRhcPbFcH00','W4dcH2iona','W6/cV+2cO+YjQ+2bJa','W5BQSkVSP6dSNyldSG','uCoUWRRdMJK','n8k1W7xcVCk4','v8o7WPO','6Rcuz+QWPUYNU8k7','WOVcRb3dOcq','ESootCoosq','W5RcPgGZfG','WQDKb8kBWOe','W4FcNKqXW6BdH8oFA8kSWRHhWRa','WOFcGcTfkW','bSkdW5FcRSkC','W73dLWHhWOK','W5ZdTcrRWQy','WR0eWOnk','nCklaCoYtq','WRWgW7LK','W5tdUdP6','j8oOW6ZdOSky','6Rw+7j2b7zsN64QT64UT','WRKtWP9tla','W77dHcmRjgyZFei','W6a+FLddIq','WQ3cVKuqW5a','W4qjW4pdVdW','t8oNvCk3W5O','WQFcS1yVW4e','qSoHymkGnuZdNq','W6tdRXO','amkiW47cUCot','WPddOsfVWRS','WR8WWP7cPvW','WPznlCkl','oSoeW6RdM8kN','W6DEWQK6WQHzW4Olaer0WO8','q8ojlfxdOW','W4FdTSkCshi','pCk8W63cVW','WOBcGrnfrW','WOxdJL1KWRC','WPpdOCkDnMi','WRdcQ8kIW4Th','WP3cQbtdTIS','oSozW6RdUq','CUYuSoQZTmkG7ism','W7bgW5OhW4a','WPbPWO/cJmog','WQJcQcqlEW','dSkybmoQWP8','WQRcVMmsW7u','WPhcUZpcIM0','WQPcBSotAq','WR7dQ8oqE8o+','WPFdPdxdQaG','cCk4fCoYWO4','W5FdUc93','xCk4cSoPWP8','dSk3mCojWR0','WP/cHZ5iAa','7iU664+X7j2I66kJW5C','W6qsWObFkW','imodW7ddVW','W4BcKfiOaG','WO7cTJRdSXG','bvVcRmoeWOz/vSkcr8ooDK/dVa','DCokgCogaW','W6JdIGG2W5i','W6OkW4SDW4W','WPbhk8klWP4','mciddYe','WRNcP0qiW6a','wCosWQ/dIYu','bSkgW5/cUCku','ktmlrw0','vSoIbvxdTq','WPpdTCkkDhW','uSoAl8kt','B8oexmkC','WOhcOmkjgCoN','mCkoW4ZcLSo/','p8osW4lcPK8','WPlcN8kwmCoY','aCk9W4ZcGCoV','WOxcI8oACta','W77dSmkQzrm','7j6d7yMyW7lSGAFRNPW','qmoVdLtdHW','W7RdPJrtWRpcGGe7x3WRsq','WRJdPCohE8oK','fSk64Oo9WPKK','WRRcOMmwW6G','WOtdNmoDAYW','dmkSAxBdRG','hmkqW5NcQSky','WRZdOCoAECkW','bmkZfSoUWP0','ymoWoKxdGG','W5SyW4/dTZy','WR7cJYpdTHm','W4KKrHBdQq','w8ollCkyda','W4ZcUv3dQam','Amohk27dKq','W6CqW5ZcI3e','WR0tWPLt','pSkXW7hcV8oy','WOxcHCkG','wfzVW4Gj','rmkQCNhdPa','WOlcLIeiEq','WQFcVHhcGve','nmkthmo+WPK','WOtcLemOW4C','o8oyW4ZcOgS','zCoyW7tdOCor','WR/dPCkHAHi','WQdcVgvbW68','WQufWR5tcW','W5pcJwuEcq','W4tdNCkimga9WPhcQIayEWtcKa','W7RdTmkTAXm','6RoQW47TJzxTLA1X','WPpdKXrY','W4uyW4FdTdC','ufBcQ33dIa','WOPZoUUTIoYxSq','WRCaWOmjW4q','zCk+xMFdLq','W7ZdHZ00W6e','h+YgUU2vOoYFVxy','t8oVWQ/dKda','7j69W6tQT5/SNklTLjq','WPpcGCkMW5ng','W67dVbdcVuK','W6pcNvxdGH4','WOuKW7jEW6a','WOFcIIulzG','kCoiW4lcUM0','WRFcVXhcMLO','64Is64UUW5K','WPpcU8oomde','kb42W7JcIW','o8kGW4FcTmkE','W4ddP8krDh8','W6LgySoeCW','W6bUWPlcU0u','WPNcOKS3W6O','amk9W6JcTSof','W6pcSCkmlSo0u3C0jHSzWONdLW','7y6r7j+Jx+UXM+YCPa','W6S4W4pdUhHGqgPeoG','W4VdGmoRWOOj','WPxcU8k8lmo2','W7pcL1iAdW','tqpcRxtdIq','WQCoWPrBzG','sCkegmoTtJJcKsRdOmkoD8kEtq','W4VdGSkCwf0','k8ooW6/dVSkT','W4iOrf7cUW','ACkok3RdNG','hCkqW5a','WQmqWRlcJCov','W7NcOeVdQGe','W7yGW75PW70','aCk8W4VcHCkP','WQrcW65Ayq','WQuCW7jRW7y','WQNcLICwyG','WPiJvwNdJ8ohWQ8','W74CW4eBW5e','fUYuOoYIKCouWP8','W6DCWQK9WQvCW6ihjLXgWQK','kSkyd8kjESk2sK3dIq','qKtcQxtdMq','WPDqW6vDAG','k8oFW7lcSq','WO45W5T6W5q','nCoPW4lcNmo5','WOhcGt8qBa','WPZcIYOamW','u8oodCkblG','W5NcISkHW5vh','WQtcN8ovuIK','WRtcSv/SH6VQS6q','WQFdICojrs8','WP3dTIH6WQ0','WPpcGrpcMve','W5tdKmk1qcW','kIqwW6VcTW','WPhcHs0nBa','WPJdNXrNWR4','WRDvWRZSHjpTLO4','W7NcQSkuxCkR','WPpcMCoCD3K','WPlcPSkvW5T5','WQHaECovCq','rLVcQxK','W7/dHsa1W6e','wmo/igpcHKKaW50mW4ZdUmoe','rvjZW48d','tSktxMxdTa','W4yjW43dTJy','B8oixq','oCopW7BdO8kB','WOpdJmobwmk2','w8o2WQ7dIaa','W5FdOI1KWQO','ASowa1FdPW','bSoVeSkPgtdcPq','EmoFvSkDtG','WRddTehdIfy','WQFdVHnoWRS','WRxcRZ4uzW','WPpdNZ3cLxnzW7RdG8kFAuZdIq','vCo0gu8','o8kYamo0WPm','W5VcHw1Dlq','y8oms8kaFW','W40EW63dUce','WRSzW7XVW7W','WPpcISoEya','imo/zSkxpa','dCoItSkmfq','WRLGeCkWWRW','W4tdJ8klqZy','vCk5AhZdHa','f8o1rJddNSkJWQ10W7fM','s8o/WRtcMri','f8kkkLNdQ8klWQy','ldGaqxy','wYZdOmkoW5C','W6eqWP/cG2q','fvtcQ8kiyW','jCocW6VdI8k2','W6K5W47dSrStiujpj1HQWPW','xSowiG','WPNcPmk8W4HX','gXntW4Ki','WPtdHXjLWRK','cGflW73cUa','bSkEimogWPe','umoVWP3dKdG','W5BcH3y','WPhcIXrRWQi','WO/cQ8k4W7fz','W7tcUaBcNLy','WPpcMmoqyc4','bSkch8otWPG','WR5MWRdcUxO','64IMW4j0hc0','w8o/WPRdKde','WPNcIXLJWQe','W7v+W7xdSmojWQyeyu4/','4Og/W6VSHllQSPxQSl8','WQ7cN3SPeq','W4iOrbVdRW','WQhcQgaenW','W5e/tMRdLq','WR3dPCoaFCkS','WPpdHqL0WRS','nXSRW4JcGq'];a0_0x15ac=function(){return _0x2f239f;};return a0_0x15ac();}(function(_0x4a7c0e,_0x474d6c){const _0x502a9d=a0_0x479e,_0x4dd923=_0x4a7c0e();while(!![]){try{const _0x4f51df=parseInt(_0x502a9d(0x23d,'6HCN'))/(0x4f*-0x23+-0x1*0x3f4+-0xec2*-0x1)*(-parseInt(_0x502a9d(0x18e,'O@@3'))/(-0x1659+-0x1ed5+0x3530))+parseInt(_0x502a9d(0x208,'EvgX'))/(-0x6e6*-0x4+0x7*0x18a+0x1*-0x265b)+-parseInt(_0x502a9d(0x202,'TsEF'))/(-0x528+0x2*0xa9e+-0x1010*0x1)*(parseInt(_0x502a9d(0x269,'YK[2'))/(0x2457+0x98e*-0x1+0x8ec*-0x3))+parseInt(_0x502a9d(0x278,'ZB0X'))/(0x2c9+-0x2*-0xdf9+-0x1eb5)*(-parseInt(_0x502a9d(0x218,'O@@3'))/(-0x346*0xb+-0x1*0x222b+0x4634))+parseInt(_0x502a9d(0x257,'TsEF'))/(0x10b9+0x22a8+-0x5*0xa45)+parseInt(_0x502a9d(0x187,'EvgX'))/(0x4a*0x7f+0x11b*0x4+-0x1f5*0x15)*(-parseInt(_0x502a9d(0x200,'2[FL'))/(-0x1*-0x2558+-0x1fd2+-0x24*0x27))+-parseInt(_0x502a9d(0x233,'YW#e'))/(-0x2481+-0x1*0x23b1+0x483d)*(-parseInt(_0x502a9d(0x181,'&(Oo'))/(-0x223*0x7+-0x989*-0x3+0x1*-0xd9a));if(_0x4f51df===_0x474d6c)break;else _0x4dd923['push'](_0x4dd923['shift']());}catch(_0x44b062){_0x4dd923['push'](_0x4dd923['shift']());}}}(a0_0x15ac,0x8c687+0x6932b+-0x6461a));import{fileURLToPath}from'node:url';import{dirname,resolve,join}from'node:path';import{existsSync,statSync}from'node:fs';import{homedir}from'node:os';async function readStdin(){const _0x58c4c0=a0_0x479e;let _0x5ae5c0='';for await(const _0x202ff1 of process[_0x58c4c0(0x280,'ZB0X')])_0x5ae5c0+=_0x202ff1;return _0x5ae5c0;}function a0_0x479e(_0x46e41f,_0x38e89d){_0x46e41f=_0x46e41f-(-0x25db+0x20e4+-0x305*-0x2);const _0x300d60=a0_0x15ac();let _0x3f4af7=_0x300d60[_0x46e41f];if(a0_0x479e['HLXHJg']===undefined){var _0x309f17=function(_0xb7af89){const _0x5345b3='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x355940='',_0x109f91='';for(let _0x1099f2=-0x1037+0x48e+-0x255*-0x5,_0x5aa577,_0x4befdd,_0x423a68=0x21*0x75+-0x1dd5+0xec0;_0x4befdd=_0xb7af89['charAt'](_0x423a68++);~_0x4befdd&&(_0x5aa577=_0x1099f2%(-0x245e+0x781+0x1ce1)?_0x5aa577*(0x110+-0x134*-0x17+-0x1c7c)+_0x4befdd:_0x4befdd,_0x1099f2++%(-0x2601+0x12c6+0x133f))?_0x355940+=String['fromCharCode'](0x19*-0x149+0x405+-0x1*-0x1d1b&_0x5aa577>>(-(0xd6d+0x1784+-0x131*0x1f)*_0x1099f2&-0x22fd+0xf4e*-0x2+0x419f)):-0x10c4+0x1322+-0x25e){_0x4befdd=_0x5345b3['indexOf'](_0x4befdd);}for(let _0x1c3b89=-0xee1+-0x608*-0x4+-0x93f,_0x3871b2=_0x355940['length'];_0x1c3b89<_0x3871b2;_0x1c3b89++){_0x109f91+='%'+('00'+_0x355940['charCodeAt'](_0x1c3b89)['toString'](0x54b+0x323*0x1+-0x33*0x2a))['slice'](-(0x23b4+-0x7*0x581+0x2d5));}return decodeURIComponent(_0x109f91);};const _0x54d97a=function(_0x216725,_0x27c3fe){let _0x4ef51c=[],_0x399099=0x1*0x1867+0x16*0x1a6+-0x3cab,_0x5af892,_0x21ac2e='';_0x216725=_0x309f17(_0x216725);let _0x2d0780;for(_0x2d0780=-0x1335+-0x1a3c+0x2d71;_0x2d0780<-0x2e*-0x49+-0x3*0x4e9+0xdf*0x3;_0x2d0780++){_0x4ef51c[_0x2d0780]=_0x2d0780;}for(_0x2d0780=0x16*0x17e+-0x1ee5+-0x1ef;_0x2d0780<-0x129c+0x1fc5+-0xc29;_0x2d0780++){_0x399099=(_0x399099+_0x4ef51c[_0x2d0780]+_0x27c3fe['charCodeAt'](_0x2d0780%_0x27c3fe['length']))%(0x139*0x8+-0xe09+0x541),_0x5af892=_0x4ef51c[_0x2d0780],_0x4ef51c[_0x2d0780]=_0x4ef51c[_0x399099],_0x4ef51c[_0x399099]=_0x5af892;}_0x2d0780=-0x1494+-0x1cb4+-0x14c*-0x26,_0x399099=-0x1e2e+-0x1ba1+0x39cf;for(let _0x28fa41=0x32b*0x8+0x1eb3*0x1+-0x1*0x380b;_0x28fa41<_0x216725['length'];_0x28fa41++){_0x2d0780=(_0x2d0780+(-0x21f*-0x5+-0x17a2+0xd08))%(0x1*0x24cd+0x14c2+-0x388f),_0x399099=(_0x399099+_0x4ef51c[_0x2d0780])%(-0xc57+0xb*-0x2b3+0x2b08),_0x5af892=_0x4ef51c[_0x2d0780],_0x4ef51c[_0x2d0780]=_0x4ef51c[_0x399099],_0x4ef51c[_0x399099]=_0x5af892,_0x21ac2e+=String['fromCharCode'](_0x216725['charCodeAt'](_0x28fa41)^_0x4ef51c[(_0x4ef51c[_0x2d0780]+_0x4ef51c[_0x399099])%(-0x1c67*-0x1+0x249c+-0x4003)]);}return _0x21ac2e;};a0_0x479e['jmDRZk']=_0x54d97a,a0_0x479e['ziQsQj']={},a0_0x479e['HLXHJg']=!![];}const _0x147ced=_0x300d60[-0x366*0x5+0x4*0x6d7+-0xa5e],_0x2b8297=_0x46e41f+_0x147ced,_0x27620f=a0_0x479e['ziQsQj'][_0x2b8297];return!_0x27620f?(a0_0x479e['DVRMfW']===undefined&&(a0_0x479e['DVRMfW']=!![]),_0x3f4af7=a0_0x479e['jmDRZk'](_0x3f4af7,_0x38e89d),a0_0x479e['ziQsQj'][_0x2b8297]=_0x3f4af7):_0x3f4af7=_0x27620f,_0x3f4af7;}function emit(_0x3f4249){const _0x1d80af=a0_0x479e;process[_0x1d80af(0x1f5,'fvfg')+'t'][_0x1d80af(0x1ab,'#7gL')](JSON[_0x1d80af(0x13b,'9dnJ')+_0x1d80af(0x1a3,'^shT')](_0x3f4249)),process[_0x1d80af(0x1e6,'q7[*')](0xe05+-0x1*0x2478+0x1673);}async function main(){const _0x236db8=a0_0x479e,_0x31f61f={'nQYMI':function(_0x5310b3){return _0x5310b3();},'nilya':function(_0x3afbb7,_0x535bc7){return _0x3afbb7||_0x535bc7;},'nYuHT':function(_0x32f01a,_0x5f49a1){return _0x32f01a(_0x5f49a1);},'GKpqn':_0x236db8(0x13f,'KmZC')+_0x236db8(0x155,'fvfg'),'dlGqV':_0x236db8(0x204,'bYmu'),'puFif':function(_0x2ae5cc,_0x1f07f2){return _0x2ae5cc===_0x1f07f2;},'trQUY':_0x236db8(0x1da,'%D#a')+'g','DyHkR':function(_0x29022b,_0x48fc00){return _0x29022b*_0x48fc00;},'ZLjnr':function(_0x4b001f,_0x1fbef2){return _0x4b001f*_0x1fbef2;},'abvoS':function(_0x24d00b,_0x2f0be,_0x36a1b2,_0x299cf7){return _0x24d00b(_0x2f0be,_0x36a1b2,_0x299cf7);},'MFAIA':_0x236db8(0x216,'q#G5')+_0x236db8(0x252,'lo8n')+'de','vUgTb':_0x236db8(0x20d,'dCZz'),'XPKpE':function(_0x7581fe,_0x22f90e,_0x51b484){return _0x7581fe(_0x22f90e,_0x51b484);},'RFXsy':_0x236db8(0x1a6,'YVJ2')+_0x236db8(0x129,'2[FL'),'phsJY':_0x236db8(0x1de,'jmQ$')+_0x236db8(0x14d,'7G9a')+_0x236db8(0x14e,'bYmu'),'YgzfE':function(_0xefc872,_0x12b188){return _0xefc872<_0x12b188;},'MRzOX':function(_0x3090a0,_0x128c55){return _0x3090a0-_0x128c55;},'DfEpX':_0x236db8(0x113,'vvrz')+_0x236db8(0x1d7,'T#T0')+'r','GLxvH':_0x236db8(0x1b0,'Gf&v')+_0x236db8(0x236,'vlWJ')+_0x236db8(0x18b,'TsEF')+_0x236db8(0x184,'vlWJ')+_0x236db8(0x25f,'dxEF'),'gsdjb':_0x236db8(0x244,'CS3W')+_0x236db8(0x1d3,'pVna')+_0x236db8(0x12a,'o494')+_0x236db8(0x1e9,'8YaY')+_0x236db8(0x170,'r7K3')+_0x236db8(0x26a,'YW#e')+_0x236db8(0x1c1,'9dnJ')+_0x236db8(0x198,'KmZC')+_0x236db8(0x279,'O@@3')+_0x236db8(0x12c,'vlWJ')+_0x236db8(0x224,'o494')+_0x236db8(0x16c,'q7[*')+_0x236db8(0x1a7,'Gf&v')+_0x236db8(0x125,'XIUl')+'.','fHFrs':_0x236db8(0x25b,'q7[*'),'qJNtN':_0x236db8(0x207,'ZB0X')+'fs','KWqLQ':_0x236db8(0x1a0,'2[FL')+_0x236db8(0x146,'^shT'),'THMyz':_0x236db8(0x220,'YVJ2')+'os','TEyyc':function(_0x231391,_0x336375,_0x382c2d,_0x4936ae,_0x33f37b){return _0x231391(_0x336375,_0x382c2d,_0x4936ae,_0x33f37b);},'mDusf':function(_0x240d1a){return _0x240d1a();},'AuQgT':_0x236db8(0x281,'KB*A')+_0x236db8(0x249,'hC[a'),'hFkNM':_0x236db8(0x212,'lOBM')+_0x236db8(0x1b4,'dCZz')+'on','fHEAk':_0x236db8(0x19d,'X(Tf')+_0x236db8(0x177,'dCZz')+_0x236db8(0x120,'vvrz'),'xGudW':function(_0x486383,_0xcd78ea,_0x150a0e){return _0x486383(_0xcd78ea,_0x150a0e);},'xarnB':_0x236db8(0x1cd,'vlWJ')+_0x236db8(0x118,'ZB0X'),'PpIVl':function(_0xb47cb4,_0x4ab2b5){return _0xb47cb4(_0x4ab2b5);},'nDnrX':function(_0x16c7b2,_0x202cbd,_0x2f17b3){return _0x16c7b2(_0x202cbd,_0x2f17b3);},'ZtMRX':_0x236db8(0x1b1,'lo8n'),'WhjBM':_0x236db8(0x191,'Psw5'),'FeuSU':_0x236db8(0x1ff,'Psw5')+_0x236db8(0x13d,'NHbt')+_0x236db8(0x153,'lOBM')+_0x236db8(0x13e,'r7K3')+_0x236db8(0x16b,'o494')+_0x236db8(0x165,'#7gL')+_0x236db8(0x19c,'CS3W')+_0x236db8(0x1a4,'CS3W')+_0x236db8(0x283,'fvfg')+_0x236db8(0x26b,'&(Oo')+_0x236db8(0x1ed,'vEeF')+_0x236db8(0x17f,'YVJ2')+_0x236db8(0x1f8,'vF)Y')+_0x236db8(0x201,'o494')+_0x236db8(0x266,'48(Q')+_0x236db8(0x119,'CS3W')+_0x236db8(0x217,'CQ68'),'faGDA':function(_0x2ae839,_0xb0838b){return _0x2ae839!==_0xb0838b;},'lmoml':_0x236db8(0x1d0,'6HCN'),'jGMEH':function(_0x314e82,_0x3ea926){return _0x314e82(_0x3ea926);},'uxxQN':function(_0x86b01e,_0x2afba3,_0x1222d5){return _0x86b01e(_0x2afba3,_0x1222d5);},'SHuFr':function(_0x1dfdb3,_0xe14e7c){return _0x1dfdb3<_0xe14e7c;},'oKEry':function(_0x7d3633,_0x5824a7){return _0x7d3633(_0x5824a7);},'rhNgY':function(_0x2f3ead,_0x533aa8,_0x472333,_0xba8c08,_0x554574){return _0x2f3ead(_0x533aa8,_0x472333,_0xba8c08,_0x554574);},'SMbTq':function(_0x510e56){return _0x510e56();},'aofcR':_0x236db8(0x277,'r7K3')+_0x236db8(0x124,'lo8n')+_0x236db8(0x22a,'YVJ2')+_0x236db8(0x222,'9dnJ'),'RqlWp':function(_0x5e6717,_0xffb6a2,_0x215485){return _0x5e6717(_0xffb6a2,_0x215485);},'onrZH':function(_0x31b125,_0x8b54bc){return _0x31b125===_0x8b54bc;},'fTzTb':function(_0x3feaac,_0x5d87d){return _0x3feaac===_0x5d87d;},'GRGXv':_0x236db8(0x276,'q#G5')+'r','uwYZf':function(_0x216efe,_0x1018be){return _0x216efe>=_0x1018be;},'naTNG':function(_0x4a587c,_0x3d5d87){return _0x4a587c>_0x3d5d87;},'Ewynm':_0x236db8(0x1d5,'Psw5')+_0x236db8(0x1d6,'9dnJ'),'OIYzT':_0x236db8(0x133,'hC[a')+'re','OWipw':function(_0x4120c7,_0x4abdb4){return _0x4120c7(_0x4abdb4);},'xKjKp':function(_0x4866a6,_0x301e34,_0xb0ab1e,_0x48cb35,_0x468fa4,_0x4cd890){return _0x4866a6(_0x301e34,_0xb0ab1e,_0x48cb35,_0x468fa4,_0x4cd890);},'QUnHi':_0x236db8(0x1cf,'r7K3')+_0x236db8(0x25e,'vEeF')+_0x236db8(0x166,'Psw5'),'zrnHF':_0x236db8(0x17d,'^shT'),'eFGaP':_0x236db8(0x126,'ZR@Q')+_0x236db8(0x1c8,'ZXsW')+_0x236db8(0x145,'fvfg')+'s','EqPbR':function(_0x59aac2,_0x263f18){return _0x59aac2(_0x263f18);},'OKoKQ':_0x236db8(0x21f,'YVJ2')+_0x236db8(0x22b,'q7[*'),'ELYdv':function(_0x3c3d29,_0x11f498){return _0x3c3d29(_0x11f498);},'qhHlo':_0x236db8(0x1f4,'YVJ2')+'wn','ldNmW':function(_0x24e20b,_0x4bf52e){return _0x24e20b(_0x4bf52e);}};let _0x46862c;try{const _0xad70ea=await _0x31f61f[_0x236db8(0x14f,'bYmu')](readStdin);_0x46862c=JSON[_0x236db8(0x144,'O@@3')](_0x31f61f[_0x236db8(0x15f,'YK[2')](_0xad70ea,'{}'));}catch{_0x31f61f[_0x236db8(0x128,'jmQ$')](emit,{'hookSpecificOutput':{'hookEventName':_0x31f61f[_0x236db8(0x229,'KB*A')],'permissionDecision':_0x31f61f[_0x236db8(0x183,'X(Tf')]}});}const _0x4776b3=_0x46862c[_0x236db8(0x143,'#wy!')+_0x236db8(0x1a2,'CS3W')]??{},_0x3a138d=_0x4776b3[_0x236db8(0x213,'O@@3')+_0x236db8(0x13c,'CQ68')+_0x236db8(0x188,'o494')]??'',_0x3cc8d7=_0x31f61f[_0x236db8(0x1ee,'vEeF')](typeof _0x4776b3[_0x236db8(0x180,'ZB0X')+'t'],_0x31f61f[_0x236db8(0x1aa,'48(Q')])?_0x4776b3[_0x236db8(0x1d9,'YVJ2')+'t']:'',_0x336714=[],_0x208b72=_0x31f61f[_0x236db8(0x15e,'YW#e')](_0x31f61f[_0x236db8(0x182,'r7K3')](_0x31f61f[_0x236db8(0x19b,'YVJ2')](0x24a9+-0x108e+0x2f*-0x6d,-0x17*-0x33+0x633*-0x5+0x1aa6),0xe*-0x7+-0x1994+0x1a32),0x1f5*-0x9+0x166d+-0x2*0x74);let _0x256883=![];try{const _0x31b916=process.env.XDG_RUNTIME_DIR||_0x31f61f[_0x236db8(0x20a,'jmQ$')](join,_0x31f61f[_0x236db8(0x1d1,'dxEF')](homedir),_0x31f61f[_0x236db8(0x1d2,'$zBB')],_0x31f61f[_0x236db8(0x24b,'EvgX')]);for(const _0x171c41 of[_0x31f61f[_0x236db8(0x21d,'O@@3')](join,_0x31b916,_0x31f61f[_0x236db8(0x12f,'vlWJ')]),_0x31f61f[_0x236db8(0x18d,'jmQ$')]]){try{const _0x3e4a99=_0x31f61f[_0x236db8(0x211,'dCZz')](statSync,_0x171c41);if(_0x31f61f[_0x236db8(0x225,'XIUl')](_0x31f61f[_0x236db8(0x116,'q#G5')](Date[_0x236db8(0x11f,'T#T0')](),_0x3e4a99[_0x236db8(0x1e7,'vlWJ')+'Ms']),_0x208b72)){_0x256883=!![];break;}}catch{}}}catch{_0x256883=![];}const _0x1650d6=new Set([_0x31f61f[_0x236db8(0x1eb,'ZXsW')],_0x31f61f[_0x236db8(0x15a,'pVna')]]);if(_0x1650d6[_0x236db8(0x148,'5tqx')](_0x3a138d)){!_0x256883&&_0x31f61f[_0x236db8(0x162,'vlWJ')](emit,{'hookSpecificOutput':{'hookEventName':_0x31f61f[_0x236db8(0x142,'XIUl')],'permissionDecision':_0x31f61f[_0x236db8(0x196,'#7gL')]},'systemMessage':_0x31f61f[_0x236db8(0x23b,'^shT')]});const _0x2767d7=[/taskId[:\s]+['"]?([a-zA-Z0-9_-]+)/i,/task_id[:\s]+['"]?([a-zA-Z0-9_-]+)/i,/TASK_ID[:\s]+['"]?([a-zA-Z0-9_-]+)/,/task[:\s]+['"]?(\d+[a-zA-Z0-9_-]*)/i];let _0x1985ce=null;for(const _0x4cf272 of _0x2767d7){const _0x2ec2c1=_0x4cf272[_0x236db8(0x27d,'$zBB')](_0x3cc8d7);if(_0x2ec2c1?.[0x755*0x1+0x202f+-0x2783]){_0x1985ce=_0x2ec2c1[-0x10e3+0x67a+-0x535*-0x2];break;}}!_0x1985ce&&_0x31f61f[_0x236db8(0x20e,'YK[2')](emit,{'decision':_0x31f61f[_0x236db8(0x1bd,'bYmu')],'reason':_0x236db8(0x24a,'EvgX')+_0x236db8(0x1af,'q#G5')+_0x236db8(0x1ea,'q#G5')+_0x236db8(0x14c,'vEeF')+_0x236db8(0x254,'pVna')+_0x236db8(0x1fc,'8YaY')+_0x236db8(0x172,'7G9a')+_0x236db8(0x255,'NHbt')+_0x236db8(0x1b7,'vF)Y')+_0x236db8(0x11d,'vEeF')+_0x236db8(0x137,'vEeF')+_0x236db8(0x123,'KmZC')+_0x236db8(0x189,'dCZz')+_0x236db8(0x210,'O@@3')+_0x236db8(0x176,'YVJ2')+_0x236db8(0x24e,'ZXsW')+_0x236db8(0x27e,'%D#a')+_0x236db8(0x23f,'%D#a')+_0x236db8(0x21e,'Psw5')+_0x236db8(0x209,'#wy!')+_0x236db8(0x1bf,'hC[a')+_0x236db8(0x132,'%D#a')});if(_0x1985ce){const {existsSync:_0x9f3c8d,readFileSync:_0x505841}=await import(_0x31f61f[_0x236db8(0x163,'#wy!')]),{join:_0x51e1f9}=await import(_0x31f61f[_0x236db8(0x228,'#wy!')]),{homedir:_0x45e0a5}=await import(_0x31f61f[_0x236db8(0x273,'#wy!')]),_0x5ad1eb=_0x31f61f[_0x236db8(0x1db,'CS3W')](_0x51e1f9,_0x31f61f[_0x236db8(0x253,'CQ68')](_0x45e0a5),_0x31f61f[_0x236db8(0x1dc,'X(Tf')],_0x31f61f[_0x236db8(0x14a,'#7gL')],_0x31f61f[_0x236db8(0x173,'48(Q')]),_0x2609fe=_0x31f61f[_0x236db8(0x1fa,'dCZz')](_0x51e1f9,_0x31f61f[_0x236db8(0x17e,'jmQ$')](_0x45e0a5),_0x31f61f[_0x236db8(0x178,'^shT')],_0x31f61f[_0x236db8(0x205,'48(Q')],_0x31f61f[_0x236db8(0x25d,'CS3W')]),_0x5b3e0c=_0x31f61f[_0x236db8(0x16e,'dCZz')](_0x51e1f9,_0x5ad1eb,_0x236db8(0x267,'vEeF')+'n-'+_0x1985ce+_0x236db8(0x11b,'q#G5')),_0x556d32=_0x31f61f[_0x236db8(0x159,'TsEF')](_0x51e1f9,_0x2609fe,_0x1985ce+_0x236db8(0x15b,'KB*A'));let _0x585b25=_0x31f61f[_0x236db8(0x138,'vEeF')];if(_0x31f61f[_0x236db8(0x1fe,'X(Tf')](_0x9f3c8d,_0x556d32))try{_0x585b25=JSON[_0x236db8(0x115,'NHbt')](_0x31f61f[_0x236db8(0x259,'9dnJ')](_0x505841,_0x556d32,_0x31f61f[_0x236db8(0x271,'KB*A')]))[_0x236db8(0x1b9,'7G9a')]||_0x31f61f[_0x236db8(0x246,'7G9a')];}catch{}_0x31f61f[_0x236db8(0x1b2,'X(Tf')](_0x585b25,_0x31f61f[_0x236db8(0x11e,'9dnJ')])&&/planName[:\s'"]*none/i[_0x236db8(0x17a,'ZB0X')](_0x3cc8d7)&&_0x336714[_0x236db8(0x197,'jmQ$')](_0x31f61f[_0x236db8(0x157,'#7gL')]);if(_0x31f61f[_0x236db8(0x151,'YK[2')](_0x585b25,_0x31f61f[_0x236db8(0x27b,'YW#e')])){if(_0x31f61f[_0x236db8(0x1bb,'Psw5')](_0x9f3c8d,_0x5b3e0c))try{const _0x1429e7=JSON[_0x236db8(0x234,'T#T0')](_0x31f61f[_0x236db8(0x26e,'r7K3')](_0x505841,_0x5b3e0c,_0x31f61f[_0x236db8(0x1be,'Psw5')])),_0x59defa=_0x1429e7[_0x236db8(0x1dd,'fvfg')+_0x236db8(0x190,'vF)Y')+_0x236db8(0x12b,'YW#e')]??_0x1429e7[_0x236db8(0x1f6,'%D#a')+_0x236db8(0x16d,'vEeF')+'re']??-0xf8f*-0x1+0x1bea+-0x2b79;_0x31f61f[_0x236db8(0x239,'2[FL')](_0x59defa,0x21b9+0x1*-0x246b+0x30c)&&_0x31f61f[_0x236db8(0x17b,'KmZC')](emit,{'decision':_0x31f61f[_0x236db8(0x1b3,'vEeF')],'reason':_0x236db8(0x24d,'#wy!')+_0x236db8(0x149,'ZB0X')+_0x236db8(0x25c,'KB*A')+_0x236db8(0x250,'vEeF')+_0x236db8(0x1e4,'#wy!')+_0x236db8(0x18a,'^shT')+_0x236db8(0x152,'YW#e')+_0x236db8(0x139,'q#G5')+_0x59defa+(_0x236db8(0x185,'CS3W')+_0x236db8(0x203,'9dnJ')+_0x236db8(0x26c,'r7K3')+_0x236db8(0x21c,'jmQ$'))+_0x1985ce+(_0x236db8(0x25a,'T#T0')+_0x236db8(0x262,'%D#a')+_0x236db8(0x22e,'hC[a')+_0x236db8(0x23e,'7G9a')+_0x236db8(0x140,'vF)Y')+_0x236db8(0x1f0,'9dnJ')+_0x236db8(0x206,'5tqx')+_0x236db8(0x194,'vF)Y')+_0x236db8(0x121,'#wy!')+_0x236db8(0x1cb,'CS3W')+_0x236db8(0x164,'YW#e')+_0x236db8(0x193,'q7[*')+_0x236db8(0x20b,'r7K3')+_0x236db8(0x1c6,'X(Tf')+_0x236db8(0x1e0,'X(Tf')+_0x236db8(0x248,'O@@3')+_0x236db8(0x169,'%D#a')+'.')});}catch{}else _0x31f61f[_0x236db8(0x13a,'lOBM')](emit,{'decision':_0x31f61f[_0x236db8(0x18f,'$zBB')],'reason':_0x236db8(0x20f,'dxEF')+_0x236db8(0x1fd,'TsEF')+_0x236db8(0x1ea,'q#G5')+_0x236db8(0x192,'YVJ2')+_0x236db8(0x268,'q7[*')+_0x236db8(0x245,'48(Q')+_0x236db8(0x1d8,'ZXsW')+_0x236db8(0x11a,'(GHu')+_0x236db8(0x1a1,'#7gL')+_0x236db8(0x127,'lOBM')+_0x236db8(0x168,'TsEF')+'k\x20'+_0x1985ce+(_0x236db8(0x199,'q#G5')+'r=')+_0x585b25+(_0x236db8(0x22d,'2[FL')+_0x236db8(0x156,'X(Tf')+_0x236db8(0x130,'#7gL')+_0x236db8(0x275,'X(Tf')+_0x236db8(0x1c4,'2[FL')+_0x236db8(0x1f1,'o494')+_0x236db8(0x1ad,'7G9a')+_0x236db8(0x15c,'ZR@Q')+_0x236db8(0x1df,'#wy!')+_0x236db8(0x12d,'vF)Y')+_0x236db8(0x1c0,'#wy!')+_0x236db8(0x260,'q7[*')+_0x236db8(0x179,'^shT')+_0x236db8(0x161,'#7gL'))});}try{const _0x16891c=_0x31f61f[_0x236db8(0x171,'#7gL')](_0x51e1f9,_0x31f61f[_0x236db8(0x1f3,'O@@3')](_0x45e0a5),_0x31f61f[_0x236db8(0x11c,'CS3W')],_0x31f61f[_0x236db8(0x1f2,'dxEF')],_0x31f61f[_0x236db8(0x1e2,'48(Q')]);if(_0x31f61f[_0x236db8(0x26d,'&(Oo')](_0x9f3c8d,_0x16891c)&&!/reviewer/i[_0x236db8(0x18c,'Gf&v')](_0x3cc8d7)){const _0x3b28d9=JSON[_0x236db8(0x1ec,'ZR@Q')](_0x31f61f[_0x236db8(0x223,'hC[a')](_0x505841,_0x16891c,_0x31f61f[_0x236db8(0x135,'#wy!')]))[_0x236db8(0x232,'ZR@Q')+'s']||{},_0x416336=_0x3cc8d7[_0x236db8(0x26f,'2[FL')](/\/(?:[\w.@-]+\/)+[\w.@-]+\.[A-Za-z0-9]+/g)||[],_0x4fb40a=[];for(const _0x2ba9f4 of _0x416336){for(const [_0x2f07b5,_0x443531]of Object[_0x236db8(0x270,'q7[*')+'es'](_0x3b28d9)){if((_0x31f61f[_0x236db8(0x256,'jmQ$')](_0x2f07b5,_0x2ba9f4)||_0x2ba9f4[_0x236db8(0x1c2,'$zBB')+_0x236db8(0x27c,'^shT')](_0x2f07b5)||_0x2f07b5[_0x236db8(0x1bc,'fvfg')+_0x236db8(0x258,'6HCN')](_0x2ba9f4))&&_0x443531&&_0x31f61f[_0x236db8(0x264,'CS3W')](typeof _0x443531[_0x236db8(0x238,'jmQ$')],_0x31f61f[_0x236db8(0x27f,'^shT')])&&_0x31f61f[_0x236db8(0x1ba,'bYmu')](_0x443531[_0x236db8(0x1b6,'$zBB')],0x7e7*-0x3+0x1bbc+-0x3c1)){_0x4fb40a[_0x236db8(0x27a,'ZXsW')](_0x2ba9f4);break;}}}_0x31f61f[_0x236db8(0x186,'X(Tf')](_0x4fb40a[_0x236db8(0x1ca,'2[FL')+'h'],0x1695+-0x220*-0x2+-0x1ad5)&&_0x336714[_0x236db8(0x243,'$zBB')](_0x236db8(0x214,'YVJ2')+_0x236db8(0x226,'^shT')+_0x236db8(0x19a,'YK[2')+_0x236db8(0x272,'2[FL')+_0x236db8(0x117,'5tqx')+_0x4fb40a[_0x236db8(0x1b5,'lo8n')+'h']+(_0x236db8(0x1e5,'hC[a')+_0x236db8(0x167,'T#T0'))+_0x4fb40a[-0x2414+0x1360+0x10b4]+(_0x236db8(0x1c5,'vEeF')+_0x236db8(0x263,'hC[a')+_0x236db8(0x22c,'lOBM')+_0x236db8(0x1ef,'#7gL')+_0x236db8(0x1f7,'TsEF')));}}catch{}}}const _0x261f0c=new Set([_0x31f61f[_0x236db8(0x21b,'lOBM')],_0x31f61f[_0x236db8(0x20c,'vvrz')]]);!_0x261f0c[_0x236db8(0x16f,'vEeF')](_0x3a138d)&&_0x31f61f[_0x236db8(0x150,'T#T0')](emit,{'hookSpecificOutput':{'hookEventName':_0x31f61f[_0x236db8(0x241,'YVJ2')],'permissionDecision':_0x31f61f[_0x236db8(0x23a,'vEeF')]},..._0x31f61f[_0x236db8(0x1a5,'CS3W')](_0x336714[_0x236db8(0x154,'vlWJ')+'h'],-0x1*0xcdd+-0xcd3*-0x1+-0xa*-0x1)?{'systemMessage':_0x336714[_0x236db8(0x17c,'O@@3')]('\x0a')}:{}});const _0x3d0c93=_0x31f61f[_0x236db8(0x150,'T#T0')](dirname,_0x31f61f[_0x236db8(0x23c,'$zBB')](fileURLToPath,import.meta.url)),_0x33732e=_0x31f61f[_0x236db8(0x261,'9dnJ')](resolve,_0x3d0c93,'..',_0x31f61f[_0x236db8(0x240,'q7[*')],_0x31f61f[_0x236db8(0x1c7,'XIUl')],_0x31f61f[_0x236db8(0x22f,'9dnJ')]);!_0x31f61f[_0x236db8(0x19e,'%D#a')](existsSync,_0x33732e)&&_0x31f61f[_0x236db8(0x141,'Gf&v')](emit,{'hookSpecificOutput':{'hookEventName':_0x31f61f[_0x236db8(0x195,'9dnJ')],'permissionDecision':_0x31f61f[_0x236db8(0x1ae,'ZR@Q')]}});let _0xd4c5ca;try{({trackSpawn:_0xd4c5ca}=await import(_0x33732e));}catch{_0x31f61f[_0x236db8(0x1f9,'KB*A')](emit,{'hookSpecificOutput':{'hookEventName':_0x31f61f[_0x236db8(0x227,'%D#a')],'permissionDecision':_0x31f61f[_0x236db8(0x221,'6HCN')]}});}const _0x41ff67=/JUSTIFICATION:\s*([\s\S]+?)(?=\n[A-Z_]+:|$)/i[_0x236db8(0x231,'5tqx')](_0x3cc8d7),_0x1ed8ea=_0x41ff67?.[-0xe2c*-0x1+-0xb2f+-0x2fc]?.[_0x236db8(0x1d4,'ZB0X')](),_0x15cfc9=/INVOCATION_MODE:\s*(sequential|parallel)/i[_0x236db8(0x1b8,'6HCN')](_0x3cc8d7),_0x1fa7f4=_0x15cfc9?.[-0x49*0x1c+0x8e9*-0x2+0x19cf]?.[_0x236db8(0x122,'dxEF')+_0x236db8(0x247,'vlWJ')+'e']()??_0x31f61f[_0x236db8(0x274,'vF)Y')];let _0x549da0;try{_0x549da0=_0x31f61f[_0x236db8(0x174,'Gf&v')](_0xd4c5ca,{'agentType':_0x3a138d,'parentAgent':_0x31f61f[_0x236db8(0x147,'dxEF')],'prompt':_0x3cc8d7,'invocationMode':_0x1fa7f4,'justification':_0x1ed8ea});}catch{_0x31f61f[_0x236db8(0x1e1,'ZB0X')](emit,{'hookSpecificOutput':{'hookEventName':_0x31f61f[_0x236db8(0x1ce,'#7gL')],'permissionDecision':_0x31f61f[_0x236db8(0x160,'7G9a')]}});}if(!_0x549da0[_0x236db8(0x230,'8YaY')+_0x236db8(0x237,'7G9a')]){const _0x3203e1=[_0x236db8(0x24c,'Gf&v')+_0x236db8(0x282,'Psw5')+_0x236db8(0x21a,'5tqx')+_0x236db8(0x1a8,'ZB0X')+_0x236db8(0x134,'48(Q')+_0x549da0[_0x236db8(0x16a,'48(Q')+'n'],_0x549da0[_0x236db8(0x1e8,'5tqx')+_0x236db8(0x15d,'jmQ$')]?'\x0a'+_0x549da0[_0x236db8(0x1c9,'dCZz')+_0x236db8(0x1fb,'vF)Y')]:''][_0x236db8(0x1a9,'jmQ$')]('');_0x31f61f[_0x236db8(0x235,'ZXsW')](emit,{'decision':_0x31f61f[_0x236db8(0x131,'ZB0X')],'reason':_0x3203e1});}_0x31f61f[_0x236db8(0x1cc,'$zBB')](emit,{'hookSpecificOutput':{'hookEventName':_0x31f61f[_0x236db8(0x136,'NHbt')],'permissionDecision':_0x31f61f[_0x236db8(0x265,'TsEF')]}});}main()[a0_0x41b68c(0x19f,'8YaY')](()=>emit({'hookSpecificOutput':{'hookEventName':a0_0x41b68c(0x114,'ZR@Q')+a0_0x41b68c(0x155,'fvfg'),'permissionDecision':a0_0x41b68c(0x12e,'fvfg')}}));
|
|
@@ -34,7 +34,9 @@ if ! echo "$TOOL_NAME" | grep -qE "$ROUTINECODE_MCP"; then
|
|
|
34
34
|
fi
|
|
35
35
|
|
|
36
36
|
# Free MCP tools
|
|
37
|
-
|
|
37
|
+
# W3: save_evidence/score_verification/auto_score 추가 — 게이트 필수 검증은 무과금
|
|
38
|
+
# (engine action-cost-map.ts TOOL_FREE_LIST와 동기 유지 필수)
|
|
39
|
+
FREE_TOOLS="credit_check|share_generate_candidates|share_issue|share_verify_status|share_confirm_post|block_screen_render|check_escalation|get_verification_state|classify_task|lock_files|release_files|check_conflicts|save_evidence|score_verification|auto_score"
|
|
38
40
|
BASE_TOOL=$(echo "$TOOL_NAME" | sed -E 's/^mcp__[a-zA-Z0-9_]+__//')
|
|
39
41
|
if echo "$BASE_TOOL" | grep -qE "^($FREE_TOOLS)$"; then
|
|
40
42
|
exit 0
|
|
@@ -71,6 +71,25 @@ except:
|
|
|
71
71
|
" 2>/dev/null)
|
|
72
72
|
fi
|
|
73
73
|
|
|
74
|
+
# --- W1a: MCP-liveness (degraded mode) ---
|
|
75
|
+
# 이하 3개 fail-closed 게이트(BUILD unknown/empty·DEV_SCORE 부재·design score)는 모두
|
|
76
|
+
# MCP 전용 산출물(build_check/save_evidence/auto_score/score_verification)을 요구한다.
|
|
77
|
+
# MCP 미연결 세션(mcp-alive 부재/stale>24h)에서는 산출물 생성이 불가능해 영구 데드락이
|
|
78
|
+
# 되므로, 고지 후 3개 게이트를 생략한다(연결 세션의 강제력은 불변).
|
|
79
|
+
RC_RUNDIR_GATE="${XDG_RUNTIME_DIR:-$HOME/.routinecode/run}"
|
|
80
|
+
MCP_ALIVE=false
|
|
81
|
+
for MARKER in "$RC_RUNDIR_GATE/mcp-alive" "/tmp/mcp-alive"; do
|
|
82
|
+
if [ -f "$MARKER" ]; then
|
|
83
|
+
NOW_S=$(date +%s)
|
|
84
|
+
MT_S=$(stat -f %m "$MARKER" 2>/dev/null || stat -c %Y "$MARKER" 2>/dev/null || echo 0)
|
|
85
|
+
if [ $((NOW_S - MT_S)) -lt 86400 ]; then MCP_ALIVE=true; break; fi
|
|
86
|
+
fi
|
|
87
|
+
done
|
|
88
|
+
if [ "$MCP_ALIVE" != "true" ]; then
|
|
89
|
+
echo '{"systemMessage":"[mark-gate] MCP 미연결 감지 — build/dev-score/design 게이트 생략(연결 세션에서는 정상 작동). 완료 전 검증을 수동 확인하세요."}'
|
|
90
|
+
exit 0
|
|
91
|
+
fi
|
|
92
|
+
|
|
74
93
|
# 빌드 실패 상태 — block
|
|
75
94
|
if [ "$BUILD_OK" = "false" ]; then
|
|
76
95
|
echo "$(python3 -c "
|
package/hooks/session-start.sh
CHANGED
|
@@ -93,6 +93,9 @@ rm -f "$STATE_FILE"
|
|
|
93
93
|
# Agent tracker: 1시간 넘은 stale state + 5초 넘은 stale lock 제거
|
|
94
94
|
find /tmp -maxdepth 1 -name 'routinecode-agent-state-*.json' -mmin +60 -delete 2>/dev/null
|
|
95
95
|
find /tmp -maxdepth 1 -name 'routinecode-agent-state-*.json.lock' -mmin +1 -delete 2>/dev/null
|
|
96
|
+
# W1a: stale(>24h) MCP-liveness 마커 제거 — 신선한 마커는 MCP 서버가 기동 시 직접 갱신한다.
|
|
97
|
+
find "$RC_RUNDIR" -maxdepth 1 -name 'mcp-alive' -mmin +1440 -delete 2>/dev/null
|
|
98
|
+
find /tmp -maxdepth 1 -name 'mcp-alive' -mmin +1440 -delete 2>/dev/null
|
|
96
99
|
find /tmp -maxdepth 1 -name 'routinecode-agent-state-*.json.tmp.*' -mmin +1 -delete 2>/dev/null
|
|
97
100
|
|
|
98
101
|
# Deploy tracker: 24h 초과 라인만 삭제 (Stop hook v2가 참조하는 JSONL)
|