From d3bd8c526fce05d3d447e168e69dc6b41f021b6e Mon Sep 17 00:00:00 2001
From: Matthaeus Wolff <8714327+WolffM@users.noreply.github.com>
Date: Fri, 13 Mar 2026 14:53:59 -0700
Subject: [PATCH 1/3] Configure pipeline: copilot instructions, CI, and static
analysis
---
.github/copilot-instructions.md | 24 +++++++++++++++++++++++
.github/workflows/ci.yml | 8 ++++++++
.github/workflows/copilot-setup-steps.yml | 13 ++++++++++++
.github/workflows/static-analysis.yml | 22 +++++++++++++++++++++
4 files changed, 67 insertions(+)
create mode 100644 .github/copilot-instructions.md
create mode 100644 .github/workflows/ci.yml
create mode 100644 .github/workflows/copilot-setup-steps.yml
create mode 100644 .github/workflows/static-analysis.yml
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 00000000000..387aafe5a8d
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,24 @@
+# Copilot Coding Agent Instructions
+
+## Mandatory Workflow (MUST follow in order)
+
+### Phase 1: Reproduce (MUST complete before Phase 2)
+- Read the issue description and understand the problem.
+- Write a failing test or run the existing test suite to confirm the bug.
+- **Do NOT proceed to Phase 2 until you have a confirmed failure.**
+
+### Phase 2: Implement (MUST complete before Phase 3)
+- Make the minimal code change to fix the bug.
+- Do NOT refactor unrelated code or add features.
+
+### Phase 3: Verify (MUST complete before committing)
+- Re-run the specific test from Phase 1 and confirm it passes.
+- Run the full test suite to check for regressions.
+- **Do NOT commit until all tests pass.**
+
+## Rules
+- DO NOT reference, close, or link any external issues. No Closes, Fixes, or Resolves directives.
+- DO NOT use GitHub MCP tools to look up issues on other repositories.
+- DO NOT modify or weaken a test to make it pass.
+- DO NOT commit __pycache__/ directories. Add to .gitignore if missing.
+- Keep changes minimal and focused.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000000..9e1f9504a94
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,8 @@
+name: CI
+on: [push]
+jobs:
+ test:
+ runs-on: self-hosted
+ steps:
+ - uses: actions/checkout@v4
+ - run: echo 'No language-specific CI configured'
diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml
new file mode 100644
index 00000000000..04d1b51afeb
--- /dev/null
+++ b/.github/workflows/copilot-setup-steps.yml
@@ -0,0 +1,13 @@
+name: "Copilot Setup Steps"
+
+on:
+ workflow_dispatch:
+ push:
+ paths:
+ - .github/workflows/copilot-setup-steps.yml
+
+jobs:
+ copilot-setup-steps:
+ runs-on: self-hosted
+ steps:
+ - uses: actions/checkout@v4
diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml
new file mode 100644
index 00000000000..80fe1f71d5a
--- /dev/null
+++ b/.github/workflows/static-analysis.yml
@@ -0,0 +1,22 @@
+name: Static Analysis (Stage 4b)
+on:
+ workflow_dispatch:
+ inputs:
+ ref:
+ description: 'Branch or SHA to analyze'
+ required: true
+
+permissions:
+ contents: write
+ pull-requests: write
+ security-events: write
+
+jobs:
+ generic:
+ name: generic
+ runs-on: self-hosted
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ inputs.ref }}
+ - run: echo 'No language-specific static analysis configured'
From 7c488c7465424c591d9d4c65d412420c24c60e3c Mon Sep 17 00:00:00 2001
From: Matthaeus Wolff <8714327+WolffM@users.noreply.github.com>
Date: Fri, 13 Mar 2026 15:38:18 -0700
Subject: [PATCH 2/3] Switch copilot-setup-steps to github-hosted runners
(firewall enforcement)
---
.github/workflows/copilot-setup-steps.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml
index 04d1b51afeb..aed9f58c372 100644
--- a/.github/workflows/copilot-setup-steps.yml
+++ b/.github/workflows/copilot-setup-steps.yml
@@ -8,6 +8,6 @@ on:
jobs:
copilot-setup-steps:
- runs-on: self-hosted
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
From 62b4e82311be792d2071505fee88e9b69618fa3c Mon Sep 17 00:00:00 2001
From: Matthaeus Wolff <8714327+WolffM@users.noreply.github.com>
Date: Sat, 14 Mar 2026 13:09:27 +0000
Subject: [PATCH 3/3] closeTab: show confirmation dialog when tab has multiple
panes
---
.github/copilot-instructions.md | 24 -------------------
.github/workflows/ci.yml | 8 -------
.github/workflows/copilot-setup-steps.yml | 13 ----------
.github/workflows/static-analysis.yml | 22 -----------------
doc/cascadia/profiles.schema.json | 5 ++++
.../Resources/en-US/Resources.resw | 12 ++++++++++
src/cascadia/TerminalApp/TabManagement.cpp | 15 ++++++++++++
src/cascadia/TerminalApp/TerminalPage.cpp | 11 +++++++++
src/cascadia/TerminalApp/TerminalPage.h | 1 +
src/cascadia/TerminalApp/TerminalPage.xaml | 6 +++++
.../InteractionViewModel.h | 1 +
.../GlobalAppSettings.idl | 1 +
.../TerminalSettingsModel/MTSMSettings.h | 1 +
.../TerminalSettingsModel/defaults.json | 1 +
14 files changed, 54 insertions(+), 67 deletions(-)
delete mode 100644 .github/copilot-instructions.md
delete mode 100644 .github/workflows/ci.yml
delete mode 100644 .github/workflows/copilot-setup-steps.yml
delete mode 100644 .github/workflows/static-analysis.yml
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
deleted file mode 100644
index 387aafe5a8d..00000000000
--- a/.github/copilot-instructions.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copilot Coding Agent Instructions
-
-## Mandatory Workflow (MUST follow in order)
-
-### Phase 1: Reproduce (MUST complete before Phase 2)
-- Read the issue description and understand the problem.
-- Write a failing test or run the existing test suite to confirm the bug.
-- **Do NOT proceed to Phase 2 until you have a confirmed failure.**
-
-### Phase 2: Implement (MUST complete before Phase 3)
-- Make the minimal code change to fix the bug.
-- Do NOT refactor unrelated code or add features.
-
-### Phase 3: Verify (MUST complete before committing)
-- Re-run the specific test from Phase 1 and confirm it passes.
-- Run the full test suite to check for regressions.
-- **Do NOT commit until all tests pass.**
-
-## Rules
-- DO NOT reference, close, or link any external issues. No Closes, Fixes, or Resolves directives.
-- DO NOT use GitHub MCP tools to look up issues on other repositories.
-- DO NOT modify or weaken a test to make it pass.
-- DO NOT commit __pycache__/ directories. Add to .gitignore if missing.
-- Keep changes minimal and focused.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
deleted file mode 100644
index 9e1f9504a94..00000000000
--- a/.github/workflows/ci.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: CI
-on: [push]
-jobs:
- test:
- runs-on: self-hosted
- steps:
- - uses: actions/checkout@v4
- - run: echo 'No language-specific CI configured'
diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml
deleted file mode 100644
index aed9f58c372..00000000000
--- a/.github/workflows/copilot-setup-steps.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: "Copilot Setup Steps"
-
-on:
- workflow_dispatch:
- push:
- paths:
- - .github/workflows/copilot-setup-steps.yml
-
-jobs:
- copilot-setup-steps:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml
deleted file mode 100644
index 80fe1f71d5a..00000000000
--- a/.github/workflows/static-analysis.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-name: Static Analysis (Stage 4b)
-on:
- workflow_dispatch:
- inputs:
- ref:
- description: 'Branch or SHA to analyze'
- required: true
-
-permissions:
- contents: write
- pull-requests: write
- security-events: write
-
-jobs:
- generic:
- name: generic
- runs-on: self-hosted
- steps:
- - uses: actions/checkout@v4
- with:
- ref: ${{ inputs.ref }}
- - run: echo 'No language-specific static analysis configured'
diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json
index b8e6c9ab401..59fadf3e6ee 100644
--- a/doc/cascadia/profiles.schema.json
+++ b/doc/cascadia/profiles.schema.json
@@ -2658,6 +2658,11 @@
"description": "When set to \"true\" closing a window with multiple tabs open will require confirmation. When set to \"false\", the confirmation dialog will not appear.",
"type": "boolean"
},
+ "warning.confirmCloseAllPanes": {
+ "default": true,
+ "description": "When set to \"true\" closing a tab with multiple panes open will require confirmation. When set to \"false\", the confirmation dialog will not appear.",
+ "type": "boolean"
+ },
"useTabSwitcher": {
"description": "[Deprecated] Replaced with the \"tabSwitcherMode\" setting.",
"default": true,
diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
index 81ca7d51f83..ece408ff174 100644
--- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
+++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
@@ -526,6 +526,18 @@
You are about to close a read-only terminal. Do you wish to continue?
+
+ Cancel
+
+
+ This tab has multiple panes. Do you want to close all of them?
+
+
+ Close tab
+
+
+ Warning
+
Cancel
diff --git a/src/cascadia/TerminalApp/TabManagement.cpp b/src/cascadia/TerminalApp/TabManagement.cpp
index 21e31fb6dd3..5b7cc82cc63 100644
--- a/src/cascadia/TerminalApp/TabManagement.cpp
+++ b/src/cascadia/TerminalApp/TabManagement.cpp
@@ -414,6 +414,21 @@ namespace winrt::TerminalApp::implementation
}
auto t = winrt::get_self(tab);
+ if (t->GetLeafPaneCount() > 1 && _settings.GlobalSettings().ConfirmCloseAllPanes())
+ {
+ const auto weak = get_weak();
+
+ auto warningResult = co_await _ShowCloseTabWarningDialog();
+
+ strong = weak.get();
+
+ // If the user didn't explicitly click on close tab - leave
+ if (!strong || warningResult != ContentDialogResult::Primary)
+ {
+ co_return;
+ }
+ }
+
auto actions = t->BuildStartupActions(BuildStartupKind::None);
_AddPreviouslyClosedPaneOrTab(std::move(actions));
diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp
index e98de6b9957..2f5ee298a43 100644
--- a/src/cascadia/TerminalApp/TerminalPage.cpp
+++ b/src/cascadia/TerminalApp/TerminalPage.cpp
@@ -913,6 +913,17 @@ namespace winrt::TerminalApp::implementation
return _ShowDialogHelper(L"CloseReadOnlyDialog");
}
+ // Method Description:
+ // - Displays a dialog to warn the user that they are about to close a tab with
+ // multiple panes open. Once the user clicks the "Close tab" button, close the tab.
+ // If "Cancel" is clicked, the dialog will close.
+ // - Only one dialog can be visible at a time. If another dialog is visible
+ // when this is called, nothing happens. See _ShowDialog for details
+ winrt::Windows::Foundation::IAsyncOperation TerminalPage::_ShowCloseTabWarningDialog()
+ {
+ return _ShowDialogHelper(L"CloseTabWarningDialog");
+ }
+
// Method Description:
// - Displays a dialog to warn the user about the fact that the text that
// they are trying to paste contains the "new line" character which can
diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h
index 4b48cc0e9d9..b9467af2a29 100644
--- a/src/cascadia/TerminalApp/TerminalPage.h
+++ b/src/cascadia/TerminalApp/TerminalPage.h
@@ -304,6 +304,7 @@ namespace winrt::TerminalApp::implementation
winrt::Windows::Foundation::IAsyncOperation _ShowQuitDialog();
winrt::Windows::Foundation::IAsyncOperation _ShowCloseWarningDialog();
winrt::Windows::Foundation::IAsyncOperation _ShowCloseReadOnlyDialog();
+ winrt::Windows::Foundation::IAsyncOperation _ShowCloseTabWarningDialog();
winrt::Windows::Foundation::IAsyncOperation _ShowMultiLinePasteWarningDialog();
winrt::Windows::Foundation::IAsyncOperation _ShowLargePasteWarningDialog();
diff --git a/src/cascadia/TerminalApp/TerminalPage.xaml b/src/cascadia/TerminalApp/TerminalPage.xaml
index 40e3b838c37..8b4fff94c64 100644
--- a/src/cascadia/TerminalApp/TerminalPage.xaml
+++ b/src/cascadia/TerminalApp/TerminalPage.xaml
@@ -104,6 +104,12 @@
x:Load="False"
DefaultButton="Close" />
+
+