aiexecode 1.0.75 → 1.0.76

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.

Potentially problematic release.


This version of aiexecode might be problematic. Click here for more details.

package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiexecode",
3
- "version": "1.0.75",
3
+ "version": "1.0.76",
4
4
  "description": "A CLI-based AI Coding Agent",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1 +1 @@
1
- <!DOCTYPE html><!--jbur8fv1gX0ZHKro3t6lN--><html lang="ko" class="dark h-full"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/ecd2072ebf41611f.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/e411019f55d87c42.js"/><script src="/_next/static/chunks/103c802c8f4a5ea1.js" async=""></script><script src="/_next/static/chunks/305b077a9873cf54.js" async=""></script><script src="/_next/static/chunks/turbopack-0ac29803ce3c3c7a.js" async=""></script><script src="/_next/static/chunks/060f9a97930f3d04.js" async=""></script><script src="/_next/static/chunks/cdd12d5c1a5a6064.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>Payload Log Viewer</title><meta name="description" content="AI Agent 로그 파일 뷰어 및 편집기"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden"><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><div data-rht-toaster="" style="position:fixed;z-index:9999;top:16px;left:16px;right:16px;bottom:16px;pointer-events:none"></div><script src="/_next/static/chunks/e411019f55d87c42.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n4:I[5766,[\"/_next/static/chunks/cdd12d5c1a5a6064.js\"],\"Toaster\"]\n5:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"OutletBoundary\"]\n7:I[11533,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"AsyncMetadataOutlet\"]\n9:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"ViewportBoundary\"]\nb:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"MetadataBoundary\"]\nc:\"$Sreact.suspense\"\ne:I[68027,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n:HL[\"/_next/static/chunks/ecd2072ebf41611f.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"jbur8fv1gX0ZHKro3t6lN\",\"p\":\"\",\"c\":[\"\",\"_not-found\",\"\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/ecd2072ebf41611f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/cdd12d5c1a5a6064.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"ko\",\"className\":\"dark h-full\",\"children\":[\"$\",\"body\",null,{\"className\":\"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden\",\"children\":[[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L4\",null,{\"position\":\"bottom-right\",\"toastOptions\":{\"duration\":4000,\"style\":{\"background\":\"hsl(var(--background))\",\"color\":\"hsl(var(--foreground))\",\"border\":\"1px solid hsl(var(--border))\"}}}]]}]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L5\",null,{\"children\":[\"$L6\",[\"$\",\"$L7\",null,{\"promise\":\"$@8\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$c\",null,{\"fallback\":null,\"children\":\"$Ld\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$e\",\"$undefined\"],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n6:null\n"])</script><script>self.__next_f.push([1,"f:I[27201,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"IconMark\"]\n8:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Payload Log Viewer\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"AI Agent 로그 파일 뷰어 및 편집기\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Lf\",\"3\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"d:\"$8:metadata\"\n"])</script></body></html>
1
+ <!DOCTYPE html><!--Wnr9eYJaRUoC5a3SUgrBr--><html lang="ko" class="dark h-full"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/ecd2072ebf41611f.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/e411019f55d87c42.js"/><script src="/_next/static/chunks/103c802c8f4a5ea1.js" async=""></script><script src="/_next/static/chunks/305b077a9873cf54.js" async=""></script><script src="/_next/static/chunks/turbopack-0ac29803ce3c3c7a.js" async=""></script><script src="/_next/static/chunks/060f9a97930f3d04.js" async=""></script><script src="/_next/static/chunks/cdd12d5c1a5a6064.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>Payload Log Viewer</title><meta name="description" content="AI Agent 로그 파일 뷰어 및 편집기"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden"><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><div data-rht-toaster="" style="position:fixed;z-index:9999;top:16px;left:16px;right:16px;bottom:16px;pointer-events:none"></div><script src="/_next/static/chunks/e411019f55d87c42.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n4:I[5766,[\"/_next/static/chunks/cdd12d5c1a5a6064.js\"],\"Toaster\"]\n5:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"OutletBoundary\"]\n7:I[11533,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"AsyncMetadataOutlet\"]\n9:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"ViewportBoundary\"]\nb:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"MetadataBoundary\"]\nc:\"$Sreact.suspense\"\ne:I[68027,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n:HL[\"/_next/static/chunks/ecd2072ebf41611f.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"Wnr9eYJaRUoC5a3SUgrBr\",\"p\":\"\",\"c\":[\"\",\"_not-found\",\"\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/ecd2072ebf41611f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/cdd12d5c1a5a6064.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"ko\",\"className\":\"dark h-full\",\"children\":[\"$\",\"body\",null,{\"className\":\"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden\",\"children\":[[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L4\",null,{\"position\":\"bottom-right\",\"toastOptions\":{\"duration\":4000,\"style\":{\"background\":\"hsl(var(--background))\",\"color\":\"hsl(var(--foreground))\",\"border\":\"1px solid hsl(var(--border))\"}}}]]}]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L5\",null,{\"children\":[\"$L6\",[\"$\",\"$L7\",null,{\"promise\":\"$@8\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$c\",null,{\"fallback\":null,\"children\":\"$Ld\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$e\",\"$undefined\"],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n6:null\n"])</script><script>self.__next_f.push([1,"f:I[27201,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"IconMark\"]\n8:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Payload Log Viewer\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"AI Agent 로그 파일 뷰어 및 편집기\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Lf\",\"3\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"d:\"$8:metadata\"\n"])</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><!--jbur8fv1gX0ZHKro3t6lN--><html lang="ko" class="dark h-full"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/ecd2072ebf41611f.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/e411019f55d87c42.js"/><script src="/_next/static/chunks/103c802c8f4a5ea1.js" async=""></script><script src="/_next/static/chunks/305b077a9873cf54.js" async=""></script><script src="/_next/static/chunks/turbopack-0ac29803ce3c3c7a.js" async=""></script><script src="/_next/static/chunks/060f9a97930f3d04.js" async=""></script><script src="/_next/static/chunks/cdd12d5c1a5a6064.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>Payload Log Viewer</title><meta name="description" content="AI Agent 로그 파일 뷰어 및 편집기"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden"><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><div data-rht-toaster="" style="position:fixed;z-index:9999;top:16px;left:16px;right:16px;bottom:16px;pointer-events:none"></div><script src="/_next/static/chunks/e411019f55d87c42.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n4:I[5766,[\"/_next/static/chunks/cdd12d5c1a5a6064.js\"],\"Toaster\"]\n5:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"OutletBoundary\"]\n7:I[11533,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"AsyncMetadataOutlet\"]\n9:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"ViewportBoundary\"]\nb:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"MetadataBoundary\"]\nc:\"$Sreact.suspense\"\ne:I[68027,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n:HL[\"/_next/static/chunks/ecd2072ebf41611f.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"jbur8fv1gX0ZHKro3t6lN\",\"p\":\"\",\"c\":[\"\",\"_not-found\",\"\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/ecd2072ebf41611f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/cdd12d5c1a5a6064.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"ko\",\"className\":\"dark h-full\",\"children\":[\"$\",\"body\",null,{\"className\":\"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden\",\"children\":[[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L4\",null,{\"position\":\"bottom-right\",\"toastOptions\":{\"duration\":4000,\"style\":{\"background\":\"hsl(var(--background))\",\"color\":\"hsl(var(--foreground))\",\"border\":\"1px solid hsl(var(--border))\"}}}]]}]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L5\",null,{\"children\":[\"$L6\",[\"$\",\"$L7\",null,{\"promise\":\"$@8\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$c\",null,{\"fallback\":null,\"children\":\"$Ld\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$e\",\"$undefined\"],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n6:null\n"])</script><script>self.__next_f.push([1,"f:I[27201,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"IconMark\"]\n8:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Payload Log Viewer\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"AI Agent 로그 파일 뷰어 및 편집기\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Lf\",\"3\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"d:\"$8:metadata\"\n"])</script></body></html>
1
+ <!DOCTYPE html><!--Wnr9eYJaRUoC5a3SUgrBr--><html lang="ko" class="dark h-full"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/ecd2072ebf41611f.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/e411019f55d87c42.js"/><script src="/_next/static/chunks/103c802c8f4a5ea1.js" async=""></script><script src="/_next/static/chunks/305b077a9873cf54.js" async=""></script><script src="/_next/static/chunks/turbopack-0ac29803ce3c3c7a.js" async=""></script><script src="/_next/static/chunks/060f9a97930f3d04.js" async=""></script><script src="/_next/static/chunks/cdd12d5c1a5a6064.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>Payload Log Viewer</title><meta name="description" content="AI Agent 로그 파일 뷰어 및 편집기"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden"><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><div data-rht-toaster="" style="position:fixed;z-index:9999;top:16px;left:16px;right:16px;bottom:16px;pointer-events:none"></div><script src="/_next/static/chunks/e411019f55d87c42.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n4:I[5766,[\"/_next/static/chunks/cdd12d5c1a5a6064.js\"],\"Toaster\"]\n5:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"OutletBoundary\"]\n7:I[11533,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"AsyncMetadataOutlet\"]\n9:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"ViewportBoundary\"]\nb:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"MetadataBoundary\"]\nc:\"$Sreact.suspense\"\ne:I[68027,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n:HL[\"/_next/static/chunks/ecd2072ebf41611f.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"Wnr9eYJaRUoC5a3SUgrBr\",\"p\":\"\",\"c\":[\"\",\"_not-found\",\"\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/ecd2072ebf41611f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/cdd12d5c1a5a6064.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"ko\",\"className\":\"dark h-full\",\"children\":[\"$\",\"body\",null,{\"className\":\"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden\",\"children\":[[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L4\",null,{\"position\":\"bottom-right\",\"toastOptions\":{\"duration\":4000,\"style\":{\"background\":\"hsl(var(--background))\",\"color\":\"hsl(var(--foreground))\",\"border\":\"1px solid hsl(var(--border))\"}}}]]}]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:1:props:children:1:props:children:props:children:0:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L5\",null,{\"children\":[\"$L6\",[\"$\",\"$L7\",null,{\"promise\":\"$@8\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$c\",null,{\"fallback\":null,\"children\":\"$Ld\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$e\",\"$undefined\"],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n6:null\n"])</script><script>self.__next_f.push([1,"f:I[27201,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"IconMark\"]\n8:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Payload Log Viewer\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"AI Agent 로그 파일 뷰어 및 편집기\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Lf\",\"3\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"d:\"$8:metadata\"\n"])</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><!--jbur8fv1gX0ZHKro3t6lN--><html lang="ko" class="dark h-full"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/chunks/ecd2072ebf41611f.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/e411019f55d87c42.js"/><script src="/_next/static/chunks/103c802c8f4a5ea1.js" async=""></script><script src="/_next/static/chunks/305b077a9873cf54.js" async=""></script><script src="/_next/static/chunks/turbopack-0ac29803ce3c3c7a.js" async=""></script><script src="/_next/static/chunks/060f9a97930f3d04.js" async=""></script><script src="/_next/static/chunks/cdd12d5c1a5a6064.js" async=""></script><script src="/_next/static/chunks/f1ac9047ac4a3fde.js" async=""></script><script src="/_next/static/chunks/37d0cd2587a38f79.js" async=""></script><meta name="next-size-adjust" content=""/><title>Payload Log Viewer</title><meta name="description" content="AI Agent 로그 파일 뷰어 및 편집기"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden"><div hidden=""><!--$--><!--/$--></div><div class="h-screen bg-background flex"><div class="flex-shrink-0 w-80 border-r border-border bg-background flex flex-col"><div class="flex-shrink-0 border-b border-border p-4"><h2 class="text-lg font-semibold flex items-center gap-2"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text h-5 w-5" aria-hidden="true"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"></path><path d="M14 2v4a2 2 0 0 0 2 2h4"></path><path d="M10 9H8"></path><path d="M16 13H8"></path><path d="M16 17H8"></path></svg>로그 파일</h2><p class="text-sm text-muted-foreground">로딩 중...</p></div><div class="flex-1 min-h-0"><div dir="ltr" class="relative overflow-hidden h-full" style="position:relative;--radix-scroll-area-corner-width:0px;--radix-scroll-area-corner-height:0px"><style>[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}</style><div data-radix-scroll-area-viewport="" class="h-full w-full rounded-[inherit]" style="overflow-x:hidden;overflow-y:hidden"><div style="min-width:100%;display:table"><div class="p-4 text-center text-muted-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw h-6 w-6 animate-spin mx-auto mb-2" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg>로딩 중...</div></div></div></div></div></div><div class="flex-1 min-w-0"><div class="rounded-lg border bg-card text-card-foreground shadow-sm h-full"><div class="p-6 pt-0 flex items-center justify-center h-full"><div class="text-center text-muted-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-pen h-12 w-12 mx-auto mb-4 opacity-50" aria-hidden="true"><path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z"></path></svg><p class="text-lg">REQ 파일을 선택하세요</p><p class="text-sm">요청 파일을 선택하면 내용을 편집하고 재실행할 수 있습니다</p></div></div></div></div></div><!--$--><!--/$--><div data-rht-toaster="" style="position:fixed;z-index:9999;top:16px;left:16px;right:16px;bottom:16px;pointer-events:none"></div><script src="/_next/static/chunks/e411019f55d87c42.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n4:I[5766,[\"/_next/static/chunks/cdd12d5c1a5a6064.js\"],\"Toaster\"]\n5:I[47257,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"ClientPageRoot\"]\n6:I[31713,[\"/_next/static/chunks/cdd12d5c1a5a6064.js\",\"/_next/static/chunks/f1ac9047ac4a3fde.js\",\"/_next/static/chunks/37d0cd2587a38f79.js\"],\"default\"]\n9:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"OutletBoundary\"]\nb:I[11533,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"AsyncMetadataOutlet\"]\nd:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"ViewportBoundary\"]\nf:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"MetadataBoundary\"]\n10:\"$Sreact.suspense\"\n12:I[68027,[\"/_next/static/chunks/cdd12d5c1a5a6064.js\"],\"default\"]\n:HL[\"/_next/static/chunks/ecd2072ebf41611f.css\",\"style\"]\n:HL[\"/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"jbur8fv1gX0ZHKro3t6lN\",\"p\":\"\",\"c\":[\"\",\"\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/ecd2072ebf41611f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/cdd12d5c1a5a6064.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"ko\",\"className\":\"dark h-full\",\"children\":[\"$\",\"body\",null,{\"className\":\"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden\",\"children\":[[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L4\",null,{\"position\":\"bottom-right\",\"toastOptions\":{\"duration\":4000,\"style\":{\"background\":\"hsl(var(--background))\",\"color\":\"hsl(var(--foreground))\",\"border\":\"1px solid hsl(var(--border))\"}}}]]}]}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"$L5\",null,{\"Component\":\"$6\",\"searchParams\":{},\"params\":{},\"promises\":[\"$@7\",\"$@8\"]}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/f1ac9047ac4a3fde.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/37d0cd2587a38f79.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L9\",null,{\"children\":[\"$La\",[\"$\",\"$Lb\",null,{\"promise\":\"$@c\"}]]}]]}],{},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[[\"$\",\"$Ld\",null,{\"children\":\"$Le\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$Lf\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$10\",null,{\"fallback\":null,\"children\":\"$L11\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$12\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/ecd2072ebf41611f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"7:{}\n8:\"$0:f:0:1:2:children:1:props:children:0:props:params\"\n"])</script><script>self.__next_f.push([1,"e:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\na:null\n"])</script><script>self.__next_f.push([1,"13:I[27201,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"IconMark\"]\nc:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Payload Log Viewer\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"AI Agent 로그 파일 뷰어 및 편집기\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$L13\",\"3\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"11:\"$c:metadata\"\n"])</script></body></html>
1
+ <!DOCTYPE html><!--Wnr9eYJaRUoC5a3SUgrBr--><html lang="ko" class="dark h-full"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/chunks/ecd2072ebf41611f.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/e411019f55d87c42.js"/><script src="/_next/static/chunks/103c802c8f4a5ea1.js" async=""></script><script src="/_next/static/chunks/305b077a9873cf54.js" async=""></script><script src="/_next/static/chunks/turbopack-0ac29803ce3c3c7a.js" async=""></script><script src="/_next/static/chunks/060f9a97930f3d04.js" async=""></script><script src="/_next/static/chunks/cdd12d5c1a5a6064.js" async=""></script><script src="/_next/static/chunks/f1ac9047ac4a3fde.js" async=""></script><script src="/_next/static/chunks/37d0cd2587a38f79.js" async=""></script><meta name="next-size-adjust" content=""/><title>Payload Log Viewer</title><meta name="description" content="AI Agent 로그 파일 뷰어 및 편집기"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden"><div hidden=""><!--$--><!--/$--></div><div class="h-screen bg-background flex"><div class="flex-shrink-0 w-80 border-r border-border bg-background flex flex-col"><div class="flex-shrink-0 border-b border-border p-4"><h2 class="text-lg font-semibold flex items-center gap-2"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text h-5 w-5" aria-hidden="true"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"></path><path d="M14 2v4a2 2 0 0 0 2 2h4"></path><path d="M10 9H8"></path><path d="M16 13H8"></path><path d="M16 17H8"></path></svg>로그 파일</h2><p class="text-sm text-muted-foreground">로딩 중...</p></div><div class="flex-1 min-h-0"><div dir="ltr" class="relative overflow-hidden h-full" style="position:relative;--radix-scroll-area-corner-width:0px;--radix-scroll-area-corner-height:0px"><style>[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}</style><div data-radix-scroll-area-viewport="" class="h-full w-full rounded-[inherit]" style="overflow-x:hidden;overflow-y:hidden"><div style="min-width:100%;display:table"><div class="p-4 text-center text-muted-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw h-6 w-6 animate-spin mx-auto mb-2" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg>로딩 중...</div></div></div></div></div></div><div class="flex-1 min-w-0"><div class="rounded-lg border bg-card text-card-foreground shadow-sm h-full"><div class="p-6 pt-0 flex items-center justify-center h-full"><div class="text-center text-muted-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-pen h-12 w-12 mx-auto mb-4 opacity-50" aria-hidden="true"><path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z"></path></svg><p class="text-lg">REQ 파일을 선택하세요</p><p class="text-sm">요청 파일을 선택하면 내용을 편집하고 재실행할 수 있습니다</p></div></div></div></div></div><!--$--><!--/$--><div data-rht-toaster="" style="position:fixed;z-index:9999;top:16px;left:16px;right:16px;bottom:16px;pointer-events:none"></div><script src="/_next/static/chunks/e411019f55d87c42.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"default\"]\n4:I[5766,[\"/_next/static/chunks/cdd12d5c1a5a6064.js\"],\"Toaster\"]\n5:I[47257,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"ClientPageRoot\"]\n6:I[31713,[\"/_next/static/chunks/cdd12d5c1a5a6064.js\",\"/_next/static/chunks/f1ac9047ac4a3fde.js\",\"/_next/static/chunks/37d0cd2587a38f79.js\"],\"default\"]\n9:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"OutletBoundary\"]\nb:I[11533,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"AsyncMetadataOutlet\"]\nd:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"ViewportBoundary\"]\nf:I[97367,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"MetadataBoundary\"]\n10:\"$Sreact.suspense\"\n12:I[68027,[\"/_next/static/chunks/cdd12d5c1a5a6064.js\"],\"default\"]\n:HL[\"/_next/static/chunks/ecd2072ebf41611f.css\",\"style\"]\n:HL[\"/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"Wnr9eYJaRUoC5a3SUgrBr\",\"p\":\"\",\"c\":[\"\",\"\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/ecd2072ebf41611f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/cdd12d5c1a5a6064.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"ko\",\"className\":\"dark h-full\",\"children\":[\"$\",\"body\",null,{\"className\":\"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden\",\"children\":[[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L4\",null,{\"position\":\"bottom-right\",\"toastOptions\":{\"duration\":4000,\"style\":{\"background\":\"hsl(var(--background))\",\"color\":\"hsl(var(--foreground))\",\"border\":\"1px solid hsl(var(--border))\"}}}]]}]}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"$L5\",null,{\"Component\":\"$6\",\"searchParams\":{},\"params\":{},\"promises\":[\"$@7\",\"$@8\"]}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/f1ac9047ac4a3fde.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/37d0cd2587a38f79.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L9\",null,{\"children\":[\"$La\",[\"$\",\"$Lb\",null,{\"promise\":\"$@c\"}]]}]]}],{},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[[\"$\",\"$Ld\",null,{\"children\":\"$Le\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$Lf\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$10\",null,{\"fallback\":null,\"children\":\"$L11\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$12\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/ecd2072ebf41611f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"7:{}\n8:\"$0:f:0:1:2:children:1:props:children:0:props:params\"\n"])</script><script>self.__next_f.push([1,"e:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\na:null\n"])</script><script>self.__next_f.push([1,"13:I[27201,[\"/_next/static/chunks/060f9a97930f3d04.js\"],\"IconMark\"]\nc:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Payload Log Viewer\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"AI Agent 로그 파일 뷰어 및 편집기\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$L13\",\"3\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"11:\"$c:metadata\"\n"])</script></body></html>
@@ -13,7 +13,7 @@ f:I[97367,["/_next/static/chunks/060f9a97930f3d04.js"],"MetadataBoundary"]
13
13
  :HL["/_next/static/chunks/ecd2072ebf41611f.css","style"]
