Skip to content

Commit ecf55a3

Browse files
author
SqlRush
committed
Accept wrapped focus alias fields
1 parent a59c329 commit ecf55a3

5 files changed

Lines changed: 86 additions & 26 deletions

File tree

docs/cc-100-roadmap.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,8 @@ M7 补充:prompt history `LogEntry` 读取现在接受 `sessionID`/`session`/`
600600

601601
本轮补充:interaction script 的 direct resize 数字 alias 字段现在也递归解包 wrapper;`resizeWidth`/`resizeHeight``screenWidth`/`screenHeight` 和 terminal width/height 相邻别名可从 wrapped `value``columns``rows` 中恢复尺寸,避免 direct field fixture 在 int decode 阶段失败。
602602

603+
本轮补充:interaction script 的 direct focus bool alias 字段现在也递归解包 wrapper;`focus``focused``focusIn``focusOut``blur`/`blurred` 可从 wrapped `enabled``value``selected` 等字段恢复焦点事件控制,避免 direct field fixture 在 bool decode 阶段失败。
604+
603605
本轮补充:interaction script action/type/kind/name/operation 动作判别字段现在也接受 compact/camel event/media aliases,包括 `focusIn``focusOut``mouseEvent``pasteImage``imagePaste`
604606

605607
本轮补充:interaction script 的 mouseEvent/pasteImage action payload 现在递归解包 JSON:API/GraphQL-style `resource`/`attributes`/`properties`/`attrs`/`edge.node` wrapper,wrapped mouse 坐标/按钮和 image filename/media/content 可直接驱动 dialog click 与 image paste。

docs/claude-code-go-rewrite-plan.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ test/parity/ # golden tests against TS/official behavior
311311
- 本轮补充:interaction script 的 typeText/pasteText/setStatus/snapshot 字符串 action payload 现在递归解包 JSON:API/GraphQL-style wrapper,`payload.resource.attributes.text``edge.node.attrs.content``resource.attributes.message` 和 wrapped snapshot `name` 可直接驱动 prompt、paste、status 与 snapshot capture。
312312
- 本轮补充:interaction script resize/terminalSize/screenSize action payload 现在递归解包 `value`/`payload`/`data`/`resource`/`attributes`/`properties`/`attrs`/`edge.node` 等 wrapper,官方/API fixture 可把 columns/rows 放在 JSON:API 或 GraphQL envelope 内。
313313
- 本轮补充:interaction script 的 direct resize 数字 alias 字段现在也递归解包 wrapper;`resizeWidth`/`resizeHeight``screenWidth`/`screenHeight` 和 terminal width/height 相邻别名可从 wrapped `value``columns``rows` 中恢复尺寸。
314+
- 本轮补充:interaction script 的 direct focus bool alias 字段现在也递归解包 wrapper;`focus``focused``focusIn``focusOut``blur`/`blurred` 可从 wrapped `enabled``value``selected` 等字段恢复焦点事件控制。
314315
- 本轮补充:interaction script action/type/kind/name/operation 动作判别字段继续接受 compact/camel event/media aliases,包括 `focusIn``focusOut``mouseEvent``pasteImage``imagePaste`
315316
- 本轮补充:interaction script mouseEvent/pasteImage action payload 现在递归解包 JSON:API/GraphQL-style `resource`/`attributes`/`properties`/`attrs`/`edge.node` wrapper,wrapped mouse 坐标/按钮和 image filename/media/content 可直接驱动 dialog click 与 image paste。
316317
- 本轮补充:interaction script action/type/kind/name/operation 动作判别字段也可驱动 runtime/dialog mutation,支持 `requestPermission``taskStatus``showTasks``cancelTasks``removeTask``showDialog` 等动作,并从 `value`/`payload`/`data`/`body` 载荷解析对象、ID 或取消原因。

docs/first-second-parity-audit.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ M7 progress now includes:
291291
- `internal/tui`: direct scripted key alias fields such as `key`, `keyPress`, and `keyPresses` now accept JSON:API/GraphQL-style wrapper objects without failing strong string/list decoding.
292292
- `internal/tui`: direct scripted string alias fields such as `text`, `pasteText`, `setStatus`, and `snapshotName` now accept JSON:API/GraphQL-style wrapper objects without failing strong scalar decoding.
293293
- `internal/tui`: direct scripted resize aliases such as `resizeWidth`/`resizeHeight` and `screenWidth`/`screenHeight` now recursively unwrap numeric JSON:API/GraphQL-style wrapper objects.
294+
- `internal/tui`: direct scripted focus aliases such as `focus`, `focused`, `focusIn`, `focusOut`, and `blurred` now recursively unwrap boolean JSON:API/GraphQL-style wrapper objects.
294295
- `internal/tui`: terminal key parsing now accepts CSI-u/kitty keyboard protocol sequences for existing ctrl/alt editing keys, shift-enter, shift-tab, and printable shift-only runes.
295296
- `internal/tui`: terminal CSI-u/kitty keyboard parsing now also accepts colon-suffixed alternate codepoint and modifier event-type fields such as `CSI 97:65;5:1u`.
296297
- `internal/tui`: terminal CSI-u/kitty keyboard parsing now also accepts base/unmodified sequences such as `CSI 97u` and `CSI 13;1u`, mapping printable runes plus Enter, Tab, Esc, and Backspace instead of treating ordinary extended-key reports as unknown.

internal/tui/script_aliases.go

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -445,14 +445,14 @@ func (step *ScriptStep) UnmarshalJSON(data []byte) error {
445445
ResizeHeightCamel *json.RawMessage `json:"resizeHeight"`
446446
SnapshotName *json.RawMessage `json:"snapshot_name"`
447447
SnapshotNameCamel *json.RawMessage `json:"snapshotName"`
448-
Focus *bool `json:"focus"`
449-
Focused *bool `json:"focused"`
450-
FocusIn *bool `json:"focus_in"`
451-
FocusInCamel *bool `json:"focusIn"`
452-
FocusOut *bool `json:"focus_out"`
453-
FocusOutCamel *bool `json:"focusOut"`
454-
Blur *bool `json:"blur"`
455-
Blurred *bool `json:"blurred"`
448+
Focus *json.RawMessage `json:"focus"`
449+
Focused *json.RawMessage `json:"focused"`
450+
FocusIn *json.RawMessage `json:"focus_in"`
451+
FocusInCamel *json.RawMessage `json:"focusIn"`
452+
FocusOut *json.RawMessage `json:"focus_out"`
453+
FocusOutCamel *json.RawMessage `json:"focusOut"`
454+
Blur *json.RawMessage `json:"blur"`
455+
Blurred *json.RawMessage `json:"blurred"`
456456
ExpectEvent *ScreenEvent `json:"expect_event"`
457457
ExpectEventCamel *ScreenEvent `json:"expectEvent"`
458458
ExpectEvents []ScreenEvent `json:"expect_events"`
@@ -817,29 +817,17 @@ func (step *ScriptStep) UnmarshalJSON(data []byte) error {
817817
"value",
818818
)
819819
}
820-
if fields.Focus != nil {
821-
step.Keys = append(step.Keys, scriptFocusKey(*fields.Focus))
820+
if value, ok := scriptRuntimeMutationBoolField(fieldMap, "focus", "focused"); ok {
821+
step.Keys = append(step.Keys, scriptFocusKey(value))
822822
}
823-
if fields.Focused != nil {
824-
step.Keys = append(step.Keys, scriptFocusKey(*fields.Focused))
825-
}
826-
if fields.FocusIn != nil && *fields.FocusIn {
827-
step.Keys = append(step.Keys, "focus-in")
828-
}
829-
if fields.FocusInCamel != nil && *fields.FocusInCamel {
823+
if value, ok := scriptRuntimeMutationBoolField(fieldMap, "focus_in", "focusIn"); ok && value {
830824
step.Keys = append(step.Keys, "focus-in")
831825
}
832-
if fields.FocusOut != nil && *fields.FocusOut {
833-
step.Keys = append(step.Keys, "focus-out")
834-
}
835-
if fields.FocusOutCamel != nil && *fields.FocusOutCamel {
836-
step.Keys = append(step.Keys, "focus-out")
837-
}
838-
if fields.Blur != nil && *fields.Blur {
826+
if value, ok := scriptRuntimeMutationBoolField(fieldMap, "focus_out", "focusOut", "blur"); ok && value {
839827
step.Keys = append(step.Keys, "focus-out")
840828
}
841-
if fields.Blurred != nil {
842-
step.Keys = append(step.Keys, scriptFocusKey(!*fields.Blurred))
829+
if value, ok := scriptRuntimeMutationBoolField(fieldMap, "blurred"); ok {
830+
step.Keys = append(step.Keys, scriptFocusKey(!value))
843831
}
844832
if fields.ExpectEvent != nil {
845833
step.ExpectEvent = fields.ExpectEvent

internal/tui/tui_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5853,6 +5853,74 @@ func TestRunInteractionScriptAcceptsCompactEventActionAliases(t *testing.T) {
58535853
}
58545854
}
58555855

5856+
func TestRunInteractionScriptAcceptsWrappedFocusAliasFields(t *testing.T) {
5857+
steps, err := ParseInteractionScript([]byte(`[
5858+
{
5859+
"focus": {
5860+
"resource": {
5861+
"attributes": {
5862+
"enabled": false
5863+
}
5864+
}
5865+
},
5866+
"expectEvent": {"type": "focus_out"},
5867+
"expectFocused": false
5868+
},
5869+
{
5870+
"focused": {
5871+
"edge": {
5872+
"node": {
5873+
"attrs": {
5874+
"value": true
5875+
}
5876+
}
5877+
}
5878+
},
5879+
"expectEvent": {"type": "focus_in"},
5880+
"expectFocused": true
5881+
},
5882+
{
5883+
"focusOut": {
5884+
"resource": {
5885+
"attributes": {
5886+
"enabled": true
5887+
}
5888+
}
5889+
},
5890+
"expectEvent": {"type": "focus_out"},
5891+
"expectFocused": false
5892+
},
5893+
{
5894+
"focusIn": {
5895+
"edge": {
5896+
"node": {
5897+
"attrs": {
5898+
"selected": true
5899+
}
5900+
}
5901+
}
5902+
},
5903+
"expectEvent": {"type": "focus_in"},
5904+
"expectFocused": true
5905+
}
5906+
]`))
5907+
if err != nil {
5908+
t.Fatal(err)
5909+
}
5910+
screen := NewREPLScreen(40, 8, nil)
5911+
result, err := RunInteractionScriptChecked(&screen, steps)
5912+
if err != nil {
5913+
t.Fatal(err)
5914+
}
5915+
if len(result.Events) != 4 ||
5916+
result.Events[0].Type != ScreenEventFocusOut ||
5917+
result.Events[1].Type != ScreenEventFocusIn ||
5918+
result.Events[2].Type != ScreenEventFocusOut ||
5919+
result.Events[3].Type != ScreenEventFocusIn {
5920+
t.Fatalf("events = %#v", result.Events)
5921+
}
5922+
}
5923+
58565924
func TestRunInteractionScriptAcceptsWrappedMouseAndImageActionPayloads(t *testing.T) {
58575925
steps, err := ParseInteractionScript([]byte(`[
58585926
{

0 commit comments

Comments
 (0)