Conversation
Add --diagram flag to 'get process-instance' command that generates a self-contained HTML file rendering the BPMN diagram with highlighted completed, active, and incident elements plus taken sequence flows. Uses bpmn-js from CDN for client-side rendering, following the same approach as Camunda Process Test coverage reports. Opens the generated HTML file in the default browser automatically. Usage: c8ctl get pi <key> --diagram [--output path.html]
Replace HTML output with PNG rendering using puppeteer-core and system-installed Chrome/Chromium. The diagram is rendered headlessly via bpmn-js, then screenshotted to PNG at 2x resolution. Requires Chrome or Chromium installed on the system. Falls back to a clear error message with download link if no browser is found.
Auto-detect terminals supporting inline images (iTerm2, kitty, WezTerm, VS Code, mintty, Konsole) and print the PNG directly to the console using the iTerm2 Inline Images Protocol. Falls back to saving a temp file and opening with the system viewer when the terminal doesn't support inline images. Explicit --output always saves to the given path.
Remove terminal auto-detection and file-open fallback. The diagram is always printed inline to the terminal via the iTerm2 Inline Images Protocol. Use --output to save the PNG to a file instead.
There was a problem hiding this comment.
Pull request overview
This pull request adds a new feature to render BPMN diagrams for process instances as PNG images with execution state highlighting. The feature integrates Puppeteer with system-installed Chrome/Chromium to render diagrams using bpmn-js, showing completed elements, active elements, incidents, and taken sequence flows with color-coded visualization.
Changes:
- Adds
--diagramflag and--outputoption toc8ctl get picommand for rendering process instance diagrams - Implements diagram generation using Puppeteer, headless Chrome, and bpmn-js from CDN
- Updates help text, shell completions (bash, zsh, fish), and unit tests to reflect the new feature
- Adds puppeteer-core dependency to package.json
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/commands/diagram.ts | New module implementing process instance diagram rendering with Puppeteer and bpmn-js |
| src/index.ts | Adds --diagram and --output flag handling in the get pi command flow |
| src/commands/help.ts | Updates help text with --diagram and --output flag documentation and examples |
| src/commands/completion.ts | Adds --diagram and --output flags to bash, zsh, and fish shell completion scripts |
| tests/unit/help.test.ts | Adds test assertions for --diagram flag presence in help output |
| package.json | Adds puppeteer-core ^24.37.4 dependency |
| package-lock.json | Lockfile updates for puppeteer-core and transitive dependencies |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
| window.__diagramRendered = true; | ||
| } catch (err) { | ||
| console.error('Failed to render BPMN diagram:', err); | ||
| window.__diagramRendered = true; | ||
| } |
There was a problem hiding this comment.
The embedded renderer sets window.__diagramRendered = true even when rendering fails (catch block), so Puppeteer will still take a screenshot (often blank) and the CLI will report success. Please propagate render failures back to Node (e.g., store an error message in window.__diagramError and have waitForFunction/assertions fail when it's set, and/or fail if no SVG is present).
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
| export async function getProcessInstanceDiagram(key: string, options: { | ||
| profile?: string; | ||
| output?: string; | ||
| }): Promise<void> { | ||
| const logger = getLogger(); | ||
| const client = createClient(options.profile); | ||
| const consistencyOptions = { consistency: { waitUpToMs: 0 } }; |
There was a problem hiding this comment.
No tests currently cover the new diagram functionality (routing via "get pi --diagram" and the diagram generation/output behavior). Per project guidelines, please add at least a minimal test (unit and/or integration) that validates the new flag behavior and expected outputs/failures.
* Initial plan * docs: add diagram flag and output option examples to README and EXAMPLES Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
* Initial plan * docs: add diagram flag examples to EXAMPLES.md Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
* Initial plan * test: add integration tests for diagram feature Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@copilot do some investigation as to why displaying/rendering the image works in iTerm2, but not in Ghostty - both should support the Kitty graphics protocol, so the png should always display. Find a way to assure correct implementation of displaying/outputting the graphic here. |
* Initial plan * feat: bundle bpmn-js assets locally instead of using CDN - Add bpmn-js@18 as a dependency - Update build script to copy bpmn-js assets to dist/assets/bpmn-js/ - Update diagram.ts to use file:// URLs for bundled assets - Removes hard internet dependency for diagram rendering - Enables diagram rendering in air-gapped/proxied environments Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> * chore: update package-lock.json after adding bpmn-js Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
* Initial plan * test: add assertion for --output flag in get help test Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
… diagrams (#68) * Initial plan * fix: ensure parent directory exists when saving diagram with --output Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
* Initial plan * test: add assertion for --output flag in help tests Add assertion to verify --output flag appears in help text alongside --diagram flag, as both flags work together for diagram rendering. Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
* Initial plan * fix: use parsed values for --variables flag instead of process.argv Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> * docs: finalize PR addressing parseArgs feedback Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
| process.stdout.write(`\x1b]1337;File=${args}:${base64}\x07\n`); | ||
| } | ||
|
|
There was a problem hiding this comment.
The file:// URLs are constructed via string concatenation and simple backslash replacement. This will break for paths containing spaces or other characters needing URL-encoding. Prefer pathToFileURL(cssPath).href / pathToFileURL(jsPath).href (from node:url) to generate valid file URLs cross-platform.
|
|
||
| // 8. Output: save to file if --output, otherwise print inline | ||
| if (options.output) { |
There was a problem hiding this comment.
When --output points to a path in a non-existent directory, writeFileSync will throw and the user only gets the generic “Failed to generate diagram…” wrapper. Create the parent directory first (recursive) before writing (similar to how src/plugin-registry.ts ensures the parent dir exists before writeFileSync).
|
|
||
| try { | ||
| const output = execSync( | ||
| `node src/index.ts get pi --key ${instanceKey} --diagram --output ${outputPath}`, |
There was a problem hiding this comment.
These new integration tests invoke get pi using --key, but the CLI expects the process instance key as a positional argument (c8ctl get pi <key>). With --key, args[0] will be empty and the command will exit before rendering. Update the exec invocations to pass the key positionally (and keep flags after it).
| `node src/index.ts get pi --key ${instanceKey} --diagram --output ${outputPath}`, | |
| `node src/index.ts get pi ${instanceKey} --diagram --output ${outputPath}`, |
| try { | ||
| const output = execSync( | ||
| `node src/index.ts get pi --key ${instanceKey} --diagram --output ${outputPath}`, | ||
| { encoding: 'utf8', cwd: process.cwd(), stdio: 'pipe' } | ||
| ); |
There was a problem hiding this comment.
This “save PNG to file” test will hard-fail on systems/CI where Chrome/Chromium isn’t installed. The next test already treats the missing-Chrome error as a skip; apply the same handling here (or skip early) so the integration suite is stable across environments.
| diagramData.activeElements.forEach(function(elementId) { | ||
| canvas.addMarker(elementId, 'active-element'); | ||
| }); | ||
|
|
||
| diagramData.incidentElements.forEach(function(elementId) { |
There was a problem hiding this comment.
The HTML renderer sets window.__diagramRendered = true even when rendering fails, and the Node side only waits for that flag. This means missing assets / importXML errors will still be treated as success and you’ll write a PNG without warning. Capture the render error (e.g., window.__diagramError) and have renderDiagramToPng() fail when an error was reported, so users get an actionable error instead of a blank image.
…ring (#71) * Initial plan * feat: add Kitty Graphics Protocol support for Ghostty and other terminals Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> * feat: add Sixel graphics protocol support and regenerate package-lock with Node 22 Co-authored-by: vobu <6573426+vobu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
| } catch (error: any) { | ||
| // On systems without Chrome/Chromium, this test may fail | ||
| // Verify it fails with a helpful error message | ||
| if (error.stderr && error.stderr.includes('No Chrome or Chromium browser found')) { |
There was a problem hiding this comment.
The test silently passes when Chrome/Chromium is not installed, which means the actual diagram rendering functionality is not being tested in CI environments without a browser. Consider using a mock or ensuring the test environment has Chrome installed, or mark this as a skipped test rather than passing.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@copilot the diagram creation doesn't work at all. fix this. then refactor so that this feature can become a c8ctl plugin rather than built into c8ctl directly. Move the code into /default-plugins for now and prepare that it can be carved out into a standalone repository. |
No description provided.