382 Commits

Author SHA1 Message Date
程序员阿江(Relakkes)
523db62b3b Merge selected chat context references 2026-05-13 14:08:24 +08:00
程序员阿江(Relakkes)
52b11697e1 feat: make selected context reusable in desktop chat
Workspace and transcript selections now flow into the composer as lightweight references so users can carry exact snippets into the next prompt without file-only workarounds. The prompt formatter keeps workspace and chat excerpts separate, and the composer avoids sending chat snippets as fake file attachments.

Constraint: Selection references must prepare model context without polluting backend file attachment payloads.
Rejected: Reuse file attachments for chat selections | would leak chat:// pseudo paths into file-oriented payloads.
Confidence: high
Scope-risk: moderate
Directive: Keep chat-selection references prompt-only unless the backend gains a first-class chat context attachment type.
Tested: bun run check:desktop
Tested: bun run verify
Tested: agent-browser UI smoke for workspace, user-message, and assistant-message selections
Not-tested: Strict Chrome extension channel; connection timed out, local browser automation covered the flow.
2026-05-13 14:08:12 +08:00
程序员阿江(Relakkes)
be01a64f1c Keep external sessions visible without reopening desktop
Desktop users can receive new sessions from IM adapters or scheduled tasks while the app stays open. The sidebar now refreshes on mount, visible focus, and a low-frequency visible-only interval, with a manual refresh control and in-flight request dedupe so the fix does not create avoidable polling pressure.

Constraint: Sessions can be created outside the desktop process by IM and scheduler entrypoints
Rejected: WebSocket push for this patch | broader server contract change than needed for the reported stale list
Confidence: high
Scope-risk: narrow
Directive: Keep session-list refresh visible-only and deduped before lowering intervals or adding more triggers
Tested: cd desktop && bunx vitest run src/components/layout/Sidebar.test.tsx src/i18n/index.test.tsx
Tested: cd desktop && bun run lint
Tested: bun run check:desktop
Tested: Browser smoke on isolated desktop backend/frontend with refresh button click
Not-tested: Full coverage gate is blocked by unrelated root test port/timeouts; changed lines coverage reported 100% (59/59)
2026-05-13 12:45:36 +08:00
程序员阿江(Relakkes)
5d66b5a94b Merge desktop zoom shortcut support
Bring the detached worktree implementation for issue #407 back into
local main while preserving a merge boundary for review and rollback.

Constraint: Local main already contains post-release-boundary desktop fixes
Confidence: high
Scope-risk: narrow
Tested: bun run verify in detached worktree before merge
Not-tested: Full gate on local main before this merge commit
2026-05-13 12:43:17 +08:00
程序员阿江(Relakkes)
95407422c0 Support IDE-style desktop zoom shortcuts
The desktop shell needed predictable zoom controls across macOS,
Windows, and Linux without depending on browser defaults. This adds a
small app zoom controller that persists a bounded zoom factor, maps the
IDE-style primary-modifier shortcuts, and uses native Tauri webview zoom
when available with a browser fallback for H5/dev runs.

Constraint: Issue #407 requested IDE-style zoom shortcuts across macOS, Windows, and Linux
Rejected: Enable Tauri built-in zoom hotkeys only | it would not cover browser/H5 fallback or app-owned persistence consistently
Confidence: high
Scope-risk: narrow
Directive: Keep app zoom bounded and validated before applying persisted localStorage values
Tested: bun run verify; browser smoke on http://127.0.0.1:45679/ with Meta+= and Meta+0
Not-tested: Manual Windows/Linux desktop runtime smoke
2026-05-13 12:43:07 +08:00
程序员阿江(Relakkes)
a54e97d532 Allow desktop confirm dialogs to reach Tauri
Superpowers can trigger plan approval or browser confirm flows inside the desktop shell. Tauri's dialog plugin shims window.confirm through the message command, but the desktop capability only allowed file open/save dialogs, so Windows rejected confirm with an ACL error and left the flow blocked.

Constraint: Tauri plugin-dialog 2.7 routes alert/confirm through the message permission.
Rejected: Grant dialog:default | broader than needed for this bugfix.
Confidence: high
Scope-risk: narrow
Directive: Keep dialog message permission whenever browser confirm or alert shims are available in desktop.
Tested: cd desktop && bun run test -- --run src/__tests__/tauriCapabilities.test.ts
Tested: bun run check:native
Tested: bun run check:desktop
2026-05-13 12:30:15 +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)
276b67083a Align file mention search with CLI path display
Desktop search results were visually misleading when many directories shared the same basename, because the UI emphasized the basename and the server ranking allowed deep basename matches to outrank direct path-prefix matches. This makes search rows show the insertable relative path and ranks direct path-prefix matches before unrelated same-name directories.

Constraint: Desktop @ file suggestions should match the CLI mental model for path search.

Rejected: Keep basename plus parent-path rows | it hides the distinction between src/, src/hooks/, and desktop/src in the primary text.

Confidence: high

Scope-risk: narrow

Directive: Preserve path-prefix ranking ahead of basename-only matches for directory searches.

Tested: bun test src/server/__tests__/filesystem.test.ts

Tested: cd desktop && bun run test -- FileSearchMenu.test.tsx ChatInput.test.tsx

Tested: bun run check:server