14
14
  :HL["/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
15
15
  :HL["/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
16
- 0:{"P":null,"b":"jbur8fv1gX0ZHKro3t6lN","p":"","c":["",""],"i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/ecd2072ebf41611f.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/cdd12d5c1a5a6064.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"ko","className":"dark h-full","children":["$","body",null,{"className":"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden","children":[["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}],["$","$L4",null,{"position":"bottom-right","toastOptions":{"duration":4000,"style":{"background":"hsl(var(--background))","color":"hsl(var(--foreground))","border":"1px solid hsl(var(--border))"}}}]]}]}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L5",null,{"Component":"$6","searchParams":{},"params":{},"promises":["$@7","$@8"]}],[["$","script","script-0",{"src":"/_next/static/chunks/f1ac9047ac4a3fde.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/37d0cd2587a38f79.js","async":true,"nonce":"$undefined"}]],["$","$L9",null,{"children":["$La",["$","$Lb",null,{"promise":"$@c"}]]}]]}],{},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Ld",null,{"children":"$Le"}],["$","meta",null,{"name":"next-size-adjust","content":""}]],["$","$Lf",null,{"children":["$","div",null,{"hidden":true,"children":["$","$10",null,{"fallback":null,"children":"$L11"}]}]}]]}],false]],"m":"$undefined","G":["$12",[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/ecd2072ebf41611f.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"s":false,"S":true}
16
+ 0:{"P":null,"b":"Wnr9eYJaRUoC5a3SUgrBr","p":"","c":["",""],"i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/ecd2072ebf41611f.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/cdd12d5c1a5a6064.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"ko","className":"dark h-full","children":["$","body",null,{"className":"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased h-screen overflow-hidden","children":[["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}],["$","$L4",null,{"position":"bottom-right","toastOptions":{"duration":4000,"style":{"background":"hsl(var(--background))","color":"hsl(var(--foreground))","border":"1px solid hsl(var(--border))"}}}]]}]}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L5",null,{"Component":"$6","searchParams":{},"params":{},"promises":["$@7","$@8"]}],[["$","script","script-0",{"src":"/_next/static/chunks/f1ac9047ac4a3fde.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/37d0cd2587a38f79.js","async":true,"nonce":"$undefined"}]],["$","$L9",null,{"children":["$La",["$","$Lb",null,{"promise":"$@c"}]]}]]}],{},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Ld",null,{"children":"$Le"}],["$","meta",null,{"name":"next-size-adjust","content":""}]],["$","$Lf",null,{"children":["$","div",null,{"hidden":true,"children":["$","$10",null,{"fallback":null,"children":"$L11"}]}]}]]}],false]],"m":"$undefined","G":["$12",[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/ecd2072ebf41611f.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"s":false,"S":true}
17
17
  7:{}
18
18
  8:"$0:f:0:1:2:children:1:props:children:0:props:params"
19
19
  e:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
@@ -865,6 +865,40 @@ edit_file_replace({
865
865
  bash({ script: "npm test" })
866
866
  ```
867
867
 
868
+ ## Markdown formatting in responses
869
+
870
+ **ALWAYS use Markdown** in all text responses. The terminal UI renders rich Markdown formatting.
871
+
872
+ **Supported features:**
873
+ - Headers: `#` to `####` (H1-H4) - use to structure responses
874
+ - Lists: `-` `*` `+` (unordered), `1.` (ordered) - nestable with indentation
875
+ - Tables: `|` pipes - keep to 3-5 columns for readability
876
+ - Code blocks: ` ```language ` - always include language tag for syntax highlighting
877
+ - Inline: `**bold**` `*italic*` `` `code` `` `~~strike~~` `[link](url)`
878
+ - Horizontal rules: `---` for visual separation
879
+ - Not supported: blockquotes, images, HTML tags
880
+
881
+ **Formatting requirements:**
882
+ - Structure all responses with headers and lists
883
+ - Use `code` for file names, commands, variable names
884
+ - Use **bold** for important points or status
885
+ - Use tables for structured data comparison
886
+ - Always tag code blocks with language (js, python, bash, etc.)
887
+
888
+ **Example:**
889
+ ```markdown
890
+ ## Changes Made
891
+ - Updated authentication with OAuth integration
892
+ - Added 5 new test cases in `auth.test.js`
893
+
894
+ | File | Status |
895
+ |------|--------|
896
+ | auth.js | **Modified** |
897
+ | config.js | Added |
898
+
899
+ **Verification:** All tests passing ✓
900
+ ```
901
+
868
902
  ## Communication during execution
869
903
 
870
904
  **response_message: Brief Upcoming Action Guidance**
@@ -173,7 +173,7 @@ function CodeResultDisplay({ item }) {
173
173
  );
174
174
  }
175
175
 
176
- function StandardDisplay({ item, isPending, hasFollowingResult, nextItem, isLastInBatch = false }) {
176
+ function StandardDisplay({ item, isPending, hasFollowingResult, nextItem, isLastInBatch = false, terminalWidth }) {
177
177
  const { type, text, operations = [], toolName, toolInput, args } = item;
178
178
  const config = getTypeConfig(type);
179
179
 
@@ -542,7 +542,7 @@ function StandardDisplay({ item, isPending, hasFollowingResult, nextItem, isLast
542
542
  bold: config.bold
543
543
  }, config.icon),
544
544
  React.createElement(Box, { flexDirection: "column", flexGrow: 1 },
545
- renderMarkdown(text)
545
+ renderMarkdown(text, { terminalWidth: terminalWidth || 80 })
546
546
  )
547
547
  );
548
548
  }
@@ -781,6 +781,7 @@ function StandardDisplay({ item, isPending, hasFollowingResult, nextItem, isLast
781
781
  let textContent;
782
782
  if (text && typeof text === 'object' && text.type === 'formatted' && Array.isArray(text.parts)) {
783
783
  // 구조화된 parts를 렌더링
784
+ debugLog(`Rendering formatted text with ${text.parts.length} parts`);
784
785
  textContent = React.createElement(Box, { flexDirection: "row" },
785
786
  ...text.parts.map((part, idx) =>
786
787
  React.createElement(Text, {
@@ -790,8 +791,13 @@ function StandardDisplay({ item, isPending, hasFollowingResult, nextItem, isLast
790
791
  }, part.text)
791
792
  )
792
793
  );
794
+ } else if (type === 'assistant' && typeof text === 'string') {
795
+ // assistant 응답은 마크다운 렌더링 적용
796
+ debugLog(`Rendering assistant response with Markdown, text length: ${text.length}, terminalWidth: ${terminalWidth || 80}`);
797
+ textContent = renderMarkdown(text, { terminalWidth: terminalWidth || 80 });
793
798
  } else {
794
799
  // 일반 문자열
800
+ debugLog(`Rendering plain text, type: ${type}, text length: ${typeof text === 'string' ? text.length : 'N/A'}`);
795
801
  textContent = React.createElement(Text, {
796
802
  color: textColor
797
803
  }, text);
@@ -831,7 +837,7 @@ export function ConversationItem({ item, isPending = false, terminalWidth, nextI
831
837
  debugLog(`hasFollowingResult: ${hasFollowingResult}`);
832
838
  debugLog('Rendering StandardDisplay');
833
839
 
834
- const result = React.createElement(StandardDisplay, { item, isPending, hasFollowingResult, nextItem, isLastInBatch });
840
+ const result = React.createElement(StandardDisplay, { item, isPending, hasFollowingResult, nextItem, isLastInBatch, terminalWidth });
835
841
 
836
842
  return result;
837
843
  }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Grid Renderer
3
+ * 마크다운 테이블을 렌더링하는 컴포넌트
4
+ */
5
+
6
+ import React from 'react';
7
+ import { Text, Box } from 'ink';
8
+ import { theme } from '../design/themeColors.js';
9
+ import { ProcessInlineText, calculateTextWidth } from './InlineFormatter.js';
10
+
11
+ /**
12
+ * 마크다운 테이블을 렌더링하는 컴포넌트
13
+ * @param {Object} props
14
+ * @param {string[]} props.columnHeaders - 테이블 헤더
15
+ * @param {string[][]} props.dataRows - 테이블 데이터 행
16
+ * @param {number} props.maxWidth - 터미널 최대 너비
17
+ */
18
+ export const GridRenderer = ({ columnHeaders, dataRows, maxWidth }) => {
19
+ // 컬럼 너비 계산 (마크다운 처리 후 실제 표시 너비 기준)
20
+ const widthPerColumn = columnHeaders.map((headerText, columnIndex) => {
21
+ const headerDisplayWidth = calculateTextWidth(headerText);
22
+ const maxDataWidth = Math.max(
23
+ ...dataRows.map((rowData) => calculateTextWidth(rowData[columnIndex] || ''))
24
+ );
25
+ return Math.max(headerDisplayWidth, maxDataWidth) + 2; // 패딩 추가
26
+ });
27
+
28
+ // 테이블이 터미널 너비를 초과하지 않도록 조정
29
+ const totalRequiredWidth = widthPerColumn.reduce((sum, w) => sum + w + 1, 1);
30
+ const shrinkRatio = totalRequiredWidth > maxWidth ? maxWidth / totalRequiredWidth : 1;
31
+ const finalWidths = widthPerColumn.map((w) => Math.floor(w * shrinkRatio));
32
+
33
+ /**
34
+ * 셀 내용을 렌더링 (너비에 맞게 잘라내거나 패딩 추가)
35
+ */
36
+ const buildCell = (cellText, cellWidth, isHeaderCell = false) => {
37
+ const availableWidth = Math.max(0, cellWidth - 2);
38
+ const actualWidth = calculateTextWidth(cellText);
39
+
40
+ let displayText = cellText;
41
+ if (actualWidth > availableWidth) {
42
+ if (availableWidth <= 3) {
43
+ // 너비가 매우 작으면 단순 잘라내기
44
+ displayText = cellText.substring(0, Math.min(cellText.length, availableWidth));
45
+ } else {
46
+ // 이진 탐색으로 마크다운을 보존하면서 최적 절단점 찾기
47
+ let leftBound = 0;
48
+ let rightBound = cellText.length;
49
+ let bestFit = cellText;
50
+
51
+ while (leftBound <= rightBound) {
52
+ const midPoint = Math.floor((leftBound + rightBound) / 2);
53
+ const testText = cellText.substring(0, midPoint);
54
+ const testWidth = calculateTextWidth(testText);
55
+
56
+ if (testWidth <= availableWidth - 3) {
57
+ bestFit = testText;
58
+ leftBound = midPoint + 1;
59
+ } else {
60
+ rightBound = midPoint - 1;
61
+ }
62
+ }
63
+
64
+ displayText = bestFit + '...';
65
+ }
66
+ }
67
+
68
+ // 정확한 패딩 계산
69
+ const finalDisplayWidth = calculateTextWidth(displayText);
70
+ const paddingRequired = Math.max(0, availableWidth - finalDisplayWidth);
71
+
72
+ return React.createElement(Text, null,
73
+ isHeaderCell
74
+ ? React.createElement(Text, { bold: true, color: theme.text.link },
75
+ React.createElement(ProcessInlineText, { content: displayText })
76
+ )
77
+ : React.createElement(ProcessInlineText, { content: displayText }),
78
+ ' '.repeat(paddingRequired)
79
+ );
80
+ };
81
+
82
+ /**
83
+ * 테두리 렌더링
84
+ */
85
+ const buildBorderLine = (position) => {
86
+ const borderStyles = {
87
+ top: { leftCorner: '┌', junction: '┬', rightCorner: '┐', line: '─' },
88
+ mid: { leftCorner: '├', junction: '┼', rightCorner: '┤', line: '─' },
89
+ bottom: { leftCorner: '└', junction: '┴', rightCorner: '┘', line: '─' }
90
+ };
91
+
92
+ const style = borderStyles[position];
93
+ const segments = finalWidths.map((width) => style.line.repeat(width));
94
+ const borderText = style.leftCorner + segments.join(style.junction) + style.rightCorner;
95
+
96
+ return React.createElement(Text, { color: theme.text.secondary }, borderText);
97
+ };
98
+
99
+ /**
100
+ * 테이블 행 렌더링
101
+ */
102
+ const buildTableRow = (rowCells, isHeaderRow = false) => {
103
+ const renderedCells = rowCells.map((cellContent, idx) => {
104
+ const width = finalWidths[idx] || 0;
105
+ return buildCell(cellContent || '', width, isHeaderRow);
106
+ });
107
+
108
+ return React.createElement(Text, { color: theme.text.primary },
109
+ '│ ',
110
+ ...renderedCells.map((cell, idx) =>
111
+ React.createElement(React.Fragment, { key: idx },
112
+ cell,
113
+ idx < renderedCells.length - 1 ? ' │ ' : ''
114
+ )
115
+ ),
116
+ ' │'
117
+ );
118
+ };
119
+
120
+ return React.createElement(Box, { flexDirection: 'column', marginY: 1 },
121
+ // 상단 테두리
122
+ buildBorderLine('top'),
123
+
124
+ // 헤더 행
125
+ buildTableRow(columnHeaders, true),
126
+
127
+ // 중간 테두리
128
+ buildBorderLine('mid'),
129
+
130
+ // 데이터 행
131
+ ...dataRows.map((row, idx) =>
132
+ React.createElement(React.Fragment, { key: idx },
133
+ buildTableRow(row)
134
+ )
135
+ ),
136
+
137
+ // 하단 테두리
138
+ buildBorderLine('bottom')
139
+ );
140
+ };
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Inline Formatter
3
+ * 인라인 마크다운 요소를 파싱하여 Ink 컴포넌트로 변환
4
+ */
5
+
6
+ import React from 'react';
7
+ import { Text } from 'ink';
8
+ import { theme } from '../design/themeColors.js';
9
+ import stringWidth from 'string-width';
10
+
11
+ // 마크다운 마커 길이 상수
12
+ const MARKER_LENGTHS = {
13
+ BOLD: 2, // "**"
14
+ ITALIC: 1, // "*" or "_"
15
+ STRIKE: 2, // "~~"
16
+ CODE: 1, // "`"
17
+ UNDERLINE_START: 3, // "<u>"
18
+ UNDERLINE_END: 4 // "</u>"
19
+ };
20
+
21
+ /**
22
+ * 인라인 마크다운을 렌더링하는 컴포넌트
23
+ */
24
+ const ProcessInlineTextInternal = ({ content }) => {
25
+ // 마크다운이나 URL이 없으면 바로 반환
26
+ if (!/[*_~`<[https?:]/.test(content)) {
27
+ return React.createElement(Text, { color: theme.text.primary }, content);
28
+ }
29
+
30
+ const elements = [];
31
+ let currentPosition = 0;
32
+ const patternRegex = /(\*\*.*?\*\*|\*.*?\*|_.*?_|~~.*?~~|\[.*?\]\(.*?\)|`+.+?`+|<u>.*?<\/u>|https?:\/\/\S+)/g;
33
+ let matchResult;
34
+
35
+ while ((matchResult = patternRegex.exec(content)) !== null) {
36
+ if (matchResult.index > currentPosition) {
37
+ elements.push(
38
+ React.createElement(Text, { key: `plain-${currentPosition}` },
39
+ content.slice(currentPosition, matchResult.index)
40
+ )
41
+ );
42
+ }
43
+
44
+ const matchedText = matchResult[0];
45
+ let formattedElement = null;
46
+ const elementKey = `fmt-${matchResult.index}`;
47
+
48
+ try {
49
+ // 볼드 처리
50
+ if (matchedText.startsWith('**') &&
51
+ matchedText.endsWith('**') &&
52
+ matchedText.length > MARKER_LENGTHS.BOLD * 2) {
53
+ formattedElement = React.createElement(Text, { key: elementKey, bold: true },
54
+ matchedText.slice(MARKER_LENGTHS.BOLD, -MARKER_LENGTHS.BOLD)
55
+ );
56
+ }
57
+ // 이탤릭 처리
58
+ else if (matchedText.length > MARKER_LENGTHS.ITALIC * 2 &&
59
+ ((matchedText.startsWith('*') && matchedText.endsWith('*')) ||
60
+ (matchedText.startsWith('_') && matchedText.endsWith('_'))) &&
61
+ !/\w/.test(content.substring(matchResult.index - 1, matchResult.index)) &&
62
+ !/\w/.test(content.substring(patternRegex.lastIndex, patternRegex.lastIndex + 1)) &&
63
+ !/\S[./\\]/.test(content.substring(matchResult.index - 2, matchResult.index)) &&
64
+ !/[./\\]\S/.test(content.substring(patternRegex.lastIndex, patternRegex.lastIndex + 2))) {
65
+ formattedElement = React.createElement(Text, { key: elementKey, italic: true },
66
+ matchedText.slice(MARKER_LENGTHS.ITALIC, -MARKER_LENGTHS.ITALIC)
67
+ );
68
+ }
69
+ // 취소선 처리
70
+ else if (matchedText.startsWith('~~') &&
71
+ matchedText.endsWith('~~') &&
72
+ matchedText.length > MARKER_LENGTHS.STRIKE * 2) {
73
+ formattedElement = React.createElement(Text, { key: elementKey, strikethrough: true },
74
+ matchedText.slice(MARKER_LENGTHS.STRIKE, -MARKER_LENGTHS.STRIKE)
75
+ );
76
+ }
77
+ // 인라인 코드 처리
78
+ else if (matchedText.startsWith('`') &&
79
+ matchedText.endsWith('`') &&
80
+ matchedText.length > MARKER_LENGTHS.CODE) {
81
+ const codePattern = matchedText.match(/^(`+)(.+?)\1$/s);
82
+ if (codePattern && codePattern[2]) {
83
+ formattedElement = React.createElement(Text, {
84
+ key: elementKey,
85
+ color: theme.status.warning
86
+ }, codePattern[2]);
87
+ }
88
+ }
89
+ // 링크 처리
90
+ else if (matchedText.startsWith('[') &&
91
+ matchedText.includes('](') &&
92
+ matchedText.endsWith(')')) {
93
+ const linkPattern = matchedText.match(/\[(.*?)\]\((.*?)\)/);
94
+ if (linkPattern) {
95
+ const linkLabel = linkPattern[1];
96
+ const linkUrl = linkPattern[2];
97
+ formattedElement = React.createElement(Text, { key: elementKey },
98
+ linkLabel,
99
+ React.createElement(Text, { color: theme.text.link }, ` (${linkUrl})`)
100
+ );
101
+ }
102
+ }
103
+ // 밑줄 처리
104
+ else if (matchedText.startsWith('<u>') &&
105
+ matchedText.endsWith('</u>') &&
106
+ matchedText.length > MARKER_LENGTHS.UNDERLINE_START + MARKER_LENGTHS.UNDERLINE_END - 1) {
107
+ formattedElement = React.createElement(Text, { key: elementKey, underline: true },
108
+ matchedText.slice(MARKER_LENGTHS.UNDERLINE_START, -MARKER_LENGTHS.UNDERLINE_END)
109
+ );
110
+ }
111
+ // URL 처리
112
+ else if (matchedText.match(/^https?:\/\//)) {
113
+ formattedElement = React.createElement(Text, {
114
+ key: elementKey,
115
+ color: theme.text.link
116
+ }, matchedText);
117
+ }
118
+ } catch (error) {
119
+ // 파싱 오류 발생 시 무시
120
+ formattedElement = null;
121
+ }
122
+
123
+ elements.push(
124
+ formattedElement ?? React.createElement(Text, { key: elementKey }, matchedText)
125
+ );
126
+ currentPosition = patternRegex.lastIndex;
127
+ }
128
+
129
+ if (currentPosition < content.length) {
130
+ elements.push(
131
+ React.createElement(Text, { key: `plain-${currentPosition}` },
132
+ content.slice(currentPosition)
133
+ )
134
+ );
135
+ }
136
+
137
+ return React.createElement(React.Fragment, null, elements.filter(el => el !== null));
138
+ };
139
+
140
+ export const ProcessInlineText = React.memo(ProcessInlineTextInternal);
141
+
142
+ /**
143
+ * 마크다운 포맷팅을 제거하고 실제 텍스트 길이를 계산
144
+ * 테이블의 컬럼 너비 계산 등에 사용
145
+ */
146
+ export function calculateTextWidth(content) {
147
+ const plainText = content
148
+ .replace(/\*\*(.*?)\*\*/g, '$1')
149
+ .replace(/\*(.*?)\*/g, '$1')
150
+ .replace(/_(.*?)_/g, '$1')
151
+ .replace(/~~(.*?)~~/g, '$1')
152
+ .replace(/`(.*?)`/g, '$1')
153
+ .replace(/<u>(.*?)<\/u>/g, '$1')
154
+ .replace(/.*\[(.*?)\]\(.*\)/g, '$1');
155
+ return stringWidth(plainText);
156
+ }
@@ -6,226 +6,372 @@
6
6
  import React from 'react';
7
7
  import { Text, Box } from 'ink';
8
8
  import { theme } from '../design/themeColors.js';
9
+ import { colorizeCode } from './syntaxHighlighter.js';
10
+ import { GridRenderer } from './GridRenderer.js';
11
+ import { ProcessInlineText } from './InlineFormatter.js';
12
+
13
+ // 렌더링 상수
14
+ const SPACING = {
15
+ EMPTY_LINE: 1,
16
+ CODE_PADDING: 1,
17
+ LIST_PREFIX_PAD: 1,
18
+ LIST_TEXT_GROW: 1
19
+ };
9
20
 
10
21
  /**
11
22
  * 마크다운 텍스트를 파싱하여 Ink 컴포넌트로 변환
23
+ * @param {string} text - 마크다운 텍스트
24
+ * @param {Object} options - 렌더링 옵션
25
+ * @param {boolean} options.isPending - 스트리밍 중 여부
26
+ * @param {number} options.availableHeight - 사용 가능한 터미널 높이
27
+ * @param {number} options.terminalWidth - 터미널 너비 (기본값: 80)
28
+ * @returns {React.ReactNode}
12
29
  */
13
- export function renderMarkdown(text) {
30
+ export function renderMarkdown(text, options = {}) {
14
31
  if (!text) return null;
15
32
 
16
- const lines = text.split('\n');
17
- const elements = [];
18
- let inCodeBlock = false;
19
- let codeLines = [];
20
- let codeLanguage = '';
21
-
22
- for (let i = 0; i < lines.length; i++) {
23
- const line = lines[i];
24
-
25
- // Code block 처리
26
- if (line.trim().startsWith('```')) {
27
- if (inCodeBlock) {
28
- // Code block
29
- if (codeLines.length > 0) {
30
- elements.push(
31
- React.createElement(Box, {
32
- key: `code-${i}`,
33
- flexDirection: 'column',
34
- borderStyle: 'round',
35
- borderColor: theme.text.secondary,
36
- paddingX: 1,
37
- marginY: 0
38
- },
39
- React.createElement(Text, { color: theme.text.secondary }, codeLines.join('\n'))
40
- )
41
- );
42
- }
43
- codeLines = [];
44
- codeLanguage = '';
45
- inCodeBlock = false;
33
+ const {
34
+ isPending = false,
35
+ availableHeight,
36
+ terminalWidth = 80
37
+ } = options;
38
+
39
+ const lineArray = text.split(/\r?\n/);
40
+
41
+ // 정규식 패턴
42
+ const patterns = {
43
+ header: /^ *(#{1,4}) +(.*)/,
44
+ codeFence: /^ *(`{3,}|~{3,}) *(\w*?) *$/,
45
+ unorderedList: /^([ \t]*)([-*+]) +(.*)/,
46
+ orderedList: /^([ \t]*)(\d+)\. +(.*)/,
47
+ horizontalRule: /^ *([-*_] *){3,} *$/,
48
+ tableRow: /^\s*\|(.+)\|\s*$/,
49
+ tableSeparator: /^\s*\|?\s*(:?-+:?)\s*(\|\s*(:?-+:?)\s*)+\|?\s*$/
50
+ };
51
+
52
+ const blocks = [];
53
+ let previousLineWasEmpty = true;
54
+
55
+ // 상태 변수
56
+ let codeBlockActive = false;
57
+ let codeBlockLines = [];
58
+ let codeBlockLanguage = null;
59
+ let codeBlockFence = '';
60
+
61
+ let tableActive = false;
62
+ let tableHeaderCells = [];
63
+ let tableDataRows = [];
64
+
65
+ function appendBlock(block) {
66
+ if (block) {
67
+ blocks.push(block);
68
+ previousLineWasEmpty = false;
69
+ }
70
+ }
71
+
72
+ lineArray.forEach((currentLine, lineIndex) => {
73
+ const lineKey = `ln-${lineIndex}`;
74
+
75
+ // 코드 블록 내부 처리
76
+ if (codeBlockActive) {
77
+ const fenceMatch = currentLine.match(patterns.codeFence);
78
+ if (fenceMatch &&
79
+ fenceMatch[1].startsWith(codeBlockFence[0]) &&
80
+ fenceMatch[1].length >= codeBlockFence.length) {
81
+ appendBlock(
82
+ React.createElement(BuildCodeBlock, {
83
+ key: lineKey,
84
+ lines: codeBlockLines,
85
+ language: codeBlockLanguage,
86
+ isPending,
87
+ availableHeight,
88
+ terminalWidth
89
+ })
90
+ );
91
+ codeBlockActive = false;
92
+ codeBlockLines = [];
93
+ codeBlockLanguage = null;
94
+ codeBlockFence = '';
46
95
  } else {
47
- // Code block 시작
48
- codeLanguage = line.trim().slice(3).trim();
49
- inCodeBlock = true;
96
+ codeBlockLines.push(currentLine);
50
97
  }
51
- continue;
98
+ return;
52
99
  }
53
100
 
54
- if (inCodeBlock) {
55
- codeLines.push(line);
56
- continue;
57
- }
101
+ // 패턴 매칭
102
+ const fenceMatch = currentLine.match(patterns.codeFence);
103
+ const headerMatch = currentLine.match(patterns.header);
104
+ const ulMatch = currentLine.match(patterns.unorderedList);
105
+ const olMatch = currentLine.match(patterns.orderedList);
106
+ const hrMatch = currentLine.match(patterns.horizontalRule);
107
+ const tableRowMatch = currentLine.match(patterns.tableRow);
108
+ const tableSepMatch = currentLine.match(patterns.tableSeparator);
58
109
 
59
- //
60
- if (line.trim() === '') {
61
- elements.push(React.createElement(Text, { key: `empty-${i}` }, ''));
62
- continue;
110
+ // 코드 블록 시작
111
+ if (fenceMatch) {
112
+ codeBlockActive = true;
113
+ codeBlockFence = fenceMatch[1];
114
+ codeBlockLanguage = fenceMatch[2] || null;
115
+ }
116
+ // 테이블 시작 감지
117
+ else if (tableRowMatch && !tableActive) {
118
+ if (lineIndex + 1 < lineArray.length &&
119
+ lineArray[lineIndex + 1].match(patterns.tableSeparator)) {
120
+ tableActive = true;
121
+ tableHeaderCells = tableRowMatch[1].split('|').map(cell => cell.trim());
122
+ tableDataRows = [];
123
+ } else {
124
+ appendBlock(
125
+ React.createElement(Box, { key: lineKey },
126
+ React.createElement(Text, { wrap: 'wrap' },
127
+ React.createElement(ProcessInlineText, { content: currentLine })
128
+ )
129
+ )
130
+ );
131
+ }
132
+ }
133
+ // 테이블 구분선 스킵
134
+ else if (tableActive && tableSepMatch) {
135
+ // 구분선은 무시
136
+ }
137
+ // 테이블 데이터 행
138
+ else if (tableActive && tableRowMatch) {
139
+ const cells = tableRowMatch[1].split('|').map(cell => cell.trim());
140
+ while (cells.length < tableHeaderCells.length) cells.push('');
141
+ if (cells.length > tableHeaderCells.length) cells.length = tableHeaderCells.length;
142
+ tableDataRows.push(cells);
63
143
  }
144
+ // 테이블 종료
145
+ else if (tableActive && !tableRowMatch) {
146
+ if (tableHeaderCells.length > 0 && tableDataRows.length > 0) {
147
+ appendBlock(
148
+ React.createElement(BuildTable, {
149
+ key: `table-${blocks.length}`,
150
+ columnHeaders: tableHeaderCells,
151
+ dataRows: tableDataRows,
152
+ maxWidth: terminalWidth
153
+ })
154
+ );
155
+ }
156
+ tableActive = false;
157
+ tableDataRows = [];
158
+ tableHeaderCells = [];
64
159
 
65
- // Heading 처리 (### 먼저 검사 - 긴 것부터)
66
- if (line.startsWith('### ')) {
67
- elements.push(
68
- React.createElement(Box, {
69
- key: `h3-${i}`,
70
- flexDirection: 'row'
71
- },
72
- React.createElement(Text, {
73
- color: theme.text.accent,
74
- bold: true
75
- }, renderInlineMarkdown(line.slice(4)))
76
- )
77
- );
78
- continue;
160
+ // 현재 처리
161
+ if (currentLine.trim().length > 0) {
162
+ appendBlock(
163
+ React.createElement(Box, { key: lineKey },
164
+ React.createElement(Text, { wrap: 'wrap' },
165
+ React.createElement(ProcessInlineText, { content: currentLine })
166
+ )
167
+ )
168
+ );
169
+ }
79
170
  }
80
- if (line.startsWith('## ')) {
81
- elements.push(
82
- React.createElement(Box, {
83
- key: `h2-${i}`,
84
- flexDirection: 'row'
85
- },
86
- React.createElement(Text, {
87
- color: theme.text.accent,
88
- bold: true
89
- }, renderInlineMarkdown(line.slice(3)))
171
+ // 수평선
172
+ else if (hrMatch) {
173
+ appendBlock(
174
+ React.createElement(Box, { key: lineKey },
175
+ React.createElement(Text, { dimColor: true }, '---')
90
176
  )
91
177
  );
92
- continue;
93
178
  }
94
- if (line.startsWith('# ')) {
95
- elements.push(
96
- React.createElement(Box, {
97
- key: `h1-${i}`,
98
- flexDirection: 'row'
99
- },
100
- React.createElement(Text, {
101
- color: theme.text.accent,
102
- bold: true
103
- }, renderInlineMarkdown(line.slice(2)))
104
- )
179
+ // 헤더
180
+ else if (headerMatch) {
181
+ const level = headerMatch[1].length;
182
+ const headerText = headerMatch[2];
183
+ let headerElement = null;
184
+
185
+ switch (level) {
186
+ case 1:
187
+ headerElement = React.createElement(Text, { bold: true, color: theme.text.link },
188
+ React.createElement(ProcessInlineText, { content: headerText })
189
+ );
190
+ break;
191
+ case 2:
192
+ headerElement = React.createElement(Text, { bold: true, color: theme.text.link },
193
+ React.createElement(ProcessInlineText, { content: headerText })
194
+ );
195
+ break;
196
+ case 3:
197
+ headerElement = React.createElement(Text, { bold: true, color: theme.text.primary },
198
+ React.createElement(ProcessInlineText, { content: headerText })
199
+ );
200
+ break;
201
+ case 4:
202
+ headerElement = React.createElement(Text, { italic: true, color: theme.text.secondary },
203
+ React.createElement(ProcessInlineText, { content: headerText })
204
+ );
205
+ break;
206
+ default:
207
+ headerElement = React.createElement(Text, { color: theme.text.primary },
208
+ React.createElement(ProcessInlineText, { content: headerText })
209
+ );
210
+ }
211
+ if (headerElement) {
212
+ appendBlock(React.createElement(Box, { key: lineKey }, headerElement));
213
+ }
214
+ }
215
+ // 순서 없는 리스트
216
+ else if (ulMatch) {
217
+ const [, indent, marker, content] = ulMatch;
218
+ appendBlock(
219
+ React.createElement(BuildListItem, {
220
+ key: lineKey,
221
+ itemText: content,
222
+ listType: 'ul',
223
+ marker: marker,
224
+ indentation: indent
225
+ })
105
226
  );
106
- continue;
107
227
  }
108
-
109
- // 리스트 항목 처리
110
- const listMatch = line.match(/^(\s*)([-*•])\s+(.+)$/);
111
- if (listMatch) {
112
- const [, indent, bullet, content] = listMatch;
113
- elements.push(
114
- React.createElement(Box, {
115
- key: `list-${i}`,
116
- flexDirection: 'row',
117
- marginLeft: indent.length
118
- },
119
- React.createElement(Text, { color: theme.text.accent }, bullet + ' '),
120
- React.createElement(Text, null, renderInlineMarkdown(content))
121
- )
228
+ // 순서 있는 리스트
229
+ else if (olMatch) {
230
+ const [, indent, marker, content] = olMatch;
231
+ appendBlock(
232
+ React.createElement(BuildListItem, {
233
+ key: lineKey,
234
+ itemText: content,
235
+ listType: 'ol',
236
+ marker: marker,
237
+ indentation: indent
238
+ })
122
239
  );
123
- continue;
124
240
  }
241
+ // 빈 줄 또는 일반 텍스트
242
+ else {
243
+ if (currentLine.trim().length === 0 && !codeBlockActive) {
244
+ if (!previousLineWasEmpty) {
245
+ blocks.push(
246
+ React.createElement(Box, {
247
+ key: `space-${lineIndex}`,
248
+ height: SPACING.EMPTY_LINE
249
+ })
250
+ );
251
+ previousLineWasEmpty = true;
252
+ }
253
+ } else {
254
+ appendBlock(
255
+ React.createElement(Box, { key: lineKey },
256
+ React.createElement(Text, { wrap: 'wrap', color: theme.text.primary },
257
+ React.createElement(ProcessInlineText, { content: currentLine })
258
+ )
259
+ )
260
+ );
261
+ }
262
+ }
263
+ });
125
264
 
126
- // 일반 텍스트 (인라인 마크다운 처리)
127
- elements.push(
128
- React.createElement(Box, {
129
- key: `line-${i}`,
130
- flexDirection: 'row'
131
- },
132
- React.createElement(Text, null, renderInlineMarkdown(line))
133
- )
265
+ // 닫히지 않은 코드 블록 처리
266
+ if (codeBlockActive) {
267
+ appendBlock(
268
+ React.createElement(BuildCodeBlock, {
269
+ key: 'eof-code',
270
+ lines: codeBlockLines,
271
+ language: codeBlockLanguage,
272
+ isPending,
273
+ availableHeight,
274
+ terminalWidth
275
+ })
134
276
  );
135
277
  }
136
278
 
137
- return React.createElement(Box, { flexDirection: 'column' }, elements);
279
+ // 닫히지 않은 테이블 처리
280
+ if (tableActive && tableHeaderCells.length > 0 && tableDataRows.length > 0) {
281
+ appendBlock(
282
+ React.createElement(BuildTable, {
283
+ key: `table-${blocks.length}`,
284
+ columnHeaders: tableHeaderCells,
285
+ dataRows: tableDataRows,
286
+ maxWidth: terminalWidth
287
+ })
288
+ );
289
+ }
290
+
291
+ return React.createElement(React.Fragment, null, blocks);
138
292
  }
139
293
 
140
294
  /**
141
- * 인라인 마크다운 처리 (**, `, 등)
295
+ * 코드 블록 렌더링 컴포넌트
142
296
  */
143
- function renderInlineMarkdown(text) {
144
- const parts = [];
145
- let currentIndex = 0;
146
- let partKey = 0;
147
-
148
- // 모든 마크다운 패턴 찾기 (정규식 재생성하여 lastIndex 문제 방지)
149
- const patterns = [];
150
-
151
- // **bold** 패턴 찾기
152
- let boldRegex = /\*\*([^*]+)\*\*/g;
153
- let match;
154
- while ((match = boldRegex.exec(text)) !== null) {
155
- patterns.push({
156
- type: 'bold',
157
- start: match.index,
158
- end: match.index + match[0].length,
159
- content: match[1]
160
- });
161
- }
162
-
163
- // `code` 패턴 찾기
164
- let codeRegex = /`([^`]+)`/g;
165
- while ((match = codeRegex.exec(text)) !== null) {
166
- patterns.push({
167
- type: 'code',
168
- start: match.index,
169
- end: match.index + match[0].length,
170
- content: match[1]
171
- });
172
- }
297
+ const BuildCodeBlockInternal = ({ lines, language, isPending, availableHeight, terminalWidth }) => {
298
+ const MIN_LINES_BEFORE_MSG = 1;
299
+ const RESERVED_LINES = 2;
173
300
 
174
- // 시작 위치로 정렬
175
- patterns.sort((a, b) => a.start - b.start);
301
+ if (isPending && availableHeight !== undefined) {
302
+ const maxLines = Math.max(0, availableHeight - RESERVED_LINES);
176
303
 
177
- // 겹치는 패턴 제거 (먼저 나온 패턴 우선)
178
- const filteredPatterns = [];
179
- let lastEnd = 0;
180
- for (const pattern of patterns) {
181
- if (pattern.start >= lastEnd) {
182
- filteredPatterns.push(pattern);
183
- lastEnd = pattern.end;
184
- }
185
- }
186
-
187
- // 패턴 적용
188
- for (const pattern of filteredPatterns) {
189
- // 이전 텍스트 추가
190
- if (currentIndex < pattern.start) {
191
- const plainText = text.slice(currentIndex, pattern.start);
192
- if (plainText) {
193
- parts.push(
194
- React.createElement(Text, { key: `text-${partKey++}` }, plainText)
304
+ if (lines.length > maxLines) {
305
+ if (maxLines < MIN_LINES_BEFORE_MSG) {
306
+ return React.createElement(Box, { paddingLeft: SPACING.CODE_PADDING },
307
+ React.createElement(Text, { color: theme.text.secondary },
308
+ '... code is being written ...'
309
+ )
195
310
  );
196
311
  }
197
- }
198
312
 
199
- // 패턴 적용된 텍스트 추가
200
- if (pattern.type === 'bold') {
201
- parts.push(
202
- React.createElement(Text, {
203
- key: `bold-${partKey++}`,
204
- bold: true,
205
- color: theme.text.primary
206
- }, pattern.content)
207
- );
208
- } else if (pattern.type === 'code') {
209
- parts.push(
210
- React.createElement(Text, {
211
- key: `code-${partKey++}`,
212
- color: theme.status.warning
213
- }, pattern.content)
214
- );
215
- }
216
-
217
- currentIndex = pattern.end;
218
- }
313
+ const truncatedLines = lines.slice(0, maxLines);
314
+ const truncatedCode = colorizeCode(truncatedLines.join('\n'), language, true);
219
315
 
220
- // 남은 텍스트 추가
221
- if (currentIndex < text.length) {
222
- const remainingText = text.slice(currentIndex);
223
- if (remainingText) {
224
- parts.push(
225
- React.createElement(Text, { key: `text-${partKey++}` }, remainingText)
316
+ return React.createElement(Box, {
317
+ paddingLeft: SPACING.CODE_PADDING,
318
+ flexDirection: 'column'
319
+ },
320
+ truncatedCode,
321
+ React.createElement(Text, { color: theme.text.secondary },
322
+ '... generating more ...'
323
+ )
226
324
  );
227
325
  }
228
326
  }
229
327
 
230
- return parts.length > 0 ? parts : text;
231
- }
328
+ const fullCode = lines.join('\n');
329
+ const highlightedCode = colorizeCode(fullCode, language, true);
330
+
331
+ return React.createElement(Box, {
332
+ paddingLeft: SPACING.CODE_PADDING,
333
+ flexDirection: 'column',
334
+ width: terminalWidth,
335
+ flexShrink: 0
336
+ }, highlightedCode);
337
+ };
338
+
339
+ const BuildCodeBlock = React.memo(BuildCodeBlockInternal);
340
+
341
+ /**
342
+ * 리스트 항목 렌더링 컴포넌트
343
+ */
344
+ const BuildListItemInternal = ({ itemText, listType, marker, indentation = '' }) => {
345
+ const displayPrefix = listType === 'ol' ? `${marker}. ` : `${marker} `;
346
+ const prefixLength = displayPrefix.length;
347
+ const indentAmount = indentation.length;
348
+
349
+ return React.createElement(Box, {
350
+ paddingLeft: indentAmount + SPACING.LIST_PREFIX_PAD,
351
+ flexDirection: 'row'
352
+ },
353
+ React.createElement(Box, { width: prefixLength },
354
+ React.createElement(Text, { color: theme.text.primary }, displayPrefix)
355
+ ),
356
+ React.createElement(Box, { flexGrow: SPACING.LIST_TEXT_GROW },
357
+ React.createElement(Text, { wrap: 'wrap', color: theme.text.primary },
358
+ React.createElement(ProcessInlineText, { content: itemText })
359
+ )
360
+ )
361
+ );
362
+ };
363
+
364
+ const BuildListItem = React.memo(BuildListItemInternal);
365
+
366
+ /**
367
+ * 테이블 렌더링 컴포넌트
368
+ */
369
+ const BuildTableInternal = ({ columnHeaders, dataRows, maxWidth }) => {
370
+ return React.createElement(GridRenderer, {
371
+ columnHeaders,
372
+ dataRows,
373
+ maxWidth
374
+ });
375
+ };
376
+
377
+ const BuildTable = React.memo(BuildTableInternal);