Replace resource modals with dedicated detail pages and richer install options#2246
Open
aaronpowell wants to merge 33 commits into
Open
Replace resource modals with dedicated detail pages and richer install options#2246aaronpowell wants to merge 33 commits into
aaronpowell wants to merge 33 commits into
Conversation
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
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>
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>
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>
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>
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>
…uide # Conflicts: # website/src/scripts/pages/card-render.ts
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>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the website UX to replace modal-based resource previews with dedicated, deep-linkable detail pages for each resource type, enabling richer per-item metadata and install actions.
Changes:
- Added per-resource detail page routes (e.g.,
/agent/[id]/,/skill/[id]/,/plugin/[id]/, etc.) built on shared layout/components and build-time helpers. - Updated list/card rendering so resource previews deep-link to these detail pages instead of opening modals.
- Introduced shared client behavior for detail pages (install split-button dropdowns, copy/share/download) plus a file browser experience for multi-file bundles (skills/hooks).
Show a summary per file
| File | Description |
|---|---|
| website/src/styles/global.css | Adds styling for the new detail page layout, sidebar, install UI, gallery, and file browser. |
| website/src/scripts/pages/workflows.ts | Removes modal wiring; keeps filtering/sorting and relies on deep links. |
| website/src/scripts/pages/workflows-render.ts | Adds workflow detail-page URL generation and card href. |
| website/src/scripts/pages/skills.ts | Removes modal wiring; ensures action buttons don’t trigger navigation. |
| website/src/scripts/pages/skills-render.ts | Adds skill detail-page URL generation and card href. |
| website/src/scripts/pages/resource-detail.ts | New shared client behavior for detail-page sidebar actions and install dropdown. |
| website/src/scripts/pages/plugins.ts | Removes modal wiring; list becomes deep-link driven. |
| website/src/scripts/pages/plugins-render.ts | Adds plugin detail-page URL generation and card href. |
| website/src/scripts/pages/instructions.ts | Removes modal wiring; list becomes deep-link driven. |
| website/src/scripts/pages/instructions-render.ts | Adds instruction detail-page URL generation and card href. |
| website/src/scripts/pages/hooks.ts | Removes modal wiring; ensures download action doesn’t trigger navigation. |
| website/src/scripts/pages/hooks-render.ts | Adds hook detail-page URL generation and card href, plus hook file list typing. |
| website/src/scripts/pages/file-browser.ts | New client-side file browser for skill/hook multi-file bundles with lazy fetch + rendering. |
| website/src/scripts/pages/extensions.ts | Removes modal wiring; keeps list-level install/copy behavior. |
| website/src/scripts/pages/extensions-render.ts | Adds extension detail-page URL generation, ghapp install link, and card href. |
| website/src/scripts/pages/extension-gallery.ts | New thumbnail-driven gallery behavior for extension detail pages. |
| website/src/scripts/pages/card-render.ts | Enables rendering preview as <a> when href is provided, otherwise <button>. |
| website/src/pages/workflows.astro | Removes modal component from workflows list page. |
| website/src/pages/workflow/[id].astro | New workflow detail page route with sidebar actions and build-time markdown rendering. |
| website/src/pages/skills.astro | Removes modal component from skills list page. |
| website/src/pages/skill/[id].astro | New skill detail page route using file browser + CLI install/download actions. |
| website/src/pages/plugins.astro | Removes modal component from plugins list page. |
| website/src/pages/plugin/[id].astro | New plugin detail page route with included-items list and richer install options. |
| website/src/pages/instructions.astro | Removes modal component from instructions list page. |
| website/src/pages/instruction/[id].astro | New instruction detail page route using shared build-time helpers + install buttons. |
| website/src/pages/hooks.astro | Removes modal component from hooks list page. |
| website/src/pages/hook/[id].astro | New hook detail page route using file browser + ZIP download actions. |
| website/src/pages/extensions.astro | Removes modal component from extensions list page. |
| website/src/pages/extension/[id].astro | New extension detail page route with preview gallery + install options. |
| website/src/pages/agents.astro | Removes modal component from agents list page. |
| website/src/pages/agent/[id].astro | New agent detail page route using shared build-time helpers + install buttons. |
| website/src/lib/file-types.ts | New helper to classify files for the file browser (lang + kind). |
| website/src/lib/detail-page.ts | New build-time helpers for reading/formatting markdown + generating install URLs. |
| website/src/components/pages/SidebarChips.astro | New chip rendering component for sidebar metadata sections. |
| website/src/components/pages/Sidebar.astro | New shared sidebar layout for detail pages (actions + metadata + frontmatter). |
| website/src/components/pages/RawMarkdown.astro | Embeds raw markdown into the page for “Copy markdown” actions. |
| website/src/components/pages/PluginInstall.astro | New split-button install UI for plugins/extensions (ghapp + VS Code variants + CLI). |
| website/src/components/pages/Main.astro | New shared “Documentation” main content section used by detail pages. |
| website/src/components/pages/InstallButtons.astro | New install dropdown UI for agent/instruction pages (VS Code + actions). |
| website/src/components/pages/IncludedItems.astro | New plugin “included items” section with internal deep links where available. |
| website/src/components/pages/Header.astro | New shared header component for detail pages. |
| website/src/components/pages/FileBrowser.astro | New build-time file browser component markup for skill/hook bundles. |
| website/src/components/pages/Breadcrumb.astro | New breadcrumb component for detail pages. |
| eng/generate-website-data.mjs | Enriches generated data to support file browsers, plugin detail info, and item linking. |
| .gitignore | Adds .impeccable to ignored files. |
Review details
- Files reviewed: 46/47 changed files
- Comments generated: 6
- Review effort level: Low
- 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>
- 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>
…ownloads - 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>
…l 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>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- 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>
| item.skillFile | ||
| ); | ||
| const lastUpdated = formatLastUpdated(item.lastUpdated); | ||
| const githubUrl = `${GITHUB_BASE}/${item.path}`; |
| item.readmeFile | ||
| ); | ||
| const lastUpdated = formatLastUpdated(item.lastUpdated); | ||
| const githubUrl = `${GITHUB_BASE}/${item.path}`; |
…ernal 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>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Checklist
npm startand verified thatREADME.mdis up to date.mainbranch for this pull request.Description
The website previously showed each resource (agent, instruction, skill, hook, workflow, plugin, canvas extension) in a popup modal. Modals can't be deep linked, can't be opened in a new tab, and left little room for the richer metadata some resource types carry. This PR replaces the modal experience with dedicated per-item pages that have real URLs, better SEO, and room for additional info, while keeping the existing Starlight visual style.
Approach
Header,Breadcrumb,Sidebar,SidebarChips,Main,RawMarkdown,InstallButtons,FileBrowser,IncludedItems,PluginInstall) plus shared build logic inlib/detail-page.tsand client behavior inscripts/pages/resource-detail.ts. Each resource type gets its ownpages/<type>/[id].astroroute built on this foundation.card-render.tsnow renders the preview as an<a>to the detail page (falling back to the button form when nohrefis given), so open-in-new-tab and shareable URLs work. All list controllers were updated to drop modal wiring.PluginInstallsplit-button offers Install in the GitHub Copilot app (the default), VS Code, VS Code Insiders, and the CLI. Internal items useghapp://plugins/install?source=<id>@awesome-copilot; external plugins useghapp://plugins/marketplace/add?source=<owner/repo>(sources are URL-encoded). The Extensions grid's old "Copy Install" button is now a direct "Install in Copilot app" deep link for internal extensions.Notes for reviewers
main; the only conflict was incard-render.ts, wheremainswitched the card wrapper from<article>to<div>while this branch refactored the preview into an href-based link. Both changes were combined.npm run build(954 pages),npm run plugin:validate, andnpm run skill:validate.Type of Contribution
Additional Notes
Generated data files under
website/public/data/remain gitignored and are produced at build time, so they are not part of this diff.By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.