Each governance sub-component had its own h2 title + subtitle that duplicated the tab label and the parent "Policy Governance" context. Removed the redundant headers from 13 tab components while preserving action buttons (Configure Budget, Add Weight, New Profile, etc.) as standalone right-aligned action bars. Detail sub-routes (risk-profile-editor, conflict-resolution-wizard) keep their titles since they are not tab panels. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
StellaOps Web
Offline-first expectations mean the workspace must restore dependencies and run tests without surprise downloads. Follow the deterministic install flow below before running commands on an air-gapped runner.
Deterministic Install (CI / Offline)
- Pick an npm cache directory (for example
/opt/stellaops/npm-cache) that you can copy into the Offline Kit. - On a connected machine, export
NPM_CONFIG_CACHEto that directory and runnpm run ci:install. This executesnpm ci --prefer-offline --no-audit --no-fund, seeding the cache without audit/fund traffic. - Provision a headless Chromium binary by either:
- installing
chromium,chromium-browser, orgoogle-chrome-stablethrough your distribution tooling; or - downloading one via
npx @puppeteer/browsers install chrome@stable --path .cache/chromiumand archiving the resulting.cache/chromium/directory.
- installing
- Transfer the npm cache (and optional
.cache/chromium/) to the offline runner, exportNPM_CONFIG_CACHE, then executenpm run ci:installagain. - Use
npm run verify:chromiumto confirm Karma can locate a browser.npm run test:cienforces this check automatically.
See docs/DeterministicInstall.md for a detailed operator checklist covering cache priming and Chromium placement.
Development server
Run ng serve for a dev server. Navigate to http://localhost:4200/. The application will automatically reload if you change any of the source files.
Code scaffolding
Run ng generate component component-name to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module.
Build
Run ng build to build the project. The build artifacts will be stored in the dist/ directory.
Running unit tests
npm testexecutesng test --watch=falseonce after verifying a Chromium binary.npm run test:cifirst callsnpm run verify:chromiumto guarantee CI/offline setups fail fast when a browser is missing.npm run test:watchkeeps Karma in watch mode for local development.
verify:chromium prints every location inspected (environment overrides, system paths, .cache/chromium/). Set CHROME_BIN or STELLAOPS_CHROMIUM_BIN if you host the binary in a non-standard path.
Headless Karma recipe (offline-friendly)
For local, deterministic Karma runs without system Chrome:
cd src/Web/StellaOps.Web
CHROME_BIN=$(pwd)/node_modules/playwright/.local-browsers/chromium-1140/chrome-linux/chrome \
LD_LIBRARY_PATH=$(pwd)/.deps/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH \
npx ng test --watch=false --browsers=ChromeHeadless --progress=false \
--include src/app/features/policy-studio/editor/policy-editor.component.spec.ts \
--source-map=false
- The
.depsfolder carries the minimal NSS/GTK libs we vendor for air-gapped nodes. - Use one
--includeper invocation; Angular CLI rejects multiple--includeflags. - Monaco is file-replaced with a lightweight test stub during Karma runs; production builds are unaffected.
Runtime configuration
The SPA loads environment details from /config.json at startup. During development we ship a stub configuration under src/config/config.json; adjust the issuer, client ID, and API base URLs to match your Authority instance. To reset, copy src/config/config.sample.json back to src/config/config.json:
cp src/config/config.sample.json src/config/config.json
When packaging for another environment, replace the file before building so the generated bundle contains the correct defaults. Gateways that rewrite /config.json at request time can override these settings without rebuilding.
End-to-end tests
Playwright drives the high-level auth UX using the stub configuration above. Ensure the Angular dev server can bind to 127.0.0.1:4400, then run:
npm run test:e2e
The Playwright config auto-starts npm run serve:test and intercepts Authority redirects, so no live IdP is required. For CI/offline nodes, pre-install the required browsers via npx playwright install --with-deps and cache the results alongside your npm cache.
Standard live-search acceptance lane
Use this lane when you need browser verification against a freshly ingested local AdvisoryAI corpus instead of mocked search responses:
npm run test:e2e:search:live
What it does:
- starts or reuses the dedicated AdvisoryAI knowledge-test Postgres via
devops/compose/docker-compose.advisoryai-knowledge-test.yml - starts or reuses the local AdvisoryAI WebService on
http://127.0.0.1:10451 - compiles the local CLI if
.artifacts/stella-cli/is missing - runs
advisoryai sources prepare --json - rebuilds
POST /v1/advisory-ai/index/rebuildandPOST /v1/search/index/rebuild - proves a grounded smoke query before the browser suite runs
- executes the live search Playwright spec through
playwright.live-search.config.ts
Prerequisites:
docker composedotnet- Playwright browsers installed locally
Optional environment overrides:
PLAYWRIGHT_LIVE_SEARCH_SKIP_DOCKER=1if the dedicated AdvisoryAI test database is already runningLIVE_ADVISORYAI_SEARCH_BASE_URLto target a non-default local AdvisoryAI hostAdvisoryAI__KnowledgeSearch__ConnectionStringto override the dedicated test database connection string
Running end-to-end tests
Run ng e2e to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
Further help
To get more help on the Angular CLI use ng help or go check out the Angular CLI Overview and Command Reference page.