diff --git a/build/config.yml b/build/config.yml
index 8cd3fd4..5c9641d 100644
--- a/build/config.yml
+++ b/build/config.yml
@@ -8,7 +8,7 @@ info:
description: "Cursor助手"
copyright: "© 2026, Cursor助手"
comments: "Cursor助手"
- version: "0.0.48"
+ version: "0.0.49"
dev_mode:
root_path: .
diff --git a/build/darwin/Info.dev.plist b/build/darwin/Info.dev.plist
index 8fac693..ae8e0e1 100644
--- a/build/darwin/Info.dev.plist
+++ b/build/darwin/Info.dev.plist
@@ -17,9 +17,9 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 0.0.48
+ 0.0.49
CFBundleVersion
- 0.0.48
+ 0.0.49
LSMinimumSystemVersion
12.0.0
LSUIElement
diff --git a/build/darwin/Info.plist b/build/darwin/Info.plist
index 66da336..a81944c 100644
--- a/build/darwin/Info.plist
+++ b/build/darwin/Info.plist
@@ -17,9 +17,9 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 0.0.48
+ 0.0.49
CFBundleVersion
- 0.0.48
+ 0.0.49
LSMinimumSystemVersion
12.0.0
LSUIElement
diff --git a/build/linux/nfpm/nfpm.yaml b/build/linux/nfpm/nfpm.yaml
index 65df4a0..15d72c2 100644
--- a/build/linux/nfpm/nfpm.yaml
+++ b/build/linux/nfpm/nfpm.yaml
@@ -6,7 +6,7 @@
name: "Cursor助手"
arch: ${GOARCH}
platform: "linux"
-version: "0.0.48"
+version: "0.0.49"
section: "default"
priority: "extra"
maintainer: ${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>
@@ -24,24 +24,24 @@ contents:
- src: "./build/linux/Cursor助手.desktop"
dst: "/usr/share/applications/Cursor助手.desktop"
-# Default dependencies for the GTK4 + WebKitGTK 6.0 stack (Ubuntu 24.04+ / Debian 13+)
+# Default dependencies for Debian 12/Ubuntu 22.04+ with WebKit 4.1
depends:
- - libgtk-4-1
- - libwebkitgtk-6.0-4
+ - libgtk-3-0
+ - libwebkit2gtk-4.1-0
-# Distribution-specific overrides for different package formats
+# Distribution-specific overrides for different package formats and WebKit versions
overrides:
- # RPM packages for Fedora / RHEL / AlmaLinux / Rocky Linux
+ # RPM packages for RHEL/CentOS/AlmaLinux/Rocky Linux (WebKit 4.0)
rpm:
depends:
- - gtk4
- - webkitgtk6.0
-
- # Arch Linux packages
+ - gtk3
+ - webkit2gtk4.1
+
+ # Arch Linux packages (WebKit 4.1)
archlinux:
depends:
- - gtk4
- - webkitgtk-6.0
+ - gtk3
+ - webkit2gtk-4.1
# scripts section to ensure desktop database is updated after install
scripts:
@@ -50,26 +50,13 @@ scripts:
# preremove: "./build/linux/nfpm/scripts/preremove.sh"
# postremove: "./build/linux/nfpm/scripts/postremove.sh"
-# If you build your app with -tags gtk3 (legacy WebKit2GTK 4.1 stack — supported through v3.0.x, removed in v3.1),
-# replace the depends/overrides above with these:
-#
-# depends:
-# - libgtk-3-0
-# - libwebkit2gtk-4.1-0
-# overrides:
-# rpm:
-# depends:
-# - gtk3
-# - webkit2gtk4.1
-# archlinux:
-# depends:
-# - gtk3
-# - webkit2gtk-4.1
-#
# replaces:
# - foobar
# provides:
# - bar
+# depends:
+# - gtk3
+# - libwebkit2gtk
# recommends:
# - whatever
# suggests:
diff --git a/build/windows/info.json b/build/windows/info.json
index 60e49dc..4a10068 100644
--- a/build/windows/info.json
+++ b/build/windows/info.json
@@ -1,10 +1,10 @@
{
"fixed": {
- "file_version": "0.0.48"
+ "file_version": "0.0.49"
},
"info": {
"0000": {
- "ProductVersion": "0.0.48",
+ "ProductVersion": "0.0.49",
"CompanyName": "Cursor助手",
"FileDescription": "Cursor助手",
"LegalCopyright": "© 2026, Cursor助手",
diff --git a/build/windows/nsis/wails_tools.nsh b/build/windows/nsis/wails_tools.nsh
index f6ae659..0afe3ef 100644
--- a/build/windows/nsis/wails_tools.nsh
+++ b/build/windows/nsis/wails_tools.nsh
@@ -14,7 +14,7 @@
!define INFO_PRODUCTNAME "Cursor助手"
!endif
!ifndef INFO_PRODUCTVERSION
- !define INFO_PRODUCTVERSION "0.0.48"
+ !define INFO_PRODUCTVERSION "0.0.49"
!endif
!ifndef INFO_COPYRIGHT
!define INFO_COPYRIGHT "© 2026, Cursor助手"
@@ -27,16 +27,8 @@
!endif
!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINST_KEY_NAME}"
-!ifndef WAILS_INSTALL_SCOPE
- !define WAILS_INSTALL_SCOPE "machine"
-!endif
-
!ifndef REQUEST_EXECUTION_LEVEL
- !if "${WAILS_INSTALL_SCOPE}" == "user"
- !define REQUEST_EXECUTION_LEVEL "user"
- !else
- !define REQUEST_EXECUTION_LEVEL "admin"
- !endif
+ !define REQUEST_EXECUTION_LEVEL "admin"
!endif
RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}"
@@ -123,40 +115,23 @@ RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}"
WriteUninstaller "$INSTDIR\uninstall.exe"
SetRegView 64
- !if "${WAILS_INSTALL_SCOPE}" == "user"
- WriteRegStr HKCU "${UNINST_KEY}" "Publisher" "${INFO_COMPANYNAME}"
- WriteRegStr HKCU "${UNINST_KEY}" "DisplayName" "${INFO_PRODUCTNAME}"
- WriteRegStr HKCU "${UNINST_KEY}" "DisplayVersion" "${INFO_PRODUCTVERSION}"
- WriteRegStr HKCU "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXECUTABLE}"
- WriteRegStr HKCU "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
- WriteRegStr HKCU "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
+ WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${INFO_COMPANYNAME}"
+ WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${INFO_PRODUCTNAME}"
+ WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${INFO_PRODUCTVERSION}"
+ WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXECUTABLE}"
+ WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
+ WriteRegStr HKLM "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
- ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
- IntFmt $0 "0x%08X" $0
- WriteRegDWORD HKCU "${UNINST_KEY}" "EstimatedSize" "$0"
- !else
- WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${INFO_COMPANYNAME}"
- WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${INFO_PRODUCTNAME}"
- WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${INFO_PRODUCTVERSION}"
- WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXECUTABLE}"
- WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
- WriteRegStr HKLM "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
-
- ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
- IntFmt $0 "0x%08X" $0
- WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" "$0"
- !endif
+ ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
+ IntFmt $0 "0x%08X" $0
+ WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" "$0"
!macroend
!macro wails.deleteUninstaller
Delete "$INSTDIR\uninstall.exe"
SetRegView 64
- !if "${WAILS_INSTALL_SCOPE}" == "user"
- DeleteRegKey HKCU "${UNINST_KEY}"
- !else
- DeleteRegKey HKLM "${UNINST_KEY}"
- !endif
+ DeleteRegKey HKLM "${UNINST_KEY}"
!macroend
!macro wails.setShellContext
diff --git a/build/windows/wails.exe.manifest b/build/windows/wails.exe.manifest
index 76832e9..19c4be8 100644
--- a/build/windows/wails.exe.manifest
+++ b/build/windows/wails.exe.manifest
@@ -1,6 +1,6 @@
-
+
diff --git a/frontend/src/i18n/generated/catalog.json b/frontend/src/i18n/generated/catalog.json
index 877e746..c5b52e9 100644
--- a/frontend/src/i18n/generated/catalog.json
+++ b/frontend/src/i18n/generated/catalog.json
@@ -142,8 +142,8 @@
"refs": [
{
"file": "src/views/Config.vue",
- "line": 50,
- "column": 48
+ "line": 51,
+ "column": 1
}
]
},
@@ -166,8 +166,8 @@
"refs": [
{
"file": "src/components/HomeMetricsCard.vue",
- "line": 337,
- "column": 65
+ "line": 338,
+ "column": 1
}
]
},
@@ -400,8 +400,8 @@
"refs": [
{
"file": "src/views/Config.vue",
- "line": 64,
- "column": 48
+ "line": 65,
+ "column": 1
}
]
},
@@ -527,8 +527,8 @@
"refs": [
{
"file": "src/components/ModelAdapterTestCard.vue",
- "line": 145,
- "column": 7
+ "line": 146,
+ "column": 1
}
]
},
@@ -575,8 +575,8 @@
"refs": [
{
"file": "src/components/ModelAdapterTestCard.vue",
- "line": 124,
- "column": 60
+ "line": 125,
+ "column": 1
}
]
},
@@ -672,8 +672,8 @@
},
{
"file": "src/components/CursorAccountCard.vue",
- "line": 187,
- "column": 11
+ "line": 188,
+ "column": 1
}
]
},
@@ -778,8 +778,8 @@
"refs": [
{
"file": "src/views/ModelConfig.vue",
- "line": 411,
- "column": 13
+ "line": 412,
+ "column": 1
}
]
},
@@ -1601,8 +1601,8 @@
"refs": [
{
"file": "src/components/HomeMetricsCard.vue",
- "line": 389,
- "column": 65
+ "line": 390,
+ "column": 1
}
]
},
@@ -1902,8 +1902,8 @@
"refs": [
{
"file": "src/components/HomeMetricsCard.vue",
- "line": 341,
- "column": 23
+ "line": 342,
+ "column": 1
}
]
},
@@ -2356,8 +2356,8 @@
"refs": [
{
"file": "src/views/ModelConfig.vue",
- "line": 404,
- "column": 13
+ "line": 405,
+ "column": 1
}
]
},
@@ -2854,8 +2854,8 @@
"refs": [
{
"file": "src/components/CursorAccountCard.vue",
- "line": 169,
- "column": 53
+ "line": 170,
+ "column": 1
}
]
},
@@ -2965,8 +2965,8 @@
"refs": [
{
"file": "src/views/Config.vue",
- "line": 76,
- "column": 48
+ "line": 77,
+ "column": 1
}
]
},
@@ -3071,8 +3071,8 @@
"refs": [
{
"file": "src/components/CursorAccountCard.vue",
- "line": 172,
- "column": 81
+ "line": 173,
+ "column": 1
}
]
},
diff --git a/internal/backend/forwarder/file_store.go b/internal/backend/forwarder/file_store.go
index dff749d..820e43f 100644
--- a/internal/backend/forwarder/file_store.go
+++ b/internal/backend/forwarder/file_store.go
@@ -506,10 +506,6 @@ func (store *ConversationFileStore) syncCursorTranscriptBestEffort(conversationI
}
func (store *ConversationFileStore) syncCursorTranscript(conversationID string, conversation *ConversationFile, transcriptsFolder string) error {
- return store.syncCursorTranscriptWithLatestStatus(conversationID, conversation, transcriptsFolder, false)
-}
-
-func (store *ConversationFileStore) syncCursorTranscriptWithLatestStatus(conversationID string, conversation *ConversationFile, transcriptsFolder string, includeLatestStatus bool) error {
if store == nil || conversation == nil {
return nil
}
@@ -517,7 +513,7 @@ func (store *ConversationFileStore) syncCursorTranscriptWithLatestStatus(convers
if err != nil {
return err
}
- data, err := projectCursorTranscriptJSONLWithLatestStatus(conversation, includeLatestStatus)
+ data, err := projectCursorTranscriptJSONL(conversation)
if err != nil {
return err
}
@@ -528,34 +524,6 @@ func (store *ConversationFileStore) syncCursorTranscriptWithLatestStatus(convers
return writeCursorTranscriptAtomic(path, data)
}
-func (store *ConversationFileStore) SyncAllCursorTranscriptsBestEffort() {
- if store == nil {
- return
- }
- conversationIDs, err := store.ListConversationIDs()
- if err != nil {
- log.Printf("forwarder transcript backfill scan failed err=%v", err)
- return
- }
- for _, conversationID := range conversationIDs {
- conversation, err := store.LoadConversation(conversationID)
- if err != nil {
- log.Printf("forwarder transcript backfill load failed conversation_id=%s err=%v", conversationID, err)
- continue
- }
- if conversation == nil || conversation.AgentTranscriptsFolder == "" {
- continue
- }
- info, err := os.Stat(conversation.AgentTranscriptsFolder)
- if err != nil || !info.IsDir() {
- continue
- }
- if err := store.syncCursorTranscriptWithLatestStatus(conversationID, conversation, conversation.AgentTranscriptsFolder, true); err != nil {
- log.Printf("forwarder transcript backfill failed conversation_id=%s err=%v", conversationID, err)
- }
- }
-}
-
func contextVersionForEntries(entries []HistoryEntry) int64 {
var version int64
for _, entry := range entries {
diff --git a/internal/backend/forwarder/service.go b/internal/backend/forwarder/service.go
index 4bb9f77..c301b01 100644
--- a/internal/backend/forwarder/service.go
+++ b/internal/backend/forwarder/service.go
@@ -307,7 +307,6 @@ func NewService(historyRoot string, resolver modeladapter.ChannelResolver) *Serv
appendSeq: newAppendSequenceTracker(),
}
service.startHistoryMaintenance()
- store.SyncAllCursorTranscriptsBestEffort()
return service
}
diff --git a/internal/backend/forwarder/transcript_adapter.go b/internal/backend/forwarder/transcript_adapter.go
index 86605a0..b8d04b4 100644
--- a/internal/backend/forwarder/transcript_adapter.go
+++ b/internal/backend/forwarder/transcript_adapter.go
@@ -68,10 +68,6 @@ type cursorTranscriptContent struct {
// projectCursorTranscriptJSONL projects the local semantic history into Cursor's
// current agent transcript JSONL contract. context.json remains the source of truth.
func projectCursorTranscriptJSONL(conversation *ConversationFile) ([]byte, error) {
- return projectCursorTranscriptJSONLWithLatestStatus(conversation, false)
-}
-
-func projectCursorTranscriptJSONLWithLatestStatus(conversation *ConversationFile, includeLatestStatus bool) ([]byte, error) {
if conversation == nil {
return nil, nil
}
@@ -85,7 +81,7 @@ func projectCursorTranscriptJSONLWithLatestStatus(conversation *ConversationFile
currentTurnSeq := int64(0)
pendingTurnStatus := cursorTranscriptLine{}
flushTurnStatus := func() {
- if currentTurnSeq > 0 && (includeLatestStatus || currentTurnSeq < maxTurnSeq) && pendingTurnStatus.Type != "" {
+ if currentTurnSeq > 0 && currentTurnSeq < maxTurnSeq && pendingTurnStatus.Type != "" {
lines = append(lines, pendingTurnStatus)
}
pendingTurnStatus = cursorTranscriptLine{}
diff --git a/internal/backend/forwarder/transcript_adapter_test.go b/internal/backend/forwarder/transcript_adapter_test.go
index 8f932f0..21671fe 100644
--- a/internal/backend/forwarder/transcript_adapter_test.go
+++ b/internal/backend/forwarder/transcript_adapter_test.go
@@ -97,42 +97,6 @@ func TestConversationFileStoreSyncsCursorTranscript(t *testing.T) {
}
}
-func TestConversationFileStoreBackfillsTranscriptOnStartup(t *testing.T) {
- historyRoot := filepath.Join(t.TempDir(), "history")
- transcriptsFolder := filepath.Join(t.TempDir(), "agent-transcripts")
- if err := os.MkdirAll(transcriptsFolder, 0o755); err != nil {
- t.Fatalf("create transcript root: %v", err)
- }
- store := NewConversationFileStore(historyRoot)
- conversation := transcriptTestConversation(nil)
- conversation.AgentTranscriptsFolder = transcriptsFolder
- _, err := store.SaveConversationWithEntries(conversation.ConversationID, conversation, []HistoryEntry{
- transcriptTestUserMessageEntry(t, 1, "request-1", "hello"),
- newAssistantTextEntry(1, "request-1", "hi", "", ""),
- newMetadataEntry(1, "request-1", "turn_completed", nil),
- })
- if err != nil {
- t.Fatalf("SaveConversationWithEntries() error = %v", err)
- }
- path := filepath.Join(transcriptsFolder, conversation.ConversationID, conversation.ConversationID+".jsonl")
- if err := os.RemoveAll(filepath.Dir(path)); err != nil {
- t.Fatalf("remove generated transcript: %v", err)
- }
- if err := os.MkdirAll(transcriptsFolder, 0o755); err != nil {
- t.Fatalf("restore transcript root: %v", err)
- }
-
- store.SyncAllCursorTranscriptsBestEffort()
- data, err := os.ReadFile(path)
- if err != nil {
- t.Fatalf("read backfilled transcript: %v", err)
- }
- lines := decodeCursorTranscriptLines(t, data)
- if len(lines) != 3 || lines[2].Type != "turn_ended" || lines[2].Status != "success" {
- t.Fatalf("backfilled transcript = %s", data)
- }
-}
-
func TestNormalizeAgentTranscriptsFolderRejectsUnexpectedPaths(t *testing.T) {
root := t.TempDir()
if got := normalizeAgentTranscriptsFolder(filepath.Join(root, "agent-transcripts")); got == "" {
diff --git a/release-notes.md b/release-notes.md
index e04ef7c..9ff0253 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -8,6 +8,4 @@ QQ交流群:
Tg群组:
https://t.me/cursor_byok
-- 修复Read Image
-- 支持不设置思考强度
-- 修复证书安全问题,需要重启一下cursor生效
+- 修复许多问题比如子代理数量等