Skip to content

Add a Copilot Canvas extension for agentic workflow operations - #42137

Merged
pelikhan merged 11 commits into
mainfrom
copilot/add-github-copilot-canvas-extension
Jun 29, 2026
Merged

Add a Copilot Canvas extension for agentic workflow operations#42137
pelikhan merged 11 commits into
mainfrom
copilot/add-github-copilot-canvas-extension

Conversation

CopilotAI commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

This PR adds a project-scoped GitHub Copilot Canvas extension specialized for agentic workflows in github/gh-aw. It introduces a minimal, GitHub-styled dashboard for browsing workflow definitions and runs, reviewing safe markdown step summaries, dispatching predefined workflows, and invoking gh aw logs / gh aw audit commands at canvas level.

  • Extension surface and wiring

    • Added .github/extensions/agentic-workflows-dashboard with Copilot extension metadata and entrypoint.
    • Implemented canvas actions required by the spec:
      • listDefinitions(page, pageSize)
      • listRuns(page, pageSize)
      • getRun(id)
      • dispatchWorkflow(definitionId, inputs)
      • runGhAwLogs(args)
      • runGhAwAudit(args)
  • Strict TypeScript domain model + paging

    • Added strict TS models for WorkflowDefinition, WorkflowRun, WorkflowStep, and generic PagedResult<T>.
    • Implemented deterministic in-memory datasets sized for high-volume pagination (hundreds of definitions/runs).
    • Added shared pagination logic used by both UI and action handlers.
  • Dashboard UI (Alpine.js + Primer CSS, native modules)

    • Added a repository-style header, nav tabs, Box-based panels, counters, status labels, flash messaging, and muted metadata.
    • Implemented responsive multi-column layout for definitions, runs, and run detail panels.
    • Added a compact command panel supporting:
      • gh aw logs
      • gh aw logs --run <id>
      • gh aw audit
      • gh aw audit --run <id>
  • Safe markdown rendering for run summaries

    • Added constrained markdown rendering for step summaries (escaping + limited formatting transforms) before injecting into the run-detail panel.
createCanvas({id: "agentic-workflows-dashboard",actions: [{name: "listDefinitions",handler: (ctx)=>paginate(definitions,Number(ctx.input?.page??1),Number(ctx.input?.pageSize??20))},{name: "listRuns",handler: (ctx)=>paginate(runs,Number(ctx.input?.page??1),Number(ctx.input?.pageSize??20))},{name: "getRun",handler: (ctx)=>({run: findRun(String(ctx.input?.id??""))})},{name: "dispatchWorkflow",handler: (ctx)=>dispatchWorkflow(String(ctx.input?.definitionId??""),ctx.input?.inputs??{})},{name: "runGhAwLogs",handler: (ctx)=>runGhAwLogs(String(ctx.input?.args??""))},{name: "runGhAwAudit",handler: (ctx)=>runGhAwAudit(String(ctx.input?.args??""))}]});

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
CopilotAI changed the title Add Copilot canvas extension for agentic workflows dashboardAdd a Copilot Canvas extension for agentic workflow operationsJun 28, 2026
CopilotAI requested a review from pelikhanJune 28, 2026 21:47
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot

  • configure vitest tests
  • add makefile target to compile canvas and run tests
  • take screenshots using playwright

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot a tabbed view design so that it is easy and modular to add views

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

CopilotAI commented Jun 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot

  • configure vitest tests
  • add makefile target to compile canvas and run tests...

