From cfa693c8ba136c7630f420599d103bac452e2bfc Mon Sep 17 00:00:00 2001 From: murashit Date: Sun, 14 Jun 2026 17:29:21 +0900 Subject: [PATCH] Organize chat application and host layers --- eslint.config.mjs | 8 +- .../actions}/diagnostics.ts | 2 +- .../actions}/host.ts | 2 +- .../actions}/metadata.ts | 0 .../actions}/threads.ts | 10 +- .../chat/app-server/inbound/controller.ts | 4 +- .../app-server/inbound/notification-plan.ts | 19 ++-- .../mappers/message-stream/agent-items.ts | 19 +--- .../mappers/message-stream/hook-run-items.ts | 2 +- .../message-stream/review-result-items.ts | 2 +- .../mappers/message-stream/streaming-items.ts | 21 ++++ .../mappers/message-stream/turn-items.ts | 4 +- .../chat/{ => application}/chat-host.ts | 8 +- .../composer/boundary-scroll.ts | 0 .../composer/obsidian-context.ts | 0 .../composer/slash-commands.ts | 0 .../composer/suggestions.ts | 0 .../composer/wikilink-context.ts | 0 .../connection/app-server-warmup.ts | 0 .../connection/connection-controller.ts | 6 +- .../connection/diagnostics-display.ts | 6 +- .../{ => application}/connection/messages.ts | 0 .../connection/reconnect-actions.ts | 0 .../conversation}/composer-submit-actions.ts | 4 +- .../conversation}/composition.ts | 14 +-- .../conversation}/messages.ts | 0 .../conversation}/optimistic-turn-start.ts | 8 +- .../conversation}/plan-implementation.ts | 6 +- .../conversation}/runtime-setting-commands.ts | 0 .../conversation}/slash-command-execution.ts | 6 +- .../conversation}/slash-command-handler.ts | 8 +- .../conversation}/turn-state.ts | 0 .../turn-submission-controller.ts | 4 +- .../chat/{ => application}/lifecycle.ts | 41 +------ .../application/pending-requests/block.ts | 18 ++++ .../pending-requests/controller.ts | 12 +-- .../application/pending-requests/snapshot.ts | 11 ++ .../{ => application}/runtime/messages.ts | 40 +------ .../runtime/settings-actions.ts | 14 +-- .../{ => application}/runtime/snapshot.ts | 29 +---- .../runtime/thread-settings-update.ts | 13 ++- .../chat/{ => application}/state/actions.ts | 16 +-- .../{ => application}/state/message-stream.ts | 10 +- .../chat/{ => application}/state/reducer.ts | 44 ++++---- .../chat/{ => application}/state/selectors.ts | 6 +- .../threads/auto-title-controller.ts | 12 +-- .../{ => application}/threads/composition.ts | 6 +- .../{ => application}/threads/goal-actions.ts | 10 +- .../threads/history-controller.ts | 8 +- .../threads/identity-sync.ts | 0 .../threads/lifecycle-parts.ts | 4 +- .../{ => application}/threads/messages.ts | 0 .../{ => application}/threads/naming-parts.ts | 4 +- .../threads/rename-editor-controller.ts | 14 +-- .../threads/restoration-controller.ts | 0 .../threads/resume-controller.ts | 4 +- .../chat/{ => application}/threads/resume.ts | 10 +- .../threads/selection-actions.ts | 0 .../threads/thread-management-actions.ts | 14 +-- .../threads/title-context.ts | 8 +- .../threads/title-display.ts | 4 +- .../chat/domain/message-stream/agent-state.ts | 20 ++++ .../message-stream/factories/goal-items.ts | 2 +- .../factories/streaming-items.ts | 22 +--- .../message-stream/factories/system-items.ts | 2 +- .../message-stream/factories/task-progress.ts | 2 +- .../message-stream/format/file-mentions.ts | 2 +- .../message-stream/{model => }/items.ts | 2 +- .../message-stream/{model => }/provenance.ts | 0 .../message-stream/{queries => }/selectors.ts | 4 +- .../message-stream/semantics/classify.ts | 2 +- .../domain/message-stream/semantics/types.ts | 4 +- .../{operations => }/updates.ts | 10 +- .../domain/pending-requests/result-items.ts | 2 +- .../chat/{ => domain}/runtime/effective.ts | 8 +- .../{ => domain}/runtime/pending-settings.ts | 0 src/features/chat/domain/runtime/snapshot.ts | 26 +++++ .../chat/{ => domain}/runtime/state.ts | 6 +- src/features/chat/domain/runtime/warnings.ts | 1 + .../model.ts => domain/turn-diff.ts} | 0 .../composition.ts => host/composer.ts} | 20 ++-- .../composition.ts => host/conversation.ts} | 22 ++-- src/features/chat/host/lifecycle.ts | 40 +++++++ src/features/chat/{ => host}/session.ts | 102 +++++++++--------- src/features/chat/{ => host}/view.ts | 12 +-- src/features/chat/panel/snapshot.ts | 8 +- src/features/chat/panel/surface/composer.ts | 10 +- .../chat/panel/surface/create-surface.ts | 18 ++-- .../chat/panel/surface/goal-surface.ts | 8 +- .../panel/surface/message-stream-presenter.ts | 11 +- .../surface/message-stream-projection.ts | 26 +++-- .../panel/surface/message-stream-scroll.ts | 2 +- .../chat/panel/surface/runtime-snapshot.ts | 8 +- .../chat/panel/surface/toolbar-surface.ts | 14 +-- src/features/chat/panel/surface/toolbar.ts | 8 +- src/features/chat/panel/toolbar-actions.ts | 4 +- src/features/chat/panel/view-state.ts | 2 +- .../message-stream/agent-summary.ts | 4 +- .../presentation/message-stream/blocks.ts | 2 +- .../presentation/message-stream/layout.ts | 2 +- .../presentation/message-stream/text-view.ts | 2 +- .../message-stream/tool-result-view.ts | 2 +- .../presentation/message-stream/work-view.ts | 2 +- .../presentation/pending-requests/snapshot.ts | 16 +-- .../pending-requests/view-model.ts | 14 +-- .../chat/presentation/runtime/messages.ts | 36 +++++++ .../chat/{ => presentation}/runtime/status.ts | 16 +-- .../composer-controller.ts} | 25 +++-- src/features/chat/ui/composer.tsx | 2 +- .../chat/ui/message-stream/context.ts | 8 +- .../message-stream/pending-request-block.tsx | 2 +- .../ui/message-stream/text-item-actions.tsx | 4 +- .../ui/message-stream/text-item-metadata.tsx | 2 +- .../chat/ui/message-stream/tool-result.tsx | 2 +- .../chat/ui/message-stream/work-items.tsx | 4 +- src/features/chat/ui/shell-state.tsx | 2 +- src/features/chat/ui/shell.tsx | 2 +- src/features/chat/ui/toolbar.tsx | 2 +- .../chat/{ => ui}/turn-diff/render.tsx | 12 +-- src/features/chat/{ => ui}/turn-diff/view.ts | 8 +- src/main.ts | 8 +- src/workspace/panel-coordinator.ts | 2 +- .../chat/connection/app-server-warmup.test.ts | 4 +- .../connection/connection-controller.test.ts | 6 +- .../chat/connection/reconnect-actions.test.ts | 7 +- .../server-actions/server-actions.test.ts | 10 +- .../composer/boundary-scroll.test.ts | 2 +- .../composer/composer-suggestions.test.ts | 4 +- .../conversation/composer/controller.test.ts | 4 +- .../composer/obsidian-context.test.ts | 2 +- .../composer/wikilink-context.test.ts | 2 +- .../pending-requests/controller.test.ts | 2 +- .../turns/composer-submit-actions.test.ts | 4 +- .../turns/optimistic-turn-start.test.ts | 4 +- .../turns/plan-implementation.test.ts | 8 +- .../turns/slash-command-execution.test.ts | 4 +- .../turns/slash-command-handler.test.ts | 4 +- .../turns/turn-submission-controller.test.ts | 4 +- tests/features/chat/diagnostics.test.ts | 2 +- tests/features/chat/mcp-status.test.ts | 2 +- .../chat/message-stream/model.test.ts | 6 +- .../presentation/blocks.test.ts | 2 +- .../chat/message-stream/selectors.test.ts | 4 +- .../chat/message-stream/semantics.test.ts | 2 +- .../surface/message-stream-presenter.test.ts | 2 +- .../chat/panel/surface/toolbar.test.ts | 4 +- .../chat/protocol/inbound/controller.test.ts | 4 +- .../chat/runtime/settings-actions.test.ts | 11 +- tests/features/chat/state-reducer.test.ts | 6 +- .../state/message-stream-selectors.test.ts | 4 +- tests/features/chat/support/message-stream.ts | 6 +- .../threads/auto-title-controller.test.ts | 4 +- .../chat/threads/goal-actions.test.ts | 4 +- .../chat/threads/history-controller.test.ts | 4 +- .../chat/threads/identity-sync.test.ts | 8 +- .../threads/rename-editor-controller.test.ts | 4 +- .../threads/restoration-controller.test.ts | 6 +- .../chat/threads/resume-controller.test.ts | 10 +- tests/features/chat/threads/resume.test.ts | 2 +- .../chat/threads/selection-actions.test.ts | 4 +- .../threads/thread-management-actions.test.ts | 6 +- .../chat/threads/title-context.test.ts | 2 +- .../chat/threads/title-display.test.ts | 2 +- .../blocks-and-messages.test.tsx | 4 +- .../message-stream/pending-requests.test.tsx | 2 +- .../chat/ui/message-stream/test-helpers.tsx | 14 ++- .../chat/ui/message-stream/work-log.test.tsx | 2 +- .../chat/ui/renderers/composer.test.ts | 2 +- .../chat/ui/renderers/turn-diff.test.ts | 6 +- tests/features/chat/ui/shell.test.tsx | 4 +- .../chat/ui/toolbar-archive-state.test.tsx | 4 +- tests/features/chat/view-connection.test.ts | 4 +- tests/features/chat/view-lifecycle.test.ts | 4 +- tests/features/chat/view-model.test.ts | 8 +- tests/main.test.ts | 36 +++---- tests/runtime/override-commands.test.ts | 4 +- tests/runtime/runtime-settings.test.ts | 21 ++-- tests/runtime/service-tier-state.test.ts | 2 +- tests/scripts/eslint-config.test.ts | 38 +++---- 179 files changed, 754 insertions(+), 709 deletions(-) rename src/features/chat/{connection/server-actions => app-server/actions}/diagnostics.ts (98%) rename src/features/chat/{connection/server-actions => app-server/actions}/host.ts (82%) rename src/features/chat/{connection/server-actions => app-server/actions}/metadata.ts (100%) rename src/features/chat/{connection/server-actions => app-server/actions}/threads.ts (89%) create mode 100644 src/features/chat/app-server/mappers/message-stream/streaming-items.ts rename src/features/chat/{ => application}/chat-host.ts (76%) rename src/features/chat/{conversation => application}/composer/boundary-scroll.ts (100%) rename src/features/chat/{conversation => application}/composer/obsidian-context.ts (100%) rename src/features/chat/{conversation => application}/composer/slash-commands.ts (100%) rename src/features/chat/{conversation => application}/composer/suggestions.ts (100%) rename src/features/chat/{conversation => application}/composer/wikilink-context.ts (100%) rename src/features/chat/{ => application}/connection/app-server-warmup.ts (100%) rename src/features/chat/{ => application}/connection/connection-controller.ts (95%) rename src/features/chat/{ => application}/connection/diagnostics-display.ts (97%) rename src/features/chat/{ => application}/connection/messages.ts (100%) rename src/features/chat/{ => application}/connection/reconnect-actions.ts (100%) rename src/features/chat/{conversation/turns => application/conversation}/composer-submit-actions.ts (96%) rename src/features/chat/{conversation/turns => application/conversation}/composition.ts (92%) rename src/features/chat/{conversation/turns => application/conversation}/messages.ts (100%) rename src/features/chat/{conversation/turns => application/conversation}/optimistic-turn-start.ts (95%) rename src/features/chat/{conversation/turns => application/conversation}/plan-implementation.ts (89%) rename src/features/chat/{conversation/turns => application/conversation}/runtime-setting-commands.ts (100%) rename src/features/chat/{conversation/turns => application/conversation}/slash-command-execution.ts (99%) rename src/features/chat/{conversation/turns => application/conversation}/slash-command-handler.ts (93%) rename src/features/chat/{conversation/turns => application/conversation}/turn-state.ts (100%) rename src/features/chat/{conversation/turns => application/conversation}/turn-submission-controller.ts (98%) rename src/features/chat/{ => application}/lifecycle.ts (79%) create mode 100644 src/features/chat/application/pending-requests/block.ts create mode 100644 src/features/chat/application/pending-requests/snapshot.ts rename src/features/chat/{ => application}/runtime/messages.ts (50%) rename src/features/chat/{ => application}/runtime/settings-actions.ts (95%) rename src/features/chat/{ => application}/runtime/snapshot.ts (57%) rename src/features/chat/{ => application}/runtime/thread-settings-update.ts (89%) rename src/features/chat/{ => application}/state/actions.ts (86%) rename src/features/chat/{ => application}/state/message-stream.ts (98%) rename src/features/chat/{ => application}/state/reducer.ts (96%) rename src/features/chat/{ => application}/state/selectors.ts (90%) rename src/features/chat/{ => application}/threads/auto-title-controller.ts (89%) rename src/features/chat/{ => application}/threads/composition.ts (94%) rename src/features/chat/{ => application}/threads/goal-actions.ts (93%) rename src/features/chat/{ => application}/threads/history-controller.ts (93%) rename src/features/chat/{ => application}/threads/identity-sync.ts (100%) rename src/features/chat/{ => application}/threads/lifecycle-parts.ts (95%) rename src/features/chat/{ => application}/threads/messages.ts (100%) rename src/features/chat/{ => application}/threads/naming-parts.ts (90%) rename src/features/chat/{ => application}/threads/rename-editor-controller.ts (93%) rename src/features/chat/{ => application}/threads/restoration-controller.ts (100%) rename src/features/chat/{ => application}/threads/resume-controller.ts (96%) rename src/features/chat/{ => application}/threads/resume.ts (89%) rename src/features/chat/{ => application}/threads/selection-actions.ts (100%) rename src/features/chat/{ => application}/threads/thread-management-actions.ts (96%) rename src/features/chat/{ => application}/threads/title-context.ts (89%) rename src/features/chat/{ => application}/threads/title-display.ts (76%) create mode 100644 src/features/chat/domain/message-stream/agent-state.ts rename src/features/chat/domain/message-stream/{model => }/items.ts (98%) rename src/features/chat/domain/message-stream/{model => }/provenance.ts (100%) rename src/features/chat/domain/message-stream/{queries => }/selectors.ts (97%) rename src/features/chat/domain/message-stream/{operations => }/updates.ts (96%) rename src/features/chat/{ => domain}/runtime/effective.ts (95%) rename src/features/chat/{ => domain}/runtime/pending-settings.ts (100%) create mode 100644 src/features/chat/domain/runtime/snapshot.ts rename src/features/chat/{ => domain}/runtime/state.ts (96%) create mode 100644 src/features/chat/domain/runtime/warnings.ts rename src/features/chat/{turn-diff/model.ts => domain/turn-diff.ts} (100%) rename src/features/chat/{conversation/composer/composition.ts => host/composer.ts} (75%) rename src/features/chat/{conversation/composition.ts => host/conversation.ts} (86%) create mode 100644 src/features/chat/host/lifecycle.ts rename src/features/chat/{ => host}/session.ts (89%) rename src/features/chat/{ => host}/view.ts (89%) create mode 100644 src/features/chat/presentation/runtime/messages.ts rename src/features/chat/{ => presentation}/runtime/status.ts (96%) rename src/features/chat/{conversation/composer/controller.ts => ui/composer-controller.ts} (93%) rename src/features/chat/{ => ui}/turn-diff/render.tsx (89%) rename src/features/chat/{ => ui}/turn-diff/view.ts (89%) diff --git a/eslint.config.mjs b/eslint.config.mjs index 448d6d75..b514b7dc 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -155,13 +155,13 @@ const chatPreactDomBridgeFiles = [ "src/features/chat/ui/message-stream/viewport.tsx", "src/features/chat/ui/composer-dom.ts", "src/features/chat/ui/shell.tsx", - "src/features/chat/turn-diff/render.tsx", + "src/features/chat/ui/turn-diff/render.tsx", ]; const chatImperativeDomBridgeFiles = [...chatExternalDomBridgeFiles, ...chatPreactDomBridgeFiles]; const uiRootBridgeFiles = [ "src/features/chat/ui/shell.tsx", - "src/features/chat/turn-diff/render.tsx", - "src/features/chat/turn-diff/view.ts", + "src/features/chat/ui/turn-diff/render.tsx", + "src/features/chat/ui/turn-diff/view.ts", "src/features/selection-rewrite/popover.tsx", "src/features/threads-view/renderer.tsx", ]; @@ -677,7 +677,7 @@ export default defineConfig([ rules: restrictedSyntaxRule(sourceSyntaxRestrictionsWithoutUiRoot), }, { - files: ["src/features/chat/state/**/*.{ts,tsx}"], + files: ["src/features/chat/application/state/**/*.{ts,tsx}"], rules: { ...restrictedSyntaxRule(pureChatStateSyntaxRestrictions), "codex-panel/no-imperative-dom": "error", diff --git a/src/features/chat/connection/server-actions/diagnostics.ts b/src/features/chat/app-server/actions/diagnostics.ts similarity index 98% rename from src/features/chat/connection/server-actions/diagnostics.ts rename to src/features/chat/app-server/actions/diagnostics.ts index ac9a9da1..1484e08c 100644 --- a/src/features/chat/connection/server-actions/diagnostics.ts +++ b/src/features/chat/app-server/actions/diagnostics.ts @@ -12,7 +12,7 @@ import { } from "../../../../domain/server/diagnostics"; import { readRateLimitMetadataProbe } from "../../../../app-server/services/metadata"; import type { SharedServerMetadata } from "../../../../domain/server/metadata"; -import { mcpStatusLines as buildMcpStatusLines } from "../diagnostics-display"; +import { mcpStatusLines as buildMcpStatusLines } from "../../application/connection/diagnostics-display"; import { cloneServerDiagnostics, type ChatServerActionHost } from "./host"; interface RefreshDiagnosticProbesOptions { diff --git a/src/features/chat/connection/server-actions/host.ts b/src/features/chat/app-server/actions/host.ts similarity index 82% rename from src/features/chat/connection/server-actions/host.ts rename to src/features/chat/app-server/actions/host.ts index e56e8562..38f04181 100644 --- a/src/features/chat/connection/server-actions/host.ts +++ b/src/features/chat/app-server/actions/host.ts @@ -1,6 +1,6 @@ import type { AppServerClient } from "../../../../app-server/connection/client"; import { cloneServerDiagnostics } from "../../../../domain/server/diagnostics"; -import type { ChatStateStore } from "../../state/reducer"; +import type { ChatStateStore } from "../../application/state/reducer"; export interface ChatServerActionHost { stateStore: ChatStateStore; diff --git a/src/features/chat/connection/server-actions/metadata.ts b/src/features/chat/app-server/actions/metadata.ts similarity index 100% rename from src/features/chat/connection/server-actions/metadata.ts rename to src/features/chat/app-server/actions/metadata.ts diff --git a/src/features/chat/connection/server-actions/threads.ts b/src/features/chat/app-server/actions/threads.ts similarity index 89% rename from src/features/chat/connection/server-actions/threads.ts rename to src/features/chat/app-server/actions/threads.ts index e9098623..461a3a74 100644 --- a/src/features/chat/connection/server-actions/threads.ts +++ b/src/features/chat/app-server/actions/threads.ts @@ -1,11 +1,11 @@ import { listThreads } from "../../../../app-server/services/threads"; import type { Thread } from "../../../../domain/threads/model"; -import type { RuntimeSnapshot } from "../../runtime/snapshot"; -import { runtimeConfigOrDefault } from "../../runtime/effective"; -import { serviceTierRequestForThreadStart } from "../../runtime/thread-settings-update"; -import { resumedThreadActionFromAppServerResponse } from "../../threads/resume"; +import type { RuntimeSnapshot } from "../../application/runtime/snapshot"; +import { runtimeConfigOrDefault } from "../../domain/runtime/effective"; +import { serviceTierRequestForThreadStart } from "../../application/runtime/thread-settings-update"; +import { resumedThreadActionFromAppServerResponse } from "../../application/threads/resume"; import type { ChatServerActionHost } from "./host"; -import type { ChatState } from "../../state/reducer"; +import type { ChatState } from "../../application/state/reducer"; interface StartedThreadSummary { threadId: string; diff --git a/src/features/chat/app-server/inbound/controller.ts b/src/features/chat/app-server/inbound/controller.ts index d735ecad..f30dfc69 100644 --- a/src/features/chat/app-server/inbound/controller.ts +++ b/src/features/chat/app-server/inbound/controller.ts @@ -2,8 +2,8 @@ import type { RequestId, ServerNotification, ServerRequest } from "../../../../a import type { McpServerStartupStatus } from "../../../../domain/server/diagnostics"; import type { ThreadConversationSummary } from "../../../../domain/threads/transcript"; import { classifyAppServerLog } from "./app-server-logs"; -import { activeTurnId, type ChatAction, type ChatState, type ChatStateStore } from "../../state/reducer"; -import type { MessageStreamNoticeSection } from "../../domain/message-stream/model/items"; +import { activeTurnId, type ChatAction, type ChatState, type ChatStateStore } from "../../application/state/reducer"; +import type { MessageStreamNoticeSection } from "../../domain/message-stream/items"; import { createStructuredSystemItem, createSystemItem } from "../../domain/message-stream/factories/system-items"; import type { ApprovalAction, PendingApproval, PendingUserInput } from "../../domain/pending-requests/model"; import { approvalResponse } from "../requests/approval"; diff --git a/src/features/chat/app-server/inbound/notification-plan.ts b/src/features/chat/app-server/inbound/notification-plan.ts index 828f956d..da84f005 100644 --- a/src/features/chat/app-server/inbound/notification-plan.ts +++ b/src/features/chat/app-server/inbound/notification-plan.ts @@ -1,4 +1,4 @@ -import { activeThreadSettingsAppliedAction } from "../../state/actions"; +import { activeThreadSettingsAppliedAction } from "../../application/state/actions"; import type { McpServerStartupStatus } from "../../../../domain/server/diagnostics"; import { threadTokenUsageFromRuntimeUsage } from "../../../../domain/runtime/metrics"; import type { FileUpdateChange } from "../../../../app-server/protocol/file-change"; @@ -7,15 +7,20 @@ import type { ServerNotification } from "../../../../app-server/connection/rpc-m import { normalizeExplicitThreadName } from "../../../../domain/threads/model"; import type { ThreadConversationSummary } from "../../../../domain/threads/transcript"; import { jsonPreview } from "../../../../utils"; -import { activeTurnId, pendingTurnStart as pendingTurnStartForState, type ChatAction, type ChatState } from "../../state/reducer"; -import { completeReasoningItems, upsertMessageStreamItemById } from "../../domain/message-stream/operations/updates"; +import { + activeTurnId, + pendingTurnStart as pendingTurnStartForState, + type ChatAction, + type ChatState, +} from "../../application/state/reducer"; +import { completeReasoningItems, upsertMessageStreamItemById } from "../../domain/message-stream/updates"; import { messageStreamItemFromTurnItem, messageStreamItemsFromTurns, shouldSuppressLifecycleItem, } from "../mappers/message-stream/turn-items"; import { taskProgressMessageStreamItem } from "../../domain/message-stream/factories/task-progress"; -import type { MessageStreamItem, MessageStreamItemKind, MessageStreamMessageItem } from "../../domain/message-stream/model/items"; +import type { MessageStreamItem, MessageStreamItemKind, MessageStreamMessageItem } from "../../domain/message-stream/items"; import { goalChangeItem } from "../../domain/message-stream/factories/goal-items"; import { hookRunMessageStreamItem } from "../mappers/message-stream/hook-run-items"; import { createAutoReviewResultItem, createReviewResultItem } from "../mappers/message-stream/review-result-items"; @@ -24,10 +29,10 @@ import { STREAMED_COMMAND_RUNNING_TEXT, STREAMED_FILE_CHANGE_IN_PROGRESS_TEXT, STREAMED_MCP_PROGRESS_LABEL, - streamingFileChangeMessageStreamItem, } from "../../domain/message-stream/factories/streaming-items"; -import { attachHookRunsToTurn } from "../../domain/message-stream/operations/updates"; -import { messageStreamItems } from "../../state/message-stream"; +import { streamingFileChangeMessageStreamItem } from "../mappers/message-stream/streaming-items"; +import { attachHookRunsToTurn } from "../../domain/message-stream/updates"; +import { messageStreamItems } from "../../application/state/message-stream"; import { routeServerNotification, type DiagnosticStatusNotificationMethod, diff --git a/src/features/chat/app-server/mappers/message-stream/agent-items.ts b/src/features/chat/app-server/mappers/message-stream/agent-items.ts index b17fa179..89a7cd6a 100644 --- a/src/features/chat/app-server/mappers/message-stream/agent-items.ts +++ b/src/features/chat/app-server/mappers/message-stream/agent-items.ts @@ -1,21 +1,10 @@ import { definedProp } from "../../../../../utils"; -import type { AgentMessageStreamItem, AgentStateSummary, ExecutionState } from "../../../domain/message-stream/model/items"; +import type { AgentMessageStreamItem, AgentStateSummary, ExecutionState } from "../../../domain/message-stream/items"; +import { collabAgentStateExecutionState } from "../../../domain/message-stream/agent-state"; type MessageStreamExecutionState = Exclude; type ExecutionStateByStatus = Readonly>; -const AGENT_STATES = { - pendingInit: "running", - running: "running", - inProgress: "running", - completed: "completed", - shutdown: "completed", - interrupted: "failed", - errored: "failed", - notFound: "failed", - failed: "failed", -} as const satisfies ExecutionStateByStatus; - const STANDARD_TOOL_STATES = { inProgress: "running", completed: "completed", @@ -82,10 +71,6 @@ function collabAgentExecutionState(tool: string, status: string, receiverThreadI return null; } -export function collabAgentStateExecutionState(status: string): ExecutionState { - return executionStateFromStatus(status, AGENT_STATES); -} - function collabAgentToolCallExecutionState(status: string): ExecutionState { return executionStateFromStatus(status, STANDARD_TOOL_STATES); } diff --git a/src/features/chat/app-server/mappers/message-stream/hook-run-items.ts b/src/features/chat/app-server/mappers/message-stream/hook-run-items.ts index 86bb2847..acf333b6 100644 --- a/src/features/chat/app-server/mappers/message-stream/hook-run-items.ts +++ b/src/features/chat/app-server/mappers/message-stream/hook-run-items.ts @@ -1,5 +1,5 @@ import { definedProp } from "../../../../../utils"; -import type { HookMessageStreamItem } from "../../../domain/message-stream/model/items"; +import type { HookMessageStreamItem } from "../../../domain/message-stream/items"; interface MessageStreamHookRun { id: string; diff --git a/src/features/chat/app-server/mappers/message-stream/review-result-items.ts b/src/features/chat/app-server/mappers/message-stream/review-result-items.ts index 68390933..49808409 100644 --- a/src/features/chat/app-server/mappers/message-stream/review-result-items.ts +++ b/src/features/chat/app-server/mappers/message-stream/review-result-items.ts @@ -1,4 +1,4 @@ -import type { ExecutionState, MessageStreamAuditFact, MessageStreamItem } from "../../../domain/message-stream/model/items"; +import type { ExecutionState, MessageStreamAuditFact, MessageStreamItem } from "../../../domain/message-stream/items"; import { pathsRelativeToRoot } from "../../../domain/message-stream/format/path-labels"; import { permissionRows } from "../../../domain/message-stream/format/permission-rows"; diff --git a/src/features/chat/app-server/mappers/message-stream/streaming-items.ts b/src/features/chat/app-server/mappers/message-stream/streaming-items.ts new file mode 100644 index 00000000..52f4171e --- /dev/null +++ b/src/features/chat/app-server/mappers/message-stream/streaming-items.ts @@ -0,0 +1,21 @@ +import type { FileUpdateChange } from "../../../../../app-server/protocol/file-change"; +import type { MessageStreamItem } from "../../../domain/message-stream/items"; +import { normalizeFileChanges } from "./turn-items"; + +export function streamingFileChangeMessageStreamItem( + itemId: string, + turnId: string, + changes: FileUpdateChange[], + status: string, +): MessageStreamItem { + return { + id: itemId, + kind: "fileChange", + role: "tool", + turnId, + sourceItemId: itemId, + provenance: { source: "appServer", channel: "notification", event: "streamingDelta", sourceItemId: itemId }, + status, + changes: normalizeFileChanges(changes), + }; +} diff --git a/src/features/chat/app-server/mappers/message-stream/turn-items.ts b/src/features/chat/app-server/mappers/message-stream/turn-items.ts index b75afc80..10e86611 100644 --- a/src/features/chat/app-server/mappers/message-stream/turn-items.ts +++ b/src/features/chat/app-server/mappers/message-stream/turn-items.ts @@ -5,8 +5,8 @@ import type { MessageStreamFileMention, MessageStreamItem, MessageStreamPrimaryTarget, -} from "../../../domain/message-stream/model/items"; -import type { MessageStreamItemProvenance } from "../../../domain/message-stream/model/provenance"; +} from "../../../domain/message-stream/items"; +import type { MessageStreamItemProvenance } from "../../../domain/message-stream/provenance"; import type { HistoricalTurn } from "../../../../../domain/threads/history"; import type { FileUpdateChange } from "../../../../../app-server/protocol/file-change"; import type { TurnItem } from "../../../../../app-server/protocol/turn"; diff --git a/src/features/chat/chat-host.ts b/src/features/chat/application/chat-host.ts similarity index 76% rename from src/features/chat/chat-host.ts rename to src/features/chat/application/chat-host.ts index eb3fa2ee..0a7988a5 100644 --- a/src/features/chat/chat-host.ts +++ b/src/features/chat/application/chat-host.ts @@ -1,7 +1,7 @@ -import type { Thread } from "../../domain/threads/model"; -import type { SharedServerMetadata } from "../../domain/server/metadata"; -import type { CodexPanelSettings } from "../../settings/model"; -import type { ChatTurnDiffViewState } from "./turn-diff/model"; +import type { Thread } from "../../../domain/threads/model"; +import type { SharedServerMetadata } from "../../../domain/server/metadata"; +import type { CodexPanelSettings } from "../../../settings/model"; +import type { ChatTurnDiffViewState } from "../domain/turn-diff"; export interface CodexChatHost { readonly settings: CodexPanelSettings; diff --git a/src/features/chat/conversation/composer/boundary-scroll.ts b/src/features/chat/application/composer/boundary-scroll.ts similarity index 100% rename from src/features/chat/conversation/composer/boundary-scroll.ts rename to src/features/chat/application/composer/boundary-scroll.ts diff --git a/src/features/chat/conversation/composer/obsidian-context.ts b/src/features/chat/application/composer/obsidian-context.ts similarity index 100% rename from src/features/chat/conversation/composer/obsidian-context.ts rename to src/features/chat/application/composer/obsidian-context.ts diff --git a/src/features/chat/conversation/composer/slash-commands.ts b/src/features/chat/application/composer/slash-commands.ts similarity index 100% rename from src/features/chat/conversation/composer/slash-commands.ts rename to src/features/chat/application/composer/slash-commands.ts diff --git a/src/features/chat/conversation/composer/suggestions.ts b/src/features/chat/application/composer/suggestions.ts similarity index 100% rename from src/features/chat/conversation/composer/suggestions.ts rename to src/features/chat/application/composer/suggestions.ts diff --git a/src/features/chat/conversation/composer/wikilink-context.ts b/src/features/chat/application/composer/wikilink-context.ts similarity index 100% rename from src/features/chat/conversation/composer/wikilink-context.ts rename to src/features/chat/application/composer/wikilink-context.ts diff --git a/src/features/chat/connection/app-server-warmup.ts b/src/features/chat/application/connection/app-server-warmup.ts similarity index 100% rename from src/features/chat/connection/app-server-warmup.ts rename to src/features/chat/application/connection/app-server-warmup.ts diff --git a/src/features/chat/connection/connection-controller.ts b/src/features/chat/application/connection/connection-controller.ts similarity index 95% rename from src/features/chat/connection/connection-controller.ts rename to src/features/chat/application/connection/connection-controller.ts index 5fa697b6..b8f30891 100644 --- a/src/features/chat/connection/connection-controller.ts +++ b/src/features/chat/application/connection/connection-controller.ts @@ -1,6 +1,6 @@ -import { StaleConnectionError } from "../../../app-server/connection/connection-manager"; -import type { AppServerClient } from "../../../app-server/connection/client"; -import type { ServerInitialization } from "../../../domain/server/initialization"; +import { StaleConnectionError } from "../../../../app-server/connection/connection-manager"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import type { ServerInitialization } from "../../../../domain/server/initialization"; import type { ChatConnectionPhase, ChatStateStore } from "../state/reducer"; import type { ChatConnectionWorkTracker, ActiveChatConnection } from "../lifecycle"; import { diff --git a/src/features/chat/connection/diagnostics-display.ts b/src/features/chat/application/connection/diagnostics-display.ts similarity index 97% rename from src/features/chat/connection/diagnostics-display.ts rename to src/features/chat/application/connection/diagnostics-display.ts index d0a54b96..349c626e 100644 --- a/src/features/chat/connection/diagnostics-display.ts +++ b/src/features/chat/application/connection/diagnostics-display.ts @@ -1,12 +1,12 @@ -import { DIAGNOSTIC_PROBE_METHODS, serverIdentity, serverPlatform } from "../../../domain/server/diagnostics"; -import { CLIENT_VERSION } from "../../../constants"; +import { DIAGNOSTIC_PROBE_METHODS, serverIdentity, serverPlatform } from "../../../../domain/server/diagnostics"; +import { CLIENT_VERSION } from "../../../../constants"; import type { Diagnostics, InitializeDiagnostics, DiagnosticProbeResult, McpServerDiagnostic, McpServerStatusSummary, -} from "../../../domain/server/diagnostics"; +} from "../../../../domain/server/diagnostics"; interface DiagnosticRow { label: string; diff --git a/src/features/chat/connection/messages.ts b/src/features/chat/application/connection/messages.ts similarity index 100% rename from src/features/chat/connection/messages.ts rename to src/features/chat/application/connection/messages.ts diff --git a/src/features/chat/connection/reconnect-actions.ts b/src/features/chat/application/connection/reconnect-actions.ts similarity index 100% rename from src/features/chat/connection/reconnect-actions.ts rename to src/features/chat/application/connection/reconnect-actions.ts diff --git a/src/features/chat/conversation/turns/composer-submit-actions.ts b/src/features/chat/application/conversation/composer-submit-actions.ts similarity index 96% rename from src/features/chat/conversation/turns/composer-submit-actions.ts rename to src/features/chat/application/conversation/composer-submit-actions.ts index 57406c1a..63716ba9 100644 --- a/src/features/chat/conversation/turns/composer-submit-actions.ts +++ b/src/features/chat/application/conversation/composer-submit-actions.ts @@ -1,7 +1,7 @@ import type { AppServerClient } from "../../../../app-server/connection/client"; import type { CodexInput } from "../../../../domain/chat/input"; -import { submissionStateSnapshot } from "../../state/selectors"; -import type { ChatStateStore } from "../../state/reducer"; +import { submissionStateSnapshot } from "../state/selectors"; +import type { ChatStateStore } from "../state/reducer"; import { parseSlashCommand } from "../composer/suggestions"; import type { SlashCommandExecutionResult } from "./slash-command-execution"; import type { SlashCommandName } from "../composer/slash-commands"; diff --git a/src/features/chat/conversation/turns/composition.ts b/src/features/chat/application/conversation/composition.ts similarity index 92% rename from src/features/chat/conversation/turns/composition.ts rename to src/features/chat/application/conversation/composition.ts index a120d0f8..52003542 100644 --- a/src/features/chat/conversation/turns/composition.ts +++ b/src/features/chat/application/conversation/composition.ts @@ -1,12 +1,12 @@ import type { AppServerClient } from "../../../../app-server/connection/client"; import type { CodexInput } from "../../../../domain/chat/input"; -import type { ChatServerThreadActions } from "../../connection/server-actions/threads"; -import type { ChatReconnectActions } from "../../connection/reconnect-actions"; -import type { MessageStreamNoticeSection } from "../../domain/message-stream/model/items"; -import type { ChatRuntimeSettingsActions } from "../../runtime/settings-actions"; -import type { ChatStateStore } from "../../state/reducer"; -import type { ThreadManagementActions } from "../../threads/thread-management-actions"; -import type { GoalActions } from "../../threads/goal-actions"; +import type { ChatServerThreadActions } from "../../app-server/actions/threads"; +import type { ChatReconnectActions } from "../connection/reconnect-actions"; +import type { MessageStreamNoticeSection } from "../../domain/message-stream/items"; +import type { ChatRuntimeSettingsActions } from "../runtime/settings-actions"; +import type { ChatStateStore } from "../state/reducer"; +import type { ThreadManagementActions } from "../threads/thread-management-actions"; +import type { GoalActions } from "../threads/goal-actions"; import { createComposerSubmitActions, type ComposerSubmitActions } from "./composer-submit-actions"; import { createPlanImplementation, type PlanImplementation } from "./plan-implementation"; import { createSlashCommandHandler } from "./slash-command-handler"; diff --git a/src/features/chat/conversation/turns/messages.ts b/src/features/chat/application/conversation/messages.ts similarity index 100% rename from src/features/chat/conversation/turns/messages.ts rename to src/features/chat/application/conversation/messages.ts diff --git a/src/features/chat/conversation/turns/optimistic-turn-start.ts b/src/features/chat/application/conversation/optimistic-turn-start.ts similarity index 95% rename from src/features/chat/conversation/turns/optimistic-turn-start.ts rename to src/features/chat/application/conversation/optimistic-turn-start.ts index cab25a4b..72294902 100644 --- a/src/features/chat/conversation/turns/optimistic-turn-start.ts +++ b/src/features/chat/application/conversation/optimistic-turn-start.ts @@ -1,9 +1,9 @@ -import type { PendingTurnStart } from "../../state/reducer"; -import type { MessageStreamFileMention, MessageStreamItem, MessageStreamMessageItem } from "../../domain/message-stream/model/items"; -import type { MessageStreamItemProvenance } from "../../domain/message-stream/model/provenance"; +import type { PendingTurnStart } from "../state/reducer"; +import type { MessageStreamFileMention, MessageStreamItem, MessageStreamMessageItem } from "../../domain/message-stream/items"; +import type { MessageStreamItemProvenance } from "../../domain/message-stream/provenance"; import { fileMentionsFromInput } from "../../domain/message-stream/format/file-mentions"; import { userMessageDisplayText } from "../../domain/message-stream/format/user-message-text"; -import { attachHookRunsToTurn } from "../../domain/message-stream/operations/updates"; +import { attachHookRunsToTurn } from "../../domain/message-stream/updates"; import type { CodexInput } from "../../../../domain/chat/input"; export interface LocalUserMessageParams { diff --git a/src/features/chat/conversation/turns/plan-implementation.ts b/src/features/chat/application/conversation/plan-implementation.ts similarity index 89% rename from src/features/chat/conversation/turns/plan-implementation.ts rename to src/features/chat/application/conversation/plan-implementation.ts index 27b61814..877edb67 100644 --- a/src/features/chat/conversation/turns/plan-implementation.ts +++ b/src/features/chat/application/conversation/plan-implementation.ts @@ -1,7 +1,7 @@ import type { AppServerClient } from "../../../../app-server/connection/client"; -import { activeThreadId, canImplementPlan } from "../../state/selectors"; -import type { ChatStateStore } from "../../state/reducer"; -import type { MessageStreamItem } from "../../domain/message-stream/model/items"; +import { activeThreadId, canImplementPlan } from "../state/selectors"; +import type { ChatStateStore } from "../state/reducer"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; const IMPLEMENT_PLAN_PROMPT = "Please implement this plan."; diff --git a/src/features/chat/conversation/turns/runtime-setting-commands.ts b/src/features/chat/application/conversation/runtime-setting-commands.ts similarity index 100% rename from src/features/chat/conversation/turns/runtime-setting-commands.ts rename to src/features/chat/application/conversation/runtime-setting-commands.ts diff --git a/src/features/chat/conversation/turns/slash-command-execution.ts b/src/features/chat/application/conversation/slash-command-execution.ts similarity index 99% rename from src/features/chat/conversation/turns/slash-command-execution.ts rename to src/features/chat/application/conversation/slash-command-execution.ts index 9642bd18..03154e1d 100644 --- a/src/features/chat/conversation/turns/slash-command-execution.ts +++ b/src/features/chat/application/conversation/slash-command-execution.ts @@ -12,8 +12,8 @@ import { type SlashCommandName, type SlashCommandSubcommandDefinition, } from "../composer/slash-commands"; -import type { MessageStreamAuditFact, MessageStreamNoticeSection } from "../../domain/message-stream/model/items"; -import { modelOverrideMessage, reasoningEffortOverrideMessage } from "../../runtime/messages"; +import type { MessageStreamAuditFact, MessageStreamNoticeSection } from "../../domain/message-stream/items"; +import { modelOverrideMessage, reasoningEffortOverrideMessage } from "../runtime/messages"; import { currentThreadReferenceMessage } from "./messages"; import { finishBeforeArchivingThreadsMessage, @@ -21,7 +21,7 @@ import { noActiveThreadToCompactMessage, noActiveThreadToForkMessage, noActiveThreadToRollbackMessage, -} from "../../threads/messages"; +} from "../threads/messages"; import { parseModelOverride, parseReasoningEffortOverride } from "./runtime-setting-commands"; export interface SlashCommandExecutionContext { diff --git a/src/features/chat/conversation/turns/slash-command-handler.ts b/src/features/chat/application/conversation/slash-command-handler.ts similarity index 93% rename from src/features/chat/conversation/turns/slash-command-handler.ts rename to src/features/chat/application/conversation/slash-command-handler.ts index 0d7d31c3..7424b52a 100644 --- a/src/features/chat/conversation/turns/slash-command-handler.ts +++ b/src/features/chat/application/conversation/slash-command-handler.ts @@ -13,10 +13,10 @@ import { import type { SlashCommandName } from "../composer/slash-commands"; import type { ReasoningEffort } from "../../../../domain/catalog/metadata"; import { findModelMetadataByIdOrName, supportedEffortsForModelMetadata } from "../../../../domain/catalog/metadata"; -import { submissionStateSnapshot } from "../../state/selectors"; -import type { ChatStateStore } from "../../state/reducer"; -import { currentModel, runtimeConfigOrDefault } from "../../runtime/effective"; -import { runtimeSnapshotForChatState } from "../../runtime/snapshot"; +import { submissionStateSnapshot } from "../state/selectors"; +import type { ChatStateStore } from "../state/reducer"; +import { currentModel, runtimeConfigOrDefault } from "../../domain/runtime/effective"; +import { runtimeSnapshotForChatState } from "../runtime/snapshot"; type DynamicSlashCommandExecutionContext = "activeThreadId" | "busy" | "listedThreads" | "referThread" | "supportedReasoningEfforts"; diff --git a/src/features/chat/conversation/turns/turn-state.ts b/src/features/chat/application/conversation/turn-state.ts similarity index 100% rename from src/features/chat/conversation/turns/turn-state.ts rename to src/features/chat/application/conversation/turn-state.ts diff --git a/src/features/chat/conversation/turns/turn-submission-controller.ts b/src/features/chat/application/conversation/turn-submission-controller.ts similarity index 98% rename from src/features/chat/conversation/turns/turn-submission-controller.ts rename to src/features/chat/application/conversation/turn-submission-controller.ts index ecd5bc73..c98ffa3a 100644 --- a/src/features/chat/conversation/turns/turn-submission-controller.ts +++ b/src/features/chat/application/conversation/turn-submission-controller.ts @@ -1,8 +1,8 @@ import type { AppServerClient } from "../../../../app-server/connection/client"; import type { CodexInput } from "../../../../domain/chat/input"; import type { ReferencedThreadMetadata } from "../../../../domain/threads/reference"; -import { submissionStateSnapshot } from "../../state/selectors"; -import type { ChatStateStore } from "../../state/reducer"; +import { submissionStateSnapshot } from "../state/selectors"; +import type { ChatStateStore } from "../state/reducer"; import { currentTurnNotSteerableMessage, STATUS_STEERED_CURRENT_TURN, STATUS_TURN_RUNNING } from "./messages"; import { acknowledgeOptimisticTurnStart, diff --git a/src/features/chat/lifecycle.ts b/src/features/chat/application/lifecycle.ts similarity index 79% rename from src/features/chat/lifecycle.ts rename to src/features/chat/application/lifecycle.ts index 6443bd8d..d4d4d50c 100644 --- a/src/features/chat/lifecycle.ts +++ b/src/features/chat/application/lifecycle.ts @@ -3,8 +3,7 @@ import { type ActiveConnectionWork, type ConnectionWorkLifecycleEvent, type ConnectionWorkLifecycleState, -} from "../../shared/lifecycle/connection-work"; -import { DeferredTask, type DeferredTaskWindow } from "../../shared/lifecycle/deferred-task"; +} from "../../../shared/lifecycle/connection-work"; export interface RestoredThreadState { threadId: string; @@ -41,44 +40,6 @@ export interface ChatViewDeferredTasks { clearAll(): void; } -export function createChatViewDeferredTasks(getWindow: () => DeferredTaskWindow): ChatViewDeferredTasks { - const diagnosticsTask = new DeferredTask(getWindow, 1_000); - const restoredThreadHydrationTask = new DeferredTask(getWindow, 1_500); - const appServerWarmupTask = new DeferredTask(getWindow, 0); - - return { - scheduleDiagnostics(callback): void { - diagnosticsTask.schedule(callback); - }, - - clearDiagnostics(): void { - diagnosticsTask.clear(); - }, - - scheduleRestoredThreadHydration(callback): void { - restoredThreadHydrationTask.schedule(callback); - }, - - clearRestoredThreadHydration(): void { - restoredThreadHydrationTask.clear(); - }, - - scheduleAppServerWarmup(callback): void { - appServerWarmupTask.schedule(callback); - }, - - clearAppServerWarmup(): void { - appServerWarmupTask.clear(); - }, - - clearAll(): void { - restoredThreadHydrationTask.clear(); - appServerWarmupTask.clear(); - diagnosticsTask.clear(); - }, - }; -} - export class ChatConnectionWorkTracker { private state: ChatConnectionLifecycleState = { kind: "idle" }; diff --git a/src/features/chat/application/pending-requests/block.ts b/src/features/chat/application/pending-requests/block.ts new file mode 100644 index 00000000..ca6c58b1 --- /dev/null +++ b/src/features/chat/application/pending-requests/block.ts @@ -0,0 +1,18 @@ +import type { ApprovalAction, PendingApproval, PendingRequestId, PendingUserInput } from "../../domain/pending-requests/model"; + +export type { PendingRequestId } from "../../domain/pending-requests/model"; + +export interface PendingRequestBlockState { + approvals: readonly PendingApproval[]; + pendingUserInputs: readonly PendingUserInput[]; + userInputDrafts: ReadonlyMap; + approvalDetails: ReadonlySet; +} + +export interface PendingRequestBlockActions { + resolveApproval: (requestId: PendingRequestId, action: ApprovalAction) => void; + resolveUserInput: (requestId: PendingRequestId) => void; + cancelUserInput: (requestId: PendingRequestId) => void; + setApprovalDetailsExpanded?: (requestId: PendingRequestId, expanded: boolean) => void; + setUserInputDraft: (key: string, value: string) => void; +} diff --git a/src/features/chat/application/pending-requests/controller.ts b/src/features/chat/application/pending-requests/controller.ts index 6fbd1ba6..a495c583 100644 --- a/src/features/chat/application/pending-requests/controller.ts +++ b/src/features/chat/application/pending-requests/controller.ts @@ -1,14 +1,14 @@ -import type { ChatStateStore } from "../../state/reducer"; +import type { ChatStateStore } from "../state/reducer"; import type { ChatInboundController } from "../../app-server/inbound/controller"; import { pendingRequestFocusSignature } from "../../domain/pending-requests/signatures"; -import { pendingRequestBlockSnapshot, type PendingRequestBlockSnapshot } from "../../presentation/pending-requests/snapshot"; +import { pendingRequestBlockState } from "./snapshot"; import { answersForPendingUserInput, type ApprovalAction, type PendingApproval, type PendingUserInput, } from "../../domain/pending-requests/model"; -import type { PendingRequestBlockActions, PendingRequestId } from "../../presentation/pending-requests/view-model"; +import type { PendingRequestBlockActions, PendingRequestBlockState, PendingRequestId } from "./block"; export interface PendingRequestControllerHost { stateStore: ChatStateStore; @@ -44,8 +44,8 @@ export class PendingRequestController { constructor(private readonly host: PendingRequestControllerHost) {} - snapshot(): PendingRequestBlockSnapshot { - return pendingRequestBlockSnapshot(this.host.stateStore.getState()); + snapshot(): PendingRequestBlockState { + return pendingRequestBlockState(this.host.stateStore.getState()); } actions(): PendingRequestBlockActions { @@ -64,7 +64,7 @@ export class PendingRequestController { if (!input) return; this.host.controller.resolveUserInput( input, - answersForPendingUserInput(input, pendingRequestBlockSnapshot(this.host.stateStore.getState()).userInputDrafts), + answersForPendingUserInput(input, pendingRequestBlockState(this.host.stateStore.getState()).userInputDrafts), ); this.commitRequestAction(); } diff --git a/src/features/chat/application/pending-requests/snapshot.ts b/src/features/chat/application/pending-requests/snapshot.ts new file mode 100644 index 00000000..c6ab636e --- /dev/null +++ b/src/features/chat/application/pending-requests/snapshot.ts @@ -0,0 +1,11 @@ +import type { ChatState } from "../state/reducer"; +import type { PendingRequestBlockState } from "./block"; + +export function pendingRequestBlockState(state: ChatState): PendingRequestBlockState { + return { + approvals: state.requests.approvals, + pendingUserInputs: state.requests.pendingUserInputs, + userInputDrafts: state.requests.userInputDrafts, + approvalDetails: state.ui.disclosures.approvalDetails, + }; +} diff --git a/src/features/chat/runtime/messages.ts b/src/features/chat/application/runtime/messages.ts similarity index 50% rename from src/features/chat/runtime/messages.ts rename to src/features/chat/application/runtime/messages.ts index b14ed1bb..0904eec2 100644 --- a/src/features/chat/runtime/messages.ts +++ b/src/features/chat/application/runtime/messages.ts @@ -1,6 +1,6 @@ -import type { ReasoningEffort } from "../../../domain/catalog/metadata"; -import type { CollaborationMode } from "./pending-settings"; -import type { TurnCollaborationModeWarning } from "./thread-settings-update"; +import type { ReasoningEffort } from "../../../../domain/catalog/metadata"; +import type { CollaborationMode } from "../../domain/runtime/pending-settings"; +import type { TurnCollaborationModeWarning } from "../../domain/runtime/warnings"; const COLLABORATION_MODE_WARNING_MESSAGES: Record = { "missing-model": "No effective model is available. Sending without a mode override.", @@ -16,40 +16,6 @@ export function reasoningEffortOverrideMessage(effort: ReasoningEffort | null): : `Reasoning effort set to ${effort} for subsequent turns.`; } -export function compactModelLabel(model: string | null): string { - if (!model) return "default"; - const match = /^gpt-(.+)$/.exec(model); - return match?.[1] ?? model; -} - -export function compactReasoningEffortLabel(effort: ReasoningEffort | null): string { - if (!effort) return "default"; - if (effort === "minimal") return "min"; - return effort; -} - -export function collaborationModeLabel(mode: CollaborationMode): string { - return mode === "plan" ? "Plan" : "Default"; -} - -export function pendingRuntimeSettingLabel( - setting: { kind: "unchanged" } | { kind: "set"; value: unknown } | { kind: "resetToConfig" }, -): string { - if (setting.kind === "set") return String(setting.value); - if (setting.kind === "resetToConfig") return "(reset to config)"; - return "(none)"; -} - -export function serviceTierLabel(value: string | null): string { - return value ?? "(Codex default)"; -} - -export function fastModeLabel(input: { requestedOff: boolean; active: boolean; serviceTier: string | null }): string { - if (input.requestedOff) return "off"; - if (input.active) return "on"; - return input.serviceTier ? "off" : "Codex default"; -} - export function fastModeToggleMessage(state: "enabled" | "disabled"): string { return state === "enabled" ? "Fast mode on for subsequent turns." : "Fast mode off for subsequent turns."; } diff --git a/src/features/chat/runtime/settings-actions.ts b/src/features/chat/application/runtime/settings-actions.ts similarity index 95% rename from src/features/chat/runtime/settings-actions.ts rename to src/features/chat/application/runtime/settings-actions.ts index 6afe51d9..fcb1708c 100644 --- a/src/features/chat/runtime/settings-actions.ts +++ b/src/features/chat/application/runtime/settings-actions.ts @@ -1,15 +1,15 @@ -import type { AppServerClient } from "../../../app-server/connection/client"; -import type { RuntimeConfigSnapshot } from "../../../domain/runtime/config"; -import type { ApprovalsReviewer } from "../../../domain/runtime/policy"; -import type { RuntimeSettingsPatch } from "../../../domain/runtime/thread-settings"; -import type { ReasoningEffort } from "../../../domain/catalog/metadata"; -import { autoReviewActive, fastModeActive, runtimeConfigOrDefault } from "./effective"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import type { RuntimeConfigSnapshot } from "../../../../domain/runtime/config"; +import type { ApprovalsReviewer } from "../../../../domain/runtime/policy"; +import type { RuntimeSettingsPatch } from "../../../../domain/runtime/thread-settings"; +import type { ReasoningEffort } from "../../../../domain/catalog/metadata"; +import { autoReviewActive, fastModeActive, runtimeConfigOrDefault } from "../../domain/runtime/effective"; import { pendingRuntimeSettingsPatch as buildPendingRuntimeSettingsPatch, type PendingRuntimeSettingsPatch, } from "./thread-settings-update"; import type { RuntimeSnapshot } from "./snapshot"; -import { nextCollaborationMode, type CollaborationMode, type RequestedServiceTier } from "./pending-settings"; +import { nextCollaborationMode, type CollaborationMode, type RequestedServiceTier } from "../../domain/runtime/pending-settings"; import { autoReviewToggleMessage, collaborationModeToggleMessage, diff --git a/src/features/chat/runtime/snapshot.ts b/src/features/chat/application/runtime/snapshot.ts similarity index 57% rename from src/features/chat/runtime/snapshot.ts rename to src/features/chat/application/runtime/snapshot.ts index 7ced118c..b7397bac 100644 --- a/src/features/chat/runtime/snapshot.ts +++ b/src/features/chat/application/runtime/snapshot.ts @@ -1,32 +1,9 @@ import type { ChatState } from "../state/reducer"; -import type { RuntimeConfigSnapshot } from "../../../domain/runtime/config"; -import type { RateLimitSnapshot, ThreadTokenUsage } from "../../../domain/runtime/metrics"; -import type { ActivePermissionProfile, ApprovalPolicy, ApprovalsReviewer, ServiceTier } from "../../../domain/runtime/policy"; -import type { ModelMetadata, ReasoningEffort } from "../../../domain/catalog/metadata"; -import type { ActiveCollaborationMode, CollaborationMode, PendingRuntimeSetting, RequestedServiceTier } from "./pending-settings"; -import type { MessageStreamItem } from "../domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; +import type { RuntimeSnapshot } from "../../domain/runtime/snapshot"; import { messageStreamItems } from "../state/message-stream"; -export interface RuntimeSnapshot { - runtimeConfig: RuntimeConfigSnapshot | null; - activeThreadId: string | null; - activeModel: string | null; - activeReasoningEffort: ReasoningEffort | null; - activeCollaborationMode: ActiveCollaborationMode; - activeServiceTier: ServiceTier | null; - activeApprovalPolicy: ApprovalPolicy | null; - activeApprovalsReviewer: ApprovalsReviewer | null; - activePermissionProfile: ActivePermissionProfile | null; - requestedModel: PendingRuntimeSetting; - requestedReasoningEffort: PendingRuntimeSetting; - requestedApprovalsReviewer: PendingRuntimeSetting; - selectedCollaborationMode: CollaborationMode; - requestedServiceTier: PendingRuntimeSetting; - tokenUsage: ThreadTokenUsage | null; - rateLimit: RateLimitSnapshot | null; - hasThreadTurns: boolean; - availableModels: readonly ModelMetadata[]; -} +export type { RuntimeSnapshot } from "../../domain/runtime/snapshot"; interface RuntimeSnapshotInput { runtimeConfig: ChatState["connection"]["runtimeConfig"]; diff --git a/src/features/chat/runtime/thread-settings-update.ts b/src/features/chat/application/runtime/thread-settings-update.ts similarity index 89% rename from src/features/chat/runtime/thread-settings-update.ts rename to src/features/chat/application/runtime/thread-settings-update.ts index 1673ee50..891773b4 100644 --- a/src/features/chat/runtime/thread-settings-update.ts +++ b/src/features/chat/application/runtime/thread-settings-update.ts @@ -3,13 +3,12 @@ import { runtimeCollaborationModeSettings, type RuntimeServiceTierRequest, type RuntimeSettingsPatch, -} from "../../../domain/runtime/thread-settings"; -import { currentModel, currentReasoningEffort, fastRuntimeServiceTierRequestValue } from "./effective"; -import type { RuntimeConfigSnapshot } from "../../../domain/runtime/config"; -import type { RuntimeSnapshot } from "./snapshot"; -import { effectiveCollaborationMode, type PendingRuntimeSetting } from "./pending-settings"; - -export type TurnCollaborationModeWarning = "missing-model"; +} from "../../../../domain/runtime/thread-settings"; +import { currentModel, currentReasoningEffort, fastRuntimeServiceTierRequestValue } from "../../domain/runtime/effective"; +import type { RuntimeConfigSnapshot } from "../../../../domain/runtime/config"; +import type { RuntimeSnapshot } from "../../domain/runtime/snapshot"; +import { effectiveCollaborationMode, type PendingRuntimeSetting } from "../../domain/runtime/pending-settings"; +import type { TurnCollaborationModeWarning } from "../../domain/runtime/warnings"; export type TurnCollaborationModeSettings = | { diff --git a/src/features/chat/state/actions.ts b/src/features/chat/application/state/actions.ts similarity index 86% rename from src/features/chat/state/actions.ts rename to src/features/chat/application/state/actions.ts index bc77decc..b966c399 100644 --- a/src/features/chat/state/actions.ts +++ b/src/features/chat/application/state/actions.ts @@ -1,11 +1,11 @@ -import type { ServerInitialization } from "../../../domain/server/initialization"; -import type { Thread } from "../../../domain/threads/model"; -import { parseServiceTier, type ServiceTier } from "../../../domain/runtime/policy"; -import { normalizeReasoningEffort, type ReasoningEffort } from "../../../domain/catalog/metadata"; -import type { ChatRuntimeState } from "../runtime/state"; -import type { CollaborationMode } from "../runtime/pending-settings"; -import type { MessageStreamItem } from "../domain/message-stream/model/items"; -import type { PendingTurnStart } from "../conversation/turns/turn-state"; +import type { ServerInitialization } from "../../../../domain/server/initialization"; +import type { Thread } from "../../../../domain/threads/model"; +import { parseServiceTier, type ServiceTier } from "../../../../domain/runtime/policy"; +import { normalizeReasoningEffort, type ReasoningEffort } from "../../../../domain/catalog/metadata"; +import type { ChatRuntimeState } from "../../domain/runtime/state"; +import type { CollaborationMode } from "../../domain/runtime/pending-settings"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; +import type { PendingTurnStart } from "../conversation/turn-state"; export interface ActiveThreadResumedAction { type: "active-thread/resumed"; diff --git a/src/features/chat/state/message-stream.ts b/src/features/chat/application/state/message-stream.ts similarity index 98% rename from src/features/chat/state/message-stream.ts rename to src/features/chat/application/state/message-stream.ts index e92a6d46..6df366d7 100644 --- a/src/features/chat/state/message-stream.ts +++ b/src/features/chat/application/state/message-stream.ts @@ -1,12 +1,12 @@ -import { upsertMessageStreamItemById } from "../domain/message-stream/operations/updates"; -import type { MessageStreamItem, MessageStreamMessageItem } from "../domain/message-stream/model/items"; -import { normalizeProposedPlanMarkdown } from "../domain/message-stream/format/proposed-plan"; -import { messageStreamIsTurnInitiator, messageStreamSemanticClassifications } from "../domain/message-stream/semantics"; +import { upsertMessageStreamItemById } from "../../domain/message-stream/updates"; +import type { MessageStreamItem, MessageStreamMessageItem } from "../../domain/message-stream/items"; +import { normalizeProposedPlanMarkdown } from "../../domain/message-stream/format/proposed-plan"; +import { messageStreamIsTurnInitiator, messageStreamSemanticClassifications } from "../../domain/message-stream/semantics"; import { streamedItemOutputMessageStreamItem, streamedTextMessageStreamItem, streamedToolOutputMessageStreamItem, -} from "../domain/message-stream/factories/streaming-items"; +} from "../../domain/message-stream/factories/streaming-items"; export interface ChatMessageStreamActiveSegment { turnId: string | null; diff --git a/src/features/chat/state/reducer.ts b/src/features/chat/application/state/reducer.ts similarity index 96% rename from src/features/chat/state/reducer.ts rename to src/features/chat/application/state/reducer.ts index 6e5beb52..ebcb97e7 100644 --- a/src/features/chat/state/reducer.ts +++ b/src/features/chat/application/state/reducer.ts @@ -1,15 +1,15 @@ -import type { ServerInitialization } from "../../../domain/server/initialization"; -import type { ReasoningEffort } from "../../../domain/catalog/metadata"; -import type { Thread } from "../../../domain/threads/model"; -import type { ModelMetadata, SkillMetadata } from "../../../domain/catalog/metadata"; -import type { ThreadGoal } from "../../../domain/threads/goal"; -import type { Diagnostics } from "../../../domain/server/diagnostics"; -import { createServerDiagnostics } from "../../../domain/server/diagnostics"; -import type { RuntimeConfigSnapshot } from "../../../domain/runtime/config"; -import type { RateLimitSnapshot, ThreadTokenUsage } from "../../../domain/runtime/metrics"; -import type { ApprovalsReviewer } from "../../../domain/runtime/policy"; -import type { RuntimeSettingsPatch } from "../../../domain/runtime/thread-settings"; -import type { CollaborationMode } from "../runtime/pending-settings"; +import type { ServerInitialization } from "../../../../domain/server/initialization"; +import type { ReasoningEffort } from "../../../../domain/catalog/metadata"; +import type { Thread } from "../../../../domain/threads/model"; +import type { ModelMetadata, SkillMetadata } from "../../../../domain/catalog/metadata"; +import type { ThreadGoal } from "../../../../domain/threads/goal"; +import type { Diagnostics } from "../../../../domain/server/diagnostics"; +import { createServerDiagnostics } from "../../../../domain/server/diagnostics"; +import type { RuntimeConfigSnapshot } from "../../../../domain/runtime/config"; +import type { RateLimitSnapshot, ThreadTokenUsage } from "../../../../domain/runtime/metrics"; +import type { ApprovalsReviewer } from "../../../../domain/runtime/policy"; +import type { RuntimeSettingsPatch } from "../../../../domain/runtime/thread-settings"; +import type { CollaborationMode } from "../../domain/runtime/pending-settings"; import { commitPendingRuntimeSettingsPatchState, clearRequestedApprovalsReviewerRuntimeState, @@ -24,11 +24,11 @@ import { resetReasoningEffortToConfigRuntimeState, setSelectedCollaborationModeRuntimeState, type ChatRuntimeState, -} from "../runtime/state"; -import type { RequestedServiceTier } from "../runtime/pending-settings"; -import type { RequestId } from "../../../app-server/connection/rpc-messages"; -import type { ComposerSuggestion } from "../conversation/composer/suggestions"; -import type { MessageStreamItem } from "../domain/message-stream/model/items"; +} from "../../domain/runtime/state"; +import type { RequestedServiceTier } from "../../domain/runtime/pending-settings"; +import type { RequestId } from "../../../../app-server/connection/rpc-messages"; +import type { ComposerSuggestion } from "../composer/suggestions"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; import type { ActiveThreadResumedAction, ActiveThreadRestoredPlaceholderAction, @@ -62,14 +62,14 @@ import { resolveChatRequest, type ChatRequestState, type RequestAction, -} from "../application/pending-requests/state"; +} from "../pending-requests/state"; import { initialChatTurnState, transitionChatTurnLifecycleState, type ChatTurnState, type PendingTurnStart, -} from "../conversation/turns/turn-state"; -import { STATUS_TURN_RUNNING, turnCompletedStatus } from "../conversation/turns/messages"; +} from "../conversation/turn-state"; +import { STATUS_TURN_RUNNING, turnCompletedStatus } from "../conversation/messages"; export { activeTurnId, @@ -79,7 +79,7 @@ export { type ChatTurnLifecycleState, type ChatTurnState, type PendingTurnStart, -} from "../conversation/turns/turn-state"; +} from "../conversation/turn-state"; export type { ChatMessageStreamState } from "./message-stream"; export type ChatConnectionPhase = @@ -112,7 +112,7 @@ export interface ChatActiveThreadState { tokenUsage: ThreadTokenUsage | null; } -export type { ChatRuntimeState } from "../runtime/state"; +export type { ChatRuntimeState } from "../../domain/runtime/state"; interface ChatComposerState { draft: string; diff --git a/src/features/chat/state/selectors.ts b/src/features/chat/application/state/selectors.ts similarity index 90% rename from src/features/chat/state/selectors.ts rename to src/features/chat/application/state/selectors.ts index 7f89a1a2..b32579cd 100644 --- a/src/features/chat/state/selectors.ts +++ b/src/features/chat/application/state/selectors.ts @@ -7,9 +7,9 @@ import type { ChatTurnState, PendingTurnStart, } from "./reducer"; -import type { Thread } from "../../../domain/threads/model"; -import type { MessageStreamItem } from "../domain/message-stream/model/items"; -import { latestImplementablePlanFromItems } from "../domain/message-stream/queries/selectors"; +import type { Thread } from "../../../../domain/threads/model"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; +import { latestImplementablePlanFromItems } from "../../domain/message-stream/selectors"; import { messageStreamItems, messageStreamIsEmpty } from "./message-stream"; export interface SubmissionStateSnapshot { diff --git a/src/features/chat/threads/auto-title-controller.ts b/src/features/chat/application/threads/auto-title-controller.ts similarity index 89% rename from src/features/chat/threads/auto-title-controller.ts rename to src/features/chat/application/threads/auto-title-controller.ts index c980ed11..aa013120 100644 --- a/src/features/chat/threads/auto-title-controller.ts +++ b/src/features/chat/application/threads/auto-title-controller.ts @@ -1,9 +1,9 @@ -import type { AppServerClient } from "../../../app-server/connection/client"; -import type { Thread } from "../../../domain/threads/model"; -import type { ThreadConversationSummary } from "../../../domain/threads/transcript"; -import type { CodexPanelSettings } from "../../../settings/model"; -import { generateThreadTitleWithCodex } from "../../thread-title/generation"; -import { threadTitleContextFromConversationSummary, type ThreadTitleContext } from "../../thread-title/model"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import type { Thread } from "../../../../domain/threads/model"; +import type { ThreadConversationSummary } from "../../../../domain/threads/transcript"; +import type { CodexPanelSettings } from "../../../../settings/model"; +import { generateThreadTitleWithCodex } from "../../../thread-title/generation"; +import { threadTitleContextFromConversationSummary, type ThreadTitleContext } from "../../../thread-title/model"; import type { ChatAction, ChatState, ChatStateStore } from "../state/reducer"; import { messageStreamItems } from "../state/message-stream"; import { threadTitleContextFromMessageStreamItems } from "./title-context"; diff --git a/src/features/chat/threads/composition.ts b/src/features/chat/application/threads/composition.ts similarity index 94% rename from src/features/chat/threads/composition.ts rename to src/features/chat/application/threads/composition.ts index c295b28c..6799998b 100644 --- a/src/features/chat/threads/composition.ts +++ b/src/features/chat/application/threads/composition.ts @@ -1,6 +1,6 @@ -import type { ConnectionManager } from "../../../app-server/connection/connection-manager"; -import type { AppServerClient } from "../../../app-server/connection/client"; -import type { ArchiveExportAdapter } from "../../thread-export/archive-markdown"; +import type { ConnectionManager } from "../../../../app-server/connection/connection-manager"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import type { ArchiveExportAdapter } from "../../../thread-export/archive-markdown"; import { createGoalActions } from "./goal-actions"; import { createSelectionActions } from "./selection-actions"; import type { ChatResumeWorkTracker, ChatViewDeferredTasks } from "../lifecycle"; diff --git a/src/features/chat/threads/goal-actions.ts b/src/features/chat/application/threads/goal-actions.ts similarity index 93% rename from src/features/chat/threads/goal-actions.ts rename to src/features/chat/application/threads/goal-actions.ts index cdc9a54c..d03b22ee 100644 --- a/src/features/chat/threads/goal-actions.ts +++ b/src/features/chat/application/threads/goal-actions.ts @@ -1,9 +1,9 @@ -import type { AppServerClient } from "../../../app-server/connection/client"; -import { readThreadGoal, recordThreadGoalUserMessage, setThreadGoal } from "../../../app-server/services/thread-goals"; -import type { ThreadGoal, ThreadGoalStatus, ThreadGoalUpdate } from "../../../domain/threads/goal"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import { readThreadGoal, recordThreadGoalUserMessage, setThreadGoal } from "../../../../app-server/services/thread-goals"; +import type { ThreadGoal, ThreadGoalStatus, ThreadGoalUpdate } from "../../../../domain/threads/goal"; import type { ChatStateStore } from "../state/reducer"; -import type { GoalMessageStreamItem } from "../domain/message-stream/model/items"; -import { goalChangeItem } from "../domain/message-stream/factories/goal-items"; +import type { GoalMessageStreamItem } from "../../domain/message-stream/items"; +import { goalChangeItem } from "../../domain/message-stream/factories/goal-items"; import { emptyGoalObjectiveMessage } from "./messages"; export interface GoalActionsHost { diff --git a/src/features/chat/threads/history-controller.ts b/src/features/chat/application/threads/history-controller.ts similarity index 93% rename from src/features/chat/threads/history-controller.ts rename to src/features/chat/application/threads/history-controller.ts index b9458ac5..8306cec4 100644 --- a/src/features/chat/threads/history-controller.ts +++ b/src/features/chat/application/threads/history-controller.ts @@ -1,8 +1,8 @@ -import type { AppServerClient } from "../../../app-server/connection/client"; -import type { TurnItem } from "../../../app-server/protocol/turn"; -import type { ThreadTurnsPage } from "../../../domain/threads/history"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import type { TurnItem } from "../../../../app-server/protocol/turn"; +import type { ThreadTurnsPage } from "../../../../domain/threads/history"; import type { ChatAction, ChatState, ChatStateStore } from "../state/reducer"; -import { messageStreamItemsFromTurns } from "../app-server/mappers/message-stream/turn-items"; +import { messageStreamItemsFromTurns } from "../../app-server/mappers/message-stream/turn-items"; import { messageStreamItems } from "../state/message-stream"; export interface HistoryControllerHost { diff --git a/src/features/chat/threads/identity-sync.ts b/src/features/chat/application/threads/identity-sync.ts similarity index 100% rename from src/features/chat/threads/identity-sync.ts rename to src/features/chat/application/threads/identity-sync.ts diff --git a/src/features/chat/threads/lifecycle-parts.ts b/src/features/chat/application/threads/lifecycle-parts.ts similarity index 95% rename from src/features/chat/threads/lifecycle-parts.ts rename to src/features/chat/application/threads/lifecycle-parts.ts index 2c7fe987..76b8b3b6 100644 --- a/src/features/chat/threads/lifecycle-parts.ts +++ b/src/features/chat/application/threads/lifecycle-parts.ts @@ -1,5 +1,5 @@ -import type { AppServerClient } from "../../../app-server/connection/client"; -import { recoverRolloutTokenUsage } from "../../../app-server/services/rollout-token-usage"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import { recoverRolloutTokenUsage } from "../../../../app-server/services/rollout-token-usage"; import type { ChatResumeWorkTracker, ChatViewDeferredTasks } from "../lifecycle"; import type { ChatStateStore } from "../state/reducer"; import type { CodexChatHost } from "../chat-host"; diff --git a/src/features/chat/threads/messages.ts b/src/features/chat/application/threads/messages.ts similarity index 100% rename from src/features/chat/threads/messages.ts rename to src/features/chat/application/threads/messages.ts diff --git a/src/features/chat/threads/naming-parts.ts b/src/features/chat/application/threads/naming-parts.ts similarity index 90% rename from src/features/chat/threads/naming-parts.ts rename to src/features/chat/application/threads/naming-parts.ts index 1d51cd34..c1f51a19 100644 --- a/src/features/chat/threads/naming-parts.ts +++ b/src/features/chat/application/threads/naming-parts.ts @@ -1,5 +1,5 @@ -import type { ConnectionManager } from "../../../app-server/connection/connection-manager"; -import type { AppServerClient } from "../../../app-server/connection/client"; +import type { ConnectionManager } from "../../../../app-server/connection/connection-manager"; +import type { AppServerClient } from "../../../../app-server/connection/client"; import type { ChatStateStore } from "../state/reducer"; import type { CodexChatHost } from "../chat-host"; import { AutoTitleController } from "./auto-title-controller"; diff --git a/src/features/chat/threads/rename-editor-controller.ts b/src/features/chat/application/threads/rename-editor-controller.ts similarity index 93% rename from src/features/chat/threads/rename-editor-controller.ts rename to src/features/chat/application/threads/rename-editor-controller.ts index f2191d68..5d7b9167 100644 --- a/src/features/chat/threads/rename-editor-controller.ts +++ b/src/features/chat/application/threads/rename-editor-controller.ts @@ -1,10 +1,10 @@ -import type { AppServerClient } from "../../../app-server/connection/client"; -import { readCompletedConversationSummariesPage } from "../../../app-server/services/threads"; -import { getThreadTitle, normalizeExplicitThreadName } from "../../../domain/threads/model"; -import type { Thread } from "../../../domain/threads/model"; -import type { CodexPanelSettings } from "../../../settings/model"; -import { generateThreadTitleWithCodex } from "../../thread-title/generation"; -import { findThreadTitleContext, THREAD_TITLE_CONTEXT_UNAVAILABLE_MESSAGE, type ThreadTitleContext } from "../../thread-title/model"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import { readCompletedConversationSummariesPage } from "../../../../app-server/services/threads"; +import { getThreadTitle, normalizeExplicitThreadName } from "../../../../domain/threads/model"; +import type { Thread } from "../../../../domain/threads/model"; +import type { CodexPanelSettings } from "../../../../settings/model"; +import { generateThreadTitleWithCodex } from "../../../thread-title/generation"; +import { findThreadTitleContext, THREAD_TITLE_CONTEXT_UNAVAILABLE_MESSAGE, type ThreadTitleContext } from "../../../thread-title/model"; import { renameGenerationStillActive, type ChatAction, diff --git a/src/features/chat/threads/restoration-controller.ts b/src/features/chat/application/threads/restoration-controller.ts similarity index 100% rename from src/features/chat/threads/restoration-controller.ts rename to src/features/chat/application/threads/restoration-controller.ts diff --git a/src/features/chat/threads/resume-controller.ts b/src/features/chat/application/threads/resume-controller.ts similarity index 96% rename from src/features/chat/threads/resume-controller.ts rename to src/features/chat/application/threads/resume-controller.ts index 156c018e..29b41f28 100644 --- a/src/features/chat/threads/resume-controller.ts +++ b/src/features/chat/application/threads/resume-controller.ts @@ -1,5 +1,5 @@ -import type { AppServerClient } from "../../../app-server/connection/client"; -import type { ThreadTokenUsage } from "../../../domain/runtime/metrics"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import type { ThreadTokenUsage } from "../../../../domain/runtime/metrics"; import { activeThreadId, canSwitchToThread, listedThreads, messageStreamItemsEmpty } from "../state/selectors"; import type { ChatStateStore } from "../state/reducer"; import type { RestorationController } from "./restoration-controller"; diff --git a/src/features/chat/threads/resume.ts b/src/features/chat/application/threads/resume.ts similarity index 89% rename from src/features/chat/threads/resume.ts rename to src/features/chat/application/threads/resume.ts index e8aefa01..15e66a76 100644 --- a/src/features/chat/threads/resume.ts +++ b/src/features/chat/application/threads/resume.ts @@ -1,11 +1,11 @@ -import { upsertThread } from "../../../domain/threads/model"; -import type { Thread } from "../../../domain/threads/model"; +import { upsertThread } from "../../../../domain/threads/model"; +import type { Thread } from "../../../../domain/threads/model"; import { threadActivationSnapshotFromAppServerResponse, type ThreadActivationSnapshot, -} from "../../../app-server/services/thread-activation"; -import type { ChatRuntimeState } from "../runtime/state"; -import type { MessageStreamItem } from "../domain/message-stream/model/items"; +} from "../../../../app-server/services/thread-activation"; +import type { ChatRuntimeState } from "../../domain/runtime/state"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; import type { ActiveThreadResumedAction } from "../state/actions"; export interface ResumedThreadActionParams { diff --git a/src/features/chat/threads/selection-actions.ts b/src/features/chat/application/threads/selection-actions.ts similarity index 100% rename from src/features/chat/threads/selection-actions.ts rename to src/features/chat/application/threads/selection-actions.ts diff --git a/src/features/chat/threads/thread-management-actions.ts b/src/features/chat/application/threads/thread-management-actions.ts similarity index 96% rename from src/features/chat/threads/thread-management-actions.ts rename to src/features/chat/application/threads/thread-management-actions.ts index bbb3e9b4..778c9016 100644 --- a/src/features/chat/threads/thread-management-actions.ts +++ b/src/features/chat/application/threads/thread-management-actions.ts @@ -1,11 +1,11 @@ import { Notice } from "obsidian"; -import type { AppServerClient } from "../../../app-server/connection/client"; -import { readThreadForArchiveExport, rollbackThread as rollbackThreadOnAppServer } from "../../../app-server/services/threads"; -import { inheritedForkThreadName, normalizeExplicitThreadName } from "../../../domain/threads/model"; -import type { CodexPanelSettings } from "../../../settings/model"; -import type { ArchiveExportAdapter } from "../../thread-export/archive-markdown"; -import { exportArchivedThreadMarkdown } from "../../thread-export/archive-markdown"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import { readThreadForArchiveExport, rollbackThread as rollbackThreadOnAppServer } from "../../../../app-server/services/threads"; +import { inheritedForkThreadName, normalizeExplicitThreadName } from "../../../../domain/threads/model"; +import type { CodexPanelSettings } from "../../../../settings/model"; +import type { ArchiveExportAdapter } from "../../../thread-export/archive-markdown"; +import { exportArchivedThreadMarkdown } from "../../../thread-export/archive-markdown"; import type { CodexChatHost } from "../chat-host"; import { archivedSourceOpenForkFailedMessage, @@ -22,7 +22,7 @@ import { STATUS_ROLLBACK_FAILED, STATUS_ROLLBACK_STARTING, } from "./messages"; -import { messageStreamItemsFromTurns } from "../app-server/mappers/message-stream/turn-items"; +import { messageStreamItemsFromTurns } from "../../app-server/mappers/message-stream/turn-items"; import { messageStreamRollbackCandidate, messageStreamTurnsAfterTurnId } from "../state/message-stream"; import { chatTurnBusy, type ChatAction, type ChatState, type ChatStateStore } from "../state/reducer"; import { resumedThreadActionFromActiveRuntime } from "./resume"; diff --git a/src/features/chat/threads/title-context.ts b/src/features/chat/application/threads/title-context.ts similarity index 89% rename from src/features/chat/threads/title-context.ts rename to src/features/chat/application/threads/title-context.ts index a357edef..5d489956 100644 --- a/src/features/chat/threads/title-context.ts +++ b/src/features/chat/application/threads/title-context.ts @@ -1,7 +1,7 @@ -import type { ThreadTitleContext } from "../../thread-title/model"; -import { truncate } from "../../../utils"; -import { isCompletedTurnOutcomeMessage } from "../domain/message-stream/queries/selectors"; -import type { MessageStreamItem, MessageStreamMessageItem } from "../domain/message-stream/model/items"; +import type { ThreadTitleContext } from "../../../thread-title/model"; +import { truncate } from "../../../../utils"; +import { isCompletedTurnOutcomeMessage } from "../../domain/message-stream/selectors"; +import type { MessageStreamItem, MessageStreamMessageItem } from "../../domain/message-stream/items"; const MAX_CONTEXT_CHARS = 4_000; diff --git a/src/features/chat/threads/title-display.ts b/src/features/chat/application/threads/title-display.ts similarity index 76% rename from src/features/chat/threads/title-display.ts rename to src/features/chat/application/threads/title-display.ts index 0bf21f2b..214af5b0 100644 --- a/src/features/chat/threads/title-display.ts +++ b/src/features/chat/application/threads/title-display.ts @@ -1,5 +1,5 @@ -import { getThreadTitle, type Thread } from "../../../domain/threads/model"; -import { shortThreadId } from "../../../utils"; +import { getThreadTitle, type Thread } from "../../../../domain/threads/model"; +import { shortThreadId } from "../../../../utils"; export function codexPanelDisplayTitle(activeThreadId: string | null, threads: readonly Thread[], fallbackTitle?: string | null): string { if (!activeThreadId) return "Codex"; diff --git a/src/features/chat/domain/message-stream/agent-state.ts b/src/features/chat/domain/message-stream/agent-state.ts new file mode 100644 index 00000000..f793b3a7 --- /dev/null +++ b/src/features/chat/domain/message-stream/agent-state.ts @@ -0,0 +1,20 @@ +import type { ExecutionState } from "./items"; + +type MessageStreamExecutionState = Exclude; +type ExecutionStateByStatus = Readonly>; + +const AGENT_STATES: ExecutionStateByStatus = { + pendingInit: "running", + running: "running", + inProgress: "running", + completed: "completed", + shutdown: "completed", + interrupted: "failed", + errored: "failed", + notFound: "failed", + failed: "failed", +}; + +export function collabAgentStateExecutionState(status: string): ExecutionState { + return AGENT_STATES[status] ?? null; +} diff --git a/src/features/chat/domain/message-stream/factories/goal-items.ts b/src/features/chat/domain/message-stream/factories/goal-items.ts index b97a8c8c..605d7ddc 100644 --- a/src/features/chat/domain/message-stream/factories/goal-items.ts +++ b/src/features/chat/domain/message-stream/factories/goal-items.ts @@ -1,6 +1,6 @@ import type { ThreadGoal, ThreadGoalStatus } from "../../../../../domain/threads/goal"; import { truncate } from "../../../../../utils"; -import type { GoalMessageStreamItem } from "../model/items"; +import type { GoalMessageStreamItem } from "../items"; const GOAL_SUMMARY_LIMIT = 140; diff --git a/src/features/chat/domain/message-stream/factories/streaming-items.ts b/src/features/chat/domain/message-stream/factories/streaming-items.ts index b6b483c9..9a7f7b44 100644 --- a/src/features/chat/domain/message-stream/factories/streaming-items.ts +++ b/src/features/chat/domain/message-stream/factories/streaming-items.ts @@ -1,6 +1,4 @@ -import type { FileUpdateChange } from "../../../../../app-server/protocol/file-change"; -import type { MessageStreamItem, MessageStreamItemKind } from "../model/items"; -import { normalizeFileChanges } from "../../../app-server/mappers/message-stream/turn-items"; +import type { MessageStreamItem, MessageStreamItemKind } from "../items"; export const STREAMED_COMMAND_RUNNING_TEXT = "Command running"; export const STREAMED_FILE_CHANGE_IN_PROGRESS_TEXT = "File change inProgress"; @@ -74,21 +72,3 @@ export function streamedItemOutputMessageStreamItem(params: { }), } as MessageStreamItem; } - -export function streamingFileChangeMessageStreamItem( - itemId: string, - turnId: string, - changes: FileUpdateChange[], - status: string, -): MessageStreamItem { - return { - id: itemId, - kind: "fileChange", - role: "tool", - turnId, - sourceItemId: itemId, - provenance: { source: "appServer", channel: "notification", event: "streamingDelta", sourceItemId: itemId }, - status, - changes: normalizeFileChanges(changes), - }; -} diff --git a/src/features/chat/domain/message-stream/factories/system-items.ts b/src/features/chat/domain/message-stream/factories/system-items.ts index 9d27cf51..623cf596 100644 --- a/src/features/chat/domain/message-stream/factories/system-items.ts +++ b/src/features/chat/domain/message-stream/factories/system-items.ts @@ -1,4 +1,4 @@ -import type { MessageStreamItem, MessageStreamNoticeSection } from "../model/items"; +import type { MessageStreamItem, MessageStreamNoticeSection } from "../items"; export function createSystemItem(id: string, text: string): MessageStreamItem { return { diff --git a/src/features/chat/domain/message-stream/factories/task-progress.ts b/src/features/chat/domain/message-stream/factories/task-progress.ts index 81f65857..7bbed21d 100644 --- a/src/features/chat/domain/message-stream/factories/task-progress.ts +++ b/src/features/chat/domain/message-stream/factories/task-progress.ts @@ -1,4 +1,4 @@ -import type { ExecutionState, MessageStreamItem } from "../model/items"; +import type { ExecutionState, MessageStreamItem } from "../items"; type MessageStreamExecutionState = Exclude; type ExecutionStateByStatus = Readonly>; diff --git a/src/features/chat/domain/message-stream/format/file-mentions.ts b/src/features/chat/domain/message-stream/format/file-mentions.ts index 090007d7..64f52b3a 100644 --- a/src/features/chat/domain/message-stream/format/file-mentions.ts +++ b/src/features/chat/domain/message-stream/format/file-mentions.ts @@ -1,5 +1,5 @@ import type { CodexInputItem } from "../../../../../domain/chat/input"; -import type { MessageStreamFileMention } from "../model/items"; +import type { MessageStreamFileMention } from "../items"; export function fileMentionsFromInput(input: readonly CodexInputItem[]): MessageStreamFileMention[] { const seen = new Set(); diff --git a/src/features/chat/domain/message-stream/model/items.ts b/src/features/chat/domain/message-stream/items.ts similarity index 98% rename from src/features/chat/domain/message-stream/model/items.ts rename to src/features/chat/domain/message-stream/items.ts index fef0c087..0a71a924 100644 --- a/src/features/chat/domain/message-stream/model/items.ts +++ b/src/features/chat/domain/message-stream/items.ts @@ -1,4 +1,4 @@ -import type { ReferencedThreadMetadata } from "../../../../../domain/threads/reference"; +import type { ReferencedThreadMetadata } from "../../../../domain/threads/reference"; import type { MessageStreamItemProvenance } from "./provenance"; export type MessageStreamItemKind = diff --git a/src/features/chat/domain/message-stream/model/provenance.ts b/src/features/chat/domain/message-stream/provenance.ts similarity index 100% rename from src/features/chat/domain/message-stream/model/provenance.ts rename to src/features/chat/domain/message-stream/provenance.ts diff --git a/src/features/chat/domain/message-stream/queries/selectors.ts b/src/features/chat/domain/message-stream/selectors.ts similarity index 97% rename from src/features/chat/domain/message-stream/queries/selectors.ts rename to src/features/chat/domain/message-stream/selectors.ts index 11fceced..79a3e6bb 100644 --- a/src/features/chat/domain/message-stream/queries/selectors.ts +++ b/src/features/chat/domain/message-stream/selectors.ts @@ -1,5 +1,5 @@ -import type { AssistantAuthoredMessageStreamItem, MessageStreamItem } from "../model/items"; -import { messageStreamIsProposedPlan, messageStreamSemanticClassifications } from "../semantics"; +import type { AssistantAuthoredMessageStreamItem, MessageStreamItem } from "./items"; +import { messageStreamIsProposedPlan, messageStreamSemanticClassifications } from "./semantics"; export interface ForkCandidate { itemId: string; diff --git a/src/features/chat/domain/message-stream/semantics/classify.ts b/src/features/chat/domain/message-stream/semantics/classify.ts index 090b3e36..d276dde5 100644 --- a/src/features/chat/domain/message-stream/semantics/classify.ts +++ b/src/features/chat/domain/message-stream/semantics/classify.ts @@ -1,4 +1,4 @@ -import type { MessageStreamItem } from "../model/items"; +import type { MessageStreamItem } from "../items"; import type { MessageStreamLifecycle, MessageStreamMeaning, diff --git a/src/features/chat/domain/message-stream/semantics/types.ts b/src/features/chat/domain/message-stream/semantics/types.ts index d5911cf3..c6fa89ce 100644 --- a/src/features/chat/domain/message-stream/semantics/types.ts +++ b/src/features/chat/domain/message-stream/semantics/types.ts @@ -1,5 +1,5 @@ -import type { ExecutionState, MessageStreamItem } from "../model/items"; -import type { MessageStreamItemProvenance } from "../model/provenance"; +import type { ExecutionState, MessageStreamItem } from "../items"; +import type { MessageStreamItemProvenance } from "../provenance"; type MessageStreamTurnRole = "initiator" | "steer" | "detail" | "outcome"; diff --git a/src/features/chat/domain/message-stream/operations/updates.ts b/src/features/chat/domain/message-stream/updates.ts similarity index 96% rename from src/features/chat/domain/message-stream/operations/updates.ts rename to src/features/chat/domain/message-stream/updates.ts index 1824e223..535e59e4 100644 --- a/src/features/chat/domain/message-stream/operations/updates.ts +++ b/src/features/chat/domain/message-stream/updates.ts @@ -1,12 +1,12 @@ -import { normalizeProposedPlanMarkdown } from "../format/proposed-plan"; -import { isAssistantAuthoredMessage } from "../queries/selectors"; -import { messageStreamIsTurnInitiator, messageStreamSemanticClassifications } from "../semantics"; +import { normalizeProposedPlanMarkdown } from "./format/proposed-plan"; +import { isAssistantAuthoredMessage } from "./selectors"; +import { messageStreamIsTurnInitiator, messageStreamSemanticClassifications } from "./semantics"; import { streamedItemOutputMessageStreamItem, streamedTextMessageStreamItem, streamedToolOutputMessageStreamItem, -} from "../factories/streaming-items"; -import type { AssistantAuthoredMessageStreamItem, MessageStreamFileChange, MessageStreamItem, MessageStreamItemKind } from "../model/items"; +} from "./factories/streaming-items"; +import type { AssistantAuthoredMessageStreamItem, MessageStreamFileChange, MessageStreamItem, MessageStreamItemKind } from "./items"; export function upsertMessageStreamItemById(items: readonly MessageStreamItem[], next: MessageStreamItem): MessageStreamItem[] { const index = items.findIndex((item) => item.id === next.id); diff --git a/src/features/chat/domain/pending-requests/result-items.ts b/src/features/chat/domain/pending-requests/result-items.ts index a491d068..3cbdd2b2 100644 --- a/src/features/chat/domain/pending-requests/result-items.ts +++ b/src/features/chat/domain/pending-requests/result-items.ts @@ -1,6 +1,6 @@ import { approvalActionKind, type ApprovalAction, type PendingApproval, type PendingUserInput } from "./model"; import { approvalDetails, approvalResultSummary, approvalTitle } from "./approval"; -import type { MessageStreamItem } from "../message-stream/model/items"; +import type { MessageStreamItem } from "../message-stream/items"; import { definedProp } from "../../../../utils"; export function createApprovalResultItem(approval: PendingApproval, action: ApprovalAction): MessageStreamItem { diff --git a/src/features/chat/runtime/effective.ts b/src/features/chat/domain/runtime/effective.ts similarity index 95% rename from src/features/chat/runtime/effective.ts rename to src/features/chat/domain/runtime/effective.ts index 1208edd7..0309b52b 100644 --- a/src/features/chat/runtime/effective.ts +++ b/src/features/chat/domain/runtime/effective.ts @@ -1,7 +1,7 @@ -import { cloneRuntimeConfigSnapshot, emptyRuntimeConfigSnapshot, type RuntimeConfigSnapshot } from "../../../domain/runtime/config"; -import { findModelMetadataByIdOrName, type ModelMetadata } from "../../../domain/catalog/metadata"; -import type { ApprovalPolicy, ApprovalsReviewer } from "../../../domain/runtime/policy"; -import { supportedEffortsForModelMetadata, type ReasoningEffort } from "../../../domain/catalog/metadata"; +import { cloneRuntimeConfigSnapshot, emptyRuntimeConfigSnapshot, type RuntimeConfigSnapshot } from "../../../../domain/runtime/config"; +import { findModelMetadataByIdOrName, type ModelMetadata } from "../../../../domain/catalog/metadata"; +import type { ApprovalPolicy, ApprovalsReviewer } from "../../../../domain/runtime/policy"; +import { supportedEffortsForModelMetadata, type ReasoningEffort } from "../../../../domain/catalog/metadata"; import type { RuntimeSnapshot } from "./snapshot"; export function runtimeConfigOrDefault(runtimeConfig: RuntimeConfigSnapshot | null): RuntimeConfigSnapshot { diff --git a/src/features/chat/runtime/pending-settings.ts b/src/features/chat/domain/runtime/pending-settings.ts similarity index 100% rename from src/features/chat/runtime/pending-settings.ts rename to src/features/chat/domain/runtime/pending-settings.ts diff --git a/src/features/chat/domain/runtime/snapshot.ts b/src/features/chat/domain/runtime/snapshot.ts new file mode 100644 index 00000000..281120a7 --- /dev/null +++ b/src/features/chat/domain/runtime/snapshot.ts @@ -0,0 +1,26 @@ +import type { ModelMetadata, ReasoningEffort } from "../../../../domain/catalog/metadata"; +import type { RuntimeConfigSnapshot } from "../../../../domain/runtime/config"; +import type { RateLimitSnapshot, ThreadTokenUsage } from "../../../../domain/runtime/metrics"; +import type { ActivePermissionProfile, ApprovalPolicy, ApprovalsReviewer, ServiceTier } from "../../../../domain/runtime/policy"; +import type { ActiveCollaborationMode, CollaborationMode, PendingRuntimeSetting, RequestedServiceTier } from "./pending-settings"; + +export interface RuntimeSnapshot { + runtimeConfig: RuntimeConfigSnapshot | null; + activeThreadId: string | null; + activeModel: string | null; + activeReasoningEffort: ReasoningEffort | null; + activeCollaborationMode: ActiveCollaborationMode; + activeServiceTier: ServiceTier | null; + activeApprovalPolicy: ApprovalPolicy | null; + activeApprovalsReviewer: ApprovalsReviewer | null; + activePermissionProfile: ActivePermissionProfile | null; + requestedModel: PendingRuntimeSetting; + requestedReasoningEffort: PendingRuntimeSetting; + requestedApprovalsReviewer: PendingRuntimeSetting; + selectedCollaborationMode: CollaborationMode; + requestedServiceTier: PendingRuntimeSetting; + tokenUsage: ThreadTokenUsage | null; + rateLimit: RateLimitSnapshot | null; + hasThreadTurns: boolean; + availableModels: readonly ModelMetadata[]; +} diff --git a/src/features/chat/runtime/state.ts b/src/features/chat/domain/runtime/state.ts similarity index 96% rename from src/features/chat/runtime/state.ts rename to src/features/chat/domain/runtime/state.ts index 810265b9..e942b96f 100644 --- a/src/features/chat/runtime/state.ts +++ b/src/features/chat/domain/runtime/state.ts @@ -4,9 +4,9 @@ import { type ApprovalPolicy, type ApprovalsReviewer, type ServiceTier, -} from "../../../domain/runtime/policy"; -import type { RuntimeSettingsPatch } from "../../../domain/runtime/thread-settings"; -import { normalizeReasoningEffort, type ReasoningEffort } from "../../../domain/catalog/metadata"; +} from "../../../../domain/runtime/policy"; +import type { RuntimeSettingsPatch } from "../../../../domain/runtime/thread-settings"; +import { normalizeReasoningEffort, type ReasoningEffort } from "../../../../domain/catalog/metadata"; import { resetRuntimeSettingToConfig, setPendingRuntimeSetting, diff --git a/src/features/chat/domain/runtime/warnings.ts b/src/features/chat/domain/runtime/warnings.ts new file mode 100644 index 00000000..3b6c9981 --- /dev/null +++ b/src/features/chat/domain/runtime/warnings.ts @@ -0,0 +1 @@ +export type TurnCollaborationModeWarning = "missing-model"; diff --git a/src/features/chat/turn-diff/model.ts b/src/features/chat/domain/turn-diff.ts similarity index 100% rename from src/features/chat/turn-diff/model.ts rename to src/features/chat/domain/turn-diff.ts diff --git a/src/features/chat/conversation/composer/composition.ts b/src/features/chat/host/composer.ts similarity index 75% rename from src/features/chat/conversation/composer/composition.ts rename to src/features/chat/host/composer.ts index 61ddf6a7..0390581d 100644 --- a/src/features/chat/conversation/composer/composition.ts +++ b/src/features/chat/host/composer.ts @@ -1,15 +1,15 @@ import type { App } from "obsidian"; -import type { CodexInput } from "../../../../domain/chat/input"; -import { MessageStreamScrollBridge } from "../../panel/surface/message-stream-scroll"; -import { currentModel, runtimeConfigOrDefault } from "../../runtime/effective"; -import { runtimeSnapshotForChatState } from "../../runtime/snapshot"; -import { activeTurnId, type ChatStateStore } from "../../state/reducer"; -import type { ComposerMetaViewModel } from "../../ui/composer"; -import type { ChatPanelComposerShellState } from "../../ui/shell-state"; -import type { CodexChatHost } from "../../chat-host"; -import type { ChatRuntimeSettingsActions } from "../../runtime/settings-actions"; -import { ChatComposerController } from "./controller"; +import type { CodexInput } from "../../../domain/chat/input"; +import { MessageStreamScrollBridge } from "../panel/surface/message-stream-scroll"; +import { currentModel, runtimeConfigOrDefault } from "../domain/runtime/effective"; +import { runtimeSnapshotForChatState } from "../application/runtime/snapshot"; +import { activeTurnId, type ChatStateStore } from "../application/state/reducer"; +import type { ComposerMetaViewModel } from "../ui/composer"; +import type { ChatPanelComposerShellState } from "../ui/shell-state"; +import type { CodexChatHost } from "../application/chat-host"; +import type { ChatRuntimeSettingsActions } from "../application/runtime/settings-actions"; +import { ChatComposerController } from "../ui/composer-controller"; export interface ConversationComposerContext { app: App; diff --git a/src/features/chat/conversation/composition.ts b/src/features/chat/host/conversation.ts similarity index 86% rename from src/features/chat/conversation/composition.ts rename to src/features/chat/host/conversation.ts index cc012f8b..427dc3b7 100644 --- a/src/features/chat/conversation/composition.ts +++ b/src/features/chat/host/conversation.ts @@ -1,22 +1,22 @@ import type { App, Component } from "obsidian"; import type { AppServerClient } from "../../../app-server/connection/client"; -import type { ChatServerThreadActions } from "../connection/server-actions/threads"; -import { type ChatStateStore } from "../state/reducer"; -import type { ChatReconnectActions } from "../connection/reconnect-actions"; +import type { ChatServerThreadActions } from "../app-server/actions/threads"; +import { type ChatStateStore } from "../application/state/reducer"; +import type { ChatReconnectActions } from "../application/connection/reconnect-actions"; import { PendingRequestController } from "../application/pending-requests/controller"; -import type { ChatRuntimeSettingsActions } from "../runtime/settings-actions"; -import type { ThreadManagementActions } from "../threads/thread-management-actions"; -import type { GoalActions } from "../threads/goal-actions"; -import type { HistoryController } from "../threads/history-controller"; +import type { ChatRuntimeSettingsActions } from "../application/runtime/settings-actions"; +import type { ThreadManagementActions } from "../application/threads/thread-management-actions"; +import type { GoalActions } from "../application/threads/goal-actions"; +import type { HistoryController } from "../application/threads/history-controller"; import type { ChatInboundController } from "../app-server/inbound/controller"; -import type { MessageStreamItem, MessageStreamNoticeSection } from "../domain/message-stream/model/items"; +import type { MessageStreamItem, MessageStreamNoticeSection } from "../domain/message-stream/items"; import type { ChatMessageScrollIntentState } from "../ui/message-stream/scroll-intent-state"; import type { ComposerMetaViewModel } from "../ui/composer"; import type { ChatPanelComposerShellState } from "../ui/shell-state"; -import type { CodexChatHost } from "../chat-host"; +import type { CodexChatHost } from "../application/chat-host"; import { MessageStreamPresenter } from "../panel/surface/message-stream-presenter"; -import { createConversationComposer } from "./composer/composition"; -import { createConversationTurnActions } from "./turns/composition"; +import { createConversationComposer } from "./composer"; +import { createConversationTurnActions } from "../application/conversation/composition"; interface ConversationPartsContext { obsidian: { diff --git a/src/features/chat/host/lifecycle.ts b/src/features/chat/host/lifecycle.ts new file mode 100644 index 00000000..e9362d76 --- /dev/null +++ b/src/features/chat/host/lifecycle.ts @@ -0,0 +1,40 @@ +import { DeferredTask, type DeferredTaskWindow } from "../../../shared/lifecycle/deferred-task"; +import type { ChatViewDeferredTasks } from "../application/lifecycle"; + +export function createChatViewDeferredTasks(getWindow: () => DeferredTaskWindow): ChatViewDeferredTasks { + const diagnosticsTask = new DeferredTask(getWindow, 1_000); + const restoredThreadHydrationTask = new DeferredTask(getWindow, 1_500); + const appServerWarmupTask = new DeferredTask(getWindow, 0); + + return { + scheduleDiagnostics(callback): void { + diagnosticsTask.schedule(callback); + }, + + clearDiagnostics(): void { + diagnosticsTask.clear(); + }, + + scheduleRestoredThreadHydration(callback): void { + restoredThreadHydrationTask.schedule(callback); + }, + + clearRestoredThreadHydration(): void { + restoredThreadHydrationTask.clear(); + }, + + scheduleAppServerWarmup(callback): void { + appServerWarmupTask.schedule(callback); + }, + + clearAppServerWarmup(): void { + appServerWarmupTask.clear(); + }, + + clearAll(): void { + restoredThreadHydrationTask.clear(); + appServerWarmupTask.clear(); + diagnosticsTask.clear(); + }, + }; +} diff --git a/src/features/chat/session.ts b/src/features/chat/host/session.ts similarity index 89% rename from src/features/chat/session.ts rename to src/features/chat/host/session.ts index f6f49ba6..003c4aa0 100644 --- a/src/features/chat/session.ts +++ b/src/features/chat/host/session.ts @@ -1,51 +1,51 @@ import { Notice, type App, type Component, type EventRef } from "obsidian"; -import { ConnectionManager, type ConnectionManagerHandlers } from "../../app-server/connection/connection-manager"; -import type { AppServerClient } from "../../app-server/connection/client"; -import type { ModelMetadata } from "../../domain/catalog/metadata"; -import type { Thread } from "../../domain/threads/model"; -import { getThreadTitle } from "../../domain/threads/model"; -import type { SharedServerMetadata } from "../../domain/server/metadata"; -import type { OpenCodexPanelSnapshot } from "../../workspace/open-panel-snapshot"; -import type { ArchiveExportAdapter } from "../thread-export/archive-markdown"; -import type { CodexChatHost } from "./chat-host"; -import { scheduleAppServerWarmup } from "./connection/app-server-warmup"; -import { ChatConnectionController } from "./connection/connection-controller"; -import { createChatReconnectActions } from "./connection/reconnect-actions"; -import { createChatServerDiagnosticsActions, type ChatServerDiagnosticsActions } from "./connection/server-actions/diagnostics"; -import { createChatServerMetadataActions, type ChatServerMetadataActions } from "./connection/server-actions/metadata"; -import { createChatServerThreadActions, type ChatServerThreadActions } from "./connection/server-actions/threads"; -import type { ChatComposerController } from "./conversation/composer/controller"; -import { createConversationParts } from "./conversation/composition"; -import type { ComposerSubmitActions } from "./conversation/turns/composer-submit-actions"; -import { codexPanelDisplayTitle } from "./threads/title-display"; -import type { MessageStreamItem, MessageStreamNoticeSection } from "./domain/message-stream/model/items"; -import { createStructuredSystemItem, createSystemItem } from "./domain/message-stream/factories/system-items"; +import { ConnectionManager, type ConnectionManagerHandlers } from "../../../app-server/connection/connection-manager"; +import type { AppServerClient } from "../../../app-server/connection/client"; +import type { ModelMetadata } from "../../../domain/catalog/metadata"; +import type { Thread } from "../../../domain/threads/model"; +import { getThreadTitle } from "../../../domain/threads/model"; +import type { SharedServerMetadata } from "../../../domain/server/metadata"; +import type { OpenCodexPanelSnapshot } from "../../../workspace/open-panel-snapshot"; +import type { ArchiveExportAdapter } from "../../thread-export/archive-markdown"; +import type { CodexChatHost } from "../application/chat-host"; +import { scheduleAppServerWarmup } from "../application/connection/app-server-warmup"; +import { ChatConnectionController } from "../application/connection/connection-controller"; +import { createChatReconnectActions } from "../application/connection/reconnect-actions"; +import { createChatServerDiagnosticsActions, type ChatServerDiagnosticsActions } from "../app-server/actions/diagnostics"; +import { createChatServerMetadataActions, type ChatServerMetadataActions } from "../app-server/actions/metadata"; +import { createChatServerThreadActions, type ChatServerThreadActions } from "../app-server/actions/threads"; +import type { ChatComposerController } from "../ui/composer-controller"; +import { createConversationParts } from "./conversation"; +import type { ComposerSubmitActions } from "../application/conversation/composer-submit-actions"; +import { codexPanelDisplayTitle } from "../application/threads/title-display"; +import type { MessageStreamItem, MessageStreamNoticeSection } from "../domain/message-stream/items"; +import { createStructuredSystemItem, createSystemItem } from "../domain/message-stream/factories/system-items"; import { effortStatusLines as buildEffortStatusLines, modelStatusLines as buildModelStatusLines, statusSummaryLines as buildStatusSummaryLines, -} from "./runtime/status"; +} from "../presentation/runtime/status"; +import { createChatViewDeferredTasks } from "./lifecycle"; import { ChatConnectionWorkTracker, ChatResumeWorkTracker, - createChatViewDeferredTasks, type ChatViewDeferredTasks, type RestoredThreadState, -} from "./lifecycle"; -import { applyChatViewState } from "./panel/view-state"; -import { closeChatView, openChatView, type ChatViewLifecycleHost } from "./panel/view-lifecycle"; -import { createToolbarPanelActions, type ToolbarPanelActions } from "./panel/toolbar-actions"; -import { connectionDiagnosticsModel } from "./panel/surface/toolbar"; -import { openPanelTurnLifecycle } from "./panel/snapshot"; -import { ChatInboundController } from "./app-server/inbound/controller"; -import { rejectServerRequest, respondToServerRequest } from "./app-server/requests/responder"; -import { collaborationModeLabel as formatCollaborationModeLabel } from "./runtime/messages"; -import { createChatRuntimeSettingsActions } from "./runtime/settings-actions"; -import { runtimeSnapshotForChatState, type RuntimeSnapshot } from "./runtime/snapshot"; -import { chatPanelComposerProjection } from "./panel/surface/composer"; -import { createChatMessageScrollIntentState, type ChatMessageScrollIntentState } from "./ui/message-stream/scroll-intent-state"; -import { renderChatPanelShell } from "./ui/shell"; +} from "../application/lifecycle"; +import { applyChatViewState } from "../panel/view-state"; +import { closeChatView, openChatView, type ChatViewLifecycleHost } from "../panel/view-lifecycle"; +import { createToolbarPanelActions, type ToolbarPanelActions } from "../panel/toolbar-actions"; +import { connectionDiagnosticsModel } from "../panel/surface/toolbar"; +import { openPanelTurnLifecycle } from "../panel/snapshot"; +import { ChatInboundController } from "../app-server/inbound/controller"; +import { rejectServerRequest, respondToServerRequest } from "../app-server/requests/responder"; +import { collaborationModeLabel as formatCollaborationModeLabel } from "../presentation/runtime/messages"; +import { createChatRuntimeSettingsActions } from "../application/runtime/settings-actions"; +import { runtimeSnapshotForChatState, type RuntimeSnapshot } from "../application/runtime/snapshot"; +import { chatPanelComposerProjection } from "../panel/surface/composer"; +import { createChatMessageScrollIntentState, type ChatMessageScrollIntentState } from "../ui/message-stream/scroll-intent-state"; +import { renderChatPanelShell } from "../ui/shell"; import { chatTurnBusy, createChatStateStore, @@ -53,20 +53,20 @@ import { type ChatConnectionPhase, type ChatState, type ChatStateStore, -} from "./state/reducer"; -import type { GoalActions } from "./threads/goal-actions"; -import type { AutoTitleController } from "./threads/auto-title-controller"; -import type { HistoryController } from "./threads/history-controller"; -import type { IdentitySync } from "./threads/identity-sync"; -import type { ThreadRenameEditorController } from "./threads/rename-editor-controller"; -import type { RestorationController } from "./threads/restoration-controller"; -import type { ResumeController } from "./threads/resume-controller"; -import type { SelectionActions } from "./threads/selection-actions"; -import { createThreadParts, createThreadSelectionActions } from "./threads/composition"; -import type { MessageStreamPresenter } from "./panel/surface/message-stream-presenter"; -import { pendingRequestsSignature } from "./domain/pending-requests/signatures"; -import { createChatPanelSurface } from "./panel/surface/create-surface"; -import type { ChatPanelSurface } from "./panel/surface/model"; +} from "../application/state/reducer"; +import type { GoalActions } from "../application/threads/goal-actions"; +import type { AutoTitleController } from "../application/threads/auto-title-controller"; +import type { HistoryController } from "../application/threads/history-controller"; +import type { IdentitySync } from "../application/threads/identity-sync"; +import type { ThreadRenameEditorController } from "../application/threads/rename-editor-controller"; +import type { RestorationController } from "../application/threads/restoration-controller"; +import type { ResumeController } from "../application/threads/resume-controller"; +import type { SelectionActions } from "../application/threads/selection-actions"; +import { createThreadParts, createThreadSelectionActions } from "../application/threads/composition"; +import type { MessageStreamPresenter } from "../panel/surface/message-stream-presenter"; +import { pendingRequestsSignature } from "../domain/pending-requests/signatures"; +import { createChatPanelSurface } from "../panel/surface/create-surface"; +import type { ChatPanelSurface } from "../panel/surface/model"; export interface ChatPanelEnvironment { obsidian: { diff --git a/src/features/chat/view.ts b/src/features/chat/host/view.ts similarity index 89% rename from src/features/chat/view.ts rename to src/features/chat/host/view.ts index 978f1ee6..485bda65 100644 --- a/src/features/chat/view.ts +++ b/src/features/chat/host/view.ts @@ -1,11 +1,11 @@ import { ItemView, type ViewStateResult, type WorkspaceLeaf } from "obsidian"; -import { VIEW_TYPE_CODEX_PANEL } from "../../constants"; -import type { ModelMetadata } from "../../domain/catalog/metadata"; -import type { Thread } from "../../domain/threads/model"; -import type { OpenCodexPanelSnapshot } from "../../workspace/open-panel-snapshot"; -import type { SharedServerMetadata } from "../../domain/server/metadata"; -import type { CodexChatHost } from "./chat-host"; +import { VIEW_TYPE_CODEX_PANEL } from "../../../constants"; +import type { ModelMetadata } from "../../../domain/catalog/metadata"; +import type { Thread } from "../../../domain/threads/model"; +import type { OpenCodexPanelSnapshot } from "../../../workspace/open-panel-snapshot"; +import type { SharedServerMetadata } from "../../../domain/server/metadata"; +import type { CodexChatHost } from "../application/chat-host"; import { ChatPanelSession } from "./session"; export class CodexChatView extends ItemView { diff --git a/src/features/chat/panel/snapshot.ts b/src/features/chat/panel/snapshot.ts index 53bc35a6..0dddaa3a 100644 --- a/src/features/chat/panel/snapshot.ts +++ b/src/features/chat/panel/snapshot.ts @@ -1,8 +1,8 @@ import type { OpenCodexPanelSnapshot } from "../../../workspace/open-panel-snapshot"; -import type { ChatState } from "../state/reducer"; -import type { MessageStreamItem } from "../domain/message-stream/model/items"; -import { latestProposedPlanFromItems } from "../domain/message-stream/queries/selectors"; -import type { RestoredThreadState } from "../lifecycle"; +import type { ChatState } from "../application/state/reducer"; +import type { MessageStreamItem } from "../domain/message-stream/items"; +import { latestProposedPlanFromItems } from "../domain/message-stream/selectors"; +import type { RestoredThreadState } from "../application/lifecycle"; export function openPanelTurnLifecycle(state: ChatState["turn"]["lifecycle"]): OpenCodexPanelSnapshot["turnLifecycle"] { if (state.kind === "running") return { kind: "running", turnId: state.turnId }; diff --git a/src/features/chat/panel/surface/composer.ts b/src/features/chat/panel/surface/composer.ts index 2d5b5304..8845f887 100644 --- a/src/features/chat/panel/surface/composer.ts +++ b/src/features/chat/panel/surface/composer.ts @@ -8,13 +8,13 @@ import { fastModeActive, runtimeConfigOrDefault, supportedReasoningEfforts, -} from "../../runtime/effective"; -import { contextSummary } from "../../runtime/status"; -import { compactReasoningEffortLabel } from "../../runtime/messages"; +} from "../../domain/runtime/effective"; +import { contextSummary } from "../../presentation/runtime/status"; +import { compactReasoningEffortLabel } from "../../presentation/runtime/messages"; import { sortedModelMetadata } from "../../../../domain/catalog/metadata"; import type { ReasoningEffort } from "../../../../domain/catalog/metadata"; -import type { RuntimeSnapshot } from "../../runtime/snapshot"; -import type { ChatState } from "../../state/reducer"; +import type { RuntimeSnapshot } from "../../application/runtime/snapshot"; +import type { ChatState } from "../../application/state/reducer"; import type { ComposerContextMeterCellViewModel, ComposerContextMeterViewModel, diff --git a/src/features/chat/panel/surface/create-surface.ts b/src/features/chat/panel/surface/create-surface.ts index 8879c011..ba07ee37 100644 --- a/src/features/chat/panel/surface/create-surface.ts +++ b/src/features/chat/panel/surface/create-surface.ts @@ -1,16 +1,16 @@ import type { CodexPanelSettings } from "../../../../settings/model"; import type { ConnectionManager } from "../../../../app-server/connection/connection-manager"; -import type { ChatStateStore } from "../../state/reducer"; -import type { ChatConnectionController } from "../../connection/connection-controller"; -import type { ChatReconnectActions } from "../../connection/reconnect-actions"; +import type { ChatStateStore } from "../../application/state/reducer"; +import type { ChatConnectionController } from "../../application/connection/connection-controller"; +import type { ChatReconnectActions } from "../../application/connection/reconnect-actions"; import type { ChatInboundController } from "../../app-server/inbound/controller"; -import type { ChatServerThreadActions } from "../../connection/server-actions/threads"; -import type { ThreadManagementActions } from "../../threads/thread-management-actions"; +import type { ChatServerThreadActions } from "../../app-server/actions/threads"; +import type { ThreadManagementActions } from "../../application/threads/thread-management-actions"; import type { ToolbarPanelActions } from "../toolbar-actions"; -import type { ThreadRenameEditorController } from "../../threads/rename-editor-controller"; -import type { SelectionActions } from "../../threads/selection-actions"; -import type { ChatRuntimeSettingsActions } from "../../runtime/settings-actions"; -import type { GoalActions } from "../../threads/goal-actions"; +import type { ThreadRenameEditorController } from "../../application/threads/rename-editor-controller"; +import type { SelectionActions } from "../../application/threads/selection-actions"; +import type { ChatRuntimeSettingsActions } from "../../application/runtime/settings-actions"; +import type { GoalActions } from "../../application/threads/goal-actions"; import type { RestoredThreadTitleSnapshot, ChatPanelSurface } from "./model"; import { createChatPanelGoalSurface } from "./goal-surface"; import { createChatPanelToolbarSurface } from "./toolbar-surface"; diff --git a/src/features/chat/panel/surface/goal-surface.ts b/src/features/chat/panel/surface/goal-surface.ts index 5c6c1917..104972e5 100644 --- a/src/features/chat/panel/surface/goal-surface.ts +++ b/src/features/chat/panel/surface/goal-surface.ts @@ -1,9 +1,9 @@ import type { CodexPanelSettings } from "../../../../settings/model"; -import type { ChatConnectionController } from "../../connection/connection-controller"; +import type { ChatConnectionController } from "../../application/connection/connection-controller"; import type { ChatInboundController } from "../../app-server/inbound/controller"; -import type { ChatServerThreadActions } from "../../connection/server-actions/threads"; -import type { GoalActions } from "../../threads/goal-actions"; -import type { ChatAction, ChatState, ChatStateStore } from "../../state/reducer"; +import type { ChatServerThreadActions } from "../../app-server/actions/threads"; +import type { GoalActions } from "../../application/threads/goal-actions"; +import type { ChatAction, ChatState, ChatStateStore } from "../../application/state/reducer"; import type { ChatPanelGoalSurface } from "./model"; export interface ChatPanelGoalSurfaceHost { diff --git a/src/features/chat/panel/surface/message-stream-presenter.ts b/src/features/chat/panel/surface/message-stream-presenter.ts index d3f1973b..13e32c23 100644 --- a/src/features/chat/panel/surface/message-stream-presenter.ts +++ b/src/features/chat/panel/surface/message-stream-presenter.ts @@ -2,16 +2,15 @@ import type { ComponentChild as UiNode } from "preact"; import { h } from "preact"; import type { App, Component } from "obsidian"; import { copyTextWithNotice } from "../../../../shared/ui/clipboard"; -import type { ChatAction, ChatStateStore } from "../../state/reducer"; +import type { ChatAction, ChatStateStore } from "../../application/state/reducer"; import type { MessageStreamScrollIntent, MessageStreamVirtualizerHandle } from "../../ui/message-stream/virtualizer"; import { MarkdownMessageRenderer } from "../../ui/message-stream/markdown-renderer"; import { MessageStreamViewport, type MessageStreamViewportState } from "../../ui/message-stream/viewport"; -import type { MessageStreamItem } from "../../domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; import { messageStreamBlocks } from "../../ui/message-stream/stream-blocks"; import { messageStreamStateFromShellState, useChatPanelShellState, type ChatPanelMessageStreamShellState } from "../../ui/shell-state"; -import type { PendingRequestBlockSnapshot } from "../../presentation/pending-requests/snapshot"; -import type { PendingRequestBlockActions } from "../../presentation/pending-requests/view-model"; -import type { ChatTurnDiffViewState } from "../../turn-diff/model"; +import type { PendingRequestBlockActions, PendingRequestBlockState } from "../../application/pending-requests/block"; +import type { ChatTurnDiffViewState } from "../../domain/turn-diff"; import { createMessageStreamSurfaceContext, messageStreamSurfaceProjectionFromState, @@ -39,7 +38,7 @@ interface ChatMessageStreamActions { interface ChatMessageStreamRequests { pendingSignature: () => string; - pendingSnapshot: () => PendingRequestBlockSnapshot; + pendingSnapshot: () => PendingRequestBlockState; pendingActions: () => PendingRequestBlockActions; consumePendingAutoFocus: () => boolean; } diff --git a/src/features/chat/panel/surface/message-stream-projection.ts b/src/features/chat/panel/surface/message-stream-projection.ts index 589a9d40..b9eb1979 100644 --- a/src/features/chat/panel/surface/message-stream-projection.ts +++ b/src/features/chat/panel/surface/message-stream-projection.ts @@ -1,25 +1,31 @@ -import { activeTurnId, chatTurnBusy, type ChatAction, type ChatDisclosureBucket, type ChatDisclosureUiState } from "../../state/reducer"; -import type { MessageStreamItem } from "../../domain/message-stream/model/items"; +import { + activeTurnId, + chatTurnBusy, + type ChatAction, + type ChatDisclosureBucket, + type ChatDisclosureUiState, +} from "../../application/state/reducer"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; import { messageStreamViewBlocks, type MessageStreamViewBlock } from "../../presentation/message-stream/view-model"; -import { implementPlanCandidateFromState } from "../../state/selectors"; +import { implementPlanCandidateFromState } from "../../application/state/selectors"; import { type ForkCandidate, forkCandidatesFromItems, isForkCandidateItem, isRollbackCandidateItem, -} from "../../domain/message-stream/queries/selectors"; +} from "../../domain/message-stream/selectors"; import { messageStreamActiveItems, messageStreamItems, messageStreamRollbackCandidate, messageStreamStableItems, type MessageStreamRollbackCandidate, -} from "../../state/message-stream"; +} from "../../application/state/message-stream"; import type { MessageStreamContext } from "../../ui/message-stream/context"; import type { ChatPanelMessageStreamShellState } from "../../ui/shell-state"; -import type { PendingRequestBlockSnapshot } from "../../presentation/pending-requests/snapshot"; -import type { PendingRequestBlockActions } from "../../presentation/pending-requests/view-model"; -import type { ChatTurnDiffViewState } from "../../turn-diff/model"; +import { pendingRequestBlockSnapshotFromState } from "../../presentation/pending-requests/snapshot"; +import type { PendingRequestBlockActions, PendingRequestBlockState } from "../../application/pending-requests/block"; +import type { ChatTurnDiffViewState } from "../../domain/turn-diff"; interface ChatMessageStreamActions { rollbackThread: (threadId: string) => void; @@ -30,7 +36,7 @@ interface ChatMessageStreamActions { interface ChatMessageStreamRequests { pendingSignature: () => string; - pendingSnapshot: () => PendingRequestBlockSnapshot; + pendingSnapshot: () => PendingRequestBlockState; pendingActions: () => PendingRequestBlockActions; consumePendingAutoFocus: () => boolean; } @@ -149,7 +155,7 @@ function messageStreamContextFromProjection( }, pendingRequests: { signature: context.requests.pendingSignature(), - snapshot: context.requests.pendingSnapshot, + snapshot: () => pendingRequestBlockSnapshotFromState(context.requests.pendingSnapshot()), actions: context.requests.pendingActions, consumeAutoFocus: context.requests.consumePendingAutoFocus, }, diff --git a/src/features/chat/panel/surface/message-stream-scroll.ts b/src/features/chat/panel/surface/message-stream-scroll.ts index b6417d50..fd76c4f8 100644 --- a/src/features/chat/panel/surface/message-stream-scroll.ts +++ b/src/features/chat/panel/surface/message-stream-scroll.ts @@ -1,4 +1,4 @@ -import type { ComposerBoundaryScrollAction } from "../../conversation/composer/boundary-scroll"; +import type { ComposerBoundaryScrollAction } from "../../application/composer/boundary-scroll"; import type { MessageStreamVirtualizerHandle } from "../../ui/message-stream/virtualizer"; export class MessageStreamScrollBridge { diff --git a/src/features/chat/panel/surface/runtime-snapshot.ts b/src/features/chat/panel/surface/runtime-snapshot.ts index 86964a5b..16db3c1b 100644 --- a/src/features/chat/panel/surface/runtime-snapshot.ts +++ b/src/features/chat/panel/surface/runtime-snapshot.ts @@ -1,7 +1,7 @@ -import { messageStreamItems } from "../../state/message-stream"; -import type { ChatState } from "../../state/reducer"; -import type { RuntimeSnapshot } from "../../runtime/snapshot"; -import { runtimeSnapshotForChatSlices } from "../../runtime/snapshot"; +import { messageStreamItems } from "../../application/state/message-stream"; +import type { ChatState } from "../../application/state/reducer"; +import type { RuntimeSnapshot } from "../../application/runtime/snapshot"; +import { runtimeSnapshotForChatSlices } from "../../application/runtime/snapshot"; export function runtimeSnapshotForShellState( state: Pick, diff --git a/src/features/chat/panel/surface/toolbar-surface.ts b/src/features/chat/panel/surface/toolbar-surface.ts index 3888506b..3c60ab2e 100644 --- a/src/features/chat/panel/surface/toolbar-surface.ts +++ b/src/features/chat/panel/surface/toolbar-surface.ts @@ -1,14 +1,14 @@ import type { CodexPanelSettings } from "../../../../settings/model"; import type { ConnectionManager } from "../../../../app-server/connection/connection-manager"; -import type { ChatConnectionController } from "../../connection/connection-controller"; -import type { ChatReconnectActions } from "../../connection/reconnect-actions"; +import type { ChatConnectionController } from "../../application/connection/connection-controller"; +import type { ChatReconnectActions } from "../../application/connection/reconnect-actions"; import type { ChatInboundController } from "../../app-server/inbound/controller"; -import type { ThreadManagementActions } from "../../threads/thread-management-actions"; +import type { ThreadManagementActions } from "../../application/threads/thread-management-actions"; import type { ToolbarPanelActions } from "../toolbar-actions"; -import type { ThreadRenameEditorController } from "../../threads/rename-editor-controller"; -import type { SelectionActions } from "../../threads/selection-actions"; -import type { ChatStateStore } from "../../state/reducer"; -import { noActiveThreadToCompactMessage } from "../../threads/messages"; +import type { ThreadRenameEditorController } from "../../application/threads/rename-editor-controller"; +import type { SelectionActions } from "../../application/threads/selection-actions"; +import type { ChatStateStore } from "../../application/state/reducer"; +import { noActiveThreadToCompactMessage } from "../../application/threads/messages"; import type { ChatPanelToolbarSurface } from "./model"; export interface ChatPanelToolbarSurfaceHost { diff --git a/src/features/chat/panel/surface/toolbar.ts b/src/features/chat/panel/surface/toolbar.ts index 55fd4ea7..49cc539b 100644 --- a/src/features/chat/panel/surface/toolbar.ts +++ b/src/features/chat/panel/surface/toolbar.ts @@ -3,10 +3,10 @@ import { h } from "preact"; import type { Thread } from "../../../../domain/threads/model"; import { getThreadTitle } from "../../../../domain/threads/model"; -import { runtimeConfigSections, rateLimitSummary } from "../../runtime/status"; -import { connectionDiagnosticSections } from "../../connection/diagnostics-display"; -import type { RuntimeSnapshot } from "../../runtime/snapshot"; -import { chatTurnBusy, type ChatState } from "../../state/reducer"; +import { runtimeConfigSections, rateLimitSummary } from "../../presentation/runtime/status"; +import { connectionDiagnosticSections } from "../../application/connection/diagnostics-display"; +import type { RuntimeSnapshot } from "../../application/runtime/snapshot"; +import { chatTurnBusy, type ChatState } from "../../application/state/reducer"; import { toolbarStateFromShellState, useChatPanelShellState, type ChatPanelToolbarShellState } from "../../ui/shell-state"; import { Toolbar, type ToolbarThreadRow, type ToolbarViewModel } from "../../ui/toolbar"; import type { ChatPanelToolbarSurface } from "./model"; diff --git a/src/features/chat/panel/toolbar-actions.ts b/src/features/chat/panel/toolbar-actions.ts index f326239f..3563dc93 100644 --- a/src/features/chat/panel/toolbar-actions.ts +++ b/src/features/chat/panel/toolbar-actions.ts @@ -1,5 +1,5 @@ -import type { ThreadManagementActions } from "../threads/thread-management-actions"; -import type { ChatAction, ChatState, ChatStateStore } from "../state/reducer"; +import type { ThreadManagementActions } from "../application/threads/thread-management-actions"; +import type { ChatAction, ChatState, ChatStateStore } from "../application/state/reducer"; export interface ToolbarPanelActionsHost { stateStore: ChatStateStore; diff --git a/src/features/chat/panel/view-state.ts b/src/features/chat/panel/view-state.ts index 2dc1fe2a..87eda911 100644 --- a/src/features/chat/panel/view-state.ts +++ b/src/features/chat/panel/view-state.ts @@ -1,5 +1,5 @@ import { parseRestoredThreadState } from "./snapshot"; -import type { RestoredThreadState } from "../lifecycle"; +import type { RestoredThreadState } from "../application/lifecycle"; export interface ChatViewStateHost { invalidateResumeWork: () => void; diff --git a/src/features/chat/presentation/message-stream/agent-summary.ts b/src/features/chat/presentation/message-stream/agent-summary.ts index a915746d..90966dcb 100644 --- a/src/features/chat/presentation/message-stream/agent-summary.ts +++ b/src/features/chat/presentation/message-stream/agent-summary.ts @@ -1,6 +1,6 @@ import { truncate } from "../../../../utils"; -import { collabAgentStateExecutionState } from "../../app-server/mappers/message-stream/agent-items"; -import type { AgentRunSummary, AgentRunSummaryAgent, AgentStateSummary, MessageStreamItem } from "../../domain/message-stream/model/items"; +import { collabAgentStateExecutionState } from "../../domain/message-stream/agent-state"; +import type { AgentRunSummary, AgentRunSummaryAgent, AgentStateSummary, MessageStreamItem } from "../../domain/message-stream/items"; const ACTIVE_AGENT_PREVIEW_LIMIT = 96; type AgentRunState = "running" | "completed" | "failed"; diff --git a/src/features/chat/presentation/message-stream/blocks.ts b/src/features/chat/presentation/message-stream/blocks.ts index 406cd85d..ab9312d3 100644 --- a/src/features/chat/presentation/message-stream/blocks.ts +++ b/src/features/chat/presentation/message-stream/blocks.ts @@ -1,5 +1,5 @@ import { activeAgentRunSummary } from "./agent-summary"; -import type { AgentRunSummary, MessageStreamItem, TaskProgressMessageStreamItem } from "../../domain/message-stream/model/items"; +import type { AgentRunSummary, MessageStreamItem, TaskProgressMessageStreamItem } from "../../domain/message-stream/items"; import { messageStreamIsCoordinationProgress, messageStreamIsTaskProgress, diff --git a/src/features/chat/presentation/message-stream/layout.ts b/src/features/chat/presentation/message-stream/layout.ts index 1e620c26..75ac04c1 100644 --- a/src/features/chat/presentation/message-stream/layout.ts +++ b/src/features/chat/presentation/message-stream/layout.ts @@ -1,4 +1,4 @@ -import type { MessageStreamItem } from "../../domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; import { pathRelativeToRoot } from "../../domain/message-stream/format/path-labels"; import { messageStreamIsApprovalResult, diff --git a/src/features/chat/presentation/message-stream/text-view.ts b/src/features/chat/presentation/message-stream/text-view.ts index 3b37b0db..19658e1d 100644 --- a/src/features/chat/presentation/message-stream/text-view.ts +++ b/src/features/chat/presentation/message-stream/text-view.ts @@ -1,4 +1,4 @@ -import type { ExecutionState, MessageStreamItem } from "../../domain/message-stream/model/items"; +import type { ExecutionState, MessageStreamItem } from "../../domain/message-stream/items"; import type { MessageStreamItemAnnotations } from "./layout"; export type TextMessageStreamItem = Extract; diff --git a/src/features/chat/presentation/message-stream/tool-result-view.ts b/src/features/chat/presentation/message-stream/tool-result-view.ts index 14c4c4d0..953713b0 100644 --- a/src/features/chat/presentation/message-stream/tool-result-view.ts +++ b/src/features/chat/presentation/message-stream/tool-result-view.ts @@ -13,7 +13,7 @@ import type { MessageStreamPrimaryTarget, ReviewResultMessageStreamItem, ToolCallMessageStreamItem, -} from "../../domain/message-stream/model/items"; +} from "../../domain/message-stream/items"; export type ToolResultMessageStreamItem = | CommandMessageStreamItem diff --git a/src/features/chat/presentation/message-stream/work-view.ts b/src/features/chat/presentation/message-stream/work-view.ts index 95edac55..2dfc5d0e 100644 --- a/src/features/chat/presentation/message-stream/work-view.ts +++ b/src/features/chat/presentation/message-stream/work-view.ts @@ -10,7 +10,7 @@ import type { MessageStreamItem, ReasoningMessageStreamItem, TaskProgressMessageStreamItem, -} from "../../domain/message-stream/model/items"; +} from "../../domain/message-stream/items"; const AGENT_ROW_MESSAGE_PREVIEW_LIMIT = 120; const AGENT_ACTIVITY_PROMPT_PREVIEW_LIMIT = 96; diff --git a/src/features/chat/presentation/pending-requests/snapshot.ts b/src/features/chat/presentation/pending-requests/snapshot.ts index 7937bd69..b148a67d 100644 --- a/src/features/chat/presentation/pending-requests/snapshot.ts +++ b/src/features/chat/presentation/pending-requests/snapshot.ts @@ -1,4 +1,3 @@ -import type { ChatState } from "../../state/reducer"; import type { PendingApproval, PendingUserInput } from "../../domain/pending-requests/model"; import { pendingApprovalViewModel, @@ -14,21 +13,14 @@ export interface PendingRequestBlockSnapshot { approvalDetails: ReadonlySet; } -export function pendingRequestBlockSnapshot(state: ChatState): PendingRequestBlockSnapshot { - return pendingRequestBlockSnapshotFromRequests({ - approvals: state.requests.approvals, - pendingUserInputs: state.requests.pendingUserInputs, - userInputDrafts: state.requests.userInputDrafts, - approvalDetails: state.ui.disclosures.approvalDetails, - }); -} - -export function pendingRequestBlockSnapshotFromRequests(source: { +export interface PendingRequestBlockSnapshotSource { approvals: readonly PendingApproval[]; pendingUserInputs: readonly PendingUserInput[]; userInputDrafts: ReadonlyMap; approvalDetails: ReadonlySet; -}): PendingRequestBlockSnapshot { +} + +export function pendingRequestBlockSnapshotFromState(source: PendingRequestBlockSnapshotSource): PendingRequestBlockSnapshot { return { approvals: source.approvals.map(pendingApprovalViewModel), pendingUserInputs: source.pendingUserInputs.map(pendingUserInputViewModel), diff --git a/src/features/chat/presentation/pending-requests/view-model.ts b/src/features/chat/presentation/pending-requests/view-model.ts index b8febc4b..185e44a4 100644 --- a/src/features/chat/presentation/pending-requests/view-model.ts +++ b/src/features/chat/presentation/pending-requests/view-model.ts @@ -1,17 +1,15 @@ -import type { RequestId } from "../../../../app-server/connection/rpc-messages"; import { approvalDetails, approvalSummary, approvalTitle } from "../../domain/pending-requests/approval"; import { approvalActionOptions, type ApprovalActionOption } from "./approval-view"; import { - type ApprovalAction, type PendingApproval, + type PendingRequestId as DomainPendingRequestId, type PendingUserInput, questionDefaultAnswer, userInputDraftKey, userInputOtherDraftKey, } from "../../domain/pending-requests/model"; -export type PendingRequestId = RequestId; -type PendingRequestApprovalAction = ApprovalAction; +type PendingRequestId = DomainPendingRequestId; type PendingRequestApprovalOption = ApprovalActionOption; @@ -52,14 +50,6 @@ export interface PendingUserInputViewModel { questions: PendingUserInputQuestionViewModel[]; } -export interface PendingRequestBlockActions { - resolveApproval: (requestId: PendingRequestId, action: PendingRequestApprovalAction) => void; - resolveUserInput: (requestId: PendingRequestId) => void; - cancelUserInput: (requestId: PendingRequestId) => void; - setApprovalDetailsExpanded?: (requestId: PendingRequestId, expanded: boolean) => void; - setUserInputDraft: (key: string, value: string) => void; -} - export function pendingApprovalViewModel(approval: PendingApproval): PendingApprovalViewModel { return { requestId: approval.requestId, diff --git a/src/features/chat/presentation/runtime/messages.ts b/src/features/chat/presentation/runtime/messages.ts new file mode 100644 index 00000000..462e2f1f --- /dev/null +++ b/src/features/chat/presentation/runtime/messages.ts @@ -0,0 +1,36 @@ +import type { ReasoningEffort } from "../../../../domain/catalog/metadata"; +import type { CollaborationMode } from "../../domain/runtime/pending-settings"; + +export function compactModelLabel(model: string | null): string { + if (!model) return "default"; + const match = /^gpt-(.+)$/.exec(model); + return match?.[1] ?? model; +} + +export function compactReasoningEffortLabel(effort: ReasoningEffort | null): string { + if (!effort) return "default"; + if (effort === "minimal") return "min"; + return effort; +} + +export function collaborationModeLabel(mode: CollaborationMode): string { + return mode === "plan" ? "Plan" : "Default"; +} + +export function pendingRuntimeSettingLabel( + setting: { kind: "unchanged" } | { kind: "set"; value: unknown } | { kind: "resetToConfig" }, +): string { + if (setting.kind === "set") return String(setting.value); + if (setting.kind === "resetToConfig") return "(reset to config)"; + return "(none)"; +} + +export function serviceTierLabel(value: string | null): string { + return value ?? "(Codex default)"; +} + +export function fastModeLabel(input: { requestedOff: boolean; active: boolean; serviceTier: string | null }): string { + if (input.requestedOff) return "off"; + if (input.active) return "on"; + return input.serviceTier ? "off" : "Codex default"; +} diff --git a/src/features/chat/runtime/status.ts b/src/features/chat/presentation/runtime/status.ts similarity index 96% rename from src/features/chat/runtime/status.ts rename to src/features/chat/presentation/runtime/status.ts index c1b02641..e981a049 100644 --- a/src/features/chat/runtime/status.ts +++ b/src/features/chat/presentation/runtime/status.ts @@ -1,8 +1,8 @@ -import type { RuntimeConfigSnapshot } from "../../../domain/runtime/config"; -import type { RateLimitWindow, SpendControlLimitSnapshot, ThreadTokenUsage } from "../../../domain/runtime/metrics"; -import { jsonPreview } from "../../../utils"; -import { sortedModelMetadata } from "../../../domain/catalog/metadata"; -import { defaultEffortForModelMetadata } from "../../../domain/catalog/metadata"; +import type { RuntimeConfigSnapshot } from "../../../../domain/runtime/config"; +import type { RateLimitWindow, SpendControlLimitSnapshot, ThreadTokenUsage } from "../../../../domain/runtime/metrics"; +import { jsonPreview } from "../../../../utils"; +import { sortedModelMetadata } from "../../../../domain/catalog/metadata"; +import { defaultEffortForModelMetadata } from "../../../../domain/catalog/metadata"; import { currentApprovalsReviewer, currentApprovalPolicy, @@ -13,9 +13,9 @@ import { fastModeActive, runtimeConfigOrDefault, supportedReasoningEfforts, -} from "./effective"; -import type { RuntimeSnapshot } from "./snapshot"; -import { effectiveCollaborationMode } from "./pending-settings"; +} from "../../domain/runtime/effective"; +import type { RuntimeSnapshot } from "../../domain/runtime/snapshot"; +import { effectiveCollaborationMode } from "../../domain/runtime/pending-settings"; import { collaborationModeLabel, fastModeLabel as formatFastModeLabel, diff --git a/src/features/chat/conversation/composer/controller.ts b/src/features/chat/ui/composer-controller.ts similarity index 93% rename from src/features/chat/conversation/composer/controller.ts rename to src/features/chat/ui/composer-controller.ts index 94355194..f86adb03 100644 --- a/src/features/chat/conversation/composer/controller.ts +++ b/src/features/chat/ui/composer-controller.ts @@ -1,14 +1,17 @@ import type { App, EventRef } from "obsidian"; -import type { CodexInput } from "../../../../domain/chat/input"; -import { isComposerSendKey, type SendShortcut } from "../../../../shared/ui/keyboard"; -import { textareaCursorAtVisualBoundary } from "../../../../shared/ui/textarea-caret"; -import { chatTurnBusy, type ChatAction, type ChatState, type ChatStateStore } from "../../state/reducer"; -import type { ComposerMetaViewModel, ComposerShellProps } from "../../ui/composer"; -import { syncComposerHeight, type ComposerCallbacks } from "../../ui/composer"; -import type { ChatPanelComposerShellState } from "../../ui/shell-state"; -import { composerBoundaryScrollDirection, type ComposerBoundaryScrollAction } from "./boundary-scroll"; -import { noteCandidates as appNoteCandidates, resolveWikiLinkMention as resolveAppWikiLinkMention } from "./obsidian-context"; +import type { CodexInput } from "../../../domain/chat/input"; +import { isComposerSendKey, type SendShortcut } from "../../../shared/ui/keyboard"; +import { textareaCursorAtVisualBoundary } from "../../../shared/ui/textarea-caret"; +import { chatTurnBusy, type ChatAction, type ChatState, type ChatStateStore } from "../application/state/reducer"; +import type { ComposerMetaViewModel, ComposerShellProps } from "./composer"; +import { syncComposerHeight, type ComposerCallbacks } from "./composer"; +import type { ChatPanelComposerShellState } from "./shell-state"; +import { composerBoundaryScrollDirection, type ComposerBoundaryScrollAction } from "../application/composer/boundary-scroll"; +import { + noteCandidates as appNoteCandidates, + resolveWikiLinkMention as resolveAppWikiLinkMention, +} from "../application/composer/obsidian-context"; import { activeComposerSuggestions, applyComposerSuggestionInsertion, @@ -17,8 +20,8 @@ import { nextComposerSuggestionIndex, type ComposerSuggestion, type NoteCandidate, -} from "./suggestions"; -import { userInputWithWikiLinkMentionsAndSkills } from "./wikilink-context"; +} from "../application/composer/suggestions"; +import { userInputWithWikiLinkMentionsAndSkills } from "../application/composer/wikilink-context"; export interface ChatComposerControllerOptions { app: App; diff --git a/src/features/chat/ui/composer.tsx b/src/features/chat/ui/composer.tsx index 7266b7d3..4f7dcebb 100644 --- a/src/features/chat/ui/composer.tsx +++ b/src/features/chat/ui/composer.tsx @@ -1,7 +1,7 @@ import type { ButtonHTMLAttributes, ComponentChild as UiNode, Ref } from "preact"; import { useLayoutEffect, useRef, useState } from "preact/hooks"; -import type { ComposerSuggestion } from "../conversation/composer/suggestions"; +import type { ComposerSuggestion } from "../application/composer/suggestions"; import { IconButton } from "../../../shared/ui/components"; import { disposeDomListeners, listenDomEvent } from "../../../shared/ui/dom-events"; import { syncTextareaHeight } from "../../../shared/ui/textarea-autogrow"; diff --git a/src/features/chat/ui/message-stream/context.ts b/src/features/chat/ui/message-stream/context.ts index f3ccdbab..0d780b76 100644 --- a/src/features/chat/ui/message-stream/context.ts +++ b/src/features/chat/ui/message-stream/context.ts @@ -1,11 +1,11 @@ import type { ComponentChild as UiNode } from "preact"; -import type { ChatDisclosureBucket, ChatDisclosureUiState, ChatTurnLifecycleState } from "../../state/reducer"; +import type { ChatDisclosureBucket, ChatDisclosureUiState, ChatTurnLifecycleState } from "../../application/state/reducer"; +import type { PendingRequestBlockActions } from "../../application/pending-requests/block"; import type { PendingRequestBlockSnapshot } from "../../presentation/pending-requests/snapshot"; -import type { PendingRequestBlockActions } from "../../presentation/pending-requests/view-model"; -import type { MessageStreamItem } from "../../domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; import type { TextMessageStreamItem } from "../../presentation/message-stream/text-view"; -import type { ChatTurnDiffViewState } from "../../turn-diff/model"; +import type { ChatTurnDiffViewState } from "../../domain/turn-diff"; export interface MessageStreamBlock { key: string; diff --git a/src/features/chat/ui/message-stream/pending-request-block.tsx b/src/features/chat/ui/message-stream/pending-request-block.tsx index a91224c5..b7667c68 100644 --- a/src/features/chat/ui/message-stream/pending-request-block.tsx +++ b/src/features/chat/ui/message-stream/pending-request-block.tsx @@ -3,10 +3,10 @@ import { useEffect, useLayoutEffect, useRef, useState } from "preact/hooks"; import { type PendingApprovalViewModel, - type PendingRequestBlockActions, type PendingUserInputQuestionViewModel, type PendingUserInputViewModel, } from "../../presentation/pending-requests/view-model"; +import type { PendingRequestBlockActions } from "../../application/pending-requests/block"; import { createWorkMessageClassName } from "./work-message"; export function pendingRequestBlockNode( diff --git a/src/features/chat/ui/message-stream/text-item-actions.tsx b/src/features/chat/ui/message-stream/text-item-actions.tsx index a9263882..9b7a5e02 100644 --- a/src/features/chat/ui/message-stream/text-item-actions.tsx +++ b/src/features/chat/ui/message-stream/text-item-actions.tsx @@ -1,8 +1,8 @@ import { type ComponentChild as UiNode } from "preact"; import { useEffect, useRef } from "preact/hooks"; -import { activeTurnId } from "../../state/reducer"; -import type { MessageStreamItem } from "../../domain/message-stream/model/items"; +import { activeTurnId } from "../../application/state/reducer"; +import type { MessageStreamItem } from "../../domain/message-stream/items"; import { IconButton } from "../../../../shared/ui/components"; import { listenDomEvent } from "../../../../shared/ui/dom-events"; import type { TextItemActionContext, TextMessageStreamItem } from "./context"; diff --git a/src/features/chat/ui/message-stream/text-item-metadata.tsx b/src/features/chat/ui/message-stream/text-item-metadata.tsx index 032d27c5..b0d4b906 100644 --- a/src/features/chat/ui/message-stream/text-item-metadata.tsx +++ b/src/features/chat/ui/message-stream/text-item-metadata.tsx @@ -5,7 +5,7 @@ import type { MessageStreamItem, MessageStreamNoticeSection, MessageStreamUserInputQuestionResult, -} from "../../domain/message-stream/model/items"; +} from "../../domain/message-stream/items"; import { IconButton } from "../../../../shared/ui/components"; import type { TextItemDetailStateContext, TextItemMetadataContext } from "./context"; diff --git a/src/features/chat/ui/message-stream/tool-result.tsx b/src/features/chat/ui/message-stream/tool-result.tsx index 4d231184..509e20f7 100644 --- a/src/features/chat/ui/message-stream/tool-result.tsx +++ b/src/features/chat/ui/message-stream/tool-result.tsx @@ -3,7 +3,7 @@ import { useLayoutEffect, useRef } from "preact/hooks"; import { type ToolResultDetailSection, type ToolResultView } from "../../presentation/message-stream/tool-result-view"; import { renderRawDiffLines } from "../../../../shared/diff/render"; -import type { ChatDisclosureUiState } from "../../state/reducer"; +import type { ChatDisclosureUiState } from "../../application/state/reducer"; export interface ToolResultRenderContext { disclosures: ChatDisclosureUiState; diff --git a/src/features/chat/ui/message-stream/work-items.tsx b/src/features/chat/ui/message-stream/work-items.tsx index 72a69782..b111e929 100644 --- a/src/features/chat/ui/message-stream/work-items.tsx +++ b/src/features/chat/ui/message-stream/work-items.tsx @@ -1,8 +1,8 @@ import type { ComponentChild as UiNode } from "preact"; -import type { ExecutionState, TaskProgressMessageStreamItem } from "../../domain/message-stream/model/items"; +import type { ExecutionState, TaskProgressMessageStreamItem } from "../../domain/message-stream/items"; import type { AgentRunSummaryView, MessageStreamWorkView } from "../../presentation/message-stream/work-view"; -import type { ChatDisclosureUiState } from "../../state/reducer"; +import type { ChatDisclosureUiState } from "../../application/state/reducer"; import { createWorkMessageClassName } from "./work-message"; export interface WorkItemContext { diff --git a/src/features/chat/ui/shell-state.tsx b/src/features/chat/ui/shell-state.tsx index 0ee3f0bc..10781494 100644 --- a/src/features/chat/ui/shell-state.tsx +++ b/src/features/chat/ui/shell-state.tsx @@ -2,7 +2,7 @@ import { createContext } from "preact"; import { useContext } from "preact/hooks"; import { batch, signal, type Signal } from "@preact/signals"; -import type { ChatState } from "../state/reducer"; +import type { ChatState } from "../application/state/reducer"; export interface ChatPanelShellState { connection: Signal; diff --git a/src/features/chat/ui/shell.tsx b/src/features/chat/ui/shell.tsx index 2b62c6c8..9f149e1d 100644 --- a/src/features/chat/ui/shell.tsx +++ b/src/features/chat/ui/shell.tsx @@ -1,6 +1,6 @@ import type { ComponentChild as UiNode } from "preact"; import { renderUiRoot, unmountUiRoot } from "../../../shared/ui/ui-root"; -import type { ChatStateStore } from "../state/reducer"; +import type { ChatStateStore } from "../application/state/reducer"; import type { ChatPanelGoalSurface, ChatPanelToolbarSurface } from "../panel/surface/model"; import { ChatPanelToolbar } from "../panel/surface/toolbar"; import { ChatPanelGoal } from "../panel/surface/goal"; diff --git a/src/features/chat/ui/toolbar.tsx b/src/features/chat/ui/toolbar.tsx index 7aee574b..03a3d81f 100644 --- a/src/features/chat/ui/toolbar.tsx +++ b/src/features/chat/ui/toolbar.tsx @@ -1,7 +1,7 @@ import type { ButtonHTMLAttributes, ComponentChild as UiNode, TargetedKeyboardEvent } from "preact"; import { useLayoutEffect, useRef } from "preact/hooks"; -import type { RuntimeConfigSection, RateLimitSummary } from "../runtime/status"; +import type { RuntimeConfigSection, RateLimitSummary } from "../presentation/runtime/status"; import { IconButton } from "../../../shared/ui/components"; type ButtonProps = ButtonHTMLAttributes & { diff --git a/src/features/chat/turn-diff/render.tsx b/src/features/chat/ui/turn-diff/render.tsx similarity index 89% rename from src/features/chat/turn-diff/render.tsx rename to src/features/chat/ui/turn-diff/render.tsx index d7ff9c2a..00e1a600 100644 --- a/src/features/chat/turn-diff/render.tsx +++ b/src/features/chat/ui/turn-diff/render.tsx @@ -1,12 +1,12 @@ import type { ComponentChild as UiNode } from "preact"; import { useLayoutEffect, useRef } from "preact/hooks"; -import { renderDisplayDiffLines } from "../../../shared/diff/render"; -import { displayDiffLines } from "../../../shared/diff/unified"; -import { IconButton } from "../../../shared/ui/components"; -import { renderUiRoot } from "../../../shared/ui/ui-root"; -import { shortThreadId } from "../../../utils"; -import type { ChatTurnDiffViewState, PersistedChatTurnDiffViewState } from "./model"; +import { renderDisplayDiffLines } from "../../../../shared/diff/render"; +import { displayDiffLines } from "../../../../shared/diff/unified"; +import { IconButton } from "../../../../shared/ui/components"; +import { renderUiRoot } from "../../../../shared/ui/ui-root"; +import { shortThreadId } from "../../../../utils"; +import type { ChatTurnDiffViewState, PersistedChatTurnDiffViewState } from "../../domain/turn-diff"; export interface ChatTurnDiffViewActions { copyDiff?: () => void; diff --git a/src/features/chat/turn-diff/view.ts b/src/features/chat/ui/turn-diff/view.ts similarity index 89% rename from src/features/chat/turn-diff/view.ts rename to src/features/chat/ui/turn-diff/view.ts index 4b760e6b..14d1b089 100644 --- a/src/features/chat/turn-diff/view.ts +++ b/src/features/chat/ui/turn-diff/view.ts @@ -1,14 +1,14 @@ import { ItemView, type ViewStateResult } from "obsidian"; -import { VIEW_TYPE_CODEX_TURN_DIFF } from "../../../constants"; -import { copyTextWithNotice } from "../../../shared/ui/clipboard"; -import { unmountUiRoot } from "../../../shared/ui/ui-root"; +import { VIEW_TYPE_CODEX_TURN_DIFF } from "../../../../constants"; +import { copyTextWithNotice } from "../../../../shared/ui/clipboard"; +import { unmountUiRoot } from "../../../../shared/ui/ui-root"; import { isPersistedChatTurnDiffViewState, persistedChatTurnDiffViewState, type PersistedChatTurnDiffViewState, type ChatTurnDiffViewState, -} from "./model"; +} from "../../domain/turn-diff"; import { renderChatTurnDiffView } from "./render"; export class CodexChatTurnDiffView extends ItemView { diff --git a/src/main.ts b/src/main.ts index bfd0844f..c6a53f78 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,16 +2,16 @@ import { Plugin } from "obsidian"; import { VIEW_TYPE_CODEX_PANEL, VIEW_TYPE_CODEX_THREADS, VIEW_TYPE_CODEX_TURN_DIFF } from "./constants"; import { registerSelectionRewriteCommand } from "./features/selection-rewrite/command"; -import { CodexChatView } from "./features/chat/view"; -import type { CodexChatHost } from "./features/chat/chat-host"; -import { CodexChatTurnDiffView } from "./features/chat/turn-diff/view"; +import { CodexChatView } from "./features/chat/host/view"; +import type { CodexChatHost } from "./features/chat/application/chat-host"; +import { CodexChatTurnDiffView } from "./features/chat/ui/turn-diff/view"; import { openThreadPicker, type ThreadPickerHost } from "./features/thread-picker/modal"; import { CodexThreadsView, type CodexThreadsHost } from "./features/threads-view/view"; import { SharedAppServerCache } from "./app-server/services/shared-cache"; import type { SharedAppServerCacheContext } from "./app-server/services/shared-cache-state"; import { DEFAULT_SETTINGS, getVaultPath, normalizeSettings, settingsMatchNormalizedData, type CodexPanelSettings } from "./settings/model"; import { CodexPanelSettingTab, type CodexPanelSettingTabHost } from "./settings/tab"; -import { persistedChatTurnDiffViewState, type ChatTurnDiffViewState } from "./features/chat/turn-diff/model"; +import { persistedChatTurnDiffViewState, type ChatTurnDiffViewState } from "./features/chat/domain/turn-diff"; import { WorkspacePanelCoordinator } from "./workspace/panel-coordinator"; import { createThreadSurfaceActions } from "./workspace/thread-surface-actions"; import type { SharedServerMetadata } from "./domain/server/metadata"; diff --git a/src/workspace/panel-coordinator.ts b/src/workspace/panel-coordinator.ts index c26a0584..f3a8c877 100644 --- a/src/workspace/panel-coordinator.ts +++ b/src/workspace/panel-coordinator.ts @@ -1,7 +1,7 @@ import type { App, WorkspaceLeaf } from "obsidian"; import { VIEW_TYPE_CODEX_PANEL } from "../constants"; -import { CodexChatView } from "../features/chat/view"; +import { CodexChatView } from "../features/chat/host/view"; import type { OpenCodexPanelSnapshot } from "./open-panel-snapshot"; const BOOT_RESTORED_PANEL_LOAD_DELAY_MS = 1_000; diff --git a/tests/features/chat/connection/app-server-warmup.test.ts b/tests/features/chat/connection/app-server-warmup.test.ts index 1d3141cf..e022ebcc 100644 --- a/tests/features/chat/connection/app-server-warmup.test.ts +++ b/tests/features/chat/connection/app-server-warmup.test.ts @@ -2,8 +2,8 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -import { scheduleAppServerWarmup } from "../../../../src/features/chat/connection/app-server-warmup"; -import { createChatViewDeferredTasks } from "../../../../src/features/chat/lifecycle"; +import { scheduleAppServerWarmup } from "../../../../src/features/chat/application/connection/app-server-warmup"; +import { createChatViewDeferredTasks } from "../../../../src/features/chat/host/lifecycle"; function createWarmupHost({ opened = true, diff --git a/tests/features/chat/connection/connection-controller.test.ts b/tests/features/chat/connection/connection-controller.test.ts index 8ec4698d..fa4b40e7 100644 --- a/tests/features/chat/connection/connection-controller.test.ts +++ b/tests/features/chat/connection/connection-controller.test.ts @@ -2,14 +2,14 @@ import { describe, expect, it, vi } from "vitest"; import type { AppServerClient } from "../../../../src/app-server/connection/client"; import { emptyRuntimeConfigSnapshot } from "../../../../src/app-server/protocol/runtime-config"; -import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; +import { createChatState, createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; import { ChatConnectionController, type ChatConnectionAdapter, type ChatConnectionDiagnosticsActions, type ChatConnectionMetadataActions, -} from "../../../../src/features/chat/connection/connection-controller"; -import { ChatConnectionWorkTracker } from "../../../../src/features/chat/lifecycle"; +} from "../../../../src/features/chat/application/connection/connection-controller"; +import { ChatConnectionWorkTracker } from "../../../../src/features/chat/application/lifecycle"; function createController({ connected = false, client = {} as AppServerClient } = {}) { const stateStore = createChatStateStore(createChatState()); diff --git a/tests/features/chat/connection/reconnect-actions.test.ts b/tests/features/chat/connection/reconnect-actions.test.ts index 3ec9ab29..cd3a91a9 100644 --- a/tests/features/chat/connection/reconnect-actions.test.ts +++ b/tests/features/chat/connection/reconnect-actions.test.ts @@ -1,7 +1,10 @@ import { describe, expect, it, vi } from "vitest"; -import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; -import { createChatReconnectActions, type ChatReconnectActionsHost } from "../../../../src/features/chat/connection/reconnect-actions"; +import { createChatState, createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; +import { + createChatReconnectActions, + type ChatReconnectActionsHost, +} from "../../../../src/features/chat/application/connection/reconnect-actions"; function createHost(overrides: Partial = {}) { const stateStore = createChatStateStore(createChatState()); diff --git a/tests/features/chat/connection/server-actions/server-actions.test.ts b/tests/features/chat/connection/server-actions/server-actions.test.ts index 46aa08df..bd78c444 100644 --- a/tests/features/chat/connection/server-actions/server-actions.test.ts +++ b/tests/features/chat/connection/server-actions/server-actions.test.ts @@ -5,11 +5,11 @@ import type { McpServerStatus } from "../../../../../src/domain/server/diagnosti import { emptyRuntimeConfigSnapshot } from "../../../../../src/app-server/protocol/runtime-config"; import type { RateLimitSnapshot } from "../../../../../src/app-server/protocol/runtime-metrics"; import { threadFromThreadRecord } from "../../../../../src/app-server/protocol/thread"; -import { createChatServerDiagnosticsActions } from "../../../../../src/features/chat/connection/server-actions/diagnostics"; -import { createChatServerMetadataActions } from "../../../../../src/features/chat/connection/server-actions/metadata"; -import { createChatServerThreadActions } from "../../../../../src/features/chat/connection/server-actions/threads"; -import { runtimeSnapshotForChatState } from "../../../../../src/features/chat/runtime/snapshot"; -import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; +import { createChatServerDiagnosticsActions } from "../../../../../src/features/chat/app-server/actions/diagnostics"; +import { createChatServerMetadataActions } from "../../../../../src/features/chat/app-server/actions/metadata"; +import { createChatServerThreadActions } from "../../../../../src/features/chat/app-server/actions/threads"; +import { runtimeSnapshotForChatState } from "../../../../../src/features/chat/application/runtime/snapshot"; +import { createChatState, createChatStateStore } from "../../../../../src/features/chat/application/state/reducer"; import type { CatalogModel, CatalogSkillMetadata } from "../../../../../src/app-server/protocol/catalog"; type ThreadStartResponse = Awaited>; diff --git a/tests/features/chat/conversation/composer/boundary-scroll.test.ts b/tests/features/chat/conversation/composer/boundary-scroll.test.ts index c298b94b..cb1cd88d 100644 --- a/tests/features/chat/conversation/composer/boundary-scroll.test.ts +++ b/tests/features/chat/conversation/composer/boundary-scroll.test.ts @@ -3,7 +3,7 @@ import { describe, expect, it, vi } from "vitest"; import { composerBoundaryScrollDirection, type ComposerBoundaryScrollAction, -} from "../../../../../src/features/chat/conversation/composer/boundary-scroll"; +} from "../../../../../src/features/chat/application/composer/boundary-scroll"; describe("composer boundary scroll shortcuts", () => { it("scrolls up from the first composer line", () => { diff --git a/tests/features/chat/conversation/composer/composer-suggestions.test.ts b/tests/features/chat/conversation/composer/composer-suggestions.test.ts index aa6d349a..157cb0f3 100644 --- a/tests/features/chat/conversation/composer/composer-suggestions.test.ts +++ b/tests/features/chat/conversation/composer/composer-suggestions.test.ts @@ -10,8 +10,8 @@ import { findWikiLinkSuggestions, nextComposerSuggestionIndex, parseSlashCommand, -} from "../../../../../src/features/chat/conversation/composer/suggestions"; -import { userInputWithWikiLinkMentions } from "../../../../../src/features/chat/conversation/composer/wikilink-context"; +} from "../../../../../src/features/chat/application/composer/suggestions"; +import { userInputWithWikiLinkMentions } from "../../../../../src/features/chat/application/composer/wikilink-context"; function expectPresent(value: T | null | undefined): T { if (value === null || value === undefined) throw new Error("Expected value to be present"); diff --git a/tests/features/chat/conversation/composer/controller.test.ts b/tests/features/chat/conversation/composer/controller.test.ts index 3bec14de..b9d4a323 100644 --- a/tests/features/chat/conversation/composer/controller.test.ts +++ b/tests/features/chat/conversation/composer/controller.test.ts @@ -4,9 +4,9 @@ import type { App } from "obsidian"; import { describe, expect, it, vi } from "vitest"; import { h } from "preact"; -import { ChatComposerController, type ChatComposerRenderActions } from "../../../../../src/features/chat/conversation/composer/controller"; +import { ChatComposerController, type ChatComposerRenderActions } from "../../../../../src/features/chat/ui/composer-controller"; import { ComposerShell } from "../../../../../src/features/chat/ui/composer"; -import { createChatStateStore, type ChatStateStore } from "../../../../../src/features/chat/state/reducer"; +import { createChatStateStore, type ChatStateStore } from "../../../../../src/features/chat/application/state/reducer"; import { renderUiRoot, unmountUiRoot } from "../../../../../src/shared/ui/ui-root"; import type { SkillMetadata } from "../../../../../src/domain/catalog/metadata"; import { installObsidianDomShims } from "../../../../support/dom"; diff --git a/tests/features/chat/conversation/composer/obsidian-context.test.ts b/tests/features/chat/conversation/composer/obsidian-context.test.ts index 074ea037..0668afef 100644 --- a/tests/features/chat/conversation/composer/obsidian-context.test.ts +++ b/tests/features/chat/conversation/composer/obsidian-context.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; import { TFile, type App } from "obsidian"; -import { noteCandidates, resolveWikiLinkMention } from "../../../../../src/features/chat/conversation/composer/obsidian-context"; +import { noteCandidates, resolveWikiLinkMention } from "../../../../../src/features/chat/application/composer/obsidian-context"; describe("Obsidian composer context", () => { it("builds note candidates from markdown files", () => { diff --git a/tests/features/chat/conversation/composer/wikilink-context.test.ts b/tests/features/chat/conversation/composer/wikilink-context.test.ts index ca828bb1..ea9b0e52 100644 --- a/tests/features/chat/conversation/composer/wikilink-context.test.ts +++ b/tests/features/chat/conversation/composer/wikilink-context.test.ts @@ -5,7 +5,7 @@ import { parsedWikiLinks, userInputWithWikiLinkMentions, userInputWithWikiLinkMentionsAndSkills, -} from "../../../../../src/features/chat/conversation/composer/wikilink-context"; +} from "../../../../../src/features/chat/application/composer/wikilink-context"; describe("wikilink context", () => { it("parses aliases, subpaths, and duplicate links", () => { diff --git a/tests/features/chat/conversation/pending-requests/controller.test.ts b/tests/features/chat/conversation/pending-requests/controller.test.ts index e1c05b08..88925ed5 100644 --- a/tests/features/chat/conversation/pending-requests/controller.test.ts +++ b/tests/features/chat/conversation/pending-requests/controller.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; import { ChatInboundController } from "../../../../../src/features/chat/app-server/inbound/controller"; -import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; +import { createChatState, createChatStateStore } from "../../../../../src/features/chat/application/state/reducer"; import { PendingRequestController } from "../../../../../src/features/chat/application/pending-requests/controller"; import { toPendingUserInput } from "../../../../../src/features/chat/app-server/requests/user-input"; import type { ServerRequest } from "../../../../../src/app-server/connection/rpc-messages"; diff --git a/tests/features/chat/conversation/turns/composer-submit-actions.test.ts b/tests/features/chat/conversation/turns/composer-submit-actions.test.ts index fc5cbb7e..46e4d4fb 100644 --- a/tests/features/chat/conversation/turns/composer-submit-actions.test.ts +++ b/tests/features/chat/conversation/turns/composer-submit-actions.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it, vi } from "vitest"; import type { AppServerClient } from "../../../../../src/app-server/connection/client"; -import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; -import { createComposerSubmitActions } from "../../../../../src/features/chat/conversation/turns/composer-submit-actions"; +import { createChatState, createChatStateStore } from "../../../../../src/features/chat/application/state/reducer"; +import { createComposerSubmitActions } from "../../../../../src/features/chat/application/conversation/composer-submit-actions"; import type { Thread } from "../../../../../src/domain/threads/model"; function thread(id: string): Thread { diff --git a/tests/features/chat/conversation/turns/optimistic-turn-start.test.ts b/tests/features/chat/conversation/turns/optimistic-turn-start.test.ts index c9ea043d..833fcb23 100644 --- a/tests/features/chat/conversation/turns/optimistic-turn-start.test.ts +++ b/tests/features/chat/conversation/turns/optimistic-turn-start.test.ts @@ -7,8 +7,8 @@ import { localUserMessageItemFromInput, optimisticTurnStart, shouldAcknowledgeTurnStart, -} from "../../../../../src/features/chat/conversation/turns/optimistic-turn-start"; -import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/model/items"; +} from "../../../../../src/features/chat/application/conversation/optimistic-turn-start"; +import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/items"; describe("optimistic turn start helpers", () => { it("builds local user messages without sharing mentioned file arrays", () => { diff --git a/tests/features/chat/conversation/turns/plan-implementation.test.ts b/tests/features/chat/conversation/turns/plan-implementation.test.ts index 63a546d2..1a5af60e 100644 --- a/tests/features/chat/conversation/turns/plan-implementation.test.ts +++ b/tests/features/chat/conversation/turns/plan-implementation.test.ts @@ -1,13 +1,13 @@ import { describe, expect, it, vi } from "vitest"; import type { AppServerClient } from "../../../../../src/app-server/connection/client"; -import { createChatState, createChatStateStore, type ChatStateStore } from "../../../../../src/features/chat/state/reducer"; -import { implementPlanCandidateFromState } from "../../../../../src/features/chat/state/selectors"; +import { createChatState, createChatStateStore, type ChatStateStore } from "../../../../../src/features/chat/application/state/reducer"; +import { implementPlanCandidateFromState } from "../../../../../src/features/chat/application/state/selectors"; import { createPlanImplementation, type PlanImplementationHost, -} from "../../../../../src/features/chat/conversation/turns/plan-implementation"; -import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/model/items"; +} from "../../../../../src/features/chat/application/conversation/plan-implementation"; +import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/items"; const planItem = (id: string): MessageStreamItem => ({ id, diff --git a/tests/features/chat/conversation/turns/slash-command-execution.test.ts b/tests/features/chat/conversation/turns/slash-command-execution.test.ts index 375effb7..4479318a 100644 --- a/tests/features/chat/conversation/turns/slash-command-execution.test.ts +++ b/tests/features/chat/conversation/turns/slash-command-execution.test.ts @@ -1,12 +1,12 @@ import { describe, expect, it, vi } from "vitest"; import type { ThreadGoal } from "../../../../../src/domain/threads/goal"; -import { slashCommandHelpLines, slashCommandHelpSections } from "../../../../../src/features/chat/conversation/composer/slash-commands"; +import { slashCommandHelpLines, slashCommandHelpSections } from "../../../../../src/features/chat/application/composer/slash-commands"; import type { Thread } from "../../../../../src/domain/threads/model"; import { executeSlashCommand, type SlashCommandExecutionContext, -} from "../../../../../src/features/chat/conversation/turns/slash-command-execution"; +} from "../../../../../src/features/chat/application/conversation/slash-command-execution"; function context(overrides: Partial = {}): SlashCommandExecutionContext { return { diff --git a/tests/features/chat/conversation/turns/slash-command-handler.test.ts b/tests/features/chat/conversation/turns/slash-command-handler.test.ts index 88bcf793..3d2f2181 100644 --- a/tests/features/chat/conversation/turns/slash-command-handler.test.ts +++ b/tests/features/chat/conversation/turns/slash-command-handler.test.ts @@ -3,11 +3,11 @@ import { describe, expect, it, vi } from "vitest"; import type { AppServerClient } from "../../../../../src/app-server/connection/client"; import type { CodexInput } from "../../../../../src/app-server/protocol/request-input"; import type { TurnItem, TurnRecord } from "../../../../../src/app-server/protocol/turn"; -import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; +import { createChatState, createChatStateStore } from "../../../../../src/features/chat/application/state/reducer"; import { createSlashCommandHandler, type SlashCommandHandlerHost, -} from "../../../../../src/features/chat/conversation/turns/slash-command-handler"; +} from "../../../../../src/features/chat/application/conversation/slash-command-handler"; import type { Thread } from "../../../../../src/domain/threads/model"; const textInput = (text: string): CodexInput => [{ type: "text", text }]; diff --git a/tests/features/chat/conversation/turns/turn-submission-controller.test.ts b/tests/features/chat/conversation/turns/turn-submission-controller.test.ts index 560cbdba..b003fe14 100644 --- a/tests/features/chat/conversation/turns/turn-submission-controller.test.ts +++ b/tests/features/chat/conversation/turns/turn-submission-controller.test.ts @@ -2,11 +2,11 @@ import { describe, expect, it, vi } from "vitest"; import type { AppServerClient } from "../../../../../src/app-server/connection/client"; import type { CodexInput } from "../../../../../src/app-server/protocol/request-input"; -import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; +import { createChatState, createChatStateStore } from "../../../../../src/features/chat/application/state/reducer"; import { TurnSubmissionController, type TurnSubmissionControllerHost, -} from "../../../../../src/features/chat/conversation/turns/turn-submission-controller"; +} from "../../../../../src/features/chat/application/conversation/turn-submission-controller"; import type { Thread } from "../../../../../src/domain/threads/model"; import { chatStateMessageStreamItems } from "../../support/message-stream"; diff --git a/tests/features/chat/diagnostics.test.ts b/tests/features/chat/diagnostics.test.ts index dd5fec73..1af05047 100644 --- a/tests/features/chat/diagnostics.test.ts +++ b/tests/features/chat/diagnostics.test.ts @@ -7,7 +7,7 @@ import { upsertMcpServerDiagnostic, upsertMcpServerStatusDiagnostics, } from "../../../src/domain/server/diagnostics"; -import { connectionDiagnosticSections, hasDiagnosticIssue } from "../../../src/features/chat/connection/diagnostics-display"; +import { connectionDiagnosticSections, hasDiagnosticIssue } from "../../../src/features/chat/application/connection/diagnostics-display"; describe("connection diagnostics", () => { it("formats base rows, capability probes, and MCP issues for /doctor", () => { diff --git a/tests/features/chat/mcp-status.test.ts b/tests/features/chat/mcp-status.test.ts index 26b5aa4d..eb66acc7 100644 --- a/tests/features/chat/mcp-status.test.ts +++ b/tests/features/chat/mcp-status.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; import type { McpServerStatusSummary } from "../../../src/domain/server/diagnostics"; -import { mcpStatusLines } from "../../../src/features/chat/connection/diagnostics-display"; +import { mcpStatusLines } from "../../../src/features/chat/application/connection/diagnostics-display"; function mcpServer(overrides: Partial = {}): McpServerStatusSummary { return { diff --git a/tests/features/chat/message-stream/model.test.ts b/tests/features/chat/message-stream/model.test.ts index 77f05b73..7d4de96f 100644 --- a/tests/features/chat/message-stream/model.test.ts +++ b/tests/features/chat/message-stream/model.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import { collabAgentStateExecutionState } from "../../../../src/features/chat/app-server/mappers/message-stream/agent-items"; +import { collabAgentStateExecutionState } from "../../../../src/features/chat/domain/message-stream/agent-state"; import { activeAgentRunSummary } from "../../../../src/features/chat/presentation/message-stream/agent-summary"; import { messageStreamLayoutBlocks } from "../../../../src/features/chat/presentation/message-stream/layout"; import { @@ -10,7 +10,7 @@ import { appendPlanDelta, appendToolOutput, upsertMessageStreamItemById, -} from "../../../../src/features/chat/domain/message-stream/operations/updates"; +} from "../../../../src/features/chat/domain/message-stream/updates"; import { taskProgressMessageStreamItem, taskProgressExecutionState, @@ -34,7 +34,7 @@ import { messageStreamItemsFromTurns, } from "../../../../src/features/chat/app-server/mappers/message-stream/turn-items"; import { referencedThreadPrompt } from "../../../../src/domain/threads/reference"; -import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/items"; import type { Thread } from "../../../../src/domain/threads/model"; import type { TurnItem, TurnRecord } from "../../../../src/app-server/protocol/turn"; diff --git a/tests/features/chat/message-stream/presentation/blocks.test.ts b/tests/features/chat/message-stream/presentation/blocks.test.ts index ea0d8b4b..dffe037e 100644 --- a/tests/features/chat/message-stream/presentation/blocks.test.ts +++ b/tests/features/chat/message-stream/presentation/blocks.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; import { messageStreamPresentationBlocks } from "../../../../../src/features/chat/presentation/message-stream/blocks"; -import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/items"; describe("message stream presentation blocks", () => { it("keeps the empty state after the history affordance", () => { diff --git a/tests/features/chat/message-stream/selectors.test.ts b/tests/features/chat/message-stream/selectors.test.ts index 318d4766..d3248ecb 100644 --- a/tests/features/chat/message-stream/selectors.test.ts +++ b/tests/features/chat/message-stream/selectors.test.ts @@ -4,8 +4,8 @@ import { forkCandidatesFromItems, isForkCandidateItem, isRollbackCandidateItem, -} from "../../../../src/features/chat/domain/message-stream/queries/selectors"; -import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/model/items"; +} from "../../../../src/features/chat/domain/message-stream/selectors"; +import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/items"; describe("message stream item selectors", () => { it("selects final assistant messages as fork candidates", () => { diff --git a/tests/features/chat/message-stream/semantics.test.ts b/tests/features/chat/message-stream/semantics.test.ts index ff2bf6d5..79eafe71 100644 --- a/tests/features/chat/message-stream/semantics.test.ts +++ b/tests/features/chat/message-stream/semantics.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest"; import { messageStreamItemFromTurnItem } from "../../../../src/features/chat/app-server/mappers/message-stream/turn-items"; import { messageStreamSemanticClassifications } from "../../../../src/features/chat/domain/message-stream/semantics"; -import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/items"; import type { TurnItem } from "../../../../src/app-server/protocol/turn"; describe("message stream semantic classification", () => { diff --git a/tests/features/chat/panel/surface/message-stream-presenter.test.ts b/tests/features/chat/panel/surface/message-stream-presenter.test.ts index 8cd3f636..8f2c5614 100644 --- a/tests/features/chat/panel/surface/message-stream-presenter.test.ts +++ b/tests/features/chat/panel/surface/message-stream-presenter.test.ts @@ -11,7 +11,7 @@ import { type ChatAction, type ChatState, type ChatStateStore, -} from "../../../../../src/features/chat/state/reducer"; +} from "../../../../../src/features/chat/application/state/reducer"; import { MessageStreamPresenter } from "../../../../../src/features/chat/panel/surface/message-stream-presenter"; import { type ChatMessageStreamSurfaceContext, diff --git a/tests/features/chat/panel/surface/toolbar.test.ts b/tests/features/chat/panel/surface/toolbar.test.ts index a6831913..95e706b9 100644 --- a/tests/features/chat/panel/surface/toolbar.test.ts +++ b/tests/features/chat/panel/surface/toolbar.test.ts @@ -2,9 +2,9 @@ import { describe, expect, it, vi } from "vitest"; -import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; +import { createChatState, createChatStateStore } from "../../../../../src/features/chat/application/state/reducer"; import { createToolbarPanelActions } from "../../../../../src/features/chat/panel/toolbar-actions"; -import type { ThreadManagementActions } from "../../../../../src/features/chat/threads/thread-management-actions"; +import type { ThreadManagementActions } from "../../../../../src/features/chat/application/threads/thread-management-actions"; describe("createToolbarPanelActions", () => { it("tracks archive confirmation and delegates archive actions", async () => { diff --git a/tests/features/chat/protocol/inbound/controller.test.ts b/tests/features/chat/protocol/inbound/controller.test.ts index 6409e9c2..364be31d 100644 --- a/tests/features/chat/protocol/inbound/controller.test.ts +++ b/tests/features/chat/protocol/inbound/controller.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; import { ChatInboundController } from "../../../../../src/features/chat/app-server/inbound/controller"; -import { attachHookRunsToTurn } from "../../../../../src/features/chat/domain/message-stream/operations/updates"; +import { attachHookRunsToTurn } from "../../../../../src/features/chat/domain/message-stream/updates"; import { activeTurnId, chatReducer, @@ -11,7 +11,7 @@ import { type ChatAction, type ChatState, type ChatStateStore, -} from "../../../../../src/features/chat/state/reducer"; +} from "../../../../../src/features/chat/application/state/reducer"; import type { ServerNotification, ServerRequest } from "../../../../../src/app-server/connection/rpc-messages"; import type { Thread as PanelThread } from "../../../../../src/domain/threads/model"; import type { TurnRecord } from "../../../../../src/app-server/protocol/turn"; diff --git a/tests/features/chat/runtime/settings-actions.test.ts b/tests/features/chat/runtime/settings-actions.test.ts index 8daae578..0b5916ed 100644 --- a/tests/features/chat/runtime/settings-actions.test.ts +++ b/tests/features/chat/runtime/settings-actions.test.ts @@ -1,9 +1,12 @@ import { describe, expect, it, vi } from "vitest"; -import { createChatRuntimeSettingsActions, type ChatRuntimeSettingsActions } from "../../../../src/features/chat/runtime/settings-actions"; -import { createChatState, createChatStateStore, type ChatState } from "../../../../src/features/chat/state/reducer"; -import { runtimeSnapshotForChatState } from "../../../../src/features/chat/runtime/snapshot"; -import type { ActiveThreadSettingsAppliedAction } from "../../../../src/features/chat/state/actions"; +import { + createChatRuntimeSettingsActions, + type ChatRuntimeSettingsActions, +} from "../../../../src/features/chat/application/runtime/settings-actions"; +import { createChatState, createChatStateStore, type ChatState } from "../../../../src/features/chat/application/state/reducer"; +import { runtimeSnapshotForChatState } from "../../../../src/features/chat/application/runtime/snapshot"; +import type { ActiveThreadSettingsAppliedAction } from "../../../../src/features/chat/application/state/actions"; import type { AppServerClient } from "../../../../src/app-server/connection/client"; import { emptyRuntimeConfigSnapshot } from "../../../../src/app-server/protocol/runtime-config"; import type { ModelMetadata } from "../../../../src/domain/catalog/metadata"; diff --git a/tests/features/chat/state-reducer.test.ts b/tests/features/chat/state-reducer.test.ts index 1d5f793b..cd785004 100644 --- a/tests/features/chat/state-reducer.test.ts +++ b/tests/features/chat/state-reducer.test.ts @@ -9,10 +9,10 @@ import { pendingTurnStart, transitionChatTurnLifecycleState, type ChatState, -} from "../../../src/features/chat/state/reducer"; -import { messageStreamItems } from "../../../src/features/chat/state/message-stream"; +} from "../../../src/features/chat/application/state/reducer"; +import { messageStreamItems } from "../../../src/features/chat/application/state/message-stream"; import type { ThreadGoal } from "../../../src/domain/threads/goal"; -import type { MessageStreamItem } from "../../../src/features/chat/domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../../src/features/chat/domain/message-stream/items"; import type { Thread } from "../../../src/domain/threads/model"; import { chatStateMessageStreamItems, setChatStateMessageStreamItems } from "./support/message-stream"; diff --git a/tests/features/chat/state/message-stream-selectors.test.ts b/tests/features/chat/state/message-stream-selectors.test.ts index d6b8d4b7..ee6dd34e 100644 --- a/tests/features/chat/state/message-stream-selectors.test.ts +++ b/tests/features/chat/state/message-stream-selectors.test.ts @@ -1,13 +1,13 @@ import { describe, expect, it } from "vitest"; -import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/items"; import { initialChatMessageStreamState, messageStreamRollbackCandidate, messageStreamTurnsAfterTurnId, messageStreamTurnIds, messageStreamWithActiveTurnItems, -} from "../../../../src/features/chat/state/message-stream"; +} from "../../../../src/features/chat/application/state/message-stream"; describe("message stream selectors", () => { it("counts turns after a turn id from message stream state", () => { diff --git a/tests/features/chat/support/message-stream.ts b/tests/features/chat/support/message-stream.ts index 43764d69..da9bb551 100644 --- a/tests/features/chat/support/message-stream.ts +++ b/tests/features/chat/support/message-stream.ts @@ -1,6 +1,6 @@ -import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/model/items"; -import { messageStreamItems, messageStreamWithItems } from "../../../../src/features/chat/state/message-stream"; -import type { ChatState } from "../../../../src/features/chat/state/reducer"; +import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/items"; +import { messageStreamItems, messageStreamWithItems } from "../../../../src/features/chat/application/state/message-stream"; +import type { ChatState } from "../../../../src/features/chat/application/state/reducer"; export function chatStateMessageStreamItems(state: Pick): readonly MessageStreamItem[] { return messageStreamItems(state.messageStream); diff --git a/tests/features/chat/threads/auto-title-controller.test.ts b/tests/features/chat/threads/auto-title-controller.test.ts index 177c566e..9b1c8910 100644 --- a/tests/features/chat/threads/auto-title-controller.test.ts +++ b/tests/features/chat/threads/auto-title-controller.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it, vi } from "vitest"; import type { AppServerClient } from "../../../../src/app-server/connection/client"; -import { createChatStateStore } from "../../../../src/features/chat/state/reducer"; -import { AutoTitleController } from "../../../../src/features/chat/threads/auto-title-controller"; +import { createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; +import { AutoTitleController } from "../../../../src/features/chat/application/threads/auto-title-controller"; import type { Thread } from "../../../../src/domain/threads/model"; import { DEFAULT_SETTINGS } from "../../../../src/settings/model"; import { deferred } from "../../../support/async"; diff --git a/tests/features/chat/threads/goal-actions.test.ts b/tests/features/chat/threads/goal-actions.test.ts index a8cda3fe..7b0693ab 100644 --- a/tests/features/chat/threads/goal-actions.test.ts +++ b/tests/features/chat/threads/goal-actions.test.ts @@ -2,8 +2,8 @@ import { describe, expect, it, vi } from "vitest"; import type { AppServerClient } from "../../../../src/app-server/connection/client"; import type { ThreadGoal } from "../../../../src/domain/threads/goal"; -import { createGoalActions } from "../../../../src/features/chat/threads/goal-actions"; -import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; +import { createGoalActions } from "../../../../src/features/chat/application/threads/goal-actions"; +import { createChatState, createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; import { deferred } from "../../../support/async"; describe("createGoalActions", () => { diff --git a/tests/features/chat/threads/history-controller.test.ts b/tests/features/chat/threads/history-controller.test.ts index 56274abd..71df351c 100644 --- a/tests/features/chat/threads/history-controller.test.ts +++ b/tests/features/chat/threads/history-controller.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; -import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; -import { HistoryController } from "../../../../src/features/chat/threads/history-controller"; +import { createChatState, createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; +import { HistoryController } from "../../../../src/features/chat/application/threads/history-controller"; import type { AppServerClient } from "../../../../src/app-server/connection/client"; import type { TurnItem, TurnRecord } from "../../../../src/app-server/protocol/turn"; import { deferred } from "../../../support/async"; diff --git a/tests/features/chat/threads/identity-sync.test.ts b/tests/features/chat/threads/identity-sync.test.ts index 74d44aad..70dbedf4 100644 --- a/tests/features/chat/threads/identity-sync.test.ts +++ b/tests/features/chat/threads/identity-sync.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it, vi } from "vitest"; -import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; -import { createIdentitySync } from "../../../../src/features/chat/threads/identity-sync"; -import type { RestorationController } from "../../../../src/features/chat/threads/restoration-controller"; -import type { RestoredThreadPlaceholderState } from "../../../../src/features/chat/lifecycle"; +import { createChatState, createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; +import { createIdentitySync } from "../../../../src/features/chat/application/threads/identity-sync"; +import type { RestorationController } from "../../../../src/features/chat/application/threads/restoration-controller"; +import type { RestoredThreadPlaceholderState } from "../../../../src/features/chat/application/lifecycle"; import type { Thread } from "../../../../src/domain/threads/model"; function thread(id: string, name: string | null = null): Thread { diff --git a/tests/features/chat/threads/rename-editor-controller.test.ts b/tests/features/chat/threads/rename-editor-controller.test.ts index 222cb59a..0763ce91 100644 --- a/tests/features/chat/threads/rename-editor-controller.test.ts +++ b/tests/features/chat/threads/rename-editor-controller.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; -import { createChatStateStore } from "../../../../src/features/chat/state/reducer"; -import { ThreadRenameEditorController } from "../../../../src/features/chat/threads/rename-editor-controller"; +import { createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; +import { ThreadRenameEditorController } from "../../../../src/features/chat/application/threads/rename-editor-controller"; import type { AppServerClient } from "../../../../src/app-server/connection/client"; import type { Thread } from "../../../../src/domain/threads/model"; import type { TurnItem, TurnRecord } from "../../../../src/app-server/protocol/turn"; diff --git a/tests/features/chat/threads/restoration-controller.test.ts b/tests/features/chat/threads/restoration-controller.test.ts index 88cad8e4..1a9a25ce 100644 --- a/tests/features/chat/threads/restoration-controller.test.ts +++ b/tests/features/chat/threads/restoration-controller.test.ts @@ -2,9 +2,9 @@ import { describe, expect, it, vi } from "vitest"; -import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; -import { RestorationController } from "../../../../src/features/chat/threads/restoration-controller"; -import { createChatViewDeferredTasks } from "../../../../src/features/chat/lifecycle"; +import { createChatState, createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; +import { RestorationController } from "../../../../src/features/chat/application/threads/restoration-controller"; +import { createChatViewDeferredTasks } from "../../../../src/features/chat/host/lifecycle"; import { deferred } from "../../../support/async"; describe("RestorationController", () => { diff --git a/tests/features/chat/threads/resume-controller.test.ts b/tests/features/chat/threads/resume-controller.test.ts index d57fa29f..8035fd69 100644 --- a/tests/features/chat/threads/resume-controller.test.ts +++ b/tests/features/chat/threads/resume-controller.test.ts @@ -1,11 +1,11 @@ import { describe, expect, it, vi } from "vitest"; import type { AppServerClient } from "../../../../src/app-server/connection/client"; -import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; -import type { RestorationController } from "../../../../src/features/chat/threads/restoration-controller"; -import { ResumeController } from "../../../../src/features/chat/threads/resume-controller"; -import type { HistoryController } from "../../../../src/features/chat/threads/history-controller"; -import { ChatResumeWorkTracker } from "../../../../src/features/chat/lifecycle"; +import { createChatState, createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; +import type { RestorationController } from "../../../../src/features/chat/application/threads/restoration-controller"; +import { ResumeController } from "../../../../src/features/chat/application/threads/resume-controller"; +import type { HistoryController } from "../../../../src/features/chat/application/threads/history-controller"; +import { ChatResumeWorkTracker } from "../../../../src/features/chat/application/lifecycle"; import type { Thread as PanelThread } from "../../../../src/domain/threads/model"; import type { ThreadTokenUsage } from "../../../../src/app-server/protocol/runtime-metrics"; import type { TurnItem, TurnRecord } from "../../../../src/app-server/protocol/turn"; diff --git a/tests/features/chat/threads/resume.test.ts b/tests/features/chat/threads/resume.test.ts index 5336028a..b251b9ca 100644 --- a/tests/features/chat/threads/resume.test.ts +++ b/tests/features/chat/threads/resume.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; import type { ThreadActivationSnapshot } from "../../../../src/app-server/services/thread-activation"; -import { resumedThreadAction } from "../../../../src/features/chat/threads/resume"; +import { resumedThreadAction } from "../../../../src/features/chat/application/threads/resume"; import type { Thread } from "../../../../src/domain/threads/model"; describe("chat thread resume helpers", () => { diff --git a/tests/features/chat/threads/selection-actions.test.ts b/tests/features/chat/threads/selection-actions.test.ts index dafe1552..2ef7989c 100644 --- a/tests/features/chat/threads/selection-actions.test.ts +++ b/tests/features/chat/threads/selection-actions.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; -import { createChatState, createChatStateStore, type ChatStateStore } from "../../../../src/features/chat/state/reducer"; -import { createSelectionActions, type SelectionActionsHost } from "../../../../src/features/chat/threads/selection-actions"; +import { createChatState, createChatStateStore, type ChatStateStore } from "../../../../src/features/chat/application/state/reducer"; +import { createSelectionActions, type SelectionActionsHost } from "../../../../src/features/chat/application/threads/selection-actions"; function resumeThreadState(stateStore: ChatStateStore, threadId: string): void { stateStore.dispatch({ diff --git a/tests/features/chat/threads/thread-management-actions.test.ts b/tests/features/chat/threads/thread-management-actions.test.ts index 56b559e4..8df12d58 100644 --- a/tests/features/chat/threads/thread-management-actions.test.ts +++ b/tests/features/chat/threads/thread-management-actions.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import type { AppServerClient } from "../../../../src/app-server/connection/client"; import type { ThreadRecord } from "../../../../src/app-server/protocol/thread"; import type { ArchiveExportAdapter } from "../../../../src/features/thread-export/archive-markdown"; -import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; +import { createChatState, createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; import { archiveThread, compactThread, @@ -12,8 +12,8 @@ import { rollbackThread as rollbackThreadAction, type ThreadManagementActions, type ThreadManagementActionsHost, -} from "../../../../src/features/chat/threads/thread-management-actions"; -import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/model/items"; +} from "../../../../src/features/chat/application/threads/thread-management-actions"; +import type { MessageStreamItem } from "../../../../src/features/chat/domain/message-stream/items"; import { DEFAULT_SETTINGS } from "../../../../src/settings/model"; import { notices } from "../../../mocks/obsidian"; import { deferred, waitForAsyncWork } from "../../../support/async"; diff --git a/tests/features/chat/threads/title-context.test.ts b/tests/features/chat/threads/title-context.test.ts index 1ec34b58..c02d995f 100644 --- a/tests/features/chat/threads/title-context.test.ts +++ b/tests/features/chat/threads/title-context.test.ts @@ -5,7 +5,7 @@ import { describe, expect, it } from "vitest"; import { firstThreadTitleContextFromMessageStreamItems, threadTitleContextFromMessageStreamItems, -} from "../../../../src/features/chat/threads/title-context"; +} from "../../../../src/features/chat/application/threads/title-context"; describe("chat thread title context", () => { it("extracts title context from streamed message stream items when completed turn items are not loaded", () => { diff --git a/tests/features/chat/threads/title-display.test.ts b/tests/features/chat/threads/title-display.test.ts index 8d5e73e4..7ada39f2 100644 --- a/tests/features/chat/threads/title-display.test.ts +++ b/tests/features/chat/threads/title-display.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; import type { Thread } from "../../../../src/domain/threads/model"; -import { codexPanelDisplayTitle } from "../../../../src/features/chat/threads/title-display"; +import { codexPanelDisplayTitle } from "../../../../src/features/chat/application/threads/title-display"; describe("chat thread title display", () => { it("formats Codex panel display titles from the active thread", () => { diff --git a/tests/features/chat/ui/message-stream/blocks-and-messages.test.tsx b/tests/features/chat/ui/message-stream/blocks-and-messages.test.tsx index d389b010..9a0bd3ee 100644 --- a/tests/features/chat/ui/message-stream/blocks-and-messages.test.tsx +++ b/tests/features/chat/ui/message-stream/blocks-and-messages.test.tsx @@ -4,8 +4,8 @@ import { describe, expect, it, vi } from "vitest"; import { act } from "preact/test-utils"; import { MarkdownRenderer } from "obsidian"; -import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/model/items"; -import { implementPlanCandidateFromState } from "../../../../../src/features/chat/state/selectors"; +import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/items"; +import { implementPlanCandidateFromState } from "../../../../../src/features/chat/application/state/selectors"; import { MarkdownMessageRenderer } from "../../../../../src/features/chat/ui/message-stream/markdown-renderer"; import { deferred } from "../../../../support/async"; import { topLevelDetailsSummaries } from "../../../../support/dom"; diff --git a/tests/features/chat/ui/message-stream/pending-requests.test.tsx b/tests/features/chat/ui/message-stream/pending-requests.test.tsx index f873aaca..db0be379 100644 --- a/tests/features/chat/ui/message-stream/pending-requests.test.tsx +++ b/tests/features/chat/ui/message-stream/pending-requests.test.tsx @@ -6,7 +6,7 @@ import type { PendingRequestBlockSnapshot } from "../../../../../src/features/ch import { pendingApprovalViewModel } from "../../../../../src/features/chat/presentation/pending-requests/view-model"; import type { PendingApproval, PendingUserInput } from "../../../../../src/features/chat/domain/pending-requests/model"; import type { PendingRequestBlockContext } from "../../../../../src/features/chat/ui/message-stream/context"; -import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/items"; import { changeInputValue } from "../../../../support/dom"; import "./setup"; import { diff --git a/tests/features/chat/ui/message-stream/test-helpers.tsx b/tests/features/chat/ui/message-stream/test-helpers.tsx index 7ab0ffe2..33ef9ed3 100644 --- a/tests/features/chat/ui/message-stream/test-helpers.tsx +++ b/tests/features/chat/ui/message-stream/test-helpers.tsx @@ -3,13 +3,17 @@ import type { ComponentChild as UiNode } from "preact"; import { act } from "preact/test-utils"; import type { PendingApproval, PendingUserInput } from "../../../../../src/features/chat/domain/pending-requests/model"; -import { pendingRequestBlockSnapshotFromRequests } from "../../../../../src/features/chat/presentation/pending-requests/snapshot"; -import type { PendingRequestBlockActions } from "../../../../../src/features/chat/presentation/pending-requests/view-model"; +import { pendingRequestBlockSnapshotFromState } from "../../../../../src/features/chat/presentation/pending-requests/snapshot"; +import type { PendingRequestBlockActions } from "../../../../../src/features/chat/application/pending-requests/block"; import { pendingRequestBlockNode } from "../../../../../src/features/chat/ui/message-stream/pending-request-block"; -import { activeTurnId, type ChatDisclosureUiState, type ChatTurnLifecycleState } from "../../../../../src/features/chat/state/reducer"; +import { + activeTurnId, + type ChatDisclosureUiState, + type ChatTurnLifecycleState, +} from "../../../../../src/features/chat/application/state/reducer"; import { messageStreamBlocks as rawMessageStreamBlocks } from "../../../../../src/features/chat/ui/message-stream/stream-blocks"; import type { MessageStreamBlock, MessageStreamContext } from "../../../../../src/features/chat/ui/message-stream/context"; -import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/items"; import { messageStreamViewBlocks } from "../../../../../src/features/chat/presentation/message-stream/view-model"; import { MessageStreamViewport } from "../../../../../src/features/chat/ui/message-stream/viewport"; import { renderUiRoot, unmountUiRoot } from "../../../../../src/shared/ui/ui-root"; @@ -159,7 +163,7 @@ export function renderPendingRequestNode( consumeAutoFocus?: () => boolean, autoFocusSignature = "", ): void { - const snapshot = pendingRequestBlockSnapshotFromRequests({ + const snapshot = pendingRequestBlockSnapshotFromState({ approvals, pendingUserInputs, userInputDrafts: drafts.values, diff --git a/tests/features/chat/ui/message-stream/work-log.test.tsx b/tests/features/chat/ui/message-stream/work-log.test.tsx index b9cb4310..3cd0c11c 100644 --- a/tests/features/chat/ui/message-stream/work-log.test.tsx +++ b/tests/features/chat/ui/message-stream/work-log.test.tsx @@ -2,7 +2,7 @@ import { describe, expect, it, vi } from "vitest"; -import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/model/items"; +import type { MessageStreamItem } from "../../../../../src/features/chat/domain/message-stream/items"; import { topLevelDetailsSummaries } from "../../../../support/dom"; import "./setup"; import { diff --git a/tests/features/chat/ui/renderers/composer.test.ts b/tests/features/chat/ui/renderers/composer.test.ts index ab94904e..b5bed937 100644 --- a/tests/features/chat/ui/renderers/composer.test.ts +++ b/tests/features/chat/ui/renderers/composer.test.ts @@ -9,7 +9,7 @@ import { syncComposerHeight, type ComposerCallbacks, } from "../../../../../src/features/chat/ui/composer"; -import type { ComposerSuggestion } from "../../../../../src/features/chat/conversation/composer/suggestions"; +import type { ComposerSuggestion } from "../../../../../src/features/chat/application/composer/suggestions"; import type { ComposerMetaViewModel } from "../../../../../src/features/chat/ui/composer"; import { renderUiRoot } from "../../../../../src/shared/ui/ui-root"; import { waitForAsyncWork } from "../../../../support/async"; diff --git a/tests/features/chat/ui/renderers/turn-diff.test.ts b/tests/features/chat/ui/renderers/turn-diff.test.ts index 962dd025..ad6075ae 100644 --- a/tests/features/chat/ui/renderers/turn-diff.test.ts +++ b/tests/features/chat/ui/renderers/turn-diff.test.ts @@ -3,9 +3,9 @@ import { describe, expect, it, vi } from "vitest"; import type { WorkspaceLeaf } from "obsidian"; -import { persistedChatTurnDiffViewState } from "../../../../../src/features/chat/turn-diff/model"; -import { renderChatTurnDiffView } from "../../../../../src/features/chat/turn-diff/render"; -import { CodexChatTurnDiffView } from "../../../../../src/features/chat/turn-diff/view"; +import { persistedChatTurnDiffViewState } from "../../../../../src/features/chat/domain/turn-diff"; +import { renderChatTurnDiffView } from "../../../../../src/features/chat/ui/turn-diff/render"; +import { CodexChatTurnDiffView } from "../../../../../src/features/chat/ui/turn-diff/view"; import { installObsidianDomShims } from "../../../../support/dom"; installObsidianDomShims(); diff --git a/tests/features/chat/ui/shell.test.tsx b/tests/features/chat/ui/shell.test.tsx index d246e4b8..35d86faa 100644 --- a/tests/features/chat/ui/shell.test.tsx +++ b/tests/features/chat/ui/shell.test.tsx @@ -3,8 +3,8 @@ import { describe, expect, it, vi } from "vitest"; import { act } from "preact/test-utils"; -import { createChatStateStore } from "../../../../src/features/chat/state/reducer"; -import { messageStreamItems } from "../../../../src/features/chat/state/message-stream"; +import { createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; +import { messageStreamItems } from "../../../../src/features/chat/application/state/message-stream"; import { renderChatPanelShell, unmountChatPanelShell, type ChatPanelShellParts } from "../../../../src/features/chat/ui/shell"; import type { ChatPanelComposerShellState, ChatPanelMessageStreamShellState } from "../../../../src/features/chat/ui/shell-state"; import type { ChatPanelSurface } from "../../../../src/features/chat/panel/surface/model"; diff --git a/tests/features/chat/ui/toolbar-archive-state.test.tsx b/tests/features/chat/ui/toolbar-archive-state.test.tsx index 35dc41eb..0595efc2 100644 --- a/tests/features/chat/ui/toolbar-archive-state.test.tsx +++ b/tests/features/chat/ui/toolbar-archive-state.test.tsx @@ -4,10 +4,10 @@ import { describe, expect, it, vi } from "vitest"; import { act } from "preact/test-utils"; import type { Thread } from "../../../../src/domain/threads/model"; -import { createChatStateStore } from "../../../../src/features/chat/state/reducer"; +import { createChatStateStore } from "../../../../src/features/chat/application/state/reducer"; import { createToolbarPanelActions, type ToolbarPanelActions } from "../../../../src/features/chat/panel/toolbar-actions"; import type { ChatPanelSurface, ChatPanelToolbarSurface } from "../../../../src/features/chat/panel/surface/model"; -import type { ThreadManagementActions } from "../../../../src/features/chat/threads/thread-management-actions"; +import type { ThreadManagementActions } from "../../../../src/features/chat/application/threads/thread-management-actions"; import { renderChatPanelShell, unmountChatPanelShell, type ChatPanelShellParts } from "../../../../src/features/chat/ui/shell"; import { installObsidianDomShims } from "../../../support/dom"; diff --git a/tests/features/chat/view-connection.test.ts b/tests/features/chat/view-connection.test.ts index b8a1d2f8..7fe22c3c 100644 --- a/tests/features/chat/view-connection.test.ts +++ b/tests/features/chat/view-connection.test.ts @@ -3,7 +3,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { DEFAULT_SETTINGS } from "../../../src/settings/model"; -import type { CodexChatHost } from "../../../src/features/chat/chat-host"; +import type { CodexChatHost } from "../../../src/features/chat/application/chat-host"; import { createServerDiagnostics } from "../../../src/domain/server/diagnostics"; import { emptyRuntimeConfigSnapshot } from "../../../src/app-server/protocol/runtime-config"; import type { ThreadRecord } from "../../../src/app-server/protocol/thread"; @@ -1273,7 +1273,7 @@ async function chatView( options: { activeLeafChangeListeners?: ((leaf: unknown) => void)[]; host?: CodexChatHost; requestSaveLayout?: () => void } = {}, ) { const host = options.host ?? chatHost(); - const { CodexChatView } = await import("../../../src/features/chat/view"); + const { CodexChatView } = await import("../../../src/features/chat/host/view"); const containerEl = document.createElement("div"); document.body.appendChild(containerEl); containerEl.createDiv(); diff --git a/tests/features/chat/view-lifecycle.test.ts b/tests/features/chat/view-lifecycle.test.ts index 853899fc..1bd3b08a 100644 --- a/tests/features/chat/view-lifecycle.test.ts +++ b/tests/features/chat/view-lifecycle.test.ts @@ -5,12 +5,12 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import { ChatConnectionWorkTracker, ChatResumeWorkTracker, - createChatViewDeferredTasks, transitionChatConnectionLifecycle, transitionChatResumeLifecycle, transitionRestoredThreadLifecycle, type ActiveChatConnection, -} from "../../../src/features/chat/lifecycle"; +} from "../../../src/features/chat/application/lifecycle"; +import { createChatViewDeferredTasks } from "../../../src/features/chat/host/lifecycle"; describe("createChatViewDeferredTasks", () => { beforeEach(() => { diff --git a/tests/features/chat/view-model.test.ts b/tests/features/chat/view-model.test.ts index f8a91217..666af814 100644 --- a/tests/features/chat/view-model.test.ts +++ b/tests/features/chat/view-model.test.ts @@ -6,13 +6,13 @@ import { type ConfigReadResult, type RuntimeConfigSnapshot, } from "../../../src/app-server/protocol/runtime-config"; -import { createChatState } from "../../../src/features/chat/state/reducer"; +import { createChatState } from "../../../src/features/chat/application/state/reducer"; import { chatPanelComposerProjection, composerMetaViewModel, composerPlaceholder } from "../../../src/features/chat/panel/surface/composer"; -import { effortStatusLines, modelStatusLines, statusSummaryLines } from "../../../src/features/chat/runtime/status"; +import { effortStatusLines, modelStatusLines, statusSummaryLines } from "../../../src/features/chat/presentation/runtime/status"; import { runtimeComposerChoices } from "../../../src/features/chat/panel/surface/composer"; -import { runtimeSnapshotForChatState } from "../../../src/features/chat/runtime/snapshot"; +import { runtimeSnapshotForChatState } from "../../../src/features/chat/application/runtime/snapshot"; import { chatPanelToolbarProjection, toolbarStateProjection } from "../../../src/features/chat/panel/surface/toolbar"; -import type { ChatState } from "../../../src/features/chat/state/reducer"; +import type { ChatState } from "../../../src/features/chat/application/state/reducer"; import type { ModelMetadata } from "../../../src/domain/catalog/metadata"; import type { Thread } from "../../../src/domain/threads/model"; import { chatPanelGoalProjection, chatPanelGoalViewModel } from "../../../src/features/chat/panel/surface/goal"; diff --git a/tests/main.test.ts b/tests/main.test.ts index 9f71ea09..ea42d247 100644 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -6,8 +6,8 @@ import { FileSystemAdapter } from "obsidian"; import { VIEW_TYPE_CODEX_PANEL } from "../src/constants"; import { DEFAULT_SETTINGS } from "../src/settings/model"; import type CodexPanelPlugin from "../src/main"; -import type { CodexChatView } from "../src/features/chat/view"; -import type { CodexChatHost } from "../src/features/chat/chat-host"; +import type { CodexChatView } from "../src/features/chat/host/view"; +import type { CodexChatHost } from "../src/features/chat/application/chat-host"; import type { Thread } from "../src/domain/threads/model"; import type { SharedAppServerCache } from "../src/app-server/services/shared-cache"; import type { SharedAppServerCacheContext } from "../src/app-server/services/shared-cache-state"; @@ -85,7 +85,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { it("loads and focuses a deferred restored panel before opening another panel", async () => { const restoredLeaf = leaf({ state: { threadId: "thread-1", threadTitle: "Restored thread" } }); const plugin = await pluginWithLeaves([restoredLeaf]); - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); restoredLeaf.loadIfDeferred.mockImplementation(async () => { restoredLeaf.view = chatView(CodexChatView, restoredLeaf); }); @@ -97,7 +97,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("focuses an already open thread before reusing an empty panel", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const openLeaf = leaf(); openLeaf.view = chatView(CodexChatView, openLeaf); const openView = openLeaf.view as CodexChatView; @@ -125,7 +125,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("reuses an idle empty panel before opening a new panel", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const busyLeaf = leaf(); busyLeaf.view = chatView(CodexChatView, busyLeaf); const busyView = busyLeaf.view as CodexChatView; @@ -161,7 +161,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("opens picker Enter selections in the most recent panel when the thread is not already open", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const olderLeaf = leaf(); olderLeaf.view = chatView(CodexChatView, olderLeaf); const olderView = olderLeaf.view as CodexChatView; @@ -180,7 +180,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("opens picker Enter selections in the active Codex panel before the right-sidebar fallback", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const fallbackLeaf = leaf(); fallbackLeaf.view = chatView(CodexChatView, fallbackLeaf); const fallbackView = fallbackLeaf.view as CodexChatView; @@ -200,7 +200,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("focuses an already open thread before picker Enter overwrites the current panel", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const openLeaf = leaf(); openLeaf.view = chatView(CodexChatView, openLeaf); const openView = openLeaf.view as CodexChatView; @@ -223,7 +223,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { const restoredLeaf = leaf({ state: { threadId: "restored-thread", threadTitle: "Restored thread" } }); const plugin = await pluginWithLeaves([restoredLeaf]); (plugin.app.workspace.getMostRecentLeaf as ReturnType).mockReturnValue(restoredLeaf); - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const view = chatView(CodexChatView, restoredLeaf); const openThread = vi.spyOn(view, "openThread").mockResolvedValue(undefined); const focusThread = vi.spyOn(view, "focusThread").mockResolvedValue(undefined); @@ -242,7 +242,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { const newLeaf = leaf(); const plugin = await pluginWithLeaves([]); (plugin.app.workspace.getRightLeaf as ReturnType).mockReturnValue(newLeaf); - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const view = chatView(CodexChatView, newLeaf); newLeaf.setViewState.mockImplementation(async () => { newLeaf.view = view; @@ -259,7 +259,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("activates the active Codex panel instead of the first existing panel", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const firstLeaf = leaf(); firstLeaf.view = chatView(CodexChatView, firstLeaf); const firstView = firstLeaf.view as CodexChatView; @@ -284,7 +284,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("marks snapshots for the last focused Codex panel", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const firstLeaf = leaf(); firstLeaf.view = chatView(CodexChatView, firstLeaf); vi.spyOn(firstLeaf.view as CodexChatView, "openPanelSnapshot").mockReturnValue( @@ -316,7 +316,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("initially marks the active Codex panel before focus events arrive", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const firstLeaf = leaf(); firstLeaf.view = chatView(CodexChatView, firstLeaf); vi.spyOn(firstLeaf.view as CodexChatView, "openPanelSnapshot").mockReturnValue( @@ -336,7 +336,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("initially falls back to the most recent right sidebar Codex panel", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const recentLeaf = leaf(); recentLeaf.view = chatView(CodexChatView, recentLeaf); vi.spyOn(recentLeaf.view as CodexChatView, "openPanelSnapshot").mockReturnValue( @@ -360,7 +360,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { const newLeaf = leaf(); const plugin = await pluginWithLeaves([]); (plugin.app.workspace.getRightLeaf as ReturnType).mockReturnValue(newLeaf); - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const view = chatView(CodexChatView, newLeaf); newLeaf.setViewState.mockImplementation(async () => { newLeaf.view = view; @@ -388,7 +388,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("closes matching chat panels only when archive notification requests it", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const restoredMatchingLeaf = leaf({ state: { threadId: "thread-1", threadTitle: "Restored" } }); const matchingLeaf = leaf(); matchingLeaf.view = chatView(CodexChatView, matchingLeaf); @@ -501,7 +501,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("refreshes shared thread lists from a connected chat panel", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const disconnectedLeaf = leaf(); disconnectedLeaf.view = chatView(CodexChatView, disconnectedLeaf); const disconnectedView = disconnectedLeaf.view as CodexChatView; @@ -523,7 +523,7 @@ describe("CodexPanelPlugin boot restored panel loading", () => { }); it("refreshes shared thread lists from a remaining connected panel after the archived panel is detached", async () => { - const { CodexChatView } = await import("../src/features/chat/view"); + const { CodexChatView } = await import("../src/features/chat/host/view"); const sourceLeaf = leaf(); sourceLeaf.view = chatView(CodexChatView, sourceLeaf); const sourceView = sourceLeaf.view as CodexChatView; diff --git a/tests/runtime/override-commands.test.ts b/tests/runtime/override-commands.test.ts index 18cc5af2..e68e1094 100644 --- a/tests/runtime/override-commands.test.ts +++ b/tests/runtime/override-commands.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; -import { collaborationModeLabel } from "../../src/features/chat/runtime/messages"; -import { nextCollaborationMode } from "../../src/features/chat/runtime/pending-settings"; +import { collaborationModeLabel } from "../../src/features/chat/presentation/runtime/messages"; +import { nextCollaborationMode } from "../../src/features/chat/domain/runtime/pending-settings"; describe("runtime collaboration mode", () => { it("toggles between Default and Plan mode", () => { diff --git a/tests/runtime/runtime-settings.test.ts b/tests/runtime/runtime-settings.test.ts index 43549e9f..9822a49e 100644 --- a/tests/runtime/runtime-settings.test.ts +++ b/tests/runtime/runtime-settings.test.ts @@ -6,13 +6,12 @@ import { type RuntimeConfigSnapshot, } from "../../src/app-server/protocol/runtime-config"; import type { ModelMetadata } from "../../src/domain/catalog/metadata"; +import { modelOverrideMessage, reasoningEffortOverrideMessage } from "../../src/features/chat/application/runtime/messages"; +import { compactModelLabel, compactReasoningEffortLabel } from "../../src/features/chat/presentation/runtime/messages"; import { - compactModelLabel, - compactReasoningEffortLabel, - modelOverrideMessage, - reasoningEffortOverrideMessage, -} from "../../src/features/chat/runtime/messages"; -import { parseModelOverride, parseReasoningEffortOverride } from "../../src/features/chat/conversation/turns/runtime-setting-commands"; + parseModelOverride, + parseReasoningEffortOverride, +} from "../../src/features/chat/application/conversation/runtime-setting-commands"; import { autoReviewActive, currentApprovalsReviewer, @@ -23,21 +22,21 @@ import { fastRuntimeServiceTierRequestValue, runtimeConfigOrDefault, supportedReasoningEfforts, -} from "../../src/features/chat/runtime/effective"; -import type { RuntimeSnapshot } from "../../src/features/chat/runtime/snapshot"; -import { resetRuntimeSettingToConfig, setPendingRuntimeSetting } from "../../src/features/chat/runtime/pending-settings"; +} from "../../src/features/chat/domain/runtime/effective"; +import type { RuntimeSnapshot } from "../../src/features/chat/application/runtime/snapshot"; +import { resetRuntimeSettingToConfig, setPendingRuntimeSetting } from "../../src/features/chat/domain/runtime/pending-settings"; import { pendingRuntimeSettingsPatch, requestedTurnCollaborationModeSettings, serviceTierRequestForThreadStart, -} from "../../src/features/chat/runtime/thread-settings-update"; +} from "../../src/features/chat/application/runtime/thread-settings-update"; import { contextSummary, fastModeLabel, runtimeConfigSections, rateLimitSummary, serviceTierLabel, -} from "../../src/features/chat/runtime/status"; +} from "../../src/features/chat/presentation/runtime/status"; describe("runtime settings", () => { it("parses model overrides", () => { diff --git a/tests/runtime/service-tier-state.test.ts b/tests/runtime/service-tier-state.test.ts index d8e721cf..95e3d26f 100644 --- a/tests/runtime/service-tier-state.test.ts +++ b/tests/runtime/service-tier-state.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import { isFastServiceTier } from "../../src/features/chat/runtime/effective"; +import { isFastServiceTier } from "../../src/features/chat/domain/runtime/effective"; describe("service tier runtime state", () => { it("recognizes Codex fast tier aliases without rejecting other tier ids", () => { diff --git a/tests/scripts/eslint-config.test.ts b/tests/scripts/eslint-config.test.ts index cc5c622c..9de88bf3 100644 --- a/tests/scripts/eslint-config.test.ts +++ b/tests/scripts/eslint-config.test.ts @@ -10,7 +10,7 @@ describe("eslint config", () => { "reports imperative DOM writes in non-bridge source files", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` export function setStatus(element: HTMLElement): void { element.textContent = "Loading"; @@ -25,7 +25,7 @@ export function setStatus(element: HTMLElement): void { it("reports Obsidian HTMLElement mutation helpers in non-bridge source files", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` export function setStatus(element: HTMLElement): void { element.addClass("is-ready"); @@ -51,7 +51,7 @@ export function renderIcon(element: HTMLElement): void { it("does not confuse plain value properties with DOM writes", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` interface Box { value: string; @@ -85,7 +85,7 @@ export function setSignalStatus(): string { it("keeps chat signals inside the shell-state adapter", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` import { signal } from "@preact/signals"; @@ -133,9 +133,9 @@ export type Turn = TurnRecord; it("reports direct ChatState alias mutation", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` -import type { ChatState } from "../state/reducer"; +import type { ChatState } from "../../application/state/reducer"; export function mutateState(current: ChatState): void { current.activeThread.id = "thread"; @@ -148,9 +148,9 @@ export function mutateState(current: ChatState): void { it("reports direct ChatState collection mutation from getState", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` -import type { ChatStateStore } from "../state/reducer"; +import type { ChatStateStore } from "../../application/state/reducer"; export function mutateState(store: ChatStateStore): void { store.getState().requests.userInputDrafts.set("key", "value"); @@ -163,9 +163,9 @@ export function mutateState(store: ChatStateStore): void { it("reports direct ChatState slice alias collection mutation", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` -import type { ChatStateStore } from "../state/reducer"; +import type { ChatStateStore } from "../../application/state/reducer"; export function mutateState(store: ChatStateStore): void { const requests = store.getState().requests; @@ -179,9 +179,9 @@ export function mutateState(store: ChatStateStore): void { it("reports direct ChatState snapshot alias collection mutation", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` -import type { ChatStateStore } from "../state/reducer"; +import type { ChatStateStore } from "../../application/state/reducer"; export function mutateState(store: ChatStateStore): void { const current = store.getState(); @@ -195,9 +195,9 @@ export function mutateState(store: ChatStateStore): void { it("allows scalar values derived from ChatState", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` -import type { ChatState } from "../state/reducer"; +import type { ChatState } from "../../application/state/reducer"; export function updateThreadId(state: ChatState, response: { threadId?: string }): string | null { let threadId = state.activeThread.id; @@ -212,9 +212,9 @@ export function updateThreadId(state: ChatState, response: { threadId?: string } it("allows replacing a ChatState snapshot reference", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` -import type { ChatState } from "../state/reducer"; +import type { ChatState } from "../../application/state/reducer"; export function replaceSnapshot(current: ChatState, next: ChatState): ChatState { current = next; @@ -228,9 +228,9 @@ export function replaceSnapshot(current: ChatState, next: ChatState): ChatState it("does not report shadowed ChatState alias names", async () => { const messages = await lintSource( - "src/features/chat/runtime/effective.ts", + "src/features/chat/domain/runtime/effective.ts", ` -import type { ChatStateStore } from "../state/reducer"; +import type { ChatStateStore } from "../../application/state/reducer"; export function mutateState(store: ChatStateStore): void { const requests = store.getState().requests; @@ -352,7 +352,7 @@ export const render = renderUiRoot; it("keeps all chat state modules deterministic", async () => { const messages = await lintSource( - "src/features/chat/state/message-stream.ts", + "src/features/chat/application/state/message-stream.ts", ` export function timestamp(): number { return Date.now();