eslint-plugin-copilot 1.0.7 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (321) hide show
  1. package/README.md +74 -71
  2. package/dist/_internal/copilot-config-references.d.ts +1 -1
  3. package/dist/_internal/copilot-config-references.d.ts.map +1 -1
  4. package/dist/_internal/copilot-config-references.js +3 -1
  5. package/dist/_internal/copilot-config-references.js.map +1 -1
  6. package/dist/_internal/copilot-file-kind.d.ts +4 -0
  7. package/dist/_internal/copilot-file-kind.d.ts.map +1 -1
  8. package/dist/_internal/copilot-file-kind.js +20 -4
  9. package/dist/_internal/copilot-file-kind.js.map +1 -1
  10. package/dist/_internal/create-copilot-rule.d.ts +4 -2
  11. package/dist/_internal/create-copilot-rule.d.ts.map +1 -1
  12. package/dist/_internal/create-copilot-rule.js.map +1 -1
  13. package/dist/_internal/file-system.d.ts.map +1 -1
  14. package/dist/_internal/file-system.js +31 -18
  15. package/dist/_internal/file-system.js.map +1 -1
  16. package/dist/_internal/frontmatter.d.ts +1 -1
  17. package/dist/_internal/frontmatter.d.ts.map +1 -1
  18. package/dist/_internal/frontmatter.js +151 -119
  19. package/dist/_internal/frontmatter.js.map +1 -1
  20. package/dist/_internal/markdown-links.d.ts.map +1 -1
  21. package/dist/_internal/markdown-links.js +3 -1
  22. package/dist/_internal/markdown-links.js.map +1 -1
  23. package/dist/_internal/markdown-rule.d.ts +2 -1
  24. package/dist/_internal/markdown-rule.d.ts.map +1 -1
  25. package/dist/_internal/markdown-rule.js.map +1 -1
  26. package/dist/_internal/repository-hooks-json.d.ts +5 -2
  27. package/dist/_internal/repository-hooks-json.d.ts.map +1 -1
  28. package/dist/_internal/repository-hooks-json.js +7 -6
  29. package/dist/_internal/repository-hooks-json.js.map +1 -1
  30. package/dist/_internal/rule-catalog.d.ts.map +1 -1
  31. package/dist/_internal/rule-catalog.js +2 -3
  32. package/dist/_internal/rule-catalog.js.map +1 -1
  33. package/dist/plugin.cjs +615 -425
  34. package/dist/plugin.cjs.map +4 -4
  35. package/dist/plugin.d.cts +2 -1
  36. package/dist/plugin.d.ts +2 -1
  37. package/dist/plugin.d.ts.map +1 -1
  38. package/dist/plugin.js +5 -3
  39. package/dist/plugin.js.map +1 -1
  40. package/dist/rules/no-blank-customization-body.d.ts +1 -0
  41. package/dist/rules/no-blank-customization-body.d.ts.map +1 -1
  42. package/dist/rules/no-blank-customization-body.js +3 -0
  43. package/dist/rules/no-blank-customization-body.js.map +1 -1
  44. package/dist/rules/no-blank-repository-instructions.d.ts +1 -0
  45. package/dist/rules/no-blank-repository-instructions.d.ts.map +1 -1
  46. package/dist/rules/no-blank-repository-instructions.js +3 -0
  47. package/dist/rules/no-blank-repository-instructions.js.map +1 -1
  48. package/dist/rules/no-blank-skill-body.d.ts +1 -0
  49. package/dist/rules/no-blank-skill-body.d.ts.map +1 -1
  50. package/dist/rules/no-blank-skill-body.js +3 -0
  51. package/dist/rules/no-blank-skill-body.js.map +1 -1
  52. package/dist/rules/no-deprecated-agent-infer.d.ts +1 -0
  53. package/dist/rules/no-deprecated-agent-infer.d.ts.map +1 -1
  54. package/dist/rules/no-deprecated-agent-infer.js +3 -0
  55. package/dist/rules/no-deprecated-agent-infer.js.map +1 -1
  56. package/dist/rules/no-duplicate-agent-names.d.ts +1 -0
  57. package/dist/rules/no-duplicate-agent-names.d.ts.map +1 -1
  58. package/dist/rules/no-duplicate-agent-names.js +6 -4
  59. package/dist/rules/no-duplicate-agent-names.js.map +1 -1
  60. package/dist/rules/no-duplicate-prompt-names.d.ts +1 -0
  61. package/dist/rules/no-duplicate-prompt-names.d.ts.map +1 -1
  62. package/dist/rules/no-duplicate-prompt-names.js +6 -4
  63. package/dist/rules/no-duplicate-prompt-names.js.map +1 -1
  64. package/dist/rules/no-duplicate-skill-names.d.ts +1 -0
  65. package/dist/rules/no-duplicate-skill-names.d.ts.map +1 -1
  66. package/dist/rules/no-duplicate-skill-names.js +6 -4
  67. package/dist/rules/no-duplicate-skill-names.js.map +1 -1
  68. package/dist/rules/no-duplicate-slash-command-names.d.ts +1 -0
  69. package/dist/rules/no-duplicate-slash-command-names.d.ts.map +1 -1
  70. package/dist/rules/no-duplicate-slash-command-names.js +6 -4
  71. package/dist/rules/no-duplicate-slash-command-names.js.map +1 -1
  72. package/dist/rules/no-empty-repository-hook-arrays.d.ts +1 -0
  73. package/dist/rules/no-empty-repository-hook-arrays.d.ts.map +1 -1
  74. package/dist/rules/no-empty-repository-hook-arrays.js +7 -3
  75. package/dist/rules/no-empty-repository-hook-arrays.js.map +1 -1
  76. package/dist/rules/no-legacy-chatmode-files.d.ts +1 -0
  77. package/dist/rules/no-legacy-chatmode-files.d.ts.map +1 -1
  78. package/dist/rules/no-legacy-chatmode-files.js +3 -0
  79. package/dist/rules/no-legacy-chatmode-files.js.map +1 -1
  80. package/dist/rules/prefer-custom-instructions-under-code-review-limit.d.ts +1 -0
  81. package/dist/rules/prefer-custom-instructions-under-code-review-limit.d.ts.map +1 -1
  82. package/dist/rules/prefer-custom-instructions-under-code-review-limit.js +3 -0
  83. package/dist/rules/prefer-custom-instructions-under-code-review-limit.js.map +1 -1
  84. package/dist/rules/prefer-fast-repository-hooks.d.ts +1 -0
  85. package/dist/rules/prefer-fast-repository-hooks.d.ts.map +1 -1
  86. package/dist/rules/prefer-fast-repository-hooks.js +5 -1
  87. package/dist/rules/prefer-fast-repository-hooks.js.map +1 -1
  88. package/dist/rules/prefer-qualified-tools.d.ts +1 -0
  89. package/dist/rules/prefer-qualified-tools.d.ts.map +1 -1
  90. package/dist/rules/prefer-qualified-tools.js +8 -3
  91. package/dist/rules/prefer-qualified-tools.js.map +1 -1
  92. package/dist/rules/require-agent-tool-for-subagents.d.ts +1 -0
  93. package/dist/rules/require-agent-tool-for-subagents.d.ts.map +1 -1
  94. package/dist/rules/require-agent-tool-for-subagents.js +6 -2
  95. package/dist/rules/require-agent-tool-for-subagents.js.map +1 -1
  96. package/dist/rules/require-agents-md-for-cross-surface-agent-instructions.d.ts +1 -0
  97. package/dist/rules/require-agents-md-for-cross-surface-agent-instructions.d.ts.map +1 -1
  98. package/dist/rules/require-agents-md-for-cross-surface-agent-instructions.js +3 -0
  99. package/dist/rules/require-agents-md-for-cross-surface-agent-instructions.js.map +1 -1
  100. package/dist/rules/require-chatmode-file-metadata.d.ts +1 -0
  101. package/dist/rules/require-chatmode-file-metadata.d.ts.map +1 -1
  102. package/dist/rules/require-chatmode-file-metadata.js +5 -1
  103. package/dist/rules/require-chatmode-file-metadata.js.map +1 -1
  104. package/dist/rules/require-existing-agent-hook-cwd.d.ts +1 -0
  105. package/dist/rules/require-existing-agent-hook-cwd.d.ts.map +1 -1
  106. package/dist/rules/require-existing-agent-hook-cwd.js +6 -2
  107. package/dist/rules/require-existing-agent-hook-cwd.js.map +1 -1
  108. package/dist/rules/require-existing-agent-mcp-servers.d.ts +1 -0
  109. package/dist/rules/require-existing-agent-mcp-servers.d.ts.map +1 -1
  110. package/dist/rules/require-existing-agent-mcp-servers.js +6 -2
  111. package/dist/rules/require-existing-agent-mcp-servers.js.map +1 -1
  112. package/dist/rules/require-existing-relative-agent-links.d.ts +1 -0
  113. package/dist/rules/require-existing-relative-agent-links.d.ts.map +1 -1
  114. package/dist/rules/require-existing-relative-agent-links.js +3 -0
  115. package/dist/rules/require-existing-relative-agent-links.js.map +1 -1
  116. package/dist/rules/require-existing-relative-instructions-links.d.ts +1 -0
  117. package/dist/rules/require-existing-relative-instructions-links.d.ts.map +1 -1
  118. package/dist/rules/require-existing-relative-instructions-links.js +3 -0
  119. package/dist/rules/require-existing-relative-instructions-links.js.map +1 -1
  120. package/dist/rules/require-existing-relative-prompt-links.d.ts +1 -0
  121. package/dist/rules/require-existing-relative-prompt-links.d.ts.map +1 -1
  122. package/dist/rules/require-existing-relative-prompt-links.js +3 -0
  123. package/dist/rules/require-existing-relative-prompt-links.js.map +1 -1
  124. package/dist/rules/require-existing-relative-skill-links.d.ts +1 -0
  125. package/dist/rules/require-existing-relative-skill-links.d.ts.map +1 -1
  126. package/dist/rules/require-existing-relative-skill-links.js +3 -0
  127. package/dist/rules/require-existing-relative-skill-links.js.map +1 -1
  128. package/dist/rules/require-existing-repository-hook-cwd.d.ts +1 -0
  129. package/dist/rules/require-existing-repository-hook-cwd.d.ts.map +1 -1
  130. package/dist/rules/require-existing-repository-hook-cwd.js +5 -1
  131. package/dist/rules/require-existing-repository-hook-cwd.js.map +1 -1
  132. package/dist/rules/require-github-copilot-target-for-mcp-servers.d.ts +1 -0
  133. package/dist/rules/require-github-copilot-target-for-mcp-servers.d.ts.map +1 -1
  134. package/dist/rules/require-github-copilot-target-for-mcp-servers.js +5 -1
  135. package/dist/rules/require-github-copilot-target-for-mcp-servers.js.map +1 -1
  136. package/dist/rules/require-instructions-apply-to.d.ts +1 -0
  137. package/dist/rules/require-instructions-apply-to.d.ts.map +1 -1
  138. package/dist/rules/require-instructions-apply-to.js +5 -1
  139. package/dist/rules/require-instructions-apply-to.js.map +1 -1
  140. package/dist/rules/require-json-agent-mcp-servers.d.ts +1 -0
  141. package/dist/rules/require-json-agent-mcp-servers.d.ts.map +1 -1
  142. package/dist/rules/require-json-agent-mcp-servers.js +6 -2
  143. package/dist/rules/require-json-agent-mcp-servers.js.map +1 -1
  144. package/dist/rules/require-prompt-file-metadata.d.ts +1 -0
  145. package/dist/rules/require-prompt-file-metadata.d.ts.map +1 -1
  146. package/dist/rules/require-prompt-file-metadata.js +43 -32
  147. package/dist/rules/require-prompt-file-metadata.js.map +1 -1
  148. package/dist/rules/require-qualified-agent-handoff-models.d.ts +1 -0
  149. package/dist/rules/require-qualified-agent-handoff-models.d.ts.map +1 -1
  150. package/dist/rules/require-qualified-agent-handoff-models.js +6 -2
  151. package/dist/rules/require-qualified-agent-handoff-models.js.map +1 -1
  152. package/dist/rules/require-relative-agent-hook-cwd.d.ts +1 -0
  153. package/dist/rules/require-relative-agent-hook-cwd.d.ts.map +1 -1
  154. package/dist/rules/require-relative-agent-hook-cwd.js +6 -2
  155. package/dist/rules/require-relative-agent-hook-cwd.js.map +1 -1
  156. package/dist/rules/require-relative-agent-links.d.ts +1 -0
  157. package/dist/rules/require-relative-agent-links.d.ts.map +1 -1
  158. package/dist/rules/require-relative-agent-links.js +3 -0
  159. package/dist/rules/require-relative-agent-links.js.map +1 -1
  160. package/dist/rules/require-relative-instructions-links.d.ts +1 -0
  161. package/dist/rules/require-relative-instructions-links.d.ts.map +1 -1
  162. package/dist/rules/require-relative-instructions-links.js +3 -0
  163. package/dist/rules/require-relative-instructions-links.js.map +1 -1
  164. package/dist/rules/require-relative-prompt-links.d.ts +1 -0
  165. package/dist/rules/require-relative-prompt-links.d.ts.map +1 -1
  166. package/dist/rules/require-relative-prompt-links.js +3 -0
  167. package/dist/rules/require-relative-prompt-links.js.map +1 -1
  168. package/dist/rules/require-relative-repository-hook-cwd.d.ts +1 -0
  169. package/dist/rules/require-relative-repository-hook-cwd.d.ts.map +1 -1
  170. package/dist/rules/require-relative-repository-hook-cwd.js +5 -1
  171. package/dist/rules/require-relative-repository-hook-cwd.js.map +1 -1
  172. package/dist/rules/require-relative-skill-links.d.ts +1 -0
  173. package/dist/rules/require-relative-skill-links.d.ts.map +1 -1
  174. package/dist/rules/require-relative-skill-links.js +3 -0
  175. package/dist/rules/require-relative-skill-links.js.map +1 -1
  176. package/dist/rules/require-repository-hook-arrays.d.ts +1 -0
  177. package/dist/rules/require-repository-hook-arrays.d.ts.map +1 -1
  178. package/dist/rules/require-repository-hook-arrays.js +7 -3
  179. package/dist/rules/require-repository-hook-arrays.js.map +1 -1
  180. package/dist/rules/require-repository-hook-command-shell.d.ts +1 -0
  181. package/dist/rules/require-repository-hook-command-shell.d.ts.map +1 -1
  182. package/dist/rules/require-repository-hook-command-shell.js +5 -1
  183. package/dist/rules/require-repository-hook-command-shell.js.map +1 -1
  184. package/dist/rules/require-repository-hooks-object.d.ts +1 -0
  185. package/dist/rules/require-repository-hooks-object.d.ts.map +1 -1
  186. package/dist/rules/require-repository-hooks-object.js +3 -0
  187. package/dist/rules/require-repository-hooks-object.js.map +1 -1
  188. package/dist/rules/require-repository-instructions-file.d.ts +1 -0
  189. package/dist/rules/require-repository-instructions-file.d.ts.map +1 -1
  190. package/dist/rules/require-repository-instructions-file.js +8 -5
  191. package/dist/rules/require-repository-instructions-file.js.map +1 -1
  192. package/dist/rules/require-skill-file-location.d.ts +1 -0
  193. package/dist/rules/require-skill-file-location.d.ts.map +1 -1
  194. package/dist/rules/require-skill-file-location.js +3 -0
  195. package/dist/rules/require-skill-file-location.js.map +1 -1
  196. package/dist/rules/require-skill-file-metadata.d.ts +1 -0
  197. package/dist/rules/require-skill-file-metadata.d.ts.map +1 -1
  198. package/dist/rules/require-skill-file-metadata.js +6 -2
  199. package/dist/rules/require-skill-file-metadata.js.map +1 -1
  200. package/dist/rules/require-skill-md-filename.d.ts +1 -0
  201. package/dist/rules/require-skill-md-filename.d.ts.map +1 -1
  202. package/dist/rules/require-skill-md-filename.js +3 -0
  203. package/dist/rules/require-skill-md-filename.js.map +1 -1
  204. package/dist/rules/require-skill-name-match-directory.d.ts +1 -0
  205. package/dist/rules/require-skill-name-match-directory.d.ts.map +1 -1
  206. package/dist/rules/require-skill-name-match-directory.js +5 -1
  207. package/dist/rules/require-skill-name-match-directory.js.map +1 -1
  208. package/dist/rules/require-string-repository-hook-env-values.d.ts +1 -0
  209. package/dist/rules/require-string-repository-hook-env-values.d.ts.map +1 -1
  210. package/dist/rules/require-string-repository-hook-env-values.js +6 -2
  211. package/dist/rules/require-string-repository-hook-env-values.js.map +1 -1
  212. package/dist/rules/require-valid-agent-argument-hint.d.ts +1 -0
  213. package/dist/rules/require-valid-agent-argument-hint.d.ts.map +1 -1
  214. package/dist/rules/require-valid-agent-argument-hint.js +5 -1
  215. package/dist/rules/require-valid-agent-argument-hint.js.map +1 -1
  216. package/dist/rules/require-valid-agent-handoff-send.d.ts +1 -0
  217. package/dist/rules/require-valid-agent-handoff-send.d.ts.map +1 -1
  218. package/dist/rules/require-valid-agent-handoff-send.js +7 -3
  219. package/dist/rules/require-valid-agent-handoff-send.js.map +1 -1
  220. package/dist/rules/require-valid-agent-handoffs.d.ts +1 -0
  221. package/dist/rules/require-valid-agent-handoffs.d.ts.map +1 -1
  222. package/dist/rules/require-valid-agent-handoffs.js +5 -1
  223. package/dist/rules/require-valid-agent-handoffs.js.map +1 -1
  224. package/dist/rules/require-valid-agent-hook-events.d.ts +1 -0
  225. package/dist/rules/require-valid-agent-hook-events.d.ts.map +1 -1
  226. package/dist/rules/require-valid-agent-hook-events.js +6 -2
  227. package/dist/rules/require-valid-agent-hook-events.js.map +1 -1
  228. package/dist/rules/require-valid-agent-hook-timeouts.d.ts +1 -0
  229. package/dist/rules/require-valid-agent-hook-timeouts.d.ts.map +1 -1
  230. package/dist/rules/require-valid-agent-hook-timeouts.js +6 -2
  231. package/dist/rules/require-valid-agent-hook-timeouts.js.map +1 -1
  232. package/dist/rules/require-valid-agent-hooks.d.ts +1 -0
  233. package/dist/rules/require-valid-agent-hooks.d.ts.map +1 -1
  234. package/dist/rules/require-valid-agent-hooks.js +31 -21
  235. package/dist/rules/require-valid-agent-hooks.js.map +1 -1
  236. package/dist/rules/require-valid-agent-invocation-controls.d.ts +1 -0
  237. package/dist/rules/require-valid-agent-invocation-controls.d.ts.map +1 -1
  238. package/dist/rules/require-valid-agent-invocation-controls.js +7 -3
  239. package/dist/rules/require-valid-agent-invocation-controls.js.map +1 -1
  240. package/dist/rules/require-valid-agent-mcp-servers.d.ts +1 -0
  241. package/dist/rules/require-valid-agent-mcp-servers.d.ts.map +1 -1
  242. package/dist/rules/require-valid-agent-mcp-servers.js +8 -4
  243. package/dist/rules/require-valid-agent-mcp-servers.js.map +1 -1
  244. package/dist/rules/require-valid-agent-model.d.ts +1 -0
  245. package/dist/rules/require-valid-agent-model.d.ts.map +1 -1
  246. package/dist/rules/require-valid-agent-model.js +7 -3
  247. package/dist/rules/require-valid-agent-model.js.map +1 -1
  248. package/dist/rules/require-valid-agent-name.d.ts +1 -0
  249. package/dist/rules/require-valid-agent-name.d.ts.map +1 -1
  250. package/dist/rules/require-valid-agent-name.js +5 -1
  251. package/dist/rules/require-valid-agent-name.js.map +1 -1
  252. package/dist/rules/require-valid-agent-subagents.d.ts +1 -0
  253. package/dist/rules/require-valid-agent-subagents.d.ts.map +1 -1
  254. package/dist/rules/require-valid-agent-subagents.js +8 -4
  255. package/dist/rules/require-valid-agent-subagents.js.map +1 -1
  256. package/dist/rules/require-valid-agent-target.d.ts +1 -0
  257. package/dist/rules/require-valid-agent-target.d.ts.map +1 -1
  258. package/dist/rules/require-valid-agent-target.js +6 -2
  259. package/dist/rules/require-valid-agent-target.js.map +1 -1
  260. package/dist/rules/require-valid-agent-tools.d.ts +1 -0
  261. package/dist/rules/require-valid-agent-tools.d.ts.map +1 -1
  262. package/dist/rules/require-valid-agent-tools.js +8 -4
  263. package/dist/rules/require-valid-agent-tools.js.map +1 -1
  264. package/dist/rules/require-valid-instructions-apply-to-globs.d.ts +1 -0
  265. package/dist/rules/require-valid-instructions-apply-to-globs.d.ts.map +1 -1
  266. package/dist/rules/require-valid-instructions-apply-to-globs.js +8 -3
  267. package/dist/rules/require-valid-instructions-apply-to-globs.js.map +1 -1
  268. package/dist/rules/require-valid-prompt-argument-hint.d.ts +1 -0
  269. package/dist/rules/require-valid-prompt-argument-hint.d.ts.map +1 -1
  270. package/dist/rules/require-valid-prompt-argument-hint.js +6 -3
  271. package/dist/rules/require-valid-prompt-argument-hint.js.map +1 -1
  272. package/dist/rules/require-valid-prompt-model.d.ts +1 -0
  273. package/dist/rules/require-valid-prompt-model.d.ts.map +1 -1
  274. package/dist/rules/require-valid-prompt-model.js +9 -5
  275. package/dist/rules/require-valid-prompt-model.js.map +1 -1
  276. package/dist/rules/require-valid-prompt-name.d.ts +1 -0
  277. package/dist/rules/require-valid-prompt-name.d.ts.map +1 -1
  278. package/dist/rules/require-valid-prompt-name.js +5 -1
  279. package/dist/rules/require-valid-prompt-name.js.map +1 -1
  280. package/dist/rules/require-valid-prompt-tools.d.ts +1 -0
  281. package/dist/rules/require-valid-prompt-tools.d.ts.map +1 -1
  282. package/dist/rules/require-valid-prompt-tools.js +8 -4
  283. package/dist/rules/require-valid-prompt-tools.js.map +1 -1
  284. package/dist/rules/require-valid-repository-hook-command-type.d.ts +1 -0
  285. package/dist/rules/require-valid-repository-hook-command-type.d.ts.map +1 -1
  286. package/dist/rules/require-valid-repository-hook-command-type.js +5 -1
  287. package/dist/rules/require-valid-repository-hook-command-type.js.map +1 -1
  288. package/dist/rules/require-valid-repository-hook-env.d.ts +1 -0
  289. package/dist/rules/require-valid-repository-hook-env.d.ts.map +1 -1
  290. package/dist/rules/require-valid-repository-hook-env.js +6 -2
  291. package/dist/rules/require-valid-repository-hook-env.js.map +1 -1
  292. package/dist/rules/require-valid-repository-hook-events.d.ts +1 -0
  293. package/dist/rules/require-valid-repository-hook-events.d.ts.map +1 -1
  294. package/dist/rules/require-valid-repository-hook-events.js +5 -1
  295. package/dist/rules/require-valid-repository-hook-events.js.map +1 -1
  296. package/dist/rules/require-valid-repository-hook-timeouts.d.ts +1 -0
  297. package/dist/rules/require-valid-repository-hook-timeouts.d.ts.map +1 -1
  298. package/dist/rules/require-valid-repository-hook-timeouts.js +7 -3
  299. package/dist/rules/require-valid-repository-hook-timeouts.js.map +1 -1
  300. package/dist/rules/require-valid-repository-hook-version.d.ts +1 -0
  301. package/dist/rules/require-valid-repository-hook-version.d.ts.map +1 -1
  302. package/dist/rules/require-valid-repository-hook-version.js +3 -0
  303. package/dist/rules/require-valid-repository-hook-version.js.map +1 -1
  304. package/dist/rules/require-valid-skill-directory-name.d.ts +1 -0
  305. package/dist/rules/require-valid-skill-directory-name.d.ts.map +1 -1
  306. package/dist/rules/require-valid-skill-directory-name.js +3 -0
  307. package/dist/rules/require-valid-skill-directory-name.js.map +1 -1
  308. package/dist/rules/require-valid-skill-license.d.ts +1 -0
  309. package/dist/rules/require-valid-skill-license.d.ts.map +1 -1
  310. package/dist/rules/require-valid-skill-license.js +5 -1
  311. package/dist/rules/require-valid-skill-license.js.map +1 -1
  312. package/dist/rules/require-valid-skill-name.d.ts +1 -0
  313. package/dist/rules/require-valid-skill-name.d.ts.map +1 -1
  314. package/dist/rules/require-valid-skill-name.js +5 -1
  315. package/dist/rules/require-valid-skill-name.js.map +1 -1
  316. package/docs/rules/getting-started.md +1 -1
  317. package/docs/rules/no-blank-customization-body.md +1 -1
  318. package/docs/rules/no-blank-repository-instructions.md +2 -1
  319. package/docs/rules/prefer-custom-instructions-under-code-review-limit.md +1 -0
  320. package/docs/rules/require-repository-instructions-file.md +8 -3
  321. package/package.json +75 -63