Implemented in bc6ad18.

  • Configured Vitest for .github/extensions/agentic-workflows-dashboard and added unit tests (test/pagination.test.ts).
  • Added make test-canvas-extension to compile the canvas extension and run its tests.
  • Captured dashboard screenshots with Playwright and added:
    • .github/extensions/agentic-workflows-dashboard/screenshots/dashboard-full.png
    • .github/extensions/agentic-workflows-dashboard/screenshots/dashboard-viewport.png

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot modularize to allow reuse, apply SOLID, DRY, YAGNI.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot also wire gh aw audit-diff and gh aw compile commands

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot

  • move css to separate file
  • add makefile target to lint/fmt

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot init impeccable (https://github.com/pbakaus/impeccable) for the canvas

Configure it as a github.com like experience for exploring, managing, running agentic workflows.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

CopilotAI commented Jun 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot modularize to allow reuse, apply SOLID, DRY, YAGNI.

Addressed in 2735ec5 and 6dfe1c2. I refactored the dashboard to a reusable tab model with shared view-switch helpers, removed duplicated run-detail navigation logic, and added guarded tab selection for cleaner SOLID/DRY behavior while keeping scope minimal.

@copilot a tabbed view design so that it is easy and modular to add views

Implemented in 2735ec5 and finalized in 6dfe1c2. The dashboard now uses a metadata-driven tabbed view system (Workflows/Runs/Run details/Commands), with each view rendered as an independent panel to make future view additions modular.

CopilotAIand others added 2 commits June 28, 2026 22:35
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

CopilotAI commented Jun 28, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot also wire gh aw audit-diff and gh aw compile commands

Implemented in 06e1f42 (plus follow-up polish in 4e3d023): wired gh aw compile and gh aw audit-diff in both canvas actions and the command panel behavior/quick-fill paths.

@copilot init impeccable (https://github.com/pbakaus/impeccable) for the canvas

Configure it as a github.com like experience for exploring, managing, running agentic workflows.

Implemented in 06e1f42: initialized Impeccable context for this canvas with .impeccable/config.json and PRODUCT.md, and aligned the dashboard toward a GitHub-like exploration/operations experience.

@pelikhanpelikhan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot make fmt / lint targets run the new fmt/lint dashboard targets

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan
pelikhan marked this pull request as ready for review June 28, 2026 22:58
CopilotAI review requested due to automatic review settings June 28, 2026 22:58
CopilotAI requested a review from pelikhanJune 28, 2026 22:58
@pelikhan

Copy link
Copy Markdown
Collaborator

/matt

@github-actions

github-actionsBot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

CopilotAI 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.

Pull request overview

This pull request introduces a project-scoped GitHub Copilot Canvas extension that provides a lightweight “agentic workflows” dashboard surface (definitions, runs, run details, and a command panel), along with build/lint/fmt targets wired into the repo Makefile.

Changes:

  • Added a new Copilot Canvas extension under .github/extensions/agentic-workflows-dashboard, including the extension entrypoint (extension.mjs) and a static dashboard UI (Primer CSS styling + Alpine.js-driven views).
  • Introduced a strict TypeScript domain model + pagination helper (with Vitest coverage for pagination) and compiled runtime assets under web/.
  • Integrated extension formatting/linting/testing into top-level make fmt, make lint, and added a dedicated test-canvas-extension target.
Show a summary per file
FileDescription
MakefileAdds build/test/fmt/lint targets for the Canvas extension and wires fmt/lint into existing top-level targets.
.github/extensions/agentic-workflows-dashboard/web/styles.cssAdds minimal dashboard-specific CSS utilities (shell spacing, scroll containers, selection styling).
.github/extensions/agentic-workflows-dashboard/web/pagination.jsAdds web runtime pagination helper used by the dashboard bundle.
.github/extensions/agentic-workflows-dashboard/web/models.jsAdds an (empty) module stub emitted for TS module boundary.
.github/extensions/agentic-workflows-dashboard/web/index.htmlAdds the dashboard HTML template (Primer layout, tabbed panels, and markdown summary rendering surface).
.github/extensions/agentic-workflows-dashboard/web/app.jsAdds the dashboard’s Alpine.js app runtime (definitions/runs datasets, command simulation, safe markdown rendering).
.github/extensions/agentic-workflows-dashboard/vitest.config.tsConfigures Vitest discovery for extension tests.
.github/extensions/agentic-workflows-dashboard/tsconfig.jsonDefines strict TypeScript compilation settings and emits JS into web/.
.github/extensions/agentic-workflows-dashboard/test/pagination.test.tsAdds unit tests for pagination behavior.
.github/extensions/agentic-workflows-dashboard/src/pagination.tsAdds typed pagination helper used by TS sources.
.github/extensions/agentic-workflows-dashboard/src/models.tsAdds strict domain model types for definitions, runs, steps, and paged results.
.github/extensions/agentic-workflows-dashboard/src/app.tsAdds typed dashboard runtime (rendering logic, command simulation, and safe markdown rendering).
.github/extensions/agentic-workflows-dashboard/PRODUCT.mdDocuments product intent and UI design lane for the extension.
.github/extensions/agentic-workflows-dashboard/package.jsonDefines extension package scripts/deps (build, lint, test, fmt).
.github/extensions/agentic-workflows-dashboard/package-lock.jsonLocks dependency tree for the extension.
.github/extensions/agentic-workflows-dashboard/extension.mjsImplements the Copilot Canvas extension (actions, in-memory data, and dashboard open() URL rendering).
.github/extensions/agentic-workflows-dashboard/copilot-extension.jsonAdds Copilot extension metadata (name/version).
.github/extensions/agentic-workflows-dashboard/.impeccable/config.jsonEnables Impeccable detector config for the dashboard’s web assets.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Files not reviewed (1)
  • .github/extensions/agentic-workflows-dashboard/package-lock.json: Generated file
  • Files reviewed: 17/20 changed files
  • Comments generated: 8
  • Review effort level: Low

Comment thread.github/extensions/agentic-workflows-dashboard/web/index.html Outdated
Comment thread.github/extensions/agentic-workflows-dashboard/web/index.html Outdated
Comment thread.github/extensions/agentic-workflows-dashboard/web/index.html Outdated
Comment on lines +3 to +19
export function paginate<T>(items: T[], page: number, pageSize: number): PagedResult<T> {
const totalItems = items.length;
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
const safePage = Math.min(Math.max(1, page), totalPages);
const start = (safePage - 1) * pageSize;
const end = start + pageSize;

return {
items: items.slice(start, end),
page: safePage,
pageSize,
totalItems,
totalPages,
hasNextPage: safePage < totalPages,
hasPreviousPage: safePage > 1,
};
}
Comment on lines +60 to +67
const status = statuses[index % statuses.length] ?? "queued";
const definition = sourceDefinitions[index % sourceDefinitions.length];
const stepStatuses = stepStatusMap[status] ?? stepStatusMap.queued;

return {
id: `run-${String(index).padStart(5, "0")}`,
definitionId: definition.id,
status,
Comment on lines +137 to +140
</main>
</div>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.15.0/dist/cdn.min.js"></script>
<script type="module">
Comment on lines +209 to +218
async function renderDashboardUrl() {
const htmlPath = join(__dirname, "web", "index.html");
const appPath = join(__dirname, "web", "app.js");
const cssPath = join(__dirname, "web", "styles.css");

const [htmlTemplate, appBundle, cssBundle] = await Promise.all([readFile(htmlPath, "utf8"), readFile(appPath, "utf8"), readFile(cssPath, "utf8")]);

const html = htmlTemplate.replace("/*__APP_CSS__*/", cssBundle).replace("/*__APP_JS__*/", appBundle);
return `data:text/html;charset=utf-8,${encodeURIComponent(html)}`;
}
Comment on lines +10 to +26
"devDependencies": {
"typescript": "6.0.3",
"vitest": "4.1.9"
},
"scripts": {
"build": "tsc -p tsconfig.json",
"typecheck": "tsc -p tsconfig.json --noEmit",
"test": "vitest run",
"lint": "npm run typecheck && npm test",
"fmt": "npm run fmt:ts && npm run fmt:html && npm run fmt:css && npm run fmt:js && npm run fmt:json",
"fmt:ts": "npx prettier --write --parser typescript \"src/**/*.ts\" \"test/**/*.ts\" \"vitest.config.ts\"",
"fmt:html": "npx prettier --write --parser html \"web/index.html\"",
"fmt:css": "npx prettier --write --parser css \"web/styles.css\"",
"fmt:js": "npx prettier --write --parser babel \"extension.mjs\"",
"fmt:json": "npx prettier --write --parser json \"copilot-extension.json\" \"package.json\"",
"impeccable:detect": "npx impeccable detect web/index.html web/styles.css"
}
@github-actions

Copy link
Copy Markdown
Contributor

Review complete: 3 blocking issues, 4 medium priority

Applied /tdd, /zoom-out, /improve-codebase-architecture, /grill-with-docs, and /diagnose. Verdict: REQUEST_CHANGES.

🔴 Blocking (must fix)
#LocationIssue
1extension.mjs:116runs.unshift() mutates shared module-level state — no session isolation
2test/pagination.test.tsZero tests for renderSafeMarkdown, runGhCommand, dispatchWorkflow
3web/app.jsTypeScript compiler output committed alongside source — drift risk
🟡 Medium priority
#LocationIssue
4tsconfig.json:16Test directory excluded from typecheck
5src/app.ts:190runFlagMatch hoisted with implicit branch-ordering dependency
6extension.mjs:151Command handling duplicated client-side and server-side with no documented relationship
7src/app.ts:358UI dispatch creates separate in-memory run vs canvas dispatchWorkflow action
8extension.mjs:67Missing null guard on definition.id (present in app.ts but not .mjs)

@copilot please address the review comments above.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 139.1 AIC · ⌖ 10.1 AIC · ⊞ 6.6K ·
Comment /matt to run again

github-actions[bot]
github-actionsBot previously requested changes Jun 28, 2026

@github-actionsgithub-actionsBot 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.

Skills-Based Review 🧠

Applied /tdd, /zoom-out, /improve-codebase-architecture, /grill-with-docs, and /diagnose — requesting changes on three blocking issues.

📋 Key Themes & Findings

Blocking Issues

  1. Mutable global state (extension.mjs:116) — runs.unshift() mutates module-level state shared across all sessions. In any multi-user deployment this is a correctness bug.

  2. Test coverage gap (test/pagination.test.ts) — 414-line app.ts and 353-line extension.mjs contain complex branchy logic (renderSafeMarkdown, runGhCommand, dispatchWorkflow) with zero tests. The HTML injection surface and command parser both need coverage before this ships.

  3. Generated artifacts committed (web/app.js) — TypeScript compiler output is checked in alongside source, creating silent drift risk on every src/*.ts edit.

Medium Priority

  • tsconfig.json excludes test/ — test files not type-checked by npm run typecheck
  • runFlagMatch hoisted with implicit branch-ordering dependency — fragile, needs localisation and tests
  • Command handling duplicated between extension.mjs and app.ts with no documented relationship
  • dispatchSelectedWorkflow() operates on a separate dataset from the canvas dispatchWorkflow action — no documented design intent

Positive Highlights

  • ✅ Clean domain model in src/models.ts with strict TypeScript (noUncheckedIndexedAccess, exactOptionalPropertyTypes)
  • ✅ Generic paginate<T> function with proper clamping and tested behaviour
  • escapeHtml runs before all inline transforms — XSS fundamentals are sound
  • ✅ Makefile integration (test-canvas-extension, lint-canvas-extension, fmt-canvas-extension) is well-structured
  • ✅ Progressive disclosure design in the Primer-based UI is clean and consistent

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 139.1 AIC · ⌖ 10.1 AIC · ⊞ 6.6K
Comment /matt to run again

pelikhanand others added 3 commits June 28, 2026 16:39
…K dep
- Replace data URI with a per-instance loopback HTTP server; the runtime
rejects data: scheme URLs with canvas_provider_url_disallowed
- Serve web/app.js and web/pagination.js as separate routes so the ES
module import chain resolves correctly from the loopback origin
- Add onClose handler to shut down the server when a panel is closed
- Fix Alpine.js x-for directives: move them from <div> to <template>
elements as required by Alpine v3 (list rendering was silently broken)
- Remove @github/copilot-sdk from package.json dependencies; the CLI
auto-resolves the SDK, and listing it risks installing a conflicting
version if someone runs npm install
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Alpine's defer script fires alpine:init before the type=module app.js
has run, so Alpine.data('dashboardApp') was never registered and the
dashboard rendered blank.
Fix: import Alpine as an ESM module directly in app.js and call
Alpine.start() at the end of the module. This gives the module full
control over startup order — Alpine.data() is registered synchronously
before Alpine.start() walks the DOM.
- Remove the defer CDN script tag from index.html (Alpine is now
imported by app.js via the +esm CDN path)
- Remove the document.addEventListener('alpine:init', ...) wrapper;
register Alpine.data() at module scope instead
- Add Alpine.start() at the end of app.js
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- extension.mjs: use execFile to call ./gh-aw (dev) or gh aw (installed);
add /api/status, /api/runs, /api/run-command, /api/refresh routes;
add 60s result cache; add systemMessage with CLI usage instructions;
assign workspacePath after joinSession; remove all dummy data functions
- web/app.js: fetch from /api/* endpoints; map real field names
(workflow, engine_id, run_id, workflow_name, duration, token_usage, turns,
error_count); add loadingDefinitions/loadingRuns/error state; add refresh()
- web/index.html: update templates for real field names; add loading spinners;
replace step list in Details tab with metrics grid; add Refresh button;
update Commands tab quick-fill buttons to real commands
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage — §28342769269

FieldValue
Categoryfeature
Riskhigh
Score69/100
Priorityhigh
Actionfast_track
StatusReady — CI passing, CHANGES_REQUESTED needs resolution

Score breakdown: Impact 42 · Urgency 15 · Quality 12

Rationale: New GitHub Copilot Canvas extension for agentic workflow operations (+2777/−2, 20 files). Significant new product surface: dashboard for browsing workflow definitions/runs, dispatching workflows, and invoking gh aw logs/gh aw audit at canvas level. CI passing. Active engagement from @pelikhan requesting make fmt/lint on dashboard code; skills-based review has CHANGES_REQUESTED with 3 blocking issues.

Next steps:

  1. Run make fmt on the dashboard code per @pelikhan
  2. Address the 3 blocking issues from the skills-based review
  3. Ready for expedited human review once resolved

Generated by 🔧 PR Triage Agent · 107.8 AIC · ⌖ 10.9 AIC · ⊞ 5.4K ·

@pelikhan
pelikhan merged commit d84a05a into mainJun 29, 2026
35 checks passed
@pelikhan
pelikhan deleted the copilot/add-github-copilot-canvas-extension branch June 29, 2026 02:10
github-actionsBot added a commit that referenced this pull request Jun 29, 2026
Covers the week's highlights including:
- Copilot Canvas extension for agentic workflow operations (PR #42137)
- create-canvas skill (PR #42147)
- sandbox.agent.sudo: false coverage hits 80% (PR #42119)
- Code Scanning Fixer expanded to all severity levels (PR #42139)
- mcpg v0.3.32 + firewall v0.27.13 bump (PR #42146)
- Agent of the Week: agent-persona-explorer
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.82.0

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@pelikhan