Tested: bun run check:desktop
2026-05-13 10:38:14 +08:00
程序员阿江(Relakkes)
3f2ce2a6c7 Make the app icon render as a single clean badge
The generated logo asset carried both an opaque square canvas and an inner rounded tile, so the desktop empty state and sidebar rendered a visible nested background. Rebuilt the canonical app icon with transparent outside corners, one white rounded badge, and a centered mark, then regenerated the Tauri icon set and docs raster assets from that source.

Constraint: Existing desktop views consume /app-icon.png directly with no wrapper background to remove.

Rejected: Add CSS masking around each img usage | would leave native app icons and docs assets with the same nested canvas problem.

Confidence: high

Scope-risk: narrow

Directive: Keep desktop/src-tauri/app-icon.png as the canonical 1024 RGBA source before regenerating platform icons.

Tested: cd desktop && bun run build; npm run --loglevel=error docs:build; git diff --check; sips alpha and size checks; iconutil icns size ladder; Chrome DevTools light and forced-dark screenshots.

Not-tested: full bun run verify gate, per prior instruction to skip local gate for this logo pass.
2026-05-13 10:38:14 +08:00
程序员阿江(Relakkes)
f41e786748 Align desktop file mentions with CLI search
Desktop @ file search was recursively walking the filesystem with a local skip list, which let Python and Node generated directories leak into results and diverged from CLI behavior. Route candidate discovery through the same git-first model: tracked files, untracked files with exclude-standard, and ripgrep fallback for non-git folders, then derive selectable directories from those candidates.

Constraint: Desktop picker must select both files and directories without surfacing ignored project artifacts.
Constraint: No new dependencies; reuse the existing git, ripgrep, settings, and ignore utilities.
Rejected: Maintain a hardcoded directory denylist | it would drift from CLI and miss project-specific ignore rules.
Rejected: Full recursive readdir scanning | it ignores git index semantics and makes large dependency trees visible.
Confidence: high
Scope-risk: moderate
Directive: Keep desktop @ file candidate discovery aligned with src/hooks/fileSuggestions.ts before changing ranking or ignore behavior.
Tested: bun test src/server/__tests__/filesystem.test.ts
Tested: cd desktop && bun run test -- FileSearchMenu.test.tsx ChatInput.test.tsx
Tested: cd desktop && bun run lint && bun run test -- --run && bun run build
Tested: bun run check:server
Tested: bun run check:coverage
Tested: bun run verify
Not-tested: Native Windows/Linux manual UI smoke; path handling relies on cross-platform git/ripgrep wrappers and normalized relative paths.
2026-05-13 10:38:13 +08:00
程序员阿江(Relakkes)
7f08e7a3bc Refresh brand assets around the new app logo
The desktop app and documentation need to present the new logo consistently, so the canonical 1024px source icon now feeds the Tauri icon family, desktop public assets, README images, and VitePress brand imagery.

Constraint: Tauri bundle icons are generated assets and must be refreshed from the source icon rather than relying on README or public image replacement alone
Rejected: Rename logo paths | existing README, desktop, and docs references can keep stable paths and pick up the new files directly
Confidence: high
Scope-risk: moderate
Directive: Regenerate desktop/src-tauri/icons whenever desktop/src-tauri/app-icon.png changes
Tested: cd desktop && bun run build; npm run --loglevel=error docs:build; git diff --check; iconutil expanded icon.icns size ladder
Not-tested: full local quality gate per request
2026-05-13 10:38:13 +08:00
程序员阿江(Relakkes)
fc3a6ea2e1 Make batch-selected sidebar rows easier to scan
The previous batch selection state let adjacent selected sessions visually merge into a single block. This keeps the existing row structure but adds per-row spacing, a transparent baseline border, and a subtle selected-row shadow so the selection is easier to read without changing behavior.

Constraint: Keep the change local to the desktop sidebar and avoid new dependencies.
Rejected: Add global sidebar CSS tokens | unnecessary for this small component-level state and harder for changed-line coverage.
Confidence: high
Scope-risk: narrow
Directive: Keep batch selection spacing on the row wrapper so adjacent selected rows remain visually separated.
Tested: bun run verify
2026-05-13 10:38:13 +08:00
程序员阿江(Relakkes)
a381bf0412 Make pure white theme complete across desktop surfaces
The pure white appearance option needed to avoid warm-theme leakage while preserving the existing warm classic brand theme. This adds the white theme mode, keeps local browser startup from reusing stale H5 server URLs in dev, and moves visible legacy warm surfaces onto theme tokens.

Constraint: H5 server auth policy, CORS policy, SDK routes, adapter routes, and IM access paths must not change for a visual theme fix
Rejected: Rename the original light theme to pure white | the original theme is a warm classic palette, not a neutral white workspace
Confidence: high
Scope-risk: moderate
Directive: Keep structural white-theme borders neutral; reserve the warm brand color for selected states, primary actions, and small accents
Tested: cd desktop && bun run test -- src/__tests__/generalSettings.test.tsx src/lib/desktopRuntime.test.ts src/lib/persistenceMigrations.test.ts src/stores/uiStore.test.ts src/stores/settingsStore.test.ts
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: bun test src/server/__tests__/settings.test.ts src/server/__tests__/h5-access-policy.test.ts src/server/__tests__/h5-access-auth.test.ts src/server/middleware/cors.test.ts
Tested: Browser smoke at http://127.0.0.1:5173 with data-theme=white, no H5 token prompt, /status inspector visible, inspector border #DDE3EA
Not-tested: Full bun run verify gate
2026-05-13 10:38:13 +08:00
程序员阿江(Relakkes)
9b540554cc Prevent desktop draft text leaking between tabs
The desktop chat composer is a single mounted component under the active session view, so switching tabs reused the same local draft state. The fix keeps unsent composer input and attachments keyed by session tab and restores the matching draft when the active tab changes.

