Skip to content

Add Kanvasban canvas extension plugin - #5389

Open
johngrant wants to merge 1 commit into
github:mainfrom
johngrant:johngrant-add-kanvasban-canvas-plugin
Open

johngrant wants to merge 1 commit into
github:mainfrom
johngrant:johngrant-add-kanvasban-canvas-plugin

Conversation

@johngrant

Copy link
Copy Markdown

Pull Request Checklist

  • I have read and followed the CONTRIBUTING.md guidelines.
  • I have read and followed the Guidance for submissions involving paid services.
  • My contribution adds a new instruction, prompt, agent, skill, workflow, or canvas extension file in the correct directory.
  • The file follows the required naming convention.
  • The content is clearly structured and follows the example format.
  • I have tested my instructions, prompt, agent, skill, workflow, or canvas extension with GitHub Copilot.
  • I have run npm start and verified that README.md is up to date.
  • I am targeting the main branch for this pull request.

Description

Add Kanvasban, a local Copilot canvas where humans and agents can manage projects, features, and linked or standalone user stories.

Unlike the existing accessibility and issue-triage boards, Kanvasban provides a personal, multi-project backlog without requiring GitHub issues or an external project-management service.

  • Add reusable implementation, documentation, tests, and a preview PNG under extensions/kanvasban/.
  • Register a standalone installable plugin under plugins/kanvasban/, using the repository's source-composition namespace and assets/preview.png logo convention.
  • Support live updates between manual board changes and agent actions, with workflow columns, priorities, comments, history, archiving, filtering, and optional feature grouping.
  • Initialize a missing store with exactly one Hello world project, one feature, and one linked user story. Preserve existing stores and report invalid or unreadable stores explicitly.
  • Regenerate plugin documentation and marketplace metadata.

Type of Contribution

  • New instruction file.
  • New prompt file.
  • New agent file.
  • New plugin.
  • New skill file.
  • New agentic workflow.
  • New canvas extension.
  • Update to existing instruction, prompt, agent, plugin, skill, workflow, or canvas extension.
  • Other (please specify):

Additional Notes

Validation

  • node --test extensions/kanvasban/backlog.test.mjs - passed, 30 tests.
  • npm run plugin:validate - passed.
  • npm run build - passed.
  • npm run website:data - passed.
  • npm start - passed; generated tracked files remained unchanged.
  • git diff --cached --check - passed before committing.
  • bash eng/fix-line-endings.sh - previously attempted; its GNU-style sed -i invocation is incompatible with macOS sed. Contribution files were separately checked for CRLF; none were found.

Copilot host test

Loaded the contribution source as a user-level canvas extension in Copilot and opened it successfully. Verified that agent actions could read the existing projects. Then temporarily moved personal data aside and verified that first access created only the Hello world project, feature, and linked user story. A subsequent read returned the same project ID rather than reseeding. The author also manually exercised the canvas and captured screenshots.

Restored the original user extension and personal data after testing; original data and backup checksums matched before and after the test.

Data and optional support link

No personal board stores, backups, or runtime test data are included. The preview shows synthetic starter content. Contribution files were scanned for secrets and personal board names/IDs.

Board data is local to the user's Copilot home and shared across workspaces using that home; it is not cloud synchronization. The host supplies the canvas SDK.

The existing optional cup-and-heart tip button is retained and links to the author's Ko-fi page, https://ko-fi.com/johnny888. Its icon embeds the original PNG within inline SVG, so rendering the canvas does not contact Ko-fi or load a remote widget script. Opening the support link is optional and is not required for any canvas feature. This author-affiliated link is disclosed for review under the paid-services guidance.


By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI max review requested due to automatic review settings October 23, 2026 19:08
@johngrant
johngrant requested review from a team as code owners October 23, 2026 19:08
@github-actions github-actions Bot added canvas-extension PR touches canvas extensions new-submission PR adds at least one new contribution plugin PR touches plugins labels Oct 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔒 PR Risk Scan Results

Scanned 12 changed file(s).

Severity Count
🔴 High 0
🟠 Medium 0
ℹ️ Info 0

✅ No matching risk patterns were detected in changed files.

Skipped non-text or missing files
  • extensions/kanvasban/assets/preview.png

This is an automated soft-gate report. Findings indicate review targets and do not block merge by themselves.

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

🚦 Submission status: 👀 Ready for review

Risk tier: merge-risk:medium — New or substantially changed resource without privileged execution
Required to merge: passing submission-gate checks plus 1 approval from reviewers with write access.

Why this tier
  • Adds 12 file(s), e.g. extensions/kanvasban/.gitignore
  • Changes 3582 lines (low-risk limit is 40)

Automated checks

Check Status Details
Line endings ✅ Passed Passed · logs
Spelling ✅ Passed Passed · logs
Generated README consistency ✅ Passed Passed · logs
Plugin and extension validation ✅ Passed Passed · logs
Canvas extension validation ✅ Passed Passed · logs
Plugin structure ✅ Passed Passed · logs
Risk scan ✅ Passed Passed · logs
Contributor reputation ✅ Passed Passed · logs
Duplicate resource scan ✅ Passed Passed · logs
PR quality signal ⏭️ Skipped Skipped by its workflow · logs
Canvas/plugin smoke test ✅ Passed Passed · logs

Review

  • Approvals: 0/1
  • Assigned reviewer: not assigned yet — comment /request-review to ask for one
  • Review target date: not set
  • Still needed: 1 more approval(s)
  • No staffed reviewer pool owns these files yet; any reviewer with write access counts as the domain reviewer.

Commands

Command Who What it does
/rerun-checks PR author, maintainers Re-runs failed or incomplete checks and re-evaluates this gate
/request-review PR author, maintainers Asks the review rotation to assign a reviewer (adds needs-reviewer)

Updated for fefd003 · gate run · This comment is maintained automatically — see submission gate docs.

@github-actions

Copy link
Copy Markdown
Contributor

🧩 Canvas smoke test

✅ Passed · 0 error(s), 8 warning(s)

Check Result
Syntax, imports, file safety ✅
Preview image (≥ 400×160 PNG) ✅
Plugin manifests ✅
Materialize ✅
Install (Copilot CLI) ✅

Plugin kanvasban v1.0.0

Field Value
Description A local Copilot canvas for humans and agents to manage projects, features, and user stories.
Author John Grant — https://github.com/johngrant
License MIT
Keywords kanban, project-management, user-stories, canvas
Extensions kanvasban
Materialize ✅
Install ✅
Changed plugin files
  • plugins/kanvasban/README.md
  • plugins/kanvasban/plugin.json

Extension kanvasban

kanvasban preview

Field Value
Registered by kanvasban
Package —
Preview 1440×961, 81.9 KB
Modules 5 (3 reachable from extension.mjs)
Files 10

Permissions and capabilities (static analysis of modules reachable from extension.mjs)

  • File system access (node:fs)
  • Network sockets / local server (node:http, node:net, ...)
  • Host information (node:os)
  • Reads environment variables (process.env)

Warnings

  • backlog.test.mjs: non-literal dynamic import cannot be analyzed safely (module is not reachable from extension.mjs)
  • backlog.test.mjs: non-literal dynamic import cannot be analyzed safely (module is not reachable from extension.mjs)
  • backlog.test.mjs: non-literal dynamic import cannot be analyzed safely (module is not reachable from extension.mjs)
  • backlog.test.mjs: non-literal dynamic import cannot be analyzed safely (module is not reachable from extension.mjs)
  • backlog.test.mjs: non-literal dynamic import cannot be analyzed safely (module is not reachable from extension.mjs)
  • backlog.test.mjs: non-literal dynamic import cannot be analyzed safely (module is not reachable from extension.mjs)
  • backlog.test.mjs: non-literal dynamic import cannot be analyzed safely (module is not reachable from extension.mjs)
  • backlog.test.mjs: import "node:test" is not a Node.js builtin, host-provided package, or declared dependency (module is not reachable from extension.mjs)
Changed extension files
  • extensions/kanvasban/.gitignore
  • extensions/kanvasban/AGENTS.md
  • extensions/kanvasban/README.md
  • extensions/kanvasban/assets/preview.png
  • extensions/kanvasban/backlog-store.mjs
  • extensions/kanvasban/backlog.test.mjs
  • extensions/kanvasban/card-details.mjs
  • extensions/kanvasban/extension.mjs
  • extensions/kanvasban/index.html
  • extensions/kanvasban/live-updates.mjs

Static checks compile modules without executing them. Minimum preview size is configurable with CANVAS_PREVIEW_MIN_WIDTH/CANVAS_PREVIEW_MIN_HEIGHT. Workflow run

@github-actions github-actions Bot added ready-for-review Submission passed intake validation and is ready for maintainer review and removed awaiting-automation labels Oct 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Missing DNS-rebinding protection exposes personal board data, while test isolation and UI state defects also need correction.

