@deepseek-harness-tui/dsh-tui 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -5
- package/assets/deepy/README.md +60 -0
- package/assets/deepy/frames.json +1 -0
- package/assets/whale-girl/whale-girl-happy.png +0 -0
- package/assets/whaleGirl/README.md +7 -0
- package/assets/whaleGirl/frames.json +1 -0
- package/assets/whaleGirl/img/building/00.png +0 -0
- package/assets/whaleGirl/img/building/01.png +0 -0
- package/assets/whaleGirl/img/building/02.png +0 -0
- package/assets/whaleGirl/img/building/03.png +0 -0
- package/assets/whaleGirl/img/building/04.png +0 -0
- package/assets/whaleGirl/img/building/05.png +0 -0
- package/assets/whaleGirl/img/building/06.png +0 -0
- package/assets/whaleGirl/img/building/07.png +0 -0
- package/assets/whaleGirl/img/building/08.png +0 -0
- package/assets/whaleGirl/img/building/09.png +0 -0
- package/assets/whaleGirl/img/building/10.png +0 -0
- package/assets/whaleGirl/img/building/11.png +0 -0
- package/assets/whaleGirl/img/building/12.png +0 -0
- package/assets/whaleGirl/img/building/13.png +0 -0
- package/assets/whaleGirl/img/building/14.png +0 -0
- package/assets/whaleGirl/img/building/15.png +0 -0
- package/assets/whaleGirl/img/building/16.png +0 -0
- package/assets/whaleGirl/img/building/17.png +0 -0
- package/assets/whaleGirl/img/building/18.png +0 -0
- package/assets/whaleGirl/img/building/19.png +0 -0
- package/assets/whaleGirl/img/building/20.png +0 -0
- package/assets/whaleGirl/img/building/21.png +0 -0
- package/assets/whaleGirl/img/building/22.png +0 -0
- package/assets/whaleGirl/img/building/23.png +0 -0
- package/assets/whaleGirl/img/carrying/00.png +0 -0
- package/assets/whaleGirl/img/carrying/01.png +0 -0
- package/assets/whaleGirl/img/carrying/02.png +0 -0
- package/assets/whaleGirl/img/carrying/03.png +0 -0
- package/assets/whaleGirl/img/carrying/04.png +0 -0
- package/assets/whaleGirl/img/carrying/05.png +0 -0
- package/assets/whaleGirl/img/carrying/06.png +0 -0
- package/assets/whaleGirl/img/carrying/07.png +0 -0
- package/assets/whaleGirl/img/compacting/00.png +0 -0
- package/assets/whaleGirl/img/compacting/01.png +0 -0
- package/assets/whaleGirl/img/compacting/02.png +0 -0
- package/assets/whaleGirl/img/compacting/03.png +0 -0
- package/assets/whaleGirl/img/compacting/04.png +0 -0
- package/assets/whaleGirl/img/compacting/05.png +0 -0
- package/assets/whaleGirl/img/compacting/06.png +0 -0
- package/assets/whaleGirl/img/compacting/07.png +0 -0
- package/assets/whaleGirl/img/compacting/08.png +0 -0
- package/assets/whaleGirl/img/compacting/09.png +0 -0
- package/assets/whaleGirl/img/conducting/00.png +0 -0
- package/assets/whaleGirl/img/conducting/01.png +0 -0
- package/assets/whaleGirl/img/conducting/02.png +0 -0
- package/assets/whaleGirl/img/conducting/03.png +0 -0
- package/assets/whaleGirl/img/conducting/04.png +0 -0
- package/assets/whaleGirl/img/conducting/05.png +0 -0
- package/assets/whaleGirl/img/conducting/06.png +0 -0
- package/assets/whaleGirl/img/conducting/07.png +0 -0
- package/assets/whaleGirl/img/conducting/08.png +0 -0
- package/assets/whaleGirl/img/conducting/09.png +0 -0
- package/assets/whaleGirl/img/conducting/10.png +0 -0
- package/assets/whaleGirl/img/conducting/11.png +0 -0
- package/assets/whaleGirl/img/drag/00.png +0 -0
- package/assets/whaleGirl/img/drag/01.png +0 -0
- package/assets/whaleGirl/img/drag/02.png +0 -0
- package/assets/whaleGirl/img/drag/03.png +0 -0
- package/assets/whaleGirl/img/drag/04.png +0 -0
- package/assets/whaleGirl/img/drag/05.png +0 -0
- package/assets/whaleGirl/img/drag/06.png +0 -0
- package/assets/whaleGirl/img/drag/07.png +0 -0
- package/assets/whaleGirl/img/drag/08.png +0 -0
- package/assets/whaleGirl/img/drag/09.png +0 -0
- package/assets/whaleGirl/img/error/00.png +0 -0
- package/assets/whaleGirl/img/error/01.png +0 -0
- package/assets/whaleGirl/img/error/02.png +0 -0
- package/assets/whaleGirl/img/error/03.png +0 -0
- package/assets/whaleGirl/img/error/04.png +0 -0
- package/assets/whaleGirl/img/error/05.png +0 -0
- package/assets/whaleGirl/img/error/06.png +0 -0
- package/assets/whaleGirl/img/error/07.png +0 -0
- package/assets/whaleGirl/img/error/08.png +0 -0
- package/assets/whaleGirl/img/error/09.png +0 -0
- package/assets/whaleGirl/img/happy/00.png +0 -0
- package/assets/whaleGirl/img/happy/01.png +0 -0
- package/assets/whaleGirl/img/happy/02.png +0 -0
- package/assets/whaleGirl/img/happy/03.png +0 -0
- package/assets/whaleGirl/img/happy/04.png +0 -0
- package/assets/whaleGirl/img/happy/05.png +0 -0
- package/assets/whaleGirl/img/happy/06.png +0 -0
- package/assets/whaleGirl/img/happy/07.png +0 -0
- package/assets/whaleGirl/img/happy/08.png +0 -0
- package/assets/whaleGirl/img/happy/09.png +0 -0
- package/assets/whaleGirl/img/happy/10.png +0 -0
- package/assets/whaleGirl/img/idle/00.png +0 -0
- package/assets/whaleGirl/img/idle/01.png +0 -0
- package/assets/whaleGirl/img/idle/02.png +0 -0
- package/assets/whaleGirl/img/idle/03.png +0 -0
- package/assets/whaleGirl/img/idle/04.png +0 -0
- package/assets/whaleGirl/img/idle/05.png +0 -0
- package/assets/whaleGirl/img/idle/06.png +0 -0
- package/assets/whaleGirl/img/idle/07.png +0 -0
- package/assets/whaleGirl/img/idle/08.png +0 -0
- package/assets/whaleGirl/img/idle/09.png +0 -0
- package/assets/whaleGirl/img/idle/10.png +0 -0
- package/assets/whaleGirl/img/idle/11.png +0 -0
- package/assets/whaleGirl/img/idle/12.png +0 -0
- package/assets/whaleGirl/img/idle/13.png +0 -0
- package/assets/whaleGirl/img/idle/14.png +0 -0
- package/assets/whaleGirl/img/idle/15.png +0 -0
- package/assets/whaleGirl/img/idle/16.png +0 -0
- package/assets/whaleGirl/img/idle/17.png +0 -0
- package/assets/whaleGirl/img/idle/18.png +0 -0
- package/assets/whaleGirl/img/idle/19.png +0 -0
- package/assets/whaleGirl/img/idle/20.png +0 -0
- package/assets/whaleGirl/img/idle-look/00.png +0 -0
- package/assets/whaleGirl/img/idle-look/01.png +0 -0
- package/assets/whaleGirl/img/idle-look/02.png +0 -0
- package/assets/whaleGirl/img/idle-look/03.png +0 -0
- package/assets/whaleGirl/img/idle-look/04.png +0 -0
- package/assets/whaleGirl/img/idle-look/05.png +0 -0
- package/assets/whaleGirl/img/idle-look/06.png +0 -0
- package/assets/whaleGirl/img/idle-look/07.png +0 -0
- package/assets/whaleGirl/img/idle-look/08.png +0 -0
- package/assets/whaleGirl/img/idle-look/09.png +0 -0
- package/assets/whaleGirl/img/idle-look/10.png +0 -0
- package/assets/whaleGirl/img/idle-look/11.png +0 -0
- package/assets/whaleGirl/img/idle-look/12.png +0 -0
- package/assets/whaleGirl/img/idle-spout/00.png +0 -0
- package/assets/whaleGirl/img/idle-spout/01.png +0 -0
- package/assets/whaleGirl/img/idle-spout/02.png +0 -0
- package/assets/whaleGirl/img/idle-spout/03.png +0 -0
- package/assets/whaleGirl/img/idle-spout/04.png +0 -0
- package/assets/whaleGirl/img/idle-spout/05.png +0 -0
- package/assets/whaleGirl/img/idle-spout/06.png +0 -0
- package/assets/whaleGirl/img/idle-spout/07.png +0 -0
- package/assets/whaleGirl/img/idle-spout/08.png +0 -0
- package/assets/whaleGirl/img/idle-spout/09.png +0 -0
- package/assets/whaleGirl/img/idle-spout/10.png +0 -0
- package/assets/whaleGirl/img/music/00.png +0 -0
- package/assets/whaleGirl/img/music/01.png +0 -0
- package/assets/whaleGirl/img/music/02.png +0 -0
- package/assets/whaleGirl/img/music/03.png +0 -0
- package/assets/whaleGirl/img/music/04.png +0 -0
- package/assets/whaleGirl/img/music/05.png +0 -0
- package/assets/whaleGirl/img/music/06.png +0 -0
- package/assets/whaleGirl/img/music/07.png +0 -0
- package/assets/whaleGirl/img/notification/00.png +0 -0
- package/assets/whaleGirl/img/notification/01.png +0 -0
- package/assets/whaleGirl/img/notification/02.png +0 -0
- package/assets/whaleGirl/img/notification/03.png +0 -0
- package/assets/whaleGirl/img/notification/04.png +0 -0
- package/assets/whaleGirl/img/notification/05.png +0 -0
- package/assets/whaleGirl/img/notification/06.png +0 -0
- package/assets/whaleGirl/img/notification/07.png +0 -0
- package/assets/whaleGirl/img/poke-left/00.png +0 -0
- package/assets/whaleGirl/img/poke-left/01.png +0 -0
- package/assets/whaleGirl/img/poke-left/02.png +0 -0
- package/assets/whaleGirl/img/poke-left/03.png +0 -0
- package/assets/whaleGirl/img/poke-left/04.png +0 -0
- package/assets/whaleGirl/img/poke-left/05.png +0 -0
- package/assets/whaleGirl/img/poke-left/06.png +0 -0
- package/assets/whaleGirl/img/poke-left/07.png +0 -0
- package/assets/whaleGirl/img/poke-left/08.png +0 -0
- package/assets/whaleGirl/img/poke-left/09.png +0 -0
- package/assets/whaleGirl/img/poke-left/10.png +0 -0
- package/assets/whaleGirl/img/poke-right/00.png +0 -0
- package/assets/whaleGirl/img/poke-right/01.png +0 -0
- package/assets/whaleGirl/img/poke-right/02.png +0 -0
- package/assets/whaleGirl/img/poke-right/03.png +0 -0
- package/assets/whaleGirl/img/poke-right/04.png +0 -0
- package/assets/whaleGirl/img/poke-right/05.png +0 -0
- package/assets/whaleGirl/img/poke-right/06.png +0 -0
- package/assets/whaleGirl/img/poke-right/07.png +0 -0
- package/assets/whaleGirl/img/poke-right/08.png +0 -0
- package/assets/whaleGirl/img/poke-right/09.png +0 -0
- package/assets/whaleGirl/img/poke-right/10.png +0 -0
- package/assets/whaleGirl/img/sleeping/00.png +0 -0
- package/assets/whaleGirl/img/sleeping/01.png +0 -0
- package/assets/whaleGirl/img/sleeping/02.png +0 -0
- package/assets/whaleGirl/img/sleeping/03.png +0 -0
- package/assets/whaleGirl/img/sleeping/04.png +0 -0
- package/assets/whaleGirl/img/sleeping/05.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/00.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/01.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/02.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/03.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/04.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/05.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/06.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/07.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/08.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/09.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/10.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/11.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/12.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/13.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/14.png +0 -0
- package/assets/whaleGirl/img/smile-hearts/15.png +0 -0
- package/assets/whaleGirl/img/swim/00.png +0 -0
- package/assets/whaleGirl/img/swim/01.png +0 -0
- package/assets/whaleGirl/img/swim/02.png +0 -0
- package/assets/whaleGirl/img/swim/03.png +0 -0
- package/assets/whaleGirl/img/swim/04.png +0 -0
- package/assets/whaleGirl/img/swim/05.png +0 -0
- package/assets/whaleGirl/img/swim/06.png +0 -0
- package/assets/whaleGirl/img/swim/07.png +0 -0
- package/assets/whaleGirl/img/thinking/00.png +0 -0
- package/assets/whaleGirl/img/thinking/01.png +0 -0
- package/assets/whaleGirl/img/thinking/02.png +0 -0
- package/assets/whaleGirl/img/thinking/03.png +0 -0
- package/assets/whaleGirl/img/thinking/04.png +0 -0
- package/assets/whaleGirl/img/thinking/05.png +0 -0
- package/assets/whaleGirl/img/thinking/06.png +0 -0
- package/assets/whaleGirl/img/thinking/07.png +0 -0
- package/assets/whaleGirl/img/thinking/08.png +0 -0
- package/assets/whaleGirl/img/thinking/09.png +0 -0
- package/assets/whaleGirl/img/thinking/10.png +0 -0
- package/assets/whaleGirl/img/thinking/11.png +0 -0
- package/assets/whaleGirl/img/thinking/12.png +0 -0
- package/assets/whaleGirl/img/thinking/13.png +0 -0
- package/assets/whaleGirl/img/thinking/14.png +0 -0
- package/assets/whaleGirl/img/thinking/15.png +0 -0
- package/assets/whaleGirl/img/thinking/16.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/00.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/01.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/02.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/03.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/04.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/05.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/06.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/07.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/08.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/09.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/10.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/11.png +0 -0
- package/assets/whaleGirl/img/thumbs-up/12.png +0 -0
- package/assets/whaleGirl/img/tickle/00.png +0 -0
- package/assets/whaleGirl/img/tickle/01.png +0 -0
- package/assets/whaleGirl/img/tickle/02.png +0 -0
- package/assets/whaleGirl/img/tickle/03.png +0 -0
- package/assets/whaleGirl/img/tickle/04.png +0 -0
- package/assets/whaleGirl/img/tickle/05.png +0 -0
- package/assets/whaleGirl/img/tickle/06.png +0 -0
- package/assets/whaleGirl/img/tickle/07.png +0 -0
- package/assets/whaleGirl/img/tickle/08.png +0 -0
- package/assets/whaleGirl/img/tickle/09.png +0 -0
- package/assets/whaleGirl/img/tickle/10.png +0 -0
- package/assets/whaleGirl/img/tickle/11.png +0 -0
- package/assets/whaleGirl/img/tickle/12.png +0 -0
- package/assets/whaleGirl/img/tickle/13.png +0 -0
- package/assets/whaleGirl/img/timings.json +1 -0
- package/assets/whaleGirl/img/typing/00.png +0 -0
- package/assets/whaleGirl/img/typing/01.png +0 -0
- package/assets/whaleGirl/img/typing/02.png +0 -0
- package/assets/whaleGirl/img/typing/03.png +0 -0
- package/assets/whaleGirl/img/typing/04.png +0 -0
- package/assets/whaleGirl/img/typing/05.png +0 -0
- package/assets/whaleGirl/img/typing/06.png +0 -0
- package/assets/whaleGirl/img/typing/07.png +0 -0
- package/assets/whaleGirl/img/typing/08.png +0 -0
- package/assets/whaleGirl/img/typing/09.png +0 -0
- package/assets/whaleGirl/img/typing/10.png +0 -0
- package/assets/whaleGirl/img/typing/11.png +0 -0
- package/assets/whaleGirl/img/typing/12.png +0 -0
- package/assets/whaleGirl/img/typing/13.png +0 -0
- package/assets/whaleGirl/img/waking/00.png +0 -0
- package/assets/whaleGirl/img/waking/01.png +0 -0
- package/assets/whaleGirl/img/waking/02.png +0 -0
- package/assets/whaleGirl/img/waking/03.png +0 -0
- package/assets/whaleGirl/img/waking/04.png +0 -0
- package/assets/whaleGirl/img/waking/05.png +0 -0
- package/assets/whaleGirl/img/waking/06.png +0 -0
- package/assets/whaleGirl/img/waking/07.png +0 -0
- package/assets/whaleGirl/img/waking/08.png +0 -0
- package/assets/whaleGirl/img/waking/09.png +0 -0
- package/assets/whaleGirl/img/waking/10.png +0 -0
- package/bin/dsh-tui.js +8 -3
- package/cordis.patch.yml +7 -1
- package/guide/dsh-tui-guide/configuration.en.md +6 -1
- package/guide/dsh-tui-guide/configuration.md +6 -1
- package/guide/dsh-tui-guide/getting-started.en.md +6 -3
- package/guide/dsh-tui-guide/getting-started.md +4 -2
- package/guide/dsh-tui-guide/interaction.en.md +68 -4
- package/guide/dsh-tui-guide/interaction.md +49 -3
- package/guide/dsh-tui-guide/plugins.en.md +16 -6
- package/guide/dsh-tui-guide/plugins.md +14 -6
- package/guide/dsh-tui-guide/themes.en.md +7 -2
- package/guide/dsh-tui-guide/themes.md +5 -2
- package/guide/dsh-tui-guide/user-guide.en.md +124 -21
- package/guide/dsh-tui-guide/user-guide.md +96 -16
- package/lib/settings.json +215 -1
- package/lib/types/adapter/channel/ui-policy.d.ts +6 -2
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
- package/lib/types/adapter/channel/ui-policy.js +14 -1
- package/lib/types/adapter/index.d.ts +1 -1
- package/lib/types/adapter/index.js +1 -1
- package/lib/types/adapter/kernel/host-facade.d.ts +4 -1
- package/lib/types/adapter/kernel/host-facade.d.ts.map +1 -1
- package/lib/types/adapter/kernel/host-facade.js +8 -1
- package/lib/types/adapter/kernel/runtime.d.ts.map +1 -1
- package/lib/types/adapter/kernel/runtime.js +13 -0
- package/lib/types/adapter/kernel/slices/index.d.ts +1 -0
- package/lib/types/adapter/kernel/slices/index.d.ts.map +1 -1
- package/lib/types/adapter/kernel/slices/index.js +3 -0
- package/lib/types/adapter/kernel/slices/panels.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/panels.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/panels.js +14 -0
- package/lib/types/adapter/ports/channel-capabilities.d.ts +48 -0
- package/lib/types/adapter/ports/channel-capabilities.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-capabilities.js +2 -0
- package/lib/types/adapter/ports/channel-catalog.d.ts +7 -0
- package/lib/types/adapter/ports/channel-catalog.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-display.d.ts +10 -0
- package/lib/types/adapter/ports/channel-display.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-ui.d.ts +62 -2
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-view.d.ts +94 -0
- package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel.d.ts +1 -1
- package/lib/types/adapter/ports/channel.js +1 -1
- package/lib/types/adapter/ports/descriptor.d.ts +1 -1
- package/lib/types/adapter/ports/descriptor.js +1 -1
- package/lib/types/adapter/ports/index.d.ts +1 -1
- package/lib/types/adapter/ports/index.js +1 -1
- package/lib/types/adapter/ports/panels.d.ts +28 -0
- package/lib/types/adapter/ports/panels.d.ts.map +1 -0
- package/lib/types/adapter/ports/panels.js +8 -0
- package/lib/types/adapter/ports/workspace.d.ts +1 -1
- package/lib/types/adapter/ports/workspace.js +1 -1
- package/lib/types/adapter/spec/index.d.ts +2 -2
- package/lib/types/adapter/spec/index.js +2 -2
- package/lib/types/adapter/spec/profile.d.ts +6 -6
- package/lib/types/adapter/spec/profile.d.ts.map +1 -1
- package/lib/types/adapter/spec/profile.js +6 -6
- package/lib/types/adapter/spec/protocol-constants.d.ts +3 -3
- package/lib/types/adapter/spec/protocol-constants.d.ts.map +1 -1
- package/lib/types/adapter/spec/protocol-constants.js +5 -5
- package/lib/types/adapter/spec/tui-contributions.d.ts +4 -4
- package/lib/types/adapter/spec/tui-contributions.d.ts.map +1 -1
- package/lib/types/adapter/spec/tui-contributions.js +5 -5
- package/lib/types/adapter/standard/descriptor.js +1 -1
- package/lib/types/adapter/standard/index.d.ts +3 -3
- package/lib/types/adapter/standard/index.js +3 -3
- package/lib/types/adapter/standard/registry.d.ts +3 -2
- package/lib/types/adapter/standard/registry.d.ts.map +1 -1
- package/lib/types/adapter/standard/registry.js +6 -5
- package/lib/types/adapter/standard/tui-extension.d.ts +1 -1
- package/lib/types/adapter/standard/tui-extension.js +1 -1
- package/lib/types/adapter/upstream/index.d.ts +1 -0
- package/lib/types/adapter/upstream/index.d.ts.map +1 -1
- package/lib/types/adapter/upstream/index.js +1 -0
- package/lib/types/adapter/upstream/panels-driver.d.ts +18 -0
- package/lib/types/adapter/upstream/panels-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/panels-driver.js +159 -0
- package/lib/types/api.d.ts +2 -0
- package/lib/types/api.d.ts.map +1 -1
- package/lib/types/api.js +3 -1
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +12 -4
- package/lib/types/components/ActivityLine.d.ts +6 -9
- package/lib/types/components/ActivityLine.d.ts.map +1 -1
- package/lib/types/components/ActivityLine.js +7 -8
- package/lib/types/components/Chat/JobCard.d.ts +18 -1
- package/lib/types/components/Chat/JobCard.d.ts.map +1 -1
- package/lib/types/components/Chat/JobCard.js +90 -22
- package/lib/types/components/Chat/JobGroupHeader.d.ts +27 -0
- package/lib/types/components/Chat/JobGroupHeader.d.ts.map +1 -0
- package/lib/types/components/Chat/JobGroupHeader.js +62 -0
- package/lib/types/components/GoalTodoPanel.d.ts +13 -1
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
- package/lib/types/components/GoalTodoPanel.js +55 -14
- package/lib/types/components/JobsPanel.d.ts +42 -2
- package/lib/types/components/JobsPanel.d.ts.map +1 -1
- package/lib/types/components/JobsPanel.js +147 -14
- package/lib/types/components/LogoV2.d.ts +43 -3
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +42 -15
- package/lib/types/components/MessageList.d.ts +8 -2
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +212 -18
- package/lib/types/components/OverlayAbove.d.ts +11 -1
- package/lib/types/components/OverlayAbove.d.ts.map +1 -1
- package/lib/types/components/OverlayAbove.js +2 -12
- package/lib/types/components/PageMargin.d.ts.map +1 -1
- package/lib/types/components/PageMargin.js +3 -1
- package/lib/types/components/PluginSceneBoundary.d.ts +1 -1
- package/lib/types/components/PluginSceneBoundary.js +1 -1
- package/lib/types/components/PromptInput.d.ts +20 -22
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +413 -156
- package/lib/types/components/SearchBox.d.ts +22 -5
- package/lib/types/components/SearchBox.d.ts.map +1 -1
- package/lib/types/components/SearchBox.js +17 -13
- package/lib/types/components/SubagentCard.d.ts.map +1 -1
- package/lib/types/components/SubagentCard.js +17 -2
- package/lib/types/components/SubagentDashboard.d.ts +18 -3
- package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
- package/lib/types/components/SubagentDashboard.js +53 -5
- package/lib/types/components/SubagentDetailScene.d.ts +7 -1
- package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
- package/lib/types/components/SubagentDetailScene.js +54 -5
- package/lib/types/components/SurfaceEdges.d.ts +21 -0
- package/lib/types/components/SurfaceEdges.d.ts.map +1 -0
- package/lib/types/components/SurfaceEdges.js +7 -0
- package/lib/types/components/ThemePicker.d.ts +9 -0
- package/lib/types/components/ThemePicker.d.ts.map +1 -1
- package/lib/types/components/ThemePicker.js +74 -10
- package/lib/types/components/ThemePreviewPane.d.ts +26 -0
- package/lib/types/components/ThemePreviewPane.d.ts.map +1 -0
- package/lib/types/components/ThemePreviewPane.js +99 -0
- package/lib/types/components/design-system/Divider.d.ts.map +1 -1
- package/lib/types/components/design-system/Divider.js +14 -9
- package/lib/types/components/launchpadActions.d.ts +73 -0
- package/lib/types/components/launchpadActions.d.ts.map +1 -0
- package/lib/types/components/launchpadActions.js +111 -0
- package/lib/types/components/launchpadLayout.d.ts +62 -0
- package/lib/types/components/launchpadLayout.d.ts.map +1 -0
- package/lib/types/components/launchpadLayout.js +176 -0
- package/lib/types/components/onboardingModel.d.ts +83 -0
- package/lib/types/components/onboardingModel.d.ts.map +1 -0
- package/lib/types/components/onboardingModel.js +128 -0
- package/lib/types/components/sidePanel/InfoPanel.d.ts +17 -0
- package/lib/types/components/sidePanel/InfoPanel.d.ts.map +1 -0
- package/lib/types/components/sidePanel/InfoPanel.js +124 -0
- package/lib/types/components/sidePanel/PanelBar.d.ts +45 -0
- package/lib/types/components/sidePanel/PanelBar.d.ts.map +1 -0
- package/lib/types/components/sidePanel/PanelBar.js +104 -0
- package/lib/types/components/sidePanel/PanelErrorBoundary.d.ts +21 -0
- package/lib/types/components/sidePanel/PanelErrorBoundary.d.ts.map +1 -0
- package/lib/types/components/sidePanel/PanelErrorBoundary.js +30 -0
- package/lib/types/components/sidePanel/PanelHost.d.ts +36 -0
- package/lib/types/components/sidePanel/PanelHost.d.ts.map +1 -0
- package/lib/types/components/sidePanel/PanelHost.js +81 -0
- package/lib/types/components/sidePanel/PanelPicker.d.ts +24 -0
- package/lib/types/components/sidePanel/PanelPicker.d.ts.map +1 -0
- package/lib/types/components/sidePanel/PanelPicker.js +45 -0
- package/lib/types/components/sidePanel/PanelStore.d.ts +55 -0
- package/lib/types/components/sidePanel/PanelStore.d.ts.map +1 -0
- package/lib/types/components/sidePanel/PanelStore.js +109 -0
- package/lib/types/components/sidePanel/SidePanelColumn.d.ts +31 -0
- package/lib/types/components/sidePanel/SidePanelColumn.d.ts.map +1 -0
- package/lib/types/components/sidePanel/SidePanelColumn.js +70 -0
- package/lib/types/components/sidePanel/SidePanelLayout.d.ts +54 -0
- package/lib/types/components/sidePanel/SidePanelLayout.d.ts.map +1 -0
- package/lib/types/components/sidePanel/SidePanelLayout.js +81 -0
- package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts +43 -0
- package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts.map +1 -0
- package/lib/types/components/sidePanel/SidePanelRuntimeContext.js +26 -0
- package/lib/types/components/sidePanel/TrajectoryPanel.d.ts +7 -0
- package/lib/types/components/sidePanel/TrajectoryPanel.d.ts.map +1 -0
- package/lib/types/components/sidePanel/TrajectoryPanel.js +263 -0
- package/lib/types/components/sidePanel/WorkspacePanel.d.ts +4 -0
- package/lib/types/components/sidePanel/WorkspacePanel.d.ts.map +1 -0
- package/lib/types/components/sidePanel/WorkspacePanel.js +171 -0
- package/lib/types/components/sidePanel/builtinPanels.d.ts +3 -0
- package/lib/types/components/sidePanel/builtinPanels.d.ts.map +1 -0
- package/lib/types/components/sidePanel/builtinPanels.js +229 -0
- package/lib/types/components/sidePanel/companion/CompanionPanel.d.ts +53 -0
- package/lib/types/components/sidePanel/companion/CompanionPanel.d.ts.map +1 -0
- package/lib/types/components/sidePanel/companion/CompanionPanel.js +528 -0
- package/lib/types/components/sidePanel/companion/SplashMascot.d.ts +32 -0
- package/lib/types/components/sidePanel/companion/SplashMascot.d.ts.map +1 -0
- package/lib/types/components/sidePanel/companion/SplashMascot.js +103 -0
- package/lib/types/components/sidePanel/companion/deepy.d.ts +75 -0
- package/lib/types/components/sidePanel/companion/deepy.d.ts.map +1 -0
- package/lib/types/components/sidePanel/companion/deepy.js +222 -0
- package/lib/types/components/sidePanel/companion/mood.d.ts +176 -0
- package/lib/types/components/sidePanel/companion/mood.d.ts.map +1 -0
- package/lib/types/components/sidePanel/companion/mood.js +212 -0
- package/lib/types/components/sidePanel/companion/pose.d.ts +43 -0
- package/lib/types/components/sidePanel/companion/pose.d.ts.map +1 -0
- package/lib/types/components/sidePanel/companion/pose.js +34 -0
- package/lib/types/components/sidePanel/companion/skins.d.ts +102 -0
- package/lib/types/components/sidePanel/companion/skins.d.ts.map +1 -0
- package/lib/types/components/sidePanel/companion/skins.js +408 -0
- package/lib/types/components/sidePanel/dimensions.d.ts +60 -0
- package/lib/types/components/sidePanel/dimensions.d.ts.map +1 -0
- package/lib/types/components/sidePanel/dimensions.js +75 -0
- package/lib/types/components/sidePanel/jobsFocusStore.d.ts +21 -0
- package/lib/types/components/sidePanel/jobsFocusStore.d.ts.map +1 -0
- package/lib/types/components/sidePanel/jobsFocusStore.js +30 -0
- package/lib/types/components/sidePanel/panelBridge.d.ts +44 -0
- package/lib/types/components/sidePanel/panelBridge.d.ts.map +1 -0
- package/lib/types/components/sidePanel/panelBridge.js +55 -0
- package/lib/types/components/sidePanel/pluginPanelAdapter.d.ts +22 -0
- package/lib/types/components/sidePanel/pluginPanelAdapter.d.ts.map +1 -0
- package/lib/types/components/sidePanel/pluginPanelAdapter.js +148 -0
- package/lib/types/components/sidePanel/types.d.ts +110 -0
- package/lib/types/components/sidePanel/types.d.ts.map +1 -0
- package/lib/types/components/sidePanel/types.js +1 -0
- package/lib/types/components/sidePanel/usePanelInput.d.ts +5 -0
- package/lib/types/components/sidePanel/usePanelInput.d.ts.map +1 -0
- package/lib/types/components/sidePanel/usePanelInput.js +44 -0
- package/lib/types/components/sidePanel/useSidePanel.d.ts +47 -0
- package/lib/types/components/sidePanel/useSidePanel.d.ts.map +1 -0
- package/lib/types/components/sidePanel/useSidePanel.js +284 -0
- package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts +3 -1
- package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts.map +1 -1
- package/lib/types/components/workspaces/HomeWorkspaceRow.js +3 -2
- package/lib/types/deepseekPricing.d.ts +10 -9
- package/lib/types/deepseekPricing.d.ts.map +1 -1
- package/lib/types/deepseekPricing.js +18 -11
- package/lib/types/dsh-adapter/channel/attached-context.d.ts +58 -0
- package/lib/types/dsh-adapter/channel/attached-context.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/attached-context.js +109 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts +6 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/binding-events.js +43 -0
- package/lib/types/dsh-adapter/channel/capabilities.d.ts +82 -0
- package/lib/types/dsh-adapter/channel/capabilities.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/capabilities.js +165 -0
- package/lib/types/dsh-adapter/channel/command-completions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/command-completions.js +8 -0
- package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts +4 -12
- package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/context-bookkeeping.js +9 -4
- package/lib/types/dsh-adapter/channel/input-delivery.d.ts +13 -2
- package/lib/types/dsh-adapter/channel/input-delivery.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/input-delivery.js +18 -1
- package/lib/types/dsh-adapter/channel/mode-actions.d.ts +0 -3
- package/lib/types/dsh-adapter/channel/mode-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/mode-actions.js +7 -2
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts +8 -1
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/mode-permission-actions.js +0 -1
- package/lib/types/dsh-adapter/channel/preferences.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/preferences.js +9 -1
- package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/projection.js +42 -37
- package/lib/types/dsh-adapter/channel/reports.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/reports.js +13 -4
- package/lib/types/dsh-adapter/channel/session-reset.d.ts +5 -1
- package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-reset.js +1 -0
- package/lib/types/dsh-adapter/channel/state.d.ts +18 -2
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/state.js +2 -1
- package/lib/types/dsh-adapter/channel/types.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/usage.d.ts +18 -1
- package/lib/types/dsh-adapter/channel/usage.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/usage.js +97 -2
- package/lib/types/dsh-adapter/channel.d.ts +1 -1
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +56 -3
- package/lib/types/dsh-adapter/context-occupancy.d.ts +204 -0
- package/lib/types/dsh-adapter/context-occupancy.d.ts.map +1 -0
- package/lib/types/dsh-adapter/context-occupancy.js +299 -0
- package/lib/types/dsh-adapter/contract.d.ts +14 -0
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +24 -0
- package/lib/types/dsh-adapter/index.d.ts +32 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +20 -1
- package/lib/types/dsh-adapter/migrate/sessionize.d.ts.map +1 -1
- package/lib/types/dsh-adapter/migrate/sessionize.js +11 -12
- package/lib/types/dsh-adapter/panel-runtime-registry.d.ts +39 -0
- package/lib/types/dsh-adapter/panel-runtime-registry.d.ts.map +1 -0
- package/lib/types/dsh-adapter/panel-runtime-registry.js +84 -0
- package/lib/types/dsh-adapter/panels.d.ts +251 -0
- package/lib/types/dsh-adapter/panels.d.ts.map +1 -0
- package/lib/types/dsh-adapter/panels.js +407 -0
- package/lib/types/dsh-adapter/plugin-host.js +1 -1
- package/lib/types/dsh-adapter/plugin.d.ts +17 -1
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +169 -32
- package/lib/types/dsh-adapter/presets.d.ts +26 -6
- package/lib/types/dsh-adapter/presets.d.ts.map +1 -1
- package/lib/types/dsh-adapter/presets.js +29 -7
- package/lib/types/dsh-adapter/startup-args.d.ts +8 -0
- package/lib/types/dsh-adapter/startup-args.d.ts.map +1 -0
- package/lib/types/dsh-adapter/startup-args.js +34 -0
- package/lib/types/history.d.ts +24 -7
- package/lib/types/history.d.ts.map +1 -1
- package/lib/types/history.js +77 -18
- package/lib/types/i18n.d.ts +734 -15
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +302 -6
- package/lib/types/ink/components/App.d.ts +14 -1
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +62 -61
- package/lib/types/ink/components/TerminalSizeContext.d.ts +7 -0
- package/lib/types/ink/components/TerminalSizeContext.d.ts.map +1 -1
- package/lib/types/ink/hooks/use-input.d.ts +11 -0
- package/lib/types/ink/hooks/use-input.d.ts.map +1 -1
- package/lib/types/ink/hooks/use-input.js +8 -2
- package/lib/types/ink/hooks/use-terminal-viewport.d.ts.map +1 -1
- package/lib/types/ink/hooks/use-terminal-viewport.js +3 -1
- package/lib/types/ink/ink.d.ts +18 -0
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +51 -8
- package/lib/types/ink/output.d.ts +10 -1
- package/lib/types/ink/output.d.ts.map +1 -1
- package/lib/types/ink/output.js +3 -3
- package/lib/types/ink/parse-keypress.d.ts +36 -3
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +262 -108
- package/lib/types/ink/render-node-to-output.d.ts +1 -1
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
- package/lib/types/ink/render-node-to-output.js +37 -5
- package/lib/types/ink/screen.d.ts +26 -1
- package/lib/types/ink/screen.d.ts.map +1 -1
- package/lib/types/ink/screen.js +96 -1
- package/lib/types/ink/selection.d.ts +23 -1
- package/lib/types/ink/selection.d.ts.map +1 -1
- package/lib/types/ink/selection.js +102 -26
- package/lib/types/ink/sixel-codec.d.ts +11 -0
- package/lib/types/ink/sixel-codec.d.ts.map +1 -1
- package/lib/types/ink/sixel-codec.js +42 -8
- package/lib/types/math/renderer.d.ts +2 -0
- package/lib/types/math/renderer.d.ts.map +1 -1
- package/lib/types/math/renderer.js +4 -0
- package/lib/types/onboardingPrefs.d.ts +52 -0
- package/lib/types/onboardingPrefs.d.ts.map +1 -0
- package/lib/types/onboardingPrefs.js +107 -0
- package/lib/types/panels.d.ts +4 -0
- package/lib/types/panels.d.ts.map +1 -0
- package/lib/types/panels.js +4 -0
- package/lib/types/screens/Chat.d.ts +22 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +1126 -299
- package/lib/types/screens/Launchpad.d.ts +194 -0
- package/lib/types/screens/Launchpad.d.ts.map +1 -0
- package/lib/types/screens/Launchpad.js +607 -0
- package/lib/types/screens/Onboarding.d.ts +37 -0
- package/lib/types/screens/Onboarding.d.ts.map +1 -0
- package/lib/types/screens/Onboarding.js +492 -0
- package/lib/types/screens/SessionSupervisor.d.ts.map +1 -1
- package/lib/types/screens/SessionSupervisor.js +18 -12
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +32 -14
- package/lib/types/screens/StatusMetrics.d.ts +22 -0
- package/lib/types/screens/StatusMetrics.d.ts.map +1 -1
- package/lib/types/screens/StatusMetrics.js +20 -0
- package/lib/types/screens/chatOverlay.d.ts +18 -1
- package/lib/types/screens/chatOverlay.d.ts.map +1 -1
- package/lib/types/screens/chatOverlay.js +3 -0
- package/lib/types/screens/sessionSupervisor/model.d.ts +1 -2
- package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -1
- package/lib/types/screens/sessionSupervisor/model.js +4 -2
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -1
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +7 -3
- package/lib/types/settings/definitions.d.ts +93 -0
- package/lib/types/settings/definitions.d.ts.map +1 -1
- package/lib/types/settings/definitions.js +83 -0
- package/lib/types/tips.js +5 -5
- package/lib/types/tuiDisplayPrefs.d.ts +42 -2
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
- package/lib/types/tuiDisplayPrefs.js +74 -0
- package/lib/types/update.d.ts +53 -9
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +101 -44
- package/lib/types/utils/bmp.d.ts.map +1 -1
- package/lib/types/utils/bmp.js +8 -1
- package/lib/types/utils/clipboard.d.ts.map +1 -1
- package/lib/types/utils/clipboard.js +25 -6
- package/lib/types/utils/credentials.d.ts.map +1 -1
- package/lib/types/utils/credentials.js +5 -1
- package/lib/types/utils/draftWordBoundary.d.ts +23 -0
- package/lib/types/utils/draftWordBoundary.d.ts.map +1 -0
- package/lib/types/utils/draftWordBoundary.js +161 -0
- package/lib/types/utils/fileTarget.d.ts.map +1 -1
- package/lib/types/utils/fileTarget.js +7 -9
- package/lib/types/utils/inputPaste.d.ts +62 -0
- package/lib/types/utils/inputPaste.d.ts.map +1 -0
- package/lib/types/utils/inputPaste.js +111 -0
- package/lib/types/utils/intl.d.ts +8 -0
- package/lib/types/utils/intl.d.ts.map +1 -1
- package/lib/types/utils/intl.js +11 -0
- package/lib/types/utils/keymap.d.ts +13 -3
- package/lib/types/utils/keymap.d.ts.map +1 -1
- package/lib/types/utils/keymap.js +27 -5
- package/package.json +19 -8
- package/{dsh-ecosystem-spec → tui-profile}/registry/README.md +1 -1
- package/{dsh-ecosystem-spec → tui-profile}/registry/registry-0.15.json +1 -1
- /package/{dsh-ecosystem-spec → tui-profile}/protocols/profile-definitions.d.ts +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/protocols/profile-definitions.js +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-channel-http.d.ts +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-channel-http.js +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-channel.d.ts +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-channel.js +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-contributions.d.ts +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/protocols/tui-contributions.js +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/registry/contracts/decision-events-v1alpha1.json +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/registry/contracts/scene-v1alpha1.json +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/registry/contracts/settings-section-v1alpha1.json +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/registry/contracts/tui-channel-v1alpha1.json +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/registry/contracts/workspace-provider-v1alpha1.json +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/registry/host-descriptor.tui.example.json +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/registry/permissions-0.1.json +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/schemas/conformance-claim.schema.json +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/schemas/effect-ledger-record.schema.json +0 -0
- /package/{dsh-ecosystem-spec → tui-profile}/schemas/host-descriptor.schema.json +0 -0
|
@@ -75,6 +75,20 @@ const SGR_MOUSE_TAIL_RE = /^\[<\d+;\d+;\d+[Mm]$/;
|
|
|
75
75
|
// "token is exactly one report" path.
|
|
76
76
|
// eslint-disable-next-line no-control-regex
|
|
77
77
|
const SGR_MOUSE_TAIL_PREFIX_RE = /^\[<\d+;\d+;\d+[Mm]/;
|
|
78
|
+
// True prefix of an SGR report body (`[<btn;col;row`), including the
|
|
79
|
+
// ambiguous 2/3-byte heads `[` and `[<`. Mirrors SGR_MOUSE_RE's grammar
|
|
80
|
+
// (three numeric params, final byte excluded) and MUST stay in sync with
|
|
81
|
+
// SGR_MOUSE_RE / parseMouseEvent() — the single SGR grammar source for this
|
|
82
|
+
// family. Only the provenance-gated head hold below uses it; the pre-existing
|
|
83
|
+
// `[<`+digits hold keeps SGR_MOUSE_PREFIX_RE.
|
|
84
|
+
const SGR_MOUSE_HEAD_PREFIX_RE = /^\[(?:<(?:\d+(?:;\d*){0,2})?)?$/;
|
|
85
|
+
// ADR-0007 D4: an ambiguous `[`/`ESC[` head may be claimed this long after a
|
|
86
|
+
// REAL mouse report (kind:'mouse') was parsed — the P2 evidence that the user
|
|
87
|
+
// is actually using the mouse. 5s is the initial value; on-device calibration
|
|
88
|
+
// may retune it (still bounded by the first-capture hold deadline below).
|
|
89
|
+
const MOUSE_REPORT_ACTIVITY_MS = 5000;
|
|
90
|
+
// ADR-0007 D5: gated head holds obey the family's 64-byte bound.
|
|
91
|
+
const MOUSE_HEAD_HOLD_MAX_LENGTH = 64;
|
|
78
92
|
// How long a held SGR mouse prefix waits for its continuation before being
|
|
79
93
|
// discarded. The hold sentinel re-arms App's 50ms flush timer, so the hold
|
|
80
94
|
// faces a discard decision on every parse call — the lifetime is measured
|
|
@@ -1122,6 +1136,11 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1122
1136
|
if (win32EscFlushedAt !== undefined && now - win32EscFlushedAt >= WIN32_INPUT_GRACE_MS) {
|
|
1123
1137
|
win32EscFlushedAt = undefined;
|
|
1124
1138
|
}
|
|
1139
|
+
// Tracks the win32 ESC-flush recovery below: a reconstructed `ESC` byte is
|
|
1140
|
+
// NOT transport evidence for the single-read `ESC[` claim (F-2) — the ESC
|
|
1141
|
+
// came from an earlier read's flush, i.e. exactly the two-stroke typing the
|
|
1142
|
+
// P2 gate exists for.
|
|
1143
|
+
let win32EscPrepended = false;
|
|
1125
1144
|
// Same deadline discipline for the reply-prefix hold: first capture only,
|
|
1126
1145
|
// checked on every call (not just on flush, so continuous input cannot
|
|
1127
1146
|
// starve it), and released by resetting the tokenizer — bytes dropped, the
|
|
@@ -1138,8 +1157,10 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1138
1157
|
// a missing introducer. Never capture arbitrary '['-led user text.
|
|
1139
1158
|
if (prevState.mode !== 'IN_PASTE' && tokenizer.buffer() === '' &&
|
|
1140
1159
|
/^\[(?:[\d;]|$)/.test(inputString) &&
|
|
1141
|
-
(WIN32_INPUT_BODY_PREFIX_RE.test('\x1b' + inputString) || win32HoldAllowed))
|
|
1160
|
+
(WIN32_INPUT_BODY_PREFIX_RE.test('\x1b' + inputString) || win32HoldAllowed)) {
|
|
1142
1161
|
inputString = '\x1b' + inputString;
|
|
1162
|
+
win32EscPrepended = true;
|
|
1163
|
+
}
|
|
1143
1164
|
win32EscFlushedAt = undefined;
|
|
1144
1165
|
}
|
|
1145
1166
|
const pending = tokenizer.buffer();
|
|
@@ -1181,6 +1202,10 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1181
1202
|
tokenizer.reset();
|
|
1182
1203
|
deferFlush = false;
|
|
1183
1204
|
}
|
|
1205
|
+
// Tokenizer buffer entering THIS call — captured before feed so the
|
|
1206
|
+
// single-read `ESC[` evidence below cannot be granted to a head whose ESC
|
|
1207
|
+
// or `[` was buffered by an earlier call.
|
|
1208
|
+
const pendingBeforeFeed = tokenizer.buffer();
|
|
1184
1209
|
// First capture only: later flushes (App re-arms its timer while
|
|
1185
1210
|
// `incomplete` is set) must not renew the deadline.
|
|
1186
1211
|
if (deferFlush && claimsResponsePrefix)
|
|
@@ -1204,6 +1229,13 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1204
1229
|
const tokens = isFlush
|
|
1205
1230
|
? deferFlush || releaseResponseHold ? [] : tokenizer.flush()
|
|
1206
1231
|
: tokenizer.feed(inputString);
|
|
1232
|
+
// ADR-0007 D4 addendum (F-2): grant the ambiguous `ESC[` head P1-only claim
|
|
1233
|
+
// when both bytes were buffered inside this one non-flush read from an empty
|
|
1234
|
+
// buffer. Set here, consumed by the flush call that emits it, then cleared
|
|
1235
|
+
// (a flush feeds nothing). Cross-read accumulation leaves it unset → P2.
|
|
1236
|
+
const mouseHeadSingleRead = !isFlush && !win32EscPrepended && pendingBeforeFeed === '' && tokenizer.buffer() === '\x1b['
|
|
1237
|
+
? '\x1b['
|
|
1238
|
+
: undefined;
|
|
1207
1239
|
if (isFlush && !inPaste && tokens.some(token => token.value === '\x1b')) {
|
|
1208
1240
|
win32EscFlushedAt = now;
|
|
1209
1241
|
}
|
|
@@ -1270,16 +1302,81 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1270
1302
|
// dropped rather than shown.
|
|
1271
1303
|
if (carryTailAfterEscFlush === undefined)
|
|
1272
1304
|
terminalResponseReattachTail = undefined;
|
|
1273
|
-
//
|
|
1274
|
-
//
|
|
1275
|
-
//
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
Date.now() - (mouseTailHoldAt ?? 0) > MOUSE_TAIL_HOLD_GRACE_MS) {
|
|
1305
|
+
// Claim provenance of the current hold (see KeyParseState docs): true =
|
|
1306
|
+
// gated (RELEASE on expiry/overflow), false = legacy silent discard,
|
|
1307
|
+
// undefined = no hold.
|
|
1308
|
+
let mouseTailHoldReleasable = prevState.mouseTailHoldReleasable;
|
|
1309
|
+
let lastMouseReportAt = prevState.lastMouseReportAt;
|
|
1310
|
+
const clearMouseTailHold = () => {
|
|
1280
1311
|
mouseTailHold = undefined;
|
|
1281
1312
|
mouseTailHoldAt = undefined;
|
|
1282
|
-
|
|
1313
|
+
mouseTailHoldReleasable = undefined;
|
|
1314
|
+
};
|
|
1315
|
+
// Evidence gate for the SGR head family (ADR-0007 D2/D4). App injects
|
|
1316
|
+
// mouseReportingActive on every processInput; absent keeps direct callers on
|
|
1317
|
+
// the pre-gate `[<`+digits hold, explicit `false` claims nothing, explicit
|
|
1318
|
+
// `true` also allows the ambiguous `[`/`[<` heads — with `[`/`ESC[` needing
|
|
1319
|
+
// a real report inside MOUSE_REPORT_ACTIVITY_MS (P2 evidence).
|
|
1320
|
+
const mouseClaim = prevState.mouseReportingActive === true
|
|
1321
|
+
? 'gated'
|
|
1322
|
+
: prevState.mouseReportingActive === false
|
|
1323
|
+
? 'closed'
|
|
1324
|
+
: 'legacy';
|
|
1325
|
+
const mouseReportActivityLive = () => lastMouseReportAt !== undefined &&
|
|
1326
|
+
now - lastMouseReportAt <= MOUSE_REPORT_ACTIVITY_MS;
|
|
1327
|
+
/**
|
|
1328
|
+
* Decide whether `body` (a token with any leading ESC stripped) is an SGR
|
|
1329
|
+
* report head this parser may hold. `undefined` = ordinary input (no claim);
|
|
1330
|
+
* otherwise `releasable` says whether invalidation RELEASES the bytes
|
|
1331
|
+
* (gated claim) or silently discards them (legacy shape-specific claim).
|
|
1332
|
+
* `singleReadHead` = the `ESC[` body was formed inside ONE read (transport
|
|
1333
|
+
* evidence, ADR-0007 D4 addendum) and therefore counts as P1 evidence.
|
|
1334
|
+
*/
|
|
1335
|
+
const claimSgrHead = (body, singleReadHead = false) => {
|
|
1336
|
+
if (mouseClaim === 'closed')
|
|
1337
|
+
return undefined;
|
|
1338
|
+
if (SGR_MOUSE_PREFIX_RE.test(body))
|
|
1339
|
+
return { releasable: mouseClaim === 'gated' };
|
|
1340
|
+
// The ambiguous 1/2-byte heads exist only for the gated family; legacy
|
|
1341
|
+
// callers keep the pre-gate behavior (plain text).
|
|
1342
|
+
if (mouseClaim !== 'gated')
|
|
1343
|
+
return undefined;
|
|
1344
|
+
if (body === '[<')
|
|
1345
|
+
return { releasable: true };
|
|
1346
|
+
// `[`/`ESC[` (D4): without a recent real report this stays ordinary text
|
|
1347
|
+
// (the pre-fix Esc+`[` behavior) unless both bytes arrived in one read —
|
|
1348
|
+
// human two-stroke typing cannot do that (F-2).
|
|
1349
|
+
if (body === '[')
|
|
1350
|
+
return mouseReportActivityLive() || singleReadHead ? { releasable: true } : undefined;
|
|
1351
|
+
return undefined;
|
|
1352
|
+
};
|
|
1353
|
+
/**
|
|
1354
|
+
* Single invalidation/RELEASE entry (F-6): a gated hold is replayed as
|
|
1355
|
+
* ordinary keys in arrival order (ADR-0007 D5); a legacy hold keeps the
|
|
1356
|
+
* pre-gate silent discard. Every invalidation, including an unrelated
|
|
1357
|
+
* protocol boundary, funnels through here; only successful completion of
|
|
1358
|
+
* the held report clears it without replay.
|
|
1359
|
+
*/
|
|
1360
|
+
const releaseHeldMouseHead = () => {
|
|
1361
|
+
if (mouseTailHold === undefined)
|
|
1362
|
+
return;
|
|
1363
|
+
if (mouseTailHoldReleasable === true)
|
|
1364
|
+
keys.push(parseKeypress(mouseTailHold));
|
|
1365
|
+
clearMouseTailHold();
|
|
1366
|
+
};
|
|
1367
|
+
/** Hard deadline + gated size bound, checked at the top of EVERY call. */
|
|
1368
|
+
const shouldReleaseHold = () => mouseTailHold !== undefined &&
|
|
1369
|
+
(now - (mouseTailHoldAt ?? 0) > MOUSE_TAIL_HOLD_GRACE_MS ||
|
|
1370
|
+
(mouseTailHoldReleasable === true &&
|
|
1371
|
+
mouseTailHold.length > MOUSE_HEAD_HOLD_MAX_LENGTH));
|
|
1372
|
+
// Hard deadline + size bound, checked at the top of EVERY call — not only on
|
|
1373
|
+
// flush. Continuous input keeps cancelling and re-arming App's 50ms flush
|
|
1374
|
+
// timer, so a flush-only check can starve while the user types: a hold past
|
|
1375
|
+
// its grace would then still merge a late `;34M` (or plain digits) into a
|
|
1376
|
+
// phantom report. A gated hold RELEASES its bytes as ordinary keys instead
|
|
1377
|
+
// of dropping them (ADR-0007 D5); legacy holds keep the pre-gate discard.
|
|
1378
|
+
if (shouldReleaseHold())
|
|
1379
|
+
releaseHeldMouseHead();
|
|
1283
1380
|
// Mutable token queue: a text token that starts with the completion of
|
|
1284
1381
|
// the CURRENT hold but carries trailing bytes is split in-place — the
|
|
1285
1382
|
// completion tail is consumed now, the suffix is pushed back for the
|
|
@@ -1326,10 +1423,9 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1326
1423
|
pasteBuffer = '';
|
|
1327
1424
|
// Bracketed paste is a terminal-controlled mode: report bytes are
|
|
1328
1425
|
// contiguous on the wire, so a held SGR prefix's report is dead
|
|
1329
|
-
// once paste starts.
|
|
1426
|
+
// once paste starts. Release it — a late `;34M` arriving after the
|
|
1330
1427
|
// paste must not merge into a phantom press.
|
|
1331
|
-
|
|
1332
|
-
mouseTailHoldAt = undefined;
|
|
1428
|
+
releaseHeldMouseHead();
|
|
1333
1429
|
}
|
|
1334
1430
|
else if (token.value === PASTE_END) {
|
|
1335
1431
|
// Always emit a paste key, even for empty pastes. This allows
|
|
@@ -1340,8 +1436,7 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1340
1436
|
pasteBuffer = '';
|
|
1341
1437
|
// Paste end is a terminal protocol boundary too — a held SGR prefix
|
|
1342
1438
|
// from before the paste cannot complete now.
|
|
1343
|
-
|
|
1344
|
-
mouseTailHoldAt = undefined;
|
|
1439
|
+
releaseHeldMouseHead();
|
|
1345
1440
|
}
|
|
1346
1441
|
else if (inPaste) {
|
|
1347
1442
|
// Sequences inside paste are treated as literal text
|
|
@@ -1354,8 +1449,7 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1354
1449
|
// A fresh protocol record proves a held SGR prefix's report died:
|
|
1355
1450
|
// report bytes are contiguous on the wire, so nothing may
|
|
1356
1451
|
// interleave between a report's fragments.
|
|
1357
|
-
|
|
1358
|
-
mouseTailHoldAt = undefined;
|
|
1452
|
+
releaseHeldMouseHead();
|
|
1359
1453
|
// win32-input-mode record. null means a swallowed event (keyup,
|
|
1360
1454
|
// bare modifier, orphaned surrogate) — the sequence is consumed
|
|
1361
1455
|
// either way and never reaches the VT keypress parser.
|
|
@@ -1370,40 +1464,62 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1370
1464
|
}
|
|
1371
1465
|
else {
|
|
1372
1466
|
// Fixed decision order (D6) for one complete token — see
|
|
1373
|
-
// claimProtocolSequence: OSC 8 drop → terminal reply
|
|
1374
|
-
//
|
|
1375
|
-
//
|
|
1376
|
-
//
|
|
1377
|
-
//
|
|
1467
|
+
// claimProtocolSequence: OSC 8 drop (#1178) → terminal reply
|
|
1468
|
+
// (#1177) → mouse (SGR 1006 first, X10 as the legacy 1000/1002
|
|
1469
|
+
// fallback). This parser's SGR head-fragment claim family
|
|
1470
|
+
// (#1160/#1120) lives inside the mouse step, below the complete
|
|
1471
|
+
// claim, and never runs ahead of OSC 8 or a reply. Wheel falls
|
|
1472
|
+
// through to parseKeypress, which turns it into a wheel key WITH
|
|
1473
|
+
// the pointer coordinates for position-based routing.
|
|
1378
1474
|
const claimed = claimProtocolSequence(token.value);
|
|
1379
1475
|
if (claimed !== null) {
|
|
1380
1476
|
// Any claim — drop, terminal reply or complete mouse report — is
|
|
1381
1477
|
// a protocol boundary: a held prefix belongs to an older, dead
|
|
1382
|
-
// report.
|
|
1383
|
-
// a phantom event.
|
|
1384
|
-
|
|
1385
|
-
|
|
1478
|
+
// report. Release it BEFORE it can merge the next fragment into
|
|
1479
|
+
// a phantom event. A complete report also lights the P2 evidence
|
|
1480
|
+
// window for the ambiguous `[`/`ESC[` heads.
|
|
1481
|
+
if (claimed.kind === 'mouse')
|
|
1482
|
+
lastMouseReportAt = now;
|
|
1483
|
+
releaseHeldMouseHead();
|
|
1386
1484
|
keys.push(claimed);
|
|
1387
1485
|
}
|
|
1388
|
-
else if (SGR_MOUSE_PREFIX_RE.test(token.value.replace(/^\x1b/, ''))) {
|
|
1389
|
-
// Flush-truncated SGR mouse report: the tokenizer's flush
|
|
1390
|
-
// emitted the buffered prefix (ESC still attached) as a
|
|
1391
|
-
// sequence token. It is protocol bytes mid-report, not a key —
|
|
1392
|
-
// strip the ESC, hold for the continuation (the text-token
|
|
1393
|
-
// branch above completes it), and never let it fall through
|
|
1394
|
-
// to parseKeypress, where it would leak into the prompt.
|
|
1395
|
-
// A fresh prefix REPLACES any stale hold instead of appending:
|
|
1396
|
-
// the new report's arrival proves the old one's tail never
|
|
1397
|
-
// came (`[<0;18` + `[<64;…` concatenated parses as garbage).
|
|
1398
|
-
mouseTailHold = token.value.replace(/^\x1b/, '');
|
|
1399
|
-
mouseTailHoldAt = Date.now();
|
|
1400
|
-
}
|
|
1401
1486
|
else {
|
|
1402
|
-
|
|
1403
|
-
//
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1487
|
+
const head = token.value.replace(/^\x1b/, '');
|
|
1488
|
+
// F-2 transport evidence: `ESC[` buffered in ONE read (see
|
|
1489
|
+
// KeyParseState.mouseHeadSingleRead) grants the P1-only claim.
|
|
1490
|
+
const singleReadHead = token.value === '\x1b[' && prevState.mouseHeadSingleRead === token.value;
|
|
1491
|
+
const claim = claimSgrHead(head, singleReadHead);
|
|
1492
|
+
if (claim !== undefined &&
|
|
1493
|
+
(!claim.releasable || head.length <= MOUSE_HEAD_HOLD_MAX_LENGTH)) {
|
|
1494
|
+
// Flush-truncated SGR head: the tokenizer's flush emitted the
|
|
1495
|
+
// buffered head (ESC still attached) as a sequence token. It
|
|
1496
|
+
// is protocol bytes mid-report, not a key — strip the ESC,
|
|
1497
|
+
// hold for the continuation (the text-token branch below
|
|
1498
|
+
// completes it), and never let it fall through to
|
|
1499
|
+
// parseKeypress, where it would leak into the prompt.
|
|
1500
|
+
// A fresh head REPLACES any stale hold instead of appending:
|
|
1501
|
+
// the new report's arrival proves the old one's tail never
|
|
1502
|
+
// came (`[<0;18` + `[<64;…` concatenated parses as garbage).
|
|
1503
|
+
// F-1: a gated old hold is RELEASED first so its bytes are
|
|
1504
|
+
// neither dropped nor ordered after the new head's bytes.
|
|
1505
|
+
releaseHeldMouseHead();
|
|
1506
|
+
mouseTailHold = head;
|
|
1507
|
+
mouseTailHoldAt = now;
|
|
1508
|
+
mouseTailHoldReleasable = claim.releasable;
|
|
1509
|
+
}
|
|
1510
|
+
else if (claim !== undefined && claim.releasable) {
|
|
1511
|
+
// Over the gated 64B bound: release immediately — never hold,
|
|
1512
|
+
// never drop (ADR-0007 D5).
|
|
1513
|
+
releaseHeldMouseHead();
|
|
1514
|
+
keys.push(parseKeypress(head));
|
|
1515
|
+
}
|
|
1516
|
+
else {
|
|
1517
|
+
// Ordinary key sequence (arrows, function keys, …) — still an
|
|
1518
|
+
// ESC protocol start, so a held head's report is dead. F-1:
|
|
1519
|
+
// a gated hold is RELEASED in arrival order first.
|
|
1520
|
+
releaseHeldMouseHead();
|
|
1521
|
+
keys.push(parseKeypress(token.value));
|
|
1522
|
+
}
|
|
1407
1523
|
}
|
|
1408
1524
|
}
|
|
1409
1525
|
}
|
|
@@ -1414,9 +1530,8 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1414
1530
|
}
|
|
1415
1531
|
else if (WIN32_INPUT_TAILS_RE.test(token.value)) {
|
|
1416
1532
|
// Protocol bytes — a live SGR mouse report cannot contain them, so
|
|
1417
|
-
// a held prefix's report is dead.
|
|
1418
|
-
|
|
1419
|
-
mouseTailHoldAt = undefined;
|
|
1533
|
+
// a held prefix's report is dead. Release before recovering.
|
|
1534
|
+
releaseHeldMouseHead();
|
|
1420
1535
|
terminalResponseReattachTail = undefined;
|
|
1421
1536
|
// A delayed win32-input-mode continuation can arrive after App's
|
|
1422
1537
|
// escape timer has already flushed its ESC prefix. Recover complete
|
|
@@ -1445,15 +1560,17 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1445
1560
|
// a full [\x20-] range would match typed input like `[MAX]` batched
|
|
1446
1561
|
// into one read and silently drop it as a phantom click.
|
|
1447
1562
|
// Any older hold belongs to a DIFFERENT, dead report: a complete
|
|
1448
|
-
// report's arrival proves its tail never came.
|
|
1563
|
+
// report's arrival proves its tail never came. Release the stale
|
|
1449
1564
|
// hold and resynthesize this tail cleanly — concatenating them
|
|
1450
1565
|
// (`ESC + hold + complete tail`) parses as garbage and leaks the
|
|
1451
1566
|
// protocol bytes into the prompt as an ordinary key.
|
|
1452
|
-
|
|
1453
|
-
mouseTailHoldAt = undefined;
|
|
1567
|
+
releaseHeldMouseHead();
|
|
1454
1568
|
terminalResponseReattachTail = undefined;
|
|
1455
1569
|
const resynthesized = '\x1b' + token.value;
|
|
1456
1570
|
const mouse = parseMouseEvent(resynthesized);
|
|
1571
|
+
// A real report lights the P2 evidence window for ambiguous heads.
|
|
1572
|
+
if (mouse)
|
|
1573
|
+
lastMouseReportAt = now;
|
|
1457
1574
|
keys.push(mouse ?? parseKeypress(resynthesized));
|
|
1458
1575
|
}
|
|
1459
1576
|
else if (mouseTailHold !== undefined &&
|
|
@@ -1476,81 +1593,109 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1476
1593
|
tokenQueue.splice(qi + 1, 0, { type: 'text', value: suffix });
|
|
1477
1594
|
}
|
|
1478
1595
|
const resynthesized = '\x1b' + combined.slice(0, reportEnd);
|
|
1479
|
-
|
|
1480
|
-
mouseTailHoldAt = undefined;
|
|
1596
|
+
clearMouseTailHold();
|
|
1481
1597
|
const mouse = parseMouseEvent(resynthesized);
|
|
1598
|
+
// A real report lights the P2 evidence window for ambiguous heads.
|
|
1599
|
+
if (mouse)
|
|
1600
|
+
lastMouseReportAt = now;
|
|
1482
1601
|
keys.push(mouse ?? parseKeypress(resynthesized));
|
|
1483
1602
|
}
|
|
1484
|
-
else if (SGR_MOUSE_PREFIX_RE.test(token.value) ||
|
|
1485
|
-
// Continuation of an active hold: with the prefix already captured,
|
|
1486
|
-
// the next fragment (`32;5M`'s leading digits, more params) is
|
|
1487
|
-
// digits/semicolons — ambiguous with typing, so treat them as part
|
|
1488
|
-
// of the in-flight report until the deadline. Completion uses the branch
|
|
1489
|
-
// above first, so reaching here with a hold means still incomplete.
|
|
1490
|
-
(mouseTailHold !== undefined && /^[\d;]*$/.test(token.value) && token.value !== '')) {
|
|
1491
|
-
// Incomplete SGR mouse prefix: ConPTY split the report mid-sequence
|
|
1492
|
-
// and the flush timer already released the buffered ESC prefix, so
|
|
1493
|
-
// this text token carries protocol bytes, not typing. Hold it for
|
|
1494
|
-
// the next chunk (which completes the tail — handled by the branch
|
|
1495
|
-
// above via the combined `hold + value` check) instead of leaking
|
|
1496
|
-
// into the prompt; the deadline check at the top of every call
|
|
1497
|
-
// discards the hold once its grace expires. The regex demands `<` +
|
|
1498
|
-
// digits, which no realistic typed text produces as a single text
|
|
1499
|
-
// token.
|
|
1500
|
-
terminalResponseReattachTail = undefined;
|
|
1501
|
-
if (mouseTailHold === undefined)
|
|
1502
|
-
mouseTailHoldAt = Date.now();
|
|
1503
|
-
mouseTailHold = (mouseTailHold ?? '') + token.value;
|
|
1504
|
-
}
|
|
1505
1603
|
else {
|
|
1506
|
-
//
|
|
1507
|
-
//
|
|
1508
|
-
//
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
// #796 re-attach + post-flush reassembly: put the flushed introducer
|
|
1512
|
-
// back, then let the one reply-shape authority decide. A fragment
|
|
1513
|
-
// held from an earlier call is joined with this token first, so a
|
|
1514
|
-
// tail that is itself split again (`[?61;4;6` then `;14;21;22c`) is
|
|
1515
|
-
// reassembled instead of falling into the prompt in pieces. A claim
|
|
1604
|
+
// #1177 terminal-reply re-attach runs first (decision order D6:
|
|
1605
|
+
// reply before mouse): the introducer ESC may already have been
|
|
1606
|
+
// flushed, so this text token — joined with any held fragment — may
|
|
1607
|
+
// be the rest of a reply. The one shape authority
|
|
1608
|
+
// (`claimExpectedResponseHead`) decides completeness, and a claim
|
|
1516
1609
|
// needs BOTH a pending query of the matching expected type and a
|
|
1517
1610
|
// shape that can still complete into it; anything else keeps the
|
|
1518
1611
|
// token literal (AC-3) and drops a stale fragment rather than
|
|
1519
1612
|
// leaking protocol bytes.
|
|
1520
|
-
const
|
|
1521
|
-
const
|
|
1522
|
-
? claimExpectedResponseHead(
|
|
1613
|
+
const replyCandidate = (terminalResponseReattachTail ?? '') + token.value;
|
|
1614
|
+
const claimedResponse = mayRecoverTerminalResponseTail
|
|
1615
|
+
? claimExpectedResponseHead(replyCandidate, expectedResponseTypes)
|
|
1523
1616
|
: undefined;
|
|
1524
|
-
if (
|
|
1617
|
+
if (claimedResponse) {
|
|
1525
1618
|
terminalResponseReattachTail = undefined;
|
|
1619
|
+
// A completed reply is a protocol boundary: a held SGR head's
|
|
1620
|
+
// report is dead (same caliber as the sequence-token reply path).
|
|
1621
|
+
releaseHeldMouseHead();
|
|
1526
1622
|
keys.push({
|
|
1527
1623
|
kind: 'response',
|
|
1528
|
-
sequence: '\x1b' +
|
|
1529
|
-
response:
|
|
1624
|
+
sequence: '\x1b' + replyCandidate.slice(0, claimedResponse.consumed),
|
|
1625
|
+
response: claimedResponse.response,
|
|
1530
1626
|
});
|
|
1531
1627
|
// Trailing bytes beyond the completed reply are ordinary input
|
|
1532
1628
|
// (the terminal batched the tail with the next keystrokes).
|
|
1533
|
-
const suffix =
|
|
1629
|
+
const suffix = replyCandidate.slice(claimedResponse.consumed);
|
|
1534
1630
|
if (suffix)
|
|
1535
1631
|
tokenQueue.splice(qi + 1, 0, { type: 'text', value: suffix });
|
|
1536
1632
|
}
|
|
1537
|
-
else if (mayRecoverTerminalResponseTail &&
|
|
1538
|
-
candidate.length <= TERMINAL_RESPONSE_MAX_LENGTH &&
|
|
1539
|
-
expectsResponseType('\x1b' + candidate, expectedResponseTypes)) {
|
|
1540
|
-
// Still an open expected reply prefix — hold it for the next call.
|
|
1541
|
-
terminalResponseReattachTail = candidate;
|
|
1542
|
-
}
|
|
1543
1633
|
else {
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1634
|
+
const replyStillOpen = mayRecoverTerminalResponseTail &&
|
|
1635
|
+
replyCandidate.length <= TERMINAL_RESPONSE_MAX_LENGTH &&
|
|
1636
|
+
expectsResponseType('\x1b' + replyCandidate, expectedResponseTypes);
|
|
1637
|
+
const freshReplyPrefix = mayRecoverTerminalResponseTail &&
|
|
1548
1638
|
token.value.length <= TERMINAL_RESPONSE_MAX_LENGTH &&
|
|
1549
|
-
expectsResponseType('\x1b' + token.value, expectedResponseTypes)
|
|
1639
|
+
expectsResponseType('\x1b' + token.value, expectedResponseTypes);
|
|
1640
|
+
if (replyStillOpen) {
|
|
1641
|
+
// Still an open expected reply prefix — hold it for the next
|
|
1642
|
+
// call. The reply shape proves any held mouse report is dead, so
|
|
1643
|
+
// release the old mouse hold before claiming the reply.
|
|
1644
|
+
releaseHeldMouseHead();
|
|
1645
|
+
terminalResponseReattachTail = replyCandidate;
|
|
1646
|
+
}
|
|
1647
|
+
else if (freshReplyPrefix) {
|
|
1648
|
+
// The held fragment (if any) cannot be completed; drop it and
|
|
1649
|
+
// give the fresh bytes their own chance to start a reply prefix.
|
|
1650
|
+
// Again the reply claim releases any old mouse hold.
|
|
1651
|
+
releaseHeldMouseHead();
|
|
1550
1652
|
terminalResponseReattachTail = token.value;
|
|
1551
1653
|
}
|
|
1552
1654
|
else {
|
|
1553
|
-
|
|
1655
|
+
// SGR head family: claim a fresh head, extend an active hold, or
|
|
1656
|
+
// pass ordinary text through. `claimSgrHead` pairs shape with
|
|
1657
|
+
// evidence; a hold only survives while `hold + token` remains a
|
|
1658
|
+
// legal head prefix (SGR_MOUSE_HEAD_PREFIX_RE, grammar-locked to
|
|
1659
|
+
// SGR_MOUSE_RE), so text that cannot continue it proves the held
|
|
1660
|
+
// report died.
|
|
1661
|
+
terminalResponseReattachTail = undefined;
|
|
1662
|
+
const combined = (mouseTailHold ?? '') + token.value;
|
|
1663
|
+
const claim = claimSgrHead(token.value);
|
|
1664
|
+
const canExtend = mouseTailHold !== undefined &&
|
|
1665
|
+
SGR_MOUSE_HEAD_PREFIX_RE.test(combined);
|
|
1666
|
+
if (canExtend &&
|
|
1667
|
+
(mouseTailHoldReleasable !== true ||
|
|
1668
|
+
combined.length <= MOUSE_HEAD_HOLD_MAX_LENGTH)) {
|
|
1669
|
+
// Continuation (`<` after a bare `[`, digits/semicolons after
|
|
1670
|
+
// `[<`): keep the FIRST-capture deadline — flushes must not
|
|
1671
|
+
// renew it.
|
|
1672
|
+
mouseTailHold = combined;
|
|
1673
|
+
}
|
|
1674
|
+
else if (claim !== undefined &&
|
|
1675
|
+
(!claim.releasable ||
|
|
1676
|
+
token.value.length <= MOUSE_HEAD_HOLD_MAX_LENGTH)) {
|
|
1677
|
+
// Incomplete SGR head arriving as a text token (ConPTY/SSH
|
|
1678
|
+
// split the report mid-sequence and the flush timer already
|
|
1679
|
+
// released the buffered ESC prefix): hold it for the next
|
|
1680
|
+
// chunk instead of leaking protocol bytes into the prompt. A
|
|
1681
|
+
// fresh head REPLACES any stale hold — two reports never
|
|
1682
|
+
// concatenate — so the deadline restarts from this capture.
|
|
1683
|
+
// F-1: a gated old hold is RELEASED first so its bytes are
|
|
1684
|
+
// replayed in arrival order, not dropped.
|
|
1685
|
+
releaseHeldMouseHead();
|
|
1686
|
+
mouseTailHold = token.value;
|
|
1687
|
+
mouseTailHoldAt = now;
|
|
1688
|
+
mouseTailHoldReleasable = claim.releasable;
|
|
1689
|
+
}
|
|
1690
|
+
else {
|
|
1691
|
+
// The open report is dead (text that cannot continue it) or
|
|
1692
|
+
// the gated 64B bound is exceeded: a gated hold RELEASES its
|
|
1693
|
+
// bytes in arrival order (ADR-0007 D5) so no user input is
|
|
1694
|
+
// dropped; legacy holds keep the pre-gate silent discard.
|
|
1695
|
+
// This token then passes through as ordinary typing.
|
|
1696
|
+
releaseHeldMouseHead();
|
|
1697
|
+
keys.push(parseKeypress(token.value));
|
|
1698
|
+
}
|
|
1554
1699
|
}
|
|
1555
1700
|
}
|
|
1556
1701
|
}
|
|
@@ -1613,13 +1758,13 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1613
1758
|
win32Protocol.held = [];
|
|
1614
1759
|
win32Protocol.sequence = '';
|
|
1615
1760
|
}
|
|
1616
|
-
// A held SGR mouse
|
|
1617
|
-
//
|
|
1618
|
-
//
|
|
1619
|
-
//
|
|
1620
|
-
//
|
|
1621
|
-
//
|
|
1622
|
-
//
|
|
1761
|
+
// A held SGR mouse head that never completed expires in the deadline check
|
|
1762
|
+
// at the top of this call — on flush AND on ordinary input alike
|
|
1763
|
+
// (continuous input starves flush-only checks). A gated hold is RELEASED as
|
|
1764
|
+
// ordinary keys there (ADR-0007 D5: delayed but never dropped); a legacy
|
|
1765
|
+
// shape-specific hold keeps the pre-gate silent discard. Partial recovery
|
|
1766
|
+
// of the coords is not attempted — a mouse event with guessed terminators
|
|
1767
|
+
// would dispatch phantom clicks.
|
|
1623
1768
|
// The reply-prefix hold lives only while the tokenizer still retains a
|
|
1624
1769
|
// reply-shaped prefix: completion, release or reset all end it, so the
|
|
1625
1770
|
// NEXT hold captures its own first-capture deadline.
|
|
@@ -1668,8 +1813,17 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
1668
1813
|
win32AltHighSurrogate: win32Ctx.altHigh,
|
|
1669
1814
|
win32Paste,
|
|
1670
1815
|
win32Protocol,
|
|
1816
|
+
// The host gate rides along as well: App replaces its state with this
|
|
1817
|
+
// object on every read, and re-injects the latest evidence each call.
|
|
1818
|
+
mouseReportingActive: prevState.mouseReportingActive,
|
|
1819
|
+
lastMouseReportAt,
|
|
1671
1820
|
mouseTailHold,
|
|
1672
1821
|
mouseTailHoldAt,
|
|
1822
|
+
mouseTailHoldReleasable,
|
|
1823
|
+
// Parser-internal transport evidence: set by the read that buffered the
|
|
1824
|
+
// head, consumed by the next call (the flush that emits `ESC[`), then
|
|
1825
|
+
// cleared because that call feeds nothing.
|
|
1826
|
+
mouseHeadSingleRead,
|
|
1673
1827
|
terminalResponseHoldAt,
|
|
1674
1828
|
terminalResponseReattachTail,
|
|
1675
1829
|
// A fresh lone-Escape flush re-arms the window; otherwise the carried
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DOMElement } from './dom.js';
|
|
2
2
|
import type { Rectangle } from './layout/geometry.js';
|
|
3
3
|
import type Output from './output.js';
|
|
4
|
-
import type
|
|
4
|
+
import { type Screen } from './screen.js';
|
|
5
5
|
import { type StyledSegment } from './squash-text-nodes.js';
|
|
6
6
|
import type { Color } from './styles.js';
|
|
7
7
|
/** Reset the per-frame layout-shift flag. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-node-to-output.d.ts","sourceRoot":"","sources":["../../../src/ink/render-node-to-output.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAIrD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"render-node-to-output.d.ts","sourceRoot":"","sources":["../../../src/ink/render-node-to-output.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAIrD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,OAAO,EAA4B,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AACnE,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAuBxC,6CAA6C;AAC7C,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAOD;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AA0BvE,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAA;AAYpE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,UAAU,CAAA;IAChB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,SAAS,gBAAgB,EAAE,CAEhE;AAED,iFAAiF;AACjF,wBAAgB,eAAe,IAAI,IAAI,CAOtC;AAsED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAuBhD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAyBtE;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAEjD;AASD,8DAA8D;AAC9D,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,UAAU,GAAG,IAAI,CAEtD;AAgBD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,MAAM,CAAA;IACtB,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAGD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG;IAC1C,wEAAwE;IACxE,IAAI,EAAE,aAAa,GAAG,WAAW,CAAA;IACjC,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAGD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GACb,aAAa,GAAG,WAAW,CAO7B;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,cAAc,EAAE,CAIzD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,YAAY,EAAE,CAIpD;AAoFD;;;;;GAKG;AACH,iBAAS,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,CASlE;AAED;;;;;;;;;;;GAWG;AACH,iBAAS,wBAAwB,CAC/B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,aAAa,EAAE,EACzB,aAAa,EAAE,MAAM,EAAE,EACvB,aAAa,EAAE,MAAM,EACrB,WAAW,GAAE,OAAe,GAC3B,MAAM,CA0GR;AA+DD;;;;;;;;;GASG;AACH,iBAAS,kBAAkB,CACzB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAM9B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,wBAAwB,CAAC,EAAE,KAAK,CAAA;CACjC,GACA,IAAI,CA4tCN;AA2OD,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,CAAA;AAE1D,eAAe,kBAAkB,CAAA"}
|
|
@@ -5,6 +5,7 @@ import getMaxWidth from './get-max-width.js';
|
|
|
5
5
|
import { LayoutDisplay, LayoutEdge } from './layout/node.js';
|
|
6
6
|
import { nodeCache, pendingClears, textPaintCache } from './node-cache.js';
|
|
7
7
|
import renderBorder from './render-border.js';
|
|
8
|
+
import { countPaintedFlankColumns } from './screen.js';
|
|
8
9
|
import { squashTextNodesToSegments, } from './squash-text-nodes.js';
|
|
9
10
|
import { isXtermJs } from './terminal.js';
|
|
10
11
|
import { terminalImageSourceFromAttributes } from './terminal-image.js';
|
|
@@ -35,6 +36,14 @@ export function resetLayoutShifted() {
|
|
|
35
36
|
export function didLayoutShift() {
|
|
36
37
|
return layoutShifted;
|
|
37
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* How many painted columns may live outside a scroll container's x-range
|
|
41
|
+
* (within the shifted rows) before the DECSTBM fast path is rejected in
|
|
42
|
+
* favor of the box-clipped full path: the hardware scroll displaces those
|
|
43
|
+
* columns and the diff must write every displaced cell back. Blank margins
|
|
44
|
+
* and the 1-2 column gutter rail qualify; a sibling split column does not.
|
|
45
|
+
*/
|
|
46
|
+
const DECSTBM_MAX_FLANK_COLUMNS = 4;
|
|
38
47
|
let scrollHint = null;
|
|
39
48
|
// Rects of position:absolute nodes from the PREVIOUS frame, used by
|
|
40
49
|
// ScrollBox's blit+shift third-pass repair (see usage site). Recorded at
|
|
@@ -673,7 +682,7 @@ function renderNodeToOutput(node, output, options) {
|
|
|
673
682
|
// The sibling-overlap check is load-bearing: Yoga's pixel-grid rounding
|
|
674
683
|
// can give a box h=0 while still leaving a row for it (next sibling at
|
|
675
684
|
// y+1, not y). HelpV2's third shortcuts column hits this — skipping
|
|
676
|
-
// unconditionally drops
|
|
685
|
+
// unconditionally drops its last row from /help output.
|
|
677
686
|
if (height === 0 && siblingSharesY(node, yogaNode)) {
|
|
678
687
|
nodeCache.set(node, { x, y, width, height, top: yogaTop, opaque: paintsOwnRect(node) });
|
|
679
688
|
node.dirty = false;
|
|
@@ -1210,14 +1219,35 @@ function renderNodeToOutput(node, output, options) {
|
|
|
1210
1219
|
const delta = contentCached.y - contentY;
|
|
1211
1220
|
const regionTop = Math.floor(y + contentYoga.getComputedTop());
|
|
1212
1221
|
const regionBottom = regionTop + innerHeight - 1;
|
|
1213
|
-
|
|
1222
|
+
// DECSTBM + SU/SD scroll WHOLE terminal rows — ANSI has no
|
|
1223
|
+
// column-scoped hardware scroll — while this fast path's edge
|
|
1224
|
+
// repaint covers only the box's own x-range. The model-side
|
|
1225
|
+
// shift below is therefore COLUMN-SCOPED to the box: the flanks
|
|
1226
|
+
// keep their correct cells in next.screen, log-update simulates
|
|
1227
|
+
// the hardware scroll on the previous frame full-width, and the
|
|
1228
|
+
// shift op's full-width damage makes the frame diff compare the
|
|
1229
|
+
// flank cells and write them back to the terminal. (Before that
|
|
1230
|
+
// scoping the model shift was full-width too, so prev and next
|
|
1231
|
+
// agreed on the displaced flanks, nothing repaired them, and the
|
|
1232
|
+
// damage stuck — the reported "scrolling the agents panel breaks
|
|
1233
|
+
// the divider seam and the chat column".) The flank repair costs
|
|
1234
|
+
// O(painted flank cells), so the hardware path is only worth it
|
|
1235
|
+
// while the flanks are near-empty (blank page margins, the 1-2
|
|
1236
|
+
// column gutter rail); a wide painted flank (a sibling column
|
|
1237
|
+
// while split) takes the full path below, which repaints the box
|
|
1238
|
+
// clipped to its own bounds.
|
|
1239
|
+
const flankColumns = prevScreen
|
|
1240
|
+
? countPaintedFlankColumns(prevScreen, regionTop, regionBottom, Math.floor(x), Math.floor(x) + Math.floor(width))
|
|
1241
|
+
: Number.MAX_SAFE_INTEGER;
|
|
1242
|
+
const inBoxScroll = cached?.y === y &&
|
|
1214
1243
|
cached.height === height &&
|
|
1215
1244
|
innerHeight > 0 &&
|
|
1216
|
-
Math.abs(delta) < innerHeight
|
|
1245
|
+
Math.abs(delta) < innerHeight;
|
|
1246
|
+
if (inBoxScroll && flankColumns <= DECSTBM_MAX_FLANK_COLUMNS) {
|
|
1217
1247
|
hint = { top: regionTop, bottom: regionBottom, delta };
|
|
1218
1248
|
scrollHint = hint;
|
|
1219
1249
|
}
|
|
1220
|
-
else {
|
|
1250
|
+
else if (!inBoxScroll) {
|
|
1221
1251
|
layoutShifted = true;
|
|
1222
1252
|
}
|
|
1223
1253
|
}
|
|
@@ -1270,7 +1300,9 @@ function renderNodeToOutput(node, output, options) {
|
|
|
1270
1300
|
const { top, bottom, delta } = hint;
|
|
1271
1301
|
const w = Math.floor(width);
|
|
1272
1302
|
output.blit(prevScreen, Math.floor(x), top, w, bottom - top + 1);
|
|
1273
|
-
|
|
1303
|
+
// Column-scoped: see the gate comment above. The terminal still
|
|
1304
|
+
// scrolls whole rows; the diff repairs the flanks.
|
|
1305
|
+
output.shift(top, bottom, delta, Math.floor(x), w);
|
|
1274
1306
|
// Edge rows: new content entering the viewport.
|
|
1275
1307
|
const edgeTop = delta > 0 ? bottom - delta + 1 : top;
|
|
1276
1308
|
const edgeBottom = delta > 0 ? bottom : top - delta - 1;
|