6435 Commits
Author SHA1 Message Date
陈大猫 eb56936e9b Prevent cloud sync from stopping active agent turns (#4045)
Fixes #4044.
2026-10-28 04:13:49 -07:00
陈大猫 6da42ebc53 feat(settings): custom temp directory for SFTP staging (#4035)
Fixes #4033

User-configurable Netcatty temp root (Settings → System → Temporary Files) with backward-compatible default, Choose folder / manual path / Reset. Electron smoke PASS tip f6f32b69.
2026-10-28 03:02:39 -07:00
陈大猫andCursor f0483488e1 feat(plugins): polish manager metadata and support verified README images (#4043)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-28 16:32:41 +08:00
陈大猫 263133f2ea Fix select-before-connect for grid and list hosts (#4042)
* Fix select before connect in host collections

* ci: retrigger lint-and-test (notes persistence flake unrelated to #4042)

* chore: retrigger CI after unrelated NotesManager.persistence flake
2026-10-28 01:28:27 -07:00
陈大猫 887c5779b5 fix(ai): submit PowerShell agent wrapper with CR only [4036]
* fix(ai): submit PowerShell agent wrapper with CR only [4036]

* ci: retrigger lint-and-test after runner cancel [4036]

Previous lint-and-test job was cancelled mid-step (Lint passed; Test skipped).
No code change.

* ci: retrigger lint-and-test (stuck cancelled job on prior tip) [4036]
2026-10-28 01:03:28 -07:00
27f26d8e69 feat(monitor): 优化磁盘IO展示与系统分区告警 [4030] (#4031)
* feat(monitor): 优化磁盘IO展示与系统分区告警 [4030]

* fix(monitor): 修复磁盘监控评审问题 [4030]

* fix(monitor): align Partitions bars with Memory; hide bare / label

Label-above-bar for partition list; single-root `/` hides the label and
centers the bar like Memory/CPU (unchanged). Multi-disk keeps top align +
system alerts. Disk IO adds a spacer row to track usage labels.

Review crops under .github/review/ for PR discussion (drop before merge OK).

* fix(monitor): keep bare-/ align; multi-disk labels stay left

Address Chris density feedback: keep the single root label hidden and vertically centered with Memory, and restore side-by-side labels for multiple disks. Remove the Disk I/O spacer and update the review crops.

* chore(monitor): drop PR #4031 discussion review crops

---------

Co-authored-by: wendeng.dong <wendeng.dong@sailuntire.com>
Co-authored-by: 陈大猫 <16399091+binaricat@users.noreply.github.com>
2026-10-27 23:54:58 -07:00
陈大猫 30a74f7c1d refactor(settings): simplify AI tool access configuration (#3957)
Move infrequent Tool Access / MCP / privacy / HTTP setup into focused dialogs; keep status and clear actions on the main page. Rebased onto current main after locale/settings conflicts.

Codex CLEAN (gpt-6.1-terra). CI lint-and-test green. Focused privacy/MCP/guidance tests passed on rebase tip. No release.
2026-10-27 20:59:11 -07:00
陈大猫 631d04b654 Fix Deck parenthesized prompt readiness (#4029)
* fix: recognize parenthesized Deck shell prompts

* fix: recognize Deck prompts with special path characters
2026-10-27 20:58:50 -07:00
陈大猫andJoseph Hau e98e236d54 fix(ai): recognize macOS zsh default prompts for PTY readiness (#3980)
Continuation of #3969 by @hexart (Joseph Hau). Preserves original commit recognition and adds spaces / %#→# coverage so idle macOS zsh terminals accept AI commands.

Codex CLEAN (gpt-6.1-terra) vs main. CI green. No release.

Co-authored-by: Joseph Hau <hexart@gmail.com>
2026-10-27 20:38:16 -07:00
陈大猫 1e063dfa3c fix(ai): stop automatic model discovery retries after failure (#4002)
Gate ModelSelector discovery on settled error; preserve explicit Refresh and config resets. Component regressions included.

Codex CLEAN (gpt-6.1-terra) vs main. CI green on tip. No release.
2026-10-27 20:38:13 -07:00
8b5b0c4416 fix(ai): keep dropped AI chats recoverable with dangling marking + /rebind; reuse workspace id on merge (#4019)
* fix(ai): keep dropped AI chats recoverable with dangling marking and /rebind

Closing a member terminal or dissolving a workspace used to clear the
chat's active pointer, making it invisible (scope rank 0) and
unrecoverable from the UI even though the record survived in storage.

- orphan cleanup now marks dropped chats `scopeDangling: true` and keeps
  record + active pointer intact; the flag clears when the target
  returns or the chat is rebound
- `/chats` lists dangling chats with a numbered inline affordance and
  hint line
- new `/rebind <n>` panel action rewrites `scope` to the panel's current
  scope, clears the marker and restores the active pointer
- i18n keys added for en / zh-CN / zh-TW / es / ru

Stacked on #4018. Refs #4015 (R2).

* fix(workspace): reuse existing workspace id when merging tabs with a workspace

createWorkspaceFromSessions silently no-opped when either merged tab
already belonged to a workspace (e.g. dragging a workspace pane onto a
standalone terminal), and the older dissolve->recreate behavior
regenerated the id that workspace-scoped AI chats bind to.

When one of the merged tabs has a workspace, the orphan tab now joins
that existing workspace (pane inserted next to the anchor session, tab
slot collapsed), so workspace-scoped chat bindings survive. Merging two
standalone tabs still creates a fresh workspace.

Stacked on #4018. Refs #4015 (R3).

* fix(ai): persist cleaned active map on dangling chat rebind

rebindSessionScope was updating React state to drop stale old-scope
pointers, then rebuilding localStorage from the pre-rebind snapshot and
resurrecting them. Persist the same cleaned map via rebindActiveSessionMap.

* fix(ai): persist rebind map inside setState; wire backup actions on terminal panel

- Write cleaned active-session map from inside the rebind updater so a
  deferred React setState cannot skip snapshot/localStorage persistence.
- Pass exportSessionsBackup/importSessionsBackup through TerminalLayerSupport
  and include them in AI_CHAT_SIDE_PANEL_AI_STATE_KEYS so history-drawer
  backup buttons work on the normal terminal path.

* fix(ai): guard backup restore races and use app-wide live targets for /chats

- Skip restore when in-memory sessions already exist; apply snapshot,
  storage write, and AI state emit atomically inside the empty-state path
  so peer useAIState instances see the restore.
- Thread validAIScopeTargetIds into AIChatSidePanel as liveScopeTargetIds
  so /chats does not mark chats bound to other open terminals as dangling.

* fix(ai): open rebound chat in panel view and refresh /chats listing

- rebindSessionScope also sets the panel view to the rebound session so an
  existing draft/other chat does not keep hiding the recovery.
- After /rebind, rewrite the stored listing instead of rebuilding from the
  stale render so the chat is no longer offered as dangling.

* fix(workspace): invert join split when dragged pane owns workspace; refresh /chats titles

- When merging a workspace-owned dragged pane onto a standalone tab, the
  orphan is inserted — invert the drop position so the previewed side matches.
- Compare workspaces in AIChatSidePanel memo so /chats picks up renames.

* fix(ai): validate live sessions array on boot; mark imported orphans dangling

- Reject parseable non-array store values (e.g. {}) via readLiveSessionsArray
  so boot restore is not blocked by a corrupt-but-truthy value.
- After manual import, re-run orphan cleanup with the last known live target
  set so chats bound to closed scopes become dangling and /rebind-able.

* fix(ai): merge imported sessions before orphan cleanup

Apply import merge to the snapshot/ref synchronously, then run dangling
marking, so a deferred setState cannot let cleanup rewrite over the import.

* fix(ai): mark restored/imported orphans dangling even with no live targets

Restore and import do not change live terminals/workspaces, so the orphan
cleanup effect will not re-run. Always call cleanup against the last known
live target set after those paths — an empty set is a valid observed state
(nothing mounted), not an unavailable snapshot — so chats bound to missing
scopes become dangling and /chats can offer /rebind.

* fix(ai): apply backup restore synchronously before dangling cleanup

Do not gate restore + orphan marking on a setState updater having run.
A deferred updater left didRestore false, skipped cleanup, and could leave
restored chats with missing scopes unmarked and unrebindable from /chats.

* fix(ai): complete /rebind from a partial slash picker selection

Selecting Rebind after typing `/re` left the composer unchanged, so a
following number became `/re 1` and could be sent to the agent. Replace the
slash query with `/rebind ` the same way Rename does.

* fix(ai): replace hostIds on rebind; skip non-array backup generations

- Rebind builds a fresh destination scope (including hostIds from the
  panel) instead of spreading the old scope, so history matching follows
  the new terminal/workspace host.
- readLatestGeneration treats valid JSON that is not a session array as
  unusable and continues to older generations, matching corrupt skips.

* fix(ai): revalidate dangling chat before /rebind from stale /chats listing

Skip rebind when the cached entry is deleted or already bound to a live
scope; drop stale listing entries so a second panel cannot steal the chat.

* fix(ai): reject malformed /rebind numbers

Require the entire trimmed argument to be digits so /rebind 1foo and
/rebind 1.5 show usage instead of silently targeting index 1.

---------

Co-authored-by: binaricat <binaricat@users.noreply.github.com>
Co-authored-by: 陈大猫 <16399091+binaricat@users.noreply.github.com>
2026-10-27 20:26:21 -07:00
GOUKI9999andNetcatty Maintainer afb0585016 feat(ai): /rename & /chats slash commands + AI session durability layer (#4018)
* feat(ai): add /rename and /chats slash commands plus a session durability layer

Panel slash commands (#4015 feedback):
- /rename <title> renames the current chat via updateSessionTitle; the
  command is intercepted in ChatInput's system-command branch and never
  reaches the agent. Empty title shows a usage hint. The history drawer
  gains an inline rename affordance.
- /chats renders a dismissible system-style note listing the panel's
  visible chats (title / agent backend / workspace-or-terminal scope with
  a dangling marker / relative last-active time; current chat marked).
  Deliberately not named /resume: session.resume already means
  flow-recovery-after-cancel. Listing logic is pure (aiChatsListing.ts)
  so a future rebind action can attach per-entry actions.
- i18n keys added for en/es/ru/zh-CN/zh-TW.

Durability layer (additive; cleanup/eviction semantics untouched):
- Every successful store write schedules a debounced (~2s) mirror of the
  exact persisted JSON to {userData}/ai-sessions-backup/ through a new
  aiSessionsBackupBridge: atomic temp+rename writes, 5 rolling
  generations, timestamped names.
- On boot, a missing/empty live store is restored from the newest
  parseable backup generation. The asymmetry is deliberate: empty ->
  restore, non-empty -> leave alone, so restored data can never
  resurrect explicitly deleted chats.
- Manual export/import in the history drawer via real file dialogs
  (fixed-path fallback where dialogs are unavailable); import merges by
  id with newer updatedAt winning.

Tests: bridge rotation/corruption/rejection, restore decisions, merge
semantics, debounce throttle, mirror-on-write, slash interception and
/chats listing seams. eslint clean; tsc unchanged vs baseline.

* fix(ai): repair sessions backup IPC and restore/import guards

- Forward write/export payloads through preload unchanged so the main
  bridge receives a string json (was double-wrapped → invalid-json).
- Restore from disk only when the live store is missing or corrupt;
  treat a valid [] as an intentional clear. Flush the debounced mirror
  on beforeunload so deletions land before quit.
- Require id + messages[] + finite updatedAt when parsing backup/
  import entries so malformed objects cannot reach pruneSessionsForStorage.

Co-authored-by: Netcatty Maintainer <binaricat@users.noreply.github.com>

* fix(ai): complete /rename from partial slash and harden import shape

- Selecting Rename from the slash picker replaces the active slash token
  with `/rename ` so a following title is intercepted, not sent to the agent.
- parseBackupSessions also requires title, agentId, and a scope object with
  a string type before accepting an imported/backup entry.

Co-authored-by: Netcatty Maintainer <binaricat@users.noreply.github.com>

* fix(ai): validate backup messages and skip prune on synced restore

- Drop backup/import sessions whose messages lack id/role/timestamp.
- When cloud AI-session sync is enabled, restore parsed sessions without
  pruneSessionsForStorage so local retention cannot truncate synced history.

Co-authored-by: Netcatty Maintainer <binaricat@users.noreply.github.com>

* fix(ai): export prepareRestoredSessions helper

Missed in the previous commit; required by useAIState boot restore and tests.

Co-authored-by: Netcatty Maintainer <binaricat@users.noreply.github.com>

* fix(ai): require message content on backup import; raise disk cap to 64MB

* fix(ai): normalize corrupt sessions store to [] before boot restore

* fix(ai): skip non-array backup generations when reading latest

* fix(ai): emit sessions change on backup restore; skip unusable gens

* fix(ai): treat empty backup gen as wipe; align gen usability with parser

* fix(ai): seed backup on boot for live store; report durable import count

* fix(ai): emit sessions change after backup import

* docs(ai): clarify sessions backup recovers in-profile store only

---------

Co-authored-by: binaricat <binaricat@users.noreply.github.com>
2026-10-27 20:04:42 -07:00
Joseph Hau 6d65c89ecf fix(appearance): 修复 macOS 托盘面板毛玻璃效果 (#4028) 2026-10-28 10:43:02 +08:00
陈大猫 2f214b8725 feat(plugin-agent): reuse host global Agent runtime with sandbox Chat sample (#4012)
Merge global Agent host runtime + sandbox Chat sample on top of #4011.

Electron plugin smoke PASS at fb691318c (S0–S4; S5 BLOCKED-FIXTURE). Codex CLEAN. No release.
2026-10-27 19:37:38 -07:00
陈大猫 350917fa0e feat(plugins): consolidate foundation and permission settings (#4011)
Merge plugin foundation + permission settings.

Electron plugin smoke PASS at stacked tip fb691318c (S0–S4; S5 BLOCKED-FIXTURE). Codex CLEAN. Marketplace artifact lifecycle deferred.
2026-10-27 19:37:19 -07:00
陈大猫 fb691318c4 chore(ci): retrigger lint-and-test after runner shutdown 2026-10-28 09:45:20 +08:00
陈奇 9c1af5c73f ci(plugin-agent): retrigger lint-and-test after runner shutdown
Empty commit only. Prior tip 57e682dc lint-and-test was cancelled by
runner shutdown mid-suite (no failing assertions). Re-runs via Actions
API are blocked for the fine-grained PAT; push retriggers PR checks.
2026-10-28 09:45:12 +08:00
陈大猫 555f193d23 fix(sync): block convergent AI session shrink after merge (#4025)
* fix(sync): block convergent AI session shrink after merge

Related #4017 — convergent smartMerge could drop many AI sessions
post-merge (e.g. 46→7) and still report success; classic syncAll
already guarded this. Gate upload/apply with detectSuspiciousShrink.

* fix(sync): drop explicit any in convergent shrink override test

* Fix blocked chat shrink advancing sync baseline
2026-10-27 10:36:19 -07:00
陈大猫 88dd20a918 Fix Enter delay with large command history (#4026)
* Fix command history Enter delay (#4022)

* Fix cleared shell history race
2026-10-27 10:11:05 -07:00
陈奇 57e682dc83 fix(agent): publish correlated names for unnamed tool results 2026-10-28 00:57:50 +08:00
陈奇 2671cf9f20 test(plugin-ai): deliver pagehide before closing fixture 2026-10-27 15:05:30 +00:00
陈奇 672a2bf406 merge: integrate verified plugin foundation into global Agent 2026-10-27 14:56:42 +00:00
陈奇 9f09af3bda Merge selected-context workspace focus correction 2026-10-27 14:29:42 +00:00
陈奇 5931eb14f0 fix(plugins): revalidate selected session context after workspace focus changes 2026-10-27 14:26:01 +00:00
陈奇 f5e2a64dfb fix(plugins): retain exact sample chat lease across modal reopen 2026-10-27 13:39:03 +00:00
陈奇 ca2280ea8b docs(plugins): record cancelled row redesign and preserved foundation fixes 2026-10-27 13:12:10 +00:00
陈奇 7e7b05620f Revert "feat(plugins): share borderless installed settings rows"
This reverts commit e4eb33856b.
2026-10-27 13:04:03 +00:00
陈奇 25e0c834da fix(plugins): preserve global chat transcript in compact modal 2026-10-27 12:51:07 +00:00
陈奇 1f0741698d docs(plugins): consolidate foundation landing ledger and sample provenance 2026-10-27 12:39:52 +00:00
陈奇 50fda91424 fix(plugins): invalidate author identity after rejected install refresh
Reuse the selection-token snapshot comparison for list and install, including a rejected stale or withdrawn selection. Preserve synchronous unavailable-source validation before the asynchronous list operation. The loaded-row regression rejects installation without downloading or executing a package.
2026-10-27 12:32:48 +00:00
陈奇 fc37ac48e1 Merge actual two-profile sync composition coverage into plugin foundation landing 2026-10-27 12:29:25 +00:00
陈奇 d035cbea38 Merge honest directory enumeration availability into plugin foundation landing 2026-10-27 12:29:25 +00:00
陈奇 b3895a477d Merge author identity refresh and borderless plugin rows into plugin foundation landing 2026-10-27 12:29:25 +00:00
陈奇 db1223d161 Merge verified main #4010 #4013 #4016 into plugin foundation landing
# Conflicts:
#	index.css
2026-10-27 12:29:25 +00:00
陈奇 14ed19d2ed test(plugins): compose two-profile settings sidecar collect and hydration 2026-10-27 12:23:21 +00:00
陈奇 a36a906292 fix(plugins): negotiate directory enumeration only with a secure adapter 2026-10-27 12:23:20 +00:00
陈奇 e4eb33856b feat(plugins): share borderless installed settings rows
Apply the exact six-file patch from implement_plugin_row_layout, based on 0c05a96fa1. Patch SHA-256: 5c58150fc3a7f72169b1a23ad1410cf37c51051b29bd6600bf30e848a9f366d6. Native visual acceptance remains pending.
2026-10-27 12:19:09 +00:00
陈奇 b14b65679f fix(plugins): invalidate mounted author identity on catalog changes 2026-10-27 12:18:27 +00:00
陈奇 f8616f5d3a fix(plugin-agent): clear stale status when conversation history changes 2026-10-27 12:11:17 +00:00
陈奇 0cab1046cf docs(plugin-agent): record composer correction package hash 2026-10-27 12:06:06 +00:00
陈奇 a56d1ab785 fix(plugins): skip destroyed WebContents during scope broadcasts 2026-10-27 12:04:34 +00:00
陈奇 cbe89995e6 fix(plugins): identify host operation and targets in Ask dialog 2026-10-27 12:02:41 +00:00
陈奇 72383a50c9 fix(plugin-agent): keep composer visible while transcript scrolls 2026-10-27 11:57:35 +00:00
陈奇 0c05a96fa1 fix(plugins): align avatar delivery with registry v2 contract 2026-10-27 11:48:35 +00:00
陈奇 05a773b426 docs(plugins): clarify default directory enumeration boundary 2026-10-27 11:25:54 +00:00
陈奇 da16b90e9e feat(plugins): add author avatars and host-controlled maintainer badges 2026-10-27 11:25:54 +00:00
2796d1113a fix(mcp): reconnect external calls that race a closed socket (#4016)
A peer FIN can leave readyState closed while destroyed is still false.
Concurrent tool calls wrote into that socket, hit writeAfterFIN, and
failed with "TCP connection lost" instead of sharing one reconnect.
Treat that socket as down, and make later callers join the in-flight re-auth.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com>
2026-10-27 19:01:45 +08:00
陈奇 8bcad28f9d fix(plugin-agent): skip home config repair for delegated Claude turns 2026-10-27 10:18:51 +00:00
陈奇 59edc87ed4 fix(plugin-agent): wait for stopped driver before replacement turn 2026-10-27 09:30:21 +00:00
陈奇 5944a02238 fix(plugin-agent): bind startup and approved actions to current authority 2026-10-27 09:28:49 +00:00