Constraint: Must preserve unsent drafts while isolating them per session tab
Rejected: Force-remount ChatInput with a React key | wider UI lifecycle change and more risk to composer substate
Confidence: high
Scope-risk: narrow
Directive: Do not make composer draft state global without preserving per-session isolation
Tested: cd desktop && bun run test -- ChatInput.test.tsx
Tested: cd desktop && bun run lint
Tested: bun run check:desktop
Tested: agent-browser reproduced the leak on an unmodified baseline and verified the fixed UI keeps history tab textarea empty while restoring the new tab draft
Not-tested: Windows 11 packaged release manual smoke
2026-05-13 10:38:13 +08:00
程序员阿江(Relakkes)
d41d5a87f0 Make H5 access easier to discover in Settings
H5 access is a user-facing desktop sharing entrypoint, so it should not be buried inside the broad General settings surface. Move it into its own Settings tab and make the empty QR state point users at the token generation action before a scan link exists.

Constraint: Preserve the existing H5 store API and token lifecycle while changing only the desktop settings surface.
Rejected: Keep H5 access inside General with a larger visual block | still hides a strong product surface in a catch-all page.
Confidence: high
Scope-risk: narrow
Directive: Keep H5 access as a first-class settings entry unless the navigation model is redesigned holistically.
Tested: cd desktop && bun run test -- src/__tests__/generalSettings.test.tsx src/i18n/index.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: bun run verify
Not-tested: Live H5 token generation against an enabled local H5 service; current local desktop state had H5 disabled.
2026-05-13 10:38:13 +08:00
程序员阿江(Relakkes)
dbb8c95905 Simplify batch cleanup to explicit selection only
The age-based quick cleanup buttons overlapped poorly with the sidebar time groups and created ambiguity around what would be deleted. Keeping batch mode focused on all/selected sessions makes the destructive path easier to understand while preserving the existing confirmation and server deletion behavior.

Constraint: Desktop batch deletion should stay routed through the existing selected-session confirmation flow.
Rejected: Rename the age-based cleanup buttons | still leaves a low-value destructive shortcut in the primary batch panel.
Confidence: high
Scope-risk: narrow
Directive: Add future destructive cleanup shortcuts only when their target set is unambiguous in the current filtered session list.
Tested: cd desktop && bun run test src/components/layout/Sidebar.test.tsx
Tested: bun run check:desktop
Tested: git diff --check
Not-tested: Manual desktop click-through after removing the buttons.
2026-05-12 17:49:51 +08:00
程序员阿江(Relakkes)
20c32ff1cf Reject SPA fallback responses during browser startup
Browser startup previously accepted any 200 response from /health. In Vite-only runs that can be the SPA fallback HTML, which lets startup continue until a later API call fails with an opaque JSON parse error.

Constraint: The H5 shell and Vite dev server can both return 200 for unknown routes.
Rejected: Only improve the visible StartupError copy | it would still misclassify the backend readiness state
Confidence: high
Scope-risk: narrow
Directive: Keep the healthcheck shape validation aligned with src/server/index.ts /health responses
Tested: cd desktop && bun run test src/lib/desktopRuntime.test.ts
Tested: cd desktop && bun run test src/lib/desktopRuntime.test.ts src/__tests__/generalSettings.test.tsx
Tested: cd desktop && bun run lint
Tested: bun run check:desktop
2026-05-12 15:46:32 +08:00
程序员阿江(Relakkes)
417e8eaa4f Add token QR workflow for H5 LAN access
H5 LAN access now uses an explicit desktop confirmation, then shows a QR launch URL that carries both the serverUrl and one-time-visible H5 token. Browser startup consumes that token from the QR URL, verifies it before storing, and requires auth for non-loopback H5 endpoints while preserving local desktop bootstrap behavior.

Constraint: LAN H5 exposes desktop capabilities and must be opt-in with a visible warning.
Constraint: QR launch has to preserve routed public URLs, so the link carries serverUrl as well as h5Token.
Rejected: Store the raw token in Zustand | it would make accidental UI diagnostics or snapshots more likely to leak it
Confidence: high
Scope-risk: moderate
Directive: Do not remove the serverUrl query parameter from QR links without testing non-root publicBaseUrl deployments
Tested: cd desktop && bun run test src/lib/desktopRuntime.test.ts src/__tests__/generalSettings.test.tsx
Tested: cd desktop && bun run lint
Tested: bun run check:desktop
2026-05-12 15:23:25 +08:00
程序员阿江(Relakkes)
1e27d4634a Bring batch session cleanup into main
The worktree implementation is ready for local mainline testing, and main
only advanced with unrelated chat URL wrapping. Merge the completed batch
session-management change so the desktop UI and server API move together.

