Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
60abcbd
Add reproducible ConPTY margin backend comparison
JavaZeroo Oct 26, 2026
5030058
Add explicit reviewed ConPTY backend experiment
JavaZeroo Oct 26, 2026
0954fea
fix(conpty): preserve failures through margin diagnostic cleanup
JavaZeroo Oct 26, 2026
f2d11f8
Record reviewed ConPTY backend evidence and remaining gaps
JavaZeroo Oct 26, 2026
29d8b8e
Merge R2 diagnostics into optional ConPTY experiment
JavaZeroo Oct 26, 2026
1155a18
docs: index experimental backend limits and frozen evidence
JavaZeroo Oct 26, 2026
e2702af
Preserve backend probe failures through independent cleanup
JavaZeroo Oct 26, 2026
3e5b96d
Merge commit '3d6d44d3b3e9a9a3e41da98e8711e9f19a211fd8' into fix/conp…
JavaZeroo Oct 26, 2026
386ebe7
Add bounded resize ordering capture and candidate replay for R51
JavaZeroo Oct 26, 2026
3cdfda9
Record fixed resize-order counterexamples without claiming a fix
JavaZeroo Oct 26, 2026
4a315ee
docs: freeze the actual three-configuration joint backend baseline
JavaZeroo Oct 26, 2026
4f67954
test: reject malformed resize replay records and inconsistent trace m…
JavaZeroo Oct 26, 2026
07ffd1f
ci: exercise actual resize replay rejection on both candidate platforms
JavaZeroo Oct 26, 2026
ce21016
ci: select the registered candidate resize replay test
JavaZeroo Oct 26, 2026
019cad9
Merge pull request #67 from JavaZeroo/fix/resize-r51
JavaZeroo Oct 26, 2026
f845ccd
Merge commit '3819093b5b622f340bec02a3057a74241507d559' into fix/conp…
JavaZeroo Oct 26, 2026
ef99b16
Merge commit '5fdc81bcbfaacd770232ca3c66ab1abdbd5e0c0f' into fix/conp…
JavaZeroo Oct 26, 2026
af563ba
Merge remote-tracking branch 'origin/main' into fix/conpty-backend-r47
JavaZeroo Oct 26, 2026
aa5fbe5
fix: isolate real application capture fixtures per run
JavaZeroo Oct 26, 2026
12bce48
test(shell): fence real writer ownership without assuming host input …
JavaZeroo Oct 26, 2026
e039bbc
docs: record native Vim fixture isolation and remaining GUI failure
JavaZeroo Oct 26, 2026
519a3f3
test(shell): exercise queue cancellation and concurrent stop on held …
JavaZeroo Oct 26, 2026
108be2d
docs: bind capture isolation proof to complete real application result
JavaZeroo Oct 26, 2026
335460b
docs: preserve bounded GUI Vim diagnostic outcomes and identity gaps
JavaZeroo Oct 26, 2026
5032975
docs: keep native failure process identity in private evidence
JavaZeroo Oct 26, 2026
b699c43
docs: record real sender ownership and stop validation boundaries
JavaZeroo Oct 26, 2026
28ddc8e
Merge pull request #70 from JavaZeroo/fix/vim-events-r52
JavaZeroo Oct 26, 2026
20900b3
Merge pull request #71 from JavaZeroo/fix/sender-fence-r62
JavaZeroo Oct 26, 2026
8108604
Merge remote-tracking branch 'origin/main' into fix/conpty-backend-r47
JavaZeroo Oct 26, 2026
abe5a85
Merge commit '163d8b8ae58496cc5f9c6e5fb0a04bed8da5b68b' into fix/ui-p…
JavaZeroo Oct 26, 2026
62226af
fix: bind UI paste sender fence before admission (#53)
JavaZeroo Oct 26, 2026
a15eb7f
test: distinguish paste wake cause and verify control pipe bounds
JavaZeroo Oct 26, 2026
9ab85b7
docs: retain UI paste progress and eight-session failures (#53)
JavaZeroo Oct 26, 2026
8ff112e
docs: record prepared Vim stage59 regression separately
JavaZeroo Oct 26, 2026
06bf6b5
perf: reuse row keys during resize replay reconciliation (#53)
JavaZeroo Oct 26, 2026
eae4b6a
fix: stop terminal replies while closing input (#53)
JavaZeroo Oct 26, 2026
848cb0e
docs: record original eight-session repair and remaining regressions …
JavaZeroo Oct 26, 2026
4daf992
fix: recognize empty record redraw before persistence output (#72)
JavaZeroo Oct 26, 2026
188228e
docs: record empty-record CR cause and configuration-specific validat…
JavaZeroo Oct 26, 2026
f199481
Merge pull request #78 from JavaZeroo/fix/persistence-empty-cr-r72
JavaZeroo Oct 26, 2026
97ac142
Merge pull request #77 from JavaZeroo/fix/candidate-replay-cost-r53
JavaZeroo Oct 26, 2026
a5fdd05
ci: retain bounded hosted shell command observations (#81)
JavaZeroo Oct 26, 2026
887c769
Merge pull request #84 from JavaZeroo/diagnose/experimental-preflight…
JavaZeroo Oct 26, 2026
e0b4d67
Merge pull request #76 from JavaZeroo/fix/ui-paste-fence-r53
JavaZeroo Oct 26, 2026
57f24f5
fix: preserve native viewport coordinates during candidate resize
JavaZeroo Oct 26, 2026
f40d347
test: retain independent native probe cleanup evidence
JavaZeroo Oct 26, 2026
92eac12
fix: distinguish native reflow padding from written spaces
JavaZeroo Oct 26, 2026
ab360c7
docs: record reviewed native resize evidence and remaining failures
JavaZeroo Oct 26, 2026
341b4c2
test: keep wrapped command echo separate from restore output
JavaZeroo Oct 26, 2026
259e036
test: align candidate identity gate with native resize patch
JavaZeroo Oct 26, 2026
c93db58
Merge branch 'diagnose/resize-native-r51' into fix/workspace-echo-cr-r88
JavaZeroo Oct 26, 2026
2d69663
Merge pull request #89 from JavaZeroo/diagnose/resize-native-r51
JavaZeroo Oct 26, 2026
f2ea8d2
docs: record reviewed workspace echo completion evidence
JavaZeroo Oct 26, 2026
6b365b3
Merge pull request #90 from JavaZeroo/fix/workspace-echo-cr-r88
JavaZeroo Oct 26, 2026
51ad19d
test: wait for a complete consumer row at replacement checkpoints
JavaZeroo Oct 26, 2026
f89b0ac
test: hold bounded record checkpoints during workflow output
JavaZeroo Oct 26, 2026
c662011
test: reject output checkpoints after window close
JavaZeroo Oct 26, 2026
3a0561c
docs: record reviewed workflow checkpoint evidence and CI coverage
JavaZeroo Oct 26, 2026
44ea45b
Merge pull request #91 from JavaZeroo/diagnose/workflow-checkpoint-r87
JavaZeroo Oct 26, 2026
c498a4e
研究:定位 Vim resize 后 MSYS 输入丢失边界 #52
JavaZeroo Oct 26, 2026
d6b3f79
文档:分列诊断停止规则与实际结果 #52
JavaZeroo Oct 26, 2026
dd53387
Merge pull request #92 from JavaZeroo/diagnose/vim-input-frida-r52
JavaZeroo Oct 26, 2026
ba9e7bd
验证:闭合工作区原生 viewport 残尾回归 #63
JavaZeroo Oct 26, 2026
ed55a87
Merge pull request #93 from JavaZeroo/diagnose/workspace-size-r63
JavaZeroo Oct 27, 2026
27bea78
research: validate isolated MSYS resize prefix prototype
JavaZeroo Oct 27, 2026
b60cd65
Merge pull request #94 from JavaZeroo/diagnose/msys-runtime-r52
JavaZeroo Oct 27, 2026
fa74143
research: 记录固定 WindTerm Vim 与原生尺寸模式对照
JavaZeroo Oct 27, 2026
3adec0b
Merge pull request #95 from JavaZeroo/research/windterm-vim-r52
JavaZeroo Oct 27, 2026
b9ce4dc
research: build the pinned ConPTY margin candidate on a disposable ho…
JavaZeroo Oct 27, 2026
4d5ade7
fix: preserve pinned patch bytes on Windows checkout
JavaZeroo Oct 27, 2026
ec66be1
fix: retain historical port objects for the pinned vcpkg manifest
JavaZeroo Oct 27, 2026
b56058e
fix: honor solution prerequisites before direct upstream project builds
JavaZeroo Oct 27, 2026
5c073e4
research: preserve same-source native baseline and verified adapter e…
JavaZeroo Oct 27, 2026
678804f
research: verify same-source ConPTY native margin repair
JavaZeroo Oct 27, 2026
19fcb6e
diag(shell): record bounded [DEBUG-r99] clipboard scenario stages ref…
JavaZeroo Nov 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
*.py text eol=lf
*.ps1 text eol=crlf
experiments/core/fixtures/*.bin binary
# Preserve upstream license bytes and unified-diff context prefixes.
research/msys-runtime-window-prefix/CYGWIN_LICENSE whitespace=-blank-at-eol,-blank-at-eof
research/msys-runtime-window-prefix/window-prefix.patch whitespace=-blank-at-eol,-space-before-tab
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ jobs:
- name: Test
env:
TERMFORGE_REQUIRE_SYSTEM_CLIPBOARD: ${{ runner.os == 'Windows' && '1' || '0' }}
# [DEBUG-r99] opt-in stage logging for issue #99 bounded observation;
# consumed only by the ui-clipboard-system scenario debug logger.
TERMFORGE_DEBUG_R99: '1'
run: ctest --test-dir build -C Release --output-on-failure --output-junit test-results.xml
- name: Preserve clipboard and window integration evidence
if: always() && runner.os == 'Windows'
Expand Down
78 changes: 78 additions & 0 deletions .github/workflows/conpty-upstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Fixed upstream ConPTY build experiment

on:
pull_request:
paths:
- '.github/workflows/conpty-upstream.yml'
- 'experiments/conpty/upstream/**'
workflow_dispatch:

permissions:
contents: read

jobs:
upstream:
runs-on: windows-2025
timeout-minutes: 45
env:
PYTHONUTF8: '1'
NUGET_CLI_LANGUAGE: en-us
VCPKG_DISABLE_METRICS: '1'
VCPKG_MAX_CONCURRENCY: '1'
steps:
- name: Preserve canonical source bytes in disposable checkouts
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: project
persist-credentials: false
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: microsoft/terminal
ref: dc8ae365847d41f62d1ebca93815bb00959bc12f
path: upstream
persist-credentials: false
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: microsoft/vcpkg
ref: 927f62e4b8838bd7e441e9c45103a16ffd75007e
fetch-depth: 0
path: vcpkg
persist-credentials: false
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
with:
python-version: '3.12'
- name: Test result rejection gates
working-directory: project
run: python -m unittest experiments.conpty.upstream.test_taef_result -v
- name: Build and test fixed upstream variants
shell: pwsh
run: >-
./project/experiments/conpty/upstream/build_hosted.ps1
-Source ./upstream -Vcpkg ./vcpkg -Out ./upstream-result
- name: Preserve source and test identity
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: conpty-upstream-summary
retention-days: 14
if-no-files-found: warn
path: upstream-result/public/
- name: Preserve experimental pair after adapter verification
if: success()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: conpty-upstream-experimental-pair
retention-days: 14
if-no-files-found: error
path: upstream-result/pair/
- name: Preserve same-source baseline for native comparison
if: success()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: conpty-upstream-baseline-pair
retention-days: 14
if-no-files-found: error
path: upstream-result/baseline-pair/
4 changes: 3 additions & 1 deletion .github/workflows/core-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ jobs:
- name: Build native measurement
run: cmake --build build --config Release --target core_measure
- name: Build and test candidate C++ adapter
run: cmake --build build --config Release --target candidate_core_test && ctest --test-dir build -C Release -R candidate_core --output-on-failure
run: cmake --build build --config Release --target candidate_core_test workflow_checkpoint_test && ctest --test-dir build -C Release -R "^(candidate_core|workflow_checkpoint)$" --no-tests=error --output-on-failure
- name: Verify resize trace and actual replay input rejection
run: cmake --build build --config Release --target candidate_resize_replay && ctest --test-dir build -C Release -R "^(resize_trace|candidate_resize_replay)$" --no-tests=error --output-on-failure
- name: Build and test candidate shell on Windows
if: runner.os == 'Windows'
run: cmake --build build --config Release --target shell_test_launcher && ctest --test-dir build -C Release -R candidate_shell_tui --output-on-failure
Expand Down
88 changes: 88 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ cmake_minimum_required(VERSION 3.20)
project(termforge_experiments VERSION 0.1.0 LANGUAGES CXX)

option(TERMFORGE_BUILD_CANDIDATE_ADAPTER "Build the Rust candidate C++ adapter checks" OFF)
option(TERMFORGE_BUILD_SOURCE_CONPTY_EXPERIMENT "Build isolated fixed-source ConPTY research probes" OFF)
set(TERMFORGE_CONPTY_BACKEND_DIR "" CACHE PATH "Explicit reviewed x64 ConPTY pair; empty uses the system API")
if(TERMFORGE_BUILD_SOURCE_CONPTY_EXPERIMENT AND (NOT WIN32 OR TERMFORGE_CONPTY_BACKEND_DIR))
message(FATAL_ERROR "Source ConPTY probes require Windows and a separate build without a product backend directory")
endif()
if(TERMFORGE_CONPTY_BACKEND_DIR AND NOT WIN32)
message(FATAL_ERROR "Side-by-side ConPTY is a Windows-only experiment")
endif()

if(WIN32)
include(cmake/ConptyBackend.cmake)
endif()

# Single-config generators use bin/, multi-config generators use bin/<config>/.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
Expand Down Expand Up @@ -69,6 +81,14 @@ if(TERMFORGE_BUILD_CANDIDATE_ADAPTER)
else()
target_link_libraries(candidate_core_test PRIVATE pthread dl m)
endif()
add_executable(candidate_resize_replay experiments/core/candidate_resize_replay.cpp experiments/core/candidate_terminal.cpp)
target_link_libraries(candidate_resize_replay PRIVATE termforge_core termforge_candidate_core)
termforge_warnings(candidate_resize_replay)
if(WIN32)
target_link_libraries(candidate_resize_replay PRIVATE ws2_32 userenv ntdll)
else()
target_link_libraries(candidate_resize_replay PRIVATE pthread dl m)
endif()
endif()

add_executable(resize_test experiments/core/resize_test.cpp)
Expand All @@ -89,6 +109,10 @@ termforge_warnings(search_test)

add_executable(paste_test experiments/shell/paste_test.cpp)
termforge_warnings(paste_test)
add_executable(sender_fence_test experiments/shell/sender_fence_test.cpp)
termforge_warnings(sender_fence_test)
find_package(Threads REQUIRED)
target_link_libraries(sender_fence_test PRIVATE Threads::Threads)
add_executable(clipboard_policy_test experiments/shell/clipboard_policy_test.cpp)
termforge_warnings(clipboard_policy_test)
add_executable(keyboard_test experiments/shell/keyboard_test.cpp)
Expand All @@ -111,6 +135,23 @@ if(WIN32)
termforge_warnings(conpty_margin_probe)
target_compile_definitions(conpty_margin_probe PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00)
target_link_libraries(conpty_margin_probe PRIVATE user32 bcrypt)
add_executable(conpty_backend_probe experiments/conpty/backend_probe.cpp)
termforge_warnings(conpty_backend_probe)
target_compile_definitions(conpty_backend_probe PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00)
if(TERMFORGE_BUILD_SOURCE_CONPTY_EXPERIMENT)
add_executable(conpty_source_margin_probe experiments/conpty/margin_probe.cpp)
add_executable(conpty_source_backend_probe experiments/conpty/backend_probe.cpp)
foreach(target conpty_source_margin_probe conpty_source_backend_probe)
termforge_warnings(${target})
target_compile_definitions(${target} PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00
TERMFORGE_CONPTY_SOURCE_EXPERIMENT=1)
target_link_libraries(${target} PRIVATE user32 bcrypt)
endforeach()
endif()
add_executable(conpty_resize_native_probe experiments/conpty/resize_native_probe.cpp)
termforge_warnings(conpty_resize_native_probe)
target_compile_definitions(conpty_resize_native_probe PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00)
target_link_libraries(conpty_resize_native_probe PRIVATE bcrypt)
add_executable(presentation_probe experiments/presentation/presentation.cpp)
termforge_warnings(presentation_probe)
target_compile_definitions(presentation_probe PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN UNICODE _UNICODE)
Expand Down Expand Up @@ -140,6 +181,9 @@ if(WIN32)
target_compile_definitions(shell_query_client PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN UNICODE _UNICODE)
add_dependencies(termforge_shell shell_query_client)
add_executable(shell_queue_probe experiments/shell/queue_probe.cpp)
add_executable(sender_fence_pipe_test experiments/shell/sender_fence_pipe_test.cpp)
termforge_warnings(sender_fence_pipe_test)
target_compile_definitions(sender_fence_pipe_test PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN)
add_executable(shell_size_client experiments/shell/size_client.cpp)
add_executable(shell_input_client experiments/shell/input_client.cpp)
add_executable(shell_text_client experiments/shell/text_client.cpp)
Expand Down Expand Up @@ -221,6 +265,16 @@ if(BUILD_TESTING)
add_test(NAME candidate_title COMMAND candidate_title_test)
set_tests_properties(candidate_title PROPERTIES TIMEOUT 35
ENVIRONMENT "TERMFORGE_TEST_ARTIFACTS=${PROJECT_BINARY_DIR}/test-artifacts")
if(TERMFORGE_CONPTY_BACKEND_DIR)
add_executable(candidate_reply_close_test experiments/shell/candidate_reply_close_test.cpp experiments/shell/shell_launch.cpp)
termforge_warnings(candidate_reply_close_test)
target_compile_definitions(candidate_reply_close_test PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN UNICODE _UNICODE)
target_link_libraries(candidate_reply_close_test PRIVATE termforge_core d2d1 dwrite gdi32 user32 imm32 ole32 oleaut32 uuid bcrypt)
termforge_candidate_shell(candidate_reply_close_test)
add_dependencies(candidate_reply_close_test termforge_shell_assets)
add_test(NAME candidate_reply_close COMMAND candidate_reply_close_test)
set_tests_properties(candidate_reply_close PROPERTIES TIMEOUT 30)
endif()
endif()
add_dependencies(runtime_observation_test termforge_shell_assets)
add_test(NAME runtime_observation COMMAND runtime_observation_test)
Expand Down Expand Up @@ -263,6 +317,13 @@ if(BUILD_TESTING)
add_executable(transport_completion_test experiments/shell/transport_completion_test.cpp)
termforge_warnings(transport_completion_test)
add_test(NAME transport_completion COMMAND transport_completion_test)
add_executable(workflow_checkpoint_test experiments/shell/workflow_checkpoint_test.cpp)
target_link_libraries(workflow_checkpoint_test PRIVATE termforge_core)
termforge_warnings(workflow_checkpoint_test)
if(TERMFORGE_BUILD_CANDIDATE_ADAPTER)
termforge_candidate_shell(workflow_checkpoint_test)
endif()
add_test(NAME workflow_checkpoint COMMAND workflow_checkpoint_test)
add_executable(scenario_tick_gate_test experiments/shell/scenario_tick_gate_test.cpp)
termforge_warnings(scenario_tick_gate_test)
add_test(NAME scenario_tick_gate COMMAND scenario_tick_gate_test)
Expand All @@ -274,6 +335,12 @@ if(BUILD_TESTING)
add_test(NAME selection_core COMMAND selection_test)
add_test(NAME search_core COMMAND search_test)
add_test(NAME paste COMMAND paste_test)
add_test(NAME sender_fence COMMAND sender_fence_test)
set_tests_properties(sender_fence PROPERTIES TIMEOUT 10)
if(WIN32)
add_test(NAME sender_fence_pipe COMMAND sender_fence_pipe_test)
set_tests_properties(sender_fence_pipe PROPERTIES TIMEOUT 10)
endif()
add_test(NAME clipboard_policy COMMAND clipboard_policy_test)
add_test(NAME keyboard COMMAND keyboard_test)
add_test(NAME text_action_policy COMMAND text_action_policy_test)
Expand All @@ -285,7 +352,15 @@ if(BUILD_TESTING)
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
TIMEOUT 180
ENVIRONMENT "TERMFORGE_BIN_DIR=$<TARGET_FILE_DIR:replay>;TERMFORGE_TRACE=$<TARGET_FILE:terminal_trace>;PYTHONUTF8=1")
if(TERMFORGE_CONPTY_BACKEND_DIR)
set_property(TEST ${name} APPEND PROPERTY ENVIRONMENT
"TERMFORGE_EXPECT_CONPTY_BACKEND=reviewed-side-by-side-1.25.260930003")
endif()
endfunction()
if(TERMFORGE_BUILD_CANDIDATE_ADAPTER)
termforge_add_python_test(candidate_resize_replay -m unittest experiments.core.test_candidate_resize_replay -v)
set_tests_properties(candidate_resize_replay PROPERTIES TIMEOUT 30)
endif()
if(TERMFORGE_BUILD_CANDIDATE_ADAPTER AND WIN32)
termforge_add_python_test(candidate_shell_tui -m unittest experiments.shell.test_candidate_tui -v)
set_tests_properties(candidate_shell_tui PROPERTIES TIMEOUT 120)
Expand All @@ -310,12 +385,15 @@ if(BUILD_TESTING)
termforge_add_python_test(workflow_system_runner -m unittest research.ime.test_workflow_system_runner -v)
set_tests_properties(workflow_system_runner PROPERTIES TIMEOUT 30)
termforge_add_python_test(copy_error_frame -m unittest experiments.shell.test_copy_error_frame -v)
termforge_add_python_test(paste_fence_evidence -m unittest experiments.shell.test_paste_checks -v)
termforge_add_python_test(resize_trace -m unittest experiments.shell.test_resize_trace -v)
if(WIN32)
termforge_add_python_test(research_guards -m unittest discover -s research/tests -v)
termforge_add_python_test(receive -m unittest experiments.receive.test_receive -v)
termforge_add_python_test(conpty -m unittest experiments.conpty.test_conpty -v)
termforge_add_python_test(conpty_ctrl_c -m unittest experiments.conpty.test_ctrl_c -v)
termforge_add_python_test(conpty_margin -m unittest experiments.conpty.test_margin_run -v)
termforge_add_python_test(conpty_backend -m unittest experiments.conpty.test_backend -v)
termforge_add_python_test(presentation -m unittest experiments.presentation.test_presentation -v)
termforge_add_python_test(shell -m unittest experiments.shell.test_shell -v)
termforge_add_python_test(selection_bytes -m unittest experiments.shell.test_selection_bytes -v)
Expand All @@ -327,3 +405,13 @@ if(BUILD_TESTING)
termforge_add_python_test(research_guards -m unittest research.tests.test_ui_probe research.tests.test_ui_typography research.tests.test_ui_r1 research.tests.test_ime_evidence -v)
endif()
endif()

if(WIN32)
foreach(target termforge_conpty_probe conpty_ctrl_c_probe conpty_margin_probe conpty_backend_probe real_app_capture
termforge_shell workflow_fixture_test shell_queue_probe shell_paste_probe
runtime_observation_test candidate_title_test candidate_reply_close_test raw_console_receiver_test)
if(TARGET ${target})
termforge_use_conpty_backend(${target})
endif()
endforeach()
endif()
46 changes: 46 additions & 0 deletions cmake/ConptyBackend.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Experimental, explicit side-by-side ConPTY selection. No downloads/fallback.
add_library(termforge_conpty_backend INTERFACE)
target_link_libraries(termforge_conpty_backend INTERFACE bcrypt)

if(TERMFORGE_CONPTY_BACKEND_DIR)
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
message(FATAL_ERROR "The reviewed ConPTY package is Windows x64 only")
endif()
if(NOT TERMFORGE_BUILD_CANDIDATE_ADAPTER)
message(FATAL_ERROR "Experimental side-by-side ConPTY requires TERMFORGE_BUILD_CANDIDATE_ADAPTER=ON")
endif()
if(NOT IS_ABSOLUTE "${TERMFORGE_CONPTY_BACKEND_DIR}")
message(FATAL_ERROR "TERMFORGE_CONPTY_BACKEND_DIR must be an absolute directory")
endif()
foreach(name conpty.dll OpenConsole.exe)
if(NOT EXISTS "${TERMFORGE_CONPTY_BACKEND_DIR}/${name}")
message(FATAL_ERROR "Reviewed ConPTY package is incomplete: ${name}")
endif()
file(SHA256 "${TERMFORGE_CONPTY_BACKEND_DIR}/${name}" actual)
if(name STREQUAL "conpty.dll")
set(expected "feeef341d891643c62d30b6b07800bc70f0bc148f44cb8c3bee84aa557ae805a")
else()
set(expected "3d66b23d0a71bb8eed2b77edc8b9df9bf54ce6c8fb74c863a30e760997f80586")
endif()
if(NOT actual STREQUAL expected)
message(FATAL_ERROR "Reviewed ConPTY identity mismatch: ${name}")
endif()
endforeach()
target_compile_definitions(termforge_conpty_backend INTERFACE TERMFORGE_CONPTY_SIDEBYSIDE=1)
add_custom_target(termforge_conpty_bundle
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:termforge_shell>/conpty-backend"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${TERMFORGE_CONPTY_BACKEND_DIR}/conpty.dll"
"${TERMFORGE_CONPTY_BACKEND_DIR}/OpenConsole.exe"
"${PROJECT_SOURCE_DIR}/third_party/conpty/manifest.json"
"${PROJECT_SOURCE_DIR}/third_party/conpty/LICENSE"
"$<TARGET_FILE_DIR:termforge_shell>/conpty-backend"
VERBATIM)
endif()

function(termforge_use_conpty_backend target)
target_link_libraries(${target} PRIVATE termforge_conpty_backend)
if(TERMFORGE_CONPTY_BACKEND_DIR)
add_dependencies(${target} termforge_conpty_bundle)
endif()
endfunction()
Loading
Loading