| name | cdp_dev_cycle |
| description | null |
[!IMPORTANT]
THE PRIME DIRECTIVE
All agent-driven development cycle verification MUST occur exclusively within the Extension Development Host. Accidental execution or discovery in the Main IDE is a critical failure.
0. Audit Pre-Flight Reflex (MANDATORY — AUTONOMOUS)
[!CAUTION]
The agent MUST execute this reflex autonomously before ANY lifecycle audit session.
Do NOT wait for the user to prompt restart. Auditing against warm/stale boot state produces meaningless results.
Skipping this pre-flight is a protocol violation equivalent to operating blind.
Before any CDP-driven audit (T-009, T-010, T-011, T-012, or any future lifecycle observation):
- Snapshot log cursor (PowerShell):
$cursor = (Get-Item diagnostics_agent.log).Length
- Open CDP shell (if not already open):
npm run cdp:shell
- Smart Start: shell auto-detects if Dev Host is open.
- Host found → logs
🟢 Dev Host already open — connected.
- No host → auto-fires
launch + wait-for-ready before dropping to prompt.
- Confirm
✅ SYSTEM READY before issuing any audit commands.
- All log reads MUST use
$cursor as the start offset — never read the full log.
[!NOTE]
After the shell opens, always run status first.
✅ SYSTEM READY → proceed directly, no launch needed.
- Host found but webview not hydrated →
wait-for-ready.
- No host found →
launch → wait-for-ready.
Only use restart when the task explicitly requires observing cold-boot behavior. Do not use by default.
1. Sovereignty Hierarchy
- Tier 1 (Host):
[Extension Development Host] — The primary target for verification.
- Tier 2 (Meta):
[Main Editor] — PROTECTED. Authorized ONLY for meta-commands (launch).
- Tier 3 (Webview):
[virgo] — The isolated execution context. Often nested and requires specific targeting.
2. The Persistent CDP Shell Workflow
[!IMPORTANT]
Shell Sovereignty — The Only Interface.
npm run cdp:shell is the agent's sole interface to the extension. All operations — status checks, evals, dispatches, audits — are issued as shell inputs inside the running session. Never bypass the shell by running node scripts/cdp-controller.mjs <cmd> as a one-shot CLI call. If you find yourself doing that, you are off-protocol.
To maintain high-integrity state awareness, keep a single cdp:shell open for the duration of the session.
Controller location: .agent/skills/cdp_dev_cycle/cdp-controller.mjs — invoked via npm run cdp:shell. Do not call the script directly.
🛠 Phase 1: High-Integrity Setup
- Open shell: Run
npm run cdp:shell.
- Run
status: Assess the current environment.
✅ SYSTEM READY → proceed directly.
- Host found, webview not hydrated →
wait-for-ready.
- No host found →
launch → wait-for-ready.
- The Wait-for-Ready Ritual: Send
wait-for-ready only if needed per step 2.
- Signal: When the shell reports
✅ SYSTEM READY, the UI is fully hydrated and ready for commands.
🛠 Phase 2: The Rapid-Reload Loop ⭐
Once initialized, NEVER close the Dev Host unless necessary. Use this cycle:
- Code: Save changes in
src/.
- Build: Verify
npm run watch (or equivalent) completes the rebuild.
- Reload: Send
dispatch workbench.action.reloadWindow to the active shell — this fully restarts the extension host.
- Audit (MANDATORY):
- State Audit: Run
verify-state to confirm Redux store hydration.
- Visual Audit: Check for layout regressions or styling drift.
🛠 Phase 2b: Cold Restart (Exceptional — Boot Audit Only) ⚠️
[!CAUTION]
Only use this path when the task explicitly requires observing cold-boot behavior (e.g., boot timing, startup sequence audit). Do not use by default.
A reload restarts the extension in-place. For a true cold-boot audit, you need a full process restart:
- Snapshot the log cursor:
(Get-Item diagnostics_agent.log).Length
- Send
restart to the shell — this runs: close-host → 2s wait → launch → wait-for-ready.
- Read the log slice from the cursor to capture all boot-window events.
[!IMPORTANT]
exit closes the shell script AND the Dev Host — it is a full cleanup ritual.
It stops any running playback first, then gracefully closes the Dev Host, then exits.
To close the Dev Host without exiting the shell: use close-host.
🛠 Phase 3: The Audit-Audit Ritual
DISPATCH-AUDIT MIRROR: Every dispatch (or exec) action MUST be followed by a state verification.
- Rationale: Extension commands are asynchronous. The UI might confirm "OK" while the underlying state is still syncing.
- Action:
dispatch Virgo: Play -> wait-for-ready (or manual poll) -> verify-state.
🛠 Phase 4: Exit Ritual
Default end-of-session: use close-host
- Closes the Extension Development Host cleanly.
- The shell exits naturally once work is done.
- Use this unless you also need to kill the shell process itself.
Full teardown: use exit (only when shell process also needs to die)
[!CAUTION]
Always use close-host or exit to terminate — never Ctrl+C or kill the process.
What exit does automatically:
- Clicks
btn-stop in the webview (stops any running playback)
- Calls
gracefulClose to shut down the Extension Development Host
- Releases the
.cdp_shell.lock file
- Exits the Node process cleanly
If the Dev Host is already closed (e.g. crashed), the exit ritual handles it gracefully and still exits cleanly.
3. Command Pipeline: Discovery Ritual
To prevent cross-pollution, always audit the field before acting.
🛠 Graceful Instance Management
status: Full situation report (Host status, Webview hydration, Active PIDs).
targets: Lists all active CDP pages and their frame counts. Essential for locating the active webview.
scan: Quick list of active [Extension Development Host] windows and their PIDs.
frames: Provides a recursive dump of all accessible frames. Use this if find fails.
🛠 Graceful Exit Ladder
When closing the dev host, the script follows a polite 3-tier ladder:
- Tier 1 (UI Action):
workbench.action.closeWindow. SAFEST way to exit.
- Tier 2 (CDP Signal):
Target.closeTarget fallback for unresponsive UI.
- Tier 3 (OS Signal):
taskkill /T (without /F) for clean process termination.
4. Shell Command Reference (send as shell input — not CLI arguments)
| Goal | Command | Output / Expectation |
|---|
| Inventory | targets | List all pages and frame counts |
| SitRep | status | Full environment health check & PIDs |
| Wake Host | launch | Smart F5 launch protocol |
| Ready Up | wait-for-ready | Polls for system hydration signal |
| Reload Ext | dispatch workbench.action.reloadWindow | Restarts extension host in-place |
| Close Host | close-host | Gracefully closes Dev Host window + PIDs |
| Smart Restart | restart | close-host (if open) → launch → wait-for-ready |
| State Dump | verify-state | Dumps the current Redux store |
| Dispatch | dispatch <cmd> | Atomic command triggering |
| Eval | eval <expr> | JS execution in webview context |
| Audit Dump | audit | Dumps live __debug state: hydration, gesture gate, playback intent, audio element |
| Click Play | click-play | DOM-clicks btn-play — satisfies browser gesture gate (use for first-run tests) |
| Visual Audit | screenshot [file] | Take a screenshot of the Dev Host to file (default: screenshot.png) |
| Full Exit | exit | Stop playback + close Dev Host + exit shell |
eval <expr> runs JavaScript inside the live webview context of the running shell session. It is not a standalone script runner — it requires an open shell with a hydrated webview. Use audit for structured state inspection; use eval only for one-off queries.
Event Probing Pattern (for DOM/interaction audits — e.g. mouseenter, gesture gates):
eval document.addEventListener('mouseenter', () => window.__PROBE_COUNT = (window.__PROBE_COUNT||0)+1)
// move mouse over panel, then:
eval JSON.stringify({ count: window.__PROBE_COUNT })
// cleanup:
eval (() => { window.__PROBE_COUNT = undefined; })(); 'PROBE_REMOVED'
Use this to verify event propagation across the webview boundary before wiring production handlers.
5. Troubleshooting the Signal
- "NOT FOUND" (Webview): If
status shows Webview: ❌, run dispatch ...show-dashboard. Webviews are lazily loaded.
- Leaked Shells: If port 9222 is blocked, run
scan to find the culprit PID and close it gracefully.
- Garbled Logic: If shell output is corrupted, it usually indicates a race. Use
wait-for-ready to synchronize.
[!TIP]
Checkbox Sovereignty: Always verify build success in the "Tasks" terminal before running refresh. If the builder is red, the reload will serve stale code.
6. Visual Diagnostics via Screenshots
To enable visual audits of the Extension Development Host when running in headless or background states, the agent can capture screenshots of the active workbench window.
- Shell command:
screenshot [file.png] (saves to the specified path, defaults to screenshot.png)
- CLI fallback:
node .agent/skills/cdp_dev_cycle/cdp-controller.mjs screenshot [file.png] (can be run directly if the lock is not held)
Use this command to verify command palette overlays, sidebar visibility, theme alignment, or layout regressions.
7. Persistent CDP Integration Testing
To prevent regressions in live synchronization, UI interaction logic, and state management, persistent integration tests using raw CDP (Chrome DevTools Protocol) are maintained under tests/integration/.
7.1 Test Anatomy and Core Rules
Every CDP integration test must adhere to these four architectural principles:
-
Dynamic Active Session / Workspace Resolution:
-
Conditional Active Port Skipping:
- To ensure integration tests do not break automated build servers or offline environments, check if the CDP port is listening before running.
- Guard the suite using
describe.runIf(isCdpActive) or similar Vitest/Jest conditional gates:
const checkCdpPort = (): Promise<boolean> => {
return new Promise((resolve) => {
const req = http.get("http://localhost:9222/json/version", (res) => {
resolve(res.statusCode === 200);
});
req.on('error', () => resolve(false));
req.setTimeout(1000, () => { req.destroy(); resolve(false); });
});
};
-
User Interaction Simulation:
- Satisfy Chromium's security gate for user interactions (e.g. playback start, clipboard copy) by dispatching real user gestures directly in the webview window before executing UI-dependent logic:
await webviewFrame.evaluate(() => {
const event = new MouseEvent('mousedown', { view: window, bubbles: true, cancelable: true });
document.dispatchEvent(event);
});
-
Resource Lifecycle Integrity:
- Always wrap browser connections and filesystems in cleanup blocks.
- Use
afterAll to close connections (browser.close()) and clean up any injected test artifacts (e.g. unlinking temp files like *.cdp_test.md).
- To prevent test pollution and cache index collisions, always name injected snippet files dynamically using timestamps (e.g.,
${Date.now()}.cdp_test.md).