[English] · 한국어
Angular adapter for agent-devtools. Mounts the floating widget into a closed Shadow DOM, walks the Ivy component tree to resolve picked components, and reuses the framework-agnostic widget shell.
Dev-only. The mount entry refuses to run when
NODE_ENV === 'production'. Bundler integrations (Angular CLI builder, Webpack) further strip imports from production builds — seedev-only-guard.
- DOM → component bridge —
getComponentInstanceForElementresolves the owning component from Ivy's debug API (window.ng.getOwningComponent/getComponent). Only exposed beforeenableProdMode(), which is the same condition the dev-only guard enforces. - Ancestor walker —
walkComponentAncestorsclimbs the Ivy component chain leaf-first via the publicgetOwningComponentAPI, capped at depth 10. - Source extraction — Angular does not ship JSX-style
_debugSource.resolveInstanceSourceresolves the component class name viaɵcmpmetadata; source line/column is omitted rather than guessed (fallback path in picker-coverage, Case C). - Component name —
resolveComponentName:component.constructor.name→ first selector →'Unknown'. mountAgentDevtoolsAngular— mounts the launcher, composer, and settings widget into a closed Shadow DOM via the@agent-devtools/widget-coreshell. Angular's zone is never patched by the widget.- Production guard —
mountAgentDevtoolsAngularthrows whenNODE_ENV === 'production'.
See picker-strategy.md for the cross-adapter contract.
pnpm add -D @agent-devtools/angularPeer dependency: @angular/core >= 17 (getOwningComponent ships and getComponent stays public).
The Angular CLI does not ship a first-party plugin for agent-devtools. The recommended host pattern below combines a runtime isDevMode() gate with a build-time fileReplacements entry so the mount module is replaced by an empty stub in production builds — that is the Layer 1 + Layer 2 guard contract described in dev-only-guard.
src/agent-devtools.dev.ts:
import { mountAgentDevtoolsAngular } from '@agent-devtools/angular';
mountAgentDevtoolsAngular();src/agent-devtools.prod.ts:
// Intentionally empty. The production build replaces the dev entry with
// this file via angular.json fileReplacements, so the widget chain never
// reaches the production bundle.src/main.ts:
import { isDevMode } from '@angular/core';
import './agent-devtools.dev';
if (isDevMode()) {
// mountAgentDevtoolsAngular was imported above for tree-shake safety;
// the dev file calls it as a side effect.
}angular.json:
{
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/agent-devtools.dev.ts",
"with": "src/agent-devtools.prod.ts"
}
]
}
}
}The walker uses window.ng.getOwningComponent / getComponent from Ivy's debug API, which is only present when Angular is bootstrapped without enableProdMode().
Published as part of the fixed-mode @agent-devtools/* release line. Walker, picker, widget and Vite-plugin integration are in place — see packages/angular/src/**/*.test.ts for the verified surface.
MIT © Seungwoo Lee