package/dist/plugin.cjs CHANGED
@@ -35,12 +35,13 @@ __export(plugin_exports, {
35
35
  module.exports = __toCommonJS(plugin_exports);
36
36
  var import_json = __toESM(require("@eslint/json"), 1);
37
37
  var import_markdown = __toESM(require("@eslint/markdown"), 1);
38
+ var import_ts_extras56 = require("ts-extras");
38
39
 
39
40
  // package.json
40
41
  var package_default = {
41
42
  $schema: "https://www.schemastore.org/package.json",
42
43
  name: "eslint-plugin-copilot",
43
- version: "1.0.7",
44
+ version: "1.1.0",
44
45
  private: false,
45
46
  description: "ESLint rules for GitHub Copilot repository customization files.",
46
47
  keywords: [
@@ -237,21 +238,23 @@ var package_default = {
237
238
  "jsonc-eslint-parser": "$jsonc-eslint-parser"
238
239
  },
239
240
  dependencies: {
240
- "@typescript-eslint/parser": "^8.58.0",
241
- "@typescript-eslint/type-utils": "^8.58.0",
242
- "@typescript-eslint/utils": "^8.58.0"
241
+ "@typescript-eslint/parser": "^8.59.0",
242
+ "@typescript-eslint/type-utils": "^8.59.0",
243
+ "@typescript-eslint/utils": "^8.59.0",
244
+ "ts-extras": "^1.0.0",
245
+ "type-fest": "^5.6.0"
243
246
  },
244
247
  devDependencies: {
245
248
  "@arethetypeswrong/cli": "^0.18.2",
246
249
  "@csstools/stylelint-formatter-github": "^2.0.0",
247
- "@docusaurus/eslint-plugin": "^3.9.2",
250
+ "@docusaurus/eslint-plugin": "^3.10.0",
248
251
  "@double-great/remark-lint-alt-text": "^1.1.1",
249
- "@double-great/stylelint-a11y": "^3.4.9",
252
+ "@double-great/stylelint-a11y": "^3.4.10",
250
253
  "@eslint-community/eslint-plugin-eslint-comments": "^4.7.1",
251
254
  "@eslint-react/eslint-plugin": "^4.2.3",
252
- "@eslint/compat": "^2.0.4",
253
- "@eslint/config-helpers": "^0.5.4",
254
- "@eslint/config-inspector": "^1.5.0",
255
+ "@eslint/compat": "^2.0.5",
256
+ "@eslint/config-helpers": "^0.5.5",
257
+ "@eslint/config-inspector": "^2.0.0",
255
258
  "@eslint/css": "^1.1.0",
256
259
  "@eslint/js": "^10.0.1",
257
260
  "@eslint/json": "^1.2.0",
@@ -260,25 +263,25 @@ var package_default = {
260
263
  "@html-eslint/parser": "^0.59.0",
261
264
  "@microsoft/eslint-plugin-sdl": "^1.1.0",
262
265
  "@microsoft/tsdoc-config": "^0.18.1",
263
- "@secretlint/secretlint-rule-anthropic": "^11.5.0",
264
- "@secretlint/secretlint-rule-aws": "^11.5.0",
265
- "@secretlint/secretlint-rule-database-connection-string": "^11.5.0",
266
- "@secretlint/secretlint-rule-gcp": "^11.5.0",
267
- "@secretlint/secretlint-rule-github": "^11.5.0",
268
- "@secretlint/secretlint-rule-no-dotenv": "^11.5.0",
269
- "@secretlint/secretlint-rule-no-homedir": "^11.5.0",
270
- "@secretlint/secretlint-rule-npm": "^11.5.0",
271
- "@secretlint/secretlint-rule-openai": "^11.5.0",
272
- "@secretlint/secretlint-rule-pattern": "^11.5.0",
273
- "@secretlint/secretlint-rule-preset-recommend": "^11.4.1",
274
- "@secretlint/secretlint-rule-privatekey": "^11.5.0",
275
- "@secretlint/secretlint-rule-secp256k1-privatekey": "^11.5.0",
276
- "@secretlint/types": "^11.5.0",
266
+ "@secretlint/secretlint-rule-anthropic": "^12.2.0",
267
+ "@secretlint/secretlint-rule-aws": "^12.2.0",
268
+ "@secretlint/secretlint-rule-database-connection-string": "^12.2.0",
269
+ "@secretlint/secretlint-rule-gcp": "^12.2.0",
270
+ "@secretlint/secretlint-rule-github": "^12.2.0",
271
+ "@secretlint/secretlint-rule-no-dotenv": "^12.2.0",
272
+ "@secretlint/secretlint-rule-no-homedir": "^12.2.0",
273
+ "@secretlint/secretlint-rule-npm": "^12.2.0",
274
+ "@secretlint/secretlint-rule-openai": "^12.2.0",
275
+ "@secretlint/secretlint-rule-pattern": "^12.2.0",
276
+ "@secretlint/secretlint-rule-preset-recommend": "^12.2.0",
277
+ "@secretlint/secretlint-rule-privatekey": "^12.2.0",
278
+ "@secretlint/secretlint-rule-secp256k1-privatekey": "^12.2.0",
279
+ "@secretlint/types": "^12.2.0",
277
280
  "@softonus/prettier-plugin-duplicate-remover": "^1.1.2",
278
281
  "@stryker-ignorer/console-all": "^0.3.2",
279
- "@stryker-mutator/core": "^9.6.0",
280
- "@stryker-mutator/typescript-checker": "^9.6.0",
281
- "@stryker-mutator/vitest-runner": "^9.6.0",
282
+ "@stryker-mutator/core": "^9.6.1",
283
+ "@stryker-mutator/typescript-checker": "^9.6.1",
284
+ "@stryker-mutator/vitest-runner": "^9.6.1",
282
285
  "@stylelint-types/stylelint-order": "^7.0.1",
283
286
  "@stylelint-types/stylelint-stylistic": "^5.0.0",
284
287
  "@stylistic/eslint-plugin": "^5.10.0",
@@ -287,7 +290,7 @@ var package_default = {
287
290
  "@types/eslint-plugin-security": "^3.0.1",
288
291
  "@types/htmlhint": "^1.1.5",
289
292
  "@types/madge": "^5.0.3",
290
- "@types/node": "^25.5.2",
293
+ "@types/node": "^25.6.0",
291
294
  "@types/postcss-clamp": "^4.1.3",
292
295
  "@types/postcss-flexbugs-fixes": "^5.0.3",
293
296
  "@types/postcss-html": "^1.5.3",
@@ -296,11 +299,12 @@ var package_default = {
296
299
  "@types/postcss-normalize": "^9.0.4",
297
300
  "@types/postcss-reporter": "^7.0.5",
298
301
  "@types/sloc": "^0.2.3",
299
- "@typescript-eslint/eslint-plugin": "^8.58.0",
300
- "@typescript-eslint/rule-tester": "^8.58.0",
301
- "@vitest/coverage-v8": "^4.1.2",
302
- "@vitest/eslint-plugin": "^1.6.14",
303
- "@vitest/ui": "^4.1.2",
302
+ "@typescript-eslint/eslint-plugin": "^8.59.0",
303
+ "@typescript-eslint/rule-tester": "^8.59.0",
304
+ "@typpi/eslint-plugin-vite": "^1.0.13",
305
+ "@vitest/coverage-v8": "^4.1.5",
306
+ "@vitest/eslint-plugin": "^1.6.16",
307
+ "@vitest/ui": "^4.1.5",
304
308
  actionlint: "^2.0.6",
305
309
  "all-contributors-cli": "^6.26.1",
306
310
  "cognitive-complexity-ts": "^0.8.1",
@@ -309,23 +313,27 @@ var package_default = {
309
313
  "cross-env": "^10.1.0",
310
314
  depcheck: "^1.4.7",
311
315
  "detect-secrets": "^1.0.6",
312
- eslint: "^10.2.0",
316
+ eslint: "^10.2.1",
313
317
  "eslint-config-flat-gitignore": "^2.3.0",
314
318
  "eslint-config-prettier": "^10.1.8",
315
319
  "eslint-formatter-unix": "^9.0.1",
316
320
  "eslint-import-resolver-typescript": "^4.4.4",
317
321
  "eslint-plugin-array-func": "^5.1.1",
318
322
  "eslint-plugin-canonical": "^5.1.3",
319
- "eslint-plugin-case-police": "^2.2.0",
320
- "eslint-plugin-comment-length": "^2.3.0",
323
+ "eslint-plugin-case-police": "^2.2.1",
324
+ "eslint-plugin-comment-length": "^2.3.1",
325
+ "eslint-plugin-copilot": "^1.0.8",
321
326
  "eslint-plugin-css-modules": "^2.12.0",
322
327
  "eslint-plugin-de-morgan": "^2.1.1",
323
328
  "eslint-plugin-depend": "^1.5.0",
329
+ "eslint-plugin-docusaurus-2": "^0.2.0",
324
330
  "eslint-plugin-eslint-plugin": "^7.3.2",
325
331
  "eslint-plugin-etc": "^2.0.3",
326
- "eslint-plugin-etc-misc": "^1.0.5",
327
- "eslint-plugin-file-progress-2": "^3.4.4",
332
+ "eslint-plugin-etc-misc": "^1.0.8",
333
+ "eslint-plugin-file-progress-2": "^5.0.1",
334
+ "eslint-plugin-github-actions-2": "^1.1.0",
328
335
  "eslint-plugin-html": "^8.1.4",
336
+ "eslint-plugin-immutable-2": "^1.0.10",
329
337
  "eslint-plugin-import-x": "^4.16.2",
330
338
  "eslint-plugin-jsdoc": "^62.9.0",
331
339
  "eslint-plugin-jsonc": "^3.1.2",
@@ -336,7 +344,7 @@ var package_default = {
336
344
  "eslint-plugin-module-interop": "^0.3.1",
337
345
  "eslint-plugin-n": "^17.24.0",
338
346
  "eslint-plugin-nitpick": "^0.12.0",
339
- "eslint-plugin-no-barrel-files": "^1.2.2",
347
+ "eslint-plugin-no-barrel-files": "^1.3.1",
340
348
  "eslint-plugin-no-explicit-type-exports": "^0.12.1",
341
349
  "eslint-plugin-no-function-declare-after-return": "^1.1.0",
342
350
  "eslint-plugin-no-lookahead-lookbehind-regexp": "^0.4.0",
@@ -346,42 +354,47 @@ var package_default = {
346
354
  "eslint-plugin-no-use-extend-native": "^0.7.2",
347
355
  "eslint-plugin-node-dependencies": "^2.2.0",
348
356
  "eslint-plugin-package-json": "^0.91.1",
349
- "eslint-plugin-perfectionist": "^5.8.0",
357
+ "eslint-plugin-perfectionist": "^5.9.0",
350
358
  "eslint-plugin-prefer-arrow": "^1.2.3",
351
359
  "eslint-plugin-prettier": "^5.5.5",
352
360
  "eslint-plugin-promise": "^7.2.1",
353
361
  "eslint-plugin-redos": "^4.5.0",
354
362
  "eslint-plugin-regexp": "^3.1.0",
355
363
  "eslint-plugin-require-jsdoc": "^1.0.4",
364
+ "eslint-plugin-sdl-2": "^1.0.7",
356
365
  "eslint-plugin-security": "^4.0.0",
357
- "eslint-plugin-sonarjs": "^4.0.2",
366
+ "eslint-plugin-sonarjs": "^4.0.3",
358
367
  "eslint-plugin-sort-class-members": "^1.22.1",
368
+ "eslint-plugin-stylelint-2": "^1.1.0",
359
369
  "eslint-plugin-testing-library": "^7.16.2",
360
370
  "eslint-plugin-toml": "^1.3.1",
361
371
  "eslint-plugin-total-functions": "^7.1.0",
362
372
  "eslint-plugin-tsdoc": "^0.5.2",
363
- "eslint-plugin-tsdoc-require-2": "^1.0.9",
373
+ "eslint-plugin-tsdoc-require-2": "^1.1.0",
374
+ "eslint-plugin-typedoc": "^1.2.0",
375
+ "eslint-plugin-typefest": "^1.2.4",
364
376
  "eslint-plugin-undefined-css-classes": "^0.1.5",
365
377
  "eslint-plugin-unicorn": "^64.0.0",
366
378
  "eslint-plugin-unused-imports": "^4.4.1",
367
379
  "eslint-plugin-write-good-comments": "^0.2.0",
380
+ "eslint-plugin-write-good-comments-2": "^1.0.6",
368
381
  "eslint-plugin-yml": "^3.3.1",
369
382
  "eslint-rule-benchmark": "^0.8.0",
370
- "fast-check": "^4.6.0",
383
+ "fast-check": "^4.7.0",
371
384
  "git-cliff": "^2.12.0",
372
385
  "gitleaks-secret-scanner": "^2.1.1",
373
- globals: "^17.4.0",
386
+ globals: "^17.5.0",
374
387
  htmlhint: "^1.9.2",
375
- jscpd: "^4.0.8",
388
+ jscpd: "^4.0.9",
376
389
  "jsonc-eslint-parser": "^3.1.0",
377
- knip: "^6.3.0",
390
+ knip: "^6.6.2",
378
391
  leasot: "^14.4.0",
379
392
  madge: "^8.0.0",
380
393
  "markdown-link-check": "^3.14.2",
381
- "npm-check-updates": "^20.0.0",
382
- "npm-package-json-lint": "^10.2.0",
394
+ "npm-check-updates": "^21.0.3",
395
+ "npm-package-json-lint": "^10.2.1",
383
396
  picocolors: "^1.1.1",
384
- postcss: "^8.5.8",
397
+ postcss: "^8.5.10",
385
398
  "postcss-assets": "^6.0.0",
386
399
  "postcss-clamp": "^4.1.0",
387
400
  "postcss-combine-duplicated-selectors": "^10.0.3",
@@ -394,17 +407,17 @@ var package_default = {
394
407
  "postcss-reporter": "^7.1.0",
395
408
  "postcss-round-subpixels": "^2.0.0",
396
409
  "postcss-scss": "^4.0.9",
397
- "postcss-sort-media-queries": "^6.3.3",
410
+ "postcss-sort-media-queries": "^6.5.0",
398
411
  "postcss-styled-jsx": "^1.0.1",
399
412
  "postcss-styled-syntax": "^0.7.1",
400
413
  "postcss-viewport-height-correction": "^1.1.1",
401
- prettier: "^3.8.1",
414
+ prettier: "^3.8.3",
402
415
  "prettier-plugin-ini": "^1.3.0",
403
416
  "prettier-plugin-interpolated-html-tags": "^2.0.1",
404
417
  "prettier-plugin-jsdoc": "^1.8.0",
405
418
  "prettier-plugin-jsdoc-type": "^0.2.0",
406
419
  "prettier-plugin-merge": "^0.10.1",
407
- "prettier-plugin-multiline-arrays": "^4.1.5",
420
+ "prettier-plugin-multiline-arrays": "^4.1.7",
408
421
  "prettier-plugin-packagejson": "^3.0.2",
409
422
  "prettier-plugin-properties": "^0.3.1",
410
423
  "prettier-plugin-sort-json": "^4.2.0",
@@ -518,16 +531,16 @@ var package_default = {
518
531
  "remark-validate-links": "^13.1.0",
519
532
  "remark-wiki-link": "^2.0.1",
520
533
  rimraf: "^6.1.3",
521
- secretlint: "^11.4.1",
534
+ secretlint: "^12.2.0",
522
535
  sloc: "^0.3.2",
523
536
  "sort-package-json": "^3.6.1",
524
- stylelint: "^17.6.0",
537
+ stylelint: "^17.9.0",
525
538
  "stylelint-actions-formatters": "^16.3.1",
526
539
  "stylelint-checkstyle-formatter": "^0.1.2",
527
540
  "stylelint-codeframe-formatter": "^1.2.0",
528
541
  "stylelint-config-alphabetical-order": "^2.0.0",
529
542
  "stylelint-config-idiomatic-order": "^10.0.0",
530
- "stylelint-config-inspector": "^2.0.3",
543
+ "stylelint-config-inspector": "^2.1.2",
531
544
  "stylelint-config-recess-order": "^7.7.0",
532
545
  "stylelint-config-recommended": "^18.0.0",
533
546
  "stylelint-config-sass-guidelines": "^13.0.0",
@@ -536,7 +549,7 @@ var package_default = {
536
549
  "stylelint-config-tailwindcss": "^1.0.1",
537
550
  "stylelint-declaration-block-no-ignored-properties": "^3.0.0",
538
551
  "stylelint-declaration-strict-value": "^1.11.1",
539
- "stylelint-define-config": "^17.5.0",
552
+ "stylelint-define-config": "^17.8.0",
540
553
  "stylelint-find-new-rules": "^6.0.0",
541
554
  "stylelint-formatter-gitlab-code-quality-report": "^1.1.0",
542
555
  "stylelint-formatter-pretty": "^4.0.1",
@@ -550,7 +563,7 @@ var package_default = {
550
563
  "stylelint-no-unresolved-module": "^2.5.2",
551
564
  "stylelint-no-unsupported-browser-features": "^8.1.1",
552
565
  "stylelint-order": "^8.1.1",
553
- "stylelint-plugin-defensive-css": "^2.8.1",
566
+ "stylelint-plugin-defensive-css": "^2.9.1",
554
567
  "stylelint-plugin-logical-css": "^2.1.0",
555
568
  "stylelint-plugin-use-baseline": "^1.4.1",
556
569
  "stylelint-prettier": "^5.0.3",
@@ -561,22 +574,22 @@ var package_default = {
561
574
  "stylelint-value-no-unknown-custom-properties": "^6.1.1",
562
575
  "toml-eslint-parser": "^1.0.3",
563
576
  "ts-unused-exports": "^11.0.1",
564
- typedoc: "^0.28.18",
565
- typescript: "^6.0.2",
566
- "typescript-eslint": "^8.58.0",
577
+ typedoc: "^0.28.19",
578
+ typescript: "^6.0.3",
579
+ "typescript-eslint": "^8.59.0",
567
580
  typesync: "^0.14.3",
568
581
  vfile: "^6.0.3",
569
- vite: "^8.0.3",
582
+ vite: "^8.0.10",
570
583
  "vite-tsconfig-paths": "^6.1.1",
571
- vitest: "^4.1.2",
584
+ vitest: "^4.1.5",
572
585
  "yaml-eslint-parser": "^2.0.0",
573
586
  "yamllint-js": "^0.2.4"
574
587
  },
575
588
  peerDependencies: {
576
- eslint: "^9.0.0 || ^10.2.0",
589
+ eslint: "^9.0.0 || ^10.2.1",
577
590
  typescript: ">=5.0.0"
578
591
  },
579
- packageManager: "npm@11.12.1",
592
+ packageManager: "npm@11.13.0",
580
593
  engines: {
581
594
  node: ">=22.0.0"
582
595
  },
@@ -600,6 +613,7 @@ var package_default = {
600
613
  };
601
614
 
602
615
  // dist/_internal/copilot-config-references.js
616
+ var import_ts_extras = require("ts-extras");
603
617
  var copilotConfigMetadataByName = {
604
618
  all: {
605
619
  icon: "\u{1F7E3}",
@@ -630,6 +644,7 @@ var copilotConfigMetadataByName = {
630
644
  // dist/_internal/copilot-file-kind.js
631
645
  var fs = __toESM(require("node:fs"), 1);
632
646
  var path = __toESM(require("node:path"), 1);
647
+ var import_ts_extras2 = require("ts-extras");
633
648
  var normalizeFilePath = (filePath) => path.resolve(filePath).replaceAll("\\", "/");
634
649
  var isLegacyChatmodeFilePath = (filePath) => {
635
650
  const normalizedFilePath = normalizeFilePath(filePath);
@@ -659,11 +674,15 @@ var isRepositoryHookFilePath = (filePath) => {
659
674
  const basename7 = path.posix.basename(normalizedFilePath);
660
675
  return normalizedFilePath.includes("/.github/hooks/") && basename7.endsWith(".json");
661
676
  };
677
+ var isRepositoryInstructionsFilePath = (filePath) => {
678
+ const normalizedFilePath = normalizeFilePath(filePath);
679
+ return normalizedFilePath.endsWith("/.github/copilot-instructions.md") || normalizedFilePath.endsWith("/.github/instructions/copilot-instructions.md");
680
+ };
662
681
  var isAgentInstructionsBasename = (basename7) => basename7 === "AGENTS.md" || basename7 === "CLAUDE.md" || basename7 === "GEMINI.md";
663
682
  var getCopilotFileKind = (filePath) => {
664
683
  const normalizedFilePath = normalizeFilePath(filePath);
665
684
  const basename7 = path.posix.basename(normalizedFilePath);
666
- if (normalizedFilePath.endsWith("/.github/copilot-instructions.md")) {
685
+ if (isRepositoryInstructionsFilePath(normalizedFilePath)) {
667
686
  return "repository-instructions";
668
687
  }
669
688
  if (normalizedFilePath.includes("/.github/instructions/") && basename7.endsWith(".instructions.md")) {
@@ -685,11 +704,11 @@ var getCopilotFileKind = (filePath) => {
685
704
  };
686
705
  var findRepositoryRoot = (filePath) => {
687
706
  const normalizedFilePath = path.resolve(filePath);
688
- const pathSegments = normalizeFilePath(normalizedFilePath).split("/");
707
+ const pathSegments = (0, import_ts_extras2.stringSplit)(normalizeFilePath(normalizedFilePath), "/");
689
708
  const githubDirectoryIndex = pathSegments.lastIndexOf(".github");
690
709
  if (githubDirectoryIndex > 0) {
691
710
  const rootSegments = pathSegments.slice(0, githubDirectoryIndex);
692
- const candidateRoot = rootSegments.join(path.sep);
711
+ const candidateRoot = (0, import_ts_extras2.arrayJoin)(rootSegments, path.sep);
693
712
  if (candidateRoot.length > 0) {
694
713
  return candidateRoot;
695
714
  }
@@ -709,12 +728,19 @@ var findRepositoryRoot = (filePath) => {
709
728
  currentDirectory = parentDirectory;
710
729
  }
711
730
  };
712
- var getRepositoryInstructionsPath = (filePath) => path.join(findRepositoryRoot(filePath), ".github", "copilot-instructions.md");
731
+ var getRepositoryInstructionsPaths = (filePath) => {
732
+ const repositoryRoot = findRepositoryRoot(filePath);
733
+ return [
734
+ path.join(repositoryRoot, ".github", "copilot-instructions.md"),
735
+ path.join(repositoryRoot, ".github", "instructions", "copilot-instructions.md")
736
+ ];
737
+ };
713
738
 
714
739
  // dist/_internal/create-copilot-rule.js
715
740
  var import_utils = require("@typescript-eslint/utils");
716
741
 
717
742
  // dist/_internal/rule-catalog.js
743
+ var import_ts_extras3 = require("ts-extras");
718
744
  var orderedRuleNames = [
719
745
  "require-instructions-apply-to",
720
746
  "require-prompt-file-metadata",
@@ -798,9 +824,7 @@ var copilotRuleCatalogEntries = orderedRuleNames.map((ruleName, index) => {
798
824
  var copilotRuleCatalogByRuleName = new Map(copilotRuleCatalogEntries.map((entry) => [entry.ruleName, entry]));
799
825
  var getRuleCatalogEntryForRuleName = (ruleName) => {
800
826
  const entry = copilotRuleCatalogByRuleName.get(ruleName);
801
- if (entry === void 0) {
802
- throw new TypeError(`Rule '${ruleName}' is missing from the stable rule catalog.`);
803
- }
827
+ (0, import_ts_extras3.assertDefined)(entry);
804
828
  return entry;
805
829
  };
806
830
 
@@ -859,6 +883,7 @@ var createCopilotRule = (ruleDefinition) => {
859
883
  };
860
884
 
861
885
  // dist/_internal/frontmatter.js
886
+ var import_ts_extras4 = require("ts-extras");
862
887
  var isAsciiLetter = (character) => character >= "A" && character <= "Z" || character >= "a" && character <= "z";
863
888
  var isYamlIdentifierCharacter = (character) => isAsciiLetter(character) || character >= "0" && character <= "9" || character === "-";
864
889
  var isSupportedFrontmatterFieldName = (value) => {
@@ -974,12 +999,15 @@ var stripQuotes = (value) => {
974
999
  function normalizeScalarValue(value) {
975
1000
  return stripQuotes(value.trim()).trim();
976
1001
  }
977
- var setObjectEntryField = (target, source) => {
1002
+ var withObjectEntryField = (target, source) => {
978
1003
  const property = parseFieldLine(source.trim());
979
1004
  if (property === null) {
980
- return;
1005
+ return { ...target };
981
1006
  }
982
- target[property.key] = normalizeScalarValue(property.value);
1007
+ return {
1008
+ ...target,
1009
+ [property.key]: normalizeScalarValue(property.value)
1010
+ };
983
1011
  };
984
1012
  var parseInlineList = (value) => {
985
1013
  const trimmedValue = value.trim();
@@ -990,7 +1018,7 @@ var parseInlineList = (value) => {
990
1018
  if (innerValue.length === 0) {
991
1019
  return [];
992
1020
  }
993
- return innerValue.split(",").map((item) => normalizeScalarValue(item)).filter((item) => item.length > 0);
1021
+ return (0, import_ts_extras4.stringSplit)(innerValue, ",").map((item) => normalizeScalarValue(item)).filter((item) => item.length > 0);
994
1022
  };
995
1023
  var parseBlockList = (lines) => lines.map((line) => {
996
1024
  const trimmedLine = line.trim();
@@ -1000,7 +1028,7 @@ var parseBlockList = (lines) => lines.map((line) => {
1000
1028
  return normalizeScalarValue(trimmedLine.slice(1));
1001
1029
  }).filter((value) => value.length > 0);
1002
1030
  var parseFrontmatterFields = (content) => {
1003
- const lines = content.replaceAll("\r\n", "\n").split("\n");
1031
+ const lines = (0, import_ts_extras4.stringSplit)(content.replaceAll("\r\n", "\n"), "\n");
1004
1032
  const fields = /* @__PURE__ */ new Map();
1005
1033
  let index = 0;
1006
1034
  while (index < lines.length) {
@@ -1082,134 +1110,145 @@ var getFrontmatterList = (document, key) => {
1082
1110
  return field?.kind === "list" && field.values.length > 0 ? field.values : void 0;
1083
1111
  };
1084
1112
  var hasFrontmatterField = (document, key) => document.fields.has(key);
1085
- var getFrontmatterObjectList = (document, key) => {
1086
- const lines = document.content.replaceAll("\r\n", "\n").split("\n");
1087
- let index = 0;
1088
- while (index < lines.length) {
1089
- const currentLine = lines[index] ?? "";
1113
+ var getFrontmatterContentLines = (document) => (0, import_ts_extras4.stringSplit)(document.content.replaceAll("\r\n", "\n"), "\n");
1114
+ var getTopLevelFrontmatterFieldBlock = (document, key) => {
1115
+ const lines = getFrontmatterContentLines(document);
1116
+ for (const [index, currentLine] of lines.entries()) {
1090
1117
  if (currentLine.startsWith(" ") || currentLine.startsWith(" ")) {
1091
- index += 1;
1092
1118
  continue;
1093
1119
  }
1094
1120
  const field = parseFieldLine(currentLine.trimEnd());
1095
- if (field === null) {
1096
- index += 1;
1097
- continue;
1098
- }
1099
- if (field.key !== key) {
1100
- index += 1;
1121
+ if (field?.key !== key) {
1101
1122
  continue;
1102
1123
  }
1103
- const rawValue = field.value.trim();
1104
- if (rawValue === "[]") {
1105
- return [];
1106
- }
1107
- if (rawValue.length > 0) {
1108
- return void 0;
1109
- }
1110
- const { blockLines } = collectIndentedBlockLines(lines, index + 1);
1111
- const entries = [];
1112
- let currentEntry = null;
1113
- for (const blockLine of blockLines) {
1114
- const trimmedLine = blockLine.trim();
1115
- if (trimmedLine.startsWith("-")) {
1116
- if (currentEntry !== null) {
1117
- entries.push(currentEntry);
1118
- }
1119
- currentEntry = {};
1120
- const inlineProperty = trimmedLine.slice(1).trim();
1121
- if (inlineProperty.length > 0) {
1122
- setObjectEntryField(currentEntry, inlineProperty);
1123
- }
1124
- continue;
1125
- }
1126
- if (currentEntry === null) {
1127
- continue;
1128
- }
1129
- setObjectEntryField(currentEntry, trimmedLine);
1130
- }
1131
- if (currentEntry !== null) {
1132
- entries.push(currentEntry);
1133
- }
1134
- return entries;
1124
+ return {
1125
+ blockLines: collectIndentedBlockLines(lines, index + 1).blockLines,
1126
+ rawValue: field.value.trim()
1127
+ };
1135
1128
  }
1136
1129
  return void 0;
1137
1130
  };
1138
- var getFrontmatterObjectListGroups = (document, key) => {
1139
- const lines = document.content.replaceAll("\r\n", "\n").split("\n");
1140
- let index = 0;
1141
- while (index < lines.length) {
1142
- const currentLine = lines[index] ?? "";
1143
- if (currentLine.startsWith(" ") || currentLine.startsWith(" ")) {
1144
- index += 1;
1131
+ var parseFrontmatterObjectListEntries = (blockLines) => {
1132
+ const entries = [];
1133
+ let currentEntry = null;
1134
+ for (const blockLine of blockLines) {
1135
+ const trimmedLine = blockLine.trim();
1136
+ if (trimmedLine.startsWith("-")) {
1137
+ if (currentEntry !== null) {
1138
+ entries.push(currentEntry);
1139
+ }
1140
+ const inlineProperty = trimmedLine.slice(1).trim();
1141
+ currentEntry = inlineProperty.length === 0 ? {} : withObjectEntryField({}, inlineProperty);
1145
1142
  continue;
1146
1143
  }
1147
- const field = parseFieldLine(currentLine.trimEnd());
1148
- if (field === null) {
1149
- index += 1;
1144
+ if (currentEntry === null) {
1150
1145
  continue;
1151
1146
  }
1152
- if (field.key !== key) {
1153
- index += 1;
1147
+ currentEntry = withObjectEntryField(currentEntry, trimmedLine);
1148
+ }
1149
+ if (currentEntry !== null) {
1150
+ entries.push(currentEntry);
1151
+ }
1152
+ return entries;
1153
+ };
1154
+ var flushGroupedObjectListEntry = (groups, state) => {
1155
+ if (state.currentGroupName === null || state.currentEntry === null) {
1156
+ return state;
1157
+ }
1158
+ const groupEntries = groups.get(state.currentGroupName) ?? [];
1159
+ groupEntries.push(state.currentEntry);
1160
+ groups.set(state.currentGroupName, groupEntries);
1161
+ return {
1162
+ ...state,
1163
+ currentEntry: null
1164
+ };
1165
+ };
1166
+ var isGroupedObjectListHeaderLine = (indentationWidth, trimmedLine) => !trimmedLine.startsWith("-") && indentationWidth <= 4;
1167
+ var createGroupedObjectListEntry = (trimmedLine) => {
1168
+ const inlineProperty = trimmedLine.slice(1).trim();
1169
+ return inlineProperty.length === 0 ? {} : withObjectEntryField({}, inlineProperty);
1170
+ };
1171
+ var handleGroupedObjectListHeaderLine = (groups, state, trimmedLine) => {
1172
+ const flushedState = flushGroupedObjectListEntry(groups, state);
1173
+ const groupField = parseFieldLine(trimmedLine);
1174
+ if (groupField === null) {
1175
+ return {
1176
+ ...flushedState,
1177
+ currentGroupName: null
1178
+ };
1179
+ }
1180
+ groups.set(groupField.key, groups.get(groupField.key) ?? []);
1181
+ return {
1182
+ ...flushedState,
1183
+ currentGroupName: groupField.key
1184
+ };
1185
+ };
1186
+ var handleGroupedObjectListEntryStartLine = (groups, state, trimmedLine) => {
1187
+ const flushedState = flushGroupedObjectListEntry(groups, state);
1188
+ if (flushedState.currentGroupName === null) {
1189
+ return flushedState;
1190
+ }
1191
+ return {
1192
+ ...flushedState,
1193
+ currentEntry: createGroupedObjectListEntry(trimmedLine)
1194
+ };
1195
+ };
1196
+ var handleGroupedObjectListPropertyLine = (state, trimmedLine) => {
1197
+ if (state.currentEntry === null) {
1198
+ return state;
1199
+ }
1200
+ return {
1201
+ ...state,
1202
+ currentEntry: withObjectEntryField(state.currentEntry, trimmedLine)
1203
+ };
1204
+ };
1205
+ var parseFrontmatterObjectListGroups = (blockLines) => {
1206
+ const groups = /* @__PURE__ */ new Map();
1207
+ let state = {
1208
+ currentEntry: null,
1209
+ currentGroupName: null
1210
+ };
1211
+ for (const blockLine of blockLines) {
1212
+ const indentationWidth = getIndentationWidth(blockLine);
1213
+ const trimmedLine = blockLine.trim();
1214
+ if (trimmedLine.length === 0) {
1154
1215
  continue;
1155
1216
  }
1156
- const rawValue = field.value.trim();
1157
- if (rawValue.length > 0) {
1158
- return void 0;
1217
+ if (isGroupedObjectListHeaderLine(indentationWidth, trimmedLine)) {
1218
+ state = handleGroupedObjectListHeaderLine(groups, state, trimmedLine);
1219
+ continue;
1159
1220
  }
1160
- const { blockLines } = collectIndentedBlockLines(lines, index + 1);
1161
- const groups = /* @__PURE__ */ new Map();
1162
- let currentGroupName = null;
1163
- let currentEntry = null;
1164
- const flushCurrentEntry = () => {
1165
- if (currentGroupName === null || currentEntry === null) {
1166
- return;
1167
- }
1168
- const groupEntries = groups.get(currentGroupName) ?? [];
1169
- groupEntries.push(currentEntry);
1170
- groups.set(currentGroupName, groupEntries);
1171
- currentEntry = null;
1172
- };
1173
- for (const blockLine of blockLines) {
1174
- const indentationWidth = getIndentationWidth(blockLine);
1175
- const trimmedLine = blockLine.trim();
1176
- if (trimmedLine.length === 0) {
1177
- continue;
1178
- }
1179
- if (!trimmedLine.startsWith("-") && indentationWidth <= 4) {
1180
- flushCurrentEntry();
1181
- const groupField = parseFieldLine(trimmedLine);
1182
- if (groupField === null) {
1183
- currentGroupName = null;
1184
- continue;
1185
- }
1186
- currentGroupName = groupField.key;
1187
- if (currentGroupName !== null && !groups.has(currentGroupName)) {
1188
- groups.set(currentGroupName, []);
1189
- }
1190
- continue;
1191
- }
1192
- if (trimmedLine.startsWith("-")) {
1193
- flushCurrentEntry();
1194
- if (currentGroupName === null) {
1195
- continue;
1196
- }
1197
- currentEntry = {};
1198
- const inlineProperty = trimmedLine.slice(1).trim();
1199
- if (inlineProperty.length > 0) {
1200
- setObjectEntryField(currentEntry, inlineProperty);
1201
- }
1202
- continue;
1203
- }
1204
- if (currentEntry === null) {
1205
- continue;
1206
- }
1207
- setObjectEntryField(currentEntry, trimmedLine);
1221
+ if (trimmedLine.startsWith("-")) {
1222
+ state = handleGroupedObjectListEntryStartLine(groups, state, trimmedLine);
1223
+ continue;
1208
1224
  }
1209
- flushCurrentEntry();
1210
- return groups;
1225
+ state = handleGroupedObjectListPropertyLine(state, trimmedLine);
1211
1226
  }
1212
- return void 0;
1227
+ flushGroupedObjectListEntry(groups, state);
1228
+ return groups;
1229
+ };
1230
+ var getFrontmatterObjectList = (document, key) => {
1231
+ const fieldBlock = getTopLevelFrontmatterFieldBlock(document, key);
1232
+ if (!(0, import_ts_extras4.isDefined)(fieldBlock)) {
1233
+ return void 0;
1234
+ }
1235
+ if (fieldBlock.rawValue === "[]") {
1236
+ return [];
1237
+ }
1238
+ if (fieldBlock.rawValue.length > 0) {
1239
+ return void 0;
1240
+ }
1241
+ return parseFrontmatterObjectListEntries(fieldBlock.blockLines);
1242
+ };
1243
+ var getFrontmatterObjectListGroups = (document, key) => {
1244
+ const fieldBlock = getTopLevelFrontmatterFieldBlock(document, key);
1245
+ if (!(0, import_ts_extras4.isDefined)(fieldBlock)) {
1246
+ return void 0;
1247
+ }
1248
+ if (fieldBlock.rawValue.length > 0) {
1249
+ return void 0;
1250
+ }
1251
+ return parseFrontmatterObjectListGroups(fieldBlock.blockLines);
1213
1252
  };
1214
1253
  var getMeaningfulMarkdownBody = (text) => stripHtmlComments(text).trim();
1215
1254
 
@@ -1259,7 +1298,8 @@ var noBlankCustomizationBodyRule = createCopilotRule({
1259
1298
  description: "disallow blank bodies in Copilot customization files other than repository-wide instructions.",
1260
1299
  frozen: false,
1261
1300
  recommended: true,
1262
- requiresTypeChecking: false
1301
+ requiresTypeChecking: false,
1302
+ url: createRuleDocsUrl("no-blank-customization-body")
1263
1303
  },
1264
1304
  messages: {
1265
1305
  blankBody: "Copilot customization files should include meaningful Markdown instructions in the document body, not only frontmatter or comments."
@@ -1299,7 +1339,8 @@ var noBlankRepositoryInstructionsRule = createCopilotRule({
1299
1339
  description: "disallow empty repository-wide Copilot instructions files.",
1300
1340
  frozen: false,
1301
1341
  recommended: true,
1302
- requiresTypeChecking: false
1342
+ requiresTypeChecking: false,
1343
+ url: createRuleDocsUrl("no-blank-repository-instructions")
1303
1344
  },
1304
1345
  messages: {
1305
1346
  blankInstructions: "Repository-wide Copilot instructions should contain actionable Markdown guidance instead of being blank."
@@ -1339,7 +1380,8 @@ var noBlankSkillBodyRule = createCopilotRule({
1339
1380
  description: "disallow blank Copilot skill definition bodies.",
1340
1381
  frozen: false,
1341
1382
  recommended: true,
1342
- requiresTypeChecking: false
1383
+ requiresTypeChecking: false,
1384
+ url: createRuleDocsUrl("no-blank-skill-body")
1343
1385
  },
1344
1386
  messages: {
1345
1387
  blankSkillBody: "Copilot skill definition files should include a non-empty Markdown body with instructions, examples, or guidance."
@@ -1378,7 +1420,8 @@ var noDeprecatedAgentInferRule = createCopilotRule({
1378
1420
  description: "disallow deprecated `infer` frontmatter in Copilot custom agent files.",
1379
1421
  frozen: false,
1380
1422
  recommended: true,
1381
- requiresTypeChecking: false
1423
+ requiresTypeChecking: false,
1424
+ url: createRuleDocsUrl("no-deprecated-agent-infer")
1382
1425
  },
1383
1426
  messages: {
1384
1427
  deprecatedInfer: "Copilot custom agent files should replace deprecated `infer` frontmatter with `user-invocable` and/or `disable-model-invocation`."
@@ -1393,6 +1436,7 @@ var no_deprecated_agent_infer_default = noDeprecatedAgentInferRule;
1393
1436
  // dist/rules/no-duplicate-agent-names.js
1394
1437
  var fs3 = __toESM(require("node:fs"), 1);
1395
1438
  var path4 = __toESM(require("node:path"), 1);
1439
+ var import_ts_extras6 = require("ts-extras");
1396
1440
 
1397
1441
  // dist/_internal/copilot-customization-names.js
1398
1442
  var path2 = __toESM(require("node:path"), 1);
@@ -1449,6 +1493,7 @@ var collectDuplicateNameGroups = (entries, normalizeName) => {
1449
1493
  // dist/_internal/file-system.js
1450
1494
  var fs2 = __toESM(require("node:fs"), 1);
1451
1495
  var path3 = __toESM(require("node:path"), 1);
1496
+ var import_ts_extras5 = require("ts-extras");
1452
1497
  var WINDOWS_ABSOLUTE_PATH_PATTERN = /^[A-Za-z]:[/\\]/u;
1453
1498
  var URI_SCHEME_PATTERN = /^[A-Za-z][+\-.0-9A-Za-z]*:/u;
1454
1499
  var normalizeAbsolutePath = (filePath) => path3.resolve(filePath).replaceAll("\\", "/");
@@ -1457,7 +1502,7 @@ var stripPathFragmentAndQuery = (value) => {
1457
1502
  const queryIndex = value.indexOf("?");
1458
1503
  const fragmentIndex = value.indexOf("#");
1459
1504
  const cutIndexCandidates = [queryIndex, fragmentIndex].filter((index) => index >= 0);
1460
- if (cutIndexCandidates.length === 0) {
1505
+ if ((0, import_ts_extras5.isEmpty)(cutIndexCandidates)) {
1461
1506
  return value;
1462
1507
  }
1463
1508
  return value.slice(0, Math.min(...cutIndexCandidates));
@@ -1481,6 +1526,30 @@ var isRelativeWorkspacePath = (value) => {
1481
1526
  };
1482
1527
  var resolveRelativeWorkspacePath = (currentFilePath, relativePath) => path3.resolve(path3.dirname(currentFilePath), stripPathFragmentAndQuery(relativePath));
1483
1528
  var resolveRepositoryRelativePath = (repositoryRootPath, relativePath) => path3.resolve(repositoryRootPath, stripPathFragmentAndQuery(relativePath));
1529
+ var collectDirectoryFiles = (currentDirectory, predicate) => {
1530
+ const discoveredFiles = [];
1531
+ const pendingDirectories = [];
1532
+ for (const entry of fs2.readdirSync(currentDirectory, {
1533
+ withFileTypes: true
1534
+ })) {
1535
+ const absoluteEntryPath = path3.join(currentDirectory, entry.name);
1536
+ if (entry.isDirectory()) {
1537
+ pendingDirectories.push(absoluteEntryPath);
1538
+ continue;
1539
+ }
1540
+ if (!entry.isFile()) {
1541
+ continue;
1542
+ }
1543
+ if ((0, import_ts_extras5.isDefined)(predicate) && !predicate(absoluteEntryPath)) {
1544
+ continue;
1545
+ }
1546
+ discoveredFiles.push(absoluteEntryPath);
1547
+ }
1548
+ return {
1549
+ discoveredFiles,
1550
+ pendingDirectories
1551
+ };
1552
+ };
1484
1553
  var listFilesRecursively = (directoryPath, predicate) => {
1485
1554
  if (!pathExists(directoryPath)) {
1486
1555
  return [];
@@ -1489,25 +1558,12 @@ var listFilesRecursively = (directoryPath, predicate) => {
1489
1558
  const pendingDirectories = [directoryPath];
1490
1559
  while (pendingDirectories.length > 0) {
1491
1560
  const currentDirectory = pendingDirectories.pop();
1492
- if (currentDirectory === void 0) {
1561
+ if (!(0, import_ts_extras5.isDefined)(currentDirectory)) {
1493
1562
  continue;
1494
1563
  }
1495
- for (const entry of fs2.readdirSync(currentDirectory, {
1496
- withFileTypes: true
1497
- })) {
1498
- const absoluteEntryPath = path3.join(currentDirectory, entry.name);
1499
- if (entry.isDirectory()) {
1500
- pendingDirectories.push(absoluteEntryPath);
1501
- continue;
1502
- }
1503
- if (!entry.isFile()) {
1504
- continue;
1505
- }
1506
- if (predicate !== void 0 && !predicate(absoluteEntryPath)) {
1507
- continue;
1508
- }
1509
- discoveredFiles.push(absoluteEntryPath);
1510
- }
1564
+ const currentDirectoryContents = collectDirectoryFiles(currentDirectory, predicate);
1565
+ pendingDirectories.push(...currentDirectoryContents.pendingDirectories);
1566
+ discoveredFiles.push(...currentDirectoryContents.discoveredFiles);
1511
1567
  }
1512
1568
  return discoveredFiles.toSorted((left, right) => left.localeCompare(right));
1513
1569
  };
@@ -1532,12 +1588,12 @@ var noDuplicateAgentNamesRule = createCopilotRule({
1532
1588
  }), normalizeNameForComparison);
1533
1589
  const currentAgentName = getAgentName(context.filename, extractFrontmatter(context.sourceCode.text));
1534
1590
  const duplicateGroup = duplicateGroups.get(normalizeNameForComparison(currentAgentName));
1535
- if (duplicateGroup === void 0) {
1591
+ if (!(0, import_ts_extras6.isDefined)(duplicateGroup)) {
1536
1592
  return;
1537
1593
  }
1538
1594
  reportAtDocumentStart(context, {
1539
1595
  data: {
1540
- files: duplicateGroup.map((entry) => normalizeRelativeFilePath(repositoryRoot, entry.filePath)).join(", "),
1596
+ files: (0, import_ts_extras6.arrayJoin)(duplicateGroup.map((entry) => normalizeRelativeFilePath(repositoryRoot, entry.filePath)), ", "),
1541
1597
  name: currentAgentName
1542
1598
  },
1543
1599
  messageId: "duplicateAgentName"
@@ -1555,7 +1611,8 @@ var noDuplicateAgentNamesRule = createCopilotRule({
1555
1611
  description: "disallow duplicate effective custom-agent names across workspace custom-agent files.",
1556
1612
  frozen: false,
1557
1613
  recommended: true,
1558
- requiresTypeChecking: false
1614
+ requiresTypeChecking: false,
1615
+ url: createRuleDocsUrl("no-duplicate-agent-names")
1559
1616
  },
1560
1617
  messages: {
1561
1618
  duplicateAgentName: "Copilot custom-agent name `{{name}}` is duplicated across agent files: {{files}}."
@@ -1570,6 +1627,7 @@ var no_duplicate_agent_names_default = noDuplicateAgentNamesRule;
1570
1627
  // dist/rules/no-duplicate-prompt-names.js
1571
1628
  var fs4 = __toESM(require("node:fs"), 1);
1572
1629
  var path5 = __toESM(require("node:path"), 1);
1630
+ var import_ts_extras7 = require("ts-extras");
1573
1631
  var normalizeRelativeFilePath2 = (repositoryRoot, filePath) => path5.relative(repositoryRoot, filePath).replaceAll("\\", "/");
1574
1632
  var noDuplicatePromptNamesRule = createCopilotRule({
1575
1633
  create(context) {
@@ -1589,12 +1647,12 @@ var noDuplicatePromptNamesRule = createCopilotRule({
1589
1647
  }), normalizeNameForComparison);
1590
1648
  const currentPromptName = getPromptName(context.filename, extractFrontmatter(context.sourceCode.text));
1591
1649
  const duplicateGroup = duplicateGroups.get(normalizeNameForComparison(currentPromptName));
1592
- if (duplicateGroup === void 0) {
1650
+ if (!(0, import_ts_extras7.isDefined)(duplicateGroup)) {
1593
1651
  return;
1594
1652
  }
1595
1653
  reportAtDocumentStart(context, {
1596
1654
  data: {
1597
- files: duplicateGroup.map((entry) => normalizeRelativeFilePath2(repositoryRoot, entry.filePath)).join(", "),
1655
+ files: (0, import_ts_extras7.arrayJoin)(duplicateGroup.map((entry) => normalizeRelativeFilePath2(repositoryRoot, entry.filePath)), ", "),
1598
1656
  name: currentPromptName
1599
1657
  },
1600
1658
  messageId: "duplicatePromptName"
@@ -1612,7 +1670,8 @@ var noDuplicatePromptNamesRule = createCopilotRule({
1612
1670
  description: "disallow duplicate effective prompt names across workspace prompt files.",
1613
1671
  frozen: false,
1614
1672
  recommended: true,
1615
- requiresTypeChecking: false
1673
+ requiresTypeChecking: false,
1674
+ url: createRuleDocsUrl("no-duplicate-prompt-names")
1616
1675
  },
1617
1676
  messages: {
1618
1677
  duplicatePromptName: "Copilot prompt name `{{name}}` is duplicated across prompt files: {{files}}."
@@ -1627,6 +1686,7 @@ var no_duplicate_prompt_names_default = noDuplicatePromptNamesRule;
1627
1686
  // dist/rules/no-duplicate-skill-names.js
1628
1687
  var fs5 = __toESM(require("node:fs"), 1);
1629
1688
  var path6 = __toESM(require("node:path"), 1);
1689
+ var import_ts_extras8 = require("ts-extras");
1630
1690
  var normalizeRelativeFilePath3 = (repositoryRoot, filePath) => path6.relative(repositoryRoot, filePath).replaceAll("\\", "/");
1631
1691
  var noDuplicateSkillNamesRule = createCopilotRule({
1632
1692
  create(context) {
@@ -1648,12 +1708,12 @@ var noDuplicateSkillNamesRule = createCopilotRule({
1648
1708
  }), normalizeNameForComparison);
1649
1709
  const currentSkillName = getSkillName(context.filename, extractFrontmatter(context.sourceCode.text));
1650
1710
  const duplicateGroup = duplicateGroups.get(normalizeNameForComparison(currentSkillName));
1651
- if (duplicateGroup === void 0) {
1711
+ if (!(0, import_ts_extras8.isDefined)(duplicateGroup)) {
1652
1712
  return;
1653
1713
  }
1654
1714
  reportAtDocumentStart(context, {
1655
1715
  data: {
1656
- files: duplicateGroup.map((entry) => normalizeRelativeFilePath3(repositoryRoot, entry.filePath)).join(", "),
1716
+ files: (0, import_ts_extras8.arrayJoin)(duplicateGroup.map((entry) => normalizeRelativeFilePath3(repositoryRoot, entry.filePath)), ", "),
1657
1717
  name: currentSkillName
1658
1718
  },
1659
1719
  messageId: "duplicateSkillName"
@@ -1671,7 +1731,8 @@ var noDuplicateSkillNamesRule = createCopilotRule({
1671
1731
  description: "disallow duplicate effective skill names across project skill definition files.",
1672
1732
  frozen: false,
1673
1733
  recommended: true,
1674
- requiresTypeChecking: false
1734
+ requiresTypeChecking: false,
1735
+ url: createRuleDocsUrl("no-duplicate-skill-names")
1675
1736
  },
1676
1737
  messages: {
1677
1738
  duplicateSkillName: "Copilot skill name `{{name}}` is duplicated across skill files: {{files}}."
@@ -1686,6 +1747,7 @@ var no_duplicate_skill_names_default = noDuplicateSkillNamesRule;
1686
1747
  // dist/rules/no-duplicate-slash-command-names.js
1687
1748
  var fs6 = __toESM(require("node:fs"), 1);
1688
1749
  var path7 = __toESM(require("node:path"), 1);
1750
+ var import_ts_extras9 = require("ts-extras");
1689
1751
  var isPromptOrSkillCommandFile = (filePath) => filePath.endsWith(".prompt.md") || isSkillFilePath(filePath);
1690
1752
  var normalizeRelativeFilePath4 = (repositoryRoot, filePath) => path7.relative(repositoryRoot, filePath).replaceAll("\\", "/");
1691
1753
  var noDuplicateSlashCommandNamesRule = createCopilotRule({
@@ -1711,12 +1773,12 @@ var noDuplicateSlashCommandNamesRule = createCopilotRule({
1711
1773
  const frontmatter = extractFrontmatter(context.sourceCode.text);
1712
1774
  const currentCommandName = context.filename.endsWith(".prompt.md") ? getPromptName(context.filename, frontmatter) : getSkillName(context.filename, frontmatter);
1713
1775
  const duplicateGroup = duplicateGroups.get(normalizeNameForComparison(currentCommandName));
1714
- if (duplicateGroup === void 0) {
1776
+ if (!(0, import_ts_extras9.isDefined)(duplicateGroup)) {
1715
1777
  return;
1716
1778
  }
1717
1779
  reportAtDocumentStart(context, {
1718
1780
  data: {
1719
- files: duplicateGroup.map((entry) => normalizeRelativeFilePath4(repositoryRoot, entry.filePath)).join(", "),
1781
+ files: (0, import_ts_extras9.arrayJoin)(duplicateGroup.map((entry) => normalizeRelativeFilePath4(repositoryRoot, entry.filePath)), ", "),
1720
1782
  name: currentCommandName
1721
1783
  },
1722
1784
  messageId: "duplicateSlashCommandName"
@@ -1734,7 +1796,8 @@ var noDuplicateSlashCommandNamesRule = createCopilotRule({
1734
1796
  description: "disallow duplicate slash-command names across prompt files and skills.",
1735
1797
  frozen: false,
1736
1798
  recommended: true,
1737
- requiresTypeChecking: false
1799
+ requiresTypeChecking: false,
1800
+ url: createRuleDocsUrl("no-duplicate-slash-command-names")
1738
1801
  },
1739
1802
  messages: {
1740
1803
  duplicateSlashCommandName: "Slash command name `{{name}}` is duplicated across prompt or skill files: {{files}}."
@@ -1746,7 +1809,11 @@ var noDuplicateSlashCommandNamesRule = createCopilotRule({
1746
1809
  });
1747
1810
  var no_duplicate_slash_command_names_default = noDuplicateSlashCommandNamesRule;
1748
1811
 
1812
+ // dist/rules/no-empty-repository-hook-arrays.js
1813
+ var import_ts_extras11 = require("ts-extras");
1814
+
1749
1815
  // dist/_internal/repository-hooks-json.js
1816
+ var import_ts_extras10 = require("ts-extras");
1750
1817
  var DEFAULT_REPOSITORY_HOOK_TIMEOUT_SECONDS = 30;
1751
1818
  var VALID_REPOSITORY_HOOK_EVENT_NAMES = /* @__PURE__ */ new Set([
1752
1819
  "agentStop",
@@ -1759,15 +1826,15 @@ var VALID_REPOSITORY_HOOK_EVENT_NAMES = /* @__PURE__ */ new Set([
1759
1826
  "userPromptSubmitted"
1760
1827
  ]);
1761
1828
  var VALID_REPOSITORY_HOOK_TYPES = /* @__PURE__ */ new Set(["command", "prompt"]);
1762
- var isRepositoryHookEventName = (value) => VALID_REPOSITORY_HOOK_EVENT_NAMES.has(value);
1763
- var isRepositoryHookType = (value) => VALID_REPOSITORY_HOOK_TYPES.has(value);
1829
+ var isRepositoryHookEventName = (value) => (0, import_ts_extras10.setHas)(VALID_REPOSITORY_HOOK_EVENT_NAMES, value);
1830
+ var isRepositoryHookType = (value) => (0, import_ts_extras10.setHas)(VALID_REPOSITORY_HOOK_TYPES, value);
1764
1831
  var isJsonObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1765
1832
  var isJsonArray = (value) => Array.isArray(value);
1766
1833
  var isJsonString = (value) => typeof value === "string";
1767
- var isJsonNumber = (value) => typeof value === "number" && Number.isFinite(value);
1834
+ var isJsonNumber = (value) => typeof value === "number" && (0, import_ts_extras10.isFinite)(value);
1768
1835
  var parseJsonText = (text) => {
1769
1836
  try {
1770
- return JSON.parse(text);
1837
+ return (0, import_ts_extras10.safeCastTo)(JSON.parse(text));
1771
1838
  } catch {
1772
1839
  return void 0;
1773
1840
  }
@@ -1776,7 +1843,7 @@ var getRepositoryHooksValue = (root) => isJsonObject(root) ? root["hooks"] : voi
1776
1843
  var getRepositoryHooksVersionValue = (root) => isJsonObject(root) ? root["version"] : void 0;
1777
1844
  var getRepositoryHookEventEntries = (root) => {
1778
1845
  const hooksValue = getRepositoryHooksValue(root);
1779
- return isJsonObject(hooksValue) ? Object.entries(hooksValue) : [];
1846
+ return isJsonObject(hooksValue) ? (0, import_ts_extras10.objectEntries)(hooksValue) : [];
1780
1847
  };
1781
1848
  var getRepositoryHookObjects = (root) => {
1782
1849
  const hookEntries = [];
@@ -1798,7 +1865,7 @@ var getRepositoryHookObjects = (root) => {
1798
1865
  return hookEntries;
1799
1866
  };
1800
1867
  var formatJsonValue = (value) => {
1801
- if (value === void 0) {
1868
+ if (!(0, import_ts_extras10.isDefined)(value)) {
1802
1869
  return "(missing)";
1803
1870
  }
1804
1871
  if (typeof value === "string") {
@@ -1816,13 +1883,13 @@ var noEmptyRepositoryHookArraysRule = createCopilotRule({
1816
1883
  return;
1817
1884
  }
1818
1885
  const root = parseJsonText(context.sourceCode.text);
1819
- const emptyEntry = getRepositoryHookEventEntries(root).find(([, eventValue]) => isJsonArray(eventValue) && eventValue.length === 0);
1820
- if (emptyEntry === void 0) {
1886
+ const emptyEntry = getRepositoryHookEventEntries(root).find(([, eventValue]) => isJsonArray(eventValue) && (0, import_ts_extras11.isEmpty)(eventValue));
1887
+ if (!(0, import_ts_extras11.isDefined)(emptyEntry)) {
1821
1888
  return;
1822
1889
  }
1823
1890
  reportAtDocumentStart(context, {
1824
1891
  data: {
1825
- eventName: emptyEntry[0]
1892
+ eventName: (0, import_ts_extras11.arrayFirst)(emptyEntry)
1826
1893
  },
1827
1894
  messageId: "emptyRepositoryHookArray"
1828
1895
  });
@@ -1836,7 +1903,8 @@ var noEmptyRepositoryHookArraysRule = createCopilotRule({
1836
1903
  description: "disallow empty repository hook arrays that opt into an event without any hook definitions.",
1837
1904
  frozen: false,
1838
1905
  recommended: false,
1839
- requiresTypeChecking: false
1906
+ requiresTypeChecking: false,
1907
+ url: createRuleDocsUrl("no-empty-repository-hook-arrays")
1840
1908
  },
1841
1909
  messages: {
1842
1910
  emptyRepositoryHookArray: "Repository hook event `{{eventName}}` should not be declared with an empty array."
@@ -1871,7 +1939,8 @@ var noLegacyChatmodeFilesRule = createCopilotRule({
1871
1939
  description: "disallow legacy Copilot `.chatmode.md` files in favor of modern `.agent.md` custom agents.",
1872
1940
  frozen: false,
1873
1941
  recommended: true,
1874
- requiresTypeChecking: false
1942
+ requiresTypeChecking: false,
1943
+ url: createRuleDocsUrl("no-legacy-chatmode-files")
1875
1944
  },
1876
1945
  messages: {
1877
1946
  legacyChatmodeFile: "Legacy Copilot `.chatmode.md` files should be migrated to `.github/agents/*.agent.md` custom agents."
@@ -1915,7 +1984,8 @@ var preferCustomInstructionsUnderCodeReviewLimitRule = createCopilotRule({
1915
1984
  description: "enforce repository and path-specific Copilot instruction files staying within the 4,000-character code-review instruction budget.",
1916
1985
  frozen: false,
1917
1986
  recommended: false,
1918
- requiresTypeChecking: false
1987
+ requiresTypeChecking: false,
1988
+ url: createRuleDocsUrl("prefer-custom-instructions-under-code-review-limit")
1919
1989
  },
1920
1990
  messages: {
1921
1991
  exceedsCodeReviewLimit: "Copilot code review only reads roughly the first {{maxCharacters}} characters of custom instructions; this file is {{characterCount}} characters long."
@@ -1928,6 +1998,7 @@ var preferCustomInstructionsUnderCodeReviewLimitRule = createCopilotRule({
1928
1998
  var prefer_custom_instructions_under_code_review_limit_default = preferCustomInstructionsUnderCodeReviewLimitRule;
1929
1999
 
1930
2000
  // dist/rules/prefer-fast-repository-hooks.js
2001
+ var import_ts_extras12 = require("ts-extras");
1931
2002
  var preferFastRepositoryHooksRule = createCopilotRule({
1932
2003
  create(context) {
1933
2004
  return {
@@ -1940,7 +2011,7 @@ var preferFastRepositoryHooksRule = createCopilotRule({
1940
2011
  const timeout2 = hook["timeoutSec"];
1941
2012
  return isJsonNumber(timeout2) && timeout2 > DEFAULT_REPOSITORY_HOOK_TIMEOUT_SECONDS;
1942
2013
  });
1943
- if (slowHook === void 0) {
2014
+ if (!(0, import_ts_extras12.isDefined)(slowHook)) {
1944
2015
  return;
1945
2016
  }
1946
2017
  const timeout = slowHook.hook["timeoutSec"];
@@ -1964,7 +2035,8 @@ var preferFastRepositoryHooksRule = createCopilotRule({
1964
2035
  description: "enforce repository hooks staying at or below the default 30-second timeout unless a slower hook is truly necessary.",
1965
2036
  frozen: false,
1966
2037
  recommended: false,
1967
- requiresTypeChecking: false
2038
+ requiresTypeChecking: false,
2039
+ url: createRuleDocsUrl("prefer-fast-repository-hooks")
1968
2040
  },
1969
2041
  messages: {
1970
2042
  slowRepositoryHookTimeout: "Repository hook `timeoutSec` for `{{eventName}}` is {{timeout}} seconds, which exceeds the default 30-second timeout budget."
@@ -1977,8 +2049,10 @@ var preferFastRepositoryHooksRule = createCopilotRule({
1977
2049
  var prefer_fast_repository_hooks_default = preferFastRepositoryHooksRule;
1978
2050
 
1979
2051
  // dist/rules/prefer-qualified-tools.js
2052
+ var import_ts_extras13 = require("ts-extras");
1980
2053
  var isQualifiedToolName = (toolName) => toolName.includes("/");
1981
2054
  var allowedUnqualifiedToolNames = /* @__PURE__ */ new Set(["agent", "runSubagent"]);
2055
+ var isAllowedUnqualifiedToolName = (toolName) => (0, import_ts_extras13.setHas)(allowedUnqualifiedToolNames, toolName);
1982
2056
  var preferQualifiedToolsRule = createCopilotRule({
1983
2057
  create(context) {
1984
2058
  return createMarkdownDocumentListener(() => {
@@ -1991,11 +2065,11 @@ var preferQualifiedToolsRule = createCopilotRule({
1991
2065
  return;
1992
2066
  }
1993
2067
  const tools = getFrontmatterList(frontmatter, "tools");
1994
- if (tools === void 0) {
2068
+ if (!(0, import_ts_extras13.isDefined)(tools)) {
1995
2069
  return;
1996
2070
  }
1997
- const firstUnqualifiedTool = tools.find((toolName) => !isQualifiedToolName(toolName) && !allowedUnqualifiedToolNames.has(toolName));
1998
- if (firstUnqualifiedTool === void 0) {
2071
+ const firstUnqualifiedTool = tools.find((toolName) => !isQualifiedToolName(toolName) && !isAllowedUnqualifiedToolName(toolName)) ?? null;
2072
+ if (firstUnqualifiedTool === null) {
1999
2073
  return;
2000
2074
  }
2001
2075
  reportAtDocumentStart(context, {
@@ -2011,7 +2085,8 @@ var preferQualifiedToolsRule = createCopilotRule({
2011
2085
  description: "enforce fully-qualified tool names in Copilot prompt files, custom agents, and legacy chat modes.",
2012
2086
  frozen: false,
2013
2087
  recommended: false,
2014
- requiresTypeChecking: false
2088
+ requiresTypeChecking: false,
2089
+ url: createRuleDocsUrl("prefer-qualified-tools")
2015
2090
  },
2016
2091
  messages: {
2017
2092
  preferQualifiedTool: "Prefer fully-qualified Copilot tool names in `tools` metadata when a documented built-in alias is not required. `{{toolName}}` should include a provider or tool-set prefix such as `search/codebase`."
@@ -2024,7 +2099,8 @@ var preferQualifiedToolsRule = createCopilotRule({
2024
2099
  var prefer_qualified_tools_default = preferQualifiedToolsRule;
2025
2100
 
2026
2101
  // dist/rules/require-agent-tool-for-subagents.js
2027
- var hasAgentTool = (tools) => tools?.some((toolName) => toolName.split("/").at(-1) === "agent") ?? false;
2102
+ var import_ts_extras14 = require("ts-extras");
2103
+ var hasAgentTool = (tools) => tools?.some((toolName) => (0, import_ts_extras14.arrayAt)((0, import_ts_extras14.stringSplit)(toolName, "/"), -1) === "agent") ?? false;
2028
2104
  var requireAgentToolForSubagentsRule = createCopilotRule({
2029
2105
  create(context) {
2030
2106
  return createMarkdownDocumentListener(() => {
@@ -2040,7 +2116,7 @@ var requireAgentToolForSubagentsRule = createCopilotRule({
2040
2116
  }
2041
2117
  const allowedAgents = getFrontmatterList(frontmatter, "agents");
2042
2118
  const agentsScalar = getFrontmatterScalar(frontmatter, "agents");
2043
- if (agentsScalar !== "*" && (allowedAgents === void 0 || allowedAgents.length === 0)) {
2119
+ if (agentsScalar !== "*" && (!(0, import_ts_extras14.isDefined)(allowedAgents) || (0, import_ts_extras14.isEmpty)(allowedAgents))) {
2044
2120
  return;
2045
2121
  }
2046
2122
  const tools = getFrontmatterList(frontmatter, "tools");
@@ -2063,7 +2139,8 @@ var requireAgentToolForSubagentsRule = createCopilotRule({
2063
2139
  description: "require custom agents that declare subagents to also include the `agent` tool.",
2064
2140
  frozen: false,
2065
2141
  recommended: true,
2066
- requiresTypeChecking: false
2142
+ requiresTypeChecking: false,
2143
+ url: createRuleDocsUrl("require-agent-tool-for-subagents")
2067
2144
  },
2068
2145
  messages: {
2069
2146
  missingAgentTool: "Copilot custom agent files that declare `agents` must include the `agent` tool in `tools`.",
@@ -2107,7 +2184,8 @@ var requireAgentsMdForCrossSurfaceAgentInstructionsRule = createCopilotRule({
2107
2184
  description: "require `CLAUDE.md` and `GEMINI.md` agent-instructions files to be paired with a sibling `AGENTS.md` for broader cross-surface support.",
2108
2185
  frozen: false,
2109
2186
  recommended: false,
2110
- requiresTypeChecking: false
2187
+ requiresTypeChecking: false,
2188
+ url: createRuleDocsUrl("require-agents-md-for-cross-surface-agent-instructions")
2111
2189
  },
2112
2190
  messages: {
2113
2191
  missingAgentsMdSibling: "`{{basename}}` is less portable across Copilot surfaces without a sibling `AGENTS.md` file in the same directory."
@@ -2120,6 +2198,7 @@ var requireAgentsMdForCrossSurfaceAgentInstructionsRule = createCopilotRule({
2120
2198
  var require_agents_md_for_cross_surface_agent_instructions_default = requireAgentsMdForCrossSurfaceAgentInstructionsRule;
2121
2199
 
2122
2200
  // dist/rules/require-chatmode-file-metadata.js
2201
+ var import_ts_extras15 = require("ts-extras");
2123
2202
  var requireChatmodeFileMetadataRule = createCopilotRule({
2124
2203
  create(context) {
2125
2204
  return createMarkdownDocumentListener(() => {
@@ -2134,7 +2213,7 @@ var requireChatmodeFileMetadataRule = createCopilotRule({
2134
2213
  return;
2135
2214
  }
2136
2215
  const description = getFrontmatterScalar(frontmatter, "description");
2137
- if (description !== void 0) {
2216
+ if ((0, import_ts_extras15.isDefined)(description)) {
2138
2217
  return;
2139
2218
  }
2140
2219
  reportAtDocumentStart(context, {
@@ -2154,7 +2233,8 @@ var requireChatmodeFileMetadataRule = createCopilotRule({
2154
2233
  description: "require custom Copilot agent files and legacy chat mode files to declare a non-empty description in frontmatter.",
2155
2234
  frozen: false,
2156
2235
  recommended: true,
2157
- requiresTypeChecking: false
2236
+ requiresTypeChecking: false,
2237
+ url: createRuleDocsUrl("require-chatmode-file-metadata")
2158
2238
  },
2159
2239
  messages: {
2160
2240
  emptyDescription: "Copilot custom agent and legacy chat mode files must define a non-empty `description` frontmatter value.",
@@ -2169,6 +2249,7 @@ var requireChatmodeFileMetadataRule = createCopilotRule({
2169
2249
  var require_chatmode_file_metadata_default = requireChatmodeFileMetadataRule;
2170
2250
 
2171
2251
  // dist/rules/require-existing-agent-hook-cwd.js
2252
+ var import_ts_extras16 = require("ts-extras");
2172
2253
  var requireExistingAgentHookCwdRule = createCopilotRule({
2173
2254
  create(context) {
2174
2255
  return createMarkdownDocumentListener(() => {
@@ -2177,7 +2258,7 @@ var requireExistingAgentHookCwdRule = createCopilotRule({
2177
2258
  }
2178
2259
  const frontmatter = extractFrontmatter(context.sourceCode.text);
2179
2260
  const hookGroups = frontmatter === null ? void 0 : getFrontmatterObjectListGroups(frontmatter, "hooks");
2180
- if (hookGroups === void 0 || hookGroups.size === 0) {
2261
+ if (!(0, import_ts_extras16.isDefined)(hookGroups) || hookGroups.size === 0) {
2181
2262
  return;
2182
2263
  }
2183
2264
  const repositoryRoot = findRepositoryRoot(context.filename);
@@ -2186,7 +2267,7 @@ var requireExistingAgentHookCwdRule = createCopilotRule({
2186
2267
  const cwd = entry["cwd"]?.trim();
2187
2268
  return typeof cwd === "string" && cwd.length > 0 && isRelativeWorkspacePath(cwd) && !pathExists(resolveRepositoryRelativePath(repositoryRoot, cwd));
2188
2269
  })?.["cwd"];
2189
- if (missingCwd === void 0) {
2270
+ if (!(0, import_ts_extras16.isDefined)(missingCwd)) {
2190
2271
  continue;
2191
2272
  }
2192
2273
  reportAtDocumentStart(context, {
@@ -2206,7 +2287,8 @@ var requireExistingAgentHookCwdRule = createCopilotRule({
2206
2287
  description: "require Copilot custom-agent hook `cwd` entries to resolve to existing repository directories.",
2207
2288
  frozen: false,
2208
2289
  recommended: false,
2209
- requiresTypeChecking: false
2290
+ requiresTypeChecking: false,
2291
+ url: createRuleDocsUrl("require-existing-agent-hook-cwd")
2210
2292
  },
2211
2293
  messages: {
2212
2294
  missingAgentHookCwd: "Copilot custom-agent hook `cwd` value `{{cwd}}` does not resolve to an existing repository path."
@@ -2219,6 +2301,7 @@ var requireExistingAgentHookCwdRule = createCopilotRule({
2219
2301
  var require_existing_agent_hook_cwd_default = requireExistingAgentHookCwdRule;
2220
2302
 
2221
2303
  // dist/rules/require-existing-agent-mcp-servers.js
2304
+ var import_ts_extras17 = require("ts-extras");
2222
2305
  var requireExistingAgentMcpServersRule = createCopilotRule({
2223
2306
  create(context) {
2224
2307
  return createMarkdownDocumentListener(() => {
@@ -2227,12 +2310,12 @@ var requireExistingAgentMcpServersRule = createCopilotRule({
2227
2310
  }
2228
2311
  const frontmatter = extractFrontmatter(context.sourceCode.text);
2229
2312
  const mcpServers = frontmatter === null ? void 0 : getFrontmatterList(frontmatter, "mcp-servers");
2230
- if (mcpServers === void 0) {
2313
+ if (!(0, import_ts_extras17.isDefined)(mcpServers)) {
2231
2314
  return;
2232
2315
  }
2233
2316
  const repositoryRoot = findRepositoryRoot(context.filename);
2234
2317
  const missingServer = mcpServers.find((serverPath) => !pathExists(resolveRepositoryRelativePath(repositoryRoot, serverPath)));
2235
- if (missingServer === void 0) {
2318
+ if (!(0, import_ts_extras17.isDefined)(missingServer)) {
2236
2319
  return;
2237
2320
  }
2238
2321
  reportAtDocumentStart(context, {
@@ -2253,7 +2336,8 @@ var requireExistingAgentMcpServersRule = createCopilotRule({
2253
2336
  description: "require Copilot custom-agent `mcp-servers` entries to resolve to existing repository files.",
2254
2337
  frozen: false,
2255
2338
  recommended: false,
2256
- requiresTypeChecking: false
2339
+ requiresTypeChecking: false,
2340
+ url: createRuleDocsUrl("require-existing-agent-mcp-servers")
2257
2341
  },
2258
2342
  messages: {
2259
2343
  missingAgentMcpServer: "Copilot custom-agent `mcp-servers` entry `{{mcpServer}}` does not resolve to an existing repository file."
@@ -2276,6 +2360,7 @@ var getCustomizationBodyWithOffset = (sourceText) => {
2276
2360
  };
2277
2361
 
2278
2362
  // dist/_internal/markdown-links.js
2363
+ var import_ts_extras18 = require("ts-extras");
2279
2364
  var FENCED_BACKTICK_CODE_BLOCK_PATTERN = /```[\s\S]*?```/gu;
2280
2365
  var FENCED_TILDE_CODE_BLOCK_PATTERN = /~~~[\s\S]*?~~~/gu;
2281
2366
  var INLINE_CODE_PATTERN = /`[^\n\r`]+`/gu;
@@ -2285,7 +2370,8 @@ var extractMarkdownLinkDestination = (rawDestination) => {
2285
2370
  if (trimmedDestination.startsWith("<") && trimmedDestination.endsWith(">")) {
2286
2371
  return trimmedDestination.slice(1, -1).trim();
2287
2372
  }
2288
- const [destination] = trimmedDestination.split(/\s+/u, 1);
2373
+ const normalizedDestination = trimmedDestination.replaceAll(/\s+/gu, " ");
2374
+ const [destination] = (0, import_ts_extras18.stringSplit)(normalizedDestination, " ");
2289
2375
  return destination?.trim() ?? "";
2290
2376
  };
2291
2377
  var extractMarkdownLinks = (text, offset = 0) => {
@@ -2377,7 +2463,8 @@ var requireExistingRelativeAgentLinksRule = createCopilotRule({
2377
2463
  description: "require relative Markdown links in Copilot custom agents to resolve to existing workspace targets.",
2378
2464
  frozen: false,
2379
2465
  recommended: false,
2380
- requiresTypeChecking: false
2466
+ requiresTypeChecking: false,
2467
+ url: createRuleDocsUrl("require-existing-relative-agent-links")
2381
2468
  },
2382
2469
  messages: {
2383
2470
  missingAgentLinkTarget: "Copilot custom-agent relative link `{{destination}}` does not resolve to an existing workspace path."
@@ -2429,7 +2516,8 @@ var requireExistingRelativeInstructionsLinksRule = createCopilotRule({
2429
2516
  description: "require relative Markdown links in path-specific Copilot instructions files to resolve to existing workspace targets.",
2430
2517
  frozen: false,
2431
2518
  recommended: false,
2432
- requiresTypeChecking: false
2519
+ requiresTypeChecking: false,
2520
+ url: createRuleDocsUrl("require-existing-relative-instructions-links")
2433
2521
  },
2434
2522
  messages: {
2435
2523
  missingInstructionsLinkTarget: "Copilot instructions relative link `{{destination}}` does not resolve to an existing workspace path."
@@ -2481,7 +2569,8 @@ var requireExistingRelativePromptLinksRule = createCopilotRule({
2481
2569
  description: "require relative Markdown links in Copilot prompt files to resolve to existing workspace targets.",
2482
2570
  frozen: false,
2483
2571
  recommended: false,
2484
- requiresTypeChecking: false
2572
+ requiresTypeChecking: false,
2573
+ url: createRuleDocsUrl("require-existing-relative-prompt-links")
2485
2574
  },
2486
2575
  messages: {
2487
2576
  missingPromptLinkTarget: "Copilot prompt-file relative link `{{destination}}` does not resolve to an existing workspace path."
@@ -2533,7 +2622,8 @@ var requireExistingRelativeSkillLinksRule = createCopilotRule({
2533
2622
  description: "require relative Markdown links in Copilot skill definition files to resolve to existing workspace resources.",
2534
2623
  frozen: false,
2535
2624
  recommended: false,
2536
- requiresTypeChecking: false
2625
+ requiresTypeChecking: false,
2626
+ url: createRuleDocsUrl("require-existing-relative-skill-links")
2537
2627
  },
2538
2628
  messages: {
2539
2629
  missingSkillLinkTarget: "Copilot skill relative link `{{destination}}` does not resolve to an existing workspace path."
@@ -2546,6 +2636,7 @@ var requireExistingRelativeSkillLinksRule = createCopilotRule({
2546
2636
  var require_existing_relative_skill_links_default = requireExistingRelativeSkillLinksRule;
2547
2637
 
2548
2638
  // dist/rules/require-existing-repository-hook-cwd.js
2639
+ var import_ts_extras19 = require("ts-extras");
2549
2640
  var requireExistingRepositoryHookCwdRule = createCopilotRule({
2550
2641
  create(context) {
2551
2642
  return {
@@ -2559,7 +2650,7 @@ var requireExistingRepositoryHookCwdRule = createCopilotRule({
2559
2650
  const cwd2 = hook["cwd"];
2560
2651
  return isJsonString(cwd2) && cwd2.trim().length > 0 && isRelativeWorkspacePath(cwd2) && !pathExists(resolveRepositoryRelativePath(repositoryRoot, cwd2));
2561
2652
  });
2562
- if (invalidHook === void 0) {
2653
+ if (!(0, import_ts_extras19.isDefined)(invalidHook)) {
2563
2654
  return;
2564
2655
  }
2565
2656
  const cwd = invalidHook.hook["cwd"];
@@ -2586,7 +2677,8 @@ var requireExistingRepositoryHookCwdRule = createCopilotRule({
2586
2677
  description: "require repository hook `cwd` values to resolve to existing repository paths.",
2587
2678
  frozen: false,
2588
2679
  recommended: false,
2589
- requiresTypeChecking: false
2680
+ requiresTypeChecking: false,
2681
+ url: createRuleDocsUrl("require-existing-repository-hook-cwd")
2590
2682
  },
2591
2683
  messages: {
2592
2684
  missingRepositoryHookCwd: "Repository hook `cwd` value `{{cwd}}` for `{{eventName}}` does not resolve to an existing repository path."
@@ -2599,6 +2691,7 @@ var requireExistingRepositoryHookCwdRule = createCopilotRule({
2599
2691
  var require_existing_repository_hook_cwd_default = requireExistingRepositoryHookCwdRule;
2600
2692
 
2601
2693
  // dist/rules/require-github-copilot-target-for-mcp-servers.js
2694
+ var import_ts_extras20 = require("ts-extras");
2602
2695
  var requireGithubCopilotTargetForMcpServersRule = createCopilotRule({
2603
2696
  create(context) {
2604
2697
  return createMarkdownDocumentListener(() => {
@@ -2613,7 +2706,7 @@ var requireGithubCopilotTargetForMcpServersRule = createCopilotRule({
2613
2706
  if (target === "github-copilot") {
2614
2707
  return;
2615
2708
  }
2616
- if (target === void 0) {
2709
+ if (!(0, import_ts_extras20.isDefined)(target)) {
2617
2710
  reportAtDocumentStart(context, {
2618
2711
  messageId: hasFrontmatterField(frontmatter, "target") ? "emptyTarget" : "missingTarget"
2619
2712
  });
@@ -2636,7 +2729,8 @@ var requireGithubCopilotTargetForMcpServersRule = createCopilotRule({
2636
2729
  description: "require custom agents that declare `mcp-servers` to set `target: github-copilot`.",
2637
2730
  frozen: false,
2638
2731
  recommended: true,
2639
- requiresTypeChecking: false
2732
+ requiresTypeChecking: false,
2733
+ url: createRuleDocsUrl("require-github-copilot-target-for-mcp-servers")
2640
2734
  },
2641
2735
  messages: {
2642
2736
  emptyTarget: "Copilot custom agent files that declare `mcp-servers` must define a non-empty `target: github-copilot` frontmatter value.",
@@ -2651,6 +2745,7 @@ var requireGithubCopilotTargetForMcpServersRule = createCopilotRule({
2651
2745
  var require_github_copilot_target_for_mcp_servers_default = requireGithubCopilotTargetForMcpServersRule;
2652
2746
 
2653
2747
  // dist/rules/require-instructions-apply-to.js
2748
+ var import_ts_extras21 = require("ts-extras");
2654
2749
  var requireInstructionsApplyToRule = createCopilotRule({
2655
2750
  create(context) {
2656
2751
  return createMarkdownDocumentListener(() => {
@@ -2666,7 +2761,7 @@ var requireInstructionsApplyToRule = createCopilotRule({
2666
2761
  }
2667
2762
  const applyToScalar = getFrontmatterScalar(frontmatter, "applyTo");
2668
2763
  const applyToList = getFrontmatterList(frontmatter, "applyTo");
2669
- if (applyToScalar !== void 0 || applyToList !== void 0) {
2764
+ if ((0, import_ts_extras21.isDefined)(applyToScalar) || (0, import_ts_extras21.isDefined)(applyToList)) {
2670
2765
  return;
2671
2766
  }
2672
2767
  reportAtDocumentStart(context, {
@@ -2686,7 +2781,8 @@ var requireInstructionsApplyToRule = createCopilotRule({
2686
2781
  description: "require path-specific Copilot instructions files to declare a non-empty `applyTo` frontmatter glob.",
2687
2782
  frozen: false,
2688
2783
  recommended: true,
2689
- requiresTypeChecking: false
2784
+ requiresTypeChecking: false,
2785
+ url: createRuleDocsUrl("require-instructions-apply-to")
2690
2786
  },
2691
2787
  messages: {
2692
2788
  emptyApplyTo: "Copilot instructions files must define a non-empty `applyTo` frontmatter value.",
@@ -2701,6 +2797,7 @@ var requireInstructionsApplyToRule = createCopilotRule({
2701
2797
  var require_instructions_apply_to_default = requireInstructionsApplyToRule;
2702
2798
 
2703
2799
  // dist/rules/require-json-agent-mcp-servers.js
2800
+ var import_ts_extras22 = require("ts-extras");
2704
2801
  var JSON_FILE_EXTENSION_PATTERN = /\.json$/iu;
2705
2802
  var requireJsonAgentMcpServersRule = createCopilotRule({
2706
2803
  create(context) {
@@ -2710,11 +2807,11 @@ var requireJsonAgentMcpServersRule = createCopilotRule({
2710
2807
  }
2711
2808
  const frontmatter = extractFrontmatter(context.sourceCode.text);
2712
2809
  const mcpServers = frontmatter === null ? void 0 : getFrontmatterList(frontmatter, "mcp-servers");
2713
- if (mcpServers === void 0) {
2810
+ if (!(0, import_ts_extras22.isDefined)(mcpServers)) {
2714
2811
  return;
2715
2812
  }
2716
2813
  const invalidServer = mcpServers.find((serverPath) => !JSON_FILE_EXTENSION_PATTERN.test(serverPath.trim()));
2717
- if (invalidServer === void 0) {
2814
+ if (!(0, import_ts_extras22.isDefined)(invalidServer)) {
2718
2815
  return;
2719
2816
  }
2720
2817
  reportAtDocumentStart(context, {
@@ -2736,7 +2833,8 @@ var requireJsonAgentMcpServersRule = createCopilotRule({
2736
2833
  description: "require Copilot custom-agent `mcp-servers` entries to reference JSON config files.",
2737
2834
  frozen: false,
2738
2835
  recommended: true,
2739
- requiresTypeChecking: false
2836
+ requiresTypeChecking: false,
2837
+ url: createRuleDocsUrl("require-json-agent-mcp-servers")
2740
2838
  },
2741
2839
  messages: {
2742
2840
  nonJsonAgentMcpServer: "Copilot custom-agent `mcp-servers` entry `{{mcpServer}}` should reference a `.json` config file."
@@ -2749,11 +2847,41 @@ var requireJsonAgentMcpServersRule = createCopilotRule({
2749
2847
  var require_json_agent_mcp_servers_default = requireJsonAgentMcpServersRule;
2750
2848
 
2751
2849
  // dist/rules/require-prompt-file-metadata.js
2850
+ var import_ts_extras23 = require("ts-extras");
2752
2851
  var VALID_BUILT_IN_PROMPT_AGENTS = /* @__PURE__ */ new Set([
2753
2852
  "agent",
2754
2853
  "ask",
2755
2854
  "plan"
2756
2855
  ]);
2856
+ var getRequiredPromptScalar = (context, frontmatter, key, emptyMessageId, missingMessageId) => {
2857
+ const value = getFrontmatterScalar(frontmatter, key);
2858
+ if ((0, import_ts_extras23.isDefined)(value)) {
2859
+ return value;
2860
+ }
2861
+ reportAtDocumentStart(context, {
2862
+ messageId: hasFrontmatterField(frontmatter, key) ? emptyMessageId : missingMessageId
2863
+ });
2864
+ return void 0;
2865
+ };
2866
+ var reportAgentToolsRequirement = (context, frontmatter, agent, tools) => {
2867
+ if (agent === "agent") {
2868
+ if ((0, import_ts_extras23.isDefined)(tools)) {
2869
+ return false;
2870
+ }
2871
+ reportAtDocumentStart(context, {
2872
+ messageId: hasFrontmatterField(frontmatter, "tools") ? "emptyTools" : "missingTools"
2873
+ });
2874
+ return true;
2875
+ }
2876
+ if ((0, import_ts_extras23.setHas)(VALID_BUILT_IN_PROMPT_AGENTS, agent) && hasFrontmatterField(frontmatter, "tools")) {
2877
+ reportAtDocumentStart(context, {
2878
+ data: { agent },
2879
+ messageId: "unexpectedTools"
2880
+ });
2881
+ return true;
2882
+ }
2883
+ return false;
2884
+ };
2757
2885
  var requirePromptFileMetadataRule = createCopilotRule({
2758
2886
  create(context) {
2759
2887
  return createMarkdownDocumentListener(() => {
@@ -2767,11 +2895,8 @@ var requirePromptFileMetadataRule = createCopilotRule({
2767
2895
  });
2768
2896
  return;
2769
2897
  }
2770
- const description = getFrontmatterScalar(frontmatter, "description");
2771
- if (description === void 0) {
2772
- reportAtDocumentStart(context, {
2773
- messageId: hasFrontmatterField(frontmatter, "description") ? "emptyDescription" : "missingDescription"
2774
- });
2898
+ const description = getRequiredPromptScalar(context, frontmatter, "description", "emptyDescription", "missingDescription");
2899
+ if (!(0, import_ts_extras23.isDefined)(description)) {
2775
2900
  return;
2776
2901
  }
2777
2902
  if (hasFrontmatterField(frontmatter, "mode")) {
@@ -2780,29 +2905,12 @@ var requirePromptFileMetadataRule = createCopilotRule({
2780
2905
  });
2781
2906
  return;
2782
2907
  }
2783
- const agent = getFrontmatterScalar(frontmatter, "agent");
2784
- if (agent === void 0) {
2785
- reportAtDocumentStart(context, {
2786
- messageId: hasFrontmatterField(frontmatter, "agent") ? "emptyAgent" : "missingAgent"
2787
- });
2908
+ const agent = getRequiredPromptScalar(context, frontmatter, "agent", "emptyAgent", "missingAgent");
2909
+ if (!(0, import_ts_extras23.isDefined)(agent)) {
2788
2910
  return;
2789
2911
  }
2790
2912
  const tools = getFrontmatterList(frontmatter, "tools");
2791
- if (agent === "agent") {
2792
- if (tools !== void 0) {
2793
- return;
2794
- }
2795
- reportAtDocumentStart(context, {
2796
- messageId: hasFrontmatterField(frontmatter, "tools") ? "emptyTools" : "missingTools"
2797
- });
2798
- return;
2799
- }
2800
- if (VALID_BUILT_IN_PROMPT_AGENTS.has(agent) && hasFrontmatterField(frontmatter, "tools")) {
2801
- reportAtDocumentStart(context, {
2802
- data: { agent },
2803
- messageId: "unexpectedTools"
2804
- });
2805
- }
2913
+ reportAgentToolsRequirement(context, frontmatter, agent, tools);
2806
2914
  });
2807
2915
  },
2808
2916
  meta: {
@@ -2817,7 +2925,8 @@ var requirePromptFileMetadataRule = createCopilotRule({
2817
2925
  description: "require reusable Copilot prompt files to declare description, agent, and built-in agent-mode tools metadata.",
2818
2926
  frozen: false,
2819
2927
  recommended: true,
2820
- requiresTypeChecking: false
2928
+ requiresTypeChecking: false,
2929
+ url: createRuleDocsUrl("require-prompt-file-metadata")
2821
2930
  },
2822
2931
  messages: {
2823
2932
  deprecatedMode: "Copilot prompt files should use `agent` instead of the deprecated `mode` frontmatter key.",
@@ -2838,6 +2947,7 @@ var requirePromptFileMetadataRule = createCopilotRule({
2838
2947
  var require_prompt_file_metadata_default = requirePromptFileMetadataRule;
2839
2948
 
2840
2949
  // dist/rules/require-qualified-agent-handoff-models.js
2950
+ var import_ts_extras24 = require("ts-extras");
2841
2951
  var isQualifiedModelName = (value) => {
2842
2952
  const trimmedValue = value.trim();
2843
2953
  if (!trimmedValue.endsWith(")")) {
@@ -2861,12 +2971,12 @@ var requireQualifiedAgentHandoffModelsRule = createCopilotRule({
2861
2971
  return;
2862
2972
  }
2863
2973
  const handoffs = getFrontmatterObjectList(frontmatter, "handoffs");
2864
- if (handoffs === void 0 || handoffs.length === 0) {
2974
+ if (!(0, import_ts_extras24.isDefined)(handoffs) || (0, import_ts_extras24.isEmpty)(handoffs)) {
2865
2975
  return;
2866
2976
  }
2867
2977
  for (const [index, handoff] of handoffs.entries()) {
2868
2978
  const model = handoff["model"]?.trim();
2869
- if (model === void 0 || model.length === 0 || isQualifiedModelName(model)) {
2979
+ if (!(0, import_ts_extras24.isDefined)(model) || model.length === 0 || isQualifiedModelName(model)) {
2870
2980
  continue;
2871
2981
  }
2872
2982
  reportAtDocumentStart(context, {
@@ -2891,7 +3001,8 @@ var requireQualifiedAgentHandoffModelsRule = createCopilotRule({
2891
3001
  description: "require Copilot custom-agent handoff models to use qualified `Model Name (vendor)` names.",
2892
3002
  frozen: false,
2893
3003
  recommended: true,
2894
- requiresTypeChecking: false
3004
+ requiresTypeChecking: false,
3005
+ url: createRuleDocsUrl("require-qualified-agent-handoff-models")
2895
3006
  },
2896
3007
  messages: {
2897
3008
  unqualifiedHandoffModel: "Copilot custom agent handoff #{{handoffNumber}} should use a qualified `handoffs.model` name like `GPT-5 (copilot)`, not `{{model}}`."
@@ -2904,6 +3015,7 @@ var requireQualifiedAgentHandoffModelsRule = createCopilotRule({
2904
3015
  var require_qualified_agent_handoff_models_default = requireQualifiedAgentHandoffModelsRule;
2905
3016
 
2906
3017
  // dist/rules/require-relative-agent-hook-cwd.js
3018
+ var import_ts_extras25 = require("ts-extras");
2907
3019
  var isValidRelativeHookCwd = (cwd) => {
2908
3020
  const trimmedCwd = cwd.trim();
2909
3021
  return trimmedCwd.length > 0 && isRelativeWorkspacePath(trimmedCwd);
@@ -2919,13 +3031,13 @@ var requireRelativeAgentHookCwdRule = createCopilotRule({
2919
3031
  return;
2920
3032
  }
2921
3033
  const hookGroups = getFrontmatterObjectListGroups(frontmatter, "hooks");
2922
- if (hookGroups === void 0 || hookGroups.size === 0) {
3034
+ if (!(0, import_ts_extras25.isDefined)(hookGroups) || hookGroups.size === 0) {
2923
3035
  return;
2924
3036
  }
2925
3037
  for (const [eventName, hooks] of hookGroups) {
2926
3038
  for (const [index, hook] of hooks.entries()) {
2927
3039
  const cwd = hook["cwd"]?.trim();
2928
- if (cwd === void 0 || isValidRelativeHookCwd(cwd)) {
3040
+ if (!(0, import_ts_extras25.isDefined)(cwd) || isValidRelativeHookCwd(cwd)) {
2929
3041
  continue;
2930
3042
  }
2931
3043
  reportAtDocumentStart(context, {
@@ -2952,7 +3064,8 @@ var requireRelativeAgentHookCwdRule = createCopilotRule({
2952
3064
  description: "require Copilot custom-agent hook `cwd` values to stay relative to the repository root.",
2953
3065
  frozen: false,
2954
3066
  recommended: true,
2955
- requiresTypeChecking: false
3067
+ requiresTypeChecking: false,
3068
+ url: createRuleDocsUrl("require-relative-agent-hook-cwd")
2956
3069
  },
2957
3070
  messages: {
2958
3071
  invalidHookCwd: "Copilot custom agent hook #{{hookNumber}} in `{{eventName}}` must use a non-empty repository-relative `cwd` value, not `{{currentValue}}`."
@@ -3002,7 +3115,8 @@ var requireRelativeAgentLinksRule = createCopilotRule({
3002
3115
  description: "require Copilot custom agents to use relative Markdown links for workspace files.",
3003
3116
  frozen: false,
3004
3117
  recommended: true,
3005
- requiresTypeChecking: false
3118
+ requiresTypeChecking: false,
3119
+ url: createRuleDocsUrl("require-relative-agent-links")
3006
3120
  },
3007
3121
  messages: {
3008
3122
  nonRelativeAgentLink: "Copilot custom agents should reference workspace files with relative Markdown links, not `{{destination}}`."
@@ -3052,7 +3166,8 @@ var requireRelativeInstructionsLinksRule = createCopilotRule({
3052
3166
  description: "require path-specific Copilot instructions files to use relative Markdown links for workspace files.",
3053
3167
  frozen: false,
3054
3168
  recommended: true,
3055
- requiresTypeChecking: false
3169
+ requiresTypeChecking: false,
3170
+ url: createRuleDocsUrl("require-relative-instructions-links")
3056
3171
  },
3057
3172
  messages: {
3058
3173
  nonRelativeInstructionsLink: "Copilot instructions files should reference workspace files with relative Markdown links, not `{{destination}}`."
@@ -3120,7 +3235,8 @@ var requireRelativePromptLinksRule = createCopilotRule({
3120
3235
  description: "require Copilot prompt files to use relative Markdown links for workspace files.",
3121
3236
  frozen: false,
3122
3237
  recommended: true,
3123
- requiresTypeChecking: false
3238
+ requiresTypeChecking: false,
3239
+ url: createRuleDocsUrl("require-relative-prompt-links")
3124
3240
  },
3125
3241
  messages: {
3126
3242
  nonRelativePromptLink: "Copilot prompt files should reference workspace files with relative Markdown links, not `{{destination}}`."
@@ -3133,6 +3249,7 @@ var requireRelativePromptLinksRule = createCopilotRule({
3133
3249
  var require_relative_prompt_links_default = requireRelativePromptLinksRule;
3134
3250
 
3135
3251
  // dist/rules/require-relative-repository-hook-cwd.js
3252
+ var import_ts_extras26 = require("ts-extras");
3136
3253
  var requireRelativeRepositoryHookCwdRule = createCopilotRule({
3137
3254
  create(context) {
3138
3255
  return {
@@ -3145,7 +3262,7 @@ var requireRelativeRepositoryHookCwdRule = createCopilotRule({
3145
3262
  const cwd2 = hook["cwd"];
3146
3263
  return isJsonString(cwd2) && isNonRelativeWorkspacePath(cwd2);
3147
3264
  });
3148
- if (invalidHook === void 0) {
3265
+ if (!(0, import_ts_extras26.isDefined)(invalidHook)) {
3149
3266
  return;
3150
3267
  }
3151
3268
  const cwd = invalidHook.hook["cwd"];
@@ -3173,7 +3290,8 @@ var requireRelativeRepositoryHookCwdRule = createCopilotRule({
3173
3290
  description: "require repository hook `cwd` values to use repository-relative paths.",
3174
3291
  frozen: false,
3175
3292
  recommended: true,
3176
- requiresTypeChecking: false
3293
+ requiresTypeChecking: false,
3294
+ url: createRuleDocsUrl("require-relative-repository-hook-cwd")
3177
3295
  },
3178
3296
  messages: {
3179
3297
  nonRelativeRepositoryHookCwd: "Repository hook `cwd` values for `{{eventName}}` should use repository-relative paths, not `{{cwd}}`."
@@ -3223,7 +3341,8 @@ var requireRelativeSkillLinksRule = createCopilotRule({
3223
3341
  description: "require Copilot skill definition files to use relative Markdown links for workspace resources.",
3224
3342
  frozen: false,
3225
3343
  recommended: true,
3226
- requiresTypeChecking: false
3344
+ requiresTypeChecking: false,
3345
+ url: createRuleDocsUrl("require-relative-skill-links")
3227
3346
  },
3228
3347
  messages: {
3229
3348
  nonRelativeSkillLink: "Copilot skill definition files should reference workspace resources with relative Markdown links, not `{{destination}}`."
@@ -3236,6 +3355,7 @@ var requireRelativeSkillLinksRule = createCopilotRule({
3236
3355
  var require_relative_skill_links_default = requireRelativeSkillLinksRule;
3237
3356
 
3238
3357
  // dist/rules/require-repository-hook-arrays.js
3358
+ var import_ts_extras27 = require("ts-extras");
3239
3359
  var requireRepositoryHookArraysRule = createCopilotRule({
3240
3360
  create(context) {
3241
3361
  return {
@@ -3244,13 +3364,13 @@ var requireRepositoryHookArraysRule = createCopilotRule({
3244
3364
  return;
3245
3365
  }
3246
3366
  const root = parseJsonText(context.sourceCode.text);
3247
- const invalidEntry = getRepositoryHookEventEntries(root).find(([, eventValue]) => !isJsonArray(eventValue));
3248
- if (invalidEntry === void 0) {
3367
+ const invalidEntry = getRepositoryHookEventEntries(root).find(([, eventValue]) => !isJsonArray(eventValue)) ?? null;
3368
+ if (invalidEntry === null) {
3249
3369
  return;
3250
3370
  }
3251
3371
  reportAtDocumentStart(context, {
3252
3372
  data: {
3253
- eventName: invalidEntry[0],
3373
+ eventName: (0, import_ts_extras27.arrayFirst)(invalidEntry),
3254
3374
  value: formatJsonValue(invalidEntry[1])
3255
3375
  },
3256
3376
  messageId: "invalidRepositoryHookArray"
@@ -3269,7 +3389,8 @@ var requireRepositoryHookArraysRule = createCopilotRule({
3269
3389
  description: "require each repository hook event entry in `hooks` to be an array.",
3270
3390
  frozen: false,
3271
3391
  recommended: true,
3272
- requiresTypeChecking: false
3392
+ requiresTypeChecking: false,
3393
+ url: createRuleDocsUrl("require-repository-hook-arrays")
3273
3394
  },
3274
3395
  messages: {
3275
3396
  invalidRepositoryHookArray: "Repository hook event `{{eventName}}` must map to an array of hook definitions (current value: `{{value}}`)."
@@ -3282,6 +3403,7 @@ var requireRepositoryHookArraysRule = createCopilotRule({
3282
3403
  var require_repository_hook_arrays_default = requireRepositoryHookArraysRule;
3283
3404
 
3284
3405
  // dist/rules/require-repository-hook-command-shell.js
3406
+ var import_ts_extras28 = require("ts-extras");
3285
3407
  var hasHookShellCommand = (value) => typeof value === "string" && value.trim().length > 0;
3286
3408
  var requireRepositoryHookCommandShellRule = createCopilotRule({
3287
3409
  create(context) {
@@ -3292,7 +3414,7 @@ var requireRepositoryHookCommandShellRule = createCopilotRule({
3292
3414
  }
3293
3415
  const root = parseJsonText(context.sourceCode.text);
3294
3416
  const invalidHook = getRepositoryHookObjects(root).find(({ hook }) => isJsonString(hook["type"]) && hook["type"] === "command" && !hasHookShellCommand(hook["bash"]) && !hasHookShellCommand(hook["powershell"]));
3295
- if (invalidHook === void 0) {
3417
+ if (!(0, import_ts_extras28.isDefined)(invalidHook)) {
3296
3418
  return;
3297
3419
  }
3298
3420
  reportAtDocumentStart(context, {
@@ -3315,7 +3437,8 @@ var requireRepositoryHookCommandShellRule = createCopilotRule({
3315
3437
  description: "require repository `command` hook definitions to declare at least one shell command under `bash` or `powershell`.",
3316
3438
  frozen: false,
3317
3439
  recommended: true,
3318
- requiresTypeChecking: false
3440
+ requiresTypeChecking: false,
3441
+ url: createRuleDocsUrl("require-repository-hook-command-shell")
3319
3442
  },
3320
3443
  messages: {
3321
3444
  missingRepositoryHookShellCommand: "Repository `command` hooks for `{{eventName}}` must declare a non-empty `bash` or `powershell` command."
@@ -3357,7 +3480,8 @@ var requireRepositoryHooksObjectRule = createCopilotRule({
3357
3480
  description: "require repository hook configuration files to declare a top-level `hooks` object.",
3358
3481
  frozen: false,
3359
3482
  recommended: true,
3360
- requiresTypeChecking: false
3483
+ requiresTypeChecking: false,
3484
+ url: createRuleDocsUrl("require-repository-hooks-object")
3361
3485
  },
3362
3486
  messages: {
3363
3487
  invalidRepositoryHooksObject: "Repository hook configuration files must declare a top-level `hooks` object."
@@ -3378,8 +3502,8 @@ var requireRepositoryInstructionsFileRule = createCopilotRule({
3378
3502
  if (fileKind !== "agent-instructions" && fileKind !== "chatmode" && fileKind !== "instructions" && fileKind !== "prompt") {
3379
3503
  return;
3380
3504
  }
3381
- const repositoryInstructionsPath = getRepositoryInstructionsPath(context.filename);
3382
- if (fs7.existsSync(repositoryInstructionsPath)) {
3505
+ const repositoryInstructionsPaths = getRepositoryInstructionsPaths(context.filename);
3506
+ if (repositoryInstructionsPaths.some((repositoryInstructionsPath) => fs7.existsSync(repositoryInstructionsPath))) {
3383
3507
  return;
3384
3508
  }
3385
3509
  reportAtDocumentStart(context, {
@@ -3394,13 +3518,14 @@ var requireRepositoryInstructionsFileRule = createCopilotRule({
3394
3518
  "copilot.configs.strict",
3395
3519
  "copilot.configs.all"
3396
3520
  ],
3397
- description: "require repositories that define Copilot customization assets to also provide `.github/copilot-instructions.md`.",
3521
+ description: "require repositories that define Copilot customization assets to also provide repository instructions via `.github/copilot-instructions.md` or `.github/instructions/copilot-instructions.md`.",
3398
3522
  frozen: false,
3399
3523
  recommended: false,
3400
- requiresTypeChecking: false
3524
+ requiresTypeChecking: false,
3525
+ url: createRuleDocsUrl("require-repository-instructions-file")
3401
3526
  },
3402
3527
  messages: {
3403
- missingRepositoryInstructions: "Repositories that define Copilot prompts, custom agents, legacy chat modes, agent instructions, or path-specific instructions should also provide `.github/copilot-instructions.md` for baseline repository guidance."
3528
+ missingRepositoryInstructions: "Repositories that define Copilot prompts, custom agents, legacy chat modes, agent instructions, or path-specific instructions should also provide baseline repository guidance in `.github/copilot-instructions.md` or `.github/instructions/copilot-instructions.md`."
3404
3529
  },
3405
3530
  schema: [],
3406
3531
  type: "suggestion"
@@ -3445,7 +3570,8 @@ var requireSkillFileLocationRule = createCopilotRule({
3445
3570
  description: "require project skill definition files to live at a documented `.github/skills/<skill>/SKILL.md` or `.claude/skills/<skill>/SKILL.md` path.",
3446
3571
  frozen: false,
3447
3572
  recommended: true,
3448
- requiresTypeChecking: false
3573
+ requiresTypeChecking: false,
3574
+ url: createRuleDocsUrl("require-skill-file-location")
3449
3575
  },
3450
3576
  messages: {
3451
3577
  invalidSkillLocation: "Copilot skill definition files should live at `.github/skills/<skill>/SKILL.md` or `.claude/skills/<skill>/SKILL.md`."
@@ -3458,6 +3584,7 @@ var requireSkillFileLocationRule = createCopilotRule({
3458
3584
  var require_skill_file_location_default = requireSkillFileLocationRule;
3459
3585
 
3460
3586
  // dist/rules/require-skill-file-metadata.js
3587
+ var import_ts_extras29 = require("ts-extras");
3461
3588
  var requireSkillFileMetadataRule = createCopilotRule({
3462
3589
  create(context) {
3463
3590
  return createMarkdownDocumentListener(() => {
@@ -3471,13 +3598,13 @@ var requireSkillFileMetadataRule = createCopilotRule({
3471
3598
  });
3472
3599
  return;
3473
3600
  }
3474
- if (getFrontmatterScalar(frontmatter, "name") === void 0) {
3601
+ if (!(0, import_ts_extras29.isDefined)(getFrontmatterScalar(frontmatter, "name"))) {
3475
3602
  reportAtDocumentStart(context, {
3476
3603
  messageId: "missingSkillName"
3477
3604
  });
3478
3605
  return;
3479
3606
  }
3480
- if (getFrontmatterScalar(frontmatter, "description") === void 0) {
3607
+ if (!(0, import_ts_extras29.isDefined)(getFrontmatterScalar(frontmatter, "description"))) {
3481
3608
  reportAtDocumentStart(context, {
3482
3609
  messageId: "missingSkillDescription"
3483
3610
  });
@@ -3495,7 +3622,8 @@ var requireSkillFileMetadataRule = createCopilotRule({
3495
3622
  description: "require Copilot skill definition files to declare `name` and `description` frontmatter.",
3496
3623
  frozen: false,
3497
3624
  recommended: true,
3498
- requiresTypeChecking: false
3625
+ requiresTypeChecking: false,
3626
+ url: createRuleDocsUrl("require-skill-file-metadata")
3499
3627
  },
3500
3628
  messages: {
3501
3629
  missingSkillDescription: "Copilot skill definition files must declare a non-empty `description` frontmatter value.",
@@ -3543,7 +3671,8 @@ var requireSkillMdFilenameRule = createCopilotRule({
3543
3671
  description: "require markdown files that declare skill-definition frontmatter to use the documented `SKILL.md` filename.",
3544
3672
  frozen: false,
3545
3673
  recommended: true,
3546
- requiresTypeChecking: false
3674
+ requiresTypeChecking: false,
3675
+ url: createRuleDocsUrl("require-skill-md-filename")
3547
3676
  },
3548
3677
  messages: {
3549
3678
  invalidSkillDefinitionFilename: "Skill-definition markdown files should be named `SKILL.md`, not `{{basename}}`."
@@ -3556,6 +3685,7 @@ var requireSkillMdFilenameRule = createCopilotRule({
3556
3685
  var require_skill_md_filename_default = requireSkillMdFilenameRule;
3557
3686
 
3558
3687
  // dist/rules/require-skill-name-match-directory.js
3688
+ var import_ts_extras30 = require("ts-extras");
3559
3689
  var requireSkillNameMatchDirectoryRule = createCopilotRule({
3560
3690
  create(context) {
3561
3691
  return createMarkdownDocumentListener(() => {
@@ -3564,7 +3694,7 @@ var requireSkillNameMatchDirectoryRule = createCopilotRule({
3564
3694
  }
3565
3695
  const frontmatter = extractFrontmatter(context.sourceCode.text);
3566
3696
  const explicitSkillName = frontmatter === null ? void 0 : getFrontmatterScalar(frontmatter, "name");
3567
- if (explicitSkillName === void 0) {
3697
+ if (!(0, import_ts_extras30.isDefined)(explicitSkillName)) {
3568
3698
  return;
3569
3699
  }
3570
3700
  const skillName = getSkillName(context.filename, frontmatter);
@@ -3591,7 +3721,8 @@ var requireSkillNameMatchDirectoryRule = createCopilotRule({
3591
3721
  description: "require Copilot skill `name` metadata to match the skill directory name.",
3592
3722
  frozen: false,
3593
3723
  recommended: false,
3594
- requiresTypeChecking: false
3724
+ requiresTypeChecking: false,
3725
+ url: createRuleDocsUrl("require-skill-name-match-directory")
3595
3726
  },
3596
3727
  messages: {
3597
3728
  skillNameDoesNotMatchDirectory: "Copilot skill `name` value `{{name}}` should match its directory name `{{directoryName}}`."
@@ -3604,6 +3735,7 @@ var requireSkillNameMatchDirectoryRule = createCopilotRule({
3604
3735
  var require_skill_name_match_directory_default = requireSkillNameMatchDirectoryRule;
3605
3736
 
3606
3737
  // dist/rules/require-string-repository-hook-env-values.js
3738
+ var import_ts_extras31 = require("ts-extras");
3607
3739
  var requireStringRepositoryHookEnvValuesRule = createCopilotRule({
3608
3740
  create(context) {
3609
3741
  return {
@@ -3614,9 +3746,9 @@ var requireStringRepositoryHookEnvValuesRule = createCopilotRule({
3614
3746
  const root = parseJsonText(context.sourceCode.text);
3615
3747
  const invalidHook = getRepositoryHookObjects(root).find(({ hook }) => {
3616
3748
  const env2 = hook["env"];
3617
- return isJsonObject(env2) && Object.values(env2).some((value) => !isJsonString(value));
3749
+ return isJsonObject(env2) && (0, import_ts_extras31.objectValues)(env2).some((value) => !isJsonString(value));
3618
3750
  });
3619
- if (invalidHook === void 0) {
3751
+ if (!(0, import_ts_extras31.isDefined)(invalidHook)) {
3620
3752
  return;
3621
3753
  }
3622
3754
  const env = invalidHook.hook["env"];
@@ -3641,7 +3773,8 @@ var requireStringRepositoryHookEnvValuesRule = createCopilotRule({
3641
3773
  description: "require repository hook `env` objects to use string values.",
3642
3774
  frozen: false,
3643
3775
  recommended: true,
3644
- requiresTypeChecking: false
3776
+ requiresTypeChecking: false,
3777
+ url: createRuleDocsUrl("require-string-repository-hook-env-values")
3645
3778
  },
3646
3779
  messages: {
3647
3780
  nonStringRepositoryHookEnvValue: "Repository hook `env` for `{{eventName}}` must use string values only (current value: `{{env}}`)."
@@ -3654,6 +3787,7 @@ var requireStringRepositoryHookEnvValuesRule = createCopilotRule({
3654
3787
  var require_string_repository_hook_env_values_default = requireStringRepositoryHookEnvValuesRule;
3655
3788
 
3656
3789
  // dist/rules/require-valid-agent-argument-hint.js
3790
+ var import_ts_extras32 = require("ts-extras");
3657
3791
  var requireValidAgentArgumentHintRule = createCopilotRule({
3658
3792
  create(context) {
3659
3793
  return createMarkdownDocumentListener(() => {
@@ -3664,7 +3798,7 @@ var requireValidAgentArgumentHintRule = createCopilotRule({
3664
3798
  if (frontmatter === null || !hasFrontmatterField(frontmatter, "argument-hint")) {
3665
3799
  return;
3666
3800
  }
3667
- if (getFrontmatterScalar(frontmatter, "argument-hint") !== void 0) {
3801
+ if ((0, import_ts_extras32.isDefined)(getFrontmatterScalar(frontmatter, "argument-hint"))) {
3668
3802
  return;
3669
3803
  }
3670
3804
  reportAtDocumentStart(context, {
@@ -3683,7 +3817,8 @@ var requireValidAgentArgumentHintRule = createCopilotRule({
3683
3817
  description: "require Copilot custom-agent `argument-hint` metadata to be a non-empty scalar when present.",
3684
3818
  frozen: false,
3685
3819
  recommended: true,
3686
- requiresTypeChecking: false
3820
+ requiresTypeChecking: false,
3821
+ url: createRuleDocsUrl("require-valid-agent-argument-hint")
3687
3822
  },
3688
3823
  messages: {
3689
3824
  invalidAgentArgumentHint: "Copilot custom-agent `argument-hint` metadata must be a non-empty scalar when present."
@@ -3696,6 +3831,7 @@ var requireValidAgentArgumentHintRule = createCopilotRule({
3696
3831
  var require_valid_agent_argument_hint_default = requireValidAgentArgumentHintRule;
3697
3832
 
3698
3833
  // dist/rules/require-valid-agent-handoff-send.js
3834
+ var import_ts_extras33 = require("ts-extras");
3699
3835
  var VALID_BOOLEAN_FIELD_VALUES = /* @__PURE__ */ new Set(["false", "true"]);
3700
3836
  var requireValidAgentHandoffSendRule = createCopilotRule({
3701
3837
  create(context) {
@@ -3708,16 +3844,16 @@ var requireValidAgentHandoffSendRule = createCopilotRule({
3708
3844
  return;
3709
3845
  }
3710
3846
  const handoffs = getFrontmatterObjectList(frontmatter, "handoffs");
3711
- if (handoffs === void 0 || handoffs.length === 0) {
3847
+ if (!(0, import_ts_extras33.isDefined)(handoffs) || (0, import_ts_extras33.isEmpty)(handoffs)) {
3712
3848
  return;
3713
3849
  }
3714
3850
  for (const [index, handoff] of handoffs.entries()) {
3715
3851
  const rawSend = handoff["send"];
3716
- if (rawSend === void 0) {
3852
+ if (!(0, import_ts_extras33.isDefined)(rawSend)) {
3717
3853
  continue;
3718
3854
  }
3719
3855
  const normalizedSend = rawSend.trim().toLowerCase();
3720
- if (VALID_BOOLEAN_FIELD_VALUES.has(normalizedSend)) {
3856
+ if ((0, import_ts_extras33.setHas)(VALID_BOOLEAN_FIELD_VALUES, normalizedSend)) {
3721
3857
  continue;
3722
3858
  }
3723
3859
  reportAtDocumentStart(context, {
@@ -3742,7 +3878,8 @@ var requireValidAgentHandoffSendRule = createCopilotRule({
3742
3878
  description: "require Copilot custom-agent handoff `send` values to use documented boolean metadata when present.",
3743
3879
  frozen: false,
3744
3880
  recommended: true,
3745
- requiresTypeChecking: false
3881
+ requiresTypeChecking: false,
3882
+ url: createRuleDocsUrl("require-valid-agent-handoff-send")
3746
3883
  },
3747
3884
  messages: {
3748
3885
  invalidHandoffSend: "Copilot custom agent handoff #{{handoffNumber}} must use a boolean `send` value (`true` or `false`), not `{{sendValue}}`."
@@ -3755,6 +3892,7 @@ var requireValidAgentHandoffSendRule = createCopilotRule({
3755
3892
  var require_valid_agent_handoff_send_default = requireValidAgentHandoffSendRule;
3756
3893
 
3757
3894
  // dist/rules/require-valid-agent-handoffs.js
3895
+ var import_ts_extras34 = require("ts-extras");
3758
3896
  var requireValidAgentHandoffsRule = createCopilotRule({
3759
3897
  create(context) {
3760
3898
  return createMarkdownDocumentListener(() => {
@@ -3766,7 +3904,7 @@ var requireValidAgentHandoffsRule = createCopilotRule({
3766
3904
  return;
3767
3905
  }
3768
3906
  const handoffs = getFrontmatterObjectList(frontmatter, "handoffs");
3769
- if (handoffs === void 0 || handoffs.length === 0) {
3907
+ if (!(0, import_ts_extras34.isDefined)(handoffs) || (0, import_ts_extras34.isEmpty)(handoffs)) {
3770
3908
  return;
3771
3909
  }
3772
3910
  for (const [index, handoff] of handoffs.entries()) {
@@ -3810,7 +3948,8 @@ var requireValidAgentHandoffsRule = createCopilotRule({
3810
3948
  description: "require Copilot custom-agent handoffs to define the metadata needed for usable guided transitions.",
3811
3949
  frozen: false,
3812
3950
  recommended: true,
3813
- requiresTypeChecking: false
3951
+ requiresTypeChecking: false,
3952
+ url: createRuleDocsUrl("require-valid-agent-handoffs")
3814
3953
  },
3815
3954
  messages: {
3816
3955
  missingAgent: "Copilot custom agent handoff #{{handoffNumber}} must define a non-empty `agent` target.",
@@ -3825,6 +3964,7 @@ var requireValidAgentHandoffsRule = createCopilotRule({
3825
3964
  var require_valid_agent_handoffs_default = requireValidAgentHandoffsRule;
3826
3965
 
3827
3966
  // dist/rules/require-valid-agent-hook-events.js
3967
+ var import_ts_extras35 = require("ts-extras");
3828
3968
  var VALID_HOOK_EVENT_NAMES = /* @__PURE__ */ new Set([
3829
3969
  "PostToolUse",
3830
3970
  "PreCompact",
@@ -3846,11 +3986,11 @@ var requireValidAgentHookEventsRule = createCopilotRule({
3846
3986
  return;
3847
3987
  }
3848
3988
  const hookGroups = getFrontmatterObjectListGroups(frontmatter, "hooks");
3849
- if (hookGroups === void 0 || hookGroups.size === 0) {
3989
+ if (!(0, import_ts_extras35.isDefined)(hookGroups) || hookGroups.size === 0) {
3850
3990
  return;
3851
3991
  }
3852
3992
  for (const eventName of hookGroups.keys()) {
3853
- if (VALID_HOOK_EVENT_NAMES.has(eventName)) {
3993
+ if ((0, import_ts_extras35.setHas)(VALID_HOOK_EVENT_NAMES, eventName)) {
3854
3994
  continue;
3855
3995
  }
3856
3996
  reportAtDocumentStart(context, {
@@ -3872,7 +4012,8 @@ var requireValidAgentHookEventsRule = createCopilotRule({
3872
4012
  description: "require Copilot custom-agent hooks to use supported VS Code hook event names.",
3873
4013
  frozen: false,
3874
4014
  recommended: true,
3875
- requiresTypeChecking: false
4015
+ requiresTypeChecking: false,
4016
+ url: createRuleDocsUrl("require-valid-agent-hook-events")
3876
4017
  },
3877
4018
  messages: {
3878
4019
  invalidHookEvent: "Copilot custom agent hooks should use a supported event name, not `{{eventName}}`."
@@ -3885,6 +4026,7 @@ var requireValidAgentHookEventsRule = createCopilotRule({
3885
4026
  var require_valid_agent_hook_events_default = requireValidAgentHookEventsRule;
3886
4027
 
3887
4028
  // dist/rules/require-valid-agent-hook-timeouts.js
4029
+ var import_ts_extras36 = require("ts-extras");
3888
4030
  var isNumericTimeoutValue = (value) => {
3889
4031
  let decimalPointCount = 0;
3890
4032
  for (const character of value) {
@@ -3912,13 +4054,13 @@ var requireValidAgentHookTimeoutsRule = createCopilotRule({
3912
4054
  return;
3913
4055
  }
3914
4056
  const hookGroups = getFrontmatterObjectListGroups(frontmatter, "hooks");
3915
- if (hookGroups === void 0 || hookGroups.size === 0) {
4057
+ if (!(0, import_ts_extras36.isDefined)(hookGroups) || hookGroups.size === 0) {
3916
4058
  return;
3917
4059
  }
3918
4060
  for (const [eventName, hooks] of hookGroups) {
3919
4061
  for (const [index, hook] of hooks.entries()) {
3920
4062
  const timeout = hook["timeout"]?.trim();
3921
- if (timeout === void 0 || timeout.length === 0 || isNumericTimeoutValue(timeout)) {
4063
+ if (!(0, import_ts_extras36.isDefined)(timeout) || timeout.length === 0 || isNumericTimeoutValue(timeout)) {
3922
4064
  continue;
3923
4065
  }
3924
4066
  reportAtDocumentStart(context, {
@@ -3945,7 +4087,8 @@ var requireValidAgentHookTimeoutsRule = createCopilotRule({
3945
4087
  description: "require Copilot custom-agent hook `timeout` values to be numeric seconds when present.",
3946
4088
  frozen: false,
3947
4089
  recommended: true,
3948
- requiresTypeChecking: false
4090
+ requiresTypeChecking: false,
4091
+ url: createRuleDocsUrl("require-valid-agent-hook-timeouts")
3949
4092
  },
3950
4093
  messages: {
3951
4094
  invalidHookTimeout: "Copilot custom agent hook #{{hookNumber}} in `{{eventName}}` should use a numeric `timeout` value in seconds, not `{{timeout}}`."
@@ -3958,6 +4101,7 @@ var requireValidAgentHookTimeoutsRule = createCopilotRule({
3958
4101
  var require_valid_agent_hook_timeouts_default = requireValidAgentHookTimeoutsRule;
3959
4102
 
3960
4103
  // dist/rules/require-valid-agent-hooks.js
4104
+ var import_ts_extras37 = require("ts-extras");
3961
4105
  var hasAnyHookCommand = (hook) => [
3962
4106
  "command",
3963
4107
  "windows",
@@ -3967,6 +4111,29 @@ var hasAnyHookCommand = (hook) => [
3967
4111
  const value = hook[key];
3968
4112
  return typeof value === "string" && value.trim().length > 0;
3969
4113
  });
4114
+ var getInvalidHookReport = (eventName, hook, hookNumber) => {
4115
+ const type = hook["type"]?.trim() ?? "";
4116
+ if (type !== "command") {
4117
+ return {
4118
+ data: {
4119
+ eventName,
4120
+ hookNumber,
4121
+ type: type.length === 0 ? "(missing)" : type
4122
+ },
4123
+ messageId: "invalidHookType"
4124
+ };
4125
+ }
4126
+ if (hasAnyHookCommand(hook)) {
4127
+ return void 0;
4128
+ }
4129
+ return {
4130
+ data: {
4131
+ eventName,
4132
+ hookNumber
4133
+ },
4134
+ messageId: "missingHookCommand"
4135
+ };
4136
+ };
3970
4137
  var requireValidAgentHooksRule = createCopilotRule({
3971
4138
  create(context) {
3972
4139
  return createMarkdownDocumentListener(() => {
@@ -3978,34 +4145,17 @@ var requireValidAgentHooksRule = createCopilotRule({
3978
4145
  return;
3979
4146
  }
3980
4147
  const hookGroups = getFrontmatterObjectListGroups(frontmatter, "hooks");
3981
- if (hookGroups === void 0 || hookGroups.size === 0) {
4148
+ if (!(0, import_ts_extras37.isDefined)(hookGroups) || hookGroups.size === 0) {
3982
4149
  return;
3983
4150
  }
3984
4151
  for (const [eventName, hooks] of hookGroups) {
3985
4152
  for (const [index, hook] of hooks.entries()) {
3986
4153
  const hookNumber = String(index + 1);
3987
- const type = hook["type"]?.trim() ?? "";
3988
- if (type !== "command") {
3989
- reportAtDocumentStart(context, {
3990
- data: {
3991
- eventName,
3992
- hookNumber,
3993
- type: type.length === 0 ? "(missing)" : type
3994
- },
3995
- messageId: "invalidHookType"
3996
- });
3997
- return;
3998
- }
3999
- if (hasAnyHookCommand(hook)) {
4154
+ const invalidHookReport = getInvalidHookReport(eventName, hook, hookNumber);
4155
+ if (!(0, import_ts_extras37.isDefined)(invalidHookReport)) {
4000
4156
  continue;
4001
4157
  }
4002
- reportAtDocumentStart(context, {
4003
- data: {
4004
- eventName,
4005
- hookNumber
4006
- },
4007
- messageId: "missingHookCommand"
4008
- });
4158
+ reportAtDocumentStart(context, invalidHookReport);
4009
4159
  return;
4010
4160
  }
4011
4161
  }
@@ -4022,7 +4172,8 @@ var requireValidAgentHooksRule = createCopilotRule({
4022
4172
  description: "require Copilot custom-agent hooks to use `type: command` and define at least one command property.",
4023
4173
  frozen: false,
4024
4174
  recommended: true,
4025
- requiresTypeChecking: false
4175
+ requiresTypeChecking: false,
4176
+ url: createRuleDocsUrl("require-valid-agent-hooks")
4026
4177
  },
4027
4178
  messages: {
4028
4179
  invalidHookType: "Copilot custom agent hook #{{hookNumber}} in `{{eventName}}` must use `type: command` (current value: `{{type}}`).",
@@ -4036,6 +4187,7 @@ var requireValidAgentHooksRule = createCopilotRule({
4036
4187
  var require_valid_agent_hooks_default = requireValidAgentHooksRule;
4037
4188
 
4038
4189
  // dist/rules/require-valid-agent-invocation-controls.js
4190
+ var import_ts_extras38 = require("ts-extras");
4039
4191
  var VALID_BOOLEAN_FIELD_VALUES2 = /* @__PURE__ */ new Set(["false", "true"]);
4040
4192
  var INVOCATION_CONTROL_FIELDS = [
4041
4193
  "disable-model-invocation",
@@ -4057,12 +4209,12 @@ var requireValidAgentInvocationControlsRule = createCopilotRule({
4057
4209
  }
4058
4210
  const fieldValue = getFrontmatterScalar(frontmatter, fieldName);
4059
4211
  const normalizedValue = fieldValue?.trim().toLowerCase();
4060
- if (normalizedValue !== void 0 && VALID_BOOLEAN_FIELD_VALUES2.has(normalizedValue)) {
4212
+ if ((0, import_ts_extras38.isDefined)(normalizedValue) && (0, import_ts_extras38.setHas)(VALID_BOOLEAN_FIELD_VALUES2, normalizedValue)) {
4061
4213
  continue;
4062
4214
  }
4063
4215
  reportAtDocumentStart(context, {
4064
4216
  data: {
4065
- currentValue: fieldValue === void 0 || fieldValue.trim().length === 0 ? "(empty)" : fieldValue,
4217
+ currentValue: !(0, import_ts_extras38.isDefined)(fieldValue) || fieldValue.trim().length === 0 ? "(empty)" : fieldValue,
4066
4218
  fieldName
4067
4219
  },
4068
4220
  messageId: "invalidInvocationControl"
@@ -4082,7 +4234,8 @@ var requireValidAgentInvocationControlsRule = createCopilotRule({
4082
4234
  description: "require Copilot custom-agent invocation-control flags to use documented boolean values when present.",
4083
4235
  frozen: false,
4084
4236
  recommended: true,
4085
- requiresTypeChecking: false
4237
+ requiresTypeChecking: false,
4238
+ url: createRuleDocsUrl("require-valid-agent-invocation-controls")
4086
4239
  },
4087
4240
  messages: {
4088
4241
  invalidInvocationControl: "Copilot custom agent `{{fieldName}}` must use a boolean `true` or `false` value (current value: `{{currentValue}}`)."
@@ -4095,12 +4248,13 @@ var requireValidAgentInvocationControlsRule = createCopilotRule({
4095
4248
  var require_valid_agent_invocation_controls_default = requireValidAgentInvocationControlsRule;
4096
4249
 
4097
4250
  // dist/rules/require-valid-agent-mcp-servers.js
4251
+ var import_ts_extras39 = require("ts-extras");
4098
4252
  var formatMcpServersValue = (scalarValue, listValue) => {
4099
- if (scalarValue !== void 0) {
4253
+ if ((0, import_ts_extras39.isDefined)(scalarValue)) {
4100
4254
  return scalarValue;
4101
4255
  }
4102
- if (listValue !== void 0) {
4103
- return `[${listValue.join(", ")}]`;
4256
+ if ((0, import_ts_extras39.isDefined)(listValue)) {
4257
+ return `[${(0, import_ts_extras39.arrayJoin)(listValue, ", ")}]`;
4104
4258
  }
4105
4259
  return "(empty)";
4106
4260
  };
@@ -4115,7 +4269,7 @@ var requireValidAgentMcpServersRule = createCopilotRule({
4115
4269
  return;
4116
4270
  }
4117
4271
  const mcpServers = getFrontmatterList(frontmatter, "mcp-servers");
4118
- if (mcpServers !== void 0 && mcpServers.length > 0) {
4272
+ if ((0, import_ts_extras39.isDefined)(mcpServers) && mcpServers.length > 0) {
4119
4273
  return;
4120
4274
  }
4121
4275
  reportAtDocumentStart(context, {
@@ -4137,7 +4291,8 @@ var requireValidAgentMcpServersRule = createCopilotRule({
4137
4291
  description: "require Copilot custom-agent `mcp-servers` metadata to be a non-empty list when present.",
4138
4292
  frozen: false,
4139
4293
  recommended: true,
4140
- requiresTypeChecking: false
4294
+ requiresTypeChecking: false,
4295
+ url: createRuleDocsUrl("require-valid-agent-mcp-servers")
4141
4296
  },
4142
4297
  messages: {
4143
4298
  invalidMcpServersField: "Copilot custom agent `mcp-servers` metadata must be a non-empty list of MCP server config names (current value: `{{mcpServersValue}}`)."
@@ -4150,6 +4305,7 @@ var requireValidAgentMcpServersRule = createCopilotRule({
4150
4305
  var require_valid_agent_mcp_servers_default = requireValidAgentMcpServersRule;
4151
4306
 
4152
4307
  // dist/rules/require-valid-agent-model.js
4308
+ var import_ts_extras40 = require("ts-extras");
4153
4309
  var INLINE_LIST_LITERAL_PATTERN = /^\s*\[.*\]\s*$/u;
4154
4310
  var requireValidAgentModelRule = createCopilotRule({
4155
4311
  create(context) {
@@ -4162,16 +4318,16 @@ var requireValidAgentModelRule = createCopilotRule({
4162
4318
  return;
4163
4319
  }
4164
4320
  const modelList = getFrontmatterList(frontmatter, "model");
4165
- if (modelList !== void 0 && modelList.length > 0) {
4321
+ if ((0, import_ts_extras40.isDefined)(modelList) && modelList.length > 0) {
4166
4322
  return;
4167
4323
  }
4168
4324
  const model = getFrontmatterScalar(frontmatter, "model");
4169
- if (model !== void 0 && model.length > 0 && !INLINE_LIST_LITERAL_PATTERN.test(model)) {
4325
+ if ((0, import_ts_extras40.isDefined)(model) && model.length > 0 && !INLINE_LIST_LITERAL_PATTERN.test(model)) {
4170
4326
  return;
4171
4327
  }
4172
4328
  reportAtDocumentStart(context, {
4173
4329
  data: {
4174
- modelValue: model === void 0 || model.trim().length === 0 ? "(empty)" : model
4330
+ modelValue: !(0, import_ts_extras40.isDefined)(model) || model.trim().length === 0 ? "(empty)" : model
4175
4331
  },
4176
4332
  messageId: "invalidAgentModel"
4177
4333
  });
@@ -4188,7 +4344,8 @@ var requireValidAgentModelRule = createCopilotRule({
4188
4344
  description: "require Copilot custom-agent `model` metadata to be a non-empty model name or non-empty prioritized model list when present.",
4189
4345
  frozen: false,
4190
4346
  recommended: true,
4191
- requiresTypeChecking: false
4347
+ requiresTypeChecking: false,
4348
+ url: createRuleDocsUrl("require-valid-agent-model")
4192
4349
  },
4193
4350
  messages: {
4194
4351
  invalidAgentModel: "Copilot custom agent `model` must be a non-empty model name or non-empty prioritized list of model names (current value: `{{modelValue}}`)."
@@ -4201,6 +4358,7 @@ var requireValidAgentModelRule = createCopilotRule({
4201
4358
  var require_valid_agent_model_default = requireValidAgentModelRule;
4202
4359
 
4203
4360
  // dist/rules/require-valid-agent-name.js
4361
+ var import_ts_extras41 = require("ts-extras");
4204
4362
  var requireValidAgentNameRule = createCopilotRule({
4205
4363
  create(context) {
4206
4364
  return createMarkdownDocumentListener(() => {
@@ -4211,7 +4369,7 @@ var requireValidAgentNameRule = createCopilotRule({
4211
4369
  if (frontmatter === null || !hasFrontmatterField(frontmatter, "name")) {
4212
4370
  return;
4213
4371
  }
4214
- if (getFrontmatterScalar(frontmatter, "name") !== void 0) {
4372
+ if ((0, import_ts_extras41.isDefined)(getFrontmatterScalar(frontmatter, "name"))) {
4215
4373
  return;
4216
4374
  }
4217
4375
  reportAtDocumentStart(context, {
@@ -4230,7 +4388,8 @@ var requireValidAgentNameRule = createCopilotRule({
4230
4388
  description: "require Copilot custom-agent `name` metadata to be a non-empty scalar when present.",
4231
4389
  frozen: false,
4232
4390
  recommended: true,
4233
- requiresTypeChecking: false
4391
+ requiresTypeChecking: false,
4392
+ url: createRuleDocsUrl("require-valid-agent-name")
4234
4393
  },
4235
4394
  messages: {
4236
4395
  invalidAgentName: "Copilot custom-agent `name` metadata must be a non-empty scalar when present."
@@ -4243,6 +4402,7 @@ var requireValidAgentNameRule = createCopilotRule({
4243
4402
  var require_valid_agent_name_default = requireValidAgentNameRule;
4244
4403
 
4245
4404
  // dist/rules/require-valid-agent-subagents.js
4405
+ var import_ts_extras42 = require("ts-extras");
4246
4406
  var EMPTY_ARRAY_LITERAL = "[]";
4247
4407
  var WILDCARD_AGENTS_LITERAL = "*";
4248
4408
  var isValidExplicitAgentName = (value) => {
@@ -4250,11 +4410,11 @@ var isValidExplicitAgentName = (value) => {
4250
4410
  return trimmedValue.length > 0 && trimmedValue !== EMPTY_ARRAY_LITERAL && trimmedValue !== WILDCARD_AGENTS_LITERAL;
4251
4411
  };
4252
4412
  var formatAgentsValue = (scalarValue, listValue) => {
4253
- if (scalarValue !== void 0) {
4413
+ if ((0, import_ts_extras42.isDefined)(scalarValue)) {
4254
4414
  return scalarValue;
4255
4415
  }
4256
- if (listValue !== void 0) {
4257
- return `[${listValue.join(", ")}]`;
4416
+ if ((0, import_ts_extras42.isDefined)(listValue)) {
4417
+ return `[${(0, import_ts_extras42.arrayJoin)(listValue, ", ")}]`;
4258
4418
  }
4259
4419
  return "(empty)";
4260
4420
  };
@@ -4273,7 +4433,7 @@ var requireValidAgentSubagentsRule = createCopilotRule({
4273
4433
  if (agentsScalar === WILDCARD_AGENTS_LITERAL || agentsScalar === EMPTY_ARRAY_LITERAL) {
4274
4434
  return;
4275
4435
  }
4276
- if (allowedAgents !== void 0 && allowedAgents.length > 0 && allowedAgents.every((agentName) => isValidExplicitAgentName(agentName))) {
4436
+ if ((0, import_ts_extras42.isDefined)(allowedAgents) && allowedAgents.length > 0 && allowedAgents.every((agentName) => isValidExplicitAgentName(agentName))) {
4277
4437
  return;
4278
4438
  }
4279
4439
  reportAtDocumentStart(context, {
@@ -4295,7 +4455,8 @@ var requireValidAgentSubagentsRule = createCopilotRule({
4295
4455
  description: "require Copilot custom-agent `agents` metadata to be `*`, `[]`, or a non-empty list of explicit agent names.",
4296
4456
  frozen: false,
4297
4457
  recommended: true,
4298
- requiresTypeChecking: false
4458
+ requiresTypeChecking: false,
4459
+ url: createRuleDocsUrl("require-valid-agent-subagents")
4299
4460
  },
4300
4461
  messages: {
4301
4462
  invalidAgentsField: "Copilot custom agent `agents` metadata must be `*`, `[]`, or a non-empty list of agent names (current value: `{{agentsValue}}`)."
@@ -4308,6 +4469,7 @@ var requireValidAgentSubagentsRule = createCopilotRule({
4308
4469
  var require_valid_agent_subagents_default = requireValidAgentSubagentsRule;
4309
4470
 
4310
4471
  // dist/rules/require-valid-agent-target.js
4472
+ var import_ts_extras43 = require("ts-extras");
4311
4473
  var VALID_AGENT_TARGETS = /* @__PURE__ */ new Set(["github-copilot", "vscode"]);
4312
4474
  var requireValidAgentTargetRule = createCopilotRule({
4313
4475
  create(context) {
@@ -4320,13 +4482,13 @@ var requireValidAgentTargetRule = createCopilotRule({
4320
4482
  return;
4321
4483
  }
4322
4484
  const target = getFrontmatterScalar(frontmatter, "target");
4323
- if (target === void 0) {
4485
+ if (!(0, import_ts_extras43.isDefined)(target)) {
4324
4486
  reportAtDocumentStart(context, {
4325
4487
  messageId: "emptyTarget"
4326
4488
  });
4327
4489
  return;
4328
4490
  }
4329
- if (VALID_AGENT_TARGETS.has(target)) {
4491
+ if ((0, import_ts_extras43.setHas)(VALID_AGENT_TARGETS, target)) {
4330
4492
  return;
4331
4493
  }
4332
4494
  reportAtDocumentStart(context, {
@@ -4346,7 +4508,8 @@ var requireValidAgentTargetRule = createCopilotRule({
4346
4508
  description: "require Copilot custom-agent `target` metadata to use a documented target value when present.",
4347
4509
  frozen: false,
4348
4510
  recommended: true,
4349
- requiresTypeChecking: false
4511
+ requiresTypeChecking: false,
4512
+ url: createRuleDocsUrl("require-valid-agent-target")
4350
4513
  },
4351
4514
  messages: {
4352
4515
  emptyTarget: "Copilot custom agent files that declare `target` must use a non-empty documented value (`vscode` or `github-copilot`).",
@@ -4360,12 +4523,13 @@ var requireValidAgentTargetRule = createCopilotRule({
4360
4523
  var require_valid_agent_target_default = requireValidAgentTargetRule;
4361
4524
 
4362
4525
  // dist/rules/require-valid-agent-tools.js
4526
+ var import_ts_extras44 = require("ts-extras");
4363
4527
  var formatToolsValue = (scalarValue, listValue) => {
4364
- if (scalarValue !== void 0) {
4528
+ if ((0, import_ts_extras44.isDefined)(scalarValue)) {
4365
4529
  return scalarValue;
4366
4530
  }
4367
- if (listValue !== void 0) {
4368
- return `[${listValue.join(", ")}]`;
4531
+ if ((0, import_ts_extras44.isDefined)(listValue)) {
4532
+ return `[${(0, import_ts_extras44.arrayJoin)(listValue, ", ")}]`;
4369
4533
  }
4370
4534
  return "(empty)";
4371
4535
  };
@@ -4380,7 +4544,7 @@ var requireValidAgentToolsRule = createCopilotRule({
4380
4544
  return;
4381
4545
  }
4382
4546
  const tools = getFrontmatterList(frontmatter, "tools");
4383
- if (tools !== void 0 && tools.length > 0) {
4547
+ if ((0, import_ts_extras44.isDefined)(tools) && tools.length > 0) {
4384
4548
  return;
4385
4549
  }
4386
4550
  reportAtDocumentStart(context, {
@@ -4402,7 +4566,8 @@ var requireValidAgentToolsRule = createCopilotRule({
4402
4566
  description: "require Copilot custom-agent `tools` metadata to be a non-empty list of tool or tool-set names when present.",
4403
4567
  frozen: false,
4404
4568
  recommended: true,
4405
- requiresTypeChecking: false
4569
+ requiresTypeChecking: false,
4570
+ url: createRuleDocsUrl("require-valid-agent-tools")
4406
4571
  },
4407
4572
  messages: {
4408
4573
  invalidAgentTools: "Copilot custom agent `tools` metadata must be a non-empty list of tool or tool-set names when present (current value: `{{toolsValue}}`)."
@@ -4415,6 +4580,7 @@ var requireValidAgentToolsRule = createCopilotRule({
4415
4580
  var require_valid_agent_tools_default = requireValidAgentToolsRule;
4416
4581
 
4417
4582
  // dist/rules/require-valid-instructions-apply-to-globs.js
4583
+ var import_ts_extras45 = require("ts-extras");
4418
4584
  var isValidApplyToGlob = (value) => {
4419
4585
  const trimmedValue = value.trim();
4420
4586
  const lowercaseValue = trimmedValue.toLowerCase();
@@ -4434,11 +4600,11 @@ var requireValidInstructionsApplyToGlobsRule = createCopilotRule({
4434
4600
  ...getFrontmatterList(frontmatter, "applyTo") ?? []
4435
4601
  ];
4436
4602
  const applyToScalar = getFrontmatterScalar(frontmatter, "applyTo");
4437
- if (applyToScalar !== void 0) {
4603
+ if ((0, import_ts_extras45.isDefined)(applyToScalar)) {
4438
4604
  applyToValues.push(applyToScalar);
4439
4605
  }
4440
- const invalidValue = applyToValues.find((value) => !isValidApplyToGlob(value));
4441
- if (invalidValue === void 0) {
4606
+ const invalidValue = applyToValues.find((value) => !isValidApplyToGlob(value)) ?? null;
4607
+ if (invalidValue === null) {
4442
4608
  return;
4443
4609
  }
4444
4610
  reportAtDocumentStart(context, {
@@ -4460,7 +4626,8 @@ var requireValidInstructionsApplyToGlobsRule = createCopilotRule({
4460
4626
  description: "require path-specific Copilot instructions `applyTo` metadata to use repository-relative glob patterns.",
4461
4627
  frozen: false,
4462
4628
  recommended: true,
4463
- requiresTypeChecking: false
4629
+ requiresTypeChecking: false,
4630
+ url: createRuleDocsUrl("require-valid-instructions-apply-to-globs")
4464
4631
  },
4465
4632
  messages: {
4466
4633
  invalidApplyToGlob: "Copilot instructions `applyTo` metadata should use repository-relative glob patterns, not `{{applyTo}}`."
@@ -4473,6 +4640,7 @@ var requireValidInstructionsApplyToGlobsRule = createCopilotRule({
4473
4640
  var require_valid_instructions_apply_to_globs_default = requireValidInstructionsApplyToGlobsRule;
4474
4641
 
4475
4642
  // dist/rules/require-valid-prompt-argument-hint.js
4643
+ var import_ts_extras46 = require("ts-extras");
4476
4644
  var requireValidPromptArgumentHintRule = createCopilotRule({
4477
4645
  create(context) {
4478
4646
  return createMarkdownDocumentListener(() => {
@@ -4483,7 +4651,7 @@ var requireValidPromptArgumentHintRule = createCopilotRule({
4483
4651
  if (frontmatter === null || !hasFrontmatterField(frontmatter, "argument-hint")) {
4484
4652
  return;
4485
4653
  }
4486
- if (getFrontmatterScalar(frontmatter, "argument-hint") !== void 0) {
4654
+ if ((0, import_ts_extras46.isDefined)(getFrontmatterScalar(frontmatter, "argument-hint"))) {
4487
4655
  return;
4488
4656
  }
4489
4657
  reportAtDocumentStart(context, {
@@ -4502,7 +4670,8 @@ var requireValidPromptArgumentHintRule = createCopilotRule({
4502
4670
  description: "require Copilot prompt-file `argument-hint` metadata to be a non-empty scalar when present.",
4503
4671
  frozen: false,
4504
4672
  recommended: true,
4505
- requiresTypeChecking: false
4673
+ requiresTypeChecking: false,
4674
+ url: createRuleDocsUrl("require-valid-prompt-argument-hint")
4506
4675
  },
4507
4676
  messages: {
4508
4677
  invalidPromptArgumentHint: "Copilot prompt-file `argument-hint` metadata must be a non-empty scalar when present."
@@ -4515,13 +4684,14 @@ var requireValidPromptArgumentHintRule = createCopilotRule({
4515
4684
  var require_valid_prompt_argument_hint_default = requireValidPromptArgumentHintRule;
4516
4685
 
4517
4686
  // dist/rules/require-valid-prompt-model.js
4687
+ var import_ts_extras47 = require("ts-extras");
4518
4688
  var INLINE_LIST_LITERAL_PATTERN2 = /^\s*\[.*\]\s*$/u;
4519
4689
  var formatPromptModelValue = (scalarValue, listValue) => {
4520
- if (scalarValue !== void 0) {
4690
+ if ((0, import_ts_extras47.isDefined)(scalarValue)) {
4521
4691
  return scalarValue;
4522
4692
  }
4523
- if (listValue !== void 0) {
4524
- return `[${listValue.join(", ")}]`;
4693
+ if ((0, import_ts_extras47.isDefined)(listValue)) {
4694
+ return `[${(0, import_ts_extras47.arrayJoin)(listValue, ", ")}]`;
4525
4695
  }
4526
4696
  return "(empty)";
4527
4697
  };
@@ -4536,7 +4706,7 @@ var requireValidPromptModelRule = createCopilotRule({
4536
4706
  return;
4537
4707
  }
4538
4708
  const modelList = getFrontmatterList(frontmatter, "model");
4539
- if (modelList !== void 0) {
4709
+ if ((0, import_ts_extras47.isDefined)(modelList)) {
4540
4710
  reportAtDocumentStart(context, {
4541
4711
  data: {
4542
4712
  modelValue: formatPromptModelValue(void 0, modelList)
@@ -4546,7 +4716,7 @@ var requireValidPromptModelRule = createCopilotRule({
4546
4716
  return;
4547
4717
  }
4548
4718
  const model = getFrontmatterScalar(frontmatter, "model");
4549
- if (model !== void 0 && model.length > 0 && !INLINE_LIST_LITERAL_PATTERN2.test(model)) {
4719
+ if ((0, import_ts_extras47.isDefined)(model) && model.length > 0 && !INLINE_LIST_LITERAL_PATTERN2.test(model)) {
4550
4720
  return;
4551
4721
  }
4552
4722
  reportAtDocumentStart(context, {
@@ -4568,7 +4738,8 @@ var requireValidPromptModelRule = createCopilotRule({
4568
4738
  description: "require Copilot prompt-file `model` metadata to be a non-empty single model name when present.",
4569
4739
  frozen: false,
4570
4740
  recommended: true,
4571
- requiresTypeChecking: false
4741
+ requiresTypeChecking: false,
4742
+ url: createRuleDocsUrl("require-valid-prompt-model")
4572
4743
  },
4573
4744
  messages: {
4574
4745
  invalidPromptModel: "Copilot prompt-file `model` metadata must be a non-empty single model name when present (current value: `{{modelValue}}`)."
@@ -4581,6 +4752,7 @@ var requireValidPromptModelRule = createCopilotRule({
4581
4752
  var require_valid_prompt_model_default = requireValidPromptModelRule;
4582
4753
 
4583
4754
  // dist/rules/require-valid-prompt-name.js
4755
+ var import_ts_extras48 = require("ts-extras");
4584
4756
  var requireValidPromptNameRule = createCopilotRule({
4585
4757
  create(context) {
4586
4758
  return createMarkdownDocumentListener(() => {
@@ -4591,7 +4763,7 @@ var requireValidPromptNameRule = createCopilotRule({
4591
4763
  if (frontmatter === null || !hasFrontmatterField(frontmatter, "name")) {
4592
4764
  return;
4593
4765
  }
4594
- if (getFrontmatterScalar(frontmatter, "name") !== void 0) {
4766
+ if ((0, import_ts_extras48.isDefined)(getFrontmatterScalar(frontmatter, "name"))) {
4595
4767
  return;
4596
4768
  }
4597
4769
  reportAtDocumentStart(context, {
@@ -4610,7 +4782,8 @@ var requireValidPromptNameRule = createCopilotRule({
4610
4782
  description: "require Copilot prompt-file `name` metadata to be a non-empty scalar when present.",
4611
4783
  frozen: false,
4612
4784
  recommended: true,
4613
- requiresTypeChecking: false
4785
+ requiresTypeChecking: false,
4786
+ url: createRuleDocsUrl("require-valid-prompt-name")
4614
4787
  },
4615
4788
  messages: {
4616
4789
  invalidPromptName: "Copilot prompt-file `name` metadata must be a non-empty scalar when present."
@@ -4623,12 +4796,13 @@ var requireValidPromptNameRule = createCopilotRule({
4623
4796
  var require_valid_prompt_name_default = requireValidPromptNameRule;
4624
4797
 
4625
4798
  // dist/rules/require-valid-prompt-tools.js
4799
+ var import_ts_extras49 = require("ts-extras");
4626
4800
  var formatToolsValue2 = (scalarValue, listValue) => {
4627
- if (scalarValue !== void 0) {
4801
+ if ((0, import_ts_extras49.isDefined)(scalarValue)) {
4628
4802
  return scalarValue;
4629
4803
  }
4630
- if (listValue !== void 0) {
4631
- return `[${listValue.join(", ")}]`;
4804
+ if ((0, import_ts_extras49.isDefined)(listValue)) {
4805
+ return `[${(0, import_ts_extras49.arrayJoin)(listValue, ", ")}]`;
4632
4806
  }
4633
4807
  return "(empty)";
4634
4808
  };
@@ -4643,7 +4817,7 @@ var requireValidPromptToolsRule = createCopilotRule({
4643
4817
  return;
4644
4818
  }
4645
4819
  const tools = getFrontmatterList(frontmatter, "tools");
4646
- if (tools !== void 0 && tools.length > 0) {
4820
+ if ((0, import_ts_extras49.isDefined)(tools) && tools.length > 0) {
4647
4821
  return;
4648
4822
  }
4649
4823
  reportAtDocumentStart(context, {
@@ -4665,7 +4839,8 @@ var requireValidPromptToolsRule = createCopilotRule({
4665
4839
  description: "require Copilot prompt-file `tools` metadata to be a non-empty list of tool or tool-set names when present.",
4666
4840
  frozen: false,
4667
4841
  recommended: true,
4668
- requiresTypeChecking: false
4842
+ requiresTypeChecking: false,
4843
+ url: createRuleDocsUrl("require-valid-prompt-tools")
4669
4844
  },
4670
4845
  messages: {
4671
4846
  invalidPromptTools: "Copilot prompt-file `tools` metadata must be a non-empty list of tool or tool-set names when present (current value: `{{toolsValue}}`)."
@@ -4678,6 +4853,7 @@ var requireValidPromptToolsRule = createCopilotRule({
4678
4853
  var require_valid_prompt_tools_default = requireValidPromptToolsRule;
4679
4854
 
4680
4855
  // dist/rules/require-valid-repository-hook-command-type.js
4856
+ var import_ts_extras50 = require("ts-extras");
4681
4857
  var requireValidRepositoryHookCommandTypeRule = createCopilotRule({
4682
4858
  create(context) {
4683
4859
  return {
@@ -4690,7 +4866,7 @@ var requireValidRepositoryHookCommandTypeRule = createCopilotRule({
4690
4866
  const typeValue = hook["type"];
4691
4867
  return !isJsonString(typeValue) || !isRepositoryHookType(typeValue);
4692
4868
  });
4693
- if (invalidHook === void 0) {
4869
+ if (!(0, import_ts_extras50.isDefined)(invalidHook)) {
4694
4870
  return;
4695
4871
  }
4696
4872
  reportAtDocumentStart(context, {
@@ -4714,7 +4890,8 @@ var requireValidRepositoryHookCommandTypeRule = createCopilotRule({
4714
4890
  description: "require repository hook definitions to declare a supported `type` value such as `command` or `prompt`.",
4715
4891
  frozen: false,
4716
4892
  recommended: true,
4717
- requiresTypeChecking: false
4893
+ requiresTypeChecking: false,
4894
+ url: createRuleDocsUrl("require-valid-repository-hook-command-type")
4718
4895
  },
4719
4896
  messages: {
4720
4897
  invalidRepositoryHookType: "Repository hook definitions for `{{eventName}}` must declare a supported `type` such as `command` or `prompt` (current value: `{{type}}`)."
@@ -4727,6 +4904,7 @@ var requireValidRepositoryHookCommandTypeRule = createCopilotRule({
4727
4904
  var require_valid_repository_hook_command_type_default = requireValidRepositoryHookCommandTypeRule;
4728
4905
 
4729
4906
  // dist/rules/require-valid-repository-hook-env.js
4907
+ var import_ts_extras51 = require("ts-extras");
4730
4908
  var requireValidRepositoryHookEnvRule = createCopilotRule({
4731
4909
  create(context) {
4732
4910
  return {
@@ -4737,9 +4915,9 @@ var requireValidRepositoryHookEnvRule = createCopilotRule({
4737
4915
  const root = parseJsonText(context.sourceCode.text);
4738
4916
  const invalidHook = getRepositoryHookObjects(root).find(({ hook }) => {
4739
4917
  const env = hook["env"];
4740
- return env !== void 0 && !isJsonObject(env);
4918
+ return (0, import_ts_extras51.isDefined)(env) && !isJsonObject(env);
4741
4919
  });
4742
- if (invalidHook === void 0) {
4920
+ if (!(0, import_ts_extras51.isDefined)(invalidHook)) {
4743
4921
  return;
4744
4922
  }
4745
4923
  reportAtDocumentStart(context, {
@@ -4763,7 +4941,8 @@ var requireValidRepositoryHookEnvRule = createCopilotRule({
4763
4941
  description: "require repository hook `env` values to be JSON objects when present.",
4764
4942
  frozen: false,
4765
4943
  recommended: true,
4766
- requiresTypeChecking: false
4944
+ requiresTypeChecking: false,
4945
+ url: createRuleDocsUrl("require-valid-repository-hook-env")
4767
4946
  },
4768
4947
  messages: {
4769
4948
  invalidRepositoryHookEnv: "Repository hook `env` for `{{eventName}}` must be a JSON object when present (current value: `{{env}}`)."
@@ -4776,6 +4955,7 @@ var requireValidRepositoryHookEnvRule = createCopilotRule({
4776
4955
  var require_valid_repository_hook_env_default = requireValidRepositoryHookEnvRule;
4777
4956
 
4778
4957
  // dist/rules/require-valid-repository-hook-events.js
4958
+ var import_ts_extras52 = require("ts-extras");
4779
4959
  var requireValidRepositoryHookEventsRule = createCopilotRule({
4780
4960
  create(context) {
4781
4961
  return {
@@ -4785,7 +4965,7 @@ var requireValidRepositoryHookEventsRule = createCopilotRule({
4785
4965
  }
4786
4966
  const root = parseJsonText(context.sourceCode.text);
4787
4967
  const invalidEventName = getRepositoryHookEventEntries(root).map(([eventName]) => eventName).find((eventName) => !isRepositoryHookEventName(eventName));
4788
- if (invalidEventName === void 0) {
4968
+ if (!(0, import_ts_extras52.isDefined)(invalidEventName)) {
4789
4969
  return;
4790
4970
  }
4791
4971
  reportAtDocumentStart(context, {
@@ -4808,7 +4988,8 @@ var requireValidRepositoryHookEventsRule = createCopilotRule({
4808
4988
  description: "require repository hook configuration files to use supported hook event names.",
4809
4989
  frozen: false,
4810
4990
  recommended: true,
4811
- requiresTypeChecking: false
4991
+ requiresTypeChecking: false,
4992
+ url: createRuleDocsUrl("require-valid-repository-hook-events")
4812
4993
  },
4813
4994
  messages: {
4814
4995
  invalidRepositoryHookEvent: "Repository hook configuration files should use a supported hook event name, not `{{eventName}}`."
@@ -4821,7 +5002,8 @@ var requireValidRepositoryHookEventsRule = createCopilotRule({
4821
5002
  var require_valid_repository_hook_events_default = requireValidRepositoryHookEventsRule;
4822
5003
 
4823
5004
  // dist/rules/require-valid-repository-hook-timeouts.js
4824
- var isValidTimeoutSeconds = (value) => typeof value === "number" && Number.isInteger(value) && value > 0;
5005
+ var import_ts_extras53 = require("ts-extras");
5006
+ var isValidTimeoutSeconds = (value) => typeof value === "number" && (0, import_ts_extras53.isInteger)(value) && value > 0;
4825
5007
  var requireValidRepositoryHookTimeoutsRule = createCopilotRule({
4826
5008
  create(context) {
4827
5009
  return {
@@ -4832,9 +5014,9 @@ var requireValidRepositoryHookTimeoutsRule = createCopilotRule({
4832
5014
  const root = parseJsonText(context.sourceCode.text);
4833
5015
  const invalidHook = getRepositoryHookObjects(root).find(({ hook }) => {
4834
5016
  const timeout = hook["timeoutSec"];
4835
- return timeout !== void 0 && !isValidTimeoutSeconds(timeout);
5017
+ return (0, import_ts_extras53.isDefined)(timeout) && !isValidTimeoutSeconds(timeout);
4836
5018
  });
4837
- if (invalidHook === void 0) {
5019
+ if (!(0, import_ts_extras53.isDefined)(invalidHook)) {
4838
5020
  return;
4839
5021
  }
4840
5022
  reportAtDocumentStart(context, {
@@ -4858,7 +5040,8 @@ var requireValidRepositoryHookTimeoutsRule = createCopilotRule({
4858
5040
  description: "require repository hook `timeoutSec` values to be positive integers when present.",
4859
5041
  frozen: false,
4860
5042
  recommended: true,
4861
- requiresTypeChecking: false
5043
+ requiresTypeChecking: false,
5044
+ url: createRuleDocsUrl("require-valid-repository-hook-timeouts")
4862
5045
  },
4863
5046
  messages: {
4864
5047
  invalidRepositoryHookTimeout: "Repository hook `timeoutSec` for `{{eventName}}` must be a positive integer when present (current value: `{{timeout}}`)."
@@ -4903,7 +5086,8 @@ var requireValidRepositoryHookVersionRule = createCopilotRule({
4903
5086
  description: "require repository hook configuration files to declare `version: 1`.",
4904
5087
  frozen: false,
4905
5088
  recommended: true,
4906
- requiresTypeChecking: false
5089
+ requiresTypeChecking: false,
5090
+ url: createRuleDocsUrl("require-valid-repository-hook-version")
4907
5091
  },
4908
5092
  messages: {
4909
5093
  invalidRepositoryHookVersion: "Repository hook configuration files must declare `version: 1` (current value: `{{version}}`)."
@@ -4945,7 +5129,8 @@ var requireValidSkillDirectoryNameRule = createCopilotRule({
4945
5129
  description: "require Copilot skill directory names to use the documented lowercase-hyphen form.",
4946
5130
  frozen: false,
4947
5131
  recommended: true,
4948
- requiresTypeChecking: false
5132
+ requiresTypeChecking: false,
5133
+ url: createRuleDocsUrl("require-valid-skill-directory-name")
4949
5134
  },
4950
5135
  messages: {
4951
5136
  invalidSkillDirectoryName: "Copilot skill directory names must use lowercase letters, digits, and hyphens only (current directory: `{{directoryName}}`)."
@@ -4958,6 +5143,7 @@ var requireValidSkillDirectoryNameRule = createCopilotRule({
4958
5143
  var require_valid_skill_directory_name_default = requireValidSkillDirectoryNameRule;
4959
5144
 
4960
5145
  // dist/rules/require-valid-skill-license.js
5146
+ var import_ts_extras54 = require("ts-extras");
4961
5147
  var requireValidSkillLicenseRule = createCopilotRule({
4962
5148
  create(context) {
4963
5149
  return createMarkdownDocumentListener(() => {
@@ -4968,7 +5154,7 @@ var requireValidSkillLicenseRule = createCopilotRule({
4968
5154
  if (frontmatter === null || !hasFrontmatterField(frontmatter, "license")) {
4969
5155
  return;
4970
5156
  }
4971
- if (getFrontmatterScalar(frontmatter, "license") !== void 0) {
5157
+ if ((0, import_ts_extras54.isDefined)(getFrontmatterScalar(frontmatter, "license"))) {
4972
5158
  return;
4973
5159
  }
4974
5160
  reportAtDocumentStart(context, {
@@ -4983,7 +5169,8 @@ var requireValidSkillLicenseRule = createCopilotRule({
4983
5169
  description: "require optional Copilot skill `license` metadata to be a non-empty scalar when present.",
4984
5170
  frozen: false,
4985
5171
  recommended: false,
4986
- requiresTypeChecking: false
5172
+ requiresTypeChecking: false,
5173
+ url: createRuleDocsUrl("require-valid-skill-license")
4987
5174
  },
4988
5175
  messages: {
4989
5176
  invalidSkillLicense: "Copilot skill `license` metadata must be a non-empty scalar when present."
@@ -4996,6 +5183,7 @@ var requireValidSkillLicenseRule = createCopilotRule({
4996
5183
  var require_valid_skill_license_default = requireValidSkillLicenseRule;
4997
5184
 
4998
5185
  // dist/rules/require-valid-skill-name.js
5186
+ var import_ts_extras55 = require("ts-extras");
4999
5187
  var requireValidSkillNameRule = createCopilotRule({
5000
5188
  create(context) {
5001
5189
  return createMarkdownDocumentListener(() => {
@@ -5007,7 +5195,7 @@ var requireValidSkillNameRule = createCopilotRule({
5007
5195
  return;
5008
5196
  }
5009
5197
  const skillName = getFrontmatterScalar(frontmatter, "name");
5010
- if (skillName !== void 0 && isValidSkillIdentifier(getSkillName(context.filename, frontmatter))) {
5198
+ if ((0, import_ts_extras55.isDefined)(skillName) && isValidSkillIdentifier(getSkillName(context.filename, frontmatter))) {
5011
5199
  return;
5012
5200
  }
5013
5201
  reportAtDocumentStart(context, {
@@ -5029,7 +5217,8 @@ var requireValidSkillNameRule = createCopilotRule({
5029
5217
  description: "require Copilot skill `name` metadata to use the documented lowercase-hyphen identifier form.",
5030
5218
  frozen: false,
5031
5219
  recommended: true,
5032
- requiresTypeChecking: false
5220
+ requiresTypeChecking: false,
5221
+ url: createRuleDocsUrl("require-valid-skill-name")
5033
5222
  },
5034
5223
  messages: {
5035
5224
  invalidSkillName: "Copilot skill `name` values must use lowercase letters, digits, and hyphens only (current value: `{{name}}`)."
@@ -5119,6 +5308,7 @@ var copilotRules = copilotRuleRegistry;
5119
5308
  var ERROR_SEVERITY = "error";
5120
5309
  var COPILOT_MARKDOWN_FILES = [
5121
5310
  ".github/copilot-instructions.md",
5311
+ ".github/instructions/copilot-instructions.md",
5122
5312
  ".github/instructions/**/*.instructions.md",
5123
5313
  ".github/prompts/**/*.prompt.md",
5124
5314
  ".github/agents/**/*.agent.md",
@@ -5156,7 +5346,7 @@ var getPackageVersion = (pkg) => {
5156
5346
  var eslintRules = copilotRules;
5157
5347
  var markdownPlugin = import_markdown.default;
5158
5348
  var jsonPlugin = import_json.default;
5159
- var copilotRuleEntries = Object.entries(copilotRules).toSorted(([left], [right]) => left.localeCompare(right));
5349
+ var copilotRuleEntries = (0, import_ts_extras56.safeCastTo)((0, import_ts_extras56.objectEntries)(copilotRules).toSorted(([left], [right]) => left.localeCompare(right)));
5160
5350
  var createEmptyPresetRuleMap = () => ({
5161
5351
  all: [],
5162
5352
  minimal: [],
@@ -5189,8 +5379,8 @@ var errorRulesFor = (ruleNames) => {
5189
5379
  };
5190
5380
  var presetRuleNamesByConfig = derivePresetRuleNamesByConfig();
5191
5381
  var partitionRuleNamesByPresetLayer = (ruleNames) => ({
5192
- jsonRuleNames: ruleNames.filter((ruleName) => REPOSITORY_HOOK_JSON_RULE_NAMES.has(ruleName)),
5193
- markdownRuleNames: ruleNames.filter((ruleName) => !REPOSITORY_HOOK_JSON_RULE_NAMES.has(ruleName))
5382
+ jsonRuleNames: ruleNames.filter((ruleName) => (0, import_ts_extras56.setHas)(REPOSITORY_HOOK_JSON_RULE_NAMES, ruleName)),
5383
+ markdownRuleNames: ruleNames.filter((0, import_ts_extras56.not)((ruleName) => (0, import_ts_extras56.setHas)(REPOSITORY_HOOK_JSON_RULE_NAMES, ruleName)))
5194
5384
  });
5195
5385
  var createPresetConfig = (configName, plugin2) => {
5196
5386
  const presetName = copilotConfigMetadataByName[configName].presetName;