mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-09 17:29:12 +00:00
refactor(web): group components into area subdirectories (#1036)
Move the 40 feature-specific components out of the flat components/ into chat/, settings/, dialogs/, and mobile/ subdirectories, leaving 9 shared layout components at the top level. Recompute every relative import (no path alias in the web app), refresh the line-1 path comments, and update the layout description in AGENTS.md. No behavior change; typecheck / test / build / lint all pass.
This commit is contained in:
parent
b1e6b64319
commit
866b91c8f5
44 changed files with 130 additions and 125 deletions
5
.changeset/web-components-subdirs.md
Normal file
5
.changeset/web-components-subdirs.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@moonshot-ai/kimi-code": patch
|
||||
---
|
||||
|
||||
Reorganize the web app's components into area subdirectories (chat/settings/dialogs/mobile) and refresh the component path comments.
|
||||
|
|
@ -10,7 +10,7 @@ The browser web UI for Kimi Code — a peer to the TUI in `apps/kimi-code`. It t
|
|||
|
||||
- `main.ts` — bootstrap (creates the app, installs i18n, mounts `#app`). `App.vue` — root component, holds most app state.
|
||||
- `api/` — server client. `index.ts` exposes the `getKimiWebApi()` singleton; `config.ts` builds REST/WS URLs; `daemon/` holds the wire client (`http.ts`, `ws.ts`, `wire.ts`, `mappers.ts`, `agentEventProjector.ts`, `eventReducer.ts`).
|
||||
- `components/` — ~50 flat SFCs, no subdirectories.
|
||||
- `components/` — SFCs grouped by area: `chat/` (conversation/chat UI), `settings/` (settings & configuration), `dialogs/` (modal dialogs & sheets), `mobile/` (mobile-specific shell), plus shared layout components at the top level.
|
||||
- `composables/` — reusable state logic, `useX` naming (`useKimiWebClient`, `useIsDark`, `usePaneLayout`, …).
|
||||
- `lib/` — pure helpers (`parseDiff`, `slashCommands`, `sessionRoute`, `toolMeta`, …).
|
||||
- `i18n/` — vue-i18n setup plus locale namespaces.
|
||||
|
|
|
|||
|
|
@ -4,25 +4,25 @@ import { computed, nextTick, onMounted, onUnmounted, provide, ref } from 'vue';
|
|||
import { useI18n } from 'vue-i18n';
|
||||
import Sidebar from './components/Sidebar.vue';
|
||||
import ResizeHandle from './components/ResizeHandle.vue';
|
||||
import ConversationPane from './components/ConversationPane.vue';
|
||||
import ConversationPane from './components/chat/ConversationPane.vue';
|
||||
import FilePreview from './components/FilePreview.vue';
|
||||
import ThinkingPanel from './components/ThinkingPanel.vue';
|
||||
import AgentDetailPanel from './components/AgentDetailPanel.vue';
|
||||
import SideChatPanel from './components/SideChatPanel.vue';
|
||||
import DiffView from './components/DiffView.vue';
|
||||
import ModelPicker from './components/ModelPicker.vue';
|
||||
import ProviderManager from './components/ProviderManager.vue';
|
||||
import LoginDialog from './components/LoginDialog.vue';
|
||||
import NewSessionDialog from './components/NewSessionDialog.vue';
|
||||
import SettingsDialog from './components/SettingsDialog.vue';
|
||||
import SessionsDialog from './components/SessionsDialog.vue';
|
||||
import AddWorkspaceDialog from './components/AddWorkspaceDialog.vue';
|
||||
import StatusPanel from './components/StatusPanel.vue';
|
||||
import ThinkingPanel from './components/chat/ThinkingPanel.vue';
|
||||
import AgentDetailPanel from './components/chat/AgentDetailPanel.vue';
|
||||
import SideChatPanel from './components/chat/SideChatPanel.vue';
|
||||
import DiffView from './components/chat/DiffView.vue';
|
||||
import ModelPicker from './components/settings/ModelPicker.vue';
|
||||
import ProviderManager from './components/settings/ProviderManager.vue';
|
||||
import LoginDialog from './components/dialogs/LoginDialog.vue';
|
||||
import NewSessionDialog from './components/dialogs/NewSessionDialog.vue';
|
||||
import SettingsDialog from './components/settings/SettingsDialog.vue';
|
||||
import SessionsDialog from './components/dialogs/SessionsDialog.vue';
|
||||
import AddWorkspaceDialog from './components/dialogs/AddWorkspaceDialog.vue';
|
||||
import StatusPanel from './components/chat/StatusPanel.vue';
|
||||
import WarningToasts from './components/WarningToasts.vue';
|
||||
import MobileTopBar from './components/MobileTopBar.vue';
|
||||
import MobileSwitcherSheet from './components/MobileSwitcherSheet.vue';
|
||||
import MobileSettingsSheet from './components/MobileSettingsSheet.vue';
|
||||
import Onboarding from './components/Onboarding.vue';
|
||||
import MobileTopBar from './components/mobile/MobileTopBar.vue';
|
||||
import MobileSwitcherSheet from './components/mobile/MobileSwitcherSheet.vue';
|
||||
import MobileSettingsSheet from './components/mobile/MobileSettingsSheet.vue';
|
||||
import Onboarding from './components/settings/Onboarding.vue';
|
||||
import GlobalLoading from './components/GlobalLoading.vue';
|
||||
import DebugPanel from './debug/DebugPanel.vue';
|
||||
import { isTraceEnabled } from './debug/trace';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, inject, nextTick, provide, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import Markdown from './Markdown.vue';
|
||||
import Markdown from './chat/Markdown.vue';
|
||||
import type { FileData, FilePreviewRequest } from '../types';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/ActivityNotice.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/ActivityNotice.vue -->
|
||||
<!-- Generic in-transcript "working on X" notice: the moon-phase spinner plus a
|
||||
body-sized label. Used for long-running session activities that are not a
|
||||
chat turn (e.g. "Compacting context…"). Renders inline at the end of the
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { AgentMember } from '../types';
|
||||
import type { AgentMember } from '../../types';
|
||||
|
||||
const props = defineProps<{ member: AgentMember; compact?: boolean }>();
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/AgentDetailPanel.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/AgentDetailPanel.vue -->
|
||||
<!-- A subagent's full detail in the right-side panel (App's shared slot — opening
|
||||
this replaces a thinking/compaction/file view and vice versa). Mirrors the
|
||||
thinking panel: the content is reactive, so a still-running subagent keeps
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { AgentMember } from '../types';
|
||||
import type { AgentMember } from '../../types';
|
||||
|
||||
const props = defineProps<{ member: AgentMember }>();
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import type { AgentMember } from '../types';
|
||||
import type { AgentMember } from '../../types';
|
||||
import AgentCard from './AgentCard.vue';
|
||||
|
||||
const props = defineProps<{ members: AgentMember[] }>();
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
<!-- apps/kimi-web/src/components/ApprovalCard.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/ApprovalCard.vue -->
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { ApprovalBlock } from '../types';
|
||||
import type { ApprovalDecision } from '../api/types';
|
||||
import type { ApprovalBlock } from '../../types';
|
||||
import type { ApprovalDecision } from '../../api/types';
|
||||
|
||||
const props = defineProps<{
|
||||
block: ApprovalBlock;
|
||||
|
|
@ -5,8 +5,8 @@
|
|||
<script setup lang="ts">
|
||||
import { onUnmounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { ActivationBadges, ApprovalBlock, ConversationStatus, PermissionMode, QueuedPromptView, TaskItem, TodoView, UIQuestion } from '../types';
|
||||
import type { AppGoal, AppModel, AppSkill, QuestionResponse, ThinkingLevel } from '../api/types';
|
||||
import type { ActivationBadges, ApprovalBlock, ConversationStatus, PermissionMode, QueuedPromptView, TaskItem, TodoView, UIQuestion } from '../../types';
|
||||
import type { AppGoal, AppModel, AppSkill, QuestionResponse, ThinkingLevel } from '../../api/types';
|
||||
import type { FileItem } from './MentionMenu.vue';
|
||||
import Composer from './Composer.vue';
|
||||
import GoalStrip from './GoalStrip.vue';
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/ChatHeader.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/ChatHeader.vue -->
|
||||
<!-- Thin context bar above the chat: workspace / session name, git branch +
|
||||
status, "open in editor", and a ⋮ more-menu that bundles copy-all plus
|
||||
the same session actions available from the sidebar session row. -->
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
<!-- apps/kimi-web/src/components/ChatPane.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/ChatPane.vue -->
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { ChatTurn, ApprovalBlock, FilePreviewRequest, ToolMedia } from '../types';
|
||||
import type { ChatTurn, ApprovalBlock, FilePreviewRequest, ToolMedia } from '../../types';
|
||||
import ToolCall from './ToolCall.vue';
|
||||
import Markdown from './Markdown.vue';
|
||||
import ThinkingBlock from './ThinkingBlock.vue';
|
||||
import ActivityNotice from './ActivityNotice.vue';
|
||||
import AgentCard from './AgentCard.vue';
|
||||
import AgentGroup from './AgentGroup.vue';
|
||||
import MoonSpinner from './MoonSpinner.vue';
|
||||
import { formatMessageTime } from '../lib/formatMessageTime';
|
||||
import MoonSpinner from '../MoonSpinner.vue';
|
||||
import { formatMessageTime } from '../../lib/formatMessageTime';
|
||||
import {
|
||||
assistantRenderBlocks,
|
||||
formatDuration,
|
||||
|
|
@ -21,7 +21,7 @@ import {
|
|||
turnBlocks,
|
||||
turnFinalText,
|
||||
turnToMarkdown,
|
||||
} from './chatTurnRendering';
|
||||
} from '../chatTurnRendering';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
<!-- apps/kimi-web/src/components/Composer.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/Composer.vue -->
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import SlashMenu from './SlashMenu.vue';
|
||||
import MentionMenu from './MentionMenu.vue';
|
||||
import { buildSlashItems, parseSlash } from '../lib/slashCommands';
|
||||
import { buildSlashItems, parseSlash } from '../../lib/slashCommands';
|
||||
import type { FileItem } from './MentionMenu.vue';
|
||||
import type { ActivationBadges, ConversationStatus, PermissionMode, QueuedPromptView } from '../types';
|
||||
import type { AppModel, AppSkill, ThinkingLevel } from '../api/types';
|
||||
import { modelThinkingAvailability } from '../lib/modelThinking';
|
||||
import { useInputHistory } from '../composables/useInputHistory';
|
||||
import { useSlashMenu } from '../composables/useSlashMenu';
|
||||
import { useMentionMenu } from '../composables/useMentionMenu';
|
||||
import { useComposerDraft } from '../composables/useComposerDraft';
|
||||
import { useAttachmentUpload } from '../composables/useAttachmentUpload';
|
||||
import type { ActivationBadges, ConversationStatus, PermissionMode, QueuedPromptView } from '../../types';
|
||||
import type { AppModel, AppSkill, ThinkingLevel } from '../../api/types';
|
||||
import { modelThinkingAvailability } from '../../lib/modelThinking';
|
||||
import { useInputHistory } from '../../composables/useInputHistory';
|
||||
import { useSlashMenu } from '../../composables/useSlashMenu';
|
||||
import { useMentionMenu } from '../../composables/useMentionMenu';
|
||||
import { useComposerDraft } from '../../composables/useComposerDraft';
|
||||
import { useAttachmentUpload } from '../../composables/useAttachmentUpload';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Props & emits
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
<!-- apps/kimi-web/src/components/ConversationPane.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/ConversationPane.vue -->
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref, watch, type ComponentPublicInstance } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { ActivationBadges, ApprovalBlock, ChatTurn, ConversationStatus, FilePreviewRequest, PermissionMode, QueuedPromptView, TaskItem, TodoView, ToolMedia, UIQuestion, WorkspaceView } from '../types';
|
||||
import type { AppGoal, AppModel, AppSkill, QuestionResponse, ThinkingLevel } from '../api/types';
|
||||
import type { SwarmGroup } from '../composables/swarmGroups';
|
||||
import type { ActivationBadges, ApprovalBlock, ChatTurn, ConversationStatus, FilePreviewRequest, PermissionMode, QueuedPromptView, TaskItem, TodoView, ToolMedia, UIQuestion, WorkspaceView } from '../../types';
|
||||
import type { AppGoal, AppModel, AppSkill, QuestionResponse, ThinkingLevel } from '../../api/types';
|
||||
import type { SwarmGroup } from '../../composables/swarmGroups';
|
||||
import type { FileItem } from './MentionMenu.vue';
|
||||
import ChatPane from './ChatPane.vue';
|
||||
import ChatHeader from './ChatHeader.vue';
|
||||
|
|
@ -12,8 +12,8 @@ import Composer from './Composer.vue';
|
|||
import SwarmCard from './SwarmCard.vue';
|
||||
import ChatDock from './ChatDock.vue';
|
||||
import ConversationToc, { type ConversationTocItem } from './ConversationToc.vue';
|
||||
import { getVisibleWorkspaces } from '../lib/workspacePicker';
|
||||
import { safeRemove, STORAGE_KEYS } from '../lib/storage';
|
||||
import { getVisibleWorkspaces } from '../../lib/workspacePicker';
|
||||
import { safeRemove, STORAGE_KEYS } from '../../lib/storage';
|
||||
|
||||
const props = defineProps<{
|
||||
turns: ChatTurn[];
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<!-- apps/kimi-web/src/components/ConversationToc.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/ConversationToc.vue -->
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { ChatTurn } from '../types';
|
||||
import type { ChatTurn } from '../../types';
|
||||
|
||||
export interface ConversationTocItem {
|
||||
id: string;
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
<!-- apps/kimi-web/src/components/DiffView.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/DiffView.vue -->
|
||||
<!-- ~/diff tab: real git changes from the daemon's fs:git_status, with a
|
||||
line-by-line unified-diff view (fs:diff) when a file is tapped.
|
||||
The changed-file list can be viewed as a flat list or as a tree. -->
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { DiffViewLine } from '../types';
|
||||
import type { DiffViewLine } from '../../types';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { AppGoal } from '../api/types';
|
||||
import type { AppGoal } from '../../api/types';
|
||||
|
||||
const props = defineProps<{ goal: AppGoal; forceExpanded?: number }>();
|
||||
const emit = defineEmits<{ controlGoal: [action: 'pause' | 'resume' | 'cancel'] }>();
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
<!-- apps/kimi-web/src/components/Markdown.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/Markdown.vue -->
|
||||
<script setup lang="ts">
|
||||
import { computed, inject, nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { MarkdownRender } from 'markstream-vue';
|
||||
import { useIsDark } from '../composables/useIsDark';
|
||||
import type { FilePreviewRequest } from '../types';
|
||||
import { collectFilePathAliases, findFilePathLinks } from '../lib/filePathLinks';
|
||||
import { markdownRenderPlan } from '../lib/markdownPerformance';
|
||||
import { useIsDark } from '../../composables/useIsDark';
|
||||
import type { FilePreviewRequest } from '../../types';
|
||||
import { collectFilePathAliases, findFilePathLinks } from '../../lib/filePathLinks';
|
||||
import { markdownRenderPlan } from '../../lib/markdownPerformance';
|
||||
// px-based CSS build (our app is px, not rem). Imported here so the styles
|
||||
// load wherever Markdown is used; scoped overrides below re-skin it to
|
||||
// Terminal Pro. Importing the same file from multiple components is a no-op
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<!-- apps/kimi-web/src/components/MentionMenu.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/MentionMenu.vue -->
|
||||
<!-- Popup list of file paths shown when user types @ in the Composer textarea. -->
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { FileItem } from '../types';
|
||||
import type { FileItem } from '../../types';
|
||||
|
||||
// Re-exported for the .vue consumers (Composer / ChatDock / ConversationPane)
|
||||
// that import FileItem from this component.
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
<!-- apps/kimi-web/src/components/OpenInMenu.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/OpenInMenu.vue -->
|
||||
<!-- "Open" button group for the chat header: workspace path label + quick-open
|
||||
(last used target) + dropdown caret, matching the kimi-cli/web pattern.
|
||||
Falls back to a simple icon+text "Open" button on non-mac platforms. -->
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onUnmounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { safeGetString, safeSetString, STORAGE_KEYS } from '../lib/storage';
|
||||
import { safeGetString, safeSetString, STORAGE_KEYS } from '../../lib/storage';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
<!-- apps/kimi-web/src/components/QuestionCard.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/QuestionCard.vue -->
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { UIQuestion } from '../types';
|
||||
import type { QuestionAnswer, QuestionResponse } from '../api/types';
|
||||
import type { UIQuestion } from '../../types';
|
||||
import type { QuestionAnswer, QuestionResponse } from '../../api/types';
|
||||
import Markdown from './Markdown.vue';
|
||||
|
||||
const props = defineProps<{ question: UIQuestion }>();
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<!-- apps/kimi-web/src/components/QueuePane.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/QueuePane.vue -->
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { QueuedPromptView } from '../types';
|
||||
import type { QueuedPromptView } from '../../types';
|
||||
|
||||
const props = defineProps<{
|
||||
queued: QueuedPromptView[];
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/SideChatPanel.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/SideChatPanel.vue -->
|
||||
<!-- BTW "side chat": a side-channel agent rendered in the right-side panel.
|
||||
It keeps the parent's context without creating a sidebar session. Reuses
|
||||
ChatPane for the transcript; its panel-open emits are no-ops here. -->
|
||||
|
|
@ -6,8 +6,8 @@
|
|||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import ChatPane from './ChatPane.vue';
|
||||
import MoonSpinner from './MoonSpinner.vue';
|
||||
import type { ChatTurn } from '../types';
|
||||
import MoonSpinner from '../MoonSpinner.vue';
|
||||
import type { ChatTurn } from '../../types';
|
||||
|
||||
const props = defineProps<{
|
||||
turns: ChatTurn[];
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
<!-- apps/kimi-web/src/components/SlashMenu.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/SlashMenu.vue -->
|
||||
<!-- Popup list of slash commands shown above the Composer textarea. -->
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { SlashCommand } from '../lib/slashCommands';
|
||||
import type { SlashCommand } from '../../lib/slashCommands';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
<!-- apps/kimi-web/src/components/StatusPanel.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/StatusPanel.vue -->
|
||||
<!-- /status overlay — renders the CURRENT session status from existing client -->
|
||||
<!-- state (no daemon call). Light only, monospace, Kimi blue, no emoji. -->
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { ConversationStatus, PermissionMode } from '../types';
|
||||
import type { ThinkingLevel } from '../api/types';
|
||||
import type { ConversationStatus, PermissionMode } from '../../types';
|
||||
import type { ThinkingLevel } from '../../api/types';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { AppSubagentPhase } from '../api/types';
|
||||
import type { SwarmGroup, SwarmMember } from '../composables/swarmGroups';
|
||||
import type { AppSubagentPhase } from '../../api/types';
|
||||
import type { SwarmGroup, SwarmMember } from '../../composables/swarmGroups';
|
||||
|
||||
const props = defineProps<{ group: SwarmGroup }>();
|
||||
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
<!-- apps/kimi-web/src/components/TasksPane.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/TasksPane.vue -->
|
||||
<!-- TUI-inspired todo list: clean rows with status glyphs, strikethrough done,
|
||||
compact output, minimal chrome. Matches the terminal todo-panel style. -->
|
||||
<script setup lang="ts">
|
||||
import { reactive } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { TaskItem } from '../types';
|
||||
import type { TaskItem } from '../../types';
|
||||
|
||||
defineProps<{ tasks: TaskItem[] }>();
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/ThinkingBlock.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/ThinkingBlock.vue -->
|
||||
<!-- 9e97773-style presentation: while this block is streaming it shows a live
|
||||
5-line scrolling window; when the stream moves past it the window folds
|
||||
into a one-paragraph teaser (the LAST paragraph of the thinking text).
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/ThinkingPanel.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/ThinkingPanel.vue -->
|
||||
<!-- Full thinking text in the right-side panel (App's shared preview slot —
|
||||
opening this replaces a file preview and vice versa). Content is reactive:
|
||||
while the block is still streaming the text keeps growing, and the body
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/TodoCard.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/TodoCard.vue -->
|
||||
<!-- Todo list driven by the model's TodoList tool (latest full-list write
|
||||
wins). Two render modes: a bordered card (used inside the wide-screen
|
||||
floating stack — the PARENT positions it) and `inline` for the ~/todo tab.
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { TodoView } from '../types';
|
||||
import type { TodoView } from '../../types';
|
||||
|
||||
const props = defineProps<{
|
||||
todos: TodoView[];
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<!-- apps/kimi-web/src/components/ToolCall.vue -->
|
||||
<!-- apps/kimi-web/src/components/chat/ToolCall.vue -->
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import type { ToolCall, ToolMedia } from '../types';
|
||||
import { toolLabel, toolGlyph, toolChip, toolSummary } from '../lib/toolMeta';
|
||||
import type { ToolCall, ToolMedia } from '../../types';
|
||||
import { toolLabel, toolGlyph, toolChip, toolSummary } from '../../lib/toolMeta';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/AddWorkspaceDialog.vue -->
|
||||
<!-- apps/kimi-web/src/components/dialogs/AddWorkspaceDialog.vue -->
|
||||
<!-- Daemon-driven folder browser for adding a workspace: starts at $HOME -->
|
||||
<!-- (fs:home), shows recent roots as quick-picks, a clickable breadcrumb, and -->
|
||||
<!-- the folder list (fs:browse). "Open this folder" adds the current path. -->
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { FsBrowseEntry, FsBrowseResult } from '../api/types';
|
||||
import type { FsBrowseEntry, FsBrowseResult } from '../../api/types';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/BottomSheet.vue -->
|
||||
<!-- apps/kimi-web/src/components/dialogs/BottomSheet.vue -->
|
||||
<!-- Reusable mobile bottom sheet: a fading scrim + a panel that slides up from -->
|
||||
<!-- the bottom (rounded top, grab handle). v-model controls open state; tapping -->
|
||||
<!-- the scrim or the grab handle closes it. Terminal Pro styling, no emoji. -->
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
<!-- apps/kimi-web/src/components/LoginDialog.vue -->
|
||||
<!-- apps/kimi-web/src/components/dialogs/LoginDialog.vue -->
|
||||
<!-- Managed Kimi OAuth device-code login dialog. -->
|
||||
<!-- Light only, monospace-forward, Kimi blue #1565C0, no emoji. -->
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useDialogFocus } from '../composables/useDialogFocus';
|
||||
import { useDialogFocus } from '../../composables/useDialogFocus';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/NewSessionDialog.vue -->
|
||||
<!-- apps/kimi-web/src/components/dialogs/NewSessionDialog.vue -->
|
||||
<!-- Modal dialog for creating a new session with a required working directory. -->
|
||||
<!-- Light only, monospace-forward, Kimi blue #1565C0, no emoji. -->
|
||||
<script setup lang="ts">
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/SessionsDialog.vue -->
|
||||
<!-- apps/kimi-web/src/components/dialogs/SessionsDialog.vue -->
|
||||
<!-- Session browser popup: lists ALL client-side sessions, searchable by title, -->
|
||||
<!-- click to switch. Reuses the composable's sessions / workspaceGroups / -->
|
||||
<!-- attentionBySession view data — no daemon call. -->
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { Session, WorkspaceGroup } from '../types';
|
||||
import type { Session, WorkspaceGroup } from '../../types';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/MobileSettingsSheet.vue -->
|
||||
<!-- apps/kimi-web/src/components/mobile/MobileSettingsSheet.vue -->
|
||||
<!-- Mobile settings: a bottom sheet that surfaces the desktop Composer-toolbar -->
|
||||
<!-- controls as big tappable rows — model (opens ModelPicker), thinking level -->
|
||||
<!-- (inline cycle picker), plan mode (toggle), permission (cycle), and a -->
|
||||
|
|
@ -8,11 +8,11 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { ConversationStatus, PermissionMode } from '../types';
|
||||
import type { ThinkingLevel } from '../api/types';
|
||||
import type { ColorScheme, Theme } from '../composables/useKimiWebClient';
|
||||
import BottomSheet from './BottomSheet.vue';
|
||||
import LanguageSwitcher from './LanguageSwitcher.vue';
|
||||
import type { ConversationStatus, PermissionMode } from '../../types';
|
||||
import type { ThinkingLevel } from '../../api/types';
|
||||
import type { ColorScheme, Theme } from '../../composables/useKimiWebClient';
|
||||
import BottomSheet from '../dialogs/BottomSheet.vue';
|
||||
import LanguageSwitcher from '../settings/LanguageSwitcher.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/MobileSwitcherSheet.vue -->
|
||||
<!-- apps/kimi-web/src/components/mobile/MobileSwitcherSheet.vue -->
|
||||
<!-- Mobile switcher bottom sheet, mirroring the desktop sidebar: a "+ New
|
||||
chat" row, then collapsible workspace groups (folder icon + name +
|
||||
branch/path sub-line + per-group "+") with their session rows beneath.
|
||||
|
|
@ -7,8 +7,8 @@
|
|||
<script setup lang="ts">
|
||||
import { onUnmounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { Session, WorkspaceGroup, WorkspaceView } from '../types';
|
||||
import BottomSheet from './BottomSheet.vue';
|
||||
import type { Session, WorkspaceGroup, WorkspaceView } from '../../types';
|
||||
import BottomSheet from '../dialogs/BottomSheet.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- apps/kimi-web/src/components/MobileTopBar.vue -->
|
||||
<!-- apps/kimi-web/src/components/mobile/MobileTopBar.vue -->
|
||||
<!-- Mobile title bar (50px): a 28px dark workspace square, a tappable middle -->
|
||||
<!-- zone showing the mono `workspace / session ⌄` path with a status sub-line -->
|
||||
<!-- (● running · branch · N sessions), and a trailing sliders button. Tapping -->
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { WorkspaceView } from '../types';
|
||||
import type { WorkspaceView } from '../../types';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<!-- apps/kimi-web/src/components/LanguageSwitcher.vue -->
|
||||
<!-- apps/kimi-web/src/components/settings/LanguageSwitcher.vue -->
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { availableLocales, setLocale, type LocaleCode } from '../i18n';
|
||||
import { availableLocales, setLocale, type LocaleCode } from '../../i18n';
|
||||
|
||||
const { locale } = useI18n();
|
||||
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
<!-- apps/kimi-web/src/components/ModelPicker.vue -->
|
||||
<!-- apps/kimi-web/src/components/settings/ModelPicker.vue -->
|
||||
<!-- Modal overlay for switching the active session's model. -->
|
||||
<!-- Light only, monospace-forward, Kimi blue #1565C0, no emoji. -->
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { AppModel } from '../api/types';
|
||||
import { useDialogFocus } from '../composables/useDialogFocus';
|
||||
import type { AppModel } from '../../api/types';
|
||||
import { useDialogFocus } from '../../composables/useDialogFocus';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
<!-- apps/kimi-web/src/components/Onboarding.vue -->
|
||||
<!-- apps/kimi-web/src/components/settings/Onboarding.vue -->
|
||||
<!-- First-run onboarding overlay: a short welcome + the two preferences
|
||||
(language, theme). Both apply live. Re-openable from the settings popover.
|
||||
Preferences can be changed any time later, so there's nothing to "lose". -->
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { availableLocales, setLocale, type LocaleCode } from '../i18n';
|
||||
import type { Theme } from '../composables/useKimiWebClient';
|
||||
import { availableLocales, setLocale, type LocaleCode } from '../../i18n';
|
||||
import type { Theme } from '../../composables/useKimiWebClient';
|
||||
|
||||
const props = defineProps<{ theme: Theme }>();
|
||||
const emit = defineEmits<{ setTheme: [theme: Theme]; complete: []; skip: [] }>();
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
<!-- apps/kimi-web/src/components/ProviderManager.vue -->
|
||||
<!-- apps/kimi-web/src/components/settings/ProviderManager.vue -->
|
||||
<!-- Modal overlay for managing providers: list, add, refresh, delete. -->
|
||||
<!-- Light only, monospace-forward, Kimi blue #1565C0, no emoji. -->
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { AppProvider } from '../api/types';
|
||||
import { useDialogFocus } from '../composables/useDialogFocus';
|
||||
import type { AppProvider } from '../../api/types';
|
||||
import { useDialogFocus } from '../../composables/useDialogFocus';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
<!-- apps/kimi-web/src/components/SettingsDialog.vue -->
|
||||
<!-- apps/kimi-web/src/components/settings/SettingsDialog.vue -->
|
||||
<!-- The app's dedicated Settings page (modal). Consolidates what used to be
|
||||
scattered in the sidebar account popover: appearance, language, account,
|
||||
connection, plus notifications and the troubleshooting-log export. -->
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useDialogFocus } from '../composables/useDialogFocus';
|
||||
import { useDialogFocus } from '../../composables/useDialogFocus';
|
||||
import LanguageSwitcher from './LanguageSwitcher.vue';
|
||||
import { serverEndpointLabel } from '../api/config';
|
||||
import { downloadTraceLog, isTraceEnabled } from '../debug/trace';
|
||||
import type { ColorScheme, Theme } from '../composables/useKimiWebClient';
|
||||
import type { AppConfig, AppConfigProvider, AppModel } from '../api/types';
|
||||
import { serverEndpointLabel } from '../../api/config';
|
||||
import { downloadTraceLog, isTraceEnabled } from '../../debug/trace';
|
||||
import type { ColorScheme, Theme } from '../../composables/useKimiWebClient';
|
||||
import type { AppConfig, AppConfigProvider, AppModel } from '../../api/types';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue