Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 4 additions & 64 deletions packages/app/e2e/settings/settings-memory.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { test, expect } from "../fixtures"
import { closeSettingsPanel, openSettings, withSession } from "../actions"
import { openSettings, withSession } from "../actions"

test("@smoke memory settings exposes the raw MEMORY.md controls", async ({ page, project }) => {
await project.open()
Expand Down Expand Up @@ -39,75 +39,15 @@ test("@smoke memory settings exposes the raw MEMORY.md controls", async ({ page,
.toContain("e2e memory settings profile")
})

test("idle session shows memory review and saves redacted entries", async ({ page, project }) => {
test("idle session does not render memory review", async ({ page, project }) => {
await project.open()
await project.sdk.memory.reset()
await project.sdk.memory.disabled({ memoryDisabledInput: { disabled: false } })

await withSession(project.sdk, "memory review e2e", async (session) => {
await withSession(project.sdk, "silent memory e2e", async (session) => {
project.trackSession(session.id)
await project.gotoSession(session.id)

const review = page.locator('[data-component="session-memory-review"]')
await expect(review).toBeVisible()
await expect(review.getByText("Remember this session?")).toBeVisible()

await review.locator('[data-action="session-memory-review-text"]').fill("Remember sk-test-secret from this session")
await review.getByRole("button", { name: "Save memory" }).click()

await expect(review).toBeHidden()
await expect
.poll(async () => {
const state = await project.sdk.memory.get().then((response) => response.data as { content?: string })
return state.content ?? ""
})
.toContain("[REDACTED]")

const state = await project.sdk.memory.get().then((response) => response.data as { content?: string })
expect(state.content ?? "").not.toContain("sk-test-secret")
})
})

test("disabled memory hides the idle session review surface", async ({ page, project }) => {
await project.open()
await project.sdk.memory.reset()
await project.sdk.memory.disabled({ memoryDisabledInput: { disabled: true } })
try {
await project.sdk.memory.acceptProposal({ memoryProposalInput: { text: "Should not be saved.", scope: "project" } })
throw new Error("expected disabled memory proposal to be blocked")
} catch (error) {
expect((error as { error?: string }).error).toBe("memory_disabled")
}

try {
await withSession(project.sdk, "disabled memory review e2e", async (session) => {
project.trackSession(session.id)
await project.gotoSession(session.id)

await expect(page.locator('[data-component="session-memory-review"]')).toBeHidden()
})
} finally {
await project.sdk.memory.disabled({ memoryDisabledInput: { disabled: false } })
}
})

test("turning memory off hides an already visible session review surface", async ({ page, project }) => {
await project.open()
await project.sdk.memory.reset()
await project.sdk.memory.disabled({ memoryDisabledInput: { disabled: false } })

await withSession(project.sdk, "memory review toggle e2e", async (session) => {
project.trackSession(session.id)
await project.gotoSession(session.id)

const review = page.locator('[data-component="session-memory-review"]')
await expect(review).toBeVisible()

const settings = await openSettings(page)
await settings.getByRole("tab", { name: "Memory" }).click()
await settings.locator('[data-slot="switch-control"]').click()
await closeSettingsPanel(page, settings)

await expect(review).toBeHidden()
await expect(page.locator('[data-component="session-memory-review"]')).toHaveCount(0)
})
})
136 changes: 0 additions & 136 deletions packages/app/src/components/memory/session-memory-review.tsx

This file was deleted.

11 changes: 1 addition & 10 deletions packages/app/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -857,20 +857,11 @@ export const dict = {
"settings.memory.safeMode": "Memory is in safe mode. Reason: {{reason}}. Reset to template or fix the file manually.",
"settings.memory.profileTooLarge": "Profile is larger than the v1 soft limit. Keep it short because it loads at session start.",
"settings.memory.raw.title": "Raw MEMORY.md",
"settings.memory.raw.description": "Profile updates in v1 are made here. Archive entries are searched only when needed.",
"settings.memory.raw.description": "Profile loads at session start. Archive stays local and is searched only when needed.",
"settings.memory.saved": "Memory saved",
"settings.memory.reset": "Reset to template",
"settings.memory.resetConfirm": "This will overwrite MEMORY.md. The previous file is saved as a backup. Continue?",
"settings.memory.resetDone": "Memory reset",
"memory.review.title": "Remember this session?",
"memory.review.placeholder": "Write one approved memory from this session...",
"memory.review.accept": "Save memory",
"memory.review.dismiss": "Dismiss",
"memory.review.saved": "Memory saved",
"memory.review.savedDescription": "Saved entry was re-read from MEMORY.md after redaction.",
"memory.review.blocked": "Memory was not saved",
"memory.review.blockedDisabled": "Memory is disabled.",
"memory.review.blockedSafeMode": "Memory is in safe mode. Reset to template or fix MEMORY.md manually.",
"settings.tab.worktrees": "Worktrees",
"settings.worktrees.title": "Worktrees",
"settings.worktrees.description": "Worktrees PawWork has created or registered. An active session keeps its worktree bound; run ExitWorktree before you can delete it.",
Expand Down
11 changes: 1 addition & 10 deletions packages/app/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -746,20 +746,11 @@ export const dict = {
"settings.memory.safeMode": "记忆处于安全模式。原因:{{reason}}。请重置模板或手动修复文件。",
"settings.memory.profileTooLarge": "Profile 超过 v1 建议大小。它会在会话启动时加载,建议保持很短。",
"settings.memory.raw.title": "原始 MEMORY.md",
"settings.memory.raw.description": "v1 中 Profile 更新通过这里手动编辑。Archive 只在需要时搜索。",
"settings.memory.raw.description": "Profile 会在会话启动时加载。Archive 留在本地,只在需要时搜索。",
"settings.memory.saved": "记忆已保存",
"settings.memory.reset": "重置为模板",
"settings.memory.resetConfirm": "这会覆盖 MEMORY.md。旧文件会先备份。继续吗?",
"settings.memory.resetDone": "记忆已重置",
"memory.review.title": "要记住这次会话吗?",
"memory.review.placeholder": "写一条本次会话确认要保存的记忆...",
"memory.review.accept": "保存记忆",
"memory.review.dismiss": "跳过",
"memory.review.saved": "记忆已保存",
"memory.review.savedDescription": "保存后已从 MEMORY.md 重新读取,敏感内容会被打码。",
"memory.review.blocked": "记忆未保存",
"memory.review.blockedDisabled": "记忆已关闭。",
"memory.review.blockedSafeMode": "记忆处于安全模式。请重置模板或手动修复 MEMORY.md。",
"settings.tab.worktrees": "工作树",
"settings.worktrees.title": "工作树",
"settings.worktrees.description": "爪印创建或登记过的工作树。正在使用中的会话会保持绑定,先调用 ExitWorktree 才能删除。",
Expand Down
1 change: 0 additions & 1 deletion packages/app/src/pages/session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,6 @@ export default function Page() {
anchor={timelineInteraction.anchor}
onRetryOpenSession={retryOpenRouteSession}
onOpenNewSession={openNewRouteSession}
memoryReviewVisible={!!timelineSessionID() && !timelineRunning()}
composerSession={renderComposerRegion("session")}
composerHome={(ctx) => renderComposerRegion("home", ctx)}
canReview={canReview}
Expand Down
3 changes: 0 additions & 3 deletions packages/app/src/pages/session/session-main-view.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Match, Show, Switch, type ComponentProps, type JSX } from "solid-js"
import { Tabs } from "@opencode-ai/ui/tabs"
import { NewSessionView, SessionHeader } from "@/components/session"
import { SessionMemoryReview } from "@/components/memory/session-memory-review"
import type { PawworkSkillName } from "@/components/session/pawwork-skill-meta"
import type { useLanguage } from "@/context/language"
import type { createSizing } from "@/pages/session/helpers"
Expand Down Expand Up @@ -49,7 +48,6 @@ export function SessionMainView(props: {
anchor: TimelineProps["anchor"]
onRetryOpenSession: () => void
onOpenNewSession: () => void
memoryReviewVisible: boolean
composerSession: JSX.Element
composerHome: (ctx: {
onModeChange: (mode: "normal" | "shell") => void
Expand Down Expand Up @@ -178,7 +176,6 @@ export function SessionMainView(props: {
</Switch>
</div>
<Show when={props.activeSessionID && !showSessionOpeningState()}>
<SessionMemoryReview sessionID={props.timelineSessionID} visible={props.memoryReviewVisible} />
{props.composerSession}
</Show>
</div>
Expand Down
3 changes: 0 additions & 3 deletions packages/app/src/shell-frame-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,6 @@ test("session composer is docked outside the scroll-clipped timeline region", ()
expect(session).toContain("const renderComposerRegion = (")
expect(session).toContain('variant: "session" | "home"')
expect(sessionMainView).toContain('<div class="flex-1 min-h-0 overflow-hidden">')
expect(sessionMainView).toContain(
'<SessionMemoryReview sessionID={props.timelineSessionID} visible={props.memoryReviewVisible} />',
)
expect(sessionMainView).toContain(
"</div>\n <Show when={props.activeSessionID && !showSessionOpeningState()}>",
)
Expand Down
Loading
Loading