Constraint: Main already contains an unrelated chat URL wrapping fix
Confidence: high
Scope-risk: moderate
Directive: Keep the merged feature commit intact; it carries the detailed implementation rationale and verification record
Tested: Feature commit verified with server batch tests, server gate, desktop gate, and browser UI smoke before merge
Not-tested: Full verify rerun after merge; merge touched no conflicting files beyond the committed feature set
2026-05-12 13:42:58 +08:00
程序员阿江(Relakkes)
b0fcbba9f0 Make desktop session cleanup practical at list scale
The sidebar had only single-session deletion, which made stale or noisy
session lists expensive to maintain. This adds a batch-management lane in
the desktop UI and a server endpoint that deletes multiple sessions while
preserving per-session failure reporting and cleanup behavior.

Constraint: Session deletion must preserve existing transcript and adapter cleanup semantics
Constraint: Desktop UI should reuse the shared confirmation dialog instead of introducing a second modal surface
Rejected: Delete all selected sessions through repeated client DELETE calls | weaker partial-failure handling and duplicated cleanup orchestration
Rejected: Use a generic checkmark entry icon | it did not communicate batch deletion clearly enough
Confidence: high
Scope-risk: moderate
Directive: Keep batch deletion routed through the server batch endpoint so rollback and adapter cleanup stay centralized
Tested: bun test src/server/__tests__/sessions.test.ts -t batch-delete
Tested: bun run check:server
Tested: cd desktop && bun run check:desktop
Tested: browser UI smoke for group select, shift range select, delete confirmation, 7/30 day cleanup, Cmd+A filtered selection, and Escape exit
Not-tested: Live provider-backed session generation; this change covers session list management after sessions already exist
2026-05-12 13:42:45 +08:00
程序员阿江(Relakkes)
b438347d2d Prevent long chat URLs from breaking message layout
Long uninterrupted URLs can otherwise force user message bubbles beyond the chat column. The fix keeps the bubble constrained to its parent and allows safe breaks inside continuous URL text, with the same guard applied to markdown paragraphs and links.

Constraint: Issue #378 reports desktop chat overflow when a conversation contains a long URL
Rejected: Add horizontal scrolling to user messages | this preserves the overflow instead of fixing normal chat readability
Confidence: high
Scope-risk: narrow
Tested: cd desktop && bunx vitest run src/components/chat/UserMessage.test.tsx src/components/chat/MessageList.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: bun run check:desktop
Tested: browser layout fixture PASS shell=619 bubbleClient=619 bubbleScroll=619
Not-tested: full root quality gate
Related: https://github.com/NanmiCoder/cc-haha/issues/378
2026-05-12 13:15:54 +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)
1597685d37 Keep H5 access open while token auth is paused
The H5 token gate still caused chat startup and runtime failures after the desktop startup hotfix, so the default server path now stays open for browser and LAN access. Explicit auth remains available through SERVER_AUTH_REQUIRED=1 or --auth-required for deployments that intentionally need it.

Constraint: Current H5 token state is blocking active users from normal chat usage

Rejected: Keep automatic remote-host auth with broader client-side token handling | still leaves existing upgraded clients vulnerable to stale or missing token state

Confidence: high

Scope-risk: moderate

Directive: Do not re-enable default H5 token auth without a migration and end-to-end browser chat verification

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

Tested: cd desktop && bun run test src/lib/desktopRuntime.test.ts src/__tests__/generalSettings.test.tsx

Tested: bun run check:server

Tested: bun run check:desktop
2026-05-11 17:59:03 +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)
d1211e4dca Keep desktop smoke on the configured backend
Browser-mode startup now respects an explicit Vite desktop server URL before falling back to same-origin H5 serving. This keeps local desktop smoke tests pointed at the real API server while preserving same-origin behavior for packaged H5 access.

Constraint: Vite dev smoke serves the web app and API on different loopback ports
Rejected: Treat same-origin as always preferred | Vite would answer /api requests with HTML and the chat surface never becomes ready
Confidence: high
Scope-risk: narrow
Tested: cd desktop && bun run test -- src/lib/desktopRuntime.test.ts src/api/client.test.ts --run
Tested: bun run check:desktop
Tested: bun run quality:gate --mode baseline --allow-live --only 'provider-smoke:*' --only 'desktop-smoke:*' --provider-model codingplan:main:codingplan-main
Not-tested: Full bun run quality:pr after this commit; it will run again during push
2026-05-10 23:01:43 +08:00
程序员阿江(Relakkes)
d37d752310 Stabilize chat scroll tests for release gate
The release push gate exposed that the MessageList scroll tests fired synthetic user scrolls before the component's programmatic auto-scroll guard had reset. Waiting for the requestAnimationFrame reset keeps the tests aligned with the runtime behavior where users cannot scroll in the same frame as mount auto-scroll.

Constraint: Pre-push quality gate must pass before publishing the release tag
Rejected: Bypass pre-push verification | would publish without the repo's required PR quality evidence
Confidence: high
Scope-risk: narrow
Tested: cd desktop && bun run test -- src/components/chat/MessageList.test.tsx --run
Tested: bun run check:desktop
Tested: bun run check:coverage
Not-tested: Full bun run quality:pr after this commit; it will run again during push
2026-05-10 22:53:23 +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)
6ae98a2f4e fix(desktop): align H5 mobile composer and diff scrolling
H5 exposes the desktop chat surfaces in a much narrower viewport, so the empty-session composer needs the same inset treatment as active sessions and generated diff rows need intrinsic width instead of compressing long code into the phone viewport.

