chore: publish from staged
@@ -97,6 +97,10 @@ function formatDisplayName(value) {
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
function normalizeText(value, fallback = "") {
|
||||
return typeof value === "string" ? value.trim() : fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the latest git-modified date for any file under a directory.
|
||||
*/
|
||||
@@ -670,6 +674,76 @@ function generatePluginsData(gitDates) {
|
||||
/**
|
||||
* 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) {
|
||||
const extensions = [];
|
||||
|
||||
@@ -679,19 +753,87 @@ function generateExtensionsData(gitDates, commitSha) {
|
||||
|
||||
const extensionDirs = fs
|
||||
.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) {
|
||||
const relPath = `extensions/${dir.name}`;
|
||||
const assetInfo = getExtensionAssetInfo(
|
||||
path.join(EXTENSIONS_DIR, dir.name),
|
||||
relPath,
|
||||
commitSha
|
||||
);
|
||||
|
||||
extensions.push({
|
||||
id: dir.name,
|
||||
name: formatDisplayName(dir.name),
|
||||
description: "Canvas extension",
|
||||
path: relPath,
|
||||
ref: commitSha,
|
||||
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) =>
|
||||
a.name.localeCompare(b.name)
|
||||
);
|
||||
|
||||
|
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.
|
||||
|
After Width: | Height: | Size: 651 KiB |
@@ -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"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 305 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
@@ -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"
|
||||
}
|
||||
]
|
||||
|
After Width: | Height: | Size: 60 KiB |
|
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.
|
||||
|
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],
|
||||
});
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 57 KiB |
@@ -36,6 +36,17 @@ const initialItems = sortExtensions(extensionsData.items, 'title');
|
||||
</div>
|
||||
</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" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -40,6 +40,11 @@ const base = import.meta.env.BASE_URL;
|
||||
Community-contributed agents, instructions, and skills to enhance your
|
||||
GitHub Copilot experience
|
||||
</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>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -3,9 +3,15 @@ import { escapeHtml, getGitHubUrl, getLastUpdatedHtml } from "../utils";
|
||||
export interface RenderableExtension {
|
||||
id: string;
|
||||
name: string;
|
||||
path: string;
|
||||
ref: string;
|
||||
path?: string | null;
|
||||
ref?: string | null;
|
||||
description?: string;
|
||||
lastUpdated?: string | null;
|
||||
imageUrl?: string | null;
|
||||
assetPath?: string | null;
|
||||
installUrl?: string | null;
|
||||
sourceUrl?: string | null;
|
||||
external?: boolean;
|
||||
}
|
||||
|
||||
export type ExtensionSortOption = "title" | "lastUpdated";
|
||||
@@ -36,37 +42,62 @@ export function renderExtensionsHtml(items: RenderableExtension[]): string {
|
||||
}
|
||||
|
||||
return items
|
||||
.map(
|
||||
(item) => `
|
||||
.map((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">
|
||||
<div class="resource-preview">
|
||||
<div class="resource-info">
|
||||
<div class="resource-title">${escapeHtml(item.name)}</div>
|
||||
<div class="resource-description">Canvas extension</div>
|
||||
<div class="resource-meta">
|
||||
${getLastUpdatedHtml(item.lastUpdated)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${
|
||||
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-title">${escapeHtml(item.name)}</div>
|
||||
<div class="resource-description">${escapeHtml(
|
||||
item.description || "Canvas extension"
|
||||
)}</div>
|
||||
<div class="resource-meta">
|
||||
${
|
||||
item.external
|
||||
? '<span class="resource-tag">External</span>'
|
||||
: ""
|
||||
}
|
||||
${getLastUpdatedHtml(item.lastUpdated)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-actions">
|
||||
<button
|
||||
class="btn btn-primary btn-small copy-install-url-btn"
|
||||
data-install-url="${escapeHtml(
|
||||
`https://github.com/github/awesome-copilot/tree/${item.ref}/${item.path.replace(
|
||||
/\\/g,
|
||||
"/"
|
||||
)}`
|
||||
)}"
|
||||
data-install-url="${escapeHtml(installUrl)}"
|
||||
title="Copy install URL"
|
||||
${installUrl ? "" : "disabled"}
|
||||
>
|
||||
Install
|
||||
</button>
|
||||
<a href="${getGitHubUrl(
|
||||
item.path
|
||||
)}" class="btn btn-secondary btn-small" target="_blank" rel="noopener noreferrer" title="View on GitHub">GitHub</a>
|
||||
${
|
||||
sourceUrl
|
||||
? `<a href="${escapeHtml(
|
||||
sourceUrl
|
||||
)}" class="btn btn-secondary btn-small" target="_blank" rel="noopener noreferrer" title="View source">Source</a>`
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
</article>
|
||||
`
|
||||
)
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
|
||||
@@ -27,6 +27,30 @@ let allItems: Extension[] = [];
|
||||
let currentSort: ExtensionSortOption = "title";
|
||||
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 {
|
||||
const countEl = document.getElementById("results-count");
|
||||
const results = sortExtensions(allItems, currentSort);
|
||||
@@ -49,6 +73,20 @@ function setupActionHandlers(list: HTMLElement | null): void {
|
||||
|
||||
list.addEventListener("click", async (event) => {
|
||||
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(
|
||||
".copy-install-url-btn"
|
||||
) as HTMLButtonElement | null;
|
||||
@@ -57,6 +95,10 @@ function setupActionHandlers(list: HTMLElement | null): void {
|
||||
|
||||
event.stopPropagation();
|
||||
const installUrl = installButton.dataset.installUrl || "";
|
||||
if (!installUrl) {
|
||||
showToast("No install URL available for this extension", "error");
|
||||
return;
|
||||
}
|
||||
const success = await copyToClipboard(installUrl);
|
||||
showToast(
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1863,7 +1863,9 @@ body:has(#main-content) {
|
||||
.resource-preview {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: block;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
@@ -1875,6 +1877,55 @@ body:has(#main-content) {
|
||||
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 {
|
||||
outline: 2px solid var(--color-accent);
|
||||
outline-offset: 4px;
|
||||
@@ -1930,6 +1981,72 @@ body:has(#main-content) {
|
||||
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 {
|
||||
font-size: 12px;
|
||||
@@ -2081,6 +2198,20 @@ body:has(#main-content) {
|
||||
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 {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||