create-canvas
Extension Canvas Authoring
Use this skill when creating or debugging an extension canvas that integrates with the runtime canvas model.
The host app no longer participates in extension canvas registration. Extensions declare canvases directly to the runtime via the Copilot SDK on joinSession; the runtime routes provider callbacks (canvas.open, canvas.action.invoke, etc.) straight to the declaring connection; the host app just renders whatever URL the provider returns.
Authoring workflow (do this in order)
-
Decide the scope. Project (
.github/extensions/<name>/) is committed to the repo and shared with the team. User ($COPILOT_HOME/extensions/<name>/) is local to the current user. Session ($COPILOT_HOME/session-state/<sessionId>/extensions/<name>/) is loaded only for the current session — ideal for a throwaway canvas for one conversation. Unless the request makes it obvious, ask before creating files — the choice changes who sees the extension, whether it's committed, and the resultingextensionId. -
Scaffold via tool, don't hand-write the skeleton.
extensions_manage({ operation: "scaffold", kind: "canvas", name: "<name>", location: "project" | "user" | "session" })The canvas scaffold produces an
extension.mjswithjoinSession({ canvases: [createCanvas({...})] }), a working loopback HTTP server per instance, an example action, andonClosecleanup. Edit from there. -
Edit the file. Implement your
open,actions[], optionalonClose, and (if needed) tools/hooks alongside. -
Reload. Call
extensions_reload. Stale canvas instances flip tostale, then back toreadyonce the provider reconnects.