Add Brainmax Canvas Extension - #2361
Conversation
There was a problem hiding this comment.
Pull request overview
Adds BrainMax Canvas, an interactive quiz and competency-report extension for the GitHub Copilot marketplace.
Changes:
- Adds the Canvas server, state machine, and SDK actions.
- Adds an accessible, responsive browser interface.
- Registers the extension in the marketplace.
Show a summary per file
| File | Description |
|---|---|
extensions/brainmax-canvas/README.md |
Documents installation and usage. |
extensions/brainmax-canvas/public/styles.css |
Defines themes and responsive styling. |
extensions/brainmax-canvas/public/index.html |
Provides the Canvas UI structure. |
extensions/brainmax-canvas/public/app.js |
Renders state and handles interactions. |
extensions/brainmax-canvas/package.json |
Defines package metadata and scripts. |
extensions/brainmax-canvas/lib/state.mjs |
Manages quiz instance state. |
extensions/brainmax-canvas/lib/http-server.test.mjs |
Tests request-body handling. |
extensions/brainmax-canvas/lib/http-server.mjs |
Serves UI, SSE, and event endpoints. |
extensions/brainmax-canvas/extension.mjs |
Implements Canvas actions and lifecycle. |
extensions/brainmax-canvas/.github/plugin/plugin.json |
Defines extension marketplace metadata. |
.github/plugin/marketplace.json |
Registers BrainMax Canvas. |
Review details
- Files reviewed: 11/12 changed files
- Comments generated: 4
- Review effort level: Medium
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b95f746-9a23-4513-80eb-9d641986aab2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b95f746-9a23-4513-80eb-9d641986aab2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b95f746-9a23-4513-80eb-9d641986aab2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22323915-a9c0-42b7-bf74-36ce4069a32e
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22323915-a9c0-42b7-bf74-36ce4069a32e
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22323915-a9c0-42b7-bf74-36ce4069a32e
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22323915-a9c0-42b7-bf74-36ce4069a32e
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22323915-a9c0-42b7-bf74-36ce4069a32e
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (3)
extensions/brainmax-canvas/extension.mjs:112
- A successful
session.senddoes not guarantee that the agent will invokerecord_score. If that follow-up action is omitted,answerStatusnever leavessubmitting, so the textarea remains disabled and the answer cannot be retried. Detect completion/timeout of the agent turn and restore an actionable error state when no score arrives.
state.answerStatus = "submitting";
extensions/brainmax-canvas/extension.mjs:160
- This request has the same permanent-pending path: if the agent responds without
show_report, the button remains disabled forever because onlyshow_reportor a rejectedsession.sendresets the status. Add a session-idle/timeout check that setsreportRequestStatustoerrorwhen no report action arrives.
state.reportRequestStatus = "submitting";
extensions/brainmax-canvas/public/app.js:456
- Web storage access can throw a
SecurityErrorwhen storage is disabled or restricted. Because this read runs before theEventSourceis created, that exception prevents the entire Canvas from connecting; guard both the read and write so theme persistence remains optional.
const storedTheme = localStorage.getItem(THEME_STORAGE_KEY);
- Files reviewed: 11/12 changed files
- Comments generated: 2
- Review effort level: Medium
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22323915-a9c0-42b7-bf74-36ce4069a32e
| handler: async (ctx) => { | ||
| const state = getState(ctx.instanceId); | ||
| const { index, score, feedback } = ctx.input || {}; | ||
| if (!state.quiz || !state.question || index !== state.question.index || state.answerStatus === "scored") { |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22323915-a9c0-42b7-bf74-36ce4069a32e
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22323915-a9c0-42b7-bf74-36ce4069a32e
aaronpowell
left a comment
There was a problem hiding this comment.
Is the BrainMax skill needed to be installed to use this canvas? If so, would it make sense to combine this with the BrainMax repo and have the plugin ship this canvas as part of it using the "external plugins" model?
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
extensions/brainmax-canvas/extension.mjs:265
- This action bypasses the state guard used by
choose-another-domain(lines 150–152). If the agent invokesshow_domainsduring an active quiz, it silently clears the current question and all quiz progress. Reject the transition unless the current view issummaryorreportbefore resetting state.
state.view = "domains";
state.question = null;
state.lastScore = null;
state.quiz = null;
- Files reviewed: 11/12 changed files
- Comments generated: 0 new
- Review effort level: Medium
@aaronpowell Yes, the canvas is dependent on the skills and I agree with your suggested approach to package as an external plugin. Submission created #2468 |
|
Closing in favour of #2468 |
Pull Request Checklist
npm startand verified thatREADME.mdis up to date.mainbranch for this pull request.Description
BrainMax Canvas is the interactive dashboard for codebase-grounded concept-mastery quizzes. It presents detected knowledge domains, accepts freeform answers, shows rubric scores, and compiles completed domains into a competency report.
The Canvas is an optional visual layer. Question generation and scoring stay with the BrainMaxxing Agent Skills, and the skills continue to work in clients without Canvas support.
Type of Contribution
Additional Notes
By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.