mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-10-30 19:32:39 +08:00
fix(revert): clarify workspace restoration (#12302)
* fix(revert): clarify workspace restoration * fix(revert): integrate current session schemas * chore: update kilo-vscode visual regression baselines --------- Co-authored-by: kilo-maintainer[bot] <kilo-maintainer[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
kilo-maintainer[bot]
parent
d237196249
commit
ad66c908a4
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@kilocode/cli": patch
|
||||
"kilo-code": patch
|
||||
---
|
||||
|
||||
Clarify when reverting a conversation does not restore workspace changes and link disabled snapshots to the Checkpoints setting.
|
||||
@@ -555,6 +555,7 @@ const SessionRevert = Schema.Struct({
|
||||
partID: optionalOmitUndefined(PartID),
|
||||
snapshot: optionalOmitUndefined(Schema.String),
|
||||
diff: optionalOmitUndefined(Schema.String),
|
||||
workspace: optionalOmitUndefined(Schema.Literals(["restored", "snapshots-disabled", "unavailable"])), // kilocode_change
|
||||
})
|
||||
|
||||
const SessionModel = Schema.Struct({
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:42c43e9ba12bc73da98c915dafca274beee1d0c893c168d8af4e3e3f41edd367
|
||||
size 630896
|
||||
oid sha256:3b1eb6cf15d5c2dc66c769a91fcf09bcf25bc2e8d17696ad0e9ab4181ed3038c
|
||||
size 658647
|
||||
|
||||
@@ -194,7 +194,7 @@ export async function runWithMessageConfirmation<T>(
|
||||
}
|
||||
}
|
||||
|
||||
export function sessionToWebview(session: Session) {
|
||||
export function sessionToWebview(session: Pick<Session, "id" | "parentID" | "title" | "time" | "summary" | "revert">) {
|
||||
return {
|
||||
id: session.id,
|
||||
parentID: session.parentID ?? null,
|
||||
|
||||
@@ -165,6 +165,14 @@ describe("sessionToWebview", () => {
|
||||
expect(result.revert).toBeNull()
|
||||
expect(result.summary).toBeNull()
|
||||
})
|
||||
|
||||
it("preserves the workspace restoration outcome from a revert response", () => {
|
||||
const session = {
|
||||
...makeSession(),
|
||||
revert: { messageID: "msg-1", workspace: "snapshots-disabled" as const },
|
||||
}
|
||||
expect(sessionToWebview(session).revert).toMatchObject({ workspace: "snapshots-disabled" })
|
||||
})
|
||||
})
|
||||
|
||||
describe("indexProvidersById", () => {
|
||||
|
||||
@@ -5,9 +5,15 @@ import path from "node:path"
|
||||
const ROOT = path.resolve(import.meta.dir, "../..")
|
||||
const TURN_FILE = path.join(ROOT, "webview-ui/src/components/chat/VscodeSessionTurn.tsx")
|
||||
const PROVIDER_FILE = path.join(ROOT, "src/KiloProvider.ts")
|
||||
const BANNER_FILE = path.join(ROOT, "webview-ui/src/components/chat/RevertBanner.tsx")
|
||||
const SESSION_FILE = path.join(ROOT, "webview-ui/src/types/messages/sessions.ts")
|
||||
const SDK_FILE = path.join(ROOT, "../sdk/js/src/v2/gen/types.gen.ts")
|
||||
|
||||
const src = fs.readFileSync(TURN_FILE, "utf-8")
|
||||
const provider = fs.readFileSync(PROVIDER_FILE, "utf-8")
|
||||
const banner = fs.readFileSync(BANNER_FILE, "utf-8")
|
||||
const session = fs.readFileSync(SESSION_FILE, "utf-8")
|
||||
const sdk = fs.readFileSync(SDK_FILE, "utf-8")
|
||||
|
||||
function method(name: string, next: string) {
|
||||
const start = provider.indexOf(` private async ${name}`)
|
||||
@@ -49,3 +55,26 @@ describe("revert session synchronization", () => {
|
||||
expect(provider).toMatch(/this\.setCurrentSession\(event\.properties\.info\)/)
|
||||
})
|
||||
})
|
||||
|
||||
describe("revert workspace restoration status", () => {
|
||||
it("renders explicit conversation-only outcomes", () => {
|
||||
expect(session).toContain('workspace?: "restored" | "snapshots-disabled" | "unavailable"')
|
||||
expect(sdk).toMatch(
|
||||
/export type Session = \{[\s\S]*?workspace\?: "restored" \| "snapshots-disabled" \| "unavailable"/,
|
||||
)
|
||||
expect(sdk).toMatch(
|
||||
/export type KilocodeSessionImportSessionData = \{[\s\S]*?workspace\?: "restored" \| "snapshots-disabled" \| "unavailable"/,
|
||||
)
|
||||
expect(banner).toContain('"revert.banner.workspace.snapshotsDisabled"')
|
||||
expect(banner).toContain('"revert.banner.workspace.unavailable"')
|
||||
})
|
||||
|
||||
it("opens the checkpoints settings tab when snapshots are disabled", () => {
|
||||
expect(banner).toContain('{ type: "openSettingsPanel", tab: "checkpoints" }')
|
||||
expect(banner).toContain('"revert.banner.workspace.enableSnapshots"')
|
||||
})
|
||||
|
||||
it("uses a legacy notice for reverts without an explicit outcome", () => {
|
||||
expect(banner).toContain('"revert.banner.workspace.legacy"')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -10,14 +10,17 @@ import { Icon } from "@kilocode/kilo-ui/icon"
|
||||
import { DiffChanges } from "@kilocode/kilo-ui/diff-changes"
|
||||
import { useSession } from "../../context/session"
|
||||
import { useLanguage } from "../../context/language"
|
||||
import { useVSCode } from "../../context/vscode"
|
||||
|
||||
export const RevertBanner: Component = () => {
|
||||
const session = useSession()
|
||||
const language = useLanguage()
|
||||
const vscode = useVSCode()
|
||||
|
||||
const info = () => session.revert()
|
||||
const count = () => session.revertedCount()
|
||||
const diffs = () => session.summary()?.diffs
|
||||
const workspace = () => info()?.workspace
|
||||
|
||||
const users = () => session.userMessages()
|
||||
|
||||
@@ -67,6 +70,31 @@ export const RevertBanner: Component = () => {
|
||||
</For>
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={workspace() && workspace() !== "restored"}>
|
||||
<div class="revert-banner-notice" role="status">
|
||||
<span>
|
||||
{language.t(
|
||||
workspace() === "snapshots-disabled"
|
||||
? "revert.banner.workspace.snapshotsDisabled"
|
||||
: "revert.banner.workspace.unavailable",
|
||||
)}
|
||||
</span>
|
||||
<Show when={workspace() === "snapshots-disabled"}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="small"
|
||||
onClick={() => vscode.postMessage({ type: "openSettingsPanel", tab: "checkpoints" })}
|
||||
>
|
||||
{language.t("revert.banner.workspace.enableSnapshots")}
|
||||
</Button>
|
||||
</Show>
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={!workspace()}>
|
||||
<div class="revert-banner-notice" role="status">
|
||||
<span>{language.t("revert.banner.workspace.legacy")}</span>
|
||||
</div>
|
||||
</Show>
|
||||
<div class="revert-banner-hint">{language.t("revert.banner.hint")}</div>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
+5
@@ -136,6 +136,11 @@ export const dict = {
|
||||
"revert.banner.redo": "إعادة",
|
||||
"revert.banner.redo.all": "إعادة الكل",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled": "تم التراجع عن المحادثة. لم تُستعَد تغييرات الملفات لأن اللقطات معطّلة.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"تم التراجع عن المحادثة. لم تكن هناك نقطة تحقق للملفات، لذا لم تُستعَد تغييرات مساحة العمل.",
|
||||
"revert.banner.workspace.legacy": "تم التراجع عن المحادثة. حالة استعادة مساحة العمل غير متاحة لهذا التراجع السابق.",
|
||||
"revert.banner.workspace.enableSnapshots": "تفعيل اللقطات",
|
||||
"revert.disabled.agentBusy": "انتظر انتهاء الوكيل",
|
||||
"command.session.compact": "ضغط الجلسة",
|
||||
"command.session.compact.description": "تلخيص الجلسة لتقليل حجم السياق",
|
||||
|
||||
+7
@@ -137,6 +137,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Refazer",
|
||||
"revert.banner.redo.all": "Refazer Tudo",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Conversa revertida. As alterações nos arquivos não foram restauradas porque os snapshots estão desativados.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Conversa revertida. Nenhum ponto de restauração dos arquivos estava disponível, portanto as alterações no espaço de trabalho não foram restauradas.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Conversa revertida. O status da restauração do espaço de trabalho não está disponível para esta reversão anterior.",
|
||||
"revert.banner.workspace.enableSnapshots": "Ativar snapshots",
|
||||
"revert.disabled.agentBusy": "Aguarde o agente terminar",
|
||||
"command.session.compact": "Compactar sessão",
|
||||
"command.session.compact.description": "Resumir a sessão para reduzir o tamanho do contexto",
|
||||
|
||||
+7
@@ -137,6 +137,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Ponovi",
|
||||
"revert.banner.redo.all": "Ponovi Sve",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Razgovor je vraćen. Promjene datoteka nisu vraćene jer su snimci stanja onemogućeni.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Razgovor je vraćen. Nije bila dostupna kontrolna tačka datoteka, pa promjene radnog prostora nisu vraćene.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Razgovor je vraćen. Status vraćanja radnog prostora nije dostupan za ovo ranije vraćanje.",
|
||||
"revert.banner.workspace.enableSnapshots": "Omogući snimke stanja",
|
||||
"revert.disabled.agentBusy": "Sačekajte da agent završi",
|
||||
"command.session.compact": "Sažmi sesiju",
|
||||
"command.session.compact.description": "Sažmi sesiju kako bi se smanjio kontekst",
|
||||
|
||||
+7
@@ -137,6 +137,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Gentag",
|
||||
"revert.banner.redo.all": "Gentag alt",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Samtalen blev gendannet. Filændringer blev ikke gendannet, fordi snapshots er deaktiveret.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Samtalen blev gendannet. Der var intet filkontrolpunkt tilgængeligt, så ændringer i arbejdsområdet blev ikke gendannet.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Samtalen blev gendannet. Status for gendannelse af arbejdsområdet er ikke tilgængelig for denne tidligere gendannelse.",
|
||||
"revert.banner.workspace.enableSnapshots": "Aktivér snapshots",
|
||||
"revert.disabled.agentBusy": "Vent på at agenten er færdig",
|
||||
"command.session.compact": "Komprimér session",
|
||||
"command.session.compact.description": "Opsummer sessionen for at reducere kontekststørrelsen",
|
||||
|
||||
@@ -143,6 +143,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Wiederholen",
|
||||
"revert.banner.redo.all": "Alle wiederholen",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Unterhaltung zurückgesetzt. Dateiänderungen wurden nicht wiederhergestellt, weil Snapshots deaktiviert sind.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Unterhaltung zurückgesetzt. Es war kein Dateiwiederherstellungspunkt verfügbar, daher wurden Änderungen im Arbeitsbereich nicht wiederhergestellt.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Unterhaltung zurückgesetzt. Der Status der Arbeitsbereichswiederherstellung ist für dieses frühere Zurücksetzen nicht verfügbar.",
|
||||
"revert.banner.workspace.enableSnapshots": "Snapshots aktivieren",
|
||||
"revert.disabled.agentBusy": "Warten bis der Agent fertig ist",
|
||||
"command.session.compact": "Sitzung komprimieren",
|
||||
"command.session.compact.description": "Sitzung zusammenfassen, um die Kontextgröße zu reduzieren",
|
||||
|
||||
@@ -136,6 +136,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Redo",
|
||||
"revert.banner.redo.all": "Redo All",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Conversation reverted. File changes were not restored because snapshots are disabled.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Conversation reverted. No file checkpoint was available, so workspace changes were not restored.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Conversation reverted. Workspace restoration status is unavailable for this earlier revert.",
|
||||
"revert.banner.workspace.enableSnapshots": "Enable snapshots",
|
||||
"revert.disabled.agentBusy": "Wait for agent to finish",
|
||||
"command.session.compact": "Compact session",
|
||||
"command.session.compact.description": "Summarize the session to reduce context size",
|
||||
|
||||
+7
@@ -137,6 +137,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Rehacer",
|
||||
"revert.banner.redo.all": "Rehacer todo",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Conversación revertida. Los cambios en los archivos no se restauraron porque las instantáneas están desactivadas.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Conversación revertida. No había ningún punto de control de archivos disponible, por lo que no se restauraron los cambios del espacio de trabajo.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Conversación revertida. El estado de restauración del espacio de trabajo no está disponible para esta reversión anterior.",
|
||||
"revert.banner.workspace.enableSnapshots": "Activar instantáneas",
|
||||
"revert.disabled.agentBusy": "Espera a que el agente termine",
|
||||
"command.session.compact": "Compactar sesión",
|
||||
"command.session.compact.description": "Resumir la sesión para reducir el tamaño del contexto",
|
||||
|
||||
+7
@@ -138,6 +138,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Rétablir",
|
||||
"revert.banner.redo.all": "Tout rétablir",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Conversation annulée. Les modifications de fichiers n’ont pas été restaurées, car les instantanés sont désactivés.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Conversation annulée. Aucun point de contrôle de fichiers n’était disponible, les modifications de l’espace de travail n’ont donc pas été restaurées.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Conversation annulée. L’état de restauration de l’espace de travail n’est pas disponible pour cette annulation antérieure.",
|
||||
"revert.banner.workspace.enableSnapshots": "Activer les instantanés",
|
||||
"revert.disabled.agentBusy": "Attendre la fin de l'agent",
|
||||
"command.session.compact": "Compacter la session",
|
||||
"command.session.compact.description": "Résumer la session pour réduire la taille du contexte",
|
||||
|
||||
+7
@@ -131,6 +131,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Ripeti",
|
||||
"revert.banner.redo.all": "Ripeti tutto",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Conversazione ripristinata. Le modifiche ai file non sono state ripristinate perché gli snapshot sono disabilitati.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Conversazione ripristinata. Non era disponibile alcun checkpoint dei file, quindi le modifiche all'area di lavoro non sono state ripristinate.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Conversazione ripristinata. Lo stato del ripristino dell'area di lavoro non è disponibile per questo ripristino precedente.",
|
||||
"revert.banner.workspace.enableSnapshots": "Abilita snapshot",
|
||||
"revert.disabled.agentBusy": "Attendi che l'agente finisca",
|
||||
"command.session.compact": "Compatta sessione",
|
||||
"command.session.compact.description": "Riassumi la sessione per ridurre la dimensione del contesto",
|
||||
|
||||
+7
@@ -137,6 +137,13 @@ export const dict = {
|
||||
"revert.banner.redo": "やり直し",
|
||||
"revert.banner.redo.all": "すべてやり直し",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"会話を元に戻しました。スナップショットが無効になっているため、ファイルの変更は復元されませんでした。",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"会話を元に戻しました。利用可能なファイルのチェックポイントがなかったため、ワークスペースの変更は復元されませんでした。",
|
||||
"revert.banner.workspace.legacy":
|
||||
"会話を元に戻しました。この以前の復元では、ワークスペースの復元状態を利用できません。",
|
||||
"revert.banner.workspace.enableSnapshots": "スナップショットを有効にする",
|
||||
"revert.disabled.agentBusy": "エージェントの完了を待ってください",
|
||||
"command.session.compact": "セッションを圧縮",
|
||||
"command.session.compact.description": "セッションを要約してコンテキストサイズを削減",
|
||||
|
||||
+7
@@ -141,6 +141,13 @@ export const dict = {
|
||||
"revert.banner.redo": "다시 실행",
|
||||
"revert.banner.redo.all": "모두 다시 실행",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"대화를 되돌렸습니다. 스냅샷이 비활성화되어 있어 파일 변경 사항은 복원되지 않았습니다.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"대화를 되돌렸습니다. 사용 가능한 파일 체크포인트가 없어 작업 공간 변경 사항은 복원되지 않았습니다.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"대화가 되돌려졌습니다. 이 이전 되돌리기에서는 작업 영역 복원 상태를 확인할 수 없습니다.",
|
||||
"revert.banner.workspace.enableSnapshots": "스냅샷 활성화",
|
||||
"revert.disabled.agentBusy": "에이전트가 완료될 때까지 기다리세요",
|
||||
"command.session.compact": "세션 압축",
|
||||
"command.session.compact.description": "컨텍스트 크기를 줄이기 위해 세션 요약",
|
||||
|
||||
+7
@@ -137,6 +137,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Opnieuw uitvoeren",
|
||||
"revert.banner.redo.all": "Alles opnieuw uitvoeren",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Conversatie teruggedraaid. Bestandswijzigingen zijn niet hersteld omdat snapshots zijn uitgeschakeld.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Conversatie teruggedraaid. Er was geen bestandscheckpoint beschikbaar, dus wijzigingen in de werkruimte zijn niet hersteld.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Gesprek teruggedraaid. De herstelstatus van de werkruimte is niet beschikbaar voor deze eerdere terugdraaiing.",
|
||||
"revert.banner.workspace.enableSnapshots": "Snapshots inschakelen",
|
||||
"revert.disabled.agentBusy": "Wacht tot de agent klaar is",
|
||||
"command.session.compact": "Sessie comprimeren",
|
||||
"command.session.compact.description": "De sessie samenvatten om de contextgrootte te verkleinen",
|
||||
|
||||
+7
@@ -140,6 +140,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Gjenta",
|
||||
"revert.banner.redo.all": "Gjenta alt",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Samtalen ble tilbakestilt. Filendringer ble ikke gjenopprettet fordi øyeblikksbilder er deaktivert.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Samtalen ble tilbakestilt. Ingen filkontrollpunkt var tilgjengelig, så endringer i arbeidsområdet ble ikke gjenopprettet.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Samtalen er tilbakeført. Statusen for gjenoppretting av arbeidsområdet er ikke tilgjengelig for denne tidligere tilbakeføringen.",
|
||||
"revert.banner.workspace.enableSnapshots": "Aktiver øyeblikksbilder",
|
||||
"revert.disabled.agentBusy": "Vent til agenten er ferdig",
|
||||
"command.session.compact": "Komprimer sesjon",
|
||||
"command.session.compact.description": "Oppsummer sesjonen for å redusere kontekststørrelsen",
|
||||
|
||||
+7
@@ -137,6 +137,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Ponów",
|
||||
"revert.banner.redo.all": "Ponów wszystko",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Rozmowa została cofnięta. Zmiany w plikach nie zostały przywrócone, ponieważ migawki są wyłączone.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Rozmowa została cofnięta. Żaden punkt kontrolny plików nie był dostępny, więc zmiany w obszarze roboczym nie zostały przywrócone.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Konwersacja została cofnięta. Stan przywracania obszaru roboczego nie jest dostępny dla tego wcześniejszego cofnięcia.",
|
||||
"revert.banner.workspace.enableSnapshots": "Włącz migawki",
|
||||
"revert.disabled.agentBusy": "Poczekaj aż agent zakończy",
|
||||
"command.session.compact": "Kompaktuj sesję",
|
||||
"command.session.compact.description": "Podsumuj sesję, aby zmniejszyć rozmiar kontekstu",
|
||||
|
||||
+7
@@ -137,6 +137,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Повторить",
|
||||
"revert.banner.redo.all": "Повторить всё",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Разговор был отменён. Изменения файлов не были восстановлены, так как снимки отключены.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Разговор был отменён. Контрольная точка файлов была недоступна, поэтому изменения в рабочей области не были восстановлены.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Диалог отменён. Статус восстановления рабочей области недоступен для этого более раннего отката.",
|
||||
"revert.banner.workspace.enableSnapshots": "Включить снимки",
|
||||
"revert.disabled.agentBusy": "Дождитесь завершения агента",
|
||||
"command.session.compact": "Сжать сессию",
|
||||
"command.session.compact.description": "Сократить сессию для уменьшения размера контекста",
|
||||
|
||||
+7
@@ -136,6 +136,13 @@ export const dict = {
|
||||
"revert.banner.redo": "ทำซ้ำ",
|
||||
"revert.banner.redo.all": "ทำซ้ำทั้งหมด",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"ย้อนกลับการสนทนาแล้ว ไม่ได้กู้คืนการเปลี่ยนแปลงไฟล์เนื่องจากปิดใช้งานสแนปชอตอยู่",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"ย้อนกลับการสนทนาแล้ว ไม่มีจุดตรวจสอบไฟล์ จึงไม่ได้กู้คืนการเปลี่ยนแปลงในพื้นที่ทำงาน",
|
||||
"revert.banner.workspace.legacy":
|
||||
"ย้อนกลับการสนทนาแล้ว ไม่ทราบสถานะการกู้คืนพื้นที่ทำงานสำหรับการย้อนกลับก่อนหน้านี้",
|
||||
"revert.banner.workspace.enableSnapshots": "เปิดใช้งานสแนปชอต",
|
||||
"revert.disabled.agentBusy": "รอให้เอเจนต์ทำงานเสร็จ",
|
||||
"command.session.compact": "บีบอัดเซสชัน",
|
||||
"command.session.compact.description": "สรุปเซสชันเพื่อลดขนาดบริบท",
|
||||
|
||||
+7
@@ -137,6 +137,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Yinele",
|
||||
"revert.banner.redo.all": "Tümünü Yinele",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Konuşma geri alındı. Anlık görüntüler devre dışı olduğu için dosya değişiklikleri geri yüklenmedi.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Konuşma geri alındı. Dosya kontrol noktası olmadığından çalışma alanı değişiklikleri geri yüklenmedi.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Konuşma geri alındı. Bu önceki geri alma için çalışma alanı geri yükleme durumu kullanılamıyor.",
|
||||
"revert.banner.workspace.enableSnapshots": "Anlık Görüntüleri Etkinleştir",
|
||||
"revert.disabled.agentBusy": "Ajanın bitmesini bekleyin",
|
||||
"command.session.compact": "Oturumu sıkıştır",
|
||||
"command.session.compact.description": "Bağlam boyutunu azaltmak için oturumu özetle",
|
||||
|
||||
+7
@@ -137,6 +137,13 @@ export const dict = {
|
||||
"revert.banner.redo": "Повторити",
|
||||
"revert.banner.redo.all": "Повторити все",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled":
|
||||
"Розмову скасовано. Зміни файлів не відновлено, оскільки знімки вимкнено.",
|
||||
"revert.banner.workspace.unavailable":
|
||||
"Розмову скасовано. Контрольна точка файлів була недоступна, тому зміни в робочому просторі не відновлено.",
|
||||
"revert.banner.workspace.legacy":
|
||||
"Розмову скасовано. Стан відновлення робочого простору для цього попереднього скасування недоступний.",
|
||||
"revert.banner.workspace.enableSnapshots": "Увімкнути знімки",
|
||||
"revert.disabled.agentBusy": "Зачекайте завершення агента",
|
||||
"command.session.compact": "Стиснути сесію",
|
||||
"command.session.compact.description": "Підсумувати сесію для зменшення розміру контексту",
|
||||
|
||||
+4
@@ -138,6 +138,10 @@ export const dict = {
|
||||
"revert.banner.redo": "重做",
|
||||
"revert.banner.redo.all": "全部重做",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled": "会话已还原。由于快照已禁用,文件更改未恢复。",
|
||||
"revert.banner.workspace.unavailable": "会话已还原。没有可用的文件检查点,因此未恢复工作区更改。",
|
||||
"revert.banner.workspace.legacy": "会话已还原。此次早期还原的工作区恢复状态不可用。",
|
||||
"revert.banner.workspace.enableSnapshots": "启用快照",
|
||||
"revert.disabled.agentBusy": "等待智能体完成",
|
||||
"command.session.compact": "精简会话",
|
||||
"command.session.compact.description": "总结会话以减少上下文大小",
|
||||
|
||||
+4
@@ -138,6 +138,10 @@ export const dict = {
|
||||
"revert.banner.redo": "重做",
|
||||
"revert.banner.redo.all": "全部重做",
|
||||
"revert.banner.hint": "You can redo these changes until you send a new message",
|
||||
"revert.banner.workspace.snapshotsDisabled": "工作階段已還原。由於快照已停用,未還原檔案變更。",
|
||||
"revert.banner.workspace.unavailable": "工作階段已還原。沒有可用的檔案檢查點,因此未還原工作區變更。",
|
||||
"revert.banner.workspace.legacy": "工作階段已還原。此次先前還原的工作區復原狀態無法取得。",
|
||||
"revert.banner.workspace.enableSnapshots": "啟用快照",
|
||||
"revert.disabled.agentBusy": "等待 Agent 完成",
|
||||
"command.session.compact": "精簡工作階段",
|
||||
"command.session.compact.description": "總結工作階段以減少上下文大小",
|
||||
|
||||
@@ -1082,6 +1082,11 @@ export const SearchPreviews: Story = {
|
||||
summary: () => ({ diffs: [{ file: "src/app.ts", additions: 4, deletions: 1 }] }),
|
||||
userMessages: () => [{ id: "tool-call-lab-user-message" }, { id: "tool-call-lab-user-message-next" }],
|
||||
}
|
||||
const conversationOnly = {
|
||||
...reverted,
|
||||
revert: () => ({ messageID: "tool-call-lab-user-message", workspace: "snapshots-disabled" as const }),
|
||||
summary: () => undefined,
|
||||
}
|
||||
|
||||
return (
|
||||
<StoryProviders
|
||||
@@ -1167,6 +1172,12 @@ export const SearchPreviews: Story = {
|
||||
<RevertBanner />
|
||||
</SessionContext.Provider>
|
||||
</div>
|
||||
<div class="tool-call-lab-example">
|
||||
<span class="tool-call-lab-example-label">Conversation-only revert</span>
|
||||
<SessionContext.Provider value={conversationOnly as any}>
|
||||
<RevertBanner />
|
||||
</SessionContext.Provider>
|
||||
</div>
|
||||
<div class="tool-call-lab-example">
|
||||
<span class="tool-call-lab-example-label">Token limit outcome</span>
|
||||
<SessionContext.Provider value={limit as any}>
|
||||
|
||||
@@ -130,6 +130,19 @@
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.revert-banner-notice {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
padding: 6px 8px;
|
||||
border-left: 3px solid var(--vscode-editorWarning-foreground, #cca700);
|
||||
background: var(--vscode-editorWarning-background, rgba(204, 167, 0, 0.1));
|
||||
color: var(--text-base, var(--vscode-foreground));
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.revert-banner-hint {
|
||||
margin-top: 6px;
|
||||
color: var(--text-muted, var(--vscode-descriptionForeground));
|
||||
|
||||
@@ -50,6 +50,7 @@ export interface SessionInfo {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
} | null
|
||||
summary?: {
|
||||
additions: number
|
||||
|
||||
@@ -59,6 +59,7 @@ const SessionSchema = Schema.Struct({
|
||||
partID: Schema.optional(Schema.String),
|
||||
snapshot: Schema.optional(Schema.String),
|
||||
diff: Schema.optional(Schema.String),
|
||||
workspace: Schema.optional(Schema.Literals(["restored", "snapshots-disabled", "unavailable"])),
|
||||
}),
|
||||
),
|
||||
permission: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
|
||||
|
||||
@@ -2,6 +2,7 @@ import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect, Layer, Context, Schema } from "effect"
|
||||
import { SessionV1 } from "@opencode-ai/core/v1/session"
|
||||
import { EventV2Bridge } from "@/event-v2-bridge"
|
||||
import { Config } from "@/config/config" // kilocode_change
|
||||
import { Snapshot } from "../snapshot"
|
||||
import { Storage } from "@/storage/storage"
|
||||
import { Session } from "./session"
|
||||
@@ -34,6 +35,7 @@ export const layer = Layer.effect(
|
||||
const events = yield* EventV2Bridge.Service
|
||||
const summary = yield* SessionSummary.Service
|
||||
const state = yield* SessionRunState.Service
|
||||
const config = yield* Config.Service // kilocode_change
|
||||
|
||||
const revert = Effect.fn("SessionRevert.revert")(function* (input: RevertInput) {
|
||||
yield* state.assertNotBusy(input.sessionID)
|
||||
@@ -67,12 +69,22 @@ export const layer = Layer.effect(
|
||||
|
||||
if (!rev) return session
|
||||
|
||||
// kilocode_change start
|
||||
// A fresh snapshot only preserves the state needed for redo. File restoration
|
||||
// is possible only when the historical turn retained checkpoint data.
|
||||
const range = all.filter((msg) => msg.info.id >= rev.messageID)
|
||||
const checkpoint = patches.length > 0
|
||||
rev.workspace = checkpoint
|
||||
? "restored"
|
||||
: (yield* config.get()).snapshot === false
|
||||
? "snapshots-disabled"
|
||||
: "unavailable"
|
||||
// kilocode_change end
|
||||
rev.snapshot = session.revert?.snapshot ?? (yield* snap.track())
|
||||
if (session.revert?.snapshot) yield* snap.restore(session.revert.snapshot)
|
||||
|
||||
// kilocode_change start - compute diffs BEFORE reverting files so the diff
|
||||
// reflects changes being undone (files on disk still have AI modifications)
|
||||
const range = all.filter((msg) => msg.info.id >= rev.messageID)
|
||||
const diffs = yield* summary.computeDiff({ messages: range })
|
||||
// kilocode_change end
|
||||
|
||||
@@ -165,6 +177,7 @@ export const defaultLayer = Layer.suspend(() =>
|
||||
Layer.provide(Storage.defaultLayer),
|
||||
Layer.provide(EventV2Bridge.defaultLayer),
|
||||
Layer.provide(SessionSummary.defaultLayer),
|
||||
Layer.provide(Config.defaultLayer), // kilocode_change
|
||||
),
|
||||
)
|
||||
|
||||
@@ -175,6 +188,7 @@ export const node = LayerNode.make(layer, [
|
||||
EventV2Bridge.node,
|
||||
SessionSummary.node,
|
||||
SessionRunState.node,
|
||||
Config.node, // kilocode_change
|
||||
])
|
||||
|
||||
export * as SessionRevert from "./revert"
|
||||
|
||||
@@ -204,6 +204,7 @@ const Revert = Schema.Struct({
|
||||
partID: optionalOmitUndefined(PartID),
|
||||
snapshot: optionalOmitUndefined(Schema.String),
|
||||
diff: optionalOmitUndefined(Schema.String),
|
||||
workspace: optionalOmitUndefined(Schema.Literals(["restored", "snapshots-disabled", "unavailable"])), // kilocode_change
|
||||
})
|
||||
|
||||
const Model = Schema.Struct({
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Layer } from "effect"
|
||||
import fs from "node:fs/promises"
|
||||
import path from "node:path"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
@@ -84,3 +86,160 @@ describe("partial assistant revert", () => {
|
||||
),
|
||||
)
|
||||
})
|
||||
|
||||
describe("workspace revert status", () => {
|
||||
it.live(
|
||||
"reports disabled snapshots when conversation-only revert leaves files unchanged",
|
||||
provideTmpdirInstance(
|
||||
(dir) =>
|
||||
Effect.gen(function* () {
|
||||
const sessions = yield* Session.Service
|
||||
const revert = yield* SessionRevert.Service
|
||||
const session = yield* sessions.create({})
|
||||
const file = path.join(dir, "created.txt")
|
||||
const providerID = ProviderV2.ID.make("test")
|
||||
yield* Effect.promise(() => fs.writeFile(file, "created"))
|
||||
const user = yield* sessions.updateMessage({
|
||||
id: MessageID.ascending(),
|
||||
sessionID: session.id,
|
||||
role: "user",
|
||||
agent: "default",
|
||||
model: { providerID, modelID: ModelV2.ID.make("test") },
|
||||
time: { created: Date.now() },
|
||||
})
|
||||
yield* sessions.updatePart({
|
||||
id: PartID.ascending(),
|
||||
messageID: user.id,
|
||||
sessionID: session.id,
|
||||
type: "text",
|
||||
text: "create a file",
|
||||
})
|
||||
|
||||
const result = yield* revert.revert({ sessionID: session.id, messageID: user.id })
|
||||
|
||||
expect(result.revert?.workspace).toBe("snapshots-disabled")
|
||||
expect(yield* Effect.promise(() => fs.readFile(file, "utf8"))).toBe("created")
|
||||
}),
|
||||
{ git: true, config: { snapshot: false } },
|
||||
),
|
||||
)
|
||||
|
||||
it.live(
|
||||
"reports unavailable when historical turns have no file checkpoint",
|
||||
provideTmpdirInstance(
|
||||
(dir) =>
|
||||
Effect.gen(function* () {
|
||||
const sessions = yield* Session.Service
|
||||
const revert = yield* SessionRevert.Service
|
||||
const session = yield* sessions.create({})
|
||||
const file = path.join(dir, "created.txt")
|
||||
const providerID = ProviderV2.ID.make("test")
|
||||
yield* Effect.promise(() => fs.writeFile(file, "created"))
|
||||
const user = yield* sessions.updateMessage({
|
||||
id: MessageID.ascending(),
|
||||
sessionID: session.id,
|
||||
role: "user",
|
||||
agent: "default",
|
||||
model: { providerID, modelID: ModelV2.ID.make("test") },
|
||||
time: { created: Date.now() },
|
||||
})
|
||||
yield* sessions.updatePart({
|
||||
id: PartID.ascending(),
|
||||
messageID: user.id,
|
||||
sessionID: session.id,
|
||||
type: "text",
|
||||
text: "create a file",
|
||||
})
|
||||
|
||||
const result = yield* revert.revert({ sessionID: session.id, messageID: user.id })
|
||||
|
||||
expect(result.revert?.workspace).toBe("unavailable")
|
||||
expect(yield* Effect.promise(() => fs.readFile(file, "utf8"))).toBe("created")
|
||||
}),
|
||||
{ git: true },
|
||||
),
|
||||
)
|
||||
|
||||
it.live(
|
||||
"reports restored when historical patches restore a file",
|
||||
provideTmpdirInstance(
|
||||
(dir) =>
|
||||
Effect.gen(function* () {
|
||||
const sessions = yield* Session.Service
|
||||
const revert = yield* SessionRevert.Service
|
||||
const snapshot = yield* Snapshot.Service
|
||||
const session = yield* sessions.create({})
|
||||
const file = path.join(dir, "tracked.txt")
|
||||
const providerID = ProviderV2.ID.make("test")
|
||||
yield* Effect.promise(() => fs.writeFile(file, "before"))
|
||||
const user = yield* sessions.updateMessage({
|
||||
id: MessageID.ascending(),
|
||||
sessionID: session.id,
|
||||
role: "user",
|
||||
agent: "default",
|
||||
model: { providerID, modelID: ModelV2.ID.make("test") },
|
||||
time: { created: Date.now() },
|
||||
})
|
||||
yield* sessions.updatePart({
|
||||
id: PartID.ascending(),
|
||||
messageID: user.id,
|
||||
sessionID: session.id,
|
||||
type: "text",
|
||||
text: "change a file",
|
||||
})
|
||||
const assistant = yield* sessions.updateMessage({
|
||||
id: MessageID.ascending(),
|
||||
sessionID: session.id,
|
||||
role: "assistant",
|
||||
parentID: user.id,
|
||||
mode: "default",
|
||||
agent: "default",
|
||||
path: { cwd: dir, root: dir },
|
||||
cost: 0,
|
||||
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
||||
modelID: ModelV2.ID.make("test"),
|
||||
providerID,
|
||||
time: { created: Date.now() },
|
||||
finish: "end_turn",
|
||||
})
|
||||
const before = yield* snapshot.track()
|
||||
if (!before) throw new Error("expected snapshot")
|
||||
yield* Effect.promise(() => fs.writeFile(file, "after"))
|
||||
const after = yield* snapshot.track()
|
||||
if (!after) throw new Error("expected snapshot")
|
||||
const patch = yield* snapshot.patch(before)
|
||||
yield* sessions.updatePart({
|
||||
id: PartID.ascending(),
|
||||
messageID: assistant.id,
|
||||
sessionID: session.id,
|
||||
type: "step-start",
|
||||
snapshot: before,
|
||||
})
|
||||
yield* sessions.updatePart({
|
||||
id: PartID.ascending(),
|
||||
messageID: assistant.id,
|
||||
sessionID: session.id,
|
||||
type: "step-finish",
|
||||
reason: "stop",
|
||||
snapshot: after,
|
||||
cost: 0,
|
||||
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
||||
})
|
||||
yield* sessions.updatePart({
|
||||
id: PartID.ascending(),
|
||||
messageID: assistant.id,
|
||||
sessionID: session.id,
|
||||
type: "patch",
|
||||
hash: patch.hash,
|
||||
files: patch.files,
|
||||
})
|
||||
|
||||
const result = yield* revert.revert({ sessionID: session.id, messageID: user.id })
|
||||
|
||||
expect(result.revert?.workspace).toBe("restored")
|
||||
expect(yield* Effect.promise(() => fs.readFile(file, "utf8"))).toBe("before")
|
||||
}),
|
||||
{ git: true },
|
||||
),
|
||||
)
|
||||
})
|
||||
|
||||
@@ -7686,6 +7686,7 @@ export class SessionImport extends HeyApiClient {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
permission?: {
|
||||
[key: string]: unknown
|
||||
|
||||
@@ -429,6 +429,7 @@ export type Session = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1983,6 +1984,7 @@ export type GlobalSession = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
project: ProjectSummary | null
|
||||
worktreeName?: string
|
||||
@@ -2365,6 +2367,7 @@ export type Session1 = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2418,6 +2421,7 @@ export type Session2 = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2478,6 +2482,7 @@ export type Session3 = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2531,6 +2536,7 @@ export type Session4 = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2584,6 +2590,7 @@ export type Session5 = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2637,6 +2644,7 @@ export type Session6 = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2690,6 +2698,7 @@ export type Session7 = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2797,6 +2806,7 @@ export type Session8 = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2850,6 +2860,7 @@ export type Session9 = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13383,6 +13394,7 @@ export type KilocodeSessionImportSessionData = {
|
||||
partID?: string
|
||||
snapshot?: string
|
||||
diff?: string
|
||||
workspace?: "restored" | "snapshots-disabled" | "unavailable"
|
||||
}
|
||||
permission?: {
|
||||
[key: string]: unknown
|
||||
|
||||
@@ -16895,6 +16895,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -24796,6 +24800,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -29284,6 +29292,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -30455,6 +30467,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -30624,6 +30640,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -30812,6 +30832,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -30981,6 +31005,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -31150,6 +31178,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -31319,6 +31351,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -31488,6 +31524,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -31819,6 +31859,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
@@ -31988,6 +32032,10 @@
|
||||
},
|
||||
"diff": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspace": {
|
||||
"type": "string",
|
||||
"enum": ["restored", "snapshots-disabled", "unavailable"]
|
||||
}
|
||||
},
|
||||
"required": ["messageID"],
|
||||
|
||||
Reference in New Issue
Block a user