Constraint: Keep desktop layout and short diff-row backgrounds unchanged while enabling sideways scrolling on H5.
Rejected: Force wrapping long diff lines | it makes code harder to inspect and diverges from desktop diff behavior.
Confidence: high
Scope-risk: narrow
Directive: Keep workspace diff rows content-width driven when adjusting mobile code preview styling.
Tested: cd desktop && bun run test -- src/pages/EmptySession.test.tsx --run
Tested: cd desktop && bun run test -- src/components/workspace/WorkspacePanel.test.tsx --run
Tested: cd desktop && bun run lint
Not-tested: Full bun run verify gate; change is scoped to desktop UI styling and covered by narrow Vitest plus typecheck.
2026-05-10 21:51:32 +08:00
程序员阿江(Relakkes)
775ddb9c51 fix(desktop): make H5 access reachable from LAN
Packaged desktop builds started the sidecar on loopback only, so phones on the same WiFi could not connect to the H5 URL. The server now binds to LAN interfaces while keeping the desktop control URL on loopback, serves the bundled H5 frontend, and reports a LAN public URL when H5 access is enabled.

Constraint: Packaged Tauri resources place ../dist under Contents/Resources/_up_/dist.
Rejected: Bind the desktop control URL to 0.0.0.0 | desktop clients should keep using loopback for local control.
Confidence: high
Scope-risk: moderate
Directive: Keep packaged H5 resource lookup aligned with Tauri resource mapping when changing bundle resources.
Tested: bun run check:server
Tested: cd desktop/src-tauri && cargo test --lib
Tested: cd desktop && bun run test -- desktopRuntime.test.ts generalSettings.test.tsx
Tested: SKIP_INSTALL=1 ./desktop/scripts/build-macos-arm64.sh
Tested: Packaged claude-sidecar smoke served H5 HTML while listening on *:39876
Not-tested: Physical phone browser test on the local WiFi network
2026-05-10 19:41:25 +08:00
程序员阿江(Relakkes)
1749d3f392 fix(desktop): fix right-click context menu not working on sidebar conversation items
- Skip startDragging() on right-click to prevent Tauri IPC from
  disrupting the contextmenu event on macOS
- Allow context menu to render when sidebar is collapsed
- Fix auto-dismiss effect to not self-clear contextMenu state
2026-05-10 18:34:18 +08:00
程序员阿江(Relakkes)
ffef5de9ef fix(desktop): fix project context chip left-aligned in compact mode 2026-05-10 12:24:51 +08:00
程序员阿江(Relakkes)
6e675f2d88 fix(desktop): prevent jump-to-latest button from flickering during streaming
Programmatic scroll calls (scrollIntoView) trigger onScroll events mid-animation,
causing updateAutoScrollState to momentarily see a non-bottom position and flash
the button on/off. Guard against this with isProgrammaticScrollingRef.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 12:15:27 +08:00
程序员阿江(Relakkes)
a00f1882ab fix(desktop): reclaim H5 chat viewport space
The mobile H5 shell was spending one row on the drawer button and another row on session metadata, which left less space for the actual chat on phones. The mobile shell now shares the drawer row with the active session title and metadata, while the session body suppresses its duplicate header on H5.

The mobile composer also restores horizontal breathing room and safe-area bottom padding so the input panel no longer sits flush against the viewport edge.

Constraint: Keep desktop/Tauri layout unchanged and scope the change to browser H5 mobile behavior.
Rejected: Keep the separate mobile menu row | it preserves the exact waste reported in phone screenshots.
Confidence: high
Scope-risk: narrow
Directive: Do not reintroduce a second mobile session title row without checking a phone-sized H5 viewport.
Tested: cd desktop && bun run test src/components/layout/AppShell.test.tsx src/pages/ActiveSession.test.tsx src/components/chat/ChatInput.test.tsx --run
Tested: git diff --check
Tested: agent-browser 393x852 H5 layout smoke with screenshot /tmp/h5-layout-verify/mobile-h5-layout.png
Not-tested: cd desktop && bun run lint, blocked by pre-existing Settings.tsx responseLanguage/responseLangDraft errors outside this change
2026-05-10 12:11:23 +08:00
程序员阿江(Relakkes)
99c964e0ca Merge response language selector into main
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 11:57:04 +08:00
程序员阿江(Relakkes)
b693aa53b4 feat: add response language selector in General settings
Expose the CLI's `language` setting in the desktop app's General tab.
Users can now pick from 21 pre-defined languages via a dropdown (value
maps directly to CLI language names such as "chinese", "japanese").
Selecting a language writes it to ~/.claude/settings.json so the CLI
injects the language instruction into every session's system prompt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 11:54:17 +08:00
程序员阿江(Relakkes)
2a6c7dc67a Merge token usage view into local main
Integrate the Token usage settings page on top of the newer local main branch, preserving the existing H5 access router surface while adding the activity stats API route.

Constraint: Local main already contained H5 access router changes after the Token usage worktree base.
Rejected: Prefer either router branch during conflict resolution | both API surfaces are independent and must remain registered.
Confidence: high
Scope-risk: narrow
Directive: Keep h5-access and activity-stats routes registered together in src/server/router.ts.
Tested: Conflict marker scan for src/server/router.ts
Not-tested: Post-merge desktop/server checks pending
2026-05-10 11:38:33 +08:00
程序员阿江(Relakkes)
ace7f7b657 feat: add desktop token usage activity view
Expose local Claude Code CLI transcript usage in Settings so users can inspect recent token consumption and daily activity without leaving the desktop app.

The page uses server-side transcript aggregation for session, message, tool, model-token, and subagent token data. Daily token buckets use assistant message timestamps, and daily session counts use active parent sessions for the same date bucket so resumed sessions and cross-midnight work do not produce token-only days. Cache accounting is bumped to v5 to force recomputation under the corrected daily semantics.

Constraint: Usage data must come from local Claude Code CLI transcripts rather than mock/demo data.
Constraint: Desktop navigation keeps Token usage directly above Diagnostics.
Rejected: Bucket all token usage by session start date | hides resumed-session and cross-midnight consumption from the actual day it was spent.
Confidence: high
Scope-risk: moderate
Directive: Keep daily token and daily session counts on the same date-bucketing semantics.
Tested: bun run check:desktop
Tested: bun run check:server
Tested: Browser verification for Token usage in English and Chinese locale date labels
Not-tested: Full bun run verify quality gate
2026-05-10 11:37:49 +08:00
程序员阿江(Relakkes)
5f9faaf01d feat: support H5 mobile chat access
H5 browser use needs to keep local desktop WebUI testing open while giving remote phones a usable chat-first surface. This change scopes browser auth by origin and target host, hides non-chat desktop chrome on H5 mobile, compacts the empty-session composer, and unifies mobile selectors behind a full-width bottom sheet with an explicit close action.

Constraint: Local browser development may bypass H5 auth only for loopback or private LAN server hosts; public or remote hosts still require an H5 token.

Constraint: Mobile H5 scope is chat-first; settings and scheduled-task surfaces stay hidden instead of fully redesigned.

Rejected: Reuse desktop popovers on mobile | hover/anchored dropdown behavior leaves key actions hard to dismiss and cramped on narrow screens.

Rejected: Let any localhost origin bypass remote auth | it would let arbitrary local pages access public H5 servers without a token.

Confidence: medium

Scope-risk: moderate

Directive: Keep future H5 selector popups on MobileBottomSheet unless a selector needs a reviewed custom mobile interaction.

Tested: cd desktop && bun run lint

Tested: cd desktop && bun run test -- src/pages/EmptySession.test.tsx src/components/chat/ChatInput.test.tsx src/lib/desktopRuntime.test.ts src/components/shared/RepositoryLaunchControls.test.tsx src/components/controls/PermissionModeSelector.test.tsx src/components/controls/ModelSelector.test.tsx src/components/shared/DirectoryPicker.test.tsx src/__tests__/pages.test.tsx

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

Tested: Chrome mobile viewport smoke for context, model, permission, project, branch, and worktree bottom sheets with no horizontal overflow.

Not-tested: Full bun run verify quality gate.
2026-05-10 11:30:03 +08:00
程序员阿江(Relakkes)
cc9bcb2017 Make H5 chat usable on phone-sized browsers
The browser H5 surface now switches to a phone-oriented shell: the sidebar becomes a closed-by-default drawer, chat stays primary, workspace and terminal panels stay off the mobile chat surface, composer controls use larger touch targets, and mobile menus avoid desktop-only widths and keyboard hints. Desktop and Tauri sidebar behavior remain on the existing store-driven path.

Constraint: H5 is personal/team browser access layered on the existing desktop web UI, so the normal desktop app must keep its current layout behavior.

Rejected: Share the global sidebarOpen default for mobile first paint | it can flash the drawer open before effects run on a phone.

Confidence: high

Scope-risk: moderate

Directive: Keep mobile-only layout branching behind useMobileViewport() && !isTauriRuntime() unless a future task explicitly redesigns the native desktop shell.

Tested: cd desktop && bunx vitest run src/hooks/useMobileViewport.test.tsx src/components/layout/AppShell.test.tsx src/components/layout/Sidebar.test.tsx src/pages/ActiveSession.test.tsx src/components/chat/ChatInput.test.tsx src/components/controls/PermissionModeSelector.test.tsx

Tested: cd desktop && bun run lint

Tested: cd desktop && bun run build
2026-05-10 01:11:24 +08:00
程序员阿江(Relakkes)
b4242d894d Prevent remote H5 tokens from leaking into local browser sessions
Browser H5 startup now binds the in-memory bearer token only when the selected server URL is non-loopback, so stored remote credentials cannot follow a later localhost, 127.0.0.1, or IPv6 loopback startup. Token verification errors also use the structured HTTP status when available instead of relying only on message text.

Constraint: Browser H5 may reuse localStorage across remote and local server URLs.

Rejected: Clear all remembered H5 connection state on every loopback startup | preserving the remote URL is useful for the next remote retry and the token alone is the leak risk.

Confidence: high

Scope-risk: narrow

Directive: Keep browser auth token assignment gated by requiresH5AuthForServerUrl before adding new bootstrap paths.

Tested: cd desktop && bunx vitest run src/api/client.test.ts src/api/websocket.test.ts src/lib/desktopRuntime.test.ts src/components/layout/AppShell.test.tsx
2026-05-10 00:55:30 +08:00
程序员阿江(Relakkes)
5c1583f852 Preserve recoverable browser H5 startup paths behind proxies
Remote browser bootstrap now keeps reverse-proxy path prefixes, recognizes IPv6 loopback as local, and converts remote health or verify failures into recoverable H5 connection prompts instead of falling back to the generic startup error surface. Token invalidation clears only the stored token so users can retry without re-entering the server address.

