69 Commits

Author SHA1 Message Date
你的姓名
c032e38081 merge: upstream v0.4.2 (NanmiCoder/cc-haha 39 commits)
Major upstream changes integrated:
- providers list drag-and-drop reordering (#753)
- streaming stability fixes for slow providers (#766)
- active-turn prompt queue with edit/dedupe (#755)
- H5 access tokens / ports / background sessions (#767, #764)
- OpenAI prompt cache semantics (#789)
- exit plan approvals preview (#793)
- Windows settings panel stability (#788, #791)
- file path expansion when revealing generated files (#776)
- in-app browser preview menus (#761)
- auto-dream background memory consolidation
- compactCount tracking on sessions
- streamingResponseChars metric
- v0.4.2 release notes

Conflict resolution highlights:
- providerService: kept HEAD's markThinkingIncompatible + upstream's reorderProviders side-by-side
- types/provider: kept FetchModelsSchema + ReorderProvidersSchema both
- Settings.tsx: migrated HEAD's compat/thinking badges into upstream's SortableProviderCard slots
- chatStore: kept both message-queue implementations (messageQueue + queuedUserMessages)
- compact_boundary: merged HEAD's registerCompactionAndShouldSuggest with upstream's compactCount field
- exposed __resetCompactionThrashForTesting to fix cross-test state pollution exposed by upstream's new compactCount=2 test

Verification:
- desktop tsc --noEmit: clean
- desktop test suite: 1789/1792 pass (3 pre-existing electron/terminal Windows-only failures, not regressions)
- server providers test: 95/95 pass
- desktop chatStore tests: 131/131 pass
- desktop settingsStore + WorkspacePanel tests: 65/65 pass
2026-06-16 04:38:24 +08:00
小橙子
355b7294b9
feat(desktop): seed cc-haha-builtin marketplace into Electron package (#50)
* feat(desktop): seed cc-haha-builtin marketplace into Electron package

Wires the missing desktop side of the plugin-seed mechanism. The CLI
side (src/utils/plugins/{pluginDirectories,marketplaceManager}.ts) has
been on main for a while and exposes `getPluginSeedDirs()` +
`registerSeedMarketplaces()` reading `CLAUDE_CODE_PLUGIN_SEED_DIR`. But
the desktop side never set that env var or copied any seed into the
Electron package, so:

- v0.5.11 packaged users see whatever marketplaces they manually
  registered (typically just `reverse-engineering` from a one-off
  `plugin marketplace add ./plugins`).
- The image-gen plugin added in PR #49 was invisible after install
  because no mechanism shipped it inside the Electron bundle.

What this commit adds

- `desktop/scripts/build-plugin-seed.ts` (new)
  - Mirrors the repo's `plugins/` directory into
    `desktop/plugin-seed/marketplaces/cc-haha-builtin/`.
  - Generates `desktop/plugin-seed/known_marketplaces.json` with a
    placeholder `installLocation`. registerSeedMarketplaces() recomputes
    the real path at runtime via findSeedMarketplaceLocation(), so the
    placeholder is intentional — handles cases like multi-stage Docker
    builds where the seed lives at a different path than where it was
    built.

- `desktop/package.json`
  - Adds `build:plugin-seed` script.
  - Prepends it to `electron:dev` and `electron:build` so the seed is
    always fresh before the app starts (or is packaged).
  - Adds `plugin-seed/**` to electron-builder `files` and `asarUnpack`
    so the seed dir ships inside the .app/.exe but stays outside the
    asar archive (CC reads files from disk, not from asar).

- `desktop/electron/services/sidecarManager.ts`
  - Threads `desktopRoot` through `buildSidecarEnv(...)` and adds
    `CLAUDE_CODE_PLUGIN_SEED_DIR=<desktopRoot>/plugin-seed` so the
    spawned server sidecar finds the seed.

- `src/server/index.ts`
  - Calls `registerSeedMarketplaces()` at server boot so the seeded
    marketplace appears in `~/.claude/plugins/known_marketplaces.json`
    and the desktop's Settings → Plugins page picks it up.
  - Fire-and-forget (`void ...`) rather than `await`, since
    `startServer` is sync and the registration takes ~ms; the seeded
    marketplace appears in the UI within 1-2 seconds of server boot.
    (The original drafted version used `await` inside a sync function,
    which doesn't compile — fixed in this commit.)

- `.gitignore` — excludes `desktop/plugin-seed/` from version control
  (regenerated on every electron build, never committed).

End-to-end flow after this lands

  build time:
    bun run electron:build
      → bun run build:plugin-seed
          → desktop/plugin-seed/marketplaces/cc-haha-builtin/{plugin/,...}
          → desktop/plugin-seed/known_marketplaces.json
      → bun run build:sidecars + electron-builder
          → packages plugin-seed/** into .app/.exe (asarUnpack ensures
            the dir is on disk, not inside asar)

  runtime (first launch):
    Electron main → spawn server sidecar with
      CLAUDE_CODE_PLUGIN_SEED_DIR=<resourcesDir>/plugin-seed
    Server sidecar starts → registerSeedMarketplaces()
      → reads seed/known_marketplaces.json
      → calls findSeedMarketplaceLocation() to resolve real path
      → writes resolved entry into ~/.claude/plugins/known_marketplaces.json
    Desktop Settings → Plugins reads ~/.claude/plugins/known_marketplaces.json
      → shows cc-haha-builtin marketplace with both reverse-engineering
        and image-gen plugins available to install.

Verification

- `bun run desktop/scripts/build-plugin-seed.ts` produces the seed
  with both plugins present, valid JSON, in expected dir layout.
- `bun run lint` (desktop): tsc --noEmit clean — no remaining type
  errors from the await→void change or the buildSidecarEnv signature
  change.
- Seed marketplace.json plugins array confirmed includes both
  reverse-engineering (v0.4.6, post-#33) and image-gen (v1.0.0, from
  #49).

Tested: build script runs locally; tsc clean.
Not-tested: live `bun run electron:package` end-to-end pack on this
host (no codesign, slow). The packaging-side wiring (asarUnpack +
files) is configuration-only and matches established patterns
(node_modules/node-pty/**, src-tauri/binaries/**); no behaviour change
to the existing package layout besides adding plugin-seed/.

Risk: low — additive across the board, no existing path changes
behaviour. The fire-and-forget marketplace registration cannot block
boot; if it fails, the worst case is the user sees no seeded
marketplace and can manually re-add it (existing flow).

Confidence: high
Scope-risk: narrow — desktop wiring + 1 server-side hook call.

* test(server): add seed-marketplaces-startup integration tests

Covers the registerSeedMarketplaces() integration that startServer()

now invokes at boot. Four cases:

- env var unset → returns false, no write

- valid seed → returns true, writes primary entry with resolved (non-placeholder) installLocation

- repeat call → primary entry stays intact (returns false on the no-op call but the previously-written entry survives)

- nonexistent seed dir → returns false, no crash

Resolves the change-policy 'Server product files changed without a server test file in the PR' block on PR #50.

* test(desktop): pass desktopRoot to buildSidecarEnv in sidecar test

buildSidecarEnv now requires desktopRoot to derive CLAUDE_CODE_PLUGIN_SEED_DIR. The existing 'passes portable config' test still called the old 2-arg signature, breaking both desktop-checks (vitest) and desktop-native-checks (tsc) on PR #50.

Tested:

  - bunx vitest run electron/services/sidecarManager.test.ts -t 'passes portable config' — 1 passed

  - tsc -p electron/tsconfig.json — clean

Confidence: high

Scope-risk: narrow

---------

Co-authored-by: 你的姓名 <you@example.com>
2026-06-15 23:18:34 +08:00
你的姓名
d13f29e097 feat(workspace): enable automatic LSP diagnostics
Co-Authored-By: Claude GPT-5.5 <noreply@anthropic.com>
2026-06-14 12:02:40 +08:00
你的姓名
f873a1a5db chore(brand): update visible product name to Code Council
Co-Authored-By: Claude GPT-5.5 <noreply@anthropic.com>
2026-06-13 15:17:01 +08:00
程序员阿江(Relakkes)
7c37384ebc release: v0.4.2
Tested: bun run scripts/release.ts 0.4.2 --dry

Tested: git diff --check

Confidence: high

Scope-risk: narrow
2026-06-13 12:00:41 +08:00
程序员阿江(Relakkes)
01d8691673 fix(providers): make provider list sortable (#753)
Render provider settings through dnd-kit sortable rows, include official providers in the same order model, and persist providerOrder across server and desktop state.

Tested:

- bun test src/server/__tests__/providers.test.ts src/server/__tests__/persistence-upgrade.test.ts

- cd desktop && bun run test -- --run src/stores/providerStore.test.ts src/__tests__/generalSettings.test.tsx -t "providerStore reorderProviders|Settings > Providers tab"

- cd desktop && bun run lint

- cd desktop && bun run build

- bun run check:persistence-upgrade

Not-tested:

- bun run check:server (broad suite hit environment failures during this run: MCP stdio zshrc timeout, adapter dependency gap at the time, and e2e cascade)

Confidence: high

Scope-risk: moderate
2026-06-13 08:07:36 +08:00
程序员阿江(Relakkes)
275dab39cc fix(native): run electron-builder through node
Avoid the bunx launcher for local Electron packaging after it can be terminated before Electron Builder starts. Use the installed Electron Builder CLI through Node for the macOS package script and desktop package shortcuts.

Tested: SKIP_INSTALL=1 SKIP_PACKAGE_SMOKE=1 bash ./scripts/build-macos-arm64.sh
Tested: bun run test:package-smoke --platform macos --package-kind release --artifacts-dir desktop/build-artifacts/macos-arm64
Tested: bash -n desktop/scripts/build-macos-arm64.sh
Tested: git diff --check
Not-tested: full bun run verify was not run because this is a narrow local packaging launcher fix.
Confidence: high
Scope-risk: narrow
2026-06-12 18:02:38 +08:00
你的姓名
a4e3306753 release: v0.5.11 2026-06-12 14:09:10 +08:00
程序员阿江(Relakkes)
978dfb2efb fix(desktop): repair Windows updater and installer flow (#801)
Prevent stale same-version update metadata from surfacing another install prompt, avoid showing a fake desktop version fallback, and configure the Windows NSIS installer to expose install directory selection.

Fixes #801

Tested: bun run verify
Confidence: high
Scope-risk: moderate
2026-06-12 10:39:13 +08:00
小橙子
3fb246ca6a
feat: CodeMirror editor + atomic save + conflict banner foundation (Phase 2) (#24)
* feat(desktop): add CodeMirror deps + bundle budget + encoding utils

Phase 2 foundation pieces (tasks 6-7 of editor-lsp-foundation):

- Add 9 @codemirror/* dependencies (state, view, commands, search, language,
  autocomplete, lang-{javascript,json,markdown}). Tree-shaking keeps the
  current bundle delta at +0.00 KB until WorkspaceEditor.tsx imports them
  in task 8.
- Add scripts/check-bundle-budget.ts + bun script "check:bundle-budget".
  Asserts dist/assets/*.js gzipped total <= baseline + 100 KB. Baseline
  captured at origin/main @ 95931d49 (post-R5, pre-CodeMirror) = 3299.76 KB.
- Add encodingDetect.ts: detectEncoding(bytes) -> 'utf-8' | 'utf-8-bom' |
  'unsupported' (uses TextDecoder fatal:true to map invalid UTF-8 to
  unsupported); detectLineEnding(text) -> 'LF' | 'CRLF' | 'CR' (dominant
  style with LF as fallback for empty/single-line buffers).

Tested:
- bun run test src/components/workspace/encodingDetect.test.ts -- --run (18/18 pass)
- bun run scripts/check-bundle-budget.ts (OK, +0.00 KB delta)

_Requirements: 1.3, 1.6, 1.7, 1.8_

* feat(server,desktop): workspace file save endpoint + buffer/conflict store

Phase 2 backend pieces (tasks 9-12 of editor-lsp-foundation):

Server:
- src/server/events/workspaceFileSaved.ts: shared emitter
  emitWorkspaceFileSaved() so both write paths (user now, agent in PR-4)
  funnel through one well-typed WS message shape.
- src/server/services/workspaceFileService.ts: WriteWorkspaceFileSchema
  (Zod), atomic write (temp file + fsync + rename, Windows EBUSY/EPERM
  retry 3x50ms), realpath-based symlink containment, BOM/CRLF/CR
  round-trip, sha256 stale-base check (409 on hash mismatch), structured
  400/404/409/500 error bodies, post-write workspace.file.saved emit.
- src/server/api/sessions.ts: POST /api/sessions/:id/workspace/file
  routes through new handleSessionWorkspacePost; GET path unchanged.
- src/server/services/workspaceFileService.test.ts: 17 tests covering
  200 / 400 (bad request, path-escape, parent-missing, absolute-path) /
  404 session-missing / 409 stale-base / BOM round-trip / CRLF round-trip /
  CR round-trip / temp-file-not-leaked / 10 MiB content cap. Includes
  symlink-escape coverage on POSIX (skipped on Windows where symlink
  creation needs elevation).

Desktop store:
- desktop/src/stores/workspacePanelStore.ts: bufferStateByTabId record,
  WorkspaceBufferState/Conflict types, initBuffer / setBufferState /
  applyExternalSave / acknowledgeConflict / clearBuffer actions.
  applyExternalSave is the WS-driven entry point — clean buffers rebase
  silently when content is supplied; dirty buffers raise a conflict
  banner. acknowledgeConflict('reload') resets to base, 'keepMine' /
  'openConflict' just dismiss the banner. closePreviewTabs and
  clearSession now drop matching buffer state to prevent leaks.

Tested:
- bun test src/server/services/workspaceFileService.test.ts (17/17 pass)
- bun run lint (server tsc clean)
- bun run test src/stores/workspacePanelStore.test.ts (24/24 pass — store
  extension is purely additive, R5 tests still green)

Note: pre-existing e2e/business-flow failures in src/server/__tests__/e2e
remain untouched by this change (44 fails on baseline, no new fails
introduced).

_Requirements: 1.5, 2.1-2.9, 3.1-3.3_

* feat(desktop): WorkspaceEditor + ConflictBanner + UnsavedChangesModal

Phase 2 UI pieces (tasks 8, 13, 14, 15 of editor-lsp-foundation):

- desktop/src/components/workspace/WorkspaceEditor.tsx: CodeMirror 6
  editor wrapping the workspace panel buffer state. Hooks
  EditorView.updateListener -> setBufferState for live dirty tracking,
  picks language by extension (ts/tsx/js/jsx/json/md), wires Save to
  sessionsApi.saveWorkspaceFile (R2 atomic write endpoint), refreshes
  base hash on success, falls back to a read-only message when
  detectEncoding returns 'unsupported'. External rebases (e.g. clean
  buffer applyExternalSave) are pushed back into the EditorView via
  dispatch.
- desktop/src/components/workspace/ConflictBanner.tsx: clean buffer ->
  single Reload button; dirty buffer -> three buttons (Reload (discard),
  Keep mine, Open conflict view). Renders workspace-relative path,
  hash first 8 hex, relative timestamp refreshing every 60 s.
- desktop/src/components/workspace/UnsavedChangesModal.tsx: Discard /
  Save / Cancel modal. Cancel is the default focus, Esc triggers it.
  While saving, all three buttons disable and the host calls onSave
  which only resolves close on success. 30 s in-prompt timeout fires
  onTimeout (host owns the toast).
- desktop/src/components/workspace/WorkspaceEditor.test.tsx: 8 RTL
  tests covering buffer init / encoding detection / unsupported
  fallback / dirty marker / unsaved-changes modal flows / conflict
  banner clean-vs-dirty layouts.
- desktop/src/api/sessions.ts: SaveWorkspaceFileInput +
  SaveWorkspaceFileResult types and sessionsApi.saveWorkspaceFile
  POST helper.

Bundle delta: +0.28 KB gz (CodeMirror 6 + 3 lang packs imported but
WorkspaceEditor is not yet wired into WorkspacePanel — that integration
ships in a follow-up PR alongside Phase 3 LSP work, keeping this PR
focused on the foundation).

Tested:
- bun run lint (tsc --noEmit clean)
- bun run test (workspacePanelStore 24/24, encodingDetect 18/18,
  WorkspaceEditor 8/8, WorkspacePanel 27/27 — 77/77 across 4 files)
- bun run check:bundle-budget (delta +0.28 KB gz, 99.72 KB headroom)
- bun run build (clean, 1.20s)

_Requirements: 1.1-1.8, 3.2-3.5, 4.1-4.6_

---------

Co-authored-by: 你的姓名 <you@example.com>
2026-06-12 07:36:52 +08:00
你的姓名
f2ede6c4df release: v0.5.10 2026-06-11 20:55:46 +08:00
你的姓名
9598e7f94c release: v0.5.9 2026-06-11 15:31:36 +08:00
程序员阿江(Relakkes)
3e52c58a33 release: v0.4.1
Tested: bun run scripts/release.ts 0.4.1 --dry
Confidence: medium
Scope-risk: narrow
2026-06-11 02:05:01 +08:00
小橙子
2b6202d381
fix(handoff): reuse empty session + ship raw tail for v0.5.8 (#5)
Two bugs in the v0.5.7 "Continue from here" hand-off path landed in
the wild and the user caught them while exercising 0.5.8 prep:

1. **Stray empty session.** When the user previously opened a "New
   session in X" tab from the sidebar, then closed the tab to
   declutter, the freshly-created empty session was already on disk
   and visible in the sidebar. Coming back to the welcome screen
   (activeTabId = null → EmptySession route) and clicking "Continue
   from here" called `createSession` unconditionally, minting yet
   another empty session next to the now-stale one. The user ended up
   with `Untitled Session 27 minutes ago` lingering in the sidebar
   while the hand-off ran in a completely separate fresh session.

   Extract the picker into `desktop/src/lib/sessionReuse.ts` —
   `pickReusableEmptySession(sessions, workDir, excludeSessionId?)`
   filters by exact-workDir match, `messageCount === 0`, excludes the
   previous session being handed off FROM, and sorts by `modifiedAt`
   desc. Caller in `EmptySession.onAutoHandoff` runs this before
   `createSession`; on hit, openTab on the existing sessionId and let
   ContentRouter switch to ActiveSession naturally; on miss, create
   fresh as before.

   7 unit tests cover the boundaries: workDir mismatch, non-zero
   messageCount, excludeSessionId honored, null workDir treated as
   "no candidates" (so we never silently merge home-dir sessions
   into a project hand-off), empty workDir argument, empty session
   list, freshness sort order.

2. **Summary too abstract; AI doesn't know specific recent state.**
   The previous implementation only injected the LLM-summarized
   `main` + `recent` paragraphs into the next session's system
   prompt. That summarization tends to wash out exact wording, file
   paths, error messages, and the user's literal last question — the
   user reported "AI doesn't know what we just hit a wall on."

   Add `recentRaw?: string` to `SessionSummary`. New helper
   `buildRecentRawSlice` keeps the LAST ~12 turns (env-tunable via
   `CLAUDE_CODE_HANDOFF_RAW_TURNS`, range 0–50, default 12), each
   truncated to 400 chars preserving the `USER:` / `ASSISTANT:`
   role prefix, total capped at ~8000 chars (env-tunable via
   `CLAUDE_CODE_HANDOFF_RAW_CHARS`, range 500–30000, default 8000).
   Older turns drop first when the total cap is busted by dense
   recent turns.

   `formatHandoffSystemPrompt` renders the raw slice inside a fenced
   code block AFTER the abstracted recent summary, so the next
   session sees both the digest and the literal text. Section is
   omitted entirely when `recentRaw` is absent — v0.5.7 caches still
   load and produce the exact same prompt bytes (back-compat).

   8 unit tests cover the formatter's back-compat path, the raw
   block placement, fence rendering, tail-N selection, all-fits
   case, per-turn truncation with role prefix preservation, total
   cap busting (older drops first), and the `RAW_TURNS=0` opt-out.

Both fixes fold into the unreleased v0.5.8 — release-notes/v0.5.8.md
gets two new fix bullets and the 范围 / 验证 sections call out the
new files and 15 added tests.

desktop/package.json bump to 0.5.8 stays as-is (preset earlier in
the same worktree before this commit).

Tested:
- bun run lint (desktop) clean
- bunx vitest run sessionReuse.test.ts → 7/7 pass
- bun test sessionSummaryService.test.ts → 8/8 pass
- bunx vitest run EmptySession.test.tsx → 22/22 pass (regression check
  after the helper extraction — the existing tests don't go through
  the hand-off branch but exercise the rest of the file)

Confidence: high
Scope-risk: narrow (no shape changes to any persistence — recentRaw
is an additive field, old caches deserialize cleanly because
`tryParseSummaryResponse` already only required main+recent)

Co-authored-by: 你的姓名 <you@example.com>
2026-06-10 20:46:46 +08:00
你的姓名
f41d88673d release: v0.5.7 2026-06-10 07:12:53 +08:00
你的姓名
4690cd9199 release: v0.5.6 2026-06-09 16:58:15 +08:00
你的姓名
3cbed50ca9 feat(desktop): point repo + update source to this fork, credit fork maintainer
- Update source: desktop/package.json publish.owner NanmiCoder -> 706412584 (electron-updater
  now checks this fork's releases via app-update.yml). Also bump homepage and the legacy
  Tauri updater endpoint to the fork.
- About page: GITHUB_REPO / issues / releases / changelog and the displayed repo name now
  point to 706412584/cc-haha. Sidebar repo link and ActivitySettings profile subtitle too.
- Attribution: original author (NanmiCoder + Bilibili/Douyin/Xiaohongshu social links) is
  preserved unchanged. Added a new "Fork maintainer" credit (706412584) with i18n keys
  settings.about.forkMaintainer / forkMaintainerHint across en/zh/zh-TW/jp/kr.

Why: this is a self-maintained fork shipping its own builds; pointing the updater at upstream
risked overwriting custom builds with upstream releases and hid the fork's own releases.

Tested:
- bunx vitest run src/pages/ActivitySettings.test.tsx src/__tests__/generalSettings.test.tsx (59 pass)
- cd desktop && bun run lint (clean)
Not-tested: full verify (long-running)
Confidence: high
Scope-risk: moderate
2026-06-09 04:36:56 +08:00
你的姓名
87e37d30d1 feat: v0.5.5 — more built-in agents, composer skill/plugin picker, AskUserQuestion notice
Built-in agents:
- Add debugger, security-reviewer, refactor, migration, docs-writer, performance, commit-pr built-ins and register them in getBuiltInAgents().

Desktop:
- AskUserQuestion prompts no longer vanish silently: when an unanswered question card is cleared by turn end (message_complete / error) — e.g. a malformed question call — a visible system notice (chat.questionDropped) is appended instead. Added across en/zh/zh-TW/jp/kr.

Versioning:
- Bump desktop/package.json to 0.5.5 and add release-notes/v0.5.5.md.

Tested:
- bunx vitest run desktop/src/stores/chatStore.test.ts (99 pass, incl. dropped-question notice for message_complete + error, and no notice for non-AskUserQuestion)
- bun test src/tools/AgentTool/builtInAgents.test.ts (pass)
- cd desktop && bun run lint (clean)
- build:windows-x64 + package-smoke (PASS, Claude-Code-Haha-0.5.5-win-x64.exe)
Not-tested: full bun run verify / check:server (long-running)
Confidence: high
Scope-risk: moderate
2026-06-09 03:25:36 +08:00
你的姓名
e66751bfe9 fix(desktop): fully pause message queue on Stop (multi-idle safe)
v0.5.3's one-shot skip only blocked a single auto-drain, but a Stop emits
multiple idle events (message_complete + status idle); the second one still
drained one queued message and flipped the button back to running. Replace
the one-shot skip with a sticky queueDrainPaused flag: Stop pauses all
auto-drains until the user sends their next message (which clears it and
fires immediately, ahead of the queue). The queue then resumes FIFO on the
next idle. Bumps desktop app to 0.5.4 with release notes.

Tested: tsc --noEmit; Vitest chatStore 94 passed (incl. multi-idle stop /
priority message / queue resume); browser end-to-end (Stop keeps button at
Run with queue intact, priority send immediate, queue resumes); Windows x64
NSIS package + package-smoke PASS.
Scope-risk: narrow
Confidence: high
2026-06-08 04:20:33 +08:00
你的姓名
408e04e500 fix(desktop): don't flush message queue on user Stop; remove donation section
Stop no longer flushes the queue: a user-initiated Stop now skips exactly the
auto-drain triggered by its resulting idle (one-shot guard). The queue stays
intact, the next message the user sends fires immediately (priority, not
queued — even with items waiting), and the queue resumes FIFO on the next idle
after that turn. Queue enqueue/drain/edit mechanics are otherwise unchanged.

Also removes the Buy-Me-a-Coffee / donation section from README (zh/en).
Bumps desktop app to 0.5.3 with release notes.

Tested: desktop tsc --noEmit; Vitest chatStore 94 + pages/ActiveSession 43
passed (incl. stop-no-flush / priority-message / queue-resume case); Windows
x64 NSIS package + package-smoke PASS.
Scope-risk: narrow
Confidence: high
2026-06-08 03:58:09 +08:00
你的姓名
e179b36e83 feat(desktop): chat message queue + provider model UX + bundled skills
Desktop chat message queue (v0.5.2):
- Queue follow-up messages (Enter) while the agent is busy; FIFO auto-drain
  on true idle. Collapsible, height-capped to-do panel above the composer so
  it never inflates the composer. Per-item move-to-top/edit/delete/clear.
  Never drains mid-stream, during tool execution, or while a permission
  prompt is pending; Stop cancels the current turn but keeps the queue.
  Per-session isolation. In-memory only (no persistence schema change).

Also included in this commit:
- Settings provider form: model-id comboboxes + fetch-models + per-slot
  context-window auto-fill.
- Bundled skills: defineGoal, pdf, screenshot.
- Bump desktop app to 0.5.2 with release notes.

Tested: desktop tsc --noEmit; Vitest chatStore/pages/ActiveSession 136 passed
(incl. 7 queue tests); browser end-to-end queue smoke; Windows x64 NSIS
package + package-smoke PASS.
Not-tested: full check:desktop suite has pre-existing unrelated failures
(electron packaging, theme cycling, ThinkingBlock label); check:server.
Scope-risk: moderate
Confidence: medium
2026-06-08 03:31:12 +08:00
你的姓名
d88c10c2df fix(server): defer runtime-config restart until session is idle
In-progress generations were interrupted when a set_runtime_config
arrived mid-stream: the handler immediately stopped and restarted the
CLI subprocess. Track per-session busy state from outbound status
events and queue the restart, applying it (with the latest override,
collapsing multiple toggles) once the session returns to idle.

Bumps desktop app to 0.5.1 with matching release notes.

Tested: desktop tsc --noEmit; Windows x64 NSIS package + package-smoke.
Not-tested: check:server, desktop Vitest.
Scope-risk: narrow
Confidence: medium
2026-06-08 02:18:00 +08:00
你的姓名
1923d5553d feat: 服务商模型下拉、跟随系统主题、会话级思考开关、NSIS 自定义安装
桌面端:
- 服务商表单的 4 个 Model ID 改成可下拉+可手动输入;新增"获取模型"按钮
  通过 ${baseUrl}/v1/models 拉取(自动适配 OpenAI Bearer / Anthropic x-api-key)
- 配色主题新增"跟随系统",监听 prefers-color-scheme 自动切换 light/dark
- ModelSelector 新增"思考模式 开/关"会话级开关,默认回退全局
- NSIS 启用许可页+ 自定义安装路径;首次复用 LICENSE 作 license.txt

Server:让会话级 thinking 真正生效
- WS schema 加 thinkingEnabled?: boolean
- handler 把字段写进 runtimeOverrides、纳入 prev/next diff、持久化进 jsonl
- sessionService.appendSessionMetadata / getSessionLaunchInfo / 摘要解析
  补充 thinkingEnabled 字段
- resolveDesktopThinkingMode 支持三态:override 优先(true=enabled、
  false=disabled),undefined 回落到全局 alwaysThinkingEnabled
- RuntimeSettings.thinking 类型放宽为 'enabled' | 'disabled',
  下游 conversationService 已支持,原生拼成 --thinking 参数

i18n:zh / zh-TW / en / jp / kr 同步
2026-06-07 18:39:02 +08:00
程序员阿江(Relakkes)
9e4893ac36 fix(release): prepare unsigned macOS v0.4.0 install path
Bump the Electron desktop package version to 0.4.0, publish a macOS unsigned install helper, and let the release workflow continue when Developer ID signing is not configured.

Tested: bash -n desktop/scripts/install-macos-unsigned.sh
Tested: bun test scripts/pr/release-workflow.test.ts
Tested: bun run scripts/release.ts 0.4.0 --dry
Tested: git diff --check
Tested: bun run check:docs
Tested: bun run check:policy
Confidence: high
Scope-risk: moderate
2026-06-03 22:03:27 +08:00
程序员阿江(Relakkes)
79d8468580 fix(release): add Linux deb package metadata
Ensure Electron Builder has the project URL and maintainer metadata required by Linux deb targets, and lock the fields with release workflow coverage.

Tested: bun test scripts/pr/release-workflow.test.ts
Tested: bun run check:policy
Tested: bun run check:native
Tested: bun run verify
Confidence: high
Scope-risk: narrow
2026-06-03 19:55:10 +08:00
程序员阿江(Relakkes)
85cf04e305 fix(desktop): make macOS signing+notarization explicit and Windows signing optional
- mac.notarize=true + hardenedRuntime + entitlements so a signed CI release
  actually notarizes (gatekeeper smoke + Squirrel.Mac auto-update need it)
- entitlements grant disable-library-validation for the Bun sidecar/node-pty
- local unsigned build passes -c.mac.notarize=false so electron:package still
  works without an Apple account
- release signing-preflight now hard-requires only the Apple secrets; Windows
  cert is optional (unsigned NSIS still auto-updates, just SmartScreen warning)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 14:17:13 +08:00
程序员阿江(Relakkes)
81845fbc49 fix: finalize Electron migration boundaries
Complete the Electron replacement boundary before merging by removing the renderer-side Tauri host fallback, tightening H5/browser access so only desktop navigation is tokenless, and moving desktop release publication to a tag-driven GitHub Actions matrix with a single final publish job.

Constraint: H5/browser capability access must not gain tokenless access through localhost or retired Tauri origins

Constraint: Desktop release artifacts must be built by GitHub Actions from version tags, not treated as local build outputs

Rejected: Keep localhost browser origins trusted for convenience | local browser contexts can access loopback services and must use the H5 token path

Rejected: Publish from each matrix job | partial releases can be created before all platforms finish

Confidence: high

Scope-risk: broad

Directive: Do not reintroduce Tauri origins or localhost browser origins into the trusted desktop origin set without a reviewed security design

Tested: bun test src/server/__tests__/h5-access-policy.test.ts src/server/__tests__/h5-access-auth.test.ts src/server/__tests__/diagnostics-service.test.ts src/server/middleware/cors.test.ts

Tested: bun test scripts/pr/release-workflow.test.ts scripts/release-update-metadata.test.ts

Tested: bun run check:desktop

Tested: bun run check:native

Tested: git diff --check

Not-tested: bun run check:server is blocked by expired quarantine entries server:cron-scheduler, server:providers-real, server:tasks, server:e2e:business-flow, server:e2e:full-flow
2026-06-02 22:42:53 +08:00
程序员阿江(Relakkes)
232855fe77 fix(desktop): serve packaged H5 shell from Electron builds
Electron's sidecar runs outside app.asar, so H5 static files must be available as normal unpacked files. Point the sidecar at the unpacked renderer dist and keep a server fallback for stale app.asar-style paths.

Constraint: Packaged Bun sidecars cannot read app.asar paths with ordinary fs stat calls.
Rejected: Serve H5 from app.asar directly | the external sidecar is not Electron and does not get asar filesystem support.
Confidence: high
Scope-risk: narrow
Directive: Keep package-smoke checking app.asar.unpacked/dist/index.html before changing asarUnpack or H5 dist paths.
Tested: bun test src/server/__tests__/h5-access-auth.test.ts src/server/__tests__/h5-access-policy.test.ts
Tested: bun test desktop/electron/services/sidecarManager.test.ts scripts/quality-gate/package-smoke/index.test.ts
Tested: bun run check:server
Tested: cd desktop && bun run check:electron
Tested: git diff --check
Tested: SKIP_INSTALL=1 SIGN_BUILD=0 MAC_TARGETS=dmg desktop/scripts/build-macos-arm64.sh
Tested: packaged sidecar curl /?serverUrl=...&h5Token=... returned HTTP 200
Not-tested: Gatekeeper notarization for the local ad-hoc DMG
2026-06-01 23:32:56 +08:00
程序员阿江(Relakkes)
386a41e606 feat(desktop): enable Electron migration path
Introduce the Electron desktop shell alongside the existing React renderer and local Bun server boundary. The migration keeps the DesktopHost contract explicit across Tauri, Electron, and browser runtimes while adding Electron main/preload services for dialogs, shell, notifications, updates, tray/window lifecycle, terminal, preview WebContentsView, app mode, and release/package validation.

The commit also carries the latest local main desktop command updates, including agent slash entries and hidden-by-default markdown thinking details, so the packaged Electron build matches the current main UX surface.

Constraint: React renderer, local Bun server, REST/WebSocket, and sidecar boundaries must remain reusable during the migration
Constraint: macOS dev packages are ad-hoc signed and cannot prove Developer ID notarization or Gatekeeper release launch
Rejected: Browser-only smoke validation | it cannot exercise native dialogs, keychain prompts, notification behavior, or packaged app startup
Confidence: medium
Scope-risk: broad
Directive: Do not remove Tauri host support until signed Electron release artifacts pass native OS smoke on macOS, Windows, and Linux
Tested: bun run check:desktop
Tested: cd desktop && bun run check:electron
Tested: CSC_IDENTITY_AUTO_DISCOVERY=false bun run electron📦dir
Tested: bun run test:package-smoke --platform macos --package-kind dir --artifacts-dir desktop/build-artifacts/electron
Tested: Computer Use read packaged Electron app window at desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.app
Not-tested: Developer ID signed/notarized Gatekeeper launch
Not-tested: Real OS notification click-to-session action
Not-tested: Windows and Linux packaged app smoke on real hosts
2026-06-01 22:43:16 +08:00
程序员阿江(Relakkes)
4d6b1855bf release: prepare v0.3.2
Prepare the desktop release metadata and concise release notes while keeping
tagging and release publishing for a later step. The staged local build-script
updates keep desktop commands on checked-in local toolchain paths and avoid
rewriting preview-agent output when the built content is unchanged.

The persistence-upgrade gate now runs the focused desktop Vitest migration
suite in non-watch mode, matching the broader desktop quality lane and avoiding
pre-push termination during release preparation.

Constraint: Release publishing is intentionally deferred per request
Constraint: Desktop release metadata must keep package, Tauri config, Cargo metadata, and Cargo.lock aligned
Confidence: medium
Scope-risk: moderate
Directive: Do not tag v0.3.2 until release dry-run and final release verification are rerun on the release candidate
Tested: bun run scripts/release.ts 0.3.2 --dry
Tested: cd desktop && bun run lint
Tested: bun run check:persistence-upgrade
Tested: git diff --check
Not-tested: Full bun run verify
2026-06-01 02:30:01 +08:00
程序员阿江(Relakkes)
26018fa40b feat(desktop): in-page screenshot capture via html2canvas (mock-tested; real-engine validation deferred)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 17:40:45 +08:00
程序员阿江(Relakkes)
d3e7a35e7a feat(desktop): build & inject preview-agent script into child webview
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 17:40:45 +08:00
程序员阿江(Relakkes)
1464ef538e release: v0.3.1
Prepare the desktop release metadata, concise release notes, and the final terminal help polish for the 0.3.1 release. The release note groups the post-0.3.0 work by user-facing area instead of listing every commit, and the desktop version metadata is aligned for the tag-triggered packaging workflow.

Constraint: GitHub Release body is sourced from release-notes/v0.3.1.md in the tagged commit
Rejected: List every post-0.3.0 commit in the release note | too noisy for this patch release
Confidence: high
Scope-risk: narrow
Tested: cd desktop && bun run test -- src/pages/TerminalSettings.test.tsx --run
Tested: bun run check:desktop
Tested: bun run check:native
Tested: bun run verify (passed=8 failed=0 skipped=2)
Not-tested: Live provider release gate
2026-05-26 00:52:43 +08:00
程序员阿江(Relakkes)
2a89331697 release: prepare v0.3.0 — release notes and version bump
Bump version from 0.2.9 to 0.3.0 across desktop/package.json,
tauri.conf.json, and Cargo.toml. Add v0.3.0 release notes covering
desktop long-session performance, streaming tool previews,
AskUserQuestion reliability, multi-client streaming, and H5 network
fixes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 00:25:38 +08:00
程序员阿江(Relakkes)
5798756e3f Prepare v0.2.9 release candidate
This records the v0.2.9 release notes and aligns desktop package,
Tauri, and Cargo metadata so the release script can create the final
annotated tag after manual validation.

Constraint: Release tag creation is intentionally deferred for manual smoke validation.
Rejected: Run scripts/release.ts now | it would create the release commit and annotated tag before manual review.
Confidence: high
Scope-risk: narrow
Directive: Do not create v0.2.9 tag until the manual release check is complete.
Tested: bun run scripts/release.ts 0.2.9 --dry
Tested: bun run check:native
Not-tested: Full bun run verify and live ChatGPT Official OAuth smoke
2026-05-21 14:28:12 +08:00
程序员阿江(Relakkes)
f2e3a31021 Prepare the v0.2.8 release boundary
The desktop release workflow expects app version files, Cargo.lock, and release-notes/vX.Y.Z.md to agree with the tag. Bump the desktop package and Tauri metadata to 0.2.8 and add the release note that will be used as the GitHub Release body.

Constraint: The release pipeline reads release-notes/v0.2.8.md from the tagged commit.
Confidence: high
Scope-risk: narrow
Directive: Keep desktop/package.json, Cargo.toml, tauri.conf.json, Cargo.lock, and release-notes/vX.Y.Z.md aligned before tagging.
Tested: Not rerun for this metadata-only release prep commit; previous push gate passed for the workflow fix immediately before this commit.
Not-tested: Full release workflow and packaged artifact smoke after tagging.
2026-05-19 02:00:27 +08:00
程序员阿江(Relakkes)
fdfe3b0fb8 Prepare v0.2.7 for manual release validation
The release branch has moved substantially past v0.2.6, so this records the desktop version bump and the release note that will be reviewed before the tag is created. The note groups the large post-v0.2.6 range by user-facing areas instead of replaying the raw commit list.

Constraint: The user wants to push the release-prep commit for manual GitHub development testing before any tag is created.
Rejected: Run scripts/release.ts directly | it would create the release commit and annotated tag before review.
Confidence: high
Scope-risk: narrow
Directive: Do not create v0.2.7 tag until manual GitHub validation is complete.
Tested: bun run scripts/release.ts 0.2.7 --dry
Tested: git diff --check
Not-tested: Full release gate or tag-triggered release workflow.
2026-05-16 18:30:43 +08:00
程序员阿江(Relakkes)
7d2836643c Render model math as readable desktop markdown
Desktop assistant responses previously showed LaTeX source for common
model outputs. The markdown renderer now extracts math outside code spans
and fences, renders it through KaTeX, and applies chat-safe layout rules
for inline, block, multiline, matrix, and long-form formulas.

Constraint: Desktop chat already forces long markdown text to wrap, so KaTeX internals must opt out of that wrapping while display blocks handle overflow locally
Rejected: Render all dollar-delimited text blindly | currency and escaped dollar text would become false-positive formulas
Confidence: high
Scope-risk: narrow
Directive: Keep math extraction before marked parsing and preserve code fence protection when extending markdown rendering
Tested: bun run test --run src/components/markdown/MarkdownRenderer.test.tsx
Tested: bun run lint
Tested: bun run build
Tested: WebUI complex formula screenshot and 390px viewport overflow check
Not-tested: Full desktop gate still has unrelated /goal command hint expectation drift
2026-05-16 13:29:08 +08:00
程序员阿江(Relakkes)
08747bfdd2 Prepare the desktop release boundary for v0.2.6
The release needs a curated GitHub Release body and matching desktop/Tauri version metadata before the annotated tag can trigger the remote packaging workflow. The notes summarize the post-v0.2.5 H5 access recovery, sidebar batch management, file mention search alignment, and desktop polish while keeping generated dependency versions unchanged.

Constraint: GitHub Release body is sourced from release-notes/v0.2.6.md in the tagged commit
Constraint: Desktop package, Tauri config, Cargo.toml, and Cargo.lock must agree on the release version
Rejected: Run the release script directly after manual edits | its default commit message does not capture the release decision context
Confidence: high
Scope-risk: narrow
Directive: Keep future release notes aligned with the tagged version file before pushing tags
Tested: git diff --check
Tested: bun run scripts/release.ts 0.2.6 --dry
Not-tested: Full release gate; this commit only prepares release metadata after markdown review
2026-05-13 11:29:44 +08:00
程序员阿江(Relakkes)
fbce0225f2 Publish open H5 access recovery release
This release packages the emergency H5 token pause so upgraded users can resume desktop and browser chat without generating or carrying a token. The release notes document the temporary open-access behavior and the verification run used before tagging.

Constraint: v0.2.4 restored startup but token auth can still break chat flows for upgraded users

Rejected: Wait for a full token-auth redesign | users are actively blocked and H5 auth is not critical right now

Confidence: high

Scope-risk: narrow

Directive: Restore H5 token controls only with migration coverage and browser chat E2E

Tested: bun run scripts/release.ts 0.2.5 --dry

Tested: bun run scripts/release.ts 0.2.5

Tested: bun test src/server/__tests__/h5-access-auth.test.ts src/server/middleware/cors.test.ts

Tested: bun run check:server

Tested: bun run check:desktop
2026-05-11 17:59:55 +08:00
程序员阿江(Relakkes)
ae7e33cf95 Publish emergency desktop startup recovery release
This release moves the verified desktop H5-auth regression fix into the versioned artifact pipeline so blocked v0.2.3 users can receive a GitHub-built replacement quickly.

Constraint: GitHub Release body is sourced from release-notes/v0.2.4.md in the tagged commit.
Constraint: Release workflow requires the app, Tauri, Cargo, and lockfile versions to match the tag.
Rejected: Ship only the hotfix commit without a release tag | affected desktop users need packaged artifacts from the release workflow.
Confidence: high
Scope-risk: narrow
Directive: Keep v0.2.4 scoped to the startup auth regression; broader H5 improvements belong in a later release.
Tested: bun run scripts/release.ts 0.2.4 --dry
Tested: bun run scripts/release.ts 0.2.4
Not-tested: GitHub release workflow before push; it only runs after the tag is pushed.
2026-05-11 13:45:25 +08:00
程序员阿江(Relakkes)
2950cef662 Prepare v0.2.3 release for H5 mobile access
The post-v0.2.2 changes are now summarized in the release body with the user-facing highlights first, while process-only H5 hardening is described as part of the new feature instead of old-version bug fixes. Desktop and Tauri version files are aligned to the release note version.

Constraint: GitHub Release body is sourced from release-notes/vX.Y.Z.md in the tagged commit
Constraint: Problem fixes should describe issues users could have seen in prior releases, not internal fixups for unreleased work
Rejected: Put every fix commit under 问题修复 | mixes development cleanup with released-user regressions
Confidence: high
Scope-risk: narrow
Tested: git diff --check
Tested: git diff --cached --check
Tested: bun run scripts/release.ts 0.2.3 --dry
Tested: version consistency check for desktop package, Tauri config, Cargo.toml, and Cargo.lock
Not-tested: Full bun run verify; release note and version bump only
2026-05-10 22:40:06 +08:00
程序员阿江(Relakkes)
623f4a5848 chore: bump desktop version to v0.2.2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 23:43:29 +08:00
程序员阿江(Relakkes)
9719726cd2 feat: make quality gates observable and enforceable
The repository now has a measurable PR quality path instead of a loose set of
manual checks. Coverage, quarantine governance, provider smoke, desktop smoke,
and workflow wiring all produce durable reports that contributors and maintainers
can inspect without reconstructing terminal output.

This also fixes the desktop smoke current-runtime path so browser-driven smoke
runs use the desktop default active provider instead of forcing the official
current model, and records that runtime decision as an artifact.

Constraint: Default PR gates must remain non-live and contributor-safe while live model checks stay explicit.
Constraint: Release packaging is still GitHub Actions based, so release preflight must run before the build matrix.
Rejected: Make live provider or desktop smoke mandatory on every PR | secrets, quotas, and model availability are maintainer-controlled.
Rejected: Let PRs lower coverage baselines in the same change | base-branch ratchet comparison must remain authoritative.
Confidence: high
Scope-risk: moderate
Directive: Do not relax coverage or quarantine policy without a maintainer approval label and a fresh quality report.
Tested: ALLOW_CLI_CORE_CHANGE=1 ALLOW_COVERAGE_BASELINE_CHANGE=1 bun run quality:gate --mode pr
Tested: bun run quality:gate --mode baseline --allow-live --only provider-smoke:* --provider-model nvidia-custom:main:nvidia-custom-main --artifacts-dir /tmp/quality-gate-live-smoke
Tested: bun run quality:gate --mode baseline --allow-live --only desktop-smoke:* --provider-model current:current:current-runtime --artifacts-dir /tmp/quality-gate-desktop-smoke-fixed
Tested: git diff --check
Not-tested: Full live release mode with multiple providers in hosted CI; provider credentials and quota remain maintainer-controlled.
2026-05-06 16:25:10 +08:00
程序员阿江(Relakkes)
47e41d68e3 Prepare the desktop 0.2.1 release
This records the user-facing 0.2.1 release notes and aligns the desktop package, Tauri config, Cargo manifest, and lockfile package version so the tag-triggered release workflow can publish the intended build.

Constraint: GitHub Release body is sourced from release-notes/v0.2.1.md in the tagged commit
Constraint: Keep provider and OpenAI login details weak in the release narrative because this release is centered on IM, notifications, context usage, and desktop stability
Rejected: Run scripts/release.ts directly | it creates a generic commit message and tag before review of the release narrative
Confidence: high
Scope-risk: narrow
Directive: Do not tag v0.2.1 from a commit that lacks release-notes/v0.2.1.md or mismatched desktop version files
Tested: bun run scripts/release.ts 0.2.1 --dry
Tested: cargo check
Tested: git diff --check
Not-tested: Live release gate with real provider credentials in this commit step
2026-05-05 22:47:37 +08:00
程序员阿江(Relakkes)
8a81636757 Merge Azure OpenAI auth into local main
Remote main already contains PR #217. Local main had provider context-window and auth-strategy work, so this merge keeps both context resolvers and reconciles the desktop Bun lockfile with the merged desktop package manifest. The accidental remote .nvimlog artifact is excluded from the merge result.

Constraint: Local main was 15 commits ahead and 8 commits behind origin/main after PR #217 was merged remotely
Rejected: Fast-forward pull | local main had unpushed commits
Rejected: Keep remote desktop lockfile verbatim | failed bun install --frozen-lockfile against the merged package.json
Confidence: high
Scope-risk: broad
Directive: Keep provider-configured context windows ahead of OpenAI OAuth model windows so explicit user/provider settings win
Tested: bun install --frozen-lockfile; cd desktop && bun install --frozen-lockfile; git diff --check; bun run check:server; bun run check:desktop; ALLOW_CLI_CORE_CHANGE=1 bun run quality:pr
Not-tested: live provider OAuth login with a real OpenAI account
2026-05-04 21:24:22 +08:00
cynicalight
ff40028ae1 fix: desktop and more test 2026-05-04 17:57:03 +08:00
程序员阿江(Relakkes)
2ca5228171 feat: make IM adapter behavior consistent
WeChat and DingTalk were using different pairing, attachment, and response
state paths, which made the new IM channels behave differently from Feishu
and Telegram. Align the shared pairing model, wire inbound media into the
existing attachment bridge, and map platform response capabilities to their
real APIs: WeChat block streaming plus typing, DingTalk AI Card streaming.

Constraint: WeChat iLink exposes typing and block streaming, but no editable message/card streaming API
Constraint: DingTalk streaming depends on the AI Card create/deliver/stream/finalize lifecycle
Rejected: Fake DingTalk typing with standalone markdown | it would add chat noise instead of platform state
Rejected: Auto-pair WeChat after QR login | it bypasses the shared IM pairing model
Confidence: high
Scope-risk: moderate
Directive: Keep WeChat streaming as block-send unless iLink adds editable messages; keep DingTalk streaming on AI Card APIs
Tested: bun run check:adapters; bun run check:server; cd desktop && bun run test src/stores/adapterStore.test.ts; cd desktop && bun run build; bunx tsc -p adapters/tsconfig.json --noEmit; git diff --check
Not-tested: Live WeChat and DingTalk platform smoke with real production credentials
2026-05-03 21:08:12 +08:00
程序员阿江(Relakkes)
fa5fda24d0 feat: notify users when desktop attention is needed
Add native system notifications as a desktop-wide attention channel for permission prompts and scheduled task completion. The implementation keeps notification presentation owned by the OS, adds a user-facing enable switch with permission handling, and lets scheduled tasks choose desktop notifications without routing that channel through IM adapters.

Constraint: Notifications must use OS-native APIs without custom sound playback.
Constraint: Desktop channel is local-only and must not be sent through IM adapter delivery.
Rejected: Browser Notification API | not reliable inside the packaged Tauri desktop runtime.
Rejected: Treat desktop as an IM channel | would leak a local-only channel into server-side adapter sending.
Confidence: high
Scope-risk: moderate
Directive: Keep notification styling at the OS layer; business code should only provide title, body, dedupe, and routing decisions.
Tested: bun run check:desktop
Tested: bun run quality:pr
Tested: Computer Use macOS debug app verification for settings toggle, permission prompt, scheduled task desktop channel, and task-run polling dedupe
Not-tested: Windows and Linux native runtime smoke tests on physical hosts
2026-05-03 16:45:32 +08:00
程序员阿江(Relakkes)
7a5f813601 Prepare the desktop 0.2.0 milestone for release
This release marks the desktop app's shift from a thin CLI wrapper toward a fuller local Coding Agent workspace. It carries the reviewed v0.2.0 release notes, bumps desktop package metadata, and refreshes Cargo.lock from the pinned Tauri stack before publishing the tag-driven GitHub Actions release.

Constraint: GitHub Release body is sourced from release-notes/v0.2.0.md in the tagged commit
Constraint: Desktop releases are built remotely from the pushed v0.2.0 tag
Rejected: Publish as v0.1.10 | the release consolidates several desktop workflow and quality-gate milestones, so v0.2.0 better communicates the scope
Confidence: high
Scope-risk: narrow
Directive: Keep the v0.2.0 tag on this commit unless the release notes or version metadata are changed together
Tested: bun run scripts/release.ts 0.2.0 --dry
Tested: bun run quality:gate --mode release --allow-live --provider-model codingplan:main:codingplan-main --provider-model minimax:main:minimax-main (18 passed, 0 failed, 0 skipped)
2026-05-02 18:11:20 +08:00