Skip to content

Commit d25828c

Browse files
author
SqlRush
committed
Replay keypress which script events
1 parent e25981f commit d25828c

5 files changed

Lines changed: 26 additions & 9 deletions

File tree

docs/cc-100-roadmap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ M7 补充:prompt history `LogEntry` 读取现在接受 `sessionID`/`session`/`
730730

731731
本轮补充:prompt history 读取旧 image pasted-content 记录时,如果缺少 source path 但对应 session 的 image-cache 文件仍存在,会自动补回 source path 并刷新内存 image path cache。
732732

733-
本轮补充:interaction script key 字段现在接受 DOM-style key event object,可从 `key`/`code``ctrlKey`/`altKey`/`metaKey`/`shiftKey``modifiers` 数组还原现有 key 名,wrapper payload 中的 key event 也可驱动脚本回放。
733+
本轮补充:interaction script key 字段现在接受 DOM-style key event object,可从 `key`/`code`旧式 `keyIdentifier`、数字 `keyCode`/`which`/`charCode``keypress.which` 字符码、`ctrlKey`/`altKey`/`metaKey`/`shiftKey``modifiers` 数组还原现有 key 名,wrapper payload 中的 key event 也可驱动脚本回放。
734734

735735
本轮补充:interaction script mouse payload 现在可从 `mouseup``pointerUp``touchend` 等 event type 推导 release 状态;显式 release bool 仍优先生效。
736736

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ test/parity/ # golden tests against TS/official behavior
232232
- 本轮补充:TUI Vim prompt editing 增加基础 visual/visual-line 模式,支持 `v`/`V` 进入选择、motion 扩展 selection、`y`/`d`/`c` 作用于选择范围、Esc 回到 normal,并让 interaction script 可用 `visual`/`visualLine` 断言当前 mode。
233233
- 本轮补充:prompt history 写入现在保留 image pasted-content 的 media type、filename、dimensions 和 image-cache source path 元数据,同时继续不把 inline base64 image bytes 或 text-paste hash 写进图片历史记录。
234234
- 本轮补充:prompt history 读取旧 image pasted-content 记录时,如果缺少 source path 但对应 session 的 image-cache 文件仍存在,会自动补回 source path 并刷新内存 image path cache。
235-
- 本轮补充:interaction script key 字段现在接受 DOM-style key event object,可从 `key`/`code`、旧式 `keyIdentifier`、数字 `keyCode`/`which`/`charCode``ctrlKey`/`altKey`/`metaKey`/`shiftKey``modifiers` 数组还原现有 key 名,wrapper payload 中的 key event 也可驱动脚本回放。
235+
- 本轮补充:interaction script key 字段现在接受 DOM-style key event object,可从 `key`/`code`、旧式 `keyIdentifier`、数字 `keyCode`/`which`/`charCode``keypress.which` 字符码、`ctrlKey`/`altKey`/`metaKey`/`shiftKey``modifiers` 数组还原现有 key 名,wrapper payload 中的 key event 也可驱动脚本回放。
236236
- 本轮补充:interaction script mouse payload 现在可从 `mouseup``pointerUp``touchend` 等 event type 推导 release 状态;显式 release bool 仍优先生效。
237237
- 本轮补充:interaction script mouse payload 现在可从 `wheel`/`mousewheel``scrollUp`/`scrollDown``direction``deltaY` 和旧式 `wheelDelta` 推导 SGR wheel button,录制的 DOM/compact 滚轮事件可直接驱动 viewport 滚动。
238238
- 本轮补充:interaction script mouse payload 现在接受 DOM `which``buttons`/`buttonState` bitmask,并映射到 SGR left/middle/right button,避免录制脚本的右键/中键被误当成 primary click。

docs/first-second-parity-audit.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ M7 progress now includes:
228228
- `internal/tui`: Vim prompt editing now includes basic visual and visual-line mode support with `v`/`V`, motion-extended selections, `y`/`d`/`c` range operators, Escape return-to-normal behavior, and script expectation aliases for `visual`/`visualLine` modes.
229229
- `internal/session`: prompt history now persists image pasted-content metadata such as media type, filename, dimensions, and image-cache source path while still omitting inline base64 image bytes and text-paste hashes for images.
230230
- `internal/session`: prompt history loading now backfills missing image source paths from existing per-session image-cache files and refreshes the in-memory image path cache when those files exist.
231-
- `internal/tui`: interaction script key fields now accept DOM-style key event objects with `key`/`code`, legacy `keyIdentifier`, numeric `keyCode`/`which`/`charCode`, modifier booleans such as `ctrlKey`/`altKey`/`metaKey`/`shiftKey`, and modifier arrays, including wrapper payloads and modifier-only event filtering.
231+
- `internal/tui`: interaction script key fields now accept DOM-style key event objects with `key`/`code`, legacy `keyIdentifier`, numeric `keyCode`/`which`/`charCode`, `keypress.which` char-code replay, modifier booleans such as `ctrlKey`/`altKey`/`metaKey`/`shiftKey`, and modifier arrays, including wrapper payloads and modifier-only event filtering.
232232
- `internal/tui`: interaction script mouse payloads now infer release state from event type aliases such as `mouseup`, `pointerUp`, and `touchend`, while explicit release booleans still take precedence.
233233
- `internal/tui`: interaction script mouse payloads now infer SGR wheel buttons from DOM/compact wheel inputs such as `wheel`, `mousewheel`, `scrollUp`/`scrollDown`, `direction`, `deltaY`, and legacy `wheelDelta`, allowing recorded wheel events to drive viewport scrolling.
234234
- `internal/tui`: interaction script mouse payloads now accept DOM `which` and `buttons`/`buttonState` bitmasks and map them to SGR left/middle/right buttons so recorded secondary or auxiliary clicks are not treated as primary clicks.

internal/tui/script_aliases.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2997,8 +2997,9 @@ func scriptKeyEventNameFromFields(fields map[string]json.RawMessage) (string, bo
29972997
}
29982998

29992999
func scriptKeyEventUnknownName(key string) bool {
3000-
switch strings.ToLower(strings.TrimSpace(key)) {
3001-
case "", "unidentified", "unknown":
3000+
normalized := strings.ToLower(strings.ReplaceAll(strings.ReplaceAll(strings.TrimSpace(key), "_", "-"), " ", "-"))
3001+
switch normalized {
3002+
case "", "unidentified", "unknown", "keydown", "key-down", "keyup", "key-up", "keypress", "key-press":
30023003
return true
30033004
default:
30043005
return false
@@ -3013,11 +3014,25 @@ func scriptKeyEventNumericNameFromFields(fields map[string]json.RawMessage) (str
30133014
return scriptKeyEventKeyCodeName(*value)
30143015
}
30153016
if value := intPtrJSONField(fields, "which", "Which"); value != nil && *value > 0 {
3017+
if scriptKeyEventWhichUsesCharCode(fields) {
3018+
return scriptKeyEventCharCodeName(*value)
3019+
}
30163020
return scriptKeyEventKeyCodeName(*value)
30173021
}
30183022
return "", false
30193023
}
30203024

3025+
func scriptKeyEventWhichUsesCharCode(fields map[string]json.RawMessage) bool {
3026+
for _, name := range []string{"type", "eventType", "event_type", "event", "kind", "action", "name"} {
3027+
value := stringJSONField(fields, name)
3028+
normalized := strings.ToLower(strings.ReplaceAll(strings.ReplaceAll(strings.TrimSpace(value), "_", "-"), " ", "-"))
3029+
if normalized == "keypress" || normalized == "key-press" {
3030+
return true
3031+
}
3032+
}
3033+
return false
3034+
}
3035+
30213036
func scriptKeyEventCharCodeName(code int) (string, bool) {
30223037
switch code {
30233038
case 8:

internal/tui/tui_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6193,6 +6193,7 @@ func TestRunInteractionScriptAcceptsKeyEventObjects(t *testing.T) {
61936193
{"keys":[{"key":"h"},{"key":"i"},{"key":"Enter"}],"expectEvent":{"type":"prompt_submitted","value":"hi"},"expectPrompt":{"empty":true}},
61946194
{"keys":[{"keyCode":72},{"which":73},{"keyCode":32},{"charCode":33},{"keyCode":13}],"expectEvent":{"type":"prompt_submitted","value":"hi !"},"expectPrompt":{"empty":true}},
61956195
{"keys":[{"keyIdentifier":"U+0061"},{"key_identifier":"U+0020"},{"keyIdentifier":"U+0062","shiftKey":true},{"keyIdentifier":"Enter"}],"expectEvent":{"type":"prompt_submitted","value":"a B"},"expectPrompt":{"empty":true}},
6196+
{"keys":[{"type":"keypress","which":33},{"eventType":"keypress","which":65},{"name":"keypress","which":32},{"keyCode":13}],"expectEvent":{"type":"prompt_submitted","value":"!A "},"expectPrompt":{"empty":true}},
61966197
{"keys":[{"keyCode":17,"ctrlKey":true},{"keyCode":88,"ctrlKey":true},{"which":75,"ctrlKey":true}],"expectEvent":{"type":"kill_agents"}},
61976198
{"kind":"keys","data":[{"code":"KeyO"},{"code":"Digit1"},{"key":"Enter"}],"expectEvent":{"type":"prompt_submitted","value":"o1"},"expectPrompt":{"empty":true}},
61986199
{"keys":[{"key":"x","modifiers":["ctrl"]},{"key":"k","modifiers":["control"]}],"expectEvent":{"type":"kill_agents"}},
@@ -6206,13 +6207,14 @@ func TestRunInteractionScriptAcceptsKeyEventObjects(t *testing.T) {
62066207
if err != nil {
62076208
t.Fatal(err)
62086209
}
6209-
if len(result.Events) != 6 ||
6210+
if len(result.Events) != 7 ||
62106211
result.Events[0].Type != ScreenEventPromptSubmitted || result.Events[0].Value != "hi" ||
62116212
result.Events[1].Type != ScreenEventPromptSubmitted || result.Events[1].Value != "hi !" ||
62126213
result.Events[2].Type != ScreenEventPromptSubmitted || result.Events[2].Value != "a B" ||
6213-
result.Events[3].Type != ScreenEventKillAgents ||
6214-
result.Events[4].Type != ScreenEventPromptSubmitted || result.Events[4].Value != "o1" ||
6215-
result.Events[5].Type != ScreenEventKillAgents {
6214+
result.Events[3].Type != ScreenEventPromptSubmitted || result.Events[3].Value != "!A " ||
6215+
result.Events[4].Type != ScreenEventKillAgents ||
6216+
result.Events[5].Type != ScreenEventPromptSubmitted || result.Events[5].Value != "o1" ||
6217+
result.Events[6].Type != ScreenEventKillAgents {
62166218
t.Fatalf("events = %#v", result.Events)
62176219
}
62186220
}

0 commit comments

Comments
 (0)