Commit graph

13 commits

Author SHA1 Message Date
liruifengv
1fb57f0ee3
feat(sidebar): add status-tabs view with open/done session lifecycle (#221)
* docs: add sidebar status-tabs + session-done flow prototype

* feat(sidebar): add status-tabs view with open/done session lifecycle

* docs: sync status-tabs prototype and record follow-ups

* feat(sidebar): use circle-check glyph for the complete action

* docs: restructure prototype to layered tabs (flat/grouped as in-tab display switch)

* feat(sidebar): make status tabs the top level; flat/grouped becomes an in-tab display switch

* feat(sidebar): keep the section-label action buttons always visible

* feat(sidebar): add a divider between the session tabs and the workspace tab

* feat(sidebar): revert the tab divider (reads noisy)

* feat(sidebar): rename the display switcher to 列表管理

* feat(sidebar): rename workspace caption and move new-workspace entry to an icon

* feat(sidebar): use matched tabler circle glyphs for the open/done state icons

* feat(sidebar): highlight the active workspace's directory row

* feat(sidebar): add shortcuts for status tabs and sibling navigation

* fix(sidebar): use letter chords for tab switching and fix workspace sibling nav

* fix(sidebar): navigate only visible rows in grouped sibling order, auto-expanding collapsed groups

* feat(sidebar): point the done toast at the Done tab and reword it

* fix(sidebar): use the tabler circle-check for the complete action (size parity)

* feat(sidebar): open/close wording for the workspace-home terminal chip

* chore: bump kimi-code submodule

* chore: sync pnpm-lock.yaml after merging main

* feat(sidebar): align grouped session rows with the flat row interaction

The grouped row's leading slot now carries only the Open/Done state glyph
(fixed gutter, aligned with the workspace folder icon) — the running
spinner, unread dot and attention pills move to the trailing status
cluster, replacing the time exactly like the flat rows. On hover the
whole cluster cross-fades out as the pin/complete actions fade in, so
pills and actions never co-exist in any row variant.

* docs: add session admin page prototype

High-fidelity prototype for an admin-style session management page
(main content area, sidebar stays): filters with labels (multi-select
workspace, status, updated-at range picker), table with click-to-copy
session IDs, status glyphs, absolute timestamps, last prompt and an
actions column, paged footer with page-size options, GitHub-style
zero-shift batch header (complete / reopen), slimmed right-click
menus, undo toasts, light + dark themes.

* feat(api): add v2 sessions page mode, updatedBefore, and batch archive/restore

Client-side plumbing for the session admin page: ListSessionsV2Input
gains page (mutually exclusive with pageToken) and updatedBefore,
V2SessionsPage gains total, and the daemon client exposes
archiveSessions / restoreSessions hitting the new
POST /api/v2/sessions:archive | :restore endpoints.

* chore: bump kimi-code submodule

Point at feat/v2-sessions-admin (6ae1b2f0e) for the session admin
server work; re-bump to main once that branch merges.

* feat(client): add session admin main view with /admin/sessions URL binding

Add a facade-level mainView state ('chat' | 'sessionAdmin') exposed via
useKimiWebClient. The session admin page owns the address bar while open:
opening pushes /admin/sessions, closing restores the active session's URL
(or '/'), load() resolves the deep link (auto-selecting the most-recent
session in the background so the URL stays put), and popstate flips the
view both ways. Session-URL writes suspend while the admin page is open
so programmatic rewrites (archive fallback, workspace removal) cannot
yank the route away; user navigations (session/workspace/draft select)
leave the page. Web keeps the shared ExtendedState field initialized at
'chat' (type maintenance only, no behavior change).

* feat(sidebar): add session admin page skeleton and view-menu entry

Mount a SessionAdminView skeleton (page head + placeholder, token-only
styles, light/dark safe) next to ConversationPane in App.vue, switched
with v-show so the chat keeps its state. The sidebar list-options menu
gains a separated 会话管理… entry at the bottom that opens the page and
carries a checkmark while it is the main view. Registers the
session-admin icon (tabler adjustments-horizontal) and the new admin
i18n namespace (en/zh), with the page head doubling as the macOS
window-drag region and clearing the floating toggle when the sidebar is
collapsed.

* feat(client): add session admin data layer with server-side paging

New useSessionAdmin module for the /admin/sessions page: filters
(workspaces / status tri-state / updated-day range), page, pageSize,
items, total and loading behind one GET /api/v2/sessions page-mode call
per change — every condition pushed down, no client-side aggregation.
Setters reset to page 1 on filter/pageSize changes and schedule a 300ms
debounced fetch; a monotonic serial drops stale responses, the page is
clamped (and refetched) when the server-side total shrinks, and failures
surface through pushOperationFailure while the stale rows stay put. The
facade seeds on entry into the page (mainView watcher) and exposes the
state and setters via useKimiWebClient. Tests pin the query mapping
(tri-state/day bounds/OR ids), the page-1 reset, the debounce, the stale
-response drop, the clamp-refetch and the page-fold helper.

* feat(admin): fill the session admin page with filters, table, and pager

Replace the P1 placeholder with the real page (prototype-faithful,
token-only styles): a filter bar (workspace MultiSelectMenu with
select-all/indeterminate panel that stays open, status FilterSelect with
open/done dots, updated-time range fusing two date inputs with an ×
clear), the seven-column table (short session ID with click-to-copy and
in-cell feedback, open/done status glyphs, title, workspace, last
prompt, absolute updated/completed times in mono tabular-nums), and a
pager (total, 10/20/50/100 page size, folded page numbers, prev/next).
First load swaps the body for a Spinner; refetches dim the stale rows
in place. Registers the chevron-left icon (tabler — the Kimi set has
none) and expands the admin i18n namespace en/zh, dropping the skeleton
placeholder key.

* feat(client): add session admin selection and batch archive/restore

The admin table's selection lives in useSessionAdmin (a reactive id set
plus a per-id lifecycle map, kept across pages and filter changes per
GitHub semantics; reconciled against fresh rows on every landing) with
toggle/page-toggle/collapse/clear methods and open/done subset getters
driving the batch bar's counts and disables. Batch Mark-as-done/Reopen
(and single-row primaries, ids of length 1) call the v2 batch endpoints:
per-item successes fold into the sidebar lists via the new
applySessionsArchivedLocally — the local pool⇄done-list reconciliation
extracted from the single-session archive/restore paths so batch pays
no per-session side effects (backfill/tracking) — leave the selection,
and trigger a silent re-pull; failures stay selected and surface via
pushOperationFailure. The toast plan (pure, tested) maps an outcome to
the shared actionToast: undo set = successes, inverse endpoint on Undo.

