返回 DeepSeek-Reasonix
migrate_native.go
根目录 / internal / agent / migrate_native.go
1 package agent
2
3 import (
4 "errors"
5 "os"
6 "path/filepath"
7 "time"
8
9 "reasonix/internal/store"
10 )
11
12 // moveFlatImport re-homes a session left in the global directory by a flat
13 // import. An mtime match distinguishes it from a same-named native session.
14 func moveFlatImport(oldPath, newPath string, srcInfo os.FileInfo) bool {
15 if srcInfo == nil {
16 return false
17 }
18 info, err := os.Stat(oldPath)
19 if err != nil {
20 return false
21 }
22 d := info.ModTime().Sub(srcInfo.ModTime())
23 if d < -2*time.Second || d > 2*time.Second {
24 return false
25 }
26 if moved, decided := moveNativeFlatImport(oldPath, newPath); decided {
27 return moved
28 }
29 if err := os.MkdirAll(filepath.Dir(newPath), 0o755); err != nil {
30 return false
31 }
32 if err := linkFileNoReplace(oldPath, newPath); err != nil {
33 if errors.Is(err, os.ErrExist) {
34 return false
35 }
36 if err := transformAndCopyJsonl(oldPath, newPath); err != nil {
37 return false
38 }
39 }
40 if err := os.Remove(oldPath); err != nil {
41 return false
42 }
43 return true
44 }
45
46 // A native flat import must be re-homed from its WAL-backed view, not its
47 // possibly older compatibility checkpoint.
48 func moveNativeFlatImport(oldPath, newPath string) (moved, decided bool) {
49 unlockOld := lockSessionSavePath(oldPath)
50 defer unlockOld()
51 probe, err := probeSessionEventLog(oldPath)
52 if err != nil || !probe.native || probe.size == 0 {
53 return false, false
54 }
55 oldFileUnlock, err := lockSessionFile(oldPath)
56 if err != nil {
57 return false, true
58 }
59 defer oldFileUnlock()
60
61 unlockNew := lockSessionSavePath(newPath)
62 defer unlockNew()
63 if err := os.MkdirAll(filepath.Dir(newPath), 0o755); err != nil {
64 return false, true
65 }
66 newFileUnlock, err := lockSessionFile(newPath)
67 if err != nil {
68 return false, true
69 }
70 defer newFileUnlock()
71 if sessionArtifactExists(newPath) {
72 return false, true
73 }
74
75 session, err := loadSessionUnlocked(oldPath)
76 if err != nil {
77 return false, true
78 }
79 if err := session.saveLocked(newPath, sessionSaveSnapshot); err != nil {
80 return false, true
81 }
82 if meta, ok, metaErr := LoadBranchMeta(oldPath); metaErr != nil {
83 return false, true
84 } else if ok {
85 meta.ID = BranchID(newPath)
86 if err := SaveBranchMeta(newPath, meta); err != nil {
87 return false, true
88 }
89 }
90 if err := migratePinnedContextSidecar(oldPath, newPath, BranchID(newPath)); err != nil {
91 return false, true
92 }
93 for _, artifact := range store.SessionSidecarFiles(oldPath) {
94 if err := os.Remove(artifact); err != nil && !os.IsNotExist(err) {
95 return false, true
96 }
97 }
98 if err := os.Remove(oldPath); err != nil && !os.IsNotExist(err) {
99 return false, true
100 }
101 return true, true
102 }
103
103 lines GO