Skip to content

feat: VS Code extension for OIDC/OAuth debugging via CDP - #13

Merged
ryanbas21 merged 45 commits into
mainfrom
feat/vscode-extension
May 11, 2026
Merged

feat: VS Code extension for OIDC/OAuth debugging via CDP#13
ryanbas21 merged 45 commits into
mainfrom
feat/vscode-extension

Conversation

@ryanbas21

@ryanbas21ryanbas21 commented May 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • Extract shared packages from the browser extension into reusable monorepo packages (devtools-core, devtools-ui)
  • Build a VS Code extension (vscode-extension) that connects to Chrome via Chrome DevTools Protocol for live OIDC/OAuth flow debugging
  • E2E test infrastructure with Playwright for the browser extension

Architecture

┌─────────────────────────────────────────────────────┐
│ VS Code Extension Host │
│ CDP Client → Event Store → Diagnosis Engine │
│ ↓ ↓ │
│ TreeView (Timeline) WebView (Elm: Flow + Learn) │
└──────────────┬──────────────────────────────────────┘
│ CDP WebSocket
▼
│ Chrome (--remote-debugging-port) │
│ Network domain → HAR-like events │
│ Runtime.bindingCalled → SDK events (injected) │

Package changes

PackageChangePurpose
devtools-coreNewAnnotators, diagnosis engine, event store, export logic (161 tests)
devtools-uiNewShared Elm UI — compiled JS, CSS, TypeScript port interface
vscode-extensionNewVS Code extension with CDP client, TreeView, WebView, status bar
devtools-extensionRefactoredNow thin — imports shared logic from devtools-core and devtools-ui
devtools-typesUnchangedSchema definitions

VS Code extension features

  • CDP network capture — connects to Chrome's debug port, captures auth-related traffic
  • SDK event injection — injects a script via Page.addScriptToEvaluateOnNewDocument to capture devtools-bridge events without a browser extension
  • Timeline TreeView — native VS Code tree with status icons, badges, and event descriptions
  • Flow WebView — loads the same Elm UI as the browser extension, with VS Code theme integration
  • Status bar — connection state and event count
  • Export — JSON envelope and Markdown report with redaction and diagnosis
  • Debug configurationoidc-devtools launch type for launch.json

Test plan

  • 308 tests passing across 27 test files
  • pnpm typecheck clean
  • pnpm build succeeds for all packages
  • Browser extension builds and e2e tests pass (no regression)
  • Manual: install VS Code extension, connect to Chrome with --remote-debugging-port=9222, verify timeline populates
  • Manual: click timeline item, verify Flow WebView opens with Elm UI
  • Manual: run export command, verify JSON/Markdown output

🤖 Generated with Claude Code

