Compare commits

..

1133 Commits

Author SHA1 Message Date
vanzue
0e2ca69947 restore change to make commit clean 2025-11-17 09:22:10 +08:00
vanzue
bdf92319da merge main 2025-11-17 09:18:49 +08:00
Jaylyn Barbee
c32bfa8c48 more jaylyn sign off 2025-11-12 16:40:20 -05:00
Jaylyn Barbee
fcac6ee941 jaylyn half way through checklist 2025-11-12 14:28:54 -05:00
Jaylyn Barbee
536aba7bbb updating link 2025-11-12 12:32:18 -05:00
Jaylyn Barbee
640a235cd2 moved new jaylyn checklist to new folder for 96 2025-11-12 12:31:01 -05:00
Jaylyn Barbee
00d580985d Jaylyn checklist 2025-11-12 12:29:24 -05:00
Jaylyn Barbee
4a3cc92382 Jaylyn checklist 2025-11-12 12:26:33 -05:00
Shawn Yuan
fb1886c2c3 Add files via upload 2025-11-12 11:42:25 +08:00
Jaylyn Barbee
0982821a82 Enhance tests checklist with Light Switch validations
Added validation checks for Light Switch module functionality including UI and service validations.
2025-11-11 09:06:39 -05:00
Leilei Zhang (from Dev Box)
fce5a05e61 fix 2025-11-11 16:55:55 +08:00
Leilei Zhang (from Dev Box)
d2537da103 add checklist 2025-11-11 16:11:39 +08:00
Leilei Zhang (from Dev Box)
f7a50de1f4 add tests checklist for dscv3 and sparse app 2025-11-10 12:51:35 +08:00
vanzue
1dd2ec27dc release check list 2025-11-06 17:24:00 +08:00
Zach Teutsch
c8a23a231e Update file locksmith checklist
Updated checklist items for File Locksmith and Hosts File Editor with completion status.
2025-10-08 10:56:45 -07:00
Zach Teutsch
bb1d9776bc Update checklist for file explorer add ons
Updated checklist items to indicate completion for various file preview tests.
2025-10-08 09:43:11 -07:00
Zach Teutsch
7605e8f560 Complete env variables checklist
Updated checklist items to reflect completion status for environment variable tests and profile management.
2025-10-08 09:25:49 -07:00
Zach Teutsch
4be145d345 Checklist for command not found
Updated checklist items to indicate completion for PowerShell and Command Not Found module installation steps.
2025-10-08 09:11:37 -07:00
Zach Teutsch
6154098e32 Update checklist for Command Palette testing 2025-10-07 17:22:39 -07:00
Jaylyn Barbee
9e8327fa60 Completed Mouse Jump testing 2025-10-06 15:14:22 -04:00
Jaylyn Barbee
784591a0a8 Workspaces testing 2025-10-06 15:10:04 -04:00
Jaylyn Barbee
8d14775e12 MWB testing done 2025-10-06 14:49:55 -04:00
Jaylyn Barbee
f22ac8ee4b First pass of manual sign off 2025-10-06 09:53:18 -04:00
Jaylyn Barbee
58d5c92863 fix for github style md 2025-09-29 11:02:38 -04:00
Jaylyn Barbee
2e6fb8f4db added new folder for .95 as well as cleared out release checklist 2025-09-29 11:01:26 -04:00
Jaylyn Barbee
628d584e33 Updates to my testing items
Always on top and Mouse pointer crosshairs
2025-08-29 14:01:20 -04:00
Jaylyn Barbee
0c3763365a Mark checklist items as completed in release notes
Tested what I can for now in Always on top
2025-08-29 13:27:47 -04:00
Gordon Lam
b11880342e Add testing checklist for PowerToys features - Gleb
Added a detailed checklist for testing various features of PowerToys, including Advanced Paste, Color Picker, Image Resizer, Keyboard Manager, New+, PowerRename, Screen Ruler, Text Extractor, and Quick Accent.
2025-08-28 11:48:44 +08:00
Gordon Lam
dc7ea58921 Create testing checklist for PowerToys features - Them3
Added a comprehensive checklist for testing various PowerToys features, including Telemetry, Advanced Paste, Color Picker, Image Resizer, Keyboard Manager, New+, PowerRename, Screen Ruler, Text Extractor, and Quick Accent.
2025-08-28 11:47:09 +08:00
Gordon Lam
00507a0af3 Create testing checklist for PowerToys features - Jaylyn
Added a comprehensive checklist for testing various features of PowerToys, including Telemetry, Always on Top, FancyZones, Workspaces, Mouse Without Borders, Mouse Utils, and ZoomIt.
2025-08-28 11:40:37 +08:00
Gordon Lam
3d1567cd07 Add testing checklist for PowerToys features - them2
Added a comprehensive checklist for testing various features and functionalities of PowerToys, including telemetry, FancyZones, and Mouse utilities.
2025-08-28 11:39:11 +08:00
Gordon Lam
a85e8e8fa2 Create testing checklist for PowerToys features for them1
Added a comprehensive checklist for testing various PowerToys features, including telemetry, command palette, environment variables, file explorer add-ons, file locksmith, hosts file editor, peek, PowerToys run, registry preview, and more.
2025-08-28 11:32:27 +08:00
Gordon Lam
b031b0195f Add testing checklist for PowerToys featuresor Zach
Added a comprehensive checklist for testing various features and functionalities in PowerToys, including telemetry, command palette, environment variables, file explorer add-ons, and more.
2025-08-28 11:30:51 +08:00
Shawn Yuan
5a8d35e76f Add files via upload 2025-08-28 08:40:45 +08:00
Yu Leng (from Dev Box)
5f9e4ef12c add test result 2025-08-27 14:20:23 +08:00
Leilei Zhang
d66f712c5d complete leilzh.checklist 2025-08-26 22:18:36 +08:00
Leilei Zhang
dd5dbf219e change folder 2025-08-26 16:39:01 +08:00
Leilei Zhang
689f055f67 Merge branch 'releaseChecklist' of https://github.com/microsoft/PowerToys into releaseChecklist 2025-08-26 16:37:46 +08:00
Leilei Zhang
94676fd31c add leilzh-checklist 2025-08-26 16:37:09 +08:00
Kai Tao
99256c73bb Create kai-checklist.md 2025-08-26 10:00:36 +08:00
Leilei Zhang
d16f605f0d update peek automation 2025-08-06 10:23:19 +08:00
Yu Leng (from Dev Box)
caf7b104dc add powertoys run 2025-08-05 15:53:02 +08:00
Yu Leng (from Dev Box)
6bf19485c1 add yu's test result 2025-08-05 15:49:20 +08:00
Kai Tao
a0ec2f471a Update ui-automation-cover-list.md 2025-08-05 15:40:29 +08:00
Yu Leng (from Dev Box)
47e90cc27f Update the UI test cover list 2025-08-05 15:35:15 +08:00
Shawn Yuan
14229092e1 Update ui-automation-cover-list.md 2025-08-05 15:30:17 +08:00
Shawn Yuan
9dbc355da8 Add files via upload 2025-08-05 15:18:43 +08:00
Kai Tao
9d6b5fae77 Update kai.md 2025-08-05 10:52:32 +08:00
Kai Tao
e7f6172e0b fancyzone testing 2025-08-04 13:46:16 +08:00
Kai Tao
560a36ccba Update tests-checklist-template.md 2025-08-04 08:47:31 +08:00
Kai Tao
95fde086cc Update tests-checklist-template-mouse-utils-section.md 2025-08-04 08:46:16 +08:00
Kai Tao
6760964e4e Delete doc/releases/0.93 directory 2025-08-04 08:31:24 +08:00
Kai Tao
8fd21a4862 Create kai.md 2025-08-04 08:30:32 +08:00
Kai Tao
11d872efa2 Create kai.md 2025-08-04 08:29:36 +08:00
Hao Liu
007e83baf9 Create tests-checklist-haoliuu.md 2025-06-30 13:39:44 +08:00
Mengyuan
22470d14fa Update mengyuan-checklist.md 2025-06-27 15:26:14 +08:00
Mengyuan
f39be85109 Update mengyuan-checklist.md 2025-06-27 15:25:41 +08:00
Peiyao Zhao (from Dev Box)
f75a926fd7 Merge branch 'releaseChecklist' of https://github.com/microsoft/PowerToys into releaseChecklist 2025-06-27 14:59:05 +08:00
Peiyao Zhao (from Dev Box)
812656d4d4 update peiyao-checklist 2025-06-27 14:53:45 +08:00
Mengyuan
42ed1a7aee Update mengyuan-checklist.md 2025-06-27 14:32:59 +08:00
Shawn Yuan
04a1ef4258 Update tests-checklist-Shawn.md 2025-06-27 13:54:27 +08:00
Mengyuan
f81ebe516b Add mengyuan-checklist 2025-06-27 12:33:27 +08:00
Leilei Zhang
b9719c19a8 update leilzh checklist 2025-06-27 10:05:17 +08:00
Yu Leng (from Dev Box)
7889e1a621 update 0.92 testing result 2025-06-26 13:28:44 +08:00
Leilei Zhang
b0f656433a Merge branch 'releaseChecklist' of https://github.com/microsoft/PowerToys into releaseChecklist 2025-06-26 12:52:22 +08:00
Leilei Zhang
f2dd2f092e update leilzh checklist 2025-06-26 12:51:30 +08:00
Kai Tao
2985b4bed4 Update kai-checklist.md 2025-06-26 09:58:44 +08:00
yaqingmi
9ee58209b7 Update yaqing-checklist.md
Update yaqing-checklist.md
2025-06-25 19:38:18 +08:00
yaqingmi
9e275134c7 Create yaqing-checklist.md
Create yaqing-checklist.md
2025-06-25 13:33:55 +08:00
Leilei Zhang
ce4585c9c1 add leilzh-checklist 2025-06-25 09:43:57 +08:00
Kai Tao
ad6d2686c1 Update kai-checklist.md 2025-06-24 19:21:57 +08:00
Kai Tao
13d3cb3539 Update kai-checklist.md 2025-06-24 18:44:48 +08:00
Kai Tao
de3f3f6af8 Update kai-checklist.md 2025-06-24 16:26:26 +08:00
Kai Tao
a1c6d0c22e Update kai-checklist.md 2025-06-24 16:24:47 +08:00
Kai Tao
23360e9652 Update kai-checklist.md 2025-06-24 16:13:46 +08:00
Kai Tao
1a2d8869cd update crop & lock & always on top 2025-06-24 15:06:36 +08:00
Kai Tao
a3a646e3eb Finish testing for workspace 2025-06-24 14:28:21 +08:00
Kai Tao
f77d450c6d Update tests-checklist-template.md 2025-06-24 13:57:51 +08:00
Kai Tao
71f4c42790 Update kai-checklist.md 2025-06-24 13:56:00 +08:00
Kai Tao
1100975dbc Update tests-checklist-template.md 2025-06-24 13:51:08 +08:00
Kai Tao
543f97eb24 Update kai-checklist.md 2025-06-24 13:47:54 +08:00
Shawn Yuan
2a916787d0 Add files via upload 2025-06-24 10:19:08 +08:00
Kai Tao
c7fe0b9839 Update tests-checklist-template.md 2025-06-23 15:34:59 +08:00
Kai Tao
39838ce00f Create kai-checklist.md 2025-06-23 15:29:44 +08:00
XiaofengWang
0c99d4a17e Add ui automation cover list (#40096)
Add ui automation cover list

Co-authored-by: Xiaofeng Wang (from Dev Box) <xiaofengwang@microsoft.com>
2025-06-18 14:48:30 +08:00
Zhaopeng Wang
148ee3ff96 add 0.91.0 release check 2025-05-14 17:55:19 +08:00
Xiaofeng Wang (from Dev Box)
7e46960d38 Update tests-checklist-xiaofengwang.md 2025-05-14 16:18:36 +08:00
Hao Liu
eccc10bd71 Update tests-checklist-haoliuu.md 2025-05-14 16:08:05 +08:00
Yu Leng (from Dev Box)
7f7825a245 add yuleng's testing result for cmdpal 2025-05-08 18:58:42 +08:00
Kai Tao
ca555a0fc2 Update tests-checklist-kai.md 2025-05-08 15:04:13 +08:00
Kai Tao
6bb0f0b84b Update tests-checklist-kai.md 2025-05-08 13:47:53 +08:00
Hao Liu
775e0d7b54 Update tests-checklist-haoliuu.md 2025-05-06 15:33:39 +08:00
XiaofengWang
c2b9c9284f Create tests-checklist-xiaofeng.md 2025-04-30 20:32:57 +08:00
yaqingmi
ce4ac2ad46 Update tests-checklists-yaqing.md
Update tests-checklists-yaqing.md
2025-04-30 17:26:41 +08:00
Mengyuan
4d0df63574 Update tests-checklist-mengyuan.md 2025-04-30 13:25:03 +08:00
Leilei Zhang
55303028a7 Merge branch 'releaseChecklist' of https://github.com/microsoft/PowerToys into releaseChecklist 2025-04-30 11:20:24 +08:00
Leilei Zhang
fc0291a115 add tests-checklist-leilzh 2025-04-30 11:19:44 +08:00
Mengyuan Chen (from Dev Box)
95d6af8be4 Update tests-checklist-mengyuan.md 2025-04-30 10:32:36 +08:00
Hao Liu
37361baac6 Update tests-checklist-haoliuu.md 2025-04-29 17:54:21 +08:00
Kai Tao
56626b240f Update tests-checklist-kai.md 2025-04-29 16:30:23 +08:00
Yu Leng (from Dev Box)
161ea58236 add yuleng test result 2025-04-29 14:25:13 +08:00
Shawn Yuan
0cd8269e25 Add files via upload 2025-04-29 13:54:36 +08:00
Hao Liu
7e494db6b6 Update tests-checklist-haoliuu.md 2025-04-29 10:56:14 +08:00
Kai Tao
e02f479fe6 Create tests-checklist-kai.md 2025-04-29 10:06:34 +08:00
Hao Liu
f9ec916810 Update tests-checklist-haoliuu.md 2025-04-28 16:55:48 +08:00
Peiyao Zhao (from Dev Box)
9a8520a9cc update test list 2025-04-28 14:02:11 +08:00
Peiyao Zhao (from Dev Box)
019b64dc5c Create tests-checklist-peiyao.md 2025-04-28 13:30:01 +08:00
Hao Liu
1a0c359b97 Update tests-checklist-haoliuu.md 2025-04-28 10:29:50 +08:00
yaqingmi
fcfaa0ecca Create tests-checklists-yaqing.md
Create tests-checklists-yaqing.md
2025-04-27 12:41:10 +08:00
Hao Liu
e7c586a56f Create tests-checklist-haoliuu.md 2025-04-27 11:23:25 +08:00
yaqingmi
57316043db Copy new tests-checklist-template.md
Copy new tests-checklist-template.md
2025-04-25 19:00:50 +08:00
Peiyao Zhao (from Dev Box)
da772358e8 update installer test step for pstool 2025-04-22 10:55:22 +08:00
Jerry Xu
1f3898e67e Breakdown check-list per section for UI-Automation converting tasks 2025-03-28 15:20:12 -07:00
Jerry Xu
caece16873 Create tests-checklist-template-fancyzones-section.md 2025-03-28 13:06:56 -07:00
Jerry Xu
8589b7536f Update tests-checklist-template.md to include PowerToys Run section hyper link 2025-03-28 13:00:55 -07:00
Jerry Xu
85963715f1 Create tests-checklist-template-runner-section.md 2025-03-28 12:58:05 -07:00
Jerry Xu
67ce8a415a Create tests-checklist-template-installer-section.md 2025-03-28 12:50:13 -07:00
Peiyao Zhao (from Dev Box)
e3a6fb809c update results 2025-03-28 11:23:19 +08:00
Xiaofeng Wang
fdbb52222c Update tests-checklist-xiaofeng.md 2025-03-27 09:29:10 +08:00
Hao Liu
f26c1d40d4 update tests-checklist-haoliuu.md 2025-03-26 17:09:20 +08:00
Xiaofeng Wang (from Dev Box)
cb552699d1 Update tests-checklist-xiaofeng.md 2025-03-26 16:19:54 +08:00
Xiaofeng Wang (from Dev Box)
e995e0b453 Update tests-checklist-xiaofeng.md 2025-03-26 15:54:58 +08:00
Xiaofeng Wang (from Dev Box)
c0cc53880b Merge branch 'releaseChecklist' of https://github.com/microsoft/PowerToys into releaseChecklist 2025-03-26 15:53:18 +08:00
Xiaofeng Wang (from Dev Box)
b5ad8bae9c Update test-checklist-xiaofeng.md 2025-03-26 15:52:50 +08:00
Peiyao Zhao (from Dev Box)
0b71d6fad6 update test results 2025-03-26 14:25:17 +08:00
Peiyao Zhao (from Dev Box)
c32e12e90a update test results 2025-03-26 14:22:19 +08:00
Peiyao Zhao (from Dev Box)
dcb99989e1 update test results 2025-03-25 20:46:20 +08:00
yaqingmi
42f899afaa Delete doc/releases/0.90.0/tests-checklist-yaqing.md 2025-03-25 19:44:49 +08:00
yaqingmi
a0dd09d758 Update tests-checklist-yaqing.md 2025-03-25 19:44:12 +08:00
yaqingmi
d80a20673d Add checklist for yaqing
Add checklist for yaqing
2025-03-25 19:43:22 +08:00
Kai Tao
468462db67 Update tests-check-list-kai.md 2025-03-25 18:15:17 +08:00
Kai Tao
8e0e891bc3 Update tests-check-list-kai.md 2025-03-25 18:11:43 +08:00
Zhaopeng Wang (from Dev Box)
4d6300442a finish test check list 2025-03-25 17:04:31 +08:00
Leilei Zhang
cb0359c7fd Merge branch 'releaseChecklist' of https://github.com/microsoft/PowerToys into releaseChecklist 2025-03-25 16:57:11 +08:00
Leilei Zhang
6e1b5c3a34 update tests-checklist-leilzh.md 2025-03-25 16:56:35 +08:00
Yu Leng (from Dev Box)
41664af97b update test result 2025-03-25 14:28:01 +08:00
Shuai Yuan
0105815166 Update tests-checklist-shawn.md 2025-03-25 14:09:42 +08:00
Peiyao Zhao (from Dev Box)
f092553005 update test results 2025-03-25 13:58:35 +08:00
chenmy77
3810c52956 Update test-checklist-mengyuan.md 2025-03-25 11:17:36 +08:00
Xiaofeng Wang
bdbed989ea Update tests-checklist-xiaofeng.md 2025-03-25 10:44:47 +08:00
Xiaofeng Wang
7d03e24ed6 Update tests-checklist-xiaofeng.md 2025-03-25 10:13:04 +08:00
Peiyao Zhao (from Dev Box)
77198891fe update checklist 2025-03-24 22:29:49 +08:00
Seraphima Zykova
c44f2f036f Updated FZ tests 2025-03-24 15:04:35 +01:00
Leilei Zhang
e18d2cc094 update tests-checklist-leilzh.md 2025-03-24 21:34:35 +08:00
Leilei Zhang
36a11295b6 update tests-checklist-leilzh.md 2025-03-24 21:33:34 +08:00
Hao Liu
b0912779a7 update tests-checklist-haoliuu.md 2025-03-24 16:34:56 +08:00
Peiyao Zhao (from Dev Box)
cadbcde351 update test results 2025-03-24 16:28:47 +08:00
Seraphima Zykova
b90b860d7f Update FZ tests: removed "Allow popup windows snapping" tests 2025-03-24 09:05:48 +01:00
Kai Tao
a1d001a748 Update tests-check-list-kai.md 2025-03-24 15:07:54 +08:00
Peiyao Zhao (from Dev Box)
4b0c8d2bb6 update test results 2025-03-24 15:04:56 +08:00
Yu Leng (from Dev Box)
a6daf226de update test result 2025-03-24 14:00:14 +08:00
Yu Leng (from Dev Box)
a5d7aca2a2 update test result 2025-03-24 14:00:14 +08:00
Kai Tao
50eb98142a Update tests-check-list-kai.md 2025-03-24 12:50:52 +08:00
Kai Tao
3047416be5 Update tests-check-list-kai.md 2025-03-24 11:21:24 +08:00
Leilei Zhang
d7ed0db164 update tests-checklist-leilzh.md 2025-03-24 11:15:31 +08:00
Shuai Yuan
fcf0382075 Update tests-checklist-shawn.md 2025-03-24 09:11:35 +08:00
Shuai Yuan
cf005d5cd9 Update tests-checklist-shawn.md 2025-03-24 09:00:01 +08:00
Xiaofeng Wang
46aba3f9ac Update tests-checklist-xiaofeng.md 2025-03-22 08:58:14 +08:00
Leilei Zhang
1a987ea95a update tests-checklist-leilzh.md 2025-03-21 22:33:09 +08:00
Zhaopeng Wang
410401d272 rge branch 'releaseChecklist' of https://github.com/microsoft/PowerToys into releaseChecklis 2025-03-21 20:19:42 +08:00
Zhaopeng Wang
98b4bcc8c1 update checklist markdown 2025-03-21 20:19:27 +08:00
Kai Tao
c7cfac6ff0 Update tests-check-list-kai.md 2025-03-21 18:39:49 +08:00
Kai Tao
de082ab9f7 Update test cases 2025-03-21 18:37:04 +08:00
Hao Liu
d66184afdb update tests checklist 2025-03-21 17:24:47 +08:00
Kai Tao
654b5c44b0 Update tests-check-list-kai.md 2025-03-21 17:04:11 +08:00
Kai Tao
b3347f1af4 Rename check-list-kai.md to tests-check-list-kai.md 2025-03-21 15:20:38 +08:00
Yu Leng (from Dev Box)
8db5d5c2c4 update test result 2025-03-21 15:04:17 +08:00
chenmy77
621d174e73 Add test-checklist-mengyuan.md 2025-03-21 15:01:01 +08:00
Yu Leng (from Dev Box)
fbdc5fca51 update template 2025-03-21 14:23:34 +08:00
Yu Leng (from Dev Box)
8d3ba403ac update test 2025-03-21 14:22:37 +08:00
dreamstart
e256d2fae7 add tests-checklist-zhaopengwang.md
add tests-checklist-zhaopengwang.md
2025-03-21 14:06:37 +08:00
Hao Liu
7a302812e0 Add tests-checklist-haoliuu.md 2025-03-21 13:41:02 +08:00
Shuai Yuan
a0c8482f84 Add files via upload 2025-03-21 11:50:24 +08:00
Yu Leng (from Dev Box)
a5917a7298 Update test result 2025-03-21 11:37:20 +08:00
Yu Leng (from Dev Box)
dd1d774c41 Update test result 2025-03-21 11:32:39 +08:00
Jaime Bernardo
c8c7c351e2 Update tests-checklist-jaime.md 2025-03-20 21:49:57 +00:00
Seraphima Zykova
2b02b0526c Update tests-checklist-seraphima.md 2025-03-20 21:55:55 +01:00
Seraphima Zykova
298c75659b Update tests-checklist-seraphima.md 2025-03-20 17:56:52 +01:00
Jaime Bernardo
bbb9034265 Update tests-checklist-jaime.md 2025-03-20 16:47:46 +00:00
Jaime Bernardo
53930f1f75 Update tests-checklist-jaime.md 2025-03-20 16:37:09 +00:00
Jaime Bernardo
448637fb1a Update tests-checklist-jaime.md 2025-03-20 12:56:55 +00:00
Jaime Bernardo
e221d0becf Update tests-checklist-jaime.md 2025-03-20 12:48:53 +00:00
Jaime Bernardo
31d8b4e5c7 Update tests-checklist-jaime.md 2025-03-20 12:37:08 +00:00
Jaime Bernardo
7ad50eb175 Update tests-checklist-jaime.md 2025-03-20 12:26:23 +00:00
Jaime Bernardo
3215bbdd27 Update tests-checklist-jaime.md 2025-03-20 12:22:09 +00:00
Jaime Bernardo
a70bbeb9cf Update tests-checklist-jaime.md 2025-03-20 12:18:13 +00:00
Jaime Bernardo
cc532c9536 Update tests-checklist-jaime.md 2025-03-20 12:15:50 +00:00
Jaime Bernardo
59e34cfd95 Update tests-checklist-jaime.md 2025-03-20 12:12:46 +00:00
Leilei Zhang
71865d39e4 Merge branch 'releaseChecklist' of https://github.com/microsoft/PowerToys into releaseChecklist 2025-03-20 20:09:31 +08:00
Leilei Zhang
17f08fa7b1 create tests-checklist-leilzh.md 2025-03-20 20:05:43 +08:00
Jaime Bernardo
9e48a1e6be Update tests-checklist-jaime.md 2025-03-20 12:02:16 +00:00
Jaime Bernardo
fea55bed39 Update tests-checklist-jaime.md 2025-03-20 12:00:06 +00:00
Jaime Bernardo
65f8c52dc4 Update tests-checklist-jaime.md 2025-03-20 11:53:42 +00:00
Jaime Bernardo
212cdcc3f2 Update tests-checklist-jaime.md 2025-03-20 11:46:48 +00:00
Jaime Bernardo
b7815e1d1b Update tests-checklist-jaime.md 2025-03-20 11:30:12 +00:00
yaqingmi
ffc48fa38c Add checklist for modules by yaqing 2025-03-20 19:15:55 +08:00
Jaime Bernardo
e85cd8b12b Update tests-checklist-jaime.md 2025-03-20 11:14:06 +00:00
Jaime Bernardo
25c4ebaee4 Update tests-checklist-jaime.md 2025-03-20 10:59:11 +00:00
Jaime Bernardo
6571c977de Update tests-checklist-jaime.md 2025-03-20 10:42:32 +00:00
Peiyao Zhao (from Dev Box)
416286b6b1 Update test-checklist 2025-03-20 17:48:12 +08:00
Kai Tao
0703f6c5e9 Create check-list-kai.md 2025-03-20 17:37:59 +08:00
Yu Leng (from Dev Box)
0b3b9e8e94 Update cmdpal checklist template 2025-03-20 15:48:34 +08:00
Yu Leng (from Dev Box)
5428f18900 Add cmdpal test case 2025-03-20 15:46:51 +08:00
Peiyao Zhao (from Dev Box)
725730636b Update test-checklist 2025-03-20 15:42:29 +08:00
Peiyao Zhao (from Dev Box)
6d603da6cf Add test checklist for 0.90.0 2025-03-20 15:34:11 +08:00
Peiyao Zhao (from Dev Box)
50761e80fa Add test checklists for 0.90.0 2025-03-20 15:31:30 +08:00
Jaime Bernardo
82bb5947fd Add test checklists for 0.90.0 2025-03-19 22:59:15 +00:00
Jaime Bernardo
4d754f4816 Update test groups for 4 2025-03-19 22:41:33 +00:00
Zhaopeng Wang (from Dev Box)
fa17e8a83b create tests-checklist-zhaopengwang.md 2025-03-03 23:11:27 +08:00
yaqingmi
0241f9235a Create tests-checklist-yaqing.md 2025-02-28 22:05:41 +08:00
Mengyuan Chen (from Dev Box)
77def69df9 Update tests-checklist-mengyuan 2025-02-28 20:17:51 +08:00
Mengyuan Chen (from Dev Box)
e2b07e3058 Revert "Merge branch 'dev/mengyuanchen/addreleasechecklist' into releaseChecklist"
This reverts commit dea5763869, reversing
changes made to eb6fb14f0a.
2025-02-28 20:04:33 +08:00
Mengyuan Chen (from Dev Box)
dea5763869 Merge branch 'dev/mengyuanchen/addreleasechecklist' into releaseChecklist
add mengyuan release chaklist
2025-02-28 19:59:23 +08:00
Mengyuan Chen (from Dev Box)
ac10cb7a16 add mengyuan release cheklist 2025-02-28 19:50:46 +08:00
Hao Liu
eb6fb14f0a Update tests-checklist-haoliuu 2025-02-28 16:58:54 +08:00
Hao Liu
940060c307 Update tests-checklist-template 2025-02-28 16:52:00 +08:00
Mengyuan Chen (from Dev Box)
f833dee2f8 add 0.89 checklist of mengyuan 2025-02-28 16:28:30 +08:00
Leilei Zhang
28ecf3734e update checklist 2025-02-28 16:28:30 +08:00
Kai Tao
7f3e344ddc Update tests-checklist-kai.md 2025-02-28 16:19:44 +08:00
Shuai Yuan
c8caeb7e35 Update tests-checklist-shawn.md 2025-02-28 16:19:22 +08:00
Kai Tao
dbf804f76f Update tests-checklist-kai for 0.89.0.md 2025-02-28 16:09:47 +08:00
Hao Liu
d3ae8deab7 Add tests-checklist-haoliuu.md 2025-02-28 15:35:22 +08:00
urnotdfs
720228cd3b Add 0.89 test reuslts for screen ruler and shortcut guide (#37680)
Co-authored-by: Xiaofeng Wang (from Dev Box) <xiaofengwang@microsoft.com>
2025-02-28 15:20:12 +08:00
moooyo
a4c085daa2 Add 0.89.0 test results (#37678)
* Add 0.89 test results

* Update results

---------

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2025-02-28 13:03:20 +08:00
Kai Tao
789bb1dcb9 Update tests-checklist-kai.md 2025-02-28 12:31:35 +08:00
Kai Tao
51a922e78d Update workspaces result 2025-02-28 12:02:23 +08:00
Kai Tao
a188527aa6 Rename tests-checklist-kai to tests-checklist-kai.md 2025-02-28 10:36:51 +08:00
Shuai Yuan
a45ad73665 Add test result 2025-02-28 10:07:21 +08:00
Kai Tao
6ca2f21e7e Update tests-checklist-kai 2025-02-28 00:42:19 +08:00
Leilei Zhang
33ffd1f1e1 udpate tests-checklist-leilzh.md 2025-02-27 22:54:54 +08:00
Leilei Zhang
7025117d4e udpate tests-checklist-leilzh.md 2025-02-27 22:52:51 +08:00
Leilei Zhang
39bda8dc8d create and udpate tests-checklist-leilzh.md 2025-02-27 22:51:52 +08:00
Kai Tao
03e16dcad1 Create tests-checklist-kai 2025-02-27 19:45:56 +08:00
Jaime Bernardo
ca55f400c8 Update tests-checklist-jaime.md 2025-02-26 22:25:45 +00:00
Jaime Bernardo
baa6b43bde Update tests-checklist-jaime.md 2025-02-26 22:17:41 +00:00
Jaime Bernardo
292272fe74 Update tests-checklist-jaime.md 2025-02-26 21:48:52 +00:00
Jaime Bernardo
fa6a6595c5 Update tests-checklist-jaime.md 2025-02-26 21:32:57 +00:00
Jaime Bernardo
037dee7d25 Update tests-checklist-jaime.md 2025-02-26 21:31:32 +00:00
Jaime Bernardo
ec525fff37 Update tests-checklist-jaime.md 2025-02-26 21:18:53 +00:00
Jaime Bernardo
097cbd031f Update tests-checklist-jaime.md 2025-02-26 21:12:59 +00:00
Jaime Bernardo
977fe8f829 Update tests-checklist-jaime.md 2025-02-26 16:28:28 +00:00
Jaime Bernardo
8be33f544b Update tests-checklist-jaime.md 2025-02-26 16:21:36 +00:00
Jaime Bernardo
86931b3c33 Update tests-checklist-jaime.md 2025-02-26 15:57:31 +00:00
Jaime Bernardo
117a535893 Update tests-checklist-jaime.md 2025-02-26 15:51:16 +00:00
Jaime Bernardo
ca3b47de9b Update tests-checklist-jaime.md 2025-02-26 15:45:28 +00:00
Jaime Bernardo
cf26e9b715 Add test checklists for 0.89 2025-02-25 22:54:55 +00:00
Jaime Bernardo
a5844473ac Update test checklist for 6 2025-02-25 22:26:22 +00:00
Jaime Bernardo
07788990ee Update tests-checklist-jaime.md 2025-01-23 13:17:07 +00:00
Jaime Bernardo
9eabcd6b46 Update tests-checklist-jaime.md 2025-01-23 13:01:35 +00:00
Jaime Bernardo
c076e8432f Update tests-checklist-jaime.md 2025-01-23 12:30:18 +00:00
Jaime Bernardo
17ed3766da Update tests-checklist-jaime.md 2025-01-23 12:25:51 +00:00
Jaime Bernardo
283a939616 Update tests-checklist-jaime.md 2025-01-23 12:15:46 +00:00
Jaime Bernardo
70efb6d496 Update tests-checklist-jaime.md 2025-01-23 12:12:04 +00:00
Jaime Bernardo
8538cc9b5f Update tests-checklist-template.md 2025-01-23 11:56:55 +00:00
Jaime Bernardo
1e3d7618a2 Update tests-checklist-jaime.md 2025-01-23 11:53:45 +00:00
Jaime Bernardo
1927682966 Update tests-checklist-jaime.md 2025-01-23 11:52:27 +00:00
Jaime Bernardo
88791ecd90 Update tests-checklist-jaime.md 2025-01-23 11:39:38 +00:00
Jaime Bernardo
a2f066380f Update tests-checklist-jaime.md 2025-01-23 11:33:55 +00:00
Jaime Bernardo
8817a9ac30 Update tests-checklist-jaime.md 2025-01-23 11:28:30 +00:00
Jaime Bernardo
968f516c5a Update tests-checklist-jaime.md 2025-01-23 11:26:02 +00:00
Jaime Bernardo
0546cb8829 Update tests-checklist-jaime.md 2025-01-23 11:12:53 +00:00
Stefan Markovic
b9a41e328e All but FZ 2025-01-23 12:12:36 +01:00
Jaime Bernardo
88d7bce75a Update tests-checklist-jaime.md 2025-01-23 11:00:31 +00:00
Jaime Bernardo
2af85fc44d Update tests-checklist-jaime.md 2025-01-23 10:54:11 +00:00
Jaime Bernardo
1c4d33c45c Add test lists for 0.88 2025-01-22 15:33:46 +00:00
Jaime Bernardo
e5af0f31d6 Update test groups for 5 2025-01-22 15:15:45 +00:00
Jaime Bernardo
424167911e Add tests for ZoomIt 2025-01-22 15:11:47 +00:00
Stefan Markovic
7760e3a90a Update tests-checklist-stefan.md 2024-12-12 15:13:38 +01:00
Stefan Markovic
307eb0faa4 color picker 2024-12-12 15:02:59 +01:00
Jaime Bernardo
cb4f008466 Update tests-checklist-jaime.md 2024-12-12 14:02:31 +00:00
Stefan Markovic
c1ca9155d3 Update tests-checklist-stefan.md 2024-12-12 14:55:51 +01:00
Jaime Bernardo
2fa9c32ce6 Update tests-checklist-jaime.md 2024-12-12 13:43:16 +00:00
Jaime Bernardo
5142bc5168 Update tests-checklist-jaime.md 2024-12-12 11:59:25 +00:00
Jaime Bernardo
3b70461cfb Update tests-checklist-jaime.md 2024-12-12 11:37:49 +00:00
Jaime Bernardo
3266fff756 Update tests-checklist-jaime.md 2024-12-12 11:33:09 +00:00
Jaime Bernardo
a9da27ab9c Update tests-checklist-jaime.md 2024-12-12 11:19:10 +00:00
Jaime Bernardo
b2cf3c948b Update tests-checklist-jaime.md 2024-12-12 11:14:15 +00:00
Jaime Bernardo
c67958e717 Update tests-checklist-jaime.md 2024-12-12 11:03:18 +00:00
Jaime Bernardo
bd36460896 Update tests-checklist-jaime.md 2024-12-12 11:01:19 +00:00
Jaime Bernardo
249fb23994 Update tests-checklist-jaime.md 2024-12-12 10:57:03 +00:00
Jaime Bernardo
dfb2f5dfef Update tests-checklist-jaime.md 2024-12-12 10:54:15 +00:00
Jaime Bernardo
f350ba9879 Update tests-checklist-jaime.md 2024-12-12 10:50:26 +00:00
Jaime Bernardo
0cc4d92711 Update tests-checklist-jaime.md 2024-12-12 10:39:56 +00:00
Jaime Bernardo
46c485558e Update tests-checklist-jaime.md 2024-12-12 10:21:45 +00:00
Jaime Bernardo
4ee5fc6d93 Update tests-checklist-jaime.md 2024-12-12 10:14:16 +00:00
Jaime Bernardo
c4b4746c48 Test checklists for 0.87 2024-12-11 14:37:49 +00:00
Jaime Bernardo
7a07689ff6 Update test groups for 5 2024-12-11 13:38:54 +00:00
Jaime Bernardo
447ffb967a Update tests-checklist-jaime.md 2024-10-29 14:12:31 +00:00
Jaime Bernardo
cd5eb4d7a8 Update tests-checklist-jaime.md 2024-10-29 14:04:17 +00:00
Jaime Bernardo
8b7951cfdc Update tests-checklist-jaime.md 2024-10-29 13:46:05 +00:00
Jaime Bernardo
b1583252ae Update tests-checklist-jaime.md 2024-10-29 13:41:19 +00:00
Jaime Bernardo
4c2ad7db42 Update tests-checklist-jaime.md 2024-10-29 13:06:56 +00:00
Jaime Bernardo
11341e6286 Update tests-checklist-jaime.md 2024-10-29 13:01:05 +00:00
Jaime Bernardo
bde4d6c512 Update tests-checklist-jaime.md 2024-10-29 10:50:56 +00:00
Jaime Bernardo
bb908fd5d4 Update tests-checklist-jaime.md 2024-10-29 10:49:28 +00:00
Jaime Bernardo
d7dff73813 Update tests-checklist-jaime.md 2024-10-29 10:32:15 +00:00
Jaime Bernardo
2522928fae Update tests-checklist-jaime.md 2024-10-29 10:20:45 +00:00
Jaime Bernardo
f0124c606d Update tests-checklist-jaime.md 2024-10-29 10:17:04 +00:00
Jaime Bernardo
f367471f6a Update tests-checklist-jaime.md 2024-10-29 10:11:55 +00:00
Jaime Bernardo
8982eeaf52 Update tests-checklist-jaime.md 2024-10-29 09:58:59 +00:00
Jaime Bernardo
3ed97e1c48 Update tests-checklist-jaime.md 2024-10-29 09:43:53 +00:00
Jaime Bernardo
456ea5a130 Update tests-checklist-jaime.md 2024-10-29 09:36:23 +00:00
Stefan Markovic
b35b8b6f09 Update tests-checklist-stefan.md 2024-10-28 21:58:30 +01:00
Jaime Bernardo
b45b4088b7 Test checklists for 0.86.0 2024-10-28 15:51:30 +00:00
Jaime Bernardo
e6b058c26f Update test checklist for 5 2024-10-28 15:27:34 +00:00
Jaime Bernardo
6547d8ca91 Update tests-checklist-template.md 2024-10-28 15:17:47 +00:00
Jaime Bernardo
a6ddfaff61 Update tests-checklist-jaime.md 2024-09-30 11:24:34 +01:00
Jaime Bernardo
ff8065a61b Update tests-checklist-jaime.md 2024-09-30 11:18:32 +01:00
Jaime Bernardo
b5b09f322b Update tests-checklist-jaime.md 2024-09-30 11:14:36 +01:00
Jaime Bernardo
8aba69e628 Update tests-checklist-jaime.md 2024-09-30 10:51:11 +01:00
Jaime Bernardo
d5b8c791fa Update tests-checklist-jaime.md 2024-09-30 10:38:29 +01:00
Jaime Bernardo
f4eaee1c5a Update tests-checklist-jaime.md 2024-09-30 10:36:47 +01:00
Jaime Bernardo
96a51cd45f Update tests-checklist-jaime.md 2024-09-30 10:23:45 +01:00
Jaime Bernardo
a45688d744 Update tests-checklist-jaime.md 2024-09-30 10:05:27 +01:00
Jaime Bernardo
694598132f Update tests-checklist-jaime.md 2024-09-30 10:01:08 +01:00
Jaime Bernardo
1ec6a5ee91 Update tests-checklist-jaime.md 2024-09-30 09:49:50 +01:00
Jaime Bernardo
8a3c30a315 Update tests-checklist-jaime.md 2024-09-30 09:34:12 +01:00
Jaime Bernardo
bf96e2de12 Update tests-checklist-jaime.md 2024-09-30 09:25:58 +01:00
Jaime Bernardo
ad5733c7f9 Update tests-checklist-jaime.md 2024-09-30 09:23:35 +01:00
Jaime Bernardo
5ade9d6012 Add test checklists for 0.85 2024-09-27 16:24:16 +01:00
Jaime Bernardo
5db21606bc Add New+ to test groups for 6 2024-09-27 16:01:45 +01:00
Jaime Bernardo
395d2a5315 Add New+ tests 2024-09-27 15:59:52 +01:00
Jaime Bernardo
f5061be3e4 Update tests-checklist-jaime.md 2024-08-26 21:03:10 +01:00
Jaime Bernardo
dc4a4bdf92 Update tests-checklist-jaime.md 2024-08-26 20:43:46 +01:00
Jaime Bernardo
04868e1a46 Update tests-checklist-jaime.md 2024-08-26 20:39:20 +01:00
Jaime Bernardo
f1387ba06d Update tests-checklist-jaime.md 2024-08-26 20:25:35 +01:00
Jaime Bernardo
f17d5da56e Update tests-checklist-jaime.md 2024-08-26 20:23:22 +01:00
Jaime Bernardo
7239a60311 Update tests-checklist-jaime.md 2024-08-26 20:13:47 +01:00
Jaime Bernardo
a9b5015fc2 Update tests-checklist-jaime.md 2024-08-26 20:06:21 +01:00
Jaime Bernardo
694303eee8 Update tests-checklist-jaime.md 2024-08-26 20:01:54 +01:00
Jaime Bernardo
e09b694d86 Update tests-checklist-jaime.md 2024-08-26 19:53:34 +01:00
Jaime Bernardo
27c1ffd7da Update tests-checklist-jaime.md 2024-08-26 15:45:17 +01:00
Jaime Bernardo
1d4d563f93 Update tests-checklist-jaime.md 2024-08-26 14:22:33 +01:00
Jaime Bernardo
bf91684f38 Update tests-checklist-jaime.md 2024-08-26 13:58:51 +01:00
Jaime Bernardo
9c5b23e29d Update tests-checklist-jaime.md 2024-08-26 12:30:10 +01:00
Jaime Bernardo
19e1eb17a3 Update tests-checklist-jaime.md 2024-08-26 12:23:32 +01:00
Stefan Markovic
4d3f6032ba Update advanced paste checklist 2024-08-26 10:51:53 +02:00
Stefan Markovic
b75a0b4461 .84 test plan 2024-08-26 09:07:35 +02:00
Stefan Markovic
72ff20df24 minor styling 2024-08-21 23:09:25 +02:00
Seraphima Zykova
90e5eb5ac5 Added tests for Workspaces 2024-08-20 14:36:00 +02:00
Jaime Bernardo
b12fa3f007 Update tests-checklist-jaime.md 2024-07-29 16:06:12 +01:00
Jaime Bernardo
a9195c06db Update tests-checklist-jaime.md 2024-07-29 12:48:41 +01:00
Jaime Bernardo
4c34ac2993 Update tests-checklist-jaime.md 2024-07-29 12:40:17 +01:00
Jaime Bernardo
6c85e72edf Update tests-checklist-jaime.md 2024-07-29 12:26:43 +01:00
Jaime Bernardo
a6e1d9d6e1 Update tests-checklist-jaime.md 2024-07-29 12:14:46 +01:00
Jaime Bernardo
9377c4d53c Update tests-checklist-jaime.md 2024-07-29 12:00:55 +01:00
Jaime Bernardo
b2b018ef0a Update tests-checklist-jaime.md 2024-07-29 11:59:31 +01:00
Jaime Bernardo
1d7ecd3777 Update tests-checklist-jaime.md 2024-07-29 11:51:08 +01:00
Jaime Bernardo
f699d33038 Update tests-checklist-jaime.md 2024-07-29 11:47:40 +01:00
Jaime Bernardo
a1ef553aed Update tests-checklist-jaime.md 2024-07-29 11:43:38 +01:00
Jaime Bernardo
a096f10b10 Update tests-checklist-jaime.md 2024-07-29 11:40:43 +01:00
Jaime Bernardo
4f33b2fc29 Update tests-checklist-jaime.md 2024-07-29 11:29:42 +01:00
Jaime Bernardo
e42bfbb834 Update tests-checklist-jaime.md 2024-07-29 11:17:41 +01:00
Jaime Bernardo
dd440c1699 Update tests-checklist-jaime.md 2024-07-29 10:58:22 +01:00
Jaime Bernardo
c0b3517056 Test checklists for 0.83.0 2024-07-28 15:07:51 +01:00
Jaime Bernardo
9e58e328d1 Update test groups for 5 2024-07-28 14:50:38 +01:00
Jaime Bernardo
6e8665c016 Update tests-checklist-jaime.md 2024-06-26 13:22:29 +01:00
Jaime Bernardo
ef20eb14d3 Update tests-checklist-jaime.md 2024-06-26 13:18:50 +01:00
Jaime Bernardo
ad082c722f Update tests-checklist-jaime.md 2024-06-26 13:14:32 +01:00
Jaime Bernardo
e5f0f88f7f Update tests-checklist-jaime.md 2024-06-26 13:05:28 +01:00
Jaime Bernardo
0af5f449f7 Update tests-checklist-jaime.md 2024-06-26 12:46:20 +01:00
Jaime Bernardo
ad0ada8726 Update tests-checklist-jaime.md 2024-06-26 12:24:04 +01:00
Seraphima Zykova
061884b71b Update tests-checklist-seraphima.md 2024-06-26 13:09:23 +02:00
Jaime Bernardo
cdb3336c97 Update tests-checklist-jaime.md 2024-06-26 00:12:07 +01:00
Jaime Bernardo
729f98e24f Update tests-checklist-jaime.md 2024-06-26 00:07:44 +01:00
Jaime Bernardo
99ef48a830 Update tests-checklist-jaime.md 2024-06-26 00:04:45 +01:00
Jaime Bernardo
34d3e19481 Update tests-checklist-jaime.md 2024-06-25 23:51:58 +01:00
Jaime Bernardo
8773f1dd70 Update tests-checklist-jaime.md 2024-06-25 23:47:03 +01:00
Jaime Bernardo
2393711eb8 Update tests-checklist-jaime.md 2024-06-25 23:45:59 +01:00
Jaime Bernardo
60c3df2d95 Update tests-checklist-jaime.md 2024-06-25 23:42:07 +01:00
Jaime Bernardo
be3e033326 Update tests-checklist-jaime.md 2024-06-25 23:36:59 +01:00
Jaime Bernardo
162b361e4b Update tests-checklist-jaime.md 2024-06-25 23:27:49 +01:00
Jaime Bernardo
9682066cbf Update tests-checklist-jaime.md 2024-06-25 23:24:14 +01:00
Jaime Bernardo
2d5652acfe Update tests-checklist-jaime.md 2024-06-25 23:10:43 +01:00
Jaime Bernardo
7c670474eb Update tests-checklist-jaime.md 2024-06-25 23:02:15 +01:00
Jaime Bernardo
76acc3505e Update tests-checklist-jaime.md 2024-06-25 22:56:51 +01:00
Jaime Bernardo
d3217c1316 Redistribute Stefan's tests so he can focus on MRT 2024-06-25 22:17:41 +01:00
Seraphima Zykova
28e9a82018 Update tests-checklist-seraphima.md 2024-06-25 17:56:42 +02:00
Seraphima Zykova
a1c99ac579 Update tests-checklist-seraphima.md 2024-06-25 17:56:12 +02:00
Jaime Bernardo
88ccb711b7 Add checklists for 0.82.0 2024-06-25 10:40:20 +01:00
Jaime Bernardo
a51223c6f5 Update test groups for 6 2024-06-25 10:18:50 +01:00
Jaime Bernardo
42a90a0454 Add Advanced Paste to release checklist 2024-06-25 10:17:04 +01:00
Jaime Bernardo
a9f792fc6c Update tests-checklist-jaime.md 2024-05-15 11:52:17 +01:00
Jaime Bernardo
5547461219 Update tests-checklist-jaime.md 2024-05-15 11:37:32 +01:00
Stefan Markovic
e53f087bde General Settings 2024-05-15 12:36:10 +02:00
Jaime Bernardo
6229777a94 Update tests-checklist-jaime.md 2024-05-15 11:32:28 +01:00
Jaime Bernardo
1283872e09 Update tests-checklist-jaime.md 2024-05-15 11:18:16 +01:00
Jaime Bernardo
a2e21acc70 Update tests-checklist-jaime.md 2024-05-15 11:04:18 +01:00
Jaime Bernardo
7c9bef2fa1 Update tests-checklist-jaime.md 2024-05-15 10:48:43 +01:00
Stefan Markovic
d63d858a87 Quick accent, Paste plain 2024-05-15 11:44:08 +02:00
Jaime Bernardo
87439acd82 Update tests-checklist-jaime.md 2024-05-15 10:33:54 +01:00
Stefan Markovic
84d441bd3c Install, Functional, Localization 2024-05-15 11:28:50 +02:00
Jaime Bernardo
46fa44889c Update tests-checklist-jaime.md 2024-05-15 10:22:44 +01:00
Jaime Bernardo
6b34f4bfd7 Update tests-checklist-jaime.md 2024-05-15 10:11:40 +01:00
Jaime Bernardo
b76c511743 Update tests-checklist-jaime.md 2024-05-15 10:08:09 +01:00
Jaime Bernardo
b0eaf662d9 Release checklists for 0.81.0 2024-05-14 14:21:01 +01:00
Jaime Bernardo
b0e443bee1 Update tests-checklist-jaime.md 2024-04-03 00:25:19 +01:00
Jaime Bernardo
9c4b0131bc Update tests-checklist-jaime.md 2024-04-03 00:09:39 +01:00
Jaime Bernardo
55a32a6d0d Update tests-checklist-jaime.md 2024-04-02 17:11:22 +01:00
Jaime Bernardo
e055e51c37 Update tests-checklist-jaime.md 2024-04-02 15:50:51 +01:00
Jaime Bernardo
2744f5e3e9 Update tests-checklist-jaime.md 2024-04-02 15:49:52 +01:00
Jaime Bernardo
c4873ccf93 Update tests-checklist-jaime.md 2024-04-02 15:24:40 +01:00
Jaime Bernardo
b8e9c51850 Update tests-checklist-jaime.md 2024-04-02 15:21:32 +01:00
Jaime Bernardo
cc2c1933c4 Update tests-checklist-jaime.md 2024-04-02 15:19:08 +01:00
Jaime Bernardo
cabea993cb Update tests-checklist-jaime.md 2024-04-02 15:16:59 +01:00
Jaime Bernardo
ef51c6e72e Update tests-checklist-jaime.md 2024-04-02 15:11:00 +01:00
Jaime Bernardo
6bb02e25d1 Update tests-checklist-jaime.md 2024-04-02 15:06:23 +01:00
Jaime Bernardo
1502f7e605 Update tests-checklist-jaime.md 2024-04-02 14:57:12 +01:00
Jaime Bernardo
da2d4fb3c4 Update tests-checklist-jaime.md 2024-04-02 14:43:28 +01:00
Jaime Bernardo
f0e9011339 Update tests-checklist-jaime.md 2024-04-02 12:05:01 +01:00
Jaime Bernardo
d868a4e1ba Update tests-checklist-jaime.md 2024-04-02 11:52:05 +01:00
Stefan Markovic
de2a4a53af FE-add ons, Quick Accent, Text Extractor and Reg Preview 2024-04-02 12:41:15 +02:00
Stefan Markovic
e56bd4fe71 Install, loc, ColorPicker and FZ Editor 2024-04-02 12:03:50 +02:00
Jaime Bernardo
40b818ccc7 Test checklists for 0.80.0 2024-04-01 23:05:11 +01:00
Jaime Bernardo
711c7a77be Add DSC tests 2024-04-01 22:40:23 +01:00
Jaime Bernardo
dabbbbccb6 Update tests-checklist-jaime.md 2024-02-29 14:08:37 +00:00
Jaime Bernardo
5860ad38e8 Update tests-checklist-jaime.md 2024-02-29 14:05:22 +00:00
Jaime Bernardo
4e28e17ffc Update tests-checklist-jaime.md 2024-02-29 13:50:44 +00:00
Jaime Bernardo
f9ec7229ea Update tests-checklist-jaime.md 2024-02-29 13:34:53 +00:00
Jaime Bernardo
64c90ffbc5 Update tests-checklist-jaime.md 2024-02-29 13:18:49 +00:00
Jaime Bernardo
389b47b7d9 Update tests-checklist-jaime.md 2024-02-29 12:57:59 +00:00
Seraphima Zykova
24fa059250 Update tests-checklist-seraphima.md 2024-02-29 13:50:38 +01:00
Stefan Markovic
615999be7c Text Extractr 2024-02-29 13:01:00 +01:00
Jaime Bernardo
7db069fd46 Update tests-checklist-jaime.md 2024-02-29 11:54:33 +00:00
Jaime Bernardo
6e5729ce87 Update tests-checklist-jaime.md 2024-02-29 11:36:45 +00:00
Jaime Bernardo
91c49a1023 Update tests-checklist-jaime.md 2024-02-29 11:20:34 +00:00
Jaime Bernardo
edd30b7098 Update tests-checklist-jaime.md 2024-02-29 11:12:59 +00:00
Stefan Markovic
a88b100c12 RegistryPreview 2024-02-29 11:01:47 +01:00
Stefan Markovic
2f8d5734ae Peek 2024-02-29 10:51:10 +01:00
Stefan Markovic
1859603a18 Quick Accent 2024-02-29 10:42:49 +01:00
Stefan Markovic
bb174066d6 FE-Addons 2024-02-29 10:36:37 +01:00
Stefan Markovic
6c4515382f FZ Editor 2024-02-29 10:28:59 +01:00
Stefan Markovic
50c7aec2b8 ColorPicker 2024-02-29 10:18:48 +01:00
Jaime Bernardo
1e410c21b0 Add tests for 0.79 2024-02-27 22:20:42 +00:00
Seraphima Zykova
b3c4200a1c Update tests-checklist-seraphima.md 2024-01-29 18:02:47 +01:00
Jaime Bernardo
a9a9f39293 Update tests-checklist-jaime.md 2024-01-29 16:52:12 +00:00
Jaime Bernardo
094ac9a77e Update tests-checklist-jaime.md 2024-01-29 16:38:21 +00:00
Jaime Bernardo
0c8b4cdc62 Update tests-checklist-jaime.md 2024-01-29 16:27:34 +00:00
Jaime Bernardo
f328c99c82 Update tests-checklist-jaime.md 2024-01-29 16:26:00 +00:00
Jaime Bernardo
5df602e3f0 Update tests-checklist-jaime.md 2024-01-29 16:24:11 +00:00
Jaime Bernardo
036c9baf4d Update tests-checklist-jaime.md 2024-01-29 16:22:00 +00:00
Jaime Bernardo
c7a35c3b89 Update tests-checklist-jaime.md 2024-01-29 16:07:31 +00:00
Jaime Bernardo
809ff3621d Update tests-checklist-jaime.md 2024-01-29 16:04:56 +00:00
Jaime Bernardo
b2dcbc5beb Update tests-checklist-jaime.md 2024-01-29 15:56:52 +00:00
Jaime Bernardo
bcf5ed2db3 Update tests-checklist-jaime.md 2024-01-29 15:42:08 +00:00
Jaime Bernardo
860bd1b452 Update tests-checklist-jaime.md 2024-01-29 15:36:09 +00:00
Jaime Bernardo
760c7be191 Test checklists for .78 2024-01-29 10:25:47 +00:00
Jaime Bernardo
dcb40e5fbd Update test groups for 6 for .78 2024-01-29 10:08:34 +00:00
Stefan Markovic
681cc781c8 update CNF checklist 2024-01-05 12:17:40 +01:00
Jaime Bernardo
14e08aacbf Update tests-checklist-jaime.md 2024-01-04 14:29:53 +00:00
Stefan Markovic
8f5c465cd7 env var 2024-01-04 14:46:33 +01:00
Stefan Markovic
fd7de044a9 ruler 2024-01-04 14:37:38 +01:00
Stefan Markovic
3e94217681 peek 2024-01-04 14:29:45 +01:00
Jaime Bernardo
112fdb6530 Update tests-checklist-jaime.md 2024-01-04 13:29:26 +00:00
Stefan Markovic
21844aa770 Update tests-checklist-stefan.md 2024-01-04 14:26:48 +01:00
Stefan Markovic
7ad22ae95c KBM 2024-01-04 14:15:09 +01:00
Jaime Bernardo
75770abd47 Update tests-checklist-jaime.md 2024-01-04 13:01:51 +00:00
Stefan Markovic
fd8f298c94 Update tests-checklist-stefan.md 2024-01-04 13:30:40 +01:00
Stefan Markovic
adfe14d352 Image Resizer 2024-01-04 13:09:38 +01:00
Stefan Markovic
9dbf5cf009 Merge branch 'releaseChecklist' of https://github.com/microsoft/PowerToys into releaseChecklist 2024-01-04 12:54:59 +01:00
Stefan Markovic
0b9a76d114 Fix checklists and tested items 2024-01-04 12:53:58 +01:00
Jaime Bernardo
a6525c11ed Update tests-checklist-jaime.md 2024-01-04 11:25:52 +00:00
Stefan Markovic
8d243d4575 Install tests 2024-01-04 12:22:37 +01:00
Jaime Bernardo
8fe38e441b Update tests-checklist-jaime.md 2024-01-04 11:21:41 +00:00
Jaime Bernardo
eae86d794f Update tests-checklist-jaime.md 2024-01-04 11:15:06 +00:00
Jaime Bernardo
604b6c0b3c Update tests-checklist-jaime.md 2024-01-04 11:08:49 +00:00
Jaime Bernardo
27e8c01544 Update tests-checklist-jaime.md 2024-01-04 10:57:03 +00:00
Jaime Bernardo
0a2b102b8c Update tests-checklist-jaime.md 2024-01-04 10:38:18 +00:00
Jaime Bernardo
55643f36cb Update tests-checklist-jaime.md 2024-01-04 10:26:45 +00:00
Jaime Bernardo
d481cd3dd1 Update tests-checklist-jaime.md 2024-01-04 10:15:36 +00:00
Stefan Markovic
8188a01ae1 Update test plan for .77 2024-01-04 08:57:45 +01:00
Jaime Bernardo
0eded24122 Update tests-checklist-jaime.md 2023-11-30 15:55:47 +00:00
Jaime Bernardo
e73c60b5fa Update tests-checklist-jaime.md 2023-11-30 14:28:04 +00:00
Jaime Bernardo
08c0b0cd48 Update tests-checklist-jaime.md 2023-11-30 14:23:43 +00:00
Jaime Bernardo
93216bcc3e Update tests-checklist-jaime.md 2023-11-30 14:21:58 +00:00
Jaime Bernardo
22f5f62f93 Update tests-checklist-jaime.md 2023-11-30 14:17:38 +00:00
Jaime Bernardo
045e2e9756 Update tests-checklist-jaime.md 2023-11-30 14:00:19 +00:00
Seraphima Zykova
f6659dfadc Update tests-checklist-seraphima.md 2023-11-30 14:57:09 +01:00
Jaime Bernardo
860c0a1012 Update tests-checklist-jaime.md 2023-11-30 12:13:44 +00:00
Jaime Bernardo
da9912a09d Update tests-checklist-jaime.md 2023-11-30 12:10:19 +00:00
Jaime Bernardo
65488ed3e8 Update tests-checklist-jaime.md 2023-11-30 12:08:12 +00:00
Jaime Bernardo
5de4599c95 Update tests-checklist-jaime.md 2023-11-30 12:01:48 +00:00
Jaime Bernardo
1c1c421154 Update tests-checklist-jaime.md 2023-11-30 11:48:30 +00:00
Jaime Bernardo
3afaddeb96 Update tests-checklist-jaime.md 2023-11-30 11:39:02 +00:00
Stefan Markovic
8c10325ce7 Text extractor and Registry preview 2023-11-30 10:17:55 +01:00
Stefan Markovic
872b30f41a Quick accent and FE Add-ons 2023-11-30 01:18:32 +01:00
Stefan Markovic
a5569a62cd Update tests-checklist-stefan.md 2023-11-30 00:53:43 +01:00
Jaime Bernardo
c38ab5adc0 Test checklists for 0.76.0 2023-11-28 15:49:17 +00:00
Jaime Bernardo
2954b3b6ea Update tests-checklist-jaime.md 2023-10-30 08:54:59 +00:00
Jaime Bernardo
1b26e758a7 Update tests-checklist-jaime.md 2023-10-25 15:37:28 +01:00
Stefan Markovic
7f817ce5f7 FZ 2023-10-25 16:37:15 +02:00
Jaime Bernardo
3d3599b88d Update tests-checklist-jaime.md 2023-10-25 15:33:59 +01:00
Jaime Bernardo
507b8501a2 Update tests-checklist-jaime.md 2023-10-25 15:21:42 +01:00
Jaime Bernardo
c80aa6bade Update tests-checklist-jaime.md 2023-10-25 15:20:16 +01:00
Jaime Bernardo
2480b4aa7e Update tests-checklist-jaime.md 2023-10-25 15:16:54 +01:00
Jaime Bernardo
77ddcf7f97 Update tests-checklist-jaime.md 2023-10-25 14:59:49 +01:00
Jaime Bernardo
1beeea0f49 Update tests-checklist-jaime.md 2023-10-25 14:52:51 +01:00
Jaime Bernardo
361ba08b8a Update tests-checklist-jaime.md 2023-10-25 14:45:51 +01:00
Jaime Bernardo
65887ae26d Update tests-checklist-jaime.md 2023-10-25 14:34:15 +01:00
Jaime Bernardo
39e8a0409d Update tests-checklist-jaime.md 2023-10-25 14:06:34 +01:00
Stefan Markovic
88b305247c Peek, Text Extractor and RegPRev 2023-10-25 12:23:57 +02:00
Stefan Markovic
050c40f0fe ColorPicker, FZEditor, FE add-ons and quick accent 2023-10-25 10:16:46 +02:00
Jaime Bernardo
36ecbde932 Add checklists for 0.75 2023-10-24 16:33:52 +01:00
Jaime Bernardo
96fb5865df Update groups for 6 for 0.75 2023-10-24 15:50:58 +01:00
Jaime Bernardo
0e42849007 Add new screens to localization check 2023-10-24 15:48:36 +01:00
Stefan Markovic
f60d64e1f2 Merge branch 'releaseChecklist' of https://github.com/microsoft/PowerToys into releaseChecklist 2023-10-22 23:20:19 +02:00
Stefan Markovic
4908572b8d Add Environment variables tests 2023-10-22 23:20:01 +02:00
Jaime Bernardo
5bc7201ae2 Update tests-checklist-jaime.md 2023-09-24 16:21:50 +01:00
Jaime Bernardo
a20dd0d8fb Update tests-checklist-jaime.md 2023-09-24 15:58:05 +01:00
Jaime Bernardo
ebcc3af61b Update tests-checklist-jaime.md 2023-09-24 15:44:53 +01:00
Jaime Bernardo
f483a44db2 Update tests-checklist-jaime.md 2023-09-24 15:40:02 +01:00
Jaime Bernardo
ff357c49e2 Update tests-checklist-jaime.md 2023-09-24 15:27:28 +01:00
Jaime Bernardo
22b8ec9fd8 Update tests-checklist-jaime.md 2023-09-24 15:06:15 +01:00
Jaime Bernardo
4b3990feaa Update tests-checklist-jaime.md 2023-09-24 14:58:33 +01:00
Jaime Bernardo
7fee4a20c7 Update tests-checklist-jaime.md 2023-09-24 14:53:27 +01:00
Jaime Bernardo
8adc4032a0 Update tests-checklist-jaime.md 2023-09-23 17:00:40 +01:00
Jaime Bernardo
9160c672df Update tests-checklist-jaime.md 2023-09-23 16:51:50 +01:00
Jaime Bernardo
3e257fafcb Update tests-checklist-jaime.md 2023-09-23 16:48:54 +01:00
Jaime Bernardo
1e3c0a698d Update tests-checklist-jaime.md 2023-09-23 16:36:42 +01:00
Jaime Bernardo
f7283d9f1f Update tests-checklist-jaime.md 2023-09-23 16:34:18 +01:00
Jaime Bernardo
614b64b476 Update tests-checklist-jaime.md 2023-09-23 16:31:15 +01:00
Jaime Bernardo
8b3bf49880 Update tests-checklist-jaime.md 2023-09-23 16:21:23 +01:00
Jaime Bernardo
9214fac22b Update tests-checklist-jaime.md 2023-09-23 16:19:24 +01:00
Jaime Bernardo
d35e5146fe Release checklists for 0.74.0 2023-09-22 16:07:06 +01:00
Jaime Bernardo
9c88c73f60 Update test groups for 5 2023-09-22 16:02:13 +01:00
Stefan Markovic
ce2672eebb Update tests-checklist-stefan.md 2023-08-28 17:58:10 +02:00
Stefan Markovic
8d70ef2c95 Update tests-checklist-stefan.md 2023-08-28 17:37:22 +02:00
Stefan Markovic
1d3acee2a0 Update tests-checklist-stefan.md 2023-08-28 17:25:57 +02:00
Jaime Bernardo
e666d703fc Update tests-checklist-jaime.md 2023-08-28 15:41:39 +01:00
Jaime Bernardo
57e507af28 Update tests-checklist-jaime.md 2023-08-28 14:25:54 +01:00
Seraphima Zykova
b8c744053b Update tests-checklist-seraphima.md 2023-08-28 15:18:54 +02:00
Jaime Bernardo
15f930b35f Update tests-checklist-jaime.md 2023-08-28 14:17:46 +01:00
Jaime Bernardo
89692fea80 Update tests-checklist-jaime.md 2023-08-28 14:14:07 +01:00
Jaime Bernardo
9820d22f0e Update tests-checklist-jaime.md 2023-08-28 14:12:27 +01:00
Jaime Bernardo
0e21214939 Update tests-checklist-jaime.md 2023-08-28 14:08:44 +01:00
Jaime Bernardo
a6b0152822 Update tests-checklist-jaime.md 2023-08-28 14:06:21 +01:00
Stefan Markovic
a39555c9ea Update tests-checklist-stefan.md 2023-08-28 13:59:47 +02:00
Stefan Markovic
dd8848cf2f Update tests-checklist-stefan.md 2023-08-28 13:42:04 +02:00
Jaime Bernardo
4d0925f181 Update tests-checklist-jaime.md 2023-08-28 12:21:49 +01:00
Stefan Markovic
02bc8aed18 Update tests-checklist-gokce.md 2023-08-28 12:36:50 +02:00
Stefan Markovic
3522553d7c Additional tests 2023-08-28 12:33:53 +02:00
Stefan Markovic
bb678282d5 Additional tests 2023-08-28 12:33:17 +02:00
Stefan Markovic
13d1c73fd3 Additional tests 2023-08-28 12:32:23 +02:00
Stefan Markovic
da4e2c042f Additional tests 2023-08-28 12:30:33 +02:00
Stefan Markovic
1282a131ff Additional tests 2023-08-28 12:29:16 +02:00
Stefan Markovic
61934d8f6a Update tests-checklist-jaime.md 2023-08-28 08:07:49 +02:00
Stefan Markovic
0a31e4a4cb Update test-groups-for-6.md 2023-08-28 08:07:14 +02:00
Stefan Markovic
4384d6f8ee Update tests-checklist-jaime.md 2023-08-28 08:04:29 +02:00
Stefan Markovic
b2c3b4381d Update checklists for .73 2023-08-27 20:58:32 +02:00
Jaime Bernardo
b976423ffb Update tests-checklist-jaime.md 2023-07-31 15:24:13 +01:00
Jaime Bernardo
58fd821ce4 Update tests-checklist-jaime.md 2023-07-29 15:46:32 +01:00
Jaime Bernardo
8aceca56dc Update tests-checklist-jaime.md 2023-07-29 14:22:53 +01:00
Jaime Bernardo
9c82c62f1b Update tests-checklist-jaime.md 2023-07-28 15:35:33 +01:00
Jaime Bernardo
21edebb0db Update tests-checklist-jaime.md 2023-07-28 15:31:29 +01:00
Jaime Bernardo
9f2ef0918f Update tests-checklist-jaime.md 2023-07-28 15:22:35 +01:00
Jaime Bernardo
05b42c7813 Update tests-checklist-jaime.md 2023-07-28 15:19:31 +01:00
Jaime Bernardo
2662072af7 Update tests-checklist-jaime.md 2023-07-28 14:41:33 +01:00
Jaime Bernardo
2fb806a82f Update tests-checklist-jaime.md 2023-07-28 14:24:43 +01:00
Jaime Bernardo
7214e9c185 Update tests-checklist-jaime.md 2023-07-28 14:16:28 +01:00
Jaime Bernardo
5325bad7ee Update tests-checklist-jaime.md 2023-07-28 11:51:53 +01:00
Jaime Bernardo
0123c8e53e Update tests-checklist-jaime.md 2023-07-28 11:39:09 +01:00
Jaime Bernardo
fb04ddca01 Update tests-checklist-jaime.md 2023-07-28 10:51:21 +01:00
Stefan Markovic
5efdf1ec3d KBM 2023-07-28 10:49:27 +02:00
Stefan Markovic
d7ca2e028f VCM, QuickAccent and Hosts 2023-07-27 23:10:17 +02:00
Stefan Markovic
b3cc2c68fe GPO and PasteAsPlain 2023-07-27 22:41:23 +02:00
Stefan Markovic
bcb9f59f41 File Explorer Add-ons and Shortcut Guide 2023-07-27 22:07:23 +02:00
Stefan Markovic
405e3c1412 [Done] Install tests and ColorPicker 2023-07-27 17:30:48 +02:00
Jaime Bernardo
9e4168e4fd Test lists for 0.72 2023-07-27 11:41:14 +01:00
Jaime Bernardo
9f2d089825 Update test groups for 4 2023-07-27 11:40:54 +01:00
Jaime Bernardo
7ff5de12ec Update tests-checklist-jaime.md 2023-07-03 16:47:34 +01:00
Jaime Bernardo
6e8a349b2d Update tests-checklist-jaime.md 2023-07-03 16:44:58 +01:00
Jaime Bernardo
cb2024d110 Update tests-checklist-jaime.md 2023-07-03 16:28:44 +01:00
Jaime Bernardo
ef2c7b0203 Update tests-checklist-jaime.md 2023-07-03 16:22:26 +01:00
Jaime Bernardo
392bb727b0 Update tests-checklist-jaime.md 2023-07-03 16:15:22 +01:00
Jaime Bernardo
d03f4d051e Update tests-checklist-jaime.md 2023-07-03 16:11:25 +01:00
Jaime Bernardo
7937d27b36 Update tests-checklist-jaime.md 2023-07-03 16:06:55 +01:00
Jaime Bernardo
d27d0b5461 Update tests-checklist-jaime.md 2023-07-03 16:04:25 +01:00
Jaime Bernardo
1c4eebf3a7 Update tests-checklist-jaime.md 2023-07-03 15:55:24 +01:00
Jaime Bernardo
e47445bc55 Update tests-checklist-jaime.md 2023-07-03 15:50:51 +01:00
Jaime Bernardo
bb4c649954 Update tests-checklist-jaime.md 2023-07-03 15:16:13 +01:00
Stefan Markovic
483b276edd Update tests-checklist-stefan.md 2023-07-03 14:01:23 +02:00
Stefan Markovic
5f5e2174e5 Merge branch 'releaseChecklist' of github.com:microsoft/PowerToys into releaseChecklist 2023-07-03 13:54:38 +02:00
Stefan Markovic
3a90bc71b5 Update tests-checklist-stefan.md 2023-07-03 13:47:46 +02:00
Stefan Markovic
ba4ecb3b51 Update Peek checklist 2023-07-03 13:42:18 +02:00
Stefan Markovic
62702acb31 Update tests-checklist-stefan.md 2023-07-03 13:15:21 +02:00
Jaime Bernardo
a091aeff54 Update tests-checklist-template.md 2023-07-03 11:40:59 +01:00
Jaime Bernardo
79f74dae79 Update tests-checklist-jaime.md 2023-07-03 11:02:08 +01:00
Seraphima Zykova
b3f536564c Update tests-checklist-seraphima.md 2023-06-28 19:32:15 +02:00
Jaime Bernardo
da8d3bdde2 Update tests-checklist-jaime.md 2023-06-28 18:13:23 +01:00
Jaime Bernardo
2f9ef10aaf Update tests-checklist-jaime.md 2023-06-28 18:10:05 +01:00
Jaime Bernardo
540b4e05b9 Update tests-checklist-jaime.md 2023-06-28 18:04:31 +01:00
Stefan Markovic
f052693e2c Merge branch 'releaseChecklist' of github.com:microsoft/PowerToys into releaseChecklist 2023-06-28 19:00:05 +02:00
Stefan Markovic
f914525542 Update Registry Preview checklist 2023-06-28 18:54:29 +02:00
Jaime Bernardo
14b7836d84 Update tests-checklist-jaime.md 2023-06-28 16:59:29 +01:00
Jaime Bernardo
78eff3b009 Update tests-checklist-jaime.md 2023-06-28 16:38:07 +01:00
Jaime Bernardo
e759af66bb Update tests-checklist-jaime.md 2023-06-28 16:29:44 +01:00
Jaime Bernardo
09f97e3c2b Update tests-checklist-jaime.md 2023-06-28 16:24:36 +01:00
Jaime Bernardo
a83ba1e8e3 Update tests-checklist-jaime.md 2023-06-28 16:21:16 +01:00
Jaime Bernardo
375f49bb89 Update tests-checklist-jaime.md 2023-06-28 16:18:22 +01:00
Jaime Bernardo
a95c6cb8b9 Update tests-checklist-jaime.md 2023-06-28 16:15:27 +01:00
Jaime Bernardo
7a0bf5eb0b Update tests-checklist-jaime.md 2023-06-28 16:01:21 +01:00
Jaime Bernardo
ddf770f181 Update tests-checklist-jaime.md 2023-06-28 15:44:49 +01:00
Stefan Markovic
94c407f0b2 v0.71 tests groups checklists 2023-06-28 11:15:41 +02:00
Stefan Markovic
306ca6a5ef Update test checklists 2023-06-27 13:06:00 +02:00
Andrey Nekrasov
12af4b1b86 add MWB tests to tests-checklist-template.md 2023-05-24 16:20:14 +02:00
Jaime Bernardo
302c405dad Update tests-checklist-jaime.md 2023-05-16 18:52:14 +01:00
Jaime Bernardo
e29fb5b51d Update tests-checklist-jaime.md 2023-05-16 18:16:13 +01:00
Jaime Bernardo
f4df22834a Update tests-checklist-jaime.md 2023-05-16 16:52:54 +01:00
Jaime Bernardo
08f29f72b3 Update tests-checklist-jaime.md 2023-05-16 16:44:17 +01:00
Jaime Bernardo
93b8e6c98c Update tests-checklist-jaime.md 2023-05-16 16:25:42 +01:00
Jaime Bernardo
2759628e6e Update tests-checklist-jaime.md 2023-05-16 15:36:42 +01:00
Jaime Bernardo
a4e8aebeea Update tests-checklist-jaime.md 2023-05-16 15:28:07 +01:00
Jaime Bernardo
0eaffd01e1 Update tests-checklist-jaime.md 2023-05-16 15:21:41 +01:00
Seraphima Zykova
5d70e3c990 Update tests-checklist-seraphima.md 2023-05-16 13:33:43 +02:00
Seraphima Zykova
a179cd63b9 Update tests-checklist-seraphima.md 2023-05-16 13:33:18 +02:00
Jaime Bernardo
8abd60a7bd Update tests-checklist-jaime.md 2023-05-16 11:25:08 +01:00
Stefan Markovic
d131a52b43 Update tests-checklist-stefan.md 2023-05-16 12:24:48 +02:00
Stefan Markovic
dc38bca9ff Update tests-checklist-stefan.md 2023-05-16 11:31:45 +02:00
Stefan Markovic
e0948e9ea3 Update tests-checklist-stefan.md 2023-05-16 11:20:53 +02:00
Stefan Markovic
e5412f9e55 Update tests-checklist-stefan.md 2023-05-16 11:00:31 +02:00
Stefan Markovic
6e60571ded Update tests-checklist-stefan.md 2023-05-16 10:49:11 +02:00
Jaime Bernardo
62bbbf49b2 Remove names from groups file 2023-05-15 17:18:57 +01:00
Jaime Bernardo
516e5e85a5 Release checklists for 0.70 2023-05-15 17:06:35 +01:00
Seraphima Zykova
881ab28a9e Update tests-checklist-template.md 2023-05-15 16:09:31 +02:00
Seraphima Zykova
2d2a692a6a Update tests-checklist-seraphima.md 2023-04-03 16:23:26 +02:00
Stefan Markovic
d991f07513 Test lists for v69 2023-03-31 13:53:13 +02:00
Stefan Markovic
0b49729849 Update test-groups-for-5.md 2023-03-31 11:54:50 +02:00
Stefan Markovic
0e4a0e206c Update tests-checklist-template.md 2023-03-31 11:49:36 +02:00
Seraphima Zykova
fa5c523c9c Update tests-checklist-seraphima.md 2023-02-28 16:19:47 +01:00
Stefan Markovic
9cfcc14023 Fix testing lists 2023-02-28 13:35:38 +01:00
Jaime Bernardo
77d262bcc0 Update tests-checklist-jaime.md 2023-02-28 12:10:57 +00:00
Jaime Bernardo
93383da348 Update tests-checklist-jaime.md 2023-02-28 12:07:32 +00:00
Jaime Bernardo
7210400d36 Update tests-checklist-jaime.md 2023-02-28 12:03:56 +00:00
Jaime Bernardo
4815f0dcf5 Update tests-checklist-jaime.md 2023-02-28 11:47:33 +00:00
Jaime Bernardo
81eb0e27fa Update tests-checklist-jaime.md 2023-02-28 11:44:35 +00:00
Jaime Bernardo
17593fd9a4 Update tests-checklist-jaime.md 2023-02-28 11:40:56 +00:00
Jaime Bernardo
8ccc5c2d11 Update tests-checklist-jaime.md 2023-02-28 11:00:23 +00:00
Jaime Bernardo
8258b1ae93 Update tests-checklist-jaime.md 2023-02-28 10:41:17 +00:00
Jaime Bernardo
6b6b38891a Update tests-checklist-jaime.md 2023-02-28 10:31:45 +00:00
Jaime Bernardo
6cf6bbcc42 Update tests-checklist-jaime.md 2023-02-28 09:49:40 +00:00
Stefan Markovic
57c5b347da Add test lists for 0.68 2023-02-27 10:48:03 +01:00
Stefan Markovic
1dcd603b51 Add Paste as Plain Text and Mouse Jump steps 2023-02-27 09:32:03 +01:00
Seraphima Zykova
b0da194a2a Update tests-checklist-template.md 2023-02-23 18:08:26 +01:00
Seraphima Zykova
767be1b698 Update tests-checklist-template.md 2023-02-07 15:52:12 +01:00
Seraphima Zykova
df8df4b4d3 Update tests-checklist-template.md 2023-02-07 15:48:20 +01:00
Jaime Bernardo
325179c508 Update tests-checklist-template.md 2023-02-07 12:41:44 +00:00
Seraphima Zykova
2423371db6 Update tests-checklist-template.md 2023-02-07 13:33:20 +01:00
Stefan Markovic
c7088c784d Update tests-checklist-template.md 2023-02-02 12:36:02 +01:00
Seraphima Zykova
40a3e41587 Update tests-checklist-seraphima.md 2023-01-31 20:31:53 +01:00
Jaime Bernardo
ada9d5cffa Update tests-checklist-jaime.md 2023-01-31 18:39:59 +00:00
Jaime Bernardo
529dfca120 Update tests-checklist-jaime.md 2023-01-31 18:36:09 +00:00
Jaime Bernardo
50bd17cef5 Update tests-checklist-jaime.md 2023-01-31 18:19:20 +00:00
Jaime Bernardo
4cc7a7c070 Update tests-checklist-jaime.md 2023-01-31 16:57:53 +00:00
Jaime Bernardo
7ab817fe27 Update tests-checklist-jaime.md 2023-01-31 16:45:04 +00:00
Seraphima Zykova
3bff297517 Update tests-checklist-seraphima.md 2023-01-31 17:39:37 +01:00
Jaime Bernardo
98465b0122 Update tests-checklist-jaime.md 2023-01-31 16:29:09 +00:00
Stefan Markovic
65102c1141 Update tests-checklist-stefan.md 2023-01-31 17:23:41 +01:00
Jaime Bernardo
948278884d Update tests-checklist-jaime.md 2023-01-31 16:21:49 +00:00
Jaime Bernardo
d94dba3506 Update tests-checklist-jaime.md 2023-01-31 16:11:32 +00:00
Stefan Markovic
0b38a69c0b Update tests-checklist-stefan.md 2023-01-31 16:31:43 +01:00
Jaime Bernardo
695824d3db Update tests-checklist-jaime.md 2023-01-31 15:13:31 +00:00
Stefan Markovic
c67fa8396b Update tests-checklist-stefan.md 2023-01-31 16:10:27 +01:00
Seraphima Zykova
ef95617c03 Update tests-checklist-seraphima.md 2023-01-31 15:57:13 +01:00
Jaime Bernardo
ab60578b4d Update tests-checklist-jaime.md 2023-01-31 14:11:39 +00:00
Stefan Markovic
4ebd614a87 Add FileLockmisth file explorer menu entry in Localization checks 2023-01-31 15:01:27 +01:00
Jaime Bernardo
81583102ba Checklists for 0.67 2023-01-31 11:23:49 +00:00
Jaime Bernardo
b061430c1a 0.67: udpate test groups for 5 2023-01-31 11:03:21 +00:00
Jaime Bernardo
2aaea3ab46 Add test checklist entries for 0.67 2023-01-31 10:35:33 +00:00
Jaime Bernardo
9cd18235da Update tests-checklist-jaime.md 2023-01-03 19:54:57 +00:00
Jaime Bernardo
816e8d6462 Update tests-checklist-jaime.md 2023-01-03 19:49:24 +00:00
Jaime Bernardo
f8c420cda5 Update tests-checklist-jaime.md 2023-01-03 19:30:33 +00:00
Jaime Bernardo
abb3d69c00 Update tests-checklist-jaime.md 2023-01-03 19:25:20 +00:00
Jaime Bernardo
e02e31ced3 Update tests-checklist-jaime.md 2023-01-03 19:04:43 +00:00
Jaime Bernardo
2993d91580 Update tests-checklist-jaime.md 2023-01-03 18:59:18 +00:00
Jaime Bernardo
edffb49c9f Update tests-checklist-jaime.md 2023-01-03 18:39:17 +00:00
Jaime Bernardo
08df962cd3 Update tests-checklist-jaime.md 2023-01-03 18:13:07 +00:00
Jaime Bernardo
c696c6480d Update tests-checklist-jaime.md 2023-01-03 18:08:45 +00:00
Jaime Bernardo
bce91f08cc Update tests-checklist-jaime.md 2023-01-03 17:52:49 +00:00
Jaime Bernardo
e8b1102c87 Update tests-checklist-jaime.md 2023-01-03 17:15:41 +00:00
Jaime Bernardo
e76558d555 Update tests-checklist-jaime.md 2023-01-03 16:58:21 +00:00
Jaime Bernardo
54024a3d0e Update tests-checklist-jaime.md 2023-01-03 16:49:56 +00:00
Jaime Bernardo
cb766ad0ed Checklist for 0.66 2023-01-03 14:48:41 +00:00
Jaime Bernardo
c7a991aa22 Add tests for new Settings 2023-01-03 14:01:59 +00:00
Jaime Bernardo
bb065937b5 Update tests-checklist-jaime.md 2022-12-05 17:20:28 +00:00
Jaime Bernardo
53b75f2d12 Update tests-checklist-jaime.md 2022-12-05 16:55:24 +00:00
Jaime Bernardo
d47a5eaa8b Update tests-checklist-jaime.md 2022-12-05 16:34:34 +00:00
Jaime Bernardo
4b73e22cf1 Update tests-checklist-jaime.md 2022-12-05 15:48:20 +00:00
Jaime Bernardo
220f7dc0b6 Update tests-checklist-jaime.md 2022-12-05 15:21:00 +00:00
Seraphima Zykova
ba74fd3e8d Update tests-checklist-seraphima.md 2022-12-05 16:20:32 +01:00
Jaime Bernardo
92969c23c5 Update tests-checklist-jaime.md 2022-12-05 13:14:13 +00:00
Jaime Bernardo
7563abace5 Update tests-checklist-jaime.md 2022-12-05 12:22:06 +00:00
Jaime Bernardo
8882c15372 Update tests-checklist-jaime.md 2022-12-05 11:38:52 +00:00
Jaime Bernardo
5981d0fa45 Checklists for 0.65 2022-12-05 10:23:46 +00:00
Taras
17940257fb [QuickAccent] Shift + Space to navigate backwards 2022-11-17 16:23:08 +02:00
Taras
9ebee55d3f Add Exclude apps for Quick Accent 2022-11-16 21:02:30 +02:00
Seraphima Zykova
6f869f0bf0 Update FancyZones tests 2022-11-03 13:54:17 +02:00
Seraphima Zykova
6cfd7d72bd Update tests-checklist-seraphima.md 2022-11-01 14:25:23 +02:00
Seraphima Zykova
837dbb5c42 Update tests-checklist-seraphima.md 2022-11-01 13:09:16 +02:00
Seraphima Zykova
d1c2623315 Update tests-checklist-seraphima.md 2022-11-01 12:39:11 +02:00
Stefan Markovic
1ac933a088 Update tests-checklist-stefan.md 2022-11-01 11:06:55 +01:00
Stefan Markovic
d5edc4b507 Update tests-checklist-stefan.md 2022-11-01 10:36:00 +01:00
Stefan Markovic
25ca8b9f4b Update tests-checklist-stefan.md 2022-11-01 10:24:23 +01:00
Stefan Markovic
4c926aa457 Update tests-checklist-stefan.md 2022-11-01 10:23:15 +01:00
Stefan Markovic
a2c358a49c Update tests-checklist-stefan.md 2022-11-01 10:12:53 +01:00
Stefan Markovic
3d5a7bf0a3 Update tests-checklist-stefan.md 2022-11-01 09:51:54 +01:00
Stefan Markovic
1d520250aa Update tests-checklist-stefan.md 2022-11-01 09:45:04 +01:00
Jaime Bernardo
c57cf0bc70 Update tests-checklist-jaime.md 2022-10-31 21:56:38 +00:00
Jaime Bernardo
8d36bbcdb4 Update tests-checklist-jaime.md 2022-10-31 21:52:35 +00:00
Jaime Bernardo
f4f4e535a0 Update tests-checklist-jaime.md 2022-10-31 21:31:31 +00:00
Jaime Bernardo
70a89c5888 Update tests-checklist-jaime.md 2022-10-31 21:19:16 +00:00
Jaime Bernardo
7a595f77cb Update tests-checklist-jaime.md 2022-10-31 21:15:51 +00:00
Jaime Bernardo
aba0545c9c Update tests-checklist-jaime.md 2022-10-31 21:09:12 +00:00
Jaime Bernardo
a3ac9cf691 Update tests-checklist-jaime.md 2022-10-31 20:58:30 +00:00
Jaime Bernardo
eef4929fc0 Update checklists for 0.64 FancyZones 2022-10-31 13:27:48 +00:00
Seraphima Zykova
cb8124b7d7 Update tests-checklist-template.md 2022-10-31 13:21:55 +02:00
Jaime Bernardo
b149d2c200 Checklists for 7 for 0.64 2022-10-30 16:12:18 +00:00
Jaime Bernardo
a74056cc6c Add new checklist entries for 0.64 2022-10-30 15:35:48 +00:00
Jaime Bernardo
149f509817 Update tests-checklist-jaime.md 2022-09-30 13:23:57 +01:00
Jaime Bernardo
d9a016a8a8 Update tests-checklist-jaime.md 2022-09-30 12:22:22 +01:00
Jaime Bernardo
29ca344cac Update tests-checklist-jaime.md 2022-09-30 12:00:59 +01:00
Jaime Bernardo
0833775bec Update tests-checklist-jaime.md 2022-09-30 11:54:37 +01:00
Jaime Bernardo
ba2a8900c5 Update tests-checklist-jaime.md 2022-09-30 11:46:20 +01:00
Seraphima Zykova
fb458dfddd Update tests-checklist-seraphima.md 2022-09-30 12:27:13 +02:00
Jaime Bernardo
d4141f98c8 Update tests-checklist-jaime.md 2022-09-30 11:20:03 +01:00
Stefan Markovic
d03f1be70f Update tests-checklist-stefan.md 2022-09-30 12:12:26 +02:00
Stefan Markovic
d76ce7cccf Update tests-checklist-stefan.md 2022-09-30 12:09:17 +02:00
Jaime Bernardo
b5875453e3 Update tests-checklist-jaime.md 2022-09-30 10:59:16 +01:00
Jaime Bernardo
3dd81254dd Update lists for 0.63.0 2022-09-29 16:11:20 +01:00
Jaime Bernardo
1927eaca97 Add Language to Quick Accent template 2022-09-29 15:47:50 +01:00
Andrey Nekrasov
cacc69f175 Update tests-checklist-template.md 2022-09-05 12:35:16 +03:00
Jaime Bernardo
07cbd4c259 Update tests-checklist-jaime.md 2022-09-02 15:17:08 +01:00
Jaime Bernardo
1587198b6f Update tests-checklist-jaime.md 2022-09-02 15:10:40 +01:00
Jaime Bernardo
de1c564b37 Update tests-checklist-jaime.md 2022-09-02 14:51:14 +01:00
Jaime Bernardo
3dab762ecd Update tests-checklist-jaime.md 2022-09-02 14:36:29 +01:00
Seraphima Zykova
1d16c16785 Update tests-checklist-seraphima.md 2022-09-02 13:19:32 +02:00
Andrey Nekrasov
decbb030cb Update tests-checklist-andrey.md 2022-09-01 23:58:16 +03:00
Andrey Nekrasov
466a382eaa Update tests-checklist-andrey.md 2022-09-01 20:51:34 +03:00
Jaime Bernardo
b5cd846cbd Add test lists for 0.62.0 2022-09-01 16:08:45 +01:00
Jaime Bernardo
72832b5ac2 Add new utilities to the checklist 2022-09-01 15:35:53 +01:00
Jaime Bernardo
692ed30413 Update tests-checklist-template.md 2022-08-26 14:55:06 +01:00
Jaime Bernardo
043ccd7063 Update tests-checklist-jaime.md 2022-07-28 13:31:21 +01:00
Jaime Bernardo
47431c27b0 Update tests-checklist-jaime.md 2022-07-28 12:25:58 +01:00
Jaime Bernardo
906c62038a Update tests-checklist-jaime.md 2022-07-28 12:12:28 +01:00
Jaime Bernardo
204f8970b2 Update tests-checklist-jaime.md 2022-07-28 11:51:29 +01:00
Stefan Markovic
1a97524e20 Update tests-checklist-stefan.md 2022-07-28 09:15:17 +02:00
Stefan Markovic
af9d610d42 Update tests-checklist-stefan.md 2022-07-28 08:54:21 +02:00
Stefan Markovic
0034db1372 Update tests-checklist-stefan.md 2022-07-28 08:45:45 +02:00
Jaime Bernardo
d8826366c0 Add test lists for 0.61 2022-07-27 17:51:57 +01:00
Jaime Bernardo
17b81df79a Update tests-checklist-jaime.md 2022-07-05 15:02:18 +01:00
Jaime Bernardo
6e2ba2a937 Update tests-checklist-jaime.md 2022-07-05 14:45:35 +01:00
Jaime Bernardo
ec806e65d6 Update tests-checklist-jaime.md 2022-07-05 14:13:16 +01:00
Jaime Bernardo
21fd11d14e Update tests-checklist-jaime.md 2022-07-05 11:39:12 +01:00
Jaime Bernardo
3b8777bc24 Update tests-checklist-jaime.md 2022-07-05 11:21:55 +01:00
Jaime Bernardo
47561b2202 Update tests-checklist-jaime.md 2022-07-05 11:21:28 +01:00
Jaime Bernardo
8df9fd7696 Add test lists for 0.60 2022-07-04 21:35:05 +01:00
Jaime Bernardo
17081b92d5 Update tests-checklist-template.md 2022-06-13 15:40:49 +01:00
Jaime Bernardo
1da1321d78 Update tests-checklist-template.md 2022-05-31 09:04:27 +01:00
Jaime Bernardo
f69cf9a0e1 Update tests-checklist-jaime.md 2022-05-30 17:11:01 +01:00
Jaime Bernardo
c6d1b0f4f1 Update tests-checklist-jaime.md 2022-05-30 16:35:24 +01:00
Jaime Bernardo
72d1ff6720 Update tests-checklist-jaime.md 2022-05-30 16:17:22 +01:00
Jaime Bernardo
5467ee7113 Update tests-checklist-jaime.md 2022-05-30 16:12:51 +01:00
Stefan Markovic
f52c813097 Update tests-checklist-stefan.md 2022-05-30 16:54:36 +02:00
Jaime Bernardo
edaeaecabd Update tests-checklist-jaime.md 2022-05-30 15:52:20 +01:00
Jaime Bernardo
f1e26b5033 Update tests-checklist-jaime.md 2022-05-30 15:21:18 +01:00
Stefan Markovic
da4f36b90f Update tests-checklist-stefan.md 2022-05-30 16:16:52 +02:00
Stefan Markovic
a0f97a57a0 Update tests-checklist-stefan.md 2022-05-30 15:45:16 +02:00
Jaime Bernardo
3782acf3df Update tests-checklist-jaime.md 2022-05-30 13:53:54 +01:00
Jaime Bernardo
b43910ea8b Add test lists for 0.59 2022-05-30 13:04:15 +01:00
Jaime Bernardo
ca00b92ca3 Update tests-checklist-jaime.md 2022-04-28 19:54:10 +01:00
Jaime Bernardo
e382f29775 Update tests-checklist-jaime.md 2022-04-28 19:18:58 +01:00
Jaime Bernardo
8d210ceaa1 Update tests-checklist-jaime.md 2022-04-28 19:09:19 +01:00
Jaime Bernardo
4e36a01721 Update tests-checklist-jaime.md 2022-04-28 17:38:24 +01:00
Jaime Bernardo
e91c3e94a5 Update tests-checklist-jaime.md 2022-04-28 16:49:58 +01:00
Jaime Bernardo
42434ad040 Update tests-checklist-jaime.md 2022-04-28 15:13:10 +01:00
Stefan Markovic
08c1e92690 Update tests-checklist-stefan.md 2022-04-28 15:32:45 +02:00
Stefan Markovic
0ca8434392 Update tests-checklist-stefan.md 2022-04-28 15:31:57 +02:00
Jaime Bernardo
1ca74813a4 Update tests-checklist-jaime.md 2022-04-28 14:11:51 +01:00
Stefan Markovic
9ca02b06b3 Update tests-checklist-stefan.md 2022-04-28 15:07:56 +02:00
Stefan Markovic
416ca196f9 Update tests-checklist-stefan.md 2022-04-28 14:56:31 +02:00
Stefan Markovic
163c2192b8 Update tests-checklist-stefan.md 2022-04-28 14:51:31 +02:00
Stefan Markovic
182a4facdc Update tests-checklist-stefan.md 2022-04-28 14:26:56 +02:00
Stefan Markovic
6851433233 Update tests-checklist-stefan.md 2022-04-28 13:36:52 +02:00
Jaime Bernardo
c8050dcad4 Add checklists for 0.58.0 2022-04-27 21:19:20 +01:00
Jaime Bernardo
b4b553fc29 Update tests-checklist-ilia.md 2022-03-29 20:16:49 +01:00
Jaime Bernardo
3a26850a2e Update tests-checklist-andrey.md 2022-03-29 17:24:08 +01:00
Jaime Bernardo
51193c0f93 Update tests-checklist-jaime.md 2022-03-29 16:59:31 +01:00
Jaime Bernardo
75a5eff759 Update tests-checklist-jaime.md 2022-03-29 16:17:56 +01:00
Jaime Bernardo
f3e8211d22 Update tests-checklist-jaime.md 2022-03-29 14:54:07 +01:00
Jaime Bernardo
2b19ce0a0d Update tests-checklist-jaime.md 2022-03-29 14:42:11 +01:00
Jaime Bernardo
9b041cc521 Update tests-checklist-jaime.md 2022-03-29 14:24:57 +01:00
Jaime Bernardo
3b26f532df Update tests-checklist-jaime.md 2022-03-29 14:11:57 +01:00
Jaime Bernardo
c5e8bfeea8 Update tests-checklist-jaime.md 2022-03-29 14:05:02 +01:00
Jaime Bernardo
79c260ab1b Update tests-checklist-seraphima.md 2022-03-29 13:58:01 +01:00
Stefan Markovic
0ce66df5eb Update tests-checklist-stefan.md 2022-03-29 13:43:47 +02:00
Stefan Markovic
ea058cfca5 Update tests-checklist-stefan.md 2022-03-29 13:35:49 +02:00
Stefan Markovic
6a4109f2f7 Update tests-checklist-stefan.md 2022-03-29 13:27:29 +02:00
Stefan Markovic
243b805891 Update tests-checklist-stefan.md 2022-03-29 13:22:42 +02:00
Jaime Bernardo
d88d554af8 checklists for 0.57 2022-03-28 18:37:32 +01:00
Seraphima Zykova
99533b4bc9 Update tests-checklist-seraphima.md 2022-02-24 20:20:12 +03:00
Jaime Bernardo
61a8f04bc7 Update tests-checklist-jaime.md 2022-02-24 16:07:26 +00:00
Jaime Bernardo
40694cb5d3 Update tests-checklist-jaime.md 2022-02-24 15:43:36 +00:00
Jaime Bernardo
8d5656a074 Update tests-checklist-jaime.md 2022-02-24 15:35:02 +00:00
Jaime Bernardo
72f1b35fe7 Update tests-checklist-jaime.md 2022-02-24 15:27:49 +00:00
Jaime Bernardo
46897d3527 Update tests-checklist-jaime.md 2022-02-24 15:13:27 +00:00
Jaime Bernardo
1b2c93e616 Update tests-checklist-jaime.md 2022-02-24 15:05:22 +00:00
Jaime Bernardo
1f7377da01 Update tests-checklist-jaime.md 2022-02-24 14:55:23 +00:00
Jaime Bernardo
76ee54a3ff Update tests-checklist-jaime.md 2022-02-24 13:46:54 +00:00
Jaime Bernardo
d3c9837581 Update tests-checklist-jaime.md 2022-02-24 13:39:06 +00:00
Jaime Bernardo
bd5c924983 Update tests-checklist-jaime.md 2022-02-24 12:44:45 +00:00
Jaime Bernardo
4dda6b1294 Update tests-checklist-jaime.md 2022-02-24 12:16:50 +00:00
Jaime Bernardo
5971d36d62 Update tests-checklist-jaime.md 2022-02-24 12:09:49 +00:00
Seraphima Zykova
a5f023145f Update tests-checklist-seraphima.md 2022-02-24 14:13:27 +03:00
Seraphima Zykova
9d7897852e Update tests-checklist-seraphima.md 2022-02-24 13:56:21 +03:00
Seraphima Zykova
717da9d362 Update tests-checklist-seraphima.md 2022-02-24 13:52:48 +03:00
Seraphima Zykova
bd1472a844 Update tests-checklist-seraphima.md 2022-02-24 13:46:04 +03:00
Seraphima Zykova
601c1f3a27 Update tests-checklist-seraphima.md 2022-02-24 13:38:59 +03:00
Seraphima Zykova
f54054eb15 Update tests-checklist-seraphima.md 2022-02-24 13:08:59 +03:00
Stefan Markovic
3ed22218af Update tests-checklist-stefan.md 2022-02-24 10:35:51 +01:00
Stefan Markovic
0195673ee5 Update tests-checklist-stefan.md 2022-02-24 10:29:09 +01:00
Stefan Markovic
f8ac59ea1a Update tests-checklist-stefan.md 2022-02-24 09:57:18 +01:00
Stefan Markovic
bd0907ec7f Update tests-checklist-stefan.md 2022-02-24 09:50:55 +01:00
Stefan Markovic
3a906f01c2 Update tests-checklist-stefan.md 2022-02-24 09:27:35 +01:00
Stefan Markovic
72e1dde777 Update tests-checklist-stefan.md 2022-02-24 00:42:28 +01:00
Stefan Markovic
72b5e61323 Update tests-checklist-stefan.md 2022-02-24 00:38:20 +01:00
Stefan Markovic
e33a4265ab Update tests-checklist-stefan.md 2022-02-24 00:33:30 +01:00
Stefan Markovic
ae6b98d3c2 Update tests-checklist-stefan.md 2022-02-24 00:30:03 +01:00
Stefan Markovic
0bb88846d2 Update tests-checklist-stefan.md 2022-02-24 00:27:38 +01:00
Jaime Bernardo
287366fe6e Tweak test groups for 3 2022-02-23 22:10:55 +00:00
Jaime Bernardo
e0c68825e3 Update checklists for 0.56 2022-02-23 22:03:41 +00:00
Jaime Bernardo
417db59404 Add tests to template 2022-02-23 21:55:42 +00:00
Jaime Bernardo
b64a41262c Update tests-checklist-jaime.md 2022-01-28 18:02:53 +00:00
Jaime Bernardo
e33b0474e6 Update tests-checklist-jaime.md 2022-01-28 17:39:33 +00:00
Jaime Bernardo
265b5d5b00 Update tests-checklist-jaime.md 2022-01-28 17:03:52 +00:00
Jaime Bernardo
8a5020cd8e Update tests-checklist-jaime.md 2022-01-28 16:57:01 +00:00
Jaime Bernardo
afc4556bdf Update tests-checklist-jaime.md 2022-01-28 16:36:08 +00:00
Jaime Bernardo
b0cc84ba41 Update tests-checklist-jaime.md 2022-01-28 16:22:29 +00:00
Jaime Bernardo
fa904a20f5 Update tests-checklist-jaime.md 2022-01-28 16:06:34 +00:00
Stefan Markovic
1ef6c10445 Update tests-checklist-stefan.md 2022-01-28 17:02:45 +01:00
Jaime Bernardo
62fd4778c3 Update tests-checklist-jaime.md 2022-01-28 15:44:14 +00:00
Jaime Bernardo
d838192819 Update tests-checklist-template.md 2022-01-28 15:41:43 +00:00
Seraphima Zykova
fdb60a88bc Update tests-checklist-seraphima.md 2022-01-28 14:36:50 +00:00
Seraphima Zykova
9eb310808c Update tests-checklist-seraphima.md 2022-01-28 14:36:27 +00:00
Seraphima Zykova
de72e9a410 Update tests-checklist-seraphima.md 2022-01-28 13:47:53 +00:00
Seraphima Zykova
75d8cc9323 Update tests-checklist-seraphima.md 2022-01-28 12:44:12 +00:00
Seraphima Zykova
68d2abb7e4 Update tests-checklist-seraphima.md 2022-01-28 12:36:03 +00:00
Andrey Nekrasov
a34e51a2f7 Update tests-checklist-andrey.md 2022-01-28 15:23:34 +03:00
Seraphima Zykova
93746efea7 Update tests-checklist-seraphima.md 2022-01-28 11:34:27 +00:00
Stefan Markovic
9813564213 Update tests-checklist-stefan.md 2022-01-28 11:32:04 +01:00
Stefan Markovic
ee74c9d920 Update tests-checklist-stefan.md 2022-01-28 11:27:41 +01:00
Stefan Markovic
239d78d504 Update tests-checklist-stefan.md 2022-01-28 11:16:18 +01:00
Stefan Markovic
22a9d8d75d Update tests-checklist-stefan.md 2022-01-28 10:41:53 +01:00
Stefan Markovic
6e35755f6b Update tests-checklist-stefan.md 2022-01-28 10:38:55 +01:00
Stefan Markovic
5db9ce7007 Update tests-checklist-stefan.md 2022-01-28 10:25:42 +01:00
Stefan Markovic
838e667462 Update tests-checklist-stefan.md 2022-01-28 10:18:02 +01:00
Stefan Markovic
939a982311 Update tests-checklist-stefan.md 2022-01-28 10:10:37 +01:00
Stefan Markovic
4434f05466 Update tests-checklist-stefan.md 2022-01-28 10:06:19 +01:00
Jaime Bernardo
1d47dc1a6b Create tests-checklist-stefan.md 2022-01-28 00:09:24 +00:00
Jaime Bernardo
7f63468f15 Create tests-checklist-seraphima.md 2022-01-28 00:09:07 +00:00
Jaime Bernardo
3c7ace8300 Create tests-checklist-jaime.md 2022-01-28 00:08:47 +00:00
Jaime Bernardo
7a139a4085 Create tests-checklist-andrey.md 2022-01-28 00:08:19 +00:00
Jaime Bernardo
a7ec20ad22 Update test-groups-for-4.md 2022-01-28 00:07:18 +00:00
Jaime Bernardo
8ce1d0188b Update test-groups-for-4.md 2022-01-27 23:40:47 +00:00
Jaime Bernardo
d2b491f07d Update tests-checklist-template.md 2022-01-27 23:38:45 +00:00
Jaime Bernardo
bfaa462be5 Update tests-checklist-template.md 2022-01-27 23:32:17 +00:00
Seraphima Zykova
56d35966bd Update tests-checklist-template.md 2022-01-27 19:07:59 +00:00
Jaime Bernardo
3bb2750478 Update tests-checklist-jaime.md 2022-01-06 13:50:15 +00:00
Jaime Bernardo
1d04ab971d Update tests-checklist-jaime.md 2022-01-06 13:35:55 +00:00
Jaime Bernardo
604a72c2f0 Update tests-checklist-jaime.md 2022-01-06 13:30:47 +00:00
Jaime Bernardo
0de7e48ccb Update tests-checklist-jaime.md 2022-01-06 13:20:01 +00:00
Jaime Bernardo
d7059abcf2 Update tests-checklist-jaime.md 2022-01-06 13:04:18 +00:00
Jaime Bernardo
9fe6e5c66d Update tests-checklist-jaime.md 2022-01-06 12:58:10 +00:00
Jaime Bernardo
f3b2f702bc Update tests-checklist-jaime.md 2022-01-06 12:55:42 +00:00
Jaime Bernardo
54553fe680 Update tests-checklist-jaime.md 2022-01-06 12:35:09 +00:00
Jaime Bernardo
0a581841dc Update tests-checklist-jaime.md 2022-01-06 12:22:49 +00:00
Stefan Markovic
3eecb434ba Update tests-checklist-stefan.md 2022-01-06 13:17:29 +01:00
Jaime Bernardo
a4cfda8175 Update tests-checklist-jaime.md 2022-01-06 12:07:19 +00:00
Jaime Bernardo
1fb68df0ab Update tests-checklist-jaime.md 2022-01-06 11:54:34 +00:00
Jaime Bernardo
6bfe0ced51 Update tests-checklist-template.md 2022-01-06 11:48:13 +00:00
Stefan Markovic
6562ab132f Update tests-checklist-stefan.md 2022-01-06 12:47:53 +01:00
Jaime Bernardo
861f5e50d7 Update tests-checklist-tameem.md 2022-01-06 11:47:46 +00:00
Jaime Bernardo
ff20f119c2 Update tests-checklist-jaime.md 2022-01-06 11:46:44 +00:00
Stefan Markovic
dc7f683cd6 Update tests-checklist-stefan.md 2022-01-06 12:36:16 +01:00
Jaime Bernardo
2621c4e40e Update tests-checklist-jaime.md 2022-01-06 11:34:00 +00:00
Stefan Markovic
e1c4d4d004 Update tests-checklist-stefan.md 2022-01-06 12:13:47 +01:00
Jaime Bernardo
f3ccc53586 Update tests-checklist-jaime.md 2022-01-06 11:12:03 +00:00
Jaime Bernardo
3ac073a2c0 Update tests-checklist-jaime.md 2022-01-06 11:04:20 +00:00
Stefan Markovic
dd0a5e391a Update tests-checklist-stefan.md 2022-01-06 11:55:44 +01:00
Jaime Bernardo
f7945457c0 Update tests-checklist-template.md 2022-01-06 10:49:37 +00:00
Jaime Bernardo
9a767b3014 Update tests-checklist-jaime.md 2022-01-06 10:49:03 +00:00
Stefan Markovic
175dd8a4d1 Update tests-checklist-stefan.md 2022-01-06 11:37:01 +01:00
Stefan Markovic
0baeb1c230 Update tests-checklist-stefan.md 2022-01-06 11:04:12 +01:00
Stefan Markovic
393d617393 Update tests-checklist-stefan.md 2022-01-06 10:53:47 +01:00
Stefan Markovic
d287d7ff76 Update tests-checklist-stefan.md 2022-01-06 10:44:01 +01:00
Stefan Markovic
dbf8e31de9 Update tests-checklist-stefan.md 2022-01-06 10:34:49 +01:00
Stefan Markovic
b44b70d8a6 Update tests-checklist-stefan.md 2022-01-06 10:27:11 +01:00
Stefan Markovic
ae1c3b6d71 Update tests-checklist-stefan.md 2022-01-06 10:04:27 +01:00
Stefan Markovic
877699fee4 Update tests-checklist-stefan.md 2022-01-06 09:20:56 +01:00
Stefan Markovic
07250c6211 Update tests-checklist-stefan.md 2022-01-06 09:16:16 +01:00
Stefan Markovic
8e81033fa4 Update tests-checklist-stefan.md 2022-01-06 09:04:46 +01:00
Jaime Bernardo
310595c8bb Add checklists for 0.53 2022-01-05 22:31:52 +00:00
Jaime Bernardo
55a74129e8 Add Always on top and awake to template 2022-01-05 22:10:53 +00:00
Jaime Bernardo
91cd82c756 Update tests-checklist-jaime.md 2021-11-25 17:46:08 +00:00
Jaime Bernardo
74c8d15a43 Update tests-checklist-jaime.md 2021-11-25 17:26:24 +00:00
Jaime Bernardo
f3d2881c71 Update tests-checklist-jaime.md 2021-11-25 17:02:10 +00:00
Jaime Bernardo
b20deac845 Update tests-checklist-jaime.md 2021-11-25 15:34:53 +00:00
Andrey Nekrasov
9c547513a6 Update tests-checklist-andrey.md 2021-11-25 18:32:51 +03:00
Stefan Markovic
81f3606a95 Update tests-checklist-stefan.md 2021-11-25 16:19:47 +01:00
Stefan Markovic
aa235be1bc Update tests-checklist-stefan.md 2021-11-25 15:59:51 +01:00
Stefan Markovic
1200fd54d0 Update tests-checklist-stefan.md 2021-11-25 15:59:15 +01:00
Seraphima Zykova
433dd3f5a6 Update tests-checklist-seraphima.md 2021-11-25 14:48:29 +00:00
Stefan Markovic
4a75203883 Update tests-checklist-stefan.md 2021-11-25 15:45:15 +01:00
Stefan Markovic
5b309cbefb Update tests-checklist-stefan.md 2021-11-25 14:03:31 +01:00
Stefan Markovic
94ad171196 Update tests-checklist-stefan.md 2021-11-25 13:16:28 +01:00
Stefan Markovic
2c8afc1881 Update tests-checklist-stefan.md 2021-11-25 12:12:38 +01:00
Stefan Markovic
7630a3eaa8 Update tests-checklist-stefan.md 2021-11-25 11:34:00 +01:00
Stefan Markovic
c924e4db88 Update tests-checklist-stefan.md 2021-11-25 11:28:00 +01:00
Jaime Bernardo
381baaa521 Rename tests-checlist-tameem-md to tests-checklist-tameem.md 2021-11-25 10:18:54 +00:00
Jaime Bernardo
a0ecbc39d8 Checklists for 0.51 2021-11-25 10:08:54 +00:00
Jaime Bernardo
210142915a Update tests-checklist-template.md 2021-11-24 23:28:36 +00:00
Andrey Nekrasov
65bf291b3c Update tests-checklist-template.md 2021-10-27 18:48:56 +03:00
Andrey Nekrasov
70712debf4 Update tests-checklist-template.md 2021-10-27 18:48:47 +03:00
Andrey Nekrasov
525027a404 Update test-groups-for-3.md 2021-10-27 18:48:08 +03:00
Andrey Nekrasov
db6b1cc84e Update tests-checklist-andrey.md 2021-10-27 17:41:10 +03:00
Jaime Bernardo
a11c60838c Update tests-checklist-jaime.md 2021-10-26 23:26:40 +01:00
Jaime Bernardo
587cfe2701 Update tests-checklist-jaime.md 2021-10-26 23:23:29 +01:00
Jaime Bernardo
d826717793 Update tests-checklist-jaime.md 2021-10-26 23:19:59 +01:00
Jaime Bernardo
24698a7ab9 Update tests-checklist-jaime.md 2021-10-26 23:06:18 +01:00
Jaime Bernardo
2ba18f746a Update tests-checklist-jaime.md 2021-10-26 22:44:22 +01:00
Jaime Bernardo
ff0905d474 Update tests-checklist-jaime.md 2021-10-26 22:22:52 +01:00
Jaime Bernardo
b6b42c68e9 Update tests-checklist-template.md 2021-10-26 22:16:53 +01:00
Seraphima Zykova
2b6b16e389 Update tests-checklist-seraphima.md 2021-10-26 19:07:59 +01:00
Seraphima Zykova
e52a9624ea Update tests-checklist-seraphima.md 2021-10-26 18:10:19 +01:00
Jaime Bernardo
7d03095c7d Update tests-checklist-jaime.md 2021-10-26 18:08:40 +01:00
Jaime Bernardo
4773cb983b Update tests-checklist-jaime.md 2021-10-26 18:05:09 +01:00
Seraphima Zykova
aec91a25d2 Update tests-checklist-seraphima.md 2021-10-26 17:57:31 +01:00
Jaime Bernardo
e7466e162b Update tests-checklist-template.md 2021-10-26 17:56:27 +01:00
Jaime Bernardo
a077cd3ca5 Update tests-checklist-jaime.md 2021-10-26 17:21:42 +01:00
Stefan Markovic
6d59a9ec05 Update tests-checklist-stefan.md 2021-10-26 18:14:00 +02:00
Seraphima Zykova
58b1f75d93 Update tests-checklist-seraphima.md 2021-10-26 17:12:04 +01:00
Seraphima Zykova
22b8e99da4 Update tests-checklist-seraphima.md 2021-10-26 16:37:41 +01:00
Seraphima Zykova
d0634e01a8 Update tests-checklist-seraphima.md 2021-10-26 16:33:14 +01:00
Stefan Markovic
e4c4e15348 Update tests-checklist-stefan.md 2021-10-26 16:23:51 +02:00
Stefan Markovic
44db739e6d Update tests-checklist-stefan.md 2021-10-26 14:54:42 +02:00
Stefan Markovic
ae4b291c67 Update tests-checklist-stefan.md 2021-10-26 14:50:10 +02:00
Stefan Markovic
f567f6a9b5 Update tests-checklist-stefan.md 2021-10-26 14:45:18 +02:00
Stefan Markovic
2bc0d39e70 Update tests-checklist-stefan.md 2021-10-26 12:23:53 +02:00
Jaime Bernardo
0798030e0b Checklists for 0.49 2021-10-26 10:40:59 +01:00
Jaime Bernardo
e5ae3f93aa Update checklist template with Find My Mouse 2021-10-26 10:40:36 +01:00
Seraphima Zykova
1c3fed6b27 Update tests-checklist-template.md 2021-10-11 16:52:36 +01:00
Jaime Bernardo
28cf763648 Update tests-checklist-jaime.md 2021-09-27 17:58:42 +01:00
Jaime Bernardo
7be73bc005 Update tests-checklist-jaime.md 2021-09-27 17:15:14 +01:00
Andrey Nekrasov
176c7790cc Update tests-checklist-andrey.md 2021-09-27 16:50:55 +03:00
Seraphima Zykova
a04096646f Update tests-checklist-seraphima.md 2021-09-27 14:06:36 +01:00
Stefan Markovic
9b33c9adcf Update tests-checklist-stefan.md 2021-09-27 13:03:53 +02:00
Stefan Markovic
c1cf59f5a7 Update tests-checklist-stefan.md 2021-09-27 12:53:30 +02:00
Stefan Markovic
84db32ba42 Update tests-checklist-stefan.md 2021-09-27 12:17:51 +02:00
Stefan Markovic
dcfba5736c Update tests-checklist-stefan.md 2021-09-27 11:51:11 +02:00
Stefan Markovic
b850fa0f78 Update tests-checklist-stefan.md 2021-09-27 11:34:47 +02:00
Stefan Markovic
c856e7f1be Update tests-checklist-stefan.md 2021-09-27 10:44:35 +02:00
Jaime Bernardo
47b585a596 Checklists for 0.47.0 2021-09-26 20:53:38 +01:00
Jaime Bernardo
90b54dcd51 Add Windows key press to the items to test 2021-09-26 20:41:55 +01:00
Jaime Bernardo
b8fd29947e Update tests-checklist-jaime.md 2021-08-27 16:49:45 +01:00
Andrey Nekrasov
f339bceae6 Update tests-checklist-andrey.md 2021-08-27 16:27:48 +03:00
Andrey Nekrasov
365b4dc0ed Update tests-checklist-andrey.md 2021-08-27 16:15:08 +03:00
Jaime Bernardo
dd898aa05c Update tests-checklist-jaime.md 2021-08-27 13:58:41 +01:00
Jaime Bernardo
3ba97b9312 Update tests-checklist-jaime.md 2021-08-27 13:05:55 +01:00
Jaime Bernardo
7dfb0eb3fc Update tests-checklist-jaime.md 2021-08-27 12:40:37 +01:00
Seraphima Zykova
8d4ecfa09e Update tests-checklist-seraphima.md 2021-08-27 12:27:28 +01:00
Jaime Bernardo
3d3e6e8a3e Update tests-checklist-jaime.md 2021-08-27 12:20:11 +01:00
Jaime Bernardo
95fad56036 Update tests-checklist-jaime.md 2021-08-27 11:48:04 +01:00
Stefan Markovic
6b78d09d3b Update tests-checklist-stefan.md 2021-08-27 12:42:06 +02:00
Seraphima Zykova
3dbdb5d5e5 Update tests-checklist-seraphima.md 2021-08-27 11:36:11 +01:00
Jaime Bernardo
6397b0ce82 Update tests-checklist-jaime.md 2021-08-27 11:29:59 +01:00
Seraphima Zykova
83a58868be Update tests-checklist-seraphima.md 2021-08-27 11:20:13 +01:00
Stefan Markovic
3001779e10 Update tests-checklist-stefan.md 2021-08-27 11:36:15 +02:00
Andrey Nekrasov
bd7b01a937 Update tests-checklist-andrey.md 2021-08-27 12:02:02 +03:00
Stefan Markovic
942eed2ac8 Update tests-checklist-stefan.md 2021-08-27 10:20:53 +02:00
Stefan Markovic
eb9fa0837f Update tests-checklist-stefan.md 2021-08-27 10:12:35 +02:00
Stefan Markovic
b6698b9c8f Update tests-checklist-stefan.md 2021-08-27 09:44:03 +02:00
Stefan Markovic
2cbac3384a Update tests-checklist-stefan.md 2021-08-27 09:43:44 +02:00
Stefan Markovic
b944cffc4c Update tests-checklist-stefan.md 2021-08-27 09:35:40 +02:00
Jaime Bernardo
78a28aa8a1 Checklist for 0.45.0 2021-08-26 22:19:10 +01:00
Jaime Bernardo
a745a53f29 Remove workflows from the releaseChecklist branch 2021-08-26 21:54:07 +01:00
Jaime Bernardo
1c827c7a7c [spellchecker] Add cleanmgr to expect.txt 2021-07-29 18:20:03 +01:00
Jaime Bernardo
b77cbf2f4c Update tests-checklist-jaime.md 2021-07-29 16:27:20 +01:00
Jaime Bernardo
53ef9fc19d Update tests-checklist-jaime.md 2021-07-29 15:00:52 +01:00
Jaime Bernardo
b559bd0a3a Update tests-checklist-jaime.md 2021-07-29 14:38:36 +01:00
Jaime Bernardo
ad7b950ddf Update tests-checklist-jaime.md 2021-07-29 14:28:59 +01:00
Jaime Bernardo
2b1a8972ef Update tests-checklist-template.md 2021-07-29 14:20:30 +01:00
Andrey Nekrasov
91ffdf056d Update tests-checklist-andrey.md 2021-07-29 15:59:11 +03:00
Jaime Bernardo
d41dff44fc Update tests-checklist-template.md 2021-07-29 13:57:29 +01:00
Jaime Bernardo
7ed4bcf196 Update tests-checklist-template.md 2021-07-29 13:36:59 +01:00
Mykhailo Pylyp
c48a41c07a Update tests-checklist-mykhailo.md 2021-07-29 15:28:32 +03:00
Jaime Bernardo
e6126a4e84 Update tests-checklist-jaime.md 2021-07-29 13:26:48 +01:00
Stefan Markovic
625573e5dc Update tests-checklist-stefan.md 2021-07-29 14:15:58 +02:00
Mykhailo Pylyp
4a13fb00d1 Update tests-checklist-mykhailo.md 2021-07-29 14:36:33 +03:00
Mykhailo Pylyp
df31ac8497 Update tests-checklist-mykhailo.md 2021-07-29 14:12:43 +03:00
Stefan Markovic
5a9c13a55c Update tests-checklist-stefan.md 2021-07-29 13:05:57 +02:00
Stefan Markovic
bf1ddf0279 Update tests-checklist-stefan.md 2021-07-29 12:34:05 +02:00
Stefan Markovic
794f9c0bf7 Update tests-checklist-stefan.md 2021-07-29 12:20:11 +02:00
Mykhailo Pylyp
459ff1fc05 Update tests-checklist-mykhailo.md 2021-07-29 13:19:28 +03:00
Mykhailo Pylyp
382557fcbf Update tests-checklist-mykhailo.md 2021-07-29 13:12:59 +03:00
Seraphima Zykova
ea42b346ef Update tests-checklist-seraphima.md 2021-07-29 10:58:54 +01:00
Stefan Markovic
f85c805640 Update tests-checklist-stefan.md 2021-07-29 11:55:25 +02:00
Seraphima Zykova
90e36b802b Update tests-checklist-seraphima.md 2021-07-29 10:44:47 +01:00
Seraphima Zykova
6fdfebf0c6 Update tests-checklist-seraphima.md 2021-07-29 10:36:33 +01:00
Seraphima Zykova
749405d7f1 Update tests-checklist-seraphima.md 2021-07-29 10:15:31 +01:00
Stefan Markovic
0a629c464c Update tests-checklist-stefan.md 2021-07-29 11:08:45 +02:00
Seraphima Zykova
43a834060c Update tests-checklist-seraphima.md 2021-07-29 09:01:54 +01:00
Jaime Bernardo
a0ccaa0701 Checklist for 0.43.0 2021-07-28 18:44:37 +01:00
Mykhailo Pylyp
f3855c633d Update tests-checklist-mykhailo.md 2021-06-24 17:29:52 +03:00
Mykhailo Pylyp
b41931d3eb Update tests-checklist-mykhailo.md 2021-06-24 17:25:26 +03:00
Mykhailo Pylyp
699d753dfb Update tests-checklist-mykhailo.md 2021-06-24 17:23:40 +03:00
Seraphima Zykova
2e7e4aad45 Update tests-checklist-seraphima.md 2021-06-24 14:38:31 +01:00
Andrey Nekrasov
5bffced4b4 Update tests-checklist-andrey.md 2021-06-24 16:11:15 +03:00
Seraphima Zykova
9ef73afc2b Update tests-checklist-seraphima.md 2021-06-24 14:10:45 +01:00
Andrey Nekrasov
1c3839e0d3 Update tests-checklist-andrey.md 2021-06-24 15:39:59 +03:00
Seraphima Zykova
92b640581b Update tests-checklist-seraphima.md 2021-06-24 12:23:01 +01:00
Mykhailo Pylyp
0c586c07bb Update tests-checklist-mykhailo.md 2021-06-24 14:22:17 +03:00
Seraphima Zykova
395be489f9 Update tests-checklist-seraphima.md 2021-06-24 12:00:58 +01:00
Seraphima Zykova
522c375d91 Update tests-checklist-seraphima.md 2021-06-24 11:49:51 +01:00
Mykhailo Pylyp
d9b082c499 Update tests-checklist-mykhailo.md 2021-06-24 13:41:44 +03:00
Seraphima Zykova
0fa87ae06b Update tests-checklist-seraphima.md 2021-06-24 11:31:17 +01:00
Seraphima Zykova
7a0b791bf9 Update tests-checklist-seraphima.md 2021-06-24 11:30:38 +01:00
Seraphima Zykova
462ddee63e Update tests-checklist-seraphima.md 2021-06-24 10:55:41 +01:00
Mykhailo Pylyp
b0572fa28b Update tests-checklist-mykhailo.md 2021-06-24 12:50:25 +03:00
Seraphima Zykova
6e1a53fb2a Update tests-checklist-seraphima.md 2021-06-24 10:49:18 +01:00
Mykhailo Pylyp
e4e9759564 Update tests-checklist-template.md 2021-06-24 12:41:56 +03:00
Seraphima Zykova
2893420120 Update tests-checklist-seraphima.md 2021-06-24 10:40:33 +01:00
Mykhailo Pylyp
ab28b43d83 Update tests-checklist-mykhailo.md 2021-06-24 12:08:18 +03:00
Mykhailo Pylyp
9917c86781 Update tests-checklist-mykhailo.md 2021-06-24 12:03:10 +03:00
Mykhailo Pylyp
4973f715e5 Update tests-checklist-mykhailo.md 2021-06-24 11:51:22 +03:00
mykhailopylyp
0702c8e602 Checklist for 0.41.0 2021-06-24 11:34:03 +03:00
Seraphima Zykova
3ee89a2520 Update tests-checklist-seraphima.md 2021-05-26 14:18:41 +01:00
Seraphima Zykova
85304529e1 Update tests-checklist-seraphima.md 2021-05-26 12:57:40 +01:00
Andrey Nekrasov
516a520532 Update tests-checklist-andrey.md 2021-05-26 14:43:24 +03:00
Seraphima Zykova
c59b9d427f Update tests-checklist-seraphima.md 2021-05-26 12:25:51 +01:00
Enrico Giordani
43079c9c63 Update tests-checklist-enrico.md 2021-05-26 13:23:54 +02:00
Enrico Giordani
b492c4fa63 Update tests-checklist-template.md 2021-05-26 13:23:40 +02:00
Enrico Giordani
849154aa04 Update tests-checklist-template.md 2021-05-26 13:20:50 +02:00
Mykhailo Pylyp
7c296654c1 Update tests-checklist-mykhailo.md 2021-05-26 14:20:30 +03:00
Mykhailo Pylyp
5f46603fe8 Update tests-checklist-mykhailo.md 2021-05-26 14:17:58 +03:00
Enrico Giordani
871de8af4d Update tests-checklist-enrico.md 2021-05-26 13:15:39 +02:00
Enrico Giordani
204f6ff31f Update tests-checklist-enrico.md 2021-05-26 13:11:37 +02:00
Enrico Giordani
6b5b7104f6 Update tests-checklist-enrico.md 2021-05-26 13:10:30 +02:00
Enrico Giordani
8c685b435c Update tests-checklist-enrico.md 2021-05-26 13:04:03 +02:00
Andrey Nekrasov
219c2b27bf Update tests-checklist-andrey.md 2021-05-26 14:01:05 +03:00
Enrico Giordani
dccb08fc98 Update tests-checklist-enrico.md 2021-05-26 12:54:35 +02:00
Seraphima Zykova
6fd1b2e5ae Update tests-checklist-seraphima.md 2021-05-26 11:54:20 +01:00
Enrico Giordani
92193eb32b Update tests-checklist-enrico.md 2021-05-26 12:51:02 +02:00
Mykhailo Pylyp
f53f4852f3 Update tests-checklist-mykhailo.md 2021-05-26 13:21:08 +03:00
Seraphima Zykova
a2f0e2ebfa Update tests-checklist-seraphima.md 2021-05-26 11:18:52 +01:00
Mykhailo Pylyp
51859fa769 Update tests-checklist-template.md 2021-05-26 13:13:02 +03:00
Mykhailo Pylyp
f6890be2ea Update tests-checklist-template.md 2021-05-26 13:11:47 +03:00
Enrico Giordani
76ecf6f026 Create test-groups.md 2021-05-26 12:07:40 +02:00
Mykhailo Pylyp
b742c4021d Update tests-checklist-mykhailo.md 2021-05-26 13:07:12 +03:00
Enrico Giordani
15e07894fb Update tests-checklist-enrico.md 2021-05-26 12:06:02 +02:00
Enrico Giordani
ad11fa1651 Update tests-checklist-template.md 2021-05-26 12:05:30 +02:00
Enrico Giordani
aba6b08ef6 Update tests-checklist-template.md 2021-05-26 12:04:37 +02:00
Enrico Giordani
a2b00091d0 Update tests-checklist-template.md 2021-05-26 12:03:47 +02:00
Enrico Giordani
ddb23a34bc Update General Settings tests 2021-05-26 12:02:43 +02:00
Enrico Giordani
e0f9d3b453 Update SG tests 2021-05-26 11:59:10 +02:00
Enrico Giordani
69cbbbc2a6 Update tests-checklist-enrico.md 2021-05-26 11:58:00 +02:00
Enrico Giordani
2e6f5152cd Update SG tests 2021-05-26 11:52:03 +02:00
Mykhailo Pylyp
17ca20d256 Update tests-checklist-mykhailo.md 2021-05-26 12:51:01 +03:00
Enrico Giordani
a2ae4f0a5d Update tests-checklist-enrico.md 2021-05-26 11:50:51 +02:00
Enrico Giordani
530b0f8cc6 Update SG tests 2021-05-26 11:50:28 +02:00
Mykhailo Pylyp
d2c97d6740 Update tests-checklist-mykhailo.md 2021-05-26 12:40:38 +03:00
Mykhailo Pylyp
003307bc3f Update tests-checklist-mykhailo.md 2021-05-26 12:30:41 +03:00
Seraphima Zykova
5cc6a85e0d Update tests-checklist-seraphima.md 2021-05-26 10:28:16 +01:00
Mykhailo Pylyp
56d249786f Update tests-checklist-mykhailo.md 2021-05-26 12:16:02 +03:00
Mykhailo Pylyp
22208830ce Update tests-checklist-mykhailo.md 2021-05-26 12:03:04 +03:00
Enrico Giordani
77a8a0c6e4 Update tests-checklist-enrico.md 2021-05-26 10:52:07 +02:00
Enrico Giordani
7fc1b7dcb2 ckecklists for 0.39.0 2021-05-26 10:38:27 +02:00
Mykhailo Pylyp
1cda7ae999 Update tests-checklist-mykhailo.md 2021-04-28 17:46:00 +03:00
Seraphima Zykova
e644ffc93f Update tests-checklist-seraphima.md 2021-04-28 15:31:49 +01:00
Mykhailo Pylyp
568aee2efb Update tests-checklist-mykhailo.md 2021-04-28 17:27:36 +03:00
Enrico Giordani
d0196cd2c0 Update tests-checklist-enricogior.md 2021-04-28 15:59:42 +02:00
Enrico Giordani
5296ed0857 Update tests-checklist-template.md 2021-04-28 15:59:31 +02:00
Enrico Giordani
efcb3eba45 Update tests-checklist-template.md 2021-04-28 15:59:02 +02:00
Enrico Giordani
3a359aba41 Simplified PT Run tests 2021-04-28 15:47:46 +02:00
Enrico Giordani
75828d1651 Update tests-checklist-enricogior.md 2021-04-28 15:43:14 +02:00
Enrico Giordani
d116b074ec PT Run, split test in multiple tests 2021-04-28 15:40:57 +02:00
Enrico Giordani
05cb42fdfa Spelling 2021-04-28 15:35:13 +02:00
Enrico Giordani
8a321cf1ae Update tests-checklist-enricogior.md 2021-04-28 15:33:11 +02:00
Enrico Giordani
6e1c58e7f3 Add example to PT Run test 2021-04-28 15:28:04 +02:00
Enrico Giordani
1b2ca69970 Update tests-checklist-template.md 2021-04-28 15:27:05 +02:00
Enrico Giordani
3cb0878fbb Split a PT Run test in two tests 2021-04-28 15:25:25 +02:00
Enrico Giordani
2d745d06a1 Update tests-checklist-enricogior.md 2021-04-28 15:21:04 +02:00
Seraphima Zykova
d274f02732 Update tests-checklist-seraphima.md 2021-04-28 14:19:57 +01:00
Enrico Giordani
2159c10c81 Ad example for PowerRename test 2021-04-28 15:19:06 +02:00
Enrico Giordani
fcdf5aa2fc Update tests-checklist-enricogior.md 2021-04-28 15:05:59 +02:00
Enrico Giordani
eea174d0a2 Update tests-checklist-enricogior.md 2021-04-28 14:44:05 +02:00
Enrico Giordani
a71b96377a Remove "wmf image" test since it's not a supported format. 2021-04-28 14:38:30 +02:00
Seraphima Zykova
7c88f9c16a Update tests-checklist-seraphima.md 2021-04-28 13:27:14 +01:00
Andrey Nekrasov
1fbb7b90bb Update tests-checklist-andrey.md 2021-04-28 14:47:50 +03:00
Andrey Nekrasov
3352624a38 Update tests-checklist-andrey.md 2021-04-28 14:33:35 +03:00
Seraphima Zykova
b2902c4eb6 Update tests-checklist-seraphima.md 2021-04-28 12:23:49 +01:00
Seraphima Zykova
d2c9f57240 Update tests-checklist-seraphima.md 2021-04-28 12:14:05 +01:00
Seraphima Zykova
218cb4840e Update tests-checklist-seraphima.md 2021-04-28 12:05:31 +01:00
Andrey Nekrasov
09c738f85c Update tests-checklist-andrey.md 2021-04-28 13:45:19 +03:00
Enrico Giordani
f3975129c0 Update tests-checklist-enricogior.md 2021-04-28 12:41:06 +02:00
Mykhailo Pylyp
b40ad4d89f Update tests-checklist-mykhailo.md 2021-04-28 13:30:30 +03:00
Enrico Giordani
522754b93f Update tests-checklist-enricogior.md 2021-04-28 12:28:46 +02:00
Andrey Nekrasov
a183712447 Update tests-checklist-andrey.md 2021-04-28 13:26:02 +03:00
Enrico Giordani
a20b1a8156 Update tests-checklist-enricogior.md 2021-04-28 12:06:01 +02:00
Enrico Giordani
4e9dbd57d2 Update tests-checklist-enricogior.md 2021-04-28 12:03:45 +02:00
Enrico Giordani
b761e513b7 Update tests-checklist-enricogior.md 2021-04-28 11:57:55 +02:00
Enrico Giordani
c341ea2f09 Update tests-checklist-enricogior.md 2021-04-28 11:55:33 +02:00
Mykhailo Pylyp
19363053e6 Update tests-checklist-mykhailo.md 2021-04-28 12:53:39 +03:00
Enrico Giordani
ef4f479ed7 Update tests-checklist-enricogior.md 2021-04-28 11:50:46 +02:00
Enrico Giordani
314800d193 Update tests-checklist-enricogior.md 2021-04-28 11:49:02 +02:00
Enrico Giordani
91ab70ef16 Update tests-checklist-enricogior.md 2021-04-28 11:45:04 +02:00
Andrey Nekrasov
bfa32fe91d Update tests-checklist-andrey.md 2021-04-28 12:41:26 +03:00
Enrico Giordani
1e67634321 Update tests-checklist-seraphima.md 2021-04-28 10:18:38 +02:00
Enrico Giordani
7033d64c3c Update tests-checklist-mykhailo.md 2021-04-28 10:18:23 +02:00
Enrico Giordani
d5981c0014 Update tests-checklist-enricogior.md 2021-04-28 10:18:07 +02:00
Enrico Giordani
f34e192995 Update tests-checklist-andrey.md 2021-04-28 10:17:50 +02:00
Enrico Giordani
29651f21ea Update tests-checklist-template.md 2021-04-28 10:17:22 +02:00
Enrico Giordani
e745235803 Add term for spelling 2021-04-28 09:46:33 +02:00
Enrico Giordani
bc35feffa3 Moved checklist for testing to its own file 2021-04-28 09:41:02 +02:00
Enrico Giordani
b755078572 Add test list template 2021-04-28 09:33:34 +02:00
Enrico Giordani
188800d15e Update .gitignore 2021-04-28 09:29:52 +02:00
Deondre Davis
da5589f3b0 Update expect.txt 2021-03-27 18:53:30 -07:00
Deondre Davis
2cc4e1222f Update expect.txt 2021-03-27 18:52:52 -07:00
Deondre Davis
6a2adb2990 Update template.md 2021-03-27 18:44:48 -07:00
Deondre Davis
9428f1c195 Update template.md 2021-03-27 18:12:36 -07:00
Clint Rutkas
af59b524c1 Update template.md 2020-12-29 17:06:42 -08:00
Clint Rutkas
ac8559c35d Update template.md 2020-12-29 17:00:37 -08:00
Clint Rutkas
b8ac50467d Update template.md 2020-12-29 16:59:57 -08:00
Clint Rutkas
80e3695dc4 Update template.md 2020-12-29 16:11:52 -08:00
Clint Rutkas
ef541130a9 Update template.md 2020-12-29 14:48:23 -08:00
Clint Rutkas
7f2a28994b Create template.md 2020-12-29 14:30:43 -08:00
1727 changed files with 99576 additions and 75170 deletions

View File

@@ -95,7 +95,6 @@ OTP
Yubi
Yubico
Perplexity
Groq
svgl
# KEYS
@@ -329,16 +328,3 @@ FFF
HHH
riday
YYY
# Unicode
precomposed
# GitHub issue/PR commands
azp
feedbackhub
needinfo
reportbug
#ffmpeg
crf
nostdin

View File

@@ -565,7 +565,7 @@ perl(?:\s+-[a-zA-Z]\w*)+
regexp?\.MustCompile\((?:`[^`]*`|".*"|'.*')\)
# regex choice
# \(\?:[^)]+\|[^)]+\)
\(\?:[^)]+\|[^)]+\)
# proto
^\s*(\w+)\s\g{-1} =

View File

@@ -104,12 +104,8 @@
^src/common/ManagedCommon/ColorFormatHelper\.cs$
^src/common/notifications/BackgroundActivatorDLL/cpp\.hint$
^src/common/sysinternals/Eula/
^src/modules/cmdpal/Tests/Microsoft\.CommandPalette\.Extensions\.Toolkit\.UnitTests/FuzzyMatcherComparisonTests.cs$
^src/modules/cmdpal/Tests/Microsoft\.CommandPalette\.Extensions\.Toolkit\.UnitTests/FuzzyMatcherDiacriticsTests.cs$
^src/modules/cmdpal/doc/initial-sdk-spec/list-elements-mock-002\.pdn$
^src/modules/cmdpal/ext/SamplePagesExtension/Pages/SampleMarkdownImagesPage\.cs$
^src/modules/cmdpal/Microsoft\.CmdPal\.UI/Settings/InternalPage\.SampleData\.cs$
^src/modules/cmdpal/Tests/Microsoft\.CmdPal\.Core\.Common\.UnitTests/.*\.TestData\.cs$
^src/modules/colorPicker/ColorPickerUI/Shaders/GridShader\.cso$
^src/modules/launcher/Plugins/Microsoft\.PowerToys\.Run\.Plugin\.TimeDate/Properties/
^src/modules/MouseUtils/MouseJumpUI/MainForm\.resx$

View File

@@ -2,8 +2,8 @@ AAAAs
abcdefghjkmnpqrstuvxyz
abgr
ABlocked
ABORTIFHUNG
ABOUTBOX
ABORTIFHUNG
Abug
Acceleratorkeys
ACCEPTFILES
@@ -22,6 +22,7 @@ ADate
ADDSTRING
ADDUNDORECORD
ADifferent
adjacents
ADMINS
adml
admx
@@ -31,7 +32,6 @@ advfirewall
AFeature
affordances
AFX
agentskills
AGGREGATABLE
AHK
AHybrid
@@ -56,7 +56,6 @@ ANull
AOC
aocfnapldcnfbofgmbbllojgocaelgdd
AOklab
aot
APARTMENTTHREADED
APeriod
apicontract
@@ -64,9 +63,6 @@ apidl
APIENTRY
APIIs
Apm
APMPOWERSTATUSCHANGE
APMRESUMEAUTOMATIC
APMRESUMESUSPEND
APPBARDATA
APPEXECLINK
appext
@@ -101,6 +97,7 @@ ASSOCSTR
ASYNCWINDOWPLACEMENT
ASYNCWINDOWPOS
atl
ATX
ATRIOX
aumid
authenticode
@@ -120,10 +117,10 @@ azman
azureaiinference
azureinference
azureopenai
backticks
bbwe
BCIE
bck
backticks
BESTEFFORT
bezelled
bhid
@@ -143,19 +140,16 @@ BITSPIXEL
bla
BLACKFRAME
BLENDFUNCTION
blittable
Blockquotes
blt
bluelightreduction
bluelightreductionstate
BLURBEHIND
BLURREGION
bmi
BNumber
BODGY
BOklab
BOOTSTRAPPERINSTALLFOLDER
Bootstrappers
BOOTSTRAPPERINSTALLFOLDER
BOTTOMALIGN
boxmodel
BPBF
@@ -182,16 +176,17 @@ BYPOSITION
CALCRECT
CALG
callbackptr
cabstr
calpwstr
caub
Cangjie
CANRENAME
Carlseibert
Canvascustomlayout
CAPTUREBLT
CAPTURECHANGED
CARETBLINKING
Carlseibert
CAtl
caub
CBN
cch
CCHDEVICENAME
@@ -208,7 +203,6 @@ certmgr
cfp
CHANGECBCHAIN
changecursor
checkmarks
CHILDACTIVATE
CHILDWINDOW
CHOOSEFONT
@@ -216,14 +210,12 @@ CIBUILD
cidl
CIELCh
cim
claude
CImage
cla
CLASSDC
classguid
classmethod
CLASSNOTAVAILABLE
claude
CLEARTYPE
cleanmgr
clickable
clickonce
CLIENTEDGE
@@ -260,7 +252,6 @@ colorformat
colorhistory
colorhistorylimit
COLORKEY
colorref
comctl
comdlg
comexp
@@ -274,6 +265,7 @@ CONFIGW
CONFLICTINGMODIFIERKEY
CONFLICTINGMODIFIERSHORTCUT
CONOUT
coreclr
constexpr
contentdialog
contentfiles
@@ -281,12 +273,10 @@ CONTEXTHELP
CONTEXTMENUHANDLER
contractversion
CONTROLPARENT
Convs
copiedcolorrepresentation
coppied
copyable
COPYPEN
coreclr
COREWINDOW
Corpor
cotaskmem
@@ -295,17 +285,18 @@ countof
covrun
cpcontrols
cph
cppcoreguidelines
cplusplus
CPower
cpptools
cppvsdbg
cppwinrt
createdump
creativecommons
CREATEPROCESS
CREATESCHEDULEDTASK
CREATESTRUCT
CREATEWINDOWFAILED
creativecommons
CRECT
CRH
critsec
@@ -325,13 +316,14 @@ CURRENTDIR
CURSORINFO
cursorpos
CURSORSHOWING
cursorwrap
CURSORWRAP
customaction
CUSTOMACTIONTEST
CUSTOMFORMATPLACEHOLDER
CVal
cvd
CVirtual
CVS
CWMO
CXSCREEN
CXSMICON
@@ -340,6 +332,7 @@ CYSCREEN
CYSMICON
CYVIRTUALSCREEN
Czechia
cziplib
Dac
dacl
DAffine
@@ -348,14 +341,12 @@ datareader
datatracker
dataversion
Dayof
dbcc
DBID
DBLCLKS
DBLEPSILON
DBPROP
DBPROPIDSET
DBPROPSET
DBT
DCBA
DCOM
DComposition
@@ -365,15 +356,16 @@ Deact
debugbreak
decryptor
Dedup
dfx
Deduplicator
Deeplink
DEFAULTBOOTSTRAPPERINSTALLFOLDER
DEFAULTCOLOR
DEFAULTFLAGS
DEFAULTICON
defaultlib
DEFAULTONLY
DEFAULTSIZE
defaulttonearest
DEFAULTTONEAREST
DEFAULTTONULL
DEFAULTTOPRIMARY
DEFERERASE
@@ -395,18 +387,12 @@ DESKTOPVERTRES
devblogs
devdocs
devenv
DEVICEINTERFACE
devicetype
DEVINTERFACE
devmgmt
DEVMODE
DEVMODEW
DEVNODES
devpal
DEVTYP
dfx
DIALOGEX
diffs
digicert
DINORMAL
DISABLEASACTIONKEY
@@ -419,6 +405,7 @@ DISPLAYFREQUENCY
displayname
DISPLAYORIENTATION
divyan
djwsxzxb
Dlg
DLGFRAME
DLGMODALFRAME
@@ -431,6 +418,7 @@ DONTVALIDATEPATH
dotnet
downsampled
downsampling
Downsampled
downscale
DPICHANGED
DPIs
@@ -544,10 +532,9 @@ EXTRINSICPROPERTIES
eyetracker
FANCYZONESDRAWLAYOUTTEST
FANCYZONESEDITOR
FNumber
FARPROC
fdw
fdx
FErase
fesf
FFFF
Figma
@@ -570,7 +557,6 @@ FILESYSPATH
Filetime
FILEVERSION
FILTERMODE
FInc
findfast
findmymouse
FIXEDFILEINFO
@@ -578,8 +564,8 @@ FIXEDSYS
flac
flyouts
FMask
foundrylocal
fmtid
FNumber
FOF
FOFX
FOLDERID
@@ -590,14 +576,11 @@ FORCEMINIMIZE
FORMATDLGORD
formatetc
FORPARSING
foundrylocal
FRAMECHANGED
FRestore
frm
FROMTOUCH
fsanitize
fsmgmt
ftps
fuzzingtesting
fxf
FZE
@@ -611,13 +594,13 @@ gdi
gdiplus
GDIPVER
GDISCALED
geolocator
GETCLIENTAREAANIMATION
GETCURSEL
GETDESKWALLPAPER
GETDLGCODE
GETDPISCALEDSIZE
getfilesiginforedist
geolocator
GETHOTKEY
GETICON
GETLBTEXT
@@ -628,14 +611,11 @@ GETSCREENSAVERRUNNING
GETSECKEY
GETSTICKYKEYS
GETTEXTLENGTH
gfx
GHND
GIFs
gitmodules
GHND
GMEM
GNumber
googleai
googlegemini
Gotchas
gpedit
gpo
GPOCA
@@ -652,6 +632,8 @@ GValue
gwl
GWLP
GWLSTYLE
googleai
googlegemini
hangeul
Hanzi
Hardlines
@@ -674,13 +656,11 @@ HCRYPTPROV
hcursor
hcwhite
hdc
HDEVNOTIFY
hdr
hdrop
hdwwiz
Helpline
helptext
hgdiobj
HGFE
hglobal
hhk
@@ -729,7 +709,7 @@ hotlight
hotspot
HPAINTBUFFER
HRAWINPUT
hredraw
HREDRAW
hres
hresult
hrgn
@@ -764,7 +744,9 @@ IDCANCEL
IDD
idk
idl
IIM
idlist
ifd
IDOK
IDOn
IDR
@@ -773,16 +755,15 @@ ietf
IEXPLORE
IFACEMETHOD
IFACEMETHODIMP
ifd
IGNOREUNKNOWN
IGo
iid
IIM
Iindex
Ijwhost
ILD
IMAGEHLP
IMAGERESIZERCONTEXTMENU
IPTC
IMAGERESIZEREXT
imageresizerinput
imageresizersettings
@@ -802,7 +783,6 @@ INITGUID
INITTOLOGFONTSTRUCT
INLINEPREFIX
inlines
Inno
INPC
inproc
INPUTHARDWARE
@@ -819,6 +799,7 @@ INSTALLFOLDERTOPREVIOUSINSTALLFOLDER
INSTALLLOCATION
INSTALLMESSAGE
INSTALLPROPERTY
installscopeperuser
INSTALLSTARTMENUSHORTCUT
INSTALLSTATE
Inste
@@ -831,7 +812,6 @@ invokecommand
ipcmanager
IPREVIEW
ipreviewhandlervisualssetfont
IPTC
irow
irprops
isbi
@@ -846,12 +826,10 @@ ITHUMBNAIL
IUI
IUWP
IWIC
jeli
jfif
jgeosdfsdsgmkedfgdfgdfgbkmhcgcflmi
jjw
jobject
JOBOBJECT
jpe
jpnime
Jsons
@@ -877,15 +855,15 @@ keyvault
KILLFOCUS
killrunner
kmph
ksa
kvp
Kybd
LARGEICON
lastcodeanalysissucceeded
LASTEXITCODE
LAYOUTRTL
lbl
Lbuttondown
LCh
lbl
lcid
LCIDTo
lcl
@@ -893,7 +871,6 @@ Lclean
Ldone
Ldr
LEFTALIGN
leftclick
LEFTSCROLLBAR
LEFTTEXT
LError
@@ -902,21 +879,20 @@ LExit
lhwnd
LIBFUZZER
LIBID
lightswitch
LIMITSIZE
LIMITTEXT
lindex
lightswitch
linkid
LINKOVERLAY
LINQTo
listview
LIVEDRAW
livezoom
LIVEZOOM
LLKH
llkhf
LMEM
LMENU
lng
LOADFROMFILE
LOBYTE
localappdata
@@ -926,19 +902,21 @@ LOCATIONCHANGE
LOCKTYPE
LOGFONT
LOGFONTW
LOGMSG
logon
lon
LOGMSG
LOGPIXELSX
LOGPIXELSY
lng
lon
longdate
LONGNAMES
lowlevel
lquadrant
LOWORD
lparam
LPBITMAPINFOHEADER
LPCFHOOKPROC
lpch
LPCITEMIDLIST
LPCLSID
lpcmi
@@ -956,7 +934,6 @@ LPMONITORINFO
LPOSVERSIONINFOEXW
LPQUERY
lprc
LPrivate
LPSAFEARRAY
lpstr
lpsz
@@ -969,7 +946,6 @@ lpv
LPW
lpwcx
lpwndpl
lquadrant
LReader
LRESULT
LSTATUS
@@ -996,7 +972,6 @@ MAKELONG
MAKELPARAM
makepri
MAKEWPARAM
Malware
manifestdependency
MAPPEDTOSAMEKEY
MAPTOSAMESHORTCUT
@@ -1008,8 +983,6 @@ maxversiontested
mber
MBM
MBR
Mbuttondown
mcp
MDICHILD
MDL
mdtext
@@ -1021,12 +994,9 @@ MENUITEMINFO
MENUITEMINFOW
MERGECOPY
MERGEPAINT
Metacharacter
metadatamatters
Metadatas
Metacharacter
metadatamatters
metafile
Metacharacter
mfc
Mgmt
Microwaved
@@ -1054,7 +1024,6 @@ mmsys
mobileredirect
mockapi
MODALFRAME
modelcontextprotocol
MODESPRUNED
MONITORENUMPROC
MONITORINFO
@@ -1072,8 +1041,11 @@ mousepointer
mouseutils
MOVESIZEEND
MOVESIZESTART
muxx
muxxc
muxxh
MRM
Mrt
MRT
mru
MSAL
msc
@@ -1098,23 +1070,17 @@ MSLLHOOKSTRUCT
Mso
msrc
msstore
mstsc
msvcp
MT
MTND
MULTIPLEUSE
multizone
muxc
muxx
muxxc
muxxh
MVPs
mvvm
MVVMTK
MWBEx
MYICON
myorg
myrepo
NAMECHANGE
namespaceanddescendants
nao
@@ -1154,7 +1120,6 @@ NEWPLUSSHELLEXTENSIONWIN
newrow
nicksnettravels
NIF
nightlight
NLog
NLSTEXT
NMAKE
@@ -1193,6 +1158,7 @@ nonstd
NOOWNERZORDER
NOPARENTNOTIFY
NOPREFIX
NPU
NOREDIRECTIONBITMAP
NOREDRAW
NOREMOVE
@@ -1221,7 +1187,6 @@ nowarn
NOZORDER
NPH
npmjs
NPU
NResize
NTAPI
ntdll
@@ -1246,17 +1211,16 @@ oldpath
oldtheme
oleaut
OLECHAR
ollama
onebranch
onnx
OOBEUI
openas
opencode
OPENFILENAME
openrdp
opensource
openurl
openxmlformats
ollama
Olllama
onnx
OPTIMIZEFORINVOKE
ORPHANEDDIALOGTITLE
ORSCANS
@@ -1329,12 +1293,10 @@ pguid
phbm
phbmp
phicon
Photoshop
phwnd
pici
pidl
PIDLIST
pii
pinfo
pinvoke
pipename
@@ -1353,6 +1315,7 @@ pnid
PNMLINK
Poc
Podcasts
Photoshop
POINTERID
POINTERUPDATE
Pokedex
@@ -1360,7 +1323,6 @@ Pomodoro
Popups
POPUPWINDOW
POSITIONITEM
POWERBROADCAST
POWERRENAMECONTEXTMENU
powerrenameinput
POWERRENAMETEST
@@ -1384,7 +1346,6 @@ ppv
ppwsz
prc
Prefixer
Premul
prependpath
prepopulate
prevhost
@@ -1449,9 +1410,10 @@ pwsz
pwtd
QDC
qit
QNN
Qualcomm
QITAB
QITABENT
QNN
qoi
Quarternary
QUERYENDSESSION
@@ -1461,8 +1423,8 @@ quickaccent
QUNS
RAII
RAlt
randi
RAquadrant
randi
rasterization
Rasterize
RAWINPUTDEVICE
@@ -1470,10 +1432,8 @@ RAWINPUTHEADER
RAWMODE
RAWPATH
rbhid
Rbuttondown
rclsid
RCZOOMIT
rdp
RDW
READMODE
READOBJECTS
@@ -1503,12 +1463,10 @@ remappings
REMAPSUCCESSFUL
REMAPUNSUCCESSFUL
Remotable
remotedesktop
remoteip
Removelnk
renamable
RENAMEONCOLLISION
RENDERFULLCONTENT
reparented
reparenting
reportfileaccesses
@@ -1531,13 +1489,11 @@ rgh
rgn
rgs
rguid
rhk
RIDEV
RIGHTSCROLLBAR
riid
RKey
RNumber
rollups
rop
ROUNDSMALL
ROWSETEXT
@@ -1550,6 +1506,7 @@ rstringalpha
rstringdigit
rtb
RTLREADING
rtm
runas
rundll
rungameid
@@ -1606,8 +1563,8 @@ SETRULES
SETSCREENSAVEACTIVE
SETSTICKYKEYS
SETTEXT
SETTINGCHANGE
settingscard
SETTINGCHANGE
SETTINGSCHANGED
settingsheader
settingshotkeycontrol
@@ -1623,7 +1580,7 @@ sharpfuzz
SHCNE
SHCNF
SHCONTF
shcore
Shcore
shellapi
SHELLDETAILS
SHELLDLL
@@ -1638,7 +1595,6 @@ SHGDNF
SHGFI
SHIL
shinfo
shk
shlwapi
shobjidl
SHORTCUTATLEAST
@@ -1683,8 +1639,6 @@ SKIPOWNPROCESS
sku
SLGP
sln
slnf
slnx
SMALLICON
smartphone
smileys
@@ -1722,8 +1676,6 @@ srw
srwlock
sse
ssf
Ssn
sszzz
STACKFRAME
stackoverflow
STARTF
@@ -1734,7 +1686,6 @@ STARTUPINFOW
startupscreen
STATFLAG
STATICEDGE
staticmethod
STATSTG
stdafx
STDAPI
@@ -1752,14 +1703,12 @@ STICKYKEYS
sticpl
storelogo
stprintf
streamable
streamjsonrpc
STRINGIZE
stringtable
stringval
Strm
strret
STRSAFE
stscanf
sttngs
Stubless
@@ -1771,6 +1720,7 @@ sublang
SUBMODULEUPDATE
subresource
Superbar
suntimes
sut
svchost
SVGIn
@@ -1778,7 +1728,7 @@ SVGIO
svgz
SVSI
SWFO
swp
SWP
SWPNOSIZE
SWPNOZORDER
SWRESTORE
@@ -1797,13 +1747,14 @@ SYSKEY
syskeydown
SYSKEYUP
SYSLIB
sysmenu
SYSMENU
systemai
SYSTEMAPPS
SYSTEMMODAL
SYSTEMTIME
TARG
TARGETAPPHEADER
TARGETDIR
targetentrypoint
TARGETHEADER
targetver
@@ -1832,18 +1783,18 @@ TEXTBOXNEWLINE
textextractor
TEXTINCLUDE
tfopen
tgamma
tgz
THEMECHANGED
themeresources
THH
THICKFRAME
THEMECHANGED
THISCOMPONENT
throughs
TILEDWINDOW
TILLSON
timedate
timediff
timeunion
timeutil
TITLEBARINFO
Titlecase
@@ -1901,16 +1852,12 @@ uild
uitests
UITo
ULONGLONG
Ultrawide
UMax
UMin
ums
uncompilable
UNCPRIORITY
UNDNAME
UNICODETEXT
unins
Uninstaller
uninstalls
Uniquifies
unitconverter
@@ -1918,7 +1865,6 @@ unittests
UNLEN
UNORM
unremapped
Unsubscribes
unvirtualized
unwide
unzoom
@@ -1938,6 +1884,7 @@ USEINSTALLERFORTEST
USESHOWWINDOW
USESTDHANDLES
USRDLL
utm
UType
uuidv
uwp
@@ -1949,7 +1896,7 @@ valuegenerator
variantassignment
VARTYPE
vcamp
vcenter
VCENTER
vcgtq
VCINSTALLDIR
Vcpkg
@@ -1977,12 +1924,11 @@ visualeffects
vkey
vmovl
VMs
vnd
vorrq
VOS
vpaddlq
vqsubq
vredraw
VREDRAW
vreinterpretq
VSC
VSCBD
@@ -2004,18 +1950,18 @@ vswhere
Vtbl
WANTNUKEWARNING
WANTPALM
WASDK
wasdk
wbem
WBounds
Wca
WCE
wcex
WClass
WCRAPI
wcsicmp
wcsncpy
wcsnicmp
WCT
WCRAPI
WDA
wdm
wdp
@@ -2043,7 +1989,6 @@ WINDOWPLACEMENT
WINDOWPOSCHANGED
WINDOWPOSCHANGING
WINDOWSBUILDNUMBER
windowsml
windowssearch
windowssettings
WINDOWSTYLES
@@ -2059,8 +2004,9 @@ Winhook
WINL
winlogon
winmd
winml
WINNT
windowsml
winml
winres
winrt
winsdk
@@ -2122,22 +2068,20 @@ WTSAT
Wubi
WUX
Wwanpp
xap
XAxis
XButton
Xbuttondown
xclip
xcopy
xap
XDeployment
xdf
XDimension
xdf
XDocument
XElement
xfd
XFile
XIncrement
XLoc
xmp
XNamespace
Xoshiro
XPels
@@ -2148,23 +2092,23 @@ xsi
XSpeed
XStr
xstyler
xmp
XTimer
XUP
XVIRTUALSCREEN
XXL
xxxxxx
YAxis
ycombinator
YDimension
YIncrement
YDimension
yinle
yinyue
YPels
YPos
YResolution
YSpeed
YStr
YTimer
YStr
YVIRTUALSCREEN
ZEROINIT
zonability
@@ -2174,4 +2118,4 @@ Zoneszonabletester
Zoomin
zoomit
ZOOMITX
Zorder
Zorder

View File

@@ -273,6 +273,3 @@ St&yle
# Usernames with numbers
# 0x6f677548 is user name but user folder causes a flag
\bx6f677548\b
# Microsoft Store URLs and product IDs
ms-windows-store://\S+

View File

@@ -1,92 +0,0 @@
---
description: 'Implements fixes for GitHub issues based on implementation plans'
name: 'FixIssue'
tools: ['read', 'edit', 'search', 'execute', 'agent', 'usages', 'problems', 'changes', 'testFailure', 'github/*', 'github.vscode-pull-request-github/*']
argument-hint: 'GitHub issue number (e.g., #12345)'
infer: true
---
# FixIssue Agent
You are an **IMPLEMENTATION AGENT** specialized in executing implementation plans to fix GitHub issues.
## Identity & Expertise
- Expert at translating plans into working code
- Deep knowledge of PowerToys codebase patterns and conventions
- Skilled at writing tests, handling edge cases, and validating builds
- You follow plans precisely while handling ambiguity gracefully
## Goal
For the given **issue_number**, execute the implementation plan and produce:
1. Working code changes applied directly to the repository
2. `Generated Files/issueFix/{{issue_number}}/pr-description.md` — PR-ready description
3. `Generated Files/issueFix/{{issue_number}}/manual-steps.md` — Only if human action needed
## Core Directive
**Follow the implementation plan in `Generated Files/issueReview/{{issue_number}}/implementation-plan.md` as the single source of truth.**
If the plan doesn't exist, invoke PlanIssue agent first via `runSubagent`.
## Working Principles
- **Plan First**: Read and understand the entire implementation plan before coding
- **Validate Always**: For each change: Edit → Build → Verify → Commit. Never proceed if build fails.
- **Atomic Commits**: Each commit must be self-contained, buildable, and meaningful
- **Ask, Don't Guess**: When uncertain, insert `// TODO(Human input needed): <question>` and document in manual-steps.md
## Strategy
**Core Loop** — For every unit of work:
1. **Edit**: Make focused changes to implement one logical piece
2. **Build**: Run `tools\build\build.cmd` and check for exit code 0
3. **Verify**: Use `problems` tool for lint/compile errors; run relevant tests
4. **Commit**: Only after build passes — use `.github/prompts/create-commit-title.prompt.md`
Never skip steps. Never commit broken code. Never proceed if build fails.
**Feature-by-Feature E2E**: For big scenarios with multiple features, complete each feature end-to-end before moving to the next:
- Settings UI → Functionality → Logging → Tests (for Feature 1)
- Then repeat for Feature 2
- Benefits: Each feature is self-contained, testable, easier to review, can ship incrementally
**Large Changes** (3+ files or cross-module):
- Use `tools\build\New-WorktreeFromBranch.ps1` for isolated worktrees
- Create separate branches per feature (e.g., `issue/{{issue_number}}-export`, `issue/{{issue_number}}-import`)
- Merge feature branches back after each is validated
**Recovery**: If implementation goes wrong:
- Create a checkpoint branch before risky changes
- On failure: branch from last known-good state, cherry-pick working changes, abandon broken branch
- For complex changes, consider multiple smaller PRs
## Guidelines
**DO**:
- Follow the plan exactly
- Validate build before every commit — **NEVER commit broken code**
- Use `.github/prompts/create-commit-title.prompt.md` for commit messages
- Add comprehensive tests for changed behavior
- Use worktrees for large changes (3+ files or cross-module)
- Document deviations from plan
**DON'T**:
- Implement everything in a single massive commit
- Continue after a failed build without fixing
- Make drive-by refactors outside issue scope
- Skip tests for behavioral changes
- Add noisy logs in hot paths
- Break IPC/JSON contracts without updating both sides
- Introduce dependencies without documenting in NOTICE.md
## References
- [Build Guidelines](../../tools/build/BUILD-GUIDELINES.md) — Build commands and validation
- [Coding Style](../../doc/devdocs/development/style.md) — Formatting and conventions
- [AGENTS.md](../../AGENTS.md) — Full contributor guide
## Parameter
- **issue_number**: Extract from `#123`, `issue 123`, or plain number. If missing, ask user.

View File

@@ -1,65 +0,0 @@
---
description: 'Analyzes GitHub issues to produce overview and implementation plans'
name: 'PlanIssue'
tools: ['execute', 'read', 'edit', 'search', 'web', 'github/*', 'agent', 'github-artifacts/*', 'todo']
argument-hint: 'GitHub issue number (e.g., #12345)'
handoffs:
- label: Start Implementation
agent: FixIssue
prompt: 'Fix issue #{{issue_number}} using the implementation plan'
- label: Open Plan in Editor
agent: agent
prompt: 'Open Generated Files/issueReview/{{issue_number}}/overview.md and implementation-plan.md'
showContinueOn: false
send: true
infer: true
---
# PlanIssue Agent
You are a **PLANNING AGENT** specialized in analyzing GitHub issues and producing comprehensive planning documentation.
## Identity & Expertise
- Expert at issue triage, priority scoring, and technical analysis
- Deep knowledge of PowerToys architecture and codebase patterns
- Skilled at breaking down problems into actionable implementation steps
- You research thoroughly before planning, gathering 80% confidence before drafting
## Goal
For the given **issue_number**, produce two deliverables:
1. `Generated Files/issueReview/{{issue_number}}/overview.md` — Issue analysis with scoring
2. `Generated Files/issueReview/{{issue_number}}/implementation-plan.md` — Technical implementation plan
Above is the core interaction with the end user. If you cannot produce the files above, you fail the task. Each time, you must check whether the files exist or have been modified by the end user, without assuming you know their contents.
3. `Generated Files/issueReview/{{issue_number}}/logs/**` — logs for your diagnostic of root cause, research steps, and reasoning
## Core Directive
**Follow the template in `.github/prompts/review-issue.prompt.md` exactly.** Read it first, then apply every section as specified.
- Fetch issue details: reactions, comments, linked PRs, images, logs
- Search related code and similar past fixes
- Ask clarifying questions when ambiguous
- Identify subject matter experts via git history
<stopping_rules>
You are a PLANNING agent, NOT an implementation agent.
STOP if you catch yourself:
- Writing code or editing source files outside `Generated Files/issueReview/`
- Making assumptions without researching
- Skipping the scoring/assessment phase
Plans describe what the USER or FixIssue agent will execute later.
</stopping_rules>
## References
- [Review Issue Prompt](../.github/prompts/review-issue.prompt.md) — Template for plan structure
- [Architecture Overview](../../doc/devdocs/core/architecture.md) — System design context
- [AGENTS.md](../../AGENTS.md) — Full contributor guide
## Parameter
- **issue_number**: Extract from `#123`, `issue 123`, or plain number. If missing, ask user.

View File

@@ -1,36 +1,59 @@
---
description: 'PowerToys AI contributor guidance'
description: PowerToys AI contributor guidance.
applyTo: pullRequests
---
# PowerToys Copilot Instructions
# PowerToys - Copilot guide (concise)
Concise guidance for AI contributions. For complete details, see [AGENTS.md](../AGENTS.md).
This is the top-level guide for AI changes. Keep edits small, follow existing patterns, and cite exact paths in PRs.
## Key Rules
# Repo map (1-line per area)
- Core apps: `src/runner/**` (tray/loader), `src/settings-ui/**` (Settings app)
- Shared libs: `src/common/**`
- Modules: `src/modules/*` (one per utility; Command Palette in `src/modules/cmdpal/**`)
- Build tools/docs: `tools/**`, `doc/devdocs/**`
- Atomic PRs: one logical change, no drive-by refactors
- Add tests when changing behavior
- Keep hot paths quiet (no logging in hooks/tight loops)
# Build and test (defaults)
- Prerequisites: Visual Studio 2022 17.4+, minimal Windows 10 1803+.
- Build discipline:
- One terminal per operation (build -> test). Do not switch or open new ones mid-flow.
- After making changes, `cd` to the project folder that changed (`.csproj`/`.vcxproj`).
- Use scripts to build, synchronously block and wait in foreground for completion: `tools/build/build.ps1|.cmd` (current folder), `build-essentials.*` (once per brand new build for missing nuget packages).
- Treat build exit code 0 as success; any non-zero exit code is a failure. Read the errors log in the build folder (such as `build.*.*.errors.log`) and surface problems.
- Do not start tests or launch Runner until the previous step succeeded.
- Tests (fast and targeted):
- Find the test project by product code prefix (for example FancyZones, AdvancedPaste). Look for a sibling folder or one to two levels up named like `<Product>*UnitTests` or `<Product>*UITests`.
- Build the test project, wait for exit, then run only those tests via VS Test Explorer or `vstest.console.exe` with filters. Avoid `dotnet test` in this repo.
- Add or adjust tests when changing behavior; if skipped, state why (for example comment-only or string rename).
## Style Enforcement
# Pull requests (expectations)
- Atomic: one logical change; no drive-by refactors.
- Describe: problem, approach, risk, test evidence.
- List: touched paths if not obvious.
- C#: `src/.editorconfig`, StyleCop.Analyzers
- C++: `src/.clang-format`
- XAML: XamlStyler
# When to ask for clarification
- Ambiguous spec after scanning relevant docs (see below).
- Cross-module impact (shared enum or struct) not clear.
- Security, elevation, or installer changes.
## When to Ask for Clarification
# Logging (use existing stacks)
- C++ logging lives in `src/common/logger/**` (`Logger::info`, `Logger::warn`, `Logger::error`, `Logger::debug`). Keep hot paths quiet (hooks, tight loops).
- C# logging goes through `ManagedCommon.Logger` (`LogInfo`, `LogWarning`, `LogError`, `LogDebug`, `LogTrace`). Some UIs use injected `ILogger` via `LoggerInstance.Logger`.
- Ambiguous spec after scanning docs
- Cross-module impact unclear
- Security, elevation, or installer changes
# Docs to consult
- `tools/build/BUILD-GUIDELINES.md`
- `doc/devdocs/core/architecture.md`
- `doc/devdocs/core/runner.md`
- `doc/devdocs/core/settings/readme.md`
- `doc/devdocs/modules/readme.md`
## Component-Specific Instructions
# Language style rules
- Always enforce repo analyzers: root `.editorconfig` plus any `stylecop.json`.
- C# code follows StyleCop.Analyzers and Microsoft.CodeAnalysis.NetAnalyzers.
- C++ code honors `.clang-format` plus `.clang-tidy` (modernize/cppcoreguidelines/readability).
- Markdown files wrap at 80 characters and use ATX headers with fenced code blocks that include language tags.
- YAML files indent two spaces and add comments for complex settings while keeping keys clear.
- PowerShell scripts use Verb-Noun names and prefer single-quoted literals while documenting parameters and satisfying PSScriptAnalyzer.
These are auto-applied based on file location:
- [Runner & Settings UI](.github/instructions/runner-settings-ui.instructions.md)
- [Common Libraries](.github/instructions/common-libraries.instructions.md)
## Detailed Documentation
- [Architecture](../doc/devdocs/core/architecture.md)
- [Coding Style](../doc/devdocs/development/style.md)
# Done checklist (self review before finishing)
- Build clean? Tests updated or passed? No unintended formatting? Any new dependency? Documented skips?

View File

@@ -1,261 +0,0 @@
---
description: 'Guidelines for creating high-quality Agent Skills for GitHub Copilot'
applyTo: '**/.github/skills/**/SKILL.md, **/.claude/skills/**/SKILL.md'
---
# Agent Skills File Guidelines
Instructions for creating effective and portable Agent Skills that enhance GitHub Copilot with specialized capabilities, workflows, and bundled resources.
## What Are Agent Skills?
Agent Skills are self-contained folders with instructions and bundled resources that teach AI agents specialized capabilities. Unlike custom instructions (which define coding standards), skills enable task-specific workflows that can include scripts, examples, templates, and reference data.
Key characteristics:
- **Portable**: Works across VS Code, Copilot CLI, and Copilot coding agent
- **Progressive loading**: Only loaded when relevant to the user's request
- **Resource-bundled**: Can include scripts, templates, examples alongside instructions
- **On-demand**: Activated automatically based on prompt relevance
## Directory Structure
Skills are stored in specific locations:
| Location | Scope | Recommendation |
|----------|-------|----------------|
| `.github/skills/<skill-name>/` | Project/repository | Recommended for project skills |
| `.claude/skills/<skill-name>/` | Project/repository | Legacy, for backward compatibility |
| `~/.github/skills/<skill-name>/` | Personal (user-wide) | Recommended for personal skills |
| `~/.claude/skills/<skill-name>/` | Personal (user-wide) | Legacy, for backward compatibility |
Each skill **must** have its own subdirectory containing at minimum a `SKILL.md` file.
## Required SKILL.md Format
### Frontmatter (Required)
```yaml
---
name: webapp-testing
description: Toolkit for testing local web applications using Playwright. Use when asked to verify frontend functionality, debug UI behavior, capture browser screenshots, check for visual regressions, or view browser console logs. Supports Chrome, Firefox, and WebKit browsers.
license: Complete terms in LICENSE.txt
---
```
| Field | Required | Constraints |
|-------|----------|-------------|
| `name` | Yes | Lowercase, hyphens for spaces, max 64 characters (e.g., `webapp-testing`) |
| `description` | Yes | Clear description of capabilities AND use cases, max 1024 characters |
| `license` | No | Reference to LICENSE.txt (e.g., `Complete terms in LICENSE.txt`) or SPDX identifier |
### Description Best Practices
**CRITICAL**: The `description` field is the PRIMARY mechanism for automatic skill discovery. Copilot reads ONLY the `name` and `description` to decide whether to load a skill. If your description is vague, the skill will never be activated.
**What to include in description:**
1. **WHAT** the skill does (capabilities)
2. **WHEN** to use it (specific triggers, scenarios, file types, or user requests)
3. **Keywords** that users might mention in their prompts
**Good description:**
```yaml
description: Toolkit for testing local web applications using Playwright. Use when asked to verify frontend functionality, debug UI behavior, capture browser screenshots, check for visual regressions, or view browser console logs. Supports Chrome, Firefox, and WebKit browsers.
```
**Poor description:**
```yaml
description: Web testing helpers
```
The poor description fails because:
- No specific triggers (when should Copilot load this?)
- No keywords (what user prompts would match?)
- No capabilities (what can it actually do?)
### Body Content
The body contains detailed instructions that Copilot loads AFTER the skill is activated. Recommended sections:
| Section | Purpose |
|---------|---------|
| `# Title` | Brief overview of what this skill enables |
| `## When to Use This Skill` | List of scenarios (reinforces description triggers) |
| `## Prerequisites` | Required tools, dependencies, environment setup |
| `## Step-by-Step Workflows` | Numbered steps for common tasks |
| `## Troubleshooting` | Common issues and solutions table |
| `## References` | Links to bundled docs or external resources |
## Bundling Resources
Skills can include additional files that Copilot accesses on-demand:
### Supported Resource Types
| Folder | Purpose | Loaded into Context? | Example Files |
|--------|---------|---------------------|---------------|
| `scripts/` | Executable automation that performs specific operations | When executed | `helper.py`, `validate.sh`, `build.ts` |
| `references/` | Documentation the AI agent reads to inform decisions | Yes, when referenced | `api_reference.md`, `schema.md`, `workflow_guide.md` |
| `assets/` | **Static files used AS-IS** in output (not modified by the AI agent) | No | `logo.png`, `brand-template.pptx`, `custom-font.ttf` |
| `templates/` | **Starter code/scaffolds that the AI agent MODIFIES** and builds upon | Yes, when referenced | `viewer.html` (insert algorithm), `hello-world/` (extend) |
### Directory Structure Example
```
.github/skills/my-skill/
├── SKILL.md # Required: Main instructions
├── LICENSE.txt # Recommended: License terms (Apache 2.0 typical)
├── scripts/ # Optional: Executable automation
│ ├── helper.py # Python script
│ └── helper.ps1 # PowerShell script
├── references/ # Optional: Documentation loaded into context
│ ├── api_reference.md
│ ├── step1-setup.md # Detailed workflow (>3 steps)
│ └── step2-deployment.md
├── assets/ # Optional: Static files used AS-IS in output
│ ├── baseline.png # Reference image for comparison
│ └── report-template.html
└── templates/ # Optional: Starter code the AI agent modifies
├── scaffold.py # Code scaffold the AI agent customizes
└── config.template # Config template the AI agent fills in
```
> **LICENSE.txt**: When creating a skill, download the Apache 2.0 license text from https://www.apache.org/licenses/LICENSE-2.0.txt and save as `LICENSE.txt`. Update the copyright year and owner in the appendix section.
### Assets vs Templates: Key Distinction
**Assets** are static resources **consumed unchanged** in the output:
- A `logo.png` that gets embedded into a generated document
- A `report-template.html` copied as output format
- A `custom-font.ttf` applied to text rendering
**Templates** are starter code/scaffolds that **the AI agent actively modifies**:
- A `scaffold.py` where the AI agent inserts logic
- A `config.template` where the AI agent fills in values based on user requirements
- A `hello-world/` project directory that the AI agent extends with new features
**Rule of thumb**: If the AI agent reads and builds upon the file content → `templates/`. If the file is used as-is in output → `assets/`.
### Referencing Resources in SKILL.md
Use relative paths to reference files within the skill directory:
```markdown
## Available Scripts
Run the [helper script](./scripts/helper.py) to automate common tasks.
See [API reference](./references/api_reference.md) for detailed documentation.
Use the [scaffold](./templates/scaffold.py) as a starting point.
```
## Progressive Loading Architecture
Skills use three-level loading for efficiency:
| Level | What Loads | When |
|-------|------------|------|
| 1. Discovery | `name` and `description` only | Always (lightweight metadata) |
| 2. Instructions | Full `SKILL.md` body | When request matches description |
| 3. Resources | Scripts, examples, docs | Only when Copilot references them |
This means:
- Install many skills without consuming context
- Only relevant content loads per task
- Resources don't load until explicitly needed
## Content Guidelines
### Writing Style
- Use imperative mood: "Run", "Create", "Configure" (not "You should run")
- Be specific and actionable
- Include exact commands with parameters
- Show expected outputs where helpful
- Keep sections focused and scannable
### Script Requirements
When including scripts, prefer cross-platform languages:
| Language | Use Case |
|----------|----------|
| Python | Complex automation, data processing |
| pwsh | PowerShell Core scripting |
| Node.js | JavaScript-based tooling |
| Bash/Shell | Simple automation tasks |
Best practices:
- Include help/usage documentation (`--help` flag)
- Handle errors gracefully with clear messages
- Avoid storing credentials or secrets
- Use relative paths where possible
### When to Bundle Scripts
Include scripts in your skill when:
- The same code would be rewritten repeatedly by the agent
- Deterministic reliability is critical (e.g., file manipulation, API calls)
- Complex logic benefits from being pre-tested rather than generated each time
- The operation has a self-contained purpose that can evolve independently
- Testability matters — scripts can be unit tested and validated
- Predictable behavior is preferred over dynamic generation
Scripts enable evolution: even simple operations benefit from being implemented as scripts when they may grow in complexity, need consistent behavior across invocations, or require future extensibility.
### Security Considerations
- Scripts rely on existing credential helpers (no credential storage)
- Include `--force` flags only for destructive operations
- Warn users before irreversible actions
- Document any network operations or external calls
## Common Patterns
### Parameter Table Pattern
Document parameters clearly:
```markdown
| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| `--input` | Yes | - | Input file or URL to process |
| `--action` | Yes | - | Action to perform |
| `--verbose` | No | `false` | Enable verbose output |
```
## Validation Checklist
Before publishing a skill:
- [ ] `SKILL.md` has valid frontmatter with `name` and `description`
- [ ] `name` is lowercase with hyphens, ≤64 characters
- [ ] `description` clearly states **WHAT** it does, **WHEN** to use it, and relevant **KEYWORDS**
- [ ] Body includes when to use, prerequisites, and step-by-step workflows
- [ ] SKILL.md body kept under 500 lines (split large content into `references/` folder)
- [ ] Large workflows (>5 steps) split into `references/` folder with clear links from SKILL.md
- [ ] Scripts include help documentation and error handling
- [ ] Relative paths used for all resource references
- [ ] No hardcoded credentials or secrets
## Workflow Execution Pattern
When executing multi-step workflows, create a TODO list where each step references the relevant documentation:
```markdown
## TODO
- [ ] Step 1: Configure environment - see [workflow-setup.md](./references/workflow-setup.md#environment)
- [ ] Step 2: Build project - see [workflow-setup.md](./references/workflow-setup.md#build)
- [ ] Step 3: Deploy to staging - see [workflow-deployment.md](./references/workflow-deployment.md#staging)
- [ ] Step 4: Run validation - see [workflow-deployment.md](./references/workflow-deployment.md#validation)
- [ ] Step 5: Deploy to production - see [workflow-deployment.md](./references/workflow-deployment.md#production)
```
This ensures traceability and allows resuming workflows if interrupted.
## Related Resources
- [Agent Skills Specification](https://agentskills.io/)
- [VS Code Agent Skills Documentation](https://code.visualstudio.com/docs/copilot/customization/agent-skills)
- [Reference Skills Repository](https://github.com/anthropics/skills)
- [Awesome Copilot Skills](https://github.com/github/awesome-copilot/blob/main/docs/README.skills.md)

View File

@@ -1,791 +0,0 @@
---
description: 'Guidelines for creating custom agent files for GitHub Copilot'
applyTo: '**/*.agent.md'
---
# Custom Agent File Guidelines
Instructions for creating effective and maintainable custom agent files that provide specialized expertise for specific development tasks in GitHub Copilot.
## Project Context
- Target audience: Developers creating custom agents for GitHub Copilot
- File format: Markdown with YAML frontmatter
- File naming convention: lowercase with hyphens (e.g., `test-specialist.agent.md`)
- Location: `.github/agents/` directory (repository-level) or `agents/` directory (organization/enterprise-level)
- Purpose: Define specialized agents with tailored expertise, tools, and instructions for specific tasks
- Official documentation: https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-custom-agents
## Required Frontmatter
Every agent file must include YAML frontmatter with the following fields:
```yaml
---
description: 'Brief description of the agent purpose and capabilities'
name: 'Agent Display Name'
tools: ['read', 'edit', 'search']
model: 'Claude Sonnet 4.5'
target: 'vscode'
infer: true
---
```
### Core Frontmatter Properties
#### **description** (REQUIRED)
- Single-quoted string, clearly stating the agent's purpose and domain expertise
- Should be concise (50-150 characters) and actionable
- Example: `'Focuses on test coverage, quality, and testing best practices'`
#### **name** (OPTIONAL)
- Display name for the agent in the UI
- If omitted, defaults to filename (without `.md` or `.agent.md`)
- Use title case and be descriptive
- Example: `'Testing Specialist'`
#### **tools** (OPTIONAL)
- List of tool names or aliases the agent can use
- Supports comma-separated string or YAML array format
- If omitted, agent has access to all available tools
- See "Tool Configuration" section below for details
#### **model** (STRONGLY RECOMMENDED)
- Specifies which AI model the agent should use
- Supported in VS Code, JetBrains IDEs, Eclipse, and Xcode
- Example: `'Claude Sonnet 4.5'`, `'gpt-4'`, `'gpt-4o'`
- Choose based on agent complexity and required capabilities
#### **target** (OPTIONAL)
- Specifies target environment: `'vscode'` or `'github-copilot'`
- If omitted, agent is available in both environments
- Use when agent has environment-specific features
#### **infer** (OPTIONAL)
- Boolean controlling whether Copilot can automatically use this agent based on context
- Default: `true` if omitted
- Set to `false` to require manual agent selection
#### **metadata** (OPTIONAL, GitHub.com only)
- Object with name-value pairs for agent annotation
- Example: `metadata: { category: 'testing', version: '1.0' }`
- Not supported in VS Code
#### **mcp-servers** (OPTIONAL, Organization/Enterprise only)
- Configure MCP servers available only to this agent
- Only supported for organization/enterprise level agents
- See "MCP Server Configuration" section below
## Tool Configuration
### Tool Specification Strategies
**Enable all tools** (default):
```yaml
# Omit tools property entirely, or use:
tools: ['*']
```
**Enable specific tools**:
```yaml
tools: ['read', 'edit', 'search', 'execute']
```
**Enable MCP server tools**:
```yaml
tools: ['read', 'edit', 'github/*', 'playwright/navigate']
```
**Disable all tools**:
```yaml
tools: []
```
### Standard Tool Aliases
All aliases are case-insensitive:
| Alias | Alternative Names | Category | Description |
|-------|------------------|----------|-------------|
| `execute` | shell, Bash, powershell | Shell execution | Execute commands in appropriate shell |
| `read` | Read, NotebookRead, view | File reading | Read file contents |
| `edit` | Edit, MultiEdit, Write, NotebookEdit | File editing | Edit and modify files |
| `search` | Grep, Glob, search | Code search | Search for files or text in files |
| `agent` | custom-agent, Task | Agent invocation | Invoke other custom agents |
| `web` | WebSearch, WebFetch | Web access | Fetch web content and search |
| `todo` | TodoWrite | Task management | Create and manage task lists (VS Code only) |
### Built-in MCP Server Tools
**GitHub MCP Server**:
```yaml
tools: ['github/*'] # All GitHub tools
tools: ['github/get_file_contents', 'github/search_repositories'] # Specific tools
```
- All read-only tools available by default
- Token scoped to source repository
**Playwright MCP Server**:
```yaml
tools: ['playwright/*'] # All Playwright tools
tools: ['playwright/navigate', 'playwright/screenshot'] # Specific tools
```
- Configured to access localhost only
- Useful for browser automation and testing
### Tool Selection Best Practices
- **Principle of Least Privilege**: Only enable tools necessary for the agent's purpose
- **Security**: Limit `execute` access unless explicitly required
- **Focus**: Fewer tools = clearer agent purpose and better performance
- **Documentation**: Comment why specific tools are required for complex configurations
## Sub-Agent Invocation (Agent Orchestration)
Agents can invoke other agents using `runSubagent` to orchestrate multi-step workflows.
### How It Works
Include `agent` in tools list to enable sub-agent invocation:
```yaml
tools: ['read', 'edit', 'search', 'agent']
```
Then invoke other agents with `runSubagent`:
```javascript
const result = await runSubagent({
description: 'What this step does',
prompt: `You are the [Specialist] specialist.
Context:
- Parameter: ${parameterValue}
- Input: ${inputPath}
- Output: ${outputPath}
Task:
1. Do the specific work
2. Write results to output location
3. Return summary of completion`
});
```
### Basic Pattern
Structure each sub-agent call with:
1. **description**: Clear one-line purpose of the sub-agent invocation
2. **prompt**: Detailed instructions with substituted variables
The prompt should include:
- Who the sub-agent is (specialist role)
- What context it needs (parameters, paths)
- What to do (concrete tasks)
- Where to write output
- What to return (summary)
### Example: Multi-Step Processing
```javascript
// Step 1: Process data
const processing = await runSubagent({
description: 'Transform raw input data',
prompt: `You are the Data Processor specialist.
Project: ${projectName}
Input: ${basePath}/raw/
Output: ${basePath}/processed/
Task:
1. Read all files from input directory
2. Apply transformations
3. Write processed files to output
4. Create summary: ${basePath}/processed/summary.md
Return: Number of files processed and any issues found`
});
// Step 2: Analyze (depends on Step 1)
const analysis = await runSubagent({
description: 'Analyze processed data',
prompt: `You are the Data Analyst specialist.
Project: ${projectName}
Input: ${basePath}/processed/
Output: ${basePath}/analysis/
Task:
1. Read processed files from input
2. Generate analysis report
3. Write to: ${basePath}/analysis/report.md
Return: Key findings and identified patterns`
});
```
### Key Points
- **Pass variables in prompts**: Use `${variableName}` for all dynamic values
- **Keep prompts focused**: Clear, specific tasks for each sub-agent
- **Return summaries**: Each sub-agent should report what it accomplished
- **Sequential execution**: Use `await` to maintain order when steps depend on each other
- **Error handling**: Check results before proceeding to dependent steps
### ⚠️ Tool Availability Requirement
**Critical**: If a sub-agent requires specific tools (e.g., `edit`, `execute`, `search`), the orchestrator must include those tools in its own `tools` list. Sub-agents cannot access tools that aren't available to their parent orchestrator.
**Example**:
```yaml
# If your sub-agents need to edit files, execute commands, or search code
tools: ['read', 'edit', 'search', 'execute', 'agent']
```
The orchestrator's tool permissions act as a ceiling for all invoked sub-agents. Plan your tool list carefully to ensure all sub-agents have the tools they need.
### ⚠️ Important Limitation
**Sub-agent orchestration is NOT suitable for large-scale data processing.** Avoid using `runSubagent` when:
- Processing hundreds or thousands of files
- Handling large datasets
- Performing bulk transformations on big codebases
- Orchestrating more than 5-10 sequential steps
Each sub-agent call adds latency and context overhead. For high-volume processing, implement logic directly in a single agent instead. Use orchestration only for coordinating specialized tasks on focused, manageable datasets.
## Agent Prompt Structure
The markdown content below the frontmatter defines the agent's behavior, expertise, and instructions. Well-structured prompts typically include:
1. **Agent Identity and Role**: Who the agent is and its primary role
2. **Core Responsibilities**: What specific tasks the agent performs
3. **Approach and Methodology**: How the agent works to accomplish tasks
4. **Guidelines and Constraints**: What to do/avoid and quality standards
5. **Output Expectations**: Expected output format and quality
### Prompt Writing Best Practices
- **Be Specific and Direct**: Use imperative mood ("Analyze", "Generate"); avoid vague terms
- **Define Boundaries**: Clearly state scope limits and constraints
- **Include Context**: Explain domain expertise and reference relevant frameworks
- **Focus on Behavior**: Describe how the agent should think and work
- **Use Structured Format**: Headers, bullets, and lists make prompts scannable
## Variable Definition and Extraction
Agents can define dynamic parameters to extract values from user input and use them throughout the agent's behavior and sub-agent communications. This enables flexible, context-aware agents that adapt to user-provided data.
### When to Use Variables
**Use variables when**:
- Agent behavior depends on user input
- Need to pass dynamic values to sub-agents
- Want to make agents reusable across different contexts
- Require parameterized workflows
- Need to track or reference user-provided context
**Examples**:
- Extract project name from user prompt
- Capture certification name for pipeline processing
- Identify file paths or directories
- Extract configuration options
- Parse feature names or module identifiers
### Variable Declaration Pattern
Define variables section early in the agent prompt to document expected parameters:
```markdown
# Agent Name
## Dynamic Parameters
- **Parameter Name**: Description and usage
- **Another Parameter**: How it's extracted and used
## Your Mission
Process [PARAMETER_NAME] to accomplish [task].
```
### Variable Extraction Methods
#### 1. **Explicit User Input**
Ask the user to provide the variable if not detected in the prompt:
```markdown
## Your Mission
Process the project by analyzing your codebase.
### Step 1: Identify Project
If no project name is provided, **ASK THE USER** for:
- Project name or identifier
- Base path or directory location
- Configuration type (if applicable)
Use this information to contextualize all subsequent tasks.
```
#### 2. **Implicit Extraction from Prompt**
Automatically extract variables from the user's natural language input:
```javascript
// Example: Extract certification name from user input
const userInput = "Process My Certification";
// Extract key information
const certificationName = extractCertificationName(userInput);
// Result: "My Certification"
const basePath = `certifications/${certificationName}`;
// Result: "certifications/My Certification"
```
#### 3. **Contextual Variable Resolution**
Use file context or workspace information to derive variables:
```markdown
## Variable Resolution Strategy
1. **From User Prompt**: First, look for explicit mentions in user input
2. **From File Context**: Check current file name or path
3. **From Workspace**: Use workspace folder or active project
4. **From Settings**: Reference configuration files
5. **Ask User**: If all else fails, request missing information
```
### Using Variables in Agent Prompts
#### Variable Substitution in Instructions
Use template variables in agent prompts to make them dynamic:
```markdown
# Agent Name
## Dynamic Parameters
- **Project Name**: ${projectName}
- **Base Path**: ${basePath}
- **Output Directory**: ${outputDir}
## Your Mission
Process the **${projectName}** project located at `${basePath}`.
## Process Steps
1. Read input from: `${basePath}/input/`
2. Process files according to project configuration
3. Write results to: `${outputDir}/`
4. Generate summary report
## Quality Standards
- Maintain project-specific coding standards for **${projectName}**
- Follow directory structure: `${basePath}/[structure]`
```
#### Passing Variables to Sub-Agents
When invoking a sub-agent, pass all context through template variables in the prompt:
```javascript
// Extract and prepare variables
const basePath = `projects/${projectName}`;
const inputPath = `${basePath}/src/`;
const outputPath = `${basePath}/docs/`;
// Pass to sub-agent with all variables substituted
const result = await runSubagent({
description: 'Generate project documentation',
prompt: `You are the Documentation specialist.
Project: ${projectName}
Input: ${inputPath}
Output: ${outputPath}
Task:
1. Read source files from ${inputPath}
2. Generate comprehensive documentation
3. Write to ${outputPath}/index.md
4. Include code examples and usage guides
Return: Summary of documentation generated (file count, word count)`
});
```
The sub-agent receives all necessary context embedded in the prompt. Variables are resolved before sending the prompt, so the sub-agent works with concrete paths and values, not variable placeholders.
### Real-World Example: Code Review Orchestrator
Example of a simple orchestrator that validates code through multiple specialized agents:
```javascript
async function reviewCodePipeline(repositoryName, prNumber) {
const basePath = `projects/${repositoryName}/pr-${prNumber}`;
// Step 1: Security Review
const security = await runSubagent({
description: 'Scan for security vulnerabilities',
prompt: `You are the Security Reviewer specialist.
Repository: ${repositoryName}
PR: ${prNumber}
Code: ${basePath}/changes/
Task:
1. Scan code for OWASP Top 10 vulnerabilities
2. Check for injection attacks, auth flaws
3. Write findings to ${basePath}/security-review.md
Return: List of critical, high, and medium issues found`
});
// Step 2: Test Coverage Check
const coverage = await runSubagent({
description: 'Verify test coverage for changes',
prompt: `You are the Test Coverage specialist.
Repository: ${repositoryName}
PR: ${prNumber}
Changes: ${basePath}/changes/
Task:
1. Analyze code coverage for modified files
2. Identify untested critical paths
3. Write report to ${basePath}/coverage-report.md
Return: Current coverage percentage and gaps`
});
// Step 3: Aggregate Results
const finalReport = await runSubagent({
description: 'Compile all review findings',
prompt: `You are the Review Aggregator specialist.
Repository: ${repositoryName}
Reports: ${basePath}/*.md
Task:
1. Read all review reports from ${basePath}/
2. Synthesize findings into single report
3. Determine overall verdict (APPROVE/NEEDS_FIXES/BLOCK)
4. Write to ${basePath}/final-review.md
Return: Final verdict and executive summary`
});
return finalReport;
}
```
This pattern applies to any orchestration scenario: extract variables, call sub-agents with clear context, await results.
### Variable Best Practices
#### 1. **Clear Documentation**
Always document what variables are expected:
```markdown
## Required Variables
- **projectName**: The name of the project (string, required)
- **basePath**: Root directory for project files (path, required)
## Optional Variables
- **mode**: Processing mode - quick/standard/detailed (enum, default: standard)
- **outputFormat**: Output format - markdown/json/html (enum, default: markdown)
## Derived Variables
- **outputDir**: Automatically set to ${basePath}/output
- **logFile**: Automatically set to ${basePath}/.log.md
```
#### 2. **Consistent Naming**
Use consistent variable naming conventions:
```javascript
// Good: Clear, descriptive naming
const variables = {
projectName, // What project to work on
basePath, // Where project files are located
outputDirectory, // Where to save results
processingMode, // How to process (detail level)
configurationPath // Where config files are
};
// Avoid: Ambiguous or inconsistent
const bad_variables = {
name, // Too generic
path, // Unclear which path
mode, // Too short
config // Too vague
};
```
#### 3. **Validation and Constraints**
Document valid values and constraints:
```markdown
## Variable Constraints
**projectName**:
- Type: string (alphanumeric, hyphens, underscores allowed)
- Length: 1-100 characters
- Required: yes
- Pattern: `/^[a-zA-Z0-9_-]+$/`
**processingMode**:
- Type: enum
- Valid values: "quick" (< 5min), "standard" (5-15min), "detailed" (15+ min)
- Default: "standard"
- Required: no
```
## MCP Server Configuration (Organization/Enterprise Only)
MCP servers extend agent capabilities with additional tools. Only supported for organization and enterprise-level agents.
### Configuration Format
```yaml
---
name: my-custom-agent
description: 'Agent with MCP integration'
tools: ['read', 'edit', 'custom-mcp/tool-1']
mcp-servers:
custom-mcp:
type: 'local'
command: 'some-command'
args: ['--arg1', '--arg2']
tools: ["*"]
env:
ENV_VAR_NAME: ${{ secrets.API_KEY }}
---
```
### MCP Server Properties
- **type**: Server type (`'local'` or `'stdio'`)
- **command**: Command to start the MCP server
- **args**: Array of command arguments
- **tools**: Tools to enable from this server (`["*"]` for all)
- **env**: Environment variables (supports secrets)
### Environment Variables and Secrets
Secrets must be configured in repository settings under "copilot" environment.
**Supported syntax**:
```yaml
env:
# Environment variable only
VAR_NAME: COPILOT_MCP_ENV_VAR_VALUE
# Variable with header
VAR_NAME: $COPILOT_MCP_ENV_VAR_VALUE
VAR_NAME: ${COPILOT_MCP_ENV_VAR_VALUE}
# GitHub Actions-style (YAML only)
VAR_NAME: ${{ secrets.COPILOT_MCP_ENV_VAR_VALUE }}
VAR_NAME: ${{ var.COPILOT_MCP_ENV_VAR_VALUE }}
```
## File Organization and Naming
### Repository-Level Agents
- Location: `.github/agents/`
- Scope: Available only in the specific repository
- Access: Uses repository-configured MCP servers
### Organization/Enterprise-Level Agents
- Location: `.github-private/agents/` (then move to `agents/` root)
- Scope: Available across all repositories in org/enterprise
- Access: Can configure dedicated MCP servers
### Naming Conventions
- Use lowercase with hyphens: `test-specialist.agent.md`
- Name should reflect agent purpose
- Filename becomes default agent name (if `name` not specified)
- Allowed characters: `.`, `-`, `_`, `a-z`, `A-Z`, `0-9`
## Agent Processing and Behavior
### Versioning
- Based on Git commit SHAs for the agent file
- Create branches/tags for different agent versions
- Instantiated using latest version for repository/branch
- PR interactions use same agent version for consistency
### Name Conflicts
Priority (highest to lowest):
1. Repository-level agent
2. Organization-level agent
3. Enterprise-level agent
Lower-level configurations override higher-level ones with the same name.
### Tool Processing
- `tools` list filters available tools (built-in and MCP)
- No tools specified = all tools enabled
- Empty list (`[]`) = all tools disabled
- Specific list = only those tools enabled
- Unrecognized tool names are ignored (allows environment-specific tools)
### MCP Server Processing Order
1. Out-of-the-box MCP servers (e.g., GitHub MCP)
2. Custom agent MCP configuration (org/enterprise only)
3. Repository-level MCP configurations
Each level can override settings from previous levels.
## Agent Creation Checklist
### Frontmatter
- [ ] `description` field present and descriptive (50-150 chars)
- [ ] `description` wrapped in single quotes
- [ ] `name` specified (optional but recommended)
- [ ] `tools` configured appropriately (or intentionally omitted)
- [ ] `model` specified for optimal performance
- [ ] `target` set if environment-specific
- [ ] `infer` set to `false` if manual selection required
### Prompt Content
- [ ] Clear agent identity and role defined
- [ ] Core responsibilities listed explicitly
- [ ] Approach and methodology explained
- [ ] Guidelines and constraints specified
- [ ] Output expectations documented
- [ ] Examples provided where helpful
- [ ] Instructions are specific and actionable
- [ ] Scope and boundaries clearly defined
- [ ] Total content under 30,000 characters
### File Structure
- [ ] Filename follows lowercase-with-hyphens convention
- [ ] File placed in correct directory (`.github/agents/` or `agents/`)
- [ ] Filename uses only allowed characters
- [ ] File extension is `.agent.md`
### Quality Assurance
- [ ] Agent purpose is unique and not duplicative
- [ ] Tools are minimal and necessary
- [ ] Instructions are clear and unambiguous
- [ ] Agent has been tested with representative tasks
- [ ] Documentation references are current
- [ ] Security considerations addressed (if applicable)
## Common Agent Patterns
### Testing Specialist
**Purpose**: Focus on test coverage and quality
**Tools**: All tools (for comprehensive test creation)
**Approach**: Analyze, identify gaps, write tests, avoid production code changes
### Implementation Planner
**Purpose**: Create detailed technical plans and specifications
**Tools**: Limited to `['read', 'search', 'edit']`
**Approach**: Analyze requirements, create documentation, avoid implementation
### Code Reviewer
**Purpose**: Review code quality and provide feedback
**Tools**: `['read', 'search']` only
**Approach**: Analyze, suggest improvements, no direct modifications
### Refactoring Specialist
**Purpose**: Improve code structure and maintainability
**Tools**: `['read', 'search', 'edit']`
**Approach**: Analyze patterns, propose refactorings, implement safely
### Security Auditor
**Purpose**: Identify security issues and vulnerabilities
**Tools**: `['read', 'search', 'web']`
**Approach**: Scan code, check against OWASP, report findings
## Common Mistakes to Avoid
### Frontmatter Errors
- ❌ Missing `description` field
- ❌ Description not wrapped in quotes
- ❌ Invalid tool names without checking documentation
- ❌ Incorrect YAML syntax (indentation, quotes)
### Tool Configuration Issues
- ❌ Granting excessive tool access unnecessarily
- ❌ Missing required tools for agent's purpose
- ❌ Not using tool aliases consistently
- ❌ Forgetting MCP server namespace (`server-name/tool`)
### Prompt Content Problems
- ❌ Vague, ambiguous instructions
- ❌ Conflicting or contradictory guidelines
- ❌ Lack of clear scope definition
- ❌ Missing output expectations
- ❌ Overly verbose instructions (exceeding character limits)
- ❌ No examples or context for complex tasks
### Organizational Issues
- ❌ Filename doesn't reflect agent purpose
- ❌ Wrong directory (confusing repo vs org level)
- ❌ Using spaces or special characters in filename
- ❌ Duplicate agent names causing conflicts
## Testing and Validation
### Manual Testing
1. Create the agent file with proper frontmatter
2. Reload VS Code or refresh GitHub.com
3. Select the agent from the dropdown in Copilot Chat
4. Test with representative user queries
5. Verify tool access works as expected
6. Confirm output meets expectations
### Integration Testing
- Test agent with different file types in scope
- Verify MCP server connectivity (if configured)
- Check agent behavior with missing context
- Test error handling and edge cases
- Validate agent switching and handoffs
### Quality Checks
- Run through agent creation checklist
- Review against common mistakes list
- Compare with example agents in repository
- Get peer review for complex agents
- Document any special configuration needs
## Additional Resources
### Official Documentation
- [Creating Custom Agents](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-custom-agents)
- [Custom Agents Configuration](https://docs.github.com/en/copilot/reference/custom-agents-configuration)
- [Custom Agents in VS Code](https://code.visualstudio.com/docs/copilot/customization/custom-agents)
- [MCP Integration](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/extend-coding-agent-with-mcp)
### Community Resources
- [Awesome Copilot Agents Collection](https://github.com/github/awesome-copilot/tree/main/agents)
- [Customization Library Examples](https://docs.github.com/en/copilot/tutorials/customization-library/custom-agents)
- [Your First Custom Agent Tutorial](https://docs.github.com/en/copilot/tutorials/customization-library/custom-agents/your-first-custom-agent)
### Related Files
- [Prompt Files Guidelines](./prompt.instructions.md) - For creating prompt files
- [Instructions Guidelines](./instructions.instructions.md) - For creating instruction files
## Version Compatibility Notes
### GitHub.com (Coding Agent)
- ✅ Fully supports all standard frontmatter properties
- ✅ Repository and org/enterprise level agents
- ✅ MCP server configuration (org/enterprise)
- ❌ Does not support `model`, `argument-hint`, `handoffs` properties
### VS Code / JetBrains / Eclipse / Xcode
- ✅ Supports `model` property for AI model selection
- ✅ Supports `argument-hint` and `handoffs` properties
- ✅ User profile and workspace-level agents
- ❌ Cannot configure MCP servers at repository level
- ⚠️ Some properties may behave differently
When creating agents for multiple environments, focus on common properties and test in all target environments. Use `target` property to create environment-specific agents when necessary.

View File

@@ -1,187 +0,0 @@
---
description: 'Best practices for Azure DevOps Pipeline YAML files'
applyTo: '**/azure-pipelines.yml, **/azure-pipelines*.yml, **/*.pipeline.yml'
---
# Azure DevOps Pipeline YAML Best Practices
Guidelines for creating maintainable, secure, and efficient Azure DevOps pipelines in PowerToys.
## General Guidelines
- Use YAML syntax consistently with proper indentation (2 spaces)
- Always include meaningful names and display names for pipelines, stages, jobs, and steps
- Implement proper error handling and conditional execution
- Use variables and parameters to make pipelines reusable and maintainable
- Follow the principle of least privilege for service connections and permissions
- Include comprehensive logging and diagnostics for troubleshooting
## Pipeline Structure
- Organize complex pipelines using stages for better visualization and control
- Use jobs to group related steps and enable parallel execution when possible
- Implement proper dependencies between stages and jobs
- Use templates for reusable pipeline components
- Keep pipeline files focused and modular - split large pipelines into multiple files
## Build Best Practices
- Use specific agent pool versions and VM images for consistency
- Cache dependencies (npm, NuGet, Maven, etc.) to improve build performance
- Implement proper artifact management with meaningful names and retention policies
- Use build variables for version numbers and build metadata
- Include code quality gates (lint checks, testing, security scans)
- Ensure builds are reproducible and environment-independent
## Testing Integration
- Run unit tests as part of the build process
- Publish test results in standard formats (JUnit, VSTest, etc.)
- Include code coverage reporting and quality gates
- Implement integration and end-to-end tests in appropriate stages
- Use test impact analysis when available to optimize test execution
- Fail fast on test failures to provide quick feedback
## Security Considerations
- Use Azure Key Vault for sensitive configuration and secrets
- Implement proper secret management with variable groups
- Use service connections with minimal required permissions
- Enable security scans (dependency vulnerabilities, static analysis)
- Implement approval gates for production deployments
- Use managed identities when possible instead of service principals
## Deployment Strategies
- Implement proper environment promotion (dev → staging → production)
- Use deployment jobs with proper environment targeting
- Implement blue-green or canary deployment strategies when appropriate
- Include rollback mechanisms and health checks
- Use infrastructure as code (ARM, Bicep, Terraform) for consistent deployments
- Implement proper configuration management per environment
## Variable and Parameter Management
- Use variable groups for shared configuration across pipelines
- Implement runtime parameters for flexible pipeline execution
- Use conditional variables based on branches or environments
- Secure sensitive variables and mark them as secrets
- Document variable purposes and expected values
- Use variable templates for complex variable logic
## Performance Optimization
- Use parallel jobs and matrix strategies when appropriate
- Implement proper caching strategies for dependencies and build outputs
- Use shallow clone for Git operations when full history isn't needed
- Optimize Docker image builds with multi-stage builds and layer caching
- Monitor pipeline performance and optimize bottlenecks
- Use pipeline resource triggers efficiently
## Monitoring and Observability
- Include comprehensive logging throughout the pipeline
- Use Azure Monitor and Application Insights for deployment tracking
- Implement proper notification strategies for failures and successes
- Include deployment health checks and automated rollback triggers
- Use pipeline analytics to identify improvement opportunities
- Document pipeline behavior and troubleshooting steps
## Template and Reusability
- Create pipeline templates for common patterns
- Use extends templates for complete pipeline inheritance
- Implement step templates for reusable task sequences
- Use variable templates for complex variable logic
- Version templates appropriately for stability
- Document template parameters and usage examples
## Branch and Trigger Strategy
- Implement appropriate triggers for different branch types
- Use path filters to trigger builds only when relevant files change
- Configure proper CI/CD triggers for main/master branches
- Use pull request triggers for code validation
- Implement scheduled triggers for maintenance tasks
- Consider resource triggers for multi-repository scenarios
## Example Structure
```yaml
# azure-pipelines.yml
trigger:
branches:
include:
- main
- develop
paths:
exclude:
- docs/*
- README.md
variables:
- group: shared-variables
- name: buildConfiguration
value: 'Release'
stages:
- stage: Build
displayName: 'Build and Test'
jobs:
- job: Build
displayName: 'Build Application'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UseDotNet@2
displayName: 'Use .NET SDK'
inputs:
version: '8.x'
- task: DotNetCoreCLI@2
displayName: 'Restore dependencies'
inputs:
command: 'restore'
projects: '**/*.csproj'
- task: DotNetCoreCLI@2
displayName: 'Build application'
inputs:
command: 'build'
projects: '**/*.csproj'
arguments: '--configuration $(buildConfiguration) --no-restore'
- stage: Deploy
displayName: 'Deploy to Staging'
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: DeployToStaging
displayName: 'Deploy to Staging Environment'
environment: 'staging'
strategy:
runOnce:
deploy:
steps:
- download: current
displayName: 'Download drop artifact'
artifact: drop
- task: AzureWebApp@1
displayName: 'Deploy to Azure Web App'
inputs:
azureSubscription: 'staging-service-connection'
appType: 'webApp'
appName: 'myapp-staging'
package: '$(Pipeline.Workspace)/drop/**/*.zip'
```
## Common Anti-Patterns to Avoid
- Hardcoding sensitive values directly in YAML files
- Using overly broad triggers that cause unnecessary builds
- Mixing build and deployment logic in a single stage
- Not implementing proper error handling and cleanup
- Using deprecated task versions without upgrade plans
- Creating monolithic pipelines that are difficult to maintain
- Not using proper naming conventions for clarity
- Ignoring pipeline security best practices

View File

@@ -1,61 +0,0 @@
---
description: 'Guidelines for shared libraries including logging, IPC, settings, DPI, telemetry, and utilities consumed by multiple modules'
applyTo: 'src/common/**'
---
# Common Libraries Shared Code Guidance
Guidelines for modifying shared code in `src/common/`. Changes here can have wide-reaching impact across the entire PowerToys codebase.
## Scope
- Logging infrastructure (`src/common/logger/`)
- IPC primitives and named pipe utilities
- Settings serialization and management
- DPI awareness and scaling utilities
- Telemetry helpers
- General utilities (JSON parsing, string helpers, etc.)
## Guidelines
### API Stability
- Avoid breaking public headers/APIs; if changed, search & update all callers
- Coordinate ABI-impacting struct/class layout changes; keep binary compatibility
- When modifying public interfaces, grep the entire codebase for usages
### Performance
- Watch perf in hot paths (hooks, timers, serialization)
- Avoid avoidable allocations in frequently called code
- Profile changes that touch performance-sensitive areas
### Dependencies
- Ask before adding third-party deps or changing serialization formats
- New dependencies must be MIT-licensed or approved by PM team
- Add any new external packages to `NOTICE.md`
### Logging
- C++ logging uses spdlog (`Logger::info`, `Logger::warn`, `Logger::error`, `Logger::debug`)
- Initialize with `init_logger()` early in startup
- Keep hot paths quiet no logging in tight loops or hooks
## Acceptance Criteria
- No unintended ABI breaks
- No noisy logs in hot paths
- New non-obvious symbols briefly commented
- All callers updated when interfaces change
## Code Style
- **C++**: Follow `.clang-format` in `src/`; use Modern C++ patterns per C++ Core Guidelines
- **C#**: Follow `src/.editorconfig`; enforce StyleCop.Analyzers
## Validation
- Build: `tools\build\build.cmd` from `src/common/` folder
- Verify no ABI breaks: grep for changed function/struct names across codebase
- Check logs: ensure no new logging in performance-critical paths

View File

@@ -1,256 +0,0 @@
---
description: 'Guidelines for creating high-quality custom instruction files for GitHub Copilot'
applyTo: '**/*.instructions.md'
---
# Custom Instructions File Guidelines
Instructions for creating effective and maintainable custom instruction files that guide GitHub Copilot in generating domain-specific code and following project conventions.
## Project Context
- Target audience: Developers and GitHub Copilot working with domain-specific code
- File format: Markdown with YAML frontmatter
- File naming convention: lowercase with hyphens (e.g., `react-best-practices.instructions.md`)
- Location: `.github/instructions/` directory
- Purpose: Provide context-aware guidance for code generation, review, and documentation
## Required Frontmatter
Every instruction file must include YAML frontmatter with the following fields:
```yaml
---
description: 'Brief description of the instruction purpose and scope'
applyTo: 'glob pattern for target files (e.g., **/*.ts, **/*.py)'
---
```
### Frontmatter Guidelines
- **description**: Single-quoted string, 1-500 characters, clearly stating the purpose
- **applyTo**: Glob pattern(s) specifying which files these instructions apply to
- Single pattern: `'**/*.ts'`
- Multiple patterns: `'**/*.ts, **/*.tsx, **/*.js'`
- Specific files: `'src/**/*.py'`
- All files: `'**'`
## File Structure
A well-structured instruction file should include the following sections:
### 1. Title and Overview
- Clear, descriptive title using `#` heading
- Brief introduction explaining the purpose and scope
- Optional: Project context section with key technologies and versions
### 2. Core Sections
Organize content into logical sections based on the domain:
- **General Instructions**: High-level guidelines and principles
- **Best Practices**: Recommended patterns and approaches
- **Code Standards**: Naming conventions, formatting, style rules
- **Architecture/Structure**: Project organization and design patterns
- **Common Patterns**: Frequently used implementations
- **Security**: Security considerations (if applicable)
- **Performance**: Optimization guidelines (if applicable)
- **Testing**: Testing standards and approaches (if applicable)
### 3. Examples and Code Snippets
Provide concrete examples with clear labels:
```markdown
### Good Example
\`\`\`language
// Recommended approach
code example here
\`\`\`
### Bad Example
\`\`\`language
// Avoid this pattern
code example here
\`\`\`
```
### 4. Validation and Verification (Optional but Recommended)
- Build commands to verify code
- Lint checks and formatting tools
- Testing requirements
- Verification steps
## Content Guidelines
### Writing Style
- Use clear, concise language
- Write in imperative mood ("Use", "Implement", "Avoid")
- Be specific and actionable
- Avoid ambiguous terms like "should", "might", "possibly"
- Use bullet points and lists for readability
- Keep sections focused and scannable
### Best Practices
- **Be Specific**: Provide concrete examples rather than abstract concepts
- **Show Why**: Explain the reasoning behind recommendations when it adds value
- **Use Tables**: For comparing options, listing rules, or showing patterns
- **Include Examples**: Real code snippets are more effective than descriptions
- **Stay Current**: Reference current versions and best practices
- **Link Resources**: Include official documentation and authoritative sources
### Common Patterns to Include
1. **Naming Conventions**: How to name variables, functions, classes, files
2. **Code Organization**: File structure, module organization, import order
3. **Error Handling**: Preferred error handling patterns
4. **Dependencies**: How to manage and document dependencies
5. **Comments and Documentation**: When and how to document code
6. **Version Information**: Target language/framework versions
## Patterns to Follow
### Bullet Points and Lists
```markdown
## Security Best Practices
- Always validate user input before processing
- Use parameterized queries to prevent SQL injection
- Store secrets in environment variables, never in code
- Implement proper authentication and authorization
- Enable HTTPS for all production endpoints
```
### Tables for Structured Information
```markdown
## Common Issues
| Issue | Solution | Example |
| ---------------- | ------------------- | ----------------------------- |
| Magic numbers | Use named constants | `const MAX_RETRIES = 3` |
| Deep nesting | Extract functions | Refactor nested if statements |
| Hardcoded values | Use configuration | Store API URLs in config |
```
### Code Comparison
```markdown
### Good Example - Using TypeScript interfaces
\`\`\`typescript
interface User {
id: string;
name: string;
email: string;
}
function getUser(id: string): User {
// Implementation
}
\`\`\`
### Bad Example - Using any type
\`\`\`typescript
function getUser(id: any): any {
// Loses type safety
}
\`\`\`
```
### Conditional Guidance
```markdown
## Framework Selection
- **For small projects**: Use Minimal API approach
- **For large projects**: Use controller-based architecture with clear separation
- **For microservices**: Consider domain-driven design patterns
```
## Patterns to Avoid
- **Overly verbose explanations**: Keep it concise and scannable
- **Outdated information**: Always reference current versions and practices
- **Ambiguous guidelines**: Be specific about what to do or avoid
- **Missing examples**: Abstract rules without concrete code examples
- **Contradictory advice**: Ensure consistency throughout the file
- **Copy-paste from documentation**: Add value by distilling and providing context
## Testing Your Instructions
Before finalizing instruction files:
1. **Test with Copilot**: Try the instructions with actual prompts in VS Code
2. **Verify Examples**: Ensure code examples are correct and run without errors
3. **Check Glob Patterns**: Confirm `applyTo` patterns match intended files
## Example Structure
Here's a minimal example structure for a new instruction file:
```markdown
---
description: 'Brief description of purpose'
applyTo: '**/*.ext'
---
# Technology Name Development
Brief introduction and context.
## General Instructions
- High-level guideline 1
- High-level guideline 2
## Best Practices
- Specific practice 1
- Specific practice 2
## Code Standards
### Naming Conventions
- Rule 1
- Rule 2
### File Organization
- Structure 1
- Structure 2
## Common Patterns
### Pattern 1
Description and example
\`\`\`language
code example
\`\`\`
### Pattern 2
Description and example
## Validation
- Build command: `command to verify`
- Lint checks: `command to lint`
- Testing: `command to test`
```
## Maintenance
- Review instructions when dependencies or frameworks are updated
- Update examples to reflect current best practices
- Remove outdated patterns or deprecated features
- Add new patterns as they emerge in the community
- Keep glob patterns accurate as project structure evolves
## Additional Resources
- [Custom Instructions Documentation](https://code.visualstudio.com/docs/copilot/customization/custom-instructions)
- [Awesome Copilot Instructions](https://github.com/github/awesome-copilot/tree/main/instructions)

View File

@@ -1,88 +0,0 @@
---
description: 'Guidelines for creating high-quality prompt files for GitHub Copilot'
applyTo: '**/*.prompt.md'
---
# Copilot Prompt Files Guidelines
Instructions for creating effective and maintainable prompt files that guide GitHub Copilot in delivering consistent, high-quality outcomes across any repository.
## Scope and Principles
- Target audience: maintainers and contributors authoring reusable prompts for Copilot Chat.
- Goals: predictable behaviour, clear expectations, minimal permissions, and portability across repositories.
- Primary references: VS Code documentation on prompt files and organization-specific conventions.
## Frontmatter Requirements
Every prompt file should include YAML frontmatter with the following fields:
### Required/Recommended Fields
| Field | Required | Description |
|-------|----------|-------------|
| `description` | Recommended | A short description of the prompt (single sentence, actionable outcome) |
| `name` | Optional | The name shown after typing `/` in chat. Defaults to filename if not specified |
| `agent` | Recommended | The agent to use: `ask`, `edit`, `agent`, or a custom agent name. Defaults to current agent |
| `model` | Optional | The language model to use. Defaults to currently selected model |
| `tools` | Optional | List of tool/tool set names available for this prompt |
| `argument-hint` | Optional | Hint text shown in chat input to guide user interaction |
### Guidelines
- Use consistent quoting (single quotes recommended) and keep one field per line for readability and version control clarity
- If `tools` are specified and current agent is `ask` or `edit`, the default agent becomes `agent`
- Preserve any additional metadata (`language`, `tags`, `visibility`, etc.) required by your organization
## File Naming and Placement
- Use kebab-case filenames ending with `.prompt.md` and store them under `.github/prompts/` unless your workspace standard specifies another directory.
- Provide a short filename that communicates the action (for example, `generate-readme.prompt.md` rather than `prompt1.prompt.md`).
## Body Structure
- Start with an `#` level heading that matches the prompt intent so it surfaces well in Quick Pick search.
- Organize content with predictable sections. Recommended baseline: `Mission` or `Primary Directive`, `Scope & Preconditions`, `Inputs`, `Workflow` (step-by-step), `Output Expectations`, and `Quality Assurance`.
- Adjust section names to fit the domain, but retain the logical flow: why → context → inputs → actions → outputs → validation.
- Reference related prompts or instruction files using relative links to aid discoverability.
## Input and Context Handling
- Use `${input:variableName[:placeholder]}` for required values and explain when the user must supply them. Provide defaults or alternatives where possible.
- Call out contextual variables such as `${selection}`, `${file}`, `${workspaceFolder}` only when they are essential, and describe how Copilot should interpret them.
- Document how to proceed when mandatory context is missing (for example, “Request the file path and stop if it remains undefined”).
## Tool and Permission Guidance
- Limit `tools` to the smallest set that enables the task. List them in the preferred execution order when the sequence matters.
- If the prompt inherits tools from a chat mode, mention that relationship and state any critical tool behaviours or side effects.
- Warn about destructive operations (file creation, edits, terminal commands) and include guard rails or confirmation steps in the workflow.
## Instruction Tone and Style
- Write in direct, imperative sentences targeted at Copilot (for example, “Analyze”, “Generate”, “Summarize”).
- Keep sentences short and unambiguous, following Google Developer Documentation translation best practices to support localization.
- Avoid idioms, humor, or culturally specific references; favor neutral, inclusive language.
## Output Definition
- Specify the format, structure, and location of expected results (for example, “Create an architecture decision record file using the template below, such as `docs/architecture-decisions/record-XXXX.md`).
- Include success criteria and failure triggers so Copilot knows when to halt or retry.
- Provide validation steps—manual checks, automated commands, or acceptance criteria lists—that reviewers can execute after running the prompt.
## Examples and Reusable Assets
- Embed Good/Bad examples or scaffolds (Markdown templates, JSON stubs) that the prompt should produce or follow.
- Maintain reference tables (capabilities, status codes, role descriptions) inline to keep the prompt self-contained. Update these tables when upstream resources change.
- Link to authoritative documentation instead of duplicating lengthy guidance.
## Quality Assurance Checklist
- [ ] Frontmatter fields are complete, accurate, and least-privilege.
- [ ] Inputs include placeholders, default behaviours, and fallbacks.
- [ ] Workflow covers preparation, execution, and post-processing without gaps.
- [ ] Output expectations include formatting and storage details.
- [ ] Validation steps are actionable (commands, diff checks, review prompts).
- [ ] Security, compliance, and privacy policies referenced by the prompt are current.
- [ ] Prompt executes successfully in VS Code (`Chat: Run Prompt`) using representative scenarios.
## Maintenance Guidance
- Version-control prompts alongside the code they affect; update them when dependencies, tooling, or review processes change.
- Review prompts periodically to ensure tool lists, model requirements, and linked documents remain valid.
- Coordinate with other repositories: when a prompt proves broadly useful, extract common guidance into instruction files or shared prompt packs.
## Additional Resources
- [Prompt Files Documentation](https://code.visualstudio.com/docs/copilot/customization/prompt-files#_prompt-file-format)
- [Awesome Copilot Prompt Files](https://github.com/github/awesome-copilot/tree/main/prompts)
- [Tool Configuration](https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode#_agent-mode-tools)

View File

@@ -1,68 +0,0 @@
---
description: 'Guidelines for Runner and Settings UI components that communicate via named pipes and manage module lifecycle'
applyTo: 'src/runner/**,src/settings-ui/**'
---
# Runner & Settings UI Core Components Guidance
Guidelines for modifying the Runner (tray/module loader) and Settings UI (configuration app). These components communicate via Windows Named Pipes using JSON messages.
## Runner (`src/runner/`)
### Scope
- Module bootstrap, hotkey management, settings bridge, update/elevation handling
### Guidelines
- If IPC/JSON contracts change, mirror updates in `src/settings-ui/**`
- Keep module discovery in `src/runner/main.cpp` in sync when adding/removing modules
- Keep startup lean: avoid blocking/network calls in early init path
- Preserve GPO & elevation behaviors; confirm no regression in policy handling
- Ask before modifying update workflow or elevation logic
### Acceptance Criteria
- Stable startup, consistent contracts, no unnecessary logging noise
## Settings UI (`src/settings-ui/`)
### Scope
- WinUI/WPF UI, communicates with Runner over named pipes; manages persisted settings schema
### Guidelines
- Don't break settings schema silently; add migration when shape changes
- If IPC/JSON contracts change, align with `src/runner/**` implementation
- Keep UI responsive: marshal to UI thread for UI-bound operations
- Reuse existing styles/resources; avoid duplicate theme keys
- Add/adjust migration or serialization tests when changing persisted settings
### Acceptance Criteria
- Schema integrity preserved, responsive UI, consistent contracts, no style duplication
## Shared Concerns
### IPC Contract Changes
When modifying the JSON message format between Runner and Settings UI:
1. Update both `src/runner/` and `src/settings-ui/` in the same PR
2. Preserve backward compatibility where possible
3. Add migration logic for settings schema changes
4. Test both directions of communication
### Code Style
- **C++ (Runner)**: Follow `.clang-format` in `src/`
- **C# (Settings UI)**: Follow `src/.editorconfig`, use StyleCop.Analyzers
- **XAML**: Use XamlStyler or run `.\.pipelines\applyXamlStyling.ps1 -Main`
## Validation
- Build Runner: `tools\build\build.cmd` from `src/runner/`
- Build Settings UI: `tools\build\build.cmd` from `src/settings-ui/`
- Test IPC: Launch both Runner and Settings UI, verify communication works
- Schema changes: Run serialization tests if settings shape changed

View File

@@ -1,228 +0,0 @@
---
description: 'Instructions for building Model Context Protocol (MCP) servers using the TypeScript SDK'
applyTo: '**/*.ts, **/*.js, **/package.json'
---
# TypeScript MCP Server Development
## Instructions
- Use the **@modelcontextprotocol/sdk** npm package: `npm install @modelcontextprotocol/sdk`
- Import from specific paths: `@modelcontextprotocol/sdk/server/mcp.js`, `@modelcontextprotocol/sdk/server/stdio.js`, etc.
- Use `McpServer` class for high-level server implementation with automatic protocol handling
- Use `Server` class for low-level control with manual request handlers
- Use **zod** for input/output schema validation: `npm install zod@3`
- Always provide `title` field for tools, resources, and prompts for better UI display
- Use `registerTool()`, `registerResource()`, and `registerPrompt()` methods (recommended over older APIs)
- Define schemas using zod: `{ inputSchema: { param: z.string() }, outputSchema: { result: z.string() } }`
- Return both `content` (for display) and `structuredContent` (for structured data) from tools
- For HTTP servers, use `StreamableHTTPServerTransport` with Express or similar frameworks
- For local integrations, use `StdioServerTransport` for stdio-based communication
- Create new transport instances per request to prevent request ID collisions (stateless mode)
- Use session management with `sessionIdGenerator` for stateful servers
- Enable DNS rebinding protection for local servers: `enableDnsRebindingProtection: true`
- Configure CORS headers and expose `Mcp-Session-Id` for browser-based clients
- Use `ResourceTemplate` for dynamic resources with URI parameters: `new ResourceTemplate('resource://{param}', { list: undefined })`
- Support completions for better UX using `completable()` wrapper from `@modelcontextprotocol/sdk/server/completable.js`
- Implement sampling with `server.server.createMessage()` to request LLM completions from clients
- Use `server.server.elicitInput()` to request additional user input during tool execution
- Enable notification debouncing for bulk updates: `debouncedNotificationMethods: ['notifications/tools/list_changed']`
- Dynamic updates: call `.enable()`, `.disable()`, `.update()`, or `.remove()` on registered items to emit `listChanged` notifications
- Use `getDisplayName()` from `@modelcontextprotocol/sdk/shared/metadataUtils.js` for UI display names
- Test servers with MCP Inspector: `npx @modelcontextprotocol/inspector`
## Best Practices
- Keep tool implementations focused on single responsibilities
- Provide clear, descriptive titles and descriptions for LLM understanding
- Use proper TypeScript types for all parameters and return values
- Implement comprehensive error handling with try-catch blocks
- Return `isError: true` in tool results for error conditions
- Use async/await for all asynchronous operations
- Close database connections and clean up resources properly
- Validate input parameters before processing
- Use structured logging for debugging without polluting stdout/stderr
- Consider security implications when exposing file system or network access
- Implement proper resource cleanup on transport close events
- Use environment variables for configuration (ports, API keys, etc.)
- Document tool capabilities and limitations clearly
- Test with multiple clients to ensure compatibility
## Common Patterns
### Basic Server Setup (HTTP)
```typescript
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express from 'express';
const server = new McpServer({
name: 'my-server',
version: '1.0.0'
});
const app = express();
app.use(express.json());
app.post('/mcp', async (req, res) => {
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
enableJsonResponse: true
});
res.on('close', () => transport.close());
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
});
app.listen(3000);
```
### Basic Server Setup (stdio)
```typescript
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new McpServer({
name: 'my-server',
version: '1.0.0'
});
// ... register tools, resources, prompts ...
const transport = new StdioServerTransport();
await server.connect(transport);
```
### Simple Tool
```typescript
import { z } from 'zod';
server.registerTool(
'calculate',
{
title: 'Calculator',
description: 'Perform basic calculations',
inputSchema: { a: z.number(), b: z.number(), op: z.enum(['+', '-', '*', '/']) },
outputSchema: { result: z.number() }
},
async ({ a, b, op }) => {
const result = op === '+' ? a + b : op === '-' ? a - b :
op === '*' ? a * b : a / b;
const output = { result };
return {
content: [{ type: 'text', text: JSON.stringify(output) }],
structuredContent: output
};
}
);
```
### Dynamic Resource
```typescript
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
server.registerResource(
'user',
new ResourceTemplate('users://{userId}', { list: undefined }),
{
title: 'User Profile',
description: 'Fetch user profile data'
},
async (uri, { userId }) => ({
contents: [{
uri: uri.href,
text: `User ${userId} data here`
}]
})
);
```
### Tool with Sampling
```typescript
server.registerTool(
'summarize',
{
title: 'Text Summarizer',
description: 'Summarize text using LLM',
inputSchema: { text: z.string() },
outputSchema: { summary: z.string() }
},
async ({ text }) => {
const response = await server.server.createMessage({
messages: [{
role: 'user',
content: { type: 'text', text: `Summarize: ${text}` }
}],
maxTokens: 500
});
const summary = response.content.type === 'text' ?
response.content.text : 'Unable to summarize';
const output = { summary };
return {
content: [{ type: 'text', text: JSON.stringify(output) }],
structuredContent: output
};
}
);
```
### Prompt with Completion
```typescript
import { completable } from '@modelcontextprotocol/sdk/server/completable.js';
server.registerPrompt(
'review',
{
title: 'Code Review',
description: 'Review code with specific focus',
argsSchema: {
language: completable(z.string(), value =>
['typescript', 'python', 'javascript', 'java']
.filter(l => l.startsWith(value))
),
code: z.string()
}
},
({ language, code }) => ({
messages: [{
role: 'user',
content: {
type: 'text',
text: `Review this ${language} code:\n\n${code}`
}
}]
})
);
```
### Error Handling
```typescript
server.registerTool(
'risky-operation',
{
title: 'Risky Operation',
description: 'An operation that might fail',
inputSchema: { input: z.string() },
outputSchema: { result: z.string() }
},
async ({ input }) => {
try {
const result = await performRiskyOperation(input);
const output = { result };
return {
content: [{ type: 'text', text: JSON.stringify(output) }],
structuredContent: output
};
} catch (err: unknown) {
const error = err as Error;
return {
content: [{ type: 'text', text: `Error: ${error.message}` }],
isError: true
};
}
}
);
```

View File

@@ -1,49 +1,16 @@
---
agent: 'agent'
description: 'Generate an 80-character git commit title for the local diff'
mode: 'agent'
model: GPT-5-Codex (Preview)
description: 'Generate an 80-character git commit title for the local diff.'
---
# Generate Commit Title
**Goal:** Provide a ready-to-paste git commit title (<= 80 characters) that captures the most important local changes since `HEAD`.
## Purpose
Provide a single-line, ready-to-paste git commit title (<= 80 characters) that reflects the most important local changes since `HEAD`.
## Input to collect
- Run exactly one command to view the local diff:
```@terminal
git diff HEAD
```
## How to decide the title
1. From the diff, find the dominant area (e.g., `src/modules/*`, `doc/devdocs/**`) and the change type (bug fix, docs update, config tweak).
2. Draft an imperative, plain-ASCII title that:
- Mentions the primary component when obvious (e.g., `FancyZones:` or `Docs:`)
- Stays within 80 characters and has no trailing punctuation
## Final output
- Reply with only the commit title on a single line—no extra text.
## PR title convention (when asked)
Use Conventional Commits style:
`<type>(<scope>): <summary>`
**Allowed types**
- feat, fix, docs, refactor, perf, test, build, ci, chore
**Scope rules**
- Use a short, PowerToys-focused scope (one word preferred). Common scopes:
- Core: `runner`, `settings-ui`, `common`, `docs`, `build`, `ci`, `installer`, `gpo`, `dsc`
- Modules: `fancyzones`, `powerrename`, `awake`, `colorpicker`, `imageresizer`, `keyboardmanager`, `mouseutils`, `peek`, `hosts`, `file-locksmith`, `screen-ruler`, `text-extractor`, `cropandlock`, `paste`, `powerlauncher`
- If unclear, pick the closest module or subsystem; omit only if unavoidable
**Summary rules**
- Imperative, present tense (“add”, “update”, “remove”, “fix”)
- Keep it <= 72 characters when possible; be specific, avoid “misc changes”
**Examples**
- `feat(fancyzones): add canvas template duplication`
- `fix(mouseutils): guard crosshair toggle when dpi info missing`
- `docs(runner): document tray icon states`
- `build(installer): align wix v5 suffix flag`
- `ci(ci): cache pipeline artifacts for x64`
**Workflow:**
1. Run a single command to view the local diff since the last commit:
```@terminal
git diff HEAD
```
2. From that diff, identify the dominant area (reference key paths like `src/modules/*`, `doc/devdocs/**`, etc.), the type of change (bug fix, docs update, config tweak), and any notable impact.
3. Draft a concise, imperative commit title summarizing the dominant change. Keep it plain ASCII, <= 80 characters, and avoid trailing punctuation. Mention the primary component when obvious (for example `FancyZones:` or `Docs:`).
4. Respond with only the final commit title on a single line so it can be pasted directly into `git commit`.

View File

@@ -1,10 +1,9 @@
---
agent: 'agent'
description: 'Generate a PowerToys-ready pull request description from the local diff'
mode: 'agent'
model: GPT-5-Codex (Preview)
description: 'Generate a PowerToys-ready pull request description from the local diff.'
---
# Generate PR Summary
**Goal:** Produce a ready-to-paste PR title and description that follows PowerToys conventions by comparing the current branch against a user-selected target branch.
**Repo guardrails:**
@@ -21,4 +20,3 @@ description: 'Generate a PowerToys-ready pull request description from the local
5. Confirm validation: list tests executed with results or state why tests were skipped in line with repo guidance.
6. Load `.github/pull_request_template.md`, mirror its section order, and populate it with the gathered facts. Include only relevant checklist entries, marking them `[x]/[ ]` and noting any intentional omissions as "N/A".
7. Present the filled template inside a fenced ```markdown code block with no extra commentary so it is ready to paste into a PR, clearly flagging any placeholders that still need user input.
8. Prepend the PR title above the filled template, applying the Conventional Commit type/scope rules from `.github/prompts/create-commit-title.prompt.md`; pick the dominant component from the diff and keep the title concise and imperative.

View File

@@ -1,72 +0,0 @@
---
agent: 'agent'
description: 'Execute the fix for a GitHub issue using the previously generated implementation plan'
---
# Fix GitHub Issue
## Dependencies
Source review prompt (for generating the implementation plan if missing):
- .github/prompts/review-issue.prompt.md
Required plan file (single source of truth):
- Generated Files/issueReview/{{issue_number}}/implementation-plan.md
## Dependency Handling
1) If `implementation-plan.md` exists → proceed.
2) If missing → run the review prompt:
- Invoke: `.github/prompts/review-issue.prompt.md`
- Pass: `issue_number={{issue_number}}`
- Then re-check for `implementation-plan.md`.
3) If still missing → stop and generate:
- `Generated Files/issueFix/{{issue_number}}/manual-steps.md` containing:
“implementation-plan.md not found; please run .github/prompts/review-issue.prompt.md for #{{issue_number}}.”
# GOAL
For **#{{issue_number}}**:
- Use implementation-plan.md as the single authority.
- Apply code and test changes directly in the repository.
- Produce a PR-ready description.
# OUTPUT FILES
1) Generated Files/issueFix/{{issue_number}}/pr-description.md
2) Generated Files/issueFix/{{issue_number}}/manual-steps.md # only if human interaction or external setup is required
# EXECUTION RULES
1) Read implementation-plan.md and execute:
- Layers & Files → edit/create as listed
- Pattern Choices → follow repository conventions
- Fundamentals (perf, security, compatibility, accessibility)
- Logging & Exceptions
- Telemetry (only if explicitly included in the plan)
- Risks & Mitigations
- Tests to Add
2) Locate affected files via `rg` or `git grep`.
3) Add/update tests to enforce the fixed behavior.
4) If any ambiguity exists, add:
// TODO(Human input needed): <clarification needed>
5) Verify locally: build & tests run successfully.
# pr-description.md should include:
- Title: `Fix: <short summary> (#{{issue_number}})`
- What changed and why the fix works
- Files or modules touched
- Risks & mitigations (implemented)
- Tests added/updated and how to run them
- Telemetry behavior (if applicable)
- Validation / reproduction steps
- `Closes #{{issue_number}}`
# manual-steps.md (only if needed)
- List required human actions: secrets, config, approvals, missing info, or code comments requiring human decisions.
# IMPORTANT
- Apply code and tests directly; do not produce patch files.
- Follow implementation-plan.md as the source of truth.
- Insert comments for human review where a decision or input is required.
- Use repository conventions and deterministic, minimal changes.
# FINALIZE
- Write pr-description.md
- Write manual-steps.md only if needed
- Print concise success message or note items requiring human interaction

View File

@@ -1,70 +0,0 @@
---
description: 'Fix active pull request comments with scoped changes'
name: 'fix-pr-active-comments'
agent: 'agent'
argument-hint: 'PR number or active PR URL'
---
# Fix Active PR Comments
## Mission
Resolve active pull request comments by applying only simple fixes. For complex refactors, write a plan instead of changing code.
## Scope & Preconditions
- You must have an active pull request context or a provided PR number.
- Only implement simple changes. Do not implement large refactors.
- If required context is missing, request it and stop.
## Inputs
- Required: ${input:pr_number:PR number or URL}
- Optional: ${input:comment_scope:files or areas to focus on}
- Optional: ${input:fixing_guidelines:additional fixing guidelines from the user}
## Workflow
1. Locate all active (unresolved) PR review comments for the given PR.
2. For each comment, classify the change scope:
- Simple change: limited edits, localized fix, low risk, no broad redesign.
- Large refactor: multi-file redesign, architecture change, or risky behavior change.
3. For each large refactor request:
- Do not modify code.
- Write a planning document to Generated Files/prReview/${input:pr_number}/fixPlan/.
4. For each simple change request:
- Implement the fix with minimal edits.
- Run quick checks if needed.
- Commit and push the change.
5. For comments that seem invalid, unclear, or not applicable (even if simple):
- Do not change code.
- Add the item to a summary table in Generated Files/prReview/${input:pr_number}/fixPlan/overview.md.
- Consult back to the end user in a friendly, polite tone.
6. Respond to each comment that you fixed:
- Reply in the active conversation.
- Use a polite or friendly tone.
- Keep the response under 200 words.
- Resolve the comment after replying.
## Output Expectations
- Simple fixes: code changes committed and pushed.
- Large refactors: a plan file saved to Generated Files/prReview/${input:pr_number}/fixPlan/.
- Invalid or unclear comments: captured in Generated Files/prReview/${input:pr_number}/fixPlan/overview.md.
- Each fixed comment has a reply under 200 words and is resolved.
## Plan File Template
Use this template for each large refactor item:
# Fix Plan: <short title>
## Context
- Comment link:
- Impacted areas:
## Overview Table Template
Use this table in Generated Files/prReview/${input:pr_number}/fixPlan/overview.md:
| Comment link | Summary | Reason not applied | Suggested follow-up |
| --- | --- | --- | --- |
| | | | |
## Quality Assurance
- Verify plan file path exists.
- Ensure no code changes were made for large refactor items.
- Confirm replies are under 200 words and comments are resolved.

View File

@@ -1,16 +1,15 @@
---
agent: 'agent'
description: 'Resolve Code scanning / check-spelling comments on the active PR'
mode: 'agent'
model: GPT-5-Codex (Preview)
description: 'Resolve Code scanning / check-spelling comments on the active PR.'
---
# Fix Spelling Comments
**Goal:** Clear every outstanding GitHub pull request comment created by the `Code scanning / check-spelling` workflow by explicitly allowing intentional terms.
**Guardrails:**
- Update only discussion threads authored by `github-actions` or `github-actions[bot]` that mention `Code scanning results / check-spelling`.
- Prefer improving the wording in the originally flagged file when it clarifies intent without changing meaning; if the wording is already clear/standard for the context, handle it via `.github/actions/spell-check/expect.txt` and reuse existing entries.
- Limit edits to the flagged text and `.github/actions/spell-check/expect.txt`; leave all other files and topics untouched.
- Resolve findings solely by editing `.github/actions/spell-check/expect.txt`; reuse existing entries.
- Leave all other files and topics untouched.
**Prerequisites:**
- Install GitHub CLI if it is not present: `winget install GitHub.cli`.
@@ -19,6 +18,5 @@ description: 'Resolve Code scanning / check-spelling comments on the active PR'
**Workflow:**
1. Determine the active pull request with a single `gh pr view --json number` call (default to the current branch).
2. Fetch all PR discussion data once via `gh pr view --json comments,reviews` and filter to check-spelling comments authored by `github-actions` or `github-actions[bot]` that are not minimized; when several remain, process only the most recent comment body.
3. For each flagged token, first consider tightening or rephrasing the original text to avoid the false positive while keeping the meaning intact; if the existing wording is already normal and professional for the context, proceed to allowlisting instead of changing it.
4. When allowlisting, review `.github/actions/spell-check/expect.txt` for an equivalent term (for example an existing lowercase variant); when found, reuse that normalized term rather than adding a new entry, even if the flagged token differs only by casing. Only add a new entry after confirming no equivalent already exists.
5. Add any remaining missing token to `.github/actions/spell-check/expect.txt`, keeping surrounding formatting intact.
3. For each flagged token, review `.github/actions/spell-check/expect.txt` for an equivalent term (for example an existing lowercase variant); when found, reuse that normalized term rather than adding a new entry, even if the flagged token differs only by casing. Only add a new entry after confirming no equivalent already exists.
4. Add any remaining missing token to `.github/actions/spell-check/expect.txt`, keeping surrounding formatting intact.

View File

@@ -1,165 +0,0 @@
---
agent: 'agent'
description: 'Review a GitHub issue, score it (0-100), and generate an implementation plan'
---
# Review GitHub Issue
## Goal
For **#{{issue_number}}** produce:
1) `Generated Files/issueReview/{{issue_number}}/overview.md`
2) `Generated Files/issueReview/{{issue_number}}/implementation-plan.md`
## Inputs
Figure out required inputs {{issue_number}} from the invocation context; if anything is missing, ask for the value or note it as a gap.
# CONTEXT (brief)
Ground evidence using `gh issue view {{issue_number}} --json number,title,body,author,createdAt,updatedAt,state,labels,milestone,reactions,comments,linkedPullRequests`, download images via MCP `github_issue_images` to better understand the issue context. Finally, use MCP `github_issue_attachments` to download logs with parameter `extractFolder` as `Generated Files/issueReview/{{issue_number}}/logs`, and analyze the downloaded logs if available to identify relevant issues. Locate the source code in the current workspace (use `rg`/`git grep` as needed). Link related issues and PRs.
## When to call MCP tools
If the following MCP "github-artifacts" tools are available in the environment, use them:
- `github_issue_images`: use when the issue/PR likely contains screenshots or other visual evidence (UI bugs, glitches, design problems).
- `github_issue_attachments`: use when the issue/PR mentions attached ZIPs (PowerToysReport_*.zip, logs.zip, debug.zip) or asks to analyze logs/diagnostics. Always provide `extractFolder` as `Generated Files/issueReview/{{issue_number}}/logs`
If these tools are not available (not listed by the runtime), start the MCP server "github-artifacts" first.
# OVERVIEW.MD
## Summary
Issue, state, milestone, labels. **Signals**: 👍/❤️/👎, comment count, last activity, linked PRs.
## At-a-Glance Score Table
Present all ratings in a compact table for quick scanning:
| Dimension | Score | Assessment | Key Drivers |
|-----------|-------|------------|-------------|
| **A) Business Importance** | X/100 | Low/Medium/High | Top 2 factors with scores |
| **B) Community Excitement** | X/100 | Low/Medium/High | Top 2 factors with scores |
| **C) Technical Feasibility** | X/100 | Low/Medium/High | Top 2 factors with scores |
| **D) Requirement Clarity** | X/100 | Low/Medium/High | Top 2 factors with scores |
| **Overall Priority** | X/100 | Low/Medium/High/Critical | Average or weighted summary |
| **Effort Estimate** | X days (T-shirt) | XS/S/M/L/XL/XXL/Epic | Type: bug/feature/chore |
| **Similar Issues Found** | X open, Y closed | — | Quick reference to related work |
| **Potential Assignees** | @username, @username | — | Top contributors to module |
**Assessment bands**: 0-25 Low, 26-50 Medium, 51-75 High, 76-100 Critical
## Ratings (0100) — add evidence & short rationale
### A) Business Importance
- Labels (priority/security/regression): **≤35**
- Milestone/roadmap: **≤25**
- Customer/contract impact: **≤20**
- Unblocks/platform leverage: **≤20**
### B) Community Excitement
- 👍+❤️ normalized: **≤45**
- Comment volume & unique participants: **≤25**
- Recent activity (≤30d): **≤15**
- Duplicates/related issues: **≤15**
### C) Technical Feasibility
- Contained surface/clear seams: **≤30**
- Existing patterns/utilities: **≤25**
- Risk (perf/sec/compat) manageable: **≤25**
- Testability & CI support: **≤20**
### D) Requirement Clarity
- Behavior/repro/constraints: **≤60**
- Non-functionals (perf/sec/i18n/a11y): **≤25**
- Decision owners/acceptance signals: **≤15**
## Effort
Days + **T-shirt** (XS 0.51d, S 12, M 24, L 47, XL 714, XXL 1430, Epic >30).
Type/level: bug/feature/chore/docs/refactor/test-only; severity/value tier.
## Suggested Actions
Provide actionable recommendations for issue triage and assignment:
### A) Requirement Clarification (if Clarity score <50)
**When Requirement Clarity (Dimension D) is Medium or Low:**
- Identify specific gaps in issue description: missing repro steps, unclear expected behavior, undefined acceptance criteria, missing non-functional requirements
- Draft 3-5 clarifying questions to post as issue comment
- Suggest additional information needed: screenshots, logs, environment details, OS version, PowerToys version, error messages
- If behavior is ambiguous, propose 2-3 interpretation scenarios and ask reporter to confirm
- Example questions:
- "Can you provide exact steps to reproduce this issue?"
- "What is the expected behavior vs. what you're actually seeing?"
- "Does this happen on Windows 10, 11, or both?"
- "Can you attach a screenshot or screen recording?"
### B) Correct Label Suggestions
- Analyze issue type, module, and severity to suggest missing or incorrect labels
- Recommend labels from: `Issue-Bug`, `Issue-Feature`, `Issue-Docs`, `Issue-Task`, `Priority-High`, `Priority-Medium`, `Priority-Low`, `Needs-Triage`, `Needs-Author-Feedback`, `Product-<ModuleName>`, etc.
- If Requirement Clarity is low (<50), add `Needs-Author-Feedback` label
- If current labels are incorrect or incomplete, provide specific label changes with rationale
### C) Find Similar Issues & Past Fixes
- Search for similar issues using `gh issue list --search "keywords" --state all --json number,title,state,closedAt`
- Identify patterns: duplicate issues, related bugs, or similar feature requests
- For closed issues, find linked PRs that fixed them: check `linkedPullRequests` in issue data
- Provide 3-5 examples of similar issues with format: `#<number> - <title> (closed by PR #<pr>)` or `(still open)`
### D) Identify Subject Matter Experts
- Use git blame/log to find who fixed similar issues in the past
- Search for PR authors who touched relevant files: `git log --all --format='%aN' -- <file_paths> | sort | uniq -c | sort -rn | head -5`
- Check issue/PR history for frequent contributors to the affected module
- Suggest 2-3 potential assignees with context: `@<username> - <reason>` (e.g., "fixed similar rendering bug in #12345", "maintains FancyZones module")
### E) Semantic Search for Related Work
- Use semantic_search tool to find similar issues, code patterns, or past discussions
- Search queries should include: issue keywords, module names, error messages, feature descriptions
- Cross-reference semantic results with GitHub issue search for comprehensive coverage
**Output format for Suggested Actions section in overview.md:**
```markdown
## Suggested Actions
### Clarifying Questions (if Clarity <50)
Post these questions as issue comment to gather missing information:
1. <question>
2. <question>
3. <question>
**Recommended label**: `Needs-Author-Feedback`
### Label Recommendations
- Add: `<label>` - <reason>
- Remove: `<label>` - <reason>
- Current labels are appropriate ✓
### Similar Issues Found
1. #<number> - <title> (<state>, closed by PR #<pr> on <date>)
2. #<number> - <title> (<state>)
...
### Potential Assignees
- @<username> - <reason>
- @<username> - <reason>
### Related Code/Discussions
- <semantic search findings>
```
# IMPLEMENTATION-PLAN.MD
1) **Problem Framing** — restate problem; current vs expected; scope boundaries.
2) **Layers & Files** — layers (UI/domain/data/infra/build). For each, list **files/dirs to modify** and **new files** (exact paths + why). Prefer repo patterns; cite examples/PRs.
3) **Pattern Choices** — reuse existing; if new, justify trade-offs & transition.
4) **Fundamentals** (brief plan or N/A + reason):
- Performance (hot paths, allocs, caching/streaming)
- Security (validation, authN/Z, secrets, SSRF/XSS/CSRF)
- G11N/L10N (resources, number/date, pluralization)
- Compatibility (public APIs, formats, OS/runtime/toolchain)
- Extensibility (DI seams, options/flags, plugin points)
- Accessibility (roles, labels, focus, keyboard, contrast)
- SOLID & repo conventions (naming, folders, dependency direction)
5) **Logging & Exception Handling**
- Where to log; levels; structured fields; correlation/traces.
- What to catch vs rethrow; retries/backoff; user-visible errors.
- **Privacy**: never log secrets/PII; redaction policy.
6) **Telemetry (optional — business metrics only)**
- Events/metrics (name, when, props); success signal; privacy/sampling; dashboards/alerts.
7) **Risks & Mitigations** — flags/canary/shadow-write/config guards.
8) **Task Breakdown (agent-ready)** — table (leave a blank line before the header so Markdown renders correctly):
| Task | Intent | Files/Areas | Steps | Tests (brief) | Owner (Agent/Human) | Human interaction needed? (why) |
|---|---|---|---|---|---|---|
9) **Tests to Add (only)**
- **Unit**: targets, cases (success/edge/error), mocks/fixtures, path, notes.
- **UI** (if applicable): flows, locator strategy, env/data/flags, path, flake mitigation.

View File

@@ -1,198 +0,0 @@
---
agent: 'agent'
description: 'Perform a comprehensive PR review with per-step Markdown and machine-readable outputs'
---
# Review Pull Request
**Goal**: Given `{{pr_number}}`, run a *one-topic-per-step* review. Write files to `Generated Files/prReview/{{pr_number}}/` (replace `{{pr_number}}` with the integer). Emit machinereadable blocks for a GitHub MCP to post review comments.
## PR selection
Resolve the target PR using these fallbacks in order:
1. Parse the invocation text for an explicit identifier (first integer following patterns such as a leading hash and digits or the text `PR:` followed by digits).
2. If no PR is found yet, locate the newest `Generated Files/prReview/_batch/batch-overview-*.md` file (highest timestamp in filename, fallback newest mtime) and take the first entry in its `## PRs` list whose review folder is missing `00-OVERVIEW.md` or contains `__error.flag`.
3. If the batch file has no pending PRs, query assignments with `gh pr list --assignee @me --state open --json number,updatedAt --limit 20` and pick the most recently updated PR that does not already have a completed review folder.
4. If still unknown, run `gh pr view --json number` in the current branch and use that result when it is unambiguous.
5. If every step above fails, prompt the user for a PR number before proceeding.
## Fetch PR data with `gh`
- `gh pr view {{pr_number}} --json number,baseRefName,headRefName,baseRefOid,headRefOid,changedFiles,files`
- `gh api repos/:owner/:repo/pulls/{{pr_number}}/files?per_page=250` # patches for line mapping
### Incremental review workflow
1. **Check for existing review**: Read `Generated Files/prReview/{{pr_number}}/00-OVERVIEW.md`
2. **Extract state**: Parse `Last reviewed SHA:` from review metadata section
3. **Detect changes**: Run `Get-PrIncrementalChanges.ps1 -PullRequestNumber {{pr_number}} -LastReviewedCommitSha {{sha}}`
4. **Analyze result**:
- `NeedFullReview: true` → Review all files in the PR
- `NeedFullReview: false` and `IsIncremental: true` → Review only files in `ChangedFiles` array
- `ChangedFiles` is empty → No changes, skip review (update iteration history with "No changes since last review")
5. **Apply smart filtering**: Use the file patterns in smart step filtering table to skip irrelevant steps
6. **Update metadata**: After completing review, save current `headRefOid` as `Last reviewed SHA:` in `00-OVERVIEW.md`
### Reusable PowerShell scripts
Scripts live in `.github/review-tools/` to avoid repeated manual approvals during PR reviews:
| Script | Usage |
| --- | --- |
| `.github/review-tools/Get-GitHubRawFile.ps1` | Download a repository file at a given ref, optionally with line numbers. |
| `.github/review-tools/Get-GitHubPrFilePatch.ps1` | Fetch the unified diff for a specific file within a pull request via `gh api`. |
| `.github/review-tools/Get-PrIncrementalChanges.ps1` | Compare last reviewed SHA with current PR head to identify incremental changes. Returns JSON with changed files, new commits, and whether full review is needed. |
| `.github/review-tools/Test-IncrementalReview.ps1` | Test helper to preview incremental review detection for a PR. Use before running full review to see what changed. |
Always prefer these scripts (or new ones added under `.github/review-tools/`) over raw `gh api` or similar shell commands so the review flow does not trigger interactive approval prompts.
## Output files
Folder: `Generated Files/prReview/{{pr_number}}/`
Files: `00-OVERVIEW.md`, `01-functionality.md`, `02-compatibility.md`, `03-performance.md`, `04-accessibility.md`, `05-security.md`, `06-localization.md`, `07-globalization.md`, `08-extensibility.md`, `09-solid-design.md`, `10-repo-patterns.md`, `11-docs-automation.md`, `12-code-comments.md`, `13-copilot-guidance.md` *(only if guidance md exists).*
- **Write-after-step rule:** Immediately after completing each TODO step, persist that step's markdown file before proceeding to the next. Generate `00-OVERVIEW.md` only after every step file has been refreshed for the current run.
## Iteration management
- Determine the current review iteration by reading `00-OVERVIEW.md` (look for `Review iteration:`). If missing, assume iteration `1`.
- Extract the last reviewed SHA from `00-OVERVIEW.md` (look for `Last reviewed SHA:` in the review metadata section). If missing, this is iteration 1.
- **Incremental review detection**:
1. Call `.github/review-tools/Get-PrIncrementalChanges.ps1 -PullRequestNumber {{pr_number}} -LastReviewedCommitSha {{last_sha}}` to get delta analysis.
2. Parse the JSON result to determine if incremental review is possible (`IsIncremental: true`, `NeedFullReview: false`).
3. If force-push detected or first review, proceed with full review of all changed files.
4. If incremental, review only the files listed in `ChangedFiles` array and apply smart step filtering (see below).
- Increment the iteration for each review run and propagate the new value to all step files and the overview.
- Preserve prior iteration notes by keeping/expanding an `## Iteration history` section in each markdown file, appending the newest summary under `### Iteration <N>`.
- Summaries should capture key deltas since the previous iteration so reruns can pick up context quickly.
- **After review completion**, update `Last reviewed SHA:` in `00-OVERVIEW.md` with the current `headRefOid` and update the timestamp.
### Smart step filtering (incremental reviews only)
When performing incremental review, skip steps that are irrelevant based on changed file types:
| File pattern | Required steps | Skippable steps |
| --- | --- | --- |
| `**/*.cs`, `**/*.cpp`, `**/*.h` | Functionality, Compatibility, Performance, Security, SOLID, Repo patterns, Code comments | (depends on files) |
| `**/*.resx`, `**/Resources/*.xaml` | Localization, Globalization | Most others |
| `**/*.md` (docs) | Docs & automation | Most others (unless copilot guidance) |
| `**/*copilot*.md`, `.github/prompts/*.md` | Copilot guidance, Docs & automation | Most others |
| `**/*.csproj`, `**/*.vcxproj`, `**/packages.config` | Compatibility, Security, Repo patterns | Localization, Globalization, Accessibility |
| `**/UI/**`, `**/*View.xaml` | Accessibility, Localization | Performance (unless perf-sensitive controls) |
**Default**: If uncertain or files span multiple categories, run all applicable steps. When in doubt, be conservative and review more rather than less.
## TODO steps (one concern each)
1) Functionality
2) Compatibility
3) Performance
4) Accessibility
5) Security
6) Localization
7) Globalization
8) Extensibility
9) SOLID principles
10) Repo patterns
11) Docs & automation coverage for the changes
12) Code comments
13) Copilot guidance (conditional): if changed folders contain `*copilot*.md` or `.github/prompts/*.md`, review diffs **against** that guidance and write `13-copilot-guidance.md` (omit if none).
## Per-step file template (use verbatim)
```md
# <STEP TITLE>
**PR:** (populate with PR identifier) — Base:<baseRefName> Head:<headRefName>
**Review iteration:** ITERATION
## Iteration history
- Maintain subsections titled `### Iteration N` in reverse chronological order (append the latest at the top) with 24 bullet highlights.
### Iteration ITERATION
- <Latest key point 1>
- <Latest key point 2>
## Checks executed
- List the concrete checks for *this step only* (510 bullets).
## Findings
(If none, write **None**. Defaults have one or more blocks:)
```mcp-review-comment
{"file":"relative/path.ext","start_line":123,"end_line":125,"severity":"high|medium|low|info","tags":["<step-slug>","pr-tag-here"],"related_files":["optional/other/file1"],"body":"Problem → Why it matters → Concrete fix. If spans multiple files, name them here."}
```
Use the second tag to encode the PR number.
```
## Overview file (`00-OVERVIEW.md`) template
```md
# PR Review Overview — (populate with PR identifier)
**Review iteration:** ITERATION
**Changed files:** <n> | **High severity issues:** <count>
## Review metadata
**Last reviewed SHA:** <headRefOid from gh pr view>
**Last review timestamp:** <ISO8601 timestamp>
**Review mode:** <Full|Incremental (N files changed since iteration X)>
**Base ref:** <baseRefName>
**Head ref:** <headRefName>
## Step results
Write lines like: `01 Functionality — <OK|Issues|Skipped> (see 01-functionality.md)` … through step 13.
Mark steps as "Skipped" when using incremental review smart filtering.
## Iteration history
- Maintain subsections titled `### Iteration N` mirroring the per-step convention with concise deltas and cross-links to the relevant step files.
- For incremental reviews, list the specific files that changed and which commits were added.
```
## Line numbers & multifile issues
- Map headside lines from `patch` hunks (`@@ -a,b +c,d @@` → new lines `+c..+c+d-1`).
- For crossfile issues: set the primary `"file"`, list others in `"related_files"`, and name them in `"body"`.
## Posting (for MCP)
- Parse all ```mcp-review-comment``` blocks across step files and post as PR review comments.
- If posting isnt available, still write all files.
## Constraint
Read/analyze only; don't modify code. Keep comments small, specific, and fixoriented.
**Testing**: Use `.github/review-tools/Test-IncrementalReview.ps1 -PullRequestNumber 42374` to preview incremental detection before running full review.
## Scratch cache for large PRs
Create a local scratch workspace to progressively summarize diffs and reload state across runs.
### Paths
- Root: `Generated Files/prReview/{{pr_number}}/__tmp/`
- Files:
- `index.jsonl` — append-only JSON Lines index of artifacts.
- `todo-queue.json` — pending items (files/chunks/steps).
- `rollup-<step>-v<N>.md` — iterative per-step aggregates.
- `file-<hash>.txt` — optional saved chunk text (when needed).
### JSON schema (per line in `index.jsonl`)
```json
{"type":"chunk|summary|issue|crosslink",
"path":"relative/file.ext","chunk_id":"f-12","step":"functionality|compatibility|...",
"base_sha":"...", "head_sha":"...", "range":[start,end], "version":1,
"notes":"short text or key:value map", "created_utc":"ISO8601"}
```
### Phases (stateful; resume-safe)
0. **Discover** PR + SHAs: `gh pr view <PR> --json baseRefName,headRefName,baseRefOid,headRefOid,files`.
1. **Chunk** each changed file (head): split into ~300600 LOC or ~4k chars; stable `chunk_id` = hash(path+start).
- Save `chunk` records. Optionally write `file-<hash>.txt` for expensive chunks.
2. **Summarize** per chunk: intent, APIs, risks per TODO step; emit `summary` records (≤600 tokens each).
3. **Issues**: convert findings to machine-readable blocks and emit `issue` records (later rendered to step MD).
4. **Rollups**: build/update `rollup-<step>-v<N>.md` from `summary`+`issue`. Keep prior versions.
5. **Finalize**: write per-step files + `00-OVERVIEW.md` from rollups. Post comments via MCP if available.
### Re-use & token limits
- Always **reload** `index.jsonl` first; skip chunks with same `head_sha` and `range`.
- **Incremental review optimization**: When `Get-PrIncrementalChanges.ps1` returns a subset of changed files, load only chunks from those files. Reuse existing chunks/summaries for unchanged files.
- Prefer re-summarizing only changed chunks; merge chunk summaries → file summaries → step rollups.
- When context is tight, load only the minimal chunk text (or its saved `file-<hash>.txt`) needed for a comment.
### Original vs diff
- Fetch base content when needed: prefer `git show <baseRefName>:<path>`; fallback `gh api repos/:owner/:repo/contents/<path>?ref=<base_sha>` (base64).
- Use patch hunks from `gh api .../pulls/<PR>/files` to compute **head** line numbers.
### Queue-driven loop
- Seed `todo-queue.json` with all changed files.
- Process: chunk → summarize → detect issues → roll up.
- Append to `index.jsonl` after each step; never rewrite previous lines (append-only).
### Hygiene
- `__tmp/` is implementation detail; do not include in final artifacts.
- It is safe to delete to force a clean pass; the next run rebuilds it.

View File

@@ -1,79 +0,0 @@
<#
.SYNOPSIS
Retrieves the unified diff patch for a specific file in a GitHub pull request.
.DESCRIPTION
This script fetches the patch content (unified diff format) for a specified file
within a pull request. It uses the GitHub CLI (gh) to query the GitHub API and
retrieve file change information.
.PARAMETER PullRequestNumber
The pull request number to query.
.PARAMETER FilePath
The relative path to the file in the repository (e.g., "src/modules/main.cpp").
.PARAMETER RepositoryOwner
The GitHub repository owner. Defaults to "microsoft".
.PARAMETER RepositoryName
The GitHub repository name. Defaults to "PowerToys".
.EXAMPLE
.\Get-GitHubPrFilePatch.ps1 -PullRequestNumber 42374 -FilePath "src/modules/cmdpal/main.cpp"
Retrieves the patch for main.cpp in PR #42374.
.EXAMPLE
.\Get-GitHubPrFilePatch.ps1 -PullRequestNumber 42374 -FilePath "README.md" -RepositoryOwner "myorg" -RepositoryName "myrepo"
Retrieves the patch from a different repository.
.NOTES
Requires GitHub CLI (gh) to be installed and authenticated.
Run 'gh auth login' if not already authenticated.
.LINK
https://cli.github.com/
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, HelpMessage = "Pull request number")]
[int]$PullRequestNumber,
[Parameter(Mandatory = $true, HelpMessage = "Relative path to the file in the repository")]
[string]$FilePath,
[Parameter(Mandatory = $false, HelpMessage = "Repository owner")]
[string]$RepositoryOwner = "microsoft",
[Parameter(Mandatory = $false, HelpMessage = "Repository name")]
[string]$RepositoryName = "PowerToys"
)
# Construct GitHub API path for pull request files
$apiPath = "repos/$RepositoryOwner/$RepositoryName/pulls/$PullRequestNumber/files?per_page=250"
# Query GitHub API to get all files in the pull request
try {
$pullRequestFiles = gh api $apiPath | ConvertFrom-Json
} catch {
Write-Error "Failed to query GitHub API for PR #$PullRequestNumber. Ensure gh CLI is authenticated. Details: $_"
exit 1
}
# Find the matching file in the pull request
$matchedFile = $pullRequestFiles | Where-Object { $_.filename -eq $FilePath }
if (-not $matchedFile) {
Write-Error "File '$FilePath' not found in PR #$PullRequestNumber."
exit 1
}
# Check if patch content exists
if (-not $matchedFile.patch) {
Write-Warning "File '$FilePath' has no patch content (possibly binary or too large)."
return
}
# Output the patch content
$matchedFile.patch

View File

@@ -1,91 +0,0 @@
<#
.SYNOPSIS
Downloads and displays the content of a file from a GitHub repository at a specific git reference.
.DESCRIPTION
This script fetches the raw content of a file from a GitHub repository using GitHub's raw content API.
It can optionally display line numbers and supports any valid git reference (branch, tag, or commit SHA).
.PARAMETER FilePath
The relative path to the file in the repository (e.g., "src/modules/main.cpp").
.PARAMETER GitReference
The git reference (branch name, tag, or commit SHA) to fetch the file from. Defaults to "main".
.PARAMETER RepositoryOwner
The GitHub repository owner. Defaults to "microsoft".
.PARAMETER RepositoryName
The GitHub repository name. Defaults to "PowerToys".
.PARAMETER ShowLineNumbers
When specified, displays line numbers before each line of content.
.PARAMETER StartLineNumber
The starting line number to use when ShowLineNumbers is enabled. Defaults to 1.
.EXAMPLE
.\Get-GitHubRawFile.ps1 -FilePath "README.md" -GitReference "main"
Downloads and displays the README.md file from the main branch.
.EXAMPLE
.\Get-GitHubRawFile.ps1 -FilePath "src/runner/main.cpp" -GitReference "dev/feature-branch" -ShowLineNumbers
Downloads main.cpp from a feature branch and displays it with line numbers.
.EXAMPLE
.\Get-GitHubRawFile.ps1 -FilePath "LICENSE" -GitReference "abc123def" -ShowLineNumbers -StartLineNumber 10
Downloads the LICENSE file from a specific commit and displays it with line numbers starting at 10.
.NOTES
Requires internet connectivity to access GitHub's raw content API.
Does not require GitHub CLI authentication for public repositories.
.LINK
https://docs.github.com/en/rest/repos/contents
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, HelpMessage = "Relative path to the file in the repository")]
[string]$FilePath,
[Parameter(Mandatory = $false, HelpMessage = "Git reference (branch, tag, or commit SHA)")]
[string]$GitReference = "main",
[Parameter(Mandatory = $false, HelpMessage = "Repository owner")]
[string]$RepositoryOwner = "microsoft",
[Parameter(Mandatory = $false, HelpMessage = "Repository name")]
[string]$RepositoryName = "PowerToys",
[Parameter(Mandatory = $false, HelpMessage = "Display line numbers before each line")]
[switch]$ShowLineNumbers,
[Parameter(Mandatory = $false, HelpMessage = "Starting line number for display")]
[int]$StartLineNumber = 1
)
# Construct the raw content URL
$rawContentUrl = "https://raw.githubusercontent.com/$RepositoryOwner/$RepositoryName/$GitReference/$FilePath"
# Fetch the file content from GitHub
try {
$response = Invoke-WebRequest -UseBasicParsing -Uri $rawContentUrl
} catch {
Write-Error "Failed to fetch file from $rawContentUrl. Details: $_"
exit 1
}
# Split content into individual lines
$contentLines = $response.Content -split "`n"
# Display the content with or without line numbers
if ($ShowLineNumbers) {
$currentLineNumber = $StartLineNumber
foreach ($line in $contentLines) {
Write-Output ("{0:d4}: {1}" -f $currentLineNumber, $line)
$currentLineNumber++
}
} else {
$contentLines | ForEach-Object { Write-Output $_ }
}

View File

@@ -1,173 +0,0 @@
<#
.SYNOPSIS
Detects changes between the last reviewed commit and current head of a pull request.
.DESCRIPTION
This script compares a previously reviewed commit SHA with the current head of a pull request
to determine what has changed. It helps enable incremental reviews by identifying new commits
and modified files since the last review iteration.
The script handles several scenarios:
- First review (no previous SHA provided)
- No changes (current SHA matches last reviewed SHA)
- Force-push detected (last reviewed SHA no longer in history)
- Incremental changes (new commits added since last review)
.PARAMETER PullRequestNumber
The pull request number to analyze.
.PARAMETER LastReviewedCommitSha
The commit SHA that was last reviewed. If omitted, this is treated as a first review.
.PARAMETER RepositoryOwner
The GitHub repository owner. Defaults to "microsoft".
.PARAMETER RepositoryName
The GitHub repository name. Defaults to "PowerToys".
.OUTPUTS
JSON object containing:
- PullRequestNumber: The PR number being analyzed
- CurrentHeadSha: The current head commit SHA
- LastReviewedSha: The last reviewed commit SHA (if provided)
- BaseRefName: Base branch name
- HeadRefName: Head branch name
- IsIncremental: Boolean indicating if incremental review is possible
- NeedFullReview: Boolean indicating if a full review is required
- ChangedFiles: Array of files that changed (filename, status, additions, deletions)
- NewCommits: Array of commits added since last review (sha, message, author, date)
- Summary: Human-readable description of changes
.EXAMPLE
.\Get-PrIncrementalChanges.ps1 -PullRequestNumber 42374
Analyzes PR #42374 with no previous review (first review scenario).
.EXAMPLE
.\Get-PrIncrementalChanges.ps1 -PullRequestNumber 42374 -LastReviewedCommitSha "abc123def456"
Compares current PR state against the last reviewed commit to identify incremental changes.
.EXAMPLE
$changes = .\Get-PrIncrementalChanges.ps1 -PullRequestNumber 42374 -LastReviewedCommitSha "abc123" | ConvertFrom-Json
if ($changes.IsIncremental) { Write-Host "Can perform incremental review" }
Captures the output as a PowerShell object for further processing.
.NOTES
Requires GitHub CLI (gh) to be installed and authenticated.
Run 'gh auth login' if not already authenticated.
.LINK
https://cli.github.com/
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, HelpMessage = "Pull request number")]
[int]$PullRequestNumber,
[Parameter(Mandatory = $false, HelpMessage = "Commit SHA that was last reviewed")]
[string]$LastReviewedCommitSha,
[Parameter(Mandatory = $false, HelpMessage = "Repository owner")]
[string]$RepositoryOwner = "microsoft",
[Parameter(Mandatory = $false, HelpMessage = "Repository name")]
[string]$RepositoryName = "PowerToys"
)
# Fetch current pull request state from GitHub
try {
$pullRequestData = gh pr view $PullRequestNumber --json headRefOid,headRefName,baseRefName,baseRefOid | ConvertFrom-Json
} catch {
Write-Error "Failed to fetch PR #$PullRequestNumber details. Details: $_"
exit 1
}
$currentHeadSha = $pullRequestData.headRefOid
$baseRefName = $pullRequestData.baseRefName
$headRefName = $pullRequestData.headRefName
# Initialize result object
$analysisResult = @{
PullRequestNumber = $PullRequestNumber
CurrentHeadSha = $currentHeadSha
BaseRefName = $baseRefName
HeadRefName = $headRefName
LastReviewedSha = $LastReviewedCommitSha
IsIncremental = $false
NeedFullReview = $true
ChangedFiles = @()
NewCommits = @()
Summary = ""
}
# Scenario 1: First review (no previous SHA provided)
if ([string]::IsNullOrWhiteSpace($LastReviewedCommitSha)) {
$analysisResult.Summary = "Initial review - no previous iteration found"
$analysisResult.NeedFullReview = $true
return $analysisResult | ConvertTo-Json -Depth 10
}
# Scenario 2: No changes since last review
if ($currentHeadSha -eq $LastReviewedCommitSha) {
$analysisResult.Summary = "No changes since last review (SHA: $currentHeadSha)"
$analysisResult.NeedFullReview = $false
$analysisResult.IsIncremental = $true
return $analysisResult | ConvertTo-Json -Depth 10
}
# Scenario 3: Check for force-push (last reviewed SHA no longer exists in history)
try {
$null = gh api "repos/$RepositoryOwner/$RepositoryName/commits/$LastReviewedCommitSha" 2>&1
if ($LASTEXITCODE -ne 0) {
# SHA not found - likely force-push or branch rewrite
$analysisResult.Summary = "Force-push detected - last reviewed SHA $LastReviewedCommitSha no longer exists. Full review required."
$analysisResult.NeedFullReview = $true
return $analysisResult | ConvertTo-Json -Depth 10
}
} catch {
$analysisResult.Summary = "Cannot verify last reviewed SHA $LastReviewedCommitSha - assuming force-push. Full review required."
$analysisResult.NeedFullReview = $true
return $analysisResult | ConvertTo-Json -Depth 10
}
# Scenario 4: Get incremental changes between last reviewed SHA and current head
try {
$compareApiPath = "repos/$RepositoryOwner/$RepositoryName/compare/$LastReviewedCommitSha...$currentHeadSha"
$comparisonData = gh api $compareApiPath | ConvertFrom-Json
# Extract new commits information
$analysisResult.NewCommits = $comparisonData.commits | ForEach-Object {
@{
Sha = $_.sha.Substring(0, 7)
Message = $_.commit.message.Split("`n")[0] # First line only
Author = $_.commit.author.name
Date = $_.commit.author.date
}
}
# Extract changed files information
$analysisResult.ChangedFiles = $comparisonData.files | ForEach-Object {
@{
Filename = $_.filename
Status = $_.status # added, modified, removed, renamed
Additions = $_.additions
Deletions = $_.deletions
Changes = $_.changes
}
}
$fileCount = $analysisResult.ChangedFiles.Count
$commitCount = $analysisResult.NewCommits.Count
$analysisResult.IsIncremental = $true
$analysisResult.NeedFullReview = $false
$analysisResult.Summary = "Incremental review: $commitCount new commit(s), $fileCount file(s) changed since SHA $($LastReviewedCommitSha.Substring(0, 7))"
} catch {
Write-Error "Failed to compare commits. Details: $_"
$analysisResult.Summary = "Error comparing commits - defaulting to full review"
$analysisResult.NeedFullReview = $true
}
# Return the analysis result as JSON
return $analysisResult | ConvertTo-Json -Depth 10

View File

@@ -1,170 +0,0 @@
<#
.SYNOPSIS
Tests and previews incremental review detection for a pull request.
.DESCRIPTION
This helper script validates the incremental review detection logic by analyzing an existing
PR review folder. It reads the last reviewed SHA from the overview file, compares it with
the current PR state, and displays detailed information about what has changed.
This is useful for:
- Testing the incremental review system before running a full review
- Understanding what changed since the last review iteration
- Verifying that review metadata was properly recorded
.PARAMETER PullRequestNumber
The pull request number to test incremental review detection for.
.PARAMETER RepositoryOwner
The GitHub repository owner. Defaults to "microsoft".
.PARAMETER RepositoryName
The GitHub repository name. Defaults to "PowerToys".
.OUTPUTS
Colored console output displaying:
- Current and last reviewed commit SHAs
- Whether incremental review is possible
- List of new commits since last review
- List of changed files with status indicators
- Recommended review strategy
.EXAMPLE
.\Test-IncrementalReview.ps1 -PullRequestNumber 42374
Tests incremental review detection for PR #42374.
.EXAMPLE
.\Test-IncrementalReview.ps1 -PullRequestNumber 42374 -RepositoryOwner "myorg" -RepositoryName "myrepo"
Tests incremental review for a PR in a different repository.
.NOTES
Requires GitHub CLI (gh) to be installed and authenticated.
Run 'gh auth login' if not already authenticated.
Prerequisites:
- PR review folder must exist at "Generated Files\prReview\{PRNumber}"
- 00-OVERVIEW.md must exist in the review folder
- For incremental detection, overview must contain "Last reviewed SHA" metadata
.LINK
https://cli.github.com/
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, HelpMessage = "Pull request number to test")]
[int]$PullRequestNumber,
[Parameter(Mandatory = $false, HelpMessage = "Repository owner")]
[string]$RepositoryOwner = "microsoft",
[Parameter(Mandatory = $false, HelpMessage = "Repository name")]
[string]$RepositoryName = "PowerToys"
)
# Resolve paths to review folder and overview file
$repositoryRoot = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
$reviewFolderPath = Join-Path $repositoryRoot "Generated Files\prReview\$PullRequestNumber"
$overviewFilePath = Join-Path $reviewFolderPath "00-OVERVIEW.md"
Write-Host "=== Testing Incremental Review for PR #$PullRequestNumber ===" -ForegroundColor Cyan
Write-Host ""
# Check if review folder exists
if (-not (Test-Path $reviewFolderPath)) {
Write-Host "❌ Review folder not found: $reviewFolderPath" -ForegroundColor Red
Write-Host "This appears to be a new review (iteration 1)" -ForegroundColor Yellow
exit 0
}
# Check if overview file exists
if (-not (Test-Path $overviewFilePath)) {
Write-Host "❌ Overview file not found: $overviewFilePath" -ForegroundColor Red
Write-Host "This appears to be an incomplete review" -ForegroundColor Yellow
exit 0
}
# Read overview file and extract last reviewed SHA
Write-Host "📄 Reading overview file..." -ForegroundColor Green
$overviewFileContent = Get-Content $overviewFilePath -Raw
if ($overviewFileContent -match '\*\*Last reviewed SHA:\*\*\s+(\w+)') {
$lastReviewedSha = $Matches[1]
Write-Host "✅ Found last reviewed SHA: $lastReviewedSha" -ForegroundColor Green
} else {
Write-Host "⚠️ No 'Last reviewed SHA' found in overview - this may be an old format" -ForegroundColor Yellow
Write-Host "Proceeding without incremental detection (full review will be needed)" -ForegroundColor Yellow
exit 0
}
Write-Host ""
Write-Host "🔍 Running incremental change detection..." -ForegroundColor Cyan
# Call the incremental changes detection script
$incrementalChangesScriptPath = Join-Path $PSScriptRoot "Get-PrIncrementalChanges.ps1"
if (-not (Test-Path $incrementalChangesScriptPath)) {
Write-Host "❌ Script not found: $incrementalChangesScriptPath" -ForegroundColor Red
exit 1
}
try {
$analysisResult = & $incrementalChangesScriptPath `
-PullRequestNumber $PullRequestNumber `
-LastReviewedCommitSha $lastReviewedSha `
-RepositoryOwner $RepositoryOwner `
-RepositoryName $RepositoryName | ConvertFrom-Json
# Display analysis results
Write-Host ""
Write-Host "=== Incremental Review Analysis ===" -ForegroundColor Cyan
Write-Host "Current HEAD SHA: $($analysisResult.CurrentHeadSha)" -ForegroundColor White
Write-Host "Last reviewed SHA: $($analysisResult.LastReviewedSha)" -ForegroundColor White
Write-Host "Base branch: $($analysisResult.BaseRefName)" -ForegroundColor White
Write-Host "Head branch: $($analysisResult.HeadRefName)" -ForegroundColor White
Write-Host ""
Write-Host "Is incremental? $($analysisResult.IsIncremental)" -ForegroundColor $(if ($analysisResult.IsIncremental) { "Green" } else { "Yellow" })
Write-Host "Need full review? $($analysisResult.NeedFullReview)" -ForegroundColor $(if ($analysisResult.NeedFullReview) { "Yellow" } else { "Green" })
Write-Host ""
Write-Host "Summary: $($analysisResult.Summary)" -ForegroundColor Cyan
Write-Host ""
# Display new commits if any
if ($analysisResult.NewCommits -and $analysisResult.NewCommits.Count -gt 0) {
Write-Host "📝 New commits ($($analysisResult.NewCommits.Count)):" -ForegroundColor Green
foreach ($commit in $analysisResult.NewCommits) {
Write-Host " - $($commit.Sha): $($commit.Message)" -ForegroundColor Gray
}
Write-Host ""
}
# Display changed files if any
if ($analysisResult.ChangedFiles -and $analysisResult.ChangedFiles.Count -gt 0) {
Write-Host "📁 Changed files ($($analysisResult.ChangedFiles.Count)):" -ForegroundColor Green
foreach ($file in $analysisResult.ChangedFiles) {
$statusDisplayColor = switch ($file.Status) {
"added" { "Green" }
"removed" { "Red" }
"modified" { "Yellow" }
"renamed" { "Cyan" }
default { "White" }
}
Write-Host " - [$($file.Status)] $($file.Filename) (+$($file.Additions)/-$($file.Deletions))" -ForegroundColor $statusDisplayColor
}
Write-Host ""
}
# Suggest review strategy based on analysis
Write-Host "=== Recommended Review Strategy ===" -ForegroundColor Cyan
if ($analysisResult.NeedFullReview) {
Write-Host "🔄 Full review recommended" -ForegroundColor Yellow
} elseif ($analysisResult.IsIncremental -and ($analysisResult.ChangedFiles.Count -eq 0)) {
Write-Host "✅ No changes detected - no review needed" -ForegroundColor Green
} elseif ($analysisResult.IsIncremental) {
Write-Host "⚡ Incremental review possible - review only changed files" -ForegroundColor Green
Write-Host "💡 Consider applying smart step filtering based on file types" -ForegroundColor Cyan
}
} catch {
Write-Host "❌ Error running incremental change detection: $_" -ForegroundColor Red
exit 1
}

View File

@@ -1,313 +0,0 @@
---
description: PowerShell scripts for efficient PR reviews in PowerToys repository
applyTo: '**'
---
# PR Review Tools - Reference Guide
PowerShell scripts to support efficient and incremental pull request reviews in the PowerToys repository.
## Quick Start
### Prerequisites
- PowerShell 7+ (or Windows PowerShell 5.1+)
- GitHub CLI (`gh`) installed and authenticated (`gh auth login`)
- Access to the PowerToys repository
### Testing Your Setup
Run the full test suite (recommended):
```powershell
cd "d:\PowerToys-00c1\.github\review-tools"
.\Run-ReviewToolsTests.ps1
```
Expected: 9-10 tests passing
### Individual Script Tests
**Test incremental change detection:**
```powershell
.\Get-PrIncrementalChanges.ps1 -PullRequestNumber 42374
```
Expected: JSON output showing review analysis
**Preview incremental review:**
```powershell
.\Test-IncrementalReview.ps1 -PullRequestNumber 42374
```
Expected: Analysis showing current vs last reviewed SHA
**Fetch file content:**
```powershell
.\Get-GitHubRawFile.ps1 -FilePath "README.md" -GitReference "main"
```
Expected: README content displayed
**Get PR file patch:**
```powershell
.\Get-GitHubPrFilePatch.ps1 -PullRequestNumber 42374 -FilePath ".github/actions/spell-check/expect.txt"
```
Expected: Unified diff output
## Available Scripts
### Get-GitHubRawFile.ps1
Downloads and displays file content from a GitHub repository at a specific git reference.
**Purpose:** Retrieve baseline file content for comparison during PR reviews.
**Parameters:**
- `FilePath` (required): Relative path to file in repository
- `GitReference` (optional): Git ref (branch, tag, SHA). Default: "main"
- `RepositoryOwner` (optional): Repository owner. Default: "microsoft"
- `RepositoryName` (optional): Repository name. Default: "PowerToys"
- `ShowLineNumbers` (switch): Prefix each line with line number
- `StartLineNumber` (optional): Starting line number when using `-ShowLineNumbers`. Default: 1
**Usage:**
```powershell
.\Get-GitHubRawFile.ps1 -FilePath "src/runner/main.cpp" -GitReference "main" -ShowLineNumbers
```
### Get-GitHubPrFilePatch.ps1
Fetches the unified diff (patch) for a specific file in a pull request.
**Purpose:** Get the exact changes made to a file in a PR for detailed review.
**Parameters:**
- `PullRequestNumber` (required): Pull request number
- `FilePath` (required): Relative path to file in the PR
- `RepositoryOwner` (optional): Repository owner. Default: "microsoft"
- `RepositoryName` (optional): Repository name. Default: "PowerToys"
**Usage:**
```powershell
.\Get-GitHubPrFilePatch.ps1 -PullRequestNumber 42374 -FilePath "src/modules/cmdpal/main.cpp"
```
**Output:** Unified diff showing changes made to the file.
### Get-PrIncrementalChanges.ps1
Compares the last reviewed commit with the current PR head to identify incremental changes.
**Purpose:** Enable efficient incremental reviews by detecting what changed since the last review iteration.
**Parameters:**
- `PullRequestNumber` (required): Pull request number
- `LastReviewedCommitSha` (optional): SHA of the commit that was last reviewed. If omitted, assumes first review.
- `RepositoryOwner` (optional): Repository owner. Default: "microsoft"
- `RepositoryName` (optional): Repository name. Default: "PowerToys"
**Usage:**
```powershell
.\Get-PrIncrementalChanges.ps1 -PullRequestNumber 42374 -LastReviewedCommitSha "abc123def456"
```
**Output:** JSON object with detailed change analysis:
```json
{
"PullRequestNumber": 42374,
"CurrentHeadSha": "xyz789abc123",
"LastReviewedSha": "abc123def456",
"IsIncremental": true,
"NeedFullReview": false,
"ChangedFiles": [
{
"Filename": "src/modules/cmdpal/main.cpp",
"Status": "modified",
"Additions": 15,
"Deletions": 8,
"Changes": 23
}
],
"NewCommits": [
{
"Sha": "def456",
"Message": "Fix memory leak",
"Author": "John Doe",
"Date": "2025-11-07T10:30:00Z"
}
],
"Summary": "Incremental review: 1 new commit(s), 1 file(s) changed since SHA abc123d"
}
```
**Scenarios Handled:**
- **No LastReviewedCommitSha**: Returns `NeedFullReview: true` (first review)
- **SHA matches current HEAD**: Returns empty `ChangedFiles` (no changes)
- **Force-push detected**: Returns `NeedFullReview: true` (SHA not in history)
- **Incremental changes**: Returns list of changed files and new commits
### Test-IncrementalReview.ps1
Helper script to test and preview incremental review detection before running the full review.
**Purpose:** Validate incremental review functionality and preview what changed.
**Parameters:**
- `PullRequestNumber` (required): Pull request number
- `RepositoryOwner` (optional): Repository owner. Default: "microsoft"
- `RepositoryName` (optional): Repository name. Default: "PowerToys"
**Usage:**
```powershell
.\Test-IncrementalReview.ps1 -PullRequestNumber 42374
```
**Output:** Colored console output showing:
- Current and last reviewed SHAs
- Whether incremental review is possible
- List of new commits and changed files
- Recommended review strategy
## Workflow Integration
These scripts integrate with the PR review prompt (`.github/prompts/review-pr.prompt.md`).
### Typical Review Flow
1. **Initial Review (Iteration 1)**
- Review prompt processes the PR
- Creates `Generated Files/prReview/{PR}/00-OVERVIEW.md`
- Includes review metadata section with current HEAD SHA
2. **Subsequent Reviews (Iteration 2+)**
- Review prompt reads `00-OVERVIEW.md` to get last reviewed SHA
- Calls `Get-PrIncrementalChanges.ps1` to detect what changed
- If incremental:
- Reviews only changed files
- Skips irrelevant review steps (e.g., skip Localization if no `.resx` files changed)
- Uses `Get-GitHubPrFilePatch.ps1` to get patches for changed files
- Updates `00-OVERVIEW.md` with new SHA and iteration number
### Manual Testing Workflow
Preview changes before review:
```powershell
# Check what changed in PR #42374 since last review
.\Test-IncrementalReview.ps1 -PullRequestNumber 42374
# Get incremental changes programmatically
$changes = .\Get-PrIncrementalChanges.ps1 -PullRequestNumber 42374 -LastReviewedCommitSha "abc123" | ConvertFrom-Json
if (-not $changes.NeedFullReview) {
Write-Host "Only need to review $($changes.ChangedFiles.Count) files"
# Review each changed file
foreach ($file in $changes.ChangedFiles) {
Write-Host "Reviewing $($file.Filename)..."
.\Get-GitHubPrFilePatch.ps1 -PullRequestNumber 42374 -FilePath $file.Filename
}
}
```
## Error Handling and Troubleshooting
### Common Requirements
All scripts:
- Exit with code 1 on error
- Write detailed error messages to stderr
- Require `gh` CLI to be installed and authenticated
### Common Issues
**Error: "gh not found"**
- **Solution**: Install GitHub CLI from https://cli.github.com/ and run `gh auth login`
**Error: "Failed to query GitHub API"**
- **Solution**: Verify `gh` authentication with `gh auth status`
- **Solution**: Check PR number exists and you have repository access
**Error: "PR not found"**
- **Solution**: Verify the PR number is correct and still exists
- **Solution**: Ensure repository owner and name are correct
**Error: "SHA not found" or "Force-push detected"**
- **Explanation**: Last reviewed SHA no longer exists in branch history (force-push occurred)
- **Solution**: A full review is required; incremental review not possible
**Tests show "FAIL" but functionality works**
- **Explanation**: Some tests may show exit code failures even when logic is correct
- **Solution**: Check test output message - if it says "Correctly detected", functionality is working
**Error: "Could not find insertion point"**
- **Explanation**: Overview file doesn't have expected "**Changed files:**" line
- **Solution**: Verify overview file format is correct or regenerate it
### Verification Checklist
After setup, verify:
- [ ] `Run-ReviewToolsTests.ps1` shows 9+ tests passing
- [ ] `Get-PrIncrementalChanges.ps1` returns valid JSON
- [ ] `Test-IncrementalReview.ps1` analyzes a PR without errors
- [ ] `Get-GitHubRawFile.ps1` downloads files correctly
- [ ] `Get-GitHubPrFilePatch.ps1` retrieves patches correctly
## Best Practices
### For Review Authors
1. **Test before full review**: Use `Test-IncrementalReview.ps1` to preview changes
2. **Check for force-push**: Review the analysis output - force-pushes require full reviews
3. **Smart step filtering**: Skip review steps for file types that didn't change
### For Script Users
1. **Use absolute paths**: When specifying folders, use absolute paths to avoid ambiguity
2. **Check exit codes**: Scripts exit with code 1 on error - check `$LASTEXITCODE` in automation
3. **Parse JSON output**: Use `ConvertFrom-Json` to work with structured output from `Get-PrIncrementalChanges.ps1`
4. **Handle empty results**: Check `ChangedFiles.Count` before iterating
### Performance Tips
1. **Batch operations**: When reviewing multiple PRs, collect all PR numbers and process in batch
2. **Cache raw files**: Download baseline files once and reuse for multiple comparisons
3. **Filter early**: Use incremental detection to skip unnecessary file reviews
4. **Parallel processing**: Consider processing independent PRs in parallel
## Integration with AI Review Systems
These tools are designed to work with AI-powered review systems:
1. **Copilot Instructions**: This file serves as reference documentation for GitHub Copilot
2. **Structured Output**: JSON output from scripts is easily parsed by AI systems
3. **Incremental Intelligence**: AI can focus on changed files for more efficient reviews
4. **Metadata Tracking**: Review iterations are tracked for context-aware suggestions
### Example AI Integration
```powershell
# Get incremental changes
$analysis = .\Get-PrIncrementalChanges.ps1 -PullRequestNumber $PR | ConvertFrom-Json
# Feed to AI review system
$reviewPrompt = @"
Review the following changed files in PR #$PR:
$($analysis.ChangedFiles | ForEach-Object { "- $($_.Filename) ($($_.Status))" } | Out-String)
Focus on incremental changes only. Previous review was at SHA $($analysis.LastReviewedSha).
"@
# Execute AI review with context
Invoke-AIReview -Prompt $reviewPrompt -Files $analysis.ChangedFiles
```
## Support and Further Information
For detailed script documentation, use PowerShell's help system:
```powershell
Get-Help .\Get-PrIncrementalChanges.ps1 -Full
Get-Help .\Test-IncrementalReview.ps1 -Detailed
```
Related documentation:
- `.github/prompts/review-pr.prompt.md` - Complete review workflow guide
- `doc/devdocs/` - PowerToys development documentation
- GitHub CLI documentation: https://cli.github.com/manual/
For issues or questions, refer to the PowerToys contribution guidelines.

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,130 +0,0 @@
---
name: issue-fix
description: Automatically fix GitHub issues using AI-assisted code generation. Use when asked to fix an issue, implement a feature from an issue, auto-fix an issue, apply implementation plan, create code changes for an issue, or resolve a GitHub issue. Creates isolated git worktree and applies AI-generated fixes based on the implementation plan.
license: Complete terms in LICENSE.txt
---
# Issue Fix Skill
Automatically fix GitHub issues by creating isolated worktrees and applying AI-generated code changes based on implementation plans.
## Skill Contents
This skill is **self-contained** with all required resources:
```
.github/skills/issue-fix/
├── SKILL.md # This file
├── LICENSE.txt # MIT License
├── scripts/
│ └── Start-IssueAutoFix.ps1 # Main fix script
└── references/
└── fix-issue.prompt.md # Full AI prompt template
```
## Output Directory
Worktrees are created at the drive root level:
```
Q:/PowerToys-xxxx/ # Worktree for issue (xxxx = short hash)
├── Generated Files/
│ └── issueReview/
│ └── <issue-number>/ # Copied from main repo
│ ├── overview.md
│ └── implementation-plan.md
└── <normal repo structure>
```
## When to Use This Skill
- Fix a specific GitHub issue automatically
- Implement a feature described in an issue
- Apply an existing implementation plan
- Create code changes for an issue
- Auto-fix high-confidence issues
- Resolve issues that have been reviewed
## Prerequisites
- GitHub CLI (`gh`) installed and authenticated
- Issue must be reviewed first (use `issue-review` skill)
- PowerShell 7+ for running scripts
- Copilot CLI or Claude CLI installed
## Required Variables
⚠️ **Before starting**, confirm `{{IssueNumber}}` with the user. If not provided, **ASK**: "What issue number should I fix?"
| Variable | Description | Example |
|----------|-------------|---------|
| `{{IssueNumber}}` | GitHub issue number to fix | `44044` |
## Workflow
### Step 1: Ensure Issue is Reviewed
If not already reviewed, use the `issue-review` skill first.
### Step 2: Run Auto-Fix
Execute the fix script (use paths relative to this skill folder):
```powershell
# From repo root
.github/skills/issue-fix/scripts/Start-IssueAutoFix.ps1 -IssueNumber {{IssueNumber}} -CLIType copilot
```
This will:
1. Create a new git worktree with branch `issue/{{IssueNumber}}`
2. Copy the review files to the worktree
3. Launch Copilot CLI to implement the fix
4. Build and verify the changes
### Step 3: Verify Changes
Navigate to the worktree and review:
```powershell
# List worktrees
git worktree list
# Check changes in the worktree
cd Q:/PowerToys-xxxx
git diff
git status
```
## CLI Options
| Parameter | Description | Default |
|-----------|-------------|---------|
| `-IssueNumber` | Issue to fix | Required |
| `-CLIType` | AI CLI to use: `copilot` or `claude` | `copilot` |
| `-Force` | Skip confirmation prompts | `false` |
## Batch Fix
To fix multiple issues:
```powershell
.github/skills/issue-fix/scripts/Start-IssueAutoFix.ps1 -IssueNumbers 44044, 32950 -CLIType copilot -Force
```
## After Fixing
Once the fix is complete, use the `submit-pr` skill to create a PR.
## AI Prompt Reference
For manual AI invocation, the full prompt is at:
- `references/fix-issue.prompt.md` (relative to this skill folder)
## Troubleshooting
| Problem | Solution |
|---------|----------|
| Worktree already exists | Use existing worktree or delete with `git worktree remove <path>` |
| No implementation plan | Use `issue-review` skill first |
| Build failures | Check build logs, may need manual intervention |
| CLI not found | Install Copilot CLI |

View File

@@ -1,72 +0,0 @@
---
agent: 'agent'
description: 'Execute the fix for a GitHub issue using the previously generated implementation plan'
---
# Fix GitHub Issue
## Dependencies
Source review prompt (for generating the implementation plan if missing):
- .github/prompts/review-issue.prompt.md
Required plan file (single source of truth):
- Generated Files/issueReview/{{issue_number}}/implementation-plan.md
## Dependency Handling
1) If `implementation-plan.md` exists → proceed.
2) If missing → run the review prompt:
- Invoke: `.github/prompts/review-issue.prompt.md`
- Pass: `issue_number={{issue_number}}`
- Then re-check for `implementation-plan.md`.
3) If still missing → stop and generate:
- `Generated Files/issueFix/{{issue_number}}/manual-steps.md` containing:
“implementation-plan.md not found; please run .github/prompts/review-issue.prompt.md for #{{issue_number}}.”
# GOAL
For **#{{issue_number}}**:
- Use implementation-plan.md as the single authority.
- Apply code and test changes directly in the repository.
- Produce a PR-ready description.
# OUTPUT FILES
1) Generated Files/issueFix/{{issue_number}}/pr-description.md
2) Generated Files/issueFix/{{issue_number}}/manual-steps.md # only if human interaction or external setup is required
# EXECUTION RULES
1) Read implementation-plan.md and execute:
- Layers & Files → edit/create as listed
- Pattern Choices → follow repository conventions
- Fundamentals (perf, security, compatibility, accessibility)
- Logging & Exceptions
- Telemetry (only if explicitly included in the plan)
- Risks & Mitigations
- Tests to Add
2) Locate affected files via `rg` or `git grep`.
3) Add/update tests to enforce the fixed behavior.
4) If any ambiguity exists, add:
// TODO(Human input needed): <clarification needed>
5) Verify locally: build & tests run successfully.
# pr-description.md should include:
- Title: `Fix: <short summary> (#{{issue_number}})`
- What changed and why the fix works
- Files or modules touched
- Risks & mitigations (implemented)
- Tests added/updated and how to run them
- Telemetry behavior (if applicable)
- Validation / reproduction steps
- `Closes #{{issue_number}}`
# manual-steps.md (only if needed)
- List required human actions: secrets, config, approvals, missing info, or code comments requiring human decisions.
# IMPORTANT
- Apply code and tests directly; do not produce patch files.
- Follow implementation-plan.md as the source of truth.
- Insert comments for human review where a decision or input is required.
- Use repository conventions and deterministic, minimal changes.
# FINALIZE
- Write pr-description.md
- Write manual-steps.md only if needed
- Print concise success message or note items requiring human interaction

View File

@@ -1,9 +0,0 @@
{
"mcpServers": {
"github-artifacts": {
"command": "cmd",
"args": ["/c", "for /f %i in ('git rev-parse --show-toplevel') do node %i/tools/mcp/github-artifacts/launch.js"],
"tools": ["*"]
}
}
}

View File

@@ -1,643 +0,0 @@
# IssueReviewLib.ps1 - Helpers for issue auto-fix workflow
# Part of the PowerToys GitHub Copilot/Claude Code issue review system
# This is a trimmed version with only what issue-fix needs
#region Console Output Helpers
function Info { param([string]$Message) Write-Host $Message -ForegroundColor Cyan }
function Warn { param([string]$Message) Write-Host $Message -ForegroundColor Yellow }
function Err { param([string]$Message) Write-Host $Message -ForegroundColor Red }
function Success { param([string]$Message) Write-Host $Message -ForegroundColor Green }
#endregion
#region Repository Helpers
function Get-RepoRoot {
$root = git rev-parse --show-toplevel 2>$null
if (-not $root) { throw 'Not inside a git repository.' }
return (Resolve-Path $root).Path
}
function Get-GeneratedFilesPath {
param([string]$RepoRoot)
return Join-Path $RepoRoot 'Generated Files'
}
function Get-IssueReviewPath {
param(
[string]$RepoRoot,
[int]$IssueNumber
)
$genFiles = Get-GeneratedFilesPath -RepoRoot $RepoRoot
return Join-Path $genFiles "issueReview/$IssueNumber"
}
function Ensure-DirectoryExists {
param([string]$Path)
if (-not (Test-Path $Path)) {
New-Item -ItemType Directory -Path $Path -Force | Out-Null
}
}
#endregion
#region CLI Detection
function Get-AvailableCLI {
<#
.SYNOPSIS
Detect which AI CLI is available: GitHub Copilot CLI or Claude Code.
#>
# Check for standalone GitHub Copilot CLI
$copilotCLI = Get-Command 'copilot' -ErrorAction SilentlyContinue
if ($copilotCLI) {
return @{ Name = 'GitHub Copilot CLI'; Command = 'copilot'; Type = 'copilot' }
}
# Check for Claude Code CLI
$claudeCode = Get-Command 'claude' -ErrorAction SilentlyContinue
if ($claudeCode) {
return @{ Name = 'Claude Code CLI'; Command = 'claude'; Type = 'claude' }
}
# Check for GitHub Copilot CLI via gh extension
$ghCopilot = Get-Command 'gh' -ErrorAction SilentlyContinue
if ($ghCopilot) {
$copilotCheck = gh extension list 2>&1 | Select-String -Pattern 'copilot'
if ($copilotCheck) {
return @{ Name = 'GitHub Copilot CLI (gh extension)'; Command = 'gh'; Type = 'gh-copilot' }
}
}
# Check for VS Code CLI
$code = Get-Command 'code' -ErrorAction SilentlyContinue
if ($code) {
return @{ Name = 'VS Code (Copilot Chat)'; Command = 'code'; Type = 'vscode' }
}
return $null
}
#endregion
#region Issue Review Results Helpers
function Get-IssueReviewResult {
<#
.SYNOPSIS
Check if an issue has been reviewed and get its results.
#>
param(
[Parameter(Mandatory)]
[int]$IssueNumber,
[Parameter(Mandatory)]
[string]$RepoRoot
)
$reviewPath = Get-IssueReviewPath -RepoRoot $RepoRoot -IssueNumber $IssueNumber
$result = @{
IssueNumber = $IssueNumber
Path = $reviewPath
HasOverview = $false
HasImplementationPlan = $false
OverviewPath = $null
ImplementationPlanPath = $null
}
$overviewPath = Join-Path $reviewPath 'overview.md'
$implPlanPath = Join-Path $reviewPath 'implementation-plan.md'
if (Test-Path $overviewPath) {
$result.HasOverview = $true
$result.OverviewPath = $overviewPath
}
if (Test-Path $implPlanPath) {
$result.HasImplementationPlan = $true
$result.ImplementationPlanPath = $implPlanPath
}
return $result
}
function Get-HighConfidenceIssues {
<#
.SYNOPSIS
Find issues with high confidence for auto-fix based on review results.
#>
param(
[Parameter(Mandatory)]
[string]$RepoRoot,
[int]$MinFeasibilityScore = 70,
[int]$MinClarityScore = 60,
[int]$MaxEffortDays = 2,
[int[]]$FilterIssueNumbers = @()
)
$genFiles = Get-GeneratedFilesPath -RepoRoot $RepoRoot
$reviewDir = Join-Path $genFiles 'issueReview'
if (-not (Test-Path $reviewDir)) {
return @()
}
$highConfidence = @()
Get-ChildItem -Path $reviewDir -Directory | ForEach-Object {
$issueNum = [int]$_.Name
if ($FilterIssueNumbers.Count -gt 0 -and $issueNum -notin $FilterIssueNumbers) {
return
}
$overviewPath = Join-Path $_.FullName 'overview.md'
$implPlanPath = Join-Path $_.FullName 'implementation-plan.md'
if (-not (Test-Path $overviewPath) -or -not (Test-Path $implPlanPath)) {
return
}
$overview = Get-Content $overviewPath -Raw
$feasibility = 0
$clarity = 0
$effortDays = 999
if ($overview -match 'Technical Feasibility[^\d]*(\d+)/100') {
$feasibility = [int]$Matches[1]
}
if ($overview -match 'Requirement Clarity[^\d]*(\d+)/100') {
$clarity = [int]$Matches[1]
}
if ($overview -match 'Effort Estimate[^|]*\|\s*[\d.]+(?:-(\d+))?\s*days?') {
if ($Matches[1]) {
$effortDays = [int]$Matches[1]
} elseif ($overview -match 'Effort Estimate[^|]*\|\s*(\d+)\s*days?') {
$effortDays = [int]$Matches[1]
}
}
if ($overview -match 'Effort Estimate[^|]*\|[^|]*\|\s*(XS|S)\b') {
if ($Matches[1] -eq 'XS') { $effortDays = 1 } else { $effortDays = 2 }
} elseif ($overview -match 'Effort Estimate[^|]*\|[^|]*\(XS\)') {
$effortDays = 1
} elseif ($overview -match 'Effort Estimate[^|]*\|[^|]*\(S\)') {
$effortDays = 2
}
if ($feasibility -ge $MinFeasibilityScore -and
$clarity -ge $MinClarityScore -and
$effortDays -le $MaxEffortDays) {
$highConfidence += @{
IssueNumber = $issueNum
FeasibilityScore = $feasibility
ClarityScore = $clarity
EffortDays = $effortDays
OverviewPath = $overviewPath
ImplementationPlanPath = $implPlanPath
}
}
}
return $highConfidence | Sort-Object -Property FeasibilityScore -Descending
}
#endregion
#region Release & PR Status Helpers
function Get-PRReleaseStatus {
<#
.SYNOPSIS
Check if a PR has been merged and released.
.DESCRIPTION
Queries GitHub to determine:
1. If the PR is merged
2. What release (if any) contains the merge commit
.OUTPUTS
@{
PRNumber = <int>
IsMerged = $true | $false
MergeCommit = <commit sha or $null>
ReleasedIn = <version string or $null> # e.g., "v0.90.0"
IsReleased = $true | $false
}
#>
param(
[Parameter(Mandatory)]
[int]$PRNumber,
[string]$Repo = 'microsoft/PowerToys'
)
$result = @{
PRNumber = $PRNumber
IsMerged = $false
MergeCommit = $null
ReleasedIn = $null
IsReleased = $false
}
try {
# Get PR details from GitHub
$prJson = gh pr view $PRNumber --repo $Repo --json state,mergeCommit,mergedAt 2>$null
if (-not $prJson) {
return $result
}
$pr = $prJson | ConvertFrom-Json
if ($pr.state -eq 'MERGED' -and $pr.mergeCommit) {
$result.IsMerged = $true
$result.MergeCommit = $pr.mergeCommit.oid
# Check which release tags contain this commit
# Use git tag --contains to find tags that include the merge commit
$tags = git tag --contains $result.MergeCommit 2>$null
if ($tags) {
# Filter to release tags (v0.XX.X pattern) and get the earliest one
$releaseTags = $tags | Where-Object { $_ -match '^v\d+\.\d+\.\d+$' } | Sort-Object
if ($releaseTags) {
$result.ReleasedIn = $releaseTags | Select-Object -First 1
$result.IsReleased = $true
}
}
}
}
catch {
# Silently fail - will return default "not merged" status
}
return $result
}
function Get-LatestRelease {
<#
.SYNOPSIS
Get the latest release version of PowerToys.
#>
param(
[string]$Repo = 'microsoft/PowerToys'
)
try {
$releaseJson = gh release view --repo $Repo --json tagName 2>$null
if ($releaseJson) {
$release = $releaseJson | ConvertFrom-Json
return $release.tagName
}
}
catch {
# Fallback: try to get from git tags
$latestTag = git describe --tags --abbrev=0 2>$null
if ($latestTag) {
return $latestTag
}
}
return $null
}
#endregion
#region Implementation Plan Analysis
function Get-ImplementationPlanStatus {
<#
.SYNOPSIS
Parse implementation-plan.md to determine the recommended action.
.DESCRIPTION
Reads the implementation plan and extracts the status/recommendation.
For "already resolved" issues, also checks if the fix has been released.
Returns an object indicating what action should be taken.
.OUTPUTS
@{
Status = 'AlreadyResolved' | 'FixedButUnreleased' | 'NeedsClarification' | 'Duplicate' | 'WontFix' | 'ReadyToImplement' | 'Unknown'
Action = 'CloseIssue' | 'AddComment' | 'LinkDuplicate' | 'ImplementFix' | 'Skip'
Reason = <string explaining why>
RelatedPR = <PR number if already fixed>
ReleasedIn = <version if released, e.g., "v0.90.0">
DuplicateOf = <issue number if duplicate>
CommentText = <suggested comment if applicable>
}
#>
param(
[Parameter(Mandatory)]
[string]$ImplementationPlanPath,
[switch]$SkipReleaseCheck
)
$result = @{
Status = 'Unknown'
Action = 'Skip'
Reason = 'Could not determine status from implementation plan'
RelatedPR = $null
ReleasedIn = $null
DuplicateOf = $null
CommentText = $null
}
if (-not (Test-Path $ImplementationPlanPath)) {
$result.Reason = 'Implementation plan file not found'
return $result
}
$content = Get-Content $ImplementationPlanPath -Raw
# Check for ALREADY RESOLVED status
if ($content -match '(?i)STATUS:\s*ALREADY\s+RESOLVED' -or
$content -match '(?i)⚠️\s*STATUS:\s*ALREADY\s+RESOLVED' -or
$content -match '(?i)This issue has been fixed by' -or
$content -match '(?i)No implementation work is needed') {
# Try to extract the PR number
$prNumber = $null
if ($content -match '\[PR #(\d+)\]' -or $content -match 'PR #(\d+)' -or $content -match '/pull/(\d+)') {
$prNumber = [int]$Matches[1]
$result.RelatedPR = $prNumber
}
# Check if the fix has been released
if ($prNumber -and -not $SkipReleaseCheck) {
$prStatus = Get-PRReleaseStatus -PRNumber $prNumber
if ($prStatus.IsReleased) {
# Fix is released - safe to close
$result.Status = 'AlreadyResolved'
$result.Action = 'CloseIssue'
$result.ReleasedIn = $prStatus.ReleasedIn
$result.Reason = "Issue fixed by PR #$prNumber, released in $($prStatus.ReleasedIn)"
$result.CommentText = @"
This issue has been fixed by PR #$prNumber and is available in **$($prStatus.ReleasedIn)**.
Please update to the latest version. If you're still experiencing this issue after updating, please reopen with additional details.
"@
}
elseif ($prStatus.IsMerged) {
# PR merged but not yet released - add comment but don't close
$result.Status = 'FixedButUnreleased'
$result.Action = 'AddComment'
$result.Reason = "Issue fixed by PR #$prNumber, but not yet released"
$result.CommentText = @"
This issue has been fixed by PR #$prNumber, which has been merged but **not yet released**.
The fix will be available in the next PowerToys release. You can:
- Wait for the next official release
- Build from source to get the fix immediately
We'll close this issue once the fix is released.
"@
}
else {
# PR exists but not merged - treat as ready to implement (PR might have been reverted)
$result.Status = 'ReadyToImplement'
$result.Action = 'ImplementFix'
$result.Reason = "PR #$prNumber exists but is not merged - may need reimplementation"
}
}
elseif ($prNumber) {
# Skip release check requested or no PR number - assume it's resolved
$result.Status = 'AlreadyResolved'
$result.Action = 'CloseIssue'
$result.Reason = 'Issue has already been fixed'
$result.CommentText = "This issue has been fixed by PR #$prNumber. Closing as resolved."
}
else {
# No PR number found - just mark as resolved with generic message
$result.Status = 'AlreadyResolved'
$result.Action = 'CloseIssue'
$result.Reason = 'Issue appears to have been resolved'
$result.CommentText = "Based on analysis, this issue appears to have already been resolved. Please verify and reopen if the issue persists."
}
return $result
}
# Check for DUPLICATE status
if ($content -match '(?i)STATUS:\s*DUPLICATE' -or
$content -match '(?i)This is a duplicate of' -or
$content -match '(?i)duplicate of #(\d+)') {
$result.Status = 'Duplicate'
$result.Action = 'LinkDuplicate'
$result.Reason = 'Issue is a duplicate'
# Try to extract the duplicate issue number
if ($content -match 'duplicate of #(\d+)' -or $content -match '#(\d+)') {
$result.DuplicateOf = [int]$Matches[1]
$result.CommentText = "This appears to be a duplicate of #$($result.DuplicateOf)."
}
return $result
}
# Check for NEEDS CLARIFICATION status
if ($content -match '(?i)STATUS:\s*NEEDS?\s+CLARIFICATION' -or
$content -match '(?i)STATUS:\s*NEEDS?\s+MORE\s+INFO' -or
$content -match '(?i)cannot proceed without' -or
$content -match '(?i)need(?:s)? more information') {
$result.Status = 'NeedsClarification'
$result.Action = 'AddComment'
$result.Reason = 'Issue needs more information from reporter'
# Try to extract what information is needed
if ($content -match '(?i)(?:need(?:s)?|require(?:s)?|missing)[:\s]+([^\n]+)') {
$result.CommentText = "Additional information is needed to proceed with this issue: $($Matches[1].Trim())"
} else {
$result.CommentText = "Could you please provide more details about this issue? Specifically, steps to reproduce and expected vs actual behavior would help."
}
return $result
}
# Check for WONT FIX / NOT FEASIBLE status
if ($content -match '(?i)STATUS:\s*(?:WONT?\s+FIX|NOT\s+FEASIBLE|REJECTED)' -or
$content -match '(?i)(?:not|cannot be) (?:feasible|implemented)' -or
$content -match '(?i)recommend(?:ed)?\s+(?:to\s+)?close') {
$result.Status = 'WontFix'
$result.Action = 'AddComment'
$result.Reason = 'Issue is not feasible or recommended to close'
# Try to extract the reason
if ($content -match '(?i)(?:because|reason|due to)[:\s]+([^\n]+)') {
$result.CommentText = "After analysis, this issue cannot be implemented: $($Matches[1].Trim())"
}
return $result
}
# Check for external dependency / blocked status
if ($content -match '(?i)STATUS:\s*BLOCKED' -or
$content -match '(?i)blocked by' -or
$content -match '(?i)depends on external' -or
$content -match '(?i)waiting for upstream') {
$result.Status = 'Blocked'
$result.Action = 'AddComment'
$result.Reason = 'Issue is blocked by external dependency'
return $result
}
# Check for READY TO IMPLEMENT (positive signals)
if ($content -match '(?i)## \d+\)\s*Task Breakdown' -or
$content -match '(?i)implementation steps' -or
$content -match '(?i)## Layers & Files' -or
($content -match '(?i)Feasibility' -and $content -notmatch '(?i)not\s+feasible')) {
$result.Status = 'ReadyToImplement'
$result.Action = 'ImplementFix'
$result.Reason = 'Implementation plan is ready'
return $result
}
# Default: if we have a detailed plan, assume it's ready
if ($content.Length -gt 500 -and $content -match '(?i)##') {
$result.Status = 'ReadyToImplement'
$result.Action = 'ImplementFix'
$result.Reason = 'Implementation plan appears complete'
}
return $result
}
function Invoke-ImplementationPlanAction {
<#
.SYNOPSIS
Execute the recommended action from the implementation plan analysis.
.DESCRIPTION
Based on the status from Get-ImplementationPlanStatus, takes appropriate action:
- CloseIssue: Closes the issue with a comment
- AddComment: Adds a comment to the issue
- LinkDuplicate: Marks as duplicate
- ImplementFix: Returns $true to indicate code fix should proceed
- Skip: Returns $false
.OUTPUTS
@{
ActionTaken = <string describing what was done>
ShouldProceedWithFix = $true | $false
Success = $true | $false
}
#>
param(
[Parameter(Mandatory)]
[int]$IssueNumber,
[Parameter(Mandatory)]
[hashtable]$PlanStatus,
[switch]$DryRun
)
$result = @{
ActionTaken = 'None'
ShouldProceedWithFix = $false
Success = $true
}
switch ($PlanStatus.Action) {
'ImplementFix' {
$result.ActionTaken = 'Proceeding with code fix'
$result.ShouldProceedWithFix = $true
Info "[Issue #$IssueNumber] Status: $($PlanStatus.Status) - $($PlanStatus.Reason)"
}
'CloseIssue' {
$result.ActionTaken = "Closing issue: $($PlanStatus.Reason)"
Info "[Issue #$IssueNumber] $($PlanStatus.Status): $($PlanStatus.Reason)"
if (-not $DryRun) {
$comment = $PlanStatus.CommentText
if (-not $comment) {
$comment = "Closing based on automated analysis: $($PlanStatus.Reason)"
}
try {
# Add comment explaining closure
gh issue comment $IssueNumber --body $comment 2>&1 | Out-Null
# Close the issue
if ($PlanStatus.RelatedPR) {
gh issue close $IssueNumber --reason "completed" --comment "Resolved by PR #$($PlanStatus.RelatedPR)" 2>&1 | Out-Null
} else {
gh issue close $IssueNumber --reason "completed" 2>&1 | Out-Null
}
Success "[Issue #$IssueNumber] ✓ Closed with comment"
}
catch {
Err "[Issue #$IssueNumber] Failed to close: $($_.Exception.Message)"
$result.Success = $false
}
} else {
Info "[Issue #$IssueNumber] (DryRun) Would close with: $($PlanStatus.CommentText)"
}
}
'AddComment' {
$result.ActionTaken = "Adding comment: $($PlanStatus.Reason)"
Info "[Issue #$IssueNumber] $($PlanStatus.Status): $($PlanStatus.Reason)"
if (-not $DryRun -and $PlanStatus.CommentText) {
try {
gh issue comment $IssueNumber --body $PlanStatus.CommentText 2>&1 | Out-Null
Success "[Issue #$IssueNumber] ✓ Comment added"
}
catch {
Err "[Issue #$IssueNumber] Failed to add comment: $($_.Exception.Message)"
$result.Success = $false
}
} else {
Info "[Issue #$IssueNumber] (DryRun) Would comment: $($PlanStatus.CommentText)"
}
}
'LinkDuplicate' {
$result.ActionTaken = "Marking as duplicate of #$($PlanStatus.DuplicateOf)"
Info "[Issue #$IssueNumber] Duplicate of #$($PlanStatus.DuplicateOf)"
if (-not $DryRun -and $PlanStatus.DuplicateOf) {
try {
gh issue close $IssueNumber --reason "not_planned" --comment "Closing as duplicate of #$($PlanStatus.DuplicateOf)" 2>&1 | Out-Null
Success "[Issue #$IssueNumber] ✓ Closed as duplicate"
}
catch {
Err "[Issue #$IssueNumber] Failed to close as duplicate: $($_.Exception.Message)"
$result.Success = $false
}
}
}
'Skip' {
$result.ActionTaken = "Skipped: $($PlanStatus.Reason)"
Warn "[Issue #$IssueNumber] Skipping: $($PlanStatus.Reason)"
}
}
return $result
}
#endregion
#region Worktree Integration
function Copy-IssueReviewToWorktree {
<#
.SYNOPSIS
Copy the Generated Files for an issue to a worktree.
#>
param(
[Parameter(Mandatory)]
[int]$IssueNumber,
[Parameter(Mandatory)]
[string]$SourceRepoRoot,
[Parameter(Mandatory)]
[string]$WorktreePath
)
$sourceReviewPath = Get-IssueReviewPath -RepoRoot $SourceRepoRoot -IssueNumber $IssueNumber
$destReviewPath = Get-IssueReviewPath -RepoRoot $WorktreePath -IssueNumber $IssueNumber
if (-not (Test-Path $sourceReviewPath)) {
throw "Issue review files not found at: $sourceReviewPath"
}
Ensure-DirectoryExists -Path $destReviewPath
Copy-Item -Path "$sourceReviewPath\*" -Destination $destReviewPath -Recurse -Force
Info "Copied issue review files to: $destReviewPath"
return $destReviewPath
}
#endregion

View File

@@ -1,530 +0,0 @@
<#!
.SYNOPSIS
Auto-fix high-confidence issues using worktrees and AI CLI.
.DESCRIPTION
Finds issues with high confidence scores from the review results, creates worktrees
for each, copies the Generated Files, and kicks off the FixIssue agent to implement fixes.
.PARAMETER IssueNumber
Specific issue number to fix. If not specified, finds high-confidence issues automatically.
.PARAMETER MinFeasibilityScore
Minimum Technical Feasibility score (0-100). Default: 70.
.PARAMETER MinClarityScore
Minimum Requirement Clarity score (0-100). Default: 60.
.PARAMETER MaxEffortDays
Maximum effort estimate in days. Default: 2 (Small fixes).
.PARAMETER MaxParallel
Maximum parallel fix jobs. Default: 5 (worktrees are resource-intensive).
.PARAMETER CLIType
AI CLI to use: claude, gh-copilot, or vscode. Auto-detected if not specified.
.PARAMETER DryRun
List issues without starting fixes.
.PARAMETER SkipWorktree
Fix in the current repository instead of creating worktrees (useful for single issue).
.PARAMETER VSCodeProfile
VS Code profile to use when opening worktrees. Default: Default.
.PARAMETER AutoCommit
Automatically commit changes after successful fix.
.PARAMETER CreatePR
Automatically create a pull request after successful fix.
.EXAMPLE
# Fix a specific issue
./Start-IssueAutoFix.ps1 -IssueNumber 12345
.EXAMPLE
# Find and fix all high-confidence issues (dry run)
./Start-IssueAutoFix.ps1 -DryRun
.EXAMPLE
# Fix issues with very high confidence
./Start-IssueAutoFix.ps1 -MinFeasibilityScore 80 -MinClarityScore 70 -MaxEffortDays 1
.EXAMPLE
# Fix single issue in current repo (no worktree)
./Start-IssueAutoFix.ps1 -IssueNumber 12345 -SkipWorktree
.NOTES
Prerequisites:
- Run Start-BulkIssueReview.ps1 first to generate review files
- GitHub CLI (gh) authenticated
- Claude Code CLI or VS Code with Copilot
Results:
- Worktrees created at ../<RepoName>-<hash>/
- Generated Files copied to each worktree
- Fix agent invoked in each worktree
#>
[CmdletBinding()]
param(
[int]$IssueNumber,
[int]$MinFeasibilityScore = 70,
[int]$MinClarityScore = 60,
[int]$MaxEffortDays = 2,
[int]$MaxParallel = 5,
[ValidateSet('claude', 'copilot', 'gh-copilot', 'vscode', 'auto')]
[string]$CLIType = 'auto',
[switch]$DryRun,
[switch]$SkipWorktree,
[Alias('Profile')]
[string]$VSCodeProfile = 'Default',
[switch]$AutoCommit,
[switch]$CreatePR,
[switch]$Force,
[switch]$Help
)
# Load libraries
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
. "$scriptDir/IssueReviewLib.ps1"
# Load worktree library from tools/build
$repoRoot = Get-RepoRoot
$worktreeLib = Join-Path $repoRoot 'tools/build/WorktreeLib.ps1'
if (Test-Path $worktreeLib) {
. $worktreeLib
}
# Show help
if ($Help) {
Get-Help $MyInvocation.MyCommand.Path -Full
return
}
function Start-IssueFixInWorktree {
<#
.SYNOPSIS
Analyze implementation plan and either take action or create worktree for fix.
.DESCRIPTION
First analyzes the implementation plan to determine if:
- Issue is already resolved (close it)
- Issue needs clarification (add comment)
- Issue is a duplicate (close as duplicate)
- Issue is ready to implement (create worktree and fix)
#>
param(
[Parameter(Mandatory)]
[int]$IssueNumber,
[Parameter(Mandatory)]
[string]$SourceRepoRoot,
[string]$CLIType = 'claude',
[string]$VSCodeProfile = 'Default',
[switch]$SkipWorktree,
[switch]$DryRun
)
$issueReviewPath = Get-IssueReviewPath -RepoRoot $SourceRepoRoot -IssueNumber $IssueNumber
$overviewPath = Join-Path $issueReviewPath 'overview.md'
$implPlanPath = Join-Path $issueReviewPath 'implementation-plan.md'
# Verify review files exist
if (-not (Test-Path $overviewPath)) {
throw "No overview.md found for issue #$IssueNumber. Run Start-BulkIssueReview.ps1 first."
}
if (-not (Test-Path $implPlanPath)) {
throw "No implementation-plan.md found for issue #$IssueNumber. Run Start-BulkIssueReview.ps1 first."
}
# =====================================
# STEP 1: Analyze the implementation plan
# =====================================
Info "Analyzing implementation plan for issue #$IssueNumber..."
$planStatus = Get-ImplementationPlanStatus -ImplementationPlanPath $implPlanPath
# =====================================
# STEP 2: Execute the recommended action
# =====================================
$actionResult = Invoke-ImplementationPlanAction -IssueNumber $IssueNumber -PlanStatus $planStatus -DryRun:$DryRun
# If we shouldn't proceed with fix, return early
if (-not $actionResult.ShouldProceedWithFix) {
return @{
IssueNumber = $IssueNumber
WorktreePath = $null
Success = $actionResult.Success
ActionTaken = $actionResult.ActionTaken
SkippedCodeFix = $true
}
}
# =====================================
# STEP 3: Proceed with code fix
# =====================================
$workingDir = $SourceRepoRoot
if (-not $SkipWorktree) {
# Use the simplified New-WorktreeFromIssue.cmd which only needs issue number
$worktreeCmd = Join-Path $SourceRepoRoot 'tools/build/New-WorktreeFromIssue.cmd'
Info "Creating worktree for issue #$IssueNumber..."
# Call the cmd script with issue number and -NoVSCode for automation
& cmd /c $worktreeCmd $IssueNumber -NoVSCode
if ($LASTEXITCODE -ne 0) {
throw "Failed to create worktree for issue #$IssueNumber"
}
# Find the created worktree
$entries = Get-WorktreeEntries
$worktreeEntry = $entries | Where-Object { $_.Branch -like "issue/$IssueNumber*" } | Select-Object -First 1
if (-not $worktreeEntry) {
throw "Failed to find worktree for issue #$IssueNumber"
}
$workingDir = $worktreeEntry.Path
Info "Worktree created at: $workingDir"
# Copy Generated Files to worktree
Info "Copying review files to worktree..."
$destReviewPath = Copy-IssueReviewToWorktree -IssueNumber $IssueNumber -SourceRepoRoot $SourceRepoRoot -WorktreePath $workingDir
Info "Review files copied to: $destReviewPath"
# Copy .github/skills folder to worktree (needed for MCP config)
$sourceSkillsPath = Join-Path $SourceRepoRoot '.github/skills'
$destSkillsPath = Join-Path $workingDir '.github/skills'
if (Test-Path $sourceSkillsPath) {
$destGithubPath = Join-Path $workingDir '.github'
if (-not (Test-Path $destGithubPath)) {
New-Item -ItemType Directory -Path $destGithubPath -Force | Out-Null
}
Copy-Item -Path $sourceSkillsPath -Destination $destGithubPath -Recurse -Force
Info "Copied .github/skills to worktree"
}
}
# Build the prompt for the fix agent
$prompt = @"
You are the FixIssue agent. Fix GitHub issue #$IssueNumber.
The implementation plan is at: Generated Files/issueReview/$IssueNumber/implementation-plan.md
The overview is at: Generated Files/issueReview/$IssueNumber/overview.md
Follow the implementation plan exactly. Build and verify after each change.
"@
# Start the fix agent
Info "Starting fix agent for issue #$IssueNumber in $workingDir..."
# MCP config for github-artifacts tools (relative to repo root)
$mcpConfig = '@.github/skills/issue-fix/references/mcp-config.json'
switch ($CLIType) {
'copilot' {
# GitHub Copilot CLI (standalone copilot command)
# -p: Non-interactive prompt mode (exits after completion)
# --yolo: Enable all permissions for automated execution
# -s: Silent mode - output only agent response
# --additional-mcp-config: Load github-artifacts MCP for image/attachment analysis
$copilotArgs = @(
'--additional-mcp-config', $mcpConfig,
'-p', $prompt,
'--yolo',
'-s'
)
Info "Running: copilot $($copilotArgs -join ' ')"
Push-Location $workingDir
try {
& copilot @copilotArgs
if ($LASTEXITCODE -ne 0) {
Warn "Copilot exited with code $LASTEXITCODE"
}
} finally {
Pop-Location
}
}
'claude' {
$claudeArgs = @(
'--print',
'--dangerously-skip-permissions',
'--prompt', $prompt
)
Start-Process -FilePath 'claude' -ArgumentList $claudeArgs -WorkingDirectory $workingDir -Wait -NoNewWindow
}
'gh-copilot' {
# Use GitHub Copilot CLI via gh extension
# gh copilot suggest requires interactive mode, so we open VS Code with the prompt
Info "GitHub Copilot CLI detected. Opening VS Code with prompt..."
# Create a prompt file in the worktree for easy access
$promptFile = Join-Path $workingDir "Generated Files/issueReview/$IssueNumber/fix-prompt.md"
$promptContent = @"
# Fix Issue #$IssueNumber
## Instructions
$prompt
## Quick Start
1. Read the implementation plan: ``Generated Files/issueReview/$IssueNumber/implementation-plan.md``
2. Read the overview: ``Generated Files/issueReview/$IssueNumber/overview.md``
3. Follow the plan step by step
4. Build and test after each change
"@
Set-Content -Path $promptFile -Value $promptContent -Force
# Open VS Code with the worktree
code --new-window $workingDir --profile $VSCodeProfile
Info "VS Code opened at $workingDir"
Info "Prompt file created at: $promptFile"
Info "Use GitHub Copilot in VS Code to implement the fix."
}
'vscode' {
# Open VS Code and let user manually trigger the fix
code --new-window $workingDir --profile $VSCodeProfile
Info "VS Code opened at $workingDir. Use Copilot to implement the fix."
}
default {
Warn "CLI type '$CLIType' not fully supported for auto-fix. Opening VS Code..."
code --new-window $workingDir --profile $VSCodeProfile
}
}
# Check if any changes were actually made
$hasChanges = $false
Push-Location $workingDir
try {
$uncommitted = git status --porcelain 2>$null
$commitsAhead = git rev-list main..HEAD --count 2>$null
if ($uncommitted -or ($commitsAhead -gt 0)) {
$hasChanges = $true
}
} finally {
Pop-Location
}
return @{
IssueNumber = $IssueNumber
WorktreePath = $workingDir
Success = $true
ActionTaken = 'CodeFixAttempted'
SkippedCodeFix = $false
HasChanges = $hasChanges
}
}
#region Main Script
try {
Info "Repository root: $repoRoot"
# Detect or validate CLI
if ($CLIType -eq 'auto') {
$cli = Get-AvailableCLI
if ($cli) {
$CLIType = $cli.Type
Info "Auto-detected CLI: $($cli.Name)"
} else {
$CLIType = 'vscode'
Info "No CLI detected, will use VS Code"
}
}
# Find issues to fix
$issuesToFix = @()
if ($IssueNumber) {
# Single issue specified
$reviewResult = Get-IssueReviewResult -IssueNumber $IssueNumber -RepoRoot $repoRoot
if (-not $reviewResult.HasOverview -or -not $reviewResult.HasImplementationPlan) {
throw "Issue #$IssueNumber does not have review files. Run Start-BulkIssueReview.ps1 first."
}
$issuesToFix += @{
IssueNumber = $IssueNumber
OverviewPath = $reviewResult.OverviewPath
ImplementationPlanPath = $reviewResult.ImplementationPlanPath
}
} else {
# Find high-confidence issues
Info "`nSearching for high-confidence issues..."
Info " Min Feasibility Score: $MinFeasibilityScore"
Info " Min Clarity Score: $MinClarityScore"
Info " Max Effort: $MaxEffortDays days"
$highConfidence = Get-HighConfidenceIssues `
-RepoRoot $repoRoot `
-MinFeasibilityScore $MinFeasibilityScore `
-MinClarityScore $MinClarityScore `
-MaxEffortDays $MaxEffortDays
if ($highConfidence.Count -eq 0) {
Warn "No high-confidence issues found matching criteria."
Info "Try lowering the score thresholds or increasing MaxEffortDays."
return
}
$issuesToFix = $highConfidence
}
Info "`nIssues ready for auto-fix: $($issuesToFix.Count)"
Info ("-" * 80)
foreach ($issue in $issuesToFix) {
$scores = ""
if ($issue.FeasibilityScore) {
$scores = " [Feasibility: $($issue.FeasibilityScore), Clarity: $($issue.ClarityScore), Effort: $($issue.EffortDays)d]"
}
Info ("#{0,-6}{1}" -f $issue.IssueNumber, $scores)
}
Info ("-" * 80)
# In DryRun mode, still analyze plans but don't take action
if ($DryRun) {
Info "`nAnalyzing implementation plans (dry run)..."
foreach ($issue in $issuesToFix) {
$implPlanPath = Join-Path (Get-IssueReviewPath -RepoRoot $repoRoot -IssueNumber $issue.IssueNumber) 'implementation-plan.md'
if (Test-Path $implPlanPath) {
$planStatus = Get-ImplementationPlanStatus -ImplementationPlanPath $implPlanPath
$color = switch ($planStatus.Action) {
'ImplementFix' { 'Green' }
'CloseIssue' { 'Yellow' }
'AddComment' { 'Cyan' }
'LinkDuplicate' { 'Magenta' }
default { 'Gray' }
}
Write-Host (" #{0,-6} [{1,-20}] -> {2}" -f $issue.IssueNumber, $planStatus.Status, $planStatus.Action) -ForegroundColor $color
if ($planStatus.RelatedPR) {
$prInfo = "PR #$($planStatus.RelatedPR)"
if ($planStatus.ReleasedIn) {
$prInfo += " (released in $($planStatus.ReleasedIn))"
} elseif ($planStatus.Status -eq 'FixedButUnreleased') {
$prInfo += " (merged, awaiting release)"
}
Write-Host " $prInfo" -ForegroundColor DarkGray
}
if ($planStatus.DuplicateOf) {
Write-Host " Duplicate of #$($planStatus.DuplicateOf)" -ForegroundColor DarkGray
}
}
}
Warn "`nDry run mode - no actions taken."
return
}
# Confirm before proceeding (skip if -Force)
if (-not $Force) {
$confirm = Read-Host "`nProceed with fixing $($issuesToFix.Count) issues? (y/N)"
if ($confirm -notmatch '^[yY]') {
Info "Cancelled."
return
}
}
# Process issues
$results = @{
Succeeded = @()
Failed = @()
AlreadyResolved = @()
AwaitingRelease = @()
NeedsClarification = @()
Duplicates = @()
NoChanges = @()
}
foreach ($issue in $issuesToFix) {
try {
Info "`n" + ("=" * 60)
Info "PROCESSING ISSUE #$($issue.IssueNumber)"
Info ("=" * 60)
$result = Start-IssueFixInWorktree `
-IssueNumber $issue.IssueNumber `
-SourceRepoRoot $repoRoot `
-CLIType $CLIType `
-VSCodeProfile $VSCodeProfile `
-SkipWorktree:$SkipWorktree `
-DryRun:$DryRun
if ($result.SkippedCodeFix) {
# Action was taken but no code fix (e.g., closed issue, added comment)
switch -Wildcard ($result.ActionTaken) {
'*Closing*' { $results.AlreadyResolved += $issue.IssueNumber }
'*clarification*' { $results.NeedsClarification += $issue.IssueNumber }
'*duplicate*' { $results.Duplicates += $issue.IssueNumber }
'*merged*awaiting*' { $results.AwaitingRelease += $issue.IssueNumber }
'*merged but not yet released*' { $results.AwaitingRelease += $issue.IssueNumber }
default { $results.Succeeded += $issue.IssueNumber }
}
Success "✓ Issue #$($issue.IssueNumber) handled: $($result.ActionTaken)"
}
elseif ($result.HasChanges) {
$results.Succeeded += $issue.IssueNumber
Success "✓ Issue #$($issue.IssueNumber) fix completed with changes"
}
else {
$results.NoChanges += $issue.IssueNumber
Warn "⚠ Issue #$($issue.IssueNumber) fix ran but no code changes were made"
}
}
catch {
Err "✗ Issue #$($issue.IssueNumber) failed: $($_.Exception.Message)"
$results.Failed += $issue.IssueNumber
}
}
# Summary
Info "`n" + ("=" * 80)
Info "AUTO-FIX COMPLETE"
Info ("=" * 80)
Info "Total issues: $($issuesToFix.Count)"
if ($results.Succeeded.Count -gt 0) {
Success "Code fixes: $($results.Succeeded.Count)"
}
if ($results.AlreadyResolved.Count -gt 0) {
Success "Already resolved: $($results.AlreadyResolved.Count) (issues closed)"
}
if ($results.AwaitingRelease.Count -gt 0) {
Info "Awaiting release: $($results.AwaitingRelease.Count) (fix merged, pending release)"
}
if ($results.NeedsClarification.Count -gt 0) {
Warn "Need clarification: $($results.NeedsClarification.Count) (comments added)"
}
if ($results.Duplicates.Count -gt 0) {
Warn "Duplicates: $($results.Duplicates.Count) (issues closed)"
}
if ($results.NoChanges.Count -gt 0) {
Warn "No changes made: $($results.NoChanges.Count)"
}
if ($results.Failed.Count -gt 0) {
Err "Failed: $($results.Failed.Count)"
Err "Failed issues: $($results.Failed -join ', ')"
}
Info ("=" * 80)
if (-not $SkipWorktree -and ($results.Succeeded.Count -gt 0 -or $results.NoChanges.Count -gt 0)) {
Info "`nWorktrees created. Use 'git worktree list' to see all worktrees."
Info "To clean up: Delete-Worktree.ps1 -Branch issue/<number>"
}
return $results
}
catch {
Err "Error: $($_.Exception.Message)"
exit 1
}
#endregion

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,114 +0,0 @@
---
name: issue-review
description: Analyze GitHub issues for feasibility and implementation planning. Use when asked to review an issue, analyze if an issue is fixable, evaluate issue complexity, create implementation plan for an issue, triage issues, assess technical feasibility, or estimate effort for an issue. Outputs structured analysis including feasibility score, clarity score, effort estimate, and detailed implementation plan.
license: Complete terms in LICENSE.txt
---
# Issue Review Skill
Analyze GitHub issues to determine technical feasibility, requirement clarity, and create detailed implementation plans for PowerToys.
## Skill Contents
This skill is **self-contained** with all required resources:
```
.github/skills/issue-review/
├── SKILL.md # This file
├── LICENSE.txt # MIT License
├── scripts/
│ ├── IssueReviewLib.ps1 # Shared library functions
│ └── Start-BulkIssueReview.ps1 # Main review script
└── references/
└── review-issue.prompt.md # Full AI prompt template
```
## Output Directory
All generated artifacts are placed under `Generated Files/issueReview/<issue-number>/` at the repository root (gitignored).
```
Generated Files/issueReview/
└── <issue-number>/
├── overview.md # High-level assessment with scores
├── implementation-plan.md # Detailed step-by-step fix plan
└── _raw-issue.json # Cached issue data from GitHub
```
## When to Use This Skill
- Review a specific GitHub issue for feasibility
- Analyze whether an issue can be fixed by AI
- Create an implementation plan for an issue
- Triage issues by complexity and clarity
- Estimate effort for fixing an issue
- Evaluate technical requirements of an issue
## Prerequisites
- GitHub CLI (`gh`) installed and authenticated
- PowerShell 7+ for running scripts
## Required Variables
⚠️ **Before starting**, confirm `{{IssueNumber}}` with the user. If not provided, **ASK**: "What issue number should I review?"
| Variable | Description | Example |
|----------|-------------|---------|
| `{{IssueNumber}}` | GitHub issue number to analyze | `44044` |
## Workflow
### Step 1: Run Issue Review
Execute the review script (use paths relative to this skill folder):
```powershell
# From repo root
.github/skills/issue-review/scripts/Start-BulkIssueReview.ps1 -IssueNumber {{IssueNumber}}
```
This will:
1. Fetch issue details from GitHub
2. Analyze the codebase for relevant files
3. Generate `overview.md` with feasibility assessment
4. Generate `implementation-plan.md` with detailed steps
### Step 2: Review Output
Check the generated files at `Generated Files/issueReview/{{IssueNumber}}/`:
| File | Contains |
|------|----------|
| `overview.md` | Feasibility score (0-100), Clarity score (0-100), Effort estimate, Risk assessment |
| `implementation-plan.md` | Step-by-step implementation with file paths, code snippets, test requirements |
### Step 3: Interpret Scores
| Score Range | Interpretation |
|-------------|----------------|
| 80-100 | High confidence - straightforward fix |
| 60-79 | Medium confidence - some complexity |
| 40-59 | Low confidence - significant challenges |
| 0-39 | Very low - may need human intervention |
## Batch Review
To review multiple issues at once:
```powershell
.github/skills/issue-review/scripts/Start-BulkIssueReview.ps1 -IssueNumbers 44044, 32950, 45029
```
## AI Prompt Reference
For manual AI invocation, the full prompt is at:
- `references/review-issue.prompt.md` (relative to this skill folder)
## Troubleshooting
| Problem | Solution |
|---------|----------|
| Issue not found | Verify issue number exists: `gh issue view {{IssueNumber}}` |
| No implementation plan | Issue may be unclear - check `overview.md` for clarity score |
| Script errors | Ensure you're in the PowerToys repo root |

View File

@@ -1,9 +0,0 @@
{
"mcpServers": {
"github-artifacts": {
"command": "cmd",
"args": ["/c", "for /f %i in ('git rev-parse --show-toplevel') do node %i/tools/mcp/github-artifacts/launch.js"],
"tools": ["*"]
}
}
}

View File

@@ -1,165 +0,0 @@
---
agent: 'agent'
description: 'Review a GitHub issue, score it (0-100), and generate an implementation plan'
---
# Review GitHub Issue
## Goal
For **#{{issue_number}}** produce:
1) `Generated Files/issueReview/{{issue_number}}/overview.md`
2) `Generated Files/issueReview/{{issue_number}}/implementation-plan.md`
## Inputs
Figure out required inputs {{issue_number}} from the invocation context; if anything is missing, ask for the value or note it as a gap.
# CONTEXT (brief)
Ground evidence using `gh issue view {{issue_number}} --json number,title,body,author,createdAt,updatedAt,state,labels,milestone,reactions,comments,linkedPullRequests`, download images via MCP `github_issue_images` to better understand the issue context. Finally, use MCP `github_issue_attachments` to download logs with parameter `extractFolder` as `Generated Files/issueReview/{{issue_number}}/logs`, and analyze the downloaded logs if available to identify relevant issues. Locate the source code in the current workspace (use `rg`/`git grep` as needed). Link related issues and PRs.
## When to call MCP tools
If the following MCP "github-artifacts" tools are available in the environment, use them:
- `github_issue_images`: use when the issue/PR likely contains screenshots or other visual evidence (UI bugs, glitches, design problems).
- `github_issue_attachments`: use when the issue/PR mentions attached ZIPs (PowerToysReport_*.zip, logs.zip, debug.zip) or asks to analyze logs/diagnostics. Always provide `extractFolder` as `Generated Files/issueReview/{{issue_number}}/logs`
If these tools are not available (not listed by the runtime), start the MCP server "github-artifacts" first.
# OVERVIEW.MD
## Summary
Issue, state, milestone, labels. **Signals**: 👍/❤️/👎, comment count, last activity, linked PRs.
## At-a-Glance Score Table
Present all ratings in a compact table for quick scanning:
| Dimension | Score | Assessment | Key Drivers |
|-----------|-------|------------|-------------|
| **A) Business Importance** | X/100 | Low/Medium/High | Top 2 factors with scores |
| **B) Community Excitement** | X/100 | Low/Medium/High | Top 2 factors with scores |
| **C) Technical Feasibility** | X/100 | Low/Medium/High | Top 2 factors with scores |
| **D) Requirement Clarity** | X/100 | Low/Medium/High | Top 2 factors with scores |
| **Overall Priority** | X/100 | Low/Medium/High/Critical | Average or weighted summary |
| **Effort Estimate** | X days (T-shirt) | XS/S/M/L/XL/XXL/Epic | Type: bug/feature/chore |
| **Similar Issues Found** | X open, Y closed | — | Quick reference to related work |
| **Potential Assignees** | @username, @username | — | Top contributors to module |
**Assessment bands**: 0-25 Low, 26-50 Medium, 51-75 High, 76-100 Critical
## Ratings (0100) — add evidence & short rationale
### A) Business Importance
- Labels (priority/security/regression): **≤35**
- Milestone/roadmap: **≤25**
- Customer/contract impact: **≤20**
- Unblocks/platform leverage: **≤20**
### B) Community Excitement
- 👍+❤️ normalized: **≤45**
- Comment volume & unique participants: **≤25**
- Recent activity (≤30d): **≤15**
- Duplicates/related issues: **≤15**
### C) Technical Feasibility
- Contained surface/clear seams: **≤30**
- Existing patterns/utilities: **≤25**
- Risk (perf/sec/compat) manageable: **≤25**
- Testability & CI support: **≤20**
### D) Requirement Clarity
- Behavior/repro/constraints: **≤60**
- Non-functionals (perf/sec/i18n/a11y): **≤25**
- Decision owners/acceptance signals: **≤15**
## Effort
Days + **T-shirt** (XS 0.51d, S 12, M 24, L 47, XL 714, XXL 1430, Epic >30).
Type/level: bug/feature/chore/docs/refactor/test-only; severity/value tier.
## Suggested Actions
Provide actionable recommendations for issue triage and assignment:
### A) Requirement Clarification (if Clarity score <50)
**When Requirement Clarity (Dimension D) is Medium or Low:**
- Identify specific gaps in issue description: missing repro steps, unclear expected behavior, undefined acceptance criteria, missing non-functional requirements
- Draft 3-5 clarifying questions to post as issue comment
- Suggest additional information needed: screenshots, logs, environment details, OS version, PowerToys version, error messages
- If behavior is ambiguous, propose 2-3 interpretation scenarios and ask reporter to confirm
- Example questions:
- "Can you provide exact steps to reproduce this issue?"
- "What is the expected behavior vs. what you're actually seeing?"
- "Does this happen on Windows 10, 11, or both?"
- "Can you attach a screenshot or screen recording?"
### B) Correct Label Suggestions
- Analyze issue type, module, and severity to suggest missing or incorrect labels
- Recommend labels from: `Issue-Bug`, `Issue-Feature`, `Issue-Docs`, `Issue-Task`, `Priority-High`, `Priority-Medium`, `Priority-Low`, `Needs-Triage`, `Needs-Author-Feedback`, `Product-<ModuleName>`, etc.
- If Requirement Clarity is low (<50), add `Needs-Author-Feedback` label
- If current labels are incorrect or incomplete, provide specific label changes with rationale
### C) Find Similar Issues & Past Fixes
- Search for similar issues using `gh issue list --search "keywords" --state all --json number,title,state,closedAt`
- Identify patterns: duplicate issues, related bugs, or similar feature requests
- For closed issues, find linked PRs that fixed them: check `linkedPullRequests` in issue data
- Provide 3-5 examples of similar issues with format: `#<number> - <title> (closed by PR #<pr>)` or `(still open)`
### D) Identify Subject Matter Experts
- Use git blame/log to find who fixed similar issues in the past
- Search for PR authors who touched relevant files: `git log --all --format='%aN' -- <file_paths> | sort | uniq -c | sort -rn | head -5`
- Check issue/PR history for frequent contributors to the affected module
- Suggest 2-3 potential assignees with context: `@<username> - <reason>` (e.g., "fixed similar rendering bug in #12345", "maintains FancyZones module")
### E) Semantic Search for Related Work
- Use semantic_search tool to find similar issues, code patterns, or past discussions
- Search queries should include: issue keywords, module names, error messages, feature descriptions
- Cross-reference semantic results with GitHub issue search for comprehensive coverage
**Output format for Suggested Actions section in overview.md:**
```markdown
## Suggested Actions
### Clarifying Questions (if Clarity <50)
Post these questions as issue comment to gather missing information:
1. <question>
2. <question>
3. <question>
**Recommended label**: `Needs-Author-Feedback`
### Label Recommendations
- Add: `<label>` - <reason>
- Remove: `<label>` - <reason>
- Current labels are appropriate ✓
### Similar Issues Found
1. #<number> - <title> (<state>, closed by PR #<pr> on <date>)
2. #<number> - <title> (<state>)
...
### Potential Assignees
- @<username> - <reason>
- @<username> - <reason>
### Related Code/Discussions
- <semantic search findings>
```
# IMPLEMENTATION-PLAN.MD
1) **Problem Framing** — restate problem; current vs expected; scope boundaries.
2) **Layers & Files** — layers (UI/domain/data/infra/build). For each, list **files/dirs to modify** and **new files** (exact paths + why). Prefer repo patterns; cite examples/PRs.
3) **Pattern Choices** — reuse existing; if new, justify trade-offs & transition.
4) **Fundamentals** (brief plan or N/A + reason):
- Performance (hot paths, allocs, caching/streaming)
- Security (validation, authN/Z, secrets, SSRF/XSS/CSRF)
- G11N/L10N (resources, number/date, pluralization)
- Compatibility (public APIs, formats, OS/runtime/toolchain)
- Extensibility (DI seams, options/flags, plugin points)
- Accessibility (roles, labels, focus, keyboard, contrast)
- SOLID & repo conventions (naming, folders, dependency direction)
5) **Logging & Exception Handling**
- Where to log; levels; structured fields; correlation/traces.
- What to catch vs rethrow; retries/backoff; user-visible errors.
- **Privacy**: never log secrets/PII; redaction policy.
6) **Telemetry (optional — business metrics only)**
- Events/metrics (name, when, props); success signal; privacy/sampling; dashboards/alerts.
7) **Risks & Mitigations** — flags/canary/shadow-write/config guards.
8) **Task Breakdown (agent-ready)** — table (leave a blank line before the header so Markdown renders correctly):
| Task | Intent | Files/Areas | Steps | Tests (brief) | Owner (Agent/Human) | Human interaction needed? (why) |
|---|---|---|---|---|---|---|
9) **Tests to Add (only)**
- **Unit**: targets, cases (success/edge/error), mocks/fixtures, path, notes.
- **UI** (if applicable): flows, locator strategy, env/data/flags, path, flake mitigation.

View File

@@ -1,731 +0,0 @@
# IssueReviewLib.ps1 - Shared helpers for bulk issue review automation
# Part of the PowerToys GitHub Copilot/Claude Code issue review system
#region Console Output Helpers
function Info { param([string]$Message) Write-Host $Message -ForegroundColor Cyan }
function Warn { param([string]$Message) Write-Host $Message -ForegroundColor Yellow }
function Err { param([string]$Message) Write-Host $Message -ForegroundColor Red }
function Success { param([string]$Message) Write-Host $Message -ForegroundColor Green }
#endregion
#region Repository Helpers
function Get-RepoRoot {
$root = git rev-parse --show-toplevel 2>$null
if (-not $root) { throw 'Not inside a git repository.' }
return (Resolve-Path $root).Path
}
function Get-GeneratedFilesPath {
param([string]$RepoRoot)
return Join-Path $RepoRoot 'Generated Files'
}
function Get-IssueReviewPath {
param(
[string]$RepoRoot,
[int]$IssueNumber
)
$genFiles = Get-GeneratedFilesPath -RepoRoot $RepoRoot
return Join-Path $genFiles "issueReview/$IssueNumber"
}
function Get-IssueTitleFromOverview {
<#
.SYNOPSIS
Extract issue title from existing overview.md file.
.DESCRIPTION
Parses the overview.md to get the issue title without requiring GitHub CLI.
#>
param(
[Parameter(Mandatory)]
[string]$OverviewPath
)
if (-not (Test-Path $OverviewPath)) {
return $null
}
$content = Get-Content $OverviewPath -Raw
# Try to match title from Summary table: | **Title** | <title> |
if ($content -match '\*\*Title\*\*\s*\|\s*([^|]+)\s*\|') {
return $Matches[1].Trim()
}
# Try to match from header: # Issue #XXXX: <title>
if ($content -match '# Issue #\d+[:\s]+(.+)$' ) {
return $Matches[1].Trim()
}
# Try to match: # Issue #XXXX Review: <title>
if ($content -match '# Issue #\d+ Review[:\s]+(.+)$') {
return $Matches[1].Trim()
}
return $null
}
function Ensure-DirectoryExists {
param([string]$Path)
if (-not (Test-Path $Path)) {
New-Item -ItemType Directory -Path $Path -Force | Out-Null
}
}
#endregion
#region GitHub Issue Query Helpers
function Get-GitHubIssues {
<#
.SYNOPSIS
Query GitHub issues by label, state, and sort order.
.PARAMETER Labels
Comma-separated list of labels to filter by (e.g., "bug,help wanted").
.PARAMETER State
Issue state: open, closed, or all. Default: open.
.PARAMETER Sort
Sort field: created, updated, comments, reactions. Default: created.
.PARAMETER Order
Sort order: asc or desc. Default: desc.
.PARAMETER Limit
Maximum number of issues to return. Default: 100.
.PARAMETER Repository
Repository in owner/repo format. Default: microsoft/PowerToys.
#>
param(
[string]$Labels,
[ValidateSet('open', 'closed', 'all')]
[string]$State = 'open',
[ValidateSet('created', 'updated', 'comments', 'reactions')]
[string]$Sort = 'created',
[ValidateSet('asc', 'desc')]
[string]$Order = 'desc',
[int]$Limit = 100,
[string]$Repository = 'microsoft/PowerToys'
)
$ghArgs = @('issue', 'list', '--repo', $Repository, '--state', $State, '--limit', $Limit)
if ($Labels) {
foreach ($label in ($Labels -split ',')) {
$ghArgs += @('--label', $label.Trim())
}
}
# Build JSON fields (use reactionGroups instead of reactions)
$jsonFields = 'number,title,state,labels,createdAt,updatedAt,author,reactionGroups,comments'
$ghArgs += @('--json', $jsonFields)
Info "Querying issues: gh $($ghArgs -join ' ')"
$result = & gh @ghArgs 2>&1
if ($LASTEXITCODE -ne 0) {
throw "Failed to query issues: $result"
}
$issues = $result | ConvertFrom-Json
# Sort by reactions if requested (gh CLI doesn't support this natively)
if ($Sort -eq 'reactions') {
$issues = $issues | ForEach-Object {
# reactionGroups is an array of {content, users} - sum up user counts
$totalReactions = ($_.reactionGroups | ForEach-Object { $_.users.totalCount } | Measure-Object -Sum).Sum
if (-not $totalReactions) { $totalReactions = 0 }
$_ | Add-Member -NotePropertyName 'totalReactions' -NotePropertyValue $totalReactions -PassThru
}
if ($Order -eq 'desc') {
$issues = $issues | Sort-Object -Property totalReactions -Descending
} else {
$issues = $issues | Sort-Object -Property totalReactions
}
}
return $issues
}
function Get-IssueDetails {
<#
.SYNOPSIS
Get detailed information about a specific issue.
#>
param(
[Parameter(Mandatory)]
[int]$IssueNumber,
[string]$Repository = 'microsoft/PowerToys'
)
$jsonFields = 'number,title,body,state,labels,createdAt,updatedAt,author,reactions,comments,linkedPullRequests,milestone'
$result = gh issue view $IssueNumber --repo $Repository --json $jsonFields 2>&1
if ($LASTEXITCODE -ne 0) {
throw "Failed to get issue #$IssueNumber`: $result"
}
return $result | ConvertFrom-Json
}
#endregion
#region CLI Detection and Execution
function Get-AvailableCLI {
<#
.SYNOPSIS
Detect which AI CLI is available: GitHub Copilot CLI or Claude Code.
.OUTPUTS
Returns object with: Name, Command, PromptArg
#>
# Check for standalone GitHub Copilot CLI (copilot command)
$copilotCLI = Get-Command 'copilot' -ErrorAction SilentlyContinue
if ($copilotCLI) {
return @{
Name = 'GitHub Copilot CLI'
Command = 'copilot'
Args = @('-p') # Non-interactive prompt mode
Type = 'copilot'
}
}
# Check for Claude Code CLI
$claudeCode = Get-Command 'claude' -ErrorAction SilentlyContinue
if ($claudeCode) {
return @{
Name = 'Claude Code CLI'
Command = 'claude'
Args = @()
Type = 'claude'
}
}
# Check for GitHub Copilot CLI via gh extension
$ghCopilot = Get-Command 'gh' -ErrorAction SilentlyContinue
if ($ghCopilot) {
$copilotCheck = gh extension list 2>&1 | Select-String -Pattern 'copilot'
if ($copilotCheck) {
return @{
Name = 'GitHub Copilot CLI (gh extension)'
Command = 'gh'
Args = @('copilot', 'suggest')
Type = 'gh-copilot'
}
}
}
# Check for VS Code CLI with Copilot
$code = Get-Command 'code' -ErrorAction SilentlyContinue
if ($code) {
return @{
Name = 'VS Code (Copilot Chat)'
Command = 'code'
Args = @()
Type = 'vscode'
}
}
return $null
}
function Invoke-AIReview {
<#
.SYNOPSIS
Invoke AI CLI to review a single issue.
.PARAMETER IssueNumber
The issue number to review.
.PARAMETER RepoRoot
Repository root path.
.PARAMETER CLIType
CLI type: 'claude', 'copilot', 'gh-copilot', or 'vscode'.
.PARAMETER WorkingDirectory
Working directory for the CLI command.
#>
param(
[Parameter(Mandatory)]
[int]$IssueNumber,
[Parameter(Mandatory)]
[string]$RepoRoot,
[ValidateSet('claude', 'copilot', 'gh-copilot', 'vscode')]
[string]$CLIType = 'copilot',
[string]$WorkingDirectory
)
if (-not $WorkingDirectory) {
$WorkingDirectory = $RepoRoot
}
$promptFile = Join-Path $RepoRoot '.github/prompts/review-issue.prompt.md'
if (-not (Test-Path $promptFile)) {
throw "Prompt file not found: $promptFile"
}
# Prepare the prompt with issue number substitution
$promptContent = Get-Content $promptFile -Raw
$promptContent = $promptContent -replace '\{\{issue_number\}\}', $IssueNumber
# Create temp prompt file
$tempPromptDir = Join-Path $env:TEMP "issue-review-$IssueNumber"
Ensure-DirectoryExists -Path $tempPromptDir
$tempPromptFile = Join-Path $tempPromptDir "prompt.md"
$promptContent | Set-Content -Path $tempPromptFile -Encoding UTF8
# Build the prompt text for CLI
$promptText = "Review GitHub issue #$IssueNumber following the template in .github/prompts/review-issue.prompt.md. Generate overview.md and implementation-plan.md in 'Generated Files/issueReview/$IssueNumber/'"
switch ($CLIType) {
'copilot' {
# GitHub Copilot CLI (standalone copilot command)
# Use --yolo for full permissions (--allow-all-tools --allow-all-paths --allow-all-urls)
# Use -s (silent) for cleaner output in batch mode
# Enable ALL GitHub MCP tools (issues, PRs, repos, etc.) + github-artifacts for images/attachments
# MCP config path relative to repo root for github-artifacts tools
$mcpConfig = '@.github/skills/issue-review/references/mcp-config.json'
$args = @(
'--additional-mcp-config', $mcpConfig, # Load github-artifacts MCP for image/attachment analysis
'-p', $promptText, # Non-interactive prompt mode (exits after completion)
'--yolo', # Enable all permissions for automated execution
'-s', # Silent mode - output only agent response
'--enable-all-github-mcp-tools', # Enable ALL GitHub MCP tools (issues, PRs, search, etc.)
'--allow-tool', 'github-artifacts' # Also enable our custom github-artifacts MCP
)
return @{
Command = 'copilot'
Arguments = $args
WorkingDirectory = $WorkingDirectory
IssueNumber = $IssueNumber
}
}
'claude' {
# Claude Code CLI
$args = @(
'--print', # Non-interactive mode
'--dangerously-skip-permissions',
'--prompt', $promptText
)
return @{
Command = 'claude'
Arguments = $args
WorkingDirectory = $WorkingDirectory
IssueNumber = $IssueNumber
}
}
'gh-copilot' {
# GitHub Copilot CLI via gh
$args = @(
'copilot', 'suggest',
'-t', 'shell',
"Review GitHub issue #$IssueNumber and generate analysis files"
)
return @{
Command = 'gh'
Arguments = $args
WorkingDirectory = $WorkingDirectory
IssueNumber = $IssueNumber
}
}
'vscode' {
# VS Code with Copilot - open with prompt
$args = @(
'--new-window',
$WorkingDirectory,
'--goto', $tempPromptFile
)
return @{
Command = 'code'
Arguments = $args
WorkingDirectory = $WorkingDirectory
IssueNumber = $IssueNumber
}
}
}
}
#endregion
#region Parallel Job Management
function Start-ParallelIssueReviews {
<#
.SYNOPSIS
Start parallel issue reviews with throttling.
.PARAMETER Issues
Array of issue objects to review.
.PARAMETER MaxParallel
Maximum number of parallel jobs. Default: 20.
.PARAMETER CLIType
CLI type to use for reviews.
.PARAMETER RepoRoot
Repository root path.
.PARAMETER TimeoutMinutes
Timeout per issue in minutes. Default: 30.
.PARAMETER MaxRetries
Maximum number of retries for failed issues. Default: 2.
.PARAMETER RetryDelaySeconds
Delay between retries in seconds. Default: 10.
#>
param(
[Parameter(Mandatory)]
[array]$Issues,
[int]$MaxParallel = 20,
[ValidateSet('claude', 'copilot', 'gh-copilot', 'vscode')]
[string]$CLIType = 'copilot',
[Parameter(Mandatory)]
[string]$RepoRoot,
[int]$TimeoutMinutes = 30,
[int]$MaxRetries = 2,
[int]$RetryDelaySeconds = 10
)
$totalIssues = $Issues.Count
$completed = 0
$failed = @()
$succeeded = @()
$retryQueue = [System.Collections.Queue]::new()
Info "Starting parallel review of $totalIssues issues (max $MaxParallel concurrent, $MaxRetries retries)"
# Use PowerShell jobs for parallelization
$jobs = @()
$issueQueue = [System.Collections.Queue]::new($Issues)
while ($issueQueue.Count -gt 0 -or $jobs.Count -gt 0 -or $retryQueue.Count -gt 0) {
# Process retry queue when main queue is empty
if ($issueQueue.Count -eq 0 -and $retryQueue.Count -gt 0 -and $jobs.Count -lt $MaxParallel) {
$retryItem = $retryQueue.Dequeue()
Warn "🔄 Retrying issue #$($retryItem.IssueNumber) (attempt $($retryItem.Attempt + 1)/$($MaxRetries + 1))"
Start-Sleep -Seconds $RetryDelaySeconds
$issueQueue.Enqueue(@{ number = $retryItem.IssueNumber; _retryAttempt = $retryItem.Attempt + 1 })
}
# Start new jobs up to MaxParallel
while ($jobs.Count -lt $MaxParallel -and $issueQueue.Count -gt 0) {
$issue = $issueQueue.Dequeue()
$issueNum = $issue.number
$retryAttempt = if ($issue._retryAttempt) { $issue._retryAttempt } else { 0 }
$attemptInfo = if ($retryAttempt -gt 0) { " (retry $retryAttempt)" } else { "" }
Info "Starting review for issue #$issueNum$attemptInfo ($($totalIssues - $issueQueue.Count)/$totalIssues)"
$job = Start-Job -Name "Issue-$issueNum" -ScriptBlock {
param($IssueNumber, $RepoRoot, $CLIType)
Set-Location $RepoRoot
# Import the library in the job context
. "$RepoRoot/.github/review-tools/IssueReviewLib.ps1"
try {
$reviewCmd = Invoke-AIReview -IssueNumber $IssueNumber -RepoRoot $RepoRoot -CLIType $CLIType
# Execute the command using invocation operator (works for .ps1 scripts and executables)
Set-Location $reviewCmd.WorkingDirectory
$argList = $reviewCmd.Arguments
# Capture both stdout and stderr for better error reporting
$output = & $reviewCmd.Command @argList 2>&1
$exitCode = $LASTEXITCODE
# Get last 20 lines of output for error context
$outputLines = $output | Out-String
$lastLines = ($outputLines -split "`n" | Select-Object -Last 20) -join "`n"
# Check if output files were created (success indicator)
$overviewPath = Join-Path $RepoRoot "Generated Files/issueReview/$IssueNumber/overview.md"
$implPlanPath = Join-Path $RepoRoot "Generated Files/issueReview/$IssueNumber/implementation-plan.md"
$filesCreated = (Test-Path $overviewPath) -and (Test-Path $implPlanPath)
return @{
IssueNumber = $IssueNumber
Success = ($exitCode -eq 0) -or $filesCreated
ExitCode = $exitCode
FilesCreated = $filesCreated
Output = $lastLines
Error = if ($exitCode -ne 0 -and -not $filesCreated) { "Exit code: $exitCode`n$lastLines" } else { $null }
}
}
catch {
return @{
IssueNumber = $IssueNumber
Success = $false
ExitCode = -1
FilesCreated = $false
Output = $null
Error = $_.Exception.Message
}
}
} -ArgumentList $issueNum, $RepoRoot, $CLIType
$jobs += @{
Job = $job
IssueNumber = $issueNum
StartTime = Get-Date
RetryAttempt = $retryAttempt
}
}
# Check for completed jobs
$completedJobs = @()
foreach ($jobInfo in $jobs) {
$job = $jobInfo.Job
$issueNum = $jobInfo.IssueNumber
$startTime = $jobInfo.StartTime
$retryAttempt = $jobInfo.RetryAttempt
if ($job.State -eq 'Completed') {
$result = Receive-Job -Job $job
Remove-Job -Job $job -Force
if ($result.Success) {
Success "✓ Issue #$issueNum completed (files created: $($result.FilesCreated))"
$succeeded += $issueNum
$completed++
} else {
# Check if we should retry
if ($retryAttempt -lt $MaxRetries) {
$errorPreview = if ($result.Error) { ($result.Error -split "`n" | Select-Object -First 3) -join " | " } else { "Unknown error" }
Warn "⚠ Issue #$issueNum failed (will retry): $errorPreview"
$retryQueue.Enqueue(@{ IssueNumber = $issueNum; Attempt = $retryAttempt; LastError = $result.Error })
} else {
$errorMsg = if ($result.Error) { $result.Error } else { "Exit code: $($result.ExitCode)" }
Err "✗ Issue #$issueNum failed after $($retryAttempt + 1) attempts:"
Err " Error: $errorMsg"
$failed += @{ IssueNumber = $issueNum; Error = $errorMsg; Attempts = $retryAttempt + 1 }
$completed++
}
}
$completedJobs += $jobInfo
}
elseif ($job.State -eq 'Failed') {
$jobError = $job.ChildJobs[0].JobStateInfo.Reason.Message
Remove-Job -Job $job -Force
if ($retryAttempt -lt $MaxRetries) {
Warn "⚠ Issue #$issueNum job crashed (will retry): $jobError"
$retryQueue.Enqueue(@{ IssueNumber = $issueNum; Attempt = $retryAttempt; LastError = $jobError })
} else {
Err "✗ Issue #$issueNum job failed after $($retryAttempt + 1) attempts: $jobError"
$failed += @{ IssueNumber = $issueNum; Error = $jobError; Attempts = $retryAttempt + 1 }
$completed++
}
$completedJobs += $jobInfo
}
elseif ((Get-Date) - $startTime -gt [TimeSpan]::FromMinutes($TimeoutMinutes)) {
Stop-Job -Job $job -ErrorAction SilentlyContinue
Remove-Job -Job $job -Force
if ($retryAttempt -lt $MaxRetries) {
Warn "⏱ Issue #$issueNum timed out after $TimeoutMinutes min (will retry)"
$retryQueue.Enqueue(@{ IssueNumber = $issueNum; Attempt = $retryAttempt; LastError = "Timeout after $TimeoutMinutes minutes" })
} else {
Err "⏱ Issue #$issueNum timed out after $($retryAttempt + 1) attempts"
$failed += @{ IssueNumber = $issueNum; Error = "Timeout after $TimeoutMinutes minutes"; Attempts = $retryAttempt + 1 }
$completed++
}
$completedJobs += $jobInfo
}
}
# Remove completed jobs from active list
$jobs = $jobs | Where-Object { $_ -notin $completedJobs }
# Brief pause to avoid tight loop
if ($jobs.Count -gt 0) {
Start-Sleep -Seconds 2
}
}
# Extract just issue numbers for the failed list
$failedNumbers = $failed | ForEach-Object { $_.IssueNumber }
return @{
Total = $totalIssues
Succeeded = $succeeded
Failed = $failedNumbers
FailedDetails = $failed
}
}
#endregion
#region Issue Review Results Helpers
function Get-IssueReviewResult {
<#
.SYNOPSIS
Check if an issue has been reviewed and get its results.
#>
param(
[Parameter(Mandatory)]
[int]$IssueNumber,
[Parameter(Mandatory)]
[string]$RepoRoot
)
$reviewPath = Get-IssueReviewPath -RepoRoot $RepoRoot -IssueNumber $IssueNumber
$result = @{
IssueNumber = $IssueNumber
Path = $reviewPath
HasOverview = $false
HasImplementationPlan = $false
OverviewPath = $null
ImplementationPlanPath = $null
}
$overviewPath = Join-Path $reviewPath 'overview.md'
$implPlanPath = Join-Path $reviewPath 'implementation-plan.md'
if (Test-Path $overviewPath) {
$result.HasOverview = $true
$result.OverviewPath = $overviewPath
}
if (Test-Path $implPlanPath) {
$result.HasImplementationPlan = $true
$result.ImplementationPlanPath = $implPlanPath
}
return $result
}
function Get-HighConfidenceIssues {
<#
.SYNOPSIS
Find issues with high confidence for auto-fix based on review results.
.PARAMETER RepoRoot
Repository root path.
.PARAMETER MinFeasibilityScore
Minimum Technical Feasibility score (0-100). Default: 70.
.PARAMETER MinClarityScore
Minimum Requirement Clarity score (0-100). Default: 60.
.PARAMETER MaxEffortDays
Maximum effort estimate in days. Default: 2 (S = Small).
.PARAMETER FilterIssueNumbers
Optional array of issue numbers to filter to. If specified, only these issues are considered.
#>
param(
[Parameter(Mandatory)]
[string]$RepoRoot,
[int]$MinFeasibilityScore = 70,
[int]$MinClarityScore = 60,
[int]$MaxEffortDays = 2,
[int[]]$FilterIssueNumbers = @()
)
$genFiles = Get-GeneratedFilesPath -RepoRoot $RepoRoot
$reviewDir = Join-Path $genFiles 'issueReview'
if (-not (Test-Path $reviewDir)) {
return @()
}
$highConfidence = @()
Get-ChildItem -Path $reviewDir -Directory | ForEach-Object {
$issueNum = [int]$_.Name
# Skip if filter is specified and this issue is not in the filter list
if ($FilterIssueNumbers.Count -gt 0 -and $issueNum -notin $FilterIssueNumbers) {
return
}
$overviewPath = Join-Path $_.FullName 'overview.md'
$implPlanPath = Join-Path $_.FullName 'implementation-plan.md'
if (-not (Test-Path $overviewPath) -or -not (Test-Path $implPlanPath)) {
return
}
# Parse overview.md to extract scores
$overview = Get-Content $overviewPath -Raw
# Extract scores using regex (looking for score table or inline scores)
$feasibility = 0
$clarity = 0
$effortDays = 999
# Try to extract from At-a-Glance Score Table
if ($overview -match 'Technical Feasibility[^\d]*(\d+)/100') {
$feasibility = [int]$Matches[1]
}
if ($overview -match 'Requirement Clarity[^\d]*(\d+)/100') {
$clarity = [int]$Matches[1]
}
# Match effort formats like "0.5-1 day", "1-2 days", "2-3 days" - extract the upper bound
if ($overview -match 'Effort Estimate[^|]*\|\s*[\d.]+(?:-(\d+))?\s*days?') {
if ($Matches[1]) {
$effortDays = [int]$Matches[1]
} elseif ($overview -match 'Effort Estimate[^|]*\|\s*(\d+)\s*days?') {
$effortDays = [int]$Matches[1]
}
}
# Also check for XS/S sizing in the table (e.g., "| XS |" or "| S |" or "(XS)" or "(S)")
if ($overview -match 'Effort Estimate[^|]*\|[^|]*\|\s*(XS|S)\b') {
# XS = 1 day, S = 2 days
if ($Matches[1] -eq 'XS') {
$effortDays = 1
} else {
$effortDays = 2
}
} elseif ($overview -match 'Effort Estimate[^|]*\|[^|]*\(XS\)') {
$effortDays = 1
} elseif ($overview -match 'Effort Estimate[^|]*\|[^|]*\(S\)') {
$effortDays = 2
}
if ($feasibility -ge $MinFeasibilityScore -and
$clarity -ge $MinClarityScore -and
$effortDays -le $MaxEffortDays) {
$highConfidence += @{
IssueNumber = $issueNum
FeasibilityScore = $feasibility
ClarityScore = $clarity
EffortDays = $effortDays
OverviewPath = $overviewPath
ImplementationPlanPath = $implPlanPath
}
}
}
return $highConfidence | Sort-Object -Property FeasibilityScore -Descending
}
#endregion
#region Worktree Integration
function Copy-IssueReviewToWorktree {
<#
.SYNOPSIS
Copy the Generated Files for an issue to a worktree.
.PARAMETER IssueNumber
The issue number.
.PARAMETER SourceRepoRoot
Source repository root (main repo).
.PARAMETER WorktreePath
Destination worktree path.
#>
param(
[Parameter(Mandatory)]
[int]$IssueNumber,
[Parameter(Mandatory)]
[string]$SourceRepoRoot,
[Parameter(Mandatory)]
[string]$WorktreePath
)
$sourceReviewPath = Get-IssueReviewPath -RepoRoot $SourceRepoRoot -IssueNumber $IssueNumber
$destReviewPath = Get-IssueReviewPath -RepoRoot $WorktreePath -IssueNumber $IssueNumber
if (-not (Test-Path $sourceReviewPath)) {
throw "Issue review files not found at: $sourceReviewPath"
}
Ensure-DirectoryExists -Path $destReviewPath
# Copy all files from the issue review folder
Copy-Item -Path "$sourceReviewPath\*" -Destination $destReviewPath -Recurse -Force
Info "Copied issue review files to: $destReviewPath"
return $destReviewPath
}
#endregion
# Note: This script is dot-sourced, not imported as a module.
# All functions above are available after: . "path/to/IssueReviewLib.ps1"

View File

@@ -1,238 +0,0 @@
<#!
.SYNOPSIS
Bulk review GitHub issues using AI CLI (Claude Code or GitHub Copilot).
.DESCRIPTION
Queries GitHub issues by labels, state, and sort order, then kicks off parallel
AI-powered reviews for each issue. Results are stored in Generated Files/issueReview/<number>/.
.PARAMETER Labels
Comma-separated list of labels to filter issues (e.g., "bug,help wanted").
.PARAMETER State
Issue state: open, closed, or all. Default: open.
.PARAMETER Sort
Sort field: created, updated, comments, reactions. Default: created.
.PARAMETER Order
Sort order: asc or desc. Default: desc.
.PARAMETER Limit
Maximum number of issues to process. Default: 100.
.PARAMETER MaxParallel
Maximum parallel review jobs. Default: 20.
.PARAMETER CLIType
AI CLI to use: claude, gh-copilot, or vscode. Auto-detected if not specified.
.PARAMETER DryRun
List issues without starting reviews.
.PARAMETER SkipExisting
Skip issues that already have review files.
.PARAMETER Repository
Repository in owner/repo format. Default: microsoft/PowerToys.
.PARAMETER TimeoutMinutes
Timeout per issue review in minutes. Default: 30.
.EXAMPLE
# Review all open bugs sorted by reactions
./Start-BulkIssueReview.ps1 -Labels "bug" -Sort reactions -Order desc
.EXAMPLE
# Dry run to see which issues would be reviewed
./Start-BulkIssueReview.ps1 -Labels "help wanted" -DryRun
.EXAMPLE
# Review top 50 issues with Claude Code, max 10 parallel
./Start-BulkIssueReview.ps1 -Labels "Issue-Bug" -Limit 50 -MaxParallel 10 -CLIType claude
.EXAMPLE
# Skip already-reviewed issues
./Start-BulkIssueReview.ps1 -Labels "Issue-Feature" -SkipExisting
.NOTES
Requires: GitHub CLI (gh) authenticated, and either Claude Code CLI or VS Code with Copilot.
Results: Generated Files/issueReview/<issue_number>/overview.md and implementation-plan.md
#>
[CmdletBinding()]
param(
[Parameter(Position = 0)]
[string]$Labels,
[ValidateSet('open', 'closed', 'all')]
[string]$State = 'open',
[ValidateSet('created', 'updated', 'comments', 'reactions')]
[string]$Sort = 'created',
[ValidateSet('asc', 'desc')]
[string]$Order = 'desc',
[int]$Limit = 1000,
[int]$MaxParallel = 20,
[ValidateSet('claude', 'copilot', 'gh-copilot', 'vscode', 'auto')]
[string]$CLIType = 'auto',
[switch]$DryRun,
[switch]$SkipExisting,
[string]$Repository = 'microsoft/PowerToys',
[int]$TimeoutMinutes = 30,
[int]$MaxRetries = 2,
[int]$RetryDelaySeconds = 10,
[switch]$Force,
[switch]$Help
)
# Load library
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
. "$scriptDir/IssueReviewLib.ps1"
# Show help
if ($Help) {
Get-Help $MyInvocation.MyCommand.Path -Full
return
}
#region Main Script
try {
# Get repo root
$repoRoot = Get-RepoRoot
Info "Repository root: $repoRoot"
# Detect or validate CLI
if ($CLIType -eq 'auto') {
$cli = Get-AvailableCLI
if (-not $cli) {
throw "No AI CLI found. Please install Claude Code CLI or GitHub Copilot CLI extension."
}
$CLIType = $cli.Type
Info "Auto-detected CLI: $($cli.Name)"
}
# Query issues
Info "`nQuerying issues with filters:"
Info " Labels: $(if ($Labels) { $Labels } else { '(none)' })"
Info " State: $State"
Info " Sort: $Sort $Order"
Info " Limit: $Limit"
$issues = Get-GitHubIssues -Labels $Labels -State $State -Sort $Sort -Order $Order -Limit $Limit -Repository $Repository
if ($issues.Count -eq 0) {
Warn "No issues found matching the criteria."
return
}
Info "`nFound $($issues.Count) issues"
# Filter out existing reviews if requested
if ($SkipExisting) {
$originalCount = $issues.Count
$issues = $issues | Where-Object {
$result = Get-IssueReviewResult -IssueNumber $_.number -RepoRoot $repoRoot
-not ($result.HasOverview -and $result.HasImplementationPlan)
}
$skipped = $originalCount - $issues.Count
if ($skipped -gt 0) {
Info "Skipping $skipped issues with existing reviews"
}
}
if ($issues.Count -eq 0) {
Warn "All issues already have reviews. Nothing to do."
return
}
# Display issue list
Info "`nIssues to review:"
Info ("-" * 80)
foreach ($issue in $issues) {
$labels = ($issue.labels | ForEach-Object { $_.name }) -join ', '
$reactions = if ($issue.reactions) { $issue.reactions.totalCount } else { 0 }
Info ("#{0,-6} {1,-50} [👍{2}] [{3}]" -f $issue.number, ($issue.title.Substring(0, [Math]::Min(50, $issue.title.Length))), $reactions, $labels)
}
Info ("-" * 80)
if ($DryRun) {
Warn "`nDry run mode - no reviews started."
Info "Would review $($issues.Count) issues with CLI: $CLIType"
return
}
# Confirm before proceeding (skip if -Force)
if (-not $Force) {
$confirm = Read-Host "`nProceed with reviewing $($issues.Count) issues using $CLIType? (y/N)"
if ($confirm -notmatch '^[yY]') {
Info "Cancelled."
return
}
} else {
Info "`nProceeding with $($issues.Count) issues (Force mode)"
}
# Create output directory
$genFiles = Get-GeneratedFilesPath -RepoRoot $repoRoot
Ensure-DirectoryExists -Path (Join-Path $genFiles 'issueReview')
# Start parallel reviews
Info "`nStarting bulk review..."
Info " Max retries: $MaxRetries (delay: ${RetryDelaySeconds}s)"
$startTime = Get-Date
$results = Start-ParallelIssueReviews `
-Issues $issues `
-MaxParallel $MaxParallel `
-CLIType $CLIType `
-RepoRoot $repoRoot `
-TimeoutMinutes $TimeoutMinutes `
-MaxRetries $MaxRetries `
-RetryDelaySeconds $RetryDelaySeconds
$duration = (Get-Date) - $startTime
# Summary
Info "`n" + ("=" * 80)
Info "BULK REVIEW COMPLETE"
Info ("=" * 80)
Info "Total issues: $($results.Total)"
Success "Succeeded: $($results.Succeeded.Count)"
if ($results.Failed.Count -gt 0) {
Err "Failed: $($results.Failed.Count)"
Err "Failed issues: $($results.Failed -join ', ')"
Info ""
Info "Failed Issue Details:"
Info ("-" * 40)
foreach ($failedItem in $results.FailedDetails) {
Err " #$($failedItem.IssueNumber) (attempts: $($failedItem.Attempts)):"
$errorLines = ($failedItem.Error -split "`n" | Select-Object -First 5) -join "`n "
Err " $errorLines"
}
Info ("-" * 40)
}
Info "Duration: $($duration.ToString('hh\:mm\:ss'))"
Info "Output: $genFiles/issueReview/"
Info ("=" * 80)
# Return results for pipeline
return $results
}
catch {
Err "Error: $($_.Exception.Message)"
exit 1
}
#endregion

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,136 +0,0 @@
---
name: issue-to-pr-cycle
description: End-to-end automation from issue analysis to PR creation and review. Use when asked to fix multiple issues automatically, run full issue cycle, batch process issues, automate issue resolution, create PRs for high-confidence issues, or process issues end-to-end. Orchestrates issue review, auto-fix, PR submission, and PR review in parallel batches.
license: Complete terms in LICENSE.txt
---
# Issue-to-PR Full Cycle Skill
Orchestrate the complete workflow from issue analysis to PR creation and review. Processes multiple issues in parallel with configurable confidence thresholds.
## Skill Contents
This skill is **self-contained** with all required resources:
```
.github/skills/issue-to-pr-cycle/
├── SKILL.md # This file
├── LICENSE.txt # MIT License
└── scripts/
└── Start-FullIssueCycle.ps1 # Main orchestration script
```
**Note**: This skill orchestrates other skills via their PowerShell scripts:
- `issue-review` skill scripts
- `issue-fix` skill scripts
- `submit-pr` skill scripts
- `pr-review` skill scripts
## Output
The skill produces:
1. Issue review files in `Generated Files/issueReview/<issue-number>/`
2. Git worktrees with fixes at `Q:/PowerToys-xxxx/`
3. Pull requests on GitHub
4. PR review files in `Generated Files/prReview/<pr-number>/`
## When to Use This Skill
- Process multiple issues end-to-end automatically
- Batch fix high-confidence issues
- Run full automation cycle for triaged issues
- Create PRs for multiple reviewed issues
- Automate issue-to-PR workflow
## Prerequisites
- GitHub CLI (`gh`) installed and authenticated
- Copilot CLI or Claude CLI installed
- PowerShell 7+ for running scripts
- Issues already reviewed (have `Generated Files/issueReview/` data)
## Quick Start
### Option 1: Dry Run First
See what would be processed without making changes:
```powershell
# From repo root
.github/skills/issue-to-pr-cycle/scripts/Start-FullIssueCycle.ps1 `
-MinFeasibilityScore 70 `
-MinClarityScore 70 `
-MaxEffortDays 10 `
-SkipExisting `
-DryRun
```
### Option 2: Run Full Cycle
Process all matching issues:
```powershell
.github/skills/issue-to-pr-cycle/scripts/Start-FullIssueCycle.ps1 `
-MinFeasibilityScore 70 `
-MinClarityScore 70 `
-MaxEffortDays 10 `
-SkipExisting `
-CLIType copilot `
-Force
```
## CLI Options
| Parameter | Description | Default |
|-----------|-------------|---------|
| `-MinFeasibilityScore` | Minimum technical feasibility score (0-100) | `70` |
| `-MinClarityScore` | Minimum requirement clarity score (0-100) | `70` |
| `-MaxEffortDays` | Maximum effort estimate in days | `10` |
| `-ExcludeIssues` | Array of issue numbers to skip | `@()` |
| `-SkipExisting` | Skip issues that already have PRs | `false` |
| `-CLIType` | AI CLI to use: `copilot` or `claude` | `copilot` |
| `-FixThrottleLimit` | Parallel limit for fix phase | `5` |
| `-PRThrottleLimit` | Parallel limit for PR phase | `5` |
| `-ReviewThrottleLimit` | Parallel limit for review phase | `3` |
| `-DryRun` | Show what would be done | `false` |
| `-Force` | Skip confirmation prompts | `false` |
## Workflow Phases
```
┌─────────────────────────────────────────────────────────────┐
│ PHASE 1: Auto-Fix Issues (Parallel) │
│ Uses: issue-fix skill scripts │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ PHASE 2: Submit PRs (Parallel) │
│ Uses: submit-pr skill scripts │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ PHASE 3: Review PRs (Parallel) │
│ Uses: pr-review skill scripts │
└─────────────────────────────────────────────────────────────┘
```
## Related Skills
This skill orchestrates (via PowerShell, not skill-to-skill):
| Skill | Script Location | Purpose |
|-------|-----------------|---------|
| `issue-review` | `.github/skills/issue-review/scripts/` | Analyze issues |
| `issue-fix` | `.github/skills/issue-fix/scripts/` | Create fixes |
| `submit-pr` | `.github/skills/submit-pr/scripts/` | Create PRs |
| `pr-review` | `.github/skills/pr-review/scripts/` | Review PRs |
You can use each skill independently for finer control.
## Troubleshooting
| Problem | Solution |
|---------|----------|
| No issues found | Lower score thresholds or run more issue reviews |
| All issues skipped | Remove `-SkipExisting` or check for existing PRs |
| Parallel failures | Reduce throttle limits |

View File

@@ -1,123 +0,0 @@
# IssueReviewLib.ps1 - Helpers for full issue-to-PR cycle workflow
# Part of the PowerToys GitHub Copilot/Claude Code issue review system
# This is a trimmed version with only what issue-to-pr-cycle needs
#region Console Output Helpers
function Info { param([string]$Message) Write-Host $Message -ForegroundColor Cyan }
function Warn { param([string]$Message) Write-Host $Message -ForegroundColor Yellow }
function Err { param([string]$Message) Write-Host $Message -ForegroundColor Red }
function Success { param([string]$Message) Write-Host $Message -ForegroundColor Green }
#endregion
#region Repository Helpers
function Get-RepoRoot {
$root = git rev-parse --show-toplevel 2>$null
if (-not $root) { throw 'Not inside a git repository.' }
return (Resolve-Path $root).Path
}
function Get-GeneratedFilesPath {
param([string]$RepoRoot)
return Join-Path $RepoRoot 'Generated Files'
}
#endregion
#region Issue Review Results Helpers
function Get-HighConfidenceIssues {
<#
.SYNOPSIS
Find issues with high confidence for auto-fix based on review results.
.PARAMETER RepoRoot
Repository root path.
.PARAMETER MinFeasibilityScore
Minimum Technical Feasibility score (0-100). Default: 70.
.PARAMETER MinClarityScore
Minimum Requirement Clarity score (0-100). Default: 60.
.PARAMETER MaxEffortDays
Maximum effort estimate in days. Default: 2 (S = Small).
.PARAMETER FilterIssueNumbers
Optional array of issue numbers to filter to. If specified, only these issues are considered.
#>
param(
[Parameter(Mandatory)]
[string]$RepoRoot,
[int]$MinFeasibilityScore = 70,
[int]$MinClarityScore = 60,
[int]$MaxEffortDays = 2,
[int[]]$FilterIssueNumbers = @()
)
$genFiles = Get-GeneratedFilesPath -RepoRoot $RepoRoot
$reviewDir = Join-Path $genFiles 'issueReview'
if (-not (Test-Path $reviewDir)) {
return @()
}
$highConfidence = @()
Get-ChildItem -Path $reviewDir -Directory | ForEach-Object {
$issueNum = [int]$_.Name
# Skip if filter is specified and this issue is not in the filter list
if ($FilterIssueNumbers.Count -gt 0 -and $issueNum -notin $FilterIssueNumbers) {
return
}
$overviewPath = Join-Path $_.FullName 'overview.md'
$implPlanPath = Join-Path $_.FullName 'implementation-plan.md'
if (-not (Test-Path $overviewPath) -or -not (Test-Path $implPlanPath)) {
return
}
# Parse overview.md to extract scores
$overview = Get-Content $overviewPath -Raw
# Extract scores using regex (looking for score table or inline scores)
$feasibility = 0
$clarity = 0
$effortDays = 999
# Try to extract from At-a-Glance Score Table
if ($overview -match 'Technical Feasibility[^\d]*(\d+)/100') {
$feasibility = [int]$Matches[1]
}
if ($overview -match 'Requirement Clarity[^\d]*(\d+)/100') {
$clarity = [int]$Matches[1]
}
# Match effort formats like "0.5-1 day", "1-2 days", "2-3 days" - extract the upper bound
if ($overview -match 'Effort Estimate[^|]*\|\s*[\d.]+(?:-(\d+))?\s*days?') {
if ($Matches[1]) {
$effortDays = [int]$Matches[1]
} elseif ($overview -match 'Effort Estimate[^|]*\|\s*(\d+)\s*days?') {
$effortDays = [int]$Matches[1]
}
}
# Also check for XS/S sizing in the table
if ($overview -match 'Effort Estimate[^|]*\|[^|]*\|\s*(XS|S)\b') {
if ($Matches[1] -eq 'XS') { $effortDays = 1 } else { $effortDays = 2 }
} elseif ($overview -match 'Effort Estimate[^|]*\|[^|]*\(XS\)') {
$effortDays = 1
} elseif ($overview -match 'Effort Estimate[^|]*\|[^|]*\(S\)') {
$effortDays = 2
}
if ($feasibility -ge $MinFeasibilityScore -and
$clarity -ge $MinClarityScore -and
$effortDays -le $MaxEffortDays) {
$highConfidence += @{
IssueNumber = $issueNum
FeasibilityScore = $feasibility
ClarityScore = $clarity
EffortDays = $effortDays
OverviewPath = $overviewPath
ImplementationPlanPath = $implPlanPath
}
}
}
return $highConfidence | Sort-Object -Property FeasibilityScore -Descending
}
#endregion

View File

@@ -1,478 +0,0 @@
<#!
.SYNOPSIS
Run the complete issue-to-PR cycle: fix issues, create PRs, review, and fix comments.
.DESCRIPTION
Orchestrates the full workflow:
1. Find high-confidence issues matching criteria
2. Create worktrees and run auto-fix for each issue
3. Commit changes and create PRs
4. Run PR review workflow (assign Copilot, review, fix comments)
.PARAMETER MinFeasibilityScore
Minimum Technical Feasibility score. Default: 70.
.PARAMETER MinClarityScore
Minimum Requirement Clarity score. Default: 70.
.PARAMETER MaxEffortDays
Maximum effort in days. Default: 10.
.PARAMETER ExcludeIssues
Array of issue numbers to exclude (already processed).
.PARAMETER CLIType
AI CLI to use: copilot or claude. Default: copilot.
.PARAMETER DryRun
Show what would be done without executing.
.PARAMETER SkipExisting
Skip issues that already have worktrees or PRs.
.EXAMPLE
./Start-FullIssueCycle.ps1 -MinFeasibilityScore 70 -MinClarityScore 70 -MaxEffortDays 10
.EXAMPLE
./Start-FullIssueCycle.ps1 -ExcludeIssues 44044,45029,32950,35703,44480 -DryRun
#>
[CmdletBinding()]
param(
[string]$Labels = '',
[int]$Limit = 500, # GitHub API max is 1000, default to 500 to get most issues
[int]$MinFeasibilityScore = 70,
[int]$MinClarityScore = 70,
[int]$MaxEffortDays = 10,
[int[]]$ExcludeIssues = @(),
[ValidateSet('copilot', 'claude')]
[string]$CLIType = 'copilot',
[int]$FixThrottleLimit = 5,
[int]$PRThrottleLimit = 5,
[int]$ReviewThrottleLimit = 3,
[switch]$DryRun,
[switch]$SkipExisting,
[switch]$SkipReview,
[switch]$Force,
[switch]$Help
)
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$skillsDir = Split-Path -Parent (Split-Path -Parent $scriptDir) # .github/skills
. (Join-Path $scriptDir 'IssueReviewLib.ps1')
# Paths to other skills' scripts
$issueFixScript = Join-Path $skillsDir 'issue-fix/scripts/Start-IssueAutoFix.ps1'
$submitPRScript = Join-Path $skillsDir 'submit-pr/scripts/Submit-IssueFixes.ps1'
$prReviewScript = Join-Path $skillsDir 'pr-review/scripts/Start-PRReviewWorkflow.ps1'
$repoRoot = Get-RepoRoot
$worktreeLib = Join-Path $repoRoot 'tools/build/WorktreeLib.ps1'
if (Test-Path $worktreeLib) {
. $worktreeLib
}
if ($Help) {
Get-Help $MyInvocation.MyCommand.Path -Full
return
}
#region Helper Functions
function Get-ExistingIssuePRs {
<#
.SYNOPSIS
Get ALL issues that already have PRs (open, closed, or merged) - checking GitHub directly.
#>
param(
[int[]]$IssueNumbers
)
$existingPRs = @{}
foreach ($issueNum in $IssueNumbers) {
# Check if there's a PR that mentions this issue (any state: open, closed, merged)
$prs = gh pr list --search "fixes #$issueNum OR closes #$issueNum OR resolves #$issueNum" --state all --json number,url,headRefName,state 2>$null | ConvertFrom-Json
if ($prs -and $prs.Count -gt 0) {
$existingPRs[$issueNum] = @{
PRNumber = $prs[0].number
PRUrl = $prs[0].url
Branch = $prs[0].headRefName
State = $prs[0].state
}
continue
}
# Also check for branch pattern issue/<number>* (any state)
$branchPrs = gh pr list --head "issue/$issueNum" --state all --json number,url,headRefName,state 2>$null | ConvertFrom-Json
if (-not $branchPrs -or $branchPrs.Count -eq 0) {
# Try with wildcard search via gh api
$branchPrs = gh pr list --state all --json number,url,headRefName,state 2>$null | ConvertFrom-Json | Where-Object { $_.headRefName -like "issue/$issueNum*" }
}
if ($branchPrs -and $branchPrs.Count -gt 0) {
$existingPRs[$issueNum] = @{
PRNumber = $branchPrs[0].number
PRUrl = $branchPrs[0].url
Branch = $branchPrs[0].headRefName
State = $branchPrs[0].state
}
}
}
return $existingPRs
}
function Get-ExistingWorktrees {
<#
.SYNOPSIS
Get issues that already have worktrees.
#>
$existingWorktrees = @{}
$worktrees = Get-WorktreeEntries | Where-Object { $_.Branch -like 'issue/*' }
foreach ($wt in $worktrees) {
if ($wt.Branch -match 'issue/(\d+)') {
$issueNum = [int]$Matches[1]
$existingWorktrees[$issueNum] = $wt.Path
}
}
return $existingWorktrees
}
#endregion
#region Main Script
try {
$startTime = Get-Date
Info "=" * 80
Info "FULL ISSUE-TO-PR CYCLE"
Info "=" * 80
Info "Repository root: $repoRoot"
Info "CLI type: $CLIType"
if ($Labels) {
Info "Labels filter: $Labels"
}
Info "Criteria: Feasibility >= $MinFeasibilityScore, Clarity >= $MinClarityScore, Effort <= $MaxEffortDays days"
# Step 0: Review issues first (if labels specified and not skipping review)
if ($Labels -and -not $SkipReview) {
Info "`n" + ("=" * 60)
Info "STEP 0: Reviewing issues with label '$Labels'"
Info ("=" * 60)
$reviewScript = Join-Path $scriptDir '../../issue-review/scripts/Start-BulkIssueReview.ps1'
if (Test-Path $reviewScript) {
$reviewArgs = @{
Labels = $Labels
Limit = $Limit
CLIType = $CLIType
Force = $Force
}
if ($DryRun) {
Info "[DRY RUN] Would run: Start-BulkIssueReview.ps1 -Labels '$Labels' -Limit $Limit -CLIType $CLIType -Force"
} else {
Info "Running bulk issue review..."
& $reviewScript @reviewArgs
}
} else {
Warn "Review script not found at: $reviewScript"
Warn "Proceeding with existing review data..."
}
}
# Step 1: Find high-confidence issues
Info "`n" + ("=" * 60)
Info "STEP 1: Finding high-confidence issues"
Info ("=" * 60)
# If labels specified, get the list of issue numbers with that label first
# This ensures we ONLY look at issues with the specified label, not all reviewed issues
$filterIssueNumbers = @()
if ($Labels) {
Info "Fetching issues with label '$Labels' from GitHub..."
$labeledIssues = gh issue list --repo microsoft/PowerToys --label "$Labels" --state open --limit $Limit --json number 2>$null | ConvertFrom-Json
$filterIssueNumbers = @($labeledIssues | ForEach-Object { $_.number })
Info "Found $($filterIssueNumbers.Count) issues with label '$Labels'"
}
$highConfidence = Get-HighConfidenceIssues `
-RepoRoot $repoRoot `
-MinFeasibilityScore $MinFeasibilityScore `
-MinClarityScore $MinClarityScore `
-MaxEffortDays $MaxEffortDays `
-FilterIssueNumbers $filterIssueNumbers
Info "Found $($highConfidence.Count) high-confidence issues matching criteria"
if ($highConfidence.Count -eq 0) {
Warn "No issues found matching criteria."
return
}
# Get issue numbers for checking
$issueNumbers = $highConfidence | ForEach-Object { $_.IssueNumber }
# Get existing PRs to skip (check GitHub directly)
Info "Checking for existing PRs..."
$existingPRs = Get-ExistingIssuePRs -IssueNumbers $issueNumbers
Info "Found $($existingPRs.Count) issues with existing PRs"
# Filter out excluded issues and those with existing PRs
$issuesToProcess = $highConfidence | Where-Object {
$issueNum = $_.IssueNumber
$excluded = $issueNum -in $ExcludeIssues
$hasPR = $existingPRs.ContainsKey($issueNum)
if ($excluded) {
Info " Excluding #$issueNum (in exclude list)"
}
if ($hasPR -and $SkipExisting) {
$prState = $existingPRs[$issueNum].State
Info " Skipping #$issueNum (has $prState PR #$($existingPRs[$issueNum].PRNumber))"
}
-not $excluded -and (-not $hasPR -or -not $SkipExisting)
}
if ($issuesToProcess.Count -eq 0) {
Warn "No new issues to process after filtering."
return
}
Info "`nIssues to process: $($issuesToProcess.Count)"
Info ("-" * 80)
foreach ($issue in $issuesToProcess) {
$prInfo = if ($existingPRs.ContainsKey($issue.IssueNumber)) {
$state = $existingPRs[$issue.IssueNumber].State
" [has $state PR #$($existingPRs[$issue.IssueNumber].PRNumber)]"
} else { "" }
Info ("#{0,-6} [F:{1}, C:{2}, E:{3}d]{4}" -f $issue.IssueNumber, $issue.FeasibilityScore, $issue.ClarityScore, $issue.EffortDays, $prInfo)
}
Info ("-" * 80)
if ($DryRun) {
Warn "`nDry run mode - showing what would be done:"
Info " 1. Create worktrees for $($issuesToProcess.Count) issues (parallel)"
Info " 2. Run Copilot auto-fix in each worktree (parallel)"
Info " 3. Commit and create PRs (parallel)"
Info " 4. Run PR review workflow (parallel)"
return
}
# Confirm
if (-not $Force) {
$confirm = Read-Host "`nProceed with full cycle for $($issuesToProcess.Count) issues? (y/N)"
if ($confirm -notmatch '^[yY]') {
Info "Cancelled."
return
}
}
# Track results
$results = @{
FixSucceeded = [System.Collections.Concurrent.ConcurrentBag[object]]::new()
FixFailed = [System.Collections.Concurrent.ConcurrentBag[object]]::new()
PRCreated = [System.Collections.Concurrent.ConcurrentBag[object]]::new()
PRFailed = [System.Collections.Concurrent.ConcurrentBag[object]]::new()
PRSkipped = [System.Collections.Concurrent.ConcurrentBag[object]]::new()
ReviewSucceeded = [System.Collections.Concurrent.ConcurrentBag[object]]::new()
ReviewFailed = [System.Collections.Concurrent.ConcurrentBag[object]]::new()
}
# ========================================
# PHASE 1: Create worktrees and fix issues (PARALLEL)
# ========================================
Info "`n" + ("=" * 60)
Info "PHASE 1: Auto-Fix Issues (Parallel)"
Info ("=" * 60)
$issuesNeedingFix = $issuesToProcess | Where-Object { -not $existingPRs.ContainsKey($_.IssueNumber) }
$issuesWithPR = $issuesToProcess | Where-Object { $existingPRs.ContainsKey($_.IssueNumber) }
Info "Issues needing fix: $($issuesNeedingFix.Count)"
Info "Issues with existing PR (skip to review): $($issuesWithPR.Count)"
if ($issuesNeedingFix.Count -gt 0) {
$issuesNeedingFix | ForEach-Object -ThrottleLimit $FixThrottleLimit -Parallel {
$issue = $_
$issueNum = $issue.IssueNumber
$issueFixScript = $using:issueFixScript
$CLIType = $using:CLIType
$results = $using:results
try {
Write-Host "[Issue #$issueNum] Starting auto-fix..." -ForegroundColor Cyan
& $issueFixScript -IssueNumber $issueNum -CLIType $CLIType -Force 2>&1 | Out-Null
$results.FixSucceeded.Add($issueNum)
Write-Host "[Issue #$issueNum] ✓ Fix completed" -ForegroundColor Green
}
catch {
$results.FixFailed.Add(@{ IssueNumber = $issueNum; Error = $_.Exception.Message })
Write-Host "[Issue #$issueNum] ✗ Fix failed: $($_.Exception.Message)" -ForegroundColor Red
}
}
}
Info "`nPhase 1 complete: $($results.FixSucceeded.Count) succeeded, $($results.FixFailed.Count) failed"
# ========================================
# PHASE 2: Commit and create PRs (PARALLEL)
# ========================================
Info "`n" + ("=" * 60)
Info "PHASE 2: Submit PRs (Parallel)"
Info ("=" * 60)
$fixedIssues = $results.FixSucceeded.ToArray()
if ($fixedIssues.Count -gt 0) {
$fixedIssues | ForEach-Object -ThrottleLimit $PRThrottleLimit -Parallel {
$issueNum = $_
$submitPRScript = $using:submitPRScript
$CLIType = $using:CLIType
$results = $using:results
try {
Write-Host "[Issue #$issueNum] Creating PR..." -ForegroundColor Cyan
$submitResult = & $submitPRScript -IssueNumbers $issueNum -CLIType $CLIType -Force 2>&1
# Parse output to find PR URL
$prUrl = $null
$prNum = 0
if ($submitResult -match 'https://github.com/[^/]+/[^/]+/pull/(\d+)') {
$prUrl = $Matches[0]
$prNum = [int]$Matches[1]
}
if ($prNum -gt 0) {
$results.PRCreated.Add(@{ IssueNumber = $issueNum; PRNumber = $prNum; PRUrl = $prUrl })
Write-Host "[Issue #$issueNum] ✓ PR #$prNum created" -ForegroundColor Green
} else {
# Check if PR was already created
$existingPr = gh pr list --head "issue/$issueNum" --state open --json number,url 2>$null | ConvertFrom-Json
if ($existingPr -and $existingPr.Count -gt 0) {
$results.PRSkipped.Add(@{ IssueNumber = $issueNum; PRNumber = $existingPr[0].number; PRUrl = $existingPr[0].url; Reason = "Already exists" })
Write-Host "[Issue #$issueNum] PR already exists: #$($existingPr[0].number)" -ForegroundColor Yellow
} else {
$results.PRFailed.Add(@{ IssueNumber = $issueNum; Error = "No PR created" })
Write-Host "[Issue #$issueNum] ✗ PR creation failed" -ForegroundColor Red
}
}
}
catch {
$results.PRFailed.Add(@{ IssueNumber = $issueNum; Error = $_.Exception.Message })
Write-Host "[Issue #$issueNum] ✗ PR failed: $($_.Exception.Message)" -ForegroundColor Red
}
}
}
Info "`nPhase 2 complete: $($results.PRCreated.Count) created, $($results.PRSkipped.Count) skipped, $($results.PRFailed.Count) failed"
# ========================================
# PHASE 3: Review PRs (PARALLEL)
# ========================================
Info "`n" + ("=" * 60)
Info "PHASE 3: Review PRs (Parallel)"
Info ("=" * 60)
# Collect all PRs to review (newly created + existing)
$prsToReview = @()
foreach ($pr in $results.PRCreated.ToArray()) {
$prsToReview += @{ IssueNumber = $pr.IssueNumber; PRNumber = $pr.PRNumber }
}
foreach ($pr in $results.PRSkipped.ToArray()) {
$prsToReview += @{ IssueNumber = $pr.IssueNumber; PRNumber = $pr.PRNumber }
}
foreach ($issue in $issuesWithPR) {
$prInfo = $existingPRs[$issue.IssueNumber]
$prsToReview += @{ IssueNumber = $issue.IssueNumber; PRNumber = $prInfo.PRNumber }
}
Info "PRs to review: $($prsToReview.Count)"
if ($prsToReview.Count -gt 0) {
$prsToReview | ForEach-Object -ThrottleLimit $ReviewThrottleLimit -Parallel {
$pr = $_
$issueNum = $pr.IssueNumber
$prNum = $pr.PRNumber
$prReviewScript = $using:prReviewScript
$CLIType = $using:CLIType
$results = $using:results
try {
Write-Host "[PR #$prNum] Starting review workflow..." -ForegroundColor Cyan
& $prReviewScript -PRNumbers $prNum -CLIType $CLIType -Force 2>&1 | Out-Null
$results.ReviewSucceeded.Add(@{ IssueNumber = $issueNum; PRNumber = $prNum })
Write-Host "[PR #$prNum] ✓ Review completed" -ForegroundColor Green
}
catch {
$results.ReviewFailed.Add(@{ IssueNumber = $issueNum; PRNumber = $prNum; Error = $_.Exception.Message })
Write-Host "[PR #$prNum] ✗ Review failed: $($_.Exception.Message)" -ForegroundColor Red
}
}
}
Info "`nPhase 3 complete: $($results.ReviewSucceeded.Count) succeeded, $($results.ReviewFailed.Count) failed"
# Final Summary
$duration = (Get-Date) - $startTime
Info "`n" + ("=" * 80)
Info "FULL CYCLE COMPLETE"
Info ("=" * 80)
Info "Duration: $($duration.ToString('hh\:mm\:ss'))"
Info ""
Info "Issues processed: $($issuesToProcess.Count)"
Success "Fixes succeeded: $($results.FixSucceeded.Count)"
if ($results.FixFailed.Count -gt 0) {
Err "Fixes failed: $($results.FixFailed.Count)"
}
Success "PRs created: $($results.PRCreated.Count)"
if ($results.PRSkipped.Count -gt 0) {
Warn "PRs skipped: $($results.PRSkipped.Count) (already existed)"
}
if ($results.PRFailed.Count -gt 0) {
Err "PRs failed: $($results.PRFailed.Count)"
}
Success "Reviews completed: $($results.ReviewSucceeded.Count)"
if ($results.ReviewFailed.Count -gt 0) {
Err "Reviews failed: $($results.ReviewFailed.Count)"
}
Info ""
Info "Summary by issue:"
foreach ($issue in $issuesToProcess) {
$issueNum = $issue.IssueNumber
$prInfo = $results.PRCreated.ToArray() | Where-Object { $_.IssueNumber -eq $issueNum } | Select-Object -First 1
if (-not $prInfo) {
$prInfo = $results.PRSkipped.ToArray() | Where-Object { $_.IssueNumber -eq $issueNum } | Select-Object -First 1
}
if (-not $prInfo -and $existingPRs.ContainsKey($issueNum)) {
$prInfo = @{ PRNumber = $existingPRs[$issueNum].PRNumber }
}
$prNum = if ($prInfo) { "PR #$($prInfo.PRNumber)" } else { "No PR" }
$fixStatus = if ($results.FixSucceeded.ToArray() -contains $issueNum) { "" } elseif ($results.FixFailed.ToArray().IssueNumber -contains $issueNum) { "" } else { "-" }
$reviewStatus = if ($results.ReviewSucceeded.ToArray().IssueNumber -contains $issueNum -or $results.ReviewSucceeded.ToArray().PRNumber -contains $prInfo.PRNumber) { "" } else { "-" }
Info (" Issue #{0,-6} [{1}Fix] [{2}Review] -> {3}" -f $issueNum, $fixStatus, $reviewStatus, $prNum)
}
Info ("=" * 80)
return @{
FixSucceeded = $results.FixSucceeded.ToArray()
FixFailed = $results.FixFailed.ToArray()
PRCreated = $results.PRCreated.ToArray()
PRSkipped = $results.PRSkipped.ToArray()
PRFailed = $results.PRFailed.ToArray()
ReviewSucceeded = $results.ReviewSucceeded.ToArray()
ReviewFailed = $results.ReviewFailed.ToArray()
}
}
catch {
Err "Error: $($_.Exception.Message)"
exit 1
}
#endregion

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,121 +0,0 @@
---
name: pr-review
description: Comprehensive pull request review with multi-step analysis and comment posting. Use when asked to review a PR, analyze pull request changes, check PR for issues, post review comments, validate PR quality, run code review on a PR, or audit pull request. Generates 13 review step files covering functionality, security, performance, accessibility, and more.
license: Complete terms in LICENSE.txt
---
# PR Review Skill
Perform comprehensive pull request reviews with multi-step analysis covering functionality, security, performance, accessibility, localization, and more.
## Skill Contents
This skill is **self-contained** with all required resources:
```
.github/skills/pr-review/
├── SKILL.md # This file
├── LICENSE.txt # MIT License
├── scripts/
│ ├── Start-PRReviewWorkflow.ps1 # Main review script
│ ├── Get-GitHubPrFilePatch.ps1 # Fetch PR file diffs
│ ├── Get-GitHubRawFile.ps1 # Download repo files
│ ├── Get-PrIncrementalChanges.ps1 # Detect incremental changes
│ └── Test-IncrementalReview.ps1 # Test incremental detection
└── references/
├── review-pr.prompt.md # Full review prompt
└── fix-pr-active-comments.prompt.md # Comment fix prompt
```
## Output Directory
All generated artifacts are placed under `Generated Files/prReview/<pr-number>/` at the repository root (gitignored).
```
Generated Files/prReview/
└── <pr-number>/
├── 00-OVERVIEW.md # Summary with all findings
├── 01-functionality.md # Functional correctness
├── 02-compatibility.md # Breaking changes, versioning
├── 03-performance.md # Performance implications
├── 04-accessibility.md # A11y compliance
├── 05-security.md # Security concerns
├── 06-localization.md # L10n readiness
├── 07-globalization.md # G11n considerations
├── 08-extensibility.md # API/extension points
├── 09-solid-design.md # SOLID principles
├── 10-repo-patterns.md # PowerToys conventions
├── 11-docs-automation.md # Documentation coverage
├── 12-code-comments.md # Code comment quality
└── 13-copilot-guidance.md # (if applicable)
```
## When to Use This Skill
- Review a specific pull request
- Analyze PR changes for quality issues
- Post review comments on a PR
- Validate PR against PowerToys standards
- Run comprehensive code review
## Prerequisites
- GitHub CLI (`gh`) installed and authenticated
- PowerShell 7+ for running scripts
- GitHub MCP configured (for posting comments)
## Required Variables
⚠️ **Before starting**, confirm `{{PRNumber}}` with the user. If not provided, **ASK**: "What PR number should I review?"
| Variable | Description | Example |
|----------|-------------|---------|
| `{{PRNumber}}` | Pull request number to review | `45234` |
## Workflow
### Step 1: Run PR Review
Execute the review workflow (use paths relative to this skill folder):
```powershell
# From repo root
.github/skills/pr-review/scripts/Start-PRReviewWorkflow.ps1 -PRNumbers {{PRNumber}} -CLIType copilot
```
This will:
1. Optionally assign GitHub Copilot as reviewer
2. Fetch PR diff and changed files
3. Generate 13 review step files
4. Post findings as review comments
### Step 2: Review Output
Check the generated files at `Generated Files/prReview/{{PRNumber}}/`
## CLI Options
| Parameter | Description | Default |
|-----------|-------------|---------|
| `-PRNumbers` | PR number(s) to review | From worktrees |
| `-CLIType` | AI CLI to use: `copilot` or `claude` | `copilot` |
| `-MinSeverity` | Min severity to post: `high`, `medium`, `low`, `info` | `medium` |
| `-SkipAssign` | Skip assigning Copilot as reviewer | `false` |
| `-SkipReview` | Skip the review step | `false` |
| `-SkipFix` | Skip the fix step | `false` |
| `-MaxParallel` | Maximum parallel jobs | `3` |
| `-Force` | Skip confirmation prompts | `false` |
## AI Prompt References
For manual AI invocation, prompts are at:
- `references/review-pr.prompt.md` - Full review instructions
- `references/fix-pr-active-comments.prompt.md` - Comment fix instructions
## Troubleshooting
| Problem | Solution |
|---------|----------|
| PR not found | Verify PR number: `gh pr view {{PRNumber}}` |
| Review incomplete | Check `_copilot-review.log` for errors |
| Comments not posted | Ensure GitHub MCP is configured |

View File

@@ -1,70 +0,0 @@
---
description: 'Fix active pull request comments with scoped changes'
name: 'fix-pr-active-comments'
agent: 'agent'
argument-hint: 'PR number or active PR URL'
---
# Fix Active PR Comments
## Mission
Resolve active pull request comments by applying only simple fixes. For complex refactors, write a plan instead of changing code.
## Scope & Preconditions
- You must have an active pull request context or a provided PR number.
- Only implement simple changes. Do not implement large refactors.
- If required context is missing, request it and stop.
## Inputs
- Required: ${input:pr_number:PR number or URL}
- Optional: ${input:comment_scope:files or areas to focus on}
- Optional: ${input:fixing_guidelines:additional fixing guidelines from the user}
## Workflow
1. Locate all active (unresolved) PR review comments for the given PR.
2. For each comment, classify the change scope:
- Simple change: limited edits, localized fix, low risk, no broad redesign.
- Large refactor: multi-file redesign, architecture change, or risky behavior change.
3. For each large refactor request:
- Do not modify code.
- Write a planning document to Generated Files/prReview/${input:pr_number}/fixPlan/.
4. For each simple change request:
- Implement the fix with minimal edits.
- Run quick checks if needed.
- Commit and push the change.
5. For comments that seem invalid, unclear, or not applicable (even if simple):
- Do not change code.
- Add the item to a summary table in Generated Files/prReview/${input:pr_number}/fixPlan/overview.md.
- Consult back to the end user in a friendly, polite tone.
6. Respond to each comment that you fixed:
- Reply in the active conversation.
- Use a polite or friendly tone.
- Keep the response under 200 words.
- Resolve the comment after replying.
## Output Expectations
- Simple fixes: code changes committed and pushed.
- Large refactors: a plan file saved to Generated Files/prReview/${input:pr_number}/fixPlan/.
- Invalid or unclear comments: captured in Generated Files/prReview/${input:pr_number}/fixPlan/overview.md.
- Each fixed comment has a reply under 200 words and is resolved.
## Plan File Template
Use this template for each large refactor item:
# Fix Plan: <short title>
## Context
- Comment link:
- Impacted areas:
## Overview Table Template
Use this table in Generated Files/prReview/${input:pr_number}/fixPlan/overview.md:
| Comment link | Summary | Reason not applied | Suggested follow-up |
| --- | --- | --- | --- |
| | | | |
## Quality Assurance
- Verify plan file path exists.
- Ensure no code changes were made for large refactor items.
- Confirm replies are under 200 words and comments are resolved.

View File

@@ -1,9 +0,0 @@
{
"mcpServers": {
"github-artifacts": {
"command": "cmd",
"args": ["/c", "for /f %i in ('git rev-parse --show-toplevel') do node %i/tools/mcp/github-artifacts/launch.js"],
"tools": ["*"]
}
}
}

View File

@@ -1,198 +0,0 @@
---
agent: 'agent'
description: 'Perform a comprehensive PR review with per-step Markdown and machine-readable outputs'
---
# Review Pull Request
**Goal**: Given `{{pr_number}}`, run a *one-topic-per-step* review. Write files to `Generated Files/prReview/{{pr_number}}/` (replace `{{pr_number}}` with the integer). Emit machinereadable blocks for a GitHub MCP to post review comments.
## PR selection
Resolve the target PR using these fallbacks in order:
1. Parse the invocation text for an explicit identifier (first integer following patterns such as a leading hash and digits or the text `PR:` followed by digits).
2. If no PR is found yet, locate the newest `Generated Files/prReview/_batch/batch-overview-*.md` file (highest timestamp in filename, fallback newest mtime) and take the first entry in its `## PRs` list whose review folder is missing `00-OVERVIEW.md` or contains `__error.flag`.
3. If the batch file has no pending PRs, query assignments with `gh pr list --assignee @me --state open --json number,updatedAt --limit 20` and pick the most recently updated PR that does not already have a completed review folder.
4. If still unknown, run `gh pr view --json number` in the current branch and use that result when it is unambiguous.
5. If every step above fails, prompt the user for a PR number before proceeding.
## Fetch PR data with `gh`
- `gh pr view {{pr_number}} --json number,baseRefName,headRefName,baseRefOid,headRefOid,changedFiles,files`
- `gh api repos/:owner/:repo/pulls/{{pr_number}}/files?per_page=250` # patches for line mapping
### Incremental review workflow
1. **Check for existing review**: Read `Generated Files/prReview/{{pr_number}}/00-OVERVIEW.md`
2. **Extract state**: Parse `Last reviewed SHA:` from review metadata section
3. **Detect changes**: Run `Get-PrIncrementalChanges.ps1 -PullRequestNumber {{pr_number}} -LastReviewedCommitSha {{sha}}`
4. **Analyze result**:
- `NeedFullReview: true` → Review all files in the PR
- `NeedFullReview: false` and `IsIncremental: true` → Review only files in `ChangedFiles` array
- `ChangedFiles` is empty → No changes, skip review (update iteration history with "No changes since last review")
5. **Apply smart filtering**: Use the file patterns in smart step filtering table to skip irrelevant steps
6. **Update metadata**: After completing review, save current `headRefOid` as `Last reviewed SHA:` in `00-OVERVIEW.md`
### Reusable PowerShell scripts
Scripts live in `.github/review-tools/` to avoid repeated manual approvals during PR reviews:
| Script | Usage |
| --- | --- |
| `.github/review-tools/Get-GitHubRawFile.ps1` | Download a repository file at a given ref, optionally with line numbers. |
| `.github/review-tools/Get-GitHubPrFilePatch.ps1` | Fetch the unified diff for a specific file within a pull request via `gh api`. |
| `.github/review-tools/Get-PrIncrementalChanges.ps1` | Compare last reviewed SHA with current PR head to identify incremental changes. Returns JSON with changed files, new commits, and whether full review is needed. |
| `.github/review-tools/Test-IncrementalReview.ps1` | Test helper to preview incremental review detection for a PR. Use before running full review to see what changed. |
Always prefer these scripts (or new ones added under `.github/review-tools/`) over raw `gh api` or similar shell commands so the review flow does not trigger interactive approval prompts.
## Output files
Folder: `Generated Files/prReview/{{pr_number}}/`
Files: `00-OVERVIEW.md`, `01-functionality.md`, `02-compatibility.md`, `03-performance.md`, `04-accessibility.md`, `05-security.md`, `06-localization.md`, `07-globalization.md`, `08-extensibility.md`, `09-solid-design.md`, `10-repo-patterns.md`, `11-docs-automation.md`, `12-code-comments.md`, `13-copilot-guidance.md` *(only if guidance md exists).*
- **Write-after-step rule:** Immediately after completing each TODO step, persist that step's markdown file before proceeding to the next. Generate `00-OVERVIEW.md` only after every step file has been refreshed for the current run.
## Iteration management
- Determine the current review iteration by reading `00-OVERVIEW.md` (look for `Review iteration:`). If missing, assume iteration `1`.
- Extract the last reviewed SHA from `00-OVERVIEW.md` (look for `Last reviewed SHA:` in the review metadata section). If missing, this is iteration 1.
- **Incremental review detection**:
1. Call `.github/review-tools/Get-PrIncrementalChanges.ps1 -PullRequestNumber {{pr_number}} -LastReviewedCommitSha {{last_sha}}` to get delta analysis.
2. Parse the JSON result to determine if incremental review is possible (`IsIncremental: true`, `NeedFullReview: false`).
3. If force-push detected or first review, proceed with full review of all changed files.
4. If incremental, review only the files listed in `ChangedFiles` array and apply smart step filtering (see below).
- Increment the iteration for each review run and propagate the new value to all step files and the overview.
- Preserve prior iteration notes by keeping/expanding an `## Iteration history` section in each markdown file, appending the newest summary under `### Iteration <N>`.
- Summaries should capture key deltas since the previous iteration so reruns can pick up context quickly.
- **After review completion**, update `Last reviewed SHA:` in `00-OVERVIEW.md` with the current `headRefOid` and update the timestamp.
### Smart step filtering (incremental reviews only)
When performing incremental review, skip steps that are irrelevant based on changed file types:
| File pattern | Required steps | Skippable steps |
| --- | --- | --- |
| `**/*.cs`, `**/*.cpp`, `**/*.h` | Functionality, Compatibility, Performance, Security, SOLID, Repo patterns, Code comments | (depends on files) |
| `**/*.resx`, `**/Resources/*.xaml` | Localization, Globalization | Most others |
| `**/*.md` (docs) | Docs & automation | Most others (unless copilot guidance) |
| `**/*copilot*.md`, `.github/prompts/*.md` | Copilot guidance, Docs & automation | Most others |
| `**/*.csproj`, `**/*.vcxproj`, `**/packages.config` | Compatibility, Security, Repo patterns | Localization, Globalization, Accessibility |
| `**/UI/**`, `**/*View.xaml` | Accessibility, Localization | Performance (unless perf-sensitive controls) |
**Default**: If uncertain or files span multiple categories, run all applicable steps. When in doubt, be conservative and review more rather than less.
## TODO steps (one concern each)
1) Functionality
2) Compatibility
3) Performance
4) Accessibility
5) Security
6) Localization
7) Globalization
8) Extensibility
9) SOLID principles
10) Repo patterns
11) Docs & automation coverage for the changes
12) Code comments
13) Copilot guidance (conditional): if changed folders contain `*copilot*.md` or `.github/prompts/*.md`, review diffs **against** that guidance and write `13-copilot-guidance.md` (omit if none).
## Per-step file template (use verbatim)
```md
# <STEP TITLE>
**PR:** (populate with PR identifier) — Base:<baseRefName> Head:<headRefName>
**Review iteration:** ITERATION
## Iteration history
- Maintain subsections titled `### Iteration N` in reverse chronological order (append the latest at the top) with 24 bullet highlights.
### Iteration ITERATION
- <Latest key point 1>
- <Latest key point 2>
## Checks executed
- List the concrete checks for *this step only* (510 bullets).
## Findings
(If none, write **None**. Defaults have one or more blocks:)
```mcp-review-comment
{"file":"relative/path.ext","start_line":123,"end_line":125,"severity":"high|medium|low|info","tags":["<step-slug>","pr-tag-here"],"related_files":["optional/other/file1"],"body":"Problem → Why it matters → Concrete fix. If spans multiple files, name them here."}
```
Use the second tag to encode the PR number.
```
## Overview file (`00-OVERVIEW.md`) template
```md
# PR Review Overview — (populate with PR identifier)
**Review iteration:** ITERATION
**Changed files:** <n> | **High severity issues:** <count>
## Review metadata
**Last reviewed SHA:** <headRefOid from gh pr view>
**Last review timestamp:** <ISO8601 timestamp>
**Review mode:** <Full|Incremental (N files changed since iteration X)>
**Base ref:** <baseRefName>
**Head ref:** <headRefName>
## Step results
Write lines like: `01 Functionality — <OK|Issues|Skipped> (see 01-functionality.md)` … through step 13.
Mark steps as "Skipped" when using incremental review smart filtering.
## Iteration history
- Maintain subsections titled `### Iteration N` mirroring the per-step convention with concise deltas and cross-links to the relevant step files.
- For incremental reviews, list the specific files that changed and which commits were added.
```
## Line numbers & multifile issues
- Map headside lines from `patch` hunks (`@@ -a,b +c,d @@` → new lines `+c..+c+d-1`).
- For crossfile issues: set the primary `"file"`, list others in `"related_files"`, and name them in `"body"`.
## Posting (for MCP)
- Parse all ```mcp-review-comment``` blocks across step files and post as PR review comments.
- If posting isnt available, still write all files.
## Constraint
Read/analyze only; don't modify code. Keep comments small, specific, and fixoriented.
**Testing**: Use `.github/review-tools/Test-IncrementalReview.ps1 -PullRequestNumber 42374` to preview incremental detection before running full review.
## Scratch cache for large PRs
Create a local scratch workspace to progressively summarize diffs and reload state across runs.
### Paths
- Root: `Generated Files/prReview/{{pr_number}}/__tmp/`
- Files:
- `index.jsonl` — append-only JSON Lines index of artifacts.
- `todo-queue.json` — pending items (files/chunks/steps).
- `rollup-<step>-v<N>.md` — iterative per-step aggregates.
- `file-<hash>.txt` — optional saved chunk text (when needed).
### JSON schema (per line in `index.jsonl`)
```json
{"type":"chunk|summary|issue|crosslink",
"path":"relative/file.ext","chunk_id":"f-12","step":"functionality|compatibility|...",
"base_sha":"...", "head_sha":"...", "range":[start,end], "version":1,
"notes":"short text or key:value map", "created_utc":"ISO8601"}
```
### Phases (stateful; resume-safe)
0. **Discover** PR + SHAs: `gh pr view <PR> --json baseRefName,headRefName,baseRefOid,headRefOid,files`.
1. **Chunk** each changed file (head): split into ~300600 LOC or ~4k chars; stable `chunk_id` = hash(path+start).
- Save `chunk` records. Optionally write `file-<hash>.txt` for expensive chunks.
2. **Summarize** per chunk: intent, APIs, risks per TODO step; emit `summary` records (≤600 tokens each).
3. **Issues**: convert findings to machine-readable blocks and emit `issue` records (later rendered to step MD).
4. **Rollups**: build/update `rollup-<step>-v<N>.md` from `summary`+`issue`. Keep prior versions.
5. **Finalize**: write per-step files + `00-OVERVIEW.md` from rollups. Post comments via MCP if available.
### Re-use & token limits
- Always **reload** `index.jsonl` first; skip chunks with same `head_sha` and `range`.
- **Incremental review optimization**: When `Get-PrIncrementalChanges.ps1` returns a subset of changed files, load only chunks from those files. Reuse existing chunks/summaries for unchanged files.
- Prefer re-summarizing only changed chunks; merge chunk summaries → file summaries → step rollups.
- When context is tight, load only the minimal chunk text (or its saved `file-<hash>.txt`) needed for a comment.
### Original vs diff
- Fetch base content when needed: prefer `git show <baseRefName>:<path>`; fallback `gh api repos/:owner/:repo/contents/<path>?ref=<base_sha>` (base64).
- Use patch hunks from `gh api .../pulls/<PR>/files` to compute **head** line numbers.
### Queue-driven loop
- Seed `todo-queue.json` with all changed files.
- Process: chunk → summarize → detect issues → roll up.
- Append to `index.jsonl` after each step; never rewrite previous lines (append-only).
### Hygiene
- `__tmp/` is implementation detail; do not include in final artifacts.
- It is safe to delete to force a clean pass; the next run rebuilds it.

View File

@@ -1,79 +0,0 @@
<#
.SYNOPSIS
Retrieves the unified diff patch for a specific file in a GitHub pull request.
.DESCRIPTION
This script fetches the patch content (unified diff format) for a specified file
within a pull request. It uses the GitHub CLI (gh) to query the GitHub API and
retrieve file change information.
.PARAMETER PullRequestNumber
The pull request number to query.
.PARAMETER FilePath
The relative path to the file in the repository (e.g., "src/modules/main.cpp").
.PARAMETER RepositoryOwner
The GitHub repository owner. Defaults to "microsoft".
.PARAMETER RepositoryName
The GitHub repository name. Defaults to "PowerToys".
.EXAMPLE
.\Get-GitHubPrFilePatch.ps1 -PullRequestNumber 42374 -FilePath "src/modules/cmdpal/main.cpp"
Retrieves the patch for main.cpp in PR #42374.
.EXAMPLE
.\Get-GitHubPrFilePatch.ps1 -PullRequestNumber 42374 -FilePath "README.md" -RepositoryOwner "myorg" -RepositoryName "myrepo"
Retrieves the patch from a different repository.
.NOTES
Requires GitHub CLI (gh) to be installed and authenticated.
Run 'gh auth login' if not already authenticated.
.LINK
https://cli.github.com/
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, HelpMessage = "Pull request number")]
[int]$PullRequestNumber,
[Parameter(Mandatory = $true, HelpMessage = "Relative path to the file in the repository")]
[string]$FilePath,
[Parameter(Mandatory = $false, HelpMessage = "Repository owner")]
[string]$RepositoryOwner = "microsoft",
[Parameter(Mandatory = $false, HelpMessage = "Repository name")]
[string]$RepositoryName = "PowerToys"
)
# Construct GitHub API path for pull request files
$apiPath = "repos/$RepositoryOwner/$RepositoryName/pulls/$PullRequestNumber/files?per_page=250"
# Query GitHub API to get all files in the pull request
try {
$pullRequestFiles = gh api $apiPath | ConvertFrom-Json
} catch {
Write-Error "Failed to query GitHub API for PR #$PullRequestNumber. Ensure gh CLI is authenticated. Details: $_"
exit 1
}
# Find the matching file in the pull request
$matchedFile = $pullRequestFiles | Where-Object { $_.filename -eq $FilePath }
if (-not $matchedFile) {
Write-Error "File '$FilePath' not found in PR #$PullRequestNumber."
exit 1
}
# Check if patch content exists
if (-not $matchedFile.patch) {
Write-Warning "File '$FilePath' has no patch content (possibly binary or too large)."
return
}
# Output the patch content
$matchedFile.patch

View File

@@ -1,91 +0,0 @@
<#
.SYNOPSIS
Downloads and displays the content of a file from a GitHub repository at a specific git reference.
.DESCRIPTION
This script fetches the raw content of a file from a GitHub repository using GitHub's raw content API.
It can optionally display line numbers and supports any valid git reference (branch, tag, or commit SHA).
.PARAMETER FilePath
The relative path to the file in the repository (e.g., "src/modules/main.cpp").
.PARAMETER GitReference
The git reference (branch name, tag, or commit SHA) to fetch the file from. Defaults to "main".
.PARAMETER RepositoryOwner
The GitHub repository owner. Defaults to "microsoft".
.PARAMETER RepositoryName
The GitHub repository name. Defaults to "PowerToys".
.PARAMETER ShowLineNumbers
When specified, displays line numbers before each line of content.
.PARAMETER StartLineNumber
The starting line number to use when ShowLineNumbers is enabled. Defaults to 1.
.EXAMPLE
.\Get-GitHubRawFile.ps1 -FilePath "README.md" -GitReference "main"
Downloads and displays the README.md file from the main branch.
.EXAMPLE
.\Get-GitHubRawFile.ps1 -FilePath "src/runner/main.cpp" -GitReference "dev/feature-branch" -ShowLineNumbers
Downloads main.cpp from a feature branch and displays it with line numbers.
.EXAMPLE
.\Get-GitHubRawFile.ps1 -FilePath "LICENSE" -GitReference "abc123def" -ShowLineNumbers -StartLineNumber 10
Downloads the LICENSE file from a specific commit and displays it with line numbers starting at 10.
.NOTES
Requires internet connectivity to access GitHub's raw content API.
Does not require GitHub CLI authentication for public repositories.
.LINK
https://docs.github.com/en/rest/repos/contents
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, HelpMessage = "Relative path to the file in the repository")]
[string]$FilePath,
[Parameter(Mandatory = $false, HelpMessage = "Git reference (branch, tag, or commit SHA)")]
[string]$GitReference = "main",
[Parameter(Mandatory = $false, HelpMessage = "Repository owner")]
[string]$RepositoryOwner = "microsoft",
[Parameter(Mandatory = $false, HelpMessage = "Repository name")]
[string]$RepositoryName = "PowerToys",
[Parameter(Mandatory = $false, HelpMessage = "Display line numbers before each line")]
[switch]$ShowLineNumbers,
[Parameter(Mandatory = $false, HelpMessage = "Starting line number for display")]
[int]$StartLineNumber = 1
)
# Construct the raw content URL
$rawContentUrl = "https://raw.githubusercontent.com/$RepositoryOwner/$RepositoryName/$GitReference/$FilePath"
# Fetch the file content from GitHub
try {
$response = Invoke-WebRequest -UseBasicParsing -Uri $rawContentUrl
} catch {
Write-Error "Failed to fetch file from $rawContentUrl. Details: $_"
exit 1
}
# Split content into individual lines
$contentLines = $response.Content -split "`n"
# Display the content with or without line numbers
if ($ShowLineNumbers) {
$currentLineNumber = $StartLineNumber
foreach ($line in $contentLines) {
Write-Output ("{0:d4}: {1}" -f $currentLineNumber, $line)
$currentLineNumber++
}
} else {
$contentLines | ForEach-Object { Write-Output $_ }
}

View File

@@ -1,173 +0,0 @@
<#
.SYNOPSIS
Detects changes between the last reviewed commit and current head of a pull request.
.DESCRIPTION
This script compares a previously reviewed commit SHA with the current head of a pull request
to determine what has changed. It helps enable incremental reviews by identifying new commits
and modified files since the last review iteration.
The script handles several scenarios:
- First review (no previous SHA provided)
- No changes (current SHA matches last reviewed SHA)
- Force-push detected (last reviewed SHA no longer in history)
- Incremental changes (new commits added since last review)
.PARAMETER PullRequestNumber
The pull request number to analyze.
.PARAMETER LastReviewedCommitSha
The commit SHA that was last reviewed. If omitted, this is treated as a first review.
.PARAMETER RepositoryOwner
The GitHub repository owner. Defaults to "microsoft".
.PARAMETER RepositoryName
The GitHub repository name. Defaults to "PowerToys".
.OUTPUTS
JSON object containing:
- PullRequestNumber: The PR number being analyzed
- CurrentHeadSha: The current head commit SHA
- LastReviewedSha: The last reviewed commit SHA (if provided)
- BaseRefName: Base branch name
- HeadRefName: Head branch name
- IsIncremental: Boolean indicating if incremental review is possible
- NeedFullReview: Boolean indicating if a full review is required
- ChangedFiles: Array of files that changed (filename, status, additions, deletions)
- NewCommits: Array of commits added since last review (sha, message, author, date)
- Summary: Human-readable description of changes
.EXAMPLE
.\Get-PrIncrementalChanges.ps1 -PullRequestNumber 42374
Analyzes PR #42374 with no previous review (first review scenario).
.EXAMPLE
.\Get-PrIncrementalChanges.ps1 -PullRequestNumber 42374 -LastReviewedCommitSha "abc123def456"
Compares current PR state against the last reviewed commit to identify incremental changes.
.EXAMPLE
$changes = .\Get-PrIncrementalChanges.ps1 -PullRequestNumber 42374 -LastReviewedCommitSha "abc123" | ConvertFrom-Json
if ($changes.IsIncremental) { Write-Host "Can perform incremental review" }
Captures the output as a PowerShell object for further processing.
.NOTES
Requires GitHub CLI (gh) to be installed and authenticated.
Run 'gh auth login' if not already authenticated.
.LINK
https://cli.github.com/
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, HelpMessage = "Pull request number")]
[int]$PullRequestNumber,
[Parameter(Mandatory = $false, HelpMessage = "Commit SHA that was last reviewed")]
[string]$LastReviewedCommitSha,
[Parameter(Mandatory = $false, HelpMessage = "Repository owner")]
[string]$RepositoryOwner = "microsoft",
[Parameter(Mandatory = $false, HelpMessage = "Repository name")]
[string]$RepositoryName = "PowerToys"
)
# Fetch current pull request state from GitHub
try {
$pullRequestData = gh pr view $PullRequestNumber --json headRefOid,headRefName,baseRefName,baseRefOid | ConvertFrom-Json
} catch {
Write-Error "Failed to fetch PR #$PullRequestNumber details. Details: $_"
exit 1
}
$currentHeadSha = $pullRequestData.headRefOid
$baseRefName = $pullRequestData.baseRefName
$headRefName = $pullRequestData.headRefName
# Initialize result object
$analysisResult = @{
PullRequestNumber = $PullRequestNumber
CurrentHeadSha = $currentHeadSha
BaseRefName = $baseRefName
HeadRefName = $headRefName
LastReviewedSha = $LastReviewedCommitSha
IsIncremental = $false
NeedFullReview = $true
ChangedFiles = @()
NewCommits = @()
Summary = ""
}
# Scenario 1: First review (no previous SHA provided)
if ([string]::IsNullOrWhiteSpace($LastReviewedCommitSha)) {
$analysisResult.Summary = "Initial review - no previous iteration found"
$analysisResult.NeedFullReview = $true
return $analysisResult | ConvertTo-Json -Depth 10
}
# Scenario 2: No changes since last review
if ($currentHeadSha -eq $LastReviewedCommitSha) {
$analysisResult.Summary = "No changes since last review (SHA: $currentHeadSha)"
$analysisResult.NeedFullReview = $false
$analysisResult.IsIncremental = $true
return $analysisResult | ConvertTo-Json -Depth 10
}
# Scenario 3: Check for force-push (last reviewed SHA no longer exists in history)
try {
$null = gh api "repos/$RepositoryOwner/$RepositoryName/commits/$LastReviewedCommitSha" 2>&1
if ($LASTEXITCODE -ne 0) {
# SHA not found - likely force-push or branch rewrite
$analysisResult.Summary = "Force-push detected - last reviewed SHA $LastReviewedCommitSha no longer exists. Full review required."
$analysisResult.NeedFullReview = $true
return $analysisResult | ConvertTo-Json -Depth 10
}
} catch {
$analysisResult.Summary = "Cannot verify last reviewed SHA $LastReviewedCommitSha - assuming force-push. Full review required."
$analysisResult.NeedFullReview = $true
return $analysisResult | ConvertTo-Json -Depth 10
}
# Scenario 4: Get incremental changes between last reviewed SHA and current head
try {
$compareApiPath = "repos/$RepositoryOwner/$RepositoryName/compare/$LastReviewedCommitSha...$currentHeadSha"
$comparisonData = gh api $compareApiPath | ConvertFrom-Json
# Extract new commits information
$analysisResult.NewCommits = $comparisonData.commits | ForEach-Object {
@{
Sha = $_.sha.Substring(0, 7)
Message = $_.commit.message.Split("`n")[0] # First line only
Author = $_.commit.author.name
Date = $_.commit.author.date
}
}
# Extract changed files information
$analysisResult.ChangedFiles = $comparisonData.files | ForEach-Object {
@{
Filename = $_.filename
Status = $_.status # added, modified, removed, renamed
Additions = $_.additions
Deletions = $_.deletions
Changes = $_.changes
}
}
$fileCount = $analysisResult.ChangedFiles.Count
$commitCount = $analysisResult.NewCommits.Count
$analysisResult.IsIncremental = $true
$analysisResult.NeedFullReview = $false
$analysisResult.Summary = "Incremental review: $commitCount new commit(s), $fileCount file(s) changed since SHA $($LastReviewedCommitSha.Substring(0, 7))"
} catch {
Write-Error "Failed to compare commits. Details: $_"
$analysisResult.Summary = "Error comparing commits - defaulting to full review"
$analysisResult.NeedFullReview = $true
}
# Return the analysis result as JSON
return $analysisResult | ConvertTo-Json -Depth 10

View File

@@ -1,18 +0,0 @@
# IssueReviewLib.ps1 - Minimal helpers for PR review workflow
# Part of the PowerToys GitHub Copilot/Claude Code issue review system
# This is a trimmed version - pr-review only needs console helpers and repo root
#region Console Output Helpers
function Info { param([string]$Message) Write-Host $Message -ForegroundColor Cyan }
function Warn { param([string]$Message) Write-Host $Message -ForegroundColor Yellow }
function Err { param([string]$Message) Write-Host $Message -ForegroundColor Red }
function Success { param([string]$Message) Write-Host $Message -ForegroundColor Green }
#endregion
#region Repository Helpers
function Get-RepoRoot {
$root = git rev-parse --show-toplevel 2>$null
if (-not $root) { throw 'Not inside a git repository.' }
return (Resolve-Path $root).Path
}
#endregion

View File

@@ -1,541 +0,0 @@
<#!
.SYNOPSIS
Review and fix PRs in parallel using GitHub Copilot and MCP.
.DESCRIPTION
For each PR (from worktrees or specified), runs in parallel:
1. Assigns GitHub Copilot as reviewer via GitHub MCP
2. Runs review-pr.prompt.md to generate review and post comments
3. Runs fix-pr-active-comments.prompt.md to fix issues
.PARAMETER PRNumbers
Array of PR numbers to process. If not specified, finds PRs from issue worktrees.
.PARAMETER SkipAssign
Skip assigning Copilot as reviewer.
.PARAMETER SkipReview
Skip the review step.
.PARAMETER SkipFix
Skip the fix step.
.PARAMETER MinSeverity
Minimum severity to post as PR comments: high, medium, low, info. Default: medium.
.PARAMETER MaxParallel
Maximum parallel jobs. Default: 3.
.PARAMETER DryRun
Show what would be done without executing.
.PARAMETER CLIType
AI CLI to use: copilot or claude. Default: copilot.
.EXAMPLE
# Process all PRs from issue worktrees
./Start-PRReviewWorkflow.ps1
.EXAMPLE
# Process specific PRs
./Start-PRReviewWorkflow.ps1 -PRNumbers 45234, 45235
.EXAMPLE
# Only review, don't fix
./Start-PRReviewWorkflow.ps1 -SkipFix
.EXAMPLE
# Dry run
./Start-PRReviewWorkflow.ps1 -DryRun
.NOTES
Prerequisites:
- GitHub CLI (gh) authenticated
- Copilot CLI installed
- GitHub MCP configured for posting comments
#>
[CmdletBinding()]
param(
[int[]]$PRNumbers,
[switch]$SkipAssign,
[switch]$SkipReview,
[switch]$SkipFix,
[ValidateSet('high', 'medium', 'low', 'info')]
[string]$MinSeverity = 'medium',
[int]$MaxParallel = 3,
[switch]$DryRun,
[ValidateSet('copilot', 'claude')]
[string]$CLIType = 'copilot',
[switch]$Force,
[switch]$Help
)
# Load libraries
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
. "$scriptDir/IssueReviewLib.ps1"
# Load worktree library
$repoRoot = Get-RepoRoot
$worktreeLib = Join-Path $repoRoot 'tools/build/WorktreeLib.ps1'
if (Test-Path $worktreeLib) {
. $worktreeLib
}
if ($Help) {
Get-Help $MyInvocation.MyCommand.Path -Full
return
}
function Get-PRsFromWorktrees {
<#
.SYNOPSIS
Get PR numbers from issue worktrees by checking for open PRs on each branch.
#>
$worktrees = Get-WorktreeEntries | Where-Object { $_.Branch -like 'issue/*' }
$prs = @()
foreach ($wt in $worktrees) {
$prInfo = gh pr list --head $wt.Branch --json number,url --state open 2>$null | ConvertFrom-Json
if ($prInfo -and $prInfo.Count -gt 0) {
$prs += @{
PRNumber = $prInfo[0].number
PRUrl = $prInfo[0].url
Branch = $wt.Branch
WorktreePath = $wt.Path
}
}
}
return $prs
}
function Invoke-AssignCopilotReviewer {
<#
.SYNOPSIS
Assign GitHub Copilot as a reviewer to the PR using GitHub MCP.
#>
param(
[Parameter(Mandatory)]
[int]$PRNumber,
[string]$CLIType = 'copilot',
[switch]$DryRun
)
if ($DryRun) {
Info " [DRY RUN] Would request Copilot review for PR #$PRNumber"
return $true
}
# Use a prompt that instructs Copilot to use GitHub MCP to assign Copilot as reviewer
$prompt = @"
Use the GitHub MCP to request a review from GitHub Copilot for PR #$PRNumber.
Steps:
1. Use the GitHub MCP tool to add "Copilot" as a reviewer to pull request #$PRNumber in the microsoft/PowerToys repository
2. This should add Copilot to the "Reviewers" section of the PR
If GitHub MCP is not available, report that and skip this step.
"@
# MCP config for github-artifacts tools (relative to repo root)
$mcpConfig = '@.github/skills/pr-review/references/mcp-config.json'
try {
Info " Requesting Copilot review via GitHub MCP..."
switch ($CLIType) {
'copilot' {
& copilot --additional-mcp-config $mcpConfig -p $prompt --yolo -s 2>&1 | Out-Null
}
'claude' {
& claude --print --dangerously-skip-permissions --prompt $prompt 2>&1 | Out-Null
}
}
return $true
}
catch {
Warn " Could not assign Copilot reviewer: $($_.Exception.Message)"
return $false
}
}
function Invoke-PRReview {
<#
.SYNOPSIS
Run review-pr.prompt.md using Copilot CLI.
#>
param(
[Parameter(Mandatory)]
[int]$PRNumber,
[string]$CLIType = 'copilot',
[string]$MinSeverity = 'medium',
[switch]$DryRun
)
# Simple prompt - let the prompt file define all the details
$prompt = @"
Follow exactly what at .github/prompts/review-pr.prompt.md to do with PR #$PRNumber.
Post findings with severity >= $MinSeverity as PR review comments via GitHub MCP.
"@
if ($DryRun) {
Info " [DRY RUN] Would run PR review for #$PRNumber"
return @{ Success = $true; ReviewPath = "Generated Files/prReview/$PRNumber" }
}
$reviewPath = Join-Path $repoRoot "Generated Files/prReview/$PRNumber"
# Ensure the review directory exists
if (-not (Test-Path $reviewPath)) {
New-Item -ItemType Directory -Path $reviewPath -Force | Out-Null
}
# MCP config for github-artifacts tools (relative to repo root)
$mcpConfig = '@.github/skills/pr-review/references/mcp-config.json'
Push-Location $repoRoot
try {
switch ($CLIType) {
'copilot' {
Info " Running Copilot review (this may take several minutes)..."
$output = & copilot --additional-mcp-config $mcpConfig -p $prompt --yolo 2>&1
# Log output for debugging
$logFile = Join-Path $reviewPath "_copilot-review.log"
$output | Out-File -FilePath $logFile -Force
}
'claude' {
Info " Running Claude review (this may take several minutes)..."
$output = & claude --print --dangerously-skip-permissions --prompt $prompt 2>&1
$logFile = Join-Path $reviewPath "_claude-review.log"
$output | Out-File -FilePath $logFile -Force
}
}
# Check if review files were created (at minimum, check for multiple step files)
$overviewPath = Join-Path $reviewPath '00-OVERVIEW.md'
$stepFiles = Get-ChildItem -Path $reviewPath -Filter "*.md" -ErrorAction SilentlyContinue
$stepCount = ($stepFiles | Where-Object { $_.Name -match '^\d{2}-' }).Count
if ($stepCount -ge 5) {
return @{ Success = $true; ReviewPath = $reviewPath; StepFilesCreated = $stepCount }
} elseif (Test-Path $overviewPath) {
Warn " Only overview created, step files may be incomplete ($stepCount step files)"
return @{ Success = $true; ReviewPath = $reviewPath; StepFilesCreated = $stepCount; Partial = $true }
} else {
return @{ Success = $false; Error = "Review files not created (found $stepCount step files)" }
}
}
catch {
return @{ Success = $false; Error = $_.Exception.Message }
}
finally {
Pop-Location
}
}
function Invoke-FixPRComments {
<#
.SYNOPSIS
Run fix-pr-active-comments.prompt.md to fix issues.
#>
param(
[Parameter(Mandatory)]
[int]$PRNumber,
[string]$WorktreePath,
[string]$CLIType = 'copilot',
[switch]$DryRun
)
# Simple prompt - let the prompt file define all the details
$prompt = "Follow .github/prompts/fix-pr-active-comments.prompt.md for PR #$PRNumber."
if ($DryRun) {
Info " [DRY RUN] Would fix PR comments for #$PRNumber"
return @{ Success = $true }
}
$workDir = if ($WorktreePath -and (Test-Path $WorktreePath)) { $WorktreePath } else { $repoRoot }
# MCP config for github-artifacts tools (relative to repo root)
$mcpConfig = '@.github/skills/pr-review/references/mcp-config.json'
Push-Location $workDir
try {
switch ($CLIType) {
'copilot' {
Info " Running Copilot to fix comments..."
$output = & copilot --additional-mcp-config $mcpConfig -p $prompt --yolo 2>&1
# Log output for debugging
$logPath = Join-Path $repoRoot "Generated Files/prReview/$PRNumber"
if (-not (Test-Path $logPath)) {
New-Item -ItemType Directory -Path $logPath -Force | Out-Null
}
$logFile = Join-Path $logPath "_copilot-fix.log"
$output | Out-File -FilePath $logFile -Force
}
'claude' {
Info " Running Claude to fix comments..."
$output = & claude --print --dangerously-skip-permissions --prompt $prompt 2>&1
$logPath = Join-Path $repoRoot "Generated Files/prReview/$PRNumber"
if (-not (Test-Path $logPath)) {
New-Item -ItemType Directory -Path $logPath -Force | Out-Null
}
$logFile = Join-Path $logPath "_claude-fix.log"
$output | Out-File -FilePath $logFile -Force
}
}
return @{ Success = $true }
}
catch {
return @{ Success = $false; Error = $_.Exception.Message }
}
finally {
Pop-Location
}
}
function Start-PRWorkflowJob {
<#
.SYNOPSIS
Process a single PR through the workflow.
#>
param(
[Parameter(Mandatory)]
[int]$PRNumber,
[string]$WorktreePath,
[string]$CLIType = 'copilot',
[string]$MinSeverity = 'medium',
[switch]$SkipAssign,
[switch]$SkipReview,
[switch]$SkipFix,
[switch]$DryRun
)
$result = @{
PRNumber = $PRNumber
AssignResult = $null
ReviewResult = $null
FixResult = $null
Success = $true
}
# Step 1: Assign Copilot as reviewer
if (-not $SkipAssign) {
Info " Step 1: Assigning Copilot reviewer..."
$result.AssignResult = Invoke-AssignCopilotReviewer -PRNumber $PRNumber -CLIType $CLIType -DryRun:$DryRun
if (-not $result.AssignResult) {
Warn " Assignment step had issues (continuing...)"
}
} else {
Info " Step 1: Skipped (assign)"
}
# Step 2: Run PR review
if (-not $SkipReview) {
Info " Step 2: Running PR review..."
$result.ReviewResult = Invoke-PRReview -PRNumber $PRNumber -CLIType $CLIType -MinSeverity $MinSeverity -DryRun:$DryRun
if (-not $result.ReviewResult.Success) {
Warn " Review step failed: $($result.ReviewResult.Error)"
$result.Success = $false
} else {
$stepInfo = if ($result.ReviewResult.StepFilesCreated) { " ($($result.ReviewResult.StepFilesCreated) step files)" } else { "" }
$partialInfo = if ($result.ReviewResult.Partial) { " [PARTIAL]" } else { "" }
Success " Review completed: $($result.ReviewResult.ReviewPath)$stepInfo$partialInfo"
}
} else {
Info " Step 2: Skipped (review)"
}
# Step 3: Fix PR comments
if (-not $SkipFix) {
Info " Step 3: Fixing PR comments..."
$result.FixResult = Invoke-FixPRComments -PRNumber $PRNumber -WorktreePath $WorktreePath -CLIType $CLIType -DryRun:$DryRun
if (-not $result.FixResult.Success) {
Warn " Fix step failed: $($result.FixResult.Error)"
$result.Success = $false
} else {
Success " Fix step completed"
}
} else {
Info " Step 3: Skipped (fix)"
}
return $result
}
#region Main Script
try {
Info "Repository root: $repoRoot"
Info "CLI type: $CLIType"
Info "Min severity for comments: $MinSeverity"
Info "Max parallel: $MaxParallel"
# Determine PRs to process
$prsToProcess = @()
if ($PRNumbers -and $PRNumbers.Count -gt 0) {
# Use specified PR numbers
foreach ($prNum in $PRNumbers) {
$prInfo = gh pr view $prNum --json number,url,headRefName 2>$null | ConvertFrom-Json
if ($prInfo) {
# Try to find matching worktree
$wt = Get-WorktreeEntries | Where-Object { $_.Branch -eq $prInfo.headRefName } | Select-Object -First 1
$prsToProcess += @{
PRNumber = $prInfo.number
PRUrl = $prInfo.url
Branch = $prInfo.headRefName
WorktreePath = if ($wt) { $wt.Path } else { $repoRoot }
}
} else {
Warn "PR #$prNum not found"
}
}
} else {
# Get PRs from worktrees
Info "`nFinding PRs from issue worktrees..."
$prsToProcess = Get-PRsFromWorktrees
}
if ($prsToProcess.Count -eq 0) {
Warn "No PRs found to process."
return
}
# Display PRs
Info "`nPRs to process:"
Info ("-" * 80)
foreach ($pr in $prsToProcess) {
Info (" #{0,-6} {1}" -f $pr.PRNumber, $pr.PRUrl)
}
Info ("-" * 80)
if ($DryRun) {
Warn "`nDry run mode - no changes will be made."
}
# Confirm
if (-not $Force -and -not $DryRun) {
$stepsDesc = @()
if (-not $SkipAssign) { $stepsDesc += "assign Copilot" }
if (-not $SkipReview) { $stepsDesc += "review" }
if (-not $SkipFix) { $stepsDesc += "fix comments" }
$confirm = Read-Host "`nProceed with $($prsToProcess.Count) PRs ($($stepsDesc -join ', '))? (y/N)"
if ($confirm -notmatch '^[yY]') {
Info "Cancelled."
return
}
}
# Process PRs (using jobs for parallelization)
$results = @{
Success = @()
Failed = @()
}
if ($MaxParallel -gt 1 -and $prsToProcess.Count -gt 1) {
# Parallel processing using PowerShell jobs
Info "`nStarting parallel processing (max $MaxParallel concurrent)..."
$jobs = @()
$prQueue = [System.Collections.Queue]::new($prsToProcess)
while ($prQueue.Count -gt 0 -or $jobs.Count -gt 0) {
# Start new jobs up to MaxParallel
while ($jobs.Count -lt $MaxParallel -and $prQueue.Count -gt 0) {
$pr = $prQueue.Dequeue()
Info "`n" + ("=" * 60)
Info "PROCESSING PR #$($pr.PRNumber)"
Info ("=" * 60)
# For simplicity, process sequentially within each PR but PRs in parallel
# Since copilot CLI might have issues with true parallel execution
$jobResult = Start-PRWorkflowJob `
-PRNumber $pr.PRNumber `
-WorktreePath $pr.WorktreePath `
-CLIType $CLIType `
-MinSeverity $MinSeverity `
-SkipAssign:$SkipAssign `
-SkipReview:$SkipReview `
-SkipFix:$SkipFix `
-DryRun:$DryRun
if ($jobResult.Success) {
$results.Success += $jobResult
Success "✓ PR #$($pr.PRNumber) workflow completed"
} else {
$results.Failed += $jobResult
Err "✗ PR #$($pr.PRNumber) workflow had failures"
}
}
}
} else {
# Sequential processing
foreach ($pr in $prsToProcess) {
Info "`n" + ("=" * 60)
Info "PROCESSING PR #$($pr.PRNumber)"
Info ("=" * 60)
$jobResult = Start-PRWorkflowJob `
-PRNumber $pr.PRNumber `
-WorktreePath $pr.WorktreePath `
-CLIType $CLIType `
-MinSeverity $MinSeverity `
-SkipAssign:$SkipAssign `
-SkipReview:$SkipReview `
-SkipFix:$SkipFix `
-DryRun:$DryRun
if ($jobResult.Success) {
$results.Success += $jobResult
Success "✓ PR #$($pr.PRNumber) workflow completed"
} else {
$results.Failed += $jobResult
Err "✗ PR #$($pr.PRNumber) workflow had failures"
}
}
}
# Summary
Info "`n" + ("=" * 80)
Info "PR REVIEW WORKFLOW COMPLETE"
Info ("=" * 80)
Info "Total PRs: $($prsToProcess.Count)"
if ($results.Success.Count -gt 0) {
Success "Succeeded: $($results.Success.Count)"
foreach ($r in $results.Success) {
Success " PR #$($r.PRNumber)"
}
}
if ($results.Failed.Count -gt 0) {
Err "Had issues: $($results.Failed.Count)"
foreach ($r in $results.Failed) {
Err " PR #$($r.PRNumber)"
}
}
Info "`nReview files location: Generated Files/prReview/<PR_NUMBER>/"
Info ("=" * 80)
return $results
}
catch {
Err "Error: $($_.Exception.Message)"
exit 1
}
#endregion

View File

@@ -1,170 +0,0 @@
<#
.SYNOPSIS
Tests and previews incremental review detection for a pull request.
.DESCRIPTION
This helper script validates the incremental review detection logic by analyzing an existing
PR review folder. It reads the last reviewed SHA from the overview file, compares it with
the current PR state, and displays detailed information about what has changed.
This is useful for:
- Testing the incremental review system before running a full review
- Understanding what changed since the last review iteration
- Verifying that review metadata was properly recorded
.PARAMETER PullRequestNumber
The pull request number to test incremental review detection for.
.PARAMETER RepositoryOwner
The GitHub repository owner. Defaults to "microsoft".
.PARAMETER RepositoryName
The GitHub repository name. Defaults to "PowerToys".
.OUTPUTS
Colored console output displaying:
- Current and last reviewed commit SHAs
- Whether incremental review is possible
- List of new commits since last review
- List of changed files with status indicators
- Recommended review strategy
.EXAMPLE
.\Test-IncrementalReview.ps1 -PullRequestNumber 42374
Tests incremental review detection for PR #42374.
.EXAMPLE
.\Test-IncrementalReview.ps1 -PullRequestNumber 42374 -RepositoryOwner "myorg" -RepositoryName "myrepo"
Tests incremental review for a PR in a different repository.
.NOTES
Requires GitHub CLI (gh) to be installed and authenticated.
Run 'gh auth login' if not already authenticated.
Prerequisites:
- PR review folder must exist at "Generated Files\prReview\{PRNumber}"
- 00-OVERVIEW.md must exist in the review folder
- For incremental detection, overview must contain "Last reviewed SHA" metadata
.LINK
https://cli.github.com/
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, HelpMessage = "Pull request number to test")]
[int]$PullRequestNumber,
[Parameter(Mandatory = $false, HelpMessage = "Repository owner")]
[string]$RepositoryOwner = "microsoft",
[Parameter(Mandatory = $false, HelpMessage = "Repository name")]
[string]$RepositoryName = "PowerToys"
)
# Resolve paths to review folder and overview file
$repositoryRoot = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
$reviewFolderPath = Join-Path $repositoryRoot "Generated Files\prReview\$PullRequestNumber"
$overviewFilePath = Join-Path $reviewFolderPath "00-OVERVIEW.md"
Write-Host "=== Testing Incremental Review for PR #$PullRequestNumber ===" -ForegroundColor Cyan
Write-Host ""
# Check if review folder exists
if (-not (Test-Path $reviewFolderPath)) {
Write-Host "❌ Review folder not found: $reviewFolderPath" -ForegroundColor Red
Write-Host "This appears to be a new review (iteration 1)" -ForegroundColor Yellow
exit 0
}
# Check if overview file exists
if (-not (Test-Path $overviewFilePath)) {
Write-Host "❌ Overview file not found: $overviewFilePath" -ForegroundColor Red
Write-Host "This appears to be an incomplete review" -ForegroundColor Yellow
exit 0
}
# Read overview file and extract last reviewed SHA
Write-Host "📄 Reading overview file..." -ForegroundColor Green
$overviewFileContent = Get-Content $overviewFilePath -Raw
if ($overviewFileContent -match '\*\*Last reviewed SHA:\*\*\s+(\w+)') {
$lastReviewedSha = $Matches[1]
Write-Host "✅ Found last reviewed SHA: $lastReviewedSha" -ForegroundColor Green
} else {
Write-Host "⚠️ No 'Last reviewed SHA' found in overview - this may be an old format" -ForegroundColor Yellow
Write-Host "Proceeding without incremental detection (full review will be needed)" -ForegroundColor Yellow
exit 0
}
Write-Host ""
Write-Host "🔍 Running incremental change detection..." -ForegroundColor Cyan
# Call the incremental changes detection script
$incrementalChangesScriptPath = Join-Path $PSScriptRoot "Get-PrIncrementalChanges.ps1"
if (-not (Test-Path $incrementalChangesScriptPath)) {
Write-Host "❌ Script not found: $incrementalChangesScriptPath" -ForegroundColor Red
exit 1
}
try {
$analysisResult = & $incrementalChangesScriptPath `
-PullRequestNumber $PullRequestNumber `
-LastReviewedCommitSha $lastReviewedSha `
-RepositoryOwner $RepositoryOwner `
-RepositoryName $RepositoryName | ConvertFrom-Json
# Display analysis results
Write-Host ""
Write-Host "=== Incremental Review Analysis ===" -ForegroundColor Cyan
Write-Host "Current HEAD SHA: $($analysisResult.CurrentHeadSha)" -ForegroundColor White
Write-Host "Last reviewed SHA: $($analysisResult.LastReviewedSha)" -ForegroundColor White
Write-Host "Base branch: $($analysisResult.BaseRefName)" -ForegroundColor White
Write-Host "Head branch: $($analysisResult.HeadRefName)" -ForegroundColor White
Write-Host ""
Write-Host "Is incremental? $($analysisResult.IsIncremental)" -ForegroundColor $(if ($analysisResult.IsIncremental) { "Green" } else { "Yellow" })
Write-Host "Need full review? $($analysisResult.NeedFullReview)" -ForegroundColor $(if ($analysisResult.NeedFullReview) { "Yellow" } else { "Green" })
Write-Host ""
Write-Host "Summary: $($analysisResult.Summary)" -ForegroundColor Cyan
Write-Host ""
# Display new commits if any
if ($analysisResult.NewCommits -and $analysisResult.NewCommits.Count -gt 0) {
Write-Host "📝 New commits ($($analysisResult.NewCommits.Count)):" -ForegroundColor Green
foreach ($commit in $analysisResult.NewCommits) {
Write-Host " - $($commit.Sha): $($commit.Message)" -ForegroundColor Gray
}
Write-Host ""
}
# Display changed files if any
if ($analysisResult.ChangedFiles -and $analysisResult.ChangedFiles.Count -gt 0) {
Write-Host "📁 Changed files ($($analysisResult.ChangedFiles.Count)):" -ForegroundColor Green
foreach ($file in $analysisResult.ChangedFiles) {
$statusDisplayColor = switch ($file.Status) {
"added" { "Green" }
"removed" { "Red" }
"modified" { "Yellow" }
"renamed" { "Cyan" }
default { "White" }
}
Write-Host " - [$($file.Status)] $($file.Filename) (+$($file.Additions)/-$($file.Deletions))" -ForegroundColor $statusDisplayColor
}
Write-Host ""
}
# Suggest review strategy based on analysis
Write-Host "=== Recommended Review Strategy ===" -ForegroundColor Cyan
if ($analysisResult.NeedFullReview) {
Write-Host "🔄 Full review recommended" -ForegroundColor Yellow
} elseif ($analysisResult.IsIncremental -and ($analysisResult.ChangedFiles.Count -eq 0)) {
Write-Host "✅ No changes detected - no review needed" -ForegroundColor Green
} elseif ($analysisResult.IsIncremental) {
Write-Host "⚡ Incremental review possible - review only changed files" -ForegroundColor Green
Write-Host "💡 Consider applying smart step filtering based on file types" -ForegroundColor Cyan
}
} catch {
Write-Host "❌ Error running incremental change detection: $_" -ForegroundColor Red
exit 1
}

View File

@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2026 Microsoft Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,132 +0,0 @@
---
name: release-note-generation
description: Toolkit for generating PowerToys release notes from GitHub milestone PRs or commit ranges. Use when asked to create release notes, summarize milestone PRs, generate changelog, prepare release documentation, request Copilot reviews for PRs, update README for a new release, manage PR milestones, or collect PRs between commits/tags. Supports PR collection by milestone or commit range, milestone assignment, grouping by label, summarization with external contributor attribution, and README version bumping.
license: Complete terms in LICENSE.txt
---
# Release Note Generation Skill
Generate professional release notes for PowerToys milestones by collecting merged PRs, requesting Copilot code reviews, grouping by label, and producing user-facing summaries.
## Output Directory
All generated artifacts are placed under `Generated Files/ReleaseNotes/` at the repository root (gitignored).
```
Generated Files/ReleaseNotes/
├── milestone_prs.json # Raw PR data from GitHub
├── sorted_prs.csv # Sorted PR list with Copilot summaries
├── prs_with_milestone.csv # Milestone assignment tracking
├── grouped_csv/ # PRs grouped by label (one CSV per label)
├── grouped_md/ # Generated markdown summaries per label
└── v{VERSION}-release-notes.md # Final consolidated release notes
```
## When to Use This Skill
- Generate release notes for a milestone
- Summarize PRs merged in a release
- Request Copilot reviews for milestone PRs
- Assign milestones to PRs missing them
- Collect PRs between two commits/tags
- Update README.md for a new version
## Prerequisites
- GitHub CLI (`gh`) installed and authenticated
- MCP Server: github-mcp-server installed
- GitHub Copilot code review enabled for the org/repo
## Required Variables
⚠️ **Before starting**, confirm `{{ReleaseVersion}}` with the user. If not provided, **ASK**: "What release version are we generating notes for? (e.g., 0.98)"
| Variable | Description | Example |
|----------|-------------|---------|
| `{{ReleaseVersion}}` | Target release version | `0.98` |
## Workflow Overview
```
┌────────────────────────────────┐
│ 1.1 Collect PRs (stable range) │
└────────────────────────────────┘
┌────────────────────────────────┐
│ 1.2 Assign Milestones │
└────────────────────────────────┘
┌────────────────────────────────┐
│ 2.12.4 Label PRs (auto+human) │
└────────────────────────────────┘
┌────────────────────────────────┐
│ 3.1 Request Reviews (Copilot) │
└────────────────────────────────┘
┌────────────────────────────────┐
│ 3.2 Refresh PR data │
│ (CopilotSummary) │
└────────────────────────────────┘
┌────────────────────────────────┐
│ 3.3 Group by label │
│ (grouped_csv) │
└────────────────────────────────┘
┌────────────────────────────────┐
│ 4.1 Summarize (grouped_md) │
└────────────────────────────────┘
┌────────────────────────────────┐
│ 4.2 Final notes (v{VERSION}.md) │
└────────────────────────────────┘
```
| Step | Action | Details |
|------|--------|---------|
| 1.1 | Collect PRs | From previous release tag on `stable` branch → `sorted_prs.csv` |
| 1.2 | Assign Milestones | Ensure all PRs have correct milestone |
| 2.12.4 | Label PRs | Auto-suggest + human label low-confidence |
| 3.13.3 | Reviews & Grouping | Request Copilot reviews → refresh → group by label |
| 4.14.2 | Summaries & Final | Generate grouped summaries, then consolidate |
## Detailed workflow docs
Do not read all steps at once—only read the step you are executing.
- [Step 1: Collection & Milestones](./references/step1-collection.md)
- [Step 2: Labeling PRs](./references/step2-labeling.md)
- [Step 3: Reviews & Grouping](./references/step3-review-grouping.md)
- [Step 4: Summarization](./references/step4-summarization.md)
## Available Scripts
| Script | Purpose |
|--------|---------|
| [dump-prs-since-commit.ps1](./scripts/dump-prs-since-commit.ps1) | Fetch PRs between commits/tags |
| [group-prs-by-label.ps1](./scripts/group-prs-by-label.ps1) | Group PRs into CSVs |
| [collect-or-apply-milestones.ps1](./scripts/collect-or-apply-milestones.ps1) | Assign milestones |
| [diff_prs.ps1](./scripts/diff_prs.ps1) | Incremental PR diff |
## References
- [Sample Output](./references/SampleOutput.md) - Example summary formatting
- [Detailed Instructions](./references/Instruction.md) - Legacy full documentation
## Conventions
- **Terminal usage**: Disabled by default; only run scripts when user explicitly requests
- **Batch generation**: Generate ALL grouped_md files in one pass, then human reviews
- **PR order**: Preserve order from `sorted_prs.csv` in all outputs
- **Label filtering**: Keeps `Product-*`, `Area-*`, `GitHub*`, `*Plugin`, `Issue-*`
## Troubleshooting
| Issue | Solution |
|-------|----------|
| `gh` command not found | Install GitHub CLI and add to PATH |
| No PRs returned | Verify milestone title matches exactly |
| Empty CopilotSummary | Request Copilot reviews first, then re-run dump |
| Many unlabeled PRs | Return to labeling step before grouping |

View File

@@ -1,9 +0,0 @@
- Added mouse button actions so you can choose what left, right, or middle click does. Thanks [@PesBandi](https://github.com/PesBandi)!
- Aligned window styling with current Windows theme for a cleaner look. Thanks [@sadirano](https://github.com/sadirano)!
- Ensured screen readers are notified when the selected item in the list changes for better accessibility.
- Implemented configurable UI test pipeline that can use pre-built official releases instead of building everything from scratch, reducing test execution time from 2+ hours.
- Fixed Alt+Left Arrow navigation not working when search box contains text. Thanks [@jiripolasek](https://github.com/jiripolasek)!

View File

@@ -1,143 +0,0 @@
# Step 1: Collection and Milestones
## 1.0 To-do
- 1.0.1 Generate MemberList.md (REQUIRED)
- 1.1 Collect PRs
- 1.2 Assign Milestones (REQUIRED)
## Required Variables
⚠️ **Before starting**, confirm these values with the user:
| Variable | Description | Example |
|----------|-------------|---------|
| `{{ReleaseVersion}}` | Target release version | `0.97` |
| `{{PreviousReleaseTag}}` | Previous release tag from releases page | `v0.96.1` |
**If user hasn't specified `{{ReleaseVersion}}`, ASK:** "What release version are we generating notes for? (e.g., 0.97)"
**`{{PreviousReleaseTag}}` is derived from the releases page, not user input.** Use the latest published release tag (top of the page). You will use its tag name and tag commit SHA in Step 1.
---
## 1.0.1 Generate MemberList.md (REQUIRED)
Create `Generated Files/ReleaseNotes/MemberList.md` from the **PowerToys core team** section in [COMMUNITY.md](../../../COMMUNITY.md).
Rules:
- One GitHub username per line, **no** `@` prefix.
- Use the usernames exactly as listed in the core team section.
- Do not include former team members or other sections.
Example (format only):
```
example-user
another-user
```
---
## 1.1 Collect PRs
### 1.1.1 Get the previous release commit
1. Open the [PowerToys releases page](https://github.com/microsoft/PowerToys/releases/)
2. Find the latest release (e.g., v0.96.1, which should be at the top)
3. Set `{{PreviousReleaseTag}}` to that tag name (e.g., `v0.96.1`)
4. Copy the full tag commit SHA as `{{SHALastRelease}}`
**If the release SHA is not in your branch history:** Use the helper script to find an equivalent commit on the target branch by matching the commit title:
```powershell
pwsh ./.github/skills/release-note-generation/scripts/find-commit-by-title.ps1 `
-Commit '{{SHALastRelease}}' `
-Branch 'stable'
```
### 1.1.2 Run collection script against stable branch
```powershell
# Collect PRs from previous release to current HEAD of stable branch
pwsh ./.github/skills/release-note-generation/scripts/dump-prs-since-commit.ps1 `
-StartCommit '{{SHALastRelease}}' `
-Branch 'stable' `
-OutputDir 'Generated Files/ReleaseNotes'
```
**Parameters:**
- `-StartCommit` - Previous release tag or commit SHA (exclusive)
- `-Branch` - Always use `stable` branch, not `main` (script uses `origin/stable` as the end ref)
- `-EndCommit` - Optional override if you need a custom end ref
- `-OutputDir` - Output directory for generated files
**Reliability check:** If the script reports “No commits found”, the stable branch has not moved since the last release. In that case, either:
- Confirm this is expected and stop (no new release notes), or
- Re-run against `main` to gather pending changes for the next release cycle.
The script detects both merge commits (`Merge pull request #12345`) and squash commits (`Feature (#12345)`).
**Output** (in `Generated Files/ReleaseNotes/`):
- `milestone_prs.json` - raw PR data
- `sorted_prs.csv` - sorted PR list with columns: Id, Title, Labels, Author, Url, Body, CopilotSummary, NeedThanks
---
## 1.2 Assign Milestones (REQUIRED)
**Before generating release notes**, ensure all collected PRs have the correct milestone assigned.
⚠️ **CRITICAL:** Do NOT proceed to labeling until all PRs have milestones assigned.
### 1.2.1 Check current milestone status (dry run)
```powershell
# Dry run first to see what would be changed:
pwsh ./.github/skills/release-note-generation/scripts/collect-or-apply-milestones.ps1 `
-InputCsv 'Generated Files/ReleaseNotes/sorted_prs.csv' `
-OutputCsv 'Generated Files/ReleaseNotes/prs_with_milestone.csv' `
-DefaultMilestone 'PowerToys {{ReleaseVersion}}' `
-ApplyMissing -WhatIf
```
This queries GitHub for each PR's current milestone and shows which PRs would be updated.
### 1.2.2 Apply milestones to PRs missing them
```powershell
# Apply for real:
pwsh ./.github/skills/release-note-generation/scripts/collect-or-apply-milestones.ps1 `
-InputCsv 'Generated Files/ReleaseNotes/sorted_prs.csv' `
-OutputCsv 'Generated Files/ReleaseNotes/prs_with_milestone.csv' `
-DefaultMilestone 'PowerToys {{ReleaseVersion}}' `
-ApplyMissing
```
**Script Behavior:**
- Queries each PR's current milestone from GitHub
- PRs that already have a milestone are **skipped** (not overwritten)
- PRs missing a milestone get the default milestone applied
- Outputs `prs_with_milestone.csv` with (Id, Milestone) columns
- Produces summary: `Updated=X Skipped=Y Failed=Z`
**Validation:** After assignment, all PRs in `prs_with_milestone.csv` should have the target milestone.
---
## Additional Commands
### Collect milestones only (no changes to GitHub)
```powershell
pwsh ./.github/skills/release-note-generation/scripts/collect-or-apply-milestones.ps1 `
-InputCsv 'Generated Files/ReleaseNotes/sorted_prs.csv' `
-OutputCsv 'Generated Files/ReleaseNotes/prs_with_milestone.csv'
```
### Local assignment only (fill blanks in CSV, no GitHub changes)
```powershell
pwsh ./.github/skills/release-note-generation/scripts/collect-or-apply-milestones.ps1 `
-InputCsv 'Generated Files/ReleaseNotes/sorted_prs.csv' `
-OutputCsv 'Generated Files/ReleaseNotes/prs_with_milestone.csv' `
-DefaultMilestone 'PowerToys {{ReleaseVersion}}' `
-LocalAssign
```

View File

@@ -1,131 +0,0 @@
# Step 2: Label Unlabeled PRs
## 2.0 To-do
- 2.1 Identify unlabeled PRs (Agent Mode)
- 2.2 Suggest labels (Agent Mode)
- 2.3 Human label low-confidence PRs
- 2.4 Recheck labels, delete Unlabeled.csv, and re-collect
**Before grouping**, ensure all PRs have appropriate labels for categorization.
⚠️ **CRITICAL:** Do NOT proceed to grouping until all PRs have labels assigned. PRs without labels will end up in `Unlabeled.csv` and won't appear in the correct release note sections.
## 2.1 Identify unlabeled PRs (Agent Mode)
Read `sorted_prs.csv` and identify PRs with empty or missing `Labels` column.
For each unlabeled PR, analyze:
- **Title** - Often contains module name or feature
- **Body** - PR description with context
- **CopilotSummary** - AI-generated summary of changes
## 2.2 Suggest labels (Agent Mode)
For each unlabeled PR, suggest an appropriate label based on the content analysis.
**Output:** Create `Generated Files/ReleaseNotes/prs_label_review.md` with the following format:
```markdown
# PR Label Review
Generated: YYYY-MM-DD HH:mm:ss
## Summary
- Total unlabeled PRs: X
- High confidence: X
- Medium confidence: X
- Low confidence: X
---
## PRs Needing Review (sorted by confidence, low first)
| PR | Title | Suggested Label | Confidence | Reason |
|----|-------|-----------------|------------|--------|
| [#12347](url) | Some generic fix | ??? | Low | Unclear from content |
| [#12346](url) | Update dependencies | `Area-Build` | Medium | Body mentions NuGet packages |
```
Sort by confidence (low first) so human reviews uncertain ones first.
After writing `prs_label_review.md`, **generate `prs_to_label.csv`, apply labels, and re-run collection** so the CSV/labels stay in sync:
```powershell
# Generate CSV from suggestions (agent)
# Apply labels
pwsh ./.github/skills/release-note-generation/scripts/apply-labels.ps1 `
-InputCsv 'Generated Files/ReleaseNotes/prs_to_label.csv'
# Refresh collection
pwsh ./.github/skills/release-note-generation/scripts/dump-prs-since-commit.ps1 `
-StartCommit '{{PreviousReleaseTag}}' -Branch 'stable' `
-OutputDir 'Generated Files/ReleaseNotes'
```
## 2.3 Human label low-confidence PRs
Ask the human to label **low-confidence** PRs directly (in GitHub). Skip any they decide not to label.
## 2.4 Recheck labels, delete Unlabeled.csv, and re-collect
Recheck that all PRs now have labels. Delete `Unlabeled.csv` (if present), then re-run the collection script to update `sorted_prs.csv`:
```powershell
# Remove stale unlabeled output if it exists
Remove-Item 'Generated Files/ReleaseNotes/Unlabeled.csv' -ErrorAction SilentlyContinue
```
```powershell
pwsh ./.github/skills/release-note-generation/scripts/dump-prs-since-commit.ps1 `
-StartCommit '{{PreviousReleaseTag}}' -Branch 'stable' `
-OutputDir 'Generated Files/ReleaseNotes'
```
---
## Common Label Mappings
| Keywords/Patterns | Suggested Label |
| ----------------- | --------------- |
| Advanced Paste, AP, clipboard, paste | `Product-Advanced Paste` |
| CmdPal, Command Palette, cmdpal | `Product-Command Palette` |
| FancyZones, zones, layout | `Product-FancyZones` |
| ZoomIt, zoom, screen annotation | `Product-ZoomIt` |
| Settings, settings-ui, Quick Access, flyout | `Product-Settings` |
| Installer, setup, MSI, MSIX, WiX | `Area-Setup/Install` |
| Build, pipeline, CI/CD, msbuild | `Area-Build` |
| Test, unit test, UI test, fuzz | `Area-Tests` |
| Localization, loc, translation, resw | `Area-Localization` |
| Foundry, AI, LLM | `Product-Advanced Paste` (AI features) |
| Mouse Without Borders, MWB | `Product-Mouse Without Borders` |
| PowerRename, rename, regex | `Product-PowerRename` |
| Peek, preview, file preview | `Product-Peek` |
| Image Resizer, resize | `Product-Image Resizer` |
| LightSwitch, theme, dark mode | `Product-LightSwitch` |
| Quick Accent, accent, diacritics | `Product-Quick Accent` |
| Awake, keep awake, caffeine | `Product-Awake` |
| ColorPicker, color picker, eyedropper | `Product-ColorPicker` |
| Hosts, hosts file | `Product-Hosts` |
| Keyboard Manager, remap | `Product-Keyboard Manager` |
| Mouse Highlighter | `Product-Mouse Highlighter` |
| Mouse Jump | `Product-Mouse Jump` |
| Find My Mouse | `Product-Find My Mouse` |
| Mouse Pointer Crosshairs | `Product-Mouse Pointer Crosshairs` |
| Shortcut Guide | `Product-Shortcut Guide` |
| Text Extractor, OCR, PowerOCR | `Product-Text Extractor` |
| Workspaces | `Product-Workspaces` |
| File Locksmith | `Product-File Locksmith` |
| Crop And Lock | `Product-CropAndLock` |
| Environment Variables | `Product-Environment Variables` |
| New+ | `Product-New+` |
## Label Filtering Rules
The grouping script keeps labels matching these patterns:
- `Product-*`
- `Area-*`
- `GitHub*`
- `*Plugin`
- `Issue-*`
Other labels are ignored for grouping purposes.

View File

@@ -1,37 +0,0 @@
# Step 3: Copilot Reviews and Grouping
## 3.0 To-do
- 3.1 Request Copilot Reviews (Agent Mode)
- 3.2 Refresh PR Data
- 3.3 Group PRs by Label
## 3.1 Request Copilot Reviews (Agent Mode)
Use MCP tools to request Copilot reviews for all PRs in `Generated Files/ReleaseNotes/sorted_prs.csv`:
- Use `mcp_github_request_copilot_review` for each PR ID
- Do NOT generate or run scripts for this step
---
## 3.2 Refresh PR Data
Re-run the collection script to capture Copilot review summaries into the `CopilotSummary` column:
```powershell
pwsh ./.github/skills/release-note-generation/scripts/dump-prs-since-commit.ps1 `
-StartCommit '{{PreviousReleaseTag}}' -Branch 'stable' `
-OutputDir 'Generated Files/ReleaseNotes'
```
---
## 3.3 Group PRs by Label
```powershell
pwsh ./.github/skills/release-note-generation/scripts/group-prs-by-label.ps1 -CsvPath 'Generated Files/ReleaseNotes/sorted_prs.csv' -OutDir 'Generated Files/ReleaseNotes/grouped_csv'
```
Creates `Generated Files/ReleaseNotes/grouped_csv/` with one CSV per label combination.
**Validation:** The `Unlabeled.csv` file should be minimal (ideally empty). If many PRs remain unlabeled, return to Step 2 (see [step2-labeling.md](./step2-labeling.md)).

View File

@@ -1,88 +0,0 @@
# Step 4: Summaries and Final Release Notes
## 4.0 To-do
- 4.1 Generate Summary Markdown (Agent Mode)
- 4.2 Produce Final Release Notes File
## 4.1 Generate Summary Markdown (Agent Mode)
For each CSV in `Generated Files/ReleaseNotes/grouped_csv/`, create a markdown file in `Generated Files/ReleaseNotes/grouped_md/`.
⚠️ **IMPORTANT:** Generate **ALL** markdown files first. Do NOT pause between files or ask for feedback during generation. Complete the entire batch, then human reviews afterwards.
### Structure per file
**1. Bullet list** - one concise, user-facing line per PR:
- Use the “Verb-ed + Scenario + Impact” sentence structure—make readers think, “Thats exactly what I need” or “Yes, thats an awesome fix.”; The "impact" can be end-user focused (written to convey user excitement) or technical (performance/stability) when user-facing impact is minimal.
- If nothing special on impact or unclear impact, mark as needing human summary
- Source from Title, Body, and CopilotSummary (prefer CopilotSummary when available)
- If the column `NeedThanks` in CSV is `True`, append: `Thanks [@Author](https://github.com/Author)!`
- Do NOT include PR numbers in bullet lines
- Do NOT mention “security” or “privacy” issues, since these are not known and could be leveraged by attackers in earlier versions. Instead, describe the user-facing scenario, usage, or impact.
- If confidence < 70%, write: `Human Summary Needed: <PR full link>`
**See [SampleOutput.md](./SampleOutput.md) for examples of well-written bullet summaries.**
**2. Three-column table** (same PR order):
- Column 1: Concise summary (same as bullet)
- Column 2: PR link `[#ID](URL)`
- Column 3: Confidence level (High/Medium/Low)
### Review Process (AFTER all files generated)
- Human reviews each `grouped_md/*.md` file and requests rewrites as needed
- Human may say "rewrite Product-X" or "combine these bullets"—apply changes to that specific file
- Do NOT interrupt generation to ask for feedback
---
## 4.2 Produce Final Release Notes File
Once all `grouped_md/*.md` files are reviewed and approved, consolidate into a single release notes file.
**Output:** `Generated Files/ReleaseNotes/v{{ReleaseVersion}}-release-notes.md`
### Structure
**1. Highlights section** (top):
- 8-12 bullets covering the most user-visible features and impactful fixes
- Pattern: `**Module**: brief description`
- Avoid internal refactors; focus on what users will notice
**2. Module sections** (alphabetical order):
- One section per product (Advanced Paste, Awake, Command Palette, etc.)
- Migrate bullet summaries from the approved `grouped_md/Product-*.md` files
- One section 'Development' for all the rest summaries from the approved `grouped_md/Area-*.md` files
- Re-review E2E, group release improvements by section, and move the most important items to the top of each section.
Some items in the Development section may overlap and should be moved to the Module section where more applicable.
### Example Final Structure
```markdown
# PowerToys v{{ReleaseVersion}} Release Notes
## Highlights
- **Command Palette**: Added theme customization and drag-and-drop support
- **Advanced Paste**: Image input for AI, color detection in clipboard history
- **FancyZones**: New CLI tool for command-line layout management
...
---
## Advanced Paste
- Wrapped paste option lists in a single ScrollViewer
- Added image input handling for AI-powered transformations
...
## Awake
- Fixed timed mode expiration. Thanks [@daverayment](https://github.com/daverayment)!
...
---
## Development
...
```

View File

@@ -1,90 +0,0 @@
<#
.SYNOPSIS
Apply labels to PRs from a CSV file.
.DESCRIPTION
Reads a CSV with Id and Label columns and applies the specified label to each PR via GitHub CLI.
Supports dry-run mode to preview changes before applying.
.PARAMETER InputCsv
CSV file with Id and Label columns. Default: prs_to_label.csv
.PARAMETER Repo
GitHub repository (owner/name). Default: microsoft/PowerToys
.PARAMETER WhatIf
Dry run - show what would be applied without making changes.
.EXAMPLE
pwsh ./apply-labels.ps1 -InputCsv 'Generated Files/ReleaseNotes/prs_to_label.csv'
.EXAMPLE
pwsh ./apply-labels.ps1 -InputCsv 'Generated Files/ReleaseNotes/prs_to_label.csv' -WhatIf
.NOTES
Requires: gh CLI authenticated with repo write access.
Input CSV format:
Id,Label
12345,Product-Advanced Paste
12346,Product-Settings
#>
[CmdletBinding()] param(
[Parameter(Mandatory=$false)][string]$InputCsv = 'prs_to_label.csv',
[Parameter(Mandatory=$false)][string]$Repo = 'microsoft/PowerToys',
[switch]$WhatIf
)
$ErrorActionPreference = 'Stop'
function Write-Info($m){ Write-Host "[info] $m" -ForegroundColor Cyan }
function Write-Warn($m){ Write-Host "[warn] $m" -ForegroundColor Yellow }
function Write-Err($m){ Write-Host "[error] $m" -ForegroundColor Red }
function Write-OK($m){ Write-Host "[ok] $m" -ForegroundColor Green }
if (-not (Get-Command gh -ErrorAction SilentlyContinue)) { Write-Err "GitHub CLI 'gh' not found in PATH"; exit 1 }
if (-not (Test-Path -LiteralPath $InputCsv)) { Write-Err "Input CSV not found: $InputCsv"; exit 1 }
$rows = Import-Csv -LiteralPath $InputCsv
if (-not $rows) { Write-Info "No rows in CSV."; exit 0 }
$firstCols = $rows[0].PSObject.Properties.Name
if (-not ($firstCols -contains 'Id' -and $firstCols -contains 'Label')) {
Write-Err "CSV must contain 'Id' and 'Label' columns"; exit 1
}
Write-Info "Processing $($rows.Count) label assignments..."
if ($WhatIf) { Write-Warn "DRY RUN - no changes will be made" }
$applied = 0
$skipped = 0
$failed = 0
foreach ($row in $rows) {
$id = $row.Id
$label = $row.Label
if ([string]::IsNullOrWhiteSpace($id) -or [string]::IsNullOrWhiteSpace($label)) {
Write-Warn "Skipping row with empty Id or Label"
$skipped++
continue
}
if ($WhatIf) {
Write-Info "Would apply label '$label' to PR #$id"
$applied++
continue
}
try {
gh pr edit $id --repo $Repo --add-label $label 2>&1 | Out-Null
Write-OK "Applied '$label' to PR #$id"
$applied++
} catch {
Write-Warn "Failed to apply label to PR #${id}: $_"
$failed++
}
}
Write-Info ""
Write-Info "Summary: Applied=$applied Skipped=$skipped Failed=$failed"

View File

@@ -1,172 +0,0 @@
<#
.SYNOPSIS
Collect existing PR milestones or (optionally) assign/apply a milestone to missing PRs in one script.
.DESCRIPTION
This unified script merges the behaviors of the previous add-milestone-column (collector) and
set-milestones-missing (remote updater) scripts.
Modes (controlled by switches):
1. Collect (default) For each PR Id in the input CSV, queries GitHub for the current milestone and
outputs a two-column CSV (Id,Milestone) leaving blanks where none are set.
2. LocalAssign Same as Collect, but for rows that end up blank assigns the value of -DefaultMilestone
in memory (does NOT touch GitHub). Useful for quickly preparing a fully populated CSV.
3. ApplyMissing After determining which PRs have no milestone, call GitHub API to set their milestone
to -DefaultMilestone. Requires milestone to already exist (open). Network + write.
You can combine LocalAssign and ApplyMissing: the remote update uses the existing live state; LocalAssign only
affects the output CSV/pipeline objects.
.PARAMETER InputCsv
Source CSV with at least an Id column. Default: sorted_prs.csv
.PARAMETER OutputCsv
Destination CSV for collected (and optionally locally assigned) milestones. Default: prs_with_milestone.csv
.PARAMETER Repo
GitHub repository (owner/name). Default: microsoft/PowerToys
.PARAMETER DefaultMilestone
Milestone title used when -LocalAssign or -ApplyMissing is specified. Default: 'PowerToys 0.97'
.PARAMETER Offline
Skip ALL GitHub lookups / updates. Implies Collect-only with all Milestone cells blank (unless LocalAssign).
.PARAMETER LocalAssign
Populate empty Milestone cells in the output with -DefaultMilestone (does not modify GitHub).
.PARAMETER ApplyMissing
For PRs which currently have no milestone (live on GitHub), set them to -DefaultMilestone via Issues API.
.PARAMETER WhatIf
Dry run for ApplyMissing: show intended remote changes without performing PATCH requests.
.EXAMPLE
# Collect only
pwsh ./collect-or-apply-milestones.ps1
.EXAMPLE
# Collect and fill blanks locally in the output only
pwsh ./collect-or-apply-milestones.ps1 -LocalAssign
.EXAMPLE
# Collect and remotely apply milestone to missing PRs
pwsh ./collect-or-apply-milestones.ps1 -ApplyMissing
.EXAMPLE
# Dry run remote application
pwsh ./collect-or-apply-milestones.ps1 -ApplyMissing -WhatIf
.EXAMPLE
# Offline local assignment
pwsh ./collect-or-apply-milestones.ps1 -Offline -LocalAssign -DefaultMilestone 'PowerToys 0.96'
.NOTES
Requires gh CLI unless -Offline AND -ApplyMissing not specified.
Remote apply path queries milestones to resolve numeric ID.
#>
[CmdletBinding()] param(
[Parameter(Mandatory=$false)][string]$InputCsv = 'sorted_prs.csv',
[Parameter(Mandatory=$false)][string]$OutputCsv = 'prs_with_milestone.csv',
[Parameter(Mandatory=$false)][string]$Repo = 'microsoft/PowerToys',
[Parameter(Mandatory=$false)][string]$DefaultMilestone = 'PowerToys 0.97',
[switch]$Offline,
[switch]$LocalAssign,
[switch]$ApplyMissing,
[switch]$WhatIf
)
$ErrorActionPreference = 'Stop'
function Write-Info($m){ Write-Host "[info] $m" -ForegroundColor Cyan }
function Write-Warn($m){ Write-Host "[warn] $m" -ForegroundColor Yellow }
function Write-Err($m){ Write-Host "[error] $m" -ForegroundColor Red }
if (-not (Test-Path -LiteralPath $InputCsv)) { Write-Err "Input CSV not found: $InputCsv"; exit 1 }
$rows = Import-Csv -LiteralPath $InputCsv
if (-not $rows) { Write-Warn "Input CSV has no rows."; @() | Export-Csv -NoTypeInformation -LiteralPath $OutputCsv; exit 0 }
if (-not ($rows[0].PSObject.Properties.Name -contains 'Id')) { Write-Err "Input CSV missing 'Id' column."; exit 1 }
$needGh = (-not $Offline) -and ($ApplyMissing -or -not $Offline)
if ($needGh -and -not (Get-Command gh -ErrorAction SilentlyContinue)) { Write-Err "GitHub CLI 'gh' not found. Use -Offline or install gh."; exit 1 }
# Step 1: Collect current milestone titles
$milestoneCache = @{}
$collected = New-Object System.Collections.Generic.List[object]
$idx = 0
foreach ($row in $rows) {
$idx++
$id = $row.Id
if (-not $id) { Write-Warn "Row $idx missing Id; skipping"; continue }
$ms = ''
if (-not $Offline) {
if ($milestoneCache.ContainsKey($id)) { $ms = $milestoneCache[$id] }
else {
try {
$json = gh pr view $id --repo $Repo --json milestone 2>$null | ConvertFrom-Json
if ($json -and $json.milestone -and $json.milestone.title) { $ms = $json.milestone.title }
} catch {
Write-Warn "Failed to fetch PR #$id milestone: $_"
}
$milestoneCache[$id] = $ms
}
}
$collected.Add([PSCustomObject]@{ Id = $id; Milestone = $ms }) | Out-Null
}
# Step 2: Remote apply (if requested)
$applySummary = @()
if ($ApplyMissing) {
if ($Offline) { Write-Err "Cannot use -ApplyMissing with -Offline."; exit 1 }
Write-Info "Resolving milestone id for '$DefaultMilestone' ..."
$milestonesRaw = gh api repos/$Repo/milestones --paginate --jq '.[] | {number,title,state}'
$msObj = $milestonesRaw | ConvertFrom-Json | Where-Object { $_.title -eq $DefaultMilestone -and $_.state -eq 'open' } | Select-Object -First 1
if (-not $msObj) { Write-Err "Milestone '$DefaultMilestone' not found/open."; exit 1 }
$msNumber = $msObj.number
$targets = $collected | Where-Object { [string]::IsNullOrWhiteSpace($_.Milestone) }
Write-Info ("ApplyMissing: {0} PR(s) without milestone." -f $targets.Count)
foreach ($t in $targets) {
$id = $t.Id
try {
# Verify still missing live
$current = gh pr view $id --repo $Repo --json milestone --jq '.milestone.title // ""'
if ($current) {
$applySummary += [PSCustomObject]@{ Id=$id; Action='Skip (already has)'; Milestone=$current; Status='OK' }
continue
}
if ($WhatIf) {
$applySummary += [PSCustomObject]@{ Id=$id; Action='Would set'; Milestone=$DefaultMilestone; Status='DRY RUN' }
continue
}
gh api -X PATCH -H 'Accept: application/vnd.github+json' repos/$Repo/issues/$id -f milestone=$msNumber | Out-Null
$applySummary += [PSCustomObject]@{ Id=$id; Action='Set'; Milestone=$DefaultMilestone; Status='OK' }
# Reflect in collected object for CSV output if not LocalAssign already doing so
$t.Milestone = $DefaultMilestone
} catch {
$errText = $_ | Out-String
$applySummary += [PSCustomObject]@{ Id=$id; Action='Failed'; Milestone=$DefaultMilestone; Status=$errText.Trim() }
Write-Warn ("Failed to set milestone for PR #{0}: {1}" -f $id, ($errText.Trim()))
}
}
}
# Step 3: Local assignment (purely for output) AFTER remote so remote actual result not overwritten accidentally
if ($LocalAssign) {
foreach ($item in $collected) {
if ([string]::IsNullOrWhiteSpace($item.Milestone)) { $item.Milestone = $DefaultMilestone }
}
}
# Step 4: Export CSV
$collected | Export-Csv -LiteralPath $OutputCsv -NoTypeInformation -Encoding UTF8
Write-Info ("Wrote collected CSV -> {0}" -f (Resolve-Path -LiteralPath $OutputCsv))
# Step 5: Summaries
if ($ApplyMissing) {
$updated = ($applySummary | Where-Object { $_.Action -eq 'Set' }).Count
$skipped = ($applySummary | Where-Object { $_.Action -like 'Skip*' }).Count
$failed = ($applySummary | Where-Object { $_.Action -eq 'Failed' }).Count
Write-Info ("ApplyMissing summary: Updated={0} Skipped={1} Failed={2}" -f $updated, $skipped, $failed)
}
# Emit objects (final collected set)
return $collected

View File

@@ -1,100 +0,0 @@
<#
.SYNOPSIS
Produce an incremental PR CSV containing rows present in a newer full export but absent from a baseline export.
.DESCRIPTION
Compares two previously generated sorted PR CSV files (same schema). Any row whose key column value
(defaults to 'Number') does not exist in the baseline file is emitted to a new incremental CSV, preserving
the original column order. If no new rows are found, an empty CSV (with headers when determinable) is written.
.PARAMETER BaseCsv
Path to the baseline (earlier) PR CSV.
.PARAMETER AllCsv
Path to the newer full PR CSV containing superset (or equal set) of rows.
.PARAMETER OutCsv
Path to write the incremental CSV containing only new rows.
.PARAMETER Key
Column name used as unique identifier (defaults to 'Number'). Must exist in both CSVs.
.EXAMPLE
pwsh ./diff_prs.ps1 -BaseCsv sorted_prs_prev.csv -AllCsv sorted_prs.csv -OutCsv sorted_prs_incremental.csv
.NOTES
Requires: PowerShell 7+, both CSVs with identical column schemas.
Exit code 0 on success (even if zero incremental rows). Throws on missing files.
#>
[CmdletBinding()] param(
[Parameter(Mandatory=$false)][string]$BaseCsv = "./sorted_prs_93_round1.csv",
[Parameter(Mandatory=$false)][string]$AllCsv = "./sorted_prs.csv",
[Parameter(Mandatory=$false)][string]$OutCsv = "./sorted_prs_93_incremental.csv",
[Parameter(Mandatory=$false)][string]$Key = "Number"
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Write-Info($m) { Write-Host "[info] $m" -ForegroundColor Cyan }
function Write-Warn($m) { Write-Host "[warn] $m" -ForegroundColor Yellow }
if (-not (Test-Path -LiteralPath $BaseCsv)) { throw "Base CSV not found: $BaseCsv" }
if (-not (Test-Path -LiteralPath $AllCsv)) { throw "All CSV not found: $AllCsv" }
# Load CSVs
$baseRows = Import-Csv -LiteralPath $BaseCsv
$allRows = Import-Csv -LiteralPath $AllCsv
if (-not $baseRows) { Write-Warn "Base CSV has no rows." }
if (-not $allRows) { Write-Warn "All CSV has no rows." }
# Validate key presence
if ($baseRows -and -not ($baseRows[0].PSObject.Properties.Name -contains $Key)) { throw "Key column '$Key' not found in base CSV." }
if ($allRows -and -not ($allRows[0].PSObject.Properties.Name -contains $Key)) { throw "Key column '$Key' not found in all CSV." }
# Build a set of existing keys from base
$set = New-Object 'System.Collections.Generic.HashSet[string]'
foreach ($row in $baseRows) {
$val = [string]($row.$Key)
if ($null -ne $val) { [void]$set.Add($val) }
}
# Filter rows in AllCsv whose key is not in base (these are the new / incremental rows)
$incremental = @()
foreach ($row in $allRows) {
$val = [string]($row.$Key)
if (-not $set.Contains($val)) { $incremental += $row }
}
# Preserve column order from the All CSV
$columns = @()
if ($allRows.Count -gt 0) {
$columns = $allRows[0].PSObject.Properties.Name
}
try {
if ($incremental.Count -gt 0) {
if ($columns.Count -gt 0) {
$incremental | Select-Object -Property $columns | Export-Csv -LiteralPath $OutCsv -NoTypeInformation -Encoding UTF8
} else {
$incremental | Export-Csv -LiteralPath $OutCsv -NoTypeInformation -Encoding UTF8
}
} else {
# Write an empty CSV with headers if we know them (facilitates downstream tooling expecting header row)
if ($columns.Count -gt 0) {
$obj = [PSCustomObject]@{}
foreach ($c in $columns) { $obj | Add-Member -NotePropertyName $c -NotePropertyValue $null }
$obj | Select-Object -Property $columns | Export-Csv -LiteralPath $OutCsv -NoTypeInformation -Encoding UTF8
} else {
'' | Out-File -LiteralPath $OutCsv -Encoding UTF8
}
}
Write-Info ("Incremental rows: {0}" -f $incremental.Count)
Write-Info ("Output: {0}" -f (Resolve-Path -LiteralPath $OutCsv))
}
catch {
Write-Host "[error] Failed writing output CSV: $_" -ForegroundColor Red
exit 1
}

View File

@@ -1,344 +0,0 @@
<#
.SYNOPSIS
Export merged PR metadata between two commits (exclusive start, inclusive end) to JSON and CSV.
.DESCRIPTION
Identifies merge/squash commits reachable from EndCommit but not StartCommit, extracts PR numbers,
queries GitHub for metadata plus (optionally) Copilot review/comment summaries, filters labels, then
emits a JSON artifact and a sorted CSV (first label alphabetical).
.PARAMETER StartCommit
Exclusive starting commit (SHA, tag, or ref). Commits AFTER this one are considered.
.PARAMETER EndCommit
Inclusive ending commit (SHA, tag, or ref). If not provided, uses origin/<Branch> when Branch is set; otherwise uses HEAD.
.PARAMETER Repo
GitHub repository (owner/name). Default: microsoft/PowerToys.
.PARAMETER OutputCsv
Destination CSV path. Default: sorted_prs.csv.
.PARAMETER OutputJson
Destination JSON path containing raw PR objects. Default: milestone_prs.json.
.EXAMPLE
pwsh ./dump-prs-since-commit.ps1 -StartCommit 0123abcd -Branch stable
.EXAMPLE
pwsh ./dump-prs-since-commit.ps1 -StartCommit 0123abcd -EndCommit 89ef7654 -OutputCsv delta.csv
.NOTES
Requires: git, gh (authenticated). No Set-StrictMode to keep parity with existing release scripts.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)][string]$StartCommit, # exclusive start (commits AFTER this one)
[string]$EndCommit,
[string]$Branch,
[string]$Repo = "microsoft/PowerToys",
[string]$OutputDir,
[string]$OutputCsv = "sorted_prs.csv",
[string]$OutputJson = "milestone_prs.json"
)
<#
.SYNOPSIS
Dump merged PR information whose merge commits are reachable from EndCommit but not from StartCommit.
.DESCRIPTION
Uses git rev-list to compute commits in the (StartCommit, EndCommit] range, extracts PR numbers from merge commit messages,
queries GitHub (gh CLI) for details, then outputs a CSV.
PR merge commit messages in PowerToys generally contain patterns like:
Merge pull request #12345 from ...
.EXAMPLE
pwsh ./dump-prs-since-commit.ps1 -StartCommit 0123abcd -Branch stable
.EXAMPLE
pwsh ./dump-prs-since-commit.ps1 -StartCommit 0123abcd -EndCommit 89ef7654 -OutputCsv changes.csv
.NOTES
Requires: gh CLI authenticated; git available in working directory (must be inside PowerToys repo clone).
CopilotSummary behavior:
- Attempts to locate the latest GitHub Copilot authored review (preferred).
- If no review is found, lazily fetches PR comments to look for a Copilot-authored comment.
- Normalizes whitespace and strips newlines. Empty when no Copilot activity detected.
- Run with -Verbose to see whether the summary came from a 'review' or 'comment' source.
#>
function Write-Info($msg) { Write-Host $msg -ForegroundColor Cyan }
function Write-Warn($msg) { Write-Host $msg -ForegroundColor Yellow }
function Write-Err($msg) { Write-Host $msg -ForegroundColor Red }
function Write-DebugMsg($msg) { if ($PSBoundParameters.ContainsKey('Verbose') -or $VerbosePreference -eq 'Continue') { Write-Host "[VERBOSE] $msg" -ForegroundColor DarkGray } }
# Load member list from Generated Files/ReleaseNotes/MemberList.md (internal team - no thanks needed)
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$repoRoot = Resolve-Path (Join-Path $scriptDir "..\..\..\..")
$defaultMemberListPath = Join-Path $repoRoot "Generated Files\ReleaseNotes\MemberList.md"
$memberListPath = $defaultMemberListPath
if ($OutputDir) {
$memberListFromOutputDir = Join-Path $OutputDir "MemberList.md"
if (Test-Path $memberListFromOutputDir) {
$memberListPath = $memberListFromOutputDir
}
}
$memberList = @()
if (Test-Path $memberListPath) {
$memberListContent = Get-Content $memberListPath -Raw
# Extract usernames - skip markdown code fence lines, get all non-empty lines
$memberList = ($memberListContent -split "`n") | Where-Object { $_ -notmatch '^\s*```' -and $_.Trim() -ne '' } | ForEach-Object { $_.Trim() }
if (-not $memberList -or $memberList.Count -eq 0) {
Write-Err "MemberList.md is empty at $memberListPath"
exit 1
}
Write-DebugMsg "Loaded $($memberList.Count) members from MemberList.md"
} else {
Write-Err "MemberList.md not found at $memberListPath"
exit 1
}
# Validate we are in a git repo
#if (-not (Test-Path .git)) {
# Write-Err "Current directory does not appear to be the root of a git repository."
# exit 1
#}
# Resolve output directory (if specified)
if ($OutputDir) {
if (-not (Test-Path $OutputDir)) {
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
}
if (-not [System.IO.Path]::IsPathRooted($OutputCsv)) {
$OutputCsv = Join-Path $OutputDir $OutputCsv
}
if (-not [System.IO.Path]::IsPathRooted($OutputJson)) {
$OutputJson = Join-Path $OutputDir $OutputJson
}
}
# Resolve commits
try {
if ($Branch) {
Write-Info "Fetching latest '$Branch' from origin (with tags)..."
git fetch origin $Branch --tags | Out-Null
if ($LASTEXITCODE -ne 0) { throw "git fetch origin $Branch --tags failed" }
}
$startSha = (git rev-parse --verify $StartCommit) 2>$null
if (-not $startSha) { throw "StartCommit '$StartCommit' not found" }
if ($Branch) {
$branchRef = $Branch
$branchSha = (git rev-parse --verify $branchRef) 2>$null
if (-not $branchSha) {
$branchRef = "origin/$Branch"
$branchSha = (git rev-parse --verify $branchRef) 2>$null
}
if (-not $branchSha) { throw "Branch '$Branch' not found" }
if (-not $PSBoundParameters.ContainsKey('EndCommit') -or [string]::IsNullOrWhiteSpace($EndCommit)) {
$EndCommit = $branchRef
}
}
if (-not $PSBoundParameters.ContainsKey('EndCommit') -or [string]::IsNullOrWhiteSpace($EndCommit)) {
$EndCommit = "HEAD"
}
$endSha = (git rev-parse --verify $EndCommit) 2>$null
if (-not $endSha) { throw "EndCommit '$EndCommit' not found" }
}
catch {
Write-Err $_
exit 1
}
Write-Info "Collecting commits between $startSha..$endSha (excluding start, including end)."
# Get list of commits reachable from end but not from start.
# IMPORTANT: In PowerShell, the .. operator creates a numeric/char range. If $startSha and $endSha look like hex strings,
# `$startSha..$endSha` must be passed as a single string argument.
$rangeArg = "$startSha..$endSha"
$commitList = git rev-list $rangeArg
# Normalize list (filter out empty strings)
$normalizedCommits = $commitList | Where-Object { $_ -and $_.Trim() -ne '' }
$commitCount = ($normalizedCommits | Measure-Object).Count
Write-DebugMsg ("Raw commitList length (including blanks): {0}" -f (($commitList | Measure-Object).Count))
Write-DebugMsg ("Normalized commit count: {0}" -f $commitCount)
if ($commitCount -eq 0) {
Write-Warn "No commits found in specified range ($startSha..$endSha)."; exit 0
}
Write-DebugMsg ("First 5 commits: {0}" -f (($normalizedCommits | Select-Object -First 5) -join ', '))
<#
Extract PR numbers from commits.
Patterns handled:
1. Merge commits: 'Merge pull request #12345 from ...'
2. Squash commits: 'Some feature change (#12345)' (GitHub default squash format)
We collect both. If a commit matches both (unlikely), it's deduped later.
#>
# Extract PR numbers from merge or squash commits
$mergeCommits = @()
foreach ($c in $normalizedCommits) {
$subject = git show -s --format=%s $c
$matched = $false
# Pattern 1: Traditional merge commit
if ($subject -match 'Merge pull request #([0-9]+) ') {
$prNumber = [int]$matches[1]
$mergeCommits += [PSCustomObject]@{ Sha = $c; Pr = $prNumber; Subject = $subject; Pattern = 'merge' }
Write-DebugMsg "Matched merge PR #$prNumber in commit $c"
$matched = $true
}
# Pattern 2: Squash merge subject line with ' (#12345)' at end (allow possible whitespace before paren)
if ($subject -match '\(#([0-9]+)\)$') {
$prNumber2 = [int]$matches[1]
# Avoid duplicate object if pattern 1 already captured same number for same commit
if (-not ($mergeCommits | Where-Object { $_.Sha -eq $c -and $_.Pr -eq $prNumber2 })) {
$mergeCommits += [PSCustomObject]@{ Sha = $c; Pr = $prNumber2; Subject = $subject; Pattern = 'squash' }
Write-DebugMsg "Matched squash PR #$prNumber2 in commit $c"
}
$matched = $true
}
if (-not $matched) {
Write-DebugMsg "No PR pattern in commit $c : $subject"
}
}
if (-not $mergeCommits -or $mergeCommits.Count -eq 0) {
Write-Warn "No merge commits with PR numbers found in range."; exit 0
}
# Deduplicate PR numbers (in case of revert or merges across branches)
$prNumbers = $mergeCommits | Select-Object -ExpandProperty Pr -Unique | Sort-Object
Write-Info ("Found {0} unique PRs: {1}" -f $prNumbers.Count, ($prNumbers -join ', '))
Write-DebugMsg ("Total merge commits examined: {0}" -f $mergeCommits.Count)
# Query GitHub for each PR
$prDetails = @()
function Get-CopilotSummaryFromPrJson {
param(
[Parameter(Mandatory=$true)]$PrJson,
[switch]$VerboseMode
)
# Returns a hashtable with Summary and Source keys.
$result = @{ Summary = ""; Source = "" }
if (-not $PrJson) { return $result }
$candidateAuthors = @(
'github-copilot[bot]', 'github-copilot', 'copilot'
)
# 1. Reviews (preferred) pick the LONGEST valid Copilot body, not the most recent
$reviews = $PrJson.reviews
if ($reviews) {
$copilotReviews = $reviews | Where-Object {
($candidateAuthors -contains $_.author.login -or $_.author.login -like '*copilot*') -and $_.body -and $_.body.Trim() -ne ''
}
if ($copilotReviews) {
$longest = $copilotReviews | Sort-Object { $_.body.Length } -Descending | Select-Object -First 1
if ($longest) {
$body = $longest.body
$norm = ($body -replace "`r", '') -replace "`n", ' '
$norm = $norm -replace '\s+', ' '
$result.Summary = $norm
$result.Source = 'review'
if ($VerboseMode) { Write-DebugMsg "Selected Copilot review length=$($body.Length) (longest)." }
return $result
}
}
}
# 2. Comments fallback (some repos surface Copilot summaries as PR comments rather than review objects)
if ($null -eq $PrJson.comments) {
try {
# Lazy fetch comments only if needed
$commentsJson = gh pr view $PrJson.number --repo $Repo --json comments 2>$null | ConvertFrom-Json
if ($commentsJson -and $commentsJson.comments) {
$PrJson | Add-Member -NotePropertyName comments -NotePropertyValue $commentsJson.comments -Force
}
} catch {
if ($VerboseMode) { Write-DebugMsg "Failed to fetch comments for PR #$($PrJson.number): $_" }
}
}
if ($PrJson.comments) {
$copilotComments = $PrJson.comments | Where-Object {
($candidateAuthors -contains $_.author.login -or $_.author.login -like '*copilot*') -and $_.body -and $_.body.Trim() -ne ''
}
if ($copilotComments) {
$longestC = $copilotComments | Sort-Object { $_.body.Length } -Descending | Select-Object -First 1
if ($longestC) {
$body = $longestC.body
$norm = ($body -replace "`r", '') -replace "`n", ' '
$norm = $norm -replace '\s+', ' '
$result.Summary = $norm
$result.Source = 'comment'
if ($VerboseMode) { Write-DebugMsg "Selected Copilot comment length=$($body.Length) (longest)." }
return $result
}
}
}
return $result
}
foreach ($pr in $prNumbers) {
Write-Info "Fetching PR #$pr ..."
try {
# Include comments only if Verbose asked; if not, we lazily pull when reviews are missing
$fields = 'number,title,labels,author,url,body,reviews'
if ($PSBoundParameters.ContainsKey('Verbose')) { $fields += ',comments' }
$json = gh pr view $pr --repo $Repo --json $fields 2>$null | ConvertFrom-Json
if ($null -eq $json) { throw "Empty response" }
$copilot = Get-CopilotSummaryFromPrJson -PrJson $json -VerboseMode:($PSBoundParameters.ContainsKey('Verbose'))
if ($copilot.Summary -and $copilot.Source -and $PSBoundParameters.ContainsKey('Verbose')) {
Write-DebugMsg "Copilot summary source=$($copilot.Source) chars=$($copilot.Summary.Length)"
} elseif (-not $copilot.Summary) {
Write-DebugMsg "No Copilot summary found for PR #$pr"
}
# Filter labels
$filteredLabels = $json.labels | Where-Object {
($_.name -like "Product-*") -or
($_.name -like "Area-*") -or
($_.name -like "GitHub*") -or
($_.name -like "*Plugin") -or
($_.name -like "Issue-*")
}
$labelNames = ($filteredLabels | ForEach-Object { $_.name }) -join ", "
$bodyValue = if ($json.body) { ($json.body -replace "`r", '') -replace "`n", ' ' } else { '' }
$bodyValue = $bodyValue -replace '\s+', ' '
# Determine if author needs thanks (not in member list)
$authorLogin = $json.author.login
$needThanks = $true
if ($memberList.Count -gt 0 -and $authorLogin) {
$needThanks = -not ($memberList -contains $authorLogin)
}
$prDetails += [PSCustomObject]@{
Id = $json.number
Title = $json.title
Labels = $labelNames
Author = $authorLogin
Url = $json.url
Body = $bodyValue
CopilotSummary = $copilot.Summary
NeedThanks = $needThanks
}
}
catch {
$err = $_
Write-Warn ("Failed to fetch PR #{0}: {1}" -f $pr, $err)
}
}
if (-not $prDetails) { Write-Warn "No PR details fetched."; exit 0 }
# Sort by Labels like original script (first label alphabetical)
$sorted = $prDetails | Sort-Object { ($_.Labels -split ',')[0] }
# Output JSON raw (optional)
$sorted | ConvertTo-Json -Depth 6 | Out-File -Encoding UTF8 $OutputJson
Write-Info "Saving CSV to $OutputCsv ..."
$sorted | Export-Csv $OutputCsv -NoTypeInformation
Write-Host "✅ Done. Generated $($prDetails.Count) PR rows." -ForegroundColor Green

View File

@@ -1,80 +0,0 @@
<#
.SYNOPSIS
Find a commit on a branch that has the same subject line as a reference commit.
.DESCRIPTION
Given a commit SHA (often from a release tag) and a branch name, this script
resolves the reference commit's subject, then searches the branch history for
commits with the exact same subject line. Useful when the release tag commit
is not reachable from your current branch history.
.PARAMETER Commit
The reference commit SHA or ref (e.g., v0.96.1 or a full SHA).
.PARAMETER Branch
The branch to search (e.g., stable or main). Defaults to stable.
.PARAMETER RepoPath
Path to the local repo. Defaults to current directory.
.EXAMPLE
pwsh ./find-commit-by-title.ps1 -Commit b62f6421845f7e5c92b8186868d98f46720db442 -Branch stable
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)][string]$Commit,
[string]$Branch = "stable",
[string]$RepoPath = "."
)
function Write-Info($msg) { Write-Host $msg -ForegroundColor Cyan }
function Write-Err($msg) { Write-Host $msg -ForegroundColor Red }
Push-Location $RepoPath
try {
Write-Info "Fetching latest '$Branch' from origin (with tags)..."
git fetch origin $Branch --tags | Out-Null
if ($LASTEXITCODE -ne 0) { throw "git fetch origin $Branch --tags failed" }
$commitSha = (git rev-parse --verify $Commit) 2>$null
if (-not $commitSha) { throw "Commit '$Commit' not found" }
$subject = (git show -s --format=%s $commitSha) 2>$null
if (-not $subject) { throw "Unable to read subject for '$commitSha'" }
$branchRef = $Branch
$branchSha = (git rev-parse --verify $branchRef) 2>$null
if (-not $branchSha) {
$branchRef = "origin/$Branch"
$branchSha = (git rev-parse --verify $branchRef) 2>$null
}
if (-not $branchSha) { throw "Branch '$Branch' not found" }
Write-Info "Reference commit: $commitSha"
Write-Info "Reference title: $subject"
Write-Info "Searching branch: $branchRef"
$matches = git log $branchRef --format="%H|%s" | Where-Object { $_ -match '\|' }
$results = @()
foreach ($line in $matches) {
$parts = $line -split '\|', 2
if ($parts.Count -eq 2 -and $parts[1] -eq $subject) {
$results += [PSCustomObject]@{ Sha = $parts[0]; Title = $parts[1] }
}
}
if (-not $results -or $results.Count -eq 0) {
Write-Info "No matching commit found on $branchRef for the given title."
exit 0
}
Write-Info ("Found {0} matching commit(s):" -f $results.Count)
$results | ForEach-Object { Write-Host ("{0} {1}" -f $_.Sha, $_.Title) }
}
catch {
Write-Err $_
exit 1
}
finally {
Pop-Location
}

View File

@@ -1,85 +0,0 @@
<#
.SYNOPSIS
Group PR rows by their Labels column and emit per-label CSV files.
.DESCRIPTION
Reads a milestone PR CSV (usually produced by dump-prs-information / dump-prs-since-commit scripts),
splits rows by label list, normalizes/sorts individual labels, and writes one CSV per unique label combination.
Each output preserves the original row ordering within that subset and column order from the source.
.PARAMETER CsvPath
Input CSV containing PR rows with a 'Labels' column (comma-separated list).
.PARAMETER OutDir
Output directory to place grouped CSVs (created if missing). Default: 'grouped_csv'.
.NOTES
Label combinations are joined using ' | ' when multiple labels present. Filenames are sanitized (invalid characters,
whitespace collapsed) and truncated to <= 120 characters.
#>
param(
[string]$CsvPath = "sorted_prs.csv",
[string]$OutDir = "grouped_csv"
)
$ErrorActionPreference = 'Stop'
function Write-Info($msg) { Write-Host "[info] $msg" -ForegroundColor Cyan }
function Write-Warn($msg) { Write-Host "[warn] $msg" -ForegroundColor Yellow }
if (-not (Test-Path -LiteralPath $CsvPath)) { throw "CSV not found: $CsvPath" }
Write-Info "Reading CSV: $CsvPath"
$rows = Import-Csv -LiteralPath $CsvPath
Write-Info ("Loaded {0} rows" -f $rows.Count)
function ConvertTo-SafeFileName {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)][string]$Name
)
if ([string]::IsNullOrWhiteSpace($Name)) { return 'Unnamed' }
$s = $Name -replace '[<>:"/\\|?*]', '-' # invalid path chars
$s = $s -replace '\s+', '-' # spaces to dashes
$s = $s -replace '-{2,}', '-' # collapse dashes
$s = $s.Trim('-')
if ($s.Length -gt 120) { $s = $s.Substring(0,120).Trim('-') }
if ([string]::IsNullOrWhiteSpace($s)) { return 'Unnamed' }
return $s
}
# Build groups keyed by normalized, sorted label combinations. Preserve original CSV row order.
$groups = @{}
foreach ($row in $rows) {
$labelsRaw = $row.Labels
if ([string]::IsNullOrWhiteSpace($labelsRaw)) {
$labelParts = @('Unlabeled')
} else {
$parts = $labelsRaw -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ }
if (-not $parts -or $parts.Count -eq 0) { $labelParts = @('Unlabeled') }
else { $labelParts = $parts | Sort-Object }
}
$key = ($labelParts -join ' | ')
if (-not $groups.ContainsKey($key)) { $groups[$key] = New-Object System.Collections.ArrayList }
[void]$groups[$key].Add($row)
}
if (-not (Test-Path -LiteralPath $OutDir)) {
Write-Info "Creating output directory: $OutDir"
New-Item -ItemType Directory -Path $OutDir | Out-Null
}
Write-Info ("Generating {0} grouped CSV file(s) into: {1}" -f $groups.Count, $OutDir)
foreach ($key in $groups.Keys) {
$labelParts = if ($key -eq 'Unlabeled') { @('Unlabeled') } else { $key -split '\s\|\s' }
$safeName = ($labelParts | ForEach-Object { ConvertTo-SafeFileName -Name $_ }) -join '-'
$filePath = Join-Path $OutDir ("$safeName.csv")
# Keep same columns and order
$groups[$key] | Export-Csv -LiteralPath $filePath -NoTypeInformation -Encoding UTF8
}
Write-Info "Done. Sample output files:"
Get-ChildItem -LiteralPath $OutDir | Select-Object -First 10 Name | Format-Table -HideTableHeaders

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,126 +0,0 @@
---
name: submit-pr
description: Commit changes and create pull requests for fixed issues. Use when asked to create a PR, submit changes, commit fixes, push changes for an issue, create pull request from worktree, or finalize issue fix. Generates AI-assisted commit messages and PR descriptions following PowerToys conventions.
license: Complete terms in LICENSE.txt
---
# Submit PR Skill
Commit changes from issue worktrees and create pull requests with AI-generated titles and descriptions following PowerToys conventions.
## Skill Contents
This skill is **self-contained** with all required resources:
```
.github/skills/submit-pr/
├── SKILL.md # This file
├── LICENSE.txt # MIT License
├── scripts/
│ └── Submit-IssueFixes.ps1 # Main submit script
└── references/
├── create-commit-title.prompt.md # Commit title rules
└── create-pr-summary.prompt.md # PR description template
```
## Output
PRs are created on GitHub with:
- Conventional commit title (e.g., `fix(fancyzones): resolve editor crash on multi-monitor`)
- Description following `.github/pull_request_template.md`
- Auto-linked to the original issue via `Fixes #{{IssueNumber}}`
## When to Use This Skill
- Create a PR for a fixed issue
- Commit and push changes from a worktree
- Submit changes after using `issue-fix` skill
- Generate PR title and description
- Finalize an issue fix with a pull request
## Prerequisites
- GitHub CLI (`gh`) installed and authenticated
- Changes made in an issue worktree (from `issue-fix` skill)
- PowerShell 7+ for running scripts
## Required Variables
| Variable | Description | Example |
|----------|-------------|---------|
| `{{IssueNumber}}` | Issue number(s) to submit | `44044` or `44044, 32950` |
## Workflow
### Step 1: Verify Changes Exist
Check that the worktree has uncommitted or unpushed changes:
```powershell
# List issue worktrees
git worktree list | Select-String "issue/"
# Check status in a worktree
cd Q:/PowerToys-xxxx
git status
```
### Step 2: Submit PR
Execute the submit script (use paths relative to this skill folder):
```powershell
# From repo root
.github/skills/submit-pr/scripts/Submit-IssueFixes.ps1 -IssueNumbers {{IssueNumber}} -CLIType copilot
```
This will:
1. Generate a commit title using AI (following conventional commits)
2. Stage and commit all changes
3. Push the branch to origin
4. Generate a PR description using AI
5. Create the PR on GitHub
### Step 3: Review Created PR
The script outputs the PR URL. Review it on GitHub.
## CLI Options
| Parameter | Description | Default |
|-----------|-------------|---------|
| `-IssueNumbers` | Issue number(s) to submit | All worktrees |
| `-CLIType` | AI CLI to use: `copilot`, `claude`, or `manual` | `copilot` |
| `-TargetBranch` | Base branch for PR | `main` |
| `-Draft` | Create as draft PR | `false` |
| `-Force` | Skip confirmation prompts | `false` |
| `-DryRun` | Show what would be done | `false` |
## PR Title Format
Titles follow conventional commits (see `references/create-commit-title.prompt.md`):
```
<type>(<scope>): <description>
```
| Type | When to use |
|------|-------------|
| `fix` | Bug fixes |
| `feat` | New features |
| `docs` | Documentation only |
| `refactor` | Code restructuring |
## AI Prompt References
For manual AI invocation, prompts are at:
- `references/create-commit-title.prompt.md` - Commit title generation
- `references/create-pr-summary.prompt.md` - PR description generation
## Troubleshooting
| Problem | Solution |
|---------|----------|
| No changes to commit | Verify fix was applied, check `git status` |
| PR already exists | Script will skip and report existing PR URL |
| Push rejected | Pull latest changes or force push with `--force-with-lease` |

View File

@@ -1,49 +0,0 @@
---
agent: 'agent'
description: 'Generate an 80-character git commit title for the local diff'
---
# Generate Commit Title
## Purpose
Provide a single-line, ready-to-paste git commit title (<= 80 characters) that reflects the most important local changes since `HEAD`.
## Input to collect
- Run exactly one command to view the local diff:
```@terminal
git diff HEAD
```
## How to decide the title
1. From the diff, find the dominant area (e.g., `src/modules/*`, `doc/devdocs/**`) and the change type (bug fix, docs update, config tweak).
2. Draft an imperative, plain-ASCII title that:
- Mentions the primary component when obvious (e.g., `FancyZones:` or `Docs:`)
- Stays within 80 characters and has no trailing punctuation
## Final output
- Reply with only the commit title on a single line—no extra text.
## PR title convention (when asked)
Use Conventional Commits style:
`<type>(<scope>): <summary>`
**Allowed types**
- feat, fix, docs, refactor, perf, test, build, ci, chore
**Scope rules**
- Use a short, PowerToys-focused scope (one word preferred). Common scopes:
- Core: `runner`, `settings-ui`, `common`, `docs`, `build`, `ci`, `installer`, `gpo`, `dsc`
- Modules: `fancyzones`, `powerrename`, `awake`, `colorpicker`, `imageresizer`, `keyboardmanager`, `mouseutils`, `peek`, `hosts`, `file-locksmith`, `screen-ruler`, `text-extractor`, `cropandlock`, `paste`, `powerlauncher`
- If unclear, pick the closest module or subsystem; omit only if unavoidable
**Summary rules**
- Imperative, present tense (“add”, “update”, “remove”, “fix”)
- Keep it <= 72 characters when possible; be specific, avoid “misc changes”
**Examples**
- `feat(fancyzones): add canvas template duplication`
- `fix(mouseutils): guard crosshair toggle when dpi info missing`
- `docs(runner): document tray icon states`
- `build(installer): align wix v5 suffix flag`
- `ci(ci): cache pipeline artifacts for x64`

View File

@@ -1,24 +0,0 @@
---
agent: 'agent'
description: 'Generate a PowerToys-ready pull request description from the local diff'
---
# Generate PR Summary
**Goal:** Produce a ready-to-paste PR title and description that follows PowerToys conventions by comparing the current branch against a user-selected target branch.
**Repo guardrails:**
- Treat `.github/pull_request_template.md` as the single source of truth; load it at runtime instead of embedding hardcoded content in this prompt.
- Preserve section order from the template but only surface checklist lines that are relevant for the detected changes, filling them with `[x]`/`[ ]` as appropriate.
- Cite touched paths with inline backticks, matching the guidance in `.github/copilot-instructions.md`.
- Call out test coverage explicitly: list automated tests run (unit/UI) or state why they are not applicable.
**Workflow:**
1. Determine the target branch from user context; default to `main` when no branch is supplied.
2. Run `git status --short` once to surface uncommitted files that may influence the summary.
3. Run `git diff <target-branch>...HEAD` a single time to review the detailed changes. Only when confidence stays low dig deeper with focused calls such as `git diff <target-branch>...HEAD -- <path>`.
4. From the diff, capture impacted areas, key file changes, behavioral risks, migrations, and noteworthy edge cases.
5. Confirm validation: list tests executed with results or state why tests were skipped in line with repo guidance.
6. Load `.github/pull_request_template.md`, mirror its section order, and populate it with the gathered facts. Include only relevant checklist entries, marking them `[x]/[ ]` and noting any intentional omissions as "N/A".
7. Present the filled template inside a fenced ```markdown code block with no extra commentary so it is ready to paste into a PR, clearly flagging any placeholders that still need user input.
8. Prepend the PR title above the filled template, applying the Conventional Commit type/scope rules from `.github/prompts/create-commit-title.prompt.md`; pick the dominant component from the diff and keep the title concise and imperative.

View File

@@ -1,9 +0,0 @@
{
"mcpServers": {
"github-artifacts": {
"command": "cmd",
"args": ["/c", "for /f %i in ('git rev-parse --show-toplevel') do node %i/tools/mcp/github-artifacts/launch.js"],
"tools": ["*"]
}
}
}

View File

@@ -1,18 +0,0 @@
# IssueReviewLib.ps1 - Minimal helpers for PR submission workflow
# Part of the PowerToys GitHub Copilot/Claude Code issue review system
# This is a trimmed version - submit-pr only needs console helpers and repo root
#region Console Output Helpers
function Info { param([string]$Message) Write-Host $Message -ForegroundColor Cyan }
function Warn { param([string]$Message) Write-Host $Message -ForegroundColor Yellow }
function Err { param([string]$Message) Write-Host $Message -ForegroundColor Red }
function Success { param([string]$Message) Write-Host $Message -ForegroundColor Green }
#endregion
#region Repository Helpers
function Get-RepoRoot {
$root = git rev-parse --show-toplevel 2>$null
if (-not $root) { throw 'Not inside a git repository.' }
return (Resolve-Path $root).Path
}
#endregion

View File

@@ -1,559 +0,0 @@
<#!
.SYNOPSIS
Commit and create PRs for completed issue fixes in worktrees.
.DESCRIPTION
For each specified issue (or all issue worktrees), commits changes using AI-generated
commit messages and creates PRs with AI-generated summaries, linking to the original issue.
.PARAMETER IssueNumbers
Array of issue numbers to submit. If not specified, processes all issue/* worktrees.
.PARAMETER DryRun
Show what would be done without actually committing or creating PRs.
.PARAMETER SkipCommit
Skip the commit step (assume changes are already committed).
.PARAMETER SkipPush
Skip pushing to remote (useful for testing).
.PARAMETER TargetBranch
Target branch for the PR. Default: main.
.PARAMETER CLIType
AI CLI to use for generating messages: copilot, claude, or manual. Default: copilot.
.PARAMETER Draft
Create PRs as drafts.
.EXAMPLE
# Submit all issue worktrees
./Submit-IssueFixes.ps1
.EXAMPLE
# Submit specific issues
./Submit-IssueFixes.ps1 -IssueNumbers 44044, 44480
.EXAMPLE
# Dry run to see what would happen
./Submit-IssueFixes.ps1 -DryRun
.EXAMPLE
# Create draft PRs
./Submit-IssueFixes.ps1 -Draft
.NOTES
Prerequisites:
- Worktrees created by Start-IssueAutoFix.ps1
- Changes made in the worktrees
- GitHub CLI (gh) authenticated
- Copilot CLI or Claude Code CLI
#>
[CmdletBinding()]
param(
[int[]]$IssueNumbers,
[switch]$DryRun,
[switch]$SkipCommit,
[switch]$SkipPush,
[string]$TargetBranch = 'main',
[ValidateSet('copilot', 'claude', 'manual')]
[string]$CLIType = 'copilot',
[switch]$Draft,
[switch]$Force,
[switch]$Help
)
# Load libraries
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
. "$scriptDir/IssueReviewLib.ps1"
# Load worktree library
$repoRoot = Get-RepoRoot
$worktreeLib = Join-Path $repoRoot 'tools/build/WorktreeLib.ps1'
if (Test-Path $worktreeLib) {
. $worktreeLib
}
if ($Help) {
Get-Help $MyInvocation.MyCommand.Path -Full
return
}
function Get-AIGeneratedCommitTitle {
<#
.SYNOPSIS
Generate commit title using AI CLI with create-commit-title prompt.
#>
param(
[Parameter(Mandatory)]
[string]$WorktreePath,
[string]$CLIType = 'copilot'
)
$promptFile = Join-Path $repoRoot '.github/prompts/create-commit-title.prompt.md'
if (-not (Test-Path $promptFile)) {
throw "Prompt file not found: $promptFile"
}
$prompt = "Follow the instructions in .github/prompts/create-commit-title.prompt.md to generate a commit title for the current changes. Output ONLY the commit title, nothing else."
# MCP config for github-artifacts tools (relative to repo root)
$mcpConfig = '@.github/skills/submit-pr/references/mcp-config.json'
Push-Location $WorktreePath
try {
switch ($CLIType) {
'copilot' {
$result = & copilot --additional-mcp-config $mcpConfig -p $prompt --yolo -s 2>&1
# Extract just the title line (last non-empty line that looks like a title)
$lines = $result -split "`n" | Where-Object { $_.Trim() -and $_ -notmatch '^\s*```' -and $_ -notmatch '^\s*#' }
$title = $lines | Select-Object -Last 1
return $title.Trim()
}
'claude' {
$result = & claude --print --dangerously-skip-permissions --prompt $prompt 2>&1
$lines = $result -split "`n" | Where-Object { $_.Trim() -and $_ -notmatch '^\s*```' }
$title = $lines | Select-Object -Last 1
return $title.Trim()
}
'manual' {
# Show diff and ask user for title
git diff HEAD --stat
return Read-Host "Enter commit title"
}
}
} finally {
Pop-Location
}
}
function Get-AIGeneratedPRSummary {
<#
.SYNOPSIS
Generate PR summary using AI CLI with create-pr-summary prompt.
#>
param(
[Parameter(Mandatory)]
[string]$WorktreePath,
[Parameter(Mandatory)]
[int]$IssueNumber,
[string]$TargetBranch = 'main',
[string]$CLIType = 'copilot'
)
$prompt = @"
Follow the instructions in .github/prompts/create-pr-summary.prompt.md to generate a PR summary.
Target branch: $TargetBranch
This PR fixes issue #$IssueNumber.
IMPORTANT:
1. Output the PR title on the first line
2. Then output the PR body in markdown format
3. Make sure to include "Fixes #$IssueNumber" in the body to auto-link the issue
"@
# MCP config for github-artifacts tools (relative to repo root)
$mcpConfig = '@.github/skills/submit-pr/references/mcp-config.json'
Push-Location $WorktreePath
try {
switch ($CLIType) {
'copilot' {
$result = & copilot --additional-mcp-config $mcpConfig -p $prompt --yolo -s 2>&1
return $result -join "`n"
}
'claude' {
$result = & claude --print --dangerously-skip-permissions --prompt $prompt 2>&1
return $result -join "`n"
}
'manual' {
git diff "$TargetBranch...HEAD" --stat
$title = Read-Host "Enter PR title"
$body = Read-Host "Enter PR body (or press Enter for default)"
if (-not $body) {
$body = "Fixes #$IssueNumber"
}
return "$title`n`n$body"
}
}
} finally {
Pop-Location
}
}
function Parse-PRContent {
<#
.SYNOPSIS
Parse AI output to extract PR title and body.
Expected format:
Line 1: feat(scope): title text
Line 2+: ```markdown
## Summary...
```
#>
param(
[Parameter(Mandatory)]
[string]$Content,
[int]$IssueNumber
)
$lines = $Content -split "`n"
# Title is the FIRST line that looks like a conventional commit
# Body is the content INSIDE the ```markdown ... ``` block
$title = $null
$body = $null
# Find title - first line matching conventional commit format
foreach ($line in $lines) {
$trimmed = $line.Trim()
if ($trimmed -match '^(feat|fix|docs|refactor|perf|test|build|ci|chore)(\([^)]+\))?:') {
$title = $trimmed -replace '^#+\s*', ''
break
}
}
# Fallback title
if (-not $title) {
$title = "fix: address issue #$IssueNumber"
}
# Extract body from markdown code block
$fullContent = $Content
if ($fullContent -match '```markdown\r?\n([\s\S]*?)\r?\n```') {
$body = $Matches[1].Trim()
} else {
# No markdown block - use everything after the title line
$titleIndex = [array]::IndexOf($lines, ($lines | Where-Object { $_.Trim() -eq $title } | Select-Object -First 1))
if ($titleIndex -ge 0 -and $titleIndex -lt $lines.Count - 1) {
$body = ($lines[($titleIndex + 1)..($lines.Count - 1)] -join "`n").Trim()
# Clean up any remaining code fences
$body = $body -replace '^```\w*\r?\n', '' -replace '\r?\n```\s*$', ''
} else {
$body = ""
}
}
# Ensure issue link is present
if ($body -notmatch "Fixes\s*#$IssueNumber" -and $body -notmatch "Closes\s*#$IssueNumber" -and $body -notmatch "Resolves\s*#$IssueNumber") {
$body = "$body`n`nFixes #$IssueNumber"
}
return @{
Title = $title
Body = $body
}
}
function Submit-IssueFix {
<#
.SYNOPSIS
Commit changes, push, and create PR for a single issue.
#>
param(
[Parameter(Mandatory)]
[int]$IssueNumber,
[Parameter(Mandatory)]
[string]$WorktreePath,
[Parameter(Mandatory)]
[string]$Branch,
[string]$TargetBranch = 'main',
[string]$CLIType = 'copilot',
[switch]$DryRun,
[switch]$SkipCommit,
[switch]$SkipPush,
[switch]$Draft
)
Push-Location $WorktreePath
try {
# Check for changes
$status = git status --porcelain
$hasUncommitted = $status.Count -gt 0
# Check for commits ahead of target
git fetch origin $TargetBranch 2>$null
$commitsAhead = git rev-list --count "origin/$TargetBranch..$Branch" 2>$null
if (-not $commitsAhead) { $commitsAhead = 0 }
Info "Issue #$IssueNumber in $WorktreePath"
Info " Branch: $Branch"
Info " Uncommitted changes: $hasUncommitted"
Info " Commits ahead of $TargetBranch`: $commitsAhead"
if (-not $hasUncommitted -and $commitsAhead -eq 0) {
Warn " No changes to submit for issue #$IssueNumber"
return @{ IssueNumber = $IssueNumber; Status = 'NoChanges' }
}
# Step 1: Commit if there are uncommitted changes
if ($hasUncommitted -and -not $SkipCommit) {
Info " Generating commit title..."
if ($DryRun) {
Info " [DRY RUN] Would generate commit title and commit changes"
} else {
$commitTitle = Get-AIGeneratedCommitTitle -WorktreePath $WorktreePath -CLIType $CLIType
if (-not $commitTitle) {
throw "Failed to generate commit title"
}
Info " Commit title: $commitTitle"
# Stage all changes and commit
git add -A
git commit -m $commitTitle
if ($LASTEXITCODE -ne 0) {
throw "Git commit failed"
}
Success " ✓ Changes committed"
}
}
# Step 2: Push to remote
if (-not $SkipPush) {
if ($DryRun) {
Info " [DRY RUN] Would push branch $Branch to origin"
} else {
Info " Pushing to origin..."
git push -u origin $Branch 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) {
# Try force push if normal push fails (branch might have been reset)
Warn " Normal push failed, trying force push..."
git push -u origin $Branch --force-with-lease 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) {
throw "Git push failed"
}
}
Success " ✓ Pushed to origin"
}
}
# Step 3: Create PR
Info " Generating PR summary..."
if ($DryRun) {
Info " [DRY RUN] Would generate PR summary and create PR"
Info " [DRY RUN] PR would link to issue #$IssueNumber"
return @{ IssueNumber = $IssueNumber; Status = 'DryRun' }
}
# Check if PR already exists
$existingPR = gh pr list --head $Branch --json number,url 2>$null | ConvertFrom-Json
if ($existingPR -and $existingPR.Count -gt 0) {
Warn " PR already exists: $($existingPR[0].url)"
return @{ IssueNumber = $IssueNumber; Status = 'PRExists'; PRUrl = $existingPR[0].url }
}
$prContent = Get-AIGeneratedPRSummary -WorktreePath $WorktreePath -IssueNumber $IssueNumber -TargetBranch $TargetBranch -CLIType $CLIType
$parsed = Parse-PRContent -Content $prContent -IssueNumber $IssueNumber
if (-not $parsed.Title) {
throw "Failed to generate PR title"
}
Info " PR Title: $($parsed.Title)"
# Create PR using gh CLI
$ghArgs = @(
'pr', 'create',
'--base', $TargetBranch,
'--head', $Branch,
'--title', $parsed.Title,
'--body', $parsed.Body
)
if ($Draft) {
$ghArgs += '--draft'
}
$prResult = & gh @ghArgs 2>&1
if ($LASTEXITCODE -ne 0) {
throw "Failed to create PR: $prResult"
}
# Extract PR URL from result
$prUrl = $prResult | Select-String -Pattern 'https://github.com/[^\s]+' | ForEach-Object { $_.Matches[0].Value }
Success " ✓ PR created: $prUrl"
return @{
IssueNumber = $IssueNumber
Status = 'Success'
PRUrl = $prUrl
CommitTitle = $commitTitle
PRTitle = $parsed.Title
}
}
catch {
Err " ✗ Failed: $($_.Exception.Message)"
return @{
IssueNumber = $IssueNumber
Status = 'Failed'
Error = $_.Exception.Message
}
}
finally {
Pop-Location
}
}
#region Main Script
try {
Info "Repository root: $repoRoot"
Info "Target branch: $TargetBranch"
Info "CLI type: $CLIType"
# Get all issue worktrees
$allWorktrees = Get-WorktreeEntries | Where-Object { $_.Branch -like 'issue/*' }
if ($allWorktrees.Count -eq 0) {
Warn "No issue worktrees found. Run Start-IssueAutoFix.ps1 first."
return
}
# Filter to specified issues if provided
$worktreesToProcess = @()
if ($IssueNumbers -and $IssueNumbers.Count -gt 0) {
foreach ($issueNum in $IssueNumbers) {
$wt = $allWorktrees | Where-Object { $_.Branch -match "issue/$issueNum\b" }
if ($wt) {
$worktreesToProcess += $wt
} else {
Warn "No worktree found for issue #$issueNum"
}
}
} else {
$worktreesToProcess = $allWorktrees
}
if ($worktreesToProcess.Count -eq 0) {
Warn "No worktrees to process."
return
}
# Display worktrees to process
Info "`nWorktrees to submit:"
Info ("-" * 80)
foreach ($wt in $worktreesToProcess) {
# Extract issue number from branch name
if ($wt.Branch -match 'issue/(\d+)') {
$issueNum = $Matches[1]
Info " #$issueNum -> $($wt.Path) [$($wt.Branch)]"
}
}
Info ("-" * 80)
if ($DryRun) {
Warn "`nDry run mode - no changes will be made."
}
# Confirm before proceeding
if (-not $Force -and -not $DryRun) {
$confirm = Read-Host "`nProceed with submitting $($worktreesToProcess.Count) fixes? (y/N)"
if ($confirm -notmatch '^[yY]') {
Info "Cancelled."
return
}
}
# Process each worktree
$results = @{
Success = @()
Failed = @()
NoChanges = @()
PRExists = @()
DryRun = @()
}
foreach ($wt in $worktreesToProcess) {
if ($wt.Branch -match 'issue/(\d+)') {
$issueNum = [int]$Matches[1]
Info "`n" + ("=" * 60)
Info "SUBMITTING ISSUE #$issueNum"
Info ("=" * 60)
$result = Submit-IssueFix `
-IssueNumber $issueNum `
-WorktreePath $wt.Path `
-Branch $wt.Branch `
-TargetBranch $TargetBranch `
-CLIType $CLIType `
-DryRun:$DryRun `
-SkipCommit:$SkipCommit `
-SkipPush:$SkipPush `
-Draft:$Draft
switch ($result.Status) {
'Success' { $results.Success += $result }
'Failed' { $results.Failed += $result }
'NoChanges' { $results.NoChanges += $result }
'PRExists' { $results.PRExists += $result }
'DryRun' { $results.DryRun += $result }
}
}
}
# Summary
Info "`n" + ("=" * 80)
Info "SUBMISSION COMPLETE"
Info ("=" * 80)
Info "Total worktrees: $($worktreesToProcess.Count)"
if ($results.Success.Count -gt 0) {
Success "PRs created: $($results.Success.Count)"
foreach ($r in $results.Success) {
Success " #$($r.IssueNumber): $($r.PRUrl)"
}
}
if ($results.PRExists.Count -gt 0) {
Warn "PRs already exist: $($results.PRExists.Count)"
foreach ($r in $results.PRExists) {
Warn " #$($r.IssueNumber): $($r.PRUrl)"
}
}
if ($results.NoChanges.Count -gt 0) {
Warn "No changes: $($results.NoChanges.Count)"
Warn " Issues: $($results.NoChanges.IssueNumber -join ', ')"
}
if ($results.Failed.Count -gt 0) {
Err "Failed: $($results.Failed.Count)"
foreach ($r in $results.Failed) {
Err " #$($r.IssueNumber): $($r.Error)"
}
}
if ($results.DryRun.Count -gt 0) {
Info "Dry run: $($results.DryRun.Count)"
}
Info ("=" * 80)
return $results
}
catch {
Err "Error: $($_.Exception.Message)"
exit 1
}
#endregion

View File

@@ -21,6 +21,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4

View File

@@ -27,7 +27,7 @@ jobs:
issue: ${{ fromJson(github.event.inputs.issue_numbers) }}
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v3
- name: Run GenAI Issue Deduplicator
uses: pelikhan/action-genai-issue-dedup@v0

1
.gitignore vendored
View File

@@ -359,4 +359,3 @@ src/common/Telemetry/*.etl
# PowerToysInstaller Build Temp Files
installer/*/*.wxs.bk
/src/modules/awake/.claude

View File

@@ -60,8 +60,6 @@
"PowerToys.FancyZonesEditorCommon.dll",
"PowerToys.FancyZonesModuleInterface.dll",
"PowerToys.FancyZones.exe",
"FancyZonesCLI.exe",
"FancyZonesCLI.dll",
"PowerToys.GcodePreviewHandler.dll",
"PowerToys.GcodePreviewHandler.exe",
@@ -117,7 +115,6 @@
"WinUI3Apps\\PowerToys.FileLocksmithUI.dll",
"WinUI3Apps\\PowerToys.FileLocksmithContextMenu.dll",
"FileLocksmithContextMenuPackage.msix",
"FileLocksmithCLI.exe",
"WinUI3Apps\\Peek.Common.dll",
"WinUI3Apps\\Peek.FilePreviewer.dll",
@@ -125,10 +122,6 @@
"WinUI3Apps\\Powertoys.Peek.UI.exe",
"WinUI3Apps\\Powertoys.Peek.dll",
"WinUI3Apps\\PowerToys.QuickAccess.dll",
"WinUI3Apps\\PowerToys.QuickAccess.exe",
"WinUI3Apps\\PowerToys.Settings.UI.Controls.dll",
"WinUI3Apps\\PowerToys.EnvironmentVariablesModuleInterface.dll",
"WinUI3Apps\\PowerToys.EnvironmentVariablesUILib.dll",
"WinUI3Apps\\PowerToys.EnvironmentVariables.dll",
@@ -136,8 +129,6 @@
"PowerToys.ImageResizer.exe",
"PowerToys.ImageResizer.dll",
"WinUI3Apps\\PowerToys.ImageResizerCLI.exe",
"WinUI3Apps\\PowerToys.ImageResizerCLI.dll",
"PowerToys.ImageResizerExt.dll",
"PowerToys.ImageResizerContextMenu.dll",
"ImageResizerContextMenuPackage.msix",
@@ -242,14 +233,6 @@
"PowerToys.CmdPalModuleInterface.dll",
"CmdPalKeyboardService.dll",
"PowerToys.ModuleContracts.dll",
"Awake.ModuleServices.dll",
"ColorPicker.ModuleServices.dll",
"Workspaces.ModuleServices.dll",
"Microsoft.CommandPalette.Extensions.dll",
"Microsoft.CommandPalette.Extensions.Toolkit.dll",
"Microsoft.CmdPal.Ext.PowerToys.dll",
"Microsoft.CmdPal.Ext.PowerToys.exe",
"*Microsoft.CmdPal.UI_*.msix",
"PowerToys.DSC.dll",
@@ -308,7 +291,6 @@
"Mono.Cecil.Rocks.dll",
"Newtonsoft.Json.dll",
"CommunityToolkit.WinUI.Controls.TitleBar.dll",
"CommunityToolkit.WinUI.Controls.OpacityMaskView.dll",
"NLog.dll",
"HtmlAgilityPack.dll",
@@ -368,18 +350,9 @@
"Microsoft.SemanticKernel.Connectors.Ollama.dll",
"OllamaSharp.dll",
"boost_regex-vc143-mt-gd-x32-1_87.dll",
"boost_regex-vc143-mt-gd-x64-1_87.dll",
"boost_regex-vc143-mt-x32-1_87.dll",
"boost_regex-vc143-mt-x64-1_87.dll",
"Microsoft.ML.OnnxRuntime.dll",
"UnitsNet.dll",
"UtfUnknown.dll",
"Wpf.Ui.dll",
"Shmuelie.WinRTServer.dll",
"ToolGood.Words.Pinyin.dll"
"Wpf.Ui.dll"
],
"SigningInfo": {
"Operations": [

View File

@@ -1,7 +1,7 @@
Param(
# Using the default value of 1.7 for winAppSdkVersionNumber and useExperimentalVersion as false
[Parameter(Mandatory=$False,Position=1)]
[string]$winAppSdkVersionNumber = "1.8",
[string]$winAppSdkVersionNumber = "1.7",
# When the pipeline calls the PS1 file, the passed parameters are converted to string type
[Parameter(Mandatory=$False,Position=2)]
@@ -16,7 +16,32 @@ Param(
[string]$sourceLink = "https://microsoft.pkgs.visualstudio.com/ProjectReunion/_packaging/Project.Reunion.nuget.internal/nuget/v3/index.json"
)
function Update-NugetConfig {
param (
[string]$filePath = [System.IO.Path]::Combine($rootPath, "nuget.config")
)
Write-Host "Updating nuget.config file"
[xml]$xml = Get-Content -Path $filePath
# Add localpackages source into nuget.config
$packageSourcesNode = $xml.configuration.packageSources
$addNode = $xml.CreateElement("add")
$addNode.SetAttribute("key", "localpackages")
$addNode.SetAttribute("value", "localpackages")
$packageSourcesNode.AppendChild($addNode) | Out-Null
# Remove <packageSourceMapping> tag and its content
$packageSourceMappingNode = $xml.configuration.packageSourceMapping
if ($packageSourceMappingNode) {
$xml.configuration.RemoveChild($packageSourceMappingNode) | Out-Null
}
# print nuget.config after modification
$xml.OuterXml
# Save the modified nuget.config file
$xml.Save($filePath)
}
function Read-FileWithEncoding {
param (
@@ -46,132 +71,6 @@ function Write-FileWithEncoding {
$writer.Close()
}
function Add-NuGetSourceAndMapping {
param (
[xml]$Xml,
[string]$Key,
[string]$Value,
[string[]]$Patterns
)
# Ensure packageSources exists
if (-not $Xml.configuration.packageSources) {
$Xml.configuration.AppendChild($Xml.CreateElement("packageSources")) | Out-Null
}
$sources = $Xml.configuration.packageSources
# Add/Update Source
$sourceNode = $sources.SelectSingleNode("add[@key='$Key']")
if (-not $sourceNode) {
$sourceNode = $Xml.CreateElement("add")
$sourceNode.SetAttribute("key", $Key)
$sources.AppendChild($sourceNode) | Out-Null
}
$sourceNode.SetAttribute("value", $Value)
# Ensure packageSourceMapping exists
if (-not $Xml.configuration.packageSourceMapping) {
$Xml.configuration.AppendChild($Xml.CreateElement("packageSourceMapping")) | Out-Null
}
$mapping = $Xml.configuration.packageSourceMapping
# Remove invalid packageSource nodes (missing key or empty key)
$invalidNodes = $mapping.SelectNodes("packageSource[not(@key) or @key='']")
if ($invalidNodes) {
foreach ($node in $invalidNodes) {
$mapping.RemoveChild($node) | Out-Null
}
}
# Add/Update Mapping Source
$mappingSource = $mapping.SelectSingleNode("packageSource[@key='$Key']")
if (-not $mappingSource) {
$mappingSource = $Xml.CreateElement("packageSource")
$mappingSource.SetAttribute("key", $Key)
# Insert at top for priority
if ($mapping.HasChildNodes) {
$mapping.InsertBefore($mappingSource, $mapping.FirstChild) | Out-Null
} else {
$mapping.AppendChild($mappingSource) | Out-Null
}
}
# Double check and force attribute
if (-not $mappingSource.HasAttribute("key")) {
$mappingSource.SetAttribute("key", $Key)
}
# Update Patterns
# RemoveAll() removes all child nodes AND attributes, so we must re-set the key afterwards
$mappingSource.RemoveAll()
$mappingSource.SetAttribute("key", $Key)
foreach ($pattern in $Patterns) {
$pkg = $Xml.CreateElement("package")
$pkg.SetAttribute("pattern", $pattern)
$mappingSource.AppendChild($pkg) | Out-Null
}
}
function Resolve-WinAppSdkSplitDependencies {
Write-Host "Version $WinAppSDKVersion detected. Resolving split dependencies..."
$installDir = Join-Path $rootPath "localpackages\output"
New-Item -ItemType Directory -Path $installDir -Force | Out-Null
# Create a temporary nuget.config to avoid interference from the repo's config
$tempConfig = Join-Path $env:TEMP "nuget_$(Get-Random).config"
Set-Content -Path $tempConfig -Value "<?xml version='1.0' encoding='utf-8'?><configuration><packageSources><clear /><add key='TempSource' value='$sourceLink' /></packageSources></configuration>"
try {
# Extract BuildTools version from Directory.Packages.props to ensure we have the required version
$dirPackagesProps = Join-Path $rootPath "Directory.Packages.props"
if (Test-Path $dirPackagesProps) {
$propsContent = Get-Content $dirPackagesProps -Raw
if ($propsContent -match '<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="([^"]+)"') {
$buildToolsVersion = $Matches[1]
Write-Host "Downloading Microsoft.Windows.SDK.BuildTools version $buildToolsVersion..."
$nugetArgsBuildTools = "install Microsoft.Windows.SDK.BuildTools -Version $buildToolsVersion -ConfigFile $tempConfig -OutputDirectory $installDir -NonInteractive -NoCache"
Invoke-Expression "nuget $nugetArgsBuildTools" | Out-Null
}
}
# Download package to inspect nuspec and keep it for the build
$nugetArgs = "install Microsoft.WindowsAppSDK -Version $WinAppSDKVersion -ConfigFile $tempConfig -OutputDirectory $installDir -NonInteractive -NoCache"
Invoke-Expression "nuget $nugetArgs" | Out-Null
# Parse dependencies from the installed folders
# Folder structure is typically {PackageId}.{Version}
$directories = Get-ChildItem -Path $installDir -Directory
$allLocalPackages = @()
foreach ($dir in $directories) {
# Match any package pattern: PackageId.Version
if ($dir.Name -match "^(.+?)\.(\d+\..*)$") {
$pkgId = $Matches[1]
$pkgVer = $Matches[2]
$allLocalPackages += $pkgId
$packageVersions[$pkgId] = $pkgVer
Write-Host "Found dependency: $pkgId = $pkgVer"
}
}
# Update repo's nuget.config to use localpackages
$nugetConfig = Join-Path $rootPath "nuget.config"
$configData = Read-FileWithEncoding -Path $nugetConfig
[xml]$xml = $configData.Content
Add-NuGetSourceAndMapping -Xml $xml -Key "localpackages" -Value $installDir -Patterns $allLocalPackages
$xml.Save($nugetConfig)
Write-Host "Updated nuget.config with localpackages mapping."
} catch {
Write-Warning "Failed to resolve dependencies: $_"
} finally {
Remove-Item $tempConfig -Force -ErrorAction SilentlyContinue
}
}
# Execute nuget list and capture the output
if ($useExperimentalVersion) {
# The nuget list for experimental versions will cost more time
@@ -213,36 +112,56 @@ if ($latestVersion) {
exit 1
}
# Resolve dependencies for 1.8+
$packageVersions = @{ "Microsoft.WindowsAppSDK" = $WinAppSDKVersion }
Resolve-WinAppSdkSplitDependencies
# Update packages.config files
Get-ChildItem -Path $rootPath -Recurse packages.config | ForEach-Object {
$file = Read-FileWithEncoding -Path $_.FullName
$content = $file.Content
if ($content -match 'package id="Microsoft.WindowsAppSDK"') {
$newVersionString = 'package id="Microsoft.WindowsAppSDK" version="' + $WinAppSDKVersion + '"'
$oldVersionString = 'package id="Microsoft.WindowsAppSDK" version="[-.0-9a-zA-Z]*"'
$content = $content -replace $oldVersionString, $newVersionString
Write-FileWithEncoding -Path $_.FullName -Content $content -Encoding $file.encoding
Write-Host "Modified " $_.FullName
}
}
# Update Directory.Packages.props file
Get-ChildItem -Path $rootPath -Recurse "Directory.Packages.props" | ForEach-Object {
$file = Read-FileWithEncoding -Path $_.FullName
$content = $file.Content
$isModified = $false
foreach ($pkgId in $packageVersions.Keys) {
$ver = $packageVersions[$pkgId]
# Escape dots in package ID for regex
$pkgIdRegex = $pkgId -replace '\.', '\.'
$newVersionString = "<PackageVersion Include=""$pkgId"" Version=""$ver"" />"
$oldVersionString = "<PackageVersion Include=""$pkgIdRegex"" Version=""[-.0-9a-zA-Z]*"" />"
if ($content -match "<PackageVersion Include=""$pkgIdRegex""") {
# Update existing package
if ($content -notmatch [regex]::Escape($newVersionString)) {
$content = $content -replace $oldVersionString, $newVersionString
$isModified = $true
}
}
}
if ($isModified) {
if ($content -match '<PackageVersion Include="Microsoft.WindowsAppSDK"') {
$newVersionString = '<PackageVersion Include="Microsoft.WindowsAppSDK" Version="' + $WinAppSDKVersion + '" />'
$oldVersionString = '<PackageVersion Include="Microsoft.WindowsAppSDK" Version="[-.0-9a-zA-Z]*" />'
$content = $content -replace $oldVersionString, $newVersionString
Write-FileWithEncoding -Path $_.FullName -Content $content -Encoding $file.encoding
Write-Host "Modified " $_.FullName
}
}
# Update .vcxproj files
Get-ChildItem -Path $rootPath -Recurse *.vcxproj | ForEach-Object {
$file = Read-FileWithEncoding -Path $_.FullName
$content = $file.Content
if ($content -match '\\Microsoft.WindowsAppSDK.') {
$newVersionString = '\Microsoft.WindowsAppSDK.' + $WinAppSDKVersion
$oldVersionString = '\\Microsoft.WindowsAppSDK.(?=[-.0-9a-zA-Z]*\d)[-.0-9a-zA-Z]*' #positive lookahead for at least a digit
$content = $content -replace $oldVersionString, $newVersionString
Write-FileWithEncoding -Path $_.FullName -Content $content -Encoding $file.encoding
Write-Host "Modified " $_.FullName
}
}
# Update .csproj files
Get-ChildItem -Path $rootPath -Recurse *.csproj | ForEach-Object {
$file = Read-FileWithEncoding -Path $_.FullName
$content = $file.Content
if ($content -match 'PackageReference Include="Microsoft.WindowsAppSDK"') {
$newVersionString = 'PackageReference Include="Microsoft.WindowsAppSDK" Version="'+ $WinAppSDKVersion + '"'
$oldVersionString = 'PackageReference Include="Microsoft.WindowsAppSDK" Version="[-.0-9a-zA-Z]*"'
$content = $content -replace $oldVersionString, $newVersionString
Write-FileWithEncoding -Path $_.FullName -Content $content -Encoding $file.encoding
Write-Host "Modified " $_.FullName
}
}
Update-NugetConfig

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.PowerToys.Telemetry" version="2.0.4" />
<package id="Microsoft.PowerToys.Telemetry" version="2.0.3" />
</packages>

View File

@@ -19,7 +19,7 @@ parameters:
- name: enableMsBuildCaching
type: boolean
displayName: "Enable MSBuild Caching"
default: false
default: true
- name: runTests
type: boolean
displayName: "Run Tests"
@@ -33,7 +33,7 @@ parameters:
default: true
- name: winAppSDKVersionNumber
type: string
default: 1.8
default: 1.7
- name: useExperimentalVersion
type: boolean
default: false

View File

@@ -35,9 +35,7 @@ stages:
${{ else }}:
name: SHINE-OSS-L
${{ if eq(parameters.useVSPreview, true) }}:
demands: ImageOverride -equals SHINE-VS18-Preview
${{ else }}:
demands: ImageOverride -equals SHINE-VS18-Latest
demands: ImageOverride -equals SHINE-VS17-Preview
buildPlatforms:
- ${{ parameters.platform }}
buildConfigurations: [Release]

View File

@@ -51,9 +51,7 @@ extends:
pool:
name: SHINE-INT-S
${{ if eq(parameters.useVSPreview, true) }}:
demands: ImageOverride -equals SHINE-VS18-Preview
${{ else }}:
demands: ImageOverride -equals SHINE-VS18-Latest
demands: ImageOverride -equals SHINE-VS17-Preview
os: windows
sdl:
tsa:
@@ -76,9 +74,7 @@ extends:
demands:
# Our INT agents have a large disk mounted at P:\
- ${{ if eq(parameters.useVSPreview, true) }}:
- ImageOverride -equals SHINE-VS18-Latest-Preview
- ${{ else }}:
- ImageOverride -equals SHINE-VS18-Latest
- ImageOverride -equals SHINE-VS17-Preview
os: windows
variables:
IsPipeline: 1 # The installer uses this to detect whether it should pick up localizations
@@ -91,7 +87,6 @@ extends:
official: true
codeSign: true
runTests: false
buildTests: false
signingIdentity:
serviceName: $(SigningServiceName)
appId: $(SigningAppId)

View File

@@ -129,7 +129,7 @@ jobs:
MSBuildMainBuildTargets: Build
${{ insert }}: ${{ parameters.variables }}
${{ if eq(parameters.useLatestWinAppSDK, true) }}:
RestoreAdditionalProjectSourcesArg: '/p:RestoreAdditionalProjectSources="$(Build.SourcesDirectory)\localpackages\NugetPackages" /p:IgnoreExperimentalWarnings=true'
RestoreAdditionalProjectSourcesArg: '/p:RestoreAdditionalProjectSources="$(Build.SourcesDirectory)\localpackages\NugetPackages"'
${{ else }}:
RestoreAdditionalProjectSourcesArg: ''
displayName: Build
@@ -192,14 +192,14 @@ jobs:
displayName: Verify XAML formatting
- pwsh: |-
& '.pipelines/verifyNugetPackages.ps1' -solution '$(build.sourcesdirectory)\PowerToys.slnx'
displayName: Verify Nuget package versions for PowerToys.slnx
& '.pipelines/verifyNugetPackages.ps1' -solution '$(build.sourcesdirectory)\PowerToys.sln'
displayName: Verify Nuget package versions for PowerToys.sln
- pwsh: |-
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\PowerToys.slnx'
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\PowerToys.sln'
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\tools\BugReportTool\BugReportTool.sln'
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\tools\StylesReportTool\StylesReportTool.sln'
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\installer\PowerToysSetup.slnx'
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\installer\PowerToysSetup.sln'
displayName: Verify ARM64 configurations
- ${{ if eq(parameters.enablePackageCaching, true) }}:
@@ -252,13 +252,12 @@ jobs:
${{ else }}:
displayName: Build PowerToys main project
inputs:
solution: 'PowerToys.slnx'
vsVersion: 18.0
solution: 'PowerToys.sln'
vsVersion: 17.0
msbuildArgs: >-
-restore -graph
/p:RestorePackagesConfig=true
/p:CIBuild=true
/p:BuildTests=${{ parameters.buildTests }}
/bl:$(LogOutputDirectory)\build-0-main.binlog
${{ parameters.additionalBuildOptions }}
$(MSBuildCacheParameters)
@@ -276,8 +275,8 @@ jobs:
displayName: Generate DSC artifacts for ARM64
condition: and(succeeded(), eq(variables['BuildPlatform'], 'arm64'))
inputs:
solution: PowerToys.slnx
vsVersion: 18.0
solution: PowerToys.sln
vsVersion: 17.0
msbuildArgs: >-
-restore
/p:Configuration=$(BuildConfiguration)
@@ -339,7 +338,7 @@ jobs:
displayName: Build BugReportTool
inputs:
solution: '**/tools/BugReportTool/BugReportTool.sln'
vsVersion: 18.0
vsVersion: 17.0
msbuildArgs: >-
-restore -graph
/p:RestorePackagesConfig=true
@@ -360,7 +359,7 @@ jobs:
displayName: Build StylesReportTool
inputs:
solution: '**/tools/StylesReportTool/StylesReportTool.sln'
vsVersion: 18.0
vsVersion: 17.0
msbuildArgs: >-
-restore -graph
/p:RestorePackagesConfig=true
@@ -382,7 +381,7 @@ jobs:
displayName: Publish ${{ project }} for Packaging
inputs:
solution: ${{ project }}
vsVersion: 18.0
vsVersion: 17.0
msbuildArgs: >-
/target:Publish
/graph
@@ -505,14 +504,6 @@ jobs:
Remove-Item -Force -Recurse "$(JobOutputDirectory)/_appx" -ErrorAction:Ignore
displayName: Re-pack the new CmdPal package after signing
- pwsh: |
$testsPath = "$(Build.SourcesDirectory)/$(BuildPlatform)/$(BuildConfiguration)/tests"
if (Test-Path $testsPath) {
Remove-Item -Path $testsPath -Recurse -Force
Write-Host "Removed tests folder to reduce signing workload: $testsPath"
}
displayName: Remove tests folder before signing
- template: steps-esrp-signing.yml
parameters:
displayName: Sign Core PowerToys
@@ -633,4 +624,4 @@ jobs:
- publish: $(JobOutputDirectory)
artifact: $(JobOutputArtifactName)-failure-$(System.JobAttempt)
displayName: Publish failure logs
condition: or(failed(), canceled())
condition: or(failed(), canceled())

View File

@@ -68,13 +68,14 @@ jobs:
- template: .\steps-restore-nuget.yml
- task: MSBuild@1
- task: NuGetCommand@2
displayName: Restore solution-level NuGet packages
inputs:
solution: PowerToys.slnx
msbuildArguments: '/t:restore /p:RestorePackagesConfig=true'
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
command: restore
feedsToUse: config
configPath: nuget.config
restoreSolution: PowerToys.sln
restoreDirectory: '$(Build.SourcesDirectory)\packages'
# Build all UI test projects if no specific modules are specified
- ${{ if eq(length(parameters.uiTestModules), 0) }}:
@@ -82,7 +83,7 @@ jobs:
displayName: Build UI Test Projects
inputs:
solution: '**/*UITest*.csproj'
vsVersion: 18.0
vsVersion: 17.0
msbuildArgs: >-
-restore
-graph
@@ -103,7 +104,7 @@ jobs:
displayName: 'Build UI Test Module: ${{ module }}'
inputs:
solution: '**/*${{ module }}*.csproj'
vsVersion: 18.0
vsVersion: 17.0
msbuildArgs: >-
-restore
-graph
@@ -128,4 +129,4 @@ jobs:
- publish: $(JobOutputDirectory)
artifact: $(JobOutputArtifactName)
displayName: Publish UI Test artifacts
condition: always()
condition: always()

View File

@@ -49,9 +49,7 @@ stages:
${{ else }}:
name: SHINE-OSS-L
${{ if eq(parameters.useVSPreview, true) }}:
demands: ImageOverride -equals SHINE-VS18-Preview
${{ else }}:
demands: ImageOverride -equals SHINE-VS18-Latest
demands: ImageOverride -equals SHINE-VS17-Preview
buildPlatforms:
- ${{ platform }}
buildConfigurations: [Release]
@@ -59,29 +57,9 @@ stages:
enableMsBuildCaching: ${{ parameters.enableMsBuildCaching }}
msBuildCacheIsReadOnly: ${{ parameters.msBuildCacheIsReadOnly }}
runTests: ${{ parameters.runTests }}
buildTests: true
useVSPreview: ${{ parameters.useVSPreview }}
useLatestWinAppSDK: ${{ parameters.useLatestWinAppSDK }}
${{ if eq(parameters.useLatestWinAppSDK, true) }}:
winAppSDKVersionNumber: ${{ parameters.winAppSDKVersionNumber }}
useExperimentalVersion: ${{ parameters.useExperimentalVersion }}
timeoutInMinutes: 90
- stage: Build_SDK
displayName: Build Command Palette Toolkit SDK
dependsOn: []
jobs:
- template: job-build-sdk.yml
parameters:
pool:
${{ if eq(variables['System.CollectionId'], 'cb55739e-4afe-46a3-970f-1b49d8ee7564') }}:
name: SHINE-INT-L
${{ else }}:
name: SHINE-OSS-L
${{ if eq(parameters.useVSPreview, true) }}:
demands: ImageOverride -equals SHINE-VS18-Preview
${{ else }}:
demands: ImageOverride -equals SHINE-VS18-Latest
buildConfigurations: [Release]
official: false
codeSign: false

View File

@@ -29,9 +29,7 @@ stages:
${{ else }}:
name: SHINE-OSS-L
${{ if eq(parameters.useVSPreview, true) }}:
demands: ImageOverride -equals SHINE-VS18-Preview
${{ else }}:
demands: ImageOverride -equals SHINE-VS18-Latest
demands: ImageOverride -equals SHINE-VS17-Preview
buildPlatforms:
- ${{ parameters.platform }}
buildConfigurations: [Release]

View File

@@ -35,8 +35,8 @@ steps:
- task: VSBuild@1
displayName: Build Shared Support DLLs
inputs:
solution: "**/installer/PowerToysSetup.slnx"
vsVersion: 18.0
solution: "**/installer/PowerToysSetup.sln"
vsVersion: 17.0
msbuildArgs: >-
/t:PowerToysSetupCustomActionsVNext;SilentFilesInUseBAFunction
/p:RunBuildEvents=true;RestorePackagesConfig=true;CIBuild=true
@@ -74,8 +74,8 @@ steps:
- task: VSBuild@1
displayName: 💻 Build VNext MSI
inputs:
solution: "**/installer/PowerToysSetup.slnx"
vsVersion: 18.0
solution: "**/installer/PowerToysSetup.sln"
vsVersion: 17.0
msbuildArgs: >-
-restore
/t:PowerToysInstallerVNext
@@ -91,8 +91,8 @@ steps:
- task: VSBuild@1
displayName: 👤 Build VNext MSI
inputs:
solution: "**/installer/PowerToysSetup.slnx"
vsVersion: 18.0
solution: "**/installer/PowerToysSetup.sln"
vsVersion: 17.0
msbuildArgs: >-
/t:PowerToysInstallerVNext
/p:RunBuildEvents=false;PerUser=true;BuildProjectReferences=false;CIBuild=true
@@ -142,8 +142,8 @@ steps:
- task: VSBuild@1
displayName: 💻 Build VNext Bootstrapper
inputs:
solution: "**/installer/PowerToysSetup.slnx"
vsVersion: 18.0
solution: "**/installer/PowerToysSetup.sln"
vsVersion: 17.0
msbuildArgs: >-
-restore
/t:PowerToysBootstrapperVNext
@@ -159,8 +159,8 @@ steps:
- task: VSBuild@1
displayName: 👤 Build VNext Bootstrapper
inputs:
solution: "**/installer/PowerToysSetup.slnx"
vsVersion: 18.0
solution: "**/installer/PowerToysSetup.sln"
vsVersion: 17.0
msbuildArgs: >-
/t:PowerToysBootstrapperVNext
/p:PerUser=true;BuildProjectReferences=false;CIBuild=true

View File

@@ -10,7 +10,7 @@ parameters:
default: {}
steps:
- task: EsrpCodeSigning@6
- task: EsrpCodeSigning@5
displayName: 🔏 ${{ parameters.displayName }}
inputs:
ConnectedServiceName: ${{ parameters.signingIdentity.serviceName }}

View File

@@ -19,20 +19,39 @@ steps:
-useExperimentalVersion $${{ parameters.useExperimentalVersion }}
-rootPath "$(build.sourcesdirectory)"
# - task: NuGetCommand@2
# displayName: 'Restore NuGet packages (slnx)'
# inputs:
# command: 'restore'
# feedsToUse: 'config'
# nugetConfigPath: '$(build.sourcesdirectory)\nuget.config'
# restoreSolution: '$(build.sourcesdirectory)\**\*.slnx'
# includeNuGetOrg: false
- script: echo $(WinAppSDKVersion)
displayName: 'Display WinAppSDK Version Found'
- task: DotNetCoreCLI@2
displayName: 'Restore NuGet packages (dotnet)'
- task: DownloadPipelineArtifact@2
displayName: 'Download WindowsAppSDK'
inputs:
buildType: 'specific'
project: '55e8140e-57ac-4e5f-8f9c-c7c15b51929d'
definition: '104083'
buildVersionToDownload: 'latestFromBranch'
branchName: 'refs/heads/release/${{ parameters.versionNumber }}-stable'
artifactName: 'WindowsAppSDK_Nuget_And_MSIX'
targetPath: '$(Build.SourcesDirectory)\localpackages'
- script: dir $(Build.SourcesDirectory)\localpackages\NugetPackages
displayName: 'List downloaded packages'
- task: NuGetCommand@2
displayName: 'Install WindowsAppSDK'
inputs:
command: 'custom'
arguments: >
install "Microsoft.WindowsAppSDK"
-Source "$(Build.SourcesDirectory)\localpackages\NugetPackages"
-Version "$(WinAppSDKVersion)"
-OutputDirectory "$(Build.SourcesDirectory)\localpackages\output"
-FallbackSource "https://microsoft.pkgs.visualstudio.com/ProjectReunion/_packaging/Project.Reunion.nuget.internal/nuget/v3/index.json"
- task: NuGetCommand@2
displayName: 'Restore NuGet packages'
inputs:
command: 'restore'
projects: '$(build.sourcesdirectory)\**\*.slnx'
feedsToUse: 'config'
nugetConfigPath: '$(build.sourcesdirectory)\nuget.config'
workingDirectory: '$(build.sourcesdirectory)'
restoreSolution: '$(build.sourcesdirectory)\**\*.sln'
includeNuGetOrg: false

View File

@@ -1,16 +1,9 @@
# Build common vswhere base arguments
$vsWhereBaseArgs = @('-latest', '-requires', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64')
if ($env:VCWhereExtraVersionTarget) {
# Add version target if specified (e.g., '-version [18.0,19.0)' for VS2026)
$vsWhereBaseArgs += $env:VCWhereExtraVersionTarget.Split(' ')
}
$VSInstances = ([xml](& 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' @vsWhereBaseArgs -include packages -format xml))
$VSInstances = ([xml](& 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -include packages -format xml))
$VSPackages = $VSInstances.instances.instance.packages.package
$LatestVCPackage = ($VSPackages | ? { $_.id -eq "Microsoft.VisualCpp.Tools.Core" })
$LatestVCToolsVersion = $LatestVCPackage.version;
$VSRoot = (& 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' @vsWhereBaseArgs -property 'resolvedInstallationPath')
$VSRoot = (& 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property 'resolvedInstallationPath')
$VCToolsRoot = Join-Path $VSRoot "VC\Tools\MSVC"
# We have observed a few instances where the VC tools package version actually
@@ -31,12 +24,5 @@ If ($Null -Eq (Get-Item $PackageVCToolPath -ErrorAction:Ignore)) {
}
Write-Output "Latest VCToolsVersion: $LatestVCToolsVersion"
# VS2026 (MSVC 14.50+) doesn't need explicit VCToolsVersion - let MSBuild auto-select
$MajorMinorVersion = [Version]::Parse($LatestVCToolsVersion)
If ($MajorMinorVersion.Major -eq 14 -and $MajorMinorVersion.Minor -ge 50) {
Write-Output "VS2026 detected (MSVC 14.50+). Skipping VCToolsVersion override to allow MSBuild auto-selection."
} Else {
Write-Output "Updating VCToolsVersion environment variable for job"
Write-Output "##vso[task.setvariable variable=VCToolsVersion]$LatestVCToolsVersion"
}
Write-Output "Updating VCToolsVersion environment variable for job"
Write-Output "##vso[task.setvariable variable=VCToolsVersion]$LatestVCToolsVersion"

View File

@@ -90,15 +90,9 @@ if ($noticeMatch.Success) {
$currentNoticePackageList = ""
}
# Test-only packages that are allowed to be in NOTICE.md but not in the build
# (e.g., when BuildTests=false, these packages won't appear in the NuGet list)
$allowedExtraPackages = @(
"- Moq"
)
if (!$noticeFile.Trim().EndsWith($returnList.Trim()))
{
Write-Host -ForegroundColor Yellow "Notice.md does not exactly match NuGet list. Analyzing differences..."
Write-Host -ForegroundColor Red "Notice.md does not match NuGet list."
# Show detailed differences
$generatedPackages = $returnList -split "`r`n|`n" | Where-Object { $_.Trim() -ne "" } | Sort-Object
@@ -111,7 +105,7 @@ if (!$noticeFile.Trim().EndsWith($returnList.Trim()))
# Find packages in proj file list but not in NOTICE.md
$missingFromNotice = $generatedPackages | Where-Object { $noticePackages -notcontains $_ }
if ($missingFromNotice.Count -gt 0) {
Write-Host -ForegroundColor Red "MissingFromNotice (ERROR - these must be added to NOTICE.md):"
Write-Host -ForegroundColor Red "MissingFromNotice:"
foreach ($pkg in $missingFromNotice) {
Write-Host -ForegroundColor Red " $pkg"
}
@@ -120,23 +114,10 @@ if (!$noticeFile.Trim().EndsWith($returnList.Trim()))
# Find packages in NOTICE.md but not in proj file list
$extraInNotice = $noticePackages | Where-Object { $generatedPackages -notcontains $_ }
# Filter out allowed extra packages (test-only dependencies)
$unexpectedExtra = $extraInNotice | Where-Object { $allowedExtraPackages -notcontains $_ }
$allowedExtra = $extraInNotice | Where-Object { $allowedExtraPackages -contains $_ }
if ($allowedExtra.Count -gt 0) {
Write-Host -ForegroundColor Green "ExtraInNotice (OK - allowed test-only packages):"
foreach ($pkg in $allowedExtra) {
Write-Host -ForegroundColor Green " $pkg"
}
Write-Host ""
}
if ($unexpectedExtra.Count -gt 0) {
Write-Host -ForegroundColor Red "ExtraInNotice (ERROR - unexpected packages in NOTICE.md):"
foreach ($pkg in $unexpectedExtra) {
Write-Host -ForegroundColor Red " $pkg"
if ($extraInNotice.Count -gt 0) {
Write-Host -ForegroundColor Yellow "ExtraInNotice:"
foreach ($pkg in $extraInNotice) {
Write-Host -ForegroundColor Yellow " $pkg"
}
Write-Host ""
}
@@ -146,17 +127,10 @@ if (!$noticeFile.Trim().EndsWith($returnList.Trim()))
Write-Host " Proj file list has $($generatedPackages.Count) packages"
Write-Host " NOTICE.md has $($noticePackages.Count) packages"
Write-Host " MissingFromNotice: $($missingFromNotice.Count) packages"
Write-Host " ExtraInNotice (allowed): $($allowedExtra.Count) packages"
Write-Host " ExtraInNotice (unexpected): $($unexpectedExtra.Count) packages"
Write-Host " ExtraInNotice: $($extraInNotice.Count) packages"
Write-Host ""
# Fail if there are missing packages OR unexpected extra packages
if ($missingFromNotice.Count -gt 0 -or $unexpectedExtra.Count -gt 0) {
Write-Host -ForegroundColor Red "FAILED: NOTICE.md mismatch detected."
exit 1
} else {
Write-Host -ForegroundColor Green "PASSED: NOTICE.md matches (with allowed test-only packages)."
}
exit 1
}
exit 0

View File

@@ -27,8 +27,7 @@ $versionExceptions = @(
"WyHash.dll",
"Microsoft.Recognizers.Text.DataTypes.TimexExpression.dll",
"ObjectModelCsProjection.dll",
"RendererCsProjection.dll",
"Microsoft.ML.OnnxRuntime.dll") -join '|';
"RendererCsProjection.dll") -join '|';
$nullVersionExceptions = @(
"SkiaSharp.Views.WinUI.Native.dll",
"libSkiaSharp.dll",
@@ -53,12 +52,7 @@ $nullVersionExceptions = @(
"System.Diagnostics.EventLog.Messages.dll",
"Microsoft.Windows.Widgets.dll",
"AdaptiveCards.ObjectModel.WinUI3.dll",
"AdaptiveCards.Rendering.WinUI3.dll",
"boost_regex_vc143_mt_gd_x32_1_87.dll",
"boost_regex_vc143_mt_gd_x64_1_87.dll",
"boost_regex_vc143_mt_x32_1_87.dll",
"boost_regex_vc143_mt_x64_1_87.dll"
) -join '|';
"AdaptiveCards.Rendering.WinUI3.dll") -join '|';
$totalFailure = 0;
Write-Host $DirPath;
@@ -104,4 +98,4 @@ if ($totalFailure -gt 0) {
exit 1
}
exit 0
exit 0

13
.vscode/mcp.json vendored
View File

@@ -1,13 +0,0 @@
{
"servers": {
"github-artifacts": {
"command": "node",
"args": [
"tools/mcp/github-artifacts/launch.js"
],
"env": {
"GITHUB_TOKEN": "${env:GITHUB_TOKEN}"
}
}
}
}

17
.vscode/settings.json vendored
View File

@@ -1,17 +0,0 @@
{
"github.copilot.chat.reviewSelection.instructions": [
{
"file": ".github/prompts/review-pr.prompt.md"
}
],
"github.copilot.chat.commitMessageGeneration.instructions": [
{
"file": ".github/prompts/create-commit-title.prompt.md"
}
],
"github.copilot.chat.pullRequestDescriptionGeneration.instructions": [
{
"file": ".github/prompts/create-pr-summary.prompt.md"
}
]
}

106
.vscode/tasks.json vendored
View File

@@ -1,106 +0,0 @@
{
"version": "2.0.0",
"windows": {
"options": {
"shell": {
"executable": "cmd.exe",
"args": ["/d", "/c"]
}
}
},
"inputs": [
{
"id": "config",
"type": "pickString",
"description": "Configuration",
"options": ["Debug", "Release"],
"default": "Debug"
},
{
"id": "platform",
"type": "pickString",
"description": "Platform (leave empty to auto-detect host platform)",
"options": ["", "X64", "ARM64"],
"default": "X64"
},
{
"id": "msbuildExtra",
"type": "promptString",
"description": "Extra MSBuild args (optional). Example: /p:CIBuild=true /m",
"default": ""
}
],
"tasks": [
{
"label": "PT: Build (quick)",
"type": "shell",
"command": "\"${workspaceFolder}\\tools\\build\\build.cmd\"",
"args": [
"-Path",
"${fileDirname}"
],
"group": { "kind": "build", "isDefault": true },
"presentation": {
"reveal": "always",
"panel": "dedicated",
"clear": true
},
"problemMatcher": "$msCompile"
},
{
"label": "PT: Build (with options)",
"type": "shell",
"command": "\"${workspaceFolder}\\tools\\build\\build.cmd\"",
"args": [
"-Path",
"${fileDirname}",
"-Platform",
"${input:platform}",
"-Configuration",
"${input:config}",
"${input:msbuildExtra}"
],
"presentation": {
"reveal": "always",
"panel": "dedicated",
"clear": true
},
"problemMatcher": "$msCompile"
},
{
"label": "PT: Build Essentials (quick)",
"type": "shell",
"command": "\"${workspaceFolder}\\tools\\build\\build-essentials.cmd\"",
"args": [],
"presentation": {
"reveal": "always",
"panel": "dedicated",
"clear": true
},
"problemMatcher": "$msCompile"
},
{
"label": "PT: Build Essentials (with options)",
"type": "shell",
"command": "\"${workspaceFolder}\\tools\\build\\build-essentials.cmd\"",
"args": [
"-Platform",
"${input:platform}",
"-Configuration",
"${input:config}",
"${input:msbuildExtra}"
],
"presentation": {
"reveal": "always",
"panel": "dedicated",
"clear": true
},
"problemMatcher": "$msCompile"
}
]
}

165
AGENTS.md
View File

@@ -1,165 +0,0 @@
---
description: 'Top-level AI contributor guidance for developing PowerToys - a collection of Windows productivity utilities'
applyTo: '**'
---
# PowerToys AI Contributor Guide
This is the top-level guidance for AI contributions to PowerToys. Keep changes atomic, follow existing patterns, and cite exact paths in PRs.
## Overview
PowerToys is a set of utilities for power users to tune and streamline their Windows experience.
| Area | Location | Description |
|------|----------|-------------|
| Runner | `src/runner/` | Main executable, tray icon, module loader, hotkey management |
| Settings UI | `src/settings-ui/` | WinUI/WPF configuration app communicating via named pipes |
| Modules | `src/modules/` | Individual PowerToys utilities (each in its own subfolder) |
| Common Libraries | `src/common/` | Shared code: logging, IPC, settings, DPI, telemetry, utilities |
| Build Tools | `tools/build/` | Build scripts and automation |
| Documentation | `doc/devdocs/` | Developer documentation |
| Installer | `installer/` | WiX-based installer projects |
For architecture details and module types, see [Architecture Overview](doc/devdocs/core/architecture.md).
## Conventions
For detailed coding conventions, see:
- [Coding Guidelines](doc/devdocs/development/guidelines.md) Dependencies, testing, PR management
- [Coding Style](doc/devdocs/development/style.md) Formatting, C++/C#/XAML style rules
- [Logging](doc/devdocs/development/logging.md) C++ spdlog and C# Logger usage
### Component-Specific Instructions
These instruction files are automatically applied when working in their respective areas:
- [Runner & Settings UI](.github/instructions/runner-settings-ui.instructions.md) IPC contracts, schema migrations
- [Common Libraries](.github/instructions/common-libraries.instructions.md) ABI stability, shared code guidelines
## Build
### Prerequisites
- Visual Studio 2022 17.4+ or Visual Studio 2026
- Windows 10 1803+ (April 2018 Update or newer)
- Initialize submodules once: `git submodule update --init --recursive`
### Build Commands
| Task | Command |
|------|---------|
| First build / NuGet restore | `tools\build\build-essentials.cmd` |
| Build current folder | `tools\build\build.cmd` |
| Build with options | `build.ps1 -Platform x64 -Configuration Release` |
### Build Discipline
1. One terminal per operation (build → test). Do not switch or open new ones mid-flow
2. After making changes, `cd` to the project folder that changed (`.csproj`/`.vcxproj`)
3. Use scripts to build: `tools/build/build.ps1` or `tools/build/build.cmd`
4. For first build or missing NuGet packages, run `build-essentials.cmd` first
5. **Exit code 0 = success; non-zero = failure** treat this as absolute
6. On failure, read the errors log: `build.<config>.<platform>.errors.log`
7. Do not start tests or launch Runner until the build succeeds
### Build Logs
Located next to the solution/project being built:
- `build.<configuration>.<platform>.errors.log` errors only (check this first)
- `build.<configuration>.<platform>.all.log` full log
- `build.<configuration>.<platform>.trace.binlog` for MSBuild Structured Log Viewer
For complete details, see [Build Guidelines](tools/build/BUILD-GUIDELINES.md).
## Tests
### Test Discovery
- Find test projects by product code prefix (e.g., `FancyZones`, `AdvancedPaste`)
- Look for sibling folders or 1-2 levels up named `<Product>*UnitTests` or `<Product>*UITests`
### Running Tests
1. **Build the test project first**, wait for exit code 0
2. Run via VS Test Explorer (`Ctrl+E, T`) or `vstest.console.exe` with filters
3. **Avoid `dotnet test`** in this repo use VS Test Explorer or vstest.console.exe
### Test Types
| Type | Requirements | Setup |
|------|--------------|-------|
| Unit Tests | Standard dev environment | None |
| UI Tests | WinAppDriver v1.2.1, Developer Mode | Install from [WinAppDriver releases](https://github.com/microsoft/WinAppDriver/releases/tag/v1.2.1) |
| Fuzz Tests | OneFuzz, .NET 8 | See [Fuzzing Tests](doc/devdocs/tools/fuzzingtesting.md) |
### Test Discipline
1. Add or adjust tests when changing behavior
2. If tests skipped, state why (e.g., comment-only change, string rename)
3. New modules handling file I/O or user input **must** implement fuzzing tests
### Special Requirements
- **Mouse Without Borders**: Requires 2+ physical computers (not VMs)
- **Multi-monitor utilities**: Test with 2+ monitors, different DPI settings
For UI test setup details, see [UI Tests](doc/devdocs/development/ui-tests.md).
## Boundaries
### Ask for Clarification When
- Ambiguous spec after scanning relevant docs
- Cross-module impact (shared enum/struct) is unclear
- Security, elevation, or installer changes involved
- GPO or policy handling modifications needed
### Areas Requiring Extra Care
| Area | Concern | Reference |
|------|---------|-----------|
| `src/common/` | ABI breaks | [Common Libraries Instructions](.github/instructions/common-libraries.instructions.md) |
| `src/runner/`, `src/settings-ui/` | IPC contracts, schema | [Runner & Settings UI Instructions](.github/instructions/runner-settings-ui.instructions.md) |
| Installer files | Release impact | Careful review required |
| Elevation/GPO logic | Security | Confirm no regression in policy handling |
### What NOT to Do
- Don't merge incomplete features into main (use feature branches)
- Don't break IPC/JSON contracts without updating both runner and settings-ui
- Don't add noisy logs in hot paths
- Don't introduce third-party deps without PM approval and `NOTICE.md` update
## Validation Checklist
Before finishing, verify:
- [ ] Build clean with exit code 0
- [ ] Tests updated and passing locally
- [ ] No unintended ABI breaks or schema changes
- [ ] IPC contracts consistent between runner and settings-ui
- [ ] New dependencies added to `NOTICE.md`
- [ ] PR is atomic (one logical change), with issue linked
## Documentation Index
### Core Architecture
- [Architecture Overview](doc/devdocs/core/architecture.md)
- [Runner](doc/devdocs/core/runner.md)
- [Settings System](doc/devdocs/core/settings/readme.md)
- [Module Interface](doc/devdocs/modules/interface.md)
### Development
- [Coding Guidelines](doc/devdocs/development/guidelines.md)
- [Coding Style](doc/devdocs/development/style.md)
- [Logging](doc/devdocs/development/logging.md)
- [UI Tests](doc/devdocs/development/ui-tests.md)
- [Fuzzing Tests](doc/devdocs/tools/fuzzingtesting.md)
### Build & Tools
- [Build Guidelines](tools/build/BUILD-GUIDELINES.md)
- [Tools Overview](doc/devdocs/tools/readme.md)
### Instructions (Auto-Applied)
- [Runner & Settings UI](.github/instructions/runner-settings-ui.instructions.md)
- [Common Libraries](.github/instructions/common-libraries.instructions.md)

View File

@@ -6,6 +6,9 @@ Names are in alphabetical order based on first name.
## High impact community members
### [@Noraa-Junker](https://github.com/Noraa-Junker) - [Noraa Junker](https://noraajunker.ch)
Noraa has helped triaging, discussing, and creating a substantial number of issues and contributed features/fixes. Noraa was the primary person for helping build the File Explorer preview pane handler for developer files.
### [@cgaarden](https://github.com/cgaarden) - [Christian Gaarden Gaardmark](https://www.onegreatworld.com)
Christian contributed New+ utility
@@ -39,12 +42,6 @@ Jay has helped triaging, discussing, creating a substantial number of issues and
### [@jefflord](https://github.com/Jjefflord) - Jeff Lord
Jeff added in multiple new features into Keyboard manager, such as key chord support and launching apps. He also contributed multiple features/fixes to PowerToys.
### [@snickler](https://github.com/snickler) - [Jeremy Sinclair](http://sinclairinat0r.com)
Jeremy has helped drive large sums of the ARM64 support inside PowerToys
### [@jiripolasek](https://github.com/jiripolasek) - [Jiří Polášek](https://github.com/jiripolasek)
Jiří has contributed a massive number of features and improvements to Command Palette, including drag & drop support, custom themes, Web Search enhancements, Remote Desktop extension fixes, and many UX improvements.
### [@TheJoeFin](https://github.com/TheJoeFin) - [Joe Finney](https://joefinapps.com)
Joe has helped triaging, discussing, issues as well as fixing bugs and building features for Text Extractor.
@@ -60,9 +57,6 @@ Color Picker is from Martin.
### [@mikeclayton](https://github.com/mikeclayton) - [Michael Clayton](https://michael-clayton.com)
Michael contributed the [initial version](https://github.com/microsoft/PowerToys/issues/23216) of the Mouse Jump tool and [a number of updates](https://github.com/microsoft/PowerToys/pulls?q=is%3Apr+author%3Amikeclayton) based on his FancyMouse utility.
### [@Noraa-Junker](https://github.com/Noraa-Junker) - [Noraa Junker](https://noraajunker.ch)
Noraa has helped triaging, discussing, and creating a substantial number of issues and contributed features/fixes. Noraa was the primary person for helping build the File Explorer preview pane handler for developer files.
### [@pedrolamas](https://github.com/pedrolamas/) - Pedro Lamas
Pedro helped create the thumbnail and File Explorer previewers for 3D files like STL and GCode. If you like 3D printing, these are very helpful.
@@ -75,12 +69,15 @@ Rafael has helped do the [upgrade from CppWinRT 1.x to 2.0](https://github.com/m
### [@royvou](https://github.com/royvou)
Roy has helped out contributing multiple features to PowerToys Run
### [@ThiefZero](https://github.com/ThiefZero)
ThiefZero has helped out contributing a features to PowerToys Run such as the unit converter plugin
### [@snickler](https://github.com/snickler) - [Jeremy Sinclair](http://sinclairinat0r.com)
Jeremy has helped drive large sums of the ARM64 support inside PowerToys
### [@TobiasSekan](https://github.com/TobiasSekan) - Tobias Sekan
Tobias Sekan has helped out contributing features to PowerToys Run such as Settings plugin, Registry plugin
### [@ThiefZero](https://github.com/ThiefZero)
ThiefZero has helped out contributing a features to PowerToys Run such as the unit converter plugin
## Open source projects
As PowerToys creates new utilities, some will be based off existing technology. We'll continue to do our best to contribute back to these projects but their efforts were the base of some of our projects. We want to be sure their work is directly recognized.
@@ -124,9 +121,6 @@ PowerToys Awake is a tool to keep your computer awake.
Randy contributed Registry Preview and some very early conversations about keyboard remapping.
### [@cinnamon-msft](https://github.com/cinnamon-msft) - Kayla Cinnamon
Kayla was a former lead for PowerToys and helped create multiple utilities, maintained the GitHub repo, and collaborated with the community to improve the overall product
### [@oldnewthing](https://github.com/oldnewthing) - Raymond Chen
Find My Mouse is based on Raymond Chen's SuperSonar.
@@ -186,14 +180,23 @@ ZoomIt source code was originally implemented by [Sysinternals](https://sysinter
## PowerToys core team
- [@cinnamon-msft](https://github.com/cinnamon-msft) - Kayla Cinnamon - Lead
- [@craigloewen-msft](https://github.com/craigloewen-msft) - Craig Loewen - Product Manager
- [@niels9001](https://github.com/niels9001/) - Niels Laute - Product Manager
- [@dhowett](https://github.com/dhowett) - Dustin Howett - Dev Lead
- [@yeelam-gordon](https://github.com/yeelam-gordon) - Gordon Lam - Dev Lead
- [@jamrobot](https://github.com/jamrobot) - Jerry Xu - Dev Lead
- [@lei9444](https://github.com/lei9444) - Leilei Zhang - Dev
- [@shuaiyuanxx](https://github.com/shuaiyuanxx) - Shawn Yuan - Dev
- [@moooyo](https://github.com/moooyo) - Yu Leng - Dev
- [@haoliuu](https://github.com/haoliuu) - Hao Liu - Dev
- [@chenmy77](https://github.com/chenmy77) - Mengyuan Chen - Dev
- [@chemwolf6922](https://github.com/chemwolf6922) - Feng Wang - Dev
- [@yaqingmi](https://github.com/yaqingmi) - Yaqing Mi - Dev
- [@zhaoqpcn](https://github.com/zhaoqpcn) - Qingpeng Zhao - Dev
- [@urnotdfs](https://github.com/urnotdfs) - Xiaofeng Wang - Dev
- [@zhaopy536](https://github.com/zhaopy536) - Peiyao Zhao - Dev
- [@wang563681252](https://github.com/wang563681252) - Zhaopeng Wang - Dev
- [@vanzue](https://github.com/vanzue) - Kai Tao - Dev
- [@zadjii-msft](https://github.com/zadjii-msft) - Mike Griese - Dev
- [@khmyznikov](https://github.com/khmyznikov) - Gleb Khmyznikov - Dev
@@ -206,7 +209,6 @@ ZoomIt source code was originally implemented by [Sysinternals](https://sysinter
## Former PowerToys core team members
- [@indierawk2k2](https://github.com/indierawk2k2) - Mike Harsh - Product Manager
- [@cinnamon-msft](https://github.com/cinnamon-msft) - Kayla Cinnamon - Product Manager
- [@ethanfangg](https://github.com/ethanfangg) - Ethan Fang - Product Manager
- [@plante-msft](https://github.com/plante-msft) - Connor Plante - Product Manager
- [@joadoumie](https://github.com/joadoumie) - Jordi Adoumie - Product Manager
@@ -224,12 +226,3 @@ ZoomIt source code was originally implemented by [Sysinternals](https://sysinter
- [@SeraphimaZykova](https://github.com/SeraphimaZykova) - Seraphima Zykova - Dev
- [@stefansjfw](https://github.com/stefansjfw) - Stefan Markovic - Dev
- [@jaimecbernardo](https://github.com/jaimecbernardo) - Jaime Bernardo - Dev Lead
- [@haoliuu](https://github.com/haoliuu) - Hao Liu - Dev
- [@chenmy77](https://github.com/chenmy77) - Mengyuan Chen - Dev
- [@chemwolf6922](https://github.com/chemwolf6922) - Feng Wang - Dev
- [@yaqingmi](https://github.com/yaqingmi) - Yaqing Mi - Dev
- [@zhaoqpcn](https://github.com/zhaoqpcn) - Qingpeng Zhao - Dev
- [@urnotdfs](https://github.com/urnotdfs) - Xiaofeng Wang - Dev
- [@zhaopy536](https://github.com/zhaopy536) - Peiyao Zhao - Dev
- [@wang563681252](https://github.com/wang563681252) - Zhaopeng Wang - Dev
- [@jamrobot](https://github.com/jamrobot) - Jerry Xu - Dev Lead

View File

@@ -2,12 +2,6 @@
<Project ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Skip building C++ test projects when BuildTests=false -->
<PropertyGroup Condition="'$(_IsSkippedTestProject)' == 'true'">
<UsePrecompiledHeaders>false</UsePrecompiledHeaders>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<!-- Project configurations -->
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
@@ -48,16 +42,11 @@
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<!-- Make angle-bracket includes external and turn off code analysis for them -->
<TreatAngleIncludeAsExternal>true</TreatAngleIncludeAsExternal>
<ExternalWarningLevel>TurnOffAllWarnings</ExternalWarningLevel>
<DisableAnalyzeExternal>true</DisableAnalyzeExternal>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PrecompiledHeader Condition="'$(UsePrecompiledHeaders)' != 'false'">Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<WarningLevel>Level4</WarningLevel>
<DisableSpecificWarnings>4679;4706;4874;5271;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<DisableSpecificWarnings>4679;5271;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<DisableAnalyzeExternal >true</DisableAnalyzeExternal>
<ExternalWarningLevel>TurnOffAllWarnings</ExternalWarningLevel>
<ConformanceMode>false</ConformanceMode>
@@ -116,18 +105,19 @@
<!-- Props that are constant for both Debug and Release configurations -->
<PropertyGroup Label="Configuration">
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '18.0'">v145</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<DesktopCompatible>true</DesktopCompatible>
<SpectreMitigation>Spectre</SpectreMitigation>
</PropertyGroup>
<!-- Debug/Release props -->
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<PropertyGroup Condition="'$(Configuration)'=='Debug'"
Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<PropertyGroup Condition="'$(Configuration)'=='Release'"
Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>

Some files were not shown because too many files have changed in this diff Show More