Constraint: Review fixes must stay inside the existing Task 4 browser-runtime scope without changing the Tauri localhost startup path
Rejected: Clear both stored server URL and token on remote bootstrap failures | it forces unnecessary re-entry after stale credentials
Directive: Any future browser-mode startup error for non-loopback backends should remain recoverable through H5ConnectionView unless the desktop/Tauri contract changes
Confidence: high
Scope-risk: narrow
Tested: cd desktop && bunx vitest run src/api/client.test.ts src/api/websocket.test.ts src/lib/desktopRuntime.test.ts src/components/layout/AppShell.test.tsx
Tested: cd desktop && bun run lint
Tested: git diff --check -- desktop/src/api/client.ts desktop/src/api/websocket.ts desktop/src/lib/desktopRuntime.ts desktop/src/components/layout/H5ConnectionView.tsx desktop/src/components/layout/AppShell.tsx desktop/src/api/client.test.ts desktop/src/api/websocket.test.ts desktop/src/lib/desktopRuntime.test.ts desktop/src/components/layout/AppShell.test.tsx
Not-tested: Live reverse-proxy browser session against a real remote H5 server
2026-05-10 00:35:42 +08:00
程序员阿江(Relakkes)
ba1807541a Enable authenticated browser bootstrap for remote H5 access
Browser-mode startup now preserves the desktop localhost path while prompting for H5 credentials when a non-loopback backend requires verification. The API client and websocket layer share a central token source so REST and session sockets authenticate consistently without leaking the token into diagnostics.

Constraint: Preserve the Tauri startup path and default localhost browser behavior
Rejected: Reuse the generic startup error view for H5 auth failures | it blocks the credential-entry recovery path
Directive: Non-loopback browser startup is the only path that should require saved H5 verification without re-checking the desktop bootstrap contract
Confidence: high
Scope-risk: moderate
Tested: cd desktop && bunx vitest run src/api/client.test.ts src/api/websocket.test.ts src/components/layout/AppShell.test.tsx
Tested: cd desktop && bun run lint
Tested: git diff --check -- desktop/src/api/client.ts desktop/src/api/websocket.ts desktop/src/lib/desktopRuntime.ts desktop/src/components/layout/H5ConnectionView.tsx desktop/src/components/layout/AppShell.tsx desktop/src/api/client.test.ts desktop/src/api/websocket.test.ts desktop/src/components/layout/AppShell.test.tsx
Not-tested: Live remote H5 browser session against a running server
2026-05-10 00:26:01 +08:00
程序员阿江(Relakkes)
4865b4f206 Keep H5 settings failures visible without persisting raw tokens
Limit the legacy fallback to missing H5 endpoints, preserve last known H5 settings on real load failures, and move the generated token lifetime into the General settings component so the raw token clears after copy or timeout instead of living in global state.

Constraint: Task 3 remains limited to desktop settings store, UI, and tests
Rejected: Treat every H5 load failure as disabled defaults | hides real outages and overwrites useful last-known state
Rejected: Keep raw tokens in Zustand until manually dismissed | re-exposes secrets after reopening Settings
Confidence: high
Scope-risk: narrow
Directive: Only 404/405 H5 endpoint misses should degrade to disabled defaults; all other H5 load failures must preserve state and surface h5AccessError
Tested: cd desktop && bunx vitest run src/__tests__/generalSettings.test.tsx src/stores/settingsStore.test.ts
Tested: cd desktop && bun run lint
Tested: git diff --check -- desktop/src/stores/settingsStore.ts desktop/src/pages/Settings.tsx desktop/src/stores/settingsStore.test.ts desktop/src/__tests__/generalSettings.test.tsx desktop/src/i18n/locales/en.ts desktop/src/i18n/locales/zh.ts
2026-05-10 00:14:34 +08:00
程序员阿江(Relakkes)
a677163e0d Make H5 browser access manageable from desktop settings
Add the desktop-side H5 settings client, store state, and General tab controls so users can opt in, regenerate tokens, manage origins, and copy the browser URL without touching unrelated desktop flows.

Constraint: Task 3 is limited to desktop Settings UI and store wiring only
Rejected: Expand into AppShell or browser runtime work now | reserved for later tasks in the plan
Confidence: high
Scope-risk: narrow
Directive: Keep H5 fetchAll integration tolerant of missing endpoint responses so existing settings loads do not regress
Tested: cd desktop && bun run test -- src/__tests__/generalSettings.test.tsx src/stores/settingsStore.test.ts
Tested: cd desktop && bun run lint
2026-05-09 23:57:52 +08:00
程序员阿江(Relakkes)
065a80580b Render scheduled task summaries as markdown
Scheduled task results can contain assistant-authored markdown, but the
runs panel previously displayed that content as plain pre-wrapped text.
Reusing the desktop markdown renderer keeps task summaries aligned with
chat and settings surfaces while adding a compact prose variant for the
narrow log panel.

