{ "auth": { "login": { "agree": "《사용 시 유의사항》을 읽고 동의합니다", "checking": "로그인 상태를 확인하는 중입니다…", "errorAgree": "먼저 《사용 시 유의사항》을 읽고 동의해 주세요", "errorBackend": "백엔드 서비스에 연결할 수 없습니다", "errorCredential": "사용자 이름 또는 비밀번호가 올바르지 않습니다", "password": "비밀번호", "passwordPlaceholder": "비밀번호를 입력해 주세요", "submit": "로그인", "submitting": "로그인 중…", "title": "로그인", "username": "사용자 이름", "welcome": "다시 오신 것을 환영합니다. 비밀번호를 입력하면 ARTEX 를 계속 사용할 수 있습니다." }, "setup": { "confirmPassword": "비밀번호 확인", "confirmPlaceholder": "비밀번호를 다시 입력해 주세요", "desc": "ARTEX 를 처음 사용합니다. 계정에 로그인 비밀번호를 설정해 주세요(8자 이상).", "errorBackend": "백엔드 서비스에 연결할 수 없습니다", "errorInit": "초기화에 실패했습니다", "errorMismatch": "두 번 입력한 비밀번호가 일치하지 않습니다", "errorTooShort": "비밀번호는 최소 8자 이상이어야 합니다", "newPassword": "새 비밀번호", "newPasswordPlaceholder": "8자 이상", "submit": "비밀번호 설정 후 로그인", "submitting": "저장 중…", "title": "비밀번호 초기화" }, "terms": { "a1Body": "본 소프트웨어(ARTEX)는 GNU Affero General Public License v3.0(AGPL-3.0)에 따라 배포되는 오픈소스 프로그램입니다. 귀하는 이 라이선스에 따라 본 소프트웨어를 자유롭게 사용·복제·수정·배포할 수 있습니다. 다만 모든 2차적 저작물(네트워크를 통해 제3자에게 제공하는 온라인 서비스를 포함합니다)도 동일하게 AGPL-3.0 으로 공개하고 이용자에게 그에 해당하는 완전한 소스 코드를 공개해야 합니다. AGPL-3.0 의 전체 조항은 함께 배포되는 LICENSE 파일을 따릅니다.", "a1Title": "제1조 · 정의와 오픈소스 라이선스", "a2Body": "본 소프트웨어는 개인 학습, 코드 연구, 보안 기술 원리의 탐구, 그리고 귀하가 직접 구축한 로컬 격리 환경에서의 기술 검증 용도로만 제공되며, 학습·학술 연구·코드 검토와 같은 비공격적·비파괴적 용도에 적합합니다. 본 조에서 명시적으로 허가한 경우를 제외하고, 귀하는 본 소프트웨어를 그 밖의 어떤 목적으로도 사용해서는 안 됩니다.", "a2Title": "제2조 · 허가 사용 범위", "a3Item1": "어떤 웹사이트, 온라인 서비스, 타인 또는 제3자가 소유한 네트워크 연결 시스템에 대해서도 스캐닝·탐지·익스플로잇·공격을 수행하는 행위를 엄격히 금지합니다(허가 여부나 귀하 소유 자산인지 여부와 무관합니다).", "a3Item2": "본 소프트웨어를 실제 침투 테스트, 공방 훈련, 레드블루 훈련, 운영 환경에 사용하는 행위를 엄격히 금지합니다.", "a3Item3": "본 소프트웨어를 불법 침입, 데이터 탈취, 금전 갈취, 서비스 거부(DoS/DDoS), 그 밖의 파괴적·범죄적 활동에 사용하는 행위를 엄격히 금지합니다.", "a3Item4": "본 소프트웨어 및 그 산출물에 포함된 저작권·라이선스·보안 고지 정보를 제거·변조·우회하는 행위를 엄격히 금지합니다.", "a3Item5": "귀하가 속한 국가·지역의 법률·법규 및 규제를 위반하는 일체의 행위를 엄격히 금지합니다.", "a3Title": "제3조 · 금지 행위", "a4Body": "본 소프트웨어의 저작권과 관련 지식재산권은 프로젝트의 작성자 및 기여자에게 귀속되며, AGPL-3.0 라이선스가 정한 범위 안에서 귀하에게 해당 권리를 부여합니다. 해당 라이선스가 명시적으로 부여한 권리를 제외하고, 본 고지는 명시적이든 묵시적이든 귀하에게 그 밖의 어떤 권리도 부여하지 않습니다.", "a4Title": "제4조 · 지식재산권", "a5Body": "본 소프트웨어는 귀하가 직접 배포할 수 있는 오픈소스 프로그램으로, 작성자는 어떤 중앙 집중식 서비스도 운영하지 않으며 귀하의 사용 데이터를 수집하거나 업로드하지 않습니다. 귀하가 사용 과정에서 생성·처리·접근하는 모든 데이터는 귀하가 직접 관리하며 그 적법성과 안전성에 대한 책임도 귀하에게 있습니다. 데이터를 부적절하게 처리하여 발생하는 모든 결과는 귀하가 부담합니다.", "a5Title": "제5조 · 데이터와 개인정보", "a6Body": "귀하는 네트워크 보안, 데이터 보안과 개인정보 보호, 컴퓨터 범죄 등에 관하여 귀하가 속한 국가·지역의 모든 법률과 법규를 스스로 준수해야 합니다(대한민국의 경우 「정보통신망 이용촉진 및 정보보호 등에 관한 법률」·「개인정보 보호법」 등을 포함하되 이에 한정되지 않습니다).", "a6Emphasis": "귀하가 위 법률·법규나 본 고지의 약정을 위반하여 발생하는 모든 법적 책임과 결과는 귀하 본인이 단독으로 부담하며, 본 소프트웨어의 작성자 및 기여자와는 무관합니다.", "a6Title": "제6조 · 준법과 법적 책임", "a7Body": "본 소프트웨어는 \"있는 그대로(AS IS)\"와 \"가용한 상태 그대로(AS AVAILABLE)\" 제공되며, 상품성, 특정 목적에의 적합성, 정확성, 비침해에 대한 보증을 포함하여 명시적이든 묵시적이든 어떠한 보증도 하지 않습니다. 적용 법률이 허용하는 최대 범위에서, 본 소프트웨어의 작성자 및 기여자는 본 소프트웨어의 사용 또는 사용 불능(사용 방식의 적절성과 무관합니다)으로 발생하는 직접·간접·부수적·특별·결과적 손해에 대해 책임을 지지 않으며, 여기에는 데이터 손실, 시스템 손상, 업무 중단, 이익 손실, 법적 분쟁이 포함되되 이에 한정되지 않습니다.", "a7Title": "제7조 · 면책 고지와 책임 제한", "a8Body": "작성자는 법률·법규나 프로젝트의 발전 필요에 따라 본 고지를 수시로 갱신할 수 있으며, 갱신된 판본은 프로젝트와 함께 배포되어 공표일부터 효력을 가집니다. 귀하가 본 소프트웨어를 계속 사용하면 개정된 조항을 수락한 것으로 간주합니다. 법률이 허용하는 범위에서 본 고지의 최종 해석 권한은 프로젝트 작성자에게 있습니다. 본 고지의 어느 한 조항이 무효로 판정되더라도 나머지 조항의 효력에는 영향을 미치지 않습니다.", "a8Title": "제8조 · 조항 변경과 최종 해석", "agreeButton": "모든 조항을 읽고 동의합니다", "footerNotRead": "조항을 끝까지 스크롤한 뒤 확인해 주세요", "footerRead": "모든 조항을 확인하셨습니다", "intro": "이 《사용 시 유의사항 및 면책 고지》(이하 \"본 고지\")는 귀하와 ARTEX 프로젝트의 작성자 및 기여자 사이에 본 소프트웨어의 사용에 관하여 맺는 약정입니다. 사용하기 전에 각 조항의 내용을 신중히 읽고 충분히 이해해 주시기 바라며, 특히 굵은 글씨나 색상 블록으로 표시된 면책·책임 제한·금지 조항에 유의해 주십시오.", "introEmphasis": "귀하가 본 소프트웨어를 내려받거나 설치·접속하거나 어떤 방식으로든 사용하는 즉시, 본 고지의 모든 내용을 읽고 이해했으며 그 전부에 동의하여 구속받는 것으로 간주합니다.", "meta": "버전 v1.0 · 시행일 2026-09-18 · 로그인하기 전에 아래 모든 조항을 끝까지 읽어 주세요", "title": "ARTEX 사용 시 유의사항 및 면책 고지" } }, "dashboard": { "activeModel": "활성 모델", "activeTasks": "활성 작업", "activityStream": "활동 흐름", "ago": "{value} 전", "all": "전체", "assetDistribution": "자산 분포", "assetNodes": "자산 노드", "assetType": { "app": "앱", "endpoint": "엔드포인트", "ip": "IP", "root_domain": "루트 도메인", "service": "서비스", "subdomain": "서브도메인" }, "byType": "유형별", "cacheHit": "캐시 적중", "cacheHitRate": "캐시 적중률", "captureOff": "캡처 꺼짐", "chartCacheRead": "캐시 읽기", "chartInput": "입력", "chartOutput": "출력", "colEngine": "엔진", "colGoalProgress": "목표 진행도", "colInFlight": "처리 중", "colLastActivity": "최근 활동", "colStatus": "상태", "colTask": "작업", "confirmedFindings": "확인된 취약점", "configured": "설정됨", "crossTaskShared": "작업 간 공유", "default": "기본", "eventCount": "{count}건 이벤트", "findings": "취약점", "inputUncached": "입력(미적중)", "llmConfig": "LLM 설정", "morePending": "외 {count}건…", "noActivity": "활동 기록 없음", "noAssetData": "자산 데이터 없음", "noData": "데이터 없음", "noFindings": "취약점 없음", "noPendingIntercepts": "승인 대기 중인 가로채기 없음", "noTasks": "작업 없음", "noTrafficData": "트래픽 데이터 없음", "notConfigured": "미설정", "off": "꺼짐", "on": "켜짐", "output": "출력", "pendingApprovals": "승인 대기 ({count})", "range7": "7일", "range30": "30일", "range90": "3개월", "range180": "6개월", "range365": "1년", "recentRequests": "최근 요청", "recording": "기록 중", "requestCount": "{count}회 요청", "srcNew": "계량 원장", "srcOld": "활동 통계", "statDone": "완료", "statExplore": "탐색", "statPaused": "일시정지", "statTokenDetail": "입력 {input}(캐시 {cache} 포함) · 출력 {output}", "subtitle": "시스템 전역 상태 · 실시간 갱신", "systemStatus": "시스템 상태", "taskCount": "{count}개 작업", "tasks": "작업", "title": "전체 개요", "tokenConsumption": "LLM Token 소비", "tokenUsage": "Token 사용량", "tooltipNew": "신버전: llm_usage 계량 원장에서 가져와 호출마다 정확하고 중단된 소비까지 포함합니다. 기능을 켠 이후의 데이터만 집계합니다.", "tooltipOld": "구버전: activity 통계에서 가져와 과거 작업까지 포함하지만, 중단된 소비는 빠지고 모델 단위까지 정확하지는 않습니다.", "totalInOut": "합계 (입력+출력)", "totalNodes": "총 {count}개 노드", "trafficCapture": "트래픽 캡처", "trafficExchanges": "트래픽 교환", "trafficStatusCodes": "트래픽 상태 코드", "verNew": "신버전", "verOld": "구버전", "viewTasks": "작업 보기" }, "header": { "updateBadge": "새 버전 {latest}", "updateBadgeShort": "새 버전", "updateTitle": "새 버전 {latest} 발견. 클릭하면 업데이트로 이동합니다.", "version": "버전 · {version}" }, "nav": { "group": { "function": "기능", "system": "시스템" }, "item": { "agents": "에이전트", "approvals": "승인 기록", "asset-intercept": "자산 차단", "assets": "자산", "chat": "대화", "commands": "도구 실행", "dashboard": "대시보드", "findings": "취약점", "intercept": "가로채기 규칙", "llm": "LLM", "llm-records": "LLM 기록", "logs": "로그", "mcp": "MCP", "notify": "알림 발송", "settings": "시스템 설정", "skills": "스킬", "sync": "자산 동기화", "tasks": "작업", "tools": "도구", "traffic": "트래픽", "workspace": "작업 공간" } }, "notFound": { "back": "홈으로 돌아가기", "description": "찾으시는 페이지가 존재하지 않습니다.", "title": "페이지를 찾을 수 없습니다." }, "search": { "button": "검색", "empty": "검색 결과가 없습니다.", "placeholder": "대시보드, 사용자 등 검색…" }, "status": { "audit": { "allow": "허용", "block": "차단" }, "delivery": { "failed": "실패", "pending": "발송 대기", "sending": "발송 중", "sent": "전달됨", "skipped": "건너뜀" }, "engine": { "exploring": "탐색 중", "idle": "유휴", "paused": "일시정지", "stalled": "정체" }, "finding": { "confirmed": "확인됨", "duplicate": "중복", "false_positive": "오탐", "fixed": "수정됨", "ignored": "무시", "in_progress": "처리 중", "pending": "처리 대기", "resolved": "처리됨", "risk_accepted": "위험 수용" }, "goal": { "abandoned": "포기", "met": "달성", "open": "진행 중" }, "intent": { "blocked": "실행 오류", "deleted": "삭제됨", "done": "완료", "exhausted": "예산 소진", "open": "대기 중", "paused": "일시정지", "running": "실행 중", "stopped": "중지됨" }, "node": { "confirmed": "확인", "observed": "관측", "tombstoned": "폐기" }, "severity": { "critical": "심각", "high": "높음", "low": "낮음", "medium": "중간" }, "task": { "created": "생성됨", "done": "완료", "failed": "실패", "paused": "일시정지", "queued": "대기 중", "running": "실행 중", "timeout": "시간 초과" } }, "userMenu": { "changePassword": "비밀번호 변경", "logout": "로그아웃" }, "taskDetail": { "report": { "title": "침투 테스트 보고서 (Markdown)", "copy": "복사", "loading": "불러오는 중…", "empty": "보고서가 없습니다", "copySuccess": "Markdown 을 복사했습니다", "copyError": "복사에 실패했습니다. 텍스트를 직접 선택해 복사하세요" }, "findings": { "columnFinding": "취약점", "sortTime": "발견 시각", "orderAsc": "오름차순", "orderDesc": "내림차순", "sortAria": "발견 시각 현재 {order}, 클릭하면 정렬 방향을 바꿉니다", "unclassified": "미분류", "sourceReadonly": "출처 #{id} · 읽기 전용", "trafficEvidence": "트래픽 증거 {count}건", "viewDetail": "취약점 상세 보기", "detail": "상세", "evidencePoc": "증거 / PoC", "markedAs": "「{label}」 상태로 변경했습니다", "updateFailed": "업데이트 실패: {message}", "empty": "이 작업과 직접 연관된 작업에 확인된 취약점이 없습니다." }, "retests": { "loadError": "작업 취약점을 불러오지 못했습니다: {error}", "retry": "다시 시도", "selectTitle": "취약점 선택", "selectDesc": "이 작업 취약점의 재검증 기록을 보거나 새 재검증을 시작합니다.", "selectAria": "취약점 선택: {name}", "emptyTitle": "재검증할 취약점이 없습니다", "emptyDesc": "이 작업에서 취약점을 발견하면 여기서 직접 재검증을 시작할 수 있습니다.", "prevPage": "이전 취약점 페이지", "nextPage": "다음 취약점 페이지", "pageIndicator": "{page} / {total} 페이지", "findingDetail": "취약점 상세" }, "tabs": { "sessions": "세션", "overview": "개요", "graph": "탐색 경로", "broadcast": "중계판", "findings": "취약점", "retests": "재검증", "assets": "테스트 자산", "coverage": "자산 커버리지 그래프", "intercept": "가로채기 승인", "report": "보고서" }, "header": { "notFound": "작업 {id} 을(를) 찾을 수 없습니다. 삭제·보관되었거나 존재하지 않습니다.", "loading": "불러오는 중…", "backToList": "작업 목록으로 돌아가기" }, "control": { "pause": "일시정지", "resume": "재개", "completed": "완료", "ended": "종료됨", "paused": "탐색을 일시정지했습니다", "resumed": "탐색을 재개했습니다", "failed": "제어에 실패했습니다: {message}" }, "archive": { "queued": "작업을 보관 대기열에 추가했습니다", "failed": "보관에 실패했습니다: {message}", "disabledQueued": "대기 중인 작업은 먼저 일시정지해야 합니다", "disabledRunning": "실행 중인 작업은 먼저 일시정지해야 합니다", "disabledInherited": "보관되지 않은 작업 #{id} 이(가) 이 작업을 직접 상속하므로, 의존하는 작업을 먼저 보관하세요", "triggerAria": "작업 보관", "dialogTitle": "작업 #{id} 을(를) 보관할까요?", "dialogDesc": "작업 그래프, 연관 기록, 전용 자산과 트래픽, 작업 파일, LLM 기록이 콜드 스토리지로 압축됩니다. 보관이 끝나면 작업 목록의 「보관됨」 페이지에서 복원할 수 있습니다.", "cancel": "취소", "confirm": "보관하기" }, "llm": { "controlAria": "작업 LLM 설정 보기 또는 전환", "exhausted": "설정 체인을 모두 소진했습니다", "profileRef": "설정 #{id}", "followDefault": "기본 설정 따름", "backupCount": "예비 {count}개", "editorDescription": "순서나 현재 설정을 바꾸면 다음 LLM 호출부터 적용됩니다.", "editorDescriptionTerminal": "작업이 이미 끝나, 변경 사항은 이후 메인 에이전트 대화에만 영향을 줍니다.", "save": "저장", "saveReset": "저장하고 초기화", "saving": "저장 중", "chainTitle": "작업 LLM 설정 체인", "exhaustedTitle": "설정 체인의 할당량을 모두 소진했습니다", "exhaustedDesc": "선택한 설정이 모두 할당량 부족으로 판정되었습니다. 설정 체인을 저장하면 장애 상태를 초기화할 수 있습니다.", "close": "닫기", "updated": "LLM 설정을 업데이트했습니다", "updatedWithReopened": "LLM 설정을 업데이트하고, 할당량 초과로 막혀 있던 의도 {count}건을 복구했습니다", "updateFailed": "업데이트에 실패했습니다: {message}" }, "coverageGraph": { "kind": { "company": "회사", "root_domain": "루트 도메인", "subdomain": "서브도메인", "ip": "IP", "service": "서비스", "app": "앱", "endpoint": "엔드포인트" }, "graph": { "moreCount": "{kind} {count}개 더", "scopeIn": "범위 내", "tested": "테스트됨", "loading": "불러오는 중…", "empty": "범위 내 자산이 없습니다(먼저 작업 범위를 지정하세요)", "refresh": "새로 고침", "legendTested": "테스트됨(강조)", "legendUntested": "미테스트", "legendOutOfScope": "범위 밖", "hint": "포스 레이아웃입니다. 노드를 드래그하고 휠로 확대·축소할 수 있습니다. 회색 「⋯」는 접힌 노드이며, 누르면 더 펼칠 수 있습니다." }, "sheet": { "attributes": "속성", "attrType": "유형", "attrTestState": "테스트 상태", "tested": "테스트됨", "untested": "미테스트", "outOfScope": "범위 밖(연결 노드)", "attrDomain": "도메인", "attrRootDomain": "루트 도메인", "attrPort": "포트", "attrTitle": "제목", "attrStatusCode": "상태 코드", "attrApp": "앱", "attrAssetId": "자산 ID", "refIntents": "연관 의도", "refFacts": "연관 사실", "refFindings": "연관 취약점", "rawData": "원본 데이터", "refSource": "출처 #{id} · 읽기 전용", "foldTitle": "표시되지 않은 {kind} ({count})", "foldHint": "테스트된 항목을 먼저 표시합니다. 「더 보기」를 누르면 다음 묶음을 그래프에 불러옵니다.", "showMore": "더 보기 (+{step})" } }, "assetsTab": { "title": "테스트 자산", "totalAll": "현재 작업에 총 {count}개 자산 연결됨", "add": "테스트 자산 추가", "empty": "현재 분류에 테스트 자산이 없습니다", "loadError": "작업 자산을 불러오지 못했습니다: {message}", "kind": { "root_domain": "루트 도메인", "ip": "IP", "subdomain": "서브도메인", "app": "앱", "service": "서비스", "endpoint": "엔드포인트" }, "col": { "domain": "도메인", "icp": "ICP 등록", "source": "출처", "action": "동작", "cSegment": "C 대역", "boundDomains": "연결된 도메인", "openPorts": "열린 포트", "rootDomain": "루트 도메인", "recordType": "레코드 유형", "recordValue": "레코드 값", "app": "앱", "address": "주소", "category": "분류", "title": "제목", "fingerprint": "핑거프린트", "addressService": "주소 / 서비스", "statusCode": "상태 코드", "responseLength": "응답 길이", "auth": "인증", "method": "메서드", "fullAddress": "전체 주소", "params": "파라미터" }, "source": { "label": { "agent": "에이전트 발견", "anchor": "블랙보드 앵커", "api": "자산 API", "company": "기업 연관", "legacy": "과거 연관", "manual": "수동 추가", "system": "시스템 연관", "task": "작업 초기화" }, "node": "출처 노드 #{id}", "legacySummary": "과거 작업 자산 연결에서 이관되어 자세한 출처 설명이 없습니다" }, "remove": { "aria": "자산 {label} 작업에서 제외", "title": "작업에서 제외", "confirmTitle": "현재 작업에서 제외할까요?", "confirmBody": "「{label}」을(를) 현재 작업의 테스트 자산에서 제외합니다.", "keep": "전역 자산·연결된 트래픽·과거 블랙보드 앵커는 그대로 유지됩니다.", "cancel": "취소", "removing": "제외 중", "confirm": "제외 확인", "success": "{label}을(를) 현재 작업에서 제외했습니다", "error": "제외 실패: {message}" }, "addSheet": { "title": "테스트 자산 추가", "description": "테스트 범위를 직접 입력합니다. 도메인과 IP 는 전역 자산을 생성하거나 재사용하고, CIDR·ICP·키워드는 에이전트 범위 컨텍스트로 쓰입니다.", "editorLabel": "테스트 자산과 범위", "editorDescription": "한 줄에 하나씩 입력하면 도메인·IP·CIDR·ICP 등록·키워드를 자동으로 인식합니다.", "cancel": "취소", "submitN": "{count}건 등록", "submit": "등록", "success": "범위 {requested}건 등록, 도메인/IP 자산 {assetSummary}개 연결", "error": "추가 실패: {message}" } }, "broadcastTab": { "kind": { "begin": "시작점", "task": "루트 작업", "goal": "목표", "intent": "의도", "fact": "사실", "finding": "취약점", "hint": "힌트", "digest": "압축" }, "rel": { "spawns": "파생", "derived_from": "의도 체인", "yields": "산출", "proves": "증명", "covers": "압축" }, "state": { "fact": { "origin": "시작점", "confirmed": "확인됨", "dismissed": "부정됨" }, "finding": { "confirmed": "확인됨", "dismissed": "제외됨" }, "hint": { "active": "채택 대기", "consumed": "채택됨" }, "digest": { "active": "활성", "superseded": "대체됨" } }, "assetType": { "app": "앱", "endpoint": "엔드포인트", "ip": "IP", "root_domain": "루트 도메인", "service": "서비스", "subdomain": "서브도메인" }, "relTime": { "now": "방금", "minutes": "{count}분 전", "hours": "{count}시간 전", "days": "{count}일 전" }, "node": "노드", "nodeRef": "노드 #{id}", "fieldType": "유형 {label}", "fieldSource": "출처 {origin}", "noSummary": "(요약 없음)", "noPayload": "(payload 없음)", "assets": "연관 자산 · {count}", "deleteReason": "삭제 사유", "upstream": "상위 · 이 노드의 유래", "downstream": "하위 · 이 노드에서 파생", "fresh": "신규", "unknownDay": "알 수 없는 날짜", "emptyFiltered": "조건에 맞는 중계가 없습니다.", "emptyNoNodes": "이 작업은 아직 탐색 노드를 생성하지 않았습니다.", "pending": "새 중계 {count}건 · 최신으로 돌아가기", "toolbar": { "searchPlaceholder": "내용 / 출처 / 노드 id 검색", "searchAria": "중계 검색", "clear": "지우기", "orderDescAria": "현재 최신순, 클릭하면 오래된순으로 변경", "orderAscAria": "현재 오래된순, 클릭하면 최신순으로 변경", "newest": "최신순", "oldest": "오래된순", "pauseAria": "자동 새로 고침 일시정지", "resumeAria": "자동 새로 고침 재개", "live": "자동 새로 고침", "paused": "일시정지됨" } }, "overviewTab": { "add": "추가", "addFailed": "추가 실패", "saveFailed": "저장 실패", "desc": { "title": "작업 설명과 목표", "descLabel": "설명", "goalLabel": "목표" }, "goals": { "title": "목표 관리", "hint": "(최종 검증 가능한 목표, 총 {count}개 · 추가·수정 시 플래너에 알리고 작업을 재개합니다)", "addPlaceholder": "목표 추가, 예: 『관리자 계정의 권한 우회 접근 확보』", "vulnPlaceholder": "취약점 유형(선택)", "empty": "목표가 없습니다. 추가하면 플래너가 이를 바탕으로 탐색 의도를 배정하고 달성 여부를 판정합니다." }, "constraints": { "title": "동작 제약", "hint": "(planner/worker 의 탐색 경계를 설정합니다. 총 {count}개 · 변경은 다음 계획 회차부터 적용됩니다)", "deny": "금지", "allow": "허용", "addPlaceholder": "동작 제약 한 건, 예: 『현재 포트만 테스트하고 다른 포트는 스캔하지 않음』", "empty": "동작 제약이 없습니다. 작업을 생성할 때 설명·목표에서 자동으로 추출하며, 여기서 직접 추가·수정·삭제해 「허용/금지할 동작」을 설정할 수도 있습니다." }, "coverage": { "title": "자산 테스트 커버리지", "rough": "(대략적인 추정치이며 참고용입니다)", "testedOf": "테스트됨 {tested} / 범위 내 {total}" }, "tokens": { "title": "LLM 토큰 사용량", "hint": "(모델별 집계{calls, plural, =0 {} other { · 총 #회 호출}})", "input": "입력", "output": "출력", "cacheRead": "캐시 읽기", "cacheHitRate": "캐시 적중률", "colModel": "모델", "colCalls": "호출", "colHitRate": "적중률", "empty": "LLM 사용량이 없습니다(작업이 아직 호출을 생성하지 않았거나, 기록을 쓰는 중입니다)." }, "scope": { "title": "테스트 범위", "hint": "(커버리지 분모 + 허가 경계, 총 {count}개)", "kind": { "company": "회사", "root_domain": "루트 도메인", "subdomain": "서브도메인", "ip": "IP", "cidr": "대역", "icp": "ICP", "keyword": "키워드" }, "source": { "auto": "자동", "agent": "에이전트", "manual": "수동" }, "placeholder": { "company": "회사명 또는 id", "ipCidr": "예: 10.0.0.1 또는 10.0.0.0/24", "icp": "예: ICP 등록번호", "keyword": "예: 기업명 키워드", "domain": "예: example.com" }, "companyFallback": "기업 #{id}", "inherited": "상속", "empty": "테스트 범위가 없습니다. 추가하면 자산 커버리지의 분모로 쓸 수 있습니다." }, "heartbeat": { "title": "하트비트", "engineState": "엔진 상태", "runningWorker": "실행 중 Worker", "lastActivity": "최근 활동", "goals": "목표 {met}/{total}", "completedAt": "완료 시각" }, "running": { "title": "진행 중 의도", "empty": "진행 중 의도가 없습니다" }, "attention": { "title": "주의 필요", "confirmedVuln": "확인된 취약점", "executing": "실행 중", "frontierPending": "frontier 대기", "blockedIntent": "차단된 의도" }, "recent": { "title": "최근 취약점", "empty": "취약점이 없습니다" }, "blocked": { "title": "차단·오류 의도", "hint": "(총 {count}개 · 재실행 가능)", "rerunAll": "전체 재실행", "rerun": "재실행", "truncated": "앞 20개만 표시합니다. 「전체 재실행」을 누르면 나머지 {rest}개를 처리합니다." }, "stat": { "pending": "대기 의도", "pendingSub": "frontier 열림", "confirmed": "확인된 취약점", "confirmedSub": "현재 작업", "total": "의도 총수", "totalSub": "현재 작업의 전체 의도" }, "rule": { "title": "작업 단위 자산 가로채기 / 허용", "hint": "(현재 작업에만 적용되고 전역에는 들어가지 않습니다. 가로채기를 먼저, 허용을 다음에 적용 · 총 {count}개)", "block": "가로채기", "allow": "허용", "notePlaceholder": "비고(선택)", "empty": "작업 단위 규칙이 없습니다. 「가로채기」에 걸리면 테스트를 금지하고, 「허용」은 화이트리스트입니다. 설정하면 현재 작업은 허용 규칙에 걸리는 자산만 테스트합니다(설정하지 않으면 화이트리스트를 적용하지 않습니다).", "kind": { "exact_domain": "도메인(완전 일치)", "exact_ip": "IP(완전 일치)", "exact_url": "URL(완전 일치)", "fuzzy_domain": "도메인(부분 일치)", "fuzzy_ip": "IP(부분 일치)", "fuzzy_url": "URL(부분 일치)", "cidr": "CIDR 대역" } } } }, "retest": { "panel": { "title": "취약점 재검증", "desc": "독립 세션에서 현재 상태를 검증하고, 재검증마다 결론과 증거를 보존합니다.", "viewRunning": "진행 중인 재검증 세션 보기", "start": "재검증 시작", "loadError": "재검증 기록을 불러오지 못했습니다: {error}", "retry": "다시 시도", "emptyTitle": "재검증 기록이 없습니다", "emptyDesc": "수정 배포가 끝난 뒤 재검증을 시작해 이전·이후 증거를 비교할 수 있습니다.", "viewSession": "세션 보기", "sessionDeleted": "세션이 삭제됨", "notes": "추가 설명: {notes}", "evidence": "재검증 증거", "status": { "pending": "시작 대기", "running": "재검증 중", "completed": "완료", "failed": "재검증 실패", "stopped": "중지됨" }, "verdict": { "reproduced": "재현됨", "fixed": "수정됨", "inconclusive": "확인 불가" } }, "dialog": { "startedNew": "재검증을 시작했습니다. 「재검증 중」을 눌러 세션을 볼 수 있습니다", "alreadyRunning": "이 취약점은 이미 재검증 중입니다. 기존 세션을 확인하세요", "startFailed": "재검증을 시작하지 못했습니다: {message}", "title": "취약점 재검증 #{id}", "desc": "재검증 에이전트가 원래 증거와 테스트 제약을 읽어, 독립 세션에서 표적 검증을 수행합니다. 재검증이 성공적으로 끝나고 수정이 확인되면 취약점 상태가 자동으로 「수정됨」으로 바뀌고, 그 밖의 결론은 기존 상태를 유지합니다.", "notesLabel": "추가 설명 (선택)", "notesPlaceholder": "예: 원래 테스트 계정으로 원래 엔드포인트를 검증하세요. 수정 버전은 v2 입니다.", "notesDesc": "수정 버전, 테스트 조건 또는 이번 제약을 덧붙일 수 있습니다.", "cancel": "취소", "submit": "재검증 시작", "submitting": "생성 중…" } }, "llmChain": { "current": "현재", "skippedTitle": "현재 커서 이전의 설정은 자동 장애 전환 대상으로 선택되지 않습니다", "skipped": "건너뜀", "backup": "예비 {n}", "profileRef": "설정 #{id}", "searchPlaceholder": "LLM 설정을 검색해 추가", "noProfiles": "사용할 수 있는 LLM 설정이 없습니다", "noMatch": "일치하는 LLM 설정이 없습니다", "activeSuffix": "(활성)", "emptyHint": "설정을 지정하지 않으면 작업은 에이전트 또는 전역 활성 설정을 따릅니다.", "unavailable": "설정을 사용할 수 없습니다", "moveUp": "설정 위로 이동", "moveDown": "설정 아래로 이동", "remove": "설정 제거", "currentProfile": "현재 설정" }, "sideQuestion": { "button": "곁질문", "buttonTitle": "/btw 곁질문", "title": "곁질문", "panelLabel": "곁질문 패널", "clearHistory": "곁질문 기록 비우기", "closePanel": "곁질문 패널 닫기", "contextUpdatedAt": "컨텍스트 갱신: {time}", "firstRunHint": "메인 에이전트가 처음 실행되면 질문할 수 있습니다", "loadEarlier": "이전 곁질문 불러오기", "emptyTitle": "언제든 질문하세요", "emptyDesc": "현재 에이전트의 컨텍스트를 바탕으로 답변하며, 메인 작업은 계속 실행됩니다.", "recentExchanges": "최근 {count}개 질의응답 원문", "historySummarized": "이전 질의응답 요약 포함", "snapshotSummarized": "메인 컨텍스트 요약 사용", "contextTime": "컨텍스트 {time}", "questionAria": "곁질문 입력", "askPlaceholder": "현재 컨텍스트에 질문…", "independentNote": "독립 질의응답 · 도구 실행 없음", "stopAnswer": "곁질문 답변 중지", "sendQuestion": "곁질문 보내기", "clearConfirmTitle": "곁질문 기록을 비울까요?", "clearConfirmDesc": "현재 에이전트의 곁질문 질의응답을 삭제하고, 생성 중인 곁질문 답변을 중지합니다. 메인 대화와 컨텍스트 스냅샷은 유지됩니다.", "cancel": "취소", "clearConfirm": "기록 비우기", "drawerDesc": "{label} 의 독립 질의응답", "parseError": "곁질문 데이터를 해석하지 못했습니다. 패널을 다시 열어 주세요.", "status": { "running": "답변 중", "completed": "완료됨", "failed": "실패", "cancelled": "중지됨", "interrupted": "중단됨" }, "phase": { "preparing": "컨텍스트를 준비하고 있습니다…", "summarizing_history": "이전 곁질문 질의응답을 정리하고 있습니다…", "compressing_snapshot": "곁질문 컨텍스트 사본을 압축하고 있습니다…", "retrying": "모델 컨텍스트 한도를 초과하여, 줄인 뒤 다시 시도하고 있습니다…", "answering": "답변하고 있습니다…" } }, "approval": { "title": { "task": "가로채기 승인", "history": "승인 기록" }, "refresh": "새로고침", "intro": "기록을 펼치면 도구 요청과 승인 판정, 그리고 당시의 컨텍스트와 실행 결과를 볼 수 있습니다.", "pendingBadge": "승인 대기 {count}건", "loadError": "불러오지 못했습니다", "recordLoadError": "기록을 불러오지 못했습니다: {error}. 새로고침을 눌러 다시 시도하세요.", "pendingLoadError": "승인 대기 목록을 불러오지 못했습니다: {error}. 새로고침을 눌러 다시 시도하세요.", "filter": { "label": "승인 기록 필터", "status": "승인 상태", "source": "판정 출처", "clear": "필터 지우기", "statusAll": "모든 상태", "sourceAll": "모든 출처" }, "status": { "pending": "승인 대기", "allowed": "허용됨", "denied": "차단됨", "timeout": "시간 초과" }, "sourceOption": { "model": "모델 판정", "rule": "규칙 판정", "unknown": "출처 미상" }, "pendingSection": "처리 대기 ({count})", "pendingHint": "펼친 뒤 허용하거나 차단하세요", "pendingTableLabel": "처리 대기 승인", "filteredResults": "필터 결과", "allRecords": "전체 기록", "emptyFiltered": "필터 조건에 맞는 승인 기록이 없습니다", "emptyTitle": "아직 승인 기록이 없습니다", "emptyFilteredDesc": "승인 상태나 판정 출처를 바꾸거나, 필터를 지우고 전체 기록을 확인하세요.", "emptyDesc": "규칙이나 모델이 승인 결정을 내리면 여기에 기록이 표시됩니다.", "historyTableLabel": "승인 기록 목록", "table": { "expandDetail": "상세 펼치기", "tool": "도구", "source": "출처", "matchRule": "일치 규칙", "params": "매개변수", "status": "상태" }, "row": { "toggleAria": "승인 #{id} {action}" }, "collapse": "접기", "expand": "펼치기", "detailAria": "승인 상세 #{id}", "conversationRef": "대화 #{id}", "taskRef": "작업 {id}", "ruleRef": "규칙 #{id}", "locateSourceAria": "승인 #{id}의 출처로 이동: {label}", "locateFailed": "해당 실행으로 이동할 수 없습니다", "modelDecision": "모델 판정", "ruleMissing": "규칙이 기록되지 않았거나 삭제되었습니다", "noReason": "사유가 기록되지 않았습니다", "copied": "복사했습니다", "copyFailed": "복사하지 못했습니다. 내용을 직접 선택해 복사하세요", "copyAria": "{label} 복사", "notRecorded": "기록되지 않았습니다", "truncatedNote": "내용이 잘렸습니다. 위는 저장된 일부입니다.", "allow": "허용", "deny": "차단", "allowedExecution": "실행을 허용했습니다", "deniedExecution": "실행을 차단했습니다", "detailLoadFailed": "상세를 불러오지 못했습니다", "detailLoadFailedWith": "상세를 불러오지 못했습니다: {error}", "retryDetail": "상세 다시 시도", "noDetailSnapshot": "이 기록은 승인 상세 스냅샷을 저장하지 않아, 당시의 컨텍스트·모델 1차 판정·실행 출력을 복원할 수 없습니다.", "collapseContext": "컨텍스트 접기", "viewContextAndResult": "컨텍스트와 실행 결과 보기", "digestOnlyNote": "이 기록은 검토 입력 지문만 저장하고 입력 원문은 저장하지 않아, 당시 모델에 전달한 컨텍스트를 복원할 수 없습니다. 검토 시 컨텍스트가 없었다는 뜻은 아니며, 새로 생성되는 모델 판정은 입력 스냅샷을 보존합니다.", "noModelInputNote": "이 기록에는 모델 검토 입력이 저장되지 않았습니다. 규칙이 직접 판정했거나, 모델 호출 전에 오류가 발생했거나, 구버전에서 생성된 기록일 수 있습니다.", "viewAuditFragmentNotSent": "대화 감사 일부 보기(모델에 전송 안 함)", "viewAuditFragment": "대화 감사 일부 보기", "auditCurrentTurn": "대화 현재 턴 입력(감사 일부)", "visibleContext": "표시 가능한 대화 컨텍스트", "savedContextNote": "{time}에 저장된 대화 기록 일부입니다. 모델이 실제로 사용한 내용은 모델 검토 입력을 기준으로 합니다.", "contextTruncated": "최근 컨텍스트만 보관하며, 일부 내용이 잘렸습니다.", "errorTag": "오류", "noRelatedContext": "연결할 수 있는 컨텍스트가 기록되지 않았습니다", "executionOutput": "실행 출력", "toolNotExecuted": "도구를 실행하지 않았습니다.", "noOutputYet": "아직 실행 출력이 없습니다", "ambiguousCorrelation": "같은 매개변수의 동시 호출이 있어 도구 호출을 하나로 연결할 수 없습니다. 이 기록은 추정 실행 결과를 표시하지 않습니다.", "noUniqueToolId": "하나로 연결할 수 있는 도구 호출 ID가 기록되지 않았습니다.", "toolCallId": "도구 호출 ID", "inputDigest": "매개변수 요약 SHA-256", "configDigest": "검토 설정 지문 SHA-256", "modelInputDigest": "모델 검토 입력 SHA-256", "resultRecordedAt": "결과 기록 시각", "toolRequest": "{agent} · 도구 요청", "agentFallback": "에이전트", "viewCommand": "명령 내용 보기", "commandContent": "명령 내용", "executionResult": "실행 결과", "loading": "불러오는 중…", "reviewStatus": "검토 상태", "approvalVerdict": "승인 판정", "noApprovalReason": "승인 사유가 기록되지 않았습니다", "finalAction": "최종 동작", "sourceLabel": "출처", "requestedAt": "신청 시각", "decidedAt": "결정 시각", "ruleSnapshot": "규칙 스냅샷", "approvalModelProfile": "승인 모델 설정", "modelInitial": "모델 1차 판정", "ruleInitial": "규칙 1차 판정", "modelFallback": "모델 오류 폴백", "action": { "allow": "허용", "ask": "확인 요청", "deny": "차단" }, "execution": { "not_started": "아직 실행하지 않음", "not_executed": "실행하지 않음", "awaiting_result": "허용됨, 실행 결과 대기 중", "succeeded": "실행 성공", "failed": "실행 실패", "unknown": "실행 결과 알 수 없음", "notCorrelated": "실행 결과를 연결하지 못함" }, "context": { "user": "사용자 메시지", "assistant": "에이전트 메시지", "text": "에이전트 메시지", "tool_use": "도구 요청", "tool_result": "도구 출력" }, "review": { "context": "모델 검토 컨텍스트", "snapshotNote": "아래는 이번에 검토 모델로 실제 전송한 입력 스냅샷입니다. 배경은 현재 동작을 이해하는 용도로만 쓰이며, 판정 근거는 검토 정책입니다.", "legacyInput": "이 기록은 구버전 입력을 사용하며, 당시 실제로 전송한 내용을 그대로 보존합니다.", "currentCall": "현재 검토 대기 호출", "bgUser": "배경 · 사용자 메시지", "bgWorkerLegacy": "배경 · Worker 의도 요약(구버전)", "bgUserNote": "현재 사용자 메시지에서 가져왔습니다.", "bgWorkerNote": "구버전에서 전송하던 Worker 의도 요약입니다. 새 버전의 Worker 검토는 이 내용을 더 이상 전송하지 않습니다.", "noBg": "이번 검토에는 배경 메시지가 없습니다.", "turnInputLegacy": "현재 턴 입력(구버전)", "taskDescLegacy": "작업 설명(구버전)", "taskGoalLegacy": "작업 목표(구버전)", "taskConstraintsLegacy": "작업 제약(구버전)", "workerIntentLegacy": "Worker 의도(구버전)", "workingDir": "작업 디렉터리", "noHistory": "이번 검토에는 과거 호출이나 실행 결과를 전송하지 않았습니다.", "historyTitleLegacy": "당시 모델에 제공한 과거 호출(구버전)", "histSucceeded": "성공", "histFailed": "실패(일부 부작용이 있을 수 있음)", "histArgs": "과거 호출 매개변수", "histResult": "과거 실행 결과", "noPairable": "이번에는 짝지을 수 있는 과거 도구 실행 기록이 없습니다.", "histTruncated": "과거 기록은 제한된 범위만 보관하며, 일부 내용이 잘렸습니다.", "viewFullJson": "모델 검토 입력 JSON 전체 보기", "modelInput": "모델 검토 입력" } }, "agentEditor": { "tab": { "prompt": "설정과 프롬프트", "wrapup": "마무리 프롬프트", "triggers": "트리거" }, "notFound": "에이전트를 찾을 수 없습니다: {key}", "llm": { "label": "기본 모델 (LLM 설정)", "follow": "작업 / 전역 활성 설정 따르기", "defaultSuffix": " · 기본", "hint": "이 에이전트에 고정 LLM 설정을 연결합니다(「설정 저장」을 눌러야 적용됩니다). 우선순위: 에이전트 연결 > 작업/세션 지정 > 전역 활성." }, "config": { "maxTurns": "최대 반복 횟수 (0=제한 없음)", "runSeconds": "실행 시간 (초, 0=제한 없음)", "save": "설정 저장" }, "webSearch": { "label": "웹 검색", "onHint": "이 에이전트에 켜면(위의 저장을 눌러야 적용) web_search 로 인터넷 검색을 쓸 수 있습니다", "offHint": "먼저 「시스템 설정」에서 웹 검색을 켜고 백엔드를 설정해야 여기서 활성화할 수 있습니다" }, "shell": { "label": "대화형 Shell", "hint": "이 에이전트에 켜면(위의 저장을 눌러야 적용) 영속 PTY 세션 도구(shell_open/send/read/close/list)로 msfconsole/ssh/REPL 같은 대화형 프로그램을 구동할 수 있습니다" }, "prompt": { "varsLabel": "변수 (클릭하면 자리표시자가 삽입되고, 렌더링 시 런타임 데이터로 치환됩니다)", "example": "예시: {example}", "noVars": "(변수 없음)", "placeholder": "비워 두면 내장 기본 프롬프트를 사용합니다", "previewBtn": "렌더링 미리 보기", "saveVersion": "새 버전으로 저장", "resetDefault": "기본값 복원" }, "preview": { "title": "렌더링 미리 보기", "descPrefix": "모든", "descSuffix": "는 백엔드가 예시 값으로 치환했습니다.", "renderError": "렌더링 오류: {error}", "failed": "미리 보기 실패: {error}" }, "version": { "historyLabel": "버전 기록", "current": "현재", "none": "(저장된 버전이 아직 없으며, 내장 기본값을 사용합니다)", "noNote": "(메모 없음)", "empty": "(비어 있음)", "compareCurrent": "현재 버전과 비교", "loadToEditor": "편집기에 불러오기" }, "diff": { "title": "버전 비교: v{from} → v{to} (현재)", "removed": "- 삭제", "added": "+ 추가" }, "wrapup": { "desc": "이 에이전트가 시간 초과나 단계 소진으로 종료될 때, 시스템이 이 「마무리 프롬프트」를 주입해 마무리 한 라운드를 돌립니다. 먼저 식별했지만 저장하지 못한 내용을 다시 기록하고, 이어서 한 문장 요약을 출력합니다(미완결 방지). 비워 두면 내장 기본값을 사용합니다.", "bodyLabel": "마무리 프롬프트 본문", "custom": "사용자 지정", "useDefault": "내장 기본값 사용", "placeholder": "비워 두면 내장 기본 마무리 프롬프트를 사용합니다", "turnsLabel": "마무리 라운드 수 (마무리 단계가 스스로 최대 몇 라운드 도는지; 0=내장 기본값 {default}라운드)", "save": "저장", "resetDefault": "기본값 복원", "defaultLabel": "내장 기본값 (읽기 전용, 참고용)" }, "taskTimeout": { "desc": "작업 시간 초과 마무리(위의 per-run 마무리와는 별개의 두 벌입니다): 작업 전체가 시간 초과 상한에 도달해 곧 끝날 때 주입됩니다. per-run 과 의미가 자주 반대입니다. 예를 들어 planner 는 per-run 에서는 “멈추지 말고 계속 계획하라”고 하지만, 작업 시간 초과에서는 “정시에 멈추고 마지막 판정을 하라”고 합니다. 비워 두면 내장 기본값을 사용합니다.", "bodyLabel": "작업 시간 초과 마무리 프롬프트 본문", "placeholder": "비워 두면 내장 기본 작업 시간 초과 마무리 프롬프트를 사용합니다", "turnsLabel": "마무리 라운드 수 (0=내장 기본값 {default}라운드)" }, "toast": { "savedVersion": "버전 v{version} 으로 저장했습니다", "saveFailed": "저장 실패: {error}", "resetToDefaultVersion": "내장 기본값으로 복원했습니다 (v{version})", "resetToDefault": "내장 기본값으로 복원했습니다", "resetFailed": "복원 실패: {error}", "wrapupSaved": "마무리 설정을 저장했습니다 (다음 실행부터 적용)", "wrapupCleared": "비웠으며, 내장 기본값을 사용합니다", "taskTimeoutWrapupSaved": "작업 시간 초과 마무리 설정을 저장했습니다 (다음 실행부터 적용)", "configSaved": "실행 설정을 저장했습니다 (즉시 적용)", "mcpVisOn": "MCP「{name}」 표시를 켰습니다", "mcpVisOff": "MCP「{name}」 표시를 껐습니다", "skillVisOn": "Skill「{name}」 표시를 켰습니다", "skillVisOff": "Skill「{name}」 표시를 껐습니다", "toolBound": "도구「{key}」 를 연결했습니다", "toolUnbound": "도구「{key}」 연결을 해제했습니다", "toolBindFailed": "도구 연결 저장 실패: {error}", "loadedToEditor": "v{version} 을 편집기에 불러왔습니다. 확인한 뒤 「새 버전으로 저장」을 누르세요" }, "mcp": { "desc": "이 에이전트에 표시할 MCP 서버를 선택하세요.", "none": "(MCP 없음)" }, "skill": { "desc": "이 에이전트에 표시할 Skill 을 선택하세요.", "none": "(Skill 없음)" }, "tools": { "desc": "이 에이전트에 연결할 내장 도구를 선택하세요.", "trafficBadge": "트래픽", "disabledBadge": "사용 중지됨", "needCapture": "트래픽 캡처를 켜야 합니다", "none": "(도구 없음)" }, "triggers": { "desc": "트리거는 이 사용자 지정 에이전트를 자동으로 실행합니다. 트리거될 때마다 새 세션을 하나 만들어 실행합니다(「대화」 페이지에서 볼 수 있습니다). 트리거 조건은 여러 개를 고를 수 있으며, 시스템이 「이번에 트리거된 이유 + 관련 작업/취약점/목표」를 당신이 쓴 기본 메시지 뒤에 자동으로 덧붙입니다.", "policyLabel": "트리거 후 처리 정책 (트리거를 어떻게 대기열에 넣고 병합해 실행할지 결정)", "runMode": "실행 모드", "serial": "직렬 (대기열, 한 번에 하나)", "parallel": "병렬 (각자 동시 세션)", "mergeMode": "병합 모드", "mergeByTask": "작업별 병합", "mergeAll": "전부 하나로 병합", "mergeNone": "병합 안 함", "maxParallel": "최대 동시 실행 (0=제한 없음)", "policyParallel": "병렬: 트리거될 때마다 즉시 세션을 하나씩 열어 동시에 실행하며 병합하지 않습니다. 최대 동시 실행을 넘는 트리거는 빈자리를 기다리며 대기열에 들어갑니다.", "policyByTask": "직렬·작업별 병합: 같은 에이전트는 한 번에 하나만 실행하며, 대기열에서 같은 작업의 이벤트 트리거를 한 세션으로 병합합니다.", "policyAll": "직렬·전부 병합: 같은 에이전트는 한 번에 하나만 실행하며, 대기열을 꺼낼 때 현재 대기 중인 모든 트리거를 한 세션으로 병합합니다.", "policyNone": "직렬·병합 안 함: 같은 에이전트는 한 번에 하나만 실행하며, 트리거마다 각자 세션 하나를 엽니다.", "editTitle": "트리거 #{id} 편집 (수정 후 「수정 저장」을 누르세요)", "addTitle": "트리거 추가 (조건마다 각자의 사용자 메시지를 적을 수 있습니다)", "onInterval": "정기 트리거", "every": "매", "seconds": "초", "intervalPlaceholder": "정기 트리거 시 에이전트에 보낼 말, 예: 모든 작업 점검", "onFinding": "취약점 발견 시 트리거", "findingPlaceholder": "취약점 발견 시 에이전트에 보낼 말 (시스템이 작업과 취약점 상세를 함께 첨부합니다)", "onGoalMet": "목표 달성 시 트리거", "goalPlaceholder": "목표 달성 시 에이전트에 보낼 말 (시스템이 작업과 달성한 목표를 함께 첨부합니다)", "onTaskTimeout": "작업 시간 초과 시 트리거", "taskTimeoutPlaceholder": "작업 시간 초과 시 에이전트에 보낼 말 (시스템이 작업 번호와 목표를 함께 첨부합니다)", "onToolCall": "도구 호출 시 트리거", "toolSelectHint": "감시할 도구를 선택하세요(최소 하나). 작업 실행 중 이 도구들이 호출을 마칠 때마다 트리거됩니다. {count}개 선택됨.", "toolListEmpty": "(도구 목록이 비어 있습니다)", "toolCallPlaceholder": "도구가 호출될 때 에이전트에 보낼 말 (시스템이 작업 정보, 도구 입력 인자와 반환 내용을 함께 첨부합니다)", "onTaskCreate": "작업 생성 시 트리거", "taskCreatePlaceholder": "작업이 생성될 때 에이전트에 보낼 말 (시스템이 작업 번호와 목표를 함께 첨부합니다)", "saveEdit": "수정 저장", "add": "트리거 추가", "cancelEdit": "편집 취소", "existing": "기존 트리거", "existingNone": "(없음)", "edit": "편집", "delete": "삭제", "errNoCondition": "트리거 조건을 최소 하나 선택하세요", "errNoTool": "도구 호출 트리거는 도구를 최소 하나 선택하세요", "savedEdit": "수정을 저장했습니다", "added": "트리거를 추가했습니다", "saveEditFailed": "저장 실패: {error}", "addFailed": "추가 실패: {error}", "savePolicyFailed": "정책 저장 실패: {error}", "deleteFailed": "삭제 실패: {error}", "cond": { "everyN": "매 {sec}초", "finding": "취약점 발견", "goalMet": "목표 달성", "taskTimeout": "작업 시간 초과", "toolCall": "도구 호출({count})", "taskCreate": "작업 생성", "none": "(조건 없음)" }, "detail": { "interval": "정기: {msg}", "finding": "취약점: {msg}", "goal": "목표: {msg}", "timeout": "시간 초과: {msg}", "taskCreate": "작업 생성: {msg}", "tools": "도구: {tools}", "toolsNone": "(선택 안 됨)", "message": "메시지: {msg}" } } }, "assetSearch": { "placeholder": "DSL 검색: domain=example AND status_code>=400", "loading": "검색 중…", "found": "검색 결과 {count}건", "field": { "domain": "도메인 (루트 도메인/서브도메인/서비스 도메인)", "ip": "IPv4/IPv6 주소", "url": "전체 URL (서비스/엔드포인트)", "root_domain": "루트 도메인", "page_title": "페이지 제목 (HTTP 서비스)", "icp": "ICP 등록번호", "service_name": "서비스 이름 (HTTP 이외 서비스)", "app_name": "앱 이름", "bundle_id": "앱 Bundle ID", "category": "앱 분류", "app_icp": "앱 ICP 등록", "method": "HTTP 메서드 GET/POST/PUT/…", "service_type": "서비스 유형: http | other", "record_type": "DNS 레코드 유형 A/CNAME/MX/…", "technology": "기술 핑거프린트 (배열 필드)", "port": "포트 번호 (정수)", "status_code": "HTTP 상태 코드 (정수)", "company_id": "소속 기업 ID (정수)", "task_id": "출처 작업 ID (정수)" }, "op": { "fuzzy": "부분 일치", "exact": "정확히 일치", "exclude": "제외", "eq": "같음", "ne": "같지 않음", "gt": "초과", "gte": "이상", "lt": "미만", "lte": "이하" }, "logic": { "and": "그리고 (두 조건 모두 충족)", "or": "또는 (둘 중 하나 충족)" } }, "taskTemplate": { "picker": { "label": "작업 템플릿", "manage": "템플릿 관리", "saveAs": "템플릿으로 저장", "loading": "템플릿 불러오는 중", "empty": "작업 템플릿 없음", "search": "작업 템플릿 검색·선택", "noMatch": "일치하는 템플릿이 없습니다", "hint": "선택하면 템플릿의 설명·목표·분류·작업 수준 규칙을 복사하며, 템플릿과 연결을 유지하지 않습니다.", "loadError": "템플릿을 불러오지 못했습니다: {error}" }, "apply": { "title": "「{name}」 템플릿을 사용할까요?", "description": "현재 입력한 설명과 목표가 템플릿 내용으로 덮어써집니다.", "cancel": "취소", "confirm": "덮어쓰고 사용" }, "manager": { "title": "작업 템플릿 관리", "description": "템플릿은 설명·목표·분류와 작업 수준 가로채기/허용 규칙을 저장합니다. 템플릿을 수정해도 이미 생성한 작업에는 영향을 주지 않습니다.", "new": "새 템플릿", "noTemplates": "템플릿 없음", "nameLabel": "템플릿 이름", "namePlaceholder": "예: 외부 웹 침투", "descriptionLabel": "설명", "descriptionPlaceholder": "테스트 대상과 배경", "goalLabel": "목표", "goalPlaceholder": "작업이 달성해야 할 목표", "categoryLabel": "작업 분류", "categoryUnclassified": "미분류", "categoryHint": "템플릿을 적용할 때 이 분류를 미리 채웁니다(다시 바꿀 수 있습니다).", "rulesLabel": "작업 수준 가로채기 / 허용 규칙", "rulesHint": "템플릿을 적용할 때 이 작업 수준 규칙을 미리 채웁니다(가로채기·허용, 새 작업에만 적용되고 전역에는 반영되지 않습니다).", "delete": "템플릿 삭제", "close": "닫기", "create": "템플릿 만들기", "saveChanges": "수정 저장", "saving": "저장 중", "validation": "템플릿 이름·설명·목표를 입력해 주세요", "created": "템플릿을 만들었습니다", "updated": "템플릿을 수정했습니다", "deleted": "템플릿을 삭제했습니다", "saveError": "저장하지 못했습니다: {error}", "deleteError": "삭제하지 못했습니다: {error}" }, "deleteDialog": { "title": "「{name}」 템플릿을 삭제할까요?", "untitled": "이름 없는 템플릿", "description": "이 템플릿으로 생성한 작업은 영향을 받지 않습니다.", "cancel": "취소", "deleting": "삭제 중", "delete": "삭제" } }, "explorationGraph": { "kind": { "task": "루트 작업", "begin": "시작점", "goal": "목표", "hint": "힌트", "intent": "의도", "fact": "사실", "finding": "취약점", "digest": "압축" }, "rel": { "spawns": "파생", "derived_from": "의도 체인", "yields": "산출", "proves": "증명" }, "detail": { "attributes": "속성", "type": "유형", "state": "상태", "priority": "우선순위", "origin": "출처", "sourceTask": "출처 작업", "time": "시간", "digestConclusion": "압축 결론", "members": "압축된 노드 ({count})", "membersNotLoaded": "멤버 노드 {count}개가 현재 그래프에 로드되지 않았습니다", "raw": "원시 데이터", "copy": "복사", "copied": "복사됨", "sourceBadge": "출처 #{id}", "sourceTaskBadge": "출처 작업 #{id} · 읽기 전용", "inheritedTooltip": "작업 #{id} 에서 상속, 읽기 전용", "inheritedReadOnly": "#{id} (상속, 읽기 전용)" }, "emptyHint": "아직 탐색 데이터가 없습니다", "lineage": { "empty": "표시할 경로가 없습니다 (이 취약점에 연결된 탐색 노드가 없거나, 해당 작업이 삭제되었습니다).", "emptyHint": "경로 없음", "loading": "불러오는 중…" } }, "pagination": { "perPage": "건/페이지", "range": "{from}–{to} / 총 {total}건", "empty": "총 0건", "prev": "이전 페이지", "next": "다음 페이지" }, "findings": { "title": "취약점", "subtitle": "작업 전반 취약점 집계", "view": { "flat": "전체 취약점", "grouped": "작업별 분류", "asset": "자산별" }, "stat": { "total": "취약점 총계", "pending": "처리 대기" }, "search": { "placeholder": "취약점 내용 검색" }, "severity": { "all": "전체", "critical": "심각", "high": "높음", "medium": "중간", "low": "낮음", "ariaFilter": "{label} 등급으로 필터" }, "status": { "placeholder": "상태", "all": "전체 상태" }, "vulnclass": { "placeholder": "취약점 유형", "all": "전체 유형" }, "task": { "placeholder": "작업", "all": "전체 작업", "unassigned": "미연결 / 삭제된 작업", "deletedShort": "작업 #{id}(삭제됨)" }, "sort": { "severity": "심각도순", "time": "시간순" }, "selectedCount": "{count}건 선택됨", "export": "내보내기", "selectAllPage": "현재 페이지 전체 선택", "selectAllGroup": "이 그룹 현재 페이지 전체 선택", "asset": { "all": "전체 자산", "totalCount": "총 {count}건" }, "group": { "withName": "{name}(작업 #{id})", "taskOnly": "작업 #{id}", "sourceUnavailable": "출처 작업을 사용할 수 없음", "viewTask": "작업 #{id} 보기" }, "empty": "일치하는 취약점이 없습니다.", "deepen": { "title": "취약점 심층 공략", "description": "원래 작업 #{id}에 우선순위 10의 Worker 인텐트를 생성해, 현재 취약점을 바탕으로 2차 검증을 진행합니다: {name}", "label": "공략 설명", "placeholder": "검증할 공략 경로, 경계 조건, 목표 또는 기대하는 증거를 설명하세요", "hint": "새 인텐트는 이 취약점의 자산 앵커를 상속합니다.", "submit": "심층 인텐트 생성" }, "exportDialog": { "title": "취약점 내보내기", "description": "내보내기 범위와 형식을 선택하세요. 생성되면 브라우저가 자동으로 다운로드합니다.", "scopeLabel": "내보내기 범위", "scopeFiltered": "현재 필터 결과 내보내기(총 {count}건)", "scopeAll": "전체 내보내기", "scopeSelected": "선택한 {count}건 내보내기", "formatLabel": "내보내기 형식", "formatMdSingle": "Markdown 통합 보고서(.md 파일 1개)", "formatMdZip": "Markdown 분할 파일(취약점당 .md 1개, .zip 압축)", "formatCsv": "CSV 표(.csv)", "formatJson": "JSON(.json)", "exporting": "내보내는 중…", "submit": "내보내기" }, "common": { "cancel": "취소", "save": "저장", "saving": "저장 중…", "delete": "삭제", "loading": "불러오는 중…" }, "toast": { "retestStatusFailed": "재검증 상태 로드 실패: {error}", "exportStarted": "내보내기 파일 다운로드를 시작했습니다", "exportFailed": "내보내기 실패: {error}", "assetTreeFailed": "자산 트리 로드 실패: {error}", "marked": "「{label}」 상태로 표시했습니다", "updateFailed": "업데이트 실패: {error}", "saved": "저장했습니다", "saveFailed": "저장 실패: {error}", "deleted": "취약점을 삭제했습니다", "deleteFailed": "삭제 실패: {error}", "deepenQueued": "심층 인텐트 #{id}을(를) 작업 큐에 추가했습니다", "deepenCreated": "우선순위가 높은 Worker 인텐트 #{id}을(를) 생성했습니다", "deepenFailed": "제출 실패: {error}" }, "table": { "colSeverity": "심각도", "colName": "취약점 이름", "colAsset": "자산", "colStatus": "상태", "colTask": "소속 작업", "colTime": "시간", "colActions": "동작", "selectOne": "이 취약점 선택", "viewDetail": "취약점 상세 보기", "unclassified": "미분류", "trafficEvidence": "트래픽 증거 {count}건", "retestingTitle": "진행 중인 재검증 세션 보기", "retesting": "재검증 중", "retestTitle": "별도 세션에서 이 취약점 재검증", "retest": "재검증", "deepen": "심층", "deleteAria": "취약점 삭제", "deleteConfirmTitle": "이 취약점을 삭제하시겠습니까?", "deleteConfirmBody": "항목을 영구 삭제합니다. 취약점 목록·작업 취약점 탭·탐색 그래프에서도 함께 제거되며, 이 작업은 되돌릴 수 없습니다.", "editName": "취약점 이름", "editNamePlaceholder": "읽기 쉬운 제목. 비우면 유형으로 대체", "editCategory": "유형", "editCategoryPlaceholder": "예: SQL Injection", "editSeverity": "심각도 등급", "evidence": "증거", "typeInline": "· 유형: ", "assetInline": "· 자산: ", "detailReport": "상세 보고서", "reportCopied": "상세 보고서를 복사했습니다", "reportLoadFailed": "보고서 로드 실패.", "reportEmpty": "상세 보고서가 없습니다." }, "assetTree": { "kind": { "company": "기업", "root_domain": "루트 도메인", "subdomain": "서브도메인", "ip": "IP", "app": "앱", "service": "서비스", "endpoint": "엔드포인트", "none": "미연결" }, "emptyNoAsset": "현재 필터에서 자산에 연결된 취약점이 없습니다.", "emptyNoMatch": "일치하는 자산이 없습니다.", "filterPlaceholder": "자산 필터", "refresh": "자산 트리 새로 고침", "truncated": "자산이 너무 많아 {kinds} 계층을 숨겼습니다(개수는 상위 계층에 합산됨). 필터나 검색 상자로 범위를 좁히면 전체 계층을 볼 수 있습니다.", "collapse": "접기", "expand": "펼치기", "criticalCount": "심각 {count}", "highCount": "높음 {count}", "totalCount": "취약점 총 {count}건" }, "detail": { "notFound": "취약점 {id}을(를) 찾을 수 없습니다", "back": "취약점 목록으로 돌아가기", "sourceTask": "출처 작업 #{id} · 읽기 전용", "tab": { "overview": "개요", "lineage": "경로도" }, "summary": "요약", "summaryEmpty": "(요약 없음)", "evidence": "증거 / PoC", "evidenceEmpty": "(증거 없음)", "reportStale": "트래픽 증거가 변경되어 상세 보고서를 갱신해야 합니다.", "statusTitle": "상태", "fieldId": "취약점 ID", "fieldSeverity": "심각도 등급", "fieldStatus": "처리 상태", "fieldType": "취약점 유형", "fieldAssets": "연관 자산", "fieldTask": "소속 작업", "taskDeleted": "—(작업이 삭제됨)", "fieldTime": "발견 시각", "severityChanged": "심각도 등급을 「{label}」(으)로 변경했습니다", "statusChanged": "처리 상태를 「{label}」(으)로 변경했습니다" }, "traffic": { "title": "연결된 트래픽", "bind": "트래픽 연결", "inherited": "증거 상속 · 읽기 전용", "description": "재현 순서대로 요청과 응답을 정리하세요. 원본 트래픽을 정리해도 연결된 증거는 그대로 유지됩니다.", "retry": "다시 시도", "empty": "연결된 트래픽이 없습니다", "emptyHint": "정상 대조·취약점 증명·보충 검증 요청을 연결할 수 있습니다.", "evidenceNo": "증거 #{id}", "viewRaw": "원문 보기", "editNote": "설명 편집", "moveUp": "증거 {id} 위로 이동", "moveDown": "증거 {id} 아래로 이동", "unbind": "연결 해제", "updated": "트래픽 증거를 갱신했습니다", "editTitle": "트래픽 증거 편집", "editDescription": "이 요청·응답 묶음이 취약점 결론을 어떻게 뒷받침하는지 설명하세요.", "roleLabel": "용도", "noteLabel": "증거 설명", "saveNote": "설명 저장", "role": { "baseline": "정상 대조", "proof": "취약점 증명", "verification": "보충 검증", "supporting": "보조 증거" } } }, "copyButton": { "label": "복사", "success": "복사했습니다", "error": "복사에 실패했습니다. 텍스트를 직접 선택해 복사하세요" }, "trafficEvidence": { "picker": { "title": "트래픽 연결", "description": "요청·응답을 필터링해 여러 개를 선택할 수 있고, 선택한 기록은 페이지를 넘겨도 유지됩니다. 연결한 뒤에는 용도·설명·순서를 설정할 수 있습니다.", "host": "대상 호스트", "hostPlaceholder": "도메인 또는 IP", "method": "요청 메서드", "allMethods": "전체 메서드", "keyword": "키워드", "keywordPlaceholder": "URL / 본문 키워드", "selectPage": "이 페이지의 미연결 트래픽 선택", "colMethodUrl": "메서드 / URL", "colTime": "시간", "colStatus": "상태 코드", "colAction": "동작", "selectOne": "트래픽 {id} 선택", "bound": "연결됨", "preview": "미리 보기", "loading": "불러오는 중…", "noMatch": "일치하는 트래픽이 없습니다", "selectedSummary": "{selected}건 선택 · 총 {total}건", "prevPage": "이전 페이지", "pageNo": "{page} 페이지", "nextPage": "다음 페이지", "cancel": "취소", "saving": "저장 중…", "bindCount": "트래픽 {count}건 연결", "boundToast": "트래픽 {count}건을 연결했습니다" }, "viewer": { "title": "트래픽 증거 #{id}", "fallbackDesc": "연결 시 저장된 요청·응답 보기", "request": "요청 Request", "response": "응답 Response", "bodyBytes": "본문 {bytes} 바이트", "previewSuffix": " · 현재 미리 보기", "downloadRequest": "전체 요청 본문 다운로드", "downloadResponse": "전체 응답 본문 다운로드", "loadMore": "본문 더 불러오기" }, "captured": { "title": "트래픽 미리 보기", "description": "트래픽 ID: {id}. 연결 시 전체 본문이 저장됩니다." }, "code": { "empty": "(비어 있음)", "copyFailed": "복사에 실패했습니다. Ctrl/Cmd+A 로 전체 선택 후 복사하세요.", "wrapOff": "자동 줄바꿈 끄기", "wrapOn": "자동 줄바꿈 켜기", "copiedPacket": "원문 복사됨", "copyPacket": "원문 복사", "copied": "복사됨", "label": "HTTP 원문 코드" } }, "transcript": { "newRound": "새 라운드", "streaming": "실시간 스트리밍 중…", "loading": "불러오는 중…", "withThinking": "추론 포함", "kind": { "thinking": "추론", "result": "요약", "note": "설명" }, "tool": { "name": "도구", "running": "실행 중…", "failed": "✕ 실패", "command": "명령", "output": "출력", "empty": "(비어 있음)", "loadFailed": "(불러오기 실패)", "pinned": "고정된 도구 호출 #{seq}" }, "approval": { "request": "승인 요청", "historyReadonly": "기록 · 읽기 전용", "allowed": "허용됨", "timeout": "시간 초과됨", "denied": "거부됨", "allow": "허용", "deny": "거부", "expand": "승인 상세 펼치기", "collapse": "승인 상세 접기", "retry": "상세 다시 시도", "loading": "승인 상세를 불러오는 중…", "loadError": "승인 상세를 불러오지 못했습니다", "allowedToast": "실행을 허용했습니다", "deniedToast": "실행을 거부했습니다" } }, "mentionTextarea": { "inputAria": "메시지. @ 를 입력해 기록을 인용하세요", "listboxAria": "인용할 기록 선택", "pickKind": "인용 유형 선택", "searchKind": "{kind} 검색", "allRecords": "전체 기록", "hintKeys": "↑↓ 이동 · Enter 선택 · Esc 닫기", "candidatesAria": "인용 후보", "searching": "검색 중…", "searchError": "검색 실패: {error}. 다시 입력해 시도해 주세요.", "noMatch": "일치하는 기록이 없습니다. 이름·주소·ID 를 바꿔 보세요.", "loadingMore": "더 불러오는 중…", "pageError": "불러오기 실패. 눌러서 다시 시도", "showingMore": "{count}건 표시됨 · 아래로 스크롤해 더 불러오기", "showingAll": "전체 {count}건 표시됨", "searchHint": "이름·주소·ID 를 입력해 기록을 검색하세요", "removeAria": "인용 제거 {label}", "selectedHint": "전송 시 최신 상세 정보를 읽습니다 · 최대 10건", "kind": { "finding": "취약점", "asset": "자산", "company": "기업", "endpoint": "엔드포인트", "ip": "IP", "app": "앱", "root_domain": "도메인", "subdomain": "서브도메인", "service": "서비스" } }, "assetInterceptRules": { "action": { "block": "차단", "allow": "허용" }, "kind": { "exact_domain": "도메인(완전 일치)", "exact_ip": "IP(완전 일치)", "exact_url": "URL(완전 일치)", "fuzzy_domain": "도메인(부분 일치)", "fuzzy_ip": "IP(부분 일치)", "fuzzy_url": "URL(부분 일치)", "cidr": "CIDR 대역" }, "notePlaceholder": "비고(선택)", "add": "규칙 추가" }, "interceptPage": { "title": "명령 가로채기", "subtitle": "도구를 실행하기 전에 먼저 가로채기 규칙으로 대조하고, 규칙에 걸리지 않은 명령은 모델이 최종 판정하도록 넘길 수 있습니다", "scope": { "label": "가로채기 범위", "empty": "활성화한 도구가 없습니다 — 가로채기 규칙과 모델 폴백이 모두 작동하지 않습니다", "toolCount": "도구 {count}개", "adjust": "범위 조정", "dialogTitle": "가로채기 범위", "dialogDesc": "가로채기를 켠 도구만 규칙 대조를 거치고, 나머지 도구는 바로 통과합니다" }, "tab": { "rules": "가로채기 규칙", "model": "모델 설정" }, "rules": { "priorityHint": "우선순위(숫자가 클수록 먼저)에 따라 한 건씩 대조하며, 가장 먼저 걸린 규칙이 적용됩니다", "add": "규칙 추가", "loading": "불러오는 중…", "empty": "규칙이 없습니다", "addFirst": "첫 규칙 만들기", "colPriority": "우선순위", "colName": "이름", "colTarget": "대상", "colType": "유형", "colPattern": "패턴", "colAction": "처리", "colEnabled": "활성화" }, "target": { "tool_name": "도구 이름", "tool_input": "입력 내용" }, "matchType": { "regex": "정규식", "string": "문자열" }, "action": { "allow": "허용", "deny": "차단", "ask": "확인 요청" }, "editor": { "editTitle": "규칙 편집", "newTitle": "규칙 추가", "desc": "우선순위가 클수록 먼저 대조하고, 가장 먼저 걸린 규칙이 적용되며 이후 규칙은 건너뜁니다", "name": "이름", "namePlaceholder": "규칙 이름을 입력하세요", "priority": "우선순위(숫자가 클수록 먼저 대조)", "matchTarget": "대조 대상", "targetToolName": "도구 이름(tool_name)", "targetToolInput": "입력 내용(tool_input JSON)", "matchTypeLabel": "대조 방식", "typeStringContains": "문자열 포함", "typeRegex": "정규식", "pattern": "패턴", "regexWarn": "Go RE2 확장 문법(예: (?i))이 포함되어 브라우저에서는 미리 볼 수 없으며, 제출하면 서버가 검증합니다", "actionLabel": "가로채기 처리", "actionAllow": "허용 — 바로 통과시키고 이후 규칙은 건너뜁니다", "actionDeny": "차단 — 막고 거부 메시지를 모델에 돌려줍니다", "actionAsk": "사용자에게 확인 요청 — 승인을 기다립니다", "denyMessage": "거부 메시지(모델에 전달)", "askMessage": "승인 안내(선택)", "denyMessagePlaceholder": "보안 정책에 의해 작업이 차단되었습니다", "enableTimeout": "승인 제한 시간 사용", "enableTimeoutHint": "제한 시간이 지나면 자동으로 처리하고 더 기다리지 않습니다", "timeoutSeconds": "제한 시간(초)", "timeoutAction": "제한 시간 후 동작", "timeoutDeny": "자동 거부", "timeoutAllow": "자동 허용", "enableRule": "이 규칙 사용", "cancel": "취소", "saving": "저장 중…", "save": "저장" }, "toast": { "ruleUpdated": "규칙을 수정했습니다", "ruleCreated": "규칙을 만들었습니다", "ruleDeleted": "규칙을 삭제했습니다", "loadRulesFailed": "가로채기 규칙을 불러오지 못했습니다", "nameRequired": "이름을 입력하세요", "patternRequired": "패턴을 입력하세요", "regexInvalid": "정규식 문법이 올바르지 않습니다", "scopeSaved": "가로채기 범위를 저장했습니다", "loadFailed": "불러오지 못했습니다: {error}", "saveFailed": "저장 실패: {error}" }, "toolGroup": { "exec": "실행 계열", "write": "쓰기/편집 계열", "system": "시스템 도구", "custom": "사용자 정의 도구" }, "toolDesc": { "Bash": "shell 에서 명령 실행", "WebFetch": "HTTP/HTTPS 요청 보내기(프록시 지원 포함)", "web_search": "웹 검색", "shell_open": "지속 PTY 대화형 세션 열기", "shell_send": "대화형 세션에 입력 보내기", "shell_read": "대화형 세션 출력 읽기", "shell_close": "대화형 세션 닫기", "shell_list": "모든 대화형 세션 목록 보기", "Write": "파일 쓰기", "Edit": "파일 편집(정확히 치환)", "MultiEdit": "파일 일괄 편집" }, "judge": { "title": "모델 폴백 승인", "desc": "가로채기 범위 안에 있고 어떤 가로채기 규칙에도 걸리지 않은 명령만 모델이 의미를 판단합니다(허용 / 확인 요청 / 차단)", "enabled": "사용 중", "disabled": "사용 안 함", "promptTitle": "승인 프롬프트", "promptDesc": "모델이 이를 근거로 ALLOW / ASK / DENY 를 판정하며, 직접 편집할 수 있습니다", "restoreTemplate": "기본 템플릿 복원", "promptPlaceholder": "비워 두면 내장 템플릿을 사용합니다", "charCount": "{count}자", "modelAndPolicy": "판정 모델과 정책", "approvalModel": "승인 모델", "followActive": "활성 설정 따르기", "judgeTimeout": "모델 판정 제한 시간(초)", "failAction": "모델 실패 시(오류 / 시간 초과 / 해석 불가)", "failAllow": "허용", "failAsk": "확인 요청으로 전환", "failDeny": "차단", "manualApproval": "수동 승인(모델이 「확인 요청」으로 판정했을 때)", "askTimeout": "승인 대기 제한 시간(초)", "askTimeoutAction": "제한 시간 후 기본 동작", "askTimeoutDeny": "차단", "askTimeoutAllow": "허용", "saving": "저장 중…", "saveConfig": "설정 저장", "loadConfigFailed": "모델 폴백 설정을 불러오지 못했습니다: {error}", "configSaved": "모델 폴백 설정을 저장했습니다", "restored": "기본 내장 템플릿으로 되돌렸습니다", "restoreFailed": "복원 실패: {error}" } }, "assetInterceptPage": { "title": "자산 차단", "subtitle": "전역 자산 블랙리스트입니다. 걸린 도메인 / IP / URL / 대역은 차단되어 어떤 작업도 수행하지 않습니다", "intro": "도메인 / IP / URL 의 완전 일치·부분 일치와 CIDR 대역을 지원합니다. 기본으로 정부(.gov / .gov.cn)와 교육(.edu / .edu.cn) 사이트를 부분 일치로 차단하도록 내장되어 있습니다", "add": "규칙 추가", "loading": "불러오는 중…", "empty": "자산 차단 규칙이 없습니다", "addFirst": "첫 규칙 만들기", "colType": "유형", "colPattern": "대조 내용", "colNote": "비고", "colEnabled": "활성화", "builtin": "내장", "group": { "exact": "완전 일치", "fuzzy": "부분 일치", "cidr": "대역" }, "editor": { "editTitle": "자산 차단 규칙 편집", "newTitle": "자산 차단 규칙 추가", "desc": "이 규칙에 걸리는 대상 자산은 전역에서 차단됩니다", "matchType": "대조 유형", "matchContent": "대조 내용", "hintCidr": "CIDR 대역, 192.168.0.0/16 형태", "hintFuzzy": "부분 일치: 대상이 이 내용을 포함하면 걸립니다", "hintExact": "완전 일치: 대상이 이 내용과 정확히 같아야 걸립니다", "note": "비고(선택)", "notePlaceholder": "이 규칙의 용도를 설명하세요", "enableRule": "이 규칙 사용", "cancel": "취소", "saving": "저장 중…", "save": "저장" }, "toast": { "loadFailed": "자산 차단 규칙을 불러오지 못했습니다", "ruleUpdated": "규칙을 수정했습니다", "ruleCreated": "규칙을 만들었습니다", "ruleDeleted": "규칙을 삭제했습니다", "contentRequired": "대조 내용을 입력하세요", "cidrInvalid": "CIDR 형식이 올바르지 않습니다. 192.168.0.0/16 형태로 입력하세요" }, "deleteConfirm": "자산 차단 규칙 「{pattern}」을(를) 삭제하시겠습니까?" }, "scopeEditor": { "defaultLabel": "자산 범위", "defaultDescription": "한 줄에 하나씩 입력하면 도메인·IP·CIDR·ICP 등록·기업 키워드를 자동으로 인식합니다.", "placeholder": "example.com\n203.0.113.10\n198.51.100.0/24\n기업명 키워드", "kind": { "domain": "도메인", "ip": "IP", "cidr": "CIDR", "icp": "ICP", "keyword": "키워드" }, "recognized": "{count}건 인식됨", "lineError": "{line}행: {error}", "moreErrors": "그 외 {count}행 오류", "error": { "empty": "범위 값을 입력해 주세요", "tooLong": "최대 {max}자까지 입력할 수 있습니다", "domainSpace": "공백 없이 유효한 도메인 또는 URL을 입력해 주세요", "domainInvalid": "유효한 도메인 또는 URL을 입력해 주세요", "ipInvalid": "유효한 IP를 입력해 주세요", "cidrInvalid": "유효한 CIDR 대역을 입력해 주세요", "cidrPrefixV4": "IPv4 대역 프리픽스는 /16 ~ /32 범위여야 합니다", "cidrPrefixV6": "IPv6 대역 프리픽스는 /32 ~ /128 범위여야 합니다" } }, "approvalFocus": { "mismatch": "승인 출처가 현재 대화와 일치하지 않습니다", "noSource": "원본 실행을 찾을 수 없습니다", "notFoundDeleted": "대화에서 해당 도구 호출을 찾지 못했습니다. 기록이 삭제되었을 수 있습니다.", "notFound": "대화에서 해당 도구 호출을 찾지 못했습니다.", "locateFail": "찾을 수 없음: {error}", "expanded": "승인 #{id}에 해당하는 도구 호출을 펼쳤습니다", "loading": "승인 #{id}가 있는 대화 위치를 불러오는 중…", "retry": "다시 찾기", "cancel": "찾기 취소" }, "todoPopover": { "parseError": "Todo 를 해석하지 못했습니다", "none": "이 대화에 Todo 없음", "view": "최근 Todo 보기", "recent": "최근 Todo", "loadingSuffix": " · 불러오는 중…", "empty": "(비어 있음)" }, "agentsPage": { "title": "에이전트", "subtitle": "기본 제공 에이전트의 프롬프트·설정과 사용자 정의 대화 에이전트의 생성·관리", "listTitle": "에이전트 목록", "countTotal": "총 {count}개", "empty": "(에이전트가 없습니다)", "new": "새 에이전트", "badgeBuiltin": "기본 제공", "badgeCustom": "사용자 정의", "badgeDisabled": "비활성화됨", "noDescription": "(설명 없음)", "toolLabel": "도구", "deleteTitle": "에이전트 「{name}」을(를) 삭제할까요?", "deleteDesc": "이 에이전트의 프롬프트, 변수, 노출 범위, 도구 연결이 함께 삭제됩니다. 이 작업은 되돌릴 수 없습니다.", "cancel": "취소", "delete": "삭제", "deleted": "에이전트 「{name}」을(를) 삭제했습니다", "deleteFailed": "삭제 실패: {msg}", "created": "에이전트 「{name}」을(를) 만들었습니다", "createFailed": "생성 실패: {msg}", "createTitle": "새 사용자 정의 에이전트", "createDesc": "대화형 어시스턴트를 만듭니다. key 는 내부 식별자로 쓰이며 생성 후에는 바꿀 수 없습니다. 이름과 설명은 식별하는 데 씁니다.", "keyPlaceholder": "예: research_helper", "keyError": "소문자로 시작하고 소문자, 숫자, 밑줄만 쓸 수 있습니다", "nameLabel": "이름", "namePlaceholder": "예: 리서치 도우미", "descLabel": "설명", "descPlaceholder": "이 에이전트가 무엇을 하는지 한 문장으로 설명합니다", "create": "만들기", "editorDescFallback": "프롬프트·설정·노출 자원·도구 연결" }, "logsPage": { "title": "시스템 로그", "subtitle": "백엔드 실시간 로그 스트림 (planner / worker / 데이터베이스 / 트래픽 …)", "filterPlaceholder": "필터 (텍스트 / tag)…", "all": "전체", "paused": "일시정지됨", "pause": "일시정지", "clear": "지우기", "totalLines": "{count}행", "warnCount": "{count} 경고", "errorCount": "{count} 오류", "loading": "불러오는 중…", "loadOlder": "이전 로그 더 보기", "empty": "로그가 없습니다." }, "mcpPage": { "subtitle": "외부 MCP 도구 서버 · 에이전트별로 노출 허용", "addCard": "MCP 추가", "enableAria": "사용", "deleteAria": "삭제", "toolCount": "도구 {count}개", "noTools": "아직 발견된 도구가 없습니다", "visibilityLabel": "노출 범위 (에이전트별 허용)", "addServer": "MCP 서버 추가", "sheetDesc": "stdio (로컬에서 프로세스 실행) 또는 http (원격 Streamable HTTP)", "tabConfig": "설정", "tabTools": "도구 목록", "save": "저장", "add": "추가", "transport": "전송 방식", "transportStdio": "stdio (로컬)", "transportHttp": "http (원격)", "transportSse": "sse (구버전)", "nameLabel": "이름", "cmdLabel": "명령", "argsLabel": "인자 (공백으로 구분)", "urlLabel": "원격 URL", "insecureLabel": "TLS 인증서 검증 건너뛰기 (자체 서명 인증서)", "headersLabel": "요청 헤더 (한 줄에 KEY=VALUE, 예: Authorization=Bearer xxx)", "envLabel": "환경 변수 (한 줄에 KEY=VALUE)", "refresh": "새로 고침", "loading": "불러오는 중…", "toolsEmpty": "아직 발견된 도구가 없습니다. 새로 고침을 눌러 다시 가져옵니다.", "errNoName": "이름을 입력해 주세요", "errNoCmd": "명령을 입력해 주세요", "errNoUrl": "원격 URL 을 입력해 주세요", "saved": "저장했습니다", "added": "MCP 서버를 추가했습니다", "saveFailed": "저장 실패: {msg}", "foundTools": "도구 {count}개를 발견했습니다", "refreshFailed": "새로 고침 실패: {msg}", "removed": "삭제했습니다: {name}", "deleteFailed": "삭제 실패: {msg}", "actionFailed": "작업 실패: {msg}", "visibilityGranted": "「{name}」 노출을 허용했습니다", "visibilityRevoked": "「{name}」 노출을 해제했습니다" }, "toolsPage": { "title": "도구", "subtitle": "시스템 도구의 설명·연결, 그리고 사용자 정의 도구(command/script/http)", "searchPlaceholder": "도구 이름, 설명, 에이전트 검색…", "tabSystem": "시스템 도구", "tabCustom": "사용자 정의 도구", "systemMatched": "{shown} / {total}개 일치, 카드를 클릭해 설명·파라미터 기본값·에이전트 연결을 편집합니다", "systemTotal": "총 {total}개, 카드를 클릭해 설명·파라미터 기본값·에이전트 연결을 편집합니다", "systemNoMatch": "일치하는 시스템 도구가 없습니다", "systemEmpty": "(시스템 도구가 아직 없습니다. 백엔드 seed 를 기다립니다)", "customMatched": "shell/command/script/http, {shown} / {total}개 일치, 카드를 클릭해 편집합니다", "customTotal": "shell(bash 선언) / command(명령) / script(Python) / http(API), 총 {total}개, 카드를 클릭해 편집합니다", "newCustom": "사용자 정의 도구 만들기", "customNoMatch": "일치하는 사용자 정의 도구가 없습니다", "customEmpty": "(사용자 정의 도구가 아직 없습니다. 오른쪽 위 「사용자 정의 도구 만들기」를 클릭하세요)", "editSheetDesc": "설명·파라미터 기본값·에이전트 연결을 편집합니다", "badgeSystem": "시스템", "badgeCustom": "사용자 정의", "badgeDisabled": "비활성화됨", "callsTitle": "누적 호출 {count}회", "callsBadge": "호출 {count}", "noDescription": "(설명 없음)", "noBoundAgents": "(연결된 에이전트 없음)", "trafficGatedNote": "이 도구는 트래픽 캡처에 의존합니다. 먼저 「시스템 설정」에서 트래픽 캡처를 켜야 에이전트에 연결하고 활성화할 수 있습니다.", "bindAgentLabel": "에이전트 연결 (이 도구를 어떤 에이전트에 줄지 결정합니다)", "bindAgentShort": "에이전트 연결", "noAgents": "(에이전트 없음)", "enabled": "활성화", "descLabel": "도구 설명 (모델에 전달)", "paramsLabel": "파라미터 (이름 / 유형 / 필수 여부는 읽기 전용, 설명과 기본값은 수정 가능)", "noParams": "(파라미터 없음)", "required": "필수", "itemsSubfield": "items 하위 필드", "rowDesc": "설명", "rowDefault": "기본값", "defaultEmptyHint": "(비우면 기본값 없음)", "scalarOnly": "스칼라만 지원", "save": "저장", "resetDefault": "기본값 복원", "savedTool": "도구 「{key}」을(를) 저장했습니다", "saveFailed": "저장 실패: {msg}", "resetDone": "「{key}」을(를) 코드 기본값으로 복원했습니다", "resetFailed": "복원 실패: {msg}", "keyError": "key 는 소문자로 시작하고 소문자, 숫자, 밑줄만 쓸 수 있습니다", "schemaError": "파라미터 JSON Schema 형식이 잘못되었습니다", "headersError": "headers JSON 형식이 잘못되었습니다", "httpSchemaRequired": "http 도구는 파라미터 JSON Schema 를 반드시 제공해야 합니다(properties 포함, 비울 수 없음)", "createdCustom": "사용자 정의 도구를 만들었습니다", "saved": "저장했습니다", "deleted": "삭제했습니다", "deleteFailed": "삭제 실패: {msg}", "testParamsError": "테스트 파라미터 JSON 형식이 잘못되었습니다", "editCustom": "{key} 편집", "customSheetDesc": "shell=bash 환경 선언(이름과 설명만 있으면 됩니다. 모델에 bash 로 호출할 수 있다고 알립니다). command/script/http 는 실행 규격을 작성해야 합니다.", "keyPlaceholder": "예: nmap_scan", "descLabelShort": "설명(모델에 전달)", "kindLabel": "유형", "kindShell": "shell(bash 환경 선언)", "kindCommand": "command(shell 명령 템플릿)", "kindScript": "script(Python 스크립트)", "kindHttp": "http(API 요청)", "shellHint": "nmap, sqlmap, ffuf 처럼 잘 알려진 도구에 적합합니다. 모델이 사용법을 이미 알고 있으므로 「bash 에서 호출할 수 있음」이라고 선언하기만 하면 됩니다. 이름과 설명은 Bash 도구 설명에 덧붙습니다.", "cmdTemplateLabel": "명령 템플릿(자리표시자 '{param}', 예: nmap -p '{ports}' '{target}')", "scriptLabel": "Python 본문(파라미터는 stdin JSON 또는 os.environ[\"TOOL_X\"] 로 전달)", "httpUrlLabel": "URL('{param}' 포함 가능)", "httpHeadersLabel": "Headers(JSON, '{param}' 포함 가능)", "httpBodyLabel": "Body('{param}' 포함 가능)", "proxyLabel": "프록시 URL(비우면 직접 연결)", "useRecordingProxy": "기록 프록시 사용", "timeoutLabel": "타임아웃(ms, 비우면 기본값)", "schemaLabel": "파라미터 JSON Schema", "schemaHttpSuffix": "(http 도구 필수, properties 포함 필요)", "schemaDefaultSuffix": "(비우면 자동으로 '{args}' 얇은 껍데기 적용)", "deferredLabel": "deferred(자주 쓰지 않는 도구가 많을 때만 켜기)", "testSectionLabel": "테스트 실행(현재 폼 사용, 저장되지 않음)", "testParamsPlaceholder": "예시 파라미터 JSON, 예: '{\"target\":\"example.com\"}'", "testRun": "테스트 실행", "testRunning": "실행 중…", "noOutput": "(출력 없음)", "create": "만들기", "delete": "삭제" }, "skillsPage": { "title": "스킬", "subtitle": "스킬 라이브러리 · agentskills.io 규격 · 에이전트별 노출 권한", "missingCount": "미적중 호출 {count}건", "missingHint": "에이전트가 지목해 호출했지만 스킬 라이브러리에 존재하지 않는 스킬입니다. 지목된 횟수 순으로 정렬합니다.", "newSkill": "새 스킬", "uploadTitle": "SKILL.md 를 포함한 .zip 압축 파일 업로드", "uploading": "업로드 중…", "uploadZip": "압축 파일 업로드", "emptySidebar": "스킬이 없습니다. 「새 스킬」을 눌러 시작하세요.", "callCountTitle": "{count}회 호출됨 · 최근 {last}", "newFile": "새 파일", "newFolder": "새 폴더", "deleteFolder": "폴더 삭제", "deleteFile": "파일 삭제", "deleteSkillAction": "스킬 삭제", "emptyOverview": "스킬이 없습니다. 왼쪽의 「새 스킬」 또는 「압축 파일 업로드」를 눌러 시작하세요.", "statTotal": "스킬 총 개수", "statTotalHint": "{count}개가 호출됨", "statCalls": "누적 호출", "statUnused": "미사용", "statUnusedHintSome": "어떤 에이전트도 로드한 적 없음", "statUnusedHintNone": "전부 사용됨", "statMissing": "미적중 호출", "statMissingHintSome": "존재하지 않는 스킬 {count}개", "statMissingHintNone": "없음", "overviewTitle": "스킬 라이브러리 전체 보기", "overviewDesc": "왼쪽의 스킬을 선택하면 상세 정보와 호출 기록을 볼 수 있습니다. 또는 여기에서 전체 사용 현황을 빠르게 파악할 수 있습니다.", "ranking": "호출 순위", "rankingEmpty": "아직 스킬 호출 기록이 없습니다.", "callsCount": "{count}회", "recent": "최근 호출", "recentEmpty": "기록이 없습니다.", "unusedSkills": "미사용 스킬", "allUsed": "모든 스킬이 호출된 적 있습니다.", "neverCalled": "호출된 적 없음", "installed": "스킬을 설치했습니다: {name}(파일 {files}개)", "overwriteConfirm": "{msg}\n\n같은 이름의 스킬을 덮어쓸까요?", "uploadFailed": "업로드 실패: {msg}", "readFileFailed": "파일 읽기 실패", "folderCreated": "폴더를 만들었습니다: {path}", "fileCreated": "파일을 만들었습니다: {path}", "createFailed": "생성 실패: {msg}", "deleted": "삭제했습니다: {path}", "deleteFailed": "삭제 실패: {msg}", "skillDeleted": "스킬을 삭제했습니다: {name}", "saved": "저장했습니다", "saveFailed": "저장 실패: {msg}", "mcpLinked": "「{name}」 연결함", "mcpUnlinked": "「{name}」 연결 해제함", "opFailed": "작업 실패: {msg}", "visGranted": "「{name}」 노출 허용함", "visRevoked": "「{name}」 노출 취소함", "needName": "name 을 입력하세요", "needDesc": "description 은 필수 항목입니다", "skillCreated": "스킬을 만들었습니다", "callStats": "호출 통계", "totalCalls": "총 호출 횟수", "coveredTasks": "관련 작업 수", "callers": "호출 주체:", "loadingCalls": "호출 상세 불러오는 중…", "recentCallsCount": "최근 호출 {count}건", "taskRef": "작업 #{id}", "sessionRef": "대화 세션", "noCallsYet": "아직 호출 기록이 없습니다.", "linkedMcp": "연결된 MCP", "linkedMcpHint": "(스킬을 로드할 때만 해당 도구가 공개·잠금 해제됩니다)", "noMcp": "MCP 가 없습니다. 「MCP」 페이지에서 추가할 수 있습니다.", "visibility": "노출 범위(에이전트별 권한)", "noAgents": "(에이전트가 없습니다)", "saving": "저장 중…", "save": "저장", "loading": "불러오는 중…", "deleteSkillQ": "스킬 「{name}」을(를) 삭제할까요?", "deleteFolderQ": "폴더 「{path}」을(를) 삭제할까요?", "deleteFileQ": "파일 「{path}」을(를) 삭제할까요?", "deleteSkillDesc": "이 스킬의 모든 파일, MCP 연결, 노출 설정을 삭제합니다. 이 작업은 되돌릴 수 없습니다.", "deleteFolderDesc": "이 폴더 아래의 모든 파일을 함께 삭제합니다. 이 작업은 되돌릴 수 없습니다.", "irreversible": "이 작업은 되돌릴 수 없습니다.", "cancel": "취소", "deleting": "삭제 중…", "delete": "삭제", "tabBasic": "기본 정보", "tabVisibility": "노출 범위", "nameLabel": "이름", "nameHint": "소문자 / 숫자 / 하이픈, 1~64자", "descLabel": "설명", "descPlaceholder": "이 스킬이 무엇을 하고 언제 사용하는지.", "compatPlaceholder": "sqlmap, python3 필요", "bodyLabel": "본문", "bodyHint": "(비워 두면 골격을 자동 생성)", "bodyPlaceholder": "## 실행 방법\n\n1. 먼저 오류를 탐지\n2. 블라인드 인젝션 유형 구분\n\n스크립트는 scripts/ 디렉터리에 둡니다.", "mcpSheetHint": "스킬을 로드할 때만 선택한 MCP 의 도구가 공개·잠금 해제됩니다.", "visSheetHint": "선택한 에이전트는 생성 직후 이 스킬을 볼 수 있습니다.", "creating": "생성 중…", "create": "생성" }, "changePasswordDialog": { "title": "비밀번호 변경", "description": "사용자 이름은 ARTEX 로 고정되어 있습니다. 먼저 현재 비밀번호를 입력해 인증해야 하며, 비밀번호를 변경한 뒤에도 이미 발급된 로그인 Token 은 만료될 때까지 유효합니다.", "currentPassword": "현재 비밀번호", "newPassword": "새 비밀번호", "confirmPassword": "새 비밀번호 확인", "cancel": "취소", "submit": "변경", "submitting": "변경 중…", "errorRequired": "현재 비밀번호와 새 비밀번호를 입력해 주세요", "errorMismatch": "두 번 입력한 새 비밀번호가 일치하지 않습니다", "success": "비밀번호를 변경했습니다", "failed": "비밀번호 변경에 실패했습니다: {msg}" }, "commands": { "title": "도구 실행", "searchPlaceholder": "도구 / 인자 검색…", "taskIdPlaceholder": "작업 ID", "stats": "통계", "colTime": "시간", "colTask": "작업", "colTool": "도구", "colInput": "입력", "colStatus": "상태", "empty": "도구 실행 기록이 없습니다", "failed": "실패", "success": "성공", "statsTitle": "도구 호출 통계", "statsDescFiltered": "현재 필터 조건의 전체 기록", "statsDescAll": "전체 도구 실행 기록", "unitTools": "개 도구", "unitCalls": "회 호출", "statsEmpty": "통계 데이터가 없습니다", "detailTitle": "도구 실행 상세", "inputLabel": "입력 Input", "outputLabel": "출력 Output", "emptyOutput": "(비어 있음)" }, "workspace": { "crumbRoot": "작업 공간", "newFolder": "새 폴더", "upload": "업로드", "refresh": "새로 고침", "colName": "이름", "colSize": "크기", "colMtime": "수정 시각", "colActions": "동작", "loading": "불러오는 중…", "empty": "빈 폴더", "download": "다운로드", "delete": "삭제", "downloadFile": "파일 다운로드", "tooLarge": "파일이 너무 커서 온라인 미리 보기·편집을 지원하지 않습니다.", "binary": "바이너리 파일이라 온라인 미리 보기·편집을 지원하지 않습니다.", "dirty": "저장되지 않은 변경", "synced": "동기화됨", "save": "저장", "saving": "저장 중…", "folderNamePlaceholder": "폴더 이름", "cancel": "취소", "create": "생성", "confirmDelete": "{kind, select, dir {폴더 「{name}」을(를) 삭제하시겠습니까? (하위 내용 전부 포함)} other {파일 「{name}」을(를) 삭제하시겠습니까?}}", "readDirFailed": "폴더 읽기 실패: {msg}", "openFileFailed": "파일 열기 실패: {msg}", "saved": "저장했습니다", "saveFailed": "저장 실패: {msg}", "deleted": "삭제했습니다", "deleteFailed": "삭제 실패: {msg}", "uploaded": "파일 {n}개를 업로드했습니다", "uploadFailed": "업로드 실패: {msg}", "folderCreated": "폴더를 만들었습니다", "createFailed": "생성 실패: {msg}", "downloadFailed": "다운로드 실패: {msg}" }, "llmRecords": { "title": "LLM 기록", "searchPlaceholder": "Session ID 검색…", "taskPlaceholder": "작업 선택…", "taskEmpty": "작업 기록이 없습니다", "deleteTaskConversations": "작업 대화 삭제", "selectTaskFirst": "먼저 위에서 작업을 선택하세요", "recording": "기록 중", "recordingOff": "꺼짐", "colTime": "시간", "colTask": "작업", "colLatency": "지연", "colStatus": "상태", "empty": "LLM 호출 기록이 없습니다", "taskBadge": "작업 #{id}", "rawTooltipHas": "provider 와 실제로 주고받은 HTTP 원문 보기", "rawTooltipNone": "이 기록은 해당 기능이 추가되기 전에 기록되어 원문이 없습니다", "raw": "원문", "loading": "불러오는 중…", "emptyContent": "(비어 있음)", "copyCopied": "복사했습니다", "copyTooltip": "내용 복사", "deleteTitle": "작업 「{taskId}」의 LLM 대화를 모두 삭제하시겠습니까?", "deleteDesc": "이 작업의 모든 LLM 호출 기록(요청·응답 원문 포함)을 영구히 삭제합니다. 이 작업은 되돌릴 수 없습니다.", "cancel": "취소", "deleting": "삭제 중…", "confirmDelete": "삭제" }, "assetSync": { "title": "자산 동기화", "subtitle": "외부 데이터 소스의 자산을 동기화해 등록합니다", "notReady": "데이터 소스가 준비되면 프로젝트·작업을 선택해 동기화할 수 있습니다.", "statusLoadFailed": "데이터 소스 상태 읽기 실패: {msg}", "dsTitle": "데이터 소스 상태", "refresh": "새로 고침", "created": "ScopeSentry 데이터 소스를 만들었습니다. 주소와 키를 입력하세요", "createFailed": "생성 실패: {msg}", "urlRequired": "MCP 주소를 입력하세요", "savedEnabled": "데이터 소스를 저장하고 활성화했습니다", "savedPending": "저장했습니다 (활성화 조건이 아직 충족되지 않았습니다)", "saveFailed": "저장 실패: {msg}", "notCreatedDesc": "아직 ScopeSentry 데이터 소스를 만들지 않았습니다. 만들면 자리 표시용 MCP 가 하나 추가됩니다 (주소·키가 비어 있고 비활성 상태).", "createDs": "데이터 소스 만들기", "notConfigured": "데이터 소스를 만들었으나 아직 설정하지 않았습니다. MCP 주소와 API Key 를 입력한 뒤 활성화하세요.", "notEnabled": "데이터 소스를 설정했으나 아직 활성화하지 않았습니다. 저장하면 자동으로 활성화됩니다.", "mcpUrl": "MCP 주소", "mcpUrlPlaceholder": "http://<호스트>:8082/mcp", "apiKeyLabel": "API Key (X-API-Key, 비워 두면 기존 값 유지)", "saveEnable": "저장하고 활성화", "toolsFound": "도구 {count}개를 발견했습니다", "badgeChecking": "확인 중…", "badgeNotCreated": "미생성", "badgeNotConfigured": "미설정", "badgeNotEnabled": "비활성", "badgeConnected": "연결됨", "badgeUnreachable": "접근 불가", "listLoadFailed": "목록 로드 실패: {msg}", "selectAtLeastOneTarget": "{dim, select, project {프로젝트를} other {작업을}} 하나 이상 선택하세요", "selectAtLeastOneType": "자산 유형을 하나 이상 선택하세요", "syncDone": "동기화 완료, 자산 {total}건을 등록했습니다", "syncFailed": "동기화 실패: {msg}", "loading": "불러오는 중…", "noData": "데이터 없음", "workbenchTitle": "동기화할 데이터 선택", "dimProject": "프로젝트 기준", "dimTask": "작업 기준", "syncAssetsLabel": "동기화할 자산:", "createCompany": "프로젝트별로 기업을 만들고 자산 범위에 기록", "searchProject": "프로젝트 이름 검색", "searchTask": "작업 이름 검색", "selectedCount": "{count}개 선택됨", "syncSelected": "선택 항목 동기화", "colProjectName": "프로젝트 이름", "colTaskName": "작업 이름", "colTag": "태그", "colAssetCount": "자산 수", "colStatus": "상태", "colTime": "시간", "pageNo": "{page} 페이지", "assetType": { "subdomain": "서브도메인", "service": "서비스", "app": "App", "ip": "IP" }, "resultCompanies": "신규·갱신 기업: {names}", "moreErrors": "… 오류 총 {count}건" }, "assets": { "title": "자산", "totalAssets": "총 {count}건", "deleteSelected": "선택 삭제 ({count})", "refresh": "새로 고침", "companyTable": { "name": "기업", "count": "자산 수", "scope": "자산 범위", "actions": "동작" }, "noScope": "범위 미설정", "deleteCompanyAria": "기업 삭제 {name}", "companyEmpty": "아직 등록된 기업이 없습니다. 오른쪽 위의 「기업 추가」를 눌러 자산 범위를 입력하면, 범위에 해당하는 자산을 시스템이 자동으로 귀속합니다.", "tab": { "company": "기업", "rootDomain": "루트 도메인", "ip": "IP", "subdomain": "서브도메인", "app": "애플리케이션", "service": "서비스", "endpoint": "엔드포인트" }, "col": { "domain": "도메인", "icp": "ICP 등록", "ownerCompany": "소속 기업", "cSegment": "C 대역", "boundDomains": "바인딩 도메인", "openPorts": "열린 포트", "rootDomain": "루트 도메인", "recordType": "레코드 유형", "recordValue": "레코드 값", "appName": "애플리케이션 이름", "category": "분류", "service": "서비스", "port": "포트", "statusCode": "상태 코드", "pageTitle": "제목", "fingerprint": "핑거프린트", "auth": "인증", "method": "메서드", "fullUrl": "전체 주소", "params": "파라미터" }, "unassigned": "미소속", "deleteAssetAria": "자산 삭제 {target}", "authFallback": "인증", "emptyData": "데이터가 없습니다", "loading": "불러오는 중…", "deleteDialog": { "title": "삭제 확인", "body": "자산 기록 {count}건을 영구히 삭제하며, 이 동작은 되돌릴 수 없습니다.", "confirm": "삭제 확인" }, "deleteCompanyDialog": { "title": "기업 삭제 · {name}", "body": "이 동작은 해당 기업과 그 자산 범위 설정을 영구히 삭제하며, 되돌릴 수 없습니다.", "alsoDeleteAssets": "이 기업에 속한 모든 자산도 함께 삭제", "alsoDeleteHint": "선택하지 않으면 자산은 그대로 두고 소속 관계만 해제합니다" }, "cancel": "취소", "saving": "저장 중…", "save": "저장", "deleting": "삭제 중…", "fixInvalidScope": "유효하지 않은 자산 범위를 수정해 주세요", "saveFailed": "저장 실패: {msg}", "reasonLabel": "소속 근거(선택)", "reasonPlaceholder": "예: 인증서 / whois / ASN 근거", "toast": { "deleted": "자산 {count}건을 삭제했습니다", "deleteFailed": "삭제 실패: {msg}", "companyDeletedWithAssets": "기업을 삭제하고 자산 {count}건도 함께 삭제했습니다", "companyDeleted": "기업을 삭제했습니다" }, "companyDialog": { "addButton": "기업 추가", "title": "기업 추가", "description": "기업과 그 자산 범위를 설정합니다. 키워드는 Agent 힌트로만 쓰이며 자산을 자동으로 귀속하지 않습니다.", "nameLabel": "기업 이름", "namePlaceholder": "예: Acme Corp (이름은 고유)", "nameRequired": "기업 이름을 입력해 주세요", "createdWithInvalid": "기업을 생성하고 범위 {added}건을 추가했습니다. {invalid}행은 무효입니다", "created": "기업을 생성하고 범위 {added}건을 추가했습니다", "exists": "기업이 이미 있습니다. 다른 이름을 사용해 주세요" }, "editScope": { "button": "편집", "title": "자산 범위 편집 · {name}", "description": "편집하면 기존 범위 전체를 대체합니다. ICP는 자산을 정확히 매칭하고, 기업 키워드는 Agent 힌트로만 쓰입니다.", "overwrite": "덮어쓰기 저장", "savedWithInvalid": "저장했습니다. {invalid}행은 무효입니다", "updated": "범위를 갱신했습니다. 총 {added}건" }, "appendScope": { "button": "추가", "title": "자산 범위 추가 · {name}", "description": "새 범위는 기존 범위에 추가됩니다. ICP는 자산을 정확히 매칭하고, 기업 키워드는 Agent 힌트로만 쓰입니다.", "scopeRequired": "추가할 범위를 입력해 주세요", "appended": "범위 {added}건을 추가했습니다" } }, "tasksPage": { "tab": { "current": "현재 작업", "archived": "보관됨" }, "filter": { "searchPlaceholder": "설명 / 목표 / ID 검색", "clearSearch": "검색어 지우기", "statusPlaceholder": "상태", "allStatus": "전체 상태", "categoryPlaceholder": "작업 분류", "allCategory": "전체 분류", "uncategorized": "미분류" }, "count": "{shown}/{total}건", "selected": "{count}건 선택됨", "clearSelection": "선택 해제", "batchPause": "일시정지 {count}", "batchResume": "재개 {count}", "batchArchive": "보관 {count}", "empty": { "noTasks": "작업이 없습니다. 오른쪽 위 「새 작업」을 눌러 시작하세요.", "noMatch": "일치하는 작업이 없습니다." }, "table": { "selectAllAria": "이 페이지 작업 전체 선택", "name": "이름", "description": "설명", "target": "목표", "status": "상태", "goalProgress": "목표 진행도", "findings": "취약점", "findingsSub": "심각/높음/중간/낮음", "findingsTitle": "심각 / 높음 / 중간 / 낮음", "runningWorker": "실행 중 Worker", "created": "생성 시각", "duration": "실행 시간", "actions": "동작" }, "delete": { "detailAssets": "자산 {n}건 삭제", "detailAssetsDetached": "공유 자산 연결 {n}건 해제", "detailTraffic": "트래픽 {n}건 삭제", "detailFiles": "작업 파일 삭제", "detailFindings": "취약점 {n}건 삭제", "detailLlm": "LLM 요청/응답 기록 {n}건 삭제", "summary": "작업을 삭제했습니다 ({details})", "summaryBare": "작업을 삭제했습니다" }, "toast": { "deleteWarn": "{summary}. 외부 데이터 일부를 정리하지 못했습니다: {warning}", "deleteFailed": "삭제 실패: {msg}", "paused": "작업 #{id}을(를) 일시정지했습니다", "resumed": "{queued, select, yes {작업 #{id}을(를) 재개했습니다 (대기열에 추가됨)} other {작업 #{id}을(를) 재개했습니다}}", "controlFailed": "{action, select, pause {일시정지 실패: {msg}} other {재개 실패: {msg}}}", "renamed": "작업 #{id}의 이름을 변경했습니다", "renameFailed": "이름 변경 실패: {msg}", "pinned": "작업 #{id}을(를) 고정했습니다", "unpinned": "작업 #{id}의 고정을 해제했습니다", "pinFailed": "{pinned, select, yes {고정 해제 실패: {msg}} other {고정 실패: {msg}}}", "archiveQueued": "작업 #{id}을(를) 보관 대기열에 추가했습니다", "archiveFailed": "보관 실패: {msg}" }, "row": { "selectAria": "작업 {id} 선택", "pinnedBadge": "고정됨", "unnamed": "이름 없음", "viewDetail": "작업 상세 보기", "tokenTitle": "입력 {input} · 캐시 {cache} · 출력 {output}", "tokenIn": "입", "tokenCache": "캐", "tokenOut": "출", "nameAria": "작업 #{id} 이름", "renameAria": "작업 #{id} 이름 변경", "renameTitle": "이름 변경", "pinAria": "작업 #{id} 고정", "unpinAria": "작업 #{id} 고정 해제", "pinTitle": "고정", "unpinTitle": "고정 해제", "resumeTask": "작업 재개", "pauseTask": "작업 일시정지", "controlDisabled": "이 상태에서는 일시정지하거나 재개할 수 없습니다", "archiveAria": "작업 #{id} 보관" }, "archiveBlock": { "queued": "대기 중인 작업은 먼저 일시정지해야 합니다", "running": "실행 중이거나 아직 끝나지 않은 작업은 먼저 일시정지해야 합니다", "inherited": "보관되지 않은 작업 #{id}이(가) 이 작업을 직접 상속하므로, 의존하는 작업을 먼저 보관하세요" }, "archiveDialog": { "title": "{count, plural, =1 {작업을 보관할까요?} other {작업 #개를 보관할까요?}}", "description": "보관하면 작업 스케줄링이 중단되고, 그래프·LLM 기록·파일과 전용 자산·트래픽이 로컬 콜드 스토리지로 압축됩니다. 보관이 끝나면 「보관됨」에서 다시 복원할 수 있습니다.", "cancel": "취소", "confirm": "보관 확인" }, "batch": { "deleted": "작업 {count}건을 삭제했습니다", "deletedDetails": "작업 {count}건을 삭제했습니다 ({details})", "deleteWarn": "{summary}. 외부 데이터 일부를 정리하지 못했습니다: {warnings}", "deleteFailed": "작업 {count}건 삭제 실패: {items}{truncated, select, yes { 등} other {}}", "archiveQueued": "작업 {count}건을 보관 대기열에 추가했습니다", "archiveFailed": "작업 {count}건을 보관할 수 없습니다: {items}", "controlLimit": "한 번에 최대 100개 작업까지만 제어할 수 있습니다", "paused": "작업 {count}건을 일시정지했습니다", "resumed": "{queued, select, yes {작업 {count}건을 재개했습니다 (일부 작업은 대기열에 들어갔습니다)} other {작업 {count}건을 재개했습니다}}", "controlFailed": "작업 {count}건 처리 실패: {items}{truncated, select, yes { 등} other {}}", "controlBatchFailed": "{action, select, pause {일괄 일시정지 실패: {msg}} other {일괄 재개 실패: {msg}}}", "moveLimit": "한 번에 최대 100개 작업의 분류까지만 변경할 수 있습니다", "moved": "작업 {count}건을 「{target}」(으)로 이동했습니다", "moveFailed": "작업 {count}건을 이동하지 못했습니다: {items}{truncated, select, yes { 등} other {}}", "moveCategoryFailed": "분류 변경 실패: {msg}", "statusChanged": "상태가 변경되었습니다", "taskGone": "작업이 더 이상 존재하지 않습니다" }, "upload": { "marker": "【업로드 파일(절대 경로)】", "hint": "worker 가 Read/Bash 로 경로를 열 수 있습니다:", "failed": "업로드 실패: {msg}" }, "taskRef": "작업 #{id}", "sort": { "default": "{label} 기준 내림차순으로 정렬합니다", "active": "{label} 기준 현재 {direction, select, asc {오름차순} other {내림차순}}입니다. 클릭하면 정렬 방향을 전환합니다" }, "concurrency": { "aria": "작업 동시 실행 설정", "trigger": "동시 실행 설정", "title": "작업 동시 실행 제한", "description": "동시에 실행하는 작업 수를 제한합니다. 상한에 도달하면 새 작업은 생성 순서대로 대기열에 들어가고, 빈자리가 생기면 자동으로 시작됩니다.", "enableLabel": "작업 동시 실행 제한 사용", "defaultOff": "기본값은 꺼짐", "limitLabel": "동시 실행 상한", "cancel": "취소", "save": "저장", "enabledToast": "동시 실행 제한을 켰습니다. 최대 {count}개 작업을 동시에 실행합니다", "disabledToast": "작업 동시 실행 제한을 껐습니다", "saveFailed": "저장 실패: {msg}" }, "archive": { "state": { "archive_queued": "보관 대기", "archiving": "보관 중", "archive_failed": "보관 실패", "ready": "복원 가능", "restore_queued": "복원 대기", "restoring": "복원 중", "restore_failed": "복원 실패", "delete_queued": "삭제 대기", "deleting": "삭제 중", "delete_failed": "삭제 실패" }, "compression": "{size} · {percent}% 절약", "deleteTitle": "작업 보관 {count}건을 영구 삭제할까요?", "deleteDescription": "보관 꾸러미 약 {size}과(와) 연관 데이터 스냅숏 {rows}건을 영구 삭제합니다. 이 동작은 되돌릴 수 없습니다.", "deleteCancel": "취소", "deleteConfirm": "영구 삭제", "loadFailed": "보관 목록을 불러오지 못했습니다: {msg}", "restoreQueued": "작업 {count}건을 복원 대기열에 넣었습니다", "restoreRejected": "작업 {count}건은 복원할 수 없습니다", "restoreFailed": "복원 실패: {msg}", "deleteQueued": "보관 {count}건을 영구 삭제 대기열에 넣었습니다", "deleteRejected": "보관 {count}건은 삭제할 수 없습니다", "permDeleteFailed": "영구 삭제 실패: {msg}", "retryQueued": "처리 대기열에 다시 넣었습니다", "retryFailed": "재시도 실패: {msg}", "searchPlaceholder": "작업 이름 / 설명 / ID 검색", "statePlaceholder": "처리 상태", "allStates": "전체 상태", "total": "보관 {count}건", "selected": "{count}건 선택됨", "restore": "복원 {count}", "deleteSelected": "영구 삭제 {count}", "selectPageAria": "이 페이지 보관 전체 선택", "colTask": "작업", "colOriginalStatus": "원래 상태", "colCategory": "분류", "colArchivedAt": "보관 시각", "colCompressedSize": "압축 크기", "colDataCount": "데이터 양", "colProcessingState": "처리 상태", "colActions": "동작", "emptyTitle": "보관된 작업이 없습니다", "emptyDescription": "일시정지했거나 종료된 작업을 현재 작업 목록에서 보관할 수 있습니다.", "selectRowAria": "작업 보관 #{id} 선택", "uncategorized": "미분류", "originalSizeTitle": "압축 전 {size}", "retryAria": "보관 동작 재시도", "retryTitle": "재시도", "restoreAria": "작업 복원", "restoreTitle": "작업 복원", "permDeleteAria": "보관 영구 삭제", "permDeleteTitle": "영구 삭제" }, "deleteOptions": { "legend": "연관 데이터 함께 정리", "allLabel": "전체 삭제", "allDescription": "아래의 연관 데이터를 모두 선택합니다. 자산·트래픽·파일·취약점·LLM 요청/응답 기록이 포함됩니다.", "assetsLabel": "연관 자산", "assetsDescription": "이 작업에만 속한 자산을 삭제합니다. 공유 자산은 현재 작업과의 연결만 해제합니다.", "trafficLabel": "연관 트래픽", "trafficDescription": "연관 자산의 정확한 호스트명을 기준으로 삭제합니다. 다른 작업이 아직 참조하는 공유 호스트 트래픽은 유지됩니다.", "filesLabel": "작업 파일", "filesDescription": "이 작업의 작업 디렉터리에 있는 업로드 파일·명령 출력·그 밖의 산출물을 삭제합니다.", "findingsLabel": "연관 취약점", "findingsDescription": "이 작업이 생성한 독립 취약점 기록과 취약점 리포트를 영구 삭제합니다.", "llmLabel": "LLM 요청/응답 기록", "llmDescription": "이 작업이 기록한 LLM 요청·응답·토큰·오류 상세를 영구 삭제합니다." }, "deleteDialog": { "aria": "작업 삭제", "title": "작업 #{id}을(를) 삭제할까요?", "descSuffix": "의 실행 기록과 탐색 경로가 영구 삭제됩니다.", "descNoTask": "이 작업의 실행 기록과 탐색 경로가 영구 삭제됩니다.", "cancel": "취소", "deleting": "삭제 중", "delete": "삭제" }, "move": { "trigger": "분류 변경", "title": "선택한 작업 {count}건의 분류 변경", "description": "대상 분류가 선택한 작업에 일괄 적용됩니다. 「미분류」를 고르면 현재 분류에서 빼냅니다.", "targetLabel": "대상 분류", "selectPlaceholder": "분류 선택", "uncategorized": "미분류", "noCategory": "아직 분류가 없습니다. 먼저 「분류 관리」에서 하나 만드세요.", "cancel": "취소", "move": "이동" }, "bulkDelete": { "trigger": "선택 삭제 {count}", "title": "선택한 작업 {count}건을 삭제할까요?", "description": "이 작업들의 실행 기록과 탐색 경로가 영구 삭제되며, 아래 정리 옵션이 선택한 작업에 일괄 적용됩니다.", "more": "…외 {count}건", "cancel": "취소", "progress": "삭제 중 {done}/{total}", "confirm": "작업 {count}건 삭제" }, "sourcePicker": { "atLimit": "작업은 최대 {max}개까지 연결할 수 있습니다", "placeholder": "작업 ID·설명·목표 검색", "empty": "일치하는 작업이 없습니다", "unknownTask": "알 수 없는 작업" }, "categoryPicker": { "unknown": "알 수 없는 분류", "placeholder": "분류를 검색하거나, 새 이름을 입력하고 엔터를 눌러 만드세요", "create": "분류 「{name}」 만들기", "hint": "이름을 입력해 분류를 검색하거나 만드세요", "created": "분류 「{name}」을(를) 만들었습니다", "createFailed": "분류 생성 실패: {msg}" }, "companyPicker": { "scopeDomain": "도메인", "scopeKeyword": "키워드", "scopeNone": "자산 범위가 설정되지 않음", "scopeEntry": "{label}: {value}", "scopeMore": "외 {count}건", "placeholder": "기업 이름이나 자산 범위 검색", "empty": "일치하는 기업이 없습니다", "fallback": "기업 #{id}", "assetCount": "자산 {count}개" }, "categoryManage": { "trigger": "분류 관리", "title": "작업 분류 관리", "description": "분류는 작업 필터링과 보관에 사용합니다. 수정해도 작업 실행에는 영향을 주지 않으며, 삭제하면 작업이 미분류로 옮겨집니다.", "newCategory": "새 분류", "uncategorized": "미분류", "nameLabel": "분류 이름", "namePlaceholder": "예: 외부망 평가", "renameHint": "현재 이 분류를 작업 {count}개가 사용 중입니다. 이름을 바꾸면 작업 목록에도 함께 반영됩니다.", "createHint": "만든 뒤 새 작업과 작업 목록 필터에서 사용할 수 있습니다.", "categoryTasks": "분류 작업", "uncategorizedTasks": "미분류 작업", "categoryTaskCount": "이 분류에는 작업 {count}개가 있습니다.", "uncategorizedTaskCount": "현재 작업 {count}개가 아직 분류되지 않았습니다.", "emptyCategoryTitle": "이 분류에는 작업이 없습니다", "emptyUncategorizedTitle": "미분류 작업이 없습니다", "emptyDescription": "작업이 분류에 들어가면 여기에 표시됩니다.", "dropHint": "놓아서 이동", "taskCount": "작업 {count}개", "dragAria": "작업 #{id} 끌기", "dragTitle": "작업 끌기", "deleteCategory": "분류 삭제", "close": "닫기", "saving": "저장 중", "create": "분류 만들기", "save": "변경 저장", "created": "분류를 만들었습니다", "updated": "분류를 수정했습니다", "createFailed": "분류 생성 실패: {msg}", "updateFailed": "분류 수정 실패: {msg}", "deleted": "분류를 삭제했고, 연관 작업은 미분류로 옮겼습니다", "deleteFailed": "분류 삭제 실패: {msg}", "targetMissing": "대상 분류가 없습니다. 새로고침 후 다시 시도하세요", "moved": "작업 #{id}을(를) 「{name}」(으)로 옮겼습니다", "moveFailed": "작업 이동 실패: {msg}", "deleteTitle": "분류 「{name}」을(를) 삭제할까요?", "unnamedCategory": "이름 없는 분류", "deleteDescription": "분류를 삭제하면 그 안의 작업 {count}개가 자동으로 미분류로 옮겨지고, 작업 데이터는 삭제되지 않습니다.", "deleteCancel": "취소", "deleting": "삭제 중", "deleteConfirm": "삭제" }, "create": { "newTask": "새 작업", "description": "테스트 대상과 목표를 입력하세요. 고급 설정은 필요할 때 펼칠 수 있습니다.", "nameLabel": "이름(선택)", "namePlaceholder": "알아보기 쉬운 이름을 지어 주세요. 예: Acme 웹사이트 침투", "categoryLabel": "작업 분류", "categoryHint": "선택 항목이고 분류는 하나만 지정합니다. 작업 목록 필터와 보관에 쓰이며 Agent 실행에는 영향을 주지 않습니다.", "descLabel": "설명", "descPlaceholder": "테스트 대상과 배경. 예: example.com 이 사이트를 테스트", "uploadButton": "파일 업로드", "uploadDone": "파일 {count}개를 업로드했고, 절대 경로를 설명 끝에 덧붙였습니다(편집 가능)", "uploadIdle": "여러 개 선택할 수 있습니다. 업로드하면 파일의 절대 경로를 설명에 덧붙여 worker 가 Read/Bash 로 엽니다", "goalLabel": "목표", "goalPlaceholder": "무엇을 달성할지. 예: 관리자 페이지 권한 획득, 서버 권한 획득", "sourceLabel": "연관 작업", "sourceHint": "작업은 최대 {max}개까지 연결합니다. 선택한 작업의 영속 블랙보드·자산 범위·관련 트래픽을 실시간 읽기 전용으로 상속하며, 새 작업은 독립 블랙보드에 기록합니다.", "companyLabel": "연관 기업 자산 범위", "companyHint": "작업을 만들 때 선택한 기업이 현재 보유한 자산을 「테스트 자산」에 추가하고, 도메인·IP·CIDR·ICP·기업 키워드를 범위 컨텍스트로 Agent 에 제공합니다. 의도를 자동으로 생성하거나 실행 목표를 강제로 바꾸지는 않습니다.", "interceptLabel": "작업 단위 자산 차단 / 허용 규칙(선택)", "interceptHint": "이 작업에만 적용되고 전역 규칙에는 쓰지 않습니다. 판정 순서는 이렇습니다. 먼저 「차단」 규칙(전역 포함)에 맞춰 보고 걸리면 테스트를 금지합니다. 걸리지 않고 이 작업에 「허용」 규칙이 설정돼 있으면 허용 규칙 하나에 맞아야 통과하며, 그렇지 않으면 마찬가지로 테스트를 허용하지 않습니다. 허용 규칙을 하나도 설정하지 않으면 화이트리스트를 적용하지 않습니다.", "llmLabel": "LLM 설정 체인", "llmHint": "목록 순서대로 장애 조치(failover)합니다. 첫 항목이 현재 설정이고, 할당량이 부족할 때만 다음 항목으로 전환합니다.", "advanced": "고급 설정", "advancedSub": "타임아웃 · 하트비트 · 첫 의도", "timeoutLabel": "작업 타임아웃(분, 선택)", "timeoutPlaceholder": "비우면 시간 제한 없음", "timeoutHint": "시각이 되면 우아한 마무리(각 agent 가 결과를 기록 반영 + planner 최종 판정)를 실행하고, 작업이 timeout 종료 상태로 들어갑니다.", "heartbeatLabel": "planner 하트비트(분)", "heartbeatPlaceholder": "기본값 10", "heartbeatHint": "직전 계획 종료 또는 작업 시작으로부터 이 시간이 지나고 그동안 트리거가 없으면, 한 차례 계획을 자동으로 실행합니다(멈춤 방지 + 실행 중인 worker 감독 재개). 하한은 10분입니다.", "seedLabel": "첫 의도를 바로 하달(설명+목표)", "seedHint": "켜면 생성 즉시 「설명+목표」를 하나의 의도로 하달해 worker 가 첫 계획을 기다리지 않고 바로 시작하고, 끝나면 planner 가 이어받아 판정·보완합니다. CTF 처럼 보통 work 하나로 바로 해결되는 상황에 권장하며, 끄면 표준대로 먼저 계획한 뒤 실행합니다.", "coverageLabel": "자산 커버리지 기능", "coverageHint": "기본값은 켜짐입니다. 테스트 커버리지를 계산·표시하고, 상황도에 테스트 진행을 보여 주며, 테스트 범위를 자동으로 누적합니다. 끄면 커버리지를 더 이상 계산·표시하지 않고, 상황도는 자산만 보여 주고 진행은 표시하지 않으며, agent 도 범위 관련 도구를 더 이상 받지 않습니다. 끄더라도 「연관 기업 자산 범위」에는 영향이 없습니다.", "cancel": "취소", "creating": "생성 중", "create": "생성", "validateRequired": "설명과 목표를 입력하세요", "validateSourceLimit": "소스 작업은 최대 {max}개까지 연결할 수 있습니다", "createdToast": "작업을 만들었습니다", "createFailed": "생성 실패: {msg}" } }, "chatSendMode": { "option": { "enter": "Enter 전송, Shift+Enter 줄바꿈", "ctrlEnter": "Ctrl+Enter 전송, Enter 줄바꿈" } }, "traffic": { "title": "트래픽", "subtitle": "전역 녹화 프록시 · 모든 HTTP 왕래", "recording": "녹화 중", "stopped": "중지됨", "total": "총 건", "picker": { "selectTarget": "대상 선택…", "selectTargetCount": "대상 선택 ({count})", "batchByTarget": "대상별 일괄 삭제", "sortAriaDesc": "데이터 패킷 수가 현재 내림차순입니다. 클릭하면 오름차순으로 전환합니다", "sortAriaAsc": "데이터 패킷 수가 현재 오름차순입니다. 클릭하면 내림차순으로 전환합니다", "sortTipDesc": "데이터 패킷 수 내림차순", "sortTipAsc": "데이터 패킷 수 오름차순", "selectAll": "전체 선택", "deselectAll": "전체 선택 해제", "empty": "트래픽 기록이 없습니다", "deleteSelected": "선택 삭제 ({count})" }, "toolbar": { "hostHint": "먼저 왼쪽에서 대상을 선택하거나 host 를 입력하세요", "deleteHost": "이 대상 삭제", "purgeTitle": "전체 트래픽을 삭제하고 저장 공간을 압축합니다", "purgeEmptyTitle": "현재 트래픽 기록이 없습니다", "purgeAll": "전체 비우기", "search": "전체 검색 (URL / 메서드 / 유형 / 상태 코드…)", "method": "메서드", "allMethods": "전체 메서드" }, "filters": { "advanced": "고급 필터", "body": "응답 내용 (본문 키워드, 3자 이상)", "path": "경로 (예: /api/user/…)", "status": "상태 코드", "allStatus": "전체 상태 코드", "respLen": "응답 길이", "min": "최소(B)", "max": "최대(B)", "clear": "필터 지우기" }, "selection": { "selected": "선택한 트래픽 {count}건", "linkToVuln": "취약점에 연결", "clear": "선택 비우기" }, "table": { "selectPage": "이 페이지 트래픽 선택", "time": "시간", "method": "메서드", "status": "상태 코드", "respLen": "응답 길이", "selectRow": "트래픽 {id} 선택", "loading": "불러오는 중…", "empty": "일치하는 트래픽이 없습니다." }, "detail": { "request": "요청 Request", "response": "응답 Response", "loadingMsg": "메시지를 불러오는 중…", "loadFailed": "(메시지를 불러올 수 없습니다)" }, "toast": { "purgedWithSpace": "트래픽 {deleted}건을 비웠습니다, 저장 공간 {space} 확보", "purged": "트래픽 {deleted}건을 비웠습니다", "purgeFailed": "비우기 실패: {msg}" }, "dialog": { "titlePurge": "전체 트래픽 기록을 비울까요?", "titleSelected": "선택한 {count}개 대상의 전체 트래픽을 삭제할까요?", "titleFilter": "이 대상의 전체 트래픽을 삭제할까요?", "descPurge": "전체 트래픽 기록 건(요청/응답 원문 포함)을 영구히 삭제하며, 현재 필터 조건은 무시합니다. 이 작업은 되돌릴 수 없습니다. 취약점에 연결된 트래픽 증거는 별도 증거 보관소에 저장되므로 영향을 받지 않습니다.

비운 뒤 저장 공간도 함께 압축해, 인덱스가 점유하던 디스크 공간을 시스템에 돌려줍니다. 이 동안 트래픽 녹화가 잠시 중단됩니다.", "descSelected": "대상 개()의 모든 트래픽 기록(요청/응답 원문 포함)을 영구히 삭제합니다. 이 작업은 되돌릴 수 없습니다.", "descFilter": "host 에 를 포함하는 모든 트래픽 기록(요청/응답 원문 포함)을 영구히 삭제합니다. 이 작업은 되돌릴 수 없습니다.", "cancel": "취소", "confirmPurge": "비우기 확인", "confirmDelete": "삭제 확인", "purging": "비우는 중…", "deleting": "삭제하는 중…" } }, "chat": { "live": "실시간", "custom": "사용자 지정", "emptyStart": "「{agent}」와(과) 대화를 시작하세요", "turnsTooltip": "에이전트 반복 횟수(모델 호출 횟수)", "turnsCount": "{turns}회", "loadEarlierHint": "위로 스크롤하면 이전 메시지를 불러옵니다…", "running": "실행 중", "untitledConversation": "새 대화", "newConversation": "새 대화", "filterByAgentAria": "에이전트별 대화 필터", "allAgents": "전체 에이전트", "agentOption": "{name}({count})", "selectAllAria": "현재 필터의 모든 대화 선택", "selectedCount": "{count}개 선택", "done": "완료", "multiSelect": "다중 선택", "emptyAll": "대화가 없습니다", "emptyForAgent": "이 에이전트의 대화가 없습니다", "loadMore": "더 보기", "deletedConversation": "대화가 삭제되었습니다", "loadingConversation": "해당 대화를 불러오는 중…", "totalCount": "총 {count}개", "filteredCount": "{shown} / {total}개", "conversationNotFound": "대화를 찾을 수 없습니다", "bulkDeleted": "{count}개 대화를 삭제했습니다", "bulkDeleteFailDetail": "#{id}({error})", "bulkDeleteFailed": "{count}개 대화 삭제 실패: {details}", "andMore": " 등", "bulkDeleteError": "일괄 삭제 실패: {msg}", "bulkDeleteTitle": "선택한 대화 {count}개를 삭제할까요?", "bulkDeleteDesc": "대화 메시지와 실행 기록이 함께 삭제되며, 이 작업은 되돌릴 수 없습니다.", "deleting": "삭제 중", "confirmDelete": "삭제 확인", "composer": { "removeAttachment": "제거", "uploadFile": "파일 업로드", "sendSideQuestion": "곁질문 보내기", "stopRun": "이번 실행 중지", "sendMessage": "메시지 보내기", "placeholder": "메시지를 입력하세요. @로 기록 인용, Enter로 전송", "placeholderRunning": "에이전트가 응답 중입니다. /btw로 질문할 수 있습니다…" }, "llmProfile": { "default": "기본값", "defaultNamed": "기본값({name})", "change": "변경", "select": "LLM 설정 선택" }, "agentPicker": { "placeholder": "에이전트 선택…" }, "item": { "selectAria": "대화 「{title}」 선택", "renameHint": "더블클릭하여 이름 변경", "pinnedAria": "고정됨", "runningTooltip": "에이전트 실행 중", "manageAria": "대화 「{title}」 관리", "rename": "이름 변경", "pin": "고정", "unpin": "고정 해제", "delete": "삭제", "deleteTitle": "대화 「{title}」을(를) 삭제할까요?", "deleteDesc": "이 작업은 되돌릴 수 없습니다.", "cancel": "취소" }, "group": { "expand": "「{name}」 펼치기", "collapse": "「{name}」 접기", "activeInside": "현재 대화가 이 그룹에 있습니다", "runningAria": "{count}개 대화 실행 중" }, "toast": { "sendFailed": "보내기 실패: {msg}", "uploadFailed": "업로드 실패: {msg}", "switchLlmFailed": "LLM 전환 실패: {msg}", "stopFailed": "중지 실패: {msg}", "deleteFailed": "삭제 실패: {msg}", "renameFailed": "이름 변경 실패: {msg}", "pinFailed": "고정 실패: {msg}", "unpinFailed": "고정 해제 실패: {msg}" } }, "linkTraffic": { "title": "취약점에 연결", "description": "선택한 트래픽 {count}건을 기존 취약점의 증거로 저장합니다.", "findLabel": "취약점 찾기", "searchPlaceholder": "이름 / 요약 / 취약점 유형", "loading": "불러오는 중…", "empty": "일치하는 취약점이 없습니다. 먼저 취약점을 등록하세요", "prevPage": "이전 페이지", "nextPage": "다음 페이지", "pageInfo": "{page} 페이지 · 총 {total}건", "selected": "선택한 취약점: #{id} {name}", "selectPrompt": "취약점을 선택하세요", "cancel": "취소", "saving": "저장 중…", "confirm": "연결 확인", "boundToast": "트래픽 {count}건을 취약점 #{id}에 연결했습니다" }, "sortableHead": { "sortBy": "{label} 기준 내림차순 정렬", "active": "{label} 현재 {direction, select, asc {오름차순} other {내림차순}} 정렬, 클릭하면 정렬 방향 전환" }, "sessions": { "token": { "inShort": "입", "cacheShort": "캐", "outShort": "출", "inLong": "입력", "cacheLong": "캐시", "outLong": "출력" }, "item": { "sourceTask": "출처 #{id}", "deleted": "삭제됨", "live": "실시간", "deleteTitle": "이 의도 삭제 (사유 입력 필요, 가삭제/완전 삭제 선택 가능)" }, "asset": { "current": "현재 자산: {label}", "sourceTask": "출처 작업 #{id}", "type": { "app": "앱", "endpoint": "엔드포인트", "ip": "IP", "root_domain": "루트 도메인", "service": "서비스", "subdomain": "서브도메인" }, "source": { "agent": "에이전트 발견", "anchor": "블랙보드 앵커", "api": "자산 API", "company": "기업 연관", "legacy": "과거 연관", "manual": "수동 추가", "system": "시스템 연관", "task": "작업 초기화" } }, "toast": { "uploadFailed": "업로드 실패: {msg}", "createSessionFailed": "새 세션 생성 실패: {msg}", "reasonRequired": "삭제 사유를 입력해 주세요", "workerPaused": "Worker #{id} 일시정지됨", "workerResumed": "Worker #{id} 재개됨, 재할당 대기 중", "hardDeleteExtra": "(의도 {intents}건 / 사실 {facts}건 / 취약점 {findings}건 포함)", "workerHardDeleted": "Worker #{id} 및 전용 하위 노드를 완전히 삭제했습니다{extra}", "workerSoftDeleted": "Worker #{id} 삭제됨 (사유 기록됨, 플래너가 이를 반영해 다시 계획합니다)", "workerActionFailed": "Worker 작업 실패: {msg}", "loadFailed": "불러오기 실패", "sendFailed": "전송 실패: {msg}", "retryLater": "잠시 후 다시 시도해 주세요", "messageTooLong": "메시지는 {max}자를 넘을 수 없습니다", "workerMessageSent": "Worker #{id} 에게 메시지를 전송했습니다. 즉시 실행을 재개합니다" }, "role": { "mainagent": "메인 에이전트", "planner": "플래너", "worker": "Workers", "system": "시스템 감사" }, "title": { "main": "메인 에이전트 · 세션 #{n}", "planner": "플래너 · 상황 판단", "system": "시스템 이벤트 · LLM 장애 전환" }, "resolution": { "unnamed": "이름 없는 설정", "current": "현재 설정: {label}", "unavailable": "모델을 사용할 수 없음", "noConfig": "사용 가능한 LLM 설정이 없습니다" }, "list": { "title": "세션 목록" }, "sse": { "live": "실시간", "reconnecting": "재연결 중", "titleLive": "실시간 연결 정상", "titleDown": "실시간 연결이 끊겨 자동으로 재연결 중입니다 (기록은 계속 볼 수 있습니다)" }, "taskTotal": "작업 합계", "tokens": { "full": "입력 {input} · 출력 {output} · 캐시 읽기 {cacheRead} · 캐시 쓰기 {cacheWrite}" }, "newMain": { "title": "새 메인 에이전트 세션 (컨텍스트를 비우고 작업 상태는 유지)", "aria": "새 메인 에이전트 세션", "label": "새로 만들기" }, "worker": { "loadOlder": "이전 Worker 더 불러오기", "noRunning": "실행 중인 Worker 세션이 없습니다.", "execSession": "Worker 실행 세션" }, "header": { "sourceTask": "출처 작업 #{id} · 읽기 전용 기록", "interactive": "상호작용 가능", "runDurationTitle": "실행 시간 (첫 단계 → 마지막 단계)", "olderHistoryTitle": "위로 스크롤해 이전 기록 불러오기", "olderHistoryLabel": "↑ 이전 기록" }, "deletedNotice": { "heading": "이 의도는 사용자가 삭제했습니다", "detail": "(실행이 중지되고 플래너에게 통지되었으며, 의도와 산출물은 보존되어 아래에서 기록을 볼 수 있습니다)", "reason": "삭제 사유: " }, "transcript": { "loadingMore": "이전 기록 불러오는 중…", "loadingActivity": "활동 스트림 불러오는 중…", "loadError": "불러오기 실패: {error}", "retry": "다시 시도", "emptyMain": "아직 대화가 없습니다. 아래에서 메인 에이전트에게 메시지를 보내 탐색 방향을 안내하거나 흐름에 개입하세요.", "emptyWorker": "활동 기록이 없습니다." }, "composer": { "attachmentRemove": "제거", "mainAria": "메인 에이전트에게 메시지 보내기", "mainBusyPlaceholder": "메인 에이전트가 실행 중입니다. /btw 로 질문할 수 있습니다…", "mainPlaceholder": "메인 에이전트에게 메시지 보내기, @ 로 취약점·자산 등 인용…", "uploadTitle": "파일 업로드", "sideQuestion": "곁질문 보내기", "stopTitle": "현재 실행 중지", "sendTitle": "메시지 보내기", "workerAria": "Worker #{id} 에게 메시지 보내기", "workerPlaceholder": "Worker #{id} 에게 메시지 보내기, @ 로 기록 인용, 실행 방향 조정…", "pauseTitle": "현재 Worker 일시정지", "resumeTitle": "메시지 없이 바로 계속 실행", "resumeAria": "바로 계속 실행", "resumeLabel": "바로 계속" }, "deleteDialog": { "title": "Worker #{id} 삭제?", "hardDesc": "완전 삭제는 해당 의도와 그 의도만 뒷받침하는 하위 노드를 물리적으로 제거하며(리프까지 연쇄 삭제해 고립 데이터를 남기지 않습니다), 공유 노드·목표·작업 루트 사실은 보존합니다. 이 동작은 되돌릴 수 없습니다. 플래너는 삭제 통지를 받고 이를 반영해 다시 계획합니다.", "softDesc": "가삭제는 해당 의도를 「삭제됨」으로 표시하고 삭제 사유를 기록하며, 의도 노드·실행 기록·등록된 사실과 취약점은 모두 보존됩니다. 플래너는 「해당 의도를 사용자가 삭제함 + 사유」를 받고 이를 반영해 다시 계획합니다.", "softLabel": "가삭제", "softHint": "데이터 보존, 추적 가능", "hardLabel": "완전 삭제", "hardHint": "연쇄 제거, 복구 불가", "reasonLabel": "삭제 사유 (필수)", "reasonPlaceholder": "이 의도를 삭제하는 이유를 적어 주세요. 예: 방향 판단 오류 / 목표가 이미 사라짐 / 다른 의도와 중복…", "back": "돌아가기", "confirmHard": "완전히 삭제", "confirmSoft": "삭제 확인" }, "newSession": { "title": "새 세션을 시작할까요?", "desc": "현재 세션은 보관되며(언제든 다시 전환 가능), 메인 에이전트는 깨끗한 컨텍스트로 이어서 진행합니다. 작업의 그래프·자산·목표는 영향을 받지 않습니다.", "cancel": "취소", "starting": "시작하는 중…", "start": "새 세션 시작" } }, "settingsPage": { "title": "시스템 설정", "subtitle": "전역 런타임 스위치", "save": "저장", "configured": "설정됨", "onSuffix": " · 켜짐", "offSuffix": " · 꺼짐", "toast": { "saveFailed": "저장 실패: {error}", "workersInvalid": "병렬 작업 수는 0보다 큰 정수여야 합니다", "workersSaved": "병렬 작업 에이전트 수를 저장했습니다 (이후 시작하는 작업에 적용됩니다)", "pythonSaved": "Python 인터프리터 설정을 저장했습니다", "bindingOn": "에이전트 자동 트래픽 연결을 켰습니다", "bindingOff": "에이전트 자동 트래픽 연결을 껐습니다", "noaOn": "noa 컨텍스트 압축을 켰습니다 (이후 시작하는 실행에 적용됩니다)", "noaOff": "noa 컨텍스트 압축을 껐습니다 (내장 압축으로 복원)", "webSearchSaved": "웹 검색 설정을 저장했습니다", "braveKeySaved": "Brave API Key를 저장했습니다", "tavilyKeySaved": "Tavily API Key를 저장했습니다", "proxySaved": "출구 프록시를 저장했습니다", "proxyCleared": "출구 프록시를 지웠습니다 (직접 연결로 전환)", "globalProxySaved": "전역 프록시를 저장했습니다", "globalProxyCleared": "전역 프록시를 지웠습니다 (직접 연결로 전환)", "testSuccess": "검색 테스트 성공 · {backend}에서 결과 {count}건 반환", "testFailed": "검색 테스트 실패: {error}", "testUnknownError": "알 수 없는 오류" }, "trafficCapture": { "title": "트래픽 캡처", "desc": "켜면 모든 에이전트의 HTTP 트래픽이 기록 프록시를 거쳐 전부 저장되고, 에이전트에 traffic_search / traffic_get 도구와 프록시 설정이 주입됩니다(프롬프트에 프록시 설명이 포함됩니다).

끄면(기본값) 어떤 트래픽도 기록하지 않습니다. 에이전트는 프록시 설정과 트래픽 도구를 받지 않고, 프롬프트에도 프록시 관련 내용이 포함되지 않습니다. 전환하면 에이전트가 즉시 다시 생성되어 적용됩니다.", "on": "켜짐 · 트래픽을 기록하고 프록시를 주입하는 중", "off": "꺼짐 · 기록·프록시 주입 안 함" }, "agentBinding": { "title": "에이전트 자동 트래픽 연결", "desc": "기본값은 꺼짐입니다. 켜면 취약점이 기록될 때 실행되는 리포트 에이전트가 기존 HTTP 요청/응답을 대조하고, 해당 트래픽을 연결한 뒤 리포트를 작성합니다. 패킷을 조회하고 도구를 추가로 호출하면 토큰 소비가 늘어납니다.

TCP이거나 패킷을 캡처하지 않았거나 일치하는 트래픽이 없을 때도 정상적으로 보고할 수 있습니다. 이 스위치는 트래픽 캡처, 수동 연결, 저장된 증거 조회에는 영향을 주지 않습니다. 다음 회차 에이전트부터 적용되며, 끄면 새로운 자동 연결을 즉시 거부합니다.", "on": "켜짐 · 토큰 소비가 늘어남", "off": "꺼짐 · 수동 연결은 계속 가능" }, "globalProxy": { "title": "전역 프록시", "desc": "모든 에이전트의 대상 트래픽이 이 프록시를 거쳐 나갑니다(출발지 IP 숨김 / 경유 서버 사용). http / https / socks5를 지원하며 user:pass 인증을 붙일 수 있습니다. 비우면 직접 연결입니다.

트래픽 캡처를 켜면 이 프록시가 기록 프록시의 상류가 됩니다(트래픽은 여전히 전부 저장되고 다시 이 프록시를 거쳐 나갑니다). 캡처를 끄면 에이전트의 bash / WebFetch 출력에 직접 주입됩니다. 웹 검색 프록시, LLM 프록시와는 서로 독립적입니다.

참고: socks5는 캡처를 끈 상태에서 각 명령줄 도구가 ALL_PROXY를 지원하는지에 의존합니다(curl은 되지만 일부 도구는 무시할 수 있습니다). 주로 socks5를 쓴다면 트래픽 캡처를 켜는 편이 좋습니다. 이 경로는 MITM이 직접 연결을 맺으므로 도구가 알아채지 못해도 안정적으로 적용됩니다.", "addrLabel": "프록시 주소", "placeholder": "socks5://user:pass@host:1080 또는 http://host:port (비우면 직접 연결)", "configured": "설정됨 · 모든 대상 트래픽이 이 프록시로 나감", "notConfigured": "설정 안 됨 · 대상 트래픽이 직접 연결로 나감" }, "constraints": { "title": "동작 제약 주입", "desc": "켜면 각 작업의 동작 제약(작업 개요의 「동작 제약」에서 관리하는 allow/deny 항목)을 해당 에이전트의 시스템 프롬프트에 덧붙여 탐색 범위를 한정합니다(예: 「현재 포트만 테스트」 「무차별 대입 금지」).

플래너(planner)와 워커(worker)에 각각 주입 여부를 제어할 수 있으며, 기본값은 모두 켜짐입니다. 전환하면 즉시 적용되고(다음 회차에 읽음) 에이전트를 다시 생성할 필요가 없습니다. 끄면 해당 에이전트는 더 이상 제약을 보지 않습니다.", "injectPlanner": "플래너(planner) 주입", "injectWorker": "워커(worker) 주입" }, "experimental": { "title": "실험 기능", "desc": "아직 검증 중인 기능으로 기본값은 꺼짐입니다. 에이전트 동작을 바꾸거나 안정성에 영향을 줄 수 있으니 영향을 파악한 뒤 켜세요.

noa 컨텍스트 압축: 모델이 긴 대화 기록을 직접 압축합니다(norma v0.4.0). 켜면 플랫폼에 연결된 네 종류 에이전트(플래너 / 워커 / 메인 에이전트 / 대화)가 내장 압축 대신 noa로 컨텍스트를 넘겨받으며, 압축 원문은 해당 작업의 작업 디렉터리에 보관되어 되짚어 보기 좋습니다. 전환하면 즉시 적용되고(이후 시작하는 실행에 적용) 에이전트를 다시 생성할 필요가 없습니다. 끄면 내장 압축으로 즉시 복원됩니다.", "noaLabel": "noa 컨텍스트 압축" }, "webSearch": { "title": "웹 검색", "desc": "웹 검색의 마스터 스위치 + 소스 설정입니다. 켜야만 각 에이전트 설정에서 web_search 사용 여부를 개별로 선택할 수 있습니다(제목/링크/요약만 반환하고 본문은 가져오지 않습니다. 본문 수집은 WebFetch가 담당합니다). 웹 검색은 기록 프록시를 거치지 않으며 트래픽 캡처와 독립적입니다.

소스는 DuckDuckGo(ddgs)(Key 불필요), Brave(무료판)(Brave API Key 입력 필요), Tavily(Tavily API Key 입력 필요), DeepSeek(현재 LLM 설정 재사용) 중에서 고를 수 있습니다. 마스터 스위치가 꺼져 있으면 각 에이전트의 웹 검색 스위치를 쓸 수 없습니다.", "on": "마스터 스위치 켜짐 · 각 에이전트 설정에서 개별로 켤 수 있음", "off": "꺼짐 · 각 에이전트에서 웹 검색을 켤 수 없음", "sourceLabel": "검색 소스", "sourcePlaceholder": "소스 선택", "sourceDdgs": "DuckDuckGo (ddgs · 무료, Key 불필요)", "sourceBrave": "Brave (무료판 · Key 필요)", "sourceTavily": "Tavily (Key 필요)", "sourceDeepseek": "DeepSeek (공식)", "deepseekTitle": "DeepSeek 공식 웹 검색", "deepseekDesc1": "이 소스는 현재 활성화된 LLM 설정을 그대로 재사용합니다. 그래서 DeepSeek 공식 모델만 지원하며, 그 설정은 반드시 anthropic 프로토콜을 사용해야 합니다. DeepSeek의 OpenAI 프로토콜 엔드포인트는 서버 측 검색을 지원하지 않습니다. LLM 설정을 바꾸면 이 소스가 작동하지 않을 수 있습니다.", "deepseekDesc2": "다른 소스와 달리 검색을 DeepSeek 서버가 실행합니다. 검색할 때마다 모델 호출이 한 번 더 소비되고(토큰 비용 발생), 검색 요청은 위의 출구 프록시를 거치지 않으며 트래픽 기록에도 포함되지 않습니다. 반환 결과에는 제목과 링크만 있고(요약 없음), 본문이 필요하면 WebFetch가 가져옵니다.", "deepseekDesc3": "위 조건을 충족하는지는 직접 확인해야 하며 시스템은 가로막지 않습니다. 아래 「검색 테스트」 버튼으로 실제로 한 번 돌려 확인할 수 있습니다.", "braveKeyLabel": "Brave Search API Key", "braveKeyPlaceholderSet": "설정됨 (비우면 유지)", "braveKeyPlaceholderUnset": "Brave API Key 입력", "braveNeedsKey": "Brave를 선택했지만 아직 Key를 설정하지 않았습니다. Key를 저장하기 전에는 검색 도구가 켜지지 않습니다.", "braveQuota": "무료판 사용량은 월 약 2,000회입니다. https://brave.com/search/api/ 에서 Key를 발급받으세요.", "tavilyKeyLabel": "Tavily Search API Key", "tavilyKeyPlaceholderSet": "설정됨 (비우면 유지)", "tavilyKeyPlaceholderUnset": "Tavily API Key 입력 (tvly-…)", "tavilyNeedsKey": "Tavily를 선택했지만 아직 Key를 설정하지 않았습니다. Key를 저장하기 전에는 검색 도구가 켜지지 않습니다.", "tavilyGetKey": "https://tavily.com 에서 가입하고 API Key를 발급받으세요.", "proxyLabel": "출구 프록시 (선택)", "proxyPlaceholder": "http://host:port 또는 socks5://host:port (비우면 직접 연결)", "proxyHint": "검색 엔드포인트 접속에만 쓰는 독립 출구 프록시입니다(VPN/SOCKS 등). 트래픽을 기록하는 MITM 프록시와는 무관하며, 네트워크가 막혔을 때 이 프록시를 거쳐 접속합니다.", "testHint": "현재 설정(소스 + 프록시 + Key)으로 「test」를 실제로 한 번 검색해 사용 가능한지 확인합니다.", "testRunning": "테스트 중…", "testButton": "검색 테스트" }, "python": { "title": "사용자 정의 스크립트 · Python 인터프리터", "desc": "사용자 정의 script 유형 도구가 이 인터프리터로 Python을 실행합니다. 시작할 때 자동으로 감지하며(python3 우선), 여기에 venv나 특정 버전의 절대 경로를 직접 입력할 수 있고, 비우면 실행 시 자동으로 감지합니다.", "placeholder": "/usr/bin/python3 (비우면 자동 감지)", "detect": "다시 감지" }, "workers": { "title": "작업 병렬성 · 워크 에이전트 수", "desc": "각 작업에서 병렬로 실행되는 워크 에이전트 수입니다(기본값 3). 값이 클수록 동시에 더 많이 탐색하고 소비도 커집니다. 수정하면 이후 시작하는 작업에 적용되고, 실행 중인 작업은 영향을 받지 않습니다." }, "sendKey": { "title": "세션 입력창 전송 키", "desc": "대화 페이지와 작업 상세의 메인 에이전트 세션 입력창이 이 설정을 공유하며, 선택하면 즉시 적용되고 저장할 필요가 없습니다.

이 설정은 이 브라우저에만 저장되고 계정과 동기화되지 않으므로, 브라우저를 바꾸거나 사이트 데이터를 지우면 다시 설정해야 합니다.", "label": "전송 방식" }, "update": { "title": "버전과 업데이트", "desc": "GitHub에서 새 버전을 확인하고 설치합니다. 업데이트하면 프로그램이 재시작되고 실행 중인 작업이 중단됩니다.", "currentVersion": "현재 버전", "latestVersion": "최신 버전", "modeDocker": "Docker", "modeStandalone": "독립 실행 프로그램", "changelog": "변경 로그", "connectError": "GitHub에 연결할 수 없습니다: {error} 위에서 전역 프록시를 설정한 뒤 다시 시도할 수 있습니다.", "noAsset": "{latest}에는 {os}/{arch}용 릴리스 패키지가 없어({asset} 누락) 자동으로 업데이트할 수 없습니다.", "willDownloadPrefix": "다운로드 대상: ", "willDownloadSize": " ({size})", "willDownloadSuffix": ". SHA256 검증과 스모크 테스트를 통과한 뒤에만 교체하며, 실패하면 현재 버전을 자동으로 유지합니다.", "upToDate": "이미 최신 버전입니다.", "dockerNote": "Docker 환경의 업데이트는 프로그램 본체만 교체하고 이미지의 playwright / nmap 등 도구 체인은 갱신하지 않습니다. 또한 docker compose up -d 명령으로 컨테이너를 재생성하면 이미지에 포함된 버전으로 되돌아갑니다. 이미지까지 함께 업그레이드하려면 docker compose pull artex && docker compose up -d artex 명령을 실행하세요.", "restarting": "재시작하고 새 버전을 적용하는 중입니다. 잠시 기다려 주세요 (페이지가 자동으로 새로고침됩니다)…", "check": "업데이트 확인", "updateToVersion": "{latest} 버전으로 업데이트", "updateNow": "지금 업데이트", "rollback": "이전 버전으로 롤백", "footer": "원클릭 업데이트는 데몬 스크립트가 프로그램을 재시작하는 기능에 의존합니다. start.sh(Windows는 start.bat)로 ARTEX를 시작하세요. artex 본체를 직접 실행하면 프로그램이 종료된 뒤 자동으로 다시 시작되지 않습니다.", "toast": { "checkFailed": "업데이트 확인 실패: {error}", "found": "새 버전 {latest} 발견", "upToDate": "이미 최신 버전입니다", "updated": "{version} 버전으로 업데이트했습니다. 페이지를 다시 불러오는 중", "restartTimeout": "서비스 재시작 대기 시간이 초과되었습니다. 백엔드 로그를 확인하거나 artex가 start.sh / start.bat로 시작되었는지 확인하세요.", "updateFailed": "업데이트 실패: {error}", "startFailed": "업데이트 시작 실패: {error}", "rollbackSwitched": "이전 버전으로 전환했습니다. 재시작 중…", "rollbackFailed": "롤백 실패: {error}", "preparing": "준비 중…" }, "confirm": { "title": "{latest} 버전으로 업데이트할까요?", "restart": "업데이트하면 프로그램이 재시작되고 실행 중인 작업이 중단됩니다.", "docker": "참고: 컨테이너 내 업데이트는 프로그램 본체만 교체하며, 이미지의 playwright / nmap 등 도구 체인은 갱신하지 않습니다. 새 버전이 새 도구에 의존하면 docker compose pull로 바꿔 실행하세요.", "rollback": "이전 버전으로 롤백할까요?\n\n프로그램이 재시작되고 실행 중인 작업이 중단됩니다.\n참고: 데이터베이스 구조는 되돌아가지 않으며, 이전 버전이 새 버전에서 기록한 데이터를 인식하지 못할 수 있습니다." } } }, "llmPage": { "page": { "subtitle": "모든 에이전트가 공유하는 형식 / 모델 / 속도 제한 설정입니다. 카드를 클릭하면 편집하고, 별표는 현재 활성 설정입니다.", "poolConfig": "순환 설정", "enabled": "켜짐", "new": "새로 만들기", "tab": { "profiles": "모델 설정", "retry": "재시도와 백오프" }, "empty": "아직 모델 설정이 없습니다. 오른쪽 위 「새로 만들기」로 첫 설정을 추가하세요.", "toast": { "activated": "활성화함: {name}", "activateFailed": "활성화 실패: {msg}", "cannotDeleteActive": "현재 활성 설정은 삭제할 수 없습니다", "deleted": "삭제함: {name}", "deleteFailed": "삭제 실패: {msg}" } }, "card": { "proxy": "프록시 {proxy}", "thinking": "사고 {effort}", "thinkingOff": "끔", "excluded": "순환 제외", "priority": "우선순위 {priority}", "active": "활성됨", "activate": "활성으로 설정", "deleteAria": "설정 삭제" }, "health": { "noKey": { "label": "Key 미설정", "hint": "API Key가 비어 있어 호출할 수 없습니다" }, "tripped": "서킷 차단됨", "trippedCooldown": "서킷 차단됨 · {cooldown}", "degraded": "비정상 · 실패 {fails}회", "ok": "정상" }, "pool": { "title": "LLM 순환 · 장애 전환", "desc": "켜면 모델을 지정하지 않은 에이전트가 현재 설정을 쓸 수 없을 때(잔액 부족 / Key 만료 / 호출 제한 / 서비스 오류) 자동으로 다음 설정으로 전환합니다.", "enable": { "label": "순환 사용", "hint": "기본값은 꺼짐입니다. 꺼져 있으면 항상 활성 설정만 쓰고, 실패하면 그대로 실패합니다.", "aria": "LLM 순환 스위치" }, "bindFallback": { "label": "지정 모델이 실패해도 폴백", "hint": "기본값은 꺼짐: 에이전트나 작업이 특정 설정을 지정하면 그 설정만 쓰고, 실패하면 그대로 실패합니다(다른 모델로 몰래 바꾸지 않습니다). 켜면 지정한 설정이 실패할 때 아래 순환 체인으로 폴백합니다.", "aria": "지정 설정 실패 폴백 스위치" }, "order": { "label": "순환 순서", "tooFew": "현재 사용할 수 있는 설정이 {n}개뿐이라 순환이 동작하지 않습니다. API Key를 채우고 순환에 참여하는 설정이 최소 2개는 필요합니다." }, "recoverAll": "전체 복구", "badge": { "active": "활성", "excluded": "순환 제외" }, "cooldown": "쿨다운 {cooldown}", "consecutiveFails": "연속 실패 {fails}회", "recoverNow": { "aria": "즉시 복구", "title": "즉시 복구: 서킷 차단을 해제하고 다음 호출에서 이 설정을 다시 시도합니다" }, "priority": "우선순위 {priority}", "empty": "설정이 없습니다", "note": "활성 설정은 항상 1순위이고, 나머지는 우선순위가 높은 순입니다(각 설정에서 지정). 어떤 설정이 실패하면 쿨다운에 들어가고(60s → 5min → 30min), 쿨다운 동안에는 건너뛰며, 복구되면 자동으로 다시 포함됩니다. 현재 요청이 컨텍스트 창에 들어가지 않는 설정은 건너뜁니다. 모델을 지정한 에이전트와 작업은 기본적으로 순환에 참여하지 않습니다.", "toast": { "enabled": "LLM 순환을 켰습니다", "disabled": "LLM 순환을 껐습니다", "fallbackUpdated": "폴백 설정을 업데이트했습니다", "setFailed": "설정 실패: {msg}", "recoveredOne": "해당 설정을 복구했습니다", "recoveredAll": "모든 설정을 복구했습니다", "recoverFailed": "복구 실패: {msg}" } }, "profile": { "titleNew": "모델 설정 새로 만들기", "titleEdit": "편집: {name}", "activeBadge": "활성", "descNew": "새로 만들어도 자동으로 활성화되지 않습니다. 카드에서 「활성으로 설정」을 눌러 사용하세요.", "descEdit": "수정한 뒤 저장을 누르세요. 활성 설정은 저장하면 모든 에이전트에 즉시 적용됩니다.", "name": { "label": "이름", "placeholder": "예: OpenAI 프로덕션" }, "format": { "label": "형식", "placeholder": "형식 선택" }, "model": { "label": "모델", "loadTitle": "API에서 사용 가능한 모델 불러오기" }, "baseUrl": { "label": "Base URL (선택)" }, "proxy": { "label": "프록시 (선택)", "hint": "LLM 아웃바운드 요청만 이 프록시를 거칩니다. http/https/socks5를 지원하며 계정·비밀번호를 포함할 수 있습니다(예: socks5://user:pass@host:port, 비밀번호에 특수문자가 있으면 URL 인코딩 필요). 비워 두면 프록시를 쓰지 않습니다(직접 연결)." }, "sessionHeader": { "label": "사용자 지정 세션 헤더 (선택)", "placeholder": "예: x-session-id (비우면 보내지 않음)", "hint": "헤더 이름을 채우면 매 요청에 이 HTTP 헤더가 실리고, 헤더 값은 현재 세션의 session id로 자동 설정됩니다(chat 세션은 conv-12, worker는 exp3-worker-i87 등). session-id 헤더로 프롬프트 캐시 / 스티키 라우팅을 하는 게이트웨이용입니다. 같은 세션은 여러 턴에서 안정적이고, 다른 세션끼리는 서로 다릅니다. 비우면 보내지 않습니다." }, "apiKey": { "placeholderSet": "설정됨({hint}), 비우면 그대로 유지" }, "rps": "초당 속도 제한", "rpm": "분당 속도 제한", "cw": "컨텍스트 창(K)", "rateHint": "속도 제한 0 = 무제한, 모든 에이전트가 공유합니다. 컨텍스트 창 단위는 K(천 token), 0 = 기본 200K, 상한 1000(즉 1M)입니다. 너무 크게 잡으면 압축이 트리거되지 않습니다.", "priority": { "label": "순환 우선순위", "hint": "숫자가 클수록 먼저 선택됩니다. 활성 설정은 이 값과 무관하게 항상 1순위입니다. 우선순위가 같은 설정은 번갈아 앞에 서서 자연스럽게 할당량을 나눠 씁니다." }, "exclude": { "label": "순환 제외", "hint": "켜면 장애 전환 대상이 되지 않습니다(에이전트나 작업이 명시적으로 지정하면 여전히 사용 가능). 「특정 에이전트 전용이라 남이 실패할 때 소모되지 않게」 하려는 값비싼 설정에 적합합니다.", "aria": "순환 제외" }, "streaming": { "label": "스트리밍 출력 · streaming", "hint": "켜면(기본) 스트리밍 SSE로 동작해 실행 중 실시간 진행 상황과 실시간 token 수를 볼 수 있습니다. 끄면 진짜 비스트리밍(stream:false, 완성된 응답을 한 번에 반환)으로 동작해 일부 게이트웨이의 불량 SSE 구현(빈 프레임 / 사고 필드 누락 프레임)을 우회할 수 있지만, 실행 중 실시간 진행 상황을 잃습니다.", "aria": "스트리밍 출력" }, "maxTokens": { "label": "출력 상한 · max tokens", "hint": "한 번의 응답에서 최대 몇 token까지 생성할지로, 매 요청에 함께 보냅니다. 0(기본) = 이 필드를 보내지 않고 서버 기본값을 따릅니다. 이는 위의 「컨텍스트 창」과는 다릅니다. 그쪽은 모델 전체 용량으로, 로컬에서 압축 임계값을 계산할 때만 씁니다. 너무 작게 잡으면 추론 모델이 사고 단계에서 잘려 한 글자도 답하지 못합니다." }, "maxTokensField": { "label": "상한 필드 이름", "opt": { "default": "max_tokens(기본)" } }, "maxTokensFieldHint": { "openai": "상한을 어느 키로 보낼지입니다. max_tokens가 기본이고 대부분의 호환 게이트웨이는 이것만 인식합니다. 반면 OpenAI 공식 추론 모델(o 계열 / GPT-5)은 max_completion_tokens만 인식하고, max_tokens를 받으면 바로 unsupported_parameter 오류를 냅니다.", "anthropic": "openai 형식에서만 선택할 수 있습니다. Anthropic의 필드 이름은 max_tokens로 고정입니다.", "openai-responses": "openai 형식에서만 선택할 수 있습니다. Responses API의 필드 이름은 max_output_tokens로 고정입니다." }, "thinkingType": { "label": "사고 스위치 · thinking.type", "hint": "thinking 필드를 보낼지 제어합니다. 보내지 않음=이 필드를 빼고 보냄(MiniMax 등 지원하지 않는 모델과 호환); 끔=disabled 전송; 켬=enabled 전송. 아래 강도와는 서로 독립입니다.", "opt": { "none": "보내지 않음(기본)", "disabled": "끔", "enabled": "켬" } }, "effort": { "label": "사고 강도 · reasoning_effort", "hint": "독립적인 강도 단계입니다(OpenAI reasoning_effort / Anthropic output_config.effort). 일부 인터페이스는 thinking 필드가 없고 강도만으로 사고를 켤 수 있어, 사고 스위치를 보내지 않고 강도만 따로 설정할 수 있습니다.", "opt": { "none": "보내지 않음(기본)" } }, "testing": "테스트 중…", "testConnection": "연결 테스트", "create": "새로 만들기", "save": "저장", "toast": { "modelsLoaded": "모델 {n}개를 불러왔습니다", "loadModelsFailed": "모델 불러오기 실패: {error}", "noModels": "모델을 가져오지 못했습니다", "loadModelsError": "모델 불러오기 오류: {msg}", "testOk": "연결 성공 · {latency}ms · {model}", "testReply": "응답: {reply}", "testFailed": "연결 실패: {error}", "unknown": "알 수 없음", "testError": "테스트 오류: {msg}", "nameModelRequired": "이름과 모델을 입력하세요", "created": "새로 만들었습니다: {name}(카드에서 「활성으로 설정」을 눌러 사용)", "savedActive": "저장했습니다. 활성 설정은 즉시 적용되며 재시작이 필요 없습니다", "saved": "저장했습니다", "saveFailed": "저장 실패: {msg}" } }, "retryLayer": { "connect": { "title": "연결 재시도", "where": "SDK · 200을 받기 전", "trigger": "연결되지 않거나 아직 200을 받지 못한 경우: 연결 리셋 / 읽기·쓰기 타임아웃 / DNS 실패 등 네트워크 계층 오류, 그리고 HTTP 408·429·500·502·503·504.", "skips": "그 밖의 상태 코드(400 / 401 / 403 / 404 / 413 / 422 등)는 확정적 거부라 다시 보내도 똑같이 실패하므로 바로 위로 올립니다.", "desc": "같은 요청을 그대로 다시 보냅니다. 스트림이 일단 시작되면(이미 200을 받음) 도중에 끊겨도 이 층이 담당하지 않습니다.", "attemptsLabel": "재시도 횟수", "defInterval": "0.5s→1s→2s 지수(최대 8s)", "offHint": "-1 = 한 번도 재시도하지 않고 실패를 즉시 위로 올림" }, "empty": { "title": "빈 응답 재시도", "where": "SDK · openai 형식 전용", "trigger": "HTTP 200이고 finish_reason은 정상 stop이지만 응답 전체에 내용 블록이 하나도 없는 경우입니다. 게이트웨이 빈 프레임, 사고 필드 누락 프레임, 샘플링 딸꾹질이 모두 이렇게 나타납니다.", "skips": "max_tokens로 잘려서 내용이 없는 경우는 제외합니다(그건 출력 상한을 높여 해결해야 하고, 다시 보내면 또 같은 벽에 부딪힙니다).", "desc": "전체 prompt를 다시 보내므로 긴 컨텍스트에서는 비용이 크니 횟수를 크게 잡지 않는 게 좋습니다.", "attemptsLabel": "재시도 횟수", "defInterval": "0.5s→1s→2s 지수(최대 8s)", "offHint": "-1 = 빈 응답을 그대로 내보냄" }, "stream": { "title": "동일 provider 안전 구간 재시도", "where": "본 프로젝트 · 출력을 전달하기 전", "trigger": "스트림이 이미 수립된(200을 받은) 뒤에 생긴 문제: 연결이 도중에 끊김, 공급자 overloaded, 스트림 내부의 429 / 5xx 오류 이벤트이며, 아직 token을 하나도 호출자에게 전달하지 않은 경우입니다.", "skips": "할당량 소진(402 / insufficient_quota, 순환이 설정을 바꿔 처리), 컨텍스트 초과(413 / context length, 압축이 처리), 400 / 401 / 403 / 404 / 422 확정적 거부는 재시도하지 않습니다.", "desc": "같은 설정에서 같은 요청을 다시 재생합니다. 아직 어떤 출력도 전달하지 않았으므로 재생해도 모델 출력이나 도구 실행이 중복되지 않습니다.", "attemptsLabel": "재시도 횟수", "defInterval": "0.5s→1s 지수(최대 4s)", "offHint": "-1 = 스트림이 끊기면 바로 바깥 층의 의도 재실행에 넘김" }, "breaker": { "title": "순환 서킷 차단", "where": "본 프로젝트 · 프로세스 단위, 전역 하나", "trigger": "일시적 실패(429·5xx·네트워크 오류)가 연속으로 임계값까지 쌓이면 차단합니다. 잔액 부족(402), 키 만료(401 / 403), 모델 없음(404) 같은 확정적 실패는 임계값을 보지 않고 처음부터 바로 차단합니다.", "skips": "한 번 성공하면 0으로 초기화되므로, 가끔 말썽을 부리는 설정이 서서히 쌓여 차단되지는 않습니다.", "desc": "차단되면 쿨다운에 들어가고, 쿨다운 동안 순환은 이 설정을 건너뜁니다. 상태는 DB에 저장되어 재시작해도 사라지지 않습니다.", "attemptsLabel": "연속 몇 번 실패하면 차단", "defInterval": "1min→5min→30min 단계", "offHint": "-1 = 일시적 실패로는 절대 차단하지 않음(확정적 실패는 여전히 차단)" }, "intent": { "title": "의도 재실행", "where": "본 프로젝트 · 프로세스 단위, 전역 하나", "trigger": "앞의 여러 층이 막지 못한 경우: worker가 model_error로 끝남. 안쪽 재시도를 모두 소진했거나, 스트림이 이미 출력을 전달하기 시작한 뒤에 끊긴 경우입니다(그때는 재생이 안전하지 않아 전체를 다시 돌릴 수밖에 없습니다).", "skips": "할당량 소진은 이미 순환이 설정을 바꿔 처리하므로 여기서 재실행하지 않습니다. 작업이 일시정지 / 종료 / 마무리에 들어가면 즉시 양보하고 백오프 시간을 차지하지 않습니다.", "desc": "의도 전체를 처음부터 다시 한 번 실행합니다. 가장 바깥 층이라, 한 번 재실행하면 안쪽 여러 층의 횟수가 다시 한 번 곱해집니다.", "attemptsLabel": "재실행 횟수", "defInterval": "고정 3s", "offHint": "-1 = 재실행하지 않고 해당 의도를 바로 blocked로 판정" } }, "retry": { "defaultN": "기본 {n}", "triggerLabel": "트리거", "skipsLabel": "이 층을 거치지 않음", "intervalMs": "간격 ms", "defaultBackoff": "기본 백오프", "fixed": "고정 {human}", "emptyLine": "비워 두면 기본값을 사용합니다. {hint}.", "override": { "label": "재시도 재정의", "hint": "이 설정에만 적용되어 「재시도와 백오프」의 전역 기본값을 재정의합니다. 각 칸을 비우면 전역을 따릅니다. 횟수에 -1을 넣으면 이 층의 재시도를 끕니다. 간격을 채우면 지수 백오프 대신 고정 간격을 씁니다. 서킷 차단과 의도 재실행은 프로세스 단위라 전역 페이지에서만 조정할 수 있습니다." }, "loading": "재시도 정책을 불러오는 중…", "intro": "모델 호출 한 번의 실패는 안쪽에서 바깥쪽 순서로 다섯 층의 재시도를 차례로 거칩니다: 연결 → 빈 응답 → 동일 provider 안전 구간 → 순환 서킷 차단 → 의도 재실행. 안쪽 층을 다 써야 바깥쪽 차례가 오므로 횟수는 서로 곱해집니다. 각 층을 최대로 올리면 한 번의 흔들림이 수십 번의 요청을 태울 수 있습니다. 전부 비우면 현재 기본값이며, 이 페이지가 없을 때의 동작과 완전히 같습니다. 앞 세 층은 각 모델 설정에서 따로 재정의할 수 있습니다.", "save": "저장", "resetAll": "전부 기본값으로 복구", "toast": { "loadFailed": "재시도 정책 읽기 실패: {msg}", "saved": "저장했습니다. 즉시 적용됩니다(지금 진행 중인 이번 호출은 이전 값을 그대로 씁니다)", "saveFailed": "저장 실패: {msg}" } } }, "notifyPage": { "title": "알림 발송", "subtitle": "취약점을 발견하면 DingTalk · Feishu · WeCom 등의 채널로 알림을 보냅니다. 채널마다 발송 시점과 필터 규칙을 따로 설정할 수 있습니다.", "globalSwitch": "전체 스위치", "addChannel": "채널 추가", "disabled": "사용 안 함", "aria": { "globalSwitch": "알림 발송 전체 스위치", "enable": "사용", "delete": "삭제", "statusChange": "상태 변경 수신" }, "toast": { "loadConfigFailed": "알림 설정을 불러오지 못했습니다: {msg}", "loadChannelsFailed": "채널 목록을 불러오지 못했습니다: {msg}", "nameRequired": "채널 이름을 입력하세요", "saved": "저장했습니다", "channelAdded": "채널을 추가했습니다", "saveFailed": "저장하지 못했습니다: {msg}", "testSent": "테스트 메시지를 보냈습니다 ({ms} ms). 채널에서 확인해 주세요", "testFailed": "테스트에 실패했습니다: {msg}", "deleted": "삭제했습니다: {name}", "deleteFailed": "삭제하지 못했습니다: {msg}", "actionFailed": "처리하지 못했습니다: {msg}", "globalOn": "알림 발송을 켰습니다", "globalOff": "알림 발송을 멈췄습니다" }, "stats": { "channels": "채널", "channelsHint": "사용 중 / 전체", "sentToday": "오늘 전달", "pending": "발송 대기", "failed": "실패", "backlog": "최장 적체", "backlogStuck": "발송이 멈췄을 수 있습니다" }, "global": { "title": "전역 설정", "baseUrl": "링크 기준 주소", "baseUrlHint": "메시지의 「상세 보기」 버튼이 가리키는 주소입니다. 비워 두면 버튼을 넣지 않습니다.", "digest": "요약 주기 (분)", "digestHint": "「요약」 모드 채널에만 적용됩니다.", "save": "전역 설정 저장" }, "tab": { "channels": "채널", "deliveries": "전송 기록" }, "mode": { "realtime": "실시간", "digest": "요약" }, "kind": { "dingtalk": "DingTalk", "feishu": "Feishu", "wecom": "WeCom", "webhook": "범용 Webhook", "telegram": "Telegram", "email": "이메일" }, "sheet": { "addTitle": "알림 채널 추가", "rateLimited": " · 기본 제한 {rate}건/분", "rateUnlimited": " · 제한 없음", "kindLabel": "채널 유형", "kindLocked": "채널 유형은 바꿀 수 없습니다. 유형을 바꾸는 것은 자격 증명을 통째로 교체하는 것과 같으므로, 새 채널을 만들어 주세요.", "nameLabel": "채널 이름", "namePlaceholder": "긴급 대응방 / 일상 공지방", "noFields": "이 채널의 입력 양식이 아직 정의되지 않았습니다 (프런트엔드에 CHANNEL_FIELDS 항목이 없습니다). 항목을 채운 뒤 다시 시도해 주세요.", "modeLabel": "발송 시점", "modeRealtime": "실시간 · 취약점마다 한 건씩 발송", "modeDigest": "요약 · 주기마다 한 건으로 묶어 발송", "modeHint": "「높음 이상은 실시간, 나머지는 요약」처럼 하려면 채널을 두 개 만드세요. 하나는 실시간 + 최소 심각도 높음, 다른 하나는 요약 + 심각도 제한 없음으로 설정합니다.", "rateLabel": "전송 제한 (건/분)", "ratePlaceholder": "0 = 제한 없음", "rateHint": "비워 두면 채널 기본값을 씁니다. 0은 제한 없음을 뜻합니다. 제한을 넘어도 메시지를 버리지 않고 발송만 미룹니다.", "enable": "이 채널 사용", "save": "저장", "add": "추가", "sendTest": "테스트 메시지 발송" }, "filter": { "title": "필터 규칙 (비워 두면 필터링하지 않음)", "minSeverity": "최소 심각도", "includeLabel": "이 취약점 유형만 발송", "includePlaceholder": "SQL 주입\n명령 실행", "includeHint": "한 줄에 키워드 하나씩. 대소문자를 구분하지 않는 부분 문자열 매칭입니다. 비우면 모든 유형입니다.", "excludeLabel": "이 취약점 유형은 제외", "excludePlaceholder": "정보 유출", "excludeHint": "제외가 포함보다 우선합니다. 둘 다 걸리면 제외됩니다.", "taskIds": "작업 ID 한정", "assetIds": "자산 ID 한정", "idsHint": "작업/자산을 비우면 제한하지 않습니다. 값을 넣으면 취약점과 교집합이 있어야 합니다.", "onStatusChange": "취약점 처리 상태가 바뀔 때도 발송 (실시간 모드만)" }, "severityOpt": { "all": "제한 없음", "low": "낮음 이상", "medium": "중간 이상", "high": "높음 이상", "critical": "심각만" }, "masked": { "savedTail": "저장됨 (끝자리 {tail}) · 새 값을 입력하면 덮어쓰고, 비우면 이 항목을 삭제합니다", "saved": "저장됨 · 새 값을 입력하면 덮어쓰고, 비우면 이 항목을 삭제합니다" }, "summary": { "includeCount": "유형 {n}개 포함", "excludeCount": "{n}개 제외", "taskCount": "작업 {n}개", "assetCount": "자산 {n}개", "statusChange": "상태 변경 포함", "all": "모든 취약점" }, "field": { "dingtalk": { "webhook": { "label": "Webhook 주소" }, "secret": { "label": "서명 비밀키", "help": "봇 보안 설정에서 「서명」을 선택했을 때 입력합니다. 「사용자 지정 키워드」를 선택했거나 보안 설정을 켜지 않았다면 비워 둡니다." } }, "feishu": { "webhook": { "label": "Webhook 주소" }, "secret": { "label": "서명 검증 비밀키", "help": "봇에서 「서명 검증」을 켰을 때 입력하고, 아니면 비워 둡니다." } }, "wecom": { "webhook": { "label": "Webhook 주소" } }, "webhook": { "url": { "label": "대상 URL" }, "method": { "label": "요청 방식", "opt": { "POST": "POST (요청 본문 포함)", "PUT": "PUT (요청 본문 포함)", "PATCH": "PATCH (요청 본문 포함)", "GET": "GET (요청 본문 없음)" } }, "headers": { "label": "사용자 지정 요청 헤더", "help": "한 줄에 KEY=VALUE 하나씩. 예: Authorization=Bearer xxx" }, "body_template": { "label": "요청 본문 템플릿", "help": "비워 두면 내장 기본 템플릿을 씁니다. 변수: '{{.Title}} {{.Batch}} {{.Count}} {{.HomeURL}} {{.SentAt}}', 그리고 range .Items 아래의 .Name/.VulnClass/.Severity/.Summary/.Assets/.DetailURL/.StatusLabel. 문자열을 넣을 때는 '{{.Xxx}}' 대신 '{{json .Xxx}}'를 쓰세요. 그러지 않으면 제목 안의 따옴표가 JSON을 깨뜨립니다." } }, "telegram": { "bot_token": { "label": "Bot Token" }, "chat_id": { "label": "Chat ID" }, "base_url": { "label": "API 주소", "help": "비워 두면 공식 주소를 씁니다. 자체 구축한 Bot API 리버스 프록시를 쓸 때 입력합니다." } }, "email": { "host": { "label": "SMTP 서버" }, "port": { "label": "포트", "help": "587은 STARTTLS를 씁니다. 465는 「암시적 TLS」를 켜 주세요." }, "username": { "label": "계정" }, "password": { "label": "비밀번호 / 앱 비밀번호" }, "from": { "label": "발신자" }, "to": { "label": "수신자", "help": "여러 주소는 쉼표로 구분합니다." }, "tls": { "label": "암시적 TLS", "help": "465 포트에서는 켜고, 587 포트에서는 끕니다 (자동으로 STARTTLS를 씁니다)." } } }, "delivery": { "loadFailed": "전송 기록을 불러오지 못했습니다: {msg}", "requeued": "다시 대기열에 넣었습니다", "resendFailed": "재발송에 실패했습니다: {msg}", "allChannels": "모든 채널", "allStates": "모든 상태", "refresh": "새로 고침", "totalCount": "총 {total}건", "colTime": "시간", "colFinding": "취약점", "colChannel": "채널", "colState": "상태", "colAttempts": "시도", "colError": "오류", "loading": "불러오는 중…", "empty": "전송 기록이 없습니다", "noTitle": "(제목 없음)", "statusChanged": "상태 변경", "resend": "재발송" }, "unit": { "sec": "{n}초", "min": "{n}분", "hour": "{n}시간" } } }