codebuff-agent 2.1.74__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. codebuff_agent-2.1.74.data/data/etc/jupyter/jupyter_server_config.d/codebuff_agent.json +7 -0
  2. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/package.json +157 -0
  3. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/104.2b8f20f9d1ac2c9db01b.js +1 -0
  4. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/150.39fa98117cc8ca590465.js +1 -0
  5. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/166.386ff9b2c37ac865fdee.js +1 -0
  6. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/216.25cf81131bf7274dabf4.js +1 -0
  7. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/353.581bd1cb00746399b62e.js +1 -0
  8. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/367.575f9621b63c9a641aa9.js +1 -0
  9. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/421.11dac223a2c2da1b09f5.js +1 -0
  10. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/432.8513b4c6cc1d1232d165.js +2 -0
  11. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/432.8513b4c6cc1d1232d165.js.LICENSE.txt +19 -0
  12. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/439.ba5b5ef70ec6de214b8c.js +2 -0
  13. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/439.ba5b5ef70ec6de214b8c.js.LICENSE.txt +8 -0
  14. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/481.cc2dec9fa869d66f1407.js +1 -0
  15. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/487.0796e931d6e651482c14.js +1 -0
  16. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/49.d326f554b6f9ccde6580.js +1 -0
  17. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/541.26897ea32845659e36be.js +1 -0
  18. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/579.e569d3edd8391fd8fbb3.js +1 -0
  19. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/58.eb7cc679f7535cc8a2f1.js +2 -0
  20. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/58.eb7cc679f7535cc8a2f1.js.LICENSE.txt +8 -0
  21. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/666.d9bfdb23f98489d0a188.js +1 -0
  22. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/677.d266c39dbed33bc388b3.js +2 -0
  23. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/677.d266c39dbed33bc388b3.js.LICENSE.txt +8 -0
  24. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/68.26b6f59c8454adb17f20.js +204 -0
  25. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/694.4ac443814260057e68f7.js +1 -0
  26. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/791.61affb8d3480d3d60e0d.js +1 -0
  27. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/848.4d2db09cfbb09374b299.js +2 -0
  28. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/848.4d2db09cfbb09374b299.js.LICENSE.txt +9 -0
  29. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/868.5cfe7e1a348ec5af1b8c.js +1 -0
  30. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/97.ea559a5b8a9a09f17c6b.js +1 -0
  31. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/remoteEntry.5292fc9c6df7e7920cc8.js +1 -0
  32. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/style.js +4 -0
  33. codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/third-party-licenses.json +724 -0
  34. codebuff_agent-2.1.74.dist-info/METADATA +142 -0
  35. codebuff_agent-2.1.74.dist-info/RECORD +217 -0
  36. codebuff_agent-2.1.74.dist-info/WHEEL +4 -0
  37. codebuff_agent-2.1.74.dist-info/licenses/LICENSE +21 -0
  38. codebuff_core/__init__.py +153 -0
  39. codebuff_core/codebuff_config_defaults.json +64 -0
  40. codebuff_core/core/__init__.py +35 -0
  41. codebuff_core/core/code_validator.py +1238 -0
  42. codebuff_core/core/error_classifier.py +579 -0
  43. codebuff_core/core/exceptions.py +49 -0
  44. codebuff_core/data/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +100256 -0
  45. codebuff_core/directory_policy.py +32 -0
  46. codebuff_core/factory.py +155 -0
  47. codebuff_core/interfaces.py +197 -0
  48. codebuff_core/knowledge/__init__.py +31 -0
  49. codebuff_core/knowledge/chunking.py +375 -0
  50. codebuff_core/knowledge/loader.py +339 -0
  51. codebuff_core/knowledge/watchdog_service.py +354 -0
  52. codebuff_core/legacy_paths.py +69 -0
  53. codebuff_core/llm/__init__.py +13 -0
  54. codebuff_core/llm/service.py +407 -0
  55. codebuff_core/managers/__init__.py +22 -0
  56. codebuff_core/managers/config_manager.py +690 -0
  57. codebuff_core/managers/remote_config.py +673 -0
  58. codebuff_core/managers/remote_skills.py +539 -0
  59. codebuff_core/managers/session_manager.py +255 -0
  60. codebuff_core/middleware/__init__.py +3 -0
  61. codebuff_core/middleware/error_recovery.py +394 -0
  62. codebuff_core/middleware/logging_utils.py +33 -0
  63. codebuff_core/models/__init__.py +111 -0
  64. codebuff_core/models/agent.py +306 -0
  65. codebuff_core/models/chat.py +57 -0
  66. codebuff_core/models/common.py +82 -0
  67. codebuff_core/models/rag.py +300 -0
  68. codebuff_core/platform_rules.py +127 -0
  69. codebuff_core/prompts/__init__.py +44 -0
  70. codebuff_core/prompts/auto_agent_prompts.py +1278 -0
  71. codebuff_core/services/__init__.py +30 -0
  72. codebuff_core/services/agent_service.py +345 -0
  73. codebuff_core/services/analytics_aggregate.py +837 -0
  74. codebuff_core/services/chat_service.py +898 -0
  75. codebuff_core/services/context_condenser.py +306 -0
  76. codebuff_core/services/pii_guardrail.py +393 -0
  77. codebuff_core/services/rag_chat_agent.py +2993 -0
  78. codebuff_core/services/rag_collections.py +2740 -0
  79. codebuff_core/services/rag_manager.py +890 -0
  80. codebuff_core/services/rag_service.py +145 -0
  81. codebuff_core/services/retriever.py +260 -0
  82. codebuff_core/services/vllm_embedding_service.py +290 -0
  83. codebuff_core/tests/__init__.py +1 -0
  84. codebuff_core/tests/conftest.py +81 -0
  85. codebuff_core/tests/test_error_recovery.py +647 -0
  86. codebuff_core/tests/test_factory.py +135 -0
  87. codebuff_core/tests/test_services.py +150 -0
  88. jupyter_ext/__init__.py +266 -0
  89. jupyter_ext/_version.py +4 -0
  90. jupyter_ext/agent/__init__.py +49 -0
  91. jupyter_ext/agent/agent_factory.py +2270 -0
  92. jupyter_ext/agent/ast_tools.py +451 -0
  93. jupyter_ext/agent/autofix_middleware.py +481 -0
  94. jupyter_ext/agent/background_procs.py +372 -0
  95. jupyter_ext/agent/code_history_middleware.py +211 -0
  96. jupyter_ext/agent/codex_autofix.py +160 -0
  97. jupyter_ext/agent/codex_bridge.py +3339 -0
  98. jupyter_ext/agent/codex_hooks.py +320 -0
  99. jupyter_ext/agent/codex_slash.py +685 -0
  100. jupyter_ext/agent/codex_threads.py +114 -0
  101. jupyter_ext/agent/content_injection.py +377 -0
  102. jupyter_ext/agent/continuation_middleware.py +548 -0
  103. jupyter_ext/agent/custom_skills.py +335 -0
  104. jupyter_ext/agent/file_diffs.py +99 -0
  105. jupyter_ext/agent/git_history.py +188 -0
  106. jupyter_ext/agent/guardrail_middleware.py +421 -0
  107. jupyter_ext/agent/json_repair_utils.py +54 -0
  108. jupyter_ext/agent/langchain_tools.py +2673 -0
  109. jupyter_ext/agent/mermaid_fixer.py +289 -0
  110. jupyter_ext/agent/mermaid_middleware.py +135 -0
  111. jupyter_ext/agent/middleware.py +359 -0
  112. jupyter_ext/agent/middleware_prompts.py +53 -0
  113. jupyter_ext/agent/observability.py +334 -0
  114. jupyter_ext/agent/patch_tool_calls.py +57 -0
  115. jupyter_ext/agent/prompts.py +112 -0
  116. jupyter_ext/agent/skill_middleware.py +257 -0
  117. jupyter_ext/agent/skills/airflow_dag_development.md +36 -0
  118. jupyter_ext/agent/skills/anomaly_detection.md +12 -0
  119. jupyter_ext/agent/skills/athena_sql.md +156 -0
  120. jupyter_ext/agent/skills/bdp_table_search.md +33 -0
  121. jupyter_ext/agent/skills/bigquery.md +65 -0
  122. jupyter_ext/agent/skills/bigquery_oracle.md +231 -0
  123. jupyter_ext/agent/skills/bigquery_tuning.md +307 -0
  124. jupyter_ext/agent/skills/classification_evaluation.md +11 -0
  125. jupyter_ext/agent/skills/clustering_analysis.md +12 -0
  126. jupyter_ext/agent/skills/comprehensive_eda.md +11 -0
  127. jupyter_ext/agent/skills/data_analysis.md +236 -0
  128. jupyter_ext/agent/skills/data_cleaning_pipeline.md +12 -0
  129. jupyter_ext/agent/skills/data_loading.md +158 -0
  130. jupyter_ext/agent/skills/data_quality_report.md +13 -0
  131. jupyter_ext/agent/skills/dimensionality_reduction.md +12 -0
  132. jupyter_ext/agent/skills/emr_script_development.md +17 -0
  133. jupyter_ext/agent/skills/experiment_tracking.md +13 -0
  134. jupyter_ext/agent/skills/feature_importance_analysis.md +10 -0
  135. jupyter_ext/agent/skills/hyperparameter_tuning.md +12 -0
  136. jupyter_ext/agent/skills/hypothesis_testing.md +12 -0
  137. jupyter_ext/agent/skills/imbalanced_data_handling.md +12 -0
  138. jupyter_ext/agent/skills/inference.md +392 -0
  139. jupyter_ext/agent/skills/lambda_function_development.md +19 -0
  140. jupyter_ext/agent/skills/model_comparison.md +11 -0
  141. jupyter_ext/agent/skills/model_explainability.md +12 -0
  142. jupyter_ext/agent/skills/model_training.md +318 -0
  143. jupyter_ext/agent/skills/pyspark.md +352 -0
  144. jupyter_ext/agent/skills/python_code_quality.md +35 -0
  145. jupyter_ext/agent/skills/regression_evaluation.md +12 -0
  146. jupyter_ext/agent/skills/spring_java_development.md +35 -0
  147. jupyter_ext/agent/skills/text_preprocessing.md +12 -0
  148. jupyter_ext/agent/skills/time_series_analysis.md +13 -0
  149. jupyter_ext/agent/skills/unit_testing.md +203 -0
  150. jupyter_ext/agent/todo_prompts.py +57 -0
  151. jupyter_ext/agent/tool_report.py +45 -0
  152. jupyter_ext/analytics_ingest.py +599 -0
  153. jupyter_ext/etc/jupyter/jupyter_server_config.d/codebuff_agent.json +7 -0
  154. jupyter_ext/handlers/__init__.py +8 -0
  155. jupyter_ext/handlers/analytics_handler.py +170 -0
  156. jupyter_ext/handlers/benchmark_handler.py +794 -0
  157. jupyter_ext/handlers/eda_benchmark_handler.py +1328 -0
  158. jupyter_ext/handlers/rag_admin_handler.py +689 -0
  159. jupyter_ext/handlers/websocket.py +497 -0
  160. jupyter_ext/http_handlers.py +8744 -0
  161. jupyter_ext/idle_monitor.py +346 -0
  162. jupyter_ext/labextension/package.json +157 -0
  163. jupyter_ext/labextension/static/104.2b8f20f9d1ac2c9db01b.js +1 -0
  164. jupyter_ext/labextension/static/150.39fa98117cc8ca590465.js +1 -0
  165. jupyter_ext/labextension/static/166.386ff9b2c37ac865fdee.js +1 -0
  166. jupyter_ext/labextension/static/216.25cf81131bf7274dabf4.js +1 -0
  167. jupyter_ext/labextension/static/353.581bd1cb00746399b62e.js +1 -0
  168. jupyter_ext/labextension/static/367.575f9621b63c9a641aa9.js +1 -0
  169. jupyter_ext/labextension/static/421.11dac223a2c2da1b09f5.js +1 -0
  170. jupyter_ext/labextension/static/432.8513b4c6cc1d1232d165.js +2 -0
  171. jupyter_ext/labextension/static/432.8513b4c6cc1d1232d165.js.LICENSE.txt +19 -0
  172. jupyter_ext/labextension/static/439.ba5b5ef70ec6de214b8c.js +2 -0
  173. jupyter_ext/labextension/static/439.ba5b5ef70ec6de214b8c.js.LICENSE.txt +8 -0
  174. jupyter_ext/labextension/static/481.cc2dec9fa869d66f1407.js +1 -0
  175. jupyter_ext/labextension/static/487.0796e931d6e651482c14.js +1 -0
  176. jupyter_ext/labextension/static/49.d326f554b6f9ccde6580.js +1 -0
  177. jupyter_ext/labextension/static/541.26897ea32845659e36be.js +1 -0
  178. jupyter_ext/labextension/static/579.e569d3edd8391fd8fbb3.js +1 -0
  179. jupyter_ext/labextension/static/58.eb7cc679f7535cc8a2f1.js +2 -0
  180. jupyter_ext/labextension/static/58.eb7cc679f7535cc8a2f1.js.LICENSE.txt +8 -0
  181. jupyter_ext/labextension/static/666.d9bfdb23f98489d0a188.js +1 -0
  182. jupyter_ext/labextension/static/677.d266c39dbed33bc388b3.js +2 -0
  183. jupyter_ext/labextension/static/677.d266c39dbed33bc388b3.js.LICENSE.txt +8 -0
  184. jupyter_ext/labextension/static/68.26b6f59c8454adb17f20.js +204 -0
  185. jupyter_ext/labextension/static/694.4ac443814260057e68f7.js +1 -0
  186. jupyter_ext/labextension/static/791.61affb8d3480d3d60e0d.js +1 -0
  187. jupyter_ext/labextension/static/848.4d2db09cfbb09374b299.js +2 -0
  188. jupyter_ext/labextension/static/848.4d2db09cfbb09374b299.js.LICENSE.txt +9 -0
  189. jupyter_ext/labextension/static/868.5cfe7e1a348ec5af1b8c.js +1 -0
  190. jupyter_ext/labextension/static/97.ea559a5b8a9a09f17c6b.js +1 -0
  191. jupyter_ext/labextension/static/remoteEntry.5292fc9c6df7e7920cc8.js +1 -0
  192. jupyter_ext/labextension/static/style.js +4 -0
  193. jupyter_ext/labextension/static/third-party-licenses.json +724 -0
  194. jupyter_ext/log_paths.py +113 -0
  195. jupyter_ext/resource_usage.py +519 -0
  196. jupyter_ext/secrets_bootstrap.py +116 -0
  197. jupyter_ext/team_access.py +105 -0
  198. jupyter_ext/tests/__init__.py +1 -0
  199. jupyter_ext/tests/test_context.py +234 -0
  200. jupyter_ext/tests/test_factory.py +563 -0
  201. jupyter_ext/tests/test_file_finder.py +139 -0
  202. jupyter_ext/tests/test_handlers.py +58 -0
  203. jupyter_ext/tests/test_mcp_selftest.py +204 -0
  204. jupyter_ext/tests/test_mermaid_fixer.py +272 -0
  205. jupyter_ext/tests/test_resource_tiers.py +298 -0
  206. jupyter_ext/tools/__init__.py +15 -0
  207. jupyter_ext/tools/base.py +90 -0
  208. jupyter_ext/tools/context.py +268 -0
  209. jupyter_ext/tools/dir_complete.py +86 -0
  210. jupyter_ext/tools/file_finder.py +303 -0
  211. jupyter_ext/tools/file_tools.py +244 -0
  212. jupyter_ext/tools/jupyter_tools.py +296 -0
  213. jupyter_ext/tools/registry.py +159 -0
  214. jupyter_ext/tools/search_tools.py +230 -0
  215. jupyter_ext/tools/security_tools.py +657 -0
  216. jupyter_ext/tools/shell_tools.py +109 -0
  217. jupyter_ext/tools/user_tools.py +132 -0
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunkcodebuff=self.webpackChunkcodebuff||[]).push([[97],{97(e,t,n){n.r(t),n.d(t,{default:()=>As});var a=n(5584),r=n(9827),s=n(8389),o=n(1805),l=n(3118),c=n(7292),i=n(3345),d=n.n(i),u=n(1409),m=n(2430);const p=({id:e,value:t,onChange:n,apiService:a,placeholder:r})=>{const[s,o]=(0,i.useState)([]),[l,c]=(0,i.useState)(!1),[u,m]=(0,i.useState)(-1),p=(0,i.useRef)(void 0),h=(0,i.useRef)(0),g=`${e}-listbox`;(0,i.useEffect)(()=>()=>window.clearTimeout(p.current),[]);const f=()=>{window.clearTimeout(p.current),h.current+=1,c(!1),m(-1)},b=e=>{n(e.path),f()};return d().createElement("div",{className:"jp-dir-autocomplete"},d().createElement("input",{id:e,type:"text",className:"jp-agent-settings-input",role:"combobox","aria-autocomplete":"list","aria-expanded":l,"aria-controls":g,"aria-activedescendant":l&&u>=0?`${g}-${u}`:void 0,autoComplete:"off",value:t,onChange:e=>{var t;n(e.target.value),t=e.target.value,window.clearTimeout(p.current),p.current=window.setTimeout(async()=>{const e=++h.current;try{const n=await a.getDirectoryCompletions(t);if(e!==h.current)return;o(n),m(-1),c(n.length>0)}catch{e===h.current&&c(!1)}},300)},onKeyDown:e=>{l&&0!==s.length&&("ArrowDown"===e.key?(e.preventDefault(),m(e=>(e+1)%s.length)):"ArrowUp"===e.key?(e.preventDefault(),m(e=>e<=0?s.length-1:e-1)):"Enter"===e.key&&u>=0?(e.preventDefault(),b(s[u])):"Escape"===e.key&&(e.preventDefault(),e.stopPropagation(),f()))},onBlur:f,placeholder:r}),l&&d().createElement("ul",{id:g,role:"listbox",className:"jp-dir-autocomplete-list"},s.map((e,t)=>{return d().createElement("li",{key:e.path,id:`${g}-${t}`,role:"option","aria-selected":t===u,className:"jp-dir-autocomplete-option"+(t===u?" jp-dir-autocomplete-option-active":""),onMouseDown:t=>{t.preventDefault(),b(e)},onMouseEnter:()=>m(t),"aria-label":e.path,title:e.path},d().createElement("span",{className:"jp-dir-autocomplete-path"},(n=e.path).replace(/[\\/]+$/,"").split(/[\\/]/).pop()||n),e.git&&d().createElement("span",{className:"jp-dir-autocomplete-badge"},"git"),e.agentsMd&&d().createElement("span",{className:"jp-user-settings-status-dot jp-user-settings-status-ok",title:"AGENTS.md 있음"},"●"));var n})))},h={disabled:"꺼짐 — 로컬 스킬만 씁니다",pending:"첫 동기화 대기 중",ok:"동기화됨",error:"동기화 실패 — 마지막으로 받은 스킬을 씁니다"},g={key_mismatch:"공유 키 불일치",no_key:"센트리에 공유 키가 설정되지 않음",unreachable:"센트리 응답 없음",no_url:"센트리 주소가 설정되지 않음"},f={"features.inference_engine":"추론 엔진","features.agent_enabled":"Agent 모드","features.eda_enabled":"EDA","features.bdp_qa_enabled":"BDP 질의응답","vllm.endpoint":"LLM 주소","vllm.model":"LLM 모델","codex.endpoint":"에이전트 게이트웨이 주소","rag.enabled":"검색 인덱스(RAG)","rag.collectionName":"RAG 컬렉션","rag.vllmEndpoint":"임베딩 주소","rag.vllmModel":"임베딩 모델","rag.vllmDimension":"임베딩 차원",idleTimeout:"유휴 종료 시간(초)",maxOutputTokens:"최대 출력 토큰",rawLlmLogging:"LLM 원문 로그","guardrails.enableInput":"입력 가드레일","guardrails.enableOutput":"출력 가드레일","guardrails.maxInputLength":"입력 최대 길이","guardrails.maxCodeLength":"코드 최대 길이"},b=new Set(["maxOutputTokens"]),v={auth:"인증",gateway:"게이트웨이",bridge:"브리지",model:"모델"};function y(e,t){const n=e.connection;if("ok"===n.state){const n=e.codex;return"codex"===n.engine&&n.configured?t?t.ok?["ok","연결됨"]:["warn",`연결 안 됨: ${v[t.stage??""]??v.gateway}`,t.detail]:["off","확인 중","에이전트 게이트웨이와 모델 응답을 확인하고 있습니다"]:["ok","연결됨"]}return"pending"===n.state?["off","연결 안 됨","아직 확인하지 않았습니다"]:["no_url"===n.reason?"off":"warn","연결 안 됨",g[n.reason??""]??n.reason]}const E=({id:e,label:t,line:n})=>{const[a,r,s]=n;return d().createElement("div",{className:"jp-user-settings-status-row","data-testid":`config-status-${e}`,"data-state":a},d().createElement("div",{className:"jp-user-settings-status"},d().createElement("span",{className:`jp-user-settings-status-dot jp-user-settings-status-${a}`},"●"),d().createElement("span",{className:"jp-user-settings-status-name"},t),d().createElement("span",{className:"jp-user-settings-status-text"},r)),s&&d().createElement("small",{className:"jp-user-settings-hint"+("warn"===a?" jp-user-settings-hint-warn":" jp-user-settings-hint-muted")},s))},k=({portal:e})=>d().createElement("span",{"data-testid":"sync-badge","data-sync":e?"portal":"local",className:"jp-user-settings-sync-badge jp-user-settings-sync-badge-"+(e?"portal":"local"),title:e?"포털에 저장되어 다른 환경에서도 쓰입니다":"이 환경에만 저장됩니다"},e?"포털":"로컬"),w=({skills:e,onClose:t})=>d().createElement("div",{className:"jp-skills-list-overlay",onClick:t},d().createElement("div",{className:"jp-skills-list-dialog","data-testid":"custom-skills-list",role:"dialog","aria-label":"커스텀 스킬 목록",onClick:e=>e.stopPropagation()},d().createElement("div",{className:"jp-skills-list-header"},d().createElement("strong",null,"커스텀 스킬 ",e.length,"개"),d().createElement("button",{type:"button",className:"jp-skills-list-close",onClick:t,"aria-label":"닫기",title:"닫기"},"×")),d().createElement("ul",{className:"jp-skills-list-body"},e.map(e=>d().createElement("li",{key:`${e.source}:${e.scope}:${e.name}`,className:"jp-skills-list-item","data-testid":"custom-skill-item"},d().createElement("div",{className:"jp-skills-list-item-head"},d().createElement("code",null,e.name),d().createElement("span",{className:`jp-skills-list-source jp-skills-list-source-${e.source}`},"centri"===e.source?"센트리":"로컬"),d().createElement("span",{className:"jp-skills-list-scope"},e.scope)),e.description&&d().createElement("div",{className:"jp-skills-list-desc"},e.description),e.dir&&d().createElement("div",{className:"jp-skills-list-dir"},e.dir)))))),x=({onClose:e,onSave:t,apiService:n,inputMode:a})=>{const[r,s]=(0,i.useState)(!0),[o,l]=(0,i.useState)(!1),[c,u]=(0,i.useState)(null),[g,v]=(0,i.useState)(""),[x,S]=(0,i.useState)(!1),[_,C]=(0,i.useState)(!1),[N,j]=(0,i.useState)(!1),[$,T]=(0,i.useState)("bypass"),[A,I]=(0,i.useState)(!1),[P,L]=(0,i.useState)(null),[M,R]=(0,i.useState)(null),[q,D]=(0,i.useState)(0),[O,z]=(0,i.useState)(!1),[F,B]=(0,i.useState)(!0),W=(0,i.useRef)(0),[U,H]=(0,i.useState)(null),[J,V]=(0,i.useState)(!1),[G,X]=(0,i.useState)(null),[Z,K]=(0,i.useState)(null),[Q,Y]=(0,i.useState)(null);(0,i.useEffect)(()=>{te()},[]);const ee=e=>{L(e.exists),R(e.path),D(e.size??0),z(e.truncated??!1),B(!1!==e.dirExists)};(0,i.useEffect)(()=>{if(!x)return;const e=++W.current,t=window.setTimeout(async()=>{try{const t=await n.getAgentsMdStatus(g.trim()||".");e===W.current&&ee(t)}catch{}},300);return()=>window.clearTimeout(t)},[g,x]);const te=async()=>{try{s(!0);const e=await n.getUserConfig();v(e.workspaceRoot||""),C(Boolean(e.remote?.savesToServer)),j(Boolean(e.autoApprove)),T("ask"===e.codexPermissionMode?"ask":"bypass");try{const e=await n.getCodexHealth();I(Boolean(e.configured))}catch{I(!1)}try{ee(await n.getAgentsMdStatus(e.workspaceRoot||"."))}catch{}try{H(await n.getSkillsStatus())}catch{H(null)}try{const e=await n.getConfigStatus();X(e),K(null),"codex"===e.codex.engine&&"no_endpoint"===e.codex.reason&&I(!0),"codex"===e.codex.engine&&e.codex.configured&&n.testCodexConnection().then(Y).catch(e=>Y({ok:!1,detail:String(e)}))}catch(e){X(null),K(String(e))}u(null)}catch(e){u(`설정을 불러오는데 실패했습니다: ${e}`)}finally{s(!1)}};return r?d().createElement("div",{className:"jp-agent-settings-overlay"},d().createElement("div",{className:"jp-agent-settings-dialog",style:{maxWidth:"400px"}},d().createElement("div",{className:"jp-agent-settings-content",style:{textAlign:"center",padding:"40px"}},d().createElement(m.A,{sx:{fontSize:48,color:"info.main"}}),d().createElement("p",null,"설정을 불러오는 중...")))):d().createElement("div",{className:"jp-agent-settings-overlay"},d().createElement("div",{className:"jp-agent-settings-dialog jp-user-settings-dialog"},d().createElement("div",{className:"jp-agent-settings-header"},d().createElement("h2",null,"사용자 설정"),d().createElement("button",{className:"jp-agent-settings-close",onClick:e,title:"닫기"},"×")),d().createElement("div",{className:"jp-agent-settings-content"},c&&d().createElement("div",{className:"jp-agent-settings-error",style:{color:"#dc2626",marginBottom:"12px"}},c),d().createElement("section",{className:"jp-user-settings-section"},d().createElement("h3",{className:"jp-user-settings-section-title"},"프로젝트"),d().createElement("div",{className:"jp-agent-settings-group"},d().createElement("div",{className:"jp-user-settings-field-head"},d().createElement("label",{className:"jp-agent-settings-label jp-user-settings-label-row",htmlFor:"jp-user-workspace-root"},"프로젝트 디렉터리",d().createElement("span",{className:"athena-tip-wrap"},d().createElement("svg",{className:"athena-tip-icon",width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("circle",{cx:"12",cy:"12",r:"10"}),d().createElement("path",{d:"M12 16v-4"}),d().createElement("path",{d:"M12 8h.01"})),d().createElement("span",{className:"athena-tip-popup"},d().createElement("span",{className:"athena-tip-title"},"프로젝트 디렉터리 입력 가이드"),d().createElement("span",{className:"athena-tip-body"},d().createElement("p",null,d().createElement("strong",null,"경로 형식")),d().createElement("ul",null,d().createElement("li",null,"절대 경로 (예: ",d().createElement("code",null,"/Users/you/project"),")"),d().createElement("li",null,"Jupyter 작업 디렉토리 기준 상대 경로 (예: ",d().createElement("code",null,"./my-project"),")"),d().createElement("li",null,"입력하면 하위 폴더를 자동완성합니다. git 프로젝트와 AGENTS.md 가 있는 폴더는 표시됩니다."),d().createElement("li",null,"비워두면 Jupyter 작업 디렉토리가 기준이 됩니다.")),d().createElement("p",null,d().createElement("strong",null,"쓰이는 곳")),d().createElement("ul",null,d().createElement("li",null,"에이전트가 파일을 읽고 쓰고 검색하는 작업 폴더입니다.")))))),d().createElement(k,{portal:_})),d().createElement(p,{id:"jp-user-workspace-root",value:g,onChange:e=>{v(e),S(!0)},apiService:n,placeholder:"예: /Users/you/project 또는 ./my-project"})),d().createElement("div",{className:"jp-agent-settings-group"},d().createElement("div",{className:"jp-user-settings-field-head"},d().createElement("label",{className:"jp-agent-settings-label"},"프로젝트 지시사항 (AGENTS.md)"),d().createElement(k,{portal:!1})),F?!0===P?d().createElement("div",{className:"jp-user-settings-status"},d().createElement("span",{className:"jp-user-settings-status-dot"+(O?" jp-user-settings-status-warn":" jp-user-settings-status-ok")},"●"),d().createElement("span",null,"감지됨 (",O?`${q.toLocaleString()}자 → 10,000자로 잘림`:`${q.toLocaleString()}자`,")")):d().createElement("small",{className:"jp-user-settings-hint jp-user-settings-hint-muted"},"파일 없음 — 프로젝트 디렉터리에 생성하면 AI 지시사항으로 사용됩니다 (최대 10,000자)"):d().createElement("small",{className:"jp-user-settings-hint jp-user-settings-hint-warn","data-testid":"project-dir-missing"},"디렉터리 없음 — 경로를 확인하세요"),M&&d().createElement("small",{className:"jp-user-settings-hint"},M))),d().createElement("section",{className:"jp-user-settings-section"},d().createElement("h3",{className:"jp-user-settings-section-title"},"에이전트 동작"),"agent"===a&&d().createElement("div",{className:"jp-agent-settings-group"},d().createElement("div",{className:"jp-user-settings-field-head"},d().createElement("label",{className:"jp-agent-settings-label"},"자동 실행 승인"),d().createElement(k,{portal:_})),d().createElement("label",{className:"jp-agent-settings-checkbox"},d().createElement("input",{type:"checkbox",checked:N,onChange:e=>j(e.target.checked)}),d().createElement("span",null,"승인 없이 바로 실행 (코드/파일/셸 포함)")),d().createElement("small",{className:"jp-user-settings-hint"+(N?" jp-user-settings-hint-warn":"")},N?"주의: 에이전트가 생성한 코드가 자동으로 실행됩니다.":"에이전트가 코드 실행, 파일 수정, 셸 명령 실행 전 승인을 요청합니다.")),A&&d().createElement("div",{className:"jp-agent-settings-group"},d().createElement("div",{className:"jp-user-settings-field-head"},d().createElement("label",{className:"jp-agent-settings-label",htmlFor:"jp-user-codex-permission"},"agent 도구 승인"),d().createElement(k,{portal:_})),d().createElement("select",{id:"jp-user-codex-permission",className:"jp-agent-settings-input",value:$,onChange:e=>T(e.target.value)},d().createElement("option",{value:"ask"},"ask — 파일 수정·셸 실행 전 승인"),d().createElement("option",{value:"bypass"},"bypass — 전부 자동 승인 (기본)")),d().createElement("small",{className:"jp-user-settings-hint"+("bypass"===$?" jp-user-settings-hint-warn":"")},"bypass"===$?"주의: 에이전트가 파일 수정과 셸 명령을 승인 없이 실행합니다.":"노트북 셀 실행은 브라우저에서만 가능하므로 두 모드 모두 승인을 거칩니다.")),U&&d().createElement("div",{className:"jp-agent-settings-group","data-testid":"custom-skills-status","data-state":U.sync.state},d().createElement("label",{className:"jp-agent-settings-label"},"커스텀 스킬"),d().createElement("div",{className:"jp-user-settings-status"},d().createElement("span",{className:"jp-user-settings-status-dot"+(U.omitted>0||"error"===U.sync.state?" jp-user-settings-status-warn":" jp-user-settings-status-ok")},"●"),d().createElement("span",null,d().createElement("button",{type:"button",className:"jp-user-settings-link","data-testid":"custom-skills-open",title:"스킬 목록 보기",onClick:()=>V(!0)},U.total,"개"),` (로컬 ${U.local} · 포털 ${U.synced})`,U.omitted>0&&` — 목록 예산 8,000자를 넘어 ${U.omitted}개가 목록에서 빠짐`)),d().createElement("small",{className:"jp-user-settings-hint"+("error"===U.sync.state?" jp-user-settings-hint-warn":" jp-user-settings-hint-muted")},"포털 동기화: ",h[U.sync.state],U.sync.dropped>0&&` · 버림 ${U.sync.dropped}`,U.sync.lastOkAt&&` · 마지막 성공 ${function(e){const t=Date.parse(e);return Number.isNaN(t)?e:new Date(t+324e5).toISOString().replace("T"," ").slice(0,19)}(U.sync.lastOkAt)}`),J&&d().createElement(w,{skills:U.skills,onClose:()=>V(!1)}))),!G&&Z&&d().createElement("section",{className:"jp-user-settings-section","data-testid":"remote-config-status"},d().createElement("h3",{className:"jp-user-settings-section-title"},"연결 상태"),d().createElement(E,{id:"status",label:"상태 조회",line:["warn","불러오지 못했습니다",Z]})),G&&d().createElement("section",{className:"jp-user-settings-section","data-testid":"remote-config-status"},d().createElement("h3",{className:"jp-user-settings-section-title"},"연결 상태"),d().createElement(E,{id:"connection",label:"센트리",line:y(G,Q)}),"ok"===G.connection.state&&G.remote.scope&&(()=>{const[e,t]=function(e){const t=[];return e.team?(t.push(`팀 ${e.team}`),t.push(e.project?`프로젝트 ${e.project}`:"프로젝트 없음 — 프로젝트 층 값은 적용되지 않습니다")):t.push("팀 정보 없음 — 팀·프로젝트 층 값은 적용되지 않습니다"),e.userToken||t.push("사용자 토큰 없음 — 개인 층 값은 적용되지 않습니다"),[!e.team||!e.project||!e.userToken,`적용 범위: ${t.join(" · ")}`]}(G.remote.scope);return d().createElement("small",{className:"jp-user-settings-hint"+(e?" jp-user-settings-hint-warn":""),"data-testid":"config-scope"},t)})(),function(e){const t=[];if(e.rag.enabled&&e.rag.error&&t.push(["rag","검색 인덱스 준비 실패",e.rag.error]),"ok"!==e.connection.state)return t;const n=e.codex;return"codex"===n.engine&&"no_endpoint"===n.reason&&t.push(["gateway","에이전트 게이트웨이: 연결 주소 없음 — 포털에 게이트웨이 주소가 없습니다",null]),"error"===e.ingest.state&&t.push(["ingest","사용 로그 전송 실패 — 기록은 이 환경의 로그 파일에 남습니다",e.ingest.lastError]),t}(G).map(([e,t,n])=>d().createElement("small",{key:e,className:"jp-user-settings-hint jp-user-settings-hint-warn","data-testid":`config-feature-error-${e}`},t,n&&` · ${n}`))),G&&(()=>{const e=G.values.filter(e=>"portal"===e.source);return d().createElement("details",{className:"jp-user-settings-section jp-user-settings-values","data-testid":"portal-config-values"},d().createElement("summary",{className:"jp-user-settings-section-title"},"센트리에서 받은 설정 · ",e.length,"개","error"===G.remote.state&&d().createElement("small",{className:"jp-user-settings-hint jp-user-settings-hint-warn","data-testid":"portal-config-error"}," ","받기 실패 — ",G.remote.lastOkAt?"마지막으로 받은 값을 씁니다":"이 환경의 설정 파일을 씁니다",G.remote.lastError&&` · ${G.remote.lastError}`)),0===e.length&&d().createElement("p",{className:"jp-user-settings-hint-muted","data-testid":"portal-config-empty"},"센트리에서 받은 설정이 없습니다"),d().createElement("table",{className:"jp-user-settings-values-table"},d().createElement("tbody",null,e.map(e=>{return d().createElement("tr",{key:e.key,"data-config-key":e.key},d().createElement("td",null,(t=e.key,f[t]??(t.startsWith("prompts.")?"프롬프트":t)),d().createElement("small",{className:"jp-user-settings-hint-muted","data-testid":"config-key"},d().createElement("br",null),d().createElement("code",null,e.key)),e.appliesTo&&d().createElement("small",{className:"jp-user-settings-hint-muted","data-testid":"config-applies-to"},d().createElement("br",null),"적용: ",e.appliesTo.where," · ",e.appliesTo.engines.join("·"))),d().createElement("td",null,function(e,t){return null==t||""===t?"—":e.startsWith("prompts.")&&"number"==typeof t?`${t.toLocaleString("ko-KR")}자`:"boolean"==typeof t?t?"켬":"끔":String(t)}(e.key,e.value),function(e,t){return e.appliesTo?!e.appliesTo.engines.includes(t):"codex"===t&&b.has(e.key)}(e,G.codex.engine)&&d().createElement("small",{className:"jp-user-settings-hint-muted"}," (현재 엔진에 적용 안 됨)")));var t}))))})()),d().createElement("div",{className:"jp-agent-settings-footer"},d().createElement("button",{className:"jp-agent-settings-button jp-agent-settings-button-secondary",onClick:e},"취소"),d().createElement("button",{className:"jp-agent-settings-button jp-agent-settings-button-primary",onClick:async()=>{try{l(!0);const a={workspaceRoot:g.trim()||"",autoApprove:N,codexPermissionMode:$};await n.updateUserConfig(a),t(a),e()}catch(e){u(`설정 저장에 실패했습니다: ${e instanceof Error?e.message:e}`)}finally{l(!1)}},disabled:o},o?"저장 중...":"저장"))))};var S=n(3959);const _="codebuff-llm-config";function C(){try{const e=(0,S.GK)(_,"hdsp-agent-llm-config");return e?JSON.parse(e):null}catch(e){return console.error("[ApiKeyManager] Failed to parse stored config:",e),null}}const N=(e,t="currentColor",n=16)=>`<svg width="${n}" height="${n}" viewBox="0 0 24 24" fill="${t}" style="vertical-align: middle; display: inline-block;">${e}</svg>`,j=(e,t="currentColor",n=16)=>`<svg width="${n}" height="${n}" viewBox="0 -960 960 960" fill="${t}" style="vertical-align: middle; display: inline-block;">${e}</svg>`,$={folder:'<path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/>',file:'<path d="M6 2c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6H6zm7 7V3.5L18.5 9H13z"/>',explore:'<path d="M12 10.9c-.61 0-1.1.49-1.1 1.1s.49 1.1 1.1 1.1c.61 0 1.1-.49 1.1-1.1s-.49-1.1-1.1-1.1zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm2.19 12.19L6 18l3.81-8.19L18 6l-3.81 8.19z"/>',read:'<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/>',write:'<path d="M19 8l-4 4h3c0 3.31-2.69 6-6 6-1.01 0-1.97-.25-2.8-.7l-1.46 1.46C8.97 19.54 10.43 20 12 20c4.42 0 8-3.58 8-8h3l-4-4zM6 12c0-3.31 2.69-6 6-6 1.01 0 1.97.25 2.8.7l1.46-1.46C15.03 4.46 13.57 4 12 4c-4.42 0-8 3.58-8 8H1l4 4 4-4H6z"/>',success:'<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>',error:'<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>',warning:'<path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>',info:'<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>',check:'<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>',edit:'<path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/>',search:'<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>',save:'<path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/>',diagnostics:'<path d="M19.5 12c0-.23-.01-.45-.03-.68l1.86-1.41c.4-.3.51-.86.26-1.3l-1.87-3.23c-.25-.44-.79-.62-1.25-.42l-2.15.91c-.37-.26-.76-.49-1.17-.68l-.29-2.31C14.8 2.38 14.37 2 13.87 2h-3.73c-.5 0-.93.38-.99.88l-.29 2.31c-.41.19-.8.42-1.17.68l-2.15-.91c-.46-.2-1-.02-1.25.42L2.41 8.62c-.25.44-.14.99.26 1.3l1.86 1.41c-.02.22-.03.44-.03.67s.01.45.03.68l-1.86 1.41c-.4.3-.51.86-.26 1.3l1.87 3.23c.25.44.79.62 1.25.42l2.15-.91c.37.26.76.49 1.17.68l.29 2.31c.06.5.49.88.99.88h3.73c.5 0 .93-.38.99-.88l.29-2.31c.41-.19.8-.42 1.17-.68l2.15.91c.46.2 1 .02 1.25-.42l1.87-3.23c.25-.44.14-.99-.26-1.3l-1.86-1.41c.03-.23.04-.45.04-.68zm-7.46 3.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/>',question:'<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/>',code:'<path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/>',terminal:'<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V8h16v10zm-2-1h-6v-2h6v2zM7.5 17l-1.41-1.41L8.67 13l-2.59-2.59L7.5 9l4 4-4 4z"/>',analytics:'<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/>',skip:'<path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/>',planner:'<path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm8.94 3c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/>',build:'<path d="M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z"/>',person:'<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>',researcher:'<path d="M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6C7.8 12.16 7 10.63 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z"/>',expandMore:'<path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"/>',expandLess:'<path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"/>',chevronRight:'<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>',summary:'<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"/>',listAlt:'<path d="M19 5v14H5V5h14m1.1-2H3.9c-.5 0-.9.4-.9.9v16.2c0 .4.4.9.9.9h16.2c.4 0 .9-.5.9-.9V3.9c0-.5-.5-.9-.9-.9zM11 7h6v2h-6V7zm0 4h6v2h-6v-2zm0 4h6v2h-6v-2zM7 7h2v2H7V7zm0 4h2v2H7v-2zm0 4h2v2H7v-2z"/>'},T={description:'<path d="m384-336 56-57-87-87 87-87-56-57-144 144 144 144Zm192 0 144-144-144-144-56 57 87 87-87 87 56 57ZM200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm0-560v560-560Z"/>',assignment:'<path d="M240-400h80q0-59 43-99.5T466-540q36 0 67 16.5t51 43.5h-64v80h200v-200h-80v62q-32-38-76.5-60T466-620q-95 0-160.5 64T240-400ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/>',thinking:'<path d="M480-40q-112 0-206-51T120-227v107H40v-240h240v80h-99q48 72 126.5 116T480-120q75 0 140.5-28.5t114-77q48.5-48.5 77-114T840-480h80q0 91-34.5 171T791-169q-60 60-140 94.5T480-40ZM40-480q0-91 34.5-171T169-791q60-60 140-94.5T480-920q112 0 206 51t154 136v-107h80v240H680v-80h99q-48-72-126.5-116T480-840q-75 0-140.5 28.5t-114 77q-48.5 48.5-77 114T120-480H40Zm440 240q21 0 35.5-14.5T530-290q0-21-14.5-36T480-341q-21 0-35.5 14.5T430-291q0 21 14.5 36t35.5 15Zm-36-152h73q0-36 8.5-54t34.5-44q35-35 46.5-56.5T618-598q0-56-40-89t-98-33q-50 0-86 26t-52 74l66 28q7-26 26.5-43t45.5-17q27 0 45.5 15.5T544-595q0 17-8 34t-34 40q-33 29-45.5 56.5T444-392Z"/>',tool:'<path d="M754-81q-8 0-15-2.5T726-92L522-296q-6-6-8.5-13t-2.5-15q0-8 2.5-15t8.5-13l85-85q6-6 13-8.5t15-2.5q8 0 15 2.5t13 8.5l204 204q6 6 8.5 13t2.5 15q0 8-2.5 15t-8.5 13l-85 85q-6 6-13 8.5T754-81Zm0-95 29-29-147-147-29 29 147 147ZM205-80q-8 0-15.5-3T176-92l-84-84q-6-6-9-13.5T80-205q0-8 3-15t9-13l212-212h85l34-34-165-165h-57L80-765l113-113 121 121v57l165 165 116-116-43-43 56-56H495l-28-28 142-142 28 28v113l56-56 142 142q17 17 26 38.5t9 45.5q0 24-9 46t-26 39l-85-85-56 56-42-42-207 207v84L233-92q-6 6-13 9t-15 3Zm0-96 170-170v-29h-29L176-205l29 29Zm0 0-29-29 15 14 14 15Zm549 0 29-29-29 29Z"/>',subagentComplete:'<path d="M702-480 560-622l57-56 85 85 170-170 56 57-226 226Zm-342 0q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47ZM40-160v-112q0-34 17.5-62.5T104-378q62-31 126-46.5T360-440q66 0 130 15.5T616-378q29 15 46.5 43.5T680-272v112H40Zm80-80h480v-32q0-11-5.5-20T580-306q-54-27-109-40.5T360-360q-56 0-111 13.5T140-306q-9 5-14.5 14t-5.5 20v32Zm240-320q33 0 56.5-23.5T440-640q0-33-23.5-56.5T360-720q-33 0-56.5 23.5T280-640q0 33 23.5 56.5T360-560Zm0 260Zm0-340Z"/>',subagentStart:'<path d="M480-240Zm-320 80v-112q0-34 17.5-62.5T224-378q62-31 126-46.5T480-440q37 0 73 4.5t72 14.5l-67 68q-20-3-39-5t-39-2q-56 0-111 13.5T260-306q-9 5-14.5 14t-5.5 20v32h240v80H160Zm400 40v-123l221-220q9-9 20-13t22-4q12 0 23 4.5t20 13.5l37 37q8 9 12.5 20t4.5 22q0 11-4 22.5T903-340L683-120H560Zm300-263-37-37 37 37ZM620-180h38l121-122-18-19-19-18-122 121v38Zm141-141-19-18 37 37-18-19ZM480-480q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47Zm0-80q33 0 56.5-23.5T560-640q0-33-23.5-56.5T480-720q-33 0-56.5 23.5T400-640q0 33 23.5 56.5T480-560Zm0-80Z"/>',agent:'<path d="M309-389q29 29 71 29t71-29l160-160q29-29 29-71t-29-71q-29-29-71-29t-71 29q-37-13-73-6t-61 32q-25 25-32 61t6 73q-29 29-29 71t29 71ZM240-80v-172q-57-52-88.5-121.5T120-520q0-150 105-255t255-105q125 0 221.5 73.5T827-615l52 205q5 19-7 34.5T840-360h-80v120q0 33-23.5 56.5T680-160h-80v80h-80v-160h160v-200h108l-38-155q-23-91-98-148t-172-57q-116 0-198 81t-82 197q0 60 24.5 114t69.5 96l26 24v208h-80Zm254-360Z"/>',pause:'<path d="M520-200v-560h240v560H520Zm-320 0v-560h240v560H200Zm400-80h80v-400h-80v400Zm-320 0h80v-400h-80v400Zm0-400v400-400Zm320 0v400-400Z"/>',play:'<path d="M320-200v-560l440 280-440 280Zm80-280Zm0 134 210-134-210-134v268Z"/>',lightbulb:'<path d="M480-80q-34 0-57.5-23.5T399-161h162q0 34-23.5 57.5T480-80ZM318-223v-80h324v80H318Zm5-120q-66-43-104.5-107.5T180-597q0-122 89-211t211-89q122 0 211 89t89 211q0 82-38.5 146.5T637-343H323Zm22-80h270q44-29 69.5-71.5T710-597q0-97-66.5-163.5T480-827q-97 0-163.5 66.5T250-597q0 60 25.5 102.5T345-423Zm135 0Z"/>',approveCircle:'<path d="m424-296 282-282-56-56-226 226-114-114-56 56 170 170Zm56 216q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/>',rejectCircle:'<path d="M480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q54 0 104-17.5t92-50.5L228-676q-33 42-50.5 92T160-480q0 134 93 227t227 93Zm252-124q33-42 50.5-92T800-480q0-134-93-227t-227-93q-54 0-104 17.5T284-732l448 448ZM480-480Z"/>',doubleCheck:'<path d="m381-240 424-424-57-56-368 367-169-170-57 57 227 226Zm0 113L42-466l169-170 170 170 366-367 172 168-538 538Z"/>',approvalWarning:'<path d="M480-120q-33 0-56.5-23.5T400-200q0-33 23.5-56.5T480-280q33 0 56.5 23.5T560-200q0 33-23.5 56.5T480-120Zm-80-240v-480h160v480H400Z"/>'},A={folder:"#ffc107",file:"#2196f3",explore:"#757575",read:"#757575",write:"#757575",success:"#4caf50",error:"#f44336",warning:"#ff9800",info:"#2196f3",check:"#757575",edit:"#757575",search:"#757575",save:"#4caf50",diagnostics:"#607d8b",question:"#2196f3",description:"#2196f3",code:"#9c27b0",terminal:"#607d8b",analytics:"#00bcd4",skip:"#9e9e9e",planner:"#e91e63",build:"#ff5722",person:"#795548",researcher:"#3f51b5",expandMore:"#757575",expandLess:"#757575",chevronRight:"#757575",summary:"#4caf50",assignment:"#2196f3",listAlt:"#ff9800",tool:"#757575",agent:"#757575",subagentComplete:"#757575",subagentStart:"#757575",pause:"#757575",play:"#757575",thinking:"#757575",lightbulb:"#ffc107",approveCircle:"#4caf50",rejectCircle:"#f44336",doubleCheck:"#4caf50",approvalWarning:"#ff9800"};function I(e,t=16,n){return N($[e],n||A[e]||"currentColor",t)}function P(e,t=16,n){return j(T[e],n||A[e]||"currentColor",t)}function L(e,t=16,n){return e in T?j(T[e],n||A[e]||"currentColor",t):e in $?N($[e],n||A[e]||"currentColor",t):""}const M={folder:I("folder"),file:I("file"),explore:I("explore"),read:I("read"),write:I("write"),success:I("success"),error:I("error"),warning:I("warning"),info:I("info"),check:I("check"),thinking:P("thinking"),edit:I("edit"),search:I("search"),save:I("save"),diagnostics:I("diagnostics"),question:I("question"),description:P("description"),code:I("code"),terminal:I("terminal"),analytics:I("analytics"),skip:I("skip"),planner:I("planner"),build:I("build"),person:I("person"),researcher:I("researcher"),expandMore:I("expandMore"),expandLess:I("expandLess"),chevronRight:I("chevronRight"),summary:I("summary"),assignment:P("assignment"),listAlt:I("listAlt"),tool:P("tool"),agent:P("agent"),subagentComplete:P("subagentComplete"),subagentStart:P("subagentStart"),pause:P("pause"),play:P("play"),lightbulb:P("lightbulb"),riskLow:I("success",16,"#4caf50"),riskMedium:I("info",16,"#2196f3"),riskHigh:I("warning",16,"#ff9800"),riskCritical:I("error",16,"#f44336"),approveCircle:P("approveCircle",20),rejectCircle:P("rejectCircle",20),doubleCheck:P("doubleCheck",16),approvalWarning:P("approvalWarning",16)};var R=n(5981),q=n.n(R),D=n(7192),O=n.n(D),z=n(5089),F=n.n(z),B=n(5772),W=n.n(B),U=n(6033),H=n.n(U),J=n(6384),V=n.n(J),G=n(5344),X=n.n(G),Z=n(1786),K=n.n(Z),Q=n(7285),Y=n.n(Q),ee=n(7533),te=n.n(ee),ne=n(2825),ae=n.n(ne);function re(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function se(e,t){let n=0,a=!1,r=!1;for(let s=t;s<e.length;s++){const t=e[s];if(a){if(r){r=!1;continue}if("\\"===t){r=!0;continue}'"'===t&&(a=!1)}else if('"'!==t){if("{"===t)n+=1;else if("}"===t&&(n-=1,0===n))return s}else a=!0}return-1}function oe(e){const t=e.trim();if(!t.startsWith("{")||!t.endsWith("}"))return console.log("[parseNextItemsPayload] Invalid JSON structure - starts with:",t.slice(0,20),"ends with:",t.slice(-20)),null;let n=e=t;e.includes('\\"')&&!e.includes('{"')&&(console.log("[parseNextItemsPayload] Detected escaped JSON, attempting to unescape"),n=e.replace(/\\"/g,'"').replace(/\\\\/g,"\\"),console.log("[parseNextItemsPayload] Unescaped JSON preview:",n.slice(0,100)));try{console.log("[parseNextItemsPayload] Attempting to parse JSON, length:",n.length);const e=JSON.parse(n);if(console.log("[parseNextItemsPayload] JSON parsed successfully, keys:",Object.keys(e)),!e||"object"!=typeof e||Array.isArray(e))return null;const t=e.next_items;if(!Array.isArray(t))return null;const a=t.map(e=>{if(!e||"object"!=typeof e)return null;const t="string"==typeof e.subject?e.subject.trim():"",n="string"==typeof e.description?e.description.trim():"";return t||n?{subject:t,description:n}:null}).filter(e=>Boolean(e)),r=e.summary,s="string"==typeof r&&r.trim()?r.trim():null;return a.length>0||s?{items:a,summary:s}:null}catch(t){return console.error("[parseNextItemsPayload] JSON parse error:",t),console.error("[parseNextItemsPayload] Failed payload:",e.slice(0,500)),null}}function le(e,t){try{return q().highlight(e,{language:t}).value}catch{return re(e)}}function ce(e,t){return t?le(e,t):re(e)}q().registerLanguage("python",O()),q().registerLanguage("javascript",F()),q().registerLanguage("json",W()),q().registerLanguage("diff",H()),q().registerLanguage("sql",V()),q().registerLanguage("bash",X()),q().registerLanguage("java",K()),q().registerLanguage("xml",Y()),q().registerLanguage("yaml",te()),q().registerLanguage("typescript",ae());const ie=/BUILD (?:SUCCESS|FAILURE|FAILED)|\bTests run: \d+|^\[(?:INFO|ERROR|WARNING|WARN)\]|\b\d+ (?:passed|failed)\b/m;function de(e){return ie.test(e)}const ue=[[/\bBUILD (?:SUCCESS(?:FUL)?)\b/g,'<span class="jp-log-success">$&</span>'],[/\bBUILD (?:FAILURE|FAILED)\b/g,'<span class="jp-log-failure">$&</span>'],[/\[(?:ERROR|FATAL)\]/g,'<span class="jp-log-failure">$&</span>'],[/\[(?:WARNING|WARN)\]/g,'<span class="jp-log-warning">$&</span>'],[/\[INFO\]/g,'<span class="jp-log-info">$&</span>'],[/\b(Failures|Errors): (\d+)/g,(e,t,n)=>`${t}: <span class="jp-log-${"0"===n?"success":"failure"}">${n}</span>`],[/\b(Tests run|Skipped): (\d+)/g,'$1: <span class="jp-log-number">$2</span>'],[/\b\d+ passed\b/g,'<span class="jp-log-success">$&</span>'],[/\b\d+ (?:failed|errors?)\b/g,'<span class="jp-log-failure">$&</span>']];function me(e){let t=re(e);for(const[e,n]of ue)t=t.replace(e,n);return t}function pe(e){return le(e,"python")}function he(e){return le(e,"diff")}function ge(e){return le(e,"javascript")}function fe(e){return le(e,"json")}function be(e){let t=re(e);return t=t.replace(/`([^`]+)`/g,'<code class="inline-code">$1</code>'),t=t.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),t=t.replace(/\*([^*]+)\*/g,"<em>$1</em>"),t}function ve(e){const t=e.trim().split("\n");if(t.length<2)return re(e);const n=t.findIndex(e=>/^\|?\s*[-:]+[-|\s:]+\s*\|?$/.test(e));if(-1===n||0===n)return re(e);const a=t.slice(0,n),r=t[n],s=t.slice(n+1),o=[];r.split("|").filter(e=>e.trim()).forEach(e=>{const t=e.trim();t.startsWith(":")&&t.endsWith(":")?o.push("center"):t.endsWith(":")?o.push("right"):o.push("left")});let l='<div class="markdown-table-wrapper"><table class="markdown-table">';return l+="<thead>",a.forEach(e=>{l+="<tr>",e.split("|").filter((e,t,n)=>!(0===t&&""===e.trim()||t===n.length-1&&""===e.trim())).forEach((e,t)=>{o[t],l+=`<th style="text-align: center;">${be(e.trim())}</th>`}),l+="</tr>"}),l+="</thead>",s.length>0&&(l+="<tbody>",s.forEach(e=>{e.trim()&&(l+="<tr>",e.split("|").filter((e,t,n)=>!(0===t&&""===e.trim()||t===n.length-1&&""===e.trim())).forEach((e,t)=>{o[t],l+=`<td style="text-align: left;">${be(e.trim())}</td>`}),l+="</tr>")}),l+="</tbody>"),l+="</table></div>",l}function ye(e,t){const n=t.endsWith("/")?t:t+"/",a=n.replace(/^(https?:\/\/[^/]+).*$/,"$1"),r=n.slice(a.length);let s=e.replace(/(https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0):(\d{2,5}))(?:\/([^\s)<>"'`]*))?/g,(e,t,r,s)=>t===a?e:`${n}proxy/${r}/${s??""}`);const o=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return s=s.replace(new RegExp(`(^|[\\s(<])(${o}proxy/(?:absolute/)?\\d{2,5})(?=[/?#)>\\s]|$)`,"g"),(e,t,n)=>`${t}${a}${n}`),s}function Ee(e){console.log("[formatMarkdownToHtml] Input text length:",e.length),console.log('[formatMarkdownToHtml] Has "next_items":',e.includes('"next_items"')),console.log("[formatMarkdownToHtml] Text preview:",e.slice(0,150));const t=function(e){if(!e.trim())return null;const t=e.includes('"summary"'),n=e.includes('"next_items"');t&&n&&(console.log("[extractNextItemsBlock] Found summary JSON markers, text length:",e.length),console.log("[extractNextItemsBlock] Text preview:",e.slice(0,200)));const a=[/```(\w+)?\n([\s\S]*?)```/g,/```(\w+)?({[\s\S]*?})```/g];for(const t of a){let n;for(;null!==(n=t.exec(e));){const t=(n[1]||"").toLowerCase(),a=n[2].trim();if(!a)continue;if(t&&"json"!==t&&!a.includes('"next_items"'))continue;const r=oe(a);if(r){const t=`__NEXT_ITEMS_${Math.random().toString(36).slice(2,11)}__`,a=e.slice(0,n.index)+t+e.slice(n.index+n[0].length);return{items:r.items,summary:r.summary,placeholder:t,text:a}}}t.lastIndex=0}const r=function(e){const t=e.indexOf('"next_items"');if(-1===t)return null;const n=[];for(let a=0;a<t;a++)"{"===e[a]&&n.push(a);console.log("[findNextItemsJsonRange] Found",n.length,'candidate { positions before "next_items"');for(const a of n){const n=se(e,a);if(-1!==n&&n>t)return console.log("[findNextItemsJsonRange] Found valid range:",a,"-",n),{start:a,end:n}}return null}(e);if(!r)return console.log("[extractNextItemsBlock] findNextItemsJsonRange returned null"),null;console.log("[extractNextItemsBlock] Found JSON range:",r.start,"-",r.end);const s=e.slice(r.start,r.end+1);console.log("[extractNextItemsBlock] Candidate JSON length:",s.length),console.log("[extractNextItemsBlock] Candidate JSON preview:",s.slice(0,200));const o=oe(s);if(!o)return console.log("[extractNextItemsBlock] parseNextItemsPayload returned null"),null;let l=r.start,c=r.end;const i=e.lastIndexOf("\n",r.start-1)+1;"json"===e.slice(i,r.start).trim().replace(/[::]$/,"").toLowerCase()&&(l=i);const d=e.slice(0,l),u=[/\{\s*"summary"\s*:\s*$/,/\{\s*"next_items"\s*:\s*$/,/\{\s*$/];for(const e of u){const t=d.match(e);if(t){const e=d.lastIndexOf(t[0]);if(-1!==e){console.log("[extractNextItemsBlock] Found orphaned wrapper:",t[0]),l=e;break}}}const m=e.slice(r.end+1).match(/^\s*\}/);m&&(console.log("[extractNextItemsBlock] Found orphaned closing brace"),c=r.end+m[0].length);const p=`__NEXT_ITEMS_${Math.random().toString(36).slice(2,11)}__`,h=e.slice(0,l)+p+e.slice(c+1);return console.log("[extractNextItemsBlock] Replacement range:",l,"-",c),console.log("[extractNextItemsBlock] Updated text preview:",h.slice(0,100)),{items:o.items,summary:o.summary,placeholder:p,text:h}}(e);console.log("[formatMarkdownToHtml] nextItemsBlock result:",t?"found":"null");const n=document.createElement("textarea");n.innerHTML=t?t.text:e;let a=n.value;const r=[];a=a.replace(/<!--DFHTML-->([\s\S]*?)<!--\/DFHTML-->/g,(e,t)=>{const n="__DATAFRAME_HTML_"+Math.random().toString(36).substr(2,9)+"__";return r.push({placeholder:n,html:t}),n});const s=[],o=[];a=a.replace(/```(\w+)?\n([\s\S]*?)```/g,(e,t,n)=>{const a=(t||"python").toLowerCase(),r=function(e){return e.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&#x27;/g,"'")}(function(e){const t=e.split("\n");let n=1/0;const a=[];for(let e=0;e<t.length;e++){const r=t[e];if(r.trim().length>0){const t=r.match(/^(\s*)/),s=t?t[1].length:0;n=Math.min(n,s),a.push(e)}}return n===1/0||0===n?e:t.map(e=>0===e.trim().length?"":e.substring(n)).join("\n")}(n.trim())),l="code-block-"+function(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n),t&=t;return Math.abs(t).toString(36)}(r+a),c="__CODE_BLOCK_"+l+"__";s.push({id:l,code:r,language:a});const i="diff"===a,d=i?he(r):"python"===a||"py"===a?pe(r):"javascript"===a||"js"===a?ge(r):"json"===a?fe(r):de(r)?me(r):re(r);let u="";if(i){const{additions:e,deletions:t}=function(e){const t=e.split("\n");let n=0,a=0;for(const e of t)e.startsWith("+++")||e.startsWith("---")||(e.startsWith("+")?n++:e.startsWith("-")&&a++);return{additions:n,deletions:a}}(r);u='<span class="diff-line-counts"><span class="diff-additions">+'+e+'</span><span class="diff-deletions">-'+t+"</span></span>"}const m='<div class="code-block-container'+(i?" diff-block":"")+'" data-block-id="'+l+'"><div class="code-block-header"><span class="code-block-language">'+re(a)+"</span>"+u+'<div class="code-block-actions">'+(i?"":'<button class="code-block-apply" data-block-id="'+l+'" title="셀에 적용">셀에 적용</button>')+'<button class="code-block-copy" data-block-id="'+l+'" title="복사">복사</button></div></div><pre class="code-block language-'+re(a)+'"><code id="'+l+'">'+d+'</code></pre><button class="code-block-toggle" data-block-id="'+l+'" title="전체 보기" aria-label="전체 보기" aria-expanded="false"><span class="code-block-toggle-icon" aria-hidden="true">▾</span></button></div>';return o.push({placeholder:c,html:m}),c});const l=[];a=a.replace(/`([^`]+)`/g,(e,t)=>{const n="__INLINE_CODE_"+Math.random().toString(36).substr(2,9)+"__";return l.push({placeholder:n,html:'<code class="inline-code">'+re(t)+"</code>"}),n}),a=ye(a,c.PageConfig.getBaseUrl());const i=[];return a=a.replace(/(?:^|\n)((?:\|[^\n]+\|\n?)+\|[-:| ]+\|(?:\n\|[^\n]+\|)*)/gm,(e,t)=>{const n="__TABLE_"+Math.random().toString(36).substr(2,9)+"__",a=ve(t.trim());return i.push({placeholder:n,html:a}),"\n"+n+"\n"}),a=a.replace(/(?:^|\n)((?:[^\n|]+\|[^\n]+\n)+[-:|\s]+[-|]+\n(?:[^\n|]+\|[^\n]+\n?)*)/gm,(e,t)=>{if(t.includes("__TABLE_"))return e;const n="__TABLE_"+Math.random().toString(36).substr(2,9)+"__",a=ve(t.trim());return i.push({placeholder:n,html:a}),"\n"+n+"\n"}),a=a.replace(/(?:^|\n)(\|[^\n]*\|\n\|[-:| ]*\|(?:\n\|[^\n]*\|)*)/gm,(e,t)=>{if(t.includes("__TABLE_"))return e;const n="__TABLE_"+Math.random().toString(36).substr(2,9)+"__",a=ve(t.trim());return i.push({placeholder:n,html:a}),"\n"+n+"\n"}),a=a.split(/(__(?:DATAFRAME_HTML|CODE_BLOCK|INLINE_CODE|TABLE|NEXT_ITEMS)_[a-z0-9-]+__)/gi).map((e,t)=>t%2==1?e:re(e)).join(""),a=a.replace(/^###### (.*$)/gim,"<h6>$1</h6>"),a=a.replace(/^##### (.*$)/gim,"<h5>$1</h5>"),a=a.replace(/^#### (.*$)/gim,"<h4>$1</h4>"),a=a.replace(/^### (.*$)/gim,"<h3>$1</h3>"),a=a.replace(/^## (.*$)/gim,"<h2>$1</h2>"),a=a.replace(/^# (.*$)/gim,"<h1>$1</h1>"),a=a.replace(/^---+$/gim,"<hr>"),a=a.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'),a=a.replace(/^[\-\*]\s+(.*$)/gim,"<li>$1</li>"),a=a.replace(/^\d+\.\s+(.*$)/gim,"<li>$1</li>"),a=a.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),a=a.replace(/(?<!\*)\*([^*\n]+)\*(?!\*)/g,"<em>$1</em>"),a=a.replace(/\n/g,"<br>"),i.forEach(e=>{a=a.replace(e.placeholder,()=>e.html)}),r.forEach(e=>{a=a.replace(e.placeholder,()=>e.html)}),l.forEach(e=>{a=a.replace(e.placeholder,()=>e.html)}),o.forEach(e=>{a=a.replace(e.placeholder,()=>e.html)}),t&&(a=a.split(t.placeholder).join(function(e,t){const n=e.map(e=>{const t=re(e.subject),n=re(e.description);return`\n<li class="jp-next-items-item" data-next-item="true" role="button" tabindex="0">\n <div class="jp-next-items-text">\n ${t?`<div class="jp-next-items-subject">${t}</div>`:""}\n ${n?`<div class="jp-next-items-description">${n}</div>`:""}\n </div>\n \n<svg class="jp-next-items-icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">\n <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/>\n</svg>\n</li>`}).join(""),a=L("summary",18),r=L("assignment",18);return`${t?`\n<div class="jp-summary-block">\n <div class="jp-summary-header"><span class="jp-summary-header-icon">${a}</span>작업 요약</div>\n <div class="jp-summary-body">\n \n<svg class="jp-summary-icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">\n <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>\n</svg>\n <div class="jp-summary-content">${re(t)}</div>\n </div>\n</div>`:""}\n${e.length>0?`\n<div class="jp-next-items" data-next-items="true">\n <div class="jp-next-items-header"><span class="jp-next-items-header-icon">${r}</span>다음 단계 제안</div>\n <ul class="jp-next-items-list" role="list">\n ${n}\n </ul>\n</div>`:""}`}(t.items,t.summary))),a}var ke=n(4849);const we="codebuff.diff.layout",xe={java:"java",py:"python",sh:"bash",bash:"bash",js:"javascript",jsx:"javascript",mjs:"javascript",ts:"typescript",tsx:"typescript",json:"json",xml:"xml",html:"xml",yml:"yaml",yaml:"yaml",sql:"sql"},Se=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/;function _e(e){let t=0,n=0;for(const a of e.hunks)for(const e of a.lines)"add"===e.type?t++:"del"===e.type&&n++;return e.added=t,e.removed=n,e}function Ce(e,t){const n=Se.exec(e);let a=n?Number(n[1]):1,r=n?Number(n[2]):1;const s=[];for(const e of t){const t=e.charAt(0),n=e.slice(1);"+"===t?s.push({type:"add",text:n,newNo:r++}):"-"===t?s.push({type:"del",text:n,oldNo:a++}):" "===t?s.push({type:"ctx",text:n,oldNo:a++,newNo:r++}):"\\"===t||s.push({type:"note",text:e})}return{header:e,lines:s}}function Ne(e,t,n,a=3){return _e({path:e,hunks:(0,ke.structuredPatch)(e,e,t,n,"","",{context:a}).hunks.map(e=>Ce(`@@ -${e.oldStart},${e.oldLines} +${e.newStart},${e.newLines} @@`,e.lines)),added:0,removed:0})}function je(e){const t=e.slice(4).split("\t")[0].trim();return"/dev/null"===t?"":t.replace(/^[ab]\//,"")}function $e(e,t=""){const n=[];let a=null,r="",s=[],o=0,l=0,c=!1,i="";const d=()=>{a&&r&&a.hunks.push(Ce(r,s)),r="",s=[],c=!1},u=e=>{d(),a={path:e,hunks:[],added:0,removed:0},n.push(a)},m=e.split("\n");for(let e=0;e<m.length;e++){const n=m[e],p=n.startsWith("--- ")&&(m[e+1]??"").startsWith("+++ ")&&(m[e+2]??"").startsWith("@@ "),h=n.startsWith("diff --git ")||n.startsWith("@@ ")||p;if(r&&c&&(o>0||l>0)&&!h){const e=n.charAt(0);"+"===e?l--:"-"===e?o--:" "!==e&&""!==n||(o--,l--),s.push(""===n?" ":n);continue}if(n.startsWith("diff --git ")){const e=/ b\/(.+)$/.exec(n);u(e?e[1]:""),i="";continue}if(!n.startsWith("--- ")||r&&!(m[e+1]??"").startsWith("+++ ")){if(n.startsWith("+++ ")&&a&&!r){const e=a;e.path=je(n)||i||e.path;continue}if(n.startsWith("@@")){a||u(t),d(),r=n;const e=/^@@ -\d+(?:,(\d+))? \+\d+(?:,(\d+))? @@/.exec(n);c=!!e,o=e?Number(e[1]??1):0,l=e?Number(e[2]??1):0;continue}r&&(n.trim()||/^[ +\-\\]/.test(n))&&s.push(n)}else i=je(n),(!a||a.hunks.length||r)&&u(i)}return d(),n.filter(e=>e.hunks.length).map(e=>(e.path||(e.path=t),_e(e)))}function Te(e){const t=[];let n=[],a=[];const r=()=>{const e=Math.max(n.length,a.length);for(let r=0;r<e;r++)t.push({left:n[r],right:a[r]});n=[],a=[]};for(const s of e.lines)"del"===s.type?(a.length&&r(),n.push(s)):"add"===s.type?a.push(s):(r(),t.push({left:s,right:s}));return r(),t}function Ae(e){return e.reduce((e,t)=>({files:e.files+1,added:e.added+t.added,removed:e.removed+t.removed}),{files:0,added:0,removed:0})}function Ie(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}const Pe={add:"+",del:"-",ctx:" ",note:""};function Le(e,t,n){return"note"!==e.type&&t&&n.highlight?n.highlight(e.text,t):Ie(e.text)}function Me(e,t,n){return`<div class="jp-diff-line jp-diff-line-${e.type}"><span class="jp-diff-ln">${e.oldNo??""}</span><span class="jp-diff-ln">${e.newNo??""}</span><span class="jp-diff-sign">${Pe[e.type]}</span><span class="jp-diff-code">${Le(e,t,n)}</span></div>`}function Re(e,t,n,a){return e?`<span class="jp-diff-ln">${("old"===t?e.oldNo:e.newNo)??""}</span><span class="jp-diff-code jp-diff-code-${e.type}">${Le(e,n,a)}</span>`:'<span class="jp-diff-ln"></span><span class="jp-diff-code jp-diff-empty"></span>'}function qe(e,t={}){const n="split"===t.layout?"split":"unified",a=Ae(e),r="split"===n?"한 줄로 보기":"나란히 보기";return`<div class="jp-diff-view" data-layout="${n}"><div class="jp-diff-toolbar"><span class="jp-diff-total">파일 ${a.files}개 <span class="jp-diff-count-add">+${a.added}</span> <span class="jp-diff-count-del">−${a.removed}</span></span><button type="button" class="jp-diff-layout-toggle" title="${r}" aria-label="${r}">${r}</button></div>${e.map(e=>function(e,t){const n=function(e){const t=e.split("/").pop()||"",n=t.lastIndexOf(".");return n<=0?"":xe[t.slice(n+1).toLowerCase()]||""}(e.path),a=[],r=[];for(const s of e.hunks){const e=`<div class="jp-diff-hunk-header">${Ie(s.header)}</div>`;a.push(`<div class="jp-diff-hunk">${e}${s.lines.map(e=>Me(e,n,t)).join("")}</div>`),r.push(`<div class="jp-diff-hunk">${e}${Te(s).map(e=>`<div class="jp-diff-row">${Re(e.left,"old",n,t)}${Re(e.right,"new",n,t)}</div>`).join("")}</div>`)}return`<details class="jp-diff-file"${t.collapsed?"":" open"}><summary class="jp-diff-file-header"><span class="jp-diff-file-path">${Ie(e.path||"(경로 없음)")}</span><span class="jp-diff-count-add">+${e.added}</span><span class="jp-diff-count-del">−${e.removed}</span></summary><div class="jp-diff-unified">${a.join("")}</div><div class="jp-diff-split">${r.join("")}</div></details>`}(e,t)).join("")}</div>`}function De(e){if(e.skipped||!e.diff)return`\n\n> 파일 변경: \`${e.path}\` (크거나 바이너리라 diff 생략)\n\n`;const t=Math.max(2,...(e.diff.match(/`+/g)||[]).map(e=>e.length)),n="`".repeat(t+1);return`\n\n${n}diff\n--- a/${e.path}\n+++ b/${e.path}\n${e.diff}\n${n}\n\n`}function Oe(e,t){const n=void 0!==t.before&&void 0!==t.after;if(!n&&!t.diff)return e;const a=e.findIndex(e=>e.path===t.path);if(a<0)return[...e,t];const r=e[a],s=n&&void 0!==r.before?{path:t.path,before:r.before,after:t.after}:t;return e.map((e,t)=>t===a?s:e)}function ze(){try{return"split"===window.localStorage.getItem(we)?"split":"unified"}catch{return"unified"}}let Fe=!1;function Be(){Fe||"undefined"==typeof document||(Fe=!0,document.addEventListener("click",e=>{const t=e.target,n=t?.closest?.(".jp-diff-layout-toggle");if(!n)return;e.preventDefault();const a=n.closest(".jp-diff-view"),r="split"===a?.getAttribute("data-layout")?"unified":"split";try{window.localStorage.setItem(we,r)}catch{}const s="split"===r?"한 줄로 보기":"나란히 보기";document.querySelectorAll(".jp-diff-view").forEach(e=>{e.setAttribute("data-layout",r);const t=e.querySelector(".jp-diff-layout-toggle");t&&(t.textContent=s,t.setAttribute("title",s),t.setAttribute("aria-label",s))})}))}const We=({changes:e})=>{const[t,n]=(0,i.useState)(!1),a=(0,i.useMemo)(()=>e.flatMap(e=>void 0!==e.before&&void 0!==e.after?[Ne(e.path,e.before,e.after)]:$e(e.diff||"",e.path)),[e]),r=(0,i.useMemo)(()=>t?(Be(),qe(a,{layout:ze(),highlight:ce})):"",[t,a]);if(!e.length)return null;const{added:s,removed:o}=Ae(a);return d().createElement("div",{className:"jp-agent-session-diff"},d().createElement("button",{type:"button",className:"jp-agent-session-diff-toggle","aria-expanded":t,title:t?"변경 내용 접기":"변경 내용 펼치기",onClick:()=>n(!t)},"변경 ",e.length,"개 파일",d().createElement("span",{className:"jp-diff-count-add"},"+",s),d().createElement("span",{className:"jp-diff-count-del"},"−",o)),t&&d().createElement("div",{className:"jp-agent-session-diff-body",dangerouslySetInnerHTML:{__html:r}}))},Ue=({filename:e,options:t,message:n,onSelect:a,onCancel:r})=>d().createElement("div",{className:"file-selection-dialog"},d().createElement("div",{className:"file-selection-overlay",onClick:r}),d().createElement("div",{className:"file-selection-content"},d().createElement("h3",null,"파일 선택"),d().createElement("p",{className:"file-selection-message"},n),d().createElement("div",{className:"file-selection-options"},t.map((e,t)=>d().createElement("button",{key:t,className:"file-option-button",onClick:()=>a(t+1)},d().createElement("span",{className:"file-option-number"},t+1),d().createElement("span",{className:"file-option-path"},e.relative)))),d().createElement("div",{className:"file-selection-actions"},d().createElement("button",{className:"file-selection-cancel",onClick:r},"취소"))),d().createElement("style",null,"\n .file-selection-dialog {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .file-selection-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n }\n\n .file-selection-content {\n position: relative;\n background: var(--jp-layout-color1);\n border: 1px solid var(--jp-border-color1);\n border-radius: 8px;\n padding: 24px;\n max-width: 600px;\n width: 90%;\n max-height: 80vh;\n overflow-y: auto;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n }\n\n .file-selection-content h3 {\n margin: 0 0 12px 0;\n color: var(--jp-ui-font-color1);\n font-size: 18px;\n font-weight: 600;\n }\n\n .file-selection-message {\n margin: 0 0 20px 0;\n color: var(--jp-ui-font-color2);\n font-size: 14px;\n white-space: pre-wrap;\n line-height: 1.6;\n }\n\n .file-selection-options {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 20px;\n }\n\n .file-option-button {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n background: var(--jp-layout-color2);\n border: 1px solid var(--jp-border-color2);\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n text-align: left;\n }\n\n .file-option-button:hover {\n background: var(--jp-layout-color3);\n border-color: var(--jp-brand-color1);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n }\n\n .file-option-number {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n background: var(--jp-brand-color1);\n color: white;\n border-radius: 50%;\n font-weight: 600;\n font-size: 14px;\n flex-shrink: 0;\n }\n\n .file-option-path {\n flex: 1;\n color: var(--jp-ui-font-color1);\n font-family: var(--jp-code-font-family);\n font-size: 13px;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .file-selection-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n }\n\n .file-selection-cancel {\n padding: 8px 16px;\n background: transparent;\n border: 1px solid var(--jp-border-color2);\n border-radius: 4px;\n color: var(--jp-ui-font-color1);\n cursor: pointer;\n font-size: 14px;\n transition: all 0.2s;\n }\n\n .file-selection-cancel:hover {\n background: var(--jp-layout-color2);\n border-color: var(--jp-border-color1);\n }\n "));var He=n(7628);function Je(e){const t={hasUnclosedCodeBlock:!1,hasUnclosedInlineCode:!1,hasUnclosedBold:!1,hasUnclosedItalic:!1,hasUnclosedLink:!1,hasUnclosedTable:!1,lastStableIndex:e.length};if(!e)return t;const n=e.match(/```/g),a=n?n.length:0;if(t.hasUnclosedCodeBlock=a%2!=0,t.hasUnclosedCodeBlock){const n=e.lastIndexOf("```");t.lastStableIndex=Math.min(t.lastStableIndex,n)}if(!t.hasUnclosedCodeBlock){const n=e.split("\n"),a=n[n.length-1];let r=0,s=0;for(;s<a.length;){if("`"===a[s]){if("```"===a.substring(s,s+3)){s+=3;continue}r++}s++}t.hasUnclosedInlineCode=r%2!=0}if(!t.hasUnclosedCodeBlock){const n=(e.split("\n").pop()||"").match(/\*\*/g),a=n?n.length:0;t.hasUnclosedBold=a%2!=0}if(!t.hasUnclosedCodeBlock&&!t.hasUnclosedBold){const n=(e.split("\n").pop()||"").replace(/\*\*/g,"").match(/\*/g),a=n?n.length:0;t.hasUnclosedItalic=a%2!=0}const r=e.split("\n").pop()||"",s=r.lastIndexOf("["),o=r.lastIndexOf("]"),l=r.lastIndexOf("("),c=r.lastIndexOf(")");(s>o||o>-1&&l>o&&l>c)&&(t.hasUnclosedLink=!0);const i=e.split("\n").filter(e=>e.trim()).pop()||"";if(i.trim().startsWith("|")&&!i.trim().endsWith("|")&&(t.hasUnclosedTable=!0),t.hasUnclosedInlineCode||t.hasUnclosedBold||t.hasUnclosedItalic||t.hasUnclosedLink){const n=e.lastIndexOf("\n");t.lastStableIndex=Math.min(t.lastStableIndex,n>0?n:0)}return t}function Ve(e){return e.hasUnclosedCodeBlock||e.hasUnclosedInlineCode||e.hasUnclosedBold||e.hasUnclosedItalic||e.hasUnclosedLink||e.hasUnclosedTable}function Ge(e,t){let n=e;if(t.hasUnclosedCodeBlock){const e=n.lastIndexOf("```"),t=n.substring(e+3);return(t.indexOf("\n")>-1||t.length>0)&&(n+="\n```"),n}if(t.hasUnclosedInlineCode&&(n+="`"),t.hasUnclosedBold&&(n+="**"),t.hasUnclosedItalic&&(n+="*"),t.hasUnclosedLink){const e=n.split("\n").pop()||"",t=e.lastIndexOf("["),a=e.lastIndexOf("]"),r=e.lastIndexOf("(");t>a?n+="]":r>a&&(n+=")")}return t.hasUnclosedTable&&(n+=" |"),n}var Xe,Ze=n(2722);!function(e){e[e.None=0]="None",e[e.Copying=1]="Copying",e[e.Copied=2]="Copied",e[e.Disabled=3]="Disabled"}(Xe||(Xe={}));const Ke=()=>d().createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor"},d().createElement("path",{d:"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"})),Qe=()=>d().createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor"},d().createElement("path",{d:"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"}));function Ye({value:e,className:t}){const n="undefined"==typeof document,[a,r]=(0,i.useState)(n?Xe.Disabled:Xe.None),s=(0,i.useRef)(null),o=(0,i.useCallback)(async()=>{if(a!==Xe.Copying){try{await async function(e){if(navigator.clipboard&&window.isSecureContext)return void await navigator.clipboard.writeText(e);const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();const n=document.execCommand("copy");if(document.body.removeChild(t),!n)throw new Error("execCommand copy failed")}(e),(window._codebuffAgentCopiedCodes??(window._codebuffAgentCopiedCodes=new Set)).add(e.trim()),Ze.c.getInstance().trackClick("code_copy_from_agent",{code_length:e.length,code_lines:e.split("\n").length,block_id:Ze.c.blockIdOf(e)})}catch(e){return console.error("Failed to copy text:",e),void r(Xe.None)}r(Xe.Copied),s.current&&clearTimeout(s.current),s.current=window.setTimeout(()=>r(Xe.None),1500)}},[a,e]),l=a===Xe.Copied,c=l?"복사됨!":"클립보드에 복사";return d().createElement("button",{className:`jp-codebuff-toolbar-btn ${t||""} ${l?"jp-codebuff-toolbar-btn-copied":""}`,onClick:o,disabled:n,title:c,"aria-label":"Copy to clipboard"},l?d().createElement(Qe,null):d().createElement(Ke,null),l&&d().createElement("span",{className:"jp-codebuff-copy-tooltip",role:"status"},"복사됨"))}const et=()=>d().createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor"},d().createElement("path",{d:"M8 11h3v10h2V11h3l-4-4-4 4zM4 3v2h16V3H4z"})),tt=()=>d().createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor"},d().createElement("path",{d:"M16 13h-3V3h-2v10H8l4 4 4-4zM4 19v2h16v-2H4z"})),nt=()=>d().createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor"},d().createElement("path",{d:"M14 10H2v2h12v-2zm0-4H2v2h12V6zm4 8v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zM2 16h8v-2H2v2z"})),at=()=>d().createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor"},d().createElement("path",{d:"M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8A5.87 5.87 0 0 1 6 12c0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z"}));function rt({content:e,language:t,onInsertAbove:n,onInsertBelow:a,onInsertAsCell:r,onReplaceCell:s,cellActionsEnabled:o=!0}){const l=(0,i.useRef)(!1);(0,i.useEffect)(()=>{l.current||(l.current=!0,Ze.c.getInstance().trackImpression("code_block_shown",{code_length:e.length,code_lines:e.split("\n").length,language:t||"unknown",block_id:Ze.c.blockIdOf(e)}))},[]);const c=(0,i.useCallback)(()=>{n?.(e)},[e,n]),u=(0,i.useCallback)(()=>{a?.(e)},[e,a]),m=(0,i.useCallback)(()=>{r?.(e)},[e,r]),p=(0,i.useCallback)(()=>{s?.(e)},[e,s]),h=o&&(n||a||r||s);return d().createElement("div",{className:"jp-codebuff-code-toolbar"},t&&d().createElement("span",{className:"jp-code-language-badge"},t),h&&d().createElement(d().Fragment,null,n&&d().createElement("button",{className:"jp-codebuff-toolbar-btn",onClick:c,disabled:!o,title:"활성 셀 위에 삽입","aria-label":"Insert above active cell"},d().createElement(et,null)),a&&d().createElement("button",{className:"jp-codebuff-toolbar-btn",onClick:u,disabled:!o,title:"활성 셀 아래에 삽입","aria-label":"Insert below active cell"},d().createElement(tt,null)),r&&d().createElement("button",{className:"jp-codebuff-toolbar-btn",onClick:m,disabled:!o,title:"새 셀로 추가","aria-label":"Insert as new cell"},d().createElement(nt,null)),s&&d().createElement("button",{className:"jp-codebuff-toolbar-btn",onClick:p,disabled:!o,title:"셀에 적용","aria-label":"Replace cell with this code"},d().createElement(at,null)),d().createElement("span",{className:"jp-codebuff-toolbar-divider"})),d().createElement(Ye,{value:e}))}const st=/(?::(\d+)(?::(\d+))?|#L(\d+)(?:-L?\d+)?)$/,ot=/^[a-z][a-z0-9+.-]*:/i;const lt="text/markdown";function ct(){return window._codebuffRenderMimeRegistry||null}function it(e,t){if(t){if(e.startsWith("@@"))return"jp-terminal-line jp-terminal-hunk";if(e.startsWith("+"))return"jp-terminal-line jp-terminal-add";if(e.startsWith("-"))return"jp-terminal-line jp-terminal-del"}return"jp-terminal-line"}const dt=/^\$\s+(?:cat|head|tail|sed|nl|less|more|bat)\b/;function ut(e){if(e)return e.split("\n").filter(e=>e.trim()&&!e.startsWith("│ ")).pop()}function mt(e){return Be(),qe(e,{layout:ze(),highlight:ce})}function pt(e){e.querySelectorAll("pre").forEach(e=>{if(e.dataset.diffPromoted)return;const t=e.querySelector("code"),n=vt(`${e.className} ${t?.className||""}`);if("diff"!==n&&"patch"!==n)return;const a=$e(e.textContent||"");if(!a.length)return;e.dataset.diffPromoted="1";const r=document.createElement("div");r.innerHTML=mt(a);const s=r.firstElementChild;if(!s)return;e.parentNode?.insertBefore(s,e),e.classList.add("jp-codebuff-hidden");const o=e.parentElement?.querySelector(":scope > .code-block-toggle");o?.classList.add("jp-codebuff-hidden")})}const ht=({lines:e,live:t,header:n})=>{const a=e.some(e=>e.startsWith("@@")),r=function(e,t){if(!e)return"";const n=e.match(/\.([A-Za-z0-9]+)(?=[\s,:'"]|$)/g)||[],a=n.length?n[n.length-1].slice(1).toLowerCase():"",r=xe[a]||"";return e.startsWith("$ ")?!t&&dt.test(e)&&r?r:"bash":r}(n,a),s=!a&&"bash"===r&&de(e.join("\n")),o=e=>e?a&&/^[+\- ]/.test(e)?re(e[0])+ce(e.slice(1),r):a?re(e):s?me(e):ce(e,r):" ",l=e=>d().createElement("pre",{className:"jp-terminal-pre"},e.map((e,t)=>d().createElement("span",{key:t,className:it(e,a),dangerouslySetInnerHTML:{__html:o(e)}}))),c=`${a?"변경":"출력"} ${e.length}줄`,i=d().createElement("span",{className:"jp-terminal-copy",onClick:e=>{e.preventDefault(),e.stopPropagation()}},d().createElement(Ye,{value:e.join("\n")}));if(a){const t=$e(e.join("\n"),function(e){if(!e||e.startsWith("$ "))return"";const t=e.match(/[\w./-]+\.[A-Za-z0-9]+(?=[\s,:'"]|$)/g)||[];return t.length?t[t.length-1]:""}(n));if(t.length)return d().createElement("div",{className:"jp-terminal-diff"},d().createElement("div",{className:"jp-terminal-count"},c,i),d().createElement("div",{dangerouslySetInnerHTML:{__html:mt(t)}}))}if(t){const t=e.slice(-12);return d().createElement("div",{className:"jp-terminal-block jp-terminal-block-live"},d().createElement("div",{className:"jp-terminal-count"},e.length>t.length?`… ${c} 중 마지막 ${t.length}줄`:c,i),l(t))}return d().createElement("details",{className:"jp-terminal-block"},d().createElement("summary",{className:"jp-terminal-count"},c,i),l(e))},gt=({statusText:e,isStreaming:t})=>{const n=e.split("\n").filter(e=>e.trim());if(0===n.length)return null;const a=function(e){const t=[];for(const n of e){if(!n.startsWith("│ ")){t.push({kind:"line",text:n});continue}const e=n.slice(2),a=t[t.length-1];a&&"terminal"===a.kind?a.lines.push(e):t.push({kind:"terminal",lines:[e],header:a&&"line"===a.kind?a.text:void 0})}return t}(n),r=a.length-1,s=t?"terminal"===a[r].kind?r-1:r:a.length,o=a.map((e,t)=>{const n=t>=s;return"terminal"===e.kind?d().createElement(ht,{key:t,lines:e.lines,live:n,header:e.header}):d().createElement("div",{key:t,className:`${a=e.text,a.startsWith("$ ")?"jp-status-line jp-status-line-command":a.startsWith("생각:")?"jp-status-line jp-status-line-thought":"jp-status-line"}${n?" jp-status-line-active":""}`},d().createElement("span",{className:"jp-status-mark"},n?"›":"✓"),d().createElement("span",{className:"jp-status-text"},e.text));var a});return t?d().createElement("div",{className:"jp-status-history"},o):d().createElement("details",{className:"jp-status-history"},d().createElement("summary",null,"진행 과정 ",a.length,"단계"),o)},ft=({current:e,toolProcessing:t,summarizing:n,startedAt:a})=>{const[r]=(0,i.useState)(()=>Date.now()),s=a??r,[,o]=(0,i.useState)(0);(0,i.useEffect)(()=>{const e=setInterval(()=>o(e=>e+1),1e3);return()=>clearInterval(e)},[]);const l=Math.max(0,Math.floor((Date.now()-s)/1e3)),c=e||(n?"대화 이력을 요약하는 중":t?"도구 결과를 분석하는 중":"생각하는 중");return d().createElement("div",{className:"jp-working-bar",role:"status","aria-live":"polite"},d().createElement("span",{className:"jp-working-spinner"}),d().createElement("span",{className:"jp-working-label"},c),d().createElement("span",{className:"jp-working-elapsed"},l,"초"))};function bt(e){return e.replace(/"/g,"&quot;").replace(/\[/g,"(").replace(/\]/g,")")}function vt(e){const t=e.match(/language-(\w+)/);if(t)return t[1];const n=e.match(/hljs\s+(\w+)/);return n?n[1]:void 0}const yt=d().memo(({content:e,isStreaming:t=!1,className:n="",debounceMs:a=16,onClick:r,useRendermime:s=!0,onInsertAbove:o,onInsertBelow:l,onInsertAsCell:u,onReplaceCell:m,cellActionsEnabled:p=!0,statusText:h,toolProcessing:g=!1,summarizing:f=!1,startedAt:b})=>{const v=(0,i.useRef)(null),y=(0,i.useRef)(null),E=(0,i.useRef)(""),[k,w]=(0,i.useState)([]),x=(0,i.useRef)([]),S=(0,i.useRef)(null),_=(0,i.useRef)(""),C=(0,i.useMemo)(()=>{const t=ct(),n=e&&e.includes('"summary"')&&e.includes('"next_items"');return s&&null!==t&&!n},[s,e]),{renderedHtml:N,isRendering:j,hasIncompleteBlocks:$}=function(e,t={}){const{debounceMs:n=50,isStreaming:a=!1,forceImmediate:r=!1,minContentLength:s=10}=t,[o,l]=(0,i.useState)(""),[c,d]=(0,i.useState)(!1),u=(0,i.useRef)(null),m=(0,i.useRef)(""),p=(0,i.useRef)(""),h=(0,i.useRef)(0),g=(0,i.useRef)(""),f=(0,i.useMemo)(()=>Je(e),[e]),b=(0,i.useMemo)(()=>Ve(f),[f]),v=(0,i.useCallback)((e,t=!1)=>{if(t||e!==m.current||!p.current)if(a&&!t&&e.length<s)d(!1);else{m.current=e,h.current++;try{let t;if(a&&b){const{stableContent:n}=function(e,t){if(!Ve(t))return{stableContent:e,unstableContent:""};if(t.hasUnclosedCodeBlock)return{stableContent:Ge(e,t),unstableContent:""};const n=e.lastIndexOf("\n");if(n>0){const t=e.substring(0,n),a=e.substring(n+1);if(!Ve(Je(t)))return{stableContent:t,unstableContent:a}}return{stableContent:Ge(e,t),unstableContent:""}}(e,f);t=n}else t=e;const n=Ee(t);p.current=n,l(n)}catch(t){console.warn("[useStreamingMarkdown] Render error:",t);const n=e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");l(`<pre style="white-space: pre-wrap;">${n}</pre>`)}d(!1)}else d(!1)},[a,b,f,s]);return(0,i.useEffect)(()=>{if(!e)return l(""),d(!1),m.current="",p.current="",g.current="",void(u.current&&(clearTimeout(u.current),u.current=null));if(r||!a)return u.current&&(clearTimeout(u.current),u.current=null),void v(e,!0);if(d(!0),g.current=e,!u.current){const t=e.length>500?.5*n:n;u.current=setTimeout(()=>{u.current=null,v(g.current)},t)}},[e,a,r,n,v]),(0,i.useEffect)(()=>{!a&&e&&v(e,!0)},[a]),{renderedHtml:o,isRendering:c,hasIncompleteBlocks:b,incompleteBlockInfo:f}}(e,{debounceMs:a,isStreaming:t,forceImmediate:!t}),T=(0,i.useCallback)(e=>{x.current.forEach(e=>{e.parentNode&&e.parentNode.removeChild(e)}),x.current=[];const t=e.querySelectorAll("pre"),n=[],a=[];t.forEach(e=>{const t=e.closest(".code-block-container");let r;if(t){const e=t.querySelector(".code-block-header");if(e){const t=e.querySelector(".code-block-language");r=t?.textContent?.trim().toLowerCase()||void 0,e.classList.add("jp-codebuff-hidden")}}else{const t=e.querySelector("code");r=t?vt(t.className):void 0}const s=document.createElement("div");s.className="jp-codebuff-code-toolbar-container",e.parentNode?.insertBefore(s,e.nextSibling),a.push(s),n.push({root:s,content:e.textContent||"",language:r})}),x.current=a,w(n)},[]),A=(0,i.useRef)(!1),I=(0,i.useCallback)(async e=>{const n=ct();if(!n||!v.current)return!1;if(e===E.current)return!0;E.current=e;try{let a=e;t&&function(e){const t=e.match(/```/g);return(t?t.length:0)%2!=0}(a)&&(a=function(e){let t=e;const n=t.match(/```/g);return(n?n.length:0)%2!=0&&(t+="\n```"),t}(a)),a=a.replace(/```mermaid\s*\n([\s\S]*?)```/g,(e,t)=>{let n=t;return n=n.replace(/%%.*$/gm,""),n=n.replace(/^(\s*)end(\s*)$/gm,"$1__END_PH__$2"),n=n.replace(/^(\s*(?:class|style|click|classDef|linkStyle)\b.*)$/gm,e=>e.replace(/\bend\b/g,"__END_PH__")),n=n.replace(/\bend\b/g,"end_node"),n=n.replace(/__END_PH__/g,"end"),n=n.replace(/\\"/g,"&quot;"),n=n.replace(/(\s)->([\s\w])/g,"$1--\x3e$2"),n=n.replace(/(\s)-\.(\s)/g,"$1-.->$2"),n=n.replace(/^(.*)$/gm,e=>{const t=[];let n=0;for(;n<e.length;)if(n>0&&/\w/.test(e[n-1])&&"["===e[n]&&"["!==e[n+1]&&"("!==e[n+1]&&"/"!==e[n+1]&&"\\"!==e[n+1]){let a=1,r=n+1;for(;r<e.length&&a>0;)"["===e[r]?a++:"]"===e[r]&&a--,a>0&&r++;if(0===a){let a=e.slice(n+1,r);if(a.startsWith('"')&&a.endsWith('"')?a=a.slice(1,-1):a.startsWith('"')&&(a=a.replace(/"/g,"")),/[\[\]"]/.test(a)){const e=a.replace(/\[/g,"&#91;").replace(/\]/g,"&#93;").replace(/"/g,"&quot;");t.push(`["${e}"]`)}else t.push(e.slice(n,r+1));n=r+1}else t.push(e[n]),n++}else t.push(e[n]),n++;return t.join("")}),n=function(e){const t=[];let n=0;for(;n<e.length;)if("["===e[n]&&n>0&&/\w/.test(e[n-1])){if("["===e[n+1]){t.push(e[n],e[n+1]),n+=2;let a=1;for(;n<e.length&&a>0;)if("["!==e[n]||"["!==e[n+1])if("]"!==e[n]||"]"!==e[n+1])t.push(e[n]),n++;else{if(a--,0===a){t.push("]","]"),n+=2;break}t.push("]","]"),n+=2}else a++,t.push(e[n],e[n+1]),n+=2;continue}t.push("["),n++;let a=1;for(;n<e.length&&a>0;)if("["!==e[n])if("]"!==e[n]){if("\n"===e[n]){t.push(e[n]),n++;break}t.push(e[n]),n++}else{if(a--,0===a){t.push("]"),n++;break}t.push(")"),n++}else a++,t.push("("),n++}else t.push(e[n]),n++;return t.join("")}(n),n=n.replace(/(\b\w+)\[\[([^\]\n]*)\]\]/g,(e,t,n)=>n.startsWith('"')&&n.endsWith('"')?e:`${t}[["${bt(n)}"]]`),n=n.replace(/(\b\w+)\[(?!\[|\()([^\]\n]*)\]/g,(e,t,n)=>n.startsWith('"')&&n.endsWith('"')?e:`${t}["${bt(n)}"]`),n=n.replace(/\|([^|]*)\|/g,(e,t)=>/[\[\]]/.test(t)?`|${t.replace(/\[/g,"&#91;").replace(/\]/g,"&#93;")}|`:e),n=n.replace(/^(\s*subgraph\s+)(?!")([^\n]*[ \t][^\n]*)$/gm,(e,t,n)=>/^\w+\s*\[/.test(n)?e:`${t}"${n.replace(/"/g,"&quot;")}"`),n=n.replace(/(\b\w+)\[""\]/g,"$1"),n=n.replace(/^(\s*direction\s+)(?!TB|BT|LR|RL|TD)(\w+)/gm,"$1TD"),"```mermaid\n"+n+"```"});let r=a.replace(/\\\(/g,"\\\\(").replace(/\\\)/g,"\\\\)").replace(/\\\[/g,"\\\\[").replace(/\\\]/g,"\\\\]");r=function(e){let t=e;t=t.replace(/\[\d+[†‡]\w*\]/g,"");const n=[];t=t.replace(/```[\s\S]*?```/g,e=>{const t=`__PREPROC_CB_${n.length}__`;return n.push({placeholder:t,original:e}),t});const a=[];return t=t.replace(/`[^`]+`/g,e=>{const t=`__PREPROC_IC_${a.length}__`;return a.push({placeholder:t,original:e}),t}),t=t.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),t=ye(t,c.PageConfig.getBaseUrl()),a.forEach(({placeholder:e,original:n})=>{t=t.replace(e,()=>n)}),n.forEach(({placeholder:e,original:n})=>{t=t.replace(e,()=>n)}),t}(r);const s=n.createModel({data:{[lt]:r}});if(t){const e=n.createRenderer(lt);if(await e.renderModel(s),e.node&&v.current){const t=v.current.querySelector(".jp-streaming-content");if(t){if(t.replaceChildren(e.node),A.current=!0,y.current&&y.current!==e)try{y.current.dispose()}catch{}y.current=e}}}else{y.current||(y.current=n.createRenderer(lt),A.current=!1);const e=y.current;if(await e.renderModel(s),e.node&&v.current){const t=v.current.querySelector(".jp-streaming-content");t&&(A.current&&t.contains(e.node)||(t.replaceChildren(e.node),A.current=!0),n.latexTypesetter&&n.latexTypesetter.typeset(t))}}return!0}catch(e){return console.warn("[StreamingMessage] Rendermime error, falling back:",e),!1}},[t]);(0,i.useEffect)(()=>{if(C&&e){if(!t)return S.current&&(clearTimeout(S.current),S.current=null),void I(e);_.current=e,S.current||(S.current=setTimeout(()=>{S.current=null,I(_.current)},a))}else S.current&&(clearTimeout(S.current),S.current=null)},[e,t,C,a,I]),(0,i.useEffect)(()=>{if(C&&!t&&e&&v.current){const e=v.current.querySelector(".jp-streaming-content");e&&(setTimeout(()=>{T(e),function(e){e.querySelectorAll("pre code").forEach(e=>{if(e.querySelector('.hljs-keyword, .hljs-string, .hljs-comment, .syntax-keyword, [class^="jp-log-"]'))return;const t=vt(e.className),n=e.textContent||"";if(!t||["text","txt","plaintext","log","console","output"].includes(t))return void(de(n)&&(e.innerHTML=me(n)));let a;switch(t){case"python":case"py":a=pe(n);break;case"javascript":case"js":case"typescript":case"ts":a=ge(n);break;case"diff":a=he(n);break;case"json":a=fe(n);break;default:return}e.innerHTML=a})}(e),pt(e)},100),setTimeout(()=>{const t=e.querySelector(".jp-codebuff-code-toolbar-container");e.querySelector("pre")&&!t&&T(e),pt(e)},500))}},[t,e,T,C]),(0,i.useEffect)(()=>{if(!C&&N&&!t&&v.current){const e=v.current.querySelector(".jp-streaming-content");e&&(setTimeout(()=>{T(e),pt(e)},100),setTimeout(()=>{const t=e.querySelector(".jp-codebuff-code-toolbar-container");e.querySelector("pre")&&!t&&T(e),pt(e)},500))}},[C,N,t,T]),(0,i.useEffect)(()=>()=>{y.current&&y.current.dispose&&(y.current.dispose(),y.current=null),A.current=!1,S.current&&(clearTimeout(S.current),S.current=null),x.current.forEach(e=>{e.parentNode&&e.parentNode.removeChild(e)}),x.current=[]},[]);const P=e&&(C||N),L=j;e&&e.includes('"summary"')&&e.includes('"next_items"')&&console.log("[StreamingMessage] Render state for summary JSON:",{useNativeRenderer:C,hasRenderedHtml:!!N,renderedHtmlPreview:N?.slice(0,100),showContent:P,contentLength:e?.length});const M=(0,i.useMemo)(()=>{const e=["jp-RenderedHTMLCommon","jp-RenderedMarkdown","jp-streaming-message"];return n&&e.push(n),t&&e.push("streaming"),$&&e.push("incomplete"),C&&e.push("jp-rendermime-native"),e.join(" ")},[n,t,$,C]);return d().createElement("div",{ref:v,className:M,style:{padding:"0 5px"}},h&&d().createElement(gt,{statusText:h,isStreaming:t}),P&&d().createElement("div",{className:"jp-streaming-content",...!C&&N?{dangerouslySetInnerHTML:{__html:N}}:{},onClick:e=>{(function(e){const t=e.target?.closest?.("a"),n=window._codebuffOpenFile;if(!t||!n)return!1;const a=window._codebuffServerRoot,r=function(e,t){const n=(e||"").trim();if(!n||n.startsWith("#")||ot.test(n))return null;const a=st.exec(n),r=a?n.slice(0,a.index):n;if(!r)return null;const s=function(e,t){let n=e;if(!n)return null;try{n=decodeURI(n)}catch{}if(!n.startsWith("/"))return n.replace(/^\.\//,"")||null;const a=(t||"").replace(/\/+$/,"");if(a.startsWith("~")){const e=a.slice(1)+"/",t=n.indexOf(e);return t>=0&&n.slice(t+e.length)||null}return a&&n.startsWith(a+"/")&&n.slice(a.length+1)||null}(r,t);if(!s)return null;const o={path:s},l=a?Number(a[1]||a[3]):0;return l>0&&(o.line=l,a&&a[2]&&(o.column=Number(a[2]))),o}(t.getAttribute("href")||"",a||"");return!!r&&(e.preventDefault(),n(r.path,r.line,r.column),!0)})(e)||r?.(e)}}),t&&e&&!L&&d().createElement("div",{className:"jp-streaming-cursor"}),t&&d().createElement(ft,{current:ut(h),toolProcessing:g,summarizing:f,startedAt:b}),!t&&k.map((e,t)=>(0,He.createPortal)(d().createElement(rt,{key:t,content:e.content,language:e.language,onInsertAbove:o,onInsertBelow:l,onInsertAsCell:u,onReplaceCell:m,cellActionsEnabled:p}),e.root)))});yt.displayName="StreamingMessage";var Et=n(1148),kt=n(5997),wt=n(2659);const xt=({apiService:e,inputValue:t,cursorPosition:n,engine:a,onSelect:r,onClose:s,onOptionsChange:o,visible:l,anchorEl:c,placement:u})=>{const[m,p]=(0,i.useState)([]),[h,g]=(0,i.useState)(0),[f,b]=(0,i.useState)(!1),[v,y]=(0,i.useState)(null),E=(0,i.useRef)(null),k=(0,i.useRef)(0),w=(0,i.useCallback)(async t=>{const n=++k.current;b(!0);try{const r=await e.getContextAutocomplete({partialCommand:t,engine:a});if(n!==k.current)return;p(r.options),g(0)}catch(e){if(n!==k.current)return;console.error("[ContextAutocomplete] Failed to fetch options:",e),p([])}finally{n===k.current&&b(!1)}},[e,a]);if((0,i.useEffect)(()=>{const e=function(e,t){let n=t;for(;n>0&&!/\s/.test(e[n-1]);)n--;const a=e.slice(n,t);return a.startsWith("@")||a.startsWith("/")?a:null}(t,n);if(y(e),e){const t=setTimeout(()=>{w(e)},150);return()=>clearTimeout(t)}p([])},[t,n,w]),(0,i.useEffect)(()=>{o?.(m.length>0)},[m,o]),(0,i.useEffect)(()=>{if(!l||0===m.length)return;const e=e=>{const t=m[h];switch(e.key){case"ArrowDown":e.preventDefault(),g(e=>(e+1)%m.length);break;case"ArrowUp":e.preventDefault(),g(e=>(e-1+m.length)%m.length);break;case"Tab":t&&!t.is_complete||t&&t.id?.startsWith("/")?(e.preventDefault(),r(t,!1)):t&&(e.preventDefault(),r(t,!0));break;case"Enter":if(e.isComposing)break;t&&(e.preventDefault(),e.stopPropagation(),r(t,!0));break;case"Escape":e.preventDefault(),s()}};return document.addEventListener("keydown",e,!0),()=>document.removeEventListener("keydown",e,!0)},[l,m,h,r,s]),(0,i.useEffect)(()=>{if(E.current&&m.length>0){const e=E.current.querySelector(".jp-context-autocomplete-item--selected");e&&e.scrollIntoView({block:"nearest"})}},[h,m]),(0,i.useEffect)(()=>{if(!l||0===m.length)return;const e=e=>{E.current&&!E.current.contains(e.target)&&c&&!c.contains(e.target)&&s()};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[l,m,c,s]),!l||!v||0===m.length)return null;const x={position:"absolute",left:0,right:0,zIndex:1e3,..."above"===(u??"above")?{bottom:c?c.offsetHeight+4:"auto"}:{top:c?c.offsetHeight+4:"auto"}};return d().createElement("div",{ref:E,className:"jp-context-autocomplete",style:x},d().createElement("div",{className:"jp-context-autocomplete-header"},d().createElement("span",{className:"jp-context-autocomplete-hint"},v.startsWith("@")?"Select a file":"Commands"),d().createElement("span",{className:"jp-context-autocomplete-loading"},f&&"Loading...")),d().createElement("div",{className:"jp-context-autocomplete-list"},m.map((e,t)=>d().createElement("div",{key:`${e.id}-${e.label}-${t}`,className:"jp-context-autocomplete-item "+(t===h?"jp-context-autocomplete-item--selected":""),onClick:()=>r(e,!0),onMouseEnter:()=>g(t)},d().createElement("span",{className:"jp-context-autocomplete-item-icon"},function(e){const t=e.label.replace(/"$/,"").toLowerCase();return"@"!==e.id||e.is_complete?t.endsWith(".py")?d().createElement(Et.A,{sx:{fontSize:16,color:"#3572A5"}}):t.endsWith(".ipynb")?d().createElement(Et.A,{sx:{fontSize:16,color:"#F37626"}}):/\.(js|jsx|ts|tsx)$/.test(t)?d().createElement(Et.A,{sx:{fontSize:16,color:"#f1e05a"}}):t.endsWith(".md")?d().createElement(wt.A,{sx:{fontSize:16,color:"var(--jp-ui-font-color2)"}}):d().createElement(Et.A,{sx:{fontSize:16,color:"var(--jp-ui-font-color2)"}}):d().createElement(kt.A,{sx:{fontSize:16,color:"var(--jp-ui-font-color2)"}})}(e)),d().createElement("span",{className:"jp-context-autocomplete-item-label"},e.label),d().createElement("span",{className:"jp-context-autocomplete-item-description"},e.description)))),d().createElement("div",{className:"jp-context-autocomplete-footer"},d().createElement("kbd",null,"Tab")," navigate, ",d().createElement("kbd",null,"Enter")," select, ",d().createElement("kbd",null,"Esc")," close"))},St={start:"새 대화",fork:"fork",side:"side"},_t=({threads:e,onSelect:t,onClose:n})=>d().createElement("div",{className:"jp-agent-codex-threads",role:"listbox","aria-label":"codex 스레드 선택"},d().createElement("div",{className:"jp-agent-codex-threads-head"},d().createElement("span",null,"이어 붙을 codex 스레드"),d().createElement("button",{type:"button",className:"jp-agent-codex-threads-close",onClick:n,"aria-label":"닫기"},"×")),e.map(e=>{return d().createElement("button",{key:e.id,type:"button",role:"option","aria-selected":Boolean(e.current),className:"jp-agent-codex-thread "+(e.current?"is-current":""),disabled:Boolean(e.error),onClick:()=>t(e.id),title:e.id},d().createElement("span",{className:"jp-agent-codex-thread-title"},e.name||e.preview||e.id,e.current&&d().createElement("span",{className:"jp-agent-codex-thread-badge"},"지금"),d().createElement("span",{className:"jp-agent-codex-thread-badge"},St[e.kind]||e.kind)),d().createElement("span",{className:"jp-agent-codex-thread-meta"},e.error?`열 수 없음: ${e.error}`:(n=e.updatedAt||e.createdAt)?new Date(1e3*n).toLocaleString():""));var n}));var Ct=n(1130),Nt=n(9507);const jt=e=>c.URLExt.join(c.PageConfig.getBaseUrl(),"proxy",String(e))+"/",$t={python:"Python 3.9 pod 라 jupyter-server-proxy 를 쓸 수 없어 브라우저로 열 수 없습니다 (3.10 이상 필요)",missing:"jupyter-server-proxy 가 설치돼 있지 않아 브라우저로 열 수 없습니다 (Nexus 반입 확인)",disabled:"jupyter-server-proxy 가 설치돼 있지만 서버 설정에서 꺼져 있어 브라우저로 열 수 없습니다"},Tt=/\x1b\[[0-9;?]*[ -/]*[@-~]/g;Ct.A.registerLanguage("log",Nt.A);const At=Ct.A,It=({proc:e,readOutput:t,onClose:n})=>{const[a,r]=d().useState(null),[s,o]=d().useState(!1),l=d().useRef(null),c=d().useRef(!0),i=d().useRef(t);i.current=t;const u=d().useRef(n);u.current=n;const m="running"===e.state;return d().useEffect(()=>{let t=!0;const n=()=>{i.current(e.id).catch(()=>null).then(e=>{t&&(o(null===e),null!==e&&r(e.replace(Tt,"")))})};n();const a=m?window.setInterval(n,2e3):void 0;return()=>{t=!1,void 0!==a&&window.clearInterval(a)}},[e.id,m]),d().useEffect(()=>{const e=e=>{"Escape"===e.key&&(e.stopPropagation(),u.current())};return document.addEventListener("keydown",e,!0),()=>document.removeEventListener("keydown",e,!0)},[]),d().useLayoutEffect(()=>{const e=l.current;e&&c.current&&(e.scrollTop=e.scrollHeight)},[a]),(0,He.createPortal)(d().createElement("div",{className:"jp-agent-codex-proc-logwin-backdrop",onMouseDown:e=>{e.target===e.currentTarget&&n()}},d().createElement("div",{className:"jp-agent-codex-proc-logwin "+(m?"is-running":"is-exited"),role:"dialog","aria-modal":"true","aria-label":`로그: ${e.command}`},d().createElement("div",{className:"jp-agent-codex-proc-logwin-head"},d().createElement("span",{className:"jp-agent-codex-proc-dot","aria-hidden":"true"}),d().createElement("code",{title:e.command},e.command),d().createElement("span",{className:"jp-agent-codex-proc-meta"},m?"실시간 · 2초마다 갱신":`종료 ${e.exit_code??""}`.trim()),d().createElement("button",{type:"button",className:"jp-agent-codex-proc-logwin-close",onClick:n,"aria-label":"로그 닫기",title:"닫기 (Esc)"},"×")),d().createElement("div",{ref:l,className:"jp-agent-codex-proc-logwin-body",onScroll:e=>{const t=e.currentTarget;c.current=t.scrollHeight-t.scrollTop-t.clientHeight<24}},a?d().createElement(At,{language:"log",useInlineStyles:!1,wrapLongLines:!0},a):d().createElement("div",{className:"jp-agent-codex-proc-logwin-empty"},s?"로그를 읽지 못했습니다.":null===a?"불러오는 중…":"(아직 출력 없음)")))),document.body)},Pt=({processes:e,proxy:t,proxyReason:n,stopping:a,onKill:r,onDismiss:s,readOutput:o})=>{const[l,c]=d().useState(null),i=e.find(e=>e.id===l);return d().createElement(d().Fragment,null,d().createElement("div",{className:"jp-agent-codex-procs",role:"list","aria-label":"백그라운드 프로세스"},e.map(e=>{const o="running"===e.state,i=e.id===l;return d().createElement("div",{key:e.id,role:"listitem",className:"jp-agent-codex-proc "+(o?"is-running":"is-exited")},d().createElement("span",{className:"jp-agent-codex-proc-dot","aria-hidden":"true"}),d().createElement("code",{className:"jp-agent-codex-proc-cmd",title:e.command},e.command),o&&t&&e.ports.map(e=>d().createElement("a",{key:e,className:"jp-agent-codex-proc-open",href:jt(e),target:"_blank",rel:"noopener noreferrer",title:`포트 ${e} 를 새 탭에서 엽니다`},":",e," 열기")),o&&!t&&e.ports.map(e=>{return d().createElement("span",{key:e,className:"jp-agent-codex-proc-port",title:(t=n,t&&$t[t]||"jupyter-server-proxy 가 없어 브라우저로 열 수 없습니다")},":",e);var t}),d().createElement("span",{className:"jp-agent-codex-proc-meta"},o?(e=>{if(void 0===e)return"";const t=Math.max(0,Math.round(e));return t<60?`${t}초`:t<3600?`${Math.floor(t/60)}분`:`${Math.floor(t/3600)}시간 ${Math.floor(t%3600/60)}분`})(e.elapsed_s):`종료 ${e.exit_code??""}`.trim()),d().createElement("button",{type:"button",className:"jp-agent-codex-proc-logbtn"+(i?" is-open":""),onClick:()=>c(i?null:e.id),"aria-expanded":i,title:"로그 보기"},"로그"),o?d().createElement("button",{type:"button",className:"jp-agent-codex-proc-kill",onClick:()=>r(e.id),disabled:a.includes(e.id),title:"중지"},a.includes(e.id)?"중지 중":"중지"):d().createElement("button",{type:"button",className:"jp-agent-codex-proc-dismiss",onClick:()=>s(e.id),"aria-label":"목록에서 숨기기"},"×"))})),i&&d().createElement(It,{key:i.id,proc:i,readOutput:o,onClose:()=>c(null)}))},Lt=[{name:"/new",help:"새 codex 스레드로 시작합니다 (`/reset` 과 같음)."},{name:"/compact",help:"지금까지의 대화를 요약해 컨텍스트를 줄입니다."},{name:"/review",help:"codex 코드리뷰. `/review` — 미커밋 변경, `/review base main`, `/review commit <sha>`, `/review <지시문>`."},{name:"/model",help:"모델 목록을 보거나 바꿉니다. 예: `/model gpt-5-mini low`."},{name:"/status",help:"현재 codex 세션의 모델·스레드·권한을 보여 줍니다."},{name:"/mcp",help:"codex 에 연결된 MCP 서버 상태를 보여 줍니다."},{name:"/skills",help:"이 작업공간에서 codex 가 쓰는 스킬 목록입니다."},{name:"/hooks",help:"이 작업공간에서 codex 가 쓰는 훅 목록입니다."},{name:"/diff",help:"작업공간의 git 변경을 보여 줍니다."},{name:"/init",help:"작업공간을 살펴 `AGENTS.md` 지시문 초안을 만듭니다."},{name:"/resume",help:"내가 연 codex 스레드를 골라 이어 붙입니다."},{name:"/fork",help:"지금 대화를 문맥째 새 스레드로 갈라 이어 갑니다."},{name:"/side",help:"곁가지 대화입니다. 문맥째 갈라 묻고 `/resume` 으로 돌아옵니다."},{name:"/rename",help:"지금 스레드 이름을 바꿉니다. 예: `/rename 결제 리팩터링`."},{name:"/archive",help:"지금 스레드를 보관하고 새 스레드로 시작합니다."},{name:"/delete",help:"지금 스레드를 지웁니다. `/delete confirm` 으로 실행합니다."}],Mt=new Set(Lt.map(e=>e.name)),Rt=e=>e.trim().split(/\s+/)[0],qt=new Set(["unauthorized","sidecar_missing","sidecar_unreachable","not_allowed","no_endpoint"]);function Dt(e){return e&&qt.has(e)?"다시 시도해도 풀리지 않는 설정 문제입니다. 설정 화면의 연결 상태를 확인해 주세요.":"잠시 후 다시 시도해 주세요."}var Ot=n(5916),zt=n(1692);const Ft='<svg xmlns="http://www.w3.org/2000/svg" width="1080" height="240" viewBox="0 0 1080 240">\n <defs>\n <linearGradient id="hg" x1="0%" y1="0%" x2="100%" y2="100%">\n <stop offset="0%" style="stop-color:#6366f1"/>\n <stop offset="100%" style="stop-color:#8b5cf6"/>\n </linearGradient>\n </defs>\n <g transform="translate(10, 20) scale(0.7)">\n <rect width="280" height="280" rx="56" fill="url(#hg)"/>\n <path d="M 100 80 L 40 140 L 100 200" stroke="white" stroke-width="20" stroke-linecap="round" stroke-linejoin="round" fill="none"/>\n <path d="M 180 80 L 240 140 L 180 200" stroke="white" stroke-width="20" stroke-linecap="round" stroke-linejoin="round" fill="none"/>\n <line x1="155" y1="65" x2="125" y2="215" stroke="rgba(255,255,255,0.4)" stroke-width="10" stroke-linecap="round"/>\n </g>\n <text x="250" y="175" font-family="system-ui, -apple-system, \'Segoe UI\', sans-serif" font-size="180" font-weight="700" fill="#1e1b4b" letter-spacing="-4">Codebuff</text>\n</svg>',Bt='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 280 280">\n <rect width="280" height="280" rx="56" fill="#6366f1"/>\n <path d="M 100 80 L 40 140 L 100 200" stroke="white" stroke-width="20" stroke-linecap="round" stroke-linejoin="round" fill="none"/>\n <path d="M 180 80 L 240 140 L 180 200" stroke="white" stroke-width="20" stroke-linecap="round" stroke-linejoin="round" fill="none"/>\n <line x1="155" y1="65" x2="125" y2="215" stroke="white" stroke-opacity="0.4" stroke-width="10" stroke-linecap="round"/>\n</svg>';let Wt=0;function Ut(e,t,n){return new Promise(a=>{Be();const r="jp-agent-apply-diff-title-"+ ++Wt,s=document.createElement("div");s.className="jp-agent-apply-diff-overlay",s.innerHTML=`<div class="jp-agent-apply-diff-dialog" role="dialog" aria-modal="true" aria-labelledby="${r}"><h3 id="${r}" class="jp-agent-apply-diff-title">${re(e)}에 적용할 변경</h3>`+qe([Ne(e,t,n)],{layout:ze()})+'<div class="jp-agent-apply-diff-actions"><button type="button" class="jp-agent-apply-diff-cancel">취소</button><button type="button" class="jp-agent-apply-diff-confirm">적용</button></div></div>';const o=e=>{document.removeEventListener("keydown",l,!0),s.remove(),a(e)},l=e=>{"Escape"===e.key&&(e.stopPropagation(),o(!1))};s.addEventListener("click",e=>{e.target===s&&o(!1)}),s.querySelector(".jp-agent-apply-diff-cancel")?.addEventListener("click",()=>o(!1));const c=s.querySelector(".jp-agent-apply-diff-confirm");c?.addEventListener("click",()=>o(!0)),document.addEventListener("keydown",l,!0),document.body.appendChild(s),c?.focus()})}function Ht(e,t){const n=(0,ke.structuredPatch)("","",e,t,"","",{context:3}),a=e.endsWith("\n")!==t.endsWith("\n"),r=[];return n.hunks.forEach((e,t)=>{t>0&&r.push("@@"),r.push(...e.lines.filter(e=>a||!e.startsWith("\\")))}),r.length?r:["(no changes)"]}function Jt(e){return e.length<=200?e:[...e.slice(0,200),`... (${e.length-200} more lines)`]}const Vt=/(^|\s)@(?:file:)?(?:"([^"\n]+)"|([^\s"'`\\]+))/,Gt=/(\.[A-Za-z0-9]+)[.,;:!?)\]}가-힣]{1,4}$/;function Xt(e){const t=Vt.exec(e);if(!t)return null;const n=t[2]??t[3].replace(Gt,"$1"),a=t.index+t[1].length;return{path:n,rest:(e.slice(0,a)+e.slice(t.index+t[0].length)).replace(/\s{2,}/g," ").trim()}}const Zt=JSON.parse('{"cell_explain_prompt":"다음 Jupyter 셀의 내용을 자세히 설명해주세요:\\n\\n```python\\n{{CELL_CONTENT}}\\n```","cell_fix_prompt":"다음 Jupyter 셀 코드에 에러가 발생했습니다.\\n\\n원본 코드:\\n```python\\n{{CELL_CONTENT}}\\n```\\n\\n에러:\\n```\\n{{ERROR_OUTPUT}}\\n```\\n\\n다음 형식으로 응답해주세요:\\n\\n## 에러 원인\\n(에러가 발생한 원인을 간단히 설명)\\n\\n## 수정 방법\\n\\n### 방법 1: (수정 방법 제목)\\n(이 방법에 대한 간단한 설명)\\n```python\\n(수정된 코드)\\n```\\n\\n### 방법 2: (수정 방법 제목)\\n(이 방법에 대한 간단한 설명)\\n```python\\n(수정된 코드)\\n```\\n\\n### 방법 3: (수정 방법 제목) (있는 경우)\\n(이 방법에 대한 간단한 설명)\\n```python\\n(수정된 코드)\\n```\\n\\n최소 2개, 최대 3개의 다양한 수정 방법을 제안해주세요.","cell_improve_prompt":"다음 Jupyter 셀 코드를 리뷰하고 개선 방법을 제안해주세요.\\n\\n코드:\\n```python\\n{{CELL_CONTENT}}\\n```{{OUTPUT_SECTION}}\\n\\n다음 형식으로 응답해주세요:\\n\\n## 코드 분석\\n(현재 코드의 기능과 특징을 간단히 설명)\\n\\n## 개선 방법\\n\\n### 방법 1: (개선 방법 제목)\\n(이 방법에 대한 간단한 설명)\\n```python\\n(개선된 코드)\\n```\\n\\n### 방법 2: (개선 방법 제목)\\n(이 방법에 대한 간단한 설명)\\n```python\\n(개선된 코드)\\n```\\n\\n### 방법 3: (개선 방법 제목) (있는 경우)\\n(이 방법에 대한 간단한 설명)\\n```python\\n(개선된 코드)\\n```\\n\\n최소 2개, 최대 3개의 다양한 개선 방법을 제안해주세요.","cell_question_prompt":"{{QUESTION}}\\n\\n셀 내용:\\n```\\n{{CELL_CONTENT}}\\n```{{OUTPUT_SECTION}}","review_rules_prompt":"\\n⚠️ 규칙:\\n- 코드를 표(table) 안에 넣지 마세요. 반드시 마크다운 코드 블록을 사용하세요.\\n- 각 관점 섹션의 코드 스니펫은 해당 부분만 발췌하세요.\\n- 섹션 제목은 반드시 프롬프트에 명시된 한국어 제목(### 보안, ### 성능, ### 코드 품질, ### 요약)을 그대로 사용하세요. 영어 제목이나 이모지를 섹션 제목에 사용하지 마세요.\\n- 이슈당 설명은 간결하게 작성하고, 개선 코드는 변경이 필요한 부분만 발췌하세요. 셀 전체 코드를 반복하지 마세요 (요약 섹션 제외).\\n","review_security_prompt":"### 보안\\n금융권 규제 준수 및 정보 유출 사고 예방을 위해 보안 취약점을 점검합니다.\\n입력 검증 미비, SQL 인젝션, 파일 경로 조작, 민감 정보(고객 계좌·신용정보) 노출, 크리덴셜 하드코딩 등을 식별합니다.\\n해당 사항 없으면 \\"✅ 보안 이슈 없음\\"으로 넘어가세요.\\n\\n⚠️ 검출 규칙:\\n- 하나의 셀에 여러 종류의 취약점이 있으면 각각 별도 항목(1-1, 1-2, ...)으로 분리하세요.\\n- 은닉/우회 패턴(변수 조합, 문자열 역순, ROT13, base64, 함수 기본 인자 등)은 패턴별로 개별 지적하세요.\\n- DataFrame에 PII 컬럼이 여러 개 있으면 모든 PII 컬럼을 나열하고 각각 마스킹/암호화 방안을 제시하세요.\\n- 개선 코드는 해당 취약점만 발췌하지 말고, 셀 전체의 개선 코드를 제시하세요.\\n\\n발견 항목은 아래 형식을 따르세요:\\n\\n#### 1-1. (이슈 제목)\\n**셀 N** | 문제에 대한 설명과 왜 개선이 필요한지 요약\\n\\n```python\\n# 개선 전\\n위험한_코드()\\n\\n# 개선 후\\n안전한_코드()\\n```\\n> 💡 **변경 내용**: 무엇을 왜 바꿨는지 한두 문장으로 설명","review_performance_prompt":"### 성능\\n{{RESOURCE_CONTEXT}}\\n\\n반드시 \\"### 성능\\" 제목을 먼저 출력한 뒤, 실행 환경 정보가 제공된 경우 아래 배너를 그 다음에 출력하세요:\\n> **실행 환경**: (위에 제공된 환경 요약을 그대로 복사)\\n\\nDS가 자주 겪는 OOM(Out-of-Memory) 방지, 전처리·학습 속도 개선, 컴퓨팅 리소스 최적 활용을 점검합니다.\\n불필요한 DataFrame 복사, 비효율적 dtypes, 중복 연산, 과도한 메모리 적재 등 실무에서 병목이 되는 패턴을 식별합니다.\\n**환경 기반 점검 가이드가 제공된 경우**, 해당 가이드에 명시된 기술 스택(pandas vs Polars vs Dask, joblib vs Ray, cuDF vs RAPIDS 등)을 기준으로 개선안을 제시하세요. 단순 파라미터 조정이 아닌, 환경 등급에 맞는 **기술 전환**(예: pandas→Polars, for루프→joblib 병렬처리, sklearn→cuML GPU 가속)을 우선 권장하세요.\\n해당 사항 없으면 다음 섹션으로 넘어가세요.\\n\\n발견 항목은 아래 형식을 **반드시** 따르세요 (환경 근거와 예상 개선 수치 누락 시 불합격):\\n\\n#### 2-1. (이슈 제목)\\n**셀 N** | 문제 설명. **현재 환경(CPU ○코어·RAM ○GB·GPU ○)에서는** 환경 가이드에 따라 ~~~기술이 적합하므로 ~~~. **예상 개선: 메모리 ~Y% 절감(OOM 위험 해소) / 처리 시간 ~X% 단축 / 리소스 사용량 N→M**\\n\\n```python\\n# 개선 전\\n비효율_코드()\\n\\n# 개선 후\\n최적화_코드()\\n```\\n> 💡 **변경 내용**: 무엇을 왜 바꿨는지 한두 문장으로 설명\\n\\n**요약** 문단도 반드시 전체 개선 효과를 수치로 집계하세요 (예: \\"OOM 위험 구간 해소, 전처리 시간 ~40% 단축, 메모리 피크 ~X% 절감, GPU 활용률 N%→M%\\").","review_quality_prompt":"### 코드 품질\\n분석 코드의 재현성·유지보수성을 높여 팀 생산성을 향상시키기 위해 점검합니다.\\n코드 구조, 일관성, 에러 처리, 변수명, 타입 힌트 등을 식별합니다.\\n해당 사항 없으면 \\"✅ 코드 품질 이슈 없음\\"으로 넘어가세요.\\n\\n발견 항목은 아래 형식을 따르세요:\\n\\n#### 3-1. (이슈 제목)\\n**셀 N** | 문제에 대한 설명과 왜 개선이 필요한지 요약\\n\\n```python\\n# 개선 전\\n나쁜_코드()\\n\\n# 개선 후\\n좋은_코드()\\n```\\n> 💡 **변경 내용**: 무엇을 왜 바꿨는지 한두 문장으로 설명","review_summary_prompt":"### 요약\\n- 보안·성능·품질 관점의 종합 평가 (한 문단)\\n- 비즈니스 임팩트가 큰 순서대로 시급한 개선 포인트 3가지\\n- 위 보안·성능·품질 섹션에서 수정이 제안된 **모든 셀**에 대해, 셀 번호 순서대로 전체 개선 코드를 제시:\\n\\n#### 셀 N 개선 코드\\n```python\\n(셀 전체를 개선한 완성 코드)\\n```\\n\\n⚠️ 각 셀의 개선 코드는 해당 셀의 전체 코드를 포함하세요. 하나의 셀에 여러 관점의 수정이 있으면 모두 통합하세요.\\n⚠️ 이전 분석 결과에서 언급된 셀을 빠뜨리지 마세요."}'),Kt=["cell_explain_prompt","cell_fix_prompt","cell_improve_prompt","cell_question_prompt","review_rules_prompt","review_security_prompt","review_performance_prompt","review_quality_prompt","review_summary_prompt"],Qt=Object.fromEntries(Kt.map(e=>[e,Zt[e]]));async function Yt(e,t=3e3){const n={...Qt},a=new AbortController,r=setTimeout(()=>a.abort(),t);try{const t=await fetch(`${e.replace(/\/?$/,"/")}codebuff/config/prompts`,{signal:a.signal});if(!t.ok)return n;const r=await t.json();for(const e of Kt){const t=r?.[e];"string"==typeof t&&t.trim()&&"(프롬프트를 불러오는 중...)"!==t&&(n[e]=t)}}catch(e){console.warn("[featurePrompts] 설정을 못 받아 기본 템플릿을 씁니다:",e)}finally{clearTimeout(r)}return n}function en(e,t){return e.replace(/\{\{([A-Z_]+)\}\}/g,(e,n)=>Object.prototype.hasOwnProperty.call(t,n)?t[n]:e)}function tn(e){return e?`\n\n실행 결과:\n\`\`\`\n${e}\n\`\`\``:""}const nn=(e,t,n=Qt)=>{const a=n.review_rules_prompt,r=[{label:"보안",prompt:n.review_security_prompt},{label:"성능",prompt:n.review_performance_prompt},{label:"코드 품질",prompt:n.review_quality_prompt},{label:"요약",prompt:n.review_summary_prompt}],s=Math.ceil(e.length/3);let o;return o=s<2e3?[{displayLabel:"전체 코드리뷰",perspectiveIndices:[0,1,2,3]}]:r.map((e,t)=>({displayLabel:`코드리뷰: ${e.label}`,perspectiveIndices:[t]})),console.log(`[AgentPanel] /review strategy: ${o.length} call(s), estimated ~${s} input tokens, ${t} items`),{callPlan:o,perspectives:r,commonRules:a}},an=new u.LabIcon({name:"codebuff:tab-icon",svgstr:Bt}),rn=8192,sn=e=>e.startsWith("provider:")?e.slice(9):null,on=({content:e})=>{const[t,n]=(0,i.useState)(!1);return t?d().createElement("div",{className:"jp-agent-orbit-raw"},d().createElement("div",{className:"jp-agent-orbit-raw-header"},d().createElement("span",{className:"jp-agent-orbit-raw-title"},"마크다운 원문 (렌더러 입력)"),d().createElement("span",{className:"jp-agent-orbit-raw-spacer"}),d().createElement("button",{className:"jp-agent-orbit-raw-tab",onClick:()=>navigator.clipboard.writeText(e),title:"원문 복사"},"복사"),d().createElement("button",{className:"jp-agent-orbit-raw-tab",onClick:()=>n(!1)},"닫기")),d().createElement("pre",{className:"jp-agent-orbit-raw-body"},e||"(빈 응답)")):d().createElement("button",{className:"jp-agent-orbit-raw-toggle",onClick:()=>n(!0),title:"렌더링 전 마크다운 원문을 표시합니다 (렌더링 문제 vs 마크다운 자체 문제 판별)"},"마크다운 원문 보기")},ln=(0,i.forwardRef)(({apiService:e,notebookTracker:t,consoleTracker:a},r)=>{const[o,l]=(0,i.useState)([]),[u,m]=(0,i.useState)(""),[p,h]=(0,i.useState)(!1),[g,f]=(0,i.useState)(!1),[b,v]=(0,i.useState)(null),y=(0,i.useRef)(Date.now()),[E,k]=(0,i.useState)(""),w=(0,i.useRef)(null),N=(0,i.useRef)({}),j=(0,i.useRef)(!1),[$,T]=(0,i.useState)([]),[A,I]=(0,i.useState)(!1),P=(0,i.useRef)(null);(0,i.useEffect)(()=>{if(!A)return;const e=e=>{P.current&&!P.current.contains(e.target)&&I(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[A]);const R="codebuff:providers",q="codebuff:active-provider",D="codebuff:last-mode",O="hdsp-agent:active-provider";(0,i.useEffect)(()=>{let t=[];try{t=JSON.parse((0,S.GK)(R,"hdsp-agent:providers")||"[]")}catch{t=[]}if(!Array.isArray(t)||0===t.length)return;const n=(0,S.GK)(q,O)||"";Promise.all(t.map(t=>e.registerAgentProvider(t.name,t.port,t.owner).catch(()=>null))).then(()=>e.getAgentProviders()).then(t=>{t.filter(e=>!e.alive).forEach(t=>{e.unregisterAgentProvider(t.name).catch(()=>null)});const a=t.filter(e=>e.alive);T(a),ia(a);const r=a.find(e=>e.name===n);r&&Q(`provider:${r.name}`)}).catch(()=>T([]))},[]);const[z,F]=(0,i.useState)(!1),[B,W]=(0,i.useState)(!1);(0,i.useEffect)(()=>{z||e.getConfigStatus().then(e=>W(function(e){return"error"===e.remote.state||"error"===e.skills.state||"error"===e.ingest.state||"codex"===e.codex.engine&&"no_endpoint"===e.codex.reason||e.rag.enabled&&!!e.rag.error}(e))).catch(()=>W(!1))},[z]);const[U,H]=(0,i.useState)(()=>"false"===document.body.getAttribute("data-jp-theme-light"));(0,i.useEffect)(()=>{const e=new MutationObserver(()=>H("false"===document.body.getAttribute("data-jp-theme-light")));return e.observe(document.body,{attributes:!0,attributeFilter:["data-jp-theme-light"]}),()=>e.disconnect()},[]);const J=(0,i.useRef)(!1);(0,i.useEffect)(()=>{if(J.current&&!g){const e=window.jupyterapp;(async function(e,t){const n=[],a=new Set;for(const r of e){if(a.has(r))continue;a.add(r);const e=r.contentsModel?.last_modified;if(!e||r.model.dirty)continue;let s;try{s=await t(r.path)}catch{continue}if(!(!s||Date.parse(s)<=Date.parse(e)||r.model.dirty))try{await r.revert(),n.push(r.path)}catch{}}return n})(function(e){const t=[],n=e?.shell?.widgets?.("main");if(!n)return t;for(const e of n){const n=e?.context;n&&"function"==typeof n.revert&&n.model&&t.push(n)}return t}(e),async t=>(await e.serviceManager.contents.get(t,{content:!1})).last_modified).catch(e=>console.warn("[AgentPanel] 열린 문서 동기화 실패",e))}J.current=g},[g]);const[V,G]=(0,i.useState)(null),[X,Z]=(0,i.useState)(!1),[K,Q]=(0,i.useState)("simple"),[Y]=(0,i.useState)(()=>localStorage.getItem(D));(0,i.useEffect)(()=>{"codex"===K||"agent"===K?localStorage.setItem(D,K):"simple"===K&&localStorage.removeItem(D)},[K]),(0,i.useEffect)(()=>{const e=sn(K);e?localStorage.setItem(q,e):(0,S.kA)(q,O)},[K]);const[ee,te]=(0,i.useState)(!1),[ne,ae]=(0,i.useState)(!0),[re,se]=(0,i.useState)(!1),[oe,le]=(0,i.useState)(!1),[ie,de]=(0,i.useState)("codex"),[ue,me]=(0,i.useState)(null),[pe,he]=(0,i.useState)(!1),[ge,fe]=(0,i.useState)(null),[be,ve]=(0,i.useState)(null),[ye,ke]=(0,i.useState)(!1),[we,xe]=(0,i.useState)(null);(0,i.useEffect)(()=>(e.setCodexThreadsListener(xe),()=>e.setCodexThreadsListener(null)),[e]);const[Se,_e]=(0,i.useState)([]),[Ce,je]=(0,i.useState)([]),[$e,Te]=(0,i.useState)(!1),[Ae,Ie]=(0,i.useState)(),[Pe,Le]=(0,i.useState)([]),[Me,Re]=(0,i.useState)([]),[De,Fe]=(0,i.useState)(0);(0,i.useEffect)(()=>{let t=!0;return e.listCodexProcesses().then(e=>{t&&(_e(e.processes||[]),Te(Boolean(e.proxy)),Ie(e.proxy_reason))}).catch(()=>{}),()=>{t=!1}},[e,De]),(0,i.useEffect)(()=>(e.setFileDiffListener(e=>{je(t=>Oe(t,{path:e.path,diff:e.diff}))}),()=>e.setFileDiffListener(null)),[e]),(0,i.useEffect)(()=>{const t=[];return e.setCodexProcessListener(e=>{_e(t=>[...t.filter(t=>t.id!==e.id),e]),t.push(window.setTimeout(()=>Fe(e=>e+1),1500))}),()=>{e.setCodexProcessListener(null),t.forEach(e=>window.clearTimeout(e))}},[e]);const He=Se.some(e=>"running"===e.state);(0,i.useEffect)(()=>{if(!He)return;const e=window.setInterval(()=>Fe(e=>e+1),5e3);return()=>window.clearInterval(e)},[He]);const Je=e=>`${e.id}:${e.pid}`,Ve=Se.filter(e=>"running"===e.state||!Pe.includes(Je(e))),[Ge,Xe]=(0,i.useState)(!1),[Ke,Qe]=(0,i.useState)(0),Ye=(0,i.useRef)(null),[et,tt]=(0,i.useState)(null),[nt,at]=(0,i.useState)(!1),rt=(0,i.useRef)([]),[st,ot]=(0,i.useState)(!1),[lt,ct]=(0,i.useState)(!1),it=2e3,dt=(0,i.useRef)(0),ut=(0,i.useRef)(null),mt=(0,i.useRef)(null),pt=(0,i.useCallback)(e=>{const t=Date.now(),n=t-dt.current;if(ut.current&&(clearTimeout(ut.current),ut.current=null),null!==e)if(n<it&&dt.current>0){const t=it-n;mt.current=e,ut.current=setTimeout(()=>{null!==mt.current&&(tt(mt.current),dt.current=Date.now(),mt.current=null)},t)}else tt(e),dt.current=t;else if(n<it&&dt.current>0){const e=it-n;ut.current=setTimeout(()=>{tt(null),dt.current=0},e)}else tt(null),dt.current=0},[]),ht=(e,t)=>{const n="string"==typeof t?t:t?.status;if(!n||"__clear__"===n)return;ut.current&&(clearTimeout(ut.current),ut.current=null),mt.current=null,rt.current=[...rt.current,n];const a=rt.current.join("\n");tt(a),l(t=>t.map(t=>t.id===e&&pa(t)?{...t,metadata:{...t.metadata,statusHistory:a}}:t))},gt=(0,i.useRef)(0);(0,i.useEffect)(()=>{if(z)return;const e=++gt.current,t=1===e;fetch(c.URLExt.join(c.PageConfig.getBaseUrl(),"codebuff/config")).then(e=>e.ok?e.json():null).then(n=>{if(!n||e!==gt.current)return;te(!1!==n?.features?.eda_enabled);const a=!0===n?.features?.agent_enabled;se(a),ae(!1!==n?.features?.bdp_qa_enabled);const r=!0===n?.features?.codex_enabled;le(r);const s="langchain"===n?.features?.inference_engine?"langchain":"codex";de(s),t&&("codex"===Y&&r&&a&&"codex"===s||"agent"===Y&&a&&"langchain"===s)&&Q(Y)}).catch(()=>{})},[z]),(0,i.useEffect)(()=>()=>{ut.current&&clearTimeout(ut.current)},[]);const[ft,bt]=(0,i.useState)(null),[vt,Et]=(0,i.useState)([]),[kt,wt]=(0,i.useState)(!0),[St,Ct]=(0,i.useState)(!1),[Nt,jt]=(0,i.useState)(null),$t=(0,i.useRef)(null),[Tt,At]=(0,i.useState)(!1),[It,qt]=(0,i.useState)(null),[Bt,Wt]=(0,i.useState)(!1),[Vt,Gt]=(0,i.useState)(null),Zt=(0,i.useRef)(null),Kt=(0,i.useRef)(new Map),Qt=(0,i.useRef)(!1),en=(0,i.useRef)([]),tn=(0,i.useRef)(new Set),an=()=>{const e=window.jupyterapp,t=e?.shell?.currentWidget;return(e=>{if(!e)return!1;if(e instanceof s.NotebookPanel)return!0;const t=e?.content?.model;return Boolean(t&&(t.cells||t.sharedModel?.cells))})(t)?t:null},ln=(e,t)=>{try{const n=e.content.widgets[t];n?.node&&setTimeout(()=>{n.node.scrollIntoView({behavior:"smooth",block:"center"})},100)}catch(e){console.warn("[AgentPanel] Failed to scroll to cell:",e)}},cn=(e,t,n)=>{const a=e.content?.model,r=a?.cells?.length??a?.sharedModel?.cells?.length;if(!a?.sharedModel||void 0===r)return console.warn("[AgentPanel] Notebook model not ready for insert"),null;const s=r;return a.sharedModel.insertCell(s,{cell_type:t,source:n,metadata:{codebuff_source:"created"}}),e.content.activeCellIndex=s,ln(e,s),s},dn=(0,i.useCallback)(e=>{const t=an();t?(((e,t)=>{const n=e.content?.model;if(!n?.sharedModel)return console.warn("[AgentPanel] Notebook model not ready for insertAbove"),null;const a=e.content.activeCellIndex,r=a>=0?a:0;n.sharedModel.insertCell(r,{cell_type:"code",source:t,metadata:{codebuff_source:"created"}}),e.content.activeCellIndex=r,ln(e,r),console.log("[AgentPanel] Inserted cell above at index:",r)})(t,e),Ze.c.getInstance().trackClick("code_insert_from_agent",{position:"above",code_length:e.length,code_lines:e.split("\n").length,block_id:Ze.c.blockIdOf(e)})):console.warn("[AgentPanel] No active notebook for insert above")},[]),un=(0,i.useCallback)(e=>{const t=an();t?(((e,t)=>{const n=e.content?.model,a=n?.cells?.length??n?.sharedModel?.cells?.length;if(!n?.sharedModel||void 0===a)return console.warn("[AgentPanel] Notebook model not ready for insertBelow"),null;const r=e.content.activeCellIndex,s=r>=0?r+1:a;n.sharedModel.insertCell(s,{cell_type:"code",source:t,metadata:{codebuff_source:"created"}}),e.content.activeCellIndex=s,ln(e,s),console.log("[AgentPanel] Inserted cell below at index:",s)})(t,e),Ze.c.getInstance().trackClick("code_insert_from_agent",{position:"below",code_length:e.length,code_lines:e.split("\n").length,block_id:Ze.c.blockIdOf(e)})):console.warn("[AgentPanel] No active notebook for insert below")},[]),mn=(0,i.useCallback)(e=>{const t=an();t?(cn(t,"code",e),Ze.c.getInstance().trackClick("code_insert_from_agent",{position:"new_cell",code_length:e.length,code_lines:e.split("\n").length,block_id:Ze.c.blockIdOf(e)})):console.warn("[AgentPanel] No active notebook for insert as cell")},[]),pn=async(e,t)=>{try{await e.sessionContext.ready,e.content.activeCellIndex=t,ln(e,t),await s.NotebookActions.run(e.content,e.sessionContext),await hn(e,t)}catch(e){console.error("[AgentPanel] Cell execution failed:",e)}},hn=(e,t,n=2e3,a=100)=>new Promise(r=>{const s=e.content.widgets[t],o=s?.model;if(!o)return void r();const l=o.outputs;if(l&&l.length>0)return void r();if(null!=o.executionCount)return void setTimeout(r,150);let c=0;const i=setInterval(()=>{c+=a;const e=o.outputs,t=o.executionCount;(e&&e.length>0||c>=n||null!=t)&&(clearInterval(i),setTimeout(r,100))},a)}),gn=(e,t)=>{const n=e.content.widgets[t],a=n?.model,r=a?.outputs,s=a?.executionState,o="string"==typeof s?s:s?.get?.()??s?.value??null,l={success:!0,output:"",error:void 0,error_type:void 0,traceback:void 0,execution_count:a?.executionCount??null,execution_state:o,kernel_status:e.sessionContext?.session?.kernel?.status??null,cell_type:a?.type??null,outputs:[]};if(!r||0===r.length)return l;const c=e=>{const t={};return Object.keys(e||{}).forEach(n=>{n.toLowerCase().startsWith("image/")||(t[n]=e[n])}),t},i=["command not found","ModuleNotFoundError","No module named","Traceback (most recent call last)","Error:"];for(let e=0;e<r.length;e++){const t=r.get(e),n=t.toJSON?.()||t;let a=n;if("error"===t.type)l.outputs.push(a),l.success=!1,l.error_type=n.ename,l.error=n.evalue,Array.isArray(n.traceback)&&(l.traceback=n.traceback);else if("stream"===t.type&&n.text){l.outputs.push(a),l.output+=n.text;const e=n.text.toLowerCase();i.some(t=>e.includes(t.toLowerCase()))&&(l.success=!1,l.error_type="runtime_error",l.error=n.text.trim())}else if(("execute_result"===t.type||"display_data"===t.type)&&n.data){const e=c(n.data);Object.keys(e).length>0&&(a={...n,data:e},l.outputs.push(a),l.output+=JSON.stringify(e))}}return l},fn=async()=>{const e=an();if(!e)return console.warn("[AgentPanel] No active notebook to execute cell"),null;const t=en.current;if(0===t.length)return Qt.current=!1,null;const n=t.shift();if(!n)return Qt.current=!1,null;if("jupyter_cell"===n.tool&&n.code&&"number"==typeof n.cellIndex){await pn(e,n.cellIndex);const t=gn(e,n.cellIndex);return t.code=n.code,n.execution_result=t,console.log("[AgentPanel] Executed approved code cell from tool call"),Qt.current=en.current.length>0,n}return Qt.current=en.current.length>0,n},bn=e=>Boolean(e?.autoApprove),vn=()=>V||C()||{workspaceRoot:"",autoApprove:!1},yn=e=>{const t=an();if(!t)return void console.warn("[AgentPanel] No active notebook to add approval cell");const n=`jupyter_cell:${e}`;if(tn.current.has(n))return;const a=cn(t,"code",e);null!==a&&(tn.current.add(n),Qt.current=!0,en.current.push({tool:"jupyter_cell",code:e,cellIndex:a}),console.log("[AgentPanel] Added code cell pending approval via interrupt"))},En=e=>{const t=`${e.tool}:${e.code||e.content||""}`;if(!tn.current.has(t)&&"jupyter_cell"!==e.tool&&"jupyter_markdown"===e.tool&&(e.content||e.code)){const n=an();if(!n)return void console.warn("[AgentPanel] No active notebook to add markdown");const a=e.content||e.code||"";null!==cn(n,"markdown",a)&&(tn.current.add(t),console.log("[AgentPanel] Added markdown cell from tool call"))}},kn=(0,i.useRef)(null),wn=(0,i.useRef)(null),xn=(0,i.useRef)(null),Sn=(0,i.useRef)(void 0),_n=(0,i.useRef)([]),Cn=(0,i.useRef)(null),Nn=(0,i.useRef)(null),jn=e=>{const t=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`;return e?`${t}-${e}`:t};(0,i.useImperativeHandle)(r,()=>({handleSendMessage:async()=>{await oa()},setInput:e=>{m(e)},setLlmPrompt:e=>{xn.current=e;const t=wn.current?.parentElement?.querySelector(".jp-agent-input");t&&t.setAttribute("data-llm-prompt",e)},setMaxTokens:e=>{Sn.current=e},setCurrentCellId:e=>{console.log("[AgentPanel] setCurrentCellId called with:",e),Cn.current=e},setCurrentCellIndex:e=>{console.log("[AgentPanel] setCurrentCellIndex called with:",e),Nn.current=e},setInputMode:e=>{console.log("[AgentPanel] setInputMode called with:",e),Q(e)},sendChatMessage:async e=>await In(e),addAssistantMessage:e=>{const t={id:jn("review-intro"),role:"assistant",content:e,timestamp:Date.now()};l(e=>[...e,t])}})),(0,i.useEffect)(()=>{$n(),function(){try{(0,S.kA)("codebuff-admin-llm-config","hdsp-agent-admin-llm-config")}catch{}}()},[]),(0,i.useEffect)(()=>{"agent"!==K&&"codex"!==K||re||(console.log("[AgentPanel] Agent feature disabled in config, forcing chat mode"),Q("simple"))},[re,K]),(0,i.useEffect)(()=>{at(!1)},[et]),(0,i.useEffect)(()=>{if(!a)return void console.log("[AgentPanel] ConsoleTracker not available");console.log("[AgentPanel] Setting up console output monitoring");const e=()=>{const e=a.currentWidget;var t;if(e)try{const n=e.node;if(!n)return;const a=n.querySelectorAll(".jp-OutputArea-output");if(0===a.length)return;const r=Array.from(a).slice(-5);let s="";r.forEach(e=>{const t=e.textContent||"";s+=t+"\n"}),t=s,[/Traceback \(most recent call last\)/i,/SyntaxError:/i,/NameError:/i,/TypeError:/i,/ImportError:/i,/ModuleNotFoundError:/i,/AttributeError:/i,/ValueError:/i,/KeyError:/i,/IndexError:/i,/FileNotFoundError:/i,/File\s+"[^"]+\.py"/i].some(e=>e.test(t))&&(console.log("[AgentPanel] Python error detected in console output"),ue!==s&&(me(s),he(!0),setTimeout(()=>{he(!1)},1e4)))}catch(e){console.error("[AgentPanel] Error checking console output:",e)}};let t=null;const n=()=>{const n=a.currentWidget;n?.node&&(t&&t.disconnect(),t=new MutationObserver(t=>{t.some(e=>"childList"===e.type||"characterData"===e.type)&&setTimeout(e,100)}),t.observe(n.node,{childList:!0,subtree:!0,characterData:!0}),console.log("[AgentPanel] MutationObserver set up for console"))};n();const r=()=>{console.log("[AgentPanel] Console changed, re-setting up observer"),n()};return a.currentChanged?.connect(r),()=>{t&&t.disconnect(),a.currentChanged?.disconnect(r)}},[a,ue]);const $n=()=>{const e=C();if(!e)return console.log("[AgentPanel] No config in localStorage, using default"),void G({workspaceRoot:"",autoApprove:!1});G(e),console.log("=== Codebuff User Preferences (localStorage) ==="),console.log("Workspace Root:",e.workspaceRoot||"(default)"),console.log("Auto Approve:",e.autoApprove?"✓ Enabled":"✗ Disabled"),console.log("Note: LLM settings are managed by Agent Server AdminConfig"),console.log("====================================================")},Tn=async()=>{if(console.log("[AgentPanel] Stopping current task..."),Ct(!0),$t.current&&($t.current.abort(),$t.current=null,console.log("[AgentPanel] Aborted fetch request")),w.current)try{await e.cancelChat(w.current)}catch(e){console.warn("[AgentPanel] Error cancelling server-side chat:",e)}if(Nt)try{const t=await e.cancelAgent(Nt);console.log("[AgentPanel] Server-side agent cancel result:",t)}catch(e){console.warn("[AgentPanel] Error cancelling server-side agent:",e)}try{const e=t?.currentWidget;if(e?.sessionContext?.session?.kernel){const t=e.sessionContext.session.kernel;console.log("[AgentPanel] Notebook kernel status:",t.status),await t.interrupt(),console.log("[AgentPanel] Interrupted notebook kernel")}if(a?.currentWidget?.sessionContext?.session?.kernel){const e=a.currentWidget.sessionContext.session.kernel;console.log("[AgentPanel] Console kernel status:",e.status),await e.interrupt(),console.log("[AgentPanel] Interrupted console kernel")}}catch(e){console.warn("[AgentPanel] Failed to interrupt kernel:",e)}h(!1),f(!1),Z(!1),v(null),bt(null),At(!1),qt(null),jt(null),Et(e=>e.map(e=>"in_progress"===e.status?{...e,status:"cancelled"}:e)),Pn("작업이 중단되었습니다.","info"),console.log("[AgentPanel] Task stopped successfully")},An=(0,i.useRef)(null);(0,i.useEffect)(()=>{const e=kn.current;if(e)return g?An.current=setInterval(()=>{e.scrollHeight-e.scrollTop-e.clientHeight<1e3&&(e.scrollTop=e.scrollHeight)},1e3):(An.current&&(clearInterval(An.current),An.current=null),setTimeout(()=>{e&&(e.scrollTop=e.scrollHeight)},100)),()=>{An.current&&(clearInterval(An.current),An.current=null)}},[g]);const In=async({displayContent:t,llmPrompt:n,textarea:a,clearInput:r=!0,maxTokens:s,freshConversation:o=!1,attachActiveNotebook:c=!1})=>{const i=t||(n?"셀 분석 요청":"");if(!i&&!n)return;Ze.c.getInstance().trackClick("agent"!==K?"chat_send":"agent_send",{input_mode:K,prompt:i});const d=vn(),u=bn(d),p={id:jn(),role:"user",content:i,timestamp:Date.now()};l(e=>[...e,p]),requestAnimationFrame(()=>{const e=kn.current;e&&(e.scrollTop=e.scrollHeight)}),r&&i&&m(""),h(!0),f(!0),Ct(!1),vt.some(e=>"pending"===e.status||"in_progress"===e.status)||Et([]),pt(null),rt.current=[],n&&(xn.current=null,a&&a.removeAttribute("data-llm-prompt"));const g=jn("assistant");let b="";y.current=Date.now(),v(g),ot(!1),ct(!1);const x={id:g,role:"assistant",content:"",timestamp:Date.now(),...sn(K)?{metadata:{providerResponse:!0}}:{}};l(e=>[...e,x]);try{const t=n||i,a=c?`${await(async()=>{const e=an(),t=e=>{const t=[];for(let n=0;n<e.length;n++){const a=e.get(n),r=a.sharedModel?.getSource?.()||"",s=a.type||"code",o=a.executionCount,l=null!=o?`, In[${o}]`:"";t.push({text:`# Cell ${n+1} (${s}${l}):\n${r}`,sourceEmpty:""===r.trim()})}return t};let n;if(e){const a=e.content.model?.cells;if(a&&0!==a.length){let e=t(a);const r=e.filter(e=>e.sourceEmpty).length;r>a.length/2&&a.length>1&&(console.warn(`[buildActiveNotebookContext] ${r}/${a.length} cells empty — waiting for model load`),await new Promise(e=>setTimeout(e,500)),e=t(a)),n=e.map(e=>e.text).join("\n\n")}else n="[노트북에 셀이 없습니다]"}else n="[노트북이 열려있지 않습니다]";return`--- Current Notebook ---\n${n}\n--- End Notebook ---`})()}\n\n${t}`:t,r=n||c?{fileMentions:!1}:{},m=sn(K);if(m)$t.current=new AbortController,await e.sendProviderStream(m,{message:a,threadId:N.current[m]||void 0},e=>{b+=e,l(e=>e.map(e=>e.id===g&&pa(e)?{...e,content:b}:e))},e=>{e.threadId&&(N.current[m]=e.threadId)},$t.current.signal,e=>{const t="string"==typeof e?e:e.status;rt.current=[...rt.current,t],tt(rt.current.join("\n"))});else if("agent"!==K&&"codex"!==K){$t.current=new AbortController;const t=o?jn("conversation"):E||jn("conversation");w.current=t,o||E||k(t);const n=s||Sn.current;Sn.current=void 0,await e.sendChatStream({message:a,conversationId:t,llmConfig:d,...r,...o?{freshConversation:!0}:{},...n?{maxTokens:n}:{}},e=>{if(e.startsWith("__input_masked__:"))try{const t=JSON.parse(e.slice(17)),n=a===i;l(e=>{const a=[...e];for(let e=a.length-1;e>=0;e--){const r=a[e];if("user"===r.role&&pa(r)){a[e]={...r,content:n?t.maskedText:r.content,metadata:{...r.metadata,maskedTypes:t.detectedTypes}};break}}return a})}catch(e){console.warn("[PII] Failed to parse input_masked chunk:",e)}else{if(!e.startsWith("__warning__:"))return"__content_clear__"===e?(b="",void l(e=>e.map(e=>e.id===g&&pa(e)?{...e,content:""}:e))):void("__tool_processing__"!==e?"__tool_processing_end__"!==e?"__summarizing__"!==e?(lt&&ct(!1),b+=e,l(e=>e.map(e=>e.id===g&&pa(e)?{...e,content:b}:e))):ct(!0):ot(!1):ot(!0));Pn(e.slice(12),"warning")}},e=>{o||!e.conversationId||E||k(e.conversationId)},$t.current.signal,e=>{const t="string"==typeof e?e:e.status;if("__clear__"===t)return rt.current=[],void tt(null);t.includes("컬럼")?rt.current=[...rt.current.filter(e=>!e.includes("컬럼")),t]:rt.current=[...rt.current,t],tt(rt.current.join("\n"))})}else e.setAgentEngine("codex"===K?"codex":"client"),$t.current=new AbortController,await e.sendAgentV2Stream({message:a,conversationId:o?void 0:E||void 0,llmConfig:d,...r},e=>{b+=e,l(e=>e.map(e=>e.id===g&&pa(e)?{...e,content:b}:e))},e=>{o||!e.conversationId||E||k(e.conversationId),(e.provider||e.model)&&l(t=>t.map(t=>t.id===g&&pa(t)?{...t,metadata:{...t.metadata,provider:e.provider,model:e.model}}:t))},e=>{"codex"===K?ht(g,e):pt(e)},e=>{if(Qt.current=!0,e.threadId&&!Nt&&(jt(e.threadId),console.log("[AgentPanel] Captured agentThreadId from interrupt:",e.threadId)),"search_notebook_cells_tool"!==e.action&&"check_resource_tool"!==e.action&&"read_file_tool"!==e.action&&"list_workspace_tool"!==e.action&&"search_files_tool"!==e.action){if("jupyter_cell_tool"===e.action&&"READ"===e.args?.operation)return console.log("[AgentPanel] Auto-approving jupyter_cell READ operation"),void ra(e,"approve").catch(e=>{console.error("[AgentPanel] jupyter_cell READ auto-approve FAILED:",e)});if("ask_user_tool"===e.action){console.log("[AgentPanel] ask_user_tool interrupt:",e.args),Wt(!0),Gt(e),h(!1),f(!1);const t=e.args?.question||"응답을 입력하세요...",n=e.args?.options,a=e.args?.input_type||"text";let r=`❓ **${t}**`;n&&n.length>0&&(r+="\n\n선택지:\n"+n.map((e,t)=>`${t+1}. ${e}`).join("\n")),"file"===a&&(r+="\n\n_(파일을 업로드하거나 파일 경로를 입력하세요)_");const s={id:jn("ask_user"),role:"assistant",content:r,timestamp:Date.now()};return l(e=>[...e,s]),void setTimeout(()=>{const e=document.querySelector(".jp-agent-input");e&&(e.focus(),e.placeholder=t)},100)}if(u||e.autoApprove){if(Kn(e,!0),"jupyter_cell_tool"===e.action&&e.args?.code){const t=Jn(e.args.code);console.log("[AgentPanel] AUTO-APPROVE jupyter_cell_tool: shouldQueue=",t,"code=",e.args.code.slice(0,80)),t&&yn(e.args.code)}return console.log("[AgentPanel] AUTO-APPROVE: calling resumeFromInterrupt, action=",e.action),void ra(e,"approve").catch(e=>{console.error("[AgentPanel] AUTO-APPROVE resumeFromInterrupt FAILED:",e)})}if("jupyter_cell_tool"===e.action&&e.args?.code){const t=Jn(e.args.code);if(Bn(e.args.code))return t&&yn(e.args.code),void ra(e,"approve").catch(e=>{console.error("[AgentPanel] auto-approved code resumeFromInterrupt FAILED:",e)});t&&yn(e.args.code)}bt(e),Kn(e),h(!1),f(!1)}else aa(e)},e=>{console.log("[AgentPanel] Todos updated:",e.length,"items"),Et(e)},()=>{pt(null)},En,e=>{e.threadId&&(jt(e.threadId),console.log("[AgentPanel] Captured agentThreadId for context persistence:",e.threadId))},Nt||void 0,$t.current?.signal)}catch(e){if(e instanceof Error&&"AbortError"===e.name)Ze.c.getInstance().trackError("chat_abort",{input_mode:K}),console.log("[AgentPanel] Chat stream stopped by user"),pt(null),b&&l(e=>e.map(e=>e.id===g&&pa(e)?{...e,content:b+"\n\n*(응답 중단됨)*"}:e));else{const t=e instanceof Error?e.message:"Failed to send message";Ze.c.getInstance().trackError("chat_error",{input_mode:K,error:t}),pt(`오류: ${t}`);const n=function(e,t){return`\n\n> 문제가 발생했습니다. ${e}\n> ${Dt(t)}`}(t,e?.gatewayReason);l(e=>e.map(e=>e.id===g&&pa(e)?{...e,content:b+n}:e))}}finally{const e=rt.current.join("\n");e&&l(t=>t.map(t=>t.id===g&&pa(t)?{...t,metadata:{...t.metadata,statusHistory:e}}:t)),Qt.current||(h(!1),f(!1),v(null)),rt.current=[],tt(null),$t.current=null,w.current=null}return b};(0,i.useEffect)(()=>{const e=setTimeout(()=>{const e=document.querySelector(".jp-agent-messages")||wn.current?.parentElement||document.querySelector('[class*="jp-agent-messages"]');if(!e)return void console.log("[AgentPanel] Messages container not found");const t=[];e.querySelectorAll(".code-block-container").forEach(e=>{const n=e.getAttribute("data-block-id");if(!n)return;const a=e.querySelector(`#${n}`);if(!a)return;const r=a.textContent||"",s=e.querySelector(".code-block-language"),o=s?.textContent?.toLowerCase()||"python";t.push({id:n,code:r,language:o})}),_n.current=t;const n=async e=>{const t=e.target,n=t.closest(".jp-next-items-item");if(n){e.stopPropagation(),e.preventDefault();const t=n.querySelector(".jp-next-items-subject")?.textContent?.trim()||"",a=n.querySelector(".jp-next-items-description")?.textContent?.trim()||"",r=t&&a?`${t}\n\n${a}`:t||a;return void(r&&(async e=>{const t=e.trim();if(!t)return;const n=null!==ft,a=0===vt.length||vt.every(e=>"completed"===e.status);n||X&&!a?Pn("다른 작업이 진행 중입니다. 완료 후 다시 시도해주세요.","warning"):await In({displayContent:t,clearInput:!0})})(r))}if(t.classList.contains("code-block-toggle")||t.closest(".code-block-toggle")){const n=t.classList.contains("code-block-toggle")?t:t.closest(".code-block-toggle");e.stopPropagation(),e.preventDefault();const a=n.closest(".code-block-container");if(!a)return;const r=a.classList.toggle("is-expanded");n.setAttribute("aria-expanded",String(r)),n.setAttribute("title",r?"접기":"전체 보기"),n.setAttribute("aria-label",r?"접기":"전체 보기");const s=n.querySelector(".code-block-toggle-icon");return void(s&&(s.textContent=r?"▴":"▾"))}if(t.classList.contains("code-block-copy")||t.closest(".code-block-copy")){const n=t.classList.contains("code-block-copy")?t:t.closest(".code-block-copy");e.stopPropagation(),e.preventDefault();const a=n.getAttribute("data-block-id");if(!a)return;const r=_n.current.find(e=>e.id===a);if(!r)return;try{await navigator.clipboard.writeText(r.code),Ze.c.getInstance().trackClick("code_copy_from_agent",{code_length:r.code.length,code_lines:r.code.split("\n").length,block_id:Ze.c.blockIdOf(r.code)});const e=n.textContent;n.textContent="복사됨!",setTimeout(()=>{n.textContent=e||"복사"},2e3)}catch(e){console.error("Failed to copy code:",e),Pn("복사에 실패했습니다.","error")}return}if(t.classList.contains("code-block-apply")||t.closest(".code-block-apply")){const n=t.classList.contains("code-block-apply")?t:t.closest(".code-block-apply");e.stopPropagation(),e.preventDefault();const a=n.getAttribute("data-block-id");if(console.log(`[AgentPanel] Apply button clicked via delegation, blockId: ${a}`),!a)return void Pn("코드 블록 ID를 찾을 수 없습니다.","error");const r=_n.current.find(e=>e.id===a);return r?(console.log(`[AgentPanel] Applying code to cell via delegation, code length: ${r.code.length}`),void await Mn(r.code,a,n)):(console.error("[AgentPanel] Block not found!",{clickedId:a,availableIds:_n.current.map(e=>e.id),blocksCount:_n.current.length}),void Pn("코드를 찾을 수 없습니다.","error"))}};e.addEventListener("click",n),e._agentPanelClickHandler=n},100);return()=>{clearTimeout(e);const t=document.querySelector(".jp-agent-messages")||wn.current?.parentElement||document.querySelector('[class*="jp-agent-messages"]');t&&t._agentPanelClickHandler&&(t.removeEventListener("click",t._agentPanelClickHandler),delete t._agentPanelClickHandler)}},[o.length,b]);const Pn=(e,t="info")=>{const n=((e,t)=>{const n=document.createElement("div");return n.style.cssText=`\n position: fixed;\n top: 20px;\n right: 20px;\n padding: 12px 16px;\n border-radius: 6px;\n color: white;\n font-size: 14px;\n font-weight: 500;\n z-index: 10001;\n opacity: 0;\n transition: opacity 0.3s ease;\n max-width: 300px;\n word-wrap: break-word;\n background: ${t};\n `,n.textContent=e,n})(e,(e=>{switch(e){case"error":return"#f56565";case"warning":return"#ed8936";default:return"#4299e1"}})(t));document.body.appendChild(n),(e=>{setTimeout(()=>e.style.opacity="1",10),setTimeout(()=>{e.style.opacity="0",setTimeout(()=>{e.parentNode&&e.parentNode.removeChild(e)},300)},3e3)})(n)},Ln=(e,t)=>{const n=document.querySelector(".jp-agent-cell-tooltip");n&&n.remove();const a=document.createElement("div");a.className="jp-agent-cell-tooltip",a.textContent=t,a.style.cssText="\n position: absolute;\n top: 0;\n left: 50%;\n transform: translateX(-50%);\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 8px 16px;\n border-radius: 0 0 8px 8px;\n font-size: 13px;\n font-weight: 500;\n box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n z-index: 1000;\n opacity: 0;\n transition: opacity 0.3s ease;\n pointer-events: none;\n white-space: nowrap;\n ";const r=e.style.position;r&&"static"!==r||(e.style.position="relative"),e.appendChild(a),requestAnimationFrame(()=>{a.style.opacity="1"}),setTimeout(()=>{a.style.opacity="0",setTimeout(()=>{a.remove(),r&&"static"!==r||(e.style.position=r||"")},300)},2e3)},Mn=async(e,t,n)=>{console.log("[AgentPanel] applyCodeToCell called",{codeLength:e.length,blockId:t});const a=n.textContent;try{n.disabled=!0,n.textContent="적용 중...";const r=window.jupyterapp;if(!r)return console.error("[AgentPanel] jupyterapp not found in window"),Pn("JupyterLab을 찾을 수 없습니다.","error"),n.disabled=!1,void(n.textContent=a||"셀에 적용");console.log("[AgentPanel] Found jupyterapp");const s=r.shell.currentWidget;if(s&&"content"in s){const r=s.content;if(r&&"model"in r&&r.model&&"cells"in r.model)return void await On(e,r,t,n,a)}zn(e,n,a)}catch(e){console.error("Failed to apply code to cell:",e),Pn("코드 적용에 실패했습니다.","error"),n.disabled=!1,n.textContent=a||"셀에 적용"}},Rn=async(e,t,n)=>{const a=e.sharedModel?.getSource?.()??e.value?.text??"";return!(function(e,t){return""!==e.trim()&&e!==t}(a,t)&&!await Ut(n,a,t)||(((e,t)=>{if(e.sharedModel&&"function"==typeof e.sharedModel.setSource)e.sharedModel.setSource(t);else if(e.setSource&&"function"==typeof e.setSource)e.setSource(t);else if(e.value&&"function"==typeof e.value.setText)e.value.setText(t);else{if(!e.value||void 0===e.value.text)throw new Error("Unable to set cell source - no compatible method found");e.value.text=t}})(e,t),"function"==typeof e.setMetadata?e.setMetadata(S.zi,"modified"):"function"==typeof e.sharedModel?.setMetadata&&e.sharedModel.setMetadata(S.zi,"modified"),0))},qn=(0,i.useCallback)(async e=>{const t=an();if(!t)return void Pn("코드를 적용할 노트북이 없습니다.","error");const n=t.content.widgets,a=Nn.current,r=null!==a&&a>=0&&a<n.length?a:t.content.activeCellIndex,s=n[r];if(s)try{if(!await Rn(s.model,e,`셀 ${r+1}`))return;Nn.current=null,Cn.current=null,Ln(s.node,"✓ 코드가 적용되었습니다"),ln(t,r),Ze.c.getInstance().trackClick("code_insert_from_agent",{position:"replace",code_length:e.length,code_lines:e.split("\n").length,block_id:Ze.c.blockIdOf(e)})}catch(e){console.error("[AgentPanel] Failed to replace cell:",e),Pn("셀 내용 업데이트 실패: "+e.message,"error")}else Pn("코드를 적용할 셀이 없습니다.","error")},[]),Dn=(e,t)=>{e.disabled=!1,e.textContent=t||"셀에 적용"},On=async(e,t,n,a,r)=>{try{const s=t.widgets||[],o=t.model?.cells?.length||0;if(console.log("[AgentPanel] applyCodeToNotebookCell called",{currentCellIndex:Nn.current,currentCellId:Cn.current,blockId:n,widgetsLength:s.length,modelCellsLength:o}),null!==Nn.current&&void 0!==Nn.current)if(console.log("[AgentPanel] Using cell index:",Nn.current),0===s.length&&o>0)console.warn("[AgentPanel] Widgets not rendered yet, model has",o,"cells");else if(Nn.current>=0&&Nn.current<s.length){const t=s[Nn.current],n=t.model||t,o=`셀 ${Nn.current+1}`;console.log("[AgentPanel] Found cell at index, applying code...");try{return await Rn(n,e,o)?(console.log("[AgentPanel] Code applied successfully!"),t.node?Ln(t.node,"✓ 코드가 적용되었습니다"):Pn("코드가 셀에 적용되었습니다!","info"),Dn(a,r),Nn.current=null,void(Cn.current=null)):void Dn(a,r)}catch(e){return console.error("Failed to update cell content:",e),Pn("셀 내용 업데이트 실패: "+e.message,"error"),void Dn(a,r)}}else console.error("[AgentPanel] Cell index out of bounds:",{currentIndex:Nn.current,widgetsLength:s.length,modelCellsLength:o}),Nn.current=null,Cn.current=null;console.log("[AgentPanel] Showing cell selector dialog"),zn(e,a,r)}catch(e){console.error("Failed to apply code:",e),Pn("코드 적용에 실패했습니다.","error"),Dn(a,r)}},zn=(e,t,n)=>{try{const a=window.jupyterapp;if(!a)return Pn("JupyterLab을 찾을 수 없습니다.","error"),t.disabled=!1,void(t.textContent=n||"셀에 적용");const r=a.shell.currentWidget;if(!r||!("content"in r))return Pn("활성 노트북을 찾을 수 없습니다.","warning"),t.disabled=!1,void(t.textContent=n||"셀에 적용");const s=r.content;if(!(s&&"model"in s&&s.model&&"cells"in s.model))return Pn("활성 노트북을 찾을 수 없습니다.","warning"),t.disabled=!1,void(t.textContent=n||"셀에 적용");const o=s.widgets||[],l=[];if(o.forEach((e,t)=>{const n=e.model||e;if("code"===n.type){const a=n.metadata?.get?.("jupyterAgentCellId")||n.id||`cell-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;try{n.metadata?.get?.("jupyterAgentCellId")||n.metadata?.set&&n.metadata.set("jupyterAgentCellId",a)}catch(e){}const r=(n.sharedModel?.getSource?.()||n.value?.text||"").toString().substring(0,100).replace(/\n/g," ");l.push({cell:e,index:t,id:a,preview:r})}}),0===l.length)return Pn("코드 셀을 찾을 수 없습니다.","warning"),t.disabled=!1,void(t.textContent=n||"셀에 적용");const c=document.querySelector(".jp-agent-cell-selector-dialog");c&&c.remove();const i=document.createElement("div");i.className="jp-agent-cell-selector-dialog",i.style.cssText="\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.3);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n ";const d=document.createElement("div");d.style.cssText="\n background: var(--jp-layout-color1);\n border: 1px solid var(--jp-border-color2);\n border-radius: 4px;\n padding: 24px;\n max-width: 500px;\n width: 90%;\n max-height: 80vh;\n overflow-y: auto;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n color: var(--jp-ui-font-color1);\n ";const u=l.map(({index:e,id:t,preview:n})=>`\n <div class="jp-agent-cell-selector-item" data-cell-id="${t}" style="\n padding: 12px;\n margin-bottom: 8px;\n background: var(--jp-layout-color1);\n border: 2px solid var(--jp-border-color2);\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s ease;\n ">\n <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 4px;">\n <span style="\n background: #667eea;\n color: white;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n ">셀 ${e+1}</span>\n </div>\n <div style="font-size: 12px; color: var(--jp-ui-font-color2); font-family: 'Menlo', monospace; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">\n ${Fn(n)}${n.length>=100?"...":""}\n </div>\n </div>\n `).join("");d.innerHTML=`\n <div style="margin-bottom: 20px;">\n <h3 style="margin: 0 0 8px 0; color: var(--jp-ui-font-color1); font-size: 16px; font-weight: 500;">\n 코드를 적용할 셀 선택\n </h3>\n <p style="margin: 0; color: var(--jp-ui-font-color2); font-size: 13px;">\n AI가 생성한 코드를 적용할 셀을 선택하세요\n </p>\n </div>\n <div class="jp-agent-cell-list" style="margin-bottom: 20px;">\n ${u}\n </div>\n <div style="display: flex; gap: 12px; justify-content: flex-end;">\n <button class="jp-agent-cell-selector-cancel-btn" style="\n background: transparent;\n color: var(--jp-ui-font-color2);\n border: 1px solid var(--jp-border-color1);\n border-radius: 3px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n ">취소</button>\n </div>\n `,i.appendChild(d),document.body.appendChild(i),d.querySelectorAll(".jp-agent-cell-selector-item").forEach(a=>{a.addEventListener("click",async()=>{const r=a.getAttribute("data-cell-id");if(!r)return;const s=l.find(e=>e.id===r);if(!s)return;const o=s.cell.model||s.cell;try{if(i.remove(),!await Rn(o,e,`셀 ${s.index+1}`))return void Dn(t,n);s.cell.node?Ln(s.cell.node,"✓ 코드가 적용되었습니다"):Pn("코드가 셀에 적용되었습니다!","info"),Dn(t,n)}catch(e){console.error("Failed to apply code to cell:",e),Pn("코드 적용에 실패했습니다.","error"),Dn(t,n)}}),a.addEventListener("mouseenter",()=>{a.style.borderColor="#667eea",a.style.background="var(--jp-layout-color2)"}),a.addEventListener("mouseleave",()=>{a.style.borderColor="var(--jp-border-color2)",a.style.background="var(--jp-layout-color1)"})});const m=d.querySelector(".jp-agent-cell-selector-cancel-btn");m&&(m.addEventListener("click",()=>{i.remove(),t.disabled=!1,t.textContent=n||"셀에 적용"}),m.addEventListener("mouseenter",()=>{m.style.background="var(--jp-layout-color2)",m.style.borderColor="#9ca3af"}),m.addEventListener("mouseleave",()=>{m.style.background="transparent",m.style.borderColor="var(--jp-border-color1)"})),i.addEventListener("click",e=>{e.target===i&&(i.remove(),t.disabled=!1,t.textContent=n||"셀에 적용")});const p=e=>{"Escape"===e.key&&(i.remove(),document.removeEventListener("keydown",p),t.disabled=!1,t.textContent=n||"셀에 적용")};document.addEventListener("keydown",p)}catch(e){console.error("Failed to show cell selector:",e),Pn("셀 선택 다이얼로그 표시에 실패했습니다.","error"),t.disabled=!1,t.textContent=n||"셀에 적용"}},Fn=e=>{const t=document.createElement("div");return t.textContent=e,t.innerHTML},Bn=e=>{const t=e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith("#"));if(0===t.length)return!0;if(t.some(e=>e.startsWith("!")||e.startsWith("%%bash")||e.startsWith("%%sh")||e.startsWith("%%shell")))return!1;const n=[/(^|[^=!<>])=([^=]|$)/,/\.read_[a-zA-Z0-9_]*\s*\(/,/\bread_[a-zA-Z0-9_]*\s*\(/,/\.to_[a-zA-Z0-9_]*\s*\(/];if(t.some(e=>n.some(t=>t.test(e))))return!1;const a=[/^print\(.+\)$/,/^display\(.+\)$/,/^df\.(head|info|describe)\s*\(.*\)$/,/^display\(df\.(head|info|describe)\s*\(.*\)\)$/,/^df\.(tail|sample)\s*\(.*\)$/,/^display\(df\.(tail|sample)\s*\(.*\)\)$/,/^df\.(shape|columns|dtypes)$/,/^import\s+pandas\s+as\s+pd$/];return t.every(e=>a.some(t=>t.test(e)))},Wn=e=>{const t=e.split("\n"),n=t.find(e=>e.trim().length>0)?.trim()||"";return!!(n.startsWith("%%bash")||n.startsWith("%%sh")||n.startsWith("%%shell"))||t.some(e=>e.trim().startsWith("!"))},Un=e=>{const t=e.split("\n"),n=t.findIndex(e=>e.trim().length>0);if(-1===n)return"";const a=t[n].trim();if(a.startsWith("%%bash")||a.startsWith("%%sh")||a.startsWith("%%shell")){const e=t.slice(n+1).join("\n").trim();return e?`bash -lc $'${e.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\r?\n/g,"\\n")}'`:""}return t.map(e=>e.trim()).filter(e=>e.startsWith("!")).map(e=>e.replace(/^!+/,"").trim()).filter(Boolean).join("\n")},Hn=e=>`python3 -c ${JSON.stringify(e)}`,Jn=e=>!(!an()||Wn(e)&&!(()=>{const e=[...o].reverse().find(e=>pa(e)&&"user"===e.role);return/노트북|셀|cell|notebook|jupyter/i.test(e?.content??"")})()),Vn=(e,t=2)=>{const n=e.split(/\r?\n/).filter(e=>e.length>0);return{text:n.slice(0,t).join("\n"),truncated:n.length>t}},Gn=e=>{const t=jn("command-output"),n={id:t,role:"system",content:`${e}\n`,timestamp:Date.now(),metadata:{kind:"shell-output",command:e}};return l(e=>[...e,n]),t},Xn=(e,t,n)=>{if(!t)return;const a="stderr"===n?"[stderr] ":"";l(n=>n.map(n=>{if(n.id!==e||!("role"in n))return n;const r=n;return{...r,content:`${r.content}${a}${t}`}}))},Zn=async(t,n,a)=>{const r=Wn(t),s=r?Un(t):Hn(t);if(!s)return{success:!1,output:"",error:r?"Shell command is empty":"Python command is empty",returncode:null,command:s,truncated:!1,execution_method:"subprocess"};const o=await(async(t,n,a)=>{try{const r=await e.executeCommandStream(t,{timeout:n,onOutput:a,stdin:void 0}),s="string"==typeof r.stdout?r.stdout:"",o="string"==typeof r.stderr?r.stderr:"",l=[s,o].filter(Boolean).join("\n"),c=Vn(l,2),i=c.truncated||Boolean(r.truncated),d=c.text||"(no output)";return r.success?{success:!0,output:d,returncode:r.returncode??null,command:t,truncated:i}:{success:!1,output:d,error:c.text||r.error||o||"Command failed",returncode:r.returncode??null,command:t,truncated:i}}catch(e){const n=e instanceof Error?e.message:"Command execution failed";a&&a({stream:"stderr",text:`${n}\n`});const r=Vn(n,2);return{success:!1,output:"",error:r.text||"Command execution failed",returncode:null,command:t,truncated:r.truncated}}})(s,n,a);return{...o,execution_method:"subprocess"}},Kn=(e,t)=>{const n=Zt.current||jn("interrupt");Zt.current=n,Kt.current.set(n,{args:e.args});const a={id:n,role:"system",content:e.description||"코드 실행 승인이 필요합니다.",timestamp:Date.now(),metadata:{interrupt:{...e,resolved:t||!1,decision:t?"approve":void 0,autoApproved:t||!1}}};l(e=>e.some(e=>e.id===n)?e.map(e=>e.id===n?a:e):[...e,a]),t||Qn(n,e)},Qn=async(t,n)=>{const a="string"==typeof n.args?.path?n.args.path:"";if(!a||!["write_file_tool","edit_file_tool","multiedit_file_tool"].includes(n.action))return;let r=null;try{const t=await e.readFile(a);t.success&&"string"==typeof t.content&&(r=t.content)}catch{}const s=function(e,t,n){if("write_file_tool"===e){if("string"!=typeof t?.content)return null;const e=t.append&&null!==n?n+t.content:t.content;return e===n?null:e}const a="edit_file_tool"===e?[t||{}]:"multiedit_file_tool"===e&&t?.edits||[];if(null===n||0===a.length)return null;let r=n;for(const e of a){const t=e.old_string??"",n=e.new_string??"";if(!t||!r.includes(t))return null;if(!e.replace_all&&r.split(t).length>2)return null;r=e.replace_all?r.split(t).join(n):r.replace(t,()=>n)}return r}(n.action,n.args,r);if(null===s)return;const o=Kt.current.get(t);o&&o.args===n.args&&(o.change={path:a,before:r??"",after:s}),l(e=>e.map(e=>{if(e.id!==t||!("role"in e))return e;const o=e,l=o.metadata?.interrupt;return l&&l.args===n.args?{...o,metadata:{...o.metadata,interrupt:{...l,preview:{path:a,before:r??"",after:s}}}}:e}))},Yn=e=>{if(!Zt.current)return;const t=Zt.current;Zt.current=null;const n=Kt.current.get(t)?.change;Kt.current.delete(t),"approve"===e&&n&&je(e=>Oe(e,n)),l(n=>n.map(n=>{if(n.id===t&&"role"in n){const t=n;return{...t,metadata:{...t.metadata,interrupt:{...t.metadata?.interrupt||{},resolved:!0,decision:e||"approve"}}}}return n}))},ea=e=>{const t=e.trim();return t.startsWith("/")||t.startsWith("\\")||/^[A-Za-z]:/.test(t)?{valid:!1,error:"Absolute paths are not allowed"}:t.includes("..")?{valid:!1,error:"Path traversal (..) is not allowed"}:{valid:!0}},ta=e=>{const t=e.trim();return t&&"."!==t&&"./"!==t?t.replace(/^\.\/+/,"").replace(/^\/+/,"").replace(/\/+$/,""):""},na=async(e,t)=>{try{const{PageConfig:a,URLExt:r}=await Promise.resolve().then(()=>n.t(7292,23)),s=a.getBaseUrl(),o=ta(e),l=r.join(s,"api/contents",o),c=new URLSearchParams;void 0!==t?.content&&c.set("content",t.content?"1":"0"),t?.format&&c.set("format",t.format);const i=c.toString()?`${l}?${c.toString()}`:l,d=await fetch(i,{method:"GET",credentials:"include"});return d.ok?{success:!0,data:await d.json()}:{success:!1,error:`Failed to load contents: ${d.status}`}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Failed to load contents"}}},aa=async t=>{const{threadId:n,action:a,args:r}=t,s=t.actionCount||1;console.log("[AgentPanel] Auto-approving tool:",a,"actionCount:",s,r);const o=setTimeout(()=>{console.error("[AgentPanel] handleAutoToolInterrupt safety timeout - 강제 해제"),h(!1),f(!1),v(null),Qt.current=!1,pt("오류: 응답 시간 초과 (Agent 응답 없음)")},33e4);try{let t;if("search_notebook_cells_tool"===a)pt({status:`노트북 검색 실행 중: ${r?.pattern||""}`,icon:"search"}),t=await e.searchNotebookCells({pattern:r?.pattern||"",notebook_path:r?.notebook_path,cell_type:r?.cell_type,max_results:r?.max_results||30,case_sensitive:r?.case_sensitive||!1}),console.log("[AgentPanel] search_notebook_cells result:",t);else if("check_resource_tool"===a){const n=r?.files||[];pt({status:`리소스 체크 중: ${n.join(", ")||"system"}`,icon:"check"}),t=await e.checkResource({files:n,dataframes:r?.dataframes||[],file_size_command:r?.file_size_command||"",dataframe_check_code:r?.dataframe_check_code||""}),console.log("[AgentPanel] check_resource result:",t)}else if("read_file_tool"===a){pt({status:"파일 읽는 중...",icon:"read"});const e={path:"string"==typeof r?.path?r.path:"",encoding:"string"==typeof r?.encoding?r.encoding:void 0,offset:"number"==typeof r?.offset?r.offset:0,limit:"number"==typeof r?.limit?r.limit:r?.max_lines??r?.maxLines??500};t=await(async e=>{if(!e.path)return{success:!1,error:"Path is required"};const t=ea(e.path);if(!t.valid)return{success:!1,error:t.error};const n="number"==typeof e.offset?Math.max(0,e.offset):0,a="number"==typeof e.limit?e.limit:"number"==typeof e.maxLines?e.maxLines:500,r=Math.max(0,a),s=await na(e.path,{content:!0,format:"text"});if(!s.success)return{success:!1,error:s.error};const o=s.data;if(!o)return{success:!1,error:"File not found"};if("directory"===o.type)return{success:!1,error:`Path is a directory: ${e.path}`};let l=o.content??"";if("base64"===o.format)return{success:!1,error:"Binary file content is not supported"};"string"!=typeof l&&(l=JSON.stringify(l,null,2));const c=l.split("\n"),i=c.length,d=c.slice(n,n+r);return{success:!0,output:d.join("\n"),metadata:{lineCount:d.length,totalLines:i,offset:n,limit:r,truncated:i>n+r}}})(e)}else if("list_workspace_tool"===a){const e=r?.pattern&&"*"!==r.pattern?` 패턴: ${r.pattern}`:"";pt({status:`파일 목록 조회${e}`,icon:"tool"});const n={path:"string"==typeof r?.path?r.path:".",pattern:"string"==typeof r?.pattern?r.pattern:"*",recursive:!0===r?.recursive};t=await(async e=>{const t=ea(e.path);if(!t.valid)return{success:!1,error:t.error};const n=new Set(["node_modules",".git","__pycache__",".venv","venv",".tox",".pytest_cache",".mypy_cache",".ruff_cache","dist","build",".next",".nuxt","coverage",".coverage",".ipynb_checkpoints"]),a=(e.pattern||"*").trim()||"*",r=e.recursive??!1,s=(e=>{const t=`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".")}$`;return new RegExp(t)})(a),o=[],l=[ta(e.path)],c=new Set;for(;l.length>0&&o.length<500;){const e=l.shift()??"";if(c.has(e))continue;c.add(e);const t=await na(e,{content:!0});if(!t.success){if(""===e||"."===e)return{success:!1,error:t.error};continue}const a=t.data;if(!a||"directory"!==a.type||!Array.isArray(a.content))return{success:!1,error:`Not a directory: ${e||"."}`};for(const e of a.content){if(!e)continue;const t=e.name||e.path?.split("/").pop()||"",a=e.path||t,c="directory"===e.type;if((!c||!n.has(t))&&(s.test(t)&&o.push({path:a,isDir:c,size:c?0:e.size??0}),r&&c&&a&&l.push(a),o.length>=500))break}}return{success:!0,output:o.map(e=>{const t=e.isDir?"[DIR]":"[FILE]",n=e.isDir?"":` (${e.size} bytes)`;return`${t} ${e.path}${e.isDir?"/":n}`}).join("\n")||"(empty directory)",metadata:{count:o.length,files:o}}})(n)}else{if("search_files_tool"!==a)return void console.warn("[AgentPanel] Unknown auto tool:",a);pt({status:`파일 검색 중: ${r?.pattern||""}`,icon:"search"});try{const n=V||C()||{workspaceRoot:"",autoApprove:!1},a=await e.searchWorkspace({pattern:r?.pattern||"",file_types:r?.file_pattern?[r.file_pattern]:["*"],path:r?.path||".",max_results:r?.max_results||30,case_sensitive:r?.case_sensitive||!1,workspaceRoot:n.workspaceRoot});t=a.success&&a.results?{success:!0,output:a.results.map(e=>`${e.file_path}:${e.line_number}: ${e.content}`).join("\n")||"(no matches found)",metadata:{count:a.total_results}}:{success:!1,error:a.error||"Search failed"}}catch(e){t={success:!1,error:e.message||"Search failed"}}console.log("[AgentPanel] search_files result:",t)}const o={...r,execution_result:t};bt(null);const c=jn("assistant");v(c),l(e=>[...e,{id:c,role:"assistant",content:"",timestamp:Date.now()}]);let i="",d=!1;pt({status:"LLM 응답 대기 중",icon:"thinking"}),rt.current=[],await e.resumeAgent(n,"edit",o,void 0,vn(),e=>{i+=e,l(e=>e.map(e=>e.id===c&&pa(e)?{...e,content:i}:e))},e=>{"codex"===K?ht(c,e):pt(e)},e=>{d=!0,Qt.current=!0;const t=bn(V||C()||{workspaceRoot:"",autoApprove:!1});if("search_notebook_cells_tool"!==e.action&&"check_resource_tool"!==e.action&&"read_file_tool"!==e.action&&"list_workspace_tool"!==e.action&&"search_files_tool"!==e.action){if("jupyter_cell_tool"===e.action&&"READ"===e.args?.operation)return console.log("[AgentPanel] Auto-approving jupyter_cell READ operation (handleAutoToolInterrupt chain)"),void ra(e,"approve").catch(e=>{console.error("[AgentPanel] jupyter_cell READ auto-approve FAILED:",e)});if("ask_user_tool"===e.action){console.log("[AgentPanel] ask_user_tool interrupt (resume):",e.args),Wt(!0),Gt(e),h(!1),f(!1);const t=e.args?.question||"응답을 입력하세요...",n=e.args?.options,a=e.args?.input_type||"text";let r=`❓ **${t}**`;n&&n.length>0&&(r+="\n\n선택지:\n"+n.map((e,t)=>`${t+1}. ${e}`).join("\n")),"file"===a&&(r+="\n\n_(파일을 업로드하거나 파일 경로를 입력하세요)_");const s={id:jn("ask_user"),role:"assistant",content:r,timestamp:Date.now()};return l(e=>[...e,s]),void setTimeout(()=>{const e=document.querySelector(".jp-agent-input");e&&(e.focus(),e.placeholder=t)},100)}if(t||e.autoApprove)Kn(e,!0),"jupyter_cell_tool"===e.action&&e.args?.code&&Jn(e.args.code)&&yn(e.args.code),ra(e,"approve").catch(e=>{console.error("[AgentPanel] nested resumeFromInterrupt FAILED:",e)});else{if("jupyter_cell_tool"===e.action&&e.args?.code){const t=Jn(e.args.code);if(Bn(e.args.code))return t&&yn(e.args.code),void ra(e,"approve").catch(e=>{console.error("[AgentPanel] nested resumeFromInterrupt FAILED:",e)});t&&yn(e.args.code)}bt(e),Kn(e),h(!1),f(!1)}}else aa(e)},e=>{Et(e)},()=>{pt(null)},En,s,$t.current?.signal),d||(h(!1),f(!1),v(null),Qt.current=!1)}catch(e){const t=e instanceof Error?e.message:"Tool execution failed";console.error("[AgentPanel] Auto tool error:",e),pt(`오류: ${t}`),h(!1),f(!1),Qt.current=!1}finally{clearTimeout(o)}},ra=async(t,n,a)=>{const{threadId:r}=t,s=t.actionCount||1;console.log("[AgentPanel] resumeFromInterrupt START: action=",t.action,"decision=",n,"threadId=",r),bt(null),pt(null),Yn(n);let o,c=n;if("approve"===n)if("codex"===K&&"jupyter_cell_tool"!==t.action);else if("write_file_tool"===t.action)try{pt({status:"파일 쓰기 중...",icon:"write"});const n=await e.writeFile(t.args?.path||"",t.args?.content||"",{encoding:t.args?.encoding||"utf-8",overwrite:t.args?.overwrite||!1});console.log("[AgentPanel] write_file result:",n),c="edit",o={...t.args,execution_result:n}}catch(e){const n=e instanceof Error?e.message:"File write failed";console.error("[AgentPanel] write_file error:",e),c="edit",o={...t.args,execution_result:{success:!1,error:n}}}else if("edit_file_tool"===t.action)try{pt({status:"파일 수정 중...",icon:"edit"});const n=t.args?.path||"",a=t.args?.old_string||"",r=t.args?.new_string||"",s=t.args?.replace_all||!1,l=await e.readFile(n);if(!l.success||void 0===l.content)throw new Error(l.error||"Failed to read file");const i=l.content,d=(i.match(new RegExp(a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"))||[]).length;if(0===d)throw new Error(`String not found in file: '${a.slice(0,100)}...'`);if(d>1&&!s)throw new Error(`String appears ${d} times. Use replace_all=True or provide more context.`);const u=s?i.split(a).join(r):i.replace(a,r),m=[],p=i.split("\n"),h=u.split("\n");m.push(`--- ${n} (before)`),m.push(`+++ ${n} (after)`);let g=0,f=0;for(;g<p.length||f<h.length;)g<p.length&&f<h.length&&p[g]===h[f]?(g++,f++):g<p.length&&(f>=h.length||p[g]!==h[f])?(m.push(`-${p[g]}`),g++):(m.push(`+${h[f]}`),f++);const b=m.join("\n"),v=await e.writeFile(n,u,{encoding:"utf-8",overwrite:!0});console.log("[AgentPanel] edit_file result:",v),c="edit",o={...t.args,execution_result:{...v,diff:b,occurrences:d,lines_added:h.length-p.length>0?h.length-p.length:0,lines_removed:p.length-h.length>0?p.length-h.length:0}}}catch(e){const n=e instanceof Error?e.message:"File edit failed";console.error("[AgentPanel] edit_file error:",e),c="edit",o={...t.args,execution_result:{success:!1,error:n}}}else if("multiedit_file_tool"===t.action)try{pt({status:"다중 파일 수정 중...",icon:"edit"});const n=t.args?.path||"",a=t.args?.edits||[];if(!n||0===a.length)throw new Error("File path and edits are required");const r=await e.readFile(n);if(!r.success||void 0===r.content)throw new Error(r.error||"Failed to read file");const s=r.content;let l=s,i=0,d=0;const u=[];for(let e=0;e<a.length;e++){const t=a[e],n=t.old_string||"",r=t.new_string||"",s=t.replace_all||!1,o=(l.match(new RegExp(n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"))||[]).length;0!==o?o>1&&!s?(u.push(`Edit ${e+1}: String appears ${o} times (use replace_all)`),d++):(l=s?l.split(n).join(r):l.replace(n,r),i++):(u.push(`Edit ${e+1}: String not found`),d++)}const m=[],p=s.split("\n"),h=l.split("\n");m.push(`--- ${n} (before)`),m.push(`+++ ${n} (after)`);let g=0,f=0;for(;g<p.length||f<h.length;)g<p.length&&f<h.length&&p[g]===h[f]?(g++,f++):g<p.length&&(f>=h.length||p[g]!==h[f])?(m.push(`-${p[g]}`),g++):(m.push(`+${h[f]}`),f++);const b=m.join("\n");if(!(i>0))throw new Error(`All ${a.length} edits failed: ${u.join("; ")}`);{const a=await e.writeFile(n,l,{encoding:"utf-8",overwrite:!0});console.log("[AgentPanel] multiedit_file result:",a,"applied:",i,"failed:",d),c="edit",o={...t.args,execution_result:{...a,diff:b,edits_applied:i,edits_failed:d,failed_details:u,lines_added:h.length-p.length>0?h.length-p.length:0,lines_removed:p.length-h.length>0?p.length-h.length:0}}}}catch(e){const n=e instanceof Error?e.message:"Multi-edit failed";console.error("[AgentPanel] multiedit_file error:",e),c="edit",o={...t.args,execution_result:{success:!1,error:n,edits_applied:0,edits_failed:0}}}else if("diagnostics_tool"===t.action)try{pt({status:"LSP 진단 조회 중...",icon:"diagnostics"});const e=t.args?.path||null,n=t.args?.severity_filter||null,a=window._codebuffLSPBridge;if(a&&a.isLSPAvailable()){let r=(await a.getDiagnostics(e)).diagnostics;n&&(r=r.filter(e=>e.severity===n)),c="approve",o={...t.args,execution_result:{success:!0,lsp_available:!0,diagnostics:r}}}else console.log("[AgentPanel] LSP not available, returning empty diagnostics"),c="approve",o={...t.args,execution_result:{success:!0,lsp_available:!1,diagnostics:[]}}}catch(e){const n=e instanceof Error?e.message:"Diagnostics failed";console.error("[AgentPanel] diagnostics_tool error:",e),c="approve",o={...t.args,execution_result:{success:!1,lsp_available:!1,error:n,diagnostics:[]}}}else if("references_tool"===t.action)try{pt({status:"참조 검색 중...",icon:"search"});const e=t.args?.symbol||"",n=t.args?.path||null,a=window._codebuffLSPBridge;if(a&&a.isLSPAvailable()){const r=await a.getReferences(e,n,t.args?.line,t.args?.character);c="approve",o={...t.args,execution_result:{success:r.success,lsp_available:!0,locations:r.locations,used_grep:!1}}}else console.log("[AgentPanel] LSP not available for references, suggesting grep fallback"),c="approve",o={...t.args,execution_result:{success:!1,lsp_available:!1,locations:[],used_grep:!1}}}catch(e){const n=e instanceof Error?e.message:"References search failed";console.error("[AgentPanel] references_tool error:",e),c="approve",o={...t.args,execution_result:{success:!1,lsp_available:!1,error:n,locations:[]}}}else if("jupyter_cell_tool"===t.action&&t.args?.code){const e=t.args.code;console.log("[AgentPanel] jupyter_cell_tool: shouldExecuteInNotebook=",Jn(e));try{if(Jn(e)){const n=await fn();if(console.log("[AgentPanel] executePendingApproval result:",n?`tool=${n.tool}`:"null"),n&&"jupyter_cell"===n.tool){const e=n.execution_result;console.log("[AgentPanel] jupyter_cell exec result: success=",e?.success,"error=",e?.error?.slice?.(0,100)),c="edit",o={code:n.code,execution_result:e}}else{const n=an();if(console.log("[AgentPanel] fallback: notebook=",!!n),n){const a=cn(n,"code",e);if(null===a){pt({status:"노트북 모델이 없어 서브프로세스로 실행 중...",icon:"terminal"});const n=Wn(e)?Un(e):Hn(e),a=n?Gn(n):null,r=await Zn(e,t.args?.timeout,a?e=>Xn(a,e.text,e.stream):void 0);c="edit",o={code:e,execution_result:r}}else{await pn(n,a);const t=gn(n,a);c="edit",o={code:e,execution_result:t}}}else{pt({status:"노트북이 없어 서브프로세스로 실행 중...",icon:"terminal"});const n=Wn(e)?Un(e):Hn(e),a=n?Gn(n):null,r=await Zn(e,t.args?.timeout,a?e=>Xn(a,e.text,e.stream):void 0);c="edit",o={code:e,execution_result:r}}}}else{pt({status:"서브프로세스로 코드 실행 중...",icon:"terminal"});const n=Wn(e)?Un(e):Hn(e),a=n?Gn(n):null,r=await Zn(e,t.args?.timeout,a?e=>Xn(a,e.text,e.stream):void 0);console.log("[AgentPanel] jupyter_cell subprocess result:",JSON.stringify(r).slice(0,200)),c="edit",o={code:e,execution_result:r}}}catch(t){const n=t instanceof Error?t.message:String(t);console.error("[AgentPanel] jupyter_cell_tool execution error (will still resume):",t),c="edit",o={code:e,execution_result:{success:!1,error:n,error_type:"FrontendExecutionError"}}}}else if("ask_user_tool"===t.action)console.log("[AgentPanel] ask_user_tool approve with user response:",a),c="edit",o={...t.args,user_response:a||""};else{const e=await fn();e&&"jupyter_cell"===e.tool?(c="edit",o={code:e.code,execution_result:e.execution_result}):e&&"markdown"===e.tool&&(c="edit",o={content:e.content})}else{const e=en.current[0];if(e&&void 0!==e.cellIndex){const t=an();t&&((e,t)=>{const n=e.content?.model,a=n?.cells?.length??n?.sharedModel?.cells?.length;n?.sharedModel&&void 0!==a?t<0||t>=a?console.warn("[AgentPanel] Invalid cell index for delete:",t):(n.sharedModel.deleteCell(t),console.log("[AgentPanel] Deleted rejected cell at index:",t)):console.warn("[AgentPanel] Notebook model not ready for delete")})(t,e.cellIndex)}en.current.shift(),Qt.current=en.current.length>0}h(!0),f(!0);let i=!1;const d=jn("assistant");v(d),l(e=>[...e,{id:d,role:"assistant",content:"",timestamp:Date.now()}]);let u="";const m="reject"===c?a?`사용자 피드백: ${a}`:"User rejected this action":void 0;console.log("[AgentPanel] CALLING resumeAgent: decision=",c,"args_keys=",o?Object.keys(o):"none","exec_result_success=",o?.execution_result?.success);try{rt.current=[],await e.resumeAgent(r,c,o,m,vn(),e=>{u+=e,l(e=>e.map(e=>e.id===d&&pa(e)?{...e,content:u}:e))},e=>{"codex"===K?ht(d,e):pt(e)},e=>{i=!0,Qt.current=!0;const t=bn(V||C()||{workspaceRoot:"",autoApprove:!1});if("search_notebook_cells_tool"!==e.action&&"check_resource_tool"!==e.action&&"read_file_tool"!==e.action&&"list_workspace_tool"!==e.action&&"search_files_tool"!==e.action){if("jupyter_cell_tool"===e.action&&"READ"===e.args?.operation)return console.log("[AgentPanel] Auto-approving jupyter_cell READ operation (resume)"),void ra(e,"approve").catch(e=>{console.error("[AgentPanel] jupyter_cell READ auto-approve FAILED (resume):",e)});if("ask_user_tool"===e.action){console.log("[AgentPanel] ask_user_tool interrupt (resume callback):",e.args),Wt(!0),Gt(e),h(!1),f(!1);const t=e.args?.question||"응답을 입력하세요...",n=e.args?.options,a=e.args?.input_type||"text";let r=`❓ **${t}**`;n&&n.length>0&&(r+="\n\n선택지:\n"+n.map((e,t)=>`${t+1}. ${e}`).join("\n")),"file"===a&&(r+="\n\n_(파일을 업로드하거나 파일 경로를 입력하세요)_");const s={id:jn("ask_user"),role:"assistant",content:r,timestamp:Date.now()};return l(e=>[...e,s]),void setTimeout(()=>{const e=document.querySelector(".jp-agent-input");e&&(e.focus(),e.placeholder=t)},100)}if(t||e.autoApprove)Kn(e,!0),"jupyter_cell_tool"===e.action&&e.args?.code&&Jn(e.args.code)&&yn(e.args.code),ra(e,"approve").catch(e=>{console.error("[AgentPanel] nested resumeFromInterrupt FAILED:",e)});else{if("jupyter_cell_tool"===e.action&&e.args?.code){const t=Jn(e.args.code);if(Bn(e.args.code))return t&&yn(e.args.code),void ra(e,"approve").catch(e=>{console.error("[AgentPanel] nested resumeFromInterrupt FAILED:",e)});t&&yn(e.args.code)}bt(e),Kn(e),h(!1),f(!1)}}else aa(e)},e=>{Et(e)},()=>{pt(null)},En,s,$t.current?.signal)}catch(e){const t=e instanceof Error?e.message:"Failed to resume";pt(`오류: ${t}`),console.error("Resume failed:",e),l(e=>[...e,{id:jn(),role:"assistant",content:`Error: ${t}`,timestamp:Date.now()}])}finally{i||(h(!1),f(!1),v(null),Qt.current=!1)}},sa=async(e,t,n,a,r)=>{const s={id:jn("review-intro"),role:"assistant",content:"코드리뷰를 시작합니다. 아래 **4가지 관점**으로 분석합니다.\n\n| 순서 | 섹션 | 설명 |\n|:---:|------|------|\n| 1 | **보안** | 코드 내 취약점 점검 |\n| 2 | **성능개선** | 코드 성능 최적화 |\n| 3 | **코드품질** | 코드 구조, 일관성, 에러 처리, 네이밍 점검 |\n| 4 | **요약** | 1~3을 셀단위로 요약 |\n",timestamp:Date.now()};l(e=>[...e,s]);const o=[];for(let s=0;s<e.length;s++){const c=e[s],i=c.perspectiveIndices.map(e=>t[e].prompt).join("\n\n"),d=c.perspectiveIndices.map(e=>t[e].label).join(", "),u=s===e.length-1;let m;if(u&&o.length>0){const t=6e3;m="## 이전 분석 결과\n아래는 이전 호출에서 수행된 보안·성능·코드 품질 분석 결과입니다. 이 결과에서 수정이 제안된 모든 셀에 대해 개선 코드를 제시하세요.\n\n"+o.map(e=>{if(e.length<=t)return e;const n=e.slice(0,t),a=n.lastIndexOf("\n");return(a>0?n.slice(0,a):n)+"\n\n… (이하 생략)"}).join("\n\n---\n\n")+"\n\n## 코드리뷰 요청 사항\n"+`이 요청은 ${e.length}개 호출 중 ${s+1}번째입니다. "${d}" 섹션만 작성하세요.\n다른 섹션(이전 호출에서 이미 분석됨)은 절대 포함하지 마세요.\n\n`+i+"\n"+n}else m=a+"\n## 코드리뷰 요청 사항\n"+`이 요청은 ${e.length}개 호출 중 ${s+1}번째입니다. "${d}" 섹션만 작성하세요.\n다른 섹션(이전 호출에서 이미 분석됨)은 절대 포함하지 마세요.\n\n`+i+"\n"+n;const p=`${c.displayLabel} [${s+1}/${e.length}]`;for(let e=0;e<2;e++)try{const e=await r({displayContent:p,llmPrompt:m,clearInput:!1,maxTokens:rn,freshConversation:!0});e&&!u&&o.push(e);break}catch(t){if(0===e)console.warn(`[AgentPanel] Review call ${s+1} failed, retrying in 2s...`,t),await new Promise(e=>setTimeout(e,2e3));else{console.error(`[AgentPanel] Review call ${s+1} failed after retry:`,t);const e={id:jn(`review-error-${s}`),role:"assistant",content:`⚠️ **${c.displayLabel}** 분석 중 오류가 발생했습니다. (${t instanceof Error?t.message:"network error"})\n\n다른 섹션은 계속 진행합니다.`,timestamp:Date.now()};l(t=>[...t,e])}}}const c={id:jn("review-done"),role:"assistant",content:"✅ **코드리뷰가 완료되었습니다.**",timestamp:Date.now()};l(e=>[...e,c])},oa=async()=>{if(Tt&&It){const e=u.trim()||void 0;if(e){const t={id:jn(),role:"user",content:e,timestamp:Date.now()};l(e=>[...e,t])}m(""),At(!1);const t=It;return qt(null),void await ra(t,"reject",e)}if(Bt&&Vt){const e=u.trim();if(!e)return;const t={id:jn(),role:"user",content:e,timestamp:Date.now()};l(e=>[...e,t]),m(""),Wt(!1);const n=Vt;return Gt(null),setTimeout(()=>{const e=document.querySelector(".jp-agent-input");e&&(e.placeholder="메세지를 입력하세요.")},100),void await ra(n,"approve",e)}const a=wn.current?.parentElement?.querySelector(".jp-agent-input"),r=xn.current||a?.getAttribute("data-llm-prompt");if(!u.trim()&&!r||p||g||X)return;const s=u.trim();if("codex"===K&&(e=>Mt.has(Rt(e)))(s))return Ze.c.getInstance().trackClick(`cmd_codex_${Rt(s).slice(1)}`,{input_mode:K}),xe(null),"/new"===Rt(s)?(m(""),void await ca()):void await In({displayContent:s,clearInput:!0});if("/discovery"===s||s.startsWith("/discovery ")){Ze.c.getInstance().trackClick("cmd_discovery",{input_mode:K}),m(""),l(e=>[...e,{id:jn(),role:"user",content:s,timestamp:Date.now()}]);const e=s.match(/^\/discovery\s+(\S+)\s+(\d+)\s*$/);return void(e?await da({name:e[1],port:parseInt(e[2],10)}):"/discovery"===s?await da():l(e=>[...e,{id:`discovery-${Date.now()}`,role:"assistant",content:"사용법: `/discovery` (등록된 전체 갱신) 또는 `/discovery <이름> <포트>` (예: `/discovery orbit 18080`)",timestamp:Date.now()}]))}if("/disconnect"===s||s.startsWith("/disconnect ")){Ze.c.getInstance().trackClick("cmd_disconnect",{input_mode:K}),m(""),l(e=>[...e,{id:jn(),role:"user",content:s,timestamp:Date.now()}]);const e=s.match(/^\/disconnect\s+(\S+)\s*$/);return void(e?await ua(e[1]):l(e=>[...e,{id:`disconnect-${Date.now()}`,role:"assistant",content:"사용법: `/disconnect <이름>` (예: `/disconnect orbit`)",timestamp:Date.now()}]))}if("/diff"===s){let t;Ze.c.getInstance().trackClick("cmd_diff",{input_mode:K}),m(""),l(e=>[...e,{id:jn(),role:"user",content:s,timestamp:Date.now()}]);try{const n=V||C()||{workspaceRoot:"",autoApprove:!1};t=(await e.gitDiff(n.workspaceRoot)).markdown}catch(e){t=`git 변경을 읽지 못했습니다: ${e instanceof Error?e.message:String(e)}`}return void l(e=>[...e,{id:jn(),role:"assistant",content:t,timestamp:Date.now()}])}if("/mcp_test"===s||s.startsWith("/mcp_test ")){Ze.c.getInstance().trackClick("cmd_mcp_test",{input_mode:K}),m(""),l(e=>[...e,{id:jn(),role:"user",content:s,timestamp:Date.now()}]);const e=s.match(/^\/mcp_test(?:\s+(stdio|streamable-http|both))?(?:\s+(\d{1,5}))?(?:\s+(?:--)?(call))?\s*$/);return void(e?await ma(e[1],e[2]?parseInt(e[2],10):void 0,!!e[3]):l(e=>[...e,{id:`mcp_test-${Date.now()}`,role:"assistant",content:"사용법: `/mcp_test` (둘 다), `/mcp_test stdio`, `/mcp_test streamable-http`, `/mcp_test streamable-http 18099` (포트 지정), `/mcp_test call` (도구를 실제로 호출 — AWS 자격 필요)",timestamp:Date.now()}]))}if(s.startsWith("/review")){Ze.c.getInstance().trackClick("cmd_review",{input_mode:K,has_file_arg:null!==Xt(s)});const t=Xt(s.replace(/^\/review\s*/,"").trim());if(t){const n=t.path,a=await e.readFile(n,{cwd:".",workspaceRoot:(V||C()||{workspaceRoot:"",autoApprove:!1}).workspaceRoot});if(!a.success||!a.content){const e={id:jn(),role:"assistant",content:`파일을 읽을 수 없습니다: ${a.error||n}`,timestamp:Date.now()};return l(t=>[...t,e]),void m("")}let r="";if(n.endsWith(".py"))try{const e=window.jupyterapp,t=e?.serviceManager?.serverSettings,a=t?.baseUrl||"/",s=await fetch(`${a}codebuff/file/enrich`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filePath:n})});if(s.ok){const e=await s.json(),t={...e.moduleSources||{},...e.transitiveModuleSources||{}},n=e.moduleSummary||{};for(const[e,a]of Object.entries(t)){const t=n[e]||{};r+=`\n### 로컬 모듈 \`${e}\` (${2===t.depth?`간접 import (imported by \`${t.importedBy}\`)`:"직접 import"})\n\`\`\`python\n${a}\n\`\`\`\n`}}}catch(e){console.warn("[Review] File enrich failed:",e)}const o=`다음은 코드리뷰 대상 파일입니다.\n\n## 파일 정보\n- 파일 경로: ${n}\n\n## 파일 내용\n\n\`\`\`python\n${a.content}\n\`\`\`\n${r}`,i=a.content.split("\n").length,d=await Yt(c.PageConfig.getBaseUrl()),{callPlan:u,perspectives:p,commonRules:h}=nn(o,i,d),g={id:jn(),role:"user",content:s,timestamp:Date.now()};return l(e=>[...e,g]),m(""),void await sa(u,p,h,o,In)}const a=window.jupyterapp,r=a?.shell?.currentWidget,o=r&&"context"in r&&r.context?.path||null;if(!o){const e={id:jn(),role:"assistant",content:"사용법:\n- `/review` — 현재 활성 탭 코드리뷰 (노트북 또는 파일)\n- `/review @경로` — 특정 파일 코드리뷰\n\n예시:\n- `/review`\n- `/review @utils.py`\n- `/review @src/analysis.py`",timestamp:Date.now()};return l(t=>[...t,e]),void m("")}if(o.endsWith(".ipynb")){const e=an();if(!e)return void m("");const t=a?.serviceManager?.serverSettings,{collectAllCodeCells:r}=await Promise.resolve().then(()=>n(6379)),i=await r(e,t,o);if(0===i.length){const e={id:jn(),role:"assistant",content:"노트북에 코드 셀이 없습니다.",timestamp:Date.now()};return l(t=>[...t,e]),void m("")}const d=(e=>{const t=e.length,n=e.filter(e=>e.output&&(e.output.includes("Error")||e.output.includes("Traceback")||e.output.includes("Exception"))).length,a=e.filter(e=>e.imports&&e.imports.length>0).length,r=e.reduce((e,t)=>t.imports?e+t.imports.filter(e=>e.isLocal).length:e,0),s=e._moduleSummary||{},o=e._crossCellDeps||[],l=e._transitiveModuleSources||{},c=Object.values(s).filter(e=>1===e.depth||!e.depth).length,i=Object.values(s).filter(e=>2===e.depth).length,d=new Set;let u=`다음은 저장하기 전의 Jupyter 노트북 전체 내용입니다.\n\n## 노트북 요약\n- 전체 셀 수: ${t}개\n- 에러가 있는 셀: ${n}개\n- Import가 있는 셀: ${a}개\n- 로컬 모듈 import: ${r}개 (직접: ${c}개, 간접: ${i}개)\n- 셀 간 의존 관계: ${o.length}개\n\n## 전체 셀 내용\n\n`;e.forEach((e,t)=>{var n;if(u+=`### 셀 ${t+1} (ID: ${e.id})\n\`\`\`python\n${e.content}\n\`\`\`\n`,e.output&&(u+=`\n**실행 결과:**\n\`\`\`\n${n=e.output,n.replace(/Out\[\d+\]/g,"Out[...]").replace(/In\[\d+\]/g,"In[...]").replace(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?/g,"[TIMESTAMP]").replace(/[ \t]+$/gm,"")}\n\`\`\`\n`),e.imports&&e.imports.length>0&&(u+="\n**Imports:**\n",e.imports.forEach(e=>{u+=`- \`${e.module}\` (${e.isLocal?"로컬":"표준 라이브러리"})\n`})),e.localModuleSources&&Object.keys(e.localModuleSources).length>0)for(const[t,n]of Object.entries(e.localModuleSources))d.has(t)||(u+=`\n**로컬 모듈 \`${t}\` 소스:**\n\`\`\`python\n${n}\n\`\`\`\n`,d.add(t));u+="\n---\n\n"});const m=Object.entries(l);if(m.length>0){u+="## 간접 Import 모듈 소스 (2단계)\n\n";for(const[e,t]of m)if(!d.has(e)){const n=s[e],a=n?.importedBy?` (imported by \`${n.importedBy}\`)`:"";u+=`### 모듈 \`${e}\`${a}\n\`\`\`python\n${t}\n\`\`\`\n\n`,d.add(e)}}return u})(i),u=await Yt(c.PageConfig.getBaseUrl()),{callPlan:p,perspectives:h,commonRules:g}=nn(d,i.length,u),f={id:jn(),role:"user",content:s,timestamp:Date.now()};l(e=>[...e,f]),m(""),await sa(p,h,g,d,In)}else{const t=await e.readFile(o);if(!t.success||!t.content){const e={id:jn(),role:"assistant",content:`파일을 읽을 수 없습니다: ${t.error||o}`,timestamp:Date.now()};return l(t=>[...t,e]),void m("")}const n=o.split(".").pop()||"",r={py:"python",js:"javascript",ts:"typescript",jsx:"jsx",tsx:"tsx",java:"java",sql:"sql",sh:"bash",yaml:"yaml",yml:"yaml",json:"json"}[n]||n;let i="";if("py"===n)try{const e=await fetch(`${a?.serviceManager?.serverSettings?.baseUrl||"/"}codebuff/file/enrich`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filePath:o})});if(e.ok){const t=await e.json(),n={...t.moduleSources||{},...t.transitiveModuleSources||{}},a=t.moduleSummary||{};for(const[e,t]of Object.entries(n)){const n=a[e]||{};i+=`\n### 로컬 모듈 \`${e}\` (${2===n.depth?`간접 import (imported by \`${n.importedBy}\`)`:"직접 import"})\n\`\`\`python\n${t}\n\`\`\`\n`}}}catch(e){console.warn("[Review] File enrich failed:",e)}const d=`다음은 코드리뷰 대상 파일입니다.\n\n## 파일 정보\n- 파일 경로: ${o}\n\n## 파일 내용\n\n\`\`\`${r}\n${t.content}\n\`\`\`\n${i}`,u=t.content.split("\n").length,p=await Yt(c.PageConfig.getBaseUrl()),{callPlan:h,perspectives:g,commonRules:f}=nn(d,u,p),b={id:jn(),role:"user",content:s,timestamp:Date.now()};l(e=>[...e,b]),m(""),await sa(h,g,f,d,In)}return}if(s.startsWith("/unittest")){Ze.c.getInstance().trackClick("cmd_unittest",{input_mode:K,has_file_arg:null!==Xt(s)});const n=s.replace(/^\/unittest\s*/,"").trim(),a=Xt(n);let r,o;if(a)r=a.path,o=a.rest;else{const e=window.jupyterapp;let a=null;const s=e?.shell?.currentWidget;if(s&&"context"in s&&(a=s.context?.path||null),a||(a=t?.currentWidget?.context?.path||null),!a){const e={id:jn(),role:"assistant",content:"테스트할 파일을 지정하거나 파일 탭을 열어주세요.\n\n사용법:\n- `/unittest @utils.py`\n- `/unittest` (활성 탭의 파일 자동 인식)\n- `/unittest @src/main.py edge case 위주로`",timestamp:Date.now()};return l(t=>[...t,e]),void m("")}r=a,o=n}const c={cwd:".",workspaceRoot:(V||C()||{workspaceRoot:"",autoApprove:!1}).workspaceRoot};let i=await e.readFile(r,a?c:void 0);if(!i.success||!i.content){const t=r.split("/").pop()||r;try{const n=await e.getContextAutocomplete({partialCommand:`@${t}`});if(n?.options?.length>0){const a=n.options.find(e=>e.label?.endsWith(`/${t}`)||e.label===`@${t}`)||n.options[0];if(a?.label){const t=Xt(a.label)?.path||"";i=await e.readFile(t,c),i.success&&i.content&&(r=t)}}}catch(e){console.warn("[AgentPanel] File search fallback failed:",e)}}if(!i.success||!i.content){const e={id:jn(),role:"assistant",content:`파일을 읽을 수 없습니다: ${i.error||r}`,timestamp:Date.now()};return l(t=>[...t,e]),void m("")}let d=`[UNITTEST] 다음 파일의 pytest 유닛테스트를 생성하세요. 먼저 unit-testing 스킬을 읽고 그 패턴을 따르세요.\n파일 경로: ${r}\n\n--- 파일 내용 ---\n${i.content}\n--- 파일 끝 ---`;return o&&(d+=`\n추가 지시: ${o}`),void await In({displayContent:s,llmPrompt:d,clearInput:!0})}if(/^\/eda-agent(\s|$)/.test(s)){Ze.c.getInstance().trackClick("cmd_eda_agent",{input_mode:K});const e=s.replace(/^\/eda-agent\s*/,"").trim();if(!e){const e={id:jn(),role:"assistant",content:"사용법: `/eda-agent <프롬프트>`\n\n예시: `/eda-agent 카드매출과 가맹점 테이블을 조인해서 월별 매출 집계해줘`",timestamp:Date.now()};return l(t=>[...t,e]),void m("")}const t={id:jn(),role:"user",content:s,timestamp:Date.now()};l(e=>[...e,t]),m("");try{const t=window.jupyterapp;await t.commands.execute("codebuff:athena-query",{prompt:e})}catch(e){const t={id:jn(),role:"assistant",content:`EDA Agent 실행 실패: ${e.message}`,timestamp:Date.now()};l(e=>[...e,t])}return}if(s.startsWith("/create-notebook")){Ze.c.getInstance().trackClick("cmd_create_notebook",{input_mode:K});const e=s.replace(/^\/create-notebook\s*/,"").trim();if(!e){const e={id:jn(),role:"assistant",content:"사용법: `/create-notebook <프롬프트>`\n\n예시: `/create-notebook 타이타닉 데이터 분석하는 노트북 만들어줘`",timestamp:Date.now()};return l(t=>[...t,e]),void m("")}const t={id:jn(),role:"user",content:s,timestamp:Date.now()};l(e=>[...e,t]),m("");try{const t=window.jupyterapp,n=await t.commands.execute("codebuff:generate-from-prompt",{prompt:e});n?.finished?.then(e=>{"failed"===e.status&&l(t=>[...t,{id:jn(),role:"assistant",content:`노트북 생성 실패: ${e.error}\n\n> ${Dt(e.gatewayReason)}`,timestamp:Date.now()}])});const a={id:jn(),role:"assistant",content:`노트북 자동생성을 시작했습니다.\n\n프롬프트: "${e}"\n\n오른쪽 하단에서 진행 상태를 확인할 수 있습니다.`,timestamp:Date.now()};l(e=>[...e,a])}catch(e){const t={id:jn(),role:"assistant",content:`노트북 생성 실패: ${e.message}\n\n> ${Dt(e.gatewayReason)}`,timestamp:Date.now()};l(e=>[...e,t])}return}if("agent"===K){const e=window.jupyterapp;let n=null;if(e?.shell?.currentWidget){const t=e.shell.currentWidget;"content"in t&&t.content?.model&&(n=t)}n||(n=t?.currentWidget),n||console.log("[AgentPanel] Agent mode: No notebook - using LangChain agent without notebook context")}const o=s||(r?"셀 분석 요청":"");await In({displayContent:o,llmPrompt:r,textarea:a,clearInput:Boolean(s)})},la=async e=>{if(ft){if(Ze.c.getInstance().trackClick("hitl_decision",{decision:e,action:ft.action}),"reject"===e){At(!0),qt(ft),bt(null),Yn("reject");const e=document.querySelector(".jp-agent-input");return void(e&&e.focus())}await ra(ft,e)}},ca=async()=>{try{const t=Nt||E;if(t){const n=await e.resetAgent(t);console.log("[AgentPanel] Reset result:",n)}l([]),je([]),k(""),jt(null),Z(!1),h(!1),f(!1),Et([]),pt(null),bt(null),At(!1),Wt(!1),console.log("[AgentPanel] Session reset complete")}catch(e){console.error("[AgentPanel] Failed to reset session:",e);const t={id:`error-${Date.now()}`,role:"assistant",content:`Failed to reset session: ${e}`,timestamp:Date.now()};l(e=>[...e,t])}},ia=e=>{const t=e.filter(e=>e.alive).map(e=>({name:e.name,port:e.port,owner:e.owner}));localStorage.setItem(R,JSON.stringify(t))},da=async t=>{let n;try{t&&await e.registerAgentProvider(t.name,t.port);const a=await e.getAgentProviders();T(a),ia(a);const r=a.map(e=>`| ${e.display_name||e.name} | \`${e.health_endpoint}\` | \`${e.stream_endpoint}\` | ${e.alive?"✅ 연결됨":"❌ 응답 없음"} |`).join("\n"),s=a.filter(e=>!e.alive).map(e=>`\n- **${e.name}**: 프로세스가 포트 ${e.port}에 떠 있는지 확인하세요. 기동 후 \`/discovery ${e.name} ${e.port}\`로 다시 연결할 수 있습니다.`).join(""),o=t?`**'${t.name}' 등록 결과**`:"**Provider Discovery 결과**",l=a.length?`\n\n| provider | ping(health) | stream | 상태 |\n|---|---|---|---|\n${r}${s}`:"\n\n등록된 provider가 없습니다. `/discovery <이름> <포트>`로 등록하세요. (예: `/discovery orbit 18080`)",c=a.filter(e=>e.alive).map(e=>`**${e.display_name||e.name}**`);n=`${o}${l}${c.length?`\n\n이제 입력창의 모드 선택 박스에서 ${c.join(", ")} 선택이 가능해집니다.`:""}`}catch(e){n=`**Provider ${t?"등록":"discovery"} 실패** — ${e instanceof Error?e.message:String(e)}`}const a={id:`discovery-${Date.now()}`,role:"assistant",content:n,timestamp:Date.now()};l(e=>[...e,a])},ua=async t=>{let n;try{const a=await e.unregisterAgentProvider(t);sn(K)===t&&Q("simple"),delete N.current[t];const r=await e.getAgentProviders();T(r),ia(r),n=a?`**'${t}' 연결 해제됨.** 모드 선택박스에서 제거되었습니다.`:`'${t}'은(는) 등록되어 있지 않습니다.`}catch(e){n=`Provider 해제 실패: ${e}`}l(e=>[...e,{id:`disconnect-${Date.now()}`,role:"assistant",content:n,timestamp:Date.now()}])},ma=async(t,n,a)=>{if(j.current)return void l(e=>[...e,{id:`mcp_test-${Date.now()}`,role:"assistant",content:"이미 자가진단이 진행 중입니다. 끝난 뒤 다시 실행하세요.",timestamp:Date.now()}]);j.current=!0;const r=`mcp_test-pending-${Date.now()}`,s=t&&"both"!==t?t:"stdio + streamable-http";let o;l(e=>[...e,{id:r,role:"assistant",content:`MCP 프로토콜 자가진단 중... (${s}${n?`, 포트 ${n}`:""}${a?", tools/call 포함":""}) — 수십 초~수 분 걸립니다`,timestamp:Date.now()}]);try{const r=await e.runMcpSelftest(t,n,a);if(r.installed)if(r.error){const e=[r.stdout,r.stderr].filter(Boolean).join("\n");o=[`**자가진단 실행 실패** — ${r.error}`,"",`검사 대상: \`${r.python}\``,e?`\n\`\`\`\n${e}\n\`\`\``:""].join("\n")}else{const e=r.report,t=e=>e.replace(/\|/g,"\\|").replace(/\r?\n/g," "),n=e.transports.map(e=>{const n=e.checks.map(e=>`| ${"PASS"===e.status?"✅":"FAIL"===e.status?"❌":"⏭️"} | ${t(e.name)} | ${t(e.detail)||"-"} |`).join("\n"),a="`".repeat(Math.max(3,...(e.server_log?.match(/`+/g)||[]).map(e=>e.length+1))),r=e.server_log?`\n\n<details><summary>서버 로그</summary>\n\n${a}\n${e.server_log}\n${a}\n\n</details>`:"";return`**[${e.transport}]** ${e.ok?"통과":"실패"}\n\n| | 검사 | 상세 |\n|---|---|---|\n${n}${r}`}).join("\n\n"),a=e.transports.flatMap(e=>e.checks.filter(e=>"FAIL"===e.status)),s=a.length>0&&a.every(e=>"tools/call"===e.name),l=e.ok?"전부 통과":s?"프로토콜 통과 · tools/call 실패":"실패 항목 있음";o=[`**MCP 프로토콜 자가진단: ${l}**`,"",n,"",s?"> 프로토콜 검사는 모두 통과했고 `tools/call` 만 실패했습니다. 이 검사는 실제 AWS 리소스를 치므로 **자격·리소스 문제일 가능성이 큽니다** — 프로토콜 결함이 아닐 수 있습니다.\n":"",`_검사 대상: \`${r.python}\`_`].filter(Boolean).join("\n")}else{const e=(r.candidates||[]).map(e=>`- \`${e}\``).join("\n");o=["**bdp-mcp 를 찾지 못했습니다.**","","MCP 서버는 코드버프와 **분리된 venv** 에 설치합니다 (주피터 서버의 의존성을 오염시키지 않기 위해).","","```bash","python3.12 -m venv ~/repo/bdp_mcp/.venv","~/repo/bdp_mcp/.venv/bin/pip install ~/repo/bdp_mcp/dist/bdp_mcp_server-*.whl","```","",`다른 위치에 설치했으면 \`${r.env_var}\` 에 그 venv 의 python 경로를 지정하고 JupyterLab 을 재기동하세요.`,"","찾아본 곳:",e].join("\n")}}catch(e){const t=e instanceof Error?e.message:String(e);o=`**자가진단 실패** — ${t}`}finally{j.current=!1}l(e=>e.filter(e=>e.id!==r).concat({id:`mcp_test-${Date.now()}`,role:"assistant",content:o,timestamp:Date.now()}))},pa=e=>!0,ha=e=>{const t=e.toLowerCase();return t.includes("calling tool")?e.replace(/Calling tool:/gi,"도구 호출 중:").trim():t.includes("waiting for user approval")?"승인 대기 중...":t.includes("resuming execution")?"승인 반영 후 실행 재개 중...":e},ga=()=>{if(!et)return"";if("string"==typeof et)return ha(et);let e;if(e=nt&&et.full_text?ha(et.full_text):ha(et.status),void 0!==et.turn&&et.turn>0){const t=[`턴 ${et.turn}`];et.tool_label&&t.push(et.tool_label),e=`[${t.join(" · ")}] ${e}`}return e},fa=()=>et&&"string"!=typeof et&&et.icon?L(et.icon):"",ba=()=>!(!et||"string"==typeof et)&&!0===et.expandable,va=ft?`승인 대기: ${ft.action}`:et?ga():p||g?"요청 처리 중":null,ya=St?vt.map(e=>"in_progress"===e.status?{...e,status:"cancelled"}:e):vt,Ea=ya.some(e=>"pending"===e.status||"in_progress"===e.status);return d().createElement("div",{className:"jp-agent-panel"},z&&d().createElement(x,{onClose:()=>F(!1),onSave:e=>{if(V){const t={...V,workspaceRoot:e.workspaceRoot,autoApprove:e.autoApprove};!function(e){try{localStorage.setItem(_,JSON.stringify(e)),console.log("[ApiKeyManager] Config saved to localStorage"),window.dispatchEvent(new CustomEvent("codebuff-config-updated",{detail:e}))}catch(e){console.error("[ApiKeyManager] Failed to save config:",e)}}(t),G(t)}console.log("[AgentPanel] User config saved")},apiService:e,inputMode:K}),d().createElement("div",{className:"jp-agent-header"},d().createElement("div",{className:"jp-agent-header-logo",dangerouslySetInnerHTML:{__html:Ft}}),d().createElement("div",{className:"jp-agent-header-buttons"},d().createElement("button",{className:"jp-agent-clear-button",onClick:()=>{Ze.c.getInstance().trackClick("panel_clear"),l([]),je([]),Et([]),pt(null),bt(null),At(!1),Wt(!1),ot(!1),ct(!1)},title:"화면 지우기"},d().createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("polyline",{points:"3 6 5 6 21 6"}),d().createElement("path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"}),d().createElement("line",{x1:"10",y1:"11",x2:"10",y2:"17"}),d().createElement("line",{x1:"14",y1:"11",x2:"14",y2:"17"}))),d().createElement("button",{className:"jp-agent-theme-button",onClick:()=>{const e=window.jupyterapp;e?.commands.execute("apputils:change-theme",{theme:U?"JupyterLab Light":"JupyterLab Dark"})},title:U?"라이트 테마로 전환":"다크 테마로 전환"},U?d().createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("circle",{cx:"12",cy:"12",r:"5"}),d().createElement("line",{x1:"12",y1:"1",x2:"12",y2:"3"}),d().createElement("line",{x1:"12",y1:"21",x2:"12",y2:"23"}),d().createElement("line",{x1:"4.22",y1:"4.22",x2:"5.64",y2:"5.64"}),d().createElement("line",{x1:"18.36",y1:"18.36",x2:"19.78",y2:"19.78"}),d().createElement("line",{x1:"1",y1:"12",x2:"3",y2:"12"}),d().createElement("line",{x1:"21",y1:"12",x2:"23",y2:"12"}),d().createElement("line",{x1:"4.22",y1:"19.78",x2:"5.64",y2:"18.36"}),d().createElement("line",{x1:"18.36",y1:"5.64",x2:"19.78",y2:"4.22"})):d().createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("path",{d:"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"}))),d().createElement("button",{className:"jp-agent-settings-button-icon",onClick:()=>{Ze.c.getInstance().trackClick("panel_settings"),F(!0)},title:B?"설정 — 연결 상태에 문제가 있습니다":"설정"},B&&d().createElement("span",{className:"jp-agent-settings-warn-dot","data-testid":"settings-status-dot"}),d().createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("line",{x1:"4",y1:"21",x2:"4",y2:"14"}),d().createElement("line",{x1:"4",y1:"10",x2:"4",y2:"3"}),d().createElement("line",{x1:"12",y1:"21",x2:"12",y2:"12"}),d().createElement("line",{x1:"12",y1:"8",x2:"12",y2:"3"}),d().createElement("line",{x1:"20",y1:"21",x2:"20",y2:"16"}),d().createElement("line",{x1:"20",y1:"12",x2:"20",y2:"3"}),d().createElement("line",{x1:"1",y1:"14",x2:"7",y2:"14"}),d().createElement("line",{x1:"9",y1:"8",x2:"15",y2:"8"}),d().createElement("line",{x1:"17",y1:"16",x2:"23",y2:"16"}))))),d().createElement("div",{className:"jp-agent-privacy-notice",role:"note"},"Codebuff 사용시 개인정보, 민감정보 입력을 금지합니다"),d().createElement("div",{className:"jp-agent-messages",ref:kn},0===o.length?d().createElement("div",{className:"jp-agent-empty-state"},d().createElement("div",{className:"jp-agent-guide-center-area"},"simple"===K&&d().createElement(d().Fragment,null,d().createElement("div",{className:"jp-agent-guide-tips"},d().createElement("div",{className:"jp-agent-guide-tip"},d().createElement("span",null,"Codebuff와 자유롭게 대화하세요. 코드 질문, 디버깅, 설명 요청 등에 활용할 수 있습니다.")),d().createElement("div",{className:"jp-agent-guide-tip"},d().createElement("span",null,"입력창의 ",d().createElement("strong",null,"모드 선택 박스"),"에서 ",["Chat","Agent",...$.filter(e=>e.alive).map(e=>e.display_name||e.name)].join(" / ")," 중 하나를 선택할 수 있습니다.",ne?` Chat은 필요하면 BDP 사내 ${ee?"가이드/테이블":"가이드"}를 검색해 답변합니다.`:"")),ee&&d().createElement("div",{className:"jp-agent-guide-tip"},d().createElement("span",null,d().createElement("code",null,"/eda-agent"),"로 EDA Agent를 바로 실행할 수 있습니다.")))),sn(K)&&(()=>{const e=sn(K),t=$.find(t=>t.name===e);return d().createElement(d().Fragment,null,d().createElement("p",{className:"jp-agent-guide-title"},d().createElement("strong",null,t?.display_name||e)),!t?.alive&&d().createElement("div",{className:"jp-agent-guide-tips"},d().createElement("div",{className:"jp-agent-guide-tip"},d().createElement("span",null,"'",e,"'이(가) 응답하지 않습니다. 프로세스 기동 후 ",d().createElement("code",null,"/discovery ",e," ",t?.port??"<포트>"),"로 다시 연결하세요."))))})())):o.map(e=>{if(pa(e)){if("assistant"===e.role&&(!e.content||""===e.content.trim())&&b!==e.id)return null;const t="assistant"===e.role,n="shell-output"===e.metadata?.kind,a=e.metadata?.interrupt?.action,r="write_file_tool"===a,s="edit_file_tool"===a,o="multiedit_file_tool"===a,l="markdown_tool"===a||"markdown"===a,c=r&&"string"==typeof e.metadata?.interrupt?.args?.path?e.metadata?.interrupt?.args?.path:"",i=(s||o)&&"string"==typeof e.metadata?.interrupt?.args?.path?e.metadata?.interrupt?.args?.path:"",u=e.metadata?.interrupt?.autoApproved,m="user"===e.role?"사용자":"system"===e.role?n?"shell 실행":u?"자동 승인됨":"승인 요청":"Agent";return d().createElement("div",{key:e.id,className:t?"jp-agent-message jp-agent-message-assistant-inline":`jp-agent-message jp-agent-message-${e.role}${n?" jp-agent-message-shell-output":""}`},!t&&d().createElement("div",{className:"jp-agent-message-header"},d().createElement("span",{className:"jp-agent-message-role"},m),d().createElement("span",{className:"jp-agent-message-time"},new Date(e.timestamp).toLocaleTimeString())),d().createElement("div",{className:`jp-agent-message-content${b===e.id?" streaming":""}${n?" jp-agent-message-content-shell":""}`},"system"===e.role&&e.metadata?.interrupt?e.metadata?.interrupt?.autoApproved?d().createElement("div",{className:"jp-agent-auto-approved-summary"},(()=>{const t=e.metadata?.interrupt?.action||"",n=e.metadata?.interrupt?.args||{};return`✅ ${"jupyter_cell_tool"===t?"셀 "+("READ"===n.operation?"읽기":"삽입"):"write_file_tool"===t?`파일 생성: ${n.path||""}`:"edit_file_tool"===t||"multiedit_file_tool"===t?`파일 수정: ${n.path||""}`:"search_notebook_cells_tool"===t?"노트북 검색":"read_file_tool"===t?`파일 읽기: ${n.path||""}`:"list_workspace_tool"===t?"워크스페이스 목록":"search_files_tool"===t?"파일 검색":"check_resource_tool"===t?"리소스 확인":t.replace(/_tool$/,"").replace(/_/g," ")}`})()):d().createElement("div",{className:"jp-agent-interrupt-inline"},d().createElement("div",{className:"jp-agent-interrupt-action"},d().createElement("div",{className:"jp-agent-interrupt-action-args"},(()=>{const t=e.metadata?.interrupt?.args?.command,n=e.metadata?.interrupt?.args?.code||e.metadata?.interrupt?.args?.content||"";let a,u;if(o)a=function(e,t){const n=[];return t.forEach((e,t)=>{t>0&&n.push(""),n.push(`# Edit ${t+1}${e.replace_all?" (replace_all)":""}`),n.push(...Ht(e.old_string||"",e.new_string||""))}),`--- ${e} (${t.length} edits)\n+++ ${e} (after)\n`+Jt(n).join("\n")}(i,e.metadata?.interrupt?.args?.edits||[]),u="diff";else if(s){const t=e.metadata?.interrupt?.args||{};a=function(e,t,n,a={}){return`--- ${e} (before)\n+++ ${e} (after)\n`+Jt(Ht(t,n)).join("\n")+(a.replaceAll?"\n\n(replace_all: true)":"")}(i,t.old_string||"",t.new_string||"",{replaceAll:t.replace_all}),u="diff"}else l?(a=n||"",u="markdown"):(a=t||n||"(no details)",u=t?"bash":"python");const m=e.metadata?.interrupt?.resolved,p=e.metadata?.interrupt?.decision,h=e.metadata?.interrupt?.autoApproved,g=m&&!h?`<div class="jp-agent-interrupt-actions ${h?"":"reject"===p?"jp-agent-interrupt-actions--rejected":"jp-agent-interrupt-actions--resolved"}">${h?"":"reject"===p?M.rejectCircle:M.doubleCheck}</div>`:m&&h?"":`\n<div class="code-block-actions jp-agent-interrupt-actions">\n <button class="jp-agent-interrupt-approve-btn" data-action="approve" title="승인">${M.approveCircle}</button>\n <button class="jp-agent-interrupt-reject-btn" data-action="reject" title="거부">${M.rejectCircle}</button>\n</div>\n`,f=r||s||o?e.metadata?.interrupt?.preview:void 0,b=e.metadata?.interrupt?.args?.description,v=(()=>{let t,n=Ee(l?a:`\n\`\`\`${u}\n${a}\n\`\`\``);if(r&&c){const e=Fn(c);n=n.replace(/<span class="code-block-language">[^<]*<\/span>/,`<span class="code-block-language jp-agent-interrupt-path">${e}</span>`)}if((s||o)&&i){const e=Fn(i),t=M.edit;n=n.replace(/<span class="code-block-language">[^<]*<\/span>/,`<span class="code-block-language jp-agent-interrupt-path">${t} ${e}</span>`)}l?t=g?`<div class="jp-agent-markdown-preview">${n}${g}</div>`:`<div class="jp-agent-markdown-preview">${n}</div>`:f?(Be(),t=`<div class="jp-agent-interrupt-diff">${qe([Ne(f.path,f.before,f.after)],{layout:ze(),highlight:ce})}${g}</div>`):t=g?n.replace("</div>",`${g}</div>`):n;let d="";if(b){const e=Fn(b).replace(/\\n/g," ").replace(/\n/g," ").replace(/\s+/g," ").trim();d+=`<div class="jp-agent-code-description">${M.description} ${e}</div>`}if(!e.metadata?.interrupt?.autoApproved&&e.content){const t=Fn(e.content);d+=`<div class="jp-agent-interrupt-description">${M.approvalWarning} ${t}</div>`}return d+=t,d})();return d().createElement("div",{className:"jp-RenderedHTMLCommon",style:{padding:"0 4px"},dangerouslySetInnerHTML:{__html:v},onClick:t=>{const n=t.target.closest("[data-action]"),a=n?.getAttribute?.("data-action");e.metadata?.interrupt?.resolved||("approve"===a?la("approve"):"reject"===a&&la("reject"))}})})()))):"assistant"===e.role?d().createElement(d().Fragment,null,d().createElement(yt,{content:e.content,isStreaming:b===e.id,onInsertAbove:dn,onInsertBelow:un,onInsertAsCell:mn,onReplaceCell:qn,cellActionsEnabled:!!an(),statusText:b===e.id?ga():e.metadata?.statusHistory||void 0,toolProcessing:b===e.id&&st,summarizing:b===e.id&&lt,startedAt:b===e.id?y.current:void 0}),e.metadata?.providerResponse&&!!e.content&&b!==e.id&&d().createElement(on,{content:e.content})):d().createElement(d().Fragment,null,d().createElement("div",{style:{whiteSpace:"pre-wrap"}},e.content),Array.isArray(e.metadata?.maskedTypes)&&e.metadata.maskedTypes.length>0&&d().createElement("div",{className:"jp-pii-mask-strip"},d().createElement("span",{className:"jp-pii-mask-icon","aria-hidden":"true"},"ⓘ"),d().createElement("span",{className:"jp-pii-mask-text"},e.metadata.maskedTypes.join("·")," 자동 마스킹됨")))))}return null}),pe&&ue&&d().createElement("div",{className:"jp-agent-console-error-notification"},d().createElement("div",{className:"jp-agent-console-error-header"},d().createElement("svg",{viewBox:"0 0 16 16",fill:"currentColor",width:"16",height:"16"},d().createElement("path",{d:"M8.982 1.566a1.13 1.13 0 00-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 01-1.1 0L7.1 5.995A.905.905 0 018 5zm.002 6a1 1 0 110 2 1 1 0 010-2z"})),d().createElement("span",null,"Console에서 Python 에러가 감지되었습니다")),d().createElement("div",{className:"jp-agent-console-error-preview"},ue.slice(0,200),ue.length>200?"...":""),d().createElement("div",{className:"jp-agent-console-error-actions"},d().createElement("button",{className:"jp-agent-console-error-fix-btn",onClick:()=>{m(`다음 에러를 분석하고 수정해주세요:\n\n${ue}`),he(!1);const e=document.querySelector(".jp-agent-input");e&&e.focus()}},"에러 분석 요청"),d().createElement("button",{className:"jp-agent-console-error-dismiss-btn",onClick:()=>he(!1)},"닫기"))),d().createElement("div",{ref:wn})),("agent"===K||"codex"===K)&&vt.length>0&&d().createElement("div",{className:"jp-agent-todo-compact"},d().createElement("div",{className:"jp-agent-todo-compact-header",onClick:()=>wt(!kt)},d().createElement("div",{className:"jp-agent-todo-compact-left"},d().createElement("svg",{className:"jp-agent-todo-expand-icon "+(kt?"jp-agent-todo-expand-icon--expanded":""),viewBox:"0 0 16 16",fill:"currentColor",width:"12",height:"12"},d().createElement("path",{d:"M6 12l4-4-4-4"})),(()=>{const e=g||p||X;if(St)return d().createElement("span",{className:"jp-agent-todo-compact-current"},"작업 중단됨");const t=ya.find(e=>"in_progress"===e.status)||ya.find(e=>"pending"===e.status);return t?d().createElement(d().Fragment,null,d().createElement("div",{className:"jp-agent-todo-compact-spinner"}),d().createElement("span",{className:"jp-agent-todo-compact-current"},t.content)):e?d().createElement(d().Fragment,null,d().createElement("div",{className:"jp-agent-todo-compact-spinner"}),d().createElement("span",{className:"jp-agent-todo-compact-current"},"작업 마무리 중...")):d().createElement("span",{className:"jp-agent-todo-compact-current",dangerouslySetInnerHTML:{__html:`${M.check} 모든 작업 완료`}})})()),!St&&(g||p||X||ya.some(e=>"in_progress"===e.status))&&d().createElement("button",{className:"jp-agent-todo-stop-btn",onClick:e=>{e.stopPropagation(),console.log("[AgentPanel] Stop button clicked"),Tn()},title:"작업 중단"},d().createElement("svg",{viewBox:"0 0 16 16",fill:"currentColor",width:"12",height:"12"},d().createElement("rect",{x:"3",y:"3",width:"10",height:"10",rx:"1"}))),d().createElement("span",{className:"jp-agent-todo-compact-progress"},vt.filter(e=>"completed"===e.status).length,"/",vt.length)),va&&Ea&&d().createElement("div",{className:"jp-agent-message jp-agent-message-debug jp-agent-message-debug--inline"+(va.startsWith("오류:")?" jp-agent-message-debug-error":"")},d().createElement("div",{className:"jp-agent-debug-content"},d().createElement("div",{className:"jp-agent-debug-branch","aria-hidden":"true"}),fa()&&d().createElement("span",{className:"jp-agent-debug-icon",dangerouslySetInnerHTML:{__html:fa()}}),d().createElement("span",{className:"jp-agent-debug-text"+(ba()?" jp-agent-debug-text--expandable":""),onClick:ba()?()=>at(!nt):void 0,title:ba()?nt?"접기":"펼치기":void 0},(()=>{const e=va?.split("\n").filter(e=>e.replace("__fade__","").trim())||[],t=e.length;return e.map((e,n)=>{const a=e.replace("__fade__",""),r=t-1-n,s=Math.max(.25,1-.25*r);return d().createElement("span",{key:n,style:{display:"block",opacity:s}},a)})})(),ba()&&d().createElement("span",{className:"jp-agent-debug-expand-icon"},nt?d().createElement(Ot.A,{sx:{fontSize:14}}):d().createElement(zt.A,{sx:{fontSize:14}}))))),kt&&d().createElement("div",{className:"jp-agent-todo-expanded"},ya.map((e,t)=>d().createElement("div",{key:t,className:`jp-agent-todo-item jp-agent-todo-item--${e.status}`},d().createElement("div",{className:"jp-agent-todo-item-indicator"},"completed"===e.status&&d().createElement("svg",{viewBox:"0 0 16 16",fill:"currentColor",width:"12",height:"12"},d().createElement("path",{d:"M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"})),"in_progress"===e.status&&d().createElement("div",{className:"jp-agent-todo-item-spinner"}),"cancelled"===e.status&&d().createElement("svg",{viewBox:"0 0 16 16",fill:"currentColor",width:"12",height:"12"},d().createElement("path",{d:"M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"})),"pending"===e.status&&d().createElement("span",{className:"jp-agent-todo-item-number"},t+1)),d().createElement("span",{className:"jp-agent-todo-item-text "+("completed"===e.status?"jp-agent-todo-item-text--done":"")},e.content))))),va&&!Ea&&!("agent"!==K&&g)&&d().createElement("div",{className:"jp-agent-message jp-agent-message-debug jp-agent-message-debug--above-input"+(va.startsWith("오류:")?" jp-agent-message-debug-error":"")},d().createElement("div",{className:"jp-agent-debug-content"},fa()&&d().createElement("span",{className:"jp-agent-debug-icon",dangerouslySetInnerHTML:{__html:fa()}}),d().createElement("span",{className:"jp-agent-debug-text"+(ba()?" jp-agent-debug-text--expandable":""),onClick:ba()?()=>at(!nt):void 0,title:ba()?nt?"접기":"펼치기":void 0},va,ba()&&d().createElement("span",{className:"jp-agent-debug-expand-icon"},nt?d().createElement(Ot.A,{sx:{fontSize:14}}):d().createElement(zt.A,{sx:{fontSize:14}}))))),d().createElement("div",{className:"jp-agent-input-container"},d().createElement(We,{changes:Ce}),Ve.length>0&&d().createElement(Pt,{processes:Ve,proxy:$e,proxyReason:Ae,stopping:Me,onKill:t=>{Re(e=>[...e,t]),e.killCodexProcess(t).catch(()=>null).then(e=>{e?_e(n=>n.map(n=>n.id===t?e:n)):Fe(e=>e+1)}).finally(()=>Re(e=>e.filter(e=>e!==t)))},readOutput:t=>e.readCodexProcessOutput(t),onDismiss:e=>{const t=Se.find(t=>t.id===e);t&&Le(e=>[...e,Je(t)])}}),we&&"codex"===K&&d().createElement(_t,{threads:we,onSelect:e=>{p||g||(xe(null),Ze.c.getInstance().trackClick("cmd_codex_resume",{input_mode:K,via:"picker"}),In({displayContent:`/resume ${e}`,clearInput:!1}))},onClose:()=>xe(null)}),d().createElement("div",{className:"jp-agent-input-wrapper",style:{position:"relative"}},d().createElement("div",{className:"jp-agent-kb-toggle-wrap",ref:P},(()=>{const e=sn(K),t=[...$.filter(e=>e.alive),...e&&!$.some(t=>t.name===e&&t.alive)?[{name:e,display_name:e,owner:""}]:[]],n=[{value:"simple",label:"Chat",desc:ne?`대화·BDP 사내 ${ee?"가이드·테이블":"가이드"} 검색`:"대화",kind:"chat"},..."codex"===ie&&oe&&re?[{value:"codex",label:"Agent",desc:"코드 읽기·수정·명령 실행",kind:"codex"}]:[],..."langchain"===ie&&re?[{value:"agent",label:"Agent",desc:"코드 읽기·수정·명령 실행",kind:"codex"}]:[],...t.map(e=>({value:`provider:${e.name}`,label:e.display_name||e.name,desc:"외부 에이전트 호출",kind:"provider"}))],a=K,r=n.find(e=>e.value===a)||n[0],s=e=>"chat"===e?d().createElement("svg",{viewBox:"0 0 24 24",width:"15",height:"15",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})):"codex"===e?d().createElement("svg",{viewBox:"0 0 24 24",width:"15",height:"15",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("polyline",{points:"16 18 22 12 16 6"}),d().createElement("polyline",{points:"8 6 2 12 8 18"})):d().createElement("svg",{viewBox:"0 0 24 24",width:"15",height:"15",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("rect",{x:"3",y:"11",width:"18",height:"10",rx:"2"}),d().createElement("circle",{cx:"12",cy:"5",r:"2"}),d().createElement("path",{d:"M12 7v4M8 16h.01M16 16h.01"}));return d().createElement(d().Fragment,null,d().createElement("button",{type:"button",className:"jp-agent-mode-dd-trigger "+(A?"is-open":""),onClick:()=>I(e=>!e),"aria-haspopup":"listbox","aria-expanded":A,"aria-label":"입력 모드 선택"},d().createElement("span",{className:"jp-agent-mode-dd-ic"},s(r.kind)),d().createElement("span",{className:"jp-agent-mode-dd-lb"},r.label),d().createElement("svg",{className:"jp-agent-mode-dd-chev",viewBox:"0 0 24 24",width:"14",height:"14",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("path",{d:"M6 9l6 6 6-6"}))),A&&d().createElement("div",{className:"jp-agent-mode-dd-menu",role:"listbox"},n.map(e=>d().createElement("button",{key:e.value,type:"button",role:"option","aria-selected":e.value===a,className:"jp-agent-mode-dd-item "+(e.value===a?"is-active":""),onClick:()=>{Q(e.value),I(!1)}},d().createElement("span",{className:"jp-agent-mode-dd-item-ic"},s(e.kind)),d().createElement("span",{className:"jp-agent-mode-dd-item-tx"},d().createElement("span",{className:"jp-agent-mode-dd-item-lb"},e.label),d().createElement("span",{className:"jp-agent-mode-dd-item-ds"},e.desc)),e.value===a&&d().createElement("svg",{className:"jp-agent-mode-dd-item-ck",viewBox:"0 0 24 24",width:"15",height:"15",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("path",{d:"M20 6L9 17l-5-5"}))))))})()),d().createElement(xt,{apiService:e,inputValue:u,cursorPosition:Ke,engine:"codex"===K?"codex":void 0,onSelect:async(e,t)=>{if("/reset"===e.id&&e.is_complete&&t)return Ze.c.getInstance().trackClick("cmd_reset",{input_mode:K}),await ca(),ke(!1),Xe(!1),void m("");if("/new"===e.id&&"codex"===K&&e.is_complete&&t)return Ze.c.getInstance().trackClick("cmd_new",{input_mode:K}),xe(null),await ca(),ke(!1),Xe(!1),void m("");if("/help"===e.id&&e.is_complete&&t)return Ze.c.getInstance().trackClick("cmd_help",{input_mode:K}),(()=>{const e=`<div style="text-align: center; margin-bottom: 16px;"><img src="data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(Ft)))}" style="max-width: 50%; height: auto;" alt="Codebuff Logo" /></div>\n\n## Codebuff 사용 가이드\n\n**Codebuff**는 LLM 기반의 지능형 데이터 분석 코딩 어시스턴트입니다. JupyterLab 환경에서 AI와 대화하며 데이터 분석, 코드 작성, 문제 해결을 도움 받을 수 있습니다.\n\n---\n\n### 📌 기능 소개\n\n| 기능 | 설명 |\n|------|------|\n| **Chat** | AI와 자유롭게 대화하며 질문하고 답변을 받습니다. 사내 데이터가 필요한 질문이면 AI가 알아서 사내 ${ee?"가이드·테이블":"가이드"}를 검색해 답변에 반영합니다. |${ee?"\n| **EDA Agent** | 자연어로 Athena SQL을 생성/튜닝합니다. Launcher에서 **EDA Agent** 버튼으로 실행합니다. |":""}\n| **Agent 모드** | AI가 직접 코드를 실행하고 작업을 수행합니다. 입력창의 모드 셀렉트에서 Agent 를 고릅니다. 추론 엔진에 따라 codex 또는 deepagents 가 돕니다. |\n\n---\n${ee?"\n### 🔎 EDA Agent (beta) 사용 가이드\n\nLauncher에서 **EDA Agent** 버튼을 클릭하면 Athena SQL 생성/튜닝 패널이 열립니다.\n\n#### 기본 사용법\n\n| 단계 | 설명 |\n|------|------|\n| **1. 프롬프트 입력** | 원하는 분석 내용을 자연어로 입력합니다. 예: `카드매출과 가맹점을 조인해서 월별 매출 집계해줘` |\n| **2. 테이블 후보 선택** | AI가 RAG 검색으로 관련 테이블 후보를 제시합니다. 각 후보를 클릭해 선택하세요. |\n| **3. SQL 생성** | **선택 완료** 버튼을 누르면 선택한 테이블 기반 SQL이 생성됩니다. |\n| **4. SQL 튜닝** | 생성된 SQL 위에 추가 요청을 입력하면 SQL을 수정/튜닝할 수 있습니다. |\n\n#### 테이블 후보 화면 버튼\n\n| 버튼 | 설명 |\n|------|------|\n| **다른 테이블 살펴보기** | 미선택 그룹만 재검색합니다. 선택 완료한 테이블은 유지됩니다. |\n| **선택 완료** | 선택한 테이블로 SQL 생성을 시작합니다. |\n| 후보 행 클릭 | 테이블을 선택/해제합니다. 펼치면 상세 메타데이터와 컬럼 목록을 볼 수 있습니다. |\n\n#### 편의 기능\n\n| 기능 | 설명 |\n|------|------|\n| 🗑️ **초기화** | 프롬프트 입력창 옆 휴지통 아이콘을 클릭하면 모든 상태(프롬프트, SQL, 테이블 선택)를 초기화합니다. |\n| **컬럼 수 표시** | 컬럼이 200개 초과 시 `200컬럼+`로 표시됩니다. |\n\n---\n":""}\n### ⌨️ 편집기 빠른 기능\n\n| 기능 | 단축키 | 설명 |\n|------|--------|------|\n| **선택 확대** | \`Ctrl+Alt+W\` | 커서의 단어·식·문장처럼 더 큰 구문을 차례로 선택합니다. 일반 텍스트는 단어 → 줄 → 문서/셀 순서입니다. |\n| **선택 축소** | \`Ctrl+Alt+Shift+W\` | Codebuff로 확대한 직전 선택으로 돌아갑니다. 편집 내용은 되돌리지 않습니다. |\n| **줄 이동** | \`Alt+↑/↓\` | 현재 줄을 위아래로 옮깁니다. 파일 편집기 전용입니다(노트북 셀에서는 입력 이력 탐색). |\n| **줄 복제** | \`Shift+Alt+↑/↓\` | 현재 줄을 위아래로 복제합니다. |\n| **다음 일치 추가** | \`Ctrl/Cmd+Shift+D\` | 현재 선택과 같은 다음 텍스트를 다중 선택에 더합니다. |\n| **사각 선택** | \`Alt+드래그\` | 열 단위 블록을 선택합니다. |\n| **파일 찾아 열기** | \`Ctrl/Cmd+Shift+O\` | 이름으로 파일을 찾아 엽니다. |\n| **파일 구조** | \`Ctrl+F12\` | 현재 파일의 클래스·메서드·필드를 골라 그 줄로 갑니다. |\n| **git 이력 diff** | 파일 우클릭 | 파일의 두 시점을 골라 비교합니다. |\n\n선택 확대·축소는 파일 편집기와 편집 중인 노트북 셀에서만 동작하며, 명령 팔레트의 **Codebuff** 항목에서도 실행할 수 있습니다.\n\n### 💬 Chat 기능 상세\n\n#### 1. 채팅 기능\n\n- AI와 자유롭게 대화하며 질문/답변을 주고받을 수 있습니다.\n- 슬래시 명령어(\`/\`)와 컨텍스트 멘션(\`@\`)을 지원합니다.\n- **사내 검색**: 질문에 사내 데이터가 필요하면 AI가 사내 ${ee?"가이드/테이블":"가이드"}를 자동 검색해 답변에 반영합니다. 따로 켤 필요가 없습니다.\n\n#### 2. 셀 내 버튼 기능\n\n노트북의 각 코드 셀 옆에 있는 아이콘 버튼을 활용하세요:\n\n| 아이콘 | 기능 | 설명 |\n|--------|------|------|\n| 💡 | **코드 설명** | 코드의 동작 원리와 로직을 상세히 설명합니다. |\n| ❓ | **질문하기** | 선택한 셀 코드에 대해 자유롭게 질문합니다. |\n| 🔧 | **수정 제안** | 선택한 셀의 코드를 분석하여 개선 사항을 제안합니다. |\n\n버튼 클릭 시 해당 셀의 코드가 자동으로 대화창에 포함됩니다.\n\n#### 3. 상단 버튼 기능\n\n| 버튼 | 설명 |\n|------|------|\n| 💾 **저장하기** (툴바 저장 버튼) | 툴바의 저장 버튼이나 File 메뉴의 저장을 누르면 **저장만 하기** 또는 **코드리뷰 후 저장** 중 선택하는 모달이 표시됩니다. 코드리뷰를 선택하면 AI가 현재 노트북을 분석한 뒤 저장합니다. \`Ctrl/Cmd+S\` 는 모달 없이 바로 저장합니다. |\n| ✨ **노트북 설명하기** | 클릭 → 확인 다이얼로그 → \`노트북 설명해줘\`가 자동 전송되고, 열린 노트북 전체가 함께 첨부되어 설명합니다. |\n\n파일 브라우저에서 파일을 우클릭하고 **git 이력 diff** 를 고르면, 그 파일의 커밋 두 개나 날짜 범위를 골라 비교하는 탭이 열립니다.\n\n#### 4. Launcher 기능\n\nLauncher 페이지에서 Codebuff 아이콘의 **노트북 자동생성** 버튼을 클릭하면:\n1. 원하는 노트북 내용을 자연어로 입력\n2. AI가 마크다운 설명 + 코드 셀이 포함된 노트북을 자동 생성\n\n채팅에서 \`/create-notebook 타이타닉 데이터 분석\`으로도 생성할 수 있습니다.\n\n#### 5. 설정 기능\n\n우측 상단 ⚙️ 아이콘으로 설정 패널을 열 수 있습니다.\n\n| 항목 | 설명 |\n|------|------|\n| **프로젝트 디렉터리** | 에이전트가 파일을 읽고 쓰는 작업 폴더입니다. 입력하면 하위 폴더를 자동완성합니다. |\n| **AGENTS.md** | 프로젝트 디렉터리의 AI 지시사항 파일 감지 상태를 표시합니다. |\n| **포털 / 로컬** | 각 항목이 포털에 저장되는지, 이 환경에만 저장되는지 표시합니다. |\n\n#### 6. 슬래시 명령어 (/) 와 컨텍스트 멘션 (@)\n\n**슬래시 명령어**\n\n| 명령어 | 설명 |\n|--------|------|\n| \`/help\` | 이 도움말을 표시합니다. |${ee?"\n| `/eda-agent` | EDA Agent를 열고 프롬프트를 바로 실행합니다. 예: `/eda-agent 카드매출 월별 집계 쿼리해줘` |":""}\n| \`/create-notebook\` | 자연어로 노트북을 자동 생성합니다. 예: \`/create-notebook 타이타닉 데이터 EDA\` |\n| \`/review\` | 코드리뷰를 수행합니다. (1) \`/review\` — 활성 탭 리뷰, (2) \`/review @경로\` — 특정 파일 리뷰. |\n| \`/unittest\` | 유닛테스트를 자동 생성합니다. (1) \`/unittest\` — 활성 탭, (2) \`/unittest @경로\` — 특정 파일. |\n| \`/reset\` | 세션을 초기화합니다. 대화 기록을 삭제하고 에이전트 스레드를 리셋합니다. |\n| \`/discovery\` | 외부 Agent Provider를 등록·확인합니다. (1) \`/discovery\` — 등록된 전체 갱신, (2) \`/discovery <이름> <포트>\` — 등록 (예: \`/discovery orbit 18080\`). 연결되면 모드 선택박스에 그 이름으로 노출됩니다. |\n| \`/disconnect\` | 등록된 Agent Provider를 해제합니다. 예: \`/disconnect orbit\`. 모드 선택박스에서 제거됩니다. |\n| \`/mcp_test\` | BDP MCP 서버의 프로토콜이 실제로 도는지 검사합니다. (1) \`/mcp_test\` — stdio+streamable-http 둘 다, (2) \`/mcp_test stdio\` — 하나만, (3) \`/mcp_test streamable-http 18099\` — 포트 지정, (4) \`/mcp_test call\` — 도구를 실제로 호출까지 (실 AWS를 치므로 자격·리소스 필요). 별도 venv에 설치된 bdp-mcp를 찾아 실행하며, 없으면 설치 방법을 안내합니다. |\n| \`/diff\` | 작업공간의 git 변경을 보여 줍니다. LLM 을 부르지 않습니다. |\n| \`/version\` | 현재 Codebuff 버전 정보를 표시합니다. |\n\n**codex 모드 명령** — 모드 선택박스에서 codex 를 고르면 codex CLI 의 명령을 쓸 수 있습니다. 로그인·클라우드·피드백 업로드처럼 SaaS 에서만 쓰는 명령은 뺐습니다. 이 모드에서는 \`/review\` 가 위 코드리뷰 대신 codex 코드리뷰로 동작합니다.\n\n| 명령어 | 설명 |\n|--------|------|\n${Lt.map(e=>`| \`${e.name}\` | ${e.help} |`).join("\n")}\n\n**파일 멘션** — 입력창에 \`@\`를 입력하면 파일을 퍼지 검색으로 고를 수 있습니다 (Tab 또는 Enter 로 선택).\n\n| 멘션 | 설명 |\n|------|------|\n| \`@경로\` | 그 파일 내용을 메시지에 포함합니다. 공백이 있는 경로는 \`@"경로"\` 로 씁니다. |\n\n\`@분석.ipynb\` 는 디스크에 저장된 노트북을 읽습니다. 지금 선택한 셀이나 에러는 셀 버튼(설명·질문·개선)을 쓰세요.\n\n#### 8. 프로젝트 지시사항 (AGENTS.md)\n\n프로젝트 디렉터리에 \`AGENTS.md\` 파일(대소문자 무관)을 생성하면 AI에게 프로젝트별 지시사항을 전달할 수 있습니다.\n\n| 항목 | 설명 |\n|------|------|\n| **파일 위치** | 프로젝트 디렉터리의 \`AGENTS.md\` |\n| **동작 방식** | 대화 시작 시 자동으로 시스템 프롬프트에 반영됩니다 |\n| **용도** | 코딩 규칙, 프로젝트 컨벤션, 특수 요구사항 등 |\n| **크기 제한** | 최대 10,000자. 초과 시 자동으로 잘립니다 |\n\n설정 메뉴(⚙️)에서 AGENTS.md 감지 여부를 확인할 수 있습니다.\n\n#### 9. 키보드 단축키\n\n| 단축키 | 동작 |\n|--------|------|\n| \`Enter\` | 메시지 전송 |\n| \`Shift+Enter\` | 줄바꿈 |\n| \`Escape\` | 스트리밍 중지 / 자동완성 닫기 |\n\n---\n\n### 🔍 사내 검색 (RAG)\n\nChat 에서 질문 내용에 따라 AI가 자동으로 RAG(벡터 검색)를 수행하여 관련 데이터를 참조합니다. 따로 켜는 토글은 없고, 관리자가 사내 검색을 끈 환경에서는 검색 없이 응답합니다.\n\n- 사내 ${ee?"가이드 문서, 테이블 메타데이터":"가이드 문서"}를 자동으로 선택해 검색합니다.\n\n**프로젝트 디렉터리 설정:**\n\n⚙️ → **사용자 설정**에서 **프로젝트 디렉터리**를 지정하면, \`@\` 파일 멘션과 파일 검색 시 해당 경로가 기준이 됩니다.\n\n---\n\n### 💡 팁\n\n- 긴 대화는 자동으로 요약/압축됩니다 (별도 조작 불필요)\n- \`/review\`로 작성한 코드의 품질을 점검하세요\n- \`/unittest\`로 테스트 코드를 자동 생성하세요\n- 코드 분석 시 \`@경로\`로 파일을 직접 참조하세요\n- 셀 버튼으로 빠르게 코드 설명/질문/개선을 요청하세요`,t={id:`help-${Date.now()}`,role:"assistant",content:e,timestamp:Date.now()};l(e=>[...e,t]),console.log("[AgentPanel] Help displayed")})(),ke(!1),Xe(!1),void m("");if("/version"===e.id&&e.is_complete&&t)return(async()=>{const{PageConfig:e}=await Promise.resolve().then(()=>n.t(7292,23)),t=e.getOption("CODEBUFF_EXTENSION_VERSION")||"unknown",a=e.getOption("CODEBUFF_BUILD_TIME")||"";let r="";if(a){const e=new Date(a);r="\nBuild: "+new Date(e.getTime()+324e5).toISOString().replace("T"," ").slice(0,19)+" KST"}const s=`**Codebuff** v${t}${r}`,o={id:`version-${Date.now()}`,role:"assistant",content:s,timestamp:Date.now()};l(e=>[...e,o])})(),ke(!1),Xe(!1),void m("");if(!Ye.current)return;const a=u;let r=Ke;for(;r>0&&!/\s/.test(a[r-1]);)r--;const s=a.slice(0,r),o=a.slice(Ke),c=!t&&e.is_complete&&e.id.startsWith("/"),i=t&&e.is_complete||c,d=s+e.label+(i?" ":"")+o,p=s.length+e.label.length+(i?1:0);m(d),Qe(p),(t||c)&&(ke(!1),Xe(!1)),setTimeout(()=>{Ye.current&&(Ye.current.focus(),Ye.current.setSelectionRange(p,p))},0)},onClose:()=>{ke(!1),Xe(!1)},onOptionsChange:Xe,visible:ye,anchorEl:Ye.current}),d().createElement("textarea",{ref:Ye,className:`jp-agent-input ${"agent"===K?"jp-agent-input--agent-mode":""} ${Tt?"jp-agent-input--rejection-mode":""}`,value:u,onChange:e=>{const t=e.target.value,n=e.target.selectionStart||0;m(t),Qe(n);let a=n;for(;a>0&&!/\s/.test(t[a-1]);)a--;const r=t.slice(a,n);r.startsWith("@")||r.startsWith("/")?ke(!0):ke(!1)},onKeyDown:e=>{if(ye&&Ge){if("Tab"===e.key||"ArrowDown"===e.key||"ArrowUp"===e.key)return;if("Enter"===e.key&&!e.shiftKey)return;if("Escape"===e.key)return ke(!1),void Xe(!1)}if("Escape"===e.key&&g)return e.preventDefault(),void Tn();"Enter"!==e.key||e.shiftKey||e.nativeEvent.isComposing||(e.preventDefault(),oa());const t=e=>{const t=["simple",...$.filter(e=>e.alive).map(e=>`provider:${e.name}`)],n=t.indexOf(e);return t[(n+1)%t.length]??"simple"};if("Tab"===e.key&&e.shiftKey)return e.preventDefault(),void Q(t);"."===e.key&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),Q(t))},onSelect:e=>Qe(e.target.selectionStart||0),placeholder:Tt?"다른 방향 제시":"agent"===K?"노트북 작업을 입력하세요... (예: @경로로 파일 참조)":"메세지를 입력하세요.",disabled:p||X}),d().createElement("div",{className:"jp-agent-button-container"},g?d().createElement("button",{className:"jp-agent-stop-button",onClick:Tn,title:"응답 중단 (Esc)"},d().createElement("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",width:"16",height:"16"},d().createElement("circle",{cx:"12",cy:"12",r:"10"}),d().createElement("rect",{x:"9",y:"9",width:"6",height:"6",rx:"1",fill:"currentColor",stroke:"none"})),"중단"):d().createElement("button",{className:"jp-agent-send-button",onClick:oa,disabled:!u.trim()&&!Tt||p||g||X,title:Tt?"거부 전송 (Enter)":"전송 (Enter)"},X?"실행 중...":Tt?"거부":"전송")))),ge&&d().createElement(Ue,{filename:ge.pattern,options:ge.options,message:ge.message,onSelect:async e=>{if(console.log("[AgentPanel] File selected:",e),!ge||!be)return void console.error("[AgentPanel] Missing file selection metadata or pending request");const t=ge.options[e-1];t?(console.log("[AgentPanel] Selected file:",t.path),fe(null),ve(null),Z(!1)):console.error("[AgentPanel] Invalid file selection index:",e)},onCancel:()=>{console.log("[AgentPanel] File selection cancelled"),fe(null),ve(null),Z(!1)}}))});ln.displayName="ChatPanel";class cn extends u.ReactWidget{constructor(e,t,n){super(),this.chatPanelRef=d().createRef(),this.apiService=e,this.notebookTracker=t,this.consoleTracker=n,this.id="codebuff-panel",this.title.caption="Codebuff Assistant",this.title.icon=an,this.addClass("jp-agent-widget")}onActivateRequest(e){super.onActivateRequest(e),Ze.c.getInstance().trackImpression("panel_open")}render(){return d().createElement(ln,{ref:this.chatPanelRef,apiService:this.apiService,notebookTracker:this.notebookTracker,consoleTracker:this.consoleTracker})}addCellActionMessage(e,t,n,a,r,s){console.log("[AgentPanel] Cell action:",e),console.log("[AgentPanel] Display prompt:",n),console.log("[AgentPanel] LLM prompt:",a),console.log("[AgentPanel] Cell ID:",r),console.log("[AgentPanel] Cell Index:",s),this.chatPanelRef.current?(this.chatPanelRef.current.setInputMode&&this.chatPanelRef.current.setInputMode("simple"),void 0!==s&&this.chatPanelRef.current.setCurrentCellIndex&&this.chatPanelRef.current.setCurrentCellIndex(s),r&&this.chatPanelRef.current.setCurrentCellId&&this.chatPanelRef.current.setCurrentCellId(r),this.chatPanelRef.current.setInput(n),this.chatPanelRef.current.setLlmPrompt(a),setTimeout(()=>{this.chatPanelRef.current&&this.chatPanelRef.current.handleSendMessage().catch(e=>{console.error("[AgentPanel] Failed to send message automatically:",e)})},100)):console.error("[AgentPanel] ChatPanel ref not available")}sendNotebookMessage(e){this.chatPanelRef.current?(this.chatPanelRef.current.setInputMode&&this.chatPanelRef.current.setInputMode("simple"),this.chatPanelRef.current.sendChatMessage({displayContent:`노트북 ${e}`,clearInput:!0,attachActiveNotebook:!0})):console.error("[AgentPanel] ChatPanel ref not available")}analyzeNotebook(e,t){if(console.log("[AgentPanel] analyzeNotebook called with",e.length,"cells"),!this.chatPanelRef.current)return console.error("[AgentPanel] ChatPanel ref not available"),void t();this.chatPanelRef.current.setInputMode&&this.chatPanelRef.current.setInputMode("simple");const n=e.length,a=e.filter(e=>e.output&&(e.output.includes("Error")||e.output.includes("Traceback")||e.output.includes("Exception"))).length,r=e.filter(e=>e.imports&&e.imports.length>0).length,s=e.reduce((e,t)=>t.imports?e+t.imports.filter(e=>e.isLocal).length:e,0),o=e._moduleSummary||{},l=e._crossCellDeps||[],i=Object.keys(o).length,d=new Set;let u=`다음은 저장하기 전의 Jupyter 노트북 전체 내용입니다.\n\n## 노트북 요약\n- 전체 셀 수: ${n}개\n- 에러가 있는 셀: ${a}개\n- Import가 있는 셀: ${r}개\n- 로컬 모듈 import: ${s}개 (소스 코드 포함: ${i}개)\n- 셀 간 의존 관계: ${l.length}개\n\n## 전체 셀 내용\n\n`;e.forEach((e,t)=>{if(u+=`### 셀 ${t+1} (ID: ${e.id})\n\`\`\`python\n${e.content}\n\`\`\`\n`,e.output){const t=e.output.replace(/Out\[\d+\]/g,"Out[...]").replace(/In\[\d+\]/g,"In[...]").replace(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?/g,"[TIMESTAMP]").replace(/[ \t]+$/gm,"");u+=`\n**실행 결과:**\n\`\`\`\n${t}\n\`\`\`\n`}if(e.imports&&e.imports.length>0&&(u+="\n**Imports:**\n",e.imports.forEach(e=>{u+=`- \`${e.module}\` (${e.isLocal?"로컬":"표준 라이브러리"})\n`})),e.localModuleSources&&Object.keys(e.localModuleSources).length>0)for(const[t,n]of Object.entries(e.localModuleSources))d.has(t)||(u+=`\n**로컬 모듈 \`${t}\` 소스:**\n\`\`\`python\n${n}\n\`\`\`\n`,d.add(t));u+="\n---\n\n"});const m=this.chatPanelRef.current;(async()=>{const e=await Yt(c.PageConfig.getBaseUrl()),{callPlan:t,perspectives:a,commonRules:r}=nn(u,n,e);m.addAssistantMessage&&m.addAssistantMessage("코드리뷰를 시작합니다. 아래 **4가지 관점**으로 분석합니다.\n\n| 순서 | 섹션 | 설명 |\n|:---:|------|------|\n| 1 | **보안** | 코드 내 취약점 점검 |\n| 2 | **성능개선** | 코드 성능 최적화 |\n| 3 | **코드품질** | 코드 구조, 일관성, 에러 처리, 네이밍 점검 |\n| 4 | **요약** | 1~3을 셀단위로 요약 |\n");for(let e=0;e<t.length;e++){const s=t[e],o=s.perspectiveIndices.map(e=>a[e].prompt).join("\n\n"),l=s.perspectiveIndices.map(e=>a[e].label).join(", "),c=u+"\n## 코드리뷰 요청 사항\n"+`이 요청은 ${t.length}개 호출 중 ${e+1}번째입니다. "${l}" 섹션만 작성하세요.\n다른 섹션(이전 호출에서 이미 분석됨)은 절대 포함하지 마세요.\n\n`+o+"\n"+r,i=`${s.displayLabel} (${n}개 셀) [${e+1}/${t.length}]`;for(let t=0;t<2;t++)try{await m.sendChatMessage({displayContent:i,llmPrompt:c,clearInput:!1,maxTokens:rn,freshConversation:!0});break}catch(n){0===t?(console.warn(`[AgentPanel] Review call ${e+1} failed, retrying in 2s...`,n),await new Promise(e=>setTimeout(e,2e3))):(console.error(`[AgentPanel] Review call ${e+1} failed after retry:`,n),m.addAssistantMessage&&m.addAssistantMessage(`⚠️ **${s.displayLabel}** 분석 중 오류가 발생했습니다. (${n instanceof Error?n.message:"network error"})\n\n다른 섹션은 계속 진행합니다.`))}}m.addAssistantMessage&&m.addAssistantMessage("✅ **코드리뷰가 완료되었습니다.**")})().catch(e=>{console.error("[AgentPanel] Code review failed:",e)}).finally(()=>{console.log("[AgentPanel] Analysis complete, executing onComplete callback"),t()})}analyzeFile(e,t){if(console.log("[AgentPanel] analyzeFile called for",e),!this.chatPanelRef.current)return console.error("[AgentPanel] ChatPanel ref not available"),void t();this.chatPanelRef.current.setInputMode&&this.chatPanelRef.current.setInputMode("simple");const n=this.chatPanelRef.current;(async()=>{const a=await this.apiService.readFile(e);if(!a.success||!a.content)return console.error("[AgentPanel] Failed to read file:",e),void t();const r=e.split(".").pop()||"",s=`다음은 코드리뷰 대상 파일입니다.\n\n## 파일 정보\n- 파일 경로: ${e}\n\n## 파일 내용\n\n\`\`\`${{py:"python",js:"javascript",ts:"typescript",jsx:"jsx",tsx:"tsx",java:"java",sql:"sql",sh:"bash",yaml:"yaml",yml:"yaml",json:"json"}[r]||r}\n${a.content}\n\`\`\`\n`,o=a.content.split("\n").length,l=await Yt(c.PageConfig.getBaseUrl()),{callPlan:i,perspectives:d,commonRules:u}=nn(s,o,l);n.addAssistantMessage&&n.addAssistantMessage("코드리뷰를 시작합니다. 아래 **4가지 관점**으로 분석합니다.\n\n| 순서 | 섹션 | 설명 |\n|:---:|------|------|\n| 1 | **보안** | 코드 내 취약점 점검 |\n| 2 | **성능개선** | 코드 성능 최적화 |\n| 3 | **코드품질** | 코드 구조, 일관성, 에러 처리, 네이밍 점검 |\n| 4 | **요약** | 1~3을 셀단위로 요약 |\n");for(let e=0;e<i.length;e++){const t=i[e],a=t.perspectiveIndices.map(e=>d[e].prompt).join("\n\n"),r=t.perspectiveIndices.map(e=>d[e].label).join(", "),o=s+"\n## 코드리뷰 요청 사항\n"+`이 요청은 ${i.length}개 호출 중 ${e+1}번째입니다. "${r}" 섹션만 작성하세요.\n다른 섹션(이전 호출에서 이미 분석됨)은 절대 포함하지 마세요.\n\n`+a+"\n"+u,l=`${t.displayLabel} [${e+1}/${i.length}]`;for(let a=0;a<2;a++)try{await n.sendChatMessage({displayContent:l,llmPrompt:o,clearInput:!1,maxTokens:rn,freshConversation:!0});break}catch(r){0===a?(console.warn(`[AgentPanel] Review call ${e+1} failed, retrying in 2s...`,r),await new Promise(e=>setTimeout(e,2e3))):(console.error(`[AgentPanel] Review call ${e+1} failed after retry:`,r),n.addAssistantMessage&&n.addAssistantMessage(`⚠️ **${t.displayLabel}** 분석 중 오류가 발생했습니다. (${r instanceof Error?r.message:"network error"})\n\n다른 섹션은 계속 진행합니다.`))}}n.addAssistantMessage&&n.addAssistantMessage("✅ **코드리뷰가 완료되었습니다.**")})().catch(e=>console.error("[AgentPanel] File review failed:",e)).finally(()=>{console.log("[AgentPanel] File analysis complete"),t()})}}function dn(e){return["path","from","to","since","until"].filter(t=>e[t]).map(t=>`${t}=${encodeURIComponent(e[t])}`).join("&")}const un=/^\d{4}-\d{2}-\d{2}$/;function mn(e,t,n){const a=n<0?"-":"+",r=Math.abs(n);return`${e}T${t?"23:59:59":"00:00:00"}${a}${String(Math.floor(r/60)).padStart(2,"0")}:${String(r%60).padStart(2,"0")}`}function pn(e){return`${e.sha.slice(0,8)} · ${e.date.slice(0,10)} · ${e.subject}`}class hn{constructor(e){if(this.resourceUsageCache=null,this.resourceUsageCacheMs=15e3,this.agentPath="agent/langchain",this.codexThreadsListener=null,this.codexProcessListener=null,this.fileDiffListener=null,e)this.baseUrl=e;else{const e=c.PageConfig.getBaseUrl();this.baseUrl=c.URLExt.join(e,"codebuff")}console.log("[ApiService] Base URL initialized:",this.baseUrl)}setAgentEngine(e){this.agentPath="codex"===e?"agent/codex":"agent/langchain"}setCodexThreadsListener(e){this.codexThreadsListener=e}setCodexProcessListener(e){this.codexProcessListener=e}setFileDiffListener(e){this.fileDiffListener=e}async listCodexProcesses(){const e=await fetch(`${this.baseUrl}/agent/codex/processes`,{method:"GET",headers:this.getHeaders(),credentials:"include"});if(!e.ok)throw new Error(`processes ${e.status}`);return e.json()}async gitDiff(e){const t=e?`?workspaceRoot=${encodeURIComponent(e)}`:"",n=await fetch(`${this.baseUrl}/git/diff${t}`,{method:"GET",headers:this.getHeaders(),credentials:"include"});return n.ok?n.json():{success:!1,markdown:`git 변경을 읽지 못했습니다 (HTTP ${n.status}).`}}async gitFileLog(e){const t=await fetch(`${this.baseUrl}/git/file-log?${dn({path:e})}`,{method:"GET",headers:this.getHeaders(),credentials:"include"});return t.ok||400===t.status?t.json():{success:!1,commits:[],error:`git 이력을 읽지 못했습니다 (HTTP ${t.status}).`}}async gitFileDiff(e){const t=await fetch(`${this.baseUrl}/git/file-diff?${dn(e)}`,{method:"GET",headers:this.getHeaders(),credentials:"include"});return t.ok||400===t.status?t.json():{success:!1,diff:"",error:`diff 를 읽지 못했습니다 (HTTP ${t.status}).`}}async killCodexProcess(e){const t=await fetch(`${this.baseUrl}/agent/codex/processes/${encodeURIComponent(e)}/kill`,{method:"POST",headers:this.getHeaders(),credentials:"include"});return t.ok?t.json():null}async readCodexProcessOutput(e,t=200){const n=await fetch(`${this.baseUrl}/agent/codex/processes/${encodeURIComponent(e)}/output?tail=${t}`,{method:"GET",headers:this.getHeaders(),credentials:"include"});if(!n.ok)return null;const a=await n.json();return"string"==typeof a.output?a.output:null}async testCodexConnection(){const e=await fetch(`${this.baseUrl}/agent/codex/test`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({})});return e.ok?e.json():{ok:!1,detail:`HTTP ${e.status}`}}async getCodexHealth(){const e=await fetch(`${this.baseUrl}/agent/codex/health`,{method:"GET",headers:this.getHeaders(),credentials:"include"});return e.ok?e.json():{configured:!1,activeSessions:0}}getCookie(e){const t=`; ${document.cookie}`.split(`; ${e}=`);return 2===t.length&&t.pop()?.split(";").shift()||""}getCsrfToken(){return this.getCookie("_xsrf")}getHeaders(){return{"Content-Type":"application/json","X-XSRFToken":this.getCsrfToken()}}async getResourceUsageSnapshot(){const e=Date.now();if(this.resourceUsageCache&&e-this.resourceUsageCache.timestamp<this.resourceUsageCacheMs)return this.resourceUsageCache.resource;try{const t=await fetch(`${this.baseUrl}/resource-usage`,{method:"GET",credentials:"include"});if(!t.ok)return null;const n=await t.json().catch(()=>({})),a=n?.resource??n,r=a&&"object"==typeof a&&!Array.isArray(a)?a:null;return r&&(this.resourceUsageCache={resource:r,timestamp:e}),r}catch(e){return console.warn("[ApiService] Resource usage fetch failed:",e),null}}async fetchWithKeyRotation(e,t,n){try{const a=await fetch(e,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify(t)});if(a.ok)return a.json();const r=await a.text();let s=n?.defaultErrorMessage||"API 요청 실패";try{const e=JSON.parse(r);s=e.detail||e.error||e.message||s}catch(e){s=r||s}throw new Error(s)}catch(e){const t=e instanceof Error?e.message:String(e);throw e instanceof Error?e:new Error(t)}}async sendMessage(e){return console.log("[ApiService] sendMessage request"),this.fetchWithKeyRotation(`${this.baseUrl}/chat/message`,e,{defaultErrorMessage:"메시지 전송 실패"})}async sendChatStream(e,t,n,a,r){await this.sendChatStreamInternal(e,t,n,a,r)}async sendChatStreamInternal(e,t,n,a,r){const s=await fetch(`${this.baseUrl}/chat/stream`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify(e),signal:a});if(!s.ok){const e=await s.text();throw new Error(`Failed to send chat message: ${e}`)}const o=s.body?.getReader();if(!o)throw new Error("Response body is not readable");const l=new TextDecoder;let c="";try{for(;;){const{done:e,value:a}=await o.read();if(e)break;c+=l.decode(a,{stream:!0});const s=c.split("\n");c=s.pop()||"";for(const e of s)if(e.startsWith("data: "))try{const a=JSON.parse(e.slice(6));if(a.error){const e=new Error(a.error);throw a.gatewayReason&&(e.gatewayReason=a.gatewayReason),e}if("input_masked"===a.type){t("__input_masked__:"+JSON.stringify({maskedText:a.masked_text,detectedTypes:a.detected_types||[]}));continue}a.warning&&t("__warning__:"+a.warning),a.status_clear&&r&&r({status:"__clear__",icon:""}),a.status&&r&&(a.icon?r({status:a.status,icon:a.icon}):r(a.status)),a.content_clear&&t("__content_clear__"),a.tool_processing&&t("__tool_processing__"),a.tool_processing_end&&t("__tool_processing_end__"),a.summarizing&&t("__summarizing__"),a.content&&(t(a.content),await new Promise(e=>setTimeout(e,0))),a.conversationId&&n&&n({conversationId:a.conversationId})}catch(e){if(!(e instanceof SyntaxError))throw e}}}finally{o.releaseLock()}}async cancelChat(e){const t=await fetch(`${this.baseUrl}/chat/cancel`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({conversationId:e})});if(!t.ok)throw new Error(await t.text());return t.json()}async getAgentProviders(){const e=await fetch(c.URLExt.join(this.baseUrl,"agent","providers"),{headers:this.getHeaders(),credentials:"include"});if(!e.ok)throw new Error(`Provider discovery 실패: ${e.status}`);return(await e.json()).providers||[]}async registerAgentProvider(e,t,n){const a=await fetch(c.URLExt.join(this.baseUrl,"agent","providers"),{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({name:e,port:t,owner:n})});if(!a.ok){const e=await a.text();let t=e;try{t=JSON.parse(e).error||e}catch{}throw new Error(t)}return(await a.json()).provider}async runMcpSelftest(e,t,n){const a=await fetch(c.URLExt.join(this.baseUrl,"mcp","selftest"),{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({transport:e,port:t,call:n})});if(!a.ok){const e=await a.text();let t=e;try{t=JSON.parse(e).error||e}catch{}throw new Error(t)}return a.json()}async unregisterAgentProvider(e){const t=`${c.URLExt.join(this.baseUrl,"agent","providers")}?name=${encodeURIComponent(e)}`,n=await fetch(t,{method:"DELETE",headers:this.getHeaders(),credentials:"include"});if(!n.ok){const e=await n.text();throw new Error(`Provider 해제 실패: ${e}`)}return!!(await n.json()).removed}async sendProviderStream(e,t,n,a,r,s){const o=c.URLExt.join(this.baseUrl,"agent","provider",e,"stream"),l=await fetch(o,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({message:t.message,thread_id:t.threadId}),signal:r});if(!l.ok){const t=await l.text();throw new Error(`'${e}' 에이전트 호출 실패: ${t}`)}const i=l.body?.getReader();if(!i)throw new Error("Response body is not readable");const d=new TextDecoder;let u="",m="";try{for(;;){const{done:e,value:t}=await i.read();if(e)break;u+=d.decode(t,{stream:!0});const r=u.split("\n");u=r.pop()||"";for(const e of r){if(e.startsWith("event: ")){m=e.slice(7).trim();continue}if(!e.startsWith("data: "))continue;let t;try{t=JSON.parse(e.slice(6))}catch{continue}switch(m){case"status":t.status&&s&&s(t.status);break;case"token":t.content&&(n(t.content),await new Promise(e=>setTimeout(e,0)));break;case"complete":a&&a({threadId:t.thread_id});break;case"error":throw new Error(`${t.error||"응답 오류"}${t.owner?` (담당: ${t.owner})`:""}`)}}}}finally{i.releaseLock()}}async sendAgentV2Stream(e,t,n,a,r,s,o,l,c,i,d){await this.sendAgentV2StreamInternal(e,t,n,a,r,s,o,l,c,i,d)}async sendMessageStream(e,t,n,a,r,s,o,l,c,i,d){return this.sendAgentV2Stream(e,t,n,a,r,s,o,l,c,i,d)}async sendAgentV2StreamInternal(e,t,n,a,r,s,o,l,c,i,d){const u=await this.getResourceUsageSnapshot(),m=u&&e.llmConfig?{...e.llmConfig,resourceContext:u}:e.llmConfig,p={request:e.message,threadId:i,notebookContext:e.context?{notebook_path:e.context.notebookPath,cell_count:0,imported_libraries:[],defined_variables:[],recent_cells:e.context.selectedCells?.map(e=>({source:e}))||[]}:void 0,llmConfig:m,workspaceRoot:e.llmConfig?.workspaceRoot||".",...!1===e.fileMentions?{fileMentions:!1}:{},agentMode:e.agentMode||"multi",uxSessionId:Ze.c.getInstance().getSessionId()},h=JSON.stringify(p);console.log("[ApiService] Sending langchain request:",{messageLength:e.message.length,bodyLength:h.length,threadId:i});const g=await fetch(`${this.baseUrl}/${this.agentPath}/stream`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:h,signal:d});if(!g.ok){const e=await g.text();throw new Error(`Failed to send message: ${e}`)}const f=g.body?.getReader();if(!f)throw new Error("Response body is not readable");const b=new TextDecoder;let v="",y=!1;try{for(;;){const{done:e,value:i}=await f.read();if(e)break;v+=b.decode(i,{stream:!0});const d=v.split("\n");v=d.pop()||"";let u="";for(const e of d)if(e.startsWith("event: "))u=e.slice(7).trim();else if(e.startsWith("data: "))try{const i=JSON.parse(e.slice(6));if("todos"===u&&i.todos&&s){console.log("[ApiService] Received todos:",i.todos.length,"items"),s(i.todos),u="";continue}if("debug_clear"===u&&o){o(),u="";continue}if("codex_threads"===u){this.codexThreadsListener?.(i.threads||[]),u="";continue}if("process"===u){this.codexProcessListener?.(i),u="";continue}if("file_diff"===u){this.fileDiffListener?.(i),t?.(De(i)),u="";continue}if("summary"===u&&void 0!==i.summary){t&&t(JSON.stringify(i)),u="";continue}if("complete"===u||"done"===u||"cancelled"===u)return y=!0,o&&o(),console.log(`[ApiService] ${u} event received, data:`,i),void(c&&i.thread_id?(console.log("[ApiService] Calling onComplete with threadId:",i.thread_id),c({threadId:i.thread_id})):console.log("[ApiService] onComplete not called - onComplete:",!!c,"thread_id:",i.thread_id));if(i.error){a&&a(`오류: ${i.error}`);const e=new Error(i.error);throw i.gatewayReason&&(e.gatewayReason=i.gatewayReason),e}if(i.status&&a&&(void 0!==i.expandable||i.icon||void 0!==i.turn||void 0!==i.step?a({status:i.status,expandable:i.expandable,full_text:i.full_text,icon:i.icon,turn:i.turn,step:i.step,tool_label:i.tool_label}):a(i.status)),i.thread_id&&i.action&&r)return y=!0,console.log("[ApiService] HITL interrupt received:",i.action,"args:",JSON.stringify(i.args||{}).slice(0,200),"currentEventType:",u),void r({threadId:i.thread_id,action:i.action,args:i.args||{},description:i.description||"",actionCount:i.actionCount,autoApprove:i.autoApprove});if(i.content){const e=String(i.content).trim(),n=e.includes('"summary"')&&e.includes('"next_items"');let a=!1;if(!n&&e.includes('"todos"'))try{const t=JSON.parse(e);if(t&&Array.isArray(t.todos)&&t.todos.length>0){const e=t.todos[0];e&&"content"in e&&"status"in e&&(a=!0)}}catch{a=/"todos"\s*:\s*\[\s*\{[^}]*"content"\s*:/.test(e)}a?console.log("[ApiService] Filtered raw todos JSON from display"):t(i.content)}if("tool_call"===u&&i.tool&&l){console.log("[ApiService] Tool call:",i.tool),l({tool:i.tool,code:i.code,content:i.content,command:i.command,timeout:i.timeout}),u="";continue}i.output,i.final_answer&&t(i.final_answer),i.conversationId&&n&&n({conversationId:i.conversationId,messageId:i.messageId,provider:i.metadata?.provider,model:i.metadata?.model}),i.done&&i.metadata&&n&&n({provider:i.metadata.provider,model:i.metadata.model}),u=""}catch(t){if(!(t instanceof SyntaxError))throw t;console.warn("Failed to parse SSE data:",e)}}if(!y)throw new Error("Agent stream terminated unexpectedly")}finally{f.releaseLock(),!y&&o&&(console.warn("[ApiService] Stream ended without proper termination, clearing debug status"),o())}}async resumeAgent(e,t,n,a,r,s,o,l,c,i,d,u,m){const p=await this.getResourceUsageSnapshot(),h={threadId:e,decisions:[{type:t,args:n,feedback:a}],llmConfig:p&&r?{...r,resourceContext:p}:r,workspaceRoot:r?.workspaceRoot||".",uxSessionId:Ze.c.getInstance().getSessionId()};u&&u>1&&(h.actionCount=u);const g=await fetch(`${this.baseUrl}/${this.agentPath}/resume`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify(h),signal:m});if(!g.ok){const e=await g.text();throw new Error(`Failed to resume agent: ${e}`)}const f=g.body?.getReader();if(!f)throw new Error("Response body is not readable");const b=new TextDecoder;let v="",y=!1;try{for(;;){const{done:e,value:t}=await f.read();if(e)break;v+=b.decode(t,{stream:!0});const n=v.split("\n");v=n.pop()||"";let a="";for(const e of n)if(e.startsWith("event: "))a=e.slice(7).trim();else if(e.startsWith("data: "))try{const t=JSON.parse(e.slice(6));if(t.error)throw o&&o(`오류: ${t.error}`),new Error(t.error);if("todos"===a&&t.todos&&c){console.log("[ApiService] Received todos (resume):",t.todos.length,"items"),c(t.todos),a="";continue}if("debug_clear"===a&&i){i(),a="";continue}if("process"===a){this.codexProcessListener?.(t),a="";continue}if("file_diff"===a){this.fileDiffListener?.(t),s?.(De(t)),a="";continue}if("summary"===a&&void 0!==t.summary){s&&s(JSON.stringify(t)),a="";continue}if("complete"===a||"done"===a||"cancelled"===a)return y=!0,void(i&&i());if(t.status&&o&&(void 0!==t.expandable||t.icon||void 0!==t.turn||void 0!==t.step?o({status:t.status,expandable:t.expandable,full_text:t.full_text,icon:t.icon,turn:t.turn,step:t.step,tool_label:t.tool_label}):o(t.status)),t.thread_id&&t.action&&l)return y=!0,void l({threadId:t.thread_id,action:t.action,args:t.args||{},description:t.description||"",actionCount:t.actionCount,autoApprove:t.autoApprove});if(t.content&&s){const e=String(t.content).trim(),n=e.includes('"summary"')&&e.includes('"next_items"');let a=!1;if(!n&&e.includes('"todos"'))try{const t=JSON.parse(e);if(t&&Array.isArray(t.todos)&&t.todos.length>0){const e=t.todos[0];e&&"content"in e&&"status"in e&&(a=!0)}}catch{a=/"todos"\s*:\s*\[\s*\{[^}]*"content"\s*:/.test(e)}a?console.log("[ApiService] Filtered raw todos JSON from display"):s(t.content)}if("tool_call"===a&&t.tool&&d){d({tool:t.tool,code:t.code,content:t.content,command:t.command,timeout:t.timeout}),a="";continue}a=""}catch(e){if(!(e instanceof SyntaxError))throw e}}if(!y)throw new Error("Agent resume stream terminated unexpectedly")}finally{f.releaseLock(),!y&&i&&(console.warn("[ApiService] Stream ended without proper termination, clearing debug status"),i())}}async cancelAgent(e){const t=await fetch(`${this.baseUrl}/${this.agentPath}/cancel`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({thread_id:e,threadId:e})});if(!t.ok){const e=await t.text();return console.warn("[ApiService] Failed to cancel agent:",e),{status:"error",message:e}}return t.json()}async resetAgent(e){const t=await fetch(`${this.baseUrl}/agent/langchain/reset`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({thread_id:e})});if(!t.ok){const e=await t.text();return console.warn("[ApiService] Failed to reset agent:",e),{status:"error",message:e}}return t.json()}async executeCommand(e,t,n,a,r){const s=await fetch(`${this.baseUrl}/execute-command`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({command:e,timeout:t,cwd:n,stdin:a,workspaceRoot:r})}),o=await s.json().catch(()=>({}));if(!s.ok){const e=o.error||"Failed to execute command";throw new Error(e)}return o}async executeCommandStream(e,t){const n=await fetch(`${this.baseUrl}/execute-command/stream`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({command:e,timeout:t?.timeout,cwd:t?.cwd,stdin:t?.stdin,workspaceRoot:t?.workspaceRoot})});if(!n.ok){const e=(await n.json().catch(()=>({}))).error||"Failed to execute command";throw new Error(e)}const a=n.body?.getReader();if(!a)throw new Error("Response body is not readable");const r=new TextDecoder;let s="",o=null,l=null;try{for(;;){const{done:e,value:n}=await a.read();if(e)break;s+=r.decode(n,{stream:!0});const c=s.split("\n");s=c.pop()||"";let i="";for(const e of c){if(e.startsWith("event: ")){i=e.slice(7).trim();continue}if(!e.startsWith("data: "))continue;let n;try{n=JSON.parse(e.slice(6))}catch(e){continue}if("output"!==i)if("error"!==i){if("result"===i)return o=n,o;i=""}else l=n.error||"Command execution failed",i="";else"string"==typeof n.text&&t?.onOutput&&t.onOutput({stream:"stderr"===n.stream?"stderr":"stdout",text:n.text}),i=""}}}finally{a.releaseLock()}if(l)throw new Error(l);if(!o)throw new Error("No command result received");return o}async readFile(e,t){const n=await fetch(`${this.baseUrl}/read-file`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({path:e,encoding:t?.encoding||"utf-8",cwd:t?.cwd,workspaceRoot:t?.workspaceRoot})}),a=await n.json().catch(()=>({}));return n.ok?a:{success:!1,error:a.error||"Failed to read file"}}async writeFile(e,t,n){const a=await fetch(`${this.baseUrl}/write-file`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({path:e,content:t,encoding:n?.encoding,overwrite:n?.overwrite,cwd:n?.cwd,workspaceRoot:n?.workspaceRoot})}),r=await a.json().catch(()=>({}));if(!a.ok){const e=r.error||"Failed to write file";throw new Error(e)}return r}async searchWorkspace(e){const t=await fetch(`${this.baseUrl}/search-workspace`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({pattern:e.pattern,file_types:e.file_types||["*.py","*.ipynb"],path:e.path||".",max_results:e.max_results||50,case_sensitive:e.case_sensitive||!1,workspaceRoot:e.workspaceRoot})}),n=await t.json().catch(()=>({}));if(!t.ok){const e=n.error||"Failed to search workspace";throw new Error(e)}return n}async searchNotebookCells(e){const t=await fetch(`${this.baseUrl}/search-notebook-cells`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({pattern:e.pattern,notebook_path:e.notebook_path,cell_type:e.cell_type,max_results:e.max_results||30,case_sensitive:e.case_sensitive||!1,workspaceRoot:e.workspaceRoot})}),n=await t.json().catch(()=>({}));if(!t.ok){const e=n.error||"Failed to search notebook cells";throw new Error(e)}return n}async checkResource(e){const t=await fetch(`${this.baseUrl}/check-resource`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify({files:e.files||[],dataframes:e.dataframes||[],file_size_command:e.file_size_command||"",dataframe_check_code:e.dataframe_check_code||"",workspaceRoot:e.workspaceRoot})}),n=await t.json().catch(()=>({}));if(!t.ok){if(404===t.status)return{success:!1,files:[],dataframes:[],error:"Resource check endpoint is not available on this Jupyter server."};const e=n.error||"Failed to check resources";throw new Error(e)}return n}async saveConfig(e){const t=await fetch(`${this.baseUrl}/config`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify(e)});if(!t.ok){const e=await t.json().catch(()=>({message:"Failed to save configuration"}));throw new Error(e.message||"Failed to save configuration")}}async getConfig(){const e=await fetch(`${this.baseUrl}/config`);if(!e.ok)throw new Error("Failed to load configuration");return e.json()}async getUserConfig(){const e=await fetch(`${this.baseUrl}/config/user`,{method:"GET",credentials:"include"});if(!e.ok)throw new Error("Failed to load user configuration");return e.json()}async updateUserConfig(e){const t=await fetch(`${this.baseUrl}/config/user`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify(e)});if(!t.ok){const e=await t.text();let n=e;try{n=JSON.parse(e).error||e}catch{}throw new Error(n)}return t.json()}async getAgentsMdStatus(e){const t=e?`?path=${encodeURIComponent(e)}`:"",n=await fetch(`${this.baseUrl}/config/agents-md-status${t}`,{method:"GET",credentials:"include"});if(!n.ok)throw new Error("Failed to get codebuff status");return n.json()}async getDirectoryCompletions(e){const t=await fetch(`${this.baseUrl}/files/directories?prefix=${encodeURIComponent(e)}`,{method:"GET",credentials:"include"});if(!t.ok)throw new Error("Failed to complete directories");return(await t.json()).directories||[]}async getConfigStatus(){const e=await fetch(`${this.baseUrl}/config/status`,{method:"GET",credentials:"include"});if(!e.ok)throw new Error("Failed to get config status");return e.json()}async getSkillsStatus(){const e=await fetch(`${this.baseUrl}/skills/status`,{method:"GET",credentials:"include"});if(!e.ok)throw new Error("Failed to get skills status");return e.json()}async getStatus(){const e=await fetch(`${this.baseUrl}/status`);if(!e.ok)throw new Error("Failed to get status");return e.json()}async getModels(){const e=await fetch(`${this.baseUrl}/models`);if(!e.ok)throw new Error("Failed to load models");return e.json()}async generateExecutionPlan(e,t){return console.log("[ApiService] generateExecutionPlan request:",e),this.fetchWithKeyRotation(`${this.baseUrl}/auto-agent/plan`,e,{onKeyRotation:t,defaultErrorMessage:"계획 생성 실패"})}async refineStepCode(e,t){return console.log("[ApiService] refineStepCode request:",e),this.fetchWithKeyRotation(`${this.baseUrl}/auto-agent/refine`,e,{onKeyRotation:t,defaultErrorMessage:"코드 수정 실패"})}async replanExecution(e,t){return console.log("[ApiService] replanExecution request:",e),this.fetchWithKeyRotation(`${this.baseUrl}/auto-agent/replan`,e,{onKeyRotation:t,defaultErrorMessage:"계획 재수립 실패"})}async validateCode(e){return console.log("[ApiService] validateCode request:",e),this.fetchWithKeyRotation(`${this.baseUrl}/auto-agent/validate`,e,{defaultErrorMessage:"코드 검증 실패"})}async reflectOnExecution(e,t){return console.log("[ApiService] reflectOnExecution request:",e),this.fetchWithKeyRotation(`${this.baseUrl}/auto-agent/reflect`,e,{onKeyRotation:t,defaultErrorMessage:"Reflection 실패"})}async verifyState(e){return console.log("[ApiService] verifyState request:",e),this.fetchWithKeyRotation(`${this.baseUrl}/auto-agent/verify-state`,e,{defaultErrorMessage:"상태 검증 실패"})}async generateExecutionPlanStream(e,t,n){const a=await fetch(`${this.baseUrl}/auto-agent/plan/stream`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)});if(!a.ok){const e=await a.text();throw new Error(`Failed to generate plan: ${e}`)}const r=a.body?.getReader();if(!r)throw new Error("Response body is not readable");const s=new TextDecoder;let o="",l=null;try{for(;;){const{done:e,value:a}=await r.read();if(e)break;o+=s.decode(a,{stream:!0});const c=o.split("\n");o=c.pop()||"";for(const e of c)if(e.startsWith("data: "))try{const a=JSON.parse(e.slice(6));if(a.error)throw new Error(a.error);a.reasoning&&n&&n(a.reasoning),a.plan&&(t(a.plan),a.done&&(l=a.plan))}catch(e){if(!(e instanceof SyntaxError))throw e}}}finally{r.releaseLock()}if(!l)throw new Error("No plan received from server");return l}async resolveFile(e){console.log("[ApiService] resolveFile request:",e);const t=await fetch(`${this.baseUrl}/file/resolve`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify(e)});if(!t.ok){const e=await t.text();throw new Error(`Failed to resolve file: ${e}`)}return t.json()}async selectFile(e){console.log("[ApiService] selectFile request:",e);const t=await fetch(`${this.baseUrl}/file/select`,{method:"POST",headers:this.getHeaders(),credentials:"include",body:JSON.stringify(e)});if(!t.ok){const e=await t.text();throw new Error(`Failed to select file: ${e}`)}return t.json()}async getContextAutocomplete(e){const t=new URLSearchParams;e?.partialCommand&&t.append("partialCommand",e.partialCommand),e?.engine&&t.append("engine",e.engine);const n=`${this.baseUrl}/context/autocomplete${t.toString()?"?"+t.toString():""}`;console.log("[ApiService] getContextAutocomplete:",n);const a=await fetch(n,{method:"GET",headers:this.getHeaders(),credentials:"include"});if(!a.ok){const e=await a.text();throw new Error(`Failed to get autocomplete options: ${e}`)}return a.json()}async listContextProviders(){const e=await fetch(`${this.baseUrl}/context/providers`,{method:"GET",headers:this.getHeaders(),credentials:"include"});if(!e.ok){const t=await e.text();throw new Error(`Failed to list context providers: ${t}`)}return(await e.json()).providers}}const gn=["Cloud개발1팀"];class fn{constructor(){this.userInfo=this.loadUserInfo()}loadUserInfo(){const e=c.PageConfig.getOption("JUPYTERHUB_USER")||"",t=c.PageConfig.getOption("HDSP_USER_TEAM")||null,n={username:e,team:t,isAllowed:this.checkAccess(t)};return console.log("[AccessControl] User info loaded:",{username:n.username,team:n.team,isAllowed:n.isAllowed}),n}checkAccess(e){if(!e)return console.log("[AccessControl] No team claim set, allowing by default (dev mode)"),!0;const t=gn.includes(e);return console.log(`[AccessControl] Team '${e}' access check: ${t?"ALLOWED":"DENIED"}`),t}isSidebarAllowed(){return this.userInfo.isAllowed}getUserInfo(){return{...this.userInfo}}getUsername(){return this.userInfo.username}getTeam(){return this.userInfo.team}}let bn=null;const vn="codebuff:toggle-sidebar",yn={id:"codebuff:sidebar",autoStart:!0,requires:[],optional:[a.ILayoutRestorer,r.ICommandPalette,s.INotebookTracker,o.IConsoleTracker,l.IRenderMimeRegistry],activate:(e,t,n,a,s,o)=>{console.log("[SidebarPlugin] Activating Jupyter Agent Sidebar");try{const l=(bn||(bn=new fn),bn);if(!l.isSidebarAllowed()){const e=l.getUserInfo();return console.log("[SidebarPlugin] Sidebar hidden for team:",e.team),void console.log("[SidebarPlugin] User:",e.username,"is not in allowed teams list")}console.log("[SidebarPlugin] Access granted for user:",l.getUsername());const i=new hn,d=new cn(i,a,s);if(t){const e=new r.WidgetTracker({namespace:"codebuff"});e.add(d),t.restore(e,{command:vn,name:()=>"codebuff"})}e.shell.add(d,"right",{rank:100}),e.commands.addCommand(vn,{label:"Codebuff Agent 사이드바 토글",caption:"Codebuff Agent 패널 표시/숨기기",execute:()=>{d.isVisible?d.close():e.shell.activateById(d.id)}}),n&&n.addItem({command:vn,category:"Codebuff Agent",args:{}}),window._codebuffAgentPanel=d,window._codebuffOpenFile=async(t,n,a)=>{const r=await e.commands.execute("docmanager:open",{path:t});return n&&r?.context?.ready&&(await r.context.ready,function(e,t,n){const a=e?.content?.editor;if(!a||"function"!=typeof a.setCursorPosition)return!1;const r=Math.max(0,(a.lineCount||1)-1),s=Math.min(Math.max(0,t-1),r),o=a.getLine?.(s)?.length??1/0,l={line:s,column:Math.min(Math.max(0,(n||1)-1),o)};a.setCursorPosition(l),a.revealPosition(l),a.focus()}(r,n,a)),r},window._codebuffServerRoot=c.PageConfig.getOption("serverRoot"),o&&(window._codebuffRenderMimeRegistry=o,console.log("[SidebarPlugin] RenderMime registry stored for markdown rendering")),console.log("[SidebarPlugin] Codebuff Agent Sidebar activated successfully")}catch(e){console.error("[SidebarPlugin] Failed to activate:",e)}}};var En,kn;!function(e){e.EXPLAIN="explain",e.FIX="fix",e.CUSTOM_PROMPT="custom_prompt"}(En||(En={})),function(e){e.CELL_ACTION="codebuff:cell-action",e.CONFIG_CHANGED="codebuff:config-changed",e.MESSAGE_SENT="codebuff:message-sent",e.MESSAGE_RECEIVED="codebuff:message-received"}(kn||(kn={}));const wn={id:"codebuff:cell-buttons",autoStart:!0,requires:[s.INotebookTracker],activate:(e,t)=>{console.log("[CellButtonsPlugin] Activated"),window.jupyterapp=e,t.widgetAdded.connect((e,t)=>{console.log("[CellButtonsPlugin] Notebook widget added:",t.id),t.sessionContext.ready.then(()=>{xn(t)}).catch(e=>{console.error("[CellButtonsPlugin] Error waiting for session:",e)})}),t.currentWidget&&xn(t.currentWidget),t.currentChanged.connect((e,t)=>{t&&xn(t)})}};function xn(e){const t=e.content;setTimeout(()=>{Sn(t,e),setTimeout(()=>{Sn(t,e)},500)},200);const n=()=>{setTimeout(()=>{Sn(t,e)},100)};try{t.model?.cells.changed.disconnect(n)}catch{}t.model?.cells.changed.connect(n),e.node.addEventListener("paste",e=>{const n=e.clipboardData?.getData("text/plain")?.trim();if(!n)return;const a=window._codebuffAgentCopiedCodes;if(!a||!a.has(n))return;const r=t.activeCell;if(r?.model){try{const e=r.model.metadata;"function"==typeof e.set?e.set("codebuff_source","pasted"):e.codebuff_source="pasted"}catch{}Ze.c.getInstance().trackClick("code_paste_from_agent",{code_length:n.length,code_lines:n.split("\n").length})}},!0)}function Sn(e,t){for(let t=0;t<e.widgets.length;t++)jn(e.widgets[t])}const _n='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <path d="M9 18h6"/>\n <path d="M10 22h4"/>\n <path d="M15.09 14c.18-.98.65-1.74 1.41-2.5A4.65 4.65 0 0 0 18 8 6 6 0 0 0 6 8c0 1 .23 2.23 1.5 3.5A4.61 4.61 0 0 1 8.91 14"/>\n </svg>',Cn='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>\n </svg>',Nn='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\n <circle cx="12" cy="12" r="10"/>\n <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/>\n <path d="M12 17h.01"/>\n </svg>';function jn(e,t){if(!e||!e.model)return;if("code"!==e.model.type)return;const n=e.node;if(!n||!n.classList.contains("jp-CodeCell"))return;const a=n.querySelector(".jp-cell-toolbar");a&&$n(a,e),function(e){if("code"!==e.model.type)return;const t=e.node;if(t.hasAttribute("data-codebuff-error-watcher"))return;t.setAttribute("data-codebuff-error-watcher","true");const n=e,a=n.model?.outputs;a&&(a.changed.connect(()=>{Bn(e)}),a.length>0&&Bn(e))}(e),n.hasAttribute("data-codebuff-observer")||(n.setAttribute("data-codebuff-observer","true"),new MutationObserver(t=>{for(const n of t)for(const t of Array.from(n.addedNodes))if(t instanceof HTMLElement){const n=t.classList.contains("jp-cell-toolbar")?t:t.querySelector(".jp-cell-toolbar");n&&$n(n,e)}}).observe(n,{childList:!0,subtree:!0}))}function $n(e,t){if(e.querySelector(".jp-codebuff-toolbar-btn"))return;const n=document.createElement("div");n.className="jp-Toolbar-item jp-codebuff-separator",n.style.cssText="\n width: 1px;\n height: 20px;\n background: var(--jp-border-color1, #ccc);\n margin: 0 4px;\n ";const a=Tn(_n,"코드 설명 (Explain)",()=>{An(En.EXPLAIN,t)}),r=Tn(Nn,"질문하기 (Ask)",()=>{An(En.CUSTOM_PROMPT,t)}),s=e.firstChild;e.insertBefore(r,s),e.insertBefore(a,s),e.insertBefore(n,s)}function Tn(e,t,n){const a=document.createElement("div");a.className="lm-Widget jp-CommandToolbarButton jp-Toolbar-item jp-codebuff-toolbar-btn";const r=document.createElement("button");return r.className="jp-ToolbarButtonComponent jp-codebuff-action-btn",r.title=t,r.setAttribute("aria-label",t),r.innerHTML=e,r.onclick=e=>{e.preventDefault(),e.stopPropagation(),n()},r.style.cssText="\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n color: var(--jp-ui-font-color1, #333);\n transition: background 0.1s ease;\n ",r.addEventListener("mouseenter",()=>{r.style.background="var(--jp-layout-color2, #e0e0e0)"}),r.addEventListener("mouseleave",()=>{r.style.background="transparent"}),a.appendChild(r),a}async function An(e,t){const n=t?.model?.sharedModel?.getSource()||"";if(!n.trim())return void Fn("셀 내용이 비어있습니다.","warning");const a=In(t),r={[En.EXPLAIN]:"cell_explain",[En.FIX]:"cell_fix",[En.CUSTOM_PROMPT]:"cell_question"}[e];if(r&&Ze.c.getInstance().trackClick(r,{cell_index:a,prompt:n}),e===En.CUSTOM_PROMPT)!function(e){const t=e?.model?.sharedModel?.getSource()||"",n=In(e),a=Rn(e);console.log("커스텀 프롬프트 다이얼로그 표시",n,a),qn("jp-agent-custom-prompt-dialog");const r=Dn("jp-agent-custom-prompt-dialog"),s=On("500px");s.innerHTML=`\n <div style="margin-bottom: 20px;">\n <h3 style="margin: 0 0 8px 0; color: var(--codebuff-dialog-title, #424242); font-size: 16px; font-weight: 500;">\n 셀에 대해 질문하기\n </h3>\n <p style="margin: 0; color: var(--codebuff-dialog-muted, #757575); font-size: 13px;">\n 물리적 위치: 셀 ${n+1}번째 (위에서 아래로 카운트)\n </p>\n </div>\n <div style="margin-bottom: 20px;">\n <textarea class="jp-agent-custom-prompt-input"\n placeholder="이 셀에 대해 질문할 내용을 입력하세요..."\n style="\n width: 100%;\n min-height: 100px;\n padding: 12px;\n border: 1px solid var(--codebuff-dialog-input-border, #d1d5db);\n border-radius: 4px;\n font-size: 14px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: var(--codebuff-dialog-input-bg, Field);\n color: var(--codebuff-dialog-title, FieldText);\n resize: vertical;\n box-sizing: border-box;\n "\n ></textarea>\n </div>\n <div style="display: flex; gap: 12px; justify-content: flex-end;">\n <button class="jp-agent-custom-prompt-cancel-btn" style="\n background: transparent;\n color: var(--codebuff-dialog-text, #616161);\n border: 1px solid var(--codebuff-dialog-input-border, #d1d5db);\n border-radius: 3px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n ">취소</button>\n <button class="jp-agent-custom-prompt-submit-btn" style="\n background: transparent;\n color: #1976d2;\n border: 1px solid #1976d2;\n border-radius: 3px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n ">질문</button>\n </div>\n `,r.appendChild(s),document.body.appendChild(r);const o=s.querySelector(".jp-agent-custom-prompt-input");setTimeout(()=>o?.focus(),100);const l=s.querySelector(".jp-agent-custom-prompt-cancel-btn"),i=s.querySelector(".jp-agent-custom-prompt-submit-btn");l.addEventListener("click",()=>{r.remove()}),l.addEventListener("mouseenter",()=>{l.style.background="var(--codebuff-dialog-hover, #f5f5f5)",l.style.borderColor="var(--codebuff-dialog-input-border-hover, #9ca3af)"}),l.addEventListener("mouseleave",()=>{l.style.background="transparent",l.style.borderColor="var(--codebuff-dialog-input-border, #d1d5db)"});const d=async()=>{const s=o?.value.trim()||"";if(!s)return void Fn("질문 내용을 입력해주세요.","warning");r.remove();const l=Pn(e),i=`${n}번째 셀: ${s}`,d=en((await Yt(c.PageConfig.getBaseUrl())).cell_question_prompt,{QUESTION:s,CELL_CONTENT:t,OUTPUT_SECTION:tn(l)}),u=window._codebuffAgentPanel;if(u){const e=window.jupyterapp;if(e&&e.shell.activateById(u.id),u.addCellActionMessage){const e=n-1;u.addCellActionMessage(En.CUSTOM_PROMPT,t,i,d,a,e)}}};i.addEventListener("click",d),i.addEventListener("mouseenter",()=>{i.style.background="rgba(25, 118, 210, 0.1)"}),i.addEventListener("mouseleave",()=>{i.style.background="transparent"}),o?.addEventListener("keydown",e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),d())}),r.addEventListener("click",e=>{e.target===r&&r.remove()});const u=e=>{"Escape"===e.key&&(r.remove(),document.removeEventListener("keydown",u))};document.addEventListener("keydown",u)}(t);else{const r=Pn(t);let s="",o="";switch(e){case En.EXPLAIN:s=`셀 ${a}번째: 설명 요청`,o="이 셀의 코드 설명을 보시겠습니까?";break;case En.FIX:{const e=Mn(t);s=e?`셀 ${a}번째: 에러 수정 요청`:`셀 ${a}번째: 개선 제안 요청`,o=e?"이 셀의 에러를 분석하고 수정 방법을 제안받으시겠습니까?":"이 셀의 코드 개선 제안을 받으시겠습니까?";break}}const l=await function(e,t){return new Promise(n=>{qn("jp-agent-confirm-dialog");const a=Dn("jp-agent-confirm-dialog"),r=On();r.innerHTML=`\n <div style="margin-bottom: 20px;">\n <h3 style="margin: 0 0 12px 0; color: var(--codebuff-dialog-title, #424242); font-size: 16px; font-weight: 500;">\n ${zn(e)}\n </h3>\n <p style="margin: 0; color: var(--codebuff-dialog-text, #616161); font-size: 14px; line-height: 1.5;">\n ${zn(t)}\n </p>\n </div>\n <div style="display: flex; gap: 12px; justify-content: flex-end;">\n <button class="jp-agent-confirm-cancel-btn" style="\n background: transparent;\n color: var(--codebuff-dialog-text, #616161);\n border: 1px solid var(--codebuff-dialog-input-border, #d1d5db);\n border-radius: 3px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n ">취소</button>\n <button class="jp-agent-confirm-submit-btn" style="\n background: #1976d2;\n color: white;\n border: 1px solid #1976d2;\n border-radius: 3px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n ">확인</button>\n </div>\n `,a.appendChild(r),document.body.appendChild(a);const s=r.querySelector(".jp-agent-confirm-cancel-btn"),o=r.querySelector(".jp-agent-confirm-submit-btn");s.addEventListener("click",()=>{a.remove(),n(!1)}),s.addEventListener("mouseenter",()=>{s.style.background="var(--codebuff-dialog-hover, #f5f5f5)"}),s.addEventListener("mouseleave",()=>{s.style.background="transparent"}),o.addEventListener("click",()=>{o.disabled=!0,o.textContent="처리 중...",setTimeout(()=>{a.remove(),n(!0)},100)}),o.addEventListener("mouseenter",()=>{o.disabled||(o.style.background="#1565c0")}),o.addEventListener("mouseleave",()=>{o.disabled||(o.style.background="#1976d2")});const l=e=>{"Escape"===e.key&&(a.remove(),document.removeEventListener("keydown",l),n(!1))};document.addEventListener("keydown",l),a.addEventListener("click",e=>{e.target===a&&(a.remove(),document.removeEventListener("keydown",l),n(!1))})})}(s,o);if(l){const s=Mn(t);await async function(e,t,n,a,r,s){const o=window._codebuffAgentPanel;if(!o)return void console.error("[CellButtonsPlugin] Agent panel not found. Make sure sidebar plugin is loaded.");const l=Rn(t),i=window.jupyterapp;i&&i.shell.activateById(o.id);let d="",u="";const m=await Yt(c.PageConfig.getBaseUrl());switch(e){case En.EXPLAIN:d=`${a}번째 셀: 설명 요청`,u=en(m.cell_explain_prompt,{CELL_CONTENT:n});break;case En.FIX:console.log("[CellButtonsPlugin] FIX action:",{hasError:s,cellOutputLength:r.length}),s?(d=`${a}번째 셀: 에러 수정 요청`,u=en(m.cell_fix_prompt,{CELL_CONTENT:n,ERROR_OUTPUT:Ln(r)})):(d=`${a}번째 셀: 개선 제안 요청`,u=en(m.cell_improve_prompt,{CELL_CONTENT:n,OUTPUT_SECTION:tn(r?Ln(r):"")}))}if(o.addCellActionMessage){const t=a-1;o.addCellActionMessage(e,n,d,u,l,t)}}(e,t,n,a,r,s)}}}function In(e){const t=window.jupyterapp,n=t?.shell?.currentWidget?.content;if(!n)return-1;const a=n.widgets;for(let t=0;t<a.length;t++)if(a[t]===e)return t+1;return-1}function Pn(e){if(!e?.model||"code"!==e.model.type)return"";const t=e,n=t.model?.outputs;if(!n||0===n.length)return"";const a=[];for(let e=0;e<n.length;e++){const t=n.get(e),r=t.type;if("stream"===r){const e=t.text;Array.isArray(e)?a.push(e.join("")):a.push(e)}else if("execute_result"===r||"display_data"===r){const e=t.data;if(e["text/plain"]){const t=e["text/plain"];Array.isArray(t)?a.push(t.join("")):a.push(t)}}else if("error"===r){const e=t.traceback;Array.isArray(e)&&a.push(e.join("\n"))}}return a.join("\n")}function Ln(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}function Mn(e){const t=e,n=t.model?.outputs;if(!n)return!1;for(let e=0;e<n.length;e++)if("error"===n.get(e).type)return!0;return!1}function Rn(e){const t=e.model;let n;try{t.metadata&&"function"==typeof t.metadata.get?n=t.metadata.get("jupyterAgentCellId"):t.metadata?.jupyterAgentCellId&&(n=t.metadata.jupyterAgentCellId)}catch(e){}if(!n){n=`cell-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;try{t.metadata&&"function"==typeof t.metadata.set?t.metadata.set("jupyterAgentCellId",n):t.metadata&&(t.metadata.jupyterAgentCellId=n)}catch(e){}}return n}function qn(e){const t=document.querySelector(`.${e}`);t&&t.remove()}function Dn(e){const t=document.createElement("div");return t.className=e,t.style.cssText="\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.3);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n ",t}function On(e="400px"){const t=document.createElement("div");return t.style.cssText=`\n background: var(--codebuff-dialog-bg, #fafafa);\n border: 1px solid var(--codebuff-dialog-border, #e0e0e0);\n border-radius: 4px;\n padding: 24px;\n max-width: ${e};\n width: 90%;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n `,t}function zn(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function Fn(e,t="info"){const n=function(e,t){const n=document.createElement("div");return n.style.cssText=`\n position: fixed;\n top: 20px;\n right: 20px;\n padding: 12px 16px;\n border-radius: 6px;\n color: white;\n font-size: 14px;\n font-weight: 500;\n z-index: 10001;\n opacity: 0;\n transition: opacity 0.3s ease;\n max-width: 300px;\n word-wrap: break-word;\n background: ${t};\n `,n.textContent=e,n}(e,function(e){switch(e){case"error":return"#f56565";case"warning":return"#ed8936";default:return"#4299e1"}}(t));document.body.appendChild(n),function(e){setTimeout(()=>e.style.opacity="1",10),setTimeout(()=>{e.style.opacity="0",setTimeout(()=>{e.parentNode&&e.parentNode.removeChild(e)},300)},3e3)}(n)}function Bn(e){const t=e,n=t.model?.outputs;if(!n)return;let a=!1;for(let e=0;e<n.length;e++)if("error"===n.get(e).type){a=!0;break}const r=e.node,s=r.querySelector(".jp-codebuff-error-fix-btn");if(!a)return void(s&&s.remove());if(s)return;Ze.c.getInstance().trackError("cell_execution_error",{cell_index:In(e),source:(e.model?.sharedModel?.getSource()||"").slice(0,3e3),output:Pn(e).slice(0,3e3)});const o=document.createElement("button");o.className="jp-codebuff-error-fix-btn jp-codebuff-fix-blink",o.title="수정 제안 (Fix)",o.innerHTML=`${Cn}<span class="jp-codebuff-error-fix-label">수정 제안</span>`,o.onclick=t=>{t.preventDefault(),t.stopPropagation(),o.classList.remove("jp-codebuff-fix-blink"),Ze.c.getInstance().trackClick("cell_error_fix",{cell_index:In(e),has_error:!0,prompt:e?.model?.sharedModel?.getSource()||""}),An(En.FIX,e)};const l=r.querySelector(".jp-Cell-outputWrapper");l&&(l.style.position="relative",l.appendChild(o))}var Wn=n(3366),Un=n(7125),Hn=n(1247),Jn=n(6661),Vn=n(8411),Gn=n(2670);const Xn=({open:e,onClose:t,onGenerate:n,apiService:a})=>{const[r,s]=(0,i.useState)(""),[o,l]=(0,i.useState)(!1),[c,u]=(0,i.useState)(0),[m,p]=(0,i.useState)(""),[h,g]=(0,i.useState)(!1),[f,b]=(0,i.useState)(!1),[v,y]=(0,i.useState)(0),E=(0,i.useRef)(null),k=()=>{r.trim()&&(l(!0),n(r.trim()),s(""),l(!1),t())};return d().createElement(Jn.Dialog,{open:e,onClose:t,maxWidth:"md",fullWidth:!0,PaperProps:{sx:{borderRadius:2,minHeight:"400px"}}},d().createElement(Jn.DialogTitle,null,d().createElement(Jn.Box,{display:"flex",alignItems:"center",gap:1},d().createElement(Vn.A,{color:"primary"}),d().createElement(Jn.Typography,{variant:"h6"},"Codebuff 노트북 자동생성"))),d().createElement(Jn.DialogContent,{sx:{overflow:"visible"}},d().createElement(Jn.Box,{display:"flex",flexDirection:"column",gap:2,mt:1},d().createElement(Jn.Typography,{variant:"body2",color:"text.secondary"},"원하는 노트북의 내용을 자연어로 설명해주세요. AI가 자동으로 노트북을 생성합니다."),d().createElement(Jn.Box,{sx:{position:"relative"}},d().createElement(xt,{placement:"below",apiService:a,inputValue:r,cursorPosition:v,onSelect:(e,t)=>{const n=r;let a=v;for(;a>0&&!/\s/.test(n[a-1]);)a--;const o=n.slice(0,a),l=n.slice(v),c=t&&e.is_complete,i=o+e.label+(c?" ":"")+l,d=a+e.label.length+(c?1:0);s(i),y(d),t&&(g(!1),b(!1)),setTimeout(()=>{E.current&&(E.current.focus(),E.current.setSelectionRange(d,d))},0)},onClose:()=>{g(!1),b(!1)},onOptionsChange:b,visible:h,anchorEl:E.current}),d().createElement("textarea",{ref:E,autoFocus:!0,value:r,onChange:e=>{const t=e.target.value,n=e.target.selectionStart||0;s(t),y(n);let a=n;for(;a>0&&!/\s/.test(t[a-1]);)a--;t.slice(a,n).startsWith("@")?g(!0):g(!1)},onKeyDown:e=>{if(h&&f){if("Tab"===e.key||"ArrowDown"===e.key||"ArrowUp"===e.key)return;if("Enter"===e.key&&!e.shiftKey)return;if("Escape"===e.key)return g(!1),void b(!1)}"Enter"===e.key&&e.ctrlKey&&(e.preventDefault(),k())},onSelect:e=>y(e.target.selectionStart||0),disabled:o,placeholder:"예: 타이타닉 생존자 예측을 dask와 lgbm으로 생성해줘",rows:6,style:{width:"100%",fontSize:"14px",fontFamily:"inherit",padding:"16.5px 14px",border:"1px solid rgba(0, 0, 0, 0.23)",borderRadius:"4px",resize:"vertical",outline:"none",boxSizing:"border-box",lineHeight:"1.4375em"},onFocus:e=>{e.target.style.borderColor="#1976d2",e.target.style.borderWidth="2px",e.target.style.padding="15.5px 13px"},onBlur:e=>{e.target.style.borderColor="rgba(0, 0, 0, 0.23)",e.target.style.borderWidth="1px",e.target.style.padding="16.5px 14px"}})),d().createElement(Jn.Box,{sx:{backgroundColor:"action.hover",borderRadius:1,padding:2}},d().createElement(Jn.Typography,{variant:"caption",color:"text.secondary",component:"div",sx:{display:"flex",flexDirection:"column"}},d().createElement(Jn.Box,{sx:{display:"flex",alignItems:"center",gap:.5}},d().createElement(Gn.A,{fontSize:"small",sx:{color:"#ffc107"}})," ",d().createElement("strong",null,"팁:")),d().createElement("br",null),"• 사용할 라이브러리를 명시하면 더 정확합니다",d().createElement("br",null),"• 분석 목적과 데이터를 구체적으로 설명하세요",d().createElement("br",null),"• Ctrl + Enter로 빠르게 생성할 수 있습니다",d().createElement("br",null),"• 생성은 백그라운드에서 진행되며, 완료되면 알림을 받습니다")))),d().createElement(Jn.DialogActions,{sx:{padding:2,paddingTop:0}},d().createElement(Jn.Button,{onClick:t,disabled:o},"취소"),d().createElement(Jn.Button,{onClick:k,variant:"contained",disabled:!r.trim()||o,startIcon:d().createElement(Vn.A,null)},"생성 시작")))};var Zn=n(6249),Kn=n(110),Qn=n(2751),Yn=n(6694),ea=n(9349),ta=n(5629),na=n(9149),aa=n(4485),ra=n(8125),sa=n(8046),oa=n(9211),la=n(1735),ca=n(8075),ia=n(1540),da=n(9568),ua=n(63),ma=n(1696);function pa(){return c.URLExt.join(c.PageConfig.getBaseUrl(),"codebuff")}function ha(){const e=`; ${document.cookie}`.split("; _xsrf=");return 2===e.length&&e.pop()?.split(";").shift()||""}function ga({title:e,children:t}){return d().createElement("span",{className:"athena-tip-wrap"},d().createElement("svg",{className:"athena-tip-icon",width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("circle",{cx:"12",cy:"12",r:"10"}),d().createElement("path",{d:"M12 16v-4"}),d().createElement("path",{d:"M12 8h.01"})),d().createElement("span",{className:"athena-tip-popup"},d().createElement("span",{className:"athena-tip-title"},e),d().createElement("span",{className:"athena-tip-body"},t)))}function fa(e){try{return(0,ma.format)(e,{language:"trino",tabWidth:2,keywordCase:"upper"})}catch{return e}}function ba(e){try{return q().highlight(e,{language:"sql"}).value}catch{return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}}function va(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\b(SELECT|FROM|WHERE|JOIN|LEFT|RIGHT|INNER|OUTER|FULL|CROSS|ON|AND|OR|NOT|IN|IS|NULL|AS|GROUP|BY|ORDER|HAVING|LIMIT|OFFSET|UNION|ALL|DISTINCT|WITH|CASE|WHEN|THEN|ELSE|END|BETWEEN|LIKE|EXISTS|ASC|DESC|INSERT|INTO|VALUES|UPDATE|SET|DELETE|CREATE|DROP|ALTER|TABLE|VIEW|INDEX|CAST|OVER|PARTITION|ROWS|RANGE|UNBOUNDED|PRECEDING|FOLLOWING|CURRENT|ROW|TRUE|FALSE|DATE|TIMESTAMP|INTERVAL)\b/gi,'<span class="athena-hl-kw">$&</span>').replace(/\b(\d+(?:\.\d+)?)\b/g,'<span class="athena-hl-num">$&</span>').replace(/('(?:[^'\\]|\\.)*')/g,'<span class="athena-hl-str">$1</span>').replace(/(--.*$)/g,'<span class="athena-hl-cmt">$1</span>')}function ya(e){const t=(e||"").split("\n").length;return Array.from({length:t},(e,t)=>`<span>${t+1}</span>`).join("\n")}q().registerLanguage("sql",V());const Ea=({initialPrompt:e})=>{const[t,n]=(0,i.useState)(""),[a,r]=(0,i.useState)(""),[s,o]=(0,i.useState)(""),[l,c]=(0,i.useState)(""),[u,m]=(0,i.useState)(!1),[p,h]=(0,i.useState)(!1),[g,f]=(0,i.useState)(!1),[b,v]=(0,i.useState)(""),[y,E]=(0,i.useState)(""),[k,w]=(0,i.useState)(""),[x,S]=(0,i.useState)(null),[_,C]=(0,i.useState)(1),[N,j]=(0,i.useState)(null),[$,T]=(0,i.useState)(null),[A,I]=(0,i.useState)(null),[P,L]=(0,i.useState)(null),[M,R]=(0,i.useState)([]),[q,D]=(0,i.useState)(new Set),[O,z]=(0,i.useState)(new Set),[F,B]=(0,i.useState)(""),[W,U]=(0,i.useState)(!1),[H,J]=(0,i.useState)(!1),[V,G]=(0,i.useState)(""),[X,Z]=(0,i.useState)(""),[K,Q]=(0,i.useState)(!1),[Y,ee]=(0,i.useState)(""),[te,ne]=(0,i.useState)(""),[ae,re]=(0,i.useState)([]),[se,oe]=(0,i.useState)(!1),[le,ce]=(0,i.useState)([]),[ie,de]=(0,i.useState)(null),[ue,me]=(0,i.useState)([]),[pe,he]=(0,i.useState)(!1),[ge,fe]=(0,i.useState)(0),be=100,ve=(0,i.useRef)(null),ye=(0,i.useRef)(null),[Ee,we]=(0,i.useState)(!1),xe=(0,i.useRef)(null),Se=(0,i.useRef)(""),_e=(0,i.useRef)(null),Ce=(0,i.useRef)(null),Ne=!p&&(t.trim()||a.trim()),je=a.trim().length>0,$e=(0,i.useRef)(!1),Te=(0,i.useCallback)(async()=>{if(!Ne)return;const e=N,n=e?e.newSql.replace(/^\s*--\s*\[REASON\].*\n?/gim,"").trim():a.trim()?fa(a).trim():"",s=e?e.originalSql:n;!e&&a.trim()&&r(fa(a)),h(!0),o(""),c(""),m(!1),E(""),w(""),S(null),j(null),v("에이전트 시작"),z(new Set),L(null),D(new Set),R([]),G(""),Z(""),J(!1);const l=new AbortController;xe.current=l;try{const e=await fetch(`${pa()}/athena/query/stream`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":ha()},body:JSON.stringify({naturalLanguage:t.trim()||void 0,existingSql:n||void 0}),signal:l.signal});if(!e.ok){const t=await e.json().catch(()=>({}));throw new Error(t.error||`HTTP ${e.status}`)}const a=e.body?.getReader();if(!a)throw new Error("Stream not available");const i=new TextDecoder;let d="",u="";for(;;){const{done:e,value:t}=await a.read();if(e)break;u+=i.decode(t,{stream:!0});const n=u.split("\n");u=n.pop()||"";for(const e of n)if(e.startsWith("data: "))try{const t=JSON.parse(e.slice(6).trim());if(t.error){E(t.error);break}if(t.needs_table_confirmation&&t.candidates)return L(t.candidates),R(t.confirmed_tables||[]),D(new Set),z(e=>{const n=new Set(e);for(const e of Object.values(t.candidates))for(const t of e)t.table_name&&n.add(t.table_name);return n}),v(""),h(!1),void(xe.current=null);t.sql_update&&r(fa(t.sql_update)),t.status&&v(t.status),t.content&&(t.is_text_only?(t.title&&o(t.title),c(t.content),v("")):(d+=t.content,v("처리 중")))}catch{}}if(d){v("응답 처리 중"),d=d.replace(/\*\*"?(\w+)"?\*\*\s*:/g,'"$1":');let e=!1;for(const t of[/\{[\s\S]*(?:"description"|"title"|"sql")[\s\S]*\}/,/```(?:json)?\s*(\{[\s\S]*?\})\s*```/]){const n=d.match(t),a=n?n[1]||n[0]:null;if(a)try{const t=JSON.parse(a);if(t.title&&o(t.title),t.description&&c(t.description),t.sql){const e=fa(t.sql);s?j({originalSql:s,newSql:e}):r(e)}e=!0;break}catch{}}!e&&d.trim()&&E(d.length>200?d.slice(0,200)+"...":d)}v("")}catch(e){"AbortError"!==e.name&&E(e.message||"요청 실패"),v("")}finally{h(!1),xe.current=null}},[Ne,t,a]),Ae=(0,i.useCallback)(()=>{xe.current?.abort(),xe.current=null,h(!1),v("")},[]);(0,i.useEffect)(()=>{e&&e.trim()&&n(e.trim())},[]),(0,i.useEffect)(()=>{e&&!$e.current&&(t!==e.trim()||p||($e.current=!0,Te()))},[t,Te,e,p]);const Ie=(0,i.useCallback)(async()=>{if(je){w(""),S(null),I(null),f(!0),v("Athena 쿼리 실행 중");try{const e=await fetch(`${pa()}/athena/execute`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":ha()},body:JSON.stringify({sql:a.trim()})}),t=await e.json();if(t.Error||t.error)return w(t.Error||t.error),f(!1),void v("");const n=t.QueryExecutionId;if(!n)return w("QueryExecutionId가 반환되지 않았습니다."),f(!1),void v("");Se.current=n,_e.current=setInterval(async()=>{try{const e=await fetch(`${pa()}/athena/status/${n}`,{headers:{"X-XSRFToken":ha()}}),t=await e.json(),a=t.State||"";if("SUCCEEDED"===a){clearInterval(_e.current),_e.current=null,t.Statistics&&I({scannedBytes:t.Statistics.DataScannedInBytes||0,execMs:t.Statistics.EngineExecutionTimeInMillis||0,costKrw:t.Statistics.CostKRW||0}),v("결과 조회 중"),T(n),C(1);const e=await fetch(`${pa()}/athena/results/${n}?page=1&page_size=100`,{headers:{"X-XSRFToken":ha()}}),a=await e.json();a.error?w(a.error):S(a),f(!1),v("")}else"FAILED"===a||"CANCELLED"===a?(clearInterval(_e.current),_e.current=null,w(t.StateChangeReason||`쿼리 ${a}`),f(!1),v("")):v(`Athena 실행 중 (${a})`)}catch(e){clearInterval(_e.current),_e.current=null,w(e.message),f(!1),v("")}},2e3)}catch(e){w(e.message||"실행 실패"),f(!1),v("")}}},[je,a]),Pe=(0,i.useCallback)(async()=>{if(_e.current&&(clearInterval(_e.current),_e.current=null),Se.current)try{await fetch(`${pa()}/athena/stop/${Se.current}`,{method:"POST",headers:{"X-XSRFToken":ha()}})}catch{}f(!1),v("")},[]),Le=(0,i.useCallback)(()=>{n(`위 SQL 실행 시 다음 오류가 발생했습니다. 수정해주세요: ${k}`),w(""),setTimeout(()=>Te(),100)},[k,Te]),Me=(0,i.useCallback)(async(e=!1)=>{if(!P)return;const t={},n=[],a=e?new Set:new Set(O);for(const[e,r]of Object.entries(P)){const s=r;s.some(e=>q.has(e.table_name))?t[e]=s.filter(e=>q.has(e.table_name)):(n.push(e),s.forEach(e=>{e.table_name&&a.add(e.table_name)}))}const r=Array.from(a);if(0===n.length)return;const s={...P};L(t),U(!0),E(""),J(!1),e&&z(new Set);const o=new AbortController;xe.current=o;try{const e=await fetch(`${pa()}/athena/candidates`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":ha()},body:JSON.stringify({queries:n,excludedTableNames:r}),signal:o.signal});if(!e.ok){const t=await e.json().catch(()=>({}));throw new Error(t.error||`HTTP ${e.status}`)}const a=await e.json();if(a.candidates&&Object.keys(a.candidates).length>0){z(e=>{const t=new Set(e);for(const e of Object.values(a.candidates))for(const n of e)n.table_name&&t.add(n.table_name);return t});const e={...t,...a.candidates};L(e)}else L(s),J(!0)}catch(e){"AbortError"!==e.name&&E(e.message||"요청 실패")}finally{U(!1),xe.current=null}},[P,q,O]),Re=(0,i.useMemo)(()=>!!P&&Object.values(P).every(e=>e.some(e=>q.has(e.table_name))),[P,q]),qe=(0,i.useCallback)(async()=>{const e=V.trim();if(e){Z("");try{const t=await fetch(`${pa()}/athena/candidates`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":ha()},body:JSON.stringify({queries:[`테이블명:${e}`],excludedTableNames:[]})});if(!t.ok)throw new Error("검색 실패");const n=(await t.json()).candidates||{};let a=null;for(const t of Object.values(n)){for(const n of t)if(n.table_name&&n.table_name.toLowerCase()===e.toLowerCase()){a=n;break}if(a)break}if(!a)return void Z(`"${e}" 테이블이 존재하지 않습니다.`);L(t=>{if(!t)return t;const n=`직접 입력: ${e}`;return{...t,[n]:[a]}}),D(e=>new Set([...e,a.table_name])),G("")}catch(e){Z(e.message||"검색 중 오류 발생")}}},[V]),De=(0,i.useCallback)(async()=>{if(0===q.size||!P)return;const e=[],n=[];for(const t of Object.values(P)){const a=t;if(a.some(e=>q.has(e.table_name)))for(const t of a)q.has(t.table_name)&&e.push(t);else{const t=a.reduce((e,t)=>(e.score||0)>=(t.score||0)?e:t,a[0]);t&&(e.push(t),n.push(t.table_name))}}for(const t of M)e.some(e=>e.table_name===t.table_name)||(e.push(t),n.push(t.table_name));console.log("[AthenaQuery] confirmTables selectedData:",e.map(e=>e.table_name),"auto:",n);const s=a.trim();L(null),h(!0),o(""),c(""),m(!1),E(""),v("SQL 생성 중 (선택된 테이블 사용)");const l=new AbortController;xe.current=l;try{const i=await fetch(`${pa()}/athena/query/stream`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":ha()},body:JSON.stringify({naturalLanguage:t.trim()||void 0,existingSql:a.trim()||void 0,selectedTables:e,autoSelectedTableNames:n.length>0?n:void 0}),signal:l.signal});if(!i.ok){const e=await i.json().catch(()=>({}));throw new Error(e.error||`HTTP ${i.status}`)}const d=i.body?.getReader();if(!d)throw new Error("Stream not available");const u=new TextDecoder;let m="",p="";for(;;){const{done:e,value:t}=await d.read();if(e)break;p+=u.decode(t,{stream:!0});const n=p.split("\n");p=n.pop()||"";for(const e of n)if(e.startsWith("data: "))try{const t=JSON.parse(e.slice(6).trim());if(t.error){E(t.error);break}t.sql_update&&r(fa(t.sql_update)),t.status&&v(t.status),t.content&&(t.is_text_only?(t.title&&o(t.title),c(t.content),v("")):(m+=t.content,v("처리 중")))}catch{}}if(m){m=m.replace(/\*\*"?(\w+)"?\*\*\s*:/g,'"$1":');let e=!1;for(const t of[/\{[\s\S]*(?:"description"|"title"|"sql")[\s\S]*\}/,/```(?:json)?\s*(\{[\s\S]*?\})\s*```/]){const n=m.match(t),a=n?n[1]||n[0]:null;if(a)try{const t=JSON.parse(a);if(t.title&&o(t.title),t.description&&c(t.description),t.sql){const e=fa(t.sql);s?j({originalSql:s,newSql:e}):r(e)}e=!0;break}catch{}}!e&&m.trim()&&E(m.length>200?m.slice(0,200)+"...":m)}v("")}catch(e){"AbortError"!==e.name&&E(e.message||"요청 실패"),v("")}finally{h(!1),xe.current=null}},[q,P,t,a]),Oe=(0,i.useCallback)(e=>{D(t=>{const n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),ze=te===Y.trim()&&ae.length>0,Fe=(0,i.useCallback)(async(e=!1,t)=>{const n=(t??Y).trim();if(!n)return;oe(!0),de(null),me([]);let a=e?[...le]:[];if(e)for(const e of ae)e.table_name&&!a.includes(e.table_name)&&a.push(e.table_name);try{const e=await fetch(`${pa()}/athena/candidates`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":ha()},body:JSON.stringify({queries:[n],excludedTableNames:a,limit:10})}),t=(await e.json()).candidates||{},r=[];for(const e of Object.values(t))for(const t of e)r.push(t);re(r),ce(a),ne(n)}catch{re([])}finally{oe(!1)}},[Y,ae,le]),[Be,We]=(0,i.useState)(""),Ue=(0,i.useRef)(!1),He=(0,i.useRef)(0),Je=(0,i.useRef)(""),Ve=(0,i.useCallback)(async(e,t,n)=>{const a=await fetch(`${pa()}/athena/table-columns`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":ha()},body:JSON.stringify({table_name:e,collection:"bdp_tables",chunk_index:t})}),r=await a.json();return r.success&&(r.meta&&de(e=>({...e,payload:r.meta})),me(n?e=>[...e,...r.columns||[]]:r.columns||[]),Ue.current=r.has_more||!1,He.current=t+1),r},[]),Ge=(0,i.useCallback)(async e=>{de(e),me([]),he(!0),We(""),fe(0),Je.current=e.table_name;try{(await Ve(e.table_name,0,!1)).success||(de(null),re([]))}catch{de(null),me([])}finally{he(!1)}},[Ve]),Xe=(0,i.useMemo)(()=>{if(!Be.trim())return ue;const e=Be.toLowerCase();return ue.filter(t=>"object"!=typeof t||Array.isArray(t)?String(t).toLowerCase().includes(e):Object.values(t).some(t=>String(t).toLowerCase().includes(e)))},[ue,Be]),Ze=(0,i.useMemo)(()=>{const e=ge*be;return Xe.slice(e,e+be)},[Xe,ge]),Ke=(0,i.useMemo)(()=>Math.ceil(Xe.length/be),[Xe]),Qe=(0,i.useMemo)(()=>new Set(["select","from","where","and","or","not","in","is","null","as","on","join","inner","left","right","outer","full","cross","natural","group","by","order","having","limit","offset","union","all","distinct","insert","into","values","update","set","delete","create","drop","alter","table","view","index","with","case","when","then","else","end","between","like","exists","asc","desc","true","false","cast","over","partition","rows","range","unbounded","preceding","following","current","row","coalesce","nullif","if","concat","substr","substring","length","trim","ltrim","rtrim","upper","lower","replace","split","regexp_extract","regexp_like","date_add","date_diff","date_trunc","date_parse","date_format","format_datetime","from_unixtime","to_unixtime","year","month","day","hour","minute","second","current_date","current_timestamp","now","count","sum","avg","min","max","row_number","rank","dense_rank","lag","lead","first_value","last_value","nth_value","ntile","approx_distinct","approx_percentile","array","map","element_at","cardinality","flatten","transform","filter","reduce","zip_with","sequence","typeof","try_cast","json_extract","json_extract_scalar","json_parse","json_format","abs","ceil","ceiling","floor","round","mod","power","sqrt","log","ln","exp","sign","random","greatest","least","arbitrary"]),[]),Ye=(0,i.useCallback)(e=>{const t=window.getSelection(),n=(t?.toString()||"").trim();if(!n||n.length<2||/\s/.test(n)||Qe.has(n.toLowerCase()))return;const a=e||"",r=a.indexOf(n);let s=!1;if(r>0){const e=a.substring(0,r).match(/(\w+)\.\s*$/);if(e){const t=e[1].toLowerCase();s=/^wd.*_bdp_db_dlk_l.*_.*$/.test(t)}}if(Q(!0),s)ee(`테이블명:${n}`),ne(""),ce([]),re([]),Ge({table_name:n,korean_name:""});else{const e=`컬럼명:${n}`;ee(e),ne(""),ce([]),Fe(!1,e)}},[Qe,Fe,Ge]),et=(0,i.useCallback)(()=>{xe.current?.abort(),xe.current=null,_e.current&&(clearInterval(_e.current),_e.current=null),n(""),r(""),o(""),c(""),m(!1),E(""),w(""),S(null),I(null),v(""),L(null),D(new Set),h(!1),f(!1),U(!1),J(!1)},[]),tt=(0,i.useCallback)(()=>{a.trim()&&r(fa(a))},[a]),nt=(0,i.useCallback)(()=>{a.trim()&&navigator.clipboard.writeText(a).then(()=>{we(!0),setTimeout(()=>we(!1),1500)})},[a]);return(0,i.useEffect)(()=>()=>{_e.current&&clearInterval(_e.current)},[]),d().createElement("div",{className:"athena-panel"},d().createElement("div",{className:"athena-header"},d().createElement("div",{className:"athena-header-left"},d().createElement("svg",{className:"athena-header-icon",viewBox:"0 0 24 24",width:"22",height:"22",fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("ellipse",{cx:"9",cy:"5",rx:"7",ry:"2.5",stroke:"#fff",strokeWidth:"1.5"}),d().createElement("path",{d:"M2 5v10c0 1.38 3.13 2.5 7 2.5",stroke:"#fff",strokeWidth:"1.5"}),d().createElement("path",{d:"M16 5v2",stroke:"#fff",strokeWidth:"1.5"}),d().createElement("path",{d:"M2 10c0 1.38 3.13 2.5 7 2.5s7-1.12 7-2.5",stroke:"#fff",strokeWidth:"1.5"}),d().createElement("circle",{cx:"17",cy:"16",r:"4",stroke:"#fbbf24",strokeWidth:"1.5"}),d().createElement("path",{d:"M20 19.5l2 2",stroke:"#fbbf24",strokeWidth:"2"})),d().createElement("div",null,d().createElement("div",{className:"athena-header-title"},"EDA Agent",d().createElement("span",{className:"athena-beta-badge",title:"현재 EDA Agent 는 베타 서비스로, L1 테이블만 자동으로 검색할 수 있습니다."},"beta")),d().createElement("div",{className:"athena-header-sub"},"쿼리 생성 · 튜닝 · 분석 · 비교 · BDP 테이블 스키마 검색(오른쪽 패널) · AI 생성 결과는 반드시 검증 후 사용하세요")))),d().createElement("div",{className:"athena-body"},d().createElement("div",{className:"athena-main-layout "+(K?"athena-sidebar-open":"")},d().createElement("div",{className:"athena-main-content"},s&&!N&&d().createElement("div",{className:"athena-result-title"},s),d().createElement("div",{className:"athena-editor-wrap"},N?d().createElement("div",{className:"athena-diff-container"},d().createElement("div",{className:"athena-diff-bar"},d().createElement("div",{className:"athena-diff-bar-left"},d().createElement("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("path",{d:"M12 3v14"}),d().createElement("path",{d:"M5 10l7 7 7-7"}),d().createElement("path",{d:"M3 21h18"})),d().createElement("span",{className:"athena-diff-bar-title"},"SQL 검토: ",s||"변경사항"),d().createElement(ga,{title:"SQL 변경사항 검토"},d().createElement("p",null,d().createElement("strong",null,"좌측"),": 원본 SQL / ",d().createElement("strong",null,"우측"),": 수정된 SQL"),d().createElement("p",null,d().createElement("strong",null,"보라색 라인"),": hover하면 변경 사유(REASON) 확인 가능"),d().createElement("p",null,d().createElement("strong",null,"적용"),": 수정된 SQL을 에디터에 반영"),d().createElement("p",null,d().createElement("strong",null,"추가 수정"),": 검토 화면에서 프롬프트로 추가 요청 가능"))),d().createElement("div",{className:"athena-diff-bar-actions"},d().createElement("button",{className:"athena-diff-btn athena-diff-btn-cancel",onClick:()=>{r(N.originalSql),j(null)}},"취소"),d().createElement("button",{className:"athena-diff-btn athena-diff-btn-apply",onClick:()=>{const e=N.newSql.replace(/^\s*--\s*\[REASON\].*\n?/gim,"");r(e),j(null)}},"변경사항 적용"))),(()=>{const e=/^\s*--\s*\[REASON\]\s*(.+)$/i,t=(0,ke.diffLines)(N.originalSql,N.newSql),n=[],a=[];let r=0,s=0,o="";for(const l of t){const t=l.value.replace(/\n$/,"").split("\n");if(l.added||l.removed)if(l.removed)for(const e of t)n.push({line:e,type:"removed",lineNo:++r}),a.push({line:"",type:"pad"});else for(const r of t){const t=e.exec(r);if(t)o=t[1];else{n.push({line:"",type:"pad"});const e={line:r,type:"added",lineNo:++s};o&&(e.reason=o,o=""),a.push(e)}}else{o="";for(const e of t)n.push({line:e,type:"context",lineNo:++r}),a.push({line:e,type:"context",lineNo:++s})}}const l=[],c=[];let i=0;for(;i<n.length;)if("removed"===n[i].type&&"pad"===a[i].type){const e=[],t=[];for(;i<n.length&&"removed"===n[i].type&&"pad"===a[i].type;)e.push(n[i]),i++;for(;i<n.length&&"pad"===n[i].type&&"added"===a[i].type;)t.push(a[i]),i++;const r=Math.max(e.length,t.length);for(let n=0;n<r;n++)l.push(n<e.length?e[n]:{line:"",type:"pad"}),c.push(n<t.length?t[n]:{line:"",type:"pad"})}else l.push(n[i]),c.push(a[i]),i++;const u=d().createRef(),m=d().createRef();let p=!1;const h=e=>{if(p)return;p=!0;const t="left"===e?u.current:m.current,n="left"===e?m.current:u.current;t&&n&&(n.scrollTop=t.scrollTop,n.scrollLeft=t.scrollLeft),requestAnimationFrame(()=>{p=!1})};return d().createElement("div",{className:"athena-diff-side-by-side"},d().createElement("div",{className:"athena-diff-pane athena-diff-pane-left"},d().createElement("div",{className:"athena-diff-pane-header"},"원본"),d().createElement("div",{className:"athena-diff-pane-body",ref:u,onScroll:()=>h("left"),onDoubleClick:()=>Ye(N.originalSql)},l.map((e,t)=>d().createElement("div",{key:t,className:`athena-diff-row athena-diff-row-${e.type}`},d().createElement("span",{className:"athena-diff-ln"},e.lineNo??""),"removed"===e.type?d().createElement("span",{className:"athena-diff-code"},e.line):d().createElement("span",{className:"athena-diff-code",dangerouslySetInnerHTML:{__html:va(e.line)}}))))),d().createElement("div",{className:"athena-diff-divider"}),d().createElement("div",{className:"athena-diff-pane athena-diff-pane-right"},d().createElement("div",{className:"athena-diff-pane-header"},"수정됨"),d().createElement("div",{className:"athena-diff-pane-body",ref:m,onScroll:()=>h("right"),onDoubleClick:()=>Ye(N.newSql)},c.map((e,t)=>d().createElement("div",{key:t,className:`athena-diff-row athena-diff-row-${e.type}`,...e.reason?{"data-reason":e.reason}:{}},d().createElement("span",{className:"athena-diff-ln"},e.lineNo??""),d().createElement("span",{className:"athena-diff-code",dangerouslySetInnerHTML:{__html:va(e.line)}}))))))})()):d().createElement("div",{className:"athena-sql-container "+(p||g?"athena-sql-busy":"")},d().createElement("div",{className:"athena-sql-loading"},d().createElement("div",{className:"athena-sql-loading-spinner"})),d().createElement("div",{ref:ye,className:"athena-sql-line-numbers","aria-hidden":!0,dangerouslySetInnerHTML:{__html:ya(a||"\n")}}),d().createElement("div",{className:"athena-sql-editor"},d().createElement(d().Fragment,null,d().createElement("div",{ref:ve,className:"athena-sql-highlight-layer","aria-hidden":!0,dangerouslySetInnerHTML:{__html:a?ba(a):""}}),d().createElement("textarea",{ref:Ce,className:"athena-sql-textarea-overlay",placeholder:"SELECT card_no, SUM(txn_amount)\nFROM bdp_card_txn_daily\nGROUP BY card_no",value:a,onChange:e=>r(e.target.value),onPaste:e=>{e.preventDefault();const t=e.clipboardData.getData("text"),n=Ce.current;if(!n)return;const s=n.selectionStart,o=n.selectionEnd;r(a.substring(0,s)+t+a.substring(o))},onDoubleClick:()=>Ye(a),onScroll:()=>{Ce.current&&(ve.current&&(ve.current.scrollTop=Ce.current.scrollTop,ve.current.scrollLeft=Ce.current.scrollLeft),ye.current&&(ye.current.scrollTop=Ce.current.scrollTop))},disabled:p,spellCheck:!1,wrap:"off"}))),je&&!p&&d().createElement("div",{className:"athena-sql-toolbar"},d().createElement("button",{className:"athena-sql-tool-btn",onClick:tt,title:"SQL 포맷팅"},d().createElement(Vn.A,{sx:{fontSize:13}})," Beautify"),d().createElement("button",{className:"athena-sql-tool-btn",onClick:nt,title:"클립보드 복사"},Ee?d().createElement(d().Fragment,null,d().createElement(na.A,{sx:{fontSize:13}})," Copied"):d().createElement(d().Fragment,null,d().createElement(ta.A,{sx:{fontSize:13}})," Copy")),d().createElement(ga,{title:"SQL 에디터"},d().createElement("p",null,d().createElement("strong",null,"직접 입력"),": SQL을 직접 작성하거나 붙여넣기"),d().createElement("p",null,d().createElement("strong",null,"더블클릭"),": 테이블명/컬럼명 더블클릭 → 오른쪽 패널에서 메타데이터 검색"),d().createElement("p",null,d().createElement("strong",null,"변수 치환"),": ",d().createElement("code",null,"${today_ymd}"),", ",d().createElement("code",null,"${bf1d_y_m_d}")," 등 날짜 변수 자동 치환"),d().createElement("p",null,d().createElement("strong",null,"Beautify"),": SQL 자동 포맷팅 (Trino 방언)")))),d().createElement("div",{className:"athena-prompt-bar"},d().createElement("button",{className:"athena-prompt-reset-btn",onClick:et,title:"초기화"},d().createElement("svg",{viewBox:"0 0 24 24",width:"16",height:"16",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("polyline",{points:"3 6 5 6 21 6"}),d().createElement("path",{d:"M19 6l-1 14H6L5 6"}),d().createElement("path",{d:"M10 11v6M14 11v6"}),d().createElement("path",{d:"M9 6V4h6v2"}))),d().createElement("div",{className:"athena-prompt-content"},d().createElement("input",{type:"text",className:"athena-prompt-input",placeholder:"BDP 데이터에 대해 무엇이든 요청하세요 (쿼리 생성, 튜닝, 분석, 비교 등)",value:t,onChange:e=>n(e.target.value),disabled:p,onKeyDown:e=>{"Enter"===e.key&&Ne&&(e.preventDefault(),Te())}}),d().createElement("div",{className:"athena-prompt-actions"},d().createElement(ga,{title:"프롬프트 사용법"},d().createElement("p",null,d().createElement("strong",null,"쿼리 생성"),': 자연어로 요청 (예: "카드매출 월별 집계 쿼리 만들어줘")'),d().createElement("p",null,d().createElement("strong",null,"쿼리 튜닝"),': SQL 에디터에 쿼리 입력 후 "튜닝해줘"'),d().createElement("p",null,d().createElement("strong",null,"추가 수정"),': SQL 검토 화면에서 수정 요청 가능 (예: "LEFT JOIN으로 바꿔줘")'),d().createElement("p",null,d().createElement("strong",null,"더블클릭"),": SQL 에디터에서 테이블/컬럼명 더블클릭 → 오른쪽 패널에서 자동 검색")),p?d().createElement("button",{className:"athena-btn athena-btn-stop",onClick:Ae},d().createElement(ea.A,{sx:{fontSize:14}})," 중지"):d().createElement("button",{className:"athena-btn athena-btn-primary",onClick:Te,disabled:!Ne},d().createElement(Qn.A,{sx:{fontSize:14}})," 요청 전송"),g?d().createElement("button",{className:"athena-btn athena-btn-stop",onClick:Pe},d().createElement(ea.A,{sx:{fontSize:14}})," 중지"):d().createElement("button",{className:"athena-btn athena-btn-execute",onClick:Ie,disabled:!je||p},d().createElement(Yn.A,{sx:{fontSize:15}})," 쿼리 실행"))))),b&&d().createElement("div",{className:"athena-status"},d().createElement("div",{className:"athena-status-dot"}),b),l&&d().createElement("div",{className:"athena-result athena-desc-wrap"},d().createElement("div",{className:"athena-result-text athena-result-markdown athena-desc-collapse"+(u?" athena-desc-expanded":"")},d().createElement(Zn.default,{remarkPlugins:[Kn.default]},l),!u&&d().createElement("div",{className:"athena-desc-fade"})),d().createElement("button",{className:"athena-desc-toggle",onClick:()=>m(e=>!e)},u?"▲ 접기":"▼ 더 보기")),P&&d().createElement("div",{className:"athena-candidates"+(W?" athena-candidates-loading":"")},d().createElement("div",{className:"athena-candidates-header"},d().createElement("span",{className:"athena-candidates-title"},"사용할 테이블을 선택해주세요"),d().createElement("div",{className:"athena-candidates-actions"},H?d().createElement("button",{className:"athena-btn athena-btn-explore",onClick:()=>Me(!0),disabled:W},W?d().createElement("span",{className:"athena-spinner-sm"}):d().createElement(sa.A,{sx:{fontSize:15}}),W?"검색 중...":"재검색"):d().createElement("button",{className:"athena-btn athena-btn-explore",onClick:()=>Me(),disabled:W||Re},W?d().createElement("span",{className:"athena-spinner-sm"}):d().createElement(sa.A,{sx:{fontSize:15}}),W?"검색 중...":"다른 테이블 살펴보기"),d().createElement("button",{className:"athena-btn athena-btn-primary",onClick:De,disabled:0===q.size||W},d().createElement(oa.A,{sx:{fontSize:14}})," 선택 완료 (",q.size,"개)"))),d().createElement("div",{className:"athena-direct-table-input"},d().createElement("input",{type:"text",placeholder:"테이블명 직접 입력 (예: card_pchs)",value:V,onChange:e=>{G(e.target.value),Z("")},onKeyDown:e=>{"Enter"===e.key&&qe()}}),d().createElement("button",{onClick:qe,disabled:!V.trim()},"추가"),X&&d().createElement("span",{className:"athena-direct-table-error"},X)),Object.entries(P).map(([e,t])=>d().createElement("div",{key:e,className:"athena-candidates-group"},d().createElement("div",{className:"athena-candidates-query"},q.has(t[0]?.table_name)?"✓":"🔍",' "',e,'" 검색 결과'),t.map(e=>d().createElement("div",{key:e.table_name,className:"athena-candidate-item "+(q.has(e.table_name)?"athena-candidate-selected":"")},d().createElement("div",{className:"athena-candidate-row athena-candidate-row-clickable",onClick:()=>{Q(!0),Ge({table_name:e.table_name,korean_name:e.korean_name||""})}},d().createElement("input",{type:"checkbox","aria-label":`테이블 선택: ${e.table_name||e.payload?.["테이블명"]||""}`,checked:q.has(e.table_name),onClick:e=>e.stopPropagation(),onChange:()=>Oe(e.table_name)}),d().createElement("span",{className:"athena-candidate-name"},e.table_name||e.payload?.["테이블명"]||""),d().createElement("span",{className:"athena-candidate-korean"},e.korean_name||e.payload?.["테이블한글명"]||""),d().createElement("span",{className:"athena-candidate-meta"},e.domain," · ",(e.columns||[]).length,e.payload?._chunk?"+":"","컬럼"))))))),y&&d().createElement("div",{className:"athena-msg athena-msg-error"},y),k&&d().createElement("div",{className:"athena-msg athena-msg-error"},k,d().createElement("div",{className:"athena-msg-error-actions"},d().createElement("button",{className:"athena-btn athena-btn-fix",onClick:Le},d().createElement(aa.A,{sx:{fontSize:14}})," 수정 요청"))),g&&d().createElement("div",{className:"athena-executing"},d().createElement("div",{className:"athena-executing-spinner"}),"쿼리 실행 중..."),x&&d().createElement("div",{className:"athena-result"},A&&d().createElement("div",{className:"athena-stats-bar"},d().createElement(ga,{title:"쿼리 결과"},d().createElement("p",null,d().createElement("strong",null,"스캔"),": Athena가 읽은 데이터 양 (비용에 직결)"),d().createElement("p",null,d().createElement("strong",null,"시간"),": 쿼리 실행 소요 시간"),d().createElement("p",null,d().createElement("strong",null,"비용"),": 스캔량 기반 예상 비용 (₩5/TB)"),d().createElement("p",null,d().createElement("strong",null,"CSV 다운로드"),": S3에서 결과 파일 다운로드")),d().createElement("span",null,d().createElement(ia.A,{sx:{fontSize:13,verticalAlign:"text-bottom",mr:.3}}),"스캔: ",A.scannedBytes>=1073741824?`${(A.scannedBytes/1024**3).toFixed(2)} GB`:A.scannedBytes>=1048576?`${(A.scannedBytes/1048576).toFixed(1)} MB`:`${(A.scannedBytes/1024).toFixed(0)} KB`),d().createElement("span",null,d().createElement(da.A,{sx:{fontSize:13,verticalAlign:"text-bottom",mr:.3}}),A.execMs>=1e3?`${(A.execMs/1e3).toFixed(1)}초`:`${A.execMs}ms`),d().createElement("span",null,d().createElement(ua.A,{sx:{fontSize:13,verticalAlign:"text-bottom",mr:.3}}),"₩",A.costKrw<1?A.costKrw.toFixed(2):A.costKrw.toLocaleString("ko-KR",{maximumFractionDigits:0})),$&&d().createElement("button",{className:"athena-download-btn",onClick:async()=>{try{const e=await fetch(`${pa()}/athena/download/${$}`,{method:"POST",headers:{"X-XSRFToken":ha()}}),t=await e.json();if(t.error)alert(`다운로드 실패: ${t.error}`);else{const e=(t.size/1048576).toFixed(1);alert(`저장 완료: ${t.filename} (${e} MB)\n파일 탐색기에서 확인하세요.`)}}catch(e){alert(`다운로드 실패: ${e.message}`)}}},d().createElement(ca.A,{sx:{fontSize:13}})," CSV")),d().createElement("div",{className:"athena-result-table-wrap"},d().createElement("table",{className:"athena-result-table"},d().createElement("thead",null,d().createElement("tr",null,x.columns.map((e,t)=>d().createElement("th",{key:t},e)))),d().createElement("tbody",null,x.rows.map((e,t)=>d().createElement("tr",{key:t},e.map((e,t)=>d().createElement("td",{key:t},e)))))),d().createElement("div",{className:"athena-result-table-meta",style:{display:"flex",justifyContent:"space-between",alignItems:"center"}},d().createElement("span",null,void 0!==x.total_rows?`전체 ${x.total_rows}건 중 ${x.count}건 표시`:`${x.count}건`),x.total_pages&&x.total_pages>1&&d().createElement("div",{style:{display:"flex",gap:4,alignItems:"center"}},d().createElement("button",{className:"athena-page-btn",disabled:_<=1,onClick:async()=>{if(!$||_<=1)return;const e=_-1,t=await fetch(`${pa()}/athena/results/${$}?page=${e}&page_size=100`,{headers:{"X-XSRFToken":ha()}}),n=await t.json();n.error||(S(n),C(e))}},"◀"),d().createElement("span",{style:{fontSize:11,minWidth:60,textAlign:"center"}},_," / ",x.total_pages),d().createElement("button",{className:"athena-page-btn",disabled:_>=(x.total_pages||1),onClick:async()=>{if(!$||_>=(x.total_pages||1))return;const e=_+1,t=await fetch(`${pa()}/athena/results/${$}?page=${e}&page_size=100`,{headers:{"X-XSRFToken":ha()}}),n=await t.json();n.error||(S(n),C(e))}},"▶")))))),d().createElement("div",{className:"athena-sidebar-bar"+(K?" athena-sidebar-bar-open":""),onClick:()=>Q(!K),title:K?"닫기":"테이블 검색"},d().createElement("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"},K?d().createElement("polyline",{points:"13 17 18 12 13 7"}):d().createElement("polyline",{points:"11 7 6 12 11 17"}))),d().createElement("div",{className:"athena-sidebar-panel"},!ie&&d().createElement("div",{className:"athena-sidebar-search"},d().createElement("div",{className:"athena-sidebar-search-tip-wrap"},d().createElement("svg",{className:"athena-sidebar-search-tip-icon",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("circle",{cx:"12",cy:"12",r:"10"}),d().createElement("path",{d:"M12 16v-4"}),d().createElement("path",{d:"M12 8h.01"})),d().createElement("div",{className:"athena-sidebar-search-tip-popup"},d().createElement("div",{className:"athena-sidebar-search-tip-title"},"검색 Tip"),d().createElement("div",{className:"athena-sidebar-search-tip-body"},d().createElement("p",null,d().createElement("strong",null,"벡터 유사도 + 텍스트 매칭"),"으로 검색합니다."),d().createElement("p",null,d().createElement("strong",null,"필드명:값")," 형식으로 검색하면 정확도가 올라갑니다."),d().createElement("ul",null,d().createElement("li",null,d().createElement("code",null,"테이블명:card_pchs")),d().createElement("li",null,d().createElement("code",null,"테이블한글명:카드매출")),d().createElement("li",null,d().createElement("code",null,"컬럼명:brno")),d().createElement("li",null,d().createElement("code",null,"원천DB명:ADW"))),d().createElement("p",null,"자연어 키워드도 가능합니다."),d().createElement("ul",null,d().createElement("li",null,d().createElement("code",null,"카드매출 관련 테이블")),d().createElement("li",null,d().createElement("code",null,"가맹점 정보"))),d().createElement("p",null,d().createElement("strong",null,"재검색"),": 같은 검색어로 다시 클릭하면 기존 결과를 제외한 새 후보를 검색합니다.")))),d().createElement("input",{type:"text",className:"athena-sidebar-input",placeholder:"예: 카드매출, 테이블명:card_pchs, 컬럼명:brno",value:Y,onChange:e=>{ee(e.target.value),ne("")},onKeyDown:e=>{"Enter"===e.key&&Fe(ze)}}),d().createElement("button",{className:"athena-sidebar-search-btn"+(ze?" athena-sidebar-research-btn":""),onClick:()=>Fe(ze),disabled:se},se?d().createElement("span",{className:"athena-spinner-sm"}):ze?d().createElement(d().Fragment,null,d().createElement(sa.A,{sx:{fontSize:14}})," 재검색"):d().createElement(d().Fragment,null,d().createElement(ra.A,{sx:{fontSize:14}})," 검색"))),d().createElement("div",{className:"athena-sidebar-content"},ie?d().createElement("div",{className:"athena-sidebar-detail"},d().createElement("button",{className:"athena-sidebar-back",onClick:()=>de(null)},d().createElement(la.A,{sx:{fontSize:13}})," 목록으로"),d().createElement("div",{className:"athena-sidebar-table-header"},d().createElement("div",{className:"athena-sidebar-table-name"},ie.table_name),d().createElement("div",{className:"athena-sidebar-table-korean"},ie.korean_name)),ie.payload&&d().createElement("div",{className:"athena-sidebar-meta"},Object.entries(ie.payload).map(([e,t])=>e.startsWith("_")||"table_name"===e||"테이블명"===e||"korean_name"===e||"테이블한글명"===e?null:d().createElement("div",{key:e,className:"athena-sidebar-meta-row"},d().createElement("span",{className:"athena-sidebar-meta-key"},e),d().createElement("span",{className:"athena-sidebar-meta-val"},String(t))))),d().createElement("div",{className:"athena-sidebar-columns-header"},d().createElement("span",{className:"athena-sidebar-columns-title"},"컬럼 ",pe?"":`(${Xe.length}${Be?`/${ue.length}`:""})`),ue.length>0&&d().createElement("input",{type:"text",className:"athena-sidebar-col-filter",placeholder:"컬럼 검색...",value:Be,onChange:e=>{We(e.target.value),fe(0)}}),Ke>1&&d().createElement("div",{className:"athena-sidebar-col-pager"},d().createElement("button",{disabled:0===ge,onClick:()=>fe(e=>e-1)},"<"),d().createElement("span",null,ge+1,"/",Ke),d().createElement("button",{disabled:ge>=Ke-1&&!Ue.current,onClick:async()=>{const e=ge+1;if((e+1)*be>ue.length&&Ue.current){he(!0);try{await Ve(Je.current,He.current,!0)}finally{he(!1)}}fe(e)}},">"))),pe?d().createElement("div",{className:"athena-sidebar-loading"},d().createElement("span",{className:"athena-spinner-sm"})," 로딩 중..."):Xe.length>0&&"object"==typeof Xe[0]&&!Array.isArray(Xe[0])?(()=>{const e=["컬럼명","컬럼한글명","컬럼타입","컬럼소수점자리수","PK여부","파기컬럼여부"],t=Object.keys(Xe[0]).filter(e=>!e.includes("원천")&&"파티션컬럼여부"!==e),n=[...e.filter(e=>t.includes(e)),...t.filter(t=>!e.includes(t))];return d().createElement("div",{className:"athena-sidebar-columns-table-wrap"},d().createElement("table",{className:"athena-sidebar-columns-table"},d().createElement("thead",null,d().createElement("tr",null,n.map(e=>d().createElement("th",{key:e},e)))),d().createElement("tbody",null,Ze.map((e,t)=>d().createElement("tr",{key:t},n.map((t,n)=>{const a=e[t],r=String(a??""),s=t.endsWith("여부")?"Y"===r.toUpperCase()?"Y":"":r;return d().createElement("td",{key:n},s)}))))))})():d().createElement("div",{className:"athena-sidebar-columns"},0===ue.length&&d().createElement("div",{className:"athena-sidebar-empty"},"컬럼 정보 없음"),ue.length>0&&0===Xe.length&&d().createElement("div",{className:"athena-sidebar-empty"},"검색 결과 없음"))):d().createElement("div",{className:"athena-sidebar-list"},ae.map((e,t)=>d().createElement("div",{key:t,className:"athena-sidebar-item",onClick:()=>Ge(e)},d().createElement("div",{className:"athena-sidebar-item-name"},e.table_name),d().createElement("div",{className:"athena-sidebar-item-korean"},e.korean_name),e.score&&d().createElement("span",{className:"athena-sidebar-item-score"},(100*e.score).toFixed(0),"%"))),0===ae.length&&!se&&Y&&d().createElement("div",{className:"athena-sidebar-empty"},"검색 결과가 없습니다"),0===ae.length&&!Y&&d().createElement("div",{className:"athena-sidebar-empty athena-sidebar-empty-icon"},d().createElement("svg",{width:"84",height:"84",viewBox:"0 0 24 24",fill:"none",strokeLinecap:"round",strokeLinejoin:"round"},d().createElement("ellipse",{cx:"9",cy:"5",rx:"7",ry:"2.5",stroke:"#e2e8f0",strokeWidth:"1.5"}),d().createElement("path",{d:"M2 5v10c0 1.38 3.13 2.5 7 2.5",stroke:"#e2e8f0",strokeWidth:"1.5"}),d().createElement("path",{d:"M16 5v2",stroke:"#e2e8f0",strokeWidth:"1.5"}),d().createElement("path",{d:"M2 10c0 1.38 3.13 2.5 7 2.5s7-1.12 7-2.5",stroke:"#e2e8f0",strokeWidth:"1.5"}),d().createElement("circle",{cx:"17",cy:"16",r:"4",stroke:"#e5e7eb",strokeWidth:"1.5"}),d().createElement("path",{d:"M20 19.5l2 2",stroke:"#e5e7eb",strokeWidth:"2"})))))))))};function ka(){return c.URLExt.join(c.PageConfig.getBaseUrl(),"codebuff")}function wa(){const e=`; ${document.cookie}`.split("; _xsrf=");return 2===e.length&&e.pop()?.split(";").shift()||""}const xa=()=>{const[e,t]=(0,i.useState)("cases"),[n,a]=(0,i.useState)([]),[r,s]=(0,i.useState)(new Set),[o,l]=(0,i.useState)("guide_docs"),[c,u]=(0,i.useState)([]),[m,p]=(0,i.useState)(new Set),[h,g]=(0,i.useState)(!1),[f,b]=(0,i.useState)({current:0,total:0,source:""}),[v,y]=(0,i.useState)([]),[E,k]=(0,i.useState)(!1),[w,x]=(0,i.useState)({current:0,total:0}),[S,_]=(0,i.useState)([]),[C,N]=(0,i.useState)(null),[j,$]=(0,i.useState)(""),[T,A]=(0,i.useState)([]),[I,P]=(0,i.useState)(new Set),[L,M]=(0,i.useState)(null),[R,q]=(0,i.useState)(null),[D,O]=(0,i.useState)(null),z=d().useRef(null),[F,B]=(0,i.useState)(null);(0,i.useEffect)(()=>{fetch(`${ka()}/benchmark/test-cases`).then(e=>e.json()).then(a).catch(()=>{})},[]),(0,i.useEffect)(()=>{"history"===e&&fetch(`${ka()}/benchmark/results`).then(e=>e.json()).then(A).catch(()=>{})},[e]),(0,i.useEffect)(()=>{fetch(`${ka()}/benchmark/sources?collection=${o}`).then(e=>e.json()).then(e=>u(e.sources||[])).catch(()=>{})},[o]);const W=(0,i.useCallback)(async e=>{const t=n.find(t=>t.id===e.id),r=t?"update":"add";await fetch(`${ka()}/benchmark/test-cases`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":wa()},body:JSON.stringify({action:r,id:e.id,test_case:e})}),a(t?t=>t.map(t=>t.id===e.id?e:t):t=>[...t,e]),B(null)},[n]),U=(0,i.useCallback)(async e=>{await fetch(`${ka()}/benchmark/test-cases`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":wa()},body:JSON.stringify({action:"delete",id:e})}),a(t=>t.filter(t=>t.id!==e))},[]),H=(0,i.useCallback)(async()=>{g(!0),y([]),b({current:0,total:0,source:""});try{const e=await fetch(`${ka()}/benchmark/generate`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":wa()},body:JSON.stringify({collection:o,sources:Array.from(m),per_source:1})}),t=e.body?.getReader();if(!t)return;const n=new TextDecoder;let a="";for(;;){const{done:e,value:r}=await t.read();if(e)break;a+=n.decode(r,{stream:!0});const s=a.split("\n");a=s.pop()||"";for(const e of s)if(e.startsWith("data: "))try{const t=JSON.parse(e.slice(6));"progress"===t.type?b({current:t.current,total:t.total,source:t.source||""}):"case"===t.type&&y(e=>[...e,t.test_case])}catch{}}}catch{}finally{g(!1)}},[o,m]),J=(0,i.useCallback)(async e=>{const t=[...n,...e];await fetch(`${ka()}/benchmark/test-cases`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":wa()},body:JSON.stringify({action:"save_all",test_cases:t})}),a(t),y([])},[n]),V=(0,i.useCallback)(async()=>{k(!0),_([]),N(null),x({current:0,total:0}),t("run");const e=new AbortController;z.current=e;try{const t=r.size>0?Array.from(r):null,n=await fetch(`${ka()}/benchmark/run`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":wa()},body:JSON.stringify({test_case_ids:t,memo:j}),signal:e.signal}),a=n.body?.getReader();if(!a)return;const s=new TextDecoder;let o="";for(;;){const{done:e,value:t}=await a.read();if(e)break;o+=s.decode(t,{stream:!0});const n=o.split("\n");o=n.pop()||"";for(const e of n)if(e.startsWith("data: "))try{const t=JSON.parse(e.slice(6));"progress"===t.type?x({current:t.current,total:t.total}):"case_result"===t.type?_(e=>[...e,t.result]):"complete"===t.type&&N(t.summary)}catch{}}}catch(e){"AbortError"!==e.name&&console.error("Benchmark run error:",e)}finally{k(!1),z.current=null}},[r,j]),G=(0,i.useCallback)(()=>{z.current?.abort()},[]),X=(0,i.useCallback)(async()=>{const e=Array.from(I);if(2===e.length)try{const[t,n]=await Promise.all(e.map(e=>fetch(`${ka()}/benchmark/results?id=${e}`).then(e=>e.json())));M({a:t,b:n})}catch{}},[I]),Z=e=>Math.round(100*e)/100,K=(e,t=10)=>{const n=e/t;return n>=.8?"#16a34a":n>=.5?"#d97706":"#dc2626"},Q=(e,t=10)=>{const n=e/t,a=n>=.8?"#16a34a":n>=.5?"#f59e0b":"#dc2626";return d().createElement("span",{style:{color:a,fontWeight:700}},"●")};return d().createElement("div",{className:"benchmark-panel"},d().createElement("div",{className:"benchmark-header"},d().createElement("div",{className:"benchmark-header-title"},"RAG Benchmark"),d().createElement("div",{className:"benchmark-header-sub"},"Chat 응답 품질 평가 (Knowledge 검색)")),d().createElement("div",{className:"benchmark-tabs"},d().createElement("button",{className:"benchmark-tab "+("cases"===e?"active":""),onClick:()=>t("cases")},"테스트 케이스 (",n.length,")"),d().createElement("button",{className:"benchmark-tab "+("run"===e?"active":""),onClick:()=>t("run")},"실행 결과"),d().createElement("button",{className:"benchmark-tab "+("history"===e?"active":""),onClick:()=>t("history")},"히스토리")),d().createElement("div",{className:"benchmark-body"},"cases"===e&&d().createElement("div",{className:"benchmark-cases"},d().createElement("div",{className:"benchmark-actions"},d().createElement("button",{className:"benchmark-btn benchmark-btn-primary",onClick:()=>B({id:"",category:"guide_docs",question:"",ground_truth:"",must_not_contain:[],difficulty:"medium"})},"+ 케이스 추가"),E?d().createElement("button",{className:"benchmark-btn benchmark-btn-stop",onClick:G},"■ 중지"):d().createElement("button",{className:"benchmark-btn benchmark-btn-execute",onClick:V,disabled:0===n.length},"▶ 실행 (",r.size>0?`${r.size}개`:"전체",")"),d().createElement("input",{type:"text",className:"benchmark-memo-input",placeholder:"실행 메모 (예: grounding 프롬프트 강화)",value:j,onChange:e=>$(e.target.value)})),d().createElement("div",{className:"benchmark-generate-section"},d().createElement("div",{className:"benchmark-generate-header"},d().createElement("span",{className:"benchmark-section-title"},"자동 생성"),d().createElement("select",{"aria-label":"자동 생성 대상 컬렉션",value:o,onChange:e=>l(e.target.value),className:"benchmark-select"},d().createElement("option",{value:"guide_docs"},"guide_docs"),d().createElement("option",{value:"ds_guide_docs"},"ds_guide_docs"),d().createElement("option",{value:"bdp_tables"},"bdp_tables")),d().createElement("button",{className:"benchmark-btn",onClick:H,disabled:h||0===m.size},h?"생성 중...":"생성")),d().createElement("div",{className:"benchmark-sources-actions"},d().createElement("button",{className:"benchmark-btn",style:{fontSize:11,padding:"3px 8px"},onClick:()=>{m.size===c.length?p(new Set):p(new Set(c.map(e=>e.source)))}},m.size===c.length?"전체 해제":"전체 선택"),d().createElement("span",{style:{fontSize:11,color:"#9ca3af"}},m.size,"/",c.length," 선택")),d().createElement("div",{className:"benchmark-sources-list"},c.map(e=>d().createElement("label",{key:e.source,className:"benchmark-source-item"},d().createElement("input",{type:"checkbox",checked:m.has(e.source),onChange:()=>p(t=>{const n=new Set(t);return n.has(e.source)?n.delete(e.source):n.add(e.source),n})}),d().createElement("span",{className:"benchmark-source-name"},e.source),d().createElement("span",{className:"benchmark-source-chunks"},e.chunks," chunks")))),h&&f.total>0&&d().createElement("div",{className:"benchmark-gen-progress"},d().createElement("div",{className:"benchmark-progress-text"},"생성 중... ",f.current,"/",f.total," — ",f.source),d().createElement("div",{className:"benchmark-progress-bar"},d().createElement("div",{className:"benchmark-progress-fill",style:{width:f.current/f.total*100+"%"}}))),v.length>0&&d().createElement("div",{className:"benchmark-gen-preview"},d().createElement("div",{className:"benchmark-section-title"},"생성된 케이스 (",v.length,"개) — 검수 후 추가"),v.map((e,t)=>d().createElement("div",{key:t,className:"benchmark-gen-item"},d().createElement("div",{className:"benchmark-gen-field"},d().createElement("span",{className:"benchmark-gen-label"},"Q:"),d().createElement("textarea",{className:"benchmark-gen-input","aria-label":`생성된 케이스 ${t+1} 질문`,value:e.question,rows:2,onChange:e=>y(n=>n.map((n,a)=>a===t?{...n,question:e.target.value}:n))})),d().createElement("div",{className:"benchmark-gen-field"},d().createElement("span",{className:"benchmark-gen-label"},"A:"),d().createElement("textarea",{className:"benchmark-gen-input","aria-label":`생성된 케이스 ${t+1} 정답`,value:e.ground_truth,rows:3,onChange:e=>y(n=>n.map((n,a)=>a===t?{...n,ground_truth:e.target.value}:n))})),d().createElement("div",{className:"benchmark-gen-footer"},d().createElement("span",{className:"benchmark-gen-src"},"출처: ",e.source),d().createElement("div",{className:"benchmark-gen-actions"},d().createElement("button",{className:"benchmark-btn",style:{fontSize:11,padding:"3px 8px"},onClick:()=>{J([e]),y(e=>e.filter((e,n)=>n!==t))}},"✓ 추가"),d().createElement("button",{className:"benchmark-btn-icon",onClick:()=>y(e=>e.filter((e,n)=>n!==t))},"✕"))))),d().createElement("button",{className:"benchmark-btn benchmark-btn-primary",onClick:()=>{J(v),y([])}},"전체 추가 (",v.length,"개)"))),d().createElement("div",{className:"benchmark-case-list"},n.map(e=>d().createElement("div",{key:e.id,className:"benchmark-case-item"},d().createElement("input",{type:"checkbox","aria-label":`케이스 선택: ${e.question}`,checked:r.has(e.id),onChange:()=>s(t=>{const n=new Set(t);return n.has(e.id)?n.delete(e.id):n.add(e.id),n})}),d().createElement("div",{className:"benchmark-case-content",onClick:()=>B(e)},d().createElement("div",{className:"benchmark-case-q"},e.question),d().createElement("div",{className:"benchmark-case-meta"},d().createElement("span",{className:"benchmark-case-category"},e.category),d().createElement("span",{className:"benchmark-case-difficulty"},e.difficulty),e.source&&d().createElement("span",{className:"benchmark-case-source"},e.source))),d().createElement("button",{className:"benchmark-btn-icon",onClick:()=>U(e.id),title:"삭제"},"✕"))),0===n.length&&d().createElement("div",{className:"benchmark-empty"},"테스트 케이스가 없습니다. 위에서 자동 생성하거나 수동으로 추가하세요."))),"run"===e&&d().createElement("div",{className:"benchmark-run"},E&&d().createElement("div",{className:"benchmark-progress"},d().createElement("div",{className:"benchmark-progress-text"},"실행 중... ",w.current,"/",w.total),d().createElement("div",{className:"benchmark-progress-bar"},d().createElement("div",{className:"benchmark-progress-fill",style:{width:(w.total?w.current/w.total*100:0)+"%"}}))),C&&d().createElement("div",{className:"benchmark-summary"},d().createElement("div",{className:"benchmark-summary-title"},"종합 결과"),d().createElement("div",{className:"benchmark-summary-cards"},d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Overall"),d().createElement("div",{className:"benchmark-score-value",style:{color:K(C.overall,100)}},C.overall),d().createElement("div",{className:"benchmark-score-max"},"/ 100")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Faithfulness"),d().createElement("div",{className:"benchmark-score-value",style:{color:K(C.faithfulness)}},C.faithfulness),d().createElement("div",{className:"benchmark-score-max"},"/ 10")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Completeness"),d().createElement("div",{className:"benchmark-score-value",style:{color:K(C.completeness)}},C.completeness),d().createElement("div",{className:"benchmark-score-max"},"/ 10")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Hallucination"),d().createElement("div",{className:"benchmark-score-value",style:{color:C.total_hallucinated_claims>0?"#dc2626":"#16a34a"}},C.total_hallucinated_claims,"건"),d().createElement("div",{className:"benchmark-score-max"},C.cases_with_hallucination,"케이스")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Avg Time"),d().createElement("div",{className:"benchmark-score-value"},C.avg_response_time,"s")),C.data_mismatch_cases>0&&d().createElement("div",{className:"benchmark-score-card",style:{borderColor:"#f59e0b"}},d().createElement("div",{className:"benchmark-score-label"},"Data Mismatch"),d().createElement("div",{className:"benchmark-score-value",style:{color:"#f59e0b"}},C.data_mismatch_cases),d().createElement("div",{className:"benchmark-score-max"},"케이스")))),d().createElement("div",{className:"benchmark-results-list"},S.map((e,t)=>d().createElement("details",{key:t,className:"benchmark-result-item"},d().createElement("summary",{className:"benchmark-result-summary"},d().createElement("span",{className:"benchmark-result-id"},e.case_id),d().createElement("span",{className:"benchmark-result-score"},e.scores.overall?`${e.scores.overall}점`:"에러"),d().createElement("span",null,Q(e.scores.faithfulness||0)," F:",e.scores.faithfulness||"-"),d().createElement("span",null,Q(e.scores.completeness||0)," C:",e.scores.completeness||"-"),d().createElement("span",null,"🔍",e.scores.search_count||0,e.scores.re_search_count>0?`(+${e.scores.re_search_count})`:""),e.scores.effort_bonus>0&&d().createElement("span",{style:{color:"#7c3aed",fontWeight:600}},"+",e.scores.effort_bonus),e.data_mismatch&&d().createElement("span",{style:{color:"#f59e0b",fontWeight:600,fontSize:10}},"⚠ 데이터불일치"),d().createElement("span",null,e.scores.response_time,"s")),d().createElement("div",{className:"benchmark-result-detail"},d().createElement("div",{className:"benchmark-result-section"},d().createElement("strong",null,"Q:")," ",e.question),d().createElement("div",{className:"benchmark-result-section"},d().createElement("strong",null,"응답:"),d().createElement("div",{className:"benchmark-result-response"},e.response)),e.data_mismatch&&d().createElement("div",{className:"benchmark-result-section",style:{background:"#fffbeb",padding:8,borderRadius:4,color:"#92400e"}},d().createElement("strong",null,"⚠ 데이터 불일치 감지:")," ",e.data_mismatch_reason),e.scores.hallucinated_claims&&e.scores.hallucinated_claims.length>0&&d().createElement("div",{className:"benchmark-result-section benchmark-result-halluc"},d().createElement("strong",null,"⚠ 할루시네이션:"),d().createElement("ul",null,e.scores.hallucinated_claims.map((e,t)=>d().createElement("li",{key:t},e)))),e.scores.comment&&d().createElement("div",{className:"benchmark-result-section"},d().createElement("strong",null,"평가:")," ",e.scores.comment)))))),"history"===e&&d().createElement("div",{className:"benchmark-history"},d().createElement("div",{className:"benchmark-actions"},d().createElement("button",{className:"benchmark-btn",onClick:X,disabled:2!==I.size},"비교 (",I.size,"/2 선택)"),d().createElement("button",{className:"benchmark-btn benchmark-btn-stop",onClick:async()=>{if(0===I.size)return;const e=Array.from(I);await fetch(`${ka()}/benchmark/results`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":wa()},body:JSON.stringify({action:"delete",ids:e})}),A(e=>e.filter(e=>!I.has(e.id))),P(new Set),M(null)},disabled:0===I.size},"삭제 (",I.size,"개)")),d().createElement("div",{className:"benchmark-history-list"},T.map(e=>d().createElement("div",{key:e.id,className:"benchmark-history-entry"},d().createElement("div",{className:"benchmark-history-item"},d().createElement("input",{type:"checkbox","aria-label":`실행 이력 선택: ${e.date?.slice(0,16)} ${e.memo||"(메모 없음)"}`,checked:I.has(e.id),onClick:e=>e.stopPropagation(),onChange:()=>P(t=>{const n=new Set(t);return n.has(e.id)?n.delete(e.id):n.add(e.id),n})}),d().createElement("div",{className:"benchmark-history-info",style:{cursor:"pointer"},onClick:async()=>{if(R===e.id)q(null),O(null);else{q(e.id);try{const t=await fetch(`${ka()}/benchmark/results?id=${e.id}`);O(await t.json())}catch{O(null)}}}},d().createElement("div",{className:"benchmark-history-date"},R===e.id?"▾":"▸"," ",e.date?.slice(0,16)),d().createElement("div",{className:"benchmark-history-memo"},e.memo||"(메모 없음)")),d().createElement("div",{className:"benchmark-history-score"},e.summary?.overall||"-","점"),d().createElement("div",{className:"benchmark-history-count"},e.total_cases,"케이스")),R===e.id&&D&&(()=>{const e=D.summary||{},t=D.results||[];return d().createElement("div",{className:"benchmark-history-detail"},d().createElement("div",{className:"benchmark-summary-cards",style:{marginBottom:8}},d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Overall"),d().createElement("div",{className:"benchmark-score-value",style:{color:K(e.overall||0,100)}},e.overall||"-"),d().createElement("div",{className:"benchmark-score-max"},"/ 100")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Correctness"),d().createElement("div",{className:"benchmark-score-value",style:{color:K(e.correctness||0)}},e.correctness||"-"),d().createElement("div",{className:"benchmark-score-max"},"/ 10")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Completeness"),d().createElement("div",{className:"benchmark-score-value",style:{color:K(e.completeness||0)}},e.completeness||"-"),d().createElement("div",{className:"benchmark-score-max"},"/ 10")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Faithfulness"),d().createElement("div",{className:"benchmark-score-value",style:{color:K(e.faithfulness||0)}},e.faithfulness||"-"),d().createElement("div",{className:"benchmark-score-max"},"/ 10")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Conciseness"),d().createElement("div",{className:"benchmark-score-value",style:{color:K(e.conciseness||0)}},e.conciseness||"-"),d().createElement("div",{className:"benchmark-score-max"},"/ 10")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Hallucination"),d().createElement("div",{className:"benchmark-score-value",style:{color:(e.total_hallucinated_claims||0)>0?"#dc2626":"#16a34a"}},e.total_hallucinated_claims||0,"건"),d().createElement("div",{className:"benchmark-score-max"},e.cases_with_hallucination||0,"케이스")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"Avg Time"),d().createElement("div",{className:"benchmark-score-value"},e.avg_response_time||"-","s"))),d().createElement("div",{className:"benchmark-section-title",style:{fontSize:11,marginTop:4}},"개별 결과 (",t.length,"건)"),d().createElement("div",{style:{maxHeight:300,overflowY:"auto"}},t.map((e,t)=>d().createElement("details",{key:t,className:"benchmark-result-item"},d().createElement("summary",{className:"benchmark-result-summary"},d().createElement("span",{className:"benchmark-result-id"},e.case_id),d().createElement("span",{className:"benchmark-result-score"},e.scores?.overall?`${e.scores.overall}점`:"에러"),d().createElement("span",null,Q(e.scores?.faithfulness||0)," F:",e.scores?.faithfulness||"-"),d().createElement("span",null,Q(e.scores?.completeness||0)," C:",e.scores?.completeness||"-")),d().createElement("div",{className:"benchmark-result-detail"},d().createElement("div",{className:"benchmark-result-section"},d().createElement("strong",null,"Q:")," ",e.question),d().createElement("div",{className:"benchmark-result-section"},d().createElement("strong",null,"응답:"),d().createElement("div",{className:"benchmark-result-response"},e.response)),e.scores?.comment&&d().createElement("div",{className:"benchmark-result-section"},d().createElement("strong",null,"평가:")," ",e.scores.comment))))))})()))),L&&(()=>{const e=L.a.summary||{},t=L.b.summary||{},n=L.a.memo||L.a.date?.slice(0,16),a=L.b.memo||L.b.date?.slice(0,16);return d().createElement("div",{className:"benchmark-compare"},d().createElement("div",{className:"benchmark-section-title"},"전체 스코어 비교"),d().createElement("table",{className:"benchmark-compare-table",style:{marginBottom:16}},d().createElement("thead",null,d().createElement("tr",null,d().createElement("th",null,"Metric"),d().createElement("th",null,n),d().createElement("th",null,a),d().createElement("th",null,"Delta"))),d().createElement("tbody",null,[{key:"overall",label:"Overall",max:100},{key:"correctness",label:"Correctness",max:10},{key:"completeness",label:"Completeness",max:10},{key:"faithfulness",label:"Faithfulness",max:10},{key:"conciseness",label:"Conciseness",max:10}].map(n=>{const a=e[n.key]||0,r=t[n.key]||0,s=Z(r-a);return d().createElement("tr",{key:n.key},d().createElement("td",{style:{fontWeight:600}},n.label),d().createElement("td",null,a),d().createElement("td",null,r),d().createElement("td",{style:{color:s>0?"#16a34a":s<0?"#dc2626":"#6b7280",fontWeight:600}},s>0?"▲":s<0?"▼":"─"," ",Math.abs(s)))}),d().createElement("tr",null,d().createElement("td",{style:{fontWeight:600}},"Hallucination"),d().createElement("td",null,e.total_hallucinated_claims||0,"건"),d().createElement("td",null,t.total_hallucinated_claims||0,"건"),d().createElement("td",{style:{color:(t.total_hallucinated_claims||0)<(e.total_hallucinated_claims||0)?"#16a34a":(t.total_hallucinated_claims||0)>(e.total_hallucinated_claims||0)?"#dc2626":"#6b7280",fontWeight:600}},(t.total_hallucinated_claims||0)<(e.total_hallucinated_claims||0)?"▼":(t.total_hallucinated_claims||0)>(e.total_hallucinated_claims||0)?"▲":"─"," ",Math.abs((t.total_hallucinated_claims||0)-(e.total_hallucinated_claims||0)))),d().createElement("tr",null,d().createElement("td",{style:{fontWeight:600}},"Avg Time"),d().createElement("td",null,e.avg_response_time||"-","s"),d().createElement("td",null,t.avg_response_time||"-","s"),d().createElement("td",null,Z((t.avg_response_time||0)-(e.avg_response_time||0)),"s")))),d().createElement("div",{className:"benchmark-section-title"},"케이스별 비교"),d().createElement("table",{className:"benchmark-compare-table"},d().createElement("thead",null,d().createElement("tr",null,d().createElement("th",null,"케이스"),d().createElement("th",null,n),d().createElement("th",null,a),d().createElement("th",null,"Delta"))),d().createElement("tbody",null,(L.b.results||[]).map(e=>{const t=(L.a.results||[]).find(t=>t.case_id===e.case_id),n=t?.scores?.overall||0,a=e.scores?.overall||0,r=Z(a-n);return d().createElement("tr",{key:e.case_id},d().createElement("td",null,e.case_id),d().createElement("td",null,n),d().createElement("td",null,a),d().createElement("td",{style:{color:r>0?"#16a34a":r<0?"#dc2626":"#6b7280"}},r>0?"▲":r<0?"▼":"─"," ",Math.abs(r)))}))))})())),F&&d().createElement("div",{className:"benchmark-modal-overlay",onClick:()=>B(null)},d().createElement("div",{className:"benchmark-modal",onClick:e=>e.stopPropagation()},d().createElement("div",{className:"benchmark-modal-title"},F.id?"케이스 편집":"케이스 추가"),d().createElement("label",null,"카테고리",d().createElement("select",{value:F.category,onChange:e=>B({...F,category:e.target.value})},d().createElement("option",{value:"guide_docs"},"guide_docs"),d().createElement("option",{value:"bdp_tables"},"bdp_tables"),d().createElement("option",{value:"hallucination_trap"},"hallucination_trap"),d().createElement("option",{value:"multi_hop"},"multi_hop"))),d().createElement("label",null,"질문",d().createElement("textarea",{value:F.question,onChange:e=>B({...F,question:e.target.value}),rows:2})),d().createElement("label",null,"기대 답변 (Ground Truth)",d().createElement("textarea",{value:F.ground_truth,onChange:e=>B({...F,ground_truth:e.target.value}),rows:3})),d().createElement("label",null,"난이도",d().createElement("select",{value:F.difficulty,onChange:e=>B({...F,difficulty:e.target.value})},d().createElement("option",{value:"easy"},"easy"),d().createElement("option",{value:"medium"},"medium"),d().createElement("option",{value:"hard"},"hard"))),d().createElement("div",{className:"benchmark-modal-actions"},d().createElement("button",{className:"benchmark-btn",onClick:()=>B(null)},"취소"),d().createElement("button",{className:"benchmark-btn benchmark-btn-primary",onClick:()=>W({...F,id:F.id||`tc_${Math.random().toString(36).slice(2,10)}`})},"저장")))))};function Sa(){return c.URLExt.join(c.PageConfig.getBaseUrl(),"codebuff")}function _a(){const e=`; ${document.cookie}`.split("; _xsrf=");return 2===e.length&&e.pop()?.split(";").shift()||""}const Ca=()=>{const[e,t]=(0,i.useState)("cases"),[n,a]=(0,i.useState)([]),[r,s]=(0,i.useState)(new Set),[o,l]=(0,i.useState)([]),[c,u]=(0,i.useState)(new Set),[m,p]=(0,i.useState)(!1),[h,g]=(0,i.useState)({current:0,total:0}),[f,b]=(0,i.useState)([]),[v,y]=(0,i.useState)(3),[E,k]=(0,i.useState)(null),[w,x]=(0,i.useState)(!1),[S,_]=(0,i.useState)({current:0,total:0}),[C,N]=(0,i.useState)([]),[j,$]=(0,i.useState)(null),[T,A]=(0,i.useState)(""),[I,P]=(0,i.useState)([]),[L,M]=(0,i.useState)(null),[R,q]=(0,i.useState)(null),D=d().useRef(null);(0,i.useEffect)(()=>{fetch(`${Sa()}/eda-benchmark/test-cases`).then(e=>e.json()).then(a).catch(()=>{})},[]),(0,i.useEffect)(()=>{"history"===e&&fetch(`${Sa()}/eda-benchmark/results`).then(e=>e.json()).then(P).catch(()=>{})},[e]),(0,i.useEffect)(()=>{fetch(`${Sa()}/eda-benchmark/sources`).then(e=>e.json()).then(e=>l(e.tables||[])).catch(()=>{})},[]);const O=(0,i.useCallback)(async()=>{p(!0),b([]),g({current:0,total:0});const e=c.size>0?Array.from(c):[];try{const t=await fetch(`${Sa()}/eda-benchmark/generate`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":_a()},body:JSON.stringify({tables:e,per_difficulty:v})}),n=t.body?.getReader();if(!n)return;const a=new TextDecoder;let r="";const s=[];for(;;){const{done:e,value:t}=await n.read();if(e)break;r+=a.decode(t,{stream:!0});const o=r.split("\n");r=o.pop()||"";for(const e of o)if(e.startsWith("data: "))try{const t=JSON.parse(e.slice(6));"progress"===t.type&&g({current:t.current,total:t.total}),"case"===t.type&&(s.push(t.test_case),b([...s]))}catch{}}}catch{}p(!1)},[c,v]),z=(0,i.useCallback)(async()=>{const e=[...n,...f];await fetch(`${Sa()}/eda-benchmark/test-cases`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":_a()},body:JSON.stringify({action:"save_all",test_cases:e})}),a(e),b([])},[n,f]),F=(0,i.useCallback)(async()=>{x(!0),N([]),$(null),_({current:0,total:0});const e=r.size>0?Array.from(r):void 0,t=new AbortController;D.current=t;try{const n=await fetch(`${Sa()}/eda-benchmark/run`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":_a()},body:JSON.stringify({test_case_ids:e,memo:T}),signal:t.signal}),a=n.body?.getReader();if(!a)return;const r=new TextDecoder;let s="";const o=[];for(;;){const{done:e,value:t}=await a.read();if(e)break;s+=r.decode(t,{stream:!0});const n=s.split("\n");s=n.pop()||"";for(const e of n)if(e.startsWith("data: "))try{const t=JSON.parse(e.slice(6));"progress"===t.type&&_({current:t.current,total:t.total}),"case_result"===t.type&&(o.push(t.result),N([...o])),"complete"===t.type&&$(t.summary)}catch{}}}catch{}x(!1),D.current=null},[r,T]),B=(0,i.useCallback)(()=>{D.current?.abort()},[]),W=(0,i.useCallback)(async e=>{const t=n.filter(t=>t.id!==e);await fetch(`${Sa()}/eda-benchmark/test-cases`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":_a()},body:JSON.stringify({action:"save_all",test_cases:t})}),a(t),r.delete(e),s(new Set(r))},[n,r]),U=(0,i.useCallback)(async e=>{if(L===e)return void M(null);const t=await fetch(`${Sa()}/eda-benchmark/results?id=${e}`),n=await t.json();q(n),M(e)},[L]),H=(0,i.useCallback)(async()=>{const e=I.map(e=>e.id);await fetch(`${Sa()}/eda-benchmark/results`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":_a()},body:JSON.stringify({action:"delete",ids:e})}),P([])},[I]),J=e=>e>=8?"#16a34a":e>=5?"#f59e0b":"#dc2626",V=e=>{return e.title||e.description,d().createElement("details",{className:"benchmark-result-item",style:{margin:"2px 0",overflow:"visible"}},d().createElement("summary",{className:"benchmark-result-summary",style:{flexWrap:"wrap",gap:"4px 10px"}},d().createElement("span",{className:"benchmark-result-score",style:{color:e.scores?.overall>=80?"#16a34a":e.scores?.overall>=50?"#f59e0b":"#dc2626",fontWeight:700,minWidth:45,textAlign:"right"}},e.scores?.overall??"-"),d().createElement("span",{className:"benchmark-result-id",style:{minWidth:80}},e.case_id),d().createElement("span",{className:"benchmark-case-category"},e.type),d().createElement("span",null,(t=e.scores?.explain_final,t?"✅":"❌")),d().createElement("span",null,"Fix:",e.scores?.fix_count||0),d().createElement("span",null,e.scores?.response_time,"s"),d().createElement("span",{style:{fontSize:10,color:"var(--jp-ui-font-color2,#9ca3af)"}},e.path_used)),d().createElement("div",{style:{padding:12,borderTop:"1px solid var(--jp-border-color2,#e5e7eb)",fontSize:12}},d().createElement("div",{style:{marginBottom:8}},d().createElement("strong",null,"Q:")," ",e.question),e.selected_tables?.length>0&&d().createElement("div",{style:{marginBottom:8,fontSize:11,color:"var(--jp-ui-font-color2,#6b7280)"}},d().createElement("strong",null,"선택 테이블:")," ",e.selected_tables.join(", ")),e.title&&d().createElement("div",{style:{marginBottom:8,padding:"6px 10px",background:"var(--jp-layout-color2,#f8fafc)",borderRadius:4,borderLeft:"3px solid #7c3aed"}},d().createElement("div",{style:{fontSize:10,fontWeight:600,color:"var(--jp-ui-font-color2,#6b7280)",marginBottom:2}},"Title"),d().createElement("div",null,e.title)),e.description&&d().createElement("div",{style:{marginBottom:8,padding:"6px 10px",background:"var(--jp-layout-color2,#f8fafc)",borderRadius:4,borderLeft:"3px solid #2563eb"}},d().createElement("div",{style:{fontSize:10,fontWeight:600,color:"var(--jp-ui-font-color2,#6b7280)",marginBottom:2}},"Description"),d().createElement("div",{style:{whiteSpace:"pre-wrap",lineHeight:1.5}},e.description)),e.scores?.sql_tables?.length>0&&d().createElement("div",{style:{marginBottom:8,fontSize:11}},d().createElement("strong",null,"SQL 사용 테이블:")," ",e.scores.sql_tables.join(", "),e.expected_tables?.length>0&&d().createElement("span",{style:{color:"var(--jp-ui-font-color2,#6b7280)",marginLeft:8}},"(기대: ",e.expected_tables.join(", "),")")),e.sql&&d().createElement("div",{style:{marginBottom:8}},d().createElement("div",{style:{fontSize:10,fontWeight:600,color:"var(--jp-ui-font-color2,#6b7280)",marginBottom:2}},e.final_sql&&e.final_sql!==e.sql?"초기 SQL":"SQL"),d().createElement("pre",{style:{background:"#1e1e1e",color:"#d4d4d4",padding:10,borderRadius:4,fontSize:11,overflow:"auto",maxHeight:300,margin:0,whiteSpace:"pre-wrap"}},e.sql)),e.final_sql&&e.final_sql!==e.sql&&d().createElement("div",{style:{marginBottom:8}},d().createElement("div",{style:{fontSize:10,fontWeight:600,color:"#16a34a",marginBottom:2}},"최종 SQL (Fix 후)"),d().createElement("pre",{style:{background:"#1e1e1e",color:"#d4d4d4",padding:10,borderRadius:4,fontSize:11,overflow:"auto",maxHeight:300,margin:0,whiteSpace:"pre-wrap"}},e.final_sql)),e.error&&d().createElement("div",{style:{marginBottom:8,padding:"6px 10px",background:"#fef2f2",borderRadius:4,color:"#dc2626",fontSize:11}},d().createElement("strong",null,"에러:")," ",e.error),(e.scores?.title_quality||e.scores?.semantic_accuracy)&&d().createElement("div",{style:{display:"flex",gap:12,flexWrap:"wrap",fontSize:11,marginBottom:4,padding:"6px 0",borderTop:"1px solid var(--jp-border-color2,#e5e7eb)"}},e.scores?.title_quality&&d().createElement("span",null,"Title: ",d().createElement("strong",{style:{color:J(e.scores.title_quality)}},e.scores.title_quality,"/10")),e.scores?.description_quality&&d().createElement("span",null,"Desc: ",d().createElement("strong",{style:{color:J(e.scores.description_quality)}},e.scores.description_quality,"/10")),e.scores?.semantic_accuracy&&d().createElement("span",null,"SA: ",d().createElement("strong",{style:{color:J(e.scores.semantic_accuracy)}},e.scores.semantic_accuracy,"/10")),e.scores?.sql_quality&&d().createElement("span",null,"SQL: ",d().createElement("strong",{style:{color:J(e.scores.sql_quality)}},e.scores.sql_quality,"/10")),void 0!==e.scores?.column_accuracy&&d().createElement("span",null,"컬럼: ",d().createElement("strong",null,e.scores.column_accuracy,"%")),void 0!==e.scores?.explain_bonus&&d().createElement("span",null,"EXPLAIN: ",d().createElement("strong",{style:{color:e.scores.explain_bonus>0?"#16a34a":e.scores.explain_bonus<0?"#dc2626":"#6b7280"}},e.scores.explain_bonus>0?"+":"",e.scores.explain_bonus)),e.scores?.partition_missing&&d().createElement("span",{style:{color:"#dc2626"}},"⚠ 파티션 미사용 -10"),e.scores?.plan_tuned&&d().createElement("span",null,"튜닝: ",e.scores?.tune_explain_success?"✅+5":"❌-5"),void 0!==e.scores?.overall&&d().createElement("span",{style:{fontWeight:600}},"Overall: ",e.scores.overall)),e.scores?.eval_comment&&d().createElement("div",{style:{fontSize:11,color:"var(--jp-ui-font-color2,#6b7280)"}},d().createElement("strong",null,"평가:")," ",e.scores.eval_comment)));var t};return d().createElement("div",{className:"benchmark-panel"},d().createElement("div",{className:"benchmark-header"},d().createElement("div",{className:"benchmark-header-title"},"EDA Agent Benchmark"),d().createElement("div",{className:"benchmark-header-sub"},"SQL 생성/튜닝 품질 평가")),d().createElement("div",{className:"benchmark-tabs"},["cases","run","history"].map(n=>d().createElement("button",{key:n,className:"benchmark-tab "+(e===n?"active":""),onClick:()=>t(n)},"cases"===n?"Test Cases":"run"===n?"Run Results":"History"))),d().createElement("div",{className:"benchmark-body"},"cases"===e&&d().createElement("div",null,d().createElement("div",{className:"benchmark-generate-section"},d().createElement("div",{className:"benchmark-section-title"},"테스트 케이스 자동 생성"),d().createElement("div",{className:"benchmark-generate-header"},d().createElement("span",{style:{fontSize:11,color:"#6b7280"}},"난이도별 개수:"),d().createElement("select",{className:"benchmark-select","aria-label":"난이도별 생성 개수",value:v,onChange:e=>y(Number(e.target.value))},[1,2,3,5,10].map(e=>d().createElement("option",{key:e,value:e},e,"개"))),d().createElement("button",{className:"benchmark-btn benchmark-btn-primary",onClick:O,disabled:m},m?"생성 중...":"자동 생성")),d().createElement("div",{className:"benchmark-sources-actions"},d().createElement("span",{style:{fontSize:11,color:"#6b7280"}},"테이블 선택 (",c.size,"/",o.length,"):"),d().createElement("button",{className:"benchmark-btn",style:{fontSize:10,padding:"2px 6px"},onClick:()=>u(new Set(o.map(e=>e.table_name)))},"전체 선택"),d().createElement("button",{className:"benchmark-btn",style:{fontSize:10,padding:"2px 6px"},onClick:()=>u(new Set)},"전체 해제")),d().createElement("div",{className:"benchmark-sources-list"},o.map(e=>d().createElement("div",{key:e.table_name,className:"benchmark-source-item",onClick:()=>{const t=new Set(c);t.has(e.table_name)?t.delete(e.table_name):t.add(e.table_name),u(t)}},d().createElement("input",{type:"checkbox","aria-label":`테이블 선택: ${e.table_name}`,checked:c.has(e.table_name),readOnly:!0}),d().createElement("span",{className:"benchmark-source-name"},e.table_name),d().createElement("span",{style:{fontSize:10,color:"#6b7280"}},e.korean_name),d().createElement("span",{className:"benchmark-source-chunks"},e.column_count,"컬럼")))),m&&h.total>0&&d().createElement("div",{className:"benchmark-gen-progress"},d().createElement("div",{className:"benchmark-progress-text"},h.current,"/",h.total),d().createElement("div",{className:"benchmark-progress-bar"},d().createElement("div",{className:"benchmark-progress-fill",style:{width:h.current/h.total*100+"%"}}))),f.length>0&&d().createElement("div",{className:"benchmark-gen-preview"},d().createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:8}},d().createElement("span",{style:{fontSize:12,fontWeight:600}},f.length,"건 생성됨"),d().createElement("div",{style:{display:"flex",gap:4}},d().createElement("button",{className:"benchmark-btn benchmark-btn-primary",onClick:z},"저장"),d().createElement("button",{className:"benchmark-btn",onClick:()=>b([])},"취소"))),f.map((e,t)=>d().createElement("div",{key:t,className:"benchmark-gen-item"},d().createElement("div",{className:"benchmark-gen-footer",style:{marginBottom:4}},d().createElement("div",{style:{display:"flex",gap:6,alignItems:"center"}},d().createElement("span",{className:"benchmark-case-category"},e.type),d().createElement("span",{className:"benchmark-case-difficulty"},e.difficulty),d().createElement("span",{className:"benchmark-gen-src"},e.expected_tables.join(", "))),d().createElement("button",{className:"benchmark-btn-icon",onClick:()=>{const e=f.filter((e,n)=>n!==t);b(e)}},"✕")),d().createElement("div",{className:"benchmark-gen-field"},d().createElement("span",{className:"benchmark-gen-label"},"Q"),d().createElement("textarea",{className:"benchmark-gen-input",rows:2,value:e.question,"aria-label":`생성된 케이스 ${t+1} 질문`,onChange:e=>{const n=[...f];n[t]={...n[t],question:e.target.value},b(n)}})),"tune"===e.type&&d().createElement("div",{className:"benchmark-gen-field"},d().createElement("span",{className:"benchmark-gen-label"},"SQL"),d().createElement("textarea",{className:"benchmark-gen-input",rows:3,value:e.existing_sql||"","aria-label":`생성된 케이스 ${t+1} SQL`,onChange:e=>{const n=[...f];n[t]={...n[t],existing_sql:e.target.value},b(n)}})),d().createElement("div",{className:"benchmark-gen-field"},d().createElement("span",{className:"benchmark-gen-label",style:{fontSize:10}},"테이블"),d().createElement("input",{className:"benchmark-gen-input",value:e.expected_tables.join(", "),"aria-label":`생성된 케이스 ${t+1} 대상 테이블`,onChange:e=>{const n=[...f];n[t]={...n[t],expected_tables:e.target.value.split(",").map(e=>e.trim()).filter(Boolean)},b(n)}})))))),d().createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginTop:16}},d().createElement("div",{className:"benchmark-section-title",style:{margin:0}},"테스트 케이스 (",n.length,"건)"),n.length>0&&d().createElement("button",{className:"benchmark-btn",style:{fontSize:10,padding:"2px 8px",color:"#dc2626"},onClick:async()=>{await fetch(`${Sa()}/eda-benchmark/test-cases`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":_a()},body:JSON.stringify({action:"save_all",test_cases:[]})}),a([]),s(new Set)}},"전체 삭제")),d().createElement("div",{className:"benchmark-case-list"},n.map((e,t)=>d().createElement("div",{key:e.id,className:"benchmark-case-item",style:{flexDirection:"column",alignItems:"stretch"}},d().createElement("div",{style:{display:"flex",alignItems:"center",gap:8}},d().createElement("input",{type:"checkbox",checked:r.has(e.id),"aria-label":`케이스 선택: ${e.question}`,onChange:()=>{const t=new Set(r);t.has(e.id)?t.delete(e.id):t.add(e.id),s(t)}}),d().createElement("div",{className:"benchmark-case-content",onClick:()=>k(E===e.id?null:e.id),style:{cursor:"pointer"}},d().createElement("div",{className:"benchmark-case-q"},e.question.slice(0,80),e.question.length>80?"...":""),d().createElement("div",{className:"benchmark-case-meta"},d().createElement("span",{className:"benchmark-case-category"},e.type),d().createElement("span",{className:"benchmark-case-difficulty"},e.difficulty),d().createElement("span",{className:"benchmark-case-source"},e.expected_tables.join(", ")))),d().createElement("button",{className:"benchmark-btn-icon",onClick:()=>W(e.id)},"✕")),E===e.id&&d().createElement("div",{style:{marginTop:6,padding:"6px 0 0 24px",borderTop:"1px solid var(--jp-border-color2,#e5e7eb)"}},d().createElement("div",{className:"benchmark-gen-field"},d().createElement("span",{className:"benchmark-gen-label"},"Q"),d().createElement("textarea",{className:"benchmark-gen-input",rows:2,value:e.question,"aria-label":"케이스 질문",onChange:e=>{const r=[...n];r[t]={...r[t],question:e.target.value},a(r)}})),"tune"===e.type&&d().createElement("div",{className:"benchmark-gen-field"},d().createElement("span",{className:"benchmark-gen-label"},"SQL"),d().createElement("textarea",{className:"benchmark-gen-input",rows:6,value:e.existing_sql||"","aria-label":"케이스 SQL",style:{fontFamily:"monospace",fontSize:11},onChange:e=>{const r=[...n];r[t]={...r[t],existing_sql:e.target.value},a(r)}})),d().createElement("div",{className:"benchmark-gen-field"},d().createElement("span",{className:"benchmark-gen-label",style:{fontSize:10}},"테이블"),d().createElement("input",{className:"benchmark-gen-input",value:e.expected_tables.join(", "),"aria-label":"케이스 대상 테이블",onChange:e=>{const r=[...n];r[t]={...r[t],expected_tables:e.target.value.split(",").map(e=>e.trim()).filter(Boolean)},a(r)}})),d().createElement("div",{className:"benchmark-gen-field"},d().createElement("span",{className:"benchmark-gen-label",style:{fontSize:10}},"난이도"),d().createElement("select",{className:"benchmark-select",value:e.difficulty,"aria-label":"케이스 난이도",onChange:e=>{const r=[...n];r[t]={...r[t],difficulty:e.target.value},a(r)}},d().createElement("option",{value:"easy"},"easy"),d().createElement("option",{value:"medium"},"medium"),d().createElement("option",{value:"hard"},"hard"))),d().createElement("div",{style:{display:"flex",justifyContent:"flex-end",gap:4,marginTop:4}},d().createElement("button",{className:"benchmark-btn benchmark-btn-primary",style:{fontSize:10,padding:"3px 8px"},onClick:async()=>{await fetch(`${Sa()}/eda-benchmark/test-cases`,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":_a()},body:JSON.stringify({action:"save_all",test_cases:n})}),k(null)}},"저장"),d().createElement("button",{className:"benchmark-btn",style:{fontSize:10,padding:"3px 8px"},onClick:()=>k(null)},"닫기"))))),0===n.length&&d().createElement("div",{className:"benchmark-empty"},"테스트 케이스가 없습니다. 자동 생성하세요."))),"run"===e&&d().createElement("div",null,d().createElement("div",{className:"benchmark-actions"},d().createElement("input",{className:"benchmark-memo-input",placeholder:"메모 (선택)",value:T,onChange:e=>A(e.target.value)}),w?d().createElement("button",{className:"benchmark-btn benchmark-btn-stop",onClick:B},"■ 중지"):d().createElement("button",{className:"benchmark-btn benchmark-btn-execute",onClick:F,disabled:0===n.length},"▶ 실행 ",r.size>0?`(${r.size}건)`:`(전체 ${n.length}건)`)),w&&d().createElement("div",{className:"benchmark-progress"},d().createElement("div",{className:"benchmark-progress-text"},S.current,"/",S.total," 완료"),d().createElement("div",{className:"benchmark-progress-bar"},d().createElement("div",{className:"benchmark-progress-fill",style:{width:(S.total?S.current/S.total*100:0)+"%"}}))),j&&d().createElement("div",{className:"benchmark-summary"},d().createElement("div",{className:"benchmark-summary-title"},"결과 요약"),d().createElement("div",{className:"benchmark-summary-cards"},d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"성공률"),d().createElement("div",{className:"benchmark-score-value"},j.overall_success_rate,"%")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"평균 Fix"),d().createElement("div",{className:"benchmark-score-value"},j.overall_avg_fix,"회")),j.generate_path_a?.count>0&&d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"RAG 테이블 F1"),d().createElement("div",{className:"benchmark-score-value"},j.generate_path_a.avg_table_f1||"-","%")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"총 케이스"),d().createElement("div",{className:"benchmark-score-value"},j.total_cases))),[j.generate_path_a,j.generate_path_b,j.tune].filter(Boolean).map((e,t)=>e.count>0&&d().createElement("div",{key:t,style:{marginTop:8,padding:"6px 10px",background:"var(--jp-layout-color2,#f8fafc)",borderRadius:4,fontSize:11}},d().createElement("strong",null,e.label),": ",e.count,"건 | 성공 ",e.success_rate,"% | Fix ",e.avg_fix_count,"회 | ",e.avg_response_time,"s",void 0!==e.avg_table_f1&&` | 테이블F1 ${e.avg_table_f1}%`))),d().createElement("div",{className:"benchmark-results-list"},C.map((e,t)=>d().createElement(d().Fragment,{key:t},V(e))))),"history"===e&&d().createElement("div",null,d().createElement("div",{className:"benchmark-actions"},d().createElement("button",{className:"benchmark-btn",onClick:H,disabled:0===I.length},"전체 삭제")),d().createElement("div",{className:"benchmark-history-list"},I.map(e=>{const t=e.summary||{};return d().createElement("div",{key:e.id,className:"benchmark-history-entry"},d().createElement("div",{onClick:()=>U(e.id),style:{cursor:"pointer",padding:"10px 12px",display:"flex",flexDirection:"column",gap:4}},d().createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"}},d().createElement("div",{style:{fontSize:12,fontWeight:500}},new Date(e.date).toLocaleString()),d().createElement("div",{style:{fontSize:11,color:"var(--jp-ui-font-color2,#9ca3af)"}},e.total_cases,"건")),e.memo&&d().createElement("div",{style:{fontSize:11,color:"var(--jp-ui-font-color2,#6b7280)"}},e.memo),d().createElement("div",{style:{display:"flex",gap:12,flexWrap:"wrap",fontSize:11,marginTop:2}},d().createElement("span",null,"성공률 ",d().createElement("strong",null,t.overall_success_rate||0,"%")),d().createElement("span",null,"Fix ",d().createElement("strong",null,t.overall_avg_fix||0,"회")),t.generate_path_a?.count>0&&d().createElement("span",null,"RAG: ",t.generate_path_a.count,"건 ",t.generate_path_a.success_rate,"%",void 0!==t.generate_path_a.avg_table_f1&&` F1:${t.generate_path_a.avg_table_f1}%`),t.generate_path_b?.count>0&&d().createElement("span",null,"직접: ",t.generate_path_b.count,"건 ",t.generate_path_b.success_rate,"%"),t.tune?.count>0&&d().createElement("span",null,"튜닝: ",t.tune.count,"건 ",t.tune.success_rate,"%"))),L===e.id&&R&&d().createElement("div",{style:{borderTop:"1px solid var(--jp-border-color2,#e5e7eb)",padding:8,display:"flex",flexDirection:"column",gap:6}},d().createElement("div",{className:"benchmark-summary-cards",style:{marginBottom:8}},d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"성공률"),d().createElement("div",{className:"benchmark-score-value"},t.overall_success_rate||0,"%"),d().createElement("div",{className:"benchmark-score-max"},e.total_cases,"건 중")),d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"평균 Fix"),d().createElement("div",{className:"benchmark-score-value"},t.overall_avg_fix||0),d().createElement("div",{className:"benchmark-score-max"},"회")),void 0!==t.generate_path_a?.avg_table_f1&&d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"테이블 F1"),d().createElement("div",{className:"benchmark-score-value"},t.generate_path_a.avg_table_f1,"%"),d().createElement("div",{className:"benchmark-score-max"},"RAG 경로")),void 0!==t.generate_path_a?.avg_overall&&d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"RAG Overall"),d().createElement("div",{className:"benchmark-score-value"},t.generate_path_a.avg_overall)),void 0!==t.tune?.avg_overall&&d().createElement("div",{className:"benchmark-score-card"},d().createElement("div",{className:"benchmark-score-label"},"튜닝 Overall"),d().createElement("div",{className:"benchmark-score-value"},t.tune.avg_overall))),R.results?.map((e,t)=>d().createElement(d().Fragment,{key:t},V(e)))))}),0===I.length&&d().createElement("div",{className:"benchmark-empty"},"실행 이력이 없습니다.")))))};var Na=n(7809),ja=n(5813),$a=n(1147),Ta=n(8047);const Aa=({taskStatus:e,onClose:t,onCancel:n,onOpenNotebook:a})=>{const[r,s]=(0,i.useState)(!0),[o,l]=(0,i.useState)(!1),{status:c,progress:u,message:m,prompt:p,error:h,notebookPath:g,gatewayReason:f}=e,b="completed"===c,v="failed"===c,y="running"===c,E=b||v||"cancelled"===c;return d().createElement(Jn.Card,{sx:{position:"fixed",bottom:20,right:20,width:r?380:320,maxWidth:"90vw",boxShadow:3,zIndex:1300,transition:"all 0.3s ease"}},d().createElement(Jn.CardContent,{sx:{padding:2,"&:last-child":{paddingBottom:2}}},d().createElement(Jn.Box,{display:"flex",justifyContent:"space-between",alignItems:"center",mb:1},d().createElement(Jn.Box,{display:"flex",alignItems:"center",gap:1},d().createElement(Jn.Typography,{variant:"subtitle2",fontWeight:"bold"},"노트북 생성"),d().createElement(Jn.Chip,{label:(k=c,{pending:"대기 중",running:"생성 중",completed:"완료",failed:"실패",cancelled:"취소됨"}[k]||k),size:"small",color:(e=>{switch(e){case"completed":return"success";case"failed":return"error";case"cancelled":return"default";default:return"primary"}})(c),icon:(e=>{switch(e){case"completed":return d().createElement(ja.A,{fontSize:"small"});case"failed":return d().createElement($a.A,{fontSize:"small"});case"cancelled":return d().createElement(Ta.A,{fontSize:"small"});default:return null}})(c)||void 0})),d().createElement(Jn.Box,{display:"flex"},d().createElement(Jn.IconButton,{size:"small",onClick:()=>l(!o)},o?d().createElement(Ot.A,{fontSize:"small"}):d().createElement(zt.A,{fontSize:"small"})),d().createElement(Jn.IconButton,{size:"small",onClick:t},d().createElement(Na.A,{fontSize:"small"})))),!E&&d().createElement(Jn.Box,{mb:2},d().createElement(Jn.LinearProgress,{variant:"determinate",value:u,sx:{height:6,borderRadius:1,"& .MuiLinearProgress-bar":{transition:"transform 0.8s ease-in-out"}}}),d().createElement(Jn.Box,{display:"flex",justifyContent:"space-between",mt:.5},d().createElement(Jn.Typography,{variant:"caption",color:"text.secondary"},m),d().createElement(Jn.Typography,{variant:"caption",color:"text.secondary"},u,"%"))),b&&d().createElement(Jn.Box,{mb:2},d().createElement(Jn.Typography,{variant:"body2",color:"success.main",sx:{display:"flex",alignItems:"center",gap:.5}},d().createElement(ja.A,{fontSize:"small"})," ",m)),v&&h&&d().createElement(Jn.Box,{mb:2},d().createElement(Jn.Typography,{variant:"body2",color:"error.main",sx:{display:"flex",alignItems:"center",gap:.5}},d().createElement($a.A,{fontSize:"small"})," ",h),d().createElement(Jn.Typography,{variant:"caption",color:"text.secondary"},Dt(f))),d().createElement(Jn.Collapse,{in:o},d().createElement(Jn.Box,{sx:{backgroundColor:"action.hover",borderRadius:1,padding:1.5,mb:2}},d().createElement(Jn.Typography,{variant:"caption",color:"text.secondary",display:"block",mb:.5},"프롬프트:"),d().createElement(Jn.Typography,{variant:"body2",sx:{wordBreak:"break-word"}},p),g&&d().createElement(d().Fragment,null,d().createElement(Jn.Typography,{variant:"caption",color:"text.secondary",display:"block",mt:1,mb:.5},"저장 위치:"),d().createElement(Jn.Typography,{variant:"caption",sx:{wordBreak:"break-all",fontFamily:"monospace"}},g)))),d().createElement(Jn.Box,{display:"flex",gap:1,justifyContent:"flex-end"},y&&d().createElement(Jn.Button,{size:"small",variant:"outlined",onClick:n},"취소"),b&&g&&d().createElement(Jn.Button,{size:"small",variant:"contained",onClick:a},"노트북 열기"),E&&d().createElement(Jn.Button,{size:"small",variant:"text",onClick:t},"닫기"))));var k};class Ia{constructor(e){if(e)this.baseUrl=e;else{const e=c.PageConfig.getBaseUrl();this.baseUrl=c.URLExt.join(e,"codebuff")}this.eventSources=new Map}getCookie(e){const t=`; ${document.cookie}`.split(`; ${e}=`);return 2===t.length&&t.pop()?.split(";").shift()||""}getCsrfToken(){return this.getCookie("_xsrf")}getHeaders(){return{"Content-Type":"application/json","X-XSRFToken":this.getCsrfToken()}}async generateNotebook(e){const t=await fetch(`${this.baseUrl}/notebook/generate`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)});if(!t.ok){const e=await t.json().catch(()=>({}));throw Object.assign(new Error(e.error||e.message||"Failed to start notebook generation"),{gatewayReason:e.gatewayReason})}return t.json()}async getTaskStatus(e){const t=await fetch(`${this.baseUrl}/task/${e}/status`);if(!t.ok){const e=await t.json().catch(()=>({message:"Failed to get task status"}));throw Object.assign(new Error(e.error||e.message||"Failed to get task status"),{status:t.status})}return t.json()}subscribeToTaskProgress(e,t,n,a){this.unsubscribeFromTask(e);const r=new EventSource(`${this.baseUrl}/task/${e}/stream`);return r.onmessage=r=>{try{const n=JSON.parse(r.data);t(n),["completed","failed","cancelled"].includes(n.status)&&(this.unsubscribeFromTask(e),a&&a())}catch(e){console.error("Failed to parse SSE message:",e),n&&n(e)}},r.onerror=t=>{console.error("SSE connection error:",t),this.unsubscribeFromTask(e),n&&n(new Error("Connection to server lost"))},this.eventSources.set(e,r),()=>this.unsubscribeFromTask(e)}unsubscribeFromTask(e){const t=this.eventSources.get(e);t&&(t.close(),this.eventSources.delete(e))}async cancelTask(e){const t=await fetch(`${this.baseUrl}/task/${e}/cancel`,{method:"POST",headers:this.getHeaders()});if(!t.ok){const e=await t.json().catch(()=>({message:"Failed to cancel task"}));throw new Error(e.error||e.message||"Failed to cancel task")}this.unsubscribeFromTask(e)}dispose(){for(const[e,t]of this.eventSources)this.unsubscribeFromTask(e)}}const Pa=["completed","failed","cancelled"],La="codebuff:generate-from-prompt",Ma="codebuff:athena-query",Ra="Codebuff",qa=new u.LabIcon({name:"codebuff:athena-icon",svgstr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke-linecap="round" stroke-linejoin="round">\n <ellipse cx="9" cy="5" rx="7" ry="2.5" stroke="#2563eb" stroke-width="1.5"/>\n <path d="M2 5v10c0 1.38 3.13 2.5 7 2.5" stroke="#2563eb" stroke-width="1.5"/>\n <path d="M16 5v2" stroke="#2563eb" stroke-width="1.5"/>\n <path d="M2 10c0 1.38 3.13 2.5 7 2.5s7-1.12 7-2.5" stroke="#2563eb" stroke-width="1.5"/>\n <circle cx="17" cy="16" r="4" stroke="#f59e0b" stroke-width="1.5"/>\n <path d="M20 19.5l2 2" stroke="#f59e0b" stroke-width="2"/>\n <rect x="11" y="0.5" width="13" height="6" rx="1.5" fill="#f59e0b"/>\n <text x="17.5" y="5.2" font-size="3.9" font-family="sans-serif" font-weight="700" fill="#fff" text-anchor="middle">beta</text>\n</svg>'}),Da=new u.LabIcon({name:"codebuff:benchmark-icon",svgstr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke-linecap="round" stroke-linejoin="round">\n <rect x="3" y="12" width="4" height="9" rx="1" fill="#7c3aed" opacity="0.3" stroke="#7c3aed" stroke-width="1.2"/>\n <rect x="10" y="7" width="4" height="14" rx="1" fill="#7c3aed" opacity="0.5" stroke="#7c3aed" stroke-width="1.2"/>\n <rect x="17" y="3" width="4" height="18" rx="1" fill="#7c3aed" opacity="0.7" stroke="#7c3aed" stroke-width="1.2"/>\n <path d="M4 10l7-5 7-2" stroke="#f59e0b" stroke-width="1.8"/>\n <circle cx="4" cy="10" r="1.5" fill="#f59e0b"/>\n <circle cx="11" cy="5" r="1.5" fill="#f59e0b"/>\n <circle cx="18" cy="3" r="1.5" fill="#f59e0b"/>\n</svg>'}),Oa=new u.LabIcon({name:"codebuff:codebuff-icon",svgstr:Bt});class za extends r.ReactWidget{constructor(e,t){super(),this.finishers=new Map,this.app=e,this.docManager=t,this.taskService=new Ia,this.activeTasks=new Map,this.addClass("jp-TaskManagerWidget")}async startGeneration(e){try{const t=(await this.taskService.generateNotebook({prompt:e})).taskId,n=new Promise(e=>this.finishers.set(t,e));return this.activeTasks.set(t,{taskId:t,prompt:e,status:"pending",progress:0,message:"노트북 생성 준비 중...",createdAt:(new Date).toISOString()}),this.taskService.subscribeToTaskProgress(t,e=>this.applyStatus(t,e),e=>{console.error("Task progress error:",e),this.pollUntilDone(t)},()=>{this.update()}),r.Notification.info("노트북 생성을 시작했습니다",{autoClose:3e3}),this.update(),{taskId:t,finished:n}}catch(e){throw console.error("Failed to start generation:",e),Ze.c.getInstance().trackError("notebook_gen_error",{error:e.message}),r.Notification.error(`생성 시작 실패: ${e.message} ${Dt(e.gatewayReason)}`,{autoClose:5e3}),e}}applyStatus(e,t){this.activeTasks.set(e,t),this.update(),Pa.includes(t.status)&&(this.finishers.get(e)?.(t),this.finishers.delete(e)),"completed"===t.status&&t.notebookPath?r.Notification.success(`노트북 생성 완료: ${t.notebookPath.split("/").pop()}`,{autoClose:5e3}):"failed"===t.status&&r.Notification.error(`노트북 생성 실패: ${t.error} ${Dt(t.gatewayReason)}`,{autoClose:1e4})}async pollUntilDone(e){for(let t=0;t<300;t++){if(await new Promise(e=>setTimeout(e,2e3)),!this.activeTasks.has(e))return;try{const t=await this.taskService.getTaskStatus(e);if(Pa.includes(t.status))return void this.applyStatus(e,t);this.activeTasks.set(e,t),this.update()}catch(t){if(404===t.status){const t=this.activeTasks.get(e);return void(t&&this.applyStatus(e,{...t,status:"failed",error:"서버에서 작업을 찾지 못했습니다. 서버가 재시작됐을 수 있습니다."}))}console.warn("Task status poll failed:",t)}}const t=this.activeTasks.get(e);t&&this.applyStatus(e,{...t,status:"failed",error:"진행 상태를 10분 동안 받지 못했습니다. 생성이 계속 중일 수 있으니 파일 브라우저를 먼저 확인해 주세요."})}async cancelTask(e){try{await this.taskService.cancelTask(e);const t=this.activeTasks.get(e);t&&this.finishers.get(e)?.({...t,status:"cancelled"}),this.finishers.delete(e),this.activeTasks.delete(e),this.update(),r.Notification.info("작업을 취소했습니다",{autoClose:3e3})}catch(e){console.error("Failed to cancel task:",e),r.Notification.error(`취소 실패: ${e.message}`,{autoClose:5e3})}}closeTask(e){this.taskService.unsubscribeFromTask(e),this.activeTasks.delete(e),this.finishers.delete(e),this.update()}async openNotebook(e,t){try{const n=e.split("/").pop()||e;await this.docManager.openOrReveal(n),this.closeTask(t),r.Notification.success(`노트북을 열었습니다: ${n}`,{autoClose:3e3})}catch(e){console.error("Failed to open notebook:",e),r.Notification.error(`노트북 열기 실패: ${e.message}`,{autoClose:5e3})}}render(){const e=(0,Jn.createTheme)(),t=Array.from(this.activeTasks.entries());return d().createElement(Jn.ThemeProvider,{theme:e},d().createElement("div",{style:{position:"fixed",bottom:0,right:0,zIndex:1300}},t.map(([e,n],a)=>d().createElement("div",{key:e,style:{marginBottom:a<t.length-1?"10px":"0"}},d().createElement(Aa,{taskStatus:n,onClose:()=>this.closeTask(e),onCancel:()=>this.cancelTask(e),onOpenNotebook:()=>n.notebookPath&&this.openNotebook(n.notebookPath,e)})))))}dispose(){this.taskService.dispose(),super.dispose()}}class Fa extends r.ReactWidget{constructor(e,t){super(),this._onGenerate=e,this._onClose=t,this._apiService=new hn}render(){const e=(0,Jn.createTheme)();return d().createElement(Jn.ThemeProvider,{theme:e},d().createElement(Xn,{open:!0,onClose:this._onClose,onGenerate:this._onGenerate,apiService:this._apiService}))}}class Ba extends r.ReactWidget{constructor(e){super(),this._initialPrompt=e,this.addClass("jp-AthenaQueryWidget")}render(){return d().createElement(Ea,{initialPrompt:this._initialPrompt})}}class Wa extends r.ReactWidget{constructor(){super(),this.addClass("jp-BenchmarkWidget")}render(){return d().createElement(xa,null)}}class Ua extends r.ReactWidget{constructor(){super(),this.addClass("jp-BenchmarkWidget")}render(){return d().createElement(Ca,null)}}const Ha={id:"codebuff:prompt-generation",autoStart:!0,requires:[Un.IDocumentManager],optional:[Wn.ILauncher,r.ICommandPalette],activate:async(e,t,n,a)=>{console.log("[PromptGenerationPlugin] Activating");try{const r=new za(e,t);r.id="codebuff-task-manager",r.title.label="Task Manager",Hn.Widget.attach(r,document.body),e.commands.addCommand(La,{label:"노트북 자동생성",caption:"노트북 자동생성",icon:Oa,execute:t=>{const n=t?.prompt;if(n)return r.startGeneration(n);let a=null;a=new Fa(async e=>{a&&(a.dispose(),a=null),Ze.c.getInstance().trackClick("notebook_gen",{prompt:e}),await r.startGeneration(e).catch(()=>{})},()=>{a&&(a.dispose(),a=null)}),a.id="codebuff-prompt-dialog",a.title.label="",e.shell.add(a,"main"),Ze.c.getInstance().trackImpression("notebook_gen_dialog")}}),e.commands.addCommand(Ma,{label:"EDA Agent",caption:"Athena SQL 쿼리 생성/튜닝",icon:qa,execute:t=>{const n=t?.prompt,a=new Ba(n);a.id="codebuff-athena-query-"+Date.now(),a.title.label="EDA Agent",a.title.icon=qa,a.title.closable=!0,e.shell.add(a,"main",{activate:!0}),Ze.c.getInstance().trackImpression("athena_query_panel")}});const s="codebuff:benchmark";e.commands.addCommand(s,{label:"RAG Benchmark",caption:"RAG 응답 품질 벤치마크",icon:Da,execute:()=>{const t=new Wa;t.id="codebuff-benchmark-"+Date.now(),t.title.label="RAG Benchmark",t.title.icon=Da,t.title.closable=!0,e.shell.add(t,"main",{activate:!0})}});const o="codebuff:eda-benchmark";e.commands.addCommand(o,{label:"EDA Benchmark",caption:"EDA Agent SQL 생성/튜닝 벤치마크",icon:Da,execute:()=>{const t=new Ua;t.id="codebuff-eda-benchmark-"+Date.now(),t.title.label="EDA Benchmark",t.title.icon=Da,t.title.closable=!0,e.shell.add(t,"main",{activate:!0})}});let l=!1,i=!1;try{const e=c.PageConfig.getBaseUrl(),t=c.URLExt.join(e,"codebuff/config"),n=await fetch(t);if(n.ok){const e=await n.json();l=!1!==e?.features?.eda_enabled}const a=c.URLExt.join(e,"codebuff/config/is-admin"),r=await fetch(a);if(r.ok){const e=await r.json();i=!!e?.isAdmin}}catch{}n&&(n.add({command:La,category:Ra,rank:0}),l&&n.add({command:Ma,category:Ra,rank:1}),i&&(n.add({command:s,category:Ra,rank:3}),l&&n.add({command:o,category:Ra,rank:4}))),a&&(a.addItem({command:La,category:Ra}),l&&a.addItem({command:Ma,category:Ra})),console.log("[PromptGenerationPlugin] Activated successfully")}catch(e){console.error("[PromptGenerationPlugin] Failed to activate:",e)}}};var Ja=n(6379),Va=n(5690);const Ga="codebuff-llm-config",Xa="hdsp-agent-llm-config",Za=3e4;class Ka{constructor(){this.checkIntervalId=null,this.countdownElement=null,this.isShuttingDown=!1,this.notebookTracker=null,this.terminalTracker=null,this.isInWarningMode=!1,this.isDisabled=!1,this.tabHiddenSince=null,this.lastServerCheckTime=0,this.SERVER_CHECK_INTERVAL_MS=3e4,this.mouseMoveThrottleTime=0,this.lastActivityTime=Date.now(),this.idleTimeoutMinutes=60,this.isDisabled=!1,this.idleTimeoutMs=60*this.idleTimeoutMinutes*1e3;const e=Math.max(Za,.25*this.idleTimeoutMs);this.warningStartMs=this.idleTimeoutMs-e,this.tabHiddenIdleTimeoutMinutes=this.loadTabHiddenTimeoutFromConfig(),this.tabHiddenIdleTimeoutMs=60*this.tabHiddenIdleTimeoutMinutes*1e3,this.setupActivityListeners(),this.setupStorageListener(),this.setupVisibilityListener(),this.createCountdownElement(),this.fetchIdleTimeoutFromServer(),this.isDisabled||this.startIdleCheck(),console.log("[IdleMonitor] Service initialized. Idle timeout:",this.idleTimeoutMinutes,"minutes, tab hidden timeout:",this.tabHiddenIdleTimeoutMinutes,"minutes",this.isDisabled?"(DISABLED)":"")}async fetchIdleTimeoutFromServer(){try{const e=c.PageConfig.getBaseUrl(),t=await fetch(`${e}codebuff/config/admin`);if(!t.ok)return void console.warn("[IdleMonitor] Failed to fetch config from server:",t.status);const n=(await t.json()).idleTimeout;if("number"==typeof n&&n>0){const e=Math.ceil(n/60);e!==this.idleTimeoutMinutes&&(this.updateIdleTimeout(e),console.log("[IdleMonitor] Updated timeout from server:",e,"minutes"))}else 0===n&&(this.isDisabled=!0,this.stopIdleCheck(),console.log("[IdleMonitor] Idle timeout disabled by server config"))}catch(e){console.warn("[IdleMonitor] Error fetching config from server:",e)}}loadTabHiddenTimeoutFromConfig(){try{const e=(0,S.GK)(Ga,Xa);if(e){const t=JSON.parse(e);if("number"==typeof t.tabHiddenIdleTimeoutMinutes)return t.tabHiddenIdleTimeoutMinutes}}catch(e){console.warn("[IdleMonitor] Failed to load tab hidden timeout config:",e)}return 30}setupVisibilityListener(){document.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState?(this.tabHiddenSince=Date.now(),console.log("[IdleMonitor] Tab became hidden")):(this.tabHiddenSince=null,this.resetIdleTimer(),console.log("[IdleMonitor] Tab became visible"))}),console.log("[IdleMonitor] Visibility listener attached")}setupStorageListener(){window.addEventListener("storage",e=>{if(e.key===Ga||e.key===Xa)try{const e=(0,S.GK)(Ga,Xa);if(e){const t=JSON.parse(e);"number"==typeof t.idleTimeoutMinutes&&t.idleTimeoutMinutes!==this.idleTimeoutMinutes&&this.updateIdleTimeout(t.idleTimeoutMinutes)}}catch(e){console.warn("[IdleMonitor] Failed to parse config update:",e)}}),window.addEventListener("codebuff-config-updated",()=>{try{const e=(0,S.GK)(Ga,Xa);if(e){const t=JSON.parse(e);"number"==typeof t.idleTimeoutMinutes&&t.idleTimeoutMinutes!==this.idleTimeoutMinutes&&this.updateIdleTimeout(t.idleTimeoutMinutes)}}catch(e){console.warn("[IdleMonitor] Failed to parse config update:",e)}})}updateIdleTimeout(e){this.idleTimeoutMinutes=e,this.idleTimeoutMs=60*e*1e3;const t=Math.max(Za,.25*this.idleTimeoutMs);this.warningStartMs=this.idleTimeoutMs-t}stopIdleCheck(){null!==this.checkIntervalId&&(clearInterval(this.checkIntervalId),this.checkIntervalId=null),this.isInWarningMode=!1,console.log("[IdleMonitor] Idle check stopped")}setNotebookTracker(e){this.notebookTracker=e,e.currentChanged.connect(()=>{this.resetIdleTimer()}),e.activeCellChanged.connect(()=>{this.resetIdleTimer()}),console.log("[IdleMonitor] Notebook tracker connected")}setTerminalTracker(e){this.terminalTracker=e,e.currentChanged.connect(()=>{this.resetIdleTimer()}),e.forEach(e=>{this.setupTerminalMonitoring(e)}),e.widgetAdded.connect((e,t)=>{this.setupTerminalMonitoring(t)}),console.log("[IdleMonitor] Terminal tracker connected")}setupTerminalMonitoring(e){const t=e.id||e.session?.name||"unknown",n=e.session;n&&(n.messageReceived.connect(()=>{this.resetIdleTimer()}),console.log("[IdleMonitor] Terminal monitoring setup:",t))}setupActivityListeners(){document.addEventListener("keydown",this.handleActivity.bind(this),!0),document.addEventListener("keyup",this.handleActivity.bind(this),!0),document.addEventListener("keypress",this.handleActivity.bind(this),!0),document.addEventListener("mousedown",this.handleActivity.bind(this),!0),document.addEventListener("mouseup",this.handleActivity.bind(this),!0),document.addEventListener("mousemove",this.throttledMouseMove.bind(this),!0),document.addEventListener("wheel",this.handleActivity.bind(this),!0),document.addEventListener("click",this.handleActivity.bind(this),!0),document.addEventListener("touchstart",this.handleActivity.bind(this),!0),document.addEventListener("touchend",this.handleActivity.bind(this),!0),console.log("[IdleMonitor] Activity listeners attached")}throttledMouseMove(){const e=Date.now();e-this.mouseMoveThrottleTime>5e3&&(this.mouseMoveThrottleTime=e,this.handleActivity())}handleActivity(){this.resetIdleTimer()}resetIdleTimer(){this.lastActivityTime=Date.now(),this.isShuttingDown=!1,this.hideCountdown(),this.switchToNormalMode()}createCountdownElement(){this.countdownElement=document.createElement("div"),this.countdownElement.id="codebuff-idle-countdown",this.countdownElement.className="codebuff-idle-countdown",this.countdownElement.style.cssText="\n display: none;\n position: fixed;\n right: 20px;\n top: 10px;\n background: linear-gradient(135deg, #ff6b6b 0%, #ee5a5a 100%);\n color: white;\n padding: 8px 16px;\n border-radius: 20px;\n font-size: 14px;\n font-weight: 600;\n box-shadow: 0 4px 12px rgba(238, 90, 90, 0.5);\n z-index: 99999;\n white-space: nowrap;\n cursor: pointer;\n user-select: none;\n ",this.countdownElement.addEventListener("click",()=>{this.resetIdleTimer(),console.log("[IdleMonitor] User clicked countdown - timer reset")});const e=document.createElement("style");e.id="codebuff-idle-countdown-style",e.textContent="\n @keyframes codebuff-pulse {\n 0% { transform: scale(1); }\n 50% { transform: scale(1.03); }\n 100% { transform: scale(1); }\n }\n\n .codebuff-idle-countdown {\n animation: codebuff-pulse 2s infinite;\n }\n\n .codebuff-idle-countdown.warning {\n background: linear-gradient(135deg, #ffa726 0%, #fb8c00 100%) !important;\n box-shadow: 0 4px 12px rgba(251, 140, 0, 0.5) !important;\n }\n\n .codebuff-idle-countdown.critical {\n background: linear-gradient(135deg, #ef5350 0%, #d32f2f 100%) !important;\n box-shadow: 0 4px 12px rgba(211, 47, 47, 0.6) !important;\n animation: codebuff-pulse-critical 0.5s infinite !important;\n }\n\n @keyframes codebuff-pulse-critical {\n 0% { transform: scale(1); opacity: 1; }\n 50% { transform: scale(1.05); opacity: 0.9; }\n 100% { transform: scale(1); opacity: 1; }\n }\n ";const t=document.getElementById("codebuff-idle-countdown-style");t&&t.remove(),document.head.appendChild(e),document.body.appendChild(this.countdownElement),console.log("[IdleMonitor] Countdown element created (fixed position)")}showCountdown(e,t=!1){if(console.log(`[IdleMonitor] showCountdown called: ${e}s remaining, tabHidden=${t}`),!this.countdownElement)return void this.createCountdownElement();this.countdownElement.style.display="block";const n=t?"(탭 비활성)":"";this.countdownElement.textContent=`Idle Shutdown ${e}초 전 ${n}`,this.countdownElement.classList.remove("warning","critical"),e<=10?this.countdownElement.classList.add("critical"):e<=30&&this.countdownElement.classList.add("warning")}hideCountdown(){this.countdownElement&&(this.countdownElement.style.display="none")}hasRunningCells(){if(!this.notebookTracker)return!1;const e=this.notebookTracker.filter(()=>!0);for(const t of e){const e=t.sessionContext?.session;if(e){const t=e.kernel?.status;if("busy"===t)return!0}if(t.content){const e=t.content.widgets;for(const t of e){const e=t.model;if(e&&"code"===e.type){const e=t.node.querySelector(".jp-InputPrompt");if(e&&e.textContent?.includes("*"))return!0}}}}return!1}startIdleCheck(){this.checkIntervalId=window.setInterval(()=>{this.checkIdleStatus()},1e4),console.log("[IdleMonitor] Started in normal mode: check every 10 seconds")}switchToWarningMode(){this.isInWarningMode||(this.isInWarningMode=!0,null!==this.checkIntervalId&&clearInterval(this.checkIntervalId),this.checkIntervalId=window.setInterval(()=>{this.checkIdleStatus()},1e3),console.log("[IdleMonitor] Switched to warning mode: check every",1,"seconds"))}switchToNormalMode(){this.isInWarningMode&&(this.isInWarningMode=!1,null!==this.checkIntervalId&&clearInterval(this.checkIntervalId),this.checkIntervalId=window.setInterval(()=>{this.checkIdleStatus()},1e4),console.log("[IdleMonitor] Switched to normal mode: check every 10 seconds"))}checkIdleStatus(){if(this.isDisabled)return;if(this.hasRunningCells())return this.tabHiddenSince=null,void this.resetIdleTimer();const e=Date.now();if(e-this.lastServerCheckTime>=this.SERVER_CHECK_INTERVAL_MS&&(this.lastServerCheckTime=e,this.checkServerIdleStatus()),null!==this.tabHiddenSince&&this.tabHiddenIdleTimeoutMs>0){const t=e-this.tabHiddenSince,n=this.tabHiddenIdleTimeoutMs-t,a=Math.ceil(n/1e3);Math.floor(t/1e3)%10==0&&console.log(`[IdleMonitor] Tab hidden for ${Math.round(t/1e3)}s, timeout at ${Math.round(this.tabHiddenIdleTimeoutMs/1e3)}s`);const r=Math.max(Za,.1*this.tabHiddenIdleTimeoutMs);if(t>=this.tabHiddenIdleTimeoutMs-r&&!this.isShuttingDown&&(this.switchToWarningMode(),this.showCountdown(a,!0)),t>=this.tabHiddenIdleTimeoutMs&&!this.isShuttingDown)return this.isShuttingDown=!0,console.log("[IdleMonitor] Tab hidden timeout reached"),void this.triggerShutdown()}const t=e-this.lastActivityTime,n=this.idleTimeoutMs-t,a=Math.ceil(n/1e3);Math.floor(t/1e3)%10==0&&console.log(`[IdleMonitor] idle=${Math.round(t/1e3)}s, warningAt=${Math.round(this.warningStartMs/1e3)}s, timeout=${Math.round(this.idleTimeoutMs/1e3)}s, remaining=${a}s`),t>=this.warningStartMs&&!this.isShuttingDown&&(this.switchToWarningMode(),this.showCountdown(a,!1)),t>=this.idleTimeoutMs&&!this.isShuttingDown&&(this.isShuttingDown=!0,this.triggerShutdown())}async triggerShutdown(){console.log("[IdleMonitor] Idle timeout reached. Checking server-side activity...");try{const e=c.PageConfig.getBaseUrl(),t=await fetch(`${e}codebuff/idle-status`);if(t.ok&&!(await t.json()).idle)return console.log("[IdleMonitor] Server reports not idle (terminal/kernel active). Resetting timer."),this.isShuttingDown=!1,void this.resetIdleTimer()}catch(e){console.warn("[IdleMonitor] Failed to check server idle status:",e)}this.hideCountdown(),this.callShutdownApi().catch(e=>console.error("[IdleMonitor] Shutdown API error:",e)),alert(`${this.idleTimeoutMinutes}분 동안 활동이 없어 세션이 종료됩니다.`)}async checkServerIdleStatus(){try{const e=c.PageConfig.getBaseUrl(),t=await fetch(`${e}codebuff/idle-status`);t.ok&&((await t.json()).idle||(console.log("[IdleMonitor] Server reports active (terminal/kernel). Resetting timer."),this.resetIdleTimer()))}catch(e){}}async callShutdownApi(){try{const e=`${c.PageConfig.getBaseUrl()}codebuff/idle-shutdown`;console.log("[IdleMonitor] Calling HDSP shutdown API:",e);const t=document.cookie.split("; ").find(e=>e.startsWith("_xsrf="))?.split("=")[1]||"",n=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-XSRFToken":t}}),a=await n.json();n.ok&&a.success?console.log("[IdleMonitor] HDSP shutdown API call successful:",a.message):console.error("[IdleMonitor] HDSP shutdown API call failed:",a.error||n.statusText)}catch(e){console.error("[IdleMonitor] HDSP shutdown API call error:",e)}}getIdleTimeMs(){return Date.now()-this.lastActivityTime}triggerActivity(){this.resetIdleTimer()}dispose(){null!==this.checkIntervalId&&(clearInterval(this.checkIntervalId),this.checkIntervalId=null),this.countdownElement&&this.countdownElement.parentNode&&this.countdownElement.parentNode.removeChild(this.countdownElement),console.log("[IdleMonitor] Service disposed")}}let Qa=null;const Ya={id:"codebuff:idle-monitor",autoStart:!0,requires:[],optional:[s.INotebookTracker,Va.ITerminalTracker],activate:(e,t,n)=>{console.log("[IdleMonitorPlugin] Activating Idle Monitor");try{Qa=new Ka,t&&Qa.setNotebookTracker(t),n&&Qa.setTerminalTracker(n),window._codebuffIdleMonitor=Qa,console.log("[IdleMonitorPlugin] Idle Monitor activated successfully")}catch(e){console.error("[IdleMonitorPlugin] Failed to activate:",e)}}};var er;!function(e){e[e.Error=1]="Error",e[e.Warning=2]="Warning",e[e.Information=3]="Information",e[e.Hint=4]="Hint"}(er||(er={}));class tr{constructor(){this.diagnosticsVersion=0,this.diagnosticsCache=new Map,this.summaryCache=null,this.summaryVersion=-1}updateDiagnostics(e,t){this.diagnosticsCache.set(e,t),this.diagnosticsVersion++}getDiagnostics(e){return e?{version:this.diagnosticsVersion,diagnostics:this.diagnosticsCache.get(e)||[]}:{version:this.diagnosticsVersion,diagnostics:this.diagnosticsCache}}getDiagnosticSummary(){if(this.summaryVersion===this.diagnosticsVersion&&this.summaryCache)return this.summaryCache;let e=0,t=0,n=0;for(const a of this.diagnosticsCache.values())for(const r of a)switch(r.severity){case er.Error:e++;break;case er.Warning:t++;break;default:n++}return this.summaryCache={errors:e,warnings:t,hints:n,total:e+t+n,version:this.diagnosticsVersion},this.summaryVersion=this.diagnosticsVersion,this.summaryCache}clearDiagnostics(e){this.diagnosticsCache.has(e)&&(this.diagnosticsCache.delete(e),this.diagnosticsVersion++)}clearAll(){this.diagnosticsCache.clear(),this.diagnosticsVersion++}getVersion(){return this.diagnosticsVersion}}class nr{constructor(){this.cache=new tr,this.lspAvailable=!1,this.notebookTracker=null,this.checkLSPAvailability()}async checkLSPAvailability(){try{this.lspAvailable=!1,console.log("[LSPBridge] LSP availability check - will be updated when connection established")}catch(e){console.warn("[LSPBridge] LSP not available:",e),this.lspAvailable=!1}}setNotebookTracker(e){this.notebookTracker=e}setLSPAvailable(e){this.lspAvailable=e,console.log("[LSPBridge] LSP available:",e)}isLSPAvailable(){return this.lspAvailable}updateDiagnostics(e,t){this.cache.updateDiagnostics(e,t),this.notifyDiagnosticsChanged(e)}async getDiagnostics(e){const t=this.cache.getDiagnostics(e?this.pathToUri(e):void 0),n=this.cache.getDiagnosticSummary(),a=[];if(e){const n=t.diagnostics;for(const t of n)a.push({severity:this.severityToString(t.severity),line:t.range.start.line+1,character:t.range.start.character,message:t.message,source:t.source,code:t.code,file:e})}else{const e=t.diagnostics;for(const[t,n]of e){const e=this.uriToPath(t);for(const t of n)a.push({severity:this.severityToString(t.severity),line:t.range.start.line+1,character:t.range.start.character,message:t.message,source:t.source,code:t.code,file:e})}}return a.sort((e,t)=>{const n={error:0,warning:1,information:2,hint:3},a=(n[e.severity]||3)-(n[t.severity]||3);if(0!==a)return a;const r=e.file.localeCompare(t.file);return 0!==r?r:e.line-t.line}),{success:!0,diagnostics:a,summary:n}}async getReferences(e,t,n,a){return this.lspAvailable,{success:!1,locations:[]}}getDiagnosticSummary(){return this.cache.getDiagnosticSummary()}notifyDiagnosticsChanged(e){const t=this.cache.getDiagnosticSummary();window.dispatchEvent(new CustomEvent("codebuff-lsp-diagnostics-changed",{detail:{uri:e,summary:t}}))}severityToString(e){switch(e){case er.Error:return"error";case er.Warning:return"warning";case er.Information:return"information";case er.Hint:default:return"hint"}}pathToUri(e){return e.startsWith("file://")?e:`file://${e.startsWith("/")?"":"/"}${e}`}uriToPath(e){return e.startsWith("file://")?e.replace("file://",""):e}dispose(){this.cache.clearAll(),console.log("[LSPBridge] Service disposed")}}let ar=null;const rr={id:"codebuff:lsp-bridge",autoStart:!0,requires:[],optional:[s.INotebookTracker],activate:(e,t)=>{console.log("[LSPBridgePlugin] Activating LSP Bridge..."),ar=new nr,t&&ar.setNotebookTracker(t),window._codebuffLSPBridge=ar,async function(e,t){try{e.commands.hasCommand("lsp:show-diagnostics-panel")?(console.log("[LSPBridgePlugin] jupyterlab-lsp detected"),t.setLSPAvailable(!0),console.log("[LSPBridgePlugin] LSP event listeners setup (placeholder)")):(console.log("[LSPBridgePlugin] jupyterlab-lsp not detected, using fallback mode"),t.setLSPAvailable(!1))}catch(e){console.warn("[LSPBridgePlugin] Failed to connect to jupyterlab-lsp:",e),t.setLSPAvailable(!1)}}(e,ar),console.log("[LSPBridgePlugin] LSP Bridge activated")}},sr=new u.LabIcon({name:"codebuff:notebook-explain",svgstr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" width="16" height="16">\n <path fill="currentColor" d="M480-80q-34 0-57.5-23.5T399-161h162q0 34-23.5 57.5T480-80ZM318-223v-80h324v80H318Zm5-120q-66-43-104.5-107.5T180-597q0-122 89-211t211-89q122 0 211 89t89 211q0 82-38.5 146.5T637-343H323Zm22-80h270q44-29 69.5-71.5T710-597q0-97-66.5-163.5T480-827q-97 0-163.5 66.5T250-597q0 60 25.5 102.5T345-423Zm135 0Z"/>\n</svg>'}),or="codebuff-summary",lr="jp-agent-notebook-explain-dialog";function cr(e,t){if(Array.from(t.toolbar.names()).includes(or))return;const n=new r.ToolbarButton({icon:sr,tooltip:"노트북 설명하기 (Codebuff)",onClick:async()=>{if(!await new Promise(e=>{!function(){const e=document.querySelector(`.${lr}`);e&&e.remove()}();const t=function(){const e=document.createElement("div");return e.className=lr,e.style.cssText="\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.3);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n ",e}(),n=function(){const e=document.createElement("div");return e.style.cssText="\n background: var(--codebuff-dialog-bg, #fafafa);\n border: 1px solid var(--codebuff-dialog-border, #e0e0e0);\n border-radius: 4px;\n padding: 24px;\n max-width: 400px;\n width: 90%;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n ",e}();n.innerHTML='\n <div style="margin-bottom: 20px;">\n <h3 style="margin: 0 0 12px 0; color: var(--codebuff-dialog-title, #424242); font-size: 16px; font-weight: 500;">\n ✨ 노트북 설명하기\n </h3>\n <p style="margin: 0; color: var(--codebuff-dialog-text, #616161); font-size: 14px; line-height: 1.5;">\n 노트북 설명을 요청하시겠습니까?\n </p>\n </div>\n <div style="display: flex; gap: 12px; justify-content: flex-end;">\n <button class="jp-agent-notebook-explain-cancel-btn" style="\n background: transparent;\n color: var(--codebuff-dialog-text, #616161);\n border: 1px solid var(--codebuff-dialog-input-border, #d1d5db);\n border-radius: 3px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n ">취소</button>\n <button class="jp-agent-notebook-explain-submit-btn" style="\n background: #1976d2;\n color: white;\n border: 1px solid #1976d2;\n border-radius: 3px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n ">확인</button>\n </div>\n ',t.appendChild(n),document.body.appendChild(t);const a=n.querySelector(".jp-agent-notebook-explain-cancel-btn"),r=n.querySelector(".jp-agent-notebook-explain-submit-btn");a.addEventListener("click",()=>{t.remove(),e(!1)}),a.addEventListener("mouseenter",()=>{a.style.background="var(--codebuff-dialog-hover, #f5f5f5)"}),a.addEventListener("mouseleave",()=>{a.style.background="transparent"}),r.addEventListener("click",()=>{r.disabled=!0,r.textContent="처리 중...",setTimeout(()=>{t.remove(),e(!0)},100)}),r.addEventListener("mouseenter",()=>{r.disabled||(r.style.background="#1565c0")}),r.addEventListener("mouseleave",()=>{r.disabled||(r.style.background="#1976d2")});const s=n=>{"Escape"===n.key&&(t.remove(),document.removeEventListener("keydown",s),e(!1))};document.addEventListener("keydown",s),t.addEventListener("click",n=>{n.target===t&&(t.remove(),document.removeEventListener("keydown",s),e(!1))})}))return;Ze.c.getInstance().trackClick("notebook_explain");const t=window._codebuffAgentPanel;t?(e.shell.activateById("codebuff-panel"),t.sendNotebookMessage("설명해줘")):console.error("[NotebookToolbarPlugin] AgentPanel not available")}});t.toolbar.insertAfter("save",or,n)||t.toolbar.insertItem(1,or,n),requestAnimationFrame(()=>{t.toolbar.node.style.display="none",t.toolbar.node.offsetHeight,t.toolbar.node.style.display=""})}const ir={id:"codebuff:notebook-toolbar",autoStart:!0,requires:[s.INotebookTracker],activate:(e,t)=>{console.log("[NotebookToolbarPlugin] Activated"),t.forEach(t=>{cr(e,t)}),t.widgetAdded.connect((t,n)=>{cr(e,n)})}};function dr(){const e=`; ${document.cookie}`.split("; _xsrf=");return 2===e.length&&e.pop()?.split(";").shift()||""}async function ur(e,t="GET",n){const a=`${function(){const e=c.PageConfig.getBaseUrl();return c.URLExt.join(e,"codebuff")}()}/${e}`,r={method:t,headers:{"Content-Type":"application/json","X-XSRFToken":dr()}};return n&&(r.body=JSON.stringify(n)),(await fetch(a,r)).json()}const mr="var(--codebuff-rag-primary, #2563eb)",pr="var(--codebuff-rag-primary-light, #dbeafe)",hr="var(--codebuff-rag-danger, #dc2626)",gr="var(--codebuff-rag-danger-light, #fef2f2)",fr="var(--codebuff-rag-success, #16a34a)",br="var(--codebuff-rag-success-light, #f0fdf4)",vr="var(--codebuff-rag-gray-50, #f9fafb)",yr="var(--codebuff-rag-gray-100, #f3f4f6)",Er="var(--codebuff-rag-gray-200, #e5e7eb)",kr="var(--codebuff-rag-gray-300, #d1d5db)",wr="var(--codebuff-rag-gray-400, #9ca3af)",xr="var(--codebuff-rag-gray-500, #6b7280)",Sr="var(--codebuff-rag-gray-600, #4b5563)",_r="var(--codebuff-rag-gray-700, #374151)",Cr="var(--codebuff-rag-white, #ffffff)",Nr=({children:e})=>d().createElement("div",{style:{height:"100%",overflow:"auto",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',fontSize:13,background:"var(--codebuff-rag-bg, #f8fafc)",color:"var(--codebuff-rag-gray-800, #1f2937)"}},e),jr=({title:e,subtitle:t,actions:n})=>d().createElement("div",{style:{padding:"20px 24px 16px",background:`linear-gradient(135deg, ${mr} 0%, var(--codebuff-rag-primary-dark, #1d4ed8) 100%)`,color:"#ffffff"}},d().createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"}},d().createElement("div",null,d().createElement("h2",{style:{margin:0,fontSize:18,fontWeight:600,letterSpacing:"-0.01em"}},e),t&&d().createElement("div",{style:{fontSize:12,opacity:.85,marginTop:4}},t)),n)),$r=({message:e})=>{if(!e)return null;const t=e.includes("실패");return d().createElement("div",{style:{position:"fixed",top:8,left:"50%",transform:"translateX(-50%)",zIndex:9999,padding:"10px 20px",background:t?gr:br,color:t?hr:fr,borderRadius:8,fontSize:12,fontWeight:500,border:"1px solid "+(t?"#fecaca":"#bbf7d0"),boxShadow:"0 4px 12px rgba(0,0,0,0.15)",maxWidth:400}},t?"✕ ":"✓ ",e)},Tr=({title:e,badge:t,expanded:n,onToggle:a,children:r,icon:s})=>d().createElement("div",{style:{margin:"12px 20px",background:Cr,borderRadius:10,border:`1px solid ${Er}`,overflow:"hidden",boxShadow:"0 1px 3px rgba(0,0,0,0.04)"}},d().createElement("div",{onClick:a,style:{display:"flex",alignItems:"center",cursor:"pointer",padding:"12px 16px",background:n?vr:Cr,borderBottom:n?`1px solid ${Er}`:"none",userSelect:"none",transition:"background 0.15s"}},d().createElement("span",{style:{fontSize:10,color:wr,marginRight:10,transition:"transform 0.2s",transform:n?"rotate(90deg)":"none"}},"▶"),s&&d().createElement("span",{style:{marginRight:8,fontSize:16}},s),d().createElement("span",{style:{fontWeight:600,fontSize:13,color:_r,flex:1}},e),t&&d().createElement("span",{style:{fontSize:11,background:pr,color:mr,padding:"2px 8px",borderRadius:10,fontWeight:600}},t)),n&&d().createElement("div",{style:{padding:"16px"}},r)),Ar=({label:e,value:t,onChange:n,type:a="text",placeholder:r,disabled:s})=>d().createElement("div",{style:{marginBottom:10,display:"flex",alignItems:"center",gap:10}},d().createElement("label",{style:{minWidth:120,fontSize:12,fontWeight:500,color:Sr}},e),d().createElement("input",{type:a,value:t,onChange:e=>n(e.target.value),placeholder:r,disabled:s,style:{flex:1,padding:"7px 10px",border:`1px solid ${kr}`,borderRadius:6,fontSize:13,outline:"none",background:s?yr:Cr,transition:"border-color 0.15s"}})),Ir=({label:e,onClick:t,disabled:n,variant:a="ghost",size:r="md"})=>{const s={primary:{background:n?kr:mr,color:"#ffffff",border:"none"},danger:{background:"transparent",color:n?wr:hr,border:`1px solid ${n?kr:"#fca5a5"}`},ghost:{background:"transparent",color:n?wr:Sr,border:`1px solid ${kr}`}},o="sm"===r?"5px 10px":"7px 14px";return d().createElement("button",{onClick:t,disabled:n,style:{padding:o,borderRadius:6,cursor:n?"not-allowed":"pointer",fontSize:"sm"===r?11:12,fontWeight:500,marginRight:6,transition:"all 0.15s",...s[a]}},e)},Pr=({headers:e,mapping:t,onChange:n,showIndexFields:a})=>{const r={groupBy:"그룹핑 키",embeddingFields:"임베딩 필드",headerFields:"강조 필드 (헤더+라벨, 선택 순서대로 최대 2개 사용)",tableFields:"테이블 필드",columnFields:"컬럼 필드",indexFields:"텍스트 인덱스 필드"},s=["groupBy","embeddingFields","headerFields","tableFields","columnFields",...a?["indexFields"]:[]];return d().createElement("div",{style:{background:vr,padding:"12px 14px",borderRadius:8,marginTop:10,border:`1px solid ${Er}`}},s.map(a=>d().createElement("div",{key:a,style:{marginBottom:8}},d().createElement("label",{style:{fontWeight:600,fontSize:12,color:Sr}},r[a]),d().createElement("div",{style:{display:"flex",flexWrap:"wrap",gap:4,marginTop:4}},e.map(e=>{const r=(t[a]||[]).indexOf(e),s=r>=0;return d().createElement("label",{key:e,style:{fontSize:11,display:"flex",alignItems:"center",gap:3,padding:"2px 6px",borderRadius:4,background:s?pr:Cr,border:`1px solid ${s?"#93c5fd":Er}`,cursor:"pointer",transition:"all 0.1s"}},d().createElement("input",{type:"checkbox",checked:s,onChange:()=>((e,a)=>{const r=t[e]||[];var s,o;s=e,o=r.includes(a)?r.filter(e=>e!==a):[...r,a],n({...t,[s]:o})})(a,e),style:{display:"none"}}),s&&"headerFields"===a?d().createElement("span",{style:{color:mr,fontSize:10,fontWeight:700}},"#",r+1):s?d().createElement("span",{style:{color:mr,fontSize:10}},"✓"):null,e)})))))},Lr=({step:e,label:t,enabled:n,running:a,complete:r,progress:s,onRun:o})=>d().createElement("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"6px 0",borderBottom:`1px solid ${Er}`}},d().createElement("span",{style:{fontWeight:600,fontSize:13,minWidth:28,color:xr}},"#",e),d().createElement("span",{style:{flex:1,fontSize:13}},t),a&&s?d().createElement("span",{style:{fontSize:12,color:xr}},"⏳ ",s.current,"/",s.total):r?d().createElement("span",{style:{fontSize:12,color:fr}},"✅ ",r.success??r.total_chunks??r.upserted??"완료"):null,d().createElement(Ir,{label:a?"실행 중...":"▶ 실행",onClick:o,variant:"primary",disabled:!n||a})),Mr=({title:e,icon:t,collection:n,points:a,expanded:r,onToggle:s,loading:o,onDeleteCollection:l})=>{const[u,m]=(0,i.useState)(""),[p,h]=(0,i.useState)({}),[g,f]=(0,i.useState)(null),[b,v]=(0,i.useState)(null),[y,E]=(0,i.useState)([]),[k,w]=(0,i.useState)(null),x=(0,i.useCallback)(async()=>{if(u)try{const e=await ur(`rag/admin/guide-pipeline/status?sourceDir=${encodeURIComponent(u)}`,"GET");w(e)}catch{}},[u]);(0,i.useEffect)(()=>{u&&x()},[u,x]);const S=async e=>{f(e),v(null),E([]);try{const t=(()=>{const e=c.PageConfig.getBaseUrl();return c.URLExt.join(e,"codebuff")})(),a={"Content-Type":"application/json","X-XSRFToken":(()=>{const e=`; ${document.cookie}`.split("; _xsrf=");return 2===e.length&&e.pop()?.split(";").shift()||""})()},r=await fetch(`${t}/rag/admin/guide-pipeline`,{method:"POST",headers:a,body:JSON.stringify({sourceDir:u,collection:n,step:e})}),s=r.body?.getReader();if(!s)return;const o=new TextDecoder;let l="";for(;;){const{done:t,value:n}=await s.read();if(t)break;l+=o.decode(n,{stream:!0});const a=l.split("\n");l=a.pop()||"";for(const t of a)if(t.startsWith("data: "))try{const n=JSON.parse(t.slice(6));"running"===n.status?v({current:n.current,total:n.total}):"error"===n.status&&n.file?E(e=>[...e,`${n.file}: ${n.error}`]):"complete"===n.status&&h(t=>({...t,[e]:n}))}catch{}}}catch(t){E(n=>[...n,`Step ${e} 실패: ${t.message}`])}finally{f(null),x()}},_=k?.mdversion?.exists&&k?.mdversion?.files>0,C=k?.chunked?.exists&&k?.chunked?.files>0;return d().createElement(Tr,{title:e,icon:t,badge:`${a}개`,expanded:r,onToggle:s},d().createElement(Ar,{label:"원본 디렉토리",value:u,onChange:m,placeholder:"/home/jovyan/guides/"}),k&&d().createElement("div",{style:{fontSize:11,color:wr,margin:"4px 0 8px"}},"mdversion: ",k.mdversion?.files||0,"개 파일 | chunked: ",k.chunked?.files||0,"개 파일"),d().createElement(Lr,{step:1,label:"MD 재구성",enabled:!!u&&!o,running:1===g,complete:p[1]||(_&&!p[1]?{success:k.mdversion.files}:null),progress:1===g?b:null,onRun:()=>S(1)}),d().createElement(Lr,{step:2,label:"청킹 + 요약",enabled:!!_&&!o,running:2===g,complete:p[2]||(C&&!p[2]?{total_chunks:k.chunked.files}:null),progress:2===g?b:null,onRun:()=>S(2)}),d().createElement(Lr,{step:3,label:"임베딩 적재",enabled:!!C&&!o,running:3===g,complete:p[3],progress:3===g?b:null,onRun:()=>S(3)}),y.length>0&&d().createElement("div",{style:{marginTop:8,fontSize:12,color:hr,maxHeight:100,overflow:"auto"}},y.map((e,t)=>d().createElement("div",{key:t},"⚠ ",e))),d().createElement("div",{style:{marginTop:12}},d().createElement(Ir,{label:"🗑 컬렉션 초기화",onClick:l,variant:"danger",disabled:o})))},Rr=["enterprise_tables","bdp_tables","guide_docs","ds_guide_docs"],qr={"A1_active_users.csv":"Jupyter vs Agent DAU/MAU","A2_agent_frequency.csv":"사용자별 사용 빈도","A3_feature_preference.csv":"기능별 사용량","A4_errors.csv":"실패 유형 집계","A5_cell_attribution.csv":"Agent 셀 기여율","A6_codebuff_users.csv":"Codebuff 사용자 분석","A7_codebuff_feature_mix.csv":"기능별 비중 (softmax)","A8_codebuff_utilization.csv":"Codebuff 활용률"},Dr=[{label:"이번 달",getValue:()=>{const e=new Date,t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0");return{from:`${t}-${n}-01`,to:`${t}-${n}-${String(e.getDate()).padStart(2,"0")}`}}},{label:"지난 달",getValue:()=>{const e=new Date;e.setMonth(e.getMonth()-1);const t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),a=new Date(t,e.getMonth()+1,0).getDate();return{from:`${t}-${n}-01`,to:`${t}-${n}-${String(a).padStart(2,"0")}`}}},{label:"최근 7일",getValue:()=>{const e=new Date,t=new Date;t.setDate(t.getDate()-6);const n=e=>e.toISOString().slice(0,10);return{from:n(t),to:n(e)}}},{label:"전체",getValue:()=>({from:"",to:""})}];async function Or(e,t,a){const{PageConfig:r}=await Promise.resolve().then(()=>n.t(7292,23)),s=r.getBaseUrl(),o=document.cookie.split("; ").find(e=>e.startsWith("_xsrf="))?.split("=")[1]||"";return(await fetch(`${s}codebuff/${e}`,{method:t,headers:{"Content-Type":"application/json","X-XSRFToken":o},body:a?JSON.stringify(a):void 0})).json()}const zr="Codebuff",Fr=[{commandId:"codebuff:open-rag-settings",widgetId:"codebuff-rag-settings",label:"RAG 설정",caption:"Qdrant, 임베딩, 청킹 설정",icon:new u.LabIcon({name:"codebuff:rag-settings",svgstr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.49.49 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.48.48 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96a.49.49 0 0 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6A3.6 3.6 0 1 1 12 8.4a3.6 3.6 0 0 1 0 7.2z"/></svg>'}),rank:1,Component:({onClose:e})=>{const[t,n]=(0,i.useState)(null),[a,r]=(0,i.useState)(!1),[s,o]=(0,i.useState)(""),[l,c]=(0,i.useState)({qdrant:!0,embedding:!0,chunking:!1}),[u,m]=(0,i.useState)(800),[p,h]=(0,i.useState)(150),[g,f]=(0,i.useState)(2e3),b=e=>c(t=>({...t,[e]:!t[e]})),v=e=>{o(e),setTimeout(()=>o(""),5e3)},y=(0,i.useCallback)(async()=>{try{const e=await ur("rag/admin/config");n(e),e.chunking&&(m(e.chunking.target_size||800),h(e.chunking.min_size||150),f(e.chunking.max_size||2e3))}catch(e){v(`로드 실패: ${e.message}`)}},[]);(0,i.useEffect)(()=>{y()},[y]);const E=async e=>{if(t){r(!0);try{const n={};"qdrant"===e?(n.qdrantMode=t.qdrantMode,n.qdrantUrl=t.qdrantUrl,n.qdrantApiKey=t.qdrantApiKey,n.qdrantPath=t.qdrantPath):n.chunking={target_size:u,min_size:p,max_size:g,overlap:0},await ur("rag/admin/config","POST",n),v(("qdrant"===e?"Qdrant":"청킹")+" 설정 저장 완료"),await y()}catch(e){v(`저장 실패: ${e.message}`)}r(!1)}},k=(e,a)=>{t&&n({...t,[e]:a})};return t?d().createElement(Nr,null,d().createElement(jr,{title:"RAG 설정",subtitle:"Qdrant 연결, 임베딩 모델, 청킹 파라미터"}),d().createElement($r,{message:s}),d().createElement(Tr,{title:"Qdrant 연결",icon:"🗄️",expanded:l.qdrant,onToggle:()=>b("qdrant")},d().createElement("div",{style:{marginBottom:10}},d().createElement("label",{style:{fontSize:12,fontWeight:500,color:Sr,marginRight:16}},"모드"),["local","server"].map(e=>d().createElement("label",{key:e,style:{fontSize:12,marginRight:14,padding:"4px 10px",borderRadius:6,border:`1px solid ${t.qdrantMode===e?mr:kr}`,background:t.qdrantMode===e?pr:"transparent",color:t.qdrantMode===e?mr:Sr,cursor:"pointer",fontWeight:500}},d().createElement("input",{type:"radio",name:"qdrantMode",value:e,checked:t.qdrantMode===e,onChange:()=>k("qdrantMode",e),style:{display:"none"}}),"local"===e?"Local (파일)":"Server (원격)"))),"server"===t.qdrantMode&&d().createElement(d().Fragment,null,d().createElement(Ar,{label:"URL",value:t.qdrantUrl,onChange:e=>k("qdrantUrl",e)}),d().createElement(Ar,{label:"API Key",value:t.qdrantApiKey,onChange:e=>k("qdrantApiKey",e),type:"password"})),"local"===t.qdrantMode&&d().createElement(Ar,{label:"저장 경로",value:t.qdrantPath,onChange:e=>k("qdrantPath",e)}),d().createElement("div",{style:{marginTop:10,display:"flex",gap:6}},d().createElement(Ir,{label:"연결 테스트",onClick:()=>(async e=>{r(!0);try{const t=await ur("rag/admin/test-connection","POST",{type:e});v(t.success?`${e} 연결 성공`:`${e} 연결 실패: ${t.error}`)}catch(e){v(`연결 테스트 실패: ${e.message}`)}r(!1)})("qdrant"),disabled:a}),d().createElement(Ir,{label:"저장",onClick:()=>E("qdrant"),variant:"primary",disabled:a}))),d().createElement(Tr,{title:"임베딩 모델",icon:"🧠",expanded:l.embedding,onToggle:()=>b("embedding")},d().createElement(Ar,{label:"Endpoint",value:t.embeddingEndpoint,onChange:()=>{},disabled:!0}),d().createElement(Ar,{label:"Model",value:t.embeddingModel,onChange:()=>{},disabled:!0}),d().createElement(Ar,{label:"Dimension",value:t.embeddingDimension,onChange:()=>{},type:"number",disabled:!0}),d().createElement("div",{"data-testid":"rag-embedding-readonly",style:{fontSize:11,color:wr,marginTop:4}},"centri 포털에서 관리합니다. API 키는 시크릿 env(EMBEDDING_API_KEY)로만 들어옵니다",t.embeddingApiKey?" — 설정됨":" — 없음",".")),d().createElement(Tr,{title:"청킹 설정",icon:"✂️",expanded:l.chunking,onToggle:()=>b("chunking")},d().createElement(Ar,{label:"Target Size (자)",value:u,onChange:e=>m(parseInt(e)||800),type:"number"}),d().createElement(Ar,{label:"Min Size (자)",value:p,onChange:e=>h(parseInt(e)||150),type:"number"}),d().createElement(Ar,{label:"Max Size (자)",value:g,onChange:e=>f(parseInt(e)||2e3),type:"number"}),d().createElement("div",{style:{fontSize:11,color:wr,marginTop:4}},"Overlap: 0 (헤더 프리픽스 + LLM 요약으로 대체)"),d().createElement("div",{style:{marginTop:10}},d().createElement(Ir,{label:"저장",onClick:()=>E("chunking"),variant:"primary",disabled:a})))):d().createElement("div",{style:{padding:40,textAlign:"center",color:wr}},"설정 로드 중...")}},{commandId:"codebuff:open-rag-load",widgetId:"codebuff-rag-load",label:"RAG 적재",caption:"컬렉션 데이터 적재 및 변환",icon:new u.LabIcon({name:"codebuff:rag-load",svgstr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></svg>'}),rank:2,Component:({onClose:e})=>{const[t,n]=(0,i.useState)(null),[a,r]=(0,i.useState)({}),[s,o]=(0,i.useState)([]),[l,c]=(0,i.useState)(!1),[u,m]=(0,i.useState)(""),[p,h]=(0,i.useState)({enterprise:!0,bdp:!1,guide:!1,dsGuide:!1,faq:!1,stats:!0,history:!1}),g="rag_load_settings",f=()=>{try{return JSON.parse(localStorage.getItem(g)||"{}")}catch{return{}}},b=e=>{try{localStorage.setItem(g,JSON.stringify({...f(),...e}))}catch{}},v=f(),[y,E]=(0,i.useState)(v.enterpriseFile||""),[k,w]=(0,i.useState)(v.enterpriseMapping||{}),[x,S]=(0,i.useState)(v.bdpTableFile||""),[_,C]=(0,i.useState)(v.bdpColumnFile||""),[N,j]=(0,i.useState)(v.bdpJoinKey||"table_id"),[$,T]=(0,i.useState)(v.bdpMapping||{}),[A,I]=(0,i.useState)(v.faqFile||""),[P,L]=(0,i.useState)([]),[M,R]=(0,i.useState)([]),[q,D]=(0,i.useState)(null),[O,z]=(0,i.useState)(null),[F,B]=(0,i.useState)(800),[W,U]=(0,i.useState)(150),[H,J]=(0,i.useState)(2e3),V=e=>h(t=>({...t,[e]:!t[e]})),G=e=>{m(e),setTimeout(()=>m(""),5e3)},X=(0,i.useCallback)(async()=>{try{const[e,t,a]=await Promise.all([ur("rag/admin/config"),ur("rag/admin/stats").catch(()=>({stats:{}})),ur("rag/admin/history").catch(()=>({history:[]}))]);n(e),r(t.stats||{}),o(a.history||[]),e.chunking&&(B(e.chunking.target_size||800),U(e.chunking.min_size||150),J(e.chunking.max_size||2e3))}catch(e){G(`로드 실패: ${e.message}`)}},[]);(0,i.useEffect)(()=>{X()},[X]);const Z=async(e,t)=>{try{const n=await ur("rag/admin/preview","POST",{filePath:e,type:"csv_headers"});(t||L)(n.headers||[])}catch(e){G(`헤더 로드 실패: ${e.message}`)}},K=async(e,t)=>{try{const n=new Set;e&&((await ur("rag/admin/preview","POST",{filePath:e,type:"csv_headers"})).headers||[]).forEach(e=>n.add(e)),t&&((await ur("rag/admin/preview","POST",{filePath:t,type:"csv_headers"})).headers||[]).forEach(e=>n.add(e)),R(Array.from(n).sort())}catch(e){G(`BDP 헤더 로드 실패: ${e.message}`)}};(0,i.useEffect)(()=>{b({enterpriseFile:y,enterpriseMapping:k,bdpTableFile:x,bdpColumnFile:_,bdpJoinKey:N,bdpMapping:$})},[y,k,x,_,N,$]),(0,i.useEffect)(()=>{y&&Z(y),(x||_)&&K(x,_)},[]);const Q=async(e,t,n,a,r)=>{c(!0);try{const s={collection:e,filePath:t,mapping:n};a&&(s.joinFilePath=a),r&&(s.joinKey=r),"guide_docs"!==e&&"ds_guide_docs"!==e||(s.chunking={target_size:F,min_size:W,max_size:H,overlap:0}),z({status:"starting"});const o=window.setInterval(async()=>{try{const e=await ur("rag/admin/progress");z(e),"done"!==e.status&&"idle"!==e.status||window.clearInterval(o)}catch{}},1e3);try{const e=await ur("rag/admin/upsert","POST",s);window.clearInterval(o),z(null);const t=e.skipped?`, 기존 ${e.skipped}건 스킵`:"";G(`적재 완료: ${e.total_chunks||e.total||0}건 (${e.elapsed_s||0}s${t})`),await X()}catch(e){window.clearInterval(o),z(null),G(`적재 실패: ${e.message}`)}}catch(e){G(`적재 실패: ${e.message}`)}c(!1)},Y=async e=>{if(confirm(`${e} 컬렉션을 초기화하시겠습니까?`)){c(!0);try{await ur(`rag/admin/collection/${e}`,"DELETE"),G(`${e} 초기화 완료`),await X()}catch(e){G(`초기화 실패: ${e.message}`)}c(!1)}},ee=async(e,t,n)=>{c(!0);try{const a={collection:e,filePath:t,mapping:n};"bdp_tables"===e&&(a.joinFilePath=_,a.joinKey=N),"guide_docs"!==e&&"ds_guide_docs"!==e||(a.chunking={target_size:F,min_size:W,max_size:H});const r=await ur("rag/admin/dry-run","POST",a);D(r),G("프리뷰 완료")}catch(e){G(`프리뷰 실패: ${e.message}`)}c(!1)};return t?d().createElement(Nr,null,d().createElement(jr,{title:"RAG 적재",subtitle:"컬렉션 데이터 적재 및 변환"}),d().createElement($r,{message:u}),O&&"idle"!==O.status&&"done"!==O.status&&"cancelled"!==O.status&&d().createElement("div",{style:{margin:"0 0 12px",padding:"10px 14px",background:vr,borderRadius:8,border:`1px solid ${Er}`}},d().createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:6}},d().createElement("span",{style:{fontSize:12,color:xr}},O.total?`${O.collection||""} 적재 중... ${O.done||0}/${O.total}`:"적재 준비 중..."),d().createElement(Ir,{label:"중지",variant:"danger",onClick:async()=>{try{await ur("rag/admin/cancel","POST"),G("적재 중지 요청됨")}catch{}}})),d().createElement("div",{style:{height:6,background:Er,borderRadius:3,overflow:"hidden"}},d().createElement("div",{style:{height:"100%",width:O.total?`${Math.round((O.done||0)/O.total*100)}%`:"0%",background:mr,borderRadius:3,transition:"width 0.3s ease"}}))),d().createElement(Tr,{title:"전사 테이블",icon:"🏢",badge:`${a.enterprise_tables?.points||0}개`,expanded:p.enterprise,onToggle:()=>V("enterprise")},d().createElement(Ar,{label:"데이터 파일 (CSV/Parquet)",value:y,onChange:e=>{E(e),e&&Z(e)},placeholder:"/home/jovyan/data/tables.csv 또는 .parquet"}),P.length>0&&d().createElement(Pr,{headers:P,mapping:k,onChange:w,showIndexFields:!0}),d().createElement("div",{style:{marginTop:12,display:"flex",gap:6}},d().createElement(Ir,{label:"검증",onClick:()=>(async(e,t)=>{try{const n=await ur("rag/admin/validate","POST",{filePath:e,mapping:t});G(n.valid?`검증 통과 (${n.total_rows}행)`:`검증 실패: ${n.missing_fields?.join(", ")}`)}catch(e){G(`검증 실패: ${e.message}`)}})(y,k),disabled:!y}),d().createElement(Ir,{label:"프리뷰",onClick:()=>ee("enterprise_tables",y,k),disabled:!y}),d().createElement(Ir,{label:"적재 실행",onClick:()=>Q("enterprise_tables",y,k),variant:"primary",disabled:l||!y}),d().createElement(Ir,{label:"초기화",onClick:()=>Y("enterprise_tables"),variant:"danger"}))),d().createElement(Tr,{title:"BDP 테이블",icon:"📋",badge:`${a.bdp_tables?.points||0}개`,expanded:p.bdp,onToggle:()=>V("bdp")},d().createElement(Ar,{label:"테이블 파일 (CSV/Parquet)",value:x,onChange:e=>{S(e),T({}),e&&K(e,_)},placeholder:"/home/jovyan/data/bdp_tables.csv 또는 .parquet"}),d().createElement(Ar,{label:"컬럼 파일 (CSV/Parquet)",value:_,onChange:e=>{C(e),e&&K(x,e)},placeholder:"/home/jovyan/data/bdp_columns.csv 또는 .parquet"}),d().createElement(Ar,{label:"조인 키",value:N,onChange:j}),M.length>0&&d().createElement(Pr,{headers:M,mapping:$,onChange:T,showIndexFields:!0}),d().createElement("div",{style:{marginTop:12,display:"flex",gap:6}},d().createElement(Ir,{label:"프리뷰",onClick:()=>ee("bdp_tables",x,$),disabled:!x}),d().createElement(Ir,{label:"적재 실행",onClick:()=>Q("bdp_tables",x,$,_,N),variant:"primary",disabled:l||!x}),d().createElement(Ir,{label:"초기화",onClick:()=>Y("bdp_tables"),variant:"danger"}))),d().createElement(Mr,{title:"BDP 가이드 문서",icon:"📖",collection:"guide_docs",points:a.guide_docs?.points||0,expanded:p.guide,onToggle:()=>V("guide"),loading:l,onDeleteCollection:()=>Y("guide_docs")}),d().createElement(Mr,{title:"DS 가이드 문서",icon:"📗",collection:"ds_guide_docs",points:a.ds_guide_docs?.points||0,expanded:p.dsGuide,onToggle:()=>V("dsGuide"),loading:l,onDeleteCollection:()=>Y("ds_guide_docs")}),d().createElement(Tr,{title:"FAQ",icon:"❓",badge:`${a.faq_docs?.points||0}개`,expanded:p.faq,onToggle:()=>V("faq")},d().createElement(Ar,{label:"CSV 파일 경로 (컬럼: question, answer, tags)",value:A,onChange:e=>{I(e),b({faqFile:e})},placeholder:"/home/jovyan/data/faq.csv"}),d().createElement("div",{style:{marginTop:12,display:"flex",gap:6}},d().createElement(Ir,{label:"적재 실행",onClick:()=>Q("faq_docs",A),variant:"primary",disabled:l||!A}),d().createElement(Ir,{label:"초기화",onClick:()=>Y("faq_docs"),variant:"danger"})),d().createElement("div",{style:{fontSize:11,color:"#888",marginTop:8,lineHeight:1.5}},"질문(question)만 임베딩됩니다. answer/tags는 payload에 저장.",d().createElement("br",null),"guide_docs 검색 시 자동으로 함께 검색되어 LLM에 참고용으로 전달됩니다.")),d().createElement(Tr,{title:"컬렉션 현황",icon:"📊",expanded:p.stats,onToggle:()=>V("stats")},d().createElement("div",{style:{display:"flex",gap:10,flexWrap:"wrap"}},["enterprise_tables","bdp_tables","guide_docs","ds_guide_docs","faq_docs"].map(e=>{const t=a[e]||{points:0,status:"unknown"},n={enterprise_tables:"전사 테이블",bdp_tables:"BDP 테이블",guide_docs:"BDP 가이드",ds_guide_docs:"DS 가이드",faq_docs:"FAQ"}[e]||e;return d().createElement("div",{key:e,style:{flex:1,minWidth:130,padding:"14px 12px",background:vr,borderRadius:10,border:`1px solid ${Er}`,textAlign:"center"}},d().createElement("div",{style:{fontSize:22,fontWeight:700,color:t.points>0?mr:wr}},t.points),d().createElement("div",{style:{fontSize:11,color:xr,marginTop:2,marginBottom:8}},n),d().createElement("button",{onClick:()=>Y(e),disabled:l||0===t.points,style:{fontSize:11,padding:"3px 10px",borderRadius:6,border:`1px solid ${t.points>0?"#fecaca":Er}`,background:t.points>0?gr:yr,color:t.points>0?hr:wr,cursor:t.points>0?"pointer":"default",fontWeight:500}},"전체 삭제"))}))),d().createElement(Tr,{title:"적재 이력",icon:"📜",expanded:p.history,onToggle:()=>V("history")},0===s.length?d().createElement("div",{style:{color:wr,fontSize:12,textAlign:"center",padding:12}},"이력 없음"):d().createElement("div",{style:{maxHeight:280,overflow:"auto"}},d().createElement("table",{style:{width:"100%",fontSize:12,borderCollapse:"collapse"}},d().createElement("thead",null,d().createElement("tr",{style:{borderBottom:`2px solid ${Er}`}},d().createElement("th",{style:{textAlign:"left",padding:"6px 8px",fontWeight:600,color:Sr}},"시각"),d().createElement("th",{style:{textAlign:"left",padding:"6px 8px",fontWeight:600,color:Sr}},"컬렉션"),d().createElement("th",{style:{textAlign:"right",padding:"6px 8px",fontWeight:600,color:Sr}},"건수"),d().createElement("th",{style:{textAlign:"right",padding:"6px 8px",fontWeight:600,color:Sr}},"시간"),d().createElement("th",{style:{textAlign:"center",padding:"6px 8px",fontWeight:600,color:Sr}},"상태"))),d().createElement("tbody",null,[...s].reverse().map((e,t)=>d().createElement("tr",{key:t,style:{borderBottom:`1px solid ${yr}`}},d().createElement("td",{style:{padding:"6px 8px",color:xr}},e.timestamp.substring(5,16)),d().createElement("td",{style:{padding:"6px 8px"}},e.collection),d().createElement("td",{style:{textAlign:"right",padding:"6px 8px",fontWeight:600}},e.count),d().createElement("td",{style:{textAlign:"right",padding:"6px 8px",color:xr}},e.elapsed_s,"s"),d().createElement("td",{style:{textAlign:"center",padding:"6px 8px"}},e.errors.length>0?d().createElement("span",{style:{color:hr,fontWeight:600}},e.errors.length," err"):d().createElement("span",{style:{color:fr}},"OK")))))))),q&&d().createElement("div",{style:{margin:"0 20px 20px",background:vr,borderRadius:10,border:`1px solid ${Er}`,overflow:"hidden"}},d().createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"10px 14px",borderBottom:`1px solid ${Er}`}},d().createElement("span",{style:{fontWeight:600,fontSize:13,color:_r}},"프리뷰 결과"),d().createElement(Ir,{label:"닫기",onClick:()=>D(null),size:"sm"})),d().createElement("pre",{style:{fontSize:11,maxHeight:300,overflow:"auto",whiteSpace:"pre-wrap",padding:14,margin:0}},JSON.stringify(q,null,2)))):d().createElement("div",{style:{padding:40,textAlign:"center",color:wr}},"로드 중...")}},{commandId:"codebuff:open-rag-browser",widgetId:"codebuff-rag-browser",label:"데이터 탐색",caption:"데이터 브라우저 및 검색 테스트",icon:new u.LabIcon({name:"codebuff:rag-browse",svgstr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>'}),rank:3,Component:({onClose:e})=>{const[t,n]=(0,i.useState)(!1),[a,r]=(0,i.useState)(""),[s,o]=(0,i.useState)({browser:!0,search:!0}),[l,c]=(0,i.useState)("enterprise_tables"),[u,m]=(0,i.useState)(null),[p,h]=(0,i.useState)(null),[g,f]=(0,i.useState)([]),[b,v]=(0,i.useState)(new Set),[y,E]=(0,i.useState)([{field:"",value:""}]),[k,w]=(0,i.useState)(""),[x,S]=(0,i.useState)(""),[_,C]=(0,i.useState)([]),[N,j]=(0,i.useState)(new Set),$=e=>o(t=>({...t,[e]:!t[e]})),T=e=>{r(e),setTimeout(()=>r(""),5e3)},A=async(e=null,t=!0)=>{n(!0);try{let n=e?`offset=${e}&limit=10`:"limit=10";const a=y.filter(e=>e.field&&e.value);a.length>0&&(n+=`&filters=${encodeURIComponent(JSON.stringify(a))}`);const r=await ur(`rag/admin/browse/${l}?${n}`);m(r),t&&f(e=>[...e,p]),h(e),v(new Set)}catch(e){T(`브라우저 오류: ${e.message}`)}n(!1)},I=e=>{if(!e)return"";if(e.title){let t=e.title;return e.section&&(t+=` > ${e.section}`),t}const t=Object.keys(e).filter(e=>!e.startsWith("_"));return t.length>0?t.slice(0,3).map(t=>{const n=e[t];return"string"==typeof n?n.length>40?n.substring(0,40)+"...":n:Array.isArray(n)?`[${n.length}건]`:String(n)}).join(" | "):JSON.stringify(e).substring(0,60)},P=e=>{if(!e)return null;const t=Object.entries(e);return d().createElement("div",{style:{display:"flex",flexDirection:"column",gap:6}},t.map(([e,t])=>d().createElement("div",{key:e,style:{display:"flex",gap:8,fontSize:12}},d().createElement("span",{style:{minWidth:100,fontWeight:600,color:mr,flexShrink:0,wordBreak:"break-all"}},e),d().createElement("span",{style:{color:_r,wordBreak:"break-all",whiteSpace:"pre-wrap",lineHeight:1.5,flex:1}},"string"==typeof t?t:JSON.stringify(t,null,2)))))};return d().createElement(Nr,null,d().createElement(jr,{title:"데이터 탐색",subtitle:"적재된 데이터 조회 및 검색 테스트"}),d().createElement($r,{message:a}),d().createElement(Tr,{title:"데이터 브라우저",icon:"🔍",expanded:s.browser,onToggle:()=>$("browser")},d().createElement("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:10}},d().createElement("label",{style:{fontSize:12,fontWeight:500,color:Sr},htmlFor:"jp-rag-browser-collection"},"컬렉션"),d().createElement("select",{id:"jp-rag-browser-collection",value:l,onChange:e=>c(e.target.value),style:{padding:"6px 10px",fontSize:13,border:`1px solid ${kr}`,borderRadius:6,outline:"none",background:Cr}},Rr.map(e=>d().createElement("option",{key:e,value:e},e))),d().createElement(Ir,{label:"조회",onClick:()=>{f([]),A(null,!1)},variant:"primary",disabled:t})),d().createElement("div",{style:{marginBottom:12,padding:"8px 10px",background:vr,borderRadius:6,border:`1px solid ${Er}`}},d().createElement("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:6}},d().createElement("label",{style:{fontSize:11,fontWeight:500,color:xr}},"필터 (AND)"),d().createElement("button",{onClick:()=>E(e=>[...e,{field:"",value:""}]),style:{fontSize:11,color:mr,background:"none",border:"none",cursor:"pointer",padding:"2px 6px",fontWeight:500}},"+ 추가")),y.map((e,t)=>d().createElement("div",{key:t,style:{display:"flex",alignItems:"center",gap:6,marginBottom:4}},d().createElement("input",{type:"text",value:e.field,onChange:e=>{const n=[...y];n[t]={...n[t],field:e.target.value},E(n)},placeholder:"필드 (예: source, columns[].col_name)",style:{padding:"4px 8px",fontSize:12,border:`1px solid ${kr}`,borderRadius:4,outline:"none",flex:1,minWidth:0}}),d().createElement("span",{style:{fontSize:11,color:wr}},"="),d().createElement("input",{type:"text",value:e.value,onChange:e=>{const n=[...y];n[t]={...n[t],value:e.target.value},E(n)},placeholder:"값",style:{padding:"4px 8px",fontSize:12,border:`1px solid ${kr}`,borderRadius:4,outline:"none",flex:1,minWidth:0}}),d().createElement("button",{onClick:()=>{y.length<=1?E([{field:"",value:""}]):E(e=>e.filter((e,n)=>n!==t))},style:{fontSize:11,color:wr,background:"none",border:"none",cursor:"pointer",padding:"2px 4px",flexShrink:0}},"✕"))),d().createElement("div",{style:{fontSize:10,color:wr,marginTop:4}},"배열 내부 필터: columns[].col_name = 값")),u&&d().createElement(d().Fragment,null,d().createElement("div",{style:{fontSize:12,color:xr,marginBottom:8}},u.count,"건 표시",y.filter(e=>e.field&&e.value).map((e,t)=>d().createElement("span",{key:t,style:{marginLeft:6,fontSize:11,background:pr,color:mr,padding:"1px 8px",borderRadius:10}},e.field," = ",e.value))),d().createElement("div",{style:{maxHeight:500,overflow:"auto"}},u.items?.map(e=>{const t=b.has(e.id);return d().createElement("div",{key:e.id,style:{marginBottom:6,background:Cr,borderRadius:8,border:`1px solid ${t?mr:Er}`,overflow:"hidden",transition:"border-color 0.15s"}},d().createElement("div",{onClick:()=>{return t=e.id,void v(e=>{const n=new Set(e);return n.has(t)?n.delete(t):n.add(t),n});var t},style:{display:"flex",alignItems:"center",padding:"8px 12px",cursor:"pointer",background:t?vr:"transparent",gap:8,userSelect:"none"}},d().createElement("span",{style:{fontSize:10,color:wr,transition:"transform 0.15s",transform:t?"rotate(90deg)":"none",flexShrink:0}},"▶"),d().createElement("code",{style:{fontSize:11,color:mr,fontWeight:600,flexShrink:0}},e.id.substring(0,8)),d().createElement("span",{style:{fontSize:12,color:Sr,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}},I(e.payload)),d().createElement("button",{onClick:t=>{t.stopPropagation(),(async e=>{try{await ur(`rag/admin/browse/${l}`,"DELETE",{pointId:e}),A(p,!1)}catch(e){T(`삭제 실패: ${e.message}`)}})(e.id)},style:{fontSize:11,color:hr,background:"none",border:"none",cursor:"pointer",padding:"2px 6px",borderRadius:4,flexShrink:0,opacity:.6},onMouseEnter:e=>e.currentTarget.style.opacity="1",onMouseLeave:e=>e.currentTarget.style.opacity="0.6"},"삭제")),t&&d().createElement("div",{style:{padding:"12px 16px",borderTop:`1px solid ${Er}`,background:Cr}},P(e.payload)))})),d().createElement("div",{style:{marginTop:10,display:"flex",gap:6}},d().createElement(Ir,{label:"← 이전",onClick:()=>{const e=g[g.length-1]??null;f(e=>e.slice(0,-1)),A(e,!1)},disabled:0===g.length}),d().createElement(Ir,{label:"다음 →",onClick:()=>A(u.next_offset),disabled:!u.next_offset})))),d().createElement(Tr,{title:"검색 테스트",icon:"⚡",expanded:s.search,onToggle:()=>$("search")},d().createElement(Ar,{label:"검색 쿼리",value:k,onChange:w,placeholder:"카드 거래 테이블"}),d().createElement("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:12}},d().createElement("label",{style:{fontSize:12,fontWeight:500,color:Sr,minWidth:120},htmlFor:"jp-rag-browser-search-collection"},"컬렉션"),d().createElement("select",{id:"jp-rag-browser-search-collection",value:x,onChange:e=>S(e.target.value),style:{padding:"6px 10px",fontSize:13,border:`1px solid ${kr}`,borderRadius:6,outline:"none",flex:1,background:Cr}},d().createElement("option",{value:""},"전체"),Rr.map(e=>d().createElement("option",{key:e,value:e},e))),d().createElement(Ir,{label:"검색",onClick:async()=>{if(k){n(!0);try{const e=await ur("rag/admin/search-test","POST",{query:k,collection:x||null,topK:5});C(e.results||[]),j(new Set)}catch(e){T(`검색 실패: ${e.message}`)}n(!1)}},variant:"primary",disabled:t||!k})),_.length>0&&d().createElement("div",{style:{maxHeight:500,overflow:"auto"}},_.map((e,t)=>{const n=N.has(t);return d().createElement("div",{key:t,style:{marginBottom:6,background:Cr,borderRadius:8,border:`1px solid ${n?mr:Er}`,overflow:"hidden",transition:"border-color 0.15s"}},d().createElement("div",{onClick:()=>{return e=t,void j(t=>{const n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n});var e},style:{display:"flex",alignItems:"center",padding:"8px 12px",cursor:"pointer",background:n?vr:"transparent",gap:8,userSelect:"none"}},d().createElement("span",{style:{fontSize:10,color:wr,transition:"transform 0.15s",transform:n?"rotate(90deg)":"none",flexShrink:0}},"▶"),d().createElement("span",{style:{fontSize:11,fontWeight:600,color:_r,flexShrink:0}},e.collection),d().createElement("span",{style:{fontSize:12,color:Sr,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}},I(e.payload)),d().createElement("span",{style:{fontSize:11,fontWeight:700,color:e.score>=.8?fr:e.score>=.5?"#d97706":hr,background:e.score>=.8?br:e.score>=.5?"var(--codebuff-rag-warn-light, #fffbeb)":gr,padding:"1px 8px",borderRadius:10,flexShrink:0}},"number"==typeof e.score?e.score.toFixed(3):e.score)),n&&d().createElement("div",{style:{padding:"12px 16px",borderTop:`1px solid ${Er}`,background:Cr}},P(e.payload)))})),0===_.length&&k&&!t&&d().createElement("div",{style:{color:wr,fontSize:12,textAlign:"center",padding:16}},"검색 버튼을 눌러 결과를 확인하세요")))}},{commandId:"codebuff:open-analytics",widgetId:"codebuff-analytics",label:"LOG 취합",caption:"Analytics JSONL → CSV 리포트 생성",icon:new u.LabIcon({name:"codebuff:analytics",svgstr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/></svg>'}),rank:4,Component:({onClose:e})=>{const t="codebuff-analytics-settings",n=(()=>{try{const e=(0,S.GK)(t,"hdsp-analytics-settings");if(e)return JSON.parse(e)}catch{}return{}})(),[a,r]=(0,i.useState)(n.inputDir||"/home/jovyan/all_logs"),[s,o]=(0,i.useState)(n.outputDir||""),[l,c]=(0,i.useState)(n.dateFrom||""),[u,m]=(0,i.useState)(n.dateTo||""),[p,h]=(0,i.useState)({status:"idle"}),[g,f]=(0,i.useState)(""),b=(0,i.useRef)(null),[v,y]=(0,i.useState)(null),[E,k]=(0,i.useState)(null),[w,x]=(0,i.useState)(!1);(0,i.useEffect)(()=>{try{localStorage.setItem(t,JSON.stringify({inputDir:a,outputDir:s,dateFrom:l,dateTo:u}))}catch{}},[a,s,l,u]),(0,i.useEffect)(()=>()=>{b.current&&clearInterval(b.current)},[]);const _=p.total?Math.round((p.current||0)/p.total*100):0,C="running"===p.status;return d().createElement("div",{className:"jp-analytics-panel"},d().createElement("div",{className:"jp-analytics-header"},d().createElement("h2",null,"LOG 취합"),d().createElement("span",{className:"jp-analytics-subtitle"},"Analytics JSONL 로그를 집계하여 CSV 리포트를 생성합니다")),d().createElement("div",{className:"jp-analytics-section"},d().createElement("div",{className:"jp-analytics-field"},d().createElement("label",null,"JSONL 디렉토리"),d().createElement("input",{type:"text",value:a,onChange:e=>r(e.target.value),placeholder:"/home/jovyan/all_logs",disabled:C})),d().createElement("div",{className:"jp-analytics-field"},d().createElement("label",null,"출력 디렉토리 ",d().createElement("span",{className:"jp-analytics-optional"},"(비워두면 입력 디렉토리/reports/)")),d().createElement("input",{type:"text",value:s,onChange:e=>o(e.target.value),placeholder:"(기본: inputDir/reports/)",disabled:C})),d().createElement("div",{className:"jp-analytics-field"},d().createElement("label",null,"기간"),d().createElement("div",{className:"jp-analytics-date-row"},d().createElement("input",{type:"date","aria-label":"기간 시작일",value:l,onChange:e=>c(e.target.value),disabled:C}),d().createElement("span",{className:"jp-analytics-date-sep"},"~"),d().createElement("input",{type:"date","aria-label":"기간 종료일",value:u,onChange:e=>m(e.target.value),disabled:C})),d().createElement("div",{className:"jp-analytics-presets"},Dr.map(e=>d().createElement("button",{key:e.label,onClick:()=>(e=>{const{from:t,to:n}=e.getValue();c(t),m(n)})(e),disabled:C,className:"jp-analytics-preset-btn"},e.label))))),d().createElement("div",{className:"jp-analytics-actions"},d().createElement("button",{onClick:async()=>{f(""),h({status:"running",current:0,total:8,step:"시작 중..."});try{const e=await Or("analytics/aggregate","POST",{inputDir:a,outputDir:s||void 0,dateFrom:l||void 0,dateTo:u||void 0});if(e.error)return f(e.error),void h({status:"error",step:e.error});b.current&&clearInterval(b.current),b.current=setInterval(async()=>{try{const e=await Or("analytics/progress","GET");h(e),"done"!==e.status&&"error"!==e.status||(b.current&&(clearInterval(b.current),b.current=null),"error"===e.status&&e.step&&f(e.step))}catch{}},500)}catch(e){f(e.message),h({status:"error",step:e.message})}},disabled:C||!a,className:"jp-analytics-run-btn"},C?"생성 중...":"리포트 생성")),C&&d().createElement("div",{className:"jp-analytics-progress"},d().createElement("div",{className:"jp-analytics-progress-label"},p.step,d().createElement("span",{className:"jp-analytics-progress-count"},p.current||0," / ",p.total||8)),d().createElement("div",{className:"jp-analytics-progress-bar"},d().createElement("div",{className:"jp-analytics-progress-fill",style:{width:`${_}%`}}))),g&&d().createElement("div",{className:"jp-analytics-error"},g),"done"===p.status&&p.reports&&d().createElement("div",{className:"jp-analytics-results"},d().createElement("div",{className:"jp-analytics-results-header"},d().createElement("span",{className:"jp-analytics-results-title"},"생성 완료"),d().createElement("span",{className:"jp-analytics-results-meta"},p.fileCounts)),d().createElement("div",{className:"jp-analytics-results-path"},"출력: ",d().createElement("code",null,p.outputDir)),d().createElement("div",{className:"jp-analytics-results-grid"},p.reports.map(e=>d().createElement("div",{key:e.name},d().createElement("div",{className:"jp-analytics-report-card "+(v===e.name?"expanded":""),onClick:()=>(async e=>{if(v===e)return y(null),void k(null);y(e),k(null),x(!0);try{const t=p.outputDir||"",n=t?`${t}/${e}`:e,a=await Or("analytics/read-csv","POST",{filePath:n});a.error?(k(null),f(a.error)):k({headers:a.headers,rows:a.rows})}catch(e){f(e.message)}finally{x(!1)}})(e.name),style:{cursor:"pointer"}},d().createElement("div",{className:"jp-analytics-report-name"},e.name),d().createElement("div",{className:"jp-analytics-report-desc"},qr[e.name]||""),d().createElement("div",{className:"jp-analytics-report-rows"},e.rows.toLocaleString(),"행",d().createElement("span",{className:"jp-analytics-expand-icon"},v===e.name?"▲":"▼"))),v===e.name&&d().createElement("div",{className:"jp-analytics-csv-preview"},w?d().createElement("div",{className:"jp-analytics-csv-loading"},"로딩 중..."):E?d().createElement("div",{className:"jp-analytics-csv-table-wrap"},d().createElement("table",{className:"jp-analytics-csv-table"},d().createElement("thead",null,d().createElement("tr",null,E.headers.map(e=>d().createElement("th",{key:e},e)))),d().createElement("tbody",null,E.rows.map((e,t)=>d().createElement("tr",{key:t},E.headers.map(t=>d().createElement("td",{key:t},e[t]??""))))))):null))))))}}],Br={id:"codebuff:rag-admin",autoStart:!0,optional:[Wn.ILauncher,r.ICommandPalette],activate:(e,t,n)=>{console.log("[RAGAdminPlugin] Activating (3 panels)");let a=null;const r=async()=>{if(null!==a)return a;try{const t=await fetch(`${e.serviceManager?.serverSettings?.baseUrl||""}codebuff/config/is-admin`),n=await t.json();a=!0===n.isAdmin}catch{a=!0}return a};for(const t of Fr)e.commands.addCommand(t.commandId,{label:t.label,caption:t.caption,icon:t.icon,execute:async()=>{if(!await r())return;const n=e.shell.widgets("main");let a=n.next();for(;a&&!a.done;){if(a.value?.id===t.widgetId)return void e.shell.activateById(t.widgetId);a=n.next()}const s=(o=t.widgetId,l=t.label,c=t.Component,new class extends u.ReactWidget{constructor(){super(),this.id=o,this.title.label=l,this.title.closable=!0,this.addClass("jp-rag-admin-widget")}render(){return d().createElement(c,{onClose:()=>this.dispose()})}});var o,l,c;e.shell.add(s,"main")}}),n&&n.addItem({command:t.commandId,category:zr});t&&r().then(e=>{if(e)for(const e of Fr)t.add({command:e.commandId,category:zr,rank:e.rank})}),console.log("[RAGAdminPlugin] Activated")}};function Wr(e){e.closable||(e.closable=!0)}const Ur={id:"codebuff:launcher-closable",autoStart:!0,requires:[a.ILabShell],activate:(e,t)=>{const n=t.isEmpty.bind(t);t.isEmpty=e=>"main"!==e&&n(e);const a=new WeakSet,r=()=>{for(const e of t.widgets("main"))e.id.startsWith("launcher-")&&!a.has(e)&&(a.add(e),Wr(e.title),e.title.changed.connect(Wr))};t.layoutModified.connect(r),r()}};var Hr=n(1907);const Jr="codebuff:navigate-file";function Vr(e,t){const n=e.toLowerCase(),a=t.toLowerCase(),r=[];let s=0;for(let e=0;e<a.length&&s<n.length;e++)a[e]===n[s]&&(r.push(e),s++);return s===n.length?r:[]}const Gr={id:"codebuff:navigate-file",autoStart:!0,optional:[r.ICommandPalette],activate:(e,t)=>{e.commands.addCommand(Jr,{label:"파일 찾아 열기 (Navigate File)",execute:()=>function(e){if(document.querySelector(".jp-codebuff-navigate"))return;const t=document.createElement("div");t.className="jp-codebuff-navigate-backdrop";const n=document.createElement("div");n.className="jp-codebuff-navigate";const a=document.createElement("input");a.className="jp-codebuff-navigate-input",a.placeholder="파일 이름 (예: ACT → AppConfigTests.java, restservice/App)",a.spellcheck=!1;const r=document.createElement("ul");r.className="jp-codebuff-navigate-list",n.append(a,r),t.appendChild(n),document.body.appendChild(t),a.focus();let s,o=[],l=0,i=0;const d=()=>{window.clearTimeout(s),t.remove()},u=t=>{const n=o[t];n&&(d(),e.commands.execute("docmanager:open",{path:n.path}))},m=()=>{r.replaceChildren(),o.forEach((e,t)=>{const n=document.createElement("li");n.className="jp-codebuff-navigate-item"+(t===l?" jp-mod-selected":"");const s=e.path.lastIndexOf("/");n.appendChild(function(e,t){const n=document.createElement("span");n.className="jp-codebuff-navigate-name";const a=new Set(Vr(t.split("/").pop()||"",e));for(let t=0;t<e.length;t++)if(a.has(t)){const a=document.createElement("b");a.textContent=e[t],n.appendChild(a)}else n.appendChild(document.createTextNode(e[t]));return n}(e.path.slice(s+1),a.value.trim()));const o=document.createElement("span");o.className="jp-codebuff-navigate-dir",o.textContent=s>=0?e.path.slice(0,s):"",n.appendChild(o),n.addEventListener("mousedown",e=>{e.preventDefault(),u(t)}),r.appendChild(n)}),r.children[l]?.scrollIntoView({block:"nearest"})};a.addEventListener("input",()=>{window.clearTimeout(s),s=window.setTimeout(async()=>{const e=++i,t=await async function(e){const t=Hr.ServerConnection.makeSettings(),n=c.URLExt.join(t.baseUrl,"codebuff","files","navigate")+"?q="+encodeURIComponent(e),a=await Hr.ServerConnection.makeRequest(n,{},t);return a.ok&&(await a.json()).files||[]}(a.value.trim());e===i&&(o=t,l=0,m())},80)}),a.addEventListener("keydown",e=>{"ArrowDown"===e.key||"ArrowUp"===e.key?(e.preventDefault(),o.length&&(l=(l+("ArrowDown"===e.key?1:-1)+o.length)%o.length,m())):"Enter"===e.key?(e.preventDefault(),u(l)):"Escape"===e.key&&(e.preventDefault(),d()),e.stopPropagation()}),t.addEventListener("mousedown",e=>{e.target===t&&d()})}(e)}),e.commands.addKeyBinding({command:Jr,keys:["Accel Shift O"],selector:"body"}),t?.addItem({command:Jr,category:"Codebuff"});let n=0;document.addEventListener("keydown",t=>{const a=function(e,t,n){return"Shift"!==t.key||t.ctrlKey||t.metaKey||t.altKey?{last:0,fire:!1}:t.repeat?{last:e,fire:!1}:e&&n-e<=400?{last:0,fire:!0}:{last:n,fire:!1}}(n,t,Date.now());n=a.last,a.fire&&e.commands.execute(Jr)},!0)}};var Xr=n(8454),Zr=n(5705),Kr=n(6580);const Qr={java:"java",py:"python",ts:"typescript",tsx:"typescript",mts:"typescript",cts:"typescript",js:"javascript",jsx:"javascript",mjs:"javascript",cjs:"javascript",md:"markdown",markdown:"markdown"};function Yr(e){const t=e.slice(e.lastIndexOf(".")+1).toLowerCase();return Qr[t]??null}const es={ClassDeclaration:"class",InterfaceDeclaration:"interface",EnumDeclaration:"enum"};function ts(e,t,n){for(let a=e.firstChild;a;a=a.nextSibling){const e=es[a.name];if(e){n(a.getChild("Definition"),e,t);const r=a.getChild("ClassBody")||a.getChild("InterfaceBody")||a.getChild("EnumBody");r&&ts(r,t+1,n)}else if("MethodDeclaration"===a.name||"ConstructorDeclaration"===a.name)n(a.getChild("Definition"),"method",t,a.getChild("FormalParameters"));else if("FieldDeclaration"===a.name)for(const e of a.getChildren("VariableDeclarator"))n(e.getChild("Definition"),"field",t);else"EnumBodyDeclarations"===a.name&&ts(a,t,n)}}function ns(e,t,n,a){for(let r=e.firstChild;r;r=r.nextSibling)if("DecoratedStatement"===r.name)ns(r,t,n,a);else if("ClassDefinition"===r.name){a(r.getChild("VariableName"),"class",t);const e=r.getChild("Body");e&&ns(e,t+1,!0,a)}else"FunctionDefinition"===r.name&&a(r.getChild("VariableName"),n?"method":"function",t,r.getChild("ParamList"))}const as={InterfaceDeclaration:"interface",TypeAliasDeclaration:"type",EnumDeclaration:"enum"};function rs(e,t,n){for(let a=e.firstChild;a;a=a.nextSibling){const e=as[a.name];if(e)n(a.getChild("TypeDefinition"),e,t);else if("ExportDeclaration"===a.name)rs(a,t,n);else if("ClassDeclaration"===a.name){n(a.getChild("VariableDefinition"),"class",t);const e=a.getChild("ClassBody");e&&rs(e,t+1,n)}else if("FunctionDeclaration"===a.name)n(a.getChild("VariableDefinition"),"function",t,a.getChild("ParamList"));else if("MethodDeclaration"===a.name)n(a.getChild("PropertyDefinition"),"method",t,a.getChild("ParamList"));else if("PropertyDeclaration"===a.name)n(a.getChild("PropertyDefinition"),"field",t);else if("VariableDeclaration"===a.name){const e=a.getChild("ArrowFunction")||a.getChild("FunctionExpression");e&&n(a.getChild("VariableDefinition"),"function",t,e.getChild("ParamList"))}}}function ss(e,t){if(!t)return[];if("markdown"===t)return function(e){const t=[];let n=null;return e.split("\n").forEach((e,a)=>{const r=e.match(/^\s{0,3}(`{3,}|~{3,})/);if(r)return void(n?r[1][0]===n[0]&&r[1].length>=n.length&&(n=null):n=r[1]);const s=!n&&e.match(/^\s{0,3}(#{1,6})\s+(.+?)\s*#*\s*$/);s&&t.push({name:s[2],kind:"heading",line:a,depth:s[1].length-1})}),t}(e);const n=[0];for(let t=0;t<e.length;t++)"\n"===e[t]&&n.push(t+1);const a=e=>{let t=0,a=n.length-1;for(;t<a;){const r=t+a+1>>1;n[r]<=e?t=r:a=r-1}return t},r=[],s=(t,n,s,o)=>{if(!t)return;const l={name:e.slice(t.from,t.to),kind:n,line:a(t.from),depth:s};o&&(l.detail=e.slice(o.from,o.to).replace(/\s+/g," ")),r.push(l)};if("java"===t)ts(Xr.parser.parse(e).topNode,0,s);else if("python"===t)ns(Kr.parser.parse(e).topNode,0,!1,s);else{const n="typescript"===t?"ts jsx":"jsx";rs(Zr.parser.configure({dialect:n}).parse(e).topNode,0,s)}return r}function os(e,t="python"){const n=[];return e.forEach((e,a)=>{const r="markdown"===e.type?"markdown":"code"===e.type?t:null;for(const t of ss(e.source,r))n.push({...t,cell:a})}),n}const ls="codebuff:file-structure",cs={class:"C",interface:"I",enum:"E",type:"T",method:"m",function:"f",field:"f",heading:"#"};function is(e){const t=e.model?.getMetadata("language_info"),n=(t?.name||"python").toLowerCase();return"java"===n||"javascript"===n||"typescript"===n||"python"===n?n:null}const ds={id:"codebuff:file-structure",autoStart:!0,optional:[r.ICommandPalette],activate:(e,t)=>{e.commands.addCommand(ls,{label:"파일 구조 (File Structure)",execute:()=>function(e){if(document.querySelector(".jp-codebuff-navigate"))return;const t=function(e){const t=e.shell.currentWidget;if(t instanceof s.NotebookPanel){const e=t.content;return{items:os(e.widgets.map(e=>({type:e.model.type,source:e.model.sharedModel.getSource()})),is(t)),go:async t=>{const n=t.cell??0;e.activeCellIndex=n,await e.scrollToItem(n,"center");const a=e.widgets[n];if(await a.ready,"markdown"===a.model.type)return void e.activate();e.mode="edit";const r={line:t.line,column:0};a.editor?.setCursorPosition(r),a.editor?.revealPosition(r),a.editor?.focus()}}}const n=t?.content?.editor,a=t?.context?.path;return n&&a?{items:ss(n.model.sharedModel.getSource(),Yr(a)),go:e=>{const t={line:e.line,column:0};n.setCursorPosition(t),n.revealPosition(t),n.focus()}}:null}(e);if(!t)return;const n=document.createElement("div");n.className="jp-codebuff-navigate-backdrop";const a=document.createElement("div");a.className="jp-codebuff-navigate jp-codebuff-structure";const r=document.createElement("input");r.className="jp-codebuff-navigate-input",r.placeholder=t.items.length?"이름 일부 (예: gA → getAppConfig)":"이 파일에서 찾은 구조가 없습니다",r.spellcheck=!1;const o=document.createElement("ul");o.className="jp-codebuff-navigate-list",a.append(r,o),n.appendChild(a),document.body.appendChild(n),r.focus();let l=t.items,c=0;const i=()=>n.remove(),d=e=>{const n=l[e];n&&(i(),t.go(n))},u=()=>{const e=r.value.trim();o.replaceChildren(),l.forEach((t,n)=>{const a=function(e,t){const n=document.createElement("li");n.className="jp-codebuff-navigate-item jp-codebuff-structure-item",n.style.paddingLeft=10+16*e.depth+"px";const a=document.createElement("span");a.className=`jp-codebuff-structure-badge jp-codebuff-structure-${e.kind}`,a.textContent=cs[e.kind];const r=document.createElement("span");r.className="jp-codebuff-navigate-name";const s=new Set(Vr(t,e.name));for(let t=0;t<e.name.length;t++)if(s.has(t)){const n=document.createElement("b");n.textContent=e.name[t],r.appendChild(n)}else r.appendChild(document.createTextNode(e.name[t]));if(n.append(a,r),e.detail){const t=document.createElement("span");t.className="jp-codebuff-navigate-dir",t.textContent=e.detail,n.appendChild(t)}return n}(t,e);n===c&&a.classList.add("jp-mod-selected"),a.addEventListener("mousedown",e=>{e.preventDefault(),d(n)}),o.appendChild(a)}),o.children[c]?.scrollIntoView({block:"nearest"})};r.addEventListener("input",()=>{const e=r.value.trim();l=e?t.items.filter(t=>Vr(e,t.name).length):t.items,c=0,u()}),r.addEventListener("keydown",e=>{"ArrowDown"===e.key||"ArrowUp"===e.key?(e.preventDefault(),l.length&&(c=(c+("ArrowDown"===e.key?1:-1)+l.length)%l.length,u())):"Enter"===e.key?(e.preventDefault(),d(c)):"Escape"===e.key&&(e.preventDefault(),i()),e.stopPropagation()}),n.addEventListener("mousedown",e=>{e.target===n&&i()}),u()}(e)}),e.commands.addKeyBinding({command:ls,keys:["Ctrl F12"],selector:"body"}),t?.addItem({command:ls,category:"Codebuff"})}};var us=n(2780);const ms="codebuff:git-history-diff";let ps=0;function hs(e,t="",n=""){const a=document.createElement(e);return t&&(a.className=t),n&&(a.textContent=n),a}function gs(e){const t=e=>String(e).padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}`}function fs(e,t){return-new Date(`${e}T${t?"23:59:59":"00:00:00"}`).getTimezoneOffset()}class bs extends Hn.Widget{constructor(e){super(),this.path=e,this.api=new hn,this.since=hs("input"),this.until=hs("input"),this.rows=hs("tbody"),this.status=hs("div","jp-codebuff-git-history-status"),this.target=hs("div","jp-codebuff-git-history-target"),this.view=hs("div","jp-codebuff-git-history-view"),this.group="codebuff-git-history-"+ ++ps,this.commits=[],this.seq=0,this.addClass("jp-codebuff-git-history"),this.status.setAttribute("role","status"),this.node.append(this.buildDates(),this.buildCommits(),this.status,this.target,this.view),this.load()}buildDates(){const e=hs("div","jp-codebuff-git-history-dates"),t=new Date,n=new Date(t.getTime()-2592e6);for(const[a,r,s]of[[this.since,"시작일",gs(n)],[this.until,"종료일",gs(t)]]){a.type="date",a.value=s,a.setAttribute("aria-label",r);const t=hs("label","jp-codebuff-git-history-date",r);t.appendChild(a),e.appendChild(t)}const a=hs("button","jp-mod-styled jp-codebuff-git-history-dates-go","기간 비교");return a.type="button",a.addEventListener("click",()=>{this.compareDates()}),e.appendChild(a),e}buildCommits(){const e=hs("div","jp-codebuff-git-history-commits"),t=hs("table"),n=hs("tr");for(const e of["기준","비교","커밋"])n.appendChild(hs("th","",e));t.append(hs("thead"),this.rows),t.tHead.appendChild(n);const a=hs("button","jp-mod-styled jp-codebuff-git-history-commits-go","커밋 비교");return a.type="button",a.addEventListener("click",()=>{this.compareCommits()}),e.append(t,a),e}radio(e,t,n){const a=hs("td"),r=hs("input");return r.type="radio",r.name=`${this.group}-${e}`,r.value=t.sha,r.checked=n,r.setAttribute("aria-label",`${"from"===e?"기준":"비교"}: ${pn(t)}`),a.appendChild(r),a}picked(e){const t=this.node.querySelector(`input[name="${this.group}-${e}"]:checked`);return t?.value}async load(){let e;this.status.textContent="git 이력을 읽는 중…";try{e=await this.api.gitFileLog(this.path)}catch(e){return void(this.status.textContent=`git 이력을 읽지 못했습니다: ${e instanceof Error?e.message:e}`)}if(!e.success)return void(this.status.textContent=e.error||"git 이력을 읽지 못했습니다.");if(this.commits=e.commits,!this.commits.length)return void(this.status.textContent="이 파일의 git 이력이 없습니다 (커밋된 적이 없는 파일).");const t=(n=this.commits,{to:n[0]?.sha,from:n[1]?.sha});var n;for(const e of this.commits){const n=hs("tr");n.append(this.radio("from",e,e.sha===t.from),this.radio("to",e,e.sha===t.to),hs("td","jp-codebuff-git-history-label",pn(e))),n.title=`${e.author} · ${e.date}`,this.rows.appendChild(n)}await this.showDiff(this.api.gitFileDiff({path:this.path,from:t.from,to:t.to}))}async compareCommits(){const e=this.picked("to");e?await this.showDiff(this.api.gitFileDiff({path:this.path,from:this.picked("from"),to:e})):this.status.textContent="비교할 커밋을 고르세요."}async compareDates(){const e=(t=this.since.value,n=this.until.value,un.test(t)&&un.test(n)?t>n?"시작일이 종료일보다 늦습니다.":null:"시작일과 종료일을 모두 고르세요.");var t,n;e?this.status.textContent=e:await this.showDiff(this.api.gitFileDiff({path:this.path,since:mn(this.since.value,!1,fs(this.since.value,!1)),until:mn(this.until.value,!0,fs(this.until.value,!0))}))}async showDiff(e){const t=++this.seq;let n;this.status.textContent="diff 를 만드는 중…";try{n=await e}catch(e){n={success:!1,diff:"",error:`diff 를 만들지 못했습니다: ${e instanceof Error?e.message:e}`}}if(t!==this.seq)return;if(!n.success)return this.status.textContent=n.error||"diff 를 만들지 못했습니다.",this.target.textContent="",void(this.view.innerHTML="");const a=n.from?pn(n.from):"(파일 생성 전)";this.target.textContent=n.to?`기준 ${a} → 비교 ${pn(n.to)}`:"";const r=[n.message,n.cut?"diff 가 길어 앞부분만 보입니다.":""].filter(Boolean);this.status.textContent=r.join(" "),Be(),this.view.innerHTML=n.diff?qe($e(n.diff,this.path),{layout:ze(),highlight:ce}):""}}const vs={id:"codebuff:git-history",description:"파일 우클릭으로 그 파일의 git 이력 diff 를 메인 영역 탭에 연다 (이슈 #153)",autoStart:!0,requires:[us.IDefaultFileBrowser],activate:(e,t)=>{const n=()=>Array.from(t.selectedItems());e.commands.addCommand(ms,{label:"git 이력 diff",caption:"이 파일의 git 이력에서 두 시점을 골라 비교합니다",isEnabled:()=>{const e=n();return 1===e.length&&"directory"!==e[0].type},execute:()=>{const[t]=n();t&&"directory"!==t.type&&function(e,t){const n="codebuff-git-history:"+t;for(const t of e.shell.widgets("main"))if(t.id===n)return void e.shell.activateById(n);const a=new r.MainAreaWidget({content:new bs(t)});a.id=n,a.title.label=`${t.split("/").pop()} — git 이력`,a.title.caption=t,a.title.closable=!0,e.shell.add(a,"main",{activate:!0})}(e,t.path)}}),e.contextMenu.addItem({command:ms,selector:'.jp-DirListing-item[data-isdir="false"]',rank:14.5})}};var ys=n(277),Es=n(6822),ks=n(2576);function ws(e,t,n){return e.anchor>e.head?ks.EditorSelection.range(n,t):ks.EditorSelection.range(t,n)}function xs(e,t){return e.from<=t.from&&e.to>=t.to&&(e.from<t.from||e.to>t.to)}class Ss{constructor(){this.histories=new WeakMap}extend(e){const t=e.state;let n=this.histories.get(e);n&&n.doc===t.doc&&n.expected.eq(t.selection)||(n={doc:t.doc,expected:t.selection,stack:[]},this.histories.set(e,n));const a=function(e){const t=e.selection.ranges.map(t=>function(e,t){const n=[],a=e.wordAt(t.empty?t.head:t.from);a&&n.push(a);const r=function(e,t){let n=null;return(0,Es.selectParentSyntax)({state:e.update({selection:ks.EditorSelection.create([t])}).state,dispatch:e=>{n=e.state.selection.main}}),n}(e,t);r&&n.push(r),n.push({from:e.doc.lineAt(t.from).from,to:e.doc.lineAt(t.to).to}),n.push({from:0,to:e.doc.length});let s=null;for(const{from:e,to:a}of n){const n=ws(t,e,a);xs(n,t)&&(!s||n.to-n.from<s.to-s.from)&&(s=n)}return s??t}(e,t));return ks.EditorSelection.create(t,e.selection.mainIndex)}(t);return!a.eq(t.selection)&&(n.stack.push(t.selection),e.dispatch(t.update({selection:a,scrollIntoView:!0})),n.doc=e.state.doc,n.expected=e.state.selection,!0)}shrink(e){const t=e.state,n=this.histories.get(e);if(!n||n.doc!==t.doc||!n.expected.eq(t.selection)||0===n.stack.length)return this.histories.delete(e),!1;const a=n.stack.pop();return e.dispatch(t.update({selection:a,scrollIntoView:!0})),n.doc=e.state.doc,n.expected=e.state.selection,!0}}const _s="codebuff:extend-selection",Cs="codebuff:shrink-selection";function Ns(e){const t=e?.editor;return t?.state&&"function"==typeof t.dispatch?t:null}let js=null;function $s(e){const t=e.shell.currentWidget;if(t instanceof s.NotebookPanel){const e=t.content.activeCell;if(!e||e instanceof ys.MarkdownCell&&e.rendered)return null;const n=Ns(e.editor);return"edit"===t.content.mode||n&&js&&n.dom.contains(js)?n:null}return Ns(t?.content?.editor)}const Ts={id:"codebuff:extended-selection",autoStart:!0,optional:[r.ICommandPalette],activate:(e,t)=>{const n=new Ss;document.addEventListener("focusin",e=>{const t=e.target;t?.closest?.(".lm-CommandPalette, .jp-ModalCommandPalette")||(js=t)},!0);const a=t=>{const a=$s(e);return!(!a||!n[t](a)||(a.focus(),0))};e.commands.addCommand(_s,{label:"선택 확대 (Extend Selection)",isEnabled:()=>null!==$s(e),execute:()=>a("extend")}),e.commands.addCommand(Cs,{label:"선택 축소 (Shrink Selection)",isEnabled:()=>null!==$s(e),execute:()=>a("shrink")}),e.commands.addKeyBinding({command:_s,keys:["Ctrl Alt W"],selector:".jp-CodeMirrorEditor"}),e.commands.addKeyBinding({command:Cs,keys:["Ctrl Alt Shift W"],selector:".jp-CodeMirrorEditor"}),t?.addItem({command:_s,category:"Codebuff"}),t?.addItem({command:Cs,category:"Codebuff"})}},As=[yn,wn,ir,Ha,Ja.q,Ya,rr,Br,Ur,Gr,ds,vs,Ts]},6379(e,t,n){n.d(t,{collectAllCodeCells:()=>i});var a=n(8389),r=n(9827),s=n(2722),o=n(3959);function l(e){try{const t=e?.content;if(!t?.widgets)return;let n=0,a=0,r=0,l=0,c=0,i=0;for(let e=0;e<t.widgets.length;e++){const s=t.widgets[e];if(!s?.model)continue;const d=s.model.type,u=(0,o.gt)(s.model.metadata);"code"===d?(n++,"created"===u?a++:"modified"===u?r++:"pasted"===u&&l++):"markdown"===d&&(c++,u&&i++)}if(0===n)return;const d=Math.round((a+r+l)/n*1e4)/100;s.c.getInstance().trackImpression("cell_attribution",{total_code_cells:n,agent_created_code_cells:a,agent_modified_code_cells:r,agent_pasted_code_cells:l,agent_code_ratio_pct:d,total_markdown_cells:c,agent_markdown_cells:i})}catch{}}const c={id:"codebuff:save-interceptor",autoStart:!0,requires:[a.INotebookTracker],optional:[r.ICommandPalette],activate:(e,t,n)=>{console.log("[SaveInterceptorPlugin] Activated");let a=!1,r=null;if(e.commands.hasCommand("docmanager:save")){console.log("[SaveInterceptorPlugin] Found docmanager:save command");const t="docmanager:save",n=e.commands._commands.get(t);n?(r=n.execute.bind(n),console.log("[SaveInterceptorPlugin] Stored original save command"),n.execute=async t=>{const n=e.shell.currentWidget;if(console.log("[SaveInterceptorPlugin] Save command triggered",{hasCurrentWidget:!!n,isSaving:a,widgetType:n?.constructor?.name}),!n)return console.log("[SaveInterceptorPlugin] No current widget, allowing default save"),r(t);const o=n.context;if(!o)return console.log("[SaveInterceptorPlugin] No context, allowing default save"),r(t);const c=o?.path||"";if(!c.endsWith(".ipynb")&&!c.endsWith(".py"))return console.log("[SaveInterceptorPlugin] Not a Python file, allowing default save",{path:c}),r(t);if(a)return console.log("[SaveInterceptorPlugin] Already in save process, executing actual save"),r(t);console.log("[SaveInterceptorPlugin] Python file save, showing dialog",{path:c}),l(n),a=!0;try{await async function(e,t,n,r,o,l){const c=await new Promise(e=>{const t=document.querySelector(".jp-agent-save-confirm-modal");t&&t.remove();const n=document.createElement("div");n.className="jp-agent-save-confirm-modal",n.style.cssText="\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.3);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n ";const a=document.createElement("div");a.style.cssText="\n background: var(--jp-layout-color1);\n border: 1px solid var(--jp-border-color1);\n border-radius: 4px;\n padding: 24px;\n max-width: 400px;\n width: 90%;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n font-family: var(--jp-ui-font-family);\n ",a.innerHTML='\n <div style="margin-bottom: 20px;">\n <h3 style="margin: 0 0 12px 0; color: var(--jp-ui-font-color1); font-size: 16px; font-weight: 500;">\n 저장 또는 코드리뷰를 선택하세요\n </h3>\n <p style="margin: 0; color: var(--jp-ui-font-color2); font-size: 14px; line-height: 1.5;">\n 코드리뷰는 모든 셀의 코드와 출력을 분석합니다.\n </p>\n </div>\n <div style="display: flex; gap: 12px; justify-content: flex-end;">\n <button class="jp-agent-save-cancel-btn" style="\n background: transparent;\n color: var(--jp-ui-font-color2);\n border: 1px solid var(--jp-border-color2);\n border-radius: 3px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n ">취소</button>\n <button class="jp-agent-save-direct-btn" style="\n background: transparent;\n color: var(--jp-ui-font-color1);\n border: 1px solid var(--jp-border-color2);\n border-radius: 3px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n ">저장</button>\n <button class="jp-agent-save-analysis-btn" style="\n background: var(--jp-brand-color1);\n color: white;\n border: 1px solid var(--jp-brand-color1);\n border-radius: 3px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n ">코드리뷰</button>\n </div>\n ',n.appendChild(a),document.body.appendChild(n),s.c.getInstance().trackImpression("save_review_modal");const r=a.querySelector(".jp-agent-save-cancel-btn"),o=a.querySelector(".jp-agent-save-direct-btn"),l=a.querySelector(".jp-agent-save-analysis-btn");r.addEventListener("click",()=>{console.log("[SaveInterceptorPlugin] User cancelled save"),s.c.getInstance().trackClick("save_cancel"),n.remove(),e(null)}),r.addEventListener("mouseenter",()=>{r.style.background="var(--jp-layout-color2)"}),r.addEventListener("mouseleave",()=>{r.style.background="transparent"}),o.addEventListener("click",()=>{console.log("[SaveInterceptorPlugin] User chose direct save"),s.c.getInstance().trackClick("save_direct"),n.remove(),e(!1)}),o.addEventListener("mouseenter",()=>{o.style.background="var(--jp-layout-color2)"}),o.addEventListener("mouseleave",()=>{o.style.background="transparent"}),l.addEventListener("click",()=>{console.log("[SaveInterceptorPlugin] User chose analysis save"),s.c.getInstance().trackClick("save_review"),n.remove(),e(!0)}),l.addEventListener("mouseenter",()=>{l.style.opacity="0.9"}),l.addEventListener("mouseleave",()=>{l.style.opacity="1"}),n.addEventListener("click",t=>{t.target===n&&(console.log("[SaveInterceptorPlugin] User cancelled save"),n.remove(),e(null))});const c=t=>{"Escape"===t.key&&(console.log("[SaveInterceptorPlugin] User cancelled save with ESC"),n.remove(),document.removeEventListener("keydown",c),e(null))};document.addEventListener("keydown",c)});null!==c?c?await async function(e,t){console.log("[SaveInterceptorPlugin] Performing code review");try{const n=window._codebuffAgentPanel;if(!n)return void console.error("[SaveInterceptorPlugin] Agent panel not available");t&&t.shell.activateById(n.id);const a=e?.context?.path||"";if(a.endsWith(".ipynb")){if(!n.analyzeNotebook)return void console.error("[SaveInterceptorPlugin] analyzeNotebook not available");const r=t?.serviceManager?.serverSettings,s=await i(e,r,a);if(0===s.length)return void console.log("[SaveInterceptorPlugin] No code cells to analyze");n.analyzeNotebook(s,()=>{console.log("[SaveInterceptorPlugin] Code review complete")})}else{if(!n.analyzeFile)return void console.error("[SaveInterceptorPlugin] analyzeFile not available");n.analyzeFile(a,()=>{console.log("[SaveInterceptorPlugin] File review complete")})}}catch(e){console.error("[SaveInterceptorPlugin] Code review failed:",e)}}(e,t):await async function(e,t,n,a,r,s){console.log("[SaveInterceptorPlugin] Performing direct save"),r();try{if(n)await n(a);else{const t=e.context;t&&await t.save()}}catch(e){console.error("[SaveInterceptorPlugin] Save failed:",e),function(e,t="info"){const n=function(e,t){const n=document.createElement("div");return n.style.cssText=`\n position: fixed;\n top: 20px;\n right: 20px;\n padding: 12px 20px;\n border-radius: 8px;\n color: white;\n font-size: 14px;\n font-weight: 500;\n z-index: 10001;\n opacity: 0;\n transition: opacity 0.3s ease;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n max-width: 300px;\n word-wrap: break-word;\n background: ${t};\n `,n.textContent=e,n}("저장에 실패했습니다.",function(e){const t={success:"#48bb78",error:"#f56565",warning:"#ed8936",info:"#4299e1"};return t[e]||t.info}(t));document.body.appendChild(n),function(e){setTimeout(()=>{e.style.opacity="1"},10),setTimeout(()=>{e.style.opacity="0",setTimeout(()=>{e.parentNode&&e.parentNode.removeChild(e)},300)},3e3)}(n)}(0,"error")}finally{s()}}(e,0,n,r,()=>{a=!0},l):l()}(n,e,r,t,0,()=>{a=!1})}finally{a=!1}},console.log("[SaveInterceptorPlugin] Wrapped save command installed")):console.error("[SaveInterceptorPlugin] Could not find original save command")}document.addEventListener("keydown",async t=>{if((t.ctrlKey||t.metaKey)&&"s"===t.key){const n=e.shell.currentWidget;if(!n)return;const s=n.context;if(!s)return;const o=s?.path||"";if(!o.endsWith(".ipynb")&&!o.endsWith(".py"))return void console.log("[SaveInterceptorPlugin] Not a Python file, allowing default save",{path:o});if(console.log("[SaveInterceptorPlugin] Save shortcut (Ctrl/Cmd+S) detected for Python file",{path:o}),t.preventDefault(),t.stopPropagation(),a)return void console.log("[SaveInterceptorPlugin] Already saving, ignoring duplicate request");if(!r)return void console.error("[SaveInterceptorPlugin] No original save command stored");l(n),await r()}},!0),console.log("[SaveInterceptorPlugin] Save interception enabled")}};async function i(e,t,n){const a=e.content,r=[];for(let e=0;e<a.widgets.length;e++){const t=a.widgets[e];if(!t?.model||"code"!==t.model.type)continue;const n=t.model.sharedModel?.getSource()||"";if(!n.trim())continue;const s=d(t),o=u(t),l=m(n);r.push({index:e,id:s,content:n,type:"code",output:o,imports:l})}if(console.log(`[SaveInterceptorPlugin] Collected ${r.length} code cells`),t&&r.length>0)try{const e=`${t.baseUrl}codebuff/notebook/enrich`,a={"Content-Type":"application/json"};t.token&&(a.Authorization=`token ${t.token}`);const s=document.cookie.split("; ").find(e=>e.startsWith("_xsrf="));s&&(a["X-XSRFToken"]=s.split("=")[1]);const o=await fetch(e,{method:"POST",headers:a,body:JSON.stringify({notebookPath:n||"",cells:r.map(e=>({index:e.index,content:e.content}))})});if(o.ok){const e=await o.json();for(const t of e.cells||[]){const e=r.find(e=>e.index===t.index);e&&(t.localModuleSources&&Object.keys(t.localModuleSources).length>0&&(e.localModuleSources=t.localModuleSources),t.dependencies&&(e.dependencies=t.dependencies))}r._crossCellDeps=e.crossCellDependencies||[],r._moduleSummary=e.moduleSummary||{},r._transitiveModuleSources=e.transitiveModuleSources||{}}}catch(e){console.warn("[SaveInterceptorPlugin] Enrich API failed, continuing without enrichment:",e)}return r}function d(e){const t=e.model;let n;try{t.metadata&&"function"==typeof t.metadata.get?n=t.metadata.get("jupyterAgentCellId"):t.metadata?.jupyterAgentCellId&&(n=t.metadata.jupyterAgentCellId)}catch(e){}if(!n){n=`cell-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;try{t.metadata&&"function"==typeof t.metadata.set?t.metadata.set("jupyterAgentCellId",n):t.metadata&&(t.metadata.jupyterAgentCellId=n)}catch(e){}}return n}function u(e){if(!e?.model||"code"!==e.model.type)return"";const t=e,n=t.model?.outputs;if(!n||0===n.length)return"";const a=[];for(let e=0;e<n.length;e++){const t=n.get(e),r=t.type;if("stream"===r){const e=t.text;Array.isArray(e)?a.push(e.join("")):a.push(e)}else if("execute_result"===r||"display_data"===r){const e=t.data;if(e["text/plain"]){const t=e["text/plain"];Array.isArray(t)?a.push(t.join("")):a.push(t)}}else if("error"===r){const e=t.traceback;Array.isArray(e)&&a.push(e.join("\n"))}}return a.join("\n")}function m(e){const t=[],n=e.split("\n");for(const e of n){const n=e.trim();if(n.startsWith("#")||""===n)continue;const a=n.match(/^from\s+(\.+[\w.]*)\s+import\s+([\w,\s*]+)/);if(a){t.push({module:a[1],items:a[2],isLocal:!0});continue}const r=n.match(/^from\s+([\w.]+)\s+import\s+([\w,\s*]+)/);if(r){const e=r[1];t.push({module:e,items:r[2],isLocal:p(e)});continue}const s=n.match(/^import\s+([\w,\s.]+)/);s&&s[1].split(",").map(e=>e.trim().split(" as ")[0]).forEach(e=>{t.push({module:e,items:e,isLocal:p(e)})})}return t}function p(e){if(e.startsWith("."))return!0;const t=e.split(".")[0];return!["numpy","np","pandas","pd","matplotlib","sklearn","scipy","torch","tensorflow","tf","keras","PIL","cv2","requests","json","os","sys","datetime","time","math","random","collections","itertools","functools","re","pathlib","typing","dataclasses","abc","argparse","logging","pickle","csv","sqlite3","http","urllib","email","plotly","seaborn","statsmodels","xgboost","lightgbm","transformers","datasets","accelerate","peft","openai","anthropic","langchain","llama_index"].includes(t)}n.d(t,["q",0,c])},2722(e,t,n){n.d(t,{c:()=>o});var a=n(7292);function r(){const e="undefined"!=typeof crypto?crypto:void 0;if(e&&"function"==typeof e.randomUUID)return e.randomUUID();const t=new Uint8Array(16);if(e&&"function"==typeof e.getRandomValues)e.getRandomValues(t);else for(let e=0;e<t.length;e++)t[e]=Math.floor(256*Math.random());t[6]=15&t[6]|64,t[8]=63&t[8]|128;const n=[];for(let e=0;e<t.length;e++)n.push(t[e].toString(16).padStart(2,"0"));return[n.slice(0,4).join(""),n.slice(4,6).join(""),n.slice(6,8).join(""),n.slice(8,10).join(""),n.slice(10,16).join("")].join("-")}const s="codebuff-analytics-session-id";class o{constructor(){this.buffer=[],this.timerId=null;const e=a.PageConfig.getBaseUrl();this.baseUrl=a.URLExt.join(e,"codebuff","analytics","events"),this.sessionId=this.getOrCreateSessionId(),this.version=a.PageConfig.getOption("CODEBUFF_EXTENSION_VERSION")||"",this.timerId=setInterval(()=>this.flush(),3e4),"undefined"!=typeof window&&window.addEventListener("beforeunload",()=>{this.enqueue("impression","session_end",{}),this.flushBeacon()}),this.enqueue("impression","session_start",{})}static getInstance(){return o.instance||(o.instance=new o),o.instance}trackImpression(e,t){try{this.enqueue("impression",e,t)}catch{}}static blockIdOf(e){let t=2166136261;const n=e.trim();for(let e=0;e<n.length;e++)t^=n.charCodeAt(e),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}getSessionId(){return this.sessionId}trackClick(e,t){try{this.enqueue("click",e,t)}catch{}}trackError(e,t){try{this.enqueue("error",e,t)}catch{}}enqueue(e,t,n){const a={event_id:r(),session_id:this.sessionId,timestamp:Date.now(),event_type:e,feature:t,extension_version:this.version,...n?{context:n}:{}};this.buffer.push(a),this.buffer.length>=20&&this.flush()}flush(){if(0===this.buffer.length)return;const e=this.buffer.splice(0);fetch(this.baseUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}).catch(()=>{})}flushBeacon(){if(0===this.buffer.length)return;const e=this.buffer.splice(0),t=new Blob([JSON.stringify(e)],{type:"application/json"});navigator.sendBeacon(this.baseUrl,t)}getOrCreateSessionId(){try{let e=sessionStorage.getItem(s);return e||(e=r(),sessionStorage.setItem(s,e)),e}catch{return r()}}}o.instance=null},3959(e,t,n){function a(e,t){try{const n=localStorage.getItem(e);return null!==n?n:localStorage.getItem(t)}catch{return null}}function r(e,t){try{localStorage.removeItem(e),localStorage.removeItem(t)}catch{}}n.d(t,{GK:()=>a,gt:()=>o,kA:()=>r});const s="codebuff_source";function o(e){try{const t=t=>"function"==typeof e?.get?e.get(t):e?.[t];return t(s)??t("hdsp_agent_source")}catch{return}}n.d(t,["zi",0,s])}}]);