From 585a5c6023645e0698a8102a6fee2afa098cf86d Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 21 Aug 2026 02:14:49 +0000
Subject: [PATCH] chore: publish from main
---
.github/plugin/marketplace.json | 6 +
docs/README.plugins.md | 1 +
extensions/chat-cards/README.md | 154 ++
extensions/chat-cards/assets/canvas.html | 896 ++++++++++
extensions/chat-cards/assets/icon.png | Bin 0 -> 4443 bytes
extensions/chat-cards/assets/preview.png | Bin 0 -> 260855 bytes
extensions/chat-cards/cards-core.mjs | 1510 +++++++++++++++++
extensions/chat-cards/copilot-extension.json | 4 +
extensions/chat-cards/extension.mjs | 1223 +++++++++++++
extensions/chat-cards/package.json | 19 +
plugins/chat-cards/README.md | 22 +
.../extensions/chat-cards/README.md | 154 ++
.../extensions/chat-cards/assets/canvas.html | 896 ++++++++++
.../extensions/chat-cards/assets/icon.png | Bin 0 -> 4443 bytes
.../extensions/chat-cards/assets/preview.png | Bin 0 -> 260855 bytes
.../extensions/chat-cards/cards-core.mjs | 1510 +++++++++++++++++
.../chat-cards/copilot-extension.json | 4 +
.../extensions/chat-cards/extension.mjs | 1223 +++++++++++++
.../extensions/chat-cards/package.json | 19 +
plugins/chat-cards/plugin.json | 23 +
20 files changed, 7664 insertions(+)
create mode 100644 extensions/chat-cards/README.md
create mode 100644 extensions/chat-cards/assets/canvas.html
create mode 100644 extensions/chat-cards/assets/icon.png
create mode 100644 extensions/chat-cards/assets/preview.png
create mode 100644 extensions/chat-cards/cards-core.mjs
create mode 100644 extensions/chat-cards/copilot-extension.json
create mode 100644 extensions/chat-cards/extension.mjs
create mode 100644 extensions/chat-cards/package.json
create mode 100644 plugins/chat-cards/README.md
create mode 100644 plugins/chat-cards/com.github.copilot/extensions/chat-cards/README.md
create mode 100644 plugins/chat-cards/com.github.copilot/extensions/chat-cards/assets/canvas.html
create mode 100644 plugins/chat-cards/com.github.copilot/extensions/chat-cards/assets/icon.png
create mode 100644 plugins/chat-cards/com.github.copilot/extensions/chat-cards/assets/preview.png
create mode 100644 plugins/chat-cards/com.github.copilot/extensions/chat-cards/cards-core.mjs
create mode 100644 plugins/chat-cards/com.github.copilot/extensions/chat-cards/copilot-extension.json
create mode 100644 plugins/chat-cards/com.github.copilot/extensions/chat-cards/extension.mjs
create mode 100644 plugins/chat-cards/com.github.copilot/extensions/chat-cards/package.json
create mode 100644 plugins/chat-cards/plugin.json
diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json
index 839c4068..ea55d0f0 100644
--- a/.github/plugin/marketplace.json
+++ b/.github/plugin/marketplace.json
@@ -280,6 +280,12 @@
"sha": "0c2716ca4f28df375529c67b4504b41f7bd29a66"
}
},
+ {
+ "name": "chat-cards",
+ "source": "plugins/chat-cards",
+ "description": "Interactive card deck in a GHCP canvas: tab cards, tables, SVG charts, show/hide sections, numbered outlines, rendered markdown documents, video clips, and forms whose submissions come back to the conversation as prompts.",
+ "version": "0.1.0"
+ },
{
"name": "chrome-devtools-plugin",
"description": "Reliable automation, in-depth debugging, and performance analysis in Chrome using Chrome DevTools and Puppeteer.",
diff --git a/docs/README.plugins.md b/docs/README.plugins.md
index a4d6ad89..4a38f891 100644
--- a/docs/README.plugins.md
+++ b/docs/README.plugins.md
@@ -41,6 +41,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-plugins) for guidelines on how t
| [backlog-swipe-triage](../plugins/backlog-swipe-triage/README.md) | Quickly swipe through backlog issues to triage decisions like assign, needs-info, defer, close, or ignore. | 1 items | agent-assignment, backlog-triage, github-issues, issue-prioritization, swipe-interface, workflow-automation |
| [backrooms-canvas](../plugins/backrooms-canvas/README.md) | Wander an endless first-person backrooms in a Copilot canvas while agents work; their status ghost-writes on the walls. | 1 items | backrooms, copilot-canvas, interactive-canvas, first-person, procedural-generation, session-breaks |
| [cast-imaging](../plugins/cast-imaging/README.md) | A comprehensive collection of specialized agents for software analysis, impact assessment, structural quality advisories, and architectural review using CAST Imaging. | 0 items | cast-imaging, software-analysis, architecture, quality, impact-analysis, devops |
+| [chat-cards](../plugins/chat-cards/README.md) | Interactive card deck in a GHCP canvas: tab cards, tables, SVG charts, show/hide sections, numbered outlines, rendered markdown documents, video clips, and forms whose submissions come back to the conversation as prompts. | 1 items | interactive-cards, charts, forms, education, visual-explanations |
| [chromium-control-canvas](../plugins/chromium-control-canvas/README.md) | Opens a real Chromium window you can navigate and interact with from a Copilot canvas control panel and agent actions. | 1 items | browser-control, chromium-browser, interactive-canvas, playwright-automation, screenshots, ui-testing, web-navigation |
| [clojure-interactive-programming](../plugins/clojure-interactive-programming/README.md) | Tools for REPL-first Clojure workflows featuring Clojure instructions, the interactive programming chat mode and supporting guidance. | 0 items | clojure, repl, interactive-programming |
| [cms-development](../plugins/cms-development/README.md) | Skills for CMS development across themes, plugins, admin tooling, media workflows, markdown rendering, and static export pipelines. | 0 items | cms, content-management-system, wordpress, shopify, drupal, theme, plugin, media, static-site |
diff --git a/extensions/chat-cards/README.md b/extensions/chat-cards/README.md
new file mode 100644
index 00000000..5ee84d78
--- /dev/null
+++ b/extensions/chat-cards/README.md
@@ -0,0 +1,154 @@
+# Chat Cards
+
+Interactive card deck for GitHub Copilot canvas. Instead of walls of text, the
+agent explains things visually with a live deck of interactive cards: tab boxes,
+tables, SVG charts, forms, collapsible sections, numbered outlines, rendered
+markdown documents, and short video clips. Forms are two-way: submitting one
+sends the values back to the conversation as the agent's next prompt, so a card
+can gather context and steer the session as easily as it presents information.
+
+The extension is a port of an MCP server, which is similar; but renders the cards
+inline of the conversation, instead of rendering the HTML in a separate panel.
+
+
+
+## What is in the deck
+
+| Action | Card |
+| ------ | ---- |
+| `create_tab_card` | Tabbed views of one subject (markdown, text, HTML, or code per tab with copy buttons) |
+| `create_table_card` | HTML table from explicit rows or loosely delimited raw text (delimiter auto-detected, URL cells become links) |
+| `create_chart_card` | SVG bar, line, pie, or donut chart with legend and a collapsible data table |
+| `create_form_card` | Form whose submission becomes the next conversation prompt |
+| `create_reveal_card` | Collapsible show/hide sections with show-all/hide-all controls |
+| `create_list_card` | Nested sequential outline numbered 1., 1.1., 1.1.1. |
+| `create_markdown_card` | Render a markdown document as one card: H1 becomes the title, H2 sections fold into reveals |
+| `create_video_card` | HTML video player for a short clip (direct file URL, `data:video/*`, or `blob:`) |
+| `update_card` | Re-render an existing card in place |
+| `remove_card` / `clear_cards` | Take cards off the deck |
+| `list_cards` | See the deck (the user may have reordered or removed cards) |
+| `get_form_responses` | Read form submissions, newest first |
+
+Every card keeps the signature interactions of the MCP version: a "Copy card" button that
+copies the card as a standalone HTML document, a `>` toggle that shows the card's own
+HTML source, a collapse toggle, drag to reorder cards in the deck, tutor terms that show
+tooltips after a hover dwell, and model-defined right-click actions that send prompts back
+to the conversation (`{{selection}}` in an action prompt is replaced with the user's
+selected text). The deck has a light and a dark theme.
+
+## Example action inputs
+
+`create_table_card`:
+
+```json
+{
+ "title": "JavaScript array methods",
+ "headers": ["Method", "Purpose"],
+ "rows": [
+ ["map", "Transform each item"],
+ ["filter", "Keep matching items"],
+ ["reduce", "Fold items into one value"]
+ ]
+}
+```
+
+`create_form_card`:
+
+```json
+{
+ "title": "Study preferences",
+ "promptTemplate": "Teach {{topic}} with {{style}} examples.",
+ "fields": [
+ { "name": "topic", "label": "Topic", "required": true },
+ { "name": "style", "type": "select", "options": ["practical", "theoretical"] }
+ ]
+}
+```
+
+When the user submits the form, the filled template is handed to the agent as the next
+prompt. If the handoff fails, the card reveals the prompt text with a copy button, and the
+agent can always read submissions later with `get_form_responses`.
+
+## Installation
+
+Requires Node.js 18.17 or newer and a GitHub Copilot client that supports
+canvas extensions (*such as GitHub Copilot CLI*).
+
+Drop this folder at `~/.copilot/extensions/chat-cards/` for user scope, or
+in a repository at `.github/extensions/chat-cards/` for project scope. Then
+install dependencies from inside the copied folder:
+
+```bash
+# User scope
+cd ~/.copilot/extensions/chat-cards
+
+# Or project scope, from the repository root
+cd .github/extensions/chat-cards
+
+npm install
+```
+
+`npm install` pulls the extension's single dependency (`@github/copilot-sdk`).
+Then register the `extension/` folder with your Copilot client as a local
+extension, start a session, and ask the agent to open the Chat Cards canvas.
+
+Reload extensions in the GitHub Copilot app, then open the chat-cards canvas in
+a conversation.
+
+## How the port maps to the MCP server
+
+| MCP server | Canvas extension |
+| ---------- | ---------------- |
+| MCP tools (`create_tab_card`, ...) | Canvas actions with the same names and input shapes |
+| MCP Apps iframe / embedded HTML resource | Live canvas page served on `127.0.0.1` |
+| Form submit posts `ui/message` to the host | Form submit calls `session.send({ prompt })` |
+| Card HTML per tool result | Deck state pushed to the page over SSE |
+| `src/cards/*` + `src/util/*` (TypeScript) | `cards-core.mjs` (dependency-free port, testable without the SDK) |
+
+Deliberate differences:
+
+- **Stricter HTML sanitizing.** Tab and reveal content can be markdown, text, code, or
+ HTML, like the MCP server, but where the server sanitizes HTML with a parser dependency,
+ the extension rebuilds it against a strict tag and attribute allowlist: unknown or
+ malformed tags render as visible literal text, attributes are re-emitted from scratch,
+ and closing tags are balanced. A tab or section with no usable content is rejected with
+ an error naming it, instead of rendering an empty panel.
+- **No file, archive, or web-fetch actions.** `read_local_file`, `unpack_archive`,
+ `fetch_reference`, `mirror_web_form`, and `submit_web_form` stay MCP-only: a Copilot
+ agent already reads files and pages natively, so it passes content inline (for example
+ `create_markdown_card` takes the markdown itself rather than a path).
+- **No multi-part splitting.** MCP hosts cap tool-result sizes, so the server splits large
+ documents into parts. The canvas renders directly and needs no parts; the deck instead
+ keeps at most 60 cards, dropping the oldest.
+
+## Folder layout
+
+```text
+extension/
+ extension.mjs Canvas/session wiring, actions, local HTTP + SSE server
+ cards-core.mjs Card builders and rendering (no SDK import; unit-testable)
+ copilot-extension.json Plugin manifest for the awesome-copilot submission
+ package.json Extension package manifest
+ assets/
+ canvas.html The canvas page (theme, card runtime, deck UI)
+ preview.png Screenshot used as the extension logo/preview
+```
+
+## Security notes
+
+- The card server binds to `127.0.0.1` on an ephemeral port; every request must carry the
+ per-canvas token, and request bodies are size-capped.
+- All model- and user-supplied text is HTML-escaped before it reaches card markup, and the
+ markdown renderer emits only escaped text nodes.
+- The canvas page loads no external scripts, stylesheets, or fonts.
+- Prompts sent from the canvas (form submissions and context actions) are length-capped.
+
+## Development
+
+The rendering core has no SDK dependency, so it can be exercised directly:
+
+```bash
+node -e "import('./cards-core.mjs').then(m => console.log(m.buildTableCard({ title: 'Demo', rows: [['a', 'b']] }).summary))"
+```
+
+To run the extension itself, follow [Installation](#installation) above.
diff --git a/extensions/chat-cards/assets/canvas.html b/extensions/chat-cards/assets/canvas.html
new file mode 100644
index 00000000..6e3fd60c
--- /dev/null
+++ b/extensions/chat-cards/assets/canvas.html
@@ -0,0 +1,896 @@
+
+
+
+
+
+Chat Cards
+
+
+
+
+
+ Chat Cards
+
+
+
+
+
+
+
+
+
No cards yet
+
Ask your agent for a tab, table, chart, form, show/hide, list, document, or video card and it will appear here.