* feat(admin): add batch header, row actions, and context menus to the table

The table gains its P3 interaction layer (prototype-faithful): a
selection column (header checkbox = select-this-page with indeterminate
state), the GitHub-style batch header that transforms in place (same
32px box — count plus Mark-as-done/Reopen disabled per the selection's
composition, table body zero-offset), an always-on actions column
(primary lifecycle button + ⋯ dropdown with Rename…/Fork/Export), inline
rename (Enter commits, Esc cancels, blur commits; a silent re-pull
follows since the table is server-fed), and the two-shape context menu
(single = Open/Rename…/Fork/Export/—/lifecycle, multi = count head +
the two batch actions) anchored to the cursor via useAnchoredMenu's new
openAt. Batch intents bubble through the view to App.vue, whose shared
actionToast now carries an adminBatch variant — succeeded (+failed)
counts, Undo through the inverse endpoint — while all-failed batches
surface as a WarningToast. Reuses the facade's renameSession /
forkSession / exportSession / selectSession chains; admin i18n grows
the P3 keys en/zh.

* fix(admin): let the session admin page own the full pane width

The page wrapper inherited the chat content-max measure (760px), which
crushed the table's flexible columns (title and last prompt collapsed
to zero width with table-layout: fixed). An admin table surface should
span the pane.

* fix(admin): reset UA button borders and restyle the ID cell

Quiet buttons (row actions, pager, range clear) inherited the UA
stylesheet's 2px outset border — the global reset only clears
backgrounds. The session ID cell becomes plain mono text with a small
copy icon (check feedback), and the actions column gains its 操作
header (batch colspan follows).

* docs(design-system): add the Session Admin Page section

