feat(conversation): follow active reasoning while preserving manual reading

This commit is contained in:
Codex committed 2026-10-21 17:21:32 +09:00
1 parent 35b9a62ed4
commit 4a72008b2e
12 files changed
+530 -40

No files matched your search

+4 -5
View File
@@ -3,9 +3,9 @@ import assert from 'node:assert/strict'
import { createRequire } from 'node:module'
const { JSDOM } = createRequire(process.cwd() + '/package.json')(process.env.YCODE_TEST_DOM_MODULE || 'jsdom')
const dom = new JSDOM('<html><body><main id="root"></main></body></html>', { pretendToBeVisual: true, url: 'http://localhost/' })
for (const key of ['window', 'document', 'Node', 'Element', 'HTMLElement', 'MouseEvent', 'KeyboardEvent', 'Event']) Object.defineProperty(globalThis, key, { value: dom.window[key], configurable: true })
for (const key of ['window', 'document', 'Node', 'Element', 'HTMLElement', 'MouseEvent', 'KeyboardEvent', 'Event', 'CustomEvent']) Object.defineProperty(globalThis, key, { value: dom.window[key], configurable: true })
Object.defineProperty(globalThis, 'navigator', { value: dom.window.navigator, configurable: true })
Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true })
Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true, requestAnimationFrame: dom.window.requestAnimationFrame.bind(dom.window), cancelAnimationFrame: dom.window.cancelAnimationFrame.bind(dom.window) })
const { act } = require('react') as typeof import('react')
const { createRoot } = require('react-dom/client') as typeof import('react-dom/client')
const { CompletedFold } = require('../src/renderer/src/workbuddy/conversation/CompletedFold') as typeof import('../src/renderer/src/workbuddy/conversation/CompletedFold')
@@ -34,7 +34,7 @@ async function main() {
await act(async () => root.render(<Fixture />))
assert.equal(expanded(outer), 'false')
await keyboard(outer, 'Enter')
for (const selector of [group, thinking, ordinary, question]) { assert.equal(expanded(selector), 'false'); await click(selector); assert.equal(expanded(selector), 'true') }
for (const selector of [group, thinking, ordinary, question]) { assert.equal(expanded(selector), 'false'); await click(selector); assert.equal(expanded(selector), 'true', `${selector} opens on click`) }
assert.equal(expanded(second), 'false', 'local summaries are independent')
for (const selector of ['.cb-task-result-item-title', '.cb-plan-header-left']) { assert.equal(expanded(selector), 'true'); await click(selector); assert.equal(expanded(selector), 'false') }
await keyboard(outer, ' ')
@@ -59,8 +59,7 @@ async function main() {
await act(async () => root.render(<Fixture id="live-message" finished={false} />))
for (const selector of [group, thinking, ordinary, question]) await click(selector)
await act(async () => root.render(<Fixture id="live-message" finished />))
assert.equal(expanded(outer), 'false', 'completion starts folded after live events')
await click(outer)
assert.equal(expanded(outer), 'true', 'completion preserves manually opened reasoning reader')
for (const selector of [group, thinking, ordinary, question]) assert.equal(expanded(selector), 'true', `${selector} survives live-to-completed reparenting`)
await act(async () => root.unmount()); dom.window.close()
console.log('completed-fold-nested: real question/tool/thinking/local-summary remount, event, keyboard and identity contracts passed')