Constraint: Desktop task logs need dense formatting without introducing a new markdown dependency
Rejected: Keep whitespace-pre-wrap summary text | markdown syntax remains visible in completed task runs
Confidence: high
Scope-risk: narrow
Directive: Keep scheduled run summary rendering on the shared MarkdownRenderer path so links, lists, inline code, and future markdown fixes stay consistent
Tested: cd desktop && bun run test src/components/markdown/MarkdownRenderer.test.tsx src/components/tasks/TaskRunsPanel.test.tsx
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Tested: bun run check:desktop
Tested: agent-browser E2E against isolated CLAUDE_CONFIG_DIR with real backend and Vite UI; verified strong/li/code/link DOM output and no raw markdown bold markers
Not-tested: Tauri native packaged app shell
2026-05-09 22:43:00 +08:00
程序员阿江(Relakkes)
da477c2b4b Merge session title sanitation into main
Bring the detached worktree fix onto local main after verifying the title-generation regression path and local quality checks.

Constraint: The worktree commit was based on an older main commit, while local main already contained later chat scroll fixes.
Confidence: high
Scope-risk: moderate
Directive: Keep title sanitation shared across CLI, server, and desktop read paths.
Tested: bun run check:server
Tested: bun run check:desktop
Tested: bun run verify (7 passed, 1 failed on existing aggregate agent-utils coverage baseline)
Not-tested: live model title-generation smoke
2026-05-09 22:34:54 +08:00
程序员阿江(Relakkes)
179f79b794 fix: sanitize generated session titles
Slash-command and skill prompts can enter the title-generation path as internal XML breadcrumbs. The async title request previously treated that transport metadata as user prose, so a generated ai-title could persist raw command tags and override the normal session title.

This routes title sources and generated title output through a shared sanitizer, preserving user-visible command names and arguments while dropping unrelated internal XML metadata. Desktop fallback title rendering now applies the same cleanup so existing transcripts with bad ai-title entries recover on read.

Constraint: Session titles can be produced by both desktop server logic and the SDK generate_session_title control request.
Rejected: Only clean desktop session display | leaves CLI and remote title generation able to persist bad titles again
Confidence: high
Scope-risk: moderate
Directive: Keep generated-title input and persisted-title readback on the shared sanitizer; do not add a title path that reads command XML directly.
Tested: bun test src/utils/__tests__/sessionTitle.test.ts src/utils/__tests__/sessionTitleText.test.ts
Tested: bun run check:server
Tested: bun run check:desktop
Tested: bun run verify (7 passed, 1 failed on existing aggregate agent-utils coverage baseline)
Not-tested: live model title-generation smoke
2026-05-09 22:34:27 +08:00
程序员阿江(Relakkes)
50d4679f51 Merge chat scroll recovery into main
Bring the detached worktree fix into the local main line while preserving the newer main behavior that passes session context into interactive chat message blocks.

Constraint: Local main already contains six unpublished commits on top of origin/main
Constraint: Merge conflict only affected MessageList message rendering around sessionId propagation
Rejected: Overwrite main's MessageBlock call shape | would regress AskUserQuestion and permission interactions that need sessionId
Confidence: high
Scope-risk: moderate
Directive: Keep MessageBlock sessionId propagation when editing chat rendering; AskUserQuestion depends on it
Tested: cd desktop && bun run test -- MessageList.test.tsx
Not-tested: Full verify after merge; previous verify remains blocked by agent-utils global coverage baseline
2026-05-09 21:52:31 +08:00
程序员阿江(Relakkes)
6382115de9 fix: keep chat tabs from losing scroll context
Chat sessions need predictable navigation when users switch tabs or read history during streaming. This preserves each session's scroll position, defaults fresh sessions to the latest message, and adds a compact jump-to-latest affordance when auto-follow is paused.

The PR gate also exposed that provider-scoped scheduled tasks must force the sdk-cli entrypoint when launched through the sidecar, so the same change records that runtime contract and its regression assertion.

Constraint: Desktop chat should not force-scroll while the user is reading older messages
Constraint: Scheduled task provider env must not inherit stale parent model runtime values
Rejected: Persist scroll positions in localStorage | session scroll is transient UI state and should not survive app restarts
Confidence: high
Scope-risk: moderate
Directive: Do not remove the sdk-cli entrypoint marker from provider-scoped cron tasks without rerunning the sidecar launcher regression
Tested: cd desktop && bun run test -- MessageList.test.tsx
Tested: cd desktop && bun run lint
Tested: bun test src/server/__tests__/cron-scheduler-launcher.test.ts src/utils/__tests__/themeWords.test.ts
Tested: bun run check:desktop
Tested: bun run check:server
Tested: bun run check:native
Not-tested: bun run verify still fails on pre-existing agent-utils global coverage baseline below threshold
Not-tested: Chrome extension E2E blocked by Codex Chrome Extension communication timeout after plugin diagnostics passed
2026-05-09 21:51:34 +08:00
程序员阿江(Relakkes)
184323ba02 Merge AskUserQuestion multi-select fix into main
The detached desktop bugfix worktree contains the AskUserQuestion multi-select handling change, while local main already carries separate local commits. Merge instead of cherry-picking so main records the worktree integration point without dropping local-only history.

Constraint: Local main and the detached worktree had diverged
Rejected: Reset main to the worktree HEAD | would discard local main commits
Confidence: high
Scope-risk: narrow
Directive: Keep AskUserQuestion selection mode controlled by the explicit multiSelect marker
Tested: cd desktop && bun run test -- src/components/chat/AskUserQuestion.test.tsx src/components/chat/chatBlocks.test.tsx src/components/chat/MessageList.test.tsx
Tested: bun run check:desktop
Not-tested: Full root bun run verify after merge
2026-05-09 21:49:59 +08:00