--- name: demonstrate-issues description: > Run a live bug-demonstration capture session before filing GitHub issues. The user drives the browser and narrates bugs one after another ("see this โ€” clicking X should do Y but does Z"); this skill captures each demo (snapshot + screenshot + description + environment context) without investigating, only after the user signals the session is over does it investigate root causes, then only after the user reviews the write-ups does it file issues. Use when asked to "demonstrate some bugs", "show you issues before filing them", or via `/demonstrate-issues`. Never fixes anything โ€” it ends at filing GitHub issue(s); any actual fix is separate, later `dev-issue` work. allowed-tools: Read, Glob, Grep, Bash, PowerShell, mcp__playwright__browser_navigate, mcp__playwright__browser_navigate_back, mcp__playwright__browser_click, mcp__playwright__browser_type, mcp__playwright__browser_fill_form, mcp__playwright__browser_select_option, mcp__playwright__browser_hover, mcp__playwright__browser_press_key, mcp__playwright__browser_wait_for, mcp__playwright__browser_snapshot, mcp__playwright__browser_take_screenshot, mcp__playwright__browser_console_messages, mcp__playwright__browser_network_requests, mcp__playwright__browser_evaluate, mcp__playwright__browser_resize, mcp__playwright__browser_tabs, mcp__playwright__browser_close, mcp__playwright__browser_handle_dialog, mcp__claude-in-chrome__tabs_context_mcp, mcp__claude-in-chrome__tabs_create_mcp, mcp__claude-in-chrome__tabs_close_mcp, mcp__claude-in-chrome__navigate, mcp__claude-in-chrome__computer, mcp__claude-in-chrome__read_page, mcp__claude-in-chrome__find, mcp__claude-in-chrome__form_input, mcp__claude-in-chrome__get_page_text, mcp__claude-in-chrome__read_console_messages, mcp__claude-in-chrome__read_network_requests, mcp__claude-in-chrome__resize_window --- # Demonstrate Issues (HMIS) **๐Ÿšจ TOOLS: Playwright MCP is the default (`mcp__playwright__*`).** Every step below is written for Playwright's plain tool names (`browser_navigate`, `browser_snapshot`, `browser_take_screenshot`, ...) โ€” don't reach for claude-in-chrome out of general habit. The `mcp__claude-in-chrome__*` tools in the `allowed-tools` frontmatter exist **only** for the discussed fallback below, not for casual use. If Playwright genuinely isn't usable in the environment (MCP server unavailable, the browser won't launch, etc. โ€” a headless box the user simply can't watch is *not* such a case; drive it click-by-click per step 2), **discuss it with the user first** rather than silently switching โ€” they may prefer to solve the Playwright-side blocker (e.g. relay screenshots) over falling back. Only switch tools after they say so. **If the claude-in-chrome fallback is approved:** use the `mcp__claude-in-chrome__*` tools for navigation, page inspection, and form input; don't call Playwright-only tools. Two steps have no fallback equivalent โ€” handle them explicitly rather than skipping silently: - **Screenshot capture (step 3):** take the shot with `mcp__claude-in-chrome__computer`; if it can't be written into the session's `tmp/` subfolder, ask the user to save/relay the image, and if even that isn't possible record the demo's evidence as "screenshot unavailable (claude-in-chrome fallback)". - **Native `confirm()`/`alert()` (step 3, "Native JS dialogs mid-demo"):** there is no `browser_handle_dialog` equivalent and the dialog blocks the extension โ€” pause and ask the user to resolve it manually in their browser, then continue. **๐Ÿšจ LOGIN: ask, don't assume.** At step 2, once the login page is open, ask the user directly whether they want to log in themselves or have Claude log in and proceed โ€” don't silently default to either one. Only look up credentials or drive the login form after they've said they want Claude to do it. Structurally separates three phases with hard stops between them: **demonstrate** โ†’ **investigate** โ†’ **file**. This exists to prevent acting on a partial picture โ€” jumping from "here's a bug" straight to code before every bug the user wants to show is on the table, and before the full picture of each one is understood. ## Non-goals - **No development or fixing ever happens inside this skill.** It ends at filing GitHub issue(s). Any actual fix is separate, later work โ€” hand the filed issue number(s) to `dev-issue`. - Does not change the behavior of `dev-issue`, `playwright-e2e`, or any other skill โ€” they keep auto-logging in with Playwright and driving the browser themselves by default, no question asked. The ask-before-login and discuss-before-tool-fallback rules below are local to this skill only. ## Reference docs - [Playwright E2E Testing Workflow](../../../developer_docs/testing/playwright-e2e-workflow.md) โ€” PrimeFaces widget commit patterns, dialog handling, the ยง1 login/department gate, the ยง2 **never-navigate-by-URL** rule (the user drives here, so follow their menu path and record it โ€” never "shortcut" to a page by URL when reproducing later; a URL-loaded page renders against uninitialised session state and yields a bug report that isn't real), and the ยง8/ยง8a screenshot-privacy-check convention this skill reuses for evidence capture. - [Playwright MCP Guide](../../../developer_docs/tools/playwright-mcp-guide.md) โ€” generic MCP tool mechanics (clicking, dropdowns, common errors). ## 1. Deploy check (environment-agnostic โ€” never hardcode names/ports) - Resolve the WAR path deterministically each run: prefer `` from `pom.xml` over globbing. Only fall back to `target/*.war` if `pom.xml` doesn't resolve one, and if that glob matches more than one file, treat it as the "ambiguous working tree state" case below rather than guessing which one to use โ€” never assume a fixed filename like `rh-3.0.0.war`, the version differs across checkouts/machines. - Resolve the Payara **admin port** and the app's **HTTP port** from the local credentials file for this machine (`C:\Credentials\credentials.txt` or equivalent) โ€” never assume the defaults (4848 / 8080). Multiple Payara installs can coexist on one box on non-default ports (see [playwright-e2e-workflow ยง27](../../../developer_docs/testing/playwright-e2e/environment-db.md#27-multi-payara-machines-asadmin-without---port-may-hit-another-users-domain)). **Don't `Read` the whole credentials file into context** โ€” it may hold passwords/tokens alongside the ports. Extract just the port line(s) (e.g. `grep`/`findstr` for the admin-port/http-port keys) and use only those values. - Resolve the deployed **context root / URL path** via `asadmin --port list-applications` rather than assuming `/rh` โ€” different instances are deployed as `/rh`, `/hmis`, `/coop`, etc. - Compare the resolved WAR's build time against `git log -1` (HEAD) โ€” mtime alone doesn't prove the WAR was built from HEAD, so also check `git status --short` and record the current commit SHA alongside it. If the running app is behind HEAD, rebuild (`mvn clean package -DskipTests`, JDK 11) and redeploy automatically using the resolved admin port/app name โ€” see [ยง0a](../../../developer_docs/testing/playwright-e2e-workflow.md#0a-rebuild-and-redeploy-local-code-changes-before-testing). Only pause and ask if the build fails or the working tree state is ambiguous (e.g. uncommitted changes on a file that affects the build, or more than one candidate WAR as above). ## 2. Open login page, then ask how to handle login - `browser_navigate` to the resolved login URL. - Ask the user whether they want to log in and select department themselves (e.g. in a visible Playwright-launched browser window, or by directing Claude click-by-click if the browser isn't visible to them), or whether they'd rather Claude look up credentials and log in/select department on its own, same as `playwright-e2e`'s normal login flow. - Don't assume either way, and don't look up or enter credentials before they've said Claude should. - **Wait until login *and* department selection are actually complete before starting the demonstration loop.** If the user handles it, pause until they confirm both steps are done (or the browser clearly shows the authenticated post-department landing page). If Claude handles it, proceed only once that landing page is reached. The shared workflow requires a selected department before any inner-page action โ€” continuing early makes the demos run against unauthenticated / wrong-department state and produce false failures. ## 3. Demonstration loop - The user narrates/points out each issue in chat while driving the browser themselves (e.g. "see this โ€” clicking X should do Y but does Z"). - On the user's cue, capture: - an accessibility snapshot (`browser_snapshot`) - a screenshot (`browser_take_screenshot`) into the project `tmp/` folder, one subfolder per session - the user's description, verbatim - auto-detected environment context: department and user **role** read from the page header (not the raw account/login name), current git branch + commit SHA (`git rev-parse --abbrev-ref HEAD` / `git rev-parse HEAD`), timestamp - **Pure capture only at this stage โ€” no code investigation yet.** Confirm each capture ("Got it, recorded as demo #N") and wait for the next cue or the end signal. - Multiple issues can be demonstrated in one session, back to back. ### Content-free capture cues If the cue to capture carries no description at all (e.g. just "capture", or "check playwrite"), don't capture speculatively and ask afterward what it was for โ€” ask for the one-line description. If the user provides it in the same turn, capture the demo; otherwise wait and do not capture until the description is available. ### Forward-looking narration vs a firm bug cue Distinguish "I'm about to show you X" (scene-setting for a demo that hasn't happened yet) from "see this, X is broken" (the actual cue). Narration that describes what's coming next is not itself a capture cue โ€” wait for the concrete bug before recording anything. The same non-capture handling applies to plain navigation/setup instructions interspersed between demos โ€” "go to inpatient dashboard", "click room details", "now click admit" โ€” where the user is just directing the browser to the next thing worth showing, with no bug implied. Follow the instruction, but don't treat it as a capture cue on its own; wait for the user to actually point out a problem. ### Keep a running navigation breadcrumb, even when not capturing The user is driving the browser, not you โ€” when they say "I'm on page X" or narrate a click, you often can't reconstruct that path from code (it may depend on session state: a selected patient, department, in-progress form) and the user may not be able to repeat the exact clicks on request. Losing the trail forces them to redo manual navigation, which defeats the point of letting them drive. So on every non-capture navigation/narration turn, silently note (don't announce it โ€” this isn't a capture, just a running log) the menu path/button clicked and, if visible from context already in front of you, the resulting page's title and URL. Don't spend an extra `browser_snapshot` call purely to fill in this log โ€” use whatever page context you already have (the last snapshot/screenshot taken, or the user's own words). If a hop's destination truly isn't inferable that way, leave it unlabeled rather than interrupting the flow to ask; a gap in the trail is better than breaking the user's narration to ask a tracking question. **Sanitize before storing, not just before filing.** URLs and page titles/breadcrumbs routinely carry patient identifiers (BHT number, PHN, patient name) even at this scratch stage โ€” strip or generalize those as you log each hop (e.g. `BHT/56757` โ†’ `[selected admission]`). Don't rely on the step-7 filing-time redaction pass alone for this: by then the trail has already been promoted into "Steps to reproduce" text, so anything left unredacted here flows straight into the draft issue body. Keep only the trail since the last completed capture (or session start, whichever is more recent), most recent step last โ€” this is scratch context, not a demo record, and applies to whatever workflow is being demonstrated, not just inpatient/admission ones. When a demo is actually captured โ€” not merely cued; a content-free cue (previous section) leaves the trail open while it waits for the required description โ€” that trail becomes the "Steps to reproduce" backbone for that demo. Clear it once the capture is consumed, so a later demo in the same session doesn't inherit an earlier demo's steps. Any trail still open at session end is simply discarded. If a capture already happened and the user later clarifies that demo #N was not meant as a bug report (e.g. "no error in this page yet, just gathering facts"), treat that as an explicit instruction to drop the prior capture โ€” whether that clarification arrives in the very next message or a later one: acknowledge it ("Dropping demo #N โ€” noted as context only") and exclude it from the investigation/filing phases. Don't carry the ambiguity forward and make the user re-resolve it during investigation. ### Native JS dialogs mid-demo If a demo step triggers a native `confirm()`/`alert()` (e.g. clicking an "Accept" or "Delete" button that pops a browser-native confirmation), the page blocks until the dialog is resolved. Don't guess whether to accept or dismiss โ€” pause and ask the user explicitly which one they want, especially if their reply is short or ambiguous. Once they've said which, call `browser_handle_dialog` with `accept: true` or `accept: false` accordingly. ### When an element-targeted screenshot won't crop cleanly `browser_take_screenshot`'s `element`/`target` params can return the wrong region for a specific gridcell/badge/small element โ€” most often after the page has scrolled or re-rendered and the accessibility-tree ref has gone stale. If that happens, fall back to a full-page screenshot and crop it manually (e.g. PowerShell `System.Drawing`) using coordinates read off the page's own layout description. When computing crop coordinates this way, remember the screenshot PNG is in **device pixels**, not the CSS pixels the accessibility snapshot reports element positions in โ€” on a machine with a >1x device pixel ratio the two disagree by that ratio (e.g. a 2000px-wide described layout can produce a 3455px-wide PNG, a ~1.73x factor). Derive the scale as `image_width / described_css_width` and multiply your target CSS coordinates by it before cropping, or the crop will land on the wrong region. **HARD STOP** โ€” do not read application code, form a root-cause hypothesis, or otherwise start investigating any demo until the end signal in step 4. ## 4. End signal The user says "that's all" (or equivalent) to end the demonstration loop. ## 5. Investigation phase For each recorded demo: full codebase access is available (grep, read controllers/JSF pages, `git blame`/`git log` on the relevant file, DB queries if needed) to work out expected-vs-actual behavior and a root-cause code pointer (file/line). Database queries are **read-only** and select only the fields needed to confirm the root cause (same rule as [playwright-e2e-workflow ยง6](../../../developer_docs/testing/playwright-e2e-workflow.md#6-verify-against-the-database)); keep raw query results โ€” and especially patient data โ€” out of the transcript and out of draft/filed issue text. Rhythm is flexible and assistant-judged: default to investigating all recorded issues quietly and bringing finished write-ups back for batch review (step 6), but switch to narrating findings live, issue-by-issue, when that reads better for a given case โ€” ask the user when genuinely unsure which mode fits. ## 6. Discuss before filing Present the **complete sanitized issue body** for each draft โ€” not just title/summary/root cause/grouping, but the full content from step 7 (environment, steps to reproduce, expected vs actual, root cause, and the evidence/attachments after redaction) โ€” together for the user's review. Default is **one GitHub issue per demonstrated bug**, but if two demos seem to share a root cause (or one demo should split into two issues), ask the user before filing rather than deciding unilaterally. If the user asks for every demo in the batch to be filed as a single combined issue, structure it as one issue with a `## Part N` section per demo โ€” each section keeping its own full template (summary, environment, repro, expected/actual, root cause, evidence) so the parts stay independently actionable/closeable via checkboxes despite sharing one issue number. Ask the user if it's unclear whether they want this per-section structure or a single merged narrative instead. **HARD STOP** โ€” do not file anything until the user confirms the exact final body and attachments for this batch. ## 7. File One GitHub issue per confirmed bug (per the discussion in step 6), each following a standard template: - **Summary** - **Environment** (branch/commit, department, user role, instance if relevant) - **Steps to reproduce** โ€” minimal and deterministic (strip anything not required to trigger the bug) - **Expected** vs **Actual** - **Root cause** โ€” code file/line pointer, with a short explanation - **Evidence** โ€” inspect **every** captured artifact for identifiable data (patient names, NICs, phone numbers, financial details, etc.) before it goes anywhere near the issue: screenshots, accessibility snapshots, the user's verbatim description, environment context, and the assembled issue body text itself โ€” not just screenshots. If clean, keep it; if it contains identifiable info, redact it, or ask the user how to handle it if clean redaction isn't straightforward. `gh issue create --body` is text-only โ€” it cannot upload local screenshots. Publish screenshots through the existing wiki flow instead, same as every other HMIS skill: copy the sanitized images into `../hmis.wiki/images/`, commit and push the wiki, then embed the raw wiki URLs (`https://raw.githubusercontent.com/wiki/hmislk/hmis/images/.png`) in the issue body โ€” see [playwright-e2e-workflow ยง8](../../../developer_docs/testing/playwright-e2e-workflow.md#8-publishing-screenshot-evidence). Before filing, re-read the assembled body against [What May Go Into a GitHub Issue, PR, or Comment](../../../developer_docs/git/github-public-content-policy.md) โ€” the repo is public, so the body must carry no patient/doctor/staff names, production record identifiers (bill/BHT/PHN numbers, entity IDs), affected-record counts, production schema names, cutover dates or per-staff statistics. A demo session collects exactly those things, so this pass is not a formality. File with `gh issue create --repo hmislk/hmis --title "" --body-file <file>` (use `--body-file` for the multiline body assembled above). Verify the created issue โ€” including that its embedded images render โ€” before removing the session's temporary screenshots from the project `tmp/` folder.