From ef27841e290e4a6706f194abc78abebeec1018a5 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Mon, 9 Nov 2026 04:24:18 -0800 Subject: [PATCH] refactor: group agent launch, status, and messaging owners (#40313) * refactor: group agent launch, status, and messaging owners * refactor: consolidate direct owner imports * refactor: import pane ownership directly in status listeners --- config/reliability-gates.jsonc | 8 +- .../scripts/ci/sharding/ci-shard-timings.json | 20 +- .../app-shell/startup-window-parity.test.ts | 4 +- .../ClaudeAccountSwitchSessionTree.tsx | 2 +- .../NativeChatResumeOnRestartAgentRow.tsx | 2 +- .../components/NewWorkspaceComposerCard.tsx | 2 +- .../activity/activity-event-state.ts | 9 +- .../activity/activity-thread-detail-pane.tsx | 2 +- .../activity-thread-hover-card-summary.tsx | 2 +- .../activity/activity-thread-presentation.ts | 2 +- .../activity/activity-thread-row.tsx | 2 +- .../activity/useActivityUnreadCount.ts | 2 +- .../AgentSessionContinuationDialog.tsx | 4 +- .../src/components/agent/AgentCombobox.tsx | 5 +- .../components/agent/AgentLaunchPicker.tsx | 3 +- .../agent/AgentLaunchPickerMenu.tsx | 2 +- .../agent/AgentLaunchPickerMenuRow.tsx | 2 +- .../agent/agent-combobox-surface-items.tsx | 7 +- .../agent/icons/AgentIcon.tsx} | 30 +-- .../agent/icons/agent-favicon-assets.ts | 70 ++++++ .../agent/icons}/agent-icon-glyphs.tsx | 2 +- .../agent/icons}/agent-type-icon.tsx | 6 +- .../AgentDefaultSurfacePreviews.tsx | 2 +- .../AutomationAgentLaunchPicker.tsx | 2 +- .../automations/AutomationDetail.tsx | 3 +- .../automations/AutomationEditorDialog.tsx | 2 +- .../AutomationEditorSettingsSidebar.test.tsx | 2 +- .../AutomationEditorSettingsSidebar.tsx | 2 +- .../automations/AutomationListFilterMenu.tsx | 5 +- .../automations/AutomationListLocalRow.tsx | 2 +- .../automations/automation-draft-model.ts | 2 +- .../use-automation-agent-picker-entries.ts | 2 +- .../use-automations-page-store-state.ts | 2 +- .../components/cmd-j/palette-live-status.tsx | 8 +- .../dashboard-popout/AgentKanbanCard.tsx | 2 +- .../dashboard-popout/AgentTerminalDialog.tsx | 2 +- .../dashboard/DashboardAgentRow.tsx | 21 +- .../components/dashboard/useRetainedAgents.ts | 9 +- .../ReviewNotesSendMenuContent.tsx | 16 +- .../review-notes-send-target-order.ts | 2 +- .../MobileEmulatorAgentSetupGuideSteps.tsx | 2 +- .../use-mobile-emulator-agent-setup-state.ts | 2 +- .../ChatUiHereFeatureTipVisual.tsx | 2 +- .../feature-tips/CliSkillSetupPanel.tsx | 5 +- .../feature-tips/CliSkillSetupTerminal.tsx | 2 +- .../feature-tip-session-panel-demo.tsx | 2 +- .../AgentCapabilitiesSetupAction.tsx | 2 +- .../feature-wall/BrowserUseSkillSetupCard.tsx | 2 +- .../feature-wall/FeatureWallBrowserAction.tsx | 4 +- .../feature-wall/OrchestrationSetupCard.tsx | 2 +- .../agent-capability-setup-status.ts | 2 +- .../agents-orchestration/StatusesPage.tsx | 3 +- .../ai-commit-pr-settings-helpers.ts | 2 +- .../use-feature-wall-tour-skills.ts | 5 +- .../feature-wall/useAiCommitPrSettings.ts | 2 +- .../FloatingTerminalOrchestrationDialog.tsx | 2 +- .../FloatingTerminalWindowControls.tsx | 3 +- ...ating-terminal-orchestration-visibility.ts | 2 +- ...se-native-chat-structured-composer-send.ts | 2 +- .../host-access/NativeChatInstallTile.tsx | 2 +- ...native-chat-agent-message-sender-source.ts | 2 +- .../rows/NativeChatAgentMessageCard.tsx | 2 +- .../pane/actions/use-native-chat-hand-off.tsx | 2 +- ...se-native-chat-session-context-actions.tsx | 2 +- .../native-chat-workspace-selection.ts | 6 +- .../serialized-screen-background-rows.test.ts | 2 +- ...se-structured-session-child-row-context.ts | 9 +- .../usage/NativeChatUsageLimitActions.tsx | 2 +- .../onboarding/AgentPickerButton.tsx | 3 +- .../src/components/onboarding/AgentStep.tsx | 2 +- .../onboarding/TerminalLaunchDemo.tsx | 3 +- .../onboarding/YoloPermissionsControl.tsx | 2 +- .../onboarding-completion-agent-launch.ts | 2 +- .../onboarding-feature-setup.test.ts | 2 +- .../onboarding/onboarding-feature-setup.ts | 2 +- .../use-onboarding-agent-surface.ts | 5 +- .../use-onboarding-flow-actions.test.tsx | 4 +- .../onboarding/use-onboarding-flow.ts | 2 +- .../orchestration-crew/CrewAgentIcons.tsx | 6 +- .../src/components/pet/PetOverlay.tsx | 2 +- .../src/components/pet/pet-agent-state.ts | 4 +- .../pull-request-page/checks/fix-launch.ts | 5 +- .../ai-vault/panel/AiVaultPanelControls.tsx | 2 +- .../scanning/AiVaultScanProgressStrip.tsx | 2 +- .../ai-vault-original-pane-index.ts | 2 +- .../session-actions/ai-vault-original-pane.ts | 2 +- .../ai-vault-session-continuation.ts | 2 +- .../ai-vault-session-launch-actions.ts | 2 +- .../ai-vault-session-row-display.tsx | 2 +- .../use-checks-panel-controller-state.tsx | 2 +- .../ai/SourceControlAgentActionDialogForm.tsx | 2 +- .../source-control/ai/controller-types.ts | 2 +- .../source-control/ai/recovery-launch.ts | 2 +- .../ai/runSourceControlAgentActionStart.ts | 2 +- .../ai/source-control-action-model-copy.ts | 2 +- ...urce-control-agent-action-dialog-result.ts | 2 +- ...rce-control-agent-action-dialog-support.ts | 4 +- .../ai/text-generation-dialog-form.tsx | 2 +- .../use-saved-source-control-action-start.ts | 2 +- .../use-source-control-action-agent-choice.ts | 2 +- .../use-source-control-launchable-agents.ts | 2 +- .../ai/useSourceControlAgentActionStart.ts | 2 +- .../sync/use-git-history-commit-actions.ts | 4 +- .../AntigravityAccountsSection.test.tsx | 4 +- .../providers/AntigravityAccountsSection.tsx | 2 +- .../providers/CursorAccountsSection.tsx | 2 +- .../providers/GrokAccountsSection.test.tsx | 2 +- .../providers/GrokAccountsSection.tsx | 2 +- .../usage/ZcodePlanAccountsSection.tsx | 2 +- .../settings/agents/agents-search.ts | 2 +- .../agents/launch/AgentCatalogRow.tsx | 2 +- .../agents/launch/AgentDefaultSetting.tsx | 3 +- .../agents/launch/AgentDetectionCatalog.tsx | 2 +- .../launch/AgentLaunchSettingsCatalog.tsx | 7 +- .../launch/AgentLaunchSettingsSection.tsx | 2 +- .../agent-permission-override-notice.tsx | 2 +- .../surfaces/AgentDefaultSurfaceSection.tsx | 2 +- .../settings/browser/use/BrowserUsePane.tsx | 2 +- .../browser/use/BrowserUseSkillStep.tsx | 2 +- .../settings/chat/ChatAgentLaunchSettings.tsx | 8 +- .../settings/chat/ChatNamingSetting.tsx | 2 +- .../settings/cli/install/CliSection.tsx | 2 +- .../ComputerUseSkillSetupPanel.tsx | 2 +- .../MobileEmulatorAgentControlRow.tsx | 2 +- .../agent-skill-nav-install-status.ts | 10 +- .../use-settings-navigation-model.ts | 7 +- .../orchestration/OrchestrationPane.tsx | 4 +- .../OrchestrationSkillAgentCoverage.tsx | 7 +- .../settings/page/use-settings-store-model.ts | 2 +- .../quick-commands/QuickCommandsList.tsx | 3 +- .../skills/linear/LinearAgentSkillPane.tsx | 2 +- .../SourceControlActionArguments.tsx | 2 +- .../source-control-action-recipe-options.ts | 2 +- .../settings/tasks/TaskSourceLinearSetup.tsx | 2 +- .../use-task-source-provider-readiness.ts | 2 +- .../recipes/EphemeralVmsPane.tsx | 2 +- .../setup-guide/use-setup-guide-progress.ts | 2 +- .../sidebar/LinearAgentSkillSetupDialog.tsx | 2 +- .../sidebar/LinearAgentSkillSetupPrompt.tsx | 4 +- .../sleep/use-worktree-sleep-state.ts | 2 +- ...e-visible-workspace-kanban-worktree-ids.ts | 2 +- .../activity/WorktreeCardAgents.tsx | 6 +- .../activity/title-derived-agent-row-input.ts | 17 ++ .../worktree-agent-activity-summary.ts | 9 +- .../worktree-agent-freshness-selector.ts | 9 +- .../activity/worktree-agent-rows.ts | 11 +- .../activity/worktree-card-agent-summary.ts | 2 +- .../worktree-card-compact-agent-line-order.ts | 4 +- .../worktree-card-compact-agent-row.tsx | 12 +- .../activity/worktree-card-compact-agents.tsx | 2 +- .../worktree-card-idle-child-agents.tsx | 2 +- .../worktree-card-send-target-inputs.ts | 2 +- .../worktree-title-derived-agent-rows.ts | 21 +- .../folder-workspace-composer-submit-input.ts | 2 +- .../folder-workspace-composer-submit.ts | 2 +- .../listing/sleeping-sweep-visibility.ts | 2 +- .../listing/use-agent-send-target.ts | 2 +- .../listing/use-visible-worktrees.ts | 2 +- .../skills/SkillFreshnessStatusPill.tsx | 2 +- .../skills/setup/AgentSkillSetupPanel.tsx | 2 +- .../skills/setup/WslAgentSkillSetupPanel.tsx | 2 +- .../setup/WslLinearAgentSkillInstallCta.tsx | 9 +- .../setup/linear-agent-skill-install-cta.tsx | 7 +- .../src/components/stats/StatsPane.tsx | 2 +- .../status-bar/StatusBarUsageEmptyCta.tsx | 2 +- .../status-bar/StatusBarVisibilityMenu.tsx | 2 +- .../provider-segment-monthly-window.test.tsx | 2 +- .../status-bar-pool-countdown.test.tsx | 4 +- .../src/components/status-bar/tooltip.tsx | 2 +- .../status-bar/usage-pool-label.test.ts | 4 +- ...use-workspace-space-decision-projection.ts | 2 +- .../workspace-space-presentation.ts | 14 +- .../components/tab-bar/QuickLaunchButton.tsx | 5 +- .../src/components/tab-bar/SortableTab.tsx | 2 +- .../tab-bar/TabBarCreateEntryRow.tsx | 2 +- .../tab-bar/TabBarQuickCommandItem.test.tsx | 6 +- .../tab-bar/TabBarQuickCommandItem.tsx | 3 +- .../tab-bar/TabBarQuickCommandsMenu.tsx | 2 +- ...rQuickCommandsMenu.virtualization.test.tsx | 6 +- .../src/components/tab-bar/TabDragPreview.tsx | 2 +- .../tab-bar/TerminalTabLeadingIcon.tsx | 2 +- .../tab-bar/native-chat-tab-agent-evidence.ts | 6 +- .../tab-bar/tab-agent-launch-options.ts | 2 +- .../tab-bar/tab-agent-row-presentation.ts | 2 +- .../tab-bar/terminal-tab-activity-status.ts | 9 +- ...use-new-tab-agent-menu-rows-owner.test.tsx | 2 +- .../tab-bar/use-new-tab-agent-menu-rows.ts | 8 +- .../tab-group/SplitPaneLandingAgentRow.tsx | 5 +- .../tab-moves-drawn-from-frames.test.ts | 4 +- .../components/terminal-agent-tab-shortcut.ts | 4 +- .../agent-status}/agent-idle-edge.ts | 8 +- .../terminal-agent-session-context-copy.ts | 2 +- .../terminal-pane-context-menu-types.ts | 2 +- ...erminal-pane-menu-agent-session-actions.ts | 2 +- .../use-terminal-pane-foundation.ts | 2 +- .../input/keyboard/terminal-ctrl-enter.ts | 4 +- .../keyboard/terminal-windows-shift-enter.ts | 4 +- .../claude-side-question-completion.test.ts | 4 +- .../parked-terminal-byte-watcher.ts | 2 +- .../parked-terminal-command-status.test.ts | 2 +- .../parked-terminal-command-status.ts | 2 +- .../command-inferred-pane-agent.ts | 4 +- .../pane-agent-status-routing.ts | 2 +- .../pane-agent-title-lifecycle.ts | 5 +- .../agent-identity/pane-title-observation.ts | 4 +- ...tion-command-code-status-inference.spec.ts | 35 +-- ...onnection-command-finished-cleanup.spec.ts | 55 +++-- ...nection-command-finished-late-done.test.ts | 12 +- ...onnection-foreground-agent-routing.spec.ts | 40 ++-- ...nnection-foreground-agent-sampling.spec.ts | 15 +- ...connection-foreground-process-exit.spec.ts | 5 +- ...on-foreground-routing-confirmation.spec.ts | 5 +- ...connection-process-exit-row-retire.test.ts | 12 +- ...ty-connection-typed-agent-identity.spec.ts | 90 +++++--- .../renderer-owned-pane-status.ts | 2 +- .../pty-connection/connect-pane-pty.ts | 4 +- ...connection-agent-idle-cursor-reset.spec.ts | 35 +-- ...ty-connection-hidden-codex-queries.spec.ts | 40 ++-- ...-connection-hidden-query-admission.spec.ts | 45 ++-- ...ion-hidden-startup-query-admission.spec.ts | 30 ++- ...nection-main-side-effect-authority.spec.ts | 35 +-- ...connection-mode-2031-subscriptions.spec.ts | 15 +- ...connection-hidden-resize-authority.spec.ts | 5 +- ...-connection-visibility-resume-size.spec.ts | 55 +++-- ...ote-reconnect-unimaged-pane-redraw.test.ts | 6 +- ...-owner-hydration-backend-retention.test.ts | 11 +- ...ection-runtime-owner-spawn-routing.spec.ts | 20 +- ...ion-runtime-pane-transport-routing.spec.ts | 55 +++-- ...and-finished-interrupt-arbitration.spec.ts | 5 +- ...ty-connection-hibernation-activity.spec.ts | 10 +- ...pty-connection-interrupt-inference.spec.ts | 65 +++--- ...nection-native-query-reply-routing.spec.ts | 10 +- ...tion-remote-new-terminal-typeahead.test.ts | 6 +- ...y-connection-terminal-input-gating.spec.ts | 85 ++++--- ...ion-terminal-input-session-listing.spec.ts | 5 +- ...ion-windows-focus-report-authority.spec.ts | 25 ++- ...-connection-deliberate-sleep-guard.spec.ts | 45 ++-- ...nnection-git-bash-console-capacity.test.ts | 12 +- ...-hibernation-kill-shell-foreground.test.ts | 6 +- .../pty-connection-hibernation-wake.spec.ts | 55 +++-- ...-connection-hidden-sleeping-resume.spec.ts | 56 +++-- ...n-provider-rebind-callback-fencing.spec.ts | 15 +- .../pty-connection-pty-exit-teardown.spec.ts | 85 ++++--- ...nection-pty-shutdown-exit-deferral.spec.ts | 16 +- .../pty-connection-session-liveness.spec.ts | 60 +++-- ...ction-hook-completion-side-effects.spec.ts | 20 +- ...y-connection-hook-idle-arbitration.test.ts | 22 +- ...ction-notification-settings-gating.spec.ts | 15 +- ...-connection-task-complete-dispatch.spec.ts | 15 +- ...-output-restore-unavailable-banner.test.ts | 6 +- ...ry-carry-osc-introducer-leak.repro.test.ts | 4 +- ...tion-hidden-backlog-reconciliation.spec.ts | 5 +- ...connection-hidden-backlog-snapshot.test.ts | 26 ++- ...ty-connection-hidden-delivery-gate.spec.ts | 5 +- ...y-connection-hidden-output-restore.spec.ts | 30 ++- ...on-hidden-query-snapshot-authority.spec.ts | 30 ++- ...ection-hidden-restore-fit-overflow.test.ts | 7 +- ...ion-hidden-restore-loss-disclosure.test.ts | 11 +- ...tion-hidden-restore-marker-handoff.test.ts | 6 +- ...connection-hidden-runtime-snapshot.test.ts | 10 +- ...ction-hidden-snapshot-live-overlap.spec.ts | 15 +- ...ion-hidden-snapshot-resize-signals.spec.ts | 25 ++- ...n-post-dispose-restore-termination.test.ts | 6 +- ...onnection-remote-pause-drop-notice.spec.ts | 5 +- ...connection-replay-payload-handling.spec.ts | 70 +++--- ...ection-restored-baseline-shortfall.test.ts | 6 +- ...-connection-stalled-hidden-restore.spec.ts | 55 +++-- ...on-visible-pane-output-pause-latch.test.ts | 6 +- ...ote-park-reveal-unverifiable-retry.test.ts | 6 +- ...y-connection-foreground-write-path.spec.ts | 50 +++-- ...onnection-hidden-output-scheduling.spec.ts | 45 ++-- ...ty-connection-agent-session-resume.spec.ts | 25 ++- ...nnection-cold-restore-agent-resume.spec.ts | 30 ++- ...ty-connection-cold-restore-repaint.spec.ts | 20 +- ...ection-cold-restore-resume-command.spec.ts | 20 +- ...-connection-daemon-snapshot-replay.spec.ts | 211 ++++-------------- ...tion-deferred-reattach-live-output.spec.ts | 45 ++-- .../pty-connection-owner-error-retry.spec.ts | 15 +- ...nection-park-reveal-model-snapshot.spec.ts | 5 +- .../pty-connection-reattach-binding.test.ts | 73 ++++-- ...pty-connection-reattach-mode-reset.spec.ts | 70 +++--- ...y-connection-remote-runtime-attach.spec.ts | 20 +- ...ection-remote-snapshot-image-title.test.ts | 6 +- ...tion-restored-runtime-pane-binding.spec.ts | 10 +- ...ction-stale-daemon-snapshot-replay.spec.ts | 188 ++++++++++++++++ .../pty-connection-fresh-spawn-guards.spec.ts | 85 ++++--- ...connection-main-pane-restore-start.test.ts | 4 +- .../pty-connection-main-pane-start.test.ts | 8 +- .../pty-connection-pending-spawn.spec.ts | 10 +- ...ion-restart-replacement-stop-claim.spec.ts | 5 +- ...-connection-sleeping-resume-banner.spec.ts | 25 ++- ...ty-connection-spawn-deferred-sleep.test.ts | 30 ++- .../spawn/pty-connection-split-spawn.spec.ts | 50 +++-- .../agent-pre-ready-typed-draft.test.ts | 14 +- .../startup/agent-pre-ready-typed-draft.ts | 4 +- .../startup/cold-restore-resume-startup.ts | 2 +- ...-agent-startup-launch-registration.spec.ts | 10 +- ...-connection-queued-startup-consume.test.ts | 14 +- ...ty-connection-split-cwd-resolution.test.ts | 6 +- ...onnection-startup-command-delivery.spec.ts | 15 +- ...-connection-startup-draft-delivery.spec.ts | 21 +- .../startup/sleeping-record-access.ts | 2 +- .../startup/startup-draft-paste.ts | 2 +- .../pty-connection-mocks.spec.ts | 2 +- .../pty-connection-test-environment.ts | 4 +- ...ty-connection-test-hidden-restore-flood.ts | 4 +- ...-connection-kitty-keyboard-restore.spec.ts | 10 +- .../ipc/pty-transport-connect-spawn.test.ts | 5 +- .../remote-runtime-pty-transport.ts | 2 +- .../TerminalQuickCommandsSubmenu.tsx | 2 +- .../terminal-agent-session-continuation.ts | 2 +- .../terminal-agent-session-fork.ts | 2 +- ...ote-snapshot-alt-screen-host-chain.test.ts | 6 +- .../remote-snapshot-alt-screen-replay.test.ts | 6 +- .../TerminalQuickCommandDialog.tsx | 2 +- .../terminal-quick-command-agent-options.ts | 2 +- .../components/terminal-workspace-keydown.ts | 2 +- ...orktree-jump-palette-workspace-tab-row.tsx | 2 +- .../hooks/agent-hook-turn-end-ownership.ts | 4 +- .../composer-state/host-runtime-effects.ts | 2 +- .../composer-state/quick-creation-request.ts | 2 +- .../composer-state/quick-startup-plan.ts | 2 +- .../workspace-identity-state.ts | 2 +- .../agent-status-event-applicator.ts | 2 +- .../ipc-events/agent-status-listeners.ts | 2 +- .../hooks/ipc-events/agent-status-routing.ts | 2 - ...minal-request-ipc-bridge-placement.test.ts | 4 +- .../src/hooks/use-linear-agent-skill-setup.ts | 4 +- .../use-local-cli-skill-freshness-name.ts | 2 +- .../src/hooks/use-onboarding-skill-runtime.ts | 5 +- .../src/hooks/useInstalledAgentSkills.ts | 4 +- .../src/lib/activity-thread-display.ts | 4 +- .../agent-catalog-entries-primary.ts | 4 +- .../agent-catalog-entries-secondary.ts | 0 .../agent-catalog-entries.ts | 2 +- .../agent-catalog-platform.ts | 0 .../src/lib/agent-catalog/agent-catalog.ts | 31 +++ .../agent-picker-search.ts | 4 +- src/renderer/src/lib/agent-favicon-assets.ts | 70 ------ .../agent-account-restart-startup.test.ts | 4 +- .../accounts/agent-account-restart-startup.ts | 2 +- .../context}/agent-session-continuation.ts | 8 +- .../context}/agent-session-fork-context.ts | 2 +- .../context}/copy-agent-session-context.ts | 0 .../launch-agent-session-continuation.ts | 6 +- .../launch/failure}/agent-launch-failure.ts | 6 +- .../agent-detection-target-inventory.ts | 14 +- .../native-chat-provider-choice.test.tsx | 2 +- .../launch/native-chat-provider-choice.ts | 2 +- ...ent-launch-caller-prompt-transport.test.ts | 4 +- .../agent-launch-caller-routing.test.ts | 8 +- .../agent-tab-launch-outcome.test-fixture.ts | 2 +- ...unch-agent-in-new-tab-main-surface.test.ts | 2 +- .../launch-agent-in-new-tab-test-fixture.ts | 8 +- ...h-agent-in-new-tab-windows-quoting.test.ts | 2 +- .../launch-agent-in-new-tab.test-fixture.ts | 4 +- .../new-tab/launch-agent-in-new-tab.test.ts | 2 +- .../launch/new-tab/launch-agent-in-new-tab.ts | 2 +- ...agent-new-tab-host-route-readiness.test.ts | 5 +- ...unch-agent-structured-chat-test-fixture.ts | 10 +- .../new-tab/launch-agent-tab-refusal.ts | 5 +- ...nt-launch-pane-verdict-application.test.ts | 4 +- .../agent-launch-tab-main-written.test.ts | 4 +- .../pane/agent-launch-tab-publication.test.ts | 4 +- .../pane/agent-launch-through-host.test.ts | 4 +- .../prompt/agent-launch-prompt-delivery.ts | 4 +- .../agent-launch-prompt-failure-notice.ts | 4 +- .../launch/routing}/agent-menu-selection.ts | 12 +- .../routing/agent-session-launch-plan.ts | 5 +- .../routing}/new-tab-agent-menu-rows.ts | 4 +- .../launch/shortcuts}/agent-tab-shortcuts.ts | 20 +- ...gent-startup-delayed-delivery-perf.test.ts | 2 +- .../agent-startup-delayed-delivery.ts | 6 +- .../startup}/agent-startup-delivery-guards.ts | 0 ...ructured-agent-session-launch-admission.ts | 2 +- ...agent-session-launch-after-failure.test.ts | 2 +- ...ed-agent-session-launch-close-race.test.ts | 2 +- ...-session-launch-completion.test-fixture.ts | 2 +- ...t-session-launch-different-request.test.ts | 2 +- ...-agent-session-launch-exited-owner.test.ts | 2 +- ...agent-session-launch-join-delivery.test.ts | 2 +- .../structured-agent-session-launch-label.ts | 2 +- ...tured-agent-session-launch-options.test.ts | 2 +- ...d-agent-session-launch-outcome-tracking.ts | 2 +- ...ent-session-launch-resume-identity.test.ts | 2 +- ...launch-selection-admission.test-fixture.ts | 2 +- ...sion-launch-unconfirmed-or-retried.test.ts | 2 +- ...tured-agent-session-launch.test-fixture.ts | 2 +- ...-agent-session-new-chat-own-launch.test.ts | 2 +- .../messaging}/agent-message-send.test.ts | 12 +- .../messaging}/agent-message-send.ts | 16 +- .../messaging}/agent-message-target.ts | 0 .../agent-send-disabled-reason-label.ts | 0 .../messaging}/agent-send-title-status.ts | 11 +- .../messaging}/notes-send-agent-targets.ts | 15 +- .../paste}/agent-draft-paste-content.ts | 8 +- .../messaging/paste}/agent-draft-readiness.ts | 6 +- .../paste}/agent-followup-delivery.ts | 8 +- .../paste}/agent-native-draft-prefill.ts | 4 +- .../agent-paste-draft-submit-retry.test.ts | 23 +- .../paste}/agent-paste-draft.test.ts | 26 ++- .../messaging/paste}/agent-paste-draft.ts | 26 +-- .../messaging/paste}/agent-ready-wait.ts | 10 +- .../messaging}/running-agent-targets.ts | 14 +- .../active-agent-note-send-delivery.ts | 8 +- .../active-agent-note-send-diagnostics.ts | 2 +- ...ve-agent-note-send-explicit-target.test.ts | 2 +- ...ve-agent-note-send-focused-session.test.ts | 2 +- .../active-agent-note-send-result.ts | 2 +- .../active-agent-note-send-test-harness.ts | 4 +- .../terminal}/active-agent-note-send.ts | 20 +- .../terminal}/active-agent-note-target.ts | 32 +-- .../active-agent-terminal-send-readiness.ts | 6 +- .../navigation}/claude-agent-row-view.ts | 12 +- .../agent-resume-launch-target.test.ts | 0 .../resume}/agent-resume-launch-target.ts | 14 +- .../resume/sleeping-agent-session-launch.ts | 2 +- .../aggregation/worktree-agent-status.ts} | 35 +-- .../evidence}/agent-status-epoch-clock.ts | 0 .../evidence}/agent-status-epoch-selector.ts | 0 .../evidence}/agent-status-terminal-title.ts | 8 +- .../evidence}/pane-agent-evidence.ts | 45 +--- .../agent-status-connection-ownership.ts | 6 +- .../ownership}/agent-status-pane-ownership.ts | 10 +- .../presentation}/agent-row-dot-state.ts | 8 +- .../presentation}/agent-row-stopping-label.ts | 6 +- .../presentation}/agent-row-tool-preview.ts | 8 +- .../agent-verdict-status-line.ts | 6 +- .../lib/command-code-prompt-status-seed.ts | 2 +- .../lib/desktop-created-server-tabs.test.ts | 4 +- .../src/lib/environment-setup-agent-launch.ts | 2 +- .../src/lib/fix-checks-agent-launch.ts | 2 +- .../src/lib/host-chat-program-acquisition.ts | 2 +- .../src/lib/host-chat-program.test.ts | 2 +- src/renderer/src/lib/host-chat-program.ts | 2 +- .../lib/launch-agent-hosted-prompt.test.ts | 4 +- src/renderer/src/lib/linear-usage-examples.ts | 2 +- .../src/lib/new-agent-prompt-outcome.ts | 2 +- src/renderer/src/lib/new-workspace.test.ts | 4 +- src/renderer/src/lib/new-workspace.ts | 6 +- .../src/lib/onboarding-folder-agent-launch.ts | 5 +- .../src/lib/recent-workspace-tab-rows.ts | 9 +- .../lib/{ => skills}/agent-skill-coverage.ts | 6 +- .../agent-feature-install-commands.ts | 2 +- .../agent-feature-skill-names.ts | 0 .../agent-skill-cli-prerequisite.test.ts | 2 +- .../agent-skill-cli-prerequisite.ts | 2 +- .../linear-agent-skill-update-target.ts | 7 +- .../orchestration-skill-coverage.ts | 10 +- .../skill-freshness-display-status.ts | 4 +- .../ai/source-control-agent-picker.ts | 2 +- .../src/lib/text-generation-error-copy.ts | 2 +- .../agent-output-error-copy.ts | 2 +- .../lib/web-host-agent-launch-completion.ts | 2 +- .../active-worktree-removal-successor.test.ts | 4 +- .../empty-workspace-default-agent-chat.ts | 2 +- .../launch-work-item-direct-agent-routing.ts | 4 +- .../launch-work-item-direct-messages.ts | 4 +- .../launch-work-item-direct-preflight.ts | 4 +- ...unch-work-item-direct-route-preparation.ts | 2 +- .../launch-work-item-direct-setup.test.tsx | 2 +- .../launch-work-item-direct-test-fixture.ts | 2 +- .../launch-work-item-direct-types.ts | 2 +- .../work-item/launch-work-item-direct.ts | 2 +- .../workspace-terminal-host-authority.test.ts | 4 +- .../src/lib/worktree-activity-state.ts | 2 +- src/renderer/src/lib/worktree-status.ts | 6 +- ...b-runtime-terminal-prompt-delivery.test.ts | 4 +- .../agent-catalogs}/chat-provider-agents.ts | 4 +- .../legacy-chat-rename-migration.test.tsx | 2 +- ...c-runtime-graph-conversion-publish.test.ts | 4 +- .../mirrored-agent-status-clock-skew.test.ts | 9 +- ...tabs-sync-remote-status-title-flap.test.ts | 9 +- .../frames/divider-ratio-refusal.test.ts | 4 +- ...ayout-changes-during-stream-outage.test.ts | 4 +- .../pane-titles-drawn-from-frames.test.ts | 4 +- .../workspace-layout-frame-binding.test.ts | 4 +- ...orkspace-layout-frame-editor-views.test.ts | 4 +- .../workspace-layout-frame-held-tabs.test.ts | 4 +- .../workspace-layout-frame-sync.test.ts | 4 +- .../workspace-layout-frame-tab-props.test.ts | 4 +- .../server/server-held-panes.test.tsx | 4 +- .../server/server-layout-apply.test.ts | 4 +- .../server-layout-editor-handover.test.ts | 4 +- .../server-layout-frames-handover.test.ts | 4 +- .../server-layout-frames-held-tabs.test.ts | 4 +- .../server/server-layout-frames.test.ts | 4 +- .../repos/store-session-cascades.test.ts | 4 +- .../agent-status/agent-status-live-actions.ts | 2 +- .../agent-status-worktree-purge-leak.test.ts | 4 +- .../cleanup/browser-cleanup-close.test.ts | 4 +- .../browser-close-focused-group.test.ts | 4 +- .../browser-close-mru-selection.test.ts | 4 +- .../browser-mount-admission-removal.test.ts | 4 +- .../store-session-browser-hydration.test.ts | 4 +- .../pages/browser-page-conversion.test.ts | 4 +- .../browser-workspace-doc-location.test.ts | 4 +- .../browser-background-tab-creation.test.ts | 4 +- .../browser-tab-creation-placement.test.ts | 4 +- .../slices/diff-comments/diffComments.test.ts | 2 +- .../editor-session-duplicate-restore.test.ts | 4 +- .../store-session-editor-hydration.test.ts | 4 +- .../editor-state-worktree-purge-leak.test.ts | 4 +- .../tabs/editor-tab-layout-owner.test.ts | 4 +- .../store/slices/settings/settings.test.ts | 2 +- .../content-tabs-from-main-frames.test.ts | 4 +- .../tabs/recently-closed-tab-position.test.ts | 4 +- .../slices/tabs/recently-closed-tabs.test.ts | 4 +- .../store-open-to-side-layout-owner.test.ts | 4 +- .../tabs/tabs-label-and-pin-state.test.ts | 4 +- .../tabs/tabs-model-reconciliation.test.ts | 4 +- .../tabs/tabs-open-close-lifecycle.test.ts | 4 +- .../tabs/tabs-pane-layout-operations.test.ts | 4 +- .../slices/tabs/tabs-split-create.test.ts | 4 +- .../slices/tabs/tabs-unread-and-focus.test.ts | 4 +- .../slices/ui/ui-agent-send-target.test.ts | 8 +- .../slices/ui/ui-feature-interactions.test.ts | 8 +- .../store/slices/ui/ui-slice-agent-actions.ts | 11 +- .../workspace-cleanup-local-evidence.ts | 4 +- .../store-active-worktree-selection.test.ts | 4 +- ...wner-warning-worktree-removal-leak.test.ts | 4 +- ...-worktree-purge-terminal-maps-leak.test.ts | 4 +- ...tion-records-worktree-removal-leak.test.ts | 4 +- .../native-chat-launch-draft-teardown.test.ts | 4 +- .../removed-worktree-renderer-teardown.ts | 2 +- .../store-worktree-removal-cascade.test.ts | 4 +- ...tab-worktree-orphan-map-purge-leak.test.ts | 6 +- .../workspace-chat-draft-removal.test.ts | 4 +- .../teardown/worktree-purge-doomed-ids.ts | 2 +- .../recently-closed-terminal-tabs.test.ts | 4 +- .../retired-terminal-tab-state-sweep.ts | 2 +- .../store-create-tab-start-in-main.test.ts | 4 +- .../store-session-terminal-reconnect.test.ts | 4 +- .../store-session-workspace-hydration.test.ts | 4 +- ...store-sleep-agent-status-retention.test.ts | 4 +- .../store-sleep-exact-runtime-stop.test.ts | 4 +- .../store-sleep-pane-hibernation.test.ts | 4 +- .../store-sleep-runtime-convergence.test.ts | 4 +- .../store-sleep-twin-host-owner.test.ts | 4 +- ...terminal-active-workspace-creation.test.ts | 4 +- ...terminal-creation-orphan-retention.test.ts | 4 +- .../terminals/terminal-ephemeral-state.ts | 4 +- ...erminal-input-activity-store-write.test.ts | 4 +- .../terminals/terminal-last-tab-close.test.ts | 4 +- ...minal-pty-release-orphan-retention.test.ts | 4 +- .../terminal-tab-close-intent.test.ts | 4 +- .../terminals/terminal-tab-presentation.ts | 6 +- .../terminals/terminal-transient-state.ts | 4 +- ...workspace-layout-frame-store-patch.test.ts | 4 +- .../agent-status-evidence-clock.test.ts | 14 +- .../title/agent-title-tracker.test.ts} | 2 +- tests/e2e/claude-agent-row-view.unit.test.ts | 5 +- ...nch-settings-hook-bookkeeping.unit.test.ts | 2 +- ...-agent-in-new-tab-web-runtime.unit.test.ts | 4 +- .../launch-agent-web-terminal.test-fixture.ts | 4 +- ...-tabs-decorative-title-fanout.unit.test.ts | 17 +- ...al-agent-fork-draft-ownership.unit.test.ts | 4 +- .../terminal-agent-pane-launch.unit.test.ts | 4 +- .../omp-picker-search-rendered/fixture.tsx | 2 +- 559 files changed, 2828 insertions(+), 2099 deletions(-) rename src/renderer/src/{lib/agent-catalog.tsx => components/agent/icons/AgentIcon.tsx} (68%) create mode 100644 src/renderer/src/components/agent/icons/agent-favicon-assets.ts rename src/renderer/src/{lib => components/agent/icons}/agent-icon-glyphs.tsx (99%) rename src/renderer/src/{lib => components/agent/icons}/agent-type-icon.tsx (80%) rename src/renderer/src/{lib => components/settings/navigation}/agent-skill-nav-install-status.ts (65%) create mode 100644 src/renderer/src/components/sidebar/workspace-card/activity/title-derived-agent-row-input.ts rename src/renderer/src/{lib => components/terminal-pane/agent-status}/agent-idle-edge.ts (56%) create mode 100644 src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-stale-daemon-snapshot-replay.spec.ts rename src/renderer/src/lib/{ => agent-catalog}/agent-catalog-entries-primary.ts (97%) rename src/renderer/src/lib/{ => agent-catalog}/agent-catalog-entries-secondary.ts (100%) rename src/renderer/src/lib/{ => agent-catalog}/agent-catalog-entries.ts (82%) rename src/renderer/src/lib/{ => agent-catalog}/agent-catalog-platform.ts (100%) create mode 100644 src/renderer/src/lib/agent-catalog/agent-catalog.ts rename src/renderer/src/lib/{ => agent-catalog}/agent-picker-search.ts (97%) delete mode 100644 src/renderer/src/lib/agent-favicon-assets.ts rename src/renderer/src/lib/{ => agent-session/context}/agent-session-continuation.ts (95%) rename src/renderer/src/lib/{ => agent-session/context}/agent-session-fork-context.ts (97%) rename src/renderer/src/lib/{ => agent-session/context}/copy-agent-session-context.ts (100%) rename src/renderer/src/lib/{ => agent-session/launch/failure}/agent-launch-failure.ts (86%) rename src/renderer/src/lib/{ => agent-session/launch/inventory}/agent-detection-target-inventory.ts (93%) rename src/renderer/src/lib/{ => agent-session/launch/new-tab}/agent-tab-launch-outcome.test-fixture.ts (65%) rename src/renderer/src/lib/{ => agent-session/launch/prompt}/agent-launch-prompt-failure-notice.ts (79%) rename src/renderer/src/lib/{ => agent-session/launch/routing}/agent-menu-selection.ts (78%) rename src/renderer/src/lib/{ => agent-session/launch/routing}/new-tab-agent-menu-rows.ts (81%) rename src/renderer/src/lib/{ => agent-session/launch/shortcuts}/agent-tab-shortcuts.ts (86%) rename src/renderer/src/lib/{ => agent-session/launch/startup}/agent-startup-delayed-delivery-perf.test.ts (98%) rename src/renderer/src/lib/{ => agent-session/launch/startup}/agent-startup-delayed-delivery.ts (97%) rename src/renderer/src/lib/{ => agent-session/launch/startup}/agent-startup-delivery-guards.ts (100%) rename src/renderer/src/lib/{ => agent-session/messaging}/agent-message-send.test.ts (88%) rename src/renderer/src/lib/{ => agent-session/messaging}/agent-message-send.ts (85%) rename src/renderer/src/lib/{ => agent-session/messaging}/agent-message-target.ts (100%) rename src/renderer/src/lib/{ => agent-session/messaging}/agent-send-disabled-reason-label.ts (100%) rename src/renderer/src/lib/{ => agent-session/messaging}/agent-send-title-status.ts (64%) rename src/renderer/src/lib/{ => agent-session/messaging}/notes-send-agent-targets.ts (92%) rename src/renderer/src/lib/{ => agent-session/messaging/paste}/agent-draft-paste-content.ts (95%) rename src/renderer/src/lib/{ => agent-session/messaging/paste}/agent-draft-readiness.ts (90%) rename src/renderer/src/lib/{ => agent-session/messaging/paste}/agent-followup-delivery.ts (85%) rename src/renderer/src/lib/{ => agent-session/messaging/paste}/agent-native-draft-prefill.ts (70%) rename src/renderer/src/lib/{ => agent-session/messaging/paste}/agent-paste-draft-submit-retry.test.ts (89%) rename src/renderer/src/lib/{ => agent-session/messaging/paste}/agent-paste-draft.test.ts (92%) rename src/renderer/src/lib/{ => agent-session/messaging/paste}/agent-paste-draft.ts (91%) rename src/renderer/src/lib/{ => agent-session/messaging/paste}/agent-ready-wait.ts (86%) rename src/renderer/src/lib/{ => agent-session/messaging}/running-agent-targets.ts (92%) rename src/renderer/src/lib/{ => agent-session/messaging/terminal}/active-agent-note-send-delivery.ts (94%) rename src/renderer/src/lib/{ => agent-session/messaging/terminal}/active-agent-note-send-diagnostics.ts (96%) rename src/renderer/src/lib/{ => agent-session/messaging/terminal}/active-agent-note-send-explicit-target.test.ts (99%) rename src/renderer/src/lib/{ => agent-session/messaging/terminal}/active-agent-note-send-focused-session.test.ts (99%) rename src/renderer/src/lib/{ => agent-session/messaging/terminal}/active-agent-note-send-result.ts (95%) rename src/renderer/src/lib/{ => agent-session/messaging/terminal}/active-agent-note-send-test-harness.ts (86%) rename src/renderer/src/lib/{ => agent-session/messaging/terminal}/active-agent-note-send.ts (91%) rename src/renderer/src/lib/{ => agent-session/messaging/terminal}/active-agent-note-target.ts (85%) rename src/renderer/src/lib/{ => agent-session/messaging/terminal}/active-agent-terminal-send-readiness.ts (92%) rename src/renderer/src/lib/{ => agent-session/navigation}/claude-agent-row-view.ts (92%) rename src/renderer/src/lib/{ => agent-session/resume}/agent-resume-launch-target.test.ts (100%) rename src/renderer/src/lib/{ => agent-session/resume}/agent-resume-launch-target.ts (92%) rename src/renderer/src/lib/{agent-status.ts => agent-status/aggregation/worktree-agent-status.ts} (75%) rename src/renderer/src/lib/{ => agent-status/evidence}/agent-status-epoch-clock.ts (100%) rename src/renderer/src/lib/{ => agent-status/evidence}/agent-status-epoch-selector.ts (100%) rename src/renderer/src/lib/{ => agent-status/evidence}/agent-status-terminal-title.ts (77%) rename src/renderer/src/lib/{ => agent-status/evidence}/pane-agent-evidence.ts (51%) rename src/renderer/src/lib/{ => agent-status/ownership}/agent-status-connection-ownership.ts (93%) rename src/renderer/src/lib/{ => agent-status/ownership}/agent-status-pane-ownership.ts (90%) rename src/renderer/src/lib/{ => agent-status/presentation}/agent-row-dot-state.ts (73%) rename src/renderer/src/lib/{ => agent-status/presentation}/agent-row-stopping-label.ts (65%) rename src/renderer/src/lib/{ => agent-status/presentation}/agent-row-tool-preview.ts (73%) rename src/renderer/src/lib/{ => agent-status/presentation}/agent-verdict-status-line.ts (82%) rename src/renderer/src/lib/{ => skills}/agent-skill-coverage.ts (79%) rename src/renderer/src/lib/{ => skills/installation}/agent-feature-install-commands.ts (92%) rename src/renderer/src/lib/{ => skills/installation}/agent-feature-skill-names.ts (100%) rename src/renderer/src/lib/{ => skills/installation}/agent-skill-cli-prerequisite.test.ts (95%) rename src/renderer/src/lib/{ => skills/installation}/agent-skill-cli-prerequisite.ts (98%) rename src/renderer/src/lib/{ => skills/installation}/linear-agent-skill-update-target.ts (83%) rename src/renderer/src/lib/{ => skills}/orchestration-skill-coverage.ts (83%) rename src/renderer/src/lib/{ => skills/presentation}/skill-freshness-display-status.ts (92%) rename src/renderer/src/lib/{ => text-generation}/agent-output-error-copy.ts (99%) rename src/renderer/src/{lib => runtime/native-chat/agent-catalogs}/chat-provider-agents.ts (85%) rename src/{renderer/src/lib => shared/agent-status/contracts}/agent-status-evidence-clock.test.ts (70%) rename src/{renderer/src/lib/agent-status.test.ts => shared/agent-status/title/agent-title-tracker.test.ts} (95%) diff --git a/config/reliability-gates.jsonc b/config/reliability-gates.jsonc index 8cbb85016c2..8ede8e6f99d 100644 --- a/config/reliability-gates.jsonc +++ b/config/reliability-gates.jsonc @@ -459,10 +459,10 @@ "invariant": "A prompt occurrence leaves the input region only when an accepted reply answers it (a current host's provider acknowledgment, or an older host's whole-write acceptance as before) or the user collapses it to a strip above the composer, which writes nothing and keeps the card mounted with its partial answer; status-backed occurrences are told apart by the host wait's start, so view toggles and remounts preserve them while real clear/replacement supersedes them, and a transcript-only one is dropped when the view stops observing it; obsolete results cannot change replacements; selector groups wait for complete writes before pacing; refusal or unknown handoff never causes replay; a card retires an unsubmitted composer send without writing under it or losing its text, and the hidden composer cannot send or interrupt; Collapse or Escape folds a card without writing, never during an in-flight answer, and a new occurrence shows expanded again; the phone blocks only Send while a card is expanded and shows one card per occurrence; cancellation stops unsent groups and active dictation can stop.", "oracle": "Audit2251 narrows agent-paste-draft.test.ts from 25 authored cases (26 literal cases) to four. Retained cases cover buffered readiness on PTY binding, separate spawn/composer lifetimes, real per-PTY paste/Enter serialization against a competing paste, and frame closure/no Enter after a rejected content chunk. Intentionally lost alarms include agent marker and fallback examples, direct-write failure/rejection, missing-PTY and Codex process-only timeout paths, exact nonprimary-PTY routing, full large-body chunk reconstruction, escaping/CRLF samples, internal laziness/yield work assertions, oversized preflight refusal, and exact configured delay/budget counts. No equivalent replacement, new execution, real PTY/provider delivery, rendered/native UI, deployment, measured performance or cross-platform result is claimed. Historical prior account (preserved verbatim): Mobile owner-layout policy retires whole tests and mixed registrations without equivalent replacement coverage. Retained callbacks and reduced selectors need fresh execution at their stated scope; prior measurements do not validate them. Historical oracle: Audit2003: Remove agent-prompt absence routing, throwing/live/missing-probe and cached-probe-count examples from the stale-leaf source. Controller-proven absence, unknown-liveness admission, obsolete-absence clearing and same-ID respawn fences remain at a supplied provider/row seam. Preserve the independent wire-codec receipt only in its original scope. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1991: Remove partial-runtime terminal-send guard/status/floor/query projection and argument-inventory samples. Retained RPC viewport admission, authenticated-client spoof refusal, text admission and stale-binding fences remain bounded mock-boundary behavior. The unchanged wire-codec receipt remains valid only for its original command; it does not validate this reduced RPC selector. Changed-source prior results do not validate reduced-source bytes. No fresh execution, equivalent replacement, red/green, measured budget, soak, physical provider/PTY, rendered, live remote/mobile or cross-platform result is claimed. Historical prior account (preserved verbatim): Audit1908 removes the complete prompt-presentation hook and literal interactive-protocol mapping suites and narrows the interactive card and prompt-card input suites. Lost alarms include replacement approval A settling after answered B; collapse/expand composer ownership and partial-answer presentation; identical new waits after an unmounted view; collapsed transcript re-reads; answered/dismissed status-backed persistence and retirement; and literal answer-to-PTY byte arrays. The retained stale-PTY acknowledgment, cancellation/answer retry, and answered-approval remount/rebind assertions remain meaningful but are not equivalent replacement coverage. No fresh reduced-selector result, physical provider, rendered/native-focus, mixed-version deployment, soak, or measured-budget validation is claimed. The unchanged wire-codec receipt remains valid only for its exact command. Historical prior account (preserved verbatim): Retained exact unchanged-source receipts remain the only current execution evidence. Reduced selectors have no fresh execution result. Historical pre-audit oracle account for changed sources: Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: Existing exact unchanged-selector receipts remain the only current execution evidence. Changed source selectors have no fresh execution result. Historical prior-source oracle account: Retained unchanged-selector receipts are the only current execution evidence. Reduced-source assertions await validation. Historical prior oracle: The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): The retained unchanged-source receipts are the only current execution evidence; reduced-source assertions await validation. Historical oracle account (not a current claim for changed sources): After acknowledged phone replies with stale host status, the exact card disappears and Send is enabled; unknown, refused or unverifiable-settlement replies retain enabled choices, while an older host's accepted reply dismisses like an acknowledged one; a same-occurrence view toggle retains pending acknowledgment and real replacements discard it. A slow 32 KiB SSH answer completes all chunks before Enter; cancellation preserves issued bytes but omits remaining groups. Paired settlement invokes the actual provider and lost callbacks remain unknown; older hosts deliver ordinary messages, launch and selector groups once and their accepted answers dismiss as before. An answered card stays hidden across a view remount; a collapsed card is a strip that frees the composer and expands back; an identical question in a new wait shows again; a composer send caught by a new card keeps its bubble without submitting or clearing the line under it. Audit2450 removes the MobileNativeChatView failure-banner callback-only example whose old banner is supplied unchanged by its props. Retain fatal-read gating and the ordering test that preserves a new delivery notice. The removed false-send/old-banner combination has no equivalent replacement; prior raw receipts and budgets retain their original source scope. No new soak, platform, performance or red/green claim.", "commands": [ - "ORCA_BACKGROUND_LAUNCH=1 pnpm test src/renderer/src/components/native-chat/prompts/NativeChatInteractiveCard.test.tsx src/renderer/src/components/native-chat/prompts/NativeChatResolvedView.prompt-card-input.test.tsx src/renderer/src/components/native-chat/surfaces/integration/NativeChatResolvedView.prompt-card-composer.test.tsx src/renderer/src/components/native-chat/conversation/turns/NativeChatResolvedView.turn-status.test.tsx src/renderer/src/runtime/hosted-terminals/inspection/runtime-terminal-inspection.test.ts src/renderer/src/lib/agent-paste-draft.test.ts src/renderer/src/lib/agent-paste-draft-submit-retry.test.ts src/main/ipc/pty/ipc/write-input-user-input.test.ts src/main/ipc/pty/pty-write-ipc-validation.test.ts src/main/runtime/terminal/input/runtime-terminal-writer.test.ts src/main/runtime/rpc/terminal-send.test.ts src/main/runtime/terminal/input/terminal-send-stale-leaf-liveness.test.ts --maxWorkers=2", + "ORCA_BACKGROUND_LAUNCH=1 pnpm test src/renderer/src/components/native-chat/prompts/NativeChatInteractiveCard.test.tsx src/renderer/src/components/native-chat/prompts/NativeChatResolvedView.prompt-card-input.test.tsx src/renderer/src/components/native-chat/surfaces/integration/NativeChatResolvedView.prompt-card-composer.test.tsx src/renderer/src/components/native-chat/conversation/turns/NativeChatResolvedView.turn-status.test.tsx src/renderer/src/runtime/hosted-terminals/inspection/runtime-terminal-inspection.test.ts src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft.test.ts src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft-submit-retry.test.ts src/main/ipc/pty/ipc/write-input-user-input.test.ts src/main/ipc/pty/pty-write-ipc-validation.test.ts src/main/runtime/terminal/input/runtime-terminal-writer.test.ts src/main/runtime/rpc/terminal-send.test.ts src/main/runtime/terminal/input/terminal-send-stale-leaf-liveness.test.ts --maxWorkers=2", "ORCA_BACKGROUND_LAUNCH=1 mobile/node_modules/.bin/vitest run --config mobile/vitest.config.ts mobile/src/session/native-chat/MobileNativeChatView.prompt-presentation.test.ts mobile/src/session/native-chat/MobileNativeChatView.failure-banner.test.ts mobile/src/session/mobile-prompt-controller.test.ts --maxWorkers=2", "ORCA_BACKGROUND_LAUNCH=1 pnpm test tests/e2e/cross-version-wire/cross-version-terminal-wire.unit.test.ts --maxWorkers=1", - "ORCA_BACKGROUND_LAUNCH=1 pnpm test src/renderer/src/components/native-chat/prompts/NativeChatInteractiveCard.test.tsx src/renderer/src/components/native-chat/prompts/NativeChatResolvedView.prompt-card-input.test.tsx src/renderer/src/components/native-chat/conversation/turns/NativeChatResolvedView.turn-status.test.tsx src/renderer/src/runtime/hosted-terminals/inspection/runtime-terminal-inspection.test.ts src/renderer/src/lib/agent-paste-draft.test.ts src/renderer/src/lib/agent-paste-draft-submit-retry.test.ts src/main/ipc/pty/ipc/write-input-user-input.test.ts src/main/ipc/pty/pty-write-ipc-validation.test.ts --maxWorkers=2", + "ORCA_BACKGROUND_LAUNCH=1 pnpm test src/renderer/src/components/native-chat/prompts/NativeChatInteractiveCard.test.tsx src/renderer/src/components/native-chat/prompts/NativeChatResolvedView.prompt-card-input.test.tsx src/renderer/src/components/native-chat/conversation/turns/NativeChatResolvedView.turn-status.test.tsx src/renderer/src/runtime/hosted-terminals/inspection/runtime-terminal-inspection.test.ts src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft.test.ts src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft-submit-retry.test.ts src/main/ipc/pty/ipc/write-input-user-input.test.ts src/main/ipc/pty/pty-write-ipc-validation.test.ts --maxWorkers=2", "ORCA_BACKGROUND_LAUNCH=1 mobile/node_modules/.bin/vitest run --config mobile/vitest.config.ts mobile/src/session/native-chat/MobileNativeChatView.prompt-presentation.test.ts mobile/src/session/native-chat/MobileNativeChatView.failure-banner.test.ts --maxWorkers=2" ], "testFiles": [ @@ -471,8 +471,8 @@ "src/renderer/src/components/native-chat/surfaces/integration/NativeChatResolvedView.prompt-card-composer.test.tsx", "src/renderer/src/components/native-chat/conversation/turns/NativeChatResolvedView.turn-status.test.tsx", "src/renderer/src/runtime/hosted-terminals/inspection/runtime-terminal-inspection.test.ts", - "src/renderer/src/lib/agent-paste-draft.test.ts", - "src/renderer/src/lib/agent-paste-draft-submit-retry.test.ts", + "src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft.test.ts", + "src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft-submit-retry.test.ts", "src/main/ipc/pty/ipc/write-input-user-input.test.ts", "src/main/ipc/pty/pty-write-ipc-validation.test.ts", "src/main/runtime/terminal/input/runtime-terminal-writer.test.ts", diff --git a/config/scripts/ci/sharding/ci-shard-timings.json b/config/scripts/ci/sharding/ci-shard-timings.json index 6daa0ea2ed4..5d34bd9557e 100644 --- a/config/scripts/ci/sharding/ci-shard-timings.json +++ b/config/scripts/ci/sharding/ci-shard-timings.json @@ -6377,8 +6377,8 @@ "src/renderer/src/lib/activate-ai-vault-structured-session-host.test.ts": 589, "src/renderer/src/lib/activate-ai-vault-structured-session-reveal.test.ts": 2099, "src/renderer/src/lib/workspace/tabs/activate-tab-and-focus-pane.test.ts": 54, - "src/renderer/src/lib/active-agent-note-send-explicit-target.test.ts": 980, - "src/renderer/src/lib/active-agent-note-send-focused-session.test.ts": 536, + "src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-explicit-target.test.ts": 980, + "src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-focused-session.test.ts": 536, "src/renderer/src/lib/activity-thread-display.test.ts": 134, "src/renderer/src/lib/agent-account-restart-startup.test.ts": 1780, "src/renderer/src/lib/agent-session/launch/background/agent-background-session-launch-host.test.ts": 1910, @@ -6395,10 +6395,10 @@ "src/renderer/src/lib/agent-session/launch/pane/agent-launch-tab-main-written.test.ts": 2084, "src/renderer/src/lib/agent-session/launch/pane/agent-launch-tab-publication.test.ts": 1855, "src/renderer/src/lib/agent-session/launch/pane/agent-launch-through-host.test.ts": 1975, - "src/renderer/src/lib/agent-message-send.test.ts": 182, - "src/renderer/src/lib/agent-paste-draft-submit-retry.test.ts": 315, - "src/renderer/src/lib/agent-paste-draft.test.ts": 445, - "src/renderer/src/lib/agent-resume-launch-target.test.ts": 3911, + "src/renderer/src/lib/agent-session/messaging/agent-message-send.test.ts": 182, + "src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft-submit-retry.test.ts": 315, + "src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft.test.ts": 445, + "src/renderer/src/lib/agent-session/resume/agent-resume-launch-target.test.ts": 3911, "src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-after-failure.test.ts": 870, "src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-close-race.test.ts": 983, "src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-create-message.test.ts": 2521, @@ -6417,10 +6417,10 @@ "src/renderer/src/lib/agent-session/structured-agent-session-draft-position-lifetime.test.tsx": 3166, "src/renderer/src/lib/agent-session/structured-agent-session-ordinary-draft.test.tsx": 9907, "src/renderer/src/lib/agent-session/structured-agent-session-provisional-tab.test.ts": 3672, - "src/renderer/src/lib/agent-skill-cli-prerequisite.test.ts": 219, - "src/renderer/src/lib/agent-startup-delayed-delivery-perf.test.ts": 1708, - "src/renderer/src/lib/agent-status-evidence-clock.test.ts": 88, - "src/renderer/src/lib/agent-status.test.ts": 172, + "src/renderer/src/lib/skills/installation/agent-skill-cli-prerequisite.test.ts": 219, + "src/renderer/src/lib/agent-session/launch/startup/agent-startup-delayed-delivery-perf.test.ts": 1708, + "src/shared/agent-status/contracts/agent-status-evidence-clock.test.ts": 88, + "src/shared/agent-status/title/agent-title-tracker.test.ts": 172, "src/renderer/src/lib/agent-session/resume/history/ai-vault-antigravity-reference-host.test.ts": 678, "src/renderer/src/lib/agent-session/resume/history/ai-vault-resume-command.drop-repin.test.ts": 541, "src/renderer/src/lib/agent-session/resume/history/ai-vault-resume-command.test.ts": 665, diff --git a/src/renderer/src/app-shell/startup-window-parity.test.ts b/src/renderer/src/app-shell/startup-window-parity.test.ts index e06ff4428af..ad55364b52d 100644 --- a/src/renderer/src/app-shell/startup-window-parity.test.ts +++ b/src/renderer/src/app-shell/startup-window-parity.test.ts @@ -1,7 +1,7 @@ // Compare window startup from disk with the Loader round trip. Enumerate each divergence as a known defect or accepted difference with its reason. import { describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { ExecutionHostId } from '../../../shared/execution-host' import type { WorkspaceSessionState } from '../../../shared/workspace-session/workspace-session-state-types' import { LEGACY_WORKSPACE_LAYOUT_PROFILES } from '../../../shared/workspace-layout/workspace-layout-legacy-profile.test-fixture' @@ -24,7 +24,7 @@ vi.mock('../../../shared/layout-owner-switch', () => ({ } })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/components/ClaudeAccountSwitchSessionTree.tsx b/src/renderer/src/components/ClaudeAccountSwitchSessionTree.tsx index be5f1670689..8b712f06a6a 100644 --- a/src/renderer/src/components/ClaudeAccountSwitchSessionTree.tsx +++ b/src/renderer/src/components/ClaudeAccountSwitchSessionTree.tsx @@ -2,7 +2,7 @@ import { Fragment, useLayoutEffect, useRef, useState } from 'react' import { Folder, GitBranch } from 'lucide-react' import { translate } from '@/i18n/i18n' import { useTranslate, type Translate } from '@/i18n/use-translate' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { formatAgentTypeLabel } from '../../../shared/agent-status/presentation/agent-type-label' import type { ClaudeAccountSwitchPromptSessions } from '@/lib/provider-accounts/claude-account-switch-sessions' import { diff --git a/src/renderer/src/components/NativeChatResumeOnRestartAgentRow.tsx b/src/renderer/src/components/NativeChatResumeOnRestartAgentRow.tsx index f60e94e8c8c..b1ebf752d87 100644 --- a/src/renderer/src/components/NativeChatResumeOnRestartAgentRow.tsx +++ b/src/renderer/src/components/NativeChatResumeOnRestartAgentRow.tsx @@ -1,5 +1,5 @@ import { useContext } from 'react' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { agentTypeToIconAgent } from '../../../shared/agent-status/presentation/agent-type-icon-agent' import { formatAgentTypeLabel } from '../../../shared/agent-status/presentation/agent-type-label' import { formatShortTimeAgo } from '@/lib/short-time-ago' diff --git a/src/renderer/src/components/NewWorkspaceComposerCard.tsx b/src/renderer/src/components/NewWorkspaceComposerCard.tsx index b3214247197..514a3b90408 100644 --- a/src/renderer/src/components/NewWorkspaceComposerCard.tsx +++ b/src/renderer/src/components/NewWorkspaceComposerCard.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next' import { toast } from 'sonner' import { useAppStore } from '@/store' import { cn } from '@/lib/utils' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { getScreenSubmitModifierLabel } from '@/lib/screen-submit-shortcut' import { resolveProjectCloneUrlPrefill } from '@/lib/project-clone-url-prefill' import { useContextualTour } from '@/components/contextual-tours/use-contextual-tour' diff --git a/src/renderer/src/components/activity/activity-event-state.ts b/src/renderer/src/components/activity/activity-event-state.ts index 63768a14a61..0c6242dba7c 100644 --- a/src/renderer/src/components/activity/activity-event-state.ts +++ b/src/renderer/src/components/activity/activity-event-state.ts @@ -1,5 +1,8 @@ -import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../shared/agent-status/contracts/agent-status-freshness' +import { + isAgentStatusFresh, + AGENT_STATUS_STALE_AFTER_MS +} from '../../../../shared/agent-status/contracts/agent-status-freshness' + import type { AgentStatusEntry, AgentStatusState, @@ -20,7 +23,7 @@ export function freshActivityLiveAgentState( ): ActivityLiveAgentState | null { if ( !isActivityHookLiveAgentState(entry.state) || - !isExplicitAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS) + !isAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS) ) { return null } diff --git a/src/renderer/src/components/activity/activity-thread-detail-pane.tsx b/src/renderer/src/components/activity/activity-thread-detail-pane.tsx index 8b4b8b28c67..db2fab50f99 100644 --- a/src/renderer/src/components/activity/activity-thread-detail-pane.tsx +++ b/src/renderer/src/components/activity/activity-thread-detail-pane.tsx @@ -1,6 +1,6 @@ import React from 'react' import { MessageSquareText, TerminalSquare } from 'lucide-react' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { cn } from '@/lib/utils' import { useTranslate } from '@/i18n/use-translate' import { EventRepoBadge, ThreadAgentStateIndicator } from './activity-thread-controls' diff --git a/src/renderer/src/components/activity/activity-thread-hover-card-summary.tsx b/src/renderer/src/components/activity/activity-thread-hover-card-summary.tsx index 743d8d6247c..f62405cbfa1 100644 --- a/src/renderer/src/components/activity/activity-thread-hover-card-summary.tsx +++ b/src/renderer/src/components/activity/activity-thread-hover-card-summary.tsx @@ -3,7 +3,7 @@ import { Cloud, Copy, FolderGit2, GitBranch, Laptop, LocateFixed, Server } from import { toast } from 'sonner' import { useAppStore } from '@/store' import { RepoBadgeMark } from '@/components/repo/RepoBadgeLabel' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { formatAgentTypeLabel } from '../../../../shared/agent-status/presentation/agent-type-label' import { getWorktreeGitIdentityDisplay } from '../../../../shared/worktree/git-identity-display' import { jumpToWorktreeFromSidebar } from '@/lib/workspace/activation/worktree-jump-navigation' diff --git a/src/renderer/src/components/activity/activity-thread-presentation.ts b/src/renderer/src/components/activity/activity-thread-presentation.ts index aa37ffe17ee..92913fa6841 100644 --- a/src/renderer/src/components/activity/activity-thread-presentation.ts +++ b/src/renderer/src/components/activity/activity-thread-presentation.ts @@ -1,7 +1,7 @@ import type { AgentDotState } from '@/components/AgentStateDot' import { formatAgentTypeLabel } from '../../../../shared/agent-status/presentation/agent-type-label' import { getAgentRowPrimaryText } from '../../../../shared/agent-status/presentation/agent-row-primary-text' -import { showsAgentToolPreview } from '@/lib/agent-row-tool-preview' +import { showsAgentToolPreview } from '@/lib/agent-status/presentation/agent-row-tool-preview' import { agentMainAgentVerdict, agentVerdictDisplayMark diff --git a/src/renderer/src/components/activity/activity-thread-row.tsx b/src/renderer/src/components/activity/activity-thread-row.tsx index ce64868966e..ef6e21f58fa 100644 --- a/src/renderer/src/components/activity/activity-thread-row.tsx +++ b/src/renderer/src/components/activity/activity-thread-row.tsx @@ -1,6 +1,6 @@ import React from 'react' import { Bell, ExternalLink, X } from 'lucide-react' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { formatAgentTypeLabel } from '../../../../shared/agent-status/presentation/agent-type-label' import { Button } from '@/components/ui/button' import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip' diff --git a/src/renderer/src/components/activity/useActivityUnreadCount.ts b/src/renderer/src/components/activity/useActivityUnreadCount.ts index 613e0941836..df3761ab0b0 100644 --- a/src/renderer/src/components/activity/useActivityUnreadCount.ts +++ b/src/renderer/src/components/activity/useActivityUnreadCount.ts @@ -2,7 +2,7 @@ import { useState } from 'react' import { migrationUnsupportedToAgentStatusEntry } from '../../../../shared/migration-unsupported-agent-entry' import { useAppStore } from '@/store' -import { createAgentStatusEpochSelector } from '@/lib/agent-status-epoch-selector' +import { createAgentStatusEpochSelector } from '@/lib/agent-status/evidence/agent-status-epoch-selector' import type { AppState } from '@/store/types' import type { AgentStatusEntry } from '../../../../shared/agent-status/contracts/agent-status-types' diff --git a/src/renderer/src/components/agent-session-continuation/AgentSessionContinuationDialog.tsx b/src/renderer/src/components/agent-session-continuation/AgentSessionContinuationDialog.tsx index 0d860a215e8..73eae33015f 100644 --- a/src/renderer/src/components/agent-session-continuation/AgentSessionContinuationDialog.tsx +++ b/src/renderer/src/components/agent-session-continuation/AgentSessionContinuationDialog.tsx @@ -29,13 +29,13 @@ import { SelectValue } from '@/components/ui/select' import { useTranslate } from '@/i18n/use-translate' -import { getAgentCatalog, getAgentLabel } from '@/lib/agent-catalog' +import { getAgentCatalog, getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import { buildAgentSessionContinuationPrompt, hasFullAgentSessionContext, type AgentSessionContinuationContextMode, type AgentSessionContinuationRequest -} from '@/lib/agent-session-continuation' +} from '@/lib/agent-session/context/agent-session-continuation' import { launchAgentSessionContinuation } from '@/lib/agent-session/launch/continuation/launch-agent-session-continuation' import { useAppStore } from '@/store' import { isTuiAgentEnabled } from '../../../../shared/agent-launch/catalog/tui-agent-selection' diff --git a/src/renderer/src/components/agent/AgentCombobox.tsx b/src/renderer/src/components/agent/AgentCombobox.tsx index 64d98889abe..a91dbaf4751 100644 --- a/src/renderer/src/components/agent/AgentCombobox.tsx +++ b/src/renderer/src/components/agent/AgentCombobox.tsx @@ -4,12 +4,13 @@ import { Button } from '@/components/ui/button' import { Command, CommandEmpty, CommandInput, CommandList } from '@/components/ui/command' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' -import { AgentIcon, type AgentCatalogEntry } from '@/lib/agent-catalog' +import type { AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { agentPickerBlankTerminalMatches, getAgentPickerCommandValue, searchAgentPickerEntries -} from '@/lib/agent-picker-search' +} from '@/lib/agent-catalog/agent-picker-search' import { cn } from '@/lib/utils' import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' import * as state from './agent-combobox-command-state' diff --git a/src/renderer/src/components/agent/AgentLaunchPicker.tsx b/src/renderer/src/components/agent/AgentLaunchPicker.tsx index a27d05e6cce..4c28231b0b6 100644 --- a/src/renderer/src/components/agent/AgentLaunchPicker.tsx +++ b/src/renderer/src/components/agent/AgentLaunchPicker.tsx @@ -21,7 +21,8 @@ import { DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu' -import { AgentIcon, getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useTranslate } from '@/i18n/use-translate' import { rowLabel } from '../tab-bar/tab-agent-row-presentation' import type { NewTabAgentMenuModel } from '../tab-bar/use-new-tab-agent-menu-rows' diff --git a/src/renderer/src/components/agent/AgentLaunchPickerMenu.tsx b/src/renderer/src/components/agent/AgentLaunchPickerMenu.tsx index 31b1804db26..90bf546b321 100644 --- a/src/renderer/src/components/agent/AgentLaunchPickerMenu.tsx +++ b/src/renderer/src/components/agent/AgentLaunchPickerMenu.tsx @@ -7,7 +7,7 @@ import { useAppStore } from '@/store/index' import { parseExecutionHostId } from '../../../../shared/execution-host' import { Input } from '@/components/ui/input' import { Terminal } from 'lucide-react' -import { agentPickerBlankTerminalMatches } from '@/lib/agent-picker-search' +import { agentPickerBlankTerminalMatches } from '@/lib/agent-catalog/agent-picker-search' import { AgentDefaultContextMenu } from './agent-combobox-items' import { AgentPickerMenuRow, type AgentPickerMenuLaunch } from './AgentLaunchPickerMenuRow' import { DropdownMenuItem } from '@/components/ui/dropdown-menu' diff --git a/src/renderer/src/components/agent/AgentLaunchPickerMenuRow.tsx b/src/renderer/src/components/agent/AgentLaunchPickerMenuRow.tsx index 18b9adfe0a1..614d48ae472 100644 --- a/src/renderer/src/components/agent/AgentLaunchPickerMenuRow.tsx +++ b/src/renderer/src/components/agent/AgentLaunchPickerMenuRow.tsx @@ -6,7 +6,7 @@ import { DropdownMenuShortcut, useDropdownMenuClose } from '@/components/ui/dropdown-menu' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useUiLanguageRevision } from '@/i18n/use-ui-language-revision' import { AgentDefaultContextMenu } from './agent-combobox-items' import { AgentLaunchSetupButton, type AgentPickerSetupIdentity } from './AgentLaunchSetupButton' diff --git a/src/renderer/src/components/agent/agent-combobox-surface-items.tsx b/src/renderer/src/components/agent/agent-combobox-surface-items.tsx index afb2c99c53c..0749ff09194 100644 --- a/src/renderer/src/components/agent/agent-combobox-surface-items.tsx +++ b/src/renderer/src/components/agent/agent-combobox-surface-items.tsx @@ -1,8 +1,9 @@ import { terminalPendingLabel, terminalPendingReason } from '../tab-bar/new-tab-agent-menu-model' import React, { useState } from 'react' import { CommandItem, CommandSeparator } from '@/components/ui/command' -import { AgentIcon, getAgentCatalog, type AgentCatalogEntry } from '@/lib/agent-catalog' -import { searchAgentPickerEntries } from '@/lib/agent-picker-search' +import { getAgentCatalog, type AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' +import { searchAgentPickerEntries } from '@/lib/agent-catalog/agent-picker-search' import type { AgentLaunchSurface } from '@/lib/agent-session/launch/routing/agent-session-launch-plan' import type { NewTabAgentMenuRow } from '../../../../shared/agent-launch/picker/agent-launch-picker-rows' import type { NewTabAgentMenuModel } from '@/components/tab-bar/use-new-tab-agent-menu-rows' @@ -16,7 +17,7 @@ import { cn } from '@/lib/utils' import { translate } from '@/i18n/i18n' import { useTranslate, type Translate } from '@/i18n/use-translate' import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' -import type { resolveAgentMenuSelection } from '@/lib/agent-menu-selection' +import type { resolveAgentMenuSelection } from '@/lib/agent-session/launch/routing/agent-menu-selection' import { renderAgentComboboxItem } from './agent-combobox-items' import { AgentSurfaceLaunchButton } from './AgentSurfaceLaunchButton' diff --git a/src/renderer/src/lib/agent-catalog.tsx b/src/renderer/src/components/agent/icons/AgentIcon.tsx similarity index 68% rename from src/renderer/src/lib/agent-catalog.tsx rename to src/renderer/src/components/agent/icons/AgentIcon.tsx index 9a18e6f075f..38189616d4d 100644 --- a/src/renderer/src/lib/agent-catalog.tsx +++ b/src/renderer/src/components/agent/icons/AgentIcon.tsx @@ -1,8 +1,7 @@ import type React from 'react' +import { getAgentCatalog, getAgentLabel } from '../../../lib/agent-catalog/agent-catalog' import { ClaudeIcon, DroidIcon, OpenAIIcon } from '@/components/status-bar/icons' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' -import type { TerminalAgent } from '../../../shared/agent-status/identity/terminal-agent' -import { formatAgentTypeLabel } from '../../../shared/agent-status/presentation/agent-type-label' +import type { TerminalAgent } from '../../../../../shared/agent-status/identity/terminal-agent' import { AgentLetterIcon, AiderIcon, @@ -12,32 +11,7 @@ import { OpenCodeIcon, PiIcon } from './agent-icon-glyphs' -import { createLocalizedCatalog } from '@/i18n/localized-catalog' import { AGENT_FAVICON_ASSETS } from './agent-favicon-assets' -import { buildAgentCatalogEntries } from './agent-catalog-entries' - -export type AgentCatalogEntry = { - id: TuiAgent - label: string - /** Default CLI binary name used for PATH detection. */ - cmd: string - searchAliases?: readonly string[] - /** Direct or bundled image URL for agents whose project identity is not represented by a favicon service. */ - iconUrl?: string - /** Domain for Google's favicon service — used for agents without an SVG icon. */ - faviconDomain?: string - /** Homepage/install docs URL, sourced from the README agent badge list. */ - homepageUrl: string -} - -export const getAgentCatalog = createLocalizedCatalog(buildAgentCatalogEntries) - -// Why: tests and a few legacy call sites still import a catalog snapshot. -export const AGENT_CATALOG: AgentCatalogEntry[] = getAgentCatalog() - -export function getAgentLabel(agent: TerminalAgent): string { - return getAgentCatalog().find((entry) => entry.id === agent)?.label ?? formatAgentTypeLabel(agent) -} export function AgentIcon({ agent, diff --git a/src/renderer/src/components/agent/icons/agent-favicon-assets.ts b/src/renderer/src/components/agent/icons/agent-favicon-assets.ts new file mode 100644 index 00000000000..87ce603600c --- /dev/null +++ b/src/renderer/src/components/agent/icons/agent-favicon-assets.ts @@ -0,0 +1,70 @@ +import qoderUrl from '../../../../../shared/agent-icons/qoder.png?url' +import type { TuiAgent } from '../../../../../shared/agent-launch/catalog/tui-agent' +import grokUrl from '../../../../../shared/agent-icons/grok.png?url' +import mimoCodeUrl from '../../../../../shared/agent-icons/mimo-code.png?url' +import anteUrl from '../../../../../shared/agent-icons/ante.png?url' +import traeUrl from '../../../../../shared/agent-icons/trae.png?url' +import primeAgentUrl from '../../../../../shared/agent-icons/prime-agent.png?url' +import geminiUrl from '../../../../../shared/agent-icons/gemini.png?url' +import antigravityUrl from '../../../../../shared/agent-icons/antigravity.png?url' +import gooseUrl from '../../../../../shared/agent-icons/goose.png?url' +import ampUrl from '../../../../../shared/agent-icons/amp.png?url' +import kiroUrl from '../../../../../shared/agent-icons/kiro.png?url' +import crushUrl from '../../../../../shared/agent-icons/crush.png?url' +import augUrl from '../../../../../shared/agent-icons/aug.png?url' +import autohandUrl from '../../../../../shared/agent-icons/autohand.png?url' +import clineUrl from '../../../../../shared/agent-icons/cline.png?url' +import freebuffUrl from '../../../../../shared/agent-icons/freebuff.png?url' +import codebuffUrl from '../../../../../shared/agent-icons/codebuff.png?url' +import commandCodeUrl from '../../../../../shared/agent-icons/command-code.png?url' +import continueUrl from '../../../../../shared/agent-icons/continue.png?url' +import cursorUrl from '../../../../../shared/agent-icons/cursor.png?url' +import kimiUrl from '../../../../../shared/agent-icons/kimi.png?url' +import mistralVibeUrl from '../../../../../shared/agent-icons/mistral-vibe.png?url' +import qwenCodeUrl from '../../../../../shared/agent-icons/qwen-code.png?url' +import rovoUrl from '../../../../../shared/agent-icons/rovo.png?url' +import hermesUrl from '../../../../../shared/agent-icons/hermes.png?url' +import devinUrl from '../../../../../shared/agent-icons/devin.png?url' +import museUrl from '../../../../../shared/agent-icons/muse.png?url' +import zcodeUrl from '../../../../../shared/agent-icons/zcode.png?url' +import openclawUrl from '../../../../../shared/agent-icons/openclaw.png?url' +import dshUrl from '../../../../../shared/agent-icons/dsh.png?url' +import jcodeUrl from '../../../../../shared/agent-icons/jcode.png?url' +import codebuddyUrl from '../../../../../shared/agent-icons/codebuddy.png?url' + +// Bundle favicons for offline/Google-blocked regions (#8451); shared/agent-icons also supplies mobile-agent-icon-assets.ts. +export const AGENT_FAVICON_ASSETS: Partial> = { + grok: grokUrl, + 'mimo-code': mimoCodeUrl, + ante: anteUrl, + trae: traeUrl, + 'prime-agent': primeAgentUrl, + qoder: qoderUrl, + 'qoder-cn': qoderUrl, + gemini: geminiUrl, + antigravity: antigravityUrl, + goose: gooseUrl, + amp: ampUrl, + kiro: kiroUrl, + crush: crushUrl, + aug: augUrl, + autohand: autohandUrl, + cline: clineUrl, + codebuff: codebuffUrl, + freebuff: freebuffUrl, + 'command-code': commandCodeUrl, + continue: continueUrl, + cursor: cursorUrl, + kimi: kimiUrl, + 'mistral-vibe': mistralVibeUrl, + 'qwen-code': qwenCodeUrl, + rovo: rovoUrl, + hermes: hermesUrl, + devin: devinUrl, + muse: museUrl, + dsh: dshUrl, + zcode: zcodeUrl, + openclaw: openclawUrl, + jcode: jcodeUrl, + codebuddy: codebuddyUrl +} diff --git a/src/renderer/src/lib/agent-icon-glyphs.tsx b/src/renderer/src/components/agent/icons/agent-icon-glyphs.tsx similarity index 99% rename from src/renderer/src/lib/agent-icon-glyphs.tsx rename to src/renderer/src/components/agent/icons/agent-icon-glyphs.tsx index 66c3aa786ed..be70a55196e 100644 --- a/src/renderer/src/lib/agent-icon-glyphs.tsx +++ b/src/renderer/src/components/agent/icons/agent-icon-glyphs.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { cn } from './utils' +import { cn } from '../../../lib/utils' export function PiIcon({ size = 14, diff --git a/src/renderer/src/lib/agent-type-icon.tsx b/src/renderer/src/components/agent/icons/agent-type-icon.tsx similarity index 80% rename from src/renderer/src/lib/agent-type-icon.tsx rename to src/renderer/src/components/agent/icons/agent-type-icon.tsx index 1b98492d56c..b12412deb72 100644 --- a/src/renderer/src/lib/agent-type-icon.tsx +++ b/src/renderer/src/components/agent/icons/agent-type-icon.tsx @@ -1,8 +1,8 @@ import type React from 'react' -import type { AgentType } from '../../../shared/agent-status/contracts/agent-status-types' -import { AgentIcon } from './agent-catalog' +import type { AgentType } from '../../../../../shared/agent-status/contracts/agent-status-types' +import { AgentIcon } from './AgentIcon' import { AgentLetterIcon } from './agent-icon-glyphs' -import { agentTypeToIconAgent } from '../../../shared/agent-status/presentation/agent-type-icon-agent' +import { agentTypeToIconAgent } from '../../../../../shared/agent-status/presentation/agent-type-icon-agent' /** Status-row icon: known agents get their brand icon, any other OSC 7501 program its first letter. */ export function AgentTypeIcon({ diff --git a/src/renderer/src/components/agent/launch-settings/AgentDefaultSurfacePreviews.tsx b/src/renderer/src/components/agent/launch-settings/AgentDefaultSurfacePreviews.tsx index c3d5bf943cc..b47f494f994 100644 --- a/src/renderer/src/components/agent/launch-settings/AgentDefaultSurfacePreviews.tsx +++ b/src/renderer/src/components/agent/launch-settings/AgentDefaultSurfacePreviews.tsx @@ -16,7 +16,7 @@ import { import { composeActiveTerminalTheme } from '@/components/terminal-pane/appearance/terminal-appearance' import { useSystemPrefersDark } from '@/hooks/theme/use-system-prefers-dark' import { useIntlLocale, useTranslate } from '@/i18n/use-translate' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { buildFontFamily } from '@/lib/monospace-font-family' import { resolveEffectiveTerminalAppearance } from '@/lib/terminal-theme' import { cn } from '@/lib/utils' diff --git a/src/renderer/src/components/automations/AutomationAgentLaunchPicker.tsx b/src/renderer/src/components/automations/AutomationAgentLaunchPicker.tsx index c84bc199de9..beee205e96a 100644 --- a/src/renderer/src/components/automations/AutomationAgentLaunchPicker.tsx +++ b/src/renderer/src/components/automations/AutomationAgentLaunchPicker.tsx @@ -10,7 +10,7 @@ import { resolveHostCapabilities, type ProspectiveWorkspace } from '@/lib/agent-session/launch/routing/agent-launch-route-input' -import type { AgentCatalogEntry } from '@/lib/agent-catalog' +import type { AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' import { parseExecutionHostId } from '../../../../shared/execution-host' import { AUTOMATION_LAUNCH_SETUP_RUNTIME_CAPABILITY } from '../../../../shared/automations/automation-runtime-capabilities' import { automationLegacyArguments } from '../../../../shared/automations/launch/automation-legacy-arguments' diff --git a/src/renderer/src/components/automations/AutomationDetail.tsx b/src/renderer/src/components/automations/AutomationDetail.tsx index 82213b9e4b5..cb8f9f992e3 100644 --- a/src/renderer/src/components/automations/AutomationDetail.tsx +++ b/src/renderer/src/components/automations/AutomationDetail.tsx @@ -3,7 +3,8 @@ import { Pencil, Pause, Play, Trash2 } from 'lucide-react' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' -import { getAgentCatalog, AgentIcon } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import type { Automation } from '../../../../shared/automations/automation-definition' import type { AutomationRun } from '../../../../shared/automations/history/automation-run' import { formatUiAutomationSchedule } from './automation-schedule-label' diff --git a/src/renderer/src/components/automations/AutomationEditorDialog.tsx b/src/renderer/src/components/automations/AutomationEditorDialog.tsx index 3d57e56bce5..9a8b4ac659e 100644 --- a/src/renderer/src/components/automations/AutomationEditorDialog.tsx +++ b/src/renderer/src/components/automations/AutomationEditorDialog.tsx @@ -9,7 +9,7 @@ import { automationLaunchWorkspace } from './automation-launch-surface' import { Dialog, DialogContent } from '@/components/ui/dialog' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { filterEnabledTuiAgents } from '../../../../shared/agent-launch/catalog/tui-agent-selection' import type { AutomationLaunchPreferences, diff --git a/src/renderer/src/components/automations/AutomationEditorSettingsSidebar.test.tsx b/src/renderer/src/components/automations/AutomationEditorSettingsSidebar.test.tsx index ced6fef4624..6e083b2ebcd 100644 --- a/src/renderer/src/components/automations/AutomationEditorSettingsSidebar.test.tsx +++ b/src/renderer/src/components/automations/AutomationEditorSettingsSidebar.test.tsx @@ -3,7 +3,7 @@ import { act, cleanup, fireEvent, render, screen } from '@testing-library/react' import { useState } from 'react' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { AGENT_CATALOG } from '@/lib/agent-catalog' +import { AGENT_CATALOG } from '@/lib/agent-catalog/agent-catalog' import { TooltipProvider } from '@/components/ui/tooltip' import { useAppStore } from '@/store' import { createCompatibleRuntimeStatusResponse } from '@/runtime/rpc/testing/runtime-compatibility-test-fixture' diff --git a/src/renderer/src/components/automations/AutomationEditorSettingsSidebar.tsx b/src/renderer/src/components/automations/AutomationEditorSettingsSidebar.tsx index 51f95c09d7d..6c89609af50 100644 --- a/src/renderer/src/components/automations/AutomationEditorSettingsSidebar.tsx +++ b/src/renderer/src/components/automations/AutomationEditorSettingsSidebar.tsx @@ -8,7 +8,7 @@ import type { OrcaHooks } from '../../../../shared/orca-yaml-hook-types' import type { ProjectHostSetup } from '../../../../shared/project-types' import type { Repo } from '../../../../shared/repo-types' import type { Worktree } from '../../../../shared/worktree/types' -import type { AgentCatalogEntry } from '@/lib/agent-catalog' +import type { AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' import { AUTOMATION_EDITOR_SECTION_LABEL_CLASS, Field } from './automation-page-parts' import { AutomationMissedRunGraceField } from './AutomationMissedRunGraceField' import { AutomationPrecheckFields } from './AutomationPrecheckFields' diff --git a/src/renderer/src/components/automations/AutomationListFilterMenu.tsx b/src/renderer/src/components/automations/AutomationListFilterMenu.tsx index e8d472695db..cc11fbcad2f 100644 --- a/src/renderer/src/components/automations/AutomationListFilterMenu.tsx +++ b/src/renderer/src/components/automations/AutomationListFilterMenu.tsx @@ -16,8 +16,9 @@ import { DropdownMenuSubTrigger, DropdownMenuTrigger } from '@/components/ui/dropdown-menu' -import { AgentIcon, getAgentCatalog } from '@/lib/agent-catalog' -import { searchAgentPickerEntries } from '@/lib/agent-picker-search' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' +import { searchAgentPickerEntries } from '@/lib/agent-catalog/agent-picker-search' import { useTranslate } from '@/i18n/use-translate' import { useBoundedHostRows } from '@/components/host-picker/use-bounded-host-rows' import { HostListSearchField } from '@/components/host-picker/HostListSearchField' diff --git a/src/renderer/src/components/automations/AutomationListLocalRow.tsx b/src/renderer/src/components/automations/AutomationListLocalRow.tsx index 0682e16c3cc..8c0bd693100 100644 --- a/src/renderer/src/components/automations/AutomationListLocalRow.tsx +++ b/src/renderer/src/components/automations/AutomationListLocalRow.tsx @@ -19,7 +19,7 @@ import { } from '@/components/ui/dropdown-menu' import { Button } from '@/components/ui/button' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { cn } from '@/lib/utils' import type { AutomationRun } from '../../../../shared/automations/history/automation-run' import { getAutomationRunRepoId } from '../../../../shared/automations/history/automation-run-identity' diff --git a/src/renderer/src/components/automations/automation-draft-model.ts b/src/renderer/src/components/automations/automation-draft-model.ts index 9b2f2fda161..cf776994c35 100644 --- a/src/renderer/src/components/automations/automation-draft-model.ts +++ b/src/renderer/src/components/automations/automation-draft-model.ts @@ -1,6 +1,6 @@ import { buildAutomationRrule } from '../../../../shared/automations/scheduling/automation-schedule-occurrences' import { automationLaunchInputs } from '../../../../shared/automations/launch/automation-launch-choices' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import type { AutomationPrecheck } from '../../../../shared/automations/automation-definition' import type { Worktree } from '../../../../shared/worktree/types' import { diff --git a/src/renderer/src/components/automations/use-automation-agent-picker-entries.ts b/src/renderer/src/components/automations/use-automation-agent-picker-entries.ts index fd9f85b3892..fb7d2ba5a49 100644 --- a/src/renderer/src/components/automations/use-automation-agent-picker-entries.ts +++ b/src/renderer/src/components/automations/use-automation-agent-picker-entries.ts @@ -1,6 +1,6 @@ import { useCallback, useMemo } from 'react' import { shallow } from 'zustand/shallow' -import type { AgentCatalogEntry } from '@/lib/agent-catalog' +import type { AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' import type { AgentLaunchRouteStore, ProspectiveWorkspace diff --git a/src/renderer/src/components/automations/use-automations-page-store-state.ts b/src/renderer/src/components/automations/use-automations-page-store-state.ts index 798b9dc13f7..4528ee6ea98 100644 --- a/src/renderer/src/components/automations/use-automations-page-store-state.ts +++ b/src/renderer/src/components/automations/use-automations-page-store-state.ts @@ -5,7 +5,7 @@ import { } from '../../../../shared/agent-launch/catalog/tui-agent-selection' import type { Repo } from '../../../../shared/repo-types' import type { Worktree } from '../../../../shared/worktree/types' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { useAppStore } from '@/store' import { useRepoMap } from '@/store/repos/use-repository-catalog' import { useWorktreeMap } from '@/store/slices/worktrees/listing/use-worktree-catalog' diff --git a/src/renderer/src/components/cmd-j/palette-live-status.tsx b/src/renderer/src/components/cmd-j/palette-live-status.tsx index 5bd08054f6f..bebe0cfe96f 100644 --- a/src/renderer/src/components/cmd-j/palette-live-status.tsx +++ b/src/renderer/src/components/cmd-j/palette-live-status.tsx @@ -11,7 +11,10 @@ import { buildExplicitEntriesByTabId, type TabPaneInputSources } from '../../../../shared/sidebar-list/smart-attention' -import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' +import { + isAgentStatusFresh, + AGENT_STATUS_STALE_AFTER_MS +} from '../../../../shared/agent-status/contracts/agent-status-freshness' import { getLiveAgentStatusByWorktreeId, type LiveAgentWorktreeStatus @@ -32,7 +35,6 @@ import { } from '@/components/tab-bar/terminal-tab-activity-status' import { useTranslate } from '@/i18n/use-translate' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../shared/agent-status/contracts/agent-status-freshness' import type { AgentStatusEntry } from '../../../../shared/agent-status/contracts/agent-status-types' import { parsePaneKey } from '../../../../shared/workspace-layout/stable-pane-id' import type { BrowserWorkspace } from '../../../../shared/browser-workspace-types' @@ -162,7 +164,7 @@ function buildLiveAgentStatusPaneIdsByTabId( } if ( entry.restoredUnconfirmed !== true && - !isExplicitAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS) + !isAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS) ) { stalePaneIds.add(paneId) continue diff --git a/src/renderer/src/components/dashboard-popout/AgentKanbanCard.tsx b/src/renderer/src/components/dashboard-popout/AgentKanbanCard.tsx index f0b18fa687e..dc46ed8d2d5 100644 --- a/src/renderer/src/components/dashboard-popout/AgentKanbanCard.tsx +++ b/src/renderer/src/components/dashboard-popout/AgentKanbanCard.tsx @@ -7,7 +7,7 @@ import { GitPullRequestClosed, GitPullRequestDraft } from 'lucide-react' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { AgentQuestionIcon } from '@/components/AgentQuestionIcon' import { AgentStateDot } from '@/components/AgentStateDot' import { RepoIconGlyph } from '@/components/repo/repo-icon' diff --git a/src/renderer/src/components/dashboard-popout/AgentTerminalDialog.tsx b/src/renderer/src/components/dashboard-popout/AgentTerminalDialog.tsx index 83505a76764..560c0e3459a 100644 --- a/src/renderer/src/components/dashboard-popout/AgentTerminalDialog.tsx +++ b/src/renderer/src/components/dashboard-popout/AgentTerminalDialog.tsx @@ -1,6 +1,6 @@ import { useEffect, useId, useRef } from 'react' import { SquareArrowOutUpRight, XIcon } from 'lucide-react' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { formatAgentTypeLabel } from '../../../../shared/agent-status/presentation/agent-type-label' import { agentStateLabel } from '@/components/AgentStateDot' import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog' diff --git a/src/renderer/src/components/dashboard/DashboardAgentRow.tsx b/src/renderer/src/components/dashboard/DashboardAgentRow.tsx index 1a61fa91825..7d676e65533 100644 --- a/src/renderer/src/components/dashboard/DashboardAgentRow.tsx +++ b/src/renderer/src/components/dashboard/DashboardAgentRow.tsx @@ -1,6 +1,9 @@ import React, { useState, useCallback } from 'react' import { cn } from '@/lib/utils' -import { opensClaudeParentConversation, viewClaudeAgentFromRow } from '@/lib/claude-agent-row-view' +import { + opensClaudeParentConversation, + viewClaudeAgentFromRow +} from '@/lib/agent-session/navigation/claude-agent-row-view' import { useClaudeAgentRowView } from './use-claude-agent-row-view' import { AgentStateDot, @@ -8,26 +11,32 @@ import { agentStateProgressLabel, type AgentDotState } from '@/components/AgentStateDot' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { formatAgentTypeLabel } from '../../../../shared/agent-status/presentation/agent-type-label' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' import { DashboardAgentRowMessage } from './DashboardAgentRowMessage' import { DashboardAgentRowTrailingControls } from './DashboardAgentRowTrailingControls' import { DashboardAgentRowToolStep } from './DashboardAgentRowToolStep' import { programStatusAttentionLine } from '../../../../shared/program-status/presentation' -import { agentRowToolInput, showsAgentToolPreview } from '@/lib/agent-row-tool-preview' +import { + agentRowToolInput, + showsAgentToolPreview +} from '@/lib/agent-status/presentation/agent-row-tool-preview' import { resolveRowProgramStatus } from '@/lib/program-status/agent-row-presentation' -import { agentRowStoppingLabel } from '@/lib/agent-row-stopping-label' +import { agentRowStoppingLabel } from '@/lib/agent-status/presentation/agent-row-stopping-label' import { agentNoUpdateLabel, formatCompactDuration } from '../../../../shared/agent-status/presentation/agent-row-decay-state' -import { agentRowDisplayDotState, agentRowDotState as asDotState } from '@/lib/agent-row-dot-state' +import { + agentRowDisplayDotState, + agentRowDotState as asDotState +} from '@/lib/agent-status/presentation/agent-row-dot-state' import { agentMainAgentVerdict, agentVerdictDisplayMark } from '../../../../shared/agent-status/lifecycle/agent-main-agent-verdict' -import { agentVerdictStatusLine } from '@/lib/agent-verdict-status-line' +import { agentVerdictStatusLine } from '@/lib/agent-status/presentation/agent-verdict-status-line' import type { DashboardAgentRow as DashboardAgentRowData } from './useDashboardData' import { getAgentRowPrimaryText } from '../../../../shared/agent-status/presentation/agent-row-primary-text' import { useAgentRowConversationName } from './use-agent-row-conversation-name' diff --git a/src/renderer/src/components/dashboard/useRetainedAgents.ts b/src/renderer/src/components/dashboard/useRetainedAgents.ts index 8bae0d6d7e1..fa75f806fa6 100644 --- a/src/renderer/src/components/dashboard/useRetainedAgents.ts +++ b/src/renderer/src/components/dashboard/useRetainedAgents.ts @@ -2,7 +2,10 @@ import { agentEntrySessionStartedAt } from '../../../../shared/agent-session/lif import { useEffect, useRef } from 'react' import { useShallow } from 'zustand/react/shallow' import { useAppStore } from '@/store' -import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' +import { + isAgentStatusFresh, + AGENT_STATUS_STALE_AFTER_MS +} from '../../../../shared/agent-status/contracts/agent-status-freshness' import type { DashboardAgentRow } from './useDashboardData' import type { RetainedAgentEntry } from '@/store/slices/agent-status/agent-status-contract' import type { FolderWorkspace } from '../../../../shared/folder-workspaces/folder-workspace-types' @@ -11,7 +14,7 @@ import type { TerminalTab } from '../../../../shared/workspace-layout/terminal-t import type { Worktree } from '../../../../shared/worktree/types' import { folderWorkspaceKey } from '../../../../shared/workspace-scope' import { resolveAgentPaneAuthorityKey } from '@/store/slices/agent-status/agent-pane-authority' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../shared/agent-status/contracts/agent-status-freshness' + import type { AgentStatusEntry } from '../../../../shared/agent-status/contracts/agent-status-types' import { parsePaneKey } from '../../../../shared/workspace-layout/stable-pane-id' import { agentTurnEndedOnPurpose } from '../../../../shared/agent-status/lifecycle/agent-main-agent-verdict' @@ -116,7 +119,7 @@ export function buildRetainedAgentsSyncSnapshot(args: RetainedAgentsSyncSnapshot if (!owner) { continue } - const isFresh = isExplicitAgentStatusFresh(entry, args.now, AGENT_STATUS_STALE_AFTER_MS) + const isFresh = isAgentStatusFresh(entry, args.now, AGENT_STATUS_STALE_AFTER_MS) const shouldDecay = !isFresh && (entry.state === 'working' || entry.state === 'blocked' || entry.state === 'waiting') diff --git a/src/renderer/src/components/editor/review-note-delivery/ReviewNotesSendMenuContent.tsx b/src/renderer/src/components/editor/review-note-delivery/ReviewNotesSendMenuContent.tsx index 027468d1b0a..6612ba225c7 100644 --- a/src/renderer/src/components/editor/review-note-delivery/ReviewNotesSendMenuContent.tsx +++ b/src/renderer/src/components/editor/review-note-delivery/ReviewNotesSendMenuContent.tsx @@ -22,24 +22,24 @@ import { } from '@/runtime/native-chat/naming/structured-chat-name-observation' import { QuickLaunchAgentMenuItems } from '@/components/tab-bar/QuickLaunchButton' import { AgentStateDot, agentStateLabel } from '@/components/AgentStateDot' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator } from '@/components/ui/dropdown-menu' import { focusTerminalTabSurface } from '@/lib/focus-terminal-tab-surface' -import '@/lib/active-agent-note-send' +import '@/lib/agent-session/messaging/terminal/active-agent-note-send' import { activeAgentNotesSendFailureMessage, type ActiveAgentNotesSendResult -} from '@/lib/active-agent-note-send-result' -import { sendMessageToAgent } from '@/lib/agent-message-send' +} from '@/lib/agent-session/messaging/terminal/active-agent-note-send-result' +import { sendMessageToAgent } from '@/lib/agent-session/messaging/agent-message-send' import { deriveNotesSendAgentTargets, type NotesSendAgentTarget -} from '@/lib/notes-send-agent-targets' -import { agentKindForAgentType } from '@/lib/agent-status' +} from '@/lib/agent-session/messaging/notes-send-agent-targets' +import { agentKindForAgentType } from '@/lib/agent-status/aggregation/worktree-agent-status' import { formatAgentTypeLabel } from '../../../../../shared/agent-status/presentation/agent-type-label' import { track } from '@/lib/telemetry' import { useNow } from '@/hooks/use-now' @@ -49,10 +49,10 @@ import { useWorktreeAgentRows } from '@/components/sidebar/workspace-card/activi import { useAgentRowConversationName } from '@/components/dashboard/use-agent-row-conversation-name' import { getAgentRowPrimaryText } from '../../../../../shared/agent-status/presentation/agent-row-primary-text' import type { LaunchSource } from '../../../../../shared/telemetry-property-schemas' -import { agentRowDisplayDotState } from '@/lib/agent-row-dot-state' +import { agentRowDisplayDotState } from '@/lib/agent-status/presentation/agent-row-dot-state' import { translate } from '@/i18n/i18n' import { useTranslate, type Translate } from '@/i18n/use-translate' -import { agentSendDisabledReasonLabel } from '@/lib/agent-send-disabled-reason-label' +import { agentSendDisabledReasonLabel } from '@/lib/agent-session/messaging/agent-send-disabled-reason-label' import { addQuoteToAgent } from '@/components/native-chat/selection-quotes/native-chat-workspace-selection' import React, { useCallback, useMemo } from 'react' import { orderSendTargetsByWorktreeAgentRows } from './review-notes-send-target-order' diff --git a/src/renderer/src/components/editor/review-note-delivery/review-notes-send-target-order.ts b/src/renderer/src/components/editor/review-note-delivery/review-notes-send-target-order.ts index d7a498d62a1..274d678fc80 100644 --- a/src/renderer/src/components/editor/review-note-delivery/review-notes-send-target-order.ts +++ b/src/renderer/src/components/editor/review-note-delivery/review-notes-send-target-order.ts @@ -1,5 +1,5 @@ import type { DashboardAgentRow as DashboardAgentRowData } from '@/components/dashboard/useDashboardData' -import type { NotesSendAgentTarget } from '@/lib/notes-send-agent-targets' +import type { NotesSendAgentTarget } from '@/lib/agent-session/messaging/notes-send-agent-targets' export type OrderedSendTarget = { target: NotesSendAgentTarget diff --git a/src/renderer/src/components/emulator-pane/MobileEmulatorAgentSetupGuideSteps.tsx b/src/renderer/src/components/emulator-pane/MobileEmulatorAgentSetupGuideSteps.tsx index 9e061859f0b..23ce5fbfadd 100644 --- a/src/renderer/src/components/emulator-pane/MobileEmulatorAgentSetupGuideSteps.tsx +++ b/src/renderer/src/components/emulator-pane/MobileEmulatorAgentSetupGuideSteps.tsx @@ -1,5 +1,5 @@ import { useAppStore } from '@/store' -import { ORCA_CLI_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_CLI_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { AgentSkillSetupPanel } from '../skills/setup/AgentSkillSetupPanel' import type { useMobileEmulatorAgentSetupState } from './use-mobile-emulator-agent-setup-state' import { useTranslate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/emulator-pane/use-mobile-emulator-agent-setup-state.ts b/src/renderer/src/components/emulator-pane/use-mobile-emulator-agent-setup-state.ts index 8182008b6c7..35d7b3e1e7c 100644 --- a/src/renderer/src/components/emulator-pane/use-mobile-emulator-agent-setup-state.ts +++ b/src/renderer/src/components/emulator-pane/use-mobile-emulator-agent-setup-state.ts @@ -1,7 +1,7 @@ import { useActiveProjectSkillRuntime } from '@/hooks/useActiveProjectSkillRuntime' import { useCallback, useEffect, useState } from 'react' import { toast } from 'sonner' -import { ORCA_CLI_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_CLI_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkill diff --git a/src/renderer/src/components/feature-tips/ChatUiHereFeatureTipVisual.tsx b/src/renderer/src/components/feature-tips/ChatUiHereFeatureTipVisual.tsx index 8843b4abca0..504ce6f3b20 100644 --- a/src/renderer/src/components/feature-tips/ChatUiHereFeatureTipVisual.tsx +++ b/src/renderer/src/components/feature-tips/ChatUiHereFeatureTipVisual.tsx @@ -5,7 +5,7 @@ import { usePrefersReducedMotion } from '@/components/feature-wall/feature-wall- import { nativeChatPermissionModeLabel } from '@/components/native-chat/session/options/controls/native-chat-permission-mode-labels' import { nativeChatToolRowVerb } from '@/components/native-chat/tools/lines/native-chat-tool-line-label' import { useIntlLocale, useTranslate } from '@/i18n/use-translate' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { cn } from '@/lib/utils' import { CHAT_DEMO_FILE, diff --git a/src/renderer/src/components/feature-tips/CliSkillSetupPanel.tsx b/src/renderer/src/components/feature-tips/CliSkillSetupPanel.tsx index 973778d798a..29e6bc84d87 100644 --- a/src/renderer/src/components/feature-tips/CliSkillSetupPanel.tsx +++ b/src/renderer/src/components/feature-tips/CliSkillSetupPanel.tsx @@ -1,6 +1,9 @@ import { CliSkillSetupTerminal } from './CliSkillSetupTerminal' import { AgentSkillSetupPanel } from '@/components/skills/setup/AgentSkillSetupPanel' -import { ORCA_CLI_SKILL_NAME, ORCHESTRATION_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { + ORCA_CLI_SKILL_NAME, + ORCHESTRATION_SKILL_NAME +} from '@/lib/skills/installation/agent-feature-skill-names' import { useActiveProjectSkillRuntime } from '@/hooks/useActiveProjectSkillRuntime' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, diff --git a/src/renderer/src/components/feature-tips/CliSkillSetupTerminal.tsx b/src/renderer/src/components/feature-tips/CliSkillSetupTerminal.tsx index a8ed33a815b..66dba756e26 100644 --- a/src/renderer/src/components/feature-tips/CliSkillSetupTerminal.tsx +++ b/src/renderer/src/components/feature-tips/CliSkillSetupTerminal.tsx @@ -8,7 +8,7 @@ import { buildSkillCommandForRuntime, buildSkillSetupTerminalCommand } from '@/lib/skill-runtime-command' -import { ORCA_CLI_ORCHESTRATION_SKILL_INSTALL_COMMAND } from '@/lib/agent-feature-install-commands' +import { ORCA_CLI_ORCHESTRATION_SKILL_INSTALL_COMMAND } from '@/lib/skills/installation/agent-feature-install-commands' import { useActiveProjectSkillRuntime } from '@/hooks/useActiveProjectSkillRuntime' import { useTranslate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/feature-tips/feature-tip-session-panel-demo.tsx b/src/renderer/src/components/feature-tips/feature-tip-session-panel-demo.tsx index 31241c22cd8..a555cebaa37 100644 --- a/src/renderer/src/components/feature-tips/feature-tip-session-panel-demo.tsx +++ b/src/renderer/src/components/feature-tips/feature-tip-session-panel-demo.tsx @@ -16,7 +16,7 @@ import { DEFAULT_AI_VAULT_GROUP, DEFAULT_AI_VAULT_HIDE_EMPTY_SESSIONS } from '@/components/right-sidebar/ai-vault/scope/ai-vault-view-defaults' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useTranslate } from '@/i18n/use-translate' import type { SessionSearchDemoRow } from './session-search-feature-tip-demo' diff --git a/src/renderer/src/components/feature-wall/AgentCapabilitiesSetupAction.tsx b/src/renderer/src/components/feature-wall/AgentCapabilitiesSetupAction.tsx index 37296243aeb..d9c96a59896 100644 --- a/src/renderer/src/components/feature-wall/AgentCapabilitiesSetupAction.tsx +++ b/src/renderer/src/components/feature-wall/AgentCapabilitiesSetupAction.tsx @@ -5,7 +5,7 @@ import { import { bundledSkillSetupActionLabel } from '../skills/setup/bundled-skill-setup-copy' import { useOnboardingSkillRuntime } from '@/hooks/use-onboarding-skill-runtime' import { FeatureSetupInlineTerminal } from '../onboarding/FeatureSetupInlineTerminal' -import { buildAgentFeatureSkillInstallCommand } from '@/lib/agent-feature-install-commands' +import { buildAgentFeatureSkillInstallCommand } from '@/lib/skills/installation/agent-feature-install-commands' import { buildSkillCommandForRuntime } from '../../lib/skill-runtime-command' import type { OnboardingFeatureSetupRuntimeContext } from '../onboarding/onboarding-feature-setup-runtime' import { useCallback, useEffect, useRef, useState } from 'react' diff --git a/src/renderer/src/components/feature-wall/BrowserUseSkillSetupCard.tsx b/src/renderer/src/components/feature-wall/BrowserUseSkillSetupCard.tsx index 79117be2416..50ba20b0691 100644 --- a/src/renderer/src/components/feature-wall/BrowserUseSkillSetupCard.tsx +++ b/src/renderer/src/components/feature-wall/BrowserUseSkillSetupCard.tsx @@ -1,5 +1,5 @@ import type { JSX } from 'react' -import { ORCA_CLI_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_CLI_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { BROWSER_USE_ENABLED_STORAGE_KEY } from '@/lib/browser/browser-use-setup-state' import type { InstalledAgentSkillState } from '@/hooks/useInstalledAgentSkills' import { useActiveProjectSkillRuntime } from '@/hooks/useActiveProjectSkillRuntime' diff --git a/src/renderer/src/components/feature-wall/FeatureWallBrowserAction.tsx b/src/renderer/src/components/feature-wall/FeatureWallBrowserAction.tsx index 2e5dacb6e21..c75a4e6cde8 100644 --- a/src/renderer/src/components/feature-wall/FeatureWallBrowserAction.tsx +++ b/src/renderer/src/components/feature-wall/FeatureWallBrowserAction.tsx @@ -1,9 +1,9 @@ import { useBundledSkillInstallAction } from '@/hooks/use-bundled-skill-install-action' import { bundledSkillSetupActionLabel } from '../skills/setup/bundled-skill-setup-copy' -import { ORCA_CLI_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_CLI_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { useOnboardingSkillRuntime } from '@/hooks/use-onboarding-skill-runtime' import { FeatureSetupInlineTerminal } from '../onboarding/FeatureSetupInlineTerminal' -import { buildAgentFeatureSkillInstallCommand } from '@/lib/agent-feature-install-commands' +import { buildAgentFeatureSkillInstallCommand } from '@/lib/skills/installation/agent-feature-install-commands' import { buildSkillCommandForRuntime } from '../../lib/skill-runtime-command' import type { OnboardingFeatureSetupRuntimeContext } from '../onboarding/onboarding-feature-setup-runtime' import { useCallback, useState } from 'react' diff --git a/src/renderer/src/components/feature-wall/OrchestrationSetupCard.tsx b/src/renderer/src/components/feature-wall/OrchestrationSetupCard.tsx index 587853da0a9..b4414b55fd4 100644 --- a/src/renderer/src/components/feature-wall/OrchestrationSetupCard.tsx +++ b/src/renderer/src/components/feature-wall/OrchestrationSetupCard.tsx @@ -1,5 +1,5 @@ import type { JSX } from 'react' -import { ORCHESTRATION_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCHESTRATION_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import type { InstalledAgentSkillState } from '@/hooks/useInstalledAgentSkills' import { useActiveProjectSkillRuntime } from '@/hooks/useActiveProjectSkillRuntime' import { AgentSkillSetupPanel } from '../skills/setup/AgentSkillSetupPanel' diff --git a/src/renderer/src/components/feature-wall/agent-capability-setup-status.ts b/src/renderer/src/components/feature-wall/agent-capability-setup-status.ts index 192f3010d2e..102ccf8ac71 100644 --- a/src/renderer/src/components/feature-wall/agent-capability-setup-status.ts +++ b/src/renderer/src/components/feature-wall/agent-capability-setup-status.ts @@ -7,7 +7,7 @@ import { COMPUTER_USE_SKILL_NAME, ORCA_CLI_SKILL_NAME, ORCHESTRATION_SKILL_NAME -} from '@/lib/agent-feature-skill-names' +} from '@/lib/skills/installation/agent-feature-skill-names' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkill diff --git a/src/renderer/src/components/feature-wall/agents-orchestration/StatusesPage.tsx b/src/renderer/src/components/feature-wall/agents-orchestration/StatusesPage.tsx index d5a4de1475b..2fa39d369e2 100644 --- a/src/renderer/src/components/feature-wall/agents-orchestration/StatusesPage.tsx +++ b/src/renderer/src/components/feature-wall/agents-orchestration/StatusesPage.tsx @@ -2,7 +2,8 @@ import { useEffect, useRef, useState } from 'react' import type { JSX, ReactNode } from 'react' import { Wrench } from 'lucide-react' import { AgentStateDot } from '@/components/AgentStateDot' -import { getAgentCatalog, AgentIcon, type AgentCatalogEntry } from '@/lib/agent-catalog' +import { getAgentCatalog, type AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { ClaudeIcon, OpenAIIcon } from '../../status-bar/icons' import { installWindowVisibilityInterval } from '@/lib/window-visibility-interval' import { cn } from '@/lib/utils' diff --git a/src/renderer/src/components/feature-wall/ai-commit-pr-settings-helpers.ts b/src/renderer/src/components/feature-wall/ai-commit-pr-settings-helpers.ts index 7a5f4046b7c..53e37a5f95d 100644 --- a/src/renderer/src/components/feature-wall/ai-commit-pr-settings-helpers.ts +++ b/src/renderer/src/components/feature-wall/ai-commit-pr-settings-helpers.ts @@ -8,7 +8,7 @@ import { type CommitMessageAgentChoice, type CommitMessageModelCapability } from '../../../../shared/source-control/ai/generation/commit-message-agent-spec' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' export const EMPTY_COMMIT_MESSAGE_AI_SETTINGS: CommitMessageAiSettings = { enabled: false, diff --git a/src/renderer/src/components/feature-wall/use-feature-wall-tour-skills.ts b/src/renderer/src/components/feature-wall/use-feature-wall-tour-skills.ts index 4545f81db62..1185bf0b6cf 100644 --- a/src/renderer/src/components/feature-wall/use-feature-wall-tour-skills.ts +++ b/src/renderer/src/components/feature-wall/use-feature-wall-tour-skills.ts @@ -1,4 +1,7 @@ -import { ORCA_CLI_SKILL_NAME, ORCHESTRATION_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { + ORCA_CLI_SKILL_NAME, + ORCHESTRATION_SKILL_NAME +} from '@/lib/skills/installation/agent-feature-skill-names' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkill diff --git a/src/renderer/src/components/feature-wall/useAiCommitPrSettings.ts b/src/renderer/src/components/feature-wall/useAiCommitPrSettings.ts index 1ab62151757..719167987c6 100644 --- a/src/renderer/src/components/feature-wall/useAiCommitPrSettings.ts +++ b/src/renderer/src/components/feature-wall/useAiCommitPrSettings.ts @@ -11,7 +11,7 @@ import { LOCAL_COMMIT_MESSAGE_HOST_KEY } from '../../../../shared/source-control import { getDefaultSourceControlAiSettings } from '../../../../shared/source-control/ai/settings/source-control-ai-settings' import { getTextGenerationModels } from '../../../../shared/source-control/ai/settings/source-control-ai-model-selection' import { isTuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent-config' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { useAppStore } from '@/store/index' import type { AgentPickerDraft, diff --git a/src/renderer/src/components/floating-terminal/FloatingTerminalOrchestrationDialog.tsx b/src/renderer/src/components/floating-terminal/FloatingTerminalOrchestrationDialog.tsx index 0140259f836..39bc18b48cf 100644 --- a/src/renderer/src/components/floating-terminal/FloatingTerminalOrchestrationDialog.tsx +++ b/src/renderer/src/components/floating-terminal/FloatingTerminalOrchestrationDialog.tsx @@ -9,7 +9,7 @@ import { import { AgentSkillSetupPanel } from '@/components/skills/setup/AgentSkillSetupPanel' import { IntegrationStatusPill } from '@/components/integration-status-pill' import { SkillFreshnessStatusPill } from '@/components/skills/SkillFreshnessStatusPill' -import { ORCHESTRATION_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCHESTRATION_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkill diff --git a/src/renderer/src/components/floating-terminal/FloatingTerminalWindowControls.tsx b/src/renderer/src/components/floating-terminal/FloatingTerminalWindowControls.tsx index d31dda2e7ae..32d7b8bb2f7 100644 --- a/src/renderer/src/components/floating-terminal/FloatingTerminalWindowControls.tsx +++ b/src/renderer/src/components/floating-terminal/FloatingTerminalWindowControls.tsx @@ -2,7 +2,8 @@ import { useCallback, useMemo } from 'react' import { Maximize2, Minimize2, Minus } from 'lucide-react' import { Button } from '@/components/ui/button' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' -import { getAgentCatalog, AgentIcon } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { focusTerminalTabSurface } from '@/lib/focus-terminal-tab-surface' import { launchAgentInNewTab } from '@/lib/agent-session/launch/new-tab/launch-agent-in-new-tab' import { newAgentLaunchRequestId } from '@/lib/agent-session/launch/routing/agent-launch-request-id' diff --git a/src/renderer/src/components/floating-terminal/use-floating-terminal-orchestration-visibility.ts b/src/renderer/src/components/floating-terminal/use-floating-terminal-orchestration-visibility.ts index fdfadb6fbc8..dd730267828 100644 --- a/src/renderer/src/components/floating-terminal/use-floating-terminal-orchestration-visibility.ts +++ b/src/renderer/src/components/floating-terminal/use-floating-terminal-orchestration-visibility.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect } from 'react' -import { isOrcaCliAvailableOnPath } from '@/lib/agent-skill-cli-prerequisite' +import { isOrcaCliAvailableOnPath } from '@/lib/skills/installation/agent-skill-cli-prerequisite' import { ORCHESTRATION_SETUP_STATE_EVENT, hasOrchestrationSetupMarker, diff --git a/src/renderer/src/components/native-chat/composer/submit/use-native-chat-structured-composer-send.ts b/src/renderer/src/components/native-chat/composer/submit/use-native-chat-structured-composer-send.ts index 3eed84ab13a..da38e3036ca 100644 --- a/src/renderer/src/components/native-chat/composer/submit/use-native-chat-structured-composer-send.ts +++ b/src/renderer/src/components/native-chat/composer/submit/use-native-chat-structured-composer-send.ts @@ -4,7 +4,7 @@ import { captureNativeChatStagedInput } from '../../drafts/native-chat-draft-attachment-staging' import { mayHoldAgentReferences } from '../../../../../../shared/orchestration/mailbox/orchestration-agent-reference' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import { formatAgentTypeLabel } from '../../../../../../shared/agent-status/presentation/agent-type-label' import { isTuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' import { MAX_SKILL_REFS } from '../../../../../../shared/rpc-contract/structured-agent-session-message-params' diff --git a/src/renderer/src/components/native-chat/host-access/NativeChatInstallTile.tsx b/src/renderer/src/components/native-chat/host-access/NativeChatInstallTile.tsx index cf9e2268acf..582e358c220 100644 --- a/src/renderer/src/components/native-chat/host-access/NativeChatInstallTile.tsx +++ b/src/renderer/src/components/native-chat/host-access/NativeChatInstallTile.tsx @@ -1,5 +1,5 @@ import { TriangleAlert } from 'lucide-react' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { agentTypeToIconAgent } from '../../../../../shared/agent-status/presentation/agent-type-icon-agent' import { cn } from '@/lib/utils' import type { AgentType } from '../../../../../shared/agent-status/contracts/agent-status-types' diff --git a/src/renderer/src/components/native-chat/messages/agent-senders/native-chat-agent-message-sender-source.ts b/src/renderer/src/components/native-chat/messages/agent-senders/native-chat-agent-message-sender-source.ts index 3686d1c0929..010560ee33f 100644 --- a/src/renderer/src/components/native-chat/messages/agent-senders/native-chat-agent-message-sender-source.ts +++ b/src/renderer/src/components/native-chat/messages/agent-senders/native-chat-agent-message-sender-source.ts @@ -9,7 +9,7 @@ import { import { createWorktreeAgentFreshnessSelector } from '@/components/sidebar/workspace-card/activity/worktree-agent-freshness-selector' import '@/components/sidebar/workspace-card/activity/worktree-agent-row-selectors' import { selectWorktreeAgentOrchestration as selectRuntimeAgentOrchestrationForWorktree } from '@/components/sidebar/workspace-card/activity/worktree-agent-orchestration-index' -import { agentRowDisplayDotState } from '@/lib/agent-row-dot-state' +import { agentRowDisplayDotState } from '@/lib/agent-status/presentation/agent-row-dot-state' import { resolveRowProgramStatus } from '@/lib/program-status/agent-row-presentation' import { agentMessageSenderView, diff --git a/src/renderer/src/components/native-chat/messages/rows/NativeChatAgentMessageCard.tsx b/src/renderer/src/components/native-chat/messages/rows/NativeChatAgentMessageCard.tsx index 8bdcbfb653b..0e07ae67a6a 100644 --- a/src/renderer/src/components/native-chat/messages/rows/NativeChatAgentMessageCard.tsx +++ b/src/renderer/src/components/native-chat/messages/rows/NativeChatAgentMessageCard.tsx @@ -1,7 +1,7 @@ import { useId } from 'react' import { ChevronDown } from 'lucide-react' import { AgentStateDot } from '@/components/AgentStateDot' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { translate } from '@/i18n/i18n' import { useTranslate, type Translate } from '@/i18n/use-translate' import { cn } from '@/lib/utils' diff --git a/src/renderer/src/components/native-chat/pane/actions/use-native-chat-hand-off.tsx b/src/renderer/src/components/native-chat/pane/actions/use-native-chat-hand-off.tsx index 20880d307d1..f02a53bffa8 100644 --- a/src/renderer/src/components/native-chat/pane/actions/use-native-chat-hand-off.tsx +++ b/src/renderer/src/components/native-chat/pane/actions/use-native-chat-hand-off.tsx @@ -9,7 +9,7 @@ import { AgentSessionContinuationDialog } from '@/components/agent-session-conti import { buildAgentSessionContinuationPrompt, type AgentSessionContinuationRequest -} from '@/lib/agent-session-continuation' +} from '@/lib/agent-session/context/agent-session-continuation' import { isTuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' import { callStructuredAgentSession } from '@/runtime/native-chat/requests/structured-agent-session-call' import { supportsStructuredAgentSessionContinuationContext } from '@/runtime/native-chat/host-capabilities/structured-agent-session-host-support' diff --git a/src/renderer/src/components/native-chat/pane/actions/use-native-chat-session-context-actions.tsx b/src/renderer/src/components/native-chat/pane/actions/use-native-chat-session-context-actions.tsx index ba947924b33..9e009550ee2 100644 --- a/src/renderer/src/components/native-chat/pane/actions/use-native-chat-session-context-actions.tsx +++ b/src/renderer/src/components/native-chat/pane/actions/use-native-chat-session-context-actions.tsx @@ -2,7 +2,7 @@ import { useCallback, useLayoutEffect, useRef, useState } from 'react' import { executionHostIdForStructuredTarget } from '@/runtime/native-chat/session-ownership/structured-agent-session-owner' import { useTranslate } from '@/i18n/use-translate' import type { AgentType } from '../../../../../../shared/agent-status/contracts/agent-status-types' -import { copyAgentSessionContext } from '@/lib/copy-agent-session-context' +import { copyAgentSessionContext } from '@/lib/agent-session/context/copy-agent-session-context' import { resolveNativeChatSessionContext, type NativeChatSessionContextSource diff --git a/src/renderer/src/components/native-chat/selection-quotes/native-chat-workspace-selection.ts b/src/renderer/src/components/native-chat/selection-quotes/native-chat-workspace-selection.ts index ecf19717574..3dc5e65160c 100644 --- a/src/renderer/src/components/native-chat/selection-quotes/native-chat-workspace-selection.ts +++ b/src/renderer/src/components/native-chat/selection-quotes/native-chat-workspace-selection.ts @@ -7,9 +7,9 @@ import { } from '../../../../../shared/workspace-layout/stable-pane-id' import type { AppState } from '@/store/types' import { useAppStore } from '@/store' -import type { AgentMessageTarget } from '@/lib/agent-message-target' -import { sendMessageToAgent } from '@/lib/agent-message-send' -import type { ActiveAgentNotesSendResult } from '@/lib/active-agent-note-send-result' +import type { AgentMessageTarget } from '@/lib/agent-session/messaging/agent-message-target' +import { sendMessageToAgent } from '@/lib/agent-session/messaging/agent-message-send' +import type { ActiveAgentNotesSendResult } from '@/lib/agent-session/messaging/terminal/active-agent-note-send-result' import { activateStructuredAgentSessionTab } from '@/lib/agent-session/structured-agent-session-tab-activation' import { activateTabAndFocusPane } from '@/lib/workspace/tabs/activate-tab-and-focus-pane' import { activateTerminalTabOnOwner } from '@/lib/workspace/tabs/terminal-tab-owner-activation' diff --git a/src/renderer/src/components/native-chat/session/options/terminal/serialized-screen-background-rows.test.ts b/src/renderer/src/components/native-chat/session/options/terminal/serialized-screen-background-rows.test.ts index a4549bc9abe..ff50d589d04 100644 --- a/src/renderer/src/components/native-chat/session/options/terminal/serialized-screen-background-rows.test.ts +++ b/src/renderer/src/components/native-chat/session/options/terminal/serialized-screen-background-rows.test.ts @@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest' import { Terminal } from '@xterm/headless' import { SerializeAddon } from '@xterm/addon-serialize' import { readClaudeSessionOptionsFromTerminalScreen } from './claude-terminal-session-options' -import { buildBoundedSessionTranscript } from '@/lib/agent-session-fork-context' +import { buildBoundedSessionTranscript } from '@/lib/agent-session/context/agent-session-fork-context' const CLAUDE_FRAME = [ '╭─ Claude Code ───╮', diff --git a/src/renderer/src/components/native-chat/tools/tasks/use-structured-session-child-row-context.ts b/src/renderer/src/components/native-chat/tools/tasks/use-structured-session-child-row-context.ts index 22930f93360..a8d6e7b4fca 100644 --- a/src/renderer/src/components/native-chat/tools/tasks/use-structured-session-child-row-context.ts +++ b/src/renderer/src/components/native-chat/tools/tasks/use-structured-session-child-row-context.ts @@ -3,10 +3,13 @@ import { agentChildRowContextForParent, type AgentChildRowContext } from '../../../../../../shared/agent-status/presentation/agent-child-row-model' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../../../shared/agent-status/contracts/agent-status-freshness' +import { + AGENT_STATUS_STALE_AFTER_MS, + isAgentStatusFresh +} from '../../../../../../shared/agent-status/contracts/agent-status-freshness' import type { AgentStatusEntry } from '../../../../../../shared/agent-status/contracts/agent-status-types' import { useNow } from '@/hooks/use-now' -import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' + import { useAppStore } from '@/store' /** The verdict a session's status row gives its children, exactly as the sidebar derives it. */ @@ -16,7 +19,7 @@ export function structuredSessionChildRowContext( ): AgentChildRowContext { return agentChildRowContextForParent( parent, - isExplicitAgentStatusFresh(parent, now, AGENT_STATUS_STALE_AFTER_MS) + isAgentStatusFresh(parent, now, AGENT_STATUS_STALE_AFTER_MS) ) } diff --git a/src/renderer/src/components/native-chat/usage/NativeChatUsageLimitActions.tsx b/src/renderer/src/components/native-chat/usage/NativeChatUsageLimitActions.tsx index 41b38c61586..5621382fb1a 100644 --- a/src/renderer/src/components/native-chat/usage/NativeChatUsageLimitActions.tsx +++ b/src/renderer/src/components/native-chat/usage/NativeChatUsageLimitActions.tsx @@ -18,7 +18,7 @@ import { AgentSessionContinuationDialog } from '@/components/agent-session-conti import { buildAgentSessionContinuationPrompt, type AgentSessionContinuationRequest -} from '@/lib/agent-session-continuation' +} from '@/lib/agent-session/context/agent-session-continuation' import { ClaudeSwitcherMenu } from '@/components/status-bar/ClaudeSwitcherMenu' import { ProviderAccountChatButton } from '@/components/status-bar/ProviderAccountChatButton' import { isTuiAgent } from '../../../../../shared/agent-launch/catalog/tui-agent-config' diff --git a/src/renderer/src/components/onboarding/AgentPickerButton.tsx b/src/renderer/src/components/onboarding/AgentPickerButton.tsx index 089ad0ba33f..d322c3c9149 100644 --- a/src/renderer/src/components/onboarding/AgentPickerButton.tsx +++ b/src/renderer/src/components/onboarding/AgentPickerButton.tsx @@ -1,5 +1,6 @@ import { Check } from 'lucide-react' -import { AgentIcon, type AgentCatalogEntry } from '@/lib/agent-catalog' +import type { AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { cn } from '@/lib/utils' export function AgentSectionHeader({ diff --git a/src/renderer/src/components/onboarding/AgentStep.tsx b/src/renderer/src/components/onboarding/AgentStep.tsx index f7dde2a9ae5..ab6249cf734 100644 --- a/src/renderer/src/components/onboarding/AgentStep.tsx +++ b/src/renderer/src/components/onboarding/AgentStep.tsx @@ -1,7 +1,7 @@ import { useState } from 'react' import { ExternalLink } from 'lucide-react' import { Trans } from 'react-i18next' -import { getAgentCatalog, type AgentCatalogEntry } from '@/lib/agent-catalog' +import { getAgentCatalog, type AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' import { Button } from '@/components/ui/button' import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible' import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' diff --git a/src/renderer/src/components/onboarding/TerminalLaunchDemo.tsx b/src/renderer/src/components/onboarding/TerminalLaunchDemo.tsx index 7fa3f1da2e7..cd73e0da8b0 100644 --- a/src/renderer/src/components/onboarding/TerminalLaunchDemo.tsx +++ b/src/renderer/src/components/onboarding/TerminalLaunchDemo.tsx @@ -1,5 +1,6 @@ import { MessagesSquare, SquareTerminal } from 'lucide-react' -import { AgentIcon, getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useTranslate } from '@/i18n/use-translate' // Shell text, not prose: what a terminal shows when the agent's CLI starts. diff --git a/src/renderer/src/components/onboarding/YoloPermissionsControl.tsx b/src/renderer/src/components/onboarding/YoloPermissionsControl.tsx index 5a7d43e9fc6..84c33613b30 100644 --- a/src/renderer/src/components/onboarding/YoloPermissionsControl.tsx +++ b/src/renderer/src/components/onboarding/YoloPermissionsControl.tsx @@ -2,7 +2,7 @@ import { useId, useState } from 'react' import { Button } from '@/components/ui/button' import { Switch } from '@/components/ui/switch' import { useTranslate } from '@/i18n/use-translate' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import { useAppStore } from '@/store' import { applyAgentPermissionOverrides, diff --git a/src/renderer/src/components/onboarding/onboarding-completion-agent-launch.ts b/src/renderer/src/components/onboarding/onboarding-completion-agent-launch.ts index 22f6e3aec81..ac04cb947ed 100644 --- a/src/renderer/src/components/onboarding/onboarding-completion-agent-launch.ts +++ b/src/renderer/src/components/onboarding/onboarding-completion-agent-launch.ts @@ -1,5 +1,5 @@ import { useAppStore } from '@/store' -import { resolveDefaultAgentForWorktree } from '@/lib/agent-tab-shortcuts' +import { resolveDefaultAgentForWorktree } from '@/lib/agent-session/launch/shortcuts/agent-tab-shortcuts' import { agentTabLaunchStore } from '@/lib/agent-session/launch/new-tab/launch-agent-execution-context' import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' import type { ExecutionHostId } from '../../../../shared/execution-host' diff --git a/src/renderer/src/components/onboarding/onboarding-feature-setup.test.ts b/src/renderer/src/components/onboarding/onboarding-feature-setup.test.ts index 8b3c9095065..0c32da19e6f 100644 --- a/src/renderer/src/components/onboarding/onboarding-feature-setup.test.ts +++ b/src/renderer/src/components/onboarding/onboarding-feature-setup.test.ts @@ -3,7 +3,7 @@ import type { ComputerUsePermissionSetupResult, ComputerUsePermissionStatusResult } from '../../../../shared/computer-use-permissions-types' -import { ORCHESTRATION_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCHESTRATION_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { BROWSER_USE_ENABLED_STORAGE_KEY } from '@/lib/browser/browser-use-setup-state' import { ORCHESTRATION_ENABLED_STORAGE_KEY } from '@/lib/orchestration-setup-state' import { diff --git a/src/renderer/src/components/onboarding/onboarding-feature-setup.ts b/src/renderer/src/components/onboarding/onboarding-feature-setup.ts index fb7b19c77b5..6b76c79d9ee 100644 --- a/src/renderer/src/components/onboarding/onboarding-feature-setup.ts +++ b/src/renderer/src/components/onboarding/onboarding-feature-setup.ts @@ -7,7 +7,7 @@ import { ORCA_LINEAR_SKILL_NAME, ORCA_CLI_SKILL_NAME, ORCHESTRATION_SKILL_NAME -} from '@/lib/agent-feature-skill-names' +} from '@/lib/skills/installation/agent-feature-skill-names' import { BROWSER_USE_ENABLED_STORAGE_KEY } from '@/lib/browser/browser-use-setup-state' import { e2eConfig } from '@/lib/e2e-config' import { diff --git a/src/renderer/src/components/onboarding/use-onboarding-agent-surface.ts b/src/renderer/src/components/onboarding/use-onboarding-agent-surface.ts index e62a29467e0..a7058d3b74f 100644 --- a/src/renderer/src/components/onboarding/use-onboarding-agent-surface.ts +++ b/src/renderer/src/components/onboarding/use-onboarding-agent-surface.ts @@ -3,7 +3,10 @@ import { LOCAL_EXECUTION_HOST_ID } from '../../../../shared/execution-host' import type { GlobalSettings } from '../../../../shared/global-settings-types' import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' import { nativeChatPreferenceFor } from '../../../../shared/structured-native-chat-launch-route' -import { chatProviderAgents, useHostStructuredAgentsVersion } from '@/lib/chat-provider-agents' +import { + chatProviderAgents, + useHostStructuredAgentsVersion +} from '@/runtime/native-chat/agent-catalogs/chat-provider-agents' import { recomputeOn } from '@/lib/recompute-on' import type { ProspectiveWorkspace } from '@/lib/agent-session/launch/routing/agent-launch-route-input' import { readChatProgram, resolveChatProgramContext } from '@/lib/host-chat-program' diff --git a/src/renderer/src/components/onboarding/use-onboarding-flow-actions.test.tsx b/src/renderer/src/components/onboarding/use-onboarding-flow-actions.test.tsx index 8263d8ab3cc..b72da1b96bd 100644 --- a/src/renderer/src/components/onboarding/use-onboarding-flow-actions.test.tsx +++ b/src/renderer/src/components/onboarding/use-onboarding-flow-actions.test.tsx @@ -54,7 +54,9 @@ vi.mock('@/components/agent-tab-launch-context', () => ({ captureAgentTabLaunchContext: () => ({ groupId: 'group', focusIntent }) })) vi.mock('@/lib/telemetry', () => ({ track })) -vi.mock('@/lib/agent-detection-target-inventory', () => ({ loadDetectedAgentsForWorktree: detect })) +vi.mock('@/lib/agent-session/launch/inventory/agent-detection-target-inventory', () => ({ + loadDetectedAgentsForWorktree: detect +})) vi.mock('@/lib/host-chat-program-acquisition', () => ({ acquireAgentLaunchChoices: acquireChoices })) diff --git a/src/renderer/src/components/onboarding/use-onboarding-flow.ts b/src/renderer/src/components/onboarding/use-onboarding-flow.ts index e857b677a56..d4c7a541b92 100644 --- a/src/renderer/src/components/onboarding/use-onboarding-flow.ts +++ b/src/renderer/src/components/onboarding/use-onboarding-flow.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { toast } from 'sonner' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { useAppStore } from '@/store' import { selectOnboardingWorkspaceId } from './onboarding-workspace-selection' import { applyDocumentTheme } from '@/lib/document-theme' diff --git a/src/renderer/src/components/orchestration-crew/CrewAgentIcons.tsx b/src/renderer/src/components/orchestration-crew/CrewAgentIcons.tsx index 4989c9688cd..7c29826bfec 100644 --- a/src/renderer/src/components/orchestration-crew/CrewAgentIcons.tsx +++ b/src/renderer/src/components/orchestration-crew/CrewAgentIcons.tsx @@ -1,10 +1,10 @@ import { useMemo } from 'react' import StatusIndicator from '@/components/sidebar/workspace-card/surface/StatusIndicator' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { cn } from '@/lib/utils' -import { getAgentLabel } from '@/lib/agent-catalog' -import { mapAgentStatusStateToVisualStatus } from '@/lib/agent-status' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' +import { mapAgentStatusStateToVisualStatus } from '@/lib/agent-status/aggregation/worktree-agent-status' import { getWorktreeStatusLabel, type WorktreeStatus } from '@/lib/worktree-status' import { useAgentMessageSenderViews, diff --git a/src/renderer/src/components/pet/PetOverlay.tsx b/src/renderer/src/components/pet/PetOverlay.tsx index c647ef28f20..223534ddae5 100644 --- a/src/renderer/src/components/pet/PetOverlay.tsx +++ b/src/renderer/src/components/pet/PetOverlay.tsx @@ -4,7 +4,7 @@ import { usePetUrl } from './usePetUrl' import type { DetectedSpriteCacheEntry } from './pet-blob-cache' import type { CustomPet } from '../../../../shared/pet-types' import { useAppStore } from '../../store' -import { getAgentStatusEpochNow } from '@/lib/agent-status-epoch-clock' +import { getAgentStatusEpochNow } from '@/lib/agent-status/evidence/agent-status-epoch-clock' import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../shared/agent-status/contracts/agent-status-freshness' import { selectPetAnimationName, diff --git a/src/renderer/src/components/pet/pet-agent-state.ts b/src/renderer/src/components/pet/pet-agent-state.ts index ad1899be9a0..f56d61562a0 100644 --- a/src/renderer/src/components/pet/pet-agent-state.ts +++ b/src/renderer/src/components/pet/pet-agent-state.ts @@ -1,5 +1,5 @@ import type { AgentStatusEntry } from '../../../../shared/agent-status/contracts/agent-status-types' -import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' +import { isAgentStatusFresh } from '../../../../shared/agent-status/contracts/agent-status-freshness' export type PetAnimationName = | 'idle' @@ -46,7 +46,7 @@ function agentStateAnimation( let hasDone = false for (const entry of entries) { - if (!isExplicitAgentStatusFresh(entry, now, staleAfterMs)) { + if (!isAgentStatusFresh(entry, now, staleAfterMs)) { continue } if (entry.state === 'blocked' || entry.state === 'waiting') { diff --git a/src/renderer/src/components/pull-request-page/checks/fix-launch.ts b/src/renderer/src/components/pull-request-page/checks/fix-launch.ts index be9111f5aab..05b033b6298 100644 --- a/src/renderer/src/components/pull-request-page/checks/fix-launch.ts +++ b/src/renderer/src/components/pull-request-page/checks/fix-launch.ts @@ -1,4 +1,7 @@ -import { agentLaunchRecoveryMessage, notifyAgentLaunchFailure } from '@/lib/agent-launch-failure' +import { + agentLaunchRecoveryMessage, + notifyAgentLaunchFailure +} from '@/lib/agent-session/launch/failure/agent-launch-failure' import type { DirectWorkItemLaunchResult } from '@/lib/workspace/creation/work-item/direct-work-item-setup' import { toast } from 'sonner' import { useAppStore } from '@/store' diff --git a/src/renderer/src/components/right-sidebar/ai-vault/panel/AiVaultPanelControls.tsx b/src/renderer/src/components/right-sidebar/ai-vault/panel/AiVaultPanelControls.tsx index 98792d4671a..d3a60d25c55 100644 --- a/src/renderer/src/components/right-sidebar/ai-vault/panel/AiVaultPanelControls.tsx +++ b/src/renderer/src/components/right-sidebar/ai-vault/panel/AiVaultPanelControls.tsx @@ -21,7 +21,7 @@ import { DropdownMenuTrigger } from '@/components/ui/dropdown-menu' import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { cn } from '@/lib/utils' import { AI_VAULT_AGENTS, diff --git a/src/renderer/src/components/right-sidebar/ai-vault/scanning/AiVaultScanProgressStrip.tsx b/src/renderer/src/components/right-sidebar/ai-vault/scanning/AiVaultScanProgressStrip.tsx index 9f7a198be66..5d7ca2c40eb 100644 --- a/src/renderer/src/components/right-sidebar/ai-vault/scanning/AiVaultScanProgressStrip.tsx +++ b/src/renderer/src/components/right-sidebar/ai-vault/scanning/AiVaultScanProgressStrip.tsx @@ -6,7 +6,7 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/component import { useNow } from '@/hooks/use-now' import { getIntlLocale, translate } from '@/i18n/i18n' import { useIntlLocale, useTranslate, type Translate } from '@/i18n/use-translate' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { cn } from '@/lib/utils' import type { AiVaultScanAgentProgress, diff --git a/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-original-pane-index.ts b/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-original-pane-index.ts index 04a3a62bf86..cfbb981f08a 100644 --- a/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-original-pane-index.ts +++ b/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-original-pane-index.ts @@ -1,4 +1,4 @@ -import { agentRowDisplayDotState } from '@/lib/agent-row-dot-state' +import { agentRowDisplayDotState } from '@/lib/agent-status/presentation/agent-row-dot-state' import type { AgentDotState } from '@/components/AgentStateDot' import type { AiVaultSession } from '../../../../../../shared/ai-vault/contracts/ai-vault-types' import { diff --git a/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-original-pane.ts b/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-original-pane.ts index 41a1d04bf9c..d16b87dc528 100644 --- a/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-original-pane.ts +++ b/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-original-pane.ts @@ -1,4 +1,4 @@ -import { agentRowDisplayDotState } from '@/lib/agent-row-dot-state' +import { agentRowDisplayDotState } from '@/lib/agent-status/presentation/agent-row-dot-state' import type { AppState } from '@/store/types' import { resolveRuntimePaneTitleLeafId } from '../../../../../../shared/runtime-pane-title-leaf-id' import type { AgentDotState } from '@/components/AgentStateDot' diff --git a/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-session-continuation.ts b/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-session-continuation.ts index 9f0e6ff07bc..c122fb22950 100644 --- a/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-session-continuation.ts +++ b/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-session-continuation.ts @@ -1,4 +1,4 @@ -import type { AgentSessionContinuationRequest } from '@/lib/agent-session-continuation' +import type { AgentSessionContinuationRequest } from '@/lib/agent-session/context/agent-session-continuation' import type { AiVaultSession } from '../../../../../../shared/ai-vault/contracts/ai-vault-types' export function canContinueAiVaultSessionInNewSession( diff --git a/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-session-launch-actions.ts b/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-session-launch-actions.ts index 4730e607073..b7312cb9b42 100644 --- a/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-session-launch-actions.ts +++ b/src/renderer/src/components/right-sidebar/ai-vault/session-actions/ai-vault-session-launch-actions.ts @@ -34,7 +34,7 @@ import { translate } from '@/i18n/i18n' import { describeAiVaultCliForkFailure } from './ai-vault-session-cli-fork' import type { AiVaultSessionResumeTargetState } from './ai-vault-session-resume' import { prepareAiVaultSessionContinuation } from './ai-vault-session-continuation' -import type { AgentSessionContinuationRequest } from '@/lib/agent-session-continuation' +import type { AgentSessionContinuationRequest } from '@/lib/agent-session/context/agent-session-continuation' import { activateAiVaultStructuredSession } from '@/lib/activate-ai-vault-structured-session' import { adoptsCliConversations } from '../../../../../../shared/structured-agent-cli-conversation-adoption' import { newAgentLaunchRequestId } from '@/lib/agent-session/launch/routing/agent-launch-request-id' diff --git a/src/renderer/src/components/right-sidebar/ai-vault/session-list/ai-vault-session-row-display.tsx b/src/renderer/src/components/right-sidebar/ai-vault/session-list/ai-vault-session-row-display.tsx index 7b7c152c34b..95897712ebf 100644 --- a/src/renderer/src/components/right-sidebar/ai-vault/session-list/ai-vault-session-row-display.tsx +++ b/src/renderer/src/components/right-sidebar/ai-vault/session-list/ai-vault-session-row-display.tsx @@ -7,7 +7,7 @@ import { Badge } from '@/components/ui/badge' import { WorktreeHostContextBadge } from '@/components/sidebar/workspace-card/host/WorktreeHostContextBadge' import RepoBadgeLabel from '@/components/repo/RepoBadgeLabel' import { AgentStateDot, type AgentDotState } from '@/components/AgentStateDot' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useRepoById } from '@/store/repos/use-repository-catalog' import { resolveRepoBadgeColor } from '../../../../../../shared/repo-badge-color' diff --git a/src/renderer/src/components/right-sidebar/checks-panel/use-checks-panel-controller-state.tsx b/src/renderer/src/components/right-sidebar/checks-panel/use-checks-panel-controller-state.tsx index 3a31a6049e5..61fa4ba4d1b 100644 --- a/src/renderer/src/components/right-sidebar/checks-panel/use-checks-panel-controller-state.tsx +++ b/src/renderer/src/components/right-sidebar/checks-panel/use-checks-panel-controller-state.tsx @@ -7,7 +7,7 @@ import { useActiveWorktree } from '@/store/workspaces/selection/use-selected-wor import { selectReviewRepositoryForWorkspace } from '@/store/slices/hosted-review/workspace-review-repository' import { useChecksPanelTerminalWorktree } from './refresh/use-checks-panel-terminal-worktree' import { getConnectionId } from '@/lib/workspace/ownership/connection-context' -import { readDetectedAgentsForWorktree } from '@/lib/agent-detection-target-inventory' +import { readDetectedAgentsForWorktree } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { useMountedRef } from '@/hooks/useMountedRef' import { useConfirmationDialog } from '@/components/confirmation-dialog-context' import { getWorktreeGitIdentityDisplay } from '../../../../../shared/worktree/git-identity-display' diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/SourceControlAgentActionDialogForm.tsx b/src/renderer/src/components/right-sidebar/source-control/ai/SourceControlAgentActionDialogForm.tsx index 89bf718a569..6ae245fbef6 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/SourceControlAgentActionDialogForm.tsx +++ b/src/renderer/src/components/right-sidebar/source-control/ai/SourceControlAgentActionDialogForm.tsx @@ -17,7 +17,7 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select' -import type { AgentCatalogEntry } from '@/lib/agent-catalog' +import type { AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' import { cn } from '@/lib/utils' import type { SourceControlLaunchActionId } from '../../../../../../shared/source-control/ai/recipes/source-control-ai-actions' import type { SourceControlAiWriteTarget } from '../../../../../../shared/source-control/ai/settings/source-control-ai-recipe-save' diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/controller-types.ts b/src/renderer/src/components/right-sidebar/source-control/ai/controller-types.ts index 041293a431e..33414bd7515 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/controller-types.ts +++ b/src/renderer/src/components/right-sidebar/source-control/ai/controller-types.ts @@ -1,5 +1,5 @@ import type { AppState } from '@/store/types' -import type { WorktreeAgentInventoryState } from '@/lib/agent-detection-target-inventory' +import type { WorktreeAgentInventoryState } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import type { GitConflictOperation, GitStatusEntry diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/recovery-launch.ts b/src/renderer/src/components/right-sidebar/source-control/ai/recovery-launch.ts index a8dbca5179f..1fbb3965fc6 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/recovery-launch.ts +++ b/src/renderer/src/components/right-sidebar/source-control/ai/recovery-launch.ts @@ -22,7 +22,7 @@ import { getConnectionId } from '@/lib/workspace/ownership/connection-context' import { ensureDetectedAgentsForWorktree, type WorktreeAgentInventoryState -} from '@/lib/agent-detection-target-inventory' +} from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { pickSourceControlLaunchAgent, readSourceControlLaunchRecipeAgentId diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/runSourceControlAgentActionStart.ts b/src/renderer/src/components/right-sidebar/source-control/ai/runSourceControlAgentActionStart.ts index 6159328fe9b..ea8ae87cfc9 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/runSourceControlAgentActionStart.ts +++ b/src/renderer/src/components/right-sidebar/source-control/ai/runSourceControlAgentActionStart.ts @@ -17,7 +17,7 @@ import { newAgentLaunchRequestId } from '@/lib/agent-session/launch/routing/agen import type { RuntimeGitContext } from '@/runtime/source-control/git/runtime-git-client-context' import type { Repo } from '../../../../../../shared/repo-types' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' -import type { AgentLaunchChoice } from '@/lib/agent-menu-selection' +import type { AgentLaunchChoice } from '@/lib/agent-session/launch/routing/agent-menu-selection' import type { LaunchSource } from '../../../../../../shared/telemetry-property-schemas' import { normalizeSourceControlActionRecipe, diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/source-control-action-model-copy.ts b/src/renderer/src/components/right-sidebar/source-control/ai/source-control-action-model-copy.ts index 0e7636a2b6e..3fd6a47de9e 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/source-control-action-model-copy.ts +++ b/src/renderer/src/components/right-sidebar/source-control/ai/source-control-action-model-copy.ts @@ -10,7 +10,7 @@ import { } from '../../../../../../shared/source-control/ai/recipes/source-control-action-options' import { sourceControlActionSelectedPreferences } from '../../../../../../shared/source-control/ai/recipes/source-control-action-launch-preferences' import { translate } from '@/i18n/i18n' -import { AGENT_CATALOG } from '@/lib/agent-catalog' +import { AGENT_CATALOG } from '@/lib/agent-catalog/agent-catalog' import { agentPermissionChoiceLabel } from '../../../agent/launch-settings/agent-permission-choice-label' import { sourceControlActionRouteHint } from '../../../agent/launch-settings/agent-choice-route-hint' diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/source-control-agent-action-dialog-result.ts b/src/renderer/src/components/right-sidebar/source-control/ai/source-control-agent-action-dialog-result.ts index f30456fb8e0..d4de6d7985d 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/source-control-agent-action-dialog-result.ts +++ b/src/renderer/src/components/right-sidebar/source-control/ai/source-control-agent-action-dialog-result.ts @@ -6,7 +6,7 @@ import type { CurrentActionSelection, SelectedSourceControlActionRecipe } from '../../../../../../shared/source-control/ai/recipes/source-control-action-selection' -import type { getAgentCatalog } from '@/lib/agent-catalog' +import type { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import type { useAppStore } from '@/store/index' import type { useRepoById } from '@/store/repos/use-repository-catalog' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/source-control-agent-action-dialog-support.ts b/src/renderer/src/components/right-sidebar/source-control/ai/source-control-agent-action-dialog-support.ts index f9d919177eb..b9717605481 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/source-control-agent-action-dialog-support.ts +++ b/src/renderer/src/components/right-sidebar/source-control/ai/source-control-agent-action-dialog-support.ts @@ -1,6 +1,6 @@ import { useAppStore } from '@/store/index' -import { ensureDetectedAgentsForWorktree } from '@/lib/agent-detection-target-inventory' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { ensureDetectedAgentsForWorktree } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { isTuiAgentEnabled } from '../../../../../../shared/agent-launch/catalog/tui-agent-selection' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import type { SourceControlAiWriteTarget } from '../../../../../../shared/source-control/ai/settings/source-control-ai-recipe-save' diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/text-generation-dialog-form.tsx b/src/renderer/src/components/right-sidebar/source-control/ai/text-generation-dialog-form.tsx index a5c3067f883..2448d683637 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/text-generation-dialog-form.tsx +++ b/src/renderer/src/components/right-sidebar/source-control/ai/text-generation-dialog-form.tsx @@ -12,7 +12,7 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { AgentLaunchPicker } from '@/components/agent/AgentLaunchPicker' import { DropdownMenuItem } from '@/components/ui/dropdown-menu' import { commitMessagePickerModel } from '@/components/feature-wall/ai-commit-pr-picker' diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/use-saved-source-control-action-start.ts b/src/renderer/src/components/right-sidebar/source-control/ai/use-saved-source-control-action-start.ts index 5e5926f218e..12ce5c77466 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/use-saved-source-control-action-start.ts +++ b/src/renderer/src/components/right-sidebar/source-control/ai/use-saved-source-control-action-start.ts @@ -14,7 +14,7 @@ import { parseExecutionHostId } from '../../../../../../shared/execution-host' import { useRef, useState } from 'react' import { toast } from 'sonner' import { useAppStore } from '@/store/index' -import { ensureDetectedAgentsForWorktree } from '@/lib/agent-detection-target-inventory' +import { ensureDetectedAgentsForWorktree } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { isTuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' import { projectSelectedSourceControlActionLaunch } from '../../../../../../shared/source-control/ai/recipes/source-control-action-launch-preferences' import { sourceControlLaunchAppliesAgentArgs } from './source-control-launch-agent-args-applicability' diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/use-source-control-action-agent-choice.ts b/src/renderer/src/components/right-sidebar/source-control/ai/use-source-control-action-agent-choice.ts index 8c86228744e..2b22ad64702 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/use-source-control-action-agent-choice.ts +++ b/src/renderer/src/components/right-sidebar/source-control/ai/use-source-control-action-agent-choice.ts @@ -9,7 +9,7 @@ import type { SelectedSourceControlActionRecipe } from '../../../../../../shared import type { Repo } from '../../../../../../shared/repo-types' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import { isTuiAgentEnabled } from '../../../../../../shared/agent-launch/catalog/tui-agent-selection' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import type { AgentLaunchSurface } from '@/lib/agent-session/launch/routing/agent-session-launch-plan' import { useAgentDetectionTargetForWorktree } from '@/hooks/useAgentDetectionTarget' import { useAgentMenuObservation } from '@/components/tab-bar/use-new-tab-agent-menu-rows' diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/use-source-control-launchable-agents.ts b/src/renderer/src/components/right-sidebar/source-control/ai/use-source-control-launchable-agents.ts index 96b4a6fbaa8..c845afccedd 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/use-source-control-launchable-agents.ts +++ b/src/renderer/src/components/right-sidebar/source-control/ai/use-source-control-launchable-agents.ts @@ -5,7 +5,7 @@ import { ensureDetectedAgentsForWorktree, readAgentInventoryForWorktree, readAgentInventoryForTarget -} from '@/lib/agent-detection-target-inventory' +} from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import { sourceControlLaunchWorkspace } from './source-control-launch-agent-args-applicability' import { acquireAgentLaunchChoices, useChatProgramFacts } from '@/lib/host-chat-program-acquisition' diff --git a/src/renderer/src/components/right-sidebar/source-control/ai/useSourceControlAgentActionStart.ts b/src/renderer/src/components/right-sidebar/source-control/ai/useSourceControlAgentActionStart.ts index 9e84b203cef..d49687e9fb3 100644 --- a/src/renderer/src/components/right-sidebar/source-control/ai/useSourceControlAgentActionStart.ts +++ b/src/renderer/src/components/right-sidebar/source-control/ai/useSourceControlAgentActionStart.ts @@ -12,7 +12,7 @@ import type { import type { SourceControlAiWriteTarget } from '../../../../../../shared/source-control/ai/settings/source-control-ai-recipe-save' import type { Repo } from '../../../../../../shared/repo-types' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' -import type { AgentLaunchChoice } from '@/lib/agent-menu-selection' +import type { AgentLaunchChoice } from '@/lib/agent-session/launch/routing/agent-menu-selection' import { buildSourceControlAgentDeliveryPlan } from './buildSourceControlAgentDeliveryPlan' import type { SourceControlAgentActionDeliveryPlanState } from './SourceControlAgentActionDialogForm' import { diff --git a/src/renderer/src/components/right-sidebar/source-control/sync/use-git-history-commit-actions.ts b/src/renderer/src/components/right-sidebar/source-control/sync/use-git-history-commit-actions.ts index 81e3e0ad429..79307304571 100644 --- a/src/renderer/src/components/right-sidebar/source-control/sync/use-git-history-commit-actions.ts +++ b/src/renderer/src/components/right-sidebar/source-control/sync/use-git-history-commit-actions.ts @@ -9,8 +9,8 @@ import { sourceControlConnectionId, useSourceControlScope } from '../panel/workt import { detectLanguage } from '../../../../../../shared/editor-language/editor-language-detect' import { launchAgentInNewTab } from '@/lib/agent-session/launch/new-tab/launch-agent-in-new-tab' import { newAgentLaunchRequestId } from '@/lib/agent-session/launch/routing/agent-launch-request-id' -import { resolveDefaultAgentForWorktreeNewTab } from '@/lib/agent-tab-shortcuts' -import { getDetectionTargetIdentityForWorktree } from '@/lib/agent-detection-target-inventory' +import { resolveDefaultAgentForWorktreeNewTab } from '@/lib/agent-session/launch/shortcuts/agent-tab-shortcuts' +import { getDetectionTargetIdentityForWorktree } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { translate } from '@/i18n/i18n' import type { GitHistoryItem } from '../../../../../../shared/git/history/git-history-types' import type { diff --git a/src/renderer/src/components/settings/accounts/providers/AntigravityAccountsSection.test.tsx b/src/renderer/src/components/settings/accounts/providers/AntigravityAccountsSection.test.tsx index d98a7879cef..287ead6b52b 100644 --- a/src/renderer/src/components/settings/accounts/providers/AntigravityAccountsSection.test.tsx +++ b/src/renderer/src/components/settings/accounts/providers/AntigravityAccountsSection.test.tsx @@ -17,7 +17,9 @@ vi.mock('@/runtime/provider-accounts/sign-in/runtime-antigravity-accounts-client vi.mock('@/runtime/rpc/calls/runtime-rpc-call', () => ({ callRuntimeRpc: vi.fn() })) -vi.mock('@/lib/agent-catalog', () => ({ AgentIcon: () => null })) +vi.mock('@/components/agent/icons/AgentIcon', () => ({ + AgentIcon: () => null +})) const state: AntigravityAccountState = { accounts: [ diff --git a/src/renderer/src/components/settings/accounts/providers/AntigravityAccountsSection.tsx b/src/renderer/src/components/settings/accounts/providers/AntigravityAccountsSection.tsx index 0b963470af2..96d0fb51956 100644 --- a/src/renderer/src/components/settings/accounts/providers/AntigravityAccountsSection.tsx +++ b/src/renderer/src/components/settings/accounts/providers/AntigravityAccountsSection.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react' import { Loader2 } from 'lucide-react' import { translate } from '@/i18n/i18n' import { useTranslate, type Translate } from '@/i18n/use-translate' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { callAntigravityAccounts } from '@/runtime/provider-accounts/sign-in/runtime-antigravity-accounts-client' import { callRuntimeRpc } from '@/runtime/rpc/calls/runtime-rpc-call' import { useManagedRuntimeInstall } from '@/runtime/hosts/installation/use-managed-runtime-install' diff --git a/src/renderer/src/components/settings/accounts/providers/CursorAccountsSection.tsx b/src/renderer/src/components/settings/accounts/providers/CursorAccountsSection.tsx index 35ea269ce80..0bea435b99e 100644 --- a/src/renderer/src/components/settings/accounts/providers/CursorAccountsSection.tsx +++ b/src/renderer/src/components/settings/accounts/providers/CursorAccountsSection.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect, useRef, useState } from 'react' import { ExternalLink, Loader2, RefreshCw, ShieldCheck } from 'lucide-react' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { translate } from '@/i18n/i18n' import { useTranslate, type Translate } from '@/i18n/use-translate' import { cn } from '@/lib/utils' diff --git a/src/renderer/src/components/settings/accounts/providers/GrokAccountsSection.test.tsx b/src/renderer/src/components/settings/accounts/providers/GrokAccountsSection.test.tsx index 87491d30d31..d4724a8e77d 100644 --- a/src/renderer/src/components/settings/accounts/providers/GrokAccountsSection.test.tsx +++ b/src/renderer/src/components/settings/accounts/providers/GrokAccountsSection.test.tsx @@ -12,7 +12,7 @@ const mocks = vi.hoisted(() => ({ grokUsage: vi.fn<() => unknown>(() => null) })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/components/agent/icons/AgentIcon', () => ({ AgentIcon: () => React.createElement('span', { 'data-testid': 'grok-icon' }) })) diff --git a/src/renderer/src/components/settings/accounts/providers/GrokAccountsSection.tsx b/src/renderer/src/components/settings/accounts/providers/GrokAccountsSection.tsx index b050f77a584..03ef79148d8 100644 --- a/src/renderer/src/components/settings/accounts/providers/GrokAccountsSection.tsx +++ b/src/renderer/src/components/settings/accounts/providers/GrokAccountsSection.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect, useState } from 'react' import { ExternalLink, Loader2, RefreshCw, ShieldCheck } from 'lucide-react' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useTranslate } from '@/i18n/use-translate' import { cn } from '@/lib/utils' import { useAppStore } from '../../../../store/index' diff --git a/src/renderer/src/components/settings/accounts/usage/ZcodePlanAccountsSection.tsx b/src/renderer/src/components/settings/accounts/usage/ZcodePlanAccountsSection.tsx index 70a7c255970..92525b8062b 100644 --- a/src/renderer/src/components/settings/accounts/usage/ZcodePlanAccountsSection.tsx +++ b/src/renderer/src/components/settings/accounts/usage/ZcodePlanAccountsSection.tsx @@ -1,7 +1,7 @@ import { useState } from 'react' import { isWebClientLocation } from '@/lib/web-client-location' import { ExternalLink, Loader2, Lock, LockOpen, RefreshCw, ShieldCheck } from 'lucide-react' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { translate } from '@/i18n/i18n' import { useTranslate, type Translate } from '@/i18n/use-translate' import { diff --git a/src/renderer/src/components/settings/agents/agents-search.ts b/src/renderer/src/components/settings/agents/agents-search.ts index 784f5a41b36..1c1f55248d5 100644 --- a/src/renderer/src/components/settings/agents/agents-search.ts +++ b/src/renderer/src/components/settings/agents/agents-search.ts @@ -3,7 +3,7 @@ import { getClaudeSubagentNavigationDescription, getClaudeSubagentNavigationSearchKeywords } from './behavior/claude-subagent-navigation-copy' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { getAgentAwakeDescription, getAgentAwakeSearchKeywords, diff --git a/src/renderer/src/components/settings/agents/launch/AgentCatalogRow.tsx b/src/renderer/src/components/settings/agents/launch/AgentCatalogRow.tsx index 414878167e2..2a7060fc14b 100644 --- a/src/renderer/src/components/settings/agents/launch/AgentCatalogRow.tsx +++ b/src/renderer/src/components/settings/agents/launch/AgentCatalogRow.tsx @@ -1,7 +1,7 @@ import { useRef, useState } from 'react' import { Check, ChevronDown, ExternalLink } from 'lucide-react' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { cn } from '@/lib/utils' import { useTranslate } from '@/i18n/use-translate' import { Button } from '../../../ui/button' diff --git a/src/renderer/src/components/settings/agents/launch/AgentDefaultSetting.tsx b/src/renderer/src/components/settings/agents/launch/AgentDefaultSetting.tsx index b8b54123c39..d88a43fb56e 100644 --- a/src/renderer/src/components/settings/agents/launch/AgentDefaultSetting.tsx +++ b/src/renderer/src/components/settings/agents/launch/AgentDefaultSetting.tsx @@ -1,7 +1,8 @@ import { Check } from 'lucide-react' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' -import { type AgentCatalogEntry, AgentIcon } from '@/lib/agent-catalog' +import type { AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { cn } from '@/lib/utils' import { useTranslate } from '@/i18n/use-translate' import { SettingsGroup } from '../../section-layout/SettingsGroup' diff --git a/src/renderer/src/components/settings/agents/launch/AgentDetectionCatalog.tsx b/src/renderer/src/components/settings/agents/launch/AgentDetectionCatalog.tsx index 20bbacf2fd3..857a46f9d91 100644 --- a/src/renderer/src/components/settings/agents/launch/AgentDetectionCatalog.tsx +++ b/src/renderer/src/components/settings/agents/launch/AgentDetectionCatalog.tsx @@ -1,6 +1,6 @@ import { Fragment } from 'react' import { AlertTriangle, RefreshCw } from 'lucide-react' -import type { AgentCatalogEntry } from '@/lib/agent-catalog' +import type { AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' import { cn } from '@/lib/utils' import { useTranslate } from '@/i18n/use-translate' import { Button } from '../../../ui/button' diff --git a/src/renderer/src/components/settings/agents/launch/AgentLaunchSettingsCatalog.tsx b/src/renderer/src/components/settings/agents/launch/AgentLaunchSettingsCatalog.tsx index ec8218f5abe..334809388b3 100644 --- a/src/renderer/src/components/settings/agents/launch/AgentLaunchSettingsCatalog.tsx +++ b/src/renderer/src/components/settings/agents/launch/AgentLaunchSettingsCatalog.tsx @@ -38,7 +38,7 @@ import { resolveTuiAgentLaunchEnv } from '../../../../../../shared/agent-launch/choices/tui-agent-launch-defaults' import { isTuiAgentEnabled } from '../../../../../../shared/agent-launch/catalog/tui-agent-selection' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { agentChoiceOpensAsChat, readChatProgram, @@ -56,7 +56,10 @@ import { AgentChatRuntimeArea, chatUnavailableOnThisDesktop } from '@/components/agent/launch-settings/AgentChatChoiceControls' -import { chatProviderAgents, useHostStructuredAgentsVersion } from '@/lib/chat-provider-agents' +import { + chatProviderAgents, + useHostStructuredAgentsVersion +} from '@/runtime/native-chat/agent-catalogs/chat-provider-agents' import { readHostStructuredAgents } from '@/runtime/native-chat/agent-catalogs/host-structured-agents' import { LOCAL_EXECUTION_HOST_ID } from '../../../../../../shared/execution-host' import { useTranslate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/settings/agents/launch/AgentLaunchSettingsSection.tsx b/src/renderer/src/components/settings/agents/launch/AgentLaunchSettingsSection.tsx index 71ac0d4de37..b073122cdf5 100644 --- a/src/renderer/src/components/settings/agents/launch/AgentLaunchSettingsSection.tsx +++ b/src/renderer/src/components/settings/agents/launch/AgentLaunchSettingsSection.tsx @@ -1,7 +1,7 @@ import { useAppStateValue } from '@/store/retained-views/app-state-view' import { useChatSettingsOwnPermissions } from '@/runtime/native-chat/host-capabilities/structured-agent-session-host-capability' import { toast } from 'sonner' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import { wholeAgentEnvironmentUpdates } from '../../../../../../shared/agent-launch/choices/agent-launch-permission-updates' import { useRef } from 'react' diff --git a/src/renderer/src/components/settings/agents/permissions/agent-permission-override-notice.tsx b/src/renderer/src/components/settings/agents/permissions/agent-permission-override-notice.tsx index 2e2c72f4209..5d6d17686a9 100644 --- a/src/renderer/src/components/settings/agents/permissions/agent-permission-override-notice.tsx +++ b/src/renderer/src/components/settings/agents/permissions/agent-permission-override-notice.tsx @@ -1,6 +1,6 @@ import { useEffect, useId, useRef } from 'react' import { toast } from 'sonner' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import { translate } from '@/i18n/i18n' import { useTranslate } from '@/i18n/use-translate' import { useMountedRef } from '@/hooks/useMountedRef' diff --git a/src/renderer/src/components/settings/agents/surfaces/AgentDefaultSurfaceSection.tsx b/src/renderer/src/components/settings/agents/surfaces/AgentDefaultSurfaceSection.tsx index 64650664606..da1605ff9da 100644 --- a/src/renderer/src/components/settings/agents/surfaces/AgentDefaultSurfaceSection.tsx +++ b/src/renderer/src/components/settings/agents/surfaces/AgentDefaultSurfaceSection.tsx @@ -10,7 +10,7 @@ import { useMountedRef } from '@/hooks/useMountedRef' import { motionSafeScrollBehavior } from '@/hooks/usePrefersReducedMotion' import { translate } from '@/i18n/i18n' import { useIntlLocale, useTranslate } from '@/i18n/use-translate' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import { cn } from '@/lib/utils' import { useAppStore } from '@/store/index' import { trackAgentDefaultSurfaceChanged } from '../../../feature-tips/feature-tip-telemetry' diff --git a/src/renderer/src/components/settings/browser/use/BrowserUsePane.tsx b/src/renderer/src/components/settings/browser/use/BrowserUsePane.tsx index 9f841ad6936..d13a352232d 100644 --- a/src/renderer/src/components/settings/browser/use/BrowserUsePane.tsx +++ b/src/renderer/src/components/settings/browser/use/BrowserUsePane.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react' -import { ORCA_CLI_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_CLI_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { BROWSER_USE_ENABLED_STORAGE_KEY } from '@/lib/browser/browser-use-setup-state' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, diff --git a/src/renderer/src/components/settings/browser/use/BrowserUseSkillStep.tsx b/src/renderer/src/components/settings/browser/use/BrowserUseSkillStep.tsx index be145e93722..36eca952eda 100644 --- a/src/renderer/src/components/settings/browser/use/BrowserUseSkillStep.tsx +++ b/src/renderer/src/components/settings/browser/use/BrowserUseSkillStep.tsx @@ -1,4 +1,4 @@ -import { ORCA_CLI_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_CLI_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { AgentSkillSetupPanel } from '../../../skills/setup/AgentSkillSetupPanel' import { StepBadge } from '../../setup-guide/SetupStepBadge' import { useTranslate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/settings/chat/ChatAgentLaunchSettings.tsx b/src/renderer/src/components/settings/chat/ChatAgentLaunchSettings.tsx index fde5228e1ae..328ae92d705 100644 --- a/src/renderer/src/components/settings/chat/ChatAgentLaunchSettings.tsx +++ b/src/renderer/src/components/settings/chat/ChatAgentLaunchSettings.tsx @@ -1,8 +1,12 @@ import type { GlobalSettings } from '../../../../../shared/global-settings-types' import { useEffect } from 'react' import { LOCAL_EXECUTION_HOST_ID } from '../../../../../shared/execution-host' -import { AgentIcon, getAgentCatalog } from '@/lib/agent-catalog' -import { chatProviderAgents, useHostStructuredAgentsVersion } from '@/lib/chat-provider-agents' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' +import { + chatProviderAgents, + useHostStructuredAgentsVersion +} from '@/runtime/native-chat/agent-catalogs/chat-provider-agents' import { recomputeOn } from '@/lib/recompute-on' import { readChatProgram, resolveChatProgramContext } from '@/lib/host-chat-program' import { useChatProgramFacts } from '@/lib/host-chat-program-acquisition' diff --git a/src/renderer/src/components/settings/chat/ChatNamingSetting.tsx b/src/renderer/src/components/settings/chat/ChatNamingSetting.tsx index 99967dc1832..824f6c2ef1f 100644 --- a/src/renderer/src/components/settings/chat/ChatNamingSetting.tsx +++ b/src/renderer/src/components/settings/chat/ChatNamingSetting.tsx @@ -10,7 +10,7 @@ import { } from '../../../../../shared/source-control/ai/recipes/source-control-ai-actions' import { CUSTOM_AGENT_ID } from '../../../../../shared/source-control/ai/generation/commit-message-agent-spec' import { isTuiAgent } from '../../../../../shared/agent-launch/catalog/tui-agent-config' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import { useTranslate } from '@/i18n/use-translate' import { Switch } from '../../ui/switch' import { Card, CardContent } from '../../ui/card' diff --git a/src/renderer/src/components/settings/cli/install/CliSection.tsx b/src/renderer/src/components/settings/cli/install/CliSection.tsx index 5e947ec0ebe..a99015c781b 100644 --- a/src/renderer/src/components/settings/cli/install/CliSection.tsx +++ b/src/renderer/src/components/settings/cli/install/CliSection.tsx @@ -4,7 +4,7 @@ import { FolderOpen, RefreshCw } from 'lucide-react' import { toast } from 'sonner' import type { CliInstallStatus } from '../../../../../../shared/cli-install-types' import type { GlobalSettings } from '../../../../../../shared/global-settings-types' -import { ORCA_CLI_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_CLI_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkill diff --git a/src/renderer/src/components/settings/computer-use/ComputerUseSkillSetupPanel.tsx b/src/renderer/src/components/settings/computer-use/ComputerUseSkillSetupPanel.tsx index c5da6073fdb..2a22ab96d7a 100644 --- a/src/renderer/src/components/settings/computer-use/ComputerUseSkillSetupPanel.tsx +++ b/src/renderer/src/components/settings/computer-use/ComputerUseSkillSetupPanel.tsx @@ -1,5 +1,5 @@ import { MonitorCog } from 'lucide-react' -import { COMPUTER_USE_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { COMPUTER_USE_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkill diff --git a/src/renderer/src/components/settings/mobile/emulator/MobileEmulatorAgentControlRow.tsx b/src/renderer/src/components/settings/mobile/emulator/MobileEmulatorAgentControlRow.tsx index ed696c8855a..83724edad2f 100644 --- a/src/renderer/src/components/settings/mobile/emulator/MobileEmulatorAgentControlRow.tsx +++ b/src/renderer/src/components/settings/mobile/emulator/MobileEmulatorAgentControlRow.tsx @@ -1,5 +1,5 @@ import { Import } from 'lucide-react' -import { ORCA_CLI_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_CLI_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { useMobileEmulatorAgentSetupState } from '../../../emulator-pane/use-mobile-emulator-agent-setup-state' import { AgentSkillSetupPanel } from '../../../skills/setup/AgentSkillSetupPanel' import { MobileEmulatorExamples } from './MobileEmulatorExamples' diff --git a/src/renderer/src/lib/agent-skill-nav-install-status.ts b/src/renderer/src/components/settings/navigation/agent-skill-nav-install-status.ts similarity index 65% rename from src/renderer/src/lib/agent-skill-nav-install-status.ts rename to src/renderer/src/components/settings/navigation/agent-skill-nav-install-status.ts index 6574a507f1e..1daeb563597 100644 --- a/src/renderer/src/lib/agent-skill-nav-install-status.ts +++ b/src/renderer/src/components/settings/navigation/agent-skill-nav-install-status.ts @@ -1,8 +1,8 @@ -import type { BundledSkillPlan } from '../../../shared/bundled-skill-plan' -import type { DiscoveredSkill } from '../../../shared/skills' -import type { SettingsNavInstallStatus } from './settings-navigation-types' -import { getLinearAgentSkillUpdateTarget } from './linear-agent-skill-update-target' -import { getSkillFreshnessDisplayStatus } from './skill-freshness-display-status' +import type { BundledSkillPlan } from '../../../../../shared/bundled-skill-plan' +import type { DiscoveredSkill } from '../../../../../shared/skills' +import type { SettingsNavInstallStatus } from '../../../lib/settings-navigation-types' +import { getLinearAgentSkillUpdateTarget } from '../../../lib/skills/installation/linear-agent-skill-update-target' +import { getSkillFreshnessDisplayStatus } from '../../../lib/skills/presentation/skill-freshness-display-status' type AgentSkillNavInstallStatusInput = { name: string diff --git a/src/renderer/src/components/settings/navigation/use-settings-navigation-model.ts b/src/renderer/src/components/settings/navigation/use-settings-navigation-model.ts index c6c682e7426..54c5daf53c9 100644 --- a/src/renderer/src/components/settings/navigation/use-settings-navigation-model.ts +++ b/src/renderer/src/components/settings/navigation/use-settings-navigation-model.ts @@ -3,11 +3,14 @@ import { applyDocumentTheme } from '@/lib/document-theme' import { resolvePaintedTheme } from '@/lib/terminal-app-theme' import { useSettingsNavigationMetadata } from '@/hooks/useSettingsNavigationMetadata' import type { SettingsNavInstallStatus } from '@/lib/settings-navigation-types' -import { COMPUTER_USE_SKILL_NAME, ORCHESTRATION_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { + COMPUTER_USE_SKILL_NAME, + ORCHESTRATION_SKILL_NAME +} from '@/lib/skills/installation/agent-feature-skill-names' import { getAgentSkillNavInstallStatus, getLinearAgentSkillNavInstallStatus -} from '@/lib/agent-skill-nav-install-status' +} from '@/components/settings/navigation/agent-skill-nav-install-status' import { getProjectHostSetupProjectionFromState } from '../../../store/projects/project-host-setup-selector' import { getSettingsSectionSearchEntries, rankSettingsSearchItems } from '../search/settings-search' import { deriveNeededSectionIds } from '../page/settings-load-performance' diff --git a/src/renderer/src/components/settings/orchestration/OrchestrationPane.tsx b/src/renderer/src/components/settings/orchestration/OrchestrationPane.tsx index 76c35f0dd4a..9c03161af50 100644 --- a/src/renderer/src/components/settings/orchestration/OrchestrationPane.tsx +++ b/src/renderer/src/components/settings/orchestration/OrchestrationPane.tsx @@ -2,9 +2,9 @@ import type { BundledSkillPlan } from '../../../../../shared/bundled-skill-plan' import { useCallback, useState } from 'react' import { OrchestrationSkillPromptDialog } from './OrchestrationSkillPromptDialog' import { buildSkillCommandForRuntime } from '../../../lib/skill-runtime-command' -import { ORCHESTRATION_SKILL_INSTALL_COMMAND } from '@/lib/agent-feature-install-commands' +import { ORCHESTRATION_SKILL_INSTALL_COMMAND } from '@/lib/skills/installation/agent-feature-install-commands' import { ArrowRightLeft, GitBranch, ListChecks, Workflow, type LucideIcon } from 'lucide-react' -import { ORCHESTRATION_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCHESTRATION_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import type { SkillUsageExample } from '@/lib/skill-usage-example' import { getOrchestrationUsageExamples } from '@/lib/orchestration-usage-examples' import { diff --git a/src/renderer/src/components/settings/orchestration/OrchestrationSkillAgentCoverage.tsx b/src/renderer/src/components/settings/orchestration/OrchestrationSkillAgentCoverage.tsx index f11098215ad..b6a079783a6 100644 --- a/src/renderer/src/components/settings/orchestration/OrchestrationSkillAgentCoverage.tsx +++ b/src/renderer/src/components/settings/orchestration/OrchestrationSkillAgentCoverage.tsx @@ -4,14 +4,15 @@ import type { } from '../../../../../shared/bundled-skill-plan' import type { DiscoveredSkill, SkillDiscoverySource } from '../../../../../shared/skills' -import { AgentIcon, getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useDetectedAgents } from '@/hooks/useDetectedAgents' import { type OrchestrationSkillAgentStatus, getOrchestrationSkillAgentStatuses, sortOrchestrationAgents -} from '@/lib/orchestration-skill-coverage' -import { ORCHESTRATION_SKILL_NAME } from '@/lib/agent-feature-skill-names' +} from '@/lib/skills/orchestration-skill-coverage' +import { ORCHESTRATION_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { cn } from '@/lib/utils' import { translate } from '@/i18n/i18n' import { useTranslate, type Translate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/settings/page/use-settings-store-model.ts b/src/renderer/src/components/settings/page/use-settings-store-model.ts index 1ba484f9d9d..f60a1c5afb5 100644 --- a/src/renderer/src/components/settings/page/use-settings-store-model.ts +++ b/src/renderer/src/components/settings/page/use-settings-store-model.ts @@ -13,7 +13,7 @@ import { COMPUTER_USE_SKILL_NAME, LINEAR_AGENT_SKILL_NAMES, ORCHESTRATION_SKILL_NAME -} from '@/lib/agent-feature-skill-names' +} from '@/lib/skills/installation/agent-feature-skill-names' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkill, diff --git a/src/renderer/src/components/settings/quick-commands/QuickCommandsList.tsx b/src/renderer/src/components/settings/quick-commands/QuickCommandsList.tsx index 3b57d836aa5..6685b17acc7 100644 --- a/src/renderer/src/components/settings/quick-commands/QuickCommandsList.tsx +++ b/src/renderer/src/components/settings/quick-commands/QuickCommandsList.tsx @@ -9,7 +9,8 @@ import { getTerminalQuickCommandScope, isTerminalAgentQuickCommand } from '../../../../../shared/terminal/quick-commands/terminal-quick-commands' -import { AgentIcon, getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useClipboardTextCopyFeedback } from '@/hooks/use-clipboard-text-copy-feedback' import { cn } from '@/lib/utils' import { translate } from '@/i18n/i18n' diff --git a/src/renderer/src/components/settings/skills/linear/LinearAgentSkillPane.tsx b/src/renderer/src/components/settings/skills/linear/LinearAgentSkillPane.tsx index 86f57bd479b..3e987ae496d 100644 --- a/src/renderer/src/components/settings/skills/linear/LinearAgentSkillPane.tsx +++ b/src/renderer/src/components/settings/skills/linear/LinearAgentSkillPane.tsx @@ -12,7 +12,7 @@ import { LinearApiKeyDialog } from '@/components/linear-api-key-dialog' import { LinearIcon } from '@/components/icons/LinearIcon' import { Button } from '@/components/ui/button' import { useAppStore } from '@/store/index' -import { ORCA_LINEAR_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_LINEAR_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { getLinearUsageExamples } from '@/lib/linear-usage-examples' import type { SkillUsageExample } from '@/lib/skill-usage-example' import { useLinearProviderConnected } from '@/hooks/useLinearProviderConnected' diff --git a/src/renderer/src/components/settings/source-control/SourceControlActionArguments.tsx b/src/renderer/src/components/settings/source-control/SourceControlActionArguments.tsx index 86d23419198..8d98e546942 100644 --- a/src/renderer/src/components/settings/source-control/SourceControlActionArguments.tsx +++ b/src/renderer/src/components/settings/source-control/SourceControlActionArguments.tsx @@ -22,7 +22,7 @@ import type { AgentLaunchChoices } from '../../../../../shared/agent-launch/choices/agent-launch-choices' import { SourceControlActionModelPicker } from './SourceControlActionModelPicker' -import { AGENT_CATALOG } from '@/lib/agent-catalog' +import { AGENT_CATALOG } from '@/lib/agent-catalog/agent-catalog' import type { TuiAgent } from '../../../../../shared/agent-launch/catalog/tui-agent' import { useAppStore } from '@/store/index' import { useTranslate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/settings/source-control/source-control-action-recipe-options.ts b/src/renderer/src/components/settings/source-control/source-control-action-recipe-options.ts index 3e4d9f52fe5..1d6d04b032c 100644 --- a/src/renderer/src/components/settings/source-control/source-control-action-recipe-options.ts +++ b/src/renderer/src/components/settings/source-control/source-control-action-recipe-options.ts @@ -11,7 +11,7 @@ import { isCustomAgentId, listCommitMessageAgentCapabilities } from '../../../../../shared/source-control/ai/generation/commit-message-agent-spec' -import { getAgentCatalog, type AgentCatalogEntry } from '@/lib/agent-catalog' +import { getAgentCatalog, type AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' import { createLocalizedCatalog } from '@/i18n/localized-catalog' import { translate } from '@/i18n/i18n' import type { Translate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/settings/tasks/TaskSourceLinearSetup.tsx b/src/renderer/src/components/settings/tasks/TaskSourceLinearSetup.tsx index 1f7560d1562..802d33ccb6a 100644 --- a/src/renderer/src/components/settings/tasks/TaskSourceLinearSetup.tsx +++ b/src/renderer/src/components/settings/tasks/TaskSourceLinearSetup.tsx @@ -2,7 +2,7 @@ import { useState } from 'react' import { LinearApiKeyDialog } from '@/components/linear-api-key-dialog' import { Button } from '@/components/ui/button' import { useAppStore } from '@/store/index' -import { ORCA_LINEAR_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_LINEAR_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { AgentSkillSetupPanel } from '../../skills/setup/AgentSkillSetupPanel' import { TaskSourceShowInTasksStep } from './TaskSourceShowInTasksStep' import { TaskSourceStepRow } from './TaskSourceStepRow' diff --git a/src/renderer/src/components/settings/tasks/use-task-source-provider-readiness.ts b/src/renderer/src/components/settings/tasks/use-task-source-provider-readiness.ts index 805ca4ebbea..758b491c601 100644 --- a/src/renderer/src/components/settings/tasks/use-task-source-provider-readiness.ts +++ b/src/renderer/src/components/settings/tasks/use-task-source-provider-readiness.ts @@ -6,7 +6,7 @@ import { } from '@/hooks/useInstalledAgentSkills' import { useActiveProjectSkillRuntime } from '@/hooks/useActiveProjectSkillRuntime' import { useLinearProviderConnected } from '@/hooks/useLinearProviderConnected' -import { LINEAR_AGENT_SKILL_NAMES } from '@/lib/agent-feature-skill-names' +import { LINEAR_AGENT_SKILL_NAMES } from '@/lib/skills/installation/agent-feature-skill-names' import { getLocalPreflightContext } from '@/lib/local-preflight-context' import { localPreflightContextKey } from '@/lib/local-preflight-context-key' import { getProviderRuntimeContextKey } from '@/runtime/hosts/observations/provider-runtime-context' diff --git a/src/renderer/src/components/settings/virtual-machines/recipes/EphemeralVmsPane.tsx b/src/renderer/src/components/settings/virtual-machines/recipes/EphemeralVmsPane.tsx index f648c44f51a..f02ffa2d649 100644 --- a/src/renderer/src/components/settings/virtual-machines/recipes/EphemeralVmsPane.tsx +++ b/src/renderer/src/components/settings/virtual-machines/recipes/EphemeralVmsPane.tsx @@ -9,7 +9,7 @@ import { AgentSkillSetupPanel } from '../../../skills/setup/AgentSkillSetupPanel import { EphemeralVmRecipeRow } from './EphemeralVmRecipeRow' import { translate } from '@/i18n/i18n' import { useTranslate } from '@/i18n/use-translate' -import { EPHEMERAL_VMS_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { EPHEMERAL_VMS_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkill diff --git a/src/renderer/src/components/setup-guide/use-setup-guide-progress.ts b/src/renderer/src/components/setup-guide/use-setup-guide-progress.ts index 83f7f921614..7ecad0c2cf1 100644 --- a/src/renderer/src/components/setup-guide/use-setup-guide-progress.ts +++ b/src/renderer/src/components/setup-guide/use-setup-guide-progress.ts @@ -10,7 +10,7 @@ import { COMPUTER_USE_SKILL_NAME, ORCA_CLI_SKILL_NAME, ORCHESTRATION_SKILL_NAME -} from '@/lib/agent-feature-skill-names' +} from '@/lib/skills/installation/agent-feature-skill-names' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkill diff --git a/src/renderer/src/components/sidebar/LinearAgentSkillSetupDialog.tsx b/src/renderer/src/components/sidebar/LinearAgentSkillSetupDialog.tsx index 4ef217b6640..f4cd809d3de 100644 --- a/src/renderer/src/components/sidebar/LinearAgentSkillSetupDialog.tsx +++ b/src/renderer/src/components/sidebar/LinearAgentSkillSetupDialog.tsx @@ -12,7 +12,7 @@ import { DialogHeader, DialogTitle } from '@/components/ui/dialog' -import { ORCA_LINEAR_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_LINEAR_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { useTranslate } from '@/i18n/use-translate' type AgentSkillSetupPanelProps = ComponentProps diff --git a/src/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.tsx b/src/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.tsx index 1055d30c418..2a61934e03f 100644 --- a/src/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.tsx +++ b/src/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.tsx @@ -6,8 +6,8 @@ import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkillNames } from '@/hooks/useInstalledAgentSkills' -import { LINEAR_AGENT_SKILL_NAMES } from '@/lib/agent-feature-skill-names' -import { getLinearAgentSkillUpdateTarget } from '@/lib/linear-agent-skill-update-target' +import { LINEAR_AGENT_SKILL_NAMES } from '@/lib/skills/installation/agent-feature-skill-names' +import { getLinearAgentSkillUpdateTarget } from '@/lib/skills/installation/linear-agent-skill-update-target' import { lazyWithRetry } from '@/lib/lazy-with-retry' import { cn } from '@/lib/utils' import { diff --git a/src/renderer/src/components/sidebar/workspace-actions/sleep/use-worktree-sleep-state.ts b/src/renderer/src/components/sidebar/workspace-actions/sleep/use-worktree-sleep-state.ts index 3e5e98d160a..f60b120aefa 100644 --- a/src/renderer/src/components/sidebar/workspace-actions/sleep/use-worktree-sleep-state.ts +++ b/src/renderer/src/components/sidebar/workspace-actions/sleep/use-worktree-sleep-state.ts @@ -1,5 +1,5 @@ import { useAppStore } from '@/store' -import { getAgentStatusEpochNow } from '@/lib/agent-status-epoch-clock' +import { getAgentStatusEpochNow } from '@/lib/agent-status/evidence/agent-status-epoch-clock' import { getWorktreeIdsWithLiveAgent, isInactiveWorkspace } from '@/lib/worktree-activity-state' import { getWorktreeIdsWithStructuredChat } from '../../worktree-list/listing/visible-worktree-activity-inputs' import type { AgentStatusEntry } from '../../../../../../shared/agent-status/contracts/agent-status-types' diff --git a/src/renderer/src/components/sidebar/workspace-board/surface/use-visible-workspace-kanban-worktree-ids.ts b/src/renderer/src/components/sidebar/workspace-board/surface/use-visible-workspace-kanban-worktree-ids.ts index 6907bdda386..936433e3ba7 100644 --- a/src/renderer/src/components/sidebar/workspace-board/surface/use-visible-workspace-kanban-worktree-ids.ts +++ b/src/renderer/src/components/sidebar/workspace-board/surface/use-visible-workspace-kanban-worktree-ids.ts @@ -1,6 +1,6 @@ import { useMemo, useState } from 'react' import { useAppStore } from '@/store' -import { getAgentStatusEpochNow } from '@/lib/agent-status-epoch-clock' +import { getAgentStatusEpochNow } from '@/lib/agent-status/evidence/agent-status-epoch-clock' import type { Repo } from '../../../../../../shared/repo-types' import type { Worktree } from '../../../../../../shared/worktree/types' import '../../worktree-list/listing/visible-worktrees' diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/WorktreeCardAgents.tsx b/src/renderer/src/components/sidebar/workspace-card/activity/WorktreeCardAgents.tsx index 5d11eff6b69..684084c951a 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/WorktreeCardAgents.tsx +++ b/src/renderer/src/components/sidebar/workspace-card/activity/WorktreeCardAgents.tsx @@ -4,7 +4,7 @@ import { useShallow } from 'zustand/react/shallow' import { useAppStore } from '@/store' import DashboardAgentRow from '@/components/dashboard/DashboardAgentRow' import { useNow } from '@/hooks/use-now' -import { deriveRunningAgentSendTargets } from '@/lib/running-agent-targets' +import { deriveRunningAgentSendTargets } from '@/lib/agent-session/messaging/running-agent-targets' import { selectSendTargetControlInputs, selectSendTargetInputs @@ -20,11 +20,11 @@ import { buildAgentRowLineageTree } from '@/components/dashboard/agent-row-linea import { revealCompactAgentCard } from '../../worktree-list/navigation/worktree-sidebar-reveal' import { useWorktreeAgentExpansionState } from './worktree-card-agents-expansion-state' import { useTranslate } from '@/i18n/use-translate' -import { agentSendDisabledReasonLabel } from '@/lib/agent-send-disabled-reason-label' +import { agentSendDisabledReasonLabel } from '@/lib/agent-session/messaging/agent-send-disabled-reason-label' import { useUiLanguageRevision } from '@/i18n/use-ui-language-revision' import { activateRetainedAgentRow } from './activate-retained-agent-row' import { selectAgentRowsUnread } from './worktree-card-agent-ack-inputs' -import { opensClaudeParentConversation } from '@/lib/claude-agent-row-view' +import { opensClaudeParentConversation } from '@/lib/agent-session/navigation/claude-agent-row-view' import { lineageAncestorPaneKeys } from './worktree-card-agent-lineage-disclosure' import { ChildAgentsWithIdleGroup, diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/title-derived-agent-row-input.ts b/src/renderer/src/components/sidebar/workspace-card/activity/title-derived-agent-row-input.ts new file mode 100644 index 00000000000..12a08d2e71b --- /dev/null +++ b/src/renderer/src/components/sidebar/workspace-card/activity/title-derived-agent-row-input.ts @@ -0,0 +1,17 @@ +import type { AgentStatusOrchestrationContext } from '../../../../../../shared/agent-status/contracts/agent-status-types' +import type { + TerminalLayoutSnapshot, + TerminalTab +} from '../../../../../../shared/workspace-layout/terminal-tab-types' +import type { TitleDerivedPaneForeground } from './title-derived-pane-agent-identity' + +export type TitleDerivedAgentRowsInput = { + tabs: TerminalTab[] + runtimePaneTitlesByTabId?: Record> + ptyIdsByTabId?: Record + terminalLayoutsByTabId?: Record + runtimeAgentOrchestrationByPaneKey?: Record + paneForegroundAgentByPaneKey?: Record + seenPaneKeys: Set + now: number +} diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-activity-summary.ts b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-activity-summary.ts index 5b1fdbb62fa..65dd3bcf182 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-activity-summary.ts +++ b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-activity-summary.ts @@ -4,14 +4,17 @@ import { type VisibleOrchestrationState } from '@/runtime/agent-orchestration/visible-agent-orchestration' import type { AppState } from '@/store/types' -import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' +import { + isAgentStatusFresh, + AGENT_STATUS_STALE_AFTER_MS +} from '../../../../../../shared/agent-status/contracts/agent-status-freshness' import { migrationUnsupportedToAgentStatusEntry } from '../../../../../../shared/migration-unsupported-agent-entry' import { mergeAgentStatusOrchestration, parseAgentStatusPaneIdentity, resolveAgentStatusWorktreeId } from '../../../../../../shared/agent-status/identity/agent-status-worktree-attribution' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../../../shared/agent-status/contracts/agent-status-freshness' + import type { AgentStatusOrchestrationContext } from '../../../../../../shared/agent-status/contracts/agent-status-types' import { agentVerdictDisplayMark } from '../../../../../../shared/agent-status/lifecycle/agent-main-agent-verdict' import { applyAgentPaneActivityFlags } from '../../../../../../shared/worktree-status-rollup' @@ -144,7 +147,7 @@ function getWorktreeAgentActivitySummaries( addAgentStatusPaneId(summary, paneIdentity.tabId, paneIdentity.paneId) continue } - if (!isExplicitAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS)) { + if (!isAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS)) { // Retain stale pane identity to suppress generated permission titles after the row loses authority. addStalePaneId(summary, paneIdentity.tabId, paneIdentity.paneId) continue diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-freshness-selector.ts b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-freshness-selector.ts index 668cded7c1a..2176358613c 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-freshness-selector.ts +++ b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-freshness-selector.ts @@ -1,6 +1,9 @@ -import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' +import { + isAgentStatusFresh, + AGENT_STATUS_STALE_AFTER_MS +} from '../../../../../../shared/agent-status/contracts/agent-status-freshness' import type { AppState } from '@/store/types' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../../../shared/agent-status/contracts/agent-status-freshness' + import { selectLiveAgentStatusEntriesForWorktree } from './worktree-agent-row-selectors' export const EMPTY_WORKTREE_AGENT_FRESHNESS_SIGNATURE = '' @@ -25,7 +28,7 @@ function buildWorktreeAgentFreshnessSignature( continue } signature += `${entry.paneKey}\0${ - isExplicitAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS) ? '1' : '0' + isAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS) ? '1' : '0' }\0` } return signature diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-rows.ts b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-rows.ts index c77921f99f2..93de8572c23 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-rows.ts +++ b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-agent-rows.ts @@ -1,9 +1,12 @@ import type { Tab } from '../../../../../../shared/tab-types' import { parseAgentStatusPaneIdentity } from '../../../../../../shared/agent-status/identity/agent-status-worktree-attribution' import type { DashboardAgentRow } from '@/components/dashboard/useDashboardData' -import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' +import { + isAgentStatusFresh, + AGENT_STATUS_STALE_AFTER_MS +} from '../../../../../../shared/agent-status/contracts/agent-status-freshness' import type { RetainedAgentEntry } from '@/store/slices/agent-status/agent-status-contract' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../../../shared/agent-status/contracts/agent-status-freshness' + import type { AgentStatusEntry, AgentStatusOrchestrationContext @@ -176,7 +179,7 @@ export function buildWorktreeAgentRows(args: { const hasLivePty = tabHasLivePty(ptyIdsByTabId, tab.id) for (const entry of explicitEntries) { const rowEntry = entryWithRuntimeOrchestration(entry, args.runtimeAgentOrchestrationByPaneKey) - const isFresh = isExplicitAgentStatusFresh(rowEntry, args.now, AGENT_STATUS_STALE_AFTER_MS) + const isFresh = isAgentStatusFresh(rowEntry, args.now, AGENT_STATUS_STALE_AFTER_MS) const shouldDecay = !isFresh && (rowEntry.state === 'working' || @@ -223,7 +226,7 @@ export function buildWorktreeAgentRows(args: { if (!tab) { continue } - const isFresh = isExplicitAgentStatusFresh(rowEntry, args.now, AGENT_STATUS_STALE_AFTER_MS) + const isFresh = isAgentStatusFresh(rowEntry, args.now, AGENT_STATUS_STALE_AFTER_MS) const shouldDecay = !isFresh && (rowEntry.state === 'working' || rowEntry.state === 'blocked' || rowEntry.state === 'waiting') diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-agent-summary.ts b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-agent-summary.ts index 62175c5f8ff..2b224f17832 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-agent-summary.ts +++ b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-agent-summary.ts @@ -1,7 +1,7 @@ import type { AgentDotState } from '@/components/AgentStateDot' import type { DashboardAgentRow as DashboardAgentRowData } from '@/components/dashboard/useDashboardData' import { formatAgentTypeLabel } from '../../../../../../shared/agent-status/presentation/agent-type-label' -import { agentRowDisplayDotState as getAgentDotState } from '@/lib/agent-row-dot-state' +import { agentRowDisplayDotState as getAgentDotState } from '@/lib/agent-status/presentation/agent-row-dot-state' import { translate } from '@/i18n/i18n' import type { Translate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agent-line-order.ts b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agent-line-order.ts index efe74c6a7b8..8f5af83fbf4 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agent-line-order.ts +++ b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agent-line-order.ts @@ -1,6 +1,6 @@ import type { DashboardAgentRow as DashboardAgentRowData } from '@/components/dashboard/useDashboardData' -import { agentRowStoppingLabel } from '@/lib/agent-row-stopping-label' -import type { agentRowDisplayDotState as getAgentDotState } from '../../../../lib/agent-row-dot-state' +import { agentRowStoppingLabel } from '@/lib/agent-status/presentation/agent-row-stopping-label' +import type { agentRowDisplayDotState as getAgentDotState } from '../../../../lib/agent-status/presentation/agent-row-dot-state' import type { Translate } from '@/i18n/use-translate' /** Lead with statuses the dot cannot express so truncation cuts the prompt instead. */ diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agent-row.tsx b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agent-row.tsx index 1d69333031e..372e2a9dfc8 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agent-row.tsx +++ b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agent-row.tsx @@ -3,22 +3,22 @@ import { DashboardAgentChildDisclosure } from '@/components/dashboard/DashboardA import { AgentStateDot, agentStateLabel, type AgentDotState } from '@/components/AgentStateDot' import { AgentChildRowContent } from '@/components/AgentChildRowContent' import type { DashboardAgentRow as DashboardAgentRowData } from '@/components/dashboard/useDashboardData' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { formatAgentTypeLabel } from '../../../../../../shared/agent-status/presentation/agent-type-label' import { cn } from '@/lib/utils' -import { viewClaudeAgentFromRow } from '@/lib/claude-agent-row-view' +import { viewClaudeAgentFromRow } from '@/lib/agent-session/navigation/claude-agent-row-view' import { useClaudeAgentRowView } from '@/components/dashboard/use-claude-agent-row-view' import './worktree-card-agent-summary' -import { agentRowDisplayDotState as getAgentDotState } from '../../../../lib/agent-row-dot-state' +import { agentRowDisplayDotState as getAgentDotState } from '../../../../lib/agent-status/presentation/agent-row-dot-state' import { getAgentRowPrimaryText } from '../../../../../../shared/agent-status/presentation/agent-row-primary-text' -import { formatAgentToolPreview } from '@/lib/agent-row-tool-preview' +import { formatAgentToolPreview } from '@/lib/agent-status/presentation/agent-row-tool-preview' import { agentNoUpdateLabel } from '../../../../../../shared/agent-status/presentation/agent-row-decay-state' import { useAgentRowConversationName } from '@/components/dashboard/use-agent-row-conversation-name' import { lastEnteredDoneAt } from '@/components/dashboard/agent-finished-timestamp' import CacheTimer, { usePromptCacheCountdownForPane } from './CacheTimer' import { formatShortTimeAgo } from '@/lib/short-time-ago' -import { agentVerdictStatusLine } from '@/lib/agent-verdict-status-line' -import { agentRowStoppingLabel } from '@/lib/agent-row-stopping-label' +import { agentVerdictStatusLine } from '@/lib/agent-status/presentation/agent-verdict-status-line' +import { agentRowStoppingLabel } from '@/lib/agent-status/presentation/agent-row-stopping-label' import { getCompactAgentLineOrder } from './worktree-card-compact-agent-line-order' import { programStatusAttentionLine, diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agents.tsx b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agents.tsx index ee3d1ed03ae..354535ba5fa 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agents.tsx +++ b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-compact-agents.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useRef } from 'react' import { ChevronDown } from 'lucide-react' import { AgentStateDot } from '@/components/AgentStateDot' import type { DashboardAgentRow as DashboardAgentRowData } from '@/components/dashboard/useDashboardData' -import { AgentTypeIcon } from '@/lib/agent-type-icon' +import { AgentTypeIcon } from '@/components/agent/icons/agent-type-icon' import { cn } from '@/lib/utils' import { buildSummaryAgentGroups, diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-idle-child-agents.tsx b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-idle-child-agents.tsx index 145a673b097..766a8fb5696 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-idle-child-agents.tsx +++ b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-idle-child-agents.tsx @@ -6,7 +6,7 @@ import { cn } from '@/lib/utils' import { useTranslate } from '@/i18n/use-translate' import { CompactAgentExpansion } from './worktree-card-compact-agents' import { SUMMARY_STATE_ORDER } from './worktree-card-agent-summary' -import { agentRowDisplayDotState as getAgentDotState } from '../../../../lib/agent-row-dot-state' +import { agentRowDisplayDotState as getAgentDotState } from '../../../../lib/agent-status/presentation/agent-row-dot-state' import type { AgentDotState } from '@/components/AgentStateDot' // A lone idle child costs the same row as its group, so only fold two or more. diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-send-target-inputs.ts b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-send-target-inputs.ts index 47e1aaf554d..98d7aa0f179 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-send-target-inputs.ts +++ b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-card-send-target-inputs.ts @@ -1,5 +1,5 @@ import type { AppState } from '@/store/types' -import type { RunningAgentTargetState } from '@/lib/running-agent-targets' +import type { RunningAgentTargetState } from '@/lib/agent-session/messaging/running-agent-targets' export type SendTargetInputsState = Pick< AppState, diff --git a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-title-derived-agent-rows.ts b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-title-derived-agent-rows.ts index da944bd9ad6..c3b5296cf45 100644 --- a/src/renderer/src/components/sidebar/workspace-card/activity/worktree-title-derived-agent-rows.ts +++ b/src/renderer/src/components/sidebar/workspace-card/activity/worktree-title-derived-agent-rows.ts @@ -1,3 +1,4 @@ +import type { TitleDerivedAgentRowsInput } from './title-derived-agent-row-input' import type { DashboardAgentRow } from '@/components/dashboard/useDashboardData' import { formatAgentTypeLabel } from '../../../../../../shared/agent-status/presentation/agent-type-label' import { @@ -5,7 +6,8 @@ import { isCursorAgentTitle } from '../../../../../../shared/agent-status/title/agent-title-core' -import { classifyTitleActivity, resolveTitleActivityLabel } from '@/lib/pane-agent-evidence' +import { detectAgentStatusFromTitle } from '../../../../../../shared/agent-status/title/agent-title-status' +import { getAgentLabel } from '../../../../../../shared/agent-status/title/agent-title-identity' import { tabHasLivePty } from '../../../../../../shared/tab-has-live-pty' import type { AgentStatusEntry, @@ -49,16 +51,7 @@ const EMPTY_LIVE_PTY_IDS: Record = {} const EMPTY_TERMINAL_LAYOUTS: Record = {} const EMPTY_PANE_FOREGROUND: Record = {} -export function buildTitleDerivedAgentRows(args: { - tabs: TerminalTab[] - runtimePaneTitlesByTabId?: Record> - ptyIdsByTabId?: Record - terminalLayoutsByTabId?: Record - runtimeAgentOrchestrationByPaneKey?: Record - paneForegroundAgentByPaneKey?: Record - seenPaneKeys: Set - now: number -}): DashboardAgentRow[] { +export function buildTitleDerivedAgentRows(args: TitleDerivedAgentRowsInput): DashboardAgentRow[] { const rows: DashboardAgentRow[] = [] const runtimePaneTitlesByTabId = args.runtimePaneTitlesByTabId ?? EMPTY_RUNTIME_TITLES const ptyIdsByTabId = args.ptyIdsByTabId ?? EMPTY_LIVE_PTY_IDS @@ -163,8 +156,8 @@ function buildTitleDerivedAgentRow(args: { // Claude management and Cursor’s status-less native titles still identify idle panes without claiming active work. const titleStatus = isClaudeAgentsTitle ? 'idle' - : (classifyTitleActivity(title) ?? (isCursorAgentTitle(title) ? 'idle' : null)) - const label = isClaudeAgentsTitle ? 'Claude Code' : resolveTitleActivityLabel(title) + : (detectAgentStatusFromTitle(title) ?? (isCursorAgentTitle(title) ? 'idle' : null)) + const label = isClaudeAgentsTitle ? 'Claude Code' : getAgentLabel(title) if (!isTerminalLeafId(args.leafId)) { return null } @@ -259,7 +252,7 @@ export function resolveAgentTypeFromTerminalTitle( return null } const normalizedTitle = normalizeCompatibleAgentTitleForOwner(title, ownerAgentType, options) - const label = resolveTitleActivityLabel(normalizedTitle) + const label = getAgentLabel(normalizedTitle) return label ? (resolveCompatibleAgentTypeForOwner( resolveTitleDerivedAgentType(normalizedTitle, label, ownerAgentType), diff --git a/src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-submit-input.ts b/src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-submit-input.ts index e0a0fc2d235..c7d59a529ed 100644 --- a/src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-submit-input.ts +++ b/src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-submit-input.ts @@ -1,4 +1,4 @@ -import type { AgentLaunchChoice } from '@/lib/agent-menu-selection' +import type { AgentLaunchChoice } from '@/lib/agent-session/launch/routing/agent-menu-selection' import type { LinkedWorkItemSummary } from '@/lib/new-workspace' import type { AgentStartupSettings } from '../../../../../../shared/agent-launch/startup/agent-startup-plan-inputs' import type { AgentLaunchInputViews } from '../../../../../../shared/agent-launch/choices/agent-launch-choices' diff --git a/src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-submit.ts b/src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-submit.ts index 49e3d80bff1..5df1d7f3bfa 100644 --- a/src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-submit.ts +++ b/src/renderer/src/components/sidebar/workspace-creation/folder/folder-workspace-composer-submit.ts @@ -29,7 +29,7 @@ import { } from './folder-workspace-agent-startup' import { translate } from '@/i18n/i18n' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import type { SubmitFolderWorkspaceCreateParams } from './folder-workspace-composer-submit-input' export async function submitFolderWorkspaceCreate({ diff --git a/src/renderer/src/components/sidebar/worktree-list/listing/sleeping-sweep-visibility.ts b/src/renderer/src/components/sidebar/worktree-list/listing/sleeping-sweep-visibility.ts index e120f504a3e..dbb9ad4bcf6 100644 --- a/src/renderer/src/components/sidebar/worktree-list/listing/sleeping-sweep-visibility.ts +++ b/src/renderer/src/components/sidebar/worktree-list/listing/sleeping-sweep-visibility.ts @@ -1,7 +1,7 @@ import type { AppState } from '@/store/types' import type { Worktree } from '../../../../../../shared/worktree/types' import { isSleepingSweepExempt } from '../../../../../../shared/workspace-view/workspace-row-filters' -import { getAgentStatusEpochNow } from '@/lib/agent-status-epoch-clock' +import { getAgentStatusEpochNow } from '@/lib/agent-status/evidence/agent-status-epoch-clock' import { getWorktreeIdsWithLiveAgent, isInactiveWorkspace } from '@/lib/worktree-activity-state' import { getVisibleWorktreeBrowserActivityTabs, diff --git a/src/renderer/src/components/sidebar/worktree-list/listing/use-agent-send-target.ts b/src/renderer/src/components/sidebar/worktree-list/listing/use-agent-send-target.ts index d6c5adac6a1..e88f5dc656a 100644 --- a/src/renderer/src/components/sidebar/worktree-list/listing/use-agent-send-target.ts +++ b/src/renderer/src/components/sidebar/worktree-list/listing/use-agent-send-target.ts @@ -1,7 +1,7 @@ import { useMemo } from 'react' import { useAppStore } from '@/store' import type { AppState } from '@/store/types' -import { deriveRunningAgentSendTargets } from '@/lib/running-agent-targets' +import { deriveRunningAgentSendTargets } from '@/lib/agent-session/messaging/running-agent-targets' import { recomputeOn } from '@/lib/recompute-on' // Why: selectors that opt out of a slice must return one stable reference, or every store tick looks like a change. diff --git a/src/renderer/src/components/sidebar/worktree-list/listing/use-visible-worktrees.ts b/src/renderer/src/components/sidebar/worktree-list/listing/use-visible-worktrees.ts index 1e74831b26e..8917a0d2b3e 100644 --- a/src/renderer/src/components/sidebar/worktree-list/listing/use-visible-worktrees.ts +++ b/src/renderer/src/components/sidebar/worktree-list/listing/use-visible-worktrees.ts @@ -3,7 +3,7 @@ import { useMemo, useState } from 'react' import { shallow } from 'zustand/shallow' import type { AppState } from '@/store/types' import { useAppStore } from '@/store' -import { getAgentStatusEpochNow } from '@/lib/agent-status-epoch-clock' +import { getAgentStatusEpochNow } from '@/lib/agent-status/evidence/agent-status-epoch-clock' import { createLiveAgentWorktreeIdsSelector } from '@/lib/worktree-activity-state' import type { Repo } from '../../../../../../shared/repo-types' import type { WorktreeLineage } from '../../../../../../shared/worktree/lineage-types' diff --git a/src/renderer/src/components/skills/SkillFreshnessStatusPill.tsx b/src/renderer/src/components/skills/SkillFreshnessStatusPill.tsx index e879f4dd335..c773de28661 100644 --- a/src/renderer/src/components/skills/SkillFreshnessStatusPill.tsx +++ b/src/renderer/src/components/skills/SkillFreshnessStatusPill.tsx @@ -14,7 +14,7 @@ import { hasSkillCopyNeedingAttention, skillPlanHasDetails, type SkillFreshnessDisplayStatus -} from '@/lib/skill-freshness-display-status' +} from '@/lib/skills/presentation/skill-freshness-display-status' import { requestSkillFreshnessUpdateDialog } from './skill-freshness-update-dialog' function statusPill( diff --git a/src/renderer/src/components/skills/setup/AgentSkillSetupPanel.tsx b/src/renderer/src/components/skills/setup/AgentSkillSetupPanel.tsx index 971d85c262c..d3ae1396723 100644 --- a/src/renderer/src/components/skills/setup/AgentSkillSetupPanel.tsx +++ b/src/renderer/src/components/skills/setup/AgentSkillSetupPanel.tsx @@ -1,6 +1,6 @@ import { bundledSkillSetupActionLabel } from './bundled-skill-setup-copy' import { useActiveProjectSkillRuntime } from '@/hooks/useActiveProjectSkillRuntime' -import { buildAgentFeatureSkillInstallCommand } from '@/lib/agent-feature-install-commands' +import { buildAgentFeatureSkillInstallCommand } from '@/lib/skills/installation/agent-feature-install-commands' import { buildSkillCommandForRuntime } from '../../../lib/skill-runtime-command' import { WslAgentSkillSetupPanel } from './WslAgentSkillSetupPanel' import { useCallback } from 'react' diff --git a/src/renderer/src/components/skills/setup/WslAgentSkillSetupPanel.tsx b/src/renderer/src/components/skills/setup/WslAgentSkillSetupPanel.tsx index 51e2c7fe26c..dced7d29f32 100644 --- a/src/renderer/src/components/skills/setup/WslAgentSkillSetupPanel.tsx +++ b/src/renderer/src/components/skills/setup/WslAgentSkillSetupPanel.tsx @@ -15,7 +15,7 @@ import { recheckSurfacesAfterAgentSkillInstall, syncSurfacesAfterAgentSkillRecheck } from '../../../hooks/agent-skill-recheck-surface-sync' -import { isOrcaCliAvailableOnPath } from '@/lib/agent-skill-cli-prerequisite' +import { isOrcaCliAvailableOnPath } from '@/lib/skills/installation/agent-skill-cli-prerequisite' import { cn } from '@/lib/utils' import { useTranslate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/skills/setup/WslLinearAgentSkillInstallCta.tsx b/src/renderer/src/components/skills/setup/WslLinearAgentSkillInstallCta.tsx index 0c01ce50947..2b197e27e76 100644 --- a/src/renderer/src/components/skills/setup/WslLinearAgentSkillInstallCta.tsx +++ b/src/renderer/src/components/skills/setup/WslLinearAgentSkillInstallCta.tsx @@ -9,12 +9,15 @@ import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkillNames } from '@/hooks/useInstalledAgentSkills' -import { LINEAR_AGENT_SKILL_NAMES, ORCA_LINEAR_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { + LINEAR_AGENT_SKILL_NAMES, + ORCA_LINEAR_SKILL_NAME +} from '@/lib/skills/installation/agent-feature-skill-names' import { ORCA_LINEAR_SKILL_INSTALL_COMMAND, buildAgentFeatureSkillInstallCommand -} from '@/lib/agent-feature-install-commands' -import { getLinearAgentSkillUpdateTarget } from '@/lib/linear-agent-skill-update-target' +} from '@/lib/skills/installation/agent-feature-install-commands' +import { getLinearAgentSkillUpdateTarget } from '@/lib/skills/installation/linear-agent-skill-update-target' import { cn } from '@/lib/utils' import { getLinearAgentSkillSetupInlineRuntimeCopy } from '../../sidebar/linear-agent-skill-setup-copy' diff --git a/src/renderer/src/components/skills/setup/linear-agent-skill-install-cta.tsx b/src/renderer/src/components/skills/setup/linear-agent-skill-install-cta.tsx index 0351fec3ed8..c65ab31085d 100644 --- a/src/renderer/src/components/skills/setup/linear-agent-skill-install-cta.tsx +++ b/src/renderer/src/components/skills/setup/linear-agent-skill-install-cta.tsx @@ -15,8 +15,11 @@ import { bundledSkillInstallNeedsAttention, useBundledSkillInstall } from '@/hooks/use-bundled-skill-install' -import { LINEAR_AGENT_SKILL_NAMES, ORCA_LINEAR_SKILL_NAME } from '@/lib/agent-feature-skill-names' -import { getLinearAgentSkillUpdateTarget } from '@/lib/linear-agent-skill-update-target' +import { + LINEAR_AGENT_SKILL_NAMES, + ORCA_LINEAR_SKILL_NAME +} from '@/lib/skills/installation/agent-feature-skill-names' +import { getLinearAgentSkillUpdateTarget } from '@/lib/skills/installation/linear-agent-skill-update-target' import { cn } from '@/lib/utils' import { getLinearAgentSkillSetupInlineRuntimeCopy } from '../../sidebar/linear-agent-skill-setup-copy' import type { LinearAgentSkillPromptSettings } from '../../sidebar/linear-agent-skill-runtime' diff --git a/src/renderer/src/components/stats/StatsPane.tsx b/src/renderer/src/components/stats/StatsPane.tsx index aec97843477..55d79b17e64 100644 --- a/src/renderer/src/components/stats/StatsPane.tsx +++ b/src/renderer/src/components/stats/StatsPane.tsx @@ -15,7 +15,7 @@ import { DropdownMenuItem, DropdownMenuTrigger } from '../ui/dropdown-menu' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { getIntlLocale, translate } from '@/i18n/i18n' import { useIntlLocale, useTranslate, type Translate } from '@/i18n/use-translate' export { getStatsPaneSearchEntries } from './stats-search' diff --git a/src/renderer/src/components/status-bar/StatusBarUsageEmptyCta.tsx b/src/renderer/src/components/status-bar/StatusBarUsageEmptyCta.tsx index 1e2cb49d1c0..782fea7c99e 100644 --- a/src/renderer/src/components/status-bar/StatusBarUsageEmptyCta.tsx +++ b/src/renderer/src/components/status-bar/StatusBarUsageEmptyCta.tsx @@ -3,7 +3,7 @@ import { BarChart3 } from 'lucide-react' import { Button } from '@/components/ui/button' import { EyeOffDismissButton } from '@/components/dismiss/EyeOffDismissButton' import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useAppStore } from '../../store' import { ClaudeIcon, GeminiIcon, OpenAIIcon, OpenCodeGoIcon } from './icons' import { useTranslate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/status-bar/StatusBarVisibilityMenu.tsx b/src/renderer/src/components/status-bar/StatusBarVisibilityMenu.tsx index 1deff4c914f..45f619e118d 100644 --- a/src/renderer/src/components/status-bar/StatusBarVisibilityMenu.tsx +++ b/src/renderer/src/components/status-bar/StatusBarVisibilityMenu.tsx @@ -6,7 +6,7 @@ import { DropdownMenuContent, DropdownMenuTrigger } from '@/components/ui/dropdown-menu' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { ClaudeIcon, GeminiIcon, MiniMaxIcon, OpenAIIcon, OpenCodeGoIcon } from './icons' import { useTranslate } from '@/i18n/use-translate' import { isStatusBarItemAvailable } from './status-bar-agent-gating' diff --git a/src/renderer/src/components/status-bar/provider-segment-monthly-window.test.tsx b/src/renderer/src/components/status-bar/provider-segment-monthly-window.test.tsx index 5574989a0c1..641182d1d89 100644 --- a/src/renderer/src/components/status-bar/provider-segment-monthly-window.test.tsx +++ b/src/renderer/src/components/status-bar/provider-segment-monthly-window.test.tsx @@ -13,7 +13,7 @@ vi.mock('@/i18n/i18n', () => ({ } })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/components/agent/icons/AgentIcon', () => ({ AgentIcon: () => null })) diff --git a/src/renderer/src/components/status-bar/status-bar-pool-countdown.test.tsx b/src/renderer/src/components/status-bar/status-bar-pool-countdown.test.tsx index 78b493a107e..c7bb483dbe7 100644 --- a/src/renderer/src/components/status-bar/status-bar-pool-countdown.test.tsx +++ b/src/renderer/src/components/status-bar/status-bar-pool-countdown.test.tsx @@ -13,7 +13,9 @@ vi.mock('@/i18n/i18n', () => ({ fallback ) })) -vi.mock('@/lib/agent-catalog', () => ({ AgentIcon: () => null })) +vi.mock('@/components/agent/icons/AgentIcon', () => ({ + AgentIcon: () => null +})) const START = Date.UTC(2026, 9, 8, 12) const MINUTE = 60_000 diff --git a/src/renderer/src/components/status-bar/tooltip.tsx b/src/renderer/src/components/status-bar/tooltip.tsx index 22e5018ab73..b2a741d02ba 100644 --- a/src/renderer/src/components/status-bar/tooltip.tsx +++ b/src/renderer/src/components/status-bar/tooltip.tsx @@ -3,7 +3,7 @@ import { formatResetCountdown, formatResetDuration } from '../../../../shared/rate-limit-reset-format' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { ClaudeIcon, GeminiIcon, MiniMaxIcon, OpenAIIcon, OpenCodeGoIcon } from './icons' import { translate } from '@/i18n/i18n' import { useTranslate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/status-bar/usage-pool-label.test.ts b/src/renderer/src/components/status-bar/usage-pool-label.test.ts index 0028e5ea023..52c4b8856c5 100644 --- a/src/renderer/src/components/status-bar/usage-pool-label.test.ts +++ b/src/renderer/src/components/status-bar/usage-pool-label.test.ts @@ -14,7 +14,9 @@ vi.mock('@/i18n/i18n', () => ({ fallback ) })) -vi.mock('@/lib/agent-catalog', () => ({ AgentIcon: () => null })) +vi.mock('@/components/agent/icons/AgentIcon', () => ({ + AgentIcon: () => null +})) vi.mock('@/hooks/useResetCountdownClock', () => ({ useResetCountdownClock: () => 0 })) vi.mock('@/components/ui/dropdown-menu', () => ({ DropdownMenuItem: () => null })) vi.mock('@/components/settings/form-controls/SettingsFormControls', () => ({ diff --git a/src/renderer/src/components/status-bar/use-workspace-space-decision-projection.ts b/src/renderer/src/components/status-bar/use-workspace-space-decision-projection.ts index a66dcd2bf11..e7fcc587015 100644 --- a/src/renderer/src/components/status-bar/use-workspace-space-decision-projection.ts +++ b/src/renderer/src/components/status-bar/use-workspace-space-decision-projection.ts @@ -1,6 +1,6 @@ import { useCallback, useMemo } from 'react' import { groupWorkspaceSpaceDecisionInputs } from './workspace-space-decision-inputs' -import { getAgentStatusEpochNow } from '@/lib/agent-status-epoch-clock' +import { getAgentStatusEpochNow } from '@/lib/agent-status/evidence/agent-status-epoch-clock' import { getWorkspaceDecisionDetails, type WorkspaceDecisionDetails diff --git a/src/renderer/src/components/status-bar/workspace-space-presentation.ts b/src/renderer/src/components/status-bar/workspace-space-presentation.ts index 72dad17b787..f8ac72c1bb1 100644 --- a/src/renderer/src/components/status-bar/workspace-space-presentation.ts +++ b/src/renderer/src/components/status-bar/workspace-space-presentation.ts @@ -1,6 +1,10 @@ -import { classifyTitleActivity, isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' +import { detectAgentStatusFromTitle } from '../../../../shared/agent-status/title/agent-title-status' +import { + isAgentStatusFresh, + AGENT_STATUS_STALE_AFTER_MS +} from '../../../../shared/agent-status/contracts/agent-status-freshness' import { tabHasLivePty } from '../../../../shared/tab-has-live-pty' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../shared/agent-status/contracts/agent-status-freshness' + import type { AgentStatusEntry } from '../../../../shared/agent-status/contracts/agent-status-types' import type { MigrationUnsupportedPtyEntry } from '../../../../shared/agent-status/contracts/agent-status-ipc-payload' import { parsePaneKey } from '../../../../shared/workspace-layout/stable-pane-id' @@ -80,12 +84,12 @@ function countTitleActiveAgentsForTab( const paneTitles = runtimePaneTitlesByTabId[tab.id] if (paneTitles && Object.keys(paneTitles).length > 0) { return Object.values(paneTitles).filter((title) => { - const status = classifyTitleActivity(title) + const status = detectAgentStatusFromTitle(title) return status === 'working' || status === 'permission' }).length } - const status = classifyTitleActivity(tab.title) + const status = detectAgentStatusFromTitle(tab.title) return status === 'working' || status === 'permission' ? 1 : 0 } @@ -106,7 +110,7 @@ export function countWorkspaceSpaceActiveAgents({ if (!isActiveAgentState(entry)) { continue } - if (!isExplicitAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS)) { + if (!isAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS)) { continue } const tabId = getPaneKeyTabId(entry.paneKey || paneKey) diff --git a/src/renderer/src/components/tab-bar/QuickLaunchButton.tsx b/src/renderer/src/components/tab-bar/QuickLaunchButton.tsx index 75f872d915a..a99202ec1f2 100644 --- a/src/renderer/src/components/tab-bar/QuickLaunchButton.tsx +++ b/src/renderer/src/components/tab-bar/QuickLaunchButton.tsx @@ -14,7 +14,7 @@ import { launchAgentInNewTab } from '@/lib/agent-session/launch/new-tab/launch-a import { newAgentLaunchRequestId } from '@/lib/agent-session/launch/routing/agent-launch-request-id' import { captureNativeChatComposerFocusIntent } from '@/components/native-chat/composer/focus/native-chat-composer-focus-intent' import { agentLaunchPromptOwnership, newAgentPromptOutcome } from '@/lib/new-agent-prompt-outcome' -import { activeAgentNotesSendFailureMessage } from '@/lib/active-agent-note-send-result' +import { activeAgentNotesSendFailureMessage } from '@/lib/agent-session/messaging/terminal/active-agent-note-send-result' import { AgentSettingsMenuItem } from '@/components/agent/AgentSettingsMenuItem' import { TabAgentSurfaceChoiceRow } from './TabAgentSurfaceChoiceRow' import { @@ -22,7 +22,8 @@ import { DropdownMenuSeparator, DropdownMenuShortcut } from '@/components/ui/dropdown-menu' -import { getAgentCatalog, AgentIcon } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useOptionalShortcutLabel } from '@/hooks/useShortcutLabel' import { useAgentMenuShortcutLabels } from './agent-menu-shortcut-labels' import type { AgentPickerInventorySource } from '../agent/use-agent-launch-picker-inventory' diff --git a/src/renderer/src/components/tab-bar/SortableTab.tsx b/src/renderer/src/components/tab-bar/SortableTab.tsx index 75ed642f9ba..e0a86fb3ddd 100644 --- a/src/renderer/src/components/tab-bar/SortableTab.tsx +++ b/src/renderer/src/components/tab-bar/SortableTab.tsx @@ -3,7 +3,7 @@ import { useCallback, useEffect } from 'react' import { useSortable } from '@dnd-kit/sortable' import { X, Minimize2, Pin } from 'lucide-react' import { stripLeadingAgentTitleDecoration } from '../../../../shared/agent-status/title/agent-title-decoration' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import { basename } from '@/lib/path' import { Input } from '@/components/ui/input' import { TabHoverCard } from './TabHoverCard' diff --git a/src/renderer/src/components/tab-bar/TabBarCreateEntryRow.tsx b/src/renderer/src/components/tab-bar/TabBarCreateEntryRow.tsx index 8d42dd4a39e..31305c1f9ab 100644 --- a/src/renderer/src/components/tab-bar/TabBarCreateEntryRow.tsx +++ b/src/renderer/src/components/tab-bar/TabBarCreateEntryRow.tsx @@ -12,7 +12,7 @@ import { Smartphone, TerminalSquare } from 'lucide-react' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { PluginContributionIcon } from '../plugins/PluginContributionIcon' import { cn } from '@/lib/utils' import { FilePathCursorTooltip, FilenameFirstPath } from '@/components/file-path-cursor-tooltip' diff --git a/src/renderer/src/components/tab-bar/TabBarQuickCommandItem.test.tsx b/src/renderer/src/components/tab-bar/TabBarQuickCommandItem.test.tsx index bb3f0ea05ba..350a8d3a7e9 100644 --- a/src/renderer/src/components/tab-bar/TabBarQuickCommandItem.test.tsx +++ b/src/renderer/src/components/tab-bar/TabBarQuickCommandItem.test.tsx @@ -22,8 +22,10 @@ vi.mock('@/i18n/i18n', () => ({ } })) -vi.mock('@/lib/agent-catalog', () => ({ - AgentIcon: () => null, +vi.mock('@/components/agent/icons/AgentIcon', () => ({ + AgentIcon: () => null +})) +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: (agent: string) => agent })) diff --git a/src/renderer/src/components/tab-bar/TabBarQuickCommandItem.tsx b/src/renderer/src/components/tab-bar/TabBarQuickCommandItem.tsx index 42f91ef9ea7..34dbd47a878 100644 --- a/src/renderer/src/components/tab-bar/TabBarQuickCommandItem.tsx +++ b/src/renderer/src/components/tab-bar/TabBarQuickCommandItem.tsx @@ -4,7 +4,8 @@ import { getTerminalQuickCommandBody, isTerminalAgentQuickCommand } from '../../../../shared/terminal/quick-commands/terminal-quick-commands' -import { AgentIcon, getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useTranslate } from '@/i18n/use-translate' import { useClipboardTextCopyFeedback } from '@/hooks/use-clipboard-text-copy-feedback' import type { HostedTerminalQuickCommand } from '@/hooks/use-terminal-quick-command-hosts' diff --git a/src/renderer/src/components/tab-bar/TabBarQuickCommandsMenu.tsx b/src/renderer/src/components/tab-bar/TabBarQuickCommandsMenu.tsx index c1f5d6a89dd..4f097749ad7 100644 --- a/src/renderer/src/components/tab-bar/TabBarQuickCommandsMenu.tsx +++ b/src/renderer/src/components/tab-bar/TabBarQuickCommandsMenu.tsx @@ -13,7 +13,7 @@ import { getTerminalQuickCommandBody, isTerminalAgentQuickCommand } from '../../../../shared/terminal/quick-commands/terminal-quick-commands' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import { TabBarQuickCommandItem } from './TabBarQuickCommandItem' import { cn } from '@/lib/utils' import { useTranslate } from '@/i18n/use-translate' diff --git a/src/renderer/src/components/tab-bar/TabBarQuickCommandsMenu.virtualization.test.tsx b/src/renderer/src/components/tab-bar/TabBarQuickCommandsMenu.virtualization.test.tsx index 1f40fe9a519..b7c4bd696cd 100644 --- a/src/renderer/src/components/tab-bar/TabBarQuickCommandsMenu.virtualization.test.tsx +++ b/src/renderer/src/components/tab-bar/TabBarQuickCommandsMenu.virtualization.test.tsx @@ -10,8 +10,10 @@ vi.mock('@/hooks/useShortcutLabel', () => ({ useShortcutKeyComboDetails: () => [ vi.mock('./tab-bar-quick-commands-shortcut', () => ({ useTabBarQuickCommandsShortcut: () => undefined })) -vi.mock('@/lib/agent-catalog', () => ({ - AgentIcon: () => null, +vi.mock('@/components/agent/icons/AgentIcon', () => ({ + AgentIcon: () => null +})) +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: (agent: string) => agent })) vi.mock('@/i18n/i18n', () => ({ diff --git a/src/renderer/src/components/tab-bar/TabDragPreview.tsx b/src/renderer/src/components/tab-bar/TabDragPreview.tsx index a975957bdbf..023134f7001 100644 --- a/src/renderer/src/components/tab-bar/TabDragPreview.tsx +++ b/src/renderer/src/components/tab-bar/TabDragPreview.tsx @@ -1,7 +1,7 @@ import { createElement } from 'react' import { Globe, Terminal as TerminalIcon } from 'lucide-react' import { FileTypeIcon } from '@/components/FileTypeIcon' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import type { TabDragItemData } from '../tab-group/useTabDragSplit' // Match the resting tab’s agent identity in the drag overlay. diff --git a/src/renderer/src/components/tab-bar/TerminalTabLeadingIcon.tsx b/src/renderer/src/components/tab-bar/TerminalTabLeadingIcon.tsx index d976d5416a7..3666cdbbd59 100644 --- a/src/renderer/src/components/tab-bar/TerminalTabLeadingIcon.tsx +++ b/src/renderer/src/components/tab-bar/TerminalTabLeadingIcon.tsx @@ -1,5 +1,5 @@ import { AgentStateDot } from '@/components/AgentStateDot' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { cn } from '@/lib/utils' import type { TerminalTab } from '../../../../shared/workspace-layout/terminal-tab-types' import type { TerminalAgent } from '../../../../shared/agent-status/identity/terminal-agent' diff --git a/src/renderer/src/components/tab-bar/native-chat-tab-agent-evidence.ts b/src/renderer/src/components/tab-bar/native-chat-tab-agent-evidence.ts index 4557431073f..74029c20348 100644 --- a/src/renderer/src/components/tab-bar/native-chat-tab-agent-evidence.ts +++ b/src/renderer/src/components/tab-bar/native-chat-tab-agent-evidence.ts @@ -2,7 +2,7 @@ import type { Tab } from '../../../../shared/tab-types' import type { TerminalTab } from '../../../../shared/workspace-layout/terminal-tab-types' import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' import { isTuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent-config' -import { resolveCommittedTitleAgentType } from '@/lib/pane-agent-evidence' +import { resolveExplicitTerminalTitleAgentType } from '../../../../shared/agent-status/title/terminal-title-agent-type' /** Resolve durable tab metadata used before a live pane status arrives. */ export function resolveNativeChatTabAgentEvidence( @@ -10,8 +10,8 @@ export function resolveNativeChatTabAgentEvidence( unifiedTab?: Pick ): TuiAgent | null { const agent = - resolveCommittedTitleAgentType(unifiedTab?.label ?? '') ?? - resolveCommittedTitleAgentType(tab.title) ?? + resolveExplicitTerminalTitleAgentType(unifiedTab?.label ?? '') ?? + resolveExplicitTerminalTitleAgentType(tab.title) ?? unifiedTab?.aiVaultTitle?.agent ?? tab.aiVaultTitle?.agent ?? null diff --git a/src/renderer/src/components/tab-bar/tab-agent-launch-options.ts b/src/renderer/src/components/tab-bar/tab-agent-launch-options.ts index 9cfa21c8eca..98a233b28ca 100644 --- a/src/renderer/src/components/tab-bar/tab-agent-launch-options.ts +++ b/src/renderer/src/components/tab-bar/tab-agent-launch-options.ts @@ -6,7 +6,7 @@ import type { } from '../../../../shared/agent-launch/picker/agent-launch-picker' import type { AgentPickerSetupIdentity } from '../agent/agent-launch-picker-drafts' import { rowLabel, rowId, chatUnavailableLabel } from './tab-agent-row-presentation' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { orderAgentLaunchPickerAgents, type NewTabAgentMenuRow diff --git a/src/renderer/src/components/tab-bar/tab-agent-row-presentation.ts b/src/renderer/src/components/tab-bar/tab-agent-row-presentation.ts index 812f66be86d..e7366e91edc 100644 --- a/src/renderer/src/components/tab-bar/tab-agent-row-presentation.ts +++ b/src/renderer/src/components/tab-bar/tab-agent-row-presentation.ts @@ -1,6 +1,6 @@ import { translate } from '@/i18n/i18n' import type { Translate } from '@/i18n/use-translate' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import type { ChatUnavailableReason, NewTabAgentMenuRow diff --git a/src/renderer/src/components/tab-bar/terminal-tab-activity-status.ts b/src/renderer/src/components/tab-bar/terminal-tab-activity-status.ts index eb103a60cc3..0f260688996 100644 --- a/src/renderer/src/components/tab-bar/terminal-tab-activity-status.ts +++ b/src/renderer/src/components/tab-bar/terminal-tab-activity-status.ts @@ -2,9 +2,12 @@ import { readAgentAttentionUnreadReason, type ReadableAgentAttentionUnread } from '@/attention/agent-attention-contract' -import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' +import { + isAgentStatusFresh, + AGENT_STATUS_STALE_AFTER_MS +} from '../../../../shared/agent-status/contracts/agent-status-freshness' import { resolveWorktreeStatus, type WorktreeStatus } from '@/lib/worktree-status' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../shared/agent-status/contracts/agent-status-freshness' + import type { AgentStatusEntry } from '../../../../shared/agent-status/contracts/agent-status-types' import { agentVerdictDisplayMark } from '../../../../shared/agent-status/lifecycle/agent-main-agent-verdict' import { resolveProgramStatusPresentation } from '../../../../shared/program-status/presentation' @@ -71,7 +74,7 @@ export function getTerminalTabActivityFlags( continue } // Apply sidebar freshness rules so abandoned/slept panes cannot keep tab spinners alive. - if (!isExplicitAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS)) { + if (!isAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS)) { // Stale identity suppresses Orca's one-shot permission label without suppressing native titles. getOrCreateTerminalTabActivityFlags(flagsByTabId, identity.tabId).stalePaneIds.add( identity.paneId diff --git a/src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows-owner.test.tsx b/src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows-owner.test.tsx index 0ded459a3da..e7df911e774 100644 --- a/src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows-owner.test.tsx +++ b/src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows-owner.test.tsx @@ -3,7 +3,7 @@ import { act, cleanup, render, renderHook, screen } from '@testing-library/react' import AgentCombobox from '@/components/agent/AgentCombobox' import { TooltipProvider } from '@/components/ui/tooltip' -import { AGENT_CATALOG } from '@/lib/agent-catalog' +import { AGENT_CATALOG } from '@/lib/agent-catalog/agent-catalog' import { afterEach, expect, it, vi } from 'vitest' import { useAppStore } from '@/store' diff --git a/src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows.ts b/src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows.ts index e7b5147ad50..2036f5abbe8 100644 --- a/src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows.ts +++ b/src/renderer/src/components/tab-bar/use-new-tab-agent-menu-rows.ts @@ -19,7 +19,7 @@ import { isTuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent-co import { useAgentPickerRefusedWake } from './use-agent-picker-refused-wake' import { buildAgentLaunchRouteInput } from '@/lib/agent-session/launch/routing/agent-launch-route-input' import { workspaceKindForWorktreeId } from '../../../../shared/agent-launch/contracts/workspace-launch-kind' -import { useHostStructuredAgentsVersion } from '@/lib/chat-provider-agents' +import { useHostStructuredAgentsVersion } from '@/runtime/native-chat/agent-catalogs/chat-provider-agents' import { structuredAgentSessionTargetForHost } from '@/runtime/native-chat/session-ownership/structured-agent-session-owner' import { readHostStructuredAgents, @@ -30,16 +30,16 @@ import { buildNewTabAgentMenuRows, type HostChatAnswer } from '../../../../shared/agent-launch/picker/agent-launch-picker-rows' -import { hostChatAnswer } from '@/lib/new-tab-agent-menu-rows' +import { hostChatAnswer } from '@/lib/agent-session/launch/routing/new-tab-agent-menu-rows' import { readLocalRuntimeCapabilityObservation, subscribeLocalRuntimeCapabilityObservation } from '@/runtime/hosts/capabilities/local-runtime-capabilities' import { useDetectedAgents, type AgentDetectionTarget } from '@/hooks/useDetectedAgents' -import { readDetectedAgentsForTarget } from '@/lib/agent-detection-target-inventory' +import { readDetectedAgentsForTarget } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { useChatProgramFacts } from '@/lib/host-chat-program-acquisition' import { readChatProgram } from '@/lib/host-chat-program' -import { resolveAgentMenuSelection } from '@/lib/agent-menu-selection' +import { resolveAgentMenuSelection } from '@/lib/agent-session/launch/routing/agent-menu-selection' import { useHostAgentMenuSettings } from '@/runtime/agent-launch-settings/use-host-agent-launch-preferences' import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' import type { AgentLaunchSurface } from '@/lib/agent-session/launch/routing/agent-session-launch-plan' diff --git a/src/renderer/src/components/tab-group/SplitPaneLandingAgentRow.tsx b/src/renderer/src/components/tab-group/SplitPaneLandingAgentRow.tsx index 0ed980ad35c..5f3be9f4759 100644 --- a/src/renderer/src/components/tab-group/SplitPaneLandingAgentRow.tsx +++ b/src/renderer/src/components/tab-group/SplitPaneLandingAgentRow.tsx @@ -3,9 +3,10 @@ import { useAppStore } from '../../store' import { useShortcutKeyDetails } from '@/hooks/useShortcutLabel' import { useTranslate } from '@/i18n/use-translate' import { cn } from '@/lib/utils' -import { AgentIcon, getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { focusTerminalTabSurface } from '@/lib/focus-terminal-tab-surface' -import { getDetectionTargetIdentityForWorktree } from '@/lib/agent-detection-target-inventory' +import { getDetectionTargetIdentityForWorktree } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { DropdownMenu, DropdownMenuContent, diff --git a/src/renderer/src/components/tab-group/tab-moves-drawn-from-frames.test.ts b/src/renderer/src/components/tab-group/tab-moves-drawn-from-frames.test.ts index ea2c17b4802..84d351f3fe8 100644 --- a/src/renderer/src/components/tab-group/tab-moves-drawn-from-frames.test.ts +++ b/src/renderer/src/components/tab-group/tab-moves-drawn-from-frames.test.ts @@ -1,7 +1,7 @@ // Exercise main-owned moves through the real frame transport and its full-build parity check. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { useAppStore } from '@/store' import { localDesktopSession } from '../../../../shared/workspace-layout/workspace-layout-profile.test-fixture' import { GIT_KEY } from '../../../../shared/workspace-layout/workspace-layout-session.test-fixture' @@ -35,7 +35,7 @@ vi.mock( }) ) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/components/terminal-agent-tab-shortcut.ts b/src/renderer/src/components/terminal-agent-tab-shortcut.ts index 73d4022cdfa..cd63dc8e7ec 100644 --- a/src/renderer/src/components/terminal-agent-tab-shortcut.ts +++ b/src/renderer/src/components/terminal-agent-tab-shortcut.ts @@ -2,13 +2,13 @@ import type { KeybindingActionId, KeybindingOverrides } from '../../../shared/ke import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' import { useAppStore } from '../store' import type { AppState } from '../store/types' -import { readDetectedAgentsForWorktree } from '@/lib/agent-detection-target-inventory' +import { readDetectedAgentsForWorktree } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { readAgentLaunchPreferencesForWorktree } from '@/runtime/agent-launch-settings/use-host-agent-launch-preferences' import { listBoundAgentTabActions, resolveDefaultAgentForNewTab, resolveDefaultAgentForWorktreeNewTab -} from '@/lib/agent-tab-shortcuts' +} from '@/lib/agent-session/launch/shortcuts/agent-tab-shortcuts' import { chosenAgentChatUnlearned } from '@/lib/host-chat-program' import { worktreeLaunchWorkspace } from '@/lib/agent-session/launch/routing/agent-launch-route-input' diff --git a/src/renderer/src/lib/agent-idle-edge.ts b/src/renderer/src/components/terminal-pane/agent-status/agent-idle-edge.ts similarity index 56% rename from src/renderer/src/lib/agent-idle-edge.ts rename to src/renderer/src/components/terminal-pane/agent-status/agent-idle-edge.ts index e5e2c1dc0f5..bcdf8ccec83 100644 --- a/src/renderer/src/lib/agent-idle-edge.ts +++ b/src/renderer/src/components/terminal-pane/agent-status/agent-idle-edge.ts @@ -1,7 +1,7 @@ -import { detectAgentStatusFromTitle } from '../../../shared/agent-status/title/agent-title-status' -import { isClaudeAgent } from '../../../shared/agent-status/title/agent-title-identity' -import type { AgentStatusEntry } from '../../../shared/agent-status/contracts/agent-status-types' -import type { AgentIdleEdgeMeta } from '../../../shared/terminal/output/terminal-output-side-effects' +import { detectAgentStatusFromTitle } from '../../../../../shared/agent-status/title/agent-title-status' +import { isClaudeAgent } from '../../../../../shared/agent-status/title/agent-title-identity' +import type { AgentStatusEntry } from '../../../../../shared/agent-status/contracts/agent-status-types' +import type { AgentIdleEdgeMeta } from '../../../../../shared/terminal/output/terminal-output-side-effects' /** Claude owns the edge: its title says so, or its status row does once the title drops its glyph. */ export function isClaudeIdleEdge(title: string, entry: AgentStatusEntry | undefined): boolean { diff --git a/src/renderer/src/components/terminal-pane/clipboard/terminal-agent-session-context-copy.ts b/src/renderer/src/components/terminal-pane/clipboard/terminal-agent-session-context-copy.ts index c10cc336d6c..b245ac50a31 100644 --- a/src/renderer/src/components/terminal-pane/clipboard/terminal-agent-session-context-copy.ts +++ b/src/renderer/src/components/terminal-pane/clipboard/terminal-agent-session-context-copy.ts @@ -1,5 +1,5 @@ import type { ManagedPane } from '../../../lib/pane-manager/pane-manager-types' -import { copyAgentSessionContext } from '../../../lib/copy-agent-session-context' +import { copyAgentSessionContext } from '../../../lib/agent-session/context/copy-agent-session-context' import { translate } from '../../../i18n/i18n' // Standalone Copy Context omits the dialog’s fork instructions so it can be pasted into another tool. diff --git a/src/renderer/src/components/terminal-pane/context-menu/terminal-pane-context-menu-types.ts b/src/renderer/src/components/terminal-pane/context-menu/terminal-pane-context-menu-types.ts index d0c2b63b195..76b5723bb54 100644 --- a/src/renderer/src/components/terminal-pane/context-menu/terminal-pane-context-menu-types.ts +++ b/src/renderer/src/components/terminal-pane/context-menu/terminal-pane-context-menu-types.ts @@ -3,7 +3,7 @@ import type { PaneManager } from '@/lib/pane-manager/pane-manager' import type { PtyTransport } from '../pty-transport/pty-transport-types' import type { PaneCwdMap } from '../layout/split/resolve-split-cwd' import type { PreparedAgentSessionFork } from '../session-fork/terminal-agent-session-fork' -import type { AgentSessionContinuationRequest } from '@/lib/agent-session-continuation' +import type { AgentSessionContinuationRequest } from '@/lib/agent-session/context/agent-session-continuation' export type UseTerminalPaneContextMenuDeps = { managerRef: React.RefObject diff --git a/src/renderer/src/components/terminal-pane/context-menu/terminal-pane-menu-agent-session-actions.ts b/src/renderer/src/components/terminal-pane/context-menu/terminal-pane-menu-agent-session-actions.ts index 23b8d5f9b7b..fbda92f1aed 100644 --- a/src/renderer/src/components/terminal-pane/context-menu/terminal-pane-menu-agent-session-actions.ts +++ b/src/renderer/src/components/terminal-pane/context-menu/terminal-pane-menu-agent-session-actions.ts @@ -6,7 +6,7 @@ import { type PreparedAgentSessionFork } from '../session-fork/terminal-agent-session-fork' import { prepareAgentSessionContinuationFromPane } from '../session-continuation/terminal-agent-session-continuation' -import type { AgentSessionContinuationRequest } from '@/lib/agent-session-continuation' +import type { AgentSessionContinuationRequest } from '@/lib/agent-session/context/agent-session-continuation' export type TerminalPaneMenuAgentSessionContext = { paneCwdRef: React.RefObject diff --git a/src/renderer/src/components/terminal-pane/controller/use-terminal-pane-foundation.ts b/src/renderer/src/components/terminal-pane/controller/use-terminal-pane-foundation.ts index d44d64151c4..3ffdec3cc73 100644 --- a/src/renderer/src/components/terminal-pane/controller/use-terminal-pane-foundation.ts +++ b/src/renderer/src/components/terminal-pane/controller/use-terminal-pane-foundation.ts @@ -13,7 +13,7 @@ import type { CloseTerminalDialogCopyKind } from '../layout/close/CloseTerminalD import type { TerminalLinkActionRequest } from '../links/terminal-link-action-request' import { closeLinkActionRequest as closeTerminalLinkActionRequest } from '@/components/link-actions/link-action-request' import type { PreparedAgentSessionFork } from '../session-fork/terminal-agent-session-fork' -import type { AgentSessionContinuationRequest } from '@/lib/agent-session-continuation' +import type { AgentSessionContinuationRequest } from '@/lib/agent-session/context/agent-session-continuation' import { createTerminalQuickCommandDraft } from '@/components/terminal-quick-commands/TerminalQuickCommandDialog' import { useDaemonActions } from '@/components/shared/useDaemonActions' import { useMobileOverlayTicks } from '../mobile-driver/use-mobile-overlay-ticks' diff --git a/src/renderer/src/components/terminal-pane/input/keyboard/terminal-ctrl-enter.ts b/src/renderer/src/components/terminal-pane/input/keyboard/terminal-ctrl-enter.ts index a5f171867c9..f295a48c374 100644 --- a/src/renderer/src/components/terminal-pane/input/keyboard/terminal-ctrl-enter.ts +++ b/src/renderer/src/components/terminal-pane/input/keyboard/terminal-ctrl-enter.ts @@ -2,7 +2,7 @@ import { isTuiAgent, TUI_AGENT_CONFIG } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' -import { resolveCommittedTitleAgentType } from '../../../../lib/pane-agent-evidence' +import { resolveExplicitTerminalTitleAgentType } from '../../../../../../shared/agent-status/title/terminal-title-agent-type' import type { PaneForegroundAgentEntry } from '@/store/slices/agent-status/pane-foreground-agent' type CtrlEnterPaneState = { @@ -26,7 +26,7 @@ export function hasCtrlEnterCsiUAuthorityForPane( if (foreground?.routingTrusted === true) { return agentAcceptsCtrlEnterCsiU(foreground.agent) } - const titleAgent = terminalTitle ? resolveCommittedTitleAgentType(terminalTitle) : null + const titleAgent = terminalTitle ? resolveExplicitTerminalTitleAgentType(terminalTitle) : null if (foreground?.agent != null && foreground.agent !== titleAgent) { return false } diff --git a/src/renderer/src/components/terminal-pane/input/keyboard/terminal-windows-shift-enter.ts b/src/renderer/src/components/terminal-pane/input/keyboard/terminal-windows-shift-enter.ts index 6c7c7cafc05..c4792deef5b 100644 --- a/src/renderer/src/components/terminal-pane/input/keyboard/terminal-windows-shift-enter.ts +++ b/src/renderer/src/components/terminal-pane/input/keyboard/terminal-windows-shift-enter.ts @@ -3,7 +3,7 @@ import { isTuiAgent, TUI_AGENT_CONFIG } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' -import { resolveCommittedTitleAgentType } from '../../../../lib/pane-agent-evidence' +import { resolveExplicitTerminalTitleAgentType } from '../../../../../../shared/agent-status/title/terminal-title-agent-type' import type { PaneForegroundAgentEntry } from '@/store/slices/agent-status/pane-foreground-agent' export type WindowsShiftEnterEncoding = 'alt-enter' | 'csi-u' @@ -58,7 +58,7 @@ export function resolveWindowsShiftEnterEncodingForPane( return encoding } // Why: strict pane-local titles recover Pi/Droid through process-scan gaps without overriding process or shell proof. - const titleAgent = resolveCommittedTitleAgentType(terminalTitle) + const titleAgent = resolveExplicitTerminalTitleAgentType(terminalTitle) // Why: pending confirmation retains the foreground identity; a stale title cannot switch agents. if ( foreground?.routingConfirmationPending === true && diff --git a/src/renderer/src/components/terminal-pane/notifications/claude-side-question-completion.test.ts b/src/renderer/src/components/terminal-pane/notifications/claude-side-question-completion.test.ts index ef4357eb019..d9e95e38930 100644 --- a/src/renderer/src/components/terminal-pane/notifications/claude-side-question-completion.test.ts +++ b/src/renderer/src/components/terminal-pane/notifications/claude-side-question-completion.test.ts @@ -169,7 +169,9 @@ describe('Claude completion banners through the real pane and hook lanes', () => dispatchNotification: (event: Parameters[1]) => dispatchTerminalNotification('wt-1', event) }) - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) await connectMockPanePty( createPane(1), diff --git a/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-byte-watcher.ts b/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-byte-watcher.ts index 7daa579d780..8f751e7d3ca 100644 --- a/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-byte-watcher.ts +++ b/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-byte-watcher.ts @@ -1,5 +1,5 @@ /** Keep mounted-pane bell/title/completion/PR-link policy active while parking unmounts TerminalPane. */ -import { isClaudeIdleEdge } from '@/lib/agent-idle-edge' +import { isClaudeIdleEdge } from '@/components/terminal-pane/agent-status/agent-idle-edge' import type { AgentIdleEdgeMeta } from '../../../../../../shared/terminal/output/terminal-output-side-effects' import { resolveTerminalNotificationOwner } from '@/attention/notification-subject-owner' import type { NotificationWorkspaceOwner } from '../../../../../../shared/notification-source' diff --git a/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-command-status.test.ts b/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-command-status.test.ts index 7a84c0f22fd..41688a997a6 100644 --- a/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-command-status.test.ts +++ b/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-command-status.test.ts @@ -40,7 +40,7 @@ vi.mock('@/store/index', () => ({ vi.mock('@/hooks/terminal-command-finished-event', () => ({ dispatchTerminalCommandFinishedEvent })) -vi.mock('@/lib/agent-status-connection-ownership', () => ({ +vi.mock('@/lib/agent-status/ownership/agent-status-connection-ownership', () => ({ resolveLiveAgentStatusConnectionRouting })) vi.mock('@/lib/workspace/ownership/connection-owner-resolution', () => ({ diff --git a/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-command-status.ts b/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-command-status.ts index 7442862a40d..1e38c1ef0fc 100644 --- a/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-command-status.ts +++ b/src/renderer/src/components/terminal-pane/parking/output-watchers/parked-terminal-command-status.ts @@ -4,7 +4,7 @@ import { resolvePaneAgentOwner } from '../../../../../../shared/agent-status/ide import { parseAppSshPtyId } from '../../../../../../shared/ssh-pty-id' import { isShellProcess } from '../../../../../../shared/agent-status/process/shell-process-detection' import { dispatchTerminalCommandFinishedEvent } from '@/hooks/terminal-command-finished-event' -import { resolveLiveAgentStatusConnectionRouting } from '@/lib/agent-status-connection-ownership' +import { resolveLiveAgentStatusConnectionRouting } from '@/lib/agent-status/ownership/agent-status-connection-ownership' import { getConnectionIdFromState } from '@/lib/workspace/ownership/connection-owner-resolution' import { rendererAgentStatusObservations } from '@/lib/renderer-agent-status-observations' import { isRetainedProgramResult } from '@/lib/program-status/row' diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/command-inferred-pane-agent.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/command-inferred-pane-agent.ts index 3694b3ced25..7244c0755c9 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/command-inferred-pane-agent.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/command-inferred-pane-agent.ts @@ -9,7 +9,7 @@ import type { import { registerAgentHookTerminalLifecycleHandler } from '../../agent-completion/agent-hook-terminal-lifecycle' import type { AgentCompletionStatusSnapshot } from '../../agent-completion/agent-completion-coordinator-types' import { resolveCompatibleAgentTypeForOwner } from '../../../../../../shared/agent-status/title/agent-title-owner' -import { resolveCommittedTitleAgentType } from '@/lib/pane-agent-evidence' +import { resolveExplicitTerminalTitleAgentType } from '../../../../../../shared/agent-status/title/terminal-title-agent-type' import { recognizeAgentLaunchCommand } from '../../../../../../shared/agent-launch/startup/agent-command-line-intent' import type { TerminalAgent } from '../../../../../../shared/agent-status/identity/terminal-agent' import { isTuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' @@ -178,7 +178,7 @@ export function installCommandInferredPaneAgent(session: ConnectPanePtySession): ) { return false } - const explicitTitleAgentType = resolveCommittedTitleAgentType(title) + const explicitTitleAgentType = resolveExplicitTerminalTitleAgentType(title) const activeHookAgentForTitle = resolveCompatibleAgentTypeForOwner( activeHookStatus?.agentType, explicitTitleAgentType diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-agent-status-routing.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-agent-status-routing.ts index e9cd183431f..1d8928cf725 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-agent-status-routing.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-agent-status-routing.ts @@ -1,4 +1,4 @@ -import { resolveLiveAgentStatusConnectionRouting } from '@/lib/agent-status-connection-ownership' +import { resolveLiveAgentStatusConnectionRouting } from '@/lib/agent-status/ownership/agent-status-connection-ownership' import { useAppStore } from '@/store' import type { ConnectPanePtySession } from '../connect-pane-pty-session' diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-agent-title-lifecycle.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-agent-title-lifecycle.ts index 3c7e17a71e3..12f9b0866c5 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-agent-title-lifecycle.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-agent-title-lifecycle.ts @@ -1,6 +1,9 @@ import type { ConnectPanePtySession } from '../connect-pane-pty-session' import type { AgentIdleEdgeMeta } from '../../../../../../shared/terminal/output/terminal-output-side-effects' -import { idleEdgeSettledAtRest, isClaudeIdleEdge } from '@/lib/agent-idle-edge' +import { + idleEdgeSettledAtRest, + isClaudeIdleEdge +} from '@/components/terminal-pane/agent-status/agent-idle-edge' import { useAppStore } from '@/store/index' export function installPaneAgentTitleLifecycle(session: ConnectPanePtySession): void { diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-title-observation.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-title-observation.ts index 5f087507e4f..6b63d342a76 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-title-observation.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pane-title-observation.ts @@ -1,7 +1,7 @@ import { resolvePaneTitleDecision } from '../../titles/terminal-title-evidence' import { useAppStore } from '@/store' import { shouldSeedCacheTimerOnInitialTitle } from '../../titles/cache-timer-seeding' -import { resolveCommittedTitleAgentType } from '@/lib/pane-agent-evidence' +import { resolveExplicitTerminalTitleAgentType } from '../../../../../../shared/agent-status/title/terminal-title-agent-type' import type { ConnectPanePtySession } from '../connect-pane-pty-session' export function installPaneTitleObservation(session: ConnectPanePtySession): void { @@ -10,7 +10,7 @@ export function installPaneTitleObservation(session: ConnectPanePtySession): voi rawTitle: string, meta?: { staleWorkingTitleClear?: boolean } ): void => { - if (!meta?.staleWorkingTitleClear && resolveCommittedTitleAgentType(rawTitle)) { + if (!meta?.staleWorkingTitleClear && resolveExplicitTerminalTitleAgentType(rawTitle)) { session.paneForegroundAgentTracker.onAgentStartupObserved() } // Share owner-aware display/title/completion/GPU decisions so raw title text cannot override stronger pane identity (#7428/#7447). diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-code-status-inference.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-code-status-inference.spec.ts index 39aae49a0ae..7841d3e0d0a 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-code-status-inference.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-code-status-inference.spec.ts @@ -57,8 +57,9 @@ export function registerPtyConnectionCommandCodeStatusInferenceTests(): void { it('seeds a working status for Command Code startup prompts after spawn', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const ptyId = 'pty-command-code' const transport = createMockTransport(ptyId) transportFactoryQueue.push(transport) @@ -105,8 +106,9 @@ export function registerPtyConnectionCommandCodeStatusInferenceTests(): void { it('seeds a working status from Command Code thinking output without a startup prompt', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const ptyId = 'pty-command-code' const transport = createMockTransport(ptyId) @@ -154,8 +156,9 @@ export function registerPtyConnectionCommandCodeStatusInferenceTests(): void { it('ignores delayed Command Code output after the leaf rebinds to another SSH host', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const oldPtyId = toAppSshPtyId('ssh-a', 'pty-command-code') const newPtyId = toAppSshPtyId('ssh-b', 'pty-command-code') @@ -192,8 +195,9 @@ export function registerPtyConnectionCommandCodeStatusInferenceTests(): void { it('marks a Command Code no-tool turn done after the idle prompt settles', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-command-code') transport.connect.mockImplementation( @@ -250,8 +254,9 @@ export function registerPtyConnectionCommandCodeStatusInferenceTests(): void { it('keeps Command Code working when an active repaint follows the idle prompt before settle', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-command-code') transport.connect.mockImplementation( @@ -295,8 +300,9 @@ export function registerPtyConnectionCommandCodeStatusInferenceTests(): void { it('does not downgrade a completed Command Code turn back to working from stale TUI output', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-command-code') transport.connect.mockImplementation( @@ -344,8 +350,9 @@ export function registerPtyConnectionCommandCodeStatusInferenceTests(): void { it('starts a new Command Code turn after done when TUI output carries a different prompt', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-command-code') transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-finished-cleanup.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-finished-cleanup.spec.ts index 127b4ef51f0..66dadacf42a 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-finished-cleanup.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-finished-cleanup.spec.ts @@ -64,8 +64,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { it('keeps Droid routing visible through command-finished foreground confirmation', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const getForegroundProcess = vi.mocked(window.api.pty.confirmForegroundProcess) getForegroundProcess.mockResolvedValue('droid') const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } @@ -123,8 +124,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { it('retires pane launch routing after one fresh scan confirms shell', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.pty.confirmForegroundProcess).mockResolvedValue('powershell.exe') const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } const ptyId = 'pty-droid-confirmed-shell' @@ -177,8 +179,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { ])('%s', async (_label, stoppingOnPurpose) => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.pty.confirmForegroundProcess).mockResolvedValue('zsh') const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } const ptyId = 'pty-sleeping-confirmed-shell' @@ -241,8 +244,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { it('keeps sleeping identity when the foreground check still sees the agent', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) // Why both: the pane's process monitor reads the same foreground the confirm read sees. vi.mocked(window.api.pty.getForegroundProcess).mockResolvedValue('codex') const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } @@ -296,8 +300,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { // Use an accepted row to exercise deferred-drop bookkeeping before reconcile; the no-row path returns early. vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) // Import dynamically to share pty-connection’s live registry; a static import can be a stale instance. const { createCommandFinishedStatusStore } = await import('./command-finished-status-store-test-fixture') @@ -350,8 +355,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { it('does NOT reconcile when the process check could not confirm a shell', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.pty.confirmForegroundProcess).mockResolvedValue(null) vi.mocked(window.api.agentStatus.reconcileEndedProcess).mockClear() const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } @@ -399,8 +405,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { it('disarms stale TUI modes in the emulator after a confirmed return to shell', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.pty.confirmForegroundProcess).mockResolvedValue('bash') const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } const ptyId = 'pty-stale-mode-disarm' @@ -449,8 +456,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { it('grounds xterm and the input mirror in stream order when output is still queued', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const confirmRead = createDeferred() vi.mocked(window.api.pty.confirmForegroundProcess).mockReturnValue(confirmRead.promise) const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } @@ -500,8 +508,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { it('keeps armed modes while the agent still owns the foreground after a leaked 133;D', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) // Why both: the pane's process monitor reads the same foreground the confirm read sees. vi.mocked(window.api.pty.getForegroundProcess).mockResolvedValue('droid') const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } @@ -542,8 +551,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { it('retires stale routing after unavailable command-finish reads without asserting shell', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.pty.confirmForegroundProcess).mockResolvedValue(null) const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } const ptyId = 'pty-droid-unavailable-finish' @@ -593,8 +603,9 @@ export function registerPtyConnectionCommandFinishedCleanupTests(): void { it('cancels deferred cleanup on a new command and retires identity at its later shell', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.pty.confirmForegroundProcess).mockResolvedValue('powershell.exe') const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } const ptyId = 'pty-droid-superseded-confirmation' diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-finished-late-done.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-finished-late-done.test.ts index 5a666f3c5a8..76a14461e1c 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-finished-late-done.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-command-finished-late-done.test.ts @@ -64,7 +64,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -156,7 +156,9 @@ describe('command-finished drop and a Done that lands after it', () => { }> { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createTestStore } = await import('@/store/testing/app-store-test-fixture') vi.mocked(window.api.pty.confirmForegroundProcess).mockResolvedValue('zsh') const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } @@ -179,7 +181,11 @@ describe('command-finished drop and a Done that lands after it', () => { await vi.advanceTimersByTimeAsync(20) await flushAsyncTicks() const realStore = createTestStore( - (await vi.importMock('@/lib/agent-status')).isClaudeAgent + ( + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) + ).isClaudeAgent ) mockStoreState.dropAgentStatus.mockImplementation((key: string) => { delete mockStoreState.agentStatusByPaneKey[key] diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-agent-routing.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-agent-routing.spec.ts index 8a63e2f4201..30d46d366be 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-agent-routing.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-agent-routing.spec.ts @@ -68,8 +68,9 @@ export function registerPtyConnectionForegroundAgentRoutingTests(): void { it('routes a manually typed Droid only after foreground enrichment confirms it', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } const pane = createPane(1) const ptyId = 'pty-manually-typed-droid' @@ -120,8 +121,9 @@ export function registerPtyConnectionForegroundAgentRoutingTests(): void { it('confirms a manually typed Droid without OSC command boundaries', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.pty.confirmForegroundProcess).mockResolvedValue('droid') const pane = createPane(1) const ptyId = 'pty-manual-droid-no-osc' @@ -161,8 +163,9 @@ export function registerPtyConnectionForegroundAgentRoutingTests(): void { // Retry across Droid boot while early foreground reads still see its shell. vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const foregroundResults = ['bash.exe', 'bash.exe', 'droid'] vi.mocked(window.api.pty.confirmForegroundProcess).mockImplementation( async () => foregroundResults.shift() ?? 'droid' @@ -208,8 +211,9 @@ export function registerPtyConnectionForegroundAgentRoutingTests(): void { // A slow-boot miss must remain recoverable; latching shell would erase launch identity and poison later routing. vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) let foreground = 'bash.exe' // Why both: the pane's process monitor reads the same foreground the confirm read sees. vi.mocked(window.api.pty.getForegroundProcess).mockImplementation(async () => foreground) @@ -266,8 +270,9 @@ export function registerPtyConnectionForegroundAgentRoutingTests(): void { it('confirms a delayed Claude from fresh startup output after the first read window expires', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) let foreground = 'sleep' vi.mocked(window.api.pty.getForegroundProcess).mockImplementation(async () => foreground) vi.mocked(window.api.pty.confirmForegroundProcess).mockImplementation(async () => foreground) @@ -307,8 +312,9 @@ export function registerPtyConnectionForegroundAgentRoutingTests(): void { it('revokes trusted Droid after accepted no-OSC exit input until shell confirmation', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.pty.confirmForegroundProcess).mockResolvedValue('cmd.exe') const pane = createPane(1) const ptyId = 'pty-droid-exit-no-osc' @@ -355,8 +361,9 @@ export function registerPtyConnectionForegroundAgentRoutingTests(): void { it('trusts Pi in a no-OSC shell and retires routing after accepted exit input', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) let foreground = 'pi' vi.mocked(window.api.pty.getForegroundProcess).mockResolvedValue('pi') vi.mocked(window.api.pty.confirmForegroundProcess).mockImplementation(async () => foreground) @@ -416,8 +423,9 @@ export function registerPtyConnectionForegroundAgentRoutingTests(): void { it('never promotes typed Droid text when foreground enrichment is unavailable', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.pty.confirmForegroundProcess) .mockResolvedValueOnce(null) .mockRejectedValueOnce(new Error('inspection unavailable')) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-agent-sampling.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-agent-sampling.spec.ts index 6aa8ee78103..8a95f9efba1 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-agent-sampling.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-agent-sampling.spec.ts @@ -91,8 +91,9 @@ export function registerPtyConnectionForegroundAgentSamplingTests(): void { cacheKey: string }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const ptyId = args.ptyId ?? 'tab-pty' const tabId = args.tabId ?? `tab-${ptyId}` const hasReattachMetadata = @@ -506,8 +507,9 @@ export function registerPtyConnectionForegroundAgentSamplingTests(): void { // Why: a cached visible read has no routing authority; on a racing command boundary, trust the shell marker over stale identity. vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const getForegroundProcess = vi.mocked(window.api.pty.getForegroundProcess) getForegroundProcess.mockResolvedValue('codex') const ptyId = 'pty-reattach-idle-codex-leaked-d' @@ -555,8 +557,9 @@ export function registerPtyConnectionForegroundAgentSamplingTests(): void { it('re-confirms leaked 133;D after detach moved pane-scoped Droid identity', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const getForegroundProcess = vi.mocked(window.api.pty.getForegroundProcess) getForegroundProcess.mockResolvedValue('droid') const ptyId = 'pty-detached-droid-leaked-d' diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-process-exit.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-process-exit.spec.ts index c74629b2120..79a04c20708 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-process-exit.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-process-exit.spec.ts @@ -64,8 +64,9 @@ export function registerPtyConnectionForegroundProcessExitTests(): void { deps: ReturnType }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const tabId = `tab-${ptyId}` const transport = createMockTransport(ptyId) transport.getPtyId.mockImplementation(() => ptyId) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-routing-confirmation.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-routing-confirmation.spec.ts index b83558fc4ab..636ac624a8f 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-routing-confirmation.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-foreground-routing-confirmation.spec.ts @@ -88,8 +88,9 @@ export function registerPtyConnectionForegroundRoutingConfirmationTests(): void cacheKey: string }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const ptyId = args.ptyId ?? 'tab-pty' const tabId = args.tabId ?? `tab-${ptyId}` const hasReattachMetadata = diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-process-exit-row-retire.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-process-exit-row-retire.test.ts index 7b8f34f30da..841944d4a55 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-process-exit-row-retire.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-process-exit-row-retire.test.ts @@ -72,7 +72,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -142,7 +142,9 @@ async function connectAgentPane(args: { terminal: ReturnType['terminal'] }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport(args.ptyId) transport.connect.mockImplementation(async ({ callbacks }: { callbacks: ConnectCallbacks }) => { @@ -189,7 +191,11 @@ async function seedHookRow( // Why the real slice: the row must carry the acceptedStatusSeq a real accepted hook stamps. const { createTestStore } = await import('@/store/testing/app-store-test-fixture') const realStore = createTestStore( - (await vi.importMock('@/lib/agent-status')).isClaudeAgent + ( + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) + ).isClaudeAgent ) realStore.getState().setAgentStatus(paneKey, { state, prompt: 'ship it', agentType }) const row = realStore.getState().agentStatusByPaneKey[paneKey] diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-typed-agent-identity.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-typed-agent-identity.spec.ts index e64386c7447..92f81eaa8f7 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-typed-agent-identity.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/pty-connection-typed-agent-identity.spec.ts @@ -66,8 +66,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('normalizes Pi-compatible remote runtime status to OMP after typed omp command', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) const pane = createPane(1) @@ -110,8 +111,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('drives runtime title, tab title, and renderer policy from one title decision', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const transport = createMockTransport('pty-gemini') transportFactoryQueue.push(transport) @@ -141,8 +143,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('keeps GPU enabled when a pane-scoped OMP owner emits a Gemini-looking title', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const paneKey = makePaneKey('tab-1', LEAF_1) mockStoreState = { ...mockStoreState, @@ -185,8 +188,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('does not let one split pane title change another pane GPU state', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane1 = createPane(1) const pane2 = createPane(2) const transport1 = createMockTransport('pty-split-1') @@ -220,8 +224,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('DOM-gates a genuine Gemini split pane even when the tab launched a non-Gemini agent', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) // The shared tab.launchAgent must not veto the renderer for a sibling pane. mockStoreState = { ...mockStoreState, @@ -260,8 +265,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('DOM-gates a genuine Gemini title in a pane whose launch agent was non-Gemini', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const transport = createMockTransport('pty-reused-gemini') transportFactoryQueue.push(transport) @@ -288,8 +294,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('DOM-gates a genuine Gemini title when the only pane row is a done non-Gemini agent', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const paneKey = makePaneKey('tab-1', LEAF_1) mockStoreState = { ...mockStoreState, @@ -331,8 +338,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('DOM-gates a genuine Gemini title when the only pane row is a stale non-Gemini agent', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const paneKey = makePaneKey('tab-1', LEAF_1) const staleAt = Date.now() - 60 * 60 * 1000 mockStoreState = { @@ -375,8 +383,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('normalizes after shell word deletion edits a typed command to omp', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) const pane = createPane(1) @@ -418,8 +427,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('keeps Pi-compatible remote runtime status as Pi after typed pi command', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) const pane = createPane(1) @@ -462,8 +472,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('does not infer shell ownership from prompts typed inside an existing Pi session', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) const now = Date.now() @@ -518,8 +529,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('does not infer shell ownership from prompts typed in a title-only Pi session', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) mockStoreState.runtimePaneTitlesByTabId = { 'tab-1': { 1: 'Pi ready' } } @@ -563,8 +575,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('lets a new typed omp command override a stale retained done status', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) const now = Date.now() @@ -616,8 +629,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('tracks cursor edits when inferring a typed omp command', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) const pane = createPane(1) @@ -658,8 +672,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('tracks delete-key cursor edits when inferring a typed omp command', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks15 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) const pane = createPane(1) @@ -699,8 +714,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('skips manual agent inference for large paste chunks', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks16 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks16 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) const pane = createPane(1) @@ -740,8 +756,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('resumes manual agent inference when large paste input is cancelled', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks17 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks17 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) const pane = createPane(1) @@ -783,8 +800,9 @@ export function registerPtyConnectionTypedAgentIdentityTests(): void { it('preserves typed shell ownership through same-chunk command-finished side effects', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks18 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks18 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const paneKey = makePaneKey('tab-1', LEAF_1) const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } diff --git a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/renderer-owned-pane-status.ts b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/renderer-owned-pane-status.ts index 59a12a94bb5..45411a1398c 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/renderer-owned-pane-status.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/agent-identity/renderer-owned-pane-status.ts @@ -1,5 +1,5 @@ import { useAppStore } from '@/store' -import { resolveAgentStatusTerminalTitle } from '@/lib/agent-status-terminal-title' +import { resolveAgentStatusTerminalTitle } from '@/lib/agent-status/evidence/agent-status-terminal-title' import { normalizeCompatibleAgentTitleForOwner, resolveCompatibleAgentTypeForOwner diff --git a/src/renderer/src/components/terminal-pane/pty-connection/connect-pane-pty.ts b/src/renderer/src/components/terminal-pane/pty-connection/connect-pane-pty.ts index 7a9db79d87e..eda17e99774 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/connect-pane-pty.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/connect-pane-pty.ts @@ -19,7 +19,7 @@ import { writeTerminalOutput } from '@/lib/pane-manager/pane-terminal-output-sch import { createTerminalStructuralReplayCoordinator } from '@/lib/pane-manager/terminal-structural-replay-coordinator' import { makePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' import type { AgentType } from '../../../../../shared/agent-status/contracts/agent-status-types' -import { resolveCommittedTitleAgentType } from '@/lib/pane-agent-evidence' +import { resolveExplicitTerminalTitleAgentType } from '../../../../../shared/agent-status/title/terminal-title-agent-type' import { shouldWritePtyOutputForeground } from './output/foreground-output-visibility' import { exposeE2eTerminalPtyOutputDebug } from './instrumentation/e2e-terminal-pty-harness' @@ -152,7 +152,7 @@ export function connectPanePty( title: string | undefined, agentType: AgentType | undefined ): void => { - const titleAgentType = resolveCommittedTitleAgentType(title ?? '') + const titleAgentType = resolveExplicitTerminalTitleAgentType(title ?? '') session.suppressNativeWindowsIdleCodexFocusReports = agentType && agentType !== 'unknown' ? agentType === 'codex' : titleAgentType === 'codex' } diff --git a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-agent-idle-cursor-reset.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-agent-idle-cursor-reset.spec.ts index cbee922763a..588cab8c923 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-agent-idle-cursor-reset.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-agent-idle-cursor-reset.spec.ts @@ -61,8 +61,9 @@ export function registerPtyConnectionAgentIdleCursorResetTests(): void { it('resets renderer cursor style when an agent becomes idle', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -97,8 +98,9 @@ export function registerPtyConnectionAgentIdleCursorResetTests(): void { ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -182,8 +184,9 @@ export function registerPtyConnectionWindowsCompletedTurnCursorResetTests(): voi ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -238,8 +241,9 @@ export function registerPtyConnectionWindowsCompletedTurnCursorResetTests(): voi ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -298,8 +302,9 @@ export function registerPtyConnectionWindowsCompletedTurnCursorResetTests(): voi ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -356,8 +361,9 @@ export function registerPtyConnectionWindowsCompletedTurnCursorResetTests(): voi ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -455,8 +461,9 @@ export function registerPtyConnectionWindowsCursorResetDisposalTests(): void { ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-codex-queries.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-codex-queries.spec.ts index 0bec885d8e7..6c18925997b 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-codex-queries.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-codex-queries.spec.ts @@ -55,8 +55,9 @@ export function registerPtyConnectionHiddenCodexQueriesTests(): void { it('keeps hidden Codex redraw floods off the live xterm path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -103,8 +104,9 @@ export function registerPtyConnectionHiddenCodexQueriesTests(): void { 'keeps hidden %s terminal query chunks on the live xterm path', async (command) => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -142,8 +144,9 @@ export function registerPtyConnectionHiddenCodexQueriesTests(): void { it('keeps only coalesced hidden Codex terminal queries on the live xterm path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -182,8 +185,9 @@ export function registerPtyConnectionHiddenCodexQueriesTests(): void { it('answers hidden OSC color queries directly inside a mixed capability-query burst', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -227,8 +231,9 @@ export function registerPtyConnectionHiddenCodexQueriesTests(): void { it('answers adjacent hidden Codex OSC color queries directly', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -272,8 +277,9 @@ export function registerPtyConnectionHiddenCodexQueriesTests(): void { it('keeps split hidden Codex terminal queries on the live xterm path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -315,8 +321,9 @@ export function registerPtyConnectionHiddenCodexQueriesTests(): void { it('keeps hidden Codex terminal queries split after ESC on the live xterm path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -358,8 +365,9 @@ export function registerPtyConnectionHiddenCodexQueriesTests(): void { it('flushes pending hidden Codex query prefixes when the pane becomes visible', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-query-admission.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-query-admission.spec.ts index d0705bc079a..af23a469a94 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-query-admission.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-query-admission.spec.ts @@ -54,8 +54,9 @@ export function registerPtyConnectionHiddenEscapeAdmissionTests(): void { it('keeps all visible bytes after a pending hidden ESC becomes non-query output', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -139,8 +140,9 @@ export function registerPtyConnectionHiddenQueryAdmissionTests(): void { it('keeps split stateful Codex queries live after becoming visible', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -190,8 +192,9 @@ export function registerPtyConnectionHiddenQueryAdmissionTests(): void { it('drops pending hidden Codex query prefixes when the PTY changes', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -235,8 +238,9 @@ export function registerPtyConnectionHiddenQueryAdmissionTests(): void { it('does not live-render split hidden Codex non-query CSI output', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -277,8 +281,9 @@ export function registerPtyConnectionHiddenQueryAdmissionTests(): void { it('answers split hidden Codex OSC color queries directly', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -319,8 +324,9 @@ export function registerPtyConnectionHiddenQueryAdmissionTests(): void { it('answers hidden Codex OSC color queries split before the prefix directly', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -361,8 +367,9 @@ export function registerPtyConnectionHiddenQueryAdmissionTests(): void { it('keeps later hidden Codex stateless terminal queries on the live xterm path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -404,8 +411,9 @@ export function registerPtyConnectionHiddenQueryAdmissionTests(): void { it('keeps clean hidden Codex stateful cursor-position queries on the live xterm path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -441,8 +449,9 @@ export function registerPtyConnectionHiddenQueryAdmissionTests(): void { it('does not answer dirty hidden Codex stateful queries from stale xterm state', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-startup-query-admission.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-startup-query-admission.spec.ts index 638fed57ea2..93cbbe54f8a 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-startup-query-admission.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-hidden-startup-query-admission.spec.ts @@ -55,8 +55,9 @@ export function registerPtyConnectionHiddenStartupQueryAdmissionTests(): void { it('keeps hidden Codex telemetry startup output parsing briefly', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -107,8 +108,9 @@ export function registerPtyConnectionHiddenStartupQueryAdmissionTests(): void { it('does not answer hidden Jcode startup color queries (composer-text leak guard)', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -155,8 +157,9 @@ export function registerPtyConnectionHiddenStartupQueryAdmissionTests(): void { it('keeps hidden Grok telemetry startup output parsing briefly', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -207,8 +210,9 @@ export function registerPtyConnectionHiddenStartupQueryAdmissionTests(): void { it('keeps hidden bare Codex startup commands parsing briefly', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -252,8 +256,9 @@ export function registerPtyConnectionHiddenStartupQueryAdmissionTests(): void { it('keeps hidden bare Grok startup commands parsing briefly', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -297,8 +302,9 @@ export function registerPtyConnectionHiddenStartupQueryAdmissionTests(): void { it('skips arbitrary hidden startup output parsing', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks15 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-main-side-effect-authority.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-main-side-effect-authority.spec.ts index d464fa40703..3d9c714a463 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-main-side-effect-authority.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-main-side-effect-authority.spec.ts @@ -81,8 +81,9 @@ export function registerPtyConnectionMainSideEffectAuthorityTests(): void { it('stops consuming facts after the pane binding is disposed', async () => { enableMainAuthority() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const handler = await import('../../pty-transport/output/terminal-side-effect-facts-handler') const transport = createMockTransport() @@ -110,8 +111,9 @@ export function registerPtyConnectionMainSideEffectAuthorityTests(): void { it('clears state without completion attention for stale-derived facts', async () => { enableMainAuthority() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const handler = await import('../../pty-transport/output/terminal-side-effect-facts-handler') const transport = createMockTransport() @@ -163,8 +165,9 @@ export function registerPtyConnectionMainSideEffectAuthorityTests(): void { it('does not byte-scan PR links or OSC 133 — facts are the only consumer', async () => { enableMainAuthority() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -205,8 +208,9 @@ export function registerPtyConnectionMainSideEffectAuthorityTests(): void { it('rejects Command Code facts when Claude owns the pane', async () => { enableMainAuthority() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const handler = await import('../../pty-transport/output/terminal-side-effect-facts-handler') const transport = createMockTransport() @@ -257,8 +261,9 @@ export function registerPtyConnectionMainSideEffectAuthorityTests(): void { it('rejects Command Code facts when retained Claude identity owns the pane', async () => { enableMainAuthority() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const handler = await import('../../pty-transport/output/terminal-side-effect-facts-handler') const transport = createMockTransport() @@ -303,8 +308,9 @@ export function registerPtyConnectionMainSideEffectAuthorityTests(): void { it('keeps Command Code working when a working fact lands before the done settles', async () => { enableMainAuthority() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const handler = await import('../../pty-transport/output/terminal-side-effect-facts-handler') const transport = createMockTransport() @@ -352,8 +358,9 @@ export function registerPtyConnectionMainSideEffectAuthorityTests(): void { getSync: vi.fn(() => ({ terminalMainSideEffectAuthority: false })) } const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks15 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const handler = await import('../../pty-transport/output/terminal-side-effect-facts-handler') const transport = createMockTransport() diff --git a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-mode-2031-subscriptions.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-mode-2031-subscriptions.spec.ts index 82d33a849a2..00f51c81ff3 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-mode-2031-subscriptions.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/emulation/pty-connection-mode-2031-subscriptions.spec.ts @@ -62,8 +62,9 @@ export function registerPtyConnectionMode2031SubscriptionsTests(): void { dispose: () => void }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const captured: { current: ((data: string, meta?: { droppedOutput?: boolean }) => void) | null @@ -269,8 +270,9 @@ export function registerPtyConnectionMode2031SubscriptionsTests(): void { it('records hidden Codex mode 2031 subscribes split across becoming visible', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -320,8 +322,9 @@ export function registerPtyConnectionMode2031SubscriptionsTests(): void { it('does not keep mode 2031 subscribed when a skipped hidden chunk unsubscribes last', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/geometry/pty-connection-hidden-resize-authority.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/geometry/pty-connection-hidden-resize-authority.spec.ts index 107c5e9a46a..d9433796eed 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/geometry/pty-connection-hidden-resize-authority.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/geometry/pty-connection-hidden-resize-authority.spec.ts @@ -52,8 +52,9 @@ export function registerPtyConnectionHiddenResizeAuthorityTests(): void { it('does not forward terminal resizes while the pane is hidden', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') transportFactoryQueue.push(transport) const pane = createPane(1) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/geometry/pty-connection-visibility-resume-size.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/geometry/pty-connection-visibility-resume-size.spec.ts index 6fc6faf68f9..cbdfc7fdd10 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/geometry/pty-connection-visibility-resume-size.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/geometry/pty-connection-visibility-resume-size.spec.ts @@ -64,8 +64,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { pane: ReturnType }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -176,8 +177,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { try { vi.mocked(window.api.pty.getSize).mockResolvedValue({ cols: 200, rows: 40 }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -207,8 +209,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { it('repairs stale xterm grid drift on foreground output even without a pane resize', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -263,8 +266,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { emitFrame: (data: string) => void }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -402,8 +406,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { it('skips foreground grid drift repair while mobile owns the PTY without a fit override', async () => { const { setDriverForPty } = await import('@/lib/pane-manager/mobile-driver-state') const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -460,8 +465,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { const observer = installObservedPane(pane) try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -510,8 +516,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { const observer = installObservedPane(pane) try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -566,8 +573,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { const observer = installObservedPane(pane) try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -614,8 +622,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { const observer = installObservedPane(pane) try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -723,8 +732,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { const getSize = vi.mocked(window.api.pty.getSize) getSize.mockClear() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('remote:env-1@@terminal-2') transport.getConnectionId.mockReturnValue(null) transportFactoryQueue.push(transport) @@ -759,8 +769,9 @@ export function registerPtyConnectionVisibilityResumeSizeTests(): void { } as unknown as Document const { setFitOverride } = await import('@/lib/pane-manager/mobile-fit-overrides') const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const ptyId = 'remote:env-1@@terminal-visible' const transport = createMockTransport(ptyId) transportFactoryQueue.push(transport) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/geometry/remote-reconnect-unimaged-pane-redraw.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/geometry/remote-reconnect-unimaged-pane-redraw.test.ts index 6076e7fa67d..5876b6a2b14 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/geometry/remote-reconnect-unimaged-pane-redraw.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/geometry/remote-reconnect-unimaged-pane-redraw.test.ts @@ -31,7 +31,7 @@ vi.mock('@/runtime/sync-runtime-graph/graph-sync-scheduler', () => ({ scheduleRu vi.mock('@/store/index', () => ({ useAppStore: { getState: () => mockStoreState, subscribe: () => () => {} } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -93,7 +93,9 @@ async function connectVisibleRemotePane( opts: { visible?: boolean } = {} ): Promise { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport(REMOTE_PTY_ID) transport.serializeBuffer = vi.fn() transport.serializeBufferOutcome = vi.fn( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-owner-hydration-backend-retention.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-owner-hydration-backend-retention.test.ts index d8607b45955..bfc2bff7ef3 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-owner-hydration-backend-retention.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-owner-hydration-backend-retention.test.ts @@ -61,7 +61,7 @@ vi.mock('@/store', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -129,7 +129,9 @@ describe('connectPanePty owner hydration and backend retention', () => { it('parks an unknown owner until hydration, then retains the acquired backend on refresh', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') @@ -200,8 +202,9 @@ describe('connectPanePty owner hydration and backend retention', () => { 'retains the connect owner through focus changes ($rowless, $remote)', async ({ rowless, remote }) => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createTerminalPaneManagerOptions } = await import('../../mounting/terminal-pane-manager-options') vi.stubGlobal('navigator', { userAgent: 'Windows' }) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-runtime-owner-spawn-routing.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-runtime-owner-spawn-routing.spec.ts index 1735db54b2c..87d3f23222c 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-runtime-owner-spawn-routing.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-runtime-owner-spawn-routing.spec.ts @@ -54,8 +54,9 @@ export function registerPtyConnectionRuntimeOwnerSpawnRoutingTests(): void { it('fails closed when the same SSH worktree id is projected by two HUBs', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') @@ -104,8 +105,9 @@ export function registerPtyConnectionRuntimeOwnerSpawnRoutingTests(): void { it('fails a missing paired-client owner closed instead of creating a local PTY', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') @@ -137,8 +139,9 @@ export function registerPtyConnectionRuntimeOwnerSpawnRoutingTests(): void { it('spawns fresh PTYs through the worktree owner runtime when focus differs', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const transport = createMockTransport('remote:owner-runtime@@terminal-1') @@ -191,8 +194,9 @@ export function registerPtyConnectionRuntimeOwnerSpawnRoutingTests(): void { it('spawns fresh PTYs locally for explicitly local worktrees while a runtime is focused', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') diff --git a/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-runtime-pane-transport-routing.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-runtime-pane-transport-routing.spec.ts index 0057ee1d9b5..73351df8de2 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-runtime-pane-transport-routing.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-runtime-pane-transport-routing.spec.ts @@ -54,8 +54,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('does not let a restored encoded PTY override the current worktree owner', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const transport = createMockTransport() @@ -102,8 +103,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('routes a paired-web mirrored pane through its session-scoped HUB owner', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') @@ -150,8 +152,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('uses a paired-web pane owner to disambiguate duplicate HUB projections', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const transport = createMockTransport() @@ -193,8 +196,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('ignores a stale runtime PTY on an explicitly local non-web pane', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') @@ -223,8 +227,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('spawns an unstamped local worktree locally while a single server is focused', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') @@ -254,8 +259,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('runs an inline setup terminal locally instead of failing its host closed', async () => { // Synthetic setup IDs have no catalog row; they must resolve locally instead of failing strict ownership as ambiguous (#9994). const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') @@ -287,8 +293,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('runs an inline setup terminal on the single active runtime for remote skill installs', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const transport = createMockTransport() @@ -321,8 +328,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('still spawns locally when the worktree row itself proves a local host', async () => { // A local-stamped worktree already names its host before its repo hydrates. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -350,8 +358,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('withholds a local spawn while a repo-backed worktree has no hydrated host', async () => { // Missing SSH repo metadata must defer resolution rather than spawn remote cwd paths on the local daemon. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') @@ -384,8 +393,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('keeps the floating terminal local even while a runtime is active', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks15 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') @@ -417,8 +427,9 @@ export function registerPtyConnectionRuntimePaneTransportRoutingTests(): void { it('routes a HUB-owned SSH PTY wake hint through the HUB without direct SSH', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks16 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks16 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') const transport = createMockTransport() diff --git a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-command-finished-interrupt-arbitration.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-command-finished-interrupt-arbitration.spec.ts index eee12960498..bd8b982d4d9 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-command-finished-interrupt-arbitration.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-command-finished-interrupt-arbitration.spec.ts @@ -60,8 +60,9 @@ export function registerPtyConnectionCommandFinishedInterruptArbitrationTests(): 'pins %s interrupt policy before acknowledged input and command exit cleanup', async (agentType) => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport() diff --git a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-hibernation-activity.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-hibernation-activity.spec.ts index 685143b73ba..8ad9ebb0934 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-hibernation-activity.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-hibernation-activity.spec.ts @@ -59,8 +59,9 @@ export function registerPtyConnectionHibernationActivityTests(): void { it('records hibernation activity from the core user-input signal, not synthetic onData replies', async () => { // Regression: xterm auto-replies share the onData stream with typing; recording them as input made the planner see "input after done" and never hibernate. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(1) @@ -106,8 +107,9 @@ export function registerPtyConnectionHibernationActivityTests(): void { it('falls back to onData hibernation recording when the core user-input signal is unavailable', async () => { // If an xterm upgrade removes the internal signal, activity recording must degrade to the historical onData behavior — never to no tracking at all. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(1) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-interrupt-inference.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-interrupt-inference.spec.ts index aa34cbe098f..c05d48603c0 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-interrupt-inference.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-interrupt-inference.spec.ts @@ -65,8 +65,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { 'handles focused Ctrl+C for %s without guessing Codex cancellation', async (agentType) => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) vi.useFakeTimers() @@ -146,8 +147,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('clears stale working pane title after inferred interrupt applies', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { resolveWorktreeStatus } = await import('@/lib/worktree-status') vi.mocked(window.api.agentStatus.inferInterrupt).mockResolvedValue(true) const transport = createMockTransport() @@ -224,8 +226,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('clears unchanged title-only working indicators after acknowledged interrupt input', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) vi.useFakeTimers() @@ -278,8 +281,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('does not clear title-only working indicators when interrupt writes are unacknowledged', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() delete transport.sendInputAccepted transportFactoryQueue.push(transport) @@ -322,8 +326,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('infers exact Ctrl+C terminal input when keydown capture misses the press', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) vi.useFakeTimers() @@ -371,8 +376,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('marks bracketed paste as stale after acknowledged Ctrl+C input', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { pasteTerminalText } = await import('../../input/paste/terminal-bracketed-paste') const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -406,8 +412,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('infers captured Ctrl+C even when xterm emits an enhanced keyboard sequence', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) vi.useFakeTimers() @@ -459,8 +466,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('infers interrupt for an explicit working status even if the title is already non-agent', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) vi.useFakeTimers() @@ -522,8 +530,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('keeps inferred interrupted status after the pane settles on a non-agent title', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) vi.useFakeTimers() @@ -601,8 +610,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('does not infer exact interrupt input when the transport cannot acknowledge writes', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() delete transport.sendInputAccepted transportFactoryQueue.push(transport) @@ -644,8 +654,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('removes agent status and pane title on PTY exit after inferred interrupt', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.agentStatus.inferInterrupt).mockResolvedValue(true) const transport = createMockTransport('tab-pty') transportFactoryQueue.push(transport) @@ -717,8 +728,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { const restoreUserAgent = temporarilySetNavigatorUserAgent('Mozilla/5.0 (X11; Linux x86_64)') try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) vi.useFakeTimers() @@ -785,8 +797,9 @@ export function registerPtyConnectionInterruptInferenceTests(): void { it('removes the terminal key listener on dispose before a remount adds another', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const firstTransport = createMockTransport() const secondTransport = createMockTransport() transportFactoryQueue.push(firstTransport, secondTransport) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-native-query-reply-routing.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-native-query-reply-routing.spec.ts index c58059baa76..5f7f6893027 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-native-query-reply-routing.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-native-query-reply-routing.spec.ts @@ -65,8 +65,9 @@ export function registerPtyConnectionNativeQueryReplyRoutingTests(): void { it('answers cursor queries while an account notice blocks user input', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-live') transportFactoryQueue.push(transport) mockStoreState.codexRestartNoticeByPtyId = { @@ -91,8 +92,9 @@ export function registerPtyConnectionNativeQueryReplyRoutingTests(): void { it('routes native onData query replies through sendInputImmediate, typed input through sendInput (#7329)', async () => { // Why this test: the mock aliases sendInputImmediate to sendInput, so other tests can't tell them apart; this pins the routing decision. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const pane = createPane(1) const transport = createMockTransport('remote:web-env-1@@pty-7329') diff --git a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-remote-new-terminal-typeahead.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-remote-new-terminal-typeahead.test.ts index 5f78c935920..922f38eb12c 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-remote-new-terminal-typeahead.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-remote-new-terminal-typeahead.test.ts @@ -67,7 +67,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -139,7 +139,9 @@ async function connectNewRemotePane() { } }) const connectArgs = [pane, createManager(1), buildPaneConnectionDeps(() => mockStoreState)] - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) bindPaneAgentTitleMocks(connectArgs[2], agentTitleMocks) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-terminal-input-gating.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-terminal-input-gating.spec.ts index 8ae74df5e24..5a0e76b1955 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-terminal-input-gating.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-terminal-input-gating.spec.ts @@ -65,8 +65,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('restores input to a Codex pane whose restart notice the user dismissed', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-live') transportFactoryQueue.push(transport) @@ -106,8 +107,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('restores input through the tab fallback when the dismissed pane has no live PTY binding', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport(null) transportFactoryQueue.push(transport) @@ -146,8 +148,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('keeps a dismissed split pane typing while a sibling still holds the prompt', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-dismissed') transportFactoryQueue.push(transport) @@ -192,8 +195,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('keeps blocking a pane with its own unanswered notice next to a dismissed sibling', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-stale') transportFactoryQueue.push(transport) @@ -236,8 +240,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('keeps a bound pane with no notice typing while a sibling holds a queued restart', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-plain-shell') transportFactoryQueue.push(transport) @@ -284,8 +289,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('keeps blocking input on a pane whose restart is requested but not yet run', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-live') transportFactoryQueue.push(transport) @@ -325,8 +331,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('blocks input to stale Codex panes until they restart', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.useFakeTimers() vi.setSystemTime(1_100) @@ -388,8 +395,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('blocks terminal writes while mobile presence lock owns the PTY', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { setDriverForPty } = await import('@/lib/pane-manager/mobile-driver-state') vi.useFakeTimers() @@ -450,8 +458,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('drops xterm protocol replies from live TUI output while mobile presence lock is active', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { setDriverForPty } = await import('@/lib/pane-manager/mobile-driver-state') const ptyId = 'pty-mobile-tui-query' @@ -504,8 +513,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('blocks remote locked terminal input before it reaches the runtime transport', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { setDriverForPty } = await import('@/lib/pane-manager/mobile-driver-state') const ptyId = 'remote:env-1@@terminal-1' @@ -547,8 +557,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('does not infer interrupts when the transport rejects terminal input', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.useFakeTimers() vi.setSystemTime(1_100) @@ -596,8 +607,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('does not infer interrupts when the main process rejects acknowledged input', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks15 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.useFakeTimers() vi.setSystemTime(1_100) @@ -646,8 +658,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('requests a connected pane remount when main reports its daemon write unavailable', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks16 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks16 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { _resetTerminalPaneRecoveryForTests } = await import('../../render-health/recovery/terminal-pane-recovery') _resetTerminalPaneRecoveryForTests() @@ -679,8 +692,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('quarantines the interrupted line after a write-unavailable remount, but never device replies', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks17 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks17 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { _resetTerminalPaneRecoveryForTests } = await import('../../render-health/recovery/terminal-pane-recovery') _resetTerminalPaneRecoveryForTests() @@ -723,8 +737,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('recovers a wedged write pipeline after accepted input without renderer output', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks18 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks18 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { settleTerminalWriteStallWatch, WRITE_PIPELINE_STALL_CHECK_MS } = await import('@/lib/pane-manager/terminal-write-pipeline-health') const remountTerminalTabForRecovery = vi.fn(() => REMOUNTED) @@ -755,8 +770,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('does not arm the wedge probe when acknowledged input is rejected', async () => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks19 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks19 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { WRITE_PIPELINE_STALL_CHECK_MS } = await import('@/lib/pane-manager/terminal-write-pipeline-health') const transport = createMockTransport('pty-rejected') @@ -784,8 +800,9 @@ export function registerPtyConnectionTerminalInputGatingTests(): void { it('blocks input when tab-level ptyId is stale even if panePtyId is null', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks20 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks20 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport(null) transportFactoryQueue.push(transport) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-terminal-input-session-listing.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-terminal-input-session-listing.spec.ts index b310f3d3b7c..79342fc08e1 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-terminal-input-session-listing.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-terminal-input-session-listing.spec.ts @@ -61,8 +61,9 @@ export function registerPtyConnectionTerminalInputSessionListingTests(): void { typeKeystroke: (data?: string) => void }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks16 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks16 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-windows-focus-report-authority.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-windows-focus-report-authority.spec.ts index 32aa2aeb59a..4607564cbd8 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-windows-focus-report-authority.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/input/pty-connection-windows-focus-report-authority.spec.ts @@ -89,8 +89,9 @@ export function registerPtyConnectionRemoteWindowsFocusReportTests(): void { ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -170,8 +171,9 @@ export function registerPtyConnectionWindowsFocusReportAuthorityTests(): void { ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -245,8 +247,9 @@ export function registerPtyConnectionWindowsFocusReportAuthorityTests(): void { ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -291,8 +294,9 @@ export function registerPtyConnectionWindowsFocusReportAuthorityTests(): void { ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -364,8 +368,9 @@ export function registerPtyConnectionWindowsFocusReportAuthorityTests(): void { ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-deliberate-sleep-guard.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-deliberate-sleep-guard.spec.ts index f612b48a4d3..13972df30e6 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-deliberate-sleep-guard.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-deliberate-sleep-guard.spec.ts @@ -58,8 +58,9 @@ export function registerPtyConnectionDeliberateSleepGuardTests(): void { // Manual sleep retains tab.ptyId as a wake hint; unguarded remount would reattach and respawn its dead shell (#10205). it('does not reattach a slept pane through its retained session id', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { markWorktreeSleepIntent } = await import('@/lib/worktree-sleep-intent') const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -88,8 +89,9 @@ export function registerPtyConnectionDeliberateSleepGuardTests(): void { it('does not fresh-spawn a slept pane that has no session id', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { markWorktreeSleepIntent } = await import('@/lib/worktree-sleep-intent') const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -109,8 +111,9 @@ export function registerPtyConnectionDeliberateSleepGuardTests(): void { it('connects a waiting pane once the workspace is woken', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { clearWorktreeSleepIntent, markWorktreeSleepIntent } = await import('@/lib/worktree-sleep-intent') const transport = createMockTransport() @@ -144,8 +147,9 @@ export function registerPtyConnectionDeliberateSleepGuardTests(): void { it('does not connect a waiting pane whose tab was remounted by the wake', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { clearWorktreeSleepIntent, markWorktreeSleepIntent } = await import('@/lib/worktree-sleep-intent') const transport = createMockTransport() @@ -182,8 +186,9 @@ export function registerPtyConnectionDeliberateSleepGuardTests(): void { it('resumes a waiting pane mounted under a unified tab id', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { clearWorktreeSleepIntent, markWorktreeSleepIntent } = await import('@/lib/worktree-sleep-intent') const transport = createMockTransport() @@ -214,8 +219,9 @@ export function registerPtyConnectionDeliberateSleepGuardTests(): void { it('re-arms after a wake so a second sleep can hold the pane again', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { clearWorktreeSleepIntent, markWorktreeSleepIntent } = await import('@/lib/worktree-sleep-intent') const transport = createMockTransport() @@ -265,8 +271,9 @@ export function registerPtyConnectionDeliberateSleepGuardTests(): void { ) try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) sleepIntent.markWorktreeSleepIntent('wt-1') @@ -295,8 +302,9 @@ export function registerPtyConnectionDeliberateSleepGuardTests(): void { it('still connects a slept pane that carries a queued startup', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { markWorktreeSleepIntent } = await import('@/lib/worktree-sleep-intent') const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -319,8 +327,9 @@ export function registerPtyConnectionDeliberateSleepGuardTests(): void { it('connects normally once the marker is released', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const deps = createDeps({ diff --git a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-git-bash-console-capacity.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-git-bash-console-capacity.test.ts index 0f1b7bcdab0..749a7eec5de 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-git-bash-console-capacity.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-git-bash-console-capacity.test.ts @@ -80,7 +80,9 @@ async function startPane({ startup, cwdPromise }) - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) await connectMockPanePty(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks)) await flushAsyncTicks() @@ -134,7 +136,7 @@ async function heldLaunch({ install(session) captured.session = session }) - const readiness = await import('@/lib/agent-draft-readiness') + const readiness = await import('@/lib/agent-session/messaging/paste/agent-draft-readiness') vi.spyOn(readiness, 'waitForAgentDraftInputReady').mockReturnValue(new Promise(() => {})) const cwd = Promise.withResolvers() const key = makePaneKey('tab-1', createPane(1).leafId) @@ -235,7 +237,9 @@ async function heldLaunch({ }) } const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const binding = connectPanePty( typedPane, typedManager, @@ -405,7 +409,7 @@ describe('Git Bash console-capacity pane retention', () => { }) it('keeps a pre-connect input attempt with the first process while cwd is pending', async () => { - const readiness = await import('@/lib/agent-draft-readiness') + const readiness = await import('@/lib/agent-session/messaging/paste/agent-draft-readiness') vi.spyOn(readiness, 'waitForAgentDraftInputReady').mockReturnValue(new Promise(() => {})) const cwd = Promise.withResolvers() const started = await startPane({ startup: null, cwdPromise: cwd.promise }) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hibernation-kill-shell-foreground.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hibernation-kill-shell-foreground.test.ts index febf3c535a8..fe82eb9fb79 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hibernation-kill-shell-foreground.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hibernation-kill-shell-foreground.test.ts @@ -64,7 +64,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -155,7 +155,9 @@ describe('shell showing through a hibernation kill', () => { }> { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.mocked(window.api.pty.confirmForegroundProcess).mockResolvedValue('zsh') const dataCallbackRef: { current: ((data: string) => void) | null } = { current: null } const ptyId = 'pty-hibernating' diff --git a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hibernation-wake.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hibernation-wake.spec.ts index d875a7a9184..f60564c0352 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hibernation-wake.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hibernation-wake.spec.ts @@ -70,8 +70,9 @@ export function registerPtyConnectionHibernationWakeTests(): void { it('disarms input modes and resumes a hibernated agent session on visibility reveal', async () => { // Regression: hibernation suppresses its kill's PTY exit while hidden; before the wake fix onExit permanently latched handledExitPtyId, leaving a frozen inert ghost pane on reveal. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(1) @@ -154,8 +155,9 @@ export function registerPtyConnectionHibernationWakeTests(): void { // A suppressed exit over a finished turn’s live anchor still arms reveal resume despite its worktree-sleep note (#16308). it('arms an in-place resume from a finished turn idle anchor on a suppressed exit', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const deps = createDeps({ @@ -215,8 +217,9 @@ export function registerPtyConnectionHibernationWakeTests(): void { it('resumes a hibernated agent from a navigation-free wake without a visibility reveal', async () => { // Mobile wakes hidden panes without visibility changes; duplicate wake events must resume exactly once (INV-1). const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(1) @@ -295,8 +298,9 @@ export function registerPtyConnectionHibernationWakeTests(): void { it('names the replaced PTY on the restart spawn only, never on a later wake of the same pane', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-restarted') transportFactoryQueue.push(transport) const deps = createDeps({ @@ -375,8 +379,9 @@ export function registerPtyConnectionHibernationWakeTests(): void { it('keeps an established split pane mounted when main labels its exit as a restart replacement', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { deliverPtyExitToHandlers } = await import('../../pty-transport/delivery/pty-exit-delivery') let onData: ((data: string) => void) | undefined @@ -456,8 +461,9 @@ export function registerPtyConnectionHibernationWakeClaimTests(): void { it('latches a navigation-free wake that lands before the hibernation kill arms the pane', async () => { // Latch wake events between recording sleep and arming the kill’s PTY ID, or the frozen pane remains stranded (#7906). const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(1) @@ -525,8 +531,9 @@ export function registerPtyConnectionHibernationWakeClaimTests(): void { it('keeps an in-place provider claim until the replacement PTY spawn settles', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const deps = createDeps({ @@ -596,8 +603,9 @@ export function registerPtyConnectionHibernationWakeClaimTests(): void { it('re-arms the exact hibernation target after a replacement spawn fails', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const paneKey = `tab-1:${leafIdForPane(2)}` @@ -660,8 +668,9 @@ export function registerPtyConnectionHibernationWakeClaimTests(): void { it('does not latch a stale sleeping record beside an unsuppressed live PTY', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const paneKey = `tab-1:${leafIdForPane(2)}` @@ -695,8 +704,9 @@ export function registerPtyConnectionHibernationWakeClaimTests(): void { it('auto-resumes a hibernated pane when its kill lands after the pane is already revealed', async () => { // If reveal precedes wake arming, the arm-time visibility check must resume the pane immediately. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(1) @@ -766,8 +776,9 @@ export function registerPtyConnectionHibernationWakeClaimTests(): void { it('invalidates the hibernation wake when another flow rebinds the pane before reveal', async () => { // A hidden restart’s rebind permanently invalidates the old armed wake, including after a later PTY death. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(1) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hidden-sleeping-resume.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hidden-sleeping-resume.spec.ts index c12eff7bfe6..66217274299 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hidden-sleeping-resume.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-hidden-sleeping-resume.spec.ts @@ -174,7 +174,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { seedSleepingPane(null) const { transport, binding, isVisibleRef } = connectHiddenPane( null, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) @@ -198,7 +200,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { setHostLiveness(false) const { transport, binding, isVisibleRef } = connectHiddenPane( DEAD_SESSION_ID, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) @@ -227,7 +231,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { setHostLiveness(isLive) const { transport } = connectHiddenPane( DEAD_SESSION_ID, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) @@ -241,7 +247,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { requestSleepingAgentWakeOnMount('wt-1', ['tab-1']) const { transport } = connectHiddenPane( null, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) @@ -261,7 +269,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { requestSleepingAgentWakeOnMount('wt-1', ['tab-1']) connectHiddenPane( null, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(20) expect(resumeSleptPane).toHaveBeenCalledWith( @@ -275,7 +285,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { setHostLiveness(false) const { transport, binding } = connectHiddenPane( DEAD_SESSION_ID, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) expect(transport.connect).not.toHaveBeenCalled() @@ -294,7 +306,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { const { isPaneSpawnDeferred } = await import('@/lib/pane-spawn-deferral-registry') const { binding, isVisibleRef } = connectHiddenPane( null, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) expect(isPaneSpawnDeferred(PANE_KEY)).toBe(true) @@ -320,7 +334,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { restoredPtyIdByLeafId: { [LEAF_2]: DEAD_SESSION_ID }, isVisibleRef: { current: false } }), - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(20) @@ -338,7 +354,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { const spawn = createDeferred() const { transport, binding, isVisibleRef } = connectHiddenPane( null, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) transport.connect.mockImplementation(() => spawn.promise.then((ptyId) => { @@ -372,7 +390,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { consumeSuppressedPtyExit: vi.fn(() => true), isVisibleRef }), - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) isVisibleRef.current = true @@ -408,7 +428,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { seedSleepingPane(null) const { transport, binding, isVisibleRef } = connectHiddenPane( null, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) const held = mockStoreState.sleepingAgentSessionsByPaneKey[PANE_KEY]! @@ -429,7 +451,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { seedSleepingPane(null) const { transport, binding, isVisibleRef } = connectHiddenPane( null, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) const held = mockStoreState.sleepingAgentSessionsByPaneKey[PANE_KEY]! @@ -451,7 +475,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { const { isPaneSpawnDeferred } = await import('@/lib/pane-spawn-deferral-registry') const { transport, binding, isVisibleRef } = connectHiddenPane( DEAD_SESSION_ID, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) const fallback = createDeferred() @@ -479,7 +505,9 @@ export function registerPtyConnectionHiddenSleepingResumeTests(): void { const { isPaneSpawnDeferred } = await import('@/lib/pane-spawn-deferral-registry') connectHiddenPane( null, - await vi.importMock('@/lib/agent-status') + await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) ) await flushAsyncTicks(10) const onPtyExit = createdTransportOptions[0]?.onPtyExit diff --git a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-provider-rebind-callback-fencing.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-provider-rebind-callback-fencing.spec.ts index 3939f6a18d2..00a1bf01974 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-provider-rebind-callback-fencing.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-provider-rebind-callback-fencing.spec.ts @@ -59,8 +59,9 @@ export function registerPtyConnectionProviderRebindCallbackFencingTests(): void it('ignores a late spawn callback after the pane adopted a provider replacement', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks18 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks18 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) let transportPtyId = 'terminal-old' const transport = createMockTransport(transportPtyId) transport.getPtyId = vi.fn(() => transportPtyId) @@ -103,8 +104,9 @@ export function registerPtyConnectionProviderRebindCallbackFencingTests(): void it('ignores a late split-pane spawn callback when the tab identity belongs to pane one', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks19 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks19 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) let transportPtyId = 'terminal-old' const transport = createMockTransport(transportPtyId) transport.getPtyId = vi.fn(() => transportPtyId) @@ -159,8 +161,9 @@ export function registerPtyConnectionProviderRebindCallbackFencingTests(): void it('accepts a fresh spawn when the persisted pane still names the retired PTY', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks20 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks20 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) let transportPtyId = 'terminal-new' const transport = createMockTransport(transportPtyId) transport.getPtyId = vi.fn(() => transportPtyId) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-pty-exit-teardown.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-pty-exit-teardown.spec.ts index 7af644c2ef5..91e634dbf0b 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-pty-exit-teardown.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-pty-exit-teardown.spec.ts @@ -117,8 +117,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('keeps a fresh split pane mounted when its newborn PTY exits before output or input', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2, 2) @@ -169,8 +170,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('closes a hidden split pane whose PTY exits before output instead of keeping a ghost', async () => { // Hidden delivery withholds bytes, so no output cannot justify retaining an exited ghost pane. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2, 2) @@ -204,8 +206,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('keeps a worktree sole terminal mounted when its freshly-spawned PTY exits before input (direnv failure)', async () => { // Keep an unused shell mounted after startup failure so direnv errors do not close the tab and return to Landing. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transportFactoryQueue.push(transport) const manager = createManager(1) @@ -236,8 +239,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('keeps a worktree sole terminal mounted when only a captured shortcut preceded the exit', async () => { // Shortcut-driven redraw activity is not typed input; Shift+Enter must not turn startup failure into tab closure. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transportFactoryQueue.push(transport) const manager = createManager(1) @@ -265,8 +269,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('forwards a synthetic host-loss exit code to the tab-level handler', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transportFactoryQueue.push(transport) const manager = createManager(1) @@ -293,8 +298,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('keeps a mounted split pane binding across a synthetic host-loss exit', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -324,8 +330,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('tears down the sole terminal when a freshly-spawned PTY exits after the user typed input', async () => { // Why: an explicit `exit` (or any typed input) is a deliberate close, not a failed-startup shell, so the worktree should deactivate as before. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const transport = createMockTransport('tab-pty') transportFactoryQueue.push(transport) @@ -356,8 +363,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('tears down a failed local terminal after user input', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const transport = createMockTransport('tab-pty') transportFactoryQueue.push(transport) @@ -383,8 +391,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('does not claim a capacity overlay for a failed local split pane', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -410,8 +419,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const callbacks: ConnectCallbacks[] = [] const transport = createMockTransport('resume-pty') transport.connect.mockImplementation(async (options: { callbacks: ConnectCallbacks }) => { @@ -462,8 +472,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks15 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const callbacks: ConnectCallbacks[] = [] let currentPtyId = 'lost-pty' const transport = createMockTransport(currentPtyId) @@ -516,8 +527,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('tears down the sole terminal when a reattached (not freshly spawned) PTY exits', async () => { // Reattach skips onPtySpawn; the unused-new-shell guard must not retain a dead previously-live session. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks16 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks16 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transportFactoryQueue.push(transport) const manager = createManager(1) @@ -542,8 +554,9 @@ export function registerPtyConnectionPtyExitTeardownTests(): void { it('rebinds a provider replacement without granting fresh-spawn exit protection', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks17 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks17 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) let transportPtyId = 'terminal-old' const transport = createMockTransport(transportPtyId) transport.getPtyId = vi.fn(() => transportPtyId) @@ -623,8 +636,9 @@ export function registerPtyConnectionEstablishedPtyExitTests(): void { it('closes a split pane when an established PTY exits after output', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks21 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks21 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-pane-2') transport.connect.mockImplementation( @@ -663,8 +677,9 @@ export function registerPtyConnectionEstablishedPtyExitTests(): void { it('removes the agent row when an established PTY exits through EOF (#12907)', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks22 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks22 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -690,8 +705,9 @@ export function registerPtyConnectionEstablishedPtyExitTests(): void { it('closes a split pane when an established PTY exits after terminal input', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks23 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks23 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(2) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) @@ -728,8 +744,9 @@ export function registerPtyConnectionEstablishedPtyExitTests(): void { it('ignores a late exit from a transport that no longer owns the pane', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const oldTransport = createMockTransport('old-pty') const replacementTransport = createMockTransport('new-pty') transportFactoryQueue.push(oldTransport) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-pty-shutdown-exit-deferral.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-pty-shutdown-exit-deferral.spec.ts index 749d509a808..9bbc7f18c57 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-pty-shutdown-exit-deferral.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-pty-shutdown-exit-deferral.spec.ts @@ -22,7 +22,9 @@ export function registerPtyConnectionShutdownExitDeferralTests( ): void { it('keeps the surviving split pane mounted when an intentional pane-close PTY exit arrives', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') fixture.transportQueue.push(transport) const manager = createManager(1) @@ -53,7 +55,9 @@ export function registerPtyConnectionShutdownExitDeferralTests( it('defers all exit-side state mutation while worktree shutdown verification is pending', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { settleDeferredPtyShutdownExits } = await import('../../pty-transport/shutdown/pty-shutdown-exit-deferral') const transport = createMockTransport('pty-pane-2') @@ -92,7 +96,9 @@ export function registerPtyConnectionShutdownExitDeferralTests( it('keeps renderer state intact for an exit deferred through rollback', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { settleDeferredPtyShutdownExits } = await import('../../pty-transport/shutdown/pty-shutdown-exit-deferral') const transport = createMockTransport('pty-pane-2') @@ -127,7 +133,9 @@ export function registerPtyConnectionShutdownExitDeferralTests( it('preserves wake identifiers when exit arrives after a committed shutdown', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { markCommittedPtyShutdowns } = await import('../../pty-transport/shutdown/pty-shutdown-exit-deferral') const transport = createMockTransport('pty-pane-2') diff --git a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-session-liveness.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-session-liveness.spec.ts index 2981ea548b5..185dc08e2c1 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-session-liveness.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/lifecycle/pty-connection-session-liveness.spec.ts @@ -67,8 +67,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { describe('reconcileIfSessionMissing', () => { it('closes a split pane when targeted liveness says its local session is missing', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-pane-2') transport.connect.mockImplementation( @@ -104,8 +105,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('does not close when targeted liveness is live or unknown', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -132,8 +134,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('does not apply a stale targeted liveness result after reattach', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) let resolveHasPty: (value: boolean) => void = () => { throw new Error('hasPty promise resolver was not initialized') } @@ -170,8 +173,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('does NOT tear down a newborn pane when liveness was requested before it bound', async () => { // Liveness requested before binding cannot prove the fresh PTY dead. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-pane-2') transport.connect.mockImplementation( @@ -215,8 +219,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('tears down the pane when liveness was requested after it bound', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-pane-2') transport.connect.mockImplementation( @@ -262,8 +267,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('routes the last pane through onPtyExitRef when its session is dead', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-1') transportFactoryQueue.push(transport) const manager = createManager(1) @@ -288,8 +294,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('is a no-op for remote: web-runtime ids', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment('env-1') const transport = createMockTransport('remote:env-1:pane-2') transport.getConnectionId.mockReturnValue(null) @@ -317,8 +324,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('is a no-op for SSH/non-local ids (non-null connectionId)', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transport.getConnectionId.mockReturnValue('ssh-target-1') transportFactoryQueue.push(transport) @@ -345,8 +353,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('respects suppression: a suppressed dead session keeps the pane mounted', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-pane-2') transportFactoryQueue.push(transport) const manager = createManager(2) @@ -375,8 +384,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('still closes the replacement PTY after a suppressed restart rebinds the pane', async () => { // Scope exit guards by PTY ID so a rebound replacement’s later exit still tears down. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-pane-2') transport.connect.mockImplementation( @@ -426,8 +436,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('closes a split pane exactly once across reconcile + a racing real exit', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-pane-2') transport.connect.mockImplementation( @@ -472,8 +483,9 @@ export function registerPtyConnectionSessionLivenessTests(): void { it('closes a genuinely-dead non-suppressed pane once (not misread as suppressed)', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-pane-2') transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-hook-completion-side-effects.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-hook-completion-side-effects.spec.ts index c9842a1bc74..c1df505f42f 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-hook-completion-side-effects.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-hook-completion-side-effects.spec.ts @@ -80,8 +80,9 @@ export function registerPtyConnectionHookCompletionSideEffectsTests(): void { // The completion settings subscription is shared per module load. await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-hook') transportFactoryQueue.push(transport) enableActiveRuntimeEnvironment() @@ -188,8 +189,9 @@ export function registerPtyConnectionHookCompletionSideEffectsTests(): void { ) await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-crashed-codex') transportFactoryQueue.push(transport) vi.useFakeTimers() @@ -282,8 +284,9 @@ export function registerPtyConnectionHookCompletionSideEffectsTests(): void { it('drops an exited agent completion when a replacement agent hook row is active', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-replaced-codex') transportFactoryQueue.push(transport) vi.useFakeTimers() @@ -355,8 +358,9 @@ export function registerPtyConnectionHookCompletionSideEffectsTests(): void { const { dispatchAgentHookTerminalLifecycle } = await import('../../agent-completion/agent-hook-terminal-lifecycle') const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-replaced-codex') transportFactoryQueue.push(transport) vi.useFakeTimers() diff --git a/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-hook-idle-arbitration.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-hook-idle-arbitration.test.ts index f9c77639cbe..9612737f831 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-hook-idle-arbitration.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-hook-idle-arbitration.test.ts @@ -65,7 +65,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -150,7 +150,9 @@ describe('connectPanePty', () => { it('dispatches agent-task-complete on working→idle and raises tab/worktree unread', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { useNotificationDispatch } = await vi.importActual( '../../notifications/use-notification-dispatch' ) @@ -240,7 +242,9 @@ describe('connectPanePty', () => { it('ignores title-only idle while fresh hook status is still working', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const paneKey = makePaneKey('tab-1', LEAF_1) @@ -286,7 +290,9 @@ describe('connectPanePty', () => { { title: '✳ Claude Code', completion: true } ])('requires replacement identity over a fresh hook: $title', async ({ title, completion }) => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) vi.useFakeTimers() @@ -345,7 +351,9 @@ describe('connectPanePty', () => { it('ignores an explicit idle title while fresh hook identity is unknown', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const paneKey = makePaneKey('tab-1', LEAF_1) @@ -388,7 +396,9 @@ describe('connectPanePty', () => { it('ignores a Pi idle title while compatible OMP hook status is active', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const paneKey = makePaneKey('tab-1', LEAF_1) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-notification-settings-gating.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-notification-settings-gating.spec.ts index 079130b0947..e6aeac4846a 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-notification-settings-gating.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-notification-settings-gating.spec.ts @@ -68,8 +68,9 @@ export function registerPtyConnectionNotificationSettingsGatingTests(): void { it('lets concurrent agent-complete notifications win over terminal bell notifications', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { useNotificationDispatch } = await vi.importActual< typeof UseNotificationDispatchModule >('../../notifications/use-notification-dispatch') @@ -127,8 +128,9 @@ export function registerPtyConnectionNotificationSettingsGatingTests(): void { it('keeps an in-flight generic completion when desktop completion banners are enabled', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-codex') transportFactoryQueue.push(transport) @@ -198,8 +200,9 @@ export function registerPtyConnectionNotificationSettingsGatingTests(): void { it('restores a suppressed terminal bell when disabling pending agent completion', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-codex') transportFactoryQueue.push(transport) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-task-complete-dispatch.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-task-complete-dispatch.spec.ts index 09c14093eaf..e88eef8c7b3 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-task-complete-dispatch.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/notifications/pty-connection-task-complete-dispatch.spec.ts @@ -61,8 +61,9 @@ export function registerPtyConnectionTaskCompleteDispatchTests(): void { it('does not dispatch generic spinner completions when process inspection finds no agent', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-shell') transportFactoryQueue.push(transport) @@ -101,8 +102,9 @@ export function registerPtyConnectionTaskCompleteDispatchTests(): void { it('queues the idle cursor reset behind hidden agent output', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -142,8 +144,9 @@ export function registerPtyConnectionTaskCompleteDispatchTests(): void { it('does not use stale agent status from an earlier turn in task-complete notifications', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { useNotificationDispatch } = await vi.importActual< typeof UseNotificationDispatchModule >('../../notifications/use-notification-dispatch') diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/direct-ssh-hidden-output-restore-unavailable-banner.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/direct-ssh-hidden-output-restore-unavailable-banner.test.ts index 48fa382871e..6a5c7e67d33 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/direct-ssh-hidden-output-restore-unavailable-banner.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/direct-ssh-hidden-output-restore-unavailable-banner.test.ts @@ -48,7 +48,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -144,7 +144,9 @@ function stubMainBufferSnapshot( async function connectHiddenDirectSshPane(): Promise { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport(SSH_PTY_ID) const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/hidden-query-carry-osc-introducer-leak.repro.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/hidden-query-carry-osc-introducer-leak.repro.test.ts index cd662e91b6a..08ae80193ab 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/hidden-query-carry-osc-introducer-leak.repro.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/hidden-query-carry-osc-introducer-leak.repro.test.ts @@ -63,7 +63,9 @@ describe('hidden query carry vs a following OSC', () => { it('does not paint an OSC payload after the reveal restore when a hidden chunk ended mid-CSI', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const dataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-backlog-reconciliation.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-backlog-reconciliation.spec.ts index b7898e0094e..7e06273e42c 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-backlog-reconciliation.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-backlog-reconciliation.spec.ts @@ -73,8 +73,9 @@ export function registerPtyConnectionHiddenBacklogReconciliationTests(): void { binding: { syncProcessTracking: () => void; dispose: () => void } }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-backlog-snapshot.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-backlog-snapshot.test.ts index 599993bd510..9e2bd77fd64 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-backlog-snapshot.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-backlog-snapshot.test.ts @@ -78,7 +78,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -161,7 +161,9 @@ describe('connectPanePty', () => { // Use a real alt-screen pane so a stubbed normal-buffer check cannot pass without emitting the missing ?1049l reset. it('emits the alt-screen unstick when the pane is on alt and the model is not', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -213,7 +215,9 @@ describe('connectPanePty', () => { // Why: pins the switch-off hidden fallback chain — 2MB lossy cap drops the backlog, latches restore, and reveal repaints from the model snapshot. it('restores hidden backlog overflow from the main terminal snapshot on foreground output', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -267,7 +271,9 @@ describe('connectPanePty', () => { it('rebuilds normal and alternate buffers from an authoritative alternate snapshot', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -342,7 +348,9 @@ describe('connectPanePty', () => { it('keeps a hidden-output alt frame at the capture grid below the fit floor', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') let onData: ConnectCallbacks['onData'] transport.connect.mockImplementation(async ({ callbacks }: { callbacks: ConnectCallbacks }) => { @@ -404,7 +412,9 @@ describe('connectPanePty', () => { it('drains foreground output after a renderer-sourced hidden-backlog snapshot without seq', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -456,7 +466,9 @@ describe('connectPanePty', () => { it('slices abandoned pending chunks against a replay that already painted', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-delivery-gate.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-delivery-gate.spec.ts index 7c055aee351..67cf40344a0 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-delivery-gate.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-delivery-gate.spec.ts @@ -80,8 +80,9 @@ export function registerPtyConnectionHiddenDeliveryGateTests(): void { binding: { syncProcessTracking: () => void; dispose: () => void } }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-output-restore.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-output-restore.spec.ts index 710a04b98ea..a80fd6f8a27 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-output-restore.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-output-restore.spec.ts @@ -77,8 +77,9 @@ export function registerPtyConnectionHiddenOutputRestoreTests(): void { } as unknown as Document const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: @@ -174,8 +175,9 @@ export function registerPtyConnectionHiddenOutputRestoreTests(): void { it('restores hidden Codex output after a suppressed exit revives the same ptyId with a restarted seq counter', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: @@ -276,8 +278,9 @@ export function registerPtyConnectionHiddenOutputRestoreTests(): void { it('restores hidden Codex output when the pty seq counter restarts without an observed exit', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: @@ -355,8 +358,9 @@ export function registerPtyConnectionHiddenOutputRestoreTests(): void { it('writes ordinary hidden output live instead of proactively restoring a snapshot', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -409,8 +413,9 @@ export function registerPtyConnectionHiddenOutputRestoreTests(): void { it('pauses capable paired output while hidden and restores exactly on reveal', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const remotePtyId = 'remote:env-1@@terminal-1' const transport = createMockTransport(remotePtyId) let callbacks: ConnectCallbacks = {} @@ -554,8 +559,9 @@ export function registerPtyConnectionHiddenOutputRestoreTests(): void { it('locally gates hidden paired output when a legacy host cannot pause it', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const remotePtyId = 'remote:legacy-env@@terminal-1' const transport = createMockTransport(remotePtyId) let callbacks: ConnectCallbacks = {} diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-query-snapshot-authority.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-query-snapshot-authority.spec.ts index 23d3cba40cf..89222c2c16f 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-query-snapshot-authority.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-query-snapshot-authority.spec.ts @@ -64,8 +64,9 @@ export function registerPtyConnectionHiddenQuerySnapshotAuthorityTests(): void { it('keeps split hidden-to-visible Codex stateful queries behind snapshot restore', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -120,8 +121,9 @@ export function registerPtyConnectionHiddenQuerySnapshotAuthorityTests(): void { it('preserves live agent cursor and focus modes on hidden-to-visible snapshot restore', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -197,8 +199,9 @@ export function registerPtyConnectionHiddenQuerySnapshotAuthorityTests(): void { it('lets fresh host shell proof outrank stale live-agent metadata on reveal', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -265,8 +268,9 @@ export function registerPtyConnectionHiddenQuerySnapshotAuthorityTests(): void { it('preserves current behavior when a snapshot has no host ownership proof', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -329,8 +333,9 @@ export function registerPtyConnectionHiddenQuerySnapshotAuthorityTests(): void { it('keeps a live alternate-screen pane interactive when a legacy snapshot omits its mode flag', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -389,8 +394,9 @@ export function registerPtyConnectionHiddenQuerySnapshotAuthorityTests(): void { it('grounds a stale alternate-screen snapshot when the host proves shell ownership', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-fit-overflow.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-fit-overflow.test.ts index 3666589ab65..5d9fa2bfc9a 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-fit-overflow.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-fit-overflow.test.ts @@ -66,7 +66,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -171,8 +171,9 @@ describe('connectPanePty', () => { 'recovers $name live output when the deadline interrupts an answered snapshot', async ({ name, pending, repaint, covered }) => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') let onData: ConnectCallbacks['onData'] transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-loss-disclosure.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-loss-disclosure.test.ts index a06040a4936..9b8cb6d1a7a 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-loss-disclosure.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-loss-disclosure.test.ts @@ -69,7 +69,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -191,7 +191,9 @@ async function connectHiddenPane( const deps = buildPaneConnectionDeps(() => mockStoreState, { isVisibleRef: { current: false } }) - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const disposable = await connectMockPanePty( pane, @@ -523,8 +525,9 @@ describe('hidden-output restore loss disclosure (STA-4869)', () => { isVisibleRef: { current: false }, startup: { command: 'codex' } }) - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const disposable = await connectMockPanePty( pane, diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-marker-handoff.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-marker-handoff.test.ts index 987669ca6cc..255e6c52abb 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-marker-handoff.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-restore-marker-handoff.test.ts @@ -63,7 +63,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -225,7 +225,9 @@ async function connectPane(visible: boolean): Promise { const deps = buildPaneConnectionDeps(() => mockStoreState, { isVisibleRef: { current: visible } }) - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const binding = await connectMockPanePty( pane, diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-runtime-snapshot.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-runtime-snapshot.test.ts index 0c998a4b8c4..61d02388f2e 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-runtime-snapshot.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-runtime-snapshot.test.ts @@ -75,7 +75,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -157,7 +157,9 @@ describe('connectPanePty', () => { it('restores overflowed hidden remote runtime output from its serialized snapshot', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('remote:env-1@@terminal-1') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -217,7 +219,9 @@ describe('connectPanePty', () => { it('preserves the painted normal buffer when a successful hidden restore has no image', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('remote:env-1@@terminal-1') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-snapshot-live-overlap.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-snapshot-live-overlap.spec.ts index ca71b2a24f8..4120dd69407 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-snapshot-live-overlap.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-snapshot-live-overlap.spec.ts @@ -55,8 +55,9 @@ export function registerPtyConnectionHiddenSnapshotLiveOverlapTests(): void { it('writes foreground chunks that are newer than the restored main snapshot', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -110,8 +111,9 @@ export function registerPtyConnectionHiddenSnapshotLiveOverlapTests(): void { it('writes only the live chunk suffix not covered by the restored main snapshot', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -169,8 +171,9 @@ export function registerPtyConnectionHiddenSnapshotLiveOverlapTests(): void { it('re-snapshots instead of duplicating partially overlapped chunks with stripped OSC bytes', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-snapshot-resize-signals.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-snapshot-resize-signals.spec.ts index d49c6ac331f..f6288555994 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-snapshot-resize-signals.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-hidden-snapshot-resize-signals.spec.ts @@ -78,8 +78,9 @@ export function registerPtyConnectionHiddenSnapshotResizeSignalsTests(): void { } as unknown as Document const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -171,8 +172,9 @@ export function registerPtyConnectionHiddenSnapshotResizeSignalsTests(): void { it('does not signal SIGWINCH after hidden-backlog snapshot replay when dimensions are unchanged', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -227,8 +229,9 @@ export function registerPtyConnectionHiddenSnapshotResizeSignalsTests(): void { it('writes a background-origin alternate-screen repaint that arrives after the reveal restore', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.useFakeTimers({ toFake: [ 'setTimeout', @@ -321,8 +324,9 @@ export function registerPtyConnectionHiddenSnapshotResizeSignalsTests(): void { it('re-restores a skipped alt frame from the model when the fit lands back on the capture grid', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.useFakeTimers({ toFake: [ 'setTimeout', @@ -399,8 +403,9 @@ export function registerPtyConnectionHiddenSnapshotResizeSignalsTests(): void { it('restores a dropped daemon alt frame from the model when the fit lands back on the capture grid', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => sessionId diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-post-dispose-restore-termination.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-post-dispose-restore-termination.test.ts index 6fd629f2b36..300e74cc669 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-post-dispose-restore-termination.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-post-dispose-restore-termination.test.ts @@ -49,7 +49,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -94,7 +94,9 @@ describe('connectPanePty', () => { // Disposed restore tasks must not re-arm from finally: instant exits otherwise create an unbounded promise chain that exhausts the heap. it('stops re-arming the hidden output restore once the pane binding is disposed', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-remote-pause-drop-notice.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-remote-pause-drop-notice.spec.ts index 61bb9964124..36bbbbe7929 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-remote-pause-drop-notice.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-remote-pause-drop-notice.spec.ts @@ -53,8 +53,9 @@ export function registerPtyConnectionRemotePauseDropNoticeTests(): void { async function connectRemotePane(dropsReported: boolean) { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const remotePtyId = 'remote:env-1@@terminal-1' const transport = createMockTransport(remotePtyId) const callbacks: { current: ConnectCallbacks } = { current: {} } diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-replay-payload-handling.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-replay-payload-handling.spec.ts index 94df5711e4f..892c4db0ddb 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-replay-payload-handling.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-replay-payload-handling.spec.ts @@ -85,8 +85,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { it('preserves a scrolled-up viewport after hidden-backlog snapshot replay', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -146,8 +147,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { it('cancels a delayed snapshot scroll restore when the pane binding is disposed', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { isTerminalScrollIntentRebuildInFlight } = await import('@/lib/pane-manager/terminal-scroll-intent-rebuild') const transport = createMockTransport('pty-id') @@ -212,8 +214,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { it('does not apply a delayed snapshot restore after newer user intent', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { markTerminalFollowOutput } = await import('@/lib/pane-manager/terminal-scroll-intent') const transport = createMockTransport('pty-id') const capturedDataCallback: { @@ -275,8 +278,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { it('rebuilds WebGL after remote buffered replay arrives on an already-open pane', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const transport = createMockTransport('remote:env-1@@terminal-1') const capturedReplayCallback: { @@ -338,8 +342,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { const manager = createManager(1) const deps = createDeps() const disposable = await withMockedDocumentActiveElement(textarea, async () => { - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const connection = connectPanePty( pane as never, @@ -384,8 +389,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { const manager = createManager(1) const deps = createDeps() const disposable = await withMockedDocumentActiveElement(textarea, async () => { - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const connection = connectPanePty( pane as never, @@ -431,8 +437,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { const manager = createManager(1) const deps = createDeps() const disposable = await withMockedDocumentActiveElement(textarea, async () => { - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const connection = connectPanePty( pane as never, @@ -479,8 +486,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { const manager = createManager(1) const deps = createDeps() const disposable = await withMockedDocumentActiveElement(textarea, async () => { - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const connection = connectPanePty( pane as never, @@ -509,8 +517,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { it('does not clear restored scrollback when eager metadata replay opts out', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedReplayCallback: { current: ((data: string, meta?: { clearBeforeReplay?: boolean }) => void) | null @@ -552,8 +561,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { it('does not write a clear or reset for empty eager metadata replay', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedReplayCallback: { current: ((data: string, meta?: { clearBeforeReplay?: boolean }) => void) | null @@ -588,8 +598,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { it('coalesces remote replay payloads that overlap before parsing starts', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const transport = createMockTransport('remote:env-1@@terminal-1') const capturedReplayCallback: { @@ -643,8 +654,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { it('holds newer live bytes until a later replay frame has fully parsed', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { deliverTerminalDataWithDeferredCredit } = await import('@/lib/pane-manager/terminal-delivery-credit') enableActiveRuntimeEnvironment() @@ -707,8 +719,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { it('drops a queued relay replay instead of retagging it for a replacement PTY', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const transport = createMockTransport('remote:env-1@@terminal-old') const replayCallback: { current: ((data: string) => void) | null } = { current: null } @@ -745,8 +758,9 @@ export function registerPtyConnectionReplayPayloadHandlingTests(): void { it('requests snapshot recovery for one oversized live frame deferred by replay', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { deliverTerminalDataWithDeferredCredit } = await import('@/lib/pane-manager/terminal-delivery-credit') const transport = createMockTransport('pty-large-live') diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-restored-baseline-shortfall.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-restored-baseline-shortfall.test.ts index a93de97c9c4..98086ad58b6 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-restored-baseline-shortfall.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-restored-baseline-shortfall.test.ts @@ -58,7 +58,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -153,7 +153,9 @@ describe('restored snapshot baseline shortfall (STA-5179)', () => { terminalMainSideEffectAuthority: true } as StoreState['settings'] const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-stalled-hidden-restore.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-stalled-hidden-restore.spec.ts index 57502b90265..e6ebf41d056 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-stalled-hidden-restore.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-stalled-hidden-restore.spec.ts @@ -64,8 +64,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { it('abandons a stalled hidden restore with reset, warning, then pending foreground', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -157,8 +158,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { // A dropped span can swallow bold reset; abandonment must ground the pen when no snapshot will restore it (STA-4042). it('clears the SGR pen before draining abandoned foreground chunks', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -217,8 +219,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { it('grounds byte-gap state before a remote restore re-arms', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const remotePtyId = 'remote:env-1@@terminal-rearm' const transport = createMockTransport(remotePtyId) const capturedDataCallback: { @@ -271,8 +274,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { it('falls back after repeated null hidden restore retries and drains blocked foreground', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -337,8 +341,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { it('drops pending foreground overflow when a stalled hidden restore falls back', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -395,8 +400,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { it('coalesces tiny pending foreground chunks when stalled hidden restore falls back', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -507,8 +513,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { let disposable: { dispose: () => void } | null = null try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -578,8 +585,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { it('keeps a newer same-PTY hidden restore after a timed-out snapshot resolves late', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -686,8 +694,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { it('ignores an async hidden-backlog snapshot if the pane changes PTYs first', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('old-pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -746,8 +755,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { it('does not recover stale hidden backlog state after the pane switches PTYs', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('old-pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null @@ -802,8 +812,9 @@ export function registerPtyConnectionStalledHiddenRestoreTests(): void { // The serializer subscribes to window.api once per module load. await loadFreshTerminalModules() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { seq?: number; rawLength?: number }) => void) | null diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-visible-pane-output-pause-latch.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-visible-pane-output-pause-latch.test.ts index f5e14dbc6be..1d9d1c8edba 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-visible-pane-output-pause-latch.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/pty-connection-visible-pane-output-pause-latch.test.ts @@ -46,7 +46,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -108,7 +108,9 @@ async function connectVisibleRemotePane(): Promise<{ pauseCalls: () => boolean[] }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport(REMOTE_PTY_ID) transport.setOutputPaused = vi.fn(() => true) transport.serializeBuffer = vi.fn() diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/remote-park-reveal-unverifiable-retry.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/remote-park-reveal-unverifiable-retry.test.ts index 05158a5dea5..ae7ce1a6c4e 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output-restore/remote-park-reveal-unverifiable-retry.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output-restore/remote-park-reveal-unverifiable-retry.test.ts @@ -69,7 +69,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -163,7 +163,9 @@ async function revealParkedRemotePane( } const pane = createPane(1) const { writes } = captureCallbackTerminalWrites(pane) - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) // Why the active pane: an inactive split defers its restore to the frame scheduler. const binding = await connectMockPanePty( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output/pty-connection-foreground-write-path.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output/pty-connection-foreground-write-path.spec.ts index fc171b25900..e0192924160 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output/pty-connection-foreground-write-path.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output/pty-connection-foreground-write-path.spec.ts @@ -60,8 +60,9 @@ export function registerPtyConnectionForegroundBulkAndInteractiveOutputTests(): it('queues visible bulk output off the synchronous xterm write path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const transport = createMockTransport('pty-1') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } @@ -93,8 +94,9 @@ export function registerPtyConnectionForegroundBulkAndInteractiveOutputTests(): it('keeps ANSI redraws after terminal input on the immediate xterm write path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const transport = createMockTransport('pty-1') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } @@ -129,8 +131,9 @@ export function registerPtyConnectionForegroundBulkAndInteractiveOutputTests(): it('keeps large ANSI redraws after terminal input on the immediate xterm write path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const transport = createMockTransport('pty-1') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } @@ -201,8 +204,9 @@ export function registerPtyConnectionForegroundFrameSchedulingTests(): void { it('keeps large ANSI redraws after captured shortcut input on the immediate path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const transport = createMockTransport('pty-1') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } @@ -233,8 +237,9 @@ export function registerPtyConnectionForegroundFrameSchedulingTests(): void { it('does not let OpenTUI-style small ANSI redraw bursts monopolize foreground writes', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const transport = createMockTransport('pty-1') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } @@ -287,8 +292,9 @@ export function registerPtyConnectionForegroundFrameSchedulingTests(): void { await loadFreshTerminalModules() try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -340,8 +346,9 @@ export function registerPtyConnectionForegroundFrameSchedulingTests(): void { await loadFreshTerminalModules() try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -391,8 +398,9 @@ export function registerPtyConnectionForegroundFrameSchedulingTests(): void { await loadFreshTerminalModules() try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -442,8 +450,9 @@ export function registerPtyConnectionForegroundFrameSchedulingTests(): void { await loadFreshTerminalModules() try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -502,8 +511,9 @@ export function registerPtyConnectionForegroundFrameSchedulingTests(): void { await loadFreshTerminalModules() try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/output/pty-connection-hidden-output-scheduling.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/output/pty-connection-hidden-output-scheduling.spec.ts index 0b6e3dfb0e7..202ccea87fa 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/output/pty-connection-hidden-output-scheduling.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/output/pty-connection-hidden-output-scheduling.spec.ts @@ -68,8 +68,9 @@ export function registerPtyConnectionHiddenOutputSchedulingTests(): void { it('keeps hidden synchronized output off the global atlas recovery path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -121,8 +122,9 @@ export function registerPtyConnectionHiddenOutputSchedulingTests(): void { it('keeps split hidden synchronized output off the global atlas recovery path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -170,8 +172,9 @@ export function registerPtyConnectionHiddenOutputSchedulingTests(): void { it('does not schedule hidden atlas recovery for ordinary rich text or metadata output', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -217,8 +220,9 @@ export function registerPtyConnectionHiddenOutputSchedulingTests(): void { it('keeps hidden TUI redraw output off the global atlas recovery path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -261,8 +265,9 @@ export function registerPtyConnectionHiddenOutputSchedulingTests(): void { it('keeps hidden rewrite frames on the pane-local output path', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -313,8 +318,9 @@ export function registerPtyConnectionHiddenOutputSchedulingTests(): void { it('keeps a background-origin alternate-screen chunk in the stream, pane-local', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string, meta?: { background?: boolean }) => void) | null @@ -373,8 +379,9 @@ export function registerPtyConnectionHiddenOutputSchedulingTests(): void { it('queues visible split-pane PTY bytes when the pane is not active', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -409,8 +416,9 @@ export function registerPtyConnectionHiddenOutputSchedulingTests(): void { it('queues visible ANSI redraws when only another split pane is active', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -451,8 +459,9 @@ export function registerPtyConnectionHiddenOutputSchedulingTests(): void { visibilityState: 'hidden' } const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-agent-session-resume.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-agent-session-resume.spec.ts index 6b765c044d0..b8a07584357 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-agent-session-resume.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-agent-session-resume.spec.ts @@ -69,8 +69,9 @@ export function registerPtyConnectionSleepingRecordResumeTests(): void { it('uses sleeping-record launch config for pane cold restore after settings change', async () => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -218,8 +219,9 @@ export function registerPtyConnectionLiveResumeIdentityTests(): void { it('prefers live-entry launch config for pane cold restore when status survived PTY loss', async () => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -311,8 +313,9 @@ export function registerPtyConnectionLiveResumeIdentityTests(): void { async (kind) => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const retainedPtyId = 'wt-1@@lost-pty' const transport = createMockTransport() transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => @@ -401,8 +404,9 @@ export function registerPtyConnectionLiveResumeIdentityTests(): void { it('ignores stale live launch config when cold restore identity lookup rejects it', async () => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -512,8 +516,9 @@ export function registerPtyConnectionLiveResumeIdentityTests(): void { it('shows the restored banner when a sleeping resume falls back to a fresh shell', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const staleSessionId = 'wt-1@@stale-session' const transport = createMockTransport() transport.connect.mockImplementation(async (opts: { sessionId?: string }) => { diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-agent-resume.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-agent-resume.spec.ts index 6be0d7e8804..4b4f0d23fbd 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-agent-resume.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-agent-resume.spec.ts @@ -68,8 +68,9 @@ export function registerPtyConnectionColdRestoreAgentResumeTests(): void { it('resumes the provider agent session when daemon reattach cold-restores a fresh shell', async () => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -162,8 +163,9 @@ export function registerPtyConnectionColdRestoreAgentResumeTests(): void { it('uses WSL quoting for cold-restored agent resume in Windows-path WSL projects', async () => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -260,8 +262,9 @@ export function registerPtyConnectionColdRestoreAgentResumeTests(): void { it('resumes the same agent after consecutive daemon losses before another status arrives', async () => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -396,8 +399,9 @@ export function registerPtyConnectionColdRestoreAgentResumeTests(): void { it('marks the pane as freshly started when main declined an unverifiable resume', async () => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -475,8 +479,9 @@ export function registerPtyConnectionColdRestoreAgentResumeTests(): void { it('resumes from an unambiguous legacy sleeping record when cold-restoring a preserved pane', async () => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -575,8 +580,9 @@ export function registerPtyConnectionColdRestoreAgentResumeTests(): void { it('does not choose a non-exact legacy record when same-tab provider sessions differ', async () => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-repaint.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-repaint.spec.ts index f774071bd02..f1053261fda 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-repaint.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-repaint.spec.ts @@ -70,8 +70,9 @@ export function registerPtyConnectionColdRestoreRepaintTests(): void { }) it('paints only the daemon snapshot when reattach result includes both snapshot and replay', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -116,8 +117,9 @@ export function registerPtyConnectionColdRestoreRepaintTests(): void { it('paints only relay replay when reattach result has replay and coldRestore but no snapshot', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -169,8 +171,9 @@ export function registerPtyConnectionColdRestoreRepaintTests(): void { it('blanks restored scrollback before fresh shell output', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') const written: string[] = [] transport.connect.mockImplementation( @@ -230,8 +233,9 @@ export function registerPtyConnectionColdRestoreRepaintTests(): void { it('cold-restores at the recovered grid and clears only the dirty viewport before blanking', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('fresh-pty') const written: string[] = [] const operations: ( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-resume-command.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-resume-command.spec.ts index eca4181b98e..3deb14afb0e 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-resume-command.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-cold-restore-resume-command.spec.ts @@ -76,8 +76,9 @@ export function registerPtyConnectionColdRestoreResumeCommandTests(): void { try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const paneKey = makePaneKey('tab-1', LEAF_2) let activePtyId: string | null = 'restored-session' const transport = createMockTransport('restored-session') @@ -203,8 +204,9 @@ export function registerPtyConnectionColdRestoreResumeCommandTests(): void { try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const paneKey = makePaneKey('tab-1', LEAF_2) let activePtyId: string | null = 'restored-session' const transport = createMockTransport('restored-session') @@ -317,8 +319,9 @@ export function registerPtyConnectionColdRestoreResumeCommandTests(): void { state: 'working' | 'done' ): Promise { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const paneKey = makePaneKey('tab-1', LEAF_2) const transport = createMockTransport('restored-session') transport.connect.mockResolvedValue({ @@ -375,8 +378,9 @@ export function registerPtyConnectionColdRestoreResumeCommandTests(): void { it('keeps a contentless reattach when a live status supersedes passive sleep evidence', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const paneKey = makePaneKey('tab-1', LEAF_2) const transport = createMockTransport('restored-session') transport.connect.mockResolvedValue({ diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-daemon-snapshot-replay.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-daemon-snapshot-replay.spec.ts index 51ba9a09bc6..2a5abf5ae40 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-daemon-snapshot-replay.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-daemon-snapshot-replay.spec.ts @@ -1,3 +1,4 @@ +import { registerStaleDaemonSnapshotReplayTests } from './pty-connection-stale-daemon-snapshot-replay.spec' import { bindPtyConnectionTestMocks } from '../test-fixtures/pty-connection-mocks.spec' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { @@ -9,11 +10,7 @@ import { } from '../../../../../../shared/terminal/protocol/input-modes/terminal-mode-reset-profiles' import { replayEpilogue } from '../test-fixtures/pty-connection-test-replay-epilogue' import { Terminal } from '@xterm/headless' -import { - flushAsyncTicks, - createDeferred, - writeHeadlessTerminal -} from '../test-fixtures/pty-connection-test-async' +import { flushAsyncTicks, writeHeadlessTerminal } from '../test-fixtures/pty-connection-test-async' import { createRect } from '../test-fixtures/pty-connection-test-dom' import { LEAF_1, @@ -71,7 +68,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('clears the captured pen for a normal-buffer fallback reattach', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') const snapshot = 'ORCA-SGR-REPRO \x1b[1mBOLD-RUN-LEFT-OPEN\x1b[1;34H' transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { @@ -145,7 +144,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('returns a shell-owned daemon snapshot to the normal buffer on reattach', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => sessionId @@ -186,7 +187,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('drops a too-wide daemon alt frame and keeps the scrollback prefix', async () => { // Why: fixed-grid alt rows clip at a narrower viewport until the owner repaints. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -232,7 +235,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('keeps a daemon alt frame at its capture grid while the target grid is unknown', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => sessionId @@ -278,7 +283,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('falls back to the merged daemon snapshot when split metadata is incomplete', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => sessionId @@ -321,7 +328,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('keeps a daemon alt frame when the pane is not narrower than the capture', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -366,7 +375,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('drops a too-wide daemon alt frame on cold restore and keeps its history', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -416,7 +427,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('resizes the pane to the snapshot grid before replaying daemon snapshot bytes (bug #7279)', async () => { // Why: the daemon serializes soft-wrapped lines flat, so reattach must resize xterm to the snapshot grid before writing, or rows rewrap wrong. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -471,7 +484,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('waits for a recovered destination fit before forwarding its grid or live output', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { safeFit } = await import('@/lib/pane-manager/pane-tree-ops') const transport = createMockTransport('tab-pty') let deliverLiveData = (_data: string): void => {} @@ -537,7 +552,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('forwards the destination grid on reveal when the reattach fit was deferred by a display:none pane', async () => { // Hidden floating panels cannot fit during replay; deferred fit must restore the client grid and signal SIGWINCH before reveal reflows a live TUI. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { safeFit } = await import('@/lib/pane-manager/pane-tree-ops') const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => @@ -593,7 +610,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('suppresses the deferred reattach grid push when mobile claims the PTY while hidden', async () => { // Recheck mobile takeover after the hidden pane gains a box; direct transport.resize bypasses the usual suppression. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { safeFit } = await import('@/lib/pane-manager/pane-tree-ops') const { setFitOverride } = await import('@/lib/pane-manager/mobile-fit-overrides') const transport = createMockTransport('tab-pty') @@ -656,7 +675,9 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { it('restores a pinned viewport only after a same-size reattach snapshot finishes parsing', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { markTerminalFollowOutput, markTerminalPinnedViewport } = await import('@/lib/pane-manager/terminal-scroll-intent') const transport = createMockTransport('tab-pty') @@ -706,160 +727,6 @@ export function registerPtyConnectionDaemonSnapshotReplayTests(): void { markTerminalFollowOutput(pane.terminal) }) - it('does not apply a queued reattach snapshot after the PTY is replaced', async () => { - const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = await vi.importMock('@/lib/agent-status') - const transport = createMockTransport('tab-pty') - const reattachResult = createDeferred<{ - id: string - snapshot: string - }>() - const replayCallback: { current: ((data: string) => void) | null } = { current: null } - transport.connect.mockImplementation( - async ({ sessionId, callbacks }: { sessionId?: string; callbacks?: ConnectCallbacks }) => { - if (!sessionId) { - return null - } - replayCallback.current = callbacks?.onReplayData ?? null - return reattachResult.promise - } - ) - transportFactoryQueue.push(transport) - const pane = createPane(1) - const { writes, parseCallbacks } = captureCallbackTerminalWrites(pane) - const deps = createDeps({ - restoredLeafId: LEAF_1, - restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } - }) - - connectPanePty( - pane as never, - createManager(1) as never, - bindPaneAgentTitleMocks(deps as never, agentTitleMocks13) - ) - await flushAsyncTicks(8) - replayCallback.current?.('blocking replay') - await flushAsyncTicks(12) - expect(writes).toEqual(['\x1b[?2026l\x1b[2J\x1b[3J\x1b[H']) - reattachResult.resolve({ id: 'tab-pty', snapshot: 'stale authoritative snapshot' }) - await flushAsyncTicks(12) - const resizeCallsBeforeReplacement = transport.resize.mock.calls.length - vi.mocked(transport.getPtyId).mockReturnValue('replacement-pty') - while (parseCallbacks.length > 0) { - parseCallbacks.shift()?.() - await flushAsyncTicks(4) - } - await flushAsyncTicks(12) - - expect(writes).not.toContain('stale authoritative snapshot') - expect(transport.resize).toHaveBeenCalledTimes(resizeCallsBeforeReplacement) - expect(window.api.pty.signal).not.toHaveBeenCalledWith('tab-pty', 'SIGWINCH') - }) - - it('does not apply a queued reattach snapshot after its PTY exits', async () => { - const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = await vi.importMock('@/lib/agent-status') - const transport = createMockTransport('tab-pty') - const reattachResult = createDeferred<{ id: string; snapshot: string }>() - const replayCallback: { current: ((data: string) => void) | null } = { current: null } - transport.connect.mockImplementation( - async ({ callbacks }: { callbacks?: ConnectCallbacks }) => { - replayCallback.current = callbacks?.onReplayData ?? null - return reattachResult.promise - } - ) - transportFactoryQueue.push(transport) - const pane = createPane(1) - const { writes, parseCallbacks } = captureCallbackTerminalWrites(pane) - const deps = createDeps({ - restoredLeafId: LEAF_1, - restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } - }) - - connectPanePty( - pane as never, - createManager(1) as never, - bindPaneAgentTitleMocks(deps as never, agentTitleMocks14) - ) - await flushAsyncTicks(8) - replayCallback.current?.('blocking replay') - await flushAsyncTicks(12) - reattachResult.resolve({ id: 'tab-pty', snapshot: 'dead authoritative snapshot' }) - await flushAsyncTicks(12) - const resizeCallsBeforeExit = transport.resize.mock.calls.length - vi.mocked(transport.getPtyId).mockReturnValue(null) - while (parseCallbacks.length > 0) { - parseCallbacks.shift()?.() - await flushAsyncTicks(4) - } - await flushAsyncTicks(12) - - expect(writes).not.toContain('dead authoritative snapshot') - expect(transport.resize).toHaveBeenCalledTimes(resizeCallsBeforeExit) - expect(window.api.pty.signal).not.toHaveBeenCalledWith('tab-pty', 'SIGWINCH') - expect(transport.sendInput).not.toHaveBeenCalledWith('\x1b[I') - }) - - it('drops stale callbacks but delivers fresh replacement output after an old replay clear', async () => { - const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks15 = await vi.importMock('@/lib/agent-status') - const { getTerminalScrollIntentKind, markTerminalPinnedViewport } = - await import('@/lib/pane-manager/terminal-scroll-intent') - const transport = createMockTransport('tab-pty') - const oldResult = createDeferred() - const oldCallbacks: { current: ConnectCallbacks | null } = { current: null } - const replacementCallbacks: { current: ConnectCallbacks | null } = { current: null } - let connectCount = 0 - transport.connect.mockImplementation( - async ({ callbacks }: { sessionId?: string; callbacks?: ConnectCallbacks }) => { - connectCount += 1 - if (connectCount === 1) { - oldCallbacks.current = callbacks ?? null - return oldResult.promise - } - vi.mocked(transport.getPtyId).mockReturnValue('replacement-pty') - replacementCallbacks.current = callbacks ?? null - return 'replacement-pty' - } - ) - transportFactoryQueue.push(transport) - const pane = createPane(1) - pane.terminal.buffer.active.viewportY = 80 - pane.terminal.buffer.active.baseY = 100 - markTerminalPinnedViewport(pane.terminal) - const { writes, parseCallbacks } = captureCallbackTerminalWrites(pane) - const deps = createDeps({ - restoredLeafId: LEAF_1, - restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } - }) - - connectPanePty( - pane as never, - createManager(1) as never, - bindPaneAgentTitleMocks(deps as never, agentTitleMocks15) - ) - await flushAsyncTicks(8) - oldCallbacks.current?.onReplayData?.('old replay') - await flushAsyncTicks(8) - parseCallbacks.shift()?.() - await flushAsyncTicks(8) - oldCallbacks.current?.onError?.('SSH_SESSION_EXPIRED: tab-pty') - oldResult.resolve(undefined) - await flushAsyncTicks(20) - expect(replacementCallbacks.current).not.toBeNull() - - replacementCallbacks.current?.onData?.('B-PROMPT') - oldCallbacks.current?.onData?.('STALE-A') - while (parseCallbacks.length > 0) { - parseCallbacks.shift()?.() - await flushAsyncTicks(4) - } - await flushAsyncTicks(20) - - expect(writes).toContain('B-PROMPT') - expect(writes).not.toContain('STALE-A') - expect(pane.terminal.scrollToBottom).toHaveBeenCalled() - expect(getTerminalScrollIntentKind(pane.terminal)).toBe('followOutput') - }) + registerStaleDaemonSnapshotReplayTests(() => ({ transportFactoryQueue, createDeps })) }) } diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-deferred-reattach-live-output.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-deferred-reattach-live-output.spec.ts index 5a09893a2d5..dbe0b241d49 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-deferred-reattach-live-output.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-deferred-reattach-live-output.spec.ts @@ -60,8 +60,9 @@ export function registerPtyConnectionDeferredReattachLiveOutputTests(): void { it('does not consume the sleeping record when daemon reattach returns a live snapshot', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -109,8 +110,9 @@ export function registerPtyConnectionDeferredReattachLiveOutputTests(): void { it('does not resume the provider session when daemon reattach returns a live snapshot', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -163,8 +165,9 @@ export function registerPtyConnectionDeferredReattachLiveOutputTests(): void { 'preserves output while reconciling $kind on daemon adoption', async ({ snapshot, seq, count }) => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation( async ({ @@ -204,8 +207,9 @@ export function registerPtyConnectionDeferredReattachLiveOutputTests(): void { it('drains live bytes after transport confirms an explicit reattach', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { deliverTerminalDataWithDeferredCredit } = await import('@/lib/pane-manager/terminal-delivery-credit') const transport = createMockTransport('tab-pty') @@ -253,8 +257,9 @@ export function registerPtyConnectionDeferredReattachLiveOutputTests(): void { it('re-enforces follow intent after deferred reattach live output parses', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { markTerminalFollowOutput } = await import('@/lib/pane-manager/terminal-scroll-intent') const transport = createMockTransport('tab-pty') transport.connect.mockImplementation( @@ -306,8 +311,9 @@ export function registerPtyConnectionDeferredReattachLiveOutputTests(): void { it('does not steal a newer user pin while deferred reattach output settles', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { markTerminalFollowOutput, markTerminalPinnedViewport } = await import('@/lib/pane-manager/terminal-scroll-intent') const transport = createMockTransport('tab-pty') @@ -368,8 +374,9 @@ export function registerPtyConnectionDeferredReattachLiveOutputTests(): void { it('does not enforce a deferred viewport after the pane becomes hidden', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { markTerminalFollowOutput } = await import('@/lib/pane-manager/terminal-scroll-intent') const transport = createMockTransport('tab-pty') transport.connect.mockImplementation( @@ -429,8 +436,9 @@ export function registerPtyConnectionDeferredReattachLiveOutputTests(): void { it('does not fresh-spawn after a dead deferred session delivers its buffered exit', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation( async ({ sessionId, callbacks }: { sessionId?: string; callbacks?: ConnectCallbacks }) => { @@ -464,8 +472,9 @@ export function registerPtyConnectionDeferredReattachLiveOutputTests(): void { // All hidden chunks use the background scheduler without content scanning. it('queues hidden PTY bytes on the background scheduler without per-chunk scanning', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-id') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-owner-error-retry.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-owner-error-retry.spec.ts index e80c92caa79..8d16e068006 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-owner-error-retry.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-owner-error-retry.spec.ts @@ -76,8 +76,9 @@ export function registerPtyConnectionOwnerErrorRetryTests(): void { it('preserves an owner-unverified restored pane after an empty reattach result', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transport.connect.mockImplementation(async (opts: { callbacks?: ConnectCallbacks }) => { opts.callbacks?.onError?.('terminal_pane_owner_unverified') @@ -109,8 +110,9 @@ export function registerPtyConnectionOwnerErrorRetryTests(): void { it('preserves an owner-unverified restored pane after a rejected reattach', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transport.connect.mockRejectedValueOnce(new Error('terminal_pane_owner_unverified')) transportFactoryQueue.push(transport) @@ -139,8 +141,9 @@ export function registerPtyConnectionOwnerErrorRetryTests(): void { 'preserves an exhausted pane until explicit Retry and clears only the current owner error (fresh: %s)', async (fresh) => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks15 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transport.connect.mockImplementation(async (opts: { callbacks?: ConnectCallbacks }) => { opts.callbacks?.onError?.('terminal_pane_owner_changed') diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-park-reveal-model-snapshot.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-park-reveal-model-snapshot.spec.ts index 6442071e376..0996bf17556 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-park-reveal-model-snapshot.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-park-reveal-model-snapshot.spec.ts @@ -57,8 +57,9 @@ export function registerPtyConnectionParkRevealModelSnapshotTests(): void { it('keeps a parked main-model alt frame at its capture grid while hidden', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const localPtyId = 'global-floating-terminal@@terminal-1' const transport = createMockTransport(localPtyId) transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-reattach-binding.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-reattach-binding.test.ts index f5122ed7493..5231037c633 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-reattach-binding.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-reattach-binding.test.ts @@ -77,7 +77,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -161,7 +161,9 @@ describe('connectPanePty', () => { it('reattaches a remounted split pane to its restored leaf PTY instead of the tab-level PTY', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) mockStoreState = { @@ -196,7 +198,9 @@ describe('connectPanePty', () => { it('publishes async layout bindings by the pane leaf, not a remapped numeric id', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const syncPanePtyLayoutBindingForLeaf = vi.fn() @@ -219,7 +223,9 @@ describe('connectPanePty', () => { it('does not publish a stale layout callback after a successor transport takes the pane slot', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const reattach = createDeferred<{ id: string; isReattach: true }>() const staleTransport = createMockTransport('terminal-old') staleTransport.connect.mockImplementation(async () => reattach.promise) @@ -251,7 +257,9 @@ describe('connectPanePty', () => { it('does not clear a successor pane error from a stale stream callback', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const staleTransport = createMockTransport('terminal-old') let callbacks: ConnectCallbacks | undefined staleTransport.connect.mockImplementation(async (options) => { @@ -282,7 +290,9 @@ describe('connectPanePty', () => { it('does not clear a successor pane error when a stale binding is disposed', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const staleTransport = createMockTransport('terminal-old') transportFactoryQueue.push(staleTransport) const paneTransportsRef = { current: new Map() } @@ -307,7 +317,9 @@ describe('connectPanePty', () => { it('does not spend queued startup from a stale spawn callback', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const staleTransport = createMockTransport() transportFactoryQueue.push(staleTransport) const paneTransportsRef = { current: new Map() } @@ -333,7 +345,9 @@ describe('connectPanePty', () => { it('resizes a reattached PTY to the current grid when the pane narrows before reattach resolves', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const reattach = createDeferred() let currentPtyId: string | null = null const transport = createMockTransport() @@ -382,7 +396,9 @@ describe('connectPanePty', () => { it('does not let a stale pane transport publish a completed reattach', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const reattach = createDeferred<{ id: string; isReattach: true }>() const staleTransport = createMockTransport() let stalePtyId: string | null = 'terminal-old' @@ -424,7 +440,9 @@ describe('connectPanePty', () => { it('accepts an explicit reattach id before the transport publishes its id', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const reattach = createDeferred<{ id: string; isReattach: true }>() const transport = createMockTransport() let transportPtyId: string | null = null @@ -454,8 +472,9 @@ describe('connectPanePty', () => { it('does not replace a split sibling with the tab-level source PTY', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) // A split spawn can report reattach while the source pane remains mounted and this leaf has no stale session ID. const sourceTransport = createMockTransport('tab-pty') const splitTransport = createMockTransport('split-pty') @@ -505,8 +524,9 @@ describe('connectPanePty', () => { it('infers a replacement when the tab PTY is bound to this leaf', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const splitTransport = createMockTransport('replacement-pty') splitTransport.connect.mockResolvedValue({ id: 'replacement-pty', isReattach: true }) transportFactoryQueue.push(splitTransport) @@ -550,8 +570,9 @@ describe('connectPanePty', () => { 'does not let a stale pane transport clear ownership on %s', async (_label, result) => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const reattach = createDeferred< { id: string; isReattach: true; sessionExpired?: boolean } | undefined >() @@ -601,8 +622,9 @@ describe('connectPanePty', () => { ptyId === eagerPtyId ? { flush: () => '', dispose: () => {} } : undefined ) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) mockStoreState = { @@ -662,8 +684,9 @@ describe('connectPanePty', () => { ptyId === otherTabPtyId ? { flush: () => '', dispose: () => {} } : undefined ) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transport.connect.mockImplementation(async (opts: { sessionId?: string }) => { if (opts.sessionId) { @@ -709,8 +732,9 @@ describe('connectPanePty', () => { it('fresh-spawns a shell into any PTY-less tab, so agent launches must never publish one', async () => { // Why: #2989 depends on PTY-less tabs taking this legitimate fresh-shell path. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks15 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transport.connect.mockImplementation(async (opts: { sessionId?: string }) => { if (opts.sessionId) { @@ -761,8 +785,9 @@ describe('connectPanePty', () => { it('spawns a fresh PTY when a restored daemon split session cannot reattach', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks16 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks16 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transport.connect.mockImplementation(async (opts: { sessionId?: string }) => { if (opts.sessionId) { diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-reattach-mode-reset.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-reattach-mode-reset.spec.ts index 75ea9226cb3..72aa77c68cb 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-reattach-mode-reset.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-reattach-mode-reset.spec.ts @@ -88,8 +88,9 @@ export function registerPtyConnectionDaemonPendingEscapeTailTests(): void { it('writes the daemon pendingEscapeTailAnsi after the reset on local reattach (#7329)', async () => { // Why: re-arm the mid-escape tail LAST, after the reattach reset whose ESC would abort it, so a live continuation completes it. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -179,8 +180,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { it('writes the onReplayData pendingEscapeTailAnsi meta last, after the replayed bytes (#7329)', async () => { // Why this test: the onReplayData meta pass-through had no failing test — severing it kept the suite green. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment() const pane = createPane(1) const writes: string[] = [] @@ -249,8 +251,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { restoredLeafId: LEAF_1, restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } }) - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) connectPanePty( ...mockPanePtyArgs(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks6)) @@ -272,8 +275,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { it('lets fresh host shell proof outrank stale live-agent metadata on reattach', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => { if (sessionId) { @@ -343,8 +347,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { restoredLeafId: LEAF_1, restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } }) - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) connectPanePty( ...mockPanePtyArgs(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks8)) @@ -408,8 +413,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { bind: bindsPaneInStore(() => mockStoreState, 'tab-1', LEAF_1) }) } - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) connectPanePty( ...mockPanePtyArgs(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks9)) @@ -466,8 +472,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { restoredLeafId: LEAF_1, restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } }) - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) connectPanePty( ...mockPanePtyArgs(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks10)) @@ -503,8 +510,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { restoredLeafId: LEAF_1, restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } }) - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) connectPanePty( ...mockPanePtyArgs(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks11)) @@ -543,8 +551,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { restoredLeafId: LEAF_1, restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } }) - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) connectPanePty( ...mockPanePtyArgs(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks12)) @@ -582,8 +591,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { restoredLeafId: LEAF_1, restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } }) - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) connectPanePty( ...mockPanePtyArgs(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks13)) @@ -636,8 +646,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { restoredLeafId: LEAF_1, restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } }) - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) connectPanePty( ...mockPanePtyArgs(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks14)) @@ -678,8 +689,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { restoredLeafId: LEAF_1, restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } }) - const agentTitleMocks15 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) connectPanePty( ...mockPanePtyArgs(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks15)) @@ -723,8 +735,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { restoredLeafId: LEAF_1, restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } }) - const agentTitleMocks16 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks16 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) connectPanePty( ...mockPanePtyArgs(pane, manager, bindPaneAgentTitleMocks(deps, agentTitleMocks16)) @@ -745,8 +758,9 @@ export function registerPtyConnectionReattachModeResetTests(): void { it('resets an already-idle agent cursor again after reattach SIGWINCH repaint', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks17 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks17 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) vi.useFakeTimers({ toFake: [ 'setTimeout', diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-remote-runtime-attach.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-remote-runtime-attach.spec.ts index 098d1e7d1e4..82bcfff3a14 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-remote-runtime-attach.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-remote-runtime-attach.spec.ts @@ -66,8 +66,9 @@ export function registerPtyConnectionRemoteRuntimeAttachTests(): void { it('reattaches via daemon sessionId when an in-session PTY is live', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -101,8 +102,9 @@ export function registerPtyConnectionRemoteRuntimeAttachTests(): void { it('attaches remote runtime PTY handles instead of creating a replacement terminal', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transport.attach.mockImplementation(({ callbacks }: { callbacks?: ConnectCallbacks }) => { transport.getPtyId.mockReturnValue('remote:env-1@@terminal-1') @@ -151,8 +153,9 @@ export function registerPtyConnectionRemoteRuntimeAttachTests(): void { it('reports remote renderer readiness only after delayed restore output is parsed', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() let remoteCallbacks: ConnectCallbacks | undefined transport.attach.mockImplementation(({ callbacks }: { callbacks?: ConnectCallbacks }) => { @@ -204,8 +207,9 @@ export function registerPtyConnectionRemoteRuntimeAttachTests(): void { it('cold-spawns slept remote runtime PTYs instead of reattaching the preserved handle', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) enableActiveRuntimeEnvironment('env-1') const restoredPtyId = 'remote:env-1@@terminal-1' const freshPtyId = 'remote:env-1@@terminal-2' diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-remote-snapshot-image-title.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-remote-snapshot-image-title.test.ts index f13c386ebde..f93b6b67fc3 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-remote-snapshot-image-title.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-remote-snapshot-image-title.test.ts @@ -68,7 +68,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -144,7 +144,9 @@ async function connectRemotePane(): Promise<{ dispose: () => void }> { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) mockStoreState = buildActiveRuntimeEnvironmentState(mockStoreState, 'env-1') const transport = createMockTransport('remote:env-1@@terminal-1') const captured: { current: ConnectCallbacks['onReplayData'] | null } = { current: null } diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-restored-runtime-pane-binding.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-restored-runtime-pane-binding.spec.ts index 3d524e53ac0..489befe2c9f 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-restored-runtime-pane-binding.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-restored-runtime-pane-binding.spec.ts @@ -55,8 +55,9 @@ export function registerPtyConnectionRestoredRuntimePaneBindingTests(): void { it('attaches restored remote PTYs for later split panes instead of spawning host tabs', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const existingTransport = createMockTransport('remote:env-1@@terminal-1') const transport = createMockTransport() transportFactoryQueue.push(transport) @@ -98,8 +99,9 @@ export function registerPtyConnectionRestoredRuntimePaneBindingTests(): void { it('publishes a restarted pane PTY id and reuses its restored hint on remount', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const restartedTransport = createMockTransport() let spawnedPtyId: string | null = null diff --git a/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-stale-daemon-snapshot-replay.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-stale-daemon-snapshot-replay.spec.ts new file mode 100644 index 00000000000..f746f753d96 --- /dev/null +++ b/src/renderer/src/components/terminal-pane/pty-connection/reattach/pty-connection-stale-daemon-snapshot-replay.spec.ts @@ -0,0 +1,188 @@ +import { expect, it, vi } from 'vitest' +import { flushAsyncTicks, createDeferred } from '../test-fixtures/pty-connection-test-async' +import { + LEAF_1, + createMockTransport, + createPane, + captureCallbackTerminalWrites, + createManager, + type ConnectCallbacks, + type MockTransport +} from '../test-fixtures/pty-connection-test-pane-fixtures' +import { + type PtyConnectionAgentTitleMocks as AgentTitleMocks, + bindPaneAgentTitleMocks, + type buildPaneConnectionDeps +} from '../test-fixtures/pty-connection-test-deps' + +export function registerStaleDaemonSnapshotReplayTests( + getContext: () => { + transportFactoryQueue: MockTransport[] + createDeps: (overrides?: Record) => ReturnType + } +): void { + it('does not apply a queued reattach snapshot after the PTY is replaced', async () => { + const { transportFactoryQueue, createDeps } = getContext() + const { connectPanePty } = await import('../connect-pane-pty') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) + const transport = createMockTransport('tab-pty') + const reattachResult = createDeferred<{ + id: string + snapshot: string + }>() + const replayCallback: { current: ((data: string) => void) | null } = { current: null } + transport.connect.mockImplementation( + async ({ sessionId, callbacks }: { sessionId?: string; callbacks?: ConnectCallbacks }) => { + if (!sessionId) { + return null + } + replayCallback.current = callbacks?.onReplayData ?? null + return reattachResult.promise + } + ) + transportFactoryQueue.push(transport) + const pane = createPane(1) + const { writes, parseCallbacks } = captureCallbackTerminalWrites(pane) + const deps = createDeps({ + restoredLeafId: LEAF_1, + restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } + }) + + connectPanePty( + pane as never, + createManager(1) as never, + bindPaneAgentTitleMocks(deps as never, agentTitleMocks13) + ) + await flushAsyncTicks(8) + replayCallback.current?.('blocking replay') + await flushAsyncTicks(12) + expect(writes).toEqual(['\x1b[?2026l\x1b[2J\x1b[3J\x1b[H']) + reattachResult.resolve({ id: 'tab-pty', snapshot: 'stale authoritative snapshot' }) + await flushAsyncTicks(12) + const resizeCallsBeforeReplacement = transport.resize.mock.calls.length + vi.mocked(transport.getPtyId).mockReturnValue('replacement-pty') + while (parseCallbacks.length > 0) { + parseCallbacks.shift()?.() + await flushAsyncTicks(4) + } + await flushAsyncTicks(12) + + expect(writes).not.toContain('stale authoritative snapshot') + expect(transport.resize).toHaveBeenCalledTimes(resizeCallsBeforeReplacement) + expect(window.api.pty.signal).not.toHaveBeenCalledWith('tab-pty', 'SIGWINCH') + }) + + it('does not apply a queued reattach snapshot after its PTY exits', async () => { + const { transportFactoryQueue, createDeps } = getContext() + const { connectPanePty } = await import('../connect-pane-pty') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) + const transport = createMockTransport('tab-pty') + const reattachResult = createDeferred<{ id: string; snapshot: string }>() + const replayCallback: { current: ((data: string) => void) | null } = { current: null } + transport.connect.mockImplementation( + async ({ callbacks }: { callbacks?: ConnectCallbacks }) => { + replayCallback.current = callbacks?.onReplayData ?? null + return reattachResult.promise + } + ) + transportFactoryQueue.push(transport) + const pane = createPane(1) + const { writes, parseCallbacks } = captureCallbackTerminalWrites(pane) + const deps = createDeps({ + restoredLeafId: LEAF_1, + restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } + }) + + connectPanePty( + pane as never, + createManager(1) as never, + bindPaneAgentTitleMocks(deps as never, agentTitleMocks14) + ) + await flushAsyncTicks(8) + replayCallback.current?.('blocking replay') + await flushAsyncTicks(12) + reattachResult.resolve({ id: 'tab-pty', snapshot: 'dead authoritative snapshot' }) + await flushAsyncTicks(12) + const resizeCallsBeforeExit = transport.resize.mock.calls.length + vi.mocked(transport.getPtyId).mockReturnValue(null) + while (parseCallbacks.length > 0) { + parseCallbacks.shift()?.() + await flushAsyncTicks(4) + } + await flushAsyncTicks(12) + + expect(writes).not.toContain('dead authoritative snapshot') + expect(transport.resize).toHaveBeenCalledTimes(resizeCallsBeforeExit) + expect(window.api.pty.signal).not.toHaveBeenCalledWith('tab-pty', 'SIGWINCH') + expect(transport.sendInput).not.toHaveBeenCalledWith('\x1b[I') + }) + + it('drops stale callbacks but delivers fresh replacement output after an old replay clear', async () => { + const { transportFactoryQueue, createDeps } = getContext() + const { connectPanePty } = await import('../connect-pane-pty') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) + const { getTerminalScrollIntentKind, markTerminalPinnedViewport } = + await import('@/lib/pane-manager/terminal-scroll-intent') + const transport = createMockTransport('tab-pty') + const oldResult = createDeferred() + const oldCallbacks: { current: ConnectCallbacks | null } = { current: null } + const replacementCallbacks: { current: ConnectCallbacks | null } = { current: null } + let connectCount = 0 + transport.connect.mockImplementation( + async ({ callbacks }: { sessionId?: string; callbacks?: ConnectCallbacks }) => { + connectCount += 1 + if (connectCount === 1) { + oldCallbacks.current = callbacks ?? null + return oldResult.promise + } + vi.mocked(transport.getPtyId).mockReturnValue('replacement-pty') + replacementCallbacks.current = callbacks ?? null + return 'replacement-pty' + } + ) + transportFactoryQueue.push(transport) + const pane = createPane(1) + pane.terminal.buffer.active.viewportY = 80 + pane.terminal.buffer.active.baseY = 100 + markTerminalPinnedViewport(pane.terminal) + const { writes, parseCallbacks } = captureCallbackTerminalWrites(pane) + const deps = createDeps({ + restoredLeafId: LEAF_1, + restoredPtyIdByLeafId: { [LEAF_1]: 'tab-pty' } + }) + + connectPanePty( + pane as never, + createManager(1) as never, + bindPaneAgentTitleMocks(deps as never, agentTitleMocks15) + ) + await flushAsyncTicks(8) + oldCallbacks.current?.onReplayData?.('old replay') + await flushAsyncTicks(8) + parseCallbacks.shift()?.() + await flushAsyncTicks(8) + oldCallbacks.current?.onError?.('SSH_SESSION_EXPIRED: tab-pty') + oldResult.resolve(undefined) + await flushAsyncTicks(20) + expect(replacementCallbacks.current).not.toBeNull() + + replacementCallbacks.current?.onData?.('B-PROMPT') + oldCallbacks.current?.onData?.('STALE-A') + while (parseCallbacks.length > 0) { + parseCallbacks.shift()?.() + await flushAsyncTicks(4) + } + await flushAsyncTicks(20) + + expect(writes).toContain('B-PROMPT') + expect(writes).not.toContain('STALE-A') + expect(pane.terminal.scrollToBottom).toHaveBeenCalled() + expect(getTerminalScrollIntentKind(pane.terminal)).toBe('followOutput') + }) +} diff --git a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-fresh-spawn-guards.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-fresh-spawn-guards.spec.ts index 7c97a1767d7..f049cc73115 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-fresh-spawn-guards.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-fresh-spawn-guards.spec.ts @@ -57,8 +57,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('does not surface the zero-dimensions diagnostic for a hidden pane', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const pane = createPane(1) @@ -78,8 +79,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('still surfaces the zero-dimensions diagnostic for a visible pane', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const pane = createPane(1) @@ -103,8 +105,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { // Do not race PTY respawn into worktree deletion; main’s removal fence must not flash a raw error before unmount. it('skips a fresh spawn while the pane worktree is being deleted', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) mockStoreState = { @@ -128,8 +131,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { // A queued row may still fail its own delete and stay; a new terminal there must still start. it('still spawns while the pane worktree is only queued for deletion', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) mockStoreState = { @@ -151,8 +155,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { // Read the live store before retiring a disposed spawn, or a remounted pane’s shell could be killed. it('lets a disposed spawn survive while the pane surface still exists in the store', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const deps = createDeps({ tabId: 'tab-retain-disposed-spawn' }) @@ -193,8 +198,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('carries the pane placement onto its transport', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) transportFactoryQueue.push(createMockTransport()) const placement = { kind: 'new-tab' } as const const deps = createDeps({ tabId: 'tab-placement', placement }) @@ -211,8 +217,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('fresh-spawns normally when the pane worktree is not being deleted', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) // Use a unique tab ID to force fresh spawn, matching the skip control. @@ -231,8 +238,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { // A racing spawn, including under a removing parent worktree, must swallow main’s removal fence instead of flashing its raw banner. it('swallows a worktree-removal fence error instead of surfacing it', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { TERMINAL_REMOVAL_IN_PROGRESS_MESSAGE } = await import('../../../../../../shared/worktree/removal-fence-error') const transport = createMockTransport() @@ -264,8 +272,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('still surfaces non-fence spawn errors through the pane error sink', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedOnError: { current: ((message: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -291,8 +300,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('threads the resolved local project runtime into IPC terminal transport options', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) mockStoreState = { @@ -327,8 +337,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('keeps an explicit host fallback out of the project runtime', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks11 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks11 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) mockStoreState = { @@ -354,8 +365,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('spawns a Floating agent on native Windows beside an active WSL project', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks12 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks12 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { createIpcPtyTransport } = await import('../../pty-transport/ipc/pty-transport') const { createRemoteRuntimePtyTransport } = await import('../../pty-transport/remote-runtime/remote-runtime-pty-transport') @@ -408,8 +420,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('observes live terminal GitHub PR URLs before agent completion', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks13 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks13 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -442,8 +455,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('surfaces an actionable error when a Codex backfill timeout drops to the shell', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks14 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks14 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } transport.connect.mockImplementation( @@ -476,8 +490,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('drops keystrokes while the replay guard is engaged, then forwards once it releases', async () => { // A stuck replay guard caused reconnect input lockout; verify suppression while armed and forwarding after release. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks15 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks15 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const transport = createMockTransport('ssh:ssh-1@@pty-1') transportFactoryQueue.push(transport) @@ -502,8 +517,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('preserves classified user input during replay while suppressing synthetic replies', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks16 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks16 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const userInputListeners = new Set<() => void>() Object.assign(pane.terminal, { @@ -584,8 +600,9 @@ export function registerPtyConnectionFreshSpawnGuardsTests(): void { it('settles a queued startup only after the pane binds its spawned PTY', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks17 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks17 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-resume') transportFactoryQueue.push(transport) const onStartupBound = vi.fn() diff --git a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-main-pane-restore-start.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-main-pane-restore-start.test.ts index 6862e23c33b..aa451e1ea3f 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-main-pane-restore-start.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-main-pane-restore-start.test.ts @@ -82,7 +82,9 @@ async function connectBound( transport = createMockTransport() ) { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) transportFactoryQueue.push(transport) setStore({ tabsByWorktree: { 'wt-1': [{ id: TAB, ptyId: 'pty-old' }] }, diff --git a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-main-pane-start.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-main-pane-start.test.ts index f68cd1774ff..7f9a3ac06b1 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-main-pane-start.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-main-pane-start.test.ts @@ -64,7 +64,9 @@ function startLeaf1(ptyId: string): void { async function connectWithStart(start: TerminalPaneStart | undefined) { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) setStore({ @@ -134,7 +136,9 @@ describe('a pane main is starting a terminal for', () => { it('attaches a split pane to the terminal main bound it to, not its tab’s', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const newLeaf = leafIdForPane(2) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-pending-spawn.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-pending-spawn.spec.ts index 9189e8561d1..8bfc81d765c 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-pending-spawn.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-pending-spawn.spec.ts @@ -58,8 +58,9 @@ export function registerPtyConnectionPendingSpawnTests(): void { it('does not hold a successor behind a canceled spawn serializer declaration', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { pendingSpawnByPaneKey } = await import('./pending-pane-spawn') const declaration = createDeferred() const spawn = createDeferred() @@ -100,8 +101,9 @@ export function registerPtyConnectionPendingSpawnTests(): void { it('joins a successful pending spawn across a StrictMode remount', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pendingSpawn = createDeferred() const firstTransport = createMockTransport() firstTransport.connect.mockReturnValueOnce(pendingSpawn.promise) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-restart-replacement-stop-claim.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-restart-replacement-stop-claim.spec.ts index f38a559ab57..febcc4f377d 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-restart-replacement-stop-claim.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-restart-replacement-stop-claim.spec.ts @@ -57,8 +57,9 @@ export function registerPtyConnectionRestartReplacementDisposeTests(): void { it('stops the replaced PTY itself when the pane is disposed before a spawn carried the stop', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) transportFactoryQueue.push(createMockTransport('pty-restarted')) const deps = createDeps({ tabId: 'tab-restart-closed', diff --git a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-sleeping-resume-banner.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-sleeping-resume-banner.spec.ts index 3e1634ea14a..b3baace618c 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-sleeping-resume-banner.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-sleeping-resume-banner.spec.ts @@ -67,8 +67,9 @@ export function registerPtyConnectionSleepingResumeBannerTests(): void { it('resumes a local sleeping pane in place when the restored PTY hint is missing', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const spawn = createDeferred() const transport = createMockTransport() transport.connect.mockImplementation(() => spawn.promise) @@ -201,8 +202,9 @@ export function registerPtyConnectionSleepingResumeBannerTests(): void { it('says the fresh-spawn resume started fresh when main declined it', async () => { // Sidebar resume creates a fresh tab without a restored PTY; it still needs a resume banner (#10757). const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const spawn = createDeferred<{ id: string; agentResumeUnavailable: true }>() const transport = createMockTransport() transport.connect.mockImplementation(() => spawn.promise) @@ -294,8 +296,9 @@ export function registerPtyConnectionSleepingResumeBannerTests(): void { it('lets a declined resume replace an already-shown restored banner', async () => { // A later declined resume must clear an earlier restored-banner latch. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() let connectCount = 0 transport.connect.mockImplementation(async () => { @@ -396,8 +399,9 @@ export function registerPtyConnectionSleepingResumeBannerTests(): void { it('keeps sleeping resume record when fresh cold-restore spawn fails', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const staleSessionId = 'wt-1@@stale-session' const transport = createMockTransport() transport.connect.mockResolvedValue(undefined) @@ -455,8 +459,9 @@ export function registerPtyConnectionSleepingResumeBannerTests(): void { it('forwards one sidebar resume spawn without writing the restored banner through xterm', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-1') transportFactoryQueue.push(transport) const pane = createPane(1) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-spawn-deferred-sleep.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-spawn-deferred-sleep.test.ts index 02d5277a76d..c611fa95762 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-spawn-deferred-sleep.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-spawn-deferred-sleep.test.ts @@ -77,7 +77,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -250,7 +250,9 @@ describe('connectPanePty: a restore the host kept asleep', () => { async function mainOwnedResumeFixture() { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const pane = createPane(1) const paneKey = makePaneKey('tab-1', pane.leafId) const record = { @@ -462,7 +464,9 @@ describe('connectPanePty: a restore the host kept asleep', () => { it('keeps the pane sleeping with its resume handle and resumes it when opened', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { getPaneSpawnDeferral } = await import('@/lib/pane-spawn-deferral-registry') const transport = deferringTransport() transportFactoryQueue.push(transport) @@ -514,7 +518,9 @@ describe('connectPanePty: a restore the host kept asleep', () => { it('resumes a hidden pane in the background once the host has room, as an automatic restore', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { getPaneSpawnDeferral } = await import('@/lib/pane-spawn-deferral-registry') const transport = deferringTransport() transportFactoryQueue.push(transport) @@ -558,7 +564,9 @@ describe('connectPanePty: a restore the host kept asleep', () => { it('does not resume a session that meanwhile started in another tab', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { getPaneSpawnDeferral } = await import('@/lib/pane-spawn-deferral-registry') const transport = deferringTransport() transportFactoryQueue.push(transport) @@ -614,7 +622,9 @@ describe('connectPanePty: a restore the host kept asleep', () => { it('stays the owner while its retry is in flight, then hands over to the PTY', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { getPaneSpawnDeferral, isPaneSpawnDeferred } = await import('@/lib/pane-spawn-deferral-registry') const transport = deferringTransport() @@ -661,7 +671,9 @@ describe('connectPanePty: a restore the host kept asleep', () => { it('does not resume a session another tab has already queued', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = deferringTransport() transportFactoryQueue.push(transport) const pane = createPane(1) @@ -696,7 +708,9 @@ describe('connectPanePty: a restore the host kept asleep', () => { it('offers to clear a crash pause on the host, then resumes the pane', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { getPaneSpawnDeferral } = await import('@/lib/pane-spawn-deferral-registry') const transport = deferringTransport('paused') transportFactoryQueue.push(transport) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-split-spawn.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-split-spawn.spec.ts index dd9d5dddc05..06b6c501298 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-split-spawn.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/spawn/pty-connection-split-spawn.spec.ts @@ -67,8 +67,9 @@ export function registerPtyConnectionSplitSpawnTests(): void { it('clears the mobile-fit pane binding when the pane connection is disposed', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { getFitOverrideForPane, setFitOverride } = await import('@/lib/pane-manager/mobile-fit-overrides') const transport = createMockTransport() @@ -101,8 +102,9 @@ export function registerPtyConnectionSplitSpawnTests(): void { it('refits immediately when binding to a PTY with an active mobile-fit override', async () => { const { setFitOverride } = await import('@/lib/pane-manager/mobile-fit-overrides') const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const pane = createPane(1) @@ -160,8 +162,9 @@ export function registerPtyConnectionSplitSpawnTests(): void { } const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { setDriverForPty } = await import('@/lib/pane-manager/mobile-driver-state') const ptyId = 'pty-post-spawn-transient-lock' @@ -235,8 +238,9 @@ export function registerPtyConnectionSplitSpawnTests(): void { vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { applyOrDeferPaneMetricOptions } = await import('@/lib/pane-manager/pane-metric-options-deferral') const transport = createMockTransport() @@ -336,8 +340,9 @@ export function registerPtyConnectionSplitSpawnTests(): void { it('spawns the delayed primary pane of an issue-command split when its sibling owns the tab PTY fallback', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks5 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks5 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) let mainPtyId: string | null = null const mainTransport = createMockTransport() mainTransport.getPtyId.mockImplementation(() => mainPtyId) @@ -432,8 +437,9 @@ export function registerPtyConnectionSplitSpawnTests(): void { it('does not reuse a sibling split pane pending spawn after remount', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks6 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks6 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const mainSpawn = createDeferred() const setupSpawn = createDeferred() @@ -502,8 +508,9 @@ export function registerPtyConnectionSplitSpawnTests(): void { it('binds a fresh spawn that resolves as a daemon reattach', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks7 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks7 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) let currentPtyId: string | null = null const transport = createMockTransport() transport.getPtyId.mockImplementation(() => currentPtyId) @@ -535,8 +542,9 @@ export function registerPtyConnectionSplitSpawnTests(): void { it('replays a stable-pane adoption without submitting the resume command', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks8 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks8 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const stablePtyId = 'stable-pane-session' const transport = createMockTransport() transport.connect.mockImplementation(async ({ callbacks }) => { @@ -594,8 +602,9 @@ export function registerPtyConnectionSplitSpawnTests(): void { it('drops xterm onData while pane is replaying restored bytes', async () => { // Guard replay query replies from leaking through onData into fresh-shell stdin (replay-guard.ts). const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-live') transportFactoryQueue.push(transport) @@ -642,8 +651,9 @@ export function registerPtyConnectionSplitSpawnTests(): void { it('forwards focus and hover reports without claiming a parked mirror (#26469)', async () => { // SIGWINCH can re-arm focus reporting; focus replies must not make different-grid mirrors steal PTY ownership from each other. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('pty-live') transportFactoryQueue.push(transport) mockStoreState = { diff --git a/src/renderer/src/components/terminal-pane/pty-connection/startup/agent-pre-ready-typed-draft.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/startup/agent-pre-ready-typed-draft.test.ts index be31b23739c..6c003bb5e01 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/startup/agent-pre-ready-typed-draft.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/startup/agent-pre-ready-typed-draft.test.ts @@ -22,7 +22,9 @@ import { import { createInitialStoreState } from '../test-fixtures/pty-connection-test-store-fixtures' import type { StoreState } from '../test-fixtures/pty-connection-test-store-state' import type * as TerminalWorktreeRouteModule from '@/lib/terminal-worktree-route' -const agentTitleMocks = await vi.importMock('@/lib/agent-status') +const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' +) const { notifyCodexPaneBoundForStaleSweep, @@ -59,7 +61,9 @@ vi.mock('../../../../../../shared/layout-owner-switch', () => ({ vi.mock('@/runtime/sync-runtime-graph/graph-sync-scheduler', () => ({ scheduleRuntimeGraphSync })) -vi.mock('@/lib/agent-draft-readiness', () => ({ waitForAgentDraftInputReady })) +vi.mock('@/lib/agent-session/messaging/paste/agent-draft-readiness', () => ({ + waitForAgentDraftInputReady +})) const { requestTerminalPaneRecovery } = vi.hoisted(() => ({ requestTerminalPaneRecovery: vi.fn(async () => undefined) @@ -101,7 +105,9 @@ vi.mock('../../pty-transport/remote-runtime/remote-runtime-pty-transport', () => ) })) -vi.mock('@/lib/agent-draft-paste-content', () => ({ sendAgentDraftPasteContent })) +vi.mock('@/lib/agent-session/messaging/paste/agent-draft-paste-content', () => ({ + sendAgentDraftPasteContent +})) vi.mock('@/lib/agent-session/launch/prompt/launch-agent-paste-timeout-notice', () => ({ createPasteReadinessTimeoutNotice: (args: unknown) => { @@ -122,7 +128,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/startup/agent-pre-ready-typed-draft.ts b/src/renderer/src/components/terminal-pane/pty-connection/startup/agent-pre-ready-typed-draft.ts index ffee67bc744..24345f1ada7 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/startup/agent-pre-ready-typed-draft.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/startup/agent-pre-ready-typed-draft.ts @@ -4,8 +4,8 @@ import { useAppStore } from '@/store/index' import { TUI_AGENT_CONFIG } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import { resolveDraftPasteReadyTimeoutMs } from '../../../../../../shared/draft-paste-ready-timeout' -import { waitForAgentDraftInputReady } from '@/lib/agent-draft-readiness' -import { sendAgentDraftPasteContent } from '@/lib/agent-draft-paste-content' +import { waitForAgentDraftInputReady } from '@/lib/agent-session/messaging/paste/agent-draft-readiness' +import { sendAgentDraftPasteContent } from '@/lib/agent-session/messaging/paste/agent-draft-paste-content' import { createPasteReadinessTimeoutNotice } from '@/lib/agent-session/launch/prompt/launch-agent-paste-timeout-notice' import { PTY_PRECONNECT_INPUT_MAX_CODE_UNITS } from '../../pty-transport/input/pty-preconnect-input-buffer' import { writeTerminalPastePtyInput } from '../../input/paste/terminal-pty-paste-writer' diff --git a/src/renderer/src/components/terminal-pane/pty-connection/startup/cold-restore-resume-startup.ts b/src/renderer/src/components/terminal-pane/pty-connection/startup/cold-restore-resume-startup.ts index af9ebe9c833..983d4b9c96f 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/startup/cold-restore-resume-startup.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/startup/cold-restore-resume-startup.ts @@ -12,7 +12,7 @@ import { resolveRuntimeHostTerminalWindowsShell, resolveSshHostReportedPlatform, resolveAgentResumeLaunchTarget -} from '@/lib/agent-resume-launch-target' +} from '@/lib/agent-session/resume/agent-resume-launch-target' import { agentResumeOriginNamesAnotherExecutionHost, sleepingRecordNamesAnotherExecutionHost diff --git a/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-agent-startup-launch-registration.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-agent-startup-launch-registration.spec.ts index ed3bdda0fe2..8b0cd403a44 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-agent-startup-launch-registration.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-agent-startup-launch-registration.spec.ts @@ -59,8 +59,9 @@ export function registerPtyConnectionNonAgentLaunchRegistrationTests(): void { it('clears stale launch config when a pane consumes a non-agent startup command', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const paneKey = makePaneKey('tab-1', LEAF_1) @@ -116,8 +117,9 @@ export function registerPtyConnectionUnboundAgentLaunchRegistrationTests(): void it('clears launch config when an agent startup spawn produces no PTY', async () => { vi.useFakeTimers({ toFake: ['Date', 'setTimeout', 'clearTimeout'] }) const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() transportFactoryQueue.push(transport) const paneKey = makePaneKey('tab-1', LEAF_1) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-queued-startup-consume.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-queued-startup-consume.test.ts index 4c1bbf33038..4b06dddc58f 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-queued-startup-consume.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-queued-startup-consume.test.ts @@ -57,7 +57,7 @@ vi.mock('@/store', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -133,7 +133,9 @@ describe('connectPanePty queued startup consume', () => { it('spends the queued startup only after the pty is bound to the tab', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() spawnOnConnect(transport, 'fresh-pty') transportFactoryQueue.push(transport) @@ -165,7 +167,9 @@ describe('connectPanePty queued startup consume', () => { it('leaves the queued startup unspent when the spawn never reaches onPtySpawn', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() // A retired/reattached spawn resolves without ever announcing a fresh pty. transport.connect.mockImplementation(async () => undefined) @@ -190,7 +194,9 @@ describe('connectPanePty queued startup consume', () => { it('keeps a throwing consume from escaping into the spawn', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks4 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks4 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport() // onPtySpawn runs inside connect; callback throws would reject spawn and strand the pane, so cleanup must not throw. let escapedIntoSpawn = false diff --git a/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-split-cwd-resolution.test.ts b/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-split-cwd-resolution.test.ts index f08a7e21194..ec52f7c6901 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-split-cwd-resolution.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-split-cwd-resolution.test.ts @@ -50,7 +50,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -99,7 +99,9 @@ describe('connectPanePty split cwd resolution', () => { const cwd = createDeferred() const transport = createMockTransport('pty-1') transportFactoryQueue.push(transport) - const agentTitleMocks2 = await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const binding = connectPanePty( createPane(1) as never, diff --git a/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-startup-command-delivery.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-startup-command-delivery.spec.ts index 9c38a3ef630..057a5ee4945 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-startup-command-delivery.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-startup-command-delivery.spec.ts @@ -59,8 +59,9 @@ export function registerPtyConnectionLocalStartupCommandDeliveryTests(): void { it('does not send startup command via sendInput for local connections', async () => { // Why: the local PTY provider already writes the command via writeStartupCommandWhenShellReady; re-sending from the renderer would double it in the terminal. const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport() @@ -139,8 +140,9 @@ export function registerPtyConnectionTerminalPasteStartupCommandDeliveryTests(): try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks9 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks9 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-id') @@ -202,8 +204,9 @@ export function registerPtyConnectionTerminalPasteStartupCommandDeliveryTests(): try { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks10 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks10 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-id') diff --git a/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-startup-draft-delivery.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-startup-draft-delivery.spec.ts index 18447526cb9..fb44e98eaaa 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-startup-draft-delivery.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/startup/pty-connection-startup-draft-delivery.spec.ts @@ -1,7 +1,7 @@ import { bindPtyConnectionTestMocks } from '../test-fixtures/pty-connection-mocks.spec' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { makePaneKey } from '../../../../../../shared/workspace-layout/stable-pane-id' -import { beginAgentStartupDeliveryAttempt } from '@/lib/agent-startup-delayed-delivery' +import { beginAgentStartupDeliveryAttempt } from '@/lib/agent-session/launch/startup/agent-startup-delayed-delivery' import { flushAsyncTicks } from '../test-fixtures/pty-connection-test-async' import { VISIBLE_PTY_SETTLE_MS } from '../test-fixtures/pty-connection-test-constants' import { @@ -61,10 +61,11 @@ export function registerPtyConnectionStartupDraftDeliveryTests(): void { it.each([10_000, 20_000])('keeps Codex draft delivery bounded after %d ms', async (waitMs) => { vi.useFakeTimers() const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { beginAgentStartupDeliveryAttempt: claimStartupDelivery } = - await import('@/lib/agent-startup-delayed-delivery') + await import('@/lib/agent-session/launch/startup/agent-startup-delayed-delivery') const capturedDataCallback: { current: ((data: string) => void) | null } = { current: null } const transport = createMockTransport('pty-codex') @@ -152,10 +153,11 @@ export function registerPtyConnectionStartupDraftDeliveryTests(): void { it('keeps startup draft ownership while deferred connect waits through setup', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const { beginAgentStartupDeliveryAttempt: claimStartupDelivery } = - await import('@/lib/agent-startup-delayed-delivery') + await import('@/lib/agent-session/launch/startup/agent-startup-delayed-delivery') const deferredFrames: FrameRequestCallback[] = [] globalThis.requestAnimationFrame = vi.fn((callback: FrameRequestCallback) => { @@ -226,8 +228,9 @@ export function registerPtyConnectionStartupDraftDeliveryTests(): void { it('releases startup draft delivery when disposed before deferred connect starts', async () => { const { connectPanePty } = await import('../connect-pane-pty') - const agentTitleMocks3 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks3 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) globalThis.requestAnimationFrame = vi.fn(() => 1) const transport = createMockTransport('pty-codex') transportFactoryQueue.push(transport) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/startup/sleeping-record-access.ts b/src/renderer/src/components/terminal-pane/pty-connection/startup/sleeping-record-access.ts index 54c095e1a7a..21abb44140e 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/startup/sleeping-record-access.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/startup/sleeping-record-access.ts @@ -15,7 +15,7 @@ import { TUI_AGENT_CONFIG } from '../../../../../../shared/agent-launch/catalog/ import { beginAgentStartupDeliveryAttempt, releaseAgentStartupDeliveryAttempt -} from '@/lib/agent-startup-delayed-delivery' +} from '@/lib/agent-session/launch/startup/agent-startup-delayed-delivery' import type { ConnectPanePtySession } from '../connect-pane-pty-session' diff --git a/src/renderer/src/components/terminal-pane/pty-connection/startup/startup-draft-paste.ts b/src/renderer/src/components/terminal-pane/pty-connection/startup/startup-draft-paste.ts index 48bdff6523b..ad642a757fd 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/startup/startup-draft-paste.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/startup/startup-draft-paste.ts @@ -2,7 +2,7 @@ import { inspectRuntimeTerminalProcess } from '@/runtime/hosted-terminals/inspec import { isExpectedAgentProcess } from '../../../../../../shared/agent-status/process/agent-process-recognition' import { resolveDraftPasteReadyTimeoutMs } from '../../../../../../shared/draft-paste-ready-timeout' import { createDraftPasteReadyScanner } from '../../../../../../shared/draft-paste-ready-scanner' -import { sendAgentDraftPasteContent } from '@/lib/agent-draft-paste-content' +import { sendAgentDraftPasteContent } from '@/lib/agent-session/messaging/paste/agent-draft-paste-content' import { writeTerminalPastePtyInput } from '../../input/paste/terminal-pty-paste-writer' import { createPasteReadinessTimeoutNotice } from '@/lib/agent-session/launch/prompt/launch-agent-paste-timeout-notice' import type { ConnectPanePtySession } from '../connect-pane-pty-session' diff --git a/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-mocks.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-mocks.spec.ts index 089090ac617..2127b7630b4 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-mocks.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-mocks.spec.ts @@ -87,7 +87,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('./pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) }) diff --git a/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-test-environment.ts b/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-test-environment.ts index 2e68f2eae1b..2d53abce03a 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-test-environment.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-test-environment.ts @@ -190,8 +190,8 @@ async function resetSharedTerminalModuleState(): Promise { paneRecovery ] = await Promise.all([ import('@/lib/pane-manager/pane-terminal-output-queue-registry'), - import('@/lib/agent-startup-delayed-delivery'), - import('@/lib/agent-startup-delivery-guards'), + import('@/lib/agent-session/launch/startup/agent-startup-delayed-delivery'), + import('@/lib/agent-session/launch/startup/agent-startup-delivery-guards'), import('@/lib/hook-command-delayed-delivery'), import('../../agent-completion/agent-completion-identity-store'), import('../../agent-completion/command-code/command-code-done-settle'), diff --git a/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-test-hidden-restore-flood.ts b/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-test-hidden-restore-flood.ts index f76da4e182a..4f6722472f7 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-test-hidden-restore-flood.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/test-fixtures/pty-connection-test-hidden-restore-flood.ts @@ -97,7 +97,9 @@ export async function connectVisiblePane(): Promise { const deps = buildPaneConnectionDeps(() => mockStoreState, { isVisibleRef: { current: true } }) - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const disposable = await connectMockPanePty( pane, diff --git a/src/renderer/src/components/terminal-pane/pty-connection/tests/input-modes/pty-connection-kitty-keyboard-restore.spec.ts b/src/renderer/src/components/terminal-pane/pty-connection/tests/input-modes/pty-connection-kitty-keyboard-restore.spec.ts index 067ea954df7..55e68dbfc4a 100644 --- a/src/renderer/src/components/terminal-pane/pty-connection/tests/input-modes/pty-connection-kitty-keyboard-restore.spec.ts +++ b/src/renderer/src/components/terminal-pane/pty-connection/tests/input-modes/pty-connection-kitty-keyboard-restore.spec.ts @@ -64,8 +64,9 @@ export function registerPtyConnectionKittyKeyboardRestoreTests(): void { async function reattachWithSnapshotFlags(kittyKeyboard: boolean) { const { connectPanePty } = await import('../../connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('tab-pty') transport.connect.mockImplementation(async ({ sessionId }: { sessionId?: string }) => sessionId @@ -114,8 +115,9 @@ export function registerPtyConnectionKittyKeyboardRestoreTests(): void { it('grounds xterm and the mirror with one scanned write before a restart-in-place spawns', async () => { const { connectPanePty } = await import('../../connect-pane-pty') - const agentTitleMocks2 = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks2 = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) transportFactoryQueue.push(createMockTransport()) const pane = createPane(91) // Use a unique tab ID to avoid other tests’ pending-spawn entries and force fresh spawn. diff --git a/src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-connect-spawn.test.ts b/src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-connect-spawn.test.ts index 25866b80bbf..91ffb9b5cca 100644 --- a/src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-connect-spawn.test.ts +++ b/src/renderer/src/components/terminal-pane/pty-transport/ipc/pty-transport-connect-spawn.test.ts @@ -512,8 +512,9 @@ describe('createIpcPtyTransport', () => { await installTerminalTestGlobals() try { const { connectPanePty } = await import('../../pty-connection/connect-pane-pty') - const agentTitleMocks = - await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) for (const proof of ['interleaved', 'covered', 'no-flags'] as const) { state = createInitialStoreState(() => state) const result = provenSpawnResponse( diff --git a/src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport.ts b/src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport.ts index 8bcc18152a5..7d9b3a08f37 100644 --- a/src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport.ts +++ b/src/renderer/src/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-transport.ts @@ -7,7 +7,7 @@ import { agentSessionCreateRequest, createAgentSessionTrustWorktreeOptions } from '@/runtime/hosted-terminals/creation/agent-launch/agent-session-create-request' -import { beginAgentStartupDeliveryAttempt } from '@/lib/agent-startup-delayed-delivery' +import { beginAgentStartupDeliveryAttempt } from '@/lib/agent-session/launch/startup/agent-startup-delayed-delivery' import { planHostedAgentPrompt, hostedAgentPromptHostFacts, diff --git a/src/renderer/src/components/terminal-pane/quick-commands/TerminalQuickCommandsSubmenu.tsx b/src/renderer/src/components/terminal-pane/quick-commands/TerminalQuickCommandsSubmenu.tsx index de332ca28d9..f8b22f5e170 100644 --- a/src/renderer/src/components/terminal-pane/quick-commands/TerminalQuickCommandsSubmenu.tsx +++ b/src/renderer/src/components/terminal-pane/quick-commands/TerminalQuickCommandsSubmenu.tsx @@ -11,7 +11,7 @@ import { import type { TerminalQuickCommand } from '../../../../../shared/terminal/quick-commands/terminal-quick-command-types' import type { ExecutionHostId } from '../../../../../shared/execution-host' import { isTerminalAgentQuickCommand } from '../../../../../shared/terminal/quick-commands/terminal-quick-commands' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { useTranslate } from '@/i18n/use-translate' import { getHostedTerminalQuickCommandKey, diff --git a/src/renderer/src/components/terminal-pane/session-continuation/terminal-agent-session-continuation.ts b/src/renderer/src/components/terminal-pane/session-continuation/terminal-agent-session-continuation.ts index 0880bd52128..096ae49f504 100644 --- a/src/renderer/src/components/terminal-pane/session-continuation/terminal-agent-session-continuation.ts +++ b/src/renderer/src/components/terminal-pane/session-continuation/terminal-agent-session-continuation.ts @@ -4,7 +4,7 @@ import { buildAgentSessionContinuationPrompt, resolveAgentSessionContinuationTranscriptPath, type AgentSessionContinuationRequest -} from '@/lib/agent-session-continuation' +} from '@/lib/agent-session/context/agent-session-continuation' import { useAppStore } from '@/store/index' import { makePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' import { isTuiAgent } from '../../../../../shared/agent-launch/catalog/tui-agent-config' diff --git a/src/renderer/src/components/terminal-pane/session-fork/terminal-agent-session-fork.ts b/src/renderer/src/components/terminal-pane/session-fork/terminal-agent-session-fork.ts index 9dfd2eb353a..fb1282278bc 100644 --- a/src/renderer/src/components/terminal-pane/session-fork/terminal-agent-session-fork.ts +++ b/src/renderer/src/components/terminal-pane/session-fork/terminal-agent-session-fork.ts @@ -3,7 +3,7 @@ import type { ManagedPane } from '@/lib/pane-manager/pane-manager-types' import { launchAgentInNewTab } from '@/lib/agent-session/launch/new-tab/launch-agent-in-new-tab' import { settleAgentTabLaunch } from '@/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-host-agents' import { newAgentPromptOutcome } from '@/lib/new-agent-prompt-outcome' -import { buildAgentSessionForkPrompt } from '@/lib/agent-session-fork-context' +import { buildAgentSessionForkPrompt } from '@/lib/agent-session/context/agent-session-fork-context' import { activateAndRevealWorktree } from '@/lib/workspace/activation/worktree-activation' import { resolveOwner } from '@/lib/workspace/ownership/resolve-owner' import { diff --git a/src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-alt-screen-host-chain.test.ts b/src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-alt-screen-host-chain.test.ts index 3b0d464ccf5..ea7a4b630ae 100644 --- a/src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-alt-screen-host-chain.test.ts +++ b/src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-alt-screen-host-chain.test.ts @@ -62,7 +62,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../pty-connection/test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -364,7 +364,9 @@ describe('host-published recovery snapshot onto a live alt screen', () => { meta: PtyReplayDataMeta ): Promise { const { connectPanePty } = await import('../pty-connection/connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('agent-pty') const replay: { current: ConnectCallbacks['onReplayData'] | null } = { current: null } transport.connect.mockImplementation(async ({ callbacks }: { callbacks: ConnectCallbacks }) => { diff --git a/src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-alt-screen-replay.test.ts b/src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-alt-screen-replay.test.ts index e4eddf0f2d8..5563a7414e9 100644 --- a/src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-alt-screen-replay.test.ts +++ b/src/renderer/src/components/terminal-pane/snapshots/remote-snapshot-alt-screen-replay.test.ts @@ -55,7 +55,7 @@ vi.mock('@/store/index', () => ({ } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const { buildAgentStatusModuleMock } = await import('../pty-connection/test-fixtures/pty-connection-test-environment') return buildAgentStatusModuleMock(await importOriginal>()) @@ -156,7 +156,9 @@ describe('remote snapshot replay onto a live alt screen', () => { paneBuffer: 'normal' | 'alternate' | 'alternate-queued' = 'alternate' ): Promise { const { connectPanePty } = await import('../pty-connection/connect-pane-pty') - const agentTitleMocks = await vi.importMock('@/lib/agent-status') + const agentTitleMocks = await vi.importMock( + '@/lib/agent-status/aggregation/worktree-agent-status' + ) const transport = createMockTransport('agent-pty') const replay: { current: ConnectCallbacks['onReplayData'] | null } = { current: null } transport.connect.mockImplementation(async ({ callbacks }: { callbacks: ConnectCallbacks }) => { diff --git a/src/renderer/src/components/terminal-quick-commands/TerminalQuickCommandDialog.tsx b/src/renderer/src/components/terminal-quick-commands/TerminalQuickCommandDialog.tsx index 1cf6312cafa..47587948685 100644 --- a/src/renderer/src/components/terminal-quick-commands/TerminalQuickCommandDialog.tsx +++ b/src/renderer/src/components/terminal-quick-commands/TerminalQuickCommandDialog.tsx @@ -21,7 +21,7 @@ import { DialogTitle } from '@/components/ui/dialog' import { Label } from '@/components/ui/label' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { getScreenSubmitShortcutLabel, isScreenSubmitShortcut } from '@/lib/screen-submit-shortcut' import { isSelectAllShortcut } from '@/lib/editable-target' import { TerminalQuickCommandActionToggle } from './TerminalQuickCommandActionToggle' diff --git a/src/renderer/src/components/terminal-quick-commands/terminal-quick-command-agent-options.ts b/src/renderer/src/components/terminal-quick-commands/terminal-quick-command-agent-options.ts index 316b9899795..a471d3ca1e4 100644 --- a/src/renderer/src/components/terminal-quick-commands/terminal-quick-command-agent-options.ts +++ b/src/renderer/src/components/terminal-quick-commands/terminal-quick-command-agent-options.ts @@ -1,4 +1,4 @@ -import { type AgentCatalogEntry, getAgentCatalog } from '@/lib/agent-catalog' +import { type AgentCatalogEntry, getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { supportsTerminalAgentQuickCommand } from '../../../../shared/terminal/quick-commands/terminal-quick-commands' import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' diff --git a/src/renderer/src/components/terminal-workspace-keydown.ts b/src/renderer/src/components/terminal-workspace-keydown.ts index fa5c6039ae4..672baf61dc7 100644 --- a/src/renderer/src/components/terminal-workspace-keydown.ts +++ b/src/renderer/src/components/terminal-workspace-keydown.ts @@ -22,7 +22,7 @@ import { translate } from '@/i18n/i18n' import { getKeybindingContext } from './terminal-workspace-model' import { isAgentTerminalPreviewTarget } from './dashboard-popout/agent-terminal-preview-target' import { resolveTerminalAgentTabShortcut } from './terminal-agent-tab-shortcut' -import { getDetectionTargetIdentityForWorktree } from '@/lib/agent-detection-target-inventory' +import { getDetectionTargetIdentityForWorktree } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { launchAgentTabShortcut, launchFloatingWorkspaceAgentShortcut diff --git a/src/renderer/src/components/worktree-jump/worktree-jump-palette-workspace-tab-row.tsx b/src/renderer/src/components/worktree-jump/worktree-jump-palette-workspace-tab-row.tsx index fd355b6d121..797d19131ca 100644 --- a/src/renderer/src/components/worktree-jump/worktree-jump-palette-workspace-tab-row.tsx +++ b/src/renderer/src/components/worktree-jump/worktree-jump-palette-workspace-tab-row.tsx @@ -1,6 +1,6 @@ import type React from 'react' import { FileText, MessageSquare, SquareTerminal } from 'lucide-react' -import { AgentIcon } from '@/lib/agent-catalog' +import { AgentIcon } from '@/components/agent/icons/AgentIcon' import { CommandItem } from '@/components/ui/command' import { PaletteRecentTabStatusDot } from '@/components/cmd-j/palette-live-status' import { getPaletteHostBadge } from '@/components/cmd-j/palette-host-badge' diff --git a/src/renderer/src/hooks/agent-hook-turn-end-ownership.ts b/src/renderer/src/hooks/agent-hook-turn-end-ownership.ts index 324e0721816..8bd916ba5b6 100644 --- a/src/renderer/src/hooks/agent-hook-turn-end-ownership.ts +++ b/src/renderer/src/hooks/agent-hook-turn-end-ownership.ts @@ -1,5 +1,5 @@ import { useAppStore } from '@/store' -import { resolveCommittedTitleAgentType } from '@/lib/pane-agent-evidence' +import { resolveExplicitTerminalTitleAgentType } from '../../../shared/agent-status/title/terminal-title-agent-type' import { resolveCompatibleAgentTypeForOwner } from '../../../shared/agent-status/title/agent-title-owner' import { isAgentStatusHooksEnabledForAgent } from '../../../shared/agent-hook-listener/configuration/agent-status-hooks-setting' import { isTuiAgent } from '../../../shared/agent-launch/catalog/tui-agent-config' @@ -45,6 +45,6 @@ export function hookLaneTitleTurnEndEvidence( title: string | null, foregroundAgent: TerminalAgent | null ): 'identified' | 'ambiguous' | null { - const agent = (title ? resolveCommittedTitleAgentType(title) : null) ?? foregroundAgent + const agent = (title ? resolveExplicitTerminalTitleAgentType(title) : null) ?? foregroundAgent return hookLaneTurnEndEvidence(paneKey, ptyId, agent) } diff --git a/src/renderer/src/hooks/composer-state/host-runtime-effects.ts b/src/renderer/src/hooks/composer-state/host-runtime-effects.ts index df460e35790..43c74065ecc 100644 --- a/src/renderer/src/hooks/composer-state/host-runtime-effects.ts +++ b/src/renderer/src/hooks/composer-state/host-runtime-effects.ts @@ -35,7 +35,7 @@ import { filterEnabledTuiAgents, isTuiAgentEnabled } from '../../../../shared/agent-launch/catalog/tui-agent-selection' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { useAppStore } from '@/store' import { isSshConnectInProgress } from '@/lib/new-workspace-ssh-gate' import { diff --git a/src/renderer/src/hooks/composer-state/quick-creation-request.ts b/src/renderer/src/hooks/composer-state/quick-creation-request.ts index 87e07d9a649..dbd6c3abfef 100644 --- a/src/renderer/src/hooks/composer-state/quick-creation-request.ts +++ b/src/renderer/src/hooks/composer-state/quick-creation-request.ts @@ -4,7 +4,7 @@ import type { AgentStartupPlan } from '../../../../shared/agent-launch/startup/t import type { LinkedWorkItemSummary } from '@/lib/new-workspace' import type { TaskSourceContext } from '../../../../shared/work-items/task-source-context' import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' -import type { AgentLaunchChoice } from '@/lib/agent-menu-selection' +import type { AgentLaunchChoice } from '@/lib/agent-session/launch/routing/agent-menu-selection' import type { GitPushTarget } from '../../../../shared/worktree/types' import type { SetupDecision } from '../../../../shared/worktree/create-types' import '@/components/sidebar/workspace-creation/folder/folder-workspace-source-repos' diff --git a/src/renderer/src/hooks/composer-state/quick-startup-plan.ts b/src/renderer/src/hooks/composer-state/quick-startup-plan.ts index 27c045aa7d3..195355aac43 100644 --- a/src/renderer/src/hooks/composer-state/quick-startup-plan.ts +++ b/src/renderer/src/hooks/composer-state/quick-startup-plan.ts @@ -18,7 +18,7 @@ import type { AgentStartupPlan } from '../../../../shared/agent-launch/startup/t import { resolveAgentStartupPlanInputs } from '../../../../shared/agent-launch/startup/agent-startup-plan-inputs' import { tuiAgentToAgentKind } from '@/lib/telemetry' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import { translate } from '@/i18n/i18n' import { requireExecutionHostPlatform } from '@/runtime/hosts/platform/execution-host-facts' import type { ExecutionHostPlatformFact } from '@/runtime/hosts/platform/execution-host-platform-fact' diff --git a/src/renderer/src/hooks/composer-state/workspace-identity-state.ts b/src/renderer/src/hooks/composer-state/workspace-identity-state.ts index 27d7fc7a9f7..f3e2f50ad42 100644 --- a/src/renderer/src/hooks/composer-state/workspace-identity-state.ts +++ b/src/renderer/src/hooks/composer-state/workspace-identity-state.ts @@ -29,7 +29,7 @@ import { filterEnabledTuiAgents, isTuiAgentEnabled } from '../../../../shared/agent-launch/catalog/tui-agent-selection' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' import { useAppStore } from '@/store' /** Older drafts lack naming intent; restore baseBranch as the branch pick it represented when saved. */ diff --git a/src/renderer/src/hooks/ipc-events/agent-status-event-applicator.ts b/src/renderer/src/hooks/ipc-events/agent-status-event-applicator.ts index 1ad486aab67..35fbfff141b 100644 --- a/src/renderer/src/hooks/ipc-events/agent-status-event-applicator.ts +++ b/src/renderer/src/hooks/ipc-events/agent-status-event-applicator.ts @@ -5,7 +5,7 @@ import type { AgentStatusIpcPayload } from '../../../../shared/agent-status/cont import { isDecorativeAgentTitleFrameChange } from '../../../../shared/agent-status/title/agent-decorative-title-signature' import { parsePaneKey } from '../../../../shared/workspace-layout/stable-pane-id' import { normalizeProgramStatusFacet } from '../../../../shared/program-status/facet' -import { resolveAgentStatusTerminalTitle } from '@/lib/agent-status-terminal-title' +import { resolveAgentStatusTerminalTitle } from '@/lib/agent-status/evidence/agent-status-terminal-title' import { track } from '@/lib/telemetry' import { resolveAgentPaneAuthorityKey } from '@/store/slices/agent-status/agent-pane-authority' import type { AgentStatusUpdate } from '@/store/slices/agent-status/agent-status-contract' diff --git a/src/renderer/src/hooks/ipc-events/agent-status-listeners.ts b/src/renderer/src/hooks/ipc-events/agent-status-listeners.ts index c66e49626cd..5783ac2fd25 100644 --- a/src/renderer/src/hooks/ipc-events/agent-status-listeners.ts +++ b/src/renderer/src/hooks/ipc-events/agent-status-listeners.ts @@ -11,7 +11,7 @@ import { import { useAppStore } from '../../store' import { forgetRefusedPaneResume, namesRefusedResume } from '@/lib/forget-refused-pane-resume' import { resolveAgentPaneAuthorityKey } from '@/store/slices/agent-status/agent-pane-authority' -import { resolvePaneKey } from './agent-status-routing' +import { resolvePaneKey } from '../../lib/agent-status/ownership/agent-status-pane-ownership' import type { PendingAgentStatusEvent } from './agent-status-bridge-types' /** An already delivered event for the pane naming a refused conversation would restore it. */ diff --git a/src/renderer/src/hooks/ipc-events/agent-status-routing.ts b/src/renderer/src/hooks/ipc-events/agent-status-routing.ts index 9455045feea..311ca5cedc1 100644 --- a/src/renderer/src/hooks/ipc-events/agent-status-routing.ts +++ b/src/renderer/src/hooks/ipc-events/agent-status-routing.ts @@ -159,5 +159,3 @@ export function isInheritedFromActivePane( }).inheritedFromActivePane ) } - -export { resolvePaneKey } from '../../lib/agent-status-pane-ownership' diff --git a/src/renderer/src/hooks/ipc-events/terminal-request-ipc-bridge-placement.test.ts b/src/renderer/src/hooks/ipc-events/terminal-request-ipc-bridge-placement.test.ts index 951d370b3d7..6493b15922a 100644 --- a/src/renderer/src/hooks/ipc-events/terminal-request-ipc-bridge-placement.test.ts +++ b/src/renderer/src/hooks/ipc-events/terminal-request-ipc-bridge-placement.test.ts @@ -1,10 +1,10 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTabsSliceMockApi } from '../../store/slices/tabs/tabs-slice-test-harness' import { createTestStore } from '../../store/testing/app-store-test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => ({ +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => ({ ...(await importOriginal()), detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) })) diff --git a/src/renderer/src/hooks/use-linear-agent-skill-setup.ts b/src/renderer/src/hooks/use-linear-agent-skill-setup.ts index eb18a2e1766..043a4af7b9b 100644 --- a/src/renderer/src/hooks/use-linear-agent-skill-setup.ts +++ b/src/renderer/src/hooks/use-linear-agent-skill-setup.ts @@ -1,6 +1,6 @@ import { useMemo } from 'react' -import { LINEAR_AGENT_SKILL_NAMES } from '@/lib/agent-feature-skill-names' -import { getLinearAgentSkillUpdateTarget } from '@/lib/linear-agent-skill-update-target' +import { LINEAR_AGENT_SKILL_NAMES } from '@/lib/skills/installation/agent-feature-skill-names' +import { getLinearAgentSkillUpdateTarget } from '@/lib/skills/installation/linear-agent-skill-update-target' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, useInstalledAgentSkillNames diff --git a/src/renderer/src/hooks/use-local-cli-skill-freshness-name.ts b/src/renderer/src/hooks/use-local-cli-skill-freshness-name.ts index 9385dcb3e84..407168fc36f 100644 --- a/src/renderer/src/hooks/use-local-cli-skill-freshness-name.ts +++ b/src/renderer/src/hooks/use-local-cli-skill-freshness-name.ts @@ -1,4 +1,4 @@ -import { ORCA_CLI_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCA_CLI_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { useActiveProjectSkillRuntime } from '@/hooks/useActiveProjectSkillRuntime' import type { LocalAgentRuntime } from '../lib/skill-runtime-command' diff --git a/src/renderer/src/hooks/use-onboarding-skill-runtime.ts b/src/renderer/src/hooks/use-onboarding-skill-runtime.ts index e6beb5f02f9..6ef94d15ab0 100644 --- a/src/renderer/src/hooks/use-onboarding-skill-runtime.ts +++ b/src/renderer/src/hooks/use-onboarding-skill-runtime.ts @@ -1,7 +1,10 @@ import { useMemo } from 'react' import { LOCAL_EXECUTION_HOST_ID } from '../../../shared/execution-host' import { nativeChatPreferenceFor } from '../../../shared/structured-native-chat-launch-route' -import { chatProviderAgents, useHostStructuredAgentsVersion } from '@/lib/chat-provider-agents' +import { + chatProviderAgents, + useHostStructuredAgentsVersion +} from '@/runtime/native-chat/agent-catalogs/chat-provider-agents' import { recomputeOn } from '@/lib/recompute-on' import { getNativeChatAgentProfile } from '../../../shared/native-chat/native-chat-agent-profiles' import { isSkillInstallProviderId } from '../../../shared/skill-install-providers' diff --git a/src/renderer/src/hooks/useInstalledAgentSkills.ts b/src/renderer/src/hooks/useInstalledAgentSkills.ts index 65506bc4f3d..908006f662d 100644 --- a/src/renderer/src/hooks/useInstalledAgentSkills.ts +++ b/src/renderer/src/hooks/useInstalledAgentSkills.ts @@ -1,5 +1,5 @@ import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' -import { agentReadsSkill } from '@/lib/agent-skill-coverage' +import { agentReadsSkill } from '@/lib/skills/agent-skill-coverage' import type { RuntimeClientTarget } from '../../../shared/runtime-client-target' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import type { @@ -9,7 +9,7 @@ import type { SkillDiscoveryTarget, SkillSourceKind } from '../../../shared/skills' -import { ORCHESTRATION_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { ORCHESTRATION_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' import { markOrchestrationSetupComplete } from '@/lib/orchestration-setup-state' import { discoverInstalledAgentSkills, diff --git a/src/renderer/src/lib/activity-thread-display.ts b/src/renderer/src/lib/activity-thread-display.ts index 8ae24edd67d..b3386b56112 100644 --- a/src/renderer/src/lib/activity-thread-display.ts +++ b/src/renderer/src/lib/activity-thread-display.ts @@ -10,8 +10,8 @@ import { isOrcaDispatchPrompt, orchestrationLabelsMatchLiveDispatch } from '../../../shared/agent-status/presentation/agent-row-primary-text' -import { formatAgentToolPreview } from './agent-row-tool-preview' -import { agentVerdictStatusLine } from './agent-verdict-status-line' +import { formatAgentToolPreview } from './agent-status/presentation/agent-row-tool-preview' +import { agentVerdictStatusLine } from './agent-status/presentation/agent-verdict-status-line' // Terse follow-ups such as “yes” are valid prompts but poor cross-worktree task labels. const TERSE_FOLLOW_UP_PATTERN = diff --git a/src/renderer/src/lib/agent-catalog-entries-primary.ts b/src/renderer/src/lib/agent-catalog/agent-catalog-entries-primary.ts similarity index 97% rename from src/renderer/src/lib/agent-catalog-entries-primary.ts rename to src/renderer/src/lib/agent-catalog/agent-catalog-entries-primary.ts index 99ac9c94ac1..aed7cf288b0 100644 --- a/src/renderer/src/lib/agent-catalog-entries-primary.ts +++ b/src/renderer/src/lib/agent-catalog/agent-catalog-entries-primary.ts @@ -1,9 +1,9 @@ import { getCatalogPlatform } from './agent-catalog-platform' -import openClaudeLogoUrl from '../../../../resources/openclaude-logo.png?url' +import openClaudeLogoUrl from '../../../../../resources/openclaude-logo.png?url' import { getTuiAgentLaunchCommand, TUI_AGENT_CONFIG -} from '../../../shared/agent-launch/catalog/tui-agent-config' +} from '../../../../shared/agent-launch/catalog/tui-agent-config' import { translate } from '@/i18n/i18n' import type { AgentCatalogEntry } from './agent-catalog' diff --git a/src/renderer/src/lib/agent-catalog-entries-secondary.ts b/src/renderer/src/lib/agent-catalog/agent-catalog-entries-secondary.ts similarity index 100% rename from src/renderer/src/lib/agent-catalog-entries-secondary.ts rename to src/renderer/src/lib/agent-catalog/agent-catalog-entries-secondary.ts diff --git a/src/renderer/src/lib/agent-catalog-entries.ts b/src/renderer/src/lib/agent-catalog/agent-catalog-entries.ts similarity index 82% rename from src/renderer/src/lib/agent-catalog-entries.ts rename to src/renderer/src/lib/agent-catalog/agent-catalog-entries.ts index b3f5e0576e7..7ddf0ccb4d5 100644 --- a/src/renderer/src/lib/agent-catalog-entries.ts +++ b/src/renderer/src/lib/agent-catalog/agent-catalog-entries.ts @@ -1,4 +1,4 @@ -import { TUI_AGENT_FAVICON_DOMAINS } from '../../../shared/agent-launch/catalog/tui-agent-favicon-domains' +import { TUI_AGENT_FAVICON_DOMAINS } from '../../../../shared/agent-launch/catalog/tui-agent-favicon-domains' import { primaryAgentCatalogEntries } from './agent-catalog-entries-primary' import { secondaryAgentCatalogEntries } from './agent-catalog-entries-secondary' import type { AgentCatalogEntry } from './agent-catalog' diff --git a/src/renderer/src/lib/agent-catalog-platform.ts b/src/renderer/src/lib/agent-catalog/agent-catalog-platform.ts similarity index 100% rename from src/renderer/src/lib/agent-catalog-platform.ts rename to src/renderer/src/lib/agent-catalog/agent-catalog-platform.ts diff --git a/src/renderer/src/lib/agent-catalog/agent-catalog.ts b/src/renderer/src/lib/agent-catalog/agent-catalog.ts new file mode 100644 index 00000000000..a4b2aefa8d5 --- /dev/null +++ b/src/renderer/src/lib/agent-catalog/agent-catalog.ts @@ -0,0 +1,31 @@ +import '@/components/status-bar/icons' +import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' +import type { TerminalAgent } from '../../../../shared/agent-status/identity/terminal-agent' +import { formatAgentTypeLabel } from '../../../../shared/agent-status/presentation/agent-type-label' +import '../../components/agent/icons/agent-icon-glyphs' +import { createLocalizedCatalog } from '@/i18n/localized-catalog' +import '../../components/agent/icons/agent-favicon-assets' +import { buildAgentCatalogEntries } from './agent-catalog-entries' + +export type AgentCatalogEntry = { + id: TuiAgent + label: string + /** Default CLI binary name used for PATH detection. */ + cmd: string + searchAliases?: readonly string[] + /** Direct or bundled image URL for agents whose project identity is not represented by a favicon service. */ + iconUrl?: string + /** Domain for Google's favicon service — used for agents without an SVG icon. */ + faviconDomain?: string + /** Homepage/install docs URL, sourced from the README agent badge list. */ + homepageUrl: string +} + +export const getAgentCatalog = createLocalizedCatalog(buildAgentCatalogEntries) + +// Why: tests and a few legacy call sites still import a catalog snapshot. +export const AGENT_CATALOG: AgentCatalogEntry[] = getAgentCatalog() + +export function getAgentLabel(agent: TerminalAgent): string { + return getAgentCatalog().find((entry) => entry.id === agent)?.label ?? formatAgentTypeLabel(agent) +} diff --git a/src/renderer/src/lib/agent-picker-search.ts b/src/renderer/src/lib/agent-catalog/agent-picker-search.ts similarity index 97% rename from src/renderer/src/lib/agent-picker-search.ts rename to src/renderer/src/lib/agent-catalog/agent-picker-search.ts index b3129feb8cc..9c03d11446d 100644 --- a/src/renderer/src/lib/agent-picker-search.ts +++ b/src/renderer/src/lib/agent-catalog/agent-picker-search.ts @@ -1,5 +1,5 @@ -import type { AgentCatalogEntry } from '@/lib/agent-catalog' -import { isClipboardTextByteLengthOverLimit } from '../../../shared/clipboard-text' +import type { AgentCatalogEntry } from '@/lib/agent-catalog/agent-catalog' +import { isClipboardTextByteLengthOverLimit } from '../../../../shared/clipboard-text' type RankedAgent = { agent: AgentCatalogEntry diff --git a/src/renderer/src/lib/agent-favicon-assets.ts b/src/renderer/src/lib/agent-favicon-assets.ts deleted file mode 100644 index 718fbbdad6e..00000000000 --- a/src/renderer/src/lib/agent-favicon-assets.ts +++ /dev/null @@ -1,70 +0,0 @@ -import qoderUrl from '../../../shared/agent-icons/qoder.png?url' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' -import grokUrl from '../../../shared/agent-icons/grok.png?url' -import mimoCodeUrl from '../../../shared/agent-icons/mimo-code.png?url' -import anteUrl from '../../../shared/agent-icons/ante.png?url' -import traeUrl from '../../../shared/agent-icons/trae.png?url' -import primeAgentUrl from '../../../shared/agent-icons/prime-agent.png?url' -import geminiUrl from '../../../shared/agent-icons/gemini.png?url' -import antigravityUrl from '../../../shared/agent-icons/antigravity.png?url' -import gooseUrl from '../../../shared/agent-icons/goose.png?url' -import ampUrl from '../../../shared/agent-icons/amp.png?url' -import kiroUrl from '../../../shared/agent-icons/kiro.png?url' -import crushUrl from '../../../shared/agent-icons/crush.png?url' -import augUrl from '../../../shared/agent-icons/aug.png?url' -import autohandUrl from '../../../shared/agent-icons/autohand.png?url' -import clineUrl from '../../../shared/agent-icons/cline.png?url' -import freebuffUrl from '../../../shared/agent-icons/freebuff.png?url' -import codebuffUrl from '../../../shared/agent-icons/codebuff.png?url' -import commandCodeUrl from '../../../shared/agent-icons/command-code.png?url' -import continueUrl from '../../../shared/agent-icons/continue.png?url' -import cursorUrl from '../../../shared/agent-icons/cursor.png?url' -import kimiUrl from '../../../shared/agent-icons/kimi.png?url' -import mistralVibeUrl from '../../../shared/agent-icons/mistral-vibe.png?url' -import qwenCodeUrl from '../../../shared/agent-icons/qwen-code.png?url' -import rovoUrl from '../../../shared/agent-icons/rovo.png?url' -import hermesUrl from '../../../shared/agent-icons/hermes.png?url' -import devinUrl from '../../../shared/agent-icons/devin.png?url' -import museUrl from '../../../shared/agent-icons/muse.png?url' -import zcodeUrl from '../../../shared/agent-icons/zcode.png?url' -import openclawUrl from '../../../shared/agent-icons/openclaw.png?url' -import dshUrl from '../../../shared/agent-icons/dsh.png?url' -import jcodeUrl from '../../../shared/agent-icons/jcode.png?url' -import codebuddyUrl from '../../../shared/agent-icons/codebuddy.png?url' - -// Bundle favicons for offline/Google-blocked regions (#8451); shared/agent-icons also supplies mobile-agent-icon-assets.ts. -export const AGENT_FAVICON_ASSETS: Partial> = { - grok: grokUrl, - 'mimo-code': mimoCodeUrl, - ante: anteUrl, - trae: traeUrl, - 'prime-agent': primeAgentUrl, - qoder: qoderUrl, - 'qoder-cn': qoderUrl, - gemini: geminiUrl, - antigravity: antigravityUrl, - goose: gooseUrl, - amp: ampUrl, - kiro: kiroUrl, - crush: crushUrl, - aug: augUrl, - autohand: autohandUrl, - cline: clineUrl, - codebuff: codebuffUrl, - freebuff: freebuffUrl, - 'command-code': commandCodeUrl, - continue: continueUrl, - cursor: cursorUrl, - kimi: kimiUrl, - 'mistral-vibe': mistralVibeUrl, - 'qwen-code': qwenCodeUrl, - rovo: rovoUrl, - hermes: hermesUrl, - devin: devinUrl, - muse: museUrl, - dsh: dshUrl, - zcode: zcodeUrl, - openclaw: openclawUrl, - jcode: jcodeUrl, - codebuddy: codebuddyUrl -} diff --git a/src/renderer/src/lib/agent-session/accounts/agent-account-restart-startup.test.ts b/src/renderer/src/lib/agent-session/accounts/agent-account-restart-startup.test.ts index 5338f2f8dc3..4f163da4f5a 100644 --- a/src/renderer/src/lib/agent-session/accounts/agent-account-restart-startup.test.ts +++ b/src/renderer/src/lib/agent-session/accounts/agent-account-restart-startup.test.ts @@ -5,7 +5,7 @@ import { makePaneKey } from '../../../../../shared/workspace-layout/stable-pane- import { getDefaultSettings } from '../../../../../shared/constants' import type { ProjectExecutionRuntimeResolution } from '../../../../../shared/execution-host/project-execution-runtime' import type * as localPreflightContext from '@/lib/local-preflight-context' -import { resolveAgentResumeLaunchTarget } from '@/lib/agent-resume-launch-target' +import { resolveAgentResumeLaunchTarget } from '@/lib/agent-session/resume/agent-resume-launch-target' import { makeTerminalTab } from '@/store/terminals/terminal-row.test-fixture' import { makeWorktree } from '@/store/slices/worktrees/worktree.test-fixture' import { TEST_REPO } from '@/store/repos/repo.test-fixture' @@ -16,7 +16,7 @@ import { let projectRuntimeContext: ProjectExecutionRuntimeResolution | undefined -vi.mock('@/lib/agent-resume-launch-target', { spy: true }) +vi.mock('@/lib/agent-session/resume/agent-resume-launch-target', { spy: true }) vi.mock('@/lib/local-preflight-context', async (importOriginal) => ({ ...(await importOriginal()), diff --git a/src/renderer/src/lib/agent-session/accounts/agent-account-restart-startup.ts b/src/renderer/src/lib/agent-session/accounts/agent-account-restart-startup.ts index 94e06a73411..de459f5ae58 100644 --- a/src/renderer/src/lib/agent-session/accounts/agent-account-restart-startup.ts +++ b/src/renderer/src/lib/agent-session/accounts/agent-account-restart-startup.ts @@ -8,7 +8,7 @@ import { resolveSshHostReportedPlatform, resolveAgentResumeLaunchTarget, type AgentResumeLaunchTarget -} from '@/lib/agent-resume-launch-target' +} from '@/lib/agent-session/resume/agent-resume-launch-target' import { getExecutionHostIdForWorktree } from '@/lib/workspace/ownership/worktree-runtime-owner' import { runtimeEnvironmentIdUnlessTwin } from '@/lib/workspace/ownership/resolve-owner' import { getLocalProjectExecutionRuntimeContext } from '@/lib/local-preflight-context' diff --git a/src/renderer/src/lib/agent-session-continuation.ts b/src/renderer/src/lib/agent-session/context/agent-session-continuation.ts similarity index 95% rename from src/renderer/src/lib/agent-session-continuation.ts rename to src/renderer/src/lib/agent-session/context/agent-session-continuation.ts index 6aa59263e40..a365e4d1b92 100644 --- a/src/renderer/src/lib/agent-session-continuation.ts +++ b/src/renderer/src/lib/agent-session/context/agent-session-continuation.ts @@ -1,7 +1,7 @@ -import { splitOpenCodeSqliteCandidate } from '../../../shared/opencode-sqlite-session-path' -import { buildBoundedSessionTranscript } from '@/lib/agent-session-fork-context' -import type { LaunchSource } from '../../../shared/telemetry-events' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' +import { splitOpenCodeSqliteCandidate } from '../../../../../shared/opencode-sqlite-session-path' +import { buildBoundedSessionTranscript } from '@/lib/agent-session/context/agent-session-fork-context' +import type { LaunchSource } from '../../../../../shared/telemetry-property-schemas' +import type { TuiAgent } from '../../../../../shared/agent-launch/catalog/tui-agent' export type AgentSessionContinuationContextMode = 'focused' | 'full' diff --git a/src/renderer/src/lib/agent-session-fork-context.ts b/src/renderer/src/lib/agent-session/context/agent-session-fork-context.ts similarity index 97% rename from src/renderer/src/lib/agent-session-fork-context.ts rename to src/renderer/src/lib/agent-session/context/agent-session-fork-context.ts index 650c3d153ad..5837113f3f5 100644 --- a/src/renderer/src/lib/agent-session-fork-context.ts +++ b/src/renderer/src/lib/agent-session/context/agent-session-fork-context.ts @@ -1,4 +1,4 @@ -import { trimAgentSessionContext } from '../../../shared/agent-session/requests/agent-session-context-budget' +import { trimAgentSessionContext } from '../../../../../shared/agent-session/requests/agent-session-context-budget' const MAX_FORK_CONTEXT_CHARS = 36_000 const MAX_FORK_CAPTURE_SANITIZE_CHARS = MAX_FORK_CONTEXT_CHARS * 4 const ESCAPE_CODE = 27 diff --git a/src/renderer/src/lib/copy-agent-session-context.ts b/src/renderer/src/lib/agent-session/context/copy-agent-session-context.ts similarity index 100% rename from src/renderer/src/lib/copy-agent-session-context.ts rename to src/renderer/src/lib/agent-session/context/copy-agent-session-context.ts diff --git a/src/renderer/src/lib/agent-session/launch/continuation/launch-agent-session-continuation.ts b/src/renderer/src/lib/agent-session/launch/continuation/launch-agent-session-continuation.ts index 5c4f1f7ceb2..86cfa89a60c 100644 --- a/src/renderer/src/lib/agent-session/launch/continuation/launch-agent-session-continuation.ts +++ b/src/renderer/src/lib/agent-session/launch/continuation/launch-agent-session-continuation.ts @@ -1,6 +1,6 @@ import { toast } from 'sonner' -import { getAgentLabel } from '@/lib/agent-catalog' -import { ensureDetectedAgentsForWorktree } from '@/lib/agent-detection-target-inventory' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' +import { ensureDetectedAgentsForWorktree } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { launchAgentInNewTab } from '@/lib/agent-session/launch/new-tab/launch-agent-in-new-tab' import { newAgentLaunchRequestId } from '@/lib/agent-session/launch/routing/agent-launch-request-id' import { useAppStore } from '@/store/index' @@ -17,7 +17,7 @@ import { adoptAgentSessionLaunchVerdict, planAgentSessionLaunch } from '@/lib/agent-session/launch/routing/agent-session-launch-plan' -import type { AgentLaunchChoice } from '@/lib/agent-menu-selection' +import type { AgentLaunchChoice } from '@/lib/agent-session/launch/routing/agent-menu-selection' import type { AgentLaunchRoute } from '@/lib/agent-session/launch/routing/agent-launch-routing' import { translate } from '@/i18n/i18n' import { resolveWorktreeDisplayName } from '@/lib/worktree-default-display-name' diff --git a/src/renderer/src/lib/agent-launch-failure.ts b/src/renderer/src/lib/agent-session/launch/failure/agent-launch-failure.ts similarity index 86% rename from src/renderer/src/lib/agent-launch-failure.ts rename to src/renderer/src/lib/agent-session/launch/failure/agent-launch-failure.ts index 180933738bf..c8b635b8639 100644 --- a/src/renderer/src/lib/agent-launch-failure.ts +++ b/src/renderer/src/lib/agent-session/launch/failure/agent-launch-failure.ts @@ -1,8 +1,8 @@ import { toast } from 'sonner' import { translate } from '@/i18n/i18n' -import { getAgentLabel } from '@/lib/agent-catalog' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' -import type { ExecutionHostPlatformFact } from '../runtime/hosts/platform/execution-host-platform-fact' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' +import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' +import type { ExecutionHostPlatformFact } from '../../../../runtime/hosts/platform/execution-host-platform-fact' type Recovery = Extract['recovery'] diff --git a/src/renderer/src/lib/agent-detection-target-inventory.ts b/src/renderer/src/lib/agent-session/launch/inventory/agent-detection-target-inventory.ts similarity index 93% rename from src/renderer/src/lib/agent-detection-target-inventory.ts rename to src/renderer/src/lib/agent-session/launch/inventory/agent-detection-target-inventory.ts index 3009c221e1f..0e1b3e5c3f8 100644 --- a/src/renderer/src/lib/agent-detection-target-inventory.ts +++ b/src/renderer/src/lib/agent-session/launch/inventory/agent-detection-target-inventory.ts @@ -1,9 +1,10 @@ import { callRuntimeRpc } from '@/runtime/rpc/calls/runtime-rpc-call' import { runtimeEnvironmentSupportsCapability } from '@/runtime/rpc/compatibility/runtime-capability-proof' import { ensureLocalRuntimeCapabilities } from '@/runtime/hosts/capabilities/local-runtime-capabilities' -import { PREFLIGHT_PROJECT_LAUNCH_CONTEXT_RUNTIME_CAPABILITY } from '../../../shared/protocol-version' -import type { ProjectLaunchContext } from '../../../shared/rpc-contract/preflight-params' -import type { RuntimeClientTarget } from '../../../shared/runtime-client-target' +import '../../../../../../shared/delegated-mobile-device-contract' +import { PREFLIGHT_PROJECT_LAUNCH_CONTEXT_RUNTIME_CAPABILITY } from '../../../../../../shared/preflight-runtime-capabilities' +import type { ProjectLaunchContext } from '../../../../../../shared/rpc-contract/preflight-params' +import type { RuntimeClientTarget } from '../../../../../../shared/runtime-client-target' import type { AppState } from '@/store/types' import type { AgentDetectionTarget } from '@/hooks/useDetectedAgents' import { @@ -12,8 +13,11 @@ import { type AgentDetectionOwnerState } from '@/hooks/useAgentDetectionTarget' import { getRuntimeAgentInventoryKey } from '@/store/slices/agent-inventory/runtime-agent-inventory-key' -import { getRepoExecutionHostId, parseExecutionHostId } from '../../../shared/execution-host' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' +import { + getRepoExecutionHostId, + parseExecutionHostId +} from '../../../../../../shared/execution-host' +import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' type DetectionReadState = Pick< AppState, diff --git a/src/renderer/src/lib/agent-session/launch/native-chat-provider-choice.test.tsx b/src/renderer/src/lib/agent-session/launch/native-chat-provider-choice.test.tsx index 815e93a2caf..353a8a3d079 100644 --- a/src/renderer/src/lib/agent-session/launch/native-chat-provider-choice.test.tsx +++ b/src/renderer/src/lib/agent-session/launch/native-chat-provider-choice.test.tsx @@ -40,7 +40,7 @@ vi.mock('../../../store/index', () => ({ getState: () => store }) })) -vi.mock('@/lib/chat-provider-agents', () => ({ +vi.mock('@/runtime/native-chat/agent-catalogs/chat-provider-agents', () => ({ chatProviderAgents: () => ['claude', 'codex', 'antigravity'], useHostStructuredAgentsVersion: () => 0 })) diff --git a/src/renderer/src/lib/agent-session/launch/native-chat-provider-choice.ts b/src/renderer/src/lib/agent-session/launch/native-chat-provider-choice.ts index 0a3d7dc2351..6dbb52e8984 100644 --- a/src/renderer/src/lib/agent-session/launch/native-chat-provider-choice.ts +++ b/src/renderer/src/lib/agent-session/launch/native-chat-provider-choice.ts @@ -9,7 +9,7 @@ import { import { nativeChatPreferenceFor } from '../../../../../shared/structured-native-chat-launch-route' import type { TuiAgent } from '../../../../../shared/agent-launch/catalog/tui-agent' import { isTuiAgentEnabled } from '../../../../../shared/agent-launch/catalog/tui-agent-selection' -import { chatProviderAgents } from '@/lib/chat-provider-agents' +import { chatProviderAgents } from '@/runtime/native-chat/agent-catalogs/chat-provider-agents' import { useAppStore } from '../../../store/index' import { createAgentSettingsUpdateQueue } from './agent-settings-update-queue' diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/agent-launch-caller-prompt-transport.test.ts b/src/renderer/src/lib/agent-session/launch/new-tab/agent-launch-caller-prompt-transport.test.ts index b331c0db77e..5132d1280e1 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/agent-launch-caller-prompt-transport.test.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/agent-launch-caller-prompt-transport.test.ts @@ -50,10 +50,10 @@ vi.mock('../../../../../../shared/agent-kind', async (importOriginal) => ({ vi.mock('../../../../../../shared/native-chat/input/native-chat-session-option-cache', () => ({ seedNativeChatAppliedSessionOptions: vi.fn() })) -vi.mock('@/lib/agent-paste-draft', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-paste-draft', () => ({ pasteDraftWhenAgentReady: mockPasteDraftWhenAgentReady })) -vi.mock('@/lib/agent-ready-wait', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-ready-wait', () => ({ waitForAgentReady: vi.fn(async () => ({ ready: true, reason: 'foreground-match' })) })) vi.mock('@/runtime/hosts/capabilities/local-runtime-capabilities', () => ({ diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/agent-launch-caller-routing.test.ts b/src/renderer/src/lib/agent-session/launch/new-tab/agent-launch-caller-routing.test.ts index e05b76b008e..ac27d959f1e 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/agent-launch-caller-routing.test.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/agent-launch-caller-routing.test.ts @@ -1,4 +1,4 @@ -import { nonRefusedAgentLaunch } from '@/lib/agent-tab-launch-outcome.test-fixture' +import { nonRefusedAgentLaunch } from '@/lib/agent-session/launch/new-tab/agent-tab-launch-outcome.test-fixture' import { EVERY_AGENT_CHAT } from '../../../../../../shared/native-chat/every-agent-chat.test-fixture' import { beforeEach, describe, expect, it, vi } from 'vitest' import { @@ -63,8 +63,10 @@ vi.mock('../../../../../../shared/agent-kind', async (importOriginal) => ({ vi.mock('../../../../../../shared/native-chat/input/native-chat-session-option-cache', () => ({ seedNativeChatAppliedSessionOptions: vi.fn() })) -vi.mock('@/lib/agent-paste-draft', () => ({ pasteDraftWhenAgentReady: vi.fn(async () => true) })) -vi.mock('@/lib/agent-ready-wait', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-paste-draft', () => ({ + pasteDraftWhenAgentReady: vi.fn(async () => true) +})) +vi.mock('@/lib/agent-session/messaging/paste/agent-ready-wait', () => ({ waitForAgentReady: vi.fn(async () => ({ ready: true, reason: 'foreground-match' })) })) // Mock structured execution while retaining real route selection; callers must still reach the correct surface. diff --git a/src/renderer/src/lib/agent-tab-launch-outcome.test-fixture.ts b/src/renderer/src/lib/agent-session/launch/new-tab/agent-tab-launch-outcome.test-fixture.ts similarity index 65% rename from src/renderer/src/lib/agent-tab-launch-outcome.test-fixture.ts rename to src/renderer/src/lib/agent-session/launch/new-tab/agent-tab-launch-outcome.test-fixture.ts index a73ac1d3408..c2640c42c58 100644 --- a/src/renderer/src/lib/agent-tab-launch-outcome.test-fixture.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/agent-tab-launch-outcome.test-fixture.ts @@ -1,4 +1,4 @@ -import type { AgentTabLaunchOutcome } from './agent-session/launch/new-tab/launch-agent-in-new-tab-host-agents' +import type { AgentTabLaunchOutcome } from './launch-agent-in-new-tab-host-agents' export function nonRefusedAgentLaunch(outcome: AgentTabLaunchOutcome | undefined) { if (outcome && 'refused' in outcome) { diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-main-surface.test.ts b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-main-surface.test.ts index 7e2f654fc3f..c558d5dff24 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-main-surface.test.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-main-surface.test.ts @@ -1,4 +1,4 @@ -import { nonRefusedAgentLaunch } from '@/lib/agent-tab-launch-outcome.test-fixture' +import { nonRefusedAgentLaunch } from '@/lib/agent-session/launch/new-tab/agent-tab-launch-outcome.test-fixture' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { FLOATING_TERMINAL_WORKTREE_ID, diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-test-fixture.ts b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-test-fixture.ts index 224a8a839a4..db515cc375b 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-test-fixture.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-test-fixture.ts @@ -2,8 +2,8 @@ import { settleAgentLaunchPaneStart } from '../pane/agent-launch-pane-start' import { beforeEach, vi } from 'vitest' import { setLocalRuntimeCapabilitiesForTests } from '@/runtime/hosts/capabilities/local-runtime-capabilities' import type { AppState } from '@/store/types' -import type { pasteDraftWhenAgentReady } from '../../../agent-paste-draft' -import type { waitForAgentReady } from '../../../agent-ready-wait' +import type { pasteDraftWhenAgentReady } from '../../messaging/paste/agent-paste-draft' +import type { waitForAgentReady } from '../../messaging/paste/agent-ready-wait' import type { track } from '../../../telemetry' import type { toast } from 'sonner' import type { createWebRuntimeSessionTerminal } from '@/runtime/hosted-terminals/creation/web-runtime-terminal-creation' @@ -139,11 +139,11 @@ vi.mock('@/components/tab-bar/reconcile-order', () => ({ ) })) -vi.mock('@/lib/agent-paste-draft', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-paste-draft', () => ({ pasteDraftWhenAgentReady: mockPasteDraftWhenAgentReady })) -vi.mock('@/lib/agent-ready-wait', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-ready-wait', () => ({ waitForAgentReady: mockWaitForAgentReady })) diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-windows-quoting.test.ts b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-windows-quoting.test.ts index d93bf6dab8b..efa0eb55487 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-windows-quoting.test.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab-windows-quoting.test.ts @@ -94,7 +94,7 @@ vi.mock('@/components/tab-bar/reconcile-order', () => ({ ) })) -vi.mock('@/lib/agent-paste-draft', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-paste-draft', () => ({ pasteDraftWhenAgentReady: mockPasteDraftWhenAgentReady })) diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.test-fixture.ts b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.test-fixture.ts index 72d533ca098..6717f9308f6 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.test-fixture.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.test-fixture.ts @@ -124,11 +124,11 @@ vi.mock('@/components/tab-bar/reconcile-order', () => ({ ) })) -vi.mock('@/lib/agent-paste-draft', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-paste-draft', () => ({ pasteDraftWhenAgentReady: mockPasteDraftWhenAgentReady })) -vi.mock('@/lib/agent-ready-wait', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-ready-wait', () => ({ waitForAgentReady: mockWaitForAgentReady })) diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.test.ts b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.test.ts index 60287d34d0f..a0160a1175a 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.test.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.test.ts @@ -1,4 +1,4 @@ -import { nonRefusedAgentLaunch } from '@/lib/agent-tab-launch-outcome.test-fixture' +import { nonRefusedAgentLaunch } from '@/lib/agent-session/launch/new-tab/agent-tab-launch-outcome.test-fixture' import { afterEach, describe, expect, it, vi } from 'vitest' import { mockCreateTab, diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.ts b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.ts index a68b478d53f..638ea12394e 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-in-new-tab.ts @@ -10,7 +10,7 @@ import { invalidTerminalArgsMessage } from '../../../workspace/creation/work-ite import { agentLaunchCheckSettingsMessage, notifyAgentLaunchFailure -} from '@/lib/agent-launch-failure' +} from '@/lib/agent-session/launch/failure/agent-launch-failure' import { planLaunchAgentStartupPrompt } from '@/lib/agent-session/launch/prompt/launch-agent-startup-prompt-plan' import { persistAgentLaunchTabOrder } from '@/lib/agent-session/launch/pane/launch-agent-tab-order' import '@/lib/telemetry' diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-new-tab-host-route-readiness.test.ts b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-new-tab-host-route-readiness.test.ts index d3e2c681736..5ce864e3fc6 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-new-tab-host-route-readiness.test.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-new-tab-host-route-readiness.test.ts @@ -61,7 +61,7 @@ vi.mock('@/runtime/hosted-terminals/input/runtime-terminal-verified-input', () = vi.mock('@/runtime/hosted-terminals/streams/runtime-terminal-data-subscription', () => ({ subscribeToRuntimeTerminalData: vi.fn() })) -vi.mock('../../../agent-ready-wait', () => ({ +vi.mock('../../messaging/paste/agent-ready-wait', () => ({ waitForAgentReady: vi.fn(async () => ({ ready: false })) })) vi.mock('@/lib/telemetry', () => ({ track: vi.fn(), tuiAgentToAgentKind: mockLaunchAgentKind })) @@ -238,7 +238,8 @@ describe('an AI button whose agent is ready before the host answers', () => { expect(testState.writes.filter(({ data }) => data.includes('task'))).toHaveLength(1) }) it('does not paste into a cancelled hosted launch after its composer becomes ready', async () => { - const { pasteDraftWhenAgentReady } = await import('@/lib/agent-paste-draft') + const { pasteDraftWhenAgentReady } = + await import('@/lib/agent-session/messaging/paste/agent-paste-draft') let cancelled = false const delivery = pasteDraftWhenAgentReady({ tabId: TAB, diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-structured-chat-test-fixture.ts b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-structured-chat-test-fixture.ts index 413a7ea81f8..30980cc52ba 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-structured-chat-test-fixture.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-structured-chat-test-fixture.ts @@ -11,8 +11,8 @@ import { createGlobalSettingsFixture } from '../../../../../../shared/global-set import type { GlobalSettings } from '../../../../../../shared/global-settings-types' import { registerStructuredSelectionCatalogStore } from '../../options/structured-agent-session-selection-controller' import type { AppState } from '@/store/types' -import type { pasteDraftWhenAgentReady } from '../../../agent-paste-draft' -import type { waitForAgentReady } from '../../../agent-ready-wait' +import type { pasteDraftWhenAgentReady } from '../../messaging/paste/agent-paste-draft' +import type { waitForAgentReady } from '../../messaging/paste/agent-ready-wait' import type { createStructuredAgentSessionLaunchIntent as create } from '../../../launch-structured-agent-session' import type { launchStructuredAgentSession as launch } from '../structured-agent-session-launch-create-call' import type { refreshLocalStructuredSessionTabs as refreshTabs } from '@/runtime/local-structured-session-tabs-sync/inventory-refresh' @@ -95,10 +95,12 @@ vi.mock('@/runtime/workspace-layout/frames/runtime-layout-client', async (origin ) vi.mock('sonner', () => ({ toast: { message: vi.fn(), error: mockToastError } })) vi.mock('@/components/tab-bar/reconcile-order', () => ({ reconcileTabOrder: vi.fn(() => []) })) -vi.mock('@/lib/agent-paste-draft', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-paste-draft', () => ({ pasteDraftWhenAgentReady: mockPasteDraftWhenAgentReady })) -vi.mock('@/lib/agent-ready-wait', () => ({ waitForAgentReady: mockWaitForAgentReady })) +vi.mock('@/lib/agent-session/messaging/paste/agent-ready-wait', () => ({ + waitForAgentReady: mockWaitForAgentReady +})) vi.mock('@/lib/telemetry', () => ({ track: vi.fn(), tuiAgentToAgentKind: mockLaunchAgentKind diff --git a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-tab-refusal.ts b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-tab-refusal.ts index 13a73aa6a6c..576b4d1090e 100644 --- a/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-tab-refusal.ts +++ b/src/renderer/src/lib/agent-session/launch/new-tab/launch-agent-tab-refusal.ts @@ -1,4 +1,7 @@ -import { agentLaunchRecoveryMessage, notifyAgentLaunchFailure } from '@/lib/agent-launch-failure' +import { + agentLaunchRecoveryMessage, + notifyAgentLaunchFailure +} from '@/lib/agent-session/launch/failure/agent-launch-failure' import type { ExecutionHostPlatformFact } from '@/runtime/hosts/platform/execution-host-platform-fact' import type { LaunchAgentInNewTabArgs } from './launch-agent-in-new-tab-args' import type { AgentTabLaunchOutcome } from './launch-agent-in-new-tab-host-agents' diff --git a/src/renderer/src/lib/agent-session/launch/pane/agent-launch-pane-verdict-application.test.ts b/src/renderer/src/lib/agent-session/launch/pane/agent-launch-pane-verdict-application.test.ts index b1fe28e345d..e7cfc7dad8a 100644 --- a/src/renderer/src/lib/agent-session/launch/pane/agent-launch-pane-verdict-application.test.ts +++ b/src/renderer/src/lib/agent-session/launch/pane/agent-launch-pane-verdict-application.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { AgentLaunchPaneVerdict } from '../../../../../../shared/agent-launch/contracts/agent-launch-pane-verdict' import { createTabsSliceMockApi } from '../../../../store/slices/tabs/tabs-slice-test-harness' import { createTestStore } from '../../../../store/testing/app-store-test-fixture' @@ -12,7 +12,7 @@ vi.mock('@/runtime/rpc/calls/runtime-rpc-call', async (importOriginal) => ) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => ({ +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => ({ ...(await importOriginal()), detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) })) diff --git a/src/renderer/src/lib/agent-session/launch/pane/agent-launch-tab-main-written.test.ts b/src/renderer/src/lib/agent-session/launch/pane/agent-launch-tab-main-written.test.ts index a0f39e6d9d9..9433b300158 100644 --- a/src/renderer/src/lib/agent-session/launch/pane/agent-launch-tab-main-written.test.ts +++ b/src/renderer/src/lib/agent-session/launch/pane/agent-launch-tab-main-written.test.ts @@ -1,11 +1,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { AgentLaunchTabPublishRequest } from '../../../../../../shared/agent-launch/contracts/agent-launch-tab-publication' import { createTabsSliceMockApi } from '../../../../store/slices/tabs/tabs-slice-test-harness' import { createTestStore } from '../../../../store/testing/app-store-test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => ({ +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => ({ ...(await importOriginal()), detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) })) diff --git a/src/renderer/src/lib/agent-session/launch/pane/agent-launch-tab-publication.test.ts b/src/renderer/src/lib/agent-session/launch/pane/agent-launch-tab-publication.test.ts index 8146a4edae1..37dc23030bf 100644 --- a/src/renderer/src/lib/agent-session/launch/pane/agent-launch-tab-publication.test.ts +++ b/src/renderer/src/lib/agent-session/launch/pane/agent-launch-tab-publication.test.ts @@ -1,11 +1,11 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { AgentLaunchTabPublishRequest } from '../../../../../../shared/agent-launch/contracts/agent-launch-tab-publication' import { createTabsSliceMockApi } from '../../../../store/slices/tabs/tabs-slice-test-harness' import { createTestStore } from '../../../../store/testing/app-store-test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => ({ +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => ({ ...(await importOriginal()), detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) })) diff --git a/src/renderer/src/lib/agent-session/launch/pane/agent-launch-through-host.test.ts b/src/renderer/src/lib/agent-session/launch/pane/agent-launch-through-host.test.ts index 477ddad7c6b..7c73959c67a 100644 --- a/src/renderer/src/lib/agent-session/launch/pane/agent-launch-through-host.test.ts +++ b/src/renderer/src/lib/agent-session/launch/pane/agent-launch-through-host.test.ts @@ -1,10 +1,10 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTabsSliceMockApi } from '../../../../store/slices/tabs/tabs-slice-test-harness' import { createTestStore } from '../../../../store/testing/app-store-test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => ({ +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => ({ ...(await importOriginal()), detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) })) diff --git a/src/renderer/src/lib/agent-session/launch/prompt/agent-launch-prompt-delivery.ts b/src/renderer/src/lib/agent-session/launch/prompt/agent-launch-prompt-delivery.ts index dfc33660d6b..c57947ab5b4 100644 --- a/src/renderer/src/lib/agent-session/launch/prompt/agent-launch-prompt-delivery.ts +++ b/src/renderer/src/lib/agent-session/launch/prompt/agent-launch-prompt-delivery.ts @@ -1,5 +1,5 @@ -import { agentDeliversDraftViaNativePrefill } from '@/lib/agent-native-draft-prefill' -import { pasteDraftWhenAgentReady } from '@/lib/agent-paste-draft' +import { agentDeliversDraftViaNativePrefill } from '@/lib/agent-session/messaging/paste/agent-native-draft-prefill' +import { pasteDraftWhenAgentReady } from '@/lib/agent-session/messaging/paste/agent-paste-draft' import { canMirrorLaunchDraftToNativeChat } from '../../../../../../shared/native-chat/input/native-chat-launch-draft-mirrorability' import { isNativeChatSupportedAgent } from '../../../../../../shared/native-chat/native-chat-agent-support' import { useAppStore } from '@/store/index' diff --git a/src/renderer/src/lib/agent-launch-prompt-failure-notice.ts b/src/renderer/src/lib/agent-session/launch/prompt/agent-launch-prompt-failure-notice.ts similarity index 79% rename from src/renderer/src/lib/agent-launch-prompt-failure-notice.ts rename to src/renderer/src/lib/agent-session/launch/prompt/agent-launch-prompt-failure-notice.ts index 5fb6fd9f664..0117a018f6b 100644 --- a/src/renderer/src/lib/agent-launch-prompt-failure-notice.ts +++ b/src/renderer/src/lib/agent-session/launch/prompt/agent-launch-prompt-failure-notice.ts @@ -1,7 +1,7 @@ import { toast } from 'sonner' import { translate } from '@/i18n/i18n' -import { structuredAgentLabel } from './agent-session/launch/structured-agent-session-launch-label' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' +import { structuredAgentLabel } from '../structured-agent-session-launch-label' +import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' export function notifyAgentLaunchPromptNotSent(agent: TuiAgent, content?: string): void { const message = translate( diff --git a/src/renderer/src/lib/agent-menu-selection.ts b/src/renderer/src/lib/agent-session/launch/routing/agent-menu-selection.ts similarity index 78% rename from src/renderer/src/lib/agent-menu-selection.ts rename to src/renderer/src/lib/agent-session/launch/routing/agent-menu-selection.ts index 6a308167ead..e4a2a403e36 100644 --- a/src/renderer/src/lib/agent-menu-selection.ts +++ b/src/renderer/src/lib/agent-session/launch/routing/agent-menu-selection.ts @@ -1,12 +1,12 @@ -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' -import type { ExecutionHostId } from '../../../shared/execution-host' -import { nativeChatPreferenceFor } from '../../../shared/structured-native-chat-launch-route' -import type { AgentLaunchSurface } from './agent-session/launch/routing/agent-session-launch-plan' -import type { AgentLaunchRoute } from './agent-session/launch/routing/agent-launch-routing' +import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' +import type { ExecutionHostId } from '../../../../../../shared/execution-host' +import { nativeChatPreferenceFor } from '../../../../../../shared/structured-native-chat-launch-route' +import type { AgentLaunchSurface } from './agent-session-launch-plan' +import type { AgentLaunchRoute } from './agent-launch-routing' import type { HostChatAnswer, NewTabAgentMenuSettings -} from '../../../shared/agent-launch/picker/agent-launch-picker-rows' +} from '../../../../../../shared/agent-launch/picker/agent-launch-picker-rows' /** Accepted renderer intent; route and explicitness remain distinct through admission. */ export type AgentLaunchChoice = { diff --git a/src/renderer/src/lib/agent-session/launch/routing/agent-session-launch-plan.ts b/src/renderer/src/lib/agent-session/launch/routing/agent-session-launch-plan.ts index 9bcee4a6731..de3c6094008 100644 --- a/src/renderer/src/lib/agent-session/launch/routing/agent-session-launch-plan.ts +++ b/src/renderer/src/lib/agent-session/launch/routing/agent-session-launch-plan.ts @@ -1,4 +1,7 @@ -import { notifyAgentLaunchFailure, agentLaunchRecoveryMessage } from '@/lib/agent-launch-failure' +import { + notifyAgentLaunchFailure, + agentLaunchRecoveryMessage +} from '@/lib/agent-session/launch/failure/agent-launch-failure' import type { StructuredLaunchSurfaceAddress } from '../structured-agent-session-launch-record' import type { StructuredAgentSessionForkSource, diff --git a/src/renderer/src/lib/new-tab-agent-menu-rows.ts b/src/renderer/src/lib/agent-session/launch/routing/new-tab-agent-menu-rows.ts similarity index 81% rename from src/renderer/src/lib/new-tab-agent-menu-rows.ts rename to src/renderer/src/lib/agent-session/launch/routing/new-tab-agent-menu-rows.ts index 8450cc7f442..738f6c8acaf 100644 --- a/src/renderer/src/lib/new-tab-agent-menu-rows.ts +++ b/src/renderer/src/lib/agent-session/launch/routing/new-tab-agent-menu-rows.ts @@ -2,8 +2,8 @@ import { structuredAgentLaunchSupport, type AgentLaunchRoutingInput } from '@/lib/agent-session/launch/routing/agent-launch-routing' -import { STRUCTURED_AGENT_SESSION_REGISTERED_AGENTS_RUNTIME_CAPABILITY as CATALOG } from '../../../shared/agent-session/structured-agent-session-surface-capabilities' -import type { HostChatAnswer } from '../../../shared/agent-launch/picker/agent-launch-picker-rows' +import { STRUCTURED_AGENT_SESSION_REGISTERED_AGENTS_RUNTIME_CAPABILITY as CATALOG } from '../../../../../../shared/agent-session/structured-agent-session-surface-capabilities' +import type { HostChatAnswer } from '../../../../../../shared/agent-launch/picker/agent-launch-picker-rows' export function hostChatAnswer(input: AgentLaunchRoutingInput): HostChatAnswer { const support = structuredAgentLaunchSupport(input) diff --git a/src/renderer/src/lib/agent-tab-shortcuts.ts b/src/renderer/src/lib/agent-session/launch/shortcuts/agent-tab-shortcuts.ts similarity index 86% rename from src/renderer/src/lib/agent-tab-shortcuts.ts rename to src/renderer/src/lib/agent-session/launch/shortcuts/agent-tab-shortcuts.ts index 7b5b2b046d3..7819d763499 100644 --- a/src/renderer/src/lib/agent-tab-shortcuts.ts +++ b/src/renderer/src/lib/agent-session/launch/shortcuts/agent-tab-shortcuts.ts @@ -1,17 +1,17 @@ -import { acquireAgentLaunchChoices } from './host-chat-program-acquisition' -import { - agentTabActionId, - type AgentTabActionId, - type KeybindingOverrides -} from '../../../shared/keybindings' -import { ALL_TUI_AGENTS } from '../../../shared/agent-launch/catalog/tui-agent-display-names' +import { acquireAgentLaunchChoices } from '../../../host-chat-program-acquisition' +import { agentTabActionId } from '../../../../../../shared/keybindings/definitions' +import type { + AgentTabActionId, + KeybindingOverrides +} from '../../../../../../shared/keybindings/types' +import { ALL_TUI_AGENTS } from '../../../../../../shared/agent-launch/catalog/tui-agent-display-names' import { normalizeDisabledTuiAgents, pickTuiAgent -} from '../../../shared/agent-launch/catalog/tui-agent-selection' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' +} from '../../../../../../shared/agent-launch/catalog/tui-agent-selection' +import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import type { AppState } from '@/store/types' -import { loadDetectedAgentsForWorktree } from '@/lib/agent-detection-target-inventory' +import { loadDetectedAgentsForWorktree } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { type AgentLaunchRouteStore, type ProspectiveWorkspace, diff --git a/src/renderer/src/lib/agent-startup-delayed-delivery-perf.test.ts b/src/renderer/src/lib/agent-session/launch/startup/agent-startup-delayed-delivery-perf.test.ts similarity index 98% rename from src/renderer/src/lib/agent-startup-delayed-delivery-perf.test.ts rename to src/renderer/src/lib/agent-session/launch/startup/agent-startup-delayed-delivery-perf.test.ts index 38ba53079f8..48e3eff6c29 100644 --- a/src/renderer/src/lib/agent-startup-delayed-delivery-perf.test.ts +++ b/src/renderer/src/lib/agent-session/launch/startup/agent-startup-delayed-delivery-perf.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { useAppStore } from '@/store' +import { useAppStore } from '@/store/index' import { queuePendingAgentStartupDelivery, resetAgentStartupDelayedDeliveryForTests diff --git a/src/renderer/src/lib/agent-startup-delayed-delivery.ts b/src/renderer/src/lib/agent-session/launch/startup/agent-startup-delayed-delivery.ts similarity index 97% rename from src/renderer/src/lib/agent-startup-delayed-delivery.ts rename to src/renderer/src/lib/agent-session/launch/startup/agent-startup-delayed-delivery.ts index 2637ef3b4b5..793caa5df31 100644 --- a/src/renderer/src/lib/agent-startup-delayed-delivery.ts +++ b/src/renderer/src/lib/agent-session/launch/startup/agent-startup-delayed-delivery.ts @@ -1,6 +1,6 @@ -import { useAppStore } from '@/store' -import type { AgentStartupPlan } from '../../../shared/agent-launch/startup/tui-agent-startup' -import { parsePaneKey } from '../../../shared/workspace-layout/stable-pane-id' +import { useAppStore } from '@/store/index' +import type { AgentStartupPlan } from '../../../../../../shared/agent-launch/startup/tui-agent-startup' +import { parsePaneKey } from '../../../../../../shared/workspace-layout/stable-pane-id' import { agentStartupDeliveryKey as deliveryKey, clearConsumedAgentStartupDeliveriesForTests, diff --git a/src/renderer/src/lib/agent-startup-delivery-guards.ts b/src/renderer/src/lib/agent-session/launch/startup/agent-startup-delivery-guards.ts similarity index 100% rename from src/renderer/src/lib/agent-startup-delivery-guards.ts rename to src/renderer/src/lib/agent-session/launch/startup/agent-startup-delivery-guards.ts diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-admission.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-admission.ts index e58cc14b796..2d320739e19 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-admission.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-admission.ts @@ -28,7 +28,7 @@ import type { RuntimeClientTarget } from '../../../../../shared/runtime-client-t import { toRuntimeWorktreeSelector } from '@/runtime/rpc/targets/runtime-worktree-selector' import { readStructuredChatHostPermissionVerdict } from '@/runtime/native-chat/host-capabilities/structured-chat-host-permission' import { notifyHostPermissionRefused } from '@/lib/agent-session/launch/structured-agent-session-launch-permission-notice' -import { readAgentInventoryForTarget } from '@/lib/agent-detection-target-inventory' +import { readAgentInventoryForTarget } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import type { WebRuntimeTerminalCreateOutcome } from '@/runtime/hosted-terminals/creation/terminal-create-contracts' import { structuredLaunchTerminalFromOutcome } from './structured-launch-terminal-outcome' diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-after-failure.test.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-after-failure.test.ts index a0750936eff..c95c13a7cf5 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-after-failure.test.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-after-failure.test.ts @@ -81,7 +81,7 @@ vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, fallback: string) => fallback })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: () => 'Codex', getAgentCatalog: () => [{ id: 'codex', label: 'Codex' }] })) diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-close-race.test.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-close-race.test.ts index 91b9da02928..1889792d8bf 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-close-race.test.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-close-race.test.ts @@ -100,7 +100,7 @@ vi.mock('@/i18n/i18n', () => ({ fallback.replace('{{value0}}', options?.value0 ?? '') })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: (agent: string) => (agent === 'codex' ? 'Codex' : 'Claude'), getAgentCatalog: () => [ { id: 'claude', label: 'Claude' }, diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-completion.test-fixture.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-completion.test-fixture.ts index 86a41c25e44..aa4daef61c9 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-completion.test-fixture.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-completion.test-fixture.ts @@ -1,5 +1,5 @@ import { expect, it, vi } from 'vitest' -import { sendMessageToAgent } from '../../agent-message-send' +import { sendMessageToAgent } from '../messaging/agent-message-send' import { SendParams } from '../../../../../shared/rpc-contract/structured-agent-session-params' import type { Tab } from '../../../../../shared/tab-types' import { beginStructuredAgentLaunchSettlement } from './continuation/structured-agent-launch-settlement' diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-different-request.test.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-different-request.test.ts index 2617313924c..abf123e89b8 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-different-request.test.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-different-request.test.ts @@ -85,7 +85,7 @@ vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, fallback: string) => fallback })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: () => 'Codex', getAgentCatalog: () => [{ id: 'codex', label: 'Codex' }] })) diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-exited-owner.test.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-exited-owner.test.ts index fdb7138e1c8..a562ee2bb10 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-exited-owner.test.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-exited-owner.test.ts @@ -38,7 +38,7 @@ vi.mock('@/store/index', () => ({ } })) vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, fallback: string) => fallback })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: () => 'Codex', getAgentCatalog: () => [{ id: 'codex', label: 'Codex' }] })) diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-join-delivery.test.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-join-delivery.test.ts index 1f6bb2cab8d..90b6e41dfe5 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-join-delivery.test.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-join-delivery.test.ts @@ -91,7 +91,7 @@ vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, fallback: string) => fallback })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: () => 'Codex', getAgentCatalog: () => [{ id: 'codex', label: 'Codex' }] })) diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-label.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-label.ts index c9b3fef0d02..e1a7798a531 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-label.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-label.ts @@ -1,5 +1,5 @@ import type { AgentType } from '../../../../../shared/agent-status/contracts/agent-status-types' -import { getAgentCatalog } from '@/lib/agent-catalog' +import { getAgentCatalog } from '@/lib/agent-catalog/agent-catalog' export function structuredAgentLabel(agent: AgentType): string { return getAgentCatalog().find((entry) => entry.id === agent)?.label ?? agent diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-options.test.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-options.test.ts index 742da475f63..2759c14d142 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-options.test.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-options.test.ts @@ -82,7 +82,7 @@ vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, fallback: string) => fallback })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: () => 'Codex', getAgentCatalog: () => [{ id: 'codex', label: 'Codex' }] })) diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-outcome-tracking.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-outcome-tracking.ts index ac9f91c35ff..331bcaad405 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-outcome-tracking.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-outcome-tracking.ts @@ -4,7 +4,7 @@ import { retireStructuredAgentSessionReadOwner } from '@/components/native-chat/ import { useAppStore } from '@/store/index' import { publishStructuredAgentSessionSends } from '@/components/native-chat/session/structured/delivery/structured-agent-session-pending-sends' import { agentSessionWriteFailureText } from '@/components/native-chat/messages/notices/agent-session-write-notice-text' -import { getAgentLabel } from '@/lib/agent-catalog' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' import { removeStructuredLaunchSlot } from './structured-agent-session-launch-slot' import { materializeStructuredLaunchSurface, diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-resume-identity.test.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-resume-identity.test.ts index 3b02d5dc1b6..eec4a76ac60 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-resume-identity.test.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-resume-identity.test.ts @@ -20,7 +20,7 @@ vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, fallback: string) => fallback })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentCatalog: () => [{ id: 'codex', label: 'Codex' }] })) diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-selection-admission.test-fixture.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-selection-admission.test-fixture.ts index b78adb7fca2..91774c43d3c 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-selection-admission.test-fixture.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-selection-admission.test-fixture.ts @@ -10,7 +10,7 @@ import { structuredAgentSessionSendOut } from '@/components/native-chat/session/structured/delivery/structured-agent-session-pending-sends' import { structuredConversationCommandRunner } from '@/components/native-chat/session/structured/writes/structured-conversation-command-send' -import { sendMessageToAgent } from '../../agent-message-send' +import { sendMessageToAgent } from '../messaging/agent-message-send' import { recordHostModelCatalogSnapshot } from '@/runtime/native-chat/model-catalogs/host-model-catalog-snapshots' import { getStructuredLaunchStateBySessionId } from './structured-agent-session-launch-registry' import { structuredSessionSelectionController } from '../options/structured-agent-session-selection-controller' diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-unconfirmed-or-retried.test.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-unconfirmed-or-retried.test.ts index 666b6f77ec7..67da66add19 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-unconfirmed-or-retried.test.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch-unconfirmed-or-retried.test.ts @@ -71,7 +71,7 @@ vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, fallback: string) => fallback })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: () => 'Codex', getAgentCatalog: () => [{ id: 'codex', label: 'Codex' }] })) diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch.test-fixture.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch.test-fixture.ts index 7c88cdd8e70..1fbf4fe56ad 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch.test-fixture.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-launch.test-fixture.ts @@ -119,7 +119,7 @@ vi.mock('@/i18n/i18n', () => ({ fallback.replace('{{value0}}', options?.value0 ?? '') })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: (agent: string) => (agent === 'codex' ? 'Codex' : 'Claude'), getAgentCatalog: () => [ { id: 'claude', label: 'Claude' }, diff --git a/src/renderer/src/lib/agent-session/launch/structured-agent-session-new-chat-own-launch.test.ts b/src/renderer/src/lib/agent-session/launch/structured-agent-session-new-chat-own-launch.test.ts index 19e189fdc75..e532d4a7685 100644 --- a/src/renderer/src/lib/agent-session/launch/structured-agent-session-new-chat-own-launch.test.ts +++ b/src/renderer/src/lib/agent-session/launch/structured-agent-session-new-chat-own-launch.test.ts @@ -56,7 +56,7 @@ const owner = vi.hoisted((): { store: ReturnType | null vi.mock('sonner', () => ({ toast: { error: vi.fn(), info: vi.fn(), message: vi.fn() } })) vi.mock('@/i18n/i18n', () => ({ translate: (_key: string, fallback: string) => fallback })) -vi.mock('@/lib/agent-catalog', () => ({ +vi.mock('@/lib/agent-catalog/agent-catalog', () => ({ getAgentLabel: () => 'Codex', getAgentCatalog: () => [{ id: 'codex', label: 'Codex' }] })) diff --git a/src/renderer/src/lib/agent-message-send.test.ts b/src/renderer/src/lib/agent-session/messaging/agent-message-send.test.ts similarity index 88% rename from src/renderer/src/lib/agent-message-send.test.ts rename to src/renderer/src/lib/agent-session/messaging/agent-message-send.test.ts index 3d5484a24e4..639cbff3777 100644 --- a/src/renderer/src/lib/agent-message-send.test.ts +++ b/src/renderer/src/lib/agent-session/messaging/agent-message-send.test.ts @@ -10,7 +10,7 @@ const mocks = vi.hoisted(() => { } }) -vi.mock('@/store', () => ({ +vi.mock('@/store/index', () => ({ useAppStore: { getState: () => ({ unifiedTabsByWorktree: { @@ -22,14 +22,16 @@ vi.mock('@/store', () => ({ vi.mock('@/runtime/native-chat/session-ownership/structured-agent-session-owner', () => ({ structuredAgentSessionTargetForTab: () => ({ kind: 'local' }) })) -vi.mock('./agent-session/launch/structured-agent-session-launch-message', () => ({ +vi.mock('../launch/structured-agent-session-launch-message', () => ({ relaunchFailedStructuredAgentSessionWithMessage: mocks.relaunch })) -vi.mock('./agent-session/launch/structured-agent-session-launch-registry', () => ({ - getStructuredAgentSessionLaunchLifecycle: () => mocks.launch.lifecycle, +vi.mock('../launch/structured-agent-session-launch-registry', () => ({ + getStructuredAgentSessionLaunchLifecycle: () => mocks.launch.lifecycle +})) +vi.mock('../launch/structured-agent-session-launch-input', () => ({ structuredAgentSessionLaunchHasRetainedInput: () => false })) -vi.mock('./active-agent-note-send', () => ({ sendNotesToActiveAgentSession: vi.fn() })) +vi.mock('./terminal/active-agent-note-send', () => ({ sendNotesToActiveAgentSession: vi.fn() })) vi.mock( '@/components/native-chat/session/structured/delivery/structured-agent-session-message-sender', () => ({ diff --git a/src/renderer/src/lib/agent-message-send.ts b/src/renderer/src/lib/agent-session/messaging/agent-message-send.ts similarity index 85% rename from src/renderer/src/lib/agent-message-send.ts rename to src/renderer/src/lib/agent-session/messaging/agent-message-send.ts index fc57a4838a9..b9987271851 100644 --- a/src/renderer/src/lib/agent-message-send.ts +++ b/src/renderer/src/lib/agent-session/messaging/agent-message-send.ts @@ -1,16 +1,12 @@ -import type { ActiveAgentNotesSendResult } from './active-agent-note-send-result' +import type { ActiveAgentNotesSendResult } from './terminal/active-agent-note-send-result' import type { AgentMessageTarget } from './agent-message-target' -import { sendNotesToActiveAgentSession } from './active-agent-note-send' -import { relaunchFailedStructuredAgentSessionWithMessage } from './agent-session/launch/structured-agent-session-launch-message' -import { - getStructuredAgentSessionLaunchLifecycle, - structuredAgentSessionLaunchHasRetainedInput -} from './agent-session/launch/structured-agent-session-launch-registry' +import { sendNotesToActiveAgentSession } from './terminal/active-agent-note-send' +import { relaunchFailedStructuredAgentSessionWithMessage } from '../launch/structured-agent-session-launch-message' +import { getStructuredAgentSessionLaunchLifecycle } from '../launch/structured-agent-session-launch-registry' +import { structuredAgentSessionLaunchHasRetainedInput } from '../launch/structured-agent-session-launch-input' import { sendStructuredAgentSessionMessage } from '@/components/native-chat/session/structured/delivery/structured-agent-session-message-sender' import { structuredAgentSessionTargetForTab } from '@/runtime/native-chat/session-ownership/structured-agent-session-owner' -import { useAppStore } from '@/store' - -export type { AgentMessageTarget } from './agent-message-target' +import { useAppStore } from '@/store/index' export async function sendMessageToAgent(args: { worktreeId: string diff --git a/src/renderer/src/lib/agent-message-target.ts b/src/renderer/src/lib/agent-session/messaging/agent-message-target.ts similarity index 100% rename from src/renderer/src/lib/agent-message-target.ts rename to src/renderer/src/lib/agent-session/messaging/agent-message-target.ts diff --git a/src/renderer/src/lib/agent-send-disabled-reason-label.ts b/src/renderer/src/lib/agent-session/messaging/agent-send-disabled-reason-label.ts similarity index 100% rename from src/renderer/src/lib/agent-send-disabled-reason-label.ts rename to src/renderer/src/lib/agent-session/messaging/agent-send-disabled-reason-label.ts diff --git a/src/renderer/src/lib/agent-send-title-status.ts b/src/renderer/src/lib/agent-session/messaging/agent-send-title-status.ts similarity index 64% rename from src/renderer/src/lib/agent-send-title-status.ts rename to src/renderer/src/lib/agent-session/messaging/agent-send-title-status.ts index d5a769d6e1b..dc003cfda22 100644 --- a/src/renderer/src/lib/agent-send-title-status.ts +++ b/src/renderer/src/lib/agent-session/messaging/agent-send-title-status.ts @@ -1,6 +1,7 @@ -import type { AgentStatus } from '../../../shared/agent-status/title/agent-title-core' -import { isOpenCodeNativeTitle } from '../../../shared/agent-status/title/providers/opencode-terminal-title' -import { classifyTitleActivity, resolveTitleActivityLabel } from '@/lib/pane-agent-evidence' +import type { AgentStatus } from '../../../../../shared/agent-status/title/agent-title-core' +import { isOpenCodeNativeTitle } from '../../../../../shared/agent-status/title/providers/opencode-terminal-title' +import { detectAgentStatusFromTitle } from '../../../../../shared/agent-status/title/agent-title-status' +import { getAgentLabel } from '../../../../../shared/agent-status/title/agent-title-identity' const EXPLICIT_IDLE_SEND_TITLE_RE = /(^|\s)(ready|idle|done)(\s|$|[.!?])/i const CLAUDE_IDLE_PREFIX = '\u2733' @@ -8,11 +9,11 @@ const GEMINI_IDLE_PREFIX = '\u25c7' const PI_IDLE_PREFIX = '\u03c0 - ' export function detectAgentSendTitleStatus(title: string | null | undefined): AgentStatus | null { - if (!title || resolveTitleActivityLabel(title) === null) { + if (!title || getAgentLabel(title) === null) { return null } - const status = classifyTitleActivity(title) + const status = detectAgentStatusFromTitle(title) if (status !== 'idle') { return status } diff --git a/src/renderer/src/lib/notes-send-agent-targets.ts b/src/renderer/src/lib/agent-session/messaging/notes-send-agent-targets.ts similarity index 92% rename from src/renderer/src/lib/notes-send-agent-targets.ts rename to src/renderer/src/lib/agent-session/messaging/notes-send-agent-targets.ts index 20c56ddca7a..f3e1ba270a6 100644 --- a/src/renderer/src/lib/notes-send-agent-targets.ts +++ b/src/renderer/src/lib/agent-session/messaging/notes-send-agent-targets.ts @@ -2,17 +2,20 @@ import { projectedStructuredChatTabName, type StructuredChatTabNames } from '@/runtime/native-chat/naming/structured-chat-tab-name' -import { structuredChatTabById } from './structured-chat-tab-index' -import type { AgentType } from '../../../shared/agent-status/contracts/agent-status-types' +import { structuredChatTabById } from '../../structured-chat-tab-index' +import type { AgentType } from '../../../../../shared/agent-status/contracts/agent-status-types' import type { AppState } from '@/store/types' -import { isTerminalLeafId, makePaneKey } from '../../../shared/workspace-layout/stable-pane-id' -import { resolveTerminalTitleAgentType } from '../../../shared/agent-status/title/terminal-title-agent-type' -import type { TerminalTab } from '../../../shared/workspace-layout/terminal-tab-types' +import { + isTerminalLeafId, + makePaneKey +} from '../../../../../shared/workspace-layout/stable-pane-id' +import { resolveTerminalTitleAgentType } from '../../../../../shared/agent-status/title/terminal-title-agent-type' +import type { TerminalTab } from '../../../../../shared/workspace-layout/terminal-tab-types' import { detectAgentSendTitleStatus } from './agent-send-title-status' import { resolveRuntimePaneTitleLeafResolution, type RuntimePaneTitleLeafResolution -} from '../../../shared/runtime-pane-title-leaf-id' +} from '../../../../../shared/runtime-pane-title-leaf-id' import { deriveRunningAgentSendTargets, deriveStatuslessStructuredAgentSendTargets, diff --git a/src/renderer/src/lib/agent-draft-paste-content.ts b/src/renderer/src/lib/agent-session/messaging/paste/agent-draft-paste-content.ts similarity index 95% rename from src/renderer/src/lib/agent-draft-paste-content.ts rename to src/renderer/src/lib/agent-session/messaging/paste/agent-draft-paste-content.ts index 457f9aa298b..f24122366b3 100644 --- a/src/renderer/src/lib/agent-draft-paste-content.ts +++ b/src/renderer/src/lib/agent-session/messaging/paste/agent-draft-paste-content.ts @@ -1,18 +1,18 @@ -import { yieldToEventLoop } from '../../../shared/event-loop-yield' +import { yieldToEventLoop } from '../../../../../../shared/event-loop-yield' import { getUtf8ByteLengthForCodePoint, readUtf8CodePointAt -} from '../../../shared/utf8-byte-limits' +} from '../../../../../../shared/utf8-byte-limits' import '@/components/terminal-pane/input/paste/terminal-bracketed-paste' import { BRACKETED_PASTE_END, BRACKETED_PASTE_START, normalizeTerminalPasteLineEndings, wrapTerminalBracketedPasteText -} from '../../../shared/terminal/input/terminal-bracketed-paste-text' +} from '../../../../../../shared/terminal/input/terminal-bracketed-paste-text' import { runTerminalPtyInputTransaction } from '@/components/terminal-pane/input/paste/terminal-pty-input-transaction' import { sendRuntimePtyInputVerified } from '@/runtime/hosted-terminals/input/runtime-terminal-verified-input' -import type { TerminalInputKind } from '../../../shared/terminal/input/terminal-input-kind' +import type { TerminalInputKind } from '../../../../../../shared/terminal/input/terminal-input-kind' // Bracketed paste keeps generated prompts together without triggering per-character TUI edits. export const AGENT_DRAFT_PASTE_DIRECT_MAX_BYTES = 64 * 1024 diff --git a/src/renderer/src/lib/agent-draft-readiness.ts b/src/renderer/src/lib/agent-session/messaging/paste/agent-draft-readiness.ts similarity index 90% rename from src/renderer/src/lib/agent-draft-readiness.ts rename to src/renderer/src/lib/agent-session/messaging/paste/agent-draft-readiness.ts index e1703faa7b3..a8c4cdb169b 100644 --- a/src/renderer/src/lib/agent-draft-readiness.ts +++ b/src/renderer/src/lib/agent-session/messaging/paste/agent-draft-readiness.ts @@ -1,9 +1,9 @@ -import type { DraftPasteReadySignal } from '../../../shared/agent-launch/catalog/tui-agent-config-types' +import type { DraftPasteReadySignal } from '../../../../../../shared/agent-launch/catalog/tui-agent-config-types' import { subscribeToPtyData } from '@/components/terminal-pane/pty-transport/delivery/pty-data-sidecar-subscriptions' import { replayPreHandlerPtyData } from '@/components/terminal-pane/pty-transport/delivery/pty-pre-handler-buffer' -import { isRemoteRuntimePtyId } from '../../../shared/remote-runtime/remote-runtime-pty-id' +import { isRemoteRuntimePtyId } from '../../../../../../shared/remote-runtime/remote-runtime-pty-id' import { subscribeToRuntimeTerminalData } from '@/runtime/hosted-terminals/streams/runtime-terminal-data-subscription' -import { createDraftPasteReadyScanner } from '../../../shared/draft-paste-ready-scanner' +import { createDraftPasteReadyScanner } from '../../../../../../shared/draft-paste-ready-scanner' const BRACKETED_PASTE_QUIET_MS = 1500 diff --git a/src/renderer/src/lib/agent-followup-delivery.ts b/src/renderer/src/lib/agent-session/messaging/paste/agent-followup-delivery.ts similarity index 85% rename from src/renderer/src/lib/agent-followup-delivery.ts rename to src/renderer/src/lib/agent-session/messaging/paste/agent-followup-delivery.ts index f74759bad76..5980ce00649 100644 --- a/src/renderer/src/lib/agent-followup-delivery.ts +++ b/src/renderer/src/lib/agent-session/messaging/paste/agent-followup-delivery.ts @@ -1,11 +1,11 @@ import { inspectRuntimeTerminalProcess } from '@/runtime/hosted-terminals/inspection/runtime-terminal-process-inspection' -import { pasteDraftToAgentPtyWhenReady } from '@/lib/agent-paste-draft' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' +import { pasteDraftToAgentPtyWhenReady } from '@/lib/agent-session/messaging/paste/agent-paste-draft' +import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import { isAgentForegroundWrapperProcess, isExpectedAgentProcess -} from '../../../shared/agent-status/process/agent-process-recognition' -import { isShellProcess } from '../../../shared/agent-status/process/shell-process-detection' +} from '../../../../../../shared/agent-status/process/agent-process-recognition' +import { isShellProcess } from '../../../../../../shared/agent-status/process/shell-process-detection' export async function sendFollowupPromptWhenAgentReady(args: { ptyId: string diff --git a/src/renderer/src/lib/agent-native-draft-prefill.ts b/src/renderer/src/lib/agent-session/messaging/paste/agent-native-draft-prefill.ts similarity index 70% rename from src/renderer/src/lib/agent-native-draft-prefill.ts rename to src/renderer/src/lib/agent-session/messaging/paste/agent-native-draft-prefill.ts index b45b7c8925d..38589cec0b5 100644 --- a/src/renderer/src/lib/agent-native-draft-prefill.ts +++ b/src/renderer/src/lib/agent-session/messaging/paste/agent-native-draft-prefill.ts @@ -1,5 +1,5 @@ -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' -import { TUI_AGENT_CONFIG } from '../../../shared/agent-launch/catalog/tui-agent-config' +import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' +import { TUI_AGENT_CONFIG } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' // Native flag/env prefill intentionally skips paste unless forcePaste is set; false then means delivered natively, not paste failure. export function agentDeliversDraftViaNativePrefill( diff --git a/src/renderer/src/lib/agent-paste-draft-submit-retry.test.ts b/src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft-submit-retry.test.ts similarity index 89% rename from src/renderer/src/lib/agent-paste-draft-submit-retry.test.ts rename to src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft-submit-retry.test.ts index 2a4f1885c9a..df082ab9708 100644 --- a/src/renderer/src/lib/agent-paste-draft-submit-retry.test.ts +++ b/src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft-submit-retry.test.ts @@ -1,12 +1,12 @@ import { beforeEach, afterEach, describe, expect, it, vi } from 'vitest' +import { pasteDraftWhenAgentReady } from './agent-paste-draft' import { AGENT_DRAFT_PASTE_DIRECT_MAX_BYTES, - pasteDraftWhenAgentReady, sendAgentDraftPasteContent -} from './agent-paste-draft' -import { AGENT_PROMPT_POST_PASTE_SUBMIT_DELAY_MS as POST_PASTE_SUBMIT_DELAY_MS } from '../../../shared/agent-launch/startup/agent-prompt-injection' -import { TUI_AGENT_CONFIG } from '../../../shared/agent-launch/catalog/tui-agent-config' -import type * as RemoteRuntimePtyIdModule from '../../../shared/remote-runtime/remote-runtime-pty-id' +} from './agent-draft-paste-content' +import { AGENT_PROMPT_POST_PASTE_SUBMIT_DELAY_MS as POST_PASTE_SUBMIT_DELAY_MS } from '../../../../../../shared/agent-launch/startup/agent-prompt-injection' +import { TUI_AGENT_CONFIG } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' +import type * as RemoteRuntimePtyIdModule from '../../../../../../shared/remote-runtime/remote-runtime-pty-id' const testState = vi.hoisted(() => ({ appState: { @@ -27,7 +27,7 @@ const testState = vi.hoisted(() => ({ subscribeToRuntimeTerminalData: vi.fn() })) -vi.mock('@/store', () => ({ +vi.mock('@/store/index', () => ({ useAppStore: { getState: () => testState.appState, subscribe: () => () => {} @@ -45,10 +45,13 @@ vi.mock('@/components/terminal-pane/pty-transport/delivery/pty-pre-handler-buffe vi.mock('@/runtime/hosted-terminals/inspection/runtime-terminal-process-inspection', () => ({ inspectRuntimeTerminalProcess: testState.inspectRuntimeTerminalProcess })) -vi.mock('../../../shared/remote-runtime/remote-runtime-pty-id', async (importOriginal) => ({ - ...(await importOriginal()), - isRemoteRuntimePtyId: testState.isRemoteRuntimePtyId -})) +vi.mock( + '../../../../../../shared/remote-runtime/remote-runtime-pty-id', + async (importOriginal) => ({ + ...(await importOriginal()), + isRemoteRuntimePtyId: testState.isRemoteRuntimePtyId + }) +) vi.mock('@/runtime/hosted-terminals/input/runtime-terminal-verified-input', () => ({ sendRuntimePtyInputVerified: testState.sendRuntimePtyInputVerified })) diff --git a/src/renderer/src/lib/agent-paste-draft.test.ts b/src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft.test.ts similarity index 92% rename from src/renderer/src/lib/agent-paste-draft.test.ts rename to src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft.test.ts index 4224f495e8f..d3000306ce9 100644 --- a/src/renderer/src/lib/agent-paste-draft.test.ts +++ b/src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft.test.ts @@ -1,14 +1,13 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { pasteDraftWhenAgentReady, sendBracketedPasteToRunningAgent } from './agent-paste-draft' import { AGENT_DRAFT_PASTE_CHUNK_MAX_BYTES, AGENT_DRAFT_PASTE_DIRECT_MAX_BYTES, - pasteDraftWhenAgentReady, - sendAgentDraftPasteContent, - sendBracketedPasteToRunningAgent -} from './agent-paste-draft' -import { AGENT_PROMPT_POST_PASTE_SUBMIT_DELAY_MS as POST_PASTE_SUBMIT_DELAY_MS } from '../../../shared/agent-launch/startup/agent-prompt-injection' -import { TUI_AGENT_CONFIG } from '../../../shared/agent-launch/catalog/tui-agent-config' -import type * as RemoteRuntimePtyIdModule from '../../../shared/remote-runtime/remote-runtime-pty-id' + sendAgentDraftPasteContent +} from './agent-draft-paste-content' +import { AGENT_PROMPT_POST_PASTE_SUBMIT_DELAY_MS as POST_PASTE_SUBMIT_DELAY_MS } from '../../../../../../shared/agent-launch/startup/agent-prompt-injection' +import { TUI_AGENT_CONFIG } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' +import type * as RemoteRuntimePtyIdModule from '../../../../../../shared/remote-runtime/remote-runtime-pty-id' const testState = vi.hoisted(() => ({ appState: { @@ -30,7 +29,7 @@ const testState = vi.hoisted(() => ({ subscribeToRuntimeTerminalData: vi.fn() })) -vi.mock('@/store', () => ({ +vi.mock('@/store/index', () => ({ useAppStore: { getState: () => testState.appState, subscribe: ( @@ -53,10 +52,13 @@ vi.mock('@/components/terminal-pane/pty-transport/delivery/pty-pre-handler-buffe vi.mock('@/runtime/hosted-terminals/inspection/runtime-terminal-process-inspection', () => ({ inspectRuntimeTerminalProcess: testState.inspectRuntimeTerminalProcess })) -vi.mock('../../../shared/remote-runtime/remote-runtime-pty-id', async (importOriginal) => ({ - ...(await importOriginal()), - isRemoteRuntimePtyId: testState.isRemoteRuntimePtyId -})) +vi.mock( + '../../../../../../shared/remote-runtime/remote-runtime-pty-id', + async (importOriginal) => ({ + ...(await importOriginal()), + isRemoteRuntimePtyId: testState.isRemoteRuntimePtyId + }) +) vi.mock('@/runtime/hosted-terminals/input/runtime-terminal-verified-input', () => ({ sendRuntimePtyInputVerified: (ptyId: string, data: string) => testState.sendRuntimePtyInputVerified(ptyId, data) diff --git a/src/renderer/src/lib/agent-paste-draft.ts b/src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft.ts similarity index 91% rename from src/renderer/src/lib/agent-paste-draft.ts rename to src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft.ts index f448a2e773d..a235dae9b95 100644 --- a/src/renderer/src/lib/agent-paste-draft.ts +++ b/src/renderer/src/lib/agent-session/messaging/paste/agent-paste-draft.ts @@ -1,28 +1,20 @@ -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' -import type { TerminalInputKind } from '../../../shared/terminal/input/terminal-input-kind' -import { TUI_AGENT_CONFIG } from '../../../shared/agent-launch/catalog/tui-agent-config' -import { AGENT_PROMPT_POST_PASTE_SUBMIT_DELAY_MS } from '../../../shared/agent-launch/startup/agent-prompt-injection' -import { resolveDraftPasteReadyTimeoutMs } from '../../../shared/draft-paste-ready-timeout' -import { resolvePasteReadySignal } from '../../../shared/draft-paste-ready-scanner' -import { useAppStore } from '@/store' +import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' +import type { TerminalInputKind } from '../../../../../../shared/terminal/input/terminal-input-kind' +import { TUI_AGENT_CONFIG } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' +import { AGENT_PROMPT_POST_PASTE_SUBMIT_DELAY_MS } from '../../../../../../shared/agent-launch/startup/agent-prompt-injection' +import { resolveDraftPasteReadyTimeoutMs } from '../../../../../../shared/draft-paste-ready-timeout' +import { resolvePasteReadySignal } from '../../../../../../shared/draft-paste-ready-scanner' +import { useAppStore } from '@/store/index' import { inspectRuntimeTerminalProcess } from '@/runtime/hosted-terminals/inspection/runtime-terminal-process-inspection' import { sendRuntimePtyInputVerified } from '@/runtime/hosted-terminals/input/runtime-terminal-verified-input' import '@/components/terminal-pane/input/paste/terminal-bracketed-paste' -import '../../../shared/terminal/input/terminal-bracketed-paste-text' +import '../../../../../../shared/terminal/input/terminal-bracketed-paste-text' import { runTerminalPtyInputTransaction } from '@/components/terminal-pane/input/paste/terminal-pty-input-transaction' import { waitForAgentReady } from './agent-ready-wait' import { sendAgentDraftPasteContentNow } from './agent-draft-paste-content' import { agentDeliversDraftViaNativePrefill } from './agent-native-draft-prefill' import { waitForAgentDraftInputReady } from './agent-draft-readiness' -import { isExpectedAgentProcess } from '../../../shared/agent-status/process/agent-process-recognition' -export { - AGENT_DRAFT_PASTE_CHUNK_MAX_BYTES, - AGENT_DRAFT_PASTE_DIRECT_MAX_BYTES, - AGENT_DRAFT_PASTE_MAX_BYTES, - chunkAgentDraftPasteContent, - iterateAgentDraftPasteContentChunks, - sendAgentDraftPasteContent -} from './agent-draft-paste-content' +import { isExpectedAgentProcess } from '../../../../../../shared/agent-status/process/agent-process-recognition' // Bracketed paste keeps prompt insertion atomic; callers separately choose whether to submit with Enter. diff --git a/src/renderer/src/lib/agent-ready-wait.ts b/src/renderer/src/lib/agent-session/messaging/paste/agent-ready-wait.ts similarity index 86% rename from src/renderer/src/lib/agent-ready-wait.ts rename to src/renderer/src/lib/agent-session/messaging/paste/agent-ready-wait.ts index 07269f9c95f..89748204434 100644 --- a/src/renderer/src/lib/agent-ready-wait.ts +++ b/src/renderer/src/lib/agent-session/messaging/paste/agent-ready-wait.ts @@ -1,7 +1,7 @@ -import { classifyTitleActivity } from '@/lib/pane-agent-evidence' -import { isExpectedAgentProcess } from '../../../shared/agent-status/process/agent-process-recognition' -import { isShellProcess } from '../../../shared/agent-status/process/shell-process-detection' -import { useAppStore } from '@/store' +import { detectAgentStatusFromTitle } from '../../../../../../shared/agent-status/title/agent-title-status' +import { isExpectedAgentProcess } from '../../../../../../shared/agent-status/process/agent-process-recognition' +import { isShellProcess } from '../../../../../../shared/agent-status/process/shell-process-detection' +import { useAppStore } from '@/store/index' import { inspectRuntimeTerminalProcess } from '@/runtime/hosted-terminals/inspection/runtime-terminal-process-inspection' // Prefer idle titles, then matching foreground process, then a non-shell child after grace; bound waiting so missing binaries cannot hang Use. @@ -42,7 +42,7 @@ function titleSuggestsReady(tabId: string): boolean { } } } - return titles.some((title) => classifyTitleActivity(title) === 'idle') + return titles.some((title) => detectAgentStatusFromTitle(title) === 'idle') } /** Resolve readiness by idle title, matching process or non-shell child after grace. Timeout resolves ready:false; never rejects. */ diff --git a/src/renderer/src/lib/running-agent-targets.ts b/src/renderer/src/lib/agent-session/messaging/running-agent-targets.ts similarity index 92% rename from src/renderer/src/lib/running-agent-targets.ts rename to src/renderer/src/lib/agent-session/messaging/running-agent-targets.ts index 1a5a1b7110f..732995ec265 100644 --- a/src/renderer/src/lib/running-agent-targets.ts +++ b/src/renderer/src/lib/agent-session/messaging/running-agent-targets.ts @@ -2,15 +2,15 @@ import type { AppState } from '@/store/types' import type { AgentStatusEntry, AgentType -} from '../../../shared/agent-status/contracts/agent-status-types' -import type { TerminalTab } from '../../../shared/workspace-layout/terminal-tab-types' -import { parsePaneKey } from '../../../shared/workspace-layout/stable-pane-id' -import { structuredAgentSessionPaneKey } from '../../../shared/agent-session/view/structured-agent-session-projection' -import { isStructuredTab } from '../../../shared/agent-session/view/structured-agent-session-tab' -import { resolvePaneAgentActivity } from '@/lib/pane-agent-evidence' +} from '../../../../../shared/agent-status/contracts/agent-status-types' +import type { TerminalTab } from '../../../../../shared/workspace-layout/terminal-tab-types' +import { parsePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' +import { structuredAgentSessionPaneKey } from '../../../../../shared/agent-session/view/structured-agent-session-projection' +import { isStructuredTab } from '../../../../../shared/agent-session/view/structured-agent-session-tab' +import { resolvePaneAgentActivity } from '@/lib/agent-status/evidence/pane-agent-evidence' import type { AgentMessageTarget } from './agent-message-target' import { detectAgentSendTitleStatus } from './agent-send-title-status' -import { resolveRuntimePaneTitleLeafResolution } from '../../../shared/runtime-pane-title-leaf-id' +import { resolveRuntimePaneTitleLeafResolution } from '../../../../../shared/runtime-pane-title-leaf-id' export type RunningAgentTargetState = Pick< AppState, diff --git a/src/renderer/src/lib/active-agent-note-send-delivery.ts b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-delivery.ts similarity index 94% rename from src/renderer/src/lib/active-agent-note-send-delivery.ts rename to src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-delivery.ts index 282cdbf1e35..7e1d7422250 100644 --- a/src/renderer/src/lib/active-agent-note-send-delivery.ts +++ b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-delivery.ts @@ -1,12 +1,12 @@ -import type { RuntimeTerminalSend } from '../../../shared/runtime-types' +import type { RuntimeTerminalSend } from '../../../../../../shared/runtime-terminal-send-contract' import { sanitizeBracketedPasteText as sanitizeTerminalPasteText, BRACKETED_PASTE_START as BRACKETED_PASTE_BEGIN, BRACKETED_PASTE_END -} from '../../../shared/terminal/input/terminal-bracketed-paste-text' +} from '../../../../../../shared/terminal/input/terminal-bracketed-paste-text' import { callRuntimeRpc } from '@/runtime/rpc/calls/runtime-rpc-call' -import './agent-paste-draft' -import { AGENT_PROMPT_POST_PASTE_SUBMIT_DELAY_MS as POST_PASTE_SUBMIT_DELAY_MS } from '../../../shared/agent-launch/startup/agent-prompt-injection' +import '../paste/agent-paste-draft' +import { AGENT_PROMPT_POST_PASTE_SUBMIT_DELAY_MS as POST_PASTE_SUBMIT_DELAY_MS } from '../../../../../../shared/agent-launch/startup/agent-prompt-injection' import type { ActiveAgentNotesSendResult } from './active-agent-note-send-result' import { ACTIVE_AGENT_SEND_RPC_TIMEOUT_MS, diff --git a/src/renderer/src/lib/active-agent-note-send-diagnostics.ts b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-diagnostics.ts similarity index 96% rename from src/renderer/src/lib/active-agent-note-send-diagnostics.ts rename to src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-diagnostics.ts index 28146783400..f5ffe401eb8 100644 --- a/src/renderer/src/lib/active-agent-note-send-diagnostics.ts +++ b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-diagnostics.ts @@ -3,7 +3,7 @@ import type { ActiveAgentNotesSendFailureCode, ActiveAgentNotesSendResult } from './active-agent-note-send-result' -import { hasRuntimeRpcErrorCode } from '../../../shared/runtime-rpc-error-code' +import { hasRuntimeRpcErrorCode } from '../../../../../../shared/runtime-rpc-error-code' export const TERMINAL_RUNTIME_FAILURE_CODES = [ 'terminal_handle_stale', diff --git a/src/renderer/src/lib/active-agent-note-send-explicit-target.test.ts b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-explicit-target.test.ts similarity index 99% rename from src/renderer/src/lib/active-agent-note-send-explicit-target.test.ts rename to src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-explicit-target.test.ts index e6b0cd2cecb..8e4811078ec 100644 --- a/src/renderer/src/lib/active-agent-note-send-explicit-target.test.ts +++ b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-explicit-target.test.ts @@ -22,7 +22,7 @@ const testState = vi.hoisted(() => ({ } })) -vi.mock('@/store', () => ({ +vi.mock('@/store/index', () => ({ useAppStore: Object.assign( (selector: (state: NoteSendAppState) => unknown) => selector(testState.appState), { diff --git a/src/renderer/src/lib/active-agent-note-send-focused-session.test.ts b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-focused-session.test.ts similarity index 99% rename from src/renderer/src/lib/active-agent-note-send-focused-session.test.ts rename to src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-focused-session.test.ts index b971afa48ef..5b71c3a0b94 100644 --- a/src/renderer/src/lib/active-agent-note-send-focused-session.test.ts +++ b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-focused-session.test.ts @@ -22,7 +22,7 @@ const testState = vi.hoisted(() => ({ } })) -vi.mock('@/store', () => ({ +vi.mock('@/store/index', () => ({ useAppStore: Object.assign( (selector: (state: NoteSendAppState) => unknown) => selector(testState.appState), { diff --git a/src/renderer/src/lib/active-agent-note-send-result.ts b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-result.ts similarity index 95% rename from src/renderer/src/lib/active-agent-note-send-result.ts rename to src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-result.ts index a739ebd71d4..c3edee7dd03 100644 --- a/src/renderer/src/lib/active-agent-note-send-result.ts +++ b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-result.ts @@ -1,4 +1,4 @@ -import { agentSessionWriteNoticeEnglish } from '../../../shared/agent-session/failures/agent-session-refusal-notice' +import { agentSessionWriteNoticeEnglish } from '../../../../../../shared/agent-session/failures/agent-session-refusal-notice' export type ActiveAgentNotesSendStatus = | 'sent' diff --git a/src/renderer/src/lib/active-agent-note-send-test-harness.ts b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-test-harness.ts similarity index 86% rename from src/renderer/src/lib/active-agent-note-send-test-harness.ts rename to src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-test-harness.ts index 0717fa37c9d..bee7f0e56cb 100644 --- a/src/renderer/src/lib/active-agent-note-send-test-harness.ts +++ b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send-test-harness.ts @@ -1,5 +1,5 @@ -import type { AgentStatusEntry } from '../../../shared/agent-status/contracts/agent-status-types' -import type { TerminalLayoutSnapshot } from '../../../shared/workspace-layout/terminal-tab-types' +import type { AgentStatusEntry } from '../../../../../../shared/agent-status/contracts/agent-status-types' +import type { TerminalLayoutSnapshot } from '../../../../../../shared/workspace-layout/terminal-tab-types' export const LEAF_ID = '11111111-1111-4111-8111-111111111111' export const OTHER_LEAF_ID = '22222222-2222-4222-8222-222222222222' diff --git a/src/renderer/src/lib/active-agent-note-send.ts b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send.ts similarity index 91% rename from src/renderer/src/lib/active-agent-note-send.ts rename to src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send.ts index 662031c2925..ba72320e0cd 100644 --- a/src/renderer/src/lib/active-agent-note-send.ts +++ b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-send.ts @@ -1,7 +1,7 @@ -import type { RuntimeTerminalWait } from '../../../shared/runtime-types' +import type { RuntimeTerminalWait } from '../../../../../../shared/runtime-terminal-contracts' import { runtimeTargetForOwnerEnvironment } from '@/runtime/rpc/targets/runtime-client-target' -import type { RuntimeClientTarget } from '../../../shared/runtime-client-target' -import { useAppStore } from '@/store' +import type { RuntimeClientTarget } from '../../../../../../shared/runtime-client-target' +import { useAppStore } from '@/store/index' import { callRuntimeRpc } from '@/runtime/rpc/calls/runtime-rpc-call' import { runtimeEnvironmentIdOrLocalUnlessTwin } from '@/lib/workspace/ownership/worktree-runtime-owner' import { findActiveRuntimeTerminal, getActiveTerminalNoteTarget } from './active-agent-note-target' @@ -24,18 +24,8 @@ import { sendPromptWithLegacyCombinedSend } from './active-agent-note-send-delivery' -export { - getActiveAgentNoteTarget, - getActiveAgentRuntimeProbeDescriptor, - getActiveTerminalNoteTarget, - probeActiveAgentNoteTarget, - type ActiveTerminalNoteTarget -} from './active-agent-note-target' -export { - activeAgentNotesSendFailureMessage, - type ActiveAgentNotesSendResult, - type ActiveAgentNotesSendStatus -} from './active-agent-note-send-result' +import './active-agent-note-send-result' + const ACTIVE_AGENT_SEND_TIMEOUT_MS = 8000 export async function sendNotesToActiveAgentSession(args: { diff --git a/src/renderer/src/lib/active-agent-note-target.ts b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-target.ts similarity index 85% rename from src/renderer/src/lib/active-agent-note-target.ts rename to src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-target.ts index 396c7d159ed..20c8655e208 100644 --- a/src/renderer/src/lib/active-agent-note-target.ts +++ b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-note-target.ts @@ -1,22 +1,26 @@ -import type { RuntimeTerminalListResult } from '../../../shared/runtime-types' +import type { RuntimeTerminalListResult } from '../../../../../../shared/runtime-terminal-contracts' import { runtimeTargetForOwnerEnvironment } from '@/runtime/rpc/targets/runtime-client-target' -import type { RuntimeClientTarget } from '../../../shared/runtime-client-target' -import { toHostSessionTabId } from '../../../shared/workspace-layout/terminal-surface-id' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../shared/agent-status/contracts/agent-status-freshness' -import type { AgentStatusEntry } from '../../../shared/agent-status/contracts/agent-status-types' +import type { RuntimeClientTarget } from '../../../../../../shared/runtime-client-target' +import { toHostSessionTabId } from '../../../../../../shared/workspace-layout/terminal-surface-id' +import { + AGENT_STATUS_STALE_AFTER_MS, + isAgentStatusFresh +} from '../../../../../../shared/agent-status/contracts/agent-status-freshness' +import type { AgentStatusEntry } from '../../../../../../shared/agent-status/contracts/agent-status-types' import type { AppState } from '@/store/types' import { callRuntimeRpc } from '@/runtime/rpc/calls/runtime-rpc-call' import { runtimeEnvironmentIdOrLocalUnlessTwin } from '@/lib/workspace/ownership/worktree-runtime-owner' import type { WorktreeRuntimeOwnerState } from '@/lib/workspace/ownership/worktree-runtime-owner-state' import { toRuntimeWorktreeSelector } from '@/runtime/rpc/targets/runtime-worktree-selector' -import { isTerminalLeafId, makePaneKey } from '../../../shared/workspace-layout/stable-pane-id' -import type { TerminalLayoutSnapshot } from '../../../shared/workspace-layout/terminal-tab-types' import { - classifyTitleActivity, - isExplicitAgentStatusFresh, - resolveTitleActivityLabel -} from '@/lib/pane-agent-evidence' -import { resolveRuntimePaneTitleForLeaf } from '../../../shared/runtime-pane-title-leaf-id' + isTerminalLeafId, + makePaneKey +} from '../../../../../../shared/workspace-layout/stable-pane-id' +import type { TerminalLayoutSnapshot } from '../../../../../../shared/workspace-layout/terminal-tab-types' +import { detectAgentStatusFromTitle } from '../../../../../../shared/agent-status/title/agent-title-status' + +import { getAgentLabel } from '../../../../../../shared/agent-status/title/agent-title-identity' +import { resolveRuntimePaneTitleForLeaf } from '../../../../../../shared/runtime-pane-title-leaf-id' const ACTIVE_AGENT_PROBE_RPC_TIMEOUT_MS = 3000 const ACTIVE_AGENT_TERMINAL_LIST_LIMIT = 200 @@ -92,7 +96,7 @@ export function getActiveAgentNoteTarget( } const entry = state.agentStatusByPaneKey?.[makePaneKey(noteTarget.tabId, noteTarget.leafId)] - if (entry && isExplicitAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS)) { + if (entry && isAgentStatusFresh(entry, now, AGENT_STATUS_STALE_AFTER_MS)) { return noteTarget } // Idle-before-first-hook hints only expose the option; runtime still verifies the focused agent is idle before Enter. @@ -232,5 +236,5 @@ function getFocusedRuntimePaneTitle( } function isRecognizedAgentTitle(title: string): boolean { - return classifyTitleActivity(title) !== null && resolveTitleActivityLabel(title) !== null + return detectAgentStatusFromTitle(title) !== null && getAgentLabel(title) !== null } diff --git a/src/renderer/src/lib/active-agent-terminal-send-readiness.ts b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-terminal-send-readiness.ts similarity index 92% rename from src/renderer/src/lib/active-agent-terminal-send-readiness.ts rename to src/renderer/src/lib/agent-session/messaging/terminal/active-agent-terminal-send-readiness.ts index a2342bc38d5..a7955465711 100644 --- a/src/renderer/src/lib/active-agent-terminal-send-readiness.ts +++ b/src/renderer/src/lib/agent-session/messaging/terminal/active-agent-terminal-send-readiness.ts @@ -1,9 +1,9 @@ -import type { RuntimeTerminalAgentStatus } from '../../../shared/runtime-types' -import { hasRuntimeRpcErrorCode } from '../../../shared/runtime-rpc-error-code' +import type { RuntimeTerminalAgentStatus } from '../../../../../../shared/runtime-terminal-contracts' +import { hasRuntimeRpcErrorCode } from '../../../../../../shared/runtime-rpc-error-code' import type { ActiveAgentNotesSendFailureCode } from './active-agent-note-send-result' import { callRuntimeRpc } from '@/runtime/rpc/calls/runtime-rpc-call' import { RuntimeRpcCallError } from '@/runtime/rpc/calls/runtime-rpc-result' -import type { RuntimeClientTarget } from '../../../shared/runtime-client-target' +import type { RuntimeClientTarget } from '../../../../../../shared/runtime-client-target' import { runtimeFailureCode, TERMINAL_RUNTIME_FAILURE_CODES diff --git a/src/renderer/src/lib/claude-agent-row-view.ts b/src/renderer/src/lib/agent-session/navigation/claude-agent-row-view.ts similarity index 92% rename from src/renderer/src/lib/claude-agent-row-view.ts rename to src/renderer/src/lib/agent-session/navigation/claude-agent-row-view.ts index 6ca2ac46196..2adf21654c5 100644 --- a/src/renderer/src/lib/claude-agent-row-view.ts +++ b/src/renderer/src/lib/agent-session/navigation/claude-agent-row-view.ts @@ -1,15 +1,15 @@ import { toast } from 'sonner' import { translate } from '@/i18n/i18n' import type { DashboardAgentRow } from '@/components/dashboard/useDashboardData' -import { useAppStore } from '@/store' +import { useAppStore } from '@/store/index' import { callRuntimeRpc } from '@/runtime/rpc/calls/runtime-rpc-call' import { hostRouteForAuthority } from '@/runtime/rpc/targets/runtime-client-target' import { getRuntimeEnvironmentRevision } from '@/runtime/rpc/environment-revisions/runtime-environment-revision' -import { resolveOwnerOrLocal } from './workspace/ownership/worktree-runtime-owner' -import { findActiveRuntimeTerminal } from './active-agent-note-target' -import { parsePaneKey } from '../../../shared/workspace-layout/stable-pane-id' -import { authorityKey } from '../../../shared/host-authority' -import type { ClaudeAgentViewResult } from '../../../shared/claude-agent-view' +import { resolveOwnerOrLocal } from '../../workspace/ownership/worktree-runtime-owner' +import { findActiveRuntimeTerminal } from '../messaging/terminal/active-agent-note-target' +import { parsePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' +import { authorityKey } from '../../../../../shared/host-authority' +import type { ClaudeAgentViewResult } from '../../../../../shared/claude-agent-view' const pendingViews = new Map() diff --git a/src/renderer/src/lib/agent-resume-launch-target.test.ts b/src/renderer/src/lib/agent-session/resume/agent-resume-launch-target.test.ts similarity index 100% rename from src/renderer/src/lib/agent-resume-launch-target.test.ts rename to src/renderer/src/lib/agent-session/resume/agent-resume-launch-target.test.ts diff --git a/src/renderer/src/lib/agent-resume-launch-target.ts b/src/renderer/src/lib/agent-session/resume/agent-resume-launch-target.ts similarity index 92% rename from src/renderer/src/lib/agent-resume-launch-target.ts rename to src/renderer/src/lib/agent-session/resume/agent-resume-launch-target.ts index 33931d8bb5b..8ff1a7e73a2 100644 --- a/src/renderer/src/lib/agent-resume-launch-target.ts +++ b/src/renderer/src/lib/agent-session/resume/agent-resume-launch-target.ts @@ -1,13 +1,13 @@ import { CLIENT_PLATFORM } from '@/lib/new-workspace' import { REMOTE_RUNTIME_PTY_HONOURS_TAB_SHELL_OVERRIDE } from '@/components/terminal-pane/pty-transport/remote-runtime/remote-runtime-pty-shell' -import { parseExecutionHostId } from '../../../shared/execution-host' -import { lastVerifiedRuntimeStatus } from '../../../shared/remote-runtime/host-status/runtime-host-status' -import { isWslUncPath } from '../../../shared/wsl-paths' -import { isWindowsAbsolutePathLike } from '../../../shared/cross-platform-path' -import { resolveHostAgentStartupShell } from '../../../shared/windows-terminal-shell' +import { parseExecutionHostId } from '../../../../../shared/execution-host' +import { lastVerifiedRuntimeStatus } from '../../../../../shared/remote-runtime/host-status/runtime-host-status' +import { isWslUncPath } from '../../../../../shared/wsl-paths' +import { isWindowsAbsolutePathLike } from '../../../../../shared/cross-platform-path' +import { resolveHostAgentStartupShell } from '../../../../../shared/windows-terminal-shell' import type { AppState } from '@/store/types' -import type { ProjectExecutionRuntimeResolution } from '../../../shared/execution-host/project-execution-runtime' -import type { AgentStartupShell } from '../../../shared/agent-launch/startup/tui-agent-startup-shell' +import type { ProjectExecutionRuntimeResolution } from '../../../../../shared/execution-host/project-execution-runtime' +import type { AgentStartupShell } from '../../../../../shared/agent-launch/startup/tui-agent-startup-shell' export type AgentResumeLaunchTarget = { platform: NodeJS.Platform diff --git a/src/renderer/src/lib/agent-session/resume/sleeping-agent-session-launch.ts b/src/renderer/src/lib/agent-session/resume/sleeping-agent-session-launch.ts index f12128c935d..1800abbfff3 100644 --- a/src/renderer/src/lib/agent-session/resume/sleeping-agent-session-launch.ts +++ b/src/renderer/src/lib/agent-session/resume/sleeping-agent-session-launch.ts @@ -11,7 +11,7 @@ import { resolveSshHostReportedPlatform, resolveAgentResumeLaunchTarget, type AgentResumeLaunchTarget -} from '@/lib/agent-resume-launch-target' +} from '@/lib/agent-session/resume/agent-resume-launch-target' import { getExecutionHostIdForWorktree } from '@/lib/workspace/ownership/worktree-runtime-owner' import { runtimeEnvironmentIdUnlessTwin } from '@/lib/workspace/ownership/resolve-owner' import { getLocalProjectExecutionRuntimeContext } from '@/lib/local-preflight-context' diff --git a/src/renderer/src/lib/agent-status.ts b/src/renderer/src/lib/agent-status/aggregation/worktree-agent-status.ts similarity index 75% rename from src/renderer/src/lib/agent-status.ts rename to src/renderer/src/lib/agent-status/aggregation/worktree-agent-status.ts index b7e21c0d15a..40629809ac2 100644 --- a/src/renderer/src/lib/agent-status.ts +++ b/src/renderer/src/lib/agent-status/aggregation/worktree-agent-status.ts @@ -1,18 +1,19 @@ -import type { TerminalTab } from '../../../shared/workspace-layout/terminal-tab-types' -import { isTuiAgent } from '../../../shared/agent-launch/catalog/tui-agent-config' -import type { Worktree } from '../../../shared/worktree/types' +import type { TerminalTab } from '../../../../../shared/workspace-layout/terminal-tab-types' +import { isTuiAgent } from '../../../../../shared/agent-launch/catalog/tui-agent-config' +import type { Worktree } from '../../../../../shared/worktree/types' import type { AgentStatusState, AgentType -} from '../../../shared/agent-status/contracts/agent-status-types' -import { tabHasLivePty } from '../../../shared/tab-has-live-pty' -import type { WorktreeStatus } from './worktree-status' -import { tuiAgentToAgentKind } from '../../../shared/agent-kind' -import { agentTypeToIconAgent } from '../../../shared/agent-status/presentation/agent-type-icon-agent' -import type { AgentKind } from '../../../shared/telemetry-events' +} from '../../../../../shared/agent-status/contracts/agent-status-types' +import { tabHasLivePty } from '../../../../../shared/tab-has-live-pty' +import type { WorktreeStatus } from '../../../../../shared/worktree-status-rollup' +import { tuiAgentToAgentKind } from '../../../../../shared/agent-kind' +import { agentTypeToIconAgent } from '../../../../../shared/agent-status/presentation/agent-type-icon-agent' +import type { AgentKind } from '../../../../../shared/telemetry-property-schemas' -import type { AgentStatus } from '../../../shared/agent-status/title/agent-title-core' -import { classifyTitleActivity, resolveTitleActivityLabel } from './pane-agent-evidence' +import type { AgentStatus } from '../../../../../shared/agent-status/title/agent-title-core' +import { detectAgentStatusFromTitle } from '../../../../../shared/agent-status/title/agent-title-status' +import { getAgentLabel } from '../../../../../shared/agent-status/title/agent-title-identity' type AgentQueryArgs = { tabsByWorktree: Record @@ -57,8 +58,8 @@ export function getWorkingAgentsPerWorktree({ const paneTitles = runtimePaneTitlesByTabId[tab.id] if (paneTitles && Object.keys(paneTitles).length > 0) { for (const [paneIdStr, title] of Object.entries(paneTitles)) { - if (classifyTitleActivity(title) === 'working') { - const label = resolveTitleActivityLabel(title) + if (detectAgentStatusFromTitle(title) === 'working') { + const label = getAgentLabel(title) if (label) { agents.push({ label, @@ -69,8 +70,8 @@ export function getWorkingAgentsPerWorktree({ } } } - } else if (classifyTitleActivity(tab.title) === 'working') { - const label = resolveTitleActivityLabel(tab.title) + } else if (detectAgentStatusFromTitle(tab.title) === 'working') { + const label = getAgentLabel(tab.title) if (label) { agents.push({ label, status: 'working', tabId: tab.id, paneId: null }) } @@ -148,13 +149,13 @@ function countWorkingAgentsForTab( // Why: split-pane tabs host multiple agents; the tab title only shows the last pane update, so prefer pane titles when mounted. if (paneTitles && Object.keys(paneTitles).length > 0) { for (const title of Object.values(paneTitles)) { - if (classifyTitleActivity(title) === 'working') { + if (detectAgentStatusFromTitle(title) === 'working') { count += 1 } } return count } - if (classifyTitleActivity(tab.title) === 'working') { + if (detectAgentStatusFromTitle(tab.title) === 'working') { count += 1 } return count diff --git a/src/renderer/src/lib/agent-status-epoch-clock.ts b/src/renderer/src/lib/agent-status/evidence/agent-status-epoch-clock.ts similarity index 100% rename from src/renderer/src/lib/agent-status-epoch-clock.ts rename to src/renderer/src/lib/agent-status/evidence/agent-status-epoch-clock.ts diff --git a/src/renderer/src/lib/agent-status-epoch-selector.ts b/src/renderer/src/lib/agent-status/evidence/agent-status-epoch-selector.ts similarity index 100% rename from src/renderer/src/lib/agent-status-epoch-selector.ts rename to src/renderer/src/lib/agent-status/evidence/agent-status-epoch-selector.ts diff --git a/src/renderer/src/lib/agent-status-terminal-title.ts b/src/renderer/src/lib/agent-status/evidence/agent-status-terminal-title.ts similarity index 77% rename from src/renderer/src/lib/agent-status-terminal-title.ts rename to src/renderer/src/lib/agent-status/evidence/agent-status-terminal-title.ts index 40d2e5a4ce8..87ddb76833b 100644 --- a/src/renderer/src/lib/agent-status-terminal-title.ts +++ b/src/renderer/src/lib/agent-status/evidence/agent-status-terminal-title.ts @@ -1,9 +1,9 @@ -import { classifyTitleActivity } from './pane-agent-evidence' -import type { ParsedAgentStatusPayload } from '../../../shared/agent-status/contracts/agent-status-types' +import { detectAgentStatusFromTitle } from '../../../../../shared/agent-status/title/agent-title-status' +import type { ParsedAgentStatusPayload } from '../../../../../shared/agent-status/contracts/agent-status-types' import { getSyntheticAgentTerminalTitle, getSyntheticAgentTitleProfile -} from '../../../shared/agent-status/title/synthetic-agent-title' +} from '../../../../../shared/agent-status/title/synthetic-agent-title' export function resolveAgentStatusTerminalTitle( payload: Pick, @@ -26,7 +26,7 @@ function shouldReplaceCurrentTitle( if (!currentTitle?.trim()) { return true } - const currentStatus = classifyTitleActivity(currentTitle) + const currentStatus = detectAgentStatusFromTitle(currentTitle) if (currentStatus === 'working') { return true } diff --git a/src/renderer/src/lib/pane-agent-evidence.ts b/src/renderer/src/lib/agent-status/evidence/pane-agent-evidence.ts similarity index 51% rename from src/renderer/src/lib/pane-agent-evidence.ts rename to src/renderer/src/lib/agent-status/evidence/pane-agent-evidence.ts index a927fe28ba8..eaebf4ba64a 100644 --- a/src/renderer/src/lib/pane-agent-evidence.ts +++ b/src/renderer/src/lib/agent-status/evidence/pane-agent-evidence.ts @@ -1,48 +1,15 @@ -import type { AgentStatus } from '../../../shared/agent-status/title/agent-title-core' -import { detectAgentStatusFromTitle } from '../../../shared/agent-status/title/agent-title-status' -import { getAgentLabel } from '../../../shared/agent-status/title/agent-title-identity' -import { resolveExplicitTerminalTitleAgentType } from '../../../shared/agent-status/title/terminal-title-agent-type' -import type { TerminalAgent } from '../../../shared/agent-status/identity/terminal-agent' +import type { AgentStatus } from '../../../../../shared/agent-status/title/agent-title-core' +import { detectAgentStatusFromTitle } from '../../../../../shared/agent-status/title/agent-title-status' + import { AGENT_STATUS_STALE_AFTER_MS, isAgentStatusFresh -} from '../../../shared/agent-status/contracts/agent-status-freshness' +} from '../../../../../shared/agent-status/contracts/agent-status-freshness' import type { AgentStatusEntry, AgentStatusState, AgentType -} from '../../../shared/agent-status/contracts/agent-status-types' - -// Hook status can outlive exited agents; share one configurable-TTL freshness gate without aggregate/resolver import cycles. -export function isExplicitAgentStatusFresh( - entry: Pick< - AgentStatusEntry, - | 'updatedAt' - | 'evidenceObservedAt' - | 'mirroredEvidenceReceivedAt' - | 'restoredUnconfirmed' - | 'structuredHostOwned' - >, - now: number, - staleAfterMs: number -): boolean { - return isAgentStatusFresh(entry, now, staleAfterMs) -} - -/** Title-only consumers (timers, readiness, sorting, synthetic writes) intentionally ignore hook/liveness evidence. */ -export function classifyTitleActivity(title: string): AgentStatus | null { - return detectAgentStatusFromTitle(title) -} - -/** Activity may treat bare Claude status prefixes as a label; committed identity requires agent proof. Choose the facet matching the product rule. */ -export function resolveTitleActivityLabel(title: string): string | null { - return getAgentLabel(title) -} - -/** See resolveTitleActivityLabel — the strict facet for identity decisions. */ -export function resolveCommittedTitleAgentType(title: string): TerminalAgent | null { - return resolveExplicitTerminalTitleAgentType(title) -} +} from '../../../../../shared/agent-status/contracts/agent-status-types' /** Expose hook/title layers separately: send menus and workspace dots combine them differently, so merging would change behavior. */ export type AgentActivityDecision = { @@ -71,7 +38,7 @@ export function resolvePaneAgentActivity( ): AgentActivityDecision { const freshEntry = input.explicitEntry && - isExplicitAgentStatusFresh(input.explicitEntry, input.now, AGENT_STATUS_STALE_AFTER_MS) + isAgentStatusFresh(input.explicitEntry, input.now, AGENT_STATUS_STALE_AFTER_MS) ? input.explicitEntry : null const titleStatus = input.liveTitle !== null ? detectAgentStatusFromTitle(input.liveTitle) : null diff --git a/src/renderer/src/lib/agent-status-connection-ownership.ts b/src/renderer/src/lib/agent-status/ownership/agent-status-connection-ownership.ts similarity index 93% rename from src/renderer/src/lib/agent-status-connection-ownership.ts rename to src/renderer/src/lib/agent-status/ownership/agent-status-connection-ownership.ts index ecf95fe0110..1f33b436299 100644 --- a/src/renderer/src/lib/agent-status-connection-ownership.ts +++ b/src/renderer/src/lib/agent-status/ownership/agent-status-connection-ownership.ts @@ -1,9 +1,9 @@ import { isRemoteRuntimePtyId, parseRemoteRuntimePtyId -} from '../../../shared/remote-runtime/remote-runtime-pty-id' -import { parseAppSshPtyId } from '../../../shared/ssh-pty-id' -import { parsePaneKey } from '../../../shared/workspace-layout/stable-pane-id' +} from '../../../../../shared/remote-runtime/remote-runtime-pty-id' +import { parseAppSshPtyId } from '../../../../../shared/ssh-pty-id' +import { parsePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' export type AgentStatusConnectionRouting = { connectionId: string | null } diff --git a/src/renderer/src/lib/agent-status-pane-ownership.ts b/src/renderer/src/lib/agent-status/ownership/agent-status-pane-ownership.ts similarity index 90% rename from src/renderer/src/lib/agent-status-pane-ownership.ts rename to src/renderer/src/lib/agent-status/ownership/agent-status-pane-ownership.ts index be93e5f281f..927a85a9631 100644 --- a/src/renderer/src/lib/agent-status-pane-ownership.ts +++ b/src/renderer/src/lib/agent-status/ownership/agent-status-pane-ownership.ts @@ -1,8 +1,8 @@ -import type { AppState } from '../store/types' -import { parsePaneKey } from '../../../shared/workspace-layout/stable-pane-id' -import { collectLeafIdsInOrder } from '../components/terminal-pane/layout/terminal-layout-leaf-traversal' -import { getIndexedRepoMap } from '../store/repos/repository-catalog-index' -import { getIndexedWorktreeMap } from '../store/slices/worktrees/listing/worktree-catalog-index' +import type { AppState } from '../../../store/types' +import { parsePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' +import { collectLeafIdsInOrder } from '../../../components/terminal-pane/layout/terminal-layout-leaf-traversal' +import { getIndexedRepoMap } from '../../../store/repos/repository-catalog-index' +import { getIndexedWorktreeMap } from '../../../store/slices/worktrees/listing/worktree-catalog-index' import { selectWorktreesByRepo } from '@/store/workspaces/catalog/workspace-record-fields' /** Resolve pane liveness, title and owner to reject torn-down tabs or events from retired SSH connections. */ diff --git a/src/renderer/src/lib/agent-row-dot-state.ts b/src/renderer/src/lib/agent-status/presentation/agent-row-dot-state.ts similarity index 73% rename from src/renderer/src/lib/agent-row-dot-state.ts rename to src/renderer/src/lib/agent-status/presentation/agent-row-dot-state.ts index c628afb9711..c0647057b3e 100644 --- a/src/renderer/src/lib/agent-row-dot-state.ts +++ b/src/renderer/src/lib/agent-status/presentation/agent-row-dot-state.ts @@ -1,11 +1,11 @@ import type { AgentDotState } from '@/components/AgentStateDot' -import type { AgentChildRowModel } from '../../../shared/agent-status/presentation/agent-child-row-model' -import { agentVerdictDisplayMark } from '../../../shared/agent-status/lifecycle/agent-main-agent-verdict' +import type { AgentChildRowModel } from '../../../../../shared/agent-status/presentation/agent-child-row-model' +import { agentVerdictDisplayMark } from '../../../../../shared/agent-status/lifecycle/agent-main-agent-verdict' import type { AgentStatusEntry, AgentWorkingMode -} from '../../../shared/agent-status/contracts/agent-status-types' -import type { AgentRowState } from '../../../shared/agent-status/presentation/agent-row-decay-state' +} from '../../../../../shared/agent-status/contracts/agent-status-types' +import type { AgentRowState } from '../../../../../shared/agent-status/presentation/agent-row-decay-state' /** Share row-state mapping across sidebar, dashboard and notes so new states cannot diverge. */ export function agentRowDotState( diff --git a/src/renderer/src/lib/agent-row-stopping-label.ts b/src/renderer/src/lib/agent-status/presentation/agent-row-stopping-label.ts similarity index 65% rename from src/renderer/src/lib/agent-row-stopping-label.ts rename to src/renderer/src/lib/agent-status/presentation/agent-row-stopping-label.ts index 35d3d43a0eb..c1f4aca7796 100644 --- a/src/renderer/src/lib/agent-row-stopping-label.ts +++ b/src/renderer/src/lib/agent-status/presentation/agent-row-stopping-label.ts @@ -1,8 +1,8 @@ -import { agentStopDisplayStatus } from '../../../shared/agent-status/lifecycle/agent-stop-display-status' -import type { AgentStatusEntry } from '../../../shared/agent-status/contracts/agent-status-types' +import { agentStopDisplayStatus } from '../../../../../shared/agent-status/lifecycle/agent-stop-display-status' +import type { AgentStatusEntry } from '../../../../../shared/agent-status/contracts/agent-status-types' import { translate } from '@/i18n/i18n' import type { Translate } from '@/i18n/use-translate' -import type { AgentRowState } from '../../../shared/agent-status/presentation/agent-row-decay-state' +import type { AgentRowState } from '../../../../../shared/agent-status/presentation/agent-row-decay-state' /** Replace the last tool line with Stopping… while a user-requested stop ends a working turn. */ export function agentRowStoppingLabel( diff --git a/src/renderer/src/lib/agent-row-tool-preview.ts b/src/renderer/src/lib/agent-status/presentation/agent-row-tool-preview.ts similarity index 73% rename from src/renderer/src/lib/agent-row-tool-preview.ts rename to src/renderer/src/lib/agent-status/presentation/agent-row-tool-preview.ts index c45bc074ede..7dec4183838 100644 --- a/src/renderer/src/lib/agent-row-tool-preview.ts +++ b/src/renderer/src/lib/agent-status/presentation/agent-row-tool-preview.ts @@ -1,10 +1,10 @@ -import type { AgentStatusEntry } from '../../../shared/agent-status/contracts/agent-status-types' -import type { AgentRowState } from '../../../shared/agent-status/presentation/agent-row-decay-state' -import { isProgramStatusRow } from './program-status/row' +import type { AgentStatusEntry } from '../../../../../shared/agent-status/contracts/agent-status-types' +import type { AgentRowState } from '../../../../../shared/agent-status/presentation/agent-row-decay-state' +import { isProgramStatusRow } from '../../program-status/row' import { agentToolPreviewInput, formatAgentToolPreviewLine -} from '../../../shared/agent-status/presentation/agent-tool-preview' +} from '../../../../../shared/agent-status/presentation/agent-tool-preview' type ToolPreviewEntry = Pick & Partial> diff --git a/src/renderer/src/lib/agent-verdict-status-line.ts b/src/renderer/src/lib/agent-status/presentation/agent-verdict-status-line.ts similarity index 82% rename from src/renderer/src/lib/agent-verdict-status-line.ts rename to src/renderer/src/lib/agent-status/presentation/agent-verdict-status-line.ts index 47739fd03e8..6744be596f9 100644 --- a/src/renderer/src/lib/agent-verdict-status-line.ts +++ b/src/renderer/src/lib/agent-status/presentation/agent-verdict-status-line.ts @@ -2,9 +2,9 @@ import { agentMainAgentVerdict, agentVerdictDisplayMark, type AgentMainAgentVerdictSource -} from '../../../shared/agent-status/lifecycle/agent-main-agent-verdict' -import type { AgentStatusEntry } from '../../../shared/agent-status/contracts/agent-status-types' -import { isProgramStatusRow } from './program-status/row' +} from '../../../../../shared/agent-status/lifecycle/agent-main-agent-verdict' +import type { AgentStatusEntry } from '../../../../../shared/agent-status/contracts/agent-status-types' +import { isProgramStatusRow } from '../../program-status/row' type VerdictLineSource = AgentMainAgentVerdictSource & Partial< diff --git a/src/renderer/src/lib/command-code-prompt-status-seed.ts b/src/renderer/src/lib/command-code-prompt-status-seed.ts index 74fd84f7b84..217e1aa1177 100644 --- a/src/renderer/src/lib/command-code-prompt-status-seed.ts +++ b/src/renderer/src/lib/command-code-prompt-status-seed.ts @@ -1,7 +1,7 @@ import { useAppStore } from '@/store' import { makePaneKey } from '../../../shared/workspace-layout/stable-pane-id' import { getConnectionIdFromState } from './workspace/ownership/connection-owner-resolution' -import { resolveLiveAgentStatusConnectionRouting } from './agent-status-connection-ownership' +import { resolveLiveAgentStatusConnectionRouting } from './agent-status/ownership/agent-status-connection-ownership' import { rendererAgentStatusObservations } from './renderer-agent-status-observations' // Command Code lacks prompt-submit hooks; seed working when generated input is delivered so rows do not stay idle until its next hook. diff --git a/src/renderer/src/lib/desktop-created-server-tabs.test.ts b/src/renderer/src/lib/desktop-created-server-tabs.test.ts index c578d62d5ff..42e9c34056d 100644 --- a/src/renderer/src/lib/desktop-created-server-tabs.test.ts +++ b/src/renderer/src/lib/desktop-created-server-tabs.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' vi.mock('../../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true })) vi.mock('sonner', () => ({ @@ -11,7 +11,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus restorePtyDataHandlersAfterFailedShutdown: vi.fn(), unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/lib/environment-setup-agent-launch.ts b/src/renderer/src/lib/environment-setup-agent-launch.ts index 60cc37865c2..1cf1d1acba4 100644 --- a/src/renderer/src/lib/environment-setup-agent-launch.ts +++ b/src/renderer/src/lib/environment-setup-agent-launch.ts @@ -1,7 +1,7 @@ import { toast } from 'sonner' import { useAppStore } from '@/store' import { translate } from '@/i18n/i18n' -import { resolveDefaultAgentForWorktree } from '@/lib/agent-tab-shortcuts' +import { resolveDefaultAgentForWorktree } from '@/lib/agent-session/launch/shortcuts/agent-tab-shortcuts' import { launchAgentInNewTabWithOutcome } from '@/lib/agent-session/launch/new-tab/launch-agent-in-new-tab' import { newAgentLaunchRequestId } from '@/lib/agent-session/launch/routing/agent-launch-request-id' import { captureAgentTabLaunchContext } from '@/components/agent-tab-launch-context' diff --git a/src/renderer/src/lib/fix-checks-agent-launch.ts b/src/renderer/src/lib/fix-checks-agent-launch.ts index 5a61b917c81..c5cf9674edf 100644 --- a/src/renderer/src/lib/fix-checks-agent-launch.ts +++ b/src/renderer/src/lib/fix-checks-agent-launch.ts @@ -15,7 +15,7 @@ import { ensureDetectedAgentsForRepo, ensureDetectedAgentsForWorktree, type RepoHostFields -} from '@/lib/agent-detection-target-inventory' +} from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { focusTerminalTabSurface } from '@/lib/focus-terminal-tab-surface' import type { ProspectiveWorkspace } from '@/lib/agent-session/launch/routing/agent-launch-route-input' import { worktreeLaunchWorkspace } from '@/lib/agent-session/launch/routing/agent-launch-route-input' diff --git a/src/renderer/src/lib/host-chat-program-acquisition.ts b/src/renderer/src/lib/host-chat-program-acquisition.ts index db085191441..abe59f741be 100644 --- a/src/renderer/src/lib/host-chat-program-acquisition.ts +++ b/src/renderer/src/lib/host-chat-program-acquisition.ts @@ -26,7 +26,7 @@ import { isTuiAgent } from '../../../shared/agent-launch/catalog/tui-agent-confi import { getDetectionTargetIdentityForWorktree, readAgentInventoryForWorktree -} from './agent-detection-target-inventory' +} from './agent-session/launch/inventory/agent-detection-target-inventory' export const useChatProgramFactsVersion = (): number => useAppViewExternalStore( diff --git a/src/renderer/src/lib/host-chat-program.test.ts b/src/renderer/src/lib/host-chat-program.test.ts index 918b44c005d..ae39be3f79f 100644 --- a/src/renderer/src/lib/host-chat-program.test.ts +++ b/src/renderer/src/lib/host-chat-program.test.ts @@ -1,6 +1,6 @@ import { agentTabLaunchStore } from './agent-session/launch/new-tab/launch-agent-execution-context' import { getRuntimeAgentInventoryKey } from '@/store/slices/agent-inventory/runtime-agent-inventory-key' -import { resolveDefaultAgentForWorkspace } from './agent-tab-shortcuts' +import { resolveDefaultAgentForWorkspace } from './agent-session/launch/shortcuts/agent-tab-shortcuts' import { EVERY_AGENT_CHAT } from '../../../shared/native-chat/every-agent-chat.test-fixture' import { makeWorktree } from '@/store/slices/worktrees/worktree.test-fixture' diff --git a/src/renderer/src/lib/host-chat-program.ts b/src/renderer/src/lib/host-chat-program.ts index f5b49b3b982..52c2440b6b1 100644 --- a/src/renderer/src/lib/host-chat-program.ts +++ b/src/renderer/src/lib/host-chat-program.ts @@ -8,7 +8,7 @@ import { import { lastVerifiedRuntimeStatus } from '../../../shared/remote-runtime/host-status/runtime-host-status' import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' import type { AgentSessionChatProgram } from '../../../shared/agent-session/agent-session-agent-availability' -import { chatProviderAgents } from './chat-provider-agents' +import { chatProviderAgents } from '../runtime/native-chat/agent-catalogs/chat-provider-agents' import { resolveAgentLaunchRoute, structuredAgentLaunchSupport diff --git a/src/renderer/src/lib/launch-agent-hosted-prompt.test.ts b/src/renderer/src/lib/launch-agent-hosted-prompt.test.ts index 2b31d7dce0b..2519190d235 100644 --- a/src/renderer/src/lib/launch-agent-hosted-prompt.test.ts +++ b/src/renderer/src/lib/launch-agent-hosted-prompt.test.ts @@ -38,7 +38,9 @@ vi.mock('@/runtime/agent-launch-settings/agent-launch-settings-transport', async vi.mock('@/runtime/hosted-terminals/creation/web-runtime-terminal-create-operation', () => ({ createWebRuntimeSessionTerminalResult: mocks.create })) -vi.mock('@/lib/agent-paste-draft', () => ({ pasteDraftWhenAgentReady: mocks.paste })) +vi.mock('@/lib/agent-session/messaging/paste/agent-paste-draft', () => ({ + pasteDraftWhenAgentReady: mocks.paste +})) beforeEach(() => { vi.clearAllMocks() diff --git a/src/renderer/src/lib/linear-usage-examples.ts b/src/renderer/src/lib/linear-usage-examples.ts index a12728d0fd4..4c8baff3e47 100644 --- a/src/renderer/src/lib/linear-usage-examples.ts +++ b/src/renderer/src/lib/linear-usage-examples.ts @@ -1,6 +1,6 @@ import { translate } from '@/i18n/i18n' import { createLocalizedCatalog } from '@/i18n/localized-catalog' -import { ORCA_LINEAR_SKILL_NAME } from './agent-feature-skill-names' +import { ORCA_LINEAR_SKILL_NAME } from './skills/installation/agent-feature-skill-names' import type { SkillUsageExample } from './skill-usage-example' const LINEAR_SLASH_COMMAND = `/${ORCA_LINEAR_SKILL_NAME}` diff --git a/src/renderer/src/lib/new-agent-prompt-outcome.ts b/src/renderer/src/lib/new-agent-prompt-outcome.ts index 7340cc7b9e0..8ca58e5ca5b 100644 --- a/src/renderer/src/lib/new-agent-prompt-outcome.ts +++ b/src/renderer/src/lib/new-agent-prompt-outcome.ts @@ -1,4 +1,4 @@ -import type { ActiveAgentNotesSendResult } from './active-agent-note-send-result' +import type { ActiveAgentNotesSendResult } from './agent-session/messaging/terminal/active-agent-note-send-result' import type { StructuredPromptDeliveryResult } from './agent-session/launch/structured-agent-session-launch-prompt' /** Delivered releases notes once host/composer owns the text; failure is omitted when the chat already reports startup/cancellation. */ diff --git a/src/renderer/src/lib/new-workspace.test.ts b/src/renderer/src/lib/new-workspace.test.ts index 26f1696fd36..d6447d19024 100644 --- a/src/renderer/src/lib/new-workspace.test.ts +++ b/src/renderer/src/lib/new-workspace.test.ts @@ -74,7 +74,7 @@ vi.mock('@/runtime/hosted-terminals/inspection/runtime-terminal-process-inspecti inspectRuntimeTerminalProcess: mockInspectRuntimeTerminalProcess })) -vi.mock('@/lib/agent-paste-draft', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-paste-draft', () => ({ pasteDraftToAgentPtyWhenReady: mockPasteDraftToAgentPtyWhenReady })) @@ -92,7 +92,7 @@ vi.mock('@/lib/agent-session/launch/background/agent-background-session-timeout- })) import { ensureAgentStartupInTerminal } from './new-workspace' -import { resetAgentStartupDelayedDeliveryForTests } from './agent-startup-delayed-delivery' +import { resetAgentStartupDelayedDeliveryForTests } from './agent-session/launch/startup/agent-startup-delayed-delivery' describe('ensureAgentStartupInTerminal prompt delivery', () => { beforeEach(() => { diff --git a/src/renderer/src/lib/new-workspace.ts b/src/renderer/src/lib/new-workspace.ts index 16964ae8145..0d75895aa06 100644 --- a/src/renderer/src/lib/new-workspace.ts +++ b/src/renderer/src/lib/new-workspace.ts @@ -1,6 +1,6 @@ import { useAppStore } from '@/store' -import { pasteDraftToAgentPtyWhenReady } from '@/lib/agent-paste-draft' -import { sendFollowupPromptWhenAgentReady } from '@/lib/agent-followup-delivery' +import { pasteDraftToAgentPtyWhenReady } from '@/lib/agent-session/messaging/paste/agent-paste-draft' +import { sendFollowupPromptWhenAgentReady } from '@/lib/agent-session/messaging/paste/agent-followup-delivery' import { showAutomationPromptNotSentToast } from '@/lib/agent-session/launch/background/agent-background-session-timeout-toast' import type { AgentStartupPlan } from '../../../shared/agent-launch/startup/tui-agent-startup' import type { LinkedWorkItemContext } from '@/lib/linked-work-item-context' @@ -9,7 +9,7 @@ import { getAgentStartupTabPtyId, queuePendingAgentStartupDelivery, resolveAgentStartupTabId -} from '@/lib/agent-startup-delayed-delivery' +} from '@/lib/agent-session/launch/startup/agent-startup-delayed-delivery' import type { WorkspaceLinkedItem as FolderWorkspaceLinkedTask } from '../../../shared/worktree/types' import { slugifyForWorkspaceName } from '../../../shared/workspace-name' import { createNonSecureContextUuid as createBrowserUuid } from '../../../shared/non-secure-context-uuid' diff --git a/src/renderer/src/lib/onboarding-folder-agent-launch.ts b/src/renderer/src/lib/onboarding-folder-agent-launch.ts index 271d816e1ff..d3a58472c16 100644 --- a/src/renderer/src/lib/onboarding-folder-agent-launch.ts +++ b/src/renderer/src/lib/onboarding-folder-agent-launch.ts @@ -4,7 +4,10 @@ import type { ExecutionHostId } from '../../../shared/execution-host' import type { OnboardingState } from '../../../shared/onboarding-state-types' import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' import type { useAppStore } from '@/store' -import { notifyAgentLaunchFailure, agentLaunchRecoveryMessage } from './agent-launch-failure' +import { + notifyAgentLaunchFailure, + agentLaunchRecoveryMessage +} from './agent-session/launch/failure/agent-launch-failure' import { resolveAgentLaunchExecutionContext } from '@/lib/agent-session/launch/new-tab/launch-agent-execution-context' import { planAgentSessionLaunch, diff --git a/src/renderer/src/lib/recent-workspace-tab-rows.ts b/src/renderer/src/lib/recent-workspace-tab-rows.ts index bc3543624fd..c73be15e0b1 100644 --- a/src/renderer/src/lib/recent-workspace-tab-rows.ts +++ b/src/renderer/src/lib/recent-workspace-tab-rows.ts @@ -6,11 +6,13 @@ import { } from '../../../shared/sidebar-list/smart-attention' import { tabHasLivePty } from '../../../shared/tab-has-live-pty' import { agentVerdictDisplayMark } from '../../../shared/agent-status/lifecycle/agent-main-agent-verdict' -import { isExplicitAgentStatusFresh } from './pane-agent-evidence' +import { + isAgentStatusFresh, + AGENT_STATUS_STALE_AFTER_MS +} from '../../../shared/agent-status/contracts/agent-status-freshness' import type { WorktreeStatus } from './worktree-status' import type { TerminalTab } from '../../../shared/workspace-layout/terminal-tab-types' import type { ExecutionHostId } from '../../../shared/execution-host' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../shared/agent-status/contracts/agent-status-freshness' /** Row model for Cmd+J's empty-query recent tabs section. */ export type RecentWorkspaceTabRow = { @@ -58,8 +60,7 @@ export function resolveRecentWorkspaceTabStatus( } const verdicts = new Set( panes.flatMap((pane) => - pane.kind === 'hook' && - isExplicitAgentStatusFresh(pane.entry, now, AGENT_STATUS_STALE_AFTER_MS) + pane.kind === 'hook' && isAgentStatusFresh(pane.entry, now, AGENT_STATUS_STALE_AFTER_MS) ? [agentVerdictDisplayMark(pane.entry)] : [] ) diff --git a/src/renderer/src/lib/agent-skill-coverage.ts b/src/renderer/src/lib/skills/agent-skill-coverage.ts similarity index 79% rename from src/renderer/src/lib/agent-skill-coverage.ts rename to src/renderer/src/lib/skills/agent-skill-coverage.ts index 0526fa4310b..9e9b2da8fae 100644 --- a/src/renderer/src/lib/agent-skill-coverage.ts +++ b/src/renderer/src/lib/skills/agent-skill-coverage.ts @@ -1,9 +1,9 @@ -import type { DiscoveredSkill, SkillDiscoverySource } from '../../../shared/skills' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' +import type { DiscoveredSkill, SkillDiscoverySource } from '../../../../shared/skills' +import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' import { getNativeChatAgentProfile, readsSkillSource -} from '../../../shared/native-chat/native-chat-agent-profiles' +} from '../../../../shared/native-chat/native-chat-agent-profiles' export function agentReadsSkill( agent: TuiAgent, diff --git a/src/renderer/src/lib/agent-feature-install-commands.ts b/src/renderer/src/lib/skills/installation/agent-feature-install-commands.ts similarity index 92% rename from src/renderer/src/lib/agent-feature-install-commands.ts rename to src/renderer/src/lib/skills/installation/agent-feature-install-commands.ts index 086bad5b361..5181248e329 100644 --- a/src/renderer/src/lib/agent-feature-install-commands.ts +++ b/src/renderer/src/lib/skills/installation/agent-feature-install-commands.ts @@ -1,5 +1,5 @@ // COMPAT(wsl-bridge): removed when WSL runs as an orcad host. -import { buildAgentFeatureSkillInstallCommand as buildPinnedSkillInstallCommand } from '../../../shared/agent-feature-install-commands' +import { buildAgentFeatureSkillInstallCommand as buildPinnedSkillInstallCommand } from '../../../../../shared/agent-feature-install-commands' import { ORCA_CLI_SKILL_NAME, ORCA_LINEAR_SKILL_NAME, diff --git a/src/renderer/src/lib/agent-feature-skill-names.ts b/src/renderer/src/lib/skills/installation/agent-feature-skill-names.ts similarity index 100% rename from src/renderer/src/lib/agent-feature-skill-names.ts rename to src/renderer/src/lib/skills/installation/agent-feature-skill-names.ts diff --git a/src/renderer/src/lib/agent-skill-cli-prerequisite.test.ts b/src/renderer/src/lib/skills/installation/agent-skill-cli-prerequisite.test.ts similarity index 95% rename from src/renderer/src/lib/agent-skill-cli-prerequisite.test.ts rename to src/renderer/src/lib/skills/installation/agent-skill-cli-prerequisite.test.ts index a89650a6e45..fd54f1e8101 100644 --- a/src/renderer/src/lib/agent-skill-cli-prerequisite.test.ts +++ b/src/renderer/src/lib/skills/installation/agent-skill-cli-prerequisite.test.ts @@ -1,6 +1,6 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { toast } from 'sonner' -import type { CliInstallStatus } from '../../../shared/cli-install-types' +import type { CliInstallStatus } from '../../../../../shared/cli-install-types' import { ensureOrcaCliAvailableForAgentSkillTerminal } from './agent-skill-cli-prerequisite' vi.mock('sonner', () => ({ diff --git a/src/renderer/src/lib/agent-skill-cli-prerequisite.ts b/src/renderer/src/lib/skills/installation/agent-skill-cli-prerequisite.ts similarity index 98% rename from src/renderer/src/lib/agent-skill-cli-prerequisite.ts rename to src/renderer/src/lib/skills/installation/agent-skill-cli-prerequisite.ts index 45752d05584..b2b855dc230 100644 --- a/src/renderer/src/lib/agent-skill-cli-prerequisite.ts +++ b/src/renderer/src/lib/skills/installation/agent-skill-cli-prerequisite.ts @@ -1,5 +1,5 @@ import { toast } from 'sonner' -import type { CliInstallStatus } from '../../../shared/cli-install-types' +import type { CliInstallStatus } from '../../../../../shared/cli-install-types' import { translate } from '@/i18n/i18n' type EnsureOrcaCliAvailableOptions = { diff --git a/src/renderer/src/lib/linear-agent-skill-update-target.ts b/src/renderer/src/lib/skills/installation/linear-agent-skill-update-target.ts similarity index 83% rename from src/renderer/src/lib/linear-agent-skill-update-target.ts rename to src/renderer/src/lib/skills/installation/linear-agent-skill-update-target.ts index b59e3a160fc..e696737337e 100644 --- a/src/renderer/src/lib/linear-agent-skill-update-target.ts +++ b/src/renderer/src/lib/skills/installation/linear-agent-skill-update-target.ts @@ -1,9 +1,12 @@ -import type { DiscoveredSkill } from '../../../shared/skills' +import type { DiscoveredSkill } from '../../../../../shared/skills' import { GLOBAL_AGENT_SKILL_SOURCE_KINDS, hasInstalledAgentSkill } from '@/hooks/useInstalledAgentSkills' -import { LINEAR_TICKETS_SKILL_NAME, ORCA_LINEAR_SKILL_NAME } from '@/lib/agent-feature-skill-names' +import { + LINEAR_TICKETS_SKILL_NAME, + ORCA_LINEAR_SKILL_NAME +} from '@/lib/skills/installation/agent-feature-skill-names' export type LinearAgentSkillUpdateTarget = { skillName: typeof ORCA_LINEAR_SKILL_NAME | typeof LINEAR_TICKETS_SKILL_NAME diff --git a/src/renderer/src/lib/orchestration-skill-coverage.ts b/src/renderer/src/lib/skills/orchestration-skill-coverage.ts similarity index 83% rename from src/renderer/src/lib/orchestration-skill-coverage.ts rename to src/renderer/src/lib/skills/orchestration-skill-coverage.ts index 61f2387979e..c6ee777b7af 100644 --- a/src/renderer/src/lib/orchestration-skill-coverage.ts +++ b/src/renderer/src/lib/skills/orchestration-skill-coverage.ts @@ -1,9 +1,9 @@ -import type { DiscoveredSkill, SkillDiscoverySource } from '../../../shared/skills' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' +import type { DiscoveredSkill, SkillDiscoverySource } from '../../../../shared/skills' +import type { TuiAgent } from '../../../../shared/agent-launch/catalog/tui-agent' import { agentReadsSkill } from './agent-skill-coverage' -import { ORCHESTRATION_SKILL_NAME } from '@/lib/agent-feature-skill-names' -import { getAgentLabel } from '@/lib/agent-catalog' -import { TUI_AGENT_AUTO_PICK_ORDER } from '../../../shared/agent-launch/catalog/tui-agent-selection' +import { ORCHESTRATION_SKILL_NAME } from '@/lib/skills/installation/agent-feature-skill-names' +import { getAgentLabel } from '@/lib/agent-catalog/agent-catalog' +import { TUI_AGENT_AUTO_PICK_ORDER } from '../../../../shared/agent-launch/catalog/tui-agent-selection' export type OrchestrationSkillAgentStatus = { agent: TuiAgent diff --git a/src/renderer/src/lib/skill-freshness-display-status.ts b/src/renderer/src/lib/skills/presentation/skill-freshness-display-status.ts similarity index 92% rename from src/renderer/src/lib/skill-freshness-display-status.ts rename to src/renderer/src/lib/skills/presentation/skill-freshness-display-status.ts index 58df730bfee..6e1857abd82 100644 --- a/src/renderer/src/lib/skill-freshness-display-status.ts +++ b/src/renderer/src/lib/skills/presentation/skill-freshness-display-status.ts @@ -1,8 +1,8 @@ -import type { BundledSkillPlan } from '../../../shared/bundled-skill-plan' +import type { BundledSkillPlan } from '../../../../../shared/bundled-skill-plan' import { bundledSkillPlanState, type BundledSkillPlanState -} from '../../../shared/bundled-skill-summary' +} from '../../../../../shared/bundled-skill-summary' export type SkillFreshnessDisplayStatus = | 'installed' diff --git a/src/renderer/src/lib/source-control/ai/source-control-agent-picker.ts b/src/renderer/src/lib/source-control/ai/source-control-agent-picker.ts index 099798ec0d5..83e783df930 100644 --- a/src/renderer/src/lib/source-control/ai/source-control-agent-picker.ts +++ b/src/renderer/src/lib/source-control/ai/source-control-agent-picker.ts @@ -21,7 +21,7 @@ import type { AgentMenuRowsTarget, NewTabAgentMenuModel } from '@/components/tab-bar/new-tab-agent-menu-model' -import type { resolveAgentMenuSelection } from '@/lib/agent-menu-selection' +import type { resolveAgentMenuSelection } from '@/lib/agent-session/launch/routing/agent-menu-selection' import type { AgentPickerEntry } from '../../../../../shared/agent-launch/picker/agent-launch-picker' import type { AgentLaunchSurface } from '@/lib/agent-session/launch/routing/agent-session-launch-plan' import { resolveSourceControlActionPreferredSurface } from '../../../../../shared/source-control/ai/recipes/source-control-action-launch-preferences' diff --git a/src/renderer/src/lib/text-generation-error-copy.ts b/src/renderer/src/lib/text-generation-error-copy.ts index 4699f3c27f2..228a1eb4960 100644 --- a/src/renderer/src/lib/text-generation-error-copy.ts +++ b/src/renderer/src/lib/text-generation-error-copy.ts @@ -3,7 +3,7 @@ import { TEXT_GENERATION_FAILURE_COPY as EN, type TextGenerationFailureCode } from '../../../shared/text-generation-failure-copy' -import { AGENT_OUTPUT_ERROR_COPY } from './agent-output-error-copy' +import { AGENT_OUTPUT_ERROR_COPY } from './text-generation/agent-output-error-copy' type CopyValues = Record diff --git a/src/renderer/src/lib/agent-output-error-copy.ts b/src/renderer/src/lib/text-generation/agent-output-error-copy.ts similarity index 99% rename from src/renderer/src/lib/agent-output-error-copy.ts rename to src/renderer/src/lib/text-generation/agent-output-error-copy.ts index 261c543ba45..d5dab5ac750 100644 --- a/src/renderer/src/lib/agent-output-error-copy.ts +++ b/src/renderer/src/lib/text-generation/agent-output-error-copy.ts @@ -2,7 +2,7 @@ import { translate } from '@/i18n/i18n' import { AGENT_OUTPUT_FAILURE_COPY as EN, type AgentOutputFailureCode -} from '../../../shared/agent-output-failure-copy' +} from '../../../../shared/agent-output-failure-copy' type CopyValues = Record diff --git a/src/renderer/src/lib/web-host-agent-launch-completion.ts b/src/renderer/src/lib/web-host-agent-launch-completion.ts index 1365840260a..5fbe9176ba1 100644 --- a/src/renderer/src/lib/web-host-agent-launch-completion.ts +++ b/src/renderer/src/lib/web-host-agent-launch-completion.ts @@ -5,7 +5,7 @@ import type { WebRuntimeTerminalCreateOutcome } from '@/runtime/hosted-terminals import type { AgentTerminalLaunchCompletion } from './agent-session/launch/structured-agent-session-launch-admission' import { webTerminalPlacementParentTabId } from '@/runtime/hosted-terminals/placement/web-session-terminal-placement' import { toWebTerminalSurfaceTabId } from '../../../shared/workspace-layout/terminal-surface-id' -import { notifyAgentLaunchPromptNotSent } from './agent-launch-prompt-failure-notice' +import { notifyAgentLaunchPromptNotSent } from './agent-session/launch/prompt/agent-launch-prompt-failure-notice' export function completeWebHostAgentLaunch(args: { agent: TuiAgent diff --git a/src/renderer/src/lib/workspace/activation/active-worktree-removal-successor.test.ts b/src/renderer/src/lib/workspace/activation/active-worktree-removal-successor.test.ts index 64adc6088de..3abb60a5a0a 100644 --- a/src/renderer/src/lib/workspace/activation/active-worktree-removal-successor.test.ts +++ b/src/renderer/src/lib/workspace/activation/active-worktree-removal-successor.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { installActiveWorktreeRemovalSuccessor, pickActiveWorktreeSuccessor @@ -27,7 +27,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus restorePtyDataHandlersAfterFailedShutdown: vi.fn(), unregisterPtyDataHandlers: vi.fn(() => []) })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/lib/workspace/activation/initial-surface/empty-workspace-default-agent-chat.ts b/src/renderer/src/lib/workspace/activation/initial-surface/empty-workspace-default-agent-chat.ts index 8850c475088..dee4d15b21e 100644 --- a/src/renderer/src/lib/workspace/activation/initial-surface/empty-workspace-default-agent-chat.ts +++ b/src/renderer/src/lib/workspace/activation/initial-surface/empty-workspace-default-agent-chat.ts @@ -11,7 +11,7 @@ import type { AgentDetectionTarget } from '@/hooks/useDetectedAgents' import { ensureDetectedAgentsForTarget, readDetectedAgentsForTarget -} from '@/lib/agent-detection-target-inventory' +} from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import { workspaceKindForWorktreeId } from '../../../../../../shared/agent-launch/contracts/workspace-launch-kind' import { worktreeLaunchWorkspace } from '@/lib/agent-session/launch/routing/agent-launch-route-input' import { chosenAgentChatUnlearned, agentChoiceOpensAsChat } from '@/lib/host-chat-program' diff --git a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-agent-routing.ts b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-agent-routing.ts index e8939699302..61cde6a3158 100644 --- a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-agent-routing.ts +++ b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-agent-routing.ts @@ -17,7 +17,7 @@ import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui import type { AppState } from '@/store/types' import { isTuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' import { isTuiAgentEnabled } from '../../../../../../shared/agent-launch/catalog/tui-agent-selection' -import { resolveDefaultAgentForWorkspace } from '../../../agent-tab-shortcuts' +import { resolveDefaultAgentForWorkspace } from '../../../agent-session/launch/shortcuts/agent-tab-shortcuts' import { worktreeLaunchWorkspace } from '@/lib/agent-session/launch/routing/agent-launch-route-input' import { agentChoiceMayOpenAsChat } from '@/lib/host-chat-program' import type { AgentSessionLaunchPlan } from '@/lib/agent-session/launch/routing/agent-session-launch-plan' @@ -30,7 +30,7 @@ import type { DeclinedStructuredLaunchTerminalOptions } from '@/lib/agent-sessio import { ensureDetectedAgentsForNewWorktree, type RepoHostFields -} from '@/lib/agent-detection-target-inventory' +} from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' export function buildDirectWorkItemStartup(args: { agent: TuiAgent | null diff --git a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-messages.ts b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-messages.ts index deeece20efa..bc6396ca4b1 100644 --- a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-messages.ts +++ b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-messages.ts @@ -1,10 +1,10 @@ import { toast } from 'sonner' -import { notifyAgentLaunchFailure } from '@/lib/agent-launch-failure' +import { notifyAgentLaunchFailure } from '@/lib/agent-session/launch/failure/agent-launch-failure' import { planAgentCliArgsSuffix, type AgentStartupShell } from '../../../../../../shared/agent-launch/startup/tui-agent-startup-shell' -import { getAgentLabel } from '../../../agent-catalog' +import { getAgentLabel } from '../../../agent-catalog/agent-catalog' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import '@/lib/new-workspace' diff --git a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-preflight.ts b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-preflight.ts index 82a4d45dce0..b220349ba93 100644 --- a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-preflight.ts +++ b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-preflight.ts @@ -10,7 +10,7 @@ import type { AppState } from '@/store/types' import { ensureDetectedAgentsForRepo, loadProjectLaunchContext -} from '../../../agent-detection-target-inventory' +} from '../../../agent-session/launch/inventory/agent-detection-target-inventory' import { CLIENT_PLATFORM } from '../../../new-workspace' import { getLocalRepoProjectExecutionRuntimeContext } from '../../../local-preflight-context' import { @@ -18,7 +18,7 @@ import { resolveRepoExecutionHostPlatform } from '../../../../runtime/hosts/platform/execution-host-facts' import { isTuiAgentEnabled } from '../../../../../../shared/agent-launch/catalog/tui-agent-selection' -import { resolveDefaultAgentForWorkspace } from '../../../agent-tab-shortcuts' +import { resolveDefaultAgentForWorkspace } from '../../../agent-session/launch/shortcuts/agent-tab-shortcuts' import { isTuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent-config' import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import type { ProjectLaunchContext } from '../../../../../../shared/rpc-contract/preflight-params' diff --git a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-route-preparation.ts b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-route-preparation.ts index 764edf5ac28..8cfd7c1b835 100644 --- a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-route-preparation.ts +++ b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-route-preparation.ts @@ -2,7 +2,7 @@ import { ensureAgentLaunchPreferences } from '@/runtime/agent-launch-settings/us import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import type { AppState } from '@/store/types' import { getConnectionIdFromState } from '@/lib/workspace/ownership/connection-owner-resolution' -import type { RepoHostFields } from '@/lib/agent-detection-target-inventory' +import type { RepoHostFields } from '@/lib/agent-session/launch/inventory/agent-detection-target-inventory' import type { ProjectExecutionRuntimeResolution } from '../../../../../../shared/execution-host/project-execution-runtime' import { refineLocalLaunchPlatform, diff --git a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-setup.test.tsx b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-setup.test.tsx index d80c6e3a125..8d8e5ce69b5 100644 --- a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-setup.test.tsx +++ b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-setup.test.tsx @@ -4,7 +4,7 @@ import { readDirectSetupRequest } from '@/lib/workspace/creation/work-item/direc import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { act, cleanup, fireEvent, render, screen } from '@testing-library/react' import * as preflight from './launch-work-item-direct-preflight' -import * as inventory from '../../../agent-detection-target-inventory' +import * as inventory from '../../../agent-session/launch/inventory/agent-detection-target-inventory' import { useAppStore } from '@/store/index' import { createUIStore } from '@/store/slices/ui/ui-slice-test-harness' diff --git a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-test-fixture.ts b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-test-fixture.ts index 45e8b90cb0b..af9479f7fff 100644 --- a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-test-fixture.ts +++ b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-test-fixture.ts @@ -78,7 +78,7 @@ vi.mock('sonner', () => ({ toast: { error: mocks.toastError, message: vi.fn(), success: vi.fn() } })) -vi.mock('@/lib/agent-paste-draft', () => ({ +vi.mock('@/lib/agent-session/messaging/paste/agent-paste-draft', () => ({ pasteDraftWhenAgentReady: mocks.pasteDraftWhenAgentReady })) diff --git a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-types.ts b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-types.ts index b86e248b8b2..f5b1f8b7cc6 100644 --- a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-types.ts +++ b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct-types.ts @@ -5,7 +5,7 @@ import type { TaskProvider } from '../../../../../../shared/work-items/task-prov import type { TuiAgent } from '../../../../../../shared/agent-launch/catalog/tui-agent' import type { WorkspaceSource as WorkspaceCreateTelemetrySource } from '../../../../../../shared/workspace-source' import type { LaunchSource } from '../../../../../../shared/telemetry-property-schemas' -import type { AgentLaunchChoice } from '@/lib/agent-menu-selection' +import type { AgentLaunchChoice } from '@/lib/agent-session/launch/routing/agent-menu-selection' import type { AgentSessionLaunchRequest } from '../../../agent-session/launch/routing/agent-session-launch-plan' export type DirectWorkItemLaunchInputs = AgentLaunchInputViews & diff --git a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct.ts b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct.ts index bd6c860b325..c6fda4e6826 100644 --- a/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct.ts +++ b/src/renderer/src/lib/workspace/creation/work-item/launch-work-item-direct.ts @@ -1,5 +1,5 @@ import { pickApprovedSetupHashes } from '../../../../../../shared/worktree/approved-setup-hashes' -import { agentLaunchRecoveryMessage } from '@/lib/agent-launch-failure' +import { agentLaunchRecoveryMessage } from '@/lib/agent-session/launch/failure/agent-launch-failure' import { prepareDirectWorkItemSetup } from './direct-work-item-setup' import type { DirectWorkItemLaunchResult } from './direct-work-item-setup' import { useAppStore } from '@/store/index' diff --git a/src/renderer/src/lib/workspace/ownership/workspace-terminal-host-authority.test.ts b/src/renderer/src/lib/workspace/ownership/workspace-terminal-host-authority.test.ts index c48ab04c49a..dab14a46146 100644 --- a/src/renderer/src/lib/workspace/ownership/workspace-terminal-host-authority.test.ts +++ b/src/renderer/src/lib/workspace/ownership/workspace-terminal-host-authority.test.ts @@ -1,6 +1,6 @@ /** Use one remote-authority question for seeding/resume: only none authorizes local terminal creation, never unverifiable. */ import { afterEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore } from '@/store/testing/app-store-test-fixture' import { makeWorktree } from '@/store/slices/worktrees/worktree.test-fixture' import { ensureWorktreeHasInitialTerminal } from '@/lib/workspace/activation/initial-surface/worktree-initial-terminal-seeding' @@ -14,7 +14,7 @@ vi.mock('@/runtime/rpc/calls/runtime-rpc-call', async (importOriginal) => ) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/lib/worktree-activity-state.ts b/src/renderer/src/lib/worktree-activity-state.ts index 968f13d09c3..1a2c77300ce 100644 --- a/src/renderer/src/lib/worktree-activity-state.ts +++ b/src/renderer/src/lib/worktree-activity-state.ts @@ -1,5 +1,5 @@ import type { AppState } from '@/store/types' -import { createAgentStatusEpochSelector } from './agent-status-epoch-selector' +import { createAgentStatusEpochSelector } from './agent-status/evidence/agent-status-epoch-selector' import { tabHasLivePty } from '../../../shared/tab-has-live-pty' import type { TerminalTab } from '../../../shared/workspace-layout/terminal-tab-types' import { isFreshNonDoneAgentStatus } from '../../../shared/agent-status/contracts/agent-status-freshness' diff --git a/src/renderer/src/lib/worktree-status.ts b/src/renderer/src/lib/worktree-status.ts index 793c0814e46..15f033f11c4 100644 --- a/src/renderer/src/lib/worktree-status.ts +++ b/src/renderer/src/lib/worktree-status.ts @@ -1,6 +1,6 @@ import { translate } from '@/i18n/i18n' import { resolveAgentTypeFromTerminalTitle } from '@/components/sidebar/workspace-card/activity/worktree-title-derived-agent-rows' -import { classifyTitleActivity } from '@/lib/pane-agent-evidence' +import { detectAgentStatusFromTitle } from '../../../shared/agent-status/title/agent-title-status' import { tabHasLivePty } from '../../../shared/tab-has-live-pty' import { collectRuntimePaneLeafIds, @@ -128,7 +128,7 @@ function tabHasStatus( continue } if ( - classifyTitleActivity(title) === status && + detectAgentStatusFromTitle(title) === status && titleStatusIsAgentAttributable(title, tab.launchAgent) ) { return true @@ -147,7 +147,7 @@ function tabHasStatus( return false } return ( - classifyTitleActivity(tab.title) === status && + detectAgentStatusFromTitle(tab.title) === status && titleStatusIsAgentAttributable(tab.title, tab.launchAgent) ) } diff --git a/src/renderer/src/runtime/hosted-terminals/creation/web-runtime-terminal-prompt-delivery.test.ts b/src/renderer/src/runtime/hosted-terminals/creation/web-runtime-terminal-prompt-delivery.test.ts index 20960172c63..7deb6cfa246 100644 --- a/src/renderer/src/runtime/hosted-terminals/creation/web-runtime-terminal-prompt-delivery.test.ts +++ b/src/renderer/src/runtime/hosted-terminals/creation/web-runtime-terminal-prompt-delivery.test.ts @@ -7,7 +7,9 @@ const mocks = vi.hoisted(() => ({ write: vi.fn<(_pty: string, _data: string) => Promise>(), draft: vi.fn() })) -vi.mock('@/lib/agent-draft-readiness', () => ({ waitForAgentDraftInputReady: mocks.ready })) +vi.mock('@/lib/agent-session/messaging/paste/agent-draft-readiness', () => ({ + waitForAgentDraftInputReady: mocks.ready +})) vi.mock('@/runtime/hosted-terminals/input/runtime-terminal-verified-input', () => ({ sendRuntimePtyInputVerified: mocks.write })) diff --git a/src/renderer/src/lib/chat-provider-agents.ts b/src/renderer/src/runtime/native-chat/agent-catalogs/chat-provider-agents.ts similarity index 85% rename from src/renderer/src/lib/chat-provider-agents.ts rename to src/renderer/src/runtime/native-chat/agent-catalogs/chat-provider-agents.ts index 38e45869072..97e6df633c2 100644 --- a/src/renderer/src/lib/chat-provider-agents.ts +++ b/src/renderer/src/runtime/native-chat/agent-catalogs/chat-provider-agents.ts @@ -1,6 +1,6 @@ import { useAppViewExternalStore } from '@/store/retained-views/app-state-view' -import type { TuiAgent } from '../../../shared/agent-launch/catalog/tui-agent' -import { isTuiAgent } from '../../../shared/agent-launch/catalog/tui-agent-config' +import type { TuiAgent } from '../../../../../shared/agent-launch/catalog/tui-agent' +import { isTuiAgent } from '../../../../../shared/agent-launch/catalog/tui-agent-config' import { hostStructuredAgentsVersion, readHostStructuredAgents, diff --git a/src/renderer/src/runtime/native-chat/naming/legacy-chat-rename-migration.test.tsx b/src/renderer/src/runtime/native-chat/naming/legacy-chat-rename-migration.test.tsx index c6f13efb56c..dd339731367 100644 --- a/src/renderer/src/runtime/native-chat/naming/legacy-chat-rename-migration.test.tsx +++ b/src/renderer/src/runtime/native-chat/naming/legacy-chat-rename-migration.test.tsx @@ -38,7 +38,7 @@ import type { RuntimeClientTarget } from '../../../../../shared/runtime-client-t import { fetchWorkspaceSessionWithRuntimeHostOwners } from '@/lib/workspace/persistence/workspace-session-host-hydration' import { buildPersistedUnifiedTabSessionData } from '@/lib/workspace/persistence/workspace-session-unified-tabs' import { persistWorkspaceSessionByHost } from '@/lib/workspace/persistence/workspace-session-host-persistence' -import { sendMessageToAgent } from '@/lib/agent-message-send' +import { sendMessageToAgent } from '@/lib/agent-session/messaging/agent-message-send' import type { WorkspaceSessionState } from '../../../../../shared/workspace-session/workspace-session-state-types' import '../../web-session-tabs-sync/snapshot-api' diff --git a/src/renderer/src/runtime/sync-runtime-graph/sync-runtime-graph-conversion-publish.test.ts b/src/renderer/src/runtime/sync-runtime-graph/sync-runtime-graph-conversion-publish.test.ts index 2b153bf933f..71d5824c6e4 100644 --- a/src/renderer/src/runtime/sync-runtime-graph/sync-runtime-graph-conversion-publish.test.ts +++ b/src/renderer/src/runtime/sync-runtime-graph/sync-runtime-graph-conversion-publish.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '../../lib/agent-status' +import type * as AgentStatusModule from '../../lib/agent-status/aggregation/worktree-agent-status' import { buildMobileSessionTabSnapshots } from './mobile-session-snapshots' import { createTestStore } from '../../store/testing/app-store-test-fixture' import { makeWorktree } from '../../store/slices/worktrees/worktree.test-fixture' @@ -14,7 +14,7 @@ vi.mock('@/lib/browser/documents/doc-preview-grants', () => ({ buildDocPreviewGrantRequest: vi.fn() })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/web-session-tabs-sync/agent-status/mirrored-agent-status-clock-skew.test.ts b/src/renderer/src/runtime/web-session-tabs-sync/agent-status/mirrored-agent-status-clock-skew.test.ts index 61e9809768a..0b7aca42250 100644 --- a/src/renderer/src/runtime/web-session-tabs-sync/agent-status/mirrored-agent-status-clock-skew.test.ts +++ b/src/renderer/src/runtime/web-session-tabs-sync/agent-status/mirrored-agent-status-clock-skew.test.ts @@ -1,11 +1,14 @@ // Age mirrored evidence by client receipt time: rendererNow minus hostStamp gains clock skew and makes remote rows immediately stale or permanently fresh. Inject separate host/client clocks. Published freshness verdicts cannot decay during silence; exact repaints must not renew receipt time. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import type { RuntimeMobileSessionTabsResult } from '../../../../../shared/runtime-session-contracts' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../../shared/agent-status/contracts/agent-status-freshness' +import { + AGENT_STATUS_STALE_AFTER_MS, + isAgentStatusFresh +} from '../../../../../shared/agent-status/contracts/agent-status-freshness' import { makePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' import { toWebTerminalSurfaceTabId } from '../../../../../shared/workspace-layout/terminal-surface-id' import { getDefaultSettings } from '../../../../../shared/constants' -import { isExplicitAgentStatusFresh } from '../../../lib/pane-agent-evidence' + import type { AppState } from '../../../store/types' import { createTestStore, seedStore } from '../../../store/testing/app-store-test-fixture' import { makeWorktree } from '../../../store/slices/worktrees/worktree.test-fixture' @@ -111,7 +114,7 @@ function applyChangedHostSnapshot( function mirroredRowIsFreshAt(store: TestStore, clientNow: number): boolean { const row = store.getState().agentStatusByPaneKey[MIRROR_PANE_KEY] expect(row, 'the mirrored row must exist for freshness to mean anything').toBeDefined() - return isExplicitAgentStatusFresh(row, clientNow, AGENT_STATUS_STALE_AFTER_MS) + return isAgentStatusFresh(row, clientNow, AGENT_STATUS_STALE_AFTER_MS) } describe('a mirrored remote row decays on the replica clock, not the host clock', () => { diff --git a/src/renderer/src/runtime/web-session-tabs-sync/agent-status/web-session-tabs-sync-remote-status-title-flap.test.ts b/src/renderer/src/runtime/web-session-tabs-sync/agent-status/web-session-tabs-sync-remote-status-title-flap.test.ts index b5d51b113e1..459de5fee60 100644 --- a/src/renderer/src/runtime/web-session-tabs-sync/agent-status/web-session-tabs-sync-remote-status-title-flap.test.ts +++ b/src/renderer/src/runtime/web-session-tabs-sync/agent-status/web-session-tabs-sync-remote-status-title-flap.test.ts @@ -1,9 +1,12 @@ /** Paired panes receive both client byte-derived status/titles and host snapshot echoes. Proven client ownership must fence stale echoes despite cross-machine clocks; teardown returns authority and host-only states pierce the fence. Drive real mirror/store logic with controlled clocks and assert transition order/count, including generatedLabel and epoch stability. */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import type { RuntimeMobileSessionTabsResult } from '../../../../../shared/runtime-session-contracts' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../../../../shared/agent-status/contracts/agent-status-freshness' +import { + AGENT_STATUS_STALE_AFTER_MS, + isAgentStatusFresh +} from '../../../../../shared/agent-status/contracts/agent-status-freshness' import type { AgentStatusEntry } from '../../../../../shared/agent-status/contracts/agent-status-types' -import { isExplicitAgentStatusFresh } from '@/lib/pane-agent-evidence' + import { makePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' import { toWebTerminalSurfaceTabId } from '../../../../../shared/workspace-layout/terminal-surface-id' import { deriveGeneratedTabTitle } from '../../../../../shared/agent-status/presentation/agent-tab-title' @@ -324,7 +327,7 @@ describe('remote-paired pane: host snapshot mirror vs client byte-derived status const entry = store.getState().agentStatusByPaneKey[MIRROR_PANE_KEY] expect(entry).toBeDefined() expect( - isExplicitAgentStatusFresh(entry!, afterStale, AGENT_STATUS_STALE_AFTER_MS), + isAgentStatusFresh(entry!, afterStale, AGENT_STATUS_STALE_AFTER_MS), 'the retained entry must read as stale so consumers render it idle' ).toBe(false) }) diff --git a/src/renderer/src/runtime/workspace-layout/frames/divider-ratio-refusal.test.ts b/src/renderer/src/runtime/workspace-layout/frames/divider-ratio-refusal.test.ts index 42670aa38a2..be63f36e322 100644 --- a/src/renderer/src/runtime/workspace-layout/frames/divider-ratio-refusal.test.ts +++ b/src/renderer/src/runtime/workspace-layout/frames/divider-ratio-refusal.test.ts @@ -1,7 +1,7 @@ // A stale divider path is refused by main; the window restores main’s unchanged ratios when its tab hold ends. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { useAppStore } from '@/store/index' import type { WorkspaceLayoutModel } from '../../../../../shared/workspace-layout/workspace-layout-model' import { localDesktopSession } from '../../../../../shared/workspace-layout/workspace-layout-profile.test-fixture' @@ -34,7 +34,7 @@ vi.mock('@/runtime/workspace-layout/frames/runtime-layout-client', async (import ).runtimeLayoutClientWithTestFrames(await importOriginal()) ) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/frames/layout-changes-during-stream-outage.test.ts b/src/renderer/src/runtime/workspace-layout/frames/layout-changes-during-stream-outage.test.ts index d63c93aa1bb..b0290960bcf 100644 --- a/src/renderer/src/runtime/workspace-layout/frames/layout-changes-during-stream-outage.test.ts +++ b/src/renderer/src/runtime/workspace-layout/frames/layout-changes-during-stream-outage.test.ts @@ -1,7 +1,7 @@ // During local stream outage, main applies intents and reconnect snapshot draws them. Local main shares this build, so window fallback drawing is unnecessary. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { useAppStore } from '@/store/index' import { applyLayoutCommand, @@ -43,7 +43,7 @@ vi.mock('./workspace-layout-frame-sync', async (importOriginal) => ({ showStartupLayoutFrames: () => {} })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/frames/pane-titles-drawn-from-frames.test.ts b/src/renderer/src/runtime/workspace-layout/frames/pane-titles-drawn-from-frames.test.ts index 3749f9dafa3..dab9b50dc8e 100644 --- a/src/renderer/src/runtime/workspace-layout/frames/pane-titles-drawn-from-frames.test.ts +++ b/src/renderer/src/runtime/workspace-layout/frames/pane-titles-drawn-from-frames.test.ts @@ -1,7 +1,7 @@ // Main applies renames and frames draw titles without a second window write. Shared transport checks each flush against full-build behavior. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { useAppStore } from '@/store/index' import { localDesktopSession } from '../../../../../shared/workspace-layout/workspace-layout-profile.test-fixture' import { leaf } from '../../../../../shared/workspace-layout/workspace-layout-session.test-fixture' @@ -31,7 +31,7 @@ vi.mock('./workspace-layout-frame-sync', async (importOriginal) => ({ showStartupLayoutFrames: () => {} })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-binding.test.ts b/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-binding.test.ts index 2bbbab68dce..867b1b757a1 100644 --- a/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-binding.test.ts +++ b/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-binding.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { WorkspaceSessionState } from '../../../../../shared/workspace-session/workspace-session-state-types' import { loadWorkspaceLayoutWithoutReport } from '../../../../../shared/workspace-layout/workspace-layout-load' import { nameBasedLoadContext } from '../../../../../shared/workspace-layout/workspace-layout-minted-ids' @@ -25,7 +25,7 @@ import { installLayoutFrameApplyCheck } from '../testing/workspace-layout-frame- import { mainLayoutFrameSender } from '../testing/main-loaded-layout-frames.test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-editor-views.test.ts b/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-editor-views.test.ts index 0afde82954a..61abea3ed1a 100644 --- a/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-editor-views.test.ts +++ b/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-editor-views.test.ts @@ -1,7 +1,7 @@ // Frame views reconstruct main-owned diff tabs after window reload, from both records frames and initial snapshots. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { LayoutEditorView } from '../../../../../shared/workspace-layout/layout-editor-view' import { applyLayoutCommand } from '../../../../../shared/workspace-layout/workspace-layout-commands' import type { CommandOf } from '../../../../../shared/workspace-layout/workspace-layout-command-types' @@ -24,7 +24,7 @@ import { installLayoutFrameApplyCheck } from '../testing/workspace-layout-frame- import { openWorkspaceLayoutFrameSync } from './workspace-layout-frame-sync' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-held-tabs.test.ts b/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-held-tabs.test.ts index 686016ecd24..fefdd3de4d8 100644 --- a/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-held-tabs.test.ts +++ b/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-held-tabs.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { Tab } from '../../../../../shared/tab-types' import type { WorkspaceSessionState } from '../../../../../shared/workspace-session/workspace-session-state-types' import type { LayoutApplyReply } from '../../../../../shared/workspace-layout/workspace-layout-command-types' @@ -29,7 +29,7 @@ import { vi.mock('../../../../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-sync.test.ts b/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-sync.test.ts index a183f41b9a5..501b0448a41 100644 --- a/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-sync.test.ts +++ b/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-sync.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { ExecutionHostId } from '../../../../../shared/execution-host' import type { WorkspaceSessionState } from '../../../../../shared/workspace-session/workspace-session-state-types' import { LEGACY_WORKSPACE_LAYOUT_PROFILES } from '../../../../../shared/workspace-layout/workspace-layout-legacy-profile.test-fixture' @@ -32,7 +32,7 @@ import { import { installLayoutFrameApplyCheck } from '../testing/workspace-layout-frame-apply-check.test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-tab-props.test.ts b/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-tab-props.test.ts index 5500c7b2216..828d968e969 100644 --- a/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-tab-props.test.ts +++ b/src/renderer/src/runtime/workspace-layout/frames/workspace-layout-frame-tab-props.test.ts @@ -1,7 +1,7 @@ // Main’s frame-drawn pin/color/rename must match current window actions and survive restart in layout-owner builds. import { afterEach, beforeEach, describe, expect, it, onTestFinished, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { WorkspaceSessionState } from '../../../../../shared/workspace-session/workspace-session-state-types' import { applyLayoutCommand } from '../../../../../shared/workspace-layout/workspace-layout-commands' import type { LayoutCommand } from '../../../../../shared/workspace-layout/workspace-layout-command-types' @@ -43,7 +43,7 @@ vi.mock('@/runtime/rpc/calls/runtime-rpc-call', async (importOriginal) => ) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/server/server-held-panes.test.tsx b/src/renderer/src/runtime/workspace-layout/server/server-held-panes.test.tsx index f7b31577feb..08c43962271 100644 --- a/src/renderer/src/runtime/workspace-layout/server/server-held-panes.test.tsx +++ b/src/renderer/src/runtime/workspace-layout/server/server-held-panes.test.tsx @@ -4,7 +4,7 @@ import { act } from 'react' import { createRoot, type Root } from 'react-dom/client' import { afterEach, beforeEach, describe, expect, it, vi, type Mock } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type * as FrameDrawnModule from '../../web-session-tabs-sync/frame-drawn-server-workspaces' import { makePaneKey } from '../../../../../shared/workspace-layout/stable-pane-id' import { toWebTerminalSurfaceTabId } from '../../../../../shared/workspace-layout/terminal-surface-id' @@ -52,7 +52,7 @@ const hoisted = vi.hoisted( vi.mock('../../../../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/server/server-layout-apply.test.ts b/src/renderer/src/runtime/workspace-layout/server/server-layout-apply.test.ts index 660dd41ff4f..9b563614554 100644 --- a/src/renderer/src/runtime/workspace-layout/server/server-layout-apply.test.ts +++ b/src/renderer/src/runtime/workspace-layout/server/server-layout-apply.test.ts @@ -1,6 +1,6 @@ import type * as RuntimeRpcCallModule from '@/runtime/rpc/calls/runtime-rpc-call' import { afterEach, beforeEach, describe, expect, it, vi, type Mock } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type * as ResolveOwnerModule from '@/lib/workspace/ownership/resolve-owner' import type * as FrameDrawnModule from '../../web-session-tabs-sync/frame-drawn-server-workspaces' @@ -63,7 +63,7 @@ const hoisted = vi.hoisted( vi.mock('../../../../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/server/server-layout-editor-handover.test.ts b/src/renderer/src/runtime/workspace-layout/server/server-layout-editor-handover.test.ts index 86b810f2f56..33c43ced8d2 100644 --- a/src/renderer/src/runtime/workspace-layout/server/server-layout-editor-handover.test.ts +++ b/src/renderer/src/runtime/workspace-layout/server/server-layout-editor-handover.test.ts @@ -1,6 +1,6 @@ import type * as RuntimeRpcCallModule from '@/runtime/rpc/calls/runtime-rpc-call' import { afterEach, beforeEach, describe, expect, it, vi, type Mock } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type * as ResolveOwnerModule from '@/lib/workspace/ownership/resolve-owner' import type * as RuntimeFileMutationClient from '../../files/mutations/runtime-file-mutation-client' @@ -67,7 +67,7 @@ const hoisted = vi.hoisted( vi.mock('../../../../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/server/server-layout-frames-handover.test.ts b/src/renderer/src/runtime/workspace-layout/server/server-layout-frames-handover.test.ts index 293d00849f1..e71fca0a5af 100644 --- a/src/renderer/src/runtime/workspace-layout/server/server-layout-frames-handover.test.ts +++ b/src/renderer/src/runtime/workspace-layout/server/server-layout-frames-handover.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi, type Mock } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type * as FrameDrawnModule from '../../web-session-tabs-sync/frame-drawn-server-workspaces' import type { AppState } from '@/store/types' import { buildWorkspaceSessionPayload } from '@/lib/workspace/persistence/workspace-session' @@ -58,7 +58,7 @@ const hoisted = vi.hoisted( vi.mock('../../../../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/server/server-layout-frames-held-tabs.test.ts b/src/renderer/src/runtime/workspace-layout/server/server-layout-frames-held-tabs.test.ts index b4e93eb24c1..62409cd8b04 100644 --- a/src/renderer/src/runtime/workspace-layout/server/server-layout-frames-held-tabs.test.ts +++ b/src/renderer/src/runtime/workspace-layout/server/server-layout-frames-held-tabs.test.ts @@ -1,6 +1,6 @@ import type * as RuntimeRpcCallModule from '@/runtime/rpc/calls/runtime-rpc-call' import { afterEach, beforeEach, describe, expect, it, vi, type Mock } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type * as ResolveOwnerModule from '@/lib/workspace/ownership/resolve-owner' import type * as WorktreeRuntimeOwnerModule from '@/lib/workspace/ownership/worktree-runtime-owner' @@ -68,7 +68,7 @@ const hoisted = vi.hoisted( vi.mock('../../../../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/runtime/workspace-layout/server/server-layout-frames.test.ts b/src/renderer/src/runtime/workspace-layout/server/server-layout-frames.test.ts index 5126ab119f7..5ec8f77b0c8 100644 --- a/src/renderer/src/runtime/workspace-layout/server/server-layout-frames.test.ts +++ b/src/renderer/src/runtime/workspace-layout/server/server-layout-frames.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi, type Mock } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type * as FrameDrawnModule from '../../web-session-tabs-sync/frame-drawn-server-workspaces' import type { AppState } from '@/store/types' import { toWebTerminalSurfaceTabId } from '../../../../../shared/workspace-layout/terminal-surface-id' @@ -51,7 +51,7 @@ const hoisted = vi.hoisted( vi.mock('../../../../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/repos/store-session-cascades.test.ts b/src/renderer/src/store/repos/store-session-cascades.test.ts index e08e7e5497e..4f20d41111f 100644 --- a/src/renderer/src/store/repos/store-session-cascades.test.ts +++ b/src/renderer/src/store/repos/store-session-cascades.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore } from '../testing/app-store-test-fixture' import { makeWorktree } from '../slices/worktrees/worktree.test-fixture' import { makeTab, makeLayout } from '../terminals/terminal-tab.test-fixture' @@ -7,7 +7,7 @@ import { createStoreSessionMockApi } from '../testing/app-store-session-api.test vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/agent-status/agent-status-live-actions.ts b/src/renderer/src/store/slices/agent-status/agent-status-live-actions.ts index 8e631abfe70..10dfdca7c57 100644 --- a/src/renderer/src/store/slices/agent-status/agent-status-live-actions.ts +++ b/src/renderer/src/store/slices/agent-status/agent-status-live-actions.ts @@ -1,4 +1,4 @@ -import { resolvePaneKey } from '../../../lib/agent-status-pane-ownership' +import { resolvePaneKey } from '../../../lib/agent-status/ownership/agent-status-pane-ownership' import type { AgentStatusSlice } from './agent-status-slice-contract' import type { AgentStatusRuntime } from './agent-status-runtime' import type { diff --git a/src/renderer/src/store/slices/agent-status/agent-status-worktree-purge-leak.test.ts b/src/renderer/src/store/slices/agent-status/agent-status-worktree-purge-leak.test.ts index 37d0707856c..f417613339f 100644 --- a/src/renderer/src/store/slices/agent-status/agent-status-worktree-purge-leak.test.ts +++ b/src/renderer/src/store/slices/agent-status/agent-status-worktree-purge-leak.test.ts @@ -3,7 +3,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' import type { AgentStatusEntry } from '../../../../../shared/agent-status/contracts/agent-status-types' import type { AppState } from '../../types' import type { SleepingAgentSessionRecord } from '../../../../../shared/agent-session/lifecycle/agent-session-resume' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn(), warning: vi.fn() } @@ -16,7 +16,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/browser/cleanup/browser-cleanup-close.test.ts b/src/renderer/src/store/slices/browser/cleanup/browser-cleanup-close.test.ts index 7f2fe92ea43..db83c822f7b 100644 --- a/src/renderer/src/store/slices/browser/cleanup/browser-cleanup-close.test.ts +++ b/src/renderer/src/store/slices/browser/cleanup/browser-cleanup-close.test.ts @@ -1,6 +1,6 @@ import type * as RuntimeRpcCallModule from '@/runtime/rpc/calls/runtime-rpc-call' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore, seedStore } from '../../../testing/app-store-test-fixture' import { makeWorktree } from '../../worktrees/worktree.test-fixture' @@ -24,7 +24,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn(() => []) })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/browser/cleanup/browser-close-focused-group.test.ts b/src/renderer/src/store/slices/browser/cleanup/browser-close-focused-group.test.ts index d2ccc72b60c..2f254821ba6 100644 --- a/src/renderer/src/store/slices/browser/cleanup/browser-close-focused-group.test.ts +++ b/src/renderer/src/store/slices/browser/cleanup/browser-close-focused-group.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore, seedStore } from '../../../testing/app-store-test-fixture' import { makeTab } from '../../../terminals/terminal-tab.test-fixture' import { makeTabGroup, makeUnifiedTab } from '../../tabs/tab-group.test-fixture' @@ -25,7 +25,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/browser/cleanup/browser-close-mru-selection.test.ts b/src/renderer/src/store/slices/browser/cleanup/browser-close-mru-selection.test.ts index 209f77c4534..2ae9b728a19 100644 --- a/src/renderer/src/store/slices/browser/cleanup/browser-close-mru-selection.test.ts +++ b/src/renderer/src/store/slices/browser/cleanup/browser-close-mru-selection.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore, seedStore } from '../../../testing/app-store-test-fixture' import { makeWorktree } from '../../worktrees/worktree.test-fixture' @@ -23,7 +23,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/browser/cleanup/browser-mount-admission-removal.test.ts b/src/renderer/src/store/slices/browser/cleanup/browser-mount-admission-removal.test.ts index 990bb6c28f9..1e536b5709f 100644 --- a/src/renderer/src/store/slices/browser/cleanup/browser-mount-admission-removal.test.ts +++ b/src/renderer/src/store/slices/browser/cleanup/browser-mount-admission-removal.test.ts @@ -1,6 +1,6 @@ /** Release background-page start admission on every removal, including bulk purge; exercise the same sweep as useTerminalWindowLifecycle (STA-7436). */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore, seedStore } from '../../../testing/app-store-test-fixture' import { makeWorktree } from '../../worktrees/worktree.test-fixture' import { createStoreCascadesMockApi } from '../../../testing/app-store-cascade-api.test-fixture' @@ -20,7 +20,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn(() => []) })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/browser/hydration/store-session-browser-hydration.test.ts b/src/renderer/src/store/slices/browser/hydration/store-session-browser-hydration.test.ts index 6a9ba48b8a8..d42b446678f 100644 --- a/src/renderer/src/store/slices/browser/hydration/store-session-browser-hydration.test.ts +++ b/src/renderer/src/store/slices/browser/hydration/store-session-browser-hydration.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { BrowserPage } from '../../../../../../shared/browser-workspace-types' import '../../../../../../shared/constants' import { ORCA_LAYOUT_OWNER_IS_MAIN } from '../../../../../../shared/layout-owner-switch' @@ -16,7 +16,7 @@ import { makeBrowserTab } from '../browser-tab.test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/browser/pages/browser-page-conversion.test.ts b/src/renderer/src/store/slices/browser/pages/browser-page-conversion.test.ts index 0d341ef281d..d1b3a070cee 100644 --- a/src/renderer/src/store/slices/browser/pages/browser-page-conversion.test.ts +++ b/src/renderer/src/store/slices/browser/pages/browser-page-conversion.test.ts @@ -1,6 +1,6 @@ import type * as RuntimeRpcCallModule from '@/runtime/rpc/calls/runtime-rpc-call' import { afterEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { browserPageSchema } from '../../../../../../shared/workspace-session/workspace-session-browser-schema' import { createTestStore } from '../../../testing/app-store-test-fixture' @@ -32,7 +32,7 @@ vi.mock('@/runtime/workspace-layout/frames/runtime-layout-client', async (import ).runtimeLayoutClientWithTestFrames(await importOriginal()) ) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/browser/pages/browser-workspace-doc-location.test.ts b/src/renderer/src/store/slices/browser/pages/browser-workspace-doc-location.test.ts index 8a9462f6074..1019981fc91 100644 --- a/src/renderer/src/store/slices/browser/pages/browser-workspace-doc-location.test.ts +++ b/src/renderer/src/store/slices/browser/pages/browser-workspace-doc-location.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { buildBrowserSessionData } from '@/lib/workspace/persistence/workspace-session-browser-tabs' import { browserPageSchema } from '../../../../../../shared/workspace-session/workspace-session-browser-schema' import { createTestStore } from '../../../testing/app-store-test-fixture' @@ -16,7 +16,7 @@ vi.mock('@/lib/browser/documents/doc-preview-grants', () => ({ buildDocPreviewGrantRequest: vi.fn() })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/browser/tabs/browser-background-tab-creation.test.ts b/src/renderer/src/store/slices/browser/tabs/browser-background-tab-creation.test.ts index d7cff2387e9..184d20ba096 100644 --- a/src/renderer/src/store/slices/browser/tabs/browser-background-tab-creation.test.ts +++ b/src/renderer/src/store/slices/browser/tabs/browser-background-tab-creation.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore, seedStore } from '../../../testing/app-store-test-fixture' import { makeTab } from '../../../terminals/terminal-tab.test-fixture' import { makeWorktree } from '../../worktrees/worktree.test-fixture' @@ -23,7 +23,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/browser/tabs/browser-tab-creation-placement.test.ts b/src/renderer/src/store/slices/browser/tabs/browser-tab-creation-placement.test.ts index af0dcd00a4c..81831aebc18 100644 --- a/src/renderer/src/store/slices/browser/tabs/browser-tab-creation-placement.test.ts +++ b/src/renderer/src/store/slices/browser/tabs/browser-tab-creation-placement.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { Tab, TabGroup } from '../../../../../../shared/tab-types' import type { ExecutionHostId } from '../../../../../../shared/execution-host' @@ -21,7 +21,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus restorePtyDataHandlersAfterFailedShutdown: vi.fn(), unregisterPtyDataHandlers: vi.fn(() => []) })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/diff-comments/diffComments.test.ts b/src/renderer/src/store/slices/diff-comments/diffComments.test.ts index d6c1f357e7f..b4e0c781b3b 100644 --- a/src/renderer/src/store/slices/diff-comments/diffComments.test.ts +++ b/src/renderer/src/store/slices/diff-comments/diffComments.test.ts @@ -11,7 +11,7 @@ import { import { clearRuntimeCompatibilityCache as clearRuntimeCompatibilityCacheForTests } from '../../../runtime/rpc/compatibility/runtime-compatibility-cache' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal>() return { ...actual, diff --git a/src/renderer/src/store/slices/editor/hydration/editor-session-duplicate-restore.test.ts b/src/renderer/src/store/slices/editor/hydration/editor-session-duplicate-restore.test.ts index de2c07f2a26..3246e557648 100644 --- a/src/renderer/src/store/slices/editor/hydration/editor-session-duplicate-restore.test.ts +++ b/src/renderer/src/store/slices/editor/hydration/editor-session-duplicate-restore.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { WorkspaceSessionState } from '../../../../../../shared/workspace-session/workspace-session-state-types' import { folderWorkspaceKey } from '../../../../../../shared/workspace-scope' import { buildWorkspaceSessionPayload } from '../../../../lib/workspace/persistence/workspace-session' @@ -19,7 +19,7 @@ vi.mock('@/runtime/workspace-layout/frames/runtime-layout-client', async (import ).runtimeLayoutClientWithTestFrames(await importOriginal()) ) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/editor/hydration/store-session-editor-hydration.test.ts b/src/renderer/src/store/slices/editor/hydration/store-session-editor-hydration.test.ts index 4d4186af5f7..ef5681a3f34 100644 --- a/src/renderer/src/store/slices/editor/hydration/store-session-editor-hydration.test.ts +++ b/src/renderer/src/store/slices/editor/hydration/store-session-editor-hydration.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { FLOATING_TERMINAL_WORKTREE_ID } from '../../../../../../shared/constants' import { createTestStore } from '../../../testing/app-store-test-fixture' import { makeWorktree } from '../../worktrees/worktree.test-fixture' @@ -7,7 +7,7 @@ import { createStoreSessionMockApi } from '../../../testing/app-store-session-ap vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/editor/tabs/editor-state-worktree-purge-leak.test.ts b/src/renderer/src/store/slices/editor/tabs/editor-state-worktree-purge-leak.test.ts index e8ea01eb1c5..3da246c43e4 100644 --- a/src/renderer/src/store/slices/editor/tabs/editor-state-worktree-purge-leak.test.ts +++ b/src/renderer/src/store/slices/editor/tabs/editor-state-worktree-purge-leak.test.ts @@ -1,6 +1,6 @@ /** Both single/bulk worktree removal must evict editorCursorLine/editorViewMode by file and gitStatusHugeByWorktree; missed keys leak per removed file/worktree for renderer lifetime. */ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn(), warning: vi.fn() } @@ -13,7 +13,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/editor/tabs/editor-tab-layout-owner.test.ts b/src/renderer/src/store/slices/editor/tabs/editor-tab-layout-owner.test.ts index 8d902dde082..85c8f3b024e 100644 --- a/src/renderer/src/store/slices/editor/tabs/editor-tab-layout-owner.test.ts +++ b/src/renderer/src/store/slices/editor/tabs/editor-tab-layout-owner.test.ts @@ -1,6 +1,6 @@ // Layout-owner editor opens/closes/promotions draw only from main frames; switch-off cases draw locally without main. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { ORCA_LAYOUT_OWNER_IS_MAIN } from '../../../../../../shared/layout-owner-switch' import type { Tab } from '../../../../../../shared/tab-types' import { layoutApplyTestTransport } from '@/runtime/workspace-layout/testing/layout-apply-test-transport.test-fixture' @@ -24,7 +24,7 @@ vi.mock('@/runtime/workspace-layout/frames/runtime-layout-client', async (import ).runtimeLayoutClientWithTestFrames(await importOriginal()) ) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/settings/settings.test.ts b/src/renderer/src/store/slices/settings/settings.test.ts index 7d2ddfe9be0..64c88b8b55d 100644 --- a/src/renderer/src/store/slices/settings/settings.test.ts +++ b/src/renderer/src/store/slices/settings/settings.test.ts @@ -17,7 +17,7 @@ import { } from '../runtime-status/runtime-status-hydration' vi.mock('sonner', () => ({ toast: { error: vi.fn(), success: vi.fn(), info: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal>() return { ...actual, diff --git a/src/renderer/src/store/slices/tabs/content-tabs-from-main-frames.test.ts b/src/renderer/src/store/slices/tabs/content-tabs-from-main-frames.test.ts index c2e41238c11..c380d8040a3 100644 --- a/src/renderer/src/store/slices/tabs/content-tabs-from-main-frames.test.ts +++ b/src/renderer/src/store/slices/tabs/content-tabs-from-main-frames.test.ts @@ -1,6 +1,6 @@ // Layout-owner browser/chat/simulator commands draw only from main’s answers; refusals preserve tabs. With switch off, window draws without sending main. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { ORCA_LAYOUT_OWNER_IS_MAIN } from '../../../../../shared/layout-owner-switch' import '../../../../../shared/agent-session/view/structured-agent-session-projection' @@ -30,7 +30,7 @@ vi.mock('@/store/index', () => ({ vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn(), warning: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/tabs/recently-closed-tab-position.test.ts b/src/renderer/src/store/slices/tabs/recently-closed-tab-position.test.ts index 904bec02964..024e3ca8c99 100644 --- a/src/renderer/src/store/slices/tabs/recently-closed-tab-position.test.ts +++ b/src/renderer/src/store/slices/tabs/recently-closed-tab-position.test.ts @@ -1,6 +1,6 @@ // Reopen terminal/browser/editor snapshots in true cross-type MRU order via Cmd/Ctrl+Shift+T. import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn(), warning: vi.fn() } @@ -13,7 +13,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/tabs/recently-closed-tabs.test.ts b/src/renderer/src/store/slices/tabs/recently-closed-tabs.test.ts index fa9a870840d..9b6f6fa23f4 100644 --- a/src/renderer/src/store/slices/tabs/recently-closed-tabs.test.ts +++ b/src/renderer/src/store/slices/tabs/recently-closed-tabs.test.ts @@ -1,6 +1,6 @@ // Reopen terminal/browser/editor snapshots in true cross-type MRU order via Cmd/Ctrl+Shift+T. import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn(), warning: vi.fn() } @@ -13,7 +13,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/tabs/store-open-to-side-layout-owner.test.ts b/src/renderer/src/store/slices/tabs/store-open-to-side-layout-owner.test.ts index 4e5025c7b8e..b2c66ea20e6 100644 --- a/src/renderer/src/store/slices/tabs/store-open-to-side-layout-owner.test.ts +++ b/src/renderer/src/store/slices/tabs/store-open-to-side-layout-owner.test.ts @@ -1,6 +1,6 @@ // With main layout ownership, each split and tab must reach main together; drawn frames must preserve group parity. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore, seedStore } from '../../testing/app-store-test-fixture' import { makeWorktree } from '../worktrees/worktree.test-fixture' import { createStoreCascadesMockApi } from '../../testing/app-store-cascade-api.test-fixture' @@ -26,7 +26,7 @@ vi.mock('@/runtime/workspace-layout/frames/runtime-layout-client', async (import vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn(), warning: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/tabs/tabs-label-and-pin-state.test.ts b/src/renderer/src/store/slices/tabs/tabs-label-and-pin-state.test.ts index d06266b63fc..2f4c8a37b20 100644 --- a/src/renderer/src/store/slices/tabs/tabs-label-and-pin-state.test.ts +++ b/src/renderer/src/store/slices/tabs/tabs-label-and-pin-state.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeEach, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTabsSliceMockApi } from './tabs-slice-test-harness' import { createTestStore } from '../../testing/app-store-test-fixture' import { makeOpenFile } from '../editor/types/open-file.test-fixture' @@ -10,7 +10,7 @@ import { ORCA_LAYOUT_OWNER_IS_MAIN } from '../../../../../shared/layout-owner-sw vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/tabs/tabs-model-reconciliation.test.ts b/src/renderer/src/store/slices/tabs/tabs-model-reconciliation.test.ts index 91016939c8f..18ce743ade8 100644 --- a/src/renderer/src/store/slices/tabs/tabs-model-reconciliation.test.ts +++ b/src/renderer/src/store/slices/tabs/tabs-model-reconciliation.test.ts @@ -1,11 +1,11 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTabsSliceMockApi } from './tabs-slice-test-harness' import { createTestStore } from '../../testing/app-store-test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/tabs/tabs-open-close-lifecycle.test.ts b/src/renderer/src/store/slices/tabs/tabs-open-close-lifecycle.test.ts index 0143a736bd8..62ae5a0cf80 100644 --- a/src/renderer/src/store/slices/tabs/tabs-open-close-lifecycle.test.ts +++ b/src/renderer/src/store/slices/tabs/tabs-open-close-lifecycle.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import '../../../../../shared/constants' import { buildMobileSessionTabSnapshots } from '../../../runtime/sync-runtime-graph/mobile-session-snapshots' import { closeMobileSessionTabInStore } from '../../../runtime/web-session-tabs-sync/closing/mobile-session-tab-close' @@ -25,7 +25,7 @@ vi.mock('@/runtime/workspace-layout/frames/runtime-layout-client', async (import vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/tabs/tabs-pane-layout-operations.test.ts b/src/renderer/src/store/slices/tabs/tabs-pane-layout-operations.test.ts index d3cbd368171..89825e8834f 100644 --- a/src/renderer/src/store/slices/tabs/tabs-pane-layout-operations.test.ts +++ b/src/renderer/src/store/slices/tabs/tabs-pane-layout-operations.test.ts @@ -1,11 +1,11 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTabsSliceMockApi } from './tabs-slice-test-harness' import { createTestStore } from '../../testing/app-store-test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/tabs/tabs-split-create.test.ts b/src/renderer/src/store/slices/tabs/tabs-split-create.test.ts index 8dd87fdfe74..5207055ee99 100644 --- a/src/renderer/src/store/slices/tabs/tabs-split-create.test.ts +++ b/src/renderer/src/store/slices/tabs/tabs-split-create.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { AppState } from '../../types' import { createTabsSliceMockApi } from './tabs-slice-test-harness' import { createTestStore, seedStore } from '../../testing/app-store-test-fixture' @@ -7,7 +7,7 @@ import { makeWorktree } from '../worktrees/worktree.test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/tabs/tabs-unread-and-focus.test.ts b/src/renderer/src/store/slices/tabs/tabs-unread-and-focus.test.ts index 05be8dfb080..3d99b48c477 100644 --- a/src/renderer/src/store/slices/tabs/tabs-unread-and-focus.test.ts +++ b/src/renderer/src/store/slices/tabs/tabs-unread-and-focus.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' import { resolveAutoAckTabTargets } from '@/hooks/agent-auto-ack-targets' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTabsSliceMockApi } from './tabs-slice-test-harness' import { createTestStore } from '../../testing/app-store-test-fixture' import { makeOpenFile } from '../editor/types/open-file.test-fixture' @@ -10,7 +10,7 @@ import { ORCA_LAYOUT_OWNER_IS_MAIN } from '../../../../../shared/layout-owner-sw vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/ui/ui-agent-send-target.test.ts b/src/renderer/src/store/slices/ui/ui-agent-send-target.test.ts index 17ad4cea94d..6e381974823 100644 --- a/src/renderer/src/store/slices/ui/ui-agent-send-target.test.ts +++ b/src/renderer/src/store/slices/ui/ui-agent-send-target.test.ts @@ -20,12 +20,14 @@ const mocks = vi.hoisted(() => ({ toastError: vi.fn() })) -vi.mock('@/lib/active-agent-note-send', () => ({ +vi.mock('@/lib/agent-session/messaging/terminal/active-agent-note-send', () => ({ + sendNotesToActiveAgentSession: mocks.sendNotesToActiveAgentSession +})) +vi.mock('@/lib/agent-session/messaging/terminal/active-agent-note-send-result', () => ({ activeAgentNotesSendFailureMessage: ( status: string, options: { explicitTarget?: boolean } = {} - ) => (options.explicitTarget ? `selected:${status}` : status), - sendNotesToActiveAgentSession: mocks.sendNotesToActiveAgentSession + ) => (options.explicitTarget ? `selected:${status}` : status) })) vi.mock( diff --git a/src/renderer/src/store/slices/ui/ui-feature-interactions.test.ts b/src/renderer/src/store/slices/ui/ui-feature-interactions.test.ts index 4f3a9fb4dce..668babba9a8 100644 --- a/src/renderer/src/store/slices/ui/ui-feature-interactions.test.ts +++ b/src/renderer/src/store/slices/ui/ui-feature-interactions.test.ts @@ -11,12 +11,14 @@ const mocks = vi.hoisted(() => ({ toastError: vi.fn() })) -vi.mock('@/lib/active-agent-note-send', () => ({ +vi.mock('@/lib/agent-session/messaging/terminal/active-agent-note-send', () => ({ + sendNotesToActiveAgentSession: mocks.sendNotesToActiveAgentSession +})) +vi.mock('@/lib/agent-session/messaging/terminal/active-agent-note-send-result', () => ({ activeAgentNotesSendFailureMessage: ( status: string, options: { explicitTarget?: boolean } = {} - ) => (options.explicitTarget ? `selected:${status}` : status), - sendNotesToActiveAgentSession: mocks.sendNotesToActiveAgentSession + ) => (options.explicitTarget ? `selected:${status}` : status) })) vi.mock('@/lib/telemetry', () => ({ diff --git a/src/renderer/src/store/slices/ui/ui-slice-agent-actions.ts b/src/renderer/src/store/slices/ui/ui-slice-agent-actions.ts index 8df16e5a40b..572c9948da5 100644 --- a/src/renderer/src/store/slices/ui/ui-slice-agent-actions.ts +++ b/src/renderer/src/store/slices/ui/ui-slice-agent-actions.ts @@ -1,12 +1,12 @@ import type { UISlice, UISliceGet, UISliceSet } from './ui-slice-contract' import { formatAgentTypeLabel } from '../../../../../shared/agent-status/presentation/agent-type-label' -import { agentKindForAgentType } from '../../../lib/agent-status' +import { agentKindForAgentType } from '../../../lib/agent-status/aggregation/worktree-agent-status' import { deriveRunningAgentSendTargets, resolveRunningAgentSendTarget, runningAgentMessageTarget, runningAgentSendTargetAgentType -} from '../../../lib/running-agent-targets' +} from '../../../lib/agent-session/messaging/running-agent-targets' import { translate } from '@/i18n/i18n' import { createUiActivityActions } from './ui-slice-activity-actions' @@ -154,9 +154,10 @@ export function createUiAgentActions( const agentType = runningAgentSendTargetAgentType(target) const label = formatAgentTypeLabel(agentType) - const [{ activeAgentNotesSendFailureMessage }, { sendMessageToAgent }] = await Promise.all([ - import('@/lib/active-agent-note-send'), - import('@/lib/agent-message-send') + const [, { activeAgentNotesSendFailureMessage }, { sendMessageToAgent }] = await Promise.all([ + import('@/lib/agent-session/messaging/terminal/active-agent-note-send'), + import('@/lib/agent-session/messaging/terminal/active-agent-note-send-result'), + import('@/lib/agent-session/messaging/agent-message-send') ]) const sending = sendMessageToAgent({ worktreeId: mode.worktreeId, diff --git a/src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-local-evidence.ts b/src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-local-evidence.ts index 946ae7a43c6..f3a54741829 100644 --- a/src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-local-evidence.ts +++ b/src/renderer/src/store/slices/workspace-cleanup/workspace-cleanup-local-evidence.ts @@ -1,5 +1,5 @@ import type { AppState } from '../../types' -import { classifyTitleActivity } from '@/lib/pane-agent-evidence' +import { detectAgentStatusFromTitle } from '../../../../../shared/agent-status/title/agent-title-status' import { getWorktreeIdsWithLiveAgent } from '@/lib/worktree-activity-state' import type { WorkspaceCleanupCandidate } from '../../../../../shared/workspace-cleanup/workspace-cleanup' import { getWorktreeVisitTimestamp } from '@/lib/workspace/activation/worktree-visit-recency' @@ -163,7 +163,7 @@ function hasIdleAgentTitleForPty( } function isIdleAgentTitle(title: string): boolean { - return classifyTitleActivity(title) === 'idle' + return detectAgentStatusFromTitle(title) === 'idle' } function normalizeProcessName(value: string | null): string | null { diff --git a/src/renderer/src/store/slices/worktrees/session/store-active-worktree-selection.test.ts b/src/renderer/src/store/slices/worktrees/session/store-active-worktree-selection.test.ts index 34bd185d7a0..dd48af07e5f 100644 --- a/src/renderer/src/store/slices/worktrees/session/store-active-worktree-selection.test.ts +++ b/src/renderer/src/store/slices/worktrees/session/store-active-worktree-selection.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' import '../../workspace-attention/workspace-unread-characterization-fixture' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { buildWorktreeComparator } from '../../../../../../shared/sidebar-list/smart-sort' import '../../../../../../shared/workspace-scope' import { createTestStore, seedStore } from '../../../testing/app-store-test-fixture' @@ -24,7 +24,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/worktrees/teardown/ambiguous-owner-warning-worktree-removal-leak.test.ts b/src/renderer/src/store/slices/worktrees/teardown/ambiguous-owner-warning-worktree-removal-leak.test.ts index 6c95e11fd9c..d8f03948ee5 100644 --- a/src/renderer/src/store/slices/worktrees/teardown/ambiguous-owner-warning-worktree-removal-leak.test.ts +++ b/src/renderer/src/store/slices/worktrees/teardown/ambiguous-owner-warning-worktree-removal-leak.test.ts @@ -1,6 +1,6 @@ /** Purge module-level ambiguous-owner warning keys on both removal paths. Otherwise IDs leak forever and recreated workspaces cannot report newly ambiguous ownership. */ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn(), warning: vi.fn() } @@ -13,7 +13,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/worktrees/teardown/bulk-worktree-purge-terminal-maps-leak.test.ts b/src/renderer/src/store/slices/worktrees/teardown/bulk-worktree-purge-terminal-maps-leak.test.ts index 98391454edc..354cf68eff7 100644 --- a/src/renderer/src/store/slices/worktrees/teardown/bulk-worktree-purge-terminal-maps-leak.test.ts +++ b/src/renderer/src/store/slices/worktrees/teardown/bulk-worktree-purge-terminal-maps-leak.test.ts @@ -1,6 +1,6 @@ /** Bulk purge runs no terminal teardown; evict tab maps and PTY maps from live/durable bindings like single removal. External scans/project removal/hydration otherwise leak ephemeral terminal/agent keys for renderer lifetime. */ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type * as RemoteRuntimePtyIdModule from '../../../../../../shared/remote-runtime/remote-runtime-pty-id' vi.mock('sonner', () => ({ @@ -14,7 +14,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/worktrees/teardown/generation-records-worktree-removal-leak.test.ts b/src/renderer/src/store/slices/worktrees/teardown/generation-records-worktree-removal-leak.test.ts index f6ecba093b9..520f0fef35d 100644 --- a/src/renderer/src/store/slices/worktrees/teardown/generation-records-worktree-removal-leak.test.ts +++ b/src/renderer/src/store/slices/worktrees/teardown/generation-records-worktree-removal-leak.test.ts @@ -1,6 +1,6 @@ /** Worktree removal must call both generation pruners; PR title/body and commit-message records otherwise leak text under ephemeral worktree/branch keys for renderer lifetime. */ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn(), warning: vi.fn() } @@ -13,7 +13,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/worktrees/teardown/native-chat-launch-draft-teardown.test.ts b/src/renderer/src/store/slices/worktrees/teardown/native-chat-launch-draft-teardown.test.ts index 23826658657..fba83e07b1c 100644 --- a/src/renderer/src/store/slices/worktrees/teardown/native-chat-launch-draft-teardown.test.ts +++ b/src/renderer/src/store/slices/worktrees/teardown/native-chat-launch-draft-teardown.test.ts @@ -1,6 +1,6 @@ /** Evict nativeChatLaunchDraftByTabId wherever launch prompt retires (close, orphan sweep, bulk/single purge); stranded drafts otherwise keep publishing to mobile. */ import { afterEach, describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { drawTabsFromMain, @@ -18,7 +18,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/worktrees/teardown/removed-worktree-renderer-teardown.ts b/src/renderer/src/store/slices/worktrees/teardown/removed-worktree-renderer-teardown.ts index d811997dffe..7f156859b6f 100644 --- a/src/renderer/src/store/slices/worktrees/teardown/removed-worktree-renderer-teardown.ts +++ b/src/renderer/src/store/slices/worktrees/teardown/removed-worktree-renderer-teardown.ts @@ -4,7 +4,7 @@ import type { WorktreeCatalogVersion } from '../../../../../../shared/worktree/c import { getRepoIdFromWorktreeId } from '../../../../../../shared/worktree/id' import { appliedWorktreeCatalogVersionPatch } from '../listing/worktree-catalog-version-state' import { cleanupEphemeralVmRuntimesForDeleted } from '@/lib/ephemeral-vm-runtime-cleanup' -import { forgetAgentStartupDeliveriesForTabs } from '@/lib/agent-startup-delivery-guards' +import { forgetAgentStartupDeliveriesForTabs } from '@/lib/agent-session/launch/startup/agent-startup-delivery-guards' import { forgetForegroundTerminalTabs } from '@/lib/foreground-terminal-tabs' import { requestVirtualizedScrollAnchorRecord } from '@/hooks/requestVirtualizedScrollAnchorRecord' import { disposeRemovedWorktreeParkedTerminalWatchers } from '../../../../components/terminal-pane/parking/output-watchers/terminal-parked-watcher-registry' diff --git a/src/renderer/src/store/slices/worktrees/teardown/store-worktree-removal-cascade.test.ts b/src/renderer/src/store/slices/worktrees/teardown/store-worktree-removal-cascade.test.ts index 90f6bcbfcd7..6a461cb9e45 100644 --- a/src/renderer/src/store/slices/worktrees/teardown/store-worktree-removal-cascade.test.ts +++ b/src/renderer/src/store/slices/worktrees/teardown/store-worktree-removal-cascade.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { getDefaultSettings } from '../../../../../../shared/constants' import { createCompatibleRuntimeStatusResponseIfNeeded } from '../../../../runtime/rpc/testing/runtime-compatibility-test-fixture' import { clearRuntimeCompatibilityCache as clearRuntimeCompatibilityCacheForTests } from '../../../../runtime/rpc/compatibility/runtime-compatibility-cache' @@ -25,7 +25,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/slices/worktrees/teardown/tab-worktree-orphan-map-purge-leak.test.ts b/src/renderer/src/store/slices/worktrees/teardown/tab-worktree-orphan-map-purge-leak.test.ts index fafb84df9af..47f1bfb0b94 100644 --- a/src/renderer/src/store/slices/worktrees/teardown/tab-worktree-orphan-map-purge-leak.test.ts +++ b/src/renderer/src/store/slices/worktrees/teardown/tab-worktree-orphan-map-purge-leak.test.ts @@ -1,6 +1,6 @@ /** Removal must evict detached-name, foreground-last-seen and consumed-startup guards; fresh tab/worktree IDs cannot reclaim leaked module entries. */ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { getForegroundTerminalTabLastSeenAtById, resetForegroundTerminalTabIdsForTests, @@ -9,7 +9,7 @@ import { import { beginAgentStartupDeliveryAttempt, resetAgentStartupDelayedDeliveryForTests -} from '@/lib/agent-startup-delayed-delivery' +} from '@/lib/agent-session/launch/startup/agent-startup-delayed-delivery' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn(), warning: vi.fn() } @@ -22,7 +22,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/worktrees/teardown/workspace-chat-draft-removal.test.ts b/src/renderer/src/store/slices/worktrees/teardown/workspace-chat-draft-removal.test.ts index eca0caeae25..1713e1fb2ae 100644 --- a/src/renderer/src/store/slices/worktrees/teardown/workspace-chat-draft-removal.test.ts +++ b/src/renderer/src/store/slices/worktrees/teardown/workspace-chat-draft-removal.test.ts @@ -1,6 +1,6 @@ /** User deletion clears drafts using pre-RPC keys; host removal announcements may purge listings before reply, while non-user purges must retain drafts. */ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { FolderWorkspace } from '../../../../../../shared/folder-workspaces/folder-workspace-types' import '../../../../../../shared/execution-host' @@ -15,7 +15,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus restorePtyDataHandlersAfterFailedShutdown: vi.fn(), unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/slices/worktrees/teardown/worktree-purge-doomed-ids.ts b/src/renderer/src/store/slices/worktrees/teardown/worktree-purge-doomed-ids.ts index ad7fe2fee68..87d2f56e950 100644 --- a/src/renderer/src/store/slices/worktrees/teardown/worktree-purge-doomed-ids.ts +++ b/src/renderer/src/store/slices/worktrees/teardown/worktree-purge-doomed-ids.ts @@ -1,7 +1,7 @@ import type { AppState } from '../../../types' import { forgetAgentHibernationTabOutput } from '@/lib/agent-session/hibernation/agent-hibernation-output-activity' import { forgetForegroundTerminalTabs } from '@/lib/foreground-terminal-tabs' -import { forgetAgentStartupDeliveriesForTabs } from '@/lib/agent-startup-delivery-guards' +import { forgetAgentStartupDeliveriesForTabs } from '@/lib/agent-session/launch/startup/agent-startup-delivery-guards' import { forgetAgentPaneAuthorityAliasesByTabIds } from '../../agent-status/agent-pane-authority' import { forgetDetachedHeadAutoDerivedDisplayName } from '../metadata/detached-head-display-name' diff --git a/src/renderer/src/store/terminals/recently-closed-terminal-tabs.test.ts b/src/renderer/src/store/terminals/recently-closed-terminal-tabs.test.ts index 12eb030ef42..21b156b63c7 100644 --- a/src/renderer/src/store/terminals/recently-closed-terminal-tabs.test.ts +++ b/src/renderer/src/store/terminals/recently-closed-terminal-tabs.test.ts @@ -1,6 +1,6 @@ // Reopen terminal/browser/editor snapshots in true cross-type MRU order via Cmd/Ctrl+Shift+T. import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { getDefaultSettings } from '../../../../shared/constants' vi.mock('sonner', () => ({ @@ -14,7 +14,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/terminals/retired-terminal-tab-state-sweep.ts b/src/renderer/src/store/terminals/retired-terminal-tab-state-sweep.ts index 40783549fb1..b68c748bd27 100644 --- a/src/renderer/src/store/terminals/retired-terminal-tab-state-sweep.ts +++ b/src/renderer/src/store/terminals/retired-terminal-tab-state-sweep.ts @@ -2,7 +2,7 @@ import { removePaneKeys } from '../slices/agent-status/agent-status-pane-keyed-r import type { AppState } from '../types' import { forgetAgentHibernationTabOutput } from '@/lib/agent-session/hibernation/agent-hibernation-output-activity' import { forgetForegroundTerminalTabs } from '@/lib/foreground-terminal-tabs' -import { forgetAgentStartupDeliveriesForTabs } from '@/lib/agent-startup-delivery-guards' +import { forgetAgentStartupDeliveriesForTabs } from '@/lib/agent-session/launch/startup/agent-startup-delivery-guards' // Use store-free registry to avoid a slice-evaluation cycle through terminal-parked-tab-watchers. import { retireParkedTerminalTab } from '@/components/terminal-pane/parking/output-watchers/terminal-parked-watcher-registry' import { forgetNativeChatPromptDismissalsForTab } from '@/components/native-chat/prompts/native-chat-prompt-dismissals' diff --git a/src/renderer/src/store/terminals/store-create-tab-start-in-main.test.ts b/src/renderer/src/store/terminals/store-create-tab-start-in-main.test.ts index 91e2155df8f..46c66ee78c7 100644 --- a/src/renderer/src/store/terminals/store-create-tab-start-in-main.test.ts +++ b/src/renderer/src/store/terminals/store-create-tab-start-in-main.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore, seedStore } from '../testing/app-store-test-fixture' import { makeWorktree } from '../slices/worktrees/worktree.test-fixture' import { createStoreCascadesMockApi } from '../testing/app-store-cascade-api.test-fixture' @@ -32,7 +32,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus restorePtyDataHandlersAfterFailedShutdown: vi.fn(), unregisterPtyDataHandlers: vi.fn(() => []) })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/terminals/store-session-terminal-reconnect.test.ts b/src/renderer/src/store/terminals/store-session-terminal-reconnect.test.ts index f8d2d5f85b9..a737c5d6f2d 100644 --- a/src/renderer/src/store/terminals/store-session-terminal-reconnect.test.ts +++ b/src/renderer/src/store/terminals/store-session-terminal-reconnect.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { isTerminalLeafId } from '../../../../shared/workspace-layout/stable-pane-id' import { createTestStore } from '../testing/app-store-test-fixture' import { makeWorktree } from '../slices/worktrees/worktree.test-fixture' @@ -11,7 +11,7 @@ import { LOCAL_EXECUTION_HOST_ID } from '../../../../shared/execution-host' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/terminals/store-session-workspace-hydration.test.ts b/src/renderer/src/store/terminals/store-session-workspace-hydration.test.ts index ecd96b390d9..d8e1856b6db 100644 --- a/src/renderer/src/store/terminals/store-session-workspace-hydration.test.ts +++ b/src/renderer/src/store/terminals/store-session-workspace-hydration.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { DetectedWorktreeListResult, Worktree } from '../../../../shared/worktree/types' import { getDefaultWorkspaceSession } from '../../../../shared/constants' import { folderWorkspaceKey } from '../../../../shared/workspace-scope' @@ -10,7 +10,7 @@ import { makeBrowserTab } from '../slices/browser/browser-tab.test-fixture' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/terminals/store-sleep-agent-status-retention.test.ts b/src/renderer/src/store/terminals/store-sleep-agent-status-retention.test.ts index 58bfd627d40..a3fe23ddccf 100644 --- a/src/renderer/src/store/terminals/store-sleep-agent-status-retention.test.ts +++ b/src/renderer/src/store/terminals/store-sleep-agent-status-retention.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { clearRuntimeCompatibilityCache as clearRuntimeCompatibilityCacheForTests } from '../../runtime/rpc/compatibility/runtime-compatibility-cache' import { createTestStore, seedStore } from '../testing/app-store-test-fixture' import { makeTab } from './terminal-tab.test-fixture' @@ -22,7 +22,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/terminals/store-sleep-exact-runtime-stop.test.ts b/src/renderer/src/store/terminals/store-sleep-exact-runtime-stop.test.ts index 239d3d72f46..bf6c1586b36 100644 --- a/src/renderer/src/store/terminals/store-sleep-exact-runtime-stop.test.ts +++ b/src/renderer/src/store/terminals/store-sleep-exact-runtime-stop.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { getDefaultSettings } from '../../../../shared/constants' import { createCompatibleRuntimeStatusResponseIfNeeded } from '../../runtime/rpc/testing/runtime-compatibility-test-fixture' import { clearRuntimeCompatibilityCache as clearRuntimeCompatibilityCacheForTests } from '../../runtime/rpc/compatibility/runtime-compatibility-cache' @@ -24,7 +24,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/terminals/store-sleep-pane-hibernation.test.ts b/src/renderer/src/store/terminals/store-sleep-pane-hibernation.test.ts index 6ed496886a7..3322852185e 100644 --- a/src/renderer/src/store/terminals/store-sleep-pane-hibernation.test.ts +++ b/src/renderer/src/store/terminals/store-sleep-pane-hibernation.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { getDefaultSettings } from '../../../../shared/constants' import { createCompatibleRuntimeStatusResponseIfNeeded } from '../../runtime/rpc/testing/runtime-compatibility-test-fixture' import { clearRuntimeCompatibilityCache as clearRuntimeCompatibilityCacheForTests } from '../../runtime/rpc/compatibility/runtime-compatibility-cache' @@ -25,7 +25,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/terminals/store-sleep-runtime-convergence.test.ts b/src/renderer/src/store/terminals/store-sleep-runtime-convergence.test.ts index e82c391f8d5..12ac0314bc8 100644 --- a/src/renderer/src/store/terminals/store-sleep-runtime-convergence.test.ts +++ b/src/renderer/src/store/terminals/store-sleep-runtime-convergence.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import '../../../../shared/constants' import { clearRuntimeCompatibilityCache as clearRuntimeCompatibilityCacheForTests } from '../../runtime/rpc/compatibility/runtime-compatibility-cache' import { createTestStore, seedStore } from '../testing/app-store-test-fixture' @@ -23,7 +23,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/terminals/store-sleep-twin-host-owner.test.ts b/src/renderer/src/store/terminals/store-sleep-twin-host-owner.test.ts index cb8dec87a26..404d7c15730 100644 --- a/src/renderer/src/store/terminals/store-sleep-twin-host-owner.test.ts +++ b/src/renderer/src/store/terminals/store-sleep-twin-host-owner.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createCompatibleRuntimeStatusResponseIfNeeded } from '../../runtime/rpc/testing/runtime-compatibility-test-fixture' import { clearRuntimeCompatibilityCache as clearRuntimeCompatibilityCacheForTests } from '../../runtime/rpc/compatibility/runtime-compatibility-cache' import { createTestStore, seedStore } from '../testing/app-store-test-fixture' @@ -23,7 +23,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/terminals/terminal-active-workspace-creation.test.ts b/src/renderer/src/store/terminals/terminal-active-workspace-creation.test.ts index 15a325634b0..02a82ac0363 100644 --- a/src/renderer/src/store/terminals/terminal-active-workspace-creation.test.ts +++ b/src/renderer/src/store/terminals/terminal-active-workspace-creation.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { getDefaultSettings } from '../../../../shared/constants' import { createTestStore, seedStore } from '../testing/app-store-test-fixture' @@ -25,7 +25,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/terminals/terminal-creation-orphan-retention.test.ts b/src/renderer/src/store/terminals/terminal-creation-orphan-retention.test.ts index 451094ff168..61bf1a4c5b4 100644 --- a/src/renderer/src/store/terminals/terminal-creation-orphan-retention.test.ts +++ b/src/renderer/src/store/terminals/terminal-creation-orphan-retention.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore, seedStore } from '../testing/app-store-test-fixture' import { makeLayout, makeTab } from './terminal-tab.test-fixture' import { makeTabGroup, makeUnifiedTab } from '../slices/tabs/tab-group.test-fixture' @@ -21,7 +21,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/terminals/terminal-ephemeral-state.ts b/src/renderer/src/store/terminals/terminal-ephemeral-state.ts index 0c7478bdcb3..92e0bdac894 100644 --- a/src/renderer/src/store/terminals/terminal-ephemeral-state.ts +++ b/src/renderer/src/store/terminals/terminal-ephemeral-state.ts @@ -1,6 +1,6 @@ import { isClaudeAgent as isClaudeAgentDefault } from '../../../../shared/agent-status/title/agent-title-identity' import { recordTerminalInputActivity } from '@/lib/terminal-input-activity-coalescing' -import { classifyTitleActivity } from '@/lib/pane-agent-evidence' +import { detectAgentStatusFromTitle } from '../../../../shared/agent-status/title/agent-title-status' import type { TerminalSlice, TerminalStoreGet, TerminalStoreSet } from './terminal-state' export function createTerminalEphemeralActions( @@ -202,7 +202,7 @@ export function createTerminalEphemeralActions( if (!tab.title || !isClaudeAgent(tab.title)) { continue } - const status = classifyTitleActivity(tab.title) + const status = detectAgentStatusFromTitle(tab.title) if (status === null || status === 'working') { continue } diff --git a/src/renderer/src/store/terminals/terminal-input-activity-store-write.test.ts b/src/renderer/src/store/terminals/terminal-input-activity-store-write.test.ts index 447447b1fe2..276e79f5519 100644 --- a/src/renderer/src/store/terminals/terminal-input-activity-store-write.test.ts +++ b/src/renderer/src/store/terminals/terminal-input-activity-store-write.test.ts @@ -4,7 +4,7 @@ * flush per window. These tests pin the properties that make that safe. */ import { beforeEach, describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn(), warning: vi.fn() } @@ -17,7 +17,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn() })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/store/terminals/terminal-last-tab-close.test.ts b/src/renderer/src/store/terminals/terminal-last-tab-close.test.ts index 9a17a2c5de3..caf6a1a2c2d 100644 --- a/src/renderer/src/store/terminals/terminal-last-tab-close.test.ts +++ b/src/renderer/src/store/terminals/terminal-last-tab-close.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore, seedStore } from '../testing/app-store-test-fixture' import { makeTab } from './terminal-tab.test-fixture' import { makeTabGroup, makeUnifiedTab } from '../slices/tabs/tab-group.test-fixture' @@ -21,7 +21,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/terminals/terminal-pty-release-orphan-retention.test.ts b/src/renderer/src/store/terminals/terminal-pty-release-orphan-retention.test.ts index 6bc22155ef3..ecfcde7431b 100644 --- a/src/renderer/src/store/terminals/terminal-pty-release-orphan-retention.test.ts +++ b/src/renderer/src/store/terminals/terminal-pty-release-orphan-retention.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { createTestStore, seedStore } from '../testing/app-store-test-fixture' import { makeTab } from './terminal-tab.test-fixture' @@ -21,7 +21,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: mockUnregisterPtyDataHandlers })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/store/terminals/terminal-tab-close-intent.test.ts b/src/renderer/src/store/terminals/terminal-tab-close-intent.test.ts index ad740f83555..e7c5b290e74 100644 --- a/src/renderer/src/store/terminals/terminal-tab-close-intent.test.ts +++ b/src/renderer/src/store/terminals/terminal-tab-close-intent.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import { TEST_REPO } from '../repos/repo.test-fixture' import { createTestStore, seedStore } from '../testing/app-store-test-fixture' import { makeTab } from './terminal-tab.test-fixture' @@ -47,7 +47,7 @@ vi.mock('@/components/terminal-pane/pty-transport/shutdown/pty-shutdown-data-sus unregisterPtyDataHandlers: vi.fn<() => unknown[]>(() => []) })) -vi.mock('@/lib/agent-status', async (importOriginal) => ({ +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => ({ ...(await importOriginal()), detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) })) diff --git a/src/renderer/src/store/terminals/terminal-tab-presentation.ts b/src/renderer/src/store/terminals/terminal-tab-presentation.ts index e6bbd9f6d11..c13adbfad85 100644 --- a/src/renderer/src/store/terminals/terminal-tab-presentation.ts +++ b/src/renderer/src/store/terminals/terminal-tab-presentation.ts @@ -1,6 +1,6 @@ import { isDecorativeAgentTitleFrameChange } from '../../../../shared/agent-status/title/agent-decorative-title-signature' import { scheduleRuntimeGraphSync } from '@/runtime/sync-runtime-graph/graph-sync-scheduler' -import { classifyTitleActivity } from '@/lib/pane-agent-evidence' +import { detectAgentStatusFromTitle } from '../../../../shared/agent-status/title/agent-title-status' import { applyGeneratedTabTitleUpdates, applyTerminalTabTitleUpdates @@ -151,7 +151,7 @@ export function createTerminalTabPresentationActions( } // Why: re-sort hookless title changes only when their activity classification changes. const classificationChanged = - classifyTitleActivity(prevTitle ?? '') !== classifyTitleActivity(title) + detectAgentStatusFromTitle(prevTitle ?? '') !== detectAgentStatusFromTitle(title) // Why: skip active-worktree remount side effects and orphaned panes. const ownerWorktreeId = classificationChanged ? getTerminalTabOwnerWorktreeId(s.tabsByWorktree, tabId) @@ -183,7 +183,7 @@ export function createTerminalTabPresentationActions( delete next[tabId] } // Clearing a classified title changes smart-sort’s verdict, like setRuntimePaneTitle. - const hadClassification = classifyTitleActivity(prevTitle ?? '') !== null + const hadClassification = detectAgentStatusFromTitle(prevTitle ?? '') !== null // Click-driven teardown must not re-rank active worktrees; skip orphaned owners too. const ownerWorktreeId = hadClassification ? getTerminalTabOwnerWorktreeId(s.tabsByWorktree, tabId) diff --git a/src/renderer/src/store/terminals/terminal-transient-state.ts b/src/renderer/src/store/terminals/terminal-transient-state.ts index 542b77b6ae4..1b03593290d 100644 --- a/src/renderer/src/store/terminals/terminal-transient-state.ts +++ b/src/renderer/src/store/terminals/terminal-transient-state.ts @@ -1,5 +1,5 @@ import type { TerminalTab } from '../../../../shared/workspace-layout/terminal-tab-types' -import { classifyTitleActivity } from '@/lib/pane-agent-evidence' +import { detectAgentStatusFromTitle } from '../../../../shared/agent-status/title/agent-title-status' export function clearTransientTerminalState(tab: TerminalTab, index: number): TerminalTab { return { @@ -13,5 +13,5 @@ function getResetTitle(tab: TerminalTab, index: number): string { const fallbackTitle = tab.customTitle?.trim() || tab.defaultTitle?.trim() || `Terminal ${index + 1}` // After restart, prior-session done/spinner titles would falsely imply a running agent. - return classifyTitleActivity(tab.title) ? fallbackTitle : tab.title + return detectAgentStatusFromTitle(tab.title) ? fallbackTitle : tab.title } diff --git a/src/renderer/src/store/workspace-layout/frames/workspace-layout-frame-store-patch.test.ts b/src/renderer/src/store/workspace-layout/frames/workspace-layout-frame-store-patch.test.ts index 836ab05fff6..c9c79a1152f 100644 --- a/src/renderer/src/store/workspace-layout/frames/workspace-layout-frame-store-patch.test.ts +++ b/src/renderer/src/store/workspace-layout/frames/workspace-layout-frame-store-patch.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import type * as AgentStatusModule from '@/lib/agent-status' +import type * as AgentStatusModule from '@/lib/agent-status/aggregation/worktree-agent-status' import type { WorkspaceSessionState } from '../../../../../shared/workspace-session/workspace-session-state-types' import { loadWorkspaceLayoutWithoutReport } from '../../../../../shared/workspace-layout/workspace-layout-load' import { nameBasedLoadContext } from '../../../../../shared/workspace-layout/workspace-layout-minted-ids' @@ -32,7 +32,7 @@ vi.mock('../../../../../shared/layout-owner-switch', () => ({ } })) vi.mock('sonner', () => ({ toast: { info: vi.fn(), success: vi.fn(), error: vi.fn() } })) -vi.mock('@/lib/agent-status', async (importOriginal) => { +vi.mock('@/lib/agent-status/aggregation/worktree-agent-status', async (importOriginal) => { const actual = await importOriginal() return { ...actual, detectAgentStatusFromTitle: vi.fn().mockReturnValue(null) } }) diff --git a/src/renderer/src/lib/agent-status-evidence-clock.test.ts b/src/shared/agent-status/contracts/agent-status-evidence-clock.test.ts similarity index 70% rename from src/renderer/src/lib/agent-status-evidence-clock.test.ts rename to src/shared/agent-status/contracts/agent-status-evidence-clock.test.ts index 51830479795..de5515bea97 100644 --- a/src/renderer/src/lib/agent-status-evidence-clock.test.ts +++ b/src/shared/agent-status/contracts/agent-status-evidence-clock.test.ts @@ -1,10 +1,10 @@ import { describe, expect, it } from 'vitest' import { AGENT_STATUS_STALE_AFTER_MS, - isFreshNonDoneAgentStatus -} from '../../../shared/agent-status/contracts/agent-status-freshness' -import type { AgentStatusEntry } from '../../../shared/agent-status/contracts/agent-status-types' -import { isExplicitAgentStatusFresh } from './pane-agent-evidence' + isFreshNonDoneAgentStatus, + isAgentStatusFresh +} from './agent-status-freshness' +import type { AgentStatusEntry } from './agent-status-types' const NOW = new Date('2026-04-09T12:00:00.000Z').getTime() const OBSERVED_AT = NOW - AGENT_STATUS_STALE_AFTER_MS - 60_000 @@ -27,7 +27,7 @@ describe('staleness measures when evidence was observed, not when it was deliver it('keeps a live row fresh when its evidence was just observed', () => { const row = workingRow({ evidenceObservedAt: NOW }) expect(isFreshNonDoneAgentStatus(row, NOW)).toBe(true) - expect(isExplicitAgentStatusFresh(row, NOW, AGENT_STATUS_STALE_AFTER_MS)).toBe(true) + expect(isAgentStatusFresh(row, NOW, AGENT_STATUS_STALE_AFTER_MS)).toBe(true) const mirrored = workingRow({ updatedAt: OBSERVED_AT, @@ -35,13 +35,13 @@ describe('staleness measures when evidence was observed, not when it was deliver mirroredEvidenceReceivedAt: NOW }) expect(isFreshNonDoneAgentStatus(mirrored, NOW)).toBe(true) - expect(isExplicitAgentStatusFresh(mirrored, NOW, AGENT_STATUS_STALE_AFTER_MS)).toBe(true) + expect(isAgentStatusFresh(mirrored, NOW, AGENT_STATUS_STALE_AFTER_MS)).toBe(true) const expiredMirror = workingRow({ evidenceObservedAt: NOW, mirroredEvidenceReceivedAt: OBSERVED_AT }) expect(isFreshNonDoneAgentStatus(expiredMirror, NOW)).toBe(false) - expect(isExplicitAgentStatusFresh(expiredMirror, NOW, AGENT_STATUS_STALE_AFTER_MS)).toBe(false) + expect(isAgentStatusFresh(expiredMirror, NOW, AGENT_STATUS_STALE_AFTER_MS)).toBe(false) }) }) diff --git a/src/renderer/src/lib/agent-status.test.ts b/src/shared/agent-status/title/agent-title-tracker.test.ts similarity index 95% rename from src/renderer/src/lib/agent-status.test.ts rename to src/shared/agent-status/title/agent-title-tracker.test.ts index fd4c21adffa..466dd55c8ce 100644 --- a/src/renderer/src/lib/agent-status.test.ts +++ b/src/shared/agent-status/title/agent-title-tracker.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { createAgentStatusTracker } from '../../../shared/agent-status/title/agent-title-status' +import { createAgentStatusTracker } from './agent-title-status' describe('createAgentStatusTracker', () => { // Claude Code v2.1.86 emits task descriptions; only ✳ identifies idle in this captured sequence. diff --git a/tests/e2e/claude-agent-row-view.unit.test.ts b/tests/e2e/claude-agent-row-view.unit.test.ts index 97113bff5eb..4479c706c6c 100644 --- a/tests/e2e/claude-agent-row-view.unit.test.ts +++ b/tests/e2e/claude-agent-row-view.unit.test.ts @@ -20,7 +20,10 @@ import { buildSubagentChildRows } from '@/components/sidebar/workspace-card/acti import { TooltipProvider } from '@/components/ui/tooltip' import { CompactAgentRow } from '@/components/sidebar/workspace-card/activity/worktree-card-compact-agent-row' import FullAgentRow from '@/components/dashboard/DashboardAgentRow' -import { opensClaudeParentConversation, viewClaudeAgentFromRow } from '@/lib/claude-agent-row-view' +import { + opensClaudeParentConversation, + viewClaudeAgentFromRow +} from '@/lib/agent-session/navigation/claude-agent-row-view' import type * as WorktreeRuntimeOwner from '@/lib/workspace/ownership/worktree-runtime-owner' import '@/store/slices/worktrees/worktree.test-fixture' import '@/store/repos/repo.test-fixture' diff --git a/tests/e2e/host-agent-launch-settings-hook-bookkeeping.unit.test.ts b/tests/e2e/host-agent-launch-settings-hook-bookkeeping.unit.test.ts index cd3f0791522..48d1840b19b 100644 --- a/tests/e2e/host-agent-launch-settings-hook-bookkeeping.unit.test.ts +++ b/tests/e2e/host-agent-launch-settings-hook-bookkeeping.unit.test.ts @@ -9,7 +9,7 @@ import { import { RuntimeClientSettingsController } from '../../src/main/runtime/client/settings/runtime-client-settings' import { HostAgentLaunchSettings } from '../../src/renderer/src/components/settings/agents/launch/HostAgentLaunchSettings' import { TooltipProvider } from '../../src/renderer/src/components/ui/tooltip' -import { getAgentCatalog } from '../../src/renderer/src/lib/agent-catalog' +import { getAgentCatalog } from '../../src/renderer/src/lib/agent-catalog/agent-catalog' const transport = vi.hoisted(() => ({ read: vi.fn(), mutate: vi.fn() })) const hooks = vi.hoisted(() => ({ apply: vi.fn(async () => {}) })) diff --git a/tests/e2e/launch-agent-in-new-tab-web-runtime.unit.test.ts b/tests/e2e/launch-agent-in-new-tab-web-runtime.unit.test.ts index 42e967c65fb..ed590378077 100644 --- a/tests/e2e/launch-agent-in-new-tab-web-runtime.unit.test.ts +++ b/tests/e2e/launch-agent-in-new-tab-web-runtime.unit.test.ts @@ -6,10 +6,10 @@ import { act, fireEvent, render, screen } from '@testing-library/react' import { useTabAgentMenuLaunch } from '@/components/tab-bar/QuickLaunchButton' import { STRUCTURED_AGENT_SESSION_REGISTERED_AGENTS_RUNTIME_CAPABILITY } from '../../src/shared/agent-session/structured-agent-session-surface-capabilities' import { AGENT_SESSION_AGENTS_METHOD } from '../../src/shared/agent-session/agent-session-registered-agents' -import { pasteDraftWhenAgentReady } from '@/lib/agent-paste-draft' +import { pasteDraftWhenAgentReady } from '@/lib/agent-session/messaging/paste/agent-paste-draft' import { newAgentPromptOutcome } from '@/lib/new-agent-prompt-outcome' import { newAgentLaunchRequestId } from '@/lib/agent-session/launch/routing/agent-launch-request-id' -import { nonRefusedAgentLaunch } from '@/lib/agent-tab-launch-outcome.test-fixture' +import { nonRefusedAgentLaunch } from '@/lib/agent-session/launch/new-tab/agent-tab-launch-outcome.test-fixture' import { stubRuntimeEnvironmentBridge } from '@/runtime/rpc/testing/runtime-environment-bridge-fixture' import { AGENT_LAUNCH_CHOICES_CAPABILITY } from '../../src/shared/agent-launch/contracts/agent-launch-runtime-capability' import { OrcaRuntimeService } from '../../src/main/runtime/orca-runtime' diff --git a/tests/e2e/launch-agent-web-terminal.test-fixture.ts b/tests/e2e/launch-agent-web-terminal.test-fixture.ts index 6e45d9705d0..353055f7090 100644 --- a/tests/e2e/launch-agent-web-terminal.test-fixture.ts +++ b/tests/e2e/launch-agent-web-terminal.test-fixture.ts @@ -115,7 +115,9 @@ vi.mock('@/lib/workspace/activation/worktree-activation', () => ({ activateAndRevealWorktree: mocks.reveal })) vi.mock('@/components/tab-bar/reconcile-order', () => ({ reconcileTabOrder: vi.fn(() => []) })) -vi.mock('@/lib/agent-paste-draft', () => ({ pasteDraftWhenAgentReady: vi.fn() })) +vi.mock('@/lib/agent-session/messaging/paste/agent-paste-draft', () => ({ + pasteDraftWhenAgentReady: vi.fn() +})) vi.mock('@/lib/telemetry', () => ({ track: vi.fn(), tuiAgentToAgentKind: mockLaunchAgentKind diff --git a/tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts b/tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts index 448b0d18992..ad42c061d52 100644 --- a/tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts +++ b/tests/e2e/session-tabs-decorative-title-fanout.unit.test.ts @@ -4,8 +4,11 @@ import type { RuntimeMobileSessionTabsSnapshot } from '../../src/shared/runtime-types' import '../../src/shared/agent-status/title/agent-title-status' -import { AGENT_STATUS_STALE_AFTER_MS } from '../../src/shared/agent-status/contracts/agent-status-freshness' -import { isExplicitAgentStatusFresh } from '../../src/renderer/src/lib/pane-agent-evidence' +import { + AGENT_STATUS_STALE_AFTER_MS, + isAgentStatusFresh +} from '../../src/shared/agent-status/contracts/agent-status-freshness' + import { OrcaRuntimeService } from '../../src/main/runtime/orca-runtime' import { SESSION_TABS_AGENT_STATUS_HEARTBEAT_INTERVAL_MS } from '../../src/main/runtime/session-lifecycle/publication/mobile-session-tabs-agent-status-heartbeat' import { applyFreshWebSessionTabsSnapshot } from '../../src/renderer/src/runtime/web-session-tabs-sync/snapshot-api' @@ -204,9 +207,9 @@ describe('real PTY decorative session-tabs fanout', () => { expect(Date.now() - firstWorkingTitleAt).toBeGreaterThan(AGENT_STATUS_STALE_AFTER_MS) const viewerAgentStatus = Object.values(viewerState.agentStatusByPaneKey)[0] expect(viewerAgentStatus?.state).toBe('working') - expect( - isExplicitAgentStatusFresh(viewerAgentStatus!, Date.now(), AGENT_STATUS_STALE_AFTER_MS) - ).toBe(true) + expect(isAgentStatusFresh(viewerAgentStatus!, Date.now(), AGENT_STATUS_STALE_AFTER_MS)).toBe( + true + ) publications.length = 0 vi.advanceTimersByTime(1) @@ -442,9 +445,7 @@ describe('real PTY decorative session-tabs fanout', () => { expect(Date.now() - initialStatus!.updatedAt).toBeGreaterThan(AGENT_STATUS_STALE_AFTER_MS) const viewerStatus = Object.values(viewerState.agentStatusByPaneKey)[0] expect(viewerStatus?.prompt).toBe('') - expect(isExplicitAgentStatusFresh(viewerStatus!, Date.now(), AGENT_STATUS_STALE_AFTER_MS)).toBe( - true - ) + expect(isAgentStatusFresh(viewerStatus!, Date.now(), AGENT_STATUS_STALE_AFTER_MS)).toBe(true) unsubscribe() uninstallStatusRepublish() statusWiring.statusStore.stop() diff --git a/tests/e2e/terminal-agent-fork-draft-ownership.unit.test.ts b/tests/e2e/terminal-agent-fork-draft-ownership.unit.test.ts index d384628e1c0..ba02072b3dc 100644 --- a/tests/e2e/terminal-agent-fork-draft-ownership.unit.test.ts +++ b/tests/e2e/terminal-agent-fork-draft-ownership.unit.test.ts @@ -1,9 +1,9 @@ // @vitest-environment happy-dom import { mocks, store } from './launch-agent-web-terminal.test-fixture' import { expect, it, vi } from 'vitest' -import { buildAgentSessionForkPrompt } from '@/lib/agent-session-fork-context' +import { buildAgentSessionForkPrompt } from '@/lib/agent-session/context/agent-session-fork-context' import { isWebRuntimeSessionActive } from '@/runtime/web-session-tabs-sync/identity/web-runtime-session-environment' -import { pasteDraftWhenAgentReady } from '@/lib/agent-paste-draft' +import { pasteDraftWhenAgentReady } from '@/lib/agent-session/messaging/paste/agent-paste-draft' import { newAgentPromptOutcome } from '@/lib/new-agent-prompt-outcome' import { projectAgentLaunchSettings } from '../../src/shared/agent-launch/choices/agent-launch-settings' import { retainedPrefillHost } from './terminal-agent-fork-retained-prefill.test-fixture' diff --git a/tests/e2e/terminal-agent-pane-launch.unit.test.ts b/tests/e2e/terminal-agent-pane-launch.unit.test.ts index 0667445774a..d1e00b1da0a 100644 --- a/tests/e2e/terminal-agent-pane-launch.unit.test.ts +++ b/tests/e2e/terminal-agent-pane-launch.unit.test.ts @@ -65,7 +65,9 @@ vi.mock('@/runtime/hosted-terminals/input/runtime-terminal-verified-input', () = vi.mock('@/runtime/hosted-terminals/streams/runtime-terminal-data-subscription', () => ({ subscribeToRuntimeTerminalData: vi.fn() })) -vi.mock('@/lib/agent-ready-wait', () => ({ waitForAgentReady: async () => ({ ready: false }) })) +vi.mock('@/lib/agent-session/messaging/paste/agent-ready-wait', () => ({ + waitForAgentReady: async () => ({ ready: false }) +})) vi.mock('@/lib/telemetry', () => ({ track: vi.fn(), tuiAgentToAgentKind: mockLaunchAgentKind })) const mockLaunchAgentKind = vi.hoisted(() => () => 'claude') vi.mock('../../src/shared/agent-kind', async (importOriginal) => ({ diff --git a/tests/tools/omp-picker-search-rendered/fixture.tsx b/tests/tools/omp-picker-search-rendered/fixture.tsx index 6fbb57f339a..d8417ac27d3 100644 --- a/tests/tools/omp-picker-search-rendered/fixture.tsx +++ b/tests/tools/omp-picker-search-rendered/fixture.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react' import { createRoot } from 'react-dom/client' import AgentCombobox from '../../../src/renderer/src/components/agent/AgentCombobox' -import { getAgentCatalog } from '../../../src/renderer/src/lib/agent-catalog' +import { getAgentCatalog } from '../../../src/renderer/src/lib/agent-catalog/agent-catalog' import type { TuiAgent } from '../../../src/shared/agent-launch/catalog/tui-agent' import './fixture.css' const baseline = new URLSearchParams(window.location.search).get('baseline') === '1'