canvas-extension: new chat cards extension - #2698
Conversation
🔒 PR Risk Scan ResultsScanned 9 changed file(s).
Skipped non-text or missing files
|
|
🔴 Contributor Reputation Check: HIGH risk
Maintainers: please review this contributor before merging. |
There was a problem hiding this comment.
Pull request overview
Adds the Chat Cards canvas extension and packages it for the Awesome Copilot marketplace.
Changes:
- Implements interactive cards, forms, charts, and deck management.
- Adds the canvas UI, local HTTP/SSE transport, and visual assets.
- Registers and documents the extension plugin.
Reviewed changes
Copilot reviewed 10 out of 12 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
plugins/chat-cards/README.md |
Documents plugin installation. |
plugins/chat-cards/plugin.json |
Defines plugin metadata. |
extensions/chat-cards/README.md |
Documents features and usage. |
extensions/chat-cards/package.json |
Declares the extension package. |
extensions/chat-cards/extension.mjs |
Implements actions, state, and transport. |
extensions/chat-cards/copilot-extension.json |
Provides extension metadata. |
extensions/chat-cards/cards-core.mjs |
Builds and sanitizes card content. |
extensions/chat-cards/assets/canvas.html |
Implements the interactive canvas UI. |
extensions/chat-cards/assets/icon.png |
Provides the extension icon. |
extensions/chat-cards/assets/preview.png |
Provides the marketplace preview. |
docs/README.plugins.md |
Adds the plugin to documentation. |
.github/plugin/marketplace.json |
Registers the marketplace entry. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| return `<label class="mcc-choice" for="${choiceId}"> | ||
| <input type="${type}" id="${choiceId}" name="${name}" value="${escapeHtml(option.value ?? option.label)}"${checked}> | ||
| ${escapeHtml(option.label)}</label>`; |
| function seriesScale(series) { | ||
| const values = series.flatMap((s) => s.values).filter((value) => Number.isFinite(value)); | ||
| return niceScale(Math.max(...values, 0), 6, values.every((value) => Number.isInteger(value))); | ||
| } |
| cardId: { type: "string", description: "The id returned when the card was created" }, | ||
| kind: { type: "string", enum: Object.keys(CARD_BUILDERS) }, | ||
| }, | ||
| required: ["cardId", "kind"], | ||
| additionalProperties: true, |
| document.addEventListener("mouseover", function (event) { | ||
| var term = event.target.closest(".mcc-term"); | ||
| if (!term) return; |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 12 changed files in this pull request and generated no new comments.
Suppressed comments (6)
extensions/chat-cards/cards-core.mjs:1219
- Chart cards expose kinds such as
chart-bar, butupdate_cardonly accepts builder keys (chart,tabs, etc.) and tells callers to pass the card's returned kind. Consequently, a chart kind returned by create/list cannot be passed back to update. Keep the stored/public kind aligned with thechartbuilder key; the subtype already remains in the replacement spec'stype.
kind: `chart-${type}`,
extensions/chat-cards/cards-core.mjs:1268
requiredis calculated but never emitted for checkbox or radio inputs. Thereforeform.checkValidity()accepts a required choice group with nothing selected, despite the required marker shown to the user. Apply nativerequiredsemantics for radio groups and explicitly validate at least one selected value for multi-checkbox groups.
<input type="${type}" id="${choiceId}" name="${name}" value="${escapeHtml(option.value ?? option.label)}"${checked}>
plugins/chat-cards/README.md:14
- This fence uses two backticks, so the installation command renders as literal delimiter text instead of a code block. Use a valid Markdown code block.
``bash
copilot plugin install chat-cards@awesome-copilot
``
extensions/chat-cards/cards-core.mjs:116
- Caller-supplied HTML can retain extension-reserved classes, allowing sanitized content to trigger privileged delegated handlers. For example, an allowed
<a class="mcc-remove-card" href="https://example.com">survives sanitization, and clicking it removes the enclosing card. Reject reservedmcc-classes when rebuilding untrusted HTML.
"*": { class: (v) => SAFE_CLASS_PATTERN.test(v), title: () => true },
extensions/chat-cards/extension.mjs:217
- Bar/line series values allow negatives, but both renderers use a zero-only scale: negative bars are clamped to zero and negative line points are placed below the plot. This silently misrepresents valid schema input. Either reject negative values in both the action schema and core builder (including updates), or implement a signed min/max axis.
values: { type: "array", items: { type: "number" } },
extensions/chat-cards/cards-core.mjs:313
- Tutor definitions are exposed only through
mouseover/mouseout, while this generated span is not focusable and has no accessible description. Keyboard and screen-reader users therefore cannot access an advertised card feature. Make terms keyboard-focusable and mirror tooltip behavior on focus/blur, or associate the tip through accessible descriptive markup.
`<span class="mcc-term" data-tip="${escapeHtml(term.tip)}">${match[0]}</span>`;
Pull Request Checklist
npm startand verified thatREADME.mdis up to date.mainbranch for this pull request.Description
Interactive HTML card deck for GitHub Copilot canvas.
Prompt
Results
Type of Contribution
By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.