@@ -21,6 +21,7 @@ import (
2121 "io"
2222 "os"
2323 "path/filepath"
24+ "runtime"
2425 "sort"
2526 "strings"
2627 "time"
@@ -126,14 +127,23 @@ func New(workspace string) (*Manager, error) {
126127 if err != nil {
127128 return nil , fmt .Errorf ("abs path: %w" , err )
128129 }
129- h := sha1 .Sum ([]byte (abs ))
130- sid := hex .EncodeToString (h [:])[:16 ]
131-
132130 home , err := os .UserHomeDir ()
133131 if err != nil {
134132 return nil , fmt .Errorf ("user home: %w" , err )
135133 }
134+ sid := sessionIDFor (abs )
136135 root := filepath .Join (home , ".deepx" , "sessions" , sid )
136+
137+ // 迁移(issue #121):旧版本直接用原始大小写哈希。Windows 路径大小写不敏感,归一为小写后
138+ // sid 会变,老用户的历史目录(原始大小写哈希)就对不上、看似"丢了"。若新目录还没有、但本次
139+ // 启动大小写对应的旧目录存在,改名过去保住历史。Linux 大小写敏感,rawSid==sid,此段不触发。
140+ if rawSid := rawSessionID (abs ); rawSid != sid {
141+ oldRoot := filepath .Join (home , ".deepx" , "sessions" , rawSid )
142+ if ! dirExists (root ) && dirExists (oldRoot ) {
143+ _ = os .Rename (oldRoot , root ) // 失败不致命:退化为新建空 session
144+ }
145+ }
146+
137147 if err := os .MkdirAll (root , 0o755 ); err != nil {
138148 return nil , fmt .Errorf ("mkdir session: %w" , err )
139149 }
@@ -145,6 +155,21 @@ func New(workspace string) (*Manager, error) {
145155 return m , nil
146156}
147157
158+ // sessionIDFor 由 workspace 绝对路径算 session id。Windows 路径大小写不敏感,归一为小写再哈希,
159+ // 避免 `C:\` 与 `c:\` 被算成两个 session(issue #121);Linux 大小写敏感,保持原样,绝不合并不同路径。
160+ func sessionIDFor (abs string ) string {
161+ if runtime .GOOS == "windows" {
162+ return rawSessionID (strings .ToLower (abs ))
163+ }
164+ return rawSessionID (abs )
165+ }
166+
167+ // rawSessionID 直接对给定字符串做 sha1 取前 16 hex(旧行为)。迁移时用它按原始大小写定位老目录。
168+ func rawSessionID (s string ) string {
169+ h := sha1 .Sum ([]byte (s ))
170+ return hex .EncodeToString (h [:])[:16 ]
171+ }
172+
148173// SessionID 返回 16 字符 hex,用作目录名与诊断显示。
149174func (m * Manager ) SessionID () string { return m .sessionID }
150175
0 commit comments