@shawnstack/quickforge 1.7.5 → 1.7.7
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/dist/assets/AgentProfilesPage-BfA_sQ3A.js +1 -0
- package/dist/assets/ChatPanelHost-Dul1ahKj.js +307 -0
- package/dist/assets/CloudAccountSettingsPage-qZh0lTUN.js +1 -0
- package/dist/assets/PluginsPage-CPE5tbbf.js +1 -0
- package/dist/assets/ScheduledTasksPage-PTxL_PPg.js +2 -0
- package/dist/assets/SettingsWorkspacePage-BE2T4d3P.js +1696 -0
- package/dist/assets/ShareLinksSettingsPage-Bl8fP62X.js +1 -0
- package/dist/assets/SharedConversationPage-BK9XJnEe.js +1 -0
- package/dist/assets/TerminalDock-CL7HU9DI.js +2 -0
- package/dist/assets/{WorkspaceInspector-D9kdnLDd.js → WorkspaceInspector-MNBLIKMn.js} +5 -5
- package/dist/assets/{dist-DLKC_odd.js → dist-yDHbi5ux.js} +1 -1
- package/dist/assets/{esm-Df4edDpj.js → esm-sdsK6gaB.js} +2 -2
- package/dist/assets/{icons-CXPP1fFT.js → icons-2D18YbSI.js} +1 -1
- package/dist/assets/index-BTPzyq7d.js +65 -0
- package/dist/assets/index-BiCTgUlY.css +3 -0
- package/dist/assets/{mcp-servers-dialog-BUSPvaqI.js → mcp-servers-dialog-GY7sdfIr.js} +2 -2
- package/dist/assets/{logger-8REuLPGK.js → model-display-label-C6-0eDxF.js} +1 -1
- package/dist/assets/{monaco-D6OhXgjg.js → monaco-DvXErxp2.js} +1 -1
- package/dist/assets/{react-vendor-1KC5PyRx.js → react-vendor-3UaA-C9W.js} +1 -1
- package/dist/assets/{skills-dialog-BThnIUBs.js → skills-dialog-C1fJ1Jl7.js} +3 -3
- package/dist/assets/{web-DoV8MSMn.js → web-B5qgZJRv.js} +1 -1
- package/dist/index.html +8 -8
- package/dist/sw.js +17 -0
- package/package.json +2 -1
- package/runtime-assets/agent/darwin-arm64/qf-agent +0 -0
- package/runtime-assets/agent/darwin-x64/qf-agent +0 -0
- package/runtime-assets/agent/linux-arm64/qf-agent +0 -0
- package/runtime-assets/agent/linux-x64/qf-agent +0 -0
- package/runtime-assets/agent/win32-x64/qf-agent.exe +0 -0
- package/server/access-policy.mjs +11 -0
- package/server/agent-manager.mjs +349 -48
- package/server/agent-profiles.mjs +27 -8
- package/server/auto-compaction.mjs +78 -9
- package/server/cloud/client.mjs +4 -7
- package/server/cloud/config.mjs +9 -16
- package/server/cloud/credential-store.mjs +10 -3
- package/server/cloud/identity.mjs +17 -60
- package/server/cloud/models.mjs +1 -1
- package/server/cloud/qf-agent-process.mjs +571 -0
- package/server/cloud/runtime.mjs +11 -5
- package/server/cloud/service-config.mjs +8 -4
- package/server/context-usage.mjs +11 -4
- package/server/index.mjs +96 -37
- package/server/mcp/registry.mjs +8 -7
- package/server/message-converters.mjs +40 -19
- package/server/model-catalog.mjs +11 -4
- package/server/opencode-acp-agent.mjs +1151 -0
- package/server/public-api.mjs +11 -5
- package/server/routes/agent-profiles.mjs +6 -3
- package/server/routes/agent.mjs +43 -3
- package/server/routes/backup.mjs +5 -4
- package/server/routes/cloud.mjs +54 -35
- package/server/routes/shares.mjs +7 -8
- package/server/routes/storage.mjs +9 -24
- package/server/routes/system.mjs +7 -4
- package/server/utils/process-tree.mjs +78 -0
- package/dist/assets/AgentProfilesPage-XNjuqJs7.js +0 -1
- package/dist/assets/ChatPanelHost-CuF-PZpc.js +0 -292
- package/dist/assets/CloudAccountSettingsPage-GJSoi6sO.js +0 -1
- package/dist/assets/PluginsPage-BQgp0qN-.js +0 -1
- package/dist/assets/ScheduledTasksPage-DdekATzq.js +0 -2
- package/dist/assets/SettingsWorkspacePage-Cb54Ic91.js +0 -1639
- package/dist/assets/ShareLinksSettingsPage-C75WJpaF.js +0 -1
- package/dist/assets/SharedConversationPage-CjMtSQTW.js +0 -1
- package/dist/assets/TerminalDock-D4zJBJc4.js +0 -2
- package/dist/assets/index-_ZhK6bvp.js +0 -65
- package/dist/assets/index-iVV2bP_f.css +0 -3
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/esm-sdsK6gaB.js","assets/pi-ai-Cr2ee4a0.js","assets/rolldown-runtime-DWdDZTNf.js","assets/dist-yDHbi5ux.js","assets/ChatPanelHost-Dul1ahKj.js","assets/pi-web-ui-DV5jKjSg.js","assets/lit-vendor-DvaQX_UQ.js","assets/icons-2D18YbSI.js","assets/react-vendor-3UaA-C9W.js","assets/plugin-api-Uu2xAB4d.js","assets/model-display-label-C6-0eDxF.js","assets/model-reference-o41fJ6jQ.js","assets/mermaid-renderer-jEbqFaTe.js","assets/SharedConversationPage-BK9XJnEe.js","assets/model-identity-CgA6_Pbm.js","assets/WorkspaceInspector-MNBLIKMn.js","assets/monaco-DvXErxp2.js","assets/TerminalDock-CL7HU9DI.js","assets/xterm-Bm_IbozX.js","assets/xterm-BrP-ENHg.css","assets/SettingsWorkspacePage-BE2T4d3P.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{At as t,B as n,C as r,Ct as i,D as a,E as o,Et as s,F as c,Ft as l,G as u,Gt as d,Ht as f,It as p,J as m,Kt as h,M as g,Mt as _,N as v,Nt as y,O as b,Ot as x,Pt as S,Q as C,Rt as w,St as T,Ut as E,V as D,W as O,Z as k,_ as ee,_t as te,at as A,d as j,f as ne,g as re,h as M,i as N,it as P,j as ie,jt as F,k as ae,kt as I,l as L,m as R,mt as oe,n as z,nt as se,o as ce,ot as le,p as ue,q as B,qt as de,r as fe,rt as pe,s as me,st as he,tt as ge,u as _e,ut as ve,w as ye,wt as be,xt as xe,y as Se,yt as Ce,z as we,zt as Te}from"./icons-2D18YbSI.js";import{i as Ee,n as De,r as Oe,t as ke}from"./react-vendor-3UaA-C9W.js";import{i as Ae,n as je,t as Me}from"./dist-yDHbi5ux.js";import{f as Ne,p as Pe,u as Fe}from"./lit-vendor-DvaQX_UQ.js";import{n as Ie,r as Le,t as Re}from"./css-utils-31qzCXsk.js";import{C as ze,D as Be,E as Ve,S as He,T as Ue,b as We,d as Ge,f as Ke,p as qe,u as Je,w as Ye}from"./pi-web-ui-DV5jKjSg.js";import{J as Xe,U as Ze,W as Qe}from"./pi-ai-Cr2ee4a0.js";import{n as V,t as $e}from"./model-display-label-C6-0eDxF.js";import{t as et}from"./skills-dialog-C1fJ1Jl7.js";import{n as tt,r as nt,t as rt}from"./model-reference-o41fJ6jQ.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var H=e(de(),1),it=Oe(),at=`language`,ot=[`en`,`zh`],st={en:{language:`Language`,displayLanguage:`Display language`,languageDescription:`Choose the display language for 速构 QuickForge. The page will reload to apply the change.`,simplifiedChinese:`Simplified Chinese`,english:`English`,apply:`Apply`,noLanguageChange:`The selected language is already active.`,newChat:`New chat`,startNewChat:`Start new chat`,newChatEmptyTitle:`What do you want to get done today?`,chooseProject:`Select project`,searchProjects:`Search projects`,newProject:`Add project`,createBlankProject:`Add project`,useExistingFolder:`Select project directory`,useNoProject:`No project`,noMatchingProjects:`No matching projects`,loadingChatWorkspace:`Loading chat workspace...`,loadingConversation:`Loading conversation`,loadingConversationPreparing:`Preparing history and tool records`,conversationLoadFailed:`Failed to load conversation`,localServiceUnavailableTitle:`Local QuickForge service unavailable`,localServiceUnavailableDescription:`QuickForge requires the local service for storage. Start QuickForge with npm run dev or the quickforge command, then reload this page.`,project:`Project`,projects:`Projects`,loadingProject:`Loading project...`,addProject:`Add project`,noProjects:`No projects yet.`,expandProject:`Expand project`,collapseProject:`Collapse project`,expandAllProjects:`Expand all projects`,collapseAllProjects:`Collapse all projects`,dragToReorder:`Drag to reorder`,newProjectChat:`New project chat`,projectChat:`Project chat`,normalChat:`Chat`,conversations:`Conversations`,turnNavigationLabel:`Conversation turns`,turnNavigationUserMessage:`User message`,turnNavigationFinalAnswer:`Final Answer`,turnNavigationGenerating:`Generating answer…`,turnNavigationNoAnswer:`No final answer yet`,turnNavigationAttachmentOnly:`Message with attachments`,turnNavigationJumpLabel:`Jump to turn {index}: {preview}`,pinnedConversations:`Pinned`,noConversations:`No conversations`,filterSort:`Filter and sort`,sidebarView:`View`,sidebarViewByProject:`By project`,sidebarViewTimeline:`Timeline`,sortBy:`Sort by`,sortByUpdatedAt:`Updated time`,sortByCreatedAt:`Created time`,filter:`Filter`,selecting:`Selecting...`,chooseFolder:`Choose folder`,selectProjectDirectory:`Select project directory`,selectProjectDirectoryDescription:`Browse local folders or paste a path, then choose the folder to add it as a project.`,quickAccess:`Quick access`,path:`Path`,go:`Go`,parentDirectory:`Parent directory`,noFolders:`No folders in this directory.`,selectThisFolder:`Select this folder`,folderPickerPathPlaceholder:`Enter or paste a folder path`,filesystemRootsFailed:`Failed to load filesystem roots.`,directoryLoadFailed:`Failed to load directory.`,noSavedConversations:`No saved conversations yet.`,rename:`Rename`,renameSession:`Rename conversation`,sessionName:`Conversation name`,deleteProject:`Delete project`,deleteProjectConfirm:`Are you sure you want to delete project "{name}"? Its conversations will be kept.`,deleteSession:`Delete session`,deleteSessionConfirm:`Are you sure you want to delete this conversation? This cannot be undone.`,deleteSessionFailed:`Failed to delete conversation.`,archiveSession:`Archive conversation`,confirmArchive:`Archive`,archivedConversations:`Archived conversations`,archivedConversationsDescription:`Archived conversations are hidden from the sidebar. Restore them here or delete them permanently.`,searchArchivedConversations:`Search archived conversations`,noArchivedConversations:`No archived conversations yet.`,archivedAt:`Archived at`,lastModified:`Last modified`,restoreSession:`Restore`,restoreSessionFailed:`Failed to restore conversation.`,sessionRestored:`Conversation restored.`,sessionNotFound:`Conversation not found.`,deletePermanently:`Delete`,deleteAll:`Delete all`,deleteArchivedSessionConfirm:`Permanently delete "{title}"? This cannot be undone.`,deleteAllArchivedSessionsConfirm:`Permanently delete all archived conversations? This cannot be undone.`,archivedSessionDeleted:`Archived conversation deleted.`,archivedSessionsDeleted:`Archived conversations deleted.`,shareLinks:`Share links`,shareLinksDescription:`Manage all conversation share links on this QuickForge instance, including expiration, disable, restore, and permanent deletion.`,cloudAccount:`QuickForge Cloud`,cloudAccountDescription:`Configure the QuickForge Cloud connection, identity, quota, model catalog, and connected devices. Local features remain available without an account.`,cloudServiceConnection:`Connection`,cloudServiceEnabled:`Enable cloud service`,cloudServiceEnabledDescription:`Allow this QuickForge instance to connect to QuickForge Cloud for remote access, managed models, account usage, and devices.`,cloudServiceDisabledDescription:`Cloud service is turned off. Local credentials are preserved, but remote access and managed cloud features are paused.`,cloudServiceEnabledSaved:`QuickForge Cloud is enabled.`,cloudServiceDisabledSaved:`QuickForge Cloud is disabled. Local credentials were preserved.`,cloudDisabledError:`QuickForge Cloud is turned off. Enable it in Cloud settings to continue.`,cloudRemoteAccess:`Remote access`,cloudRemoteAccessDescription:`QuickForge manages a separate local agent that securely connects this runtime to QuickForge Cloud.`,cloudRemoteServerUrl:`Bound server`,cloudRemotePid:`Agent PID`,cloudRemoteAuthorization:`Device authorization`,cloudRemoteOpenAuthorization:`Open authorization page`,cloudRemoteStatusLoading:`Loading`,cloudRemoteStatusDisabled:`Disabled`,cloudRemoteStatusUnavailable:`Agent unavailable`,cloudRemoteStatusStopped:`Stopped`,cloudRemoteStatusStarting:`Connecting`,cloudRemoteStatusAuthorizing:`Authorization required`,cloudRemoteStatusRunning:`Connected`,cloudRemoteStatusConflict:`Used by another runtime`,cloudRemoteStatusError:`Error`,cloudServiceType:`Service type`,cloudUrl:`Cloud API URL`,cloudUrlPlaceholder:`http://127.0.0.1:8082/`,cloudUrlInvalid:`Invalid URL`,cloudUrlInvalidProtocol:`http/https only`,cloudUrlHttpRestricted:`HTTP: localhost only`,cloudUrlAdminPort:`8081: admin console port`,cloudConfigSource:`Source`,cloudConfigSourceSaved:`Saved setting`,cloudConfigSourceEnv:`Environment`,cloudConfigSourceDefault:`Product default`,cloudTestConnection:`Test connection`,cloudConnectionTestSucceeded:`QuickForge Cloud health and readiness checks succeeded.`,cloudConnectionSaved:`QuickForge Cloud connection saved.`,cloudConnectionTestResult:`Connection test`,cloudHealth:`Health`,cloudReady:`Ready`,cloudConnectionOk:`OK`,cloudConnectionError:`Failed`,cloudConnectionUnknown:`Unknown`,cloudConnectionFailed:`Failed to connect to QuickForge Cloud.`,cloudRequestFailed:`QuickForge Cloud request failed.`,cloudRequestFailedWithStatus:`QuickForge Cloud request failed ({status}).`,cloudLocalOnlyError:`QuickForge Cloud is available only on this computer or an authenticated remote client.`,cloudConfigurationError:`The QuickForge Cloud configuration is invalid. Check the Cloud API URL.`,cloudSessionServiceMismatch:`This cloud session belongs to another service. Rebuild the cloud identity before continuing.`,cloudSessionExpired:`The cloud session is no longer valid. Sign in or start again.`,cloudDeviceFlowExpiredError:`The device sign-in code expired. Start account sign-in again.`,cloudDeviceFlowDeniedError:`The account authorization was denied.`,cloudSessionActiveGuidance:`A cloud session is active. Sign out this device first, or use “Rebuild identity and switch” after reviewing the warning.`,cloudForceSwitch:`Rebuild identity and switch`,cloudForceSwitchTitle:`Rebuild the cloud identity and switch services?`,cloudForceSwitchDescription:`This permanently clears the local cloud session and rotates the installation identity without sending its Refresh Token to either service. Existing guest quota cannot be recovered. The new URL is saved only after the reset succeeds.`,cloudForceSwitchConfirm:`Reset and switch`,cloudForceSwitchSucceeded:`The cloud identity was rebuilt and the service URL was switched. Start a new guest only when you are ready.`,cloudIdentityRebuiltUrlSaveFailed:`The cloud identity was rebuilt, but the new Cloud API URL was not saved. The previous saved URL is still active; review the URL above and retry saving.`,cloudSessionMismatchLabel:`Identity rebuild required`,cloudUnavailableDescription:`The local cloud session exists, but QuickForge Cloud cannot be reached. Check the service and retry.`,cloudUsageLoadFailed:`Failed to load cloud usage. Retry to refresh the quota.`,cloudModelsLoadFailed:`Failed to load the cloud model catalog. Retry to refresh it.`,cloudDevicesLoadFailed:`Failed to load connected devices. Retry to refresh them.`,cloudModels:`Cloud model catalog`,cloudNoModels:`No available cloud models were returned.`,cloudCapabilityTools:`Tools`,cloudCapabilityVision:`Vision`,cloudCapabilityReasoning:`Reasoning`,cloudCapabilityText:`Text`,cloudIdentityStatus:`Cloud identity`,cloudNotConfiguredDescription:`QuickForge Cloud is not configured on this instance.`,cloudConnectedDescription:`Cloud credentials are held by the local QuickForge service and are never exposed to the browser.`,cloudLocalOnlyDescription:`Local features remain anonymous and available. A cloud guest is created only after you choose to start.`,cloudFormalAccount:`Account`,cloudNotConnected:`Not connected`,cloudRemainingQuota:`Remaining quota`,cloudQuotaExpiresAt:`Quota resets or expires at`,cloudLoginOrRegister:`Sign in or register`,cloudLoginOrRegisterDescription:`QuickForge opens the Cloud verification page. Email and password are entered only there, never in QuickForge.`,cloudDeviceFlowTitle:`Complete sign-in in your browser`,cloudDeviceFlowDescription:`Open the Cloud verification page and enter the code if it is not filled automatically.`,cloudDeviceCode:`Device code`,cloudOpenVerificationPage:`Open verification page`,cloudDeviceFlowCountdown:`{seconds}s remaining`,cloudDeviceFlowSlowDown:`Cloud asked QuickForge to poll less often. Automatic polling will continue.`,cloudDeviceFlowSucceeded:`The account is connected.`,cloudDeviceFlowDenied:`The account authorization was denied. The guest session was kept.`,cloudDeviceFlowExpired:`The sign-in code expired. The guest session was kept.`,cloudDeviceFlowNetwork:`QuickForge Cloud is temporarily unreachable. Automatic polling will retry.`,cloudDeviceFlowCancelled:`Account sign-in cancelled. The guest session was kept.`,cloudDeviceCodeCopied:`Device code copied.`,cloudAccountEmail:`Email`,cloudAccountPlan:`Plan`,cloudDevices:`Connected devices`,cloudCurrentDevice:`Current device`,cloudUnnamedDevice:`Unnamed device`,cloudRegisteredAt:`Registered`,cloudLastSeenAt:`Last active`,cloudDuplicateDevicesHint:`{count} devices share the same name (e.g. “{name}”) — likely duplicates from repeated sign-ins. Revoke the ones you no longer need.`,cloudNoDevices:`No connected devices were returned.`,cloudRevokeDevice:`Revoke`,cloudRevokeDeviceConfirm:`Revoke cloud access for “{name}”? Its cloud sessions will stop working.`,cloudDeviceRevoked:`Device access revoked.`,cloudLogout:`Sign out this device`,cloudLogoutTitle:`Sign out this device?`,cloudLogoutDescription:`QuickForge will first revoke this device in the cloud, then clear its local cloud session. If the cloud cannot be reached, local credentials are kept so you can retry safely.`,cloudLogoutRowDescription:`This does not affect local projects, conversations, custom model providers, or API keys. Starting again creates a new guest identity and quota.`,cloudLoggedOut:`This device has been signed out of QuickForge Cloud.`,cloudLoadFailed:`Failed to load QuickForge Cloud status.`,cloudNotAvailable:`Not available`,searchShareLinks:`Search by conversation title or link ID`,shareLinksCount:`{count} links`,noShareLinks:`No share links yet.`,noMatchingShareLinks:`No matching share links.`,shareLinksLoadFailed:`Failed to load share links.`,shareStatusActive:`Active`,shareStatusDisabled:`Disabled`,shareStatusExpired:`Expired`,sharePermissionRead:`Read-only`,sharePermissionOperate:`Operate`,sharePasswordProtected:`Password protected`,shareCreatedAt:`Created`,shareExpiresAt:`Expires`,shareNeverExpires:`Never`,shareAccessCount:`{count} accesses`,shareLastAccessedAt:`Last accessed`,shareRestoreExpiration:`Expiration after restore`,shareUpdateExpiration:`New expiration`,updateShareExpiration:`Update expiration`,editShare:`Edit`,manageShare:`More`,editShareTitle:`Edit share link`,sharePermissionTitle:`Permission`,sharePermissionReadHint:`View-only access to this conversation.`,sharePermissionOperateHint:`Allows operating the original conversation. Password required.`,sharePasswordTitle:`Password`,sharePasswordPlaceholderKeep:`Leave blank to keep the current password`,sharePasswordPlaceholderNone:`Leave blank to keep it passwordless`,sharePasswordEditHint:`Leave blank to keep the current password. A new password invalidates previous ones.`,sharePasswordSetHint:`Filling a password adds protection and invalidates previous unlocks.`,sharePasswordRemovalSelected:`Password protection will be removed after saving.`,removePassword:`Remove password`,keepCurrentExpiration:`Keep current expiration`,saveChanges:`Save changes`,shareUpdated:`Share settings updated.`,operateRequiresPassword:`Operate shares require a non-empty password.`,oneHour:`1 hour`,twentyFourHours:`24 hours`,sevenDays:`7 days`,copyShareLink:`Copy share link`,openShareLink:`Open share link`,disableShare:`Disable`,restoreShare:`Restore`,deleteShare:`Delete permanently`,disableShareConfirm:`Disable the share link for "{title}"? Existing access and live connections will stop immediately.`,deleteShareConfirm:`Permanently delete the share link for "{title}"? This cannot be undone.`,shareLinkCopied:`Share link copied.`,shareDisabled:`Share link disabled.`,shareRestored:`Share link restored.`,shareExpirationUpdated:`Share link expiration updated.`,shareDeleted:`Share link permanently deleted.`,untitledConversation:`Untitled conversation`,allProjects:`All projects`,unknownProject:`Unknown project`,conversationCount:`{count} conversations`,confirm:`Confirm`,confirmDelete:`Delete`,settings:`Settings`,toggleSidebar:`Toggle sidebar`,failedToSelectProjectDirectory:`Failed to select project directory.`,projectSwitchFailed:`Failed to switch to the project for this conversation. Workspace tools were not started.`,copy:`Copy`,copied:`Copied`,svgDisplayMode:`SVG display mode`,svgPreviewMode:`Preview`,svgSourceMode:`Source`,svgEnlargePreview:`Click to enlarge SVG preview`,copySvgSource:`Copy SVG source`,downloadSvg:`Download SVG`,mermaidPreviewLabel:`Mermaid diagram preview`,mermaidEnlargePreview:`Click to enlarge Mermaid diagram`,copyMermaidSource:`Copy Mermaid source`,downloadMermaidSvg:`Download Mermaid SVG`,mermaidRendering:`Rendering Mermaid diagram...`,mermaidRenderFailed:`Could not render this Mermaid diagram. Source is shown instead.`,rollback:`Rollback`,retry:`Retry`,reloadPage:`Reload page`,fork:`Fork`,forkConversation:`Fork conversation from here`,yoloEnabledTitle:`Workspace access enabled: local tools can use this project`,yoloDisabledTitle:`Workspace access locked: local tools are blocked`,agentAccessMenuLabel:`Agent access mode`,agentAccessDefaultLabel:`Default permissions`,agentAccessFullLabel:`Full access`,agentAccessDefaultTitle:`Default permissions: work inside the current repository; ask before actions that may affect the system.`,agentAccessFullTitle:`Full access: developer-level authorization; tools can run automatically within the configured workspace boundaries.`,agentAccessModeSyncFailed:`Failed to sync Agent access mode.`,planModeLabel:`Plan`,planModeEnabledTitle:`Plan mode enabled: send the next message as /plan. Click to remove. Shortcut: Shift+Tab`,planModeDisabledTitle:`Plan mode: send the next message as /plan. Shortcut: Shift+Tab`,composerPlaceholder:`Describe what you want to do`,assistantWaitingThinking:`Thinking`,assistantWaitingOrganizing:`Organizing the answer`,assistantWaitingContinuing:`This may take a little longer`,assistantWaitingAriaLabel:`Assistant is preparing a response`,customCommandsHint:`Custom commands`,customCommandsEmptyHint:`No project commands yet.`,customCommandsListDescription:`List project custom commands`,customCommandsNewDescription:`Create a project custom command`,initCommandDescription:`Generate or update a concise AGENTS.md contributor guide for the current repository.`,planCommandDescription:`Create a plan first; this turn cannot edit files or run commands.`,reviewCommandDescription:`Review pending code changes before commit; this turn cannot edit files.`,summaryCommandDescription:`Create a new chat with this conversation summarized to reduce context usage.`,compactCommandDescription:`Compact this conversation context in place using the same rolling summary as auto-compaction.`,clearCommandDescription:`Clear the current chat history and context without calling the model.`,helpCommandDescription:`Show all available commands and their usage.`,yoloBlockedReason:`Local tool {name} was blocked by the current Agent permission mode. Switch to Full access or approve the tool call when prompted.`,globalToolBlockedReason:`Local tool {name} was blocked because this is a normal chat with no project attached. Start or open a project chat to use workspace tools.`,noActiveProjectToolBlockedReason:`Local tool {name} was blocked because there is no active project. Add or select a project to use workspace tools.`,generationAlreadyRunning:`Generation is still running. Stop it or wait until it finishes.`,generationStillRunning:`Generation is still running. Stop it or wait until it finishes before rolling back.`,noConversationTurnToRollback:`There is no conversation turn to roll back.`,rollbackConfirmTitle:`Confirm rollback?`,rollbackConfirm:`Roll back to before this message? This message and all following conversation history will be removed, and the message content will be restored to the composer.`,sharedRollbackConfirmTitle:`Confirm shared conversation rollback?`,sharedRollbackConfirm:`This will directly modify the sharer's original conversation. This message and all following conversation history will be removed, and the message content will be restored to the composer.`,confirmRollback:`Confirm rollback`,rollingBack:`Rolling back...`,rollbackFailed:`Rollback failed.`,retryFailed:`Retry failed.`,openCodeMessageHistoryActionUnavailable:`OpenCode does not support rollback, retry, or forking from a message position. These actions are unavailable for OpenCode conversations.`,openCodeConfigMenuLabel:`OpenCode config`,openCodeConfigButtonLabel:`Config`,openCodeConfigDisabledWhileStreaming:`OpenCode config is disabled while a generation is running.`,openCodeConfigModesTitle:`Mode`,openCodeConfigOptionsTitle:`Options`,openCodeModeMenuLabel:`OpenCode mode`,openCodeModeDisabledWhileStreaming:`OpenCode mode is disabled while a generation is running.`,openCodeUsageTokensTitle:`Used {used} / {size} tokens`,openCodeUsageCostTitle:`Cost: {amount} {currency}`,forkCurrentSession:`Duplicate current conversation`,forkCurrentSessionTitle:`Create a full copy of this OpenCode conversation as a new session.`,openCodeForkUnavailable:`This OpenCode conversation cannot be duplicated because no ACP session is available.`,openCodeForkFailed:`Failed to duplicate the conversation.`,copyFailed:`Copy failed. Please check clipboard permissions.`,errorBoundaryTitle:`Something went wrong`,errorBoundaryUnexpected:`An unexpected error occurred.`,errorBoundaryTryAgain:`Try again`,execute:`Run`,addCustomModelFirst:`Please add a custom model in Settings and make sure the model ID is filled in before saving.`,modelSetupRequired:`Please add a model before starting a new chat.`,modelSetupTitle:`No model configured yet`,modelSetupDescription:`Add an OpenAI-Compatible or Anthropic-compatible model to start chatting. QuickForge will only use models that you configure.`,modelSetupSupports:`Supports LiteLLM, OpenRouter, DeepSeek, Qwen, Zhipu, Ollama, and most /v1/chat/completions services.`,modelSetupLocalStorage:`Providers, model IDs, and API keys are stored locally by the QuickForge service on this machine.`,modelSetupAddModel:`Add model`,modelSetupUseLiteLlmExample:`Use LiteLLM example`,firstUseGuideTitle:`Start with a safe workflow`,firstUseGuideDescription:`Add a project, ask QuickForge to understand it, and use /plan before granting local tool access for code changes.`,firstUseGuideStepModel:`Confirm the model you want to use.`,firstUseGuideStepProject:`Add a local project so AI can use workspace context.`,firstUseGuideStepPlan:`Use /plan first; that turn cannot edit files or run commands.`,firstUseGuideConfigureModel:`Configure model`,firstUseGuideAddProject:`Add project`,firstUseGuideUsePrompt:`Try example prompt`,firstUseGuideCopyPrompt:`Copy /plan example`,firstUseGuideDismiss:`Got it`,firstUseGuideProjectPrompt:`/plan Read this project and explain its structure, run commands, and main risks. Do not modify files yet.`,firstUseGuideGeneralPrompt:`/plan Break this request into implementation steps and risks first. Do not modify files yet.`,defaultOptions:`General`,defaultOptionsDescription:`Configure language, default model, thinking level, tool display, and context management for new chats and scheduled tasks.`,memory:`Memory`,memoryDescription:`Let QuickForge remember useful preferences and habits across chats and projects.`,globalMemory:`Global memory`,globalMemoryDescription:`When enabled, QuickForge uses existing memory and can proactively remember durable preferences, habits, background, workflows, and goals that may help in future conversations.`,globalMemoryInfo:`Memory is stored locally and shared by all chats and projects. QuickForge avoids temporary task details, uncertain inferences, and sensitive credentials. Turn memory off to stop future reads and writes while keeping the existing file.`,memoryFile:`Memory file`,memoryFileDescription:`Saved as a readable Markdown file in the local QuickForge data directory.`,memoryCurrentSessionNote:`Changes are loaded by running chats before their next message. Turning memory off stops future reads and writes while keeping the existing file.`,memoryEnabledSaved:`Global memory enabled.`,memoryDisabledSaved:`Global memory disabled. Existing memory was kept.`,memoryContent:`Memory content`,memoryContentDescription:`View or edit the complete free-form Markdown document. Content and formatting are saved exactly as written.`,memoryContentDisabledDescription:`Turn global memory on to edit and save this file. Existing content remains available after reloading.`,memoryReload:`Reload`,memorySave:`Save memory`,memoryReloaded:`Memory reloaded.`,memoryContentSaved:`Global memory saved.`,memoryContentEmpty:`Global user memory is empty.`,defaultModel:`Default model`,defaultModelDescription:`Used by new chats and scheduled tasks unless overridden.`,defaultHarness:`Default Harness`,defaultHarnessDescription:`Used by new chats. The current blank chat updates immediately; existing chats keep their Harness.`,claudeCodeHarnessUnavailable:`Claude Code (not available yet)`,defaultThinkingLevel:`Default thinking level`,defaultThinkingLevelDescription:`Choose the default reasoning effort for supported models.`,toolDisplay:`Tool display`,toolDisplayModeDescription:`Compact shows summaries with details collapsed. Detailed shows full parameters and details with tool calls expanded.`,toolDisplayCompact:`Compact`,toolDisplayDetailed:`Detailed`,showContextUsage:`Show context usage`,showContextUsageDescription:`Show the context usage ring and details next to the model selector.`,fontSize:`Font size`,fontSizeDescription:`Adjust interface and conversation text size.`,fontSizeRangeDescription:`Drag to preview immediately; release to save.`,appearance:`Appearance`,appearanceDescription:`Customize the interface theme and font size.`,theme:`Theme`,themeDescription:`Switch between light and dark. Changes apply instantly.`,lightTheme:`Light`,darkTheme:`Dark`,appearanceSaved:`Appearance saved`,interfaceFontSize:`Interface font size`,messageFontSize:`Conversation font size`,messageFontSizeNote:`Applies to the main text in chat messages.`,fontSizeSaved:`Font size saved`,toolDetailsHidden:`Tool details are hidden in compact mode. Switch Tool display to Detailed in Settings to view full parameters.`,toolArgsSummary:`Arguments summary`,saveDefaultOptions:`Save defaults`,saving:`Saving...`,defaultOptionsSaved:`Default options saved`,networkConnection:`Network connection`,networkProxyMode:`Proxy mode`,networkProxyDirect:`Direct`,networkProxySystem:`Follow system`,networkProxyManual:`Manual proxy`,networkProxyPac:`PAC URL`,networkProxyDescription:`Controls supported external HTTP requests made by QuickForge. Localhost always connects directly. Follow system reads the operating-system proxy configuration, including PAC/WPAD when supported. Custom PAC URLs are supported by Desktop only.`,networkProxyAddress:`Proxy address`,networkProxyAddressDescription:`Enter an HTTP or HTTPS proxy URL with a port. Paths, query strings, fragments, and proxy credentials are not supported.`,networkProxyAddressRequired:`Enter a proxy address before saving.`,networkProxyAddressInvalid:`Enter a valid HTTP or HTTPS proxy address.`,networkProxyAddressProtocolError:`Only HTTP and HTTPS proxy addresses are supported.`,networkProxyAddressPortError:`The proxy address must include a host and port.`,networkProxyAddressCredentialsError:`Proxy credentials are not supported in the address.`,networkProxyAddressPathError:`The proxy address cannot contain a path, query string, or fragment.`,networkProxyPacUrl:`PAC URL`,networkProxyPacUrlDescription:`Enter an HTTP or HTTPS URL for a PAC script. Paths and query strings are supported; credentials and fragments are not.`,networkProxyPacUrlRequired:`Enter a PAC URL before saving.`,networkProxyPacUrlInvalid:`Enter a valid HTTP or HTTPS PAC URL.`,networkProxyPacUrlProtocolError:`Only HTTP and HTTPS PAC URLs are supported.`,networkProxyPacUrlHostError:`The PAC URL must include a host.`,networkProxyPacUrlCredentialsError:`Credentials are not supported in the PAC URL.`,networkProxyPacUrlFragmentError:`The PAC URL cannot contain a fragment.`,networkProxyPacUnsupported:`Custom PAC URLs are supported only by the Desktop runtime.`,networkProxySave:`Save proxy`,networkProxyRefresh:`Reload system proxy`,networkProxyRefreshDescription:`Reload the current operating-system proxy configuration and close existing network connections.`,networkProxyStatus:`Source: {source}; runtime: {runtime}.`,networkProxyUnsupported:`The operating-system proxy is not supported by this runtime.`,networkProxyLoadFailed:`Unable to load the current proxy configuration. Proxy controls are disabled.`,networkProxySaved:`Network proxy setting saved`,networkProxyRefreshed:`System proxy reloaded`,contextManagement:`Context Management`,contextUsageTitle:`Context usage`,contextUsageAriaLabel:`Context usage: {percent}%. Show details`,contextUsageTotal:`{used} / {limit} tokens`,contextUsageInputLabel:`Input / context`,contextUsageReservedOutputLabel:`Reserved output`,contextUsageSystemPromptLabel:`System prompt`,contextUsageToolsSchemaLabel:`Tools schema`,contextUsageMessagesLabel:`Messages`,contextUsageSourceServerShort:`Server calculated`,contextUsageSourceLocalShort:`Local estimate`,contextUsageScopeCompactedShort:`Compacted model context`,contextUsageScopeFullShort:`Full model context`,contextUsageUsed:`Context used: {percent}% ({used} / {limit} tokens)`,contextUsageInput:`Input/context: {tokens} ({source})`,contextUsageSourceProvider:`provider context`,contextUsageSourceMixed:`provider/local mixed context`,contextUsageSourceEstimated:`estimated context`,contextUsageLocalEstimate:`Local estimate: {tokens}`,contextUsageSystemPrompt:` System prompt: {tokens}`,contextUsageToolsSchema:` Tools schema: {tokens}`,contextUsageMessages:` Messages: {tokens}`,contextUsageProviderBaseline:` Provider usage baseline: {tokens}`,contextUsageTrailingMessages:` Trailing messages after usage: {tokens}`,contextUsageReservedOutput:`Reserved output: {tokens}`,contextUsageServerCalculated:`Source: server calculated via pi-agent-core/pi-ai`,contextUsageScopeCompacted:`Scope: compacted model context, not full visible chat history`,contextUsageScopeFull:`Scope: full model context`,contextUsageEffectiveMessages:`Messages: {effective} effective / {visible} visible`,contextUsageProviderTokens:`Provider context tokens: {tokens}`,autoCompactEnabled:`Automatically compact context`,autoCompactRequireConfirmation:`Ask before compacting automatically`,autoCompactRequireConfirmationDescription:`Ask for approval before QuickForge summarizes older history.`,autoCompactTriggerNote:`Checks run before each model request. Lower the threshold or reduce the model Context Window to test triggering.`,autoCompactThresholdPercent:`Compact when context reaches (%)`,autoCompactThresholdDescription:`Percentage of the model context window that triggers compaction.`,autoCompactKeepRecentTurns:`Keep recent user turns`,autoCompactKeepRecentTurnsDescription:`Recent turns stay in full detail after older context is summarized.`,autoCompactDescription:`When the estimated next request reaches the configured share of the model context window, QuickForge summarizes older history and continues the current task. This uses one extra model call.`,autoCompactHistoryPreserved:`The full chat history remains visible; only the context sent to the model is compacted.`,autoArchiveEnabled:`Automatically archive old conversations`,autoArchiveTriggerNote:`Conversations not updated for more than 30 days are moved to Archived conversations.`,autoArchiveDescription:`Archived conversations are not deleted. Turning this off only stops future automatic archiving; existing archived conversations can still be viewed and restored.`,autoArchiveSaved:`Automatic archive setting saved`,thinkingLevel:`Thinking level`,thinkingOff:`Off`,thinkingLow:`Low`,thinkingMedium:`Medium`,thinkingHigh:`High`,thinkingXHigh:`XHigh`,currentConfiguration:`Current configuration`,thinkingSupported:`Thinking`,thinkingNotSupported:`This model does not support thinking levels.`,thinkingRequiresReasoningModel:`Thinking levels require a reasoning / thinking model.`,customModels:`Custom Models`,customModelsTitle:`Custom models`,customModelsDescription:`Only use custom OpenAI-Compatible models that you configure.`,addModel:`Add model`,editModel:`Edit model`,delete:`Delete`,editCustomModel:`Edit custom model`,addCustomModel:`Add custom model`,providerName:`Provider name`,providerNamePlaceholder:`e.g., LiteLLM`,protocolType:`Protocol type`,protocolHelp:`Use OpenAI Compatible for LiteLLM, OpenRouter, and most /v1/chat/completions services. Use Anthropic Messages only for the direct Anthropic API.`,apiKey:`API Key`,apiKeyPlaceholder:`Leave empty if not required`,showApiKey:`Show API Key`,hideApiKey:`Hide API Key`,customHeaders:`Custom Headers JSON`,customHeadersPlaceholder:`{
|
|
3
|
+
"X-Custom-Header": "value"
|
|
4
|
+
}`,customHeadersHelp:`Optional provider-level HTTP headers. Must be a JSON object with string values. Headers are saved locally with this model configuration.`,invalidHeadersJson:`Custom headers must be a valid JSON object with string key-value pairs.`,modelId:`Model ID`,modelIdPlaceholder:`e.g., anthropic/claude-sonnet-4`,contextWindow:`Context Window`,maxTokens:`Max Tokens`,reasoningModel:`Reasoning / Thinking model (DeepSeek V4, Qwen, etc.)`,imageInputModel:`Image input / vision model`,imageInputModelHelp:`Enable only when the model documentation confirms image input support. When disabled, attached images are omitted before the request is sent so non-vision models do not fail.`,showModelInSelectors:`Show in model selectors`,showModelInSelectorsHelp:`Turn off to keep this model configured while hiding it from model selection lists.`,providerProtocol:`Protocol`,model:`Model`,reasoning:`Reasoning`,noModelAdded:`No model added`,modelsCount:`{count} model(s)`,modelIndex:`Model #{index}`,modelsList:`Models`,atLeastOneModel:`At least one model is required.`,duplicateModelId:`Duplicate model IDs are not allowed.`,cancel:`Cancel`,save:`Save`,yes:`Yes`,no:`No`,loading:`Loading...`,noCustomModels:`No custom models yet. Click "Add model".`,fillProviderBaseUrlModel:`Please fill in provider name and Base URL.`,saveCustomModelFailed:`Failed to save custom model.`,confirmDeleteProvider:`Delete {name}?`,deleteFailed:`Delete failed.`,selectCustomModel:`Select custom model`,close:`Close`,back:`Back`,more:`More`,searchModels:`Search models...`,searchSettings:`Search settings...`,noSettingsResults:`No matching settings found`,noMatchingCustomModels:`No matching custom models`,presets:`Quick templates`,presetOpenai:`OpenAI`,presetDeepseek:`DeepSeek`,presetGlm:`Zhipu GLM`,presetOllama:`Local Ollama`,presetLitellm:`LiteLLM Proxy`,presetCustom:`Custom`,providerAdvanced:`Advanced options`,expandModel:`Adjust context window, max tokens, reasoning, image input`,addHeader:`Add header`,headerName:`Header name`,headerValue:`Value`,removeHeader:`Remove header`,testConnection:`Test connection`,testingConnection:`Testing...`,connectionOk:`Connection OK`,connectionFailed:`Connection failed`,testRequiresFields:`Fill in Base URL and at least one model ID.`,readFile:`Read File`,manageGlobalMemory:`Manage Memory`,searchFiles:`Search Files`,writeFile:`Write File`,editFile:`Edit File`,runCommand:`Run Command`,presentFiles:`Present Files`,generateImage:`Generate Image`,generatingImage:`Generating image...`,generatedImageAlt:`Generated image {index}`,openGeneratedImage:`Open generated image`,downloadGeneratedImage:`Download generated image`,executeInTerminal:`Run in terminal`,confirmExecuteCommandTitle:`Run command in terminal?`,confirmExecuteMultipleCommands:`This will run multiple lines in your local terminal. Continue?`,confirmExecuteDangerousCommand:`This command may modify your system, publish packages, push code, or run a remote script. Continue?`,terminalCommandExecuteFailed:`Failed to run command in terminal.`,runSubagent:`Run subagent`,subagentGeneral:`General`,subagentExplore:`Explore`,subagentRunning:`{name} running`,subagentCompleted:`{name} completed`,subagentFailed:`{name} failed`,subagentTask:`Task`,subagentContext:`Context`,subagentExpectedOutput:`Expected output`,subagentResult:`Result`,subagentToolCalls:`Tool calls`,subagentToolApprovalWaiting:`{source} requests approval: {toolName}`,toolApprovalSourceSubagent:`Source: {source} subagent`,activateSkill:`Activate Skill`,readSkillResource:`Read Skill Resource`,yoloModeSyncFailed:`Failed to sync Agent access mode. The previous state has been restored.`,toolApprovalFailed:`Failed to submit tool approval. Please try again.`,toolApprovalSubmitting:`Submitting...`,toolApprovalRetry:`Retry submission`,toolApprovalNeedsConfirmation:`Confirmation required`,toolApprovalRiskCommand:`This operation will execute a Shell command in the current workspace.`,toolApprovalRiskFileChange:`This operation will modify files in the current workspace.`,toolApprovalRiskExternal:`This operation may send data to an external service and change remote content.`,toolApprovalRiskGeneric:`This tool may change local or external state. Review the parameters before continuing.`,toolApprovalViewDetails:`View full parameters`,toolApprovalHideDetails:`Hide full parameters`,toolApprovalSource:`Source`,toolApprovalServer:`Server`,toolApprovalPlugin:`Plugin`,toolApprovalTool:`Tool`,toolApprovalPath:`Path`,toolApprovalCommand:`Command`,toolApprovalDisabled:`This approval cannot be handled here.`,autoCompactApprovalStatus:`Context near limit`,autoCompactApprovalTitle:`Compact older conversation content`,autoCompactApprovalRisk:`QuickForge will summarize older history and keep the latest {keepRecentTurns} user turn(s). It will not modify workspace files.`,autoCompactApprovalAccept:`Compact now`,autoCompactApprovalReject:`Not now`,autoCompactApprovalUnavailable:`Context compaction approval is unavailable in this view.`,sharedApprovalReadOnly:`Please handle this approval in the sharer’s original conversation.`,terminateCommand:`Terminate`,terminateCommandTitle:`Terminate this running command`,commandTerminateRequested:`Terminating...`,running:`Running`,done:`Done`,error:`Error`,taskCompleted:`Task completed`,taskError:`Task error`,systemNotifications:`System notifications`,systemNotificationsDescription:`Show a browser or Android notification when a chat or scheduled task finishes while QuickForge is running in the background.`,systemNotificationsPermissionGranted:`Permission granted on this device. Foreground activity continues to use in-app messages only.`,systemNotificationsPermissionPrompt:`Permission has not been requested on this device.`,systemNotificationsPermissionDenied:`Permission was denied on this device.`,systemNotificationsUnsupported:`System notifications are not supported in this environment.`,systemNotificationsDeniedHelp:`Notification permission was denied. Allow it in the browser site settings or Android app settings, then try again.`,systemNotificationsEnabled:`System notifications enabled on this device.`,systemNotificationsDisabled:`System notifications disabled on this device.`,systemNotificationsTest:`Send test`,systemNotificationTestTitle:`QuickForge notification test`,systemNotificationTestFailed:`The test notification could not be displayed. Check the system permission and try again.`,systemNotificationOpenDetails:`Tap to open QuickForge for details.`,called:`Called`,input:`Input`,output:`Output`,details:`Details`,scheduledTasks:`Scheduled Tasks`,scheduledTasksDescription:`Tasks are saved in the local backend service and run by the cron expression parsed by AI.`,createTask:`Create task`,editTask:`Edit`,cancelEditTask:`Cancel edit`,saveTask:`Save task`,taskScheduleDescriptionLabel:`Schedule description`,taskScheduleDescriptionPlaceholder:`e.g., Every day at 9 AM, send this to AI: generate my daily sales report.`,quickAiParseTask:`AI parses this description into a cron expression. The system stores and runs by cron.`,taskTitleLabel:`Task name`,taskTitlePlaceholder:`e.g., Daily work summary`,promptContentLabel:`AI will send this content`,promptContentPlaceholder:`Write the exact content that should be sent to AI when this task runs.`,taskEnabledSwitch:`Enable this task`,taskInstructionPlaceholder:`e.g., Generate a daily sales report at 9 AM every day`,aiParseTask:`AI Parse`,confirmCreate:`Confirm create`,taskList:`Task list`,noScheduledTasks:`No scheduled tasks yet. Enter a natural language instruction above to create one.`,taskEnabled:`Enabled`,taskRunning:`Running`,taskPaused:`Paused`,taskFinished:`Completed`,taskFailed:`Failed`,executeNow:`Run now`,enable:`Enable`,pauseTask:`Pause`,deleteTask:`Delete`,recentExecutions:`Recent executions`,executionSuccess:`Success`,executionRunning:`Running`,nextExecution:`Next`,lastExecution:`Last`,noModelAvailable:`No models available`,noProjectBound:`No project`,aiParsed:`AI parsed, please confirm`,taskName:`Task name`,executionRule:`Execution rule`,nextExecutionTime:`Next execution`,taskProject:`Project`,taskThinkingLevel:`Thinking`,aiInstruction:`AI instruction`,taskModel:`Model`,taskThinking:`Thinking`,taskProjectLabel:`Project`,taskExecutionMode:`Execution mode`,taskExecutionModeSerial:`Serial`,taskExecutionModeParallel:`Parallel`,taskExecutionModeHelp:`This only controls whether the same task may overlap. Different scheduled tasks still run in parallel.`,tasksCount:`{total} tasks, {enabled} enabled`,confirmDeleteTask:`Are you sure you want to delete this scheduled task? This cannot be undone.`,waitingForResult:`Waiting for result`,autoRun:`Auto`,manualRun:`Manual test`,runInputContent:`Sent to AI`,runAiResult:`AI result`,runDuration:`Duration: `,taskListTab:`Task list`,executionHistoryTab:`Execution history`,agentsTab:`Agents`,agentsDescription:`Create reusable Agent Profiles for scheduled tasks and run_subagent delegation.`,createAgent:`Create agent`,editAgent:`Edit agent`,builtinAgent:`Built-in`,builtinAgentReadonly:`Built-in agents are read-only in this version.`,builtinAgentModelSettings:`Model & thinking settings`,builtinAgentModelOnly:`This built-in Agent is system-managed. Only its model and thinking level can be changed.`,readonlyAgentDescription:`This Agent is loaded from a read-only source and cannot be edited here.`,enabledAsSubagent:`Enabled as subagent`,enableAsSubagent:`Enable as subagent`,disableAsSubagent:`Disable as subagent`,noDescription:`No description.`,maxRuntimeMs:`Max runtime: `,maxToolCalls:`Max tool calls: `,defaultAgent:`Default Agent`,executionAgent:`Execution Agent: `,agentName:`Agent name`,agentLabel:`Display name`,agentLabelPlaceholder:`e.g., Code Review Agent`,agentDescription:`Description`,agentSystemPrompt:`System prompt`,agentModelMode:`Model mode`,agentModelInherit:`Inherit parent model`,agentModelFixed:`Use fixed model`,agentFixedModel:`Fixed model`,agentThinkingLevel:`Thinking level`,agentThinkingInherit:`Inherit caller setting`,agentThinkingDescription:`When the runtime model does not support reasoning, this automatically falls back to Off.`,agentThinkingUnsupported:`The selected fixed model does not support reasoning, so thinking is Off.`,allowedTools:`Allowed tools`,agentSourcePath:`Source path`,highRiskTool:`High risk`,confirmDeleteAgent:`Are you sure you want to delete this custom agent? Scheduled tasks using it will fall back to the default agent.`,aiFillAgent:`AI fill`,aiFillAgentDescription:`Describe the agent you want. AI will only fill agent name, display name, description, and system prompt.`,aiFillAgentPlaceholder:`e.g., Create a read-only code review agent focused on architecture, bugs, and test coverage.`,aiFillAgentLoading:`Generating...`,aiFillAgentNoModel:`Please configure a default model first.`,aiFillAgentFailed:`AI fill failed. Please check model configuration and API key, then try again.`,aiFillAgentInputRequired:`Please describe the agent you want to create.`,taskContent:`Task content`,viewDetails:`View details`,moreActions:`More actions`,historyFilters:`Filters`,allTasks:`All tasks`,allStatuses:`All statuses`,allTriggers:`All triggers`,triggerType:`Trigger`,keyword:`Keyword`,keywordPlaceholder:`Search input, result, or error`,startTime:`Start time`,endTime:`End time`,query:`Search`,reset:`Reset`,previousPage:`Previous`,nextPage:`Next`,pageSize:`{size} / page`,paginationSummary:`Page {page} / {pages}, {total} total`,noExecutionHistory:`No execution history yet.`,viewConversation:`View conversation`,createdAt:`Created at`,status:`Status`,search:`Search`,noMatchingOptions:`No matching options`,searchDialog:`Search conversations...`,noSearchResults:`No matching conversations found`,searchHint:`Enter keywords to search loaded conversations`,scheduledTasksLabel:`Scheduled Tasks`,skills:`Skills`,mcp:`MCP`,mcpServers:`MCP Servers`,plugins:`Plugins`,pluginMentionHeader:`Plugins`,composerAddMenu:`Add`,composerAddAttachment:`Attachment`,composerAddPlugins:`Plugins`,composerAddBack:`Back`,pluginDocumentsName:`Documents`,pluginDocumentsDescription:`Create and edit document artifacts`,pluginSpreadsheetsName:`Spreadsheets`,pluginSpreadsheetsDescription:`Create, analyze, and structure spreadsheet files`,pluginPresentationsName:`Presentations`,pluginPresentationsDescription:`Create and edit presentations`,pluginsDescription:`Manage local QuickForge plugins. This first version supports manifest-based plugins that contribute Agent tools.`,pluginsReload:`Reload plugins`,loadingPlugins:`Loading plugins...`,noPlugins:`No plugins found`,noPluginsDescription:`Place a plugin folder with plugin.json under one of these search paths, then reload.`,pluginsCount:`{total} plugins, {enabled} enabled`,pluginToolsCount:`{count} tools`,pluginPermissionsCount:`{count} permissions`,pluginDetails:`Plugin details`,pluginVersion:`Version`,pluginStatusLoaded:`Loaded`,pluginStatusDisabled:`Disabled`,pluginStatusError:`Error`,pluginTools:`Tools`,pluginPermissions:`Declared permissions`,pluginNoTools:`No tools declared.`,pluginNoPermissions:`No permissions declared.`,pluginTrustedNotice:`Plugins are local trusted Node.js code in this MVP; permissions are displayed for review and future enforcement.`,pluginDiscoveryErrors:`Plugin discovery errors`,enablePlugin:`Enable`,disablePlugin:`Disable`,pluginsLoadFailed:`Failed to load plugins.`,pluginsSaveFailed:`Failed to update plugin.`,manageMcpServers:`Manage MCP servers`,mcpNoServersDescription:`No MCP servers configured yet. Click "Add server" or paste an mcpServers JSON on the right.`,mcpConfiguredServers:`Configured servers`,mcpAddServer:`Add server`,mcpEditServer:`Edit server`,mcpServerName:`Server name`,mcpCommand:`Command`,mcpTransport:`Transport`,mcpUrl:`URL`,mcpArgs:`Arguments, one per line`,mcpCwd:`Working directory`,mcpEnv:`Environment variables, KEY=value per line`,mcpToolsCount:`{count} tools`,mcpLoadFailed:`Failed to load MCP servers.`,mcpSaveFailed:`Failed to save MCP server.`,mcpDeleteFailed:`Failed to delete MCP server.`,mcpReconnectFailed:`Failed to reconnect MCP server.`,mcpDeleteConfirm:`Delete MCP server "{name}"?`,mcpImportConfig:`Import MCP JSON`,mcpImportConfigDescription:"Paste an MCP JSON configuration in mcpServers format. QuickForge supports stdio, HTTP, and SSE transports. For remote servers, headers are accepted and resolved from backend environment variables when using ${...}.",mcpUseExample:`Use example`,mcpImportUpdate:`Import / update`,mcpReplaceAll:`Replace all`,mcpReplaceConfirm:`This will remove MCP servers that are not included in the JSON. Continue?`,mcpInvalidJson:`MCP configuration must be valid JSON.`,mcpInvalidConfigJson:`MCP configuration must contain a mcpServers object.`,mcpEmptyConfigJson:`mcpServers cannot be empty.`,mcpInvalidServerName:`Invalid MCP server name: {name}. Use lowercase letters, numbers, and hyphens only.`,mcpInvalidServerConfig:`MCP server "{name}" must be an object.`,mcpInvalidTransport:`MCP server "{name}" transport must be stdio, http, or sse.`,mcpMissingCommand:`MCP server "{name}" requires command for stdio transport.`,mcpMissingUrl:`MCP server "{name}" requires url for HTTP/SSE transport.`,mcpArgsMustBeArray:`MCP server "{name}" args must be an array.`,mcpEnvMustBeObject:`MCP server "{name}" env must be an object.`,mcpHeadersMustBeObject:`MCP server "{name}" headers must be an object.`,mcpHeaders:`Headers, KEY=value per line`,mcpReconnectServer:`Reconnect`,mcpMoreTools:`+{count}`,mcpNamePlaceholder:`e.g. my-server`,mcpUrlPlaceholder:`https://example.com/mcp`,mcpCommandPlaceholder:`e.g. npx`,mcpTabServer:`Server`,mcpTabJson:`JSON`,optional:`Optional`,globalSkills:`Global Skills`,projectSkills:`Project Skills`,help:`Help`,projectCommands:`Project Commands`,projectCommandsDescription:`Configure extra Markdown slash-command directories for the current project. QuickForge also reads user-level commands from ~/.quickforge/commands/ (shared across all projects), then project directories .claude/commands, .opencode/commands, .ai/commands, and these configured directories in order. Later duplicate command names override earlier ones.`,projectCommandsProjectDescription:`Choose the project whose command directories should be configured.`,selectProjectForCommands:`Please select or add a project before configuring project commands.`,commandDirectory:`Command directory`,commandDirectories:`Command directories`,commandDirectoriesDescription:`Add one directory per line. Relative paths are resolved from the selected project root.`,commandDirectoryPlaceholder:`.claude/commands
|
|
5
|
+
.opencode/commands
|
|
6
|
+
D:\\shared\\ai-commands`,commandDirectoryHelp:`One directory per line. Supports relative paths and absolute paths. Relative paths are resolved from the current project root. Leave empty to use the built-in compatible command directories only.`,commandDirectoryExamples:`Examples`,commandDirectoryExamplesDescription:`Common compatible directories are still discovered automatically.`,projectCommandsSaved:`Project command settings saved.`,loadedCommands:`Loaded commands ({count})`,loadedCommandsDescription:`Commands discovered from user-level, compatible, and configured directories for this project.`,noCommandsLoaded:`No commands loaded yet. Add a directory above or create a command to get started.`,openCommandDir:`Open command directory`,createCommand:`New command`,projectCommandsActions:`Actions`,projectCommandsActionsDescription:`Save configured directories before reloading discovered commands.`,newCommandPrompt:`Enter a command name (lowercase letters, numbers, hyphens):`,commandCreated:`Command created: {name}`,commandAlreadyExists:`Command already exists: {name}`,invalidCommandName:`Invalid command name. Use lowercase letters, numbers, and hyphens.`,manageSkills:`Manage skills`,manageGlobalSkills:`Manage global skills`,manageProjectSkills:`Manage project skills`,openFolder:`Open folder`,fileManager:`File Manager`,openWorkspace:`Open workspace`,chooseWorkspaceOpenTarget:`Choose workspace open target`,openInExplorer:`Open in Explorer`,openInExplorerFailed:`Failed to open the project folder.`,openInVSCode:`Open in VS Code`,openInVSCodeFailed:`Failed to open the project in VS Code. Make sure the VS Code command-line tool is installed.`,openInIDEA:`Open in IntelliJ IDEA`,openInIDEAFailed:`Failed to open the project in IntelliJ IDEA. Make sure IntelliJ IDEA is installed or the idea command-line tool is available.`,moreOptions:`More options`,gitBranchMenu:`Git branch menu`,searchBranches:`Search branches`,uncommittedChanges:`Uncommitted changes:`,filesCount:`{count} file(s)`,noBranchesFound:`No branches found`,currentBranch:`Current`,createBranchTitle:`Create and checkout new branch`,createBranchDescription:`Enter a new branch name. QuickForge will create it from the current HEAD and check it out.`,createBranchPlaceholder:`feature/my-branch`,createAndCheckoutBranch:`Create and checkout`,createAndCheckoutBranchEllipsis:`Create and checkout new branch...`,gitGraph:`Git Graph`,gitBranchesFailed:`Failed to load branches.`,gitCheckoutFailed:`Failed to switch branch.`,gitBranchSwitched:`Branch switched`,gitBranchCreated:`Branch created`,gitToolsTitle:`Git Tools`,togglePinnedSummary:`Toggle pinned summary`,environmentInfo:`Environment info`,gitToolsCollapse:`Collapse Git tools`,gitToolsChanges:`Changes`,gitToolsCommitOrPush:`Commit or push`,gitCommitMessagePlaceholder:`Commit message`,gitGenerateCommitMessage:`Generate commit message`,gitGenerateCommitMessageFailed:`Failed to generate commit message.`,gitIncludeUnstagedChanges:`Include all unstaged changes`,gitIncludeUnstagedWarning:`All modified, untracked, and deleted files will be added to this commit.`,gitCommitFilesSummary:`{selected} of {total} files`,gitFileNotIncluded:`Not included`,gitCommitMessageRequired:`Enter or generate a commit message first.`,gitNoStagedChanges:`There are no staged changes to commit.`,gitDetachedHeadBlocked:`Switch to a branch before committing or pushing.`,gitCommitSucceededPushFailed:`Commit succeeded, but push failed.`,gitRetryPush:`Retry push`,gitRefreshingStatus:`Refreshing Git status…`,gitStatusRefreshFailed:`Failed to refresh Git status.`,gitCommitOnly:`Commit`,gitCommitAndPush:`Commit and push`,gitPushOnly:`Push`,gitCommitNoProject:`No project is selected.`,gitCommitNoModel:`Please configure a default model first.`,gitCommitConflictsBlocked:`Resolve conflicts before committing.`,gitOperationFailed:`Git operation failed.`,gitOperationCompleted:`Git operation completed`,gitGraphFailed:`Failed to load Git graph.`,noGitCommits:`No commits found.`,refresh:`Refresh`,graphColumn:`Graph`,description:`Description`,date:`Date`,author:`Author`,commit:`Commit`,pinSession:`Pin conversation`,unpinSession:`Unpin conversation`,shareSession:`Share conversation`,selectProjectForSkills:`Please select or add a project before managing skills.`,skillsDescription:`Select reusable Agent Skills enabled for project "{project}". QuickForge discloses only name/description in the prompt; full SKILL.md instructions are loaded on demand with activate_skill.`,globalSkillsDescription:`Select reusable Agent Skills enabled globally for QuickForge. New chats receive only the skill catalog; full SKILL.md instructions load on demand with activate_skill.`,projectSkillsDescription:`Select project Agent Skills for "{project}". Project skills override global skills with the same name; new project chats receive only the catalog and load full instructions on demand.`,searchSkills:`Search skills...`,availableSkills:`Available skills`,selectedSkillsCount:`{count} selected`,noMatchingSkills:`No matching skills found`,skillSearchPaths:`Search paths`,failedToLoadSkills:`Failed to load skills.`,failedToSaveSkills:`Failed to save skills.`,readSkill:`Read skill`,readSkillContent:`Read skill content`,backToSkillList:`Back to skill list`,failedToReadSkill:`Failed to read skill content.`,noSkillContent:`This skill has no readable content.`,requestFailed:`Request failed`,backupRestore:`Backup & Restore`,backupRestoreDescription:`Export or restore QuickForge settings, providers, and scheduled tasks. Local project lists and conversation history are not included. Imports create a safety backup before writing data.`,exportData:`Export data`,exportDataDescription:`Choose the settings data to include in a portable JSON backup.`,selectExportSections:`Select data to export`,selectExportSectionsDescription:`All settings data is selected by default. Turn off anything you do not want in this backup.`,conversationBackupExcluded:`Conversation history and local project lists are not part of settings backup and will not be exported here.`,selectAtLeastOneExportSection:`Select at least one data section to export.`,includeApiKeys:`Include API keys`,includeApiKeysDescription:`Saved provider API keys.`,backupExportSecretsConfirm:`This backup will contain API keys. Continue?`,exportBackup:`Export backup`,exportBackupDescription:`Download the selected data as a timestamped JSON file.`,backupExported:`Backup exported.`,backupExportFailed:`Backup export failed.`,importData:`Import data`,importDataDescription:`Restore core settings from a previously exported JSON backup. Conversation history in older full backups is ignored by this settings import flow.`,importBackup:`Import backup`,backupInspectTitle:`Backup preview`,backupInspectDescription:`Review metadata and choose what to restore before writing local data.`,backupInspectExportedAt:`Exported at`,backupInspectVersion:`Version`,backupInspectScope:`Scope`,backupInspectSecrets:`Contains API keys`,backupInspectSections:`Sections`,backupInspectFailed:`Backup inspection failed.`,backupInvalidSections:`The following invalid sections were skipped:`,backupInspected:`Backup inspected. Choose what to restore below.`,backupInspectedWithIgnoredConversations:`Backup inspected. Conversation history in this older backup was ignored; choose the settings data to restore below.`,selectRestoreSections:`Select data to restore`,restoreMode:`Restore mode`,restoreModeDescription:`Choose how imported data should be applied to local data.`,restoreModeReplace:`Replace`,restoreModeReplaceDescription:`Replace local data in the selected sections entirely with the backup. Existing local data will be overwritten.`,restoreModeMerge:`Merge`,restoreModeMergeDescription:`Merge backup data into local. On conflict the backup wins; local-only entries are preserved.`,backupImportActions:`Import actions`,backupImportActionsDescription:`Import the selected sections or cancel this backup preview.`,confirmImportSelected:`Import selected data`,selectAtLeastOneRestoreSection:`Select at least one data section to restore.`,restoreSettings:`Settings`,restoreSettingsDescription:`App preferences such as language and default options.`,restoreMcp:`MCP servers`,restoreMcpDescription:`Global MCP server definitions and their enable/disable state.`,restoreProviderKeys:`API keys`,restoreProviderKeysDescription:`Saved provider API keys.`,restoreCustomProviders:`Custom providers and models`,restoreCustomProvidersDescription:`Custom model providers, endpoints, model IDs, and related configuration.`,restoreScheduledTasks:`Scheduled tasks`,restoreScheduledTasksDescription:`Saved scheduled AI tasks.`,restoreConversations:`Conversations`,restoreConversationsDescription:`Conversation history and metadata. This is restored as one consistent unit.`,backupImportConfirm:`A safety backup will be created before importing. Continue?`,backupImportReplaceConfirm:`Replace local data in the selected sections with this backup? A safety backup will be created first.`,backupImportMergeConfirm:`Merge the selected backup data into local data? A safety backup will be created first.`,backupImported:`Backup imported. The app will reload.`,backupImportFailed:`Backup import failed.`,backupFileTooLarge:`This backup file is larger than {size}MB. Current settings import is intended for core settings; export a core settings backup or reduce conversation history before importing.`,backupStringTooLarge:`This backup is too large to process in the current browser-based import flow. Use a core settings backup, or reduce/exclude conversation history.`,backupSafetyBackupPath:`Safety backup saved at`,about:`About`,desktopUpdate:`Desktop releases`,desktopExit:`Exit`,aboutQuickForge:`About QuickForge`,aboutQuickForgeDescription:`View version and project links.`,projectInfo:`Project information`,packageName:`Package`,packageNameDescription:`The installed QuickForge package name.`,currentVersion:`Current version`,currentVersionDescription:`The version currently running on this machine.`,latestVersion:`Latest version`,latestVersionDescription:`The newest version returned by the update check.`,github:`GitHub`,githubDescription:`Open the project repository and release notes.`,checkUpdate:`Check for updates`,checkingUpdate:`Checking...`,checkUpdateDescription:`Check npm for the latest QuickForge Runtime release. This does not update the Electron Desktop shell.`,desktopUpdates:`Desktop updates`,desktopUpdatesDescription:`Download the latest desktop app.`,desktopUpdateFrequencyDescription:`Desktop updates open the download page.`,desktopUpdateHint:`Opened the download page.`,openDesktopReleases:`Download latest version`,runtimeUpdates:`Updates`,runtimeUpdatesDescription:`Check for a newer version.`,updateChannel:`Channel`,runtimeUpdateChannel:`Runtime (npm)`,checkRuntimeUpdate:`Check for updates`,updateAvailableMessage:`A new version is available: {current} → {latest}.`,localVersionNewerMessage:`You are using a newer local version: {current}.`,alreadyLatestVersion:`QuickForge is up to date ({version}).`,updateNow:`Update now`,updateRuntimeNow:`Update now`,updatingQuickForge:`Updating...`,updateStarted:`Update started. QuickForge will restart automatically.`,updateRestarted:`Update completed. Reloading...`,updateRestartTimeout:`Update is taking longer than expected. Please try again later.`,updateCompleted:`Update completed. Please restart QuickForge.`,updateFailed:`Update failed.`,updateCheckFailed:`Failed to check for updates.`,updateCommand:`Command`,updateLog:`Update log`,updateLogDescription:`Log file for the current update attempt.`,updateLogFile:`Log: {path}`,updateConfirm:`QuickForge will update and restart. Running tasks will be interrupted. Continue?`,updateFrequencySection:`Auto-check updates`,updateFrequencyDescription:`Show a reminder when a new version is available.`,frequencyStartup:`On every startup`,frequencyDaily:`Once a day`,frequencyWeekly:`Once a week`,frequencyOff:`Off`,lastCheckedAt:`Last checked: {time}`,lastCheckedNever:`Not checked yet`,newVersionAvailable:`New version {version} available`,newVersionAvailableSub:`Current {current} · click to view`,updateLater:`Later`,backendService:`Backend Service`,backendServiceDescription:`Restart the local QuickForge backend service. Running generations will be interrupted and the page will reconnect automatically.`,backendServiceStatus:`Service status`,restartBackendService:`Restart backend service`,restartBackendServiceDescription:`Use this when the local backend is stuck or after changing environment-level service settings.`,restartBackendConfirm:`Restart the backend service now? Running generations will be interrupted and the page will reconnect automatically.`,backendRestarting:`Backend is restarting...`,backendRestarted:`Backend restarted. Reloading...`,backendRestartFailed:`Backend restart failed.`,backendRestartTimeout:`Backend restart timed out. Please restart QuickForge manually.`,backendRestartUnsupported:`This launch mode does not support restarting from the UI. Please restart QuickForge manually.`,systemRestartRequiresAuth:`Restart requires a local or authenticated remote client.`,systemUpdateRequiresAuth:`Update requires a local or authenticated remote client.`,serviceMode:`Mode`,serviceModeDescription:`How the local QuickForge service is running.`,servicePid:`PID`,servicePidDescription:`Operating system process ID of the backend service.`,serviceStartedAt:`Started at`,serviceStartedAtDescription:`When this backend process was started.`,serviceDataDir:`Data directory`,serviceDataDirDescription:`Local directory used for settings, storage, logs, and cache.`,serviceWorkspace:`Workspace`,serviceWorkspaceDescription:`Workspace root used by the current service process.`,terminalShell:`Terminal shell`,terminalShellDescription:`QuickForge auto-detects common macOS, Windows, and Linux shells. Choose the default from the list, or use a custom command/path when it is missing. QUICKFORGE_TERMINAL_SHELL still takes priority.`,terminalShellAutoDetectedHint:`Detected entries are shown automatically for this computer.`,terminalShellDefault:`Default shell`,terminalShellCustomOption:`Custom command or path…`,terminalShellSaved:`Terminal shell setting saved. New terminal sessions will use it.`,terminalShellProfilesSaved:`Terminal shell profiles saved.`,terminalShellCommand:`Custom shell command or path`,terminalShellCustomDescription:`Add a shell only when it was not detected automatically.`,terminalShellCommandPlaceholder:`C:\\Program Files\\Git\\bin\\bash.exe`,terminalShellAdd:`Add`,terminalShellSetDefault:`Set as default`,terminalShellDefaultBadge:`Default`,terminalShellDetected:`Detected`,terminalShellNoDetected:`No shell was detected. Add a custom shell command or path below.`,terminalShellProfileRequired:`Enter a shell command or executable path before saving.`,terminalShellDeleteConfirm:`Delete terminal shell profile "{name}"?`,channels:`Channels`,channelsDescription:`Manage local communication channels that bridge external apps to QuickForge agents.`,channelsSecurityWarning:`Channel actions run local processes and are available only on this computer.`,channelsEmpty:`No channels are available yet.`,start:`Start`,stop:`Stop`,restart:`Restart`,channelWorkspace:`Launch workspace`,channelWorkspaceDescription:`Choose the workspace used when this channel starts. Use the default workspace for global, non-project chats.`,channelDefaultWorkspace:`Default workspace`,channelNoWorkspaces:`No workspace is available. Configure the default workspace before starting this channel.`,channelOpenLogs:`Open log folder`,channelOpeningLogs:`Opening log folder...`,channelOpenLogsFailed:`Failed to open the channel log folder.`,channelQrTitle:`Scan with WeChat`,channelQrDescription:`Use WeChat to scan the QR code shown below.`,channelStatusStopped:`Stopped`,channelStatusStarting:`Starting`,channelStatusWaitingScan:`Waiting for scan`,channelStatusRunning:`Running`,channelStatusStopping:`Stopping`,channelStatusError:`Error`,channelRestartConfirm:`Restart channel "{name}"?`,channelLogoutConfirm:`Log out channel "{name}"? You will need to scan again before using it.`,channelReloginConfirm:`Re-login channel "{name}"? The current process will stop and a new QR code will be generated.`,terminalNew:`New terminal`,rightPanelOpenTabsTitle:`Open tabs`,rightPanelOpenTabsDescription:`Choose a tab to open in the right panel.`,rightPanelAddTab:`Open tab`,rightPanelCloseOtherTabs:`Close other tabs`,rightPanelCloseAllTabs:`Close all tabs`,rightPanelFiles:`Files`,rightPanelReview:`Review`,rightPanelTerminal:`Terminal`,rightPanelBrowser:`Browser`,rightPanelFilesDesc:`Browse project files`,rightPanelReviewDesc:`Review Git changes`,rightPanelTerminalDesc:`Run terminal commands`,rightPanelBrowserDesc:`Preview web pages`,terminalNewWith:`New terminal with`,terminalNewWithProfile:`New terminal: {name}`,terminalSelectShell:`Choose shell for new terminal`,terminalCollapse:`Collapse terminal`,terminalFullscreen:`Fullscreen terminal`,terminalExitFullscreen:`Exit fullscreen`,terminalStarting:`Starting terminal...`,terminalUnavailable:`Terminal unavailable`,terminalNoSessions:`No terminal sessions`,terminalCreateFailed:`Failed to create terminal`,terminalCloseFailed:`Failed to close terminal`,terminalConnectionFailed:`Failed to connect to terminal.`,terminalConnectionTimedOut:`Terminal connection timed out.`,terminalConnectionClosedUnexpectedly:`Terminal connection closed unexpectedly.`,terminalSessionUnavailable:`The original terminal session has ended, possibly because the service restarted or the session expired. The process cannot be restored.`,terminalStartNew:`Start new terminal`,terminalConnecting:`Connecting to terminal...`,terminalReconnecting:`Reconnecting to terminal ({attempt}/{max})...`,terminalCloseSession:`Close {name}`,workspaceNoFilesToDisplay:`No files to display.`,workspaceNoWorkingTreeChanges:`No working tree changes.`,workspaceNoStagedChanges:`No staged changes.`,workspaceNoLastRunChanges:`No changed files matched the last run artifacts.`,workspaceRootPath:`Project root`,workspaceLoadingDiff:`Loading diff...`,workspaceNoDiffPreview:`No diff preview available.`,workspaceDiffTooLarge:`This diff is too large to preview inline.`,workspaceUnmodifiedLines:`{count} unmodified lines`,noProjectSelected:`No project selected`,workspacePanel:`Workspace`,workspaceExpandRightPanel:`Expand right panel`,workspaceCollapseRightPanel:`Collapse right panel`,workspaceOverview:`Overview`,workspaceFiles:`Workspace Files`,workspaceBrowser:`Browser`,workspaceChanges:`Changes`,workspaceCurrentArtifacts:`Review`,workspaceNoArtifacts:`No AI-produced files detected in this session yet.`,workspacePresentedArtifact:`Presented artifact`,workspaceInferredArtifact:`Inferred artifact`,workspaceCommands:`Commands`,workspaceCommandOutput:`Output`,workspaceCurrentBranch:`Current branch`,workspaceChangeCount:`changes`,workspaceNotGitRepository:`This project is not a Git repository.`,workspaceSelectProject:`Select a project to inspect its workspace.`,workspaceLoading:`Loading workspace...`,workspaceLoadFailed:`Failed to load workspace.`,workspaceFilterFiles:`Filter files by name or path`,workspaceOpenFileTitle:`Open a file`,workspaceOpenFileDescription:`Open a file from the workspace directory.`,workspaceOpenFileFailed:`Failed to open file.`,workspaceOpenDiffFailed:`Failed to open diff.`,workspaceViewDiff:`View diff`,refreshWorkspace:`Refresh workspace`,closeWorkspace:`Close workspace`,workspaceFullscreen:`Fullscreen workspace`,workspaceExitFullscreen:`Exit fullscreen`,workspaceStaged:`Staged`,workspaceUntracked:`Untracked`,workspaceConflicts:`Conflicts`,workspaceStagedChanges:`Staged Changes`,workspaceReview:`Review`,workspaceReviewFilter:`Review filter`,workspaceReviewFilterUnstaged:`Unstaged changes`,workspaceReviewFilterStaged:`Staged changes`,workspaceReviewFilterAllBranches:`All branch changes`,workspaceReviewFilterLastRun:`Last run changes`,workspaceRestoreFile:`Restore file`,workspaceStageFile:`Stage file`,workspaceUnstageFile:`Move back to unstaged`,workspaceOpenFileInNewTab:`Open file in new tab`,workspaceCannotOpenDeletedFile:`Deleted files cannot be opened directly.`,workspaceRestoreAll:`Restore all`,workspaceStageAll:`Stage all`,workspaceUnstageAll:`Unstage all`,workspaceRestoreConfirmTitle:`Discard changes?`,workspaceRestoreFileConfirm:`Restore "{path}" and discard its local changes? This cannot be undone.`,workspaceRestoreAllConfirm:`Restore all listed changes and delete untracked files? This cannot be undone.`,workspaceStageFailed:`Failed to stage changes.`,workspaceUnstageFailed:`Failed to unstage changes.`,workspaceRestoreFailed:`Failed to restore changes.`,workspaceCommitMessage:`Commit msg`,workspaceReviewPrompt:`Please review the current workspace changes and generate a concise summary, risk assessment, verification plan, and a suggested commit message.
|
|
7
|
+
|
|
8
|
+
Changed files:
|
|
9
|
+
{list}`,workspaceCommitMessagePrompt:`Please generate a concise Conventional Commit message for the current Git changes. Include a one-line subject and an optional short body if useful.
|
|
10
|
+
|
|
11
|
+
Changed files:
|
|
12
|
+
{list}`,unknown:`Unknown`,webPreview:`Web Preview`,artifactPreview:`Artifacts`,artifactPreviewFiles:`Show artifact files`,artifactPreviewEmpty:`No artifact files to preview.`,artifactPreviewLoadFailed:`Failed to load artifact preview.`,artifactPreviewUnsupported:`Preview unavailable for this file`,artifactPreviewUnsupportedDescription:`This file type cannot be displayed in the browser preview. Open it in a supported app or use the Reader when available.`,previewChecking:`Checking preview...`,previewErrorNotFoundTitle:`File not found`,previewErrorNotFoundDescription:`The file may have been deleted, moved, or renamed. Check the path and try again.`,previewErrorTooLargeTitle:`File is too large to preview`,previewErrorTooLargeDescription:`This file exceeds the browser preview size limit. Open it with another application.`,previewErrorPermissionTitle:`Unable to access this file`,previewErrorPermissionDescription:`The path is restricted or QuickForge does not have permission to read it.`,previewErrorServiceTitle:`Preview service unavailable`,previewErrorServiceDescription:`QuickForge could not prepare this preview. Check the local service and try again.`,previewErrorUnknownTitle:`Unable to preview this file`,previewErrorUnknownDescription:`An unexpected error occurred while preparing the preview. You can retry or inspect the details below.`,previewErrorDetails:`Error details`,previewErrorStatusCode:`Status code`,previewErrorCode:`Error code`,previewErrorFilePath:`File path`,previewErrorRawMessage:`Original error`,artifactPreviewViewSource:`View source`,artifactPreviewPin:`Pin artifact tools`,artifactPreviewUnpin:`Unpin artifact tools`,artifacts:`Artifacts`,previewArtifact:`Preview artifact`,previewUrl:`Preview URL`,previewUrlPlaceholder:`Enter URL`,openPreview:`Open`,refreshPreview:`Refresh preview`,openInBrowser:`Open in browser`,zoom:`Zoom`,zoomIn:`Zoom in`,zoomOut:`Zoom out`,resetZoom:`Reset zoom`,invalidPreviewUrl:`Please enter a valid http:// or https:// URL.`,noPreviewUrlTitle:`Start browsing`,noPreviewUrlDescription:`Enter a URL to open a page.`,workspaceStatusAdded:`Added`,workspaceStatusDeleted:`Deleted`,workspaceStatusRenamed:`Renamed`,workspaceStatusUntracked:`Untracked`,workspaceStatusConflict:`Conflict`,workspaceStatusModified:`Modified`,copyPath:`Copy path`,copyContent:`Copy content`,copyFileContent:`Copy file content`,copyDiffContent:`Copy diff content`,readerMoreActions:`More file actions`,readerOpen:`Open`,enableWordWrap:`Enable word wrap`,showFileNavigation:`Show file navigation`,hideFileNavigation:`Hide file navigation`,askAiAboutThis:`Ask AI about this`,readerFileMarkdownPrompt:"Please read the Markdown document `{path}` in the current workspace. Summarize its purpose, key sections, important instructions, outdated or risky parts, and suggest concise improvements.",readerFilePrompt:"Please inspect `{path}` in the current workspace and explain its role, important implementation details, and any risks or improvement opportunities.",readerDiffPrompt:"Please review the working-tree changes in `{path}`. Summarize what changed, point out possible bugs or regressions, and suggest focused verification steps.",openingReader:`Opening...`,markdownPreview:`Preview`,markdownSource:`Source`,viewMarkdownSource:`View source`,returnToMarkdownPreview:`Back to preview`,lanAccess:`LAN Access`,lanAccessDescription:`Allow trusted devices on the same LAN to access the full QuickForge app after entering a password.`,lanAccessRiskWarning:`High risk: LAN devices that pass this password can access your conversations, projects, and available tools. Enable only on trusted networks.`,lanAccessStatus:`LAN access status`,lanAccessEnabled:`Full LAN access`,lanAccessEnabledDescription:`Whether full access from LAN devices is currently enabled.`,lanAccessPassword:`Access password`,lanAccessPasswordStatusDescription:`Password status for LAN sign-in.`,lanAccessActiveDevices:`Signed-in devices ({count})`,lanAccessActiveDevicesDescription:`LAN devices that still have access. The same device may appear more than once when using different browsers.`,lanAccessBrowser:`Browser`,lanAccessUnknownDevice:`LAN device`,lanAccessUnknownAddress:`Unknown address`,lanAccessSignedInAt:`Signed in {time}`,lanAccessExpiresAt:`Expires {time}`,lanAccessNoActiveDevices:`No LAN devices are currently signed in.`,lanAccessRevokeDevice:`Sign out`,lanAccessRevokeDeviceConfirm:`Sign out {device}? This session will need the LAN password again.`,lanAccessDeviceRevoked:`The selected LAN session has been signed out.`,lanAccessUrls:`LAN URLs`,lanAccessUrlsDescription:`Open one of these addresses from another trusted device on this network.`,lanAccessAllowFull:`Allow LAN devices to access full QuickForge`,lanAccessAllowFullDescription:`Enable only on trusted networks; authenticated LAN devices can use the full app.`,lanAccessPasswordPlaceholder:`At least 8 characters`,lanAccessPasswordPlaceholderConfigured:`Leave empty to keep current password`,showPassword:`Show password`,hidePassword:`Hide password`,lanAccessSessionTtl:`Login validity`,lanAccessSessionTtlDescription:`How long a LAN device stays signed in after entering the password.`,lanAccessActions:`Actions`,lanAccessActionsDescription:`Save access settings or sign out all LAN devices.`,lanAccessRevokeAll:`Sign out all LAN devices`,lanAccessRevokeAllConfirm:`Sign out all unlocked LAN devices now?`,lanAccessEnableConfirm:`Enable full LAN access? Only continue on a trusted network.`,lanAccessPasswordRequired:`Set an access password before enabling LAN access.`,lanAccessPasswordTooShort:`The access password must be at least 8 characters.`,lanAccessSaved:`LAN access settings saved.`,lanAccessRevoked:`All LAN devices have been signed out.`,enabled:`Enabled`,disabled:`Disabled`,configured:`Configured`,notConfigured:`Not configured`,generatePassword:`Generate password`,hour:`hour`,hours:`hours`,days:`days`,toolApprovalWaiting:`Waiting for approval: {toolName}`,autoCompactApprovalWaiting:`Context reached {percent}% of the {threshold}% threshold. Compact now?`,autoCompactApprovalPreview:`QuickForge will summarize older history and continue with the summary plus the latest {keepRecentTurns} user turn(s). Full chat history remains visible.`,autoCompactFailed:`Automatic context compaction failed; continuing with the current history.`,contextCompactedTimelineLabel:`Earlier context is summarized for the model`,contextCompactedLabel:`Compressed context`,contextCompactedTooltip:`This chat is using a summarized context for model requests while keeping the full history visible.`,contextCompactedViewSummary:`View summary`,contextCompactedHideSummary:`Hide summary`,contextCompactedSummaryTitle:`Summary used by the model`,contextCompactedCopySummary:`Copy summary`,toolApprovalAccept:`Allow once`,toolApprovalReject:`Reject`,toolApprovalTimeout:`Timeout`,toolApprovalTruncated:`... (truncated)`,processed:`Processed`,processing:`Processing`,processExecuted:`Executed`,processExecuting:`Executing`,processGroupToolsCalled:`{count} tool calls`,processGroupCommandsRan:`{count} commands`,processGroupFilesEdited:`Edited {count} files`,processFailed:`Failed`,processAborted:`Aborted`,processDurationSeconds:`{seconds}s`,processDurationMinutesSeconds:`{minutes}m {seconds}s`,processThinking:`Thinking process`,processCommandsRan:`Ran {count} commands`,processFilesEdited:`Edited {count} files`,processToolsCalled:`Called {count} tools`,processToolsFailedCount:`{count} failed`,expandProcess:`Expand processing details`,collapseProcess:`Collapse processing details`,expandProcessTools:`Expand tool activity`,collapseProcessTools:`Collapse tool activity`,relativeMinuteShort:`{count}m`,relativeHourShort:`{count}h`,relativeDayShort:`{count}d`,relativeWeekShort:`{count}w`,relativeYearShort:`{count}y`},zh:{language:`语言`,displayLanguage:`界面语言`,languageDescription:`选择速构 QuickForge 的界面显示语言。切换后页面会刷新以应用到所有组件。`,simplifiedChinese:`简体中文`,english:`English`,apply:`应用`,noLanguageChange:`当前已经是所选语言。`,newChat:`新建对话`,startNewChat:`新对话`,newChatEmptyTitle:`今天想推进什么?`,chooseProject:`选择项目`,searchProjects:`搜索项目`,newProject:`添加项目`,createBlankProject:`添加项目`,useExistingFolder:`选择项目目录`,useNoProject:`无项目`,noMatchingProjects:`没有匹配的项目`,loadingChatWorkspace:`正在加载聊天工作区...`,loadingConversation:`正在加载对话`,loadingConversationPreparing:`正在准备历史消息与工具记录`,conversationLoadFailed:`对话加载失败`,localServiceUnavailableTitle:`QuickForge 本地服务不可用`,localServiceUnavailableDescription:`QuickForge 需要通过本地服务进行存储。请使用 npm run dev 或 quickforge 命令启动后刷新此页面。`,project:`项目`,projects:`项目`,loadingProject:`正在加载项目...`,addProject:`添加项目`,noProjects:`暂无项目。`,expandProject:`展开项目`,collapseProject:`折叠项目`,expandAllProjects:`展开所有项目`,collapseAllProjects:`折叠所有项目`,dragToReorder:`拖拽排序`,newProjectChat:`新建项目对话`,projectChat:`项目对话`,normalChat:`普通对话`,conversations:`对话`,turnNavigationLabel:`对话轮次导航`,turnNavigationUserMessage:`用户消息`,turnNavigationFinalAnswer:`Final Answer`,turnNavigationGenerating:`正在生成回答…`,turnNavigationNoAnswer:`暂无最终回答`,turnNavigationAttachmentOnly:`包含附件的消息`,turnNavigationJumpLabel:`跳转到第 {index} 轮:{preview}`,pinnedConversations:`置顶`,noConversations:`暂无对话`,filterSort:`筛选与排序`,sidebarView:`视图`,sidebarViewByProject:`按项目`,sidebarViewTimeline:`时间线`,sortBy:`排序方式`,sortByUpdatedAt:`更新时间`,sortByCreatedAt:`创建时间`,filter:`筛选`,selecting:`选择中...`,chooseFolder:`选择文件夹`,selectProjectDirectory:`选择项目目录`,selectProjectDirectoryDescription:`浏览本地文件夹或粘贴路径,然后选择一个文件夹作为项目。`,quickAccess:`快捷入口`,path:`路径`,go:`前往`,parentDirectory:`上级目录`,noFolders:`该目录下没有文件夹。`,selectThisFolder:`选择此文件夹`,folderPickerPathPlaceholder:`输入或粘贴文件夹路径`,filesystemRootsFailed:`加载文件系统入口失败。`,directoryLoadFailed:`加载目录失败。`,noSavedConversations:`暂无保存的对话。`,deleteProject:`删除项目`,deleteProjectConfirm:`确定要删除项目「{name}」吗?该项目的对话记录将保留。`,deleteSession:`删除会话`,deleteSessionConfirm:`确定要删除该对话吗?删除后不可恢复。`,deleteSessionFailed:`删除对话失败。`,archiveSession:`归档对话`,confirmArchive:`确认归档`,archivedConversations:`已归档对话`,archivedConversationsDescription:`已归档的对话会从侧边栏隐藏,你可以在这里恢复或永久删除。`,searchArchivedConversations:`搜索已归档对话`,noArchivedConversations:`暂无已归档对话。`,archivedAt:`归档时间`,lastModified:`最后更新`,restoreSession:`恢复`,restoreSessionFailed:`恢复对话失败。`,sessionRestored:`对话已恢复。`,sessionNotFound:`未找到该对话。`,deletePermanently:`删除`,deleteAll:`全部删除`,deleteArchivedSessionConfirm:`确定要永久删除「{title}」吗?此操作不可恢复。`,deleteAllArchivedSessionsConfirm:`确定要永久删除所有已归档对话吗?此操作不可恢复。`,archivedSessionDeleted:`已归档对话已删除。`,archivedSessionsDeleted:`已归档对话已删除。`,shareLinks:`分享链接`,shareLinksDescription:`统一管理此 QuickForge 实例的全部对话分享链接,包括有效期、停用、恢复和永久删除。`,cloudAccount:`云服务`,cloudAccountDescription:`配置 QuickForge Cloud 连接、云身份、额度、模型目录和已连接设备;无需账户也可继续使用本地功能。`,cloudServiceConnection:`连接`,cloudServiceEnabled:`启用云服务`,cloudServiceEnabledDescription:`允许此 QuickForge 实例连接 QuickForge Cloud,使用远程访问、云模型、账户额度和设备管理。`,cloudServiceDisabledDescription:`云服务已关闭。本地云身份会继续保留,但远程访问和云端功能均已暂停。`,cloudServiceEnabledSaved:`已启用 QuickForge Cloud。`,cloudServiceDisabledSaved:`已关闭 QuickForge Cloud,本地云身份已保留。`,cloudDisabledError:`QuickForge Cloud 已关闭,请先在云服务设置中启用。`,cloudRemoteAccess:`远程访问`,cloudRemoteAccessDescription:`QuickForge 托管独立的本地 Agent,将当前运行实例安全连接到 QuickForge Cloud。`,cloudRemoteServerUrl:`绑定服务`,cloudRemotePid:`Agent PID`,cloudRemoteAuthorization:`设备授权`,cloudRemoteOpenAuthorization:`打开授权页面`,cloudRemoteStatusLoading:`加载中`,cloudRemoteStatusDisabled:`已禁用`,cloudRemoteStatusUnavailable:`Agent 不可用`,cloudRemoteStatusStopped:`已停止`,cloudRemoteStatusStarting:`连接中`,cloudRemoteStatusAuthorizing:`等待授权`,cloudRemoteStatusRunning:`已连接`,cloudRemoteStatusConflict:`已被其他运行实例占用`,cloudRemoteStatusError:`异常`,cloudServiceType:`服务类型`,cloudUrl:`Cloud API 地址`,cloudUrlPlaceholder:`http://127.0.0.1:8082/`,cloudUrlInvalid:`无效的 URL`,cloudUrlInvalidProtocol:`仅支持 http/https`,cloudUrlHttpRestricted:`HTTP 仅限本机地址`,cloudUrlAdminPort:`8081 为管理后台端口`,cloudConfigSource:`来源`,cloudConfigSourceSaved:`已保存设置`,cloudConfigSourceEnv:`环境变量`,cloudConfigSourceDefault:`产品默认值`,cloudTestConnection:`测试连接`,cloudConnectionTestSucceeded:`QuickForge Cloud 健康检查和就绪检查均已通过。`,cloudConnectionSaved:`已保存 QuickForge Cloud 连接。`,cloudConnectionTestResult:`连接测试`,cloudHealth:`健康检查`,cloudReady:`就绪检查`,cloudConnectionOk:`正常`,cloudConnectionError:`异常`,cloudConnectionUnknown:`未知`,cloudConnectionFailed:`无法连接 QuickForge Cloud。`,cloudRequestFailed:`QuickForge Cloud 请求失败。`,cloudRequestFailedWithStatus:`QuickForge Cloud 请求失败(状态码 {status})。`,cloudLocalOnlyError:`QuickForge Cloud 仅可从本机或已认证的远程客户端访问。`,cloudConfigurationError:`QuickForge Cloud 配置无效,请检查 Cloud API 地址。`,cloudSessionServiceMismatch:`当前云会话属于其他服务,请先重建云身份再继续。`,cloudSessionExpired:`云会话已失效,请重新登录或开始体验。`,cloudDeviceFlowExpiredError:`登录设备码已过期,请重新开始账户登录。`,cloudDeviceFlowDeniedError:`账户授权已被拒绝。`,cloudSessionActiveGuidance:`当前存在云会话。请先退出当前设备,或阅读警告后使用“重建身份并切换”。`,cloudForceSwitch:`重建身份并切换`,cloudForceSwitchTitle:`重建云身份并切换服务?`,cloudForceSwitchDescription:`此操作会永久清除本地云会话并轮换设备身份,不会把 Refresh Token 发送给旧服务或新服务。现有游客额度无法恢复;重置成功后才会保存新的 Cloud API 地址。`,cloudForceSwitchConfirm:`重置并切换`,cloudForceSwitchSucceeded:`已重建云身份并切换 Cloud API 地址。准备好后可重新开始游客体验。`,cloudIdentityRebuiltUrlSaveFailed:`云身份已重建,但新的 Cloud API 地址保存失败。之前保存的地址仍然有效,请检查上方地址后重试保存。`,cloudSessionMismatchLabel:`需要重建身份`,cloudUnavailableDescription:`本地存在云会话,但当前无法连接 QuickForge Cloud。请检查服务后重试。`,cloudUsageLoadFailed:`加载云额度失败,请重试刷新额度。`,cloudModelsLoadFailed:`加载云模型目录失败,请重试刷新。`,cloudDevicesLoadFailed:`加载已连接设备失败,请重试刷新。`,cloudModels:`云模型目录`,cloudNoModels:`云服务未返回可用模型。`,cloudCapabilityTools:`工具`,cloudCapabilityVision:`视觉`,cloudCapabilityReasoning:`推理`,cloudCapabilityText:`文本`,cloudIdentityStatus:`云身份`,cloudNotConfiguredDescription:`此 QuickForge 实例尚未配置 QuickForge Cloud。`,cloudConnectedDescription:`云凭据仅由本机 QuickForge 服务持有,不会暴露给浏览器。`,cloudLocalOnlyDescription:`本地功能保持匿名可用;只有你主动开始体验时才会创建云游客。`,cloudFormalAccount:`正式账户`,cloudNotConnected:`未连接`,cloudRemainingQuota:`剩余额度`,cloudQuotaExpiresAt:`额度重置或到期时间`,cloudLoginOrRegister:`登录或注册`,cloudLoginOrRegisterDescription:`QuickForge 只打开云端验证页;邮箱和密码仅在该页面输入,不会进入 QuickForge。`,cloudDeviceFlowTitle:`在浏览器完成登录`,cloudDeviceFlowDescription:`打开云端验证页;若页面未自动填入,请输入以下设备码。`,cloudDeviceCode:`设备码`,cloudOpenVerificationPage:`打开验证页`,cloudDeviceFlowCountdown:`剩余 {seconds} 秒`,cloudDeviceFlowSlowDown:`云端要求降低轮询频率,QuickForge 将继续自动检查。`,cloudDeviceFlowSucceeded:`正式账户已连接。`,cloudDeviceFlowDenied:`账户授权已拒绝,原游客 Session 已保留。`,cloudDeviceFlowExpired:`登录设备码已过期,原游客 Session 已保留。`,cloudDeviceFlowNetwork:`暂时无法连接 QuickForge Cloud,将继续自动重试。`,cloudDeviceFlowCancelled:`已取消账户登录,原游客 Session 已保留。`,cloudDeviceCodeCopied:`设备码已复制。`,cloudAccountEmail:`邮箱`,cloudAccountPlan:`套餐`,cloudDevices:`已连接设备`,cloudCurrentDevice:`当前设备`,cloudUnnamedDevice:`未命名设备`,cloudRegisteredAt:`注册于`,cloudLastSeenAt:`最近活跃`,cloudDuplicateDevicesHint:`{count} 台设备同名(如“{name}”),疑似重复注册(重复登录会累积设备),可撤销不再需要的设备。`,cloudNoDevices:`云服务未返回已连接设备。`,cloudRevokeDevice:`撤销`,cloudRevokeDeviceConfirm:`撤销“{name}”的云服务访问权限?该设备的云会话将立即失效。`,cloudDeviceRevoked:`已撤销设备访问权限。`,cloudLogout:`退出当前设备`,cloudLogoutTitle:`退出当前设备?`,cloudLogoutDescription:`QuickForge 会先在云端撤销当前设备,再清除本地云会话。如果暂时无法连接云端,将保留本地凭据以便安全重试。`,cloudLogoutRowDescription:`不会影响本地项目、对话、自定义模型提供商或 API Key。再次开始将创建新的游客身份和额度。`,cloudLoggedOut:`当前设备已退出 QuickForge Cloud。`,cloudLoadFailed:`加载 QuickForge Cloud 状态失败。`,cloudNotAvailable:`暂无`,searchShareLinks:`按对话标题或链接 ID 搜索`,shareLinksCount:`{count} 个链接`,noShareLinks:`暂无分享链接。`,noMatchingShareLinks:`没有匹配的分享链接。`,shareLinksLoadFailed:`加载分享链接失败。`,shareStatusActive:`有效`,shareStatusDisabled:`已停用`,shareStatusExpired:`已过期`,sharePermissionRead:`只读`,sharePermissionOperate:`可操作`,sharePasswordProtected:`密码保护`,shareCreatedAt:`创建时间`,shareExpiresAt:`有效期至`,shareNeverExpires:`永久`,shareAccessCount:`访问 {count} 次`,shareLastAccessedAt:`最近访问`,shareRestoreExpiration:`恢复后的有效期`,shareUpdateExpiration:`新的有效期`,updateShareExpiration:`更新有效期`,editShare:`编辑`,manageShare:`更多`,editShareTitle:`编辑分享链接`,sharePermissionTitle:`权限`,sharePermissionReadHint:`只能查看这一个对话。`,sharePermissionOperateHint:`允许操作原对话,必须设置密码。`,sharePasswordTitle:`密码`,sharePasswordPlaceholderKeep:`留空保持现有密码`,sharePasswordPlaceholderNone:`留空则保持无密码`,sharePasswordEditHint:`留空保持现有密码;填写新密码后旧密码和已解锁状态立即失效。`,sharePasswordSetHint:`填写密码后开启保护,已有解锁状态会失效。`,sharePasswordRemovalSelected:`保存后将取消密码保护。`,removePassword:`取消密码`,keepCurrentExpiration:`保持当前有效期`,saveChanges:`保存修改`,shareUpdated:`已更新分享设置。`,operateRequiresPassword:`可操作分享必须设置非空密码。`,oneHour:`1 小时`,twentyFourHours:`24 小时`,sevenDays:`7 天`,copyShareLink:`复制分享链接`,openShareLink:`打开分享链接`,disableShare:`停用`,restoreShare:`恢复`,deleteShare:`永久删除`,disableShareConfirm:`停用“{title}”的分享链接?已有访问和实时连接会立即停止。`,deleteShareConfirm:`永久删除“{title}”的分享链接?此操作无法撤销。`,shareLinkCopied:`已复制分享链接。`,shareDisabled:`已停用分享链接。`,shareRestored:`已恢复分享链接。`,shareExpirationUpdated:`已更新分享链接有效期。`,shareDeleted:`已永久删除分享链接。`,untitledConversation:`未命名对话`,allProjects:`所有项目`,unknownProject:`未知项目`,conversationCount:`{count} 个对话`,confirm:`确认`,confirmDelete:`确认删除`,rename:`重命名`,renameSession:`重命名对话`,sessionName:`对话名称`,settings:`设置`,toggleSidebar:`切换侧边栏`,failedToSelectProjectDirectory:`选择项目目录失败。`,projectSwitchFailed:`切换到该对话绑定的项目失败,工作区工具未启动。`,copy:`复制`,copied:`已复制`,svgDisplayMode:`SVG 显示模式`,svgPreviewMode:`预览`,svgSourceMode:`源码`,svgEnlargePreview:`点击放大 SVG 预览`,copySvgSource:`复制 SVG 源码`,downloadSvg:`下载 SVG`,mermaidPreviewLabel:`Mermaid 图表预览`,mermaidEnlargePreview:`点击放大 Mermaid 图表`,copyMermaidSource:`复制 Mermaid 源码`,downloadMermaidSvg:`下载 Mermaid SVG`,mermaidRendering:`正在渲染 Mermaid 图表...`,mermaidRenderFailed:`无法渲染此 Mermaid 图表,已保留源码。`,rollback:`回滚`,retry:`重试`,reloadPage:`刷新页面`,fork:`分支`,forkConversation:`从此处分支新对话`,yoloEnabledTitle:`工作区授权已开启:本地工具可使用当前项目`,yoloDisabledTitle:`工作区授权已锁定:本地工具已阻止`,agentAccessMenuLabel:`Agent 权限模式`,agentAccessDefaultLabel:`默认权限`,agentAccessFullLabel:`完全访问权限`,agentAccessDefaultTitle:`默认权限:仅在当前代码仓库内工作,可能影响系统的操作需要确认。`,agentAccessFullTitle:`完全访问权限:等同开发者授权,工具可在既有工作区边界内自动执行。`,agentAccessModeSyncFailed:`同步 Agent 权限模式失败。`,planModeLabel:`计划`,planModeEnabledTitle:`计划模式已开启:下一条消息会按 /plan 发送。点击可移除。快捷键:Shift+Tab`,planModeDisabledTitle:`计划模式:下一条消息按 /plan 发送。快捷键:Shift+Tab`,composerPlaceholder:`描述你想做的事`,assistantWaitingThinking:`正在思考`,assistantWaitingOrganizing:`正在整理答案`,assistantWaitingContinuing:`内容较多,正在继续处理`,assistantWaitingAriaLabel:`AI 正在准备回复`,customCommandsHint:`自定义指令`,customCommandsEmptyHint:`还没有项目指令。`,customCommandsListDescription:`列出项目自定义指令`,customCommandsNewDescription:`创建项目自定义指令`,initCommandDescription:`为当前仓库生成或更新简洁的 AGENTS.md 贡献者指南。`,planCommandDescription:`先生成计划;本轮禁止编辑文件或运行命令。`,reviewCommandDescription:`提交前自检待提交代码;本轮禁止编辑文件。`,summaryCommandDescription:`基于当前对话创建总结后的新对话,减少上下文占用。`,compactCommandDescription:`在当前对话内压缩上下文,使用与自动压缩一致的滚动摘要。`,clearCommandDescription:`清除当前对话历史和上下文,不调用模型。`,helpCommandDescription:`显示所有可用命令及其用法。`,yoloBlockedReason:`本地工具 {name} 已被当前 Agent 权限模式阻止。请切换到完全访问权限,或在弹出审批时确认该工具调用。`,globalToolBlockedReason:`本地工具 {name} 已被阻止,因为这是未绑定项目的普通对话。请新建或打开项目对话后使用工作区工具。`,noActiveProjectToolBlockedReason:`本地工具 {name} 已被阻止,因为当前没有激活项目。请添加或选择项目后再使用工作区工具。`,generationAlreadyRunning:`生成仍在进行中。请停止生成或等待完成。`,generationStillRunning:`生成仍在进行中。请停止生成或等待完成后再回滚。`,noConversationTurnToRollback:`没有可回滚的对话轮次。`,rollbackConfirmTitle:`确认回滚?`,rollbackConfirm:`确定回滚到这条消息之前吗?该消息及其之后的对话记录会被移除,消息内容会恢复到输入框。`,sharedRollbackConfirmTitle:`确认回滚分享对话?`,sharedRollbackConfirm:`该操作会直接影响分享者本机中的原始对话。该消息及其之后的对话记录会被移除,消息内容会恢复到输入框。`,confirmRollback:`确认回滚`,rollingBack:`回滚中...`,rollbackFailed:`回滚失败。`,retryFailed:`重试失败。`,openCodeMessageHistoryActionUnavailable:`OpenCode 不支持按消息位置回滚、重试或分叉,这些操作在 OpenCode 对话中暂不可用。`,openCodeConfigMenuLabel:`OpenCode 配置`,openCodeConfigButtonLabel:`配置`,openCodeConfigDisabledWhileStreaming:`生成期间 OpenCode 配置不可用。`,openCodeConfigModesTitle:`模式`,openCodeConfigOptionsTitle:`选项`,openCodeModeMenuLabel:`OpenCode 模式`,openCodeModeDisabledWhileStreaming:`生成期间 OpenCode 模式不可用。`,openCodeUsageTokensTitle:`已用 {used} / {size} tokens`,openCodeUsageCostTitle:`费用:{amount} {currency}`,forkCurrentSession:`复制当前会话`,forkCurrentSessionTitle:`将当前 OpenCode 对话整体复制为新会话。`,openCodeForkUnavailable:`当前 OpenCode 对话没有可用的 ACP 会话,无法复制。`,openCodeForkFailed:`复制对话失败。`,copyFailed:`复制失败,请检查剪贴板权限。`,errorBoundaryTitle:`出错了`,errorBoundaryUnexpected:`发生了意外错误。`,errorBoundaryTryAgain:`重试`,execute:`执行`,addCustomModelFirst:`请先在设置里添加自定义模型,并确保填写了模型 ID 后保存。`,modelSetupRequired:`请先添加模型后再新建对话。`,modelSetupTitle:`还没有配置模型`,modelSetupDescription:`添加一个 OpenAI-Compatible 或 Anthropic 兼容模型后即可开始对话。QuickForge 只会使用你自己配置的模型。`,modelSetupSupports:`支持 LiteLLM、OpenRouter、DeepSeek、通义千问、智谱、Ollama,以及大多数 /v1/chat/completions 服务。`,modelSetupLocalStorage:`提供商、模型 ID 和 API Key 会由本机 QuickForge 本地服务保存。`,modelSetupAddModel:`添加模型`,modelSetupUseLiteLlmExample:`使用 LiteLLM 示例配置`,firstUseGuideTitle:`从安全工作流开始`,firstUseGuideDescription:`添加项目后,先让 QuickForge 理解项目;涉及代码修改时,建议先用 /plan 生成计划,再授权本地工具执行。`,firstUseGuideStepModel:`确认要使用的模型配置。`,firstUseGuideStepProject:`添加本地项目,让 AI 使用工作区上下文。`,firstUseGuideStepPlan:`先使用 /plan;该轮不会编辑文件或运行命令。`,firstUseGuideConfigureModel:`配置模型`,firstUseGuideAddProject:`添加项目`,firstUseGuideUsePrompt:`试用示例提示词`,firstUseGuideCopyPrompt:`复制 /plan 示例`,firstUseGuideDismiss:`我知道了`,firstUseGuideProjectPrompt:`/plan 阅读这个项目,说明项目结构、运行方式和主要风险。先不要修改文件。`,firstUseGuideGeneralPrompt:`/plan 先把这个需求拆成实现步骤和风险点。暂时不要修改文件。`,defaultOptions:`常规`,defaultOptionsDescription:`配置界面语言,以及新建对话和定时任务默认使用的模型、思考等级、工具展示和上下文管理。`,memory:`记忆`,memoryDescription:`让 QuickForge 跨对话和项目记住有用的偏好与习惯。`,globalMemory:`全局记忆`,globalMemoryDescription:`开启后,QuickForge 会使用已有记忆,并可从对话中主动记住对未来有帮助的长期偏好、习惯、背景、工作方式和目标。`,globalMemoryInfo:`记忆保存在本机,并由所有对话和项目共享。QuickForge 会避开临时任务细节、不确定推断和敏感凭据。关闭记忆后停止后续读取和写入,但保留已有文件。`,memoryFile:`记忆文件`,memoryFileDescription:`以可读的 Markdown 文件保存在本机 QuickForge 数据目录中。`,memoryCurrentSessionNote:`修改会在运行中对话发送下一条消息前加载。关闭后停止后续读取和写入,但保留已有文件。`,memoryEnabledSaved:`全局记忆已开启。`,memoryDisabledSaved:`全局记忆已关闭,已有记忆已保留。`,memoryContent:`记忆内容`,memoryContentDescription:`查看或编辑完整的自由 Markdown 文档,内容和格式会按原文保存。`,memoryContentDisabledDescription:`开启全局记忆后才能编辑和保存。关闭时仍可重新加载查看已有内容。`,memoryReload:`重新加载`,memorySave:`保存记忆`,memoryReloaded:`记忆已重新加载。`,memoryContentSaved:`全局记忆已保存。`,memoryContentEmpty:`全局用户记忆为空。`,defaultModel:`默认模型`,defaultModelDescription:`新建对话和定时任务默认使用的模型,可在具体场景中覆盖。`,defaultHarness:`默认 Harness`,defaultHarnessDescription:`用于新对话;当前空白对话会立即应用,已有对话保持不变。`,claudeCodeHarnessUnavailable:`Claude Code(尚未接入)`,defaultThinkingLevel:`默认思考等级`,defaultThinkingLevelDescription:`为支持 reasoning 的模型选择默认思考强度。`,toolDisplay:`Tool 显示模式`,toolDisplayModeDescription:`简洁模式显示摘要并默认收起详情;详细模式显示完整参数和 details,并默认展开 Tool 调用。`,toolDisplayCompact:`简洁`,toolDisplayDetailed:`详细`,showContextUsage:`显示上下文用量`,showContextUsageDescription:`在模型选择器旁显示上下文用量圆环及详情。`,fontSize:`字号`,fontSizeDescription:`调整界面和对话文字大小。`,fontSizeRangeDescription:`拖动时即时预览,松开后保存。`,appearance:`外观`,appearanceDescription:`自定义界面的主题和字号。`,theme:`主题`,themeDescription:`在浅色和深色之间切换,即时生效。`,lightTheme:`浅色`,darkTheme:`深色`,appearanceSaved:`外观已保存`,interfaceFontSize:`界面字号`,messageFontSize:`对话字号`,messageFontSizeNote:`应用到聊天消息里的主要正文。`,fontSizeSaved:`字号已保存`,toolDetailsHidden:`简洁模式已隐藏 Tool 详细信息。可在设置中将“Tool 显示模式”切换为“详细”查看完整参数。`,toolArgsSummary:`参数摘要`,saveDefaultOptions:`保存默认选项`,saving:`保存中...`,defaultOptionsSaved:`默认选项已保存`,networkConnection:`网络连接`,networkProxyMode:`代理模式`,networkProxyDirect:`直连`,networkProxySystem:`跟随系统`,networkProxyManual:`手动代理`,networkProxyPac:`PAC 地址`,networkProxyDescription:`控制 QuickForge 自身受支持的外部 HTTP 请求,本地地址始终直连。“跟随系统”会读取操作系统代理配置,并在系统支持时处理 PAC/WPAD。自定义 PAC 地址仅 Desktop 运行环境支持。`,networkProxyAddress:`代理地址`,networkProxyAddressDescription:`填写包含端口的 HTTP 或 HTTPS 代理地址。不支持路径、查询参数、片段和代理账号密码。`,networkProxyAddressRequired:`请先填写代理地址。`,networkProxyAddressInvalid:`请输入有效的 HTTP 或 HTTPS 代理地址。`,networkProxyAddressProtocolError:`仅支持 HTTP 和 HTTPS 代理地址。`,networkProxyAddressPortError:`代理地址必须包含主机和端口。`,networkProxyAddressCredentialsError:`代理地址暂不支持账号密码。`,networkProxyAddressPathError:`代理地址不能包含路径、查询参数或片段。`,networkProxyPacUrl:`PAC 地址`,networkProxyPacUrlDescription:`填写 PAC 脚本的 HTTP 或 HTTPS 地址。支持路径和查询参数,不支持账号密码和片段。`,networkProxyPacUrlRequired:`请先填写 PAC 地址。`,networkProxyPacUrlInvalid:`请输入有效的 HTTP 或 HTTPS PAC 地址。`,networkProxyPacUrlProtocolError:`PAC 地址仅支持 HTTP 和 HTTPS。`,networkProxyPacUrlHostError:`PAC 地址必须包含主机。`,networkProxyPacUrlCredentialsError:`PAC 地址不支持账号密码。`,networkProxyPacUrlFragmentError:`PAC 地址不能包含片段。`,networkProxyPacUnsupported:`自定义 PAC 地址仅 Desktop 运行环境支持。`,networkProxySave:`保存代理`,networkProxyRefresh:`重新读取系统代理`,networkProxyRefreshDescription:`重新读取操作系统当前代理配置,并关闭已有网络连接。`,networkProxyStatus:`来源:{source};运行环境:{runtime}。`,networkProxyUnsupported:`当前运行环境不支持读取操作系统代理。`,networkProxyLoadFailed:`无法读取当前代理配置,代理控件已禁用。`,networkProxySaved:`网络代理设置已保存`,networkProxyRefreshed:`已重新读取系统代理`,contextManagement:`上下文管理`,contextUsageTitle:`上下文用量`,contextUsageAriaLabel:`上下文已使用 {percent}%,查看详情`,contextUsageTotal:`{used} / {limit} tokens`,contextUsageInputLabel:`输入 / 上下文`,contextUsageReservedOutputLabel:`预留输出`,contextUsageSystemPromptLabel:`系统提示词`,contextUsageToolsSchemaLabel:`工具定义`,contextUsageMessagesLabel:`消息`,contextUsageSourceServerShort:`服务端计算`,contextUsageSourceLocalShort:`本地估算`,contextUsageScopeCompactedShort:`压缩后模型上下文`,contextUsageScopeFullShort:`完整模型上下文`,contextUsageUsed:`上下文已使用:{percent}%({used} / {limit} tokens)`,contextUsageInput:`输入/上下文:{tokens}({source})`,contextUsageSourceProvider:`提供商上下文`,contextUsageSourceMixed:`提供商/本地混合上下文`,contextUsageSourceEstimated:`本地估算上下文`,contextUsageLocalEstimate:`本地估算:{tokens}`,contextUsageSystemPrompt:` 系统提示词:{tokens}`,contextUsageToolsSchema:` 工具定义:{tokens}`,contextUsageMessages:` 消息:{tokens}`,contextUsageProviderBaseline:` 提供商用量基线:{tokens}`,contextUsageTrailingMessages:` 用量基线后的消息:{tokens}`,contextUsageReservedOutput:`预留输出:{tokens}`,contextUsageServerCalculated:`数据来源:服务端通过 pi-agent-core/pi-ai 计算`,contextUsageScopeCompacted:`统计范围:模型压缩后的上下文,不是界面中可见的完整聊天历史`,contextUsageScopeFull:`统计范围:完整模型上下文`,contextUsageEffectiveMessages:`消息:{effective} 条有效 / {visible} 条可见`,contextUsageProviderTokens:`提供商上下文 Token:{tokens}`,autoCompactEnabled:`自动压缩上下文`,autoCompactRequireConfirmation:`自动压缩前先询问确认`,autoCompactRequireConfirmationDescription:`在 QuickForge 总结较早历史前先请求确认。`,autoCompactTriggerNote:`系统会在每次请求模型前检查。测试时可降低阈值,或调小模型 Context Window。`,autoCompactThresholdPercent:`上下文达到多少百分比时压缩`,autoCompactThresholdDescription:`触发压缩的模型上下文窗口占比。`,autoCompactKeepRecentTurns:`保留最近用户回合数`,autoCompactKeepRecentTurnsDescription:`较早上下文总结后,最近回合仍保留完整内容。`,autoCompactDescription:`当预计下一次请求达到模型上下文窗口的指定比例时,QuickForge 会总结较早历史并继续当前任务。该过程会额外消耗一次模型调用。`,autoCompactHistoryPreserved:`完整聊天历史仍会保留在界面中;只有发送给模型的上下文会被压缩。`,autoArchiveEnabled:`自动归档历史对话`,autoArchiveTriggerNote:`最后更新超过 30 天的对话会移入“已归档对话”。`,autoArchiveDescription:`归档不会删除对话。关闭后只停止后续自动归档,已有归档仍可查看和恢复。`,autoArchiveSaved:`自动归档设置已保存`,thinkingLevel:`思考等级`,thinkingOff:`关`,thinkingLow:`低`,thinkingMedium:`中`,thinkingHigh:`高`,thinkingXHigh:`超高`,currentConfiguration:`当前配置`,thinkingSupported:`支持思考`,thinkingNotSupported:`该模型不支持思考等级。`,thinkingRequiresReasoningModel:`思考等级需要推理/思考模型。`,customModels:`自定义模型`,customModelsTitle:`自定义模型`,customModelsDescription:`只使用你配置的自定义 OpenAI-Compatible 模型。`,addModel:`添加模型`,editModel:`编辑模型`,delete:`删除`,editCustomModel:`编辑自定义模型`,addCustomModel:`添加自定义模型`,providerName:`提供商名称`,providerNamePlaceholder:`例如:LiteLLM`,protocolType:`协议类型`,protocolHelp:`LiteLLM、OpenRouter、大多数 /v1/chat/completions 服务请选择 OpenAI Compatible;直连 Anthropic API 才选 Anthropic Messages。`,apiKey:`API Key`,apiKeyPlaceholder:`没有可以留空`,showApiKey:`查看 API Key`,hideApiKey:`隐藏 API Key`,customHeaders:`自定义 Headers JSON`,customHeadersPlaceholder:`{
|
|
13
|
+
"X-Custom-Header": "value"
|
|
14
|
+
}`,customHeadersHelp:`可选的提供商级 HTTP Headers。必须是值为字符串的 JSON 对象,会随模型配置保存在本地。`,invalidHeadersJson:`自定义 Headers 必须是有效 JSON 对象,并且键和值都必须是字符串。`,modelId:`模型 ID`,modelIdPlaceholder:`例如:anthropic/claude-sonnet-4`,contextWindow:`Context Window`,maxTokens:`Max Tokens`,reasoningModel:`推理/思考模型(DeepSeek V4、Qwen 等)`,imageInputModel:`图片输入 / 视觉模型`,imageInputModelHelp:`仅在模型文档确认支持图片输入时开启。关闭后,请求发送前会省略附件图片,避免非视觉模型报错。`,showModelInSelectors:`在模型选择中显示`,showModelInSelectorsHelp:`关闭后会保留模型配置,但不再出现在模型选择列表中。`,providerProtocol:`协议`,model:`模型`,reasoning:`推理`,noModelAdded:`未添加模型`,modelsCount:`{count} 个模型`,modelIndex:`模型 #{index}`,modelsList:`模型列表`,atLeastOneModel:`至少需要一个模型。`,duplicateModelId:`模型 ID 不能重复。`,cancel:`取消`,save:`保存`,yes:`是`,no:`否`,loading:`加载中...`,noCustomModels:`还没有自定义模型,请点击"添加模型"。`,fillProviderBaseUrlModel:`请填写提供商名称和 Base URL。`,saveCustomModelFailed:`保存自定义模型失败。`,confirmDeleteProvider:`确定删除 {name} 吗?`,deleteFailed:`删除失败。`,selectCustomModel:`选择自定义模型`,close:`关闭`,back:`返回`,more:`更多`,searchModels:`搜索模型...`,searchSettings:`搜索设置...`,noSettingsResults:`没有匹配的设置`,noMatchingCustomModels:`没有匹配的自定义模型`,presets:`快速模板`,presetOpenai:`OpenAI`,presetDeepseek:`DeepSeek`,presetGlm:`智谱 GLM`,presetOllama:`本地 Ollama`,presetLitellm:`LiteLLM 代理`,presetCustom:`自定义`,providerAdvanced:`高级选项`,expandModel:`调整上下文窗口、最大输出、推理、图片输入`,addHeader:`添加请求头`,headerName:`请求头名称`,headerValue:`值`,removeHeader:`移除请求头`,testConnection:`测试连接`,testingConnection:`测试中…`,connectionOk:`连接成功`,connectionFailed:`连接失败`,testRequiresFields:`请填写 Base URL 和至少一个模型 ID。`,readFile:`读取文件`,manageGlobalMemory:`管理记忆`,searchFiles:`搜索文件`,writeFile:`写入文件`,editFile:`编辑文件`,runCommand:`运行命令`,presentFiles:`展示文件`,generateImage:`生成图片`,generatingImage:`正在生成图片…`,generatedImageAlt:`生成的图片 {index}`,openGeneratedImage:`打开生成图片`,downloadGeneratedImage:`下载生成图片`,executeInTerminal:`在终端中执行`,confirmExecuteCommandTitle:`在终端中执行命令?`,confirmExecuteMultipleCommands:`即将在本地终端中执行多行命令,是否继续?`,confirmExecuteDangerousCommand:`该命令可能修改系统、发布包、推送代码或执行远程脚本,是否继续?`,terminalCommandExecuteFailed:`在终端中执行命令失败。`,runSubagent:`运行 subagent`,subagentGeneral:`General`,subagentExplore:`Explore`,subagentRunning:`{name} 运行中`,subagentCompleted:`{name} 已完成`,subagentFailed:`{name} 失败`,subagentTask:`任务`,subagentContext:`上下文`,subagentExpectedOutput:`期望输出`,subagentResult:`结果`,subagentToolCalls:`工具调用`,subagentToolApprovalWaiting:`{source} 请求审批:{toolName}`,toolApprovalSourceSubagent:`来源:{source} subagent`,activateSkill:`激活技能`,readSkillResource:`读取技能资源`,yoloModeSyncFailed:`同步 Agent 权限模式失败,已恢复为之前的状态。`,toolApprovalFailed:`提交工具审批失败,请重试。`,toolApprovalSubmitting:`提交中...`,toolApprovalRetry:`重试提交`,toolApprovalNeedsConfirmation:`需要确认`,toolApprovalRiskCommand:`此操作将在当前工作区执行 Shell 命令。`,toolApprovalRiskFileChange:`此操作会修改当前工作区中的文件内容。`,toolApprovalRiskExternal:`此操作可能向外部服务发送数据,并修改远程内容。`,toolApprovalRiskGeneric:`此工具可能修改本地或外部状态,请确认参数后继续。`,toolApprovalViewDetails:`查看完整参数`,toolApprovalHideDetails:`收起完整参数`,toolApprovalSource:`来源`,toolApprovalServer:`服务`,toolApprovalPlugin:`插件`,toolApprovalTool:`工具`,toolApprovalPath:`路径`,toolApprovalCommand:`命令`,toolApprovalDisabled:`当前无法在此处处理该审批。`,autoCompactApprovalStatus:`上下文接近上限`,autoCompactApprovalTitle:`压缩较早的对话内容`,autoCompactApprovalRisk:`QuickForge 会总结较早历史并保留最近 {keepRecentTurns} 个用户回合,不会修改工作区文件。`,autoCompactApprovalAccept:`现在压缩`,autoCompactApprovalReject:`暂不压缩`,autoCompactApprovalUnavailable:`当前视图无法处理上下文压缩审批。`,sharedApprovalReadOnly:`请在分享者原始对话处理。`,terminateCommand:`终止`,terminateCommandTitle:`终止这个正在运行的命令`,commandTerminateRequested:`正在终止...`,running:`运行中`,done:`完成`,error:`错误`,taskCompleted:`对话任务完成`,taskError:`对话任务出错`,systemNotifications:`系统通知`,systemNotificationsDescription:`QuickForge 在后台运行时,对话或定时任务结束后显示浏览器或 Android 系统通知。`,systemNotificationsPermissionGranted:`当前设备已授权。应用处于前台时仍只显示页面内提示。`,systemNotificationsPermissionPrompt:`当前设备尚未请求通知权限。`,systemNotificationsPermissionDenied:`当前设备已拒绝通知权限。`,systemNotificationsUnsupported:`当前环境不支持系统通知。`,systemNotificationsDeniedHelp:`通知权限已被拒绝,请在浏览器网站设置或 Android 应用设置中允许后重试。`,systemNotificationsEnabled:`已在当前设备启用系统通知。`,systemNotificationsDisabled:`已在当前设备关闭系统通知。`,systemNotificationsTest:`发送测试`,systemNotificationTestTitle:`QuickForge 通知测试`,systemNotificationTestFailed:`无法显示测试通知,请检查系统权限后重试。`,systemNotificationOpenDetails:`点击打开 QuickForge 查看详情。`,called:`已调用`,input:`输入`,output:`输出`,details:`详情`,scheduledTasks:`定时任务`,scheduledTasksDescription:`任务保存在本地后台服务中,并按 AI 解析出的 cron 表达式执行。`,createTask:`创建任务`,editTask:`编辑`,cancelEditTask:`取消编辑`,saveTask:`保存任务`,taskScheduleDescriptionLabel:`定时描述`,taskScheduleDescriptionPlaceholder:`例如:每天早上 9 点,把这段内容发给 AI:帮我生成销售日报。`,quickAiParseTask:`AI 会把这段描述解析为 cron 表达式,系统只保存并按 cron 执行。`,taskTitleLabel:`任务名称`,taskTitlePlaceholder:`例如:每日工作总结`,promptContentLabel:`AI 将发送的内容`,promptContentPlaceholder:`填写到点后原样发送给 AI 的内容。`,taskEnabledSwitch:`启用这个任务`,taskInstructionPlaceholder:`例如:每天早上 9 点帮我生成销售日报`,aiParseTask:`AI 解析任务`,confirmCreate:`确认创建`,taskList:`任务列表`,noScheduledTasks:`还没有定时任务。先输入一句自然语言指令创建一个。`,taskEnabled:`启用中`,taskRunning:`执行中`,taskPaused:`已暂停`,taskFinished:`已完成`,taskFailed:`执行失败`,executeNow:`立即执行`,enable:`启用`,pauseTask:`暂停`,deleteTask:`删除`,recentExecutions:`最近执行记录`,executionSuccess:`成功`,executionRunning:`执行中`,nextExecution:`下一次:`,lastExecution:`上次:`,noModelAvailable:`暂无可用模型`,noProjectBound:`不绑定项目`,aiParsed:`AI 已解析,请确认`,taskName:`任务名称:`,executionRule:`执行规则:`,nextExecutionTime:`下一次执行:`,taskProject:`项目:`,taskThinkingLevel:`思考:`,aiInstruction:`AI 指令:`,taskModel:`模型`,taskThinking:`思考`,taskProjectLabel:`项目`,taskExecutionMode:`执行模式`,taskExecutionModeSerial:`串行`,taskExecutionModeParallel:`并行`,taskExecutionModeHelp:`该设置只控制同一个任务是否允许重叠执行;不同定时任务之间仍可并行执行。`,tasksCount:`共 {total} 个任务,{enabled} 个启用中`,confirmDeleteTask:`确定要删除这个定时任务吗?删除后不可恢复。`,waitingForResult:`等待结果`,autoRun:`自动执行`,manualRun:`手动测试`,runInputContent:`发送给 AI 的内容`,runAiResult:`AI 结果`,runDuration:`耗时:`,taskListTab:`任务列表`,executionHistoryTab:`执行历史`,agentsTab:`智能体`,agentsDescription:`创建可复用的智能体配置,用于定时任务和 run_subagent 委派。`,createAgent:`创建智能体`,editAgent:`编辑智能体`,builtinAgent:`内置`,builtinAgentReadonly:`内置智能体在当前版本中只读。`,builtinAgentModelSettings:`模型与思考设置`,builtinAgentModelOnly:`该内置智能体由系统管理,仅允许修改使用的模型和思考等级。`,readonlyAgentDescription:`该智能体来自只读来源,无法在此编辑。`,enabledAsSubagent:`允许作为 sub agent`,enableAsSubagent:`启用作为 sub agent`,disableAsSubagent:`禁用作为 sub agent`,noDescription:`暂无描述。`,maxRuntimeMs:`最大运行时间:`,maxToolCalls:`最大工具调用:`,defaultAgent:`默认智能体`,executionAgent:`执行智能体:`,agentName:`智能体名称`,agentLabel:`显示名称`,agentLabelPlaceholder:`例如:代码审查智能体`,agentDescription:`描述`,agentSystemPrompt:`系统提示词`,agentModelMode:`模型模式`,agentModelInherit:`继承主模型`,agentModelFixed:`使用固定模型`,agentFixedModel:`固定模型`,agentThinkingLevel:`思考等级`,agentThinkingInherit:`继承调用方设置`,agentThinkingDescription:`运行时模型不支持推理时,将自动降级为关闭。`,agentThinkingUnsupported:`所选固定模型不支持推理,思考等级将关闭。`,allowedTools:`可用工具`,agentSourcePath:`来源路径`,highRiskTool:`高风险`,confirmDeleteAgent:`确定删除这个自定义智能体吗?使用它的定时任务将回退到默认智能体。`,aiFillAgent:`AI 填充`,aiFillAgentDescription:`描述你想创建的智能体,AI 只会填充智能体名称、显示名称、描述和系统提示词。`,aiFillAgentPlaceholder:`例如:生成一个只读代码审查智能体,重点检查架构、潜在 bug 和测试覆盖。`,aiFillAgentLoading:`生成中...`,aiFillAgentNoModel:`请先配置默认模型。`,aiFillAgentFailed:`AI 填充失败,请检查模型配置和 API Key 后重试。`,aiFillAgentInputRequired:`请描述你想创建的智能体。`,taskContent:`任务内容`,viewDetails:`查看详情`,moreActions:`更多操作`,historyFilters:`筛选条件`,allTasks:`全部任务`,allStatuses:`全部状态`,allTriggers:`全部触发方式`,triggerType:`触发方式`,keyword:`关键词`,keywordPlaceholder:`搜索输入、结果或错误`,startTime:`开始时间`,endTime:`结束时间`,query:`查询`,reset:`重置`,previousPage:`上一页`,nextPage:`下一页`,pageSize:`每页 {size} 条`,paginationSummary:`第 {page} / {pages} 页,共 {total} 条`,noExecutionHistory:`暂无执行历史。`,viewConversation:`查看对话`,createdAt:`创建时间`,status:`状态`,search:`搜索`,noMatchingOptions:`没有匹配的选项`,searchDialog:`搜索对话记录...`,noSearchResults:`没有找到相关对话`,searchHint:`输入关键词搜索已加载的对话记录`,scheduledTasksLabel:`定时任务`,skills:`技能`,mcp:`MCP`,mcpServers:`MCP 服务`,plugins:`插件`,pluginMentionHeader:`插件`,composerAddMenu:`添加`,composerAddAttachment:`附件`,composerAddPlugins:`插件`,composerAddBack:`返回`,pluginDocumentsName:`文档`,pluginDocumentsDescription:`创建和编辑文档产物`,pluginSpreadsheetsName:`表格`,pluginSpreadsheetsDescription:`创建、分析和整理表格文件`,pluginPresentationsName:`演示文稿`,pluginPresentationsDescription:`创建和编辑演示文稿`,pluginsDescription:`管理本地 QuickForge 插件。当前首版支持通过 manifest 声明并贡献 Agent 工具的插件。`,pluginsReload:`重新加载插件`,loadingPlugins:`正在加载插件...`,noPlugins:`未发现插件`,noPluginsDescription:`将包含 plugin.json 的插件目录放到以下任一搜索路径,然后重新加载。`,pluginsCount:`共 {total} 个插件,{enabled} 个已启用`,pluginToolsCount:`{count} 个工具`,pluginPermissionsCount:`{count} 个权限`,pluginDetails:`插件详情`,pluginVersion:`版本`,pluginStatusLoaded:`已加载`,pluginStatusDisabled:`已停用`,pluginStatusError:`错误`,pluginTools:`工具`,pluginPermissions:`声明权限`,pluginNoTools:`未声明工具。`,pluginNoPermissions:`未声明权限。`,pluginTrustedNotice:`首版插件属于本地可信 Node.js 代码;权限目前用于展示和后续强校验。`,pluginDiscoveryErrors:`插件发现错误`,enablePlugin:`启用`,disablePlugin:`禁用`,pluginsLoadFailed:`加载插件失败。`,pluginsSaveFailed:`更新插件失败。`,manageMcpServers:`管理 MCP 服务`,mcpNoServersDescription:`还没有配置 MCP 服务。点击「添加服务」,或在右侧粘贴 mcpServers JSON 配置。`,mcpConfiguredServers:`已配置服务`,mcpAddServer:`添加服务`,mcpEditServer:`编辑服务`,mcpServerName:`服务名称`,mcpCommand:`命令`,mcpTransport:`传输方式`,mcpUrl:`URL`,mcpArgs:`参数,每行一个`,mcpCwd:`工作目录`,mcpEnv:`环境变量,每行 KEY=value`,mcpToolsCount:`{count} 个工具`,mcpLoadFailed:`加载 MCP 服务失败。`,mcpSaveFailed:`保存 MCP 服务失败。`,mcpDeleteFailed:`删除 MCP 服务失败。`,mcpReconnectFailed:`重新连接 MCP 服务失败。`,mcpDeleteConfirm:`确定删除 MCP 服务「{name}」吗?`,mcpImportConfig:`导入 MCP JSON`,mcpImportConfigDescription:"直接粘贴 mcpServers 格式的 MCP JSON 配置。QuickForge 支持 stdio、HTTP 和 SSE 传输;远程服务可使用 headers,并支持通过 ${...} 从后端进程环境变量读取。",mcpUseExample:`使用示例`,mcpImportUpdate:`导入 / 更新`,mcpReplaceAll:`替换全部`,mcpReplaceConfirm:`这会删除当前未包含在 JSON 中的 MCP 服务,确定继续吗?`,mcpInvalidJson:`MCP 配置必须是合法 JSON。`,mcpInvalidConfigJson:`MCP 配置必须包含 mcpServers 对象。`,mcpEmptyConfigJson:`mcpServers 不能为空。`,mcpInvalidServerName:`MCP 服务名称无效:{name}。请只使用小写字母、数字和连字符。`,mcpInvalidServerConfig:`MCP 服务「{name}」必须是对象。`,mcpInvalidTransport:`MCP 服务「{name}」的传输方式必须是 stdio、http 或 sse。`,mcpMissingCommand:`MCP 服务「{name}」使用 stdio 传输时必须提供 command。`,mcpMissingUrl:`MCP 服务「{name}」使用 HTTP/SSE 传输时必须提供 url。`,mcpArgsMustBeArray:`MCP 服务「{name}」的 args 必须是数组。`,mcpEnvMustBeObject:`MCP 服务「{name}」的 env 必须是对象。`,mcpHeadersMustBeObject:`MCP 服务「{name}」的 headers 必须是对象。`,mcpHeaders:`Headers,每行 KEY=value`,mcpReconnectServer:`重连`,mcpMoreTools:`+{count}`,mcpNamePlaceholder:`例如 my-server`,mcpUrlPlaceholder:`https://example.com/mcp`,mcpCommandPlaceholder:`例如 npx`,mcpTabServer:`服务`,mcpTabJson:`JSON`,optional:`可选`,globalSkills:`全局技能`,projectSkills:`项目技能`,help:`帮助`,projectCommands:`项目命令`,projectCommandsDescription:`为当前项目配置额外的 Markdown slash command 目录。QuickForge 还会读取用户级目录 ~/.quickforge/commands/(所有项目共享),然后依次读取项目目录 .claude/commands、.opencode/commands、.ai/commands 及此处的配置目录;同名 command 以后面的目录覆盖前面的目录。`,projectCommandsProjectDescription:`选择要配置命令目录的项目。`,selectProjectForCommands:`请先选择或添加一个项目,再配置项目命令。`,commandDirectory:`命令目录`,commandDirectories:`命令目录`,commandDirectoriesDescription:`一行添加一个目录。相对路径会基于所选项目根目录解析。`,commandDirectoryPlaceholder:`.claude/commands
|
|
15
|
+
.opencode/commands
|
|
16
|
+
D:\\shared\\ai-commands`,commandDirectoryHelp:`一行一个目录。支持相对路径和绝对路径。相对路径会基于当前项目根目录解析。留空则只使用内置兼容命令目录。`,commandDirectoryExamples:`示例`,commandDirectoryExamplesDescription:`常见兼容目录仍会自动发现。`,projectCommandsSaved:`项目命令设置已保存。`,loadedCommands:`已加载命令({count})`,loadedCommandsDescription:`从用户级、兼容目录和此项目配置目录中发现的命令。`,noCommandsLoaded:`暂未加载到任何命令。请在上方添加目录或新建命令后重试。`,openCommandDir:`打开命令目录`,createCommand:`新建命令`,projectCommandsActions:`操作`,projectCommandsActionsDescription:`保存配置目录后会重新加载已发现的命令。`,newCommandPrompt:`请输入命令名(小写字母、数字、连字符):`,commandCreated:`命令已创建:{name}`,commandAlreadyExists:`命令已存在:{name}`,invalidCommandName:`命令名无效,请使用小写字母、数字和连字符。`,manageSkills:`管理技能`,manageGlobalSkills:`管理全局技能`,manageProjectSkills:`管理项目技能`,openFolder:`打开文件夹`,fileManager:`资源管理器`,openWorkspace:`打开工作区`,chooseWorkspaceOpenTarget:`选择工作区打开方式`,openInExplorer:`在资源管理器打开`,openInExplorerFailed:`打开项目目录失败。`,openInVSCode:`在 VS Code 中打开`,openInVSCodeFailed:`在 VS Code 中打开项目失败,请确认已安装 VS Code 命令行工具。`,openInIDEA:`在 IntelliJ IDEA 中打开`,openInIDEAFailed:`在 IntelliJ IDEA 中打开项目失败,请确认已安装 IntelliJ IDEA 或 idea 命令行工具。`,moreOptions:`更多选项`,gitBranchMenu:`Git 分支菜单`,searchBranches:`搜索分支`,uncommittedChanges:`未提交的更改:`,filesCount:`{count} 个文件`,noBranchesFound:`没有匹配的分支`,currentBranch:`当前`,createBranchTitle:`创建并检出新分支`,createBranchDescription:`输入新分支名称,QuickForge 会从当前 HEAD 创建并检出该分支。`,createBranchPlaceholder:`feature/my-branch`,createAndCheckoutBranch:`创建并检出`,createAndCheckoutBranchEllipsis:`创建并检出新分支...`,gitGraph:`Git 图谱`,gitBranchesFailed:`加载分支失败。`,gitCheckoutFailed:`切换分支失败。`,gitBranchSwitched:`已切换分支`,gitBranchCreated:`已创建分支`,gitToolsTitle:`Git 工具`,togglePinnedSummary:`切换置顶摘要`,environmentInfo:`环境信息`,gitToolsCollapse:`收起 Git 工具`,gitToolsChanges:`更改`,gitToolsCommitOrPush:`提交或推送`,gitCommitMessagePlaceholder:`提交信息`,gitGenerateCommitMessage:`生成提交信息`,gitGenerateCommitMessageFailed:`生成提交信息失败。`,gitIncludeUnstagedChanges:`包含全部未暂存更改`,gitIncludeUnstagedWarning:`所有修改、未跟踪和删除的文件都会加入本次提交。`,gitCommitFilesSummary:`将提交 {selected}/{total} 个文件`,gitFileNotIncluded:`不提交`,gitCommitMessageRequired:`请先填写或生成提交信息。`,gitNoStagedChanges:`没有可提交的已暂存更改。`,gitDetachedHeadBlocked:`请先切换到一个分支,再提交或推送。`,gitCommitSucceededPushFailed:`本地提交成功,但推送失败。`,gitRetryPush:`重试推送`,gitRefreshingStatus:`正在刷新 Git 状态…`,gitStatusRefreshFailed:`刷新 Git 状态失败。`,gitCommitOnly:`提交`,gitCommitAndPush:`提交并推送`,gitPushOnly:`推送`,gitCommitNoProject:`当前没有选择项目。`,gitCommitNoModel:`请先配置默认模型。`,gitCommitConflictsBlocked:`请先解决冲突后再提交。`,gitOperationFailed:`Git 操作失败。`,gitOperationCompleted:`Git 操作已完成`,gitGraphFailed:`加载 Git 图谱失败。`,noGitCommits:`没有找到提交记录。`,refresh:`刷新`,graphColumn:`图`,description:`描述`,date:`日期`,author:`作者`,commit:`提交`,pinSession:`置顶对话`,unpinSession:`取消置顶`,shareSession:`分享对话`,selectProjectForSkills:`请先选择或添加一个项目,再管理技能。`,skillsDescription:`选择项目「{project}」启用的 Agent Skills。QuickForge 只在提示词中披露名称/描述;完整 SKILL.md 指令会在需要时通过 activate_skill 按需加载。`,globalSkillsDescription:`选择 QuickForge 全局启用的 Agent Skills。新对话只注入技能目录,完整 SKILL.md 指令会在需要时通过 activate_skill 按需加载。`,projectSkillsDescription:`选择项目「{project}」启用的 Agent Skills。同名项目技能会覆盖全局技能;新项目对话只注入技能目录,完整指令按需加载。`,searchSkills:`搜索技能...`,availableSkills:`可用技能`,selectedSkillsCount:`已选择 {count} 个`,noMatchingSkills:`没有匹配的技能`,skillSearchPaths:`搜索路径`,failedToLoadSkills:`加载技能失败。`,failedToSaveSkills:`保存技能失败。`,readSkill:`阅读技能`,readSkillContent:`阅读技能内容`,backToSkillList:`返回技能列表`,failedToReadSkill:`读取技能内容失败。`,noSkillContent:`该技能没有可阅读的内容。`,requestFailed:`请求失败`,backupRestore:`备份与恢复`,backupRestoreDescription:`导出或恢复 QuickForge 的设置、模型提供商和定时任务。本机项目列表及对话历史不包含在设置备份中,导入前会先创建安全备份。`,exportData:`导出数据`,exportDataDescription:`选择需要包含在 JSON 设置备份中的数据。`,selectExportSections:`选择导出内容`,selectExportSectionsDescription:`默认选中全部设置数据,可以关闭不需要导出的内容。`,conversationBackupExcluded:`对话历史和本机项目列表不属于设置备份,不会从这里导出。`,selectAtLeastOneExportSection:`请至少选择一个要导出的数据项。`,includeApiKeys:`包含 API Key`,includeApiKeysDescription:`已保存的模型提供商 API Key。`,backupExportSecretsConfirm:`此备份将包含 API Key,是否继续?`,exportBackup:`导出备份`,exportBackupDescription:`将所选数据下载为带时间戳的 JSON 文件。`,backupExported:`备份已导出。`,backupExportFailed:`导出备份失败。`,importData:`导入数据`,importDataDescription:`从之前导出的 JSON 备份中恢复核心设置。旧完整备份里的对话历史会被此设置导入流程忽略。`,importBackup:`导入备份`,backupInspectTitle:`备份预览`,backupInspectDescription:`写入本地数据前,先检查元数据并选择要恢复的内容。`,backupInspectExportedAt:`导出时间`,backupInspectVersion:`版本`,backupInspectScope:`范围`,backupInspectSecrets:`包含 API Key`,backupInspectSections:`数据项`,backupInspectFailed:`检查备份失败。`,backupInvalidSections:`以下格式异常的数据项已跳过:`,backupInspected:`备份已检查,请在下方选择要恢复的数据。`,backupInspectedWithIgnoredConversations:`备份已检查。这个旧备份中的对话历史已忽略,请在下方选择要恢复的设置数据。`,selectRestoreSections:`选择要恢复的数据`,restoreMode:`恢复模式`,restoreModeDescription:`选择导入数据如何应用到本地数据。`,restoreModeReplace:`替换`,restoreModeReplaceDescription:`用备份内容完全替换所选分区的本地数据,现有本地数据将被覆盖。`,restoreModeMerge:`合并`,restoreModeMergeDescription:`将备份内容合并到本地,冲突时以备份为准,本地独有的条目将被保留。`,backupImportActions:`导入操作`,backupImportActionsDescription:`导入所选数据项,或取消这次备份预览。`,confirmImportSelected:`导入所选数据`,selectAtLeastOneRestoreSection:`请至少选择一个要恢复的数据项。`,restoreSettings:`设置`,restoreSettingsDescription:`语言、默认选项等应用偏好设置。`,restoreMcp:`MCP 服务`,restoreMcpDescription:`全局 MCP 服务定义及其启用/停用状态。`,restoreProviderKeys:`API Key`,restoreProviderKeysDescription:`已保存的模型提供商 API Key。`,restoreCustomProviders:`自定义提供商和模型`,restoreCustomProvidersDescription:`自定义模型提供商、端点、模型 ID 及相关配置。`,restoreScheduledTasks:`定时任务`,restoreScheduledTasksDescription:`已保存的 AI 定时任务。`,restoreConversations:`对话`,restoreConversationsDescription:`对话历史和元数据。会作为一个一致的整体恢复。`,backupImportConfirm:`导入前会先创建安全备份,是否继续?`,backupImportReplaceConfirm:`确定用此备份替换所选数据项的本地数据吗?导入前会先创建安全备份。`,backupImportMergeConfirm:`确定将所选备份数据合并到本地吗?导入前会先创建安全备份。`,backupImported:`备份已导入,应用即将刷新。`,backupImportFailed:`导入备份失败。`,backupFileTooLarge:`该备份文件超过 {size}MB。当前设置导入主要用于核心设置迁移,请导出核心设置备份,或先减少/排除对话历史后再导入。`,backupStringTooLarge:`该备份过大,当前浏览器导入流程无法稳定处理。请使用核心设置备份,或减少/排除对话历史。`,backupSafetyBackupPath:`安全备份保存位置`,about:`关于`,desktopUpdate:`桌面版发布页`,desktopExit:`退出`,aboutQuickForge:`关于 QuickForge`,aboutQuickForgeDescription:`查看版本和项目链接。`,projectInfo:`项目信息`,packageName:`包名`,packageNameDescription:`当前安装的 QuickForge 包名称。`,currentVersion:`当前版本`,currentVersionDescription:`这台机器上正在运行的版本。`,latestVersion:`最新版本`,latestVersionDescription:`更新检查返回的最新版本。`,github:`GitHub`,githubDescription:`打开项目仓库和发布说明。`,checkUpdate:`检查更新`,checkingUpdate:`检查中...`,checkUpdateDescription:`从 npm 检查 QuickForge Runtime 最新版本。此操作不会更新 Electron 桌面壳。`,desktopUpdates:`桌面版更新`,desktopUpdatesDescription:`下载最新桌面版。`,desktopUpdateFrequencyDescription:`桌面版更新会打开下载页。`,desktopUpdateHint:`已打开下载页。`,openDesktopReleases:`下载最新版本`,runtimeUpdates:`更新`,runtimeUpdatesDescription:`检查是否有新版本。`,updateChannel:`通道`,runtimeUpdateChannel:`Runtime(npm)`,checkRuntimeUpdate:`检查更新`,updateAvailableMessage:`发现新版本:{current} → {latest}。`,localVersionNewerMessage:`你正在使用较新的本地版本:{current}。`,alreadyLatestVersion:`QuickForge 已是最新版本({version})。`,updateNow:`立即更新`,updateRuntimeNow:`立即更新`,updatingQuickForge:`正在更新...`,updateStarted:`更新已开始。QuickForge 会自动重启。`,updateRestarted:`更新完成,正在刷新页面...`,updateRestartTimeout:`更新时间超过预期,请稍后重试。`,updateCompleted:`更新完成,请重启 QuickForge。`,updateFailed:`更新失败。`,updateCheckFailed:`检查更新失败。`,updateCommand:`命令`,updateLog:`更新日志`,updateLogDescription:`当前更新操作的日志文件。`,updateLogFile:`日志:{path}`,updateConfirm:`QuickForge 将更新并重启。正在运行的任务会被中断。是否继续?`,updateFrequencySection:`自动检查更新`,updateFrequencyDescription:`发现新版本时显示提醒。`,frequencyStartup:`每次启动检查`,frequencyDaily:`每天一次`,frequencyWeekly:`每周一次`,frequencyOff:`关闭`,lastCheckedAt:`上次检查:{time}`,lastCheckedNever:`尚未检查`,newVersionAvailable:`发现新版本 {version}`,newVersionAvailableSub:`当前 {current} · 点击查看`,updateLater:`稍后`,backendService:`后端服务`,backendServiceDescription:`重启 QuickForge 本地后端服务。正在运行的生成会被中断,页面会自动重新连接。`,backendServiceStatus:`服务状态`,restartBackendService:`重启后端服务`,restartBackendServiceDescription:`当本地后端卡住,或调整了服务级环境配置后,可以在这里重启。`,restartBackendConfirm:`确定现在重启后端服务吗?正在运行的生成会被中断,页面会自动重新连接。`,backendRestarting:`后端正在重启...`,backendRestarted:`后端已重启,正在刷新页面...`,backendRestartFailed:`后端重启失败。`,backendRestartTimeout:`后端重启超时,请手动重启 QuickForge。`,backendRestartUnsupported:`当前启动方式不支持从界面重启,请手动重启 QuickForge。`,systemRestartRequiresAuth:`重启需要本机或已认证的远程客户端。`,systemUpdateRequiresAuth:`更新需要本机或已认证的远程客户端。`,serviceMode:`模式`,serviceModeDescription:`QuickForge 本地服务当前的运行方式。`,servicePid:`PID`,servicePidDescription:`后端服务的操作系统进程 ID。`,serviceStartedAt:`启动时间`,serviceStartedAtDescription:`当前后端进程的启动时间。`,serviceDataDir:`数据目录`,serviceDataDirDescription:`保存设置、存储、日志和缓存的本地目录。`,serviceWorkspace:`工作区`,serviceWorkspaceDescription:`当前服务进程使用的工作区根目录。`,terminalShell:`终端 Shell`,terminalShellDescription:`QuickForge 会自动识别这台电脑上常见的 macOS、Windows 和 Linux Shell。请从列表中选择默认项;只有缺少时才需要使用自定义命令或路径。QUICKFORGE_TERMINAL_SHELL 仍会优先生效。`,terminalShellAutoDetectedHint:`已识别的条目会自动显示在列表中。`,terminalShellDefault:`默认 Shell`,terminalShellCustomOption:`自定义命令或路径…`,terminalShellSaved:`终端 Shell 设置已保存,新建终端会话会使用该设置。`,terminalShellProfilesSaved:`终端 Shell 配置已保存。`,terminalShellCommand:`自定义 Shell 命令或路径`,terminalShellCustomDescription:`只有自动识别不到时,才需要手动添加 Shell。`,terminalShellCommandPlaceholder:`C:\\Program Files\\Git\\bin\\bash.exe`,terminalShellAdd:`添加`,terminalShellSetDefault:`设为默认`,terminalShellDefaultBadge:`默认`,terminalShellDetected:`已识别`,terminalShellNoDetected:`未识别到可用 Shell,请在下方添加自定义 Shell 命令或路径。`,terminalShellProfileRequired:`保存前请输入 Shell 命令或可执行文件路径。`,terminalShellDeleteConfirm:`确定删除终端 Shell 配置“{name}”吗?`,channels:`渠道`,channelsDescription:`管理把外部应用接入 QuickForge Agent 的本地通信渠道。`,channelsSecurityWarning:`渠道操作会启动本地进程,仅可在本机使用。`,channelsEmpty:`暂无可用渠道。`,start:`启动`,stop:`停止`,restart:`重启`,channelWorkspace:`启动工作区`,channelWorkspaceDescription:`选择渠道启动时使用的工作区。使用默认工作区时,对应非项目的全局对话。`,channelDefaultWorkspace:`默认工作区`,channelNoWorkspaces:`当前没有可用工作区。请先配置默认工作区再启动此渠道。`,channelOpenLogs:`打开日志文件夹`,channelOpeningLogs:`正在打开日志文件夹…`,channelOpenLogsFailed:`无法打开渠道日志文件夹。`,channelQrTitle:`使用微信扫码`,channelQrDescription:`请用微信扫描下方二维码。`,channelStatusStopped:`已停止`,channelStatusStarting:`启动中`,channelStatusWaitingScan:`等待扫码`,channelStatusRunning:`运行中`,channelStatusStopping:`停止中`,channelStatusError:`出错`,channelRestartConfirm:`确定重启渠道“{name}”吗?`,channelLogoutConfirm:`确定退出渠道“{name}”的登录吗?再次使用前需要重新扫码。`,channelReloginConfirm:`确定重新登录渠道“{name}”吗?当前进程会停止,并生成新的二维码。`,terminalNew:`新建终端`,rightPanelOpenTabsTitle:`打开标签页`,rightPanelOpenTabsDescription:`选择要在右侧面板中打开的标签。`,rightPanelAddTab:`打开标签页`,rightPanelCloseOtherTabs:`关闭其他标签页`,rightPanelCloseAllTabs:`关闭全部标签页`,rightPanelFiles:`文件`,rightPanelReview:`审查`,rightPanelTerminal:`终端`,rightPanelBrowser:`浏览器`,rightPanelFilesDesc:`浏览项目文件结构`,rightPanelReviewDesc:`查看 Git 代码变更`,rightPanelTerminalDesc:`运行命令行操作`,rightPanelBrowserDesc:`预览网页效果`,terminalNewWith:`新建终端使用`,terminalNewWithProfile:`新建终端:{name}`,terminalSelectShell:`选择 Shell 新建终端`,terminalCollapse:`收起终端`,terminalFullscreen:`全屏终端`,terminalExitFullscreen:`退出全屏`,terminalStarting:`正在启动终端...`,terminalUnavailable:`终端不可用`,terminalNoSessions:`没有终端会话`,terminalCreateFailed:`创建终端失败`,terminalCloseFailed:`关闭终端失败`,terminalConnectionFailed:`连接终端失败。`,terminalConnectionTimedOut:`终端连接超时。`,terminalConnectionClosedUnexpectedly:`终端连接异常断开。`,terminalSessionUnavailable:`原终端会话已结束,可能是服务重启或会话过期,原进程无法恢复。`,terminalStartNew:`启动新终端`,terminalConnecting:`正在连接终端…`,terminalReconnecting:`正在重新连接终端({attempt}/{max})…`,terminalCloseSession:`关闭 {name}`,workspaceNoFilesToDisplay:`没有可显示的文件。`,workspaceNoWorkingTreeChanges:`工作区没有变更。`,workspaceNoStagedChanges:`没有已暂存变更。`,workspaceNoLastRunChanges:`上一轮产物没有命中 Git 变更文件。`,workspaceRootPath:`项目根目录`,workspaceLoadingDiff:`正在加载差异...`,workspaceNoDiffPreview:`没有可预览的差异。`,workspaceDiffTooLarge:`此差异过大,无法在列表中预览。`,workspaceUnmodifiedLines:`{count} 行未修改`,noProjectSelected:`未选择项目`,workspacePanel:`工作空间`,workspaceExpandRightPanel:`展开右侧边栏`,workspaceCollapseRightPanel:`关闭右侧边栏`,workspaceOverview:`概览`,workspaceFiles:`工作空间文件`,workspaceBrowser:`浏览器`,workspaceChanges:`变更`,workspaceCurrentArtifacts:`审查`,workspaceNoArtifacts:`当前 Session 尚未检测到 AI 产生的文件。`,workspacePresentedArtifact:`展示产物`,workspaceInferredArtifact:`推断产物`,workspaceCommands:`命令`,workspaceCommandOutput:`输出`,workspaceCurrentBranch:`当前分支`,workspaceChangeCount:`项变更`,workspaceNotGitRepository:`此项目不是 Git 仓库。`,workspaceSelectProject:`请选择一个项目来查看工作空间。`,workspaceLoading:`正在加载工作空间...`,workspaceLoadFailed:`加载工作空间失败。`,workspaceFilterFiles:`筛选文件`,workspaceOpenFileTitle:`打开文件`,workspaceOpenFileDescription:`从工作区目录打开文件`,workspaceOpenFileFailed:`打开文件失败。`,workspaceOpenDiffFailed:`打开 diff 失败。`,workspaceViewDiff:`查看 diff`,refreshWorkspace:`刷新工作空间`,closeWorkspace:`关闭工作空间`,workspaceFullscreen:`全屏工作空间`,workspaceExitFullscreen:`退出全屏`,workspaceStaged:`已暂存`,workspaceUntracked:`未跟踪`,workspaceConflicts:`冲突`,workspaceStagedChanges:`已暂存变更`,workspaceReview:`审查`,workspaceReviewFilter:`审查筛选`,workspaceReviewFilterUnstaged:`未暂存`,workspaceReviewFilterStaged:`已暂存`,workspaceReviewFilterAllBranches:`全部分支更改`,workspaceReviewFilterLastRun:`上一轮更改`,workspaceRestoreFile:`还原文件`,workspaceStageFile:`暂存文件`,workspaceUnstageFile:`退回到未暂存`,workspaceOpenFileInNewTab:`在新标签中打开文件`,workspaceCannotOpenDeletedFile:`已删除文件不能直接打开。`,workspaceRestoreAll:`还原全部`,workspaceStageAll:`暂存全部`,workspaceUnstageAll:`退回全部`,workspaceRestoreConfirmTitle:`丢弃更改?`,workspaceRestoreFileConfirm:`还原“{path}”并丢弃它的本地更改?此操作不可撤销。`,workspaceRestoreAllConfirm:`还原列表中的全部更改并删除未跟踪文件?此操作不可撤销。`,workspaceStageFailed:`暂存更改失败。`,workspaceUnstageFailed:`退回未暂存失败。`,workspaceRestoreFailed:`还原更改失败。`,workspaceCommitMessage:`提交信息`,workspaceReviewPrompt:`请审查当前工作空间的变更,并生成一份简要的总结、风险评估、验证计划以及建议的提交信息。
|
|
17
|
+
|
|
18
|
+
变更文件:
|
|
19
|
+
{list}`,workspaceCommitMessagePrompt:`请为当前的 Git 变更生成一条简洁的 Conventional Commit 提交信息。包含一行标题,必要时可附带简短的正文。
|
|
20
|
+
|
|
21
|
+
变更文件:
|
|
22
|
+
{list}`,unknown:`未知`,webPreview:`网页预览`,artifactPreview:`产物`,artifactPreviewFiles:`显示产物文件`,artifactPreviewEmpty:`没有可预览的产物文件。`,artifactPreviewLoadFailed:`加载产物预览失败。`,artifactPreviewUnsupported:`暂不支持预览此文件`,artifactPreviewUnsupportedDescription:`当前文件类型无法在浏览器中直接展示,请使用对应应用打开;如支持阅读模式,也可在 Reader 中查看。`,previewChecking:`正在检查预览…`,previewErrorNotFoundTitle:`找不到文件`,previewErrorNotFoundDescription:`文件可能已被删除、移动或重命名,请检查路径后重试。`,previewErrorTooLargeTitle:`文件过大,无法预览`,previewErrorTooLargeDescription:`该文件超过浏览器预览大小限制,请使用其他应用打开。`,previewErrorPermissionTitle:`无法访问此文件`,previewErrorPermissionDescription:`该路径受到限制,或 QuickForge 没有读取权限。`,previewErrorServiceTitle:`预览服务暂不可用`,previewErrorServiceDescription:`QuickForge 无法准备此预览,请检查本地服务后重试。`,previewErrorUnknownTitle:`无法预览此文件`,previewErrorUnknownDescription:`准备预览时发生未知错误,你可以重试或展开下方详情进行排查。`,previewErrorDetails:`错误详情`,previewErrorStatusCode:`状态码`,previewErrorCode:`错误代码`,previewErrorFilePath:`文件路径`,previewErrorRawMessage:`原始报错`,artifactPreviewViewSource:`查看源码`,artifactPreviewPin:`固定产物工具`,artifactPreviewUnpin:`取消固定产物工具`,artifacts:`产物`,previewArtifact:`预览产物`,previewUrl:`预览地址`,previewUrlPlaceholder:`输入 URL`,openPreview:`打开`,refreshPreview:`刷新预览`,openInBrowser:`在浏览器中打开`,zoom:`缩放`,zoomIn:`放大`,zoomOut:`缩小`,resetZoom:`重置缩放`,invalidPreviewUrl:`请输入有效的 http:// 或 https:// 地址。`,noPreviewUrlTitle:`开始浏览`,noPreviewUrlDescription:`输入 URL 以打开页面`,workspaceStatusAdded:`新增`,workspaceStatusDeleted:`删除`,workspaceStatusRenamed:`重命名`,workspaceStatusUntracked:`未跟踪`,workspaceStatusConflict:`冲突`,workspaceStatusModified:`修改`,copyPath:`复制路径`,copyContent:`复制内容`,copyFileContent:`复制文件内容`,copyDiffContent:`复制差异内容`,readerMoreActions:`更多文件操作`,readerOpen:`打开`,enableWordWrap:`启用自动换行`,showFileNavigation:`显示文件导航`,hideFileNavigation:`隐藏文件导航`,askAiAboutThis:`就此询问 AI`,readerFileMarkdownPrompt:"请阅读当前工作空间中的 Markdown 文档 `{path}`。总结其用途、关键章节、重要说明、过时或有风险的部分,并给出简洁的改进建议。",readerFilePrompt:"请检查当前工作空间中的 `{path}`,说明它的作用、重要的实现细节,以及任何风险或改进机会。",readerDiffPrompt:"请审查 `{path}` 的工作区变更。总结改了什么,指出可能的 bug 或回归,并给出有针对性的验证步骤。",openingReader:`打开中...`,markdownPreview:`预览`,markdownSource:`源码`,viewMarkdownSource:`查看源代码`,returnToMarkdownPreview:`返回预览`,lanAccess:`局域网访问`,lanAccessDescription:`允许同一局域网内可信设备在输入密码后访问完整 QuickForge。`,lanAccessRiskWarning:`高风险:通过密码的局域网设备可以访问你的对话、项目和可用工具。请只在可信网络中开启。`,lanAccessStatus:`局域网访问状态`,lanAccessEnabled:`完整局域网访问`,lanAccessEnabledDescription:`当前是否允许局域网设备完整访问 QuickForge。`,lanAccessPassword:`访问密码`,lanAccessPasswordStatusDescription:`局域网登录使用的密码状态。`,lanAccessActiveDevices:`已登录设备({count})`,lanAccessActiveDevicesDescription:`当前仍有访问权限、可以踢出的局域网设备;使用不同浏览器时,同一设备可能出现多次。`,lanAccessBrowser:`浏览器`,lanAccessUnknownDevice:`局域网设备`,lanAccessUnknownAddress:`未知地址`,lanAccessSignedInAt:`登录于 {time}`,lanAccessExpiresAt:`到期于 {time}`,lanAccessNoActiveDevices:`当前没有保持登录状态的局域网设备。`,lanAccessRevokeDevice:`踢出`,lanAccessRevokeDeviceConfirm:`确定踢出 {device} 吗?该会话需要重新输入局域网密码。`,lanAccessDeviceRevoked:`所选局域网会话已退出登录。`,lanAccessUrls:`局域网地址`,lanAccessUrlsDescription:`在同一可信网络的其他设备上打开这些地址访问。`,lanAccessAllowFull:`允许局域网设备访问完整 QuickForge`,lanAccessAllowFullDescription:`仅在可信网络开启;通过密码的局域网设备可使用完整应用。`,lanAccessPasswordPlaceholder:`至少 8 个字符`,lanAccessPasswordPlaceholderConfigured:`留空则保留当前密码`,showPassword:`显示密码`,hidePassword:`隐藏密码`,lanAccessSessionTtl:`登录有效期`,lanAccessSessionTtlDescription:`局域网设备输入密码后保持登录的时间。`,lanAccessActions:`操作`,lanAccessActionsDescription:`保存访问设置,或让所有局域网设备退出登录。`,lanAccessRevokeAll:`踢掉所有局域网设备`,lanAccessRevokeAllConfirm:`确定要让所有已解锁的局域网设备退出登录吗?`,lanAccessEnableConfirm:`确定开启完整局域网访问吗?请仅在可信网络中继续。`,lanAccessPasswordRequired:`开启局域网访问前请先设置访问密码。`,lanAccessPasswordTooShort:`访问密码至少需要 8 个字符。`,lanAccessSaved:`局域网访问设置已保存。`,lanAccessRevoked:`所有局域网设备已退出登录。`,enabled:`已开启`,disabled:`已关闭`,configured:`已设置`,notConfigured:`未设置`,generatePassword:`生成密码`,hour:`小时`,hours:`小时`,days:`天`,toolApprovalWaiting:`等待审批:{toolName}`,autoCompactApprovalWaiting:`上下文已达到 {percent}%(阈值 {threshold}%),是否现在压缩?`,autoCompactApprovalPreview:`QuickForge 会总结较早历史,并使用摘要加最近 {keepRecentTurns} 个用户回合继续任务。完整聊天历史仍会保留在界面中。`,autoCompactFailed:`自动上下文压缩失败,将继续使用当前历史。`,contextCompactedTimelineLabel:`较早上下文已整理为摘要供模型使用`,contextCompactedLabel:`已压缩上下文`,contextCompactedTooltip:`此对话的模型请求正在使用摘要上下文,完整聊天历史仍会保留在界面中。`,contextCompactedViewSummary:`查看摘要`,contextCompactedHideSummary:`收起摘要`,contextCompactedSummaryTitle:`模型正在使用的压缩摘要`,contextCompactedCopySummary:`复制摘要`,toolApprovalAccept:`仅本次允许`,toolApprovalReject:`拒绝`,toolApprovalTimeout:`超时时间`,toolApprovalTruncated:`...(内容已截断)`,processed:`已处理`,processing:`处理中`,processExecuted:`已执行`,processExecuting:`执行中`,processGroupToolsCalled:`{count} 个工具调用`,processGroupCommandsRan:`{count} 条命令`,processGroupFilesEdited:`编辑 {count} 个文件`,processFailed:`处理出错`,processAborted:`已中止`,processDurationSeconds:`{seconds}秒`,processDurationMinutesSeconds:`{minutes}分 {seconds}秒`,processThinking:`思考过程`,processCommandsRan:`运行了 {count} 个命令`,processFilesEdited:`编辑了 {count} 个文件`,processToolsCalled:`调用了 {count} 项工具`,processToolsFailedCount:`{count} 项失败`,expandProcess:`展开处理详情`,collapseProcess:`收起处理详情`,expandProcessTools:`展开工具执行记录`,collapseProcessTools:`收起工具执行记录`,relativeMinuteShort:`{count}分`,relativeHourShort:`{count}小时`,relativeDayShort:`{count}天`,relativeWeekShort:`{count}周`,relativeYearShort:`{count}年`}},ct={...ze.en,"Configure API keys for LLM providers. Keys are stored locally in your browser.":`Configure API keys for LLM providers. Keys are stored by the local QuickForge service on this machine.`,"Settings are stored locally in your browser":`Settings are stored by the local QuickForge service on this machine`,"Storage Permission Required":`Local Service Required`,"This app needs persistent storage to save your conversations":`This app needs the local QuickForge service to save your conversations`,"Without persistent storage, your browser may delete saved conversations when it needs disk space. Granting this permission ensures your chat history is preserved.":`QuickForge saves data to local files through the local service on this machine so your chat history is preserved.`,"Your conversations will be saved locally in your browser":`Your conversations will be saved to local files by the local QuickForge service`,"Cloud LLM providers with predefined models. API keys are stored locally in your browser.":`Cloud LLM providers with predefined models. API keys are stored by the local QuickForge service on this machine.`},lt={...ze.en,Free:`免费`,"Input Required":`需要输入`,Cancel:`取消`,Confirm:`确认`,"Select Model":`选择模型`,"Search models...":`搜索模型...`,Format:`格式`,Thinking:`思考`,Vision:`视觉`,You:`你`,Assistant:`助手`,"Thinking...":`正在思考...`,"Type your message...":`输入你的消息...`,"API Keys Configuration":`API Key 配置`,"Configure API keys for LLM providers. Keys are stored locally in your browser.":`配置 LLM 提供商的 API Key。密钥会由本机 QuickForge 本地服务保存。`,Configured:`已配置`,"Not configured":`未配置`,"✓ Valid":`✓ 有效`,"✗ Invalid":`✗ 无效`,"Testing...":`测试中...`,Update:`更新`,Test:`测试`,Remove:`移除`,Save:`保存`,"Update API key":`更新 API Key`,"Enter API key":`输入 API Key`,"Type a message...":`输入消息...`,"Failed to fetch file":`获取文件失败`,"Invalid source type":`无效的来源类型`,PDF:`PDF`,Document:`文档`,Presentation:`演示文稿`,Spreadsheet:`电子表格`,Text:`文本`,"Error loading file":`加载文件出错`,"No text content available":`没有可用的文本内容`,"Failed to load PDF":`加载 PDF 失败`,"Failed to load document":`加载文档失败`,"Failed to load spreadsheet":`加载电子表格失败`,"Error loading PDF":`加载 PDF 出错`,"Error loading document":`加载文档出错`,"Error loading spreadsheet":`加载电子表格出错`,"Preview not available for this file type.":`此文件类型不支持预览。`,"Click the download button above to view it on your computer.":`点击上方下载按钮在电脑上查看。`,"No content available":`没有可用内容`,"Failed to display text content":`显示文本内容失败`,"API keys are required to use AI models. Get your keys from the provider's website.":`使用 AI 模型需要 API Key。请从提供商网站获取。`,console:`控制台`,"Copy output":`复制输出`,"Copied!":`已复制!`,"Error:":`错误:`,"Request aborted":`请求已中止`,Call:`调用`,Result:`结果`,"(no result)":`(无结果)`,"Waiting for tool result…":`等待工具结果…`,"Call was aborted; no result.":`调用已中止,没有结果。`,"No session available":`没有可用会话`,"No session set":`未设置会话`,"Preparing tool parameters...":`正在准备工具参数...`,"(no output)":`(无输出)`,Input:`输入`,Output:`输出`,"Writing expression...":`正在写入表达式...`,"Waiting for expression...":`等待表达式...`,Calculating:`计算中`,"Getting current time in":`正在获取当前时间:`,"Getting current date and time":`正在获取当前日期和时间`,"Waiting for command...":`等待命令...`,"Writing command...":`正在写入命令...`,"Running command...":`正在运行命令...`,"Command failed:":`命令失败:`,"Enter Auth Token":`输入认证令牌`,"Please enter your auth token.":`请输入你的认证令牌。`,"Execution aborted":`执行已中止`,"Code parameter is required":`需要代码参数`,"Unknown error":`未知错误`,"Code executed successfully (no output)":`代码执行成功(无输出)`,"Execution failed":`执行失败`,"JavaScript REPL":`JavaScript REPL`,"JavaScript code to execute":`要执行的 JavaScript 代码`,"Writing JavaScript code...":`正在写入 JavaScript 代码...`,"Executing JavaScript":`正在执行 JavaScript`,"Preparing JavaScript...":`正在准备 JavaScript...`,"Preparing command...":`正在准备命令...`,"Preparing calculation...":`正在准备计算...`,"Preparing tool...":`正在准备工具...`,"Getting time...":`正在获取时间...`,"Processing artifact...":`正在处理产物...`,"Preparing artifact...":`正在准备产物...`,"Processing artifact":`正在处理产物`,"Processed artifact":`已处理产物`,"Creating artifact":`正在创建产物`,"Created artifact":`已创建产物`,"Updating artifact":`正在更新产物`,"Updated artifact":`已更新产物`,"Rewriting artifact":`正在重写产物`,"Rewrote artifact":`已重写产物`,"Getting artifact":`正在获取产物`,"Got artifact":`已获取产物`,"Deleting artifact":`正在删除产物`,"Deleted artifact":`已删除产物`,"Getting logs":`正在获取日志`,"Got logs":`已获取日志`,"An error occurred":`发生错误`,"Copy logs":`复制日志`,"Autoscroll enabled":`已启用自动滚动`,"Autoscroll disabled":`已关闭自动滚动`,Processing:`处理中`,Create:`创建`,Rewrite:`重写`,Get:`获取`,Delete:`删除`,"Get logs":`获取日志`,"Show artifacts":`显示产物`,"Close artifacts":`关闭产物`,Artifacts:`产物`,"Copy HTML":`复制 HTML`,"Download HTML":`下载 HTML`,"Reload HTML":`重新加载 HTML`,"Copy SVG":`复制 SVG`,"Download SVG":`下载 SVG`,"Copy Markdown":`复制 Markdown`,"Download Markdown":`下载 Markdown`,Download:`下载`,"No logs for {filename}":`{filename} 没有日志`,"API Keys Settings":`API Key 设置`,Settings:`设置`,"API Keys":`API Key`,"Settings are stored locally in your browser":`设置会由本机 QuickForge 本地服务保存`,Clear:`清除`,"API Key Required":`需要 API Key`,"Enter your API key for {provider}":`输入 {provider} 的 API Key`,Off:`关闭`,Minimal:`最小`,Low:`低`,Medium:`中`,High:`高`,"Storage Permission Required":`需要本地服务`,"This app needs persistent storage to save your conversations":`此应用需要 QuickForge 本地服务来保存你的对话`,"Why is this needed?":`为什么需要?`,"Without persistent storage, your browser may delete saved conversations when it needs disk space. Granting this permission ensures your chat history is preserved.":`QuickForge 会通过本机本地服务把数据保存到本地文件中,确保聊天历史可持久保留。`,"What this means:":`这意味着:`,"Your conversations will be saved locally in your browser":`你的对话会由本机 QuickForge 本地服务保存到本地文件`,"Data will not be deleted automatically to free up space":`数据不会被自动删除来释放空间`,"You can still manually clear data at any time":`你仍然可以随时手动清除数据`,"No data is sent to external servers":`不会向外部服务器发送数据`,"Continue Anyway":`仍然继续`,"Requesting...":`请求中...`,"Grant Permission":`授予权限`,Sessions:`会话`,"Load a previous conversation":`加载之前的对话`,"No sessions yet":`暂无会话`,"Delete this session?":`删除此会话?`,Today:`今天`,Yesterday:`昨天`,"{days} days ago":`{days} 天前`,messages:`条消息`,tokens:`tokens`,"Drop files here":`将文件拖到这里`,"Providers & Models":`提供商与模型`,"Cloud Providers":`云提供商`,"Cloud LLM providers with predefined models. API keys are stored locally in your browser.":`带有预定义模型的云 LLM 提供商。API Key 会由本机 QuickForge 本地服务保存。`,"Custom Providers":`自定义提供商`,"User-configured servers with auto-discovered or manually defined models.":`用户配置的服务器,支持自动发现或手动定义模型。`,"Add Provider":`添加提供商`,"No custom providers configured. Click 'Add Provider' to get started.":`尚未配置自定义提供商。点击"添加提供商"开始。`,Models:`模型`,"auto-discovered":`自动发现`,Refresh:`刷新`,Edit:`编辑`,"Are you sure you want to delete this provider?":`确定删除这个提供商吗?`,"Edit Provider":`编辑提供商`,"Provider Name":`提供商名称`,"e.g., My Ollama Server":`例如:我的 Ollama 服务`,"Provider Type":`提供商类型`,"Base URL":`Base URL`,"e.g., http://localhost:11434":`例如:http://localhost:11434`,"API Key (Optional)":`API Key(可选)`,"Leave empty if not required":`不需要可以留空`,"Test Connection":`测试连接`,Discovered:`已发现`,models:`个模型`,and:`以及`,more:`更多`,"For manual provider types, add models after saving the provider.":`手动提供商类型需要保存提供商后再添加模型。`,"Please fill in all required fields":`请填写所有必填项`,"Failed to save provider":`保存提供商失败`,"OpenAI Completions Compatible":`OpenAI Completions 兼容`,"OpenAI Responses Compatible":`OpenAI Responses 兼容`,"Anthropic Messages Compatible":`Anthropic Messages 兼容`,"Checking...":`检查中...`,Disconnected:`未连接`,"*":`*`,Copy:`复制`,"Copy code":`复制代码`,Close:`关闭`,Preview:`预览`,Code:`代码`,"Loading...":`加载中...`,"Select an option":`选择一个选项`,"Mode 1":`模式 1`,"Mode 2":`模式 2`,Required:`必填`,Optional:`可选`},ut=dt();function dt(){return typeof navigator<`u`&&navigator.language.toLowerCase().startsWith(`zh`)?`zh`:`en`}function ft(e){return typeof e==`string`&&ot.includes(e)}function pt(e){typeof document>`u`||(document.documentElement.lang=e===`zh`?`zh-CN`:`en`,document.documentElement.dir=`ltr`)}function mt(e){let t=e===`zh`?lt:ct;for(let e of Object.keys(ze))ze[e]=t}function U(e){ut=e,mt(e),pt(e)}ze.zh=lt,U(ut);function ht(){return ut}function W(e,t){let n=st[ht()][e]??st.en[e];if(!t)return n;for(let[e,r]of Object.entries(t))n=n.replaceAll(`{${e}}`,String(r));return n}function gt(){return ht()===`zh`?`zh-CN`:`en-US`}async function _t(e){let t=await e.settings.get(at),n=ft(t)?t:dt();return ft(t)||await e.settings.set(at,n),U(n),n}async function vt(e,t){return t===ht()?!1:(await e.settings.set(at,t),U(t),window.location.reload(),!0)}var yt=new Set([`off`,`low`,`medium`,`high`,`xhigh`]),bt=[{value:`off`,label:()=>Be(`Off`)},{value:`low`,label:()=>Be(`Low`)},{value:`medium`,label:()=>Be(`Medium`)},{value:`high`,label:()=>Be(`High`)},{value:`xhigh`,label:()=>ht()===`zh`?`极高`:`XHigh`}];function xt(e){return typeof e==`string`&&yt.has(e)}function St(e){return Array.from(e.querySelectorAll(`.flex.gap-2.items-center`)).find(e=>e.querySelector(`button[role="combobox"]`)||e.querySelector(`[data-quickforge-thinking-selector]`))}function Ct(e,t){Ne(Ye({value:xt(t.thinkingLevel)?t.thinkingLevel:`off`,placeholder:Be(`Off`),options:bt.map(e=>({value:e.value,label:e.label(),icon:Ue(Ve,`sm`)})),onChange:e=>{let n=xt(e)?e:`off`;t.thinkingLevel=n,t.onThinkingChange?.(n),t.requestUpdate?.()},width:`80px`,size:`sm`,variant:`ghost`,fitContent:!0}),e)}function wt(e){let t=e;xt(t.thinkingLevel)||(t.thinkingLevel=`off`,t.onThinkingChange?.(`off`));let n=St(e);if(!n)return;let r=n.querySelector(`[data-quickforge-thinking-selector]`);if(r){Ct(r,t);return}let i=n.querySelector(`button[role="combobox"]`);if(!i)return;i.style.display=`none`,i.setAttribute(`aria-hidden`,`true`);let a=document.createElement(`span`);a.dataset.quickforgeThinkingSelector=`true`,i.insertAdjacentElement(`afterend`,a),Ct(a,t)}function Tt(e={}){let{hideSelector:t=!1}=e,n=()=>{let e=customElements.get(`message-editor`);if(!e?.prototype.render||e.prototype.render.__quickforgePatched)return;let n=e.prototype.render;e.prototype.render=function(){let e=n.call(this);return queueMicrotask(()=>{if(t){let e=this;e.showThinkingSelector!==!1&&(e.showThinkingSelector=!1,e.requestUpdate?.());return}wt(this)}),e},e.prototype.render.__quickforgePatched=!0};if(customElements.get(`message-editor`)){n();return}customElements.whenDefined(`message-editor`).then(n).catch(()=>{})}function Et(e){return new Promise((t,n)=>{let r=document.createElement(`textarea`);r.value=e,r.style.position=`fixed`,r.style.left=`-9999px`,r.style.top=`-9999px`,r.style.opacity=`0`,document.body.append(r),r.select();try{document.execCommand(`copy`)?t():n(Error(`execCommand("copy") returned false`))}catch(e){n(e)}finally{r.remove()}})}function Dt(){navigator.clipboard||Object.defineProperty(navigator,`clipboard`,{value:{writeText:Et,readText:()=>Promise.reject(Error(`Clipboard read is not available in non-secure contexts`)),read:()=>Promise.reject(Error(`Clipboard read is not available in non-secure contexts`)),write:()=>Promise.reject(Error(`Clipboard write is not available in non-secure contexts`))},configurable:!0,enumerable:!0,writable:!1})}var Ot=`quickforge:mobile-server-url`,kt=`quickforge:mobile-server-settings:v1`,At=`quickforgeMobile`,jt=`quickforge:mobile-shell`,Mt=`quickforgeAlias`;function Nt(e){let t=e.split(`.`).map(Number);return t.length!==4||t.some(e=>!Number.isInteger(e)||e<0||e>255)?!1:t[0]===100&&t[1]>=64&&t[1]<=127}function Pt(e){return e.toLowerCase().endsWith(`.ts.net`)}function Ft(e){let t=e.trim();if(!t)throw Error(`请输入 QuickForge 服务地址`);let n=/^[a-z][a-z\d+.-]*:\/\//i.test(t)?t:`http://${t}`,r;try{r=new URL(n)}catch{throw Error(`服务地址格式不正确`)}if(r.protocol!==`http:`&&r.protocol!==`https:`)throw Error(`服务地址只支持 HTTP 或 HTTPS`);if(r.username||r.password)throw Error(`服务地址不能包含用户名或密码`);if(!Pt(r.hostname)&&!Nt(r.hostname))throw Error(`该服务器地址不受支持`);if(r.pathname!==`/`||r.search||r.hash)throw Error(`请输入服务根地址,不要附加路径、参数或锚点`);return r.port||=`5176`,r.origin}function It(e){if(!Array.isArray(e))return[];let t=[];for(let n of e)if(typeof n==`string`)try{let e=Ft(n);t.includes(e)||t.push(e)}catch{}return t}function Lt(e,t){if(typeof e!=`object`||!e||Array.isArray(e))return{};let n={};for(let[r,i]of Object.entries(e)){if(typeof i!=`string`)continue;let e=i.trim();if(!e)continue;let a=It([r])[0];!a||!t.includes(a)||(n[a]=e)}return n}function Rt(e=window.localStorage){try{let t=e.getItem(kt);if(t!==null)try{let e=JSON.parse(t),n=It(e?.urls),r=typeof e?.lastUsedUrl==`string`&&It([e.lastUsedUrl])[0]||``;return{urls:n,lastUsedUrl:n.includes(r)?r:n[0]||``,aliases:Lt(e?.aliases,n)}}catch{}let n=e.getItem(Ot),r=n&&It([n])[0]||``;return r?{urls:[r],lastUsedUrl:r,aliases:{}}:{urls:[],lastUsedUrl:``,aliases:{}}}catch{return{urls:[],lastUsedUrl:``,aliases:{}}}}function zt(e,t=window.localStorage){let n=It(e.urls),r=It([e.lastUsedUrl])[0]||``,i=n.includes(r)?r:n[0]||``,a=Lt(e.aliases,n);t.setItem(kt,JSON.stringify({urls:n,lastUsedUrl:i,aliases:a})),i?t.setItem(Ot,i):t.removeItem(Ot)}function Bt(e){try{let t=Ft(e);return Rt().aliases?.[t]?.trim()||void 0}catch{return}}function Vt(e){let t=new URL(e);t.searchParams.set(At,`1`);let n=Bt(e);return n&&t.searchParams.set(Mt,n),t.toString()}function Ht(e=typeof window<`u`?window.location.search:``){return new URLSearchParams(e).get(Mt)?.trim()||void 0}function Ut(){return Me.isNativePlatform()&&location.hostname===`localhost`}function Wt(){if(new URLSearchParams(location.search).get(At)===`1`){try{window.sessionStorage.setItem(jt,`1`)}catch{}return!0}try{return window.sessionStorage.getItem(jt)===`1`}catch{return!1}}function Gt(){return Kt()?!0:![`localhost`,`127.0.0.1`,`::1`].includes(location.hostname)}function Kt(){return new URLSearchParams(location.search).get(`quickforgeRemote`)===`1`}function qt(e){let t=new URLSearchParams({connect:`1`});e&&t.set(`tab`,e),window.location.href=`https://localhost/?${t.toString()}`}function G(...e){return Le(Ie(e))}var K=De(),Jt=Re(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0`,{variants:{variant:{default:`bg-primary text-primary-foreground hover:bg-primary/90`,destructive:`bg-destructive text-destructive-foreground hover:bg-destructive/90`,outline:`border border-input bg-background hover:bg-accent hover:text-accent-foreground`,secondary:`bg-secondary text-secondary-foreground hover:bg-secondary/80`,ghost:`hover:bg-accent hover:text-accent-foreground`},size:{default:`h-9 px-4 py-2`,sm:`h-8 rounded-md px-3`,icon:`size-9`}},defaultVariants:{variant:`default`,size:`default`}}),q=H.forwardRef(({className:e,variant:t,size:n,...r},i)=>(0,K.jsx)(`button`,{className:G(Jt({variant:t,size:n,className:e})),ref:i,...r}));q.displayName=`Button`;var Yt=class extends H.Component{constructor(e){super(e),this.state={error:null}}static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){V.error(`ErrorBoundary caught an error:`,e,t)}handleRetry=()=>{this.setState({error:null})};handleReload=()=>{window.location.reload()};render(){return this.state.error?this.props.fallback?this.props.fallback:(0,K.jsx)(`div`,{className:`flex h-screen items-center justify-center bg-background p-6 text-foreground`,children:(0,K.jsxs)(`div`,{className:`max-w-md rounded-lg border border-border bg-background p-5 text-center`,children:[(0,K.jsx)(`h1`,{className:`text-base font-medium`,children:W(`errorBoundaryTitle`)}),(0,K.jsx)(`p`,{className:`mt-2 text-sm text-muted-foreground break-all`,children:this.state.error.message||W(`errorBoundaryUnexpected`)}),(0,K.jsxs)(`div`,{className:`mt-4 flex justify-center gap-2`,children:[(0,K.jsx)(q,{variant:`outline`,size:`sm`,onClick:this.handleRetry,children:W(`errorBoundaryTryAgain`)}),(0,K.jsx)(q,{variant:`default`,size:`sm`,onClick:this.handleReload,children:W(`reloadPage`)})]})]})}):this.props.children}};async function Xt(e){let t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||`HTTP ${e.status}`);return t}function Zt({open:e,initialPath:t,disabled:n,onOpenChange:r,onSelect:i}){let a=(0,H.useRef)(null),[o,s]=(0,H.useState)([]),[c,l]=(0,H.useState)(``),[u,d]=(0,H.useState)(``),[f,p]=(0,H.useState)(null),[m,h]=(0,H.useState)([]),[g,v]=(0,H.useState)(!1),[y,b]=(0,H.useState)(!1),[x,S]=(0,H.useState)(``),C=async e=>{if(e.trim()){v(!0),S(``);try{let t=await Xt(await fetch(`/api/filesystem/directories?path=${encodeURIComponent(e.trim())}`));l(t.path),d(t.path),p(t.parent),h(Array.isArray(t.directories)?t.directories:[])}catch(e){S(e instanceof Error?e.message:W(`directoryLoadFailed`))}finally{v(!1)}}};return(0,H.useEffect)(()=>{if(!e)return;let n=!1;return(async()=>{v(!0),S(``);try{let e=await Xt(await fetch(`/api/filesystem/roots`));if(n)return;let r=Array.isArray(e.roots)?e.roots:[];s(r);let i=t||r[0]?.path||``;i&&await C(i)}catch(e){n||S(e instanceof Error?e.message:W(`filesystemRootsFailed`))}finally{n||v(!1)}})(),window.setTimeout(()=>a.current?.focus(),0),()=>{n=!0}},[t,e]),(0,H.useEffect)(()=>{if(!e)return;let t=e=>{e.key===`Escape`&&!y&&r(!1)};return document.addEventListener(`keydown`,t),()=>document.removeEventListener(`keydown`,t)},[r,e,y]),e?(0,K.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4`,onClick:e=>{e.target===e.currentTarget&&!y&&r(!1)},children:(0,K.jsxs)(`div`,{className:`flex max-h-[85vh] w-full max-w-2xl flex-col rounded-lg border border-border bg-background shadow-quickforge`,children:[(0,K.jsxs)(`div`,{className:`border-b border-border p-4`,children:[(0,K.jsx)(`h2`,{className:`text-base font-semibold text-foreground`,children:W(`selectProjectDirectory`)}),(0,K.jsx)(`p`,{className:`mt-1 text-sm text-muted-foreground`,children:W(`selectProjectDirectoryDescription`)})]}),(0,K.jsxs)(`div`,{className:`space-y-4 overflow-y-auto p-4`,children:[o.length>0?(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`div`,{className:`mb-2 text-xs font-medium uppercase tracking-wide text-muted-foreground`,children:W(`quickAccess`)}),(0,K.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:o.map(e=>(0,K.jsx)(q,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>C(e.path),disabled:g||y,children:e.name},`${e.name}:${e.path}`))})]}):null,(0,K.jsxs)(`form`,{className:`space-y-2`,onSubmit:e=>{e.preventDefault(),C(u)},children:[(0,K.jsx)(`label`,{className:`text-xs font-medium uppercase tracking-wide text-muted-foreground`,htmlFor:`project-path-input`,children:W(`path`)}),(0,K.jsxs)(`div`,{className:`flex gap-2`,children:[(0,K.jsx)(`input`,{id:`project-path-input`,ref:a,className:G(`min-w-0 flex-1 rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground shadow-sm`,`focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring`),value:u,onChange:e=>d(e.target.value),placeholder:W(`folderPickerPathPlaceholder`),disabled:g||y}),(0,K.jsx)(q,{type:`submit`,variant:`outline`,disabled:g||y||!u.trim(),children:W(`go`)})]})]}),x?(0,K.jsx)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:x}):null,(0,K.jsxs)(`div`,{className:`rounded-md border border-border`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between gap-2 border-b border-border px-3 py-2`,children:[(0,K.jsx)(`div`,{className:`min-w-0 truncate text-sm font-medium`,title:c,children:c||W(`loading`)}),g?(0,K.jsx)(B,{className:`size-4 shrink-0 animate-spin text-muted-foreground`}):null]}),(0,K.jsxs)(`div`,{className:`max-h-80 overflow-y-auto p-1`,children:[f?(0,K.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-2 rounded-md px-3 py-2 text-left text-sm hover:bg-muted/28 disabled:opacity-50`,onClick:()=>C(f),disabled:g||y,children:[(0,K.jsx)(_,{className:`size-4 text-muted-foreground`}),(0,K.jsx)(`span`,{children:W(`parentDirectory`)})]}):null,!g&&m.length===0?(0,K.jsx)(`div`,{className:`px-3 py-8 text-center text-sm text-muted-foreground`,children:W(`noFolders`)}):null,m.map(e=>(0,K.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-2 rounded-md px-3 py-2 text-left text-sm hover:bg-muted/28 disabled:opacity-50`,onClick:()=>C(e.path),disabled:g||y,title:e.path,children:[(0,K.jsx)(A,{className:`size-4 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`truncate`,children:e.name})]},e.path))]})]})]}),(0,K.jsxs)(`div`,{className:`flex justify-end gap-2 border-t border-border p-4`,children:[(0,K.jsx)(q,{type:`button`,variant:`outline`,onClick:()=>r(!1),disabled:y,children:W(`cancel`)}),(0,K.jsx)(q,{type:`button`,onClick:async()=>{let e=u.trim()||c;if(!(!e||y||n)){b(!0),S(``);try{await i(e),r(!1)}catch(e){S(e instanceof Error?e.message:W(`failedToSelectProjectDirectory`))}finally{b(!1)}}},disabled:g||y||n||!(u.trim()||c),children:W(y?`selecting`:`selectThisFolder`)})]})]})}):null}var Qt=`data:image/svg+xml,%3csvg%20width='64'%20height='64'%20viewBox='0%200%2064%2064'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20clip-path='url(%23clip0_4363_9194)'%3e%3cpath%20d='M15.9476%205.81836L4.07215%205.8201C1.82284%205.8201%200%207.64352%200%209.89283V21.3994C0%2022.5881%200.519564%2023.718%201.42196%2024.4918L39.5828%2057.2016C40.3212%2057.8341%2041.2614%2058.182%2042.2336%2058.182H54.1091C56.3584%2058.182%2058.1818%2056.3586%2058.1818%2054.1093V42.6009C58.1818%2041.4123%2057.6623%2040.2824%2056.7599%2039.5085L18.599%206.7993C17.8607%206.16629%2016.9204%205.81894%2015.9476%205.81894V5.81836Z'%20fill='%23FF8100'/%3e%3cpath%20d='M14.5193%205.81836H4.07273C1.82342%205.81836%200%207.64178%200%209.89109V22.9837C0%2023.1763%200.0139636%2023.3689%200.0407273%2023.5597L5.31782%2060.5035C5.60465%2062.5101%207.32276%2064.0002%209.34982%2064.0002H25.0228C27.2727%2064.0002%2029.0961%2062.1762%2029.0956%2059.9263L29.0909%2041.3878C29.0909%2040.9503%2029.0205%2040.5157%2028.882%2040.1008L18.3825%208.60294C17.8281%206.9401%2016.2717%205.81836%2014.5187%205.81836H14.5193Z'%20fill='url(%23paint0_linear_4363_9194)'/%3e%3cpath%20d='M59.9275%200H25.9592C24.3301%200%2022.8575%200.971054%2022.2157%202.46807L6.14767%2039.9587C5.93065%2040.4655%205.81836%2041.0118%205.81836%2041.5633V59.9273C5.81836%2062.1766%207.64178%2064%209.89109%2064H27.8571C28.6617%2064%2029.4483%2063.7615%2030.118%2063.3146L62.1866%2041.9113C63.3189%2041.1561%2063.9984%2039.8848%2063.9984%2038.5239L64.0002%204.07273C64.0002%201.82342%2062.1768%200%2059.9275%200Z'%20fill='url(%23paint1_linear_4363_9194)'/%3e%3cpath%20d='M52%2012H12V52H52V12Z'%20fill='black'/%3e%3cpath%20d='M17.0001%2029.3856H19.9789V19.6144H17.0001V17H25.8391V19.6144H22.8603V29.3856H25.8391V32H17.0001V29.3856Z'%20fill='white'/%3e%3cpath%20d='M27.3391%2029.3002H29.4928C29.9282%2029.3002%2030.3161%2029.2074%2030.6553%2029.0218C30.9945%2028.8361%2031.2569%2028.5737%2031.4426%2028.2345C31.6282%2027.8953%2031.721%2027.508%2031.721%2027.072V17H34.646V27.2748C34.646%2028.1749%2034.4386%2028.984%2034.0243%2029.7019C33.6101%2030.4198%2033.0388%2030.9824%2032.31%2031.3892C31.5812%2031.7966%2030.7636%2032%2029.8566%2032H27.3391V29.3002Z'%20fill='white'/%3e%3cpath%20d='M33%2044H17V47H33V44Z'%20fill='white'/%3e%3c/g%3e%3cdefs%3e%3clinearGradient%20id='paint0_linear_4363_9194'%20x1='-0.717383'%20y1='7.62141'%20x2='24.1455'%20y2='61.2476'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20offset='0.1'%20stop-color='%23FC801D'/%3e%3cstop%20offset='0.59'%20stop-color='%23FE2857'/%3e%3c/linearGradient%3e%3clinearGradient%20id='paint1_linear_4363_9194'%20x1='4.22243'%20y1='60.0186'%20x2='62.9273'%20y2='1.31316'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20offset='0.21'%20stop-color='%23FE2857'/%3e%3cstop%20offset='0.7'%20stop-color='%23007EFF'/%3e%3c/linearGradient%3e%3cclipPath%20id='clip0_4363_9194'%3e%3crect%20width='64'%20height='64'%20fill='white'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e`,$t=`data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20256%20256'%20role='img'%20aria-label='File%20Manager'%3e%3cdefs%3e%3clinearGradient%20id='folder-tab'%20x1='28'%20y1='42'%20x2='139'%20y2='99'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20offset='0'%20stop-color='%23EAA900'/%3e%3cstop%20offset='1'%20stop-color='%23FFD347'/%3e%3c/linearGradient%3e%3clinearGradient%20id='folder-front'%20x1='30'%20y1='86'%20x2='226'%20y2='213'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20offset='0'%20stop-color='%23FFD85A'/%3e%3cstop%20offset='0.58'%20stop-color='%23FFC32B'/%3e%3cstop%20offset='1'%20stop-color='%23F2A700'/%3e%3c/linearGradient%3e%3clinearGradient%20id='folder-blue'%20x1='75'%20y1='139'%20x2='152'%20y2='207'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20offset='0'%20stop-color='%2327A8F7'/%3e%3cstop%20offset='1'%20stop-color='%230068B7'/%3e%3c/linearGradient%3e%3cfilter%20id='folder-shadow'%20x='12'%20y='35'%20width='232'%20height='190'%20color-interpolation-filters='sRGB'%20filterUnits='userSpaceOnUse'%3e%3cfeDropShadow%20dx='0'%20dy='4'%20stdDeviation='5'%20flood-color='%230F172A'%20flood-opacity='.18'/%3e%3c/filter%3e%3c/defs%3e%3cg%20filter='url(%23folder-shadow)'%3e%3cpath%20fill='url(%23folder-tab)'%20d='M25%2067.7C25%2055.2%2035.2%2045%2047.7%2045h50.8c7.7%200%2014.9%203.8%2019.1%2010.2l9.8%2014.6h80.9c12.5%200%2022.7%2010.2%2022.7%2022.7v15.2H25v-40Z'/%3e%3cpath%20fill='%23D89600'%20d='M25%2092h206v25H25z'%20opacity='.55'/%3e%3cpath%20fill='url(%23folder-front)'%20d='M25%2094.3h206v91C231%20198%20220.7%20208%20208.3%20208H47.7C35.2%20208%2025%20197.8%2025%20185.3v-91Z'/%3e%3cpath%20fill='%23FFE584'%20d='M35%20105h186v18H35z'%20opacity='.35'/%3e%3crect%20width='93'%20height='61'%20x='61'%20y='134'%20fill='url(%23folder-blue)'%20rx='8'/%3e%3cpath%20fill='%230B5FA9'%20d='M70%20151h75v8H70zm0%2018h60v8H70z'%20opacity='.95'/%3e%3cpath%20fill='%2372C7FF'%20d='M71%20143h72a5%205%200%200%201%205%205v2H66v-2a5%205%200%200%201%205-5Z'%20opacity='.55'/%3e%3c/g%3e%3c/svg%3e`,en=`/assets/vscode-C_7wk1WI.svg`,tn=`quickforge:project-open-target`;function J(){if(typeof window>`u`)return`vscode`;let e=window.localStorage.getItem(tn);return e===`explorer`||e===`idea`?e:`vscode`}function nn({project:e,disabled:t,disabledTargets:n,targetDisabledLabel:r,onOpenInExplorer:i,onOpenInVSCode:a,onOpenInIDEA:o}){let[s,c]=(0,H.useState)(!1),[l,u]=(0,H.useState)(J),d=(0,H.useRef)(null),f=t||!e?.id,p=!!n?.[l],m=l===`explorer`?$t:l===`idea`?Qt:en,h=p&&r?r:W(l===`explorer`?`openInExplorer`:l===`idea`?`openInIDEA`:`openInVSCode`);(0,H.useEffect)(()=>{if(!s)return;let e=e=>{d.current?.contains(e.target)||c(!1)},t=e=>{e.key===`Escape`&&c(!1)};return document.addEventListener(`pointerdown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`pointerdown`,e),document.removeEventListener(`keydown`,t)}},[s]);let g=e=>{u(e),window.localStorage.setItem(tn,e),c(!1)};return(0,K.jsxs)(`div`,{ref:d,className:`relative shrink-0`,children:[(0,K.jsxs)(`div`,{className:G(`inline-flex h-8 overflow-hidden rounded-xl border border-[color-mix(in_oklab,var(--border)_38%,transparent)] bg-background/90 text-foreground transition-colors`,s&&`border-[color-mix(in_oklab,var(--border)_50%,transparent)] bg-background`,f&&`opacity-50`),children:[(0,K.jsx)(`button`,{type:`button`,className:`flex h-full w-8 items-center justify-center bg-background/90 transition-colors hover:bg-muted/25 disabled:pointer-events-none`,disabled:f||p,onClick:()=>{if(e){if(l===`explorer`){i(e);return}if(l===`idea`){o(e);return}a(e)}},"aria-label":h,title:h,children:(0,K.jsx)(`img`,{src:m,alt:``,className:`size-4`,draggable:!1})}),(0,K.jsx)(`button`,{type:`button`,className:`flex h-full w-7 items-center justify-center border-l border-[color-mix(in_oklab,var(--border)_34%,transparent)] bg-muted/18 transition-colors hover:bg-muted/35 disabled:pointer-events-none`,disabled:f,onClick:()=>c(e=>!e),"aria-label":W(`chooseWorkspaceOpenTarget`),title:W(`chooseWorkspaceOpenTarget`),"aria-haspopup":`menu`,"aria-expanded":s,children:(0,K.jsx)(y,{className:G(`size-3.5 text-muted-foreground/85 transition-transform`,s&&`rotate-180 text-foreground/85`)})})]}),s&&e?(0,K.jsxs)(`div`,{className:`absolute right-0 top-10 z-50 w-52 overflow-hidden rounded-2xl border border-[color-mix(in_oklab,var(--border)_38%,transparent)] bg-popover py-1.5 text-popover-foreground shadow-quickforge`,role:`menu`,children:[(0,K.jsxs)(`button`,{type:`button`,className:`flex h-10 w-full items-center gap-3 px-3 text-left text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground`,onClick:()=>g(`explorer`),role:`menuitem`,children:[(0,K.jsx)(`img`,{src:$t,alt:``,className:`size-5 shrink-0`,draggable:!1}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:W(`fileManager`)}),l===`explorer`?(0,K.jsx)(S,{className:`size-4 shrink-0 text-muted-foreground`}):null]}),(0,K.jsxs)(`button`,{type:`button`,className:`flex h-10 w-full items-center gap-3 px-3 text-left text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-45`,onClick:()=>g(`vscode`),disabled:!!n?.vscode,title:n?.vscode?r:void 0,role:`menuitem`,children:[(0,K.jsx)(`img`,{src:en,alt:``,className:`size-5 shrink-0`,draggable:!1}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:`VS Code`}),l===`vscode`?(0,K.jsx)(S,{className:`size-4 shrink-0 text-muted-foreground`}):null]}),(0,K.jsxs)(`button`,{type:`button`,className:`flex h-10 w-full items-center gap-3 px-3 text-left text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-45`,onClick:()=>g(`idea`),disabled:!!n?.idea,title:n?.idea?r:void 0,role:`menuitem`,children:[(0,K.jsx)(`img`,{src:Qt,alt:``,className:`size-5 shrink-0`,draggable:!1}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:`IntelliJ IDEA`}),l===`idea`?(0,K.jsx)(S,{className:`size-4 shrink-0 text-muted-foreground`}):null]})]}):null]})}var rn=class extends Fe{static properties={label:{type:String}};_open=!1;_popover=null;_hoverTimer;createRenderRoot(){return this}_clearHoverTimer(){this._hoverTimer&&=(clearTimeout(this._hoverTimer),void 0)}_openPopover(){this._clearHoverTimer(),!this._open&&(this._open=!0,this._renderPopover(),this._updateTriggerAria())}_closePopover(){this._clearHoverTimer(),this._open&&(this._open=!1,this._removePopover(),this._updateTriggerAria())}_togglePopover(){this._clearHoverTimer(),this._open?this._closePopover():this._openPopover()}_updateTriggerAria(){this.querySelector(`.quickforge-info-tip-trigger`)?.setAttribute(`aria-expanded`,this._open?`true`:`false`)}_renderPopover(){if(this._removePopover(),!this.label)return;let e=this.querySelector(`.quickforge-info-tip-trigger`);if(!e)return;let t=document.createElement(`div`);t.className=`quickforge-info-tip-popover`,t.setAttribute(`role`,`tooltip`),t.textContent=this.label,document.body.appendChild(t),this._popover=t,this._positionPopover(e,t)}_positionPopover(e,t){let n=e.getBoundingClientRect(),{width:r,height:i}=t.getBoundingClientRect(),a=n.left;a+r>window.innerWidth-8&&(a=window.innerWidth-r-8),a<8&&(a=8);let o=n.bottom+6;if(o+i>window.innerHeight-8){let e=n.top-6-i;o=e>8?e:n.bottom+6}t.style.top=`${Math.round(o)}px`,t.style.left=`${Math.round(a)}px`}_removePopover(){this._popover&&=(this._popover.remove(),null)}_handleEnter=()=>{this._clearHoverTimer(),this._hoverTimer=setTimeout(()=>this._openPopover(),150)};_handleLeave=()=>{this._clearHoverTimer(),this._hoverTimer=setTimeout(()=>this._closePopover(),120)};_handleFocus=()=>{this._clearHoverTimer(),this._openPopover()};_handleOutsidePointerDown=e=>{if(!this._open)return;let t=e.target;t&&(this.contains(t)||this._popover?.contains(t))||this._closePopover()};_handleKeyDown=e=>{!this._open||e.key!==`Escape`||(e.preventDefault(),e.stopPropagation(),this._closePopover())};_handleScrollOrResize=()=>{if(!this._open)return;let e=this.querySelector(`.quickforge-info-tip-trigger`);e&&this._popover&&this._positionPopover(e,this._popover)};connectedCallback(){super.connectedCallback(),document.addEventListener(`pointerdown`,this._handleOutsidePointerDown,!0),document.addEventListener(`keydown`,this._handleKeyDown,!0),window.addEventListener(`scroll`,this._handleScrollOrResize,!0),window.addEventListener(`resize`,this._handleScrollOrResize)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(`pointerdown`,this._handleOutsidePointerDown,!0),document.removeEventListener(`keydown`,this._handleKeyDown,!0),window.removeEventListener(`scroll`,this._handleScrollOrResize,!0),window.removeEventListener(`resize`,this._handleScrollOrResize),this._clearHoverTimer(),this._removePopover()}render(){return Pe`
|
|
23
|
+
<span class="quickforge-info-tip">
|
|
24
|
+
<button
|
|
25
|
+
type="button"
|
|
26
|
+
class="quickforge-info-tip-trigger"
|
|
27
|
+
aria-label=${W(`help`)}
|
|
28
|
+
aria-expanded="false"
|
|
29
|
+
@mouseenter=${this._handleEnter}
|
|
30
|
+
@mouseleave=${this._handleLeave}
|
|
31
|
+
@focus=${this._handleFocus}
|
|
32
|
+
@blur=${this._handleLeave}
|
|
33
|
+
@click=${this._togglePopover}
|
|
34
|
+
>
|
|
35
|
+
<svg
|
|
36
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
37
|
+
width="14"
|
|
38
|
+
height="14"
|
|
39
|
+
viewBox="0 0 24 24"
|
|
40
|
+
fill="none"
|
|
41
|
+
stroke="currentColor"
|
|
42
|
+
stroke-width="2"
|
|
43
|
+
stroke-linecap="round"
|
|
44
|
+
stroke-linejoin="round"
|
|
45
|
+
aria-hidden="true"
|
|
46
|
+
>
|
|
47
|
+
<circle cx="12" cy="12" r="10" />
|
|
48
|
+
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" />
|
|
49
|
+
<path d="M12 17h.01" />
|
|
50
|
+
</svg>
|
|
51
|
+
</button>
|
|
52
|
+
</span>
|
|
53
|
+
`}},an=`quickforge-info-tip`;customElements.get(an)||customElements.define(an,rn);function on({label:e}){return(0,H.createElement)(`quickforge-info-tip`,{label:e})}var sn=new Set;function cn(e){return typeof e[Symbol.iterator]==`function`}var ln=class{baseUrl;blockedStores;storeOverrides;fakeProviderKeys;constructor(e=``,t=sn){this.baseUrl=e,cn(t)?(this.blockedStores=new Set(t),this.storeOverrides={},this.fakeProviderKeys=new Set):(this.blockedStores=new Set(t.blockedStores??sn),this.storeOverrides=t.storeOverrides??{},this.fakeProviderKeys=new Set(t.fakeProviderKeys??[]))}assertStoreAccess(e){if(this.blockedStores.has(e))throw Error(`This storage area is not available in the current page.`)}static async isAvailable(e=``){let t=new AbortController,n=window.setTimeout(()=>t.abort(),1e3);try{let n=await fetch(`${e}/api/health`,{method:`GET`,cache:`no-store`,signal:t.signal});return n.ok?(await n.json().catch(()=>null))?.ok===!0:!1}catch{return!1}finally{window.clearTimeout(n)}}path(...e){return`${this.baseUrl}/api/storage/${e.map(e=>encodeURIComponent(e)).join(`/`)}`}async request(e,t){let n=await fetch(e,{...t,cache:`no-store`,headers:{...t?.body?{"content-type":`application/json`}:void 0,...t?.headers}}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||`Local storage request failed: ${n.status}`);return r}async get(e,t){if(e===`provider-keys`&&this.fakeProviderKeys.has(t))return`shared-server-managed-key`;let n=this.storeOverrides[e];return n?.get?n.get(t):(this.assertStoreAccess(e),(await this.request(this.path(e,`key`,t))).value??null)}async set(e,t,n){this.assertStoreAccess(e),await this.request(this.path(e,`key`,t),{method:`PUT`,body:JSON.stringify({value:n})})}async delete(e,t){this.assertStoreAccess(e),await this.request(this.path(e,`key`,t),{method:`DELETE`})}async keys(e,t){if(e===`provider-keys`&&this.fakeProviderKeys.size>0)return[...this.fakeProviderKeys];let n=this.storeOverrides[e];if(n?.keys)return n.keys(t);this.assertStoreAccess(e);let r=t?`?prefix=${encodeURIComponent(t)}`:``;return(await this.request(`${this.path(e,`keys`)}${r}`)).keys}async getAllFromIndex(e,t,n=`asc`){return this.assertStoreAccess(e),(await this.request(`${this.path(e,`index`,t)}?direction=${encodeURIComponent(n)}`)).values}async fetchPaginatedFromIndex(e,t,n){this.assertStoreAccess(e);let r=new URLSearchParams;return r.set(`direction`,n.direction||`desc`),r.set(`limit`,String(n.limit)),r.set(`offset`,String(n.offset)),n.scope&&r.set(`scope`,n.scope),n.projectId&&r.set(`projectId`,n.projectId),n.archived&&r.set(`archived`,n.archived),n.pinned&&r.set(`pinned`,n.pinned),this.request(`${this.path(e,`index`,t)}?${r.toString()}`)}async clear(e){this.assertStoreAccess(e),await this.request(this.path(e),{method:`DELETE`})}async has(e,t){if(e===`provider-keys`&&this.fakeProviderKeys.has(t))return!0;let n=this.storeOverrides[e];return n?.has?n.has(t):(this.assertStoreAccess(e),(await this.request(this.path(e,`has`,t))).exists)}async transaction(e,t,n){for(let t of e)t===`provider-keys`&&this.fakeProviderKeys.size>0||this.storeOverrides[t]||this.assertStoreAccess(t);return n({get:(e,t)=>this.get(e,t),set:(e,t,n)=>this.set(e,t,n),delete:(e,t)=>this.delete(e,t)})}async getQuotaInfo(){return this.request(`${this.baseUrl}/api/storage/quota`)}async requestPersistence(){return!0}},un=`quickforge:model-list-cache:v1`,dn=1,fn=600*1e3,Y=null;function pn(){if(Y)return Y;try{let e=globalThis.localStorage?.getItem(un);if(!e)return null;let t=JSON.parse(e);return t.v!==dn||!Array.isArray(t.models)?null:(Y=t,t)}catch{return null}}function mn(e=fn){let t=pn();return!t||Date.now()-t.cachedAt>e?null:t.models}function hn(){return pn()?.models??null}function gn(e){let t={v:dn,cachedAt:Date.now(),models:e};Y=t;try{globalThis.localStorage?.setItem(un,JSON.stringify(t))}catch{}}function _n(){Y=null;try{globalThis.localStorage?.removeItem(un)}catch{}}typeof window<`u`&&window.addEventListener(`storage`,e=>{e.key===un&&(Y=null)});function vn(e){return(e??``).trim().replace(/\/$/,``)}function yn(e,t){return e.id===t.id&&e.provider===t.provider&&e.api===t.api&&vn(e.baseUrl)===vn(t.baseUrl)}function bn(e,t,...n){let r=[];for(let i of n)for(let n of i){if(!t(n))continue;let i=e(n);r.some(e=>yn(e,i))||r.push(i)}return r}function xn(e){return e.quickforgeHidden!==!0}function Sn(e){return e.filter(xn)}function X(){if(typeof crypto<`u`&&typeof crypto.randomUUID==`function`)return crypto.randomUUID();let e=new Uint8Array(16);if(typeof crypto<`u`&&typeof crypto.getRandomValues==`function`)crypto.getRandomValues(e);else for(let t=0;t<e.length;t+=1)e[t]=Math.floor(Math.random()*256);e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,e=>e.toString(16).padStart(2,`0`));return`${t.slice(0,4).join(``)}-${t.slice(4,6).join(``)}-${t.slice(6,8).join(``)}-${t.slice(8,10).join(``)}-${t.slice(10).join(``)}`}var Cn={id:`opencode-managed`,name:`OpenCode managed model`,api:`openai-completions`,provider:`opencode`,baseUrl:`opencode://managed`,reasoning:!1,input:[`text`],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:1,maxTokens:1};function wn(){return Cn}function Tn(e){return String(e||``).trim().replace(/\/$/,``)}function En(e,t){let n=e.quickforgeModelRef,r=t.quickforgeModelRef;if(n?.source&&r?.source&&n.source===r.source){if(n.source===`cloud`)return n.catalogId===r.catalogId;if(n.source===`custom`)return n.providerId===r.providerId&&n.modelId===r.modelId}return e.id===t.id&&e.provider===t.provider&&e.api===t.api&&Tn(e.baseUrl)===Tn(t.baseUrl)}function Dn(e,t,n){if(e.length===0)return null;if(t){let n=e.find(e=>En(e,t));if(n)return n}if(n){let t=e.find(e=>En(e,n));if(t)return t}return e[0]}function On(e,t,n){return nt(e)?n.find(t=>En(t,e))??Dn([...t,...n]):t.find(t=>En(t,e))??Dn([...t,...n])}function kn(e){return{modelRef:tt(e),modelSnapshot:e}}function An(e){if(!e||typeof e!=`object`)return;let t=e,n=t.modelSnapshot||(t.id?t:void 0);if(!(!n?.id||!n.provider||!n.api||!n.baseUrl))return{...n,...t.modelRef?{quickforgeModelRef:t.modelRef}:{}}}function jn(e){return e===`opencode`?`opencode`:`quickforge`}function Mn(e){return e===!0||e===`true`?`full-access`:`default`}function Nn(e,t=`default`){return e===`default`||e===`full-access`?e:e===!0||e===`true`?`full-access`:e===!1||e===`false`||t===e?`default`:Nn(t,`default`)}function Pn(e){return e===`full-access`}function Fn(e,t){let n=e===`New chat`?W(`newChat`):e,r=t?.trim();return r?`${r} · ${n}`:n}var In=`active-model`,Ln=`agent-access-mode`,Rn=`agent-access-mode-project:`,zn=`yolo-mode`,Bn=`yolo-mode-project:`,Vn=`default-options`,Hn={id:`default-litellm-anthropic`,name:`LiteLLM Anthropic`,baseUrl:`http://localhost:4000/v1`,apiKey:``,modelId:`anthropic/claude-sonnet-4`,contextWindow:2e5,maxTokens:32768,supportsImages:!0};function Un(e,t,n=``){let r=e.toLowerCase(),i=t.toLowerCase(),a=n.toLowerCase();return r.includes(`deepseek-v4`)&&(a.includes(`deepseek`)||i.includes(`api.deepseek.com`)||i.includes(`deepseek.com`))}function Wn(){return{requiresReasoningContentOnAssistantMessages:!0,thinkingFormat:`deepseek`}}var Gn={low:`high`,medium:`high`,high:`high`,xhigh:`max`};function Kn(e,t){let n=e.toLowerCase(),r=t.toLowerCase();return n.includes(`deepseek`)||r.includes(`api.deepseek.com`)||r.includes(`deepseek.com`)?`deepseek`:r.includes(`openrouter.ai`)?`openrouter`:n===`zai`||r.includes(`bigmodel.cn`)||r.includes(`z.ai`)?`zai`:`openai`}function qn(e){let t={...e.compat,...e.reasoning===!0&&e.compat?.supportsReasoningEffort===void 0?{supportsReasoningEffort:!0}:{},thinkingFormat:e.compat?.thinkingFormat??Kn(e.provider,e.baseUrl)};return{...e,compat:t}}function Jn(e){if(e.api!==`openai-completions`)return e;let t=qn(e);return Un(t.id,t.baseUrl,t.provider)?{...t,reasoning:!0,thinkingLevelMap:{...t.thinkingLevelMap,...Gn},compat:{...t.compat,supportsReasoningEffort:!0,...Wn()}}:t}function Yn(e){let t=e.baseUrl.trim().replace(/\/$/,``),n=e.modelId.trim(),r=e.name.trim(),i=Un(n,t,r),a=e.reasoning===!0||i,o=e.supportsImages===!0?[`text`,`image`]:[`text`];return Jn({id:n,name:`${n} (${r})`,api:`openai-completions`,provider:r,baseUrl:t,reasoning:a,input:o,cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:Number(e.contextWindow)||Hn.contextWindow,maxTokens:Number(e.maxTokens)||Hn.maxTokens,thinkingLevelMap:i?Gn:void 0,compat:{supportsStore:!1,supportsDeveloperRole:!1,supportsReasoningEffort:a,supportsUsageInStreaming:!1,supportsStrictMode:!1,maxTokensField:`max_tokens`,...i?Wn():{}}})}function Xn(){return{settings:new Je,providerKeys:new Ke,sessions:new Ge,customProviders:new qe}}function Zn(e,t){e.settings.setBackend(t),e.providerKeys.setBackend(t),e.sessions.setBackend(t),e.customProviders.setBackend(t)}async function Qn(e){if(!await ln.isAvailable())throw Error(`QuickForge local service is unavailable.`);return new ln(``,e)}async function $n(e={}){let t=Xn(),n=await Qn(e.blockedStores);Zn(t,n);let r=new We(t.settings,t.providerKeys,t.sessions,t.customProviders,n);return He(r),r}async function er(e,t){let n=kn(Jn(t));await e.settings.set(In,n)}function tr(e){return e?.reasoning?`medium`:`off`}function nr(e){return e===`off`||e===`low`||e===`medium`||e===`high`||e===`xhigh`}async function rr(e,t){let n=t.model?kn(Jn(t.model)):{};await e.settings.set(Vn,{...n,thinkingLevel:nr(t.thinkingLevel)?t.thinkingLevel:void 0,harness:jn(t.harness)})}async function ir(e){let t=await e.settings.get(Vn);return!t||typeof t!=`object`?{}:{model:t.modelSnapshot?Jn(An(t)):t.model?Jn(t.model):void 0,thinkingLevel:nr(t.thinkingLevel)?t.thinkingLevel:void 0,harness:jn(t.harness)}}async function ar(e){let t=An(await e.settings.get(In));return t?Jn(t):null}function or(e,t){return(e??``).trim().replace(/\/$/,``)===(t??``).trim().replace(/\/$/,``)}function sr(e){let t=e;return!!(t?.id&&t.provider&&t.api&&t.baseUrl)}function cr(e){return e.flatMap(e=>e.models??[]).filter(sr).map(e=>Jn(e))}async function lr(e){try{let e=await rt();if(e.length)return e}catch(e){V.warn(`Failed to load model catalog, falling back to local provider store:`,e)}return cr(await e.customProviders.getAll())}async function ur(e){return Sn(await lr(e))}function dr(...e){return bn(Jn,sr,...e)}async function fr(e,t=[],n){let r=dr(await ur(e),t);return r.length===0?null:Dn(r,n,await ar(e))}function pr(e,t){return lr(e).then(e=>e.find(e=>e.id===t.id&&e.api===t.api&&e.provider===t.provider&&or(e.baseUrl,t.baseUrl)))}async function mr(e,t){try{let n=await pr(e,t);if(n)return n.reasoning===!0?Jn(n):n}catch(e){V.warn(`Failed to resolve configured model:`,e)}return Jn(t)}async function hr(e,t,n){if(!e&&!nt(t))return Jn(t);let r=[];if(nt(t))try{r=await n()}catch(e){V.warn(`Failed to load QuickForge Cloud models for new session:`,e)}let i=On(t,e?await ur(e):[],r);if(i)return i;throw Error(`No available model can be used to create a new session.`)}async function gr(e,t,n){let r=Nn(t),i=n?`${Rn}${n}`:Ln;await e.settings.set(i,r);let a=n?`${Bn}${n}`:zn;await e.settings.set(a,Pn(r))}async function _r(e,t){if(t){let n=`${Rn}${t}`,r=await e.settings.get(n);if(r!=null)return Nn(r);let i=`${Bn}${t}`,a=await e.settings.get(i);if(a!=null)return Nn(a)}let n=await e.settings.get(Ln);if(n!=null)return Nn(n);let r=await e.settings.get(zn);return r==null?(await gr(e,`default`),`default`):Nn(r)}async function vr(e,t,n){let r=t.id||X(),i={id:r,name:t.name.trim(),type:`openai-completions`,baseUrl:n.baseUrl,apiKey:t.apiKey.trim()||void 0,models:[n]};return await e.customProviders.set(i),t.apiKey.trim()&&await e.providerKeys.set(n.provider,t.apiKey.trim()),_n(),r}var yr=ke();function br(e,t){let n=document.createElement(`template`);n.innerHTML=t;let r=n.content.firstElementChild;if(!r)return;let i=e.querySelector(`svg`);i?i.replaceWith(r):e.appendChild(r)}function xr(e,t){let n=document.createElement(`template`);n.innerHTML=t;let r=Array.from(n.content.children);for(let t of Array.from(e.children))t.remove();for(let t of r)e.appendChild(t)}var Sr=()=>({text:``,attachments:[]}),Cr=e=>e.text.length>0||(e.attachments?.length??0)>0;function wr(e){try{return JSON.stringify(e)}catch{return``}}function Tr(e){let t=String(e||``);if(!t)return 0;let n=t.match(/[\u3400-\u9fff\uf900-\ufaff]/g)?.length??0,r=Math.max(0,t.length-n);return Math.ceil(n+r/3.5)}function Er(e){return e?typeof e==`string`?e:Array.isArray(e)?e.map(e=>{if(!e||typeof e!=`object`)return Er(e);let t=e;return t.type===`text`?typeof t.text==`string`?t.text:``:t.type===`thinking`?typeof t.thinking==`string`?t.thinking:``:t.type===`image`?`[image:${typeof t.mimeType==`string`?t.mimeType:`unknown`}]`:t.type===`toolCall`?`[toolCall:${typeof t.name==`string`?t.name:`unknown`}] ${wr(t.arguments)}`:wr(t)}).filter(Boolean).join(`
|
|
54
|
+
`):typeof e==`object`?wr(e):String(e):``}function Dr(e){let t=[e.role??``,Er(e.content)];return e.toolName&&t.push(e.toolName),e.toolCallId&&t.push(e.toolCallId),e.attachments!==void 0&&t.push(wr(e.attachments)),Tr(t.filter(Boolean).join(`
|
|
55
|
+
`))}function Or(e,t,n=[]){return Tr(e)+t.reduce((e,t)=>e+Dr(t),0)+Tr(wr(n))}function kr(e){if(typeof e.timestamp==`number`)return e.timestamp;if(typeof e.timestamp==`string`){let t=Date.parse(e.timestamp);return Number.isNaN(t)?0:t}return 0}function Ar(e){let t=new Date(e),n=e=>String(e).padStart(2,`0`);return`${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`}function jr(e){return e.role===`user`&&Er(e.content).includes(`<compact_summary>`)}function Mr(e){let t=0;for(let n of e)jr(n)&&(t=Math.max(t,kr(n)));return t}function Nr(e,t,n,r=[],i){let a=Mr(t),o=t.reduce((e,t)=>{let n=t.usage;return t.role!==`assistant`||!n||a>0&&kr(t)<=a?e:n},void 0),s=o?.input??o?.totalTokens??0,c=Or(e,t,r),l=Number.isFinite(Number(s))&&Number(s)>0,u=l?Number(s):c,d=u,f=l?`provider`:`estimated`,p=Math.max(0,Number(i)||4096),m=d+p,h=n>0?Math.round(m/n*1e3)/10:0,g=Math.round(142-142*Math.min(100,Math.max(0,h))/100);return{contextWindow:n,usedTokens:d,totalTokens:m,inputTokens:u,estimatedInputTokens:c,knownInputTokens:l?Number(s):0,inputTokenSource:f,reservedOutputTokens:p,percent:h,color:`hsl(${g} 72% 45%)`}}function Pr(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${Math.round(e/1e3)}K`:String(e)}function Fr(e,t){return e===t?!0:!e||!t||e.gitBranch!==t.gitBranch?!1:!e.context||!t.context?e.context===t.context:e.context.percent===t.context.percent&&e.context.color===t.context.color&&e.context.label===t.context.label&&e.context.title===t.context.title}function Ir(e){return`hsl(${Math.round(142-142*Math.min(100,Math.max(0,e))/100)} 72% 45%)`}function Lr(e,t){let n=Number(e.inputTokens)||0,r=Math.max(0,Number(e.knownInputTokens??e.providerContextTokens)||0),i=Math.max(0,Number(e.estimatedInputTokens)||0),a=Math.max(0,Number(e.reservedOutputTokens)||0),o=Math.max(0,Number(e.totalTokens)||n+a),s=Number.isFinite(Number(e.percent))?Number(e.percent):0,c=e.inputTokenSource??(r>0?`provider`:`estimated`);return{contextWindow:Math.max(0,Number(e.contextWindow)||t),usedTokens:Math.max(0,Number(e.usedTokens)||n),totalTokens:o,inputTokens:n,estimatedInputTokens:i,knownInputTokens:r,inputTokenSource:c,reservedOutputTokens:a,percent:s,color:e.color||Ir(s),isCompacted:e.isCompacted,compactedUpToIndex:e.compactedUpToIndex,originalMessageCount:e.originalMessageCount,effectiveMessageCount:e.effectiveMessageCount,breakdown:e.breakdown}}function Rr(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`)}function zr(e){let t=Math.max(0,Number(e)||0);return t>0?Pr(t):null}function Br({usage:e,contextWindow:t,serverCalculated:n,compacted:r}){let i=e.inputTokenSource===`provider`?W(`contextUsageSourceProvider`):e.inputTokenSource===`mixed`?W(`contextUsageSourceMixed`):W(`contextUsageSourceEstimated`),a=[W(`contextUsageUsed`,{percent:e.percent,used:Pr(e.totalTokens),limit:Pr(t)}),W(`contextUsageInput`,{tokens:Pr(e.inputTokens),source:i}),W(`contextUsageLocalEstimate`,{tokens:Pr(e.estimatedInputTokens)})],o=e.breakdown;return o&&(a.push(W(`contextUsageSystemPrompt`,{tokens:zr(o.systemPromptTokens)??`0`}),W(`contextUsageToolsSchema`,{tokens:zr(o.toolsTokens)??`0`}),W(`contextUsageMessages`,{tokens:zr(o.messagesTokens)??`0`})),(o.providerUsageTokens||o.trailingTokens)&&a.push(W(`contextUsageProviderBaseline`,{tokens:zr(o.providerUsageTokens)??`0`}),W(`contextUsageTrailingMessages`,{tokens:zr(o.trailingTokens)??`0`}))),a.push(W(`contextUsageReservedOutput`,{tokens:Pr(e.reservedOutputTokens)})),n&&a.push(W(`contextUsageServerCalculated`)),a.push(W(r?`contextUsageScopeCompacted`:`contextUsageScopeFull`)),r&&e.originalMessageCount!==void 0&&e.effectiveMessageCount!==void 0&&a.push(W(`contextUsageEffectiveMessages`,{effective:e.effectiveMessageCount,visible:e.originalMessageCount})),e.knownInputTokens&&e.knownInputTokens>0&&a.push(W(`contextUsageProviderTokens`,{tokens:Pr(e.knownInputTokens)})),a.join(`
|
|
56
|
+
`)}function Vr(){let e=null,t=null,n=null,r=``,i,a=null,o=()=>b(),s=()=>x(),c=()=>v(),l=()=>x(),u=t=>{t.key!==`Enter`&&t.key!==` `||(t.preventDefault(),e?y():v())},d=t=>{t.preventDefault(),t.stopPropagation(),e?y():v()},f=()=>{a&&=(a.removeEventListener(`mouseenter`,o),a.removeEventListener(`mouseleave`,s),a.removeEventListener(`focus`,c),a.removeEventListener(`blur`,l),a.removeEventListener(`keydown`,u),a.removeEventListener(`click`,d),null)},p=()=>{i&&=(clearTimeout(i),void 0)},m=()=>{e?.remove(),e=null,t?.setAttribute(`aria-expanded`,`false`),t?.removeAttribute(`aria-describedby`)},h=()=>{if(!t||!e)return;let n=t.getBoundingClientRect(),{width:r,height:i}=e.getBoundingClientRect(),a=n.right-r;a=Math.min(Math.max(12,a),window.innerWidth-r-12);let o=n.top-8-i;o<12&&(o=n.bottom+8),e.style.left=`${Math.round(a)}px`,e.style.top=`${Math.round(o)}px`},g=(e,t,n,r=!1)=>{let i=document.createElement(`div`);i.className=r?`quickforge-context-usage-tip-row is-subtle`:`quickforge-context-usage-tip-row`;let a=document.createElement(`span`);a.textContent=t;let o=document.createElement(`span`);o.textContent=n,i.append(a,o),e.append(i)},_=()=>{if(m(),!t||!n)return;let{usage:r,contextWindow:i,serverCalculated:a,compacted:o}=n,s=document.createElement(`div`);s.className=`quickforge-context-usage-tip`,s.id=`quickforge-context-usage-tip`,s.setAttribute(`role`,`tooltip`);let c=document.createElement(`div`);c.className=`quickforge-context-usage-tip-header`;let l=document.createElement(`span`);l.textContent=W(`contextUsageTitle`);let u=document.createElement(`span`);u.className=`quickforge-context-usage-tip-percent`,u.style.color=r.color,u.textContent=`${r.percent}%`,c.append(l,u);let d=document.createElement(`div`);d.className=`quickforge-context-usage-tip-total`,d.textContent=W(`contextUsageTotal`,{used:Pr(r.totalTokens),limit:Pr(i)});let f=document.createElement(`div`);f.className=`quickforge-context-usage-tip-section`,g(f,W(`contextUsageInputLabel`),Pr(r.inputTokens)),g(f,W(`contextUsageReservedOutputLabel`),Pr(r.reservedOutputTokens)),s.append(c,d,f);let p=r.breakdown,_=[[W(`contextUsageSystemPromptLabel`),zr(p?.systemPromptTokens)],[W(`contextUsageToolsSchemaLabel`),zr(p?.toolsTokens)],[W(`contextUsageMessagesLabel`),zr(p?.messagesTokens)]].filter(e=>!!e[1]);if(_.length>0){let e=document.createElement(`div`);e.className=`quickforge-context-usage-tip-section quickforge-context-usage-tip-details`;for(let[t,n]of _)g(e,t,n,!0);s.append(e)}let v=document.createElement(`div`);v.className=`quickforge-context-usage-tip-meta`,v.textContent=`${W(a?`contextUsageSourceServerShort`:`contextUsageSourceLocalShort`)} · ${W(o?`contextUsageScopeCompactedShort`:`contextUsageScopeFullShort`)}`,s.append(v),document.body.append(s),e=s,t.setAttribute(`aria-expanded`,`true`),t.setAttribute(`aria-describedby`,s.id),h()},v=()=>{p(),_()},y=()=>{p(),m()},b=()=>{p(),i=setTimeout(v,150)},x=()=>{p(),i=setTimeout(y,120)},S=n=>{let r=n.target;r&&(t?.contains(r)||e?.contains(r))||y()},C=n=>{n.key!==`Escape`||!e||(n.preventDefault(),y(),t?.focus())},w=()=>{e&&h()};return document.addEventListener(`pointerdown`,S,!0),document.addEventListener(`keydown`,C,!0),window.addEventListener(`scroll`,w,!0),window.addEventListener(`resize`,w),{bind:(i,p)=>{let m=JSON.stringify(p),h=r!==m;n=p,r=m,t===i?e&&h&&_():(f(),t=i,a=i,i.tabIndex=0,i.setAttribute(`role`,`button`),i.setAttribute(`aria-haspopup`,`true`),i.setAttribute(`aria-expanded`,`false`),i.addEventListener(`mouseenter`,o),i.addEventListener(`mouseleave`,s),i.addEventListener(`focus`,c),i.addEventListener(`blur`,l),i.addEventListener(`keydown`,u),i.addEventListener(`click`,d))},close:y,cleanup:()=>{p(),m(),f(),document.removeEventListener(`pointerdown`,S,!0),document.removeEventListener(`keydown`,C,!0),window.removeEventListener(`scroll`,w,!0),window.removeEventListener(`resize`,w)}}}function Hr(e,t){if(!t){e.removeAttribute(`role`),e.removeAttribute(`tabindex`),e.style.cursor=``;return}e.setAttribute(`role`,`button`),e.tabIndex=0,e.style.cursor=`pointer`,!e.dataset.quickforgeGitBranchBound&&(e.dataset.quickforgeGitBranchBound=`true`,e.addEventListener(`click`,e=>{e.preventDefault(),e.stopPropagation(),t()}),e.addEventListener(`keydown`,e=>{e.key!==`Enter`&&e.key!==` `||(e.preventDefault(),e.stopPropagation(),t())}))}var Ur=(0,yr.renderToStaticMarkup)((0,H.createElement)(pe,{size:13,strokeWidth:2,"aria-hidden":!0,style:{flex:`0 0 auto`}}));function Wr({panel:e,getSystemPrompt:t,getMessages:n,getContextWindow:r,getTools:i,getMaxTokens:a,getEffectiveMessages:o,getServerContextUsage:s,getIsCompacted:c,getGitBranch:l,onGitBranchClick:u,renderInline:d=!0,renderModelRing:f=!1,onDisplayChange:p}){let m=Vr(),h,g=``,_=null,v=(e,n)=>{let r=`${n}|${t().length}|${e.length}`;for(let t of e)t.role===`toolResult`&&(r+=`|${t.toolCallId??``}:${t.toolName??``}`);return r},y=(e,n)=>{let r=v(e,n);return r===g&&_?_:(g=r,_=Nr(t(),e,n,i?.()??[],a?.()),_)},b=e=>{Fr(h,e)||(h=e,p?.(e))};return{update:()=>{let t=r(),i=n(),a=s?.(),p=a?i:o?.()??i,h=e.querySelector(`.quickforge-context-usage`),g=e.querySelector(`.quickforge-context-usage-label`),_=e.querySelector(`.quickforge-git-branch-inline`),v=d?e.querySelector(`message-editor`)?.parentElement?.querySelector(`.ml-auto.items-center`):null,x=f?e.querySelector(`.quickforge-model-trigger`):null,S=x?.parentElement??null,C=l?.()?.trim()||void 0,w={gitBranch:C};if(!d)_?.remove(),g?.remove(),f||h?.remove();else if(C&&v){let e=`${Ur}<span style="max-width: 8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${Rr(C)}</span>`,t=`Git branch: ${C}`;if(_)_.dataset.quickforgeGitBranch!==C&&(_.innerHTML=e,_.dataset.quickforgeGitBranch=C),_.title=t,_.setAttribute(`aria-label`,t),Hr(_,u);else{let n=document.createElement(`span`);n.className=`quickforge-git-branch-inline`,n.dataset.quickforgeGitBranch=C,n.title=t,n.setAttribute(`aria-label`,t),n.innerHTML=e,n.style.cssText=[`display: inline-flex`,`align-items: center`,`gap: 0.25rem`,`max-width: 10rem`,`color: hsl(var(--muted-foreground))`,`font-size: 12px`,`line-height: 1`,`font-weight: 500`].join(`;`),Hr(n,u),v.prepend(n)}}else _?.remove();if(!t)return m.close(),h?.remove(),g?.remove(),b(w),w;let T=p.length>0,E=a?Lr(a,t):T?y(p,t):{contextWindow:t,usedTokens:0,totalTokens:0,inputTokens:0,estimatedInputTokens:0,inputTokenSource:`estimated`,reservedOutputTokens:0,percent:0,color:`hsl(142 72% 45%)`},D=E.contextWindow||t,O=!!E.isCompacted||(a?!!c?.():p!==i),k=Br({usage:E,contextWindow:D,serverCalculated:!!a,compacted:O});if(w.context={percent:E.percent,color:E.color,label:`${E.percent}% · ${Pr(E.totalTokens)} / ${Pr(D)} tokens`,title:k},b(w),!d&&!f||f&&(!x||!S)||!f&&!v)return h?.remove(),g?.remove(),w;let ee=Math.min(100,Math.max(0,E.percent)),te=`conic-gradient(${E.color} ${ee*3.6}deg, color-mix(in oklab, var(--muted-foreground) 20%, transparent) 0deg)`,A=h??document.createElement(`span`);if(A.className=`quickforge-context-usage`,A.removeAttribute(`title`),A.setAttribute(`aria-label`,W(`contextUsageAriaLabel`,{percent:E.percent})),A.style.cssText=[`display: inline-flex`,`width: 14px`,`height: 14px`,`flex: 0 0 auto`,`border-radius: 9999px`,`background: ${te}`,`vertical-align: middle`,`mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 0)`,`-webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 0)`].join(`;`),A.replaceChildren(),f&&x&&S)return g?.remove(),(A.parentElement!==S||A.nextElementSibling!==x)&&S.insertBefore(A,x),m.bind(A,{usage:E,contextWindow:D,serverCalculated:!!a,compacted:O}),w;if(!v)return w;let j=A.nextElementSibling;return j?.classList.contains(`quickforge-context-usage-label`)||(j=document.createElement(`span`),j.className=`quickforge-context-usage-label`,j.style.cssText=`color: hsl(var(--muted-foreground)); font-size: 12px; line-height: 1;`),j.textContent=`${E.percent}%`,j.title=k,j.setAttribute(`aria-label`,k),h?A.nextElementSibling!==j&&A.after(j):(v.prepend(j),v.prepend(A)),w},cleanup:m.cleanup}}function Gr({hasProject:e,onConfigureModel:t,onAddProject:n,onCopyExamplePrompt:r,onDismiss:i}){return(0,K.jsx)(`div`,{className:`pointer-events-none absolute inset-0 z-20 flex items-center justify-center bg-background/35 p-3 backdrop-blur-sm sm:p-6`,children:(0,K.jsx)(`div`,{className:`pointer-events-auto w-full max-w-4xl rounded-2xl border border-border bg-background/95 p-5 shadow-quickforge backdrop-blur-md sm:p-6`,children:(0,K.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,K.jsx)(`div`,{className:`mt-0.5 flex size-10 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary`,children:(0,K.jsx)(w,{className:`size-5`})}),(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsx)(`h2`,{className:`text-base font-semibold text-foreground sm:text-lg`,children:W(`firstUseGuideTitle`)}),(0,K.jsx)(`p`,{className:`mt-1.5 text-sm leading-6 text-muted-foreground`,children:W(`firstUseGuideDescription`)})]}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:`-mr-1 -mt-1 size-7 shrink-0`,onClick:i,"aria-label":W(`firstUseGuideDismiss`),children:(0,K.jsx)(z,{className:`size-4`})})]}),(0,K.jsxs)(`div`,{className:`mt-4 grid gap-3 text-sm text-muted-foreground sm:grid-cols-3`,children:[(0,K.jsxs)(`div`,{className:`flex gap-2.5 rounded-xl border border-border/70 bg-muted/15 p-3`,children:[(0,K.jsx)(M,{className:`mt-0.5 size-4 shrink-0 text-primary`}),(0,K.jsx)(`span`,{children:W(`firstUseGuideStepModel`)})]}),(0,K.jsxs)(`div`,{className:`flex gap-2.5 rounded-xl border border-border/70 bg-muted/15 p-3`,children:[(0,K.jsx)(le,{className:`mt-0.5 size-4 shrink-0 text-primary`}),(0,K.jsx)(`span`,{children:W(`firstUseGuideStepProject`)})]}),(0,K.jsxs)(`div`,{className:`flex gap-2.5 rounded-xl border border-border/70 bg-muted/15 p-3`,children:[(0,K.jsx)(ue,{className:`mt-0.5 size-4 shrink-0 text-primary`}),(0,K.jsx)(`span`,{children:W(`firstUseGuideStepPlan`)})]})]}),(0,K.jsxs)(`div`,{className:`mt-4 flex flex-wrap gap-2.5`,children:[(0,K.jsxs)(q,{size:`sm`,onClick:t,children:[(0,K.jsx)(M,{className:`size-4`}),W(`firstUseGuideConfigureModel`)]}),(0,K.jsxs)(q,{size:`sm`,variant:e?`outline`:`default`,onClick:n,children:[(0,K.jsx)(le,{className:`size-4`}),W(`firstUseGuideAddProject`)]}),(0,K.jsxs)(q,{size:`sm`,variant:`outline`,onClick:r,children:[(0,K.jsx)(we,{className:`size-4`}),W(`firstUseGuideCopyPrompt`)]}),(0,K.jsx)(q,{size:`sm`,variant:`ghost`,onClick:i,children:W(`firstUseGuideDismiss`)})]})]})]})})})}function Kr({onAddModel:e,onUseExample:t}){return(0,K.jsx)(`div`,{className:`flex min-h-0 flex-1 items-center justify-center p-6`,children:(0,K.jsxs)(`div`,{className:`w-full max-w-xl rounded-xl border border-border bg-background p-6 text-center`,children:[(0,K.jsx)(`div`,{className:`mx-auto flex size-12 items-center justify-center rounded-2xl bg-primary/10 text-primary`,children:(0,K.jsx)(w,{className:`size-6`})}),(0,K.jsx)(`h2`,{className:`mt-4 text-lg font-medium text-foreground`,children:W(`modelSetupTitle`)}),(0,K.jsx)(`p`,{className:`mx-auto mt-2 max-w-md text-sm leading-6 text-muted-foreground`,children:W(`modelSetupDescription`)}),(0,K.jsxs)(`div`,{className:`mt-5 grid gap-3 rounded-xl border border-border bg-muted/20 p-4 text-left text-sm`,children:[(0,K.jsxs)(`div`,{className:`flex gap-3`,children:[(0,K.jsx)(j,{className:`mt-0.5 size-4 shrink-0 text-primary`}),(0,K.jsx)(`span`,{className:`text-muted-foreground`,children:W(`modelSetupSupports`)})]}),(0,K.jsxs)(`div`,{className:`flex gap-3`,children:[(0,K.jsx)(te,{className:`mt-0.5 size-4 shrink-0 text-primary`}),(0,K.jsx)(`span`,{className:`text-muted-foreground`,children:W(`modelSetupLocalStorage`)})]})]}),(0,K.jsxs)(`div`,{className:`mt-6 flex flex-col justify-center gap-3 sm:flex-row`,children:[(0,K.jsxs)(q,{onClick:e,className:`gap-2`,children:[(0,K.jsx)(o,{className:`size-4`}),W(`modelSetupAddModel`)]}),(0,K.jsx)(q,{variant:`outline`,onClick:t,children:W(`modelSetupUseLiteLlmExample`)})]})]})})}var qr=Ee();function Jr({projects:e,selectedProject:t,onSelectProject:n,onClearProject:r,onNewProject:i,className:a}){let o=(0,H.useRef)(null),s=(0,H.useRef)(null),c=(0,H.useRef)(null),[l,u]=(0,H.useState)(!1),[d,f]=(0,H.useState)(``),[p,m]=(0,H.useState)(),h=t,g=h?.id,_=(0,H.useMemo)(()=>{let t=d.trim().toLowerCase();return t?e.filter(e=>{let n=e.name.toLowerCase(),r=e.path.toLowerCase();return n.includes(t)||r.includes(t)}):e},[e,d]),v=(0,H.useCallback)(()=>{let e=s.current;if(!e)return;let t=e.getBoundingClientRect(),n=Math.min(350,window.innerWidth-24);m({position:`fixed`,left:Math.min(Math.max(12,t.left),window.innerWidth-n-12),bottom:Math.max(12,window.innerHeight-t.top+10),width:n})},[]);(0,H.useEffect)(()=>{if(!l)return;v();let e=()=>v();return window.addEventListener(`resize`,e),window.addEventListener(`scroll`,e,!0),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`scroll`,e,!0)}},[l,v]),(0,H.useEffect)(()=>{if(!l)return;let e=e=>{let t=e.target;!o.current?.contains(t)&&!c.current?.contains(t)&&u(!1)},t=e=>{e.key===`Escape`&&u(!1)};return document.addEventListener(`pointerdown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`pointerdown`,e),document.removeEventListener(`keydown`,t)}},[l]);let y=e=>{u(!1),n(e)},b=()=>{u(!1),i()},x={ref:s,role:`button`,tabIndex:0,onClick:(0,H.useCallback)(()=>{u(e=>!e)},[]),onKeyDown:(0,H.useCallback)(e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),u(e=>!e))},[]),"aria-haspopup":`menu`,"aria-expanded":l},C=l&&p?(0,K.jsxs)(`div`,{ref:c,className:`quickforge-project-picker-popover`,style:p,role:`menu`,children:[(0,K.jsxs)(`label`,{className:`quickforge-project-picker-search`,children:[(0,K.jsx)(Se,{className:`size-4`,"aria-hidden":`true`}),(0,K.jsx)(`input`,{value:d,onChange:e=>f(e.target.value),placeholder:W(`searchProjects`),autoFocus:!0})]}),(0,K.jsx)(`div`,{className:`quickforge-project-picker-list`,children:_.length>0?_.map(e=>(0,K.jsxs)(`button`,{type:`button`,className:`quickforge-project-picker-item`,onClick:()=>y(e),role:`menuitem`,children:[(0,K.jsx)(A,{className:`size-4 quickforge-project-picker-item-leading`,"aria-hidden":`true`}),(0,K.jsx)(`span`,{className:`truncate`,children:e.name}),g===e.id?(0,K.jsx)(S,{className:`ml-auto size-4`,"aria-hidden":`true`}):null]},e.id)):(0,K.jsx)(`div`,{className:`quickforge-project-picker-empty`,children:W(`noMatchingProjects`)})}),(0,K.jsx)(`div`,{className:`quickforge-project-picker-separator`}),(0,K.jsxs)(`button`,{type:`button`,className:`quickforge-project-picker-item quickforge-project-picker-item-emphasis`,onClick:b,role:`menuitem`,children:[(0,K.jsx)(A,{className:`size-4 quickforge-project-picker-item-leading`,"aria-hidden":`true`}),(0,K.jsx)(`span`,{className:`truncate`,children:W(`selectProjectDirectory`)})]})]}):null;return(0,K.jsxs)(`div`,{ref:o,className:G(`quickforge-empty-project-picker`,l?`quickforge-empty-project-picker-open`:void 0,a),children:[(0,K.jsx)(`div`,{className:`quickforge-empty-project-trigger`,children:g?(0,K.jsxs)(`span`,{className:`quickforge-empty-project-chip`,...x,children:[(0,K.jsxs)(`span`,{className:`quickforge-empty-project-chip-action`,children:[(0,K.jsx)(A,{className:`size-3.5 quickforge-empty-project-chip-folder`,"aria-hidden":`true`}),(0,K.jsx)(`button`,{type:`button`,className:`quickforge-empty-project-chip-clear`,onClick:e=>{e.stopPropagation(),u(!1),r()},"aria-label":W(`useNoProject`),title:W(`useNoProject`),children:(0,K.jsx)(z,{className:`size-3`,"aria-hidden":`true`})})]}),(0,K.jsx)(`span`,{className:`truncate`,children:h?.name})]}):(0,K.jsxs)(`span`,{className:`quickforge-empty-project-pill`,...x,children:[(0,K.jsx)(A,{className:`size-4`,"aria-hidden":`true`}),(0,K.jsx)(`span`,{className:`truncate`,children:W(`chooseProject`)})]})}),typeof document<`u`?(0,qr.createPortal)(C,document.body):null]})}function Yr(){var e=[...arguments];return(0,H.useMemo)(()=>t=>{e.forEach(e=>e(t))},e)}var Z=typeof window<`u`&&window.document!==void 0&&window.document.createElement!==void 0;function Xr(e){let t=Object.prototype.toString.call(e);return t===`[object Window]`||t===`[object global]`}function Zr(e){return`nodeType`in e}function Qr(e){return e?Xr(e)?e:Zr(e)?e.ownerDocument?.defaultView??window:window:window}function $r(e){let{Document:t}=Qr(e);return e instanceof t}function ei(e){return Xr(e)?!1:e instanceof Qr(e).HTMLElement}function ti(e){return e instanceof Qr(e).SVGElement}function ni(e){return e?Xr(e)?e.document:Zr(e)?$r(e)?e:ei(e)||ti(e)?e.ownerDocument:document:document:document}var ri=Z?H.useLayoutEffect:H.useEffect;function ii(e){let t=(0,H.useRef)(e);return ri(()=>{t.current=e}),(0,H.useCallback)(function(){var e=[...arguments];return t.current==null?void 0:t.current(...e)},[])}function ai(){let e=(0,H.useRef)(null);return[(0,H.useCallback)((t,n)=>{e.current=setInterval(t,n)},[]),(0,H.useCallback)(()=>{e.current!==null&&(clearInterval(e.current),e.current=null)},[])]}function oi(e,t){t===void 0&&(t=[e]);let n=(0,H.useRef)(e);return ri(()=>{n.current!==e&&(n.current=e)},t),n}function si(e,t){let n=(0,H.useRef)();return(0,H.useMemo)(()=>{let t=e(n.current);return n.current=t,t},[...t])}function ci(e){let t=ii(e),n=(0,H.useRef)(null);return[n,(0,H.useCallback)(e=>{e!==n.current&&t?.(e,n.current),n.current=e},[])]}function li(e){let t=(0,H.useRef)();return(0,H.useEffect)(()=>{t.current=e},[e]),t.current}var ui={};function di(e,t){return(0,H.useMemo)(()=>{if(t)return t;let n=ui[e]==null?0:ui[e]+1;return ui[e]=n,e+`-`+n},[e,t])}function fi(e){return function(t){return[...arguments].slice(1).reduce((t,n)=>{let r=Object.entries(n);for(let[n,i]of r){let r=t[n];r!=null&&(t[n]=r+e*i)}return t},{...t})}}var pi=fi(1),mi=fi(-1);function hi(e){return`clientX`in e&&`clientY`in e}function gi(e){if(!e)return!1;let{KeyboardEvent:t}=Qr(e.target);return t&&e instanceof t}function _i(e){if(!e)return!1;let{TouchEvent:t}=Qr(e.target);return t&&e instanceof t}function vi(e){if(_i(e)){if(e.touches&&e.touches.length){let{clientX:t,clientY:n}=e.touches[0];return{x:t,y:n}}else if(e.changedTouches&&e.changedTouches.length){let{clientX:t,clientY:n}=e.changedTouches[0];return{x:t,y:n}}}return hi(e)?{x:e.clientX,y:e.clientY}:null}var yi=Object.freeze({Translate:{toString(e){if(!e)return;let{x:t,y:n}=e;return`translate3d(`+(t?Math.round(t):0)+`px, `+(n?Math.round(n):0)+`px, 0)`}},Scale:{toString(e){if(!e)return;let{scaleX:t,scaleY:n}=e;return`scaleX(`+t+`) scaleY(`+n+`)`}},Transform:{toString(e){if(e)return[yi.Translate.toString(e),yi.Scale.toString(e)].join(` `)}},Transition:{toString(e){let{property:t,duration:n,easing:r}=e;return t+` `+n+`ms `+r}}}),bi=`a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]`;function xi(e){return e.matches(bi)?e:e.querySelector(bi)}var Si={display:`none`};function Ci(e){let{id:t,value:n}=e;return H.createElement(`div`,{id:t,style:Si},n)}function wi(e){let{id:t,announcement:n,ariaLiveType:r=`assertive`}=e;return H.createElement(`div`,{id:t,style:{position:`fixed`,top:0,left:0,width:1,height:1,margin:-1,border:0,padding:0,overflow:`hidden`,clip:`rect(0 0 0 0)`,clipPath:`inset(100%)`,whiteSpace:`nowrap`},role:`status`,"aria-live":r,"aria-atomic":!0},n)}function Ti(){let[e,t]=(0,H.useState)(``);return{announce:(0,H.useCallback)(e=>{e!=null&&t(e)},[]),announcement:e}}var Ei=(0,H.createContext)(null);function Di(e){let t=(0,H.useContext)(Ei);(0,H.useEffect)(()=>{if(!t)throw Error(`useDndMonitor must be used within a children of <DndContext>`);return t(e)},[e,t])}function Oi(){let[e]=(0,H.useState)(()=>new Set),t=(0,H.useCallback)(t=>(e.add(t),()=>e.delete(t)),[e]);return[(0,H.useCallback)(t=>{let{type:n,event:r}=t;e.forEach(e=>e[n]?.call(e,r))},[e]),t]}var ki={draggable:`
|
|
57
|
+
To pick up a draggable item, press the space bar.
|
|
58
|
+
While dragging, use the arrow keys to move the item.
|
|
59
|
+
Press space again to drop the item in its new position, or press escape to cancel.
|
|
60
|
+
`},Ai={onDragStart(e){let{active:t}=e;return`Picked up draggable item `+t.id+`.`},onDragOver(e){let{active:t,over:n}=e;return n?`Draggable item `+t.id+` was moved over droppable area `+n.id+`.`:`Draggable item `+t.id+` is no longer over a droppable area.`},onDragEnd(e){let{active:t,over:n}=e;return n?`Draggable item `+t.id+` was dropped over droppable area `+n.id:`Draggable item `+t.id+` was dropped.`},onDragCancel(e){let{active:t}=e;return`Dragging was cancelled. Draggable item `+t.id+` was dropped.`}};function ji(e){let{announcements:t=Ai,container:n,hiddenTextDescribedById:r,screenReaderInstructions:i=ki}=e,{announce:a,announcement:o}=Ti(),s=di(`DndLiveRegion`),[c,l]=(0,H.useState)(!1);if((0,H.useEffect)(()=>{l(!0)},[]),Di((0,H.useMemo)(()=>({onDragStart(e){let{active:n}=e;a(t.onDragStart({active:n}))},onDragMove(e){let{active:n,over:r}=e;t.onDragMove&&a(t.onDragMove({active:n,over:r}))},onDragOver(e){let{active:n,over:r}=e;a(t.onDragOver({active:n,over:r}))},onDragEnd(e){let{active:n,over:r}=e;a(t.onDragEnd({active:n,over:r}))},onDragCancel(e){let{active:n,over:r}=e;a(t.onDragCancel({active:n,over:r}))}}),[a,t])),!c)return null;let u=H.createElement(H.Fragment,null,H.createElement(Ci,{id:r,value:i.draggable}),H.createElement(wi,{id:s,announcement:o}));return n?(0,qr.createPortal)(u,n):u}var Mi;(function(e){e.DragStart=`dragStart`,e.DragMove=`dragMove`,e.DragEnd=`dragEnd`,e.DragCancel=`dragCancel`,e.DragOver=`dragOver`,e.RegisterDroppable=`registerDroppable`,e.SetDroppableDisabled=`setDroppableDisabled`,e.UnregisterDroppable=`unregisterDroppable`})(Mi||={});function Ni(){}function Pi(e,t){return(0,H.useMemo)(()=>({sensor:e,options:t??{}}),[e,t])}function Fi(){var e=[...arguments];return(0,H.useMemo)(()=>[...e].filter(e=>e!=null),[...e])}var Ii=Object.freeze({x:0,y:0});function Li(e,t){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}function Ri(e,t){let{data:{value:n}}=e,{data:{value:r}}=t;return n-r}function zi(e,t){let{data:{value:n}}=e,{data:{value:r}}=t;return r-n}function Bi(e,t){if(!e||e.length===0)return null;let[n]=e;return t?n[t]:n}function Vi(e,t,n){return t===void 0&&(t=e.left),n===void 0&&(n=e.top),{x:t+e.width*.5,y:n+e.height*.5}}var Hi=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:r}=e,i=Vi(t,t.left,t.top),a=[];for(let e of r){let{id:t}=e,r=n.get(t);if(r){let n=Li(Vi(r),i);a.push({id:t,data:{droppableContainer:e,value:n}})}}return a.sort(Ri)};function Ui(e,t){let n=Math.max(t.top,e.top),r=Math.max(t.left,e.left),i=Math.min(t.left+t.width,e.left+e.width),a=Math.min(t.top+t.height,e.top+e.height),o=i-r,s=a-n;if(r<i&&n<a){let n=t.width*t.height,r=e.width*e.height,i=o*s,a=i/(n+r-i);return Number(a.toFixed(4))}return 0}var Wi=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:r}=e,i=[];for(let e of r){let{id:r}=e,a=n.get(r);if(a){let n=Ui(a,t);n>0&&i.push({id:r,data:{droppableContainer:e,value:n}})}}return i.sort(zi)};function Gi(e,t,n){return{...e,scaleX:t&&n?t.width/n.width:1,scaleY:t&&n?t.height/n.height:1}}function Ki(e,t){return e&&t?{x:e.left-t.left,y:e.top-t.top}:Ii}function qi(e){return function(t){return[...arguments].slice(1).reduce((t,n)=>({...t,top:t.top+e*n.y,bottom:t.bottom+e*n.y,left:t.left+e*n.x,right:t.right+e*n.x}),{...t})}}var Ji=qi(1);function Yi(e){if(e.startsWith(`matrix3d(`)){let t=e.slice(9,-1).split(/, /);return{x:+t[12],y:+t[13],scaleX:+t[0],scaleY:+t[5]}}else if(e.startsWith(`matrix(`)){let t=e.slice(7,-1).split(/, /);return{x:+t[4],y:+t[5],scaleX:+t[0],scaleY:+t[3]}}return null}function Xi(e,t,n){let r=Yi(t);if(!r)return e;let{scaleX:i,scaleY:a,x:o,y:s}=r,c=e.left-o-(1-i)*parseFloat(n),l=e.top-s-(1-a)*parseFloat(n.slice(n.indexOf(` `)+1)),u=i?e.width/i:e.width,d=a?e.height/a:e.height;return{width:u,height:d,top:l,right:c+u,bottom:l+d,left:c}}var Zi={ignoreTransform:!1};function Qi(e,t){t===void 0&&(t=Zi);let n=e.getBoundingClientRect();if(t.ignoreTransform){let{transform:t,transformOrigin:r}=Qr(e).getComputedStyle(e);t&&(n=Xi(n,t,r))}let{top:r,left:i,width:a,height:o,bottom:s,right:c}=n;return{top:r,left:i,width:a,height:o,bottom:s,right:c}}function $i(e){return Qi(e,{ignoreTransform:!0})}function ea(e){let t=e.innerWidth,n=e.innerHeight;return{top:0,left:0,right:t,bottom:n,width:t,height:n}}function ta(e,t){return t===void 0&&(t=Qr(e).getComputedStyle(e)),t.position===`fixed`}function na(e,t){t===void 0&&(t=Qr(e).getComputedStyle(e));let n=/(auto|scroll|overlay)/;return[`overflow`,`overflowX`,`overflowY`].some(e=>{let r=t[e];return typeof r==`string`?n.test(r):!1})}function ra(e,t){let n=[];function r(i){if(t!=null&&n.length>=t||!i)return n;if($r(i)&&i.scrollingElement!=null&&!n.includes(i.scrollingElement))return n.push(i.scrollingElement),n;if(!ei(i)||ti(i)||n.includes(i))return n;let a=Qr(e).getComputedStyle(i);return i!==e&&na(i,a)&&n.push(i),ta(i,a)?n:r(i.parentNode)}return e?r(e):n}function ia(e){let[t]=ra(e,1);return t??null}function aa(e){return!Z||!e?null:Xr(e)?e:Zr(e)?$r(e)||e===ni(e).scrollingElement?window:ei(e)?e:null:null}function oa(e){return Xr(e)?e.scrollX:e.scrollLeft}function sa(e){return Xr(e)?e.scrollY:e.scrollTop}function ca(e){return{x:oa(e),y:sa(e)}}var la;(function(e){e[e.Forward=1]=`Forward`,e[e.Backward=-1]=`Backward`})(la||={});function ua(e){return!Z||!e?!1:e===document.scrollingElement}function da(e){let t={x:0,y:0},n=ua(e)?{height:window.innerHeight,width:window.innerWidth}:{height:e.clientHeight,width:e.clientWidth},r={x:e.scrollWidth-n.width,y:e.scrollHeight-n.height};return{isTop:e.scrollTop<=t.y,isLeft:e.scrollLeft<=t.x,isBottom:e.scrollTop>=r.y,isRight:e.scrollLeft>=r.x,maxScroll:r,minScroll:t}}var fa={x:.2,y:.2};function pa(e,t,n,r,i){let{top:a,left:o,right:s,bottom:c}=n;r===void 0&&(r=10),i===void 0&&(i=fa);let{isTop:l,isBottom:u,isLeft:d,isRight:f}=da(e),p={x:0,y:0},m={x:0,y:0},h={height:t.height*i.y,width:t.width*i.x};return!l&&a<=t.top+h.height?(p.y=la.Backward,m.y=r*Math.abs((t.top+h.height-a)/h.height)):!u&&c>=t.bottom-h.height&&(p.y=la.Forward,m.y=r*Math.abs((t.bottom-h.height-c)/h.height)),!f&&s>=t.right-h.width?(p.x=la.Forward,m.x=r*Math.abs((t.right-h.width-s)/h.width)):!d&&o<=t.left+h.width&&(p.x=la.Backward,m.x=r*Math.abs((t.left+h.width-o)/h.width)),{direction:p,speed:m}}function ma(e){if(e===document.scrollingElement){let{innerWidth:e,innerHeight:t}=window;return{top:0,left:0,right:e,bottom:t,width:e,height:t}}let{top:t,left:n,right:r,bottom:i}=e.getBoundingClientRect();return{top:t,left:n,right:r,bottom:i,width:e.clientWidth,height:e.clientHeight}}function ha(e){return e.reduce((e,t)=>pi(e,ca(t)),Ii)}function ga(e){return e.reduce((e,t)=>e+oa(t),0)}function _a(e){return e.reduce((e,t)=>e+sa(t),0)}function va(e,t){if(t===void 0&&(t=Qi),!e)return;let{top:n,left:r,bottom:i,right:a}=t(e);ia(e)&&(i<=0||a<=0||n>=window.innerHeight||r>=window.innerWidth)&&e.scrollIntoView({block:`center`,inline:`center`})}var ya=[[`x`,[`left`,`right`],ga],[`y`,[`top`,`bottom`],_a]],ba=class{constructor(e,t){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;let n=ra(t),r=ha(n);this.rect={...e},this.width=e.width,this.height=e.height;for(let[e,t,i]of ya)for(let a of t)Object.defineProperty(this,a,{get:()=>{let t=i(n),o=r[e]-t;return this.rect[a]+o},enumerable:!0});Object.defineProperty(this,`rect`,{enumerable:!1})}},xa=class{constructor(e){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(e=>this.target?.removeEventListener(...e))},this.target=e}add(e,t,n){var r;(r=this.target)==null||r.addEventListener(e,t,n),this.listeners.push([e,t,n])}};function Sa(e){let{EventTarget:t}=Qr(e);return e instanceof t?e:ni(e)}function Ca(e,t){let n=Math.abs(e.x),r=Math.abs(e.y);return typeof t==`number`?Math.sqrt(n**2+r**2)>t:`x`in t&&`y`in t?n>t.x&&r>t.y:`x`in t?n>t.x:`y`in t?r>t.y:!1}var wa;(function(e){e.Click=`click`,e.DragStart=`dragstart`,e.Keydown=`keydown`,e.ContextMenu=`contextmenu`,e.Resize=`resize`,e.SelectionChange=`selectionchange`,e.VisibilityChange=`visibilitychange`})(wa||={});function Ta(e){e.preventDefault()}function Ea(e){e.stopPropagation()}var Q;(function(e){e.Space=`Space`,e.Down=`ArrowDown`,e.Right=`ArrowRight`,e.Left=`ArrowLeft`,e.Up=`ArrowUp`,e.Esc=`Escape`,e.Enter=`Enter`,e.Tab=`Tab`})(Q||={});var Da={start:[Q.Space,Q.Enter],cancel:[Q.Esc],end:[Q.Space,Q.Enter,Q.Tab]},Oa=(e,t)=>{let{currentCoordinates:n}=t;switch(e.code){case Q.Right:return{...n,x:n.x+25};case Q.Left:return{...n,x:n.x-25};case Q.Down:return{...n,y:n.y+25};case Q.Up:return{...n,y:n.y-25}}},ka=class{constructor(e){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=e;let{event:{target:t}}=e;this.props=e,this.listeners=new xa(ni(t)),this.windowListeners=new xa(Qr(t)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(wa.Resize,this.handleCancel),this.windowListeners.add(wa.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(wa.Keydown,this.handleKeyDown))}handleStart(){let{activeNode:e,onStart:t}=this.props,n=e.node.current;n&&va(n),t(Ii)}handleKeyDown(e){if(gi(e)){let{active:t,context:n,options:r}=this.props,{keyboardCodes:i=Da,coordinateGetter:a=Oa,scrollBehavior:o=`smooth`}=r,{code:s}=e;if(i.end.includes(s)){this.handleEnd(e);return}if(i.cancel.includes(s)){this.handleCancel(e);return}let{collisionRect:c}=n.current,l=c?{x:c.left,y:c.top}:Ii;this.referenceCoordinates||=l;let u=a(e,{active:t,context:n.current,currentCoordinates:l});if(u){let t=mi(u,l),r={x:0,y:0},{scrollableAncestors:i}=n.current;for(let n of i){let i=e.code,{isTop:a,isRight:s,isLeft:c,isBottom:l,maxScroll:d,minScroll:f}=da(n),p=ma(n),m={x:Math.min(i===Q.Right?p.right-p.width/2:p.right,Math.max(i===Q.Right?p.left:p.left+p.width/2,u.x)),y:Math.min(i===Q.Down?p.bottom-p.height/2:p.bottom,Math.max(i===Q.Down?p.top:p.top+p.height/2,u.y))},h=i===Q.Right&&!s||i===Q.Left&&!c,g=i===Q.Down&&!l||i===Q.Up&&!a;if(h&&m.x!==u.x){let e=n.scrollLeft+t.x,a=i===Q.Right&&e<=d.x||i===Q.Left&&e>=f.x;if(a&&!t.y){n.scrollTo({left:e,behavior:o});return}a?r.x=n.scrollLeft-e:r.x=i===Q.Right?n.scrollLeft-d.x:n.scrollLeft-f.x,r.x&&n.scrollBy({left:-r.x,behavior:o});break}else if(g&&m.y!==u.y){let e=n.scrollTop+t.y,a=i===Q.Down&&e<=d.y||i===Q.Up&&e>=f.y;if(a&&!t.x){n.scrollTo({top:e,behavior:o});return}a?r.y=n.scrollTop-e:r.y=i===Q.Down?n.scrollTop-d.y:n.scrollTop-f.y,r.y&&n.scrollBy({top:-r.y,behavior:o});break}}this.handleMove(e,pi(mi(u,this.referenceCoordinates),r))}}}handleMove(e,t){let{onMove:n}=this.props;e.preventDefault(),n(t)}handleEnd(e){let{onEnd:t}=this.props;e.preventDefault(),this.detach(),t()}handleCancel(e){let{onCancel:t}=this.props;e.preventDefault(),this.detach(),t()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}};ka.activators=[{eventName:`onKeyDown`,handler:(e,t,n)=>{let{keyboardCodes:r=Da,onActivation:i}=t,{active:a}=n,{code:o}=e.nativeEvent;if(r.start.includes(o)){let t=a.activatorNode.current;return t&&e.target!==t?!1:(e.preventDefault(),i?.({event:e.nativeEvent}),!0)}return!1}}];function Aa(e){return!!(e&&`distance`in e)}function ja(e){return!!(e&&`delay`in e)}var Ma=class{constructor(e,t,n){n===void 0&&(n=Sa(e.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=e,this.events=t;let{event:r}=e,{target:i}=r;this.props=e,this.events=t,this.document=ni(i),this.documentListeners=new xa(this.document),this.listeners=new xa(n),this.windowListeners=new xa(Qr(i)),this.initialCoordinates=vi(r)??Ii,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){let{events:e,props:{options:{activationConstraint:t,bypassActivationConstraint:n}}}=this;if(this.listeners.add(e.move.name,this.handleMove,{passive:!1}),this.listeners.add(e.end.name,this.handleEnd),e.cancel&&this.listeners.add(e.cancel.name,this.handleCancel),this.windowListeners.add(wa.Resize,this.handleCancel),this.windowListeners.add(wa.DragStart,Ta),this.windowListeners.add(wa.VisibilityChange,this.handleCancel),this.windowListeners.add(wa.ContextMenu,Ta),this.documentListeners.add(wa.Keydown,this.handleKeydown),t){if(n!=null&&n({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(ja(t)){this.timeoutId=setTimeout(this.handleStart,t.delay),this.handlePending(t);return}if(Aa(t)){this.handlePending(t);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(e,t){let{active:n,onPending:r}=this.props;r(n,e,this.initialCoordinates,t)}handleStart(){let{initialCoordinates:e}=this,{onStart:t}=this.props;e&&(this.activated=!0,this.documentListeners.add(wa.Click,Ea,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(wa.SelectionChange,this.removeTextSelection),t(e))}handleMove(e){let{activated:t,initialCoordinates:n,props:r}=this,{onMove:i,options:{activationConstraint:a}}=r;if(!n)return;let o=vi(e)??Ii,s=mi(n,o);if(!t&&a){if(Aa(a)){if(a.tolerance!=null&&Ca(s,a.tolerance))return this.handleCancel();if(Ca(s,a.distance))return this.handleStart()}if(ja(a)&&Ca(s,a.tolerance))return this.handleCancel();this.handlePending(a,s);return}e.cancelable&&e.preventDefault(),i(o)}handleEnd(){let{onAbort:e,onEnd:t}=this.props;this.detach(),this.activated||e(this.props.active),t()}handleCancel(){let{onAbort:e,onCancel:t}=this.props;this.detach(),this.activated||e(this.props.active),t()}handleKeydown(e){e.code===Q.Esc&&this.handleCancel()}removeTextSelection(){var e;(e=this.document.getSelection())==null||e.removeAllRanges()}},Na={cancel:{name:`pointercancel`},move:{name:`pointermove`},end:{name:`pointerup`}},Pa=class extends Ma{constructor(e){let{event:t}=e,n=ni(t.target);super(e,Na,n)}};Pa.activators=[{eventName:`onPointerDown`,handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;return!n.isPrimary||n.button!==0?!1:(r?.({event:n}),!0)}}];var Fa={move:{name:`mousemove`},end:{name:`mouseup`}},Ia;(function(e){e[e.RightClick=2]=`RightClick`})(Ia||={});var La=class extends Ma{constructor(e){super(e,Fa,ni(e.event.target))}};La.activators=[{eventName:`onMouseDown`,handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;return n.button===Ia.RightClick?!1:(r?.({event:n}),!0)}}];var Ra={cancel:{name:`touchcancel`},move:{name:`touchmove`},end:{name:`touchend`}},za=class extends Ma{constructor(e){super(e,Ra)}static setup(){return window.addEventListener(Ra.move.name,e,{capture:!1,passive:!1}),function(){window.removeEventListener(Ra.move.name,e)};function e(){}}};za.activators=[{eventName:`onTouchStart`,handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t,{touches:i}=n;return i.length>1?!1:(r?.({event:n}),!0)}}];var Ba;(function(e){e[e.Pointer=0]=`Pointer`,e[e.DraggableRect=1]=`DraggableRect`})(Ba||={});var Va;(function(e){e[e.TreeOrder=0]=`TreeOrder`,e[e.ReversedTreeOrder=1]=`ReversedTreeOrder`})(Va||={});function Ha(e){let{acceleration:t,activator:n=Ba.Pointer,canScroll:r,draggingRect:i,enabled:a,interval:o=5,order:s=Va.TreeOrder,pointerCoordinates:c,scrollableAncestors:l,scrollableAncestorRects:u,delta:d,threshold:f}=e,p=Wa({delta:d,disabled:!a}),[m,h]=ai(),g=(0,H.useRef)({x:0,y:0}),_=(0,H.useRef)({x:0,y:0}),v=(0,H.useMemo)(()=>{switch(n){case Ba.Pointer:return c?{top:c.y,bottom:c.y,left:c.x,right:c.x}:null;case Ba.DraggableRect:return i}},[n,i,c]),y=(0,H.useRef)(null),b=(0,H.useCallback)(()=>{let e=y.current;if(!e)return;let t=g.current.x*_.current.x,n=g.current.y*_.current.y;e.scrollBy(t,n)},[]),x=(0,H.useMemo)(()=>s===Va.TreeOrder?[...l].reverse():l,[s,l]);(0,H.useEffect)(()=>{if(!a||!l.length||!v){h();return}for(let e of x){if(r?.(e)===!1)continue;let n=u[l.indexOf(e)];if(!n)continue;let{direction:i,speed:a}=pa(e,n,v,t,f);for(let e of[`x`,`y`])p[e][i[e]]||(a[e]=0,i[e]=0);if(a.x>0||a.y>0){h(),y.current=e,m(b,o),g.current=a,_.current=i;return}}g.current={x:0,y:0},_.current={x:0,y:0},h()},[t,b,r,h,a,o,JSON.stringify(v),JSON.stringify(p),m,l,x,u,JSON.stringify(f)])}var Ua={x:{[la.Backward]:!1,[la.Forward]:!1},y:{[la.Backward]:!1,[la.Forward]:!1}};function Wa(e){let{delta:t,disabled:n}=e,r=li(t);return si(e=>{if(n||!r||!e)return Ua;let i={x:Math.sign(t.x-r.x),y:Math.sign(t.y-r.y)};return{x:{[la.Backward]:e.x[la.Backward]||i.x===-1,[la.Forward]:e.x[la.Forward]||i.x===1},y:{[la.Backward]:e.y[la.Backward]||i.y===-1,[la.Forward]:e.y[la.Forward]||i.y===1}}},[n,t,r])}function Ga(e,t){let n=t==null?void 0:e.get(t),r=n?n.node.current:null;return si(e=>t==null?null:r??e??null,[r,t])}function Ka(e,t){return(0,H.useMemo)(()=>e.reduce((e,n)=>{let{sensor:r}=n,i=r.activators.map(e=>({eventName:e.eventName,handler:t(e.handler,n)}));return[...e,...i]},[]),[e,t])}var qa;(function(e){e[e.Always=0]=`Always`,e[e.BeforeDragging=1]=`BeforeDragging`,e[e.WhileDragging=2]=`WhileDragging`})(qa||={});var Ja;(function(e){e.Optimized=`optimized`})(Ja||={});var Ya=new Map;function Xa(e,t){let{dragging:n,dependencies:r,config:i}=t,[a,o]=(0,H.useState)(null),{frequency:s,measure:c,strategy:l}=i,u=(0,H.useRef)(e),d=g(),f=oi(d),p=(0,H.useCallback)(function(e){e===void 0&&(e=[]),!f.current&&o(t=>t===null?e:t.concat(e.filter(e=>!t.includes(e))))},[f]),m=(0,H.useRef)(null),h=si(t=>{if(d&&!n)return Ya;if(!t||t===Ya||u.current!==e||a!=null){let t=new Map;for(let n of e){if(!n)continue;if(a&&a.length>0&&!a.includes(n.id)&&n.rect.current){t.set(n.id,n.rect.current);continue}let e=n.node.current,r=e?new ba(c(e),e):null;n.rect.current=r,r&&t.set(n.id,r)}return t}return t},[e,a,n,d,c]);return(0,H.useEffect)(()=>{u.current=e},[e]),(0,H.useEffect)(()=>{d||p()},[n,d]),(0,H.useEffect)(()=>{a&&a.length>0&&o(null)},[JSON.stringify(a)]),(0,H.useEffect)(()=>{d||typeof s!=`number`||m.current!==null||(m.current=setTimeout(()=>{p(),m.current=null},s))},[s,d,p,...r]),{droppableRects:h,measureDroppableContainers:p,measuringScheduled:a!=null};function g(){switch(l){case qa.Always:return!1;case qa.BeforeDragging:return n;default:return!n}}}function Za(e,t){return si(n=>e?n||(typeof t==`function`?t(e):e):null,[t,e])}function Qa(e,t){return Za(e,t)}function $a(e){let{callback:t,disabled:n}=e,r=ii(t),i=(0,H.useMemo)(()=>{if(n||typeof window>`u`||window.MutationObserver===void 0)return;let{MutationObserver:e}=window;return new e(r)},[r,n]);return(0,H.useEffect)(()=>()=>i?.disconnect(),[i]),i}function eo(e){let{callback:t,disabled:n}=e,r=ii(t),i=(0,H.useMemo)(()=>{if(n||typeof window>`u`||window.ResizeObserver===void 0)return;let{ResizeObserver:e}=window;return new e(r)},[n]);return(0,H.useEffect)(()=>()=>i?.disconnect(),[i]),i}function to(e){return new ba(Qi(e),e)}function no(e,t,n){t===void 0&&(t=to);let[r,i]=(0,H.useState)(null);function a(){i(r=>{if(!e)return null;if(e.isConnected===!1)return r??n??null;let i=t(e);return JSON.stringify(r)===JSON.stringify(i)?r:i})}let o=$a({callback(t){if(e)for(let n of t){let{type:t,target:r}=n;if(t===`childList`&&r instanceof HTMLElement&&r.contains(e)){a();break}}}}),s=eo({callback:a});return ri(()=>{a(),e?(s?.observe(e),o?.observe(document.body,{childList:!0,subtree:!0})):(s?.disconnect(),o?.disconnect())},[e]),r}function ro(e){return Ki(e,Za(e))}var io=[];function ao(e){let t=(0,H.useRef)(e),n=si(n=>e?n&&n!==io&&e&&t.current&&e.parentNode===t.current.parentNode?n:ra(e):io,[e]);return(0,H.useEffect)(()=>{t.current=e},[e]),n}function oo(e){let[t,n]=(0,H.useState)(null),r=(0,H.useRef)(e),i=(0,H.useCallback)(e=>{let t=aa(e.target);t&&n(e=>e?(e.set(t,ca(t)),new Map(e)):null)},[]);return(0,H.useEffect)(()=>{let t=r.current;if(e!==t){a(t);let o=e.map(e=>{let t=aa(e);return t?(t.addEventListener(`scroll`,i,{passive:!0}),[t,ca(t)]):null}).filter(e=>e!=null);n(o.length?new Map(o):null),r.current=e}return()=>{a(e),a(t)};function a(e){e.forEach(e=>{aa(e)?.removeEventListener(`scroll`,i)})}},[i,e]),(0,H.useMemo)(()=>e.length?t?Array.from(t.values()).reduce((e,t)=>pi(e,t),Ii):ha(e):Ii,[e,t])}function so(e,t){t===void 0&&(t=[]);let n=(0,H.useRef)(null);return(0,H.useEffect)(()=>{n.current=null},t),(0,H.useEffect)(()=>{let t=e!==Ii;t&&!n.current&&(n.current=e),!t&&n.current&&(n.current=null)},[e]),n.current?mi(e,n.current):Ii}function co(e){(0,H.useEffect)(()=>{if(!Z)return;let t=e.map(e=>{let{sensor:t}=e;return t.setup==null?void 0:t.setup()});return()=>{for(let e of t)e?.()}},e.map(e=>{let{sensor:t}=e;return t}))}function lo(e,t){return(0,H.useMemo)(()=>e.reduce((e,n)=>{let{eventName:r,handler:i}=n;return e[r]=e=>{i(e,t)},e},{}),[e,t])}function uo(e){return(0,H.useMemo)(()=>e?ea(e):null,[e])}var fo=[];function po(e,t){t===void 0&&(t=Qi);let[n]=e,r=uo(n?Qr(n):null),[i,a]=(0,H.useState)(fo);function o(){a(()=>e.length?e.map(e=>ua(e)?r:new ba(t(e),e)):fo)}let s=eo({callback:o});return ri(()=>{s?.disconnect(),o(),e.forEach(e=>s?.observe(e))},[e]),i}function mo(e){if(!e)return null;if(e.children.length>1)return e;let t=e.children[0];return ei(t)?t:e}function ho(e){let{measure:t}=e,[n,r]=(0,H.useState)(null),i=eo({callback:(0,H.useCallback)(e=>{for(let{target:n}of e)if(ei(n)){r(e=>{let r=t(n);return e?{...e,width:r.width,height:r.height}:r});break}},[t])}),[a,o]=ci((0,H.useCallback)(e=>{let n=mo(e);i?.disconnect(),n&&i?.observe(n),r(n?t(n):null)},[t,i]));return(0,H.useMemo)(()=>({nodeRef:a,rect:n,setRef:o}),[n,a,o])}var go=[{sensor:Pa,options:{}},{sensor:ka,options:{}}],_o={current:{}},vo={draggable:{measure:$i},droppable:{measure:$i,strategy:qa.WhileDragging,frequency:Ja.Optimized},dragOverlay:{measure:Qi}},yo=class extends Map{get(e){return e==null?void 0:super.get(e)??void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(e=>{let{disabled:t}=e;return!t})}getNodeFor(e){return this.get(e)?.node.current??void 0}},bo={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new yo,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:Ni},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:vo,measureDroppableContainers:Ni,windowRect:null,measuringScheduled:!1},xo={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:``},dispatch:Ni,draggableNodes:new Map,over:null,measureDroppableContainers:Ni},So=(0,H.createContext)(xo),Co=(0,H.createContext)(bo);function wo(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new yo}}}function To(e,t){switch(t.type){case Mi.DragStart:return{...e,draggable:{...e.draggable,initialCoordinates:t.initialCoordinates,active:t.active}};case Mi.DragMove:return e.draggable.active==null?e:{...e,draggable:{...e.draggable,translate:{x:t.coordinates.x-e.draggable.initialCoordinates.x,y:t.coordinates.y-e.draggable.initialCoordinates.y}}};case Mi.DragEnd:case Mi.DragCancel:return{...e,draggable:{...e.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case Mi.RegisterDroppable:{let{element:n}=t,{id:r}=n,i=new yo(e.droppable.containers);return i.set(r,n),{...e,droppable:{...e.droppable,containers:i}}}case Mi.SetDroppableDisabled:{let{id:n,key:r,disabled:i}=t,a=e.droppable.containers.get(n);if(!a||r!==a.key)return e;let o=new yo(e.droppable.containers);return o.set(n,{...a,disabled:i}),{...e,droppable:{...e.droppable,containers:o}}}case Mi.UnregisterDroppable:{let{id:n,key:r}=t,i=e.droppable.containers.get(n);if(!i||r!==i.key)return e;let a=new yo(e.droppable.containers);return a.delete(n),{...e,droppable:{...e.droppable,containers:a}}}default:return e}}function Eo(e){let{disabled:t}=e,{active:n,activatorEvent:r,draggableNodes:i}=(0,H.useContext)(So),a=li(r),o=li(n?.id);return(0,H.useEffect)(()=>{if(!t&&!r&&a&&o!=null){if(!gi(a)||document.activeElement===a.target)return;let e=i.get(o);if(!e)return;let{activatorNode:t,node:n}=e;if(!t.current&&!n.current)return;requestAnimationFrame(()=>{for(let e of[t.current,n.current]){if(!e)continue;let t=xi(e);if(t){t.focus();break}}})}},[r,t,i,o,a]),null}function Do(e,t){let{transform:n,...r}=t;return e!=null&&e.length?e.reduce((e,t)=>t({transform:e,...r}),n):n}function Oo(e){return(0,H.useMemo)(()=>({draggable:{...vo.draggable,...e?.draggable},droppable:{...vo.droppable,...e?.droppable},dragOverlay:{...vo.dragOverlay,...e?.dragOverlay}}),[e?.draggable,e?.droppable,e?.dragOverlay])}function ko(e){let{activeNode:t,measure:n,initialRect:r,config:i=!0}=e,a=(0,H.useRef)(!1),{x:o,y:s}=typeof i==`boolean`?{x:i,y:i}:i;ri(()=>{if(!o&&!s||!t){a.current=!1;return}if(a.current||!r)return;let e=t?.node.current;if(!e||e.isConnected===!1)return;let i=Ki(n(e),r);if(o||(i.x=0),s||(i.y=0),a.current=!0,Math.abs(i.x)>0||Math.abs(i.y)>0){let t=ia(e);t&&t.scrollBy({top:i.y,left:i.x})}},[t,o,s,r,n])}var Ao=(0,H.createContext)({...Ii,scaleX:1,scaleY:1}),jo;(function(e){e[e.Uninitialized=0]=`Uninitialized`,e[e.Initializing=1]=`Initializing`,e[e.Initialized=2]=`Initialized`})(jo||={});var Mo=(0,H.memo)(function(e){let{id:t,accessibility:n,autoScroll:r=!0,children:i,sensors:a=go,collisionDetection:o=Wi,measuring:s,modifiers:c,...l}=e,[u,d]=(0,H.useReducer)(To,void 0,wo),[f,p]=Oi(),[m,h]=(0,H.useState)(jo.Uninitialized),g=m===jo.Initialized,{draggable:{active:_,nodes:v,translate:y},droppable:{containers:b}}=u,x=_==null?null:v.get(_),S=(0,H.useRef)({initial:null,translated:null}),C=(0,H.useMemo)(()=>_==null?null:{id:_,data:x?.data??_o,rect:S},[_,x]),w=(0,H.useRef)(null),[T,E]=(0,H.useState)(null),[D,O]=(0,H.useState)(null),k=oi(l,Object.values(l)),ee=di(`DndDescribedBy`,t),te=(0,H.useMemo)(()=>b.getEnabled(),[b]),A=Oo(s),{droppableRects:j,measureDroppableContainers:ne,measuringScheduled:re}=Xa(te,{dragging:g,dependencies:[y.x,y.y],config:A.droppable}),M=Ga(v,_),N=(0,H.useMemo)(()=>D?vi(D):null,[D]),P=Oe(),ie=Qa(M,A.draggable.measure);ko({activeNode:_==null?null:v.get(_),config:P.layoutShiftCompensation,initialRect:ie,measure:A.draggable.measure});let F=no(M,A.draggable.measure,ie),ae=no(M?M.parentElement:null),I=(0,H.useRef)({activatorEvent:null,active:null,activeNode:M,collisionRect:null,collisions:null,droppableRects:j,draggableNodes:v,draggingNode:null,draggingNodeRect:null,droppableContainers:b,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),L=b.getNodeFor(I.current.over?.id),R=ho({measure:A.dragOverlay.measure}),oe=R.nodeRef.current??M,z=g?R.rect??F:null,se=!!(R.nodeRef.current&&R.rect),ce=ro(se?null:F),le=uo(oe?Qr(oe):null),ue=ao(g?L??M:null),B=po(ue),de=Do(c,{transform:{x:y.x-ce.x,y:y.y-ce.y,scaleX:1,scaleY:1},activatorEvent:D,active:C,activeNodeRect:F,containerNodeRect:ae,draggingNodeRect:z,over:I.current.over,overlayNodeRect:R.rect,scrollableAncestors:ue,scrollableAncestorRects:B,windowRect:le}),fe=N?pi(N,y):null,pe=oo(ue),me=so(pe),he=so(pe,[F]),ge=pi(de,me),_e=z?Ji(z,de):null,ve=C&&_e?o({active:C,collisionRect:_e,droppableRects:j,droppableContainers:te,pointerCoordinates:fe}):null,ye=Bi(ve,`id`),[be,xe]=(0,H.useState)(null),Se=Gi(se?de:pi(de,he),be?.rect??null,F),Ce=(0,H.useRef)(null),we=(0,H.useCallback)((e,t)=>{let{sensor:n,options:r}=t;if(w.current==null)return;let i=v.get(w.current);if(!i)return;let a=e.nativeEvent;Ce.current=new n({active:w.current,activeNode:i,event:a,options:r,context:I,onAbort(e){if(!v.get(e))return;let{onDragAbort:t}=k.current,n={id:e};t?.(n),f({type:`onDragAbort`,event:n})},onPending(e,t,n,r){if(!v.get(e))return;let{onDragPending:i}=k.current,a={id:e,constraint:t,initialCoordinates:n,offset:r};i?.(a),f({type:`onDragPending`,event:a})},onStart(e){let t=w.current;if(t==null)return;let n=v.get(t);if(!n)return;let{onDragStart:r}=k.current,i={activatorEvent:a,active:{id:t,data:n.data,rect:S}};(0,qr.unstable_batchedUpdates)(()=>{r?.(i),h(jo.Initializing),d({type:Mi.DragStart,initialCoordinates:e,active:t}),f({type:`onDragStart`,event:i}),E(Ce.current),O(a)})},onMove(e){d({type:Mi.DragMove,coordinates:e})},onEnd:o(Mi.DragEnd),onCancel:o(Mi.DragCancel)});function o(e){return async function(){let{active:t,collisions:n,over:r,scrollAdjustedTranslate:i}=I.current,o=null;if(t&&i){let{cancelDrop:s}=k.current;o={activatorEvent:a,active:t,collisions:n,delta:i,over:r},e===Mi.DragEnd&&typeof s==`function`&&await Promise.resolve(s(o))&&(e=Mi.DragCancel)}w.current=null,(0,qr.unstable_batchedUpdates)(()=>{d({type:e}),h(jo.Uninitialized),xe(null),E(null),O(null),Ce.current=null;let t=e===Mi.DragEnd?`onDragEnd`:`onDragCancel`;if(o){let e=k.current[t];e?.(o),f({type:t,event:o})}})}}},[v]),Te=Ka(a,(0,H.useCallback)((e,t)=>(n,r)=>{let i=n.nativeEvent,a=v.get(r);if(w.current!==null||!a||i.dndKit||i.defaultPrevented)return;let o={active:a};e(n,t.options,o)===!0&&(i.dndKit={capturedBy:t.sensor},w.current=r,we(n,t))},[v,we]));co(a),ri(()=>{F&&m===jo.Initializing&&h(jo.Initialized)},[F,m]),(0,H.useEffect)(()=>{let{onDragMove:e}=k.current,{active:t,activatorEvent:n,collisions:r,over:i}=I.current;if(!t||!n)return;let a={active:t,activatorEvent:n,collisions:r,delta:{x:ge.x,y:ge.y},over:i};(0,qr.unstable_batchedUpdates)(()=>{e?.(a),f({type:`onDragMove`,event:a})})},[ge.x,ge.y]),(0,H.useEffect)(()=>{let{active:e,activatorEvent:t,collisions:n,droppableContainers:r,scrollAdjustedTranslate:i}=I.current;if(!e||w.current==null||!t||!i)return;let{onDragOver:a}=k.current,o=r.get(ye),s=o&&o.rect.current?{id:o.id,rect:o.rect.current,data:o.data,disabled:o.disabled}:null,c={active:e,activatorEvent:t,collisions:n,delta:{x:i.x,y:i.y},over:s};(0,qr.unstable_batchedUpdates)(()=>{xe(s),a?.(c),f({type:`onDragOver`,event:c})})},[ye]),ri(()=>{I.current={activatorEvent:D,active:C,activeNode:M,collisionRect:_e,collisions:ve,droppableRects:j,draggableNodes:v,draggingNode:oe,draggingNodeRect:z,droppableContainers:b,over:be,scrollableAncestors:ue,scrollAdjustedTranslate:ge},S.current={initial:z,translated:_e}},[C,M,ve,_e,v,oe,z,j,b,be,ue,ge]),Ha({...P,delta:y,draggingRect:_e,pointerCoordinates:fe,scrollableAncestors:ue,scrollableAncestorRects:B});let Ee=(0,H.useMemo)(()=>({active:C,activeNode:M,activeNodeRect:F,activatorEvent:D,collisions:ve,containerNodeRect:ae,dragOverlay:R,draggableNodes:v,droppableContainers:b,droppableRects:j,over:be,measureDroppableContainers:ne,scrollableAncestors:ue,scrollableAncestorRects:B,measuringConfiguration:A,measuringScheduled:re,windowRect:le}),[C,M,F,D,ve,ae,R,v,b,j,be,ne,ue,B,A,re,le]),De=(0,H.useMemo)(()=>({activatorEvent:D,activators:Te,active:C,activeNodeRect:F,ariaDescribedById:{draggable:ee},dispatch:d,draggableNodes:v,over:be,measureDroppableContainers:ne}),[D,Te,C,F,d,ee,v,be,ne]);return H.createElement(Ei.Provider,{value:p},H.createElement(So.Provider,{value:De},H.createElement(Co.Provider,{value:Ee},H.createElement(Ao.Provider,{value:Se},i)),H.createElement(Eo,{disabled:n?.restoreFocus===!1})),H.createElement(ji,{...n,hiddenTextDescribedById:ee}));function Oe(){let e=T?.autoScrollEnabled===!1,t=typeof r==`object`?r.enabled===!1:r===!1,n=g&&!e&&!t;return typeof r==`object`?{...r,enabled:n}:{enabled:n}}}),No=(0,H.createContext)(null),Po=`button`,Fo=`Draggable`;function Io(e){let{id:t,data:n,disabled:r=!1,attributes:i}=e,a=di(Fo),{activators:o,activatorEvent:s,active:c,activeNodeRect:l,ariaDescribedById:u,draggableNodes:d,over:f}=(0,H.useContext)(So),{role:p=Po,roleDescription:m=`draggable`,tabIndex:h=0}=i??{},g=c?.id===t,_=(0,H.useContext)(g?Ao:No),[v,y]=ci(),[b,x]=ci(),S=lo(o,t),C=oi(n);return ri(()=>(d.set(t,{id:t,key:a,node:v,activatorNode:b,data:C}),()=>{let e=d.get(t);e&&e.key===a&&d.delete(t)}),[d,t]),{active:c,activatorEvent:s,activeNodeRect:l,attributes:(0,H.useMemo)(()=>({role:p,tabIndex:h,"aria-disabled":r,"aria-pressed":g&&p===Po?!0:void 0,"aria-roledescription":m,"aria-describedby":u.draggable}),[r,p,h,g,m,u.draggable]),isDragging:g,listeners:r?void 0:S,node:v,over:f,setNodeRef:y,setActivatorNodeRef:x,transform:_}}function Lo(){return(0,H.useContext)(Co)}var Ro=`Droppable`,zo={timeout:25};function Bo(e){let{data:t,disabled:n=!1,id:r,resizeObserverConfig:i}=e,a=di(Ro),{active:o,dispatch:s,over:c,measureDroppableContainers:l}=(0,H.useContext)(So),u=(0,H.useRef)({disabled:n}),d=(0,H.useRef)(!1),f=(0,H.useRef)(null),p=(0,H.useRef)(null),{disabled:m,updateMeasurementsFor:h,timeout:g}={...zo,...i},_=oi(h??r),v=eo({callback:(0,H.useCallback)(()=>{if(!d.current){d.current=!0;return}p.current!=null&&clearTimeout(p.current),p.current=setTimeout(()=>{l(Array.isArray(_.current)?_.current:[_.current]),p.current=null},g)},[g]),disabled:m||!o}),[y,b]=ci((0,H.useCallback)((e,t)=>{v&&(t&&(v.unobserve(t),d.current=!1),e&&v.observe(e))},[v])),x=oi(t);return(0,H.useEffect)(()=>{!v||!y.current||(v.disconnect(),d.current=!1,v.observe(y.current))},[y,v]),(0,H.useEffect)(()=>(s({type:Mi.RegisterDroppable,element:{id:r,key:a,disabled:n,node:y,rect:f,data:x}}),()=>s({type:Mi.UnregisterDroppable,key:a,id:r})),[r]),(0,H.useEffect)(()=>{n!==u.current.disabled&&(s({type:Mi.SetDroppableDisabled,id:r,key:a,disabled:n}),u.current.disabled=n)},[r,a,n,s]),{active:o,rect:f,isOver:c?.id===r,node:y,over:c,setNodeRef:b}}function Vo(e,t,n){let r=e.slice();return r.splice(n<0?r.length+n:n,0,r.splice(t,1)[0]),r}function Ho(e,t){return e.reduce((e,n,r)=>{let i=t.get(n);return i&&(e[r]=i),e},Array(e.length))}function Uo(e){return e!==null&&e>=0}function Wo(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function Go(e){return typeof e==`boolean`?{draggable:e,droppable:e}:e}var Ko={scaleX:1,scaleY:1},qo=e=>{let{rects:t,activeNodeRect:n,activeIndex:r,overIndex:i,index:a}=e,o=t[r]??n;if(!o)return null;let s=Jo(t,a,r);if(a===r){let e=t[i];return e?{x:r<i?e.left+e.width-(o.left+o.width):e.left-o.left,y:0,...Ko}:null}return a>r&&a<=i?{x:-o.width-s,y:0,...Ko}:a<r&&a>=i?{x:o.width+s,y:0,...Ko}:{x:0,y:0,...Ko}};function Jo(e,t,n){let r=e[t],i=e[t-1],a=e[t+1];return!r||!i&&!a?0:n<t?i?r.left-(i.left+i.width):a.left-(r.left+r.width):a?a.left-(r.left+r.width):r.left-(i.left+i.width)}var Yo=e=>{let{rects:t,activeIndex:n,overIndex:r,index:i}=e,a=Vo(t,r,n),o=t[i],s=a[i];return!s||!o?null:{x:s.left-o.left,y:s.top-o.top,scaleX:s.width/o.width,scaleY:s.height/o.height}},Xo={scaleX:1,scaleY:1},Zo=e=>{let{activeIndex:t,activeNodeRect:n,index:r,rects:i,overIndex:a}=e,o=i[t]??n;if(!o)return null;if(r===t){let e=i[a];return e?{x:0,y:t<a?e.top+e.height-(o.top+o.height):e.top-o.top,...Xo}:null}let s=Qo(i,r,t);return r>t&&r<=a?{x:0,y:-o.height-s,...Xo}:r<t&&r>=a?{x:0,y:o.height+s,...Xo}:{x:0,y:0,...Xo}};function Qo(e,t,n){let r=e[t],i=e[t-1],a=e[t+1];return r?n<t?i?r.top-(i.top+i.height):a?a.top-(r.top+r.height):0:a?a.top-(r.top+r.height):i?r.top-(i.top+i.height):0:0}var $o=`Sortable`,es=H.createContext({activeIndex:-1,containerId:$o,disableTransforms:!1,items:[],overIndex:-1,useDragOverlay:!1,sortedRects:[],strategy:Yo,disabled:{draggable:!1,droppable:!1}});function ts(e){let{children:t,id:n,items:r,strategy:i=Yo,disabled:a=!1}=e,{active:o,dragOverlay:s,droppableRects:c,over:l,measureDroppableContainers:u}=Lo(),d=di($o,n),f=s.rect!==null,p=(0,H.useMemo)(()=>r.map(e=>typeof e==`object`&&`id`in e?e.id:e),[r]),m=o!=null,h=o?p.indexOf(o.id):-1,g=l?p.indexOf(l.id):-1,_=(0,H.useRef)(p),v=!Wo(p,_.current),y=g!==-1&&h===-1||v,b=Go(a);ri(()=>{v&&m&&u(p)},[v,p,m,u]),(0,H.useEffect)(()=>{_.current=p},[p]);let x=(0,H.useMemo)(()=>({activeIndex:h,containerId:d,disabled:b,disableTransforms:y,items:p,overIndex:g,useDragOverlay:f,sortedRects:Ho(p,c),strategy:i}),[h,d,b.draggable,b.droppable,y,p,g,c,f,i]);return H.createElement(es.Provider,{value:x},t)}var ns=e=>{let{id:t,items:n,activeIndex:r,overIndex:i}=e;return Vo(n,r,i).indexOf(t)},rs=e=>{let{containerId:t,isSorting:n,wasDragging:r,index:i,items:a,newIndex:o,previousItems:s,previousContainerId:c,transition:l}=e;return!l||!r||s!==a&&i===o?!1:n?!0:o!==i&&t===c},is={duration:200,easing:`ease`},as=`transform`,os=yi.Transition.toString({property:as,duration:0,easing:`linear`}),ss={roleDescription:`sortable`};function cs(e){let{disabled:t,index:n,node:r,rect:i}=e,[a,o]=(0,H.useState)(null),s=(0,H.useRef)(n);return ri(()=>{if(!t&&n!==s.current&&r.current){let e=i.current;if(e){let t=Qi(r.current,{ignoreTransform:!0}),n={x:e.left-t.left,y:e.top-t.top,scaleX:e.width/t.width,scaleY:e.height/t.height};(n.x||n.y)&&o(n)}}n!==s.current&&(s.current=n)},[t,n,r,i]),(0,H.useEffect)(()=>{a&&o(null)},[a]),a}function ls(e){let{animateLayoutChanges:t=rs,attributes:n,disabled:r,data:i,getNewIndex:a=ns,id:o,strategy:s,resizeObserverConfig:c,transition:l=is}=e,{items:u,containerId:d,activeIndex:f,disabled:p,disableTransforms:m,sortedRects:h,overIndex:g,useDragOverlay:_,strategy:v}=(0,H.useContext)(es),y=us(r,p),b=u.indexOf(o),x=(0,H.useMemo)(()=>({sortable:{containerId:d,index:b,items:u},...i}),[d,i,b,u]),S=(0,H.useMemo)(()=>u.slice(u.indexOf(o)),[u,o]),{rect:C,node:w,isOver:T,setNodeRef:E}=Bo({id:o,data:x,disabled:y.droppable,resizeObserverConfig:{updateMeasurementsFor:S,...c}}),{active:D,activatorEvent:O,activeNodeRect:k,attributes:ee,setNodeRef:te,listeners:A,isDragging:j,over:ne,setActivatorNodeRef:re,transform:M}=Io({id:o,data:x,attributes:{...ss,...n},disabled:y.draggable}),N=Yr(E,te),P=!!D,ie=P&&!m&&Uo(f)&&Uo(g),F=!_&&j,ae=ie?(F&&ie?M:null)??(s??v)({rects:h,activeNodeRect:k,activeIndex:f,overIndex:g,index:b}):null,I=Uo(f)&&Uo(g)?a({id:o,items:u,activeIndex:f,overIndex:g}):b,L=D?.id,R=(0,H.useRef)({activeId:L,items:u,newIndex:I,containerId:d}),oe=u!==R.current.items,z=t({active:D,containerId:d,isDragging:j,isSorting:P,id:o,index:b,items:u,newIndex:R.current.newIndex,previousItems:R.current.items,previousContainerId:R.current.containerId,transition:l,wasDragging:R.current.activeId!=null}),se=cs({disabled:!z,index:b,node:w,rect:C});return(0,H.useEffect)(()=>{P&&R.current.newIndex!==I&&(R.current.newIndex=I),d!==R.current.containerId&&(R.current.containerId=d),u!==R.current.items&&(R.current.items=u)},[P,I,d,u]),(0,H.useEffect)(()=>{if(L===R.current.activeId)return;if(L!=null&&R.current.activeId==null){R.current.activeId=L;return}let e=setTimeout(()=>{R.current.activeId=L},50);return()=>clearTimeout(e)},[L]),{active:D,activeIndex:f,attributes:ee,data:x,rect:C,index:b,newIndex:I,items:u,isOver:T,isSorting:P,isDragging:j,listeners:A,node:w,overIndex:g,over:ne,setNodeRef:N,setActivatorNodeRef:re,setDroppableNodeRef:E,setDraggableNodeRef:te,transform:se??ae,transition:ce()};function ce(){if(se||oe&&R.current.newIndex===b)return os;if(!(F&&!gi(O)||!l)&&(P||z))return yi.Transition.toString({...l,property:as})}}function us(e,t){return typeof e==`boolean`?{draggable:e,droppable:!1}:{draggable:e?.draggable??t.draggable,droppable:e?.droppable??t.droppable}}Q.Down,Q.Right,Q.Up,Q.Left;function ds(e){let t=e.parentElement;for(;t;){let e=window.getComputedStyle(t).overflowY;if(e===`auto`||e===`scroll`)return t;t=t.parentElement}return null}function fs(e,t){let n=(0,H.useRef)(null),r=(0,H.useRef)(e);(0,H.useEffect)(()=>{r.current=e},[e]);let i=(0,H.useCallback)(e=>{n.current=e},[]);return(0,H.useEffect)(()=>{let e=n.current;if(!e||!t)return;let i=ds(e),a=new IntersectionObserver(e=>{e[0]?.isIntersecting&&r.current()},{root:i,rootMargin:`100px`,threshold:0});return a.observe(e),()=>a.disconnect()},[t]),i}var ps=60*1e3,ms=60*ps,hs=24*ms,gs=7*hs,_s=365*hs,vs=360,ys=400,bs=400,xs=35,Ss=1e3,Cs=192,ws=120,Ts=224,Es=244,Ds=320,Os=320,ks=520,As=.5;function js(){return typeof window>`u`?ks:Math.max(Os,Math.min(ks,window.innerWidth*As))}function Ms(e){return Math.min(js(),Math.max(Os,e))}function Ns(e){if(!e)return``;let t=new Date(e).getTime();if(Number.isNaN(t))return``;let n=Math.max(0,Date.now()-t);return n<ms?W(`relativeMinuteShort`,{count:Math.max(1,Math.floor(n/ps))}):n<hs?W(`relativeHourShort`,{count:Math.floor(n/ms)}):n<gs?W(`relativeDayShort`,{count:Math.floor(n/hs)}):n<_s?W(`relativeWeekShort`,{count:Math.floor(n/gs)}):W(`relativeYearShort`,{count:Math.floor(n/_s)})}function Ps(e){if(!e)return!1;let t=e.trim();return!t||t===`undefined`||t===`null`||t===`false`?!1:!Number.isNaN(Date.parse(t))}function Fs({onLoadMore:e,enabled:t}){let n=fs(e,t);return t?(0,K.jsx)(`div`,{ref:n,className:`flex items-center justify-center py-1`,children:(0,K.jsx)(B,{className:`size-3 animate-spin text-muted-foreground/45`})}):null}function Is({title:e,className:t}){let n=(0,H.useRef)(null),r=(0,H.useRef)(null),i=(0,H.useRef)(null),a=(0,H.useRef)(null),o=(0,H.useCallback)(()=>{i.current!==null&&(window.clearTimeout(i.current),i.current=null),a.current?.cancel(),a.current=null,n.current&&(n.current.style.visibility=``),r.current&&(r.current.style.display=``,r.current.style.transform=`translateX(0)`)},[]),s=(0,H.useCallback)(e=>{if(o(),window.matchMedia(`(prefers-reduced-motion: reduce)`).matches)return;let t=e.currentTarget,s=r.current;if(!s)return;s.style.display=`inline-block`;let c=s.scrollWidth-t.clientWidth;s.style.display=``,!(c<=1)&&(i.current=window.setTimeout(()=>{i.current=null;let e=n.current,t=r.current;if(!e||!t)return;e.style.visibility=`hidden`,t.style.display=`inline-block`;let o=c/xs*1e3,s=Math.min(500,Math.max(240,o*.25)),l=o+Ss+s,u=o/l,d=(o+Ss)/l,f=t.animate([{transform:`translateX(0)`,offset:0,easing:`linear`},{transform:`translateX(-${c}px)`,offset:u,easing:`linear`},{transform:`translateX(-${c}px)`,offset:d,easing:`ease-out`},{transform:`translateX(0)`,offset:1}],{duration:l,fill:`forwards`});a.current=f,f.finished.then(()=>{a.current===f&&(f.cancel(),a.current=null,e.style.visibility=``,t.style.display=``,t.style.transform=`translateX(0)`)}).catch(()=>void 0)},bs))},[o]);return(0,H.useEffect)(()=>o,[o]),(0,K.jsxs)(`span`,{className:G(`relative min-w-0 flex-1 overflow-hidden whitespace-nowrap`,t),onMouseEnter:s,onMouseLeave:o,children:[(0,K.jsx)(`span`,{ref:n,className:`block truncate`,children:e}),(0,K.jsx)(`span`,{ref:r,className:`pointer-events-none absolute left-0 top-0 hidden whitespace-nowrap will-change-transform`,"aria-hidden":`true`,children:e})]})}function Ls({id:e,children:t}){let{attributes:n,listeners:r,setNodeRef:i,transform:a,transition:o,isDragging:s}=ls({id:e});return(0,K.jsx)(`div`,{ref:i,style:{transform:yi.Translate.toString(a),transition:s?void 0:o},className:G(s&&`relative z-50 opacity-40`),children:t({listeners:r,attributes:n})})}var Rs=(0,H.memo)(function({sidebarOpen:e,variant:r=`desktop`,projectsCollapsed:s,pinnedCollapsed:c,conversationsCollapsed:u,projects:f,expandedProjectIds:m,activeProject:h,currentSessionId:_,loadingSessionId:y,sessionViewMode:b,sessionSortMode:x,globalSessions:C,pinnedSessions:T,pinnedHasMore:E,pinnedLoading:D,sessionsForProject:O,projectTimelineSessions:k,projectTimelineHasMore:te,projectTimelineLoading:j,globalHasMore:M,globalLoading:N,onLoadMoreGlobal:ie,onLoadMorePinned:ae,projectHasMore:L,projectLoading:R,projectLoaded:z,onLoadMoreProject:se,onLoadMoreProjectTimeline:ce,sessionTaskStatus:le,selectingProject:ue,onTogglePinnedCollapsed:de,onToggleProjectsCollapsed:fe,onToggleConversationsCollapsed:ge,onToggleProjectExpanded:_e,onToggleAllProjectsExpanded:ve,onReorderProjects:xe,onSelectProjectDirectory:Ce,onStartNewProjectChat:we,onOpenGlobalSkills:Ee,onOpenAgents:De,onOpenScheduledTasks:Oe,onOpenProjectSkills:ke,onOpenProjectInExplorer:Ae,onDeleteProject:je,onLoadSession:Me,onSessionViewModeChange:Ne,onSessionSortModeChange:Pe,onTogglePinSession:Fe,onDeleteSession:Ie,onStartNewGlobalChat:Le,onOpenSettings:Re,currentServerUrl:ze,currentServerAlias:Be,onOpenServer:Ve,onOpenUpdate:He,onDismissUpdate:Ue,updateAvailable:We,latestVersion:Ge,currentVersion:Ke,onToggleSidebar:qe,currentSessionHoverInfo:Je}){let Ye=`hover:bg-[var(--quickforge-sidebar-hover-bg)]`,Xe=`quickforge-sidebar-section-header group mb-1 flex w-full items-center gap-1 rounded-lg px-2 py-1 text-sm font-[350] leading-5 text-muted-foreground/50 transition-colors ${Ye}`,Ze=`quickforge-sidebar-section-toggle flex min-w-0 flex-1 items-center gap-1 text-left transition-colors`,Qe=`quickforge-sidebar-section-icon size-4 shrink-0 text-current opacity-0 transition-[transform,opacity] duration-200 ease-out group-hover:opacity-100 group-focus-within:opacity-100 motion-reduce:transition-none`,V=`grid transition-[grid-template-rows,opacity] duration-200 ease-out motion-reduce:transition-none`,$e=`grid-rows-[1fr] opacity-100`,et=`pointer-events-none grid-rows-[0fr] opacity-0`,tt=`min-h-0 overflow-hidden`,nt=`group relative flex items-center gap-2 overflow-hidden rounded-lg py-1.5 text-left transition-[background-color,color,box-shadow] duration-160 ease-out ${e?`px-2`:`justify-center px-0`} `,rt=`group relative flex items-center gap-2 overflow-hidden py-1.5 text-left transition-[background-color,color,box-shadow] duration-160 ease-out ${e?`px-2`:`justify-center px-0`}`,it=`bg-[var(--quickforge-sidebar-hover-bg)] text-foreground/84 shadow-[0_8px_22px_-20px_rgb(15_23_42_/_0.32)]`,at=`text-foreground/80 ${Ye}`,ot=`text-muted-foreground/68 ${Ye} hover:text-foreground/80`,st=`text-muted-foreground/70 ${Ye} hover:text-foreground/82`,ct=`inline-flex size-6 shrink-0 items-center justify-center rounded-full text-muted-foreground/55 transition-colors group-hover:text-foreground/70`,lt=`size-7 shrink-0 rounded-full text-muted-foreground/55 transition-[background-color,color,box-shadow,opacity] duration-160 ease-out ${Ye} hover:text-foreground/85 `,ut=`quickforge-sidebar-section-icon ${lt} pointer-events-none opacity-0 group-hover:pointer-events-auto group-hover:opacity-100 group-focus-within:pointer-events-auto group-focus-within:opacity-100`,dt=`pointer-events-none absolute inset-y-0 right-1 z-20 flex items-center gap-px rounded-r-lg bg-gradient-to-l from-[var(--quickforge-sidebar-hover-bg)] via-[var(--quickforge-sidebar-hover-bg)]/95 to-transparent pl-4 opacity-0 transition-opacity duration-160`,ft=`${dt} group-hover:pointer-events-auto group-hover:opacity-100 group-focus-within:pointer-events-auto group-focus-within:opacity-100`,pt=`${dt} group-hover:pointer-events-auto group-hover:opacity-100`,mt=`size-6 shrink-0 rounded-full text-muted-foreground/55 transition-[background-color,color,box-shadow] duration-160 ease-out ${Ye} hover:text-foreground/85 `,U=`truncate text-sm font-[350] leading-5`,ht=`flex min-w-0 flex-1 items-center gap-2 text-left`,gt=`flex min-w-0 flex-1 items-center gap-1 truncate`,_t=e=>y===e?(0,K.jsx)(B,{className:`size-3 shrink-0 animate-spin text-muted-foreground/55`,"aria-hidden":`true`}):null,vt=`relative z-10 inline-flex size-5 shrink-0 items-center justify-center rounded-full text-muted-foreground/55 transition-opacity duration-160 transition-colors ${Ye} hover:text-foreground/85`,yt=`group-hover:pointer-events-none group-hover:opacity-0 group-focus-within:pointer-events-none group-focus-within:opacity-0`,bt=`font-[350] text-foreground/84`,xt=`quickforge-sidebar-session-time shrink-0 text-[11px] leading-4 transition-opacity duration-160`,St=`px-3 pb-1 pt-2 text-xs font-[350] leading-4 text-muted-foreground/50`,Ct=`flex w-full items-center gap-3 whitespace-nowrap rounded-xl px-3 py-2.5 text-left text-sm text-foreground/86 transition-colors hover:bg-muted/45`,wt=`mt-2 flex items-center gap-2 text-sm leading-5 text-muted-foreground/72`,Tt=r===`mobile`,[Et,Dt]=(0,H.useState)(!1),[Ot,kt]=(0,H.useState)(``),[At,jt]=(0,H.useState)(null),[Mt,Nt]=(0,H.useState)(null),[Pt,Ft]=(0,H.useState)(!1),[It,Lt]=(0,H.useState)(null),[Rt,zt]=(0,H.useState)(null),[Bt,Vt]=(0,H.useState)(null),[Ht,Ut]=(0,H.useState)(null),[Wt,Gt]=(0,H.useState)(null),[Kt,qt]=(0,H.useState)(null),[Jt,Yt]=(0,H.useState)(null),[Xt,Zt]=(0,H.useState)(!1),[Qt,$t]=(0,H.useState)(Ds),[en,tn]=(0,H.useState)(!1),J=(0,H.useRef)(null),nn=(0,H.useRef)(null),rn=(0,H.useRef)(null),an=(0,H.useRef)(null),on=(0,H.useRef)(null),sn=(0,H.useRef)(null),cn=(0,H.useRef)(null),ln=Fi(Pi(Pa,{activationConstraint:{distance:6}})),un=(0,H.useCallback)(e=>({...e.transform,x:0}),[]),dn=(0,H.useMemo)(()=>f.map(e=>e.id),[f]),fn=(0,H.useMemo)(()=>f.find(e=>e.id===At),[At,f]),Y=(0,H.useMemo)(()=>new Map(f.map(e=>[e.id,e.name])),[f]),pn=(0,H.useMemo)(()=>{let e=new Set;return k.filter(t=>e.has(t.id)?!1:(e.add(t.id),!0)).map(e=>({session:e,projectName:e.projectId?Y.get(e.projectId)??W(`unknownProject`):W(`unknownProject`)}))},[Y,k]),mn=(0,H.useMemo)(()=>T.filter(e=>Ps(e.pinnedAt)).map(e=>({session:e,sourceName:e.scope===`project`?e.projectId?Y.get(e.projectId)??W(`unknownProject`):W(`unknownProject`):W(`normalChat`)})),[T,Y]),hn=(0,H.useCallback)(()=>{Zt(!0),jt(null),Nt(null),cn.current!==null&&(window.clearTimeout(cn.current),cn.current=null),Yt(null)},[]),gn=(0,H.useCallback)(()=>{Zt(!1)},[]),_n=(0,H.useCallback)(e=>{gn();let{active:t,over:n}=e;if(!n||t.id===n.id)return;let r=dn.indexOf(t.id),i=dn.indexOf(n.id);if(r===-1||i===-1)return;let a=[...dn];a.splice(r,1),a.splice(i,0,t.id),xe(a)},[gn,dn,xe]),vn=(0,H.useRef)(null),yn=(0,H.useMemo)(()=>{let e=mn.map(({session:e,sourceName:t})=>({session:e,projectName:t})),t=f.flatMap(e=>O(e.id).map(t=>({session:t,projectName:e.name}))),n=k.map(e=>({session:e,projectName:e.projectId?Y.get(e.projectId)??W(`unknownProject`):W(`unknownProject`)})),r=C.map(e=>({session:e,projectName:``})),i=new Set;return[...e,...t,...n,...r].filter(({session:e})=>i.has(e.id)?!1:(i.add(e.id),!0))},[C,mn,Y,k,f,O]),bn=Ot.trim()?yn.filter(({session:e,projectName:t})=>`${Fn(e.title,e.channelName)} ${t}`.toLowerCase().includes(Ot.trim().toLowerCase())).slice(0,8):[],xn=()=>{Dt(!0),window.setTimeout(()=>vn.current?.focus(),0)},Sn=e=>{Me(e),Dt(!1),kt(``)},X=()=>{cn.current!==null&&(window.clearTimeout(cn.current),cn.current=null)},Cn=(e,t)=>{if(Tt)return;let n=e.currentTarget.getBoundingClientRect(),r=Math.max(8,Math.min(n.right+8,window.innerWidth-392)),i=n.top+n.height/2;X(),cn.current=window.setTimeout(()=>{cn.current=null,Yt({sessionId:t,x:r,y:i})},ys)},wn=e=>{X(),Yt(t=>t?.sessionId===e?null:t)},Tn=(e,t)=>{e.stopPropagation();let n=e.currentTarget.getBoundingClientRect();zt(null),jt(e=>e===t?(Nt(null),null):(Nt({x:Math.max(8,Math.min(n.right-Cs,window.innerWidth-Cs-8)),y:Math.max(8,Math.min(n.bottom+4,window.innerHeight-ws-8))}),t))},En=e=>{e.stopPropagation();let t=e.currentTarget.getBoundingClientRect();jt(null),Nt(null),Ft(e=>e?(Lt(null),!1):(Lt({x:Math.max(8,Math.min(t.right-Ts,window.innerWidth-Ts-8)),y:Math.max(8,Math.min(t.bottom+6,window.innerHeight-Es-8))}),!0))},Dn=(0,H.useCallback)(()=>{Ft(!1),Lt(null)},[]),On=e=>{Ne(e),Dn()},kn=e=>{Pe(e),Dn()},An=(0,H.useCallback)(()=>{jt(null),Nt(null),zt(null)},[]),jn=(e,t)=>{e.stopPropagation(),zt(t)},Mn=(e,t)=>{e.stopPropagation(),jt(null),Nt(null),Vt(t),sn.current!==null&&window.clearTimeout(sn.current),sn.current=window.setTimeout(()=>{sn.current=null,zt(e=>e===t?null:e),Promise.resolve(je(t)).catch(()=>{Vt(e=>e===t?null:e)})},vs)},Nn=(e,t)=>{e.currentTarget.blur(),Ut(t),Fe(t)},Pn=(e,t)=>{e.stopPropagation(),e.currentTarget.blur(),Gt(t)},In=(e,t)=>{e.stopPropagation(),qt(t),wn(t),on.current!==null&&window.clearTimeout(on.current),on.current=window.setTimeout(()=>{on.current=null,Gt(e=>e===t?null:e),Promise.resolve(Ie(t)).catch(()=>{qt(e=>e===t?null:e)})},vs)},Ln=(0,H.useCallback)(()=>{let e=an.current;e&&(document.body.style.cursor=e.cursor,document.body.style.userSelect=e.userSelect,an.current=null)},[]),Rn=(0,H.useCallback)(e=>{if(nn.current=null,rn.current!==null&&(window.cancelAnimationFrame(rn.current),rn.current=null),typeof e==`number`){let t=Ms(e);J.current&&(J.current.style.width=`${t}px`),$t(t)}Ln(),tn(!1)},[Ln]);function zn(e){let t=J.current?.getBoundingClientRect().width??Qt;nn.current={startX:e.clientX,startWidth:t,currentWidth:t},an.current={cursor:document.body.style.cursor,userSelect:document.body.style.userSelect},document.body.style.cursor=`col-resize`,document.body.style.userSelect=`none`,tn(!0),e.preventDefault(),e.stopPropagation();try{e.currentTarget.setPointerCapture(e.pointerId)}catch{}}function Bn(e){let t=nn.current;!t||!J.current||(t.currentWidth=Ms(t.startWidth+e.clientX-t.startX),rn.current===null&&(rn.current=window.requestAnimationFrame(()=>{rn.current=null;let e=nn.current;!e||!J.current||(J.current.style.width=`${e.currentWidth}px`)})))}function Vn(e){let t=nn.current?.currentWidth;Rn(t);try{e.currentTarget.releasePointerCapture(e.pointerId)}catch{}}function Hn(){Rn(Ds)}return(0,H.useEffect)(()=>()=>{on.current!==null&&window.clearTimeout(on.current),sn.current!==null&&window.clearTimeout(sn.current),cn.current!==null&&window.clearTimeout(cn.current),rn.current!==null&&window.cancelAnimationFrame(rn.current),nn.current=null,Ln()},[Ln]),(0,H.useEffect)(()=>{if(!Tt&&e)return;let t=window.requestAnimationFrame(()=>Rn());return()=>window.cancelAnimationFrame(t)},[Rn,Tt,e]),(0,H.useEffect)(()=>{if(Tt)return;let e=()=>{Rn(Ms(nn.current?.currentWidth??Qt))};return window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[Rn,Tt,Qt]),(0,H.useEffect)(()=>{if(At)return window.addEventListener(`click`,An),window.addEventListener(`blur`,An),window.addEventListener(`resize`,An),()=>{window.removeEventListener(`click`,An),window.removeEventListener(`blur`,An),window.removeEventListener(`resize`,An)}},[At,An]),(0,H.useEffect)(()=>{if(Pt)return window.addEventListener(`click`,Dn),window.addEventListener(`blur`,Dn),window.addEventListener(`resize`,Dn),()=>{window.removeEventListener(`click`,Dn),window.removeEventListener(`blur`,Dn),window.removeEventListener(`resize`,Dn)}},[Pt,Dn]),(0,K.jsxs)(`aside`,{ref:J,className:G(`relative z-10 min-h-0 shrink-0 overflow-hidden border-r-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] bg-[var(--quickforge-sidebar-bg)] transition-[width] duration-200 ease-out motion-reduce:transition-none`,Tt?`flex h-full w-80 max-w-[85vw] flex-col`:`hidden md:flex md:flex-col`,!Tt&&!e?`w-14`:void 0,en&&`transition-none`),style:!Tt&&e?{width:Qt,minWidth:Os,maxWidth:`min(${ks}px, ${As*100}vw)`}:void 0,children:[!Tt&&e?(0,K.jsx)(`div`,{role:`separator`,"aria-orientation":`vertical`,"aria-valuemin":Os,"aria-valuemax":js(),"aria-valuenow":Math.round(Qt),className:G(`group absolute inset-y-0 right-0 z-30 w-2 cursor-col-resize touch-none bg-transparent transition-colors hover:bg-border/20`,en&&`bg-border/25`),onDoubleClick:Hn,onPointerDown:zn,onPointerMove:Bn,onPointerUp:Vn,onPointerCancel:Vn,children:(0,K.jsx)(`span`,{className:G(`absolute inset-y-0 right-0 w-px bg-border/70 opacity-0 transition-opacity`,en?`opacity-100`:`group-hover:opacity-100`)})}):null,(0,K.jsxs)(`div`,{className:`shrink-0 px-3 pt-3 pb-1`,children:[(0,K.jsx)(`div`,{className:G(nt,`w-full`),children:e?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(`span`,{className:ct,children:(0,K.jsx)(`img`,{src:`/favicon.svg`,alt:``,"aria-hidden":`true`,className:`size-5`})}),(0,K.jsx)(`button`,{type:`button`,className:G(lt,`ml-auto inline-flex items-center justify-center`),onClick:qe,"aria-label":W(`toggleSidebar`),title:W(`toggleSidebar`),children:(0,K.jsx)(g,{className:`size-4`})})]}):(0,K.jsxs)(`button`,{type:`button`,className:G(lt,`group/toggle relative inline-flex items-center justify-center`),onClick:qe,"aria-label":W(`toggleSidebar`),title:W(`toggleSidebar`),children:[(0,K.jsx)(`img`,{src:`/favicon.svg`,alt:``,"aria-hidden":`true`,className:`size-5 transition-opacity duration-160 group-hover/toggle:opacity-0 group-focus-visible/toggle:opacity-0`}),(0,K.jsx)(v,{className:`absolute size-4 opacity-0 transition-opacity duration-160 group-hover/toggle:opacity-100 group-focus-visible/toggle:opacity-100`})]})}),(0,K.jsxs)(`button`,{type:`button`,className:G(nt,`mt-4 w-full`,ot),onClick:Le,"aria-label":W(`startNewChat`),title:W(`startNewChat`),children:[(0,K.jsx)(`span`,{className:ct,children:(0,K.jsx)(n,{className:`size-4`})}),e?(0,K.jsx)(`span`,{className:U,children:W(`startNewChat`)}):null]}),(0,K.jsxs)(`button`,{type:`button`,className:G(nt,`w-full`,ot),onClick:xn,"aria-label":W(`search`),children:[(0,K.jsx)(`span`,{className:ct,children:(0,K.jsx)(Se,{className:`size-4`})}),e?(0,K.jsx)(`span`,{className:U,children:W(`search`)}):null]}),(0,K.jsxs)(`button`,{type:`button`,className:G(nt,`w-full`,ot),onClick:Oe,"aria-label":W(`scheduledTasks`),title:W(`scheduledTasks`),children:[(0,K.jsx)(`span`,{className:ct,children:(0,K.jsx)(p,{className:`size-4`})}),e?(0,K.jsx)(`span`,{className:U,children:W(`scheduledTasks`)}):null]}),(0,K.jsxs)(`button`,{type:`button`,className:G(nt,`w-full`,ot),onClick:Ee,"aria-label":W(`manageGlobalSkills`),title:W(`manageGlobalSkills`),children:[(0,K.jsx)(`span`,{className:ct,children:(0,K.jsx)(Te,{className:`size-4`})}),e?(0,K.jsx)(`span`,{className:U,children:W(`skills`)}):null]}),(0,K.jsxs)(`button`,{type:`button`,className:G(nt,`w-full`,ot),onClick:De,"aria-label":W(`agentsTab`),title:W(`agentsTab`),children:[(0,K.jsx)(`span`,{className:ct,children:(0,K.jsx)(w,{className:`size-4`})}),e?(0,K.jsx)(`span`,{className:U,children:W(`agentsTab`)}):null]})]}),e?(0,K.jsxs)(K.Fragment,{children:[mn.length>0||D?(0,K.jsxs)(`div`,{className:`md:shrink-0 px-3 pb-1 max-h-[28%] flex flex-col min-h-0 overflow-hidden`,children:[(0,K.jsx)(`div`,{className:Xe,children:(0,K.jsxs)(`button`,{type:`button`,className:Ze,onClick:de,"aria-expanded":!c,children:[(0,K.jsx)(`span`,{className:`truncate`,children:W(`pinnedConversations`)}),(0,K.jsx)(F,{className:G(Qe,!c&&`rotate-90`)})]})}),(0,K.jsx)(`div`,{className:G(V,`flex-1 min-h-0`,c?et:$e),children:(0,K.jsx)(`div`,{className:tt,children:(0,K.jsx)(`div`,{className:`h-full overflow-y-auto`,children:(0,K.jsx)(`div`,{className:`space-y-0.5`,children:mn.length===0?(0,K.jsxs)(`div`,{className:`flex items-center px-3 py-3 text-xs text-muted-foreground/55`,children:[(0,K.jsx)(B,{className:`mr-1.5 size-3 animate-spin`}),W(`loadingChatWorkspace`)]}):(0,K.jsxs)(K.Fragment,{children:[mn.map(({session:e})=>{let t=_===e.id,n=Ht===e.id,r=Kt===e.id;return(0,K.jsx)(`div`,{className:G(`grid transition-[grid-template-rows,opacity,transform] duration-[360ms] ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none`,r?`grid-rows-[0fr] -translate-x-1 opacity-0`:`grid-rows-[1fr] translate-x-0 opacity-100`),children:(0,K.jsx)(`div`,{className:`min-h-0 overflow-hidden`,children:(0,K.jsxs)(`div`,{className:G(nt,t?it:st,r&&`pointer-events-none scale-[0.98] opacity-0 duration-[360ms] ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none`),onMouseEnter:t=>Cn(t,e.id),onClickCapture:()=>wn(e.id),onMouseLeave:()=>{Ut(t=>t===e.id?null:t),r||Gt(t=>t===e.id?null:t),wn(e.id)},children:[(0,K.jsxs)(`div`,{role:`button`,tabIndex:0,"aria-busy":y===e.id,className:`flex min-w-0 flex-1 items-center gap-2 text-left`,onClick:()=>Me(e.id),onKeyDown:t=>{t.key!==`Enter`&&t.key!==` `||(t.preventDefault(),Me(e.id))},children:[(0,K.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,K.jsxs)(`div`,{className:gt,children:[_t(e.id),le(e)===`running`?(0,K.jsx)(`span`,{className:`size-1.5 shrink-0 rounded-full bg-emerald-500`}):null,(0,K.jsx)(Is,{className:G(U,t&&bt),title:Fn(e.title,e.channelName)})]})}),(0,K.jsx)(`button`,{type:`button`,className:G(vt,!n&&yt),onClick:t=>{t.stopPropagation(),Fe(e.id)},"aria-label":W(`unpinSession`),title:W(`unpinSession`),children:(0,K.jsx)(a,{className:`size-3`})}),(0,K.jsx)(`span`,{className:G(xt,!n&&yt),children:Ns(e.pinnedAt)})]}),(0,K.jsx)(`div`,{className:G(ft,n&&`hidden`),children:Wt===e.id?(0,K.jsx)(q,{variant:`destructive`,size:`sm`,className:`h-6 rounded-full px-2 text-xs`,onClick:t=>In(t,e.id),"aria-label":W(`confirmArchive`),title:W(`confirmArchive`),children:W(`confirm`)}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:mt,onClick:t=>Nn(t,e.id),"aria-label":W(`unpinSession`),children:(0,K.jsx)(a,{className:`size-3.5`})}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:mt,onClick:t=>Pn(t,e.id),"aria-label":W(`archiveSession`),children:(0,K.jsx)(d,{className:`size-3.5`})})]})})]})})},e.id)}),(0,K.jsx)(Fs,{onLoadMore:ae,enabled:E&&!D})]})})})})})]}):null,(0,K.jsx)(`div`,{className:`md:shrink-0 px-3 max-h-[55%] flex flex-col min-h-0 overflow-hidden`,children:(0,K.jsxs)(`div`,{className:`mb-0.5 flex min-h-0 flex-1 flex-col`,children:[(0,K.jsxs)(`div`,{className:Xe,children:[(0,K.jsxs)(`button`,{type:`button`,className:Ze,onClick:fe,"aria-expanded":!s,children:[(0,K.jsx)(`span`,{className:`truncate`,children:W(`projects`)}),(0,K.jsx)(F,{className:G(Qe,!s&&`rotate-90`)})]}),f.length>0&&(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:ut,onClick:En,"aria-label":W(`filterSort`),title:W(`filterSort`),"aria-haspopup":`menu`,"aria-expanded":Pt,children:(0,K.jsx)(ne,{className:`size-4`})}),f.length>0&&(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:ut,onClick:ve,"aria-label":m.size===f.length?W(`collapseAllProjects`):W(`expandAllProjects`),children:m.size===f.length?(0,K.jsx)(t,{className:`size-4`}):(0,K.jsx)(I,{className:`size-4`})}),Ce?(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:ut,onClick:Ce,disabled:ue,"aria-label":W(`addProject`),children:(0,K.jsx)(o,{className:`size-4`})}):null]}),(0,K.jsx)(`div`,{className:G(V,`flex-1 min-h-0`,s?et:$e),children:(0,K.jsx)(`div`,{className:tt,children:(0,K.jsx)(`div`,{className:`h-full overflow-y-auto`,children:(0,K.jsx)(`div`,{className:`space-y-0.5`,children:f.length===0?(0,K.jsx)(`div`,{className:`px-3 py-3 text-xs text-muted-foreground/55`,children:W(`noProjects`)}):b===`timeline`?pn.length===0?j?(0,K.jsxs)(`div`,{className:`flex items-center px-3 py-3 text-xs text-muted-foreground/55`,children:[(0,K.jsx)(B,{className:`mr-1.5 size-3 animate-spin`}),W(`loadingChatWorkspace`)]}):(0,K.jsx)(`div`,{className:`px-3 py-3 text-xs text-muted-foreground/55`,children:W(`noConversations`)}):(0,K.jsxs)(K.Fragment,{children:[pn.map(({session:e})=>{let t=_===e.id,n=Ht===e.id,r=Kt===e.id,i=x===`createdAt`?e.createdAt:e.lastModified;return(0,K.jsx)(`div`,{className:G(`grid transition-[grid-template-rows,opacity,transform] duration-[360ms] ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none`,r?`grid-rows-[0fr] -translate-x-1 opacity-0`:`grid-rows-[1fr] translate-x-0 opacity-100`),children:(0,K.jsx)(`div`,{className:`min-h-0 overflow-hidden`,children:(0,K.jsxs)(`div`,{className:G(nt,t?it:st,r&&`pointer-events-none scale-[0.98] opacity-0 duration-[360ms] ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none`),onMouseEnter:t=>Cn(t,e.id),onClickCapture:()=>wn(e.id),onMouseLeave:()=>{Ut(t=>t===e.id?null:t),r||Gt(t=>t===e.id?null:t),wn(e.id)},children:[(0,K.jsxs)(`button`,{className:`flex min-w-0 flex-1 items-center gap-2 text-left`,type:`button`,"aria-busy":y===e.id,onClick:()=>Me(e.id),children:[(0,K.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,K.jsxs)(`div`,{className:gt,children:[_t(e.id),le(e)===`running`?(0,K.jsx)(`span`,{className:`size-1.5 shrink-0 rounded-full bg-emerald-500`}):null,(0,K.jsx)(Is,{className:G(U,t&&bt),title:Fn(e.title,e.channelName)})]})}),e.pinnedAt?(0,K.jsx)(`button`,{type:`button`,className:G(vt,!n&&yt),onClick:t=>{t.stopPropagation(),Fe(e.id)},"aria-label":W(`unpinSession`),title:W(`unpinSession`),children:(0,K.jsx)(a,{className:`size-3`})}):null,(0,K.jsx)(`span`,{className:G(xt,!n&&yt),children:Ns(i)})]}),(0,K.jsx)(`div`,{className:G(ft,n&&`hidden`),children:Wt===e.id?(0,K.jsx)(q,{variant:`destructive`,size:`sm`,className:`h-6 rounded-full px-2 text-xs`,onClick:t=>In(t,e.id),"aria-label":W(`confirmArchive`),title:W(`confirmArchive`),children:W(`confirm`)}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:mt,onClick:t=>Nn(t,e.id),"aria-label":e.pinnedAt?W(`unpinSession`):W(`pinSession`),children:(0,K.jsx)(a,{className:`size-3.5`})}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:mt,onClick:t=>Pn(t,e.id),"aria-label":W(`archiveSession`),children:(0,K.jsx)(d,{className:`size-3.5`})})]})})]})})},e.id)}),(0,K.jsx)(Fs,{onLoadMore:ce,enabled:te&&!j})]}):(0,K.jsx)(Mo,{sensors:ln,collisionDetection:Hi,onDragStart:hn,onDragEnd:_n,onDragCancel:gn,measuring:{droppable:{strategy:qa.Always}},modifiers:[un],children:(0,K.jsx)(ts,{items:dn,strategy:Zo,children:f.map(e=>{let t=O(e.id),r=!Xt&&m.has(e.id),i=h?.id===e.id,o=z(e.id),s=At===e.id,c=Bt===e.id;return(0,K.jsx)(Ls,{id:e.id,children:({listeners:l,attributes:u})=>(0,K.jsx)(`div`,{className:G(`grid transition-[grid-template-rows,opacity,transform] duration-[360ms] ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none`,c?`grid-rows-[0fr] -translate-x-1 opacity-0`:`grid-rows-[1fr] translate-x-0 opacity-100`),children:(0,K.jsxs)(`div`,{className:`min-h-0 overflow-hidden`,children:[(0,K.jsxs)(`div`,{className:G(nt,i?at:ot,s&&`z-20 overflow-visible`,c&&`pointer-events-none scale-[0.98] opacity-0 duration-[360ms] ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none`),style:{touchAction:`none`},...l,...u,children:[(0,K.jsx)(`button`,{type:`button`,className:ct,onClick:()=>_e(e.id),"aria-label":W(r?`collapseProject`:`expandProject`),children:r?(0,K.jsx)(he,{className:`size-4`}):(0,K.jsx)(A,{className:`size-4`})}),(0,K.jsx)(`button`,{className:`flex min-w-0 flex-1 items-center text-left`,type:`button`,title:e.path,onClick:()=>_e(e.id),children:(0,K.jsx)(`span`,{className:G(U,i&&`font-[350] text-foreground/80`),children:e.name})}),(0,K.jsxs)(`div`,{className:pt,children:[(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:mt,onClick:t=>Tn(t,e.id),"aria-label":W(`moreOptions`),"aria-expanded":s,children:(0,K.jsx)(oe,{className:`size-4`})}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:mt,onClick:()=>we(e),"aria-label":W(`newProjectChat`),children:(0,K.jsx)(n,{className:`size-4`})})]})]}),(0,K.jsx)(`div`,{className:G(V,Xt&&`transition-none`,r?$e:et),children:(0,K.jsx)(`div`,{className:tt,children:(0,K.jsx)(`div`,{className:`mt-0.5 space-y-0.5 pl-8 max-h-[35vh] overflow-y-auto`,children:t.length===0&&!o||t.length===0&&R(e.id)?(0,K.jsxs)(`div`,{className:`flex items-center px-2 py-1.5 text-xs text-muted-foreground/55`,children:[(0,K.jsx)(B,{className:`mr-1.5 size-3 animate-spin`}),W(`loadingChatWorkspace`)]}):t.length===0&&!L(e.id)?(0,K.jsx)(`div`,{className:`px-2 py-1.5 text-xs text-muted-foreground/55`,children:W(`noConversations`)}):(0,K.jsxs)(K.Fragment,{children:[t.map(e=>{let t=_===e.id,n=Ht===e.id,r=Kt===e.id;return(0,K.jsx)(`div`,{className:G(`grid transition-[grid-template-rows,opacity,transform] duration-[360ms] ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none`,r?`grid-rows-[0fr] -translate-x-1 opacity-0`:`grid-rows-[1fr] translate-x-0 opacity-100`),children:(0,K.jsx)(`div`,{className:`min-h-0 overflow-hidden`,children:(0,K.jsxs)(`div`,{className:G(nt,`gap-1`,t?it:st,r&&`pointer-events-none scale-[0.98] opacity-0 duration-[360ms] ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none`),onMouseEnter:t=>Cn(t,e.id),onClickCapture:()=>wn(e.id),onMouseLeave:()=>{Ut(t=>t===e.id?null:t),r||Gt(t=>t===e.id?null:t),wn(e.id)},children:[(0,K.jsxs)(`button`,{className:ht,type:`button`,"aria-busy":y===e.id,onClick:()=>Me(e.id),children:[(0,K.jsxs)(`div`,{className:gt,children:[_t(e.id),le(e)===`running`?(0,K.jsx)(`span`,{className:`size-1.5 shrink-0 rounded-full bg-emerald-500`}):null,(0,K.jsx)(Is,{className:G(U,t&&bt),title:Fn(e.title,e.channelName)})]}),e.pinnedAt?(0,K.jsx)(`button`,{type:`button`,className:G(vt,!n&&yt),onClick:t=>{t.stopPropagation(),Fe(e.id)},"aria-label":W(`unpinSession`),title:W(`unpinSession`),children:(0,K.jsx)(a,{className:`size-3`})}):null,(0,K.jsx)(`span`,{className:G(xt,!n&&yt),children:Ns(x===`createdAt`?e.createdAt:e.lastModified)})]}),(0,K.jsx)(`div`,{className:G(ft,n&&`hidden`),children:Wt===e.id?(0,K.jsx)(q,{variant:`destructive`,size:`sm`,className:`h-6 rounded-full px-2 text-xs`,onClick:t=>In(t,e.id),"aria-label":W(`confirmArchive`),title:W(`confirmArchive`),children:W(`confirm`)}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:mt,onClick:t=>Nn(t,e.id),"aria-label":e.pinnedAt?W(`unpinSession`):W(`pinSession`),children:(0,K.jsx)(a,{className:`size-3.5`})}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:mt,onClick:t=>Pn(t,e.id),"aria-label":W(`archiveSession`),children:(0,K.jsx)(d,{className:`size-3.5`})})]})})]})})},e.id)}),(0,K.jsx)(Fs,{onLoadMore:()=>se(e.id),enabled:L(e.id)&&!R(e.id)})]})})})})]})})},e.id)})})})})})})})]})}),(0,K.jsxs)(`div`,{className:`flex-1 min-h-0 flex flex-col px-3 pb-3`,children:[(0,K.jsxs)(`div`,{className:Xe,children:[(0,K.jsxs)(`button`,{type:`button`,className:Ze,onClick:ge,"aria-expanded":!u,children:[(0,K.jsx)(`span`,{className:`truncate`,children:W(`conversations`)}),(0,K.jsx)(F,{className:G(Qe,!u&&`rotate-90`)})]}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:G(lt,`quickforge-sidebar-section-icon`),onClick:Le,"aria-label":W(`newChat`),children:(0,K.jsx)(n,{className:`size-4`})})]}),(0,K.jsx)(`div`,{className:G(V,`flex-1 min-h-0`,u?et:$e),children:(0,K.jsx)(`div`,{className:tt,children:(0,K.jsx)(`div`,{className:`h-full overflow-y-auto`,children:C.length===0&&!M?(0,K.jsx)(`div`,{className:`px-3 py-3 text-xs text-muted-foreground/55`,children:W(`noSavedConversations`)}):(0,K.jsxs)(`div`,{className:`space-y-0.5`,children:[C.map(e=>{let t=_===e.id,n=Ht===e.id,r=Kt===e.id;return(0,K.jsx)(`div`,{className:G(`grid transition-[grid-template-rows,opacity,transform] duration-[360ms] ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none`,r?`grid-rows-[0fr] -translate-x-1 opacity-0`:`grid-rows-[1fr] translate-x-0 opacity-100`),children:(0,K.jsx)(`div`,{className:`min-h-0 overflow-hidden`,children:(0,K.jsxs)(`div`,{className:G(nt,t?it:st,r&&`pointer-events-none scale-[0.98] opacity-0 duration-[360ms] ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none`),onMouseEnter:t=>Cn(t,e.id),onClickCapture:()=>wn(e.id),onMouseLeave:()=>{Ut(t=>t===e.id?null:t),r||Gt(t=>t===e.id?null:t),wn(e.id)},children:[(0,K.jsxs)(`button`,{className:ht,type:`button`,"aria-busy":y===e.id,onClick:()=>Me(e.id),children:[(0,K.jsxs)(`div`,{className:gt,children:[_t(e.id),le(e)===`running`?(0,K.jsx)(`span`,{className:`size-1.5 shrink-0 rounded-full bg-emerald-500`}):null,(0,K.jsx)(Is,{className:G(U,t&&bt),title:Fn(e.title,e.channelName)})]}),e.pinnedAt?(0,K.jsx)(`button`,{type:`button`,className:G(vt,!n&&yt),onClick:t=>{t.stopPropagation(),Fe(e.id)},"aria-label":W(`unpinSession`),title:W(`unpinSession`),children:(0,K.jsx)(a,{className:`size-3`})}):null,(0,K.jsx)(`span`,{className:G(xt,!n&&yt),children:Ns(x===`createdAt`?e.createdAt:e.lastModified)})]}),(0,K.jsx)(`div`,{className:G(ft,n&&`hidden`),children:Wt===e.id?(0,K.jsx)(q,{variant:`destructive`,size:`sm`,className:`h-6 rounded-full px-2 text-xs`,onClick:t=>In(t,e.id),"aria-label":W(`confirmArchive`),title:W(`confirmArchive`),children:W(`confirm`)}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:mt,onClick:t=>Nn(t,e.id),"aria-label":e.pinnedAt?W(`unpinSession`):W(`pinSession`),children:(0,K.jsx)(a,{className:`size-3.5`})}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:mt,onClick:t=>Pn(t,e.id),"aria-label":W(`archiveSession`),children:(0,K.jsx)(d,{className:`size-4`})})]})})]})})},e.id)}),(0,K.jsx)(Fs,{onLoadMore:ie,enabled:M&&!N})]})})})})]})]}):null,(0,K.jsxs)(`div`,{className:`mt-auto shrink-0 border-t border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-3 py-3`,children:[We&&Ge?(0,K.jsxs)(`button`,{type:`button`,className:G(rt,`relative mb-2 w-full border border-primary/30 bg-primary/5 text-primary hover:bg-primary/10`),onClick:He,"aria-label":W(`newVersionAvailable`,{version:Ge}),title:W(`newVersionAvailable`,{version:Ge}),children:[(0,K.jsx)(`span`,{className:G(ct,`text-primary/80`),children:(0,K.jsx)(i,{className:`size-4`})}),e?(0,K.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,K.jsx)(`span`,{className:`block truncate text-xs font-medium leading-tight`,children:W(`newVersionAvailable`,{version:Ge})}),Ke?(0,K.jsx)(`span`,{className:`block truncate text-[11px] leading-tight text-primary/70`,children:W(`newVersionAvailableSub`,{current:Ke})}):null]}):null,e&&Ue?(0,K.jsx)(`span`,{className:`shrink-0 rounded-full px-1.5 py-0.5 text-[11px] text-primary/60 transition-colors hover:bg-primary/15 hover:text-primary`,role:`button`,tabIndex:0,onClick:e=>{e.stopPropagation(),Ue()},onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.stopPropagation(),e.preventDefault(),Ue())},children:W(`updateLater`)}):null,e?null:(0,K.jsx)(`span`,{className:`absolute right-1 top-1 size-2 rounded-full bg-primary`})]}):null,ze&&Ve?(0,K.jsxs)(`button`,{type:`button`,className:G(rt,`min-h-9 w-full shrink-0 rounded-lg`,ot),onClick:Ve,"aria-label":Be?`${Be}(${ze})`:ze,title:ze,children:[(0,K.jsx)(`span`,{className:ct,children:(0,K.jsx)(ee,{className:`size-4`})}),e?Be?(0,K.jsx)(`span`,{className:G(U,`min-w-0 flex-1`),children:Be}):(0,K.jsx)(`span`,{className:G(U,`min-w-0 flex-1`),children:ze}):null]}):null,(0,K.jsxs)(`button`,{type:`button`,className:G(rt,`min-h-9 w-full shrink-0 rounded-lg`,ot),onClick:Re,"aria-label":W(`settings`),title:W(`settings`),children:[(0,K.jsx)(`span`,{className:ct,children:(0,K.jsx)(re,{className:`size-4`})}),e?(0,K.jsx)(`span`,{className:U,children:W(`settings`)}):null]})]}),Jt?(()=>{let e=yn.find(e=>e.session.id===Jt.sessionId)?.session;if(!e)return null;let t=Je?.sessionId===e.id;return(0,qr.createPortal)((0,K.jsxs)(`div`,{className:`pointer-events-none fixed z-50 w-[min(24rem,calc(100vw-1rem))] max-w-sm rounded-2xl border border-border bg-popover px-4 py-3 text-left shadow-quickforge`,style:{left:Jt.x,top:Jt.y,transform:`translateY(-50%)`},children:[(0,K.jsx)(`div`,{className:`whitespace-normal break-words text-sm font-medium leading-5 text-foreground/92`,children:Fn(e.title,e.channelName)}),t&&Je?.gitBranch?(0,K.jsxs)(`div`,{className:wt,children:[(0,K.jsx)(pe,{className:`size-4 shrink-0 text-muted-foreground/60`}),(0,K.jsx)(`span`,{className:`truncate`,children:Je.gitBranch})]}):null,t&&Je?.context?(0,K.jsxs)(`div`,{className:wt,title:Je.context.title,children:[(0,K.jsx)(P,{className:`size-4 shrink-0 text-muted-foreground/60`}),(0,K.jsx)(`span`,{className:`size-2 shrink-0 rounded-full`,style:{backgroundColor:Je.context.color}}),(0,K.jsx)(`span`,{className:`truncate`,children:Je.context.label})]}):null]}),document.body)})():null,Pt&&It?(0,qr.createPortal)((0,K.jsxs)(`div`,{className:`fixed z-50 overflow-hidden rounded-2xl border border-border bg-background p-1.5 shadow-quickforge`,style:{left:It.x,top:It.y,width:Ts},role:`menu`,"aria-label":W(`filterSort`),onClick:e=>e.stopPropagation(),children:[(0,K.jsx)(`div`,{className:St,children:W(`sidebarView`)}),(0,K.jsxs)(`button`,{type:`button`,role:`menuitemradio`,"aria-checked":b===`project`,className:Ct,onClick:()=>On(`project`),children:[(0,K.jsx)(A,{className:`size-4 shrink-0 text-muted-foreground/70`}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:W(`sidebarViewByProject`)}),b===`project`?(0,K.jsx)(S,{className:`size-4 shrink-0 text-muted-foreground/70`}):(0,K.jsx)(`span`,{className:`size-4 shrink-0`})]}),(0,K.jsxs)(`button`,{type:`button`,role:`menuitemradio`,"aria-checked":b===`timeline`,className:Ct,onClick:()=>On(`timeline`),children:[(0,K.jsx)(be,{className:`size-4 shrink-0 text-muted-foreground/70`}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:W(`sidebarViewTimeline`)}),b===`timeline`?(0,K.jsx)(S,{className:`size-4 shrink-0 text-muted-foreground/70`}):(0,K.jsx)(`span`,{className:`size-4 shrink-0`})]}),(0,K.jsx)(`div`,{className:`my-1 border-t`,style:{borderColor:`color-mix(in oklab, var(--muted-foreground) 50%, transparent)`}}),(0,K.jsx)(`div`,{className:St,children:W(`sortBy`)}),(0,K.jsxs)(`button`,{type:`button`,role:`menuitemradio`,"aria-checked":x===`updatedAt`,className:Ct,onClick:()=>kn(`updatedAt`),children:[(0,K.jsx)(be,{className:`size-4 shrink-0 text-muted-foreground/70`}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:W(`sortByUpdatedAt`)}),x===`updatedAt`?(0,K.jsx)(S,{className:`size-4 shrink-0 text-muted-foreground/70`}):(0,K.jsx)(`span`,{className:`size-4 shrink-0`})]}),(0,K.jsxs)(`button`,{type:`button`,role:`menuitemradio`,"aria-checked":x===`createdAt`,className:Ct,onClick:()=>kn(`createdAt`),children:[(0,K.jsx)(l,{className:`size-4 shrink-0 text-muted-foreground/70`}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:W(`sortByCreatedAt`)}),x===`createdAt`?(0,K.jsx)(S,{className:`size-4 shrink-0 text-muted-foreground/70`}):(0,K.jsx)(`span`,{className:`size-4 shrink-0`})]})]}),document.body):null,fn&&Mt?(0,qr.createPortal)((0,K.jsxs)(`div`,{className:`fixed z-50 min-w-48 overflow-hidden rounded-lg border border-border bg-background p-1 shadow-quickforge`,style:{left:Mt.x,top:Mt.y},onClick:e=>e.stopPropagation(),children:[Ae?(0,K.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-2 whitespace-nowrap rounded-md px-2 py-1.5 text-left text-sm text-foreground/86 transition-colors hover:bg-muted`,title:W(`openInExplorer`),"aria-label":W(`openInExplorer`),onClick:()=>{An(),Ae(fn)},children:[(0,K.jsx)(he,{className:`size-4 shrink-0 text-muted-foreground/70`}),(0,K.jsx)(`span`,{children:W(`openFolder`)})]}):null,(0,K.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-2 whitespace-nowrap rounded-md px-2 py-1.5 text-left text-sm text-foreground/86 transition-colors hover:bg-muted`,onClick:()=>{An(),ke(fn)},children:[(0,K.jsx)(ye,{className:`size-4 shrink-0 text-muted-foreground/70`}),(0,K.jsx)(`span`,{children:W(`manageProjectSkills`)})]}),Rt===fn.id?(0,K.jsx)(`button`,{type:`button`,className:`flex w-full items-center justify-center gap-2 whitespace-nowrap rounded-md bg-destructive px-2 py-1.5 text-left text-sm font-medium text-destructive-foreground transition-colors hover:bg-destructive/90`,"aria-label":W(`confirmDelete`),onClick:e=>Mn(e,fn.id),children:(0,K.jsx)(`span`,{children:W(`confirm`)})}):(0,K.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-2 whitespace-nowrap rounded-md px-2 py-1.5 text-left text-sm text-destructive transition-colors hover:bg-destructive/10`,"aria-label":W(`deleteProject`),onClick:e=>jn(e,fn.id),children:[(0,K.jsx)(me,{className:`size-4 shrink-0`}),(0,K.jsx)(`span`,{children:W(`deleteProject`)})]})]}),document.body):null,Et?(0,K.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-start justify-center bg-background/50 px-4 pt-[12vh] backdrop-blur-sm`,role:`dialog`,"aria-modal":`true`,onMouseDown:()=>Dt(!1),children:(0,K.jsxs)(`div`,{className:`w-full max-w-xl rounded-2xl border border-border bg-popover p-3 shadow-quickforge`,onMouseDown:e=>e.stopPropagation(),children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2 rounded-xl border border-input bg-background px-3 py-2`,children:[(0,K.jsx)(Se,{className:`size-4 shrink-0 text-muted-foreground/60`}),(0,K.jsx)(`input`,{ref:vn,value:Ot,onChange:e=>kt(e.target.value),onKeyDown:e=>{e.key===`Escape`&&Dt(!1)},placeholder:W(`searchDialog`),className:`min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground/45`})]}),(0,K.jsx)(`div`,{className:`mt-2 max-h-[50vh] overflow-y-auto`,children:Ot.trim()?bn.length>0?bn.map(({session:e,projectName:t})=>(0,K.jsxs)(`button`,{type:`button`,"aria-busy":y===e.id,className:`flex w-full items-center gap-2 rounded-xl px-3 py-2 text-left transition-colors hover:bg-muted/28`,onClick:()=>Sn(e.id),children:[_t(e.id),(0,K.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,K.jsx)(`span`,{className:`block truncate text-sm text-foreground/90`,children:Fn(e.title,e.channelName)}),(0,K.jsxs)(`span`,{className:`block truncate text-[11px] text-muted-foreground/55`,children:[t||W(`normalChat`),` · `,Ns(e.lastModified)]})]})]},e.id)):(0,K.jsx)(`div`,{className:`px-3 py-3 text-xs text-muted-foreground/55`,children:W(`noSearchResults`)}):(0,K.jsx)(`div`,{className:`px-3 py-3 text-xs text-muted-foreground/55`,children:W(`searchHint`)})})]})}):null]})}),zs=`quickforge:api-cache:v1:`,Bs=1,Vs=256*1024,Hs=new Map;function Us(e){return`${zs}${e}`}function Ws(e,t){return e!=null&&Date.now()-e.cachedAt<=t}function Gs(e){try{let t=globalThis.localStorage?.getItem(Us(e));if(!t)return null;let n=JSON.parse(t);return n.v===Bs?n:null}catch{return null}}function Ks(e,t){let n=Hs.get(e);if(Ws(n,t))return n.value;n&&Hs.delete(e);let r=Gs(e);if(!Ws(r,t)){if(r)try{globalThis.localStorage?.removeItem(Us(e))}catch{}return null}return Hs.set(e,r),r.value}function qs(e,t){let n={v:Bs,cachedAt:Date.now(),value:t};Hs.set(e,n);try{let t=JSON.stringify(n);t.length<=Vs&&globalThis.localStorage?.setItem(Us(e),t)}catch{}}function Js(e){let t=t=>typeof e==`string`?t===e:e.test(t);for(let e of[...Hs.keys()])if(t(e)){Hs.delete(e);try{globalThis.localStorage?.removeItem(Us(e))}catch{}}}typeof window<`u`&&window.addEventListener(`storage`,e=>{e.key&&e.key.startsWith(zs)&&Hs.delete(e.key.slice(24))});var Ys=`quickforge:expanded-project-ids:v1`;function Xs(){try{return globalThis.localStorage}catch{return}}function Zs(e){if(!Array.isArray(e))return[];let t=[];for(let n of e)typeof n==`string`&&n.length>0&&t.push(n);return t}function Qs(){let e=Xs();if(!e)return new Set;try{let t=e.getItem(Ys);return t?new Set(Zs(JSON.parse(t))):new Set}catch{return new Set}}function $s(e){let t=Xs();if(t)try{let n=[...new Set(Array.from(e).filter(e=>typeof e==`string`&&e.length>0))];t.setItem(Ys,JSON.stringify(n))}catch{}}function ec(e,t){let n=new Set(t),r=new Set;for(let t of e)n.has(t)&&r.add(t);return r}var tc=`/api/project`,nc=15*1e3;function rc(){let[e,t]=(0,H.useState)(),[n,r]=(0,H.useState)([]),[i,a]=(0,H.useState)(),[o,s]=(0,H.useState)(()=>Qs()),[c,l]=(0,H.useState)(!1),[u,d]=(0,H.useState)(!1);(0,H.useEffect)(()=>{$s(o)},[o]);let f=(0,H.useCallback)(e=>{t(e.project),r(Array.isArray(e.projects)?e.projects:[]),a(typeof e.defaultWorkspaceRoot==`string`&&e.defaultWorkspaceRoot?{id:`default`,name:`workspace`,path:e.defaultWorkspaceRoot,lastOpenedAt:``}:void 0),s(t=>ec(t,(Array.isArray(e.projects)?e.projects:[]).map(e=>e.id)))},[]);return{activeProject:e,projects:n,defaultWorkspace:i,expandedProjectIds:o,selectingProject:c,projectPickerOpen:u,loadProject:(0,H.useCallback)(async(e=!1)=>{try{if(!e){let e=Ks(tc,nc);if(e){f(e);return}}let t=await fetch(`/api/project`);if(!t.ok)return;let n=await t.json();qs(tc,n),f(n)}catch(e){V.error(`Failed to load project:`,e)}},[f]),switchActiveProject:(0,H.useCallback)(async e=>{let n=await fetch(`/api/project/active`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({id:e})}),i=await n.json().catch(()=>null);if(!n.ok)throw Error(i?.error||`Project switch failed with HTTP ${n.status}`);return t(i.project),r(Array.isArray(i.projects)?i.projects:[]),s(new Set([e])),Js(tc),i.project},[]),handleSelectProjectPath:(0,H.useCallback)(async e=>{l(!0);try{let n=await fetch(`/api/project/path`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({path:e})}),i=await n.json().catch(()=>null);if(!n.ok)throw Error(i?.error||`Project selection failed with HTTP ${n.status}`);i?.project&&(t(i.project),r(Array.isArray(i.projects)?i.projects:[]),Js(tc),s(e=>ec(e,(Array.isArray(i.projects)?i.projects:[]).map(e=>e.id))))}catch(e){throw V.error(`Failed to select project:`,e),e}finally{l(!1)}},[]),selectProjectDirectory:(0,H.useCallback)(()=>{d(!0)},[]),setProjectPickerOpen:d,toggleProjectExpanded:(0,H.useCallback)(e=>{s(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),toggleAllProjectsExpanded:(0,H.useCallback)(()=>{s(e=>e.size===n.length&&n.length>0?new Set:new Set(n.map(e=>e.id)))},[n]),reorderProjects:(0,H.useCallback)(async e=>{r(t=>{let n=new Map(t.map(e=>[e.id,e])),r=[];for(let t of e){let e=n.get(t);e&&(r.push(e),n.delete(t))}return r});try{let t=await fetch(`/api/project/reorder`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify({orderedIds:e})}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||`Reorder failed with HTTP ${t.status}`);Array.isArray(n?.projects)&&r(n.projects),Js(tc)}catch(e){V.error(`Failed to reorder projects:`,e)}},[]),setActiveProject:t,setProjects:r,setExpandedProjectIds:s}}function ic(){let[e,t]=(0,H.useState)(`default`);return{agentAccessMode:e,setAgentAccessMode:t,initialize:(0,H.useCallback)(async e=>{let n=await _r(e);return t(n),n},[])}}var ac=`quickforge:default-harness-changed`,oc=`quickforge-sync`,sc=X();function cc(){return sc}function lc(e){if(window.dispatchEvent(new CustomEvent(ac,{detail:{harness:e}})),!(typeof BroadcastChannel>`u`))try{let t=new BroadcastChannel(oc);t.postMessage({type:`settings-changed`,settings:{defaultHarness:e},sourceTabId:sc,timestamp:Date.now()}),t.close()}catch{}}var uc=`quickforge-sync`;function dc(e){let t=(0,H.useRef)(e);(0,H.useEffect)(()=>{t.current=e});let n=(0,H.useRef)(cc()),r=(0,H.useRef)(null);(0,H.useEffect)(()=>{if(typeof BroadcastChannel<`u`)try{let e=new BroadcastChannel(uc);r.current=e;let i=e=>{let r=e.data;if(!(!r||r.sourceTabId===n.current))switch(r.type){case`sessions-changed`:t.current.onSessionsChanged();break;case`projects-changed`:t.current.onProjectsChanged();break;case`settings-changed`:t.current.onSettingsChanged(r.settings);break}};return e.addEventListener(`message`,i),()=>{e.removeEventListener(`message`,i),e.close()}}catch{r.current=null}},[]),(0,H.useEffect)(()=>{let e=()=>{document.visibilityState===`visible`&&(t.current.onSessionsChanged(),t.current.onProjectsChanged())};return document.addEventListener(`visibilitychange`,e),()=>{document.removeEventListener(`visibilitychange`,e)}},[]);let i=(0,H.useCallback)((e,t)=>{let i={type:e,sourceTabId:n.current,timestamp:Date.now(),settings:t};r.current?.postMessage(i)},[]);return{notifySessionsChanged:(0,H.useCallback)(()=>i(`sessions-changed`),[i]),notifyProjectsChanged:(0,H.useCallback)(()=>i(`projects-changed`),[i]),notifySettingsChanged:(0,H.useCallback)(e=>i(`settings-changed`,e),[i])}}function fc(e){return e===`assistant`||e===`user`||e===`user-with-attachments`}function pc(e,t){let n=t.toolCallId;if(t.role===`toolResult`&&typeof n==`string`){let r=e.findIndex(e=>e.role===`toolResult`&&e.toolCallId===n);if(r>=0){let n=e.slice();return n[r]=t,n}return[...e,t]}if(fc(t.role)){let n=t.timestamp;if(n!==void 0){let r=e.findIndex(e=>e.role===t.role&&e.timestamp===n);if(r>=0){let n=e.slice();return n[r]=t,n}}}let r=e.slice(),i=r.length-1;return i>=0&&r[i]?.role===t.role?r[i]=t:r.push(t),r}function mc(e){return!!(e&&typeof e==`object`&&!Array.isArray(e))}function hc(e){if(!mc(e))return;let t=e.quickforgeTiming;if(!mc(t))return;let n=typeof t.startedAt==`number`?t.startedAt:void 0,r=typeof t.finishedAt==`number`?t.finishedAt:void 0,i=typeof t.durationMs==`number`?t.durationMs:void 0;if(!(n===void 0&&r===void 0&&i===void 0))return{startedAt:n,finishedAt:r,durationMs:i}}function gc(e,t){return mc(e)?{...e,quickforgeTiming:t}:{quickforgeTiming:t}}function _c(e,t){let n=e.quickforgeTiming??hc(e.partialResult?.details)??{startedAt:Date.now()};return{...e,partialResult:e.partialResult??{content:[],details:{quickforgeTiming:n,sessionId:t,toolCallId:e.toolCallId}}}}function vc(e,t,n){if(!t.toolCallId||!t.toolName)return e;let r=n?t.partialResult:t.result;if(!r)return e;let i=hc(r.details)??t.quickforgeTiming;if(!i){let n=e.findIndex(e=>e.role===`toolResult`&&e.toolCallId===t.toolCallId);n>=0&&(i=hc(e[n].details))}let a=i?gc(r.details,i):r.details,o=mc(a)?{...a,sessionId:a.sessionId??t.sessionId,toolCallId:a.toolCallId??t.toolCallId}:a;return pc(e,{role:`toolResult`,toolCallId:t.toolCallId,toolName:t.toolName,content:r.content??[],details:o,isError:n?!1:t.isError,timestamp:Date.now()})}function yc(){return``}var bc=5e3,xc=15e3,Sc=1e4,Cc=3e4,wc={GENERATION_ALREADY_RUNNING:`generationAlreadyRunning`,GENERATION_STILL_RUNNING_BEFORE_ROLLBACK:`generationStillRunning`};function Tc(e,t){let n=e?.code?wc[e.code]:void 0;return n?W(n):e?.error||t}async function Ec(e,t,n={}){let r=new AbortController,i=n.signal,a=()=>r.abort(i?.reason);i?.aborted?a():i?.addEventListener(`abort`,a,{once:!0});let o=setTimeout(()=>r.abort(),t);try{let t=await fetch(e,{...n,signal:r.signal});return{response:t,body:await t.json().catch(()=>void 0)}}finally{clearTimeout(o),i?.removeEventListener(`abort`,a)}}var Dc=new class{eventSource=null;handlersBySession=new Map;baseUrl=``;reconnectTimer=null;reconnectDelay=1e3;directBaseUrl=yc();fallbackBaseUrl=``;subscribe(e,t,n){this.fallbackBaseUrl=t;let r=this.directBaseUrl||this.fallbackBaseUrl;(!this.eventSource||this.baseUrl!==r)&&(this.disconnect(),this.baseUrl=r,this.connect());let i=this.handlersBySession.get(e);return i||(i=new Set,this.handlersBySession.set(e,i)),i.add(n),()=>{let t=this.handlersBySession.get(e);t?.delete(n),t?.size===0&&this.handlersBySession.delete(e),this.handlersBySession.size===0&&this.globalHandlers.size===0&&this.disconnect()}}globalHandlers=new Set;subscribeAll(e,t){this.fallbackBaseUrl=e;let n=this.directBaseUrl||this.fallbackBaseUrl;return(!this.eventSource||this.baseUrl!==n)&&(this.disconnect(),this.baseUrl=n,this.connect()),this.globalHandlers.add(t),()=>{this.globalHandlers.delete(t),this.handlersBySession.size===0&&this.globalHandlers.size===0&&this.disconnect()}}connect(){let e=`${this.baseUrl}/api/agents/events`;this.eventSource=new EventSource(e),this.eventSource.onopen=()=>{this.reconnectDelay=1e3};let t=[`state`,`agent_start`,`agent_end`,`message_start`,`message_end`,`turn_start`,`turn_end`,`message_update`,`tool_execution_start`,`tool_execution_update`,`tool_execution_end`,`error`,`session_created`,`title_updated`,`session_forked`,`scheduled_task_notification`,`scheduled_task_started`,`tool_approval_required`,`auto_compact_threshold_reached`,`auto_compact_approval_required`,`auto_compact_completed`,`auto_compact_failed`,`messages_replaced`,`acp_session_usage_update`,`acp_session_update`],n=e=>t=>{try{let n=JSON.parse(t.data),r=n.sessionId;if(!r&&e!==`scheduled_task_notification`)return;let i=e?{type:e,...n}:n;r?this.emit(r,i):this.emitGlobal(i)}catch{}};this.eventSource.onmessage=n();for(let e of t)this.eventSource.addEventListener(e,n(e));this.eventSource.onerror=()=>{if(this.eventSource?.close(),this.eventSource=null,this.baseUrl===this.directBaseUrl&&this.fallbackBaseUrl!==this.directBaseUrl){this.baseUrl=this.fallbackBaseUrl,this.connect();return}this.scheduleReconnect()}}scheduleReconnect(){this.reconnectTimer||this.handlersBySession.size===0&&this.globalHandlers.size===0||(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,!(this.handlersBySession.size===0&&this.globalHandlers.size===0)&&(this.reconnectDelay=Math.min(this.reconnectDelay*2,3e4),this.connect())},this.reconnectDelay))}emitGlobal(e){for(let t of this.globalHandlers)try{t(e)}catch{}}emit(e,t){this.emitGlobal(t);let n=this.handlersBySession.get(e);if(n)for(let e of n)try{e(t)}catch{}}disconnect(){this.reconnectTimer&&=(clearTimeout(this.reconnectTimer),null),this.eventSource?.close(),this.eventSource=null}},Oc=200,kc=null;function Ac(e=``){let t=Date.now(),n=kc;if(n&&n.baseUrl===e&&t-n.startedAt<Oc)return n.promise;let r=(async()=>{let t=await fetch(`${e}/api/agents`,{cache:`no-store`});if(!t.ok)return[];let n=await t.json().catch(()=>null);return Array.isArray(n?.sessions)?n.sessions:[]})();return kc={baseUrl:e,startedAt:t,promise:r},r.finally(()=>{kc?.promise===r&&(kc=null)}),r}function jc(e,t=``){return Dc.subscribeAll(t,e)}var Mc=class e{state;streamFn=Ze;getApiKey;sessionId;listeners=new Set;unsubscribeSse;baseUrl;disposed=!1;_syncingThinkingLevel=!1;pollTimer=null;refreshPromise=null;statusPromise=null;lastSseEventAt=Date.now();lastServerStateVersion=0;nextPromptCapabilities=[];planMode=!1;harness;harnessSessionId;onPlanModeConsumed;stateVersion=0;constructor(e){this.sessionId=e.sessionId,this.baseUrl=e.baseUrl??``;let t=e.initialState??{};this.harness=t.harness??`quickforge`,this.harnessSessionId=t.harnessSessionId,this.lastServerStateVersion=typeof t.stateVersion==`number`?t.stateVersion:0;let n={systemPrompt:t.systemPrompt??``,model:t.model??null,thinkingLevel:t.thinkingLevel??`off`,messages:t.messages?.slice()??[],tools:t.tools??[],accessMode:Nn(t.accessMode,Mn(t.yoloMode)),harness:t.harness??`quickforge`,yoloMode:Pn(Nn(t.accessMode,Mn(t.yoloMode))),isStreaming:t.isStreaming??!1,streamingMessage:void 0,pendingToolCalls:new Set(t.pendingToolCalls??[]),errorMessage:t.errorMessage,contextCompaction:t.contextCompaction??null,contextUsage:t.contextUsage??null,pendingToolApproval:t.pendingToolApproval??null,pendingAutoCompactApproval:t.pendingAutoCompactApproval??null,acpSession:t.acpSession??null};this.state=new Proxy(n,{set:(e,t,n)=>{let r=e[t];return e[t]=n,t===`thinkingLevel`&&!this._syncingThinkingLevel&&n!==r&&this.updateThinkingLevel(n),!0}}),this.unsubscribeSse=Dc.subscribe(this.sessionId,this.baseUrl,e=>this.handleSseEvent(e)),this.state.isStreaming&&this.startStateWatchdog()}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}setNextPromptCapabilities(e){this.nextPromptCapabilities=Array.isArray(e)?e.slice(0,4):[]}setPlanMode(e,t){this.planMode=e,this.onPlanModeConsumed=e?t:void 0}async prompt(e){if(this.disposed)return;if(this.state.isStreaming){V.warn(`Ignored prompt while agent is already streaming`);return}let t;t=typeof e==`string`?{role:`user`,content:e,timestamp:Date.now()}:Array.isArray(e)?[...e].reverse().find(e=>e.role===`user`||e.role===`user-with-attachments`)??e[e.length-1]:e;let n=t.metadata&&typeof t.metadata==`object`&&!Array.isArray(t.metadata)?t.metadata:{};nt(this.state.model)&&(typeof n.quickforgeClientMessageId!=`string`||!n.quickforgeClientMessageId)&&(t={...t,metadata:{...n,quickforgeClientMessageId:`qfcm_${X()}`}});let r=this.nextPromptCapabilities,i=this.planMode?{type:`plan`}:void 0;if(this.nextPromptCapabilities=[],this.planMode){this.planMode=!1;let e=this.onPlanModeConsumed;this.onPlanModeConsumed=void 0,e?.()}let a=this.state.messages.length,o=t;this.state.messages=[...this.state.messages,o],this.state.contextUsage=null,this.emitToListeners({type:`message_start`,message:o}),this.state.isStreaming||(this.state.isStreaming=!0,this.state.errorMessage=void 0,this.emitToListeners({type:`agent_start`}));let s=new AbortController,c=setTimeout(()=>s.abort(),3e4),l=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/prompt`;fetch(l,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({message:o,selectedCapabilities:r,command:i}),signal:s.signal}).then(async e=>{if(clearTimeout(c),!e.ok){let t=await e.json().catch(()=>null);throw Error(Tc(t,`Failed to send prompt: HTTP ${e.status}`))}}).catch(e=>{clearTimeout(c);let t=e instanceof Error?e.message:String(e);V.error(`Failed to send prompt:`,e),this.state.messages.length===a+1&&this.state.messages[this.state.messages.length-1]===o&&(this.state.messages=this.state.messages.slice(0,-1)),this.state.errorMessage=t,this.state.isStreaming=!1,this.state.streamingMessage=void 0,this.stopStateWatchdog(),this.emitToListeners({type:`error`,error:t}),this.emitToListeners({type:`agent_end`,messages:this.state.messages})}),this.startStateWatchdog()}abort(){let e=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/abort`;fetch(e,{method:`POST`}).catch(e=>{V.error(`Failed to abort:`,e)})}steer(e){let t=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/steer`;fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({message:e})}).catch(e=>{V.error(`Failed to send steer:`,e)})}followUp(e){let t=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/follow-up`;fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({message:e})}).catch(e=>{V.error(`Failed to send follow-up:`,e)})}reset(){this.state.messages=[],this.state.errorMessage=void 0,this.state.isStreaming=!1,this.state.streamingMessage=void 0,this.state.pendingToolCalls=new Set,this.state.pendingToolApproval=null,this.state.pendingAutoCompactApproval=null}async updateAccessMode(e){let t=Nn(e),n=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/access-mode`,r=await fetch(n,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({accessMode:t})});if(!r.ok){let e=await r.json().catch(()=>null);throw Error(e?.error||`Failed to sync Agent access mode: HTTP ${r.status}`)}this.state.accessMode=t,this.state.yoloMode=Pn(t)}async updateYoloMode(e){await this.updateAccessMode(e?`full-access`:`default`)}async updateModel(e){let t=this.state.model;this.state.model=e,this.state.contextUsage=null;let n=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/model`;try{let t=await fetch(n,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({modelRef:tt(e),model:e})}),r=await t.json().catch(()=>null);if(!t.ok)throw Error(r?.error||`Failed to sync model update: HTTP ${t.status}`);r?.model&&(this.state.model=r.model)}catch(e){throw this.state.model=t,V.error(`Failed to sync model update to server:`,e),e}}async updateThinkingLevel(e){let t=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/thinking-level`;fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({thinkingLevel:e})}).catch(e=>{V.error(`Failed to sync thinking level update to server:`,e)})}async rollback(e){let t=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/rollback`,n=await fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({messageIndex:e})}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(Tc(r,`Failed to roll back: HTTP ${n.status}`));return r}async continue(){let e=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/continue`,t=await fetch(e,{method:`POST`});if(!t.ok){let e=await t.json().catch(()=>null);throw Error(Tc(e,`Failed to continue: HTTP ${t.status}`))}this.state.isStreaming=!0,this.state.errorMessage=void 0,this.startStateWatchdog()}async setConfigOption(e,t){let n=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/harness/config-option`,r=await fetch(n,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({configId:e,value:t})}),i=await r.json().catch(()=>null);if(!r.ok)throw Error(i?.error||`Failed to update OpenCode config option: HTTP ${r.status}`);i?.acpSession&&(this.state.acpSession=i.acpSession,this.emitToListeners({type:`acp_session_update`,acpSession:i.acpSession}))}async setMode(e){let t=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/harness/mode`,n=await fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({modeId:e})}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||`Failed to update OpenCode mode: HTTP ${n.status}`);r?.acpSession&&(this.state.acpSession=r.acpSession,this.emitToListeners({type:`acp_session_update`,acpSession:r.acpSession}))}async forkSession(){let e=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/fork`,t=await fetch(e,{method:`POST`}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||`Failed to fork conversation: HTTP ${t.status}`);return n}async approveToolCall(e){let t=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/approve-tool`,n=await fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({toolCallId:e})});if(!n.ok){let e=await n.json().catch(()=>null);throw Error(e?.error||`Failed to approve tool call: HTTP ${n.status}`)}this.state.pendingToolApproval?.toolCallId===e&&(this.state.pendingToolApproval=null)}async rejectToolCall(e){let t=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/reject-tool`,n=await fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({toolCallId:e})});if(!n.ok){let e=await n.json().catch(()=>null);throw Error(e?.error||`Failed to reject tool call: HTTP ${n.status}`)}this.state.pendingToolApproval?.toolCallId===e&&(this.state.pendingToolApproval=null)}async approveAutoCompact(e){let t=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/approve-auto-compact`,n=await fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({approvalId:e})});if(!n.ok){let e=await n.json().catch(()=>null);throw Error(e?.error||`Failed to approve auto compact: HTTP ${n.status}`)}this.state.pendingAutoCompactApproval?.approvalId===e&&(this.state.pendingAutoCompactApproval=null)}async rejectAutoCompact(e){let t=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/reject-auto-compact`,n=await fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({approvalId:e})});if(!n.ok){let e=await n.json().catch(()=>null);throw Error(e?.error||`Failed to reject auto compact: HTTP ${n.status}`)}this.state.pendingAutoCompactApproval?.approvalId===e&&(this.state.pendingAutoCompactApproval=null)}dispose(){this.disposed=!0,this.pollTimer&&=(clearInterval(this.pollTimer),null),this.statusPromise=null,this.unsubscribeSse?.(),this.unsubscribeSse=void 0,this.listeners.clear()}handleSseEvent(e){if(this.noteSseEvent(e)){switch(e.type){case`state`:{let t=e;if(t.systemPrompt!==void 0&&(this.state.systemPrompt=t.systemPrompt),t.messages&&(t.messages.length>this.state.messages.length||!this.state.isStreaming&&t.messages.length===this.state.messages.length)&&(this.state.messages=t.messages,this.stateVersion++),t.model&&(this.state.model=t.model),t.thinkingLevel&&(this._syncingThinkingLevel=!0,this.state.thinkingLevel=t.thinkingLevel,this._syncingThinkingLevel=!1),t.accessMode!==void 0||t.yoloMode!==void 0){let e=Nn(t.accessMode,Mn(t.yoloMode));this.state.accessMode=e,this.state.yoloMode=Pn(e)}t.tools&&(this.state.tools=t.tools),t.contextCompaction!==void 0&&(this.state.contextCompaction=t.contextCompaction),t.contextUsage===void 0?t.messages&&(this.state.contextUsage=null):this.state.contextUsage=t.contextUsage,t.pendingToolApproval!==void 0&&(this.state.pendingToolApproval=t.pendingToolApproval),t.pendingAutoCompactApproval!==void 0&&(this.state.pendingAutoCompactApproval=t.pendingAutoCompactApproval),t.pendingToolCalls!==void 0&&(this.state.pendingToolCalls=new Set(t.pendingToolCalls)),t.acpSession!==void 0&&(this.state.acpSession=t.acpSession);let n=this.state.isStreaming;t.isStreaming!==void 0&&(n=this.state.isStreaming,this.state.isStreaming=t.isStreaming,t.isStreaming?this.startStateWatchdog():this.stopStateWatchdog()),t.isStreaming?(this.state.errorMessage=void 0,this.emitToListeners({type:`agent_start`})):n&&(this.stateVersion++,this.emitToListeners({type:`agent_end`,messages:this.state.messages}));return}case`agent_start`:this.state.isStreaming=!0,this.state.errorMessage=void 0,this.state.pendingToolApproval=null,this.state.pendingAutoCompactApproval=null,this.startStateWatchdog();break;case`agent_end`:{this.stopStateWatchdog();let t=e;if(t.messages&&t.messages.length>=this.state.messages.length){this.state.messages=t.messages,this.state.contextUsage=t.contextUsage===void 0?null:t.contextUsage,this.state.isStreaming=!1,this.state.streamingMessage=void 0,this.state.pendingToolApproval=null,this.state.pendingAutoCompactApproval=null,t.errorMessage&&(this.state.errorMessage=t.errorMessage),this.stateVersion++,this.emitToListeners(e);return}this.refreshStateFromServer({forceMessages:!0}).finally(()=>{this.state.isStreaming=!1,this.state.streamingMessage=void 0,this.state.pendingToolApproval=null,this.state.pendingAutoCompactApproval=null,t.errorMessage&&(this.state.errorMessage=t.errorMessage),this.emitToListeners(e)});return}case`message_end`:{let t=e;if(t.message){this.state.messages=pc(this.state.messages,t.message),this.state.contextUsage=t.contextUsage===void 0?null:t.contextUsage,this.stateVersion++,this.emitToListeners(e);return}if(t.messages&&t.messages.length>=this.state.messages.length){this.state.messages=t.messages,this.state.contextUsage=t.contextUsage===void 0?null:t.contextUsage,this.stateVersion++,this.emitToListeners(e);return}this.refreshStateFromServer().finally(()=>{this.emitToListeners(e)});return}case`turn_end`:{let t=e;if(t.messages&&t.messages.length>=this.state.messages.length){this.state.messages=t.messages,this.state.contextUsage=t.contextUsage===void 0?null:t.contextUsage,this.stateVersion++,this.emitToListeners(e);return}this.refreshStateFromServer().finally(()=>{this.emitToListeners(e)});return}case`messages_replaced`:{let t=e;t.messages&&(this.state.messages=t.messages,this.state.streamingMessage=void 0,this.stateVersion++),t.contextCompaction!==void 0&&(this.state.contextCompaction=t.contextCompaction),t.contextUsage===void 0?t.messages&&(this.state.contextUsage=null):this.state.contextUsage=t.contextUsage;break}case`error`:{let t=e.error;this.state.errorMessage=t||`Unknown error`,this.state.pendingToolApproval=null,this.state.pendingAutoCompactApproval=null;break}case`title_updated`:break;case`session_forked`:break;case`acp_session_usage_update`:{let t=e;if(t.usage!==void 0){let e=this.state.acpSession?{...this.state.acpSession,usage:t.usage}:{configOptions:[],modes:null,availableCommands:[],sessionInfo:{},usage:t.usage};this.state.acpSession=e}break}case`acp_session_update`:{let t=e;t.acpSession&&(this.state.acpSession=t.acpSession);break}case`tool_execution_start`:{let t=e;t.toolCallId&&(this.state.messages=vc(this.state.messages,_c(t,this.sessionId),!0),this.state.pendingToolCalls=new Set([...this.state.pendingToolCalls,t.toolCallId]),this.stateVersion++);break}case`tool_execution_update`:{let t=e;this.state.messages=vc(this.state.messages,t,!0),t.toolCallId&&(this.state.pendingToolCalls=new Set([...this.state.pendingToolCalls,t.toolCallId])),this.stateVersion++;break}case`tool_execution_end`:{let t=e;if(this.state.messages=vc(this.state.messages,t,!1),t.toolCallId){let e=new Set(this.state.pendingToolCalls);e.delete(t.toolCallId),this.state.pendingToolCalls=e}this.stateVersion++;break}case`auto_compact_completed`:{let t=e;t.contextCompaction!==void 0&&(this.state.contextCompaction=t.contextCompaction),t.contextUsage!==void 0&&(this.state.contextUsage=t.contextUsage);break}case`auto_compact_failed`:case`message_start`:case`message_update`:case`turn_start`:case`auto_compact_threshold_reached`:break;case`tool_approval_required`:{let t=e;typeof t.toolCallId==`string`&&typeof t.toolName==`string`&&(this.state.pendingToolApproval=t,this.state.pendingAutoCompactApproval=null);break}case`auto_compact_approval_required`:{let t=e;typeof t.approvalId==`string`&&(this.state.pendingAutoCompactApproval=t,this.state.pendingToolApproval=null);break}}this.emitToListeners(e)}}emitToListeners(e){for(let t of this.listeners)try{t(e)}catch{}}noteSseEvent(e){this.lastSseEventAt=Date.now();let t=e.stateVersion;if(typeof t==`number`&&Number.isFinite(t)){if(t<this.lastServerStateVersion)return!1;this.lastServerStateVersion=t}return!0}startStateWatchdog(){this.pollTimer||this.disposed||(this.lastSseEventAt=Date.now(),this.pollTimer=setInterval(()=>{if(this.disposed||!this.state.isStreaming){this.stopStateWatchdog();return}Date.now()-this.lastSseEventAt<xc||this.refreshStatusFromServer()},bc))}stopStateWatchdog(){this.pollTimer&&=(clearInterval(this.pollTimer),null)}async refreshStatusFromServer(){return this.statusPromise||=this._doRefreshStatusFromServer().finally(()=>{this.statusPromise=null}),this.statusPromise}async _doRefreshStatusFromServer(){let e=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/status`;try{let{response:t,body:n}=await Ec(e,Sc);if(!t.ok){t.status===404&&this.state.isStreaming&&(this.state.isStreaming=!1,this.stopStateWatchdog(),this.emitToListeners({type:`agent_end`,messages:this.state.messages}));return}let r=n??{};this.lastSseEventAt=Date.now();let i=typeof r.stateVersion==`number`&&Number.isFinite(r.stateVersion)?r.stateVersion:this.lastServerStateVersion;if(r.isStreaming===!1){let e=this.state.isStreaming;this.stopStateWatchdog(),await this.refreshStateFromServer({notify:!0,forceMessages:!0}),e&&this.state.isStreaming&&(this.state.isStreaming=!1,this.state.streamingMessage=void 0,this.state.pendingToolApproval=null,this.state.pendingAutoCompactApproval=null,this.emitToListeners({type:`agent_end`,messages:this.state.messages}));return}r.isStreaming===!0&&(this.state.isStreaming=!0,this.state.errorMessage=r.errorMessage),i>this.lastServerStateVersion&&await this.refreshStateFromServer({notify:!0,forceMessages:!0})}catch{}}async syncState(){await this.refreshStateFromServer({notify:!0,forceMessages:!0})}async refreshStateFromServer(e){return this.refreshPromise||=this._doRefreshStateFromServer(e).finally(()=>{this.refreshPromise=null}),this.refreshPromise}async _doRefreshStateFromServer(e){let t=`${this.baseUrl}/api/agents/${encodeURIComponent(this.sessionId)}/state`;try{let n=this.stateVersion,{response:r,body:i}=await Ec(t,Cc);if(!r.ok){r.status===404&&this.state.isStreaming&&(this.state.isStreaming=!1,this.stopStateWatchdog(),this.emitToListeners({type:`agent_end`,messages:this.state.messages}));return}let a=i??{},o=typeof a.stateVersion==`number`&&Number.isFinite(a.stateVersion)?a.stateVersion:void 0;if(o!==void 0&&o<this.lastServerStateVersion||n!==this.stateVersion)return;o!==void 0&&(this.lastServerStateVersion=o);let s=!!(a.messages&&(e?.forceMessages||a.messages.length>this.state.messages.length||!this.state.isStreaming&&a.messages.length===this.state.messages.length));if(s&&a.messages&&(this.state.messages=a.messages,this.state.contextUsage=a.contextUsage===void 0?null:a.contextUsage,this.stateVersion++),a.systemPrompt!==void 0&&(this.state.systemPrompt=a.systemPrompt),a.model&&(this.state.model=a.model),a.thinkingLevel&&(this._syncingThinkingLevel=!0,this.state.thinkingLevel=a.thinkingLevel,this._syncingThinkingLevel=!1),a.accessMode!==void 0||a.yoloMode!==void 0){let e=Nn(a.accessMode,Mn(a.yoloMode));this.state.accessMode=e,this.state.yoloMode=Pn(e)}if(a.tools&&(this.state.tools=a.tools),a.contextCompaction!==void 0&&(this.state.contextCompaction=a.contextCompaction),a.contextUsage!==void 0&&(this.state.contextUsage=a.contextUsage),a.pendingToolApproval!==void 0&&(this.state.pendingToolApproval=a.pendingToolApproval),a.pendingAutoCompactApproval!==void 0&&(this.state.pendingAutoCompactApproval=a.pendingAutoCompactApproval),a.pendingToolCalls!==void 0&&(this.state.pendingToolCalls=new Set(a.pendingToolCalls)),a.acpSession!==void 0&&(this.state.acpSession=a.acpSession),a.isStreaming!==void 0){let t=this.state.isStreaming;if(this.state.isStreaming=!!a.isStreaming,a.isStreaming?(this.state.errorMessage=void 0,t||this.emitToListeners({type:`agent_start`})):(this.stopStateWatchdog(),this.state.pendingToolApproval=null,this.state.pendingAutoCompactApproval=null),e?.notify&&t&&!a.isStreaming){this.stateVersion++,this.emitToListeners({type:`agent_end`,messages:this.state.messages});return}}if(e?.notify)if(a.isStreaming&&s){let e=this.state.messages[this.state.messages.length-1];e&&this.emitToListeners({type:`message_update`,message:e})}else a.isStreaming||this.emitToListeners({type:`message_end`})}catch{}}static async restore(t,n={}){let r=n.baseUrl??``,i=performance.now(),{response:a,body:o}=await Ec(`${r}/api/agents/${encodeURIComponent(t)}/restore`,Cc,{method:`POST`,signal:n.signal});if(!a.ok)throw Error(o?.error||`Failed to restore agent: HTTP ${a.status}`);if(n.signal?.aborted)throw n.signal.reason??new DOMException(`Aborted`,`AbortError`);let s=o??{},c=new e({sessionId:t,baseUrl:r,initialState:{systemPrompt:s.systemPrompt??``,model:s.model??null,thinkingLevel:s.thinkingLevel??`off`,messages:s.messages??[],tools:s.tools??[],accessMode:Nn(s.accessMode,s.yoloMode),harness:s.harness??`quickforge`,harnessSessionId:s.harnessSessionId,yoloMode:!!s.yoloMode,isStreaming:!!s.isStreaming,pendingToolCalls:s.pendingToolCalls??[],errorMessage:s.errorMessage,contextCompaction:s.contextCompaction,contextUsage:s.contextUsage,pendingToolApproval:s.pendingToolApproval,pendingAutoCompactApproval:s.pendingAutoCompactApproval,acpSession:s.acpSession,stateVersion:s.stateVersion}});return V.debug(`Restored ServerAgent`,{sessionId:t,messageCount:s.messages?.length??0,durationMs:Math.round((performance.now()-i)*10)/10}),{agent:c,snapshot:s}}static async create(t,n={}){let r=n.baseUrl??``,i=n.harness===`opencode`,a=await fetch(`${r}/api/agents/${encodeURIComponent(t)}`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({scope:n.scope??`global`,projectId:n.projectId,source:n.source,channelId:n.channelId,channelName:n.channelName,harness:n.harness,sourceHarnessSessionId:n.sourceHarnessSessionId,accessMode:n.accessMode,yoloMode:n.yoloMode??Pn(Nn(n.accessMode)),modelRef:!i&&n.model?tt(n.model):void 0,model:i?void 0:n.model,thinkingLevel:i?void 0:n.thinkingLevel??`off`,messages:n.messages??[],title:n.title??`New chat`,contextCompaction:n.contextCompaction})});if(!a.ok){let e=await a.json().catch(()=>({error:`Failed to create agent`}));throw Error(e.error||`Failed to create agent`)}let o={};try{let{response:e,body:n}=await Ec(`${r}/api/agents/${encodeURIComponent(t)}/state`,Cc);e.ok&&(o=n??{})}catch{}return new e({sessionId:t,baseUrl:r,initialState:{systemPrompt:o.systemPrompt??``,model:o.model??n.model??null,thinkingLevel:o.thinkingLevel??n.thinkingLevel??`off`,messages:o.messages??n.messages??[],tools:o.tools??[],accessMode:Nn(o.accessMode,n.accessMode??o.yoloMode??n.yoloMode),harness:o.harness??n.harness??`quickforge`,harnessSessionId:o.harnessSessionId,yoloMode:!!(o.yoloMode??n.yoloMode),isStreaming:!!o.isStreaming,pendingToolCalls:o.pendingToolCalls??[],errorMessage:o.errorMessage,contextCompaction:o.contextCompaction,contextUsage:o.contextUsage,pendingToolApproval:o.pendingToolApproval,pendingAutoCompactApproval:o.pendingAutoCompactApproval,acpSession:o.acpSession,stateVersion:o.stateVersion}})}},Nc=class{sessionId;streamFn=Ze;getApiKey;scope;project;harness;createAgent;listeners=new Set;disposed=!1;realAgentPromise;promotedAgent;nextPromptCapabilities=[];planMode=!1;onPlanModeConsumed;state;constructor(e){this.sessionId=`pending-${X()}`,this.scope=e.scope,this.project=e.project,this.harness=e.harness,this.createAgent=e.createAgent;let t=Nn(e.accessMode,e.yoloMode?`full-access`:`default`);this.state={systemPrompt:``,model:e.model,thinkingLevel:e.thinkingLevel,messages:[],tools:[],accessMode:t,yoloMode:Pn(t),isStreaming:!1,pendingToolCalls:new Set,contextCompaction:null,contextUsage:null}}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}setNextPromptCapabilities(e){this.nextPromptCapabilities=Array.isArray(e)?e.slice(0,4):[]}setPlanMode(e,t){this.planMode=e,this.onPlanModeConsumed=e?t:void 0}async prompt(e){if(this.disposed||this.state.isStreaming)return;let t=this.normalizePromptInput(e),n=this.state.messages.length;this.state.messages=[...this.state.messages,t],this.state.contextUsage=null,this.emitToListeners({type:`message_start`,message:t}),this.state.isStreaming=!0,this.state.errorMessage=void 0,this.emitToListeners({type:`agent_start`});let r;try{r=await this.ensureRealAgent()}catch(e){this.state.messages.length===n+1&&this.state.messages[this.state.messages.length-1]===t&&(this.state.messages=this.state.messages.slice(0,-1));let r=e instanceof Error?e.message:String(e);throw this.state.errorMessage=r,this.state.isStreaming=!1,this.state.streamingMessage=void 0,this.emitToListeners({type:`error`,error:r}),this.emitToListeners({type:`agent_end`,messages:this.state.messages}),e}r.setNextPromptCapabilities(this.nextPromptCapabilities),r.setPlanMode(this.planMode,this.onPlanModeConsumed),this.nextPromptCapabilities=[],this.planMode=!1,this.onPlanModeConsumed=void 0,await r.prompt(t)}abort(){this.realAgentPromise?.then(e=>e.abort())}reset(){this.state.messages=[],this.state.isStreaming=!1,this.state.streamingMessage=void 0,this.state.pendingToolCalls=new Set,this.state.errorMessage=void 0}async rollback(){throw Error(`Cannot roll back a pending chat`)}async continue(){await(await this.ensureRealAgent()).continue()}async approveToolCall(){throw Error(`No pending tool call`)}async rejectToolCall(){throw Error(`No pending tool call`)}async approveAutoCompact(){throw Error(`No pending auto compact request`)}async rejectAutoCompact(){throw Error(`No pending auto compact request`)}async updateAccessMode(e){let t=Nn(e);this.state.accessMode=t,this.state.yoloMode=Pn(t);let n=await this.realAgentPromise;n&&await n.updateAccessMode(t)}async updateYoloMode(e){await this.updateAccessMode(e?`full-access`:`default`)}async updateModel(e){if(this.harness===`opencode`)return;this.state.model=e;let t=await this.realAgentPromise;t&&await t.updateModel(e)}async updateThinkingLevel(e){if(this.harness===`opencode`)return;this.state.thinkingLevel=e;let t=await this.realAgentPromise;t&&await t.updateThinkingLevel(e)}dispose(){this.disposed=!0,this.listeners.clear(),this.promotedAgent||this.realAgentPromise?.then(e=>{this.promotedAgent!==e&&e.dispose()}).catch(()=>{})}promoteTo(e){this.promotedAgent=e,this.listeners.clear()}normalizePromptInput(e){let t;t=typeof e==`string`?{role:`user`,content:e,timestamp:Date.now()}:Array.isArray(e)?[...e].reverse().find(e=>e.role===`user`||e.role===`user-with-attachments`)??e[e.length-1]:e;let n=t.metadata;return!nt(this.state.model)||n&&typeof n.quickforgeClientMessageId==`string`&&n.quickforgeClientMessageId?t:{...t,metadata:{...n&&typeof n==`object`&&!Array.isArray(n)?n:{},quickforgeClientMessageId:`qfcm_${X()}`}}}emitToListeners(e){for(let t of this.listeners)try{t(e)}catch{}}async ensureRealAgent(){if(!this.realAgentPromise){let e=X();this.realAgentPromise=this.createAgent({model:this.state.model,thinkingLevel:this.state.thinkingLevel,tools:[]},e,{scope:this.scope,project:this.project,attachToView:!0,harness:this.harness,accessMode:this.state.accessMode,yoloMode:this.state.yoloMode}).then(e=>(this.disposed&&this.promotedAgent!==e&&e.dispose(),e))}return this.realAgentPromise}};function Pc(e){return e.isDeferredSession&&!e.isStreaming&&e.messageCount===0&&e.currentScope===e.targetScope}function Fc(e){return Pc(e)&&e.currentHarness!==e.defaultHarness}async function Ic(e,t){if(!Pc({...e,defaultHarness:e.currentHarness}))return{action:`not-reusable`};let n=await t();return Fc({...e,defaultHarness:n})?{action:`replace`,defaultHarness:n}:{action:`reuse`,defaultHarness:n}}function Lc(e,t=` `){return Array.isArray(e)?e.filter(e=>typeof e==`object`&&!!e&&`type`in e&&e.type===`text`&&`text`in e&&typeof e.text==`string`).map(e=>e.text).join(t):``}function Rc(e){return e.role===`assistant`?Lc(e.content,`
|
|
61
|
+
|
|
62
|
+
`).trim():``}function zc(e,t){let n=t;if(e[t]?.role===`assistant`){for(let r=t-1;r>=0;r--)if(e[r].role===`user`||e[r].role===`user-with-attachments`){n=r;break}}let r=e[n];return!r||r.role!==`user`&&r.role!==`user-with-attachments`?-1:n}function Bc(e){return e.role!==`user`&&e.role!==`user-with-attachments`?``:typeof e.content==`string`?e.content:Lc(e.content,`
|
|
63
|
+
|
|
64
|
+
`)}async function Vc(e){if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(e);return}let t=document.createElement(`textarea`);t.value=e,t.style.position=`fixed`,t.style.left=`-9999px`,document.body.append(t),t.select(),document.execCommand(`copy`),t.remove()}function Hc(e){let t=e.find(e=>e.role===`user`||e.role===`user-with-attachments`);if(!t||t.role!==`user`&&t.role!==`user-with-attachments`)return`New chat`;let n=t.content,r=(typeof n==`string`?n:Lc(n)).trim().replace(/\s+/g,` `);return r?r.length>46?`${r.slice(0,43)}...`:r:`New chat`}function Uc(e){return e===`New chat`||e===W(`newChat`)}function Wc(e){return e.some(e=>e.role===`user`||e.role===`user-with-attachments`)}function Gc(e){return Wc(e)&&e.some(e=>e.role===`assistant`)}var Kc=new Set([`idle`,`error`,`aborted`]);function qc(e,t=Date.now()){e.lastAccessedAt=t}function Jc(e,t,n=5){let r=Array.from(e).filter(e=>e.sessionId!==t&&e.status!==`running`&&!e.agent.state.isStreaming&&Kc.has(e.status));return r.length<=n?[]:(r.sort((e,t)=>(e.lastAccessedAt??0)-(t.lastAccessedAt??0)),r.slice(0,r.length-n).map(e=>e.sessionId))}function Yc(e,t){let n=e.get(t);return n?(n.unsubscribe(),n.agent.dispose(),e.delete(t),!0):!1}function Xc(e){for(let t of[...e.keys()])Yc(e,t)}function Zc({title:e,description:t,actions:n,onCancel:r}){let i=(0,H.useRef)(null),a=(0,H.useRef)(!1),o=(0,H.useCallback)(()=>{a.current||(a.current=!0,r())},[r]),s=(0,H.useCallback)(e=>{a.current||(a.current=!0,e.onClick())},[]);return(0,H.useEffect)(()=>{i.current?.focus();let e=e=>{if(e.key===`Escape`&&o(),e.key===`Enter`){let e;for(let t=n.length-1;t>=0;t--)if(n[t].enter!==!1){e=n[t];break}e&&s(e)}};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[o,s,n]),(0,qr.createPortal)((0,K.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/45 px-4 py-6`,onMouseDown:e=>{e.target===e.currentTarget&&o()},children:(0,K.jsxs)(`div`,{className:G(`w-full max-w-[420px] rounded-2xl border border-border bg-background p-5 shadow-quickforge`),role:`dialog`,"aria-modal":`true`,"aria-labelledby":e?`message-dialog-title`:void 0,"aria-describedby":`message-dialog-description`,onMouseDown:e=>e.stopPropagation(),children:[e?(0,K.jsx)(`h2`,{id:`message-dialog-title`,className:`text-base font-semibold text-foreground/90`,children:e}):null,(0,K.jsx)(`p`,{id:`message-dialog-description`,className:G(`text-sm leading-6 text-muted-foreground/72`,e?`mt-2`:void 0),children:t}),(0,K.jsx)(`div`,{className:`mt-6 flex justify-end gap-2`,children:n.map((e,t)=>(0,K.jsx)(q,{ref:e.autoFocus?i:void 0,variant:e.variant,size:`sm`,onClick:()=>s(e),children:e.label},`${e.label}-${t}`))})]})}),document.body)}function Qc(e){return new Promise(t=>{let n=document.createElement(`div`);document.body.appendChild(n);let r=(0,it.createRoot)(n);function i(){r.unmount(),setTimeout(()=>n.remove(),0)}function a(e){i(),t(e)}r.render(e(a))})}function $c(e){return Qc(t=>(0,K.jsx)(Zc,{title:e.title,description:e.description,onCancel:()=>t(!1),actions:[{label:e.cancelLabel??`Cancel`,variant:`outline`,onClick:()=>t(!1),autoFocus:e.variant===`destructive`},{label:e.confirmLabel??`Confirm`,variant:e.variant===`destructive`?`destructive`:`default`,autoFocus:e.variant!==`destructive`,enter:e.variant!==`destructive`,onClick:()=>t(!0)}]}))}function $(e){let t=typeof e==`string`?{description:e}:e;return Qc(e=>(0,K.jsx)(Zc,{title:t.title,description:t.description,onCancel:()=>e(),actions:[{label:t.confirmLabel??`OK`,autoFocus:!0,onClick:()=>e()}]}))}function el(e){let{storageRef:t,activeModelRef:n,agentAccessModeRef:r,activeProjectRef:i,defaultWorkspaceRef:a,setAgentAccessMode:o,switchActiveProject:s,refreshSessions:c,updateSessionTitle:l,loadCloudModels:u}=e,d=(0,H.useRef)(null),f=(0,H.useRef)(new Map),p=(0,H.useRef)(`global`),m=(0,H.useRef)(void 0),h=(0,H.useRef)(`New chat`),g=(0,H.useRef)(void 0),_=(0,H.useRef)(null),v=(0,H.useRef)(0),y=(0,H.useRef)(null),b=(0,H.useRef)(null),x=(0,H.useRef)(0),S=(0,H.useRef)(e.onTaskComplete);(0,H.useEffect)(()=>{S.current=e.onTaskComplete}),(0,H.useEffect)(()=>()=>{y.current?.abort()},[]);let[C,w]=(0,H.useState)(null),[T,E]=(0,H.useState)(),[D,O]=(0,H.useState)(`New chat`),[k,ee]=(0,H.useState)(`global`),[te,A]=(0,H.useState)(),[j,ne]=(0,H.useState)({}),[re,M]=(0,H.useState)(0),[N,P]=(0,H.useState)(),ie=(0,H.useCallback)(e=>{e.length!==0&&ne(t=>{let n={...t},r=!1;for(let t of e)Object.prototype.hasOwnProperty.call(n,t)&&(delete n[t],r=!0);return r?n:t})},[]),F=(0,H.useCallback)(e=>{let t=Jc(f.current.values(),e);for(let e of t)Yc(f.current,e);ie(t)},[ie]),ae=(0,H.useCallback)((e,t)=>{!e||e===t||[...f.current.values()].some(t=>t.agent===e)||e.dispose()},[f]),I=(0,H.useCallback)(async e=>{if(m.current===e.sessionId){let t=e.agent.state.messages,n=e.title;Uc(n)&&(n=Hc(t)),g.current=e.createdAt??new Date().toISOString(),h.current=n,O(n)}await c({broadcast:!0})},[c]),L=(0,H.useCallback)(e=>{ae(d.current,e.agent),qc(e),p.current=e.scope,m.current=e.sessionId,g.current=e.createdAt,h.current=e.title,ee(e.scope),E(e.sessionId),O(e.title),A(e.project),d.current=e.agent,w(e.agent);let t=new URL(window.location.href);t.searchParams.set(`session`,e.sessionId),window.history.replaceState({},``,t)},[ae]),R=(0,H.useCallback)(async(e,s=X(),g)=>{let v=d.current,y=f.current.get(s);if(y)return g?.attachToView!==!1&&g?.shouldAttachToView?.()!==!1&&(ae(v,y.agent),L(y)),y.agent;let b=g?.scope??p.current,x=b===`project`?g?.project??i.current:g?.project??a.current;if(b===`project`&&!x?.id)throw Error(`Cannot create project chat without an active project.`);let C=new Date().toISOString(),{model:w,thinkingLevel:T,tools:E,...D}=e??{},k=t.current,ee=k?await ir(k):{},te=g?.harness??ee.harness??`quickforge`,A=w??ee.model??n.current,j=w!==void 0&&!!D.messages?.length,re=te===`opencode`?wn():j?k?await mr(k,A):Jn(A):await hr(k,A,u),M=te===`opencode`?`off`:T??ee.thinkingLevel??tr(re);te===`quickforge`&&(n.current=re);let N=Nn(g?.accessMode,g?.yoloMode??r.current);r.current=N,o(N);let P=await Mc.create(s,{scope:b,projectId:b===`project`?x?.id:void 0,source:g?.source,channelId:g?.channelId,channelName:g?.channelName,harness:te,sourceHarnessSessionId:g?.sourceHarnessSessionId,accessMode:N,yoloMode:Pn(N),model:re,thinkingLevel:M,messages:D.messages??[],title:g?.title,contextCompaction:D.contextCompaction});D.contextCompaction&&!P.state.contextCompaction&&(P.state.contextCompaction=D.contextCompaction);let ie=P.state.isStreaming?`running`:P.state.errorMessage?`error`:`idle`,R={sessionId:P.sessionId,agent:P,scope:b,project:x,title:g?.title??`New chat`,createdAt:g?.createdAt??C,status:ie,startedAt:C,lastAccessedAt:Date.now(),unsubscribe:()=>void 0};return R.unsubscribe=P.subscribe(e=>{if(e.type===`agent_start`&&(R.status=`running`,R.startedAt=R.startedAt??new Date().toISOString(),R.finishedAt=void 0,ne(e=>({...e,[R.sessionId]:R.status}))),e.type===`message_end`&&(P.state.messages=[...P.state.messages]),e.type===`agent_end`){let t=R.status===`running`,n=e;R.status=n.status===`aborted`?`aborted`:n.errorMessage||P.state.errorMessage?`error`:`idle`,R.finishedAt=new Date().toISOString(),qc(R),ne(e=>({...e,[R.sessionId]:R.status})),I(R).catch(e=>V.error(`Failed to sync session UI:`,e)),t&&S.current?.(R.sessionId,R.title,R.status),F(m.current)}if(e.type===`title_updated`){let t=e;t.title&&(R.title=t.title),R.sessionId===m.current&&t.title&&(h.current=t.title,O(t.title)),t.title&&l(R.sessionId,t.title)}if(e.type===`session_forked`){let t=e;if(!t.targetSessionId)return;c({broadcast:!0}).catch(e=>V.error(`Failed to refresh sessions:`,e)),_.current?.(t.targetSessionId,{title:t.title,createdAt:t.createdAt,scope:t.scope,projectId:t.projectId??void 0})}}),f.current.set(s,R),R.status!==`idle`&&ne(e=>({...e,[R.sessionId]:R.status})),g?.attachToView!==!1&&g?.shouldAttachToView?.()!==!1&&(v instanceof Nc?v.promoteTo(R.agent):d.current===v&&ae(v,R.agent),L(R)),F(m.current),g?.refreshSessions!==!1&&P.state.messages.length>0&&await c({broadcast:!0}),P},[L,ae,F,c,I,l,u,t,n,r,i,a,o]),oe=(0,H.useCallback)(async e=>{let i=++x.current,o=t.current,s=o?await ir(o):{},c=e.harness??s.harness??`quickforge`,l=s.model??n.current,f=c===`opencode`?wn():await hr(o,l,u),_=c===`opencode`?`off`:s.thinkingLevel??tr(f);c===`quickforge`&&(n.current=f);let v=e.scope,y=v===`project`?e.project:e.project??a.current,b=new Nc({scope:v,project:y,model:f,thinkingLevel:_,accessMode:r.current,harness:c,yoloMode:Pn(r.current),createAgent:R});if(b.subscribe(e=>{d.current===b&&(e.type===`message_start`||e.type===`agent_end`)&&M(e=>e+1)}),i!==x.current||e.shouldAttachToView?.()===!1)return b.dispose(),b;ae(d.current),p.current=v,m.current=void 0,g.current=void 0,h.current=`New chat`,ee(v),E(void 0),O(`New chat`),A(y),d.current=b,w(b);let S=new URL(window.location.href);return S.searchParams.delete(`session`),window.history.replaceState({},``,S),b},[n,R,a,ae,u,t,r]),z=(0,H.useCallback)(async e=>{let n=d.current,r=x.current,i=e??(t.current?(await ir(t.current)).harness??`quickforge`:`quickforge`);if(x.current!==r||!Fc({isDeferredSession:n instanceof Nc&&d.current===n,isStreaming:n?.state.isStreaming??!1,messageCount:n?.state.messages.length??0,currentScope:p.current,targetScope:`global`,currentHarness:n?.harness??`quickforge`,defaultHarness:i}))return!1;let a=n,o=x.current+1;return await oe({scope:`global`,harness:i,shouldAttachToView:()=>{let e=d.current;return e===a&&e instanceof Nc&&!e.state.isStreaming&&e.state.messages.length===0&&p.current===`global`}}),x.current===o&&d.current!==a},[d,p,oe,t]);(0,H.useEffect)(()=>{let e=e=>{let t=e.detail;z(t?.harness).catch(e=>{V.error(`Failed to apply the default Harness to the blank chat:`,e)})};return window.addEventListener(ac,e),()=>window.removeEventListener(ac,e)},[z]);let se=(0,H.useCallback)(async(e,t)=>{let u=++v.current;y.current?.abort();let d=new AbortController;y.current=d;let p=()=>v.current===u&&!d.signal.aborted;P(e);try{if(!p())return!1;let u=f.current.get(e);if(u){if(u.scope===`project`&&u.project?.id&&i.current?.id!==u.project.id)try{await s(u.project.id)}catch(e){V.error(`Failed to switch project for running session:`,e)}return p()?(L(u),F(u.sessionId),!0):!1}let g,v;try{let t=await Mc.restore(e,{signal:d.signal});g=t.agent,v=t.snapshot}catch(e){return d.signal.aborted||!p()||V.error(`Failed to restore session:`,e),!1}if(!p())return g.dispose(),!1;let y=t?.scope??v.scope??`global`,b=t?.projectId??v.projectId??void 0,x;if(y===`project`&&b)if(i.current?.id!==b)try{x=await s(b)}catch(e){return g.dispose(),V.error(`Failed to switch project for session:`,e),p()&&$(W(`projectSwitchFailed`)),!1}else x=i.current;if(!p())return g.dispose(),!1;n.current=g.state.model;let C=Nn(g.state.accessMode,g.state.yoloMode);r.current=C,o(C);let w={sessionId:e,agent:g,scope:y,project:y===`project`?x:a.current,title:v.title??t?.title??`New chat`,createdAt:v.createdAt??t?.createdAt??new Date().toISOString(),status:v.status===`running`||g.state.isStreaming?`running`:g.state.errorMessage?`error`:v.status===`aborted`?`aborted`:`idle`,startedAt:v.startedAt??void 0,finishedAt:v.finishedAt??void 0,lastAccessedAt:Date.now(),unsubscribe:()=>void 0};return w.unsubscribe=g.subscribe(e=>{if(e.type===`agent_start`&&(w.status=`running`,w.startedAt=w.startedAt??new Date().toISOString(),w.finishedAt=void 0,ne(e=>({...e,[w.sessionId]:w.status}))),e.type===`message_end`&&(g.state.messages=[...g.state.messages]),e.type===`agent_end`){let t=w.status===`running`,n=e;w.status=n.status===`aborted`?`aborted`:n.errorMessage||g.state.errorMessage?`error`:`idle`,w.finishedAt=new Date().toISOString(),qc(w),ne(e=>({...e,[w.sessionId]:w.status})),I(w).catch(e=>V.error(`Failed to sync session UI:`,e)),t&&S.current?.(w.sessionId,w.title,w.status),F(m.current)}if(e.type===`title_updated`){let t=e;t.title&&(w.title=t.title),w.sessionId===m.current&&t.title&&(h.current=t.title,O(t.title)),t.title&&l(w.sessionId,t.title)}if(e.type===`session_forked`){let t=e;if(!t.targetSessionId)return;c({broadcast:!0}).catch(e=>V.error(`Failed to refresh sessions:`,e)),_.current?.(t.targetSessionId,{title:t.title,createdAt:t.createdAt,scope:t.scope,projectId:t.projectId??void 0})}}),f.current.set(e,w),w.status!==`idle`&&ne(e=>({...e,[w.sessionId]:w.status})),L(w),F(e),!0}finally{y.current===d&&(y.current=null),v.current===u&&P(void 0)}},[n,i,r,L,a,F,c,o,s,I,l]),ce=(0,H.useCallback)((e,t)=>{let n=b.current;if(n?.sessionId===e)return n.promise;let r=se(e,t);return b.current={sessionId:e,promise:r},r.then(()=>{b.current?.promise===r&&(b.current=null)},()=>{b.current?.promise===r&&(b.current=null)}),r},[se]);return(0,H.useEffect)(()=>{_.current=ce},[ce]),{agentRef:d,taskMapRef:f,currentSessionIdRef:m,currentChatScopeRef:p,agent:C,currentSessionId:T,currentTitle:D,chatScope:k,currentToolProject:te,taskStatuses:j,chatPanelRevision:re,loadingSessionId:N,createAgent:R,startDeferredSession:oe,applyDefaultHarnessToBlankSession:z,loadSession:ce,syncSessionUI:I,setChatPanelRevision:M,setCurrentAgentMessages:(0,H.useCallback)(e=>{d.current&&(d.current.state.messages=e)},[]),updateCurrentAgentModel:(0,H.useCallback)(e=>{d.current&&(d.current.state.model=e,d.current.updateModel(e).catch(e=>{V.error(`Failed to sync model to server:`,e)}))},[]),setCurrentTitleRef:(0,H.useCallback)(e=>{h.current=e,O(e)},[])}}function tl(e){if(!e)return 0;let t=new Date(e).getTime();return Number.isNaN(t)?0:t}function nl(e,t){let n=t===`createdAt`?`createdAt`:`lastModified`;return[...e].sort((e,t)=>{let r=tl(t.pinnedAt)-tl(e.pinnedAt);return r===0?e.pinnedAt&&!t.pinnedAt?-1:!e.pinnedAt&&t.pinnedAt?1:tl(t[n])-tl(e[n]):r})}function rl(e){let t=new Set;return e.filter(e=>t.has(e.id)?!1:(t.add(e.id),!0))}function il(e,t,n){let r=e.items.some(e=>e.id===t.id);return{...e,items:nl(rl([t,...e.items.filter(e=>e.id!==t.id)]),n),total:r?e.total:e.total+1}}function al(e,t,n){return e.items.some(e=>e.id===t)?{...e,items:e.items.map(e=>e.id===t?{...e,title:n}:e)}:e}var ol=20;function sl(e){if(!e)return!1;let t=e.trim();return!t||t===`undefined`||t===`null`||t===`false`?!1:!Number.isNaN(Date.parse(t))}function cl({backendRef:e,expandedProjectIds:t,externalProjectIds:n,viewMode:r,sortMode:i,onBroadcastSessionsChanged:a}){let[o,s]=(0,H.useState)({items:[],total:0,loading:!1}),[c,l]=(0,H.useState)({items:[],total:0,loading:!1}),[u,d]=(0,H.useState)({}),[f,p]=(0,H.useState)({items:[],total:0,loading:!1}),m=(0,H.useRef)(u),h=(0,H.useRef)(t),g=(0,H.useRef)(n??new Set),_=(0,H.useRef)(0);(0,H.useEffect)(()=>{m.current=u},[u]),(0,H.useEffect)(()=>{h.current=t},[t]),(0,H.useEffect)(()=>{g.current=n??new Set},[n]);let v=(0,H.useCallback)(()=>(_.current+=1,_.current),[]),y=(0,H.useCallback)(e=>e===_.current,[]),b=(0,H.useMemo)(()=>rl([...c.items,...o.items,...Object.values(u).flatMap(e=>e.items),...f.items]),[c.items,o.items,u,f.items]),x=(0,H.useCallback)(async(t,n=_.current)=>{let r=e.current;if(r){l(e=>({...e,loading:!0}));try{let e=await r.fetchPaginatedFromIndex(`sessions-metadata`,`pinnedAt`,{direction:`desc`,limit:ol,offset:t,pinned:`only`});if(!y(n))return;let a=e.values.filter(e=>sl(e.pinnedAt));l(n=>({items:nl(t===0?a:rl([...n.items,...a]),i),total:e.total,loading:!1}))}catch{if(!y(n))return;l(e=>({...e,loading:!1}))}}},[e,y,i]),S=(0,H.useCallback)(async(t,n=_.current)=>{let r=e.current;if(r){s(e=>({...e,loading:!0}));try{let e=i===`createdAt`?`createdAt`:`lastModified`,a=await r.fetchPaginatedFromIndex(`sessions-metadata`,e,{direction:`desc`,limit:ol,offset:t,scope:`global`});if(!y(n))return;s(e=>({items:nl(t===0?a.values:rl([...e.items,...a.values]),i),total:a.total,loading:!1}))}catch{if(!y(n))return;s(e=>({...e,loading:!1}))}}},[e,y,i]),C=(0,H.useCallback)(async(t,n,r=_.current)=>{let a=e.current;if(a){d(e=>{let n=e[t];return{...e,[t]:{...n??{items:[],total:0},loading:!0}}});try{let e=i===`createdAt`?`createdAt`:`lastModified`,o=await a.fetchPaginatedFromIndex(`sessions-metadata`,e,{direction:`desc`,limit:ol,offset:n,scope:`project`,projectId:t});if(!y(r))return;d(e=>{let r=e[t]?.items??[];return{...e,[t]:{items:nl(n===0?o.values:rl([...r,...o.values]),i),total:o.total,loading:!1}}})}catch{if(!y(r))return;d(e=>{let n=e[t];return{...e,[t]:{...n??{items:[],total:0},loading:!1}}})}}},[e,y,i]),w=(0,H.useCallback)(async(t,n=_.current)=>{let r=e.current;if(r){p(e=>({...e,loading:!0}));try{let e=i===`createdAt`?`createdAt`:`lastModified`,a=await r.fetchPaginatedFromIndex(`sessions-metadata`,e,{direction:`desc`,limit:ol,offset:t,scope:`projects`});if(!y(n))return;p(e=>({items:nl(t===0?a.values:rl([...e.items,...a.values]),i),total:a.total,loading:!1}))}catch{if(!y(n))return;p(e=>({...e,loading:!1}))}}},[e,y,i]),T=(0,H.useCallback)(async t=>{if(!e.current)return;let n=v();if(await Promise.all([x(0,n),S(0,n)]),!y(n))return;if(r===`timeline`){d(e=>{let t={};for(let[n,r]of Object.entries(e))t[n]={...r,loading:!1};return t}),await w(0,n),t?.broadcast&&y(n)&&a?.();return}p(e=>({...e,loading:!1}));let i=new Set([...Object.keys(m.current),...h.current,...g.current]);i.size===0?d({}):await Promise.all([...i].map(e=>C(e,0,n))),t?.broadcast&&y(n)&&a?.()},[e,y,S,x,C,w,v,a,r]),E=(0,H.useCallback)(e=>{if(sl(e.pinnedAt)&&l(t=>il(t,e,i)),e.scope===`project`&&e.projectId){d(t=>{let n=t[e.projectId];return n?{...t,[e.projectId]:il(n,e,i)}:t}),r===`timeline`&&p(t=>il(t,e,i));return}s(t=>il(t,e,i))},[i,r]),D=(0,H.useCallback)((e,t)=>{l(n=>al(n,e,t)),s(n=>al(n,e,t)),p(n=>al(n,e,t)),d(n=>{let r=!1,i=Object.fromEntries(Object.entries(n).map(([n,i])=>{let a=al(i,e,t);return a!==i&&(r=!0),[n,a]}));return r?i:n})},[]),O=(0,H.useCallback)(e=>u[e]?.items??[],[u]),k=(0,H.useCallback)(e=>{let t=u[e];return t?t.items.length<t.total:!0},[u]),ee=(0,H.useCallback)(e=>u[e]?.loading??!1,[u]),te=(0,H.useCallback)(e=>e in u,[u]),A=(0,H.useCallback)(()=>{c.loading||c.items.length>=c.total||x(c.items.length)},[x,c.items.length,c.loading,c.total]),j=(0,H.useCallback)(()=>{S(o.items.length)},[o.items.length,S]),ne=(0,H.useCallback)(e=>{let t=u[e];C(e,t?.items.length??0)},[C,u]),re=(0,H.useCallback)(()=>{f.loading||f.items.length>=f.total||w(f.items.length)},[w,f.items.length,f.loading,f.total]);return(0,H.useEffect)(()=>{Promise.resolve().then(()=>T())},[T]),{allLoadedSessions:b,pinnedSessions:c.items,pinnedHasMore:c.items.length<c.total,pinnedLoading:c.loading,globalSessions:o.items,sessionsForProject:O,projectTimelineSessions:f.items,projectTimelineHasMore:f.items.length<f.total,projectTimelineLoading:f.loading,globalHasMore:o.items.length<o.total,projectHasMore:k,globalLoading:o.loading,projectLoading:ee,projectLoaded:te,loadGlobalSessions:S,loadProjectSessions:C,refreshSessions:T,upsertSessionMetadata:E,updateSessionTitle:D,loadMorePinned:A,loadMoreGlobal:j,loadMoreProject:ne,loadMoreProjectTimeline:re}}function ll(){let[e,t]=(0,H.useState)([]),n=(0,H.useCallback)(e=>{t(t=>[...t,{...e,id:X(),createdAt:Date.now()}])},[]);return{toasts:e,handleTaskComplete:(0,H.useCallback)((e,t,r)=>{n({sessionId:e,title:t,status:r})},[n]),addToast:n,dismissToast:(0,H.useCallback)(e=>{t(t=>t.filter(t=>t.id!==e))},[])}}var ul=`tool-display-settings`,dl={toolDisplayMode:`compact`,showContextUsage:!1},fl={...dl};function pl(e){if(!e||typeof e!=`object`)return{...dl};let t=e;return{toolDisplayMode:t.toolDisplayMode===`detailed`?`detailed`:`compact`,showContextUsage:t.showContextUsage===!0}}function ml(){return fl}async function hl(e){let t=pl(await e.settings.get(ul));return fl=t,t}async function gl(e,t){let n=pl(t);await e.settings.set(ul,n),fl=n}var _l=`font-size-settings`,vl=`font-size-settings-force-13px-v1`,yl={min:12,max:18},bl={interfaceFontSizePx:13,messageFontSizePx:13},xl=`quickforge:font-size-settings-changed`;function Sl(){if(typeof document>`u`)return bl.interfaceFontSizePx;let e=Number.parseFloat(getComputedStyle(document.documentElement).fontSize);return Number.isFinite(e)?e:bl.interfaceFontSizePx}function Cl(e=Sl()){let t=Tl(e-1,13,yl.min,yl.max);return{fontSize:t,lineHeight:Math.round(t*1.54)}}function wl(e=Sl()){return{fontSize:Tl(e-2,12,yl.min,yl.max),lineHeight:1.2}}function Tl(e,t,n,r){let i=Number(e);return Number.isFinite(i)?Math.min(r,Math.max(n,Math.round(i))):t}function El(e){if(!e||typeof e!=`object`)return{...bl};let t=e;return{interfaceFontSizePx:Tl(t.interfaceFontSizePx??t.baseFontSizePx??t.bodyFontSizePx,bl.interfaceFontSizePx,yl.min,yl.max),messageFontSizePx:Tl(t.messageFontSizePx,bl.messageFontSizePx,yl.min,yl.max)}}function Dl(e){if(typeof document>`u`)return;let t=El(e),n=document.documentElement;n.style.fontSize=`${t.interfaceFontSizePx}px`,n.style.setProperty(`--quickforge-message-font-size`,`${t.messageFontSizePx}px`),n.style.setProperty(`--quickforge-message-line-height`,`1.625`),window.dispatchEvent(new CustomEvent(xl,{detail:t}))}async function Ol(e){if(!await e.settings.get(vl)){let t={...bl};return await e.settings.set(_l,t),await e.settings.set(vl,!0),t}return El(await e.settings.get(_l))}async function kl(e){let t=await Ol(e);return Dl(t),t}async function Al(e,t){let n=El(t);await e.settings.set(_l,n),Dl(n)}var jl=`appearance-settings`,Ml={theme:`light`};function Nl(e){return!e||typeof e!=`object`?{...Ml}:{theme:e.theme===`dark`?`dark`:`light`}}function Pl(e){if(typeof document>`u`)return;let t=Nl(e),n=document.documentElement;n.classList.toggle(`dark`,t.theme===`dark`),n.style.setProperty(`color-scheme`,t.theme)}function Fl(){return typeof document>`u`?Ml.theme:document.documentElement.classList.contains(`dark`)?`dark`:`light`}async function Il(e){return Nl(await e.settings.get(jl))}async function Ll(e){let t=await Il(e);return Pl(t),t}async function Rl(e,t){let n=Nl(t);await e.settings.set(jl,n),Pl(n)}function zl({storageRef:e,backendRef:t,activeModelRef:n,agentAccessModeRef:r,taskMapRef:i,refreshSessions:a,loadProject:o,initAgentAccessMode:s,createAgent:c,loadSession:l,loadCloudModels:u,setNeedsModelSetup:d,onStorageReady:f}){let[p,m]=(0,H.useState)(!1),[h,g]=(0,H.useState)(),[_,v]=(0,H.useState)(0),y=(0,H.useRef)({refreshSessions:a,loadProject:o,initAgentAccessMode:s,createAgent:c,loadSession:l,loadCloudModels:u,setNeedsModelSetup:d,onStorageReady:f});return(0,H.useEffect)(()=>{y.current={refreshSessions:a,loadProject:o,initAgentAccessMode:s,createAgent:c,loadSession:l,loadCloudModels:u,setNeedsModelSetup:d,onStorageReady:f}}),(0,H.useEffect)(()=>{let a=!1;async function o(){let{refreshSessions:i,loadProject:o,initAgentAccessMode:s,createAgent:c,loadSession:l,loadCloudModels:u,setNeedsModelSetup:d,onStorageReady:f}=y.current;try{m(!1),g(void 0);let p=await $n();if(a)return;e.current=p,f?.(p),t.current=p.backend,await _t(p),await hl(p),await Ll(p),await kl(p),await Promise.all([i(),o()]),r.current=await s(p);let h=[];try{h=await u()}catch(e){V.warn(`Failed to restore QuickForge Cloud models:`,e)}let _=await ir(p),v=jn(_.harness),y=v===`opencode`?null:await fr(p,h,_.model),b=y??(v===`opencode`?wn():null);y&&(n.current=y);let x=()=>c({model:b,thinkingLevel:_.thinkingLevel,tools:[]},X(),{scope:`global`,attachToView:!0,harness:v}),S=new URLSearchParams(window.location.search).get(`session`);S&&await l(S)?d(!1):(d(v===`quickforge`&&!y),b&&await x()),m(!0)}catch(e){V.error(`Failed to bootstrap QuickForge:`,e),a||g(W(`localServiceUnavailableDescription`))}}o();let s=i.current;return()=>{a=!0,Xc(s)}},[e,t,n,r,i,_]),{ready:p,startupError:h,retryBootstrap:(0,H.useCallback)(()=>{m(!1),g(void 0),v(e=>e+1)},[])}}var Bl=`update-check-settings`,Vl={frequency:`startup`,lastCheckAt:null,ignoredVersion:null};function Hl(e){if(!e||typeof e!=`object`)return{...Vl};let t=e;return{frequency:[`startup`,`daily`,`weekly`,`off`].includes(t.frequency)?t.frequency:Vl.frequency,lastCheckAt:typeof t.lastCheckAt==`string`?t.lastCheckAt:null,ignoredVersion:typeof t.ignoredVersion==`string`?t.ignoredVersion:null}}var Ul=1440*60*1e3;function Wl(e,t=Date.now()){switch(e.frequency){case`off`:return!1;case`startup`:return!0;case`daily`:case`weekly`:{if(!e.lastCheckAt)return!0;let n=Date.parse(e.lastCheckAt);if(Number.isNaN(n))return!0;let r=e.frequency===`daily`?Ul:7*Ul;return t-n>=r}default:return!1}}async function Gl(e){return Hl(await e.settings.get(Bl))}async function Kl(e,t){await e.settings.set(Bl,Hl(t))}var ql={status:`idle`,updateAvailable:!1};function Jl(){if(typeof document>`u`)return!1;let e=window;return document.body.classList.contains(`quickforge-desktop-app`)||e.__quickforgeDesktopApp===!0}function Yl(e,t){let[n,r]=(0,H.useState)(ql),i=(0,H.useRef)(!1);return(0,H.useEffect)(()=>{if(!t||i.current||Jl())return;let n=e.current;n&&(i.current=!0,(async()=>{let e;try{e=await Gl(n)}catch(e){V.error(`Failed to load update-check settings:`,e);return}if(Wl(e)){r(e=>({...e,status:`checking`}));try{let t=await fetch(`/api/system/update/check`,{cache:`no-store`});if(!t.ok){r(e=>({...e,status:`error`}));return}let i=await t.json(),a=i.updateAvailable&&i.latestVersion!==e.ignoredVersion;try{await Kl(n,{...e,lastCheckAt:new Date().toISOString()})}catch(e){V.error(`Failed to persist last update-check time:`,e)}r({status:`done`,currentVersion:i.currentVersion,latestVersion:i.latestVersion,updateAvailable:a})}catch(e){V.error(`Startup update check failed:`,e),r(e=>({...e,status:`error`}))}}})())},[t,e]),{result:n,dismissUpdate:(0,H.useCallback)(()=>{let t=e.current,i=n.latestVersion;!t||!i||(r(e=>({...e,updateAvailable:!1})),(async()=>{try{await Kl(t,{...await Gl(t),ignoredVersion:i})}catch(e){V.error(`Failed to persist ignored update version:`,e)}})())},[n.latestVersion,e])}}var Xl=[`low`,`medium`,`high`,`xhigh`];function Zl(e){switch(e){case`low`:return W(`thinkingLow`);case`medium`:return W(`thinkingMedium`);case`high`:return W(`thinkingHigh`);case`xhigh`:return W(`thinkingXHigh`);default:return W(`thinkingOff`)}}function Ql(e,t=``){let n=document.createElement(`button`);return n.type=`button`,n.className=e,n.textContent=t,n}function $l(e){document.querySelectorAll(`.quickforge-model-menu, .quickforge-model-submenu, .quickforge-model-sheet-backdrop`).forEach(e=>{e.__quickforgeCleanup?.(),e.remove()}),e?.setAttribute(`aria-expanded`,`false`)}function eu(e){return e??document.querySelector(`.quickforge-model-trigger`)}function tu(e,t){let n=eu(t),r=Math.min(260,window.innerWidth-24);e.style.width=`${r}px`;let i=e.offsetHeight||360;if(!n){e.style.left=`${Math.max(12,Math.round((window.innerWidth-r)/2))}px`,e.style.top=`${Math.max(12,Math.round((window.innerHeight-i)/2))}px`;return}let a=n.getBoundingClientRect(),o=Math.max(12,Math.min(a.right-r,window.innerWidth-r-12)),s=a.top-i-8,c=a.bottom+8,l=s>=12?s:Math.min(c,window.innerHeight-i-12);e.style.left=`${o}px`,e.style.top=`${Math.max(12,l)}px`}function nu(e,t){let n=Math.min(252,window.innerWidth-24);e.style.width=`${n}px`;let r=t.getBoundingClientRect(),i=e.offsetHeight||320,a=r.left-n-0>=12?r.left-n-0:Math.min(r.right+0,window.innerWidth-n-12),o=Math.max(12,Math.min(r.top,window.innerHeight-i-12));e.style.left=`${a}px`,e.style.top=`${o}px`}function ru(e){let t=Ql(`quickforge-model-menu-item`);t.setAttribute(`role`,`menuitemradio`),t.setAttribute(`aria-checked`,String(!!e.selected)),e.disabled&&(t.disabled=!0);let n=document.createElement(`span`);n.className=`quickforge-model-menu-item-label`,n.textContent=e.label;let r=document.createElement(`span`);return r.className=`quickforge-model-menu-item-suffix`,r.textContent=e.chevron?`›`:e.selected?`✓`:``,t.append(n,r),e.onPointerDown&&(t.onpointerdown=e.onPointerDown),e.onPointerEnter&&(t.onpointerenter=e.onPointerEnter),e.onClick&&t.addEventListener(`click`,e.onClick),t}function iu(e,t,n,r,i){let a=r.thinkingLevel??`off`,o=e,s=document.createElement(`div`);s.className=`quickforge-model-sheet-backdrop`;let c=document.createElement(`div`);c.className=`quickforge-model-sheet`,c.setAttribute(`role`,`dialog`),c.setAttribute(`aria-modal`,`true`),c.setAttribute(`aria-label`,W(`selectCustomModel`));let l=document.createElement(`div`);l.className=`quickforge-model-sheet-drag-zone`;let u=document.createElement(`div`);u.className=`quickforge-model-sheet-handle`,l.append(u);let d=document.createElement(`div`);d.className=`quickforge-model-sheet-header`;let f=document.createElement(`div`);f.className=`quickforge-model-sheet-title`,f.textContent=W(`selectCustomModel`);let p=Ql(`quickforge-model-sheet-close`,`×`);p.setAttribute(`aria-label`,W(`close`)),p.title=W(`close`),p.onpointerdown=e=>{e.preventDefault(),e.stopPropagation(),$l(i)},d.append(f,p);let m=r.showThinking===!1?null:document.createElement(`div`),h;if(m){m.className=`quickforge-model-sheet-section`;let e=document.createElement(`div`);e.className=`quickforge-model-sheet-section-label`,e.textContent=W(`reasoning`),h=()=>{if(m.replaceChildren(e),o?.reasoning===!0){let e=document.createElement(`div`);e.className=`quickforge-model-sheet-thinking-options`;let t=new Map;for(let n of Xl){let i=Ql(`quickforge-model-sheet-thinking-option`,Zl(n));t.set(n,i),i.onpointerdown=e=>{e.preventDefault(),e.stopPropagation(),a=n,r.onThinkingLevelSelect?.(n);for(let[e,n]of t){let t=e===a;n.classList.toggle(`is-selected`,t),n.setAttribute(`aria-pressed`,String(t))}};let o=n===a;i.classList.toggle(`is-selected`,o),i.setAttribute(`aria-pressed`,String(o)),e.append(i)}m.append(e)}else{let e=document.createElement(`div`);e.className=`quickforge-model-menu-note`,e.textContent=W(`thinkingNotSupported`),m.append(e)}},h()}let g=document.createElement(`div`);g.className=`quickforge-model-sheet-section-label quickforge-model-sheet-model-label`,g.textContent=W(`model`);let _=document.createElement(`div`);_.className=`quickforge-model-sheet-model-list`,_.setAttribute(`role`,`menu`),_.setAttribute(`aria-label`,W(`model`));let v=0;_.addEventListener(`scroll`,()=>{v=Date.now()});let y=new Map,b=e=>{o=e,!e.reasoning&&a!==`off`&&(a=`off`,r.onThinkingLevelSelect?.(`off`));for(let[t,n]of y){let r=Qe(n,e);t.setAttribute(`aria-checked`,String(r));let i=t.querySelector(`.quickforge-model-menu-item-suffix`);i&&(i.textContent=r?`✓`:``)}h?.(),n(e)};if(r.noneLabel){let t=ru({label:r.noneLabel,selected:e===null});t.addEventListener(`click`,e=>{e.preventDefault(),e.stopPropagation(),!(Date.now()-v<300)&&(r.onNoneSelect?.(),$l(i))}),_.append(t)}let x=[...t].sort((e,t)=>$e(e).localeCompare($e(t)));for(let e of x){let t=ru({label:r.modelLabelOverride?r.modelLabelOverride(e):$e(e),selected:Qe(o,e),onClick:t=>{t.preventDefault(),t.stopPropagation(),!(Date.now()-v<300)&&b(e)}});y.set(t,e),_.append(t)}c.append(l,d,...m?[m]:[],g,_),c.addEventListener(`pointerdown`,e=>e.stopPropagation()),s.addEventListener(`pointerdown`,e=>{e.target===s&&$l(i)});let S=0,C=!1,w=!1,T,E=e=>{e.pointerType===`mouse`&&e.button!==0||(S=e.clientY,C=!0,w=!1,c.style.transition=`none`)},D=e=>{if(!C)return;let t=e.clientY-S;t>0&&(w=!0,c.style.transform=`translateY(${t}px)`,s.style.background=`rgb(15 23 42 / ${Math.max(0,.34*(1-t/480))})`)},O=()=>{C&&(C=!1,c.style.transition=`transform 0.24s ease`,(w&&Number.parseFloat(c.style.transform.replace(/[^0-9.-]/g,``))||0)>=112?(c.style.transform=`translateY(110%)`,s.style.background=`rgb(15 23 42 / 0)`,T=setTimeout(()=>$l(i),220)):(c.style.transform=``,s.style.background=``))};l.addEventListener(`pointerdown`,E),window.addEventListener(`pointermove`,D),window.addEventListener(`pointerup`,O),window.addEventListener(`pointercancel`,O);let k=e=>{if(e.type===`resize`){window.innerWidth>768&&$l(i);return}!(e instanceof KeyboardEvent)||e.key!==`Escape`||(e.preventDefault(),$l(i))};s.__quickforgeCleanup=()=>{T&&clearTimeout(T),document.removeEventListener(`keydown`,k,!0),window.removeEventListener(`resize`,k,!0),window.removeEventListener(`pointermove`,D),window.removeEventListener(`pointerup`,O),window.removeEventListener(`pointercancel`,O)},s.append(c),document.body.append(s),i?.setAttribute(`aria-expanded`,`true`),document.addEventListener(`keydown`,k,!0),window.addEventListener(`resize`,k,!0)}function au(e,t,n,r={}){let i=eu(r.anchor);if(document.querySelector(`.quickforge-model-menu, .quickforge-model-sheet-backdrop`)){$l(i);return}iu(e,t,n,{...r,showThinking:!1,onNoneSelect:r.noneLabel?()=>n(null):void 0},i)}function ou(e,t,n,r,i={}){let a=eu(i.anchor);if(document.querySelector(`.quickforge-model-menu, .quickforge-model-sheet-backdrop`)){$l(a);return}if(window.innerWidth<=768){iu(e,t,n,i,a);return}let o=i.thinkingLevel??`off`,s=e,c=null,l=document.createElement(`div`);l.className=`quickforge-model-menu`,l.setAttribute(`role`,`menu`),l.setAttribute(`aria-label`,W(`selectCustomModel`));let u=()=>{c?.remove(),c=document.createElement(`div`),c.className=`quickforge-model-submenu`,c.setAttribute(`role`,`menu`),c.setAttribute(`aria-label`,W(`model`));let e=document.createElement(`div`);e.className=`quickforge-model-menu-header`,e.textContent=W(`model`),c.append(e);let r=[...t].sort((e,t)=>$e(e).localeCompare($e(t)));for(let e of r)c.append(ru({label:$e(e),selected:Qe(s,e),onPointerDown:t=>{t.preventDefault(),t.stopPropagation(),!e.reasoning&&o!==`off`&&(o=`off`,i.onThinkingLevelSelect?.(`off`)),s=e,n(e),$l(a)}}));c.addEventListener(`pointerdown`,e=>e.stopPropagation()),document.body.append(c),nu(c,l)},d=()=>{l.replaceChildren();let e=document.createElement(`div`);if(e.className=`quickforge-model-menu-header`,e.textContent=W(`reasoning`),l.append(e),s?.reasoning===!0)for(let e of Xl)l.append(ru({label:Zl(e),selected:o===e,onPointerDown:t=>{t.preventDefault(),t.stopPropagation(),o=e,i.onThinkingLevelSelect?.(e),d(),tu(l,a)}}));else{let e=document.createElement(`div`);e.className=`quickforge-model-menu-note`,e.textContent=W(`thinkingNotSupported`),l.append(e)}let t=document.createElement(`div`);t.className=`quickforge-model-menu-separator`,l.append(t),l.append(ru({label:s?$e(s):W(`noModelAdded`),chevron:!0,onPointerEnter:u,onPointerDown:e=>{e.preventDefault(),e.stopPropagation(),u()}}))},f=()=>$l(a),p=e=>{if(e.type===`resize`||e.type===`scroll`){tu(l,a),c&&nu(c,l);return}if(e instanceof KeyboardEvent){if(e.key!==`Escape`)return;e.preventDefault()}else{let t=e.target;if(l.contains(t)||c?.contains(t)||a?.contains(t))return}f()};l.__quickforgeCleanup=()=>{document.removeEventListener(`pointerdown`,p,!0),document.removeEventListener(`keydown`,p,!0),window.removeEventListener(`resize`,p,!0),window.removeEventListener(`scroll`,p,!0)},l.addEventListener(`pointerdown`,e=>e.stopPropagation()),d(),document.body.append(l),tu(l,a),a?.setAttribute(`aria-expanded`,`true`),document.addEventListener(`pointerdown`,p,!0),document.addEventListener(`keydown`,p,!0),window.addEventListener(`resize`,p,!0),window.addEventListener(`scroll`,p,!0)}function su({storageRef:e,activeModelRef:t,agentRef:n,createAgent:r,updateCurrentAgentModel:i,setChatPanelRevision:a,setNeedsModelSetup:o,setRestoredDraft:s,notifySettingsChanged:c,openSettingsPage:l,loadCloudModels:u}){let d=(0,H.useCallback)(async()=>{let s=e.current;if(!s)return!1;let l=await fr(s);return l?(t.current=l,o(!1),await er(s,l),n.current?(i(l),a(e=>e+1)):await r({model:l,tools:[]},X(),{scope:`global`,attachToView:!0}),c(),!0):(o(!0),!1)},[e,t,n,r,i,a,o,c]),f=(0,H.useCallback)((e,t)=>{l(e,t)},[l]),p=(0,H.useCallback)(()=>{f(`customModels`)},[f]);return{activateConfiguredModel:d,openModelSettings:p,openDefaultOptionsSettings:(0,H.useCallback)(()=>{f(`defaults`)},[f]),openAboutSettings:(0,H.useCallback)(()=>{f(`about`)},[f]),activateLiteLlmExampleModel:(0,H.useCallback)(async()=>{let s=e.current;if(!s)return;let l=Yn(Hn);await vr(s,Hn,l),await er(s,l),t.current=l,o(!1),n.current?(i(l),a(e=>e+1)):await r({model:l,tools:[]},X(),{scope:`global`,attachToView:!0}),c()},[e,t,n,r,i,a,o,c]),openCustomModelSelector:(0,H.useCallback)(async r=>{let o=e.current,c=n.current;if(!o||!c)return;let l=r instanceof HTMLElement?r:r?.currentTarget instanceof HTMLElement?r.currentTarget:document.querySelector(`.quickforge-model-trigger`),d=document.querySelector(`agent-interface message-editor textarea`),m=document.querySelector(`agent-interface message-editor`),h=d?.value??``,g=m?.attachments?[...m.attachments]:[],_=mn();if(!_){try{_=await ur(o),gn(_)}catch(e){V.error(`Failed to load custom models, falling back to cache:`,e),_=hn()}if(!_)return}let v=await u().catch(e=>(V.warn(`Failed to load QuickForge Cloud models:`,e),[])),y=dr(_,v);if(y.length===0){await $c({description:W(`addCustomModelFirst`),confirmLabel:W(`modelSetupAddModel`),cancelLabel:W(`cancel`)})&&p();return}ou(c.state.model??t.current,y,e=>{let n=e,r=n.reasoning?c.state.thinkingLevel:`off`;c.state.thinkingLevel!==r&&(c.state.thinkingLevel=r,c.updateThinkingLevel(r).catch(e=>{V.error(`Failed to sync thinking level to server:`,e)})),t.current=n,i(n),(h||g.length>0)&&s({id:Date.now(),sessionId:c.sessionId,text:h,attachments:g}),a(e=>e+1),er(o,n).catch(e=>{V.error(`Failed to save active model:`,e)})},async e=>{e.provider!==`quickforge-cloud`&&f(`customModels`,e.provider)},{thinkingLevel:c.state.thinkingLevel,anchor:l,onThinkingLevelSelect:e=>{c.state.thinkingLevel=e,c.updateThinkingLevel(e).catch(e=>{V.error(`Failed to sync thinking level to server:`,e)}),a(e=>e+1)}})},[e,t,n,i,a,s,p,f,u])}}var cu=`x-quickforge-action`,lu=`cloud-action`,uu=new Set([`GET`,`HEAD`,`OPTIONS`]),du=class extends Error{status;code;details;constructor(e,{status:t=0,code:n=`cloud_request_failed`,details:r}={}){super(e),this.name=`CloudClientError`,this.status=t,this.code=n,this.details=r}};async function fu(e,t={}){let n=String(t.method||`GET`).toUpperCase(),r=await fetch(e,{...t,cache:`no-store`,headers:{Accept:`application/json`,...t.headers||{},...uu.has(n)?{}:{[cu]:lu},...t.body===void 0?{}:{"Content-Type":`application/json`}}});if(!r.ok){let e=`QuickForge Cloud request failed (${r.status})`,t=`cloud_request_failed`,n;try{let i=await r.json();typeof i.error==`string`?e=i.error:i.error?.message&&(e=i.error.message),typeof i.code==`string`?t=i.code:typeof i.error==`object`&&typeof i.error?.code==`string`&&(t=i.error.code),typeof i.error==`object`&&(n=i.error?.details)}catch{}throw new du(e,{status:r.status,code:t,details:n})}return r.json()}function pu(e){return fu(`/api/cloud/config`,{signal:e})}function mu(e,t){return fu(`/api/cloud/config`,{method:`PUT`,body:JSON.stringify(e),signal:t})}function hu(e,t){return fu(`/api/cloud/test-connection`,{method:`POST`,body:JSON.stringify({cloudUrl:e}),signal:t})}function gu(e){return fu(`/api/cloud/identity/reset`,{method:`POST`,body:JSON.stringify({confirm:`reset-cloud-identity`}),signal:e})}function _u(e){return fu(`/api/cloud/status`,{signal:e})}function vu(e){return fu(`/api/cloud/remote/status`,{signal:e})}function yu(e){return fu(`/api/cloud/device/start`,{method:`POST`,body:`{}`,signal:e})}function bu(e){return fu(`/api/cloud/device/poll`,{method:`POST`,body:`{}`,signal:e})}function xu(e){return fu(`/api/cloud/device/cancel`,{method:`POST`,body:`{}`,signal:e})}async function Su(e){let t=await fu(`/api/cloud/models`,{signal:e});return Array.isArray(t.items)?t.items:[]}function Cu(e){return fu(`/api/cloud/usage`,{signal:e})}async function wu(e){let t=await fu(`/api/cloud/installations`,{signal:e});return Array.isArray(t.items)?t.items:[]}function Tu(e,t){return fu(`/api/cloud/installations/${encodeURIComponent(e)}`,{method:`DELETE`,signal:t})}function Eu(e){return fu(`/api/cloud/logout`,{method:`POST`,signal:e})}var Du=`quickforge:cloud-state-changed`;function Ou(e=!0){let[t,n]=(0,H.useState)(!1),r=(0,H.useRef)([]),i=(0,H.useRef)(null),a=(0,H.useRef)(null),o=(0,H.useRef)(null),s=(0,H.useRef)(0),c=(0,H.useRef)(!0),l=(0,H.useCallback)(()=>{s.current+=1,a.current?.abort(),o.current?.abort(),a.current=null,o.current=null,i.current=null,r.current=[]},[]),u=(0,H.useCallback)(async(t=!1)=>{if(!e||!c.current)return[];if(t&&(r.current=[]),!t&&r.current.length>0)return r.current;if(i.current)return i.current;let o=s.current,l=new AbortController;a.current=l;let u=(async()=>{try{let e=await _u(l.signal);if(!c.current||o!==s.current||l.signal.aborted)return[];if(n(!!(e.enabled!==!1&&e.configured)),e.enabled===!1||!e.configured||e.mode===`local`||!e.hasSession)return r.current=[],[];let t=await Su(l.signal);return!c.current||o!==s.current||l.signal.aborted?[]:(r.current=t,t)}catch(e){if(!c.current||o!==s.current||l.signal.aborted)return[];throw e}})().finally(()=>{i.current===u&&(i.current=null),a.current===l&&(a.current=null)});return i.current=u,u},[e]);return(0,H.useEffect)(()=>{c.current=!0;let e=()=>{if(l(),!c.current)return;let e=s.current,t=new AbortController;o.current=t,_u(t.signal).then(r=>{c.current&&e===s.current&&!t.signal.aborted&&n(!!(r.enabled!==!1&&r.configured))}).catch(()=>void 0).finally(()=>{o.current===t&&(o.current=null)})};return window.addEventListener(Du,e),()=>{window.removeEventListener(Du,e),c.current=!1,l()}},[l]),(0,H.useEffect)(()=>{e||l()},[e,l]),{configured:t,loadCloudModels:u}}function ku(){let e=new URL(window.location.href);e.searchParams.delete(`session`),window.history.replaceState({},``,e)}function Au({storageRef:e,activeModelRef:t,activeProjectRef:n,currentChatScopeRef:r,currentSessionIdRef:i,taskMapRef:a,agentRef:o,startDeferredSession:s,createAgent:c,syncSessionUI:l,setCurrentAgentMessages:u,setChatPanelRevision:d,refreshSessions:f,needsModelSetup:p,setNeedsModelSetup:m,switchActiveProject:h,closeWorkspacePage:g,setRestoredDraft:_}){let v=(0,H.useCallback)(async()=>{if(p){if(((e.current?await ir(e.current):{}).harness??`quickforge`)!==`opencode`){$(W(`modelSetupRequired`));return}m(!1)}g();let t=o.current,n=await Ic({isDeferredSession:t instanceof Nc,isStreaming:t?.state.isStreaming??!1,messageCount:t?.state.messages.length??0,currentScope:r.current,targetScope:`global`,currentHarness:t?.harness??`quickforge`},async()=>(e.current?await ir(e.current):{}).harness??`quickforge`);if(n.action!==`reuse`){if(n.action===`replace`){_(void 0),ku(),await s({scope:`global`,harness:n.defaultHarness});return}_(void 0),ku(),await s({scope:`global`})}},[o,r,p,m,_,g,s,e]),y=(0,H.useCallback)(async t=>{if(p){if(((e.current?await ir(e.current):{}).harness??`quickforge`)!==`opencode`){$(W(`modelSetupRequired`));return}m(!1)}g();let i=t??n.current;if(!i)return;let a=o.current,c=await Ic({isDeferredSession:a instanceof Nc,isStreaming:a?.state.isStreaming??!1,messageCount:a?.state.messages.length??0,currentScope:r.current,targetScope:`project`,currentHarness:a?.harness??`quickforge`},async()=>(e.current?await ir(e.current):{}).harness??`quickforge`),l=n.current?.id===i.id;if(!(l&&c.action===`reuse`)){if(l&&c.action===`replace`){_(void 0),ku(),await s({scope:`project`,project:i,harness:c.defaultHarness});return}l||await h(i.id),_(void 0),ku(),await s({scope:`project`,project:i})}},[n,o,r,p,m,_,g,s,e,h]),b=(0,H.useCallback)(async s=>{let p=o.current;if(!p)return;if(p.harness===`opencode`){$(W(`openCodeMessageHistoryActionUnavailable`));return}if(p.state.isStreaming){$(W(`generationStillRunning`));return}let m=zc(p.state.messages,s),h=m>=0?p.state.messages[m]:void 0;if(m<0||!h){$(W(`noConversationTurnToRollback`));return}let g={id:Date.now(),sessionId:p.sessionId,text:Bc(h),attachments:h.role===`user-with-attachments`?h.attachments:void 0},v=p.state.messages.slice(0,m);try{v=(await p.rollback(s)).session.messages??v}catch(e){V.error(`Failed to rollback conversation:`,e),$(e instanceof Error?e.message:W(`rollbackFailed`));return}u(v);let y=i.current?a.current.get(i.current):void 0;if(Gc(v)&&y){g&&_(g),d(e=>e+1),l(y).catch(e=>V.error(`Failed to sync session UI:`,e));return}let b=e.current,x=i.current,S=r.current,C=S===`project`?n.current:void 0,w=p.state.model??t.current,T=p.state.thinkingLevel;if(x&&Yc(a.current,x),b&&x)try{await b.sessions.delete(x),await f({broadcast:!0})}catch(e){V.error(`Failed to delete rolled back empty session:`,e)}let E=X();await c({model:w,thinkingLevel:T,messages:[],tools:[]},E,{scope:S,project:C,attachToView:!0,title:`New chat`,harness:p.harness,sourceHarnessSessionId:void 0}),_({...g,sessionId:E}),d(e=>e+1)},[t,n,o,c,r,i,f,d,u,_,e,l,a]),x=(0,H.useCallback)(async e=>{try{await Vc(e)}catch(e){throw V.error(`Failed to copy answer:`,e),$(W(`copyFailed`)),e}},[]),S=(0,H.useCallback)(async()=>{let t=o.current;if(!(!t||!(t instanceof Mc))&&t.harness===`opencode`){if(t.state.isStreaming){$(W(`generationAlreadyRunning`));return}if(!t.harnessSessionId){$(W(`openCodeForkUnavailable`));return}try{await t.forkSession()}catch(e){V.error(`Failed to fork current conversation:`,e),$(e instanceof Error?e.message:W(`openCodeForkFailed`));return}e.current&&f({broadcast:!0}).catch(e=>V.error(`Failed to refresh sessions:`,e))}},[o,f,e]),C=(0,H.useCallback)(async i=>{let a=o.current;if(!a)return;if(a.harness===`opencode`){$(W(`openCodeMessageHistoryActionUnavailable`));return}if(a.state.isStreaming){$(W(`generationAlreadyRunning`));return}let s=a.state.messages.slice(0,i+1);if(!Wc(s))return;let l=r.current,u=l===`project`?n.current:void 0,d=X(),p=Hc(s),m=e.current;await c({model:a.state.model??t.current,thinkingLevel:a.state.thinkingLevel,messages:s,tools:[]},d,{scope:l,project:u,attachToView:!0,title:p,harness:a.harness,sourceHarnessSessionId:void 0}),m&&f({broadcast:!0}).catch(e=>V.error(`Failed to refresh sessions:`,e))},[t,n,o,c,r,f,e]);return{startNewGlobalChat:v,startNewProjectChat:y,rollbackFromMessage:b,retryFromMessage:(0,H.useCallback)(async e=>{let t=o.current;if(!t)return;if(t.harness===`opencode`){$(W(`openCodeMessageHistoryActionUnavailable`));return}if(t.state.isStreaming){$(W(`generationAlreadyRunning`));return}let n=t.state.messages;if(e<0||e>=n.length)return;let r=n[e];if(r.role!==`user`&&r.role!==`user-with-attachments`)return;u(n.slice(0,e+1)),d(e=>e+1);try{await t.continue()}catch(e){V.error(`Failed to retry:`,e),$(e instanceof Error?e.message:W(`retryFailed`));return}let s=i.current?a.current.get(i.current):void 0;s&&(l(s).catch(e=>V.error(`Failed to sync session UI after retry:`,e)),d(e=>e+1))},[o,i,d,u,l,a]),copyAnswer:x,forkFromMessage:C,forkCurrentSession:S}}function ju({activeProjectRef:e,refreshSessions:t,notifyProjectsChanged:n,setActiveProject:r,setProjects:i,setExpandedProjectIds:a,setChatPanelRevision:o}){return{deleteProjectInline:(0,H.useCallback)(async s=>{let c=await fetch(`/api/project/${encodeURIComponent(s)}`,{method:`DELETE`}),l=await c.json().catch(()=>null);if(!c.ok)throw Error(l?.error||`Failed to delete project`);r(l.project),i(l.projects),a(e=>{let t=new Set(e);return t.delete(s),t}),Js(`/api/project`),await t({broadcast:!0}),n(),e.current?.id===s&&(e.current=l.project,o(e=>e+1))},[e,t,n,r,i,a,o])}}var Mu=H.forwardRef(({className:e,type:t,...n},r)=>(0,K.jsx)(`input`,{type:t,className:G(`flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:border-primary focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50`,e),ref:r,...n}));Mu.displayName=`Input`;function Nu({options:e,onResolve:t}){let n=(0,H.useRef)(null),[r,i]=(0,H.useState)(e.defaultValue??``),a=(0,H.useRef)(r);return(0,H.useEffect)(()=>{a.current=r},[r]),(0,H.useEffect)(()=>{n.current?.focus(),n.current?.select()},[]),(0,H.useEffect)(()=>{let e=e=>{e.key===`Escape`&&t(null),e.key===`Enter`&&a.current.trim()&&t(a.current.trim())};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[t]),(0,qr.createPortal)((0,K.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50`,onClick:e=>{e.target===e.currentTarget&&t(null)},children:(0,K.jsxs)(`div`,{className:G(`w-full max-w-sm rounded-lg border border-border bg-background p-6 shadow-quickforge`,`mx-4`),children:[(0,K.jsx)(`h2`,{className:`text-base font-semibold text-foreground`,children:e.title}),e.description?(0,K.jsx)(`p`,{className:`mt-2 text-sm text-muted-foreground`,children:e.description}):null,(0,K.jsx)(`div`,{className:`mt-4`,children:(0,K.jsx)(Mu,{ref:n,value:r,onChange:e=>i(e.target.value),placeholder:e.placeholder,className:`w-full`})}),(0,K.jsxs)(`div`,{className:`mt-5 flex justify-end gap-2`,children:[(0,K.jsx)(q,{variant:`outline`,size:`sm`,onClick:()=>t(null),children:e.cancelLabel??`Cancel`}),(0,K.jsx)(q,{size:`sm`,onClick:()=>r.trim()?t(r.trim()):void 0,disabled:!r.trim(),children:e.confirmLabel??`Save`})]})]})}),document.body)}function Pu(e){return new Promise(t=>{let n=document.createElement(`div`);document.body.appendChild(n);let r=(0,it.createRoot)(n);function i(){r.unmount(),setTimeout(()=>n.remove(),0)}function a(e){i(),t(e)}r.render((0,K.jsx)(Nu,{options:e,onResolve:a}))})}function Fu({storageRef:e,taskMapRef:t,currentSessionIdRef:n,loadAgentSession:r,setCurrentTitleRef:i,refreshSessions:a,updateSessionTitle:o,closeWorkspacePage:s,startNewGlobalChat:c}){return{loadSession:(0,H.useCallback)(e=>(s(),r(e)),[r,s]),renameSession:(0,H.useCallback)(async(t,r)=>{if(!e.current)return;let a=await Pu({title:W(`renameSession`),description:W(`sessionName`),defaultValue:r,confirmLabel:W(`save`),cancelLabel:W(`cancel`)});if(!a||a===r)return;let s=await fetch(`/api/agents/${encodeURIComponent(t)}/title`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({title:a})});if(!s.ok)throw Error(`Failed to rename session: HTTP ${s.status}`);o(t,a),n.current===t&&i(a)},[n,i,e,o]),togglePinSession:(0,H.useCallback)(async t=>{let n=e.current;if(!n)return;let r=await n.sessions.getMetadata(t);if(!r)return;let i=r.pinnedAt?void 0:new Date().toISOString(),o={...r,pinnedAt:i};await n.backend.set(`sessions-metadata`,t,o),await a({broadcast:!0})},[a,e]),archiveSession:(0,H.useCallback)(async r=>{let i=e.current;if(!i)return;Yc(t.current,r);let o=await i.sessions.get(r);if(!o)return;let l=await i.sessions.getMetadata(r);if(!l)return;let u=new Date().toISOString(),d={...o,archivedAt:u},f={...l,archivedAt:u};await i.sessions.save(d,f),await a({broadcast:!0}),n.current===r&&(s(),await c())},[n,a,s,c,e,t]),startNewGlobalSession:(0,H.useCallback)(()=>{s(),c()},[s,c])}}var Iu=e=>e===`full-access`;function Lu({storageRef:e,agentAccessModeRef:t,setAgentAccessMode:n,agentRef:r,setChatPanelRevision:i,notifySettingsChanged:a}){let o=(0,H.useCallback)(o=>{let s=e.current,c=r.current,l=t.current;if(l===o)return;n(o),t.current=o;let u=()=>{t.current=l,n(l),i(e=>e+1)};(async()=>{try{c&&await c.updateAccessMode(o),s&&await gr(s,o),i(e=>e+1),a()}catch(e){V.error(`Failed to sync agent access mode:`,e),u(),$(e instanceof Error?e.message:W(`agentAccessModeSyncFailed`))}})()},[t,r,a,n,i,e]);return{setAccessMode:o,toggleYoloMode:(0,H.useCallback)(()=>{o(Iu(t.current)?`default`:`full-access`)},[t,o])}}function Ru(){let[e,t]=(0,H.useState)(!0),[n,r]=(0,H.useState)(!1),[i,a]=(0,H.useState)(!1),[o,s]=(0,H.useState)(!1),[c,l]=(0,H.useState)(!1),[u,d]=(0,H.useState)(),[f,p]=(0,H.useState)(!1),[m,h]=(0,H.useState)(!1),[g,_]=(0,H.useState)(!1),[v,y]=(0,H.useState)(),[b,x]=(0,H.useState)(!1),[S,C]=(0,H.useState)(),[w,T]=(0,H.useState)(!1),[E,D]=(0,H.useState)(!1),[O,k]=(0,H.useState)(`defaults`),[ee,te]=(0,H.useState)();return{sidebarOpen:e,setSidebarOpen:t,mobileSidebarOpen:n,setMobileSidebarOpen:r,projectsCollapsed:i,setProjectsCollapsed:a,pinnedCollapsed:o,setPinnedCollapsed:s,conversationsCollapsed:c,setConversationsCollapsed:l,skillsDialog:u,setSkillsDialog:d,shareDialogOpen:f,setShareDialogOpen:p,conversationMenuOpen:m,setConversationMenuOpen:h,workspaceInspectorOpen:g,setWorkspaceInspectorOpen:_,workspaceInspectorRequest:v,setWorkspaceInspectorRequest:y,artifactPreviewOpen:b,setArtifactPreviewOpen:x,activeArtifactPath:S,setActiveArtifactPath:C,firstUseGuideDismissed:w,setFirstUseGuideDismissed:T,settingsDialogOpen:E,setSettingsDialogOpen:D,settingsInitialTab:O,setSettingsInitialTab:k,settingsCustomProvider:ee,setSettingsCustomProvider:te,toggleProjectsCollapsed:(0,H.useCallback)(()=>a(e=>!e),[]),togglePinnedCollapsed:(0,H.useCallback)(()=>s(e=>!e),[]),toggleConversationsCollapsed:(0,H.useCallback)(()=>l(e=>!e),[])}}function zu(e){return e===`running`||e===`idle`||e===`error`||e===`aborted`?e:void 0}function Bu(e){let[t,n]=(0,H.useState)({}),r=(0,H.useMemo)(()=>new Set(e.map(e=>e.id)),[e]),i=(0,H.useMemo)(()=>e.map(e=>e.id).sort().join(`
|
|
65
|
+
`),[e]),a=(0,H.useCallback)(async()=>{if(r.size===0){n({});return}try{let e=await Ac(),t=new Map(e.map(e=>[e.sessionId,zu(e.status)]).filter(e=>!!e[1]));n(e=>{let n={};for(let i of r){let r=t.get(i),a=e[i];r?n[i]=r:a===`running`?n[i]=`idle`:a&&a!==`idle`&&(n[i]=a)}return n})}catch(e){V.error(`Failed to refresh visible agent statuses:`,e)}},[r]);return(0,H.useEffect)(()=>{let e=window.setTimeout(()=>{a()},0);return()=>window.clearTimeout(e)},[a,i]),(0,H.useEffect)(()=>jc(e=>{let t=e.sessionId;if(!(!t||!r.has(t))){if(e.type===`agent_start`){n(e=>({...e,[t]:`running`}));return}if(e.type===`agent_end`){let r=zu(e.status)===`aborted`?`aborted`:e.errorMessage?`error`:`idle`;n(e=>({...e,[t]:r}))}}}),[r]),(0,H.useEffect)(()=>{let e=()=>{document.visibilityState===`visible`&&a()};return document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e)},[a]),t}function Vu(e,t=window.requestAnimationFrame.bind(window),n=window.cancelAnimationFrame.bind(window)){let r=!1,i=t(()=>{r||(i=t(()=>{r||e()}))});return()=>{r=!0,n(i)}}var Hu=`quickforge:tunnel-recovered`,Uu=null;async function Wu(e){if(Uu)return{status:`deferred`,reason:`in-flight`};Uu=Gu(e);try{return await Uu}finally{Uu=null}}async function Gu(e){let t=e.fetchImpl??globalThis.fetch,n=e.reload??(()=>window.location.reload()),r=e.dispatchEvent??(e=>window.dispatchEvent(e)),i=e.maxAttempts??2,a=e.retryDelayMs??700,o=e.timeoutMs??3e3,s=e.recoveryWaitTimeoutMs??5e3;if(!await Ku(e.probe))return{status:`deferred`,reason:`probe-failed`};for(let e=0;e<i;e++)if(e>0&&await Xu(a),await qu(t,o)){if(await Yu(r,s))return{status:`recovered`};break}try{n()}catch{}return{status:`reloaded`}}async function Ku(e){try{return await e()}catch{return!1}}async function qu(e,t){let[n,r]=await Promise.all([Ju(e,`/api/health`,t),Ju(e,`/api/agents`,t)]);if(!n?.ok||!r?.ok)return!1;let i=r.body;return Array.isArray(i?.sessions)}async function Ju(e,t,n){let r=new AbortController,i=globalThis.setTimeout(()=>r.abort(),n);try{let n=await e(t,{cache:`no-store`,signal:r.signal}),i=n.ok?await n.json().catch(()=>null):null;return{ok:n.ok,body:i}}catch{return null}finally{globalThis.clearTimeout(i)}}async function Yu(e,t){let n=0,r=[],i={at:Date.now(),waitUntil:e=>{n+=1,r.push(e)}};try{e(new Event(`online`)),e(new CustomEvent(Hu,{detail:i}))}catch{return!1}if(n===0)return!1;let a=Promise.all(r),o,s=new Promise((e,n)=>{o=globalThis.setTimeout(()=>n(Error(`tunnel recovery waitUntil timeout`)),t)});try{return await Promise.race([a,s]),!0}catch{return!1}finally{globalThis.clearTimeout(o)}}function Xu(e){return new Promise(t=>setTimeout(t,e))}var Zu=`quickforge:sidebar-session-view-mode:v1`,Qu=`quickforge:sidebar-session-sort-mode:v1`,$u=`project`,ed=`updatedAt`;function td(){try{return globalThis.localStorage}catch{return}}function nd(){let e=td();if(!e)return $u;try{let t=e.getItem(Zu);return t===`timeline`||t===`project`?t:$u}catch{return $u}}function rd(e){let t=td();if(t)try{t.setItem(Zu,e)}catch{}}function id(){let e=td();if(!e)return ed;try{let t=e.getItem(Qu);return t===`createdAt`||t===`updatedAt`?t:ed}catch{return ed}}function ad(e){let t=td();if(t)try{t.setItem(Qu,e)}catch{}}function od({ready:e,currentToolProjectId:t,projects:n,activeProject:r,recoveringProjectId:i}){return!e||!t||t===`default`||n.some(e=>e.id===t)||i===t?{type:`none`}:r?{type:`project`,deletedProjectId:t,project:r}:{type:`global`,deletedProjectId:t}}function sd(e,t,n){return e.projectId===t&&e.requestId===n}var cd=new Set([`write_file`,`edit_file`,`run_command`,`run_subagent`]);function ld(e,t,n){return e.type!==`tool_execution_end`||!t||e.sessionId!==t||!n?!1:typeof e.toolName==`string`&&cd.has(e.toolName)}function ud(e){return e===`idle`?{tone:`success`,message:W(`taskCompleted`)}:e===`error`?{tone:`error`,message:W(`taskError`)}:e===`aborted`?{tone:`aborted`,message:W(`processAborted`)}:e===`running`?{tone:`running`,message:W(`taskRunning`)}:{tone:`neutral`,message:W(`taskRunning`)}}function dd({toast:e,onDismiss:t,onClick:n}){let[r,i]=(0,H.useState)(!1),[a,o]=(0,H.useState)(!1),c=(0,H.useRef)(null);(0,H.useEffect)(()=>{let n=window.setTimeout(()=>i(!0),10);return c.current=window.setTimeout(()=>{o(!0),c.current=window.setTimeout(()=>t(e.id),200)},5e3),()=>{window.clearTimeout(n),c.current!==null&&window.clearTimeout(c.current)}},[e.id,t]);let l=()=>{o(!0),c.current!==null&&window.clearTimeout(c.current),c.current=window.setTimeout(()=>t(e.id),200)},u=ud(e.status),d=u.tone===`error`,f=u.tone===`success`,p=G(`size-5`,d&&`text-destructive`,f&&`text-emerald-500`,u.tone===`aborted`&&`text-amber-600`,u.tone===`running`&&`text-blue-600`,u.tone===`neutral`&&`text-muted-foreground`);return(0,K.jsxs)(`div`,{role:`alert`,onClick:()=>n(e.sessionId),className:G(`pointer-events-auto flex w-80 cursor-pointer items-start gap-3 rounded-xl border border-border bg-background p-3 shadow-quickforge transition-all duration-200 ease-out`,r&&!a?`translate-x-0 opacity-100`:`translate-x-4 opacity-0`),children:[(0,K.jsx)(`div`,{className:`mt-0.5 shrink-0`,children:f?(0,K.jsx)(x,{className:p}):(0,K.jsx)(s,{className:p})}),(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsx)(`p`,{className:`truncate text-sm font-medium text-foreground/90`,children:e.title}),(0,K.jsx)(`p`,{className:`mt-0.5 line-clamp-3 text-xs text-muted-foreground`,children:e.message||u.message})]}),(0,K.jsx)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),l()},className:`shrink-0 rounded-md p-0.5 text-muted-foreground/60 transition-colors hover:text-foreground`,"aria-label":W(`close`),children:(0,K.jsx)(z,{className:`size-4`})})]})}function fd({toasts:e,onDismiss:t,onClick:n}){return e.length===0?null:(0,K.jsx)(`div`,{className:`pointer-events-none fixed right-4 top-16 z-50 flex flex-col gap-2`,children:e.map(e=>(0,K.jsx)(dd,{toast:e,onDismiss:t,onClick:n},e.id))})}async function pd(e){let t=await fetch(e,{cache:`no-store`}),n=await t.json().catch(()=>null);if(!t.ok)throw Error(n?.error||`Request failed: ${t.status}`);return n}async function md(e,t){let n=await fetch(e,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||`Request failed: ${n.status}`);return r}function hd(e){return`projectId=${encodeURIComponent(e)}`}function gd(e){return pd(`/api/workspace/tree?${hd(e)}`)}function _d(e,t){return pd(`/api/workspace/file?${hd(e)}&path=${encodeURIComponent(t)}`)}function vd(e,t){return md(`/api/workspace/resolve-path`,{projectId:e,path:t})}function yd(e,t,n){return md(`/api/workspace/open-external`,{projectId:e,path:t,target:n})}function bd(e){return pd(`/api/git/status?${hd(e)}`)}function xd(e,t){return pd(`/api/git/file-diff?${hd(e)}&path=${encodeURIComponent(t)}`)}function Sd(e,t){return md(`/api/git/stage`,{projectId:e,path:t})}function Cd(e){return md(`/api/git/stage-all`,{projectId:e})}function wd(e,t){return md(`/api/git/unstage`,{projectId:e,path:t})}function Td(e){return md(`/api/git/unstage-all`,{projectId:e})}function Ed(e,t){return md(`/api/git/restore`,{projectId:e,path:t})}function Dd(e){return md(`/api/git/restore-all`,{projectId:e})}function Od(e){return pd(`/api/git/branches?${hd(e)}`)}function kd(e,t){return md(`/api/git/checkout`,{projectId:e,branch:t})}function Ad(e,t){return md(`/api/git/create-branch`,{projectId:e,branch:t})}function jd(e){return pd(`/api/git/log?${hd(e)}`)}function Md(e,t,n,r){return md(`/api/git/generate-commit-message`,{projectId:e,modelRef:t&&typeof t==`object`?tt(t):void 0,model:t,thinkingLevel:n,includeUnstaged:r})}function Nd(e,t,n){return md(`/api/git/commit`,{projectId:e,message:t,includeUnstaged:n})}function Pd(e){return md(`/api/git/push`,{projectId:e})}function Fd(e,t,n){return md(`/api/git/commit-and-push`,{projectId:e,message:t,includeUnstaged:n})}function Id({projectId:e,currentBranch:t,dirtyCount:n=0,className:r,openChangesClassName:i,onCheckout:a,onCreated:s,onOpenGraph:c,onOpenChanges:l}){let u=(0,H.useRef)(null),[d,f]=(0,H.useState)(``),[p,m]=(0,H.useState)([]),[h,g]=(0,H.useState)(!0),[_,v]=(0,H.useState)(),[y,b]=(0,H.useState)(),x=(0,H.useCallback)(async()=>{g(!0),v(void 0);try{m((await Od(e)).branches)}catch(e){v(e instanceof Error?e.message:W(`gitBranchesFailed`))}finally{g(!1)}},[e]);(0,H.useEffect)(()=>{let e=window.setTimeout(()=>{x(),u.current?.focus()},0);return()=>window.clearTimeout(e)},[x]);let S=(0,H.useMemo)(()=>{let e=d.trim().toLowerCase();return e?p.filter(t=>t.name.toLowerCase().includes(e)):p},[p,d]),C=(0,H.useCallback)(async e=>{if(!(e.current||y)){b(e.name);try{await a(e.name),await x()}finally{b(void 0)}}},[y,a,x]),w=(0,H.useCallback)(async()=>{let t=await Pu({title:W(`createBranchTitle`),description:W(`createBranchDescription`),placeholder:W(`createBranchPlaceholder`),confirmLabel:W(`createAndCheckoutBranch`),cancelLabel:W(`cancel`)});if(t){b(t);try{let n=await Ad(e,t);s?.(n),await x()}catch(e){$(e instanceof Error?e.message:W(`gitCheckoutFailed`))}finally{b(void 0)}}},[s,e,x]);return(0,K.jsxs)(`div`,{className:G(`absolute left-0 top-10 z-40 w-[340px] overflow-hidden rounded-2xl border border-border bg-popover shadow-quickforge`,r),onClick:e=>e.stopPropagation(),children:[(0,K.jsx)(`div`,{className:`border-b-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] p-3`,children:(0,K.jsxs)(`div`,{className:`relative`,children:[(0,K.jsx)(Se,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground/70`}),(0,K.jsx)(Mu,{ref:u,value:d,onChange:e=>f(e.target.value),placeholder:W(`searchBranches`),className:`h-10 rounded-xl border-transparent bg-background pl-9 text-sm shadow-none focus-visible:border-border`})]})}),l?(0,K.jsxs)(`button`,{type:`button`,className:G(`flex w-full items-center justify-center gap-2 border-b-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-3 py-3 text-sm text-muted-foreground transition-colors hover:bg-muted/20 hover:text-foreground`,i),onClick:l,children:[(0,K.jsx)(`span`,{children:W(`uncommittedChanges`)}),(0,K.jsx)(`span`,{children:W(`filesCount`,{count:n})})]}):null,(0,K.jsx)(`div`,{className:`max-h-[340px] overflow-y-auto p-2`,children:h?(0,K.jsxs)(`div`,{className:`flex items-center justify-center gap-2 px-3 py-8 text-sm text-muted-foreground`,children:[(0,K.jsx)(B,{className:`size-4 animate-spin`}),(0,K.jsx)(`span`,{children:W(`loading`)})]}):_?(0,K.jsx)(`div`,{className:`rounded-xl bg-muted/40 px-3 py-4 text-sm text-muted-foreground`,children:_}):S.length===0?(0,K.jsx)(`div`,{className:`rounded-xl bg-muted/40 px-3 py-4 text-sm text-muted-foreground`,children:W(`noBranchesFound`)}):S.map(e=>{let n=e.current||e.name===t,r=y===e.name;return(0,K.jsxs)(`button`,{type:`button`,className:G(`flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-left text-sm transition-colors`,n?`bg-muted text-foreground`:`text-foreground/88 hover:bg-muted/70`),onClick:()=>void C(e),disabled:n||!!y,title:e.name,children:[r?(0,K.jsx)(B,{className:`size-4 shrink-0 animate-spin`}):(0,K.jsx)(pe,{className:G(`size-4 shrink-0`,n?`text-foreground`:`text-muted-foreground`)}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:e.name}),n?(0,K.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(`currentBranch`)}):null]},`${e.remote?`remote`:`local`}:${e.name}`)})}),s||c?(0,K.jsxs)(`div`,{className:`border-t-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] p-2`,children:[s?(0,K.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-left text-sm text-foreground/88 transition-colors hover:bg-muted/70`,onClick:()=>void w(),disabled:!!y,children:[(0,K.jsx)(o,{className:`size-4 text-muted-foreground`}),(0,K.jsx)(`span`,{children:W(`createAndCheckoutBranchEllipsis`)})]}):null,c?(0,K.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-left text-sm text-foreground/88 transition-colors hover:bg-muted/70`,onClick:c,children:[(0,K.jsx)(ge,{className:`size-4 text-muted-foreground`}),(0,K.jsx)(`span`,{children:W(`gitGraph`)})]}):null]}):null]})}function Ld(e){return e?.detached===!0||e?.branch===`HEAD`||!!e?.branch?.startsWith(`HEAD `)}function Rd(e,t){return e?.files?.length?e.files.filter(e=>!e.conflict&&(t||e.staged)):[]}function zd(e,t,n){return!!(e?.isGitRepository&&!e.counts?.conflicts&&!Ld(e)&&n.trim()&&Rd(e,t).length)}function Bd(e){return(e?.files??[]).reduce((e,t)=>(e.additions+=t.additions??0,e.deletions+=t.deletions??0,e),{additions:0,deletions:0})}function Vd(e){return e.conflict?`!`:e.status===`untracked`?`?`:e.status===`added`?`A`:e.status===`deleted`?`D`:e.status===`renamed`?`R`:`M`}function Hd({open:e,projectId:t,status:n,onClose:r,onCheckout:i,onRefreshStatus:a,onStatusChange:o,onCompleted:s}){let[c,l]=(0,H.useState)(``),[u,d]=(0,H.useState)(!1),[p,m]=(0,H.useState)(!1),[h,g]=(0,H.useState)(!1),[_,v]=(0,H.useState)(!0),[b,x]=(0,H.useState)(),[C,w]=(0,H.useState)(``),[E,D]=(0,H.useState)(``),[O,k]=(0,H.useState)(),[ee,te]=(0,H.useState)(`off`),A=(0,H.useMemo)(()=>Bd(n),[n]),ne=(0,H.useMemo)(()=>Rd(n,u),[u,n]),re=(0,H.useMemo)(()=>new Set(ne.map(e=>e.path)),[ne]),M=n?.counts?.total??n?.files.length??0,N=Ld(n),P=!_&&zd(n,u,c);if((0,H.useEffect)(()=>{if(!e)return;let t=!1;return a().then(e=>{!t&&!e&&w(W(`gitStatusRefreshFailed`))}).finally(()=>{t||v(!1)}),()=>{t=!0}},[a,e,t]),(0,H.useEffect)(()=>{if(!e)return;let t=!1;async function n(){try{let e=await $n(),n=await ir(e),r=await fr(e,[],n.model);if(t||!r)return;k(r),te(n.thinkingLevel??tr(r))}catch{}}return n(),()=>{t=!0}},[e]),(0,H.useEffect)(()=>{if(!p)return;let e=()=>m(!1);return window.addEventListener(`click`,e),window.addEventListener(`blur`,e),()=>{window.removeEventListener(`click`,e),window.removeEventListener(`blur`,e)}},[p]),(0,H.useEffect)(()=>{if(!e)return;function t(e){e.key===`Escape`&&!b&&(m(!1),r())}return window.addEventListener(`keydown`,t),()=>window.removeEventListener(`keydown`,t)},[b,r,e]),!e)return null;async function ie(){if(!t){w(W(`gitCommitNoProject`));return}if(!O){w(W(`gitCommitNoModel`));return}if(!ne.length){w(W(`gitNoStagedChanges`));return}x(`generate`),w(``);try{l((await Md(t,O,ee,u)).message)}catch(e){w(e instanceof Error?e.message:W(`gitGenerateCommitMessageFailed`))}finally{x(void 0)}}async function F(e){if(t){if(e!==`push`){if(!c.trim()){w(W(`gitCommitMessageRequired`));return}if(!P){w(W(N?`gitDetachedHeadBlocked`:`gitNoStagedChanges`));return}}if(N){w(W(`gitDetachedHeadBlocked`));return}x(e),w(``);try{if(e===`push`){let e=await Pd(t);D(``),s(e);return}if(e===`commit-push`){let e=await Fd(t,c.trim(),u);if(!e.pushed){o(e),l(``),D(e.pushError||W(`gitOperationFailed`));return}l(``),s(e);return}let n=await Nd(t,c.trim(),u);l(``),s(n)}catch(e){w(e instanceof Error?e.message:W(`gitOperationFailed`))}finally{x(void 0)}}}return(0,qr.createPortal)((0,K.jsx)(`div`,{className:`fixed inset-0 z-[80] flex items-center justify-center bg-black/50 px-6 py-8`,role:`dialog`,"aria-modal":`true`,onMouseDown:e=>{e.target===e.currentTarget&&!b&&(m(!1),r())},children:(0,K.jsxs)(`div`,{className:`flex max-h-[min(700px,calc(100vh-64px))] w-full max-w-[760px] flex-col overflow-hidden rounded-3xl border border-[color-mix(in_oklab,var(--border)_42%,transparent)] bg-background shadow-2xl`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between px-6 py-5`,children:[(0,K.jsxs)(`div`,{className:`relative min-w-0`,onClick:e=>e.stopPropagation(),children:[(0,K.jsxs)(`button`,{type:`button`,className:`flex max-w-[280px] items-center gap-2.5 rounded-xl px-2 py-1.5 text-base text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,onClick:()=>m(e=>!e),disabled:!t||!!b,"aria-label":W(`gitBranchMenu`),"aria-haspopup":`menu`,"aria-expanded":p,children:[(0,K.jsx)(pe,{className:`size-5 shrink-0`}),(0,K.jsx)(`span`,{className:`min-w-0 truncate`,children:n?.branch||W(`unknown`)}),(0,K.jsx)(y,{className:`size-4 shrink-0`})]}),p&&t?(0,K.jsx)(Id,{projectId:t,currentBranch:n?.branch,className:`top-11`,onCheckout:async e=>{await i(e),m(!1)}}):null]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-3 text-base font-medium`,children:[(0,K.jsxs)(`span`,{className:`text-emerald-600`,children:[`+`,A.additions]}),(0,K.jsxs)(`span`,{className:`text-red-600`,children:[`-`,A.deletions]}),(0,K.jsx)(`button`,{type:`button`,className:`ml-2 rounded-full p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,onClick:()=>{m(!1),r()},disabled:!!b,"aria-label":W(`close`),children:(0,K.jsx)(z,{className:`size-5`})})]})]}),(0,K.jsxs)(`div`,{className:`relative min-h-44 px-6 pb-4`,children:[(0,K.jsx)(`textarea`,{value:c,onChange:e=>{l(e.target.value),w(``)},onKeyDown:e=>{(e.ctrlKey||e.metaKey)&&e.key===`Enter`&&(e.preventDefault(),!b&&P&&F(`commit`))},placeholder:W(`gitCommitMessagePlaceholder`),disabled:!!b,className:`min-h-40 w-full resize-none bg-transparent pr-12 text-base leading-7 text-foreground/90 outline-none placeholder:text-muted-foreground/72 disabled:opacity-60`}),(0,K.jsx)(`button`,{type:`button`,className:G(`absolute right-6 top-0 rounded-full p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground`,b===`generate`&&`pointer-events-none`),onClick:()=>void ie(),disabled:!!b||_||!ne.length||N,title:W(`gitGenerateCommitMessage`),"aria-label":W(`gitGenerateCommitMessage`),children:b===`generate`?(0,K.jsx)(B,{className:`size-5 animate-spin`}):(0,K.jsx)(j,{className:`size-5`})})]}),(0,K.jsxs)(`div`,{className:`border-t border-[color-mix(in_oklab,var(--border)_24%,transparent)] px-6 py-3 text-sm`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,K.jsxs)(`label`,{className:`flex min-w-0 items-center gap-3 text-foreground/92`,children:[(0,K.jsx)(`button`,{type:`button`,className:G(`flex size-5 shrink-0 items-center justify-center rounded-md border transition-colors`,u?`border-black bg-black text-white`:`border-border bg-background text-transparent`),onClick:()=>{d(e=>!e),D(``),w(``)},disabled:!!b||_,"aria-pressed":u,children:(0,K.jsx)(S,{className:`size-3.5`})}),(0,K.jsx)(`span`,{children:W(`gitIncludeUnstagedChanges`)})]}),(0,K.jsxs)(`button`,{type:`button`,className:`flex shrink-0 items-center gap-1.5 text-muted-foreground transition-colors hover:text-foreground`,onClick:()=>g(e=>!e),disabled:!M,children:[(0,K.jsx)(`span`,{children:W(`gitCommitFilesSummary`,{selected:ne.length,total:M})}),(0,K.jsx)(y,{className:G(`size-4 transition-transform`,h&&`rotate-180`)})]})]}),u?(0,K.jsx)(`div`,{className:`mt-2 text-xs text-muted-foreground`,children:W(`gitIncludeUnstagedWarning`)}):null,h?(0,K.jsx)(`div`,{className:`mt-3 max-h-44 space-y-1 overflow-y-auto border-t border-[color-mix(in_oklab,var(--border)_24%,transparent)] pt-3`,children:(n?.files??[]).map(e=>{let t=re.has(e.path);return(0,K.jsxs)(`div`,{className:G(`flex items-center gap-2 rounded-lg px-2 py-1.5`,!t&&`opacity-45`),children:[(0,K.jsx)(`span`,{className:`w-4 shrink-0 text-center font-mono text-xs text-muted-foreground`,children:Vd(e)}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,title:e.path,children:e.oldPath?`${e.oldPath} → ${e.path}`:e.path}),t?null:(0,K.jsx)(`span`,{className:`shrink-0 text-xs text-muted-foreground`,children:W(`gitFileNotIncluded`)})]},`${e.oldPath??``}:${e.path}`)})}):null]}),_?(0,K.jsx)(`div`,{className:`mx-6 mb-3 rounded-2xl bg-muted/55 px-4 py-3 text-sm text-muted-foreground`,children:W(`gitRefreshingStatus`)}):null,N?(0,K.jsx)(`div`,{className:`mx-6 mb-3 rounded-2xl bg-destructive/10 px-4 py-3 text-sm text-destructive`,children:W(`gitDetachedHeadBlocked`)}):null,E?(0,K.jsxs)(`div`,{className:`mx-6 mb-3 rounded-2xl bg-destructive/10 px-4 py-3 text-sm text-destructive`,children:[(0,K.jsx)(`div`,{className:`font-medium`,children:W(`gitCommitSucceededPushFailed`)}),(0,K.jsx)(`div`,{className:`mt-1 break-words text-xs opacity-90`,children:E})]}):null,C?(0,K.jsx)(`div`,{className:`mx-6 mb-3 rounded-2xl bg-destructive/10 px-4 py-3 text-sm text-destructive`,children:C}):null,n?.counts?.conflicts?(0,K.jsx)(`div`,{className:`mx-6 mb-3 rounded-2xl bg-destructive/10 px-4 py-3 text-sm text-destructive`,children:W(`gitCommitConflictsBlocked`)}):null,(0,K.jsx)(`div`,{className:`border-t border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-6 py-4`,children:E?(0,K.jsxs)(`button`,{type:`button`,className:`flex h-12 w-full items-center gap-3 rounded-2xl bg-muted/70 px-3 text-left transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-45`,disabled:!!b||N,onClick:()=>void F(`push`),children:[b===`push`?(0,K.jsx)(B,{className:`size-4 shrink-0 animate-spin`}):(0,K.jsx)(f,{className:`size-4 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{children:W(`gitRetryPush`)})]}):(0,K.jsxs)(`div`,{className:`space-y-1.5 text-base`,children:[(0,K.jsxs)(`button`,{type:`button`,className:`flex h-11 w-full items-center gap-3 rounded-2xl px-3 text-left transition-colors hover:bg-muted/55 disabled:cursor-not-allowed disabled:opacity-45`,disabled:!!b||!P,onClick:()=>void F(`commit`),children:[b===`commit`?(0,K.jsx)(B,{className:`size-4 shrink-0 animate-spin`}):(0,K.jsx)(se,{className:`size-4 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{children:W(`gitCommitOnly`)})]}),(0,K.jsxs)(`button`,{type:`button`,className:`flex h-12 w-full items-center gap-3 rounded-2xl bg-muted/70 px-3 text-left transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-45`,disabled:!!b||!P,onClick:()=>void F(`commit-push`),children:[b===`commit-push`?(0,K.jsx)(B,{className:`size-4 shrink-0 animate-spin`}):(0,K.jsx)(T,{className:`size-4 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`flex-1`,children:W(`gitCommitAndPush`)})]}),(0,K.jsxs)(`button`,{type:`button`,className:`flex h-11 w-full items-center gap-3 rounded-2xl px-3 text-left text-muted-foreground transition-colors hover:bg-muted/45 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-35`,disabled:!!b||_||N,onClick:()=>void F(`push`),children:[b===`push`?(0,K.jsx)(B,{className:`size-4 shrink-0 animate-spin`}):(0,K.jsx)(f,{className:`size-4 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{children:W(`gitPushOnly`)})]})]})})]})}),document.body)}function Ud(e){return e.files.reduce((e,t)=>(e.additions+=t.additions??0,e.deletions+=t.deletions??0,e),{additions:0,deletions:0})}function Wd({projectId:e,status:t,expanded:n,onExpandedChange:r,onOpenChanges:i,onOpenCommitPush:a,onCheckout:o,onCreated:s,onOpenGraph:c,mobileShell:l=!1}){let u=(0,H.useRef)(null),[d,f]=(0,H.useState)(!1),p=(0,H.useMemo)(()=>Ud(t),[t]),h=t.counts?.total??t.files.length;return(0,H.useEffect)(()=>{if(!n)return;function e(){f(!1),r(!1)}function t(t){u.current?.contains(t.target)||e()}function i(t){t.key===`Escape`&&e()}return document.addEventListener(`pointerdown`,t),document.addEventListener(`keydown`,i),()=>{document.removeEventListener(`pointerdown`,t),document.removeEventListener(`keydown`,i)}},[n,r]),t.isGitRepository?(0,K.jsxs)(`div`,{ref:u,className:`relative`,onClick:e=>e.stopPropagation(),children:[(0,K.jsx)(`button`,{type:`button`,className:G(`inline-flex size-9 items-center justify-center rounded-2xl bg-transparent text-muted-foreground/85 transition-colors hover:bg-muted/45 hover:text-foreground/90`,n&&`bg-muted/45 text-foreground/90`),onClick:()=>r(!n),"aria-label":W(`togglePinnedSummary`),title:W(`togglePinnedSummary`),"aria-expanded":n,children:(0,K.jsx)(m,{className:`size-[18px]`})}),n?(0,K.jsxs)(`div`,{className:G(`fixed inset-x-2 top-14 z-40 max-h-[calc(100dvh-4rem)] overflow-y-auto overscroll-contain rounded-3xl border border-[color-mix(in_oklab,var(--border)_38%,transparent)] bg-background p-4 text-foreground shadow-quickforge md:absolute md:inset-x-auto md:-right-10 md:top-11 md:max-h-none md:w-[min(15rem,calc(100vw-1rem))] md:overflow-visible lg:-right-20`,l&&`md:fixed md:inset-x-2 md:right-auto md:top-14 md:max-h-[calc(100dvh-4rem)] md:w-auto md:overflow-y-auto lg:inset-x-2 lg:right-auto lg:top-14`),children:[(0,K.jsxs)(`div`,{className:`mb-4 flex items-center justify-between`,children:[(0,K.jsx)(`div`,{className:`text-sm font-medium text-muted-foreground`,children:W(`environmentInfo`)}),(0,K.jsx)(`button`,{type:`button`,className:`rounded-full p-1.5 text-foreground/85 transition-colors hover:bg-muted`,onClick:()=>{f(!1),r(!1)},"aria-label":W(`gitToolsCollapse`),title:W(`gitToolsCollapse`),children:(0,K.jsx)(z,{className:`size-4`})})]}),(0,K.jsxs)(`div`,{className:`space-y-1 text-sm`,children:[(0,K.jsxs)(`button`,{type:`button`,className:G(`hidden h-11 w-full items-center gap-3 rounded-2xl px-2.5 text-left text-foreground/88 transition-colors hover:bg-muted/45 hover:text-foreground md:flex`,l&&`md:hidden`),onClick:i,children:[(0,K.jsx)(ve,{className:`size-4 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`flex-1 font-medium`,children:W(`gitToolsChanges`)}),(0,K.jsxs)(`span`,{className:`font-medium text-emerald-600`,children:[`+`,p.additions]}),(0,K.jsxs)(`span`,{className:`font-medium text-red-600`,children:[`-`,p.deletions]})]}),(0,K.jsxs)(`div`,{className:`relative`,children:[(0,K.jsxs)(`button`,{type:`button`,className:`flex h-11 w-full items-center gap-3 rounded-2xl px-2.5 text-left text-foreground/88 transition-colors hover:bg-muted/45 hover:text-foreground`,onClick:()=>f(e=>!e),"aria-expanded":d,children:[(0,K.jsx)(pe,{className:`size-4 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-medium`,children:t.branch||W(`unknown`)}),(0,K.jsx)(y,{className:G(`size-4 shrink-0 text-muted-foreground transition-transform`,d&&`rotate-180`)})]}),d?(0,K.jsx)(Id,{projectId:e,currentBranch:t.branch,dirtyCount:h,className:G(`fixed inset-x-2 top-[7.75rem] max-h-[calc(100dvh-8.25rem)] w-auto overflow-y-auto md:absolute md:inset-x-auto md:left-auto md:right-0 md:top-full md:mt-2 md:max-h-none md:w-[min(340px,calc(100vw-1rem))] md:overflow-hidden lg:right-full lg:top-0 lg:mr-3 lg:mt-0`,l&&`md:fixed md:inset-x-2 md:right-auto md:top-[7.75rem] md:mt-0 md:max-h-[calc(100dvh-8.25rem)] md:w-auto md:overflow-y-auto lg:inset-x-2 lg:right-auto lg:top-[7.75rem] lg:mr-0`),openChangesClassName:G(`hidden md:flex`,l&&`md:hidden`),onCheckout:async e=>{await o(e),f(!1)},onCreated:e=>{s(e),f(!1)},onOpenGraph:()=>{f(!1),c()},onOpenChanges:()=>{f(!1),i()}}):null]}),(0,K.jsxs)(`button`,{type:`button`,className:`flex h-11 w-full items-center gap-3 rounded-2xl px-2.5 text-left text-foreground/88 transition-colors hover:bg-muted/45 hover:text-foreground`,onClick:a,children:[(0,K.jsx)(ne,{className:`size-4 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`font-medium`,children:W(`gitToolsCommitOrPush`)})]})]})]}):null]}):null}function Gd(e){let t=new Date(e);return Number.isNaN(t.getTime())?e:new Intl.DateTimeFormat(gt(),{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`}).format(t)}function Kd(e){return e.type===`head`?`border-amber-500 text-foreground`:e.type===`tag`?`border-emerald-600 text-emerald-700 dark:text-emerald-300`:e.type===`remote`?`border-border bg-muted/40 text-muted-foreground`:`border-border bg-muted/30 text-muted-foreground`}function qd({decoration:e}){return(0,K.jsxs)(`span`,{className:G(`inline-flex h-6 items-center gap-1 rounded-lg border px-2 text-xs`,Kd(e)),children:[e.type===`tag`?(0,K.jsx)(L,{className:`size-3`}):(0,K.jsx)(pe,{className:`size-3`}),(0,K.jsx)(`span`,{children:e.name})]})}function Jd({index:e,isLast:t}){return(0,K.jsxs)(`div`,{className:`relative flex h-full min-h-14 w-full justify-center`,"aria-hidden":`true`,children:[t?null:(0,K.jsx)(`div`,{className:`absolute left-1/2 top-0 h-full w-px -translate-x-1/2 bg-amber-500/20`}),e>0?(0,K.jsx)(`div`,{className:`absolute left-1/2 top-0 h-1/2 w-px -translate-x-1/2 bg-amber-500/20`}):null,(0,K.jsx)(`div`,{className:G(`relative z-10 mt-5 rounded-full border bg-background`,e===0?`size-3.5 border-2 border-amber-500/80`:`size-2.5 border-amber-500/65`)})]})}function Yd({projectId:e,projectName:t,onClose:n}){let[i,a]=(0,H.useState)([]),[o,s]=(0,H.useState)(!0),[c,l]=(0,H.useState)(),u=(0,H.useCallback)(async()=>{s(!0),l(void 0);try{a((await jd(e)).commits)}catch(e){l(e instanceof Error?e.message:W(`gitGraphFailed`))}finally{s(!1)}},[e]);(0,H.useEffect)(()=>{let e=window.setTimeout(()=>{u()},0);return()=>window.clearTimeout(e)},[u]),(0,H.useEffect)(()=>{let e=e=>{e.key===`Escape`&&n()};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[n]);let d=(0,H.useMemo)(()=>i,[i]);return(0,qr.createPortal)((0,K.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/45 p-6 backdrop-blur-sm`,onClick:e=>e.target===e.currentTarget?n():void 0,children:(0,K.jsxs)(`div`,{className:`flex h-[78vh] w-[86vw] max-w-[1500px] flex-col overflow-hidden rounded-2xl border border-border bg-background shadow-quickforge`,children:[(0,K.jsxs)(`div`,{className:`flex h-14 shrink-0 items-center gap-3 border-b-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-5`,children:[(0,K.jsx)(ge,{className:`size-5 text-muted-foreground`}),(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsx)(`div`,{className:`truncate text-base font-medium text-foreground`,children:W(`gitGraph`)}),(0,K.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,children:t})]}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:`size-8`,onClick:()=>void u(),"aria-label":W(`refresh`),disabled:o,children:o?(0,K.jsx)(B,{className:`size-4 animate-spin`}):(0,K.jsx)(r,{className:`size-4`})}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:`size-8`,onClick:n,"aria-label":W(`close`),children:(0,K.jsx)(z,{className:`size-4`})})]}),(0,K.jsxs)(`div`,{className:`grid shrink-0 grid-cols-[72px_minmax(360px,1fr)_160px_140px_120px] border-b-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] bg-muted/20 text-sm font-medium text-muted-foreground`,children:[(0,K.jsx)(`div`,{className:`border-r-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-5 py-3`,children:W(`graphColumn`)}),(0,K.jsx)(`div`,{className:`border-r-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-5 py-3`,children:W(`description`)}),(0,K.jsx)(`div`,{className:`border-r-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-5 py-3`,children:W(`date`)}),(0,K.jsx)(`div`,{className:`border-r-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-5 py-3`,children:W(`author`)}),(0,K.jsx)(`div`,{className:`px-5 py-3`,children:W(`commit`)})]}),(0,K.jsx)(`div`,{className:`min-h-0 flex-1 overflow-auto`,children:o?(0,K.jsxs)(`div`,{className:`flex h-full items-center justify-center gap-2 text-sm text-muted-foreground`,children:[(0,K.jsx)(B,{className:`size-4 animate-spin`}),(0,K.jsx)(`span`,{children:W(`loading`)})]}):c?(0,K.jsx)(`div`,{className:`m-5 rounded-2xl border border-border bg-muted/30 p-5 text-sm text-muted-foreground`,children:c}):d.length===0?(0,K.jsx)(`div`,{className:`m-5 rounded-2xl border border-border bg-muted/30 p-5 text-sm text-muted-foreground`,children:W(`noGitCommits`)}):d.map((e,t)=>(0,K.jsxs)(`div`,{className:G(`grid min-h-14 grid-cols-[72px_minmax(360px,1fr)_160px_140px_120px] border-b-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] text-sm`,e.decorations.some(e=>e.type===`head`||e.name===`HEAD`)?`bg-muted/28`:`bg-background`),children:[(0,K.jsx)(Jd,{index:t,isLast:t===d.length-1}),(0,K.jsx)(`div`,{className:`flex min-w-0 items-center gap-2 px-5 py-3`,children:(0,K.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[e.decorations.map(t=>(0,K.jsx)(qd,{decoration:t},`${e.hash}:${t.type}:${t.name}`)),(0,K.jsx)(`span`,{className:`min-w-0 break-words text-foreground/90`,children:e.subject})]})}),(0,K.jsx)(`div`,{className:`flex items-center border-l-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-5 py-3 text-muted-foreground`,children:Gd(e.date)}),(0,K.jsx)(`div`,{className:`flex min-w-0 items-center border-l-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-5 py-3 text-muted-foreground`,children:(0,K.jsx)(`span`,{className:`truncate`,children:e.author})}),(0,K.jsx)(`div`,{className:`flex items-center border-l-[0.5px] border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-5 py-3 font-mono text-muted-foreground`,children:e.shortHash})]},e.hash))})]})}),document.body)}async function Xd(e,t){let n=await fetch(e,{...t,cache:`no-store`,headers:{...t?.body?{"content-type":`application/json`}:void 0,...t?.headers}}),r=await n.json().catch(()=>null);if(!n.ok)throw Error(r?.error||`Request failed: ${n.status}`);return r}function Zd(e){if(typeof crypto<`u`&&typeof crypto.getRandomValues==`function`){let t=new Uint8Array(1);return crypto.getRandomValues(t),e[t[0]%e.length]}return e[Math.floor(Math.random()*e.length)]}function Qd(){let e=()=>Array.from({length:6},()=>Zd(`ABCDEFGHJKLMNPQRSTUVWXYZ23456789`)).join(``);return`${e()}-${e()}`}function $d(e=24){return new Date(Date.now()+e*60*60*1e3).toISOString()}async function ef(e){return Xd(`/api/shares`,{method:`POST`,body:JSON.stringify(e)})}async function tf(e){return Xd(`/api/shares${e?`?sessionId=${encodeURIComponent(e)}`:``}`)}async function nf(e){return Xd(`/api/shares/${encodeURIComponent(e)}`,{method:`DELETE`})}async function rf(e){return Xd(`/api/shares/${encodeURIComponent(e)}/disable`,{method:`POST`})}async function af(e,t){return Xd(`/api/shares/${encodeURIComponent(e)}/restore`,{method:`POST`,body:JSON.stringify({expiresAt:t})})}async function of(e,t){return Xd(`/api/shares/${encodeURIComponent(e)}/expiration`,{method:`POST`,body:JSON.stringify({expiresAt:t})})}async function sf(e,t){return Xd(`/api/shares/${encodeURIComponent(e)}/update`,{method:`POST`,body:JSON.stringify(t)})}async function cf(e){return Xd(`/api/shares/${encodeURIComponent(e)}/permanent`,{method:`DELETE`})}function lf(e){return e.revokedAt?`disabled`:e.expiresAt&&Date.parse(e.expiresAt)<=Date.now()?`expired`:`active`}async function uf(e){return Xd(`/api/shared/${encodeURIComponent(e)}/meta`)}async function df(e,t=``){return Xd(`/api/shared/${encodeURIComponent(e)}/unlock`,{method:`POST`,body:JSON.stringify({password:t})})}async function ff(e){return Xd(`/api/shared/${encodeURIComponent(e)}/models`)}function pf({open:e,sessionId:t,title:n,onOpenChange:i}){let a=(0,H.useId)(),[o,s]=(0,H.useState)(`read`),[c,l]=(0,H.useState)(``),[u,d]=(0,H.useState)(`24h`),[f,p]=(0,H.useState)(!1),[m,h]=(0,H.useState)(!1),[g,_]=(0,H.useState)(``),[v,y]=(0,H.useState)([]),[b,x]=(0,H.useState)(!1),[S,C]=(0,H.useState)(),w=(0,H.useMemo)(()=>{if(u!==`never`)return $d(u===`1h`?1:u===`7d`?168:24)},[u]);if((0,H.useEffect)(()=>{!e||!t||tf(t).then(e=>y(e.shares)).catch(e=>C(e instanceof Error?e.message:`Failed to load shares`))},[e,t]),!e)return null;let T=o===`operate`,E=!!t&&(o!==`operate`||f&&c.trim()),D=async()=>{if(!(!t||!E)){if(T&&!c.trim()){C(`可操作分享必须设置密码。`);return}x(!0),C(void 0);try{let e=await ef({sessionId:t,permission:o,password:c.trim(),expiresAt:w,allowCloudUsage:o===`operate`&&m});_(e.url),await Vc(e.url),p(!1),y((await tf(t)).shares)}catch(e){C(e instanceof Error?e.message:`Failed to create share`)}finally{x(!1)}}},O=async e=>{let t=e.url||`${window.location.origin}/share/${encodeURIComponent(e.id)}`;_(t),await Vc(t)},k=async e=>{try{await nf(e),y(t=>t.map(t=>t.id===e?{...t,revokedAt:new Date().toISOString()}:t))}catch(e){C(e instanceof Error?e.message:`Failed to revoke share`)}};return(0,K.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4`,onMouseDown:e=>{e.target===e.currentTarget&&i(!1)},children:(0,K.jsxs)(`div`,{className:`flex max-h-[90vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl border border-border bg-background shadow-quickforge`,onMouseDown:e=>e.stopPropagation(),children:[(0,K.jsxs)(`div`,{className:`shrink-0 border-b border-border px-5 py-4`,children:[(0,K.jsx)(`h2`,{className:`text-base font-semibold`,children:`分享到局域网`}),(0,K.jsxs)(`p`,{className:`mt-1 text-sm text-muted-foreground`,children:[`当前对话:`,n,`。同一个对话只会有一个固定分享链接;只读分享密码可选,可操作分享必须设置密码。`]})]}),(0,K.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-5 py-4`,children:(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`div`,{className:`mb-2 text-sm font-medium`,children:`权限`}),(0,K.jsxs)(`div`,{className:`grid gap-2 sm:grid-cols-2`,children:[(0,K.jsxs)(`button`,{type:`button`,className:`rounded-xl border p-3 text-left text-sm ${o===`read`?`border-primary bg-primary/10`:`border-border`}`,onClick:()=>s(`read`),children:[(0,K.jsx)(`div`,{className:`font-medium`,children:`仅阅读`}),(0,K.jsx)(`div`,{className:`mt-1 text-xs text-muted-foreground`,children:`只能查看这一个对话。`})]}),(0,K.jsxs)(`button`,{type:`button`,className:`rounded-xl border p-3 text-left text-sm ${o===`operate`?`border-red-400 bg-red-50 text-red-950`:`border-border`}`,onClick:()=>s(`operate`),children:[(0,K.jsx)(`div`,{className:`font-medium text-red-700`,children:`可操作(高危)`}),(0,K.jsx)(`div`,{className:`mt-1 text-xs text-red-700`,children:`允许对方操作这个原对话,禁止 Fork。`})]})]})]}),o===`operate`?(0,K.jsxs)(`div`,{className:`rounded-xl border border-red-300 bg-red-50 p-3 text-sm text-red-900`,children:[(0,K.jsxs)(`div`,{className:`flex gap-2 font-semibold`,children:[(0,K.jsx)(ce,{className:`mt-0.5 size-4`}),`高危可操作权限`]}),(0,K.jsx)(`p`,{className:`mt-2 text-xs leading-5`,children:`拥有链接和密码的人只能操作这一个原对话,但对方的消息、停止生成、回滚、模型/思考等级选择、YOLO 状态下可用工具等操作会按正常对话权限直接影响你的本机原对话。可操作分享必须设置密码。`}),(0,K.jsxs)(`label`,{className:`mt-3 flex items-center gap-2 text-xs font-medium`,children:[(0,K.jsx)(`input`,{type:`checkbox`,checked:f,onChange:e=>p(e.target.checked)}),`我已了解风险,仍然允许可操作权限。`]}),(0,K.jsxs)(`label`,{className:`mt-3 flex items-start gap-2 text-xs font-medium`,children:[(0,K.jsx)(`input`,{type:`checkbox`,checked:m,onChange:e=>h(e.target.checked)}),(0,K.jsx)(`span`,{children:`允许该分享使用我的 QuickForge Cloud 模型和额度。默认关闭。`})]})]}):null,(0,K.jsxs)(`div`,{className:`space-y-2`,children:[(0,K.jsx)(`label`,{htmlFor:a,className:`block text-sm font-medium`,children:T?`密码(可操作必填)`:`密码(可选)`}),(0,K.jsxs)(`div`,{className:`flex flex-col gap-3 sm:flex-row sm:items-center`,children:[(0,K.jsx)(`input`,{id:a,value:c,onChange:e=>l(e.target.value),className:`h-10 w-full min-w-0 rounded-md border border-input bg-background px-3 text-sm`,placeholder:T?`可操作分享必须设置密码`:`留空则打开链接无需密码`}),(0,K.jsxs)(q,{variant:`outline`,className:`h-10 sm:shrink-0`,onClick:()=>l(Qd()),children:[(0,K.jsx)(r,{className:`mr-2 size-4`}),`生成密码`]})]}),(0,K.jsx)(`span`,{className:`block text-xs text-muted-foreground`,children:T?`可操作分享必须设置非空密码;修改密码后旧密码和已解锁状态会失效。`:`留空保存会取消密码保护;填写新密码保存后旧密码和已解锁状态会失效。`})]}),(0,K.jsxs)(`label`,{className:`block text-sm font-medium`,children:[`有效期`,(0,K.jsxs)(`select`,{value:u,onChange:e=>d(e.target.value),className:`mt-2 h-10 w-full rounded-md border border-input bg-background px-3 text-sm`,children:[(0,K.jsx)(`option`,{value:`1h`,children:`1 小时`}),(0,K.jsx)(`option`,{value:`24h`,children:`24 小时`}),(0,K.jsx)(`option`,{value:`7d`,children:`7 天`}),(0,K.jsx)(`option`,{value:`never`,children:`永久,需手动撤销`})]})]}),g?(0,K.jsxs)(`div`,{className:`rounded-xl border border-emerald-300 bg-emerald-50 p-3 text-sm text-emerald-900`,children:[`已复制到剪切板。`,(0,K.jsx)(`pre`,{className:`mt-2 max-h-36 overflow-auto whitespace-pre-wrap text-xs`,children:g})]}):null,S?(0,K.jsx)(`div`,{className:`rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive`,children:S}):null,v.length?(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`div`,{className:`mb-2 text-sm font-medium`,children:`已有分享`}),(0,K.jsx)(`div`,{className:`space-y-2`,children:v.map(e=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 rounded-lg border border-border p-2 text-xs`,children:[(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsx)(`div`,{className:`truncate font-mono`,children:e.id}),(0,K.jsxs)(`div`,{className:`text-muted-foreground`,children:[e.permission===`operate`?`可操作`:`只读`,` · `,e.hasPassword?`有密码`:`无密码`,` · `,e.allowCloudUsage?`允许 Cloud`:`不允许 Cloud`,` · `,e.revokedAt?`已撤销`:e.expiresAt?`到期 ${new Date(e.expiresAt).toLocaleString()}`:`永久`]})]}),e.revokedAt?null:(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(q,{variant:`ghost`,size:`icon`,onClick:()=>void O(e),"aria-label":`复制分享链接`,title:`复制分享链接`,children:(0,K.jsx)(Ce,{className:`size-4`})}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:`text-destructive`,onClick:()=>void k(e.id),"aria-label":`撤销分享`,title:`撤销分享`,children:(0,K.jsx)(me,{className:`size-4`})})]})]},e.id))})]}):null]})}),(0,K.jsx)(`div`,{className:`shrink-0 border-t border-border px-5 py-4`,children:(0,K.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,K.jsx)(q,{variant:`outline`,onClick:()=>i(!1),children:W(`cancel`)}),(0,K.jsxs)(q,{variant:o===`operate`?`destructive`:`default`,disabled:!E||b,onClick:()=>void D(),title:o===`operate`&&!c.trim()?`可操作分享必须设置密码`:void 0,children:[(0,K.jsx)(Ce,{className:`mr-2 size-4`}),o===`operate`?`保存配置并复制高危可操作链接`:`保存配置并复制链接`]})]})})]})})}function mf(e){let t=e.replace(/\\/g,`/`);return t.split(`/`).filter(Boolean).pop()||t||`artifact`}function hf(e){let t=e.toLowerCase(),n=t.replace(/\\/g,`/`).split(`/`).pop()||t;return t.endsWith(`.html`)||t.endsWith(`.htm`)?`html`:/\.(svg|png|jpe?g|webp|gif|ico)$/i.test(t)?`image`:/\.(md|mdx|markdown)$/i.test(t)?`markdown`:n===`dockerfile`||n.endsWith(`.dockerfile`)||n===`makefile`||/\.(ts|tsx|js|jsx|mjs|cjs|css|scss|less|json|jsonc|txt|csv|tsv|log|sql|xml|yml|yaml|toml|ini|py|rb|go|rs|java|swift|kt|kts|c|h|cpp|hpp|cs|php|sh|bash|zsh|ps1)$/i.test(t)?`code`:`unknown`}function gf(e){return hf(e)!==`unknown`}var _f=/\.(svg|png|jpe?g|webp|gif|ico)$/i;function vf(e){return hf(e)===`html`||_f.test(e)}function yf(e,t=hf(e)){if(t===`markdown`||t===`code`)return`reader`;if((t===`html`||t===`image`)&&vf(e))return`browser`}function bf(e,t){let n=t.replace(/\\/g,`/`);return!e?.trim()||n.startsWith(`/`)||/^[a-zA-Z]:\//.test(n)?t:`${e.trim().replace(/\\/g,`/`).replace(/\/+$/,``)}/${n.replace(/^\/+/,``)}`}function xf(e,t,n){let r=t.replace(/\\/g,`/`),i=r.match(/^\/+/)?.[0]??``,a=i+r.slice(i.length).split(`/`).filter(Boolean).map(e=>encodeURIComponent(e)).join(`/`),o=`/api/workspace/preview/${encodeURIComponent(e)}/${a}`;return n?`${o}?r=${n}`:o}function Sf(e){return e.replace(/\\/g,`/`).toLowerCase()}function Cf(e){let t=mf(e.path).toLowerCase();return e.defaultPreview?0:e.explicit&&e.preview?1:e.explicit?2:t===`index.html`?3:e.kind===`html`?4:e.kind===`image`?5:e.kind===`markdown`?6:e.kind===`code`?7:20}function wf(e){let t=new Map;for(let n of e){if(!n.path)continue;let e=Sf(n.path),r=n.kind??hf(n.path),i=t.get(e),a=n.preview??gf(n.path),o=n.source===`present_files`||n.presentation===`explicit`;if(!i){t.set(e,{id:e,path:n.path,title:n.title,description:n.description,kind:r,preview:a,defaultPreview:!!n.defaultPreview,explicit:o,addedLines:n.addedLines,removedLines:n.removedLines,sources:[n.source],toolCallIds:n.toolCallId?[n.toolCallId]:[]});continue}i.preview=i.preview||a,i.defaultPreview=i.defaultPreview||!!n.defaultPreview,i.explicit=i.explicit||o,i.title=n.title||i.title,i.description=n.description||i.description,typeof n.addedLines==`number`&&(i.addedLines=(i.addedLines??0)+n.addedLines),typeof n.removedLines==`number`&&(i.removedLines=(i.removedLines??0)+n.removedLines),i.kind=i.kind===`unknown`?r:i.kind,i.sources.includes(n.source)||i.sources.push(n.source),n.toolCallId&&!i.toolCallIds.includes(n.toolCallId)&&i.toolCallIds.push(n.toolCallId)}return[...t.values()].sort((e,t)=>Cf(e)-Cf(t))}function Tf(e){let t=wf(e).filter(e=>e.preview&&e.explicit);if(t.length<=1)return t[0];let n=new Map;for(let t=0;t<e.length;t++){let r=e[t]?.toolCallId;r&&n.set(r,t)}let r=e=>{let t=e.toolCallIds,r=-1;for(let e of t){let t=n.get(e);typeof t==`number`&&t>r&&(r=t)}return r};return[...t].sort((e,t)=>r(t)-r(e))[0]}var Ef=`http://42.194.187.88:8080`,Df=`quickforge-mobile`,Of=`1.0.0`,kf=`手机 (Android)`,Af=`android`,jf=`urn:ietf:params:oauth:grant-type:device_code`,Mf=`refresh_token`,Nf=5,Pf=60,Ff=600*1e3,If=class extends Error{status;code;constructor(e,t=0,n=`cloud_remote_request_failed`){super(e),this.name=`CloudRemoteClientError`,this.status=t,this.code=n}};function Lf(e){return typeof e==`object`&&e?e:{}}function Rf(e){if(typeof e==`object`&&e){let t=e,n=t.error;if(typeof n==`string`)return{message:n,code:typeof t.code==`string`?t.code:`cloud_remote_request_failed`};if(typeof n==`object`&&n){let e=n;return{message:typeof e.message==`string`?e.message:`云服务请求失败`,code:typeof e.code==`string`?e.code:`cloud_remote_request_failed`}}}return{message:`云服务请求失败`,code:`cloud_remote_request_failed`}}function zf(){if(globalThis.crypto!==void 0&&typeof globalThis.crypto.randomUUID==`function`)return globalThis.crypto.randomUUID();let e=new Uint8Array(16);globalThis.crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}async function Bf(){if(globalThis.crypto===void 0||globalThis.crypto.subtle===void 0)throw new If(`当前设备不支持安全登录,请升级系统`,0,`cloud_remote_unsupported_crypto`);try{return await globalThis.crypto.subtle.generateKey({name:`Ed25519`},!0,[`sign`,`verify`])}catch{throw new If(`当前设备不支持安全登录,请升级系统`,0,`cloud_remote_unsupported_crypto`)}}async function Vf(e){let t=new Uint8Array(await globalThis.crypto.subtle.exportKey(`raw`,e)),n=``;for(let e of t)n+=String.fromCharCode(e);return btoa(n).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function Hf(e){return new Promise(t=>{setTimeout(t,e)})}async function Uf(e,t,n,r){let i={Accept:`application/json`,...n.body===void 0?{}:{"Content-Type":`application/json`},...r?{Authorization:`Bearer ${r}`}:{},...n.headers};if(Me!==void 0&&typeof Me.isNativePlatform==`function`&&Me.isNativePlatform()){let r=await je.request({url:`${e}${t}`,method:n.method??`GET`,headers:i,data:n.body,connectTimeout:15e3,readTimeout:3e4});if(r.status<200||r.status>=300){let e=Rf(r.data);throw new If(e.message,r.status,e.code)}return r.data}let a=await fetch(`${e}${t}`,{method:n.method??`GET`,headers:i,body:n.body===void 0?void 0:JSON.stringify(n.body),cache:`no-store`});if(!a.ok){let e={};try{e=await a.json()}catch{}let t=Rf(e);throw new If(t.message===`云服务请求失败`?`云服务请求失败 (${a.status})`:t.message,a.status,t.code)}return a.json()}var Wf=class{baseUrl;accessToken=``;refreshToken=``;refreshPromise=null;constructor(e){this.baseUrl=e.replace(/\/+$/,``)}get cloudUrl(){return this.baseUrl}clearTokens(){this.accessToken=``,this.refreshToken=``}async deviceAuthorization(){let e=zf(),t=await Bf(),n=await Vf(t.publicKey),r=Lf(await this.request(`POST`,`/oauth/device_authorization`,{installationId:e,clientId:Df,publicKey:n,installationName:kf,platform:Af,clientVersion:Of})),i=r.deviceCode,a=r.userCode;if(typeof i!=`string`||i===``||typeof a!=`string`||a===``)throw new If(`无法获取设备授权码,请稍后重试`,0,`cloud_remote_request_failed`);return{deviceCode:i,userCode:a,interval:typeof r.interval==`number`&&r.interval>0?r.interval:Nf,privateKey:t.privateKey}}async login(e,t,n=``){let r=await this.request(`POST`,`/v1/accounts/login`,{userCode:n,email:e,password:t});return this.consumeSession(r)}async register(e,t,n=``){let r=await this.request(`POST`,`/v1/accounts/register`,{userCode:n,email:e,password:t});return this.consumeSession(r)}async pollDeviceToken(e,t){let n=t>0?t:Nf,r=Date.now()+Ff;for(;;){if(Date.now()>r)throw new If(`登录超时,请重新发起登录`,0,`device_flow_timeout`);try{let t=await this.request(`POST`,`/oauth/token`,{grantType:jf,deviceCode:e,clientId:Df}),n=this.parseTokenSet(t);return this.accessToken=n.accessToken,this.refreshToken=n.refreshToken,n}catch(e){if(!(e instanceof If)||e.status!==400)throw e;if(e.code!==`authorization_pending`)if(e.code===`slow_down`)n=Math.min(n+5,Pf);else if(e.code===`expired_token`)throw new If(`设备授权已过期,请重新发起登录`,400,`expired_token`);else if(e.code===`access_denied`)throw new If(`设备授权已被拒绝`,400,`access_denied`);else if(e.code===`invalid_grant`)throw new If(`授权请求无效,请重新登录`,400,`invalid_grant`);else throw e;await Hf(n*1e3)}}}refresh(){return this.refreshPromise||=this.doRefresh().finally(()=>{this.refreshPromise=null}),this.refreshPromise}async doRefresh(){if(this.refreshToken===``)throw new If(`登录已过期,请重新登录`,0,`auth_expired`);let e=await this.request(`POST`,`/oauth/token`,{grantType:Mf,refreshToken:this.refreshToken,clientId:Df}),t=this.parseTokenSet(e);return this.accessToken=t.accessToken,t.refreshToken!==``&&(this.refreshToken=t.refreshToken),t}async getMe(){let e=Lf(await this.request(`GET`,`/v1/me`,void 0,!0)),t=Lf(e.account??e);return{id:typeof t.id==`string`?t.id:``,email:typeof t.email==`string`?t.email:``,mode:typeof t.mode==`string`?t.mode:void 0,plan:typeof t.plan==`string`?t.plan:void 0}}async listDevices(){let e=Lf(await this.request(`GET`,`/v1/remote/devices`,void 0,!0)).items;return Array.isArray(e)?{items:e.map(e=>{let t=Lf(e),n=Array.isArray(t.services)?t.services.map(e=>{let t=Lf(e);return{id:typeof t.id==`number`?t.id:0,name:typeof t.name==`string`?t.name:``,port:typeof t.port==`number`?t.port:0,protocol:typeof t.protocol==`string`?t.protocol:``}}):void 0;return{installationId:typeof t.installationId==`string`?t.installationId:typeof t.id==`string`?t.id:``,name:typeof t.name==`string`?t.name:void 0,online:t.online===!0,services:n}})}:{items:[]}}async turnCredentials(){let e=Lf(await this.request(`POST`,`/v1/remote/turn-credentials`,void 0,!0));return{urls:Array.isArray(e.urls)?e.urls.filter(e=>typeof e==`string`):[],username:typeof e.username==`string`?e.username:``,credential:typeof e.credential==`string`?e.credential:``,ttl:typeof e.ttl==`number`?e.ttl:0}}async request(e,t,n,r=!1){try{return await Uf(this.baseUrl,t,{method:e,body:n},r&&this.accessToken||void 0)}catch(i){if(r&&i instanceof If&&i.status===401){try{await this.refresh()}catch{throw new If(`登录已过期,请重新登录`,0,`auth_expired`)}return Uf(this.baseUrl,t,{method:e,body:n},this.accessToken||void 0)}throw i instanceof If?i:new If(`无法连接云服务,请检查网络或云服务地址`,0,`network_error`)}}parseTokenSet(e){let t=Lf(e),n=t.access_token??t.accessToken,r=t.refresh_token??t.refreshToken;if(typeof n!=`string`||n===``)throw new If(`云服务返回了无效的令牌`,0,`cloud_remote_request_failed`);let i=t.token_type??t.tokenType,a=t.expires_in??t.expiresIn,o=t.refresh_token_expires_in??t.refreshTokenExpiresIn,s=t.installation_id??t.installationId,c=t.identity_mode??t.identityMode;return{accessToken:n,refreshToken:typeof r==`string`?r:``,tokenType:typeof i==`string`?i:`Bearer`,expiresIn:typeof a==`number`?a:0,refreshTokenExpiresIn:typeof o==`number`?o:0,installationId:typeof s==`string`?s:``,identityMode:typeof c==`string`?c:``}}consumeSession(e){let t=Lf(e),n=typeof t.token==`object`&&t.token!==null?t.token:t,r=n.access_token??n.accessToken,i=n.refresh_token??n.refreshToken,a=Lf(t.account??t.user),o=Object.keys(a).length>0?{id:typeof a.id==`string`?a.id:``,email:typeof a.email==`string`?a.email:``,mode:typeof a.mode==`string`?a.mode:void 0,plan:typeof a.plan==`string`?a.plan:void 0}:void 0;if(typeof r==`string`&&r!==``&&typeof i==`string`&&i!==``){let e=n.expires_in??n.expiresIn;return this.accessToken=r,this.refreshToken=i,{accessToken:r,refreshToken:i,expiresIn:typeof e==`number`?e:void 0,account:o,bound:!0}}return{accessToken:``,refreshToken:``,account:o,bound:!0}}},Gf=Ae(`RemoteTunnel`),Kf=`http://127.0.0.1:18080/?quickforgeRemote=1`,qf=`http://127.0.0.1:18080/`;async function Jf(){for(let e=0;e<3;e++){let t=new AbortController,n=window.setTimeout(()=>t.abort(),3e3);try{await fetch(qf,{mode:`no-cors`,cache:`no-store`,signal:t.signal}),window.clearTimeout(n),window.location.href=Kf;return}catch{window.clearTimeout(n),e<2&&await new Promise(e=>setTimeout(e,700))}}throw Error(`本地隧道端口未就绪,请断开后重试`)}function Yf(e){return e instanceof If?e.message||`云服务请求失败,请稍后重试`:e instanceof Error?e.message:`操作失败,请稍后重试`}function Xf(e){return e instanceof If?e.code===`cloud_remote_unsupported_crypto`||e.code===`access_denied`||e.code===`expired_token`||e.code===`device_flow_timeout`?e.message||`设备授权未完成,请重新尝试`:e.status===0?`无法连接云服务,请检查“云服务地址”与网络后重试`:e.message||`云服务请求失败,请稍后重试`:`无法连接云服务,请检查“云服务地址”与网络后重试`}function Zf(e){return e.name?.trim()||e.installationId}function Qf({onSessionChange:e}){let[t,n]=(0,H.useState)(`checking`),[i,a]=(0,H.useState)(`login`),[o,s]=(0,H.useState)(``),[l,d]=(0,H.useState)(``),[f,p]=(0,H.useState)(``),[m,h]=(0,H.useState)(!1),[g,_]=(0,H.useState)(Ef),[v,b]=(0,H.useState)(!1),[x,S]=(0,H.useState)(``),[C,w]=(0,H.useState)(``),[T,E]=(0,H.useState)(!1),[D,te]=(0,H.useState)(null),[A,j]=(0,H.useState)([]),[ne,re]=(0,H.useState)(null),[M,N]=(0,H.useState)(null),[P,ie]=(0,H.useState)(null),F=(0,H.useRef)(null),ae=()=>((!F.current||F.current.cloudUrl!==g.replace(/\/+$/,``))&&(F.current=new Wf(g)),F.current);(0,H.useEffect)(()=>{let e=!0;return Gf.addListener(`remoteStateChanged`,t=>{e&&(N(t),t.state===`connected`?Jf().catch(t=>{e&&(re(null),N({state:`error`,error:Yf(t)}),S(Yf(t)),Gf.disconnect().catch(()=>{}))}):t.state===`reconnecting`?(re(null),N(t)):t.state===`error`&&(re(null),S(t.error||`隧道连接失败,请重试`)))}).catch(()=>{}),()=>{e=!1}},[]);let I=async()=>{E(!0),S(``);try{j((await Gf.listDevices()).items??[]),n(`devices`)}catch{try{j((await ae().listDevices()).items),n(`devices`)}catch(e){S(Yf(e)),n(`sign-in`)}}finally{E(!1)}};(0,H.useEffect)(()=>{let t=!0;return(async()=>{try{let r=await Gf.hasSession();if(!t)return;ie(r),e?.(r);let i=r.cloudUrl;i&&_(e=>e===`http://42.194.187.88:8080`?i:e),n(r.signedIn?`session-choice`:`sign-in`)}catch{t&&n(`sign-in`)}})(),()=>{t=!1}},[e]);let L=async()=>{te(`continue`);try{await I()}finally{te(null)}},R=async()=>{E(!0),te(`switch`),S(``),w(``);try{await Gf.disconnect().catch(()=>{}),await Gf.signOut(),ae().clearTokens(),j([]),re(null),N(null),d(``),n(`sign-in`),e?.({signedIn:!1})}catch(e){S(Yf(e))}finally{te(null),E(!1)}},oe=async t=>{t.preventDefault();let n=o.trim(),r=f.trim();if(!n||!l){S(`请输入邮箱和密码`);return}E(!0),S(``),w(``);try{let t=ae();if(r){let a=i===`register`?await t.register(n,l,r):await t.login(n,l,r);a.accessToken&&a.refreshToken?(await Gf.setToken({accessToken:a.accessToken,refreshToken:a.refreshToken,cloudUrl:t.cloudUrl,email:n}),ie({signedIn:!0,email:n,cloudUrl:t.cloudUrl}),e?.({signedIn:!0,email:n,cloudUrl:t.cloudUrl}),await I()):w(`已在电脑端完成设备授权;若电脑端 QuickForge 正在等待授权,请返回电脑端确认。`);return}let a=await t.deviceAuthorization();await(i===`register`?t.register(n,l,a.userCode):t.login(n,l,a.userCode));let o=await t.pollDeviceToken(a.deviceCode,a.interval);await Gf.setToken({accessToken:o.accessToken,refreshToken:o.refreshToken,cloudUrl:t.cloudUrl,email:n}),ie({signedIn:!0,email:n,cloudUrl:t.cloudUrl}),e?.({signedIn:!0,email:n,cloudUrl:t.cloudUrl}),await I()}catch(e){S(Xf(e))}finally{E(!1)}},z=async e=>{S(``),re(e.installationId),N({state:`connecting`});try{(await Gf.getState()).state!==`idle`&&await Gf.disconnect().catch(()=>{}),await Gf.connect({installationId:e.installationId})}catch(e){re(null),S(Yf(e))}},se=async()=>{E(!0),S(``),w(``);try{await Gf.disconnect().catch(()=>{}),await Gf.signOut()}catch(e){S(Yf(e))}finally{ae().clearTokens(),j([]),re(null),N(null),d(``),n(`sign-in`),E(!1),e?.({signedIn:!1})}};return t===`checking`?(0,K.jsxs)(`main`,{className:`flex min-h-dvh flex-col items-center justify-center bg-background px-8 pb-[max(2rem,env(safe-area-inset-bottom))] pt-[max(2rem,env(safe-area-inset-top))] text-foreground`,role:`status`,"aria-live":`polite`,children:[(0,K.jsx)(B,{className:`size-7 animate-spin text-muted-foreground`,"aria-hidden":`true`}),(0,K.jsx)(`p`,{className:`mt-4 text-sm text-muted-foreground`,children:`正在检查云账户状态…`})]}):t===`session-choice`?(0,K.jsxs)(`section`,{"aria-labelledby":`quickforge-cloud-remote-session-choice`,children:[(0,K.jsxs)(`header`,{className:`mb-6 flex items-start gap-3.5`,children:[(0,K.jsx)(`div`,{className:`flex size-11 shrink-0 items-center justify-center rounded-xl border border-border bg-background shadow-quickforge`,children:(0,K.jsx)(xe,{className:`size-5 text-foreground/75`,"aria-hidden":`true`})}),(0,K.jsxs)(`div`,{className:`min-w-0 pt-0.5`,children:[(0,K.jsx)(`h1`,{id:`quickforge-cloud-remote-session-choice`,className:`text-lg font-semibold tracking-tight`,children:`云账户远程访问`}),(0,K.jsx)(`p`,{className:`mt-1 text-sm leading-5 text-muted-foreground`,children:`检测到此设备已登录。选择是否继续当前会话。`})]})]}),(0,K.jsxs)(`div`,{className:`rounded-2xl border border-border bg-background p-4 shadow-quickforge`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`p`,{className:`truncate text-base font-semibold text-foreground`,children:P?.email||`已登录账号`}),(0,K.jsx)(`span`,{className:`shrink-0 rounded-full bg-emerald-500/10 px-2 py-0.5 text-[11px] font-medium text-emerald-600`,children:`会话有效`})]}),P?.cloudUrl?(0,K.jsx)(`p`,{className:`mt-1 truncate font-mono text-xs text-muted-foreground`,children:P.cloudUrl}):null]}),(0,K.jsxs)(`div`,{className:`mt-4 rounded-2xl border border-border bg-background p-5 shadow-quickforge`,children:[(0,K.jsxs)(`div`,{className:`flex gap-2.5 rounded-xl bg-muted/30 px-3 py-2.5 text-xs leading-5 text-muted-foreground`,children:[(0,K.jsx)(ue,{className:`mt-0.5 size-4 shrink-0`,"aria-hidden":`true`}),(0,K.jsx)(`p`,{children:`继续后才会加载当前账户的在线设备;也可以清理本机会话并重新登录。`})]}),x?(0,K.jsx)(`p`,{className:`mt-4 text-sm text-destructive`,role:`alert`,children:x}):null,(0,K.jsxs)(`button`,{type:`button`,className:`mt-5 inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-92 active:opacity-85 disabled:opacity-60`,onClick:()=>{L()},disabled:T,children:[D===`continue`?(0,K.jsx)(B,{className:`size-4 animate-spin`,"aria-hidden":`true`}):(0,K.jsx)(xe,{className:`size-4`,"aria-hidden":`true`}),`继续当前登录`]}),(0,K.jsxs)(`button`,{type:`button`,className:`mt-3 inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl border border-border text-sm font-medium text-foreground/80 transition-colors hover:bg-muted/45 hover:text-foreground active:bg-muted/65 disabled:opacity-60`,onClick:()=>{R()},disabled:T,children:[D===`switch`?(0,K.jsx)(B,{className:`size-4 animate-spin`,"aria-hidden":`true`}):(0,K.jsx)(u,{className:`size-4`,"aria-hidden":`true`}),`使用其他账号`]}),T?(0,K.jsx)(`p`,{className:`mt-2 text-center text-xs text-muted-foreground`,role:`status`,"aria-live":`polite`,children:D===`switch`?`正在清理当前登录…`:`正在加载设备…`}):null]})]}):t===`devices`?(0,K.jsxs)(`section`,{"aria-labelledby":`quickforge-cloud-remote-devices`,children:[(0,K.jsxs)(`header`,{className:`mb-6 flex items-start gap-3.5`,children:[(0,K.jsx)(`div`,{className:`flex size-11 shrink-0 items-center justify-center rounded-xl border border-border bg-background shadow-quickforge`,children:(0,K.jsx)(xe,{className:`size-5 text-foreground/75`,"aria-hidden":`true`})}),(0,K.jsxs)(`div`,{className:`min-w-0 flex-1 pt-0.5`,children:[(0,K.jsx)(`h1`,{id:`quickforge-cloud-remote-devices`,className:`text-lg font-semibold tracking-tight`,children:`云账户远程访问`}),(0,K.jsx)(`p`,{className:`mt-1 text-sm leading-5 text-muted-foreground`,children:`选择一台在线设备建立远程连接。`})]}),(0,K.jsx)(`button`,{type:`button`,className:`inline-flex size-10 shrink-0 items-center justify-center rounded-xl text-muted-foreground transition-colors hover:bg-muted/45 hover:text-foreground active:bg-muted/65`,onClick:()=>{I()},disabled:T,title:`刷新设备列表`,"aria-label":`刷新设备列表`,children:(0,K.jsx)(r,{className:`size-4 ${T?`animate-spin`:``}`,"aria-hidden":`true`})})]}),(0,K.jsxs)(`div`,{className:`mb-4 flex items-center justify-between gap-3 rounded-2xl border border-border bg-background p-4 shadow-quickforge`,children:[(0,K.jsxs)(`div`,{className:`min-w-0`,children:[(0,K.jsx)(`p`,{className:`text-xs font-medium text-muted-foreground`,children:`当前账号`}),(0,K.jsx)(`p`,{className:`mt-0.5 truncate text-sm font-medium text-foreground`,children:P?.email||`已登录账号`}),P?.cloudUrl?(0,K.jsx)(`p`,{className:`mt-0.5 truncate font-mono text-xs text-muted-foreground`,children:P.cloudUrl}):null]}),(0,K.jsxs)(`button`,{type:`button`,className:`inline-flex h-11 shrink-0 items-center justify-center gap-2 rounded-xl border border-border px-4 text-sm font-medium text-foreground/80 transition-colors hover:bg-muted/45 hover:text-foreground active:bg-muted/65 disabled:opacity-60`,onClick:()=>{R()},disabled:T,children:[D===`switch`?(0,K.jsx)(B,{className:`size-4 animate-spin`,"aria-hidden":`true`}):(0,K.jsx)(r,{className:`size-4`,"aria-hidden":`true`}),`切换账号`]})]}),x?(0,K.jsx)(`p`,{className:`mb-4 text-sm text-destructive`,role:`alert`,children:x}):null,C?(0,K.jsx)(`p`,{className:`mb-4 text-sm text-muted-foreground`,role:`status`,children:C}):null,M&&M.state!==`idle`?(0,K.jsxs)(`div`,{className:`mb-4`,children:[(0,K.jsxs)(`p`,{className:`flex items-center gap-2 text-sm text-muted-foreground`,role:`status`,"aria-live":`polite`,children:[M.state===`connecting`||M.state===`reconnecting`?(0,K.jsx)(B,{className:`size-4 animate-spin`,"aria-hidden":`true`}):(0,K.jsx)(fe,{className:`size-4`,"aria-hidden":`true`}),M.state===`connecting`?`正在建立加密隧道…`:M.state===`reconnecting`?`连接中断,正在自动重连…`:M.state===`connected`?`隧道已就绪,正在打开远程界面…`:`连接已断开`]}),M.state===`connected`||M.state===`reconnecting`?(0,K.jsxs)(`p`,{className:`mt-2 flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,K.jsx)(ue,{className:`size-3.5 shrink-0`,"aria-hidden":`true`}),`断线自动重连已开启,网络恢复后自动恢复连接`]}):null]}):null,(0,K.jsx)(`div`,{className:`overflow-hidden rounded-2xl border border-border bg-background`,children:A.length===0?(0,K.jsxs)(`div`,{className:`px-5 py-10 text-center`,children:[(0,K.jsx)(c,{className:`mx-auto size-8 text-muted-foreground/50`,"aria-hidden":`true`}),(0,K.jsx)(`p`,{className:`mt-3 text-sm text-muted-foreground`,children:`没有可用的在线设备`}),(0,K.jsx)(`p`,{className:`mt-1 text-xs leading-5 text-muted-foreground/75`,children:`请确认电脑端 QuickForge 的云远程代理(agent)已登录并在线。`})]}):A.map(e=>{let t=ne===e.installationId;return(0,K.jsx)(`div`,{className:`border-b border-border last:border-b-0`,children:(0,K.jsxs)(`button`,{type:`button`,className:`flex min-h-[68px] w-full items-center gap-3 p-3 text-left transition-colors hover:bg-muted/45 active:bg-muted/65 disabled:opacity-60`,onClick:()=>{z(e)},disabled:T||ne!==null||e.online===!1,title:e.online===!1?`设备当前离线`:`连接 ${Zf(e)}`,children:[(0,K.jsx)(`span`,{className:`flex size-9 shrink-0 items-center justify-center rounded-xl bg-muted/45 text-muted-foreground`,children:(0,K.jsx)(ee,{className:`size-4`,"aria-hidden":`true`})}),(0,K.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,K.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`span`,{className:`truncate text-sm font-medium text-foreground`,children:Zf(e)}),(0,K.jsx)(`span`,{className:`shrink-0 rounded-full px-2 py-0.5 text-[11px] font-medium ${e.online===!1?`bg-muted text-muted-foreground`:`bg-emerald-500/10 text-emerald-600`}`,children:e.online===!1?`离线`:`在线`})]}),(0,K.jsx)(`span`,{className:`mt-1 block truncate font-mono text-xs text-muted-foreground`,children:e.installationId})]}),t?(0,K.jsx)(B,{className:`size-4 shrink-0 animate-spin text-muted-foreground`,"aria-hidden":`true`}):(0,K.jsx)(y,{className:`size-4 shrink-0 -rotate-90 text-muted-foreground/65`,"aria-hidden":`true`})]})},e.installationId)})}),(0,K.jsxs)(`button`,{type:`button`,className:`mt-6 inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl border border-border text-sm font-medium text-foreground/80 transition-colors hover:bg-muted/45 hover:text-foreground active:bg-muted/65 disabled:opacity-60`,onClick:()=>{se()},disabled:T,children:[(0,K.jsx)(u,{className:`size-4`,"aria-hidden":`true`}),`退出登录`]})]}):(0,K.jsxs)(`section`,{"aria-labelledby":`quickforge-cloud-remote-signin`,children:[(0,K.jsxs)(`header`,{className:`mb-6 flex items-start gap-3.5`,children:[(0,K.jsx)(`div`,{className:`flex size-11 shrink-0 items-center justify-center rounded-xl border border-border bg-background shadow-quickforge`,children:(0,K.jsx)(xe,{className:`size-5 text-foreground/75`,"aria-hidden":`true`})}),(0,K.jsxs)(`div`,{className:`min-w-0 pt-0.5`,children:[(0,K.jsx)(`h1`,{id:`quickforge-cloud-remote-signin`,className:`text-lg font-semibold tracking-tight`,children:`云账户远程访问`}),(0,K.jsx)(`p`,{className:`mt-1 text-sm leading-5 text-muted-foreground`,children:`通过云账户加密隧道访问家中电脑:输入邮箱密码即可登录,手机自动完成设备授权。`})]})]}),(0,K.jsxs)(`form`,{className:`rounded-2xl border border-border bg-background p-5 shadow-quickforge`,onSubmit:oe,children:[(0,K.jsxs)(`div`,{className:`mb-5 grid grid-cols-2 gap-1 rounded-xl bg-muted/40 p-1`,role:`tablist`,"aria-label":`登录或注册`,children:[(0,K.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":i===`login`,className:`rounded-lg py-2 text-sm font-medium transition-colors ${i===`login`?`bg-background text-foreground shadow-sm`:`text-muted-foreground hover:text-foreground`}`,onClick:()=>{a(`login`),S(``),w(``)},children:`登录`}),(0,K.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":i===`register`,className:`rounded-lg py-2 text-sm font-medium transition-colors ${i===`register`?`bg-background text-foreground shadow-sm`:`text-muted-foreground hover:text-foreground`}`,onClick:()=>{a(`register`),S(``),w(``)},children:`注册`})]}),(0,K.jsxs)(`div`,{className:`mb-5 flex gap-2.5 rounded-xl bg-muted/30 px-3 py-2.5 text-xs leading-5 text-muted-foreground`,children:[(0,K.jsx)(ue,{className:`mt-0.5 size-4 shrink-0`,"aria-hidden":`true`}),(0,K.jsx)(`p`,{children:`直连云 API(原生通道绕 CORS)。令牌仅存于内存,刷新令牌由系统安全存储保护。`})]}),(0,K.jsx)(`label`,{className:`block text-sm font-medium`,htmlFor:`quickforge-cloud-remote-email`,children:`邮箱`}),(0,K.jsx)(`input`,{id:`quickforge-cloud-remote-email`,type:`email`,autoCapitalize:`none`,autoCorrect:`off`,spellCheck:!1,autoComplete:`email`,value:o,onChange:e=>{s(e.target.value),S(``),w(``)},placeholder:`you@example.com`,className:`mt-2 h-11 w-full rounded-xl border border-input bg-background px-3.5 text-sm outline-none transition-[border-color,box-shadow] placeholder:text-muted-foreground/60 focus:border-foreground/30 focus:shadow-quickforge`}),(0,K.jsx)(`label`,{className:`mt-4 block text-sm font-medium`,htmlFor:`quickforge-cloud-remote-password`,children:`密码`}),(0,K.jsx)(`input`,{id:`quickforge-cloud-remote-password`,type:`password`,autoComplete:i===`register`?`new-password`:`current-password`,value:l,onChange:e=>{d(e.target.value),S(``),w(``)},placeholder:i===`register`?`至少 8 个字符`:`输入密码`,className:`mt-2 h-11 w-full rounded-xl border border-input bg-background px-3.5 text-sm outline-none transition-[border-color,box-shadow] placeholder:text-muted-foreground/60 focus:border-foreground/30 focus:shadow-quickforge`}),(0,K.jsxs)(`button`,{type:`button`,className:`mt-4 flex w-full items-center justify-between rounded-xl px-1 py-2 text-sm text-muted-foreground transition-colors hover:text-foreground`,onClick:()=>h(e=>!e),"aria-expanded":m,children:[(0,K.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(k,{className:`size-4`,"aria-hidden":`true`}),`设备验证码`,(0,K.jsx)(`span`,{className:`text-xs text-muted-foreground/70`,children:`(高级)`})]}),(0,K.jsx)(y,{className:`size-4 transition-transform ${m?`rotate-180`:``}`,"aria-hidden":`true`})]}),m?(0,K.jsxs)(`div`,{className:`mt-1 rounded-xl bg-muted/30 px-3 py-2.5`,children:[(0,K.jsx)(`input`,{id:`quickforge-cloud-remote-usercode`,autoCapitalize:`characters`,autoCorrect:`off`,spellCheck:!1,value:f,onChange:e=>{p(e.target.value),S(``),w(``)},placeholder:`ABCD-2345`,className:`h-10 w-full rounded-lg border border-input bg-background px-3 font-mono text-sm tracking-widest outline-none transition-[border-color,box-shadow] placeholder:text-muted-foreground/50 focus:border-foreground/30 focus:shadow-quickforge`}),(0,K.jsx)(`p`,{className:`mt-2 text-xs leading-5 text-muted-foreground`,children:`电脑端 QuickForge 已发起“云远程访问”授权时,可填写电脑端显示的验证码直接批准;通常无需填写。`})]}):null,(0,K.jsxs)(`button`,{type:`button`,className:`mt-2 flex w-full items-center justify-between rounded-xl px-1 py-2 text-sm text-muted-foreground transition-colors hover:text-foreground`,onClick:()=>b(e=>!e),"aria-expanded":v,children:[(0,K.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(xe,{className:`size-4`,"aria-hidden":`true`}),`云服务地址`]}),(0,K.jsx)(y,{className:`size-4 transition-transform ${v?`rotate-180`:``}`,"aria-hidden":`true`})]}),v?(0,K.jsxs)(`div`,{className:`mt-1 rounded-xl bg-muted/30 px-3 py-2.5`,children:[(0,K.jsx)(`input`,{id:`quickforge-cloud-remote-baseurl`,autoCapitalize:`none`,autoCorrect:`off`,inputMode:`url`,spellCheck:!1,value:g,onChange:e=>{_(e.target.value),S(``),w(``)},placeholder:`https://cloud.quickforge.app`,className:`h-10 w-full rounded-lg border border-input bg-background px-3 font-mono text-sm outline-none transition-[border-color,box-shadow] placeholder:text-muted-foreground/50 focus:border-foreground/30 focus:shadow-quickforge`}),(0,K.jsx)(`p`,{className:`mt-2 text-xs leading-5 text-muted-foreground`,children:`正式域名确定前的占位地址;仅在本次会话内生效,不持久化。`})]}):null,x?(0,K.jsx)(`p`,{className:`mt-3 text-sm text-destructive`,role:`alert`,children:x}):null,C?(0,K.jsx)(`p`,{className:`mt-3 text-sm text-muted-foreground`,role:`status`,children:C}):null,(0,K.jsxs)(`button`,{type:`submit`,className:`mt-5 inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-92 active:opacity-85 disabled:opacity-60`,disabled:T,children:[T?(0,K.jsx)(B,{className:`size-4 animate-spin`,"aria-hidden":`true`}):(0,K.jsx)(O,{className:`size-4`,"aria-hidden":`true`}),i===`register`?`注册并授权`:`登录`]}),T?(0,K.jsx)(`p`,{className:`mt-2 text-center text-xs text-muted-foreground`,role:`status`,children:`正在发起安全登录…`}):null]}),(0,K.jsxs)(`p`,{className:`mt-4 px-1 text-xs leading-5 text-muted-foreground/80`,children:[`连接成功后将在本机 `,(0,K.jsx)(`span`,{className:`font-mono text-foreground/70`,children:`127.0.0.1:18080`}),` 打开远程 QuickForge 界面;远程会话沿用与 Tailscale 相同的安全裁剪(终端、系统代理等不可用)。`]})]})}var $f=800;function ep(){let e=(0,H.useMemo)(()=>Rt(),[]),[t,n]=(0,H.useState)(e),[r,i]=(0,H.useState)(null),[a,s]=(0,H.useState)(e.urls.length===0),[c,l]=(0,H.useState)(``),[u,d]=(0,H.useState)(``),[f,p]=(0,H.useState)(``),[m,h]=(0,H.useState)(!1),[g,_]=(0,H.useState)(null),[v,y]=(0,H.useState)(null),[b,x]=(0,H.useState)(``),[C,w]=(0,H.useState)(null),[T,D]=(0,H.useState)(()=>new URLSearchParams(location.search).get(`tab`)===`servers`?`servers`:`cloud`),[O,k]=(0,H.useState)({signedIn:!1});(0,H.useEffect)(()=>{if(!r)return;let e=window.setTimeout(()=>{window.location.assign(Vt(r))},$f);return()=>window.clearTimeout(e)},[r]),(0,H.useEffect)(()=>{let e=!0;return Gf.hasSession().then(t=>{e&&k(t)}).catch(()=>{}),()=>{e=!1}},[]);let te=(0,H.useMemo)(()=>{if(!c.trim())return``;try{return Ft(c)}catch{return``}},[c]),A=e=>{zt(e),n(e)},j=()=>{l(``),d(``),p(``)},ne=()=>{j(),h(!1),_(null),y(null),s(!0)},re=e=>{try{let n=Ft(c),r=t.urls.includes(n)?t.urls:[...t.urls,n],a=u.trim(),o={...t.aliases??{}};a&&(o[n]=a),A({urls:r,aliases:o,lastUsedUrl:e?n:t.lastUsedUrl||n}),j(),h(!0),e?i(n):s(!1)}catch(e){h(!1),p(e instanceof Error?e.message:`无法保存 QuickForge 服务地址`)}},M=e=>{e.preventDefault(),re(!0)},N=e=>{try{A({...t,lastUsedUrl:e}),i(e)}catch(e){p(e instanceof Error?e.message:`无法连接到 QuickForge 服务`)}},P=e=>{try{let n=t.urls.filter(t=>t!==e),r={...t.aliases??{}};delete r[e],A({urls:n,aliases:r,lastUsedUrl:t.lastUsedUrl===e?n[0]||``:t.lastUsedUrl}),_(null),w(null),v===e&&(y(null),x(``)),n.length===0&&s(!0),p(``),h(!1)}catch(e){w(null),p(e instanceof Error?e.message:`无法删除服务器地址`)}},ie=e=>{y(e),x(t.aliases?.[e]??``)},I=()=>{y(null),x(``)},L=e=>{let n=b.trim(),r={...t.aliases??{}};n?r[e]=n:delete r[e],A({...t,aliases:r}),I(),_(null)},R=C?t.aliases?.[C]?.trim()||C:``;if(r){let e=t.aliases?.[r]?.trim()||r;return(0,K.jsxs)(`main`,{className:`flex min-h-dvh flex-col items-center justify-center bg-background px-8 pb-[max(2rem,env(safe-area-inset-bottom))] pt-[max(2rem,env(safe-area-inset-top))] text-foreground`,role:`status`,"aria-live":`polite`,children:[(0,K.jsxs)(`div`,{className:`relative flex size-24 items-center justify-center`,"aria-hidden":`true`,children:[(0,K.jsx)(`span`,{className:`absolute inset-0 animate-ping rounded-full bg-primary/15`}),(0,K.jsx)(`span`,{className:`absolute inset-0 animate-ping rounded-full bg-primary/10 [animation-delay:0.45s]`}),(0,K.jsx)(`div`,{className:`relative flex size-14 items-center justify-center rounded-2xl border border-border bg-background shadow-quickforge`,children:(0,K.jsx)(ee,{className:`size-6 text-foreground/75`})})]}),(0,K.jsx)(`p`,{className:`mt-9 text-sm font-medium text-foreground/85`,children:`正在建立连接…`}),(0,K.jsx)(`p`,{className:`mt-2 w-full max-w-xs truncate text-center font-mono text-xs text-muted-foreground`,children:e})]})}return(0,K.jsxs)(`main`,{className:`min-h-dvh bg-background px-5 pb-[max(2rem,env(safe-area-inset-bottom))] pt-[max(2rem,env(safe-area-inset-top))] text-foreground`,children:[(0,K.jsxs)(`div`,{className:`mx-auto w-full max-w-md`,children:[(0,K.jsxs)(`div`,{className:`mb-6 grid grid-cols-2 gap-1 rounded-xl bg-muted/40 p-1`,role:`tablist`,"aria-label":`连接方式`,children:[(0,K.jsxs)(`button`,{type:`button`,role:`tab`,"aria-selected":T===`servers`,className:`flex items-center justify-center gap-1.5 rounded-lg py-2 text-sm font-medium transition-colors ${T===`servers`?`bg-background text-foreground shadow-sm`:`text-muted-foreground hover:text-foreground`}`,onClick:()=>D(`servers`),children:[(0,K.jsx)(ee,{className:`size-4`,"aria-hidden":`true`}),`服务器列表`]}),(0,K.jsxs)(`button`,{type:`button`,role:`tab`,"aria-selected":T===`cloud`,className:`flex min-w-0 flex-col items-center justify-center gap-0.5 rounded-lg px-1.5 py-1.5 text-sm font-medium transition-colors ${T===`cloud`?`bg-background text-foreground shadow-sm`:`text-muted-foreground hover:text-foreground`}`,onClick:()=>D(`cloud`),children:[(0,K.jsxs)(`span`,{className:`flex items-center justify-center gap-1.5`,children:[(0,K.jsx)(xe,{className:`size-4`,"aria-hidden":`true`}),`云账户`]}),O.signedIn&&O.email?(0,K.jsx)(`span`,{className:`block w-full max-w-full truncate text-center text-xs leading-tight text-muted-foreground/80`,children:O.email}):null]})]}),T===`cloud`?(0,K.jsx)(Qf,{onSessionChange:k}):(0,K.jsxs)(`section`,{className:`mx-auto w-full max-w-md`,children:[(0,K.jsxs)(`header`,{className:`mb-8 flex items-start gap-3.5`,children:[(0,K.jsx)(`div`,{className:`flex size-11 shrink-0 items-center justify-center rounded-xl border border-border bg-background shadow-quickforge`,children:(0,K.jsx)(ee,{className:`size-5 text-foreground/75`,"aria-hidden":`true`})}),(0,K.jsxs)(`div`,{className:`min-w-0 pt-0.5`,children:[(0,K.jsx)(`h1`,{className:`text-lg font-semibold tracking-tight`,children:`连接 QuickForge`}),(0,K.jsx)(`p`,{className:`mt-1 text-sm leading-5 text-muted-foreground`,children:`选择一台已保存的服务器,或添加新的 Tailscale 地址。`})]})]}),t.urls.length>0?(0,K.jsxs)(`section`,{"aria-labelledby":`quickforge-mobile-saved-servers`,children:[(0,K.jsxs)(`div`,{className:`mb-2.5 flex items-center justify-between px-1`,children:[(0,K.jsx)(`h2`,{id:`quickforge-mobile-saved-servers`,className:`text-xs font-medium text-muted-foreground`,children:`已保存的服务器`}),(0,K.jsxs)(`span`,{className:`text-xs text-muted-foreground/70`,children:[t.urls.length,` 台`]})]}),(0,K.jsx)(`div`,{className:`overflow-hidden rounded-2xl border border-border bg-background`,children:t.urls.map(e=>{let n=e===t.lastUsedUrl,r=t.aliases?.[e]?.trim(),i=g===e,a=v===e;return(0,K.jsxs)(`div`,{className:`border-b border-border last:border-b-0`,children:[(0,K.jsxs)(`div`,{className:`flex min-h-[68px] items-stretch gap-1 p-1.5`,children:[(0,K.jsxs)(`button`,{type:`button`,className:`flex min-w-0 flex-1 items-center gap-3 rounded-xl px-2.5 py-2 text-left transition-colors hover:bg-muted/45 active:bg-muted/65`,onClick:()=>N(e),title:`连接 ${r||e}`,children:[(0,K.jsx)(`span`,{className:`flex size-9 shrink-0 items-center justify-center rounded-xl bg-muted/45 text-muted-foreground`,children:(0,K.jsx)(ee,{className:`size-4`,"aria-hidden":`true`})}),(0,K.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,K.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`span`,{className:`truncate text-sm font-medium text-foreground`,children:r||`QuickForge 服务器`}),n?(0,K.jsx)(`span`,{className:`shrink-0 rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium text-muted-foreground`,children:`上次使用`}):null]}),(0,K.jsx)(`span`,{className:`mt-1 block truncate font-mono text-xs text-muted-foreground`,children:e})]}),(0,K.jsx)(F,{className:`size-4 shrink-0 text-muted-foreground/65`,"aria-hidden":`true`})]}),(0,K.jsx)(`button`,{type:`button`,className:`inline-flex w-10 shrink-0 items-center justify-center rounded-xl text-muted-foreground transition-colors hover:bg-muted/45 hover:text-foreground active:bg-muted/65`,onClick:()=>{_(i?null:e),i&&I()},"aria-label":`管理 ${r||e}`,title:`管理服务器`,"aria-expanded":i,children:i?(0,K.jsx)(z,{className:`size-4`,"aria-hidden":`true`}):(0,K.jsx)(oe,{className:`size-5`,"aria-hidden":`true`})})]}),i?(0,K.jsx)(`div`,{className:`border-t border-border bg-muted/30 px-3 py-3`,children:a?(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground`,htmlFor:`quickforge-mobile-alias-${e}`,children:`服务器别名`}),(0,K.jsx)(`input`,{id:`quickforge-mobile-alias-${e}`,autoFocus:!0,autoCapitalize:`none`,autoCorrect:`off`,spellCheck:!1,value:b,onChange:e=>x(e.target.value),onKeyDown:t=>{t.key===`Enter`&&L(e),t.key===`Escape`&&I()},placeholder:`例如:公司开发机`,className:`mt-2 h-11 w-full rounded-xl border border-input bg-background px-3.5 text-sm outline-none transition-[border-color,box-shadow] placeholder:text-muted-foreground/60 focus:border-foreground/30 focus:shadow-quickforge`}),(0,K.jsxs)(`div`,{className:`mt-2.5 flex justify-end gap-2`,children:[(0,K.jsx)(`button`,{type:`button`,className:`inline-flex h-9 items-center justify-center rounded-xl px-3 text-sm text-muted-foreground transition-colors hover:bg-muted/60 hover:text-foreground`,onClick:I,children:`取消`}),(0,K.jsxs)(`button`,{type:`button`,className:`inline-flex h-9 items-center justify-center gap-1.5 rounded-xl bg-primary px-3.5 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-92 active:opacity-85`,onClick:()=>L(e),children:[(0,K.jsx)(S,{className:`size-4`,"aria-hidden":`true`}),`保存`]})]})]}):(0,K.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,K.jsxs)(`button`,{type:`button`,className:`inline-flex h-10 items-center justify-center gap-2 rounded-xl text-sm text-foreground/80 transition-colors hover:bg-muted/60`,onClick:()=>ie(e),children:[(0,K.jsx)(ae,{className:`size-4 text-muted-foreground`,"aria-hidden":`true`}),`编辑别名`]}),(0,K.jsxs)(`button`,{type:`button`,className:`inline-flex h-10 items-center justify-center gap-2 rounded-xl text-sm text-foreground/80 transition-colors hover:bg-destructive/10 hover:text-destructive`,onClick:()=>w(e),children:[(0,K.jsx)(me,{className:`size-4 text-muted-foreground`,"aria-hidden":`true`}),`删除服务器`]})]})}):null]},e)})}),a?null:(0,K.jsxs)(`button`,{type:`button`,className:`mt-3 inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl text-sm font-medium text-foreground/80 transition-colors hover:bg-muted/45 active:bg-muted/65`,onClick:ne,children:[(0,K.jsx)(o,{className:`size-4`,"aria-hidden":`true`}),`添加服务器`]}),m&&!a?(0,K.jsxs)(`p`,{className:`mt-2 flex items-center justify-center gap-1.5 text-sm text-muted-foreground`,role:`status`,children:[(0,K.jsx)(S,{className:`size-4`,"aria-hidden":`true`}),`服务器已保存`]}):null]}):null,a?(0,K.jsxs)(`section`,{className:t.urls.length>0?`mt-7`:``,"aria-labelledby":`quickforge-mobile-add-server`,children:[(0,K.jsxs)(`div`,{className:`mb-2.5 flex items-center justify-between px-1`,children:[(0,K.jsx)(`h2`,{id:`quickforge-mobile-add-server`,className:`text-xs font-medium text-muted-foreground`,children:t.urls.length>0?`添加服务器`:`添加第一台服务器`}),t.urls.length>0?(0,K.jsx)(`button`,{type:`button`,className:`rounded-lg px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-muted/45 hover:text-foreground`,onClick:()=>{j(),s(!1)},children:`收起`}):null]}),(0,K.jsxs)(`form`,{className:`rounded-2xl border border-border bg-background p-5 shadow-quickforge`,onSubmit:M,children:[(0,K.jsxs)(`div`,{className:`mb-5 flex gap-2.5 rounded-xl bg-muted/30 px-3 py-2.5 text-xs leading-5 text-muted-foreground`,children:[(0,K.jsx)(ue,{className:`mt-0.5 size-4 shrink-0`,"aria-hidden":`true`}),(0,K.jsxs)(`p`,{children:[`仅支持 Tailnet 内的 `,(0,K.jsx)(`span`,{className:`font-mono text-foreground/75`,children:`.ts.net`}),` 或 `,(0,K.jsx)(`span`,{className:`font-mono text-foreground/75`,children:`100.64.0.0/10`}),` 地址,未填写端口时默认使用 5176。`]})]}),(0,K.jsx)(`label`,{className:`block text-sm font-medium`,htmlFor:`quickforge-mobile-server`,children:`服务器地址`}),(0,K.jsx)(`input`,{id:`quickforge-mobile-server`,autoCapitalize:`none`,autoCorrect:`off`,inputMode:`url`,spellCheck:!1,value:c,onChange:e=>{l(e.target.value),p(``),h(!1)},placeholder:`devbox.example.ts.net`,className:`mt-2 h-11 w-full rounded-xl border border-input bg-background px-3.5 text-sm outline-none transition-[border-color,box-shadow] placeholder:text-muted-foreground/60 focus:border-foreground/30 focus:shadow-quickforge`}),te?(0,K.jsxs)(`p`,{className:`mt-2 break-all text-xs text-muted-foreground`,children:[`将连接到 `,(0,K.jsx)(`span`,{className:`font-mono text-foreground/70`,children:te})]}):(0,K.jsx)(`p`,{className:`mt-2 text-xs text-muted-foreground`,children:`请确保手机与服务器已登录同一个 Tailnet。`}),(0,K.jsxs)(`label`,{className:`mt-5 block text-sm font-medium`,htmlFor:`quickforge-mobile-server-alias`,children:[`服务器别名 `,(0,K.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:`(可选)`})]}),(0,K.jsx)(`input`,{id:`quickforge-mobile-server-alias`,autoCapitalize:`none`,autoCorrect:`off`,spellCheck:!1,value:u,onChange:e=>{d(e.target.value),p(``),h(!1)},placeholder:`例如:公司开发机`,className:`mt-2 h-11 w-full rounded-xl border border-input bg-background px-3.5 text-sm outline-none transition-[border-color,box-shadow] placeholder:text-muted-foreground/60 focus:border-foreground/30 focus:shadow-quickforge`}),f?(0,K.jsx)(`p`,{className:`mt-3 text-sm text-destructive`,role:`alert`,children:f}):null,(0,K.jsxs)(`button`,{type:`submit`,className:`mt-5 inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-92 active:opacity-85`,children:[`保存并连接`,(0,K.jsx)(E,{className:`size-4`,"aria-hidden":`true`})]}),(0,K.jsx)(`button`,{type:`button`,className:`mt-2 inline-flex h-10 w-full items-center justify-center rounded-xl text-sm text-muted-foreground transition-colors hover:bg-muted/45 hover:text-foreground active:bg-muted/65`,onClick:()=>re(!1),children:`仅保存,稍后连接`})]})]}):null]})]}),C?(0,K.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-end justify-center bg-black/35 p-4 pb-[max(1rem,env(safe-area-inset-bottom))] sm:items-center`,role:`presentation`,children:(0,K.jsxs)(`section`,{className:`w-full max-w-sm rounded-2xl border border-border bg-background p-5 shadow-xl`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`quickforge-mobile-delete-title`,children:[(0,K.jsx)(`h2`,{id:`quickforge-mobile-delete-title`,className:`text-base font-semibold`,children:`删除这台服务器?`}),(0,K.jsxs)(`p`,{className:`mt-2 break-all text-sm leading-6 text-muted-foreground`,children:[`“`,R,`”将从已保存列表中移除,之后仍可重新添加。`]}),(0,K.jsxs)(`div`,{className:`mt-5 grid grid-cols-2 gap-3`,children:[(0,K.jsx)(`button`,{type:`button`,className:`inline-flex h-11 items-center justify-center rounded-xl border border-border text-sm font-medium text-foreground/80 transition-colors hover:bg-muted/45`,onClick:()=>w(null),children:`取消`}),(0,K.jsx)(`button`,{type:`button`,className:`inline-flex h-11 items-center justify-center rounded-xl bg-destructive text-sm font-medium text-destructive-foreground transition-opacity hover:opacity-92 active:opacity-85`,onClick:()=>P(C),children:`删除`})]})]})}):null]})}var tp=`https://localhost/?connect=1&tab=cloud`,np=`http://127.0.0.1:18080/`;async function rp(){for(let e=0;e<3;e++){let t=new AbortController,n=window.setTimeout(()=>t.abort(),3e3);try{return await fetch(np,{mode:`no-cors`,cache:`no-store`,signal:t.signal}),window.clearTimeout(n),!0}catch{window.clearTimeout(n),e<2&&await new Promise(e=>setTimeout(e,700))}}return!1}function ip(){let[e,t]=(0,H.useState)(!1),[n,i]=(0,H.useState)(null),[a,o]=(0,H.useState)(!1),[s,c]=(0,H.useState)(0),[l,u]=(0,H.useState)(!1),d=(0,H.useRef)(!1),f=(0,H.useRef)(0),p=(0,H.useCallback)(async()=>{(await Wu({probe:rp})).status===`recovered`&&(d.current=!1,o(!1),i(null))},[]);if((0,H.useEffect)(()=>{let e=!0,n,r=()=>{d.current||(d.current=!0,o(!0))},a=t=>{e&&(i(t),t.state!==`connected`&&r(),t.state===`reconnecting`&&(f.current+=1,c(f.current)),t.state===`connected`&&d.current&&p())};return Gf.getState().then(t=>{if(e)return a(t),Gf.addListener(`remoteStateChanged`,a).then(e=>{n=e})}).catch(()=>{e&&t(!0)}),()=>{e=!1,n?.remove()}},[p]),(0,H.useEffect)(()=>{let e=()=>{document.visibilityState===`visible`&&d.current&&Gf.getState().then(e=>{e.state===`connected`&&d.current&&p()}).catch(()=>{})};return document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e)},[p]),!Gt()||e||!n||n.state===`connected`&&!a)return null;let m=n.state===`reconnecting`||n.state===`connecting`,h=n.state===`connected`&&a,g=async()=>{u(!0);try{await Gf.retry()}catch{}finally{u(!1)}},_=()=>{window.location.href=tp},v=`连接已断开`,y=`不会自动重连,请返回设备列表。`;m?y=`连接已断开,正在自动重连…(已重试 ${s} 次)`:h?(v=`正在恢复连接`,y=`连接已恢复,正在同步任务状态…`):n.state===`error`&&(v=`连接失败`,y=n.error||`隧道连接失败,请重试`,y.includes(`登录已过期`)&&(y=`${y},请重新登录`));let b=`inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-92 active:opacity-85 disabled:opacity-60`;return(0,K.jsx)(`div`,{className:`fixed inset-0 z-[90] flex items-center justify-center bg-background/80 p-6 backdrop-blur-sm`,children:(0,K.jsxs)(`div`,{className:`w-full max-w-sm rounded-2xl border border-border bg-background p-5 shadow-quickforge`,role:`status`,"aria-live":`polite`,children:[(0,K.jsxs)(`div`,{className:`flex items-start gap-3.5`,children:[(0,K.jsx)(`div`,{className:`flex size-11 shrink-0 items-center justify-center rounded-xl border border-border bg-background shadow-quickforge`,children:m?(0,K.jsx)(B,{className:`size-5 animate-spin text-foreground/75`,"aria-hidden":`true`}):(0,K.jsx)(N,{className:`size-5 text-foreground/75`,"aria-hidden":`true`})}),(0,K.jsxs)(`div`,{className:`min-w-0 pt-0.5`,children:[(0,K.jsx)(`h2`,{className:`text-base font-semibold tracking-tight`,children:v}),(0,K.jsx)(`p`,{className:`mt-1 text-sm leading-5 text-muted-foreground`,children:y})]})]}),(0,K.jsxs)(`div`,{className:`mt-5 flex flex-col gap-2.5`,children:[m?(0,K.jsxs)(`button`,{type:`button`,className:b,onClick:()=>{g()},disabled:l,children:[l?(0,K.jsx)(B,{className:`size-4 animate-spin`,"aria-hidden":`true`}):(0,K.jsx)(r,{className:`size-4`,"aria-hidden":`true`}),`立即重试`]}):null,(0,K.jsx)(`button`,{type:`button`,className:m?`inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl border border-border text-sm font-medium text-foreground/80 transition-colors hover:bg-muted/45 hover:text-foreground active:bg-muted/65 disabled:opacity-60`:b,onClick:_,children:`返回设备列表`})]})]})})}var ap=`quickforge:system-notifications-enabled`,op=`quickforge:android-remote-notification-permission-requested:v1`,sp=`quickforge:system-notifications-recent:v1`,cp=`quickforge:open-session`,lp=1e4,up=100,dp=!1,fp=!1;function pp(){if(!(typeof window>`u`||!Me.isNativePlatform()))return window.QuickForgeBridge}function mp(){if(typeof window>`u`)return;let e=window;e.__quickforgeOpenSession||=e=>{yp(e)}}function hp(){let e=pp();if(!e?.setNotificationService)return;let t=window.location.origin;if(t)try{e.setNotificationService(Cp(),t)}catch(e){V.warn(`Failed to sync native notification service:`,e)}}mp();function gp(){if(typeof document>`u`||typeof window>`u`)return!1;let e=window;return document.body?.classList.contains(`quickforge-desktop-app`)||e.__quickforgeDesktopApp===!0}function _p(){return Me.isNativePlatform()&&Me.isPluginAvailable(`LocalNotifications`)}function vp(e){return`${W(e===`idle`?`taskCompleted`:e===`error`?`taskError`:e===`aborted`?`processAborted`:`taskRunning`)}. ${W(`systemNotificationOpenDetails`)}`}function yp(e){typeof window>`u`||(window.focus(),e&&window.dispatchEvent(new CustomEvent(`quickforge:open-session-from-settings`,{detail:{sessionId:e}})))}function bp(e){let t=0;for(let n=0;n<e.length;n+=1)t=(t<<5)-t+e.charCodeAt(n)|0;return(t>>>0)%2147483646+1}function xp(){if(typeof localStorage>`u`)return{};try{let e=JSON.parse(localStorage.getItem(sp)||`{}`);return!e||typeof e!=`object`||Array.isArray(e)?{}:Object.fromEntries(Object.entries(e).filter(e=>typeof e[1]==`number`&&Number.isFinite(e[1])))}catch{return{}}}function Sp(e){if(typeof localStorage>`u`)return!0;let t=Date.now(),n=xp(),r=n[e];if(typeof r==`number`&&t-r<lp)return!1;let i=Object.entries({...n,[e]:t}).filter(([,e])=>t-e<lp).sort((e,t)=>t[1]-e[1]).slice(0,up);try{localStorage.setItem(sp,JSON.stringify(Object.fromEntries(i)))}catch{}return!0}function Cp(){if(typeof localStorage>`u`)return!1;try{return localStorage.getItem(ap)===`1`}catch{return!1}}function wp(e){if(!(typeof localStorage>`u`)){try{e?localStorage.setItem(ap,`1`):localStorage.removeItem(ap)}catch{}hp()}}function Tp(){if(!(typeof window>`u`||typeof navigator>`u`)&&!(Me.isNativePlatform()||!/Android/i.test(navigator.userAgent))&&!(!Gt()||!window.isSecureContext)&&!(typeof Notification>`u`||!navigator.serviceWorker)&&!(Notification.permission!==`default`||typeof localStorage>`u`)){try{if(localStorage.getItem(op))return;localStorage.setItem(op,`1`)}catch{return}Dp()}}async function Ep(){try{if(_p()){let{LocalNotifications:e}=await Xe(async()=>{let{LocalNotifications:e}=await import(`./esm-sdsK6gaB.js`);return{LocalNotifications:e}},__vite__mapDeps([0,1,2,3])),t=await e.checkPermissions();return t.display===`granted`?`granted`:t.display===`prompt`||t.display===`prompt-with-rationale`?`prompt`:`denied`}return gp()||typeof Notification>`u`?`unsupported`:Notification.permission===`granted`?`granted`:Notification.permission===`denied`?`denied`:`prompt`}catch(e){return V.warn(`Failed to check system notification permission:`,e),`unsupported`}}async function Dp(){try{let e;if(_p()){let{LocalNotifications:t}=await Xe(async()=>{let{LocalNotifications:e}=await import(`./esm-sdsK6gaB.js`);return{LocalNotifications:e}},__vite__mapDeps([0,1,2,3]));e=(await t.requestPermissions()).display===`granted`?`granted`:`denied`,await Op()}else if(!gp()&&typeof Notification<`u`){let t=await Notification.requestPermission();e=t===`granted`?`granted`:t===`denied`?`denied`:`prompt`}else e=`unsupported`;return wp(e===`granted`),e}catch(e){return V.warn(`Failed to request system notification permission:`,e),wp(!1),`denied`}}async function Op(){if(hp(),!fp&&typeof navigator<`u`&&navigator.serviceWorker&&(fp=!0,navigator.serviceWorker.addEventListener(`message`,e=>{let t=e.data;t?.type===cp&&yp(typeof t.sessionId==`string`?t.sessionId:void 0)})),!(!_p()||dp)){dp=!0;try{let{LocalNotifications:e}=await Xe(async()=>{let{LocalNotifications:e}=await import(`./esm-sdsK6gaB.js`);return{LocalNotifications:e}},__vite__mapDeps([0,1,2,3]));await e.addListener(`localNotificationActionPerformed`,e=>{let t=e.notification.extra?.sessionId;yp(typeof t==`string`?t:void 0)})}catch(e){dp=!1,V.warn(`Failed to initialize native notification listener:`,e)}}}async function kp(e){if(!Cp()||!e.force&&e.status===`running`&&typeof document<`u`&&document.visibilityState===`visible`&&document.hasFocus())return!1;try{if(await Ep()!==`granted`||!Sp(e.key))return!1;let t=vp(e.status);if(_p()){let{LocalNotifications:n}=await Xe(async()=>{let{LocalNotifications:e}=await import(`./esm-sdsK6gaB.js`);return{LocalNotifications:e}},__vite__mapDeps([0,1,2,3]));return await Op(),await n.schedule({notifications:[{id:bp(e.key),title:e.title,body:t,extra:{sessionId:e.sessionId}}]}),!0}if(typeof Notification>`u`)return!1;let n=typeof navigator<`u`&&/Android/i.test(navigator.userAgent);if(typeof navigator<`u`&&navigator.serviceWorker)try{let n=await navigator.serviceWorker.getRegistration();if(n?.showNotification)return await n.showNotification(e.title,{body:t,icon:`/pwa-icon-192.png`,tag:e.key,data:{sessionId:e.sessionId}}),!0}catch(e){V.warn(`Failed to show Service Worker notification:`,e)}if(n)return!1;let r=new Notification(e.title,{body:t,icon:`/pwa-icon-192.png`,tag:e.key});return r.onclick=()=>{r.close(),yp(e.sessionId)},!0}catch(e){return V.warn(`Failed to show system notification:`,e),!1}}var Ap=Object.freeze({modelSelection:!0,thinkingSelection:!0,clientApiKeyCheck:!0,planMode:!0,accessMode:!0,commands:!0,capabilitySuggestions:!0,contextUsage:!0,compaction:!0,rollback:!0,retry:!0,forkFromMessage:!0,forkSession:!1,harnessConfig:!1,attachments:!0}),jp=Object.freeze({modelSelection:!1,thinkingSelection:!1,clientApiKeyCheck:!1,planMode:!1,accessMode:!1,commands:!1,capabilitySuggestions:!1,contextUsage:!1,compaction:!1,rollback:!1,retry:!1,forkFromMessage:!1,forkSession:!0,harnessConfig:!0,attachments:!0});function Mp(e){return e===`opencode`?jp:Ap}function Np(e,t){return!t.readOnly&&!t.disableFork?e:{...e,rollback:e.rollback&&!t.readOnly,retry:e.retry&&!t.readOnly,forkFromMessage:e.forkFromMessage&&!t.readOnly&&!t.disableFork,forkSession:e.forkSession&&!t.readOnly&&!t.disableFork,harnessConfig:e.harnessConfig&&!t.readOnly,attachments:e.attachments&&!t.readOnly,planMode:e.planMode&&!t.readOnly,accessMode:e.accessMode&&!t.readOnly,commands:e.commands&&!t.readOnly,capabilitySuggestions:e.capabilitySuggestions&&!t.readOnly}}function Pp(e,t,n){let r=String(t??``).trim().length>0,i=(n?.length??0)>0;return!e.attachments&&i?!1:r||i}var Fp=(0,H.lazy)(()=>Xe(()=>import(`./ChatPanelHost-Dul1ahKj.js`).then(e=>({default:e.ChatPanelHost})),__vite__mapDeps([4,2,5,1,6,7,8,9,10,11,12]))),Ip=(0,H.lazy)(()=>Xe(()=>import(`./SharedConversationPage-BK9XJnEe.js`).then(e=>({default:e.SharedConversationPage})),__vite__mapDeps([13,2,1,5,6,7,8,4,9,10,11,12,14]))),Lp=(0,H.lazy)(()=>Xe(()=>import(`./WorkspaceInspector-MNBLIKMn.js`).then(e=>({default:e.WorkspaceInspector})),__vite__mapDeps([15,2,16,7,8,17,18,19,12,1]))),Rp=(0,H.lazy)(()=>Xe(()=>import(`./TerminalDock-CL7HU9DI.js`).then(e=>({default:e.TerminalDock})),__vite__mapDeps([17,2,18,19,7,8]))),zp=(0,H.lazy)(()=>Xe(()=>import(`./SettingsWorkspacePage-BE2T4d3P.js`).then(e=>({default:e.SettingsWorkspacePage})),__vite__mapDeps([20,2,1,5,6,7,8,10,11]))),Bp=`quickforge:auto-preview-seen-signatures`,Vp=200,Hp=`https://github.com/shawnstack/quickforge/releases/latest`,Up=1350,Wp=280,Gp=280;function Kp(){if(typeof window>`u`)return new Set;try{let e=window.sessionStorage.getItem(Bp),t=e?JSON.parse(e):void 0;return Array.isArray(t)?new Set(t.filter(e=>typeof e==`string`&&e.length>0)):new Set}catch{return new Set}}function qp(e){return Kp().has(e)}function Jp(e){if(!(typeof window>`u`))try{let t=[...Kp(),e].slice(-Vp);window.sessionStorage.setItem(Bp,JSON.stringify(t))}catch{}}function Yp(){return(0,K.jsx)(`div`,{className:`flex min-h-0 flex-1 items-center justify-center text-sm text-muted-foreground`,children:W(`loading`)})}function Xp(){return null}function Zp({exiting:e=!1}){let t=W(`loadingChatWorkspace`);return(0,K.jsxs)(`div`,{className:G(`quickforge-startup-splash`,e&&`quickforge-startup-splash-exit`),role:`status`,"aria-label":t,children:[(0,K.jsxs)(`svg`,{className:`quickforge-startup-splash-icon`,viewBox:`0 0 64 64`,fill:`none`,"aria-hidden":`true`,children:[(0,K.jsxs)(`defs`,{children:[(0,K.jsxs)(`linearGradient`,{id:`startupIconStroke`,x1:`0`,y1:`0`,x2:`1`,y2:`1`,children:[(0,K.jsx)(`stop`,{offset:`0`,stopColor:`#9ca3af`}),(0,K.jsx)(`stop`,{offset:`1`,stopColor:`#4b5563`})]}),(0,K.jsxs)(`linearGradient`,{id:`startupIconBolt`,x1:`0`,y1:`0`,x2:`1`,y2:`1`,children:[(0,K.jsx)(`stop`,{offset:`0`,stopColor:`#374151`}),(0,K.jsx)(`stop`,{offset:`1`,stopColor:`#0f172a`})]})]}),(0,K.jsx)(`polygon`,{className:`quickforge-startup-splash-outline`,points:`32,6 52.78,18 52.78,42 32,54 11.22,42 11.22,18`,fill:`none`,stroke:`url(#startupIconStroke)`,strokeWidth:`4.5`,strokeLinejoin:`round`}),(0,K.jsx)(`polygon`,{className:`quickforge-startup-splash-outline-final`,points:`32,6 52.78,18 52.78,42 32,54 11.22,42 11.22,18`,fill:`none`,stroke:`url(#startupIconStroke)`,strokeWidth:`4.5`,strokeLinejoin:`round`}),(0,K.jsx)(`path`,{className:`quickforge-startup-splash-bolt`,d:`M37.2 13 L22 34 L30.6 34 L26.8 50 L42.8 26 L33.8 26 Z`,fill:`url(#startupIconBolt)`}),(0,K.jsx)(`path`,{className:`quickforge-startup-splash-bolt-trace`,d:`M37.2 13 L22 34 L30.6 34 L26.8 50 L42.8 26 L33.8 26 Z`,fill:`none`,stroke:`#f8fafc`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`}),(0,K.jsx)(`path`,{className:`quickforge-startup-splash-bolt-highlight`,d:`M37.2 13 L22 34 L30.6 34 L33.8 26 Z`,fill:`#e5e7eb`})]}),(0,K.jsx)(`span`,{className:`sr-only`,children:t})]})}function Qp({exiting:e=!1}){let t=W(`loadingConversation`);return(0,K.jsxs)(`div`,{className:G(`quickforge-conversation-loading`,e&&`quickforge-conversation-loading-exit`),role:`status`,"aria-live":`polite`,"aria-label":t,children:[(0,K.jsxs)(`div`,{className:`quickforge-conversation-loading-status`,"aria-hidden":`true`,children:[(0,K.jsx)(`span`,{children:t}),(0,K.jsxs)(`span`,{className:`quickforge-conversation-loading-dots`,children:[(0,K.jsx)(`span`,{children:`•`}),(0,K.jsx)(`span`,{children:`•`}),(0,K.jsx)(`span`,{children:`•`})]})]}),(0,K.jsx)(`div`,{className:`quickforge-conversation-loading-track`,"aria-hidden":`true`,children:(0,K.jsx)(`div`,{className:`quickforge-conversation-loading-runner`})}),(0,K.jsx)(`span`,{className:`quickforge-conversation-loading-helper`,"aria-hidden":`true`,children:W(`loadingConversationPreparing`)})]})}function $p(e){return e===`idle`||e===`running`||e===`error`||e===`aborted`}function em(e){return e.type===`scheduled_task_notification`}function tm(e){return e.type===`scheduled_task_started`}function nm(e){return e.workspace?.kind===`project`&&typeof e.workspace.id==`string`&&e.workspace.id.length>0?e.workspace.id:typeof e.projectId==`string`&&e.projectId.length>0?e.projectId:void 0}function rm(){let e=Gt(),t=Kt(),n=Wt(),i=Ou(!0),o=n?window.location.origin:void 0,s=n?Ht():void 0,c=()=>qt(t?`cloud`:`servers`),l=(0,H.useRef)(null),f=(0,H.useRef)(Yn(Hn)),p=(0,H.useRef)(`default`),m=(0,H.useRef)(void 0),h=(0,H.useRef)(void 0),{activeProject:g,projects:_,defaultWorkspace:v,expandedProjectIds:x,selectingProject:S,projectPickerOpen:w,loadProject:T,switchActiveProject:E,handleSelectProjectPath:O,selectProjectDirectory:k,setProjectPickerOpen:ee,toggleProjectExpanded:te,toggleAllProjectsExpanded:j,reorderProjects:ne,setActiveProject:re,setProjects:M,setExpandedProjectIds:N}=rc(),{agentAccessMode:P,setAgentAccessMode:F,initialize:I}=ic(),L=Ru(),{setArtifactPreviewOpen:z,setWorkspaceInspectorOpen:se,setWorkspaceInspectorRequest:ce}=L,[le,ue]=(0,H.useState)(!1),[B,de]=(0,H.useState)(),[fe,me]=(0,H.useState)(!1),[he,ge]=(0,H.useState)(null),[ve,ye]=(0,H.useState)(!1),[be,xe]=(0,H.useState)(!1),[Se,we]=(0,H.useState)({artifacts:[]}),[Te,Ee]=(0,H.useState)(nd),[De,Oe]=(0,H.useState)(id),[ke,Ae]=(0,H.useState)(!1),je=(0,H.useRef)(!1),Me=(0,H.useRef)(``),[Ne,Pe]=(0,H.useState)(),[Fe,Ie]=(0,H.useState)(),Le=(0,H.useRef)(0),Re=(0,H.useRef)(void 0),[ze,Be]=(0,H.useState)(!1),[Ve,He]=(0,H.useState)(!1),[Ue,We]=(0,H.useState)(!1),[Ge,Ke]=(0,H.useState)(!1),[qe,Je]=(0,H.useState)(()=>new Set),Ye=(0,H.useRef)(0),Xe=(0,H.useRef)(0),Ze=(0,H.useRef)(0),Qe=(0,H.useRef)(0),$e=(0,H.useRef)(void 0),tt=(0,H.useRef)(void 0),[nt,rt]=(0,H.useState)(null),[it,at]=(0,H.useState)(!1),[ot,st]=(0,H.useState)(!1),[ct,lt]=(0,H.useState)(),ut=(0,H.useRef)(void 0),[dt,ft]=(0,H.useState)(),{toasts:pt,handleTaskComplete:mt,addToast:U,dismissToast:ht}=ll(),gt=(0,H.useCallback)((e,t,n)=>{mt(e,t,n),kp({key:`agent:${e}:${n}`,sessionId:e,title:t,status:n})},[mt]),_t=(0,H.useCallback)(()=>void 0,[]),vt=(0,H.useCallback)(()=>me(!1),[]),yt=(0,H.useCallback)(()=>{me(!1),window.open(Hp,`_blank`,`noopener,noreferrer`)},[]),bt=(0,H.useCallback)(()=>{me(!1),window.open(`quickforge://exit`,`_blank`,`noopener,noreferrer`)},[]);(0,H.useEffect)(()=>{rd(Te)},[Te]),(0,H.useEffect)(()=>{ad(De)},[De]);let xt=(0,H.useRef)(null),St=(0,H.useRef)(null),Ct=(0,H.useRef)(null),{allLoadedSessions:wt,pinnedSessions:Tt,pinnedHasMore:Et,pinnedLoading:Dt,globalSessions:Ot,sessionsForProject:kt,globalHasMore:At,projectTimelineSessions:jt,projectTimelineHasMore:Mt,projectTimelineLoading:Nt,projectHasMore:Pt,globalLoading:Ft,projectLoading:It,projectLoaded:Lt,loadGlobalSessions:Rt,loadProjectSessions:zt,refreshSessions:Bt,upsertSessionMetadata:Vt,updateSessionTitle:Ut,loadMorePinned:Jt,loadMoreGlobal:Xt,loadMoreProject:Qt,loadMoreProjectTimeline:$t}=cl({backendRef:Ct,expandedProjectIds:x,externalProjectIds:qe,viewMode:Te,sortMode:De,onBroadcastSessionsChanged:(0,H.useCallback)(()=>xt.current?.notifySessionsChanged(),[])}),en=dc({onSessionsChanged:()=>{Bt()},onProjectsChanged:()=>{T(!0)},onSettingsChanged:e=>{Bt(),e?.defaultHarness&&St.current?.(e.defaultHarness).catch(e=>{V.error(`Failed to apply the cross-tab default Harness change:`,e)})}});(0,H.useEffect)(()=>{p.current=P},[P]),(0,H.useEffect)(()=>{m.current=g},[g]),(0,H.useEffect)(()=>{h.current=v},[v]),(0,H.useEffect)(()=>{xt.current=en},[en]),(0,H.useEffect)(()=>{Op()},[]),(0,H.useEffect)(()=>{let e=window.setTimeout(()=>at(!0),Up);return()=>window.clearTimeout(e)},[]);let tn=(0,H.useCallback)((e,t)=>{Pe(n=>n?.sessionId===e&&Fr(n,t)?n:{sessionId:e,...t})},[]),J=el({storageRef:l,activeModelRef:f,agentAccessModeRef:p,activeProjectRef:m,defaultWorkspaceRef:h,setAgentAccessMode:F,switchActiveProject:E,sessions:wt,refreshSessions:Bt,updateSessionTitle:Ut,loadCloudModels:i.loadCloudModels,onTaskComplete:gt});(0,H.useEffect)(()=>{let e=J.loadingSessionId;if(!e||ut.current===e)return;let t=window.setTimeout(()=>{ut.current!==e&&($e.current?.(),$e.current=void 0,Qe.current+=1,ft(void 0),ut.current=e,lt(e))},0);return()=>window.clearTimeout(t)},[J.loadingSessionId]),(0,H.useEffect)(()=>{let e=ut.current;if(!e||dt!==e)return;let t=window.setTimeout(()=>{ut.current===e&&(ut.current=void 0,lt(void 0))},Gp);return()=>window.clearTimeout(t)},[J.loadingSessionId,dt,ct]);let{createAgent:rn,startDeferredSession:an,applyDefaultHarnessToBlankSession:on,loadSession:sn,syncSessionUI:cn,setCurrentAgentMessages:ln,updateCurrentAgentModel:un,setChatPanelRevision:dn,setCurrentTitleRef:fn,agentRef:Y,taskMapRef:pn,currentSessionIdRef:mn,currentChatScopeRef:hn}=J;(0,H.useEffect)(()=>{St.current=on},[on]),(0,H.useEffect)(()=>{Re.current=J.currentToolProject?.id,Le.current+=1,Ze.current+=1},[J.currentToolProject?.id]);let gn=(0,H.useCallback)(e=>{if(!e||e===mn.current)return;$e.current?.(),$e.current=void 0;let t=Qe.current+1;return Qe.current=t,ft(void 0),ut.current=e,lt(e),t},[mn]),_n=(0,H.useCallback)((e,t)=>{t!==void 0&&Qe.current!==t||ut.current===e&&($e.current?.(),$e.current=void 0,Qe.current+=1,ut.current=void 0,ft(void 0),lt(void 0))},[]),vn=(0,H.useCallback)(e=>{ut.current===e&&($e.current=void 0,ft(e))},[]),yn=(0,H.useCallback)((e,t)=>{V.error(`Failed to render conversation:`,t),_n(e),U({sessionId:e,title:W(`conversationLoadFailed`),status:`error`})},[U,_n]),bn=(0,H.useCallback)((e,t)=>{let n=gn(e);if(n===void 0){$e.current?.(),$e.current=void 0,Qe.current+=1,t();return}$e.current=Vu(()=>{$e.current=void 0,!(Qe.current!==n||ut.current!==e)&&t().then(t=>{t||_n(e,n)})})},[gn,_n]);(0,H.useEffect)(()=>()=>{$e.current?.()},[]);let xn=(0,H.useCallback)(e=>{e&&bn(e,()=>sn(e))},[sn,bn]);(0,H.useEffect)(()=>{let e=e=>{let t=e.detail;typeof t?.sessionId==`string`&&xn(t.sessionId)};return window.addEventListener(`quickforge:open-session-from-settings`,e),()=>window.removeEventListener(`quickforge:open-session-from-settings`,e)},[xn]);let Sn=(0,H.useCallback)(e=>{de(t=>t?.id===e?void 0:t)},[]),X=(0,H.useCallback)(e=>{Xe.current+=1,ce({...e,id:Xe.current}),se(!0)},[se,ce]),Cn=(0,H.useCallback)(e=>{ce(t=>t?.id===e?void 0:t)},[ce]),wn=(0,H.useCallback)(()=>{let e=J.currentToolProject?.id;e&&(z(!1),X({projectId:e,kind:`review`,view:`changes`}))},[J.currentToolProject?.id,X,z]),Tn=(0,H.useCallback)(async()=>{let e=J.currentToolProject?.id,t=Le.current+1;if(Le.current=t,!e){Ie(void 0);return}try{let n=await bd(e);return sd({projectId:e,requestId:t},Re.current,Le.current)?(Ie(n),n):void 0}catch(n){if(!sd({projectId:e,requestId:t},Re.current,Le.current))return;V.warn(`Failed to refresh title git status:`,n),Ie(void 0);return}},[J.currentToolProject?.id]);(0,H.useEffect)(()=>{let e=window.setTimeout(()=>{Tn()},0);return()=>window.clearTimeout(e)},[Tn]),(0,H.useEffect)(()=>{let e,t=jc(t=>{ld(t,mn.current,Re.current)&&(e!==void 0&&window.clearTimeout(e),e=window.setTimeout(()=>{e=void 0,Tn()},400))});return()=>{e!==void 0&&window.clearTimeout(e),t()}},[J.currentSessionId,mn,Tn]);let En=(0,H.useCallback)(async e=>{let t=J.currentToolProject?.id;if(!t)return;let n=Le.current+1;Le.current=n;try{let r=await kd(t,e);if(!sd({projectId:t,requestId:n},Re.current,Le.current))return;Ie(r),Be(!1),U({sessionId:J.currentSessionId??``,title:W(`gitBranchSwitched`),status:`idle`,message:e})}catch(e){if(!sd({projectId:t,requestId:n},Re.current,Le.current))return;throw V.error(`Failed to checkout git branch:`,e),$(e instanceof Error?e.message:W(`gitCheckoutFailed`)),e}},[U,J.currentSessionId,J.currentToolProject?.id]),Dn=(0,H.useCallback)(e=>{Ie(e),Be(!1),U({sessionId:J.currentSessionId??``,title:W(`gitBranchCreated`),status:`idle`,message:e.branch??``})},[U,J.currentSessionId]),On=(0,H.useCallback)(e=>{Ie(e),U({sessionId:J.currentSessionId??``,title:W(`gitOperationCompleted`),status:`idle`,message:e.branch??``})},[U,J.currentSessionId]),kn=(0,H.useCallback)(async e=>{let t=J.currentToolProject?.id;if(!t){U({sessionId:J.currentSessionId??``,title:`无法打开文件`,status:`error`,message:`当前对话没有关联项目。`});return}let n=Ze.current+1;Ze.current=n;try{let r=await vd(t,e);if(!sd({projectId:t,requestId:n},Re.current,Ze.current))return;X({projectId:t,kind:`reader`,path:r.relativePath})}catch(e){if(!sd({projectId:t,requestId:n},Re.current,Ze.current))return;let r=e instanceof Error?e.message:`打开文件失败`;U({sessionId:J.currentSessionId??``,title:`无法打开文件`,status:`error`,message:r})}},[U,J.currentSessionId,J.currentToolProject?.id,X]),An=(0,H.useCallback)((e,t,n)=>{let r=J.currentToolProject,i=yf(t,n);if(!(!r||r.id!==e||!i)){if(z(!1),i===`reader`){X({projectId:e,kind:`reader`,path:t});return}X({projectId:e,kind:`browser`,url:bf(r.path,t)})}},[J.currentToolProject,X,z]);(0,H.useEffect)(()=>{let e=J.currentToolProject,t=e?.id;if(!t||Se.projectId!==t||Se.sessionId!==J.currentSessionId)return;let n=Tf(Se.artifacts);if(!n?.path)return;let r=n.toolCallIds[n.toolCallIds.length-1],i=`${t}:${n.path}:${n.defaultPreview?`default`:n.explicit?`explicit`:`inferred`}:${r??``}`;if(i!==Me.current){if(qp(i)){Me.current=i;return}Me.current=i,Jp(i),queueMicrotask(()=>{let r=yf(n.path,n.kind);r&&(z(!1),X(r===`reader`?{projectId:t,kind:`reader`,path:n.path}:{projectId:t,kind:`browser`,url:bf(e.path,n.path)}))})}},[J.currentSessionId,J.currentToolProject,Se,X,z]),(0,H.useEffect)(()=>{Me.current=``,z(!1),ce(void 0)},[J.currentToolProject?.id,z,ce]),(0,H.useEffect)(()=>{if(!An)return;let e=e=>{let t=e.detail,n=J.currentToolProject?.id;n&&t&&typeof t.path==`string`&&An(n,t.path,t.kind)};return window.addEventListener(`quickforge:preview-artifact`,e),()=>window.removeEventListener(`quickforge:preview-artifact`,e)},[J.currentToolProject?.id,An]),(0,H.useEffect)(()=>{let e=e=>{let t=e.detail;if(!t||typeof t.waitUntil!=`function`)return;let n=(async()=>{let e=new Set,t=Y.current;t instanceof Mc&&e.add(t);for(let t of pn.current.values())t.agent instanceof Mc&&e.add(t.agent);await Promise.all([...e].map(async e=>{try{let t=await fetch(`/api/agents/${encodeURIComponent(e.sessionId)}/state`,{cache:`no-store`});if(!t.ok)throw Error(`HTTP ${t.status}`);await e.syncState()}catch(e){throw V.error(`Tunnel recovery failed to sync agent state:`,e),e}})),await Bt({broadcast:!0})})();t.waitUntil(n)};return window.addEventListener(Hu,e),()=>window.removeEventListener(Hu,e)},[Y,pn,Bt]),(0,H.useEffect)(()=>jc(e=>{if(tm(e)){let t=typeof e.projectId==`string`?e.projectId:void 0;t&&(N(e=>{let n=new Set(e);return n.add(t),n}),zt(t,0)),Bt({broadcast:!0});return}if(e.type===`session_created`){let t=e.metadata;t?.id&&Vt(t)}else if(e.type===`title_updated`){let t=typeof e.sessionId==`string`?e.sessionId:void 0,n=typeof e.title==`string`?e.title:void 0;t&&n&&Ut(t,n)}else (e.type===`agent_end`||e.type===`session_forked`)&&Bt({broadcast:!0});if(!em(e))return;let t=typeof e.sessionId==`string`?e.sessionId:void 0,n=typeof e.title==`string`?e.title:W(`scheduledTasks`),r=$p(e.status)?e.status:`idle`,i=typeof e.message==`string`?e.message:void 0;U({sessionId:t??``,title:n,status:r,message:i});let a=typeof e.runId==`string`?e.runId:void 0;kp({key:a?`scheduled:${a}`:`scheduled:${t??n}:${r}`,sessionId:t,title:n,status:r})}),[U,zt,Bt,N,Ut,Vt]);let{ready:jn,startupError:Mn,retryBootstrap:Nn}=zl({storageRef:l,backendRef:Ct,activeModelRef:f,agentAccessModeRef:p,taskMapRef:pn,refreshSessions:Bt,loadProject:T,initAgentAccessMode:I,createAgent:rn,loadSession:sn,loadCloudModels:i.loadCloudModels,setNeedsModelSetup:ue,onStorageReady:rt}),Pn=Yl(l,jn),In=jn&&it&&!!(J.agent||le);(0,H.useEffect)(()=>{if(!In)return;let e=window.setTimeout(()=>st(!0),Wp);return()=>window.clearTimeout(e)},[In]),(0,H.useEffect)(()=>{if(!jn)return;let e=new EventSource(`/api/channels/events`),t=e=>{try{let t=JSON.parse(e.data);if(t.type!==`sessions-changed`||typeof t.sessionId!=`string`)return;let n=nm(t);n&&Je(e=>e.has(n)?e:new Set([...e,n])),t.metadata?.id===t.sessionId?Vt(t.metadata):n?zt(n,0):Rt(0);let r=Y.current;t.sessionId===mn.current&&r instanceof Mc&&r.syncState()}catch{}};return e.addEventListener(`sessions-changed`,t),()=>{e.removeEventListener(`sessions-changed`,t),e.close()}},[Y,mn,Rt,zt,jn,Vt]),(0,H.useEffect)(()=>{if(jn)for(let e of x)!Lt(e)&&!It(e)&&zt(e,0)},[jn,x,Lt,It,zt]);let{startNewGlobalChat:Ln,startNewProjectChat:Rn,rollbackFromMessage:zn,retryFromMessage:Bn,copyAnswer:Vn,forkFromMessage:Un,forkCurrentSession:Wn}=Au({storageRef:l,activeModelRef:f,activeProjectRef:m,currentChatScopeRef:hn,currentSessionIdRef:mn,taskMapRef:pn,agentRef:Y,createAgent:rn,startDeferredSession:an,syncSessionUI:cn,setCurrentAgentMessages:ln,setChatPanelRevision:dn,refreshSessions:Bt,needsModelSetup:le,setNeedsModelSetup:ue,switchActiveProject:E,closeWorkspacePage:_t,setRestoredDraft:de}),{deleteProjectInline:Gn}=ju({activeProjectRef:m,refreshSessions:Bt,notifyProjectsChanged:en.notifyProjectsChanged,setActiveProject:re,setProjects:M,setExpandedProjectIds:N,setChatPanelRevision:dn});(0,H.useEffect)(()=>{let e=od({ready:jn,currentToolProjectId:J.currentToolProject?.id,projects:_,activeProject:g,recoveringProjectId:tt.current});if(e.type===`none`){let e=J.currentToolProject?.id;tt.current&&tt.current!==e&&(tt.current=void 0);return}tt.current=e.deletedProjectId,we({artifacts:[]}),ce(void 0),z(!1),ge(null),ye(!1),Ze.current+=1,an(e.type===`project`?{scope:`project`,project:e.project}:{scope:`global`}).catch(e=>{tt.current=void 0,V.error(`Failed to recover after the current project was deleted:`,e)})},[g,J.currentToolProject?.id,_,jn,z,ce,an]);let{setAccessMode:Kn}=Lu({storageRef:l,agentAccessModeRef:p,setAgentAccessMode:F,agentRef:Y,setChatPanelRevision:dn,notifySettingsChanged:en.notifySettingsChanged}),qn=(0,H.useCallback)(async e=>{let t=Y.current;if(!t)throw Error(W(`toolApprovalFailed`));try{await t.approveToolCall(e)}catch(e){throw V.error(`Failed to approve tool call:`,e),e instanceof Error?e:Error(W(`toolApprovalFailed`))}},[Y]),Jn=(0,H.useCallback)(async e=>{let t=Y.current;if(!t)throw Error(W(`toolApprovalFailed`));try{await t.rejectToolCall(e)}catch(e){throw V.error(`Failed to reject tool call:`,e),e instanceof Error?e:Error(W(`toolApprovalFailed`))}},[Y]),Xn=(0,H.useCallback)(async e=>{let t=Y.current;if(!t?.approveAutoCompact)throw Error(W(`toolApprovalFailed`));await t.approveAutoCompact(e)},[Y]),Zn=(0,H.useCallback)(async e=>{let t=Y.current;if(!t?.rejectAutoCompact)throw Error(W(`toolApprovalFailed`));await t.rejectAutoCompact(e)},[Y]),{loadSession:Qn,renameSession:$n,togglePinSession:er,archiveSession:tr,startNewGlobalSession:nr}=Fu({storageRef:l,taskMapRef:pn,currentSessionIdRef:mn,loadAgentSession:sn,setCurrentTitleRef:fn,refreshSessions:Bt,updateSessionTitle:Ut,closeWorkspacePage:_t,startNewGlobalChat:Ln}),rr=(0,H.useCallback)(e=>{bn(e,()=>Qn(e))},[Qn,bn]),ir=(0,H.useCallback)((e,t)=>{L.setSettingsInitialTab(e),L.setSettingsCustomProvider(t),L.setSettingsDialogOpen(!0),L.setMobileSidebarOpen(!1)},[L]),{activateConfiguredModel:ar,openModelSettings:or,openDefaultOptionsSettings:sr,openAboutSettings:cr,activateLiteLlmExampleModel:lr,openCustomModelSelector:ur}=su({storageRef:l,activeModelRef:f,agentRef:Y,createAgent:rn,updateCurrentAgentModel:un,setChatPanelRevision:dn,setNeedsModelSetup:ue,setRestoredDraft:de,notifySettingsChanged:en.notifySettingsChanged,openSettingsPage:ir,loadCloudModels:i.loadCloudModels}),dr=(0,H.useCallback)(()=>{L.setSettingsDialogOpen(!1),L.setSettingsCustomProvider(void 0),(le||!Y.current)&&ar().catch(e=>V.error(`Failed to activate configured model:`,e))},[ar,Y,le,L]),fr=(0,H.useCallback)(()=>{me(!1),cr()},[cr]),pr=(0,H.useMemo)(()=>wt,[wt]),mr=(0,H.useMemo)(()=>{if(J.currentSessionId)return pr.find(e=>e.id===J.currentSessionId)},[J.currentSessionId,pr]),hr=!!mr?.pinnedAt,gr=Bu(pr),_r=(0,H.useCallback)(e=>J.taskStatuses[e.id]??gr[e.id]??e.taskStatus??`idle`,[J.taskStatuses,gr]);(0,H.useEffect)(()=>{if(fe)return window.addEventListener(`click`,vt),window.addEventListener(`blur`,vt),()=>{window.removeEventListener(`click`,vt),window.removeEventListener(`blur`,vt)}},[vt,fe]),(0,H.useEffect)(()=>{if(!L.conversationMenuOpen)return;let e=()=>L.setConversationMenuOpen(!1),t=t=>{t.key===`Escape`&&e()};return window.addEventListener(`click`,e),window.addEventListener(`blur`,e),window.addEventListener(`resize`,e),window.addEventListener(`orientationchange`,e),document.addEventListener(`keydown`,t),()=>{window.removeEventListener(`click`,e),window.removeEventListener(`blur`,e),window.removeEventListener(`resize`,e),window.removeEventListener(`orientationchange`,e),document.removeEventListener(`keydown`,t)}},[L,L.conversationMenuOpen]),(0,H.useEffect)(()=>{if(!ze)return;let e=()=>Be(!1);return window.addEventListener(`click`,e),window.addEventListener(`blur`,e),()=>{window.removeEventListener(`click`,e),window.removeEventListener(`blur`,e)}},[ze]),(0,H.useEffect)(()=>{let t=t=>{if(e){$(`远程客户端不能使用服务端终端`);return}let n=t.detail,r=typeof n?.command==`string`?n.command.trim():``;r&&(async()=>{(n?.confirm||n?.dangerous)&&!await $c({title:W(`confirmExecuteCommandTitle`),description:n?.dangerous?W(`confirmExecuteDangerousCommand`):W(`confirmExecuteMultipleCommands`),confirmLabel:W(`executeInTerminal`),cancelLabel:W(`cancel`),variant:n?.dangerous?`destructive`:`default`})||(z(!1),ye(!0),ge({id:++Ye.current,command:r,execute:!0}))})().catch(e=>{V.error(`Failed to execute markdown command:`,e),$(e instanceof Error?e.message:W(`terminalCommandExecuteFailed`))})};return window.addEventListener(`quickforge:execute-markdown-command`,t),()=>window.removeEventListener(`quickforge:execute-markdown-command`,t)},[e,z]);let vr=(0,H.useCallback)(e=>{ge(t=>t?.id===e?null:t)},[]),yr=(0,H.useCallback)(()=>{L.setFirstUseGuideDismissed(!0)},[L]),br=(0,H.useCallback)(()=>{let e=J.currentToolProject?.id?W(`firstUseGuideProjectPrompt`):W(`firstUseGuideGeneralPrompt`);navigator.clipboard.writeText(e).then(()=>U({sessionId:J.currentSessionId??``,title:W(`copied`),status:`idle`,message:e})).catch(e=>{V.error(`Failed to copy first-use guide prompt:`,e),$(W(`copyFailed`))})},[U,J.currentSessionId,J.currentToolProject?.id]),xr=!le&&!!J.agent&&!J.agent?.state.isStreaming&&(J.agent?.state.messages.length??0)===0;(0,H.useEffect)(()=>{xr&&!je.current&&Ae(!1),je.current=xr},[xr]),(0,H.useEffect)(()=>{!xr||ke||!g||J.chatScope!==`global`||Rn(g)},[g,J.chatScope,ke,xr,Rn]);let Sr=(0,H.useCallback)(()=>{if(Ae(!1),g){Rn(g);return}nr()},[g,nr,Rn]),Cr=(0,H.useCallback)(e=>{Rn(e)},[Rn]),wr=(0,H.useCallback)(()=>{Ae(!0),nr()},[nr]),Tr=(0,H.useCallback)(()=>{k()},[k]),Er=!!nt&&!L.firstUseGuideDismissed&&!xr&&_.length===0&&Ot.length===0,Dr=(0,H.useCallback)(()=>{let e=J.currentSessionId;e&&(L.setConversationMenuOpen(!1),er(e))},[J.currentSessionId,er,L]),Or=(0,H.useCallback)(()=>{let e=J.currentSessionId;e&&(L.setConversationMenuOpen(!1),$n(e,J.currentTitle))},[J.currentSessionId,J.currentTitle,$n,L]),kr=(0,H.useCallback)(()=>{L.setConversationMenuOpen(!1),L.setShareDialogOpen(!0)},[L]),Ar=J.agent,jr=Ar?.harness===`opencode`&&!Ar.state.isStreaming&&Ar instanceof Mc&&!!Ar.harnessSessionId,Mr=(0,H.useCallback)(()=>{let e=J.currentSessionId;e&&(L.setConversationMenuOpen(!1),tr(e))},[J.currentSessionId,tr,L]),{setSkillsDialog:Nr,setSidebarOpen:Pr}=L,Ir=(0,H.useCallback)(()=>{ir(`skills`)},[ir]),Lr=(0,H.useCallback)(()=>{ir(`agents`)},[ir]),Rr=(0,H.useCallback)(()=>{ir(`scheduledTasks`)},[ir]),zr=(0,H.useCallback)(e=>{Nr({scope:`project`,project:e})},[Nr]),Br=(0,H.useCallback)(async e=>{let t=await fetch(`/api/project/${encodeURIComponent(e.id)}/open-in-explorer`,{method:`POST`});if(t.ok)return;let n=await t.json().catch(()=>null);throw Error(n?.error||W(`openInExplorerFailed`))},[]),Vr=(0,H.useCallback)(async e=>{let t=await fetch(`/api/project/${encodeURIComponent(e.id)}/open-in-vscode`,{method:`POST`});if(t.ok)return;let n=await t.json().catch(()=>null);throw Error(n?.error||W(`openInVSCodeFailed`))},[]),Hr=(0,H.useCallback)(async e=>{let t=await fetch(`/api/project/${encodeURIComponent(e.id)}/open-in-idea`,{method:`POST`});if(t.ok)return;let n=await t.json().catch(()=>null);throw Error(n?.error||W(`openInIDEAFailed`))},[]),Ur=(0,H.useCallback)(e=>{Br(e).catch(e=>{V.error(`Failed to open project in explorer:`,e),$(e instanceof Error?e.message:W(`openInExplorerFailed`))})},[Br]),Wr=(0,H.useCallback)(e=>{Vr(e).catch(e=>{V.error(`Failed to open project in VS Code:`,e),$(e instanceof Error?e.message:W(`openInVSCodeFailed`))})},[Vr]),qr=(0,H.useCallback)(e=>{Hr(e).catch(e=>{V.error(`Failed to open project in IntelliJ IDEA:`,e),$(e instanceof Error?e.message:W(`openInIDEAFailed`))})},[Hr]),Yr=(0,H.useCallback)(()=>Pr(e=>!e),[Pr]),Z=(0,H.useCallback)(()=>{L.setMobileSidebarOpen(!1)},[L]),Xr=(0,H.useCallback)(e=>{Z(),rr(e)},[Z,rr]),Zr=(0,H.useCallback)(()=>{Z(),Sr()},[Z,Sr]),Qr=(0,H.useCallback)(e=>{Z(),Rn(e)},[Z,Rn]),$r=(0,H.useCallback)(()=>{Z(),Ir()},[Z,Ir]),ei=(0,H.useCallback)(()=>{Z(),Lr()},[Z,Lr]),ti=(0,H.useCallback)(()=>{Z(),Rr()},[Z,Rr]),ni=(0,H.useCallback)(e=>{Z(),zr(e)},[Z,zr]),ri=(0,H.useCallback)(e=>{if(e.scope===`project`&&e.project&&e.projects){M(e.projects),L.setSkillsDialog({scope:`project`,project:e.project}),m.current?.id===e.project.id&&(re(e.project),m.current=e.project),en.notifyProjectsChanged();return}en.notifyProjectsChanged()},[en,re,M,L]);return Mn?(0,K.jsx)(`div`,{className:`flex h-screen items-center justify-center bg-background p-6 text-foreground`,children:(0,K.jsxs)(`div`,{className:`max-w-md rounded-lg border border-border bg-background p-5 text-center`,children:[(0,K.jsx)(`h1`,{className:`text-base font-semibold`,children:W(`localServiceUnavailableTitle`)}),(0,K.jsx)(`p`,{className:`mt-2 text-sm text-muted-foreground`,children:Mn}),(0,K.jsxs)(`div`,{className:`mt-4 flex justify-center gap-2`,children:[(0,K.jsx)(q,{variant:`outline`,size:`sm`,onClick:Nn,children:W(`retry`)}),(0,K.jsx)(q,{variant:`default`,size:`sm`,onClick:()=>window.location.reload(),children:W(`reloadPage`)})]})]})}):In?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`div`,{className:`quickforge-desktop-titlebar fixed left-0 right-0 top-0 z-40 hidden h-8 items-center px-2`,children:[(0,K.jsxs)(`button`,{type:`button`,className:`quickforge-desktop-titlebar-trigger inline-flex h-8 translate-y-1 items-center gap-2.5 rounded-none px-3 text-[13px] font-medium leading-none text-foreground/90 transition-colors hover:bg-accent hover:text-accent-foreground`,onClick:e=>{e.stopPropagation(),me(e=>!e)},"aria-haspopup":`menu`,"aria-expanded":fe,children:[(0,K.jsxs)(`svg`,{className:`h-[18px] w-[18px] shrink-0`,viewBox:`0 0 64 64`,"aria-hidden":`true`,children:[(0,K.jsxs)(`defs`,{children:[(0,K.jsxs)(`linearGradient`,{id:`titlebarIconStroke`,x1:`0`,y1:`0`,x2:`1`,y2:`1`,children:[(0,K.jsx)(`stop`,{offset:`0`,stopColor:`#9ca3af`}),(0,K.jsx)(`stop`,{offset:`1`,stopColor:`#4b5563`})]}),(0,K.jsxs)(`linearGradient`,{id:`titlebarIconBolt`,x1:`0`,y1:`0`,x2:`1`,y2:`1`,children:[(0,K.jsx)(`stop`,{offset:`0`,stopColor:`#374151`}),(0,K.jsx)(`stop`,{offset:`1`,stopColor:`#0f172a`})]})]}),(0,K.jsx)(`polygon`,{points:`32,6 52.78,18 52.78,42 32,54 11.22,42 11.22,18`,fill:`none`,stroke:`url(#titlebarIconStroke)`,strokeWidth:`4.5`,strokeLinejoin:`round`}),(0,K.jsx)(`path`,{d:`M37.2 13 L22 34 L30.6 34 L26.8 50 L42.8 26 L33.8 26 Z`,fill:`url(#titlebarIconBolt)`}),(0,K.jsx)(`path`,{d:`M37.2 13 L22 34 L30.6 34 L33.8 26 Z`,fill:`#e5e7eb`,opacity:`0.4`})]}),(0,K.jsx)(`span`,{children:`QuickForge`})]}),fe&&(0,K.jsxs)(`div`,{className:`quickforge-desktop-titlebar-menu absolute left-2 top-8 min-w-40 overflow-hidden rounded-md border border-border bg-popover py-1 text-[13px] text-popover-foreground shadow-lg`,role:`menu`,onClick:e=>e.stopPropagation(),children:[(0,K.jsxs)(`button`,{type:`button`,className:`flex h-8 w-full items-center gap-2.5 px-3 text-left hover:bg-accent hover:text-accent-foreground`,role:`menuitem`,onClick:fr,children:[(0,K.jsx)(C,{className:`size-4`}),(0,K.jsx)(`span`,{children:W(`about`)})]}),(0,K.jsxs)(`button`,{type:`button`,className:`flex h-8 w-full items-center gap-2.5 px-3 text-left hover:bg-accent hover:text-accent-foreground`,role:`menuitem`,onClick:yt,children:[(0,K.jsx)(r,{className:`size-4`}),(0,K.jsx)(`span`,{children:W(`desktopUpdate`)})]}),(0,K.jsx)(`div`,{className:`my-1 border-t border-border`}),(0,K.jsxs)(`button`,{type:`button`,className:`flex h-8 w-full items-center gap-2.5 px-3 text-left text-destructive hover:bg-destructive/10`,role:`menuitem`,onClick:bt,children:[(0,K.jsx)(u,{className:`size-4`}),(0,K.jsx)(`span`,{children:W(`desktopExit`)})]})]})]}),!L.settingsDialogOpen&&(0,K.jsxs)(`div`,{className:G(`quickforge-window-toolbar fixed right-2 z-30 flex items-center gap-1`,be&&`pointer-events-none invisible`),"aria-hidden":be||void 0,"aria-label":W(`workspacePanel`),children:[!e&&!L.workspaceInspectorOpen?(0,K.jsx)(nn,{project:J.currentToolProject,disabled:le,onOpenInExplorer:Ur,onOpenInVSCode:Wr,onOpenInIDEA:qr}):null,!L.workspaceInspectorOpen&&J.currentToolProject?.id&&Fe?.isGitRepository?(0,K.jsx)(Wd,{projectId:J.currentToolProject.id,status:Fe,expanded:Ve,onExpandedChange:He,onOpenChanges:()=>{He(!1),wn()},onOpenCommitPush:()=>{He(!1),We(!0)},onCheckout:En,onCreated:Dn,onOpenGraph:()=>Ke(!0),mobileShell:n}):null,e?null:(0,K.jsx)(q,{variant:`ghost`,size:`icon`,onClick:()=>{z(!1),ye(e=>!e)},disabled:!J.currentToolProject?.id||le,"aria-label":W(ve?`terminalCollapse`:`rightPanelTerminal`),title:W(ve?`terminalCollapse`:`rightPanelTerminal`),className:G(`rounded-[10px] text-muted-foreground/85 hover:bg-muted/45 hover:text-foreground/90 disabled:opacity-40`,ve?`bg-accent text-accent-foreground hover:bg-accent hover:text-accent-foreground`:void 0),children:(0,K.jsx)(_e,{className:`size-[18px] stroke-[1.85]`})}),(0,K.jsx)(q,{variant:`ghost`,size:`icon`,onClick:()=>{z(!1),L.setWorkspaceInspectorOpen(e=>!e)},disabled:!J.currentToolProject?.id||le,"aria-label":L.workspaceInspectorOpen?W(`workspaceCollapseRightPanel`):W(`workspaceExpandRightPanel`),title:L.workspaceInspectorOpen?W(`workspaceCollapseRightPanel`):W(`workspaceExpandRightPanel`),className:G(`hidden rounded-[10px] text-muted-foreground/85 hover:bg-muted/45 hover:text-foreground/90 disabled:opacity-40 lg:inline-flex`,L.workspaceInspectorOpen?`bg-accent text-accent-foreground hover:bg-accent hover:text-accent-foreground`:void 0),children:(0,K.jsx)(ie,{className:`size-[18px] stroke-[1.85]`})})]}),L.settingsDialogOpen?(0,K.jsx)(H.Suspense,{fallback:(0,K.jsx)(Yp,{}),children:(0,K.jsx)(zp,{initialTab:L.settingsInitialTab,customProvider:L.settingsCustomProvider,onBack:dr})}):null,(0,K.jsxs)(`div`,{className:G(`flex h-screen min-h-0 supports-[height:100dvh]:h-dvh bg-[var(--quickforge-sidebar-bg)] text-foreground`,L.settingsDialogOpen&&`hidden`),"aria-hidden":L.settingsDialogOpen||void 0,children:[(0,K.jsx)(Rs,{sidebarOpen:L.sidebarOpen,projectsCollapsed:L.projectsCollapsed,pinnedCollapsed:L.pinnedCollapsed,conversationsCollapsed:L.conversationsCollapsed,projects:_,expandedProjectIds:x,activeProject:g,currentSessionId:J.currentSessionId,loadingSessionId:J.loadingSessionId,sessionViewMode:Te,sessionSortMode:De,globalSessions:Ot,pinnedSessions:Tt,pinnedHasMore:Et,pinnedLoading:Dt,sessionsForProject:kt,projectTimelineSessions:jt,projectTimelineHasMore:Mt,projectTimelineLoading:Nt,globalHasMore:At,globalLoading:Ft,onLoadMoreGlobal:Xt,onLoadMorePinned:Jt,projectHasMore:Pt,projectLoading:It,projectLoaded:Lt,onLoadMoreProject:Qt,onLoadMoreProjectTimeline:$t,sessionTaskStatus:_r,selectingProject:S,onTogglePinnedCollapsed:L.togglePinnedCollapsed,onToggleProjectsCollapsed:L.toggleProjectsCollapsed,onToggleConversationsCollapsed:L.toggleConversationsCollapsed,onToggleProjectExpanded:te,onToggleAllProjectsExpanded:j,onReorderProjects:ne,onSelectProjectDirectory:e?void 0:k,onStartNewProjectChat:Rn,onOpenGlobalSkills:Ir,onOpenAgents:Lr,onOpenScheduledTasks:Rr,onOpenProjectSkills:zr,onOpenProjectInExplorer:e?void 0:Ur,onDeleteProject:Gn,onLoadSession:rr,onSessionViewModeChange:Ee,onSessionSortModeChange:Oe,onTogglePinSession:er,onDeleteSession:tr,onStartNewGlobalChat:Sr,onOpenSettings:sr,currentServerUrl:t?`云账户远程访问`:o,currentServerAlias:s,onOpenServer:n||t?c:void 0,updateAvailable:Pn.result.updateAvailable,latestVersion:Pn.result.latestVersion,currentVersion:Pn.result.currentVersion,onOpenUpdate:cr,onDismissUpdate:Pn.dismissUpdate,onToggleSidebar:Yr,currentSessionHoverInfo:Ne}),L.mobileSidebarOpen?(0,K.jsxs)(`div`,{className:`fixed inset-0 z-50 md:hidden`,role:`dialog`,"aria-modal":`true`,children:[(0,K.jsx)(`button`,{type:`button`,className:`absolute inset-0 bg-background/65 backdrop-blur-sm`,onClick:Z,"aria-label":W(`toggleSidebar`)}),(0,K.jsx)(`div`,{className:`absolute inset-y-0 left-0 max-w-[85vw] shadow-quickforge`,children:(0,K.jsx)(Rs,{variant:`mobile`,sidebarOpen:!0,projectsCollapsed:L.projectsCollapsed,pinnedCollapsed:L.pinnedCollapsed,conversationsCollapsed:L.conversationsCollapsed,projects:_,expandedProjectIds:x,activeProject:g,currentSessionId:J.currentSessionId,loadingSessionId:J.loadingSessionId,sessionViewMode:Te,sessionSortMode:De,globalSessions:Ot,pinnedSessions:Tt,pinnedHasMore:Et,pinnedLoading:Dt,sessionsForProject:kt,projectTimelineSessions:jt,projectTimelineHasMore:Mt,projectTimelineLoading:Nt,globalHasMore:At,globalLoading:Ft,onLoadMoreGlobal:Xt,onLoadMorePinned:Jt,projectHasMore:Pt,projectLoading:It,projectLoaded:Lt,onLoadMoreProject:Qt,onLoadMoreProjectTimeline:$t,sessionTaskStatus:_r,selectingProject:S,onTogglePinnedCollapsed:L.togglePinnedCollapsed,onToggleProjectsCollapsed:L.toggleProjectsCollapsed,onToggleConversationsCollapsed:L.toggleConversationsCollapsed,onToggleProjectExpanded:te,onToggleAllProjectsExpanded:j,onReorderProjects:ne,onSelectProjectDirectory:e?void 0:()=>{Z(),k()},onStartNewProjectChat:Qr,onOpenGlobalSkills:$r,onOpenAgents:ei,onOpenScheduledTasks:ti,onOpenProjectSkills:ni,onOpenProjectInExplorer:e?void 0:e=>{Z(),Br(e).catch(e=>{V.error(`Failed to open project in explorer:`,e),$(e instanceof Error?e.message:W(`openInExplorerFailed`))})},onDeleteProject:Gn,onLoadSession:Xr,onSessionViewModeChange:Ee,onSessionSortModeChange:Oe,onTogglePinSession:er,onDeleteSession:tr,onStartNewGlobalChat:Zr,onOpenSettings:()=>{Z(),sr()},currentServerUrl:t?`云账户远程访问`:o,currentServerAlias:s,onOpenServer:n||t?()=>{Z(),c()}:void 0,updateAvailable:Pn.result.updateAvailable,latestVersion:Pn.result.latestVersion,currentVersion:Pn.result.currentVersion,onOpenUpdate:()=>{Z(),cr()},onDismissUpdate:Pn.dismissUpdate,onToggleSidebar:Z,currentSessionHoverInfo:Ne})})]}):null,(0,K.jsxs)(`main`,{className:G(`flex min-w-0 flex-1 flex-col bg-[var(--quickforge-main-bg)] md:overflow-hidden md:rounded-tl-2xl`),children:[(0,K.jsxs)(`header`,{className:`flex h-14 shrink-0 items-center gap-2 border-b border-[color-mix(in_oklab,var(--border)_34%,transparent)] px-3 pr-20`,children:[(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:`md:hidden`,onClick:()=>L.setMobileSidebarOpen(!0),"aria-label":W(`toggleSidebar`),children:(0,K.jsx)(D,{className:`size-[18px]`})}),(0,K.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,K.jsxs)(`div`,{className:`flex max-w-full min-w-0 items-center gap-2`,children:[(0,K.jsxs)(`div`,{className:`min-w-0`,children:[(0,K.jsx)(`div`,{className:`min-w-0 truncate text-sm font-semibold text-foreground/92`,children:Fn(J.currentTitle,mr?.channelName)}),J.currentToolProject?.name||Fe?.isGitRepository&&Fe.branch?(0,K.jsxs)(`div`,{className:`mt-0.5 flex min-w-0 items-center gap-2 overflow-hidden whitespace-nowrap text-xs leading-none text-muted-foreground sm:hidden`,children:[J.currentToolProject?.name?(0,K.jsxs)(`div`,{className:`flex min-w-0 flex-1 basis-0 items-center gap-1`,title:J.currentToolProject.name,children:[(0,K.jsx)(A,{className:`size-3 shrink-0`}),(0,K.jsx)(`span`,{className:`min-w-0 truncate`,children:J.currentToolProject.name})]}):null,Fe?.isGitRepository&&Fe.branch?(0,K.jsxs)(`div`,{className:`flex min-w-0 flex-1 basis-0 items-center gap-1`,title:Fe.branch,children:[(0,K.jsx)(pe,{className:`size-3 shrink-0`}),(0,K.jsx)(`span`,{className:`min-w-0 truncate`,children:Fe.branch})]}):null]}):null]}),!n&&J.currentToolProject?.name?(0,K.jsxs)(`div`,{className:`hidden h-9 max-w-[220px] shrink-0 items-center gap-2 rounded-full bg-muted/55 px-3 text-sm text-foreground/88 md:inline-flex`,title:J.currentToolProject.name,children:[(0,K.jsx)(A,{className:`size-4 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`min-w-0 truncate`,children:J.currentToolProject.name})]}):null,!n&&J.currentToolProject?.id&&Fe?.isGitRepository&&Fe.branch?(0,K.jsxs)(`div`,{className:`relative hidden shrink-0 md:block`,onClick:e=>e.stopPropagation(),children:[(0,K.jsxs)(`button`,{type:`button`,className:`inline-flex h-9 max-w-[220px] items-center gap-2 rounded-full bg-muted/55 px-3 text-sm text-foreground/88 transition-colors hover:bg-muted`,onClick:()=>Be(e=>!e),"aria-label":W(`gitBranchMenu`),"aria-expanded":ze,children:[(0,K.jsx)(pe,{className:`size-4 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`min-w-0 truncate`,children:Fe.branch}),(0,K.jsx)(y,{className:`size-4 text-muted-foreground`})]}),ze?(0,K.jsx)(Id,{projectId:J.currentToolProject.id,currentBranch:Fe.branch,dirtyCount:Fe.counts?.total??0,onCheckout:En,onCreated:Dn,onOpenGraph:()=>{Be(!1),Ke(!0)},onOpenChanges:()=>{Be(!1),wn()}}):null]}):null,(0,K.jsxs)(`div`,{className:`relative shrink-0`,onClick:e=>e.stopPropagation(),children:[(0,K.jsx)(q,{variant:`ghost`,size:`icon`,className:G(L.conversationMenuOpen&&`bg-muted/45 text-foreground/90`),onClick:()=>L.setConversationMenuOpen(e=>!e),disabled:!J.currentSessionId||le,"aria-label":W(`moreOptions`),"aria-haspopup":`menu`,"aria-expanded":L.conversationMenuOpen,children:(0,K.jsx)(oe,{className:`size-[18px]`})}),L.conversationMenuOpen?(0,K.jsxs)(`div`,{className:G(`fixed inset-x-2 top-14 z-40 max-h-[calc(100dvh-4rem)] overflow-y-auto overscroll-contain rounded-lg border border-border bg-popover p-1 shadow-quickforge md:absolute md:inset-x-auto md:left-0 md:top-full md:z-30 md:mt-1 md:min-w-44 md:max-h-none md:overflow-visible`,n&&`md:fixed md:inset-x-2 md:left-auto md:top-14 md:z-40 md:mt-0 md:max-h-[calc(100dvh-4rem)] md:min-w-0 md:overflow-y-auto lg:inset-x-2 lg:left-auto lg:top-14`),role:`menu`,"aria-label":W(`moreOptions`),children:[(0,K.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`flex h-10 w-full items-center gap-2 whitespace-nowrap rounded-md px-2 text-left text-sm text-foreground/86 transition-colors hover:bg-muted`,onClick:Dr,children:[hr?(0,K.jsx)(b,{className:`size-[18px]`}):(0,K.jsx)(a,{className:`size-[18px]`}),(0,K.jsx)(`span`,{children:W(hr?`unpinSession`:`pinSession`)})]}),(0,K.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`flex h-10 w-full items-center gap-2 whitespace-nowrap rounded-md px-2 text-left text-sm text-foreground/86 transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50`,onClick:()=>{L.setConversationMenuOpen(!1),Wn()},disabled:!jr,title:W(`forkCurrentSessionTitle`),children:[(0,K.jsx)(Ce,{className:`size-[18px]`}),(0,K.jsx)(`span`,{children:W(`forkCurrentSession`)})]}),(0,K.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`flex h-10 w-full items-center gap-2 whitespace-nowrap rounded-md px-2 text-left text-sm text-foreground/86 transition-colors hover:bg-muted`,onClick:Or,children:[(0,K.jsx)(ae,{className:`size-[18px]`}),(0,K.jsx)(`span`,{children:W(`renameSession`)})]}),(0,K.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`flex h-10 w-full items-center gap-2 whitespace-nowrap rounded-md px-2 text-left text-sm text-foreground/86 transition-colors hover:bg-muted`,onClick:kr,children:[(0,K.jsx)(R,{className:`size-[18px]`}),(0,K.jsx)(`span`,{children:W(`shareSession`)})]}),(0,K.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`flex h-10 w-full items-center gap-2 whitespace-nowrap rounded-md px-2 text-left text-sm text-foreground/86 transition-colors hover:bg-muted`,onClick:Mr,children:[(0,K.jsx)(d,{className:`size-[18px]`}),(0,K.jsx)(`span`,{children:W(`archiveSession`)})]})]}):null]})]})})]}),(0,K.jsxs)(`section`,{className:`relative flex min-h-0 flex-1 flex-col`,children:[ct?(0,K.jsx)(Qp,{exiting:dt===ct},ct):null,le?(0,K.jsx)(Kr,{onAddModel:or,onUseExample:()=>{lr().catch(e=>V.error(`Failed to use LiteLLM example:`,e))}}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`div`,{className:G(`flex min-h-0 flex-1 flex-col`,xr?`quickforge-empty-chat`:void 0,dt===ct&&`quickforge-conversation-enter`),children:[xr?(0,K.jsx)(`div`,{className:`quickforge-empty-chat-hero`,"aria-hidden":`true`,children:(0,K.jsx)(`h1`,{className:`quickforge-empty-chat-title`,children:W(`newChatEmptyTitle`)})}):null,(0,K.jsx)(Yt,{children:(0,K.jsx)(H.Suspense,{fallback:(0,K.jsx)(Yp,{}),children:(0,K.jsx)(Fp,{agent:J.agent,onModelSelect:ur,revision:J.chatPanelRevision,agentAccessMode:P,workspaceToolsEnabled:!!J.currentToolProject?.id,project:J.currentToolProject,projectId:J.currentToolProject?.id,chatScope:J.chatScope,onAccessModeChange:Kn,onRollbackFromMessage:zn,onRetryFromMessage:Bn,onCopyAnswer:Vn,onForkFromMessage:Un,onApproveToolCall:qn,onRejectToolCall:Jn,onApproveAutoCompact:Xn,onRejectAutoCompact:Zn,onOpenWorkspaceGitChanges:wn,onOpenLocalFilePath:kn,onArtifactsChange:e=>{we({projectId:J.currentToolProject?.id,sessionId:J.currentSessionId,artifacts:e})},onContextUsageDisplayChange:tn,onInitialRenderReady:vn,onInitialRenderError:yn,capabilities:Mp(J.agent?.harness),disableFork:J.agent?.harness===`opencode`,bypassClientApiKeyCheck:J.agent?.harness===`opencode`,allowModelControls:J.agent?.harness!==`opencode`,restoredDraft:B,onRestoredDraftConsumed:Sn,newChatEmptyState:xr})})}),xr?(0,K.jsx)(Jr,{projects:_,selectedProject:J.chatScope===`project`?J.currentToolProject:void 0,onSelectProject:Cr,onClearProject:wr,onNewProject:Tr}):null]}),Er?(0,K.jsx)(Gr,{hasProject:!!J.currentToolProject?.id,onConfigureModel:or,onAddProject:k,onCopyExamplePrompt:br,onDismiss:yr}):null]})]}),ve&&!e&&J.currentToolProject?.id?(0,K.jsx)(H.Suspense,{fallback:(0,K.jsx)(Yp,{}),children:(0,K.jsx)(Rp,{project:J.currentToolProject,pendingCommand:he,onPendingCommandHandled:vr,onCollapse:()=>ye(!1)})}):null]}),J.currentToolProject?.id?(0,K.jsxs)(K.Fragment,{children:[L.workspaceInspectorOpen?(0,K.jsx)(`div`,{"aria-hidden":`true`,className:`hidden w-px shrink-0 bg-[color-mix(in_oklab,var(--border)_30%,var(--quickforge-sidebar-bg))] lg:block`}):null,(0,K.jsx)(H.Suspense,{fallback:(0,K.jsx)(Xp,{}),children:(0,K.jsx)(Lp,{project:J.currentToolProject,open:L.workspaceInspectorOpen,onOpenChange:L.setWorkspaceInspectorOpen,onOpenCommitPush:()=>We(!0),onOpenProjectInExplorer:e?void 0:Ur,onOpenProjectInVSCode:e?void 0:Wr,onOpenProjectInIDEA:e?void 0:qr,onPreviewArtifact:An,request:L.workspaceInspectorRequest,onRequestHandled:Cn,artifacts:Se.projectId===J.currentToolProject.id&&Se.sessionId===J.currentSessionId?Se.artifacts:[],globalTerminalOpen:e?!1:ve,onShowGlobalTerminal:e?void 0:()=>{z(!1),ye(!0)},onFullscreenChange:xe},J.currentToolProject.id)})]}):null,Ge&&J.currentToolProject?.id?(0,K.jsx)(Yd,{projectId:J.currentToolProject.id,projectName:J.currentToolProject.name,onClose:()=>Ke(!1)}):null,Ue?(0,K.jsx)(Hd,{open:!0,projectId:J.currentToolProject?.id,status:Fe,onClose:()=>We(!1),onCheckout:En,onRefreshStatus:Tn,onStatusChange:Ie,onCompleted:On},J.currentToolProject?.id??`git-commit`):null]}),ot?null:(0,K.jsx)(Zp,{exiting:!0}),(0,K.jsx)(Zt,{open:w,initialPath:g?.path,disabled:S,onOpenChange:ee,onSelect:O}),(0,K.jsx)(et,{open:!!L.skillsDialog,scope:L.skillsDialog?.scope??`global`,project:L.skillsDialog?.project,onOpenChange:e=>{e||L.setSkillsDialog(void 0)},onSaved:ri}),(0,K.jsx)(pf,{open:L.shareDialogOpen,sessionId:J.currentSessionId,title:Fn(J.currentTitle),onOpenChange:L.setShareDialogOpen}),(0,K.jsx)(fd,{toasts:pt,onDismiss:ht,onClick:xn}),(0,K.jsx)(ip,{})]}):(0,K.jsx)(Zp,{})}function im(){if(Ut())return(0,K.jsx)(ep,{});let e=window.location.pathname.match(/^\/share\/([^/]+)\/?$/)?.[1];return e?(0,K.jsx)(H.Suspense,{fallback:(0,K.jsx)(`div`,{className:`flex h-screen items-center justify-center bg-background text-sm text-muted-foreground`,children:W(`loadingChatWorkspace`)}),children:(0,K.jsx)(Ip,{shareId:decodeURIComponent(e)})}):(0,K.jsx)(rm,{})}Tt({hideSelector:!0}),Dt(),Me.isNativePlatform()&&Wt()&&document.documentElement.classList.add(`quickforge-mobile-native`),window.addEventListener(`error`,e=>{V.error(`Uncaught error:`,e.error??e.message)}),window.addEventListener(`unhandledrejection`,e=>{V.error(`Unhandled promise rejection:`,e.reason)}),`serviceWorker`in navigator&&!Me.isNativePlatform()&&window.addEventListener(`load`,()=>{navigator.serviceWorker.register(`/sw.js`).catch(()=>{})}),(0,it.createRoot)(document.getElementById(`root`)).render((0,K.jsx)(H.StrictMode,{children:(0,K.jsx)(h,{strokeWidth:1.75,children:(0,K.jsx)(Yt,{children:(0,K.jsx)(im,{})})})}));export{Tu as $,lr as $t,_d as A,hc as At,Mu as B,Hi as Bt,ff as C,gl as Ct,of as D,Vc as Dt,sf as E,Rc as Et,Cd as F,ts as Ft,wu as G,Sr as Gt,du as H,Fi as Ht,Sd as I,qo as It,_u as J,kr as Jt,Su as K,Ar as Kt,Td as L,ls as Lt,yd as M,pc as Mt,Dd as N,vc as Nt,xd as O,Bc as Ot,Ed as P,lc as Pt,gu as Q,tr as Qt,wd as R,Mo as Rt,uf as S,hl as St,df as T,$c as Tt,xu as U,yi as Ut,Du as V,Pi as Vt,pu as W,Wr as Wt,Eu as X,br as Xt,Cu as Y,xr as Yt,bu as Z,Hn as Zt,$d as _,ht as _n,wl as _t,Cp as a,rr as an,au as at,Qd as b,Al as bt,wp as c,Sn as cn,Kl as ct,yf as d,ln as dn,Rl as dt,ur as en,yu as et,hf as f,on as fn,bl as ft,lf as g,vt as gn,Cl as gt,xf as h,G as hn,Dl as ht,Ep as i,Jn as in,ou as it,gd as j,_c as jt,bd as k,zc as kt,kp as l,xn as ln,Fl as lt,wf as m,q as mn,xl as mt,Np as n,ir as nn,mu as nt,Tp as o,Fn as on,Vl as ot,vf as p,nn as pn,yl as pt,vu as q,Cr as qt,Pp as r,dr as rn,$l as rt,Dp as s,X as sn,Gl as st,Ap as t,$n as tn,hu as tt,mf as u,_n as un,Il as ut,cf as v,gt as vn,Ol as vt,af as w,$ as wt,tf as x,ml as xt,rf as y,W as yn,El as yt,Vu as z,Pa as zt};
|