diff --git a/.github/extensions/external-plugins-board/extension.mjs b/.github/extensions/external-plugins-board/extension.mjs deleted file mode 100644 index 1896ec03b9..0000000000 --- a/.github/extensions/external-plugins-board/extension.mjs +++ /dev/null @@ -1,580 +0,0 @@ -import { createServer } from "node:http"; -import { execFileSync, spawnSync, execSync } from "node:child_process"; -import { dirname } from "node:path"; -import { createRequire } from "node:module"; -import { joinSession, createCanvas } from "@github/copilot-sdk/extension"; - -const require = createRequire(import.meta.url); -const { marked } = require("marked"); - -const servers = new Map(); -let workspacePath = null; -let lastError = null; - -// Fetch live issues from GitHub REST API instead of gh CLI subprocess -async function fetchLiveIssues(cwd) { - try { - // Use GitHub REST API to fetch issues - // This avoids the subprocess execution restriction - const owner = "github"; - const repo = "awesome-copilot"; - const label = "external-plugin"; - - // Get authentication token from environment or use public access - const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN; - - const headers = { - "Accept": "application/vnd.github.v3+json" - }; - - if (token) { - headers["Authorization"] = `token ${token}`; - } - - // Fetch issues with external-plugin label - const response = await fetch( - `https://api.github.com/repos/${owner}/${repo}/issues?labels=${label}&state=open&per_page=100`, - { headers } - ); - - if (!response.ok) { - const error = await response.text(); - throw new Error(`GitHub API error ${response.status}: ${error.substring(0, 200)}`); - } - - const issues = await response.json(); - - // Filter to only external-plugin labeled issues and map to our format - return issues - .filter(issue => issue.labels && issue.labels.some(l => l.name === label)) - .map(issue => ({ - number: issue.number, - title: issue.title, - body: issue.body || "", - bodyHtml: marked.parse(issue.body || ""), - labels: (issue.labels || []).map(l => ({ name: l.name })), - pr_url: issue.body?.match(/\[Generated PR\]\(([^)]+)\)/)?.[1], - created_at: issue.created_at, - updated_at: issue.updated_at - })); - } catch (err) { - lastError = err.message; - throw err; - } -} - -function renderHtml() { - return ` - - - - External Plugins Board - - - -

External Plugins Board

-
Loading issues...
- - - - - -`; -} - -async function startServer(instanceId, cwd) { - const server = createServer(async (req, res) => { - res.setHeader("Access-Control-Allow-Origin", "*"); - - if (req.url === "/" && req.method === "GET") { - res.setHeader("Content-Type", "text/html; charset=utf-8"); - res.end(renderHtml()); - } else if (req.url === "/api/issues" && req.method === "GET") { - try { - const issues = await fetchLiveIssues(cwd); - res.setHeader("Content-Type", "application/json"); - res.end(JSON.stringify(issues || [])); - } catch (err) { - res.writeHead(500, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ error: err.message })); - } - } else if (req.url === "/api/issues/update" && req.method === "POST") { - let body = ""; - req.on("data", chunk => { body += chunk; }); - req.on("end", async () => { - try { - const { issueNumber, newState } = JSON.parse(body); - const labels = ['requires-submitter-fixes', 'ready-for-review', 'approved', 'rejected']; - for (const label of labels.filter(l => l !== newState)) { - try { - spawnSync("gh", [ - "issue", "edit", issueNumber.toString(), - "--remove-label", label - ], { cwd, shell: true }); - } catch (e) {} - } - spawnSync("gh", [ - "issue", "edit", issueNumber.toString(), - "--add-label", newState - ], { cwd, shell: true }); - res.setHeader("Content-Type", "application/json"); - res.end(JSON.stringify({ ok: true })); - } catch (err) { - res.writeHead(500, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ error: err.message })); - } - }); - } else { - res.writeHead(404); - res.end("Not found"); - } - }); - - await new Promise(resolve => server.listen(0, "127.0.0.1", resolve)); - const port = server.address().port; - return { server, url: `http://127.0.0.1:${port}/` }; -} - -const session = await joinSession({ - canvases: [ - createCanvas({ - id: "external-plugins-board", - displayName: "External Plugins Board", - description: "Kanban board for managing external plugin submission issues", - open: async (ctx) => { - let entry = servers.get(ctx.instanceId); - if (!entry) { - if (!workspacePath) { - const filePath = import.meta.url.replace(/^file:\/\//, '').replace(/\//g, '\\'); - workspacePath = dirname(dirname(dirname(filePath))); - } - entry = await startServer(ctx.instanceId, workspacePath); - servers.set(ctx.instanceId, entry); - } - return { title: "External Plugins Board", url: entry.url }; - }, - onClose: async (ctx) => { - const entry = servers.get(ctx.instanceId); - if (entry) { - servers.delete(ctx.instanceId); - await new Promise(resolve => entry.server.close(() => resolve())); - } - }, - }), - ], -}); diff --git a/.github/extensions/external-plugins-board/package-lock.json b/.github/extensions/external-plugins-board/package-lock.json deleted file mode 100644 index 749f14a696..0000000000 --- a/.github/extensions/external-plugins-board/package-lock.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "external-plugins-board", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "external-plugins-board", - "version": "1.0.0", - "dependencies": { - "marked": "^15.0.0" - } - }, - "node_modules/marked": { - "version": "15.0.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", - "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 18" - } - } - } -} diff --git a/.github/extensions/external-plugins-board/package.json b/.github/extensions/external-plugins-board/package.json deleted file mode 100644 index 495cf54f08..0000000000 --- a/.github/extensions/external-plugins-board/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "external-plugins-board", - "version": "1.0.0", - "type": "module", - "dependencies": { - "marked": "^15.0.0" - } -}