10 open issues
What changed in this PR

Adds Kanvasban to the repository’s installable canvas plugins: a local, multi-project backlog shared by humans and agents without requiring GitHub issues or an external project-management service.

Changes:

  • Adds a board for projects, features, and user stories, with browser controls and agent actions.
  • Implements local persistence, first-run starter content, live updates, and automated tests.
  • Registers the plugin and updates documentation and marketplace metadata.
File Description
plugins/​kanvasban/​README.md Documents installation, features, and local storage.
plugins/​kanvasban/​plugin.json Registers the plugin and reusable extension source.
extensions/​kanvasban/​README.md Explains board behavior, actions, storage, and testing.
extensions/​kanvasban/​live-updates.mjs Streams board snapshots and storage errors.
extensions/​kanvasban/​index.html Implements the interactive board interface.
extensions/​kanvasban/​extension.mjs Connects canvas lifecycle, HTTP routes, and agent actions.
extensions/​kanvasban/​card-details.mjs Provides inline editing, comments, and history.
extensions/​kanvasban/​backlog.test.mjs Adds storage, API, concurrency, and streaming coverage.
extensions/​kanvasban/​backlog-store.mjs Implements validation, persistence, locking, and mutations.
extensions/​kanvasban/​AGENTS.md Documents agent actions and coordination workflows.
extensions/​kanvasban/​.gitignore Excludes local stores and temporary data.
docs/​README.plugins.md Adds Kanvasban to the plugin catalog.
.github/​plugin/​marketplace.json Adds the marketplace installation entry.

Review effort: Max

Comment on lines +203 to +204
async function handleHttpRequest(request, response) {
const url = new URL(request.url ?? '/', 'http://127.0.0.1')
Comment on lines +27 to +35
const previousHome = process.env.HOME
const previousCopilotHome = process.env.COPILOT_HOME
t.after(() => {
if (previousHome === undefined) delete process.env.HOME
else process.env.HOME = previousHome
if (previousCopilotHome === undefined) delete process.env.COPILOT_HOME
else process.env.COPILOT_HOME = previousCopilotHome
})
process.env.HOME = path.join(directory, 'home')
Comment on lines +42 to +51
display.setAttribute('aria-label', `Edit ${label}`)
parent.append(root)
let editing = false
let saving = false
let baseline
const show = () => {
display.textContent = choices
? choices().find(([value]) => value === (currentItem[field] ?? ''))?.[1] ?? 'Unavailable Feature'
: currentItem[field] || `Add ${label.toLowerCase()}...`
}
saving = false
accept.disabled = cancel.disabled = editor.disabled = false
find('#close-item').disabled = false
for (const other of fields.values()) other.setDisabled(false)
Comment on lines +236 to +237
await save(editingId ? 'edit' : 'add', editingId, find('#comment-body').value)
resetEditor()
Comment on lines +265 to +266
const comments = find('#comment-list')
comments.replaceChildren()
let size = 0
for await (const chunk of request) {
size += chunk.length
if (size > 16384) throw new CanvasError('INVALID_INPUT', 'Request body exceeds the 16 KB limit.')
.archived-badge { display: inline-block; padding: 2px 6px; margin: 4px 0; border-radius: 3px; background: #dcdfe4; color: #44546f; font-size: .75rem; font-weight: 600; }
[data-theme="dark"] #toggle-archive[aria-pressed="true"] { background: #1c2b41; color: #85b8ff; }
[data-theme="dark"] .archived-badge { background: #454f59; color: #b6c2cf; }
.feature-create { display: grid; place-items: center; width: 32px; height: 32px; margin: .6rem 0 0 auto; padding: 0; font-size: 1.4rem; line-height: 1; }
option.textContent = title
parentFeature.append(option)
}
if (selectedParent && !features.some((feature) => feature.id === selectedParent)) {
(!story.archivedAt || toggleArchive.getAttribute('aria-pressed') === 'true') && (!priorityFilter.value || story.priority === priorityFilter.value)
&& (!typeFilter.value || story.type === typeFilter.value)
&& `${story.title} ${story.description} ${story.acceptanceCriteria} KB-${story.id} ${features.find((feature) => feature.id === story.parentFeatureId)?.title ?? ''}`.toLowerCase().includes(query))
storyList.replaceChildren()

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

canvas-extension PR touches canvas extensions merge-risk:medium new-submission PR adds at least one new contribution plugin PR touches plugins ready-for-review Submission passed intake validation and is ready for maintainer review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants