diff --git a/eng/generate-website-data.mjs b/eng/generate-website-data.mjs index f20a8bbea..49b6aecf7 100755 --- a/eng/generate-website-data.mjs +++ b/eng/generate-website-data.mjs @@ -101,6 +101,25 @@ function normalizeText(value, fallback = "") { return typeof value === "string" ? value.trim() : fallback; } +/** + * Normalize an author value (npm string form or { name, url } object) to + * { name, url? } | null. Returns null when no usable name is present. + */ +function normalizeAuthor(value) { + if (!value) return null; + if (typeof value === "string") { + const name = value.trim(); + return name ? { name } : null; + } + if (typeof value === "object") { + const name = normalizeText(value.name); + if (!name) return null; + const url = normalizeText(value.url); + return url ? { name, url } : { name }; + } + return null; +} + /** * Find the latest git-modified date for any file under a directory. */ @@ -1044,6 +1063,7 @@ function generateCanvasManifest(gitDates, commitSha) { installUrl, sourceUrl: null, external: false, + author: normalizeAuthor(packageJson.author), keywords, }); } @@ -1116,6 +1136,7 @@ function generateCanvasManifest(gitDates, commitSha) { installUrl, sourceUrl: sourceUrl || null, external: true, + author: normalizeAuthor(ext?.author), keywords, }); } diff --git a/extensions/accessibility-kanban/package.json b/extensions/accessibility-kanban/package.json index 48b33dbd3..8b47bce4a 100644 --- a/extensions/accessibility-kanban/package.json +++ b/extensions/accessibility-kanban/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "type": "module", "main": "extension.mjs", + "author": { "name": "Aaron Powell", "url": "https://github.com/aaronpowell" }, "dependencies": { "@github/copilot-sdk": "latest" }, diff --git a/extensions/arcade-canvas/package.json b/extensions/arcade-canvas/package.json index 1c7734e04..4086990e7 100644 --- a/extensions/arcade-canvas/package.json +++ b/extensions/arcade-canvas/package.json @@ -2,7 +2,7 @@ "name": "arcade-canvas", "version": "1.0.0", "main": "extension.mjs", - "author": "Dan Wahlin", + "author": { "name": "Dan Wahlin", "url": "https://github.com/DanWahlin" }, "license": "MIT", "type": "module", "dependencies": { diff --git a/extensions/backlog-swipe-triage/package.json b/extensions/backlog-swipe-triage/package.json index 34f712651..fa38ba318 100644 --- a/extensions/backlog-swipe-triage/package.json +++ b/extensions/backlog-swipe-triage/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "type": "module", "main": "extension.mjs", + "author": { "name": "James Montemagno", "url": "https://github.com/jamesmontemagno" }, "dependencies": { "@github/copilot-sdk": "1.0.1" }, diff --git a/extensions/chromium-control-canvas/package.json b/extensions/chromium-control-canvas/package.json index 5b6197b2f..180e11f77 100644 --- a/extensions/chromium-control-canvas/package.json +++ b/extensions/chromium-control-canvas/package.json @@ -2,7 +2,7 @@ "name": "chromium-control-canvas", "version": "1.0.0", "main": "extension.mjs", - "author": "Andrea Griffiths", + "author": { "name": "Andrea Griffiths", "url": "https://github.com/AndreaGriffiths11" }, "license": "MIT", "type": "module", "dependencies": { diff --git a/extensions/color-orb/package.json b/extensions/color-orb/package.json index a28cd5c3f..cd0f8e3eb 100644 --- a/extensions/color-orb/package.json +++ b/extensions/color-orb/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "type": "module", "main": "extension.mjs", + "author": { "name": "Aaron Powell", "url": "https://github.com/aaronpowell" }, "dependencies": { "@github/copilot-sdk": "latest" }, diff --git a/extensions/diagram-viewer/package.json b/extensions/diagram-viewer/package.json index 054ebcf77..e97f026a1 100644 --- a/extensions/diagram-viewer/package.json +++ b/extensions/diagram-viewer/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "type": "module", "main": "extension.mjs", + "author": { "name": "Aaron Powell", "url": "https://github.com/aaronpowell" }, "dependencies": { "@github/copilot-sdk": "latest" }, diff --git a/extensions/external.json b/extensions/external.json index c6b98bccf..f0e2f561a 100644 --- a/extensions/external.json +++ b/extensions/external.json @@ -3,6 +3,7 @@ "id": "coffilot", "name": "Coffilot", "description": "Java-focused Copilot canvas extension from jdubois.", + "author": { "name": "Julien Dubois", "url": "https://github.com/jdubois" }, "keywords": [ "java", "canvas", diff --git a/extensions/feedback-themes/package.json b/extensions/feedback-themes/package.json index f769acee7..e1aa4543f 100644 --- a/extensions/feedback-themes/package.json +++ b/extensions/feedback-themes/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "type": "module", "main": "extension.mjs", + "author": { "name": "Aaron Powell", "url": "https://github.com/aaronpowell" }, "dependencies": { "@github/copilot-sdk": "latest" }, diff --git a/extensions/gesture-review/package.json b/extensions/gesture-review/package.json index 1f5a911f9..d0627cab7 100644 --- a/extensions/gesture-review/package.json +++ b/extensions/gesture-review/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "type": "module", "main": "extension.mjs", + "author": { "name": "Aaron Powell", "url": "https://github.com/aaronpowell" }, "dependencies": { "@github/copilot-sdk": "latest" }, diff --git a/extensions/release-notes-showcase/package.json b/extensions/release-notes-showcase/package.json index cb192cd1c..490f8ace9 100644 --- a/extensions/release-notes-showcase/package.json +++ b/extensions/release-notes-showcase/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "type": "module", "main": "extension.mjs", + "author": { "name": "James Montemagno", "url": "https://github.com/jamesmontemagno" }, "dependencies": { "@github/copilot-sdk": "1.0.1" }, diff --git a/extensions/where-was-i/package.json b/extensions/where-was-i/package.json index 5534b4dbb..deb44ac1b 100644 --- a/extensions/where-was-i/package.json +++ b/extensions/where-was-i/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "type": "module", "main": "extension.mjs", + "author": { "name": "Aaron Powell", "url": "https://github.com/aaronpowell" }, "description": "Reconstruct your dev context (branch, commits, uncommitted work, PR clues) and trigger a resume prompt to continue quickly.", "keywords": [ "interrupt-recovery", diff --git a/website/src/scripts/pages/extensions-render.ts b/website/src/scripts/pages/extensions-render.ts index ac8f2539a..9e81f19c6 100644 --- a/website/src/scripts/pages/extensions-render.ts +++ b/website/src/scripts/pages/extensions-render.ts @@ -1,4 +1,4 @@ -import { escapeHtml, getGitHubUrl, getLastUpdatedHtml } from "../utils"; +import { escapeHtml, getGitHubUrl, getLastUpdatedHtml, sanitizeUrl } from "../utils"; import { renderEmptyStateHtml, renderSharedCardHtml } from "./card-render"; export interface RenderableExtension { @@ -34,6 +34,7 @@ export interface RenderableExtension { installUrl?: string | null; sourceUrl?: string | null; external?: boolean; + author?: { name: string; url?: string } | null; } export type ExtensionSortOption = "title" | "lastUpdated"; @@ -92,8 +93,21 @@ export function renderExtensionsHtml(items: RenderableExtension[]): string { `; + const authorHtml = item.author?.name + ? `by ${ + item.author.url + ? `${escapeHtml( + item.author.name + )}` + : escapeHtml(item.author.name) + }` + : ""; + const metaHtml = ` ${item.external ? 'External' : ""} + ${authorHtml} ${getLastUpdatedHtml(item.lastUpdated)} `; diff --git a/website/src/scripts/pages/extensions.ts b/website/src/scripts/pages/extensions.ts index 3c3c9c946..201b8edcb 100644 --- a/website/src/scripts/pages/extensions.ts +++ b/website/src/scripts/pages/extensions.ts @@ -15,6 +15,7 @@ import { getGitHubUrl, getQueryParam, getQueryParamValues, + sanitizeUrl, showToast, updateQueryParams, } from "../utils"; @@ -178,6 +179,19 @@ function openDetailsModal( if (item.external) { metaParts.push('External'); } + if (item.author?.name) { + metaParts.push( + item.author.url + ? `by ${escapeHtml( + item.author.name + )}` + : `by ${escapeHtml( + item.author.name + )}` + ); + } if (item.lastUpdated) { metaParts.push( `Updated ${escapeHtml(