12 Commits

Author SHA1 Message Date
Stefan Broenner 5eafcbfc8f Keep npm lockfiles portable and preserve inherited package sources (#871)
Co-authored-by: Stefan Broenner <stbrnner@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-09-11 09:07:01 -07:00
Stefan Broenner 9d54902254 Use one feature overview and fix documentation commit checks (#866)
* docs: trim agent instructions to repository-specific essentials

Consolidate overlapping guidance, correct stale contracts and testing policy, and preserve scoped Excel safety and release requirements.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* docs: preserve detailed guidance in contributor documentation

Move useful examples and authoring procedures out of automatic instructions into their general guides; correct stale contributor guidance and retain short discovery links.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* docs: single-source feature overview and refine commit checks

Generate the website overview from FEATURES.md. Keep validation-only commits out of release packaging while preserving build and count checks, and retain the original output when packaging fails.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Stefan Broenner <stbrnner@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-09-10 22:17:25 -07:00
Stefan Broenner 0a89220c61 Fix release metadata line-ending normalization (#821)
Closes #820
2026-08-28 11:11:17 +02:00
Stefan Broenner 11de41ac7f chore: refresh coding agent setup (#802)
* chore: refresh coding agent setup

Remove the unused Squad configuration and align Copilot instructions with the current generated architecture. Add deterministic Windows cloud-agent dependency setup.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b6c52095-fe7c-4482-8789-f490af2ffad3

* docs: update generated surface checklist

Replace obsolete hand-written MCP wiring steps in the pull request template with the current generator and parity checks.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b6c52095-fe7c-4482-8789-f490af2ffad3

---------

Copilot-Session: b6c52095-fe7c-4482-8789-f490af2ffad3
2026-08-20 08:44:24 +00:00
Stefan Broenner f05294fd25 Generate shared bootstrap template (#794)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3e5fb997-433e-427b-9b60-5485fb0813a8
2026-08-20 07:13:37 +00:00
Stefan Broenner 3f51870d40 fix(docs): report real page dates in the sitemap, assert accessibility fixes (#774)
* fix(docs): report real page dates in the sitemap, assert accessibility fixes

The sitemap carried no <lastmod> at all. hooks.py stripped every value with a
regex over the built XML, because MkDocs stamps the *build* date on each URL --
which told crawlers all 52 pages changed on every deploy. Removing them avoided
the false signal but replaced it with no signal.

Dates now come from git: one `git log` walk maps each tracked path to its last
commit, and a wrapper page takes the newest date among itself and the canonical
repo file it mirrors. Verified against `git log -1` for five paths across all
four source layouts.

That let the sitemap become a real template. overrides/sitemap.xml renders both
<lastmod> and the home page's <video:video> block declaratively, replacing ~55
lines of regex surgery plus a manual re-gzip in on_post_build. MkDocs now writes
sitemap.xml.gz from the same rendered output, so the two cannot diverge.

Same treatment for two of the three accessibility patches: the logo (alt="logo",
no dimensions) and the progress bar (role=progressbar with no accessible name)
are now overrides/partials/, since upstream ships them as a 7-line and a 1-line
template. The search dialog stays a string patch on purpose -- Material's search
partial is ~45 lines of markup, icon lookups and feature flags, so forking it to
add one attribute would pin a large slice of theme internals.

None of these were verified before. audit_site.py now asserts all four in the
built HTML, so a Material upgrade that renames a class fails the build instead
of silently regressing accessibility, and asserts every URL has a valid,
non-uniform <lastmod>.

Both workflows that build the site check out with fetch-depth: 0, because a
shallow clone dates every page to the tip commit.

Verification:
- Negative-tested every new guard. Stripped lastmod, uniform dates and a
  malformed date each exit 1 with the right message; rebuilding with the
  overrides removed and the search patch disabled produces 208 failures
  (4 per page x 52).
- That exercise caught a bug in the a11y guard itself (`for ... = checks`
  instead of `in`), which had made the check a no-op.
- It also disproved a heuristic I had written: a shallow clone lists all 843
  tracked files under one date, so the "few paths means shallow" test never
  fires. Replaced with `git rev-parse --is-shallow-repository`, verified True
  against a real depth-1 clone and False here.
- Only HTML delta versus the previous build is the minifier dropping quotes
  around the logo's src/width/height, which hooks.py used to re-add after
  minification. Semantically identical.
- mkdocs build --strict --clean, audit_site.py (52 pages) and
  check_deploy_paths.py all pass; 166 files.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 388229c1-868a-416f-8b0a-7d6ee058e788

* fix(docs): match the a11y audit to the elements it actually patches

Copilot review raised two problems with audit_accessibility, both real.

The checks matched any <div role=dialog> / <div role=progressbar> rather than
the specific Material elements the build patches. That fails the wrong way in
both directions: an unrelated dialog Material grows later would fail the build
even though nothing we patch regressed, and - worse - if an upgrade restructured
the search markup out from under the patch, the role-based search would find
nothing and pass silently. Absence was indistinguishable from success, which is
the exact failure mode the audit exists to prevent.

Both now match on the Material class we patch (md-search, md-progress), and an
element that cannot be found is an explicit failure rather than a quiet skip.

Measured first: every built page carries exactly one md-search, one md-progress
and two logo images, so requiring at least one of each is safe.

Verified both of the reported cases:
- Renaming md-search and dropping the aria-label now fails with "no search
  dialog found" instead of passing.
- Injecting an unrelated unlabelled <div role=dialog> no longer fails the build.
- Removing both overrides and disabling the search patch still produces the
  original 208 failures, and a clean build still passes at 52 pages.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 388229c1-868a-416f-8b0a-7d6ee058e788

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 388229c1-868a-416f-8b0a-7d6ee058e788
2026-08-15 17:06:56 +02:00
Stefan Broenner 8310b3f27c ci(docs): validate the Pages site on PRs and harden the build (#772)
* ci(docs): validate the Pages site on PRs and harden the build

The docs site was validated by nothing before merge: CI Gate never built
it, and pre-commit.ps1 classifies gh-pages/ as doc-only. A broken site was
only discoverable after it had already deployed.

Validation
- New "Docs Site" CI job: mkdocs build --strict, audit_site.py and the new
  check_deploy_paths.py on every pull request.
- check_deploy_paths.py proves the deploy workflow paths: filter covers
  every source hooks.py mirrors. That filter was hand-maintained, so a new
  mirrored file silently stopped triggering a deploy.
- Dependabot pip entry for gh-pages: mkdocs-material was never updating.

Build fixes
- hooks.py wrote its generated pages into docs_dir, which mkdocs serve
  watches, so every build retriggered itself and looped forever. Generated
  output moved to gh-pages/_generated/ with snippets base_path extended to
  match. Rebuild detections after one edit: 9+ -> 1.
- Added a watch: key so serve reloads on FEATURES.md, CHANGELOG.md, docs/
  and skills/ instead of only on gh-pages/.

Workflow split
- Persisting the star history needs contents: write, and it shared a job
  with pip install -r requirements.txt. Split into star-history.yml; the
  Pages build is now contents: read and only renders the chart. The
  generator tests also run on pull requests now, not just after merge.
- New link-check.yml runs lychee weekly over the built site and files an
  issue on link rot. Scheduled rather than per-PR because external
  endpoints rate-limit and would make it flaky.

Site output is byte-identical across all 164 files.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 388229c1-868a-416f-8b0a-7d6ee058e788

* fix(docs): keep excluding the former docs/_generated/ location

Moving generated output out of docs_dir also removed the exclude_docs
entry, so a stale docs/_generated/ left in a long-lived clone was silently
built and published as real pages: reproduced at 52 pages instead of 51,
with audit_site.py passing.

Restore the exclusion and keep the old .gitignore entry so the leftover
directory neither gets published nor shows up as untracked.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 388229c1-868a-416f-8b0a-7d6ee058e788

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 388229c1-868a-416f-8b0a-7d6ee058e788
2026-08-15 15:51:34 +02:00
Copilot 8f7340ae66 Fix conditional formatting deserialization and retire Excel runner (#757)
* Initial plan

* fix: accept bool/int args for conditionalformat add-rule over MCP

Co-authored-by: sbroenne <3026464+sbroenne@users.noreply.github.com>

* ci: run Excel-dependent smoke tests on self-hosted Windows Excel runner

Co-authored-by: sbroenne <3026464+sbroenne@users.noreply.github.com>

* ci: fix stale note about smoke tests not running in CI

Co-authored-by: sbroenne <3026464+sbroenne@users.noreply.github.com>

* fix: harden conditional formatting and local E2E

Validate conditional-format rule arguments, release Border COM objects, and verify typed bool/int arguments through CLI and MCP workflows. Retire the Azure Excel runner and replace it with explicit local integration and E2E attestations.

Tests: Release build (0 warnings); ConditionalFormat 27/27; CLI E2E 12/12; MCP E2E 1/1; COM leak and documentation count checks passed.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b7375555-1096-40ae-92a3-2b76383e7934

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sbroenne <3026464+sbroenne@users.noreply.github.com>
Co-authored-by: sbroenne <stefan_broenner@yahoo.com>
Copilot-Session: b7375555-1096-40ae-92a3-2b76383e7934
2026-08-06 20:06:29 +02:00
Stefan Broenner a67212a278 Update all dependencies and GitHub Actions (#758)
* chore(deps): update all dependencies

Updates NuGet, npm, Python, the .NET SDK, VS Code tooling, and GitHub Actions.

Tests: Release build; MCP protocol and transport tests; extension compile and lint; documentation build; package vulnerability audits.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5e3452df-35bd-418d-b1f4-8b6903f8df24

* ci: allow verified Python package licenses

Allows MIT-0 and PSF-2.0 dependencies and scopes the typing-extensions metadata exception to that package.

Tests: dependency workflow YAML parse; full pre-commit gates.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5e3452df-35bd-418d-b1f4-8b6903f8df24

---------

Copilot-Session: 5e3452df-35bd-418d-b1f4-8b6903f8df24
2026-08-06 16:54:31 +02:00
github-actions[bot] 352b1da895 Revert: remove RELEASE_PAT verification scratch file [skip ci]
Reverts the scratch verification commit; confirms PAT push authentication
and ruleset bypass work end-to-end for the release-automation fix.
2026-07-23 09:40:03 +02:00
github-actions[bot] f1d85698f3 test: verify RELEASE_PAT can push directly to protected main [skip ci]
This is a scratch verification commit for the release-automation fix in
PR #739 (direct changelog push using RELEASE_PAT as a ruleset bypass
actor). It will be reverted immediately by a follow-up commit.
2026-07-23 09:39:47 +02:00
Stefan Broenner 97df07a316 Harden PR/CI: add required CI Gate, remove stale/superseded workflows (#715)
* ci: add required CI Gate, remove stale/superseded workflows

Consolidate PR validation into a single always-running 'CI Gate' workflow
(.github/workflows/ci.yml) that ports the Excel-free pre-commit gates so they
are enforced server-side even if the local hook is bypassed:
- Release build (compile + source generators)
- COM-leak, success-flag, coverage/naming, MCP-Core, doc-counts, dynamic-cast,
  plugin-README audits
- Excel-free CLI --help and MCP Server build smoke + artifact upload

Excel-dependent gates (CLI workflow smoke, MCP smoke, integration tests) are
NOT run in CI - GitHub runners have no Excel - and remain local-only.

Also:
- Remove superseded Build CLI / Build MCP Server workflows (absorbed by CI Gate;
  fixes the missing pull_request trigger on the MCP build)
- Remove stale.yml (stale-issues automation)
- Drop the dead 'develop' push trigger from CodeQL (branch does not exist)
- Add .github/CODEOWNERS (routing only)
- Document that the CI Gate mirrors the Excel-free gates

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a1546dd0-9bc6-46a6-8648-e700b0bcc8bf

* docs: point workflow references at consolidated CI Gate

Update README badges, PRE-COMMIT-SETUP.md, and development-workflow
instructions to reference ci.yml (CI Gate) instead of the removed
build-cli.yml / build-mcp-server.yml workflows. Addresses Copilot PR
review feedback on #715.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a1546dd0-9bc6-46a6-8648-e700b0bcc8bf

* ci: drop brittle gate/rule number citations in CI Gate step labels

Release build comment referenced 'pre-commit gate 6' and the dynamic-cast
step was labeled 'Rule 14'; both cross-references were inaccurate (gate
numbering differs between pre-commit.ps1 and the instructions table, and
Rule 14 is unrelated). Describe the steps instead. Addresses Copilot
review feedback on #715.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a1546dd0-9bc6-46a6-8648-e700b0bcc8bf

---------

Co-authored-by: Stefan Broenner <stbrnner@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-07-12 08:11:50 +02:00