ryanbas21and others added 30 commits May 10, 2026 18:52
… endpoints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rinfo requests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace __dirname with import.meta.dirname (ESM modules)
- Use spawnSync with process.execPath instead of execSync
- Fix relative paths from e2e/tests/ and e2e/fixtures/ (need ../../)
- Move build step to CI (Playwright workers can't spawn node)
- Simplify firefox-build test to verify output only (no in-test builds)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ests from Chrome run
- Remove spawnSync build from extension fixture (CI builds before e2e)
- Exclude "firefox build" tests from Chrome e2e run (they need Firefox build first)
- Run firefox-build tests after the Firefox build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… dir
- Share browser context across tests in same worker (avoid re-launching)
- Use mkdtempSync for user data dir instead of empty string
- Add --no-first-run and --disable-default-apps flags
- Set workers: 1 to serialize Chrome tests
- Remove unused launchOptions from playwright config (fixture handles launch)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add CLAUDE.md with agent skills config (issue tracker, triage labels, domain docs)
- Add docs/agents/ with GitHub issue tracker, triage labels, and domain doc conventions
- Add mattpocock/skills (.agents/skills/) for diagnose, tdd, triage, etc.
- Add .claude/skills/ symlinks for Claude Code skill discovery
- Ignore .claude/settings.local.json (machine-specific permissions)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ght builtin collision
Playwright registers 'context' as a built-in test-scoped fixture.
Renaming to 'extensionContext' avoids the conflict and uses a
module-level singleton to share the browser instance across tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Design for bringing OIDC DevTools to VS Code using CDP for network
capture and SDK event injection. Covers package extraction strategy
(devtools-core, devtools-ui), TreeView + WebView hybrid UI, and
five-phase implementation plan that keeps the browser extension
working throughout.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
15-task plan covering 5 phases: extract devtools-core, extract
devtools-ui (Elm), scaffold vscode-extension with CDP, wire WebView
to shared Elm UI, and add launch configuration. Each task has
concrete code, exact file paths, and verification steps.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy all annotator source files and tests into packages/devtools-core/src/annotators/.
Also copy jwt-utils from shared/, and diagnosis-engine into src/background/ so the
integration test resolves. Fix import paths: dpop-detector and diagnosis-engine
previously imported from ../shared/jwt-utils.js, now resolved within devtools-core.
Update barrel export in src/index.ts with all annotator public API.
70 tests passing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move diagnosis-engine.ts from src/background/ to src/diagnosis/
- Add diagnosis-engine.test.ts, serialize-diagnosis.ts, serialize-diagnosis.test.ts
- Add export/markdown.ts, export/markdown.test.ts, export/redact.ts, export/redact.test.ts
- Fix import paths: markdown.ts and markdown.test.ts now import from ../diagnosis/
- Fix oidc-integration.test.ts import from ../diagnosis/diagnosis-engine.js
- Delete src/background/ directory
- Extend barrel export with diagnosis and export public API
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add EventStoreInMemory layer with no-op persist/rehydrate (no chrome.storage)
- Export updateSummary for reuse by the chrome-backed layer in Task 5
- Add message-handler with corrected imports pointing to annotators/
- Update barrel export in index.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move annotators, diagnosis engine, event store, message handler, and
export logic to @wolfcola/devtools-core. Browser extension now imports
shared logic and provides chrome.storage-backed EventStore layer.
- Add @wolfcola/devtools-core as workspace dependency
- Create EventStoreChromeLive layer with chrome.storage persistence
- Update service-worker.ts and panel.ts imports to use devtools-core
- Delete 28 files that now live in devtools-core
- Update tsconfig references
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create packages/devtools-ui with elm.json (source-directories: src/src,
src), elm-tooling.json, package.json, build.mjs, ports.ts interface,
extracted panel.css, and simplified panel.html. Copy all 13 Elm modules
from devtools-extension. Build verified: elm compiles, terser minifies.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Browser extension now imports compiled Elm and CSS from
@wolfcola/devtools-ui instead of compiling Elm in-tree.
Elm source, elm.json, and panel CSS extracted to devtools-ui.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ryanbas21and others added 15 commits May 10, 2026 20:30
…tegration
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implement the exportFlow command with JSON and Markdown export modes.
Redacts sensitive data via redactFlowState before export, runs diagnosis
for Markdown output, and opens the result in an untitled VS Code document.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Root README: updated with full package table, architecture diagram,
and references to both browser and VS Code extensions
- devtools-core: new README documenting annotators, diagnosis, event
store, and export modules
- devtools-ui: new README documenting Elm views, ports, and build
- vscode-extension: new README with quick start, commands, architecture
- devtools-extension: updated architecture section to reference shared
packages (devtools-core, devtools-ui)
- devtools-bridge: updated to reference VS Code extension and CDP
capture path
- devtools-types: added FlowState/FlowExport/OidcSemantics to exports
table and consumers section
- e2e: new README documenting test suite and mock OIDC server
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace #app selector with .toolbar in all tests — Elm replaces the
mount point on init, so #app is never visible to Playwright
- Fix SDK event payload to match AuthEventSchema (add _tag, source,
flags, causedBy fields)
- Use relative row count assertions to handle shared browser context
state from prior tests
- Restrict Firefox project to firefox-build tests only (extension e2e
not supported by Playwright)
- Skip Firefox manifest test when Firefox build not present
- Add panel.css to expected dist files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ing first candidate
findChromePath() now uses `which` (or `where` on Windows) to check
each candidate actually exists before returning it. Fixes detection
on Arch Linux where the binary is `chromium` not `google-chrome`.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The VS Code extension was calling buildNetworkEvent directly, bypassing
the OIDC annotation pipeline (annotateOidc, detectDpop, detectPar),
well-known config discovery, and causal linking. Now uses the same
handleMessage + EventStoreInMemory pipeline as the browser extension.
Also adds .vscode/launch.json for Extension Development Host, fixes
viewsContainers icon to use SVG file instead of invalid codicon syntax,
and removes "type": "module" which prevented CJS extension from loading.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
findPageTarget was connecting to DevTools inspector pages instead of
the actual web app. Now filters to only http:// and https:// URLs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ting
- VS Code README: complete rewrite with step-by-step setup, browser
launch commands for Chromium/Chrome/Edge/macOS, mock OIDC server
instructions, troubleshooting section, and handleMessage pipeline
documentation
- Root README: fix VS Code quick start to use --extensionDevelopmentPath
instead of F5, add --user-data-dir note for separate browser instance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Set publisher to RyanBasmajian
- Bump version to 0.1.0, remove private flag
- Add repository, keywords, marketplace icon
- Add @vscode/vsce with package/publish scripts
- Add LICENSE
- Add .vsix to .gitignore
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix publisher to lowercase 'ryanbasmajian' to match Marketplace ID
- Convert marketplace icon from 16-bit to 8-bit PNG (fixes upload error)
- Lower engines.vscode to ^1.85.0 for broader compatibility
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove unused imports (Effect, EventStoreService) from extension.ts
- Add eslint-disable for declaration merging in cdp-client.ts
(TypeScript pattern for typed EventEmitter)
- Format target-discovery.ts with prettier
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The VS Code extension is published via vsce to the Marketplace, not npm.
Setting private:true prevents accidental npm publish while vsce ignores it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ryanbas21
ryanbas21 merged commit 3132936 into mainMay 11, 2026
1 check passed
@github-actionsgithub-actionsBot mentioned this pull request May 11, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@ryanbas21