mirror of
https://github.com/sst/opencode.git
synced 2025-12-23 10:11:41 +00:00
improve snapshot system
This commit is contained in:
parent
ae1f3be109
commit
9b0935d14c
4 changed files with 34 additions and 17 deletions
|
|
@ -3,6 +3,7 @@ import { ConfigHooks } from "../config/hooks"
|
|||
import { Format } from "../format"
|
||||
import { LSP } from "../lsp"
|
||||
import { Share } from "../share/share"
|
||||
import { Snapshot } from "../snapshot"
|
||||
|
||||
export async function bootstrap<T>(input: App.Input, cb: (app: App.Info) => Promise<T>) {
|
||||
return App.provide(input, async (app) => {
|
||||
|
|
@ -10,6 +11,7 @@ export async function bootstrap<T>(input: App.Input, cb: (app: App.Info) => Prom
|
|||
Format.init()
|
||||
ConfigHooks.init()
|
||||
LSP.init()
|
||||
Snapshot.init()
|
||||
|
||||
return cb(app)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ const CreateCommand = cmd({
|
|||
command: "create",
|
||||
async handler() {
|
||||
await bootstrap({ cwd: process.cwd() }, async () => {
|
||||
const result = await Snapshot.create("test")
|
||||
const result = await Snapshot.create()
|
||||
console.log(result)
|
||||
})
|
||||
},
|
||||
|
|
@ -30,7 +30,7 @@ const RestoreCommand = cmd({
|
|||
}),
|
||||
async handler(args) {
|
||||
await bootstrap({ cwd: process.cwd() }, async () => {
|
||||
await Snapshot.restore("test", args.commit)
|
||||
await Snapshot.restore(args.commit)
|
||||
console.log("restored")
|
||||
})
|
||||
},
|
||||
|
|
@ -47,7 +47,7 @@ export const DiffCommand = cmd({
|
|||
}),
|
||||
async handler(args) {
|
||||
await bootstrap({ cwd: process.cwd() }, async () => {
|
||||
const diff = await Snapshot.diff("test", args.commit)
|
||||
const diff = await Snapshot.diff(args.commit)
|
||||
console.log(diff)
|
||||
})
|
||||
},
|
||||
|
|
|
|||
|
|
@ -819,7 +819,7 @@ export namespace Session {
|
|||
})
|
||||
switch (value.type) {
|
||||
case "start":
|
||||
const snapshot = await Snapshot.create(assistantMsg.sessionID, true)
|
||||
const snapshot = await Snapshot.create()
|
||||
if (snapshot)
|
||||
await updatePart({
|
||||
id: Identifier.ascending("part"),
|
||||
|
|
@ -883,7 +883,7 @@ export namespace Session {
|
|||
},
|
||||
})
|
||||
delete toolCalls[value.toolCallId]
|
||||
const snapshot = await Snapshot.create(assistantMsg.sessionID)
|
||||
const snapshot = await Snapshot.create()
|
||||
if (snapshot)
|
||||
await updatePart({
|
||||
id: Identifier.ascending("part"),
|
||||
|
|
@ -912,7 +912,7 @@ export namespace Session {
|
|||
},
|
||||
})
|
||||
delete toolCalls[value.toolCallId]
|
||||
const snapshot = await Snapshot.create(assistantMsg.sessionID)
|
||||
const snapshot = await Snapshot.create()
|
||||
if (snapshot)
|
||||
await updatePart({
|
||||
id: Identifier.ascending("part"),
|
||||
|
|
@ -1075,9 +1075,9 @@ export namespace Session {
|
|||
if ((msg.info.id === input.messageID && !input.partID) || part.id === input.partID) {
|
||||
// if no useful parts left in message, same as reverting whole message
|
||||
const partID = remaining.some((item) => ["text", "tool"].includes(item.type)) ? input.partID : undefined
|
||||
const snapshot = session.revert?.snapshot ?? (await Snapshot.create(input.sessionID, true))
|
||||
const snapshot = session.revert?.snapshot ?? (await Snapshot.create(true))
|
||||
log.info("revert snapshot", { snapshot })
|
||||
if (lastSnapshot) await Snapshot.restore(input.sessionID, lastSnapshot.snapshot)
|
||||
if (lastSnapshot) await Snapshot.restore(lastSnapshot.snapshot)
|
||||
const next = await update(input.sessionID, (draft) => {
|
||||
draft.revert = {
|
||||
// if not part id jump to the last user message
|
||||
|
|
@ -1097,7 +1097,7 @@ export namespace Session {
|
|||
log.info("unreverting", input)
|
||||
const session = await get(input.sessionID)
|
||||
if (!session.revert) return session
|
||||
if (session.revert.snapshot) await Snapshot.restore(input.sessionID, session.revert.snapshot)
|
||||
if (session.revert.snapshot) await Snapshot.restore(session.revert.snapshot)
|
||||
const next = await update(input.sessionID, (draft) => {
|
||||
draft.revert = undefined
|
||||
})
|
||||
|
|
|
|||
|
|
@ -4,11 +4,26 @@ import path from "path"
|
|||
import fs from "fs/promises"
|
||||
import { Ripgrep } from "../file/ripgrep"
|
||||
import { Log } from "../util/log"
|
||||
import { Global } from "../global"
|
||||
|
||||
export namespace Snapshot {
|
||||
const log = Log.create({ service: "snapshot" })
|
||||
|
||||
export async function create(sessionID: string, force?: boolean) {
|
||||
export function init() {
|
||||
Array.fromAsync(
|
||||
new Bun.Glob("**/snapshot").scan({
|
||||
absolute: true,
|
||||
onlyFiles: false,
|
||||
cwd: Global.Path.data,
|
||||
}),
|
||||
).then((files) => {
|
||||
for (const file of files) {
|
||||
fs.rmdir(file, { recursive: true })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function create(force?: boolean) {
|
||||
log.info("creating snapshot")
|
||||
const app = App.info()
|
||||
|
||||
|
|
@ -23,7 +38,7 @@ export namespace Snapshot {
|
|||
if (files.length >= 1000) return
|
||||
}
|
||||
|
||||
const git = gitdir(sessionID)
|
||||
const git = gitdir()
|
||||
if (await fs.mkdir(git, { recursive: true })) {
|
||||
await $`git init`
|
||||
.env({
|
||||
|
|
@ -50,22 +65,22 @@ export namespace Snapshot {
|
|||
return match![1]
|
||||
}
|
||||
|
||||
export async function restore(sessionID: string, snapshot: string) {
|
||||
export async function restore(snapshot: string) {
|
||||
log.info("restore", { commit: snapshot })
|
||||
const app = App.info()
|
||||
const git = gitdir(sessionID)
|
||||
const git = gitdir()
|
||||
await $`git --git-dir=${git} reset --hard ${snapshot}`.quiet().cwd(app.path.root)
|
||||
}
|
||||
|
||||
export async function diff(sessionID: string, commit: string) {
|
||||
const git = gitdir(sessionID)
|
||||
export async function diff(commit: string) {
|
||||
const git = gitdir()
|
||||
const result = await $`git --git-dir=${git} diff -R ${commit}`.quiet().cwd(App.info().path.root)
|
||||
const text = result.stdout.toString("utf8")
|
||||
return text
|
||||
}
|
||||
|
||||
function gitdir(sessionID: string) {
|
||||
function gitdir() {
|
||||
const app = App.info()
|
||||
return path.join(app.path.data, "snapshot", sessionID)
|
||||
return path.join(app.path.data, "snapshots")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue