chore: publish from staged

This commit is contained in:
github-actions[bot]
2026-06-16 23:19:14 +00:00
parent 8750d19424
commit ce41daf445
25 changed files with 5482 additions and 26 deletions
+143 -1
View File
@@ -97,6 +97,10 @@ function formatDisplayName(value) {
.join(" "); .join(" ");
} }
function normalizeText(value, fallback = "") {
return typeof value === "string" ? value.trim() : fallback;
}
/** /**
* Find the latest git-modified date for any file under a directory. * Find the latest git-modified date for any file under a directory.
*/ */
@@ -670,6 +674,76 @@ function generatePluginsData(gitDates) {
/** /**
* Generate canvas extensions metadata * Generate canvas extensions metadata
*/ */
function getExtensionAssetInfo(extensionDir, relPath, ref) {
const assetDir = path.join(extensionDir, "assets");
if (!fs.existsSync(assetDir)) {
return null;
}
const imageExtensions = new Set([
".png",
".jpg",
".jpeg",
".webp",
".gif",
]);
const preferredNames = [
"preview.png",
"preview.jpg",
"preview.jpeg",
"preview.webp",
"preview.gif",
"screenshot.png",
"screenshot.jpg",
"screenshot.jpeg",
"screenshot.webp",
"screenshot.gif",
"image.png",
"image.jpg",
"image.jpeg",
"image.webp",
"image.gif",
];
for (const candidate of preferredNames) {
const candidatePath = path.join(assetDir, candidate);
if (fs.existsSync(candidatePath)) {
const assetPath = `${relPath}/assets/${candidate}`;
return {
assetPath,
imageUrl: buildRepoImageUrl(assetPath, ref),
};
}
}
const files = fs
.readdirSync(assetDir)
.filter((file) => imageExtensions.has(path.extname(file).toLowerCase()))
.sort((a, b) => a.localeCompare(b));
if (files.length === 0) {
return null;
}
const assetFile = files[0];
const assetPath = `${relPath}/assets/${assetFile}`;
return {
assetPath,
imageUrl: buildRepoImageUrl(assetPath, ref),
};
}
function buildRepoImageUrl(assetPath, ref) {
const encodedAssetPath = assetPath
.split("/")
.map((segment) => encodeURIComponent(segment))
.join("/");
return `https://raw.githubusercontent.com/github/awesome-copilot/${ref}/${encodedAssetPath}`;
}
function generateExtensionsData(gitDates, commitSha) { function generateExtensionsData(gitDates, commitSha) {
const extensions = []; const extensions = [];
@@ -679,19 +753,87 @@ function generateExtensionsData(gitDates, commitSha) {
const extensionDirs = fs const extensionDirs = fs
.readdirSync(EXTENSIONS_DIR, { withFileTypes: true }) .readdirSync(EXTENSIONS_DIR, { withFileTypes: true })
.filter((entry) => entry.isDirectory()); .filter((entry) => {
if (!entry.isDirectory()) return false;
const extensionEntryPoint = path.join(
EXTENSIONS_DIR,
entry.name,
"extension.mjs"
);
return fs.existsSync(extensionEntryPoint);
});
for (const dir of extensionDirs) { for (const dir of extensionDirs) {
const relPath = `extensions/${dir.name}`; const relPath = `extensions/${dir.name}`;
const assetInfo = getExtensionAssetInfo(
path.join(EXTENSIONS_DIR, dir.name),
relPath,
commitSha
);
extensions.push({ extensions.push({
id: dir.name, id: dir.name,
name: formatDisplayName(dir.name), name: formatDisplayName(dir.name),
description: "Canvas extension",
path: relPath, path: relPath,
ref: commitSha, ref: commitSha,
lastUpdated: getDirectoryLastUpdated(gitDates, relPath), lastUpdated: getDirectoryLastUpdated(gitDates, relPath),
imageUrl: assetInfo?.imageUrl || null,
assetPath: assetInfo?.assetPath || null,
installUrl: `https://github.com/github/awesome-copilot/tree/${commitSha}/${relPath.replace(
/\\/g,
"/"
)}`,
sourceUrl: null,
external: false,
}); });
} }
const externalJsonPath = path.join(EXTENSIONS_DIR, "external.json");
if (fs.existsSync(externalJsonPath)) {
try {
const externalExtensions = JSON.parse(
fs.readFileSync(externalJsonPath, "utf-8")
);
if (Array.isArray(externalExtensions)) {
for (const ext of externalExtensions) {
const name = normalizeText(ext?.name);
const installUrl = normalizeText(ext?.installUrl);
const sourceUrl = normalizeText(ext?.sourceUrl || installUrl);
if (!name || !installUrl) {
continue;
}
const id = normalizeText(ext?.id || name.toLowerCase().replace(/\s+/g, "-"));
let imageUrl = normalizeText(ext?.imageUrl);
let assetPath = null;
const imagePath = normalizeText(ext?.imagePath);
if (!imageUrl && imagePath) {
const repoAssetPath = imagePath.replace(/\\/g, "/");
imageUrl = buildRepoImageUrl(repoAssetPath, commitSha);
assetPath = repoAssetPath;
}
extensions.push({
id,
name,
description: normalizeText(ext?.description, "External canvas extension"),
path: null,
ref: null,
lastUpdated: null,
imageUrl: imageUrl || null,
assetPath,
installUrl,
sourceUrl: sourceUrl || null,
external: true,
});
}
}
} catch (e) {
console.warn(`Failed to parse external extensions: ${e.message}`);
}
}
const sortedExtensions = extensions.sort((a, b) => const sortedExtensions = extensions.sort((a, b) =>
a.name.localeCompare(b.name) a.name.localeCompare(b.name)
); );
Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

@@ -0,0 +1,8 @@
# Backlog Swipe Triage
Swipe-driven backlog triage canvas for reviewing open issues, applying quick decisions, and starting implementation sessions.
## Assets
- `assets/preview.png` — preferred screenshot path for the triage experience.
- `assets/swipe-canvas-triage.png` — existing reference screenshot kept for compatibility.
Binary file not shown.

After

Width:  |  Height:  |  Size: 651 KiB

File diff suppressed because it is too large Load Diff
+218
View File
@@ -0,0 +1,218 @@
{
"name": "backlog-swipe-triage",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "backlog-swipe-triage",
"version": "1.0.0",
"dependencies": {
"@github/copilot-sdk": "1.0.1"
}
},
"node_modules/@github/copilot": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.61.tgz",
"integrity": "sha512-E4f7YXTL2uUZY/ypnfsUruAeSgrHx3AGYEbm5N0DrpzPqoNAZqV6kHEWM4vu+W/nGvydIfPxmOTqaMEhM8r0Uw==",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"detect-libc": "^2.1.2"
},
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
"@github/copilot-darwin-arm64": "1.0.61",
"@github/copilot-darwin-x64": "1.0.61",
"@github/copilot-linux-arm64": "1.0.61",
"@github/copilot-linux-x64": "1.0.61",
"@github/copilot-linuxmusl-arm64": "1.0.61",
"@github/copilot-linuxmusl-x64": "1.0.61",
"@github/copilot-win32-arm64": "1.0.61",
"@github/copilot-win32-x64": "1.0.61"
}
},
"node_modules/@github/copilot-darwin-arm64": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.61.tgz",
"integrity": "sha512-10prvjHRXB0SD28NsIpzdNDgLquQYUwaH5Ev9KVdIWdBPAvlQsHmQ4JSCyD/UILc/nrrr02CKUgum+mZRKUKIg==",
"cpu": [
"arm64"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"darwin"
],
"bin": {
"copilot-darwin-arm64": "copilot"
}
},
"node_modules/@github/copilot-darwin-x64": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.61.tgz",
"integrity": "sha512-NXUjageJ3mxDfHtXGYu//XhJ+dhJFYObT4R3jeWgIHhd+4lX7FlC754nwlBP/ZuVhJ3ND22JK9sua9d2F3Cbwg==",
"cpu": [
"x64"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"darwin"
],
"bin": {
"copilot-darwin-x64": "copilot"
}
},
"node_modules/@github/copilot-linux-arm64": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.61.tgz",
"integrity": "sha512-dwB2+QSMr622JkePeK56M7YWXsTT/DQzKfpDq8Lk2kmGU052RZAarRmt8gcNm4anofN7pMSrqc3YHj1TM84MFw==",
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"linux"
],
"bin": {
"copilot-linux-arm64": "copilot"
}
},
"node_modules/@github/copilot-linux-x64": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.61.tgz",
"integrity": "sha512-q6n8R8oybvuCmmkP+43w809Wpud/wwRi/fFSZEYJagiNGmYJ00SDkrfJxHbZsAFMpaJC+oTswqzJHjRoZbO74w==",
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"linux"
],
"bin": {
"copilot-linux-x64": "copilot"
}
},
"node_modules/@github/copilot-linuxmusl-arm64": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.61.tgz",
"integrity": "sha512-yWo7JXnZS11eJpm68E1RWKMR47EwzPKj3V7GX0EMTd8Fw0T2Aurk9wt9p3c9w0v02nTO1DqJhi68KVWJPdVqvA==",
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"linux"
],
"bin": {
"copilot-linuxmusl-arm64": "copilot"
}
},
"node_modules/@github/copilot-linuxmusl-x64": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.61.tgz",
"integrity": "sha512-nHzx27Ac4B0fpD9CcmvyrGOBEMJ01CPRgVRP0yAl4wpU4cM2I6+9TPyfYThlWDqZqiUKGXC1ZRQ+B8cJREVGmA==",
"cpu": [
"x64"
],
"libc": [
"musl"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"linux"
],
"bin": {
"copilot-linuxmusl-x64": "copilot"
}
},
"node_modules/@github/copilot-sdk": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@github/copilot-sdk/-/copilot-sdk-1.0.1.tgz",
"integrity": "sha512-w6AaS0WqqTE/3iyUrZznvgCLQhsUF7ZmEVCneacuHCfOzlH0r6ww9WUmyA0zgqmXO75V0IYrkIcnFke/qJkkDg==",
"license": "MIT",
"dependencies": {
"@github/copilot": "^1.0.61",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@github/copilot-win32-arm64": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.61.tgz",
"integrity": "sha512-k6knzI+K5HlZeJDS/yeJAfoYD4xcURWfuqunpTCyk1pDbIFxmrLSqR/TDi7KNlpsf883n5WqpnB06K5kysdHHQ==",
"cpu": [
"arm64"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"win32"
],
"bin": {
"copilot-win32-arm64": "copilot.exe"
}
},
"node_modules/@github/copilot-win32-x64": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.61.tgz",
"integrity": "sha512-L6NZ6o73VZFHd7OoRaztV3Prh1PbW9HXqYsAx+XywNALQvE1u489WBUC1ggfYBW5MTBCf8mxSkYQdb3Am2omsw==",
"cpu": [
"x64"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"win32"
],
"bin": {
"copilot-win32-x64": "copilot.exe"
}
},
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
},
"node_modules/vscode-jsonrpc": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz",
"integrity": "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ==",
"license": "MIT",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/zod": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}
@@ -0,0 +1,10 @@
{
"name": "backlog-swipe-triage",
"version": "1.0.0",
"type": "module",
"main": "extension.mjs",
"description": "Swipe-driven backlog triage canvas for reviewing open issues and assigning implementation work.",
"dependencies": {
"@github/copilot-sdk": "1.0.1"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

+10
View File
@@ -0,0 +1,10 @@
[
{
"id": "coffilot",
"name": "Coffilot",
"description": "Java-focused Copilot canvas extension from jdubois.",
"installUrl": "https://github.com/jdubois/coffilot",
"sourceUrl": "https://github.com/jdubois/coffilot",
"imagePath": "extensions/external-assets/coffilot-preview.png"
}
]
Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@@ -0,0 +1,7 @@
# Release Notes Showcase
Interactive canvas for composing, reviewing, and exporting release notes content.
## Assets
- `assets/preview.png` — screenshot preview used by the extensions gallery.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

@@ -0,0 +1,7 @@
import { joinSession } from "@github/copilot-sdk/extension";
import { releaseNotesShowcaseCanvas } from "./releaseNotesShowcase.mjs";
await joinSession({
canvases: [releaseNotesShowcaseCanvas],
});
+286
View File
@@ -0,0 +1,286 @@
{
"name": "release-notes-showcase",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "release-notes-showcase",
"version": "1.0.0",
"dependencies": {
"@github/copilot-sdk": "1.0.1"
}
},
"node_modules/@github/copilot": {
"version": "1.0.63",
"resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.63.tgz",
"integrity": "sha512-e8DRYiWJQc4kepVXsXjC8vpDU2FXS/TfR+Z6p/KAojfcwIUZzKMAfCV5D1lD25hV4CryVH1Z9t7mHqChickj0Q==",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"detect-libc": "^2.1.2",
"os-theme": "^0.0.8"
},
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
"@github/copilot-darwin-arm64": "1.0.63",
"@github/copilot-darwin-x64": "1.0.63",
"@github/copilot-linux-arm64": "1.0.63",
"@github/copilot-linux-x64": "1.0.63",
"@github/copilot-linuxmusl-arm64": "1.0.63",
"@github/copilot-linuxmusl-x64": "1.0.63",
"@github/copilot-win32-arm64": "1.0.63",
"@github/copilot-win32-x64": "1.0.63"
}
},
"node_modules/@github/copilot-darwin-arm64": {
"version": "1.0.63",
"resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.63.tgz",
"integrity": "sha512-z6CMBxNDlKvT6bvOpqhu4M2bhb0daEbVwSe9SN9WfDUJbt7bpoL7OKKas428iyPSWHoL2WXwxSsy/FjIwSLV6w==",
"cpu": [
"arm64"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"darwin"
],
"bin": {
"copilot-darwin-arm64": "copilot"
}
},
"node_modules/@github/copilot-darwin-x64": {
"version": "1.0.63",
"resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.63.tgz",
"integrity": "sha512-YKd7cXZgAGxhudzrtWdWh2NS35p2G5bV22Gz3jhEyBTqmq45o4sD4OwO87+UpkvM+3nZpwsHaLd3a+ILYX6OXg==",
"cpu": [
"x64"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"darwin"
],
"bin": {
"copilot-darwin-x64": "copilot"
}
},
"node_modules/@github/copilot-linux-arm64": {
"version": "1.0.63",
"resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.63.tgz",
"integrity": "sha512-A3DOeEfmsJH9j1N+QLc7WXmESBskbezmhDyhyAJcHkw0ngRbKctuWQf/evUHFMh/kgwy1Lr/+9jXJm3NZqr0MA==",
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"linux"
],
"bin": {
"copilot-linux-arm64": "copilot"
}
},
"node_modules/@github/copilot-linux-x64": {
"version": "1.0.63",
"resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.63.tgz",
"integrity": "sha512-OMKfZJRoDaJOV7vuWX/nFPNdLa9/H+nhajdE83v4YT9mKLXr86aWrkXE3pPoDYsKWvgQFHg4APA6oZPao0Fyow==",
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"linux"
],
"bin": {
"copilot-linux-x64": "copilot"
}
},
"node_modules/@github/copilot-linuxmusl-arm64": {
"version": "1.0.63",
"resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.63.tgz",
"integrity": "sha512-jcIo6B3uHgcOluNfUHp+6atShKKrXYBPLaRyF6aDT699lwI83gW9KTDuEvDs5FDg8qWsWFfOl+al2dkWDYD3CQ==",
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"linux"
],
"bin": {
"copilot-linuxmusl-arm64": "copilot"
}
},
"node_modules/@github/copilot-linuxmusl-x64": {
"version": "1.0.63",
"resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.63.tgz",
"integrity": "sha512-BEdBbEF3fG7VqXzuaAY4JtmbdGSkpJFeb2ZQYaMpq7OP3aS7ssGe1cCX8ehZNegcMM/eb4GC6PXNXsvl3X/PAQ==",
"cpu": [
"x64"
],
"libc": [
"musl"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"linux"
],
"bin": {
"copilot-linuxmusl-x64": "copilot"
}
},
"node_modules/@github/copilot-sdk": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@github/copilot-sdk/-/copilot-sdk-1.0.1.tgz",
"integrity": "sha512-w6AaS0WqqTE/3iyUrZznvgCLQhsUF7ZmEVCneacuHCfOzlH0r6ww9WUmyA0zgqmXO75V0IYrkIcnFke/qJkkDg==",
"license": "MIT",
"dependencies": {
"@github/copilot": "^1.0.61",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@github/copilot-win32-arm64": {
"version": "1.0.63",
"resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.63.tgz",
"integrity": "sha512-7FqUwOmtoeBoOn4zkKQqRL+WGFwektVRSr5Po2FvPAbKxGXGyFXApZTmRLqVcHhMKDRzMb8KLST1LU1TMTY/wg==",
"cpu": [
"arm64"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"win32"
],
"bin": {
"copilot-win32-arm64": "copilot.exe"
}
},
"node_modules/@github/copilot-win32-x64": {
"version": "1.0.63",
"resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.63.tgz",
"integrity": "sha512-RC/6y9KHdw/YRCrCEksF2RzbeblfBUNE7bkYZxygaQGYThuv1GeZL2YD2jVqxC2LxKzsUmWGvwEMxerfR6pmeQ==",
"cpu": [
"x64"
],
"license": "SEE LICENSE IN LICENSE.md",
"optional": true,
"os": [
"win32"
],
"bin": {
"copilot-win32-x64": "copilot.exe"
}
},
"node_modules/@os-theme/darwin-arm64": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@os-theme/darwin-arm64/-/darwin-arm64-0.0.8.tgz",
"integrity": "sha512-gMsOs+8Ju396a5yyMWigkbA0dMTxD78U3HzG3mlpiAyn6hfd5dbyI4VGP+sfTB82KGgWLzIhWWTFX5UYY6iX0A==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@os-theme/linux-x64": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@os-theme/linux-x64/-/linux-x64-0.0.8.tgz",
"integrity": "sha512-zvjmBUiSQPjM1RbhpsfCDYMJxW4eLlGmkFPnpteC/03X2lz6CjiX2hfbN2EWLxXjNnIje3Jqaen8IsqEnWrRBg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@os-theme/win32-x64": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@os-theme/win32-x64/-/win32-x64-0.0.8.tgz",
"integrity": "sha512-N3yxKNbVl2IBa/ncDuq55QhwqwUjnYLJxDKMEmYeJbLIV950qZNojPw3scXA6PbfxPZfIiRa8iz1pzNg9XxP8w==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
},
"node_modules/os-theme": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/os-theme/-/os-theme-0.0.8.tgz",
"integrity": "sha512-u1q3bLSv5uMHNIiPItkfDrHXu6ZFs2juwqxWREFM/uVBa+7Kkhy2v49LmJev2JcinGwqiEccElB/XsH9gwasuA==",
"license": "MIT",
"optionalDependencies": {
"@os-theme/darwin-arm64": "0.0.8",
"@os-theme/linux-x64": "0.0.8",
"@os-theme/win32-x64": "0.0.8"
},
"peerDependencies": {
"typescript": "^5"
}
},
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/vscode-jsonrpc": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz",
"integrity": "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ==",
"license": "MIT",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/zod": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}
@@ -0,0 +1,10 @@
{
"name": "release-notes-showcase",
"version": "1.0.0",
"type": "module",
"main": "extension.mjs",
"description": "Release notes canvas for building polished release communications and exports.",
"dependencies": {
"@github/copilot-sdk": "1.0.1"
}
}
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

+11
View File
@@ -36,6 +36,17 @@ const initialItems = sortExtensions(extensionsData.items, 'title');
</div> </div>
</div> </div>
<div class="resource-list" id="resource-list" role="list" set:html={renderExtensionsHtml(initialItems)}></div> <div class="resource-list" id="resource-list" role="list" set:html={renderExtensionsHtml(initialItems)}></div>
<div id="extension-preview-modal" class="extension-preview-modal hidden" aria-hidden="true">
<div class="extension-preview-dialog" role="dialog" aria-modal="true" aria-labelledby="extension-preview-title">
<div class="extension-preview-header">
<h3 id="extension-preview-title" class="extension-preview-title">Extension preview</h3>
<button id="extension-preview-close" class="btn btn-secondary extension-preview-close" type="button" aria-label="Close preview">Close</button>
</div>
<div class="extension-preview-body">
<img id="extension-preview-image" class="extension-preview-image" src="" alt="" />
</div>
</div>
</div>
<ContributeCTA resourceType="extensions" /> <ContributeCTA resourceType="extensions" />
</div> </div>
</div> </div>
+5
View File
@@ -40,6 +40,11 @@ const base = import.meta.env.BASE_URL;
Community-contributed agents, instructions, and skills to enhance your Community-contributed agents, instructions, and skills to enhance your
GitHub Copilot experience GitHub Copilot experience
</p> </p>
<p>
<a href="https://github.com/github/awesome-copilot/" target="_blank" rel="noopener noreferrer">
View the Awesome Copilot repository on GitHub
</a>
</p>
</div> </div>
</section> </section>
+47 -16
View File
@@ -3,9 +3,15 @@ import { escapeHtml, getGitHubUrl, getLastUpdatedHtml } from "../utils";
export interface RenderableExtension { export interface RenderableExtension {
id: string; id: string;
name: string; name: string;
path: string; path?: string | null;
ref: string; ref?: string | null;
description?: string;
lastUpdated?: string | null; lastUpdated?: string | null;
imageUrl?: string | null;
assetPath?: string | null;
installUrl?: string | null;
sourceUrl?: string | null;
external?: boolean;
} }
export type ExtensionSortOption = "title" | "lastUpdated"; export type ExtensionSortOption = "title" | "lastUpdated";
@@ -36,14 +42,39 @@ export function renderExtensionsHtml(items: RenderableExtension[]): string {
} }
return items return items
.map( .map((item) => {
(item) => ` const installUrl =
item.installUrl ||
(item.path && item.ref
? `https://github.com/github/awesome-copilot/tree/${item.ref}/${item.path.replace(
/\\/g,
"/"
)}`
: "");
const sourceUrl =
item.sourceUrl || (item.path ? getGitHubUrl(item.path) : "");
return `
<article class="resource-item" role="listitem"> <article class="resource-item" role="listitem">
<div class="resource-preview"> <div class="resource-preview">
${
item.imageUrl
? `<button type="button" class="resource-thumbnail-btn" data-preview-url="${escapeHtml(item.imageUrl)}" data-preview-alt="${escapeHtml(item.name)} preview" aria-label="Open ${escapeHtml(item.name)} preview">
<img class="resource-thumbnail" src="${escapeHtml(item.imageUrl)}" alt="${escapeHtml(item.name)} preview" loading="lazy" />
</button>`
: `<div class="resource-thumbnail resource-thumbnail-placeholder" aria-hidden="true">Canvas</div>`
}
<div class="resource-info"> <div class="resource-info">
<div class="resource-title">${escapeHtml(item.name)}</div> <div class="resource-title">${escapeHtml(item.name)}</div>
<div class="resource-description">Canvas extension</div> <div class="resource-description">${escapeHtml(
item.description || "Canvas extension"
)}</div>
<div class="resource-meta"> <div class="resource-meta">
${
item.external
? '<span class="resource-tag">External</span>'
: ""
}
${getLastUpdatedHtml(item.lastUpdated)} ${getLastUpdatedHtml(item.lastUpdated)}
</div> </div>
</div> </div>
@@ -51,22 +82,22 @@ export function renderExtensionsHtml(items: RenderableExtension[]): string {
<div class="resource-actions"> <div class="resource-actions">
<button <button
class="btn btn-primary btn-small copy-install-url-btn" class="btn btn-primary btn-small copy-install-url-btn"
data-install-url="${escapeHtml( data-install-url="${escapeHtml(installUrl)}"
`https://github.com/github/awesome-copilot/tree/${item.ref}/${item.path.replace(
/\\/g,
"/"
)}`
)}"
title="Copy install URL" title="Copy install URL"
${installUrl ? "" : "disabled"}
> >
Install Install
</button> </button>
<a href="${getGitHubUrl( ${
item.path sourceUrl
)}" class="btn btn-secondary btn-small" target="_blank" rel="noopener noreferrer" title="View on GitHub">GitHub</a> ? `<a href="${escapeHtml(
sourceUrl
)}" class="btn btn-secondary btn-small" target="_blank" rel="noopener noreferrer" title="View source">Source</a>`
: ""
}
</div> </div>
</article> </article>
` `;
) })
.join(""); .join("");
} }
+63
View File
@@ -27,6 +27,30 @@ let allItems: Extension[] = [];
let currentSort: ExtensionSortOption = "title"; let currentSort: ExtensionSortOption = "title";
let actionHandlersReady = false; let actionHandlersReady = false;
function openPreviewModal(url: string, alt: string): void {
const modal = document.getElementById("extension-preview-modal");
const image = document.getElementById("extension-preview-image") as HTMLImageElement | null;
const title = document.getElementById("extension-preview-title");
if (!modal || !image || !title) return;
image.src = url;
image.alt = alt;
title.textContent = alt.replace(/ preview$/i, "");
modal.classList.remove("hidden");
modal.setAttribute("aria-hidden", "false");
document.body.style.overflow = "hidden";
}
function closePreviewModal(): void {
const modal = document.getElementById("extension-preview-modal");
if (!modal) return;
modal.classList.add("hidden");
modal.setAttribute("aria-hidden", "true");
document.body.style.overflow = "";
}
function applySortAndRender(): void { function applySortAndRender(): void {
const countEl = document.getElementById("results-count"); const countEl = document.getElementById("results-count");
const results = sortExtensions(allItems, currentSort); const results = sortExtensions(allItems, currentSort);
@@ -49,6 +73,20 @@ function setupActionHandlers(list: HTMLElement | null): void {
list.addEventListener("click", async (event) => { list.addEventListener("click", async (event) => {
const target = event.target as HTMLElement; const target = event.target as HTMLElement;
const thumbnailButton = target.closest(
".resource-thumbnail-btn"
) as HTMLButtonElement | null;
if (thumbnailButton) {
event.preventDefault();
event.stopPropagation();
openPreviewModal(
thumbnailButton.dataset.previewUrl || "",
thumbnailButton.dataset.previewAlt || "Extension preview"
);
return;
}
const installButton = target.closest( const installButton = target.closest(
".copy-install-url-btn" ".copy-install-url-btn"
) as HTMLButtonElement | null; ) as HTMLButtonElement | null;
@@ -57,6 +95,10 @@ function setupActionHandlers(list: HTMLElement | null): void {
event.stopPropagation(); event.stopPropagation();
const installUrl = installButton.dataset.installUrl || ""; const installUrl = installButton.dataset.installUrl || "";
if (!installUrl) {
showToast("No install URL available for this extension", "error");
return;
}
const success = await copyToClipboard(installUrl); const success = await copyToClipboard(installUrl);
showToast( showToast(
success ? "Install URL copied!" : "Failed to copy install URL", success ? "Install URL copied!" : "Failed to copy install URL",
@@ -64,6 +106,27 @@ function setupActionHandlers(list: HTMLElement | null): void {
); );
}); });
const modal = document.getElementById("extension-preview-modal");
const closeButton = document.getElementById("extension-preview-close");
if (modal) {
modal.addEventListener("click", (event) => {
if (event.target === modal) {
closePreviewModal();
}
});
}
if (closeButton) {
closeButton.addEventListener("click", closePreviewModal);
}
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
closePreviewModal();
}
});
actionHandlersReady = true; actionHandlersReady = true;
} }
+132 -1
View File
@@ -1863,7 +1863,9 @@ body:has(#main-content) {
.resource-preview { .resource-preview {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
display: block; display: flex;
align-items: flex-start;
gap: 16px;
width: 100%; width: 100%;
padding: 0; padding: 0;
margin: 0; margin: 0;
@@ -1875,6 +1877,55 @@ body:has(#main-content) {
cursor: pointer; cursor: pointer;
} }
.resource-thumbnail-btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
border: 0;
background: transparent;
cursor: pointer;
flex-shrink: 0;
}
.resource-thumbnail-btn:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 4px;
border-radius: var(--border-radius);
}
.resource-thumbnail {
width: clamp(120px, 24vw, 160px);
aspect-ratio: 16 / 10;
object-fit: cover;
border-radius: var(--border-radius);
border: 1px solid var(--color-glass-border);
background: var(--color-bg-tertiary);
flex-shrink: 0;
box-shadow: var(--shadow);
transition: transform var(--transition), box-shadow var(--transition);
}
.resource-thumbnail-btn:hover .resource-thumbnail,
.resource-thumbnail-btn:focus-visible .resource-thumbnail {
transform: translateY(-1px);
box-shadow: var(--shadow-lg);
}
.resource-thumbnail-placeholder {
display: flex;
align-items: center;
justify-content: center;
color: var(--color-text-muted);
font-size: 13px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
background:
linear-gradient(135deg, rgba(133, 52, 243, 0.18), rgba(254, 76, 37, 0.08)),
var(--color-bg-tertiary);
}
.resource-preview:focus-visible { .resource-preview:focus-visible {
outline: 2px solid var(--color-accent); outline: 2px solid var(--color-accent);
outline-offset: 4px; outline-offset: 4px;
@@ -1930,6 +1981,72 @@ body:has(#main-content) {
margin: 0px; margin: 0px;
} }
.extension-preview-modal {
position: fixed;
inset: 0;
z-index: 100000;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
background: rgba(5, 7, 15, 0.72);
backdrop-filter: blur(8px);
}
.extension-preview-modal.hidden {
display: none;
}
.extension-preview-dialog {
width: min(100%, 980px);
max-height: 90vh;
display: flex;
flex-direction: column;
gap: 12px;
background: var(--color-bg-secondary);
border: 1px solid var(--color-glass-border);
border-radius: var(--border-radius-lg);
box-shadow: var(--shadow-lg);
overflow: hidden;
}
.extension-preview-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 16px 18px 0;
}
.extension-preview-title {
margin: 0;
font-size: 1rem;
color: var(--color-text-emphasis);
}
.extension-preview-close {
border: 1px solid var(--color-glass-border);
background: var(--color-bg-tertiary);
}
.extension-preview-body {
padding: 0 18px 18px;
display: flex;
justify-content: center;
overflow: auto;
}
.extension-preview-image {
display: block;
width: 100%;
max-width: 920px;
max-height: 72vh;
object-fit: contain;
border-radius: var(--border-radius);
border: 1px solid var(--color-glass-border);
background: var(--color-bg-tertiary);
}
/* Last Updated */ /* Last Updated */
.last-updated { .last-updated {
font-size: 12px; font-size: 12px;
@@ -2081,6 +2198,20 @@ body:has(#main-content) {
align-items: stretch; align-items: stretch;
} }
.resource-preview {
flex-direction: column;
gap: 12px;
}
.resource-thumbnail-btn {
width: 100%;
}
.resource-thumbnail {
width: min(100%, 320px);
max-width: 100%;
}
.resource-actions { .resource-actions {
justify-content: flex-end; justify-content: flex-end;
} }