New §10 registering the admin page's first-of-kind patterns: the
full-pane admin surface (why --p-content-max must not apply), the table
geometry (colgroup, hairlines, hover wash, mono tabular-nums absolute
times, state glyphs), the zero-offset batch header transform with its
cross-page selection, the session ID cell plus the quiet-button UA
border lesson, the quiet filter control family (FilterSelect /
MultiSelectMenu / time range), point-anchored two-shape context menus,
and inline rename. Adds the section to the side nav.

* docs(prototype): back-sync the session admin prototype to the implementation

Align the prototype with what shipped: the ID cell becomes plain mono
text (long session_ ids truncated to 10 chars) with a small copy
affordance that flips to a check (new IC.copy glyph), the prompt column
renders a faint em-dash when empty, batch ops carry an implementation
note that all-failed batches surface as a WarningToast rather than the
ActionToast, and the short-id mock field is dropped in favor of
truncating the full id. No behavioral rework of the prototype itself.

* docs(desktop): register the session admin page as a desktop-first divergence

The /admin/sessions page ships desktop-first and is deliberately not
synced to apps/web this cycle: record the desktop divergence blocks
(workspace-state mainView/URL guard + applySessionsArchivedLocally, the
new useSessionAdmin module, facade exports + watcher, App.vue toast +
mount, the sidebar menu entry, components/admin/, DesignSystemView §10)
plus the single web-side touchpoint to preserve on future syncs (the
mainView: 'chat' type initializer in web's useKimiWebClient).

* docs: add the session admin implementation plan and changeset

* feat(admin): switch session admin filters to a query form

The filter bar is now an antd-Pro-style query form: the workspace
multi-select, status select, and time-range control only edit a local
draft inside SessionAdminView — nothing is requested until 查询 (Button
primary) applies the whole draft through the facade's new
applySessionAdminFilters (atomic write + page reset + exactly one
immediate request, bypassing the per-setter debounce), 重置 (ghost)
restores defaults the same way, and Enter inside the bar queries too,
suppressed while any dropdown or the calendar panel is open. Pagination
still fetches immediately. The two native date inputs are replaced by
@vuepic/vue-datepicker (range, dual-month panel, auto-apply, teleported,
app-language locale via date-fns, :dark off useIsDark) with its input
restyled into the quiet filter-control look and every --dp-* variable
mapped onto the design tokens — panel on --color-menu-bg +
--p-menu-backdrop + --shadow-menu, selection/range from the accent
family; Date values bridge to the facade's 'YYYY-MM-DD' strings by
hand-splitting (local time, no toISOString). FilterSelect/MultiSelectMenu
expose their open state for the Enter guard; admin i18n gains query/reset
(en/zh); date-fns ^4.4.0 is declared for the locale objects (lockfile
synced, which also records the picker itself).

* docs(design-system): switch §10 filters to the query-form pattern

The Quiet filter controls subsection becomes Quiet filter controls
(query form): draft semantics with 查询/重置/Enter (overlay-aware),
pagination exempt, and the updated-time range re-specified as the
@vuepic/vue-datepicker wrapper with its --dp-* → token mapping and the
local-timezone Date bridging.

* docs(prototype): switch the session admin filters to a query form

The prototype's filter bar gains 查询/重置 buttons and a draft state —
controls (workspace panel, status, native date inputs) only edit the
draft, and 查询/重置/Enter apply it in one render — with comments noting
production uses @vuepic/vue-datepicker for the range control. Pagination
stays immediate.

* feat(admin): default the status filter to open and move the title into a 48px title bar

The status filter now defaults to 进行中 (重置 restores the same
default, not 全部) — the page is for triaging live work first. The page
title moves out of the body into a slim 48px title bar (window-drag
region, hairline bottom edge); the collapsed-sidebar clearance now pads
only that bar, so the table spans the full pane width when the sidebar
is collapsed.

* feat(admin): swap the time range picker for relative presets and streamline the table

The 更新时间 filter is now a quiet FilterSelect of relative windows
(全部时间 / 3 天以前 / 7 天以前 / 30 天以前) — a pick maps onto the
facade's updatedTo bound at apply time, so a saved draft never goes
stale. Triage asks "older than X", not "between two dates"; the
@vuepic/vue-datepicker and date-fns dependencies leave with the picker.

The table drops the session ID column and moves 状态 right after
工作空间. 标记完成 becomes an accent primary button (row action and
batch bar alike); 重新打开 becomes a bordered neutral button.

* docs(design-system): sync section 10 to the preset time filter and streamlined table

* docs(prototype): sync the session admin prototype to the preset filter and streamlined table

* fix(admin): shrink the lifecycle and batch buttons to xs

The 24px/13px controls read oversized against the 40px rows once every
row carried a filled button — 22px row buttons and 24px batch buttons in
--text-xs sit quieter without losing the primary/outline language.

* feat(admin): polish the session lifecycle entries

- The chat header's 完成 primary button goes away — the ⋯ menu keeps
  标记完成/重新打开, and a completed session still shows the Done pill
  with a quiet reopen.
- The 列表管理 menu entry is plain 会话管理: no ellipsis, no check.
- The admin page's subtitle row leads with a quiet 返回 button that
  closes the page back to the chat underneath.
- The workspace home's recent-sessions list gains a 查看更多 foot entry
  that opens the admin page, with a tip pointing at it.

* fix(home): align the recent-sessions list with the composer and quiet the view-more button

The list now takes the composer's inline insets so both edges line up
with the card above. The tip line goes away; 查看更多 becomes a centered
quiet button (text + down chevron) whose hover tooltip points at the
session admin page.

* feat(admin): select all matching sessions (Gmail-style)

Page caps (<=100) made mark-everything-done hopeless against thousands
of rows. Once the header checkbox has the whole page selected and total
says more exist, the batch bar offers 选中当前条件下的全部 N 项; it
materializes every matching id through the new ids projection
(fields=id,archived, page_size ceiling relaxed to 10000, cursor-walked),
merging atomically (a filter change mid-flight discards the fetch).
Unchecking rows are exclusions, an emptied selection or a single-row
collapse drops the mode, and a real filter change clears it — while
re-applying the same conditions keeps it. Batch executions chunk at the
wire's 5000-unique-ids ceiling, sequentially with merged outcomes.

Also bumps the kimi-code submodule for the projection.

* docs: sync the design spec and prototype to select-all-matching

* feat(admin): pre-select the draft workspace when entering from the workspace home

The 查看更多 entry now passes the home's workspace id through
openSessionAdmin, which applies it as the workspace filter atomically
with the navigation (status defaults to 进行中, no time bound). The
sidebar menu entry passes nothing and keeps the current conditions.
Because the page is v-show-kept, the filter draft now re-seeds from the
applied filters on every entry, so the controls always show the true
conditions.

* fix(chat): hide the new-messages pill without a transcript

The empty state (workspace home / classic hero) shares the panes scroll
container — once the terminal panel squeezes it into overflow, scrolling
up tripped the 最新消息 pill over content that has no messages. The pill
now requires an actual transcript; in-session behavior is unchanged.
Same one-line gate on the web copy.

* fix(sidebar): make rename work in the workspaces tab

Right-click → 重命名 set the renaming id, but the ws-dir row had no
rename input — only WorkspaceGroup (grouped session views) hosts one —
so nothing happened. The directory row now swaps its name for an inline
input (Enter commits, Esc/blur cancels, IME Enter guarded, clicks kept
off the row's create-session target), sharing the existing
renamingId/renameValue/confirmRenameWorkspace flow.

* fix(admin): default the status filter to all and quiet the row actions

- The ActionToast's inline action buttons get an inline margin — the
  condensed template drops the word space between the text runs and the
  action (已标记完成 1 个会话 撤销, not 已标记完成 1 个会话撤销).
- The status filter defaults to 全部状态 (all): the page is the whole
  inventory; 重置 and the workspace-home pre-selection follow suit.
- Row lifecycle actions shrink from text buttons to the sidebar row's
  icon language (state-done completes, undo reopens; tooltips carry the
  labels) — a filled button per row was visual noise.

* feat(admin): a bigger default window, a title-bar back button, and a responsive table

- The desktop default window grows to 1440x900 (saved bounds still win) —
  an admin table at 1280x860 crushed its flexible columns.
- The back affordance moves from the subtitle row into the title bar as
  an icon-only button with a tooltip.
- The table now steps down responsively (the card is the query
  container): time values compact to MM-DD HH:mm at 108px under 1020px,
  the time columns and the workspace folder icon drop under 760px, the
  title column keeps a max(200px, 20%) floor, and past the table's 640px
  floor the card scrolls horizontally instead of imploding.

* feat(admin): rewrite the page subtitle to guide the cleanup flow

管理所有会话,把任务完成的会话标记完成。旧会话按更新时间筛选,即可
批量清理。 — the verb matches the row/batch action (标记完成), and the
second sentence points at the filter-then-batch cleanup path.

* chore: bump kimi-code submodule

* feat(desktop): tag-style workspace filter and batch-action loading in session admin

* chore: bump kimi-code submodule

* chore: update lockfile for the bumped kimi-code submodule

* chore: bump kimi-code submodule

* feat(desktop): relabel the session reopen action as Mark as open

* feat(desktop): relabel the session reopen action as Mark as open

* feat(desktop): hide session-less workspace groups in the open tab

* feat(desktop): drop the Open/Done state glyphs from sidebar session rows

* fix(sidebar): exclude archived sessions from the grouped open projection

* fix(desktop): guard in-flight undo writes against newer action toasts

* fix(admin): exit select-all-matching when a batch empties the selection

* fix(sidebar): keep paging the done list past all-filtered pages

* fix(admin): apply the workspace pre-filter before the view switch to avoid a duplicate seed request

* fix(desktop): ignore the complete shortcut on an already-done session

* build: retry font source downloads on 429/5xx with backoff

* build: stretch the font download retry window past the raw-CDN rate-limit reset

* chore: bump kimi-code submodule

* feat(sidebar): show and sort done sessions by last-activity time

* chore: bump kimi-code submodule

* chore: bump kimi-code submodule

* chore: bump kimi-code submodule

* feat(desktop): trim the complete toast to just the undo action

* chore: bump kimi-code submodule

* chore: bump kimi-code submodule

* chore: bump kimi-code submodule

* chore: bump kimi-code submodule

* chore: bump kimi-code submodule

* chore: bump kimi-code submodule

* chore: bump kimi-code submodule

* fix(desktop): sync done-session renames and wire Gen Title on done rows

* feat(web): sync the sidebar status tabs and workspace home from desktop

* chore: consolidate the branch changesets into two entries

* Merge remote-tracking branch 'origin/main' into docs/session-status-tabs-prototype

chore: bump kimi-code submodule to 86674ac89

* feat(sidebar): show live status on done rows and unify the tab attention dots

Done rows were projected inert: chatting in a completed session showed no
spinner, approval, answer, or unread state, and the row never re-sorted.
The done projection now merges the pool row's live state (busy /
pendingInteraction / lastTurnReason / updatedAt) over the v2 snapshot, so
done rows render the full status cluster and the list floats a session
back to the top when its turn starts.

Both status tabs now share one accent-blue attention dot (the per-state
warning/info/danger/success swatches are gone), and the done tab gains
the same aggregation over its loaded rows. Workspace directory rows also
yield the hover menu's footprint (margin, since the fade mask and
overflow clip measure the border box) so the path no longer renders
under the button.
2026-08-18 17:15:54 +08:00
liruifengv
20964142d1
refactor: P1 lib migration to app-core + rename shared packages web-* → app-* (#185)
* docs: add renderer architecture refactor plan

* docs: add renderer architecture spec and progress ledger

* refactor: move shared renderer lib modules and tests into web-core

* refactor: point apps/web and apps/desktop renderer at web-core/lib

* refactor: fix dangling lib imports folded in by the main merge

Main added relative lib imports (modelThinking / pathRelativeTo /
nativeWorkspaceDrop / rootKey) alongside P1's rewrites; point them at
@moonshot-ai/web-core/lib like the rest.

* refactor: rename shared packages @moonshot-ai/web-* to app-*

These packages are shared by the web and desktop apps, so the web-
prefix is a misnomer: app-core / app-ui / app-markdown / app-i18n,
with packages/web-* directories renamed to packages/app-* to match.
The planned web-client package will land as app-client. vite-preset
is untouched; the app package names (kimi-code-web / kimi-code-app)
stay per repo policy. Historical plan/spec docs keep the old names.

* chore: point gitignored font paths at packages/app-ui

* test: fix type import path in mergeWorkspaces.test (../src/api/types)

Type-only so vitest erased it and never resolved at runtime, but the
path was wrong since the move into packages/ — flagged in review.

* chore: regenerate lockfile after kimi-code submodule bump

agent-core-v2 at cfd14a1f dropped its react/xyflow deps; the lockfile
staged in the merge predated the submodule sync and failed
--frozen-lockfile in CI.

* test: fix taskMerge.test import paths for its packages/ home

Same staging trap as before: a non-matching pathspec in the git add
aborted it silently, so the merge commit carried the pre-sed content.
2026-08-11 11:29:33 +08:00
liruifengv
a7b0eb0748 chore: drop the git add -f note from the web sync reminder 2026-08-05 12:40:34 +08:00
liruifengv
1b97e95243
feat(web): settings-native provider management, blue-mark brand fork (#173)
- Move custom provider management into Settings as a Providers tab
  (ProvidersPanel + AddProviderFlow + ProviderForm + providerForm lib),
  replacing the standalone ProviderManager overlay; add/update/delete,
  models.dev directory import, custom registry import, API key
  show/hide, inline error banners
- Onboarding login step gains a custom-provider card landing on
  Settings → Providers
- Fork web branding back to the legacy little-blue mark (sidebar,
  onboarding BrandLogo, favicon); build-brand-icons.mjs now only
  writes desktop assets
- Drop the dev backend switcher pill from the sidebar (switch backends
  via KIMI_SERVER_URL instead)
- Rebind web new-chat shortcut to Ctrl+Shift+O (browsers reserve
  Cmd/Ctrl+N for new window)
- Source __KIMI_CLIENT_VERSION__ from the kimi-code submodule CLI
  version instead of apps/web/package.json
- Warning toasts honor notice severity (info/success/error variants)
- Remove the stale ToolRow.vue copy from the desktop renderer snapshot
- Minor internal tidy-ups in transcript/detail-panel helpers
2026-08-04 16:44:25 +08:00
liruifengv
8140820d59
feat(desktop): add a custom Windows title bar (#123)
* feat: refine Windows desktop chrome

* fix: preserve Windows menu interactions

* fix: address Windows titlebar review feedback

* fix: clear Windows menu access on blur

* fix: align Windows menu shortcut handling
2026-07-27 17:23:03 +08:00
Luyu Cheng
4de4c9c0ff
feat(desktop): theme-following Dock icon, app-icon picker, v2 brand kit (#92)
* feat(desktop): adopt new brand kit for app icons and in-UI brandmarks

- replace KIMI CODE LOGO/ with the new designer delivery
- regenerate icon.icns/icon.ico/icon.png, tray icons and web favicon
  (squircle baked at Apple's 824/1024 grid so pre-Tahoe macOS keeps a
  correctly sized, rounded Dock icon)
- port onboarding BrandLogo and the sidebar mark to the new geometry
  in both apps, keeping the blink easter eggs
- add scripts/build-brand-icons.mjs (pnpm build:icons) so future kit
  updates regenerate everything reproducibly

* feat(desktop): theme-following Dock icon, app-icon picker, and v2 brand kit

- runtime Dock icon follows the effective appearance (light/dark tile);
  new macOS-only settings row picks light/dark/system with live previews
  in a dedicated DockIconPicker (squircle tiles, sliding indicator)
- choice persists renderer-side (lib/dockIconChoice.ts) and pushes via
  kimi:dock-icon-choice; ipc/preload validate the three literals
- icon-dark.png ships in mac packages only; afterPack compiles an
  optional build/AppIcon.icon into Assets.car for Tahoe appearances
  (no-op until the artifact lands; .icns stays as pre-Tahoe fallback)
- adopt the v2 KIMI CODE LOGO kit; rasterize app icons from the SVG
  vectors (the v2 PNGs are previews), parse stroke widths from the kit
  instead of hardcoding, drop the 5px centering correction (v2 is
  centered by design)

* fix(desktop): resolve Dock icon auto mode against the real OS appearance

nativeTheme.shouldUseDarkColors follows themeSource, which the renderer
sets from the app's own theme setting — so 'auto' would track the app
theme instead of macOS. Read systemPreferences.getEffectiveAppearance()
(unknown falls back to shouldUseDarkColors) and also subscribe to
AppleInterfaceThemeChangedNotification, since nativeTheme 'updated'
does not fire on OS changes while the app theme is pinned.

* fix(desktop): follow the real OS appearance for the auto Dock icon

- resolve 'auto' via /usr/bin/defaults read -g AppleInterfaceStyle:
  nativeTheme.shouldUseDarkColors and getEffectiveAppearance both follow
  the app-level appearance override (themeSource), so they can't serve
- push the same OS appearance to the renderer (kimi:os-appearance +
  kimi:os-appearance-changed) so the picker's System preview matches
  the actual Dock icon; older bridges fall back to the app theme
- register the DockIconPicker pattern in DesignSystemView (§03, with a
  live demo) and move its caption onto --text-2xs / --weight-caption
- tolerate the brand-mark viewBox height in check-style (32x28.x)

* chore: split the brand mark into Icon Composer layers

scripts/export-icon-layers.mjs regenerates KIMI CODE LOGO/layers/
(1024pt per-layer SVGs + PNGs, bottom-to-top: background, head, eyes,
terminal, dot) from the kit's White/Black Background.svg

* fix(desktop): address codex review on dock icon picker

- osAppearance: fall back to the app-level appearance when macOS
  appearance is Auto (AppleInterfaceStyle key absent) instead of
  wrongly reporting light
- DockIconPicker: WAI-ARIA radio-group keyboard model (roving tabindex,
  arrow/Home/End keys move selection and focus)
- move 2px group gap/padding onto the new --space-05 token; trim the
  component header comment (rationale stays in docs)

* fix(desktop): address second codex pass on dock icon picker

- give the icon radiogroup an accessible name (aria-label)
- guard the async IPC gap in onMounted so late resolves can't
  subscribe listeners after unmount
- build-brand-icons: fail on non-macOS instead of leaving a stale
  icon.icns next to regenerated assets
- trim rationale comments (details live in docs)

* fix(desktop): address third codex pass on dock icon picker

- build-brand-icons: move the macOS guard before any output is written
  (a mid-run throw left a partially refreshed icon set)
- caption line-height uses --leading-tight instead of a bare 1
- trim the remaining rationale comments in DockIconPicker

* fix(desktop): read the true system appearance in macOS Auto mode

When macOS appearance is Auto the AppleInterfaceStyle key is absent;
the previous fallback (nativeTheme.shouldUseDarkColors) follows the
app-level theme override, so a pinned app theme would win over the OS.
Ask a fresh JXA helper process for its own effectiveAppearance instead —
no override in that process, no TCC prompt, accurate under Auto.
2026-07-24 06:31:53 +08:00
liruifengv
6ea3027e2d chore(scripts): migrate desktop CDN publish script to repo root 2026-07-18 18:44:23 +08:00
liruifengv
a83f5dfded chore(scripts): migrate desktop CDN publish script into this repo 2026-07-18 18:34:21 +08:00
liruifengv
034c432d3f
feat(desktop): add auto-update via CDN generic feed (#26)
* feat(desktop): add auto-update via CDN generic feed

* fix(desktop): address review — merge dual-arch mac update feed, token radius, snapshot race, rollback reset

* chore(desktop): drop dev-only updater mock

* test(desktop): move renderer update tests into dedicated test dirs

* fix(desktop): keep in-flight update state on repeated update-available

* ci(desktop): merge mac update feeds with a repo-local node script

* test(desktop): fix moved update tests' import paths

* fix(desktop): clear rolled-back download errors on update-not-available
2026-07-18 16:34:23 +08:00
liruifengv
2d0b6fbeb2
ci: migrate desktop packaging to GitHub Actions and add changesets release flow (#1)
* ci: migrate desktop packaging pipeline to GitHub Actions

Replace the GitLab CI pipeline with a GitHub Actions workflow:

- .github/workflows/desktop-build.yml: workflow_dispatch trigger with
  sign-macos / retention-days inputs; matrix builds macOS arm64+x64,
  Windows x64 and Linux x64 on standard GitHub-hosted runners; checkout
  pulls the kimi-code submodule recursively; installers upload as
  kimi-desktop-<target> artifacts.
- .github/actions/macos-keychain-{setup,cleanup}: composite actions
  taken from the kimi-code repo (the previous GitLab shell scripts were
  themselves translated from these).
- Delete .gitlab-ci.yml; update AGENTS.md and apps/desktop/README.md;
  the scripts/ci/*.sh helpers are now only used by local packaging
  (package-local-macos.sh) and their headers say so.

* ci: temporarily trigger desktop-build on branch push for verification

workflow_dispatch requires the workflow file on the default branch;
before merge, run the pipeline on pushes to this branch (signed macOS
builds by default). Removed after verification.

* fix(desktop): unbreak Windows and Linux CI packaging

- Linux: electron-builder 26 validates executableName file-path safety;
  derive from package name fails (@moonshot-aikimi-desktop contains @).
  Set linux.executableName to kimi-code explicitly.
- Windows: @electron/rebuild 3.7.1 pins an old @electron/node-gyp fork
  that does not recognize Visual Studio 2026 (v18), the only toolchain
  on the windows-2025 image. Bump to 4.2.0, which uses plain
  node-gyp 12.4.0 with VS2026 support (and dedupes with
  electron-builder's own copy).

* ci: drop temporary branch push trigger from desktop-build

All four platforms verified green (macOS signed + notarized, Windows,
Linux). Back to workflow_dispatch-only as intended; the manual dispatch
becomes available once the workflow lands on the default branch.

* ci: add changesets-based desktop release flow

Mirror the kimi-code repo's changesets setup, but the publish step
produces desktop installers on a GitHub Release instead of npm:

- .changeset/: only @moonshot-ai/kimi-desktop is versioned; every other
  workspace package is ignored.
- release.yml (push to main): changesets/action maintains the
  'ci: release desktop' version PR; once it merges and the desktop
  version has no matching tag, the workflow calls desktop-build.yml
  (signed + notarized, four platforms), creates GitHub Release
  v<version> pinned to the merge commit, and uploads all installers
  as release assets. Idempotent: existing tag -> skip; the tag is only
  created alongside the release after a successful build, so reruns
  are safe.
- desktop-build.yml: restore the workflow_call trigger (same interface
  as the kimi-code repo) and switch the artifact prefix to
  kimi-code-app.

* refactor: rename desktop package to kimi-code-app, drop license fields

- apps/desktop: @moonshot-ai/kimi-desktop -> kimi-code-app (unscoped);
  homepage follows the repo name. The workflow artifact prefix already
  moved to kimi-code-app, so naming is now consistent end to end.
- Update every package-name reference (root scripts, desktop-build.yml,
  package-local-macos.sh, docs). Runtime identity strings are
  intentionally untouched: userAgentProduct 'kimi-desktop' (required
  upstream), storage keys, and [kimi-desktop] log prefixes.
- Remove the "license": "MIT" field from root / apps/web /
  apps/desktop package.json.

* refactor: rename web package to kimi-code-web

Follows the desktop rename: @moonshot-ai/kimi-web -> kimi-code-web
(unscoped). Updates every live reference (root scripts, sync script,
docs, test run hints, changesets ignore list). apps/web/CHANGELOG.md
keeps the historical name; the kimi-code submodule has no dependency
on this package name.

* chore: reset desktop version to 0.0.0

Fresh versioning baseline for the changesets flow — the first
'ci: release desktop' PR will produce the initial real version.
2026-07-16 22:45:14 +08:00
程鲁豫
f7547e49f3 feat: refresh UI typography, colors, spacing, and layout 2026-07-16 09:53:40 +00:00
liruifengv
ada047e90e chore(scripts): require KIMI_CODE_REPO in sync:web, drop dead copy-web-dist
- sync-web-to-kimi-code.mjs: KIMI_CODE_REPO is now required (no more ../kimi-code-2 default), the target is validated as a kimi-code checkout, errors are in Chinese, and a reminder to open a PR in the kimi-code repo prints after a successful sync
- Remove apps/desktop/scripts/copy-web-dist.mjs and the web-dist .gitignore entry: the desktop renderer builds from src/renderer into desktop-dist, so the web-dist copy flow is dead
- README.md / AGENTS.md updated to match
2026-07-15 13:32:03 +08:00
liruifengv
a4e0f42b59 feat: add sync-web script to vendoring web dist into kimi-code SEA 2026-07-10 11:45:48 +08:00