@alivault/pico 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +1 -1
- package/.output/public/assets/addon-fit-CMMXLNsg.js +1 -0
- package/.output/public/assets/{index-DQLwecED.js → index-CW1T9dk-.js} +11 -10
- package/.output/public/assets/routes-2LboeUx4.js +2194 -0
- package/.output/public/assets/styles-B1ITYh-r.css +2 -0
- package/.output/public/assets/xterm-CCMwI7sy.js +36 -0
- package/.output/server/_libs/lucide-react.mjs +20 -1
- package/.output/server/_libs/xterm__addon-fit.mjs +44 -0
- package/.output/server/_libs/xterm__xterm.mjs +10234 -0
- package/.output/server/_ssr/{router-D36lUq7O.mjs → router-l__gf5Y7.mjs} +703 -170
- package/.output/server/_ssr/{routes-9nZumcXQ.mjs → routes-CuWg5WTI.mjs} +159 -18
- package/.output/server/_ssr/{routes-C8qT6Oju.mjs → routes-DySm_W8N.mjs} +1659 -561
- package/.output/server/_ssr/ssr.mjs +2 -2
- package/.output/server/{_tanstack-start-manifest_v-Cd2ypHmK.mjs → _tanstack-start-manifest_v-CVoKKKc_.mjs} +5 -4
- package/.output/server/index.mjs +583 -569
- package/.output/server/node_modules/node-pty/LICENSE +69 -0
- package/.output/server/node_modules/node-pty/README.md +165 -0
- package/.output/server/node_modules/node-pty/binding.gyp +111 -0
- package/.output/server/node_modules/node-pty/build/Makefile +369 -0
- package/.output/server/node_modules/node-pty/build/Release/pty.node +0 -0
- package/.output/server/node_modules/node-pty/build/binding.Makefile +6 -0
- package/.output/server/node_modules/node-pty/build/pty.target.mk +168 -0
- package/.output/server/node_modules/node-pty/deps/.editorconfig +2 -0
- package/.output/server/node_modules/node-pty/deps/winpty/.drone.yml +17 -0
- package/.output/server/node_modules/node-pty/deps/winpty/.gitattributes +19 -0
- package/.output/server/node_modules/node-pty/deps/winpty/LICENSE +21 -0
- package/.output/server/node_modules/node-pty/deps/winpty/Makefile +166 -0
- package/.output/server/node_modules/node-pty/deps/winpty/README.md +151 -0
- package/.output/server/node_modules/node-pty/deps/winpty/RELEASES.md +280 -0
- package/.output/server/node_modules/node-pty/deps/winpty/VERSION.txt +1 -0
- package/.output/server/node_modules/node-pty/deps/winpty/configure +167 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/BufferResizeTests.cc +90 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/ChangeScreenBuffer.cc +53 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/ClearConsole.cc +72 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/ConinMode.cc +117 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/ConinMode.ps1 +116 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/ConoutMode.cc +113 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/DebugClient.py +42 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/DebugServer.py +63 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/DumpLines.py +5 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/EnableExtendedFlags.txt +46 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Font-Report-June2016/CP437-Consolas.txt +528 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Font-Report-June2016/CP437-Lucida.txt +633 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Font-Report-June2016/CP932.txt +630 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Font-Report-June2016/CP936.txt +630 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Font-Report-June2016/CP949.txt +630 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Font-Report-June2016/CP950.txt +630 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Font-Report-June2016/MinimumWindowWidths.txt +16 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Font-Report-June2016/Results.txt +4 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Font-Report-June2016/Windows10SetFontBugginess.txt +144 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/FontSurvey.cc +100 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/FormatChar.h +21 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/FreezePerfTest.cc +62 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/GetCh.cc +20 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/GetConsolePos.cc +41 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/GetFont.cc +261 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/IdentifyConsoleWindow.ps1 +51 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/IsNewConsole.cc +87 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/MouseInputNotes.txt +90 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/MoveConsoleWindow.cc +34 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Notes.txt +219 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/OSVersion.cc +27 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/ScreenBufferFreezeInactive.cc +101 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/ScreenBufferTest.cc +671 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/ScreenBufferTest2.cc +151 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/SelectAllTest.cc +45 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/SetBufferSize.cc +32 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/SetCursorPos.cc +10 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/SetFont.cc +145 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/SetWindowRect.cc +36 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/ShowArgv.cc +12 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/ShowConsoleInput.cc +40 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Spew.py +5 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/TestUtil.cc +172 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/UnicodeDoubleWidthTest.cc +102 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/UnicodeWideTest1.cc +246 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/UnicodeWideTest2.cc +130 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/UnixEcho.cc +89 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Utf16Echo.cc +46 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/VeryLargeRead.cc +122 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/VkEscapeTest.cc +56 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Win10ResizeWhileFrozen.cc +52 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Win10WrapTest1.cc +57 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Win10WrapTest2.cc +30 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Win32Echo1.cc +26 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Win32Echo2.cc +19 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Win32Test1.cc +46 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Win32Test2.cc +70 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Win32Test3.cc +78 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/Win32Write1.cc +44 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/WindowsBugCrashReader.cc +27 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/WriteConsole.cc +106 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/build32.sh +9 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/build64.sh +9 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/color-test.sh +212 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/font-notes.txt +300 -0
- package/.output/server/node_modules/node-pty/deps/winpty/misc/winbug-15048.cc +201 -0
- package/.output/server/node_modules/node-pty/deps/winpty/ship/build-pty4j-libpty.bat +36 -0
- package/.output/server/node_modules/node-pty/deps/winpty/ship/common_ship.py +53 -0
- package/.output/server/node_modules/node-pty/deps/winpty/ship/make_msvc_package.py +165 -0
- package/.output/server/node_modules/node-pty/deps/winpty/ship/ship.py +108 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Agent.cc +613 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Agent.h +103 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/AgentCreateDesktop.cc +84 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/AgentCreateDesktop.h +28 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/ConsoleFont.cc +632 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/ConsoleFont.h +28 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/ConsoleInput.cc +852 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/ConsoleInput.h +109 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/ConsoleInputReencoding.cc +121 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/ConsoleInputReencoding.h +36 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/ConsoleLine.cc +152 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/ConsoleLine.h +41 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Coord.h +87 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/DebugShowInput.cc +239 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/DebugShowInput.h +32 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/DefaultInputMap.cc +422 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/DefaultInputMap.h +28 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/DsrSender.h +30 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/EventLoop.cc +99 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/EventLoop.h +47 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/InputMap.cc +246 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/InputMap.h +114 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/LargeConsoleRead.cc +71 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/LargeConsoleRead.h +68 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/NamedPipe.cc +378 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/NamedPipe.h +125 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Scraper.cc +699 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Scraper.h +103 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/SimplePool.h +75 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/SmallRect.h +143 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Terminal.cc +535 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Terminal.h +69 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/UnicodeEncoding.h +157 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/UnicodeEncodingTest.cc +189 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Win32Console.cc +107 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Win32Console.h +67 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Win32ConsoleBuffer.cc +193 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/Win32ConsoleBuffer.h +99 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/main.cc +114 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/agent/subdir.mk +61 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/configurations.gypi +60 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/debugserver/DebugServer.cc +117 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/debugserver/subdir.mk +41 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/include/winpty.h +242 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/include/winpty_constants.h +131 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/libwinpty/AgentLocation.cc +75 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/libwinpty/AgentLocation.h +28 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/libwinpty/LibWinptyException.h +54 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/libwinpty/WinptyInternal.h +72 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/libwinpty/subdir.mk +46 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/libwinpty/winpty.cc +970 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/AgentMsg.h +38 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/BackgroundDesktop.cc +122 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/BackgroundDesktop.h +73 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/Buffer.cc +103 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/Buffer.h +102 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/DebugClient.cc +187 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/DebugClient.h +38 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/GenRandom.cc +138 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/GenRandom.h +55 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/GetCommitHash.bat +13 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/Mutex.h +54 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/OsModule.h +63 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/OwnedHandle.cc +36 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/OwnedHandle.h +45 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/PrecompiledHeader.h +43 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/StringBuilder.h +227 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/StringBuilderTest.cc +114 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/StringUtil.cc +55 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/StringUtil.h +80 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/TimeMeasurement.h +63 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/UnixCtrlChars.h +45 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/UpdateGenVersion.bat +20 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/WindowsSecurity.cc +460 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/WindowsSecurity.h +104 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/WindowsVersion.cc +252 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/WindowsVersion.h +29 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/WinptyAssert.cc +55 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/WinptyAssert.h +64 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/WinptyException.cc +57 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/WinptyException.h +43 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/WinptyVersion.cc +42 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/WinptyVersion.h +27 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/shared/winpty_snprintf.h +99 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/subdir.mk +5 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/tests/subdir.mk +28 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/tests/trivial_test.cc +158 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/unix-adapter/InputHandler.cc +114 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/unix-adapter/InputHandler.h +56 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/unix-adapter/OutputHandler.cc +80 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/unix-adapter/OutputHandler.h +53 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/unix-adapter/Util.cc +86 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/unix-adapter/Util.h +31 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/unix-adapter/WakeupFd.cc +70 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/unix-adapter/WakeupFd.h +42 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/unix-adapter/main.cc +729 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/unix-adapter/subdir.mk +41 -0
- package/.output/server/node_modules/node-pty/deps/winpty/src/winpty.gyp +234 -0
- package/.output/server/node_modules/node-pty/deps/winpty/vcbuild.bat +83 -0
- package/.output/server/node_modules/node-pty/lib/conpty_console_list_agent.js +16 -0
- package/.output/server/node_modules/node-pty/lib/conpty_console_list_agent.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/eventEmitter2.js +47 -0
- package/.output/server/node_modules/node-pty/lib/eventEmitter2.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/eventEmitter2.test.js +30 -0
- package/.output/server/node_modules/node-pty/lib/eventEmitter2.test.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/index.js +52 -0
- package/.output/server/node_modules/node-pty/lib/index.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/interfaces.js +7 -0
- package/.output/server/node_modules/node-pty/lib/interfaces.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/shared/conout.js +11 -0
- package/.output/server/node_modules/node-pty/lib/shared/conout.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/terminal.js +190 -0
- package/.output/server/node_modules/node-pty/lib/terminal.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/terminal.test.js +139 -0
- package/.output/server/node_modules/node-pty/lib/terminal.test.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/testUtils.test.js +28 -0
- package/.output/server/node_modules/node-pty/lib/testUtils.test.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/types.js +7 -0
- package/.output/server/node_modules/node-pty/lib/types.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/unixTerminal.js +346 -0
- package/.output/server/node_modules/node-pty/lib/unixTerminal.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/unixTerminal.test.js +351 -0
- package/.output/server/node_modules/node-pty/lib/unixTerminal.test.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/utils.js +39 -0
- package/.output/server/node_modules/node-pty/lib/utils.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/windowsConoutConnection.js +125 -0
- package/.output/server/node_modules/node-pty/lib/windowsConoutConnection.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/windowsPtyAgent.js +320 -0
- package/.output/server/node_modules/node-pty/lib/windowsPtyAgent.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/windowsPtyAgent.test.js +90 -0
- package/.output/server/node_modules/node-pty/lib/windowsPtyAgent.test.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/windowsTerminal.js +199 -0
- package/.output/server/node_modules/node-pty/lib/windowsTerminal.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/windowsTerminal.test.js +219 -0
- package/.output/server/node_modules/node-pty/lib/windowsTerminal.test.js.map +1 -0
- package/.output/server/node_modules/node-pty/lib/worker/conoutSocketWorker.js +22 -0
- package/.output/server/node_modules/node-pty/lib/worker/conoutSocketWorker.js.map +1 -0
- package/.output/server/node_modules/node-pty/package.json +64 -0
- package/.output/server/node_modules/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/darwin-x64/pty.node +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/conpty.pdb +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.pdb +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/pty.node +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/pty.pdb +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/winpty-agent.exe +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/winpty-agent.pdb +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/winpty.dll +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-arm64/winpty.pdb +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/conpty.node +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/conpty.pdb +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.pdb +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/pty.node +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/pty.pdb +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/winpty-agent.exe +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/winpty-agent.pdb +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/winpty.dll +0 -0
- package/.output/server/node_modules/node-pty/prebuilds/win32-x64/winpty.pdb +0 -0
- package/.output/server/node_modules/node-pty/scripts/gen-compile-commands.js +8 -0
- package/.output/server/node_modules/node-pty/scripts/increment-version.js +54 -0
- package/.output/server/node_modules/node-pty/scripts/post-install.js +80 -0
- package/.output/server/node_modules/node-pty/scripts/prebuild.js +34 -0
- package/.output/server/node_modules/node-pty/src/conpty_console_list_agent.ts +15 -0
- package/.output/server/node_modules/node-pty/src/eventEmitter2.test.ts +30 -0
- package/.output/server/node_modules/node-pty/src/eventEmitter2.ts +48 -0
- package/.output/server/node_modules/node-pty/src/index.ts +52 -0
- package/.output/server/node_modules/node-pty/src/interfaces.ts +130 -0
- package/.output/server/node_modules/node-pty/src/native.d.ts +54 -0
- package/.output/server/node_modules/node-pty/src/shared/conout.ts +15 -0
- package/.output/server/node_modules/node-pty/src/terminal.test.ts +119 -0
- package/.output/server/node_modules/node-pty/src/terminal.ts +211 -0
- package/.output/server/node_modules/node-pty/src/testUtils.test.ts +23 -0
- package/.output/server/node_modules/node-pty/src/tsconfig.json +22 -0
- package/.output/server/node_modules/node-pty/src/types.ts +15 -0
- package/.output/server/node_modules/node-pty/src/unix/pty.cc +799 -0
- package/.output/server/node_modules/node-pty/src/unix/spawn-helper.cc +23 -0
- package/.output/server/node_modules/node-pty/src/unixTerminal.test.ts +367 -0
- package/.output/server/node_modules/node-pty/src/unixTerminal.ts +388 -0
- package/.output/server/node_modules/node-pty/src/utils.ts +29 -0
- package/.output/server/node_modules/node-pty/src/win/conpty.cc +583 -0
- package/.output/server/node_modules/node-pty/src/win/conpty.h +41 -0
- package/.output/server/node_modules/node-pty/src/win/conpty_console_list.cc +44 -0
- package/.output/server/node_modules/node-pty/src/win/path_util.cc +95 -0
- package/.output/server/node_modules/node-pty/src/win/path_util.h +26 -0
- package/.output/server/node_modules/node-pty/src/win/winpty.cc +333 -0
- package/.output/server/node_modules/node-pty/src/windowsConoutConnection.ts +82 -0
- package/.output/server/node_modules/node-pty/src/windowsPtyAgent.test.ts +94 -0
- package/.output/server/node_modules/node-pty/src/windowsPtyAgent.ts +321 -0
- package/.output/server/node_modules/node-pty/src/windowsTerminal.test.ts +229 -0
- package/.output/server/node_modules/node-pty/src/windowsTerminal.ts +203 -0
- package/.output/server/node_modules/node-pty/src/worker/conoutSocketWorker.ts +22 -0
- package/.output/server/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/OpenConsole.exe +0 -0
- package/.output/server/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/conpty.dll +0 -0
- package/.output/server/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/OpenConsole.exe +0 -0
- package/.output/server/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/conpty.dll +0 -0
- package/.output/server/node_modules/node-pty/typings/node-pty.d.ts +211 -0
- package/.output/server/package.json +1 -0
- package/package.json +11 -4
- package/.output/public/assets/routes-DynLhCvj.js +0 -2195
- package/.output/public/assets/styles-DJ9ubgcc.css +0 -2
- package/scripts/patch-react-jsx-dev-runtime.mjs +0 -93
- /package/.output/public/assets/{wasm-CEUrWlVz.js → wasm-D_MQmneJ.js} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { i as __toESM } from "../_runtime.mjs";
|
|
2
2
|
import { $ as require_react, A as TabsTab, B as Input, C as MenuPositioner, D as MenuGroupLabel, E as MenuItem, F as DialogPopup, H as useRender, I as DialogDescription$1, L as DialogClose$1, M as DialogTitle$1, N as DialogRoot, O as MenuGroup, P as DialogPortal$1, Q as require_jsx_runtime, R as DialogBackdrop, S as MenuRoot, T as MenuPopup, V as Button, Y as mergeProps, _ as AccordionItem$1, a as ContextMenuRoot, b as MenuTrigger, c as CollapsibleRoot, d as PopoverPortal, f as PopoverTrigger$1, g as AccordionHeader, h as AccordionTrigger$1, i as ContextMenuTrigger$1, j as TabsRoot, k as TabsList$1, l as PopoverPopup, m as AccordionPanel, n as ToggleGroup, o as CollapsiblePanel, p as PopoverRoot, r as Toggle, s as CollapsibleTrigger$1, t as AlertDialogRoot, u as PopoverPositioner, v as AccordionRoot, w as MenuPortal, x as MenuSubmenuRoot, y as MenuSubmenuTrigger, z as Separator } from "../_libs/@base-ui/react+[...].mjs";
|
|
3
3
|
import { t as cva } from "../_libs/class-variance-authority+clsx.mjs";
|
|
4
|
-
import { A as
|
|
5
|
-
import { $ as
|
|
4
|
+
import { A as Folder, B as ChevronsUpDown, C as ListStart, D as GitPullRequestArrow, E as ImagePlus, F as EllipsisVertical, G as Check, I as Download, J as ArrowUpRight, K as ArrowUp, L as Copy, M as FileDiff, N as ExternalLink, O as GitBranch, P as Ellipsis, R as Command, S as Maximize2, U as ChevronRight, V as ChevronsDownUp, W as ChevronDown, X as ArrowLeft, Z as ArrowDown, _ as PanelLeftClose, a as TriangleAlert, b as Minus, c as Square, d as Settings2, f as Search, g as PanelLeftOpen, h as PanelLeft, i as Undo2, j as FolderPlus, k as GitCommitHorizontal, l as SquareTerminal, m as PanelRight, n as WandSparkles, o as Trash2, p as Plus, q as ArrowUpToLine, r as Upload, s as Tag, t as X, u as SquarePen, w as ListEnd, x as Minimize2, y as OctagonX } from "../_libs/lucide-react.mjs";
|
|
5
|
+
import { $ as normalizeSessionSelectionKeys, A as THEME_STORAGE_KEY, At as themeFamilyDescription, B as buildItemsFromSync, C as SESSION_DONE_SOUND_ENABLED_STORAGE_KEY, Ct as rememberStoredPromptDraft, D as TERMINAL_PANEL_OPEN_STORAGE_KEY, Dt as sameContextUsage, E as TERMINAL_PANEL_HEIGHT_STORAGE_KEY, Et as safeLocalStorageSetItem, F as TooltipTrigger, Ft as thinkingSummaryText, G as exploreShellCommandNameFromTool, I as VIEWER_CONTEXT_STORAGE_KEY, It as toolArgsAreIncompleteJsonObject, L as appliedThemeClass, Lt as toolCategoryFromTool, M as Tooltip$1, Mt as themeFamilyKeywords, N as TooltipContent, Nt as themeFamilyLabel, O as THEME_COLOR_MODE_STORAGE_KEY, Ot as sessionListEntryKey, Pt as themeFamilySupportsColorMode, Q as normalizePromptImage, R as appliedThemeClassColorMode, Rt as toolCouldBecomeExploreFromTool, S as SESSION_DONE_DESKTOP_NOTIFICATIONS_ENABLED_STORAGE_KEY, St as readStoredThemeColorMode, T as Spinner, Tt as safeLocalStorageGetItem, U as createContextId, V as cn, W as createInitialSessionState, X as getSessionTitle, Y as flattenTree, _ as RIGHT_SIDEBAR_HISTORY_HEIGHT_STORAGE_KEY, _t as readStoredSessionDoneSoundEnabled, a as COLLAPSED_DIRECTORIES_STORAGE_KEY, at as promptDraftKeyMatchesOwner, b as RIGHT_SIDEBAR_WIDTHS_STORAGE_KEY, bt as readStoredTerminalTabs, c as Kbd, ct as readStoredCenterMessages, d as PICO_DIFF_SHIKI_THEMES, dt as readStoredHideToolBlocks, et as normalizeStoredDirectoryList, f as PICO_SHIKI_VARIABLE_DEFAULTS, ft as readStoredPinnedSessionKeys, g as RIGHT_SIDEBAR_FILE_TREE_WIDTH_STORAGE_KEY, gt as readStoredSessionDoneDesktopNotificationsEnabled, h as RIGHT_SIDEBAR_ACTIVE_TAB_STORAGE_KEY, ht as readStoredRightSidebarOpen, i as CENTER_MESSAGES_STORAGE_KEY, it as promptDraftKey, j as TitleTooltip, jt as themeFamilyFixedMode, k as THEME_FAMILIES, kt as themeColorModeLabel, l as KeyboardShortcutContent, lt as readStoredCollapsedDirectories, m as RECENT_DIRECTORIES_STORAGE_KEY, mt as readStoredRecentDirectories, n as APPLIED_THEME_STORAGE_KEY, nt as normalizeThemeFamily, o as DRAFT_DIRECTORY_STORAGE_KEY, ot as rawShellCommandTextFromTool, p as PINNED_SESSIONS_STORAGE_KEY, pt as readStoredPromptDraft, r as AUTO_SCROLL_ENABLED_STORAGE_KEY, rt as previewUrlForImage, s as HIDE_TOOL_BLOCKS_STORAGE_KEY, st as readStoredAutoScrollEnabled, tt as normalizeThemeColorMode, ut as readStoredDraftDirectory, v as RIGHT_SIDEBAR_HISTORY_TAB_STORAGE_KEY, vt as readStoredSidebarDirectories, w as SIDEBAR_DIRECTORIES_STORAGE_KEY, wt as rememberStoredTerminalTabs, x as Route, xt as readStoredTheme, y as RIGHT_SIDEBAR_OPEN_STORAGE_KEY, yt as readStoredTerminalPanelOpen } from "./routes-CuWg5WTI.mjs";
|
|
6
6
|
import { i as useQuery, n as useIsMutating, o as useQueryClient, r as useIsFetching, t as useMutation } from "../_libs/tanstack__react-query.mjs";
|
|
7
7
|
import { t as useHotkeys } from "../_libs/tanstack__react-hotkeys.mjs";
|
|
8
8
|
import { a as matchesKeyboardEvent, i as batch, o as formatForDisplay, r as createStore } from "../_libs/@tanstack/hotkeys+[...].mjs";
|
|
@@ -22,7 +22,7 @@ import { t as remarkGfm } from "../_libs/remark-gfm.mjs";
|
|
|
22
22
|
import { a as getBuiltInSpriteSheet, i as getBuiltInFileIconColor, n as FileTree, r as createFileTreeIconResolver, t as useFileTree } from "../_libs/@pierre/trees+[...].mjs";
|
|
23
23
|
import { a as closestCenter, c as useDraggable, d as useSensors, f as CSS$1, i as PointerSensor, n as DragOverlay, t as DndContext, u as useSensor } from "../_libs/@dnd-kit/core+[...].mjs";
|
|
24
24
|
import { a as verticalListSortingStrategy, i as useSortable, n as arrayMove, r as horizontalListSortingStrategy, t as SortableContext } from "../_libs/dnd-kit__sortable.mjs";
|
|
25
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/routes-
|
|
25
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/routes-DySm_W8N.js
|
|
26
26
|
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
27
27
|
var import_jsx_runtime = require_jsx_runtime();
|
|
28
28
|
var MOBILE_BREAKPOINT = 768;
|
|
@@ -503,8 +503,9 @@ function SidebarProvider({ defaultOpen = true, open: openProp, onOpenChange: set
|
|
|
503
503
|
window.addEventListener("keydown", handleKeyDown);
|
|
504
504
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
505
505
|
}, [toggleSidebarRef]);
|
|
506
|
+
const state = open ? "expanded" : "collapsed";
|
|
506
507
|
const contextValue = {
|
|
507
|
-
state
|
|
508
|
+
state,
|
|
508
509
|
open,
|
|
509
510
|
setOpen,
|
|
510
511
|
isMobile,
|
|
@@ -522,6 +523,7 @@ function SidebarProvider({ defaultOpen = true, open: openProp, onOpenChange: set
|
|
|
522
523
|
value: contextValue,
|
|
523
524
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
524
525
|
"data-slot": "sidebar-wrapper",
|
|
526
|
+
"data-sidebar-state": state,
|
|
525
527
|
style: {
|
|
526
528
|
...style,
|
|
527
529
|
"--sidebar-width": sidebarWidth,
|
|
@@ -10618,10 +10620,9 @@ var PICO_DIFF_COLOR_CSS = `
|
|
|
10618
10620
|
--diffs-bg-deletion-emphasis-override: color-mix(in lab, var(--diffs-bg) 42%, var(--diffs-deletion-base));
|
|
10619
10621
|
}
|
|
10620
10622
|
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
}
|
|
10623
|
+
[data-overflow="wrap"] [data-annotation-content] {
|
|
10624
|
+
inline-size: var(--diffs-column-content-width, auto);
|
|
10625
|
+
max-inline-size: min(100%, calc(100vw - 1rem));
|
|
10625
10626
|
}
|
|
10626
10627
|
|
|
10627
10628
|
[data-line-type="change-addition"]:is(
|
|
@@ -10813,22 +10814,7 @@ function formatToolArgString(value) {
|
|
|
10813
10814
|
return trimmed;
|
|
10814
10815
|
}
|
|
10815
10816
|
function rawShellCommandText(block) {
|
|
10816
|
-
|
|
10817
|
-
if (typeof block.args === "string") {
|
|
10818
|
-
const trimmed = block.args.trim();
|
|
10819
|
-
if (!trimmed) return "";
|
|
10820
|
-
try {
|
|
10821
|
-
const parsed = JSON.parse(trimmed);
|
|
10822
|
-
if (parsed && typeof parsed === "object" && "command" in parsed) {
|
|
10823
|
-
const command = parsed.command;
|
|
10824
|
-
return typeof command === "string" ? command.trim() : trimmed;
|
|
10825
|
-
}
|
|
10826
|
-
} catch {
|
|
10827
|
-
return trimmed;
|
|
10828
|
-
}
|
|
10829
|
-
return trimmed;
|
|
10830
|
-
}
|
|
10831
|
-
return getToolArgText(normalizeToolArgs(block.args), "command") || toolCommandPreview(block);
|
|
10817
|
+
return block.type === "tool" ? rawShellCommandTextFromTool(block.name, block.args) : "";
|
|
10832
10818
|
}
|
|
10833
10819
|
function toolCallText(block) {
|
|
10834
10820
|
if (block.type !== "tool") return "";
|
|
@@ -10862,64 +10848,12 @@ function toolOutputText(block) {
|
|
|
10862
10848
|
if (block.isError) return "Tool failed with no output.";
|
|
10863
10849
|
return "No output available.";
|
|
10864
10850
|
}
|
|
10865
|
-
var EXPLORE_TOOL_NAMES = new Set([
|
|
10866
|
-
"read",
|
|
10867
|
-
"grep",
|
|
10868
|
-
"glob",
|
|
10869
|
-
"find",
|
|
10870
|
-
"ls",
|
|
10871
|
-
"list",
|
|
10872
|
-
"rg"
|
|
10873
|
-
]);
|
|
10874
|
-
var EXPLORE_SHELL_COMMAND_NAMES = new Set([
|
|
10875
|
-
"find",
|
|
10876
|
-
"grep",
|
|
10877
|
-
"ls",
|
|
10878
|
-
"rg"
|
|
10879
|
-
]);
|
|
10880
|
-
var SKIPPABLE_SHELL_COMMAND_NAMES = new Set([
|
|
10881
|
-
"cd",
|
|
10882
|
-
"export",
|
|
10883
|
-
"pwd",
|
|
10884
|
-
"set"
|
|
10885
|
-
]);
|
|
10886
|
-
var SHELL_COMMAND_WRAPPER_NAMES = new Set([
|
|
10887
|
-
"command",
|
|
10888
|
-
"env",
|
|
10889
|
-
"noglob",
|
|
10890
|
-
"sudo",
|
|
10891
|
-
"time"
|
|
10892
|
-
]);
|
|
10893
|
-
function shellCommandNameFromSegment(segment) {
|
|
10894
|
-
let text = segment.trim();
|
|
10895
|
-
while (text) {
|
|
10896
|
-
const assignmentMatch = text.match(/^[A-Za-z_][A-Za-z0-9_]*=\S+\s+/);
|
|
10897
|
-
if (assignmentMatch) {
|
|
10898
|
-
text = text.slice(assignmentMatch[0].length).trimStart();
|
|
10899
|
-
continue;
|
|
10900
|
-
}
|
|
10901
|
-
const commandMatch = text.match(/^([./A-Za-z0-9_-]+)\b/);
|
|
10902
|
-
if (!commandMatch) return "";
|
|
10903
|
-
const commandPath = commandMatch[1] || "";
|
|
10904
|
-
const commandName = pathBaseName$1(commandPath);
|
|
10905
|
-
if (!SHELL_COMMAND_WRAPPER_NAMES.has(commandName)) return commandName;
|
|
10906
|
-
text = text.slice(commandPath.length).trimStart();
|
|
10907
|
-
}
|
|
10908
|
-
return "";
|
|
10909
|
-
}
|
|
10910
10851
|
function exploreShellCommandName(block) {
|
|
10911
|
-
|
|
10912
|
-
const segments = rawShellCommandText(block).split(/(?:&&|\|\||;)/);
|
|
10913
|
-
for (const segment of segments) {
|
|
10914
|
-
const commandName = shellCommandNameFromSegment(segment);
|
|
10915
|
-
if (!commandName || SKIPPABLE_SHELL_COMMAND_NAMES.has(commandName)) continue;
|
|
10916
|
-
return EXPLORE_SHELL_COMMAND_NAMES.has(commandName) ? commandName : "";
|
|
10917
|
-
}
|
|
10918
|
-
return "";
|
|
10852
|
+
return block.type === "tool" ? exploreShellCommandNameFromTool(block.name, block.args) : "";
|
|
10919
10853
|
}
|
|
10920
10854
|
function matchesExploreToolBlock(block) {
|
|
10921
10855
|
if (block.type !== "tool") return false;
|
|
10922
|
-
return block.category === "explore" ||
|
|
10856
|
+
return block.category === "explore" || toolCategoryFromTool(block.name, block.args) === "explore";
|
|
10923
10857
|
}
|
|
10924
10858
|
function isExploreToolBlock(block) {
|
|
10925
10859
|
return matchesExploreToolBlock(block);
|
|
@@ -10927,7 +10861,10 @@ function isExploreToolBlock(block) {
|
|
|
10927
10861
|
function isPendingUnclassifiedToolBlock(block) {
|
|
10928
10862
|
if (block.type !== "tool" || !block.running || matchesExploreToolBlock(block)) return false;
|
|
10929
10863
|
if (!block.name) return true;
|
|
10930
|
-
if (block.name === "bash")
|
|
10864
|
+
if (block.name === "bash") {
|
|
10865
|
+
const category = toolCategoryFromTool(block.name, block.args);
|
|
10866
|
+
return !rawShellCommandText(block) || category !== "explore" && (toolArgsAreIncompleteJsonObject(block.args) || toolCouldBecomeExploreFromTool(block.name, block.args));
|
|
10867
|
+
}
|
|
10931
10868
|
return false;
|
|
10932
10869
|
}
|
|
10933
10870
|
function getToolArgNumber(args, key) {
|
|
@@ -11725,7 +11662,7 @@ function PlainToolOutput({ isError = false, text }) {
|
|
|
11725
11662
|
children: text
|
|
11726
11663
|
});
|
|
11727
11664
|
}
|
|
11728
|
-
function scrollDistanceFromBottom(element) {
|
|
11665
|
+
function scrollDistanceFromBottom$1(element) {
|
|
11729
11666
|
return element.scrollHeight - element.clientHeight - element.scrollTop;
|
|
11730
11667
|
}
|
|
11731
11668
|
function scrollElementToBottom(element) {
|
|
@@ -11749,7 +11686,7 @@ function useRunningToolAutoScroll({ contentKey, enabled }) {
|
|
|
11749
11686
|
}, [contentKey, enabled]);
|
|
11750
11687
|
const handleScroll = (event) => {
|
|
11751
11688
|
if (!enabled) return;
|
|
11752
|
-
autoScrollRef.current = scrollDistanceFromBottom(event.currentTarget) < 1;
|
|
11689
|
+
autoScrollRef.current = scrollDistanceFromBottom$1(event.currentTarget) < 1;
|
|
11753
11690
|
};
|
|
11754
11691
|
return {
|
|
11755
11692
|
onScroll: handleScroll,
|
|
@@ -12055,53 +11992,67 @@ var UserMessageCard = import_react.memo(function UserMessageCard({ item }) {
|
|
|
12055
11992
|
const selectedImage = selectedImageIndex === null ? null : item.images[selectedImageIndex] ?? null;
|
|
12056
11993
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12057
11994
|
className: "mr-2 ml-auto w-fit max-w-[80%]",
|
|
12058
|
-
children: [
|
|
12059
|
-
|
|
12060
|
-
|
|
12061
|
-
|
|
12062
|
-
|
|
12063
|
-
|
|
12064
|
-
|
|
12065
|
-
|
|
12066
|
-
|
|
12067
|
-
|
|
12068
|
-
|
|
12069
|
-
|
|
12070
|
-
|
|
12071
|
-
|
|
12072
|
-
|
|
12073
|
-
|
|
12074
|
-
|
|
12075
|
-
|
|
12076
|
-
|
|
12077
|
-
|
|
12078
|
-
|
|
12079
|
-
|
|
12080
|
-
|
|
12081
|
-
|
|
12082
|
-
|
|
12083
|
-
|
|
12084
|
-
|
|
12085
|
-
|
|
12086
|
-
|
|
12087
|
-
|
|
12088
|
-
|
|
12089
|
-
|
|
12090
|
-
|
|
12091
|
-
|
|
12092
|
-
|
|
12093
|
-
|
|
12094
|
-
|
|
12095
|
-
|
|
12096
|
-
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
|
|
12100
|
-
|
|
12101
|
-
|
|
12102
|
-
|
|
11995
|
+
children: [
|
|
11996
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11997
|
+
className: "relative rounded-3xl bg-primary px-5 py-2.5 text-primary-foreground before:absolute before:-right-1.75 before:bottom-0 before:h-5.5 before:w-4 before:rounded-bl-[16px_14px] before:bg-primary before:content-[''] after:absolute after:-right-6.5 after:bottom-0 after:h-6.25 after:w-6.5 after:rounded-bl-[10px] after:bg-background after:content-['']",
|
|
11998
|
+
children: [
|
|
11999
|
+
labelText ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12000
|
+
className: "mb-2 flex items-center gap-2",
|
|
12001
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
|
|
12002
|
+
variant: "outline",
|
|
12003
|
+
className: "border-primary-foreground/35 bg-primary-foreground/10 text-primary-foreground",
|
|
12004
|
+
children: labelText
|
|
12005
|
+
})
|
|
12006
|
+
}) : null,
|
|
12007
|
+
item.text ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12008
|
+
className: "text-sm break-words whitespace-pre-wrap text-primary-foreground",
|
|
12009
|
+
children: item.text
|
|
12010
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12011
|
+
className: "text-sm text-primary-foreground/80",
|
|
12012
|
+
children: "Image prompt"
|
|
12013
|
+
}),
|
|
12014
|
+
item.images.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12015
|
+
className: "mt-3 flex flex-wrap gap-3",
|
|
12016
|
+
children: item.images.map((image, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
12017
|
+
type: "button",
|
|
12018
|
+
className: "max-w-full cursor-zoom-in overflow-hidden rounded-lg border border-primary-foreground/20 bg-primary-foreground/10 p-0 transition hover:opacity-90 focus-visible:ring-2 focus-visible:ring-primary-foreground/70 focus-visible:ring-offset-2 focus-visible:ring-offset-primary focus-visible:outline-none",
|
|
12019
|
+
onClick: () => setSelectedImageIndex(index),
|
|
12020
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
|
|
12021
|
+
src: image.previewUrl,
|
|
12022
|
+
alt: "Prompt upload",
|
|
12023
|
+
className: "block h-28 max-w-full object-cover"
|
|
12024
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
12025
|
+
className: "sr-only",
|
|
12026
|
+
children: "Open prompt upload"
|
|
12027
|
+
})]
|
|
12028
|
+
}, `${promptImageKey(image)}:${index}`))
|
|
12029
|
+
}) : null
|
|
12030
|
+
]
|
|
12031
|
+
}),
|
|
12032
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(UserMessageFooter, { copyText: item.text }),
|
|
12033
|
+
selectedImage ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImageLightbox, {
|
|
12034
|
+
open: true,
|
|
12035
|
+
onOpenChange: (open) => {
|
|
12036
|
+
if (!open) setSelectedImageIndex(null);
|
|
12037
|
+
},
|
|
12038
|
+
imageSrc: selectedImage.previewUrl,
|
|
12039
|
+
imageAlt: "Prompt upload",
|
|
12040
|
+
title: "Prompt upload preview",
|
|
12041
|
+
description: "Expanded preview of an image attached to a user message."
|
|
12042
|
+
}) : null
|
|
12043
|
+
]
|
|
12103
12044
|
});
|
|
12104
12045
|
});
|
|
12046
|
+
function UserMessageFooter({ copyText }) {
|
|
12047
|
+
if (!copyText.trim()) return null;
|
|
12048
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12049
|
+
className: "mt-1 flex justify-end gap-1.5 text-xs font-medium text-muted-foreground",
|
|
12050
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MessageFooterCopyButton, {
|
|
12051
|
+
idleLabel: "Copy user message",
|
|
12052
|
+
text: copyText
|
|
12053
|
+
})
|
|
12054
|
+
});
|
|
12055
|
+
}
|
|
12105
12056
|
function assistantBlockIsVisible({ block, hideThinking, hideToolBlocks }) {
|
|
12106
12057
|
switch (block.type) {
|
|
12107
12058
|
case "text": return Boolean(block.text.trim());
|
|
@@ -12200,7 +12151,7 @@ function AssistantBlockGroupsView({ anchorBlockKey, store, streaming }) {
|
|
|
12200
12151
|
streaming
|
|
12201
12152
|
}, descriptor.key)) });
|
|
12202
12153
|
}
|
|
12203
|
-
function
|
|
12154
|
+
function MessageFooterCopyButton({ className, idleLabel, text }) {
|
|
12204
12155
|
const [copyState, setCopyState] = import_react.useState("idle");
|
|
12205
12156
|
const canCopy = Boolean(text.trim());
|
|
12206
12157
|
const copyMessage = async () => {
|
|
@@ -12214,13 +12165,13 @@ function AssistantMessageFooterCopyButton({ text }) {
|
|
|
12214
12165
|
window.setTimeout(() => setCopyState("idle"), 1400);
|
|
12215
12166
|
}
|
|
12216
12167
|
};
|
|
12217
|
-
const label = copyState === "copied" ? "Copied" : copyState === "error" ? "Retry copy" :
|
|
12168
|
+
const label = copyState === "copied" ? "Copied" : copyState === "error" ? "Retry copy" : idleLabel;
|
|
12218
12169
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
12219
12170
|
title: label,
|
|
12220
12171
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
12221
12172
|
variant: "ghost",
|
|
12222
12173
|
size: "icon-xs",
|
|
12223
|
-
className: "
|
|
12174
|
+
className: cn("text-muted-foreground", className),
|
|
12224
12175
|
disabled: !canCopy,
|
|
12225
12176
|
"aria-label": label,
|
|
12226
12177
|
onClick: copyMessage,
|
|
@@ -12234,7 +12185,11 @@ function AssistantMessageFooter({ copyText, modelLabel, streaming }) {
|
|
|
12234
12185
|
if (!showCopyButton && !modelLabel) return null;
|
|
12235
12186
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12236
12187
|
className: "-mt-2 flex items-center gap-1.5 text-xs font-medium text-muted-foreground",
|
|
12237
|
-
children: [showCopyButton ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
12188
|
+
children: [showCopyButton ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MessageFooterCopyButton, {
|
|
12189
|
+
className: "-ml-2",
|
|
12190
|
+
idleLabel: "Copy assistant message",
|
|
12191
|
+
text: copyText
|
|
12192
|
+
}) : null, modelLabel ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
12238
12193
|
className: "truncate",
|
|
12239
12194
|
children: modelLabel
|
|
12240
12195
|
}) : null]
|
|
@@ -12264,7 +12219,7 @@ function AssistantMessagesStoreCard({ className, hideFooter = false, store }) {
|
|
|
12264
12219
|
store
|
|
12265
12220
|
]);
|
|
12266
12221
|
const shellSnapshot = import_react.useSyncExternalStore(shellStore.subscribe, shellStore.getSnapshot, shellStore.getSnapshot);
|
|
12267
|
-
const showFooter = Boolean(!hideFooter && !shellSnapshot.
|
|
12222
|
+
const showFooter = Boolean(!hideFooter && !shellSnapshot.working && shellSnapshot.hasFooter);
|
|
12268
12223
|
if (!shellSnapshot.hasBlocks && !showFooter) return null;
|
|
12269
12224
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12270
12225
|
className: cn("flex flex-col gap-4", className),
|
|
@@ -14593,6 +14548,78 @@ function useAppShellMessageScroll({ autoScrollEnabled, isSessionViewLoading, ses
|
|
|
14593
14548
|
syncAfterConversationChange
|
|
14594
14549
|
};
|
|
14595
14550
|
}
|
|
14551
|
+
var DEFAULT_SCROLL_GRADIENT_MAX_HEIGHT = 4;
|
|
14552
|
+
var EMPTY_SCROLL_GRADIENT_STATE = {
|
|
14553
|
+
bottomHeight: 0,
|
|
14554
|
+
topHeight: 0
|
|
14555
|
+
};
|
|
14556
|
+
function scrollDistanceFromBottom(element) {
|
|
14557
|
+
return Math.max(0, element.scrollHeight - element.scrollTop - element.clientHeight);
|
|
14558
|
+
}
|
|
14559
|
+
function scrollGradientHeight(distanceFromEdge, maxHeight) {
|
|
14560
|
+
return Math.min(maxHeight, Math.max(0, distanceFromEdge));
|
|
14561
|
+
}
|
|
14562
|
+
function scrollGradientState(element, maxHeight) {
|
|
14563
|
+
if (!element) return EMPTY_SCROLL_GRADIENT_STATE;
|
|
14564
|
+
return {
|
|
14565
|
+
bottomHeight: scrollGradientHeight(scrollDistanceFromBottom(element), maxHeight),
|
|
14566
|
+
topHeight: scrollGradientHeight(element.scrollTop, maxHeight)
|
|
14567
|
+
};
|
|
14568
|
+
}
|
|
14569
|
+
function setScrollGradientState(setState, nextState) {
|
|
14570
|
+
setState((currentState) => currentState.bottomHeight === nextState.bottomHeight && currentState.topHeight === nextState.topHeight ? currentState : nextState);
|
|
14571
|
+
}
|
|
14572
|
+
function useScrollGradients({ disabled = false, maxHeight = DEFAULT_SCROLL_GRADIENT_MAX_HEIGHT } = {}) {
|
|
14573
|
+
const elementRef = import_react.useRef(null);
|
|
14574
|
+
const [state, setState] = import_react.useState(EMPTY_SCROLL_GRADIENT_STATE);
|
|
14575
|
+
const syncScrollGradients = import_react.useCallback((element = elementRef.current) => {
|
|
14576
|
+
setScrollGradientState(setState, disabled ? EMPTY_SCROLL_GRADIENT_STATE : scrollGradientState(element, maxHeight));
|
|
14577
|
+
}, [disabled, maxHeight]);
|
|
14578
|
+
const setScrollElement = import_react.useCallback((element) => {
|
|
14579
|
+
elementRef.current = element;
|
|
14580
|
+
syncScrollGradients(element);
|
|
14581
|
+
}, [syncScrollGradients]);
|
|
14582
|
+
const onScroll = import_react.useCallback((event) => {
|
|
14583
|
+
syncScrollGradients(event.currentTarget);
|
|
14584
|
+
}, [syncScrollGradients]);
|
|
14585
|
+
import_react.useLayoutEffect(() => {
|
|
14586
|
+
const element = elementRef.current;
|
|
14587
|
+
syncScrollGradients(element);
|
|
14588
|
+
if (!element || typeof ResizeObserver === "undefined") return;
|
|
14589
|
+
let animationFrame = 0;
|
|
14590
|
+
const scheduleSync = () => {
|
|
14591
|
+
window.cancelAnimationFrame(animationFrame);
|
|
14592
|
+
animationFrame = window.requestAnimationFrame(() => {
|
|
14593
|
+
animationFrame = 0;
|
|
14594
|
+
syncScrollGradients(elementRef.current);
|
|
14595
|
+
});
|
|
14596
|
+
};
|
|
14597
|
+
const resizeObserver = new ResizeObserver(scheduleSync);
|
|
14598
|
+
resizeObserver.observe(element);
|
|
14599
|
+
const content = element.firstElementChild;
|
|
14600
|
+
if (content instanceof HTMLElement) resizeObserver.observe(content);
|
|
14601
|
+
return () => {
|
|
14602
|
+
window.cancelAnimationFrame(animationFrame);
|
|
14603
|
+
resizeObserver.disconnect();
|
|
14604
|
+
};
|
|
14605
|
+
}, [syncScrollGradients]);
|
|
14606
|
+
return {
|
|
14607
|
+
bottomHeight: state.bottomHeight,
|
|
14608
|
+
onScroll,
|
|
14609
|
+
setScrollElement,
|
|
14610
|
+
syncScrollGradients,
|
|
14611
|
+
topHeight: state.topHeight
|
|
14612
|
+
};
|
|
14613
|
+
}
|
|
14614
|
+
function ScrollGradientOverlays({ bottomClassName, bottomHeight, className, topClassName, topHeight }) {
|
|
14615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
14616
|
+
className: cn("pointer-events-none absolute inset-x-0 top-0 z-10 bg-gradient-to-b from-black/10 to-transparent transition-[height,opacity] duration-150", topHeight > 0 ? "opacity-100" : "opacity-0", className, topClassName),
|
|
14617
|
+
style: { height: topHeight }
|
|
14618
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
14619
|
+
className: cn("pointer-events-none absolute inset-x-0 bottom-0 z-10 bg-gradient-to-t from-black/10 to-transparent transition-[height,opacity] duration-150", bottomHeight > 0 ? "opacity-100" : "opacity-0", className, bottomClassName),
|
|
14620
|
+
style: { height: bottomHeight }
|
|
14621
|
+
})] });
|
|
14622
|
+
}
|
|
14596
14623
|
function ConversationLatestMessageButton({ conversationItemsStore, draft, onClick, scrollStateStore }) {
|
|
14597
14624
|
const hasMessages = useConversationHasMessages(conversationItemsStore);
|
|
14598
14625
|
const isDisabled = useMessageScrollValue(scrollStateStore, (snapshot) => draft || !hasMessages || snapshot.isMessagesNearBottom);
|
|
@@ -14659,6 +14686,11 @@ function AppShellConversationFrame({ autoScrollEnabled, children, centerMessages
|
|
|
14659
14686
|
isSessionViewLoading,
|
|
14660
14687
|
sessionState
|
|
14661
14688
|
});
|
|
14689
|
+
const { bottomHeight: conversationScrollBottomGradientHeight, onScroll: onConversationScrollGradientScroll, setScrollElement: setConversationScrollGradientElement, topHeight: conversationScrollTopGradientHeight } = useScrollGradients({ disabled: isSessionViewLoading });
|
|
14690
|
+
const setMessagesScrollAreaElement = import_react.useCallback((element) => {
|
|
14691
|
+
messagesScrollAreaRef.current = element;
|
|
14692
|
+
setConversationScrollGradientElement(element);
|
|
14693
|
+
}, [messagesScrollAreaRef, setConversationScrollGradientElement]);
|
|
14662
14694
|
import_react.useImperativeHandle(ref, () => ({
|
|
14663
14695
|
jumpToNextMessage,
|
|
14664
14696
|
jumpToPreviousMessage,
|
|
@@ -14672,39 +14704,47 @@ function AppShellConversationFrame({ autoScrollEnabled, children, centerMessages
|
|
|
14672
14704
|
]);
|
|
14673
14705
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
14674
14706
|
className: "relative min-h-0 flex-1",
|
|
14675
|
-
children: [
|
|
14676
|
-
|
|
14677
|
-
|
|
14678
|
-
|
|
14679
|
-
|
|
14680
|
-
|
|
14681
|
-
|
|
14682
|
-
|
|
14683
|
-
|
|
14684
|
-
|
|
14685
|
-
|
|
14686
|
-
|
|
14687
|
-
|
|
14688
|
-
|
|
14689
|
-
|
|
14690
|
-
|
|
14691
|
-
|
|
14692
|
-
|
|
14693
|
-
|
|
14694
|
-
|
|
14695
|
-
|
|
14696
|
-
|
|
14697
|
-
|
|
14698
|
-
|
|
14699
|
-
|
|
14700
|
-
|
|
14701
|
-
|
|
14702
|
-
|
|
14703
|
-
|
|
14704
|
-
|
|
14705
|
-
|
|
14706
|
-
|
|
14707
|
-
|
|
14707
|
+
children: [
|
|
14708
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
14709
|
+
ref: setMessagesScrollAreaElement,
|
|
14710
|
+
"data-conversation-viewport": "true",
|
|
14711
|
+
tabIndex: 0,
|
|
14712
|
+
role: "region",
|
|
14713
|
+
"aria-label": "Conversation messages",
|
|
14714
|
+
className: "h-full overflow-x-hidden overflow-y-auto overscroll-contain px-4 outline-none [overflow-anchor:none]",
|
|
14715
|
+
onScroll: onConversationScrollGradientScroll,
|
|
14716
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
14717
|
+
ref: messagesContentRef,
|
|
14718
|
+
className: "flex min-h-full flex-col",
|
|
14719
|
+
children: [
|
|
14720
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConversationScrollRevisionObserver, {
|
|
14721
|
+
conversationItemsStore,
|
|
14722
|
+
disabled: isSessionViewLoading,
|
|
14723
|
+
onRevisionChange: syncAfterConversationChange
|
|
14724
|
+
}),
|
|
14725
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConversationContentChangeContext.Provider, {
|
|
14726
|
+
value: syncAfterConversationChange,
|
|
14727
|
+
children
|
|
14728
|
+
}),
|
|
14729
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: bottomRef })
|
|
14730
|
+
]
|
|
14731
|
+
})
|
|
14732
|
+
}),
|
|
14733
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollGradientOverlays, {
|
|
14734
|
+
bottomHeight: conversationScrollBottomGradientHeight,
|
|
14735
|
+
topHeight: conversationScrollTopGradientHeight
|
|
14736
|
+
}),
|
|
14737
|
+
!isSessionViewLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConversationLatestMessageButton, {
|
|
14738
|
+
conversationItemsStore,
|
|
14739
|
+
draft: sessionState.draft,
|
|
14740
|
+
onClick: scrollConversationToBottom,
|
|
14741
|
+
scrollStateStore
|
|
14742
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConversationPreviousMessageButton, {
|
|
14743
|
+
centerMessages,
|
|
14744
|
+
onClick: jumpToPreviousMessage,
|
|
14745
|
+
scrollStateStore
|
|
14746
|
+
})] }) : null
|
|
14747
|
+
]
|
|
14708
14748
|
});
|
|
14709
14749
|
}
|
|
14710
14750
|
function AppShellWorkingIndicatorLabel({ fallbackLabel, hiddenThinkingPreviewStore, useHiddenThinkingPreview }) {
|
|
@@ -16762,6 +16802,7 @@ function GitRepositorySummary({ viewerContextId, cwd, active, onBranchClick }) {
|
|
|
16762
16802
|
}
|
|
16763
16803
|
function GitPanelToolbar({ viewerContextId, cwd, active }) {
|
|
16764
16804
|
const queryClient = useQueryClient();
|
|
16805
|
+
const isMobile = useIsMobile();
|
|
16765
16806
|
const normalizedCwd = normalizeCwd(cwd);
|
|
16766
16807
|
const [branchDialogOpen, setBranchDialogOpen] = import_react.useState(false);
|
|
16767
16808
|
const [commitDialogOpen, setCommitDialogOpen] = import_react.useState(false);
|
|
@@ -16875,6 +16916,7 @@ function GitPanelToolbar({ viewerContextId, cwd, active }) {
|
|
|
16875
16916
|
kbd: formatShortcutLabel("Control+C"),
|
|
16876
16917
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
|
|
16877
16918
|
variant: "outline",
|
|
16919
|
+
size: isMobile ? "default" : "sm",
|
|
16878
16920
|
onClick: () => {
|
|
16879
16921
|
setCommitDialogOpen(true);
|
|
16880
16922
|
},
|
|
@@ -16886,6 +16928,7 @@ function GitPanelToolbar({ viewerContextId, cwd, active }) {
|
|
|
16886
16928
|
kbd: formatShortcutLabel("Control+P"),
|
|
16887
16929
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
|
|
16888
16930
|
variant: "outline",
|
|
16931
|
+
size: isMobile ? "default" : "sm",
|
|
16889
16932
|
disabled: gitActionBusy,
|
|
16890
16933
|
onClick: () => {
|
|
16891
16934
|
gitActionMutation.mutate("push");
|
|
@@ -16898,6 +16941,7 @@ function GitPanelToolbar({ viewerContextId, cwd, active }) {
|
|
|
16898
16941
|
kbd: formatShortcutLabel("Control+Shift+P"),
|
|
16899
16942
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
|
|
16900
16943
|
variant: "outline",
|
|
16944
|
+
size: isMobile ? "default" : "sm",
|
|
16901
16945
|
disabled: gitActionBusy,
|
|
16902
16946
|
onClick: () => {
|
|
16903
16947
|
gitActionMutation.mutate("force-push");
|
|
@@ -16910,6 +16954,7 @@ function GitPanelToolbar({ viewerContextId, cwd, active }) {
|
|
|
16910
16954
|
kbd: formatShortcutLabel("Alt+P"),
|
|
16911
16955
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
|
|
16912
16956
|
variant: "outline",
|
|
16957
|
+
size: isMobile ? "default" : "sm",
|
|
16913
16958
|
disabled: gitActionBusy,
|
|
16914
16959
|
onClick: () => {
|
|
16915
16960
|
gitActionMutation.mutate("pull");
|
|
@@ -17018,26 +17063,6 @@ function AlertDialogCancel({ className, variant = "outline", size = "default", .
|
|
|
17018
17063
|
...props
|
|
17019
17064
|
});
|
|
17020
17065
|
}
|
|
17021
|
-
function setDerivedScrollState(setState, nextState) {
|
|
17022
|
-
setState((current) => Object.is(current, nextState) ? current : nextState);
|
|
17023
|
-
}
|
|
17024
|
-
function hasScrolledContent(scrollElement) {
|
|
17025
|
-
return Boolean(scrollElement && scrollElement.scrollTop > 0);
|
|
17026
|
-
}
|
|
17027
|
-
function hasRemainingScrollContent(scrollElement) {
|
|
17028
|
-
if (!scrollElement) return false;
|
|
17029
|
-
return scrollElement.scrollHeight - scrollElement.clientHeight - scrollElement.scrollTop > 1;
|
|
17030
|
-
}
|
|
17031
|
-
function getStuckScrollTriggerValue({ getValue, scrollElement, selector }) {
|
|
17032
|
-
if (!scrollElement || scrollElement.scrollTop <= 0) return "";
|
|
17033
|
-
const containerTop = scrollElement.getBoundingClientRect().top;
|
|
17034
|
-
const triggers = Array.from(scrollElement.querySelectorAll(selector));
|
|
17035
|
-
for (const trigger of triggers) {
|
|
17036
|
-
const rect = trigger.getBoundingClientRect();
|
|
17037
|
-
if (rect.top <= containerTop + 1 && rect.bottom > containerTop + 1) return getValue(trigger);
|
|
17038
|
-
}
|
|
17039
|
-
return "";
|
|
17040
|
-
}
|
|
17041
17066
|
function GitSection({ title, meta, controls, className, bodyClassName, children }) {
|
|
17042
17067
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
|
|
17043
17068
|
className: cn("overflow-hidden rounded-xl border border-border/80 bg-card/50", className),
|
|
@@ -17081,10 +17106,7 @@ var initialGitCommitRowState = {
|
|
|
17081
17106
|
formDialog: null,
|
|
17082
17107
|
confirmDialog: null,
|
|
17083
17108
|
contextMenuOpen: false,
|
|
17084
|
-
contextMenuKey: 0
|
|
17085
|
-
scrollValue: "",
|
|
17086
|
-
commitBodyHeaderShadowed: false,
|
|
17087
|
-
commitBodyFooterShadowed: false
|
|
17109
|
+
contextMenuKey: 0
|
|
17088
17110
|
};
|
|
17089
17111
|
function gitCommitRowReducer(state, action) {
|
|
17090
17112
|
switch (action.type) {
|
|
@@ -17132,18 +17154,10 @@ function gitCommitRowReducer(state, action) {
|
|
|
17132
17154
|
contextMenuOpen: false,
|
|
17133
17155
|
contextMenuKey: state.contextMenuKey + 1
|
|
17134
17156
|
};
|
|
17135
|
-
case "set-scroll-shadows":
|
|
17136
|
-
if (state.scrollValue === action.value && state.commitBodyHeaderShadowed === action.headerShadowed && state.commitBodyFooterShadowed === action.footerShadowed) return state;
|
|
17137
|
-
return {
|
|
17138
|
-
...state,
|
|
17139
|
-
scrollValue: action.value,
|
|
17140
|
-
commitBodyHeaderShadowed: action.headerShadowed,
|
|
17141
|
-
commitBodyFooterShadowed: action.footerShadowed
|
|
17142
|
-
};
|
|
17143
17157
|
}
|
|
17144
17158
|
}
|
|
17145
17159
|
function gitGraphLaneColor(index, active = false) {
|
|
17146
|
-
if (active) return "
|
|
17160
|
+
if (active) return "var(--warning)";
|
|
17147
17161
|
return GIT_GRAPH_LANE_COLORS[index % GIT_GRAPH_LANE_COLORS.length];
|
|
17148
17162
|
}
|
|
17149
17163
|
var GitCommitGraphBranch = class {
|
|
@@ -17768,8 +17782,8 @@ function useGitCommitRowView({ viewerContextId, cwd, graphWidth, line, value, on
|
|
|
17768
17782
|
const [rowState, dispatchRow] = import_react.useReducer(gitCommitRowReducer, initialGitCommitRowState);
|
|
17769
17783
|
const hashCopiedResetRef = import_react.useRef(void 0);
|
|
17770
17784
|
const messageCopiedResetRef = import_react.useRef(void 0);
|
|
17771
|
-
const commitBodyScrollRef = import_react.useRef(null);
|
|
17772
17785
|
const contextMenuActionsRef = import_react.useRef(null);
|
|
17786
|
+
const { bottomHeight: commitBodyBottomGradientHeight, onScroll: onCommitBodyGradientScroll, setScrollElement: setCommitBodyGradientElement, topHeight: commitBodyTopGradientHeight } = useScrollGradients();
|
|
17773
17787
|
const title = parsed.subject.trim();
|
|
17774
17788
|
const time = formatGitCommitDetailTime(parsed.relativeDate);
|
|
17775
17789
|
const fullTime = formatGitCommitFullDate(parsed.fullDate);
|
|
@@ -17778,19 +17792,6 @@ function useGitCommitRowView({ viewerContextId, cwd, graphWidth, line, value, on
|
|
|
17778
17792
|
const shortHash = parsed.hash || parsed.fullHash.slice(0, 7);
|
|
17779
17793
|
const canRunCommitAction = Boolean(viewerContextId && cwd && parsed.fullHash);
|
|
17780
17794
|
const { hashCopied, messageCopied, formDialog, confirmDialog, contextMenuOpen, contextMenuKey } = rowState;
|
|
17781
|
-
const commitBodyHeaderShadowed = rowState.scrollValue === value && rowState.commitBodyHeaderShadowed;
|
|
17782
|
-
const commitBodyFooterShadowed = rowState.scrollValue === value && rowState.commitBodyFooterShadowed;
|
|
17783
|
-
const updateCommitBodyScrollShadows = (scrollElement) => {
|
|
17784
|
-
dispatchRow({
|
|
17785
|
-
type: "set-scroll-shadows",
|
|
17786
|
-
value,
|
|
17787
|
-
headerShadowed: hasScrolledContent(scrollElement),
|
|
17788
|
-
footerShadowed: hasRemainingScrollContent(scrollElement)
|
|
17789
|
-
});
|
|
17790
|
-
};
|
|
17791
|
-
import_react.useLayoutEffect(() => {
|
|
17792
|
-
updateCommitBodyScrollShadows(commitBodyScrollRef.current);
|
|
17793
|
-
});
|
|
17794
17795
|
import_react.useEffect(() => {
|
|
17795
17796
|
return () => {
|
|
17796
17797
|
if (typeof hashCopiedResetRef.current === "number") window.clearTimeout(hashCopiedResetRef.current);
|
|
@@ -17957,7 +17958,7 @@ function useGitCommitRowView({ viewerContextId, cwd, graphWidth, line, value, on
|
|
|
17957
17958
|
});
|
|
17958
17959
|
};
|
|
17959
17960
|
if (!parsed.hash && !parsed.subject) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
17960
|
-
className: "flex h-8 max-w-full min-w-0 items-center
|
|
17961
|
+
className: "flex h-8 max-w-full min-w-0 items-center text-[13px] leading-5",
|
|
17961
17962
|
children: parsed.subject ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
17962
17963
|
className: "min-w-0 flex-1 truncate text-foreground",
|
|
17963
17964
|
children: parsed.subject
|
|
@@ -17965,7 +17966,7 @@ function useGitCommitRowView({ viewerContextId, cwd, graphWidth, line, value, on
|
|
|
17965
17966
|
});
|
|
17966
17967
|
const trigger = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AccordionTrigger, {
|
|
17967
17968
|
headerClassName: "min-w-0",
|
|
17968
|
-
className: cn("h-8 min-h-8 w-full items-center gap-2 rounded-none px-1.5 py-0
|
|
17969
|
+
className: cn("h-8 min-h-8 w-full items-center gap-2 rounded-none px-1.5 py-0 text-[13px] leading-5 font-normal transition-[background-color,box-shadow,color] hover:no-underline focus-visible:ring-0 aria-expanded:bg-muted/50 **:data-[slot=accordion-trigger-icon]:size-4"),
|
|
17969
17970
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
17970
17971
|
className: "min-w-0 flex-1 truncate pr-8 text-foreground",
|
|
17971
17972
|
style: { paddingLeft: graphWidth },
|
|
@@ -18107,122 +18108,119 @@ function useGitCommitRowView({ viewerContextId, cwd, graphWidth, line, value, on
|
|
|
18107
18108
|
}),
|
|
18108
18109
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AccordionContent, {
|
|
18109
18110
|
className: "relative h-[200px] border-b border-border/70 bg-muted/50 p-0",
|
|
18110
|
-
children: [
|
|
18111
|
-
|
|
18112
|
-
|
|
18113
|
-
|
|
18114
|
-
|
|
18115
|
-
|
|
18116
|
-
},
|
|
18117
|
-
children:
|
|
18118
|
-
|
|
18119
|
-
|
|
18120
|
-
|
|
18121
|
-
|
|
18122
|
-
|
|
18123
|
-
|
|
18111
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
18112
|
+
ref: setCommitBodyGradientElement,
|
|
18113
|
+
className: "h-full overflow-y-auto pr-2 pb-2",
|
|
18114
|
+
onScroll: onCommitBodyGradientScroll,
|
|
18115
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18116
|
+
className: "grid content-start gap-1.5 pt-1 text-xs leading-4",
|
|
18117
|
+
style: { paddingLeft: graphWidth },
|
|
18118
|
+
children: [
|
|
18119
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18120
|
+
className: "flex min-w-0 flex-wrap items-center gap-1.5 font-sans",
|
|
18121
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
|
|
18122
|
+
type: "button",
|
|
18123
|
+
size: "xs",
|
|
18124
|
+
variant: "outline",
|
|
18125
|
+
disabled: !canRunCommitAction,
|
|
18126
|
+
onClick: () => openDiff("commit"),
|
|
18127
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileDiff, {}), "View diff"]
|
|
18128
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitCommitActionsMenu, { ...commitActionProps })]
|
|
18129
|
+
}),
|
|
18130
|
+
parsed.author || time || parsed.fullHash ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18131
|
+
className: "flex max-w-full flex-wrap items-center gap-x-2 gap-y-1 text-muted-foreground",
|
|
18132
|
+
children: [
|
|
18133
|
+
parsed.author ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: parsed.author }) : null,
|
|
18134
|
+
parsed.author && time ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18135
|
+
"aria-hidden": true,
|
|
18136
|
+
children: "·"
|
|
18137
|
+
}) : null,
|
|
18138
|
+
time ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
18139
|
+
title: fullTime,
|
|
18140
|
+
side: "top",
|
|
18141
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: time })
|
|
18142
|
+
}) : null,
|
|
18143
|
+
(parsed.author || time) && parsed.fullHash ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18144
|
+
"aria-hidden": true,
|
|
18145
|
+
children: "·"
|
|
18146
|
+
}) : null,
|
|
18147
|
+
parsed.fullHash ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
18148
|
+
className: "inline-flex min-w-0 items-center gap-1.5",
|
|
18149
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18150
|
+
className: "min-w-0 truncate",
|
|
18151
|
+
children: shortHash
|
|
18152
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
18153
|
+
title: hashCopied ? "Copied" : "Copy full commit hash",
|
|
18154
|
+
side: "top",
|
|
18155
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
18156
|
+
type: "button",
|
|
18157
|
+
"aria-label": "Copy full commit hash",
|
|
18158
|
+
className: "inline-flex size-5 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
18159
|
+
onClick: (event) => {
|
|
18160
|
+
event.preventDefault();
|
|
18161
|
+
event.stopPropagation();
|
|
18162
|
+
copyFullHashInline();
|
|
18163
|
+
},
|
|
18164
|
+
children: hashCopied ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, { className: "size-3.5 text-emerald-500" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Copy, { className: "size-3.5" })
|
|
18165
|
+
})
|
|
18166
|
+
})]
|
|
18167
|
+
}) : null
|
|
18168
|
+
]
|
|
18169
|
+
}) : null,
|
|
18170
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18171
|
+
className: "max-w-full break-words whitespace-normal text-foreground",
|
|
18172
|
+
children: [title || "No commit message", title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
18173
|
+
title: messageCopied ? "Copied" : "Copy commit message",
|
|
18174
|
+
side: "top",
|
|
18175
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
18124
18176
|
type: "button",
|
|
18125
|
-
|
|
18126
|
-
|
|
18127
|
-
|
|
18128
|
-
|
|
18129
|
-
|
|
18130
|
-
|
|
18131
|
-
|
|
18132
|
-
|
|
18133
|
-
|
|
18177
|
+
"aria-label": "Copy commit message",
|
|
18178
|
+
className: "ml-1 inline-flex size-4 items-center justify-center rounded-sm align-middle text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
18179
|
+
onClick: (event) => {
|
|
18180
|
+
event.preventDefault();
|
|
18181
|
+
event.stopPropagation();
|
|
18182
|
+
copyCommitMessageInline();
|
|
18183
|
+
},
|
|
18184
|
+
children: messageCopied ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, { className: "size-3.5 text-emerald-500" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Copy, { className: "size-3.5" })
|
|
18185
|
+
})
|
|
18186
|
+
}) : null]
|
|
18187
|
+
}),
|
|
18188
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18189
|
+
className: "flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1",
|
|
18190
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
18191
|
+
className: "text-emerald-500",
|
|
18134
18192
|
children: [
|
|
18135
|
-
|
|
18136
|
-
|
|
18137
|
-
|
|
18138
|
-
|
|
18139
|
-
}) : null,
|
|
18140
|
-
time ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
18141
|
-
title: fullTime,
|
|
18142
|
-
side: "top",
|
|
18143
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: time })
|
|
18144
|
-
}) : null,
|
|
18145
|
-
(parsed.author || time) && parsed.fullHash ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18146
|
-
"aria-hidden": true,
|
|
18147
|
-
children: "·"
|
|
18148
|
-
}) : null,
|
|
18149
|
-
parsed.fullHash ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
18150
|
-
className: "inline-flex min-w-0 items-center gap-1.5",
|
|
18151
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18152
|
-
className: "min-w-0 truncate",
|
|
18153
|
-
children: shortHash
|
|
18154
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
18155
|
-
title: hashCopied ? "Copied" : "Copy full commit hash",
|
|
18156
|
-
side: "top",
|
|
18157
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
18158
|
-
type: "button",
|
|
18159
|
-
"aria-label": "Copy full commit hash",
|
|
18160
|
-
className: "inline-flex size-5 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
18161
|
-
onClick: (event) => {
|
|
18162
|
-
event.preventDefault();
|
|
18163
|
-
event.stopPropagation();
|
|
18164
|
-
copyFullHashInline();
|
|
18165
|
-
},
|
|
18166
|
-
children: hashCopied ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, { className: "size-3.5 text-emerald-500" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Copy, { className: "size-3.5" })
|
|
18167
|
-
})
|
|
18168
|
-
})]
|
|
18169
|
-
}) : null
|
|
18193
|
+
"+",
|
|
18194
|
+
insertions,
|
|
18195
|
+
" addition",
|
|
18196
|
+
insertions === 1 ? "" : "s"
|
|
18170
18197
|
]
|
|
18171
|
-
})
|
|
18172
|
-
|
|
18173
|
-
|
|
18174
|
-
|
|
18175
|
-
|
|
18176
|
-
|
|
18177
|
-
|
|
18178
|
-
|
|
18179
|
-
|
|
18180
|
-
|
|
18181
|
-
|
|
18182
|
-
|
|
18183
|
-
|
|
18184
|
-
|
|
18185
|
-
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
|
|
18189
|
-
|
|
18190
|
-
|
|
18191
|
-
|
|
18192
|
-
|
|
18193
|
-
|
|
18194
|
-
|
|
18195
|
-
|
|
18196
|
-
|
|
18197
|
-
" addition",
|
|
18198
|
-
insertions === 1 ? "" : "s"
|
|
18199
|
-
]
|
|
18200
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
18201
|
-
className: "text-red-400",
|
|
18202
|
-
children: [
|
|
18203
|
-
"-",
|
|
18204
|
-
deletions,
|
|
18205
|
-
" deletion",
|
|
18206
|
-
deletions === 1 ? "" : "s"
|
|
18207
|
-
]
|
|
18208
|
-
})]
|
|
18209
|
-
}),
|
|
18210
|
-
parsed.fullHash ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitCommitFilesList, {
|
|
18211
|
-
viewerContextId,
|
|
18212
|
-
cwd,
|
|
18213
|
-
commit: parsed.fullHash,
|
|
18214
|
-
shortHash,
|
|
18215
|
-
previousShortHash: parsed.parents[0]?.slice(0, 7) || "",
|
|
18216
|
-
subject: title,
|
|
18217
|
-
disabled: !canRunCommitAction,
|
|
18218
|
-
onOpenCommitDiff
|
|
18219
|
-
}) : null
|
|
18220
|
-
]
|
|
18221
|
-
})
|
|
18222
|
-
}),
|
|
18223
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cn("pointer-events-none absolute inset-x-0 top-0 h-1 bg-gradient-to-b from-black/10 to-transparent transition-opacity duration-150", commitBodyHeaderShadowed ? "opacity-100" : "opacity-0") }),
|
|
18224
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cn("pointer-events-none absolute inset-x-0 bottom-0 h-1 bg-gradient-to-t from-black/10 to-transparent transition-opacity duration-150", commitBodyFooterShadowed ? "opacity-100" : "opacity-0") })
|
|
18225
|
-
]
|
|
18198
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
18199
|
+
className: "text-red-400",
|
|
18200
|
+
children: [
|
|
18201
|
+
"-",
|
|
18202
|
+
deletions,
|
|
18203
|
+
" deletion",
|
|
18204
|
+
deletions === 1 ? "" : "s"
|
|
18205
|
+
]
|
|
18206
|
+
})]
|
|
18207
|
+
}),
|
|
18208
|
+
parsed.fullHash ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitCommitFilesList, {
|
|
18209
|
+
viewerContextId,
|
|
18210
|
+
cwd,
|
|
18211
|
+
commit: parsed.fullHash,
|
|
18212
|
+
shortHash,
|
|
18213
|
+
previousShortHash: parsed.parents[0]?.slice(0, 7) || "",
|
|
18214
|
+
subject: title,
|
|
18215
|
+
disabled: !canRunCommitAction,
|
|
18216
|
+
onOpenCommitDiff
|
|
18217
|
+
}) : null
|
|
18218
|
+
]
|
|
18219
|
+
})
|
|
18220
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollGradientOverlays, {
|
|
18221
|
+
bottomHeight: commitBodyBottomGradientHeight,
|
|
18222
|
+
topHeight: commitBodyTopGradientHeight
|
|
18223
|
+
})]
|
|
18226
18224
|
}),
|
|
18227
18225
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog$1, {
|
|
18228
18226
|
open: formDialog !== null,
|
|
@@ -18473,6 +18471,22 @@ function GitCommitsSection({ viewerContextId, cwd, active, onOpenCommitDiff, onR
|
|
|
18473
18471
|
children: content
|
|
18474
18472
|
});
|
|
18475
18473
|
}
|
|
18474
|
+
function setDerivedScrollState(setState, nextState) {
|
|
18475
|
+
setState((current) => Object.is(current, nextState) ? current : nextState);
|
|
18476
|
+
}
|
|
18477
|
+
function hasScrolledContent(scrollElement) {
|
|
18478
|
+
return Boolean(scrollElement && scrollElement.scrollTop > 0);
|
|
18479
|
+
}
|
|
18480
|
+
function getStuckScrollTriggerValue({ getValue, scrollElement, selector }) {
|
|
18481
|
+
if (!scrollElement || scrollElement.scrollTop <= 0) return "";
|
|
18482
|
+
const containerTop = scrollElement.getBoundingClientRect().top;
|
|
18483
|
+
const triggers = Array.from(scrollElement.querySelectorAll(selector));
|
|
18484
|
+
for (const trigger of triggers) {
|
|
18485
|
+
const rect = trigger.getBoundingClientRect();
|
|
18486
|
+
if (rect.top <= containerTop + 1 && rect.bottom > containerTop + 1) return getValue(trigger);
|
|
18487
|
+
}
|
|
18488
|
+
return "";
|
|
18489
|
+
}
|
|
18476
18490
|
function GitFileStatus({ status }) {
|
|
18477
18491
|
const [indexCharacter, worktreeCharacter] = gitFileStatusCharacters(status);
|
|
18478
18492
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
@@ -18576,7 +18590,7 @@ function ReviewDiffPendingLineComment({ comment }) {
|
|
|
18576
18590
|
comment.onSubmit(normalizedText);
|
|
18577
18591
|
};
|
|
18578
18592
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
|
|
18579
|
-
className: "m-2 w-[
|
|
18593
|
+
className: "m-2 w-[calc(100%_-_1rem)] max-w-[38rem] rounded-lg border border-border/70 bg-background p-2 shadow-sm",
|
|
18580
18594
|
onPointerDown: (event) => event.stopPropagation(),
|
|
18581
18595
|
onSubmit: (event) => {
|
|
18582
18596
|
event.preventDefault();
|
|
@@ -18776,6 +18790,11 @@ function useFileReviewContentView({ viewerContextId, cwd, active, diffLineCommen
|
|
|
18776
18790
|
});
|
|
18777
18791
|
};
|
|
18778
18792
|
const changesScrollRef = import_react.useRef(null);
|
|
18793
|
+
const { bottomHeight: changesScrollBottomGradientHeight, onScroll: onChangesScrollGradientScroll, setScrollElement: setChangesScrollGradientElement, topHeight: changesScrollTopGradientHeight } = useScrollGradients();
|
|
18794
|
+
const setChangesScrollElement = import_react.useCallback((element) => {
|
|
18795
|
+
changesScrollRef.current = element;
|
|
18796
|
+
setChangesScrollGradientElement(element);
|
|
18797
|
+
}, [setChangesScrollGradientElement]);
|
|
18779
18798
|
const reviewContentRef = import_react.useRef(null);
|
|
18780
18799
|
const historyPanelRef = import_react.useRef(null);
|
|
18781
18800
|
const historyScrollRef = import_react.useRef(null);
|
|
@@ -18974,7 +18993,7 @@ function useFileReviewContentView({ viewerContextId, cwd, active, diffLineCommen
|
|
|
18974
18993
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DropdownMenu, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DropdownMenuTrigger, {
|
|
18975
18994
|
render: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
18976
18995
|
variant: "outline",
|
|
18977
|
-
size: "icon",
|
|
18996
|
+
size: isMobile ? "icon" : "icon-sm",
|
|
18978
18997
|
"aria-label": "Diff actions",
|
|
18979
18998
|
disabled: bulkActionDisabled
|
|
18980
18999
|
}),
|
|
@@ -19012,7 +19031,7 @@ function useFileReviewContentView({ viewerContextId, cwd, active, diffLineCommen
|
|
|
19012
19031
|
title: hasOpenFile ? "Collapse all" : "Expand all",
|
|
19013
19032
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
19014
19033
|
variant: "outline",
|
|
19015
|
-
size: "icon",
|
|
19034
|
+
size: isMobile ? "icon" : "icon-sm",
|
|
19016
19035
|
"aria-label": hasOpenFile ? "Collapse all" : "Expand all",
|
|
19017
19036
|
disabled: changedFiles.length === 0,
|
|
19018
19037
|
onClick: toggleAll,
|
|
@@ -19021,6 +19040,7 @@ function useFileReviewContentView({ viewerContextId, cwd, active, diffLineCommen
|
|
|
19021
19040
|
}),
|
|
19022
19041
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToggleGroup$1, {
|
|
19023
19042
|
variant: "outline",
|
|
19043
|
+
size: isMobile ? "default" : "sm",
|
|
19024
19044
|
value: [diffStyle],
|
|
19025
19045
|
onValueChange: (values) => {
|
|
19026
19046
|
const value = values[0];
|
|
@@ -19037,54 +19057,61 @@ function useFileReviewContentView({ viewerContextId, cwd, active, diffLineCommen
|
|
|
19037
19057
|
]
|
|
19038
19058
|
})]
|
|
19039
19059
|
}),
|
|
19040
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
19041
|
-
|
|
19042
|
-
|
|
19043
|
-
|
|
19044
|
-
|
|
19045
|
-
|
|
19046
|
-
|
|
19047
|
-
|
|
19048
|
-
children: "No directory selected."
|
|
19049
|
-
}) : !viewerContextId ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, {
|
|
19050
|
-
className: "px-3 py-2.5",
|
|
19051
|
-
children: "Waiting for viewer context…"
|
|
19052
|
-
}) : filesQuery.isPending && typeof files === "undefined" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GitSectionNote, {
|
|
19053
|
-
className: "px-3 py-2.5",
|
|
19054
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}), " Loading changes…"]
|
|
19055
|
-
}) : filesQuery.error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, {
|
|
19056
|
-
tone: "destructive",
|
|
19057
|
-
className: "px-3 py-2.5",
|
|
19058
|
-
children: getErrorMessage(filesQuery.error, "Failed to load changes")
|
|
19059
|
-
}) : files === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, {
|
|
19060
|
-
className: "px-3 py-2.5",
|
|
19061
|
-
children: "No git repository detected."
|
|
19062
|
-
}) : changedFiles.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Accordion$1, {
|
|
19063
|
-
multiple: true,
|
|
19064
|
-
value: openFiles,
|
|
19065
|
-
onValueChange: (nextOpenFiles) => {
|
|
19066
|
-
dispatch({
|
|
19067
|
-
type: "openFilesChanged",
|
|
19068
|
-
openFiles: nextOpenFiles
|
|
19069
|
-
});
|
|
19060
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
19061
|
+
className: "relative min-h-0 flex-1",
|
|
19062
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
19063
|
+
ref: setChangesScrollElement,
|
|
19064
|
+
className: "h-full overflow-auto",
|
|
19065
|
+
onScroll: (event) => {
|
|
19066
|
+
updateStickyReviewFileHeader(event.currentTarget);
|
|
19067
|
+
onChangesScrollGradientScroll(event);
|
|
19070
19068
|
},
|
|
19071
|
-
|
|
19072
|
-
|
|
19073
|
-
|
|
19074
|
-
|
|
19075
|
-
|
|
19076
|
-
|
|
19077
|
-
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
|
|
19086
|
-
|
|
19087
|
-
|
|
19069
|
+
children: !normalizedCwd ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, {
|
|
19070
|
+
className: "px-3 py-2.5",
|
|
19071
|
+
children: "No directory selected."
|
|
19072
|
+
}) : !viewerContextId ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, {
|
|
19073
|
+
className: "px-3 py-2.5",
|
|
19074
|
+
children: "Waiting for viewer context…"
|
|
19075
|
+
}) : filesQuery.isPending && typeof files === "undefined" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GitSectionNote, {
|
|
19076
|
+
className: "px-3 py-2.5",
|
|
19077
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}), " Loading changes…"]
|
|
19078
|
+
}) : filesQuery.error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, {
|
|
19079
|
+
tone: "destructive",
|
|
19080
|
+
className: "px-3 py-2.5",
|
|
19081
|
+
children: getErrorMessage(filesQuery.error, "Failed to load changes")
|
|
19082
|
+
}) : files === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, {
|
|
19083
|
+
className: "px-3 py-2.5",
|
|
19084
|
+
children: "No git repository detected."
|
|
19085
|
+
}) : changedFiles.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Accordion$1, {
|
|
19086
|
+
multiple: true,
|
|
19087
|
+
value: openFiles,
|
|
19088
|
+
onValueChange: (nextOpenFiles) => {
|
|
19089
|
+
dispatch({
|
|
19090
|
+
type: "openFilesChanged",
|
|
19091
|
+
openFiles: nextOpenFiles
|
|
19092
|
+
});
|
|
19093
|
+
},
|
|
19094
|
+
className: "border-b border-border/80",
|
|
19095
|
+
children: changedFiles.map((file) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReviewFileAccordionItem, {
|
|
19096
|
+
viewerContextId,
|
|
19097
|
+
cwd: normalizedCwd,
|
|
19098
|
+
active,
|
|
19099
|
+
diffLineComments,
|
|
19100
|
+
diffStyle,
|
|
19101
|
+
file,
|
|
19102
|
+
open: openFiles.includes(reviewFileValue(file)),
|
|
19103
|
+
stuck: stickyReviewFileValue === reviewFileValue(file),
|
|
19104
|
+
onAddDiffLineComment,
|
|
19105
|
+
onOpenFile
|
|
19106
|
+
}, reviewFileValue(file)))
|
|
19107
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, {
|
|
19108
|
+
className: "px-3 py-2.5",
|
|
19109
|
+
children: "Working tree clean."
|
|
19110
|
+
})
|
|
19111
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollGradientOverlays, {
|
|
19112
|
+
bottomHeight: changesScrollBottomGradientHeight,
|
|
19113
|
+
topHeight: changesScrollTopGradientHeight
|
|
19114
|
+
})]
|
|
19088
19115
|
}),
|
|
19089
19116
|
showEmbeddedHistory && normalizedCwd && viewerContextId && files !== null && !filesQuery.error ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
19090
19117
|
ref: historyPanelRef,
|
|
@@ -19235,6 +19262,7 @@ function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffLineComment
|
|
|
19235
19262
|
} : {};
|
|
19236
19263
|
const themeOptions = usePicoDiffThemeOptions();
|
|
19237
19264
|
const canStage = gitFileCanStage(file);
|
|
19265
|
+
const canUnstage = gitFileCanUnstage(file);
|
|
19238
19266
|
const invalidateChangedFileQueries = async () => {
|
|
19239
19267
|
await invalidateGitQueries({
|
|
19240
19268
|
queryClient,
|
|
@@ -19243,26 +19271,27 @@ function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffLineComment
|
|
|
19243
19271
|
});
|
|
19244
19272
|
};
|
|
19245
19273
|
const stageMutation = useMutation({
|
|
19246
|
-
mutationFn: async () => await fetchJson(buildRequestUrl("/api/git-stage", { contextId: viewerContextId }), {
|
|
19274
|
+
mutationFn: async (action) => await fetchJson(buildRequestUrl("/api/git-stage", { contextId: viewerContextId }), {
|
|
19247
19275
|
method: "POST",
|
|
19248
19276
|
headers: { "content-type": "application/json" },
|
|
19249
19277
|
body: JSON.stringify({
|
|
19278
|
+
action,
|
|
19250
19279
|
cwd: normalizedCwd,
|
|
19251
19280
|
path: file.path,
|
|
19252
19281
|
previousPath: file.previousPath
|
|
19253
19282
|
})
|
|
19254
19283
|
}),
|
|
19255
|
-
onSuccess: async () => {
|
|
19284
|
+
onSuccess: async (_response, action) => {
|
|
19256
19285
|
await queryClient.invalidateQueries({
|
|
19257
19286
|
queryKey: picoQueryKeys.gitStatus(viewerContextId, normalizedCwd),
|
|
19258
19287
|
exact: true,
|
|
19259
19288
|
refetchType: "active"
|
|
19260
19289
|
});
|
|
19261
19290
|
await invalidateChangedFileQueries();
|
|
19262
|
-
toast.success("Staged changes", { description: file.path });
|
|
19291
|
+
toast.success(action === "unstage" ? "Unstaged changes" : "Staged changes", { description: file.path });
|
|
19263
19292
|
},
|
|
19264
|
-
onError: (error) => {
|
|
19265
|
-
toast.error(getErrorMessage(error, "Failed to stage changes"));
|
|
19293
|
+
onError: (error, action) => {
|
|
19294
|
+
toast.error(getErrorMessage(error, action === "unstage" ? "Failed to unstage changes" : "Failed to stage changes"));
|
|
19266
19295
|
}
|
|
19267
19296
|
});
|
|
19268
19297
|
const discardMutation = useMutation({
|
|
@@ -19299,6 +19328,9 @@ function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffLineComment
|
|
|
19299
19328
|
oldContent,
|
|
19300
19329
|
newContent
|
|
19301
19330
|
]);
|
|
19331
|
+
const gitActionDisabled = actionPending || !viewerContextId || !normalizedCwd;
|
|
19332
|
+
const stagePending = stageMutation.isPending && stageMutation.variables === "stage";
|
|
19333
|
+
const unstagePending = stageMutation.isPending && stageMutation.variables === "unstage";
|
|
19302
19334
|
const openFile = (event) => {
|
|
19303
19335
|
event?.stopPropagation();
|
|
19304
19336
|
onOpenFile?.(file.path, { pin: true });
|
|
@@ -19309,50 +19341,81 @@ function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffLineComment
|
|
|
19309
19341
|
};
|
|
19310
19342
|
const stageFileChanges = (event) => {
|
|
19311
19343
|
event?.stopPropagation();
|
|
19312
|
-
stageMutation.mutate();
|
|
19344
|
+
stageMutation.mutate("stage");
|
|
19313
19345
|
};
|
|
19314
|
-
|
|
19315
|
-
|
|
19316
|
-
|
|
19317
|
-
|
|
19318
|
-
|
|
19319
|
-
|
|
19320
|
-
|
|
19321
|
-
|
|
19322
|
-
|
|
19346
|
+
const unstageFileChanges = (event) => {
|
|
19347
|
+
event?.stopPropagation();
|
|
19348
|
+
stageMutation.mutate("unstage");
|
|
19349
|
+
};
|
|
19350
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AccordionTrigger$1, {
|
|
19351
|
+
"data-review-file-trigger": true,
|
|
19352
|
+
"data-review-file-value": value,
|
|
19353
|
+
className: "group/review-file-trigger relative flex min-h-10 min-w-0 flex-1 items-center justify-between gap-3 rounded-none border border-transparent bg-background px-3 py-2 text-left text-[13px] font-medium transition-all outline-none hover:no-underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-disabled:pointer-events-none aria-disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground",
|
|
19354
|
+
children: [
|
|
19355
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
19356
|
+
className: "grid min-w-0 flex-1 grid-cols-[auto_auto_minmax(0,1fr)_auto] items-center gap-2",
|
|
19323
19357
|
children: [
|
|
19324
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
19325
|
-
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19358
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitFileStatus, { status: file.status }),
|
|
19359
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProjectFileTypeIcon, { path: file.path }),
|
|
19360
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
19361
|
+
className: "min-w-0 truncate text-left",
|
|
19362
|
+
children: file.previousPath ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
19329
19363
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
19330
|
-
className: "
|
|
19331
|
-
children: file.previousPath
|
|
19332
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
19333
|
-
className: "text-muted-foreground",
|
|
19334
|
-
children: file.previousPath
|
|
19335
|
-
}),
|
|
19336
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
19337
|
-
className: "text-muted-foreground/70",
|
|
19338
|
-
children: " → "
|
|
19339
|
-
}),
|
|
19340
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: file.path })
|
|
19341
|
-
] }) : file.path
|
|
19364
|
+
className: "text-muted-foreground",
|
|
19365
|
+
children: file.previousPath
|
|
19342
19366
|
}),
|
|
19343
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
19344
|
-
|
|
19345
|
-
|
|
19346
|
-
|
|
19347
|
-
|
|
19348
|
-
|
|
19367
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
19368
|
+
className: "text-muted-foreground/70",
|
|
19369
|
+
children: " → "
|
|
19370
|
+
}),
|
|
19371
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: file.path })
|
|
19372
|
+
] }) : file.path
|
|
19349
19373
|
}),
|
|
19350
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
19351
|
-
"data-slot": "accordion-trigger-icon",
|
|
19352
|
-
className: "pointer-events-none hidden size-4 shrink-0 group-aria-expanded/review-file-trigger:inline"
|
|
19353
|
-
})
|
|
19374
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitFileDiff, { file })
|
|
19354
19375
|
]
|
|
19376
|
+
}),
|
|
19377
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, {
|
|
19378
|
+
"data-slot": "accordion-trigger-icon",
|
|
19379
|
+
className: "pointer-events-none size-4 shrink-0 group-aria-expanded/review-file-trigger:hidden"
|
|
19380
|
+
}),
|
|
19381
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, {
|
|
19382
|
+
"data-slot": "accordion-trigger-icon",
|
|
19383
|
+
className: "pointer-events-none hidden size-4 shrink-0 group-aria-expanded/review-file-trigger:inline"
|
|
19355
19384
|
})
|
|
19385
|
+
]
|
|
19386
|
+
});
|
|
19387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AccordionItem, {
|
|
19388
|
+
value,
|
|
19389
|
+
className: "border-border/70",
|
|
19390
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AccordionHeader, {
|
|
19391
|
+
className: cn("group/review-file-header sticky top-0 z-20 flex bg-background transition-shadow", stuck && "shadow-sm"),
|
|
19392
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenu$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuTrigger, { render: trigger }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenuContent, {
|
|
19393
|
+
className: "w-48",
|
|
19394
|
+
children: [
|
|
19395
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenuItem, {
|
|
19396
|
+
disabled: !onOpenFile,
|
|
19397
|
+
onClick: openFile,
|
|
19398
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowUpRight, {}), "Open file"]
|
|
19399
|
+
}),
|
|
19400
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuSeparator, {}),
|
|
19401
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenuItem, {
|
|
19402
|
+
disabled: gitActionDisabled || !canStage,
|
|
19403
|
+
onClick: stageFileChanges,
|
|
19404
|
+
children: [stagePending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { size: "xs" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Plus, {}), "Stage changes"]
|
|
19405
|
+
}),
|
|
19406
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenuItem, {
|
|
19407
|
+
disabled: gitActionDisabled || !canUnstage,
|
|
19408
|
+
onClick: unstageFileChanges,
|
|
19409
|
+
children: [unstagePending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { size: "xs" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Minus, {}), "Unstage changes"]
|
|
19410
|
+
}),
|
|
19411
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ContextMenuItem, {
|
|
19412
|
+
variant: "destructive",
|
|
19413
|
+
disabled: gitActionDisabled,
|
|
19414
|
+
onClick: discardFileChanges,
|
|
19415
|
+
children: [discardMutation.isPending ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { size: "xs" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Undo2, {}), "Discard changes"]
|
|
19416
|
+
})
|
|
19417
|
+
]
|
|
19418
|
+
})] })
|
|
19356
19419
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AccordionContent, {
|
|
19357
19420
|
className: "bg-background p-0",
|
|
19358
19421
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
@@ -19597,7 +19660,7 @@ function assignClassName(element, className) {
|
|
|
19597
19660
|
}
|
|
19598
19661
|
function renderPendingCommitDiffLineComment(pendingComment) {
|
|
19599
19662
|
const form = document.createElement("form");
|
|
19600
|
-
assignClassName(form, "m-2 w-[
|
|
19663
|
+
assignClassName(form, "m-2 w-[calc(100%_-_1rem)] max-w-[38rem] rounded-lg border border-border/70 bg-background p-2 shadow-sm");
|
|
19601
19664
|
const header = document.createElement("div");
|
|
19602
19665
|
assignClassName(header, "mb-2 flex min-w-0 items-center justify-between gap-2 text-xs text-muted-foreground");
|
|
19603
19666
|
const label = document.createElement("span");
|
|
@@ -19740,7 +19803,7 @@ function CommitFileDiffAccordionItem({ comments, diffStyle, fileDiff, index, onS
|
|
|
19740
19803
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AccordionTrigger$1, {
|
|
19741
19804
|
"data-commit-file-trigger": true,
|
|
19742
19805
|
"data-commit-file-value": value,
|
|
19743
|
-
className: "group/commit-file-trigger relative flex min-h-10 min-w-0 flex-1 items-center justify-between gap-3 rounded-none border border-transparent bg-background px-3 py-2 text-left
|
|
19806
|
+
className: "group/commit-file-trigger relative flex min-h-10 min-w-0 flex-1 items-center justify-between gap-3 rounded-none border border-transparent bg-background px-3 py-2 text-left text-[13px] font-medium transition-all outline-none hover:no-underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-disabled:pointer-events-none aria-disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground",
|
|
19744
19807
|
children: [
|
|
19745
19808
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
19746
19809
|
className: "grid min-w-0 flex-1 grid-cols-[minmax(0,1fr)_auto] items-baseline gap-3",
|
|
@@ -19878,8 +19941,14 @@ function CommitDiffHeaderTitle({ tab }) {
|
|
|
19878
19941
|
function CommitDiffContent({ viewerContextId, cwd, active, diffLineComments, onAddDiffLineComment, tab }) {
|
|
19879
19942
|
const [diffStyle, setDiffStyle] = import_react.useState("unified");
|
|
19880
19943
|
const [stickyCommitFileValue, setStickyCommitFileValue] = import_react.useState("");
|
|
19944
|
+
const isMobile = useIsMobile();
|
|
19881
19945
|
const [commentTarget, setCommentTarget] = import_react.useState(null);
|
|
19882
19946
|
const diffScrollRef = import_react.useRef(null);
|
|
19947
|
+
const { bottomHeight: diffScrollBottomGradientHeight, onScroll: onDiffScrollGradientScroll, setScrollElement: setDiffScrollGradientElement, topHeight: diffScrollTopGradientHeight } = useScrollGradients();
|
|
19948
|
+
const setDiffScrollElement = import_react.useCallback((element) => {
|
|
19949
|
+
diffScrollRef.current = element;
|
|
19950
|
+
setDiffScrollGradientElement(element);
|
|
19951
|
+
}, [setDiffScrollGradientElement]);
|
|
19883
19952
|
const updateStickyCommitFileHeader = (scrollElement) => {
|
|
19884
19953
|
setDerivedScrollState(setStickyCommitFileValue, getStuckScrollTriggerValue({
|
|
19885
19954
|
getValue: (trigger) => trigger.dataset.commitFileValue || "",
|
|
@@ -19945,6 +20014,7 @@ function CommitDiffContent({ viewerContextId, cwd, active, diffLineComments, onA
|
|
|
19945
20014
|
className: "flex min-h-10 shrink-0 items-center justify-between gap-2 border-b border-border/70 bg-background p-2",
|
|
19946
20015
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitDiffHeaderTitle, { tab }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ToggleGroup$1, {
|
|
19947
20016
|
variant: "outline",
|
|
20017
|
+
size: isMobile ? "default" : "sm",
|
|
19948
20018
|
value: [diffStyle],
|
|
19949
20019
|
onValueChange: (values) => {
|
|
19950
20020
|
const value = values[0];
|
|
@@ -19958,41 +20028,48 @@ function CommitDiffContent({ viewerContextId, cwd, active, diffLineComments, onA
|
|
|
19958
20028
|
children: "Split"
|
|
19959
20029
|
})]
|
|
19960
20030
|
})]
|
|
19961
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.
|
|
19962
|
-
|
|
19963
|
-
|
|
19964
|
-
|
|
19965
|
-
|
|
19966
|
-
|
|
19967
|
-
|
|
19968
|
-
|
|
19969
|
-
|
|
19970
|
-
|
|
19971
|
-
|
|
19972
|
-
|
|
19973
|
-
|
|
19974
|
-
|
|
20031
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20032
|
+
className: "relative min-h-0 flex-1",
|
|
20033
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20034
|
+
ref: setDiffScrollElement,
|
|
20035
|
+
className: "h-full overflow-auto",
|
|
20036
|
+
onScroll: (event) => {
|
|
20037
|
+
updateStickyCommitFileHeader(event.currentTarget);
|
|
20038
|
+
onDiffScrollGradientScroll(event);
|
|
20039
|
+
},
|
|
20040
|
+
children: diffQuery.isPending && !diffQuery.data ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20041
|
+
className: "p-4",
|
|
20042
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GitSectionNote, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}), " Loading commit diff…"] })
|
|
20043
|
+
}) : diffQuery.error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20044
|
+
className: "p-4",
|
|
20045
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, {
|
|
20046
|
+
tone: "destructive",
|
|
20047
|
+
children: getErrorMessage(diffQuery.error, "Failed to load commit diff")
|
|
20048
|
+
})
|
|
20049
|
+
}) : diffQuery.data?.patch && tab.path ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitSingleFileDiff, {
|
|
20050
|
+
comments: commentsForTab.filter((comment) => {
|
|
20051
|
+
if (!tab.path) return true;
|
|
20052
|
+
return comment.path === tab.path || comment.path === tab.previousPath;
|
|
20053
|
+
}),
|
|
20054
|
+
diffStyle,
|
|
20055
|
+
onStartComment: startLineComment,
|
|
20056
|
+
patch: diffQuery.data.patch,
|
|
20057
|
+
pendingComment
|
|
20058
|
+
}) : diffQuery.data?.patch ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitPatchDiffs, {
|
|
20059
|
+
comments: commentsForTab,
|
|
20060
|
+
diffStyle,
|
|
20061
|
+
onStartComment: startLineComment,
|
|
20062
|
+
patch: diffQuery.data.patch,
|
|
20063
|
+
pendingComment,
|
|
20064
|
+
stuckFileValue: stickyCommitFileValue
|
|
20065
|
+
}, `${diffQuery.data.commit}:${diffQuery.data.mode}`) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20066
|
+
className: "p-4",
|
|
20067
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, { children: "No line changes." })
|
|
19975
20068
|
})
|
|
19976
|
-
})
|
|
19977
|
-
|
|
19978
|
-
|
|
19979
|
-
|
|
19980
|
-
}),
|
|
19981
|
-
diffStyle,
|
|
19982
|
-
onStartComment: startLineComment,
|
|
19983
|
-
patch: diffQuery.data.patch,
|
|
19984
|
-
pendingComment
|
|
19985
|
-
}) : diffQuery.data?.patch ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitPatchDiffs, {
|
|
19986
|
-
comments: commentsForTab,
|
|
19987
|
-
diffStyle,
|
|
19988
|
-
onStartComment: startLineComment,
|
|
19989
|
-
patch: diffQuery.data.patch,
|
|
19990
|
-
pendingComment,
|
|
19991
|
-
stuckFileValue: stickyCommitFileValue
|
|
19992
|
-
}, `${diffQuery.data.commit}:${diffQuery.data.mode}`) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
19993
|
-
className: "p-4",
|
|
19994
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, { children: "No line changes." })
|
|
19995
|
-
})
|
|
20069
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollGradientOverlays, {
|
|
20070
|
+
bottomHeight: diffScrollBottomGradientHeight,
|
|
20071
|
+
topHeight: diffScrollTopGradientHeight
|
|
20072
|
+
})]
|
|
19996
20073
|
})]
|
|
19997
20074
|
});
|
|
19998
20075
|
}
|
|
@@ -20249,6 +20326,701 @@ function RightSidebar({ viewerContextId, cwd, active, activeFilePath = "", activ
|
|
|
20249
20326
|
})]
|
|
20250
20327
|
});
|
|
20251
20328
|
}
|
|
20329
|
+
var TERMINAL_ANSI_THEMES = {
|
|
20330
|
+
dark: {
|
|
20331
|
+
black: "#484f58",
|
|
20332
|
+
red: "#ff7b72",
|
|
20333
|
+
green: "#3fb950",
|
|
20334
|
+
yellow: "#d29922",
|
|
20335
|
+
blue: "#58a6ff",
|
|
20336
|
+
magenta: "#bc8cff",
|
|
20337
|
+
cyan: "#39c5cf",
|
|
20338
|
+
white: "#b1bac4",
|
|
20339
|
+
brightBlack: "#6e7681",
|
|
20340
|
+
brightRed: "#ffa198",
|
|
20341
|
+
brightGreen: "#56d364",
|
|
20342
|
+
brightYellow: "#e3b341",
|
|
20343
|
+
brightBlue: "#79c0ff",
|
|
20344
|
+
brightMagenta: "#d2a8ff",
|
|
20345
|
+
brightCyan: "#56d4dd",
|
|
20346
|
+
brightWhite: "#f0f6fc"
|
|
20347
|
+
},
|
|
20348
|
+
light: {
|
|
20349
|
+
black: "#24292f",
|
|
20350
|
+
red: "#cf222e",
|
|
20351
|
+
green: "#116329",
|
|
20352
|
+
yellow: "#953800",
|
|
20353
|
+
blue: "#0969da",
|
|
20354
|
+
magenta: "#8250df",
|
|
20355
|
+
cyan: "#1b7c83",
|
|
20356
|
+
white: "#6e7781",
|
|
20357
|
+
brightBlack: "#57606a",
|
|
20358
|
+
brightRed: "#a40e26",
|
|
20359
|
+
brightGreen: "#1a7f37",
|
|
20360
|
+
brightYellow: "#9a6700",
|
|
20361
|
+
brightBlue: "#218bff",
|
|
20362
|
+
brightMagenta: "#a475f9",
|
|
20363
|
+
brightCyan: "#3192aa",
|
|
20364
|
+
brightWhite: "#24292f"
|
|
20365
|
+
}
|
|
20366
|
+
};
|
|
20367
|
+
var terminalTabCounter = 0;
|
|
20368
|
+
function createTerminalTabId() {
|
|
20369
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return `terminal-tab-${crypto.randomUUID()}`;
|
|
20370
|
+
terminalTabCounter += 1;
|
|
20371
|
+
return `terminal-tab-${Date.now()}-${terminalTabCounter}`;
|
|
20372
|
+
}
|
|
20373
|
+
function createTerminalTab(id = createTerminalTabId()) {
|
|
20374
|
+
return {
|
|
20375
|
+
id,
|
|
20376
|
+
status: { type: "idle" },
|
|
20377
|
+
terminalId: null
|
|
20378
|
+
};
|
|
20379
|
+
}
|
|
20380
|
+
function createTerminalTabsState(scopeKey) {
|
|
20381
|
+
const storedTabs = readStoredTerminalTabs(scopeKey);
|
|
20382
|
+
const tabs = storedTabs.tabs.map((id) => createTerminalTab(id));
|
|
20383
|
+
return {
|
|
20384
|
+
activeTabId: storedTabs.activeTabId ?? tabs[0]?.id ?? null,
|
|
20385
|
+
scopeKey,
|
|
20386
|
+
tabs
|
|
20387
|
+
};
|
|
20388
|
+
}
|
|
20389
|
+
function rememberTerminalTabsState(state) {
|
|
20390
|
+
rememberStoredTerminalTabs(state.scopeKey, {
|
|
20391
|
+
activeTabId: state.activeTabId,
|
|
20392
|
+
tabs: state.tabs.map((tab) => tab.id)
|
|
20393
|
+
});
|
|
20394
|
+
}
|
|
20395
|
+
function terminalStatusText(status) {
|
|
20396
|
+
switch (status.type) {
|
|
20397
|
+
case "idle": return "Idle";
|
|
20398
|
+
case "connecting": return "Connecting…";
|
|
20399
|
+
case "connected": return status.shell ? `Running ${status.shell}` : "Connected";
|
|
20400
|
+
case "exited": return `Exited ${status.exitCode}`;
|
|
20401
|
+
case "error": return "Terminal error";
|
|
20402
|
+
}
|
|
20403
|
+
}
|
|
20404
|
+
function terminalStatusDetail(status) {
|
|
20405
|
+
switch (status.type) {
|
|
20406
|
+
case "idle": return "This terminal has not started yet.";
|
|
20407
|
+
case "connecting": return "Pico is connecting to the terminal process.";
|
|
20408
|
+
case "connected": return status.shell ? `The terminal is connected and running ${status.shell}.` : "The terminal is connected.";
|
|
20409
|
+
case "exited": return typeof status.signal === "number" ? `The terminal process exited with code ${status.exitCode} and signal ${status.signal}.` : `The terminal process exited with code ${status.exitCode}.`;
|
|
20410
|
+
case "error": return status.message;
|
|
20411
|
+
}
|
|
20412
|
+
}
|
|
20413
|
+
function terminalTabLabel(tab, index) {
|
|
20414
|
+
if (tab.status.type === "connected" && tab.status.shell) return `${index + 1}: ${tab.status.shell}`;
|
|
20415
|
+
return `Terminal ${index + 1}`;
|
|
20416
|
+
}
|
|
20417
|
+
function statusDotClassName(status) {
|
|
20418
|
+
switch (status.type) {
|
|
20419
|
+
case "connected": return "bg-success";
|
|
20420
|
+
case "connecting": return "bg-warning";
|
|
20421
|
+
case "error":
|
|
20422
|
+
case "exited": return "bg-destructive";
|
|
20423
|
+
case "idle": return "bg-muted-foreground/50";
|
|
20424
|
+
}
|
|
20425
|
+
}
|
|
20426
|
+
function cssVariable(name, fallback) {
|
|
20427
|
+
return window.getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
|
|
20428
|
+
}
|
|
20429
|
+
function resolveTerminalThemeMode() {
|
|
20430
|
+
for (const className of document.documentElement.classList) {
|
|
20431
|
+
const mode = appliedThemeClassColorMode(className);
|
|
20432
|
+
if (mode) return mode;
|
|
20433
|
+
}
|
|
20434
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
20435
|
+
}
|
|
20436
|
+
function terminalAnsiTheme() {
|
|
20437
|
+
const fallback = TERMINAL_ANSI_THEMES[resolveTerminalThemeMode()];
|
|
20438
|
+
return {
|
|
20439
|
+
black: cssVariable("--terminal-ansi-black", fallback.black),
|
|
20440
|
+
red: cssVariable("--terminal-ansi-red", fallback.red),
|
|
20441
|
+
green: cssVariable("--terminal-ansi-green", fallback.green),
|
|
20442
|
+
yellow: cssVariable("--terminal-ansi-yellow", fallback.yellow),
|
|
20443
|
+
blue: cssVariable("--terminal-ansi-blue", fallback.blue),
|
|
20444
|
+
magenta: cssVariable("--terminal-ansi-magenta", fallback.magenta),
|
|
20445
|
+
cyan: cssVariable("--terminal-ansi-cyan", fallback.cyan),
|
|
20446
|
+
white: cssVariable("--terminal-ansi-white", fallback.white),
|
|
20447
|
+
brightBlack: cssVariable("--terminal-ansi-bright-black", fallback.brightBlack),
|
|
20448
|
+
brightRed: cssVariable("--terminal-ansi-bright-red", fallback.brightRed),
|
|
20449
|
+
brightGreen: cssVariable("--terminal-ansi-bright-green", fallback.brightGreen),
|
|
20450
|
+
brightYellow: cssVariable("--terminal-ansi-bright-yellow", fallback.brightYellow),
|
|
20451
|
+
brightBlue: cssVariable("--terminal-ansi-bright-blue", fallback.brightBlue),
|
|
20452
|
+
brightMagenta: cssVariable("--terminal-ansi-bright-magenta", fallback.brightMagenta),
|
|
20453
|
+
brightCyan: cssVariable("--terminal-ansi-bright-cyan", fallback.brightCyan),
|
|
20454
|
+
brightWhite: cssVariable("--terminal-ansi-bright-white", fallback.brightWhite)
|
|
20455
|
+
};
|
|
20456
|
+
}
|
|
20457
|
+
function createTerminalTheme() {
|
|
20458
|
+
const ansiTheme = terminalAnsiTheme();
|
|
20459
|
+
return {
|
|
20460
|
+
...ansiTheme,
|
|
20461
|
+
background: cssVariable("--terminal-background", cssVariable("--background", "#111111")),
|
|
20462
|
+
cursor: cssVariable("--terminal-cursor", cssVariable("--primary", "#7aa2f7")),
|
|
20463
|
+
foreground: cssVariable("--terminal-foreground", cssVariable("--foreground", ansiTheme.brightWhite)),
|
|
20464
|
+
selectionBackground: cssVariable("--terminal-selection-background", cssVariable("--code-selection", "#334155"))
|
|
20465
|
+
};
|
|
20466
|
+
}
|
|
20467
|
+
function createTerminalFontFamily() {
|
|
20468
|
+
return cssVariable("--font-mono", "Menlo, ui-monospace, SFMono-Regular, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace");
|
|
20469
|
+
}
|
|
20470
|
+
function errorMessage(error) {
|
|
20471
|
+
if (error instanceof Error && error.message.trim()) return error.message;
|
|
20472
|
+
if (typeof error === "string" && error.trim()) return error;
|
|
20473
|
+
return "Unknown terminal error";
|
|
20474
|
+
}
|
|
20475
|
+
function exitedStatus(event) {
|
|
20476
|
+
return typeof event.signal === "number" && event.signal > 0 ? {
|
|
20477
|
+
type: "exited",
|
|
20478
|
+
exitCode: event.exitCode,
|
|
20479
|
+
signal: event.signal
|
|
20480
|
+
} : {
|
|
20481
|
+
type: "exited",
|
|
20482
|
+
exitCode: event.exitCode
|
|
20483
|
+
};
|
|
20484
|
+
}
|
|
20485
|
+
function isTerminalToggleEvent(event) {
|
|
20486
|
+
return event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && (event.key === "`" || event.code === "Backquote");
|
|
20487
|
+
}
|
|
20488
|
+
function TerminalStatusDot({ status }) {
|
|
20489
|
+
if (status.type === "connecting") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
|
|
20490
|
+
size: "xs",
|
|
20491
|
+
className: "shrink-0"
|
|
20492
|
+
});
|
|
20493
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20494
|
+
"aria-hidden": "true",
|
|
20495
|
+
className: cn("size-2 shrink-0 rounded-full", statusDotClassName(status))
|
|
20496
|
+
});
|
|
20497
|
+
}
|
|
20498
|
+
function TerminalStatusDialog({ cwd, index, onOpenChange, open, tab }) {
|
|
20499
|
+
const status = tab?.status ?? { type: "idle" };
|
|
20500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog$1, {
|
|
20501
|
+
open,
|
|
20502
|
+
onOpenChange,
|
|
20503
|
+
focusPromptOnClose: false,
|
|
20504
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent, {
|
|
20505
|
+
className: "max-w-sm",
|
|
20506
|
+
children: [
|
|
20507
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogHeader, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogTitle, { children: [tab ? terminalTabLabel(tab, index) : "Terminal", " status"] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription, { children: terminalStatusDetail(status) })] }),
|
|
20508
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dl", {
|
|
20509
|
+
className: "grid gap-3 text-sm",
|
|
20510
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20511
|
+
className: "grid gap-1",
|
|
20512
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
20513
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
20514
|
+
children: "Status"
|
|
20515
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: terminalStatusText(status) })]
|
|
20516
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20517
|
+
className: "grid gap-1",
|
|
20518
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
20519
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
20520
|
+
children: "Working directory"
|
|
20521
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
|
|
20522
|
+
className: "break-all",
|
|
20523
|
+
children: cwd
|
|
20524
|
+
})]
|
|
20525
|
+
})]
|
|
20526
|
+
}),
|
|
20527
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogFooter, { showCloseButton: true })
|
|
20528
|
+
]
|
|
20529
|
+
})
|
|
20530
|
+
});
|
|
20531
|
+
}
|
|
20532
|
+
function TerminalTabPane({ active, cwd, onStatusChange, onTerminalIdChange, selected, sessionId, tabId, viewerContextId }) {
|
|
20533
|
+
const terminalElementRef = import_react.useRef(null);
|
|
20534
|
+
const terminalRef = import_react.useRef(null);
|
|
20535
|
+
const terminalIdRef = import_react.useRef(null);
|
|
20536
|
+
const activeRef = import_react.useRef(active);
|
|
20537
|
+
const fitAndResizeRef = import_react.useRef(() => {});
|
|
20538
|
+
const onStatusChangeRef = import_react.useRef(onStatusChange);
|
|
20539
|
+
const onTerminalIdChangeRef = import_react.useRef(onTerminalIdChange);
|
|
20540
|
+
const [status, setStatus] = import_react.useState({ type: "idle" });
|
|
20541
|
+
import_react.useLayoutEffect(() => {
|
|
20542
|
+
activeRef.current = active;
|
|
20543
|
+
}, [active]);
|
|
20544
|
+
import_react.useEffect(() => {
|
|
20545
|
+
onStatusChangeRef.current = onStatusChange;
|
|
20546
|
+
}, [onStatusChange]);
|
|
20547
|
+
import_react.useEffect(() => {
|
|
20548
|
+
onTerminalIdChangeRef.current = onTerminalIdChange;
|
|
20549
|
+
}, [onTerminalIdChange]);
|
|
20550
|
+
import_react.useEffect(() => {
|
|
20551
|
+
if (!cwd) {
|
|
20552
|
+
setStatus({ type: "idle" });
|
|
20553
|
+
onStatusChangeRef.current(tabId, { type: "idle" });
|
|
20554
|
+
return;
|
|
20555
|
+
}
|
|
20556
|
+
const terminalElement = terminalElementRef.current;
|
|
20557
|
+
if (!terminalElement) return;
|
|
20558
|
+
let disposed = false;
|
|
20559
|
+
let eventSource = null;
|
|
20560
|
+
let inputDisposable = null;
|
|
20561
|
+
let fitAddon = null;
|
|
20562
|
+
let resizeObserver = null;
|
|
20563
|
+
let inputFlushTimer = null;
|
|
20564
|
+
let resizeFrame = null;
|
|
20565
|
+
let inputBuffer = "";
|
|
20566
|
+
let lastResizeKey = "";
|
|
20567
|
+
const requestOptions = sessionId ? {
|
|
20568
|
+
contextId: viewerContextId,
|
|
20569
|
+
sessionId
|
|
20570
|
+
} : { contextId: viewerContextId };
|
|
20571
|
+
const publishStatus = (nextStatus) => {
|
|
20572
|
+
if (disposed) return;
|
|
20573
|
+
setStatus(nextStatus);
|
|
20574
|
+
onStatusChangeRef.current(tabId, nextStatus);
|
|
20575
|
+
};
|
|
20576
|
+
const postJson = async (path, body) => {
|
|
20577
|
+
return await fetchJson(buildRequestUrl(path, requestOptions), {
|
|
20578
|
+
body: JSON.stringify(body),
|
|
20579
|
+
headers: { "content-type": "application/json" },
|
|
20580
|
+
method: "POST"
|
|
20581
|
+
});
|
|
20582
|
+
};
|
|
20583
|
+
const flushInput = () => {
|
|
20584
|
+
inputFlushTimer = null;
|
|
20585
|
+
const id = terminalIdRef.current;
|
|
20586
|
+
if (!id || !inputBuffer) return;
|
|
20587
|
+
const data = inputBuffer;
|
|
20588
|
+
inputBuffer = "";
|
|
20589
|
+
postJson(`/api/terminal/${encodeURIComponent(id)}/input`, { data }).catch((error) => {
|
|
20590
|
+
if (!disposed) publishStatus({
|
|
20591
|
+
type: "error",
|
|
20592
|
+
message: errorMessage(error)
|
|
20593
|
+
});
|
|
20594
|
+
});
|
|
20595
|
+
};
|
|
20596
|
+
const scheduleInputFlush = () => {
|
|
20597
|
+
if (inputFlushTimer !== null) return;
|
|
20598
|
+
inputFlushTimer = window.setTimeout(flushInput, 12);
|
|
20599
|
+
};
|
|
20600
|
+
const fitAndResize = () => {
|
|
20601
|
+
const terminal = terminalRef.current;
|
|
20602
|
+
if (!terminal || !fitAddon) return;
|
|
20603
|
+
try {
|
|
20604
|
+
fitAddon.fit();
|
|
20605
|
+
} catch {
|
|
20606
|
+
return;
|
|
20607
|
+
}
|
|
20608
|
+
const id = terminalIdRef.current;
|
|
20609
|
+
if (!id) return;
|
|
20610
|
+
const resizeKey = `${terminal.cols}x${terminal.rows}`;
|
|
20611
|
+
if (resizeKey === lastResizeKey) return;
|
|
20612
|
+
lastResizeKey = resizeKey;
|
|
20613
|
+
postJson(`/api/terminal/${encodeURIComponent(id)}/resize`, {
|
|
20614
|
+
cols: terminal.cols,
|
|
20615
|
+
rows: terminal.rows
|
|
20616
|
+
}).catch(() => {});
|
|
20617
|
+
};
|
|
20618
|
+
const scheduleFitAndResize = () => {
|
|
20619
|
+
if (resizeFrame !== null) return;
|
|
20620
|
+
resizeFrame = window.requestAnimationFrame(() => {
|
|
20621
|
+
resizeFrame = null;
|
|
20622
|
+
fitAndResize();
|
|
20623
|
+
});
|
|
20624
|
+
};
|
|
20625
|
+
fitAndResizeRef.current = scheduleFitAndResize;
|
|
20626
|
+
const startTerminal = async () => {
|
|
20627
|
+
try {
|
|
20628
|
+
publishStatus({ type: "connecting" });
|
|
20629
|
+
terminalElement.textContent = "";
|
|
20630
|
+
const [{ Terminal }, { FitAddon }] = await Promise.all([import("../_libs/xterm__xterm.mjs").then((n) => n.t), import("../_libs/xterm__addon-fit.mjs").then((n) => n.t)]);
|
|
20631
|
+
if (disposed) return;
|
|
20632
|
+
const terminal = new Terminal({
|
|
20633
|
+
allowTransparency: true,
|
|
20634
|
+
convertEol: false,
|
|
20635
|
+
cursorBlink: true,
|
|
20636
|
+
fontFamily: createTerminalFontFamily(),
|
|
20637
|
+
fontSize: 12,
|
|
20638
|
+
letterSpacing: 0,
|
|
20639
|
+
lineHeight: 1.2,
|
|
20640
|
+
scrollback: 5e3,
|
|
20641
|
+
theme: createTerminalTheme()
|
|
20642
|
+
});
|
|
20643
|
+
fitAddon = new FitAddon();
|
|
20644
|
+
terminal.loadAddon(fitAddon);
|
|
20645
|
+
terminal.open(terminalElement);
|
|
20646
|
+
terminalRef.current = terminal;
|
|
20647
|
+
inputDisposable = terminal.onData((data) => {
|
|
20648
|
+
if (!activeRef.current) return;
|
|
20649
|
+
inputBuffer += data;
|
|
20650
|
+
scheduleInputFlush();
|
|
20651
|
+
});
|
|
20652
|
+
scheduleFitAndResize();
|
|
20653
|
+
const terminalResponse = await postJson("/api/terminal", {
|
|
20654
|
+
clientKey: tabId,
|
|
20655
|
+
cols: terminal.cols,
|
|
20656
|
+
rows: terminal.rows
|
|
20657
|
+
});
|
|
20658
|
+
if (disposed) return;
|
|
20659
|
+
terminalIdRef.current = terminalResponse.id;
|
|
20660
|
+
onTerminalIdChangeRef.current(tabId, terminalResponse.id);
|
|
20661
|
+
publishStatus({
|
|
20662
|
+
type: "connected",
|
|
20663
|
+
shell: terminalResponse.shell
|
|
20664
|
+
});
|
|
20665
|
+
eventSource = new EventSource(buildRequestUrl(`/api/terminal/${encodeURIComponent(terminalResponse.id)}/events`, requestOptions));
|
|
20666
|
+
eventSource.onmessage = (message) => {
|
|
20667
|
+
if (disposed) return;
|
|
20668
|
+
const event = JSON.parse(message.data);
|
|
20669
|
+
if (event.type === "output") {
|
|
20670
|
+
terminal.write(event.data);
|
|
20671
|
+
return;
|
|
20672
|
+
}
|
|
20673
|
+
if (event.type === "ready") {
|
|
20674
|
+
publishStatus({
|
|
20675
|
+
type: "connected",
|
|
20676
|
+
shell: event.shell
|
|
20677
|
+
});
|
|
20678
|
+
return;
|
|
20679
|
+
}
|
|
20680
|
+
if (event.type === "exit") {
|
|
20681
|
+
publishStatus(exitedStatus(event));
|
|
20682
|
+
return;
|
|
20683
|
+
}
|
|
20684
|
+
if (event.type === "error") publishStatus({
|
|
20685
|
+
type: "error",
|
|
20686
|
+
message: event.error
|
|
20687
|
+
});
|
|
20688
|
+
};
|
|
20689
|
+
eventSource.onerror = () => {
|
|
20690
|
+
if (!disposed && terminalIdRef.current) setStatus((current) => {
|
|
20691
|
+
if (current.type === "connected") return current;
|
|
20692
|
+
const nextStatus = {
|
|
20693
|
+
type: "error",
|
|
20694
|
+
message: "Terminal connection interrupted."
|
|
20695
|
+
};
|
|
20696
|
+
onStatusChangeRef.current(tabId, nextStatus);
|
|
20697
|
+
return nextStatus;
|
|
20698
|
+
});
|
|
20699
|
+
};
|
|
20700
|
+
resizeObserver = new ResizeObserver(scheduleFitAndResize);
|
|
20701
|
+
resizeObserver.observe(terminalElement);
|
|
20702
|
+
scheduleFitAndResize();
|
|
20703
|
+
} catch (error) {
|
|
20704
|
+
if (disposed) return;
|
|
20705
|
+
const message = errorMessage(error);
|
|
20706
|
+
publishStatus({
|
|
20707
|
+
type: "error",
|
|
20708
|
+
message
|
|
20709
|
+
});
|
|
20710
|
+
terminalRef.current?.writeln(`\r\n${message}`);
|
|
20711
|
+
}
|
|
20712
|
+
};
|
|
20713
|
+
startTerminal();
|
|
20714
|
+
return () => {
|
|
20715
|
+
disposed = true;
|
|
20716
|
+
if (inputFlushTimer !== null) window.clearTimeout(inputFlushTimer);
|
|
20717
|
+
if (resizeFrame !== null) window.cancelAnimationFrame(resizeFrame);
|
|
20718
|
+
flushInput();
|
|
20719
|
+
resizeObserver?.disconnect();
|
|
20720
|
+
eventSource?.close();
|
|
20721
|
+
inputDisposable?.dispose();
|
|
20722
|
+
terminalRef.current?.dispose();
|
|
20723
|
+
terminalRef.current = null;
|
|
20724
|
+
terminalIdRef.current = null;
|
|
20725
|
+
fitAndResizeRef.current = () => {};
|
|
20726
|
+
};
|
|
20727
|
+
}, [
|
|
20728
|
+
cwd,
|
|
20729
|
+
sessionId,
|
|
20730
|
+
tabId,
|
|
20731
|
+
viewerContextId
|
|
20732
|
+
]);
|
|
20733
|
+
import_react.useEffect(() => {
|
|
20734
|
+
const applyTheme = () => {
|
|
20735
|
+
const terminal = terminalRef.current;
|
|
20736
|
+
if (!terminal) return;
|
|
20737
|
+
terminal.options.theme = createTerminalTheme();
|
|
20738
|
+
terminal.options.fontFamily = createTerminalFontFamily();
|
|
20739
|
+
};
|
|
20740
|
+
const observer = new MutationObserver(applyTheme);
|
|
20741
|
+
observer.observe(document.documentElement, {
|
|
20742
|
+
attributeFilter: ["class", "data-pico-theme-mode"],
|
|
20743
|
+
attributes: true
|
|
20744
|
+
});
|
|
20745
|
+
applyTheme();
|
|
20746
|
+
return () => observer.disconnect();
|
|
20747
|
+
}, []);
|
|
20748
|
+
import_react.useEffect(() => {
|
|
20749
|
+
if (!active) {
|
|
20750
|
+
terminalRef.current?.blur();
|
|
20751
|
+
return;
|
|
20752
|
+
}
|
|
20753
|
+
const frame = window.requestAnimationFrame(() => {
|
|
20754
|
+
fitAndResizeRef.current();
|
|
20755
|
+
terminalRef.current?.focus();
|
|
20756
|
+
});
|
|
20757
|
+
return () => window.cancelAnimationFrame(frame);
|
|
20758
|
+
}, [active, status]);
|
|
20759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20760
|
+
"aria-hidden": !selected,
|
|
20761
|
+
"data-terminal-tab": tabId,
|
|
20762
|
+
className: cn("absolute inset-0 min-h-0 w-full overflow-hidden bg-background", selected ? "z-10 opacity-100" : "pointer-events-none z-0 opacity-0"),
|
|
20763
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20764
|
+
ref: terminalElementRef,
|
|
20765
|
+
className: "h-full min-h-0 w-full"
|
|
20766
|
+
})
|
|
20767
|
+
});
|
|
20768
|
+
}
|
|
20769
|
+
function TerminalPanel({ active, className, cwd, onClose, sessionId, showCloseButton = true, viewerContextId }) {
|
|
20770
|
+
const normalizedCwd = cwd?.trim() || "";
|
|
20771
|
+
const scopeKey = `${viewerContextId}:${sessionId ?? "no-session"}:${normalizedCwd}`;
|
|
20772
|
+
const [tabsState, setTabsState] = import_react.useState(() => createTerminalTabsState(scopeKey));
|
|
20773
|
+
const [statusDialogTabId, setStatusDialogTabId] = import_react.useState(null);
|
|
20774
|
+
const tabs = tabsState.scopeKey === scopeKey ? tabsState.tabs : [];
|
|
20775
|
+
const selectedTabId = tabsState.scopeKey === scopeKey ? tabsState.activeTabId ?? tabs[0]?.id ?? null : null;
|
|
20776
|
+
import_react.useEffect(() => {
|
|
20777
|
+
if (tabsState.scopeKey === scopeKey) return;
|
|
20778
|
+
setTabsState(createTerminalTabsState(scopeKey));
|
|
20779
|
+
}, [scopeKey, tabsState.scopeKey]);
|
|
20780
|
+
import_react.useEffect(() => {
|
|
20781
|
+
if (!active || !normalizedCwd || tabs.length > 0 || tabsState.scopeKey !== scopeKey) return;
|
|
20782
|
+
const tab = createTerminalTab();
|
|
20783
|
+
const nextState = {
|
|
20784
|
+
activeTabId: tab.id,
|
|
20785
|
+
scopeKey,
|
|
20786
|
+
tabs: [tab]
|
|
20787
|
+
};
|
|
20788
|
+
rememberTerminalTabsState(nextState);
|
|
20789
|
+
setTabsState(nextState);
|
|
20790
|
+
}, [
|
|
20791
|
+
active,
|
|
20792
|
+
normalizedCwd,
|
|
20793
|
+
scopeKey,
|
|
20794
|
+
tabs.length,
|
|
20795
|
+
tabsState.scopeKey
|
|
20796
|
+
]);
|
|
20797
|
+
const activeStatus = tabs.find((tab) => tab.id === selectedTabId)?.status ?? { type: "idle" };
|
|
20798
|
+
const activeError = activeStatus.type === "error" ? activeStatus.message : void 0;
|
|
20799
|
+
const statusDialogTab = tabs.find((tab) => tab.id === statusDialogTabId);
|
|
20800
|
+
const statusDialogTabIndex = statusDialogTab ? tabs.indexOf(statusDialogTab) : 0;
|
|
20801
|
+
const requestOptions = sessionId ? {
|
|
20802
|
+
contextId: viewerContextId,
|
|
20803
|
+
sessionId
|
|
20804
|
+
} : { contextId: viewerContextId };
|
|
20805
|
+
const addTerminalTab = () => {
|
|
20806
|
+
if (!normalizedCwd) return;
|
|
20807
|
+
const tab = createTerminalTab();
|
|
20808
|
+
setTabsState((current) => {
|
|
20809
|
+
const nextState = current.scopeKey !== scopeKey ? {
|
|
20810
|
+
activeTabId: tab.id,
|
|
20811
|
+
scopeKey,
|
|
20812
|
+
tabs: [tab]
|
|
20813
|
+
} : {
|
|
20814
|
+
...current,
|
|
20815
|
+
activeTabId: tab.id,
|
|
20816
|
+
tabs: [...current.tabs, tab]
|
|
20817
|
+
};
|
|
20818
|
+
rememberTerminalTabsState(nextState);
|
|
20819
|
+
return nextState;
|
|
20820
|
+
});
|
|
20821
|
+
};
|
|
20822
|
+
const closeServerTerminal = (terminalId) => {
|
|
20823
|
+
if (!terminalId) return;
|
|
20824
|
+
fetchJson(buildRequestUrl(`/api/terminal/${encodeURIComponent(terminalId)}/close`, requestOptions), { method: "POST" }).catch(() => {});
|
|
20825
|
+
};
|
|
20826
|
+
const closeTerminalTab = (tabId) => {
|
|
20827
|
+
if (tabs.length <= 0) return;
|
|
20828
|
+
closeServerTerminal(tabs.find((tab) => tab.id === tabId)?.terminalId ?? null);
|
|
20829
|
+
setTabsState((current) => {
|
|
20830
|
+
if (current.scopeKey !== scopeKey || current.tabs.length <= 0) return current;
|
|
20831
|
+
const closingIndex = current.tabs.findIndex((tab) => tab.id === tabId);
|
|
20832
|
+
const nextTabs = current.tabs.filter((tab) => tab.id !== tabId);
|
|
20833
|
+
const nextActiveTabId = current.activeTabId === tabId ? nextTabs[Math.min(Math.max(closingIndex, 0), nextTabs.length - 1)]?.id ?? null : current.activeTabId;
|
|
20834
|
+
const nextState = {
|
|
20835
|
+
...current,
|
|
20836
|
+
activeTabId: nextActiveTabId,
|
|
20837
|
+
tabs: nextTabs
|
|
20838
|
+
};
|
|
20839
|
+
rememberTerminalTabsState(nextState);
|
|
20840
|
+
return nextState;
|
|
20841
|
+
});
|
|
20842
|
+
};
|
|
20843
|
+
const updateTabStatus = (tabId, status) => {
|
|
20844
|
+
setTabsState((current) => {
|
|
20845
|
+
if (current.scopeKey !== scopeKey) return current;
|
|
20846
|
+
return {
|
|
20847
|
+
...current,
|
|
20848
|
+
tabs: current.tabs.map((tab) => tab.id === tabId ? {
|
|
20849
|
+
...tab,
|
|
20850
|
+
status
|
|
20851
|
+
} : tab)
|
|
20852
|
+
};
|
|
20853
|
+
});
|
|
20854
|
+
};
|
|
20855
|
+
const updateTabTerminalId = (tabId, terminalId) => {
|
|
20856
|
+
setTabsState((current) => {
|
|
20857
|
+
if (current.scopeKey !== scopeKey) return current;
|
|
20858
|
+
return {
|
|
20859
|
+
...current,
|
|
20860
|
+
tabs: current.tabs.map((tab) => tab.id === tabId ? {
|
|
20861
|
+
...tab,
|
|
20862
|
+
terminalId
|
|
20863
|
+
} : tab)
|
|
20864
|
+
};
|
|
20865
|
+
});
|
|
20866
|
+
};
|
|
20867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
|
|
20868
|
+
"data-terminal-panel": "true",
|
|
20869
|
+
className: cn("pico-terminal-panel flex h-full min-h-0 w-full min-w-0 flex-col bg-background", className),
|
|
20870
|
+
onKeyDownCapture: (event) => {
|
|
20871
|
+
if (!isTerminalToggleEvent(event) || !onClose) return;
|
|
20872
|
+
event.preventDefault();
|
|
20873
|
+
event.stopPropagation();
|
|
20874
|
+
event.nativeEvent.stopImmediatePropagation();
|
|
20875
|
+
onClose();
|
|
20876
|
+
},
|
|
20877
|
+
children: [
|
|
20878
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20879
|
+
className: "flex min-h-10 shrink-0 items-center gap-2 border-b border-border/70 px-2",
|
|
20880
|
+
children: [
|
|
20881
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20882
|
+
className: "hidden max-w-56 min-w-0 flex-col gap-0 px-1 sm:flex",
|
|
20883
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20884
|
+
className: "truncate text-xs font-medium",
|
|
20885
|
+
children: "Terminal"
|
|
20886
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20887
|
+
className: "flex min-w-0 items-center gap-1 truncate text-[11px] text-muted-foreground",
|
|
20888
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TerminalStatusDot, { status: activeStatus }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20889
|
+
className: "truncate",
|
|
20890
|
+
children: normalizedCwd ? formatDisplayPath$1(normalizedCwd) : "No cwd"
|
|
20891
|
+
})]
|
|
20892
|
+
})]
|
|
20893
|
+
}),
|
|
20894
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20895
|
+
className: "flex min-w-0 flex-1 items-center gap-1 overflow-x-auto py-1",
|
|
20896
|
+
children: [tabs.map((tab, index) => {
|
|
20897
|
+
const selected = tab.id === selectedTabId;
|
|
20898
|
+
const label = terminalTabLabel(tab, index);
|
|
20899
|
+
const statusText = terminalStatusText(tab.status);
|
|
20900
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20901
|
+
className: cn("group flex h-7 max-w-48 shrink-0 items-center overflow-hidden rounded-md border text-xs", selected ? "border-border bg-muted text-foreground" : "border-transparent bg-transparent text-muted-foreground hover:bg-muted/60 hover:text-foreground"),
|
|
20902
|
+
children: [
|
|
20903
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
20904
|
+
title: `${label} · ${statusText}`,
|
|
20905
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
20906
|
+
type: "button",
|
|
20907
|
+
className: "flex h-full w-7 shrink-0 items-center justify-center outline-hidden focus-visible:ring-1 focus-visible:ring-ring",
|
|
20908
|
+
"aria-label": `Show ${label} status`,
|
|
20909
|
+
onClick: (event) => {
|
|
20910
|
+
event.stopPropagation();
|
|
20911
|
+
setStatusDialogTabId(tab.id);
|
|
20912
|
+
},
|
|
20913
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TerminalStatusDot, { status: tab.status })
|
|
20914
|
+
})
|
|
20915
|
+
}),
|
|
20916
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
20917
|
+
title: `${label} · ${statusText}`,
|
|
20918
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
20919
|
+
type: "button",
|
|
20920
|
+
className: "flex h-full min-w-0 flex-1 items-center px-1 text-left outline-hidden focus-visible:ring-1 focus-visible:ring-ring",
|
|
20921
|
+
onClick: () => {
|
|
20922
|
+
setTabsState((current) => {
|
|
20923
|
+
if (current.scopeKey !== scopeKey) return current;
|
|
20924
|
+
const nextState = {
|
|
20925
|
+
...current,
|
|
20926
|
+
activeTabId: tab.id
|
|
20927
|
+
};
|
|
20928
|
+
rememberTerminalTabsState(nextState);
|
|
20929
|
+
return nextState;
|
|
20930
|
+
});
|
|
20931
|
+
},
|
|
20932
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20933
|
+
className: "truncate",
|
|
20934
|
+
children: label
|
|
20935
|
+
})
|
|
20936
|
+
})
|
|
20937
|
+
}),
|
|
20938
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
20939
|
+
title: `Close ${label}`,
|
|
20940
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
20941
|
+
type: "button",
|
|
20942
|
+
className: "flex h-full w-6 shrink-0 items-center justify-center text-muted-foreground opacity-70 outline-hidden group-hover:opacity-100 hover:bg-muted hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-30",
|
|
20943
|
+
"aria-label": `Close ${label}`,
|
|
20944
|
+
onClick: (event) => {
|
|
20945
|
+
event.stopPropagation();
|
|
20946
|
+
closeTerminalTab(tab.id);
|
|
20947
|
+
},
|
|
20948
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-3" })
|
|
20949
|
+
})
|
|
20950
|
+
})
|
|
20951
|
+
]
|
|
20952
|
+
}, tab.id);
|
|
20953
|
+
}), normalizedCwd ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
20954
|
+
title: "New terminal tab",
|
|
20955
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
20956
|
+
size: "icon",
|
|
20957
|
+
variant: "ghost",
|
|
20958
|
+
className: "size-7 shrink-0",
|
|
20959
|
+
"aria-label": "New terminal tab",
|
|
20960
|
+
onClick: addTerminalTab,
|
|
20961
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Plus, { className: "size-4" })
|
|
20962
|
+
})
|
|
20963
|
+
}) : null]
|
|
20964
|
+
}),
|
|
20965
|
+
activeError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
20966
|
+
title: activeError,
|
|
20967
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20968
|
+
className: "hidden max-w-48 truncate text-[11px] text-destructive sm:inline",
|
|
20969
|
+
children: activeError
|
|
20970
|
+
})
|
|
20971
|
+
}) : null,
|
|
20972
|
+
onClose && showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
20973
|
+
title: "Hide terminal",
|
|
20974
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
20975
|
+
size: "icon",
|
|
20976
|
+
variant: "ghost",
|
|
20977
|
+
className: "size-8 shrink-0",
|
|
20978
|
+
"aria-label": "Hide terminal",
|
|
20979
|
+
onClick: onClose,
|
|
20980
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, {})
|
|
20981
|
+
})
|
|
20982
|
+
}) : null
|
|
20983
|
+
]
|
|
20984
|
+
}),
|
|
20985
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TerminalStatusDialog, {
|
|
20986
|
+
cwd: normalizedCwd,
|
|
20987
|
+
index: statusDialogTabIndex,
|
|
20988
|
+
open: statusDialogTab !== void 0,
|
|
20989
|
+
tab: statusDialogTab,
|
|
20990
|
+
onOpenChange: (open) => {
|
|
20991
|
+
if (!open) setStatusDialogTabId(null);
|
|
20992
|
+
}
|
|
20993
|
+
}),
|
|
20994
|
+
normalizedCwd ? tabs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20995
|
+
className: "relative min-h-0 flex-1 overflow-hidden bg-background",
|
|
20996
|
+
children: tabs.map((tab) => {
|
|
20997
|
+
const selected = tab.id === selectedTabId;
|
|
20998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TerminalTabPane, {
|
|
20999
|
+
active: active && selected,
|
|
21000
|
+
cwd: normalizedCwd,
|
|
21001
|
+
onStatusChange: updateTabStatus,
|
|
21002
|
+
onTerminalIdChange: updateTabTerminalId,
|
|
21003
|
+
selected,
|
|
21004
|
+
sessionId,
|
|
21005
|
+
tabId: tab.id,
|
|
21006
|
+
viewerContextId
|
|
21007
|
+
}, tab.id);
|
|
21008
|
+
})
|
|
21009
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
21010
|
+
className: "flex min-h-0 flex-1 flex-col items-center justify-center gap-3 p-6 text-sm text-muted-foreground",
|
|
21011
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "No terminal tabs are open." }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button$1, {
|
|
21012
|
+
size: "sm",
|
|
21013
|
+
variant: "outline",
|
|
21014
|
+
onClick: addTerminalTab,
|
|
21015
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Plus, { className: "size-4" }), "New terminal tab"]
|
|
21016
|
+
})]
|
|
21017
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
21018
|
+
className: "flex min-h-0 flex-1 items-center justify-center p-6 text-sm text-muted-foreground",
|
|
21019
|
+
children: "Open a session before starting a terminal."
|
|
21020
|
+
})
|
|
21021
|
+
]
|
|
21022
|
+
});
|
|
21023
|
+
}
|
|
20252
21024
|
function readStoredRightSidebarActiveTab() {
|
|
20253
21025
|
const stored = safeLocalStorageGetItem(RIGHT_SIDEBAR_ACTIVE_TAB_STORAGE_KEY);
|
|
20254
21026
|
return stored === "files" || stored === "review" ? stored : "review";
|
|
@@ -20363,22 +21135,33 @@ function reorderRightSidebarFiles(store, paths) {
|
|
|
20363
21135
|
fileTabs: uniquePaths
|
|
20364
21136
|
}));
|
|
20365
21137
|
}
|
|
21138
|
+
function shallowTerminalSession(left, right) {
|
|
21139
|
+
return left.cwd === right.cwd && left.sessionId === right.sessionId;
|
|
21140
|
+
}
|
|
20366
21141
|
function AppShellTabsList({ sessionStore, viewerContextId }) {
|
|
20367
21142
|
const cwd = useSelector(sessionStore, (sessionState) => sessionState.cwd);
|
|
20368
21143
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TabsList, {
|
|
20369
21144
|
className: "w-full gap-2 rounded-none border-b border-border/70 bg-background p-2 group-data-horizontal/tabs:h-auto md:hidden",
|
|
20370
|
-
children: [
|
|
20371
|
-
|
|
20372
|
-
|
|
20373
|
-
|
|
20374
|
-
|
|
20375
|
-
|
|
20376
|
-
|
|
20377
|
-
|
|
20378
|
-
|
|
20379
|
-
|
|
21145
|
+
children: [
|
|
21146
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsTrigger, {
|
|
21147
|
+
value: "session",
|
|
21148
|
+
className: "h-8 data-active:bg-muted dark:data-active:bg-muted",
|
|
21149
|
+
children: "Session"
|
|
21150
|
+
}),
|
|
21151
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsTrigger, {
|
|
21152
|
+
value: "git",
|
|
21153
|
+
className: "h-8 data-active:bg-muted dark:data-active:bg-muted",
|
|
21154
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitTabStatusText, {
|
|
21155
|
+
viewerContextId,
|
|
21156
|
+
cwd
|
|
21157
|
+
})
|
|
21158
|
+
}),
|
|
21159
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsTrigger, {
|
|
21160
|
+
value: "terminal",
|
|
21161
|
+
className: "h-8 data-active:bg-muted dark:data-active:bg-muted",
|
|
21162
|
+
children: "Terminal"
|
|
20380
21163
|
})
|
|
20381
|
-
|
|
21164
|
+
]
|
|
20382
21165
|
});
|
|
20383
21166
|
}
|
|
20384
21167
|
var AppShellGitPanelController = import_react.memo(function AppShellGitPanelController({ active, composerDiffLineComments, onAddDiffLineComment, onCloseAllFiles, onCloseFile, onCloseFilesToRight, onCloseOtherFiles, onOpenFile, onReorderFiles, rightSidebarStore, sessionStore, viewerContextId }) {
|
|
@@ -20457,6 +21240,10 @@ var DESKTOP_DEFAULT_GIT_PANEL_WIDTH = 320;
|
|
|
20457
21240
|
var DESKTOP_MIN_SESSION_WIDTH = 320;
|
|
20458
21241
|
var DESKTOP_MIN_SIDE_PANEL_WIDTH = 260;
|
|
20459
21242
|
var DESKTOP_MAX_STORED_SIDE_PANEL_WIDTH = 1600;
|
|
21243
|
+
var DESKTOP_DEFAULT_TERMINAL_PANEL_HEIGHT = 280;
|
|
21244
|
+
var DESKTOP_MIN_TERMINAL_PANEL_HEIGHT = 160;
|
|
21245
|
+
var DESKTOP_MIN_TOP_PANEL_HEIGHT = 220;
|
|
21246
|
+
var DESKTOP_MAX_STORED_TERMINAL_PANEL_HEIGHT = 1200;
|
|
20460
21247
|
function defaultDesktopSidePanelWidths() {
|
|
20461
21248
|
return {
|
|
20462
21249
|
fileViewWidth: DESKTOP_DEFAULT_FILE_VIEW_WIDTH,
|
|
@@ -20491,6 +21278,18 @@ function storeDesktopSidePanelWidths(widths) {
|
|
|
20491
21278
|
function sameDesktopSidePanelWidths(left, right) {
|
|
20492
21279
|
return left.fileViewWidth === right.fileViewWidth && left.gitPanelWidth === right.gitPanelWidth;
|
|
20493
21280
|
}
|
|
21281
|
+
function clampStoredDesktopTerminalPanelHeight(value) {
|
|
21282
|
+
if (value == null || value === "") return DESKTOP_DEFAULT_TERMINAL_PANEL_HEIGHT;
|
|
21283
|
+
const height = typeof value === "number" ? value : Number(value);
|
|
21284
|
+
if (!Number.isFinite(height)) return DESKTOP_DEFAULT_TERMINAL_PANEL_HEIGHT;
|
|
21285
|
+
return Math.round(Math.min(DESKTOP_MAX_STORED_TERMINAL_PANEL_HEIGHT, Math.max(DESKTOP_MIN_TERMINAL_PANEL_HEIGHT, height)));
|
|
21286
|
+
}
|
|
21287
|
+
function readStoredDesktopTerminalPanelHeight() {
|
|
21288
|
+
return clampStoredDesktopTerminalPanelHeight(safeLocalStorageGetItem(TERMINAL_PANEL_HEIGHT_STORAGE_KEY));
|
|
21289
|
+
}
|
|
21290
|
+
function storeDesktopTerminalPanelHeight(height) {
|
|
21291
|
+
safeLocalStorageSetItem(TERMINAL_PANEL_HEIGHT_STORAGE_KEY, String(clampStoredDesktopTerminalPanelHeight(height)));
|
|
21292
|
+
}
|
|
20494
21293
|
function clampDesktopPanelSize(value, min, max) {
|
|
20495
21294
|
if (!Number.isFinite(value)) return min;
|
|
20496
21295
|
if (max <= min) return Math.max(0, max);
|
|
@@ -20614,21 +21413,106 @@ function AppShellDesktopResizeHandle({ label, max, min, onResize, onResizeEnd, o
|
|
|
20614
21413
|
}
|
|
20615
21414
|
});
|
|
20616
21415
|
}
|
|
21416
|
+
function AppShellDesktopVerticalResizeHandle({ label, max, min, onResize, onResizeEnd, onResizeStart, size }) {
|
|
21417
|
+
const propsRef = useLatestRef({
|
|
21418
|
+
max,
|
|
21419
|
+
min,
|
|
21420
|
+
onResize,
|
|
21421
|
+
onResizeEnd,
|
|
21422
|
+
onResizeStart,
|
|
21423
|
+
size
|
|
21424
|
+
});
|
|
21425
|
+
const [verticalResizeCursor, setVerticalResizeCursor] = import_react.useState("row-resize");
|
|
21426
|
+
const [resizeTargetMinimumSize, setResizeTargetMinimumSize] = import_react.useState(10);
|
|
21427
|
+
import_react.useEffect(() => {
|
|
21428
|
+
const updateResizeTarget = () => {
|
|
21429
|
+
setResizeTargetMinimumSize(getSidebarResizeTargetMinimumSize());
|
|
21430
|
+
};
|
|
21431
|
+
const coarsePointerQuery = window.matchMedia("(pointer:coarse)");
|
|
21432
|
+
setVerticalResizeCursor(getSidebarVerticalResizeCursor());
|
|
21433
|
+
updateResizeTarget();
|
|
21434
|
+
coarsePointerQuery.addEventListener("change", updateResizeTarget);
|
|
21435
|
+
return () => {
|
|
21436
|
+
coarsePointerQuery.removeEventListener("change", updateResizeTarget);
|
|
21437
|
+
};
|
|
21438
|
+
}, []);
|
|
21439
|
+
const verticalResizeCursorClass = verticalResizeCursor === "ns-resize" ? "cursor-ns-resize" : "cursor-row-resize";
|
|
21440
|
+
const resizeTo = (nextSize) => {
|
|
21441
|
+
const current = propsRef.current;
|
|
21442
|
+
current.onResize(clampDesktopPanelSize(nextSize, current.min, current.max));
|
|
21443
|
+
};
|
|
21444
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
21445
|
+
role: "separator",
|
|
21446
|
+
"aria-label": label,
|
|
21447
|
+
"aria-orientation": "horizontal",
|
|
21448
|
+
tabIndex: 0,
|
|
21449
|
+
style: {
|
|
21450
|
+
"--resize-target-height": `${resizeTargetMinimumSize}px`,
|
|
21451
|
+
cursor: verticalResizeCursor
|
|
21452
|
+
},
|
|
21453
|
+
className: `absolute inset-x-0 top-0 z-20 h-(--resize-target-height) -translate-y-1/2 touch-none bg-transparent outline-hidden after:absolute after:inset-x-0 after:top-1/2 after:h-px after:bg-transparent focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 ${resizeRailPrimaryInteractiveClass} ${verticalResizeCursorClass}`,
|
|
21454
|
+
onKeyDown: (event) => {
|
|
21455
|
+
if (event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
|
|
21456
|
+
event.preventDefault();
|
|
21457
|
+
const delta = event.shiftKey ? 48 : 16;
|
|
21458
|
+
resizeTo(propsRef.current.size + (event.key === "ArrowUp" ? delta : -delta));
|
|
21459
|
+
},
|
|
21460
|
+
onPointerDown: (event) => {
|
|
21461
|
+
if (event.button !== 0) return;
|
|
21462
|
+
event.preventDefault();
|
|
21463
|
+
const current = propsRef.current;
|
|
21464
|
+
const startY = event.clientY;
|
|
21465
|
+
const startSize = current.size;
|
|
21466
|
+
const cursor = getSidebarVerticalResizeCursor();
|
|
21467
|
+
const previousCursor = document.body.style.cursor;
|
|
21468
|
+
const previousUserSelect = document.body.style.userSelect;
|
|
21469
|
+
const cleanupGlobalResizeCursor = installGlobalResizeCursor(cursor);
|
|
21470
|
+
current.onResizeStart?.();
|
|
21471
|
+
Object.assign(document.body.style, {
|
|
21472
|
+
userSelect: "none",
|
|
21473
|
+
cursor
|
|
21474
|
+
});
|
|
21475
|
+
const handlePointerMove = (moveEvent) => {
|
|
21476
|
+
resizeTo(startSize + startY - moveEvent.clientY);
|
|
21477
|
+
};
|
|
21478
|
+
const handlePointerUp = () => {
|
|
21479
|
+
cleanupGlobalResizeCursor();
|
|
21480
|
+
Object.assign(document.body.style, {
|
|
21481
|
+
userSelect: previousUserSelect,
|
|
21482
|
+
cursor: previousCursor
|
|
21483
|
+
});
|
|
21484
|
+
document.removeEventListener("pointermove", handlePointerMove);
|
|
21485
|
+
document.removeEventListener("pointerup", handlePointerUp);
|
|
21486
|
+
document.removeEventListener("pointercancel", handlePointerUp);
|
|
21487
|
+
propsRef.current.onResizeEnd?.();
|
|
21488
|
+
};
|
|
21489
|
+
document.addEventListener("pointermove", handlePointerMove);
|
|
21490
|
+
document.addEventListener("pointerup", handlePointerUp);
|
|
21491
|
+
document.addEventListener("pointercancel", handlePointerUp);
|
|
21492
|
+
}
|
|
21493
|
+
});
|
|
21494
|
+
}
|
|
20617
21495
|
function AppShellTabsController(props) {
|
|
20618
21496
|
return useAppShellTabsControllerView(props);
|
|
20619
21497
|
}
|
|
20620
|
-
function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTurn, composerDiffLineComments, composerPanelRef, contextUsageStore, conversationFrameRef, conversationItemsStore, defaultNewSessionDirectory, displaySettingsStore, fileInputRef, gitPanelOpen, hiddenThinkingPreviewStore, isSessionViewLoading, isSubmitting, isMobile, newSessionDirectoryOptions, onCancelCompaction, onCreateSession, onOpenAddDirectoryDialog, onCloseAllFileViewTabs, onCloseFileViewTab, onCloseFileViewTabsToRight, onCloseOtherFileViewTabs, onAddDiffLineComment, onOpenFileViewTab, onReorderFileViewTabs, onValueChange, rightSidebarStore, sessionStore, store, viewerContextId, workingStateStore }) {
|
|
21498
|
+
function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTurn, composerDiffLineComments, composerPanelRef, contextUsageStore, conversationFrameRef, conversationItemsStore, defaultNewSessionDirectory, displaySettingsStore, fileInputRef, gitPanelOpen, terminalPanelOpen, hiddenThinkingPreviewStore, isSessionViewLoading, isSubmitting, isMobile, newSessionDirectoryOptions, onCancelCompaction, onCreateSession, onOpenAddDirectoryDialog, onCloseAllFileViewTabs, onCloseFileViewTab, onCloseFileViewTabsToRight, onCloseOtherFileViewTabs, onCloseTerminalPanel, onAddDiffLineComment, onOpenFileViewTab, onReorderFileViewTabs, onValueChange, rightSidebarStore, sessionStore, store, viewerContextId, workingStateStore }) {
|
|
20621
21499
|
const currentTab = useSelector(appUiStore, (state) => state.currentTab);
|
|
20622
21500
|
const isDraftSession = useSelector(sessionStore, (sessionState) => sessionState.draft);
|
|
21501
|
+
const terminalSession = useSelector(sessionStore, (sessionState) => ({
|
|
21502
|
+
cwd: sessionState.cwd,
|
|
21503
|
+
sessionId: sessionState.sessionId
|
|
21504
|
+
}), { compare: shallowTerminalSession });
|
|
20623
21505
|
const showTabsList = isMobile || !isDraftSession || isSessionViewLoading;
|
|
20624
|
-
const sessionVisibleClassName = currentTab === "
|
|
21506
|
+
const sessionVisibleClassName = currentTab === "session" ? "flex min-h-0 flex-1 flex-col" : "hidden min-h-0 flex-1 flex-col md:flex";
|
|
20625
21507
|
const mobileGitClassName = currentTab === "git" ? "min-h-0 flex-1 overflow-hidden md:hidden" : "hidden";
|
|
21508
|
+
const mobileTerminalClassName = currentTab === "terminal" ? "min-h-0 flex-1 overflow-hidden md:hidden" : "hidden";
|
|
20626
21509
|
const rightSidebarHasVisibleFiles = useSelector(rightSidebarStore, selectRightSidebarHasVisibleFiles);
|
|
20627
21510
|
const desktopGitPanelOpen = !isMobile && gitPanelOpen;
|
|
20628
21511
|
const desktopFileViewOpen = !isMobile && gitPanelOpen && rightSidebarHasVisibleFiles;
|
|
20629
21512
|
const desktopSideWorkspaceOpen = desktopFileViewOpen || desktopGitPanelOpen;
|
|
20630
21513
|
const desktopLayoutRef = import_react.useRef(null);
|
|
20631
21514
|
const [desktopLayoutWidth, setDesktopLayoutWidth] = import_react.useState(0);
|
|
21515
|
+
const [desktopLayoutHeight, setDesktopLayoutHeight] = import_react.useState(0);
|
|
20632
21516
|
const [desktopSidePanelWidths, setDesktopSidePanelWidthsState] = import_react.useState(() => defaultDesktopSidePanelWidths());
|
|
20633
21517
|
const desktopSidePanelWidthsLoadedRef = import_react.useRef(false);
|
|
20634
21518
|
const desktopSidePanelWidthsRef = import_react.useRef(desktopSidePanelWidths);
|
|
@@ -20656,12 +21540,30 @@ function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTu
|
|
|
20656
21540
|
}));
|
|
20657
21541
|
};
|
|
20658
21542
|
const [desktopGitPanelMounted, setDesktopGitPanelMounted] = import_react.useState(desktopGitPanelOpen);
|
|
21543
|
+
const [desktopTerminalPanelHeight, setDesktopTerminalPanelHeightState] = import_react.useState(() => DESKTOP_DEFAULT_TERMINAL_PANEL_HEIGHT);
|
|
21544
|
+
const desktopTerminalPanelHeightLoadedRef = import_react.useRef(false);
|
|
21545
|
+
const desktopTerminalPanelHeightRef = import_react.useRef(desktopTerminalPanelHeight);
|
|
21546
|
+
desktopTerminalPanelHeightRef.current = desktopTerminalPanelHeight;
|
|
21547
|
+
const [desktopTerminalPanelMounted, setDesktopTerminalPanelMounted] = import_react.useState(!isMobile && terminalPanelOpen);
|
|
20659
21548
|
const [desktopPanelResizing, setDesktopPanelResizing] = import_react.useState(false);
|
|
21549
|
+
const [desktopTerminalResizing, setDesktopTerminalResizing] = import_react.useState(false);
|
|
21550
|
+
const setDesktopTerminalPanelHeight = (action) => {
|
|
21551
|
+
const current = desktopTerminalPanelHeightRef.current;
|
|
21552
|
+
const next = clampStoredDesktopTerminalPanelHeight(applyStoreAction(current, action));
|
|
21553
|
+
if (current === next) return;
|
|
21554
|
+
desktopTerminalPanelHeightRef.current = next;
|
|
21555
|
+
setDesktopTerminalPanelHeightState(next);
|
|
21556
|
+
if (desktopTerminalPanelHeightLoadedRef.current) storeDesktopTerminalPanelHeight(next);
|
|
21557
|
+
};
|
|
20660
21558
|
import_react.useEffect(() => {
|
|
20661
21559
|
const storedWidths = readStoredDesktopSidePanelWidths();
|
|
21560
|
+
const storedTerminalPanelHeight = readStoredDesktopTerminalPanelHeight();
|
|
20662
21561
|
desktopSidePanelWidthsLoadedRef.current = true;
|
|
21562
|
+
desktopTerminalPanelHeightLoadedRef.current = true;
|
|
20663
21563
|
desktopSidePanelWidthsRef.current = storedWidths;
|
|
21564
|
+
desktopTerminalPanelHeightRef.current = storedTerminalPanelHeight;
|
|
20664
21565
|
setDesktopSidePanelWidthsState((current) => sameDesktopSidePanelWidths(current, storedWidths) ? current : storedWidths);
|
|
21566
|
+
setDesktopTerminalPanelHeightState((current) => current === storedTerminalPanelHeight ? current : storedTerminalPanelHeight);
|
|
20665
21567
|
}, []);
|
|
20666
21568
|
const sessionPane = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20667
21569
|
className: "flex h-full min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
|
|
@@ -20689,7 +21591,7 @@ function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTu
|
|
|
20689
21591
|
viewerContextId,
|
|
20690
21592
|
workingStateStore
|
|
20691
21593
|
})
|
|
20692
|
-
}), isMobile ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
21594
|
+
}), isMobile ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20693
21595
|
className: mobileGitClassName,
|
|
20694
21596
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppShellGitPanelController, {
|
|
20695
21597
|
viewerContextId,
|
|
@@ -20705,32 +21607,50 @@ function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTu
|
|
|
20705
21607
|
onOpenFile: onOpenFileViewTab,
|
|
20706
21608
|
onReorderFiles: onReorderFileViewTabs
|
|
20707
21609
|
})
|
|
20708
|
-
})
|
|
21610
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
21611
|
+
className: mobileTerminalClassName,
|
|
21612
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TerminalPanel, {
|
|
21613
|
+
active: currentTab === "terminal",
|
|
21614
|
+
cwd: terminalSession.cwd,
|
|
21615
|
+
onClose: onCloseTerminalPanel,
|
|
21616
|
+
sessionId: terminalSession.sessionId,
|
|
21617
|
+
showCloseButton: false,
|
|
21618
|
+
viewerContextId
|
|
21619
|
+
})
|
|
21620
|
+
})] }) : null]
|
|
20709
21621
|
});
|
|
20710
21622
|
import_react.useLayoutEffect(() => {
|
|
20711
21623
|
if (isMobile) {
|
|
20712
21624
|
setDesktopGitPanelMounted(false);
|
|
21625
|
+
setDesktopTerminalPanelMounted(false);
|
|
20713
21626
|
return;
|
|
20714
21627
|
}
|
|
20715
21628
|
if (desktopSideWorkspaceOpen) setDesktopGitPanelMounted(true);
|
|
20716
|
-
|
|
21629
|
+
if (terminalPanelOpen) setDesktopTerminalPanelMounted(true);
|
|
21630
|
+
}, [
|
|
21631
|
+
desktopSideWorkspaceOpen,
|
|
21632
|
+
isMobile,
|
|
21633
|
+
terminalPanelOpen
|
|
21634
|
+
]);
|
|
20717
21635
|
import_react.useLayoutEffect(() => {
|
|
20718
21636
|
if (isMobile) return;
|
|
20719
21637
|
const element = desktopLayoutRef.current;
|
|
20720
21638
|
if (!element) return;
|
|
20721
|
-
const
|
|
21639
|
+
const updateSize = () => {
|
|
20722
21640
|
setDesktopLayoutWidth(element.clientWidth);
|
|
21641
|
+
setDesktopLayoutHeight(element.clientHeight);
|
|
20723
21642
|
};
|
|
20724
|
-
|
|
21643
|
+
updateSize();
|
|
20725
21644
|
if (typeof ResizeObserver === "undefined") {
|
|
20726
|
-
window.addEventListener("resize",
|
|
20727
|
-
return () => window.removeEventListener("resize",
|
|
21645
|
+
window.addEventListener("resize", updateSize);
|
|
21646
|
+
return () => window.removeEventListener("resize", updateSize);
|
|
20728
21647
|
}
|
|
20729
|
-
const observer = new ResizeObserver(
|
|
21648
|
+
const observer = new ResizeObserver(updateSize);
|
|
20730
21649
|
observer.observe(element);
|
|
20731
21650
|
return () => observer.disconnect();
|
|
20732
21651
|
}, [isMobile]);
|
|
20733
21652
|
const desktopAvailableWidth = desktopLayoutWidth || (typeof window === "undefined" ? 1200 : window.innerWidth);
|
|
21653
|
+
const desktopAvailableHeight = desktopLayoutHeight || (typeof window === "undefined" ? 800 : window.innerHeight);
|
|
20734
21654
|
const desktopGitPanelRendered = desktopSideWorkspaceOpen || desktopGitPanelMounted || desktopGitPanelOpen;
|
|
20735
21655
|
const desktopFittedWidths = fitDesktopSidePanelWidths({
|
|
20736
21656
|
availableWidth: desktopAvailableWidth,
|
|
@@ -20741,14 +21661,25 @@ function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTu
|
|
|
20741
21661
|
});
|
|
20742
21662
|
const desktopSideWorkspaceRendered = desktopSideWorkspaceOpen || desktopGitPanelMounted;
|
|
20743
21663
|
const desktopSideWorkspaceWidth = desktopSideWorkspaceOpen ? desktopFittedWidths.sideWidth : 0;
|
|
20744
|
-
const
|
|
20745
|
-
const
|
|
21664
|
+
const desktopTerminalOpen = !isMobile && terminalPanelOpen;
|
|
21665
|
+
const desktopTerminalRendered = desktopTerminalOpen || desktopTerminalPanelMounted;
|
|
21666
|
+
const desktopTerminalMaxHeight = Math.max(DESKTOP_MIN_TERMINAL_PANEL_HEIGHT, desktopAvailableHeight - DESKTOP_MIN_TOP_PANEL_HEIGHT);
|
|
21667
|
+
const desktopFittedTerminalPanelHeight = clampDesktopPanelSize(desktopTerminalPanelHeight, Math.min(DESKTOP_MIN_TERMINAL_PANEL_HEIGHT, desktopTerminalMaxHeight), desktopTerminalMaxHeight);
|
|
21668
|
+
const desktopTerminalVisibleHeight = desktopTerminalOpen ? desktopFittedTerminalPanelHeight : 0;
|
|
21669
|
+
const desktopTransitionClassName = !desktopPanelResizing && !desktopTerminalResizing ? "transition-[width,height] duration-200 ease-linear" : "";
|
|
21670
|
+
const desktopPanelGroupClassName = "relative flex min-h-0 w-full shrink-0 overflow-hidden";
|
|
20746
21671
|
const desktopResizeStart = () => {
|
|
20747
21672
|
setDesktopPanelResizing(true);
|
|
20748
21673
|
};
|
|
20749
21674
|
const desktopResizeEnd = () => {
|
|
20750
21675
|
setDesktopPanelResizing(false);
|
|
20751
21676
|
};
|
|
21677
|
+
const desktopTerminalResizeStart = () => {
|
|
21678
|
+
setDesktopTerminalResizing(true);
|
|
21679
|
+
};
|
|
21680
|
+
const desktopTerminalResizeEnd = () => {
|
|
21681
|
+
setDesktopTerminalResizing(false);
|
|
21682
|
+
};
|
|
20752
21683
|
const desktopSideWorkspaceMaxWidth = Math.max(0, desktopAvailableWidth - DESKTOP_MIN_SESSION_WIDTH);
|
|
20753
21684
|
const setDesktopSideWorkspaceWidth = (nextSize) => {
|
|
20754
21685
|
if (!desktopFileViewOpen) {
|
|
@@ -20757,6 +21688,9 @@ function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTu
|
|
|
20757
21688
|
}
|
|
20758
21689
|
setDesktopFileViewWidth(Math.max(DESKTOP_MIN_SIDE_PANEL_WIDTH, nextSize - desktopGitPanelWidth));
|
|
20759
21690
|
};
|
|
21691
|
+
const setDesktopTerminalHeight = (nextSize) => {
|
|
21692
|
+
setDesktopTerminalPanelHeight(clampDesktopPanelSize(nextSize, Math.min(DESKTOP_MIN_TERMINAL_PANEL_HEIGHT, desktopTerminalMaxHeight), desktopTerminalMaxHeight));
|
|
21693
|
+
};
|
|
20760
21694
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tabs$1, {
|
|
20761
21695
|
value: currentTab,
|
|
20762
21696
|
onValueChange,
|
|
@@ -20769,54 +21703,83 @@ function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTu
|
|
|
20769
21703
|
children: sessionPane
|
|
20770
21704
|
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20771
21705
|
ref: desktopLayoutRef,
|
|
20772
|
-
className:
|
|
20773
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.
|
|
20774
|
-
|
|
20775
|
-
|
|
20776
|
-
|
|
20777
|
-
|
|
20778
|
-
|
|
20779
|
-
|
|
20780
|
-
|
|
20781
|
-
|
|
20782
|
-
|
|
20783
|
-
|
|
20784
|
-
|
|
20785
|
-
|
|
20786
|
-
|
|
20787
|
-
className: `relative h-full min-h-0 min-w-0 shrink-0 overflow-visible ${desktopTransitionClassName}`,
|
|
21706
|
+
className: "flex min-h-0 flex-1 flex-col overflow-hidden",
|
|
21707
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
21708
|
+
className: desktopPanelGroupClassName,
|
|
21709
|
+
style: { height: desktopTerminalOpen ? `calc(100% - ${desktopTerminalVisibleHeight}px)` : "100%" },
|
|
21710
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
21711
|
+
"data-desktop-panel": "session",
|
|
21712
|
+
className: `h-full min-h-0 min-w-0 shrink-0 overflow-hidden max-md:w-full! ${desktopTransitionClassName}`,
|
|
21713
|
+
style: { width: desktopSideWorkspaceOpen ? `calc(100% - ${desktopSideWorkspaceWidth}px)` : "100%" },
|
|
21714
|
+
children: sessionPane
|
|
21715
|
+
}), desktopSideWorkspaceRendered ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("aside", {
|
|
21716
|
+
"aria-label": "Desktop side workspace",
|
|
21717
|
+
"aria-hidden": !desktopSideWorkspaceOpen,
|
|
21718
|
+
"data-state": desktopSideWorkspaceOpen ? "open" : "closed",
|
|
21719
|
+
"data-desktop-panel": "side-workspace",
|
|
21720
|
+
className: `hidden h-full min-h-0 min-w-0 shrink-0 overflow-visible bg-background data-[state=closed]:pointer-events-none md:flex ${desktopTransitionClassName}`,
|
|
20788
21721
|
style: { width: `${desktopSideWorkspaceWidth}px` },
|
|
20789
|
-
children:
|
|
20790
|
-
|
|
20791
|
-
|
|
20792
|
-
|
|
20793
|
-
|
|
20794
|
-
|
|
20795
|
-
|
|
20796
|
-
|
|
20797
|
-
|
|
20798
|
-
|
|
20799
|
-
|
|
20800
|
-
|
|
20801
|
-
|
|
20802
|
-
|
|
20803
|
-
|
|
20804
|
-
|
|
20805
|
-
|
|
20806
|
-
|
|
20807
|
-
|
|
20808
|
-
|
|
20809
|
-
|
|
20810
|
-
|
|
20811
|
-
|
|
20812
|
-
|
|
20813
|
-
|
|
20814
|
-
|
|
21722
|
+
children: desktopGitPanelRendered ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
21723
|
+
"data-desktop-panel": "git",
|
|
21724
|
+
className: `relative h-full min-h-0 min-w-0 shrink-0 overflow-visible ${desktopTransitionClassName}`,
|
|
21725
|
+
style: { width: `${desktopSideWorkspaceWidth}px` },
|
|
21726
|
+
children: [desktopGitPanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppShellDesktopResizeHandle, {
|
|
21727
|
+
label: "Resize right sidebar",
|
|
21728
|
+
min: Math.min(DESKTOP_MIN_SIDE_PANEL_WIDTH, desktopSideWorkspaceMaxWidth),
|
|
21729
|
+
max: desktopSideWorkspaceMaxWidth,
|
|
21730
|
+
size: desktopSideWorkspaceWidth,
|
|
21731
|
+
onResize: setDesktopSideWorkspaceWidth,
|
|
21732
|
+
onResizeStart: desktopResizeStart,
|
|
21733
|
+
onResizeEnd: desktopResizeEnd
|
|
21734
|
+
}) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
21735
|
+
className: "h-full min-h-0 min-w-0 overflow-hidden",
|
|
21736
|
+
children: desktopGitPanelRendered ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppShellDesktopGitPanel, {
|
|
21737
|
+
viewerContextId,
|
|
21738
|
+
sessionStore,
|
|
21739
|
+
active: desktopGitPanelOpen,
|
|
21740
|
+
composerDiffLineComments,
|
|
21741
|
+
rightSidebarStore,
|
|
21742
|
+
onAddDiffLineComment,
|
|
21743
|
+
onCloseAllFiles: onCloseAllFileViewTabs,
|
|
21744
|
+
onCloseFile: onCloseFileViewTab,
|
|
21745
|
+
onCloseFilesToRight: onCloseFileViewTabsToRight,
|
|
21746
|
+
onCloseOtherFiles: onCloseOtherFileViewTabs,
|
|
21747
|
+
onOpenFile: onOpenFileViewTab,
|
|
21748
|
+
onReorderFiles: onReorderFileViewTabs
|
|
21749
|
+
}) : null
|
|
21750
|
+
})]
|
|
21751
|
+
}) : null
|
|
21752
|
+
}) : null]
|
|
21753
|
+
}), desktopTerminalRendered ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
|
|
21754
|
+
"aria-label": "Terminal",
|
|
21755
|
+
"aria-hidden": !desktopTerminalOpen,
|
|
21756
|
+
"data-state": desktopTerminalOpen ? "open" : "closed",
|
|
21757
|
+
"data-desktop-panel": "terminal",
|
|
21758
|
+
className: `relative hidden min-h-0 w-full shrink-0 overflow-visible border-t border-border/70 bg-background data-[state=closed]:pointer-events-none data-[state=closed]:border-transparent md:flex ${desktopTransitionClassName}`,
|
|
21759
|
+
style: { height: `${desktopTerminalVisibleHeight}px` },
|
|
21760
|
+
children: [desktopTerminalOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppShellDesktopVerticalResizeHandle, {
|
|
21761
|
+
label: "Resize terminal",
|
|
21762
|
+
min: Math.min(DESKTOP_MIN_TERMINAL_PANEL_HEIGHT, desktopTerminalMaxHeight),
|
|
21763
|
+
max: desktopTerminalMaxHeight,
|
|
21764
|
+
size: desktopTerminalVisibleHeight,
|
|
21765
|
+
onResize: setDesktopTerminalHeight,
|
|
21766
|
+
onResizeStart: desktopTerminalResizeStart,
|
|
21767
|
+
onResizeEnd: desktopTerminalResizeEnd
|
|
21768
|
+
}) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
21769
|
+
className: "h-full min-h-0 w-full min-w-0 overflow-hidden",
|
|
21770
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TerminalPanel, {
|
|
21771
|
+
active: desktopTerminalOpen,
|
|
21772
|
+
cwd: terminalSession.cwd,
|
|
21773
|
+
onClose: onCloseTerminalPanel,
|
|
21774
|
+
sessionId: terminalSession.sessionId,
|
|
21775
|
+
viewerContextId
|
|
21776
|
+
})
|
|
21777
|
+
})]
|
|
20815
21778
|
}) : null]
|
|
20816
21779
|
})]
|
|
20817
21780
|
});
|
|
20818
21781
|
}
|
|
20819
|
-
var AppShellSessionHeader = import_react.memo(function AppShellSessionHeader({ actionsRef, defaultNewSessionDirectory, displaySessionCwd, gitPanelOpen, loadingDisplaySessionTitle, currentSessionPinned, displaySettingsStore, isSessionViewLoading, newSessionDirectoryOptions, onToggleGitPanel, sessionStore, viewerContextId }) {
|
|
21782
|
+
var AppShellSessionHeader = import_react.memo(function AppShellSessionHeader({ actionsRef, defaultNewSessionDirectory, displaySessionCwd, gitPanelOpen, terminalPanelOpen, loadingDisplaySessionTitle, currentSessionPinned, displaySettingsStore, isSessionViewLoading, newSessionDirectoryOptions, onToggleGitPanel, onToggleTerminalPanel, sessionStore, viewerContextId }) {
|
|
20820
21783
|
const sessionHeaderState = useSelector(sessionStore, (sessionState) => ({
|
|
20821
21784
|
firstMessage: sessionState.firstMessage,
|
|
20822
21785
|
hideThinkingBlock: sessionState.hideThinkingBlock,
|
|
@@ -20825,8 +21788,6 @@ var AppShellSessionHeader = import_react.memo(function AppShellSessionHeader({ a
|
|
|
20825
21788
|
sessionStreaming: sessionState.streaming
|
|
20826
21789
|
}), { compare: shallowRecordEqual });
|
|
20827
21790
|
const hideToolBlocks = useSelector(displaySettingsStore, (settings) => settings.hideToolBlocks);
|
|
20828
|
-
const { isMobile: sidebarIsMobile, openMobile: sidebarOpenMobile, state: sidebarState } = useSidebar();
|
|
20829
|
-
const showCollapsedNewSessionButton = !(sidebarIsMobile ? sidebarOpenMobile : sidebarState === "expanded");
|
|
20830
21791
|
const displaySessionTitle = isSessionViewLoading ? loadingDisplaySessionTitle : getCurrentSessionTitleFromState(sessionHeaderState);
|
|
20831
21792
|
const moveSessionDirectoryOptions = newSessionDirectoryOptions.filter((option) => option.path !== displaySessionCwd);
|
|
20832
21793
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
@@ -20835,25 +21796,26 @@ var AppShellSessionHeader = import_react.memo(function AppShellSessionHeader({ a
|
|
|
20835
21796
|
className: "relative flex w-full items-center gap-1",
|
|
20836
21797
|
children: [
|
|
20837
21798
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarTrigger, { className: "shrink-0" }),
|
|
20838
|
-
|
|
21799
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
20839
21800
|
title: defaultNewSessionDirectory ? `Create a new session in ${formatDisplayPath$1(defaultNewSessionDirectory)}` : "Create a new session",
|
|
20840
21801
|
kbd: formatShortcutLabel("Control+N"),
|
|
20841
21802
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
20842
21803
|
size: "icon",
|
|
20843
21804
|
variant: "ghost",
|
|
20844
|
-
className: "shrink-0",
|
|
21805
|
+
className: "shrink-0 md:group-data-[sidebar-state=expanded]/sidebar-wrapper:hidden",
|
|
20845
21806
|
"aria-label": "Create a new session",
|
|
20846
21807
|
onClick: () => {
|
|
20847
21808
|
actionsRef.current.createSession();
|
|
20848
21809
|
},
|
|
20849
21810
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SquarePen, {})
|
|
20850
21811
|
})
|
|
20851
|
-
})
|
|
21812
|
+
}),
|
|
20852
21813
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20853
21814
|
className: "absolute left-1/2 flex w-max max-w-[calc(100%-4rem)] -translate-x-1/2 flex-col items-center justify-center gap-0 text-center",
|
|
20854
21815
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20855
21816
|
className: "flex max-w-full min-w-0 items-center justify-center gap-1.5",
|
|
20856
21817
|
children: [!isSessionViewLoading && sessionHeaderState.sessionStreaming ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
|
|
21818
|
+
size: "xs",
|
|
20857
21819
|
className: "shrink-0",
|
|
20858
21820
|
"aria-label": "Session streaming"
|
|
20859
21821
|
}) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
@@ -20864,7 +21826,7 @@ var AppShellSessionHeader = import_react.memo(function AppShellSessionHeader({ a
|
|
|
20864
21826
|
})
|
|
20865
21827
|
})]
|
|
20866
21828
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20867
|
-
className: "flex max-w-full min-w-0 items-center justify-center gap-x-
|
|
21829
|
+
className: "flex max-w-full min-w-0 items-center justify-center gap-x-2",
|
|
20868
21830
|
children: [displaySessionCwd ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20869
21831
|
className: "inline-flex min-w-0 items-center text-xs text-muted-foreground",
|
|
20870
21832
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
@@ -21002,6 +21964,19 @@ var AppShellSessionHeader = import_react.memo(function AppShellSessionHeader({ a
|
|
|
21002
21964
|
})
|
|
21003
21965
|
]
|
|
21004
21966
|
})] }),
|
|
21967
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
21968
|
+
title: "Toggle terminal",
|
|
21969
|
+
kbd: formatShortcutLabel("Control+`"),
|
|
21970
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
21971
|
+
size: "icon",
|
|
21972
|
+
variant: "ghost",
|
|
21973
|
+
className: "hidden md:inline-flex",
|
|
21974
|
+
"aria-pressed": terminalPanelOpen,
|
|
21975
|
+
"aria-label": "Toggle terminal panel",
|
|
21976
|
+
onClick: onToggleTerminalPanel,
|
|
21977
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SquareTerminal, {})
|
|
21978
|
+
})
|
|
21979
|
+
}),
|
|
21005
21980
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
21006
21981
|
title: "Toggle right sidebar",
|
|
21007
21982
|
kbd: formatShortcutLabel("Control+\\"),
|
|
@@ -21347,7 +22322,10 @@ function SidebarSessionItem({ entryKey, directorySessionsStore, activeSessionSto
|
|
|
21347
22322
|
},
|
|
21348
22323
|
children: [entry.streaming ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
21349
22324
|
className: "absolute top-2.5 left-2 flex size-4 items-center justify-center",
|
|
21350
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
|
|
22325
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
|
|
22326
|
+
size: "xs",
|
|
22327
|
+
"aria-label": "Session streaming"
|
|
22328
|
+
})
|
|
21351
22329
|
}) : showUnread ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
21352
22330
|
className: "absolute top-2.5 left-2 flex size-4 items-center justify-center",
|
|
21353
22331
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
@@ -21524,7 +22502,10 @@ var DirectorySessionGroup = import_react.memo(function DirectorySessionGroup({ d
|
|
|
21524
22502
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DirectoryPathLabel, { path: directory })
|
|
21525
22503
|
}),
|
|
21526
22504
|
!searchActive && !overlay ? collapsed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "size-4 shrink-0 opacity-0 transition-opacity group-hover/directory-label:opacity-100 group-focus-visible/directory-label:opacity-100" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: "size-4 shrink-0 opacity-0 transition-opacity group-hover/directory-label:opacity-100 group-focus-visible/directory-label:opacity-100" }) : null,
|
|
21527
|
-
showHeaderLoadingSpinner ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
|
|
22505
|
+
showHeaderLoadingSpinner ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
|
|
22506
|
+
size: "xs",
|
|
22507
|
+
className: "shrink-0"
|
|
22508
|
+
}) : null
|
|
21528
22509
|
]
|
|
21529
22510
|
}),
|
|
21530
22511
|
onCreateSessionInDirectory && !overlay && !isMobile ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
@@ -21594,7 +22575,7 @@ var DirectorySessionGroup = import_react.memo(function DirectorySessionGroup({ d
|
|
|
21594
22575
|
]
|
|
21595
22576
|
})] }) : directoryHeader, !overlay ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarGroupContent, { children: showLoadingState ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
21596
22577
|
className: "flex items-center gap-2 p-2 text-sm text-sidebar-foreground/70",
|
|
21597
|
-
children: [showLoadingSpinner ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
22578
|
+
children: [showLoadingSpinner ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { size: "xs" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
21598
22579
|
className: "size-4",
|
|
21599
22580
|
"aria-hidden": "true"
|
|
21600
22581
|
}), "Loading sessions…"]
|
|
@@ -23027,7 +24008,11 @@ function createLocalPendingId() {
|
|
|
23027
24008
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return `optimistic:${crypto.randomUUID()}`;
|
|
23028
24009
|
return `optimistic:${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
23029
24010
|
}
|
|
23030
|
-
function buildCurrentSessionRequestUrl(path, { contextId, sessionState, fallbackSessionId }) {
|
|
24011
|
+
function buildCurrentSessionRequestUrl(path, { contextId, sessionState, fallbackSessionId, targetSessionKey }) {
|
|
24012
|
+
if (targetSessionKey) return buildRequestUrl(path, {
|
|
24013
|
+
contextId,
|
|
24014
|
+
searchParams: { sessionKey: targetSessionKey }
|
|
24015
|
+
});
|
|
23031
24016
|
const sessionKey = sessionState.sessionKey && !sessionState.sessionKey.startsWith("optimistic:") ? sessionState.sessionKey : void 0;
|
|
23032
24017
|
const shouldUseSessionKey = Boolean(sessionKey && (sessionState.draft || !sessionState.sessionId));
|
|
23033
24018
|
return buildRequestUrl(path, {
|
|
@@ -23088,13 +24073,14 @@ function movePendingComposerMessage(messages, pendingId, direction) {
|
|
|
23088
24073
|
function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultNewSessionDirectory, sessionStore, sessionStateRef, draftSessionLoadingOwnerKey, pendingDraftPrompt, pendingDraftFollowUps, awaitingFirstTurn, pendingMessages, composerDiffLineCommentsRef, composerImagesRef, composerTextRef, composerSkillRef, replaceComposerDraft, lastSyncedEditorTextRef, rememberRecentDirectory, prefetchDirectorySessionsIndex, addOptimisticUserMessage, removeOptimisticUserMessage, addOptimisticSidebarSession, removeOptimisticSidebarSession, updateOptimisticSidebarSessionPreview, setSidebarDirectories, setStoredDraftDirectory, setDraftSessionLoadingOwnerKey, setPendingDraftPrompt, setPendingDraftFollowUps, setPendingMessages, setAwaitingFirstTurn, setIsSubmitting, setComposerDiffLineComments, setComposerImages }) {
|
|
23089
24074
|
const queryClient = useQueryClient();
|
|
23090
24075
|
const draftSessionLoadingOwnerKeyRef = import_react.useRef(draftSessionLoadingOwnerKey);
|
|
24076
|
+
const pendingNewSessionPromptTargetRef = import_react.useRef(null);
|
|
24077
|
+
const newSessionRequestNonceRef = import_react.useRef(0);
|
|
23091
24078
|
const pendingDraftPromptRef = import_react.useRef(pendingDraftPrompt);
|
|
23092
24079
|
const pendingDraftFollowUpsRef = import_react.useRef(pendingDraftFollowUps);
|
|
23093
24080
|
const pendingMessagesRef = import_react.useRef(pendingMessages);
|
|
23094
24081
|
const awaitingFirstTurnRef = import_react.useRef(awaitingFirstTurn);
|
|
23095
24082
|
const awaitingFirstTurnAssistantOutputSignatureRef = import_react.useRef(null);
|
|
23096
24083
|
const sessionSnapshot = usePromptMutationSessionSnapshot(sessionStore);
|
|
23097
|
-
const sessionStreamingRef = import_react.useRef(sessionSnapshot.streaming);
|
|
23098
24084
|
const flushPendingDraftPromptRef = import_react.useRef(async () => false);
|
|
23099
24085
|
import_react.useEffect(() => {
|
|
23100
24086
|
draftSessionLoadingOwnerKeyRef.current = draftSessionLoadingOwnerKey;
|
|
@@ -23111,9 +24097,6 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23111
24097
|
import_react.useEffect(() => {
|
|
23112
24098
|
awaitingFirstTurnRef.current = awaitingFirstTurn;
|
|
23113
24099
|
}, [awaitingFirstTurn]);
|
|
23114
|
-
import_react.useEffect(() => {
|
|
23115
|
-
sessionStreamingRef.current = sessionSnapshot.streaming;
|
|
23116
|
-
}, [sessionSnapshot.streaming]);
|
|
23117
24100
|
const updatePendingMessages = import_react.useCallback((updater) => {
|
|
23118
24101
|
setPendingMessages((current) => {
|
|
23119
24102
|
const next = updater(current);
|
|
@@ -23168,6 +24151,7 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23168
24151
|
removeOptimisticUserMessage(nextPrompt.optimisticId);
|
|
23169
24152
|
removeOptimisticSidebarSession(nextPrompt.optimisticSidebarSessionId);
|
|
23170
24153
|
for (const followUp of pendingDraftFollowUpsRef.current) removeOptimisticUserMessage(followUp.optimisticId);
|
|
24154
|
+
pendingNewSessionPromptTargetRef.current = null;
|
|
23171
24155
|
pendingDraftPromptRef.current = null;
|
|
23172
24156
|
pendingDraftFollowUpsRef.current = [];
|
|
23173
24157
|
setPendingDraftPrompt(null);
|
|
@@ -23240,17 +24224,32 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23240
24224
|
const ownerKey = promptDraftKey({ cwd: nextCwd });
|
|
23241
24225
|
draftSessionLoadingOwnerKeyRef.current = ownerKey;
|
|
23242
24226
|
setDraftSessionLoadingOwnerKey(ownerKey);
|
|
24227
|
+
awaitingFirstTurnAssistantOutputSignatureRef.current = null;
|
|
24228
|
+
awaitingFirstTurnRef.current = false;
|
|
24229
|
+
setAwaitingFirstTurn(false);
|
|
24230
|
+
pendingMessagesRef.current = [];
|
|
24231
|
+
setPendingMessages((current) => current.length === 0 ? current : []);
|
|
24232
|
+
const requestNonce = newSessionRequestNonceRef.current + 1;
|
|
24233
|
+
newSessionRequestNonceRef.current = requestNonce;
|
|
23243
24234
|
try {
|
|
23244
|
-
await createSessionRequest({ cwd: nextCwd });
|
|
24235
|
+
const response = await createSessionRequest({ cwd: nextCwd });
|
|
24236
|
+
if (newSessionRequestNonceRef.current !== requestNonce) return true;
|
|
24237
|
+
pendingNewSessionPromptTargetRef.current = {
|
|
24238
|
+
ownerKey,
|
|
24239
|
+
sessionKey: response.sessionKey,
|
|
24240
|
+
cwd: response.cwd
|
|
24241
|
+
};
|
|
23245
24242
|
if (draftSessionLoadingOwnerKeyRef.current === ownerKey) {
|
|
23246
24243
|
draftSessionLoadingOwnerKeyRef.current = null;
|
|
23247
24244
|
setDraftSessionLoadingOwnerKey((current) => current === ownerKey ? null : current);
|
|
23248
24245
|
}
|
|
23249
|
-
if (pendingDraftPromptRef.current?.ownerKey === ownerKey) flushPendingDraftPromptRef.current(ownerKey);
|
|
24246
|
+
if (pendingDraftPromptRef.current?.ownerKey === ownerKey) flushPendingDraftPromptRef.current(ownerKey, response.sessionKey);
|
|
23250
24247
|
return true;
|
|
23251
24248
|
} catch (error) {
|
|
24249
|
+
if (newSessionRequestNonceRef.current !== requestNonce) return true;
|
|
23252
24250
|
if (draftSessionLoadingOwnerKeyRef.current === ownerKey) draftSessionLoadingOwnerKeyRef.current = null;
|
|
23253
24251
|
setDraftSessionLoadingOwnerKey((current) => current === ownerKey ? null : current);
|
|
24252
|
+
if (pendingNewSessionPromptTargetRef.current?.ownerKey === ownerKey) pendingNewSessionPromptTargetRef.current = null;
|
|
23254
24253
|
restorePendingDraftPrompt(ownerKey);
|
|
23255
24254
|
toast.error(error instanceof Error ? error.message : "Failed to create session");
|
|
23256
24255
|
return false;
|
|
@@ -23261,12 +24260,14 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23261
24260
|
rememberRecentDirectory,
|
|
23262
24261
|
restorePendingDraftPrompt,
|
|
23263
24262
|
sessionStateRef,
|
|
24263
|
+
setAwaitingFirstTurn,
|
|
23264
24264
|
setDraftSessionLoadingOwnerKey,
|
|
24265
|
+
setPendingMessages,
|
|
23265
24266
|
setStoredDraftDirectory,
|
|
23266
24267
|
viewerContextId
|
|
23267
24268
|
]);
|
|
23268
|
-
const queuePendingDraftPrompt = import_react.useCallback((streamingBehavior) => {
|
|
23269
|
-
const ownerKey = draftSessionLoadingOwnerKeyRef.current;
|
|
24269
|
+
const queuePendingDraftPrompt = import_react.useCallback((streamingBehavior, ownerKeyOverride) => {
|
|
24270
|
+
const ownerKey = ownerKeyOverride || draftSessionLoadingOwnerKeyRef.current;
|
|
23270
24271
|
if (!ownerKey) return false;
|
|
23271
24272
|
const message = buildComposerPromptMessage({
|
|
23272
24273
|
text: composerTextRef.current,
|
|
@@ -23282,6 +24283,7 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23282
24283
|
ownerKey,
|
|
23283
24284
|
message,
|
|
23284
24285
|
images,
|
|
24286
|
+
streamingBehavior,
|
|
23285
24287
|
optimisticId: addOptimisticUserMessage({
|
|
23286
24288
|
message,
|
|
23287
24289
|
images,
|
|
@@ -23332,12 +24334,13 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23332
24334
|
updateOptimisticSidebarSessionPreview
|
|
23333
24335
|
]);
|
|
23334
24336
|
const promptMutation = useMutation({
|
|
23335
|
-
mutationFn: async ({ message, images, streamingBehavior, pendingId, thinkingLevel }) => {
|
|
24337
|
+
mutationFn: async ({ message, images, streamingBehavior, pendingId, thinkingLevel, targetSessionKey, draftTarget }) => {
|
|
23336
24338
|
if (!viewerContextId) throw new Error("Viewer context unavailable");
|
|
23337
24339
|
return await fetchJson(buildCurrentSessionRequestUrl("/api/prompt", {
|
|
23338
24340
|
contextId: viewerContextId,
|
|
23339
24341
|
sessionState: sessionStateRef.current,
|
|
23340
|
-
fallbackSessionId: activeSessionId
|
|
24342
|
+
fallbackSessionId: activeSessionId,
|
|
24343
|
+
targetSessionKey
|
|
23341
24344
|
}), {
|
|
23342
24345
|
method: "POST",
|
|
23343
24346
|
headers: { "content-type": "application/json" },
|
|
@@ -23346,7 +24349,9 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23346
24349
|
images,
|
|
23347
24350
|
streamingBehavior,
|
|
23348
24351
|
pendingId,
|
|
23349
|
-
thinkingLevel
|
|
24352
|
+
thinkingLevel,
|
|
24353
|
+
draftOwnerKey: draftTarget?.ownerKey,
|
|
24354
|
+
draftCwd: draftTarget?.cwd
|
|
23350
24355
|
})
|
|
23351
24356
|
});
|
|
23352
24357
|
},
|
|
@@ -23367,13 +24372,29 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23367
24372
|
diffLineComments: submittedDiffLineComments
|
|
23368
24373
|
}).trim();
|
|
23369
24374
|
if (!message && composerImagesRef.current.length === 0) return false;
|
|
23370
|
-
const
|
|
24375
|
+
const currentSessionState = sessionStateRef.current;
|
|
24376
|
+
const pendingNewSessionPromptTarget = pendingNewSessionPromptTargetRef.current;
|
|
24377
|
+
const currentDraftOwnerKey = currentSessionState.draft ? promptDraftKey(currentSessionState) : "";
|
|
24378
|
+
const implicitTargetSessionKey = !options?.targetSessionKey && currentSessionState.draft && pendingNewSessionPromptTarget && promptDraftKeyMatchesOwner(currentDraftOwnerKey, pendingNewSessionPromptTarget.ownerKey) ? pendingNewSessionPromptTarget.sessionKey : void 0;
|
|
24379
|
+
const targetSessionKey = options?.targetSessionKey || implicitTargetSessionKey;
|
|
24380
|
+
const targetDraft = currentSessionState.draft ? {
|
|
24381
|
+
ownerKey: options?.targetDraftOwnerKey || (targetSessionKey && pendingNewSessionPromptTarget?.sessionKey === targetSessionKey ? pendingNewSessionPromptTarget.ownerKey : currentDraftOwnerKey),
|
|
24382
|
+
cwd: options?.targetDraftCwd || (targetSessionKey && pendingNewSessionPromptTarget?.sessionKey === targetSessionKey ? pendingNewSessionPromptTarget.cwd || currentSessionState.cwd : currentSessionState.cwd)
|
|
24383
|
+
} : void 0;
|
|
24384
|
+
if (currentSessionState.draft && currentSessionState.sessionKey?.startsWith("optimistic:") && !targetSessionKey) {
|
|
24385
|
+
if (!draftSessionLoadingOwnerKeyRef.current && currentDraftOwnerKey) {
|
|
24386
|
+
draftSessionLoadingOwnerKeyRef.current = currentDraftOwnerKey;
|
|
24387
|
+
setDraftSessionLoadingOwnerKey(currentDraftOwnerKey);
|
|
24388
|
+
}
|
|
24389
|
+
return queuePendingDraftPrompt(streamingBehavior, currentDraftOwnerKey);
|
|
24390
|
+
}
|
|
24391
|
+
const treatAsQueuedPrompt = options?.forceFirstPrompt ? false : Boolean(currentSessionState.streaming || awaitingFirstTurnRef.current);
|
|
23371
24392
|
const normalizedStreamingBehavior = treatAsQueuedPrompt ? normalizeQueuedStreamingBehavior(streamingBehavior) : void 0;
|
|
23372
24393
|
const submittedImages = composerImagesRef.current.map((image) => ({ ...image }));
|
|
23373
24394
|
const sidebarPreview = promptSidebarPreview(message, submittedImages);
|
|
23374
24395
|
const queuedPendingId = treatAsQueuedPrompt ? createLocalPendingId() : void 0;
|
|
23375
24396
|
if (!treatAsQueuedPrompt) {
|
|
23376
|
-
awaitingFirstTurnAssistantOutputSignatureRef.current = sessionAssistantOutputSignature(
|
|
24397
|
+
awaitingFirstTurnAssistantOutputSignatureRef.current = sessionAssistantOutputSignature(currentSessionState.items);
|
|
23377
24398
|
awaitingFirstTurnRef.current = true;
|
|
23378
24399
|
setAwaitingFirstTurn(true);
|
|
23379
24400
|
}
|
|
@@ -23382,7 +24403,7 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23382
24403
|
images: submittedImages,
|
|
23383
24404
|
queued: false
|
|
23384
24405
|
}));
|
|
23385
|
-
const optimisticSidebarSessionId = options?.optimisticSidebarSessionId ?? (!treatAsQueuedPrompt &&
|
|
24406
|
+
const optimisticSidebarSessionId = options?.optimisticSidebarSessionId ?? (!treatAsQueuedPrompt && currentSessionState.draft ? addOptimisticSidebarSession({ lastMessagePreview: sidebarPreview }) : void 0);
|
|
23386
24407
|
updateOptimisticSidebarSessionPreview({
|
|
23387
24408
|
...optimisticSidebarSessionId ? { optimisticSidebarSessionId } : {},
|
|
23388
24409
|
preview: sidebarPreview
|
|
@@ -23404,9 +24425,12 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23404
24425
|
images: submittedImages,
|
|
23405
24426
|
streamingBehavior: normalizedStreamingBehavior,
|
|
23406
24427
|
pendingId: queuedPendingId,
|
|
23407
|
-
thinkingLevel:
|
|
24428
|
+
thinkingLevel: currentSessionState.thinkingLevel,
|
|
24429
|
+
targetSessionKey,
|
|
24430
|
+
draftTarget: targetDraft
|
|
23408
24431
|
});
|
|
23409
24432
|
if (queuedPendingId && "queued" in response && (!response.queued || response.canceled)) removeOptimisticPendingMessage(queuedPendingId);
|
|
24433
|
+
if (targetSessionKey && pendingNewSessionPromptTargetRef.current?.sessionKey === targetSessionKey) pendingNewSessionPromptTargetRef.current = null;
|
|
23410
24434
|
return true;
|
|
23411
24435
|
} catch (error) {
|
|
23412
24436
|
if (queuedPendingId) removeOptimisticPendingMessage(queuedPendingId);
|
|
@@ -23449,11 +24473,12 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23449
24473
|
setAwaitingFirstTurn,
|
|
23450
24474
|
setComposerDiffLineComments,
|
|
23451
24475
|
setComposerImages,
|
|
24476
|
+
setDraftSessionLoadingOwnerKey,
|
|
23452
24477
|
setIsSubmitting,
|
|
23453
24478
|
updateOptimisticSidebarSessionPreview,
|
|
23454
24479
|
viewerContextId
|
|
23455
24480
|
]);
|
|
23456
|
-
const flushPendingDraftFollowUps = import_react.useCallback(async () => {
|
|
24481
|
+
const flushPendingDraftFollowUps = import_react.useCallback(async (targetSessionKey, draftTarget) => {
|
|
23457
24482
|
if (draftSessionLoadingOwnerKeyRef.current) return false;
|
|
23458
24483
|
const pendingFollowUps = pendingDraftFollowUpsRef.current;
|
|
23459
24484
|
if (pendingFollowUps.length === 0) return false;
|
|
@@ -23474,7 +24499,9 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23474
24499
|
images: followUp.images,
|
|
23475
24500
|
streamingBehavior: followUp.streamingBehavior,
|
|
23476
24501
|
pendingId: followUp.optimisticId,
|
|
23477
|
-
thinkingLevel: sessionStateRef.current.thinkingLevel
|
|
24502
|
+
thinkingLevel: sessionStateRef.current.thinkingLevel,
|
|
24503
|
+
targetSessionKey,
|
|
24504
|
+
draftTarget
|
|
23478
24505
|
});
|
|
23479
24506
|
} catch (error) {
|
|
23480
24507
|
for (const unsentFollowUp of followUps.slice(index)) removeOptimisticUserMessage(unsentFollowUp.optimisticId);
|
|
@@ -23497,24 +24524,35 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23497
24524
|
setComposerImages,
|
|
23498
24525
|
setPendingDraftFollowUps
|
|
23499
24526
|
]);
|
|
23500
|
-
const flushPendingDraftPrompt = import_react.useCallback(async (ownerKey) => {
|
|
24527
|
+
const flushPendingDraftPrompt = import_react.useCallback(async (ownerKey, targetSessionKey) => {
|
|
23501
24528
|
const nextPrompt = pendingDraftPromptRef.current;
|
|
23502
24529
|
if (!nextPrompt || nextPrompt.ownerKey !== ownerKey || draftSessionLoadingOwnerKeyRef.current) return false;
|
|
24530
|
+
const pendingTarget = pendingNewSessionPromptTargetRef.current;
|
|
24531
|
+
const resolvedTargetSessionKey = targetSessionKey || (pendingTarget?.ownerKey === ownerKey ? pendingTarget.sessionKey : void 0);
|
|
24532
|
+
const resolvedDraftTarget = {
|
|
24533
|
+
ownerKey,
|
|
24534
|
+
cwd: pendingTarget?.cwd || sessionStateRef.current.cwd
|
|
24535
|
+
};
|
|
23503
24536
|
pendingDraftPromptRef.current = null;
|
|
23504
24537
|
setPendingDraftPrompt(null);
|
|
23505
24538
|
applyPendingDraftPromptToComposer(nextPrompt);
|
|
23506
24539
|
if (!await submitPrompt(nextPrompt.streamingBehavior, {
|
|
23507
24540
|
forceFirstPrompt: true,
|
|
23508
24541
|
optimisticId: nextPrompt.optimisticId,
|
|
23509
|
-
optimisticSidebarSessionId: nextPrompt.optimisticSidebarSessionId
|
|
24542
|
+
optimisticSidebarSessionId: nextPrompt.optimisticSidebarSessionId,
|
|
24543
|
+
targetSessionKey: resolvedTargetSessionKey,
|
|
24544
|
+
targetDraftOwnerKey: resolvedDraftTarget.ownerKey,
|
|
24545
|
+
targetDraftCwd: resolvedDraftTarget.cwd
|
|
23510
24546
|
})) {
|
|
23511
24547
|
removeOptimisticSidebarSession(nextPrompt.optimisticSidebarSessionId);
|
|
23512
24548
|
for (const followUp of pendingDraftFollowUpsRef.current) removeOptimisticUserMessage(followUp.optimisticId);
|
|
23513
24549
|
pendingDraftFollowUpsRef.current = [];
|
|
23514
24550
|
setPendingDraftFollowUps([]);
|
|
24551
|
+
if (pendingNewSessionPromptTargetRef.current?.ownerKey === ownerKey) pendingNewSessionPromptTargetRef.current = null;
|
|
23515
24552
|
return false;
|
|
23516
24553
|
}
|
|
23517
|
-
await flushPendingDraftFollowUps();
|
|
24554
|
+
await flushPendingDraftFollowUps(resolvedTargetSessionKey, resolvedDraftTarget);
|
|
24555
|
+
if (pendingNewSessionPromptTargetRef.current?.ownerKey === ownerKey) pendingNewSessionPromptTargetRef.current = null;
|
|
23518
24556
|
return true;
|
|
23519
24557
|
}, [
|
|
23520
24558
|
applyPendingDraftPromptToComposer,
|
|
@@ -23532,9 +24570,15 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
23532
24570
|
if (currentSessionState.sessionKey?.startsWith("optimistic:")) return;
|
|
23533
24571
|
const currentOwnerKey = promptDraftKey(currentSessionState);
|
|
23534
24572
|
if (!currentSessionState.draft || !promptDraftKeyMatchesOwner(currentOwnerKey, draftSessionLoadingOwnerKey)) return;
|
|
24573
|
+
const targetSessionKey = currentSessionState.sessionKey?.startsWith("optimistic:") ? void 0 : currentSessionState.sessionKey;
|
|
24574
|
+
if (targetSessionKey) pendingNewSessionPromptTargetRef.current = {
|
|
24575
|
+
ownerKey: draftSessionLoadingOwnerKey,
|
|
24576
|
+
sessionKey: targetSessionKey,
|
|
24577
|
+
cwd: currentSessionState.cwd
|
|
24578
|
+
};
|
|
23535
24579
|
draftSessionLoadingOwnerKeyRef.current = null;
|
|
23536
24580
|
setDraftSessionLoadingOwnerKey(null);
|
|
23537
|
-
if (pendingDraftPromptRef.current?.ownerKey === draftSessionLoadingOwnerKey) flushPendingDraftPrompt(draftSessionLoadingOwnerKey);
|
|
24581
|
+
if (pendingDraftPromptRef.current?.ownerKey === draftSessionLoadingOwnerKey) flushPendingDraftPrompt(draftSessionLoadingOwnerKey, targetSessionKey);
|
|
23538
24582
|
}, [
|
|
23539
24583
|
draftSessionLoadingOwnerKey,
|
|
23540
24584
|
flushPendingDraftPrompt,
|
|
@@ -24941,10 +25985,13 @@ function useAppShellSessionSync({ viewerContextId, sessionId, draftSessionLoadin
|
|
|
24941
25985
|
]);
|
|
24942
25986
|
}
|
|
24943
25987
|
var DOUBLE_ESCAPE_INTERVAL_MS = 500;
|
|
25988
|
+
function isTerminalTarget(target) {
|
|
25989
|
+
return target instanceof HTMLElement && target.closest("[data-terminal-panel=\"true\"]") !== null;
|
|
25990
|
+
}
|
|
24944
25991
|
function isEditableTarget(target) {
|
|
24945
25992
|
if (!(target instanceof HTMLElement)) return false;
|
|
24946
25993
|
const tagName = target.tagName.toLowerCase();
|
|
24947
|
-
return target.isContentEditable || tagName === "input" || tagName === "textarea" || target.closest("[contenteditable=\"true\"]") !== null;
|
|
25994
|
+
return target.isContentEditable || isTerminalTarget(target) || tagName === "input" || tagName === "textarea" || target.closest("[contenteditable=\"true\"]") !== null;
|
|
24948
25995
|
}
|
|
24949
25996
|
function isPromptTextareaTarget(target) {
|
|
24950
25997
|
return target instanceof HTMLTextAreaElement && target.name === "prompt";
|
|
@@ -24984,7 +26031,7 @@ function useAppShellShortcuts({ addDirectoryOpenRef, commandPaletteOpenRef, comp
|
|
|
24984
26031
|
};
|
|
24985
26032
|
const handleEscape = (event) => {
|
|
24986
26033
|
const context = getShortcutContext(event);
|
|
24987
|
-
if (event.repeat || context.modalOpen || event.defaultPrevented) return;
|
|
26034
|
+
if (event.repeat || context.modalOpen || event.defaultPrevented || isTerminalTarget(event.target)) return;
|
|
24988
26035
|
const now = Date.now();
|
|
24989
26036
|
if (now - lastEscapeKeyDownAtRef.current <= DOUBLE_ESCAPE_INTERVAL_MS) {
|
|
24990
26037
|
lastEscapeKeyDownAtRef.current = 0;
|
|
@@ -25023,7 +26070,7 @@ function useAppShellShortcuts({ addDirectoryOpenRef, commandPaletteOpenRef, comp
|
|
|
25023
26070
|
};
|
|
25024
26071
|
const handleFocusPrompt = (event) => {
|
|
25025
26072
|
const context = getShortcutContext(event);
|
|
25026
|
-
if (context.blockingModalOpen || event.defaultPrevented) return;
|
|
26073
|
+
if (context.blockingModalOpen || event.defaultPrevented || isTerminalTarget(event.target)) return;
|
|
25027
26074
|
event.preventDefault();
|
|
25028
26075
|
closeCommandPaletteForShortcut(context.commandPaletteOpen);
|
|
25029
26076
|
shortcutActionsRef.current.focusPrompt();
|
|
@@ -25050,12 +26097,19 @@ function useAppShellShortcuts({ addDirectoryOpenRef, commandPaletteOpenRef, comp
|
|
|
25050
26097
|
const key = event.altKey && event.code.startsWith("Key") ? event.code.slice(3).toLowerCase() : event.key.toLowerCase();
|
|
25051
26098
|
const context = getShortcutContext(event);
|
|
25052
26099
|
if (context.blockingModalOpen || event.defaultPrevented) return;
|
|
26100
|
+
if (isTerminalTarget(event.target) && !context.commandPaletteOpen && key !== "`") return;
|
|
25053
26101
|
if (key === "\\") {
|
|
25054
26102
|
event.preventDefault();
|
|
25055
26103
|
closeCommandPaletteForShortcut(context.commandPaletteOpen);
|
|
25056
26104
|
shortcutActionsRef.current.toggleGitPanel();
|
|
25057
26105
|
return;
|
|
25058
26106
|
}
|
|
26107
|
+
if (key === "`") {
|
|
26108
|
+
event.preventDefault();
|
|
26109
|
+
closeCommandPaletteForShortcut(context.commandPaletteOpen);
|
|
26110
|
+
shortcutActionsRef.current.toggleTerminalPanel();
|
|
26111
|
+
return;
|
|
26112
|
+
}
|
|
25059
26113
|
if (key === "k") {
|
|
25060
26114
|
event.preventDefault();
|
|
25061
26115
|
shortcutActionsRef.current.openCommandPalette();
|
|
@@ -25227,6 +26281,7 @@ function useAppShellShortcuts({ addDirectoryOpenRef, commandPaletteOpenRef, comp
|
|
|
25227
26281
|
})),
|
|
25228
26282
|
...[
|
|
25229
26283
|
{ key: "\\" },
|
|
26284
|
+
{ key: "`" },
|
|
25230
26285
|
{ key: "K" },
|
|
25231
26286
|
{ key: "P" },
|
|
25232
26287
|
{
|
|
@@ -25295,6 +26350,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25295
26350
|
if (!appUiStoreRef.current) appUiStoreRef.current = createPicoStore({
|
|
25296
26351
|
currentTab: "session",
|
|
25297
26352
|
gitPanelOpen: false,
|
|
26353
|
+
terminalPanelOpen: false,
|
|
25298
26354
|
initialLoadingSessionId: sessionId || null,
|
|
25299
26355
|
loadingSessionId: null
|
|
25300
26356
|
}, shallowRecordEqual);
|
|
@@ -25310,6 +26366,11 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25310
26366
|
setStoreField(appUiStore, "gitPanelOpen", nextOpen);
|
|
25311
26367
|
safeLocalStorageSetItem(RIGHT_SIDEBAR_OPEN_STORAGE_KEY, nextOpen ? "1" : "0");
|
|
25312
26368
|
}, [appUiStore]);
|
|
26369
|
+
const setTerminalPanelOpen = import_react.useCallback((action) => {
|
|
26370
|
+
const nextOpen = applyStoreAction(appUiStore.state.terminalPanelOpen, action);
|
|
26371
|
+
setStoreField(appUiStore, "terminalPanelOpen", nextOpen);
|
|
26372
|
+
safeLocalStorageSetItem(TERMINAL_PANEL_OPEN_STORAGE_KEY, nextOpen ? "1" : "0");
|
|
26373
|
+
}, [appUiStore]);
|
|
25313
26374
|
const setLoadingSessionId = import_react.useCallback((action) => {
|
|
25314
26375
|
setStoreField(appUiStore, "loadingSessionId", action);
|
|
25315
26376
|
}, [appUiStore]);
|
|
@@ -25735,6 +26796,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25735
26796
|
sessionKey: currentSessionState.sessionKey
|
|
25736
26797
|
}), { compare: shallowRecordEqual });
|
|
25737
26798
|
const gitPanelOpen = useSelector(appUiStore, (state) => state.gitPanelOpen);
|
|
26799
|
+
const terminalPanelOpen = useSelector(appUiStore, (state) => state.terminalPanelOpen);
|
|
25738
26800
|
const openFileViewTab = (path, options) => {
|
|
25739
26801
|
if (!path) return;
|
|
25740
26802
|
batch(() => {
|
|
@@ -25831,7 +26893,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25831
26893
|
} : currentSession : { draft: true }, sessionId);
|
|
25832
26894
|
setStoreState(appUiStore, (current) => ({
|
|
25833
26895
|
...current,
|
|
25834
|
-
currentTab: current.currentTab === "git" ? "session" : current.currentTab,
|
|
26896
|
+
currentTab: current.currentTab === "git" || current.currentTab === "terminal" ? "session" : current.currentTab,
|
|
25835
26897
|
initialLoadingSessionId: sessionId ? current.initialLoadingSessionId : null,
|
|
25836
26898
|
loadingSessionId: sessionId && sessionStateRef.current.sessionId !== sessionId ? sessionId : null
|
|
25837
26899
|
}));
|
|
@@ -25843,7 +26905,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25843
26905
|
]);
|
|
25844
26906
|
import_react.useEffect(() => {
|
|
25845
26907
|
if (isMobile) return;
|
|
25846
|
-
setCurrentTab((tab) => tab === "git" ? "session" : tab);
|
|
26908
|
+
setCurrentTab((tab) => tab === "git" || tab === "terminal" ? "session" : tab);
|
|
25847
26909
|
}, [isMobile, setCurrentTab]);
|
|
25848
26910
|
const syncComposerDraft = (value, target = sessionStateRef.current) => {
|
|
25849
26911
|
const parsed = parseComposerSkillMessage(value);
|
|
@@ -25887,6 +26949,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25887
26949
|
const applyStoredClientPreferences = () => {
|
|
25888
26950
|
batch(() => {
|
|
25889
26951
|
setGitPanelOpen(readStoredRightSidebarOpen());
|
|
26952
|
+
setTerminalPanelOpen(readStoredTerminalPanelOpen());
|
|
25890
26953
|
setStoredDraftDirectory(readStoredDraftDirectory() || "");
|
|
25891
26954
|
setSessionDoneSoundEnabled(readStoredSessionDoneSoundEnabled());
|
|
25892
26955
|
setSessionDoneDesktopNotificationsEnabled(readStoredSessionDoneDesktopNotificationsEnabled());
|
|
@@ -26050,6 +27113,20 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
26050
27113
|
}
|
|
26051
27114
|
setGitPanelOpen((open) => !open);
|
|
26052
27115
|
};
|
|
27116
|
+
const toggleTerminalPanel = () => {
|
|
27117
|
+
if (isMobile) {
|
|
27118
|
+
setCurrentTab((tab) => tab === "terminal" ? "session" : "terminal");
|
|
27119
|
+
return;
|
|
27120
|
+
}
|
|
27121
|
+
setTerminalPanelOpen((open) => !open);
|
|
27122
|
+
};
|
|
27123
|
+
const closeTerminalPanel = () => {
|
|
27124
|
+
if (isMobile) {
|
|
27125
|
+
setCurrentTab((tab) => tab === "terminal" ? "session" : tab);
|
|
27126
|
+
return;
|
|
27127
|
+
}
|
|
27128
|
+
setTerminalPanelOpen(false);
|
|
27129
|
+
};
|
|
26053
27130
|
const openRenameDialog = () => {
|
|
26054
27131
|
const currentState = sessionStateRef.current;
|
|
26055
27132
|
if (!currentState.sessionFile) return;
|
|
@@ -26528,10 +27605,6 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
26528
27605
|
const createSessionPromise = requestCreateSession(nextCwd);
|
|
26529
27606
|
handleSelectSession(void 0);
|
|
26530
27607
|
clearSelectedSidebarSelection();
|
|
26531
|
-
if (shouldCloseMobileSidebar) {
|
|
26532
|
-
pendingMobileSidebarPromptFocusRef.current = true;
|
|
26533
|
-
setOpenMobile(false);
|
|
26534
|
-
} else focusPrompt();
|
|
26535
27608
|
setAwaitingFirstTurn(false);
|
|
26536
27609
|
setPendingMessages((current) => current.length === 0 ? current : []);
|
|
26537
27610
|
const nextState = createOptimisticDraftSessionState({
|
|
@@ -26542,6 +27615,10 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
26542
27615
|
sessionStateRef.current = nextState;
|
|
26543
27616
|
conversationItemsStore.setItems(nextState.items);
|
|
26544
27617
|
setSessionState(nextState);
|
|
27618
|
+
if (shouldCloseMobileSidebar) {
|
|
27619
|
+
pendingMobileSidebarPromptFocusRef.current = true;
|
|
27620
|
+
setOpenMobile(false);
|
|
27621
|
+
} else focusPrompt();
|
|
26545
27622
|
if (await createSessionPromise) return;
|
|
26546
27623
|
if (sessionStateRef.current.sessionKey !== optimisticSessionKey) return;
|
|
26547
27624
|
sessionStateRef.current = previousState;
|
|
@@ -26928,7 +28005,8 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
26928
28005
|
hasAvailableModels: sessionStateRef.current.availableModels.length > 0,
|
|
26929
28006
|
isMobile,
|
|
26930
28007
|
selectedSidebarSessions,
|
|
26931
|
-
sessionFile: sessionState.sessionFile
|
|
28008
|
+
sessionFile: sessionState.sessionFile,
|
|
28009
|
+
terminalPanelOpen
|
|
26932
28010
|
});
|
|
26933
28011
|
const buildCommandPaletteCommands = () => {
|
|
26934
28012
|
const commandState = commandPaletteStateRef.current;
|
|
@@ -26979,6 +28057,21 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
26979
28057
|
],
|
|
26980
28058
|
onSelect: toggleGitPanel
|
|
26981
28059
|
},
|
|
28060
|
+
{
|
|
28061
|
+
id: "toggle-terminal",
|
|
28062
|
+
group: "Workspace",
|
|
28063
|
+
title: commandState.isMobile ? "Toggle terminal tab" : commandState.terminalPanelOpen ? "Close terminal" : "Open terminal",
|
|
28064
|
+
description: commandState.isMobile ? "Switch the mobile terminal tab on or off" : "Toggle the bottom terminal panel",
|
|
28065
|
+
shortcut: formatShortcutLabel("Control+`"),
|
|
28066
|
+
keywords: [
|
|
28067
|
+
"terminal",
|
|
28068
|
+
"shell",
|
|
28069
|
+
"console",
|
|
28070
|
+
"bottom",
|
|
28071
|
+
"panel"
|
|
28072
|
+
],
|
|
28073
|
+
onSelect: toggleTerminalPanel
|
|
28074
|
+
},
|
|
26982
28075
|
{
|
|
26983
28076
|
id: "commit-changes",
|
|
26984
28077
|
group: "Git",
|
|
@@ -27343,6 +28436,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
27343
28436
|
conversationFrameRef.current?.scrollConversationToTop();
|
|
27344
28437
|
},
|
|
27345
28438
|
toggleGitPanel,
|
|
28439
|
+
toggleTerminalPanel,
|
|
27346
28440
|
toggleHideThinking,
|
|
27347
28441
|
toggleHideToolBlocks,
|
|
27348
28442
|
cycleThinkingLevel
|
|
@@ -27483,12 +28577,14 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
27483
28577
|
defaultNewSessionDirectory,
|
|
27484
28578
|
displaySessionCwd,
|
|
27485
28579
|
gitPanelOpen,
|
|
28580
|
+
terminalPanelOpen,
|
|
27486
28581
|
loadingDisplaySessionTitle,
|
|
27487
28582
|
currentSessionPinned,
|
|
27488
28583
|
displaySettingsStore,
|
|
27489
28584
|
isSessionViewLoading,
|
|
27490
28585
|
newSessionDirectoryOptions,
|
|
27491
28586
|
onToggleGitPanel: toggleGitPanel,
|
|
28587
|
+
onToggleTerminalPanel: toggleTerminalPanel,
|
|
27492
28588
|
sessionStore,
|
|
27493
28589
|
viewerContextId
|
|
27494
28590
|
}),
|
|
@@ -27508,6 +28604,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
27508
28604
|
displaySettingsStore,
|
|
27509
28605
|
fileInputRef,
|
|
27510
28606
|
gitPanelOpen,
|
|
28607
|
+
terminalPanelOpen,
|
|
27511
28608
|
hiddenThinkingPreviewStore,
|
|
27512
28609
|
isSessionViewLoading,
|
|
27513
28610
|
isSubmitting,
|
|
@@ -27525,6 +28622,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
27525
28622
|
onAddDiffLineComment: addComposerDiffLineComment,
|
|
27526
28623
|
onOpenFileViewTab: openFileViewTab,
|
|
27527
28624
|
onReorderFileViewTabs: reorderFileViewTabs,
|
|
28625
|
+
onCloseTerminalPanel: closeTerminalPanel,
|
|
27528
28626
|
rightSidebarStore,
|
|
27529
28627
|
sessionStore,
|
|
27530
28628
|
store: composerStore,
|