* feat(website): dedicated agent detail pages instead of modal
Replace the popup/modal viewer for agents with dedicated per-agent pages at /agent/<id>/ for real URLs and better deep linking.
- Build-time rendered docs (marked + gray-matter) with a details sidebar
- Sidebar Actions card: Install split-button (VS Code/Insiders/Download/Copy markdown), Share, View on GitHub
- Cards now link natively via anchors (no modal); card-render gains optional href (backward compatible for other types)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* feat(website): dedicated instruction detail pages + shared detail layout
Extend the dedicated detail-page pattern (introduced for agents) to
instructions, and factor the shared behavior/styles out for reuse:
- Add instruction/[id].astro with build-time markdown render, breadcrumb,
install split-button (VS Code/Insiders/Download/Copy markdown), Share,
View on GitHub, and a details sidebar (Applies to / Source / Last updated)
plus collapsible frontmatter.
- Extract shared client behavior into resource-detail.ts (renamed from
agent-detail.ts) keyed on [data-resource-detail].
- Move detail-page CSS into global.css under .resource-detail-page.
- Point the agent detail page at the shared script/styles.
- Instruction cards now link to /instruction/<id>/ and the modal is removed
from the instructions listing.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* refactor(website): extract shared detail-page components
Break the agent and instruction detail pages down into reusable Astro
components under src/components/pages: Breadcrumb, Header, Main, Sidebar,
SidebarChips, InstallButtons, and RawMarkdown. Both detail pages now
compose these components instead of duplicating markup.
Fix RawMarkdown to read the `markdown` prop (matching both call sites) and
emit exact text via set:text, which restores the Copy markdown action that
had silently broken when the hidden textarea stopped rendering.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* refactor(website): share detail-page build logic in lib/detail-page
Both detail pages duplicated the install/GitHub URL builders, the
build-time markdown read+render, and the last-updated formatting. Move all
of it into a DOM-free build-time helper (src/lib/detail-page.ts) exposing
loadDetailPage(item, type), and reduce each [id].astro to a single call plus
its type-specific chip data.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add dedicated skill detail pages with multi-file browser
Migrate skills from the popup/modal viewer to dedicated per-item pages
(/skill/<id>/) matching the agent and instruction detail pages.
Skills need a few skill-specific mechanics:
- Install via `gh skills install github/awesome-copilot <id>` (copyable),
since skills have no VS Code install URL.
- Download ZIP for the multi-file skill contents.
- A file browser that defaults to SKILL.md and lets you inspect other
files, with Shiki syntax highlighting for code and marked-rendered
markdown. SKILL.md is embedded (rendered + raw) at build time; other
files are lazy-fetched on demand and cached. Deep links via #file=.
Also fixes a production build regression in the shared detail-page
helper: repoRoot now resolves via process.cwd() instead of import.meta
.url, which resolved incorrectly once bundled and silently returned
empty markdown (breaking rendered docs + copy-markdown for agents and
instructions too).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Replace skill file list with a dropdown selector
The two-column file browser (side list + content pane) was cramped,
splitting the already-narrow main column in half. Replace the side list
with a dropdown in the file view header so the content pane spans the
full width.
- Multi-file skills get a <select> grouped by folder via <optgroup>,
SKILL.md first. Single-file skills keep a static filename label.
- Client script drives selection from the <select> change event instead
of the removed file buttons; deep links, copy-file, Download ZIP, and
Share all read the file list from the select options.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Fix skill sidebar card overflowing its column
The install command in the actions card used white-space: nowrap, which
gave the grid tracks a large min-content size. Grid items default to
min-width: auto (won't shrink below content), so the actions card grew
past the 352px sidebar, making it look wider than the agent/instruction
sidebars. Add min-width: 0 down the sidebar grid chain so the command
box stays within the column and scrolls horizontally instead.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Make skill file content pane grow to full page height
Remove the fixed max-height/overflow on .skill-file-content so file
content flows to natural height and the page scrolls, instead of a
nested inner scroll region. Shiki <pre> keeps its own horizontal scroll.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Center-align skill file picker label with the select
Reset the Starlight-injected margin-top on .skill-file-select so the
'File' label and the dropdown share a common vertical midline.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Render code files edge-to-edge in skill file viewer
For code files, drop the container padding and the pre border/radius so
the highlighted code fills the full column width. Markdown files keep
their padded, bordered layout. Toggled via an is-code class on the
content pane based on the selected file kind.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add dedicated detail pages for hooks with a reusable file browser
Hooks had no good install path (manual copy or ZIP), so mirror the
Skills dedicated-page pattern: a multi-file browser plus a Download ZIP
action, replacing the modal on the hooks listing.
Generalise the Skills-specific file browser so both resource types share
one implementation:
- Rename SkillFileBrowser.astro -> FileBrowser.astro with neutral props.
- Rename skill-detail.ts -> file-browser.ts with neutral data attributes
(data-file-browser-page, data-bundle-id, data-primary-file).
- Rescope install-slot styles under a shared .bundle-detail-page class.
- generate-website-data: rename getSkillFiles -> getFolderFiles and emit a
files[] + readmeFileName for each hook.
Hooks list cards now deep-link to /hook/<id>/ instead of opening a modal.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add dedicated detail pages for workflows
Migrate agentic workflows from the popup/modal viewer to dedicated per-item pages (/workflow/<id>/) with deep linking, matching the pattern used for agents, instructions, skills, and hooks.
Workflows are single .md files, so they reuse the single-file detail components (Main, Sidebar, Header, Breadcrumb, RawMarkdown) and the resource-detail client script. Since workflows have no VS Code install, the install slot instead documents the gh aw CLI flow and offers Download + Copy markdown actions.
Also rescope the shared install-slot CSS from .bundle-detail-page to .detail-actions-card so skill, hook, and workflow pages share it without a page-specific class, and drop the now-unused bundle-detail-page class from the skill and hook pages.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Format workflow install note
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add dedicated plugin detail pages
Replace the plugins modal with dedicated /plugin/<id>/ pages that deep link, render the bundled README, and surface an Included items section linking each constituent agent/skill/instruction/hook to its own detail page (falling back to GitHub for items without a page, e.g. extensions).
- generate-website-data: resolve plugin items to detail URLs + titles, add readmeFile for local and extension-derived plugins
- new IncludedItems component groups bundled resources by kind
- plugin/[id].astro handles local, extension-derived, and external plugins with VS Code + CLI install actions
- resource-detail: copy-install handler shared with detail pages
- plugins list cards now deep link; modal wiring removed
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Show plugin version, ref, and commit in detail sidebar
Capture version from plugin.json (local + extension-derived) and external.json, and surface it in the plugin detail Details card. For external plugins, also show the pinned source ref and short commit SHA when present.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add dedicated canvas extension detail pages with preview gallery
Replace the extensions modal with per-extension pages at /extension/<id>/,
mirroring the skill/plugin detail layout. Each page shows a preview image
gallery, README docs (or an About fallback), and a sidebar with install
actions and details (version, canvas ID, keywords, author, commit).
- generate-website-data.mjs: emit readmeFile for extensions
- extensions-render.ts: deep-link cards to detail pages
- extensions.ts: strip modal/gallery wiring, keep filter/sort/copy actions
- resource-detail.ts: add copy-install-url action
- extension-gallery.ts: thumbnail switching for multi-image previews
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add VS Code Insiders and GitHub Copilot app install links
Introduce a shared PluginInstall component used by both plugin and canvas
extension detail pages. It renders a split-button dropdown deep-linking into
VS Code, VS Code Insiders, and the GitHub Copilot app (ghapp://), plus the
CLI command for internal items.
- Internal plugins/extensions: ghapp://plugins/install?source=<id>@awesome-copilot
- External plugins: ghapp://plugins/marketplace/add?source=<owner/repo>
- ghapp source values are URL-encoded per the app's deep-link contract
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Make GitHub Copilot app the default install option
Promote the ghapp:// deep link to the primary split-button action and list
it first in the dropdown, ahead of VS Code and VS Code Insiders.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Ignoring impeccable files
* Make Extensions grid Copy Install a direct Copilot app install
Replace the CLI-command copy button on extension cards with an
'Install in Copilot app' deep link (ghapp://plugins/install) for internal
extensions, matching the detail page. External extensions keep the Copy URL
fallback since they have no Copilot app install path.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Address PR review feedback on detail pages
- Remove DOM innerHTML read/write round trip in file browser cache
(CodeQL js/xss-through-dom); seed primary file from raw text and
render lazily.
- Use Shiki dual light/dark themes in the file browser and add dark
mode CSS overrides.
- Guard decodeURIComponent for #file= deep links against malformed
percent-encoding.
- Slugify SidebarChips title before using it in the tag class name.
- Use a neutral aria-label on the shared detail Sidebar.
- URL-encode the external plugin source in VS Code and Insiders
install links.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Prevent client-side path traversal in file deep links
Addresses the CSPT-to-XSS class reported in github/open-source#1739.
A '#file=' hash value containing '../' sequences could resolve outside
the awesome-copilot repo prefix once normalized by fetch, loading
attacker-controlled content that was then rendered into the page.
- Add isSafeRepoFilePath() and enforce it at the raw-URL choke point
(getRawGitHubUrl, fetchFileContent, downloadFile, getVSCodeInstallUrl),
so no consumer can escape the repo prefix.
- Validate the decoded '#file=' path in the modal hash handler and guard
its decodeURIComponent against malformed input.
The new hash-based file browser already restricts deep links to an
allowlist of build-time file descriptors; the choke-point guard is an
additional backstop.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Fix accessibility violations on resource detail pages
Run the a11y audit against the new detail pages and resolve every
critical/serious axe violation it surfaced:
- Nest the detail column as a <div> instead of a second <main>, fixing the
duplicate/non-top-level/non-unique landmark rules on every detail page.
- Add a shared enhanceMarkdownA11y() helper that makes rendered <pre>/<table>
blocks keyboard focusable and gives task-list checkboxes a state-based
accessible name; apply it at build time and in the client file browser.
- Make Shiki-highlighted code and install-command <code> blocks focusable.
- Underline links inside rendered docs and install notes so they are
distinguishable without color, overriding the global #main-content reset.
- Extend the a11y audit to cover one representative page per detail type.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Fix file browser GitHub URL handling
Encode selected file paths before assigning GitHub detail links and render load errors with DOM APIs so DOM-derived file names are not reinterpreted as markup.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Address PR review feedback on detail pages and file browser
- Deep-link plugin extension items to their /extension/<id>/ detail pages:
generate canvas extensions before building the resource index, and index
extensions (by id and folder basename) so resolvePluginItem can resolve them.
- Render image files in the bundle file browser via an <img> tag built from the
safe raw URL instead of decoding binary assets as UTF-8 text; skip the
copy-file action for images.
- Use a neutral 'Install' heading on internal plugin and extension pages so the
split-button primary label accurately communicates the target.
- Warn (with the file path) when readResourceMarkdown fails instead of swallowing
the error silently, keeping the build unbroken.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Address PR review feedback on install links, dropdown a11y, and ZIP downloads
- externalRepoUrl (plugin detail pages) now builds the 'View on GitHub' tree
URL from the pinned source.ref or source.sha, falling back to main only when
neither is present, so the link matches the sidebar Ref/Commit chips.
- Install split-button dropdown on resource detail pages is now keyboard
accessible: opening focuses the first item, ArrowUp/ArrowDown wrap, Home/End
jump, and Escape closes and restores focus to the toggle, mirroring modal.ts.
- downloadZipBundle fetches each file as an ArrayBuffer and hands it to JSZip so
binary assets (PNG/JPG/etc.) are preserved instead of corrupted by UTF-8 text
decoding.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Address PR review feedback on external repo links and workflow install note
- externalRepoUrl now uses a pinned source.ref/sha even when the external
plugin has no path, returning /tree/<ref> so "View on GitHub" points at the
pinned revision and stays consistent with the sidebar Ref/Commit chips.
- Reflow the workflow install note so each inline code and link element stays on
a single line (using explicit whitespace expressions for word spacing),
removing the split end-tag artifacts while preserving the exact rendered text
and spacing.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Harden repo path validation and fix Included Items file links
- isSafeRepoFilePath now fails closed on any "%" so percent-encoded dot-segments
(%2e%2e and double-encoded %252e%252e) cannot be normalized back into path
traversal by the browser URL parser during fetch, and also rejects "." and
empty path segments. Legitimate repo paths never contain these.
- IncludedItems githubHref now links file paths via /blob/ and directories via
/tree/, detecting files by a trailing extension on the last path segment, so
the fallback links for agent/instruction/command items no longer 404.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Harden detail pages: sanitize markdown, fix search deep-links and external URLs
Addresses rubber-duck review items 1-5 for the detail-page migration:
1. Sanitize rendered markdown as untrusted HTML. Add isomorphic
sanitize-html helper (isomorphic-dompurify) applied in the build-time
pipeline (detail-page.ts) and the client file browser before a11y
enhancement, so marked output can no longer inject scripts/handlers.
2. Point Pagefind search results at canonical /type/id/ detail pages
instead of inert #file= listing hashes for types that have a detail page.
3. Sanitize external/generated URLs on plugin and extension detail pages
and their render scripts so only http(s) links are emitted.
4. Add a shared externalRepoUrl helper that pins GitHub links to the
source ref/sha (preferring sha) with encoded path segments, replacing
the duplicated always-main logic in the pages, modal, and renderers.
5. Handle #file= hash navigation after initial load in the file browser
via a hashchange listener.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Detail pages: clickable filter chips + code-block copy buttons (#2255)
* Add clickable filter chips on detail pages
Turn read-only metadata chips into navigation: tags (hooks/plugins),
keywords (extensions), and extensions (instructions) now link to their
list page pre-filtered by that value (e.g. /hooks/?tag=testing).
SidebarChips gains optional filterBase/filterParam props; when both are
set each chip renders as an <a> with an aria-label and hover/focus
styling, otherwise it stays a plain <span>. Agent/skill/workflow chips
are unchanged. Filtering was verified end to end against each list
page's existing query-param handling.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add copy buttons to documentation code blocks
Detail-page markdown is rendered as plain <pre><code> with no syntax
highlighter, so code and config snippets had no copy affordance. Add a
hover-revealed copy button to every code block in the rendered docs:
copies to the clipboard, shows a toast, and swaps to a check icon for
confirmation. Buttons are keyboard-accessible, always visible on touch
devices, and respect reduced-motion. The sidebar frontmatter block is
left untouched.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Fix detail-page GitHub links, empty-state link contrast, and file cache
Addresses four PR review comments on the detail-page migration:
- skill/hook detail pages: build the sidebar "View on GitHub" link from a
/tree/main base instead of /blob/main, since item.path is a directory and
/blob/<dir> URLs 404. The FileBrowser githubBase stays on /blob for
individual file links.
- global.css: include .detail-empty a in the underline override so links in
empty-state notes stay distinguishable without relying on color alone
(WCAG 1.4.1 / axe link-in-text-block).
- file-browser.ts: seed the primary file's cache with its already-rendered
(frontmatter-stripped) HTML in addition to raw text, so re-selecting the
primary file after navigating away no longer re-renders the raw source and
surfaces frontmatter. Copy still uses the full raw text.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Ayan Gupta <74832088+ayangupt@users.noreply.github.com>
* fix(website): remediate WCAG accessibility issues and add axe regression guardrail
Fixes accessibility violations found by an axe-core sweep of every website
page in both light and dark themes:
- aria-allowed-role (WCAG 1.3.1, 4.1.2): the shared resource card rendered
an <article> with role="listitem", which is not an allowed role for that
element. Switched the wrapper to a <div role="listitem"> so the listitem
role is valid (affected every card, e.g. #arcade-canvas on /extensions/).
- aria-required-children (WCAG 1.3.1): removed role="list" from the tools,
contributors, and cookbook containers whose children are not list items.
- nested-interactive (WCAG 4.1.2): removed tabIndex=0 from extension cards
and rendered the author as a non-interactive span so no interactive
control is nested inside another (the author link remains in the modal).
- color-contrast (WCAG 1.4.3): gave .btn-primary explicit white text with an
AA-compliant hover (#7326d6), and bumped the dark-theme secondary text gray
(--sl-color-gray-3) to #84849c (5.32:1) so ToC / meta / footer text passes.
Adds a checked-in regression guardrail:
- website/scripts/a11y-audit.mjs runs axe-core over all routes in both themes
against the production build and fails on critical/serious violations only
(moderate/minor are reported but non-blocking). Transitions/animations are
disabled before sampling so axe measures settled, steady-state colors
instead of mid-theme-transition frames.
- Adds npm scripts (website:a11y at the root, a11y in website/) and README
docs. The matching Build Website CI step is proposed in the PR description
(omitted from this commit because the authoring token lacks workflow scope).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* fix(website): harden a11y audit per PR review
- Fail fast when a route navigation returns a non-2xx response, so the
guardrail can't silently pass against a broken/missing route (page.goto
resolves even for 4xx/5xx).
- Launch the Astro preview server via `node <astro-bin>` instead of
`spawn(..., { shell: true })`. Removing the shell layer keeps signal
delivery / detached-PGID shutdown predictable; resolving Astro's bin and
running it with process.execPath also avoids the EINVAL that modern Node
raises when spawning the npx.cmd shim without a shell on Windows.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: David Pine <7679720+IEvangelist@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Remove pluginRoots property from marketplace.json
The pluginRoots property is not used by install tooling and was only
informational about the extension/plugin source directories. Removing it
simplifies the marketplace.json structure while maintaining all functionality.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Migrate java-modernization-studio to plugin.json and update validation workflow
- Create .github/plugin/plugin.json for java-modernization-studio extension
- Remove legacy canvas.json from java-modernization-studio
- Update validate-canvas-extensions.yml workflow to check for plugin.json instead of canvas.json
- Update workflow to trigger on .schemas/plugin.schema.json changes (instead of canvas.schema.json)
- Remove schema validation logic that relied on canvas.schema.json
- All 12 extensions now use plugin.json for metadata
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add extensions field to all extension plugin.json files
Per https://github.com/github/copilot-agent-runtime/pull/9929, plugins that ship
extensions need to include an extensions field specifying where the extension code
is located. All 12 extensions now have extensions set to '.' to reference the
current directory where extension.mjs is located.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Enforce convention-based extension metadata and remove x-awesome-copilot
- Remove x-awesome-copilot.screenshots from all extension plugin.json files
- Enforce logo=assets/preview.png convention for all extensions
- Enforce extensions=. per copilot-agent-runtime#9929
- Update validate-plugins.mjs to enforce conventions
- Update validate-canvas-extensions.yml workflow with convention checks
- Update AGENTS.md and CONTRIBUTING.md documentation
All 12 extensions validated successfully.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Use standard plugin validation for extensions
Remove the custom extension schema and schema validation helper, and
validate extension plugin.json files through the existing plugin validator
instead. Update workflows to stop depending on the removed schema.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Show "by @handle" on each canvas extension card and in the details
modal, linking to the contributor's GitHub profile. Author metadata
lives in each extension's canvas.json (and external.json for external
extensions), where the rest of the canvas metadata is stored.
- Store author {name, url} in canvas.json / external.json
- Read author from canvas.json in the website data generator and emit
it to extensions.json
- Render the GitHub @handle, derived from the profile URL, as the link
text, with the contributor's name as the link title
- Escape the sanitized author URL before interpolating it into href
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Prototype extension details modal
- Add detail popup modal for extension cards with full metadata and gallery
- Implement image gallery with thumbnail strip and main image selection
- Add modal styling and positioning in global.css
- Connect card click handlers to open modal with extension data
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix accessibility issues with modal focus restoration
- Add missing listing-cards-page class to agents.astro page root
- Pass focusable button element to openCardDetailsModal instead of article
- Fixes focus restoration for keyboard users when closing modal
- Applied fix across all listing pages (agents, instructions, hooks, plugins, skills, workflows)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address remaining PR review feedback
- Fix extension modal ARIA state by setting aria-current to "true" and removing it when inactive
- Use focusable .resource-preview as modal trigger for extension thumbnail/click/keyboard paths
- Extract shared multi-select helpers into pages/select-utils.ts and reuse across instructions/hooks/plugins/workflows
- Remove unused card-model.ts to avoid dead/overlapping type definitions
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: add canvas extensions learning hub guide
Add a new Learning Hub page for creating and iterating canvas extensions with /create-canvas, including examples and best practices for storage scope and joinSession/createCanvas handlers.
Wire the article into Fundamentals navigation and related Learning Hub pages, and add stable extension card anchors so docs can deep-link to specific entries in the Canvas Extensions listing.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Add keyword display to extension cards on website
- Add .resource-keywords and .keyword-tag CSS styles for rendering keyword badges
- Update renderExtensionsHtml() to display keywords below extension description
- Keywords now visible on the website extensions page with styled badges
- Regenerate website data to include keyword metadata
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Canvas manifest implementation for all extensions
Add per-extension canvas manifests with:
- Structured canvas metadata (name, description, version, keywords)
- Screenshot definitions (icon and gallery with path/type)
- Relative paths for images within each extension directory
Enhance extension metadata:
- Generate meaningful descriptions from source analysis
- Extract and assign keywords for discoverability
- Store metadata in package.json and extension source files
Update website rendering and data generation:
- Include keywords in extension cards and search index
- Add per-extension canvas.json files for independent evolution
- Support screenshot metadata in manifest structure
- Generate extensions.json with full canonical paths for website
All 9 local canvas extensions now have complete manifests with descriptions, keywords, and screenshot references.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Tweaking some descriptions
* Fix description priority to prefer package.json over in-source metadata
Reverse the priority in canvasDescription so that package.json descriptions
(which contain the enhanced, manually-curated descriptions) take precedence
over older in-source descriptions extracted from createCanvas(...) calls.
This prevents regression when npm run website:data regenerates outputs,
ensuring that committed canvas.json files maintain the current descriptions.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix canvas validation to skip external.json file
The validation script was treating extensions/external.json as if it were
a directory, causing false validation failures. Added check to skip files
(identified by presence of dot in filename) and only validate actual
canvas extension directories.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Generate extensions data, add the extensions listing route/navigation, and include install URL copy actions pinned to the build commit SHA.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fixing path on chrome devtools external pluginPath is to the folder in the repo where the plugin structure starts, not where the plugin.json file lives.
* Updating validation scripts and guidance to avoid this mistake again
* Removing search from the home pageThis was a little confusing because there are two searches, but the overall site search is a lot more powerful
* Prefilter website search by resource page
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* small error handling and formatting
* Simplify website listing controls
Remove per-page text search, trim page-specific controls, and move remaining sort/filter controls into compact flyouts.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fixing model names
* handling arrays of models for agent frontmatter
* Cleaning up some warnings on website build
* adding a workflow to run and perform CI of the website
* feat(ui): replace emoji icons with SVG icon system
Replace all emoji icons with a consistent SVG icon system to improve:
- Visual consistency across platforms
- Design token control and theming
- Professional appearance
Changes:
- Add new Icon.astro component with 16 custom SVG icons
- Update index.astro to use SVG icons in resource cards
- Update index.ts to render SVG icons in search results
- Update utils.ts to return icon names instead of emojis
- Update global.css with proper SVG icon styling
- Remove emoji from Footer component
Icons added: robot, document, lightning, hook, workflow, plug, wrench, book,
plus action icons: close, copy, download, share, external, plus, search, chevron-down
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ui): enhance hero section, add animations and mobile responsiveness
Phase 2 & 3 UI/UX improvements:
Hero Section Enhancements:
- Add gradient text effect for title (purple to orange gradient)
- Add animated floating particles in hero background
- Increase hero padding for better visual impact
Card Category Colors:
- Add category-specific accent colors (AI, docs, power, automation, etc.)
- Each category has unique glow effect on hover
- Category colors: purple (AI), orange (docs), red (power), etc.
Entrance Animations:
- Add staggered fade-in animation for cards (50ms delay each)
- Cards animate in with translateY + opacity
- Add slide-down animation for search results
Mobile Responsiveness:
- Responsive grid: 4 cols → 2 cols → 1 col
- Adjust font sizes for mobile screens
- Add safe-area-inset support for notched devices
- Ensure touch targets ≥44px
Accessibility:
- Add prefers-reduced-motion support
- Disable animations for users who prefer reduced motion
- Smooth scroll with fallback
Additional Improvements:
- Add arrow indicator on card hover
- Add loading animation for count numbers
- Enhanced scrollbar styling
- Print styles for better printing
Co-Authored-By: Claude <noreply@anthropic.com>
* feat(ui): add theme toggle, enhanced search, and back to top button
Theme Toggle:
- Create ThemeToggle.astro component with sun/moon icons
- Add theme initialization in Head.astro to prevent flash
- Store theme preference in localStorage
- Keyboard shortcut: Cmd/Ctrl + Shift + L
- Smooth icon transition animation
Back to Top Button:
- Create BackToTop.astro component
- Appears after scrolling 400px
- Smooth scroll to top on click
- Fixed position bottom-right
- Respects reduced motion preference
Enhanced Search:
- Recent searches functionality with localStorage
- Show recent searches on focus when empty
- Remove individual items or clear all
- Enhanced empty state with icon and hint
- Cmd/Ctrl + K keyboard shortcut to focus search
- Add search to recent when getting results
CSS Enhancements:
- Theme toggle container styles
- Recent searches section styling
- Search empty state with icon
- Search loading spinner
- Keyboard shortcut hint styles
- Print styles for new components
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(ui): resolve header and theme toggle issues
- Add Copilot logo to header via Starlight config with automatic theme switching
- Fix theme toggle slider direction (was reversed)
- Fix theme toggle active icon highlighting (was backwards)
- Change theme toggle from purple circle slider to bold text indicator
- Fix theme toggle slider overflow by adding overflow: hidden
- Remove duplicate banner image from home page
- Clean up conflicting logo CSS rules to prevent duplication
The header now displays: [ Copilot Icon ] Awesome GitHub Copilot [ Search ]
Theme toggle indicators are now visually clear with bold text for selected theme.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* fix(ui): address feedback on UI/UX improvements
- Remove logo from header per brand guidance (logo config and CSS)
- Fix back-to-top button visibility by moving to body level and using global styles
- Fix modal visibility by adding 'visible' class for CSS animations
- Fix theme toggle applying site-wide by using global styles and proper theme initialization
- Update icons to use GitHub Primer SVG icons with proper fill-based styling
- Fix plugin modal to render SVG icons instead of icon names
- Add theme initialization script to prevent flash of unstyled content
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: move modal to body level to fix z-index stacking context issue
The modal was nested inside .main-pane which has isolation: isolate,
creating a new stacking context. This caused the modal's z-index
to be evaluated within that context, unable to stack above the header.
This fix moves the modal to be a direct child of body on page load,
allowing it to properly cover the entire viewport including navbar.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Make the skill modal download button reuse the existing skill ZIP behavior so it downloads the full skill bundle instead of only the current file. Extract the ZIP creation into a shared utility and reuse it from the skills and hooks pages.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Some layout tweaks
* SSR resource listing pages
Render resource listing pages in Astro for first paint and hydrate client filtering/search behavior on top.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fixing font path
* removing feature plugin reference as we don't track that anymore
* button alignment
* rendering markdown
* Improve skills modal file browsing
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Improving the layout of the search/filter section
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: show external plugins on the website
Read plugins/external.json during website data generation and include
external plugins alongside local ones in plugins.json. External plugins
are flagged with external:true and carry metadata (author, repository,
homepage, license, source).
On the website:
- Plugin cards show a '🔗 External' badge and author attribution
- The 'Repository' button links to the source path within the repo
- The modal shows metadata (author, repo, homepage, license) and a
'View Repository' CTA instead of an items list
- External plugins are searchable and filterable by tags
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: address PR #937 security and UX review comments
- Add sanitizeUrl() function to validate URLs and prevent XSS via javascript:/data: schemes
- Add rel="noopener noreferrer" to all target="_blank" links to prevent reverse-tabnabbing
- Change external plugin path from external/<name> to plugins/<name> for proper deep-linking
- Track actual count of external plugins added (after filtering/deduplication) in build logs
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(schema): add external recipe fields to cookbook schema
Add optional external, url, and author fields to the recipe schema
in cookbook.schema.json. When external is true, url is required via
conditional validation. Author supports name (required) and url
(optional) for attribution.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(data): support external recipes in data generator
- External recipes (external: true) skip local file validation
- Validate URL format for external recipes
- Pass through external, url, and author fields to output JSON
- Add per-recipe languages array: derived from resolved variant keys
for local recipes, and from tags matching known language IDs for
external recipes
- Collect language IDs in a first pass before processing recipes
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(website): render external recipe cards on cookbook page
- Extend Recipe interface with external, url, author, and languages
- Render external recipes with Community badge, author attribution,
and View on GitHub link instead of View Recipe/View Example buttons
- Language filter uses per-recipe languages array uniformly
- Remove Nerd Font icons from select dropdown options (native selects
cannot render custom web fonts)
- Add CSS for external recipe cards (dashed border, badge, author)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(cookbook): add community samples section with first external recipe
Add a Community Samples cookbook section to cookbook.yml with the
Node.js Agentic Issue Resolver as the first external recipe entry,
linking to https://github.com/Impesud/nodejs-copilot-issue-resolver.
Resolves the use case from PR #613 for supporting external samples.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(cookbook): add Copilot SDK Web App to community samples
Add aaronpowell/copilot-sdk-web-app — a full-stack chat app built with
the GitHub Copilot SDK, .NET Aspire, and React.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Update parseWorkflowMetadata to extract triggers from the 'on'
property keys (e.g. schedule, issue_comment) instead of a separate
'triggers' field. Remove tags support from workflows since workflows
don't use tags.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use 'type' modifier on SearchItem imports to satisfy
verbatimModuleSyntax. Without this, esbuild strips the interface
export but leaves the value import, causing a runtime error.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a new /workflows/ page for browsing agentic workflow definitions
with search, trigger/tag filters, and sorting. Follows the same
patterns as the existing hooks page.
New files:
- website/src/pages/workflows.astro
- website/src/scripts/pages/workflows.ts
Updated files:
- BaseLayout.astro: add Workflows nav link
- index.astro: add Workflows card to homepage
- pages/index.ts: add workflows to counts
- utils.ts: add workflow type to icons, labels, and getResourceType
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the prompts page, navigation link, homepage card, and all
references to prompts across the website source code. The repo no
longer contains prompt files, so the website should not reference them.
Files removed:
- website/src/pages/prompts.astro
- website/src/scripts/pages/prompts.ts
Files updated:
- BaseLayout.astro: remove nav link and update description
- index.astro: remove prompts card and update text
- llms.txt.ts: remove prompts import and section
- plugins.astro: update description text
- utils.ts: remove prompt type from install config, icons, labels
- pages/index.ts: remove prompts from counts
- modal.ts: update JSDoc comment
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace Collections with Plugins as first-class citizens in the repo.
With the Copilot CLI v0.409 release making plugins an on-by-default
marketplace, collections are redundant overhead.
## What changed
### Plugin Infrastructure
- Created eng/validate-plugins.mjs (replaces validate-collections.mjs)
- Created eng/create-plugin.mjs (replaces create-collection.mjs)
- Enhanced all 42 plugin.json files with tags, featured, display, and
items metadata from their corresponding collection.yml files
### Build & Website
- Updated eng/update-readme.mjs to generate plugin docs
- Updated eng/generate-website-data.mjs to emit plugins.json with full
items array for modal rendering
- Renamed website collections page to plugins (/plugins/)
- Fixed plugin modal to use <div> instead of <pre> for proper styling
- Updated README.md featured section from Collections to Plugins
### Documentation & CI
- Updated CONTRIBUTING.md, AGENTS.md, copilot-instructions.md, PR template
- Updated CI workflows to validate plugins instead of collections
- Replaced docs/README.collections.md with docs/README.plugins.md
### Cleanup
- Removed eng/validate-collections.mjs, eng/create-collection.mjs,
eng/collection-to-plugin.mjs
- Removed entire collections/ directory (41 .collection.yml + .md files)
- Removed parseCollectionYaml from yaml-parser.mjs
- Removed COLLECTIONS_DIR from constants.mjs
Closes#711
The samples page never called setupModal(), so the close button,
Escape key, and backdrop click handlers were never registered.
Add the missing setupModal() call matching all other pages.
- Add git-dates.mjs utility to extract file modification dates from git history
- Include lastUpdated field in JSON data for all resource types
- Display relative time (e.g., '3 days ago') with full date on hover
- Add 'Recently Updated' sort option to agents, prompts, instructions, and skills pages
- Update deploy-website.yml to use fetch-depth: 0 for full git history
CI overhead: ~20-30s additional for full git checkout
- Standardized string quotes to double quotes across multiple files.
- Improved formatting and indentation for better readability.
- Added a function to format multiline text in tools rendering.
- Enhanced dropdown and action button handlers for better event management.
- Updated the theme application logic to initialize on page load.
- Refactored utility functions for consistency and clarity.
- Improved error handling and user feedback in download and share functionalities.
- Remove SearchableRecipe interface that conflicted with SearchableItem
- Use proper type casting for search results
- Fix FuzzySearch generic type usage
Integrates the cookbook/ folder into the website's Samples page:
Data Structure:
- Add cookbook/cookbook.yml manifest defining cookbooks and recipes
- Add .schemas/cookbook.schema.json for validation
- Add COOKBOOK_DIR constant to eng/constants.mjs
Build Integration:
- Add generateSamplesData() to generate samples.json from cookbook.yml
- Include recipe variants with file paths for each language
- Add samples count to manifest.json
Website UI:
- Create samples.ts with FuzzySearch, language/tag filtering
- Replace placeholder samples.astro with functional recipe browser
- Recipe cards with language indicators and action buttons
- Language tabs for switching between implementations
- View Recipe/View Example buttons open modal
- GitHub link for each recipe
Features:
- Search recipes by name/description
- Filter by programming language (Node.js, Python, .NET, Go)
- Filter by tags (multi-select with Choices.js)
- 5 recipes across 4 languages = 20 recipe variants
- Remove separate hero-stats section
- Add card-count element to each resource card
- Update JS to populate counts from manifest
- Add card-with-count CSS for layout with count badge
- Reduces vertical space on home page
- Add SearchableItem base interface for minimum required fields
- Make FuzzySearch class generic with type parameter
- Update all page scripts to use typed FuzzySearch instances
- Fix type casting in calculateScore method
- Add Download button to download file as .md file
- Add Share button to copy GitHub link to clipboard
- Both buttons appear in modal header and list view actions
- Use icon-only buttons in list view for cleaner UI
- Replace separate VS Code/Insiders buttons with single Install dropdown
- Primary 'Install' button opens in VS Code, dropdown chevron reveals options
- Dropdown shows 'VS Code' and 'VS Code Insiders' choices
- Add CSS for split button styling with glassmorphism dropdown
- Apply to modal and all list views (agents, prompts, instructions)
- Add VS Code and VS Code Insiders install buttons to agent, prompt, and instruction list items
- Use smaller button style for list view
- Include VS Code icon for visual identification