Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/web-drop-workspace-git-badges.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---

web: Remove per-workspace git repo badges and branch labels; branch, PR, and diff status remain shown for the active session.
2 changes: 0 additions & 2 deletions apps/kimi-web/src/api/daemon/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1175,8 +1175,6 @@ export class DaemonKimiWebApi implements KimiWebApi {
name: e.name,
path: e.path,
isDir: e.is_dir,
isGitRepo: e.is_git_repo,
branch: e.branch,
})),
};
} catch {
Expand Down
2 changes: 0 additions & 2 deletions apps/kimi-web/src/api/daemon/mappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ export function toAppWorkspace(wire: WireWorkspace): AppWorkspace {
id: wire.id,
root: wire.root,
name: wire.name,
isGitRepo: wire.is_git_repo,
branch: wire.branch ?? undefined,
lastOpenedAt: wire.last_opened_at,
sessionCount: wire.session_count,
};
Expand Down
4 changes: 0 additions & 4 deletions apps/kimi-web/src/api/daemon/wire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,6 @@ export interface WireWorkspace {
id: string;
root: string;
name: string;
is_git_repo: boolean;
branch: string | null;
last_opened_at?: string;
session_count: number;
}
Expand All @@ -168,8 +166,6 @@ export interface WireFsBrowseEntry {
name: string;
path: string;
is_dir: boolean;
is_git_repo: boolean;
branch?: string;
}

export interface WireFsBrowseResult {
Expand Down
6 changes: 0 additions & 6 deletions apps/kimi-web/src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,6 @@ export interface AppWorkspace {
root: string;
/** Display name — defaults to basename(root), may be renamed on the daemon. */
name: string;
/** Whether root is inside a git repository. */
isGitRepo: boolean;
/** Current branch, when known. */
branch?: string;
/** ISO timestamp of when this workspace was last opened. */
lastOpenedAt?: string;
/** Number of sessions belonging to this workspace. */
Expand All @@ -135,8 +131,6 @@ export interface FsBrowseEntry {
name: string;
path: string;
isDir: boolean;
isGitRepo: boolean;
branch?: string;
}

export interface FsBrowseResult {
Expand Down
15 changes: 2 additions & 13 deletions apps/kimi-web/src/components/dialogs/AddWorkspaceDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import Dialog from '../ui/Dialog.vue';
import Button from '../ui/Button.vue';
import IconButton from '../ui/IconButton.vue';
import Spinner from '../ui/Spinner.vue';
import Badge from '../ui/Badge.vue';
import Icon from '../ui/Icon.vue';
import Tooltip from '../ui/Tooltip.vue';

Expand Down Expand Up @@ -62,7 +61,7 @@ const entries = ref<FsBrowseEntry[]>([]);
// dialog never resizes while searching.
const filter = ref('');
const searching = ref(false);
interface SearchHit { path: string; name: string; rel: string; isGitRepo?: boolean; branch?: string }
interface SearchHit { path: string; name: string; rel: string }
const searchResults = ref<SearchHit[]>([]);
const isSearching = computed(() => filter.value.trim().length > 0);
let searchToken = 0;
Expand Down Expand Up @@ -137,7 +136,7 @@ async function runSearch(query: string): Promise<void> {
if (!e.isDir) continue;
const rel = e.path.startsWith(root) ? e.path.slice(root.length).replace(/^\/+/, '') : e.path;
if (fuzzyMatch(q, rel || e.name)) {
hits.push({ path: e.path, name: e.name, rel: rel || e.name, isGitRepo: e.isGitRepo, branch: e.branch });
hits.push({ path: e.path, name: e.name, rel: rel || e.name });
if (hits.length >= SEARCH_MAX_RESULTS) break;
}
if (node.depth + 1 < SEARCH_MAX_DEPTH) queue.push({ path: e.path, depth: node.depth + 1 });
Expand Down Expand Up @@ -419,9 +418,6 @@ onUnmounted(() => {
>
<Icon class="dir-icon" name="folder-closed" size="sm" />
<span class="folder-name">{{ c.name }}</span>
<Badge v-if="c.isGitRepo" variant="info" size="sm">
{{ t('workspace.gitTag') }}<span v-if="c.branch" class="git-branch"> {{ c.branch }}</span>
</Badge>
</button>
<div v-if="pathCandidates.length === 0" class="fl-empty fl-error">
{{ t('workspace.noPathMatch', { parent: pathParent }) }}
Expand All @@ -442,9 +438,6 @@ onUnmounted(() => {
>
<Icon class="dir-icon" name="folder-closed" size="sm" />
<span class="folder-name search-rel">{{ hit.rel }}</span>
<Badge v-if="hit.isGitRepo" variant="info" size="sm">
{{ t('workspace.gitTag') }}<span v-if="hit.branch" class="git-branch"> {{ hit.branch }}</span>
</Badge>
</button>
<div v-if="!searching && searchResults.length === 0" class="fl-empty">{{ t('workspace.noFilterMatch', { q: filter.trim() }) }}</div>
<div v-else-if="searching && searchResults.length === 0" class="fl-loading">{{ t('workspace.searching') }}</div>
Expand All @@ -460,9 +453,6 @@ onUnmounted(() => {
>
<Icon class="dir-icon" name="folder-closed" size="sm" />
<span class="folder-name">{{ entry.name }}</span>
<Badge v-if="entry.isGitRepo" variant="info" size="sm">
{{ t('workspace.gitTag') }}<span v-if="entry.branch" class="git-branch"> {{ entry.branch }}</span>
</Badge>
</button>
<div v-if="entries.length === 0" class="fl-empty">{{ t('workspace.noSubfolders') }}</div>
</template>
Expand Down Expand Up @@ -603,7 +593,6 @@ onUnmounted(() => {
white-space: nowrap;
color: var(--color-text);
}
.git-branch { color: var(--color-text-muted); }

/* Degraded mode (daemon can't browse): compact hint under the input box. */
.degraded-hint {
Expand Down
4 changes: 2 additions & 2 deletions apps/kimi-web/src/components/mobile/MobileSwitcherSheet.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- 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.
path sub-line + per-group "+") with their session rows beneath.
Tapping a session selects it AND closes the sheet; tapping a group header
folds it, same as the desktop sidebar. -->
<script setup lang="ts">
Expand Down Expand Up @@ -211,7 +211,7 @@ function onDeleteWorkspace(ws: WorkspaceView): void {
<div class="mgh-main">
<span class="mgh-name">{{ g.workspace.name }}</span>
<Tooltip :text="g.workspace.root">
<span class="mgh-path">{{ g.workspace.branch || g.workspace.shortPath }}</span>
<span class="mgh-path">{{ g.workspace.shortPath }}</span>
</Tooltip>
</div>

Expand Down
3 changes: 0 additions & 3 deletions apps/kimi-web/src/composables/useKimiWebClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2282,8 +2282,6 @@ const mergedWorkspaces = computed<AppWorkspace[]>(() =>
workspaces: rawState.workspaces,
sessions: rawState.sessions,
hiddenWorkspaceRoots: rawState.hiddenWorkspaceRoots,
activeRoot: rawState.sessions.find((s) => s.id === rawState.activeSessionId)?.cwd,
activeBranch: gitInfo.value?.branch ?? null,
sessionsHasMoreByWorkspace: rawState.sessionsHasMoreByWorkspace,
}),
);
Expand Down Expand Up @@ -2342,7 +2340,6 @@ const workspacesView = computed<WorkspaceView[]>(() => {
name: w.name,
root: w.root,
shortPath: shortenHome(w.root, rawState.fsHome),
branch: w.branch,
sessionCount: w.sessionCount,
}));
if (workspaceSortMode.value === 'recent') {
Expand Down
1 change: 0 additions & 1 deletion apps/kimi-web/src/i18n/locales/en/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export default {
searching: 'Searching…',
noFilterMatch: 'No subfolders match “{q}”',
noSubfolders: 'No subfolders here',
gitTag: 'git',
browseHint: 'Click a folder to enter it, then "Open this folder" to add it as a workspace.',
// Path entry (absolute path typed into the same box)
checkingPath: 'Checking path…',
Expand Down
1 change: 0 additions & 1 deletion apps/kimi-web/src/i18n/locales/zh/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export default {
searching: '搜索中…',
noFilterMatch: '没有匹配「{q}」的子文件夹',
noSubfolders: '此处没有子文件夹',
gitTag: 'git',
browseHint: '点击文件夹进入,再点"打开此文件夹"将其添加为工作区。',
// Path entry (absolute path typed into the same box)
checkingPath: '检查路径…',
Expand Down
11 changes: 1 addition & 10 deletions apps/kimi-web/src/lib/mergeWorkspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ export interface MergeWorkspacesInput {
sessions: Pick<AppSession, 'id' | 'cwd' | 'workspaceId'>[];
/** Root paths the user removed from the sidebar. */
hiddenWorkspaceRoots: string[];
/** cwd of the active session, used to hint the branch on the active workspace. */
activeRoot: string | undefined;
/** Live git branch of the active session, or null when unknown. */
activeBranch: string | null;
/** Per-workspace "server has more sessions" flag; false means the local
* session count is exact. */
sessionsHasMoreByWorkspace: Record<string, boolean>;
Expand All @@ -43,8 +39,6 @@ export function mergeWorkspaces(input: MergeWorkspacesInput): AppWorkspace[] {
workspaces,
sessions,
hiddenWorkspaceRoots,
activeRoot,
activeBranch,
sessionsHasMoreByWorkspace,
} = input;

Expand Down Expand Up @@ -73,7 +67,6 @@ export function mergeWorkspaces(input: MergeWorkspacesInput): AppWorkspace[] {
id: s.workspaceId ?? root,
root,
name: basename(root),
isGitRepo: false,
sessionCount: 0,
});
}
Expand Down Expand Up @@ -111,9 +104,7 @@ export function mergeWorkspaces(input: MergeWorkspacesInput): AppWorkspace[] {
sessionsHasMoreByWorkspace[w.id] === false
? localCount
: Math.max(w.sessionCount, localCount);
let branch = w.branch;
if (!branch && activeBranch && activeRoot === w.root) branch = activeBranch;
result.push({ ...w, sessionCount: count, branch });
result.push({ ...w, sessionCount: count });
}
return result;
}
2 changes: 0 additions & 2 deletions apps/kimi-web/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ export interface WorkspaceView {
root: string;
/** Home-shortened path for dim display, e.g. `~/code/kimi-code-web`. */
shortPath: string;
/** Current branch, when known. */
branch?: string;
/** Number of sessions in this workspace. */
sessionCount: number;
}
Expand Down
1 change: 0 additions & 1 deletion apps/kimi-web/test/event-batcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,6 @@ describe('useKimiWebClient (resync integration)', () => {
id: 'workspace-1',
root: '/workspace',
name: 'Workspace',
isGitRepo: false,
sessionCount: 1,
},
]),
Expand Down
23 changes: 8 additions & 15 deletions apps/kimi-web/test/workspace-state.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ function installStorage(storage: Storage): void {
}

function workspace(id: string, root: string, name: string) {
return { id, root, name, isGitRepo: false, sessionCount: 0 };
return { id, root, name, sessionCount: 0 };
}

function questionRequest(questionId: string): AppQuestionRequest {
Expand Down Expand Up @@ -416,14 +416,12 @@ describe('mergeWorkspaces', () => {
workspaces: [
// Server orders by last_opened_at desc, so the most recently opened
// (typically the canonical re-add) comes first.
{ id: 'wd_current', root: '/agent/GEO', name: 'GEO', isGitRepo: false, sessionCount: 0 },
{ id: 'wd_legacy', root: '/agent/GEO', name: 'GEO', isGitRepo: false, sessionCount: 0 },
{ id: 'wd_current', root: '/agent/GEO', name: 'GEO', sessionCount: 0 },
{ id: 'wd_legacy', root: '/agent/GEO', name: 'GEO', sessionCount: 0 },
],
// A session whose daemon workspace_id points at the dropped (legacy) entry.
sessions: [{ id: 's1', cwd: '/agent/GEO', workspaceId: 'wd_legacy' }],
hiddenWorkspaceRoots: [],
activeRoot: undefined,
activeBranch: null,
sessionsHasMoreByWorkspace: { wd_current: false },
});

Expand All @@ -438,15 +436,13 @@ describe('mergeWorkspaces', () => {
it('keeps distinct roots separate and appends derived cwds after real ones', () => {
const result = mergeWorkspaces({
workspaces: [
{ id: 'wd_a', root: '/agent/A', name: 'A', isGitRepo: false, sessionCount: 1 },
{ id: 'wd_a', root: '/agent/A', name: 'A', sessionCount: 1 },
],
sessions: [
{ id: 's1', cwd: '/agent/A', workspaceId: 'wd_a' },
{ id: 's2', cwd: '/agent/B', workspaceId: 'wd_b' },
],
hiddenWorkspaceRoots: [],
activeRoot: undefined,
activeBranch: null,
sessionsHasMoreByWorkspace: {},
});

Expand All @@ -457,12 +453,10 @@ describe('mergeWorkspaces', () => {
it('hides workspaces whose root the user removed', () => {
const result = mergeWorkspaces({
workspaces: [
{ id: 'wd_a', root: '/agent/A', name: 'A', isGitRepo: false, sessionCount: 1 },
{ id: 'wd_a', root: '/agent/A', name: 'A', sessionCount: 1 },
],
sessions: [{ id: 's1', cwd: '/agent/A', workspaceId: 'wd_a' }],
hiddenWorkspaceRoots: ['/agent/A'],
activeRoot: undefined,
activeBranch: null,
sessionsHasMoreByWorkspace: {},
});

Expand Down Expand Up @@ -551,7 +545,6 @@ describe('useWorkspaceState — addWorkspaceByPath', () => {
id: 'wd_abc',
root: '/abs/path',
name: 'path',
isGitRepo: false,
sessionCount: 0,
};
apiMock.addWorkspace.mockResolvedValue(registered);
Expand Down Expand Up @@ -731,7 +724,7 @@ describe('useWorkspaceState — cancelTask', () => {
});

describe('useWorkspaceState — startSessionAndActivateSkill', () => {
const registered = { id: 'wd_1', root: '/abs/path', name: 'A', isGitRepo: false, sessionCount: 0 };
const registered = { id: 'wd_1', root: '/abs/path', name: 'A', sessionCount: 0 };
const newSession = { ...createSession(), id: 'sess_new', workspaceId: 'wd_1', cwd: '/abs/path' };

beforeEach(() => {
Expand Down Expand Up @@ -873,7 +866,7 @@ describe('useWorkspaceState — startSessionAndActivateSkill', () => {
});

describe('useWorkspaceState — createGoal from an empty composer', () => {
const registered = { id: 'wd_1', root: '/abs/path', name: 'A', isGitRepo: false, sessionCount: 0 };
const registered = { id: 'wd_1', root: '/abs/path', name: 'A', sessionCount: 0 };
const newSession = { ...createSession(), id: 'sess_new', workspaceId: 'wd_1', cwd: '/abs/path' };

beforeEach(() => {
Expand Down Expand Up @@ -1047,7 +1040,7 @@ describe('useWorkspaceState — createGoal from an empty composer', () => {
});

describe('useWorkspaceState — startSessionAndOpenSideChat', () => {
const registered = { id: 'wd_1', root: '/abs/path', name: 'A', isGitRepo: false, sessionCount: 0 };
const registered = { id: 'wd_1', root: '/abs/path', name: 'A', sessionCount: 0 };
const newSession = { ...createSession(), id: 'sess_new', workspaceId: 'wd_1', cwd: '/abs/path' };

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ export const fsBrowseEntrySchema = z.object({
name: z.string().min(1),
path: z.string().min(1),
is_dir: z.literal(true),
is_git_repo: z.boolean(),
branch: z.string().optional(),
});
export type FsBrowseEntry = z.infer<typeof fsBrowseEntrySchema>;

Expand Down
Loading
Loading