diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c7fd0ee6..489b525d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,6 +122,7 @@ jobs: runs-on: ubuntu-latest env: LIBS: chat,langgraph,ag-ui,render,a2ui,telemetry + FOUNDATIONS: core,content,angular,react steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 @@ -130,9 +131,21 @@ jobs: cache: npm - run: npm ci - run: npx nx run-many -t lint --projects=$LIBS + - name: React migration baseline and boundaries + run: | + node --test scripts/react-parity/*.spec.mjs fixtures/react-parity/traces.spec.mjs + node scripts/react-parity/inventory.mjs --check + node scripts/react-parity/verify-boundaries.mjs + - name: Build and validate private React foundations + run: npx nx run-many -t lint test type-tests build --projects=$FOUNDATIONS --parallel=2 - run: npx nx test langgraph --coverage --maxWorkers=2 --reporter=default - run: npx nx run-many -t test --projects=chat,ag-ui,render,a2ui,telemetry --coverage --parallel=1 --maxWorkers=2 - run: npx nx run-many -t build --projects=$LIBS --configuration=production + - name: Verify emitted boundaries and isolated packages + run: | + node scripts/react-parity/verify-boundaries.mjs --built + node scripts/react-parity/verify-packages.mjs + node scripts/react-parity/verify-angular-package.mjs - run: node scripts/verify-release-versions.mjs - name: DX-coverage — public dev-facing functions must have a JSDoc summary run: node scripts/check-dx-coverage.mjs diff --git a/eslint.config.mjs b/eslint.config.mjs index 6fc832f55..b2c2b2dae 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -34,6 +34,31 @@ export default [ '^.*/pricing/tiers\\.config$', ], depConstraints: [ + { + sourceTag: 'layer:core', + onlyDependOnLibsWithTags: ['layer:core'], + bannedExternalImports: ['@angular/*', 'react', 'react-dom', 'rxjs', '@langchain/*', '@ag-ui/*'], + }, + { + sourceTag: 'layer:content', + onlyDependOnLibsWithTags: ['layer:core', 'layer:content'], + bannedExternalImports: ['@angular/*', 'react', 'react-dom', 'rxjs', '@langchain/*', '@ag-ui/*'], + }, + { + sourceTag: 'layer:backend', + onlyDependOnLibsWithTags: ['layer:core', 'layer:content', 'layer:backend'], + bannedExternalImports: ['@angular/*', 'react', 'react-dom'], + }, + { + sourceTag: 'layer:angular', + onlyDependOnLibsWithTags: ['layer:core', 'layer:content', 'layer:render', 'layer:a2ui', 'layer:angular'], + bannedExternalImports: ['react', 'react/*', 'react-dom', 'react-dom/*', '@types/react', '@types/react-dom', '@langchain/*', '@ag-ui/*'], + }, + { + sourceTag: 'layer:react', + onlyDependOnLibsWithTags: ['layer:core', 'layer:content', 'layer:react'], + bannedExternalImports: ['@angular/*', '@langchain/*', '@ag-ui/*'], + }, { sourceTag: '*', onlyDependOnLibsWithTags: ['*'], diff --git a/fixtures/react-parity/README.md b/fixtures/react-parity/README.md new file mode 100644 index 000000000..da5461da4 --- /dev/null +++ b/fixtures/react-parity/README.md @@ -0,0 +1,224 @@ +# React parity foundations + +This directory supports the first migration increment: a reviewed Angular baseline +and four private, empty package scaffolds. It does not provide React components, +state management, or extracted backend runtimes. +The existing Angular packages and release group remain the production path. + +## Reviewed baseline + +The current facts were generated from the uncommitted foundation working tree at +base HEAD `7e80cebd607f5c605ef1ec81f11e5ebe3324f81b`. The baseline records the four +reviewed configuration changes: CI foundation projects and Angular consumer gate, +the direct semver tooling dependency, workspace lockfile links, and package aliases. +No inventoried API or implementation changed. This follows the main integration +at `a93977ff1e75796336ddd93a882eab2e40f0ca7b`, including v0.2.0 and its package-version +alignment fix. The inventory contains **1,438 records**: 550 public export +occurrences (514 distinct local definitions), 102 decorated components in 100 +files, 461 non-test source files, 128 package assets, 16 distribution/configuration +files, 12 entry points, 41 cockpit topics, and 128 documentation pages. These +counts cover the 16 existing libraries selected for migration; the four new empty +packages are checked separately by the boundary and packaging gates. + +The earlier research snapshot at `b1685838069c6b1ec56d5e97a1a01170b26aa125` +had 547 export occurrences and 1,435 records. Integration added `AgentRecovery`, +`AGENT_RECOVERY_MESSAGES`, and `AGENT_RECOVERY_DETAILS`. Reviewed changed contracts +also include optional `Agent.checkStatus`, `AgentError.recovery/detail`, recovery +UI actions, unexpected stream closure handling, and development-session observation. +The ownership ledger records these additions. A status check must remain read-only: +a dropped stream does not justify resubmitting work that may already have run. + +## Inventory workflow + +Run from the repository root after `npm ci`: + +```sh +node --test scripts/react-parity/*.spec.mjs fixtures/react-parity/traces.spec.mjs +node scripts/react-parity/inventory.mjs --check +node scripts/react-parity/verify-boundaries.mjs +``` + +`baseline.json` records source facts and generation provenance; `dispositions.json` +assigns every fact to migration tasks. Both live in `scripts/react-parity/`. +`planned` means assigned future work, not implemented parity. Declaration hashes +include implementation bodies/templates; source and lockfile hashes catch changes +outside declaration names. The checker is a migration drift gate, not a semver +compatibility analyzer. It does not inspect external package declarations. + +When a gate detects drift, review the changed API, implementation, asset, docs or +configuration. Update its disposition explicitly, then run: + +```sh +node scripts/react-parity/inventory.mjs --write-baseline +node scripts/react-parity/inventory.mjs --check +``` + +Writing facts never rewrites dispositions. Review the diff, especially removed or +renamed entries, before committing both. CI routes changes to the inventory's +selected libraries, docs, topic definitions and configuration into these gates, +including rootless scripts and fixtures. This intentionally requires review when +an Angular fix or dependency update changes the migration baseline. + +## Private package boundaries + +| Current private scaffold | Intended responsibility | +| --- | --- | +| `@threadplane/core` | Framework-free data, observation, execution and tool contracts | +| `@threadplane/content` | Shared Markdown, JSON, A2UI and rendering data processing | +| `@threadplane/angular` | Native Angular binding and presentation | +| `@threadplane/react` | Native React binding, rendering and presentation | + +All four are private version `0.0.0`, with empty entry points. Core, content and +React use plain ESM packaging; Angular uses Angular Package Format (APF). Their +intended responsibilities are not implemented. The source/declaration verifier follows +module edges, including type-only imports, aliases and re-exports. It blocks +framework dependencies in neutral layers, UI dependencies in backend layers, +backend SDKs in framework layers, Angular/React crossover, and optional/testing +paths reachable from package roots. The populated chat, LangGraph, AG-UI and render +packages retain explicit Angular transition allowances, as does telemetry/browser. +Nx lint constraints provide an additional source gate. The final release gate +remains blocked until those transition allowances and retired packages are removed. + +The final package map is a separate destination, not the implemented topology: + +| Final package | Responsibility | +| --- | --- | +| `@threadplane/core` | Dependency-free data, observation, execution and tool contracts | +| `@threadplane/langgraph` | Neutral LangGraph transport and lifecycle | +| `@threadplane/ag-ui` | Neutral AG-UI transport and recovery | +| `@threadplane/render` | Neutral render data and registry contracts | +| `@threadplane/a2ui` | A2UI protocol data and processing | +| `@threadplane/content` | Optional Markdown, JSON and A2UI processing | +| `@threadplane/angular` | Angular binding, render components and UI | +| `@threadplane/react` | React binding, render components and UI | +| `@threadplane/telemetry` | Neutral collector; native Angular providers belong to `@threadplane/angular` | + +There are no suffixed backend packages or separate React renderer in that map. +The first runtime proof keeps the execution owner and publisher private to the +backend; these foundations do not introduce a general shared store. +The new tool contract deliberately omits a schema DSL, automatic argument +validation/transformation and validator-to-JSON-Schema conversion. Callers may +supply optional JSON Schema metadata and own any validation in their handlers. +The ledger retains these legacy capabilities as explicit migration omissions; +current Angular behavior is unchanged. Protocol schema assets, form validation and +transport decoding remain in scope. + +```sh +NX_DAEMON=false CI=true npx nx run-many -t lint test type-tests build --projects=core,content,angular,react --parallel=2 --skip-nx-cache +NX_DAEMON=false CI=true npx nx run-many -t build --projects=chat,langgraph,ag-ui,render,a2ui,telemetry --configuration=production --parallel=1 --skip-nx-cache +node scripts/react-parity/verify-boundaries.mjs --built +node scripts/react-parity/verify-packages.mjs +node scripts/react-parity/verify-angular-package.mjs +``` + +The plain packaging check packs core, content and React, validates their nine export +paths, README/license inclusion and production exclusions, then imports and +type-checks the tarballs outside workspace aliases with `skipLibCheck: false`. +Its core-only consumer checks all three core exports and rejects extra dependencies. +The separate Angular check packs the one Angular APF entry and proves CLI +compilation/linking with `skipLibCheck: false`. Both inspect consumer module inputs +for unwanted parsers. Installation footprints include actual installed files; +lockfile locations also include optional platform packages. The Angular footprint +includes CLI/compiler/build tooling. These measurements prove scaffold packaging +and isolation, not runtime performance, React SSR or shared-runtime correctness. + +## Existing Angular regression checks + +```sh +NX_DAEMON=false CI=true npx nx run-many -t test --projects=chat,langgraph,ag-ui,render,a2ui,telemetry --parallel=1 --maxWorkers=2 --skip-nx-cache +NX_DAEMON=false CI=true npx nx run-many -t type-tests --projects=chat,langgraph,ag-ui --parallel=1 --skip-nx-cache +NX_DAEMON=false CI=true npx nx run-many -t build --projects=chat,langgraph,ag-ui,render,a2ui,telemetry --configuration=production --parallel=1 --skip-nx-cache +node --test examples/chat/smoke/*.spec.mjs scripts/verify-angular-support.spec.mjs +NX_DAEMON=false CI=true npx nx run telemetry:test-install-pack --skip-nx-cache +CI=true node examples/chat/smoke/cli.mjs --non-interactive --fresh --target tmp/react-parity/angular-21 --local-dist-root dist/libs --angular-major 21 --install --build --runtime +``` + +`--fresh` replaces the disposable generated consumer. The consumer uses local +Threadplane tarballs but independently resolves external ranges; that graph can +differ from the workspace lockfile. Its browser smoke is backend-free. Angular +20/21/22 remain separate existing CI lanes. See [baseline-evidence.json](./baseline-evidence.json) +for commands actually executed, environment and limitations. + +## Deterministic traces and performance limits + +`traces/*.sse` are newly authored synthetic fixtures with no captured user data or +credentials. Tests use the locked LangGraph SDK and AG-UI HTTP client, splitting +responses into three-byte chunks including a UTF-8 character boundary. They check +text/final state, request identity and terminal reduction without duplicate messages. +They establish decoder behavior, not parity between Threadplane framework bindings. + +The existing LangGraph stream-manager/agent tests cover cancellation, delivery +generations, queues and staged results. AG-UI interruption, resume-wire and +persistence tests cover recovery and request serialization. Client-tool tests cover +claim/record, cancellation and completed-result reuse. Later migration tasks must +replay these behaviors through the extracted runtime and both bindings. + +The parser work test checks linear character processing under duplicate cumulative +argument updates. A single test duration is not a calibrated performance budget. +Consumer bundle warnings describe the canonical example, not the headless package. +T38 still requires stream-to-paint latency, React commit work, long tasks, retained +heap and emitted-module graphs on recorded hardware, including long transcripts, +burst streams and repeated agent/thread disposal. + +## Maintenance and release + +The integrated candidate is `codex/react-support-baseline`. The local maintenance +branch `codex/angular-maintenance-v0.2` points to released tag `v0.2.0` +(`8daea78d35bfa27513474bd624d0e9495af3cfab`) and retains its released lockfile. +Creating that local branch does not establish an operated release lane: a maintainer +must own the backport/publication workflow before it is used. No Angular facade +currently depends on a new package. Version/tag enforcement, remote maintenance +policy and a tested backport/rollback remain T37 work. The existing release group +is unchanged, and none of the scaffolds is publishable. + +## Task identifiers + +The following task index makes the ownership ledger readable independently of local +research documents. It is a scope map, not evidence that the tasks are complete. +T01/T02 are this foundation increment. The next G1 proof is deliberately limited +to shared LangGraph text streaming and fixed function-tool execution with borrowed native +Angular and React bindings: the runtime owns execution while each binding observes +it. Renderer reuse and SSR are deferred gates, alongside the broader T01–T39 map. +No runtime proof or parity is claimed by these foundations. + +| Task | Scope | +| --- | --- | +| T01 | Establish the parity baseline and finding ledger | +| T02 | Create package scaffolding and dependency boundaries | +| T03 | Extract data contracts and error identity; omit tool schema ownership | +| T04 | Implement immutable publication and execution scope | +| T05 | Build behavioral replay and unchanged Angular consumer fixtures | +| T06 | Prove native binding and execution ownership; full SSR is deferred to T21 | +| T07 | Prove renderer reuse before writing the catalog | +| T08 | Extract LangGraph transport and request normalization | +| T09 | Extract LangGraph event reduction and delivery projection | +| T10 | Extract LangGraph cancellation, history, branching, queues and subagents | +| T11 | Rebind Angular LangGraph and extract thread services | +| T12 | Extract AG-UI event processing and transaction state | +| T13 | Extract AG-UI interrupts and durable recovery | +| T14 | Extract AG-UI lifecycle and rebind Angular | +| T15 | Extract client-tool declarations and execution; callers own argument validation | +| T16 | Unify tool coordination and correlate presentation results | +| T17 | Separate neutral telemetry from framework integration | +| T18 | Extract Markdown documents and citation projections | +| T19 | Extract JSON classification and A2UI surface processing | +| T20 | Extract render state, readiness and form-session helpers | +| T21 | Introduce safe SSR dehydration and browser boundaries | +| T22 | Build React component foundations, styles and overlays | +| T23 | Implement transcript, composer and basic chat composition | +| T24 | Implement React render registry, context and element lifecycle | +| T25 | Implement render actions, host events and tool views | +| T26 | Implement all Markdown views and citation UI | +| T27 | Implement A2UI surface and all 18 catalog views | +| T28 | Implement approvals, tools, reasoning and subagent UI | +| T29 | Implement thread/project/search/history/timeline/debug surfaces | +| T30 | Implement popup, sidebar and sidenav compositions | +| T31 | Create canonical React applications and public testing utilities | +| T32 | Add frontend identity to registry and runtime bridge | +| T33 | Build React cockpit host and all 41 scenario variants | +| T34 | Make docs routes, navigation and search framework-aware | +| T35 | Author and generate React documentation and agent context | +| T36 | Expand CI and packed consumer compatibility | +| T37 | Prepare prerelease, publishing, provenance and rollback | +| T38 | Measure and optimize streaming, bundles and retention | +| T39 | Complete accessibility, parity audit and maintenance handoff | diff --git a/fixtures/react-parity/baseline-evidence.json b/fixtures/react-parity/baseline-evidence.json new file mode 100644 index 000000000..d4a9e9fd5 --- /dev/null +++ b/fixtures/react-parity/baseline-evidence.json @@ -0,0 +1,254 @@ +{ + "schemaVersion": 1, + "observedOn": "2026-09-21", + "sourceHead": "7e80cebd607f5c605ef1ec81f11e5ebe3324f81b", + "sourceState": "Uncommitted foundation working tree based on sourceHead; no eventual commit SHA is asserted.", + "scope": "Four private empty scaffolds and regression/boundary/packaging gates; no G1 runtime proof or React parity.", + "environment": { + "os": "Darwin", + "architecture": "arm64", + "cpu": "Apple M1 Max", + "memoryBytes": 34359738368, + "node": "v24.20.0", + "npm": "11.19.0", + "typescript": "5.9.3", + "vitest": "4.1.0", + "nx": "22.5.1", + "nxVitestExecutor": "22.6.0", + "ciNodeNotUsed": "22.22.3" + }, + "rootLockfileSha256": "b16eed343e4be6e7d677ffccd7ed004191682eaf248287b1ed4e0fd3bd9f4b5e", + "checks": [ + { + "id": "foundation-node-suites", + "exitCode": 0, + "logSha256": "bd7b2a542f1321ce4b4d3214e61d374e5ebdc948d6391d34f1cdb361c5d5fa8b", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "reproductionCommand": "node --test scripts/ci-scope.spec.mjs scripts/ci-workflow.spec.mjs scripts/react-parity/*.spec.mjs fixtures/react-parity/traces.spec.mjs", + "note": "384 tests passed; independent rerun below also passed 384." + }, + { + "id": "independent-node-suites", + "exitCode": 0, + "logSha256": "3018af731147c3e8292f9a63ce249915b4e6ec318ad2b078f729f8d5cf7fcb4d", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "node --test scripts/ci-scope.spec.mjs scripts/ci-workflow.spec.mjs scripts/react-parity/*.spec.mjs fixtures/react-parity/traces.spec.mjs" + }, + { + "id": "foundation-targets", + "exitCode": 0, + "logSha256": "569c4cf93d399046a0974c24361d68897ba0f307d52ec7ae837b9149c03fa449", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "reproductionCommand": "NX_DAEMON=false NX_TUI=false CI=true npx nx run-many -t lint test type-tests build --projects=core,content,angular,react --parallel=2 --skip-nx-cache --outputStyle=static", + "note": "16 target configurations across four empty scaffolds; no runtime behavior tests." + }, + { + "id": "source-boundaries", + "exitCode": 0, + "logSha256": "995db896b38cf7de5ca9db6590dba47e082d26abdf69bab04b92eee484696063", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "node scripts/react-parity/verify-boundaries.mjs" + }, + { + "id": "built-boundaries", + "exitCode": 0, + "logSha256": "c983a97d17ff7ced7aa9113afa031f464103f566f1bc94eec8160558ec2553f7", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "node scripts/react-parity/verify-boundaries.mjs --built" + }, + { + "id": "plain-foundation-consumers", + "exitCode": 0, + "logSha256": "90a04e6f3e258aa716f2f59fdb9589bfbe30e30509bf414941f21be23762e1f3", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "node scripts/react-parity/verify-packages.mjs" + }, + { + "id": "angular-foundation-consumer", + "exitCode": 0, + "logSha256": "c6b87b930c2611fde7d3428a974c81280810f99179aa208fb7e47c93d23f0a1b", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "node scripts/react-parity/verify-angular-package.mjs" + }, + { + "id": "inventory-check", + "exitCode": 0, + "logSha256": "f074835105020dcfd8dbbbd8fd594e164ee791e5df68413b52c8ec48eaa4e985", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "node scripts/react-parity/inventory.mjs --check" + }, + { + "id": "library-tests", + "exitCode": 0, + "logSha256": "a92f99b91e44eeee4ead10e54e1f6b1b230ba800c8413f4b642a3bd153028e85", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "NX_DAEMON=false NX_TUI=false CI=true npx nx run-many -t test --projects=chat,langgraph,ag-ui,render,a2ui,telemetry --parallel=1 --maxWorkers=2 --skip-nx-cache --outputStyle=static" + }, + { + "id": "type-tests", + "exitCode": 0, + "logSha256": "e6cd13c8a6492171f33578e6c6f6644b067722013006a2cabc4f50f403ecf26b", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "NX_DAEMON=false NX_TUI=false CI=true npx nx run-many -t type-tests --projects=chat,langgraph,ag-ui --parallel=1 --skip-nx-cache --outputStyle=static" + }, + { + "id": "existing-library-lint", + "exitCode": 0, + "logSha256": "020d0db8c7d98adfd96994508ee837bf2ce6d6efc83c3e93836d5ce5ea208bd1", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "NX_DAEMON=false NX_TUI=false CI=true npx nx run-many -t lint --projects=chat,langgraph,ag-ui,render,a2ui,telemetry --parallel=2 --skip-nx-cache --outputStyle=static" + }, + { + "id": "production-builds", + "exitCode": 0, + "logSha256": "726d7d105c725e6fd4f422bcbfc49107a3f6cbbffd6444c207c49d8d00450a41", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "NX_DAEMON=false NX_TUI=false CI=true npx nx run-many -t build --projects=chat,langgraph,ag-ui,render,a2ui,telemetry --configuration=production --parallel=1 --skip-nx-cache --outputStyle=static" + }, + { + "id": "consumer-harness-tests", + "exitCode": 0, + "logSha256": "8c58dfb1cde1ef0688049f63b695350c8f9fcc3fa951aed0d03653028a7ebda9", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "node --test examples/chat/smoke/*.spec.mjs scripts/verify-angular-support.spec.mjs" + }, + { + "id": "angular-21-legacy-consumer", + "exitCode": 0, + "logSha256": "b138985a27837cd0ed1e856ec86bd80ed2ae627620cf4e12672d37511d6ac1e6", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "reproductionCommand": "NX_DAEMON=false NX_TUI=false CI=true PUPPETEER_SKIP_DOWNLOAD=true PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 node examples/chat/smoke/cli.mjs --non-interactive --fresh --target tmp/react-parity/angular-21 --local-dist-root dist/libs --angular-major 21 --install --build --runtime" + }, + { + "id": "verification-script-lint", + "exitCode": 0, + "logSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "logRetention": "Local execution log is ephemeral; rerun the recorded command for fresh evidence.", + "command": "node node_modules/eslint/bin/eslint.js scripts/react-parity/package-policy.mjs scripts/react-parity/package-policy.spec.mjs scripts/react-parity/verify-boundaries.mjs scripts/react-parity/verify-boundaries.spec.mjs scripts/react-parity/verify-packages.mjs scripts/react-parity/verify-packages.spec.mjs scripts/react-parity/verify-angular-package.mjs scripts/react-parity/verify-angular-package.spec.mjs scripts/ci-scope.mjs scripts/ci-scope.spec.mjs scripts/ci-workflow.spec.mjs" + } + ], + "lockfileAudit": { + "method": "Compare registry package entries against base HEAD separately from reviewed workspace links and root metadata.", + "exitCode": 0, + "logSha256": "70e8222a915522423503273e6a0b9e68beef6609b0f00a3d74ffc2c2ca7856e3", + "changedRegistryPackageEntries": [], + "lockEntries": 3047, + "reviewedChanges": [ + "Direct semver 7.7.4 tooling dependency, already resolved in the lockfile", + "Replace retired scaffold workspace links with the Angular scaffold and its peer metadata" + ] + }, + "scopeCounts": { + "libraryTestTargetsPassed": 6, + "typeTestTargetsPassed": 3, + "libraryLintTargetsPassed": 6, + "productionBuildTargetsPassed": 6, + "consumerHarnessTestsPassed": 44, + "foundationTargetConfigurationsPassed": 16, + "foundationLibraryBehaviorTests": 0, + "privateTarballs": 4, + "plainExportPaths": 9, + "angularExportPaths": 1, + "focusedNodeTestsPassed": 384, + "independentFocusedNodeTestsPassed": 384, + "inventoryRows": 1438, + "componentDeclarations": 102, + "publicExportOccurrences": 550, + "sourceFiles": 461, + "packageSupportAssets": 128, + "distributionConfigs": 16, + "publicEntryPoints": 12, + "cockpitTopics": 41, + "docsPages": 128, + "uniqueExportDefinitions": 514 + }, + "foundationConsumers": { + "core": { + "installedPackages": 1, + "installedFileBytes": 3639, + "lockLocations": 1, + "exportsChecked": 3 + }, + "plain": { + "installedPackages": 3, + "installedFileBytes": 10837, + "lockLocations": 3, + "exportsChecked": 9, + "packages": [ + "core", + "content", + "react" + ] + }, + "reactRootBundle": { + "inputModules": 2, + "bytes": 128, + "contentParserInputs": 0 + }, + "angular": { + "installedPackages": 410, + "installedFileBytes": 196886714, + "lockLocationsIncludingOptionalPlatforms": 515, + "includes": "Angular CLI, compiler and build development tooling", + "exportsChecked": 1, + "initialBundleRawReported": "92.07 kB", + "initialBundleEstimatedTransferReported": "27.62 kB", + "bundleInputModules": 252, + "threadplaneAPFInputModules": 1, + "contentParserInputs": 0, + "angularCore": "21.1.6", + "angularCli": "21.1.5" + }, + "limits": "Installed files, lockfile locations and bundle inputs measure different surfaces. These empty-scaffold measurements are not runtime benchmarks. Both consumers use skipLibCheck:false." + }, + "consumer": { + "outputDirectory": "tmp/react-parity/angular-21", + "threadplaneVersion": "0.2.0", + "angularMajor": 21, + "install": "local tarballs for all six published libraries, independently resolved external dependency ranges", + "runtime": "backend-free Playwright Chromium compatibility smoke", + "resolvedExternalDependencies": { + "node_modules/@ag-ui/client": "0.0.59", + "node_modules/@angular/core": "21.2.22", + "node_modules/@cacheplane/partial-json": "0.2.2", + "node_modules/@cacheplane/partial-markdown": "0.3.2", + "node_modules/@langchain/core": "1.2.12", + "node_modules/@langchain/langgraph-sdk": "1.11.2", + "node_modules/@threadplane/chat/node_modules/@cacheplane/partial-markdown": "0.5.8", + "node_modules/typescript": "5.9.3" + }, + "initialBundleRawReported": "1.91 MB", + "initialBundleEstimatedTransferReported": "390.10 kB", + "budgetWarning": "500.00 kB initial budget exceeded by 1.41 MB" + }, + "stableLane": { + "tag": "v0.2.0", + "peeledCommit": "8daea78d35bfa27513474bd624d0e9495af3cfab", + "localBranch": "codex/angular-maintenance-v0.2", + "lockfileSha256": "a8c25ef403eedaad064d5da45ec4f7dc2b66538597a29ee4796b5e52b2f42e26", + "verification": "Local branch/tag commit and lockfile verified. Remote branch status, publication policy and operated maintenance workflow were not established." + }, + "candidateLane": { + "branch": "codex/react-support-baseline", + "baseCommit": "7e80cebd607f5c605ef1ec81f11e5ebe3324f81b", + "workingTree": "Uncommitted P01\u2013P06 foundation changes; populated Angular implementations unchanged." + }, + "warnings": [ + "Existing Angular lint targets pass with existing warnings.", + "Native builds report stale Browserslist data and packaging lifecycle-script notices.", + "Legacy Angular consumer emits NG8107, initial bundle budget and p-queue CommonJS warnings." + ], + "notRun": [ + "Angular20 and Angular22 consumer lanes", + "CI Node22.22.3 environment", + "Live backend/deployment smoke", + "Calibrated latency, heap retention or stream-to-paint benchmarks", + "Shared runtime extraction or native binding behavior proof", + "React runtime/component/SSR tests and renderer reuse proof", + "Release publication or backport rehearsal" + ], + "review": { + "scope": "P01\u2013P06 foundation code, ledger and evidence received independent specification and quality approval. Review findings were addressed before commit.", + "implementationParity": false + } +} diff --git a/fixtures/react-parity/consumers/angular/angular.json b/fixtures/react-parity/consumers/angular/angular.json new file mode 100644 index 000000000..7e1f2a543 --- /dev/null +++ b/fixtures/react-parity/consumers/angular/angular.json @@ -0,0 +1,25 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { "analytics": false, "packageManager": "npm" }, + "projects": { + "consumer": { + "projectType": "application", + "root": "", + "sourceRoot": "src", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "browser": "src/main.ts", + "index": "src/index.html", + "tsConfig": "tsconfig.app.json", + "outputPath": "dist/consumer" + }, + "configurations": { "production": { "optimization": true, "outputHashing": "all" } }, + "defaultConfiguration": "production" + } + } + } + } +} diff --git a/fixtures/react-parity/consumers/angular/package.json b/fixtures/react-parity/consumers/angular/package.json new file mode 100644 index 000000000..8ff3eaa3a --- /dev/null +++ b/fixtures/react-parity/consumers/angular/package.json @@ -0,0 +1,7 @@ +{ + "name": "threadplane-angular-foundation-consumer", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { "build": "ng build --configuration=production --stats-json" } +} diff --git a/fixtures/react-parity/consumers/angular/src/index.html b/fixtures/react-parity/consumers/angular/src/index.html new file mode 100644 index 000000000..dabfde832 --- /dev/null +++ b/fixtures/react-parity/consumers/angular/src/index.html @@ -0,0 +1,5 @@ + + + Angular package consumer + + diff --git a/fixtures/react-parity/consumers/angular/src/main.ts b/fixtures/react-parity/consumers/angular/src/main.ts new file mode 100644 index 000000000..e36902711 --- /dev/null +++ b/fixtures/react-parity/consumers/angular/src/main.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import * as angular from '@threadplane/angular'; +/* PACKAGE_IMPORTS */ + +@Component({ + selector: 'app-root', + standalone: true, + template: '

Private Angular scaffold: {{ supportedExportCount }} supported exports.

', +}) +class App { + readonly supportedExportCount = Object.keys(angular).length /* PACKAGE_EXPORT_COUNT */; +} + +bootstrapApplication(App).catch(console.error); diff --git a/fixtures/react-parity/consumers/angular/tsconfig.app.json b/fixtures/react-parity/consumers/angular/tsconfig.app.json new file mode 100644 index 000000000..60a1469b2 --- /dev/null +++ b/fixtures/react-parity/consumers/angular/tsconfig.app.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, + "files": ["src/main.ts"] +} diff --git a/fixtures/react-parity/consumers/angular/tsconfig.json b/fixtures/react-parity/consumers/angular/tsconfig.json new file mode 100644 index 000000000..960967cc8 --- /dev/null +++ b/fixtures/react-parity/consumers/angular/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["ES2022", "DOM"], + "strict": true, + "skipLibCheck": false, + "isolatedModules": true, + "experimentalDecorators": true, + "importHelpers": true + }, + "angularCompilerOptions": { + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/fixtures/react-parity/traces.spec.mjs b/fixtures/react-parity/traces.spec.mjs new file mode 100644 index 000000000..aadb5e81d --- /dev/null +++ b/fixtures/react-parity/traces.spec.mjs @@ -0,0 +1,66 @@ +import assert from 'node:assert/strict'; +import { readFile } from 'node:fs/promises'; +import test from 'node:test'; +import { Client } from '@langchain/langgraph-sdk'; +import { HttpAgent } from '@ag-ui/client'; + +// Synthetic wire fixtures only. Production adapter/conformance suites remain +// authoritative for reduction, execution ownership, interrupts, and recovery. +async function response(name) { + const bytes = new Uint8Array(await readFile(new URL(`./traces/${name}`, import.meta.url))); + let offset = 0; + return new Response(new ReadableStream({ + pull(controller) { + if (offset === bytes.length) return controller.close(); + const end = Math.min(offset + 3, bytes.length); + controller.enqueue(bytes.slice(offset, end)); + offset = end; + }, + }), { headers: { 'content-type': 'text/event-stream' } }); +} + +test('LangGraph SDK decodes the synthetic delta/canonical trace across split UTF-8 chunks', async () => { + const requests = []; + const client = new Client({ + apiUrl: 'https://parity.invalid', + callerOptions: { + maxRetries: 0, + fetch: async (url, init) => { + requests.push({ url: String(url), body: JSON.parse(init.body) }); + return response('langgraph-text-state.sse'); + }, + }, + }); + const events = []; + for await (const event of client.runs.stream('thread-parity', 'parity', { + input: { messages: [{ role: 'user', content: 'Say hello.' }] }, + streamMode: ['messages', 'values'], + })) events.push(event); + assert.equal(requests.length, 1); + assert.match(requests[0].url, /\/threads\/thread-parity\/runs\/stream$/); + assert.deepEqual(requests[0].body.input.messages, [{ role: 'user', content: 'Say hello.' }]); + const deltas = events.filter(event => event.event === 'messages'); + assert.equal(deltas.map(event => event.data[0].content).join(''), 'Hello 🌍.'); + const final = events.findLast(event => event.event === 'values'); + assert.equal(final.data.messages[0].content, 'Hello 🌍.'); + assert.equal(final.data.messages[0].id, 'message-parity'); + assert.equal(final.data.stage, 'complete'); +}); + +test('AG-UI client completes the synthetic text/state trace without duplicate messages', async () => { + const requests = []; + const source = new HttpAgent({ + url: 'https://parity.invalid/agent', + threadId: 'thread-parity', + fetch: async (url, init) => { + requests.push({ url: String(url), body: JSON.parse(init.body) }); + return response('ag-ui-text-state.sse'); + }, + }); + await source.runAgent({ runId: 'run-parity' }); + assert.equal(requests.length, 1); + assert.equal(requests[0].body.threadId, 'thread-parity'); + assert.equal(source.isRunning, false); + assert.deepEqual(source.messages, [{ id: 'message-parity', role: 'assistant', content: 'Hello 🌍.' }]); + assert.deepEqual(source.state, { stage: 'complete' }); +}); diff --git a/fixtures/react-parity/traces/.gitattributes b/fixtures/react-parity/traces/.gitattributes new file mode 100644 index 000000000..2b503887f --- /dev/null +++ b/fixtures/react-parity/traces/.gitattributes @@ -0,0 +1,2 @@ +# SSE dispatches the final event at its terminating blank line. +*.sse whitespace=-blank-at-eof diff --git a/fixtures/react-parity/traces/ag-ui-text-state.sse b/fixtures/react-parity/traces/ag-ui-text-state.sse new file mode 100644 index 000000000..6a66384ee --- /dev/null +++ b/fixtures/react-parity/traces/ag-ui-text-state.sse @@ -0,0 +1,16 @@ +data: {"type":"RUN_STARTED","threadId":"thread-parity","runId":"run-parity"} + +data: {"type":"STATE_SNAPSHOT","snapshot":{"stage":"streaming"}} + +data: {"type":"TEXT_MESSAGE_START","messageId":"message-parity","role":"assistant"} + +data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"message-parity","delta":"Hello "} + +data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"message-parity","delta":"🌍."} + +data: {"type":"TEXT_MESSAGE_END","messageId":"message-parity"} + +data: {"type":"STATE_SNAPSHOT","snapshot":{"stage":"complete"}} + +data: {"type":"RUN_FINISHED","threadId":"thread-parity","runId":"run-parity"} + diff --git a/fixtures/react-parity/traces/langgraph-text-state.sse b/fixtures/react-parity/traces/langgraph-text-state.sse new file mode 100644 index 000000000..ceacdcff7 --- /dev/null +++ b/fixtures/react-parity/traces/langgraph-text-state.sse @@ -0,0 +1,12 @@ +event: metadata +data: {"run_id":"run-parity","attempt":1} + +event: messages +data: [{"type":"AIMessageChunk","id":"message-parity","content":"Hello "},{"langgraph_node":"assistant"}] + +event: messages +data: [{"type":"AIMessageChunk","id":"message-parity","content":"🌍."},{"langgraph_node":"assistant"}] + +event: values +data: {"messages":[{"type":"ai","id":"message-parity","content":"Hello 🌍."}],"stage":"complete"} + diff --git a/libs/angular/LICENSE.md b/libs/angular/LICENSE.md new file mode 100644 index 000000000..c1a0122f7 --- /dev/null +++ b/libs/angular/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Brian Love d/b/a cacheplane + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/angular/README.md b/libs/angular/README.md new file mode 100644 index 000000000..63063389d --- /dev/null +++ b/libs/angular/README.md @@ -0,0 +1,14 @@ +# @threadplane/angular + +Private, unpublished Angular foundation scaffolding. The empty root entry point +provides no supported runtime API or secondary entry points. Angular bindings, +providers, components, and backend integrations are not implemented. + +Build with `npx nx build angular`. The production target uses ng-packagr and +partial Angular compilation to emit the Angular Package Format. Tests currently +contain no cases and pass with `passWithNoTests`; the type-tests target checks +the empty source with TypeScript. + +The declared Angular peer range follows the existing workspace packages. It is +not a compatibility-matrix claim. An installed Angular CLI consumer must verify +package resolution and linking separately before this foundation is complete. diff --git a/libs/angular/ng-package.json b/libs/angular/ng-package.json new file mode 100644 index 000000000..f836f38de --- /dev/null +++ b/libs/angular/ng-package.json @@ -0,0 +1,6 @@ +{ + "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../dist/libs/angular", + "lib": { "entryFile": "src/public-api.ts" }, + "assets": ["LICENSE.md", "README.md"] +} diff --git a/libs/angular/package.json b/libs/angular/package.json new file mode 100644 index 000000000..bd0dbf964 --- /dev/null +++ b/libs/angular/package.json @@ -0,0 +1,19 @@ +{ + "name": "@threadplane/angular", + "version": "0.0.0", + "private": true, + "description": "Private Angular foundation scaffolding. No supported runtime API yet.", + "license": "MIT", + "type": "module", + "sideEffects": false, + "peerDependencies": { + "@angular/core": "^20.0.0 || ^21.0.0 || ^22.0.0" + }, + "files": [ + "fesm2022/*.mjs", + "fesm2022/*.mjs.map", + "types/**/*.d.ts", + "LICENSE.md", + "README.md" + ] +} diff --git a/libs/angular/project.json b/libs/angular/project.json new file mode 100644 index 000000000..38a2ec79d --- /dev/null +++ b/libs/angular/project.json @@ -0,0 +1,35 @@ +{ + "name": "angular", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/angular/src", + "projectType": "library", + "tags": ["scope:react-parity", "scope:library", "type:lib", "layer:angular"], + "targets": { + "build": { + "executor": "@nx/angular:package", + "outputs": ["{workspaceRoot}/dist/{projectRoot}"], + "options": { + "project": "libs/angular/ng-package.json", + "tsConfig": "libs/angular/tsconfig.lib.json" + }, + "configurations": { + "production": { "tsConfig": "libs/angular/tsconfig.lib.prod.json" }, + "development": {} + }, + "defaultConfiguration": "production" + }, + "lint": { "executor": "@nx/eslint:lint" }, + "test": { + "executor": "@nx/vitest:test", + "options": { "configFile": "libs/angular/vite.config.mts" } + }, + "type-tests": { + "executor": "nx:run-commands", + "cache": true, + "inputs": ["default", "^production"], + "options": { + "command": "node node_modules/typescript/bin/tsc --project libs/angular/tsconfig.spec.json --noEmit --emitDeclarationOnly false --composite false --incremental false" + } + } + } +} diff --git a/libs/angular/src/public-api.ts b/libs/angular/src/public-api.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/libs/angular/src/public-api.ts @@ -0,0 +1 @@ +export {}; diff --git a/libs/angular/tsconfig.json b/libs/angular/tsconfig.json new file mode 100644 index 000000000..83e52b464 --- /dev/null +++ b/libs/angular/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "experimentalDecorators": true, + "noPropertyAccessFromIndexSignature": true, + "module": "preserve", + "emitDeclarationOnly": false, + "composite": false + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + }, + "files": [], + "include": [], + "references": [ + { "path": "./tsconfig.lib.json" }, + { "path": "./tsconfig.spec.json" } + ] +} diff --git a/libs/angular/tsconfig.lib.json b/libs/angular/tsconfig.lib.json new file mode 100644 index 000000000..9860c8eec --- /dev/null +++ b/libs/angular/tsconfig.lib.json @@ -0,0 +1,18 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc/angular", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "lib": ["es2022", "dom"], + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": [ + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.type-test.ts", + "src/test-setup.ts" + ] +} diff --git a/libs/angular/tsconfig.lib.prod.json b/libs/angular/tsconfig.lib.prod.json new file mode 100644 index 000000000..1d3d0bab7 --- /dev/null +++ b/libs/angular/tsconfig.lib.prod.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { "declarationMap": false }, + "angularCompilerOptions": { "compilationMode": "partial" } +} diff --git a/libs/angular/tsconfig.spec.json b/libs/angular/tsconfig.spec.json new file mode 100644 index 000000000..786a68ab2 --- /dev/null +++ b/libs/angular/tsconfig.spec.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declaration": false, + "declarationMap": false, + "inlineSources": false, + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/libs/angular/vite.config.mts b/libs/angular/vite.config.mts new file mode 100644 index 000000000..382d0ec66 --- /dev/null +++ b/libs/angular/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + root: import.meta.dirname, + test: { + environment: 'node', + include: ['src/**/*.spec.ts', 'src/**/*.test.ts'], + passWithNoTests: true, + }, +}); diff --git a/libs/content/LICENSE.md b/libs/content/LICENSE.md new file mode 100644 index 000000000..c1a0122f7 --- /dev/null +++ b/libs/content/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Brian Love d/b/a cacheplane + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/content/README.md b/libs/content/README.md new file mode 100644 index 000000000..3fc701ae1 --- /dev/null +++ b/libs/content/README.md @@ -0,0 +1,14 @@ +# @threadplane/content + +Private, unpublished foundation scaffolding for the React parity work. These empty +entry points reserve planned package boundaries; they provide no supported runtime +API. No React bindings, stores, renderers, or backend adapters are implemented. + +Reserved exports: `@threadplane/content`, `@threadplane/content/markdown`, `@threadplane/content/json`, `@threadplane/content/a2ui`, `@threadplane/content/testing`. + +Framework-neutral render contracts belong to `@threadplane/render`; content owns +the higher-level content protocols that use those contracts. + +Build with `npx nx build content`. Packaging and dependency boundaries are +verified by the scripts in `scripts/react-parity`. Optional and testing entry +points must remain unreachable from the root runtime and declarations. diff --git a/libs/content/package.json b/libs/content/package.json new file mode 100644 index 000000000..98ac5d462 --- /dev/null +++ b/libs/content/package.json @@ -0,0 +1,43 @@ +{ + "name": "@threadplane/content", + "version": "0.0.0", + "private": true, + "description": "Private content foundation scaffolding. No supported runtime API yet.", + "license": "MIT", + "type": "module", + "sideEffects": false, + "files": [ + "src/**/*.js", + "src/**/*.d.ts", + "src/**/*.d.ts.map", + "LICENSE.md", + "README.md" + ], + "exports": { + ".": { + "types": "./src/index.d.ts", + "import": "./src/index.js", + "default": "./src/index.js" + }, + "./markdown": { + "types": "./src/markdown/index.d.ts", + "import": "./src/markdown/index.js", + "default": "./src/markdown/index.js" + }, + "./json": { + "types": "./src/json/index.d.ts", + "import": "./src/json/index.js", + "default": "./src/json/index.js" + }, + "./a2ui": { + "types": "./src/a2ui/index.d.ts", + "import": "./src/a2ui/index.js", + "default": "./src/a2ui/index.js" + }, + "./testing": { + "types": "./src/testing/index.d.ts", + "import": "./src/testing/index.js", + "default": "./src/testing/index.js" + } + } +} diff --git a/libs/content/project.json b/libs/content/project.json new file mode 100644 index 000000000..baf0c8495 --- /dev/null +++ b/libs/content/project.json @@ -0,0 +1,59 @@ +{ + "name": "content", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/content/src", + "projectType": "library", + "tags": [ + "scope:react-parity", + "type:lib", + "layer:content", + "scope:library" + ], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "cache": true, + "dependsOn": [ + "^build" + ], + "inputs": [ + "production", + "^production" + ], + "outputs": [ + "{workspaceRoot}/dist/libs/content" + ], + "options": { + "outputPath": "dist/libs/content", + "main": "libs/content/src/index.ts", + "tsConfig": "libs/content/tsconfig.lib.json", + "generatePackageJson": false, + "assets": [ + "libs/content/package.json", + "libs/content/LICENSE.md", + "libs/content/README.md" + ] + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vitest:test", + "options": { + "configFile": "libs/content/vite.config.mts" + } + }, + "type-tests": { + "executor": "nx:run-commands", + "cache": true, + "inputs": [ + "default", + "^production" + ], + "options": { + "command": "node node_modules/typescript/bin/tsc --project libs/content/tsconfig.spec.json --noEmit --emitDeclarationOnly false --composite false --incremental false" + } + } + } +} diff --git a/libs/content/src/a2ui/index.ts b/libs/content/src/a2ui/index.ts new file mode 100644 index 000000000..d045c0857 --- /dev/null +++ b/libs/content/src/a2ui/index.ts @@ -0,0 +1,2 @@ +// Reserved private entry point. Runtime implementation follows in later work. +export {}; diff --git a/libs/content/src/index.ts b/libs/content/src/index.ts new file mode 100644 index 000000000..d045c0857 --- /dev/null +++ b/libs/content/src/index.ts @@ -0,0 +1,2 @@ +// Reserved private entry point. Runtime implementation follows in later work. +export {}; diff --git a/libs/content/src/json/index.ts b/libs/content/src/json/index.ts new file mode 100644 index 000000000..d045c0857 --- /dev/null +++ b/libs/content/src/json/index.ts @@ -0,0 +1,2 @@ +// Reserved private entry point. Runtime implementation follows in later work. +export {}; diff --git a/libs/content/src/markdown/index.ts b/libs/content/src/markdown/index.ts new file mode 100644 index 000000000..d045c0857 --- /dev/null +++ b/libs/content/src/markdown/index.ts @@ -0,0 +1,2 @@ +// Reserved private entry point. Runtime implementation follows in later work. +export {}; diff --git a/libs/content/src/testing/index.ts b/libs/content/src/testing/index.ts new file mode 100644 index 000000000..d045c0857 --- /dev/null +++ b/libs/content/src/testing/index.ts @@ -0,0 +1,2 @@ +// Reserved private entry point. Runtime implementation follows in later work. +export {}; diff --git a/libs/content/tsconfig.json b/libs/content/tsconfig.json new file mode 100644 index 000000000..64d2d4b34 --- /dev/null +++ b/libs/content/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "types": [], + "lib": [ + "ES2022" + ] + }, + "files": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/content/tsconfig.lib.json b/libs/content/tsconfig.lib.json new file mode 100644 index 000000000..00695e4fa --- /dev/null +++ b/libs/content/tsconfig.lib.json @@ -0,0 +1,24 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "../../dist/libs/content", + "declaration": true, + "emitDeclarationOnly": false, + "module": "ES2022", + "target": "ES2022" + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ], + "exclude": [ + "src/**/*.spec.ts", + "src/**/*.spec.tsx", + "src/**/*.test.ts", + "src/**/*.test.tsx", + "src/**/*.type-test.ts", + "src/**/*.type-test.tsx", + "src/test-setup.ts" + ] +} diff --git a/libs/content/tsconfig.spec.json b/libs/content/tsconfig.spec.json new file mode 100644 index 000000000..c0047ae5d --- /dev/null +++ b/libs/content/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "types": [ + "vitest/globals" + ], + "outDir": "../../dist/out-tsc/content" + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ], + "exclude": [] +} diff --git a/libs/content/vite.config.mts b/libs/content/vite.config.mts new file mode 100644 index 000000000..f05211ebe --- /dev/null +++ b/libs/content/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + root: import.meta.dirname, + test: { + environment: 'node', + include: ['src/**/*.spec.{ts,tsx}', 'src/**/*.test.{ts,tsx}'], + passWithNoTests: true, + }, +}); diff --git a/libs/core/LICENSE.md b/libs/core/LICENSE.md new file mode 100644 index 000000000..c1a0122f7 --- /dev/null +++ b/libs/core/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Brian Love d/b/a cacheplane + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/core/README.md b/libs/core/README.md new file mode 100644 index 000000000..6edd905a7 --- /dev/null +++ b/libs/core/README.md @@ -0,0 +1,14 @@ +# @threadplane/core + +Private, unpublished foundation scaffolding for the React parity work. These empty +entry points reserve planned package boundaries; they provide no supported runtime +API. No React bindings, stores, renderers, or backend adapters are implemented. + +Reserved exports: `@threadplane/core`, `@threadplane/core/tools`, `@threadplane/core/testing`. + +Core owns dependency-free agent contracts. Schema validation belongs to consumers +and their chosen libraries. + +Build with `npx nx build core`. Packaging and dependency boundaries are +verified by the scripts in `scripts/react-parity`. Optional and testing entry +points must remain unreachable from the root runtime and declarations. diff --git a/libs/core/package.json b/libs/core/package.json new file mode 100644 index 000000000..3bc539bb0 --- /dev/null +++ b/libs/core/package.json @@ -0,0 +1,33 @@ +{ + "name": "@threadplane/core", + "version": "0.0.0", + "private": true, + "description": "Private core foundation scaffolding. No supported runtime API yet.", + "license": "MIT", + "type": "module", + "sideEffects": false, + "files": [ + "src/**/*.js", + "src/**/*.d.ts", + "src/**/*.d.ts.map", + "LICENSE.md", + "README.md" + ], + "exports": { + ".": { + "types": "./src/index.d.ts", + "import": "./src/index.js", + "default": "./src/index.js" + }, + "./tools": { + "types": "./src/tools/index.d.ts", + "import": "./src/tools/index.js", + "default": "./src/tools/index.js" + }, + "./testing": { + "types": "./src/testing/index.d.ts", + "import": "./src/testing/index.js", + "default": "./src/testing/index.js" + } + } +} diff --git a/libs/core/project.json b/libs/core/project.json new file mode 100644 index 000000000..cf7842e59 --- /dev/null +++ b/libs/core/project.json @@ -0,0 +1,59 @@ +{ + "name": "core", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/core/src", + "projectType": "library", + "tags": [ + "scope:react-parity", + "type:lib", + "layer:core", + "scope:library" + ], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "cache": true, + "dependsOn": [ + "^build" + ], + "inputs": [ + "production", + "^production" + ], + "outputs": [ + "{workspaceRoot}/dist/libs/core" + ], + "options": { + "outputPath": "dist/libs/core", + "main": "libs/core/src/index.ts", + "tsConfig": "libs/core/tsconfig.lib.json", + "generatePackageJson": false, + "assets": [ + "libs/core/package.json", + "libs/core/LICENSE.md", + "libs/core/README.md" + ] + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vitest:test", + "options": { + "configFile": "libs/core/vite.config.mts" + } + }, + "type-tests": { + "executor": "nx:run-commands", + "cache": true, + "inputs": [ + "default", + "^production" + ], + "options": { + "command": "node node_modules/typescript/bin/tsc --project libs/core/tsconfig.spec.json --noEmit --emitDeclarationOnly false --composite false --incremental false" + } + } + } +} diff --git a/libs/core/src/index.ts b/libs/core/src/index.ts new file mode 100644 index 000000000..d045c0857 --- /dev/null +++ b/libs/core/src/index.ts @@ -0,0 +1,2 @@ +// Reserved private entry point. Runtime implementation follows in later work. +export {}; diff --git a/libs/core/src/testing/index.ts b/libs/core/src/testing/index.ts new file mode 100644 index 000000000..d045c0857 --- /dev/null +++ b/libs/core/src/testing/index.ts @@ -0,0 +1,2 @@ +// Reserved private entry point. Runtime implementation follows in later work. +export {}; diff --git a/libs/core/src/tools/index.ts b/libs/core/src/tools/index.ts new file mode 100644 index 000000000..d045c0857 --- /dev/null +++ b/libs/core/src/tools/index.ts @@ -0,0 +1,2 @@ +// Reserved private entry point. Runtime implementation follows in later work. +export {}; diff --git a/libs/core/tsconfig.json b/libs/core/tsconfig.json new file mode 100644 index 000000000..64d2d4b34 --- /dev/null +++ b/libs/core/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "types": [], + "lib": [ + "ES2022" + ] + }, + "files": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/core/tsconfig.lib.json b/libs/core/tsconfig.lib.json new file mode 100644 index 000000000..d0b6ad56c --- /dev/null +++ b/libs/core/tsconfig.lib.json @@ -0,0 +1,24 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "../../dist/libs/core", + "declaration": true, + "emitDeclarationOnly": false, + "module": "ES2022", + "target": "ES2022" + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ], + "exclude": [ + "src/**/*.spec.ts", + "src/**/*.spec.tsx", + "src/**/*.test.ts", + "src/**/*.test.tsx", + "src/**/*.type-test.ts", + "src/**/*.type-test.tsx", + "src/test-setup.ts" + ] +} diff --git a/libs/core/tsconfig.spec.json b/libs/core/tsconfig.spec.json new file mode 100644 index 000000000..0aafa3b7b --- /dev/null +++ b/libs/core/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "types": [ + "vitest/globals" + ], + "outDir": "../../dist/out-tsc/core" + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ], + "exclude": [] +} diff --git a/libs/core/vite.config.mts b/libs/core/vite.config.mts new file mode 100644 index 000000000..f05211ebe --- /dev/null +++ b/libs/core/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + root: import.meta.dirname, + test: { + environment: 'node', + include: ['src/**/*.spec.{ts,tsx}', 'src/**/*.test.{ts,tsx}'], + passWithNoTests: true, + }, +}); diff --git a/libs/react/LICENSE.md b/libs/react/LICENSE.md new file mode 100644 index 000000000..c1a0122f7 --- /dev/null +++ b/libs/react/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Brian Love d/b/a cacheplane + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/react/README.md b/libs/react/README.md new file mode 100644 index 000000000..8da3a8372 --- /dev/null +++ b/libs/react/README.md @@ -0,0 +1,15 @@ +# @threadplane/react + +Private, unpublished foundation scaffolding for the React parity work. The empty +root entry point provides no supported runtime API. No React bindings, stores, +renderers, or backend adapters are implemented. + +The only current export is `@threadplane/react`. React rendering and feature +bindings belong to this package; feature subpaths will be added with their +implementations. + +Build with `npx nx build react`. Packaging and dependency boundaries are +verified by the scripts in `scripts/react-parity`. Feature entry points must +remain unreachable from the root runtime and declarations. + +The root entry point retains `use client`. diff --git a/libs/react/package.json b/libs/react/package.json new file mode 100644 index 000000000..d55ec30d9 --- /dev/null +++ b/libs/react/package.json @@ -0,0 +1,23 @@ +{ + "name": "@threadplane/react", + "version": "0.0.0", + "private": true, + "description": "Private react foundation scaffolding. No supported runtime API yet.", + "license": "MIT", + "type": "module", + "sideEffects": false, + "files": [ + "src/**/*.js", + "src/**/*.d.ts", + "src/**/*.d.ts.map", + "LICENSE.md", + "README.md" + ], + "exports": { + ".": { + "types": "./src/index.d.ts", + "import": "./src/index.js", + "default": "./src/index.js" + } + } +} diff --git a/libs/react/project.json b/libs/react/project.json new file mode 100644 index 000000000..6ad5bdc20 --- /dev/null +++ b/libs/react/project.json @@ -0,0 +1,59 @@ +{ + "name": "react", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/react/src", + "projectType": "library", + "tags": [ + "scope:react-parity", + "type:lib", + "layer:react", + "scope:library" + ], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "cache": true, + "dependsOn": [ + "^build" + ], + "inputs": [ + "production", + "^production" + ], + "outputs": [ + "{workspaceRoot}/dist/libs/react" + ], + "options": { + "outputPath": "dist/libs/react", + "main": "libs/react/src/index.ts", + "tsConfig": "libs/react/tsconfig.lib.json", + "generatePackageJson": false, + "assets": [ + "libs/react/package.json", + "libs/react/LICENSE.md", + "libs/react/README.md" + ] + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vitest:test", + "options": { + "configFile": "libs/react/vite.config.mts" + } + }, + "type-tests": { + "executor": "nx:run-commands", + "cache": true, + "inputs": [ + "default", + "^production" + ], + "options": { + "command": "node node_modules/typescript/bin/tsc --project libs/react/tsconfig.spec.json --noEmit --emitDeclarationOnly false --composite false --incremental false" + } + } + } +} diff --git a/libs/react/src/index.ts b/libs/react/src/index.ts new file mode 100644 index 000000000..127e42d26 --- /dev/null +++ b/libs/react/src/index.ts @@ -0,0 +1,4 @@ +'use client'; + +// Reserved private entry point. Runtime implementation follows in later work. +export {}; diff --git a/libs/react/tsconfig.json b/libs/react/tsconfig.json new file mode 100644 index 000000000..435f5a08d --- /dev/null +++ b/libs/react/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "types": [], + "lib": [ + "ES2022", + "DOM", + "DOM.Iterable" + ], + "jsx": "react-jsx" + }, + "files": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/react/tsconfig.lib.json b/libs/react/tsconfig.lib.json new file mode 100644 index 000000000..2eae4aba1 --- /dev/null +++ b/libs/react/tsconfig.lib.json @@ -0,0 +1,24 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "../../dist/libs/react", + "declaration": true, + "emitDeclarationOnly": false, + "module": "ES2022", + "target": "ES2022" + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ], + "exclude": [ + "src/**/*.spec.ts", + "src/**/*.spec.tsx", + "src/**/*.test.ts", + "src/**/*.test.tsx", + "src/**/*.type-test.ts", + "src/**/*.type-test.tsx", + "src/test-setup.ts" + ] +} diff --git a/libs/react/tsconfig.spec.json b/libs/react/tsconfig.spec.json new file mode 100644 index 000000000..86fbbd4e0 --- /dev/null +++ b/libs/react/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "types": [ + "vitest/globals" + ], + "outDir": "../../dist/out-tsc/react" + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ], + "exclude": [] +} diff --git a/libs/react/vite.config.mts b/libs/react/vite.config.mts new file mode 100644 index 000000000..f05211ebe --- /dev/null +++ b/libs/react/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + root: import.meta.dirname, + test: { + environment: 'node', + include: ['src/**/*.spec.{ts,tsx}', 'src/**/*.test.{ts,tsx}'], + passWithNoTests: true, + }, +}); diff --git a/nx.json b/nx.json index f37f5b792..840ab30f2 100644 --- a/nx.json +++ b/nx.json @@ -5,6 +5,11 @@ "production": [ "default", "!{projectRoot}/**/*.spec.ts", + "!{projectRoot}/**/*.spec.tsx", + "!{projectRoot}/**/*.test.ts", + "!{projectRoot}/**/*.test.tsx", + "!{projectRoot}/**/*.type-test.ts", + "!{projectRoot}/**/*.type-test.tsx", "!{projectRoot}/src/test-setup.ts", "!{projectRoot}/jest.config.ts", "!{projectRoot}/.eslintrc.json", diff --git a/package-lock.json b/package-lock.json index aca072aa3..0d53d8609 100644 --- a/package-lock.json +++ b/package-lock.json @@ -102,6 +102,7 @@ "puppeteer": "^22.0.0", "remark-gfm": "^4.0.1", "resend": "^6.10.0", + "semver": "7.7.4", "tailwindcss": "^4.3.0", "tslib": "^2.3.0", "tsx": "^4.21.0", @@ -418,6 +419,14 @@ "rxjs": "~7.8.0" } }, + "libs/angular": { + "name": "@threadplane/angular", + "version": "0.0.0", + "license": "MIT", + "peerDependencies": { + "@angular/core": "^20.0.0 || ^21.0.0 || ^22.0.0" + } + }, "libs/chat": { "name": "@threadplane/chat", "version": "0.2.0", @@ -524,6 +533,16 @@ "web-vitals": "^5.1.0" } }, + "libs/content": { + "name": "@threadplane/content", + "version": "0.0.0", + "license": "MIT" + }, + "libs/core": { + "name": "@threadplane/core", + "version": "0.0.0", + "license": "MIT" + }, "libs/design-tokens": { "name": "@threadplane/design-tokens", "version": "0.0.35", @@ -610,6 +629,11 @@ "@langchain/langgraph": "^1.0.0" } }, + "libs/react": { + "name": "@threadplane/react", + "version": "0.0.0", + "license": "MIT" + }, "libs/render": { "name": "@threadplane/render", "version": "0.2.0", @@ -21534,6 +21558,10 @@ "resolved": "libs/ag-ui", "link": true }, + "node_modules/@threadplane/angular": { + "resolved": "libs/angular", + "link": true + }, "node_modules/@threadplane/chat": { "resolved": "libs/chat", "link": true @@ -21554,6 +21582,14 @@ "resolved": "libs/cockpit-telemetry", "link": true }, + "node_modules/@threadplane/content": { + "resolved": "libs/content", + "link": true + }, + "node_modules/@threadplane/core": { + "resolved": "libs/core", + "link": true + }, "node_modules/@threadplane/design-tokens": { "resolved": "libs/design-tokens", "link": true @@ -21570,6 +21606,10 @@ "resolved": "libs/middleware", "link": true }, + "node_modules/@threadplane/react": { + "resolved": "libs/react", + "link": true + }, "node_modules/@threadplane/render": { "resolved": "libs/render", "link": true diff --git a/package.json b/package.json index 8c5ebcadd..ba6a94fbd 100644 --- a/package.json +++ b/package.json @@ -94,6 +94,7 @@ "puppeteer": "^22.0.0", "remark-gfm": "^4.0.1", "resend": "^6.10.0", + "semver": "7.7.4", "tailwindcss": "^4.3.0", "tslib": "^2.3.0", "tsx": "^4.21.0", diff --git a/scripts/ci-scope.mjs b/scripts/ci-scope.mjs index 3cfd9d0eb..8e8fcdd5e 100644 --- a/scripts/ci-scope.mjs +++ b/scripts/ci-scope.mjs @@ -1,8 +1,9 @@ #!/usr/bin/env node import { execFileSync } from 'node:child_process'; -import { appendFileSync } from 'node:fs'; +import { appendFileSync, readFileSync } from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { privateScaffoldProjects } from './react-parity/package-policy.mjs'; export const SCOPE_KEYS = [ 'library', @@ -90,6 +91,27 @@ const LINT_SCOPE_KEYS = [ * this regex only decides which CI scope a change to them lights up. */ const COCKPIT_ROOTLESS_SPEC = /^cockpit\/[^/]+\/[^/]+\.spec\.ts$/; +// Keep migration CI ownership aligned with the inventory's reviewed scope. +// Rootless fixtures and documentation can change it without affecting an Nx library. +const parityScope = JSON.parse( + readFileSync(new URL('./react-parity/baseline.json', import.meta.url), 'utf8') +).scope; +const PARITY_PREFIXES = [ + 'scripts/react-parity/', + 'fixtures/react-parity/', + `${parityScope.docsRoot}/`, + ...[...parityScope.libraries, ...privateScaffoldProjects] + .map((name) => `libs/${name}/`), +]; + +function isParityChange(file) { + const normalized = normalizePath(file); + return PARITY_PREFIXES.some((prefix) => normalized.startsWith(prefix)) || + parityScope.configFiles.includes(normalized) || + (normalized.startsWith(`${parityScope.topicsRoot}/`) && + /\/angular\/(?:project\.json|src\/index\.ts)$/.test(normalized)); +} + export function emptyScope() { return Object.fromEntries(SCOPE_KEYS.map((k) => [k, false])); } @@ -152,6 +174,9 @@ export function classifyFromAffected(changedFiles, affectedProjects) { if (isAngularCompatibilityChange(changedFiles)) { scope.angular_compatibility = true; } + if (changedFiles.some(isParityChange)) { + scope.library = true; + } return scope; } diff --git a/scripts/ci-scope.spec.mjs b/scripts/ci-scope.spec.mjs index f22645d79..3675037ae 100644 --- a/scripts/ci-scope.spec.mjs +++ b/scripts/ci-scope.spec.mjs @@ -39,6 +39,35 @@ const EXAMPLES_CHAT_TAGS = [ const POSTHOG_TAGS = ['scope:posthog']; const GROWTH_LIFECYCLE_TAGS = ['scope:growth-lifecycle']; +describe('React migration baseline scope', () => { + for (const file of [ + 'scripts/react-parity/inventory.mjs', + 'fixtures/react-parity/traces/ag-ui-text-state.sse', + 'libs/core/src/index.ts', + 'libs/angular/src/public-api.ts', + 'libs/react/src/index.ts', + 'scripts/react-parity/package-policy.mjs', + 'fixtures/react-parity/consumers/angular/src/main.ts', + 'fixtures/react-parity/consumers/plain/package.json', + 'libs/ui-react/src/button.tsx', + 'apps/website/content/docs/chat/api/example.mdx', + 'cockpit/chat/messages/angular/src/index.ts', + 'cockpit/chat/new-topic/angular/project.json', + 'scripts/verify-release-versions.mjs', + ]) { + it(`runs library gates for ${file} even without Nx ownership`, () => { + assert.equal(classifyFromAffected([file], []).library, true); + }); + } + + it('does not send unrelated marketing or backend changes to library gates', () => { + for (const file of [ + 'apps/website/content/blog/post.mdx', + 'cockpit/chat/messages/python/src/graph.py', + ]) assert.equal(classifyFromAffected([file], []).library, false); + }); +}); + function nxAffectedFiles(file) { return JSON.parse( execFileSync( diff --git a/scripts/ci-workflow.spec.mjs b/scripts/ci-workflow.spec.mjs index 1f22d6a60..d9d55b144 100644 --- a/scripts/ci-workflow.spec.mjs +++ b/scripts/ci-workflow.spec.mjs @@ -1,6 +1,7 @@ import { readdir, readFile } from 'node:fs/promises'; import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; +import { privateScaffoldProjects } from './react-parity/package-policy.mjs'; import { spawnSync } from 'node:child_process'; function escapeRegExp(value) { @@ -78,6 +79,23 @@ function readNamedStep(job, name) { } describe('CI workflow', () => { + it('enforces React migration source, build, and packaged-consumer gates', async () => { + const job = readJobBlock(await readFile('.github/workflows/ci.yml', 'utf8'), 'library'); + const source = readNamedStep(job, 'React migration baseline and boundaries'); + assert.match(source, /node --test scripts\/react-parity\/\*\.spec\.mjs fixtures\/react-parity\/traces\.spec\.mjs/); + assert.match(source, /inventory\.mjs --check/); + assert.match(source, /node scripts\/react-parity\/verify-boundaries\.mjs/); + const build = readNamedStep(job, 'Build and validate private React foundations'); + assert.ok(job.includes(`FOUNDATIONS: ${privateScaffoldProjects.join(',')}`)); + assert.match(job, /LIBS: chat,langgraph,ag-ui,render,a2ui,telemetry/); + assert.match(build, /run-many -t lint test type-tests build --projects=\$FOUNDATIONS/); + const packages = readNamedStep(job, 'Verify emitted boundaries and isolated packages'); + assert.match(packages, /verify-boundaries\.mjs --built/); + assert.match(packages, /verify-packages\.mjs/); + assert.match(packages, /verify-angular-package\.mjs/); + assert.ok(job.indexOf(build) < job.indexOf(packages)); + assert.ok(job.indexOf('run-many -t build --projects=$LIBS') < job.indexOf(packages)); + }); it('verifies stage scrolling and interaction against the matching local replay build', async () => { const workflow = await readFile('.github/workflows/ci.yml', 'utf8'); const step = readNamedStep(readJobBlock(workflow, 'website-e2e'), 'Stage scroll verification (scroll-craft harness)'); @@ -107,7 +125,7 @@ describe('CI workflow', () => { assert.match( workflow, - /^ merge_group:\s*$/m, + /^ {2}merge_group:\s*$/m, 'ci.yml must trigger on merge_group or a merge queue blocks forever' ); @@ -169,14 +187,6 @@ describe('CI workflow', () => { return readJobBlock(await readWorkflow(), 'angular-compatibility'); } - async function readLibraryJob() { - const workflow = await readWorkflow(); - return workflow.slice( - workflow.indexOf('\n library:\n'), - workflow.indexOf('\n website:\n') - ); - } - async function readCanonicalDemoJob() { return readJobBlock(await readWorkflow(), 'demo-deploy'); } diff --git a/scripts/react-parity/baseline.json b/scripts/react-parity/baseline.json new file mode 100644 index 000000000..9d25d26b8 --- /dev/null +++ b/scripts/react-parity/baseline.json @@ -0,0 +1,13629 @@ +{ + "schemaVersion": 1, + "baselineHead": "7e80cebd607f5c605ef1ec81f11e5ebe3324f81b", + "sourceState": { + "modified": [ + ".github/workflows/ci.yml", + "package-lock.json", + "package.json", + "tsconfig.base.json" + ], + "untracked": [] + }, + "scope": { + "libraries": [ + "a2ui", + "ag-ui", + "chat", + "cockpit-registry", + "cockpit-runtime-bridge", + "cockpit-shell", + "cockpit-telemetry", + "design-tokens", + "e2e-harness", + "example-layouts", + "langgraph", + "middleware", + "render", + "telemetry", + "ui-react", + "workspace-react" + ], + "entryPoints": [ + "libs/a2ui/src/index.ts", + "libs/ag-ui/src/public-api.ts", + "libs/chat/src/public-api.ts", + "libs/chat/debug/public-api.ts", + "libs/chat/testing/public-api.ts", + "libs/langgraph/src/public-api.ts", + "libs/middleware/src/langgraph/index.ts", + "libs/render/src/public-api.ts", + "libs/telemetry/src/index.ts", + "libs/telemetry/src/browser/public-api.ts", + "libs/telemetry/src/node/index.ts", + "libs/telemetry/src/shared/public-api.ts" + ], + "docsRoot": "apps/website/content/docs", + "topicsRoot": "cockpit", + "configFiles": [ + "package.json", + "package-lock.json", + "nx.json", + "tsconfig.base.json", + ".github/workflows/ci.yml", + ".github/workflows/publish.yml", + ".github/workflows/release-provenance.yml", + ".github/workflows/publish-middleware-npm.yml", + ".github/workflows/publish-middleware-python.yml", + "scripts/verify-release-versions.mjs", + "scripts/cockpit-matrix.mjs", + "scripts/assemble-examples.ts", + "scripts/examples/serve-example.ts", + "apps/website/scripts/generate-api-docs.ts", + "apps/website/scripts/generate-narrative-docs.ts", + "apps/website/scripts/generate-agent-context.ts" + ] + }, + "rows": [ + { + "id": "asset:libs/a2ui/LICENSE.md", + "kind": "asset", + "path": "libs/a2ui/LICENSE.md", + "sha256": "d20c571ef693b2ea2e1c552d688d596804d64795aee4c941ab12a21e01752ba4" + }, + { + "id": "asset:libs/a2ui/README.md", + "kind": "asset", + "path": "libs/a2ui/README.md", + "sha256": "64af0e330742433af441de75fc9c31617c034cf062c3abcfab6c7fa49d0902af" + }, + { + "id": "asset:libs/a2ui/package.json", + "kind": "asset", + "path": "libs/a2ui/package.json", + "sha256": "43ac544a06ad9bf6ea765c56962aea67553205c1319db52aa1c4ad60b9dc463d" + }, + { + "id": "asset:libs/a2ui/project.json", + "kind": "asset", + "path": "libs/a2ui/project.json", + "sha256": "4bb3a6df0955b314df44cbcc527958606bae0a0a8a5f1edc30ccbe049f277f1b" + }, + { + "id": "asset:libs/a2ui/schemas/README.md", + "kind": "asset", + "path": "libs/a2ui/schemas/README.md", + "sha256": "ba3fd7a7c1fc0e9dc42c068c2d01df550e7d6ed89e3391f90e143ff38c23b4c7" + }, + { + "id": "asset:libs/a2ui/schemas/basic-catalog.json", + "kind": "asset", + "path": "libs/a2ui/schemas/basic-catalog.json", + "sha256": "8cc94d0a482e67048f9fc989964ca5da56fe42f531d919315a508989fb22e13e" + }, + { + "id": "asset:libs/a2ui/schemas/common_types.json", + "kind": "asset", + "path": "libs/a2ui/schemas/common_types.json", + "sha256": "ac79788e95e5bdf0a39808953593a53c1bc9fcdcdb55480f4610613c6591e94c" + }, + { + "id": "asset:libs/a2ui/schemas/server_to_client.json", + "kind": "asset", + "path": "libs/a2ui/schemas/server_to_client.json", + "sha256": "da75d25378b0d02069cc3de54db76f6f71cffdf2a3fd95a8fabbb1f516c07cbe" + }, + { + "id": "asset:libs/a2ui/tsconfig.json", + "kind": "asset", + "path": "libs/a2ui/tsconfig.json", + "sha256": "09fb3febb18047e8433470b3ceabd1341c66e1f951b5d7120c52be80592f4cfa" + }, + { + "id": "asset:libs/a2ui/tsconfig.lib.json", + "kind": "asset", + "path": "libs/a2ui/tsconfig.lib.json", + "sha256": "a9a1f803de9abefe825450b26516345b8b3f4325489e215431d1ebf34472e23d" + }, + { + "id": "asset:libs/ag-ui/LICENSE.md", + "kind": "asset", + "path": "libs/ag-ui/LICENSE.md", + "sha256": "d20c571ef693b2ea2e1c552d688d596804d64795aee4c941ab12a21e01752ba4" + }, + { + "id": "asset:libs/ag-ui/README.md", + "kind": "asset", + "path": "libs/ag-ui/README.md", + "sha256": "ff308bf07651a3a6849db1dc841bd39d54bc585a6f882bc6d709b49aba9c5293" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/maf-hitl-interrupt.sse", + "kind": "asset", + "path": "libs/ag-ui/fixtures/runtime-transcripts/maf-hitl-interrupt.sse", + "sha256": "4a708036495330cc71e4b25fc2af73cd804420ee3bd8bcba4a84511022d18cdb" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/maf-hitl-resume.sse", + "kind": "asset", + "path": "libs/ag-ui/fixtures/runtime-transcripts/maf-hitl-resume.sse", + "sha256": "ec0abebb6bf31420dc00c8d70ac9fa0754aca5519022a91b457665af2161acb1" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/mastra-interrupt.sse", + "kind": "asset", + "path": "libs/ag-ui/fixtures/runtime-transcripts/mastra-interrupt.sse", + "sha256": "5b8a7f8ae7276176c836876ee12b969d40f23104e726a304edb7bb7a8080af7d" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/mastra-reinterrupt.sse", + "kind": "asset", + "path": "libs/ag-ui/fixtures/runtime-transcripts/mastra-reinterrupt.sse", + "sha256": "965f13948f5f503c3840221c50122a0c77a445bbbe5d172d7be629d6b784be6e" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/mastra-resume-correct.request.json", + "kind": "asset", + "path": "libs/ag-ui/fixtures/runtime-transcripts/mastra-resume-correct.request.json", + "sha256": "5ae57cfe51e43869e492e481e3afa1f9336b9610030f64a247d85bfc7978d57f" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/strands-interrupt.sse", + "kind": "asset", + "path": "libs/ag-ui/fixtures/runtime-transcripts/strands-interrupt.sse", + "sha256": "5c64091845cb2da7978730cba6fad10c6d15876c17e70a9a801256c178790d83" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/strands-plain-chat.sse", + "kind": "asset", + "path": "libs/ag-ui/fixtures/runtime-transcripts/strands-plain-chat.sse", + "sha256": "2e86620659e31153c8a8ece61afaf97c2a5434a646d212afd059862f8e0e4d82" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/strands-resume.request.json", + "kind": "asset", + "path": "libs/ag-ui/fixtures/runtime-transcripts/strands-resume.request.json", + "sha256": "5121ca1d69d7511f46b7d4b42b4ba315f13d10fc26dc07916a813ecdc3661130" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/subagent-lifecycle.json", + "kind": "asset", + "path": "libs/ag-ui/fixtures/runtime-transcripts/subagent-lifecycle.json", + "sha256": "3af9a41186b0090da68183a8454e972a2dd8d7b0a299bf4a6517bae012b9dbee" + }, + { + "id": "asset:libs/ag-ui/ng-package.json", + "kind": "asset", + "path": "libs/ag-ui/ng-package.json", + "sha256": "082cb09f9fb8e3f1b98c32fc51c2024cabce42f40e12d21c108751cf6ff9697f" + }, + { + "id": "asset:libs/ag-ui/package.json", + "kind": "asset", + "path": "libs/ag-ui/package.json", + "sha256": "27190919faa732b07c278bc78b68e0663fa39e6c7e96d6ba45fbafc65e2bd3ee" + }, + { + "id": "asset:libs/ag-ui/project.json", + "kind": "asset", + "path": "libs/ag-ui/project.json", + "sha256": "6bbdf56f7f8275a191b3bb24550f62022bead7d2d4b173ed3067e6dcfc89b2fa" + }, + { + "id": "asset:libs/ag-ui/tsconfig.json", + "kind": "asset", + "path": "libs/ag-ui/tsconfig.json", + "sha256": "346ce4348a6d17fd234f516939f4b4b31c70cd0d90f523a7e9dfbe6979469aa4" + }, + { + "id": "asset:libs/ag-ui/tsconfig.lib.json", + "kind": "asset", + "path": "libs/ag-ui/tsconfig.lib.json", + "sha256": "2d56829b5aa728927dca322cff6d7521ff9a65a8d8f258bee0f3a4d146826219" + }, + { + "id": "asset:libs/ag-ui/tsconfig.lib.prod.json", + "kind": "asset", + "path": "libs/ag-ui/tsconfig.lib.prod.json", + "sha256": "4815c5ece87bc626f79d81495b3b60bce7bca2dc355106a9b77bea8d11855a8b" + }, + { + "id": "asset:libs/ag-ui/tsconfig.type-tests.json", + "kind": "asset", + "path": "libs/ag-ui/tsconfig.type-tests.json", + "sha256": "c178776b9c33a23d56c7c6bb2bf99caedd3f05b1b3de0ebe5ec46076f9ff0ba6" + }, + { + "id": "asset:libs/chat/CHANGELOG.md", + "kind": "asset", + "path": "libs/chat/CHANGELOG.md", + "sha256": "756220afda94558c8796a60ed80b7124a33b34199ed2d83c765a1f4f2d969d3f" + }, + { + "id": "asset:libs/chat/LICENSE.md", + "kind": "asset", + "path": "libs/chat/LICENSE.md", + "sha256": "d20c571ef693b2ea2e1c552d688d596804d64795aee4c941ab12a21e01752ba4" + }, + { + "id": "asset:libs/chat/NOTICE.md", + "kind": "asset", + "path": "libs/chat/NOTICE.md", + "sha256": "af77ae590ec0dde1495cf3a413338d7afb19aa1882fbaae7db138bc1b4dca99b" + }, + { + "id": "asset:libs/chat/README.md", + "kind": "asset", + "path": "libs/chat/README.md", + "sha256": "1d839f635effebb4091a757d476f04cf01eecb36cf3e4295f55acb8a99ed06c7" + }, + { + "id": "asset:libs/chat/debug/ng-package.json", + "kind": "asset", + "path": "libs/chat/debug/ng-package.json", + "sha256": "da669baa95391ee10d693fa87f41deb8e647e2277076ee4663ca40598cbaceb7" + }, + { + "id": "asset:libs/chat/ng-package.json", + "kind": "asset", + "path": "libs/chat/ng-package.json", + "sha256": "5b1947224519b367fb619f61b560aa956ee62339a0efa45b3f0e23205e1bb52c" + }, + { + "id": "asset:libs/chat/package.json", + "kind": "asset", + "path": "libs/chat/package.json", + "sha256": "2f98085df292faf821cf9bb7225b7822e1af28d96cd59537b2a474a71e6a0adb" + }, + { + "id": "asset:libs/chat/project.json", + "kind": "asset", + "path": "libs/chat/project.json", + "sha256": "650f32a6f72513086685aeee1ad31e0de6686a4458a6f247e09e7d5689d4f68b" + }, + { + "id": "asset:libs/chat/src/themes/default-dark.css", + "kind": "asset", + "path": "libs/chat/src/themes/default-dark.css", + "sha256": "70b8384de67f6409a9b161fe2484167078bdd3418a97fa3934346fd07779cd02" + }, + { + "id": "asset:libs/chat/src/themes/default-light.css", + "kind": "asset", + "path": "libs/chat/src/themes/default-light.css", + "sha256": "06e2562965baed880c91fdb71526befc6c9bb65eec2cbf6d7b6bfe5101612926" + }, + { + "id": "asset:libs/chat/src/themes/material-dark.css", + "kind": "asset", + "path": "libs/chat/src/themes/material-dark.css", + "sha256": "096deedbf7001e1ab81c9c6df1450a250955d60b2d780a19aaf8ad300e4e2802" + }, + { + "id": "asset:libs/chat/src/themes/material-light.css", + "kind": "asset", + "path": "libs/chat/src/themes/material-light.css", + "sha256": "4c4782f2230c0340d450d35c6956109312be6adddc4f16d1dafa3060031938d5" + }, + { + "id": "asset:libs/chat/testing/ng-package.json", + "kind": "asset", + "path": "libs/chat/testing/ng-package.json", + "sha256": "da669baa95391ee10d693fa87f41deb8e647e2277076ee4663ca40598cbaceb7" + }, + { + "id": "asset:libs/chat/tsconfig.json", + "kind": "asset", + "path": "libs/chat/tsconfig.json", + "sha256": "346ce4348a6d17fd234f516939f4b4b31c70cd0d90f523a7e9dfbe6979469aa4" + }, + { + "id": "asset:libs/chat/tsconfig.lib.json", + "kind": "asset", + "path": "libs/chat/tsconfig.lib.json", + "sha256": "762e5d78bcbd48c9b72a55cf602603203c86011f7814e74a122a607e24906628" + }, + { + "id": "asset:libs/chat/tsconfig.lib.prod.json", + "kind": "asset", + "path": "libs/chat/tsconfig.lib.prod.json", + "sha256": "4815c5ece87bc626f79d81495b3b60bce7bca2dc355106a9b77bea8d11855a8b" + }, + { + "id": "asset:libs/chat/tsconfig.spec.json", + "kind": "asset", + "path": "libs/chat/tsconfig.spec.json", + "sha256": "440dbebe320488070e90cd28d50ed4e6b1e7a727762dceae581ff17e38133e8c" + }, + { + "id": "asset:libs/chat/tsconfig.type-tests.json", + "kind": "asset", + "path": "libs/chat/tsconfig.type-tests.json", + "sha256": "dc1c927e6591f9339047bab6b5d8b61f26112c6384fb1b356c5157b0b8ee946b" + }, + { + "id": "asset:libs/cockpit-registry/package.json", + "kind": "asset", + "path": "libs/cockpit-registry/package.json", + "sha256": "d902a2a4e45a696cafcba342a159ed19195452c71a37f26ae6e0ad38aa06896a" + }, + { + "id": "asset:libs/cockpit-registry/project.json", + "kind": "asset", + "path": "libs/cockpit-registry/project.json", + "sha256": "147ddacc5a66c7afbab40bdfcfde83d4d56848ce184ac40ec904f340a28c5982" + }, + { + "id": "asset:libs/cockpit-registry/tsconfig.json", + "kind": "asset", + "path": "libs/cockpit-registry/tsconfig.json", + "sha256": "8a7e70669e9d12c19027e61235f270d0b40b13c763bc5d872c468c09808a27f3" + }, + { + "id": "asset:libs/cockpit-registry/tsconfig.lib.json", + "kind": "asset", + "path": "libs/cockpit-registry/tsconfig.lib.json", + "sha256": "0ce8fcc728a55abcbb446802f632cc9bb38da7936723417b68c10cc550d99ec5" + }, + { + "id": "asset:libs/cockpit-runtime-bridge/package.json", + "kind": "asset", + "path": "libs/cockpit-runtime-bridge/package.json", + "sha256": "e16ee6400593700fd102b0409b5bdab3bf1b5350f04ba2d42f2a3c35cf930760" + }, + { + "id": "asset:libs/cockpit-runtime-bridge/project.json", + "kind": "asset", + "path": "libs/cockpit-runtime-bridge/project.json", + "sha256": "ac3cea9981fbea850d96a6ec8597b1b2f5d5277bec3752b47280c5e04ff792fe" + }, + { + "id": "asset:libs/cockpit-runtime-bridge/tsconfig.json", + "kind": "asset", + "path": "libs/cockpit-runtime-bridge/tsconfig.json", + "sha256": "8a7e70669e9d12c19027e61235f270d0b40b13c763bc5d872c468c09808a27f3" + }, + { + "id": "asset:libs/cockpit-runtime-bridge/tsconfig.lib.json", + "kind": "asset", + "path": "libs/cockpit-runtime-bridge/tsconfig.lib.json", + "sha256": "35fc76dec3884cdf6b551e4b5ca830705dd203117dc028fac2939badde5e3483" + }, + { + "id": "asset:libs/cockpit-shell/package.json", + "kind": "asset", + "path": "libs/cockpit-shell/package.json", + "sha256": "815556b4cbfbb8b8e95f334fa2038e2d269f0de518079e717bcc5a478c709669" + }, + { + "id": "asset:libs/cockpit-shell/project.json", + "kind": "asset", + "path": "libs/cockpit-shell/project.json", + "sha256": "7c7dcdb56030f53c03cc1df21ff8b88894ab574a02f59727ad4cf4823a2a7d36" + }, + { + "id": "asset:libs/cockpit-shell/tsconfig.json", + "kind": "asset", + "path": "libs/cockpit-shell/tsconfig.json", + "sha256": "8a7e70669e9d12c19027e61235f270d0b40b13c763bc5d872c468c09808a27f3" + }, + { + "id": "asset:libs/cockpit-shell/tsconfig.lib.json", + "kind": "asset", + "path": "libs/cockpit-shell/tsconfig.lib.json", + "sha256": "e33ccc531d242904beff0345b135526f3697b6d6f18ceb53122c75bb00272d22" + }, + { + "id": "asset:libs/cockpit-telemetry/README.md", + "kind": "asset", + "path": "libs/cockpit-telemetry/README.md", + "sha256": "51156dc3e88189e4611933fcbc5508788629a954a8647bf30c2e8d9bc39c86b3" + }, + { + "id": "asset:libs/cockpit-telemetry/ng-package.json", + "kind": "asset", + "path": "libs/cockpit-telemetry/ng-package.json", + "sha256": "8c2ae14f0d94d274008ab714564dcb740421ad5a8f27c5cc3945784e3814ac36" + }, + { + "id": "asset:libs/cockpit-telemetry/package.json", + "kind": "asset", + "path": "libs/cockpit-telemetry/package.json", + "sha256": "0aa354d862c286860495653842b6fcccd3236294e8587776703d56fb275c5820" + }, + { + "id": "asset:libs/cockpit-telemetry/project.json", + "kind": "asset", + "path": "libs/cockpit-telemetry/project.json", + "sha256": "bc0f45fad49e9ae0edf0b1430edba1b13d4615e6fbd4b531eb80f11c23441555" + }, + { + "id": "asset:libs/cockpit-telemetry/tsconfig.json", + "kind": "asset", + "path": "libs/cockpit-telemetry/tsconfig.json", + "sha256": "97ed5ceb01ae9e6f2f7abd6e313c8d48934a5688acf2933f04b4cf396ac4d536" + }, + { + "id": "asset:libs/cockpit-telemetry/tsconfig.lib.json", + "kind": "asset", + "path": "libs/cockpit-telemetry/tsconfig.lib.json", + "sha256": "d9ecc637cae84224d735e811dc95bd83ef50126436f26c5a48aac850e2a593a2" + }, + { + "id": "asset:libs/cockpit-telemetry/tsconfig.spec.json", + "kind": "asset", + "path": "libs/cockpit-telemetry/tsconfig.spec.json", + "sha256": "440dbebe320488070e90cd28d50ed4e6b1e7a727762dceae581ff17e38133e8c" + }, + { + "id": "asset:libs/design-tokens/package.json", + "kind": "asset", + "path": "libs/design-tokens/package.json", + "sha256": "5d3d69b881f6562910b70f37a382736d6ce14fbbe891212fabfcafb73c1d1135" + }, + { + "id": "asset:libs/design-tokens/project.json", + "kind": "asset", + "path": "libs/design-tokens/project.json", + "sha256": "118f350aaf0f5e5cfb02e31acc4b0fbddbf2049bd88046c36b318cf4f2a87bfc" + }, + { + "id": "asset:libs/design-tokens/src/lib/theme.css", + "kind": "asset", + "path": "libs/design-tokens/src/lib/theme.css", + "sha256": "62a11f8c405d0623422a8b56384b877b27e08f1ac0affb92c018ae8ffca2678b" + }, + { + "id": "asset:libs/design-tokens/src/lib/tokens-dark.css", + "kind": "asset", + "path": "libs/design-tokens/src/lib/tokens-dark.css", + "sha256": "79da4d7bf003cf70b9958db8b1dd7466c4d4b8b720e441c38d856b55b51e2a09" + }, + { + "id": "asset:libs/design-tokens/src/lib/tokens.css", + "kind": "asset", + "path": "libs/design-tokens/src/lib/tokens.css", + "sha256": "80d9d105bfacaefc9eb3b14691cb326c2e910574d3d0bb9c168269004afda8ec" + }, + { + "id": "asset:libs/design-tokens/tsconfig.json", + "kind": "asset", + "path": "libs/design-tokens/tsconfig.json", + "sha256": "cb6c39f6fde12afb9446c6b5675c3a54018aa8e9e465467bf2b55d6818589f8b" + }, + { + "id": "asset:libs/design-tokens/tsconfig.lib.json", + "kind": "asset", + "path": "libs/design-tokens/tsconfig.lib.json", + "sha256": "c30c0ead57f820cc2569bf7fc6512adc81aec89bb8096e13b2b2cc17a4f41e61" + }, + { + "id": "asset:libs/e2e-harness/README.md", + "kind": "asset", + "path": "libs/e2e-harness/README.md", + "sha256": "ade046c81687b13b35d8e94fa141ae74acbd5436332fa05136cfcffbb2a77858" + }, + { + "id": "asset:libs/e2e-harness/project.json", + "kind": "asset", + "path": "libs/e2e-harness/project.json", + "sha256": "4fed1b1085c486e1442ffbdec83b120a40b29d61c850340a17e8ed6a28ee272f" + }, + { + "id": "asset:libs/e2e-harness/tsconfig.json", + "kind": "asset", + "path": "libs/e2e-harness/tsconfig.json", + "sha256": "0bf7edd81c7eb1b3bbc4162e6fb5e1c7d4f12e11e1200a6e3c1baa889559b269" + }, + { + "id": "asset:libs/example-layouts/ng-package.json", + "kind": "asset", + "path": "libs/example-layouts/ng-package.json", + "sha256": "351451aadb83769b8c008637a35bf9d757846cc515f44982429fa8659d53d96f" + }, + { + "id": "asset:libs/example-layouts/package.json", + "kind": "asset", + "path": "libs/example-layouts/package.json", + "sha256": "4bbc799b31804cd537ff4676f3d357df49218495e1de6c06062a1a1299db4212" + }, + { + "id": "asset:libs/example-layouts/project.json", + "kind": "asset", + "path": "libs/example-layouts/project.json", + "sha256": "6c8dcafef216c17beb8aa038fc1c818418564a72a163a45246c4b67dcaaa9ab7" + }, + { + "id": "asset:libs/example-layouts/src/theme.css", + "kind": "asset", + "path": "libs/example-layouts/src/theme.css", + "sha256": "4f43c82173dc25ca7a2b23fa2c980a8cdc897ae6f491502c02794f2ddbc2817d" + }, + { + "id": "asset:libs/example-layouts/tsconfig.json", + "kind": "asset", + "path": "libs/example-layouts/tsconfig.json", + "sha256": "346ce4348a6d17fd234f516939f4b4b31c70cd0d90f523a7e9dfbe6979469aa4" + }, + { + "id": "asset:libs/example-layouts/tsconfig.lib.json", + "kind": "asset", + "path": "libs/example-layouts/tsconfig.lib.json", + "sha256": "7e74f6e3f731327559641a508535e9e745bb017fa8cd1ab6f3ef4862e8a20e56" + }, + { + "id": "asset:libs/example-layouts/tsconfig.lib.prod.json", + "kind": "asset", + "path": "libs/example-layouts/tsconfig.lib.prod.json", + "sha256": "4815c5ece87bc626f79d81495b3b60bce7bca2dc355106a9b77bea8d11855a8b" + }, + { + "id": "asset:libs/example-layouts/tsconfig.spec.json", + "kind": "asset", + "path": "libs/example-layouts/tsconfig.spec.json", + "sha256": "511690d3046bbdf57e55a1d50212daadd6b38348032216b2c1ff1819974e46a5" + }, + { + "id": "asset:libs/langgraph/LICENSE.md", + "kind": "asset", + "path": "libs/langgraph/LICENSE.md", + "sha256": "d20c571ef693b2ea2e1c552d688d596804d64795aee4c941ab12a21e01752ba4" + }, + { + "id": "asset:libs/langgraph/README.md", + "kind": "asset", + "path": "libs/langgraph/README.md", + "sha256": "c9e0dbf35d1d2906bf5115318b96e78c115a77454c4f3243a26d89d62989ae93" + }, + { + "id": "asset:libs/langgraph/ng-package.json", + "kind": "asset", + "path": "libs/langgraph/ng-package.json", + "sha256": "be986583fdfea5cf0bddbf2a67d90221db770bc5da947c5516bd0c2c83a9f6e1" + }, + { + "id": "asset:libs/langgraph/package.json", + "kind": "asset", + "path": "libs/langgraph/package.json", + "sha256": "78a1bbfe2d9341ad6d41f43929fbf8e129c51979d49dea7e8cfe3ea3074195b0" + }, + { + "id": "asset:libs/langgraph/project.json", + "kind": "asset", + "path": "libs/langgraph/project.json", + "sha256": "ec15f5414827294ea51ce5bf56755f576c28cd112961b97adbffbfa379b2fd73" + }, + { + "id": "asset:libs/langgraph/test/fixtures/streaming-reasoning-puzzle.json", + "kind": "asset", + "path": "libs/langgraph/test/fixtures/streaming-reasoning-puzzle.json", + "sha256": "2849a0b101e371f89a593a05e284e283289c53a15d775a7be3b80cc8e72dfe56" + }, + { + "id": "asset:libs/langgraph/tsconfig.json", + "kind": "asset", + "path": "libs/langgraph/tsconfig.json", + "sha256": "346ce4348a6d17fd234f516939f4b4b31c70cd0d90f523a7e9dfbe6979469aa4" + }, + { + "id": "asset:libs/langgraph/tsconfig.lib.json", + "kind": "asset", + "path": "libs/langgraph/tsconfig.lib.json", + "sha256": "2d56829b5aa728927dca322cff6d7521ff9a65a8d8f258bee0f3a4d146826219" + }, + { + "id": "asset:libs/langgraph/tsconfig.lib.prod.json", + "kind": "asset", + "path": "libs/langgraph/tsconfig.lib.prod.json", + "sha256": "4815c5ece87bc626f79d81495b3b60bce7bca2dc355106a9b77bea8d11855a8b" + }, + { + "id": "asset:libs/langgraph/tsconfig.type-tests.json", + "kind": "asset", + "path": "libs/langgraph/tsconfig.type-tests.json", + "sha256": "c178776b9c33a23d56c7c6bb2bf99caedd3f05b1b3de0ebe5ec46076f9ff0ba6" + }, + { + "id": "asset:libs/middleware/CHANGELOG.md", + "kind": "asset", + "path": "libs/middleware/CHANGELOG.md", + "sha256": "711b6aa1190931990668c14bc34e887e36ab6f45026703cf79c7c610668c496b" + }, + { + "id": "asset:libs/middleware/README.md", + "kind": "asset", + "path": "libs/middleware/README.md", + "sha256": "74ebc0a85ad48d3812d3a504c9b5764432ed754148c86518809782ad3fc04f40" + }, + { + "id": "asset:libs/middleware/package.json", + "kind": "asset", + "path": "libs/middleware/package.json", + "sha256": "e03c913eb465267e27e89c71710ea7ce96355b3ee92a461791ad60fb5b0ecb4c" + }, + { + "id": "asset:libs/middleware/project.json", + "kind": "asset", + "path": "libs/middleware/project.json", + "sha256": "182b82c6d3126234bfbff665a18aaabd230858345b7d6a1eaa2d541eddb8a185" + }, + { + "id": "asset:libs/middleware/tsconfig.json", + "kind": "asset", + "path": "libs/middleware/tsconfig.json", + "sha256": "45dfd1a77ff5e64ff918c34e2a7e8956af079c19dd01dc2dbcfd308ac8c5f6a4" + }, + { + "id": "asset:libs/middleware/tsconfig.lib.json", + "kind": "asset", + "path": "libs/middleware/tsconfig.lib.json", + "sha256": "61d1a2efe47f679afd45d5fbebaf2836f669f5e5daac243d2647462a13516c33" + }, + { + "id": "asset:libs/middleware/tsconfig.spec.json", + "kind": "asset", + "path": "libs/middleware/tsconfig.spec.json", + "sha256": "9a15688caeaea6c7159bdbff2a3bd53dd09dc6ffbe35b40f14d67b961567715c" + }, + { + "id": "asset:libs/render/LICENSE.md", + "kind": "asset", + "path": "libs/render/LICENSE.md", + "sha256": "d20c571ef693b2ea2e1c552d688d596804d64795aee4c941ab12a21e01752ba4" + }, + { + "id": "asset:libs/render/README.md", + "kind": "asset", + "path": "libs/render/README.md", + "sha256": "8c1ffd36a69279746e310e7e81414a461960bd53b7859b010e008739469727f6" + }, + { + "id": "asset:libs/render/ng-package.json", + "kind": "asset", + "path": "libs/render/ng-package.json", + "sha256": "240362e3ff5443fca5844266004d78e8ac08f73decce5cddaa990e06426078b3" + }, + { + "id": "asset:libs/render/package.json", + "kind": "asset", + "path": "libs/render/package.json", + "sha256": "a04e3afc50fe47d0ca4fae72af72113867b403d63bdfdc754952685aedeb1aec" + }, + { + "id": "asset:libs/render/project.json", + "kind": "asset", + "path": "libs/render/project.json", + "sha256": "88a51fd7c907aebebb2a7739ce134fa80fd1e7d83b9d5e7c48947d470b4f81a1" + }, + { + "id": "asset:libs/render/tsconfig.json", + "kind": "asset", + "path": "libs/render/tsconfig.json", + "sha256": "346ce4348a6d17fd234f516939f4b4b31c70cd0d90f523a7e9dfbe6979469aa4" + }, + { + "id": "asset:libs/render/tsconfig.lib.json", + "kind": "asset", + "path": "libs/render/tsconfig.lib.json", + "sha256": "2d56829b5aa728927dca322cff6d7521ff9a65a8d8f258bee0f3a4d146826219" + }, + { + "id": "asset:libs/render/tsconfig.lib.prod.json", + "kind": "asset", + "path": "libs/render/tsconfig.lib.prod.json", + "sha256": "4815c5ece87bc626f79d81495b3b60bce7bca2dc355106a9b77bea8d11855a8b" + }, + { + "id": "asset:libs/render/tsconfig.spec.json", + "kind": "asset", + "path": "libs/render/tsconfig.spec.json", + "sha256": "440dbebe320488070e90cd28d50ed4e6b1e7a727762dceae581ff17e38133e8c" + }, + { + "id": "asset:libs/telemetry/LICENSE.md", + "kind": "asset", + "path": "libs/telemetry/LICENSE.md", + "sha256": "d20c571ef693b2ea2e1c552d688d596804d64795aee4c941ab12a21e01752ba4" + }, + { + "id": "asset:libs/telemetry/README.md", + "kind": "asset", + "path": "libs/telemetry/README.md", + "sha256": "ac737f1a97ddac477be99875e958361d3ac07fa004d34d6fe3b3973e30f6db41" + }, + { + "id": "asset:libs/telemetry/ng-package.json", + "kind": "asset", + "path": "libs/telemetry/ng-package.json", + "sha256": "6bbb0c6fba5cabf5da76d91187bbece069a3576de1fc6fb96809c1c2ca21bfbf" + }, + { + "id": "asset:libs/telemetry/package.json", + "kind": "asset", + "path": "libs/telemetry/package.json", + "sha256": "ae9c6c0e0d6a268f3265ac0ae141c2396e4094f1f2883d6e3c49cc6f07a70512" + }, + { + "id": "asset:libs/telemetry/project.json", + "kind": "asset", + "path": "libs/telemetry/project.json", + "sha256": "df2dbdfa58e093e1c0618b7da718109e9b8c2db7a46fc98f34d7eec779c53b3c" + }, + { + "id": "asset:libs/telemetry/tsconfig.json", + "kind": "asset", + "path": "libs/telemetry/tsconfig.json", + "sha256": "ababd9a21bedd818fdeafbb6f884209ad5461418827d0bd2059b1b51199373b7" + }, + { + "id": "asset:libs/telemetry/tsconfig.lib.browser.json", + "kind": "asset", + "path": "libs/telemetry/tsconfig.lib.browser.json", + "sha256": "02149876c4882ab3cfcc83fb603ab55065d8dbe2609901281baccd4f53dfbed9" + }, + { + "id": "asset:libs/telemetry/tsconfig.lib.json", + "kind": "asset", + "path": "libs/telemetry/tsconfig.lib.json", + "sha256": "68b4d6fff1bf680da595aeb9eec4dfd99b3ec771f2419dca78b76db6c2e746cf" + }, + { + "id": "asset:libs/telemetry/tsconfig.spec.json", + "kind": "asset", + "path": "libs/telemetry/tsconfig.spec.json", + "sha256": "ecc7bb80f8719d4170a8f2da0ba981a4f6ea1106c019980828d0f09b347254bb" + }, + { + "id": "asset:libs/ui-react/package.json", + "kind": "asset", + "path": "libs/ui-react/package.json", + "sha256": "9374053061b02a2cd65b128c8456a036c81a06e49b65a6c3d775a96793f027a3" + }, + { + "id": "asset:libs/ui-react/project.json", + "kind": "asset", + "path": "libs/ui-react/project.json", + "sha256": "56be25a5f6c8a4d91f9c531750ca13aedc4cf3602ed418ec4c8ca801e902d97a" + }, + { + "id": "asset:libs/ui-react/src/lib/.gitkeep", + "kind": "asset", + "path": "libs/ui-react/src/lib/.gitkeep", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "id": "asset:libs/ui-react/tsconfig.json", + "kind": "asset", + "path": "libs/ui-react/tsconfig.json", + "sha256": "2d940b66b47d944b18198425d0a235877951d2f0d24ae307cb05a85e32309db0" + }, + { + "id": "asset:libs/ui-react/tsconfig.lib.json", + "kind": "asset", + "path": "libs/ui-react/tsconfig.lib.json", + "sha256": "f178f927edd8991650b3504c164228729a21a394e06cd406e9c88e6bee9a9c0a" + }, + { + "id": "asset:libs/workspace-react/package.json", + "kind": "asset", + "path": "libs/workspace-react/package.json", + "sha256": "ceac8226026346f427c8eced071393319f43199939dd70b13e0ead17ce039b5d" + }, + { + "id": "asset:libs/workspace-react/project.json", + "kind": "asset", + "path": "libs/workspace-react/project.json", + "sha256": "cb5f7051ca646de29574971bb6304ac699055936a3c6d081b610d98bcc1e0cf9" + }, + { + "id": "asset:libs/workspace-react/src/styles/workspace.css", + "kind": "asset", + "path": "libs/workspace-react/src/styles/workspace.css", + "sha256": "e13582704da42f9ab600c0409de451aa96533136ad78d487d973f16b3922d487" + }, + { + "id": "asset:libs/workspace-react/tsconfig.json", + "kind": "asset", + "path": "libs/workspace-react/tsconfig.json", + "sha256": "aa6318db64921756810642bcc4b001c61cd0c06044afc7c9f327b3f02b1fee5d" + }, + { + "id": "asset:libs/workspace-react/tsconfig.lib.json", + "kind": "asset", + "path": "libs/workspace-react/tsconfig.lib.json", + "sha256": "7b1c282944428eef146c336541cd5c6ac8e6b1cc4c6452ab39a55481896d6be0" + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/chat-debug.component.ts#ChatDebugComponent", + "kind": "component", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/chat-debug.component.ts", + "symbol": "ChatDebugComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-debug',\n standalone: true,\n imports: [TimelineInspectorComponent, StateInspectorComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_DEBUG_TOKENS,\n `\n :host {\n display: contents;\n }\n\n /* ── Status pill launcher ─────────────────────────────────────── */\n .launcher {\n position: fixed;\n top: 20px;\n right: 20px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: var(--tplane-chat-debug-radius-pill);\n background: var(--tplane-chat-debug-bg);\n border: 1px solid var(--tplane-chat-debug-border);\n color: var(--tplane-chat-debug-text);\n cursor: pointer;\n z-index: 990;\n box-shadow: var(--tplane-chat-debug-shadow-pill);\n transition: background 120ms ease, border-color 120ms ease;\n padding: 0;\n }\n .launcher:hover {\n background: var(--tplane-chat-debug-surface);\n border-color: var(--tplane-chat-debug-border-strong);\n }\n .launcher__dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--tplane-chat-debug-success);\n box-shadow: 0 0 8px\n color-mix(in srgb, var(--tplane-chat-debug-success) 60%, transparent);\n }\n .launcher__dot--streaming {\n background: var(--tplane-chat-debug-accent);\n box-shadow: 0 0 8px\n color-mix(in srgb, var(--tplane-chat-debug-accent) 70%, transparent);\n animation: chat-debug-pill-pulse 1.2s ease-in-out infinite;\n }\n @keyframes chat-debug-pill-pulse {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.6;\n transform: scale(0.85);\n }\n }\n\n /* ── Docked panel ─────────────────────────────────────────────── */\n .panel {\n position: fixed;\n background: var(--tplane-chat-debug-bg);\n color: var(--tplane-chat-debug-text);\n border: 1px solid var(--tplane-chat-debug-border);\n z-index: 991;\n display: flex;\n flex-direction: column;\n box-shadow: var(--tplane-chat-debug-shadow-panel);\n animation: chat-debug-panel-enter 120ms ease;\n }\n .panel--right {\n top: 0;\n right: var(--tplane-chat-sidebar-claim-right, 0);\n bottom: 0;\n width: var(--panel-size, 420px);\n border-right: 0;\n border-top-left-radius: var(--tplane-chat-debug-radius-panel);\n border-bottom-left-radius: var(--tplane-chat-debug-radius-panel);\n transform-origin: bottom right;\n transition: right 200ms ease-out;\n }\n .panel--left {\n top: 0;\n left: 0;\n bottom: 0;\n width: var(--panel-size, 420px);\n border-left: 0;\n border-top-right-radius: var(--tplane-chat-debug-radius-panel);\n border-bottom-right-radius: var(--tplane-chat-debug-radius-panel);\n transform-origin: bottom left;\n }\n .panel--bottom {\n left: 0;\n right: var(--tplane-chat-sidebar-claim-right, 0);\n bottom: 0;\n height: var(--panel-size, 40vh);\n border-bottom: 0;\n border-top-left-radius: var(--tplane-chat-debug-radius-panel);\n border-top-right-radius: var(--tplane-chat-debug-radius-panel);\n transform-origin: bottom right;\n transition: right 200ms ease-out;\n }\n /* Mobile breakpoint: when an edge-claimer occupies the right and\n the device is narrow, the bottom strip's effective width is\n ~zero. Explicitly hide it so it doesn't intercept pointer events\n on the sidebar drawer. The chat-debug launcher remains visible. */\n @media (max-width: 767px) {\n .panel--bottom {\n display: none;\n }\n }\n @keyframes chat-debug-panel-enter {\n from {\n opacity: 0;\n transform: scale(0.96);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n .panel__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--tplane-chat-debug-border);\n min-height: 44px;\n box-sizing: border-box;\n }\n .panel__title {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--tplane-chat-debug-text);\n }\n .panel__actions {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .panel__dock-group {\n display: inline-flex;\n gap: 0;\n padding: 2px;\n background: var(--tplane-chat-debug-bg-deep);\n border: 1px solid var(--tplane-chat-debug-border);\n border-radius: 6px;\n }\n .panel__dock-btn {\n appearance: none;\n background: transparent;\n border: 0;\n border-radius: 4px;\n width: 24px;\n height: 22px;\n padding: 0;\n color: var(--tplane-chat-debug-text-subtle);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background 120ms ease, color 120ms ease;\n }\n .panel__dock-btn:hover {\n color: var(--tplane-chat-debug-text);\n }\n .panel__dock-btn.is-active {\n background: var(--tplane-chat-debug-border);\n color: var(--tplane-chat-debug-text);\n }\n .panel__dock-btn svg {\n display: block;\n }\n\n .panel__close {\n appearance: none;\n background: transparent;\n border: 0;\n border-radius: 6px;\n width: 26px;\n height: 26px;\n margin-left: 4px;\n color: var(--tplane-chat-debug-text-subtle);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background 120ms ease, color 120ms ease;\n }\n .panel__close:hover {\n background: var(--tplane-chat-debug-surface);\n color: var(--tplane-chat-debug-text);\n }\n\n .panel__controls {\n border-bottom: 1px solid var(--tplane-chat-debug-border);\n overflow-y: auto;\n max-height: 50%;\n background: var(--tplane-chat-debug-bg);\n }\n .panel__controls:empty {\n display: none;\n }\n\n .panel__tabs {\n display: flex;\n gap: 4px;\n border-bottom: 1px solid var(--tplane-chat-debug-border);\n padding: 0 12px;\n background: var(--tplane-chat-debug-bg);\n }\n .panel__tab {\n appearance: none;\n background: transparent;\n border: 0;\n border-bottom: 2px solid transparent;\n padding: 10px 8px;\n font: inherit;\n font-size: 13px;\n font-weight: 500;\n color: var(--tplane-chat-debug-text-muted);\n cursor: pointer;\n transition: color 120ms ease, border-color 120ms ease;\n margin-bottom: -1px;\n }\n .panel__tab:hover {\n color: var(--tplane-chat-debug-text);\n }\n .panel__tab.is-active {\n color: var(--tplane-chat-debug-text);\n border-bottom-color: var(--tplane-chat-debug-accent);\n }\n\n .panel__body {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n background: var(--tplane-chat-debug-bg);\n }\n `,\n ],\n template: `\n @if (!open() && launcher() === 'floating') {\n \n \n \n } @else if (open() && agent(); as currentAgent) {\n \n
\n

Chat Devtools

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n \n
\n \n\n @if (tabs().length > 1) {\n
\n @for (tab of tabs(); track tab.id) {\n \n {{ tab.label }}\n \n }\n
\n }\n\n
\n @switch (activeTab()?.kind) { @case ('builtin-timeline') { @if\n (historyAgent(); as history) {\n \n } } @case ('builtin-state') {\n \n } }\n
\n \n }\n `,\n})\nexport class ChatDebugComponent {\n readonly agent = input(null);\n readonly dock = input('right');\n readonly defaultOpen = input(false);\n readonly launcher = input<'floating' | 'none'>('floating');\n readonly storageKey = input('chat-debug');\n readonly replayRequested = output();\n readonly forkRequested = output();\n readonly openChange = output();\n readonly dockChange = output();\n protected readonly open = signal(false);\n protected readonly dockState = signal('right');\n private readonly userDockOverride = signal(false);\n protected readonly activeTabId = signal('timeline');\n protected readonly historyAgent = computed(() => {\n const agent = this.agent();\n return agent && hasHistory(agent) ? agent : null;\n });\n private readonly hydrated = signal(false);\n protected readonly isStreaming = computed(() => {\n const status = this.agent()?.status?.();\n return status === 'running';\n });\n protected readonly tabs = computed((): TabEntry[] => {\n if (!this.agent())\n return [];\n return [\n ...(this.historyAgent()\n ? [\n {\n id: 'timeline',\n label: 'Timeline',\n kind: 'builtin-timeline',\n } satisfies TabEntry,\n ]\n : []),\n { id: 'state', label: 'State', kind: 'builtin-state' },\n ];\n });\n protected readonly activeTab = computed(() => this.tabs().find((t) => t.id === this.activeTabId()));\n private readonly hostEl: ElementRef = inject(ElementRef);\n constructor() {\n ensureChatDebugRootStyles();\n effect(() => {\n const tabs = this.tabs();\n if (tabs.length === 0)\n return;\n if (tabs.some((tab) => tab.id === this.activeTabId()))\n return;\n this.activeTabId.set(tabs[0].id);\n });\n afterNextRender(() => {\n const restore = createPersistence(this.storageKey());\n const persistedOpen = restore.read('open');\n if (!this.open()) {\n this.open.set(persistedOpen ?? this.defaultOpen());\n }\n const persistedDock = restore.read('dock');\n this.dockState.set(persistedDock ?? this.dock());\n const persistedTab = restore.read('tab');\n if (persistedTab)\n this.activeTabId.set(persistedTab);\n this.hydrated.set(true);\n });\n effect(() => {\n if (!this.hydrated())\n return;\n const p = createPersistence(this.storageKey());\n p.write('open', this.open());\n p.write('dock', this.dockState());\n p.write('tab', this.activeTabId());\n });\n effect(() => {\n if (typeof document === 'undefined')\n return;\n const html = document.documentElement;\n if (this.open()) {\n html.dataset['threadplaneChatDebug'] = this.dockState();\n }\n else {\n delete html.dataset['threadplaneChatDebug'];\n }\n });\n effect(() => {\n const isOpen = this.open();\n if (!isOpen)\n return;\n if (this.userDockOverride())\n return;\n if (typeof document === 'undefined')\n return;\n if (!document.querySelector('chat-sidebar'))\n return;\n this.dockState.set('bottom');\n });\n }\n setOpen(value: boolean): void {\n this.open.set(value);\n this.openChange.emit(value);\n }\n setDock(next: DockPosition): void {\n this.userDockOverride.set(true);\n this.dockState.set(next);\n this.dockChange.emit(next);\n }\n setActiveTab(id: string): void {\n this.activeTabId.set(id);\n }\n @HostListener('document:keydown.escape')\n protected onEsc(): void {\n if (this.open())\n this.setOpen(false);\n }\n @HostListener('document:click', ['$event'])\n protected onDocumentClick(event: MouseEvent): void {\n if (!this.open())\n return;\n const path = event.composedPath();\n if (path.includes(this.hostEl.nativeElement))\n return;\n this.setOpen(false);\n }\n}" + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/debug-checkpoint-card.component.ts#DebugCheckpointCardComponent", + "kind": "component", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/debug-checkpoint-card.component.ts", + "symbol": "DebugCheckpointCardComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-debug-checkpoint-card',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_DEBUG_TOKENS,\n `\n .debug-checkpoint-card {\n width: 100%;\n text-align: left;\n border-radius: var(--tplane-chat-radius-card);\n border: 1px solid var(--tplane-chat-separator);\n padding: 8px 12px;\n cursor: pointer;\n background: var(--tplane-chat-bg);\n transition: background 150ms ease, border-color 150ms ease;\n }\n .debug-checkpoint-card:hover {\n background: color-mix(in srgb, var(--tplane-chat-text) 5%, transparent);\n }\n .debug-checkpoint-card--selected {\n border-color: var(--tplane-chat-text-muted);\n background: color-mix(in srgb, var(--tplane-chat-text) 5%, transparent);\n }\n .debug-checkpoint-card__title {\n font-size: var(--tplane-chat-font-size-xs);\n font-weight: 500;\n color: var(--tplane-chat-text);\n margin: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .debug-checkpoint-card__meta {\n display: flex;\n gap: 8px;\n margin-top: 4px;\n }\n .debug-checkpoint-card__badge {\n font-size: var(--tplane-chat-font-size-xs);\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--tplane-chat-surface-alt);\n color: var(--tplane-chat-text-muted);\n }\n `,\n ],\n template: `\n \n

{{ checkpoint().node ?? 'Unknown' }}

\n
\n @if (checkpoint().duration !== null && checkpoint().duration !== undefined) {\n {{ checkpoint().duration }}ms\n }\n @if (checkpoint().tokenCount !== null && checkpoint().tokenCount !== undefined) {\n {{ checkpoint().tokenCount }} tok\n }\n
\n \n `,\n})\nexport class DebugCheckpointCardComponent {\n readonly checkpoint = input.required();\n readonly isSelected = input(false);\n readonly selected = output();\n}" + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/debug-state-diff.component.ts#DebugStateDiffComponent", + "kind": "component", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/debug-state-diff.component.ts", + "symbol": "DebugStateDiffComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-debug-state-diff',\n standalone: true,\n imports: [JsonPipe],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_DEBUG_TOKENS,\n `\n .debug-state-diff__empty {\n font-size: var(--tplane-chat-font-size-xs);\n color: var(--tplane-chat-text-muted);\n font-style: italic;\n margin: 0;\n }\n .debug-state-diff__list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n .debug-state-diff__entry {\n font-size: var(--tplane-chat-font-size-xs);\n font-family: var(--tplane-chat-font-mono);\n padding: 4px 8px;\n border-radius: 4px;\n }\n .debug-state-diff__entry--added {\n background: var(--tplane-chat-surface-alt);\n color: var(--tplane-chat-success);\n }\n .debug-state-diff__entry--removed {\n background: var(--tplane-chat-error-bg);\n color: var(--tplane-chat-error-text);\n }\n .debug-state-diff__entry--changed {\n background: var(--tplane-chat-warning-bg);\n color: var(--tplane-chat-warning-text);\n }\n .debug-state-diff__key { font-weight: 600; }\n .debug-state-diff__value {\n display: block;\n padding-left: 16px;\n color: var(--tplane-chat-text-muted);\n }\n `,\n ],\n template: `\n @if (diffEntries().length === 0) {\n

No changes

\n } @else {\n
\n @for (entry of diffEntries(); track entry.path) {\n
\n {{ prefix(entry.type) }} {{ entry.path }}\n @if (entry.type === 'changed') {\n {{ entry.before | json }} → {{ entry.after | json }}\n } @else if (entry.type === 'added') {\n {{ entry.after | json }}\n } @else {\n {{ entry.before | json }}\n }\n
\n }\n
\n }\n `,\n})\nexport class DebugStateDiffComponent {\n readonly before = input>({});\n readonly after = input>({});\n readonly diffEntries = computed((): DiffEntry[] => computeStateDiff(this.before(), this.after()));\n prefix(type: DiffEntry['type']): string {\n switch (type) {\n case 'added': return '+';\n case 'removed': return '-';\n case 'changed': return '~';\n }\n }\n entryClass(type: DiffEntry['type']): string {\n switch (type) {\n case 'added': return 'debug-state-diff__entry--added';\n case 'removed': return 'debug-state-diff__entry--removed';\n case 'changed': return 'debug-state-diff__entry--changed';\n }\n }\n colorClass(type: DiffEntry['type']): string {\n return this.entryClass(type);\n }\n}" + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/debug-state-inspector.component.ts#DebugStateInspectorComponent", + "kind": "component", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/debug-state-inspector.component.ts", + "symbol": "DebugStateInspectorComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-debug-state-inspector',\n standalone: true,\n imports: [JsonPipe],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_DEBUG_TOKENS,\n `\n .debug-state-inspector {\n overflow: auto;\n max-height: 256px;\n }\n .debug-state-inspector__pre {\n font-size: var(--tplane-chat-font-size-xs);\n font-family: var(--tplane-chat-font-mono);\n color: var(--tplane-chat-text);\n white-space: pre-wrap;\n word-break: break-all;\n margin: 0;\n }\n `,\n ],\n template: `\n
\n
{{ state() | json }}
\n
\n `,\n})\nexport class DebugStateInspectorComponent {\n readonly state = input>({});\n}" + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/inspectors/state-inspector.component.ts#StateInspectorComponent", + "kind": "component", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/inspectors/state-inspector.component.ts", + "symbol": "StateInspectorComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-debug-state-tab',\n standalone: true,\n imports: [DebugStateInspectorComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_DEBUG_TOKENS,\n `\n :host { display: flex; flex-direction: column; height: 100%; background: var(--tplane-chat-debug-bg); }\n .state__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n border-bottom: 1px solid var(--tplane-chat-debug-border);\n background: var(--tplane-chat-debug-bg);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--tplane-chat-debug-text-subtle);\n }\n .state__copy {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--tplane-chat-debug-bg-deep);\n border: 1px solid var(--tplane-chat-debug-border);\n border-radius: 6px;\n padding: 3px 8px;\n font: inherit;\n font-size: 11px;\n letter-spacing: 0;\n text-transform: none;\n color: var(--tplane-chat-debug-text-muted);\n cursor: pointer;\n transition: color 120ms ease, border-color 120ms ease;\n }\n .state__copy:hover {\n color: var(--tplane-chat-debug-text);\n border-color: var(--tplane-chat-debug-border-strong);\n }\n .state__copy.is-copied {\n color: var(--tplane-chat-debug-success);\n border-color: var(--tplane-chat-debug-success);\n }\n .state__copy svg { display: block; }\n .state__body {\n flex: 1;\n overflow-y: auto;\n padding: 12px 16px;\n color: var(--tplane-chat-debug-text);\n }\n `,\n ],\n template: `\n
\n Current state\n \n
\n
\n \n
\n `,\n})\nexport class StateInspectorComponent {\n readonly agent = input.required();\n readonly state = computed((): Record => {\n return this.agent().state();\n });\n protected readonly justCopied = signal(false);\n copy(): void {\n if (typeof navigator === 'undefined' || !navigator.clipboard)\n return;\n void navigator.clipboard.writeText(JSON.stringify(this.state(), null, 2));\n this.justCopied.set(true);\n setTimeout(() => this.justCopied.set(false), 1500);\n }\n}" + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/inspectors/timeline-inspector.component.ts#TimelineInspectorComponent", + "kind": "component", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/inspectors/timeline-inspector.component.ts", + "symbol": "TimelineInspectorComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-debug-timeline-inspector',\n standalone: true,\n imports: [DebugCheckpointCardComponent, DebugStateDiffComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_DEBUG_TOKENS,\n `\n :host { display: flex; flex-direction: column; height: 100%; outline: none; }\n .timeline__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n border-bottom: 1px solid var(--tplane-chat-debug-border);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--tplane-chat-debug-text-subtle);\n background: var(--tplane-chat-debug-bg);\n }\n .timeline__count { display: inline-flex; align-items: center; gap: 6px; }\n .timeline__count-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 18px;\n padding: 0 6px;\n border-radius: 9px;\n background: var(--tplane-chat-debug-surface);\n border: 1px solid var(--tplane-chat-debug-border);\n color: var(--tplane-chat-debug-text);\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0;\n text-transform: none;\n font-variant-numeric: tabular-nums;\n }\n .timeline__clear {\n background: transparent;\n border: 0;\n cursor: pointer;\n color: var(--tplane-chat-debug-text-subtle);\n font: inherit;\n font-size: 11px;\n letter-spacing: 0;\n text-transform: none;\n padding: 2px 6px;\n border-radius: 6px;\n transition: color 120ms ease, background 120ms ease;\n }\n .timeline__clear:hover:not(:disabled) {\n color: var(--tplane-chat-debug-text);\n background: var(--tplane-chat-debug-surface);\n }\n .timeline__clear:disabled { opacity: 0.4; cursor: default; }\n .timeline__list {\n flex: 1;\n overflow-y: auto;\n padding: 12px 16px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n background: var(--tplane-chat-debug-bg);\n }\n .timeline__empty {\n padding: 24px 16px;\n text-align: center;\n color: var(--tplane-chat-debug-text-subtle);\n font-size: 13px;\n }\n .timeline__row { display: flex; flex-direction: column; gap: 8px; }\n .timeline__row-actions {\n display: none;\n gap: 8px;\n padding-left: 12px;\n }\n .timeline__row:hover .timeline__row-actions { display: flex; }\n .timeline__row button.row-action {\n background: var(--tplane-chat-debug-bg-deep);\n border: 1px solid var(--tplane-chat-debug-border);\n border-radius: 6px;\n padding: 3px 8px;\n font: inherit;\n font-size: 11px;\n color: var(--tplane-chat-debug-text-muted);\n cursor: pointer;\n transition: color 120ms ease, border-color 120ms ease;\n }\n .timeline__row button.row-action:hover {\n color: var(--tplane-chat-debug-text);\n border-color: var(--tplane-chat-debug-border-strong);\n }\n .timeline__diff {\n padding: 12px;\n background: var(--tplane-chat-debug-bg-deep);\n border: 1px solid var(--tplane-chat-debug-border);\n border-radius: var(--tplane-chat-debug-radius-input);\n color: var(--tplane-chat-debug-text);\n }\n `,\n ],\n template: `\n
\n \n {{ checkpoints().length }}\n checkpoint{{ checkpoints().length === 1 ? '' : 's' }}\n \n Clear selection\n
\n \n @if (checkpoints().length === 0) {\n
No checkpoints yet. Send a message to populate the timeline.
\n }\n @for (cp of checkpoints(); let i = $index; track cp.checkpointId ?? i) {\n
\n \n @if (i === selectedIndex() && cp.checkpointId) {\n
\n \n \n
\n }\n @if (i === selectedIndex()) {\n
\n \n
\n }\n
\n }\n \n `,\n})\nexport class TimelineInspectorComponent {\n readonly agent = input.required();\n readonly replayRequested = output();\n readonly forkRequested = output();\n readonly selectedIndex = signal(-1);\n readonly checkpoints = computed((): DebugCheckpoint[] => this.agent().history().map((cp, i) => toDebugCheckpoint(cp, i)));\n currentStateAt(i: number): Record {\n return extractStateValues(this.agent().history()[i]);\n }\n previousStateAt(i: number): Record {\n if (i <= 0)\n return {};\n return extractStateValues(this.agent().history()[i - 1]);\n }\n @HostListener('keydown', ['$event'])\n protected onKey(ev: KeyboardEvent): void {\n const map: Record = {\n ArrowDown: 'down',\n ArrowUp: 'up',\n Home: 'home',\n End: 'end',\n };\n const dir = map[ev.key];\n if (!dir)\n return;\n ev.preventDefault();\n this.selectedIndex.set(stepSelection(dir, this.selectedIndex(), this.checkpoints().length));\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/a2ui-default-fallback.component.ts#A2uiDefaultFallbackComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/a2ui-default-fallback.component.ts", + "symbol": "A2uiDefaultFallbackComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-default-fallback',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host { display: block; width: 100%; }\n .a2ui-default-fallback {\n border: 1px solid var(--tplane-chat-separator);\n border-radius: 10px;\n padding: 14px;\n background: var(--tplane-chat-surface-alt);\n }\n .a2ui-default-fallback__label {\n font-size: 12px;\n color: var(--tplane-chat-text-muted);\n margin-bottom: 10px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .a2ui-default-fallback__rows {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .a2ui-default-fallback__row {\n height: 10px;\n border-radius: 5px;\n background: linear-gradient(\n 90deg,\n var(--tplane-chat-separator) 0%,\n color-mix(in srgb, var(--tplane-chat-separator) 70%, transparent) 50%,\n var(--tplane-chat-separator) 100%\n );\n background-size: 200% 100%;\n animation: a2ui-default-fallback-shimmer 1.4s ease-in-out infinite;\n }\n .a2ui-default-fallback__row:nth-child(1) { width: 70%; }\n .a2ui-default-fallback__row:nth-child(2) { width: 90%; }\n .a2ui-default-fallback__row:nth-child(3) { width: 50%; }\n @keyframes a2ui-default-fallback-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n `],\n template: `\n
\n
\n \n Building UI…\n
\n
\n
\n
\n
\n
\n
\n `,\n})\nexport class A2uiDefaultFallbackComponent {\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/audio-player.component.ts#A2uiAudioPlayerComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/audio-player.component.ts", + "symbol": "A2uiAudioPlayerComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-audio-player',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `\n
\n @if (description()) {\n {{ description() }}\n }\n \n
\n `,\n styles: [`\n .a2ui-audio-wrap {\n display: flex;\n flex-direction: column;\n gap: var(--a2ui-spacing-1);\n }\n .a2ui-audio-description {\n font-size: var(--a2ui-typography-caption-size);\n color: var(--a2ui-on-surface-variant);\n }\n .a2ui-audio {\n display: block;\n width: 100%;\n }\n `],\n})\nexport class A2uiAudioPlayerComponent {\n readonly url = input('');\n readonly description = input('');\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/button.component.ts#A2uiButtonComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/button.component.ts", + "symbol": "A2uiButtonComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-button',\n standalone: true,\n imports: [RenderElementComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n \n @for (key of childKeys(); track key) {\n \n }\n \n `,\n styles: [`\n .a2ui-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: var(--a2ui-spacing-2) var(--a2ui-spacing-4);\n border-radius: var(--a2ui-shape-small);\n font-size: var(--a2ui-typography-body-size);\n font-weight: 500;\n cursor: pointer;\n transition: background var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard),\n opacity var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n border: none;\n }\n .a2ui-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n .a2ui-btn--primary {\n background: var(--a2ui-primary);\n color: var(--a2ui-on-primary);\n }\n .a2ui-btn--primary:hover:not(:disabled) { background: var(--a2ui-primary-hover); }\n .a2ui-btn--default {\n background: var(--a2ui-surface-variant);\n color: var(--a2ui-on-surface);\n border: 1px solid var(--a2ui-outline);\n }\n .a2ui-btn--default:hover:not(:disabled) { background: var(--a2ui-outline); }\n .a2ui-btn--borderless {\n background: transparent;\n color: var(--a2ui-on-surface);\n border: none;\n }\n .a2ui-btn--borderless:hover:not(:disabled) { background: var(--a2ui-surface-variant); }\n `],\n})\nexport class A2uiButtonComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly variant = input('default');\n readonly disabled = input(false);\n readonly emit = input<(event: string) => void>(() => { });\n readonly bindings = input>({});\n readonly loading = input(false);\n protected cssClass(): string {\n return VARIANT_CLASS[this.variant()] ?? VARIANT_CLASS['default'];\n }\n handleClick(): void {\n this.emit()('click');\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/card.component.ts#A2uiCardComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/card.component.ts", + "symbol": "A2uiCardComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-card',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n
\n @for (key of childKeys(); track key) {\n \n }\n
\n `,\n styles: [`\n .a2ui-card {\n display: flex;\n flex-direction: column;\n gap: var(--a2ui-spacing-2);\n border-radius: var(--a2ui-shape-medium);\n border: 1px solid var(--a2ui-outline);\n background: var(--a2ui-surface);\n padding: var(--a2ui-spacing-4);\n box-shadow: var(--a2ui-elevation-1);\n }\n `],\n})\nexport class A2uiCardComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/check-box.component.ts#A2uiCheckBoxComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/check-box.component.ts", + "symbol": "A2uiCheckBoxComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-check-box',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n \n @if (errorText()) {\n
{{ errorText() }}
\n }\n `,\n styles: [`\n .a2ui-cb {\n display: flex;\n align-items: center;\n gap: var(--a2ui-spacing-2);\n font-size: var(--a2ui-typography-body-size);\n cursor: pointer;\n }\n .a2ui-cb__input {\n width: 16px;\n height: 16px;\n border-radius: var(--a2ui-shape-extra-small);\n cursor: pointer;\n accent-color: var(--a2ui-primary);\n }\n .a2ui-check-error {\n font-size: var(--a2ui-typography-label-size);\n color: var(--a2ui-error, #d33d55);\n }\n`],\n})\nexport class A2uiCheckBoxComponent {\n private readonly host = injectRenderHost();\n readonly label = input('');\n readonly value = input(false);\n readonly errorText = input('');\n readonly _bindings = input>({});\n readonly bindings = input>({});\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n onChange(event: Event): void {\n const val = (event.target as HTMLInputElement).checked;\n emitBinding(this.host, this._bindings(), 'value', val);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/choice-picker.component.ts#A2uiChoicePickerComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/choice-picker.component.ts", + "symbol": "A2uiChoicePickerComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-choice-picker',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
\n @if (label()) {\n {{ label() }}\n }\n\n @if (filterable()) {\n \n }\n\n @if (displayStyle() === 'chips') {\n \n
\n @for (opt of visibleOptions(); track opt.value) {\n {{ opt.label }}\n }\n
\n } @else {\n \n
\n @for (opt of visibleOptions(); track opt.value) {\n \n }\n
\n }\n @if (errorText()) {\n
{{ errorText() }}
\n }\n
\n `,\n styles: [`\n .a2ui-cp { display: flex; flex-direction: column; gap: var(--a2ui-spacing-1); }\n .a2ui-cp__label {\n font-size: var(--a2ui-typography-label-size);\n font-weight: var(--a2ui-typography-label-weight);\n color: var(--a2ui-label);\n }\n .a2ui-cp__filter {\n padding: var(--a2ui-spacing-1) var(--a2ui-spacing-2);\n font-size: var(--a2ui-typography-caption-size);\n border-radius: var(--a2ui-shape-small);\n background: var(--a2ui-input-bg);\n color: var(--a2ui-on-surface);\n border: 1px solid var(--a2ui-outline);\n outline: none;\n transition: border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n }\n .a2ui-cp__filter:focus {\n outline: var(--a2ui-focus-ring-width) solid var(--a2ui-focus-ring-color);\n outline-offset: 2px;\n border-color: var(--a2ui-primary);\n }\n .a2ui-cp__checks { display: flex; flex-direction: column; gap: var(--a2ui-spacing-2); }\n .a2ui-cp__check-row {\n display: flex;\n align-items: center;\n gap: var(--a2ui-spacing-2);\n font-size: var(--a2ui-typography-body-size);\n cursor: pointer;\n }\n .a2ui-cp__checkbox {\n width: 16px;\n height: 16px;\n border-radius: var(--a2ui-shape-extra-small);\n cursor: pointer;\n accent-color: var(--a2ui-primary);\n }\n .a2ui-cp__chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--a2ui-spacing-2);\n }\n .a2ui-cp__chip {\n padding: var(--a2ui-spacing-1) var(--a2ui-spacing-3);\n font-size: var(--a2ui-typography-body-size);\n border-radius: var(--a2ui-shape-large, 9999px);\n background: var(--a2ui-surface-variant);\n color: var(--a2ui-on-surface);\n border: 1px solid var(--a2ui-outline);\n cursor: pointer;\n transition: background var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard),\n border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n }\n .a2ui-cp__chip--selected {\n background: var(--a2ui-primary);\n color: var(--a2ui-on-primary);\n border-color: var(--a2ui-primary);\n }\n .a2ui-check-error {\n font-size: var(--a2ui-typography-label-size);\n color: var(--a2ui-error, #d33d55);\n }\n`],\n})\nexport class A2uiChoicePickerComponent {\n private static _idCounter = 0;\n protected readonly _groupName = `a2ui-choice-picker-${++A2uiChoicePickerComponent._idCounter}`;\n private readonly host = injectRenderHost();\n readonly label = input('');\n readonly value = input(undefined);\n readonly options = input([]);\n readonly variant = input<'mutuallyExclusive' | 'multipleSelection'>('mutuallyExclusive');\n readonly displayStyle = input<'checkbox' | 'chips'>('checkbox');\n readonly filterable = input(false);\n readonly errorText = input('');\n readonly _bindings = input>({});\n readonly bindings = input>({});\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected readonly valueArray = computed(() => {\n const v = this.value();\n if (Array.isArray(v))\n return v;\n if (v == null || v === '')\n return [];\n return [String(v)];\n });\n protected readonly isSingleSelect = computed(() => this.variant() !== 'multipleSelection');\n protected readonly filterText = signal('');\n protected readonly visibleOptions = computed(() => {\n const f = this.filterText().trim().toLowerCase();\n const opts = this.options();\n return f ? opts.filter(o => o.label.toLowerCase().includes(f)) : opts;\n });\n protected isSelected(value: string): boolean {\n return this.valueArray().includes(value);\n }\n onFilterInput(event: Event): void {\n this.filterText.set((event.target as HTMLInputElement).value);\n }\n onCheckChange(value: string, event: Event): void {\n const checked = (event.target as HTMLInputElement).checked;\n if (this.isSingleSelect()) {\n if (checked)\n emitBinding(this.host, this._bindings(), 'value', [value]);\n return;\n }\n emitBinding(this.host, this._bindings(), 'value', this.toggled(value, checked));\n }\n onChipToggle(value: string): void {\n if (this.isSingleSelect()) {\n emitBinding(this.host, this._bindings(), 'value', [value]);\n return;\n }\n const checked = !this.isSelected(value);\n emitBinding(this.host, this._bindings(), 'value', this.toggled(value, checked));\n }\n private toggled(value: string, checked: boolean): string[] {\n const current = [...this.valueArray()];\n const idx = current.indexOf(value);\n if (checked && idx === -1) {\n current.push(value);\n }\n else if (!checked && idx !== -1) {\n current.splice(idx, 1);\n }\n return current;\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/column.component.ts#A2uiColumnComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/column.component.ts", + "symbol": "A2uiColumnComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-column',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n \n @for (key of childKeys(); track key) {\n \n }\n \n `,\n styles: [`\n .a2ui-col {\n display: flex;\n flex-direction: column;\n gap: var(--a2ui-spacing-3);\n }\n .a2ui-col--justify-stretch > render-element {\n flex: 1;\n }\n `],\n})\nexport class A2uiColumnComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly align = input('stretch');\n readonly justify = input('start');\n readonly gap = input(undefined);\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n protected readonly alignItems = computed(() => ALIGN_MAP[this.align()] ?? 'stretch');\n protected readonly justifyContent = computed(() => JUSTIFY_MAP[this.justify()] ?? 'flex-start');\n protected readonly cssClass = computed(() => this.justify() === 'stretch' ? 'a2ui-col a2ui-col--justify-stretch' : 'a2ui-col');\n protected readonly gapPx = computed(() => {\n const g = this.gap();\n if (typeof g === 'number' && Number.isFinite(g))\n return g * 4;\n if (g === 'small')\n return 8;\n if (g === 'medium')\n return 12;\n if (g === 'large')\n return 16;\n return null;\n });\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/date-time-input.component.ts#A2uiDateTimeInputComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/date-time-input.component.ts", + "symbol": "A2uiDateTimeInputComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-date-time-input',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
\n @if (label()) {\n \n }\n \n @if (errorText()) {\n
{{ errorText() }}
\n }\n
\n `,\n styles: [`\n .a2ui-dti { display: flex; flex-direction: column; gap: var(--a2ui-spacing-1); }\n .a2ui-dti__label {\n font-size: var(--a2ui-typography-label-size);\n font-weight: var(--a2ui-typography-label-weight);\n color: var(--a2ui-label);\n }\n .a2ui-dti__input {\n padding: var(--a2ui-spacing-2) var(--a2ui-spacing-3);\n font-size: var(--a2ui-typography-body-size);\n border-radius: var(--a2ui-shape-small);\n background: var(--a2ui-input-bg);\n color: var(--a2ui-on-surface);\n border: 1px solid var(--a2ui-outline);\n outline: none;\n transition: border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n }\n .a2ui-dti__input:focus {\n outline: var(--a2ui-focus-ring-width) solid var(--a2ui-focus-ring-color);\n outline-offset: 2px;\n border-color: var(--a2ui-primary);\n }\n .a2ui-check-error {\n font-size: var(--a2ui-typography-label-size);\n color: var(--a2ui-error, #d33d55);\n }\n`],\n})\nexport class A2uiDateTimeInputComponent {\n private static _idCounter = 0;\n protected readonly _inputId = `a2ui-date-time-input-${++A2uiDateTimeInputComponent._idCounter}`;\n private readonly host = injectRenderHost();\n readonly label = input('');\n readonly value = input('');\n readonly enableDate = input(true);\n readonly enableTime = input(false);\n readonly min = input(undefined);\n readonly max = input(undefined);\n readonly errorText = input('');\n readonly _bindings = input>({});\n readonly bindings = input>({});\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected readonly htmlInputType = computed(() => {\n const d = this.enableDate();\n const t = this.enableTime();\n if (d && t)\n return 'datetime-local';\n if (t)\n return 'time';\n return 'date';\n });\n onChange(event: Event): void {\n const val = (event.target as HTMLInputElement).value;\n emitBinding(this.host, this._bindings(), 'value', val);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/divider.component.ts#A2uiDividerComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/divider.component.ts", + "symbol": "A2uiDividerComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-divider',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `\n @if (orientation() === 'vertical') {\n
\n } @else {\n
\n }\n `,\n styles: [`\n .a2ui-divider--horizontal {\n display: block;\n width: 100%;\n border: none;\n border-top: 1px solid var(--a2ui-outline);\n margin: var(--a2ui-spacing-2) 0;\n }\n .a2ui-divider--vertical {\n display: inline-block;\n align-self: stretch;\n width: 1px;\n background: var(--a2ui-outline);\n margin: 0 var(--a2ui-spacing-2);\n }\n `],\n})\nexport class A2uiDividerComponent {\n readonly axis = input<'horizontal' | 'vertical'>('horizontal');\n protected readonly orientation = computed<'horizontal' | 'vertical'>(() => this.axis());\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/icon.component.ts#A2uiIconComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/icon.component.ts", + "symbol": "A2uiIconComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-icon',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `\n @if (svgPath(); as path) {\n \n } @else if (ligatureName(); as name) {\n {{ glyphName() }}\n }\n `,\n styles: [`\n /* Renders Material Symbols by ligature name (A2UI's canonical icon set).\n Relies only on the Material Symbols Outlined @font-face being present —\n host apps load the stylesheet (see README). Unknown / not-yet-loaded\n names fall back to the browser default glyph. */\n .a2ui-icon {\n font-family: 'Material Symbols Outlined';\n font-weight: normal;\n font-style: normal;\n font-size: 1.125rem;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n white-space: nowrap;\n word-wrap: normal;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n color: currentColor;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n user-select: none;\n }\n .a2ui-icon--svg {\n width: 1.125rem;\n height: 1.125rem;\n }\n `],\n})\nexport class A2uiIconComponent {\n readonly name = input(undefined);\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected readonly svgPath = computed(() => {\n const n = this.name();\n return typeof n === 'object' && n !== null && typeof n.svgPath === 'string'\n ? n.svgPath\n : null;\n });\n protected readonly ligatureName = computed(() => typeof this.name() === 'string' ? (this.name() as string) : '');\n protected readonly glyphName = computed(() => toMaterialSymbolName(this.ligatureName()));\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/image.component.ts#A2uiImageComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/image.component.ts", + "symbol": "A2uiImageComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-image',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `\n \n `,\n styles: [`\n .a2ui-img {\n display: block;\n max-width: 100%;\n border-radius: var(--a2ui-shape-extra-small);\n }\n .a2ui-img--icon {\n width: 24px;\n height: 24px;\n }\n .a2ui-img--avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n }\n .a2ui-img--smallFeature {\n width: 120px;\n }\n .a2ui-img--mediumFeature {\n width: 240px;\n }\n .a2ui-img--largeFeature {\n width: 400px;\n }\n .a2ui-img--header {\n width: 100%;\n aspect-ratio: 16 / 5;\n }\n `],\n})\nexport class A2uiImageComponent {\n readonly url = input('');\n readonly description = input('');\n readonly fit = input('fill');\n readonly variant = input('mediumFeature');\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected readonly objectFit = computed(() => FIT_MAP[this.fit()] ?? 'fill');\n protected readonly cssClass = computed(() => `a2ui-img a2ui-img--${this.variant()}`);\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/list.component.ts#A2uiListComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/list.component.ts", + "symbol": "A2uiListComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-list',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n
\n @for (key of childKeys(); track key) {\n \n }\n
\n `,\n styles: [`\n .a2ui-list--vertical {\n display: flex;\n flex-direction: column;\n gap: var(--a2ui-spacing-1);\n overflow-y: auto;\n max-height: 384px;\n }\n .a2ui-list--horizontal {\n display: flex;\n flex-direction: row;\n gap: var(--a2ui-spacing-1);\n overflow-x: auto;\n }\n `],\n})\nexport class A2uiListComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly direction = input<'vertical' | 'horizontal'>('vertical');\n readonly align = input<'start' | 'center' | 'end' | 'stretch'>('stretch');\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n protected readonly listClass = computed(() => {\n return this.direction() === 'horizontal'\n ? 'a2ui-list--horizontal'\n : 'a2ui-list--vertical';\n });\n protected readonly alignmentCss = computed(() => {\n const a = this.align();\n return a === 'start' ? 'flex-start'\n : a === 'end' ? 'flex-end'\n : a;\n });\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/modal.component.ts#A2uiModalComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/modal.component.ts", + "symbol": "A2uiModalComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-modal',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n \n @if (entryPointKey(); as epKey) {\n \n \n \n }\n\n \n @if (open()) {\n \n \n
\n @if (contentKey(); as cKey) {\n \n }\n
\n \n }\n `,\n styles: [`\n .a2ui-modal__trigger {\n display: contents;\n }\n .a2ui-modal__overlay {\n position: fixed;\n inset: 0;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .a2ui-modal__backdrop {\n position: absolute;\n inset: 0;\n background: var(--a2ui-scrim);\n backdrop-filter: blur(4px);\n }\n .a2ui-modal__panel {\n position: relative;\n background: var(--a2ui-surface);\n border: 1px solid var(--a2ui-outline);\n border-radius: var(--a2ui-shape-medium);\n padding: var(--a2ui-spacing-5);\n max-width: 512px;\n width: 100%;\n margin: 0 var(--a2ui-spacing-4);\n box-shadow: var(--a2ui-elevation-4);\n }\n `],\n})\nexport class A2uiModalComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n protected readonly open = signal(false);\n protected readonly entryPointKey = computed(() => this.childKeys()[0] ?? null);\n protected readonly contentKey = computed(() => this.childKeys()[1] ?? null);\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/row.component.ts#A2uiRowComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/row.component.ts", + "symbol": "A2uiRowComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-row',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n \n @for (key of childKeys(); track key) {\n \n }\n \n `,\n styles: [`\n .a2ui-row {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: var(--a2ui-spacing-3);\n }\n .a2ui-row--justify-stretch > render-element {\n flex: 1;\n }\n `],\n})\nexport class A2uiRowComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly align = input('stretch');\n readonly justify = input('start');\n readonly gap = input(undefined);\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n protected readonly alignItems = computed(() => ALIGN_MAP[this.align()] ?? 'stretch');\n protected readonly justifyContent = computed(() => JUSTIFY_MAP[this.justify()] ?? 'flex-start');\n protected readonly cssClass = computed(() => this.justify() === 'stretch' ? 'a2ui-row a2ui-row--justify-stretch' : 'a2ui-row');\n protected readonly gapPx = computed(() => {\n const g = this.gap();\n if (typeof g === 'number' && Number.isFinite(g))\n return g * 4;\n if (g === 'small')\n return 8;\n if (g === 'medium')\n return 12;\n if (g === 'large')\n return 16;\n return null;\n });\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/slider.component.ts#A2uiSliderComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/slider.component.ts", + "symbol": "A2uiSliderComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-slider',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
\n @if (label()) {\n \n }\n \n @if (errorText()) {\n
{{ errorText() }}
\n }\n
\n `,\n styles: [`\n .a2ui-slider { display: flex; flex-direction: column; gap: var(--a2ui-spacing-1); }\n .a2ui-slider__label {\n font-size: var(--a2ui-typography-label-size);\n font-weight: var(--a2ui-typography-label-weight);\n color: var(--a2ui-label);\n }\n .a2ui-slider__input {\n width: 100%;\n cursor: pointer;\n accent-color: var(--a2ui-primary);\n }\n .a2ui-check-error {\n font-size: var(--a2ui-typography-label-size);\n color: var(--a2ui-error, #d33d55);\n }\n`],\n})\nexport class A2uiSliderComponent {\n private static _idCounter = 0;\n protected readonly _inputId = `a2ui-slider-${++A2uiSliderComponent._idCounter}`;\n private readonly host = injectRenderHost();\n readonly label = input('');\n readonly value = input(0);\n readonly min = input(0);\n readonly max = input(100);\n readonly errorText = input('');\n readonly _bindings = input>({});\n readonly bindings = input>({});\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n onInput(event: Event): void {\n const val = Number((event.target as HTMLInputElement).value);\n emitBinding(this.host, this._bindings(), 'value', val);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/tabs.component.ts#A2uiTabsComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/tabs.component.ts", + "symbol": "A2uiTabsComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-tabs',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n
\n
\n @for (title of tabTitles(); track $index) {\n {{ title }}\n }\n
\n
\n @if (activeChildKey(); as key) {\n \n }\n
\n
\n `,\n styles: [`\n .a2ui-tabs { display: flex; flex-direction: column; }\n .a2ui-tabs__tablist {\n display: flex;\n border-bottom: 1px solid var(--a2ui-outline);\n }\n .a2ui-tabs__tab {\n padding: var(--a2ui-spacing-2) var(--a2ui-spacing-4);\n font-size: var(--a2ui-typography-body-size);\n font-weight: 500;\n cursor: pointer;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n color: var(--a2ui-label);\n transition: color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard),\n border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n margin-bottom: -1px;\n }\n .a2ui-tabs__tab:hover { color: var(--a2ui-on-surface); }\n .a2ui-tabs__tab--active {\n border-bottom-color: var(--a2ui-primary);\n color: var(--a2ui-on-surface);\n }\n .a2ui-tabs__panel { padding-top: var(--a2ui-spacing-3); }\n `],\n})\nexport class A2uiTabsComponent {\n readonly tabTitles = input([]);\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n protected readonly activeIndex = signal(0);\n constructor() {\n effect(() => {\n const len = this.childKeys().length;\n if (this.activeIndex() >= len && len > 0)\n this.activeIndex.set(0);\n });\n }\n protected readonly activeChildKey = computed(() => {\n const idx = this.activeIndex();\n const keys = this.childKeys();\n return idx >= 0 && idx < keys.length ? keys[idx] : null;\n });\n selectTab(index: number): void {\n this.activeIndex.set(index);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/text-field.component.ts#A2uiTextFieldComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/text-field.component.ts", + "symbol": "A2uiTextFieldComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-text-field',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
\n @if (label()) {\n \n }\n @if (variant() === 'longText') {\n \n } @else {\n \n }\n @if (errorText()) {\n
{{ errorText() }}
\n }\n
\n `,\n styles: [`\n .a2ui-tf { display: flex; flex-direction: column; gap: var(--a2ui-spacing-1); }\n .a2ui-tf__label {\n font-size: var(--a2ui-typography-label-size);\n font-weight: var(--a2ui-typography-label-weight);\n color: var(--a2ui-label);\n }\n .a2ui-tf__input {\n padding: var(--a2ui-spacing-2) var(--a2ui-spacing-3);\n font-size: var(--a2ui-typography-body-size);\n border-radius: var(--a2ui-shape-small);\n background: var(--a2ui-input-bg);\n color: var(--a2ui-on-surface);\n border: 1px solid var(--a2ui-outline);\n outline: none;\n transition: border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n resize: vertical;\n }\n .a2ui-tf__input:focus {\n outline: var(--a2ui-focus-ring-width) solid var(--a2ui-focus-ring-color);\n outline-offset: 2px;\n border-color: var(--a2ui-primary);\n }\n .a2ui-check-error {\n font-size: var(--a2ui-typography-label-size);\n color: var(--a2ui-error, #d33d55);\n }\n`],\n})\nexport class A2uiTextFieldComponent {\n private static _idCounter = 0;\n protected readonly _inputId = `a2ui-text-field-${++A2uiTextFieldComponent._idCounter}`;\n private readonly host = injectRenderHost();\n readonly label = input('');\n readonly value = input('');\n readonly placeholder = input('');\n readonly variant = input('shortText');\n readonly validationRegexp = input('');\n readonly errorText = input('');\n readonly _bindings = input>({});\n readonly bindings = input>({});\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected readonly htmlInputType = computed(() => TYPE_MAP[this.variant()] ?? 'text');\n onInput(event: Event): void {\n const val = (event.target as HTMLInputElement | HTMLTextAreaElement).value;\n emitBinding(this.host, this._bindings(), 'value', val);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/text.component.ts#A2uiTextComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/text.component.ts", + "symbol": "A2uiTextComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-text',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `{{ text() }}`,\n styles: [`\n .a2ui-text-h1 {\n display: block;\n font-size: var(--a2ui-typography-h1-size);\n font-weight: var(--a2ui-typography-h1-weight);\n line-height: var(--a2ui-typography-h1-line-height);\n margin: 0;\n }\n .a2ui-text-h2 {\n display: block;\n font-size: var(--a2ui-typography-h2-size);\n font-weight: var(--a2ui-typography-h2-weight);\n line-height: var(--a2ui-typography-h2-line-height);\n margin: 0;\n }\n .a2ui-text-h3 {\n display: block;\n font-size: var(--a2ui-typography-h3-size);\n font-weight: var(--a2ui-typography-h3-weight);\n line-height: var(--a2ui-typography-h3-line-height);\n margin: 0;\n }\n .a2ui-text-h4 {\n display: block;\n font-size: var(--a2ui-typography-h4-size);\n font-weight: var(--a2ui-typography-h4-weight);\n line-height: var(--a2ui-typography-h4-line-height);\n margin: 0;\n }\n .a2ui-text-h5 {\n display: block;\n font-size: var(--a2ui-typography-h5-size);\n font-weight: var(--a2ui-typography-h5-weight);\n line-height: var(--a2ui-typography-h5-line-height);\n margin: 0;\n }\n .a2ui-text-caption {\n display: block;\n font-size: var(--a2ui-typography-caption-size);\n font-weight: var(--a2ui-typography-caption-weight);\n color: var(--a2ui-caption);\n line-height: var(--a2ui-typography-caption-line-height);\n }\n .a2ui-text-body {\n display: block;\n font-size: var(--a2ui-typography-body-size);\n font-weight: var(--a2ui-typography-body-weight);\n line-height: var(--a2ui-typography-body-line-height);\n }\n `],\n})\nexport class A2uiTextComponent {\n readonly text = input('');\n readonly variant = input('body');\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected cssClass(): string {\n return `a2ui-text-${this.variant()}`;\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/video.component.ts#A2uiVideoComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/catalog/video.component.ts", + "symbol": "A2uiVideoComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-video',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `\n \n `,\n styles: [`\n .a2ui-video {\n display: block;\n width: 100%;\n border-radius: var(--a2ui-shape-small);\n }\n `],\n})\nexport class A2uiVideoComponent {\n readonly url = input('');\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n}" + }, + { + "id": "component:libs/chat/src/lib/a2ui/surface.component.ts#A2uiSurfaceComponent", + "kind": "component", + "path": "libs/chat/src/lib/a2ui/surface.component.ts", + "symbol": "A2uiSurfaceComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'a2ui-surface',\n standalone: true,\n imports: [\n RenderSpecComponent,\n A2uiDefaultFallbackComponent,\n NgComponentOutlet,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[style.--a2ui-primary]': 'primaryColor()',\n },\n styles: `\n .a2ui-surface-chrome {\n display: flex;\n align-items: center;\n gap: var(--a2ui-spacing-2);\n margin-bottom: var(--a2ui-spacing-2);\n color: var(--a2ui-label);\n font-size: var(--a2ui-typography-label-size);\n }\n .a2ui-surface-chrome img {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n object-fit: cover;\n }\n `,\n template: `\n @if (agentDisplayName() || iconUrl()) {\n
\n @if (iconUrl(); as icon) {\n \"\"\n }\n @if (agentDisplayName(); as name) {\n {{ name }}\n }\n
\n }\n @if (spec(); as s) {\n \n } @else if (state(); as st) {\n @if (surfaceFallback(); as fb) {\n \n } @else {\n \n }\n }\n `,\n})\nexport class A2uiSurfaceComponent {\n readonly surface = input();\n readonly state = input();\n readonly catalog = input.required();\n readonly handlers = input) => unknown | Promise>>({});\n readonly surfaceFallback = input | undefined>(undefined);\n readonly events = output();\n readonly action = output();\n readonly validationError = output();\n readonly liveStore = signalStateStore({});\n private readonly seeded = new Map();\n constructor() {\n effect(() => {\n const s = this.spec();\n const state = s?.state as Record | undefined;\n if (!state)\n return;\n untracked(() => {\n for (const [key, value] of Object.entries(state)) {\n const path = key.startsWith('/') ? key : `/${key}`;\n const current = this.liveStore.get(path);\n const untouched = current === undefined ||\n (this.seeded.has(path) && current === this.seeded.get(path));\n if (untouched) {\n if (current !== value)\n this.liveStore.set(path, value);\n this.seeded.set(path, value);\n }\n }\n });\n });\n }\n readonly primaryColor = computed(() => (this.state()?.surface ?? this.surface())?.theme?.primaryColor ?? null);\n protected readonly agentDisplayName = computed(() => (this.state()?.surface ?? this.surface())?.theme?.agentDisplayName ?? null);\n protected readonly iconUrl = computed(() => (this.state()?.surface ?? this.surface())?.theme?.iconUrl ?? null);\n readonly rootIds = computed(() => {\n const st = this.state();\n if (!st)\n return [];\n return [...st.componentViews.keys()].slice(0, 1);\n });\n readonly spec = computed(() => {\n const surf = this.state()?.surface ?? this.surface();\n return surf && surf.components.size > 0 ? surfaceToSpec(surf) : null;\n });\n readonly registry = computed(() => toRenderRegistry(this.catalog() as ViewRegistry));\n readonly internalHandlers = computed(() => {\n const consumerHandlers = this.handlers();\n return {\n 'a2ui:event': (params: Record) => {\n const surf = this.state()?.surface ?? this.surface();\n if (!surf)\n return undefined;\n const liveModel = this.mergedLiveModel(surf);\n const failures = evaluateSurfaceChecks(surf, liveModel);\n if (failures.length > 0) {\n for (const f of failures) {\n this.liveStore.set(`/_a2uiChecks/${f.componentId}`, f.message);\n }\n const first = failures[0];\n this.validationError.emit({\n version: A2UI_WIRE_VERSION,\n error: {\n code: 'VALIDATION_FAILED',\n surfaceId: surf.surfaceId,\n ...(first.path ? { path: first.path } : {}),\n message: first.message,\n },\n });\n return undefined;\n }\n for (const [id, comp] of surf.components) {\n if (componentHasChecks(comp as unknown as Record)) {\n this.liveStore.set(`/_a2uiChecks/${id}`, '');\n }\n }\n const rawContext = (params['context'] as Record) ?? {};\n const context: Record = {};\n for (const [k, v] of Object.entries(rawContext)) {\n if (v != null && typeof v === 'object' && '$bindState' in (v as Record)) {\n const path = String((v as Record)['$bindState']);\n context[k] = getByPointer(liveModel, path);\n }\n else {\n context[k] = v;\n }\n }\n const { _a2uiChecks, ...publicModel } = liveModel;\n void _a2uiChecks;\n const message = buildA2uiActionMessage({ ...params, context }, { ...surf, dataModel: publicModel });\n this.action.emit(message);\n return message;\n },\n 'a2ui:localAction': (params: Record) => {\n const call = params['call'] as string;\n const args = (params['args'] as Record) ?? {};\n if (consumerHandlers[call]) {\n return consumerHandlers[call](args);\n }\n if (call === 'openUrl' && typeof globalThis.window !== 'undefined') {\n globalThis.window.open(String(args['url'] ?? ''), '_blank', 'noopener');\n }\n return undefined;\n },\n };\n });\n onRenderEvent(event: RenderEvent): void {\n this.events.emit(event);\n }\n private mergedLiveModel(surf: A2uiSurface): Record {\n const snapshot = this.liveStore.getSnapshot() as Record;\n return deepOverlay(surf.dataModel, snapshot);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-approval-card/chat-approval-card.component.ts#ChatApprovalCardComponent", + "kind": "component", + "path": "libs/chat/src/lib/compositions/chat-approval-card/chat-approval-card.component.ts", + "symbol": "ChatApprovalCardComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-approval-card',\n standalone: true,\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_HOST_TOKENS,\n `\n :host { display: contents; }\n dialog.chat-approval-card {\n width: 440px;\n max-width: calc(100vw - 32px);\n /* Center in the viewport. The UA stylesheet sets margin:auto on open\n modal dialogs, but our reset properties below shadow it. Re-assert. */\n margin: auto;\n padding: 0;\n border: 0;\n border-radius: 12px;\n background: var(--tplane-chat-surface);\n color: var(--tplane-chat-text);\n box-shadow: 0 20px 50px rgba(0,0,0,0.18);\n }\n dialog.chat-approval-card::backdrop {\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n }\n .chat-approval-card__header {\n padding: 14px 16px 12px;\n display: flex;\n align-items: center;\n gap: 8px;\n border-bottom: 1px solid var(--tplane-chat-separator);\n }\n .chat-approval-card__header h4 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--tplane-chat-text);\n }\n .chat-approval-card__header svg {\n color: var(--tplane-chat-warning-text);\n width: 16px;\n height: 16px;\n flex: 0 0 16px;\n }\n .chat-approval-card__body {\n padding: 14px 16px;\n font-size: var(--tplane-chat-font-size-sm, 13px);\n color: var(--tplane-chat-text);\n }\n .chat-approval-card__actions {\n padding: 8px 16px 14px;\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n align-items: center;\n }\n .btn {\n border: 0;\n padding: 6px 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: transform 200ms ease, opacity 200ms ease;\n }\n .btn:hover { transform: scale(1.03); }\n .btn-primary { background: var(--tplane-chat-primary); color: var(--tplane-chat-on-primary); }\n .btn-secondary { background: transparent; color: var(--tplane-chat-text); border: 1px solid var(--tplane-chat-separator); }\n .btn-text {\n background: transparent;\n color: var(--tplane-chat-text-muted);\n padding: 6px 10px;\n }\n .btn-text:hover { color: var(--tplane-chat-text); }\n `,\n ],\n template: `\n \n
\n \n

{{ title() }}

\n
\n
\n @if (bodyTemplate(); as tpl) {\n @if (payload(); as p) {\n \n }\n }\n
\n
\n \n @if (showEdit()) {\n \n }\n \n
\n
\n `,\n})\nexport class ChatApprovalCardComponent {\n readonly agent = input.required();\n readonly matchKind = input(undefined);\n readonly title = input('Approval required');\n readonly showEdit = input(false);\n readonly action = output();\n protected readonly bodyTemplate = contentChild>('body');\n private readonly dialogRef = viewChild>('dialogEl');\n private readonly interrupt = computed(() => this.agent().interrupt?.());\n protected readonly payload = computed(() => {\n const i = this.interrupt();\n if (!i)\n return undefined;\n const v = i.value as {\n kind?: unknown;\n } | undefined;\n const want = this.matchKind();\n if (want !== undefined) {\n if (!v || typeof v !== 'object' || (v as {\n kind?: unknown;\n }).kind !== want) {\n return undefined;\n }\n }\n return v;\n });\n constructor() {\n effect(() => {\n const p = this.payload();\n const dialog = this.dialogRef()?.nativeElement;\n if (!dialog)\n return;\n if (p && !dialog.open) {\n dialog.showModal();\n }\n else if (!p && dialog.open) {\n dialog.close();\n }\n });\n }\n protected emit(action: ChatApprovalAction): void {\n this.action.emit(action);\n if (action !== 'edit') {\n this.closeDialog();\n }\n }\n protected onCancelEvent(ev: Event): void {\n ev.preventDefault();\n this.action.emit('cancel');\n this.closeDialog();\n }\n private closeDialog(): void {\n const dialog = this.dialogRef()?.nativeElement;\n if (!dialog)\n return;\n if (dialog.open)\n dialog.close();\n }\n protected onDialogClose(): void {\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-interrupt-panel/chat-interrupt-panel.component.ts#ChatInterruptPanelComponent", + "kind": "component", + "path": "libs/chat/src/lib/compositions/chat-interrupt-panel/chat-interrupt-panel.component.ts", + "symbol": "ChatInterruptPanelComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-interrupt-panel',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_HOST_TOKENS,\n `\n .chat-interrupt-panel {\n background: var(--tplane-chat-surface);\n color: var(--tplane-chat-text);\n border: 1px solid var(--tplane-chat-separator);\n border-radius: var(--tplane-chat-radius-card);\n padding: 14px 16px;\n font-size: var(--tplane-chat-font-size-sm);\n }\n .chat-interrupt-panel__eyebrow {\n font-family: ui-monospace, Menlo, Consolas, monospace;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.12em;\n color: var(--tplane-chat-warning-text);\n margin: 0 0 8px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .chat-interrupt-panel__dot {\n width: 6px;\n height: 6px;\n border-radius: 999px;\n background: var(--tplane-chat-warning-text);\n flex: 0 0 6px;\n }\n .chat-interrupt-panel__body {\n margin: 0 0 12px;\n color: var(--tplane-chat-text);\n white-space: pre-wrap;\n }\n .chat-interrupt-panel__actions {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n align-items: center;\n }\n .btn {\n border: 0;\n padding: 6px 14px;\n border-radius: var(--tplane-chat-radius-button);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: transform 200ms ease, opacity 200ms ease;\n }\n .btn:hover { transform: scale(1.03); }\n .btn-primary { background: var(--tplane-chat-primary); color: var(--tplane-chat-on-primary); }\n .btn-secondary { background: transparent; color: var(--tplane-chat-text); border: 1px solid var(--tplane-chat-separator); }\n .btn-text {\n background: transparent;\n color: var(--tplane-chat-text-muted);\n padding: 6px 10px;\n }\n .btn-text:hover { color: var(--tplane-chat-text); }\n `,\n ],\n template: `\n @if (interrupt()) {\n
\n

\n \n Agent paused — review needed\n

\n

{{ interruptReason() }}

\n
\n \n \n \n \n
\n
\n }\n `,\n})\nexport class ChatInterruptPanelComponent {\n readonly agent = input.required();\n readonly action = output();\n readonly interrupt = computed(() => getInterruptFromAgent(this.agent()));\n readonly interruptReason = computed(() => interruptReasonText(this.interrupt()));\n}" + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-popup/chat-popup.component.ts#ChatPopupComponent", + "kind": "component", + "path": "libs/chat/src/lib/compositions/chat-popup/chat-popup.component.ts", + "symbol": "ChatPopupComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-popup',\n standalone: true,\n imports: [ChatComponent, ChatLauncherButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host {\n position: fixed;\n bottom: var(--tplane-chat-launcher-offset-y);\n right: var(--tplane-chat-launcher-offset-x);\n z-index: var(--tplane-chat-z-overlay-content, 30);\n }\n .chat-popup__launcher { position: relative; }\n .chat-popup__window {\n position: fixed;\n bottom: 5rem;\n right: var(--tplane-chat-launcher-offset-x);\n width: 24rem;\n height: 600px;\n max-height: calc(100vh - 6rem);\n background: var(--tplane-chat-bg);\n border: 1px solid var(--tplane-chat-separator);\n border-radius: 0.75rem;\n box-shadow: 0 5px 40px rgba(0,0,0,.16);\n transform-origin: bottom right;\n transform: scale(0.95) translateY(20px);\n opacity: 0;\n pointer-events: none;\n transition: transform 200ms ease-out, opacity 100ms ease-out;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n .chat-popup__window[data-open=\"true\"] {\n transform: scale(1) translateY(0);\n opacity: 1;\n pointer-events: auto;\n }\n @media (max-width: 640px) {\n .chat-popup__window { inset: 0; width: 100vw; height: 100vh; max-height: 100vh; border-radius: 0; bottom: auto; right: auto; }\n }\n .chat-popup__close {\n position: absolute; top: 8px; right: 8px;\n width: 32px; height: 32px;\n background: transparent; border: 0; cursor: pointer;\n color: var(--tplane-chat-text-muted);\n border-radius: 50%;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .chat-popup__close:hover { background: var(--tplane-chat-surface-alt); color: var(--tplane-chat-text); }\n `],\n template: `\n
\n \n
\n
\n \n \n \n \n \n
\n `,\n})\nexport class ChatPopupComponent {\n readonly agent = input.required();\n readonly views = input(undefined);\n readonly clientTools = input(undefined);\n readonly modelOptions = input([]);\n readonly showModelPicker = input(true);\n readonly selectedModel = model('');\n readonly open = model(false);\n readonly shortcut = input('k');\n readonly closeOnEscape = input(true);\n private readonly destroyRef = inject(DestroyRef);\n private readonly document = inject(DOCUMENT);\n constructor() {\n ensureChatRootStyles();\n effect(() => {\n const shortcut = this.shortcut();\n const closeOnEscape = this.closeOnEscape();\n const win = this.document.defaultView;\n if (!win)\n return;\n const isMac = /Mac|iPhone|iPad/i.test(win.navigator.platform || win.navigator.userAgent);\n const handler = (e: KeyboardEvent): void => {\n if (shortcut && e.key.toLowerCase() === shortcut.toLowerCase() && (isMac ? e.metaKey : e.ctrlKey)) {\n e.preventDefault();\n this.toggle();\n return;\n }\n if (closeOnEscape && this.open() && e.key === 'Escape') {\n this.closeWindow();\n }\n };\n win.addEventListener('keydown', handler);\n this.destroyRef.onDestroy(() => win.removeEventListener('keydown', handler));\n });\n }\n toggle(): void { this.open.update((v) => !v); }\n openWindow(): void { this.open.set(true); }\n closeWindow(): void { this.open.set(false); }\n}" + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-sidebar/chat-sidebar.component.ts#ChatSidebarComponent", + "kind": "component", + "path": "libs/chat/src/lib/compositions/chat-sidebar/chat-sidebar.component.ts", + "symbol": "ChatSidebarComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-sidebar',\n standalone: true,\n imports: [ChatComponent, ChatLauncherButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.data-push]': 'pushContent() ? \"true\" : \"false\"',\n '[attr.data-open]': 'open() ? \"true\" : \"false\"',\n },\n styles: [CHAT_HOST_TOKENS, `\n /* Flex row so the projected main content fills the area beside the panel\n and inherits the host's height (no hardcoded 100vh). Consumers thread\n height: 100% from their layout down to ; the content slot\n then fills it via flex. */\n :host { display: flex; height: 100%; min-height: 0; }\n .chat-sidebar__content {\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n transition: margin-right 300ms ease;\n }\n :host([data-push=\"true\"][data-open=\"true\"]) .chat-sidebar__content {\n margin-right: var(--tplane-chat-sidebar-width-drawer, 28rem);\n }\n @media (max-width: 640px) {\n :host([data-push=\"true\"][data-open=\"true\"]) .chat-sidebar__content { margin-right: 0; }\n }\n .chat-sidebar__panel {\n position: fixed;\n top: 0; right: 0;\n bottom: var(--tplane-chat-debug-claim-bottom, 0);\n width: var(--tplane-chat-sidebar-width-drawer, 28rem);\n background: var(--tplane-chat-bg);\n border-left: 1px solid var(--tplane-chat-separator);\n box-shadow: -8px 0 32px rgba(0,0,0,.08);\n transform: translateX(100%);\n transition: transform 200ms ease-out, bottom 200ms ease-out;\n z-index: var(--tplane-chat-z-overlay-content, 30);\n display: flex;\n flex-direction: column;\n }\n .chat-sidebar__panel[data-open=\"true\"] { transform: translateX(0); }\n @media (max-width: 640px) {\n .chat-sidebar__panel { width: 100vw; }\n }\n .chat-sidebar__panel-header {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--tplane-chat-separator);\n min-height: 48px;\n }\n .chat-sidebar__panel-title {\n min-width: 0;\n flex: 1 1 auto;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n color: var(--tplane-chat-text);\n font-weight: 500;\n font-size: var(--tplane-chat-font-size-sm);\n }\n .chat-sidebar__close {\n flex: 0 0 auto;\n width: 32px; height: 32px;\n background: transparent; border: 0; cursor: pointer;\n color: var(--tplane-chat-text-muted);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .chat-sidebar__close:hover { background: var(--tplane-chat-surface-alt); color: var(--tplane-chat-text); }\n .chat-sidebar__launcher {\n position: fixed;\n bottom: calc(1rem + var(--tplane-chat-debug-claim-bottom, 0));\n right: 1rem;\n z-index: var(--tplane-chat-z-overlay-content, 30);\n transition: bottom 200ms ease-out;\n }\n /* Hide the launcher when the sidebar is open — the close button on the\n panel handles dismissal, and the panel covers the launcher anyway. */\n :host([data-open=\"true\"]) .chat-sidebar__launcher { display: none; }\n `],\n template: `\n
\n
\n \n
\n \n `,\n})\nexport class ChatSidebarComponent {\n readonly agent = input.required();\n readonly views = input(undefined);\n readonly clientTools = input(undefined);\n readonly modelOptions = input([]);\n readonly showModelPicker = input(true);\n readonly selectedModel = model('');\n readonly open = model(false);\n readonly closeOnEscape = input(true);\n readonly pushContent = input(false);\n private readonly document = inject(DOCUMENT);\n constructor() {\n ensureChatRootStyles();\n effect((onCleanup) => {\n if (typeof document === 'undefined')\n return;\n const html = document.documentElement;\n if (this.open()) {\n html.dataset['threadplaneChatSidebar'] = 'open';\n }\n else {\n delete html.dataset['threadplaneChatSidebar'];\n }\n onCleanup(() => { delete html.dataset['threadplaneChatSidebar']; });\n });\n effect((onCleanup) => {\n const closeOnEscape = this.closeOnEscape();\n const win = this.document.defaultView;\n if (!win)\n return;\n const handler = (e: KeyboardEvent): void => {\n if (closeOnEscape && this.open() && e.key === 'Escape') {\n this.closeWindow();\n }\n };\n win.addEventListener('keydown', handler);\n onCleanup(() => win.removeEventListener('keydown', handler));\n });\n }\n toggle(): void { this.open.update((v) => !v); }\n openWindow(): void { this.open.set(true); }\n closeWindow(): void { this.open.set(false); }\n}" + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-sidenav/chat-sidenav.component.ts#ChatSidenavComponent", + "kind": "component", + "path": "libs/chat/src/lib/compositions/chat-sidenav/chat-sidenav.component.ts", + "symbol": "ChatSidenavComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-sidenav',\n standalone: true,\n imports: [ChatThreadListComponent, ChatProjectListComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.data-mode]': 'mode()',\n '[attr.data-open]': 'open() ? \"true\" : \"false\"',\n },\n styles: [CHAT_HOST_TOKENS, CHAT_SIDENAV_STYLES],\n template: `\n \n
\n \n
\n\n
\n \n \n \n \n \n New chat\n \n @if (mode() === 'drawer') {\n \n \n \n \n \n Close\n \n }\n
\n\n
\n \n \n \n \n \n Search\n \n
\n\n
\n \n
\n\n @if (projects() !== null) {\n
\n
Projects
\n \n
\n } @if (threads() !== null) {\n
\n
Recent
\n \n
\n } @if (archivedThreads() !== null) {\n \n \n \n \n \n Archived\n \n @if (archivedOpen()) {\n
\n @if (archivedThreads()!.length === 0) {\n
\n No archived conversations.\n
\n } @else {\n \n }\n
\n }\n \n }\n\n
\n \n
\n\n
\n \n \n \n
\n \n
\n
\n \n \n `,\n})\nexport class ChatSidenavComponent {\n readonly mode = input('expanded');\n readonly open = input(false);\n readonly threads = input(null);\n readonly activeThreadId = input(null);\n readonly actions = input(null);\n readonly archivedThreads = input(null);\n readonly projects = input(null);\n readonly selectedProjectId = input(null);\n readonly projectActions = input(null);\n readonly agent = input(null);\n readonly debug = input(true);\n readonly newChat = output();\n readonly threadSelected = output();\n readonly searchOpened = output();\n readonly openChange = output();\n readonly modeChange = output();\n readonly projectSelected = output();\n readonly newProjectRequested = output();\n protected readonly archivedOpen = signal(false);\n protected readonly showDebugButton = computed(() => CHAT_DEBUG_INCLUDED && this.debug() && this.agent() !== null);\n protected readonly isDebugStreaming = computed(() => this.agent()?.status?.() === 'running');\n private readonly destroyRef = inject(DestroyRef);\n private readonly injector = inject(Injector);\n private readonly debugHost = viewChild('debugHost', {\n read: ViewContainerRef,\n });\n private debugRef: ComponentRef | null = null;\n private debugOutputSubscriptions: OutputRefSubscription[] = [];\n private currentDebugDock: ChatDebugDock = 'right';\n constructor() {\n this.destroyRef.onDestroy(() => this.destroyDebug());\n effect(() => {\n const showDebug = this.showDebugButton();\n const agent = this.agent();\n if (!showDebug || !agent) {\n this.destroyDebug();\n return;\n }\n this.debugRef?.setInput('agent', agent);\n });\n fromEvent(window, 'keydown')\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((e) => {\n if (!(e.metaKey || e.ctrlKey))\n return;\n const key = e.key.toLowerCase();\n if (key !== 'k' && key !== 'b')\n return;\n const t = e.target as HTMLElement | null;\n if (t) {\n const tag = t.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || t.isContentEditable)\n return;\n }\n if (key === 'k') {\n e.preventDefault();\n this.searchOpened.emit();\n return;\n }\n if (this.mode() === 'drawer')\n return;\n e.preventDefault();\n this.modeChange.emit(this.mode() === 'collapsed' ? 'expanded' : 'collapsed');\n });\n }\n protected openDebug(event: MouseEvent): void {\n event.stopPropagation();\n void this.ensureDebugPanel();\n }\n protected onEscape(): void {\n if (this.mode() === 'drawer' && this.open()) {\n this.openChange.emit(false);\n }\n }\n protected onCollapseToggle(): void {\n const m = this.mode();\n if (m === 'drawer')\n return;\n this.modeChange.emit(m === 'collapsed' ? 'expanded' : 'collapsed');\n }\n private async ensureDebugPanel(): Promise {\n if (!CHAT_DEBUG_INCLUDED) {\n return;\n }\n if (!this.showDebugButton()) {\n this.destroyDebug();\n return;\n }\n const host = this.debugHost();\n const agent = this.agent();\n if (!host || !agent)\n return;\n if (!this.debugRef) {\n const { ChatDebugComponent } = await import('@threadplane/chat/debug');\n if (!this.showDebugButton())\n return;\n this.debugRef = host.createComponent(ChatDebugComponent, {\n injector: this.injector,\n });\n this.debugRef.setInput('launcher', 'none');\n this.debugRef.setInput('storageKey', 'chat-sidenav-debug');\n const initialDock = this.defaultDebugDock();\n this.debugRef.setInput('dock', initialDock);\n const openSub = this.debugRef.instance.openChange?.subscribe((open) => {\n if (open) {\n this.setDebugEdgeClaim(this.currentDebugDock);\n }\n else {\n this.clearDebugEdgeClaim();\n }\n });\n const dockSub = this.debugRef.instance.dockChange?.subscribe((dock) => {\n this.currentDebugDock = dock;\n this.setDebugEdgeClaim(dock);\n });\n this.debugOutputSubscriptions = [\n openSub,\n dockSub,\n ].filter((sub): sub is OutputRefSubscription => !!sub);\n this.currentDebugDock = initialDock;\n this.setDebugEdgeClaim(initialDock);\n }\n this.debugRef.setInput('agent', agent);\n this.debugRef.instance.setOpen(true);\n this.debugRef.changeDetectorRef.detectChanges();\n if (this.currentDebugDock === 'bottom') {\n this.debugRef.instance.setDock?.('bottom');\n this.debugRef.changeDetectorRef.detectChanges();\n }\n this.setDebugEdgeClaim(this.currentDebugDock);\n }\n private destroyDebug(): void {\n for (const subscription of this.debugOutputSubscriptions) {\n subscription.unsubscribe();\n }\n this.debugOutputSubscriptions = [];\n this.debugRef?.destroy();\n this.debugRef = null;\n this.clearDebugEdgeClaim();\n }\n private defaultDebugDock(): ChatDebugDock {\n if (typeof document === 'undefined')\n return 'right';\n return document.querySelector('chat-sidebar') ? 'bottom' : 'right';\n }\n private setDebugEdgeClaim(dock: ChatDebugDock): void {\n if (typeof document === 'undefined')\n return;\n document.documentElement.dataset['threadplaneChatDebug'] = dock;\n }\n private clearDebugEdgeClaim(): void {\n if (typeof document === 'undefined')\n return;\n delete document.documentElement.dataset['threadplaneChatDebug'];\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-subagent-card/chat-subagent-card.component.ts#ChatSubagentCardComponent", + "kind": "component", + "path": "libs/chat/src/lib/compositions/chat-subagent-card/chat-subagent-card.component.ts", + "symbol": "ChatSubagentCardComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-subagent-card',\n standalone: true,\n imports: [ChatTraceComponent, ChatToolCallCardComponent, ChatStreamingMdComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host { display: block; }\n .sac__name { color: var(--tplane-chat-text); font-weight: 500; font-size: var(--tplane-chat-font-size-sm); }\n .sac__id { font-family: var(--tplane-chat-font-mono); font-size: var(--tplane-chat-font-size-xs); color: var(--tplane-chat-text-muted); margin-left: 4px; }\n .sac__pill {\n padding: 1px 8px;\n border-radius: 9999px;\n font-size: 11px;\n font-weight: 500;\n margin-left: 4px;\n }\n .sac__pill[data-status=\"pending\"] { background: var(--tplane-chat-surface-alt); color: var(--tplane-chat-text-muted); }\n .sac__pill[data-status=\"running\"] { background: var(--tplane-chat-warning-bg); color: var(--tplane-chat-warning-text); }\n .sac__pill[data-status=\"complete\"] { color: var(--tplane-chat-success); }\n .sac__pill[data-status=\"error\"] { background: var(--tplane-chat-error-bg); color: var(--tplane-chat-error-text); }\n .sac__count { font-size: var(--tplane-chat-font-size-xs); color: var(--tplane-chat-text-muted); }\n .sac__msg { padding: 6px 0; }\n .sac__msg + .sac__msg { border-top: 1px solid var(--tplane-chat-separator); }\n .sac__reasoning {\n font-size: var(--tplane-chat-font-size-xs);\n color: var(--tplane-chat-text-muted);\n font-style: italic;\n margin-bottom: 4px;\n }\n `],\n template: `\n \n \n {{ subagent().name ?? 'Subagent' }}\n {{ subagent().toolCallId }}\n {{ subagent().status() }}\n \n
{{ subagent().messages().length }} message(s)
\n @for (m of subagent().messages(); track m.id) {\n
\n @if (m.reasoning) {\n
{{ m.reasoning }}
\n }\n @if (textOf(m); as t) {\n \n }\n @for (tc of toolCallsFor(m); track tc.id) {\n \n }\n
\n }\n
\n `,\n})\nexport class ChatSubagentCardComponent {\n readonly subagent = input.required();\n readonly state = computed(() => statusToTraceState(this.subagent().status()));\n private readonly markdownDocuments = new Map();\n constructor() {\n effect(() => {\n let liveIds: Set;\n try {\n liveIds = new Set(this.subagent().messages().map((message) => message.id));\n }\n catch {\n return;\n }\n for (const id of [...this.markdownDocuments.keys()]) {\n if (!liveIds.has(id))\n this.markdownDocuments.delete(id);\n }\n });\n }\n protected markdownDocumentFor(content: string, message: Message): StreamingMarkdownDocument {\n const prior = this.markdownDocuments.get(message.id);\n const delivery = message.delivery;\n if (prior?.generation === delivery.generation &&\n prior.phase === delivery.phase &&\n prior.content === content) {\n return prior;\n }\n const document = markdownDocument(content, delivery);\n this.markdownDocuments.set(message.id, document);\n return document;\n }\n protected textOf(m: Message): string {\n const c = m.content;\n return typeof c === 'string' ? c : '';\n }\n protected toolCallsFor(m: Message): ToolCall[] {\n const ids = m.toolCallIds ?? [];\n if (ids.length === 0)\n return [];\n const all = this.subagent().toolCalls?.() ?? [];\n return ids.map((id) => all.find((tc) => tc.id === id)).filter((tc): tc is ToolCall => !!tc);\n }\n protected toToolCallInfo(tc: ToolCall): ToolCallInfo {\n return { id: tc.id, name: tc.name, args: tc.args, result: tc.result, status: tc.status };\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-timeline-slider/chat-timeline-slider.component.ts#ChatTimelineSliderComponent", + "kind": "component", + "path": "libs/chat/src/lib/compositions/chat-timeline-slider/chat-timeline-slider.component.ts", + "symbol": "ChatTimelineSliderComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-timeline-slider',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host { display: block; padding: var(--tplane-chat-space-2); }\n .timeline-slider__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 var(--tplane-chat-space-1) var(--tplane-chat-space-2);\n }\n .timeline-slider__title {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--tplane-chat-text-muted);\n margin: 0;\n }\n .timeline-slider__count {\n font-size: var(--tplane-chat-font-size-xs);\n color: var(--tplane-chat-text-muted);\n }\n .timeline-slider__empty {\n text-align: center;\n padding: var(--tplane-chat-space-4);\n color: var(--tplane-chat-text-muted);\n font-size: var(--tplane-chat-font-size-xs);\n }\n .timeline-slider__list {\n list-style: none;\n padding-left: 12px;\n margin: 0;\n border-left: 1px solid var(--tplane-chat-separator);\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n .timeline-slider__entry {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n margin-left: -1px;\n border-left: 2px solid transparent;\n border-radius: var(--tplane-chat-radius-button);\n cursor: default;\n color: var(--tplane-chat-text-muted);\n font-size: var(--tplane-chat-font-size-sm);\n transition: background 150ms ease;\n }\n .timeline-slider__entry:hover { background: color-mix(in srgb, var(--tplane-chat-text) 5%, transparent); }\n .timeline-slider__entry[data-active=\"true\"] {\n border-left-color: var(--tplane-chat-primary);\n color: var(--tplane-chat-text);\n }\n .timeline-slider__index {\n width: 22px;\n height: 22px;\n border-radius: 9999px;\n background: var(--tplane-chat-surface-alt);\n color: var(--tplane-chat-text-muted);\n font-size: 11px;\n font-weight: 600;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n .timeline-slider__entry[data-active=\"true\"] .timeline-slider__index {\n background: var(--tplane-chat-primary);\n color: var(--tplane-chat-on-primary);\n }\n .timeline-slider__body { flex: 1; min-width: 0; }\n .timeline-slider__label {\n font-weight: 500;\n color: var(--tplane-chat-text);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--tplane-chat-font-size-sm);\n }\n .timeline-slider__id {\n font-family: var(--tplane-chat-font-mono);\n font-size: 11px;\n color: var(--tplane-chat-text-muted);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .timeline-slider__actions { display: flex; gap: 4px; flex-shrink: 0; }\n .timeline-slider__btn {\n padding: 2px 8px;\n font-size: var(--tplane-chat-font-size-xs);\n border-radius: var(--tplane-chat-radius-button);\n background: var(--tplane-chat-surface-alt);\n color: var(--tplane-chat-text);\n border: 0;\n cursor: pointer;\n transition: background 150ms ease;\n }\n .timeline-slider__btn:hover { background: color-mix(in srgb, var(--tplane-chat-text) 8%, transparent); }\n `],\n template: `\n
\n

Timeline

\n {{ history().length }} checkpoint(s)\n
\n\n @if (history().length === 0) {\n

No checkpoints yet.

\n } @else {\n
    \n @for (cp of history(); track $index; let i = $index) {\n \n {{ i + 1 }}\n
    \n

    {{ cp.label ?? 'Step ' + (i + 1) }}

    \n @if (cp.id) {\n

    {{ cp.id }}

    \n }\n
    \n
    \n \n \n
    \n \n }\n
\n }\n `,\n})\nexport class ChatTimelineSliderComponent {\n readonly agent = input.required();\n readonly selectedIndex = signal(-1);\n readonly history = computed(() => this.agent().history());\n readonly replayRequested = output();\n readonly forkRequested = output();\n replay(cp: AgentCheckpoint): void {\n if (cp.id)\n this.replayRequested.emit(cp.id);\n }\n fork(cp: AgentCheckpoint, index: number): void {\n this.selectedIndex.set(index);\n if (cp.id)\n this.forkRequested.emit(cp.id);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-tool-call-card/chat-tool-call-card.component.ts#ChatToolCallCardComponent", + "kind": "component", + "path": "libs/chat/src/lib/compositions/chat-tool-call-card/chat-tool-call-card.component.ts", + "symbol": "ChatToolCallCardComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-tool-call-card',\n standalone: true,\n imports: [ChatTraceComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host { display: block; }\n .tcc__name {\n font-family: var(--tplane-chat-font-mono);\n font-size: var(--tplane-chat-font-size-sm, 13px);\n color: var(--tplane-chat-text-muted);\n font-weight: 400;\n padding-left: 2px;\n }\n .tcc__pill {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 1px 6px;\n border-radius: 9999px;\n background: var(--tplane-chat-surface-alt);\n color: var(--tplane-chat-text-muted);\n font-size: 10px;\n font-weight: 500;\n margin-left: 6px;\n line-height: 1.4;\n }\n .tcc__pill svg { width: 10px; height: 10px; }\n .tcc__pill[data-status=\"running\"] svg { animation: tcc-spin 0.8s linear infinite; }\n @keyframes tcc-spin { to { transform: rotate(360deg); } }\n .tcc__section { padding: 8px 0; }\n .tcc__section + .tcc__section { border-top: 1px solid var(--tplane-chat-separator); }\n .tcc__section-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--tplane-chat-text-muted);\n margin: 0 0 4px;\n }\n .tcc__section-body {\n font-family: var(--tplane-chat-font-mono);\n font-size: var(--tplane-chat-font-size-xs);\n color: var(--tplane-chat-text);\n white-space: pre-wrap;\n overflow-x: auto;\n margin: 0;\n }\n `],\n template: `\n \n \n {{ toolCall().name }}\n \n @switch (status()) {\n @case ('running') {\n \n \n \n }\n @case ('complete') {\n \n \n \n }\n @case ('error') {\n \n \n \n \n }\n }\n \n \n
\n \n
{{ formatJson(toolCall().args) }}
\n
\n @if (toolCall().result !== undefined) {\n
\n \n
{{ formatJson(toolCall().result) }}
\n
\n }\n
\n `,\n})\nexport class ChatToolCallCardComponent {\n readonly toolCall = input.required();\n readonly defaultCollapsed = input(true);\n readonly status = computed(() => {\n const tc = this.toolCall();\n if (tc.status)\n return tc.status;\n return tc.result !== undefined ? 'complete' : 'running';\n });\n readonly state = computed(() => {\n switch (this.status()) {\n case 'complete': return 'done';\n case 'error': return 'error';\n case 'running': return 'running';\n default: return 'pending';\n }\n });\n readonly autoExpanded = computed(() => {\n const s = this.status();\n if (s === 'running' || s === 'error')\n return true;\n return !this.defaultCollapsed();\n });\n readonly ariaLabel = computed(() => {\n switch (this.status()) {\n case 'running': return 'Running';\n case 'complete': return 'Completed';\n case 'error': return 'Failed';\n default: return '';\n }\n });\n formatJson(value: unknown): string {\n if (typeof value === 'string')\n return value;\n try {\n return JSON.stringify(value, null, 2);\n }\n catch {\n return String(value);\n }\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/compositions/chat/chat.component.ts#ChatComponent", + "kind": "component", + "path": "libs/chat/src/lib/compositions/chat/chat.component.ts", + "symbol": "ChatComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat',\n standalone: true,\n imports: [\n KeyValuePipe,\n ChatWindowComponent, ChatMessageListComponent, MessageTemplateDirective, ChatMessageComponent,\n ChatInputComponent, ChatTypingIndicatorComponent, ChatErrorComponent,\n ChatThreadListComponent, ChatGenerativeUiComponent,\n ChatStreamingMdComponent, ChatToolCallsComponent, ChatToolViewsComponent, A2uiSurfaceComponent,\n ChatMessageActionsComponent, ChatWelcomeComponent, ChatSelectComponent, ChatReasoningComponent,\n ChatScrollBubbleComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n { provide: CHAT_LIFECYCLE, useFactory: createChatLifecycle },\n {\n provide: DEVELOPMENT_COLLECTION_POLICY,\n useFactory: () => {\n const host = inject(ChatComponent);\n const parent = inject(DEVELOPMENT_COLLECTION_POLICY, { optional: true, skipSelf: true });\n return () => (parent?.() ?? true) && isDevelopmentRuntimeEnabled(host.agent());\n },\n },\n ],\n styles: [CHAT_HOST_TOKENS, `\n :host {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n height: 100%;\n min-height: 0;\n max-height: 100%;\n overflow: hidden;\n background: var(--tplane-chat-bg);\n }\n :host > chat-welcome {\n display: flex;\n flex: 1 1 auto;\n width: 100%;\n }\n .chat-shell { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .chat-shell__sidebar {\n width: 240px;\n flex-shrink: 0;\n border-right: 1px solid var(--tplane-chat-separator);\n background: var(--tplane-chat-surface-alt);\n overflow-y: auto;\n display: none;\n }\n @media (min-width: 768px) { .chat-shell__sidebar { display: block; } }\n .chat-shell__main { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 0; }\n .chat-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 60px 20px;\n color: var(--tplane-chat-text-muted);\n text-align: center;\n flex: 1;\n min-height: 0;\n }\n .chat-empty[hidden] { display: none; }\n .chat-empty__title { font-size: 1.125rem; font-weight: 500; color: var(--tplane-chat-text); margin: 0; }\n .chat-empty__sub { margin: 0; font-size: var(--tplane-chat-font-size-sm); }\n .chat-empty__title { font-size: 1.125rem; font-weight: 500; color: var(--tplane-chat-text); margin: 0; }\n .chat-empty__sub { margin: 0; font-size: var(--tplane-chat-font-size-sm); }\n .chat-scroll { flex: 1; min-height: 0; overflow-y: auto; padding-top: var(--tplane-chat-edge-pad); }\n .chat-scroll::-webkit-scrollbar { width: 6px; }\n .chat-scroll::-webkit-scrollbar-thumb { background: var(--tplane-chat-separator); border-radius: 10px; }\n [chatFooter] {\n padding-bottom: var(--tplane-chat-edge-pad);\n }\n .chat-footer-wrap { position: relative; }\n `],\n template: `\n @if (showWelcome()) {\n \n \n @if (showModelPicker() && modelOptions().length > 0) {\n \n }\n \n \n \n \n \n } @else {\n
\n @if (threads().length > 0) {\n \n }\n
\n \n \n
\n \n \n {{ humanContent(message) }}\n \n\n \n @let content = messageContent(message);\n @let classified = classifyMessage(content, message);\n \n \n @if (message.reasoning && reasoningRunStart(i)) {\n @let run = reasoningRun(i);\n \n }\n \n \n \n \n \n \n @if (classified.markdown(); as md) {\n \n }\n @if (classified.spec(); as spec) {\n \n \n }\n @if (classified.type() === 'a2ui' && views(); as catalog) {\n @for (entry of classified.a2uiSurfaces() | keyvalue; track entry.key) {\n \n }\n }\n \n @if (content.trim()) {\n \n }\n \n \n\n \n \n \n\n \n {{ messageContent(message) }}\n \n \n\n \n @if (pinned() && !currentAssistantStreaming()) {\n \n }\n
\n \n
\n
\n
\n }\n `,\n})\nexport class ChatComponent {\n readonly agent = input.required();\n readonly views = input(undefined);\n readonly clientTools = input(undefined);\n readonly store = input(undefined);\n readonly handlers = input) => unknown | Promise>>({});\n readonly threads = input([]);\n readonly activeThreadId = input('');\n readonly welcomeDisabled = input(false);\n readonly modelOptions = input([]);\n readonly showModelPicker = input(true);\n readonly selectedModel = model('');\n readonly modelPickerPlaceholder = input('Choose a model');\n readonly genuiToolNames = input([\n 'generate_a2ui_schema',\n 'generate_json_render_spec',\n 'render_spec',\n ]);\n readonly clientToolExecutionGuard = input(undefined);\n readonly clientToolContinuationPolicy = input(undefined);\n readonly showWelcome = computed(() => {\n if (this.welcomeDisabled())\n return false;\n const a = this.agent() as unknown as {\n isThreadLoading?: () => boolean;\n };\n if (a.isThreadLoading?.())\n return false;\n return this.agent().messages().length === 0;\n });\n readonly threadSelected = output();\n readonly renderEvent = output();\n readonly clientToolContinuationLimit = output();\n readonly regenerate = output();\n readonly rate = output<{\n messageIndex: number;\n rating: 'up' | 'down';\n }>();\n readonly messageCopy = output<{\n messageIndex: number;\n content: string;\n }>();\n private readonly _internalStore = signalStateStore({});\n readonly resolvedStore = computed(() => {\n const explicit = this.store();\n if (explicit)\n return explicit;\n if (this.effectiveViews())\n return this._internalStore;\n return undefined;\n });\n private readonly coordinator = computed(() => {\n const reg = this.clientTools();\n const policy = this.clientToolContinuationPolicy();\n return reg ? createClientToolsCoordinator(reg, {\n executionGuard: this.clientToolExecutionGuard(),\n continuationPolicy: {\n ...policy,\n onLimit: (event) => {\n policy?.onLimit?.(event);\n this.clientToolContinuationLimit.emit(event);\n },\n },\n }) : undefined;\n });\n protected readonly effectiveViews = computed(() => {\n const base = this.views();\n const coord = this.coordinator();\n if (!coord)\n return base;\n return base ? withViews(base, coord.viewRegistry) : coord.viewRegistry;\n });\n readonly renderRegistry = computed(() => {\n const v = this.views();\n return v ? toRenderRegistry(v) : undefined;\n });\n readonly viewToolNames = computed(() => Object.keys(this.effectiveViews() ?? {}));\n readonly excludedToolNames = computed(() => [\n ...this.genuiToolNames(),\n ...this.viewToolNames(),\n ]);\n readonly messageContent = messageContent;\n protected humanContent(message: {\n content: unknown;\n }): string {\n const raw = messageContent(message);\n return a2uiActionLabel(raw) ?? raw;\n }\n private prevAssistant(msgs: Message[], index: number): Message | undefined {\n for (let j = index - 1; j >= 0; j--) {\n if (msgs[j].role === 'tool')\n continue;\n return msgs[j].role === 'assistant' ? msgs[j] : undefined;\n }\n return undefined;\n }\n protected reasoningRunStart(index: number): boolean {\n const msgs = this.agent().messages();\n if (!msgs[index]?.reasoning)\n return false;\n return !this.prevAssistant(msgs, index)?.reasoning;\n }\n protected reasoningRun(index: number): {\n content: string;\n durationMs: number | undefined;\n delivery: MessageDelivery;\n label: string | undefined;\n } {\n const msgs = this.agent().messages();\n const steps: Message[] = [];\n for (let j = index; j < msgs.length; j++) {\n const m = msgs[j];\n if (m.role === 'tool')\n continue;\n if (m.role === 'assistant' && m.reasoning) {\n steps.push(m);\n continue;\n }\n break;\n }\n const content = steps.map((step) => step.reasoning ?? '').filter(Boolean).join('\\n\\n');\n const durations = steps\n .map((step) => step.reasoningDurationMs)\n .filter((d): d is number => typeof d === 'number');\n const durationMs = durations.length ? durations.reduce((a, b) => a + b, 0) : undefined;\n const last = steps[steps.length - 1];\n const delivery = last?.delivery ?? msgs[index].delivery;\n const label = steps.length > 1\n ? durationMs !== undefined\n ? `Thought for ${formatDuration(durationMs)} · ${steps.length} steps`\n : `${steps.length} steps`\n : undefined;\n return { content, durationMs, delivery, label };\n }\n private readonly classifiers = new Map();\n private readonly markdownDocuments = new Map();\n private readonly destroyRef = inject(DestroyRef);\n private readonly injector = inject(Injector);\n private readonly lifecycle = (inject(CHAT_LIFECYCLE, { optional: true }) ?? createChatLifecycle()) as ChatLifecycleInternal;\n private eventsSubscribed = false;\n protected readonly liveSurfaceStore: A2uiSurfaceStore = createA2uiSurfaceStore();\n private readonly partialBridge: PartialArgsBridge = createPartialArgsBridge(this.liveSurfaceStore);\n private partialEventsLastIndex = 0;\n private readonly scrollContainer = viewChild>('scrollContainer');\n private readonly messageCount = computed(() => this.agent().messages().length);\n private prevMessageCount = 0;\n private wasLoading = false;\n protected readonly pinned = signal(true);\n private programmaticScrollCount = 0;\n private static readonly PIN_TOLERANCE_PX = 150;\n protected readonly currentAssistantStreaming = computed(() => {\n const msgs = this.agent().messages();\n if (msgs.length === 0)\n return false;\n const last = msgs[msgs.length - 1];\n return last?.role === 'assistant' && last.delivery.phase === 'streaming';\n });\n constructor() {\n ensureChatRootStyles();\n effect(() => {\n if (this.eventsSubscribed)\n return;\n let agent: ReturnType;\n try {\n agent = this.agent();\n }\n catch {\n return;\n }\n this.eventsSubscribed = true;\n this.lifecycle._internal.componentReady.set(true);\n agent.events$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {\n if (event.type !== 'state_update')\n return;\n const store = this.resolvedStore();\n if (!store)\n return;\n store.update(event.data);\n });\n });\n effect(() => {\n let agentRef: ReturnType;\n try {\n agentRef = this.agent();\n }\n catch {\n return;\n }\n const stateFn = (agentRef as unknown as {\n state?: () => unknown;\n }).state;\n if (typeof stateFn !== 'function')\n return;\n const state = stateFn.call(agentRef);\n const store = this.resolvedStore();\n if (!store || state == null || typeof state !== 'object' || Array.isArray(state))\n return;\n const updates: Record = {};\n for (const [k, v] of Object.entries(state as Record)) {\n if (k === 'messages')\n continue;\n updates['/' + k] = v;\n }\n if (Object.keys(updates).length > 0)\n store.update(updates);\n });\n effect(() => {\n let agentRef: ReturnType;\n try {\n agentRef = this.agent();\n }\n catch {\n return;\n }\n const lc = (agentRef as unknown as {\n lifecycle?: {\n streamStartedAt?: () => number | null;\n };\n }).lifecycle;\n const streamStartedAt = lc?.streamStartedAt?.();\n if (streamStartedAt != null && !this.lifecycle._internal.firstMessageSent()) {\n this.lifecycle._internal.firstMessageSent.set(true);\n }\n });\n effect(() => {\n let count: number;\n let msgs: ReturnType['messages']>;\n try {\n count = this.messageCount();\n msgs = this.agent().messages();\n }\n catch {\n return;\n }\n const lastContent = msgs.length > 0 ? (msgs[msgs.length - 1] as unknown as Record)['content'] : undefined;\n void lastContent;\n const el = this.scrollContainer()?.nativeElement;\n if (!el)\n return;\n const isNewMessage = count !== this.prevMessageCount;\n this.prevMessageCount = count;\n if (isNewMessage || this.pinned()) {\n this.programmaticScrollCount++;\n el.scrollTop = el.scrollHeight;\n requestAnimationFrame(() => { this.programmaticScrollCount--; });\n if (isNewMessage)\n untracked(() => this.pinned.set(true));\n }\n });\n effect(() => {\n let loading: boolean;\n try {\n loading = this.agent().isLoading();\n }\n catch {\n return;\n }\n if (loading) {\n this.wasLoading = true;\n return;\n }\n if (!this.wasLoading)\n return;\n this.wasLoading = false;\n if (this.pinned()) {\n requestAnimationFrame(() => {\n const el2 = this.scrollContainer()?.nativeElement;\n if (!el2)\n return;\n this.programmaticScrollCount++;\n el2.scrollTop = el2.scrollHeight;\n requestAnimationFrame(() => { this.programmaticScrollCount--; });\n });\n }\n });\n effect(() => {\n let agent: ReturnType;\n try {\n agent = this.agent();\n }\n catch {\n return;\n }\n const customSig = (agent as unknown as {\n customEvents?: () => readonly {\n name: string;\n data: unknown;\n }[];\n }).customEvents;\n if (typeof customSig !== 'function')\n return;\n const events = customSig();\n for (let i = this.partialEventsLastIndex; i < events.length; i++) {\n const e = events[i];\n if (e.name !== 'a2ui-partial')\n continue;\n const d = e.data as {\n tool_call_id?: string;\n args_so_far?: string;\n } | null;\n if (!d || typeof d.tool_call_id !== 'string' || typeof d.args_so_far !== 'string')\n continue;\n this.partialBridge.push(d.tool_call_id, d.args_so_far);\n }\n this.partialEventsLastIndex = events.length;\n });\n let connected: unknown;\n effect(() => {\n const coord = this.coordinator();\n let agentRef: ReturnType;\n try {\n agentRef = this.agent();\n }\n catch {\n return;\n }\n if (!coord || !agentRef)\n return;\n if (connected === coord)\n return;\n connected = coord;\n queueMicrotask(() => {\n runInInjectionContext(this.injector, () => coord.connect(agentRef));\n });\n });\n effect(() => {\n let liveIds: Set;\n try {\n liveIds = new Set();\n for (const m of this.agent().messages()) {\n const id = (m as unknown as {\n id?: string;\n }).id;\n if (id)\n liveIds.add(id);\n }\n }\n catch {\n return;\n }\n for (const key of [...this.classifiers.keys()]) {\n if (!liveIds.has(key)) {\n this.classifiers.get(key)?.classifier.dispose();\n this.classifiers.delete(key);\n }\n }\n for (const key of [...this.markdownDocuments.keys()]) {\n if (!liveIds.has(key))\n this.markdownDocuments.delete(key);\n }\n });\n }\n prevRole(index: number): ChatMessageRole | undefined {\n if (index === 0)\n return undefined;\n const prev = this.agent().messages()[index - 1];\n if (!prev)\n return undefined;\n const role = (prev as unknown as {\n role?: string;\n }).role;\n if (role === 'user')\n return 'user';\n if (role === 'assistant')\n return 'assistant';\n if (role === 'system')\n return 'system';\n if (role === 'tool')\n return 'tool';\n return undefined;\n }\n protected onScroll(): void {\n if (this.programmaticScrollCount > 0)\n return;\n const el = this.scrollContainer()?.nativeElement;\n if (!el)\n return;\n const nextPinned = isPinned(el.scrollHeight, el.scrollTop, el.clientHeight, ChatComponent.PIN_TOLERANCE_PX);\n if (nextPinned !== this.pinned())\n this.pinned.set(nextPinned);\n }\n scrollToBottom(): void {\n const el = this.scrollContainer()?.nativeElement;\n if (!el)\n return;\n this.programmaticScrollCount++;\n el.scrollTop = el.scrollHeight;\n requestAnimationFrame(() => { this.programmaticScrollCount--; });\n this.pinned.set(true);\n }\n protected onScrollBubbleClick(): void {\n this.scrollToBottom();\n }\n protected onUserSubmitted(): void {\n this.pinned.set(true);\n this.recordSubmit();\n }\n submitMessage(text: string): void {\n const trimmed = text.trim();\n if (!trimmed || this.agent().isInputBlocked?.())\n return;\n void this.agent().submit({ message: trimmed });\n this.recordSubmit();\n }\n clearThread(): void {\n this.clearClassifiers();\n this.lifecycle._internal.messageCount.set(0);\n this.lifecycle._internal.inputSubmittedAt.set(null);\n }\n private recordSubmit(): void {\n if (!this.lifecycle._internal.firstMessageSent()) {\n this.lifecycle._internal.firstMessageSent.set(true);\n }\n this.lifecycle._internal.messageCount.update((c) => c + 1);\n this.lifecycle._internal.inputSubmittedAt.set(Date.now());\n }\n protected prevMessage(index: number): unknown {\n if (index === 0)\n return undefined;\n return this.agent().messages()[index - 1];\n }\n protected isGenuiTurn(message: unknown, _prevMsg: unknown, index?: number): boolean {\n const names = new Set(this.genuiToolNames());\n const m = message as {\n extra?: Record;\n } | null | undefined;\n if (!m)\n return false;\n const calls = (m.extra?.['tool_calls'] as Array<{\n name?: string;\n }> | undefined) ?? [];\n if (calls.some(c => c.name != null && names.has(c.name)))\n return true;\n const rawContent = m.extra?.['content'];\n if (Array.isArray(rawContent)) {\n for (const block of rawContent) {\n if (block != null\n && typeof block === 'object'\n && (block as {\n type?: unknown;\n }).type === 'function_call'\n && typeof (block as {\n name?: unknown;\n }).name === 'string'\n && names.has((block as {\n name: string;\n }).name)) {\n return true;\n }\n }\n }\n const projectedContent = (m as {\n content?: unknown;\n }).content;\n if (typeof projectedContent === 'string' && projectedContent.length > 0) {\n if (projectedContent.includes('\"createSurface\"')\n || projectedContent.includes('\"updateComponents\"')\n || projectedContent.includes('\"updateDataModel\"')) {\n return true;\n }\n if (projectedContent.includes('\"root\"') && projectedContent.includes('\"elements\"')) {\n return true;\n }\n }\n const p = _prevMsg as {\n role?: string;\n name?: string;\n extra?: Record;\n } | null | undefined;\n if (p && p.role === 'tool') {\n const toolName = (p.extra?.['name'] as string | undefined) ?? p.name;\n if (typeof toolName === 'string' && names.has(toolName))\n return true;\n }\n if (typeof index === 'number' && index > 0) {\n const msgs = this.agent().messages();\n for (let i = index - 1; i >= 0; i--) {\n const prev = msgs[i] as {\n role?: string;\n extra?: Record;\n };\n if (!prev)\n break;\n if (prev.role === 'user')\n break;\n const prevCalls = (prev.extra?.['tool_calls'] as Array<{\n name?: string;\n }> | undefined) ?? [];\n if (prevCalls.some(c => c.name != null && names.has(c.name)))\n return true;\n const prevRaw = prev.extra?.['content'];\n if (Array.isArray(prevRaw)) {\n for (const block of prevRaw) {\n if (block != null\n && typeof block === 'object'\n && (block as {\n type?: unknown;\n }).type === 'function_call'\n && typeof (block as {\n name?: unknown;\n }).name === 'string'\n && names.has((block as {\n name: string;\n }).name)) {\n return true;\n }\n }\n }\n }\n }\n return false;\n }\n classifyMessage(content: string, message: Pick): ContentClassifier {\n const generation = message.delivery.generation;\n let entry = this.classifiers.get(message.id);\n if (!entry || entry.generation !== generation) {\n entry?.classifier.dispose();\n entry = { generation, classifier: createContentClassifier() };\n this.classifiers.set(message.id, entry);\n }\n entry.classifier.update(content);\n return entry.classifier;\n }\n protected markdownDocumentFor(content: string, message: Pick): StreamingMarkdownDocument {\n const prior = this.markdownDocuments.get(message.id);\n const delivery = message.delivery;\n if (prior?.generation === delivery.generation &&\n prior.phase === delivery.phase &&\n prior.content === content) {\n return prior;\n }\n const document = markdownDocument(content, delivery);\n this.markdownDocuments.set(message.id, document);\n return document;\n }\n clearClassifiers(): void {\n for (const [, entry] of this.classifiers) {\n entry.classifier.dispose();\n }\n this.classifiers.clear();\n this.markdownDocuments.clear();\n }\n onSpecEvent(event: RenderEvent, messageIndex: number): void {\n this.renderEvent.emit({ messageIndex, event });\n }\n protected onClientToolEvent(event: RenderEvent): void {\n const coord = this.coordinator();\n if (!coord)\n return;\n let agentRef: ReturnType;\n try {\n agentRef = this.agent();\n }\n catch {\n return;\n }\n coord.handleRenderEvent(agentRef, event);\n }\n onA2uiAction(message: A2uiActionMessage): void {\n if (this.agent().isInputBlocked?.())\n return;\n void this.agent().submit({ message: JSON.stringify(message) });\n }\n onA2uiEvent(event: RenderEvent, messageIndex: number, surfaceId: string): void {\n this.renderEvent.emit({ messageIndex, surfaceId, event });\n }\n onRegenerate(messageIndex: number): void {\n void this.agent().regenerate(messageIndex);\n this.regenerate.emit();\n }\n onRate(message: unknown, value: 'up' | 'down'): void {\n const idx = this.agent().messages().indexOf(message as never);\n this.rate.emit({ messageIndex: idx, rating: value });\n }\n onCopy(message: unknown, content: string): void {\n const idx = this.agent().messages().indexOf(message as never);\n this.messageCopy.emit({ messageIndex: idx, content });\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/markdown-children.component.ts#MarkdownChildrenComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/markdown-children.component.ts", + "symbol": "MarkdownChildrenComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-children',\n standalone: true,\n imports: [NgComponentOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @for (child of children(); track $index) {\n @let comp = resolve(child);\n @if (comp) {\n \n }\n }\n `,\n})\nexport class MarkdownChildrenComponent {\n readonly parent = input.required();\n private readonly registry = inject(MARKDOWN_VIEW_REGISTRY);\n protected readonly children = computed(() => {\n const p = this.parent();\n return 'children' in p && Array.isArray((p as {\n children?: MarkdownNode[];\n }).children)\n ? ((p as {\n children: MarkdownNode[];\n }).children as readonly MarkdownNode[])\n : [];\n });\n protected resolve(child: MarkdownNode): Type | null {\n const entry = this.registry[child.type];\n if (!entry)\n return null;\n return typeof entry === 'function' ? entry : entry.component;\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-autolink.component.ts#MarkdownAutolinkComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-autolink.component.ts", + "symbol": "MarkdownAutolinkComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-autolink',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `{{ node().url }}`,\n})\nexport class MarkdownAutolinkComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-blockquote.component.ts#MarkdownBlockquoteComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-blockquote.component.ts", + "symbol": "MarkdownBlockquoteComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-blockquote',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `
`,\n})\nexport class MarkdownBlockquoteComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-citation-reference.component.ts#MarkdownCitationReferenceComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-citation-reference.component.ts", + "symbol": "MarkdownCitationReferenceComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-citation-reference',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [ChatConnectedOverlayDirective, ChatOverlayOriginDirective, ChatCitationPreviewComponent],\n styles: [CHAT_HOST_TOKENS, CHAT_CITATION_MARKER_STYLES],\n template: `\n @if (resolved(); as r) {\n {{ node().index }}\n \n \n \n } @else {\n {{ node().index }}\n }\n `,\n})\nexport class MarkdownCitationReferenceComponent {\n readonly node = input.required();\n private readonly resolver = inject(CitationsResolverService);\n private readonly document = inject(DOCUMENT);\n protected readonly resolved = computed(() => this.resolver.lookup(this.node().refId)());\n protected readonly open = signal(false);\n protected readonly positions: ConnectedPosition[] = [\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 6 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -6 },\n ];\n private get hoverCapable(): boolean {\n return this.document.defaultView?.matchMedia?.('(hover: hover) and (pointer: fine)').matches ?? false;\n }\n private openTimer = 0;\n private closeTimer = 0;\n private pane: HTMLElement | null = null;\n private justOpenedByFocus = false;\n constructor() {\n inject(DestroyRef).onDestroy(() => this.clearTimers());\n }\n protected ariaLabel(c: Citation): string {\n const domain = deriveDomain(c.url);\n const parts = [`Source ${c.index}`];\n if (c.title)\n parts.push(c.title);\n if (domain)\n parts.push(domain);\n const base = parts.join(', ');\n return c.url ? `${base}, opens in new tab` : base;\n }\n protected onEnter(): void {\n if (!this.hoverCapable)\n return;\n this.cancelClose();\n const win = this.document.defaultView;\n if (win)\n this.openTimer = win.setTimeout(() => this.open.set(true), OPEN_DELAY_MS);\n }\n protected onLeave(): void {\n if (!this.hoverCapable)\n return;\n this.cancelOpen();\n this.scheduleClose();\n }\n protected onFocus(): void {\n this.open.set(true);\n this.justOpenedByFocus = true;\n }\n protected onBlur(): void {\n this.justOpenedByFocus = false;\n const active = this.document.activeElement;\n if (this.pane && active && this.pane.contains(active))\n return;\n this.close();\n }\n protected onClick(e: MouseEvent, c: Citation): void {\n if (this.hoverCapable && c.url)\n return;\n e.preventDefault();\n if (this.justOpenedByFocus) {\n this.justOpenedByFocus = false;\n return;\n }\n this.open.update((v) => !v);\n }\n protected onKeydown(e: KeyboardEvent, c: Citation): void {\n if (e.key === 'Escape') {\n this.close();\n return;\n }\n if (!c.url && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n this.open.set(true);\n }\n }\n protected onAttached(pane: HTMLElement): void {\n this.pane = pane;\n pane.addEventListener('mouseenter', this.onPaneEnter);\n pane.addEventListener('mouseleave', this.onPaneLeave);\n }\n protected close(): void {\n this.clearTimers();\n this.justOpenedByFocus = false;\n this.open.set(false);\n this.pane = null;\n }\n private readonly onPaneEnter = () => this.cancelClose();\n private readonly onPaneLeave = () => this.scheduleClose();\n private scheduleClose(): void {\n const win = this.document.defaultView;\n if (win)\n this.closeTimer = win.setTimeout(() => this.open.set(false), CLOSE_DELAY_MS);\n }\n private cancelOpen(): void {\n const win = this.document.defaultView;\n if (this.openTimer && win)\n win.clearTimeout(this.openTimer);\n this.openTimer = 0;\n }\n private cancelClose(): void {\n const win = this.document.defaultView;\n if (this.closeTimer && win)\n win.clearTimeout(this.closeTimer);\n this.closeTimer = 0;\n }\n private clearTimers(): void {\n this.cancelOpen();\n this.cancelClose();\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-code-block.component.ts#MarkdownCodeBlockComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-code-block.component.ts", + "symbol": "MarkdownCodeBlockComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-code-block',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `
{{ node().text }}
`,\n})\nexport class MarkdownCodeBlockComponent {\n readonly node = input.required();\n protected readonly languageClass = computed(() => {\n const lang = this.node().language;\n return lang ? `language-${lang}` : '';\n });\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-document.component.ts#MarkdownDocumentComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-document.component.ts", + "symbol": "MarkdownDocumentComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-document',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: ``,\n})\nexport class MarkdownDocumentComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-emphasis.component.ts#MarkdownEmphasisComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-emphasis.component.ts", + "symbol": "MarkdownEmphasisComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-emphasis',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: ``,\n})\nexport class MarkdownEmphasisComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-hard-break.component.ts#MarkdownHardBreakComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-hard-break.component.ts", + "symbol": "MarkdownHardBreakComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-hard-break',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `
`,\n})\nexport class MarkdownHardBreakComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-heading.component.ts#MarkdownHeadingComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-heading.component.ts", + "symbol": "MarkdownHeadingComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-heading',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @switch (node().level) {\n @case (1) {

}\n @case (2) {

}\n @case (3) {

}\n @case (4) {

}\n @case (5) {
}\n @case (6) {
}\n }\n `,\n})\nexport class MarkdownHeadingComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-html.component.ts#MarkdownHtmlComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-html.component.ts", + "symbol": "MarkdownHtmlComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-html',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `{{ raw() }}`,\n})\nexport class MarkdownHtmlComponent {\n readonly node = input.required();\n protected readonly raw = computed(() => this.node().raw);\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-image.component.ts#MarkdownImageComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-image.component.ts", + "symbol": "MarkdownImageComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-image',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (failed()) {\n \n 🖼️\n @if (node().alt) {\n {{ node().alt }}\n } @else {\n image unavailable\n }\n \n } @else {\n \n }\n `,\n})\nexport class MarkdownImageComponent {\n readonly node = input.required();\n protected readonly failed = signal(false);\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-inline-code.component.ts#MarkdownInlineCodeComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-inline-code.component.ts", + "symbol": "MarkdownInlineCodeComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-inline-code',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `{{ node().text }}`,\n})\nexport class MarkdownInlineCodeComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-link.component.ts#MarkdownLinkComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-link.component.ts", + "symbol": "MarkdownLinkComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-link',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: ``,\n})\nexport class MarkdownLinkComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-list-item.component.ts#MarkdownListItemComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-list-item.component.ts", + "symbol": "MarkdownListItemComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-list-item',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
  • \n @if (node().task !== undefined) {\n \n }\n \n
  • \n `,\n})\nexport class MarkdownListItemComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-list.component.ts#MarkdownListComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-list.component.ts", + "symbol": "MarkdownListComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-list',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (node().ordered) {\n
    \n } @else {\n
    \n }\n `,\n})\nexport class MarkdownListComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-math.component.ts#MarkdownMathComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-math.component.ts", + "symbol": "MarkdownMathComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-math',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n template: `\n @if (html(); as h) {\n \n } @else {\n {{ raw() }}\n }\n `,\n})\nexport class MarkdownMathComponent {\n readonly node = input.required();\n private readonly sanitizer = inject(DomSanitizer);\n protected readonly display = computed(() => this.node().type === 'math-display');\n protected readonly raw = computed(() => {\n const n = this.node();\n const [open, close] = DELIMITERS[n.delimiter];\n return `${open}${n.text}${close}`;\n });\n protected readonly html = computed(() => {\n katexReady();\n const n = this.node();\n const out = renderMath(n.text, n.type === 'math-display');\n if (out == null)\n return null;\n return this.sanitizer.bypassSecurityTrustHtml(out);\n });\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-paragraph.component.ts#MarkdownParagraphComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-paragraph.component.ts", + "symbol": "MarkdownParagraphComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-paragraph',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `

    `,\n})\nexport class MarkdownParagraphComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-soft-break.component.ts#MarkdownSoftBreakComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-soft-break.component.ts", + "symbol": "MarkdownSoftBreakComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-soft-break',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `
    `,\n})\nexport class MarkdownSoftBreakComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-strikethrough.component.ts#MarkdownStrikethroughComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-strikethrough.component.ts", + "symbol": "MarkdownStrikethroughComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-strikethrough',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: ``,\n})\nexport class MarkdownStrikethroughComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-strong.component.ts#MarkdownStrongComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-strong.component.ts", + "symbol": "MarkdownStrongComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-strong',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: ``,\n})\nexport class MarkdownStrongComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-table-cell.component.ts#MarkdownTableCellComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-table-cell.component.ts", + "symbol": "MarkdownTableCellComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-table-cell',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (isHeader()) {\n \n \n \n } @else {\n \n \n \n }\n `,\n})\nexport class MarkdownTableCellComponent {\n readonly node = input.required();\n private readonly isHeaderRowToken = inject(IS_HEADER_ROW, { optional: true });\n protected readonly isHeader = computed(() => this.isHeaderRowToken ? this.isHeaderRowToken() : false);\n protected readonly alignment = computed(() => this.node().alignment);\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-table-row.component.ts#MarkdownTableRowComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-table-row.component.ts", + "symbol": "MarkdownTableRowComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-table-row',\n standalone: true,\n imports: [NgComponentOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n \n @for (child of node().children; track $index) {\n @let comp = resolve(child);\n @if (comp) {\n \n }\n }\n \n `,\n providers: [\n {\n provide: IS_HEADER_ROW,\n useFactory: () => {\n const comp = inject(MarkdownTableRowComponent);\n return computed(() => comp.node().isHeader);\n },\n },\n ],\n})\nexport class MarkdownTableRowComponent {\n readonly node = input.required();\n private readonly registry = inject(MARKDOWN_VIEW_REGISTRY);\n protected resolve(child: MarkdownNode): Type | null {\n const entry = this.registry[child.type];\n if (!entry)\n return null;\n return typeof entry === 'function' ? entry : entry.component;\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-table.component.ts#MarkdownTableComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-table.component.ts", + "symbol": "MarkdownTableComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-table',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n \n \n @if (headerRow(); as row) {\n \n @for (cell of row.children; track $index) {\n \n }\n \n }\n \n \n @for (row of bodyRows(); track $index) {\n \n @for (cell of row.children; track $index) {\n \n }\n \n }\n \n
    \n \n
    \n \n
    \n `,\n})\nexport class MarkdownTableComponent {\n readonly node = input.required();\n protected readonly headerRow = computed(() => {\n const rows = this.node().children;\n return rows.length > 0 && rows[0].isHeader ? rows[0] : null;\n });\n protected readonly bodyRows = computed(() => {\n const rows = this.node().children;\n return rows[0]?.isHeader ? rows.slice(1) : rows;\n });\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-text.component.ts#MarkdownTextComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-text.component.ts", + "symbol": "MarkdownTextComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-text',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `{{ node().text }}`,\n})\nexport class MarkdownTextComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-thematic-break.component.ts#MarkdownThematicBreakComponent", + "kind": "component", + "path": "libs/chat/src/lib/markdown/views/markdown-thematic-break.component.ts", + "symbol": "MarkdownThematicBreakComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-md-thematic-break',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `
    `,\n})\nexport class MarkdownThematicBreakComponent {\n readonly node = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-citations/chat-citation-preview.component.ts#ChatCitationPreviewComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citation-preview.component.ts", + "symbol": "ChatCitationPreviewComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-citation-preview',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_CITATION_PREVIEW_STYLES],\n template: `\n
    \n
    \n @if (sourceIconUrl(); as icon) {\n \"\"\n } @else if (sourceIcon(); as icon) {\n \n \n @switch (icon) {\n @case ('file') {\n \n \n }\n @case ('app') {\n \n \n }\n @case ('memory') {\n \n \n }\n @case ('web') {\n \n \n }\n @default {\n \n \n }\n }\n \n \n } @else {\n {{ sourceMonogram() }}\n }\n @if (domain(); as d) { {{ d }} }\n @if (typeLabel(); as t) {\n {{ t }}\n }\n
    \n @if (citation().title; as title) {\n

    {{ title }}

    \n }\n @if (citation().snippet; as s) {\n

    {{ s }}

    \n }\n @if (citation().url; as url) {\n
    \n \n \n \n \n Open source\n \n @if (published(); as p) { {{ p }} }\n
    \n }\n
    \n `,\n})\nexport class ChatCitationPreviewComponent {\n readonly citation = input.required();\n private readonly sourceVisual = computed(() => citationSourceVisual(this.citation()));\n private readonly typeMeta = computed(() => citationTypeMeta(this.citation()));\n protected readonly domain = computed(() => deriveDomain(this.citation().url));\n protected readonly sourceIconUrl = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'image' ? visual.iconUrl : null;\n });\n protected readonly sourceIcon = computed((): CitationTypeIcon | null => {\n const visual = this.sourceVisual();\n return visual.kind === 'type-icon' ? visual.icon : null;\n });\n protected readonly sourceMonogram = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'monogram' ? visual.monogram : null;\n });\n protected readonly sourceMonoColor = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'monogram' ? visual.color : null;\n });\n protected readonly typeLabel = computed(() => this.typeMeta().label);\n protected readonly typeTone = computed(() => this.typeMeta().tone);\n protected readonly published = computed(() => formatPublished(this.citation().publishedAt));\n protected isTypeTone(tone: CitationTypeIcon): boolean {\n return this.typeTone() === tone;\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-citations/chat-citations-card.component.ts#ChatCitationsCardComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citations-card.component.ts", + "symbol": "ChatCitationsCardComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-citations-card',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet],\n styles: [CHAT_HOST_TOKENS, CHAT_CITATIONS_PANEL_STYLES],\n template: `\n @if (citation().url; as url) {\n \n \n \n } @else {\n
    \n \n
    \n }\n\n \n {{ citation().index }}\n \n \n @if (sourceIconUrl(); as icon) {\n \"\"\n } @else if (sourceIcon(); as icon) {\n \n \n @switch (icon) {\n @case ('file') {\n \n \n }\n @case ('app') {\n \n \n }\n @case ('memory') {\n \n \n }\n @case ('web') {\n \n \n }\n @default {\n \n \n }\n }\n \n \n } @else {\n {{ sourceMonogram() }}\n }\n @if (domain(); as d) { {{ d }} }\n @if (typeLabel(); as t) {\n {{ t }}\n }\n \n @if (title(); as t) {\n {{ t }}\n }\n @if (citation().snippet; as s) {\n {{ s }}\n }\n \n \n `,\n})\nexport class ChatCitationsCardComponent {\n readonly citation = input.required();\n private readonly sourceVisual = computed(() => citationSourceVisual(this.citation()));\n private readonly typeMeta = computed(() => citationTypeMeta(this.citation()));\n protected readonly domain = computed(() => deriveDomain(this.citation().url));\n protected readonly title = computed(() => this.citation().title ?? this.citation().url ?? null);\n protected readonly sourceIconUrl = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'image' ? visual.iconUrl : null;\n });\n protected readonly sourceIcon = computed((): CitationTypeIcon | null => {\n const visual = this.sourceVisual();\n return visual.kind === 'type-icon' ? visual.icon : null;\n });\n protected readonly sourceMonogram = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'monogram' ? visual.monogram : null;\n });\n protected readonly sourceMonoColor = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'monogram' ? visual.color : null;\n });\n protected readonly typeLabel = computed(() => this.typeMeta().label);\n protected readonly typeTone = computed(() => this.typeMeta().tone);\n protected isTypeTone(tone: CitationTypeIcon): boolean {\n return this.typeTone() === tone;\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts#ChatCitationCardTemplateDirective", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts", + "symbol": "ChatCitationCardTemplateDirective", + "decorators": [ + "Directive" + ], + "signature": "@Directive({ selector: 'ng-template[chatCitationCard]', standalone: true })\nexport class ChatCitationCardTemplateDirective {\n readonly tpl = inject>(TemplateRef);\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts#ChatCitationsComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts", + "symbol": "ChatCitationsComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-citations',\n standalone: true,\n imports: [NgTemplateOutlet, ChatCitationsCardComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_CITATIONS_PANEL_STYLES],\n template: `\n @if (citations().length > 0) {\n
    \n \n {{ heading() }}\n {{ citations().length }}\n \n @for (f of favstack(); track f.id) {\n @if (f.kind === 'image' && f.iconUrl) {\n \"\"\n } @else if (f.kind === 'type-icon' && f.icon) {\n \n \n @switch (f.icon) {\n @case ('file') {\n \n \n }\n @case ('app') {\n \n \n }\n @case ('memory') {\n \n \n }\n @case ('web') {\n \n \n }\n @default {\n \n \n }\n }\n \n \n } @else {\n {{ f.monogram }}\n }\n }\n \n \n \n \n \n @if (expanded()) {\n
      \n @for (c of citations(); track c.id) {\n
    • \n @if (cardTpl) {\n \n } @else {\n \n }\n
    • \n }\n
    \n }\n
    \n }\n `,\n})\nexport class ChatCitationsComponent {\n readonly message = input.required();\n readonly heading = input('Sources');\n protected readonly expanded = signal(false);\n protected readonly listId = `chat-citations-list-${nextCitationsId++}`;\n @ContentChild(ChatCitationCardTemplateDirective)\n cardTpl: ChatCitationCardTemplateDirective | null = null;\n private readonly resolver = inject(CitationsResolverService, { optional: true });\n protected readonly citations = computed(() => {\n const fromMessage = this.message().citations ?? [];\n const seenIds = new Set(fromMessage.map((c) => c.id));\n const fromMarkdown: Citation[] = [];\n const mdDefs = this.resolver?.markdownDefs();\n if (mdDefs) {\n for (const def of mdDefs.values()) {\n if (!seenIds.has(def.id))\n fromMarkdown.push(mdDefToCitation(def));\n }\n }\n return [...fromMessage, ...fromMarkdown].sort((a, b) => a.index - b.index);\n });\n protected readonly favstack = computed(() => this.citations().slice(0, 3).map((c) => ({ id: c.id, ...citationSourceVisual(c) })));\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-confirm-dialog/chat-confirm-dialog.component.ts#ChatConfirmDialogComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-confirm-dialog/chat-confirm-dialog.component.ts", + "symbol": "ChatConfirmDialogComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-confirm-dialog',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_CONFIRM_DIALOG_STYLES],\n template: `\n @if (open()) {\n \n \n

    {{ title() }}

    \n @if (body()) {\n

    {{ body() }}

    \n }\n
    \n {{ cancelLabel() }}\n {{ confirmLabel() }}\n
    \n \n }\n `,\n})\nexport class ChatConfirmDialogComponent {\n readonly open = input(false);\n readonly title = input('Are you sure?');\n readonly body = input('');\n readonly confirmLabel = input('Confirm');\n readonly cancelLabel = input('Cancel');\n readonly tone = input<'destructive' | 'normal'>('normal');\n readonly confirmed = output();\n readonly cancelled = output();\n private readonly instanceId = ++confirmDialogInstanceCounter;\n protected readonly titleId = `chat-confirm-dialog__title-${this.instanceId}`;\n protected readonly bodyId = `chat-confirm-dialog__body-${this.instanceId}`;\n private readonly cancelBtn = viewChild>('cancelBtn');\n constructor() {\n effect(() => {\n if (!this.open())\n return;\n queueMicrotask(() => this.cancelBtn()?.nativeElement.focus());\n });\n }\n protected onDialogKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.cancelled.emit();\n }\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-error/chat-error.component.ts#ChatErrorComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-error/chat-error.component.ts", + "symbol": "ChatErrorComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-error',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_ERROR_STYLES],\n template: `\n @if (agent().error(); as err) {\n
    \n \n \n \n {{ err.message }}\n \n @if (err.recovery === 'check') {\n @if (agent().checkStatus) {\n \n }\n } @else if (err.retryable) {\n \n }\n @if (err.detail) {\n {{ err.detail }}\n }\n
    \n }\n `,\n})\nexport class ChatErrorComponent {\n readonly agent = input.required();\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-generative-ui/chat-generative-ui.component.ts#ChatGenerativeUiComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-generative-ui/chat-generative-ui.component.ts", + "symbol": "ChatGenerativeUiComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-generative-ui',\n standalone: true,\n imports: [RenderSpecComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_GENERATIVE_UI_STYLES],\n template: `\n @if (normalizedSpec()) {\n \n }\n `,\n})\nexport class ChatGenerativeUiComponent {\n readonly spec = input(null);\n readonly registry = input(undefined);\n readonly store = input(undefined);\n readonly handlers = input) => unknown | Promise> | undefined>(undefined);\n readonly loading = input(false);\n readonly events = output();\n protected readonly normalizedSpec = computed(() => {\n const s = this.spec();\n return s ? normalizeJsonRenderSpec(s) : null;\n });\n private readonly seeded = new Map();\n constructor() {\n effect(() => {\n const s = this.spec();\n const store = this.store();\n const state = s?.state as Record | undefined;\n if (!state || !store)\n return;\n untracked(() => {\n for (const [key, value] of Object.entries(state)) {\n const path = key.startsWith('/') ? key : `/${key}`;\n const current = store.get(path);\n const untouched = current === undefined ||\n (this.seeded.has(path) && current === this.seeded.get(path));\n if (untouched) {\n if (current !== value)\n store.set(path, value);\n this.seeded.set(path, value);\n }\n }\n });\n });\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-genui-skeleton/chat-genui-skeleton.component.ts#ChatGenuiSkeletonComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-genui-skeleton/chat-genui-skeleton.component.ts", + "symbol": "ChatGenuiSkeletonComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-genui-skeleton',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host { display: block; width: 100%; }\n .chat-genui-skeleton {\n border: 1px solid var(--tplane-chat-separator);\n border-radius: 10px;\n padding: 14px;\n background: var(--tplane-chat-surface-alt);\n }\n .chat-genui-skeleton__label {\n font-size: 12px;\n color: var(--tplane-chat-text-muted);\n margin-bottom: 10px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .chat-genui-skeleton__rows {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .chat-genui-skeleton__row {\n height: 10px;\n border-radius: 5px;\n background: linear-gradient(\n 90deg,\n var(--tplane-chat-separator) 0%,\n color-mix(in srgb, var(--tplane-chat-separator) 70%, transparent) 50%,\n var(--tplane-chat-separator) 100%\n );\n background-size: 200% 100%;\n animation: chat-genui-skeleton-shimmer 1.4s ease-in-out infinite;\n }\n .chat-genui-skeleton__row:nth-child(1) { width: 70%; }\n .chat-genui-skeleton__row:nth-child(2) { width: 90%; }\n .chat-genui-skeleton__row:nth-child(3) { width: 50%; }\n @keyframes chat-genui-skeleton-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n `],\n template: `\n
    \n
    \n \n Building UI…\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n `,\n})\nexport class ChatGenuiSkeletonComponent {\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-history-search-palette/chat-history-search-palette.component.ts#ChatHistorySearchPaletteComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-history-search-palette/chat-history-search-palette.component.ts", + "symbol": "ChatHistorySearchPaletteComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-history-search-palette',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_HISTORY_SEARCH_PALETTE_STYLES],\n template: `\n @if (open()) {\n \n \n
    \n \n \n \n \n \n \n \n \n \n \n \n
    \n\n @if (loading() && results().length === 0) {\n
    \n
    \n
    \n
    \n
    \n } @else if (results().length === 0 && query().length === 0) {\n
    Type to search your conversations.
    \n } @else if (results().length === 0) {\n
    No conversations match.
    \n } @else {\n
      \n @for (row of results(); let i = $index; track row.id) {\n \n {{ row.title }}\n @if (row.subtitle) {\n {{ row.subtitle }}\n }\n \n }\n
    \n }\n \n }\n `,\n})\nexport class ChatHistorySearchPaletteComponent {\n readonly open = model(false);\n readonly query = model('');\n readonly results = input([]);\n readonly loading = input(false);\n readonly placeholder = input('Search conversations');\n readonly threadSelected = output();\n readonly closed = output();\n protected readonly activeIndex = signal(0);\n protected readonly listId = `chat-history-search-palette__results-${++paletteInstanceCounter}`;\n private readonly inputEl = viewChild>('inputEl');\n constructor() {\n effect(() => {\n if (this.open()) {\n this.activeIndex.set(0);\n queueMicrotask(() => this.inputEl()?.nativeElement.focus());\n }\n });\n effect(() => {\n const max = this.results().length - 1;\n if (max >= 0 && this.activeIndex() > max) {\n this.activeIndex.set(max);\n }\n });\n }\n protected rowId(index: number): string {\n return `${this.listId}__row-${index}`;\n }\n protected activeRowId(): string | null {\n return this.results().length > 0 ? this.rowId(this.activeIndex()) : null;\n }\n protected onInput(e: Event): void {\n const value = (e.target as HTMLInputElement).value;\n this.query.set(value);\n }\n protected onInputKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.closed.emit();\n return;\n }\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n const max = this.results().length - 1;\n if (max < 0)\n return;\n this.activeIndex.set(Math.min(this.activeIndex() + 1, max));\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n this.activeIndex.set(Math.max(this.activeIndex() - 1, 0));\n return;\n }\n if (e.key === 'Enter') {\n e.preventDefault();\n const rows = this.results();\n if (rows.length === 0)\n return;\n const row = rows[this.activeIndex()];\n this.threadSelected.emit(row.id);\n return;\n }\n }\n protected onRowClick(id: string): void {\n this.threadSelected.emit(id);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-input/chat-input.component.ts#ChatInputComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-input/chat-input.component.ts", + "symbol": "ChatInputComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-input',\n standalone: true,\n imports: [],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_INPUT_STYLES],\n template: `\n
    \n \n \n
    \n \n \n
    \n \n \n @if (isLoading() && canStop()) {\n \n \n \n \n \n } @else {\n \n \n \n \n \n \n }\n
    \n
    \n \n
    \n `,\n})\nexport class ChatInputComponent {\n readonly agent = input.required();\n readonly submitOnEnter = input(true);\n readonly placeholder = input('');\n readonly showStopButton = input(true);\n readonly submitted = output();\n readonly stopped = output();\n readonly messageText = signal('');\n readonly isLoading = computed(() => this.agent().isLoading());\n protected readonly composing = signal(false);\n readonly focused = signal(false);\n readonly canSubmit = computed(() => {\n if (this.isLoading() || this.agent().isInputBlocked?.())\n return false;\n return this.messageText().trim().length > 0;\n });\n readonly canStop = computed(() => this.showStopButton());\n private readonly textareaEl = viewChild>('textareaEl');\n constructor() {\n effect(() => {\n const text = this.messageText();\n const el = this.textareaEl()?.nativeElement;\n if (!el)\n return;\n const viewportH = typeof window === 'undefined' ? 600 : window.innerHeight;\n const cap = Math.min(viewportH * 0.4, 320);\n el.style.height = 'auto';\n const next = Math.min(el.scrollHeight, cap);\n el.style.height = `${next}px`;\n el.style.overflowY = el.scrollHeight > cap ? 'auto' : 'hidden';\n void text;\n });\n }\n focusTextarea(): void {\n this.textareaEl()?.nativeElement.focus();\n }\n onSubmit(): void {\n const submitted = submitMessage(this.agent(), this.messageText());\n if (submitted !== null) {\n this.submitted.emit(submitted);\n this.messageText.set('');\n const el = this.textareaEl()?.nativeElement;\n if (el)\n el.value = '';\n requestAnimationFrame(() => this.textareaEl()?.nativeElement.focus());\n }\n }\n protected onInput(event: Event): void {\n this.messageText.set((event.target as HTMLTextAreaElement).value);\n }\n onStop(): void {\n const a = this.agent() as unknown as {\n stop?: () => void | Promise;\n };\n if (typeof a.stop === 'function') {\n void a.stop();\n }\n this.stopped.emit();\n }\n onKeydown(event: KeyboardEvent): void {\n if (!this.submitOnEnter() || event.shiftKey)\n return;\n if (this.composing() || event.isComposing || event.keyCode === 229)\n return;\n event.preventDefault();\n this.onSubmit();\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-interrupt/chat-interrupt.component.ts#ChatInterruptComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-interrupt/chat-interrupt.component.ts", + "symbol": "ChatInterruptComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-interrupt',\n standalone: true,\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_INTERRUPT_STYLES],\n template: `\n @if (interrupt(); as currentInterrupt) {\n
    \n
    \n \n \n \n Agent paused\n
    \n @if (templateRef()) {\n \n } @else {\n

    {{ defaultText(currentInterrupt) }}

    \n }\n
    \n }\n `,\n})\nexport class ChatInterruptComponent {\n readonly agent = input.required();\n readonly templateRef = contentChild(TemplateRef);\n readonly interrupt = computed(() => getInterrupt(this.agent()));\n defaultText(i: AgentInterrupt): string {\n const v = (i as {\n value?: unknown;\n }).value;\n return typeof v === 'string' ? v : JSON.stringify(v);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-launcher-button/chat-launcher-button.component.ts#ChatLauncherButtonComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-launcher-button/chat-launcher-button.component.ts", + "symbol": "ChatLauncherButtonComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-launcher-button',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_LAUNCHER_BUTTON_STYLES],\n template: `\n \n `,\n})\nexport class ChatLauncherButtonComponent {\n readonly clicked = output();\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-message-actions/chat-message-actions.component.ts#ChatMessageActionsComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-message-actions/chat-message-actions.component.ts", + "symbol": "ChatMessageActionsComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-message-actions',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_MESSAGE_ACTIONS_STYLES],\n host: {\n 'role': 'toolbar',\n '[attr.aria-label]': '\"Message actions\"',\n },\n template: `\n \n \n \n \n \n \n \n \n \n @if (copied()) {\n \n } @else {\n \n \n \n \n }\n \n \n \n \n \n \n \n \n \n \n \n \n \n `,\n})\nexport class ChatMessageActionsComponent {\n readonly content = input('');\n readonly disabled = input(false);\n readonly regenerate = output();\n readonly rate = output<'up' | 'down'>();\n readonly contentCopied = output();\n protected readonly copied = signal(false);\n protected readonly rating = signal<'up' | 'down' | null>(null);\n private readonly document = inject(DOCUMENT);\n protected async onCopy(): Promise {\n const text = this.content();\n if (!text)\n return;\n let succeeded = false;\n const win = this.document.defaultView;\n if (win?.navigator?.clipboard?.writeText) {\n try {\n await win.navigator.clipboard.writeText(text);\n succeeded = true;\n }\n catch {\n }\n }\n if (!succeeded) {\n try {\n const ta = this.document.createElement('textarea');\n ta.value = text;\n ta.style.position = 'fixed';\n ta.style.opacity = '0';\n this.document.body.appendChild(ta);\n ta.select();\n succeeded = !!this.document.execCommand?.('copy');\n ta.remove();\n }\n catch {\n }\n }\n if (succeeded) {\n this.copied.set(true);\n this.contentCopied.emit(text);\n setTimeout(() => this.copied.set(false), 2000);\n }\n }\n protected onRate(value: 'up' | 'down'): void {\n this.rating.set(this.rating() === value ? null : value);\n this.rate.emit(value);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-message-list/chat-message-list.component.ts#ChatMessageListComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-message-list/chat-message-list.component.ts", + "symbol": "ChatMessageListComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-message-list',\n standalone: true,\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_MESSAGE_LIST_STYLES],\n template: `\n @for (message of messages(); track message.id) {\n @let template = findTemplate(getMessageType(message));\n @if (template) {\n \n }\n }\n `,\n})\nexport class ChatMessageListComponent {\n readonly agent = input.required();\n readonly messageTemplates = contentChildren(MessageTemplateDirective);\n readonly messages = computed(() => this.agent().messages());\n readonly getMessageType = getMessageType;\n findTemplate(type: MessageTemplateType): MessageTemplateDirective | undefined {\n return this.messageTemplates().find(t => t.chatMessageTemplate() === type);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-message-list/message-template.directive.ts#MessageTemplateDirective", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-message-list/message-template.directive.ts", + "symbol": "MessageTemplateDirective", + "decorators": [ + "Directive" + ], + "signature": "@Directive({\n selector: 'ng-template[chatMessageTemplate]',\n standalone: true,\n})\nexport class MessageTemplateDirective {\n readonly chatMessageTemplate = input.required();\n readonly templateRef = inject(TemplateRef);\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-message/chat-message.component.ts#ChatMessageComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-message/chat-message.component.ts", + "symbol": "ChatMessageComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-message',\n standalone: true,\n imports: [ChatCitationsComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_MESSAGE_STYLES],\n providers: [CitationsResolverService],\n host: {\n '[attr.data-role]': 'role()',\n '[attr.data-current]': 'currentStr()',\n '[attr.data-streaming]': 'streamingStr()',\n '[attr.data-prev-role]': 'prevRole() ?? null',\n },\n template: `\n
    \n \n \n
    \n @if (message()?.role === 'assistant' && message(); as msg) {\n \n }\n
    \n \n
    \n `,\n})\nexport class ChatMessageComponent {\n readonly role = input.required();\n readonly current = input(false);\n readonly streaming = input(false);\n readonly prevRole = input(undefined);\n readonly message = input(undefined);\n private readonly resolver = inject(CitationsResolverService);\n constructor() {\n effect(() => {\n this.resolver.message.set(this.message() ?? null);\n });\n }\n readonly currentStr = computed(() => String(this.current()));\n readonly streamingStr = computed(() => String(this.streaming()));\n readonly bodyClass = computed(() => {\n switch (this.role()) {\n case 'user': return 'chat-message__bubble';\n case 'assistant': return 'chat-message__assistant-body';\n default: return 'chat-message__plain';\n }\n });\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-overflow-menu/chat-overflow-menu.component.ts#ChatOverflowMenuComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-overflow-menu/chat-overflow-menu.component.ts", + "symbol": "ChatOverflowMenuComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-overflow-menu',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_OVERFLOW_MENU_STYLES],\n template: `\n @if (open()) {\n \n \n @for (item of items(); track item.id) {\n \n {{ item.label }}\n \n }\n \n }\n `,\n})\nexport class ChatOverflowMenuComponent {\n readonly open = input(false);\n readonly items = input([]);\n readonly anchor = input(null);\n readonly anchorPos = input<{\n x: number;\n y: number;\n } | null>(null);\n readonly itemSelected = output();\n readonly closed = output();\n protected readonly position = computed<{\n top: number;\n left: number;\n }>(() => {\n if (!this.open())\n return { top: 0, left: 0 };\n const pos = this.anchorPos();\n if (pos) {\n return { top: pos.y + 4, left: Math.max(pos.x, 8) };\n }\n const el = this.anchor();\n if (!el) {\n const vw = typeof window === 'undefined' ? 0 : window.innerWidth;\n const vh = typeof window === 'undefined' ? 0 : window.innerHeight;\n return { top: Math.max(vh / 3, 0), left: Math.max(vw / 2 - 80, 0) };\n }\n const rect = el.getBoundingClientRect();\n return { top: rect.bottom + 4, left: Math.max(rect.right - 160, 8) };\n });\n constructor() {\n effect(() => {\n if (!this.open())\n return;\n queueMicrotask(() => {\n const root = document.querySelector('.chat-overflow-menu');\n const first = root?.querySelector('.chat-overflow-menu__item:not(.chat-overflow-menu__item--disabled)');\n first?.focus();\n });\n });\n }\n protected onItemClick(item: OverflowMenuItem): void {\n if (item.disabled)\n return;\n this.itemSelected.emit(item.id);\n this.closed.emit();\n }\n protected onMenuKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.closed.emit();\n return;\n }\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n const root = (e.currentTarget as HTMLElement);\n const items = Array.from(root.querySelectorAll('.chat-overflow-menu__item:not(.chat-overflow-menu__item--disabled)'));\n if (items.length === 0)\n return;\n const current = document.activeElement as HTMLElement | null;\n const idx = current ? items.indexOf(current) : -1;\n const next = e.key === 'ArrowDown'\n ? Math.min((idx < 0 ? 0 : idx + 1), items.length - 1)\n : Math.max(idx - 1, 0);\n items[next]?.focus();\n }\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-project-list/chat-project-list.component.ts#ChatProjectListComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-project-list/chat-project-list.component.ts", + "symbol": "ChatProjectListComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-project-list',\n standalone: true,\n imports: [ChatOverflowMenuComponent, ChatConfirmDialogComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_PROJECT_LIST_STYLES],\n template: `\n @if (showNewProjectButton()) {\n \n }\n
      \n @if (creatingProject()) {\n
    • \n \n
    • \n }\n @for (project of visibleProjects(); track project.id) {\n
    • \n @if (editingProjectId() === project.id) {\n \n } @else {\n {{ project.name }}\n\n @if (showKebab()) {\n ⋯\n }\n }\n
    • \n }\n
    \n\n \n\n \n `,\n})\nexport class ChatProjectListComponent {\n readonly projects = input.required();\n readonly activeProjectId = input(null);\n readonly showNewProjectButton = input(false);\n readonly actions = input(null);\n readonly projectSelected = output();\n readonly newProjectRequested = output();\n protected readonly creatingProject = signal(false);\n protected readonly creatingValue = signal('');\n protected readonly editingProjectId = signal(null);\n protected readonly editingValue = signal('');\n protected readonly menuOpenForId = signal(null);\n protected readonly menuAnchor = signal(null);\n protected readonly confirmDeleteId = signal(null);\n private readonly pendingHidden = signal>(new Set());\n private readonly pendingRenames = signal>(new Map());\n protected readonly visibleProjects = computed(() => {\n const hidden = this.pendingHidden();\n const renames = this.pendingRenames();\n return this.projects()\n .filter((p) => !hidden.has(p.id))\n .map((p) => (renames.has(p.id) ? ({ ...p, name: renames.get(p.id)! }) : p));\n });\n protected readonly currentMenuItems = computed(() => {\n const id = this.menuOpenForId();\n if (!id)\n return [];\n const a = this.actions();\n if (!a)\n return [];\n const items: OverflowMenuItem[] = [];\n if (a.rename)\n items.push({ id: 'rename', label: 'Rename' });\n if (a.delete)\n items.push({ id: 'delete', label: 'Delete', tone: 'destructive' });\n return items;\n });\n private readonly createInput = viewChild>('createInput');\n private readonly editInput = viewChild>('editInput');\n constructor() {\n effect(() => {\n if (this.creatingProject()) {\n queueMicrotask(() => this.createInput()?.nativeElement.focus());\n }\n });\n }\n protected selectProject(projectId: string): void {\n this.projectSelected.emit(projectId);\n }\n protected showKebab(): boolean {\n const a = this.actions();\n if (!a)\n return false;\n return Boolean(a.rename || a.delete);\n }\n protected openMenu(projectId: string, anchor: HTMLElement): void {\n this.menuAnchor.set(anchor);\n this.menuOpenForId.set(projectId);\n }\n protected onMenuAction(id: string): void {\n const projectId = this.menuOpenForId();\n this.menuOpenForId.set(null);\n if (!projectId)\n return;\n if (id === 'rename') {\n const p = this.projects().find((x) => x.id === projectId);\n this.editingValue.set(p?.name ?? '');\n this.editingProjectId.set(projectId);\n queueMicrotask(() => this.editInput()?.nativeElement.focus());\n }\n else if (id === 'delete') {\n this.confirmDeleteId.set(projectId);\n }\n }\n protected onNewProjectClicked(): void {\n this.creatingValue.set('');\n this.creatingProject.set(true);\n this.newProjectRequested.emit();\n }\n protected onCreateInput(e: Event): void {\n this.creatingValue.set((e.target as HTMLInputElement).value);\n }\n protected cancelCreate(): void {\n this.creatingProject.set(false);\n this.creatingValue.set('');\n }\n protected async commitCreate(): Promise {\n const name = this.creatingValue().trim();\n this.creatingProject.set(false);\n this.creatingValue.set('');\n if (!name)\n return;\n const a = this.actions();\n if (!a?.create)\n return;\n try {\n await a.create(name);\n }\n catch { }\n }\n protected onEditInput(e: Event): void {\n this.editingValue.set((e.target as HTMLInputElement).value);\n }\n protected cancelRename(): void {\n this.editingProjectId.set(null);\n }\n protected async commitRename(projectId: string): Promise {\n const newName = this.editingValue().trim();\n this.editingProjectId.set(null);\n if (!newName)\n return;\n const a = this.actions();\n if (!a?.rename)\n return;\n this.pendingRenames.update((m) => {\n const n = new Map(m);\n n.set(projectId, newName);\n return n;\n });\n try {\n await a.rename(projectId, newName);\n }\n catch {\n }\n finally {\n this.pendingRenames.update((m) => {\n const n = new Map(m);\n n.delete(projectId);\n return n;\n });\n }\n }\n protected async performDelete(): Promise {\n const projectId = this.confirmDeleteId();\n this.confirmDeleteId.set(null);\n if (!projectId)\n return;\n const a = this.actions();\n if (!a?.delete)\n return;\n this.pendingHidden.update((s) => new Set([...s, projectId]));\n try {\n await a.delete(projectId);\n }\n catch {\n }\n finally {\n this.pendingHidden.update((s) => {\n const n = new Set(s);\n n.delete(projectId);\n return n;\n });\n }\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-reasoning/chat-reasoning.component.ts#ChatReasoningComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-reasoning/chat-reasoning.component.ts", + "symbol": "ChatReasoningComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-reasoning',\n standalone: true,\n imports: [ChatStreamingMdComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_REASONING_STYLES],\n host: {\n '[attr.data-has-content]': 'hasContent()',\n '[attr.data-expanded]': 'expandedStr()',\n '[attr.data-streaming]': 'isStreaming()',\n },\n template: `\n \n \n \n \n @if (isStreaming()) {\n \n }\n {{ resolvedLabel() }}\n \n @if (expanded()) {\n
    \n \n
    \n }\n `,\n})\nexport class ChatReasoningComponent {\n readonly content = input('');\n readonly delivery = input.required();\n readonly durationMs = input(undefined);\n readonly label = input(undefined);\n readonly defaultExpanded = input(false);\n readonly hasContent = computed(() => (this.content() ?? '').length > 0);\n readonly isStreaming = computed(() => this.delivery().phase === 'streaming');\n readonly document = computed(() => markdownDocument(this.content(), this.delivery(), ':reasoning'));\n private readonly _expandedOverride = signal(null);\n readonly expanded = computed(() => {\n const override = this._expandedOverride();\n if (override !== null)\n return override;\n if (this.isStreaming())\n return true;\n return this.defaultExpanded();\n });\n readonly expandedStr = computed(() => String(this.expanded()));\n readonly resolvedLabel = computed(() => {\n const explicit = this.label();\n if (explicit)\n return explicit;\n if (this.isStreaming())\n return 'Thinking…';\n const ms = this.durationMs();\n if (typeof ms === 'number')\n return `Thought for ${formatDuration(ms)}`;\n return 'Show reasoning';\n });\n constructor() {\n let prevStreaming = false;\n effect(() => {\n const streaming = this.isStreaming();\n if (!prevStreaming && streaming) {\n this._expandedOverride.set(null);\n }\n prevStreaming = streaming;\n });\n }\n toggle(): void {\n this._expandedOverride.set(!this.expanded());\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-scroll-bubble/chat-scroll-bubble.component.ts#ChatScrollBubbleComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-scroll-bubble/chat-scroll-bubble.component.ts", + "symbol": "ChatScrollBubbleComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-scroll-bubble',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_SCROLL_BUBBLE_STYLES],\n template: `\n \n @if (mode() === 'streaming') {\n \n \n \n \n \n } @else {\n \n \n \n \n }\n \n `,\n})\nexport class ChatScrollBubbleComponent {\n readonly mode = input.required();\n readonly clicked = output();\n protected readonly ariaLabel = computed(() => this.mode() === 'streaming' ? 'Latest activity' : 'Scroll to latest');\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-select/chat-select.component.ts#ChatSelectComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-select/chat-select.component.ts", + "symbol": "ChatSelectComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-select',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [ChatConnectedOverlayDirective, ChatOverlayOriginDirective],\n styles: [CHAT_HOST_TOKENS, CHAT_SELECT_STYLES],\n template: `\n \n {{ currentLabel() }}\n \n \n \n \n \n \n @for (opt of options(); track opt.value) {\n \n {{ opt.label }}\n @if (opt.description) {\n {{ opt.description }}\n }\n \n }\n \n \n `,\n})\nexport class ChatSelectComponent {\n readonly options = input.required();\n readonly value = model('');\n readonly placeholder = input('Select');\n readonly disabled = input(false);\n readonly menuLabel = input(undefined);\n readonly panelClass = input('');\n protected readonly open = signal(false);\n protected readonly menuId = `chat-select-menu-${nextChatSelectId++}`;\n protected readonly overlayPositions: ConnectedPosition[] = [\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -8 },\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 8 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -8 },\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 8 },\n ];\n protected readonly panelClasses = computed(() => {\n const extra = this.panelClass();\n const list = Array.isArray(extra) ? extra : extra ? [extra] : [];\n return ['chat-select__overlay', ...list];\n });\n protected readonly currentLabel = computed(() => {\n const v = this.value();\n return this.options().find((o) => o.value === v)?.label ?? this.placeholder();\n });\n private readonly hostEl = inject(ElementRef).nativeElement as HTMLElement;\n private readonly document = inject(DOCUMENT);\n private menuPane: HTMLElement | null = null;\n protected onAttached(pane: HTMLElement): void {\n this.menuPane = pane;\n this.focusOption(0);\n }\n protected toggle(): void {\n if (this.disabled())\n return;\n this.open.update((v) => !v);\n }\n protected selectOption(opt: ChatSelectOption): void {\n if (opt.disabled)\n return;\n this.value.set(opt.value);\n this.open.set(false);\n }\n protected onTriggerKeydown(e: KeyboardEvent): void {\n if (this.disabled())\n return;\n if (e.key === 'Escape' && this.open()) {\n e.preventDefault();\n this.open.set(false);\n return;\n }\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {\n e.preventDefault();\n this.open.set(true);\n }\n }\n protected onMenuKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.open.set(false);\n this.queryTrigger()?.focus();\n return;\n }\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n this.moveFocus(e.key === 'ArrowDown' ? 1 : -1);\n return;\n }\n if (e.key === 'Enter' || e.key === ' ') {\n const t = e.target as HTMLElement;\n if (t.classList.contains('chat-select__option')) {\n e.preventDefault();\n (t as HTMLButtonElement).click();\n }\n }\n }\n private focusOption(index: number): void {\n this.queryOptions()[index]?.focus();\n }\n private moveFocus(dir: 1 | -1): void {\n const opts = this.queryOptions().filter((b) => !b.disabled);\n if (!opts.length)\n return;\n const active = this.document.activeElement as HTMLElement | null;\n const idx = active ? opts.indexOf(active as HTMLButtonElement) : -1;\n opts[(idx + dir + opts.length) % opts.length]?.focus();\n }\n private queryOptions(): HTMLButtonElement[] {\n const root = this.menuPane;\n return root ? Array.from(root.querySelectorAll('.chat-select__option')) : [];\n }\n private queryTrigger(): HTMLButtonElement | null {\n return this.hostEl.querySelector('.chat-select__trigger');\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-sidenav-scrim/chat-sidenav-scrim.component.ts#ChatSidenavScrimComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-sidenav-scrim/chat-sidenav-scrim.component.ts", + "symbol": "ChatSidenavScrimComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-sidenav-scrim',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (open()) {\n \n }\n `,\n styles: [\n `\n :host { display: contents; }\n .chat-sidenav-scrim__button {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: var(--tplane-chat-z-drawer-scrim, 1000);\n border: 0;\n padding: 0;\n cursor: pointer;\n }\n `,\n ],\n})\nexport class ChatSidenavScrimComponent {\n readonly open = input(false);\n readonly dismiss = output();\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-subagents/chat-subagents.component.ts#ChatSubagentsComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-subagents/chat-subagents.component.ts", + "symbol": "ChatSubagentsComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-subagents',\n standalone: true,\n imports: [NgTemplateOutlet, ChatSubagentCardComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @for (subagent of activeSubagents(); track subagent.toolCallId) {\n @if (templateRef()) {\n \n } @else {\n \n }\n }\n `,\n})\nexport class ChatSubagentsComponent {\n readonly agent = input.required();\n readonly templateRef = contentChild(TemplateRef);\n readonly activeSubagents = computed(() => activeSubagentsFromAgent(this.agent()));\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-suggestions/chat-suggestions.component.ts#ChatSuggestionsComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-suggestions/chat-suggestions.component.ts", + "symbol": "ChatSuggestionsComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-suggestions',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_SUGGESTIONS_STYLES],\n template: `\n
    \n @for (s of suggestions(); track s) {\n \n }\n
    \n `,\n})\nexport class ChatSuggestionsComponent {\n readonly suggestions = input([]);\n readonly selected = output();\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-thread-list/chat-thread-list.component.ts#ChatThreadListComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-thread-list/chat-thread-list.component.ts", + "symbol": "ChatThreadListComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-thread-list',\n standalone: true,\n imports: [NgTemplateOutlet, ChatOverflowMenuComponent, ChatConfirmDialogComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_THREAD_LIST_STYLES],\n template: `\n @if (showNewThreadButton()) {\n \n }\n
      \n @for (thread of visibleThreads(); track thread.id) {\n \n @if (templateRef()) {\n \n } @else if (editingThreadId() === thread.id) {\n \n } @else {\n \n {{ initialOf(threadLabel(thread)) }}\n \n @if (thread.pinned) {\n \n \n \n \n @if (actions()?.reorderPinned) {\n ⋮⋮\n }\n \n }\n {{ threadLabel(thread) }}\n \n @if (thread.updatedAt !== undefined) {\n {{ relativeTime(thread.updatedAt) }}\n }\n \n\n @if (showKebab()) {\n ⋯\n }\n }\n \n }\n
    \n\n \n\n \n\n \n `,\n})\nexport class ChatThreadListComponent {\n readonly threads = input.required();\n readonly activeThreadId = input('');\n readonly showNewThreadButton = input(false);\n readonly actions = input(null);\n readonly mode = input<'active' | 'archived'>('active');\n readonly projects = input(null);\n readonly threadSelected = output();\n readonly newThreadRequested = output();\n readonly templateRef = contentChild(TemplateRef);\n protected readonly editingThreadId = signal(null);\n protected readonly editingValue = signal('');\n protected readonly menuOpenForId = signal(null);\n protected readonly menuAnchor = signal(null);\n protected readonly menuAnchorPos = signal<{\n x: number;\n y: number;\n } | null>(null);\n protected readonly confirmDeleteId = signal(null);\n protected readonly moveMenuOpenForId = signal(null);\n protected readonly moveMenuItems = computed(() => {\n if (!this.moveMenuOpenForId())\n return [];\n const list: OverflowMenuItem[] = [{ id: '__none__', label: 'No project' }];\n for (const p of this.projects() ?? []) {\n list.push({ id: p.id, label: p.name });\n }\n return list;\n });\n private readonly pendingHidden = signal>(new Set());\n private readonly pendingRenames = signal>(new Map());\n private readonly pendingOrder = signal>(new Map());\n protected readonly draggingThreadId = signal(null);\n protected readonly dropTarget = signal<{\n threadId: string;\n position: 'before' | 'after';\n } | null>(null);\n protected readonly visibleThreads = computed(() => {\n const hidden = this.pendingHidden();\n const renames = this.pendingRenames();\n const pending = this.pendingOrder();\n let result = this.threads()\n .filter((t) => !hidden.has(t.id))\n .map((t) => (renames.has(t.id) ? ({ ...t, title: renames.get(t.id) }) : t));\n if (pending.size > 0) {\n const pinned = result.filter((t) => t.pinned === true);\n const unpinned = result.filter((t) => t.pinned !== true);\n for (const [threadId, beforeId] of pending) {\n const idx = pinned.findIndex((t) => t.id === threadId);\n if (idx < 0)\n continue;\n const [moved] = pinned.splice(idx, 1);\n if (beforeId === null) {\n pinned.push(moved);\n }\n else {\n const beforeIdx = pinned.findIndex((t) => t.id === beforeId);\n if (beforeIdx < 0)\n pinned.push(moved);\n else\n pinned.splice(beforeIdx, 0, moved);\n }\n }\n result = [...pinned, ...unpinned];\n }\n return result;\n });\n protected readonly currentMenuItems = computed(() => {\n const id = this.menuOpenForId();\n if (!id)\n return [];\n const a = this.actions();\n if (!a)\n return [];\n const items: OverflowMenuItem[] = [];\n if (this.mode() === 'active') {\n const thread = this.threads().find((t) => t.id === id);\n const isPinned = thread?.pinned === true;\n if (a.rename)\n items.push({ id: 'rename', label: 'Rename' });\n if (a.pin && !isPinned)\n items.push({ id: 'pin', label: 'Pin' });\n if (a.unpin && isPinned)\n items.push({ id: 'unpin', label: 'Unpin' });\n if (isPinned && a.reorderPinned) {\n const pinned = this.threads().filter((t) => t.pinned === true);\n const pinnedIdx = pinned.findIndex((t) => t.id === id);\n if (pinnedIdx > 0)\n items.push({ id: 'move-up', label: 'Move up' });\n if (pinnedIdx >= 0 && pinnedIdx < pinned.length - 1)\n items.push({ id: 'move-down', label: 'Move down' });\n }\n if (a.moveToProject && this.projects() !== null) {\n items.push({ id: 'move', label: 'Move to project' });\n }\n if (a.archive)\n items.push({ id: 'archive', label: 'Archive' });\n if (a.delete)\n items.push({ id: 'delete', label: 'Delete', tone: 'destructive' });\n }\n else {\n if (a.unarchive)\n items.push({ id: 'unarchive', label: 'Unarchive' });\n if (a.delete)\n items.push({ id: 'delete', label: 'Delete', tone: 'destructive' });\n }\n return items;\n });\n private readonly editInput = viewChild>('editInput');\n selectThread(threadId: string): void {\n this.threadSelected.emit(threadId);\n }\n protected threadLabel(thread: Thread): string {\n const title = thread['title'];\n if (typeof title === 'string' && title.length > 0)\n return title;\n return thread.id;\n }\n protected relativeTime(epochMs: number): string {\n const delta = Date.now() - epochMs;\n if (delta < 60000)\n return 'just now';\n if (delta < 3600000)\n return `${Math.floor(delta / 60000)} min ago`;\n if (delta < 86400000)\n return `${Math.floor(delta / 3600000)} hr ago`;\n return `${Math.floor(delta / 86400000)} day ago`;\n }\n protected showKebab(): boolean {\n const a = this.actions();\n if (!a)\n return false;\n if (this.mode() === 'active') {\n return Boolean(a.rename || a.pin || a.unpin || a.archive || a.delete ||\n a.reorderPinned ||\n (a.moveToProject && this.projects() !== null));\n }\n return Boolean(a.unarchive || a.delete);\n }\n protected openMenu(threadId: string, anchor: HTMLElement): void {\n this.menuAnchor.set(anchor);\n this.menuAnchorPos.set(null);\n this.menuOpenForId.set(threadId);\n }\n protected onRowContextMenu(threadId: string, event: MouseEvent): void {\n event.preventDefault();\n if (!this.showKebab())\n return;\n if (this.editingThreadId() !== null)\n return;\n this.menuAnchor.set(null);\n this.menuAnchorPos.set({ x: event.clientX, y: event.clientY });\n this.menuOpenForId.set(threadId);\n }\n protected initialOf(title: string): string {\n const trimmed = (title ?? '').trim();\n if (!trimmed)\n return '?';\n const first = Array.from(trimmed)[0];\n return first.toUpperCase ? first.toUpperCase() : first;\n }\n protected onMenuAction(id: string): void {\n const threadId = this.menuOpenForId();\n this.menuOpenForId.set(null);\n if (!threadId)\n return;\n if (id === 'rename') {\n const t = this.threads().find((x) => x.id === threadId);\n this.editingValue.set(typeof t?.title === 'string' ? t.title : '');\n this.editingThreadId.set(threadId);\n queueMicrotask(() => this.editInput()?.nativeElement.focus());\n }\n else if (id === 'delete') {\n this.confirmDeleteId.set(threadId);\n }\n else if (id === 'archive') {\n void this.performArchive(threadId);\n }\n else if (id === 'unarchive') {\n void this.performUnarchive(threadId);\n }\n else if (id === 'pin') {\n void this.performPin(threadId);\n }\n else if (id === 'unpin') {\n void this.performUnpin(threadId);\n }\n else if (id === 'move') {\n this.moveMenuOpenForId.set(threadId);\n }\n else if (id === 'move-up') {\n void this.performMoveUp(threadId);\n }\n else if (id === 'move-down') {\n void this.performMoveDown(threadId);\n }\n }\n protected async performPin(threadId: string): Promise {\n const a = this.actions();\n if (!a?.pin)\n return;\n try {\n await a.pin(threadId);\n }\n catch { }\n }\n protected async performUnpin(threadId: string): Promise {\n const a = this.actions();\n if (!a?.unpin)\n return;\n try {\n await a.unpin(threadId);\n }\n catch { }\n }\n protected onEditInput(e: Event): void {\n this.editingValue.set((e.target as HTMLInputElement).value);\n }\n protected cancelRename(): void {\n this.editingThreadId.set(null);\n }\n protected async commitRename(threadId: string): Promise {\n const newTitle = this.editingValue().trim();\n this.editingThreadId.set(null);\n if (!newTitle)\n return;\n const a = this.actions();\n if (!a?.rename)\n return;\n this.pendingRenames.update((m) => {\n const n = new Map(m);\n n.set(threadId, newTitle);\n return n;\n });\n try {\n await a.rename(threadId, newTitle);\n }\n catch {\n }\n finally {\n this.pendingRenames.update((m) => {\n const n = new Map(m);\n n.delete(threadId);\n return n;\n });\n }\n }\n protected async performDelete(): Promise {\n const threadId = this.confirmDeleteId();\n this.confirmDeleteId.set(null);\n if (!threadId)\n return;\n const a = this.actions();\n if (!a?.delete)\n return;\n this.pendingHidden.update((s) => new Set([...s, threadId]));\n try {\n await a.delete(threadId);\n }\n catch {\n }\n finally {\n this.pendingHidden.update((s) => {\n const n = new Set(s);\n n.delete(threadId);\n return n;\n });\n }\n }\n protected async performArchive(threadId: string): Promise {\n const a = this.actions();\n if (!a?.archive)\n return;\n this.pendingHidden.update((s) => new Set([...s, threadId]));\n try {\n await a.archive(threadId);\n }\n catch {\n }\n finally {\n this.pendingHidden.update((s) => {\n const n = new Set(s);\n n.delete(threadId);\n return n;\n });\n }\n }\n protected onMoveMenuAction(itemId: string): void {\n const threadId = this.moveMenuOpenForId();\n this.moveMenuOpenForId.set(null);\n if (!threadId)\n return;\n const projectId = itemId === '__none__' ? null : itemId;\n void this.performMoveToProject(threadId, projectId);\n }\n protected async performMoveToProject(threadId: string, projectId: string | null): Promise {\n const a = this.actions();\n if (!a?.moveToProject)\n return;\n this.pendingHidden.update((s) => new Set([...s, threadId]));\n try {\n await a.moveToProject(threadId, projectId);\n }\n catch {\n }\n finally {\n this.pendingHidden.update((s) => {\n const n = new Set(s);\n n.delete(threadId);\n return n;\n });\n }\n }\n protected async performReorderPinned(threadId: string, beforeId: string | null): Promise {\n const a = this.actions();\n if (!a?.reorderPinned)\n return;\n this.pendingOrder.update((m) => {\n const n = new Map(m);\n n.set(threadId, beforeId);\n return n;\n });\n try {\n await a.reorderPinned(threadId, beforeId);\n }\n catch {\n }\n finally {\n this.pendingOrder.update((m) => {\n const n = new Map(m);\n n.delete(threadId);\n return n;\n });\n }\n }\n protected async performMoveUp(threadId: string): Promise {\n const pinned = this.threads().filter((t) => t.pinned === true);\n const idx = pinned.findIndex((t) => t.id === threadId);\n if (idx <= 0)\n return;\n const beforeId = pinned[idx - 1].id;\n await this.performReorderPinned(threadId, beforeId);\n }\n protected async performMoveDown(threadId: string): Promise {\n const pinned = this.threads().filter((t) => t.pinned === true);\n const idx = pinned.findIndex((t) => t.id === threadId);\n if (idx < 0 || idx >= pinned.length - 1)\n return;\n const beforeId = idx + 2 < pinned.length ? pinned[idx + 2].id : null;\n await this.performReorderPinned(threadId, beforeId);\n }\n protected onDragStart(e: DragEvent, threadId: string): void {\n const dt = e.dataTransfer;\n if (!dt)\n return;\n dt.setData('text/plain', threadId);\n dt.effectAllowed = 'move';\n this.draggingThreadId.set(threadId);\n }\n protected onDragOver(e: DragEvent, threadId: string): void {\n const dragging = this.draggingThreadId();\n if (!dragging || dragging === threadId)\n return;\n const target = this.threads().find((t) => t.id === threadId);\n if (target?.pinned !== true)\n return;\n e.preventDefault();\n if (e.dataTransfer)\n e.dataTransfer.dropEffect = 'move';\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const offsetY = e.clientY - rect.top;\n const position: 'before' | 'after' = offsetY < rect.height / 2 ? 'before' : 'after';\n const cur = this.dropTarget();\n if (!cur || cur.threadId !== threadId || cur.position !== position) {\n this.dropTarget.set({ threadId, position });\n }\n }\n protected onDragLeave(_e: DragEvent, threadId: string): void {\n if (this.dropTarget()?.threadId === threadId) {\n this.dropTarget.set(null);\n }\n }\n protected onDrop(e: DragEvent, targetThreadId: string): void {\n e.preventDefault();\n const dragId = e.dataTransfer?.getData('text/plain') ?? this.draggingThreadId();\n const target = this.dropTarget();\n this.draggingThreadId.set(null);\n this.dropTarget.set(null);\n if (!dragId || dragId === targetThreadId || !target)\n return;\n const pinned = this.threads().filter((t) => t.pinned === true);\n const targetIdx = pinned.findIndex((t) => t.id === targetThreadId);\n if (targetIdx < 0)\n return;\n let beforeId: string | null;\n if (target.position === 'before') {\n beforeId = targetThreadId;\n }\n else {\n const filteredPinned = pinned.filter((t) => t.id !== dragId);\n const filteredTargetIdx = filteredPinned.findIndex((t) => t.id === targetThreadId);\n beforeId = filteredTargetIdx + 1 < filteredPinned.length\n ? filteredPinned[filteredTargetIdx + 1].id\n : null;\n }\n void this.performReorderPinned(dragId, beforeId);\n }\n protected onDragEnd(): void {\n this.draggingThreadId.set(null);\n this.dropTarget.set(null);\n }\n protected dropPositionFor(threadId: string): 'before' | 'after' | null {\n const t = this.dropTarget();\n return t?.threadId === threadId ? t.position : null;\n }\n protected async performUnarchive(threadId: string): Promise {\n const a = this.actions();\n if (!a?.unarchive)\n return;\n this.pendingHidden.update((s) => new Set([...s, threadId]));\n try {\n await a.unarchive(threadId);\n }\n catch {\n }\n finally {\n this.pendingHidden.update((s) => {\n const n = new Set(s);\n n.delete(threadId);\n return n;\n });\n }\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-timeline/chat-timeline.component.ts#ChatTimelineComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-timeline/chat-timeline.component.ts", + "symbol": "ChatTimelineComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-timeline',\n standalone: true,\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @for (cp of history(); track $index) {\n @if (templateRef()) {\n \n }\n }\n `,\n})\nexport class ChatTimelineComponent {\n readonly agent = input.required();\n readonly checkpointSelected = output();\n readonly templateRef = contentChild(TemplateRef);\n readonly history = computed(() => this.agent().history());\n selectCheckpoint(cp: AgentCheckpoint): void {\n this.checkpointSelected.emit(cp);\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-call-template.directive.ts#ChatToolCallTemplateDirective", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-call-template.directive.ts", + "symbol": "ChatToolCallTemplateDirective", + "decorators": [ + "Directive" + ], + "signature": "@Directive({\n selector: '[chatToolCallTemplate]',\n standalone: true,\n})\nexport class ChatToolCallTemplateDirective {\n readonly name = input.required({ alias: 'chatToolCallTemplate' });\n readonly templateRef = inject(TemplateRef);\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-calls.component.ts#ChatToolCallsComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-calls.component.ts", + "symbol": "ChatToolCallsComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-tool-calls',\n standalone: true,\n imports: [NgTemplateOutlet, ChatToolCallCardComponent, ChatSubagentCardComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [`\n :host { display: block; margin-bottom: 20px; }\n .ctc__group {\n border: 1px solid var(--tplane-chat-separator);\n border-radius: var(--tplane-chat-radius-card);\n margin: 0 0 4px;\n }\n .ctc__group-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 8px 12px;\n background: transparent;\n border: 0;\n font: inherit;\n color: var(--tplane-chat-text);\n cursor: pointer;\n text-align: left;\n }\n .ctc__group-chevron {\n width: 10px; height: 10px;\n transition: transform 120ms ease;\n }\n .ctc__group[data-expanded=\"true\"] .ctc__group-chevron { transform: rotate(90deg); }\n .ctc__group-body {\n padding: 0 12px 8px;\n border-top: 1px solid var(--tplane-chat-separator);\n }\n `],\n template: `\n @for (group of groups(); track $index) {\n @if (group.subagent) {\n \n } @else if (group.calls.length > 1 && !group.templateRef) {\n \n @let expanded = expandedGroups().has($index);\n
    \n \n @if (expanded) {\n
    \n @for (tc of group.calls; track tc.id) {\n \n }\n
    \n }\n
    \n } @else if (group.templateRef) {\n @for (tc of group.calls; track tc.id) {\n \n }\n } @else {\n @for (tc of group.calls; track tc.id) {\n \n }\n }\n }\n `,\n})\nexport class ChatToolCallsComponent {\n readonly agent = input.required();\n readonly message = input(undefined);\n readonly grouping = input<'auto' | 'none'>('auto');\n readonly groupSummary = input<((name: string, count: number) => string) | undefined>(undefined);\n readonly excludeToolNames = input([]);\n readonly templates = contentChildren(ChatToolCallTemplateDirective);\n private readonly templateRegistry = computed(() => {\n const map = new Map();\n for (const t of this.templates()) {\n map.set(t.name(), t);\n }\n return map;\n });\n readonly toolCalls = computed((): ToolCall[] => resolveMessageToolCalls(this.agent(), this.message()));\n readonly groups = computed((): Group[] => {\n const excludeSet = new Set(this.excludeToolNames());\n const calls = this.toolCalls().filter(tc => !excludeSet.has(tc.name));\n const rawSubs = this.agent().subagents?.() ?? new Map();\n const subs = new Map();\n rawSubs.forEach((sa) => subs.set(sa.toolCallId, sa));\n const groupingMode = this.grouping();\n const registry = this.templateRegistry();\n const wildcard = registry.get('*');\n const out: Group[] = [];\n for (const tc of calls) {\n if (subs.has(tc.id)) {\n out.push({ name: tc.name, calls: [tc], subagent: subs.get(tc.id) });\n continue;\n }\n const tpl = registry.get(tc.name) ?? wildcard;\n const last = out[out.length - 1];\n const sameName = last && !last.subagent && last.name === tc.name;\n const canGroup = groupingMode === 'auto' && sameName;\n if (canGroup) {\n last.calls.push(tc);\n if (!last.templateRef && tpl)\n last.templateRef = tpl;\n }\n else {\n out.push({ name: tc.name, calls: [tc], templateRef: tpl });\n }\n }\n return out;\n });\n private readonly _expandedGroups = signal(new Set());\n readonly expandedGroups = this._expandedGroups.asReadonly();\n toggleGroup(index: number): void {\n this._expandedGroups.update((prev) => {\n const next = new Set(prev);\n if (next.has(index))\n next.delete(index);\n else\n next.add(index);\n return next;\n });\n }\n protected summarize(name: string, count: number): string {\n return (this.groupSummary() ?? defaultSummarizeGroup)(name, count);\n }\n protected toToolCallInfo(tc: ToolCall): ToolCallInfo {\n return { id: tc.id, name: tc.name, args: tc.args, result: tc.result, status: tc.status };\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-tool-views/chat-tool-views.component.ts#ChatToolViewsComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-tool-views/chat-tool-views.component.ts", + "symbol": "ChatToolViewsComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-tool-views',\n standalone: true,\n imports: [ChatGenerativeUiComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @for (view of toolViews(); track view.id) {\n \n }\n `,\n})\nexport class ChatToolViewsComponent {\n readonly agent = input.required();\n readonly events = output();\n readonly message = input(undefined);\n readonly views = input(undefined);\n readonly store = input(undefined);\n readonly handlers = input) => unknown | Promise>>({});\n readonly registry = computed(() => {\n const v = this.views();\n return v ? toRenderRegistry(v) : undefined;\n });\n readonly toolViews = computed(() => {\n const v = this.views();\n if (!v)\n return [];\n const names = new Set(Object.keys(v));\n return resolveMessageToolCalls(this.agent(), this.message())\n .filter((tc) => names.has(tc.name))\n .map((tc) => ({ id: tc.id, loading: tc.status === 'running', spec: toToolViewSpec(tc) }));\n });\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-trace/chat-trace.component.ts#ChatTraceComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-trace/chat-trace.component.ts", + "symbol": "ChatTraceComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-trace',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_TRACE_STYLES],\n host: {\n '[attr.data-state]': 'state()',\n '[attr.data-expanded]': 'expandedStr()',\n },\n template: `\n \n \n \n \n \n \n \n \n \n \n @if (expanded()) {\n
    \n }\n `,\n})\nexport class ChatTraceComponent {\n readonly state = input('pending');\n readonly defaultExpanded = input(false);\n private readonly _expandedOverride = signal(null);\n readonly expanded = computed(() => {\n const override = this._expandedOverride();\n if (override !== null)\n return override;\n const s = this.state();\n if (s === 'running' || s === 'error')\n return true;\n return this.defaultExpanded();\n });\n readonly expandedStr = computed(() => String(this.expanded()));\n constructor() {\n let prevState: TraceState | undefined;\n effect(() => {\n const s = this.state();\n if ((s === 'running' || s === 'error') && prevState && prevState !== s) {\n this._expandedOverride.set(null);\n }\n prevState = s;\n });\n }\n toggle(): void {\n this._expandedOverride.set(!this.expanded());\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-typing-indicator/chat-typing-indicator.component.ts#ChatTypingIndicatorComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-typing-indicator/chat-typing-indicator.component.ts", + "symbol": "ChatTypingIndicatorComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-typing-indicator',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_TYPING_INDICATOR_STYLES],\n template: `\n @if (visible()) {\n
    \n \n \n \n
    \n }\n `,\n})\nexport class ChatTypingIndicatorComponent {\n readonly agent = input.required();\n readonly visible = computed(() => isTyping(this.agent()));\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-welcome/chat-welcome-suggestion.component.ts#ChatWelcomeSuggestionComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-welcome/chat-welcome-suggestion.component.ts", + "symbol": "ChatWelcomeSuggestionComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-welcome-suggestion',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_WELCOME_SUGGESTION_STYLES],\n template: `\n \n \n {{ label() }}\n \n \n `,\n})\nexport class ChatWelcomeSuggestionComponent {\n readonly label = input.required();\n readonly value = input.required();\n readonly description = input();\n readonly selected = output();\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-welcome/chat-welcome.component.ts#ChatWelcomeComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-welcome/chat-welcome.component.ts", + "symbol": "ChatWelcomeComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-welcome',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_WELCOME_STYLES],\n template: `\n
    \n \n \n

    How can I help?

    \n
    \n
    \n
    \n \n
    \n
    \n `,\n})\nexport class ChatWelcomeComponent {\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-window/chat-window.component.ts#ChatWindowComponent", + "kind": "component", + "path": "libs/chat/src/lib/primitives/chat-window/chat-window.component.ts", + "symbol": "ChatWindowComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-window',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_WINDOW_STYLES],\n template: `\n
    \n
    \n
    \n
    \n \n
    \n `,\n})\nexport class ChatWindowComponent {\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts#ChatConnectedOverlayDirective", + "kind": "component", + "path": "libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts", + "symbol": "ChatConnectedOverlayDirective", + "decorators": [ + "Directive" + ], + "signature": "@Directive({\n selector: '[chatConnectedOverlay]',\n standalone: true,\n})\nexport class ChatConnectedOverlayDirective {\n readonly origin = input.required({ alias: 'chatOverlayOrigin' });\n readonly open = input(false, { alias: 'chatOverlayOpen' });\n readonly positions = input([], { alias: 'chatOverlayPositions' });\n readonly panelClass = input('', { alias: 'chatOverlayPanelClass' });\n readonly attached = output({ alias: 'chatOverlayAttached' });\n readonly outsideClick = output({ alias: 'chatOverlayOutsideClick' });\n readonly detached = output({ alias: 'chatOverlayDetach' });\n private readonly templateRef = inject(TemplateRef);\n private readonly viewContainerRef = inject(ViewContainerRef);\n private readonly document = inject(DOCUMENT);\n private pane: HTMLElement | null = null;\n private viewRef: EmbeddedViewRef | null = null;\n private resizeObs: ResizeObserver | null = null;\n private rafId = 0;\n private previouslyFocused: HTMLElement | null = null;\n private readonly onScrollOrResize = () => this.scheduleReposition();\n private readonly onDocMouseDown = (e: MouseEvent) => {\n if (!this.pane)\n return;\n const path = e.composedPath();\n if (path.includes(this.pane) || path.includes(this.origin().elementRef.nativeElement))\n return;\n this.outsideClick.emit(e);\n };\n private readonly onKeydown = (e: KeyboardEvent) => {\n if (e.key !== 'Tab' || !this.pane)\n return;\n const active = this.document.activeElement;\n if (this.pane.contains(active) || active === this.origin().elementRef.nativeElement) {\n this.detached.emit();\n }\n };\n constructor() {\n effect(() => {\n if (this.open())\n this.attach();\n else\n this.dispose();\n });\n inject(DestroyRef).onDestroy(() => this.dispose());\n }\n private attach(): void {\n if (this.pane)\n return;\n const win = this.document.defaultView;\n if (!win)\n return;\n this.previouslyFocused = this.document.activeElement as HTMLElement | null;\n const pane = this.document.createElement('div');\n pane.className = 'chat-overlay-pane';\n for (const c of this.normalizePanelClass())\n pane.classList.add(c);\n getOverlayContainer(this.document).appendChild(pane);\n this.viewRef = this.viewContainerRef.createEmbeddedView(this.templateRef);\n this.viewRef.detectChanges();\n for (const node of this.viewRef.rootNodes)\n pane.appendChild(node as Node);\n this.pane = pane;\n this.reposition();\n win.addEventListener('scroll', this.onScrollOrResize, { capture: true, passive: true });\n win.addEventListener('resize', this.onScrollOrResize, { passive: true });\n this.document.addEventListener('mousedown', this.onDocMouseDown, true);\n this.document.addEventListener('keydown', this.onKeydown, true);\n if (typeof win.ResizeObserver === 'function') {\n this.resizeObs = new win.ResizeObserver(() => this.scheduleReposition());\n this.resizeObs.observe(this.origin().elementRef.nativeElement);\n this.resizeObs.observe(pane);\n }\n this.attached.emit(pane);\n }\n private scheduleReposition(): void {\n const win = this.document.defaultView;\n if (!win || !this.pane)\n return;\n if (this.rafId)\n win.cancelAnimationFrame(this.rafId);\n this.rafId = win.requestAnimationFrame(() => this.reposition());\n }\n private reposition(): void {\n const win = this.document.defaultView;\n if (!win || !this.pane)\n return;\n const r = this.pane.getBoundingClientRect();\n const result = computeConnectedPosition({\n originRect: this.origin().elementRef.nativeElement.getBoundingClientRect(),\n overlaySize: { width: r.width, height: r.height },\n viewport: narrowViewport(win, VIEWPORT_MARGIN),\n positions: this.positions(),\n });\n this.pane.style.top = `${Math.round(result.top)}px`;\n this.pane.style.left = `${Math.round(result.left)}px`;\n }\n private dispose(): void {\n const win = this.document.defaultView;\n if (this.rafId && win)\n win.cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n if (win) {\n win.removeEventListener('scroll', this.onScrollOrResize, { capture: true } as EventListenerOptions);\n win.removeEventListener('resize', this.onScrollOrResize);\n }\n this.document.removeEventListener('mousedown', this.onDocMouseDown, true);\n this.document.removeEventListener('keydown', this.onKeydown, true);\n this.resizeObs?.disconnect();\n this.resizeObs = null;\n const focusWasInPane = !!this.pane && this.pane.contains(this.document.activeElement);\n this.viewRef?.destroy();\n this.viewRef = null;\n this.pane?.remove();\n this.pane = null;\n if (focusWasInPane && this.previouslyFocused)\n this.previouslyFocused.focus();\n this.previouslyFocused = null;\n }\n private normalizePanelClass(): string[] {\n const pc = this.panelClass();\n return Array.isArray(pc) ? pc : pc ? [pc] : [];\n }\n}" + }, + { + "id": "component:libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts#ChatOverlayOriginDirective", + "kind": "component", + "path": "libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts", + "symbol": "ChatOverlayOriginDirective", + "decorators": [ + "Directive" + ], + "signature": "@Directive({\n selector: '[chatOverlayOrigin]',\n standalone: true,\n exportAs: 'chatOverlayOrigin',\n})\nexport class ChatOverlayOriginDirective {\n readonly elementRef = inject(ElementRef) as ElementRef;\n}" + }, + { + "id": "component:libs/chat/src/lib/streaming/streaming-markdown.component.ts#ChatStreamingMdComponent", + "kind": "component", + "path": "libs/chat/src/lib/streaming/streaming-markdown.component.ts", + "symbol": "ChatStreamingMdComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'chat-streaming-md',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n styles: CHAT_MARKDOWN_STYLES,\n template: `\n @if (root(); as r) {\n \n }\n `,\n providers: [\n {\n provide: MARKDOWN_VIEW_REGISTRY,\n useFactory: (host: ChatStreamingMdComponent) => host.resolvedRegistry(),\n deps: [ChatStreamingMdComponent],\n },\n ],\n})\nexport class ChatStreamingMdComponent {\n readonly document = input.required();\n readonly viewRegistry = input(undefined);\n private readonly ancestorRegistry = inject(MARKDOWN_VIEW_REGISTRY, { optional: true, skipSelf: true });\n readonly resolvedRegistry = computed(() => this.viewRegistry() ?? this.ancestorRegistry ?? cacheplaneMarkdownViews);\n private readonly resolver = inject(CitationsResolverService, {\n optional: true,\n });\n private readonly violationPolicy = inject(STREAMING_MARKDOWN_CONTRACT_VIOLATION_POLICY);\n private readonly createParser = inject(STREAMING_MARKDOWN_PARSER_FACTORY);\n private parser: PartialMarkdownParser | null = null;\n private prior: StreamingMarkdownDocument | null = null;\n private materializedRoot: MarkdownDocumentNode | null = null;\n readonly root = computed(() => {\n this.process(this.document());\n return this.materializedRoot;\n });\n constructor() {\n effect(() => {\n const root = this.root();\n if (this.resolver) {\n this.resolver.markdownDefs.set(root?.citations ?? new Map());\n }\n });\n }\n private process(supplied: StreamingMarkdownDocument): void {\n const prior = this.prior;\n if (!prior || supplied.generation !== prior.generation) {\n this.replaceFrom(supplied);\n return;\n }\n if (supplied.phase === prior.phase && supplied.content === prior.content) {\n return;\n }\n const violationReason = contractViolationReason(prior, supplied);\n if (violationReason) {\n if (this.violationPolicy === 'throw') {\n throw contractViolation(prior, supplied, violationReason);\n }\n this.replaceFrom(supplied);\n return;\n }\n const parser = this.parser as PartialMarkdownParser;\n const delta = supplied.content.slice(prior.content.length);\n if (delta.length > 0)\n parser.push(delta);\n if (supplied.phase === 'complete')\n parser.finish();\n this.materializedRoot = materialize(parser.root) as MarkdownDocumentNode | null;\n this.prior = { ...supplied };\n }\n private replaceFrom(supplied: StreamingMarkdownDocument): void {\n const parser = this.createParser();\n parser.push(supplied.content);\n if (supplied.phase === 'complete')\n parser.finish();\n const root = materialize(parser.root) as MarkdownDocumentNode | null;\n this.parser = parser;\n this.prior = { ...supplied };\n this.materializedRoot = root;\n }\n}" + }, + { + "id": "component:libs/example-layouts/src/lib/example-chat-layout.component.ts#ExampleChatLayoutComponent", + "kind": "component", + "path": "libs/example-layouts/src/lib/example-chat-layout.component.ts", + "symbol": "ExampleChatLayoutComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'example-chat-layout',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n height: 100vh;\n height: 100dvh;\n background: var(--tplane-chat-bg, #fff);\n color: var(--tplane-chat-text, #1a1a1a);\n font-family: var(--tplane-chat-font-family, system-ui, sans-serif);\n }\n .layout {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n }\n .layout__main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }\n .layout__sidebar {\n width: 100%;\n flex-shrink: 0;\n border-top: 1px solid var(--tplane-chat-separator, #e5e5e5);\n overflow-y: auto;\n }\n .layout__sidebar:empty { display: none; }\n @media (min-width: 768px) {\n .layout { flex-direction: row; }\n .layout--sidebar-left { flex-direction: row-reverse; }\n .layout__sidebar {\n width: var(--example-layout-sidebar-width, 18rem);\n border-top: 0;\n border-left: 1px solid var(--tplane-chat-separator, #e5e5e5);\n }\n .layout--sidebar-left .layout__sidebar {\n border-left: 0;\n border-right: 1px solid var(--tplane-chat-separator, #e5e5e5);\n }\n }\n `,\n template: `\n
    \n
    \n \n
    \n `,\n})\nexport class ExampleChatLayoutComponent {\n readonly sidebarPosition = input<'left' | 'right'>('right');\n readonly sidebarWidth = input('18rem');\n}" + }, + { + "id": "component:libs/example-layouts/src/lib/example-split-layout.component.ts#ExampleSplitLayoutComponent", + "kind": "component", + "path": "libs/example-layouts/src/lib/example-split-layout.component.ts", + "symbol": "ExampleSplitLayoutComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'example-split-layout',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n height: 100vh;\n height: 100dvh;\n background: var(--tplane-chat-bg, #fff);\n color: var(--tplane-chat-text, #1a1a1a);\n font-family: var(--tplane-chat-font-family, system-ui, sans-serif);\n }\n .split__header {\n flex-shrink: 0;\n border-bottom: 1px solid var(--tplane-chat-separator, #e5e5e5);\n }\n .split__header:empty { display: none; }\n .split__body {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n }\n .split__primary {\n flex: 1;\n overflow-y: auto;\n padding: 1rem;\n min-height: 200px;\n }\n .split__secondary {\n width: 100%;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n border-top: 1px solid var(--tplane-chat-separator, #e5e5e5);\n background: var(--tplane-chat-surface-alt, #fafafa);\n }\n .split__secondary:empty { display: none; }\n .split__footer { flex-shrink: 0; }\n .split__footer:empty { display: none; }\n @media (min-width: 768px) {\n .split__body { flex-direction: row; }\n .split__primary { padding: 1.5rem; min-height: 0; }\n .split__secondary {\n width: 20rem;\n border-top: 0;\n border-left: 1px solid var(--tplane-chat-separator, #e5e5e5);\n }\n }\n `,\n template: `\n
    \n
    \n
    \n
    \n
    \n
    \n `,\n})\nexport class ExampleSplitLayoutComponent {\n}" + }, + { + "id": "component:libs/render/src/lib/default-fallback.component.ts#DefaultFallbackComponent", + "kind": "component", + "path": "libs/render/src/lib/default-fallback.component.ts", + "symbol": "DefaultFallbackComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'render-default-fallback',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [`\n :host { display: block; width: 100%; }\n .render-default-fallback {\n border: 1px solid var(--tplane-chat-separator, #303540);\n border-radius: 10px;\n padding: 14px;\n background: var(--tplane-chat-surface-alt, #1a1d23);\n }\n .render-default-fallback__label {\n font-size: 12px;\n color: var(--tplane-chat-text-muted, #9aa0aa);\n margin-bottom: 10px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .render-default-fallback__rows {\n display: flex; flex-direction: column; gap: 8px;\n }\n .render-default-fallback__row {\n height: 10px; border-radius: 5px;\n background: linear-gradient(\n 90deg,\n var(--tplane-chat-separator, #303540) 0%,\n color-mix(in srgb, var(--tplane-chat-separator, #303540) 70%, transparent) 50%,\n var(--tplane-chat-separator, #303540) 100%\n );\n background-size: 200% 100%;\n animation: render-default-fallback-shimmer 1.4s ease-in-out infinite;\n }\n .render-default-fallback__row:nth-child(1) { width: 70%; }\n .render-default-fallback__row:nth-child(2) { width: 90%; }\n .render-default-fallback__row:nth-child(3) { width: 50%; }\n @keyframes render-default-fallback-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n `],\n template: `\n
    \n
    \n \n Building UI…\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n `,\n})\nexport class DefaultFallbackComponent {\n}" + }, + { + "id": "component:libs/render/src/lib/render-element.component.ts#RenderElementComponent", + "kind": "component", + "path": "libs/render/src/lib/render-element.component.ts", + "symbol": "RenderElementComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'render-element',\n standalone: true,\n imports: [NgComponentOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n { provide: RENDER_HOST, useFactory: (el: RenderElementComponent) => el.host, deps: [RenderElementComponent] },\n ],\n template: `\n @if (!element()?.repeat) {\n @if (visible()) {\n \n }\n } @else {\n @for (repeatInjector of repeatInjectors(); track $index) {\n @if (repeatVisible()[$index]) {\n \n }\n }\n }\n `,\n})\nexport class RenderElementComponent implements OnInit {\n readonly elementKey = input.required();\n readonly spec = input.required();\n private readonly ctx = inject(RENDER_CONTEXT);\n private readonly repeatScope = inject(REPEAT_SCOPE, { optional: true });\n readonly parentInjector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n private readonly document = inject(DOCUMENT);\n private readonly collectionPolicy = inject(DEVELOPMENT_COLLECTION_POLICY, { optional: true });\n private readonly outlets = viewChildren(NgComponentOutlet);\n private readonly observedInstances = new WeakSet();\n private readonly development = createDevelopmentRuntime({\n integration: 'render', packageName: '@threadplane/render', packageVersion,\n installationToken: (typeof ngDevMode === 'undefined' || ngDevMode) && isDevMode() ? installationToken : null,\n enabled: () => this.collectionPolicy?.() ?? true,\n });\n private destroyed = false;\n constructor() {\n this.development.touch();\n this.destroyRef.onDestroy(() => this.development.dispose());\n afterEveryRender(() => {\n if (this.destroyed)\n return;\n const component = this.componentClass();\n if (!component)\n return;\n for (const outlet of this.outlets()) {\n const instance = outlet.componentInstance;\n if (outlet.ngComponentOutlet !== component || !instance || this.observedInstances.has(instance))\n continue;\n this.observedInstances.add(instance);\n this.development.milestone('generative_ui.rendered');\n }\n });\n this.destroyRef.onDestroy(() => {\n const el = this.element();\n if (el && this.ctx.emitEvent) {\n this.ctx.emitEvent({\n type: 'lifecycle',\n event: 'destroyed',\n scope: 'element',\n elementKey: this.elementKey(),\n elementType: el.type,\n });\n }\n this.destroyed = true;\n });\n effect(() => {\n if (this.mountedReal())\n return;\n const el = this.element();\n if (!el || el.repeat)\n return;\n if (!this.notReady() && this.entry()?.component) {\n this.mountedReal.set(true);\n }\n });\n effect(() => {\n const el = this.element();\n if (!el?.repeat || !this.entry()?.component)\n return;\n const raw = this.repeatRawNotReady();\n const latched = this.repeatMountedReal();\n const next = raw.map((notReady, index) => (latched[index] ?? false) || !notReady);\n if (next.length !== latched.length || next.some((v, i) => v !== latched[i])) {\n this.repeatMountedReal.set(next);\n }\n });\n }\n ngOnInit(): void {\n const el = this.element();\n if (el && this.ctx.emitEvent) {\n this.ctx.emitEvent({\n type: 'lifecycle',\n event: 'mounted',\n scope: 'element',\n elementKey: this.elementKey(),\n elementType: el.type,\n });\n }\n }\n readonly element: Signal = computed(() => this.spec()?.elements?.[this.elementKey()], { equal: Object.is });\n readonly entry = computed(() => {\n const el = this.element();\n return el ? this.ctx.registry.getEntry(el.type) : undefined;\n });\n readonly componentClass = computed(() => {\n const el = this.element();\n if (!el)\n return null;\n return this.entry()?.component ?? null;\n });\n private readonly propCtx = computed(() => buildPropResolutionContext(this.ctx.store, this.repeatScope ?? undefined, this.ctx.functions));\n private readonly mountedReal = signal(false);\n readonly notReady = computed(() => {\n if (this.mountedReal())\n return false;\n const el = this.element();\n if (!el || !el.props)\n return false;\n const resolved = resolveElementProps(el.props, this.propCtx());\n return !isElementReady(this.entry(), resolved);\n });\n readonly mountClass = computed(() => {\n const el = this.element();\n if (!el)\n return null;\n const real = this.entry()?.component ?? null;\n if (this.notReady()) {\n return this.entry()?.fallback ?? null;\n }\n return real;\n });\n readonly visible = computed(() => {\n const el = this.element();\n if (!el)\n return false;\n if (this.mountClass() === null)\n return false;\n return evaluateVisibility(el.visible, this.propCtx());\n });\n private invokeHandlers(event: string, payload?: Record, repeatIndex?: number): void {\n const el = this.element();\n if (!el?.on)\n return;\n const binding = el.on[event];\n if (!binding)\n return;\n const bindings = Array.isArray(binding) ? binding : [binding];\n for (const b of bindings) {\n if (b.preventDefault)\n preventDefaultOn(payload);\n if (b.confirm && !this.askForConfirmation(b.confirm))\n continue;\n const handler = this.ctx.handlers?.[b.action];\n if (!handler)\n continue;\n const resolved = resolveElementProps((b.params ?? {}) as Record, repeatIndex === undefined\n ? this.propCtx()\n : this.repeatPropCtxs()[repeatIndex] ?? this.propCtx());\n const params = { ...resolved, ...(payload ?? {}) };\n let result: unknown;\n try {\n result = runInInjectionContext(this.parentInjector, () => handler(params));\n }\n catch (error) {\n if (!b.onError)\n throw error;\n this.runOnError(b.onError, error);\n continue;\n }\n if (result instanceof Promise) {\n result.then(() => this.runOnSuccess(b.onSuccess), (error: unknown) => {\n if (!b.onError)\n return;\n this.runOnError(b.onError, error);\n });\n }\n else {\n this.runOnSuccess(b.onSuccess);\n }\n }\n }\n private askForConfirmation(confirm: ActionConfirm): boolean {\n const view = this.document.defaultView;\n if (!view?.confirm)\n return true;\n return Boolean(view.confirm(confirm.message));\n }\n private runOnSuccess(onSuccess: ActionOnSuccess | undefined): void {\n if (!onSuccess || this.destroyed)\n return;\n if ('navigate' in onSuccess) {\n this.document.defaultView?.location.assign(onSuccess.navigate);\n return;\n }\n if ('set' in onSuccess) {\n for (const [path, value] of Object.entries(onSuccess.set)) {\n this.ctx.store.set(path, value);\n }\n return;\n }\n this.dispatchAction(onSuccess.action);\n }\n private runOnError(onError: ActionOnError, error: unknown): void {\n if (this.destroyed)\n return;\n if ('set' in onError) {\n const message = error instanceof Error ? error.message : String(error);\n for (const [path, value] of Object.entries(onError.set)) {\n this.ctx.store.set(path, value === '$error.message' ? message : value);\n }\n return;\n }\n this.dispatchAction(onError.action);\n }\n private dispatchAction(name: string): void {\n const handler = this.ctx.handlers?.[name];\n if (!handler)\n return;\n runInInjectionContext(this.parentInjector, () => handler({}));\n }\n readonly host: RenderHost = {\n set: (path: string, value: unknown) => { if (this.destroyed)\n return; this.ctx.store?.set(path, value); },\n emit: (event: string, payload?: Record) => { if (this.destroyed)\n return; this.invokeHandlers(event, payload); },\n result: (value: unknown) => { if (this.destroyed)\n return; this.ctx.emitEvent?.({ type: 'result', value, elementKey: this.elementKey() }); },\n };\n private hostForRepeatIndex(index: number): RenderHost {\n return {\n set: this.host.set,\n result: this.host.result,\n emit: (event: string, payload?: Record) => {\n if (this.destroyed)\n return;\n this.invokeHandlers(event, payload, index);\n },\n };\n }\n private readonly emitFn = (event: string) => {\n this.invokeHandlers(event);\n };\n readonly resolvedInputs = computed(() => {\n const el = this.element();\n if (!el)\n return {};\n const ctx = this.propCtx();\n const resolved = resolveElementProps(el.props ?? {}, ctx);\n const bindings = resolveBindings(el.props ?? {}, ctx);\n return {\n ...resolved,\n bindings,\n emit: this.emitFn,\n loading: this.ctx.loading ?? false,\n childKeys: el.children ?? [],\n spec: this.spec(),\n };\n });\n readonly filteredResolvedInputs = computed(() => filterInputsForClass(this.mountClass() as Type | null, this.resolvedInputs()));\n private readonly repeatItems = computed(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n const items = this.ctx.store.get(el.repeat.statePath);\n return Array.isArray(items) ? items : [];\n });\n private readonly repeatScopes = computed(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n return this.repeatItems().map((item, index) => ({\n item,\n index,\n basePath: `${el.repeat!.statePath}/${index}`,\n } satisfies RepeatScope));\n });\n private readonly repeatPropCtxs = computed(() => this.repeatScopes().map(scope => buildPropResolutionContext(this.ctx.store, scope, this.ctx.functions)));\n readonly repeatInjectors = computed(() => {\n return this.repeatScopes().map((scope, index) => Injector.create({\n providers: [\n { provide: REPEAT_SCOPE, useValue: scope },\n { provide: RENDER_HOST, useValue: this.hostForRepeatIndex(index) },\n ],\n parent: this.parentInjector,\n }));\n });\n private readonly repeatMountedReal = signal([]);\n private readonly repeatRawNotReady = computed(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n const props = el.props;\n if (!props)\n return this.repeatPropCtxs().map(() => false);\n const entry = this.entry();\n return this.repeatPropCtxs().map(ctx => !isElementReady(entry, resolveElementProps(props, ctx)));\n });\n readonly repeatNotReady = computed(() => {\n const latched = this.repeatMountedReal();\n return this.repeatRawNotReady().map((notReady, index) => latched[index] ? false : notReady);\n });\n readonly repeatMountClasses = computed<(AngularComponentRenderer | null)[]>(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n const entry = this.entry();\n const real = entry?.component ?? null;\n const fallback = entry?.fallback ?? null;\n return this.repeatNotReady().map(notReady => (notReady ? fallback : real));\n });\n readonly repeatInputs = computed(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n return this.repeatPropCtxs().map((ctx, index) => {\n const resolved = resolveElementProps(el.props ?? {}, ctx);\n const bindings = resolveBindings(el.props ?? {}, ctx);\n return {\n ...resolved,\n bindings,\n emit: (event: string) => this.invokeHandlers(event, undefined, index),\n loading: this.ctx.loading ?? false,\n childKeys: el.children ?? [],\n spec: this.spec(),\n };\n });\n });\n readonly filteredRepeatInputs = computed(() => {\n const classes = this.repeatMountClasses();\n return this.repeatInputs().map((inputs, index) => filterInputsForClass(classes[index] as Type | null, inputs));\n });\n readonly repeatVisible = computed(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n const classes = this.repeatMountClasses();\n return this.repeatPropCtxs().map((ctx, index) => classes[index] !== null && evaluateVisibility(el.visible, ctx));\n });\n}" + }, + { + "id": "component:libs/render/src/lib/render-spec.component.ts#RenderSpecComponent", + "kind": "component", + "path": "libs/render/src/lib/render-spec.component.ts", + "symbol": "RenderSpecComponent", + "decorators": [ + "Component" + ], + "signature": "@Component({\n selector: 'render-spec',\n standalone: true,\n imports: [RenderElementComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n viewProviders: [\n {\n provide: DEVELOPMENT_COLLECTION_POLICY,\n useFactory: () => {\n const host = inject(RenderSpecComponent);\n const parent = inject(DEVELOPMENT_COLLECTION_POLICY, { optional: true, skipSelf: true });\n const config = inject(RENDER_CONFIG, { optional: true });\n return () => (parent?.() ?? true) && host.telemetry() !== false && config?.telemetry !== false;\n },\n },\n {\n provide: RENDER_CONTEXT,\n useFactory: () => inject(RenderSpecComponent)._context(),\n },\n ],\n template: `\n @if (spec()?.root; as rootKey) {\n \n }\n `,\n})\nexport class RenderSpecComponent implements OnInit {\n readonly spec = input(null);\n readonly registry = input(undefined);\n readonly store = input(undefined);\n readonly functions = input | undefined>(undefined);\n readonly handlers = input) => unknown | Promise> | undefined>(undefined);\n readonly loading = input(false);\n readonly events = output();\n readonly telemetry = input(undefined);\n private readonly config = inject(RENDER_CONFIG, { optional: true });\n private readonly viewRegistry = inject(VIEW_REGISTRY, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n private readonly lifecycle = inject(RenderLifecycleService, { optional: true });\n private destroyed = false;\n private isDestroyed(): boolean {\n return this.destroyed || this.destroyRef.destroyed;\n }\n private readonly guardedEmit = makeGuardedEmit((e) => this.events.emit(e), () => this.isDestroyed());\n private _internalStore: StateStore | undefined;\n private getOrCreateInternalStore(): StateStore {\n if (!this._internalStore) {\n this._internalStore = signalStateStore(this.spec()?.state ?? {});\n }\n return this._internalStore;\n }\n private readonly resolvedStore = computed(() => {\n const inputStore = this.store();\n if (inputStore)\n return inputStore;\n const configStore = this.config?.store;\n if (configStore)\n return configStore;\n return this.getOrCreateInternalStore();\n });\n private readonly resolvedRegistry = computed(() => {\n const inputRegistry = this.registry();\n if (inputRegistry)\n return inputRegistry;\n const configRegistry = this.config?.registry;\n if (configRegistry)\n return configRegistry;\n if (this.viewRegistry)\n return toRenderRegistry(this.viewRegistry);\n return { getEntry: () => undefined, names: () => [] };\n });\n private readonly wrappedHandlers = computed(() => {\n const inputHandlers = this.handlers() ?? this.config?.handlers;\n if (!inputHandlers)\n return undefined;\n const wrapped: Record) => unknown | Promise> = {};\n for (const [name, handler] of Object.entries(inputHandlers)) {\n wrapped[name] = (params: Record) => {\n const result = handler(params);\n if (result instanceof Promise) {\n result.then((r) => {\n this.emitTapped({ type: 'handler', action: name, params, result: r });\n }, () => {\n this.emitTapped({ type: 'handler', action: name, params, result: undefined });\n });\n }\n else {\n this.emitTapped({ type: 'handler', action: name, params, result });\n }\n return result;\n };\n }\n return wrapped;\n });\n private readonly emitTapped = (event: RenderEvent): void => {\n this.guardedEmit(event);\n if (this.isDestroyed() || !this.lifecycle)\n return;\n switch (event.type) {\n case 'lifecycle':\n this.lifecycle.notifyLifecycle({\n kind: event.scope,\n type: event.event,\n elementType: event.elementType,\n });\n break;\n case 'stateChange':\n this.lifecycle.notifyStateChange();\n break;\n case 'handler':\n this.lifecycle.notifyHandlerInvoked(event.action);\n break;\n }\n };\n private readonly emitEvent = (event: RenderEvent) => {\n this.emitTapped(event);\n };\n readonly _context = computed(() => ({\n registry: this.resolvedRegistry(),\n store: this.resolvedStore(),\n functions: this.functions() ?? this.config?.functions,\n handlers: this.wrappedHandlers(),\n emitEvent: this.emitEvent,\n loading: this.loading(),\n }));\n constructor() {\n effect(() => {\n const store = this.resolvedStore();\n const unsub = store.subscribe(() => {\n const snapshot = store.getSnapshot() as Record;\n const change = (store as SignalStateStore).lastChange?.();\n this.emitTapped({\n type: 'stateChange',\n path: change?.path ?? '/',\n value: change ? change.value : snapshot,\n snapshot,\n });\n });\n this.destroyRef.onDestroy(unsub);\n });\n this.destroyRef.onDestroy(() => {\n this.destroyed = true;\n this.emitTapped({ type: 'lifecycle', event: 'destroyed', scope: 'spec' });\n });\n }\n ngOnInit(): void {\n this.emitTapped({ type: 'lifecycle', event: 'mounted', scope: 'spec' });\n }\n}" + }, + { + "id": "config:.github/workflows/ci.yml", + "kind": "config", + "path": ".github/workflows/ci.yml", + "sha256": "7b4b5143058dc90229686fe8e541312ca6ea7276f428bd90fcd7c95e143fb9b6" + }, + { + "id": "config:.github/workflows/publish-middleware-npm.yml", + "kind": "config", + "path": ".github/workflows/publish-middleware-npm.yml", + "sha256": "be292d89365482208c170c787cf754c059985a82013191c06eb3923d990eac03" + }, + { + "id": "config:.github/workflows/publish-middleware-python.yml", + "kind": "config", + "path": ".github/workflows/publish-middleware-python.yml", + "sha256": "0140fde4295d5fa52bdc3fe3179a14063feafeed9fefbf0714ffd42ba43ad84b" + }, + { + "id": "config:.github/workflows/publish.yml", + "kind": "config", + "path": ".github/workflows/publish.yml", + "sha256": "461a9d4ea9f6f2f747040b36a78b4ecb74e4611260c60f9e68fdb8324d57a021" + }, + { + "id": "config:.github/workflows/release-provenance.yml", + "kind": "config", + "path": ".github/workflows/release-provenance.yml", + "sha256": "d788d29e178836d8ef8f3232429b3bc1099ad9cffe9f1d03c8e041e212f253a5" + }, + { + "id": "config:apps/website/scripts/generate-agent-context.ts", + "kind": "config", + "path": "apps/website/scripts/generate-agent-context.ts", + "sha256": "7ac8b31d316e03901a3652a80cc855e0d5a771ed8296e10ec4dc7de8b0236fbd" + }, + { + "id": "config:apps/website/scripts/generate-api-docs.ts", + "kind": "config", + "path": "apps/website/scripts/generate-api-docs.ts", + "sha256": "15e8b7ed03fac6950ab8d6e432374d335214026d07db5c4d4a2bcab8606b03f9" + }, + { + "id": "config:apps/website/scripts/generate-narrative-docs.ts", + "kind": "config", + "path": "apps/website/scripts/generate-narrative-docs.ts", + "sha256": "9fb9b06c7e42f02f64354094f7e9fb9d340391953962f3c44c147cb2aea34589" + }, + { + "id": "config:nx.json", + "kind": "config", + "path": "nx.json", + "sha256": "5a2b4d6d2a395d8c34b716ff2a2e3ca889c154f08dace74d694e6d0d09d8e9f4" + }, + { + "id": "config:package-lock.json", + "kind": "config", + "path": "package-lock.json", + "sha256": "b16eed343e4be6e7d677ffccd7ed004191682eaf248287b1ed4e0fd3bd9f4b5e" + }, + { + "id": "config:package.json", + "kind": "config", + "path": "package.json", + "sha256": "1454dd65be7cc56cf85c23eaf83c17953bb3d4b0dc98350cb1bdd392fbdade25" + }, + { + "id": "config:scripts/assemble-examples.ts", + "kind": "config", + "path": "scripts/assemble-examples.ts", + "sha256": "5c6dc435027c37cbb771bf3aefd7eebfdafb71244a3aa4d694905e0445a47e0f" + }, + { + "id": "config:scripts/cockpit-matrix.mjs", + "kind": "config", + "path": "scripts/cockpit-matrix.mjs", + "sha256": "18b30aeb7cfd515176bbcab3d2b76febc6e674ffb19b22faf5f770622530ad10" + }, + { + "id": "config:scripts/examples/serve-example.ts", + "kind": "config", + "path": "scripts/examples/serve-example.ts", + "sha256": "ec5c3742e1864a15d2efb32ec250fd07e3539a36050b2802bb9628d2895d21ab" + }, + { + "id": "config:scripts/verify-release-versions.mjs", + "kind": "config", + "path": "scripts/verify-release-versions.mjs", + "sha256": "5da9c5e2c4a1ad1ce1cce2288d6aaf01754d25c1e75e46c5b203698000037440" + }, + { + "id": "config:tsconfig.base.json", + "kind": "config", + "path": "tsconfig.base.json", + "sha256": "0948b24b699da2cd2e4bc61f35a0340d25dd21300245b9c04aabadaa32c48fdd" + }, + { + "id": "doc:apps/website/content/docs/a2ui/getting-started/introduction.mdx", + "kind": "doc", + "path": "apps/website/content/docs/a2ui/getting-started/introduction.mdx", + "sha256": "86a4a8a1a12de6c2a91c70634897bb2826aaf7c5114b656c56f41f9502c2b935" + }, + { + "id": "doc:apps/website/content/docs/a2ui/getting-started/quickstart.mdx", + "kind": "doc", + "path": "apps/website/content/docs/a2ui/getting-started/quickstart.mdx", + "sha256": "c26cbce66f9ed50b89c6314d433758be7e9cefbd1557a9d0885841aeb73dda2e" + }, + { + "id": "doc:apps/website/content/docs/a2ui/guides/adapters-and-validation.mdx", + "kind": "doc", + "path": "apps/website/content/docs/a2ui/guides/adapters-and-validation.mdx", + "sha256": "efe874672a6a0cd343e0f0b34e03e5fc27b73776f4518f24f8fd32e610dcc822" + }, + { + "id": "doc:apps/website/content/docs/a2ui/guides/data-model.mdx", + "kind": "doc", + "path": "apps/website/content/docs/a2ui/guides/data-model.mdx", + "sha256": "2f4bfa89c6262b83fdceb39c2e03126cdf8a9c4d62a014995766d54821963e9f" + }, + { + "id": "doc:apps/website/content/docs/a2ui/guides/message-protocol.mdx", + "kind": "doc", + "path": "apps/website/content/docs/a2ui/guides/message-protocol.mdx", + "sha256": "b528d6b1cbbbd2f63cd49f8a8b4571b62e9ea2ba8ea11c1030aedeca2467df53" + }, + { + "id": "doc:apps/website/content/docs/a2ui/reference/parser-resolver-guards.mdx", + "kind": "doc", + "path": "apps/website/content/docs/a2ui/reference/parser-resolver-guards.mdx", + "sha256": "a7fe1c90e3c26297d5de89032e839e4f46627716dc8acdf3fcc50402d75c0446" + }, + { + "id": "doc:apps/website/content/docs/a2ui/reference/schema.mdx", + "kind": "doc", + "path": "apps/website/content/docs/a2ui/reference/schema.mdx", + "sha256": "8369b0fa456db1fd3bcb2741148837ee9440b22e0b830f9775cb280c64aa3211" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/api/fake-agent.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/api/fake-agent.mdx", + "sha256": "f3bc8a6a08f66310106d8903ed29861c0222ab34a388481eb715a215a17afc14" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/api/inject-agent.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/api/inject-agent.mdx", + "sha256": "3b234ef854158a8f9e01c46e1a21544caea9b4db610d903364b7b840298ad7d7" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/api/provide-agent.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/api/provide-agent.mdx", + "sha256": "db8cfbb4b4a087e7301a0bdee430f4e91abae56815282e58adc81529441ae73f" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/api/to-agent.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/api/to-agent.mdx", + "sha256": "43bd676f8f9a73256dd516ad3f9dd9b5146845607491860d9aaf7d73f592563d" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/concepts/architecture.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/concepts/architecture.mdx", + "sha256": "c1ddbbb122aa6811a502fa839354ea6f9de1aad260ee1fb093fd5c6bbe6bf575" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/getting-started/installation.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/getting-started/installation.mdx", + "sha256": "52cb1ebf813965cb619990468af2a0affdac41dadf259d682349a92059896cfa" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/getting-started/introduction.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/getting-started/introduction.mdx", + "sha256": "3ce42ff32f74f98e75d9c8172f96b77d6c8c9952f96631b2a9b5516bcc03acb3" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/getting-started/quickstart.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/getting-started/quickstart.mdx", + "sha256": "dd38ab865761669ddaf98bf010f73b6440d79a6123e574309c6cb6285ea79e74" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/citations.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/citations.mdx", + "sha256": "48288d267ecf6c47fd4f52bd40e71befc0f08f2b6372697b058e4893c069f3b8" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/client-tools.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/client-tools.mdx", + "sha256": "faea9e1d32d5d25f36c96c1eb6fb89a47108d28c0d2f3ec12738666118e5b355" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/custom-events.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/custom-events.mdx", + "sha256": "c9b7e6d483a6bae8b4cb1d13b304a5eec2b0fc010d42877b131a637d9158c3c0" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/deployment.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/deployment.mdx", + "sha256": "31f241c59aa5e05bfddde45aa3a6bfc26bc6e1e362d26a33683e187ddc6598f0" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/fake-agent.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/fake-agent.mdx", + "sha256": "e1de1a9ad6bd93923d34ea98164ee340697a4cac9d4caa9a168cc3c3fd73370f" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/interrupts.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/interrupts.mdx", + "sha256": "71e8eb9b06a9c8fd72194e69cc8dda066ffea998d3ed5049d2fa802e99a3ecaa" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/json-render.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/json-render.mdx", + "sha256": "8adf10a8abbf0235079ce4560e7276a57dc0d941374c12dafc3f74fcf3747cc6" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/subagents.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/subagents.mdx", + "sha256": "85c6ca296fac605a3d9ed0c94b4dfa5ae965cbadd2ce78bc49e3d10fed060058" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/testing.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/testing.mdx", + "sha256": "810ab379ea409a7c1c55bb0d88730572266d7c1fda9dbdeb1e4e2b57315b1f02" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/tool-views.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/tool-views.mdx", + "sha256": "e3fc5eaff940235980637304f5916913ba6de9716052182530a4cf6995e636f8" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/troubleshooting.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/guides/troubleshooting.mdx", + "sha256": "ec12a44a75b042a505f86cf0b1acf52fae566fbd09630a5cd33b74b363f03335" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/reference/event-mapping.mdx", + "kind": "doc", + "path": "apps/website/content/docs/ag-ui/reference/event-mapping.mdx", + "sha256": "457234cf179d4fdda4acaaca491201c0b79bc1aac2470c836dc4503c07a36c12" + }, + { + "id": "doc:apps/website/content/docs/chat/a2ui/catalog.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/a2ui/catalog.mdx", + "sha256": "9214af6adf05723cba5850826854937d4c351145188a81c5d5eaf3a25643b586" + }, + { + "id": "doc:apps/website/content/docs/chat/a2ui/overview.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/a2ui/overview.mdx", + "sha256": "1cebb907d3cd9e936568c0c86769aa2387bd23374e01248a423cc642283ad7ab" + }, + { + "id": "doc:apps/website/content/docs/chat/a2ui/surface-component.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/a2ui/surface-component.mdx", + "sha256": "84d569d723d0470a26afb4de43369022f66c25a21f996eb240f27eed30eb44e0" + }, + { + "id": "doc:apps/website/content/docs/chat/a2ui/surface-store.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/a2ui/surface-store.mdx", + "sha256": "68825892cc896b7146990f123e978fb403be077bca328c0e40faf2c35dea2839" + }, + { + "id": "doc:apps/website/content/docs/chat/api/content-classifier.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/api/content-classifier.mdx", + "sha256": "94a6949b6f06098fb3272db0606627a5795bb01ef2acb6341f0726c4e3bcd5c9" + }, + { + "id": "doc:apps/website/content/docs/chat/api/mock-agent.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/api/mock-agent.mdx", + "sha256": "fcaa1997039b7d09eccb4b996efe75ac1467c756dc5c9e9fe44ba26d9dd954a3" + }, + { + "id": "doc:apps/website/content/docs/chat/api/parse-tree-store.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/api/parse-tree-store.mdx", + "sha256": "5a490b18bae511f56fcca21580513709b2c1fef1b7b3e797c53fe258c7950493" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-debug.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-debug.mdx", + "sha256": "cc1768297c8fa1f3061a6c4e3a71a5157cfd25cf6a760a916aea44954b86a1a7" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-input.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-input.mdx", + "sha256": "b09cb7e495d9f5ab2dfb632440c3b4c477ddc1825b9fddb2a6388df8157fa7dc" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-interrupt-panel.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-interrupt-panel.mdx", + "sha256": "58ebc53fa8da07b6ddd0a84cd24e496182273bbdbecf9116cd76e03d57a107c3" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-message-list.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-message-list.mdx", + "sha256": "98b839ffd38279815f7317de2a12c4a386f482e7af5a6fc060f548d971e7eba5" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-popup.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-popup.mdx", + "sha256": "38f00b1ad909c771ddffaecf79e98b5eb3f4faa0e76e466e135ec971582f696e" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-reasoning.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-reasoning.mdx", + "sha256": "5bf5063d472524cc4eae72d4f944390d69970ab07faaf22781c69afb0f4af2a3" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-select.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-select.mdx", + "sha256": "92a1ec0225f5b6dbe5c17ee42848c2568ab422bdbd4e0136a83a2a374d5e35ce" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-sidebar.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-sidebar.mdx", + "sha256": "88e640b9506fb8568fb2ce181865a2a46ac632d4609311f1b88f754f5edab676" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-sidenav.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-sidenav.mdx", + "sha256": "e545f96aba0d36cd00a10d79d9d06a63a52174081f776f2ed97e240e83ff4575" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-subagent-card.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-subagent-card.mdx", + "sha256": "adda9dccadbf468879c6762bb80eb3314993b514d6ba41fec19fe5d1ed128853" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-tool-call-card.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-tool-call-card.mdx", + "sha256": "994b591b2cb556b8c3ffd6cc8e4166b29b751f9cbfcd4576c9dc7bfa954ee15f" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-tool-call-template.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-tool-call-template.mdx", + "sha256": "3bd532c491a74f092fe4b14a3588b2bc812dcaf26037928c5f6476832438b6ac" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-tool-calls.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-tool-calls.mdx", + "sha256": "7bdf655e5b4436895a228bcde2dace80518910e5c85266886336dcfbcf1df9ad" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-trace.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat-trace.mdx", + "sha256": "34c38f59f8fe80ef0f1c5dc0a2f15b4baeb7b98cb92fc17d99c0f871a4c0aff1" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/components/chat.mdx", + "sha256": "93d1cd92531484437ddee9a7ebc4292d946a7b77f53d62e85f570bff5b07f583" + }, + { + "id": "doc:apps/website/content/docs/chat/concepts/message-model.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/concepts/message-model.mdx", + "sha256": "f5f5f358c72f917e10e797928888186a2c2f5e6af1cf6b16668ba4cc5d56b60c" + }, + { + "id": "doc:apps/website/content/docs/chat/concepts/primitives-vs-compositions.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/concepts/primitives-vs-compositions.mdx", + "sha256": "f44c9cc2097acc5def3592e718d14f010e0275dfddddc00da117ec5f3fc1b794" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/changelog.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/getting-started/changelog.mdx", + "sha256": "41900f462a181319ff4fbc3d1f01fef4dca5c8cc405a834295b18bac753ee61e" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/coding-agents.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/getting-started/coding-agents.mdx", + "sha256": "3f3c1638889700c09319077340879f24ea17486bdc5477ffce387eee00bcd899" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/installation.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/getting-started/installation.mdx", + "sha256": "08816c1b268efdc3ee26b2ceba1732c0616e74ae7d04ea887921177b90406518" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/introduction.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/getting-started/introduction.mdx", + "sha256": "7d1226938d4d496d955404342032564c5a7303d8b4f7b7eb8b572e5084b5af8e" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/quickstart.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/getting-started/quickstart.mdx", + "sha256": "a5addb05ca320c2b2ee9c3890af4d9aff517287256faddbc9acfff1f8fa0d30c" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/try-without-a-backend.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/getting-started/try-without-a-backend.mdx", + "sha256": "80d1593d31ca377747d0f4b13c878f69474e46ae0e9c2fbfc885b17435404ad7" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/client-tools.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/client-tools.mdx", + "sha256": "143b405c376bb84b5fb3c965c0dbe718824f3534a3f6c663707b0b894faa0f7c" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/custom-catalogs.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/custom-catalogs.mdx", + "sha256": "60a7a51eda779d62e629fc2c246ee2ce4d02444f4c048fb7b7f81418558dab77" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/error-handling.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/error-handling.mdx", + "sha256": "1264630503e9243346cb683383d190056bbeb289953014f785b556ee839fd71f" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/generative-ui.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/generative-ui.mdx", + "sha256": "e5a7458d1e969968ae66018bf53cb918599e5928d49a0611c4c8eb6e2cc42708" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/layout-modes.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/layout-modes.mdx", + "sha256": "8ed101aa99281dc6d0caa8b0bcde6f03197768e9eb12a7c873ae4c486ca108cd" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/lifecycle.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/lifecycle.mdx", + "sha256": "5f981ec036fea1568d7cf9dcbd5cbb47576640e06a526dba9429b0490ced6260" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/markdown.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/markdown.mdx", + "sha256": "e1099e176503a480e6d7309a607a7f051df0e05b2b8789ae400792455de5f31d" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/streaming.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/streaming.mdx", + "sha256": "0ccbd5c81d25f41ad2c37d47b6516b38661d906537e117f178b44b65bbcb1f7b" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/theming.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/theming.mdx", + "sha256": "ed9e88c2954925c653acf498f0027fac696001dff791cb61a4fac1b040bad955" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/thread-routing.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/thread-routing.mdx", + "sha256": "dcd915387484935b08c44628ff028b8345f97c55e2315218ca3bc981b406cc55" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/writing-an-adapter.mdx", + "kind": "doc", + "path": "apps/website/content/docs/chat/guides/writing-an-adapter.mdx", + "sha256": "aebc8ba85ac7888d1757e51dd010cebc2c01817956e041e873feff486f1a436d" + }, + { + "id": "doc:apps/website/content/docs/choosing-an-adapter/index.mdx", + "kind": "doc", + "path": "apps/website/content/docs/choosing-an-adapter/index.mdx", + "sha256": "67347b4fc3096b428ee955d5b873a4b55af53de96ff7f3bafd4d2ee884f78110" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/capabilities/filesystem.mdx", + "kind": "doc", + "path": "apps/website/content/docs/deep-agents/capabilities/filesystem.mdx", + "sha256": "3a02cf18319cdbebf786b4a0d72d6340ead8d49d2b099119cf257a3649d8229e" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/capabilities/memory.mdx", + "kind": "doc", + "path": "apps/website/content/docs/deep-agents/capabilities/memory.mdx", + "sha256": "62160da63e594cb423645e708fd260043dc01fe50942507cde4296e13a0890b8" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/capabilities/planning.mdx", + "kind": "doc", + "path": "apps/website/content/docs/deep-agents/capabilities/planning.mdx", + "sha256": "48fc7346f3aab0d9da40558432b9826ea84be15e0e4407196057f6cbaef2a8fa" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/capabilities/skills.mdx", + "kind": "doc", + "path": "apps/website/content/docs/deep-agents/capabilities/skills.mdx", + "sha256": "108415815e56f3b72b99a0c0204029b7764454c6ad0942804bff8654066fc7ee" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/capabilities/subagents.mdx", + "kind": "doc", + "path": "apps/website/content/docs/deep-agents/capabilities/subagents.mdx", + "sha256": "19e8785ec483298a26172b0e30b1da110090d874bb1f725cff080e645b4f6ab2" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/getting-started/introduction.mdx", + "kind": "doc", + "path": "apps/website/content/docs/deep-agents/getting-started/introduction.mdx", + "sha256": "dd2c712bf83374b61a2ce10fcf30fdb174cde9e68085a413f0cf73c09b89d372" + }, + { + "id": "doc:apps/website/content/docs/langgraph/api/fetch-stream-transport.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/api/fetch-stream-transport.mdx", + "sha256": "4529c605e78f0c365d9c217ab41458f9553915bfdaedbb9221e39f4dc8763555" + }, + { + "id": "doc:apps/website/content/docs/langgraph/api/inject-agent.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/api/inject-agent.mdx", + "sha256": "ab57baacb08e3c479c114c22ad7f423afb1fce891d35b6475af2048c3634b2f8" + }, + { + "id": "doc:apps/website/content/docs/langgraph/api/langgraph-threads-adapter.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/api/langgraph-threads-adapter.mdx", + "sha256": "318e6f50129667ff9afeebb6e3c72c5faec8b3cd6b350a27509c5fa3399d0bf8" + }, + { + "id": "doc:apps/website/content/docs/langgraph/api/mock-stream-transport.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/api/mock-stream-transport.mdx", + "sha256": "fbee1508467248ae6ea55cb8252d155c2d8db516f1746780e92c31756c2131d2" + }, + { + "id": "doc:apps/website/content/docs/langgraph/api/provide-agent.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/api/provide-agent.mdx", + "sha256": "6b09d3088365b7bfff85d00f935566547182e2ce78e5cc49d00f5a8a409a2680" + }, + { + "id": "doc:apps/website/content/docs/langgraph/concepts/agent-architecture.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/concepts/agent-architecture.mdx", + "sha256": "2096e52f80988735393879487aba9ebbfd853b7993b0e2c3da68a1d7b494c152" + }, + { + "id": "doc:apps/website/content/docs/langgraph/concepts/agent-contract.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/concepts/agent-contract.mdx", + "sha256": "34fa6cf25f2250647f3cd9046f7f364b5b5f3fdcfa48cdaa499c77ac53f70c4b" + }, + { + "id": "doc:apps/website/content/docs/langgraph/concepts/angular-signals.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/concepts/angular-signals.mdx", + "sha256": "c8d9510126d4f66cbfdc8f091fa51787010a8920b0706c5bab10cc660a4ff7e5" + }, + { + "id": "doc:apps/website/content/docs/langgraph/concepts/langgraph-basics.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/concepts/langgraph-basics.mdx", + "sha256": "eda1f2ebe4c33dfd0d56aa773b13697134670e30a18b6785c6f4fd198048c32a" + }, + { + "id": "doc:apps/website/content/docs/langgraph/concepts/state-management.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/concepts/state-management.mdx", + "sha256": "11c05d5fe10dae31391af7ed79ad58cd33a23014152c12589ef62e2bfc49e42f" + }, + { + "id": "doc:apps/website/content/docs/langgraph/getting-started/installation.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/getting-started/installation.mdx", + "sha256": "d46c300abb634f563b4e27157894d6f2f130044889abe827e9407685d69a3858" + }, + { + "id": "doc:apps/website/content/docs/langgraph/getting-started/introduction.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/getting-started/introduction.mdx", + "sha256": "c1fa0a34a8d3b84d8e3c6bce603d61bd6f5cb58415cc2342263e7e81b127083b" + }, + { + "id": "doc:apps/website/content/docs/langgraph/getting-started/quickstart.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/getting-started/quickstart.mdx", + "sha256": "723f6e889af01c9dc20c5740ce485ad6311418296b212e96518d7e09f4409b05" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/deployment.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/guides/deployment.mdx", + "sha256": "f421cfb14476fbcf05b3ae1b5043f3391d9b45f3d0fd70821f581e07b6fc48bd" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/durable-execution.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/guides/durable-execution.mdx", + "sha256": "981dbb4d00518c135400c18e978d9ba64a3a8d244fb3503046e9c1757a793895" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/interrupts.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/guides/interrupts.mdx", + "sha256": "cb1cee84d9bc7ebaeda78f92289069709d8e8dff404f5447f4aad31317333c64" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/lifecycle.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/guides/lifecycle.mdx", + "sha256": "66db0a0cf63cd1afb13eefc966ab7c6704159cfe7d0caf807d4d270cc1dc64ed" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/memory.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/guides/memory.mdx", + "sha256": "0fec2bdf83ce0d9c7446900a2b12856179182b6b4389b09412c2f095ffe7ce83" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/persistence.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/guides/persistence.mdx", + "sha256": "4555d118ae730837b723c1f39a7454933eac7a976fddc8e79a4ef53577110bab" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/streaming.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/guides/streaming.mdx", + "sha256": "ace11a33c0952e102a45bcacea78998fb52de5d0cf8159d52a02ebf3451a8c32" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/subgraphs.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/guides/subgraphs.mdx", + "sha256": "d459e748cde45589aa04711d777fd79916ad595e6f35f9929ce519e8273db2f6" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/testing.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/guides/testing.mdx", + "sha256": "a30c96f882422afb76809b8f2927ee53e9607a7ecf8ce4959d952b28efb1a3f6" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/time-travel.mdx", + "kind": "doc", + "path": "apps/website/content/docs/langgraph/guides/time-travel.mdx", + "sha256": "34ea8b1fbb52db5ba0a49e679104c8ca78c4ef476edcd058b201cac301d88022" + }, + { + "id": "doc:apps/website/content/docs/middleware/api/client-tool-helpers.mdx", + "kind": "doc", + "path": "apps/website/content/docs/middleware/api/client-tool-helpers.mdx", + "sha256": "c30f91ef36b3836439692ba34a486018b810d25dafaf557ce04021d7f0d8d72b" + }, + { + "id": "doc:apps/website/content/docs/middleware/getting-started/introduction.mdx", + "kind": "doc", + "path": "apps/website/content/docs/middleware/getting-started/introduction.mdx", + "sha256": "544ca54c46d8341cd4fd6473e7296702c31bf65495d97932ecd9f09bb41b5bfa" + }, + { + "id": "doc:apps/website/content/docs/middleware/getting-started/quickstart.mdx", + "kind": "doc", + "path": "apps/website/content/docs/middleware/getting-started/quickstart.mdx", + "sha256": "6365eb17d4ba4f8ec5a227d0ccaa07aa947b09a13995226940c0e5e114fe5f68" + }, + { + "id": "doc:apps/website/content/docs/middleware/guides/langgraph-client-tools.mdx", + "kind": "doc", + "path": "apps/website/content/docs/middleware/guides/langgraph-client-tools.mdx", + "sha256": "466f90a4e317d1727c3fd01a44b36a39d9fc1687489a4633e9337cf3899b16cc" + }, + { + "id": "doc:apps/website/content/docs/middleware/guides/python-langgraph.mdx", + "kind": "doc", + "path": "apps/website/content/docs/middleware/guides/python-langgraph.mdx", + "sha256": "a9d0198d3c4081c5d5524ee4740c7dec842a9ccc0e9130940050962a7e56bb67" + }, + { + "id": "doc:apps/website/content/docs/render/api/define-angular-registry.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/api/define-angular-registry.mdx", + "sha256": "10eabf2a42bdfc1f989cd156b4fc9f2933c3eb4948b46586d6adf2c7e4b9f591" + }, + { + "id": "doc:apps/website/content/docs/render/api/provide-render.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/api/provide-render.mdx", + "sha256": "1496bdc324c34dcfcfef3c4a736039e1c28978ee98824727d5f65970e123dcdf" + }, + { + "id": "doc:apps/website/content/docs/render/api/render-spec-component.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/api/render-spec-component.mdx", + "sha256": "87cfdede1578b1ac54dec0db333d3e84ab1df4fb94a3bd3c7cdda2931d1924cd" + }, + { + "id": "doc:apps/website/content/docs/render/api/signal-state-store.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/api/signal-state-store.mdx", + "sha256": "ac6365a33fb09bfa9c8a7f71f640b8aa73d665d4673847e9aef5af59c45dd8d0" + }, + { + "id": "doc:apps/website/content/docs/render/api/views.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/api/views.mdx", + "sha256": "9f81104331ec9e5fd250eb6c1bd8dfde2af9214f1a8ab36770b70979f67e6454" + }, + { + "id": "doc:apps/website/content/docs/render/concepts/json-render-vs-a2ui.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/concepts/json-render-vs-a2ui.mdx", + "sha256": "97b4ba1b979f2fe0a5a9c658edefc240cbf39c5642a5b1c63b9a1eb09a3a8002" + }, + { + "id": "doc:apps/website/content/docs/render/getting-started/installation.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/getting-started/installation.mdx", + "sha256": "97729f3e71e27a89ca392631a48e991085a1208d10244816a07c750c9a3a0984" + }, + { + "id": "doc:apps/website/content/docs/render/getting-started/introduction.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/getting-started/introduction.mdx", + "sha256": "cae0d2dc4f6e8acc86e2374699982078728babd7eec8eb4c78fc4120627ffc6d" + }, + { + "id": "doc:apps/website/content/docs/render/getting-started/quickstart.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/getting-started/quickstart.mdx", + "sha256": "0bd26979bed6a7b6fec55c68353b1dbc0f4399e2ea11091f39f092d197d0e108" + }, + { + "id": "doc:apps/website/content/docs/render/guides/events.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/guides/events.mdx", + "sha256": "2b71afd0d7c189839779a795cc790a258e48dbbe2b6dd103e6f49fb8c1459a4c" + }, + { + "id": "doc:apps/website/content/docs/render/guides/lifecycle.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/guides/lifecycle.mdx", + "sha256": "e4b4bc1d8555265b92b2f61bd78b7769db2161a7ab1b6ef74ba775d0744b5caa" + }, + { + "id": "doc:apps/website/content/docs/render/guides/registry.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/guides/registry.mdx", + "sha256": "e0c6a4dcadeca0c562ddec9289bdf6460ffa1555c70d7cc1d2ac0231fdbe0db4" + }, + { + "id": "doc:apps/website/content/docs/render/guides/repeat-loops.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/guides/repeat-loops.mdx", + "sha256": "ad8f99807a3af952a0d0560f263d38207f5a265b7c75d22fa5ede550b07bdaba" + }, + { + "id": "doc:apps/website/content/docs/render/guides/specs.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/guides/specs.mdx", + "sha256": "cb0c915de98264459a401c702eeed3961b9f86059ae4b589da26a170ea4d6e6f" + }, + { + "id": "doc:apps/website/content/docs/render/guides/state-store.mdx", + "kind": "doc", + "path": "apps/website/content/docs/render/guides/state-store.mdx", + "sha256": "40d936c1c103a4644e2ff2527af78703ddd894e684329a3513663593e0911527" + }, + { + "id": "doc:apps/website/content/docs/runtimes/aws-strands/how-it-connects.mdx", + "kind": "doc", + "path": "apps/website/content/docs/runtimes/aws-strands/how-it-connects.mdx", + "sha256": "624dd309b718db445b672851cb30b5e674ff3eaca7266a3542338861a6ca9f35" + }, + { + "id": "doc:apps/website/content/docs/runtimes/aws-strands/overview.mdx", + "kind": "doc", + "path": "apps/website/content/docs/runtimes/aws-strands/overview.mdx", + "sha256": "e093efaf9ce09a575701cab6305021f3083a966a9680962df12eec8ecfa8b6bd" + }, + { + "id": "doc:apps/website/content/docs/runtimes/aws-strands/quickstart.mdx", + "kind": "doc", + "path": "apps/website/content/docs/runtimes/aws-strands/quickstart.mdx", + "sha256": "896c32dc6176e08b7908562b7dd260e83dc0d2d162170ee4f074c5a56261afe3" + }, + { + "id": "doc:apps/website/content/docs/runtimes/getting-started/introduction.mdx", + "kind": "doc", + "path": "apps/website/content/docs/runtimes/getting-started/introduction.mdx", + "sha256": "e2a70e0192daefd28ac46ae1eb67fc58f3dcc9727334afa32748b2e0608165d9" + }, + { + "id": "doc:apps/website/content/docs/runtimes/mastra/how-it-connects.mdx", + "kind": "doc", + "path": "apps/website/content/docs/runtimes/mastra/how-it-connects.mdx", + "sha256": "f6fc4d4db24e487bb5a478dbf01e046c91079e5ac20510b54fe7a8cfb42ef28d" + }, + { + "id": "doc:apps/website/content/docs/runtimes/mastra/overview.mdx", + "kind": "doc", + "path": "apps/website/content/docs/runtimes/mastra/overview.mdx", + "sha256": "4bbf3bfb26bacc5bedc2fc1790d44f707c28f6cc08220da730fe55a5dc0175b1" + }, + { + "id": "doc:apps/website/content/docs/runtimes/mastra/quickstart.mdx", + "kind": "doc", + "path": "apps/website/content/docs/runtimes/mastra/quickstart.mdx", + "sha256": "d4addec10501b566b4c77229127ea73631ea6ac2eeffeeada74eb9f7475bd1d1" + }, + { + "id": "doc:apps/website/content/docs/runtimes/microsoft-agent-framework/how-it-connects.mdx", + "kind": "doc", + "path": "apps/website/content/docs/runtimes/microsoft-agent-framework/how-it-connects.mdx", + "sha256": "b8c244e7fb2642efeaffa7b980b5476bdc464ae22cf79d2e5148a6d45efc6075" + }, + { + "id": "doc:apps/website/content/docs/runtimes/microsoft-agent-framework/overview.mdx", + "kind": "doc", + "path": "apps/website/content/docs/runtimes/microsoft-agent-framework/overview.mdx", + "sha256": "36d41ef551bbf62b7adcbc60a124459779f7af9472be32da9940083e39ce0a63" + }, + { + "id": "doc:apps/website/content/docs/runtimes/microsoft-agent-framework/quickstart.mdx", + "kind": "doc", + "path": "apps/website/content/docs/runtimes/microsoft-agent-framework/quickstart.mdx", + "sha256": "b15736aee1214e18a946a0f79ccb5c07bdcfbeada035aeee1e34018dcb4ae36f" + }, + { + "id": "entry:libs/a2ui/src/index.ts", + "kind": "entry", + "path": "libs/a2ui/src/index.ts" + }, + { + "id": "entry:libs/ag-ui/src/public-api.ts", + "kind": "entry", + "path": "libs/ag-ui/src/public-api.ts" + }, + { + "id": "entry:libs/chat/debug/public-api.ts", + "kind": "entry", + "path": "libs/chat/debug/public-api.ts" + }, + { + "id": "entry:libs/chat/src/public-api.ts", + "kind": "entry", + "path": "libs/chat/src/public-api.ts" + }, + { + "id": "entry:libs/chat/testing/public-api.ts", + "kind": "entry", + "path": "libs/chat/testing/public-api.ts" + }, + { + "id": "entry:libs/langgraph/src/public-api.ts", + "kind": "entry", + "path": "libs/langgraph/src/public-api.ts" + }, + { + "id": "entry:libs/middleware/src/langgraph/index.ts", + "kind": "entry", + "path": "libs/middleware/src/langgraph/index.ts" + }, + { + "id": "entry:libs/render/src/public-api.ts", + "kind": "entry", + "path": "libs/render/src/public-api.ts" + }, + { + "id": "entry:libs/telemetry/src/browser/public-api.ts", + "kind": "entry", + "path": "libs/telemetry/src/browser/public-api.ts" + }, + { + "id": "entry:libs/telemetry/src/index.ts", + "kind": "entry", + "path": "libs/telemetry/src/index.ts" + }, + { + "id": "entry:libs/telemetry/src/node/index.ts", + "kind": "entry", + "path": "libs/telemetry/src/node/index.ts" + }, + { + "id": "entry:libs/telemetry/src/shared/public-api.ts", + "kind": "entry", + "path": "libs/telemetry/src/shared/public-api.ts" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2UI_BASIC_CATALOG_ID", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2UI_BASIC_CATALOG_ID", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2UI_BASIC_CATALOG_ID", + "syntaxKind": "VariableDeclaration", + "signature": "A2UI_BASIC_CATALOG_ID = 'https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json'" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2UI_MIME_TYPE", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2UI_MIME_TYPE", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2UI_MIME_TYPE", + "syntaxKind": "VariableDeclaration", + "signature": "A2UI_MIME_TYPE = 'application/a2ui+json'" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2UI_WIRE_VERSION", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2UI_WIRE_VERSION", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2UI_WIRE_VERSION", + "syntaxKind": "VariableDeclaration", + "signature": "A2UI_WIRE_VERSION = 'v0.9'" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiAction", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiAction", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiAction", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiAction = A2uiEventAction | A2uiFunctionAction;" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiActionMessage", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiActionMessage", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiActionMessage", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiActionMessage {\n version: string;\n action: {\n name: string;\n surfaceId: string;\n sourceComponentId: string;\n timestamp: string;\n context?: Record;\n label?: string;\n };\n metadata?: {\n a2uiClientDataModel?: A2uiClientDataModel;\n };\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiAudioPlayer", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiAudioPlayer", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiAudioPlayer", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiAudioPlayer extends A2uiComponentBase {\n component: 'AudioPlayer';\n url: DynamicString;\n description?: DynamicString;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiButton", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiButton", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiButton", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiButton extends A2uiComponentBase {\n component: 'Button';\n child: string;\n variant?: 'default' | 'primary' | 'borderless';\n action: A2uiAction;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCard", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiCard", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiCard", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiCard extends A2uiComponentBase {\n component: 'Card';\n child: string;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCatalogComponent", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiCatalogComponent", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiCatalogComponent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiCatalogComponent = A2uiText | A2uiImage | A2uiIcon | A2uiVideo | A2uiAudioPlayer | A2uiRow | A2uiColumn | A2uiList | A2uiCard | A2uiTabs | A2uiModal | A2uiDivider | A2uiButton | A2uiCheckBox | A2uiTextField | A2uiDateTimeInput | A2uiChoicePicker | A2uiSlider;" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCheck", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiCheck", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiCheck", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiCheck {\n condition: DynamicValue;\n message: string;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCheckBox", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiCheckBox", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiCheckBox", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiCheckBox extends A2uiComponentBase, A2uiCheckable {\n component: 'CheckBox';\n label: DynamicString;\n value: DynamicBoolean;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCheckable", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiCheckable", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiCheckable", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiCheckable {\n checks?: A2uiCheck[];\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiChildren", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiChildren", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiChildren", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiChildren = string[] | {\n path: string;\n componentId: string;\n};" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiChoicePicker", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiChoicePicker", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiChoicePicker", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiChoicePicker extends A2uiComponentBase, A2uiCheckable {\n component: 'ChoicePicker';\n options: {\n label: DynamicString;\n value: string;\n }[];\n value: DynamicStringList;\n variant?: 'mutuallyExclusive' | 'multipleSelection';\n displayStyle?: 'checkbox' | 'chips';\n filterable?: boolean;\n label?: DynamicString;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiClientCapabilities", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiClientCapabilities", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiClientCapabilities", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiClientCapabilities {\n supportedCatalogIds: string[];\n inlineCatalogs?: unknown[];\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiClientDataModel", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiClientDataModel", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiClientDataModel", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiClientDataModel {\n surfaces: Record>;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiColumn", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiColumn", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiColumn", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiColumn extends A2uiComponentBase {\n component: 'Column';\n children: A2uiChildren;\n justify?: A2uiJustify;\n align?: A2uiAlign;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiComponent", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiComponent", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiComponent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiComponent = A2uiCatalogComponent | (A2uiComponentBase & Record);" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiComponentBase", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiComponentBase", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiComponentBase", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiComponentBase {\n id: string;\n component: string;\n catalogId?: string;\n weight?: number;\n accessibility?: Record;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCreateSurface", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiCreateSurface", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiCreateSurface", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiCreateSurface {\n surfaceId: string;\n catalogId: string;\n theme?: A2uiTheme;\n sendDataModel?: boolean;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiDateTimeInput", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiDateTimeInput", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiDateTimeInput", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiDateTimeInput extends A2uiComponentBase, A2uiCheckable {\n component: 'DateTimeInput';\n value: DynamicString;\n enableDate?: boolean;\n enableTime?: boolean;\n min?: DynamicString;\n max?: DynamicString;\n label?: DynamicString;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiDeleteSurface", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiDeleteSurface", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiDeleteSurface", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiDeleteSurface {\n surfaceId: string;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiDivider", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiDivider", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiDivider", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiDivider extends A2uiComponentBase {\n component: 'Divider';\n axis?: 'horizontal' | 'vertical';\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiErrorMessage", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiErrorMessage", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiErrorMessage", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiErrorMessage {\n version: string;\n error: {\n code: string;\n surfaceId?: string;\n path?: string;\n message?: string;\n };\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiEventAction", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiEventAction", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiEventAction", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiEventAction {\n event: {\n name: string;\n context?: Record;\n };\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiFunctionAction", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiFunctionAction", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiFunctionAction", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiFunctionAction {\n functionCall: A2uiFunctionCall;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiFunctionCall", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiFunctionCall", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiFunctionCall", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiFunctionCall {\n call: string;\n args?: Record;\n returnType?: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'any' | 'void';\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiFunctionContext", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiFunctionContext", + "declarations": [ + { + "path": "libs/a2ui/src/lib/functions.ts", + "symbol": "A2uiFunctionContext", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiFunctionContext {\n resolveArg(value: unknown): unknown;\n locale?: string;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiFunctionImpl", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiFunctionImpl", + "declarations": [ + { + "path": "libs/a2ui/src/lib/functions.ts", + "symbol": "A2uiFunctionImpl", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiFunctionImpl = (args: Record, ctx: A2uiFunctionContext) => unknown;" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiFunctionRegistry", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiFunctionRegistry", + "declarations": [ + { + "path": "libs/a2ui/src/lib/functions.ts", + "symbol": "A2uiFunctionRegistry", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiFunctionRegistry = ReadonlyMap;" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiIcon", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiIcon", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiIcon", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiIcon extends A2uiComponentBase {\n component: 'Icon';\n name: DynamicString | {\n svgPath: string;\n };\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiImage", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiImage", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiImage", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiImage extends A2uiComponentBase {\n component: 'Image';\n url: DynamicString;\n description?: DynamicString;\n fit?: 'contain' | 'cover' | 'fill' | 'none' | 'scaleDown';\n variant?: 'icon' | 'avatar' | 'smallFeature' | 'mediumFeature' | 'largeFeature' | 'header';\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiList", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiList", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiList", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiList extends A2uiComponentBase {\n component: 'List';\n children: A2uiChildren;\n direction?: 'vertical' | 'horizontal';\n align?: A2uiAlign;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiMessage", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiMessage", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiMessage", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiMessage = A2uiEnvelopeBase & ({\n createSurface: A2uiCreateSurface;\n} | {\n updateComponents: A2uiUpdateComponents;\n} | {\n updateDataModel: A2uiUpdateDataModel;\n} | {\n deleteSurface: A2uiDeleteSurface;\n});" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiMessageParser", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiMessageParser", + "declarations": [ + { + "path": "libs/a2ui/src/lib/parser.ts", + "symbol": "A2uiMessageParser", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiMessageParser {\n push(chunk: string): A2uiMessage[];\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiModal", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiModal", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiModal", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiModal extends A2uiComponentBase {\n component: 'Modal';\n trigger: string;\n content: string;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiPathRef", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiPathRef", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiPathRef", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiPathRef {\n path: string;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiRow", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiRow", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiRow", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiRow extends A2uiComponentBase {\n component: 'Row';\n children: A2uiChildren;\n justify?: A2uiJustify;\n align?: A2uiAlign;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiScope", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiScope", + "declarations": [ + { + "path": "libs/a2ui/src/lib/resolve.ts", + "symbol": "A2uiScope", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiScope {\n basePath: string;\n item: unknown;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiSlider", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiSlider", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiSlider", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiSlider extends A2uiComponentBase, A2uiCheckable {\n component: 'Slider';\n value: DynamicNumber;\n max: number;\n min?: number;\n label?: DynamicString;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiSurface", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiSurface", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiSurface", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiSurface {\n surfaceId: string;\n catalogId: string;\n theme?: A2uiTheme;\n sendDataModel?: boolean;\n components: Map;\n dataModel: Record;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiTabs", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiTabs", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiTabs", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiTabs extends A2uiComponentBase {\n component: 'Tabs';\n tabs: {\n title: DynamicString;\n child: string;\n }[];\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiText", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiText", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiText", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiText extends A2uiComponentBase {\n component: 'Text';\n text: DynamicString;\n variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'caption' | 'body';\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiTextField", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiTextField", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiTextField", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiTextField extends A2uiComponentBase, A2uiCheckable {\n component: 'TextField';\n label: DynamicString;\n value?: DynamicString;\n variant?: 'shortText' | 'longText' | 'number' | 'obscured';\n validationRegexp?: string;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiTheme", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiTheme", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiTheme", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiTheme {\n primaryColor?: string;\n iconUrl?: string;\n agentDisplayName?: string;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiUpdateComponents", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiUpdateComponents", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiUpdateComponents", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiUpdateComponents {\n surfaceId: string;\n components: A2uiComponent[];\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiUpdateDataModel", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiUpdateDataModel", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiUpdateDataModel", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiUpdateDataModel {\n surfaceId: string;\n path?: string;\n value?: unknown;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiVideo", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "A2uiVideo", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiVideo", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiVideo extends A2uiComponentBase {\n component: 'Video';\n url: DynamicString;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#DynamicBoolean", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "DynamicBoolean", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "DynamicBoolean", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DynamicBoolean = boolean | A2uiPathRef | A2uiFunctionCall;" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#DynamicNumber", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "DynamicNumber", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "DynamicNumber", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DynamicNumber = number | A2uiPathRef | A2uiFunctionCall;" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#DynamicString", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "DynamicString", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "DynamicString", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DynamicString = string | A2uiPathRef | A2uiFunctionCall;" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#DynamicStringList", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "DynamicStringList", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "DynamicStringList", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DynamicStringList = string[] | A2uiPathRef | A2uiFunctionCall;" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#DynamicValue", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "DynamicValue", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "DynamicValue", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DynamicValue = unknown;" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#createA2uiFunctionRegistry", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "createA2uiFunctionRegistry", + "declarations": [ + { + "path": "libs/a2ui/src/lib/functions.ts", + "symbol": "createA2uiFunctionRegistry", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createA2uiFunctionRegistry(overrides?: Record): A2uiFunctionRegistry {\n const map = new Map(Object.entries(STANDARD_FUNCTIONS));\n if (overrides) {\n for (const [name, impl] of Object.entries(overrides))\n map.set(name, impl);\n }\n return map;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#createA2uiMessageParser", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "createA2uiMessageParser", + "declarations": [ + { + "path": "libs/a2ui/src/lib/parser.ts", + "symbol": "createA2uiMessageParser", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createA2uiMessageParser(): A2uiMessageParser {\n let buffer = '';\n function parseEnvelope(json: Record): A2uiMessage | null {\n for (const key of ENVELOPE_KEYS) {\n if (key in json && typeof json[key] === 'object' && json[key] !== null) {\n const version = typeof json['version'] === 'string' ? json['version'] : A2UI_WIRE_VERSION;\n return { version, [key]: json[key] } as unknown as A2uiMessage;\n }\n }\n return null;\n }\n function push(chunk: string): A2uiMessage[] {\n buffer += chunk;\n const messages: A2uiMessage[] = [];\n let newlineIndex: number;\n while ((newlineIndex = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newlineIndex).trim();\n buffer = buffer.slice(newlineIndex + 1);\n if (!line)\n continue;\n try {\n const json = JSON.parse(line);\n if (json && typeof json === 'object' && !Array.isArray(json)) {\n const msg = parseEnvelope(json as Record);\n if (msg)\n messages.push(msg);\n }\n }\n catch {\n }\n }\n return messages;\n }\n return { push };\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#deleteByPointer", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "deleteByPointer", + "declarations": [ + { + "path": "libs/a2ui/src/lib/pointer.ts", + "symbol": "deleteByPointer", + "syntaxKind": "FunctionDeclaration", + "signature": "export function deleteByPointer(model: Record, pointer: string): Record {\n const segments = parsePointer(pointer);\n if (segments.length === 0)\n return {};\n const parentPath = segments.slice(0, -1);\n const key = segments[segments.length - 1];\n if (parentPath.length === 0) {\n const copy = { ...model };\n delete copy[key];\n return copy;\n }\n const parent = getByPointer(model, '/' + parentPath.join('/'));\n if (parent == null || typeof parent !== 'object')\n return model;\n if (Array.isArray(parent)) {\n const parentCopy = [...(parent as unknown[])];\n parentCopy[Number(key)] = undefined;\n return setByPointer(model, '/' + parentPath.join('/'), parentCopy);\n }\n const parentCopy = { ...(parent as Record) };\n delete parentCopy[key];\n return setByPointer(model, '/' + parentPath.join('/'), parentCopy);\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#getByPointer", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "getByPointer", + "declarations": [ + { + "path": "libs/a2ui/src/lib/pointer.ts", + "symbol": "getByPointer", + "syntaxKind": "FunctionDeclaration", + "signature": "export function getByPointer(model: Record, pointer: string): unknown {\n const segments = parsePointer(pointer);\n let current: unknown = model;\n for (const seg of segments) {\n if (current == null || typeof current !== 'object')\n return undefined;\n current = (current as Record)[seg];\n }\n return current;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#isFunctionCall", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "isFunctionCall", + "declarations": [ + { + "path": "libs/a2ui/src/lib/guards.ts", + "symbol": "isFunctionCall", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isFunctionCall(value: unknown): value is {\n call: string;\n args?: Record;\n} {\n return typeof value === 'object' && value !== null\n && 'call' in value && typeof (value as {\n call: unknown;\n }).call === 'string';\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#isPathRef", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "isPathRef", + "declarations": [ + { + "path": "libs/a2ui/src/lib/guards.ts", + "symbol": "isPathRef", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isPathRef(value: unknown): value is {\n path: string;\n} {\n return typeof value === 'object' && value !== null\n && 'path' in value && typeof (value as {\n path: unknown;\n }).path === 'string';\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#resolveDynamic", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "resolveDynamic", + "declarations": [ + { + "path": "libs/a2ui/src/lib/resolve.ts", + "symbol": "resolveDynamic", + "syntaxKind": "FunctionDeclaration", + "signature": "export function resolveDynamic(value: unknown, model: Record, scope?: A2uiScope, registry?: A2uiFunctionRegistry): unknown {\n if (value == null)\n return value;\n if (Array.isArray(value))\n return value.map(item => resolveDynamic(item, model, scope, registry));\n if (isFunctionCall(value)) {\n if (!registry)\n return undefined;\n const impl = registry.get(value.call);\n if (!impl) {\n warnUnknownA2uiFunction(value.call);\n return undefined;\n }\n const args = (value.args ?? {}) as Record;\n return withActiveRegistry(registry, () => impl(args, {\n resolveArg: (v) => resolveDynamic(v, model, scope, registry),\n }));\n }\n if (isPathRef(value))\n return resolvePathRef(value, model, scope);\n return value;\n}" + } + ] + }, + { + "id": "export:libs/a2ui/src/index.ts#setByPointer", + "kind": "export", + "path": "libs/a2ui/src/index.ts", + "symbol": "setByPointer", + "declarations": [ + { + "path": "libs/a2ui/src/lib/pointer.ts", + "symbol": "setByPointer", + "syntaxKind": "FunctionDeclaration", + "signature": "export function setByPointer(model: Record, pointer: string, value: unknown): Record {\n const segments = parsePointer(pointer);\n if (segments.length === 0)\n return value as Record;\n function clone(obj: unknown, segs: string[], val: unknown): unknown {\n if (segs.length === 0)\n return val;\n const [head, ...rest] = segs;\n const base = (obj != null && typeof obj === 'object') ? obj : {};\n const isArray = Array.isArray(base);\n const copy = isArray ? [...(base as unknown[])] : { ...(base as Record) };\n (copy as Record)[head] = clone((base as Record)[head], rest, val);\n return copy;\n }\n return clone(model, segments, value) as Record;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgUiAgent", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "AgUiAgent", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/to-agent.ts", + "symbol": "AgUiAgent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgUiAgent> extends Agent {\n submit(input: AgentSubmitInput, opts?: AgUiSubmitOptions): Promise;\n ready: Promise;\n reconcileInterrupt(): Promise;\n interruptSession: Signal;\n dispose(): void;\n customEvents: Signal;\n clientTools: ClientToolsCapability;\n subagents: Signal>;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgUiFakeAgentConfig", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "AgUiFakeAgentConfig", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/testing/provide-fake-agent.ts", + "symbol": "AgUiFakeAgentConfig", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgUiFakeAgentConfig extends FakeAgentConfig {\n script?: FakeAgentScript;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgUiInterruptPersistence", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "AgUiInterruptPersistence", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/interrupt-persistence.ts", + "symbol": "AgUiInterruptPersistence", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgUiInterruptPersistence {\n namespace: string;\n store: {\n load(key: string): Promise;\n compareAndSwap(key: string, expectedRevision: number | null, next: AgUiThreadRecord): Promise;\n };\n reconcile?: (record: AgUiThreadRecord) => Promise<{\n status: 'unknown';\n } | {\n status: 'pending' | 'acknowledged' | 'completed';\n committed: ThreadSnapshot;\n session: InterruptSessionSnapshot;\n }>;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgUiSubmitOptions", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "AgUiSubmitOptions", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/to-agent.ts", + "symbol": "AgUiSubmitOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgUiSubmitOptions extends AgentSubmitOptions {\n interruptGeneration?: number;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgUiThreadRecord", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "AgUiThreadRecord", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/interrupt-persistence.ts", + "symbol": "AgUiThreadRecord", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgUiThreadRecord {\n version: 1;\n namespace: string;\n threadId: string;\n revision: number;\n committed: ThreadSnapshot;\n session: InterruptSessionSnapshot;\n resumeInput?: ThreadSnapshot;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgentConfig", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "AgentConfig", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/provide-agent.ts", + "symbol": "AgentConfig", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentConfig {\n interruptTransport?: ToAgentOptions['interruptTransport'];\n persistence?: ToAgentOptions['persistence'];\n url: string;\n agentId?: string;\n threadId?: string;\n headers?: Record;\n telemetry?: AgentRuntimeTelemetrySink | false;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#CustomStreamEvent", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "CustomStreamEvent", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/reducer.ts", + "symbol": "CustomStreamEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface CustomStreamEvent {\n name: string;\n data: unknown;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#FakeAgent", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "FakeAgent", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/testing/fake-agent.ts", + "symbol": "FakeAgent", + "syntaxKind": "ClassDeclaration", + "signature": "export class FakeAgent extends AbstractAgent {\n private readonly tokens: string[];\n private readonly reasoningTokens: string[];\n private readonly delayMs: number;\n private readonly script: FakeAgentScript;\n constructor(opts: {\n tokens?: string[];\n reasoningTokens?: string[];\n delayMs?: number;\n script?: FakeAgentScript;\n } = {}) {\n super();\n this.tokens = opts.tokens ?? [\n 'Hello', ' from', ' the', ' fake', ' AG-UI', ' agent.',\n ' This', ' is', ' a', ' canned', ' streaming', ' reply.',\n ];\n this.reasoningTokens = opts.reasoningTokens ?? [];\n this.delayMs = opts.delayMs ?? 60;\n this.script = opts.script ?? [];\n }\n run(input: RunAgentInput): Observable {\n const scripted = this.scriptedSequence(input);\n if (scripted)\n return this.emitSequence(scripted, 30);\n const tokens = this.tokens;\n const reasoningTokens = this.reasoningTokens;\n const messageId = `fake-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const sequence: BaseEvent[] = [\n { type: EventType.RUN_STARTED, threadId: input.threadId, runId: input.runId } as BaseEvent,\n ];\n if (reasoningTokens.length > 0) {\n sequence.push({ type: EventType.REASONING_MESSAGE_START, messageId, role: 'assistant' } as BaseEvent);\n for (const delta of reasoningTokens) {\n sequence.push({ type: EventType.REASONING_MESSAGE_CONTENT, messageId, delta } as BaseEvent);\n }\n sequence.push({ type: EventType.REASONING_MESSAGE_END, messageId } as BaseEvent);\n }\n sequence.push({ type: EventType.TEXT_MESSAGE_START, messageId, role: 'assistant' } as BaseEvent);\n for (const delta of tokens) {\n sequence.push({ type: EventType.TEXT_MESSAGE_CONTENT, messageId, delta } as BaseEvent);\n }\n sequence.push({ type: EventType.TEXT_MESSAGE_END, messageId } as BaseEvent);\n sequence.push({ type: EventType.RUN_FINISHED, threadId: input.threadId, runId: input.runId } as BaseEvent);\n return this.emitSequence(sequence, 30);\n }\n private scriptedSequence(input: RunAgentInput): BaseEvent[] | undefined {\n if (this.script.length === 0)\n return undefined;\n const branch = this.script.find((candidate) => matchesBranch(candidate.when, input));\n if (!branch)\n return undefined;\n return [\n { type: EventType.RUN_STARTED, threadId: input.threadId, runId: input.runId } as BaseEvent,\n ...branch.events,\n { type: EventType.RUN_FINISHED, threadId: input.threadId, runId: input.runId } as BaseEvent,\n ];\n }\n private emitSequence(sequence: readonly BaseEvent[], initialDelayMs: number): Observable {\n const delayMs = this.delayMs;\n return new Observable((observer) => {\n let cancelled = false;\n let timer: ReturnType | undefined;\n let i = 0;\n const emitNext = () => {\n if (cancelled)\n return;\n if (i >= sequence.length) {\n observer.complete();\n return;\n }\n observer.next(sequence[i]);\n i++;\n timer = setTimeout(emitNext, delayMs);\n };\n timer = setTimeout(emitNext, initialDelayMs);\n return () => {\n cancelled = true;\n if (timer !== undefined)\n clearTimeout(timer);\n };\n });\n }\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#FakeAgentScript", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "FakeAgentScript", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/testing/fake-agent.ts", + "symbol": "FakeAgentScript", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type FakeAgentScript = readonly {\n when: 'initial' | {\n toolMessageFor: string;\n };\n events: readonly BaseEvent[];\n}[];" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#InterruptSessionPhase", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "InterruptSessionPhase", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/interrupt-session.types.ts", + "symbol": "InterruptSessionPhase", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type InterruptSessionPhase = 'none' | 'collecting' | 'pending' | 'claimed' | 'resuming' | 'acknowledged' | 'uncertain' | 'recovery-required';" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#InterruptSessionSnapshot", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "InterruptSessionSnapshot", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/interrupt-session.types.ts", + "symbol": "InterruptSessionSnapshot", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface InterruptSessionSnapshot {\n phase: InterruptSessionPhase;\n generation: number;\n interrupts: Interrupt[];\n legacy?: AgentInterrupt;\n runId?: string;\n attempt?: ResumeAttempt;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#InterruptTransport", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "InterruptTransport", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/interrupt-session.types.ts", + "symbol": "InterruptTransport", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type InterruptTransport = 'auto' | 'protocol' | 'legacy-command' | 'mastra-command';" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#ResumeAttempt", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "ResumeAttempt", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/interrupt-session.types.ts", + "symbol": "ResumeAttempt", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ResumeAttempt {\n id: string;\n runId: string;\n input: AgentSubmitInput;\n parameters: {\n resume?: ResumeEntry[];\n forwardedProps?: Record;\n };\n generation: number;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#ThreadSnapshot", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "ThreadSnapshot", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/run-state-transaction.ts", + "symbol": "ThreadSnapshot", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ThreadSnapshot {\n state: Record;\n messages: Message[];\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#ToAgentOptions", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "ToAgentOptions", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/to-agent.ts", + "symbol": "ToAgentOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ToAgentOptions {\n persistence?: AgUiInterruptPersistence;\n interruptTransport?: InterruptTransport;\n telemetry?: AgentRuntimeTelemetrySink | false;\n a2uiClientCapabilities?: {\n supportedCatalogIds: string[];\n inlineCatalogs?: unknown[];\n };\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#bridgeCitationsState", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "bridgeCitationsState", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/bridge-citations-state.ts", + "symbol": "bridgeCitationsState", + "syntaxKind": "FunctionDeclaration", + "signature": "export function bridgeCitationsState(thread: ThreadStateLike, messages: Message[]): Message[] {\n const citationsByMsg = (thread.state as {\n citations?: unknown;\n })?.citations;\n if (!citationsByMsg || typeof citationsByMsg !== 'object')\n return messages;\n const map = citationsByMsg as Record;\n return messages.map(msg => {\n const raw = map[msg.id];\n if (!Array.isArray(raw) || raw.length === 0)\n return msg;\n return { ...msg, citations: raw.map((entry, i) => normalizeCitation(entry, i + 1)) };\n });\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#injectAgent", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "injectAgent", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/provide-agent.ts", + "symbol": "injectAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function injectAgent(): AgUiAgent;" + }, + { + "path": "libs/ag-ui/src/lib/provide-agent.ts", + "symbol": "injectAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function injectAgent(ref: AgentRef): AgUiAgent;" + }, + { + "path": "libs/ag-ui/src/lib/provide-agent.ts", + "symbol": "injectAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function injectAgent(ref?: AgentRef): AgUiAgent {\n return inject(ref ? ref.token : AGENT) as AgUiAgent;\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#provideAgent", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "provideAgent", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/provide-agent.ts", + "symbol": "provideAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideAgent(configOrFactory: AgentConfig | (() => AgentConfig)): Provider[];" + }, + { + "path": "libs/ag-ui/src/lib/provide-agent.ts", + "symbol": "provideAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideAgent>(ref: AgentRef, configOrFactory: AgentConfig | (() => AgentConfig)): Provider[];" + }, + { + "path": "libs/ag-ui/src/lib/provide-agent.ts", + "symbol": "provideAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideAgent>(refOrConfig: AgentRef | AgentConfig | (() => AgentConfig), maybeConfig?: AgentConfig | (() => AgentConfig)): Provider[] {\n const ref = isAgentRef(refOrConfig) ? refOrConfig : undefined;\n const configOrFactory = (ref ? maybeConfig : refOrConfig) as AgentConfig | (() => AgentConfig);\n if (!ref) {\n return [{ provide: AGENT, useFactory: () => buildAgUiAgent(configOrFactory) }];\n }\n return [\n { provide: AGENT_REF_DEBUG_NAMES, multi: true, useValue: refDebugName(ref) },\n {\n provide: ref.token,\n useFactory: () => {\n warnOnAmbiguousSharedAlias();\n return buildAgUiAgent(configOrFactory);\n },\n },\n { provide: AGENT, useExisting: ref.token },\n ];\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#provideFakeAgent", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "provideFakeAgent", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/testing/provide-fake-agent.ts", + "symbol": "provideFakeAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideFakeAgent(config: AgUiFakeAgentConfig = {}): Provider[] {\n return [\n {\n provide: AGENT,\n useFactory: () => {\n const adapter = toAgent(new FakeAgent(config));\n inject(DestroyRef).onDestroy(() => adapter.dispose());\n return adapter;\n },\n },\n ];\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#toAgent", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "toAgent", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/to-agent.ts", + "symbol": "toAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function toAgent(source: AbstractAgent, options: ToAgentOptions = {}): AgUiAgent {\n return createAgentAdapter(source, options);\n}" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#ɵAG_UI_RUNTIME_OPERATION_REPORTER", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "ɵAG_UI_RUNTIME_OPERATION_REPORTER", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/runtime-operation-reporter.ts", + "symbol": "ɵAG_UI_RUNTIME_OPERATION_REPORTER", + "syntaxKind": "VariableDeclaration", + "signature": "ɵAG_UI_RUNTIME_OPERATION_REPORTER = new InjectionToken('ɵAG_UI_RUNTIME_OPERATION_REPORTER')" + } + ] + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#ɵAgUiRuntimeOperationFailureReporter", + "kind": "export", + "path": "libs/ag-ui/src/public-api.ts", + "symbol": "ɵAgUiRuntimeOperationFailureReporter", + "declarations": [ + { + "path": "libs/ag-ui/src/lib/runtime-operation-reporter.ts", + "symbol": "RuntimeOperationFailureReporter", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type RuntimeOperationFailureReporter = (code: 'unauthorized' | 'network_blocked') => void;" + } + ] + }, + { + "id": "export:libs/chat/debug/public-api.ts#ChatDebugComponent", + "kind": "export", + "path": "libs/chat/debug/public-api.ts", + "symbol": "ChatDebugComponent", + "declarations": [ + { + "path": "libs/chat/debug/src/lib/compositions/chat-debug/chat-debug.component.ts", + "symbol": "ChatDebugComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-debug',\n standalone: true,\n imports: [TimelineInspectorComponent, StateInspectorComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_DEBUG_TOKENS,\n `\n :host {\n display: contents;\n }\n\n /* ── Status pill launcher ─────────────────────────────────────── */\n .launcher {\n position: fixed;\n top: 20px;\n right: 20px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: var(--tplane-chat-debug-radius-pill);\n background: var(--tplane-chat-debug-bg);\n border: 1px solid var(--tplane-chat-debug-border);\n color: var(--tplane-chat-debug-text);\n cursor: pointer;\n z-index: 990;\n box-shadow: var(--tplane-chat-debug-shadow-pill);\n transition: background 120ms ease, border-color 120ms ease;\n padding: 0;\n }\n .launcher:hover {\n background: var(--tplane-chat-debug-surface);\n border-color: var(--tplane-chat-debug-border-strong);\n }\n .launcher__dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--tplane-chat-debug-success);\n box-shadow: 0 0 8px\n color-mix(in srgb, var(--tplane-chat-debug-success) 60%, transparent);\n }\n .launcher__dot--streaming {\n background: var(--tplane-chat-debug-accent);\n box-shadow: 0 0 8px\n color-mix(in srgb, var(--tplane-chat-debug-accent) 70%, transparent);\n animation: chat-debug-pill-pulse 1.2s ease-in-out infinite;\n }\n @keyframes chat-debug-pill-pulse {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.6;\n transform: scale(0.85);\n }\n }\n\n /* ── Docked panel ─────────────────────────────────────────────── */\n .panel {\n position: fixed;\n background: var(--tplane-chat-debug-bg);\n color: var(--tplane-chat-debug-text);\n border: 1px solid var(--tplane-chat-debug-border);\n z-index: 991;\n display: flex;\n flex-direction: column;\n box-shadow: var(--tplane-chat-debug-shadow-panel);\n animation: chat-debug-panel-enter 120ms ease;\n }\n .panel--right {\n top: 0;\n right: var(--tplane-chat-sidebar-claim-right, 0);\n bottom: 0;\n width: var(--panel-size, 420px);\n border-right: 0;\n border-top-left-radius: var(--tplane-chat-debug-radius-panel);\n border-bottom-left-radius: var(--tplane-chat-debug-radius-panel);\n transform-origin: bottom right;\n transition: right 200ms ease-out;\n }\n .panel--left {\n top: 0;\n left: 0;\n bottom: 0;\n width: var(--panel-size, 420px);\n border-left: 0;\n border-top-right-radius: var(--tplane-chat-debug-radius-panel);\n border-bottom-right-radius: var(--tplane-chat-debug-radius-panel);\n transform-origin: bottom left;\n }\n .panel--bottom {\n left: 0;\n right: var(--tplane-chat-sidebar-claim-right, 0);\n bottom: 0;\n height: var(--panel-size, 40vh);\n border-bottom: 0;\n border-top-left-radius: var(--tplane-chat-debug-radius-panel);\n border-top-right-radius: var(--tplane-chat-debug-radius-panel);\n transform-origin: bottom right;\n transition: right 200ms ease-out;\n }\n /* Mobile breakpoint: when an edge-claimer occupies the right and\n the device is narrow, the bottom strip's effective width is\n ~zero. Explicitly hide it so it doesn't intercept pointer events\n on the sidebar drawer. The chat-debug launcher remains visible. */\n @media (max-width: 767px) {\n .panel--bottom {\n display: none;\n }\n }\n @keyframes chat-debug-panel-enter {\n from {\n opacity: 0;\n transform: scale(0.96);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n .panel__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--tplane-chat-debug-border);\n min-height: 44px;\n box-sizing: border-box;\n }\n .panel__title {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--tplane-chat-debug-text);\n }\n .panel__actions {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .panel__dock-group {\n display: inline-flex;\n gap: 0;\n padding: 2px;\n background: var(--tplane-chat-debug-bg-deep);\n border: 1px solid var(--tplane-chat-debug-border);\n border-radius: 6px;\n }\n .panel__dock-btn {\n appearance: none;\n background: transparent;\n border: 0;\n border-radius: 4px;\n width: 24px;\n height: 22px;\n padding: 0;\n color: var(--tplane-chat-debug-text-subtle);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background 120ms ease, color 120ms ease;\n }\n .panel__dock-btn:hover {\n color: var(--tplane-chat-debug-text);\n }\n .panel__dock-btn.is-active {\n background: var(--tplane-chat-debug-border);\n color: var(--tplane-chat-debug-text);\n }\n .panel__dock-btn svg {\n display: block;\n }\n\n .panel__close {\n appearance: none;\n background: transparent;\n border: 0;\n border-radius: 6px;\n width: 26px;\n height: 26px;\n margin-left: 4px;\n color: var(--tplane-chat-debug-text-subtle);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background 120ms ease, color 120ms ease;\n }\n .panel__close:hover {\n background: var(--tplane-chat-debug-surface);\n color: var(--tplane-chat-debug-text);\n }\n\n .panel__controls {\n border-bottom: 1px solid var(--tplane-chat-debug-border);\n overflow-y: auto;\n max-height: 50%;\n background: var(--tplane-chat-debug-bg);\n }\n .panel__controls:empty {\n display: none;\n }\n\n .panel__tabs {\n display: flex;\n gap: 4px;\n border-bottom: 1px solid var(--tplane-chat-debug-border);\n padding: 0 12px;\n background: var(--tplane-chat-debug-bg);\n }\n .panel__tab {\n appearance: none;\n background: transparent;\n border: 0;\n border-bottom: 2px solid transparent;\n padding: 10px 8px;\n font: inherit;\n font-size: 13px;\n font-weight: 500;\n color: var(--tplane-chat-debug-text-muted);\n cursor: pointer;\n transition: color 120ms ease, border-color 120ms ease;\n margin-bottom: -1px;\n }\n .panel__tab:hover {\n color: var(--tplane-chat-debug-text);\n }\n .panel__tab.is-active {\n color: var(--tplane-chat-debug-text);\n border-bottom-color: var(--tplane-chat-debug-accent);\n }\n\n .panel__body {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n background: var(--tplane-chat-debug-bg);\n }\n `,\n ],\n template: `\n @if (!open() && launcher() === 'floating') {\n \n \n \n } @else if (open() && agent(); as currentAgent) {\n \n
    \n

    Chat Devtools

    \n
    \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    \n \n \n \n \n \n \n
    \n \n\n @if (tabs().length > 1) {\n
    \n @for (tab of tabs(); track tab.id) {\n \n {{ tab.label }}\n \n }\n
    \n }\n\n
    \n @switch (activeTab()?.kind) { @case ('builtin-timeline') { @if\n (historyAgent(); as history) {\n \n } } @case ('builtin-state') {\n \n } }\n
    \n \n }\n `,\n})\nexport class ChatDebugComponent {\n readonly agent = input(null);\n readonly dock = input('right');\n readonly defaultOpen = input(false);\n readonly launcher = input<'floating' | 'none'>('floating');\n readonly storageKey = input('chat-debug');\n readonly replayRequested = output();\n readonly forkRequested = output();\n readonly openChange = output();\n readonly dockChange = output();\n protected readonly open = signal(false);\n protected readonly dockState = signal('right');\n private readonly userDockOverride = signal(false);\n protected readonly activeTabId = signal('timeline');\n protected readonly historyAgent = computed(() => {\n const agent = this.agent();\n return agent && hasHistory(agent) ? agent : null;\n });\n private readonly hydrated = signal(false);\n protected readonly isStreaming = computed(() => {\n const status = this.agent()?.status?.();\n return status === 'running';\n });\n protected readonly tabs = computed((): TabEntry[] => {\n if (!this.agent())\n return [];\n return [\n ...(this.historyAgent()\n ? [\n {\n id: 'timeline',\n label: 'Timeline',\n kind: 'builtin-timeline',\n } satisfies TabEntry,\n ]\n : []),\n { id: 'state', label: 'State', kind: 'builtin-state' },\n ];\n });\n protected readonly activeTab = computed(() => this.tabs().find((t) => t.id === this.activeTabId()));\n private readonly hostEl: ElementRef = inject(ElementRef);\n constructor() {\n ensureChatDebugRootStyles();\n effect(() => {\n const tabs = this.tabs();\n if (tabs.length === 0)\n return;\n if (tabs.some((tab) => tab.id === this.activeTabId()))\n return;\n this.activeTabId.set(tabs[0].id);\n });\n afterNextRender(() => {\n const restore = createPersistence(this.storageKey());\n const persistedOpen = restore.read('open');\n if (!this.open()) {\n this.open.set(persistedOpen ?? this.defaultOpen());\n }\n const persistedDock = restore.read('dock');\n this.dockState.set(persistedDock ?? this.dock());\n const persistedTab = restore.read('tab');\n if (persistedTab)\n this.activeTabId.set(persistedTab);\n this.hydrated.set(true);\n });\n effect(() => {\n if (!this.hydrated())\n return;\n const p = createPersistence(this.storageKey());\n p.write('open', this.open());\n p.write('dock', this.dockState());\n p.write('tab', this.activeTabId());\n });\n effect(() => {\n if (typeof document === 'undefined')\n return;\n const html = document.documentElement;\n if (this.open()) {\n html.dataset['threadplaneChatDebug'] = this.dockState();\n }\n else {\n delete html.dataset['threadplaneChatDebug'];\n }\n });\n effect(() => {\n const isOpen = this.open();\n if (!isOpen)\n return;\n if (this.userDockOverride())\n return;\n if (typeof document === 'undefined')\n return;\n if (!document.querySelector('chat-sidebar'))\n return;\n this.dockState.set('bottom');\n });\n }\n setOpen(value: boolean): void {\n this.open.set(value);\n this.openChange.emit(value);\n }\n setDock(next: DockPosition): void {\n this.userDockOverride.set(true);\n this.dockState.set(next);\n this.dockChange.emit(next);\n }\n setActiveTab(id: string): void {\n this.activeTabId.set(id);\n }\n @HostListener('document:keydown.escape')\n protected onEsc(): void {\n if (this.open())\n this.setOpen(false);\n }\n @HostListener('document:click', ['$event'])\n protected onDocumentClick(event: MouseEvent): void {\n if (!this.open())\n return;\n const path = event.composedPath();\n if (path.includes(this.hostEl.nativeElement))\n return;\n this.setOpen(false);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/debug/public-api.ts#DockPosition", + "kind": "export", + "path": "libs/chat/debug/public-api.ts", + "symbol": "DockPosition", + "declarations": [ + { + "path": "libs/chat/debug/src/lib/compositions/chat-debug/chat-debug.component.ts", + "symbol": "DockPosition", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DockPosition = 'right' | 'bottom' | 'left';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2UI_BASIC_CATALOG_ID", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2UI_BASIC_CATALOG_ID", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2UI_BASIC_CATALOG_ID", + "syntaxKind": "VariableDeclaration", + "signature": "A2UI_BASIC_CATALOG_ID = 'https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json'" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2UI_MIME_TYPE", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2UI_MIME_TYPE", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2UI_MIME_TYPE", + "syntaxKind": "VariableDeclaration", + "signature": "A2UI_MIME_TYPE = 'application/a2ui+json'" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2UI_WIRE_VERSION", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2UI_WIRE_VERSION", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2UI_WIRE_VERSION", + "syntaxKind": "VariableDeclaration", + "signature": "A2UI_WIRE_VERSION = 'v0.9'" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiAction", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiAction", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiAction", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiAction = A2uiEventAction | A2uiFunctionAction;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiActionMessage", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiActionMessage", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiActionMessage", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiActionMessage {\n version: string;\n action: {\n name: string;\n surfaceId: string;\n sourceComponentId: string;\n timestamp: string;\n context?: Record;\n label?: string;\n };\n metadata?: {\n a2uiClientDataModel?: A2uiClientDataModel;\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiAudioPlayerComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiAudioPlayerComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/audio-player.component.ts", + "symbol": "A2uiAudioPlayerComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-audio-player',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `\n
    \n @if (description()) {\n {{ description() }}\n }\n \n
    \n `,\n styles: [`\n .a2ui-audio-wrap {\n display: flex;\n flex-direction: column;\n gap: var(--a2ui-spacing-1);\n }\n .a2ui-audio-description {\n font-size: var(--a2ui-typography-caption-size);\n color: var(--a2ui-on-surface-variant);\n }\n .a2ui-audio {\n display: block;\n width: 100%;\n }\n `],\n})\nexport class A2uiAudioPlayerComponent {\n readonly url = input('');\n readonly description = input('');\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiButtonComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiButtonComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/button.component.ts", + "symbol": "A2uiButtonComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-button',\n standalone: true,\n imports: [RenderElementComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n \n @for (key of childKeys(); track key) {\n \n }\n \n `,\n styles: [`\n .a2ui-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: var(--a2ui-spacing-2) var(--a2ui-spacing-4);\n border-radius: var(--a2ui-shape-small);\n font-size: var(--a2ui-typography-body-size);\n font-weight: 500;\n cursor: pointer;\n transition: background var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard),\n opacity var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n border: none;\n }\n .a2ui-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n .a2ui-btn--primary {\n background: var(--a2ui-primary);\n color: var(--a2ui-on-primary);\n }\n .a2ui-btn--primary:hover:not(:disabled) { background: var(--a2ui-primary-hover); }\n .a2ui-btn--default {\n background: var(--a2ui-surface-variant);\n color: var(--a2ui-on-surface);\n border: 1px solid var(--a2ui-outline);\n }\n .a2ui-btn--default:hover:not(:disabled) { background: var(--a2ui-outline); }\n .a2ui-btn--borderless {\n background: transparent;\n color: var(--a2ui-on-surface);\n border: none;\n }\n .a2ui-btn--borderless:hover:not(:disabled) { background: var(--a2ui-surface-variant); }\n `],\n})\nexport class A2uiButtonComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly variant = input('default');\n readonly disabled = input(false);\n readonly emit = input<(event: string) => void>(() => { });\n readonly bindings = input>({});\n readonly loading = input(false);\n protected cssClass(): string {\n return VARIANT_CLASS[this.variant()] ?? VARIANT_CLASS['default'];\n }\n handleClick(): void {\n this.emit()('click');\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiCardComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiCardComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/card.component.ts", + "symbol": "A2uiCardComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-card',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n
    \n @for (key of childKeys(); track key) {\n \n }\n
    \n `,\n styles: [`\n .a2ui-card {\n display: flex;\n flex-direction: column;\n gap: var(--a2ui-spacing-2);\n border-radius: var(--a2ui-shape-medium);\n border: 1px solid var(--a2ui-outline);\n background: var(--a2ui-surface);\n padding: var(--a2ui-spacing-4);\n box-shadow: var(--a2ui-elevation-1);\n }\n `],\n})\nexport class A2uiCardComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiCatalogComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiCatalogComponent", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiCatalogComponent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiCatalogComponent = A2uiText | A2uiImage | A2uiIcon | A2uiVideo | A2uiAudioPlayer | A2uiRow | A2uiColumn | A2uiList | A2uiCard | A2uiTabs | A2uiModal | A2uiDivider | A2uiButton | A2uiCheckBox | A2uiTextField | A2uiDateTimeInput | A2uiChoicePicker | A2uiSlider;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiCheck", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiCheck", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiCheck", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiCheck {\n condition: DynamicValue;\n message: string;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiCheckBoxComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiCheckBoxComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/check-box.component.ts", + "symbol": "A2uiCheckBoxComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-check-box',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n \n @if (errorText()) {\n
    {{ errorText() }}
    \n }\n `,\n styles: [`\n .a2ui-cb {\n display: flex;\n align-items: center;\n gap: var(--a2ui-spacing-2);\n font-size: var(--a2ui-typography-body-size);\n cursor: pointer;\n }\n .a2ui-cb__input {\n width: 16px;\n height: 16px;\n border-radius: var(--a2ui-shape-extra-small);\n cursor: pointer;\n accent-color: var(--a2ui-primary);\n }\n .a2ui-check-error {\n font-size: var(--a2ui-typography-label-size);\n color: var(--a2ui-error, #d33d55);\n }\n`],\n})\nexport class A2uiCheckBoxComponent {\n private readonly host = injectRenderHost();\n readonly label = input('');\n readonly value = input(false);\n readonly errorText = input('');\n readonly _bindings = input>({});\n readonly bindings = input>({});\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n onChange(event: Event): void {\n const val = (event.target as HTMLInputElement).checked;\n emitBinding(this.host, this._bindings(), 'value', val);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiChildren", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiChildren", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiChildren", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiChildren = string[] | {\n path: string;\n componentId: string;\n};" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiChoicePickerComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiChoicePickerComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/choice-picker.component.ts", + "symbol": "A2uiChoicePickerComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-choice-picker',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
    \n @if (label()) {\n {{ label() }}\n }\n\n @if (filterable()) {\n \n }\n\n @if (displayStyle() === 'chips') {\n \n
    \n @for (opt of visibleOptions(); track opt.value) {\n {{ opt.label }}\n }\n
    \n } @else {\n \n
    \n @for (opt of visibleOptions(); track opt.value) {\n \n }\n
    \n }\n @if (errorText()) {\n
    {{ errorText() }}
    \n }\n
    \n `,\n styles: [`\n .a2ui-cp { display: flex; flex-direction: column; gap: var(--a2ui-spacing-1); }\n .a2ui-cp__label {\n font-size: var(--a2ui-typography-label-size);\n font-weight: var(--a2ui-typography-label-weight);\n color: var(--a2ui-label);\n }\n .a2ui-cp__filter {\n padding: var(--a2ui-spacing-1) var(--a2ui-spacing-2);\n font-size: var(--a2ui-typography-caption-size);\n border-radius: var(--a2ui-shape-small);\n background: var(--a2ui-input-bg);\n color: var(--a2ui-on-surface);\n border: 1px solid var(--a2ui-outline);\n outline: none;\n transition: border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n }\n .a2ui-cp__filter:focus {\n outline: var(--a2ui-focus-ring-width) solid var(--a2ui-focus-ring-color);\n outline-offset: 2px;\n border-color: var(--a2ui-primary);\n }\n .a2ui-cp__checks { display: flex; flex-direction: column; gap: var(--a2ui-spacing-2); }\n .a2ui-cp__check-row {\n display: flex;\n align-items: center;\n gap: var(--a2ui-spacing-2);\n font-size: var(--a2ui-typography-body-size);\n cursor: pointer;\n }\n .a2ui-cp__checkbox {\n width: 16px;\n height: 16px;\n border-radius: var(--a2ui-shape-extra-small);\n cursor: pointer;\n accent-color: var(--a2ui-primary);\n }\n .a2ui-cp__chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--a2ui-spacing-2);\n }\n .a2ui-cp__chip {\n padding: var(--a2ui-spacing-1) var(--a2ui-spacing-3);\n font-size: var(--a2ui-typography-body-size);\n border-radius: var(--a2ui-shape-large, 9999px);\n background: var(--a2ui-surface-variant);\n color: var(--a2ui-on-surface);\n border: 1px solid var(--a2ui-outline);\n cursor: pointer;\n transition: background var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard),\n border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n }\n .a2ui-cp__chip--selected {\n background: var(--a2ui-primary);\n color: var(--a2ui-on-primary);\n border-color: var(--a2ui-primary);\n }\n .a2ui-check-error {\n font-size: var(--a2ui-typography-label-size);\n color: var(--a2ui-error, #d33d55);\n }\n`],\n})\nexport class A2uiChoicePickerComponent {\n private static _idCounter = 0;\n protected readonly _groupName = `a2ui-choice-picker-${++A2uiChoicePickerComponent._idCounter}`;\n private readonly host = injectRenderHost();\n readonly label = input('');\n readonly value = input(undefined);\n readonly options = input([]);\n readonly variant = input<'mutuallyExclusive' | 'multipleSelection'>('mutuallyExclusive');\n readonly displayStyle = input<'checkbox' | 'chips'>('checkbox');\n readonly filterable = input(false);\n readonly errorText = input('');\n readonly _bindings = input>({});\n readonly bindings = input>({});\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected readonly valueArray = computed(() => {\n const v = this.value();\n if (Array.isArray(v))\n return v;\n if (v == null || v === '')\n return [];\n return [String(v)];\n });\n protected readonly isSingleSelect = computed(() => this.variant() !== 'multipleSelection');\n protected readonly filterText = signal('');\n protected readonly visibleOptions = computed(() => {\n const f = this.filterText().trim().toLowerCase();\n const opts = this.options();\n return f ? opts.filter(o => o.label.toLowerCase().includes(f)) : opts;\n });\n protected isSelected(value: string): boolean {\n return this.valueArray().includes(value);\n }\n onFilterInput(event: Event): void {\n this.filterText.set((event.target as HTMLInputElement).value);\n }\n onCheckChange(value: string, event: Event): void {\n const checked = (event.target as HTMLInputElement).checked;\n if (this.isSingleSelect()) {\n if (checked)\n emitBinding(this.host, this._bindings(), 'value', [value]);\n return;\n }\n emitBinding(this.host, this._bindings(), 'value', this.toggled(value, checked));\n }\n onChipToggle(value: string): void {\n if (this.isSingleSelect()) {\n emitBinding(this.host, this._bindings(), 'value', [value]);\n return;\n }\n const checked = !this.isSelected(value);\n emitBinding(this.host, this._bindings(), 'value', this.toggled(value, checked));\n }\n private toggled(value: string, checked: boolean): string[] {\n const current = [...this.valueArray()];\n const idx = current.indexOf(value);\n if (checked && idx === -1) {\n current.push(value);\n }\n else if (!checked && idx !== -1) {\n current.splice(idx, 1);\n }\n return current;\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiClientCapabilities", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiClientCapabilities", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiClientCapabilities", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiClientCapabilities {\n supportedCatalogIds: string[];\n inlineCatalogs?: unknown[];\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiClientDataModel", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiClientDataModel", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiClientDataModel", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiClientDataModel {\n surfaces: Record>;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiColumnComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiColumnComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/column.component.ts", + "symbol": "A2uiColumnComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-column',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n \n @for (key of childKeys(); track key) {\n \n }\n \n `,\n styles: [`\n .a2ui-col {\n display: flex;\n flex-direction: column;\n gap: var(--a2ui-spacing-3);\n }\n .a2ui-col--justify-stretch > render-element {\n flex: 1;\n }\n `],\n})\nexport class A2uiColumnComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly align = input('stretch');\n readonly justify = input('start');\n readonly gap = input(undefined);\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n protected readonly alignItems = computed(() => ALIGN_MAP[this.align()] ?? 'stretch');\n protected readonly justifyContent = computed(() => JUSTIFY_MAP[this.justify()] ?? 'flex-start');\n protected readonly cssClass = computed(() => this.justify() === 'stretch' ? 'a2ui-col a2ui-col--justify-stretch' : 'a2ui-col');\n protected readonly gapPx = computed(() => {\n const g = this.gap();\n if (typeof g === 'number' && Number.isFinite(g))\n return g * 4;\n if (g === 'small')\n return 8;\n if (g === 'medium')\n return 12;\n if (g === 'large')\n return 16;\n return null;\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiComponent", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiComponent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiComponent = A2uiCatalogComponent | (A2uiComponentBase & Record);" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiComponentBase", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiComponentBase", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiComponentBase", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiComponentBase {\n id: string;\n component: string;\n catalogId?: string;\n weight?: number;\n accessibility?: Record;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiComponentView", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiComponentView", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/component-view.ts", + "symbol": "A2uiComponentView", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiComponentView {\n readonly id: string;\n readonly type: string;\n readonly bindings: readonly string[];\n readonly ready: boolean;\n readonly props: Readonly>;\n readonly def: A2uiComponent;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiDateTimeInputComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiDateTimeInputComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/date-time-input.component.ts", + "symbol": "A2uiDateTimeInputComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-date-time-input',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
    \n @if (label()) {\n \n }\n \n @if (errorText()) {\n
    {{ errorText() }}
    \n }\n
    \n `,\n styles: [`\n .a2ui-dti { display: flex; flex-direction: column; gap: var(--a2ui-spacing-1); }\n .a2ui-dti__label {\n font-size: var(--a2ui-typography-label-size);\n font-weight: var(--a2ui-typography-label-weight);\n color: var(--a2ui-label);\n }\n .a2ui-dti__input {\n padding: var(--a2ui-spacing-2) var(--a2ui-spacing-3);\n font-size: var(--a2ui-typography-body-size);\n border-radius: var(--a2ui-shape-small);\n background: var(--a2ui-input-bg);\n color: var(--a2ui-on-surface);\n border: 1px solid var(--a2ui-outline);\n outline: none;\n transition: border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n }\n .a2ui-dti__input:focus {\n outline: var(--a2ui-focus-ring-width) solid var(--a2ui-focus-ring-color);\n outline-offset: 2px;\n border-color: var(--a2ui-primary);\n }\n .a2ui-check-error {\n font-size: var(--a2ui-typography-label-size);\n color: var(--a2ui-error, #d33d55);\n }\n`],\n})\nexport class A2uiDateTimeInputComponent {\n private static _idCounter = 0;\n protected readonly _inputId = `a2ui-date-time-input-${++A2uiDateTimeInputComponent._idCounter}`;\n private readonly host = injectRenderHost();\n readonly label = input('');\n readonly value = input('');\n readonly enableDate = input(true);\n readonly enableTime = input(false);\n readonly min = input(undefined);\n readonly max = input(undefined);\n readonly errorText = input('');\n readonly _bindings = input>({});\n readonly bindings = input>({});\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected readonly htmlInputType = computed(() => {\n const d = this.enableDate();\n const t = this.enableTime();\n if (d && t)\n return 'datetime-local';\n if (t)\n return 'time';\n return 'date';\n });\n onChange(event: Event): void {\n const val = (event.target as HTMLInputElement).value;\n emitBinding(this.host, this._bindings(), 'value', val);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiDividerComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiDividerComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/divider.component.ts", + "symbol": "A2uiDividerComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-divider',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `\n @if (orientation() === 'vertical') {\n
    \n } @else {\n
    \n }\n `,\n styles: [`\n .a2ui-divider--horizontal {\n display: block;\n width: 100%;\n border: none;\n border-top: 1px solid var(--a2ui-outline);\n margin: var(--a2ui-spacing-2) 0;\n }\n .a2ui-divider--vertical {\n display: inline-block;\n align-self: stretch;\n width: 1px;\n background: var(--a2ui-outline);\n margin: 0 var(--a2ui-spacing-2);\n }\n `],\n})\nexport class A2uiDividerComponent {\n readonly axis = input<'horizontal' | 'vertical'>('horizontal');\n protected readonly orientation = computed<'horizontal' | 'vertical'>(() => this.axis());\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiErrorMessage", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiErrorMessage", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiErrorMessage", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiErrorMessage {\n version: string;\n error: {\n code: string;\n surfaceId?: string;\n path?: string;\n message?: string;\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiEventAction", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiEventAction", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiEventAction", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiEventAction {\n event: {\n name: string;\n context?: Record;\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiFunctionAction", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiFunctionAction", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiFunctionAction", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiFunctionAction {\n functionCall: A2uiFunctionCall;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiFunctionCall", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiFunctionCall", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiFunctionCall", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiFunctionCall {\n call: string;\n args?: Record;\n returnType?: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'any' | 'void';\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiIconComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiIconComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/icon.component.ts", + "symbol": "A2uiIconComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-icon',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `\n @if (svgPath(); as path) {\n \n } @else if (ligatureName(); as name) {\n {{ glyphName() }}\n }\n `,\n styles: [`\n /* Renders Material Symbols by ligature name (A2UI's canonical icon set).\n Relies only on the Material Symbols Outlined @font-face being present —\n host apps load the stylesheet (see README). Unknown / not-yet-loaded\n names fall back to the browser default glyph. */\n .a2ui-icon {\n font-family: 'Material Symbols Outlined';\n font-weight: normal;\n font-style: normal;\n font-size: 1.125rem;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n white-space: nowrap;\n word-wrap: normal;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n color: currentColor;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n user-select: none;\n }\n .a2ui-icon--svg {\n width: 1.125rem;\n height: 1.125rem;\n }\n `],\n})\nexport class A2uiIconComponent {\n readonly name = input(undefined);\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected readonly svgPath = computed(() => {\n const n = this.name();\n return typeof n === 'object' && n !== null && typeof n.svgPath === 'string'\n ? n.svgPath\n : null;\n });\n protected readonly ligatureName = computed(() => typeof this.name() === 'string' ? (this.name() as string) : '');\n protected readonly glyphName = computed(() => toMaterialSymbolName(this.ligatureName()));\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiImageComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiImageComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/image.component.ts", + "symbol": "A2uiImageComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-image',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `\n \n `,\n styles: [`\n .a2ui-img {\n display: block;\n max-width: 100%;\n border-radius: var(--a2ui-shape-extra-small);\n }\n .a2ui-img--icon {\n width: 24px;\n height: 24px;\n }\n .a2ui-img--avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n }\n .a2ui-img--smallFeature {\n width: 120px;\n }\n .a2ui-img--mediumFeature {\n width: 240px;\n }\n .a2ui-img--largeFeature {\n width: 400px;\n }\n .a2ui-img--header {\n width: 100%;\n aspect-ratio: 16 / 5;\n }\n `],\n})\nexport class A2uiImageComponent {\n readonly url = input('');\n readonly description = input('');\n readonly fit = input('fill');\n readonly variant = input('mediumFeature');\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected readonly objectFit = computed(() => FIT_MAP[this.fit()] ?? 'fill');\n protected readonly cssClass = computed(() => `a2ui-img a2ui-img--${this.variant()}`);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiListComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiListComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/list.component.ts", + "symbol": "A2uiListComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-list',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n
    \n @for (key of childKeys(); track key) {\n \n }\n
    \n `,\n styles: [`\n .a2ui-list--vertical {\n display: flex;\n flex-direction: column;\n gap: var(--a2ui-spacing-1);\n overflow-y: auto;\n max-height: 384px;\n }\n .a2ui-list--horizontal {\n display: flex;\n flex-direction: row;\n gap: var(--a2ui-spacing-1);\n overflow-x: auto;\n }\n `],\n})\nexport class A2uiListComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly direction = input<'vertical' | 'horizontal'>('vertical');\n readonly align = input<'start' | 'center' | 'end' | 'stretch'>('stretch');\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n protected readonly listClass = computed(() => {\n return this.direction() === 'horizontal'\n ? 'a2ui-list--horizontal'\n : 'a2ui-list--vertical';\n });\n protected readonly alignmentCss = computed(() => {\n const a = this.align();\n return a === 'start' ? 'flex-start'\n : a === 'end' ? 'flex-end'\n : a;\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiModalComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiModalComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/modal.component.ts", + "symbol": "A2uiModalComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-modal',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n \n @if (entryPointKey(); as epKey) {\n \n \n \n }\n\n \n @if (open()) {\n \n \n
    \n @if (contentKey(); as cKey) {\n \n }\n
    \n \n }\n `,\n styles: [`\n .a2ui-modal__trigger {\n display: contents;\n }\n .a2ui-modal__overlay {\n position: fixed;\n inset: 0;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .a2ui-modal__backdrop {\n position: absolute;\n inset: 0;\n background: var(--a2ui-scrim);\n backdrop-filter: blur(4px);\n }\n .a2ui-modal__panel {\n position: relative;\n background: var(--a2ui-surface);\n border: 1px solid var(--a2ui-outline);\n border-radius: var(--a2ui-shape-medium);\n padding: var(--a2ui-spacing-5);\n max-width: 512px;\n width: 100%;\n margin: 0 var(--a2ui-spacing-4);\n box-shadow: var(--a2ui-elevation-4);\n }\n `],\n})\nexport class A2uiModalComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n protected readonly open = signal(false);\n protected readonly entryPointKey = computed(() => this.childKeys()[0] ?? null);\n protected readonly contentKey = computed(() => this.childKeys()[1] ?? null);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiPathRef", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiPathRef", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiPathRef", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiPathRef {\n path: string;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiRowComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiRowComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/row.component.ts", + "symbol": "A2uiRowComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-row',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n \n @for (key of childKeys(); track key) {\n \n }\n \n `,\n styles: [`\n .a2ui-row {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: var(--a2ui-spacing-3);\n }\n .a2ui-row--justify-stretch > render-element {\n flex: 1;\n }\n `],\n})\nexport class A2uiRowComponent {\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly align = input('stretch');\n readonly justify = input('start');\n readonly gap = input(undefined);\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n protected readonly alignItems = computed(() => ALIGN_MAP[this.align()] ?? 'stretch');\n protected readonly justifyContent = computed(() => JUSTIFY_MAP[this.justify()] ?? 'flex-start');\n protected readonly cssClass = computed(() => this.justify() === 'stretch' ? 'a2ui-row a2ui-row--justify-stretch' : 'a2ui-row');\n protected readonly gapPx = computed(() => {\n const g = this.gap();\n if (typeof g === 'number' && Number.isFinite(g))\n return g * 4;\n if (g === 'small')\n return 8;\n if (g === 'medium')\n return 12;\n if (g === 'large')\n return 16;\n return null;\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiSliderComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiSliderComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/slider.component.ts", + "symbol": "A2uiSliderComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-slider',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
    \n @if (label()) {\n \n }\n \n @if (errorText()) {\n
    {{ errorText() }}
    \n }\n
    \n `,\n styles: [`\n .a2ui-slider { display: flex; flex-direction: column; gap: var(--a2ui-spacing-1); }\n .a2ui-slider__label {\n font-size: var(--a2ui-typography-label-size);\n font-weight: var(--a2ui-typography-label-weight);\n color: var(--a2ui-label);\n }\n .a2ui-slider__input {\n width: 100%;\n cursor: pointer;\n accent-color: var(--a2ui-primary);\n }\n .a2ui-check-error {\n font-size: var(--a2ui-typography-label-size);\n color: var(--a2ui-error, #d33d55);\n }\n`],\n})\nexport class A2uiSliderComponent {\n private static _idCounter = 0;\n protected readonly _inputId = `a2ui-slider-${++A2uiSliderComponent._idCounter}`;\n private readonly host = injectRenderHost();\n readonly label = input('');\n readonly value = input(0);\n readonly min = input(0);\n readonly max = input(100);\n readonly errorText = input('');\n readonly _bindings = input>({});\n readonly bindings = input>({});\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n onInput(event: Event): void {\n const val = Number((event.target as HTMLInputElement).value);\n emitBinding(this.host, this._bindings(), 'value', val);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiSurface", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiSurface", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiSurface", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiSurface {\n surfaceId: string;\n catalogId: string;\n theme?: A2uiTheme;\n sendDataModel?: boolean;\n components: Map;\n dataModel: Record;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiSurfaceComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiSurfaceComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/surface.component.ts", + "symbol": "A2uiSurfaceComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-surface',\n standalone: true,\n imports: [\n RenderSpecComponent,\n A2uiDefaultFallbackComponent,\n NgComponentOutlet,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[style.--a2ui-primary]': 'primaryColor()',\n },\n styles: `\n .a2ui-surface-chrome {\n display: flex;\n align-items: center;\n gap: var(--a2ui-spacing-2);\n margin-bottom: var(--a2ui-spacing-2);\n color: var(--a2ui-label);\n font-size: var(--a2ui-typography-label-size);\n }\n .a2ui-surface-chrome img {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n object-fit: cover;\n }\n `,\n template: `\n @if (agentDisplayName() || iconUrl()) {\n
    \n @if (iconUrl(); as icon) {\n \"\"\n }\n @if (agentDisplayName(); as name) {\n {{ name }}\n }\n
    \n }\n @if (spec(); as s) {\n \n } @else if (state(); as st) {\n @if (surfaceFallback(); as fb) {\n \n } @else {\n \n }\n }\n `,\n})\nexport class A2uiSurfaceComponent {\n readonly surface = input();\n readonly state = input();\n readonly catalog = input.required();\n readonly handlers = input) => unknown | Promise>>({});\n readonly surfaceFallback = input | undefined>(undefined);\n readonly events = output();\n readonly action = output();\n readonly validationError = output();\n readonly liveStore = signalStateStore({});\n private readonly seeded = new Map();\n constructor() {\n effect(() => {\n const s = this.spec();\n const state = s?.state as Record | undefined;\n if (!state)\n return;\n untracked(() => {\n for (const [key, value] of Object.entries(state)) {\n const path = key.startsWith('/') ? key : `/${key}`;\n const current = this.liveStore.get(path);\n const untouched = current === undefined ||\n (this.seeded.has(path) && current === this.seeded.get(path));\n if (untouched) {\n if (current !== value)\n this.liveStore.set(path, value);\n this.seeded.set(path, value);\n }\n }\n });\n });\n }\n readonly primaryColor = computed(() => (this.state()?.surface ?? this.surface())?.theme?.primaryColor ?? null);\n protected readonly agentDisplayName = computed(() => (this.state()?.surface ?? this.surface())?.theme?.agentDisplayName ?? null);\n protected readonly iconUrl = computed(() => (this.state()?.surface ?? this.surface())?.theme?.iconUrl ?? null);\n readonly rootIds = computed(() => {\n const st = this.state();\n if (!st)\n return [];\n return [...st.componentViews.keys()].slice(0, 1);\n });\n readonly spec = computed(() => {\n const surf = this.state()?.surface ?? this.surface();\n return surf && surf.components.size > 0 ? surfaceToSpec(surf) : null;\n });\n readonly registry = computed(() => toRenderRegistry(this.catalog() as ViewRegistry));\n readonly internalHandlers = computed(() => {\n const consumerHandlers = this.handlers();\n return {\n 'a2ui:event': (params: Record) => {\n const surf = this.state()?.surface ?? this.surface();\n if (!surf)\n return undefined;\n const liveModel = this.mergedLiveModel(surf);\n const failures = evaluateSurfaceChecks(surf, liveModel);\n if (failures.length > 0) {\n for (const f of failures) {\n this.liveStore.set(`/_a2uiChecks/${f.componentId}`, f.message);\n }\n const first = failures[0];\n this.validationError.emit({\n version: A2UI_WIRE_VERSION,\n error: {\n code: 'VALIDATION_FAILED',\n surfaceId: surf.surfaceId,\n ...(first.path ? { path: first.path } : {}),\n message: first.message,\n },\n });\n return undefined;\n }\n for (const [id, comp] of surf.components) {\n if (componentHasChecks(comp as unknown as Record)) {\n this.liveStore.set(`/_a2uiChecks/${id}`, '');\n }\n }\n const rawContext = (params['context'] as Record) ?? {};\n const context: Record = {};\n for (const [k, v] of Object.entries(rawContext)) {\n if (v != null && typeof v === 'object' && '$bindState' in (v as Record)) {\n const path = String((v as Record)['$bindState']);\n context[k] = getByPointer(liveModel, path);\n }\n else {\n context[k] = v;\n }\n }\n const { _a2uiChecks, ...publicModel } = liveModel;\n void _a2uiChecks;\n const message = buildA2uiActionMessage({ ...params, context }, { ...surf, dataModel: publicModel });\n this.action.emit(message);\n return message;\n },\n 'a2ui:localAction': (params: Record) => {\n const call = params['call'] as string;\n const args = (params['args'] as Record) ?? {};\n if (consumerHandlers[call]) {\n return consumerHandlers[call](args);\n }\n if (call === 'openUrl' && typeof globalThis.window !== 'undefined') {\n globalThis.window.open(String(args['url'] ?? ''), '_blank', 'noopener');\n }\n return undefined;\n },\n };\n });\n onRenderEvent(event: RenderEvent): void {\n this.events.emit(event);\n }\n private mergedLiveModel(surf: A2uiSurface): Record {\n const snapshot = this.liveStore.getSnapshot() as Record;\n return deepOverlay(surf.dataModel, snapshot);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiSurfaceState", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiSurfaceState", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/surface-store.ts", + "symbol": "A2uiSurfaceState", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiSurfaceState {\n readonly surface: A2uiSurface;\n readonly componentViews: ReadonlyMap;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiSurfaceStore", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiSurfaceStore", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/surface-store.ts", + "symbol": "A2uiSurfaceStore", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiSurfaceStore {\n apply(message: A2uiMessage): void;\n applyPartialArgs(toolCallId: string, envelopes: readonly A2uiMessage[]): void;\n isPartialLive(toolCallId: string): boolean;\n readonly surfaces: Signal>;\n surface(surfaceId: string): Signal;\n readonly surfaceStates: Signal>;\n surfaceState(surfaceId: string): Signal;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiTabsComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiTabsComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/tabs.component.ts", + "symbol": "A2uiTabsComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-tabs',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [RenderElementComponent],\n template: `\n
    \n
    \n @for (title of tabTitles(); track $index) {\n {{ title }}\n }\n
    \n
    \n @if (activeChildKey(); as key) {\n \n }\n
    \n
    \n `,\n styles: [`\n .a2ui-tabs { display: flex; flex-direction: column; }\n .a2ui-tabs__tablist {\n display: flex;\n border-bottom: 1px solid var(--a2ui-outline);\n }\n .a2ui-tabs__tab {\n padding: var(--a2ui-spacing-2) var(--a2ui-spacing-4);\n font-size: var(--a2ui-typography-body-size);\n font-weight: 500;\n cursor: pointer;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n color: var(--a2ui-label);\n transition: color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard),\n border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n margin-bottom: -1px;\n }\n .a2ui-tabs__tab:hover { color: var(--a2ui-on-surface); }\n .a2ui-tabs__tab--active {\n border-bottom-color: var(--a2ui-primary);\n color: var(--a2ui-on-surface);\n }\n .a2ui-tabs__panel { padding-top: var(--a2ui-spacing-3); }\n `],\n})\nexport class A2uiTabsComponent {\n readonly tabTitles = input([]);\n readonly childKeys = input([]);\n readonly spec = input.required();\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n protected readonly activeIndex = signal(0);\n constructor() {\n effect(() => {\n const len = this.childKeys().length;\n if (this.activeIndex() >= len && len > 0)\n this.activeIndex.set(0);\n });\n }\n protected readonly activeChildKey = computed(() => {\n const idx = this.activeIndex();\n const keys = this.childKeys();\n return idx >= 0 && idx < keys.length ? keys[idx] : null;\n });\n selectTab(index: number): void {\n this.activeIndex.set(index);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiTextComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiTextComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/text.component.ts", + "symbol": "A2uiTextComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-text',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `{{ text() }}`,\n styles: [`\n .a2ui-text-h1 {\n display: block;\n font-size: var(--a2ui-typography-h1-size);\n font-weight: var(--a2ui-typography-h1-weight);\n line-height: var(--a2ui-typography-h1-line-height);\n margin: 0;\n }\n .a2ui-text-h2 {\n display: block;\n font-size: var(--a2ui-typography-h2-size);\n font-weight: var(--a2ui-typography-h2-weight);\n line-height: var(--a2ui-typography-h2-line-height);\n margin: 0;\n }\n .a2ui-text-h3 {\n display: block;\n font-size: var(--a2ui-typography-h3-size);\n font-weight: var(--a2ui-typography-h3-weight);\n line-height: var(--a2ui-typography-h3-line-height);\n margin: 0;\n }\n .a2ui-text-h4 {\n display: block;\n font-size: var(--a2ui-typography-h4-size);\n font-weight: var(--a2ui-typography-h4-weight);\n line-height: var(--a2ui-typography-h4-line-height);\n margin: 0;\n }\n .a2ui-text-h5 {\n display: block;\n font-size: var(--a2ui-typography-h5-size);\n font-weight: var(--a2ui-typography-h5-weight);\n line-height: var(--a2ui-typography-h5-line-height);\n margin: 0;\n }\n .a2ui-text-caption {\n display: block;\n font-size: var(--a2ui-typography-caption-size);\n font-weight: var(--a2ui-typography-caption-weight);\n color: var(--a2ui-caption);\n line-height: var(--a2ui-typography-caption-line-height);\n }\n .a2ui-text-body {\n display: block;\n font-size: var(--a2ui-typography-body-size);\n font-weight: var(--a2ui-typography-body-weight);\n line-height: var(--a2ui-typography-body-line-height);\n }\n `],\n})\nexport class A2uiTextComponent {\n readonly text = input('');\n readonly variant = input('body');\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected cssClass(): string {\n return `a2ui-text-${this.variant()}`;\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiTextFieldComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiTextFieldComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/text-field.component.ts", + "symbol": "A2uiTextFieldComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-text-field',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
    \n @if (label()) {\n \n }\n @if (variant() === 'longText') {\n \n } @else {\n \n }\n @if (errorText()) {\n
    {{ errorText() }}
    \n }\n
    \n `,\n styles: [`\n .a2ui-tf { display: flex; flex-direction: column; gap: var(--a2ui-spacing-1); }\n .a2ui-tf__label {\n font-size: var(--a2ui-typography-label-size);\n font-weight: var(--a2ui-typography-label-weight);\n color: var(--a2ui-label);\n }\n .a2ui-tf__input {\n padding: var(--a2ui-spacing-2) var(--a2ui-spacing-3);\n font-size: var(--a2ui-typography-body-size);\n border-radius: var(--a2ui-shape-small);\n background: var(--a2ui-input-bg);\n color: var(--a2ui-on-surface);\n border: 1px solid var(--a2ui-outline);\n outline: none;\n transition: border-color var(--a2ui-motion-duration-short) var(--a2ui-motion-easing-standard);\n resize: vertical;\n }\n .a2ui-tf__input:focus {\n outline: var(--a2ui-focus-ring-width) solid var(--a2ui-focus-ring-color);\n outline-offset: 2px;\n border-color: var(--a2ui-primary);\n }\n .a2ui-check-error {\n font-size: var(--a2ui-typography-label-size);\n color: var(--a2ui-error, #d33d55);\n }\n`],\n})\nexport class A2uiTextFieldComponent {\n private static _idCounter = 0;\n protected readonly _inputId = `a2ui-text-field-${++A2uiTextFieldComponent._idCounter}`;\n private readonly host = injectRenderHost();\n readonly label = input('');\n readonly value = input('');\n readonly placeholder = input('');\n readonly variant = input('shortText');\n readonly validationRegexp = input('');\n readonly errorText = input('');\n readonly _bindings = input>({});\n readonly bindings = input>({});\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n protected readonly htmlInputType = computed(() => TYPE_MAP[this.variant()] ?? 'text');\n onInput(event: Event): void {\n const val = (event.target as HTMLInputElement | HTMLTextAreaElement).value;\n emitBinding(this.host, this._bindings(), 'value', val);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiTheme", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiTheme", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "A2uiTheme", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface A2uiTheme {\n primaryColor?: string;\n iconUrl?: string;\n agentDisplayName?: string;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiVideoComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiVideoComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/video.component.ts", + "symbol": "A2uiVideoComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'a2ui-video',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.Default,\n template: `\n \n `,\n styles: [`\n .a2ui-video {\n display: block;\n width: 100%;\n border-radius: var(--a2ui-shape-small);\n }\n `],\n})\nexport class A2uiVideoComponent {\n readonly url = input('');\n readonly bindings = input>({});\n readonly emit = input<(event: string) => void>(() => { });\n readonly loading = input(false);\n readonly childKeys = input([]);\n readonly spec = input(undefined);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiViewEntry", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiViewEntry", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/views.ts", + "symbol": "A2uiViewEntry", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiViewEntry = RenderViewEntry;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiViews", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "A2uiViews", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/views.ts", + "symbol": "A2uiViews", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type A2uiViews = Readonly | A2uiViewEntry>>;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AGENT_ERROR_MESSAGES", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AGENT_ERROR_MESSAGES", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-error.ts", + "symbol": "AGENT_ERROR_MESSAGES", + "syntaxKind": "VariableDeclaration", + "signature": "AGENT_ERROR_MESSAGES: Record = {\n connection: \"Can't reach the server. Check your connection and try again.\",\n auth: 'Authentication failed. Check your API key or credentials.',\n server: 'The server ran into an error. You can try again.',\n interrupted: 'The response was interrupted. Try again.',\n aborted: 'Stopped.',\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AGENT_RECOVERY_DETAILS", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AGENT_RECOVERY_DETAILS", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-error.ts", + "symbol": "AGENT_RECOVERY_DETAILS", + "syntaxKind": "VariableDeclaration", + "signature": "AGENT_RECOVERY_DETAILS: Record = {\n retry: 'Nothing reached the server, so nothing was duplicated.',\n check: 'Checking will tell you whether it did.',\n none: 'Trying again could repeat it.',\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AGENT_RECOVERY_MESSAGES", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AGENT_RECOVERY_MESSAGES", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-error.ts", + "symbol": "AGENT_RECOVERY_MESSAGES", + "syntaxKind": "VariableDeclaration", + "signature": "AGENT_RECOVERY_MESSAGES: Record = {\n retry: 'The response was interrupted before it started. Try again.',\n check: 'The connection dropped. The request may still have completed on the server.',\n none: 'The connection dropped. We could not confirm whether the request completed.',\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#Agent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "Agent", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent.ts", + "symbol": "Agent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface Agent {\n messages: Signal;\n status: Signal;\n isLoading: Signal;\n isInputBlocked?: Signal;\n error: Signal;\n toolCalls: Signal;\n state: Signal;\n submit: (input: AgentSubmitInput, opts?: AgentSubmitOptions) => Promise;\n stop: () => Promise;\n retry: () => Promise;\n regenerate: (assistantMessageIndex: number) => Promise;\n interrupt?: Signal;\n subagents?: Signal>;\n clientTools?: ClientToolsCapability;\n checkStatus?: () => Promise;\n events$: Observable;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentCheckpoint", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentCheckpoint", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-checkpoint.ts", + "symbol": "AgentCheckpoint", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentCheckpoint {\n id?: string;\n label?: string;\n values: Record;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentCustomEvent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentCustomEvent", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-event.ts", + "symbol": "AgentCustomEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentCustomEvent {\n readonly type: 'custom';\n readonly name: string;\n readonly data: unknown;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentError", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentError", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-error.ts", + "symbol": "AgentError", + "syntaxKind": "ClassDeclaration", + "signature": "export class AgentError extends Error {\n readonly kind: AgentErrorKind;\n readonly retryable: boolean;\n readonly status?: number;\n override readonly cause: unknown;\n readonly recovery?: AgentRecovery;\n readonly detail?: string;\n constructor(init: {\n kind: AgentErrorKind;\n message: string;\n retryable: boolean;\n status?: number;\n cause?: unknown;\n recovery?: AgentRecovery;\n detail?: string;\n }) {\n super(init.message);\n this.name = 'AgentError';\n this.kind = init.kind;\n this.retryable = init.retryable;\n this.status = init.status;\n this.cause = init.cause;\n this.recovery = init.recovery;\n this.detail = init.detail;\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentErrorKind", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentErrorKind", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-error.ts", + "symbol": "AgentErrorKind", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type AgentErrorKind = 'connection' | 'auth' | 'server' | 'interrupted' | 'aborted';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentEvent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentEvent", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-event.ts", + "symbol": "AgentEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type AgentEvent = AgentStateUpdateEvent | AgentCustomEvent;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentInterrupt", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentInterrupt", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-interrupt.ts", + "symbol": "AgentInterrupt", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentInterrupt {\n id: string;\n value: unknown;\n resumable: boolean;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRecovery", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentRecovery", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-error.ts", + "symbol": "AgentRecovery", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type AgentRecovery = 'retry' | 'check' | 'none';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRef", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentRef", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-ref.ts", + "symbol": "AgentRef", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentRef {\n readonly token: InjectionToken>;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRuntimeTelemetryEvent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentRuntimeTelemetryEvent", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/runtime-telemetry.ts", + "symbol": "AgentRuntimeTelemetryEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type AgentRuntimeTelemetryEvent = 'tplane:runtime_instance_created' | 'tplane:runtime_request_created' | 'tplane:stream_started' | 'tplane:stream_ended' | 'tplane:stream_errored';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRuntimeTelemetryPayload", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentRuntimeTelemetryPayload", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/runtime-telemetry.ts", + "symbol": "AgentRuntimeTelemetryPayload", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentRuntimeTelemetryPayload {\n event: AgentRuntimeTelemetryEvent;\n properties: AgentRuntimeTelemetryProperties;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRuntimeTelemetryProperties", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentRuntimeTelemetryProperties", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/runtime-telemetry.ts", + "symbol": "AgentRuntimeTelemetryProperties", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentRuntimeTelemetryProperties {\n transport: 'langgraph' | 'ag-ui' | 'custom' | string;\n surface?: string;\n requestType?: string;\n provider?: string;\n model?: string;\n durationMs?: number;\n errorClass?: string;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRuntimeTelemetrySink", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentRuntimeTelemetrySink", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/runtime-telemetry.ts", + "symbol": "AgentRuntimeTelemetrySink", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type AgentRuntimeTelemetrySink = (payload: AgentRuntimeTelemetryPayload) => void | Promise;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentStateUpdateEvent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentStateUpdateEvent", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-event.ts", + "symbol": "AgentStateUpdateEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentStateUpdateEvent {\n readonly type: 'state_update';\n readonly data: Record;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentStatus", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentStatus", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-status.ts", + "symbol": "AgentStatus", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type AgentStatus = 'idle' | 'running' | 'error';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentSubmitInput", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentSubmitInput", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-submit.ts", + "symbol": "AgentSubmitInput", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentSubmitInput {\n message?: string | ContentBlock[];\n resume?: unknown;\n state?: Record;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentSubmitOptions", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentSubmitOptions", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-submit.ts", + "symbol": "AgentSubmitOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentSubmitOptions {\n signal?: AbortSignal;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentWithHistory", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AgentWithHistory", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-with-history.ts", + "symbol": "AgentWithHistory", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentWithHistory extends Agent {\n history: Signal;\n messageCheckpoints?: Signal>;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AnyFunctionToolDef", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AnyFunctionToolDef", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "AnyFunctionToolDef", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AnyFunctionToolDef {\n readonly kind: 'function';\n readonly description: string;\n readonly schema: StandardSchemaV1;\n readonly followUp?: boolean;\n readonly idempotent?: boolean;\n readonly handler: (args: any, context: FunctionToolHandlerContext) => unknown | Promise;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#AskToolDef", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "AskToolDef", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "AskToolDef", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AskToolDef {\n readonly kind: 'ask';\n readonly description: string;\n readonly schema: S;\n readonly followUp?: boolean;\n readonly component: Type;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#CHAT_LIFECYCLE", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "CHAT_LIFECYCLE", + "declarations": [ + { + "path": "libs/chat/src/lib/lifecycle.ts", + "symbol": "CHAT_LIFECYCLE", + "syntaxKind": "VariableDeclaration", + "signature": "CHAT_LIFECYCLE = new InjectionToken('CHAT_LIFECYCLE')" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatApprovalAction", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatApprovalAction", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-approval-card/chat-approval-card.component.ts", + "symbol": "ChatApprovalAction", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ChatApprovalAction = 'approve' | 'edit' | 'cancel';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatApprovalCardComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatApprovalCardComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-approval-card/chat-approval-card.component.ts", + "symbol": "ChatApprovalCardComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-approval-card',\n standalone: true,\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_HOST_TOKENS,\n `\n :host { display: contents; }\n dialog.chat-approval-card {\n width: 440px;\n max-width: calc(100vw - 32px);\n /* Center in the viewport. The UA stylesheet sets margin:auto on open\n modal dialogs, but our reset properties below shadow it. Re-assert. */\n margin: auto;\n padding: 0;\n border: 0;\n border-radius: 12px;\n background: var(--tplane-chat-surface);\n color: var(--tplane-chat-text);\n box-shadow: 0 20px 50px rgba(0,0,0,0.18);\n }\n dialog.chat-approval-card::backdrop {\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n }\n .chat-approval-card__header {\n padding: 14px 16px 12px;\n display: flex;\n align-items: center;\n gap: 8px;\n border-bottom: 1px solid var(--tplane-chat-separator);\n }\n .chat-approval-card__header h4 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--tplane-chat-text);\n }\n .chat-approval-card__header svg {\n color: var(--tplane-chat-warning-text);\n width: 16px;\n height: 16px;\n flex: 0 0 16px;\n }\n .chat-approval-card__body {\n padding: 14px 16px;\n font-size: var(--tplane-chat-font-size-sm, 13px);\n color: var(--tplane-chat-text);\n }\n .chat-approval-card__actions {\n padding: 8px 16px 14px;\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n align-items: center;\n }\n .btn {\n border: 0;\n padding: 6px 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: transform 200ms ease, opacity 200ms ease;\n }\n .btn:hover { transform: scale(1.03); }\n .btn-primary { background: var(--tplane-chat-primary); color: var(--tplane-chat-on-primary); }\n .btn-secondary { background: transparent; color: var(--tplane-chat-text); border: 1px solid var(--tplane-chat-separator); }\n .btn-text {\n background: transparent;\n color: var(--tplane-chat-text-muted);\n padding: 6px 10px;\n }\n .btn-text:hover { color: var(--tplane-chat-text); }\n `,\n ],\n template: `\n \n
    \n \n

    {{ title() }}

    \n
    \n
    \n @if (bodyTemplate(); as tpl) {\n @if (payload(); as p) {\n \n }\n }\n
    \n
    \n \n @if (showEdit()) {\n \n }\n \n
    \n
    \n `,\n})\nexport class ChatApprovalCardComponent {\n readonly agent = input.required();\n readonly matchKind = input(undefined);\n readonly title = input('Approval required');\n readonly showEdit = input(false);\n readonly action = output();\n protected readonly bodyTemplate = contentChild>('body');\n private readonly dialogRef = viewChild>('dialogEl');\n private readonly interrupt = computed(() => this.agent().interrupt?.());\n protected readonly payload = computed(() => {\n const i = this.interrupt();\n if (!i)\n return undefined;\n const v = i.value as {\n kind?: unknown;\n } | undefined;\n const want = this.matchKind();\n if (want !== undefined) {\n if (!v || typeof v !== 'object' || (v as {\n kind?: unknown;\n }).kind !== want) {\n return undefined;\n }\n }\n return v;\n });\n constructor() {\n effect(() => {\n const p = this.payload();\n const dialog = this.dialogRef()?.nativeElement;\n if (!dialog)\n return;\n if (p && !dialog.open) {\n dialog.showModal();\n }\n else if (!p && dialog.open) {\n dialog.close();\n }\n });\n }\n protected emit(action: ChatApprovalAction): void {\n this.action.emit(action);\n if (action !== 'edit') {\n this.closeDialog();\n }\n }\n protected onCancelEvent(ev: Event): void {\n ev.preventDefault();\n this.action.emit('cancel');\n this.closeDialog();\n }\n private closeDialog(): void {\n const dialog = this.dialogRef()?.nativeElement;\n if (!dialog)\n return;\n if (dialog.open)\n dialog.close();\n }\n protected onDialogClose(): void {\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatCitationCardTemplateDirective", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatCitationCardTemplateDirective", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts", + "symbol": "ChatCitationCardTemplateDirective", + "syntaxKind": "ClassDeclaration", + "signature": "@Directive({ selector: 'ng-template[chatCitationCard]', standalone: true })\nexport class ChatCitationCardTemplateDirective {\n readonly tpl = inject>(TemplateRef);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatCitationPreviewComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatCitationPreviewComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citation-preview.component.ts", + "symbol": "ChatCitationPreviewComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-citation-preview',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_CITATION_PREVIEW_STYLES],\n template: `\n
    \n
    \n @if (sourceIconUrl(); as icon) {\n \"\"\n } @else if (sourceIcon(); as icon) {\n \n \n @switch (icon) {\n @case ('file') {\n \n \n }\n @case ('app') {\n \n \n }\n @case ('memory') {\n \n \n }\n @case ('web') {\n \n \n }\n @default {\n \n \n }\n }\n \n \n } @else {\n {{ sourceMonogram() }}\n }\n @if (domain(); as d) { {{ d }} }\n @if (typeLabel(); as t) {\n {{ t }}\n }\n
    \n @if (citation().title; as title) {\n

    {{ title }}

    \n }\n @if (citation().snippet; as s) {\n

    {{ s }}

    \n }\n @if (citation().url; as url) {\n
    \n \n \n \n \n Open source\n \n @if (published(); as p) { {{ p }} }\n
    \n }\n
    \n `,\n})\nexport class ChatCitationPreviewComponent {\n readonly citation = input.required();\n private readonly sourceVisual = computed(() => citationSourceVisual(this.citation()));\n private readonly typeMeta = computed(() => citationTypeMeta(this.citation()));\n protected readonly domain = computed(() => deriveDomain(this.citation().url));\n protected readonly sourceIconUrl = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'image' ? visual.iconUrl : null;\n });\n protected readonly sourceIcon = computed((): CitationTypeIcon | null => {\n const visual = this.sourceVisual();\n return visual.kind === 'type-icon' ? visual.icon : null;\n });\n protected readonly sourceMonogram = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'monogram' ? visual.monogram : null;\n });\n protected readonly sourceMonoColor = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'monogram' ? visual.color : null;\n });\n protected readonly typeLabel = computed(() => this.typeMeta().label);\n protected readonly typeTone = computed(() => this.typeMeta().tone);\n protected readonly published = computed(() => formatPublished(this.citation().publishedAt));\n protected isTypeTone(tone: CitationTypeIcon): boolean {\n return this.typeTone() === tone;\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatCitationsCardComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatCitationsCardComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citations-card.component.ts", + "symbol": "ChatCitationsCardComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-citations-card',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet],\n styles: [CHAT_HOST_TOKENS, CHAT_CITATIONS_PANEL_STYLES],\n template: `\n @if (citation().url; as url) {\n \n \n \n } @else {\n
    \n \n
    \n }\n\n \n {{ citation().index }}\n \n \n @if (sourceIconUrl(); as icon) {\n \"\"\n } @else if (sourceIcon(); as icon) {\n \n \n @switch (icon) {\n @case ('file') {\n \n \n }\n @case ('app') {\n \n \n }\n @case ('memory') {\n \n \n }\n @case ('web') {\n \n \n }\n @default {\n \n \n }\n }\n \n \n } @else {\n {{ sourceMonogram() }}\n }\n @if (domain(); as d) { {{ d }} }\n @if (typeLabel(); as t) {\n {{ t }}\n }\n \n @if (title(); as t) {\n {{ t }}\n }\n @if (citation().snippet; as s) {\n {{ s }}\n }\n \n \n `,\n})\nexport class ChatCitationsCardComponent {\n readonly citation = input.required();\n private readonly sourceVisual = computed(() => citationSourceVisual(this.citation()));\n private readonly typeMeta = computed(() => citationTypeMeta(this.citation()));\n protected readonly domain = computed(() => deriveDomain(this.citation().url));\n protected readonly title = computed(() => this.citation().title ?? this.citation().url ?? null);\n protected readonly sourceIconUrl = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'image' ? visual.iconUrl : null;\n });\n protected readonly sourceIcon = computed((): CitationTypeIcon | null => {\n const visual = this.sourceVisual();\n return visual.kind === 'type-icon' ? visual.icon : null;\n });\n protected readonly sourceMonogram = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'monogram' ? visual.monogram : null;\n });\n protected readonly sourceMonoColor = computed(() => {\n const visual = this.sourceVisual();\n return visual.kind === 'monogram' ? visual.color : null;\n });\n protected readonly typeLabel = computed(() => this.typeMeta().label);\n protected readonly typeTone = computed(() => this.typeMeta().tone);\n protected isTypeTone(tone: CitationTypeIcon): boolean {\n return this.typeTone() === tone;\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatCitationsComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatCitationsComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts", + "symbol": "ChatCitationsComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-citations',\n standalone: true,\n imports: [NgTemplateOutlet, ChatCitationsCardComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_CITATIONS_PANEL_STYLES],\n template: `\n @if (citations().length > 0) {\n
    \n \n {{ heading() }}\n {{ citations().length }}\n \n @for (f of favstack(); track f.id) {\n @if (f.kind === 'image' && f.iconUrl) {\n \"\"\n } @else if (f.kind === 'type-icon' && f.icon) {\n \n \n @switch (f.icon) {\n @case ('file') {\n \n \n }\n @case ('app') {\n \n \n }\n @case ('memory') {\n \n \n }\n @case ('web') {\n \n \n }\n @default {\n \n \n }\n }\n \n \n } @else {\n {{ f.monogram }}\n }\n }\n \n \n \n \n \n @if (expanded()) {\n
      \n @for (c of citations(); track c.id) {\n
    • \n @if (cardTpl) {\n \n } @else {\n \n }\n
    • \n }\n
    \n }\n
    \n }\n `,\n})\nexport class ChatCitationsComponent {\n readonly message = input.required();\n readonly heading = input('Sources');\n protected readonly expanded = signal(false);\n protected readonly listId = `chat-citations-list-${nextCitationsId++}`;\n @ContentChild(ChatCitationCardTemplateDirective)\n cardTpl: ChatCitationCardTemplateDirective | null = null;\n private readonly resolver = inject(CitationsResolverService, { optional: true });\n protected readonly citations = computed(() => {\n const fromMessage = this.message().citations ?? [];\n const seenIds = new Set(fromMessage.map((c) => c.id));\n const fromMarkdown: Citation[] = [];\n const mdDefs = this.resolver?.markdownDefs();\n if (mdDefs) {\n for (const def of mdDefs.values()) {\n if (!seenIds.has(def.id))\n fromMarkdown.push(mdDefToCitation(def));\n }\n }\n return [...fromMessage, ...fromMarkdown].sort((a, b) => a.index - b.index);\n });\n protected readonly favstack = computed(() => this.citations().slice(0, 3).map((c) => ({ id: c.id, ...citationSourceVisual(c) })));\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat/chat.component.ts", + "symbol": "ChatComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat',\n standalone: true,\n imports: [\n KeyValuePipe,\n ChatWindowComponent, ChatMessageListComponent, MessageTemplateDirective, ChatMessageComponent,\n ChatInputComponent, ChatTypingIndicatorComponent, ChatErrorComponent,\n ChatThreadListComponent, ChatGenerativeUiComponent,\n ChatStreamingMdComponent, ChatToolCallsComponent, ChatToolViewsComponent, A2uiSurfaceComponent,\n ChatMessageActionsComponent, ChatWelcomeComponent, ChatSelectComponent, ChatReasoningComponent,\n ChatScrollBubbleComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n { provide: CHAT_LIFECYCLE, useFactory: createChatLifecycle },\n {\n provide: DEVELOPMENT_COLLECTION_POLICY,\n useFactory: () => {\n const host = inject(ChatComponent);\n const parent = inject(DEVELOPMENT_COLLECTION_POLICY, { optional: true, skipSelf: true });\n return () => (parent?.() ?? true) && isDevelopmentRuntimeEnabled(host.agent());\n },\n },\n ],\n styles: [CHAT_HOST_TOKENS, `\n :host {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n height: 100%;\n min-height: 0;\n max-height: 100%;\n overflow: hidden;\n background: var(--tplane-chat-bg);\n }\n :host > chat-welcome {\n display: flex;\n flex: 1 1 auto;\n width: 100%;\n }\n .chat-shell { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .chat-shell__sidebar {\n width: 240px;\n flex-shrink: 0;\n border-right: 1px solid var(--tplane-chat-separator);\n background: var(--tplane-chat-surface-alt);\n overflow-y: auto;\n display: none;\n }\n @media (min-width: 768px) { .chat-shell__sidebar { display: block; } }\n .chat-shell__main { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 0; }\n .chat-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 60px 20px;\n color: var(--tplane-chat-text-muted);\n text-align: center;\n flex: 1;\n min-height: 0;\n }\n .chat-empty[hidden] { display: none; }\n .chat-empty__title { font-size: 1.125rem; font-weight: 500; color: var(--tplane-chat-text); margin: 0; }\n .chat-empty__sub { margin: 0; font-size: var(--tplane-chat-font-size-sm); }\n .chat-empty__title { font-size: 1.125rem; font-weight: 500; color: var(--tplane-chat-text); margin: 0; }\n .chat-empty__sub { margin: 0; font-size: var(--tplane-chat-font-size-sm); }\n .chat-scroll { flex: 1; min-height: 0; overflow-y: auto; padding-top: var(--tplane-chat-edge-pad); }\n .chat-scroll::-webkit-scrollbar { width: 6px; }\n .chat-scroll::-webkit-scrollbar-thumb { background: var(--tplane-chat-separator); border-radius: 10px; }\n [chatFooter] {\n padding-bottom: var(--tplane-chat-edge-pad);\n }\n .chat-footer-wrap { position: relative; }\n `],\n template: `\n @if (showWelcome()) {\n \n \n @if (showModelPicker() && modelOptions().length > 0) {\n \n }\n \n \n \n \n \n } @else {\n
    \n @if (threads().length > 0) {\n \n }\n
    \n \n \n
    \n \n \n {{ humanContent(message) }}\n \n\n \n @let content = messageContent(message);\n @let classified = classifyMessage(content, message);\n \n \n @if (message.reasoning && reasoningRunStart(i)) {\n @let run = reasoningRun(i);\n \n }\n \n \n \n \n \n \n @if (classified.markdown(); as md) {\n \n }\n @if (classified.spec(); as spec) {\n \n \n }\n @if (classified.type() === 'a2ui' && views(); as catalog) {\n @for (entry of classified.a2uiSurfaces() | keyvalue; track entry.key) {\n \n }\n }\n \n @if (content.trim()) {\n \n }\n \n \n\n \n \n \n\n \n {{ messageContent(message) }}\n \n \n\n \n @if (pinned() && !currentAssistantStreaming()) {\n \n }\n
    \n \n
    \n
    \n
    \n }\n `,\n})\nexport class ChatComponent {\n readonly agent = input.required();\n readonly views = input(undefined);\n readonly clientTools = input(undefined);\n readonly store = input(undefined);\n readonly handlers = input) => unknown | Promise>>({});\n readonly threads = input([]);\n readonly activeThreadId = input('');\n readonly welcomeDisabled = input(false);\n readonly modelOptions = input([]);\n readonly showModelPicker = input(true);\n readonly selectedModel = model('');\n readonly modelPickerPlaceholder = input('Choose a model');\n readonly genuiToolNames = input([\n 'generate_a2ui_schema',\n 'generate_json_render_spec',\n 'render_spec',\n ]);\n readonly clientToolExecutionGuard = input(undefined);\n readonly clientToolContinuationPolicy = input(undefined);\n readonly showWelcome = computed(() => {\n if (this.welcomeDisabled())\n return false;\n const a = this.agent() as unknown as {\n isThreadLoading?: () => boolean;\n };\n if (a.isThreadLoading?.())\n return false;\n return this.agent().messages().length === 0;\n });\n readonly threadSelected = output();\n readonly renderEvent = output();\n readonly clientToolContinuationLimit = output();\n readonly regenerate = output();\n readonly rate = output<{\n messageIndex: number;\n rating: 'up' | 'down';\n }>();\n readonly messageCopy = output<{\n messageIndex: number;\n content: string;\n }>();\n private readonly _internalStore = signalStateStore({});\n readonly resolvedStore = computed(() => {\n const explicit = this.store();\n if (explicit)\n return explicit;\n if (this.effectiveViews())\n return this._internalStore;\n return undefined;\n });\n private readonly coordinator = computed(() => {\n const reg = this.clientTools();\n const policy = this.clientToolContinuationPolicy();\n return reg ? createClientToolsCoordinator(reg, {\n executionGuard: this.clientToolExecutionGuard(),\n continuationPolicy: {\n ...policy,\n onLimit: (event) => {\n policy?.onLimit?.(event);\n this.clientToolContinuationLimit.emit(event);\n },\n },\n }) : undefined;\n });\n protected readonly effectiveViews = computed(() => {\n const base = this.views();\n const coord = this.coordinator();\n if (!coord)\n return base;\n return base ? withViews(base, coord.viewRegistry) : coord.viewRegistry;\n });\n readonly renderRegistry = computed(() => {\n const v = this.views();\n return v ? toRenderRegistry(v) : undefined;\n });\n readonly viewToolNames = computed(() => Object.keys(this.effectiveViews() ?? {}));\n readonly excludedToolNames = computed(() => [\n ...this.genuiToolNames(),\n ...this.viewToolNames(),\n ]);\n readonly messageContent = messageContent;\n protected humanContent(message: {\n content: unknown;\n }): string {\n const raw = messageContent(message);\n return a2uiActionLabel(raw) ?? raw;\n }\n private prevAssistant(msgs: Message[], index: number): Message | undefined {\n for (let j = index - 1; j >= 0; j--) {\n if (msgs[j].role === 'tool')\n continue;\n return msgs[j].role === 'assistant' ? msgs[j] : undefined;\n }\n return undefined;\n }\n protected reasoningRunStart(index: number): boolean {\n const msgs = this.agent().messages();\n if (!msgs[index]?.reasoning)\n return false;\n return !this.prevAssistant(msgs, index)?.reasoning;\n }\n protected reasoningRun(index: number): {\n content: string;\n durationMs: number | undefined;\n delivery: MessageDelivery;\n label: string | undefined;\n } {\n const msgs = this.agent().messages();\n const steps: Message[] = [];\n for (let j = index; j < msgs.length; j++) {\n const m = msgs[j];\n if (m.role === 'tool')\n continue;\n if (m.role === 'assistant' && m.reasoning) {\n steps.push(m);\n continue;\n }\n break;\n }\n const content = steps.map((step) => step.reasoning ?? '').filter(Boolean).join('\\n\\n');\n const durations = steps\n .map((step) => step.reasoningDurationMs)\n .filter((d): d is number => typeof d === 'number');\n const durationMs = durations.length ? durations.reduce((a, b) => a + b, 0) : undefined;\n const last = steps[steps.length - 1];\n const delivery = last?.delivery ?? msgs[index].delivery;\n const label = steps.length > 1\n ? durationMs !== undefined\n ? `Thought for ${formatDuration(durationMs)} · ${steps.length} steps`\n : `${steps.length} steps`\n : undefined;\n return { content, durationMs, delivery, label };\n }\n private readonly classifiers = new Map();\n private readonly markdownDocuments = new Map();\n private readonly destroyRef = inject(DestroyRef);\n private readonly injector = inject(Injector);\n private readonly lifecycle = (inject(CHAT_LIFECYCLE, { optional: true }) ?? createChatLifecycle()) as ChatLifecycleInternal;\n private eventsSubscribed = false;\n protected readonly liveSurfaceStore: A2uiSurfaceStore = createA2uiSurfaceStore();\n private readonly partialBridge: PartialArgsBridge = createPartialArgsBridge(this.liveSurfaceStore);\n private partialEventsLastIndex = 0;\n private readonly scrollContainer = viewChild>('scrollContainer');\n private readonly messageCount = computed(() => this.agent().messages().length);\n private prevMessageCount = 0;\n private wasLoading = false;\n protected readonly pinned = signal(true);\n private programmaticScrollCount = 0;\n private static readonly PIN_TOLERANCE_PX = 150;\n protected readonly currentAssistantStreaming = computed(() => {\n const msgs = this.agent().messages();\n if (msgs.length === 0)\n return false;\n const last = msgs[msgs.length - 1];\n return last?.role === 'assistant' && last.delivery.phase === 'streaming';\n });\n constructor() {\n ensureChatRootStyles();\n effect(() => {\n if (this.eventsSubscribed)\n return;\n let agent: ReturnType;\n try {\n agent = this.agent();\n }\n catch {\n return;\n }\n this.eventsSubscribed = true;\n this.lifecycle._internal.componentReady.set(true);\n agent.events$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {\n if (event.type !== 'state_update')\n return;\n const store = this.resolvedStore();\n if (!store)\n return;\n store.update(event.data);\n });\n });\n effect(() => {\n let agentRef: ReturnType;\n try {\n agentRef = this.agent();\n }\n catch {\n return;\n }\n const stateFn = (agentRef as unknown as {\n state?: () => unknown;\n }).state;\n if (typeof stateFn !== 'function')\n return;\n const state = stateFn.call(agentRef);\n const store = this.resolvedStore();\n if (!store || state == null || typeof state !== 'object' || Array.isArray(state))\n return;\n const updates: Record = {};\n for (const [k, v] of Object.entries(state as Record)) {\n if (k === 'messages')\n continue;\n updates['/' + k] = v;\n }\n if (Object.keys(updates).length > 0)\n store.update(updates);\n });\n effect(() => {\n let agentRef: ReturnType;\n try {\n agentRef = this.agent();\n }\n catch {\n return;\n }\n const lc = (agentRef as unknown as {\n lifecycle?: {\n streamStartedAt?: () => number | null;\n };\n }).lifecycle;\n const streamStartedAt = lc?.streamStartedAt?.();\n if (streamStartedAt != null && !this.lifecycle._internal.firstMessageSent()) {\n this.lifecycle._internal.firstMessageSent.set(true);\n }\n });\n effect(() => {\n let count: number;\n let msgs: ReturnType['messages']>;\n try {\n count = this.messageCount();\n msgs = this.agent().messages();\n }\n catch {\n return;\n }\n const lastContent = msgs.length > 0 ? (msgs[msgs.length - 1] as unknown as Record)['content'] : undefined;\n void lastContent;\n const el = this.scrollContainer()?.nativeElement;\n if (!el)\n return;\n const isNewMessage = count !== this.prevMessageCount;\n this.prevMessageCount = count;\n if (isNewMessage || this.pinned()) {\n this.programmaticScrollCount++;\n el.scrollTop = el.scrollHeight;\n requestAnimationFrame(() => { this.programmaticScrollCount--; });\n if (isNewMessage)\n untracked(() => this.pinned.set(true));\n }\n });\n effect(() => {\n let loading: boolean;\n try {\n loading = this.agent().isLoading();\n }\n catch {\n return;\n }\n if (loading) {\n this.wasLoading = true;\n return;\n }\n if (!this.wasLoading)\n return;\n this.wasLoading = false;\n if (this.pinned()) {\n requestAnimationFrame(() => {\n const el2 = this.scrollContainer()?.nativeElement;\n if (!el2)\n return;\n this.programmaticScrollCount++;\n el2.scrollTop = el2.scrollHeight;\n requestAnimationFrame(() => { this.programmaticScrollCount--; });\n });\n }\n });\n effect(() => {\n let agent: ReturnType;\n try {\n agent = this.agent();\n }\n catch {\n return;\n }\n const customSig = (agent as unknown as {\n customEvents?: () => readonly {\n name: string;\n data: unknown;\n }[];\n }).customEvents;\n if (typeof customSig !== 'function')\n return;\n const events = customSig();\n for (let i = this.partialEventsLastIndex; i < events.length; i++) {\n const e = events[i];\n if (e.name !== 'a2ui-partial')\n continue;\n const d = e.data as {\n tool_call_id?: string;\n args_so_far?: string;\n } | null;\n if (!d || typeof d.tool_call_id !== 'string' || typeof d.args_so_far !== 'string')\n continue;\n this.partialBridge.push(d.tool_call_id, d.args_so_far);\n }\n this.partialEventsLastIndex = events.length;\n });\n let connected: unknown;\n effect(() => {\n const coord = this.coordinator();\n let agentRef: ReturnType;\n try {\n agentRef = this.agent();\n }\n catch {\n return;\n }\n if (!coord || !agentRef)\n return;\n if (connected === coord)\n return;\n connected = coord;\n queueMicrotask(() => {\n runInInjectionContext(this.injector, () => coord.connect(agentRef));\n });\n });\n effect(() => {\n let liveIds: Set;\n try {\n liveIds = new Set();\n for (const m of this.agent().messages()) {\n const id = (m as unknown as {\n id?: string;\n }).id;\n if (id)\n liveIds.add(id);\n }\n }\n catch {\n return;\n }\n for (const key of [...this.classifiers.keys()]) {\n if (!liveIds.has(key)) {\n this.classifiers.get(key)?.classifier.dispose();\n this.classifiers.delete(key);\n }\n }\n for (const key of [...this.markdownDocuments.keys()]) {\n if (!liveIds.has(key))\n this.markdownDocuments.delete(key);\n }\n });\n }\n prevRole(index: number): ChatMessageRole | undefined {\n if (index === 0)\n return undefined;\n const prev = this.agent().messages()[index - 1];\n if (!prev)\n return undefined;\n const role = (prev as unknown as {\n role?: string;\n }).role;\n if (role === 'user')\n return 'user';\n if (role === 'assistant')\n return 'assistant';\n if (role === 'system')\n return 'system';\n if (role === 'tool')\n return 'tool';\n return undefined;\n }\n protected onScroll(): void {\n if (this.programmaticScrollCount > 0)\n return;\n const el = this.scrollContainer()?.nativeElement;\n if (!el)\n return;\n const nextPinned = isPinned(el.scrollHeight, el.scrollTop, el.clientHeight, ChatComponent.PIN_TOLERANCE_PX);\n if (nextPinned !== this.pinned())\n this.pinned.set(nextPinned);\n }\n scrollToBottom(): void {\n const el = this.scrollContainer()?.nativeElement;\n if (!el)\n return;\n this.programmaticScrollCount++;\n el.scrollTop = el.scrollHeight;\n requestAnimationFrame(() => { this.programmaticScrollCount--; });\n this.pinned.set(true);\n }\n protected onScrollBubbleClick(): void {\n this.scrollToBottom();\n }\n protected onUserSubmitted(): void {\n this.pinned.set(true);\n this.recordSubmit();\n }\n submitMessage(text: string): void {\n const trimmed = text.trim();\n if (!trimmed || this.agent().isInputBlocked?.())\n return;\n void this.agent().submit({ message: trimmed });\n this.recordSubmit();\n }\n clearThread(): void {\n this.clearClassifiers();\n this.lifecycle._internal.messageCount.set(0);\n this.lifecycle._internal.inputSubmittedAt.set(null);\n }\n private recordSubmit(): void {\n if (!this.lifecycle._internal.firstMessageSent()) {\n this.lifecycle._internal.firstMessageSent.set(true);\n }\n this.lifecycle._internal.messageCount.update((c) => c + 1);\n this.lifecycle._internal.inputSubmittedAt.set(Date.now());\n }\n protected prevMessage(index: number): unknown {\n if (index === 0)\n return undefined;\n return this.agent().messages()[index - 1];\n }\n protected isGenuiTurn(message: unknown, _prevMsg: unknown, index?: number): boolean {\n const names = new Set(this.genuiToolNames());\n const m = message as {\n extra?: Record;\n } | null | undefined;\n if (!m)\n return false;\n const calls = (m.extra?.['tool_calls'] as Array<{\n name?: string;\n }> | undefined) ?? [];\n if (calls.some(c => c.name != null && names.has(c.name)))\n return true;\n const rawContent = m.extra?.['content'];\n if (Array.isArray(rawContent)) {\n for (const block of rawContent) {\n if (block != null\n && typeof block === 'object'\n && (block as {\n type?: unknown;\n }).type === 'function_call'\n && typeof (block as {\n name?: unknown;\n }).name === 'string'\n && names.has((block as {\n name: string;\n }).name)) {\n return true;\n }\n }\n }\n const projectedContent = (m as {\n content?: unknown;\n }).content;\n if (typeof projectedContent === 'string' && projectedContent.length > 0) {\n if (projectedContent.includes('\"createSurface\"')\n || projectedContent.includes('\"updateComponents\"')\n || projectedContent.includes('\"updateDataModel\"')) {\n return true;\n }\n if (projectedContent.includes('\"root\"') && projectedContent.includes('\"elements\"')) {\n return true;\n }\n }\n const p = _prevMsg as {\n role?: string;\n name?: string;\n extra?: Record;\n } | null | undefined;\n if (p && p.role === 'tool') {\n const toolName = (p.extra?.['name'] as string | undefined) ?? p.name;\n if (typeof toolName === 'string' && names.has(toolName))\n return true;\n }\n if (typeof index === 'number' && index > 0) {\n const msgs = this.agent().messages();\n for (let i = index - 1; i >= 0; i--) {\n const prev = msgs[i] as {\n role?: string;\n extra?: Record;\n };\n if (!prev)\n break;\n if (prev.role === 'user')\n break;\n const prevCalls = (prev.extra?.['tool_calls'] as Array<{\n name?: string;\n }> | undefined) ?? [];\n if (prevCalls.some(c => c.name != null && names.has(c.name)))\n return true;\n const prevRaw = prev.extra?.['content'];\n if (Array.isArray(prevRaw)) {\n for (const block of prevRaw) {\n if (block != null\n && typeof block === 'object'\n && (block as {\n type?: unknown;\n }).type === 'function_call'\n && typeof (block as {\n name?: unknown;\n }).name === 'string'\n && names.has((block as {\n name: string;\n }).name)) {\n return true;\n }\n }\n }\n }\n }\n return false;\n }\n classifyMessage(content: string, message: Pick): ContentClassifier {\n const generation = message.delivery.generation;\n let entry = this.classifiers.get(message.id);\n if (!entry || entry.generation !== generation) {\n entry?.classifier.dispose();\n entry = { generation, classifier: createContentClassifier() };\n this.classifiers.set(message.id, entry);\n }\n entry.classifier.update(content);\n return entry.classifier;\n }\n protected markdownDocumentFor(content: string, message: Pick): StreamingMarkdownDocument {\n const prior = this.markdownDocuments.get(message.id);\n const delivery = message.delivery;\n if (prior?.generation === delivery.generation &&\n prior.phase === delivery.phase &&\n prior.content === content) {\n return prior;\n }\n const document = markdownDocument(content, delivery);\n this.markdownDocuments.set(message.id, document);\n return document;\n }\n clearClassifiers(): void {\n for (const [, entry] of this.classifiers) {\n entry.classifier.dispose();\n }\n this.classifiers.clear();\n this.markdownDocuments.clear();\n }\n onSpecEvent(event: RenderEvent, messageIndex: number): void {\n this.renderEvent.emit({ messageIndex, event });\n }\n protected onClientToolEvent(event: RenderEvent): void {\n const coord = this.coordinator();\n if (!coord)\n return;\n let agentRef: ReturnType;\n try {\n agentRef = this.agent();\n }\n catch {\n return;\n }\n coord.handleRenderEvent(agentRef, event);\n }\n onA2uiAction(message: A2uiActionMessage): void {\n if (this.agent().isInputBlocked?.())\n return;\n void this.agent().submit({ message: JSON.stringify(message) });\n }\n onA2uiEvent(event: RenderEvent, messageIndex: number, surfaceId: string): void {\n this.renderEvent.emit({ messageIndex, surfaceId, event });\n }\n onRegenerate(messageIndex: number): void {\n void this.agent().regenerate(messageIndex);\n this.regenerate.emit();\n }\n onRate(message: unknown, value: 'up' | 'down'): void {\n const idx = this.agent().messages().indexOf(message as never);\n this.rate.emit({ messageIndex: idx, rating: value });\n }\n onCopy(message: unknown, content: string): void {\n const idx = this.agent().messages().indexOf(message as never);\n this.messageCopy.emit({ messageIndex: idx, content });\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatConfirmDialogComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatConfirmDialogComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-confirm-dialog/chat-confirm-dialog.component.ts", + "symbol": "ChatConfirmDialogComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-confirm-dialog',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_CONFIRM_DIALOG_STYLES],\n template: `\n @if (open()) {\n \n \n

    {{ title() }}

    \n @if (body()) {\n

    {{ body() }}

    \n }\n
    \n {{ cancelLabel() }}\n {{ confirmLabel() }}\n
    \n \n }\n `,\n})\nexport class ChatConfirmDialogComponent {\n readonly open = input(false);\n readonly title = input('Are you sure?');\n readonly body = input('');\n readonly confirmLabel = input('Confirm');\n readonly cancelLabel = input('Cancel');\n readonly tone = input<'destructive' | 'normal'>('normal');\n readonly confirmed = output();\n readonly cancelled = output();\n private readonly instanceId = ++confirmDialogInstanceCounter;\n protected readonly titleId = `chat-confirm-dialog__title-${this.instanceId}`;\n protected readonly bodyId = `chat-confirm-dialog__body-${this.instanceId}`;\n private readonly cancelBtn = viewChild>('cancelBtn');\n constructor() {\n effect(() => {\n if (!this.open())\n return;\n queueMicrotask(() => this.cancelBtn()?.nativeElement.focus());\n });\n }\n protected onDialogKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.cancelled.emit();\n }\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatConnectedOverlayDirective", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatConnectedOverlayDirective", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts", + "symbol": "ChatConnectedOverlayDirective", + "syntaxKind": "ClassDeclaration", + "signature": "@Directive({\n selector: '[chatConnectedOverlay]',\n standalone: true,\n})\nexport class ChatConnectedOverlayDirective {\n readonly origin = input.required({ alias: 'chatOverlayOrigin' });\n readonly open = input(false, { alias: 'chatOverlayOpen' });\n readonly positions = input([], { alias: 'chatOverlayPositions' });\n readonly panelClass = input('', { alias: 'chatOverlayPanelClass' });\n readonly attached = output({ alias: 'chatOverlayAttached' });\n readonly outsideClick = output({ alias: 'chatOverlayOutsideClick' });\n readonly detached = output({ alias: 'chatOverlayDetach' });\n private readonly templateRef = inject(TemplateRef);\n private readonly viewContainerRef = inject(ViewContainerRef);\n private readonly document = inject(DOCUMENT);\n private pane: HTMLElement | null = null;\n private viewRef: EmbeddedViewRef | null = null;\n private resizeObs: ResizeObserver | null = null;\n private rafId = 0;\n private previouslyFocused: HTMLElement | null = null;\n private readonly onScrollOrResize = () => this.scheduleReposition();\n private readonly onDocMouseDown = (e: MouseEvent) => {\n if (!this.pane)\n return;\n const path = e.composedPath();\n if (path.includes(this.pane) || path.includes(this.origin().elementRef.nativeElement))\n return;\n this.outsideClick.emit(e);\n };\n private readonly onKeydown = (e: KeyboardEvent) => {\n if (e.key !== 'Tab' || !this.pane)\n return;\n const active = this.document.activeElement;\n if (this.pane.contains(active) || active === this.origin().elementRef.nativeElement) {\n this.detached.emit();\n }\n };\n constructor() {\n effect(() => {\n if (this.open())\n this.attach();\n else\n this.dispose();\n });\n inject(DestroyRef).onDestroy(() => this.dispose());\n }\n private attach(): void {\n if (this.pane)\n return;\n const win = this.document.defaultView;\n if (!win)\n return;\n this.previouslyFocused = this.document.activeElement as HTMLElement | null;\n const pane = this.document.createElement('div');\n pane.className = 'chat-overlay-pane';\n for (const c of this.normalizePanelClass())\n pane.classList.add(c);\n getOverlayContainer(this.document).appendChild(pane);\n this.viewRef = this.viewContainerRef.createEmbeddedView(this.templateRef);\n this.viewRef.detectChanges();\n for (const node of this.viewRef.rootNodes)\n pane.appendChild(node as Node);\n this.pane = pane;\n this.reposition();\n win.addEventListener('scroll', this.onScrollOrResize, { capture: true, passive: true });\n win.addEventListener('resize', this.onScrollOrResize, { passive: true });\n this.document.addEventListener('mousedown', this.onDocMouseDown, true);\n this.document.addEventListener('keydown', this.onKeydown, true);\n if (typeof win.ResizeObserver === 'function') {\n this.resizeObs = new win.ResizeObserver(() => this.scheduleReposition());\n this.resizeObs.observe(this.origin().elementRef.nativeElement);\n this.resizeObs.observe(pane);\n }\n this.attached.emit(pane);\n }\n private scheduleReposition(): void {\n const win = this.document.defaultView;\n if (!win || !this.pane)\n return;\n if (this.rafId)\n win.cancelAnimationFrame(this.rafId);\n this.rafId = win.requestAnimationFrame(() => this.reposition());\n }\n private reposition(): void {\n const win = this.document.defaultView;\n if (!win || !this.pane)\n return;\n const r = this.pane.getBoundingClientRect();\n const result = computeConnectedPosition({\n originRect: this.origin().elementRef.nativeElement.getBoundingClientRect(),\n overlaySize: { width: r.width, height: r.height },\n viewport: narrowViewport(win, VIEWPORT_MARGIN),\n positions: this.positions(),\n });\n this.pane.style.top = `${Math.round(result.top)}px`;\n this.pane.style.left = `${Math.round(result.left)}px`;\n }\n private dispose(): void {\n const win = this.document.defaultView;\n if (this.rafId && win)\n win.cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n if (win) {\n win.removeEventListener('scroll', this.onScrollOrResize, { capture: true } as EventListenerOptions);\n win.removeEventListener('resize', this.onScrollOrResize);\n }\n this.document.removeEventListener('mousedown', this.onDocMouseDown, true);\n this.document.removeEventListener('keydown', this.onKeydown, true);\n this.resizeObs?.disconnect();\n this.resizeObs = null;\n const focusWasInPane = !!this.pane && this.pane.contains(this.document.activeElement);\n this.viewRef?.destroy();\n this.viewRef = null;\n this.pane?.remove();\n this.pane = null;\n if (focusWasInPane && this.previouslyFocused)\n this.previouslyFocused.focus();\n this.previouslyFocused = null;\n }\n private normalizePanelClass(): string[] {\n const pc = this.panelClass();\n return Array.isArray(pc) ? pc : pc ? [pc] : [];\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatErrorComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatErrorComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-error/chat-error.component.ts", + "symbol": "ChatErrorComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-error',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_ERROR_STYLES],\n template: `\n @if (agent().error(); as err) {\n
    \n \n \n \n {{ err.message }}\n \n @if (err.recovery === 'check') {\n @if (agent().checkStatus) {\n \n }\n } @else if (err.retryable) {\n \n }\n @if (err.detail) {\n {{ err.detail }}\n }\n
    \n }\n `,\n})\nexport class ChatErrorComponent {\n readonly agent = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatGenerativeUiComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatGenerativeUiComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-generative-ui/chat-generative-ui.component.ts", + "symbol": "ChatGenerativeUiComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-generative-ui',\n standalone: true,\n imports: [RenderSpecComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_GENERATIVE_UI_STYLES],\n template: `\n @if (normalizedSpec()) {\n \n }\n `,\n})\nexport class ChatGenerativeUiComponent {\n readonly spec = input(null);\n readonly registry = input(undefined);\n readonly store = input(undefined);\n readonly handlers = input) => unknown | Promise> | undefined>(undefined);\n readonly loading = input(false);\n readonly events = output();\n protected readonly normalizedSpec = computed(() => {\n const s = this.spec();\n return s ? normalizeJsonRenderSpec(s) : null;\n });\n private readonly seeded = new Map();\n constructor() {\n effect(() => {\n const s = this.spec();\n const store = this.store();\n const state = s?.state as Record | undefined;\n if (!state || !store)\n return;\n untracked(() => {\n for (const [key, value] of Object.entries(state)) {\n const path = key.startsWith('/') ? key : `/${key}`;\n const current = store.get(path);\n const untouched = current === undefined ||\n (this.seeded.has(path) && current === this.seeded.get(path));\n if (untouched) {\n if (current !== value)\n store.set(path, value);\n this.seeded.set(path, value);\n }\n }\n });\n });\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatGenuiSkeletonComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatGenuiSkeletonComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-genui-skeleton/chat-genui-skeleton.component.ts", + "symbol": "ChatGenuiSkeletonComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-genui-skeleton',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host { display: block; width: 100%; }\n .chat-genui-skeleton {\n border: 1px solid var(--tplane-chat-separator);\n border-radius: 10px;\n padding: 14px;\n background: var(--tplane-chat-surface-alt);\n }\n .chat-genui-skeleton__label {\n font-size: 12px;\n color: var(--tplane-chat-text-muted);\n margin-bottom: 10px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .chat-genui-skeleton__rows {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .chat-genui-skeleton__row {\n height: 10px;\n border-radius: 5px;\n background: linear-gradient(\n 90deg,\n var(--tplane-chat-separator) 0%,\n color-mix(in srgb, var(--tplane-chat-separator) 70%, transparent) 50%,\n var(--tplane-chat-separator) 100%\n );\n background-size: 200% 100%;\n animation: chat-genui-skeleton-shimmer 1.4s ease-in-out infinite;\n }\n .chat-genui-skeleton__row:nth-child(1) { width: 70%; }\n .chat-genui-skeleton__row:nth-child(2) { width: 90%; }\n .chat-genui-skeleton__row:nth-child(3) { width: 50%; }\n @keyframes chat-genui-skeleton-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n `],\n template: `\n
    \n
    \n \n Building UI…\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n `,\n})\nexport class ChatGenuiSkeletonComponent {\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatHistorySearchPaletteComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatHistorySearchPaletteComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-history-search-palette/chat-history-search-palette.component.ts", + "symbol": "ChatHistorySearchPaletteComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-history-search-palette',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_HISTORY_SEARCH_PALETTE_STYLES],\n template: `\n @if (open()) {\n \n \n
    \n \n \n \n \n \n \n \n \n \n \n \n
    \n\n @if (loading() && results().length === 0) {\n
    \n
    \n
    \n
    \n
    \n } @else if (results().length === 0 && query().length === 0) {\n
    Type to search your conversations.
    \n } @else if (results().length === 0) {\n
    No conversations match.
    \n } @else {\n
      \n @for (row of results(); let i = $index; track row.id) {\n \n {{ row.title }}\n @if (row.subtitle) {\n {{ row.subtitle }}\n }\n \n }\n
    \n }\n \n }\n `,\n})\nexport class ChatHistorySearchPaletteComponent {\n readonly open = model(false);\n readonly query = model('');\n readonly results = input([]);\n readonly loading = input(false);\n readonly placeholder = input('Search conversations');\n readonly threadSelected = output();\n readonly closed = output();\n protected readonly activeIndex = signal(0);\n protected readonly listId = `chat-history-search-palette__results-${++paletteInstanceCounter}`;\n private readonly inputEl = viewChild>('inputEl');\n constructor() {\n effect(() => {\n if (this.open()) {\n this.activeIndex.set(0);\n queueMicrotask(() => this.inputEl()?.nativeElement.focus());\n }\n });\n effect(() => {\n const max = this.results().length - 1;\n if (max >= 0 && this.activeIndex() > max) {\n this.activeIndex.set(max);\n }\n });\n }\n protected rowId(index: number): string {\n return `${this.listId}__row-${index}`;\n }\n protected activeRowId(): string | null {\n return this.results().length > 0 ? this.rowId(this.activeIndex()) : null;\n }\n protected onInput(e: Event): void {\n const value = (e.target as HTMLInputElement).value;\n this.query.set(value);\n }\n protected onInputKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.closed.emit();\n return;\n }\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n const max = this.results().length - 1;\n if (max < 0)\n return;\n this.activeIndex.set(Math.min(this.activeIndex() + 1, max));\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n this.activeIndex.set(Math.max(this.activeIndex() - 1, 0));\n return;\n }\n if (e.key === 'Enter') {\n e.preventDefault();\n const rows = this.results();\n if (rows.length === 0)\n return;\n const row = rows[this.activeIndex()];\n this.threadSelected.emit(row.id);\n return;\n }\n }\n protected onRowClick(id: string): void {\n this.threadSelected.emit(id);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatInputComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatInputComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-input/chat-input.component.ts", + "symbol": "ChatInputComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-input',\n standalone: true,\n imports: [],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_INPUT_STYLES],\n template: `\n
    \n \n \n
    \n \n \n
    \n \n \n @if (isLoading() && canStop()) {\n \n \n \n \n \n } @else {\n \n \n \n \n \n \n }\n
    \n
    \n \n
    \n `,\n})\nexport class ChatInputComponent {\n readonly agent = input.required();\n readonly submitOnEnter = input(true);\n readonly placeholder = input('');\n readonly showStopButton = input(true);\n readonly submitted = output();\n readonly stopped = output();\n readonly messageText = signal('');\n readonly isLoading = computed(() => this.agent().isLoading());\n protected readonly composing = signal(false);\n readonly focused = signal(false);\n readonly canSubmit = computed(() => {\n if (this.isLoading() || this.agent().isInputBlocked?.())\n return false;\n return this.messageText().trim().length > 0;\n });\n readonly canStop = computed(() => this.showStopButton());\n private readonly textareaEl = viewChild>('textareaEl');\n constructor() {\n effect(() => {\n const text = this.messageText();\n const el = this.textareaEl()?.nativeElement;\n if (!el)\n return;\n const viewportH = typeof window === 'undefined' ? 600 : window.innerHeight;\n const cap = Math.min(viewportH * 0.4, 320);\n el.style.height = 'auto';\n const next = Math.min(el.scrollHeight, cap);\n el.style.height = `${next}px`;\n el.style.overflowY = el.scrollHeight > cap ? 'auto' : 'hidden';\n void text;\n });\n }\n focusTextarea(): void {\n this.textareaEl()?.nativeElement.focus();\n }\n onSubmit(): void {\n const submitted = submitMessage(this.agent(), this.messageText());\n if (submitted !== null) {\n this.submitted.emit(submitted);\n this.messageText.set('');\n const el = this.textareaEl()?.nativeElement;\n if (el)\n el.value = '';\n requestAnimationFrame(() => this.textareaEl()?.nativeElement.focus());\n }\n }\n protected onInput(event: Event): void {\n this.messageText.set((event.target as HTMLTextAreaElement).value);\n }\n onStop(): void {\n const a = this.agent() as unknown as {\n stop?: () => void | Promise;\n };\n if (typeof a.stop === 'function') {\n void a.stop();\n }\n this.stopped.emit();\n }\n onKeydown(event: KeyboardEvent): void {\n if (!this.submitOnEnter() || event.shiftKey)\n return;\n if (this.composing() || event.isComposing || event.keyCode === 229)\n return;\n event.preventDefault();\n this.onSubmit();\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatInterruptComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatInterruptComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-interrupt/chat-interrupt.component.ts", + "symbol": "ChatInterruptComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-interrupt',\n standalone: true,\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_INTERRUPT_STYLES],\n template: `\n @if (interrupt(); as currentInterrupt) {\n
    \n
    \n \n \n \n Agent paused\n
    \n @if (templateRef()) {\n \n } @else {\n

    {{ defaultText(currentInterrupt) }}

    \n }\n
    \n }\n `,\n})\nexport class ChatInterruptComponent {\n readonly agent = input.required();\n readonly templateRef = contentChild(TemplateRef);\n readonly interrupt = computed(() => getInterrupt(this.agent()));\n defaultText(i: AgentInterrupt): string {\n const v = (i as {\n value?: unknown;\n }).value;\n return typeof v === 'string' ? v : JSON.stringify(v);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatInterruptPanelComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatInterruptPanelComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-interrupt-panel/chat-interrupt-panel.component.ts", + "symbol": "ChatInterruptPanelComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-interrupt-panel',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\n CHAT_HOST_TOKENS,\n `\n .chat-interrupt-panel {\n background: var(--tplane-chat-surface);\n color: var(--tplane-chat-text);\n border: 1px solid var(--tplane-chat-separator);\n border-radius: var(--tplane-chat-radius-card);\n padding: 14px 16px;\n font-size: var(--tplane-chat-font-size-sm);\n }\n .chat-interrupt-panel__eyebrow {\n font-family: ui-monospace, Menlo, Consolas, monospace;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.12em;\n color: var(--tplane-chat-warning-text);\n margin: 0 0 8px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .chat-interrupt-panel__dot {\n width: 6px;\n height: 6px;\n border-radius: 999px;\n background: var(--tplane-chat-warning-text);\n flex: 0 0 6px;\n }\n .chat-interrupt-panel__body {\n margin: 0 0 12px;\n color: var(--tplane-chat-text);\n white-space: pre-wrap;\n }\n .chat-interrupt-panel__actions {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n align-items: center;\n }\n .btn {\n border: 0;\n padding: 6px 14px;\n border-radius: var(--tplane-chat-radius-button);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: transform 200ms ease, opacity 200ms ease;\n }\n .btn:hover { transform: scale(1.03); }\n .btn-primary { background: var(--tplane-chat-primary); color: var(--tplane-chat-on-primary); }\n .btn-secondary { background: transparent; color: var(--tplane-chat-text); border: 1px solid var(--tplane-chat-separator); }\n .btn-text {\n background: transparent;\n color: var(--tplane-chat-text-muted);\n padding: 6px 10px;\n }\n .btn-text:hover { color: var(--tplane-chat-text); }\n `,\n ],\n template: `\n @if (interrupt()) {\n
    \n

    \n \n Agent paused — review needed\n

    \n

    {{ interruptReason() }}

    \n
    \n \n \n \n \n
    \n
    \n }\n `,\n})\nexport class ChatInterruptPanelComponent {\n readonly agent = input.required();\n readonly action = output();\n readonly interrupt = computed(() => getInterruptFromAgent(this.agent()));\n readonly interruptReason = computed(() => interruptReasonText(this.interrupt()));\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatLauncherButtonComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatLauncherButtonComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-launcher-button/chat-launcher-button.component.ts", + "symbol": "ChatLauncherButtonComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-launcher-button',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_LAUNCHER_BUTTON_STYLES],\n template: `\n \n `,\n})\nexport class ChatLauncherButtonComponent {\n readonly clicked = output();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatLifecycle", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatLifecycle", + "declarations": [ + { + "path": "libs/chat/src/lib/lifecycle.ts", + "symbol": "ChatLifecycle", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ChatLifecycle {\n readonly componentReady: Signal;\n readonly firstMessageSent: Signal;\n readonly messageCount: Signal;\n readonly inputSubmittedAt: Signal;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatMessageActionsComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatMessageActionsComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-message-actions/chat-message-actions.component.ts", + "symbol": "ChatMessageActionsComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-message-actions',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_MESSAGE_ACTIONS_STYLES],\n host: {\n 'role': 'toolbar',\n '[attr.aria-label]': '\"Message actions\"',\n },\n template: `\n \n \n \n \n \n \n \n \n \n @if (copied()) {\n \n } @else {\n \n \n \n \n }\n \n \n \n \n \n \n \n \n \n \n \n \n \n `,\n})\nexport class ChatMessageActionsComponent {\n readonly content = input('');\n readonly disabled = input(false);\n readonly regenerate = output();\n readonly rate = output<'up' | 'down'>();\n readonly contentCopied = output();\n protected readonly copied = signal(false);\n protected readonly rating = signal<'up' | 'down' | null>(null);\n private readonly document = inject(DOCUMENT);\n protected async onCopy(): Promise {\n const text = this.content();\n if (!text)\n return;\n let succeeded = false;\n const win = this.document.defaultView;\n if (win?.navigator?.clipboard?.writeText) {\n try {\n await win.navigator.clipboard.writeText(text);\n succeeded = true;\n }\n catch {\n }\n }\n if (!succeeded) {\n try {\n const ta = this.document.createElement('textarea');\n ta.value = text;\n ta.style.position = 'fixed';\n ta.style.opacity = '0';\n this.document.body.appendChild(ta);\n ta.select();\n succeeded = !!this.document.execCommand?.('copy');\n ta.remove();\n }\n catch {\n }\n }\n if (succeeded) {\n this.copied.set(true);\n this.contentCopied.emit(text);\n setTimeout(() => this.copied.set(false), 2000);\n }\n }\n protected onRate(value: 'up' | 'down'): void {\n this.rating.set(this.rating() === value ? null : value);\n this.rate.emit(value);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatMessageComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatMessageComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-message/chat-message.component.ts", + "symbol": "ChatMessageComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-message',\n standalone: true,\n imports: [ChatCitationsComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_MESSAGE_STYLES],\n providers: [CitationsResolverService],\n host: {\n '[attr.data-role]': 'role()',\n '[attr.data-current]': 'currentStr()',\n '[attr.data-streaming]': 'streamingStr()',\n '[attr.data-prev-role]': 'prevRole() ?? null',\n },\n template: `\n
    \n \n \n
    \n @if (message()?.role === 'assistant' && message(); as msg) {\n \n }\n
    \n \n
    \n `,\n})\nexport class ChatMessageComponent {\n readonly role = input.required();\n readonly current = input(false);\n readonly streaming = input(false);\n readonly prevRole = input(undefined);\n readonly message = input(undefined);\n private readonly resolver = inject(CitationsResolverService);\n constructor() {\n effect(() => {\n this.resolver.message.set(this.message() ?? null);\n });\n }\n readonly currentStr = computed(() => String(this.current()));\n readonly streamingStr = computed(() => String(this.streaming()));\n readonly bodyClass = computed(() => {\n switch (this.role()) {\n case 'user': return 'chat-message__bubble';\n case 'assistant': return 'chat-message__assistant-body';\n default: return 'chat-message__plain';\n }\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatMessageListComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatMessageListComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-message-list/chat-message-list.component.ts", + "symbol": "ChatMessageListComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-message-list',\n standalone: true,\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_MESSAGE_LIST_STYLES],\n template: `\n @for (message of messages(); track message.id) {\n @let template = findTemplate(getMessageType(message));\n @if (template) {\n \n }\n }\n `,\n})\nexport class ChatMessageListComponent {\n readonly agent = input.required();\n readonly messageTemplates = contentChildren(MessageTemplateDirective);\n readonly messages = computed(() => this.agent().messages());\n readonly getMessageType = getMessageType;\n findTemplate(type: MessageTemplateType): MessageTemplateDirective | undefined {\n return this.messageTemplates().find(t => t.chatMessageTemplate() === type);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatMessageRole", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatMessageRole", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-message/chat-message.component.ts", + "symbol": "ChatMessageRole", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ChatMessageRole = 'user' | 'assistant' | 'system' | 'tool';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatOverflowMenuComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatOverflowMenuComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-overflow-menu/chat-overflow-menu.component.ts", + "symbol": "ChatOverflowMenuComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-overflow-menu',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_OVERFLOW_MENU_STYLES],\n template: `\n @if (open()) {\n \n \n @for (item of items(); track item.id) {\n \n {{ item.label }}\n \n }\n \n }\n `,\n})\nexport class ChatOverflowMenuComponent {\n readonly open = input(false);\n readonly items = input([]);\n readonly anchor = input(null);\n readonly anchorPos = input<{\n x: number;\n y: number;\n } | null>(null);\n readonly itemSelected = output();\n readonly closed = output();\n protected readonly position = computed<{\n top: number;\n left: number;\n }>(() => {\n if (!this.open())\n return { top: 0, left: 0 };\n const pos = this.anchorPos();\n if (pos) {\n return { top: pos.y + 4, left: Math.max(pos.x, 8) };\n }\n const el = this.anchor();\n if (!el) {\n const vw = typeof window === 'undefined' ? 0 : window.innerWidth;\n const vh = typeof window === 'undefined' ? 0 : window.innerHeight;\n return { top: Math.max(vh / 3, 0), left: Math.max(vw / 2 - 80, 0) };\n }\n const rect = el.getBoundingClientRect();\n return { top: rect.bottom + 4, left: Math.max(rect.right - 160, 8) };\n });\n constructor() {\n effect(() => {\n if (!this.open())\n return;\n queueMicrotask(() => {\n const root = document.querySelector('.chat-overflow-menu');\n const first = root?.querySelector('.chat-overflow-menu__item:not(.chat-overflow-menu__item--disabled)');\n first?.focus();\n });\n });\n }\n protected onItemClick(item: OverflowMenuItem): void {\n if (item.disabled)\n return;\n this.itemSelected.emit(item.id);\n this.closed.emit();\n }\n protected onMenuKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.closed.emit();\n return;\n }\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n const root = (e.currentTarget as HTMLElement);\n const items = Array.from(root.querySelectorAll('.chat-overflow-menu__item:not(.chat-overflow-menu__item--disabled)'));\n if (items.length === 0)\n return;\n const current = document.activeElement as HTMLElement | null;\n const idx = current ? items.indexOf(current) : -1;\n const next = e.key === 'ArrowDown'\n ? Math.min((idx < 0 ? 0 : idx + 1), items.length - 1)\n : Math.max(idx - 1, 0);\n items[next]?.focus();\n }\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatOverlayOriginDirective", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatOverlayOriginDirective", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts", + "symbol": "ChatOverlayOriginDirective", + "syntaxKind": "ClassDeclaration", + "signature": "@Directive({\n selector: '[chatOverlayOrigin]',\n standalone: true,\n exportAs: 'chatOverlayOrigin',\n})\nexport class ChatOverlayOriginDirective {\n readonly elementRef = inject(ElementRef) as ElementRef;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatPopupComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatPopupComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-popup/chat-popup.component.ts", + "symbol": "ChatPopupComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-popup',\n standalone: true,\n imports: [ChatComponent, ChatLauncherButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host {\n position: fixed;\n bottom: var(--tplane-chat-launcher-offset-y);\n right: var(--tplane-chat-launcher-offset-x);\n z-index: var(--tplane-chat-z-overlay-content, 30);\n }\n .chat-popup__launcher { position: relative; }\n .chat-popup__window {\n position: fixed;\n bottom: 5rem;\n right: var(--tplane-chat-launcher-offset-x);\n width: 24rem;\n height: 600px;\n max-height: calc(100vh - 6rem);\n background: var(--tplane-chat-bg);\n border: 1px solid var(--tplane-chat-separator);\n border-radius: 0.75rem;\n box-shadow: 0 5px 40px rgba(0,0,0,.16);\n transform-origin: bottom right;\n transform: scale(0.95) translateY(20px);\n opacity: 0;\n pointer-events: none;\n transition: transform 200ms ease-out, opacity 100ms ease-out;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n .chat-popup__window[data-open=\"true\"] {\n transform: scale(1) translateY(0);\n opacity: 1;\n pointer-events: auto;\n }\n @media (max-width: 640px) {\n .chat-popup__window { inset: 0; width: 100vw; height: 100vh; max-height: 100vh; border-radius: 0; bottom: auto; right: auto; }\n }\n .chat-popup__close {\n position: absolute; top: 8px; right: 8px;\n width: 32px; height: 32px;\n background: transparent; border: 0; cursor: pointer;\n color: var(--tplane-chat-text-muted);\n border-radius: 50%;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .chat-popup__close:hover { background: var(--tplane-chat-surface-alt); color: var(--tplane-chat-text); }\n `],\n template: `\n
    \n \n
    \n
    \n \n \n \n \n \n
    \n `,\n})\nexport class ChatPopupComponent {\n readonly agent = input.required();\n readonly views = input(undefined);\n readonly clientTools = input(undefined);\n readonly modelOptions = input([]);\n readonly showModelPicker = input(true);\n readonly selectedModel = model('');\n readonly open = model(false);\n readonly shortcut = input('k');\n readonly closeOnEscape = input(true);\n private readonly destroyRef = inject(DestroyRef);\n private readonly document = inject(DOCUMENT);\n constructor() {\n ensureChatRootStyles();\n effect(() => {\n const shortcut = this.shortcut();\n const closeOnEscape = this.closeOnEscape();\n const win = this.document.defaultView;\n if (!win)\n return;\n const isMac = /Mac|iPhone|iPad/i.test(win.navigator.platform || win.navigator.userAgent);\n const handler = (e: KeyboardEvent): void => {\n if (shortcut && e.key.toLowerCase() === shortcut.toLowerCase() && (isMac ? e.metaKey : e.ctrlKey)) {\n e.preventDefault();\n this.toggle();\n return;\n }\n if (closeOnEscape && this.open() && e.key === 'Escape') {\n this.closeWindow();\n }\n };\n win.addEventListener('keydown', handler);\n this.destroyRef.onDestroy(() => win.removeEventListener('keydown', handler));\n });\n }\n toggle(): void { this.open.update((v) => !v); }\n openWindow(): void { this.open.set(true); }\n closeWindow(): void { this.open.set(false); }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatProjectListComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatProjectListComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-project-list/chat-project-list.component.ts", + "symbol": "ChatProjectListComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-project-list',\n standalone: true,\n imports: [ChatOverflowMenuComponent, ChatConfirmDialogComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_PROJECT_LIST_STYLES],\n template: `\n @if (showNewProjectButton()) {\n \n }\n
      \n @if (creatingProject()) {\n
    • \n \n
    • \n }\n @for (project of visibleProjects(); track project.id) {\n
    • \n @if (editingProjectId() === project.id) {\n \n } @else {\n {{ project.name }}\n\n @if (showKebab()) {\n ⋯\n }\n }\n
    • \n }\n
    \n\n \n\n \n `,\n})\nexport class ChatProjectListComponent {\n readonly projects = input.required();\n readonly activeProjectId = input(null);\n readonly showNewProjectButton = input(false);\n readonly actions = input(null);\n readonly projectSelected = output();\n readonly newProjectRequested = output();\n protected readonly creatingProject = signal(false);\n protected readonly creatingValue = signal('');\n protected readonly editingProjectId = signal(null);\n protected readonly editingValue = signal('');\n protected readonly menuOpenForId = signal(null);\n protected readonly menuAnchor = signal(null);\n protected readonly confirmDeleteId = signal(null);\n private readonly pendingHidden = signal>(new Set());\n private readonly pendingRenames = signal>(new Map());\n protected readonly visibleProjects = computed(() => {\n const hidden = this.pendingHidden();\n const renames = this.pendingRenames();\n return this.projects()\n .filter((p) => !hidden.has(p.id))\n .map((p) => (renames.has(p.id) ? ({ ...p, name: renames.get(p.id)! }) : p));\n });\n protected readonly currentMenuItems = computed(() => {\n const id = this.menuOpenForId();\n if (!id)\n return [];\n const a = this.actions();\n if (!a)\n return [];\n const items: OverflowMenuItem[] = [];\n if (a.rename)\n items.push({ id: 'rename', label: 'Rename' });\n if (a.delete)\n items.push({ id: 'delete', label: 'Delete', tone: 'destructive' });\n return items;\n });\n private readonly createInput = viewChild>('createInput');\n private readonly editInput = viewChild>('editInput');\n constructor() {\n effect(() => {\n if (this.creatingProject()) {\n queueMicrotask(() => this.createInput()?.nativeElement.focus());\n }\n });\n }\n protected selectProject(projectId: string): void {\n this.projectSelected.emit(projectId);\n }\n protected showKebab(): boolean {\n const a = this.actions();\n if (!a)\n return false;\n return Boolean(a.rename || a.delete);\n }\n protected openMenu(projectId: string, anchor: HTMLElement): void {\n this.menuAnchor.set(anchor);\n this.menuOpenForId.set(projectId);\n }\n protected onMenuAction(id: string): void {\n const projectId = this.menuOpenForId();\n this.menuOpenForId.set(null);\n if (!projectId)\n return;\n if (id === 'rename') {\n const p = this.projects().find((x) => x.id === projectId);\n this.editingValue.set(p?.name ?? '');\n this.editingProjectId.set(projectId);\n queueMicrotask(() => this.editInput()?.nativeElement.focus());\n }\n else if (id === 'delete') {\n this.confirmDeleteId.set(projectId);\n }\n }\n protected onNewProjectClicked(): void {\n this.creatingValue.set('');\n this.creatingProject.set(true);\n this.newProjectRequested.emit();\n }\n protected onCreateInput(e: Event): void {\n this.creatingValue.set((e.target as HTMLInputElement).value);\n }\n protected cancelCreate(): void {\n this.creatingProject.set(false);\n this.creatingValue.set('');\n }\n protected async commitCreate(): Promise {\n const name = this.creatingValue().trim();\n this.creatingProject.set(false);\n this.creatingValue.set('');\n if (!name)\n return;\n const a = this.actions();\n if (!a?.create)\n return;\n try {\n await a.create(name);\n }\n catch { }\n }\n protected onEditInput(e: Event): void {\n this.editingValue.set((e.target as HTMLInputElement).value);\n }\n protected cancelRename(): void {\n this.editingProjectId.set(null);\n }\n protected async commitRename(projectId: string): Promise {\n const newName = this.editingValue().trim();\n this.editingProjectId.set(null);\n if (!newName)\n return;\n const a = this.actions();\n if (!a?.rename)\n return;\n this.pendingRenames.update((m) => {\n const n = new Map(m);\n n.set(projectId, newName);\n return n;\n });\n try {\n await a.rename(projectId, newName);\n }\n catch {\n }\n finally {\n this.pendingRenames.update((m) => {\n const n = new Map(m);\n n.delete(projectId);\n return n;\n });\n }\n }\n protected async performDelete(): Promise {\n const projectId = this.confirmDeleteId();\n this.confirmDeleteId.set(null);\n if (!projectId)\n return;\n const a = this.actions();\n if (!a?.delete)\n return;\n this.pendingHidden.update((s) => new Set([...s, projectId]));\n try {\n await a.delete(projectId);\n }\n catch {\n }\n finally {\n this.pendingHidden.update((s) => {\n const n = new Set(s);\n n.delete(projectId);\n return n;\n });\n }\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatReasoningComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatReasoningComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-reasoning/chat-reasoning.component.ts", + "symbol": "ChatReasoningComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-reasoning',\n standalone: true,\n imports: [ChatStreamingMdComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_REASONING_STYLES],\n host: {\n '[attr.data-has-content]': 'hasContent()',\n '[attr.data-expanded]': 'expandedStr()',\n '[attr.data-streaming]': 'isStreaming()',\n },\n template: `\n \n \n \n \n @if (isStreaming()) {\n \n }\n {{ resolvedLabel() }}\n \n @if (expanded()) {\n
    \n \n
    \n }\n `,\n})\nexport class ChatReasoningComponent {\n readonly content = input('');\n readonly delivery = input.required();\n readonly durationMs = input(undefined);\n readonly label = input(undefined);\n readonly defaultExpanded = input(false);\n readonly hasContent = computed(() => (this.content() ?? '').length > 0);\n readonly isStreaming = computed(() => this.delivery().phase === 'streaming');\n readonly document = computed(() => markdownDocument(this.content(), this.delivery(), ':reasoning'));\n private readonly _expandedOverride = signal(null);\n readonly expanded = computed(() => {\n const override = this._expandedOverride();\n if (override !== null)\n return override;\n if (this.isStreaming())\n return true;\n return this.defaultExpanded();\n });\n readonly expandedStr = computed(() => String(this.expanded()));\n readonly resolvedLabel = computed(() => {\n const explicit = this.label();\n if (explicit)\n return explicit;\n if (this.isStreaming())\n return 'Thinking…';\n const ms = this.durationMs();\n if (typeof ms === 'number')\n return `Thought for ${formatDuration(ms)}`;\n return 'Show reasoning';\n });\n constructor() {\n let prevStreaming = false;\n effect(() => {\n const streaming = this.isStreaming();\n if (!prevStreaming && streaming) {\n this._expandedOverride.set(null);\n }\n prevStreaming = streaming;\n });\n }\n toggle(): void {\n this._expandedOverride.set(!this.expanded());\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatRenderEvent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatRenderEvent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat/chat-render-event.ts", + "symbol": "ChatRenderEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ChatRenderEvent {\n readonly messageIndex: number;\n readonly surfaceId?: string;\n readonly event: RenderEvent;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatScrollBubbleComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatScrollBubbleComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-scroll-bubble/chat-scroll-bubble.component.ts", + "symbol": "ChatScrollBubbleComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-scroll-bubble',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_SCROLL_BUBBLE_STYLES],\n template: `\n \n @if (mode() === 'streaming') {\n \n \n \n \n \n } @else {\n \n \n \n \n }\n \n `,\n})\nexport class ChatScrollBubbleComponent {\n readonly mode = input.required();\n readonly clicked = output();\n protected readonly ariaLabel = computed(() => this.mode() === 'streaming' ? 'Latest activity' : 'Scroll to latest');\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatScrollBubbleMode", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatScrollBubbleMode", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-scroll-bubble/chat-scroll-bubble.component.ts", + "symbol": "ChatScrollBubbleMode", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ChatScrollBubbleMode = 'streaming' | 'idle';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSelectComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatSelectComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-select/chat-select.component.ts", + "symbol": "ChatSelectComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-select',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [ChatConnectedOverlayDirective, ChatOverlayOriginDirective],\n styles: [CHAT_HOST_TOKENS, CHAT_SELECT_STYLES],\n template: `\n \n {{ currentLabel() }}\n \n \n \n \n \n \n @for (opt of options(); track opt.value) {\n \n {{ opt.label }}\n @if (opt.description) {\n {{ opt.description }}\n }\n \n }\n \n \n `,\n})\nexport class ChatSelectComponent {\n readonly options = input.required();\n readonly value = model('');\n readonly placeholder = input('Select');\n readonly disabled = input(false);\n readonly menuLabel = input(undefined);\n readonly panelClass = input('');\n protected readonly open = signal(false);\n protected readonly menuId = `chat-select-menu-${nextChatSelectId++}`;\n protected readonly overlayPositions: ConnectedPosition[] = [\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -8 },\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 8 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -8 },\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 8 },\n ];\n protected readonly panelClasses = computed(() => {\n const extra = this.panelClass();\n const list = Array.isArray(extra) ? extra : extra ? [extra] : [];\n return ['chat-select__overlay', ...list];\n });\n protected readonly currentLabel = computed(() => {\n const v = this.value();\n return this.options().find((o) => o.value === v)?.label ?? this.placeholder();\n });\n private readonly hostEl = inject(ElementRef).nativeElement as HTMLElement;\n private readonly document = inject(DOCUMENT);\n private menuPane: HTMLElement | null = null;\n protected onAttached(pane: HTMLElement): void {\n this.menuPane = pane;\n this.focusOption(0);\n }\n protected toggle(): void {\n if (this.disabled())\n return;\n this.open.update((v) => !v);\n }\n protected selectOption(opt: ChatSelectOption): void {\n if (opt.disabled)\n return;\n this.value.set(opt.value);\n this.open.set(false);\n }\n protected onTriggerKeydown(e: KeyboardEvent): void {\n if (this.disabled())\n return;\n if (e.key === 'Escape' && this.open()) {\n e.preventDefault();\n this.open.set(false);\n return;\n }\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {\n e.preventDefault();\n this.open.set(true);\n }\n }\n protected onMenuKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.open.set(false);\n this.queryTrigger()?.focus();\n return;\n }\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n this.moveFocus(e.key === 'ArrowDown' ? 1 : -1);\n return;\n }\n if (e.key === 'Enter' || e.key === ' ') {\n const t = e.target as HTMLElement;\n if (t.classList.contains('chat-select__option')) {\n e.preventDefault();\n (t as HTMLButtonElement).click();\n }\n }\n }\n private focusOption(index: number): void {\n this.queryOptions()[index]?.focus();\n }\n private moveFocus(dir: 1 | -1): void {\n const opts = this.queryOptions().filter((b) => !b.disabled);\n if (!opts.length)\n return;\n const active = this.document.activeElement as HTMLElement | null;\n const idx = active ? opts.indexOf(active as HTMLButtonElement) : -1;\n opts[(idx + dir + opts.length) % opts.length]?.focus();\n }\n private queryOptions(): HTMLButtonElement[] {\n const root = this.menuPane;\n return root ? Array.from(root.querySelectorAll('.chat-select__option')) : [];\n }\n private queryTrigger(): HTMLButtonElement | null {\n return this.hostEl.querySelector('.chat-select__trigger');\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSelectOption", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatSelectOption", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-select/chat-select.component.ts", + "symbol": "ChatSelectOption", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ChatSelectOption {\n value: string;\n label: string;\n description?: string;\n disabled?: boolean;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSidebarComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatSidebarComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-sidebar/chat-sidebar.component.ts", + "symbol": "ChatSidebarComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-sidebar',\n standalone: true,\n imports: [ChatComponent, ChatLauncherButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.data-push]': 'pushContent() ? \"true\" : \"false\"',\n '[attr.data-open]': 'open() ? \"true\" : \"false\"',\n },\n styles: [CHAT_HOST_TOKENS, `\n /* Flex row so the projected main content fills the area beside the panel\n and inherits the host's height (no hardcoded 100vh). Consumers thread\n height: 100% from their layout down to ; the content slot\n then fills it via flex. */\n :host { display: flex; height: 100%; min-height: 0; }\n .chat-sidebar__content {\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n transition: margin-right 300ms ease;\n }\n :host([data-push=\"true\"][data-open=\"true\"]) .chat-sidebar__content {\n margin-right: var(--tplane-chat-sidebar-width-drawer, 28rem);\n }\n @media (max-width: 640px) {\n :host([data-push=\"true\"][data-open=\"true\"]) .chat-sidebar__content { margin-right: 0; }\n }\n .chat-sidebar__panel {\n position: fixed;\n top: 0; right: 0;\n bottom: var(--tplane-chat-debug-claim-bottom, 0);\n width: var(--tplane-chat-sidebar-width-drawer, 28rem);\n background: var(--tplane-chat-bg);\n border-left: 1px solid var(--tplane-chat-separator);\n box-shadow: -8px 0 32px rgba(0,0,0,.08);\n transform: translateX(100%);\n transition: transform 200ms ease-out, bottom 200ms ease-out;\n z-index: var(--tplane-chat-z-overlay-content, 30);\n display: flex;\n flex-direction: column;\n }\n .chat-sidebar__panel[data-open=\"true\"] { transform: translateX(0); }\n @media (max-width: 640px) {\n .chat-sidebar__panel { width: 100vw; }\n }\n .chat-sidebar__panel-header {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--tplane-chat-separator);\n min-height: 48px;\n }\n .chat-sidebar__panel-title {\n min-width: 0;\n flex: 1 1 auto;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n color: var(--tplane-chat-text);\n font-weight: 500;\n font-size: var(--tplane-chat-font-size-sm);\n }\n .chat-sidebar__close {\n flex: 0 0 auto;\n width: 32px; height: 32px;\n background: transparent; border: 0; cursor: pointer;\n color: var(--tplane-chat-text-muted);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .chat-sidebar__close:hover { background: var(--tplane-chat-surface-alt); color: var(--tplane-chat-text); }\n .chat-sidebar__launcher {\n position: fixed;\n bottom: calc(1rem + var(--tplane-chat-debug-claim-bottom, 0));\n right: 1rem;\n z-index: var(--tplane-chat-z-overlay-content, 30);\n transition: bottom 200ms ease-out;\n }\n /* Hide the launcher when the sidebar is open — the close button on the\n panel handles dismissal, and the panel covers the launcher anyway. */\n :host([data-open=\"true\"]) .chat-sidebar__launcher { display: none; }\n `],\n template: `\n
    \n
    \n \n
    \n \n `,\n})\nexport class ChatSidebarComponent {\n readonly agent = input.required();\n readonly views = input(undefined);\n readonly clientTools = input(undefined);\n readonly modelOptions = input([]);\n readonly showModelPicker = input(true);\n readonly selectedModel = model('');\n readonly open = model(false);\n readonly closeOnEscape = input(true);\n readonly pushContent = input(false);\n private readonly document = inject(DOCUMENT);\n constructor() {\n ensureChatRootStyles();\n effect((onCleanup) => {\n if (typeof document === 'undefined')\n return;\n const html = document.documentElement;\n if (this.open()) {\n html.dataset['threadplaneChatSidebar'] = 'open';\n }\n else {\n delete html.dataset['threadplaneChatSidebar'];\n }\n onCleanup(() => { delete html.dataset['threadplaneChatSidebar']; });\n });\n effect((onCleanup) => {\n const closeOnEscape = this.closeOnEscape();\n const win = this.document.defaultView;\n if (!win)\n return;\n const handler = (e: KeyboardEvent): void => {\n if (closeOnEscape && this.open() && e.key === 'Escape') {\n this.closeWindow();\n }\n };\n win.addEventListener('keydown', handler);\n onCleanup(() => win.removeEventListener('keydown', handler));\n });\n }\n toggle(): void { this.open.update((v) => !v); }\n openWindow(): void { this.open.set(true); }\n closeWindow(): void { this.open.set(false); }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSidenavComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatSidenavComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-sidenav/chat-sidenav.component.ts", + "symbol": "ChatSidenavComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-sidenav',\n standalone: true,\n imports: [ChatThreadListComponent, ChatProjectListComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.data-mode]': 'mode()',\n '[attr.data-open]': 'open() ? \"true\" : \"false\"',\n },\n styles: [CHAT_HOST_TOKENS, CHAT_SIDENAV_STYLES],\n template: `\n \n
    \n \n
    \n\n
    \n \n \n \n \n \n New chat\n \n @if (mode() === 'drawer') {\n \n \n \n \n \n Close\n \n }\n
    \n\n
    \n \n \n \n \n \n Search\n \n
    \n\n
    \n \n
    \n\n @if (projects() !== null) {\n
    \n
    Projects
    \n \n
    \n } @if (threads() !== null) {\n
    \n
    Recent
    \n \n
    \n } @if (archivedThreads() !== null) {\n \n \n \n \n \n Archived\n \n @if (archivedOpen()) {\n
    \n @if (archivedThreads()!.length === 0) {\n
    \n No archived conversations.\n
    \n } @else {\n \n }\n
    \n }\n \n }\n\n
    \n \n
    \n\n
    \n \n \n \n
    \n \n
    \n
    \n \n \n `,\n})\nexport class ChatSidenavComponent {\n readonly mode = input('expanded');\n readonly open = input(false);\n readonly threads = input(null);\n readonly activeThreadId = input(null);\n readonly actions = input(null);\n readonly archivedThreads = input(null);\n readonly projects = input(null);\n readonly selectedProjectId = input(null);\n readonly projectActions = input(null);\n readonly agent = input(null);\n readonly debug = input(true);\n readonly newChat = output();\n readonly threadSelected = output();\n readonly searchOpened = output();\n readonly openChange = output();\n readonly modeChange = output();\n readonly projectSelected = output();\n readonly newProjectRequested = output();\n protected readonly archivedOpen = signal(false);\n protected readonly showDebugButton = computed(() => CHAT_DEBUG_INCLUDED && this.debug() && this.agent() !== null);\n protected readonly isDebugStreaming = computed(() => this.agent()?.status?.() === 'running');\n private readonly destroyRef = inject(DestroyRef);\n private readonly injector = inject(Injector);\n private readonly debugHost = viewChild('debugHost', {\n read: ViewContainerRef,\n });\n private debugRef: ComponentRef | null = null;\n private debugOutputSubscriptions: OutputRefSubscription[] = [];\n private currentDebugDock: ChatDebugDock = 'right';\n constructor() {\n this.destroyRef.onDestroy(() => this.destroyDebug());\n effect(() => {\n const showDebug = this.showDebugButton();\n const agent = this.agent();\n if (!showDebug || !agent) {\n this.destroyDebug();\n return;\n }\n this.debugRef?.setInput('agent', agent);\n });\n fromEvent(window, 'keydown')\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((e) => {\n if (!(e.metaKey || e.ctrlKey))\n return;\n const key = e.key.toLowerCase();\n if (key !== 'k' && key !== 'b')\n return;\n const t = e.target as HTMLElement | null;\n if (t) {\n const tag = t.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || t.isContentEditable)\n return;\n }\n if (key === 'k') {\n e.preventDefault();\n this.searchOpened.emit();\n return;\n }\n if (this.mode() === 'drawer')\n return;\n e.preventDefault();\n this.modeChange.emit(this.mode() === 'collapsed' ? 'expanded' : 'collapsed');\n });\n }\n protected openDebug(event: MouseEvent): void {\n event.stopPropagation();\n void this.ensureDebugPanel();\n }\n protected onEscape(): void {\n if (this.mode() === 'drawer' && this.open()) {\n this.openChange.emit(false);\n }\n }\n protected onCollapseToggle(): void {\n const m = this.mode();\n if (m === 'drawer')\n return;\n this.modeChange.emit(m === 'collapsed' ? 'expanded' : 'collapsed');\n }\n private async ensureDebugPanel(): Promise {\n if (!CHAT_DEBUG_INCLUDED) {\n return;\n }\n if (!this.showDebugButton()) {\n this.destroyDebug();\n return;\n }\n const host = this.debugHost();\n const agent = this.agent();\n if (!host || !agent)\n return;\n if (!this.debugRef) {\n const { ChatDebugComponent } = await import('@threadplane/chat/debug');\n if (!this.showDebugButton())\n return;\n this.debugRef = host.createComponent(ChatDebugComponent, {\n injector: this.injector,\n });\n this.debugRef.setInput('launcher', 'none');\n this.debugRef.setInput('storageKey', 'chat-sidenav-debug');\n const initialDock = this.defaultDebugDock();\n this.debugRef.setInput('dock', initialDock);\n const openSub = this.debugRef.instance.openChange?.subscribe((open) => {\n if (open) {\n this.setDebugEdgeClaim(this.currentDebugDock);\n }\n else {\n this.clearDebugEdgeClaim();\n }\n });\n const dockSub = this.debugRef.instance.dockChange?.subscribe((dock) => {\n this.currentDebugDock = dock;\n this.setDebugEdgeClaim(dock);\n });\n this.debugOutputSubscriptions = [\n openSub,\n dockSub,\n ].filter((sub): sub is OutputRefSubscription => !!sub);\n this.currentDebugDock = initialDock;\n this.setDebugEdgeClaim(initialDock);\n }\n this.debugRef.setInput('agent', agent);\n this.debugRef.instance.setOpen(true);\n this.debugRef.changeDetectorRef.detectChanges();\n if (this.currentDebugDock === 'bottom') {\n this.debugRef.instance.setDock?.('bottom');\n this.debugRef.changeDetectorRef.detectChanges();\n }\n this.setDebugEdgeClaim(this.currentDebugDock);\n }\n private destroyDebug(): void {\n for (const subscription of this.debugOutputSubscriptions) {\n subscription.unsubscribe();\n }\n this.debugOutputSubscriptions = [];\n this.debugRef?.destroy();\n this.debugRef = null;\n this.clearDebugEdgeClaim();\n }\n private defaultDebugDock(): ChatDebugDock {\n if (typeof document === 'undefined')\n return 'right';\n return document.querySelector('chat-sidebar') ? 'bottom' : 'right';\n }\n private setDebugEdgeClaim(dock: ChatDebugDock): void {\n if (typeof document === 'undefined')\n return;\n document.documentElement.dataset['threadplaneChatDebug'] = dock;\n }\n private clearDebugEdgeClaim(): void {\n if (typeof document === 'undefined')\n return;\n delete document.documentElement.dataset['threadplaneChatDebug'];\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSidenavMode", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatSidenavMode", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-sidenav/chat-sidenav.component.ts", + "symbol": "ChatSidenavMode", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ChatSidenavMode = 'expanded' | 'collapsed' | 'drawer';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSidenavScrimComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatSidenavScrimComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-sidenav-scrim/chat-sidenav-scrim.component.ts", + "symbol": "ChatSidenavScrimComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-sidenav-scrim',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (open()) {\n \n }\n `,\n styles: [\n `\n :host { display: contents; }\n .chat-sidenav-scrim__button {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: var(--tplane-chat-z-drawer-scrim, 1000);\n border: 0;\n padding: 0;\n cursor: pointer;\n }\n `,\n ],\n})\nexport class ChatSidenavScrimComponent {\n readonly open = input(false);\n readonly dismiss = output();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatStreamingMdComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatStreamingMdComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/streaming-markdown.component.ts", + "symbol": "ChatStreamingMdComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-streaming-md',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n styles: CHAT_MARKDOWN_STYLES,\n template: `\n @if (root(); as r) {\n \n }\n `,\n providers: [\n {\n provide: MARKDOWN_VIEW_REGISTRY,\n useFactory: (host: ChatStreamingMdComponent) => host.resolvedRegistry(),\n deps: [ChatStreamingMdComponent],\n },\n ],\n})\nexport class ChatStreamingMdComponent {\n readonly document = input.required();\n readonly viewRegistry = input(undefined);\n private readonly ancestorRegistry = inject(MARKDOWN_VIEW_REGISTRY, { optional: true, skipSelf: true });\n readonly resolvedRegistry = computed(() => this.viewRegistry() ?? this.ancestorRegistry ?? cacheplaneMarkdownViews);\n private readonly resolver = inject(CitationsResolverService, {\n optional: true,\n });\n private readonly violationPolicy = inject(STREAMING_MARKDOWN_CONTRACT_VIOLATION_POLICY);\n private readonly createParser = inject(STREAMING_MARKDOWN_PARSER_FACTORY);\n private parser: PartialMarkdownParser | null = null;\n private prior: StreamingMarkdownDocument | null = null;\n private materializedRoot: MarkdownDocumentNode | null = null;\n readonly root = computed(() => {\n this.process(this.document());\n return this.materializedRoot;\n });\n constructor() {\n effect(() => {\n const root = this.root();\n if (this.resolver) {\n this.resolver.markdownDefs.set(root?.citations ?? new Map());\n }\n });\n }\n private process(supplied: StreamingMarkdownDocument): void {\n const prior = this.prior;\n if (!prior || supplied.generation !== prior.generation) {\n this.replaceFrom(supplied);\n return;\n }\n if (supplied.phase === prior.phase && supplied.content === prior.content) {\n return;\n }\n const violationReason = contractViolationReason(prior, supplied);\n if (violationReason) {\n if (this.violationPolicy === 'throw') {\n throw contractViolation(prior, supplied, violationReason);\n }\n this.replaceFrom(supplied);\n return;\n }\n const parser = this.parser as PartialMarkdownParser;\n const delta = supplied.content.slice(prior.content.length);\n if (delta.length > 0)\n parser.push(delta);\n if (supplied.phase === 'complete')\n parser.finish();\n this.materializedRoot = materialize(parser.root) as MarkdownDocumentNode | null;\n this.prior = { ...supplied };\n }\n private replaceFrom(supplied: StreamingMarkdownDocument): void {\n const parser = this.createParser();\n parser.push(supplied.content);\n if (supplied.phase === 'complete')\n parser.finish();\n const root = materialize(parser.root) as MarkdownDocumentNode | null;\n this.parser = parser;\n this.prior = { ...supplied };\n this.materializedRoot = root;\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSubagentCardComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatSubagentCardComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-subagent-card/chat-subagent-card.component.ts", + "symbol": "ChatSubagentCardComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-subagent-card',\n standalone: true,\n imports: [ChatTraceComponent, ChatToolCallCardComponent, ChatStreamingMdComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host { display: block; }\n .sac__name { color: var(--tplane-chat-text); font-weight: 500; font-size: var(--tplane-chat-font-size-sm); }\n .sac__id { font-family: var(--tplane-chat-font-mono); font-size: var(--tplane-chat-font-size-xs); color: var(--tplane-chat-text-muted); margin-left: 4px; }\n .sac__pill {\n padding: 1px 8px;\n border-radius: 9999px;\n font-size: 11px;\n font-weight: 500;\n margin-left: 4px;\n }\n .sac__pill[data-status=\"pending\"] { background: var(--tplane-chat-surface-alt); color: var(--tplane-chat-text-muted); }\n .sac__pill[data-status=\"running\"] { background: var(--tplane-chat-warning-bg); color: var(--tplane-chat-warning-text); }\n .sac__pill[data-status=\"complete\"] { color: var(--tplane-chat-success); }\n .sac__pill[data-status=\"error\"] { background: var(--tplane-chat-error-bg); color: var(--tplane-chat-error-text); }\n .sac__count { font-size: var(--tplane-chat-font-size-xs); color: var(--tplane-chat-text-muted); }\n .sac__msg { padding: 6px 0; }\n .sac__msg + .sac__msg { border-top: 1px solid var(--tplane-chat-separator); }\n .sac__reasoning {\n font-size: var(--tplane-chat-font-size-xs);\n color: var(--tplane-chat-text-muted);\n font-style: italic;\n margin-bottom: 4px;\n }\n `],\n template: `\n \n \n {{ subagent().name ?? 'Subagent' }}\n {{ subagent().toolCallId }}\n {{ subagent().status() }}\n \n
    {{ subagent().messages().length }} message(s)
    \n @for (m of subagent().messages(); track m.id) {\n
    \n @if (m.reasoning) {\n
    {{ m.reasoning }}
    \n }\n @if (textOf(m); as t) {\n \n }\n @for (tc of toolCallsFor(m); track tc.id) {\n \n }\n
    \n }\n
    \n `,\n})\nexport class ChatSubagentCardComponent {\n readonly subagent = input.required();\n readonly state = computed(() => statusToTraceState(this.subagent().status()));\n private readonly markdownDocuments = new Map();\n constructor() {\n effect(() => {\n let liveIds: Set;\n try {\n liveIds = new Set(this.subagent().messages().map((message) => message.id));\n }\n catch {\n return;\n }\n for (const id of [...this.markdownDocuments.keys()]) {\n if (!liveIds.has(id))\n this.markdownDocuments.delete(id);\n }\n });\n }\n protected markdownDocumentFor(content: string, message: Message): StreamingMarkdownDocument {\n const prior = this.markdownDocuments.get(message.id);\n const delivery = message.delivery;\n if (prior?.generation === delivery.generation &&\n prior.phase === delivery.phase &&\n prior.content === content) {\n return prior;\n }\n const document = markdownDocument(content, delivery);\n this.markdownDocuments.set(message.id, document);\n return document;\n }\n protected textOf(m: Message): string {\n const c = m.content;\n return typeof c === 'string' ? c : '';\n }\n protected toolCallsFor(m: Message): ToolCall[] {\n const ids = m.toolCallIds ?? [];\n if (ids.length === 0)\n return [];\n const all = this.subagent().toolCalls?.() ?? [];\n return ids.map((id) => all.find((tc) => tc.id === id)).filter((tc): tc is ToolCall => !!tc);\n }\n protected toToolCallInfo(tc: ToolCall): ToolCallInfo {\n return { id: tc.id, name: tc.name, args: tc.args, result: tc.result, status: tc.status };\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSubagentsComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatSubagentsComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-subagents/chat-subagents.component.ts", + "symbol": "ChatSubagentsComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-subagents',\n standalone: true,\n imports: [NgTemplateOutlet, ChatSubagentCardComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @for (subagent of activeSubagents(); track subagent.toolCallId) {\n @if (templateRef()) {\n \n } @else {\n \n }\n }\n `,\n})\nexport class ChatSubagentsComponent {\n readonly agent = input.required();\n readonly templateRef = contentChild(TemplateRef);\n readonly activeSubagents = computed(() => activeSubagentsFromAgent(this.agent()));\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSuggestionsComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatSuggestionsComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-suggestions/chat-suggestions.component.ts", + "symbol": "ChatSuggestionsComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-suggestions',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_SUGGESTIONS_STYLES],\n template: `\n
    \n @for (s of suggestions(); track s) {\n \n }\n
    \n `,\n})\nexport class ChatSuggestionsComponent {\n readonly suggestions = input([]);\n readonly selected = output();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatThreadListComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatThreadListComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-thread-list/chat-thread-list.component.ts", + "symbol": "ChatThreadListComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-thread-list',\n standalone: true,\n imports: [NgTemplateOutlet, ChatOverflowMenuComponent, ChatConfirmDialogComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_THREAD_LIST_STYLES],\n template: `\n @if (showNewThreadButton()) {\n \n }\n
      \n @for (thread of visibleThreads(); track thread.id) {\n \n @if (templateRef()) {\n \n } @else if (editingThreadId() === thread.id) {\n \n } @else {\n \n {{ initialOf(threadLabel(thread)) }}\n \n @if (thread.pinned) {\n \n \n \n \n @if (actions()?.reorderPinned) {\n ⋮⋮\n }\n \n }\n {{ threadLabel(thread) }}\n \n @if (thread.updatedAt !== undefined) {\n {{ relativeTime(thread.updatedAt) }}\n }\n \n\n @if (showKebab()) {\n ⋯\n }\n }\n \n }\n
    \n\n \n\n \n\n \n `,\n})\nexport class ChatThreadListComponent {\n readonly threads = input.required();\n readonly activeThreadId = input('');\n readonly showNewThreadButton = input(false);\n readonly actions = input(null);\n readonly mode = input<'active' | 'archived'>('active');\n readonly projects = input(null);\n readonly threadSelected = output();\n readonly newThreadRequested = output();\n readonly templateRef = contentChild(TemplateRef);\n protected readonly editingThreadId = signal(null);\n protected readonly editingValue = signal('');\n protected readonly menuOpenForId = signal(null);\n protected readonly menuAnchor = signal(null);\n protected readonly menuAnchorPos = signal<{\n x: number;\n y: number;\n } | null>(null);\n protected readonly confirmDeleteId = signal(null);\n protected readonly moveMenuOpenForId = signal(null);\n protected readonly moveMenuItems = computed(() => {\n if (!this.moveMenuOpenForId())\n return [];\n const list: OverflowMenuItem[] = [{ id: '__none__', label: 'No project' }];\n for (const p of this.projects() ?? []) {\n list.push({ id: p.id, label: p.name });\n }\n return list;\n });\n private readonly pendingHidden = signal>(new Set());\n private readonly pendingRenames = signal>(new Map());\n private readonly pendingOrder = signal>(new Map());\n protected readonly draggingThreadId = signal(null);\n protected readonly dropTarget = signal<{\n threadId: string;\n position: 'before' | 'after';\n } | null>(null);\n protected readonly visibleThreads = computed(() => {\n const hidden = this.pendingHidden();\n const renames = this.pendingRenames();\n const pending = this.pendingOrder();\n let result = this.threads()\n .filter((t) => !hidden.has(t.id))\n .map((t) => (renames.has(t.id) ? ({ ...t, title: renames.get(t.id) }) : t));\n if (pending.size > 0) {\n const pinned = result.filter((t) => t.pinned === true);\n const unpinned = result.filter((t) => t.pinned !== true);\n for (const [threadId, beforeId] of pending) {\n const idx = pinned.findIndex((t) => t.id === threadId);\n if (idx < 0)\n continue;\n const [moved] = pinned.splice(idx, 1);\n if (beforeId === null) {\n pinned.push(moved);\n }\n else {\n const beforeIdx = pinned.findIndex((t) => t.id === beforeId);\n if (beforeIdx < 0)\n pinned.push(moved);\n else\n pinned.splice(beforeIdx, 0, moved);\n }\n }\n result = [...pinned, ...unpinned];\n }\n return result;\n });\n protected readonly currentMenuItems = computed(() => {\n const id = this.menuOpenForId();\n if (!id)\n return [];\n const a = this.actions();\n if (!a)\n return [];\n const items: OverflowMenuItem[] = [];\n if (this.mode() === 'active') {\n const thread = this.threads().find((t) => t.id === id);\n const isPinned = thread?.pinned === true;\n if (a.rename)\n items.push({ id: 'rename', label: 'Rename' });\n if (a.pin && !isPinned)\n items.push({ id: 'pin', label: 'Pin' });\n if (a.unpin && isPinned)\n items.push({ id: 'unpin', label: 'Unpin' });\n if (isPinned && a.reorderPinned) {\n const pinned = this.threads().filter((t) => t.pinned === true);\n const pinnedIdx = pinned.findIndex((t) => t.id === id);\n if (pinnedIdx > 0)\n items.push({ id: 'move-up', label: 'Move up' });\n if (pinnedIdx >= 0 && pinnedIdx < pinned.length - 1)\n items.push({ id: 'move-down', label: 'Move down' });\n }\n if (a.moveToProject && this.projects() !== null) {\n items.push({ id: 'move', label: 'Move to project' });\n }\n if (a.archive)\n items.push({ id: 'archive', label: 'Archive' });\n if (a.delete)\n items.push({ id: 'delete', label: 'Delete', tone: 'destructive' });\n }\n else {\n if (a.unarchive)\n items.push({ id: 'unarchive', label: 'Unarchive' });\n if (a.delete)\n items.push({ id: 'delete', label: 'Delete', tone: 'destructive' });\n }\n return items;\n });\n private readonly editInput = viewChild>('editInput');\n selectThread(threadId: string): void {\n this.threadSelected.emit(threadId);\n }\n protected threadLabel(thread: Thread): string {\n const title = thread['title'];\n if (typeof title === 'string' && title.length > 0)\n return title;\n return thread.id;\n }\n protected relativeTime(epochMs: number): string {\n const delta = Date.now() - epochMs;\n if (delta < 60000)\n return 'just now';\n if (delta < 3600000)\n return `${Math.floor(delta / 60000)} min ago`;\n if (delta < 86400000)\n return `${Math.floor(delta / 3600000)} hr ago`;\n return `${Math.floor(delta / 86400000)} day ago`;\n }\n protected showKebab(): boolean {\n const a = this.actions();\n if (!a)\n return false;\n if (this.mode() === 'active') {\n return Boolean(a.rename || a.pin || a.unpin || a.archive || a.delete ||\n a.reorderPinned ||\n (a.moveToProject && this.projects() !== null));\n }\n return Boolean(a.unarchive || a.delete);\n }\n protected openMenu(threadId: string, anchor: HTMLElement): void {\n this.menuAnchor.set(anchor);\n this.menuAnchorPos.set(null);\n this.menuOpenForId.set(threadId);\n }\n protected onRowContextMenu(threadId: string, event: MouseEvent): void {\n event.preventDefault();\n if (!this.showKebab())\n return;\n if (this.editingThreadId() !== null)\n return;\n this.menuAnchor.set(null);\n this.menuAnchorPos.set({ x: event.clientX, y: event.clientY });\n this.menuOpenForId.set(threadId);\n }\n protected initialOf(title: string): string {\n const trimmed = (title ?? '').trim();\n if (!trimmed)\n return '?';\n const first = Array.from(trimmed)[0];\n return first.toUpperCase ? first.toUpperCase() : first;\n }\n protected onMenuAction(id: string): void {\n const threadId = this.menuOpenForId();\n this.menuOpenForId.set(null);\n if (!threadId)\n return;\n if (id === 'rename') {\n const t = this.threads().find((x) => x.id === threadId);\n this.editingValue.set(typeof t?.title === 'string' ? t.title : '');\n this.editingThreadId.set(threadId);\n queueMicrotask(() => this.editInput()?.nativeElement.focus());\n }\n else if (id === 'delete') {\n this.confirmDeleteId.set(threadId);\n }\n else if (id === 'archive') {\n void this.performArchive(threadId);\n }\n else if (id === 'unarchive') {\n void this.performUnarchive(threadId);\n }\n else if (id === 'pin') {\n void this.performPin(threadId);\n }\n else if (id === 'unpin') {\n void this.performUnpin(threadId);\n }\n else if (id === 'move') {\n this.moveMenuOpenForId.set(threadId);\n }\n else if (id === 'move-up') {\n void this.performMoveUp(threadId);\n }\n else if (id === 'move-down') {\n void this.performMoveDown(threadId);\n }\n }\n protected async performPin(threadId: string): Promise {\n const a = this.actions();\n if (!a?.pin)\n return;\n try {\n await a.pin(threadId);\n }\n catch { }\n }\n protected async performUnpin(threadId: string): Promise {\n const a = this.actions();\n if (!a?.unpin)\n return;\n try {\n await a.unpin(threadId);\n }\n catch { }\n }\n protected onEditInput(e: Event): void {\n this.editingValue.set((e.target as HTMLInputElement).value);\n }\n protected cancelRename(): void {\n this.editingThreadId.set(null);\n }\n protected async commitRename(threadId: string): Promise {\n const newTitle = this.editingValue().trim();\n this.editingThreadId.set(null);\n if (!newTitle)\n return;\n const a = this.actions();\n if (!a?.rename)\n return;\n this.pendingRenames.update((m) => {\n const n = new Map(m);\n n.set(threadId, newTitle);\n return n;\n });\n try {\n await a.rename(threadId, newTitle);\n }\n catch {\n }\n finally {\n this.pendingRenames.update((m) => {\n const n = new Map(m);\n n.delete(threadId);\n return n;\n });\n }\n }\n protected async performDelete(): Promise {\n const threadId = this.confirmDeleteId();\n this.confirmDeleteId.set(null);\n if (!threadId)\n return;\n const a = this.actions();\n if (!a?.delete)\n return;\n this.pendingHidden.update((s) => new Set([...s, threadId]));\n try {\n await a.delete(threadId);\n }\n catch {\n }\n finally {\n this.pendingHidden.update((s) => {\n const n = new Set(s);\n n.delete(threadId);\n return n;\n });\n }\n }\n protected async performArchive(threadId: string): Promise {\n const a = this.actions();\n if (!a?.archive)\n return;\n this.pendingHidden.update((s) => new Set([...s, threadId]));\n try {\n await a.archive(threadId);\n }\n catch {\n }\n finally {\n this.pendingHidden.update((s) => {\n const n = new Set(s);\n n.delete(threadId);\n return n;\n });\n }\n }\n protected onMoveMenuAction(itemId: string): void {\n const threadId = this.moveMenuOpenForId();\n this.moveMenuOpenForId.set(null);\n if (!threadId)\n return;\n const projectId = itemId === '__none__' ? null : itemId;\n void this.performMoveToProject(threadId, projectId);\n }\n protected async performMoveToProject(threadId: string, projectId: string | null): Promise {\n const a = this.actions();\n if (!a?.moveToProject)\n return;\n this.pendingHidden.update((s) => new Set([...s, threadId]));\n try {\n await a.moveToProject(threadId, projectId);\n }\n catch {\n }\n finally {\n this.pendingHidden.update((s) => {\n const n = new Set(s);\n n.delete(threadId);\n return n;\n });\n }\n }\n protected async performReorderPinned(threadId: string, beforeId: string | null): Promise {\n const a = this.actions();\n if (!a?.reorderPinned)\n return;\n this.pendingOrder.update((m) => {\n const n = new Map(m);\n n.set(threadId, beforeId);\n return n;\n });\n try {\n await a.reorderPinned(threadId, beforeId);\n }\n catch {\n }\n finally {\n this.pendingOrder.update((m) => {\n const n = new Map(m);\n n.delete(threadId);\n return n;\n });\n }\n }\n protected async performMoveUp(threadId: string): Promise {\n const pinned = this.threads().filter((t) => t.pinned === true);\n const idx = pinned.findIndex((t) => t.id === threadId);\n if (idx <= 0)\n return;\n const beforeId = pinned[idx - 1].id;\n await this.performReorderPinned(threadId, beforeId);\n }\n protected async performMoveDown(threadId: string): Promise {\n const pinned = this.threads().filter((t) => t.pinned === true);\n const idx = pinned.findIndex((t) => t.id === threadId);\n if (idx < 0 || idx >= pinned.length - 1)\n return;\n const beforeId = idx + 2 < pinned.length ? pinned[idx + 2].id : null;\n await this.performReorderPinned(threadId, beforeId);\n }\n protected onDragStart(e: DragEvent, threadId: string): void {\n const dt = e.dataTransfer;\n if (!dt)\n return;\n dt.setData('text/plain', threadId);\n dt.effectAllowed = 'move';\n this.draggingThreadId.set(threadId);\n }\n protected onDragOver(e: DragEvent, threadId: string): void {\n const dragging = this.draggingThreadId();\n if (!dragging || dragging === threadId)\n return;\n const target = this.threads().find((t) => t.id === threadId);\n if (target?.pinned !== true)\n return;\n e.preventDefault();\n if (e.dataTransfer)\n e.dataTransfer.dropEffect = 'move';\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const offsetY = e.clientY - rect.top;\n const position: 'before' | 'after' = offsetY < rect.height / 2 ? 'before' : 'after';\n const cur = this.dropTarget();\n if (!cur || cur.threadId !== threadId || cur.position !== position) {\n this.dropTarget.set({ threadId, position });\n }\n }\n protected onDragLeave(_e: DragEvent, threadId: string): void {\n if (this.dropTarget()?.threadId === threadId) {\n this.dropTarget.set(null);\n }\n }\n protected onDrop(e: DragEvent, targetThreadId: string): void {\n e.preventDefault();\n const dragId = e.dataTransfer?.getData('text/plain') ?? this.draggingThreadId();\n const target = this.dropTarget();\n this.draggingThreadId.set(null);\n this.dropTarget.set(null);\n if (!dragId || dragId === targetThreadId || !target)\n return;\n const pinned = this.threads().filter((t) => t.pinned === true);\n const targetIdx = pinned.findIndex((t) => t.id === targetThreadId);\n if (targetIdx < 0)\n return;\n let beforeId: string | null;\n if (target.position === 'before') {\n beforeId = targetThreadId;\n }\n else {\n const filteredPinned = pinned.filter((t) => t.id !== dragId);\n const filteredTargetIdx = filteredPinned.findIndex((t) => t.id === targetThreadId);\n beforeId = filteredTargetIdx + 1 < filteredPinned.length\n ? filteredPinned[filteredTargetIdx + 1].id\n : null;\n }\n void this.performReorderPinned(dragId, beforeId);\n }\n protected onDragEnd(): void {\n this.draggingThreadId.set(null);\n this.dropTarget.set(null);\n }\n protected dropPositionFor(threadId: string): 'before' | 'after' | null {\n const t = this.dropTarget();\n return t?.threadId === threadId ? t.position : null;\n }\n protected async performUnarchive(threadId: string): Promise {\n const a = this.actions();\n if (!a?.unarchive)\n return;\n this.pendingHidden.update((s) => new Set([...s, threadId]));\n try {\n await a.unarchive(threadId);\n }\n catch {\n }\n finally {\n this.pendingHidden.update((s) => {\n const n = new Set(s);\n n.delete(threadId);\n return n;\n });\n }\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatTimelineComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatTimelineComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-timeline/chat-timeline.component.ts", + "symbol": "ChatTimelineComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-timeline',\n standalone: true,\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @for (cp of history(); track $index) {\n @if (templateRef()) {\n \n }\n }\n `,\n})\nexport class ChatTimelineComponent {\n readonly agent = input.required();\n readonly checkpointSelected = output();\n readonly templateRef = contentChild(TemplateRef);\n readonly history = computed(() => this.agent().history());\n selectCheckpoint(cp: AgentCheckpoint): void {\n this.checkpointSelected.emit(cp);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatTimelineSliderComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatTimelineSliderComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-timeline-slider/chat-timeline-slider.component.ts", + "symbol": "ChatTimelineSliderComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-timeline-slider',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host { display: block; padding: var(--tplane-chat-space-2); }\n .timeline-slider__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 var(--tplane-chat-space-1) var(--tplane-chat-space-2);\n }\n .timeline-slider__title {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--tplane-chat-text-muted);\n margin: 0;\n }\n .timeline-slider__count {\n font-size: var(--tplane-chat-font-size-xs);\n color: var(--tplane-chat-text-muted);\n }\n .timeline-slider__empty {\n text-align: center;\n padding: var(--tplane-chat-space-4);\n color: var(--tplane-chat-text-muted);\n font-size: var(--tplane-chat-font-size-xs);\n }\n .timeline-slider__list {\n list-style: none;\n padding-left: 12px;\n margin: 0;\n border-left: 1px solid var(--tplane-chat-separator);\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n .timeline-slider__entry {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n margin-left: -1px;\n border-left: 2px solid transparent;\n border-radius: var(--tplane-chat-radius-button);\n cursor: default;\n color: var(--tplane-chat-text-muted);\n font-size: var(--tplane-chat-font-size-sm);\n transition: background 150ms ease;\n }\n .timeline-slider__entry:hover { background: color-mix(in srgb, var(--tplane-chat-text) 5%, transparent); }\n .timeline-slider__entry[data-active=\"true\"] {\n border-left-color: var(--tplane-chat-primary);\n color: var(--tplane-chat-text);\n }\n .timeline-slider__index {\n width: 22px;\n height: 22px;\n border-radius: 9999px;\n background: var(--tplane-chat-surface-alt);\n color: var(--tplane-chat-text-muted);\n font-size: 11px;\n font-weight: 600;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n .timeline-slider__entry[data-active=\"true\"] .timeline-slider__index {\n background: var(--tplane-chat-primary);\n color: var(--tplane-chat-on-primary);\n }\n .timeline-slider__body { flex: 1; min-width: 0; }\n .timeline-slider__label {\n font-weight: 500;\n color: var(--tplane-chat-text);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--tplane-chat-font-size-sm);\n }\n .timeline-slider__id {\n font-family: var(--tplane-chat-font-mono);\n font-size: 11px;\n color: var(--tplane-chat-text-muted);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .timeline-slider__actions { display: flex; gap: 4px; flex-shrink: 0; }\n .timeline-slider__btn {\n padding: 2px 8px;\n font-size: var(--tplane-chat-font-size-xs);\n border-radius: var(--tplane-chat-radius-button);\n background: var(--tplane-chat-surface-alt);\n color: var(--tplane-chat-text);\n border: 0;\n cursor: pointer;\n transition: background 150ms ease;\n }\n .timeline-slider__btn:hover { background: color-mix(in srgb, var(--tplane-chat-text) 8%, transparent); }\n `],\n template: `\n
    \n

    Timeline

    \n {{ history().length }} checkpoint(s)\n
    \n\n @if (history().length === 0) {\n

    No checkpoints yet.

    \n } @else {\n
      \n @for (cp of history(); track $index; let i = $index) {\n \n {{ i + 1 }}\n
      \n

      {{ cp.label ?? 'Step ' + (i + 1) }}

      \n @if (cp.id) {\n

      {{ cp.id }}

      \n }\n
      \n
      \n \n \n
      \n \n }\n
    \n }\n `,\n})\nexport class ChatTimelineSliderComponent {\n readonly agent = input.required();\n readonly selectedIndex = signal(-1);\n readonly history = computed(() => this.agent().history());\n readonly replayRequested = output();\n readonly forkRequested = output();\n replay(cp: AgentCheckpoint): void {\n if (cp.id)\n this.replayRequested.emit(cp.id);\n }\n fork(cp: AgentCheckpoint, index: number): void {\n this.selectedIndex.set(index);\n if (cp.id)\n this.forkRequested.emit(cp.id);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatToolCallCardComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatToolCallCardComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-tool-call-card/chat-tool-call-card.component.ts", + "symbol": "ChatToolCallCardComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-tool-call-card',\n standalone: true,\n imports: [ChatTraceComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, `\n :host { display: block; }\n .tcc__name {\n font-family: var(--tplane-chat-font-mono);\n font-size: var(--tplane-chat-font-size-sm, 13px);\n color: var(--tplane-chat-text-muted);\n font-weight: 400;\n padding-left: 2px;\n }\n .tcc__pill {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 1px 6px;\n border-radius: 9999px;\n background: var(--tplane-chat-surface-alt);\n color: var(--tplane-chat-text-muted);\n font-size: 10px;\n font-weight: 500;\n margin-left: 6px;\n line-height: 1.4;\n }\n .tcc__pill svg { width: 10px; height: 10px; }\n .tcc__pill[data-status=\"running\"] svg { animation: tcc-spin 0.8s linear infinite; }\n @keyframes tcc-spin { to { transform: rotate(360deg); } }\n .tcc__section { padding: 8px 0; }\n .tcc__section + .tcc__section { border-top: 1px solid var(--tplane-chat-separator); }\n .tcc__section-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--tplane-chat-text-muted);\n margin: 0 0 4px;\n }\n .tcc__section-body {\n font-family: var(--tplane-chat-font-mono);\n font-size: var(--tplane-chat-font-size-xs);\n color: var(--tplane-chat-text);\n white-space: pre-wrap;\n overflow-x: auto;\n margin: 0;\n }\n `],\n template: `\n \n \n {{ toolCall().name }}\n \n @switch (status()) {\n @case ('running') {\n \n \n \n }\n @case ('complete') {\n \n \n \n }\n @case ('error') {\n \n \n \n \n }\n }\n \n \n
    \n \n
    {{ formatJson(toolCall().args) }}
    \n
    \n @if (toolCall().result !== undefined) {\n
    \n \n
    {{ formatJson(toolCall().result) }}
    \n
    \n }\n
    \n `,\n})\nexport class ChatToolCallCardComponent {\n readonly toolCall = input.required();\n readonly defaultCollapsed = input(true);\n readonly status = computed(() => {\n const tc = this.toolCall();\n if (tc.status)\n return tc.status;\n return tc.result !== undefined ? 'complete' : 'running';\n });\n readonly state = computed(() => {\n switch (this.status()) {\n case 'complete': return 'done';\n case 'error': return 'error';\n case 'running': return 'running';\n default: return 'pending';\n }\n });\n readonly autoExpanded = computed(() => {\n const s = this.status();\n if (s === 'running' || s === 'error')\n return true;\n return !this.defaultCollapsed();\n });\n readonly ariaLabel = computed(() => {\n switch (this.status()) {\n case 'running': return 'Running';\n case 'complete': return 'Completed';\n case 'error': return 'Failed';\n default: return '';\n }\n });\n formatJson(value: unknown): string {\n if (typeof value === 'string')\n return value;\n try {\n return JSON.stringify(value, null, 2);\n }\n catch {\n return String(value);\n }\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatToolCallTemplateContext", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatToolCallTemplateContext", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-call-template.directive.ts", + "symbol": "ChatToolCallTemplateContext", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ChatToolCallTemplateContext {\n $implicit: ToolCall;\n status: ToolCallStatus;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatToolCallTemplateDirective", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatToolCallTemplateDirective", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-call-template.directive.ts", + "symbol": "ChatToolCallTemplateDirective", + "syntaxKind": "ClassDeclaration", + "signature": "@Directive({\n selector: '[chatToolCallTemplate]',\n standalone: true,\n})\nexport class ChatToolCallTemplateDirective {\n readonly name = input.required({ alias: 'chatToolCallTemplate' });\n readonly templateRef = inject(TemplateRef);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatToolCallsComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatToolCallsComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-calls.component.ts", + "symbol": "ChatToolCallsComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-tool-calls',\n standalone: true,\n imports: [NgTemplateOutlet, ChatToolCallCardComponent, ChatSubagentCardComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [`\n :host { display: block; margin-bottom: 20px; }\n .ctc__group {\n border: 1px solid var(--tplane-chat-separator);\n border-radius: var(--tplane-chat-radius-card);\n margin: 0 0 4px;\n }\n .ctc__group-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 8px 12px;\n background: transparent;\n border: 0;\n font: inherit;\n color: var(--tplane-chat-text);\n cursor: pointer;\n text-align: left;\n }\n .ctc__group-chevron {\n width: 10px; height: 10px;\n transition: transform 120ms ease;\n }\n .ctc__group[data-expanded=\"true\"] .ctc__group-chevron { transform: rotate(90deg); }\n .ctc__group-body {\n padding: 0 12px 8px;\n border-top: 1px solid var(--tplane-chat-separator);\n }\n `],\n template: `\n @for (group of groups(); track $index) {\n @if (group.subagent) {\n \n } @else if (group.calls.length > 1 && !group.templateRef) {\n \n @let expanded = expandedGroups().has($index);\n
    \n \n @if (expanded) {\n
    \n @for (tc of group.calls; track tc.id) {\n \n }\n
    \n }\n
    \n } @else if (group.templateRef) {\n @for (tc of group.calls; track tc.id) {\n \n }\n } @else {\n @for (tc of group.calls; track tc.id) {\n \n }\n }\n }\n `,\n})\nexport class ChatToolCallsComponent {\n readonly agent = input.required();\n readonly message = input(undefined);\n readonly grouping = input<'auto' | 'none'>('auto');\n readonly groupSummary = input<((name: string, count: number) => string) | undefined>(undefined);\n readonly excludeToolNames = input([]);\n readonly templates = contentChildren(ChatToolCallTemplateDirective);\n private readonly templateRegistry = computed(() => {\n const map = new Map();\n for (const t of this.templates()) {\n map.set(t.name(), t);\n }\n return map;\n });\n readonly toolCalls = computed((): ToolCall[] => resolveMessageToolCalls(this.agent(), this.message()));\n readonly groups = computed((): Group[] => {\n const excludeSet = new Set(this.excludeToolNames());\n const calls = this.toolCalls().filter(tc => !excludeSet.has(tc.name));\n const rawSubs = this.agent().subagents?.() ?? new Map();\n const subs = new Map();\n rawSubs.forEach((sa) => subs.set(sa.toolCallId, sa));\n const groupingMode = this.grouping();\n const registry = this.templateRegistry();\n const wildcard = registry.get('*');\n const out: Group[] = [];\n for (const tc of calls) {\n if (subs.has(tc.id)) {\n out.push({ name: tc.name, calls: [tc], subagent: subs.get(tc.id) });\n continue;\n }\n const tpl = registry.get(tc.name) ?? wildcard;\n const last = out[out.length - 1];\n const sameName = last && !last.subagent && last.name === tc.name;\n const canGroup = groupingMode === 'auto' && sameName;\n if (canGroup) {\n last.calls.push(tc);\n if (!last.templateRef && tpl)\n last.templateRef = tpl;\n }\n else {\n out.push({ name: tc.name, calls: [tc], templateRef: tpl });\n }\n }\n return out;\n });\n private readonly _expandedGroups = signal(new Set());\n readonly expandedGroups = this._expandedGroups.asReadonly();\n toggleGroup(index: number): void {\n this._expandedGroups.update((prev) => {\n const next = new Set(prev);\n if (next.has(index))\n next.delete(index);\n else\n next.add(index);\n return next;\n });\n }\n protected summarize(name: string, count: number): string {\n return (this.groupSummary() ?? defaultSummarizeGroup)(name, count);\n }\n protected toToolCallInfo(tc: ToolCall): ToolCallInfo {\n return { id: tc.id, name: tc.name, args: tc.args, result: tc.result, status: tc.status };\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatToolViewsComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatToolViewsComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-tool-views/chat-tool-views.component.ts", + "symbol": "ChatToolViewsComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-tool-views',\n standalone: true,\n imports: [ChatGenerativeUiComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @for (view of toolViews(); track view.id) {\n \n }\n `,\n})\nexport class ChatToolViewsComponent {\n readonly agent = input.required();\n readonly events = output();\n readonly message = input(undefined);\n readonly views = input(undefined);\n readonly store = input(undefined);\n readonly handlers = input) => unknown | Promise>>({});\n readonly registry = computed(() => {\n const v = this.views();\n return v ? toRenderRegistry(v) : undefined;\n });\n readonly toolViews = computed(() => {\n const v = this.views();\n if (!v)\n return [];\n const names = new Set(Object.keys(v));\n return resolveMessageToolCalls(this.agent(), this.message())\n .filter((tc) => names.has(tc.name))\n .map((tc) => ({ id: tc.id, loading: tc.status === 'running', spec: toToolViewSpec(tc) }));\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatTraceComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatTraceComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-trace/chat-trace.component.ts", + "symbol": "ChatTraceComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-trace',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_TRACE_STYLES],\n host: {\n '[attr.data-state]': 'state()',\n '[attr.data-expanded]': 'expandedStr()',\n },\n template: `\n \n \n \n \n \n \n \n \n \n \n @if (expanded()) {\n
    \n }\n `,\n})\nexport class ChatTraceComponent {\n readonly state = input('pending');\n readonly defaultExpanded = input(false);\n private readonly _expandedOverride = signal(null);\n readonly expanded = computed(() => {\n const override = this._expandedOverride();\n if (override !== null)\n return override;\n const s = this.state();\n if (s === 'running' || s === 'error')\n return true;\n return this.defaultExpanded();\n });\n readonly expandedStr = computed(() => String(this.expanded()));\n constructor() {\n let prevState: TraceState | undefined;\n effect(() => {\n const s = this.state();\n if ((s === 'running' || s === 'error') && prevState && prevState !== s) {\n this._expandedOverride.set(null);\n }\n prevState = s;\n });\n }\n toggle(): void {\n this._expandedOverride.set(!this.expanded());\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatTypingIndicatorComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatTypingIndicatorComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-typing-indicator/chat-typing-indicator.component.ts", + "symbol": "ChatTypingIndicatorComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-typing-indicator',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_TYPING_INDICATOR_STYLES],\n template: `\n @if (visible()) {\n
    \n \n \n \n
    \n }\n `,\n})\nexport class ChatTypingIndicatorComponent {\n readonly agent = input.required();\n readonly visible = computed(() => isTyping(this.agent()));\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatWelcomeComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatWelcomeComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-welcome/chat-welcome.component.ts", + "symbol": "ChatWelcomeComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-welcome',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_WELCOME_STYLES],\n template: `\n
    \n \n \n

    How can I help?

    \n
    \n
    \n
    \n \n
    \n
    \n `,\n})\nexport class ChatWelcomeComponent {\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatWelcomeSuggestionComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatWelcomeSuggestionComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-welcome/chat-welcome-suggestion.component.ts", + "symbol": "ChatWelcomeSuggestionComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-welcome-suggestion',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_WELCOME_SUGGESTION_STYLES],\n template: `\n \n \n {{ label() }}\n \n \n `,\n})\nexport class ChatWelcomeSuggestionComponent {\n readonly label = input.required();\n readonly value = input.required();\n readonly description = input();\n readonly selected = output();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatWindowComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ChatWindowComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-window/chat-window.component.ts", + "symbol": "ChatWindowComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-window',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CHAT_HOST_TOKENS, CHAT_WINDOW_STYLES],\n template: `\n
    \n
    \n
    \n
    \n \n
    \n `,\n})\nexport class ChatWindowComponent {\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#Citation", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "Citation", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation.ts", + "symbol": "Citation", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface Citation {\n id: string;\n index: number;\n title?: string;\n url?: string;\n snippet?: string;\n extra?: Record;\n sourceType?: string;\n iconUrl?: string;\n publishedAt?: string | number | Date;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationImageVisual", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "CitationImageVisual", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "CitationImageVisual", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface CitationImageVisual {\n kind: 'image';\n iconUrl: string;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationMonogramVisual", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "CitationMonogramVisual", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "CitationMonogramVisual", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface CitationMonogramVisual {\n kind: 'monogram';\n monogram: string;\n color: string;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationSourceVisual", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "CitationSourceVisual", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "CitationSourceVisual", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type CitationSourceVisual = CitationImageVisual | CitationTypeIconVisual | CitationMonogramVisual;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationTypeIcon", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "CitationTypeIcon", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "CitationTypeIcon", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type CitationTypeIcon = 'web' | 'file' | 'app' | 'memory' | 'generic';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationTypeIconVisual", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "CitationTypeIconVisual", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "CitationTypeIconVisual", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface CitationTypeIconVisual {\n kind: 'type-icon';\n icon: CitationTypeIcon;\n tone: CitationTypeIcon;\n label: string | null;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationTypeMeta", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "CitationTypeMeta", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "CitationTypeMeta", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface CitationTypeMeta {\n type: string;\n label: string | null;\n icon: CitationTypeIcon;\n tone: CitationTypeIcon;\n isKnown: boolean;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationsResolverService", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "CitationsResolverService", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/citations-resolver.service.ts", + "symbol": "CitationsResolverService", + "syntaxKind": "ClassDeclaration", + "signature": "@Injectable()\nexport class CitationsResolverService {\n readonly message = signal(null);\n readonly markdownDefs = signal>(new Map());\n lookup(refId: string): Signal {\n return computed(() => {\n const fromMessage = this.message()?.citations?.find(c => c.id === refId);\n if (fromMessage)\n return { source: 'message', citation: fromMessage };\n const fromMd = this.markdownDefs().get(refId);\n if (fromMd)\n return { source: 'markdown', citation: mdDefToCitation(fromMd) };\n return null;\n });\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolContinuationLimitEvent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolContinuationLimitEvent", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "ClientToolContinuationLimitEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolContinuationLimitEvent {\n readonly maxTurns: number;\n readonly attemptedTurn: number;\n readonly toolCallIds: readonly string[];\n readonly toolNames: readonly string[];\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolContinuationOptions", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolContinuationOptions", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "ClientToolContinuationOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolContinuationOptions {\n readonly followUp?: boolean;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolContinuationPolicy", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolContinuationPolicy", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "ClientToolContinuationPolicy", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolContinuationPolicy {\n readonly maxTurns?: number;\n readonly onLimit?: (event: ClientToolContinuationLimitEvent) => void;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolDef", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolDef", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "ClientToolDef", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ClientToolDef = AnyFunctionToolDef | ViewToolDef | AskToolDef;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutionGuard", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolExecutionGuard", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "symbol": "ClientToolExecutionGuard", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolExecutionGuard {\n readonly threadId: string;\n readonly store: ClientToolExecutionStore;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutionKey", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolExecutionKey", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "symbol": "ClientToolExecutionKey", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolExecutionKey {\n readonly threadId: string;\n readonly toolCallId: string;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutionOptions", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolExecutionOptions", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "ClientToolExecutionOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolExecutionOptions extends ClientToolContinuationOptions {\n readonly idempotent?: boolean;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutionRecord", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolExecutionRecord", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "symbol": "ClientToolExecutionRecord", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ClientToolExecutionRecord = {\n readonly status: 'executing';\n} | {\n readonly status: 'done';\n readonly result: ClientToolResult;\n} | {\n readonly status: 'failed';\n readonly result?: ClientToolResult;\n};" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutionStore", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolExecutionStore", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "symbol": "ClientToolExecutionStore", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolExecutionStore {\n claim(key: ClientToolExecutionKey): Promise<'claimed' | ClientToolExecutionRecord>;\n record(key: ClientToolExecutionKey, result: ClientToolResult): Promise;\n lookup(threadId: string, toolCallIds: readonly string[]): Promise>;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutorOptions", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolExecutorOptions", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tool-executor.ts", + "symbol": "ClientToolExecutorOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolExecutorOptions {\n readonly executionGuard?: ClientToolExecutionGuard;\n readonly settleToolCall?: (toolCall: ToolCall, result: ClientToolResult) => void;\n readonly settleWithoutContinuing?: (toolCall: ToolCall, result: ClientToolResult) => void;\n readonly shouldExecuteToolCall?: (toolCall: ToolCall) => boolean;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolLifecycle", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolLifecycle", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "ClientToolLifecycle", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolLifecycle {\n readonly id: string;\n readonly name: string;\n readonly status: ToolCallStatus;\n readonly phase: ClientToolLifecyclePhase;\n readonly hasResult: boolean;\n readonly result?: unknown;\n readonly error?: unknown;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolLifecyclePhase", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolLifecyclePhase", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "ClientToolLifecyclePhase", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ClientToolLifecyclePhase = 'running' | 'complete' | 'error';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolRegistry", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolRegistry", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "ClientToolRegistry", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ClientToolRegistry = Readonly>;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolResult", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolResult", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tools-capability.ts", + "symbol": "ClientToolResult", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ClientToolResult = {\n readonly ok: true;\n readonly value: unknown;\n} | {\n readonly ok: false;\n readonly error: string;\n};" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolSpec", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolSpec", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/to-json-schema.ts", + "symbol": "ClientToolSpec", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolSpec {\n readonly name: string;\n readonly description: string;\n readonly parameters: Record;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolViewProps", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolViewProps", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "ClientToolViewProps", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ClientToolViewProps = StandardSchemaInferOutput & {\n readonly status?: ToolCallStatus;\n readonly clientTool?: ClientToolLifecycle;\n};" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolsCapability", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolsCapability", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tools-capability.ts", + "symbol": "ClientToolsCapability", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolsCapability {\n setCatalog(specs: readonly ClientToolSpec[]): void;\n readonly pending: Signal;\n settle?(toolCallId: string, result: ClientToolResult): void;\n flush?(): void | Promise;\n resolve(toolCallId: string, result: ClientToolResult): void;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolsCoordinator", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ClientToolsCoordinator", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tools-coordinator.ts", + "symbol": "ClientToolsCoordinator", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolsCoordinator {\n readonly viewRegistry: ViewRegistry;\n connect(agent: Agent): void;\n handleRenderEvent(agent: Agent, event: RenderEvent): void;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#CompleteOutcome", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "CompleteOutcome", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message-delivery.ts", + "symbol": "CompleteOutcome", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type CompleteOutcome = 'success' | 'error' | 'aborted' | 'interrupted' | 'paused';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ConnectedPosition", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ConnectedPosition", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/overlay/connected-position.ts", + "symbol": "ConnectedPosition", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ConnectedPosition {\n originX: HorizontalConnectionPos;\n originY: VerticalConnectionPos;\n overlayX: HorizontalConnectionPos;\n overlayY: VerticalConnectionPos;\n offsetX?: number;\n offsetY?: number;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ContentBlock", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ContentBlock", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/content-block.ts", + "symbol": "ContentBlock", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ContentBlock = {\n type: 'text';\n text: string;\n} | {\n type: 'image';\n url: string;\n alt?: string;\n} | {\n type: 'tool_use';\n id: string;\n name: string;\n args: unknown;\n} | {\n type: 'tool_result';\n toolCallId: string;\n result: unknown;\n isError?: boolean;\n};" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ContentClassifier", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ContentClassifier", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/content-classifier.ts", + "symbol": "ContentClassifier", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ContentClassifier {\n update(content: string): void;\n readonly type: Signal;\n readonly markdown: Signal;\n readonly spec: Signal;\n readonly elementStates: Signal>;\n readonly a2uiSurfaces: Signal>;\n readonly a2uiSurfaceStates: Signal>;\n readonly streaming: Signal;\n readonly errors: Signal;\n dispose(): void;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ContentType", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ContentType", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/content-classifier.ts", + "symbol": "ContentType", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ContentType = 'pending' | 'markdown' | 'json-render' | 'a2ui';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#DynamicBoolean", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "DynamicBoolean", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "DynamicBoolean", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DynamicBoolean = boolean | A2uiPathRef | A2uiFunctionCall;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#DynamicNumber", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "DynamicNumber", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "DynamicNumber", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DynamicNumber = number | A2uiPathRef | A2uiFunctionCall;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#DynamicString", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "DynamicString", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "DynamicString", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DynamicString = string | A2uiPathRef | A2uiFunctionCall;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#DynamicStringList", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "DynamicStringList", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "DynamicStringList", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DynamicStringList = string[] | A2uiPathRef | A2uiFunctionCall;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#DynamicValue", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "DynamicValue", + "declarations": [ + { + "path": "libs/a2ui/src/lib/types.ts", + "symbol": "DynamicValue", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DynamicValue = unknown;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ElementAccumulationState", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ElementAccumulationState", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/parse-tree-store.ts", + "symbol": "ElementAccumulationState", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ElementAccumulationState {\n hasType: boolean;\n hasProps: boolean;\n hasChildren: boolean;\n streaming: boolean;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#FunctionToolDef", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "FunctionToolDef", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "FunctionToolDef", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface FunctionToolDef {\n readonly kind: 'function';\n readonly description: string;\n readonly schema: S;\n readonly followUp?: boolean;\n readonly idempotent?: boolean;\n readonly handler: (args: StandardSchemaInferOutput, context: FunctionToolHandlerContext) => R | Promise;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#FunctionToolHandlerContext", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "FunctionToolHandlerContext", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "FunctionToolHandlerContext", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface FunctionToolHandlerContext {\n readonly signal: AbortSignal;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#IS_HEADER_ROW", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "IS_HEADER_ROW", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/markdown-table-row.token.ts", + "symbol": "IS_HEADER_ROW", + "syntaxKind": "VariableDeclaration", + "signature": "IS_HEADER_ROW = new InjectionToken>('IS_HEADER_ROW', {\n providedIn: null,\n factory: () => signal(false),\n})" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#InterruptAction", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "InterruptAction", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-interrupt-panel/chat-interrupt-panel.component.ts", + "symbol": "InterruptAction", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type InterruptAction = 'accept' | 'edit' | 'respond' | 'ignore';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MARKDOWN_VIEW_REGISTRY", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MARKDOWN_VIEW_REGISTRY", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/markdown-view-registry.ts", + "symbol": "MARKDOWN_VIEW_REGISTRY", + "syntaxKind": "VariableDeclaration", + "signature": "MARKDOWN_VIEW_REGISTRY = new InjectionToken('MARKDOWN_VIEW_REGISTRY')" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownAutolinkComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownAutolinkComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-autolink.component.ts", + "symbol": "MarkdownAutolinkComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-autolink',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `{{ node().url }}`,\n})\nexport class MarkdownAutolinkComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownBlockquoteComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownBlockquoteComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-blockquote.component.ts", + "symbol": "MarkdownBlockquoteComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-blockquote',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `
    `,\n})\nexport class MarkdownBlockquoteComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownChildrenComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownChildrenComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/markdown-children.component.ts", + "symbol": "MarkdownChildrenComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-children',\n standalone: true,\n imports: [NgComponentOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @for (child of children(); track $index) {\n @let comp = resolve(child);\n @if (comp) {\n \n }\n }\n `,\n})\nexport class MarkdownChildrenComponent {\n readonly parent = input.required();\n private readonly registry = inject(MARKDOWN_VIEW_REGISTRY);\n protected readonly children = computed(() => {\n const p = this.parent();\n return 'children' in p && Array.isArray((p as {\n children?: MarkdownNode[];\n }).children)\n ? ((p as {\n children: MarkdownNode[];\n }).children as readonly MarkdownNode[])\n : [];\n });\n protected resolve(child: MarkdownNode): Type | null {\n const entry = this.registry[child.type];\n if (!entry)\n return null;\n return typeof entry === 'function' ? entry : entry.component;\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownCitationReferenceComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownCitationReferenceComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-citation-reference.component.ts", + "symbol": "MarkdownCitationReferenceComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-citation-reference',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [ChatConnectedOverlayDirective, ChatOverlayOriginDirective, ChatCitationPreviewComponent],\n styles: [CHAT_HOST_TOKENS, CHAT_CITATION_MARKER_STYLES],\n template: `\n @if (resolved(); as r) {\n {{ node().index }}\n \n \n \n } @else {\n {{ node().index }}\n }\n `,\n})\nexport class MarkdownCitationReferenceComponent {\n readonly node = input.required();\n private readonly resolver = inject(CitationsResolverService);\n private readonly document = inject(DOCUMENT);\n protected readonly resolved = computed(() => this.resolver.lookup(this.node().refId)());\n protected readonly open = signal(false);\n protected readonly positions: ConnectedPosition[] = [\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 6 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -6 },\n ];\n private get hoverCapable(): boolean {\n return this.document.defaultView?.matchMedia?.('(hover: hover) and (pointer: fine)').matches ?? false;\n }\n private openTimer = 0;\n private closeTimer = 0;\n private pane: HTMLElement | null = null;\n private justOpenedByFocus = false;\n constructor() {\n inject(DestroyRef).onDestroy(() => this.clearTimers());\n }\n protected ariaLabel(c: Citation): string {\n const domain = deriveDomain(c.url);\n const parts = [`Source ${c.index}`];\n if (c.title)\n parts.push(c.title);\n if (domain)\n parts.push(domain);\n const base = parts.join(', ');\n return c.url ? `${base}, opens in new tab` : base;\n }\n protected onEnter(): void {\n if (!this.hoverCapable)\n return;\n this.cancelClose();\n const win = this.document.defaultView;\n if (win)\n this.openTimer = win.setTimeout(() => this.open.set(true), OPEN_DELAY_MS);\n }\n protected onLeave(): void {\n if (!this.hoverCapable)\n return;\n this.cancelOpen();\n this.scheduleClose();\n }\n protected onFocus(): void {\n this.open.set(true);\n this.justOpenedByFocus = true;\n }\n protected onBlur(): void {\n this.justOpenedByFocus = false;\n const active = this.document.activeElement;\n if (this.pane && active && this.pane.contains(active))\n return;\n this.close();\n }\n protected onClick(e: MouseEvent, c: Citation): void {\n if (this.hoverCapable && c.url)\n return;\n e.preventDefault();\n if (this.justOpenedByFocus) {\n this.justOpenedByFocus = false;\n return;\n }\n this.open.update((v) => !v);\n }\n protected onKeydown(e: KeyboardEvent, c: Citation): void {\n if (e.key === 'Escape') {\n this.close();\n return;\n }\n if (!c.url && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n this.open.set(true);\n }\n }\n protected onAttached(pane: HTMLElement): void {\n this.pane = pane;\n pane.addEventListener('mouseenter', this.onPaneEnter);\n pane.addEventListener('mouseleave', this.onPaneLeave);\n }\n protected close(): void {\n this.clearTimers();\n this.justOpenedByFocus = false;\n this.open.set(false);\n this.pane = null;\n }\n private readonly onPaneEnter = () => this.cancelClose();\n private readonly onPaneLeave = () => this.scheduleClose();\n private scheduleClose(): void {\n const win = this.document.defaultView;\n if (win)\n this.closeTimer = win.setTimeout(() => this.open.set(false), CLOSE_DELAY_MS);\n }\n private cancelOpen(): void {\n const win = this.document.defaultView;\n if (this.openTimer && win)\n win.clearTimeout(this.openTimer);\n this.openTimer = 0;\n }\n private cancelClose(): void {\n const win = this.document.defaultView;\n if (this.closeTimer && win)\n win.clearTimeout(this.closeTimer);\n this.closeTimer = 0;\n }\n private clearTimers(): void {\n this.cancelOpen();\n this.cancelClose();\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownCodeBlockComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownCodeBlockComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-code-block.component.ts", + "symbol": "MarkdownCodeBlockComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-code-block',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `
    {{ node().text }}
    `,\n})\nexport class MarkdownCodeBlockComponent {\n readonly node = input.required();\n protected readonly languageClass = computed(() => {\n const lang = this.node().language;\n return lang ? `language-${lang}` : '';\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownDocumentComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownDocumentComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-document.component.ts", + "symbol": "MarkdownDocumentComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-document',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: ``,\n})\nexport class MarkdownDocumentComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownEmphasisComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownEmphasisComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-emphasis.component.ts", + "symbol": "MarkdownEmphasisComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-emphasis',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: ``,\n})\nexport class MarkdownEmphasisComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownHardBreakComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownHardBreakComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-hard-break.component.ts", + "symbol": "MarkdownHardBreakComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-hard-break',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `
    `,\n})\nexport class MarkdownHardBreakComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownHeadingComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownHeadingComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-heading.component.ts", + "symbol": "MarkdownHeadingComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-heading',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @switch (node().level) {\n @case (1) {

    }\n @case (2) {

    }\n @case (3) {

    }\n @case (4) {

    }\n @case (5) {
    }\n @case (6) {
    }\n }\n `,\n})\nexport class MarkdownHeadingComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownHtmlComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownHtmlComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-html.component.ts", + "symbol": "MarkdownHtmlComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-html',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `{{ raw() }}`,\n})\nexport class MarkdownHtmlComponent {\n readonly node = input.required();\n protected readonly raw = computed(() => this.node().raw);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownImageComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownImageComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-image.component.ts", + "symbol": "MarkdownImageComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-image',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (failed()) {\n \n 🖼️\n @if (node().alt) {\n {{ node().alt }}\n } @else {\n image unavailable\n }\n \n } @else {\n \n }\n `,\n})\nexport class MarkdownImageComponent {\n readonly node = input.required();\n protected readonly failed = signal(false);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownInlineCodeComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownInlineCodeComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-inline-code.component.ts", + "symbol": "MarkdownInlineCodeComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-inline-code',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `{{ node().text }}`,\n})\nexport class MarkdownInlineCodeComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownLinkComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownLinkComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-link.component.ts", + "symbol": "MarkdownLinkComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-link',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: ``,\n})\nexport class MarkdownLinkComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownListComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownListComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-list.component.ts", + "symbol": "MarkdownListComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-list',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (node().ordered) {\n
    \n } @else {\n
    \n }\n `,\n})\nexport class MarkdownListComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownListItemComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownListItemComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-list-item.component.ts", + "symbol": "MarkdownListItemComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-list-item',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
  • \n @if (node().task !== undefined) {\n \n }\n \n
  • \n `,\n})\nexport class MarkdownListItemComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownMathComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownMathComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-math.component.ts", + "symbol": "MarkdownMathComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-math',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n template: `\n @if (html(); as h) {\n \n } @else {\n {{ raw() }}\n }\n `,\n})\nexport class MarkdownMathComponent {\n readonly node = input.required();\n private readonly sanitizer = inject(DomSanitizer);\n protected readonly display = computed(() => this.node().type === 'math-display');\n protected readonly raw = computed(() => {\n const n = this.node();\n const [open, close] = DELIMITERS[n.delimiter];\n return `${open}${n.text}${close}`;\n });\n protected readonly html = computed(() => {\n katexReady();\n const n = this.node();\n const out = renderMath(n.text, n.type === 'math-display');\n if (out == null)\n return null;\n return this.sanitizer.bypassSecurityTrustHtml(out);\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownParagraphComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownParagraphComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-paragraph.component.ts", + "symbol": "MarkdownParagraphComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-paragraph',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `

    `,\n})\nexport class MarkdownParagraphComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownSoftBreakComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownSoftBreakComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-soft-break.component.ts", + "symbol": "MarkdownSoftBreakComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-soft-break',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `
    `,\n})\nexport class MarkdownSoftBreakComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownStrikethroughComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownStrikethroughComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-strikethrough.component.ts", + "symbol": "MarkdownStrikethroughComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-strikethrough',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: ``,\n})\nexport class MarkdownStrikethroughComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownStrongComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownStrongComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-strong.component.ts", + "symbol": "MarkdownStrongComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-strong',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: ``,\n})\nexport class MarkdownStrongComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownTableCellComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownTableCellComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-table-cell.component.ts", + "symbol": "MarkdownTableCellComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-table-cell',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (isHeader()) {\n \n \n \n } @else {\n \n \n \n }\n `,\n})\nexport class MarkdownTableCellComponent {\n readonly node = input.required();\n private readonly isHeaderRowToken = inject(IS_HEADER_ROW, { optional: true });\n protected readonly isHeader = computed(() => this.isHeaderRowToken ? this.isHeaderRowToken() : false);\n protected readonly alignment = computed(() => this.node().alignment);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownTableComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownTableComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-table.component.ts", + "symbol": "MarkdownTableComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-table',\n standalone: true,\n imports: [MarkdownChildrenComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n \n \n @if (headerRow(); as row) {\n \n @for (cell of row.children; track $index) {\n \n }\n \n }\n \n \n @for (row of bodyRows(); track $index) {\n \n @for (cell of row.children; track $index) {\n \n }\n \n }\n \n
    \n \n
    \n \n
    \n `,\n})\nexport class MarkdownTableComponent {\n readonly node = input.required();\n protected readonly headerRow = computed(() => {\n const rows = this.node().children;\n return rows.length > 0 && rows[0].isHeader ? rows[0] : null;\n });\n protected readonly bodyRows = computed(() => {\n const rows = this.node().children;\n return rows[0]?.isHeader ? rows.slice(1) : rows;\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownTableRowComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownTableRowComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-table-row.component.ts", + "symbol": "MarkdownTableRowComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-table-row',\n standalone: true,\n imports: [NgComponentOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n \n @for (child of node().children; track $index) {\n @let comp = resolve(child);\n @if (comp) {\n \n }\n }\n \n `,\n providers: [\n {\n provide: IS_HEADER_ROW,\n useFactory: () => {\n const comp = inject(MarkdownTableRowComponent);\n return computed(() => comp.node().isHeader);\n },\n },\n ],\n})\nexport class MarkdownTableRowComponent {\n readonly node = input.required();\n private readonly registry = inject(MARKDOWN_VIEW_REGISTRY);\n protected resolve(child: MarkdownNode): Type | null {\n const entry = this.registry[child.type];\n if (!entry)\n return null;\n return typeof entry === 'function' ? entry : entry.component;\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownTextComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownTextComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-text.component.ts", + "symbol": "MarkdownTextComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-text',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `{{ node().text }}`,\n})\nexport class MarkdownTextComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownThematicBreakComponent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MarkdownThematicBreakComponent", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/views/markdown-thematic-break.component.ts", + "symbol": "MarkdownThematicBreakComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'chat-md-thematic-break',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `
    `,\n})\nexport class MarkdownThematicBreakComponent {\n readonly node = input.required();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#Message", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "Message", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message.ts", + "symbol": "Message", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface Message {\n id: string;\n delivery: MessageDelivery;\n role: Role;\n content: string | ContentBlock[];\n toolCallId?: string;\n name?: string;\n reasoning?: string;\n reasoningDurationMs?: number;\n extra?: Record;\n citations?: Citation[];\n toolCallIds?: string[];\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MessageDelivery", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MessageDelivery", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message-delivery.ts", + "symbol": "MessageDelivery", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type MessageDelivery = {\n readonly generation: string;\n readonly phase: 'streaming';\n} | {\n readonly generation: string;\n readonly phase: 'complete';\n readonly outcome: CompleteOutcome;\n};" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MessageTemplateDirective", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MessageTemplateDirective", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-message-list/message-template.directive.ts", + "symbol": "MessageTemplateDirective", + "syntaxKind": "ClassDeclaration", + "signature": "@Directive({\n selector: 'ng-template[chatMessageTemplate]',\n standalone: true,\n})\nexport class MessageTemplateDirective {\n readonly chatMessageTemplate = input.required();\n readonly templateRef = inject(TemplateRef);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MessageTemplateType", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MessageTemplateType", + "declarations": [ + { + "path": "libs/chat/src/lib/chat.types.ts", + "symbol": "MessageTemplateType", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type MessageTemplateType = 'human' | 'ai' | 'tool' | 'system' | 'function';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MockAgent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MockAgent", + "declarations": [ + { + "path": "libs/chat/src/lib/testing/mock-agent.ts", + "symbol": "MockAgent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface MockAgent extends Agent {\n messages: WritableSignal;\n status: WritableSignal;\n isLoading: WritableSignal;\n error: WritableSignal;\n toolCalls: WritableSignal;\n state: WritableSignal>;\n interrupt?: WritableSignal;\n subagents?: WritableSignal>;\n history?: WritableSignal;\n events$: Observable;\n lifecycle: {\n streamStartedAt: Signal;\n };\n _internal: {\n streamStartedAt: WritableSignal;\n };\n submitCalls: Array<{\n input: AgentSubmitInput;\n opts?: AgentSubmitOptions;\n }>;\n stopCount: number;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#MockAgentOptions", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "MockAgentOptions", + "declarations": [ + { + "path": "libs/chat/src/lib/testing/mock-agent.ts", + "symbol": "MockAgentOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface MockAgentOptions {\n messages?: Message[];\n status?: AgentStatus;\n isLoading?: boolean;\n error?: AgentError;\n toolCalls?: ToolCall[];\n state?: Record;\n withInterrupt?: boolean;\n withSubagents?: boolean;\n history?: AgentCheckpoint[];\n events$?: Observable;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#OverflowMenuItem", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "OverflowMenuItem", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-overflow-menu/chat-overflow-menu.component.ts", + "symbol": "OverflowMenuItem", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface OverflowMenuItem {\n id: string;\n label: string;\n tone?: 'normal' | 'destructive';\n disabled?: boolean;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#OverlayPositionResult", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "OverlayPositionResult", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/overlay/connected-position.ts", + "symbol": "OverlayPositionResult", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface OverlayPositionResult {\n top: number;\n left: number;\n position: ConnectedPosition;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ParseTreeStore", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ParseTreeStore", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/parse-tree-store.ts", + "symbol": "ParseTreeStore", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ParseTreeStore {\n push(chunk: string): void;\n readonly spec: Signal;\n readonly elementStates: Signal>;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#PartialArgsBridge", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "PartialArgsBridge", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/partial-args-bridge.ts", + "symbol": "PartialArgsBridge", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface PartialArgsBridge {\n push(toolCallId: string, argsSoFar: string): void;\n isPoisoned(toolCallId: string): boolean;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#Project", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "Project", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-project-list/chat-project-list.component.ts", + "symbol": "Project", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type Project = {\n id: string;\n name: string;\n [key: string]: unknown;\n};" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ProjectActionAdapter", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ProjectActionAdapter", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-project-list/chat-project-list.component.ts", + "symbol": "ProjectActionAdapter", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ProjectActionAdapter {\n create?(name: string): Promise<{\n id: string;\n }>;\n rename?(projectId: string, newName: string): Promise;\n delete?(projectId: string): Promise;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ResolvedCitation", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ResolvedCitation", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/citations-resolver.service.ts", + "symbol": "ResolvedCitation", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ResolvedCitation {\n source: 'message' | 'markdown';\n citation: Citation;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#Role", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "Role", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message.ts", + "symbol": "Role", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type Role = 'user' | 'assistant' | 'system' | 'tool';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#STREAMING_MARKDOWN_CONTRACT_VIOLATION_POLICY", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "STREAMING_MARKDOWN_CONTRACT_VIOLATION_POLICY", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/streaming-markdown.component.ts", + "symbol": "STREAMING_MARKDOWN_CONTRACT_VIOLATION_POLICY", + "syntaxKind": "VariableDeclaration", + "signature": "STREAMING_MARKDOWN_CONTRACT_VIOLATION_POLICY = new InjectionToken('STREAMING_MARKDOWN_CONTRACT_VIOLATION_POLICY', {\n providedIn: 'root',\n factory: () => (isDevMode() ? 'throw' : 'rebuild'),\n})" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#SelectPendingClientToolCallsInput", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "SelectPendingClientToolCallsInput", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/select-pending-client-tool-calls.ts", + "symbol": "SelectPendingClientToolCallsInput", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface SelectPendingClientToolCallsInput {\n isLoading: boolean;\n toolCalls: readonly ToolCall[];\n catalogNames: ReadonlySet;\n resolvedIds: ReadonlySet;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#StandardSchemaInferInput", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "StandardSchemaInferInput", + "declarations": [ + { + "path": "libs/render/src/lib/standard-schema.ts", + "symbol": "StandardSchemaInferInput", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type StandardSchemaInferInput = NonNullable['input'];" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#StandardSchemaInferOutput", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "StandardSchemaInferOutput", + "declarations": [ + { + "path": "libs/render/src/lib/standard-schema.ts", + "symbol": "StandardSchemaInferOutput", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type StandardSchemaInferOutput = NonNullable['output'];" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#StandardSchemaV1", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "StandardSchemaV1", + "declarations": [ + { + "path": "libs/render/src/lib/standard-schema.ts", + "symbol": "StandardSchemaV1", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface StandardSchemaV1 {\n readonly '~standard': StandardSchemaProps;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#StreamingMarkdownContractViolationPolicy", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "StreamingMarkdownContractViolationPolicy", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/streaming-markdown.component.ts", + "symbol": "StreamingMarkdownContractViolationPolicy", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type StreamingMarkdownContractViolationPolicy = 'throw' | 'rebuild';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#StreamingMarkdownDocument", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "StreamingMarkdownDocument", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/streaming-markdown.component.ts", + "symbol": "StreamingMarkdownDocument", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface StreamingMarkdownDocument {\n readonly generation: string;\n readonly phase: 'streaming' | 'complete';\n readonly content: string;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#Subagent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "Subagent", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/subagent.ts", + "symbol": "Subagent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface Subagent {\n toolCallId: string;\n name?: string;\n status: Signal;\n messages: Signal;\n toolCalls?: Signal;\n state: Signal>;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#SubagentStatus", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "SubagentStatus", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/subagent.ts", + "symbol": "SubagentStatus", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type SubagentStatus = 'pending' | 'running' | 'complete' | 'error';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#Thread", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "Thread", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-thread-list/chat-thread-list.component.ts", + "symbol": "Thread", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type Thread = {\n id: string;\n title?: string;\n updatedAt?: number;\n status?: 'active' | 'archived';\n pinned?: boolean;\n projectId?: string | null;\n [key: string]: unknown;\n};" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ThreadActionAdapter", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ThreadActionAdapter", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-thread-list/chat-thread-list.component.ts", + "symbol": "ThreadActionAdapter", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ThreadActionAdapter {\n delete?(threadId: string): Promise;\n rename?(threadId: string, newTitle: string): Promise;\n archive?(threadId: string): Promise;\n unarchive?(threadId: string): Promise;\n pin?(threadId: string): Promise;\n unpin?(threadId: string): Promise;\n moveToProject?(threadId: string, projectId: string | null): Promise;\n reorderPinned?(threadId: string, beforeId: string | null): Promise;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ThreadMatch", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ThreadMatch", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-history-search-palette/chat-history-search-palette.component.ts", + "symbol": "ThreadMatch", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ThreadMatch {\n id: string;\n title: string;\n subtitle?: string;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ThreadRoutingConfig", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ThreadRoutingConfig", + "declarations": [ + { + "path": "libs/chat/src/lib/routing/thread-routing.ts", + "symbol": "ThreadRoutingConfig", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ThreadRoutingConfig {\n threadId: WritableSignal;\n toCommands?: (id: string | null) => unknown[];\n threadIdFromUrl?: (url: string) => string | null;\n validate?: (id: string) => Promise;\n navigationExtras?: NavigationExtras;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ToolArgs", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ToolArgs", + "declarations": [ + { + "path": "libs/chat/src/public-api.ts", + "symbol": "ToolArgs", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ToolArgs = import('./lib/client-tools/tool-def').StandardSchemaInferOutput;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ToolCall", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ToolCall", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/tool-call.ts", + "symbol": "ToolCall", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ToolCall {\n id: string;\n name: string;\n args: unknown;\n status: ToolCallStatus;\n result?: unknown;\n error?: unknown;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ToolCallInfo", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ToolCallInfo", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-tool-call-card/chat-tool-call-card.component.ts", + "symbol": "ToolCallInfo", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ToolCallInfo {\n id: string;\n name: string;\n args: unknown;\n result?: unknown;\n status?: ToolCallStatus;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ToolCallStatus", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ToolCallStatus", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/tool-call.ts", + "symbol": "ToolCallStatus", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ToolCallStatus = 'pending' | 'running' | 'complete' | 'error';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#TraceState", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "TraceState", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-trace/chat-trace.component.ts", + "symbol": "TraceState", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type TraceState = 'pending' | 'running' | 'done' | 'error';" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ViewProps", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ViewProps", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/component-inputs.ts", + "symbol": "ViewProps", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ViewProps = Prettify>;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ViewRegistry", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ViewRegistry", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "ViewRegistry", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ViewRegistry = Readonly | RenderViewEntry>>;" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ViewToolDef", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ViewToolDef", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "symbol": "ViewToolDef", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ViewToolDef {\n readonly kind: 'view';\n readonly description: string;\n readonly schema: S;\n readonly followUp?: boolean;\n readonly component: Type;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#a2uiBasicCatalog", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "a2uiBasicCatalog", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/index.ts", + "symbol": "a2uiBasicCatalog", + "syntaxKind": "FunctionDeclaration", + "signature": "export function a2uiBasicCatalog(): ViewRegistry {\n return views({\n AudioPlayer: A2uiAudioPlayerComponent,\n Button: A2uiButtonComponent,\n Card: A2uiCardComponent,\n CheckBox: A2uiCheckBoxComponent,\n ChoicePicker: A2uiChoicePickerComponent,\n Column: A2uiColumnComponent,\n DateTimeInput: A2uiDateTimeInputComponent,\n Divider: A2uiDividerComponent,\n Icon: A2uiIconComponent,\n Image: A2uiImageComponent,\n List: A2uiListComponent,\n Modal: A2uiModalComponent,\n Row: A2uiRowComponent,\n Slider: A2uiSliderComponent,\n Tabs: A2uiTabsComponent,\n Text: A2uiTextComponent,\n TextField: A2uiTextFieldComponent,\n Video: A2uiVideoComponent,\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#a2uiClientCapabilities", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "a2uiClientCapabilities", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/capabilities.ts", + "symbol": "a2uiClientCapabilities", + "syntaxKind": "FunctionDeclaration", + "signature": "export function a2uiClientCapabilities(): A2uiClientCapabilities {\n return { supportedCatalogIds: [A2UI_BASIC_CATALOG_ID] };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#action", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "action", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tools.ts", + "symbol": "action", + "syntaxKind": "FunctionDeclaration", + "signature": "export function action(description: string, schema: S, handler: (args: StandardSchemaInferOutput, context: FunctionToolHandlerContext) => R | Promise, options: ClientToolExecutionOptions = {}): FunctionToolDef {\n return { kind: 'function', description, schema, handler, ...options };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#ask", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "ask", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tools.ts", + "symbol": "ask", + "syntaxKind": "FunctionDeclaration", + "signature": "export function ask(description: string, schema: S, component: AcceptComponent, options: ClientToolContinuationOptions = {}): AskToolDef {\n return { kind: 'ask', description, schema, component: component as Type, ...options };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#buildA2uiActionMessage", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "buildA2uiActionMessage", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/build-action-message.ts", + "symbol": "buildA2uiActionMessage", + "syntaxKind": "FunctionDeclaration", + "signature": "export function buildA2uiActionMessage(params: Record, surface: A2uiSurface): A2uiActionMessage {\n const context = (params['context'] as Record) ?? {};\n const sourceComponentId = params['sourceComponentId'] as string;\n const message: A2uiActionMessage = {\n version: A2UI_WIRE_VERSION,\n action: {\n name: params['name'] as string,\n surfaceId: surface.surfaceId,\n sourceComponentId,\n timestamp: new Date().toISOString(),\n context,\n },\n };\n const label = deriveActionLabel(surface, sourceComponentId);\n if (label)\n message.action.label = label;\n if (surface.sendDataModel) {\n message.metadata = {\n a2uiClientDataModel: {\n surfaces: { [surface.surfaceId]: surface.dataModel },\n },\n };\n }\n return message;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#cacheplaneMarkdownViews", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "cacheplaneMarkdownViews", + "declarations": [ + { + "path": "libs/chat/src/lib/markdown/cacheplane-markdown-views.ts", + "symbol": "cacheplaneMarkdownViews", + "syntaxKind": "VariableDeclaration", + "signature": "cacheplaneMarkdownViews: ViewRegistry = views({\n 'document': MarkdownDocumentComponent,\n 'paragraph': MarkdownParagraphComponent,\n 'heading': MarkdownHeadingComponent,\n 'blockquote': MarkdownBlockquoteComponent,\n 'list': MarkdownListComponent,\n 'list-item': MarkdownListItemComponent,\n 'code-block': MarkdownCodeBlockComponent,\n 'thematic-break': MarkdownThematicBreakComponent,\n 'text': MarkdownTextComponent,\n 'emphasis': MarkdownEmphasisComponent,\n 'strong': MarkdownStrongComponent,\n 'strikethrough': MarkdownStrikethroughComponent,\n 'inline-code': MarkdownInlineCodeComponent,\n 'math-inline': MarkdownMathComponent,\n 'math-display': MarkdownMathComponent,\n 'link': MarkdownLinkComponent,\n 'autolink': MarkdownAutolinkComponent,\n 'image': MarkdownImageComponent,\n 'soft-break': MarkdownSoftBreakComponent,\n 'hard-break': MarkdownHardBreakComponent,\n 'citation-reference': MarkdownCitationReferenceComponent,\n 'table': MarkdownTableComponent,\n 'table-row': MarkdownTableRowComponent,\n 'table-cell': MarkdownTableCellComponent,\n 'html-block': MarkdownHtmlComponent,\n 'html-inline': MarkdownHtmlComponent,\n})" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#cancelledClientToolResult", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "cancelledClientToolResult", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "symbol": "cancelledClientToolResult", + "syntaxKind": "FunctionDeclaration", + "signature": "export function cancelledClientToolResult(toolCallId: string): ClientToolResult {\n return {\n ok: false,\n error: `client tool execution cancelled before completion: ${toolCallId}`,\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#citationSourceVisual", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "citationSourceVisual", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "citationSourceVisual", + "syntaxKind": "FunctionDeclaration", + "signature": "export function citationSourceVisual(c: Citation): CitationSourceVisual {\n const iconUrl = c.iconUrl?.trim();\n if (iconUrl) {\n return { kind: 'image', iconUrl };\n }\n const meta = citationTypeMeta(c);\n if (meta.icon !== 'web') {\n return {\n kind: 'type-icon',\n icon: meta.icon,\n tone: meta.tone,\n label: meta.label,\n };\n }\n return {\n kind: 'monogram',\n monogram: deriveMonogram(c),\n color: monogramColor(c),\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#citationTypeLabel", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "citationTypeLabel", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "citationTypeLabel", + "syntaxKind": "FunctionDeclaration", + "signature": "export function citationTypeLabel(c: Citation): string | null {\n return citationTypeMeta(c).label;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#citationTypeMeta", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "citationTypeMeta", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "citationTypeMeta", + "syntaxKind": "FunctionDeclaration", + "signature": "export function citationTypeMeta(c: Citation): CitationTypeMeta {\n const type = deriveSourceType(c);\n const canonicalType = type.toLowerCase();\n if (isKnownType(canonicalType)) {\n return {\n type: canonicalType,\n label: KNOWN_TYPE_LABELS[canonicalType],\n icon: canonicalType,\n tone: canonicalType,\n isKnown: true,\n };\n }\n return {\n type,\n label: type === 'unknown' ? null : readableSourceTypeLabel(type),\n icon: 'generic',\n tone: 'generic',\n isKnown: false,\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#clientToolGuardFailureResult", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "clientToolGuardFailureResult", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "symbol": "clientToolGuardFailureResult", + "syntaxKind": "FunctionDeclaration", + "signature": "export function clientToolGuardFailureResult(toolCallId: string, error: unknown): ClientToolResult {\n const message = error instanceof Error ? error.message : String(error);\n return {\n ok: false,\n error: `client tool execution guard failed for ${toolCallId}: ${message}`,\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#completeDelivery", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "completeDelivery", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message-delivery.ts", + "symbol": "completeDelivery", + "syntaxKind": "FunctionDeclaration", + "signature": "export function completeDelivery(generation: string, outcome: TOutcome) {\n const delivery = { generation, phase: 'complete', outcome } as const;\n return delivery satisfies MessageDelivery;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#createA2uiSurfaceStore", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "createA2uiSurfaceStore", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/surface-store.ts", + "symbol": "createA2uiSurfaceStore", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createA2uiSurfaceStore(): A2uiSurfaceStore {\n const surfacesSignal = signal>(new Map());\n const surfaceStatesSignal = signal>(new Map());\n const buffers = new Map();\n function bufferOf(surfaceId: string): SurfaceBuffer {\n let b = buffers.get(surfaceId);\n if (!b) {\n b = { components: new Map(), componentViews: new Map(), dataModelDeltas: [] };\n buffers.set(surfaceId, b);\n }\n return b;\n }\n function publish(surface: A2uiSurface, views: Map): void {\n const nextSurfaces = new Map(surfacesSignal());\n nextSurfaces.set(surface.surfaceId, surface);\n surfacesSignal.set(nextSurfaces);\n const nextStates = new Map(surfaceStatesSignal());\n nextStates.set(surface.surfaceId, { surface, componentViews: views });\n surfaceStatesSignal.set(nextStates);\n }\n function refreshViews(views: ReadonlyMap, dataModel: Record): Map {\n const next = new Map();\n for (const [id, v] of views) {\n const allResolved = v.bindings.every((p) => isResolved(dataModel, p));\n const nextReady = v.ready || allResolved;\n next.set(id, {\n ...v,\n ready: nextReady,\n props: nextReady ? resolveViewProps(v.def, dataModel) : v.props,\n });\n }\n return next;\n }\n function tryCommit(surfaceId: string): void {\n const b = buffers.get(surfaceId);\n if (!b || !b.create || !b.components.has('root'))\n return;\n let dataModel: Record = {};\n for (const d of b.dataModelDeltas) {\n dataModel = applyDataModelDelta(dataModel, d);\n }\n const surface: A2uiSurface = {\n surfaceId,\n catalogId: b.create.catalogId,\n ...(b.create.theme ? { theme: b.create.theme } : {}),\n ...(b.create.sendDataModel !== undefined ? { sendDataModel: b.create.sendDataModel } : {}),\n components: new Map(b.components),\n dataModel,\n };\n publish(surface, refreshViews(b.componentViews, dataModel));\n buffers.delete(surfaceId);\n }\n function apply(message: A2uiMessage): void {\n if ('createSurface' in message) {\n const create = message.createSurface;\n const live = surfacesSignal().get(create.surfaceId);\n if (live) {\n const state = surfaceStatesSignal().get(create.surfaceId);\n const surface: A2uiSurface = {\n ...live,\n catalogId: create.catalogId,\n ...(create.theme !== undefined ? { theme: create.theme } : {}),\n ...(create.sendDataModel !== undefined ? { sendDataModel: create.sendDataModel } : {}),\n };\n publish(surface, new Map(state?.componentViews ?? []));\n return;\n }\n bufferOf(create.surfaceId).create = create;\n tryCommit(create.surfaceId);\n return;\n }\n if ('updateComponents' in message) {\n const upd = message.updateComponents as A2uiUpdateComponents;\n const live = surfacesSignal().get(upd.surfaceId);\n if (live) {\n const components = new Map(live.components);\n const state = surfaceStatesSignal().get(upd.surfaceId);\n const views = new Map(state?.componentViews ?? []);\n for (const c of upd.components) {\n components.set(c.id, c);\n views.set(c.id, projectView(c));\n }\n const surface: A2uiSurface = { ...live, components };\n publish(surface, refreshViews(views, surface.dataModel));\n return;\n }\n const b = bufferOf(upd.surfaceId);\n for (const c of upd.components) {\n b.components.set(c.id, c);\n b.componentViews.set(c.id, projectView(c));\n }\n tryCommit(upd.surfaceId);\n return;\n }\n if ('updateDataModel' in message) {\n const upd = message.updateDataModel as A2uiUpdateDataModel;\n const delta = { path: upd.path, value: upd.value, del: !('value' in upd) || upd.value === undefined };\n const live = surfacesSignal().get(upd.surfaceId);\n if (live) {\n const dataModel = applyDataModelDelta(live.dataModel, delta);\n const surface: A2uiSurface = { ...live, dataModel };\n const state = surfaceStatesSignal().get(upd.surfaceId);\n publish(surface, refreshViews(state?.componentViews ?? new Map(), dataModel));\n }\n else {\n bufferOf(upd.surfaceId).dataModelDeltas.push(delta);\n }\n return;\n }\n if ('deleteSurface' in message) {\n const del = message.deleteSurface as A2uiDeleteSurface;\n buffers.delete(del.surfaceId);\n const next = new Map(surfacesSignal());\n next.delete(del.surfaceId);\n surfacesSignal.set(next);\n const nextStates = new Map(surfaceStatesSignal());\n nextStates.delete(del.surfaceId);\n surfaceStatesSignal.set(nextStates);\n return;\n }\n }\n function surface(surfaceId: string): Signal {\n return computed(() => surfacesSignal().get(surfaceId));\n }\n function surfaceState(surfaceId: string): Signal {\n return computed(() => surfaceStatesSignal().get(surfaceId));\n }\n const liveTools = new Set();\n function applyPartialArgs(toolCallId: string, envelopes: readonly A2uiMessage[]): void {\n liveTools.add(toolCallId);\n for (const env of envelopes) {\n apply(env);\n }\n }\n function isPartialLive(toolCallId: string): boolean {\n return liveTools.has(toolCallId);\n }\n return {\n apply,\n applyPartialArgs,\n isPartialLive,\n surfaces: surfacesSignal.asReadonly(),\n surface,\n surfaceStates: surfaceStatesSignal.asReadonly(),\n surfaceState,\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#createAgentRef", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "createAgentRef", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/agent-ref.ts", + "symbol": "createAgentRef", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createAgentRef(debugName?: string): AgentRef {\n return { token: new InjectionToken>(debugName ?? 'ThreadplaneAgent') };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#createContentClassifier", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "createContentClassifier", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/content-classifier.ts", + "symbol": "createContentClassifier", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createContentClassifier(): ContentClassifier {\n const typeSignal = signal('pending');\n const markdownSignal = signal('');\n const specSignal = signal(null);\n const elementStatesSignal = signal>(new Map());\n const streamingSignal = signal(false);\n const errorsSignal = signal([]);\n let processedLength = 0;\n let previousContent = '';\n let store: ParseTreeStore | null = null;\n let jsonStartIndex = 0;\n let a2uiParser: A2uiMessageParser | null = null;\n let a2uiStore: A2uiSurfaceStore | null = null;\n const a2uiSurfacesSignal = signal>(new Map());\n const a2uiSurfaceStatesSignal = signal>(new Map());\n function detectType(content: string): ContentType {\n for (let i = 0; i < content.length; i++) {\n const ch = content[i];\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r')\n continue;\n if (ch === '{') {\n return 'json-render';\n }\n if (ch === '-') {\n if (content.startsWith(A2UI_PREFIX, i)) {\n return 'a2ui';\n }\n const remaining = content.length - i;\n if (remaining < A2UI_PREFIX.length) {\n const candidate = content.slice(i);\n if (A2UI_PREFIX.startsWith(candidate)) {\n return 'pending';\n }\n return 'markdown';\n }\n return 'markdown';\n }\n return 'markdown';\n }\n return 'pending';\n }\n function initJsonStore(jsonContent: string): void {\n const parser = createPartialJsonParser();\n store = createParseTreeStore(parser);\n if (jsonContent.length > 0) {\n store.push(jsonContent);\n }\n syncJsonSignals();\n }\n function syncJsonSignals(): void {\n if (!store)\n return;\n specSignal.set(store.spec());\n elementStatesSignal.set(store.elementStates());\n const spec = store.spec();\n if (spec) {\n streamingSignal.set(isStillStreaming());\n }\n else {\n streamingSignal.set(true);\n }\n }\n function isStillStreaming(): boolean {\n if (!store)\n return false;\n const states = store.elementStates();\n for (const state of states.values()) {\n if (state.streaming)\n return true;\n }\n const spec = store.spec();\n if (!spec || !spec.root || !spec.elements)\n return true;\n return false;\n }\n function resetState(): void {\n typeSignal.set('pending');\n markdownSignal.set('');\n specSignal.set(null);\n elementStatesSignal.set(new Map());\n streamingSignal.set(false);\n errorsSignal.set([]);\n processedLength = 0;\n store = null;\n jsonStartIndex = 0;\n a2uiParser = null;\n a2uiStore = null;\n a2uiSurfacesSignal.set(new Map());\n a2uiSurfaceStatesSignal.set(new Map());\n }\n function update(content: string): void {\n untracked(() => {\n if (!content.startsWith(previousContent)) {\n resetState();\n }\n previousContent = content;\n const currentType = typeSignal();\n if (currentType === 'pending') {\n const detected = detectType(content);\n if (detected === 'pending')\n return;\n typeSignal.set(detected);\n if (detected === 'markdown') {\n markdownSignal.set(content);\n processedLength = content.length;\n }\n else if (detected === 'json-render') {\n streamingSignal.set(true);\n jsonStartIndex = 0;\n for (let i = 0; i < content.length; i++) {\n if (content[i] !== ' ' && content[i] !== '\\t' && content[i] !== '\\n' && content[i] !== '\\r') {\n jsonStartIndex = i;\n break;\n }\n }\n const jsonContent = content.slice(jsonStartIndex);\n try {\n initJsonStore(jsonContent);\n }\n catch (err) {\n errorsSignal.update(prev => [...prev, err instanceof Error ? err.message : String(err)]);\n }\n processedLength = content.length;\n }\n else if (detected === 'a2ui') {\n streamingSignal.set(true);\n a2uiParser = createA2uiMessageParser();\n a2uiStore = createA2uiSurfaceStore();\n jsonStartIndex = content.indexOf(A2UI_PREFIX) + A2UI_PREFIX.length;\n const a2uiContent = content.slice(jsonStartIndex);\n if (a2uiContent.length > 0) {\n try {\n const msgs = a2uiParser.push(a2uiContent);\n for (const msg of msgs)\n a2uiStore.apply(msg);\n a2uiSurfacesSignal.set(a2uiStore.surfaces());\n a2uiSurfaceStatesSignal.set(a2uiStore.surfaceStates());\n }\n catch (err) {\n errorsSignal.update(prev => [...prev, err instanceof Error ? err.message : String(err)]);\n }\n }\n processedLength = content.length;\n }\n return;\n }\n const delta = content.slice(processedLength);\n processedLength = content.length;\n if (delta.length === 0)\n return;\n if (currentType === 'markdown') {\n markdownSignal.set(content);\n }\n else if (currentType === 'json-render') {\n if (store) {\n try {\n store.push(delta);\n syncJsonSignals();\n }\n catch (err) {\n errorsSignal.update(prev => [...prev, err instanceof Error ? err.message : String(err)]);\n }\n }\n }\n else if (currentType === 'a2ui') {\n if (a2uiParser && a2uiStore) {\n try {\n const msgs = a2uiParser.push(delta);\n for (const msg of msgs)\n a2uiStore.apply(msg);\n a2uiSurfacesSignal.set(a2uiStore.surfaces());\n a2uiSurfaceStatesSignal.set(a2uiStore.surfaceStates());\n }\n catch (err) {\n errorsSignal.update(prev => [...prev, err instanceof Error ? err.message : String(err)]);\n }\n }\n }\n if (isTraceEnabled()) {\n trace('classifier.update', { contentLength: content.length, type: typeSignal() });\n }\n });\n }\n function dispose(): void {\n store = null;\n a2uiParser = null;\n a2uiStore = null;\n }\n return {\n update,\n type: typeSignal.asReadonly(),\n markdown: markdownSignal.asReadonly(),\n spec: specSignal.asReadonly(),\n elementStates: elementStatesSignal.asReadonly(),\n a2uiSurfaces: a2uiSurfacesSignal.asReadonly(),\n a2uiSurfaceStates: a2uiSurfaceStatesSignal.asReadonly(),\n streaming: streamingSignal.asReadonly(),\n errors: errorsSignal.asReadonly(),\n dispose,\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#createParseTreeStore", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "createParseTreeStore", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/parse-tree-store.ts", + "symbol": "createParseTreeStore", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createParseTreeStore(parser: PartialJsonParser): ParseTreeStore {\n const specSignal = signal(null);\n const elementStatesSignal = signal>(new Map());\n function computeElementStates(materialized: any): Map {\n const states = new Map();\n if (!materialized || typeof materialized !== 'object' || !materialized.elements) {\n return states;\n }\n const elements = materialized.elements as Record;\n const elementsNode = parser.getByPath('/elements') as JsonObjectNode | null;\n for (const [key, el] of Object.entries(elements)) {\n if (!el || typeof el !== 'object')\n continue;\n let streaming = true;\n if (elementsNode) {\n const elNode = elementsNode.children.get(key);\n if (elNode && elNode.status === 'complete') {\n streaming = false;\n }\n }\n states.set(key, {\n hasType: 'type' in el && el.type !== undefined,\n hasProps: 'props' in el && el.props !== undefined,\n hasChildren: 'children' in el && el.children !== undefined,\n streaming,\n });\n }\n return states;\n }\n function push(chunk: string): void {\n parser.push(chunk);\n if (parser.root) {\n const materialized = materialize(parser.root);\n specSignal.set(materialized as Spec);\n elementStatesSignal.set(computeElementStates(materialized));\n }\n }\n return {\n push,\n spec: specSignal.asReadonly(),\n elementStates: elementStatesSignal.asReadonly(),\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#createPartialArgsBridge", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "createPartialArgsBridge", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/partial-args-bridge.ts", + "symbol": "createPartialArgsBridge", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createPartialArgsBridge(store: A2uiSurfaceStore): PartialArgsBridge {\n const states = new Map();\n function stateOf(toolCallId: string): BridgeState {\n let s = states.get(toolCallId);\n if (!s) {\n s = {\n parser: createPartialJsonParser(),\n args: '',\n dispatchedCount: 0,\n createDispatched: new Set(),\n poisoned: false,\n };\n states.set(toolCallId, s);\n }\n return s;\n }\n function push(toolCallId: string, argsSoFar: string): void {\n const state = stateOf(toolCallId);\n if (state.poisoned)\n return;\n if (argsSoFar === state.args)\n return;\n if (!isValidJsonPrefix(argsSoFar)) {\n state.poisoned = true;\n return;\n }\n try {\n if (!argsSoFar.startsWith(state.args)) {\n state.parser = createPartialJsonParser();\n state.args = '';\n }\n state.parser.push(argsSoFar.slice(state.args.length));\n state.args = argsSoFar;\n }\n catch {\n state.poisoned = true;\n return;\n }\n const rootNode = state.parser.getByPath('/');\n if (!rootNode)\n return;\n const materialised = materialize(rootNode) as Record | null;\n if (!materialised || typeof materialised !== 'object')\n return;\n const envelopes = normalizeEnvelopeArgs(materialised);\n if (!envelopes)\n return;\n const newEnvelopes: A2uiMessage[] = [];\n for (let i = state.dispatchedCount; i < envelopes.length; i++) {\n const env = envelopes[i] as A2uiMessage;\n if (!isStructurallyComplete(env)) {\n break;\n }\n if ('createSurface' in env) {\n state.createDispatched.add(env.createSurface.surfaceId);\n }\n else if ('updateComponents' in env) {\n const surfaceId = env.updateComponents.surfaceId;\n if (!state.createDispatched.has(surfaceId)) {\n state.createDispatched.add(surfaceId);\n newEnvelopes.push({\n version: A2UI_WIRE_VERSION,\n createSurface: { surfaceId, catalogId: A2UI_BASIC_CATALOG_ID },\n });\n }\n }\n newEnvelopes.push(env);\n state.dispatchedCount = i + 1;\n }\n if (newEnvelopes.length > 0) {\n store.applyPartialArgs(toolCallId, newEnvelopes);\n }\n }\n function isPoisoned(toolCallId: string): boolean {\n return stateOf(toolCallId).poisoned;\n }\n return { push, isPoisoned };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#defaultInterruptedClientToolResult", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "defaultInterruptedClientToolResult", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "symbol": "defaultInterruptedClientToolResult", + "syntaxKind": "FunctionDeclaration", + "signature": "export function defaultInterruptedClientToolResult(toolCallId: string): ClientToolResult {\n return {\n ok: false,\n error: `client tool execution interrupted before completion: ${toolCallId}`,\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#deriveDomain", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "deriveDomain", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "deriveDomain", + "syntaxKind": "FunctionDeclaration", + "signature": "export function deriveDomain(url?: string): string | null {\n if (!url)\n return null;\n try {\n return new URL(url).hostname.replace(/^www\\./, '');\n }\n catch {\n return null;\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#deriveJsonSchema", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "deriveJsonSchema", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/to-json-schema.ts", + "symbol": "deriveJsonSchema", + "syntaxKind": "FunctionDeclaration", + "signature": "export function deriveJsonSchema(toolName: string, schema: StandardSchemaV1): Record {\n try {\n return toJSONSchema(schema as never) as Record;\n }\n catch (err) {\n throw new Error(`client tool \"${toolName}\": could not derive a JSON Schema from its schema. ` +\n `Use a Zod schema (recommended) or an already-JSON-Schema-compatible validator. ` +\n `Underlying error: ${err instanceof Error ? err.message : String(err)}`);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#deriveMonogram", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "deriveMonogram", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "deriveMonogram", + "syntaxKind": "FunctionDeclaration", + "signature": "export function deriveMonogram(c: Citation): string {\n const seed = deriveDomain(c.url) ?? c.title ?? '';\n const ch = seed.trim().charAt(0);\n return ch ? ch.toUpperCase() : '?';\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#deriveSourceType", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "deriveSourceType", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "deriveSourceType", + "syntaxKind": "FunctionDeclaration", + "signature": "export function deriveSourceType(c: Citation): string {\n const explicit = c.sourceType?.trim();\n if (explicit)\n return explicit;\n return c.url ? 'web' : 'unknown';\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#emitBinding", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "emitBinding", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/catalog/emit-binding.ts", + "symbol": "emitBinding", + "syntaxKind": "FunctionDeclaration", + "signature": "export function emitBinding(host: RenderHost, bindings: Record | undefined, prop: string, value: unknown): void {\n const path = bindings?.[prop];\n if (path) {\n host.set(path, value);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#executeFunctionTool", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "executeFunctionTool", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/execute.ts", + "symbol": "executeFunctionTool", + "syntaxKind": "FunctionDeclaration", + "signature": "export async function executeFunctionTool(def: AnyFunctionToolDef, rawArgs: unknown, context: FunctionToolHandlerContext = { signal: defaultSignal }): Promise {\n const v = await validateArgs(def.schema, rawArgs);\n if (!v.ok)\n return { ok: false, error: `invalid arguments: ${(v as {\n error: string;\n }).error}` };\n try {\n const value = await def.handler((v as {\n value: unknown;\n }).value as never, context);\n return { ok: true, value };\n }\n catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#extractErrorMessage", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "extractErrorMessage", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-error/chat-error.component.ts", + "symbol": "extractErrorMessage", + "syntaxKind": "FunctionDeclaration", + "signature": "export function extractErrorMessage(error: unknown): string | null {\n if (!error)\n return null;\n if (error instanceof Error)\n return error.message;\n if (typeof error === 'string')\n return error;\n return String(error);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#formatDuration", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "formatDuration", + "declarations": [ + { + "path": "libs/chat/src/lib/utils/format-duration.ts", + "symbol": "formatDuration", + "syntaxKind": "FunctionDeclaration", + "signature": "export function formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 1000)\n return '<1s';\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds < 60)\n return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds - minutes * 60;\n return `${minutes}m ${seconds}s`;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#formatPublished", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "formatPublished", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "formatPublished", + "syntaxKind": "FunctionDeclaration", + "signature": "export function formatPublished(value?: string | number | Date): string | null {\n if (value == null)\n return null;\n const d = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(d.getTime()))\n return null;\n return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short' });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#getInterrupt", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "getInterrupt", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-interrupt/chat-interrupt.component.ts", + "symbol": "getInterrupt", + "syntaxKind": "FunctionDeclaration", + "signature": "export function getInterrupt(agent: Agent): AgentInterrupt | undefined {\n return agent.interrupt?.();\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#getMessageType", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "getMessageType", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-message-list/chat-message-list.component.ts", + "symbol": "getMessageType", + "syntaxKind": "FunctionDeclaration", + "signature": "export function getMessageType(message: Message): MessageTemplateType {\n switch (message.role) {\n case 'user':\n return 'human';\n case 'assistant':\n return 'ai';\n case 'tool':\n return 'tool';\n case 'system':\n return 'system';\n default:\n return 'ai';\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#injectThreadRouting", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "injectThreadRouting", + "declarations": [ + { + "path": "libs/chat/src/lib/routing/thread-routing.ts", + "symbol": "injectThreadRouting", + "syntaxKind": "FunctionDeclaration", + "signature": "export function injectThreadRouting(config: ThreadRoutingConfig): void {\n const router = inject(Router);\n const fromUrl = config.threadIdFromUrl ?? defaultFromUrl;\n const toCommands = config.toCommands ?? defaultToCommands;\n const extras: NavigationExtras = config.navigationExtras ?? { queryParamsHandling: 'preserve' };\n const urlThreadId = toSignal(router.events.pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd), map((e) => fromUrl(e.urlAfterRedirects)), startWith(fromUrl(router.url))), { initialValue: fromUrl(router.url) });\n config.threadId.set(urlThreadId());\n effect(() => {\n const urlId = urlThreadId();\n if (urlId !== untracked(() => config.threadId()))\n config.threadId.set(urlId);\n });\n effect(() => {\n const id = config.threadId();\n const urlId = untracked(() => urlThreadId());\n if (id !== urlId)\n void router.navigate(toCommands(id), extras);\n });\n if (config.validate) {\n const validate = config.validate;\n let lastValidated: string | null = null;\n effect(() => {\n const id = urlThreadId();\n if (!id || id === lastValidated)\n return;\n lastValidated = id;\n void validate(id).then((ok) => {\n if (!ok && untracked(() => urlThreadId()) === id) {\n void router.navigate(toCommands(null), { ...extras, replaceUrl: true });\n }\n });\n });\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#isAbortError", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "isAbortError", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/to-agent-error.ts", + "symbol": "isAbortError", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isAbortError(raw: unknown): boolean {\n return raw instanceof Error && (raw.name === 'AbortError' || /\\babort/i.test(raw.message));\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#isAssistantMessage", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "isAssistantMessage", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message.ts", + "symbol": "isAssistantMessage", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isAssistantMessage(m: Message): m is Message & {\n role: 'assistant';\n} {\n return m.role === 'assistant';\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#isFunctionCall", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "isFunctionCall", + "declarations": [ + { + "path": "libs/a2ui/src/lib/guards.ts", + "symbol": "isFunctionCall", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isFunctionCall(value: unknown): value is {\n call: string;\n args?: Record;\n} {\n return typeof value === 'object' && value !== null\n && 'call' in value && typeof (value as {\n call: unknown;\n }).call === 'string';\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#isPathRef", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "isPathRef", + "declarations": [ + { + "path": "libs/a2ui/src/lib/guards.ts", + "symbol": "isPathRef", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isPathRef(value: unknown): value is {\n path: string;\n} {\n return typeof value === 'object' && value !== null\n && 'path' in value && typeof (value as {\n path: unknown;\n }).path === 'string';\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#isSystemMessage", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "isSystemMessage", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message.ts", + "symbol": "isSystemMessage", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isSystemMessage(m: Message): m is Message & {\n role: 'system';\n} {\n return m.role === 'system';\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#isToolMessage", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "isToolMessage", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message.ts", + "symbol": "isToolMessage", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isToolMessage(m: Message): m is Message & {\n role: 'tool';\n} {\n return m.role === 'tool';\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#isTyping", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "isTyping", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-typing-indicator/chat-typing-indicator.component.ts", + "symbol": "isTyping", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isTyping(agent: Agent): boolean {\n if (!agent.isLoading())\n return false;\n const msgs = agent.messages();\n if (msgs.length === 0)\n return true;\n const last = msgs[msgs.length - 1];\n if (last.role === 'user')\n return true;\n if (last.role === 'assistant') {\n return typeof last.content === 'string'\n ? !last.content\n : last.content.length === 0;\n }\n return false;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#isUserMessage", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "isUserMessage", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message.ts", + "symbol": "isUserMessage", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isUserMessage(m: Message): m is Message & {\n role: 'user';\n} {\n return m.role === 'user';\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#markdownDocument", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "markdownDocument", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/streaming-markdown.component.ts", + "symbol": "markdownDocument", + "syntaxKind": "FunctionDeclaration", + "signature": "export function markdownDocument(content: string, delivery: MessageDelivery, suffix = ''): StreamingMarkdownDocument {\n return {\n generation: delivery.generation + suffix,\n phase: delivery.phase,\n content,\n };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#messageContent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "messageContent", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/shared/message-utils.ts", + "symbol": "messageContent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function messageContent(message: {\n content: unknown;\n}): string {\n return extractText(message.content);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#mockAgent", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "mockAgent", + "declarations": [ + { + "path": "libs/chat/src/lib/testing/mock-agent.ts", + "symbol": "mockAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function mockAgent(opts: MockAgentOptions = {}): MockAgent {\n const messages = signal(opts.messages ?? []);\n const status = signal(opts.status ?? 'idle');\n const isLoading = signal(opts.isLoading ?? false);\n const error = signal(opts.error ?? undefined);\n const toolCalls = signal(opts.toolCalls ?? []);\n const state = signal>(opts.state ?? {});\n const interrupt = opts.withInterrupt\n ? signal(undefined)\n : undefined;\n const subagents = opts.withSubagents\n ? signal>(new Map())\n : undefined;\n const history = opts.history\n ? signal(opts.history)\n : undefined;\n const submitCalls: MockAgent['submitCalls'] = [];\n let stopCount = 0;\n const streamStartedAt = signal(null);\n const agent: MockAgent = {\n messages, status, isLoading, error, toolCalls, state,\n ...(interrupt ? { interrupt } : {}),\n ...(subagents ? { subagents } : {}),\n ...(history ? { history } : {}),\n lifecycle: { streamStartedAt: streamStartedAt.asReadonly() },\n _internal: { streamStartedAt },\n events$: opts.events$ ?? EMPTY,\n submit: async (input, submitOpts) => { submitCalls.push({ input, opts: submitOpts }); },\n stop: async () => { stopCount++; },\n retry: async () => { return; },\n regenerate: async (assistantMessageIndex: number) => {\n const current = messages();\n messages.set(current.slice(0, assistantMessageIndex));\n submitCalls.push({ input: { regenerate: { assistantMessageIndex } } as never, opts: undefined });\n },\n submitCalls,\n get stopCount() { return stopCount; },\n };\n return agent;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#monogramColor", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "monogramColor", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "monogramColor", + "syntaxKind": "FunctionDeclaration", + "signature": "export function monogramColor(c: Citation): string {\n const seed = deriveDomain(c.url) ?? c.title ?? '?';\n return `hsl(${monogramHue(seed)} 60% 45%)`;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#monogramHue", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "monogramHue", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/citation-display.ts", + "symbol": "monogramHue", + "syntaxKind": "FunctionDeclaration", + "signature": "export function monogramHue(seed: string): number {\n let h = 0;\n for (let i = 0; i < seed.length; i++) {\n h = (h * 31 + seed.charCodeAt(i)) % 360;\n }\n return h;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#normalizeEnvelopeArgs", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "normalizeEnvelopeArgs", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/envelope-normalizer.ts", + "symbol": "normalizeEnvelopeArgs", + "syntaxKind": "FunctionDeclaration", + "signature": "export function normalizeEnvelopeArgs(args: Record | null | undefined): unknown[] | null {\n if (!args || typeof args !== 'object' || Array.isArray(args))\n return null;\n if (Array.isArray((args as {\n envelopes?: unknown;\n }).envelopes)) {\n return (args as {\n envelopes: unknown[];\n }).envelopes;\n }\n if (Array.isArray((args as {\n envelope?: unknown;\n }).envelope)) {\n return (args as {\n envelope: unknown[];\n }).envelope;\n }\n const keys = Object.keys(args);\n if (keys.length === 0)\n return null;\n if (keys.every((k) => /^\\d+$/.test(k))) {\n return keys\n .map((k) => Number(k))\n .sort((a, b) => a - b)\n .map((k) => (args as Record)[String(k)]);\n }\n if (ENVELOPE_KEYS.some((k) => k in args)) {\n return [args];\n }\n return null;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#normalizeViewEntry", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "normalizeViewEntry", + "declarations": [ + { + "path": "libs/chat/src/lib/a2ui/views.ts", + "symbol": "normalizeViewEntry", + "syntaxKind": "FunctionDeclaration", + "signature": "export function normalizeViewEntry(entry: Type | A2uiViewEntry): A2uiViewEntry {\n if (typeof entry === 'function')\n return { component: entry };\n return entry;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#renderMarkdown", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "renderMarkdown", + "declarations": [ + { + "path": "libs/chat/src/lib/streaming/markdown-render.ts", + "symbol": "renderMarkdown", + "syntaxKind": "FunctionDeclaration", + "signature": "export function renderMarkdown(content: string, sanitizer: DomSanitizer): SafeHtml {\n if (markedParse) {\n const html = markedParse(content);\n return sanitizer.bypassSecurityTrustHtml(sanitizer.sanitize(SecurityContext.HTML, html) ?? '');\n }\n return sanitizer.bypassSecurityTrustHtml(plainTextToHtml(content));\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#selectPendingClientToolCalls", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "selectPendingClientToolCalls", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/select-pending-client-tool-calls.ts", + "symbol": "selectPendingClientToolCalls", + "syntaxKind": "FunctionDeclaration", + "signature": "export function selectPendingClientToolCalls(input: SelectPendingClientToolCallsInput): readonly ToolCall[] {\n if (input.isLoading)\n return [];\n return input.toolCalls.filter((tc) => input.catalogNames.has(tc.name) &&\n tc.result === undefined &&\n !input.resolvedIds.has(tc.id));\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#shouldClaimBeforeExecute", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "shouldClaimBeforeExecute", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "symbol": "shouldClaimBeforeExecute", + "syntaxKind": "FunctionDeclaration", + "signature": "export function shouldClaimBeforeExecute(def: AnyFunctionToolDef): boolean {\n return def.idempotent !== true;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#startClientToolExecutor", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "startClientToolExecutor", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tool-executor.ts", + "symbol": "startClientToolExecutor", + "syntaxKind": "FunctionDeclaration", + "signature": "export function startClientToolExecutor(agent: Agent, registry: ClientToolRegistry, options: ClientToolExecutorOptions = {}): void {\n const cap = agent.clientTools;\n if (!cap)\n return;\n const destroyRef = inject(DestroyRef);\n const inFlight = new Map();\n const abortAll = (): void => {\n for (const controller of inFlight.values()) {\n controller.abort();\n }\n };\n let patch = patchedAgents.get(agent);\n if (!patch) {\n const originalStop = agent.stop;\n const boundStop = originalStop.bind(agent);\n const aborts = new Set<() => void>();\n const wrapper = async (): Promise => {\n for (const abort of aborts)\n abort();\n await boundStop();\n };\n patch = { aborts, originalStop, wrapper };\n patchedAgents.set(agent, patch);\n agent.stop = wrapper;\n }\n const registration = patch;\n registration.aborts.add(abortAll);\n destroyRef.onDestroy(() => {\n registration.aborts.delete(abortAll);\n if (registration.aborts.size === 0 && patchedAgents.get(agent) === registration) {\n if (agent.stop === registration.wrapper)\n agent.stop = registration.originalStop;\n patchedAgents.delete(agent);\n }\n });\n destroyRef.onDestroy(abortAll);\n const settleToolCall = options.settleToolCall ?? ((toolCall, result) => cap.resolve(toolCall.id, result));\n const settleWithoutContinuing = options.settleWithoutContinuing ??\n ((toolCall: ToolCall, result: ClientToolResult) => {\n if (!cap.settle) {\n console.warn(`Client tool \"${toolCall.name}\" was cancelled but the agent capability does not implement settle(); the result cannot be recorded without starting a run.`);\n return;\n }\n cap.settle(toolCall.id, result);\n void Promise.resolve(cap.flush?.()).catch(() => undefined);\n });\n effect(() => {\n for (const tc of cap.pending()) {\n const def = registry[tc.name];\n if (!def || def.kind !== 'function')\n continue;\n if (inFlight.has(tc.id))\n continue;\n if (options.shouldExecuteToolCall && !options.shouldExecuteToolCall(tc))\n continue;\n const controller = new AbortController();\n inFlight.set(tc.id, controller);\n void runFunctionTool({\n def,\n toolCall: tc,\n rawArgs: tc.args,\n toolCallId: tc.id,\n controller,\n executionGuard: options.executionGuard,\n settleToolCall,\n settleWithoutContinuing,\n }).finally(() => {\n inFlight.delete(tc.id);\n });\n }\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#staticDelivery", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "staticDelivery", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message-delivery.ts", + "symbol": "staticDelivery", + "syntaxKind": "FunctionDeclaration", + "signature": "export function staticDelivery(messageId: string) {\n return completeDelivery(messageId, 'success');\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#statusColor", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "statusColor", + "declarations": [ + { + "path": "libs/chat/src/lib/compositions/chat-subagent-card/chat-subagent-card.component.ts", + "symbol": "statusColor", + "syntaxKind": "FunctionDeclaration", + "signature": "export function statusColor(status: SubagentStatus): string {\n switch (status) {\n case 'pending': return 'background: var(--tplane-chat-surface-alt); color: var(--tplane-chat-text-muted);';\n case 'running': return 'background: var(--tplane-chat-warning-bg); color: var(--tplane-chat-warning-text);';\n case 'complete': return 'color: var(--tplane-chat-success);';\n case 'error': return 'background: var(--tplane-chat-error-bg); color: var(--tplane-chat-error-text);';\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#streamingDelivery", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "streamingDelivery", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/message-delivery.ts", + "symbol": "streamingDelivery", + "syntaxKind": "FunctionDeclaration", + "signature": "export function streamingDelivery(generation: string) {\n return { generation, phase: 'streaming' } as const satisfies MessageDelivery;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#submitMessage", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "submitMessage", + "declarations": [ + { + "path": "libs/chat/src/lib/primitives/chat-input/chat-input.component.ts", + "symbol": "submitMessage", + "syntaxKind": "FunctionDeclaration", + "signature": "export function submitMessage(agent: Agent, text: string): string | null {\n const trimmed = text.trim();\n if (!trimmed || agent.isInputBlocked?.())\n return null;\n void agent.submit({ message: trimmed });\n return trimmed;\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#toAgentError", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "toAgentError", + "declarations": [ + { + "path": "libs/chat/src/lib/agent/to-agent-error.ts", + "symbol": "toAgentError", + "syntaxKind": "FunctionDeclaration", + "signature": "export function toAgentError(raw: unknown): AgentError {\n if (raw instanceof AgentError)\n return raw;\n if (isAbortError(raw))\n return make('aborted', false, raw);\n const structured = structuredStatus(raw);\n if (structured !== undefined)\n return classifyByStatus(structured, raw);\n if (isConnectionError(raw))\n return make('connection', true, raw);\n const httpStatus = httpStatusFromMessage(raw);\n if (httpStatus !== undefined)\n return classifyByStatus(httpStatus, raw);\n const msg = raw instanceof Error && raw.message ? raw.message : 'Something went wrong. You can try again.';\n return make('server', true, raw, undefined, msg);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#toClientToolSpecs", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "toClientToolSpecs", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/client-tools-coordinator.ts", + "symbol": "toClientToolSpecs", + "syntaxKind": "FunctionDeclaration", + "signature": "export function toClientToolSpecs(registry: ClientToolRegistry): ClientToolSpec[] {\n return Object.entries(registry).map(([name, def]) => ({\n name,\n description: def.description,\n parameters: deriveJsonSchema(name, def.schema),\n }));\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#toRenderRegistry", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "toRenderRegistry", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "toRenderRegistry", + "syntaxKind": "FunctionDeclaration", + "signature": "export function toRenderRegistry(registry: ViewRegistry): AngularRegistry {\n return defineAngularRegistry(registry);\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#tools", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "tools", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tools.ts", + "symbol": "tools", + "syntaxKind": "FunctionDeclaration", + "signature": "export function tools>(map: M): Readonly {\n return Object.freeze({ ...map });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#validateArgs", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "validateArgs", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/execute.ts", + "symbol": "validateArgs", + "syntaxKind": "FunctionDeclaration", + "signature": "export async function validateArgs(schema: StandardSchemaV1, args: unknown): Promise<{\n ok: true;\n value: unknown;\n} | {\n ok: false;\n error: string;\n}> {\n const res = await schema['~standard'].validate(args);\n if (res.issues) {\n return { ok: false, error: res.issues.map((i) => i.message).join('; ') };\n }\n return { ok: true, value: (res as {\n value: unknown;\n }).value };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#view", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "view", + "declarations": [ + { + "path": "libs/chat/src/lib/client-tools/tools.ts", + "symbol": "view", + "syntaxKind": "FunctionDeclaration", + "signature": "export function view(description: string, schema: S, component: AcceptComponent, options: ClientToolContinuationOptions = {}): ViewToolDef {\n return { kind: 'view', description, schema, component: component as Type, ...options };\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#views", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "views", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "views", + "syntaxKind": "FunctionDeclaration", + "signature": "export function views(map: Record | RenderViewEntry>): ViewRegistry {\n return Object.freeze({ ...map });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#withViews", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "withViews", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "withViews", + "syntaxKind": "FunctionDeclaration", + "signature": "export function withViews(base: ViewRegistry, additions: Record | RenderViewEntry>): ViewRegistry {\n return Object.freeze({ ...additions, ...base });\n}" + } + ] + }, + { + "id": "export:libs/chat/src/public-api.ts#withoutViews", + "kind": "export", + "path": "libs/chat/src/public-api.ts", + "symbol": "withoutViews", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "withoutViews", + "syntaxKind": "FunctionDeclaration", + "signature": "export function withoutViews(base: ViewRegistry, ...names: string[]): ViewRegistry {\n const result = { ...base };\n for (const name of names)\n delete result[name];\n return Object.freeze(result);\n}" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#AbstractEvent", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "AbstractEvent", + "declarations": [ + { + "path": "libs/chat/testing/reasoning-fixture.ts", + "symbol": "AbstractEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AbstractEvent {\n kind: 'reasoning-start' | 'reasoning-chunk' | 'reasoning-end' | 'text-start' | 'text-chunk' | 'text-end';\n delta?: string;\n}" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#FakeAgentConfig", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "FakeAgentConfig", + "declarations": [ + { + "path": "libs/chat/testing/fake-agent-config.ts", + "symbol": "FakeAgentConfig", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface FakeAgentConfig {\n tokens?: string[];\n reasoningTokens?: string[];\n delayMs?: number;\n}" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#INTERRUPT_CONFORMANCE_BATCH", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "INTERRUPT_CONFORMANCE_BATCH", + "declarations": [ + { + "path": "libs/chat/testing/interrupt-conformance.ts", + "symbol": "INTERRUPT_CONFORMANCE_BATCH", + "syntaxKind": "VariableDeclaration", + "signature": "INTERRUPT_CONFORMANCE_BATCH = [\n { id: 'approval-a', value: { question: 'Approve A?' } },\n { id: 'approval-b', value: { question: 'Approve B?' } },\n]" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#InterruptConformanceHarness", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "InterruptConformanceHarness", + "declarations": [ + { + "path": "libs/chat/testing/interrupt-conformance.ts", + "symbol": "InterruptConformanceHarness", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface InterruptConformanceHarness {\n agent: Agent;\n resume: unknown;\n pause(): Promise;\n pendingBatch(): Array<{\n id: string;\n value: unknown;\n }>;\n failNextDispatch(): void;\n requests: InterruptConformanceRequest[];\n backendCancellationCount(): number;\n startLateDelivery(): Promise;\n deliverLateEvents(): Promise;\n cleanup(): void | Promise;\n restore?: () => Promise;\n}" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#InterruptConformanceRequest", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "InterruptConformanceRequest", + "declarations": [ + { + "path": "libs/chat/testing/interrupt-conformance.ts", + "symbol": "InterruptConformanceRequest", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface InterruptConformanceRequest {\n resume: unknown;\n state: Record;\n messages: string[];\n}" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#REASONING_FIXTURE_EVENTS", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "REASONING_FIXTURE_EVENTS", + "declarations": [ + { + "path": "libs/chat/testing/reasoning-fixture.ts", + "symbol": "REASONING_FIXTURE_EVENTS", + "syntaxKind": "VariableDeclaration", + "signature": "REASONING_FIXTURE_EVENTS: AbstractEvent[] = [\n { kind: 'reasoning-start' },\n { kind: 'reasoning-chunk', delta: 'I read the prompt ' },\n { kind: 'reasoning-chunk', delta: 'and decided ' },\n { kind: 'reasoning-chunk', delta: 'to greet the user.' },\n { kind: 'reasoning-end' },\n { kind: 'text-start' },\n { kind: 'text-chunk', delta: 'Hel' },\n { kind: 'text-chunk', delta: 'lo' },\n { kind: 'text-chunk', delta: '!' },\n { kind: 'text-end' },\n]" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#REASONING_FIXTURE_MESSAGE_ID", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "REASONING_FIXTURE_MESSAGE_ID", + "declarations": [ + { + "path": "libs/chat/testing/reasoning-fixture.ts", + "symbol": "REASONING_FIXTURE_MESSAGE_ID", + "syntaxKind": "VariableDeclaration", + "signature": "REASONING_FIXTURE_MESSAGE_ID = 'fixture-msg-1'" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#REASONING_FIXTURE_REASONING", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "REASONING_FIXTURE_REASONING", + "declarations": [ + { + "path": "libs/chat/testing/reasoning-fixture.ts", + "symbol": "REASONING_FIXTURE_REASONING", + "syntaxKind": "VariableDeclaration", + "signature": "REASONING_FIXTURE_REASONING = 'I read the prompt and decided to greet the user.'" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#REASONING_FIXTURE_RESPONSE", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "REASONING_FIXTURE_RESPONSE", + "declarations": [ + { + "path": "libs/chat/testing/reasoning-fixture.ts", + "symbol": "REASONING_FIXTURE_RESPONSE", + "syntaxKind": "VariableDeclaration", + "signature": "REASONING_FIXTURE_RESPONSE = 'Hello!'" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#assertReasoningFixtureMessages", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "assertReasoningFixtureMessages", + "declarations": [ + { + "path": "libs/chat/testing/reasoning-fixture.ts", + "symbol": "assertReasoningFixtureMessages", + "syntaxKind": "FunctionDeclaration", + "signature": "export function assertReasoningFixtureMessages(messages: readonly Message[]): void {\n if (messages.length !== 1) {\n throw new Error(`Expected exactly 1 message, got ${messages.length}: ${JSON.stringify(messages)}`);\n }\n const m = messages[0];\n if (m.role !== 'assistant') {\n throw new Error(`Expected assistant role, got ${m.role}`);\n }\n if (m.content !== REASONING_FIXTURE_RESPONSE) {\n throw new Error(`Expected content ${JSON.stringify(REASONING_FIXTURE_RESPONSE)}, got ${JSON.stringify(m.content)}`);\n }\n if (m.reasoning !== REASONING_FIXTURE_REASONING) {\n throw new Error(`Expected reasoning ${JSON.stringify(REASONING_FIXTURE_REASONING)}, got ${JSON.stringify(m.reasoning)}`);\n }\n if (typeof m.reasoningDurationMs !== 'number') {\n throw new Error(`Expected reasoningDurationMs to be a number, got ${typeof m.reasoningDurationMs}`);\n }\n if (m.reasoningDurationMs < 0) {\n throw new Error(`Expected reasoningDurationMs >= 0, got ${m.reasoningDurationMs}`);\n }\n}" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#runAgentConformance", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "runAgentConformance", + "declarations": [ + { + "path": "libs/chat/testing/agent-conformance.ts", + "symbol": "runAgentConformance", + "syntaxKind": "FunctionDeclaration", + "signature": "export function runAgentConformance(label: string, factory: () => Agent): void {\n describe(`${label} — Agent conformance`, () => {\n it('exposes required core signals', () => {\n const a = factory();\n expect(typeof a.messages).toBe('function');\n expect(typeof a.status).toBe('function');\n expect(typeof a.isLoading).toBe('function');\n expect(typeof a.error).toBe('function');\n expect(typeof a.toolCalls).toBe('function');\n expect(typeof a.state).toBe('function');\n });\n it('messages() returns an array', () => {\n expect(Array.isArray(factory().messages())).toBe(true);\n });\n it('toolCalls() returns an array', () => {\n expect(Array.isArray(factory().toolCalls())).toBe(true);\n });\n it('state() returns a plain object', () => {\n const v = factory().state();\n expect(typeof v).toBe('object');\n expect(v).not.toBeNull();\n });\n it('status() returns one of the allowed values', () => {\n expect(['idle', 'running', 'error']).toContain(factory().status());\n });\n it('isLoading() is true only when status === \"running\"', () => {\n const a = factory();\n if (a.isLoading()) {\n expect(a.status()).toBe('running');\n }\n });\n it('submit() returns a Promise', () => {\n const result = factory().submit({ message: 'test' });\n expect(result).toBeInstanceOf(Promise);\n });\n it('stop() returns a Promise', () => {\n const result = factory().stop();\n expect(result).toBeInstanceOf(Promise);\n });\n it('events$ is an Observable-like with .subscribe', () => {\n const agent = factory();\n expect(typeof agent.events$.subscribe).toBe('function');\n });\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#runAgentWithHistoryConformance", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "runAgentWithHistoryConformance", + "declarations": [ + { + "path": "libs/chat/testing/agent-with-history-conformance.ts", + "symbol": "runAgentWithHistoryConformance", + "syntaxKind": "FunctionDeclaration", + "signature": "export function runAgentWithHistoryConformance(label: string, factory: (seed?: {\n history?: AgentCheckpoint[];\n}) => AgentWithHistory): void {\n runAgentConformance(label, () => factory());\n describe(`${label} — history`, () => {\n it('exposes a history signal', () => {\n const agent = factory();\n expect(typeof agent.history).toBe('function');\n expect(Array.isArray(agent.history())).toBe(true);\n });\n it('reflects seeded checkpoints', () => {\n const seed: AgentCheckpoint[] = [\n { id: 'c1', label: 'Step 1', values: { foo: 1 } },\n { id: 'c2', label: 'Step 2', values: { foo: 2 } },\n ];\n const agent = factory({ history: seed });\n const entries = agent.history();\n expect(entries).toHaveLength(2);\n expect(entries[0].id).toBe('c1');\n expect(entries[1].values).toEqual({ foo: 2 });\n });\n });\n}" + } + ] + }, + { + "id": "export:libs/chat/testing/public-api.ts#runInterruptConformance", + "kind": "export", + "path": "libs/chat/testing/public-api.ts", + "symbol": "runInterruptConformance", + "declarations": [ + { + "path": "libs/chat/testing/interrupt-conformance.ts", + "symbol": "runInterruptConformance", + "syntaxKind": "FunctionDeclaration", + "signature": "export function runInterruptConformance(label: string, factory: () => InterruptConformanceHarness, options: {\n restoration?: boolean;\n} = {}): void {\n describe(`${label} — interrupt conformance`, () => {\n for (const [name, scenario] of interruptConformanceScenarios(factory, options)) {\n it(name, scenario);\n }\n });\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AGENT_LIFECYCLE", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AGENT_LIFECYCLE", + "declarations": [ + { + "path": "libs/langgraph/src/lib/lifecycle.ts", + "symbol": "AGENT_LIFECYCLE", + "syntaxKind": "VariableDeclaration", + "signature": "AGENT_LIFECYCLE = new InjectionToken('AGENT_LIFECYCLE')" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentBranchTree", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AgentBranchTree", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "AgentBranchTree", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentBranchTree {\n type: 'sequence';\n items: Array | AgentBranchTreeFork>;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentBranchTreeFork", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AgentBranchTreeFork", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "AgentBranchTreeFork", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentBranchTreeFork {\n type: 'fork';\n items: AgentBranchTree[];\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentBranchTreeNode", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AgentBranchTreeNode", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "AgentBranchTreeNode", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentBranchTreeNode {\n type: 'node';\n value: ThreadState;\n path: string[];\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentConfig", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AgentConfig", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.provider.ts", + "symbol": "AgentConfig", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentConfig, _Bag extends BagTemplate = BagTemplate> {\n apiUrl?: string;\n assistantId?: string;\n threadId?: Signal | string | null;\n onThreadId?: (id: string) => void;\n initialValues?: Partial;\n throttle?: number | false;\n toMessage?: (msg: unknown) => BaseMessage;\n transport?: AgentTransport;\n clientOptions?: LangGraphClientOptions;\n telemetry?: AgentRuntimeTelemetrySink | false;\n subagentToolNames?: string[];\n transcriptNodeNames?: string[];\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentLifecycle", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AgentLifecycle", + "declarations": [ + { + "path": "libs/langgraph/src/lib/lifecycle.ts", + "symbol": "AgentLifecycle", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentLifecycle {\n readonly streamStartedAt: Signal;\n readonly streamErrorAt: Signal<{\n at: number;\n kind: AgentErrorKind | string;\n } | null>;\n readonly interruptReceivedAt: Signal;\n readonly interruptResolvedAt: Signal;\n readonly threadCreatedAt: Signal;\n readonly threadPersistedAt: Signal;\n readonly toolCallStartedAt: Signal;\n readonly toolCallCompletedAt: Signal;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentLifecycleRegistry", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AgentLifecycleRegistry", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent-lifecycle-registry.ts", + "symbol": "AgentLifecycleRegistry", + "syntaxKind": "ClassDeclaration", + "signature": "@Injectable({ providedIn: 'root' })\nexport class AgentLifecycleRegistry {\n private readonly _lifecycles = signal([]);\n readonly lifecycles: Signal = this._lifecycles.asReadonly();\n register(lifecycle: AgentLifecycle): void {\n this._lifecycles.update((curr) => [...curr, lifecycle]);\n }\n unregister(lifecycle: AgentLifecycle): void {\n this._lifecycles.update((curr) => curr.filter((l) => l !== lifecycle));\n }\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentOptions", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AgentOptions", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "AgentOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentOptions {\n apiUrl?: string;\n assistantId: string;\n threadId?: Signal | string | null;\n onThreadId?: (id: string) => void;\n initialValues?: Partial;\n throttle?: number | false;\n toMessage?: (msg: unknown) => BaseMessage;\n transport?: AgentTransport;\n clientOptions?: LangGraphClientOptions;\n telemetry?: AgentRuntimeTelemetrySink | false;\n subagentToolNames?: string[];\n a2uiClientCapabilities?: {\n supportedCatalogIds: string[];\n inlineCatalogs?: unknown[];\n };\n transcriptNodeNames?: string[];\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentQueue", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AgentQueue", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "AgentQueue", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentQueue {\n readonly entries: ReadonlyArray>;\n readonly size: number;\n cancel: (id: string) => Promise;\n clear: () => Promise;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentQueueEntry", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AgentQueueEntry", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "AgentQueueEntry", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentQueueEntry {\n id: string;\n threadId: string;\n values: T | null | undefined;\n options?: LangGraphSubmitOptions;\n createdAt: Date;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentTransport", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "AgentTransport", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "AgentTransport", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AgentTransport {\n stream(assistantId: string, threadId: string | null, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): AsyncIterable;\n joinStream?(threadId: string, runId: string, lastEventId: string | undefined, signal: AbortSignal): AsyncIterable;\n createQueuedRun?(assistantId: string, threadId: string, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): Promise;\n cancelRun?(threadId: string, runId: string, signal: AbortSignal): Promise;\n getHistory?(threadId: string, signal: AbortSignal): Promise;\n updateState?(threadId: string, values: Record, signal: AbortSignal, options?: {\n asNode?: string;\n }): Promise;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#BagTemplate", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "BagTemplate", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "BagTemplate", + "syntaxKind": "ImportSpecifier", + "signature": "import type { BagTemplate, Checkpoint, Command, Config, InferBag, Interrupt, Metadata, ThreadState, ToolProgress, ToolCallWithResult, StreamMode, } from '@langchain/langgraph-sdk';" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#CustomStreamEvent", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "CustomStreamEvent", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "CustomStreamEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface CustomStreamEvent {\n name: string;\n data: unknown;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#FakeStreamTransport", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "FakeStreamTransport", + "declarations": [ + { + "path": "libs/langgraph/src/lib/testing/fake-stream.transport.ts", + "symbol": "FakeStreamTransport", + "syntaxKind": "ClassDeclaration", + "signature": "export class FakeStreamTransport implements AgentTransport {\n private readonly tokens: string[];\n private readonly reasoningTokens: string[];\n private readonly delayMs: number;\n constructor(config: FakeAgentConfig = {}) {\n this.tokens = config.tokens ?? DEFAULT_TOKENS;\n this.reasoningTokens = config.reasoningTokens ?? [];\n this.delayMs = config.delayMs ?? 60;\n }\n async *stream(_assistantId: string, _threadId: string | null, _payload: unknown, signal: AbortSignal, _options?: LangGraphSubmitOptions): AsyncIterable {\n const id = 'fake-ai-1';\n let reasoning = '';\n for (const chunk of this.reasoningTokens) {\n if (signal.aborted)\n return;\n reasoning += chunk;\n yield {\n type: 'messages',\n messages: [\n { id, type: 'ai', content: '', additional_kwargs: { reasoning_content: reasoning } },\n ],\n } as unknown as StreamEvent;\n if (this.delayMs > 0)\n await delay(this.delayMs);\n }\n let content = '';\n for (const tok of this.tokens) {\n if (signal.aborted)\n return;\n content += tok;\n yield {\n type: 'messages',\n messages: [{ id, type: 'ai', content }],\n } as unknown as StreamEvent;\n if (this.delayMs > 0)\n await delay(this.delayMs);\n }\n }\n async createQueuedRun(_assistantId: string, threadId: string, payload: unknown, _signal: AbortSignal, options?: LangGraphSubmitOptions): Promise {\n return {\n id: 'fake-queued-run',\n threadId,\n values: payload,\n options: { ...options, multitaskStrategy: 'enqueue' },\n createdAt: new Date(),\n };\n }\n async cancelRun(_threadId: string, _runId: string, _signal: AbortSignal): Promise {\n return;\n }\n async getHistory(_threadId: string, _signal: AbortSignal): Promise {\n return [];\n }\n async *joinStream(): AsyncIterable {\n yield* [];\n }\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#FetchStreamTransport", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "FetchStreamTransport", + "declarations": [ + { + "path": "libs/langgraph/src/lib/transport/fetch-stream.transport.ts", + "symbol": "FetchStreamTransport", + "syntaxKind": "ClassDeclaration", + "signature": "export class FetchStreamTransport implements AgentTransport {\n private client: Client;\n private onThreadId?: (id: string) => void;\n private readonly protectErrors: boolean;\n private readonly reportOperationFailure?: RuntimeOperationFailureReporter;\n readonly protectsOperationErrors: boolean;\n constructor(apiUrl: string, onThreadId?: (id: string) => void, clientOptions?: LangGraphClientOptions, reportOperationFailure?: RuntimeOperationFailureReporter) {\n this.protectErrors = clientOptions?.defaultHeaders !== undefined || reportOperationFailure !== undefined;\n this.protectsOperationErrors = this.protectErrors;\n this.reportOperationFailure = reportOperationFailure;\n this.client = this.protectErrors\n ? ɵcreateProtectedLangGraphClient(apiUrl, clientOptions, createLangGraphRuntimeFetch(reportOperationFailure))\n : createLangGraphClient(apiUrl, clientOptions);\n this.onThreadId = onThreadId;\n }\n async *stream(assistantId: string, threadId: string | null, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): AsyncIterable {\n let thread = threadId;\n if (!thread) {\n try {\n const t = await this.client.threads.create();\n thread = t.thread_id;\n }\n catch (error) {\n this.rethrowOperationError(error, signal);\n }\n try {\n this.onThreadId?.(thread);\n }\n catch (error) {\n this.rethrowLocalError(error, signal);\n }\n }\n let runPayload: ReturnType;\n try {\n runPayload = buildRunPayload(payload, signal, options);\n }\n catch (error) {\n return this.rethrowLocalError(error, signal);\n }\n let run: ReturnType;\n try {\n run = this.client.runs.stream(thread, assistantId, runPayload);\n }\n catch (error) {\n this.rethrowOperationError(error, signal);\n }\n yield* this.iterateSdkRun(run, signal);\n }\n async *joinStream(threadId: string, runId: string, lastEventId: string | undefined, signal: AbortSignal): AsyncIterable {\n let run: ReturnType;\n try {\n run = this.client.runs.joinStream(threadId, runId, {\n signal,\n ...(lastEventId !== undefined ? { lastEventId } : {}),\n });\n }\n catch (error) {\n this.rethrowOperationError(error, signal);\n }\n yield* this.iterateSdkRun(run, signal);\n }\n async createQueuedRun(assistantId: string, threadId: string, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): Promise {\n let runPayload: ReturnType & {\n multitaskStrategy: 'enqueue';\n };\n try {\n runPayload = {\n ...buildRunPayload(payload, signal, options),\n multitaskStrategy: 'enqueue',\n };\n }\n catch (error) {\n return this.rethrowLocalError(error, signal);\n }\n let run: Awaited>;\n try {\n run = await this.client.runs.create(threadId, assistantId, runPayload);\n }\n catch (error) {\n return this.rethrowOperationError(error, signal);\n }\n try {\n return {\n id: run.run_id,\n threadId: run.thread_id ?? threadId,\n values: payload,\n options: { multitaskStrategy: 'enqueue', signal },\n createdAt: run.created_at ? new Date(run.created_at) : new Date(),\n };\n }\n catch (error) {\n return this.rethrowLocalError(error, signal);\n }\n }\n async cancelRun(threadId: string, runId: string, signal: AbortSignal): Promise {\n try {\n await this.client.runs.cancel(threadId, runId, false, 'interrupt', { signal });\n }\n catch (error) {\n this.rethrowOperationError(error, signal);\n }\n }\n async getHistory(threadId: string, signal: AbortSignal): Promise {\n try {\n return await this.client.threads.getHistory(threadId, { signal });\n }\n catch (error) {\n return this.rethrowOperationError(error, signal);\n }\n }\n async updateState(threadId: string, values: Record, _signal: AbortSignal, options?: {\n asNode?: string;\n }): Promise {\n const body: {\n values: Record;\n asNode?: string;\n } = { values };\n if (options?.asNode !== undefined) {\n body.asNode = options.asNode;\n }\n try {\n await this.client.threads.updateState(threadId, body);\n }\n catch (error) {\n this.rethrowOperationError(error, _signal);\n }\n }\n private rethrowOperationError(error: unknown, signal: AbortSignal): never {\n if (!this.protectErrors)\n throw error;\n return projectLangGraphOperationFailure(error, signal, this.reportOperationFailure);\n }\n private rethrowLocalError(error: unknown, signal: AbortSignal): never {\n if (!this.protectErrors)\n throw error;\n return projectLangGraphOperationFailure(error, signal, undefined);\n }\n private async *iterateSdkRun(run: ReturnType | ReturnType, signal: AbortSignal): AsyncIterable {\n let iterator: AsyncIterator<{\n event: string;\n data: unknown;\n }>;\n try {\n iterator = run[Symbol.asyncIterator]();\n }\n catch (error) {\n return this.rethrowOperationError(error, signal);\n }\n while (true) {\n let next: IteratorResult<{\n event: string;\n data: unknown;\n }>;\n try {\n next = await iterator.next();\n }\n catch (error) {\n return this.rethrowOperationError(error, signal);\n }\n if (next.done)\n return;\n try {\n yield normalizeSdkEvent(next.value.event as StreamEvent['type'], next.value.data);\n }\n catch (error) {\n return this.rethrowLocalError(error, signal);\n }\n }\n }\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#InferBag", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "InferBag", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "InferBag", + "syntaxKind": "ImportSpecifier", + "signature": "import type { BagTemplate, Checkpoint, Command, Config, InferBag, Interrupt, Metadata, ThreadState, ToolProgress, ToolCallWithResult, StreamMode, } from '@langchain/langgraph-sdk';" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#Interrupt", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "Interrupt", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "Interrupt", + "syntaxKind": "ImportSpecifier", + "signature": "import type { BagTemplate, Checkpoint, Command, Config, InferBag, Interrupt, Metadata, ThreadState, ToolProgress, ToolCallWithResult, StreamMode, } from '@langchain/langgraph-sdk';" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LANGGRAPH_CLIENT", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "LANGGRAPH_CLIENT", + "declarations": [ + { + "path": "libs/langgraph/src/lib/threads/threads-adapter.ts", + "symbol": "LANGGRAPH_CLIENT", + "syntaxKind": "VariableDeclaration", + "signature": "LANGGRAPH_CLIENT = new InjectionToken('LANGGRAPH_CLIENT')" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LANGGRAPH_CLIENT_OPTIONS", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "LANGGRAPH_CLIENT_OPTIONS", + "declarations": [ + { + "path": "libs/langgraph/src/lib/client/client-options.ts", + "symbol": "LANGGRAPH_CLIENT_OPTIONS", + "syntaxKind": "VariableDeclaration", + "signature": "LANGGRAPH_CLIENT_OPTIONS = new InjectionToken('LANGGRAPH_CLIENT_OPTIONS')" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LANGGRAPH_THREADS_CONFIG", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "LANGGRAPH_THREADS_CONFIG", + "declarations": [ + { + "path": "libs/langgraph/src/lib/threads/threads-adapter.ts", + "symbol": "LANGGRAPH_THREADS_CONFIG", + "syntaxKind": "VariableDeclaration", + "signature": "LANGGRAPH_THREADS_CONFIG = new InjectionToken('LANGGRAPH_THREADS_CONFIG')" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphAgent", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "LangGraphAgent", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "LangGraphAgent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface LangGraphAgent extends AgentWithHistory {\n interrupt: Signal;\n langGraphMessages: Signal;\n langGraphInterrupts: Signal[]>;\n langGraphToolCalls: Signal;\n langGraphHistory: Signal[]>;\n experimentalBranchTree: Signal>;\n submit: (input: AgentSubmitInput | null | undefined, opts?: AgentSubmitOptions & LangGraphSubmitOptions) => Promise;\n clientTools: ClientToolsCapability;\n value: Signal;\n hasValue: Signal;\n reload: () => void;\n regenerate: (assistantMessageIndex: number) => Promise;\n toolProgress: Signal;\n queue: Signal;\n activeSubagents: Signal;\n getSubagent: (toolCallId: string) => SubagentStreamRef | undefined;\n getSubagentsByType: (type: string) => SubagentStreamRef[];\n getSubagentsByMessage: (msg: CoreAIMessage) => SubagentStreamRef[];\n customEvents: Signal;\n branch: Signal;\n setBranch: (branch: string) => void;\n isThreadLoading: Signal;\n switchThread: (threadId: string | null) => void;\n joinStream: (runId: string, lastEventId?: string) => Promise;\n getMessagesMetadata: (msg: BaseMessage, idx?: number) => MessageMetadata> | undefined;\n getToolCalls: (msg: CoreAIMessage) => ToolCallWithResult[];\n lifecycle: AgentLifecycle;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphClientOptions", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "LangGraphClientOptions", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "LangGraphClientOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface LangGraphClientOptions {\n defaultHeaders?: Record;\n maxRetries?: number;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphMultitaskStrategy", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "LangGraphMultitaskStrategy", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "LangGraphMultitaskStrategy", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type LangGraphMultitaskStrategy = 'reject' | 'interrupt' | 'rollback' | 'enqueue';" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphSubmitOptions", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "LangGraphSubmitOptions", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "LangGraphSubmitOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface LangGraphSubmitOptions {\n signal?: AbortSignal;\n config?: Config;\n context?: unknown;\n checkpoint?: Omit | null;\n checkpointId?: string;\n command?: Command;\n metadata?: Metadata;\n checkpointDuring?: boolean;\n durability?: LangGraphDurability;\n interruptBefore?: '*' | string[];\n interruptAfter?: '*' | string[];\n onCompletion?: LangGraphOnCompletion;\n webhook?: string;\n onDisconnect?: LangGraphOnDisconnect;\n afterSeconds?: number;\n ifNotExists?: 'create' | 'reject';\n onRunCreated?: (params: {\n run_id: string;\n thread_id?: string;\n }) => void;\n streamMode?: StreamMode[];\n streamSubgraphs?: boolean;\n streamResumable?: boolean;\n feedbackKeys?: string[];\n resume?: unknown;\n multitaskStrategy?: LangGraphMultitaskStrategy;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphThreadsAdapter", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "LangGraphThreadsAdapter", + "declarations": [ + { + "path": "libs/langgraph/src/lib/threads/threads-adapter.ts", + "symbol": "LangGraphThreadsAdapter", + "syntaxKind": "ClassDeclaration", + "signature": "@Injectable({ providedIn: 'root' })\nexport class LangGraphThreadsAdapter {\n private readonly config = inject(LANGGRAPH_THREADS_CONFIG);\n private readonly clientState = (() => {\n const clientOptions = inject(LANGGRAPH_CLIENT_OPTIONS, { optional: true }) ?? undefined;\n const reportOperationFailure = inject(ɵLANGGRAPH_RUNTIME_OPERATION_REPORTER, { optional: true }) ??\n undefined;\n const injectedClient = inject(LANGGRAPH_CLIENT, { optional: true });\n const ownsProtectedClient = injectedClient === null &&\n (clientOptions?.defaultHeaders !== undefined ||\n reportOperationFailure !== undefined);\n return {\n client: injectedClient ??\n (ownsProtectedClient\n ? ɵcreateProtectedLangGraphClient(this.config.apiUrl, clientOptions, createLangGraphRuntimeFetch(reportOperationFailure))\n : createLangGraphClient(this.config.apiUrl, clientOptions)),\n protectErrors: clientOptions?.defaultHeaders !== undefined || ownsProtectedClient,\n reportOperationFailure: ownsProtectedClient\n ? reportOperationFailure\n : undefined,\n };\n })();\n private readonly client: Client = this.clientState.client;\n private readonly fallback: string = this.config.titleFallback ?? 'Untitled';\n private readonly _threads: WritableSignal = signal([]);\n private readonly _archived: WritableSignal = signal([]);\n readonly threads: Signal = this._threads.asReadonly();\n readonly archivedThreads: Signal = this._archived.asReadonly();\n async refresh(): Promise {\n console.debug('[LangGraphThreadsAdapter.refresh] invoked');\n try {\n const list = await this.client.threads.search({ limit: 50 });\n console.debug('[LangGraphThreadsAdapter.refresh] resolved', list.length);\n const mapped = list.map((t) => this.toThread(t));\n this._threads.set(mapped\n .filter((t) => t.status !== 'archived')\n .sort((a, b) => {\n const aP = a.pinned === true;\n const bP = b.pinned === true;\n if (aP !== bP)\n return Number(bP) - Number(aP);\n if (aP && bP) {\n const aO = typeof a['pinnedOrder'] === 'number' ? (a['pinnedOrder'] as number) : Infinity;\n const bO = typeof b['pinnedOrder'] === 'number' ? (b['pinnedOrder'] as number) : Infinity;\n return aO - bO;\n }\n return 0;\n }));\n this._archived.set(mapped.filter((t) => t.status === 'archived'));\n }\n catch (e) {\n console.error('[LangGraphThreadsAdapter.refresh] failed:', this.safeError(e));\n }\n }\n async getThread(threadId: string): Promise {\n try {\n const t = await this.client.threads.get(threadId);\n return this.toThread(t);\n }\n catch (e) {\n const status = safeThreadErrorStatus(e);\n if (status === 404 || status === 422)\n return null;\n throw this.safeError(e);\n }\n }\n async create(metadata: Record = {}): Promise {\n try {\n const t = await this.client.threads.create({ metadata });\n await this.refresh();\n return t.thread_id;\n }\n catch (e) {\n console.error('[LangGraphThreadsAdapter.create] failed:', this.safeError(e));\n return null;\n }\n }\n async delete(threadId: string): Promise {\n await this.request(() => this.client.threads.delete(threadId));\n await this.refresh();\n }\n async rename(threadId: string, newTitle: string): Promise {\n await this.request(() => this.client.threads.update(threadId, { metadata: { title: newTitle } }));\n await this.refresh();\n }\n async archive(threadId: string): Promise {\n await this.request(() => this.client.threads.update(threadId, { metadata: { archived: true } }));\n await this.refresh();\n }\n async unarchive(threadId: string): Promise {\n await this.request(() => this.client.threads.update(threadId, { metadata: { archived: false } }));\n await this.refresh();\n }\n async pin(threadId: string): Promise {\n await this.request(() => this.client.threads.update(threadId, { metadata: { pinned: true } }));\n await this.refresh();\n }\n async unpin(threadId: string): Promise {\n await this.request(() => this.client.threads.update(threadId, { metadata: { pinned: false } }));\n await this.refresh();\n }\n async moveToProject(threadId: string, projectId: string | null): Promise {\n await this.request(() => this.client.threads.update(threadId, { metadata: { projectId } }));\n await this.refresh();\n }\n async reorderPinned(threadId: string, beforeId: string | null): Promise {\n const current = this._threads().filter((t) => t.pinned === true);\n const moved = current.find((t) => t.id === threadId);\n if (!moved)\n return;\n const rest = current.filter((t) => t.id !== threadId);\n const next: Thread[] = [];\n for (const t of rest) {\n if (t.id === beforeId)\n next.push(moved);\n next.push(t);\n }\n if (beforeId === null)\n next.push(moved);\n await this.request(() => Promise.all(next.map((t, idx) => this.client.threads.update(t.id, { metadata: { pinnedOrder: idx } }))));\n await this.refresh();\n }\n private async request(operation: () => Promise): Promise {\n try {\n return await operation();\n }\n catch (error) {\n throw this.safeError(error);\n }\n }\n private safeError(error: unknown): unknown {\n if (!this.clientState.protectErrors)\n return error;\n if (this.clientState.reportOperationFailure !== undefined) {\n return sanitizeLangGraphClientOperationFailure(error, this.clientState.reportOperationFailure);\n }\n return createSafeRequestError();\n }\n private toThread(t: SdkThread): Thread {\n const meta = (t.metadata ?? {}) as Record;\n const rawTitle = meta['title'];\n const archived = meta['archived'] === true;\n const pinned = meta['pinned'] === true;\n const projectId = typeof meta['projectId'] === 'string' && (meta['projectId'] as string).length > 0\n ? (meta['projectId'] as string)\n : null;\n const pinnedOrder = typeof meta['pinnedOrder'] === 'number' ? (meta['pinnedOrder'] as number) : undefined;\n return {\n id: t.thread_id,\n title: typeof rawTitle === 'string' && rawTitle.length > 0 ? rawTitle : this.fallback,\n status: archived ? 'archived' : 'active',\n pinned,\n projectId,\n pinnedOrder,\n updatedAt: t.updated_at ? Date.parse(t.updated_at) : undefined,\n };\n }\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphThreadsConfig", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "LangGraphThreadsConfig", + "declarations": [ + { + "path": "libs/langgraph/src/lib/threads/threads-adapter.ts", + "symbol": "LangGraphThreadsConfig", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface LangGraphThreadsConfig {\n apiUrl: string;\n titleFallback?: string;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#MockAgentTransport", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "MockAgentTransport", + "declarations": [ + { + "path": "libs/langgraph/src/lib/transport/mock-stream.transport.ts", + "symbol": "MockAgentTransport", + "syntaxKind": "ClassDeclaration", + "signature": "export class MockAgentTransport implements AgentTransport {\n history: ThreadState[] = [];\n readonly historyCalls: string[] = [];\n readonly streams: Array<{\n threadId: string | null;\n payload: unknown;\n options?: LangGraphSubmitOptions;\n }> = [];\n readonly createdQueuedRuns: AgentQueueEntry[] = [];\n readonly cancelledRuns: Array<{\n threadId: string;\n runId: string;\n }> = [];\n readonly joinedRuns: Array<{\n threadId: string;\n runId: string;\n }> = [];\n private script: StreamEvent[][];\n private scriptIndex = 0;\n private streaming = false;\n private eventQueue: StreamEvent[] = [];\n private resolvers: Array<() => void> = [];\n private consumers: Array<() => void> = [];\n private closed = false;\n private pendingError: Error | null = null;\n private idle = false;\n private finished = true;\n constructor(script: StreamEvent[][] = []) {\n this.script = script;\n }\n nextBatch(): StreamEvent[] {\n if (this.scriptIndex >= this.script.length)\n return [];\n return this.script[this.scriptIndex++];\n }\n emit(events: StreamEvent[]): Promise {\n this.eventQueue.push(...events);\n this.wake();\n return this.consumed();\n }\n emitError(err: Error): Promise {\n this.pendingError = err;\n this.wake();\n return this.consumed();\n }\n close(): Promise {\n this.closed = true;\n this.wake();\n return this.consumed();\n }\n flush(): Promise {\n return this.consumed();\n }\n isStreaming(): boolean {\n return this.streaming;\n }\n async *stream(_assistantId: string, _threadId: string | null, _payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): AsyncIterable {\n this.streams.push({ threadId: _threadId, payload: _payload, options });\n this.streaming = true;\n this.finished = false;\n try {\n while (!this.closed && !signal.aborted) {\n if (this.pendingError)\n throw this.pendingError;\n if (this.eventQueue.length > 0) {\n const event = this.eventQueue.shift();\n if (event)\n yield event;\n }\n else {\n this.settleConsumers();\n this.idle = true;\n await new Promise((resolve) => {\n if (signal.aborted) {\n resolve();\n return;\n }\n this.resolvers.push(resolve);\n });\n this.idle = false;\n }\n }\n if (signal.aborted)\n return;\n while (this.eventQueue.length > 0) {\n const event = this.eventQueue.shift();\n if (event)\n yield event;\n }\n }\n finally {\n this.streaming = false;\n this.idle = false;\n this.finished = true;\n this.settleConsumers();\n }\n }\n async createQueuedRun(_assistantId: string, threadId: string, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): Promise {\n void signal;\n const entry: AgentQueueEntry = {\n id: `queued-run-${this.createdQueuedRuns.length + 1}`,\n threadId,\n values: payload,\n options: { ...options, multitaskStrategy: 'enqueue' },\n createdAt: new Date(),\n };\n this.createdQueuedRuns.push(entry);\n return entry;\n }\n async cancelRun(threadId: string, runId: string, signal: AbortSignal): Promise {\n void signal;\n this.cancelledRuns.push({ threadId, runId });\n }\n async getHistory(threadId: string, signal: AbortSignal): Promise {\n void signal;\n this.historyCalls.push(threadId);\n return this.history;\n }\n async *joinStream(threadId: string, runId: string, lastEventId: string | undefined, signal: AbortSignal): AsyncIterable {\n void lastEventId;\n void signal;\n this.joinedRuns.push({ threadId, runId });\n yield { type: 'values', values: { queued: true } };\n }\n private wake(): void {\n const resolve = this.resolvers.shift();\n if (resolve)\n resolve();\n }\n private consumed(): Promise {\n const alreadySettled = this.finished ||\n (this.idle && this.eventQueue.length === 0 && this.pendingError === null && !this.closed);\n if (alreadySettled)\n return new Promise((resolve) => setTimeout(resolve, 0));\n return new Promise((resolve) => { this.consumers.push(resolve); });\n }\n private settleConsumers(): void {\n const pending = this.consumers;\n this.consumers = [];\n for (const resolve of pending)\n setTimeout(resolve, 0);\n }\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#MockLangGraphAgent", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "MockLangGraphAgent", + "declarations": [ + { + "path": "libs/langgraph/src/lib/testing/mock-langgraph-agent.ts", + "symbol": "MockLangGraphAgent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface MockLangGraphAgent extends LangGraphAgent {\n messages: WritableSignal;\n status: WritableSignal;\n isLoading: WritableSignal;\n error: WritableSignal;\n toolCalls: WritableSignal;\n interrupt: WritableSignal;\n subagents: WritableSignal>;\n history: WritableSignal;\n submitCalls: MockAgent['submitCalls'];\n stopCount: MockAgent['stopCount'];\n _internal: MockAgent['_internal'];\n langGraphMessages: WritableSignal;\n hasValue: WritableSignal;\n value: WritableSignal;\n langGraphInterrupts: WritableSignal[]>;\n langGraphToolCalls: WritableSignal;\n toolProgress: WritableSignal;\n queue: WritableSignal;\n branch: WritableSignal;\n langGraphHistory: WritableSignal[]>;\n experimentalBranchTree: WritableSignal>;\n isThreadLoading: WritableSignal;\n activeSubagents: WritableSignal;\n customEvents: WritableSignal;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#ResourceStatus", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "ResourceStatus", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "ResourceStatus", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ResourceStatus = NgResourceStatus;" + }, + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "ResourceStatus", + "syntaxKind": "VariableDeclaration", + "signature": "ResourceStatus = {\n Idle: 'idle',\n Loading: 'loading',\n Reloading: 'reloading',\n Resolved: 'resolved',\n Error: 'error',\n Local: 'local',\n} as const satisfies Record" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#StreamEvent", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "StreamEvent", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "StreamEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface StreamEvent {\n type: 'values' | `values|${string}` | 'messages' | `messages|${string}` | `messages/${string}` | `messages/${string}|${string}` | 'updates' | `updates|${string}` | 'tools' | `tools|${string}` | 'custom' | `custom|${string}` | 'error' | `error|${string}` | 'metadata' | 'checkpoints' | `checkpoints|${string}` | 'tasks' | `tasks|${string}` | 'debug' | `debug|${string}` | 'events' | `events|${string}` | 'interrupt' | 'interrupts';\n namespace?: string[];\n messages?: unknown[];\n messageMetadata?: Record;\n [key: string]: unknown;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#SubagentStreamRef", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "SubagentStreamRef", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "SubagentStreamRef", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface SubagentStreamRef {\n toolCallId: string;\n name?: string;\n status: Signal<'pending' | 'running' | 'complete' | 'error'>;\n values: Signal>;\n messages: Signal;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#SubmitOptions", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "SubmitOptions", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "SubmitOptions", + "syntaxKind": "ImportSpecifier", + "signature": "import type { MessageMetadata, SubmitOptions, } from '@langchain/langgraph-sdk/ui';" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#ThreadState", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "ThreadState", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.types.ts", + "symbol": "ThreadState", + "syntaxKind": "ImportSpecifier", + "signature": "import type { BagTemplate, Checkpoint, Command, Config, InferBag, Interrupt, Metadata, ThreadState, ToolProgress, ToolCallWithResult, StreamMode, } from '@langchain/langgraph-sdk';" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#createLangGraphClient", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "createLangGraphClient", + "declarations": [ + { + "path": "libs/langgraph/src/lib/client/create-langgraph-client.ts", + "symbol": "createLangGraphClient", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createLangGraphClient(apiUrl: string, clientOptions?: LangGraphClientOptions): Client {\n return constructLangGraphClient(apiUrl, clientOptions);\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#extractCitations", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "extractCitations", + "declarations": [ + { + "path": "libs/langgraph/src/lib/internals/extract-citations.ts", + "symbol": "extractCitations", + "syntaxKind": "FunctionDeclaration", + "signature": "export function extractCitations(msg: KwargsLike): Citation[] | undefined {\n const raw = msg.additional_kwargs?.['citations'] ?? msg.additional_kwargs?.['sources'];\n if (!Array.isArray(raw) || raw.length === 0)\n return undefined;\n return raw.map((entry, i) => normalizeCitation(entry, i + 1));\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#injectAgent", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "injectAgent", + "declarations": [ + { + "path": "libs/langgraph/src/lib/inject-agent.ts", + "symbol": "injectAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function injectAgent(): LangGraphAgent>;" + }, + { + "path": "libs/langgraph/src/lib/inject-agent.ts", + "symbol": "injectAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function injectAgent, ResolvedBag extends BagTemplate = BagTemplate>(ref?: AgentRef): LangGraphAgent {\n return inject(ref ? ref.token : AGENT) as LangGraphAgent;\n}" + }, + { + "path": "libs/langgraph/src/lib/inject-agent.ts", + "symbol": "injectAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function injectAgent(ref: AgentRef): LangGraphAgent;" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#mockLangGraphAgent", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "mockLangGraphAgent", + "declarations": [ + { + "path": "libs/langgraph/src/lib/testing/mock-langgraph-agent.ts", + "symbol": "mockLangGraphAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function mockLangGraphAgent(initial: MockAgentOptions & {\n langGraphMessages?: BaseMessage[];\n hasValue?: boolean;\n isThreadLoading?: boolean;\n} = {}): MockLangGraphAgent {\n const base = mockAgent({\n ...initial,\n withInterrupt: true,\n withSubagents: true,\n history: initial.history ?? [],\n });\n const langGraphMessages$ = signal(initial.langGraphMessages ?? []);\n const hasValue$ = signal(initial.hasValue ?? false);\n const value$ = signal(null);\n const langGraphInterrupts$ = signal[]>([]);\n const langGraphToolCalls$ = signal([]);\n const toolProgress$ = signal([]);\n const queue$ = signal({\n entries: [],\n size: 0,\n cancel: async () => false,\n clear: async () => undefined,\n });\n const branch$ = signal('');\n const langGraphHistory$ = signal[]>([]);\n const experimentalBranchTree$ = signal>({ type: 'sequence', items: [] });\n const isThreadLoading$ = signal(initial.isThreadLoading ?? false);\n const activeSubagents$ = signal([]);\n const customEvents$ = signal([]);\n const state$ = computed>(() => {\n const v = value$();\n return v && typeof v === 'object' ? (v as Record) : {};\n });\n const mock: MockLangGraphAgent = {\n ...base,\n state: state$ as never,\n langGraphMessages: langGraphMessages$,\n langGraphInterrupts: langGraphInterrupts$,\n langGraphToolCalls: langGraphToolCalls$,\n langGraphHistory: langGraphHistory$,\n experimentalBranchTree: experimentalBranchTree$,\n value: value$,\n hasValue: hasValue$,\n reload: () => { },\n toolProgress: toolProgress$,\n queue: queue$,\n activeSubagents: activeSubagents$,\n getSubagent: (toolCallId: string) => activeSubagents$().find(subagent => subagent.toolCallId === toolCallId),\n getSubagentsByType: (type: string) => activeSubagents$().filter(subagent => subagent.name === type),\n getSubagentsByMessage: (msg: CoreAIMessage) => {\n const toolCalls = (msg as unknown as Record)['tool_calls'];\n if (!Array.isArray(toolCalls))\n return [];\n const ids = toolCalls\n .map(toolCall => {\n if (toolCall == null || typeof toolCall !== 'object' || Array.isArray(toolCall))\n return undefined;\n const id = (toolCall as Record)['id'];\n return typeof id === 'string' ? id : undefined;\n })\n .filter((id): id is string => id != null);\n return activeSubagents$().filter(subagent => ids.includes(subagent.toolCallId));\n },\n customEvents: customEvents$,\n branch: branch$,\n setBranch: (_branch: string) => { },\n isThreadLoading: isThreadLoading$,\n switchThread: (_threadId: string | null) => { },\n joinStream: (_runId: string, _lastEventId?: string) => Promise.resolve(),\n getMessagesMetadata: (_msg: BaseMessage, _idx?: number): MessageMetadata> | undefined => undefined,\n getToolCalls: (_msg: CoreAIMessage): ToolCallWithResult[] => [],\n lifecycle: {\n streamStartedAt: signal(null),\n streamErrorAt: signal<{\n at: number;\n kind: AgentErrorKind | string;\n } | null>(null),\n interruptReceivedAt: signal(null),\n interruptResolvedAt: signal(null),\n threadCreatedAt: signal(null),\n threadPersistedAt: signal(null),\n toolCallStartedAt: signal(null),\n toolCallCompletedAt: signal(null),\n },\n } as MockLangGraphAgent;\n return mock;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#provideAgent", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "provideAgent", + "declarations": [ + { + "path": "libs/langgraph/src/lib/agent.provider.ts", + "symbol": "provideAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideAgent>(configOrFactory: AgentConfig | (() => AgentConfig)): Provider[];" + }, + { + "path": "libs/langgraph/src/lib/agent.provider.ts", + "symbol": "provideAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideAgent>(ref: AgentRef, configOrFactory: AgentConfig | (() => AgentConfig)): Provider[];" + }, + { + "path": "libs/langgraph/src/lib/agent.provider.ts", + "symbol": "provideAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideAgent>(refOrConfig: AgentRef | AgentConfig | (() => AgentConfig), maybeConfig?: AgentConfig | (() => AgentConfig)): Provider[] {\n const ref = isAgentRef(refOrConfig) ? refOrConfig : undefined;\n const configOrFactory = (ref ? maybeConfig : refOrConfig) as AgentConfig | (() => AgentConfig);\n const resolveConfig = (): AgentConfig => typeof configOrFactory === 'function' ? (configOrFactory as () => AgentConfig)() : configOrFactory;\n if (!ref) {\n return [\n { provide: AGENT_CONFIG, useFactory: resolveConfig },\n { provide: AGENT, useFactory: agentFactory },\n { provide: AGENT_LIFECYCLE, useFactory: () => inject(AGENT).lifecycle },\n ];\n }\n const refConfig = new InjectionToken>(`AGENT_CONFIG(${ref.token.toString()})`);\n const thisRefName = refDebugName(ref as AgentRef);\n return [\n { provide: refConfig, useFactory: resolveConfig },\n { provide: ref.token, useFactory: () => createAgentFromConfig(inject(refConfig)) },\n { provide: AGENT_CONFIG, useExisting: refConfig },\n { provide: AGENT_REF_NAMES, useValue: thisRefName, multi: true },\n {\n provide: AGENT,\n useFactory: () => {\n if (isDevMode()) {\n const names = inject(AGENT_REF_NAMES, { optional: true }) ?? [];\n const others = names.filter((n) => n !== thisRefName);\n if (others.length > 0) {\n console.warn(`[@threadplane/langgraph] provideAgent(): ${names.length} agent refs ` +\n `(${names.join(', ')}) are provided at the same injector level. ` +\n `The ref-less injectAgent() resolves a single shared token, so it now ` +\n `returns the last one provided (${thisRefName}). ` +\n `Inject by ref — injectAgent(${others[0]}) / injectAgent(${thisRefName}) — ` +\n `to reach each agent unambiguously.`);\n }\n }\n return inject(ref.token) as LangGraphAgent;\n },\n },\n {\n provide: AGENT_LIFECYCLE,\n useFactory: () => (inject(ref.token) as LangGraphAgent).lifecycle,\n },\n ];\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#provideFakeAgent", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "provideFakeAgent", + "declarations": [ + { + "path": "libs/langgraph/src/lib/testing/provide-fake-agent.ts", + "symbol": "provideFakeAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideFakeAgent(config: FakeAgentConfig = {}): Provider[] {\n return provideAgent({\n assistantId: 'fake',\n transport: new FakeStreamTransport(config),\n });\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#refreshOnRunEnd", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "refreshOnRunEnd", + "declarations": [ + { + "path": "libs/langgraph/src/lib/threads/refresh-on.ts", + "symbol": "refreshOnRunEnd", + "syntaxKind": "FunctionDeclaration", + "signature": "export function refreshOnRunEnd(agent: LangGraphAgent, fn: () => void | Promise): void {\n let lastStatus = agent.status();\n effect(() => {\n const status = agent.status();\n if (lastStatus === 'running' && status !== 'running') {\n void fn();\n }\n lastStatus = status;\n });\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#refreshOnTransition", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "refreshOnTransition", + "declarations": [ + { + "path": "libs/langgraph/src/lib/threads/refresh-on.ts", + "symbol": "refreshOnTransition", + "syntaxKind": "FunctionDeclaration", + "signature": "export function refreshOnTransition(watch: Signal, isActive: (v: T) => boolean, fn: () => void | Promise): void {\n let lastActive = isActive(watch());\n effect(() => {\n const active = isActive(watch());\n if (lastActive && !active)\n void fn();\n lastActive = active;\n });\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#toAbsoluteApiUrl", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "toAbsoluteApiUrl", + "declarations": [ + { + "path": "libs/langgraph/src/lib/client/create-langgraph-client.ts", + "symbol": "toAbsoluteApiUrl", + "syntaxKind": "FunctionDeclaration", + "signature": "export function toAbsoluteApiUrl(apiUrl: string): string {\n if (apiUrl.startsWith('http://') || apiUrl.startsWith('https://'))\n return apiUrl;\n return typeof window !== 'undefined' ? `${window.location.origin}${apiUrl}` : apiUrl;\n}" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#ɵLANGGRAPH_RUNTIME_OPERATION_REPORTER", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "ɵLANGGRAPH_RUNTIME_OPERATION_REPORTER", + "declarations": [ + { + "path": "libs/langgraph/src/lib/runtime-operation-reporter.ts", + "symbol": "ɵLANGGRAPH_RUNTIME_OPERATION_REPORTER", + "syntaxKind": "VariableDeclaration", + "signature": "ɵLANGGRAPH_RUNTIME_OPERATION_REPORTER = new InjectionToken('ɵLANGGRAPH_RUNTIME_OPERATION_REPORTER')" + } + ] + }, + { + "id": "export:libs/langgraph/src/public-api.ts#ɵLangGraphRuntimeOperationFailureReporter", + "kind": "export", + "path": "libs/langgraph/src/public-api.ts", + "symbol": "ɵLangGraphRuntimeOperationFailureReporter", + "declarations": [ + { + "path": "libs/langgraph/src/lib/runtime-operation-reporter.ts", + "symbol": "RuntimeOperationFailureReporter", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type RuntimeOperationFailureReporter = (code: 'unauthorized' | 'network_blocked') => void;" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#BaseMessage", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "BaseMessage", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/types.ts", + "symbol": "BaseMessage", + "syntaxKind": "ImportSpecifier", + "signature": "import type { BaseMessage } from '@langchain/core/messages';" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#BindableModel", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "BindableModel", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/middleware.ts", + "symbol": "BindableModel", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface BindableModel {\n bindTools(tools: unknown[], kwargs?: unknown): unknown;\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolExecutionKey", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "ClientToolExecutionKey", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-execution-store.ts", + "symbol": "ClientToolExecutionKey", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolExecutionKey {\n readonly threadId: string;\n readonly toolCallId: string;\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolExecutionRecord", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "ClientToolExecutionRecord", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-execution-store.ts", + "symbol": "ClientToolExecutionRecord", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ClientToolExecutionRecord = {\n status: 'executing';\n} | {\n status: 'done';\n result: ClientToolResult;\n} | {\n status: 'failed';\n result?: ClientToolResult;\n};" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolExecutionStatus", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "ClientToolExecutionStatus", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-execution-store.ts", + "symbol": "ClientToolExecutionStatus", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ClientToolExecutionStatus = 'executing' | 'done' | 'failed';" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolExecutionStore", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "ClientToolExecutionStore", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-execution-store.ts", + "symbol": "ClientToolExecutionStore", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolExecutionStore {\n claim(key: ClientToolExecutionKey): Promise<'claimed' | ClientToolExecutionRecord>;\n record(key: ClientToolExecutionKey, result: ClientToolResult): Promise;\n lookup(threadId: string, toolCallIds: readonly string[]): Promise>;\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolResult", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "ClientToolResult", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-execution-store.ts", + "symbol": "ClientToolResult", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ClientToolResult = {\n readonly ok: true;\n readonly value: unknown;\n} | {\n readonly ok: false;\n readonly error: string;\n};" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolResultMessage", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "ClientToolResultMessage", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-result-guard.ts", + "symbol": "ClientToolResultMessage", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolResultMessage {\n readonly toolCallId: string;\n readonly result: ClientToolResult;\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolSpec", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "ClientToolSpec", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/types.ts", + "symbol": "ClientToolSpec", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolSpec {\n name: string;\n description?: string;\n parameters?: Record;\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolsState", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "ClientToolsState", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/types.ts", + "symbol": "ClientToolsState", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ClientToolsState {\n messages: BaseMessage[];\n tools?: ClientToolSpec[];\n client_tools?: ClientToolSpec[];\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#OpenAIFunctionTool", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "OpenAIFunctionTool", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/types.ts", + "symbol": "OpenAIFunctionTool", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface OpenAIFunctionTool {\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: Record;\n };\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#PostgresClientToolExecutionStoreOptions", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "PostgresClientToolExecutionStoreOptions", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/postgres-client-tool-execution-store.ts", + "symbol": "PostgresClientToolExecutionStoreOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface PostgresClientToolExecutionStoreOptions {\n readonly tenantId?: string | null;\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#PostgresRow", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "PostgresRow", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/postgres-client-tool-execution-store.ts", + "symbol": "PostgresRow", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type PostgresRow = Record;" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#PostgresTaggedSql", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "PostgresTaggedSql", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/postgres-client-tool-execution-store.ts", + "symbol": "PostgresTaggedSql", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type PostgresTaggedSql = (strings: TemplateStringsArray, ...values: unknown[]) => Promise;" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#RecordClientToolResultsInput", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "RecordClientToolResultsInput", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-result-guard.ts", + "symbol": "RecordClientToolResultsInput", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RecordClientToolResultsInput {\n readonly threadId: string;\n readonly messages: readonly BaseMessage[];\n readonly store: ClientToolExecutionStore;\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#RecordClientToolResultsResult", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "RecordClientToolResultsResult", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-result-guard.ts", + "symbol": "RecordClientToolResultsResult", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RecordClientToolResultsResult {\n readonly recordedToolCallIds: string[];\n readonly duplicateToolCallIds: string[];\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#THREADPLANE_CLIENT_TOOL_EXECUTIONS_SCHEMA", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "THREADPLANE_CLIENT_TOOL_EXECUTIONS_SCHEMA", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/postgres-client-tool-execution-store.ts", + "symbol": "THREADPLANE_CLIENT_TOOL_EXECUTIONS_SCHEMA", + "syntaxKind": "VariableDeclaration", + "signature": "THREADPLANE_CLIENT_TOOL_EXECUTIONS_SCHEMA = `\nCREATE TABLE IF NOT EXISTS threadplane_client_tool_executions (\n tenant_id text NOT NULL DEFAULT '',\n thread_id text NOT NULL,\n tool_call_id text NOT NULL,\n status text NOT NULL,\n result jsonb,\n created_at timestamptz NOT NULL DEFAULT now(),\n updated_at timestamptz NOT NULL DEFAULT now(),\n PRIMARY KEY (tenant_id, thread_id, tool_call_id)\n);\n`" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#bindClientTools", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "bindClientTools", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/middleware.ts", + "symbol": "bindClientTools", + "syntaxKind": "FunctionDeclaration", + "signature": "export function bindClientTools(llm: M, serverTools: unknown[], state: ClientToolsState): ReturnType {\n return llm.bindTools([...serverTools, ...clientToolSpecs(state)]) as ReturnType;\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#clientToolNames", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "clientToolNames", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/middleware.ts", + "symbol": "clientToolNames", + "syntaxKind": "FunctionDeclaration", + "signature": "export function clientToolNames(state: ClientToolsState): Set {\n return new Set(catalog(state).map((t) => t.name));\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#clientToolSpecs", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "clientToolSpecs", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/middleware.ts", + "symbol": "clientToolSpecs", + "syntaxKind": "FunctionDeclaration", + "signature": "export function clientToolSpecs(state: ClientToolsState): OpenAIFunctionTool[] {\n return catalog(state).map((t) => ({\n type: 'function',\n function: { name: t.name, description: t.description ?? '', parameters: t.parameters ?? {} },\n }));\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#clientToolsChannel", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "clientToolsChannel", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/channel.ts", + "symbol": "clientToolsChannel", + "syntaxKind": "FunctionDeclaration", + "signature": "export function clientToolsChannel() {\n return {\n tools: Annotation(),\n client_tools: Annotation(),\n };\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#clientToolsRouter", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "clientToolsRouter", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/router.ts", + "symbol": "clientToolsRouter", + "syntaxKind": "FunctionDeclaration", + "signature": "export function clientToolsRouter(serverToolNames: Iterable, opts?: {\n toolsNode?: string;\n end?: string;\n}): (state: ClientToolsState) => string {\n const names = [...serverToolNames];\n return (state: ClientToolsState) => routeAfterAgent(state, names, opts);\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#createInMemoryClientToolExecutionStore", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "createInMemoryClientToolExecutionStore", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-execution-store.ts", + "symbol": "createInMemoryClientToolExecutionStore", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createInMemoryClientToolExecutionStore(): ClientToolExecutionStore {\n const records = new Map();\n return {\n async claim(key: ClientToolExecutionKey): Promise<'claimed' | ClientToolExecutionRecord> {\n const existing = records.get(mapKey(key));\n if (existing)\n return cloneRecord(existing);\n records.set(mapKey(key), { status: 'executing' });\n return 'claimed';\n },\n async record(key: ClientToolExecutionKey, result: ClientToolResult): Promise {\n records.set(mapKey(key), { status: 'done', result: cloneResult(result) });\n },\n async lookup(threadId: string, toolCallIds: readonly string[]): Promise> {\n const out: Record = {};\n for (const toolCallId of toolCallIds) {\n const existing = records.get(mapKey({ threadId, toolCallId }));\n if (existing)\n out[toolCallId] = cloneRecord(existing);\n }\n return out;\n },\n };\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#createPostgresClientToolExecutionStore", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "createPostgresClientToolExecutionStore", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/postgres-client-tool-execution-store.ts", + "symbol": "createPostgresClientToolExecutionStore", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createPostgresClientToolExecutionStore(sql: PostgresTaggedSql, opts: PostgresClientToolExecutionStoreOptions = {}): ClientToolExecutionStore {\n const tenantId = opts.tenantId ?? '';\n return {\n async claim(key: ClientToolExecutionKey): Promise<'claimed' | ClientToolExecutionRecord> {\n const inserted = await sql `\n INSERT INTO threadplane_client_tool_executions\n (tenant_id, thread_id, tool_call_id, status)\n VALUES (${tenantId}, ${key.threadId}, ${key.toolCallId}, 'executing')\n ON CONFLICT (tenant_id, thread_id, tool_call_id) DO NOTHING\n RETURNING status, result\n `;\n if (inserted.length > 0)\n return 'claimed';\n const existing = await sql `\n SELECT status, result\n FROM threadplane_client_tool_executions\n WHERE tenant_id = ${tenantId}\n AND thread_id = ${key.threadId}\n AND tool_call_id = ${key.toolCallId}\n LIMIT 1\n `;\n return rowToRecord(existing[0]);\n },\n async record(key: ClientToolExecutionKey, result: ClientToolResult): Promise {\n await sql `\n INSERT INTO threadplane_client_tool_executions\n (tenant_id, thread_id, tool_call_id, status, result)\n VALUES (${tenantId}, ${key.threadId}, ${key.toolCallId}, 'done', ${JSON.stringify(result)}::jsonb)\n ON CONFLICT (tenant_id, thread_id, tool_call_id) DO UPDATE\n SET status = 'done',\n result = CASE\n WHEN threadplane_client_tool_executions.status = 'done'\n THEN threadplane_client_tool_executions.result\n ELSE EXCLUDED.result\n END,\n updated_at = now()\n `;\n },\n async lookup(threadId: string, toolCallIds: readonly string[]): Promise> {\n if (toolCallIds.length === 0)\n return {};\n const rows = await sql `\n SELECT tool_call_id, status, result\n FROM threadplane_client_tool_executions\n WHERE tenant_id = ${tenantId}\n AND thread_id = ${threadId}\n AND tool_call_id = ANY(${[...toolCallIds]})\n `;\n const out: Record = {};\n for (const row of rows) {\n if (typeof row['tool_call_id'] !== 'string')\n continue;\n out[row['tool_call_id']] = rowToRecord(row);\n }\n return out;\n },\n };\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#extractClientToolResultMessages", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "extractClientToolResultMessages", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-result-guard.ts", + "symbol": "extractClientToolResultMessages", + "syntaxKind": "FunctionDeclaration", + "signature": "export function extractClientToolResultMessages(messages: readonly BaseMessage[]): ClientToolResultMessage[] {\n const out: ClientToolResultMessage[] = [];\n for (const message of messages) {\n const toolCallId = toolCallIdFromMessage(message);\n if (!toolCallId)\n continue;\n out.push({ toolCallId, result: resultFromMessageContent(message.content) });\n }\n return out;\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#filterDuplicateClientToolResultMessages", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "filterDuplicateClientToolResultMessages", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-result-guard.ts", + "symbol": "filterDuplicateClientToolResultMessages", + "syntaxKind": "FunctionDeclaration", + "signature": "export function filterDuplicateClientToolResultMessages(input: {\n readonly messages: readonly BaseMessage[];\n readonly duplicateToolCallIds: ReadonlySet;\n}): BaseMessage[] {\n return input.messages.filter((message) => {\n const toolCallId = toolCallIdFromMessage(message);\n return !toolCallId || !input.duplicateToolCallIds.has(toolCallId);\n });\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#hasClientToolCall", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "hasClientToolCall", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/middleware.ts", + "symbol": "hasClientToolCall", + "syntaxKind": "FunctionDeclaration", + "signature": "export function hasClientToolCall(state: ClientToolsState): boolean {\n const names = clientToolNames(state);\n return toolCalls(lastMessage(state)).some((c) => {\n const n = callName(c);\n return n !== undefined && names.has(n);\n });\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#hasServerToolCall", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "hasServerToolCall", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/middleware.ts", + "symbol": "hasServerToolCall", + "syntaxKind": "FunctionDeclaration", + "signature": "export function hasServerToolCall(state: ClientToolsState, serverToolNames: Iterable): boolean {\n const server = new Set(serverToolNames);\n const client = clientToolNames(state);\n return toolCalls(lastMessage(state)).some((c) => {\n const n = callName(c);\n return n !== undefined && (server.has(n) || !client.has(n));\n });\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#lastMessage", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "lastMessage", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/middleware.ts", + "symbol": "lastMessage", + "syntaxKind": "FunctionDeclaration", + "signature": "export function lastMessage(state: ClientToolsState): BaseMessage | undefined {\n const msgs = state.messages ?? [];\n return msgs.length ? msgs[msgs.length - 1] : undefined;\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#lookupClientToolExecutions", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "lookupClientToolExecutions", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-result-guard.ts", + "symbol": "lookupClientToolExecutions", + "syntaxKind": "FunctionDeclaration", + "signature": "export function lookupClientToolExecutions(input: {\n readonly threadId: string;\n readonly toolCallIds: readonly string[];\n readonly store: ClientToolExecutionStore;\n}): Promise> {\n return input.store.lookup(input.threadId, input.toolCallIds);\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#recordClientToolResults", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "recordClientToolResults", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/client-tool-result-guard.ts", + "symbol": "recordClientToolResults", + "syntaxKind": "FunctionDeclaration", + "signature": "export async function recordClientToolResults(input: RecordClientToolResultsInput): Promise {\n const recordedToolCallIds: string[] = [];\n const duplicateToolCallIds: string[] = [];\n for (const entry of extractClientToolResultMessages(input.messages)) {\n const key = { threadId: input.threadId, toolCallId: entry.toolCallId };\n const claim = await input.store.claim(key);\n if (claim === 'claimed') {\n await input.store.record(key, entry.result);\n recordedToolCallIds.push(entry.toolCallId);\n continue;\n }\n if (claim.status === 'done') {\n duplicateToolCallIds.push(entry.toolCallId);\n continue;\n }\n await input.store.record(key, entry.result);\n recordedToolCallIds.push(entry.toolCallId);\n }\n return { recordedToolCallIds, duplicateToolCallIds };\n}" + } + ] + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#routeAfterAgent", + "kind": "export", + "path": "libs/middleware/src/langgraph/index.ts", + "symbol": "routeAfterAgent", + "declarations": [ + { + "path": "libs/middleware/src/langgraph/middleware.ts", + "symbol": "routeAfterAgent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function routeAfterAgent(state: ClientToolsState, serverToolNames: Iterable, opts?: {\n toolsNode?: string;\n end?: string;\n}): string {\n const toolsNode = opts?.toolsNode ?? 'server_tools';\n const end = opts?.end ?? '__end__';\n return hasServerToolCall(state, serverToolNames) ? toolsNode : end;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#AngularComponentInputs", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "AngularComponentInputs", + "declarations": [ + { + "path": "libs/render/src/lib/render.types.ts", + "symbol": "AngularComponentInputs", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AngularComponentInputs {\n bindings?: Record;\n emit: (event: string) => void;\n loading?: boolean;\n childKeys: string[];\n spec: Spec;\n [key: string]: unknown;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#AngularComponentRenderer", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "AngularComponentRenderer", + "declarations": [ + { + "path": "libs/render/src/lib/render.types.ts", + "symbol": "AngularComponentRenderer", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type AngularComponentRenderer = Type;" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#AngularRegistry", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "AngularRegistry", + "declarations": [ + { + "path": "libs/render/src/lib/render.types.ts", + "symbol": "AngularRegistry", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface AngularRegistry {\n getEntry(name: string): NormalizedEntry | undefined;\n names(): string[];\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#DefaultFallbackComponent", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "DefaultFallbackComponent", + "declarations": [ + { + "path": "libs/render/src/lib/default-fallback.component.ts", + "symbol": "DefaultFallbackComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'render-default-fallback',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [`\n :host { display: block; width: 100%; }\n .render-default-fallback {\n border: 1px solid var(--tplane-chat-separator, #303540);\n border-radius: 10px;\n padding: 14px;\n background: var(--tplane-chat-surface-alt, #1a1d23);\n }\n .render-default-fallback__label {\n font-size: 12px;\n color: var(--tplane-chat-text-muted, #9aa0aa);\n margin-bottom: 10px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .render-default-fallback__rows {\n display: flex; flex-direction: column; gap: 8px;\n }\n .render-default-fallback__row {\n height: 10px; border-radius: 5px;\n background: linear-gradient(\n 90deg,\n var(--tplane-chat-separator, #303540) 0%,\n color-mix(in srgb, var(--tplane-chat-separator, #303540) 70%, transparent) 50%,\n var(--tplane-chat-separator, #303540) 100%\n );\n background-size: 200% 100%;\n animation: render-default-fallback-shimmer 1.4s ease-in-out infinite;\n }\n .render-default-fallback__row:nth-child(1) { width: 70%; }\n .render-default-fallback__row:nth-child(2) { width: 90%; }\n .render-default-fallback__row:nth-child(3) { width: 50%; }\n @keyframes render-default-fallback-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n `],\n template: `\n
    \n
    \n \n Building UI…\n
    \n
    \n
    \n
    \n
    \n
    \n
    \n `,\n})\nexport class DefaultFallbackComponent {\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RENDER_CONFIG", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RENDER_CONFIG", + "declarations": [ + { + "path": "libs/render/src/lib/provide-render.ts", + "symbol": "RENDER_CONFIG", + "syntaxKind": "VariableDeclaration", + "signature": "RENDER_CONFIG = new InjectionToken('RENDER_CONFIG')" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RENDER_CONTEXT", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RENDER_CONTEXT", + "declarations": [ + { + "path": "libs/render/src/lib/contexts/render-context.ts", + "symbol": "RENDER_CONTEXT", + "syntaxKind": "VariableDeclaration", + "signature": "RENDER_CONTEXT = new InjectionToken('RENDER_CONTEXT')" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RENDER_HOST", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RENDER_HOST", + "declarations": [ + { + "path": "libs/render/src/lib/contexts/render-host.ts", + "symbol": "RENDER_HOST", + "syntaxKind": "VariableDeclaration", + "signature": "RENDER_HOST = new InjectionToken('RENDER_HOST')" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RENDER_LIFECYCLE", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RENDER_LIFECYCLE", + "declarations": [ + { + "path": "libs/render/src/lib/lifecycle.ts", + "symbol": "RENDER_LIFECYCLE", + "syntaxKind": "VariableDeclaration", + "signature": "RENDER_LIFECYCLE = new InjectionToken('RENDER_LIFECYCLE')" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#REPEAT_SCOPE", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "REPEAT_SCOPE", + "declarations": [ + { + "path": "libs/render/src/lib/contexts/repeat-scope.ts", + "symbol": "REPEAT_SCOPE", + "syntaxKind": "VariableDeclaration", + "signature": "REPEAT_SCOPE = new InjectionToken('REPEAT_SCOPE')" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderConfig", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderConfig", + "declarations": [ + { + "path": "libs/render/src/lib/render.types.ts", + "symbol": "RenderConfig", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RenderConfig {\n telemetry?: boolean;\n registry?: AngularRegistry;\n store?: StateStore;\n functions?: Record;\n handlers?: Record) => unknown | Promise>;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderContext", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderContext", + "declarations": [ + { + "path": "libs/render/src/lib/contexts/render-context.ts", + "symbol": "RenderContext", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RenderContext {\n registry: AngularRegistry;\n store: StateStore;\n functions?: Record;\n handlers?: Record) => unknown | Promise>;\n emitEvent?: (event: RenderEvent) => void;\n loading?: boolean;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderElementComponent", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderElementComponent", + "declarations": [ + { + "path": "libs/render/src/lib/render-element.component.ts", + "symbol": "RenderElementComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'render-element',\n standalone: true,\n imports: [NgComponentOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n { provide: RENDER_HOST, useFactory: (el: RenderElementComponent) => el.host, deps: [RenderElementComponent] },\n ],\n template: `\n @if (!element()?.repeat) {\n @if (visible()) {\n \n }\n } @else {\n @for (repeatInjector of repeatInjectors(); track $index) {\n @if (repeatVisible()[$index]) {\n \n }\n }\n }\n `,\n})\nexport class RenderElementComponent implements OnInit {\n readonly elementKey = input.required();\n readonly spec = input.required();\n private readonly ctx = inject(RENDER_CONTEXT);\n private readonly repeatScope = inject(REPEAT_SCOPE, { optional: true });\n readonly parentInjector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n private readonly document = inject(DOCUMENT);\n private readonly collectionPolicy = inject(DEVELOPMENT_COLLECTION_POLICY, { optional: true });\n private readonly outlets = viewChildren(NgComponentOutlet);\n private readonly observedInstances = new WeakSet();\n private readonly development = createDevelopmentRuntime({\n integration: 'render', packageName: '@threadplane/render', packageVersion,\n installationToken: (typeof ngDevMode === 'undefined' || ngDevMode) && isDevMode() ? installationToken : null,\n enabled: () => this.collectionPolicy?.() ?? true,\n });\n private destroyed = false;\n constructor() {\n this.development.touch();\n this.destroyRef.onDestroy(() => this.development.dispose());\n afterEveryRender(() => {\n if (this.destroyed)\n return;\n const component = this.componentClass();\n if (!component)\n return;\n for (const outlet of this.outlets()) {\n const instance = outlet.componentInstance;\n if (outlet.ngComponentOutlet !== component || !instance || this.observedInstances.has(instance))\n continue;\n this.observedInstances.add(instance);\n this.development.milestone('generative_ui.rendered');\n }\n });\n this.destroyRef.onDestroy(() => {\n const el = this.element();\n if (el && this.ctx.emitEvent) {\n this.ctx.emitEvent({\n type: 'lifecycle',\n event: 'destroyed',\n scope: 'element',\n elementKey: this.elementKey(),\n elementType: el.type,\n });\n }\n this.destroyed = true;\n });\n effect(() => {\n if (this.mountedReal())\n return;\n const el = this.element();\n if (!el || el.repeat)\n return;\n if (!this.notReady() && this.entry()?.component) {\n this.mountedReal.set(true);\n }\n });\n effect(() => {\n const el = this.element();\n if (!el?.repeat || !this.entry()?.component)\n return;\n const raw = this.repeatRawNotReady();\n const latched = this.repeatMountedReal();\n const next = raw.map((notReady, index) => (latched[index] ?? false) || !notReady);\n if (next.length !== latched.length || next.some((v, i) => v !== latched[i])) {\n this.repeatMountedReal.set(next);\n }\n });\n }\n ngOnInit(): void {\n const el = this.element();\n if (el && this.ctx.emitEvent) {\n this.ctx.emitEvent({\n type: 'lifecycle',\n event: 'mounted',\n scope: 'element',\n elementKey: this.elementKey(),\n elementType: el.type,\n });\n }\n }\n readonly element: Signal = computed(() => this.spec()?.elements?.[this.elementKey()], { equal: Object.is });\n readonly entry = computed(() => {\n const el = this.element();\n return el ? this.ctx.registry.getEntry(el.type) : undefined;\n });\n readonly componentClass = computed(() => {\n const el = this.element();\n if (!el)\n return null;\n return this.entry()?.component ?? null;\n });\n private readonly propCtx = computed(() => buildPropResolutionContext(this.ctx.store, this.repeatScope ?? undefined, this.ctx.functions));\n private readonly mountedReal = signal(false);\n readonly notReady = computed(() => {\n if (this.mountedReal())\n return false;\n const el = this.element();\n if (!el || !el.props)\n return false;\n const resolved = resolveElementProps(el.props, this.propCtx());\n return !isElementReady(this.entry(), resolved);\n });\n readonly mountClass = computed(() => {\n const el = this.element();\n if (!el)\n return null;\n const real = this.entry()?.component ?? null;\n if (this.notReady()) {\n return this.entry()?.fallback ?? null;\n }\n return real;\n });\n readonly visible = computed(() => {\n const el = this.element();\n if (!el)\n return false;\n if (this.mountClass() === null)\n return false;\n return evaluateVisibility(el.visible, this.propCtx());\n });\n private invokeHandlers(event: string, payload?: Record, repeatIndex?: number): void {\n const el = this.element();\n if (!el?.on)\n return;\n const binding = el.on[event];\n if (!binding)\n return;\n const bindings = Array.isArray(binding) ? binding : [binding];\n for (const b of bindings) {\n if (b.preventDefault)\n preventDefaultOn(payload);\n if (b.confirm && !this.askForConfirmation(b.confirm))\n continue;\n const handler = this.ctx.handlers?.[b.action];\n if (!handler)\n continue;\n const resolved = resolveElementProps((b.params ?? {}) as Record, repeatIndex === undefined\n ? this.propCtx()\n : this.repeatPropCtxs()[repeatIndex] ?? this.propCtx());\n const params = { ...resolved, ...(payload ?? {}) };\n let result: unknown;\n try {\n result = runInInjectionContext(this.parentInjector, () => handler(params));\n }\n catch (error) {\n if (!b.onError)\n throw error;\n this.runOnError(b.onError, error);\n continue;\n }\n if (result instanceof Promise) {\n result.then(() => this.runOnSuccess(b.onSuccess), (error: unknown) => {\n if (!b.onError)\n return;\n this.runOnError(b.onError, error);\n });\n }\n else {\n this.runOnSuccess(b.onSuccess);\n }\n }\n }\n private askForConfirmation(confirm: ActionConfirm): boolean {\n const view = this.document.defaultView;\n if (!view?.confirm)\n return true;\n return Boolean(view.confirm(confirm.message));\n }\n private runOnSuccess(onSuccess: ActionOnSuccess | undefined): void {\n if (!onSuccess || this.destroyed)\n return;\n if ('navigate' in onSuccess) {\n this.document.defaultView?.location.assign(onSuccess.navigate);\n return;\n }\n if ('set' in onSuccess) {\n for (const [path, value] of Object.entries(onSuccess.set)) {\n this.ctx.store.set(path, value);\n }\n return;\n }\n this.dispatchAction(onSuccess.action);\n }\n private runOnError(onError: ActionOnError, error: unknown): void {\n if (this.destroyed)\n return;\n if ('set' in onError) {\n const message = error instanceof Error ? error.message : String(error);\n for (const [path, value] of Object.entries(onError.set)) {\n this.ctx.store.set(path, value === '$error.message' ? message : value);\n }\n return;\n }\n this.dispatchAction(onError.action);\n }\n private dispatchAction(name: string): void {\n const handler = this.ctx.handlers?.[name];\n if (!handler)\n return;\n runInInjectionContext(this.parentInjector, () => handler({}));\n }\n readonly host: RenderHost = {\n set: (path: string, value: unknown) => { if (this.destroyed)\n return; this.ctx.store?.set(path, value); },\n emit: (event: string, payload?: Record) => { if (this.destroyed)\n return; this.invokeHandlers(event, payload); },\n result: (value: unknown) => { if (this.destroyed)\n return; this.ctx.emitEvent?.({ type: 'result', value, elementKey: this.elementKey() }); },\n };\n private hostForRepeatIndex(index: number): RenderHost {\n return {\n set: this.host.set,\n result: this.host.result,\n emit: (event: string, payload?: Record) => {\n if (this.destroyed)\n return;\n this.invokeHandlers(event, payload, index);\n },\n };\n }\n private readonly emitFn = (event: string) => {\n this.invokeHandlers(event);\n };\n readonly resolvedInputs = computed(() => {\n const el = this.element();\n if (!el)\n return {};\n const ctx = this.propCtx();\n const resolved = resolveElementProps(el.props ?? {}, ctx);\n const bindings = resolveBindings(el.props ?? {}, ctx);\n return {\n ...resolved,\n bindings,\n emit: this.emitFn,\n loading: this.ctx.loading ?? false,\n childKeys: el.children ?? [],\n spec: this.spec(),\n };\n });\n readonly filteredResolvedInputs = computed(() => filterInputsForClass(this.mountClass() as Type | null, this.resolvedInputs()));\n private readonly repeatItems = computed(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n const items = this.ctx.store.get(el.repeat.statePath);\n return Array.isArray(items) ? items : [];\n });\n private readonly repeatScopes = computed(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n return this.repeatItems().map((item, index) => ({\n item,\n index,\n basePath: `${el.repeat!.statePath}/${index}`,\n } satisfies RepeatScope));\n });\n private readonly repeatPropCtxs = computed(() => this.repeatScopes().map(scope => buildPropResolutionContext(this.ctx.store, scope, this.ctx.functions)));\n readonly repeatInjectors = computed(() => {\n return this.repeatScopes().map((scope, index) => Injector.create({\n providers: [\n { provide: REPEAT_SCOPE, useValue: scope },\n { provide: RENDER_HOST, useValue: this.hostForRepeatIndex(index) },\n ],\n parent: this.parentInjector,\n }));\n });\n private readonly repeatMountedReal = signal([]);\n private readonly repeatRawNotReady = computed(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n const props = el.props;\n if (!props)\n return this.repeatPropCtxs().map(() => false);\n const entry = this.entry();\n return this.repeatPropCtxs().map(ctx => !isElementReady(entry, resolveElementProps(props, ctx)));\n });\n readonly repeatNotReady = computed(() => {\n const latched = this.repeatMountedReal();\n return this.repeatRawNotReady().map((notReady, index) => latched[index] ? false : notReady);\n });\n readonly repeatMountClasses = computed<(AngularComponentRenderer | null)[]>(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n const entry = this.entry();\n const real = entry?.component ?? null;\n const fallback = entry?.fallback ?? null;\n return this.repeatNotReady().map(notReady => (notReady ? fallback : real));\n });\n readonly repeatInputs = computed(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n return this.repeatPropCtxs().map((ctx, index) => {\n const resolved = resolveElementProps(el.props ?? {}, ctx);\n const bindings = resolveBindings(el.props ?? {}, ctx);\n return {\n ...resolved,\n bindings,\n emit: (event: string) => this.invokeHandlers(event, undefined, index),\n loading: this.ctx.loading ?? false,\n childKeys: el.children ?? [],\n spec: this.spec(),\n };\n });\n });\n readonly filteredRepeatInputs = computed(() => {\n const classes = this.repeatMountClasses();\n return this.repeatInputs().map((inputs, index) => filterInputsForClass(classes[index] as Type | null, inputs));\n });\n readonly repeatVisible = computed(() => {\n const el = this.element();\n if (!el?.repeat)\n return [];\n const classes = this.repeatMountClasses();\n return this.repeatPropCtxs().map((ctx, index) => classes[index] !== null && evaluateVisibility(el.visible, ctx));\n });\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderEvent", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderEvent", + "declarations": [ + { + "path": "libs/render/src/lib/render-event.ts", + "symbol": "RenderEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type RenderEvent = RenderHandlerEvent | RenderStateChangeEvent | RenderLifecycleEvent | RenderResultEvent;" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderHandlerEvent", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderHandlerEvent", + "declarations": [ + { + "path": "libs/render/src/lib/render-event.ts", + "symbol": "RenderHandlerEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RenderHandlerEvent {\n readonly type: 'handler';\n readonly action: string;\n readonly params: Record;\n readonly result?: unknown;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderHost", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderHost", + "declarations": [ + { + "path": "libs/render/src/lib/contexts/render-host.ts", + "symbol": "RenderHost", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RenderHost {\n set(path: string, value: unknown): void;\n emit(event: string, payload?: Record): void;\n result(value: unknown): void;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderLifecycle", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderLifecycle", + "declarations": [ + { + "path": "libs/render/src/lib/lifecycle.ts", + "symbol": "RenderLifecycle", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RenderLifecycle {\n readonly firstMountAt: Signal<{\n kind: 'spec' | 'element';\n elementType?: string;\n at: number;\n } | null>;\n readonly mountCount: Signal;\n readonly lastMountAt: Signal;\n readonly lastStateChangeAt: Signal;\n readonly lastHandlerInvokedAt: Signal<{\n action: string;\n at: number;\n } | null>;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderLifecycleEvent", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderLifecycleEvent", + "declarations": [ + { + "path": "libs/render/src/lib/render-event.ts", + "symbol": "RenderLifecycleEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RenderLifecycleEvent {\n readonly type: 'lifecycle';\n readonly event: 'mounted' | 'destroyed';\n readonly scope: 'spec' | 'element';\n readonly elementKey?: string;\n readonly elementType?: string;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderResultEvent", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderResultEvent", + "declarations": [ + { + "path": "libs/render/src/lib/render-event.ts", + "symbol": "RenderResultEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RenderResultEvent {\n readonly type: 'result';\n readonly value: unknown;\n readonly elementKey?: string;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderSpecComponent", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderSpecComponent", + "declarations": [ + { + "path": "libs/render/src/lib/render-spec.component.ts", + "symbol": "RenderSpecComponent", + "syntaxKind": "ClassDeclaration", + "signature": "@Component({\n selector: 'render-spec',\n standalone: true,\n imports: [RenderElementComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n viewProviders: [\n {\n provide: DEVELOPMENT_COLLECTION_POLICY,\n useFactory: () => {\n const host = inject(RenderSpecComponent);\n const parent = inject(DEVELOPMENT_COLLECTION_POLICY, { optional: true, skipSelf: true });\n const config = inject(RENDER_CONFIG, { optional: true });\n return () => (parent?.() ?? true) && host.telemetry() !== false && config?.telemetry !== false;\n },\n },\n {\n provide: RENDER_CONTEXT,\n useFactory: () => inject(RenderSpecComponent)._context(),\n },\n ],\n template: `\n @if (spec()?.root; as rootKey) {\n \n }\n `,\n})\nexport class RenderSpecComponent implements OnInit {\n readonly spec = input(null);\n readonly registry = input(undefined);\n readonly store = input(undefined);\n readonly functions = input | undefined>(undefined);\n readonly handlers = input) => unknown | Promise> | undefined>(undefined);\n readonly loading = input(false);\n readonly events = output();\n readonly telemetry = input(undefined);\n private readonly config = inject(RENDER_CONFIG, { optional: true });\n private readonly viewRegistry = inject(VIEW_REGISTRY, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n private readonly lifecycle = inject(RenderLifecycleService, { optional: true });\n private destroyed = false;\n private isDestroyed(): boolean {\n return this.destroyed || this.destroyRef.destroyed;\n }\n private readonly guardedEmit = makeGuardedEmit((e) => this.events.emit(e), () => this.isDestroyed());\n private _internalStore: StateStore | undefined;\n private getOrCreateInternalStore(): StateStore {\n if (!this._internalStore) {\n this._internalStore = signalStateStore(this.spec()?.state ?? {});\n }\n return this._internalStore;\n }\n private readonly resolvedStore = computed(() => {\n const inputStore = this.store();\n if (inputStore)\n return inputStore;\n const configStore = this.config?.store;\n if (configStore)\n return configStore;\n return this.getOrCreateInternalStore();\n });\n private readonly resolvedRegistry = computed(() => {\n const inputRegistry = this.registry();\n if (inputRegistry)\n return inputRegistry;\n const configRegistry = this.config?.registry;\n if (configRegistry)\n return configRegistry;\n if (this.viewRegistry)\n return toRenderRegistry(this.viewRegistry);\n return { getEntry: () => undefined, names: () => [] };\n });\n private readonly wrappedHandlers = computed(() => {\n const inputHandlers = this.handlers() ?? this.config?.handlers;\n if (!inputHandlers)\n return undefined;\n const wrapped: Record) => unknown | Promise> = {};\n for (const [name, handler] of Object.entries(inputHandlers)) {\n wrapped[name] = (params: Record) => {\n const result = handler(params);\n if (result instanceof Promise) {\n result.then((r) => {\n this.emitTapped({ type: 'handler', action: name, params, result: r });\n }, () => {\n this.emitTapped({ type: 'handler', action: name, params, result: undefined });\n });\n }\n else {\n this.emitTapped({ type: 'handler', action: name, params, result });\n }\n return result;\n };\n }\n return wrapped;\n });\n private readonly emitTapped = (event: RenderEvent): void => {\n this.guardedEmit(event);\n if (this.isDestroyed() || !this.lifecycle)\n return;\n switch (event.type) {\n case 'lifecycle':\n this.lifecycle.notifyLifecycle({\n kind: event.scope,\n type: event.event,\n elementType: event.elementType,\n });\n break;\n case 'stateChange':\n this.lifecycle.notifyStateChange();\n break;\n case 'handler':\n this.lifecycle.notifyHandlerInvoked(event.action);\n break;\n }\n };\n private readonly emitEvent = (event: RenderEvent) => {\n this.emitTapped(event);\n };\n readonly _context = computed(() => ({\n registry: this.resolvedRegistry(),\n store: this.resolvedStore(),\n functions: this.functions() ?? this.config?.functions,\n handlers: this.wrappedHandlers(),\n emitEvent: this.emitEvent,\n loading: this.loading(),\n }));\n constructor() {\n effect(() => {\n const store = this.resolvedStore();\n const unsub = store.subscribe(() => {\n const snapshot = store.getSnapshot() as Record;\n const change = (store as SignalStateStore).lastChange?.();\n this.emitTapped({\n type: 'stateChange',\n path: change?.path ?? '/',\n value: change ? change.value : snapshot,\n snapshot,\n });\n });\n this.destroyRef.onDestroy(unsub);\n });\n this.destroyRef.onDestroy(() => {\n this.destroyed = true;\n this.emitTapped({ type: 'lifecycle', event: 'destroyed', scope: 'spec' });\n });\n }\n ngOnInit(): void {\n this.emitTapped({ type: 'lifecycle', event: 'mounted', scope: 'spec' });\n }\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderStateChangeEvent", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderStateChangeEvent", + "declarations": [ + { + "path": "libs/render/src/lib/render-event.ts", + "symbol": "RenderStateChangeEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RenderStateChangeEvent {\n readonly type: 'stateChange';\n readonly path: string;\n readonly value: unknown;\n readonly snapshot: Record;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RenderViewEntry", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RenderViewEntry", + "declarations": [ + { + "path": "libs/render/src/lib/render.types.ts", + "symbol": "RenderViewEntry", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RenderViewEntry {\n component: Type;\n fallback?: Type;\n schema?: StandardSchemaV1;\n description?: string;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#RepeatScope", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "RepeatScope", + "declarations": [ + { + "path": "libs/render/src/lib/contexts/repeat-scope.ts", + "symbol": "RepeatScope", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RepeatScope {\n item: unknown;\n index: number;\n basePath: string;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#SignalStateStore", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "SignalStateStore", + "declarations": [ + { + "path": "libs/render/src/lib/signal-state-store.ts", + "symbol": "SignalStateStore", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface SignalStateStore extends StateStore {\n lastChange?: () => StateChangeRecord | undefined;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#StandardSchemaInferInput", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "StandardSchemaInferInput", + "declarations": [ + { + "path": "libs/render/src/lib/standard-schema.ts", + "symbol": "StandardSchemaInferInput", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type StandardSchemaInferInput = NonNullable['input'];" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#StandardSchemaInferOutput", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "StandardSchemaInferOutput", + "declarations": [ + { + "path": "libs/render/src/lib/standard-schema.ts", + "symbol": "StandardSchemaInferOutput", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type StandardSchemaInferOutput = NonNullable['output'];" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#StandardSchemaV1", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "StandardSchemaV1", + "declarations": [ + { + "path": "libs/render/src/lib/standard-schema.ts", + "symbol": "StandardSchemaV1", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface StandardSchemaV1 {\n readonly '~standard': StandardSchemaProps;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#StateChangeRecord", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "StateChangeRecord", + "declarations": [ + { + "path": "libs/render/src/lib/signal-state-store.ts", + "symbol": "StateChangeRecord", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface StateChangeRecord {\n readonly path: string;\n readonly value: unknown;\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#VIEW_REGISTRY", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "VIEW_REGISTRY", + "declarations": [ + { + "path": "libs/render/src/lib/provide-views.ts", + "symbol": "VIEW_REGISTRY", + "syntaxKind": "VariableDeclaration", + "signature": "VIEW_REGISTRY = new InjectionToken('VIEW_REGISTRY')" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#ViewRegistry", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "ViewRegistry", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "ViewRegistry", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ViewRegistry = Readonly | RenderViewEntry>>;" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#defineAngularRegistry", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "defineAngularRegistry", + "declarations": [ + { + "path": "libs/render/src/lib/define-angular-registry.ts", + "symbol": "defineAngularRegistry", + "syntaxKind": "FunctionDeclaration", + "signature": "export function defineAngularRegistry(componentMap: RegistryInput): AngularRegistry {\n const map = new Map();\n for (const [name, entry] of Object.entries(componentMap)) {\n map.set(name, normalize(entry));\n }\n return {\n getEntry: (name: string) => map.get(name),\n names: () => [...map.keys()],\n };\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#injectRenderHost", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "injectRenderHost", + "declarations": [ + { + "path": "libs/render/src/lib/contexts/render-host.ts", + "symbol": "injectRenderHost", + "syntaxKind": "FunctionDeclaration", + "signature": "export function injectRenderHost(): RenderHost {\n return inject(RENDER_HOST);\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#overrideViews", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "overrideViews", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "overrideViews", + "syntaxKind": "FunctionDeclaration", + "signature": "export function overrideViews(base: ViewRegistry, overrides: Record | RenderViewEntry>): ViewRegistry {\n return Object.freeze({ ...base, ...overrides });\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#provideRender", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "provideRender", + "declarations": [ + { + "path": "libs/render/src/lib/provide-render.ts", + "symbol": "provideRender", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideRender(config: RenderConfig) {\n return makeEnvironmentProviders([\n { provide: RENDER_CONFIG, useValue: config },\n RenderLifecycleService,\n { provide: RENDER_LIFECYCLE, useExisting: RenderLifecycleService },\n ]);\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#provideViews", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "provideViews", + "declarations": [ + { + "path": "libs/render/src/lib/provide-views.ts", + "symbol": "provideViews", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideViews(registry: ViewRegistry) {\n return makeEnvironmentProviders([\n { provide: VIEW_REGISTRY, useValue: registry },\n ]);\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#signalStateStore", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "signalStateStore", + "declarations": [ + { + "path": "libs/render/src/lib/signal-state-store.ts", + "symbol": "signalStateStore", + "syntaxKind": "FunctionDeclaration", + "signature": "export function signalStateStore(initialState: StateModel = {}): SignalStateStore {\n const state = signal(initialState);\n const listeners = new Set<() => void>();\n let lastChange: StateChangeRecord | undefined;\n function notify(): void {\n for (const listener of listeners)\n listener();\n }\n return {\n get(path: string): unknown {\n return getByPath(state(), parsePointer(path));\n },\n set(path: string, value: unknown): void {\n const segments = parsePointer(path);\n const current = getByPath(state(), segments);\n if (current === value)\n return;\n state.set(setByPath(state(), segments, value) as StateModel);\n lastChange = { path, value };\n notify();\n },\n update(updates: Record): void {\n let current = state();\n let applied: StateChangeRecord | undefined;\n for (const [path, value] of Object.entries(updates)) {\n const segments = parsePointer(path);\n const existing = getByPath(current, segments);\n if (existing !== value) {\n current = setByPath(current, segments, value) as StateModel;\n applied = { path, value };\n }\n }\n if (applied) {\n state.set(current);\n lastChange = applied;\n notify();\n }\n },\n getSnapshot(): StateModel {\n return state();\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n lastChange(): StateChangeRecord | undefined {\n return lastChange;\n },\n };\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#toRenderRegistry", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "toRenderRegistry", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "toRenderRegistry", + "syntaxKind": "FunctionDeclaration", + "signature": "export function toRenderRegistry(registry: ViewRegistry): AngularRegistry {\n return defineAngularRegistry(registry);\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#views", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "views", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "views", + "syntaxKind": "FunctionDeclaration", + "signature": "export function views(map: Record | RenderViewEntry>): ViewRegistry {\n return Object.freeze({ ...map });\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#withViews", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "withViews", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "withViews", + "syntaxKind": "FunctionDeclaration", + "signature": "export function withViews(base: ViewRegistry, additions: Record | RenderViewEntry>): ViewRegistry {\n return Object.freeze({ ...additions, ...base });\n}" + } + ] + }, + { + "id": "export:libs/render/src/public-api.ts#withoutViews", + "kind": "export", + "path": "libs/render/src/public-api.ts", + "symbol": "withoutViews", + "declarations": [ + { + "path": "libs/render/src/lib/views.ts", + "symbol": "withoutViews", + "syntaxKind": "FunctionDeclaration", + "signature": "export function withoutViews(base: ViewRegistry, ...names: string[]): ViewRegistry {\n const result = { ...base };\n for (const name of names)\n delete result[name];\n return Object.freeze(result);\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#CaptureConfig", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "CaptureConfig", + "declarations": [ + { + "path": "libs/telemetry/src/browser/properties.ts", + "symbol": "CaptureConfig", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type CaptureConfig = {\n token?: string;\n captureLocal?: boolean;\n host?: string;\n};" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#DEVELOPMENT_COLLECTION_POLICY", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "DEVELOPMENT_COLLECTION_POLICY", + "declarations": [ + { + "path": "libs/telemetry/src/browser/development/runtime.ts", + "symbol": "DEVELOPMENT_COLLECTION_POLICY", + "syntaxKind": "VariableDeclaration", + "signature": "DEVELOPMENT_COLLECTION_POLICY = new InjectionToken<() => boolean>('DEVELOPMENT_COLLECTION_POLICY')" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#DevelopmentMilestone", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "DevelopmentMilestone", + "declarations": [ + { + "path": "libs/telemetry/src/browser/development/types.ts", + "symbol": "DevelopmentMilestone", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type DevelopmentMilestone = 'transport.connected' | 'runtime.first_stream_completed' | 'thread.persisted' | 'interrupt.handled' | 'generative_ui.rendered';" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#DevelopmentRuntime", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "DevelopmentRuntime", + "declarations": [ + { + "path": "libs/telemetry/src/browser/development/types.ts", + "symbol": "DevelopmentRuntime", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface DevelopmentRuntime {\n touch(): void;\n milestone(kind: DevelopmentMilestone, durationMs?: number): void;\n dispose(): void;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#DevelopmentRuntimeOptions", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "DevelopmentRuntimeOptions", + "declarations": [ + { + "path": "libs/telemetry/src/browser/development/types.ts", + "symbol": "DevelopmentRuntimeOptions", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface DevelopmentRuntimeOptions {\n integration: DevelopmentIntegration;\n packageName: '@threadplane/langgraph' | '@threadplane/ag-ui' | '@threadplane/render';\n packageVersion: string;\n installationToken?: string | null;\n enabled?: () => boolean;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#THREADPLANE_TELEMETRY_CONFIG", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "THREADPLANE_TELEMETRY_CONFIG", + "declarations": [ + { + "path": "libs/telemetry/src/browser/tokens.ts", + "symbol": "THREADPLANE_TELEMETRY_CONFIG", + "syntaxKind": "VariableDeclaration", + "signature": "THREADPLANE_TELEMETRY_CONFIG = new InjectionToken('THREADPLANE_TELEMETRY_CONFIG')" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneBrowserEvent", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "ThreadplaneBrowserEvent", + "declarations": [ + { + "path": "libs/telemetry/src/browser/service.ts", + "symbol": "ThreadplaneBrowserEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ThreadplaneBrowserEvent = ThreadplaneTelemetryEvent;" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneBrowserRuntimeTelemetry", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "ThreadplaneBrowserRuntimeTelemetry", + "declarations": [ + { + "path": "libs/telemetry/src/browser/service.ts", + "symbol": "ThreadplaneBrowserRuntimeTelemetry", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ThreadplaneBrowserRuntimeTelemetry {\n transport: string;\n surface?: string;\n provider?: string;\n model?: string;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneBrowserStreamErrorTelemetry", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "ThreadplaneBrowserStreamErrorTelemetry", + "declarations": [ + { + "path": "libs/telemetry/src/browser/service.ts", + "symbol": "ThreadplaneBrowserStreamErrorTelemetry", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ThreadplaneBrowserStreamErrorTelemetry extends ThreadplaneBrowserStreamTelemetry {\n error?: unknown;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneBrowserStreamTelemetry", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "ThreadplaneBrowserStreamTelemetry", + "declarations": [ + { + "path": "libs/telemetry/src/browser/service.ts", + "symbol": "ThreadplaneBrowserStreamTelemetry", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ThreadplaneBrowserStreamTelemetry extends ThreadplaneBrowserRuntimeTelemetry {\n durationMs?: number;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneTelemetryConfig", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "ThreadplaneTelemetryConfig", + "declarations": [ + { + "path": "libs/telemetry/src/browser/tokens.ts", + "symbol": "ThreadplaneTelemetryConfig", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ThreadplaneTelemetryConfig {\n enabled: boolean;\n sink?: ThreadplaneTelemetrySink;\n endpoint?: string;\n posthogKey?: string;\n posthogHost?: string;\n sampleRate?: number;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneTelemetryEvent", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "ThreadplaneTelemetryEvent", + "declarations": [ + { + "path": "libs/telemetry/src/browser/tokens.ts", + "symbol": "ThreadplaneTelemetryEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ThreadplaneTelemetryEvent = 'tplane:browser_provided' | 'tplane:browser_chat_init' | 'tplane:runtime_instance_created' | 'tplane:runtime_request_created' | 'tplane:stream_started' | 'tplane:stream_ended' | 'tplane:stream_errored';" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneTelemetryEventPayload", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "ThreadplaneTelemetryEventPayload", + "declarations": [ + { + "path": "libs/telemetry/src/browser/tokens.ts", + "symbol": "ThreadplaneTelemetryEventPayload", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ThreadplaneTelemetryEventPayload {\n event: ThreadplaneTelemetryEvent;\n properties?: Record;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneTelemetryService", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "ThreadplaneTelemetryService", + "declarations": [ + { + "path": "libs/telemetry/src/browser/service.ts", + "symbol": "ThreadplaneTelemetryService", + "syntaxKind": "ClassDeclaration", + "signature": "@Injectable({ providedIn: 'root' })\nexport class ThreadplaneTelemetryService {\n private config: ThreadplaneTelemetryConfig | null = inject(THREADPLANE_TELEMETRY_CONFIG, { optional: true });\n private postHogPromise: Promise | null = null;\n private distinctId: string | null = null;\n async capture(event: ThreadplaneTelemetryEvent, properties?: Record): Promise {\n if (!this.config?.enabled)\n return;\n const sampleRate = normalizeSampleRate(this.config.sampleRate);\n if (sampleRate === 0)\n return;\n if (sampleRate < 1 && Math.random() >= sampleRate)\n return;\n const enrichedProperties = {\n ...(properties ?? {}),\n sample_weight: properties?.['sample_weight'] ?? 1 / sampleRate,\n };\n try {\n if (this.config.sink) {\n await this.config.sink({ event, properties: enrichedProperties });\n return;\n }\n if (this.config.endpoint) {\n await this.captureEndpoint(event, enrichedProperties);\n return;\n }\n if (!this.config.posthogKey)\n return;\n const ph = await this.loadPostHog();\n if (!ph)\n return;\n ph.capture(event, enrichedProperties);\n }\n catch {\n }\n }\n captureRuntimeInstanceCreated(input: ThreadplaneBrowserRuntimeTelemetry): Promise {\n return this.capture('tplane:runtime_instance_created', { ...input });\n }\n captureRuntimeRequestCreated(input: ThreadplaneBrowserRuntimeTelemetry & {\n requestType: string;\n }): Promise {\n return this.capture('tplane:runtime_request_created', { ...input });\n }\n captureStreamStarted(input: ThreadplaneBrowserStreamTelemetry): Promise {\n return this.capture('tplane:stream_started', { ...input });\n }\n captureStreamEnded(input: ThreadplaneBrowserStreamTelemetry): Promise {\n return this.capture('tplane:stream_ended', { ...input });\n }\n captureStreamErrored(input: ThreadplaneBrowserStreamErrorTelemetry): Promise {\n const { error, ...rest } = input;\n return this.capture('tplane:stream_errored', {\n ...rest,\n errorClass: errorClass(error),\n });\n }\n private async captureEndpoint(event: ThreadplaneTelemetryEvent, properties: Record): Promise {\n if (typeof fetch !== 'function' || !this.config?.endpoint)\n return;\n await fetch(this.config.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n keepalive: true,\n body: JSON.stringify({\n event,\n distinctId: this.getDistinctId(),\n properties,\n }),\n });\n }\n private getDistinctId(): string {\n if (!this.distinctId) {\n const cryptoApi = globalThis.crypto as Crypto | undefined;\n const value = typeof cryptoApi?.randomUUID === 'function'\n ? cryptoApi.randomUUID()\n : Math.random().toString(36).slice(2, 12);\n this.distinctId = `browser:${value}`;\n }\n return this.distinctId;\n }\n private loadPostHog(): Promise {\n if (!this.postHogPromise) {\n this.postHogPromise = import('posthog-js').then((mod) => {\n if (!this.config?.posthogKey)\n return null;\n mod.default.init(this.config.posthogKey, {\n api_host: this.config.posthogHost ?? 'https://us.i.posthog.com',\n });\n return mod.default;\n }).catch(() => null);\n }\n return this.postHogPromise;\n }\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneTelemetrySink", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "ThreadplaneTelemetrySink", + "declarations": [ + { + "path": "libs/telemetry/src/browser/tokens.ts", + "symbol": "ThreadplaneTelemetrySink", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ThreadplaneTelemetrySink = (payload: ThreadplaneTelemetryEventPayload) => void | Promise;" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#createDevelopmentRuntime", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "createDevelopmentRuntime", + "declarations": [ + { + "path": "libs/telemetry/src/browser/development/runtime.ts", + "symbol": "createDevelopmentRuntime", + "syntaxKind": "FunctionDeclaration", + "signature": "export function createDevelopmentRuntime(options: DevelopmentRuntimeOptions): DevelopmentRuntime {\n let disposed = false;\n const owner: RuntimeOwner = {\n options: {\n ...options,\n installationToken: typeof options.installationToken === 'string' &&\n UUID.test(options.installationToken)\n ? options.installationToken\n : undefined,\n },\n allowed: () => {\n try {\n return (!disposed &&\n (options.enabled?.() ?? true) &&\n ['langgraph', 'ag-ui', 'render'].includes(options.integration) &&\n options.packageName === `@threadplane/${options.integration}` &&\n /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/u.test(options.packageVersion) &&\n options.packageVersion.length <= 64 &&\n browserAllowed());\n }\n catch {\n return false;\n }\n },\n };\n const use = (kind?: Parameters[0], durationMs?: number) => {\n try {\n if (!owner.allowed()) {\n collector?.prune();\n return;\n }\n collector ??= new DevelopmentCollector();\n collector.touch(owner, kind, durationMs);\n }\n catch {\n }\n };\n return {\n touch: () => use(),\n milestone: (kind, durationMs) => {\n if (MILESTONES.includes(kind))\n use(kind, durationMs);\n },\n dispose: () => {\n disposed = true;\n collector?.prune();\n },\n };\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#getDevelopmentCollectionDiagnostics", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "getDevelopmentCollectionDiagnostics", + "declarations": [ + { + "path": "libs/telemetry/src/browser/development/runtime.ts", + "symbol": "getDevelopmentCollectionDiagnostics", + "syntaxKind": "FunctionDeclaration", + "signature": "export function getDevelopmentCollectionDiagnostics() {\n return (collector?.diagnostics() ?? {\n discarded: 0,\n failures: 0,\n acknowledged: 0,\n pending: 0,\n });\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#isDevelopmentRuntimeEnabled", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "isDevelopmentRuntimeEnabled", + "declarations": [ + { + "path": "libs/telemetry/src/browser/development/runtime.ts", + "symbol": "isDevelopmentRuntimeEnabled", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isDevelopmentRuntimeEnabled(agent: object): boolean {\n try {\n return policies.get(agent)?.() === true;\n }\n catch {\n return false;\n }\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#isLocalAnalyticsHost", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "isLocalAnalyticsHost", + "declarations": [ + { + "path": "libs/telemetry/src/browser/properties.ts", + "symbol": "isLocalAnalyticsHost", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isLocalAnalyticsHost(host: unknown): boolean {\n const value = toSafeString(host, 300)?.toLowerCase();\n if (!value)\n return false;\n if (value === '::1' || value.startsWith('[::1]'))\n return true;\n const hostname = value.split(':')[0];\n return hostname === 'localhost' || hostname === '127.0.0.1';\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#provideThreadplaneTelemetry", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "provideThreadplaneTelemetry", + "declarations": [ + { + "path": "libs/telemetry/src/browser/provide.ts", + "symbol": "provideThreadplaneTelemetry", + "syntaxKind": "FunctionDeclaration", + "signature": "export function provideThreadplaneTelemetry(config: ThreadplaneTelemetryConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: THREADPLANE_TELEMETRY_CONFIG, useValue: config },\n ThreadplaneTelemetryService,\n ]);\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#registerDevelopmentRuntimePolicy", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "registerDevelopmentRuntimePolicy", + "declarations": [ + { + "path": "libs/telemetry/src/browser/development/runtime.ts", + "symbol": "registerDevelopmentRuntimePolicy", + "syntaxKind": "FunctionDeclaration", + "signature": "export function registerDevelopmentRuntimePolicy(agent: T, policy: () => boolean): T {\n policies.set(agent, policy);\n return agent;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#setDevelopmentCollectionEnabled", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "setDevelopmentCollectionEnabled", + "declarations": [ + { + "path": "libs/telemetry/src/browser/development/runtime.ts", + "symbol": "setDevelopmentCollectionEnabled", + "syntaxKind": "FunctionDeclaration", + "signature": "export function setDevelopmentCollectionEnabled(value: boolean): void {\n enabled = value === true;\n if (!enabled)\n collector?.clear();\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#shouldCaptureAnalytics", + "kind": "export", + "path": "libs/telemetry/src/browser/public-api.ts", + "symbol": "shouldCaptureAnalytics", + "declarations": [ + { + "path": "libs/telemetry/src/browser/properties.ts", + "symbol": "shouldCaptureAnalytics", + "syntaxKind": "FunctionDeclaration", + "signature": "export function shouldCaptureAnalytics({ token, captureLocal = false, host }: CaptureConfig): boolean {\n if (!toSafeString(token, 500))\n return false;\n if (isLocalAnalyticsHost(host) && !captureLocal)\n return false;\n return true;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/index.ts#ThreadplaneBrowserEvent", + "kind": "export", + "path": "libs/telemetry/src/index.ts", + "symbol": "ThreadplaneBrowserEvent", + "declarations": [ + { + "path": "libs/telemetry/src/shared/events.ts", + "symbol": "ThreadplaneBrowserEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ThreadplaneBrowserEvent = 'tplane:browser_provided' | 'tplane:browser_chat_init';" + } + ] + }, + { + "id": "export:libs/telemetry/src/index.ts#ThreadplaneEvent", + "kind": "export", + "path": "libs/telemetry/src/index.ts", + "symbol": "ThreadplaneEvent", + "declarations": [ + { + "path": "libs/telemetry/src/shared/events.ts", + "symbol": "ThreadplaneEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ThreadplaneEvent = ThreadplaneNodeEvent | ThreadplaneBrowserEvent;" + } + ] + }, + { + "id": "export:libs/telemetry/src/index.ts#ThreadplaneNodeEvent", + "kind": "export", + "path": "libs/telemetry/src/index.ts", + "symbol": "ThreadplaneNodeEvent", + "declarations": [ + { + "path": "libs/telemetry/src/shared/events.ts", + "symbol": "ThreadplaneNodeEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ThreadplaneNodeEvent = 'tplane:runtime_instance_created' | 'tplane:runtime_request_created' | 'tplane:stream_started' | 'tplane:stream_ended' | 'tplane:stream_errored';" + } + ] + }, + { + "id": "export:libs/telemetry/src/index.ts#getAnonId", + "kind": "export", + "path": "libs/telemetry/src/index.ts", + "symbol": "getAnonId", + "declarations": [ + { + "path": "libs/telemetry/src/shared/anon-id.ts", + "symbol": "getAnonId", + "syntaxKind": "FunctionDeclaration", + "signature": "export function getAnonId(): string {\n if (!cached)\n cached = `anon_${randomUUID()}`;\n return cached;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/index.ts#getDisableReason", + "kind": "export", + "path": "libs/telemetry/src/index.ts", + "symbol": "getDisableReason", + "declarations": [ + { + "path": "libs/telemetry/src/shared/env.ts", + "symbol": "getDisableReason", + "syntaxKind": "FunctionDeclaration", + "signature": "export function getDisableReason(env: NodeJS.ProcessEnv = process.env): DisableReason {\n if (truthy(env.DO_NOT_TRACK) || truthy(env.npm_config_do_not_track) || truthy(env.NPM_CONFIG_DO_NOT_TRACK)) {\n return 'DO_NOT_TRACK';\n }\n if (truthy(env.TPLANE_TELEMETRY_DISABLED))\n return 'TPLANE_TELEMETRY_DISABLED';\n if (truthy(env.CI) ||\n truthy(env.GITHUB_ACTIONS) ||\n truthy(env.CONTINUOUS_INTEGRATION) ||\n truthy(env.BUILDKITE) ||\n truthy(env.CIRCLECI)) {\n return 'CI';\n }\n return null;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/index.ts#isTelemetryDisabled", + "kind": "export", + "path": "libs/telemetry/src/index.ts", + "symbol": "isTelemetryDisabled", + "declarations": [ + { + "path": "libs/telemetry/src/shared/env.ts", + "symbol": "isTelemetryDisabled", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isTelemetryDisabled(env: NodeJS.ProcessEnv = process.env): boolean {\n return getDisableReason(env) !== null;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/index.ts#sha256", + "kind": "export", + "path": "libs/telemetry/src/index.ts", + "symbol": "sha256", + "declarations": [ + { + "path": "libs/telemetry/src/shared/hash.ts", + "symbol": "sha256", + "syntaxKind": "FunctionDeclaration", + "signature": "export async function sha256(input: string): Promise {\n const data = new TextEncoder().encode(input);\n const buf = await crypto.subtle.digest('SHA-256', data);\n return Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/index.ts#shouldSample", + "kind": "export", + "path": "libs/telemetry/src/index.ts", + "symbol": "shouldSample", + "declarations": [ + { + "path": "libs/telemetry/src/shared/sample.ts", + "symbol": "shouldSample", + "syntaxKind": "FunctionDeclaration", + "signature": "export function shouldSample(rate: number, anonId: string): boolean {\n if (rate <= 0)\n return false;\n if (rate >= 1)\n return true;\n return hashString(anonId) / 0xffffffff < rate;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#CaptureResult", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "CaptureResult", + "declarations": [ + { + "path": "libs/telemetry/src/node/client.ts", + "symbol": "CaptureResult", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type CaptureResult = {\n sent: true;\n} | {\n sent: false;\n reason: 'disabled' | 'sampled' | 'failed' | 'invalid';\n};" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#RuntimeInstanceTelemetry", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "RuntimeInstanceTelemetry", + "declarations": [ + { + "path": "libs/telemetry/src/node/adapter.ts", + "symbol": "RuntimeInstanceTelemetry", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RuntimeInstanceTelemetry {\n transport: string;\n provider?: string;\n model?: string;\n angularVersion?: string;\n apiKey?: string;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#RuntimeRequestTelemetry", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "RuntimeRequestTelemetry", + "declarations": [ + { + "path": "libs/telemetry/src/node/adapter.ts", + "symbol": "RuntimeRequestTelemetry", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface RuntimeRequestTelemetry {\n transport: string;\n requestType: string;\n provider?: string;\n model?: string;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#StreamTelemetry", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "StreamTelemetry", + "declarations": [ + { + "path": "libs/telemetry/src/node/adapter.ts", + "symbol": "StreamTelemetry", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface StreamTelemetry {\n transport?: string;\n provider: string;\n model: string;\n durationMs?: number;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureEvent", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "captureEvent", + "declarations": [ + { + "path": "libs/telemetry/src/node/client.ts", + "symbol": "captureEvent", + "syntaxKind": "FunctionDeclaration", + "signature": "export async function captureEvent(event: ThreadplaneNodeEvent, properties: Record = {}): Promise {\n if (isTelemetryDisabled() || isProgrammaticallyDisabled())\n return { sent: false, reason: 'disabled' };\n const parsed = parseTelemetryEvent(event, properties);\n if (!parsed || parsed.event.startsWith('tplane:browser_'))\n return { sent: false, reason: 'invalid' };\n const rate = getSampleRate();\n const anonId = getAnonId();\n if (!shouldSample(rate, anonId))\n return { sent: false, reason: 'sampled' };\n const payload = parseTelemetryEvent(parsed.event, {\n ...parsed.properties,\n sample_weight: rate > 0 ? 1 / Math.min(1, rate) : 1,\n });\n if (!payload)\n return { sent: false, reason: 'invalid' };\n try {\n await postJson(process.env.TPLANE_TELEMETRY_INGEST_URL ?? DEFAULT_INGEST, {\n key: PUBLIC_INGEST_KEY,\n distinctId: anonId,\n event: payload.event,\n properties: payload.properties,\n });\n return { sent: true };\n }\n catch {\n return { sent: false, reason: 'failed' };\n }\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureRuntimeInstanceCreated", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "captureRuntimeInstanceCreated", + "declarations": [ + { + "path": "libs/telemetry/src/node/adapter.ts", + "symbol": "captureRuntimeInstanceCreated", + "syntaxKind": "FunctionDeclaration", + "signature": "export async function captureRuntimeInstanceCreated(input: RuntimeInstanceTelemetry): Promise {\n await safe(async () => {\n const { apiKey, ...rest } = input;\n void apiKey;\n await captureEvent('tplane:runtime_instance_created', { ...rest });\n });\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureRuntimeRequestCreated", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "captureRuntimeRequestCreated", + "declarations": [ + { + "path": "libs/telemetry/src/node/adapter.ts", + "symbol": "captureRuntimeRequestCreated", + "syntaxKind": "FunctionDeclaration", + "signature": "export async function captureRuntimeRequestCreated(input: RuntimeRequestTelemetry): Promise {\n await safe(() => captureEvent('tplane:runtime_request_created', { ...input }));\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureStreamEnded", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "captureStreamEnded", + "declarations": [ + { + "path": "libs/telemetry/src/node/adapter.ts", + "symbol": "captureStreamEnded", + "syntaxKind": "FunctionDeclaration", + "signature": "export async function captureStreamEnded(input: StreamTelemetry): Promise {\n await safe(async () => {\n const properties = streamProperties(input);\n if (properties)\n await captureEvent('tplane:stream_ended', properties);\n });\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureStreamErrored", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "captureStreamErrored", + "declarations": [ + { + "path": "libs/telemetry/src/node/adapter.ts", + "symbol": "captureStreamErrored", + "syntaxKind": "FunctionDeclaration", + "signature": "export async function captureStreamErrored(input: StreamTelemetry & {\n error: Error | unknown;\n}): Promise {\n await safe(async () => {\n const properties = streamProperties(input);\n if (!properties)\n return;\n const { error, ...rest } = input;\n const errorClass = error instanceof Error ? error.constructor.name : 'Unknown';\n await captureEvent('tplane:stream_errored', { ...rest, transport: properties['transport'], errorClass });\n });\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureStreamStarted", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "captureStreamStarted", + "declarations": [ + { + "path": "libs/telemetry/src/node/adapter.ts", + "symbol": "captureStreamStarted", + "syntaxKind": "FunctionDeclaration", + "signature": "export async function captureStreamStarted(input: StreamTelemetry): Promise {\n await safe(async () => {\n const properties = streamProperties(input);\n if (properties)\n await captureEvent('tplane:stream_started', properties);\n });\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/node/index.ts#disableTelemetry", + "kind": "export", + "path": "libs/telemetry/src/node/index.ts", + "symbol": "disableTelemetry", + "declarations": [ + { + "path": "libs/telemetry/src/node/disable.ts", + "symbol": "disableTelemetry", + "syntaxKind": "FunctionDeclaration", + "signature": "export function disableTelemetry(): void {\n disabled = true;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#PERSONAL_EMAIL_DOMAINS", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "PERSONAL_EMAIL_DOMAINS", + "declarations": [ + { + "path": "libs/telemetry/src/shared/personal-email-domains.ts", + "symbol": "PERSONAL_EMAIL_DOMAINS", + "syntaxKind": "VariableDeclaration", + "signature": "PERSONAL_EMAIL_DOMAINS: ReadonlySet = new Set([\n 'gmail.com',\n 'yahoo.com',\n 'hotmail.com',\n 'outlook.com',\n 'live.com',\n 'icloud.com',\n 'me.com',\n 'mac.com',\n 'proton.me',\n 'protonmail.com',\n 'aol.com',\n 'gmx.com',\n 'mail.com',\n 'yandex.com',\n 'fastmail.com',\n 'msn.com',\n 'qq.com',\n '163.com',\n '126.com',\n])" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#ParsedTelemetryEvent", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "ParsedTelemetryEvent", + "declarations": [ + { + "path": "libs/telemetry/src/shared/ingest.ts", + "symbol": "ParsedTelemetryEvent", + "syntaxKind": "InterfaceDeclaration", + "signature": "export interface ParsedTelemetryEvent {\n event: ThreadplaneEvent;\n properties: Record;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#ThreadplaneBrowserEvent", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "ThreadplaneBrowserEvent", + "declarations": [ + { + "path": "libs/telemetry/src/shared/events.ts", + "symbol": "ThreadplaneBrowserEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ThreadplaneBrowserEvent = 'tplane:browser_provided' | 'tplane:browser_chat_init';" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#ThreadplaneEvent", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "ThreadplaneEvent", + "declarations": [ + { + "path": "libs/telemetry/src/shared/events.ts", + "symbol": "ThreadplaneEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ThreadplaneEvent = ThreadplaneNodeEvent | ThreadplaneBrowserEvent;" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#ThreadplaneNodeEvent", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "ThreadplaneNodeEvent", + "declarations": [ + { + "path": "libs/telemetry/src/shared/events.ts", + "symbol": "ThreadplaneNodeEvent", + "syntaxKind": "TypeAliasDeclaration", + "signature": "export type ThreadplaneNodeEvent = 'tplane:runtime_instance_created' | 'tplane:runtime_request_created' | 'tplane:stream_started' | 'tplane:stream_ended' | 'tplane:stream_errored';" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#getEmailDomain", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "getEmailDomain", + "declarations": [ + { + "path": "libs/telemetry/src/shared/properties.ts", + "symbol": "getEmailDomain", + "syntaxKind": "FunctionDeclaration", + "signature": "export function getEmailDomain(email: unknown): string | null {\n const value = toSafeAnalyticsString(email, 320);\n if (!value)\n return null;\n const atIndex = value.lastIndexOf('@');\n if (atIndex <= 0 || atIndex === value.length - 1)\n return null;\n const domain = value.slice(atIndex + 1).toLowerCase();\n return domain.includes('.') ? domain : null;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#getSourcePage", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "getSourcePage", + "declarations": [ + { + "path": "libs/telemetry/src/shared/properties.ts", + "symbol": "getSourcePage", + "syntaxKind": "FunctionDeclaration", + "signature": "export function getSourcePage(value: unknown): string {\n const source = toSafeAnalyticsString(value, 2000);\n if (!source)\n return '/';\n if (source.startsWith('/'))\n return source;\n try {\n const url = new URL(source);\n return `${url.pathname}${url.search}${url.hash}` || '/';\n }\n catch {\n return '/';\n }\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#isPersonalEmailDomain", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "isPersonalEmailDomain", + "declarations": [ + { + "path": "libs/telemetry/src/shared/personal-email-domains.ts", + "symbol": "isPersonalEmailDomain", + "syntaxKind": "FunctionDeclaration", + "signature": "export function isPersonalEmailDomain(domain: string | null | undefined): boolean {\n if (!domain)\n return false;\n return PERSONAL_EMAIL_DOMAINS.has(domain.toLowerCase());\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#normalizePostHogHost", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "normalizePostHogHost", + "declarations": [ + { + "path": "libs/telemetry/src/shared/properties.ts", + "symbol": "normalizePostHogHost", + "syntaxKind": "FunctionDeclaration", + "signature": "export function normalizePostHogHost(host: unknown): string {\n const value = toSafeAnalyticsString(host, 500);\n if (!value)\n return DEFAULT_POSTHOG_HOST;\n return value.endsWith('/') ? value.slice(0, -1) : value;\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#parseTelemetryEvent", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "parseTelemetryEvent", + "declarations": [ + { + "path": "libs/telemetry/src/shared/ingest.ts", + "symbol": "parseTelemetryEvent", + "syntaxKind": "FunctionDeclaration", + "signature": "export function parseTelemetryEvent(event: unknown, properties: unknown): ParsedTelemetryEvent | null {\n try {\n if (typeof event !== 'string' || !EVENTS.has(event))\n return null;\n if (properties === null || typeof properties !== 'object' || Array.isArray(properties))\n return null;\n const prototype = Object.getPrototypeOf(properties);\n if (prototype !== Object.prototype && prototype !== null)\n return null;\n const result: Record = {};\n for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(properties))) {\n if (!STRING_PROPERTIES.has(key) && key !== 'durationMs' && key !== 'sample_weight')\n continue;\n if (!('value' in descriptor))\n return null;\n const value: unknown = descriptor.value;\n if (value === undefined)\n continue;\n if (STRING_PROPERTIES.has(key)) {\n if (typeof value !== 'string' || /[\\u0000-\\u001f\\u007f]/u.test(value))\n return null;\n const label = value.trim();\n if (!label || label.length > 128)\n return null;\n result[key] = label;\n }\n else {\n if (typeof value !== 'number' || !Number.isFinite(value))\n return null;\n if (key === 'durationMs' && (value < 0 || value > 86400000))\n return null;\n if (key === 'sample_weight' && value < 1)\n return null;\n result[key] = value;\n }\n }\n if (event === 'tplane:browser_chat_init' && !result['surface'])\n return null;\n if (event !== 'tplane:browser_provided' && event !== 'tplane:browser_chat_init' && !result['transport'])\n return null;\n return { event: event as ThreadplaneEvent, properties: result };\n }\n catch {\n return null;\n }\n}" + } + ] + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#toSafeAnalyticsString", + "kind": "export", + "path": "libs/telemetry/src/shared/public-api.ts", + "symbol": "toSafeAnalyticsString", + "declarations": [ + { + "path": "libs/telemetry/src/shared/properties.ts", + "symbol": "toSafeAnalyticsString", + "syntaxKind": "FunctionDeclaration", + "signature": "export function toSafeAnalyticsString(value: unknown, maxLength = 200): string | undefined {\n if (typeof value !== 'string')\n return undefined;\n const trimmed = value.trim();\n if (!trimmed)\n return undefined;\n return trimmed.slice(0, maxLength);\n}" + } + ] + }, + { + "id": "source:libs/a2ui/src/index.ts", + "kind": "source", + "path": "libs/a2ui/src/index.ts", + "sha256": "ca445536bb370bf660e0867b5533e174200056a68701d2f1a5c6f9541259376a" + }, + { + "id": "source:libs/a2ui/src/lib/functions.ts", + "kind": "source", + "path": "libs/a2ui/src/lib/functions.ts", + "sha256": "e3c22d6f7eb536fbb2b20029d0633ca0bddcf37d49f1bb065e246e26f7907ab5" + }, + { + "id": "source:libs/a2ui/src/lib/guards.ts", + "kind": "source", + "path": "libs/a2ui/src/lib/guards.ts", + "sha256": "bd1dea3e1e1344d1956deb5bbbf47071a512b02658bbf815d1a2f9cd251a0d42" + }, + { + "id": "source:libs/a2ui/src/lib/parser.ts", + "kind": "source", + "path": "libs/a2ui/src/lib/parser.ts", + "sha256": "a1337f1962bc41df5995394e36f791bb2f0643198a6f1afa31747bb0ab926df1" + }, + { + "id": "source:libs/a2ui/src/lib/pointer.ts", + "kind": "source", + "path": "libs/a2ui/src/lib/pointer.ts", + "sha256": "c13c100e771fbef0b10359001349fd253801ddc90be28bd47393d6e8b2970d69" + }, + { + "id": "source:libs/a2ui/src/lib/resolve.ts", + "kind": "source", + "path": "libs/a2ui/src/lib/resolve.ts", + "sha256": "97624a6d9e842d53eb1bcc2cb0f5fff2697401e3bca6942b487a373652cdaeb7" + }, + { + "id": "source:libs/a2ui/src/lib/types.ts", + "kind": "source", + "path": "libs/a2ui/src/lib/types.ts", + "sha256": "273fff2b2d039d01be82777728985c5eb13e0ada8908d46544bf788ff5bc701c" + }, + { + "id": "source:libs/a2ui/vite.config.mts", + "kind": "source", + "path": "libs/a2ui/vite.config.mts", + "sha256": "27b9a06834f763f31ee56c0746f6be8115cb921f530442336569f4d5e7403933" + }, + { + "id": "source:libs/ag-ui/.install-collector/development-install.d.ts", + "kind": "source", + "path": "libs/ag-ui/.install-collector/development-install.d.ts", + "sha256": "bb95a098f92383f2d131eb1b9ff9d9e7d0ee7304a8debc188c033017a14284ce" + }, + { + "id": "source:libs/ag-ui/.install-collector/development-install.mjs", + "kind": "source", + "path": "libs/ag-ui/.install-collector/development-install.mjs", + "sha256": "a69938ff45c56be138849066563917e17169fc7e0d9143e95801af40f472cbe4" + }, + { + "id": "source:libs/ag-ui/eslint.config.mjs", + "kind": "source", + "path": "libs/ag-ui/eslint.config.mjs", + "sha256": "677c24253f9bbf0a4357c73c41f9e124b8db772e2f049ed9171e98ee73cb083c" + }, + { + "id": "source:libs/ag-ui/install/postinstall.cjs", + "kind": "source", + "path": "libs/ag-ui/install/postinstall.cjs", + "sha256": "5624c16b6e7dc1c61bc4b9233de01ba6d13e1baa78f06a9977b652a59d67a5a2" + }, + { + "id": "source:libs/ag-ui/src/lib/bridge-citations-state.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/bridge-citations-state.ts", + "sha256": "aaa6f76e35a2e3e4adc77efcef453c98ea07dbdf6a5251d4ff431a495e96fd92" + }, + { + "id": "source:libs/ag-ui/src/lib/client-tools.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/client-tools.ts", + "sha256": "63f22ef3f3e1f1dee57cb6adf13135f4a7fc7219bb0858935a993499402e012f" + }, + { + "id": "source:libs/ag-ui/src/lib/internal/apply-patch.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/internal/apply-patch.ts", + "sha256": "6a348d876814bc7f1ec10c698bcbca11eb5e224866f0df55546f4e3481d2af1f" + }, + { + "id": "source:libs/ag-ui/src/lib/interrupt-persistence.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/interrupt-persistence.ts", + "sha256": "48c3015c1ea225ae7a9557eb95cfaafb8be86605fff71eac0ee6560dfd74d9ea" + }, + { + "id": "source:libs/ag-ui/src/lib/interrupt-session.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/interrupt-session.ts", + "sha256": "88fa95647734a0eb2dd3bc326728e7d4ba7fe29199d7add2ba6603694ea3b3ce" + }, + { + "id": "source:libs/ag-ui/src/lib/interrupt-session.types.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/interrupt-session.types.ts", + "sha256": "3caca0e4cba89109efab869567b1a0f1a520d051ef0b53101cd924e266ea4ba4" + }, + { + "id": "source:libs/ag-ui/src/lib/package-version.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/package-version.ts", + "sha256": "653f7da57624a0da7e7d8dec8cf7590de7217ab5f9f98aa0f16b3546088fb3ac" + }, + { + "id": "source:libs/ag-ui/src/lib/provide-agent.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/provide-agent.ts", + "sha256": "551da65caa6df29c8f1904ef69bd2ee3f52ddca80152fc95650093c7c39106e3" + }, + { + "id": "source:libs/ag-ui/src/lib/reducer.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/reducer.ts", + "sha256": "82ed040383d718c9460b4d8040a942a0b5f969f3060c2522cfb4adfd23686379" + }, + { + "id": "source:libs/ag-ui/src/lib/run-state-transaction.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/run-state-transaction.ts", + "sha256": "5a7ea0e9c6dd6e278428fdc4905cb3f6dc22094d7d19044b9022a1b1c5f3c82d" + }, + { + "id": "source:libs/ag-ui/src/lib/runtime-operation-reporter.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/runtime-operation-reporter.ts", + "sha256": "79faeeb59dc446de394828a0101e79c6d4af328dfec16307158e379a0ee343c8" + }, + { + "id": "source:libs/ag-ui/src/lib/testing/fake-agent.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/testing/fake-agent.ts", + "sha256": "907be3269a540a07447833a119c4bac60672900db6b6ee5d0a96037df2f9ba1c" + }, + { + "id": "source:libs/ag-ui/src/lib/testing/provide-fake-agent.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/testing/provide-fake-agent.ts", + "sha256": "0e44dd51a422c266b45e86866b4bbc6a6a5deb1a675c149587c5612cfa3a672a" + }, + { + "id": "source:libs/ag-ui/src/lib/to-agent.ts", + "kind": "source", + "path": "libs/ag-ui/src/lib/to-agent.ts", + "sha256": "9c8a34f9ee960311ba26a281bb4726d0436129767ddf7d68f6404ecd037f5bb9" + }, + { + "id": "source:libs/ag-ui/src/public-api.ts", + "kind": "source", + "path": "libs/ag-ui/src/public-api.ts", + "sha256": "3a6e03c590c4ed74eca832b04c206b8efa6544232618a8f573981e26ed8ee180" + }, + { + "id": "source:libs/ag-ui/src/test-setup.ts", + "kind": "source", + "path": "libs/ag-ui/src/test-setup.ts", + "sha256": "8875a42d0fef8f38aa0ac638ef1905fea20a65e9df944514356e959aebad9c1d" + }, + { + "id": "source:libs/ag-ui/src/testing/type-assert.ts", + "kind": "source", + "path": "libs/ag-ui/src/testing/type-assert.ts", + "sha256": "b53bbee7967e7079ecb3143325ef154f13656243555c0dbc89cce0a86a73ea2e" + }, + { + "id": "source:libs/ag-ui/vite.config.mts", + "kind": "source", + "path": "libs/ag-ui/vite.config.mts", + "sha256": "3c93dbe6de30075f257d09a992fa84ee272078a8dea4520ad7e40afc4be72624" + }, + { + "id": "source:libs/chat/.install-collector/development-install.d.ts", + "kind": "source", + "path": "libs/chat/.install-collector/development-install.d.ts", + "sha256": "bb95a098f92383f2d131eb1b9ff9d9e7d0ee7304a8debc188c033017a14284ce" + }, + { + "id": "source:libs/chat/.install-collector/development-install.mjs", + "kind": "source", + "path": "libs/chat/.install-collector/development-install.mjs", + "sha256": "a69938ff45c56be138849066563917e17169fc7e0d9143e95801af40f472cbe4" + }, + { + "id": "source:libs/chat/debug/public-api.ts", + "kind": "source", + "path": "libs/chat/debug/public-api.ts", + "sha256": "eaf7798b8a04266196b538cd9c767f8a7b31a1bb9a13a40e346577a0ec9c7968" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/chat-debug-root-styles.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/chat-debug-root-styles.ts", + "sha256": "3a0446b4952d42ec66331694b8ea320a026a20b1c68abf4ea0aeced7712e8eeb" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/chat-debug-tokens.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/chat-debug-tokens.ts", + "sha256": "53a03f1dda73726b7b44cfd67d2c0e38a3a289dd46e2b771701ce9815b3ce97c" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/chat-debug.component.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/chat-debug.component.ts", + "sha256": "3e36ac4875871589e757c60faabe3931dafa9de582f7bba5ae030a007e2d4462" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/debug-agent.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/debug-agent.ts", + "sha256": "e66b705d2ae779976bf1d3d4cce0038d104853cf941e9f49fcb4e44e55b36986" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/debug-checkpoint-card.component.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/debug-checkpoint-card.component.ts", + "sha256": "14366bf3ff2094df1a07a608bccd6c7746b3bdd36d4958c7d5b032d068a2d5c0" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/debug-state-diff.component.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/debug-state-diff.component.ts", + "sha256": "cf0feaa728e649ad79923ef6a9cbce48f4ec274ccecbba6ab60878e82badc2ab" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/debug-state-inspector.component.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/debug-state-inspector.component.ts", + "sha256": "7c34b09d4403665a13a083182aa9e1a2faf3e282746db9146d6bbcc608824261" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/debug-utils.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/debug-utils.ts", + "sha256": "d4a80b16bc5afb2f0796ed56c971ed7eeca06169c1a9e39eacff89c21b953c53" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/inspectors/state-inspector.component.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/inspectors/state-inspector.component.ts", + "sha256": "aff5d50889ff217c705c7049c491e0ddc57b7146f7e8b22db094ed484da80d22" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/inspectors/timeline-inspector.component.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/inspectors/timeline-inspector.component.ts", + "sha256": "59da03a65863eb684031cd9f602a8f4433152845d657e92c15e4a675b3d06bc9" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/persistence.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/persistence.ts", + "sha256": "8f4cdb110bd4dfb0db71b3b5cbd69352c656f665bc54a60857948044ebe04daf" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/state-diff.ts", + "kind": "source", + "path": "libs/chat/debug/src/lib/compositions/chat-debug/state-diff.ts", + "sha256": "3163e58c79c8752013463f5d5246b58efccee2ccb764ea3ce5e5836939241fdf" + }, + { + "id": "source:libs/chat/eslint.config.mjs", + "kind": "source", + "path": "libs/chat/eslint.config.mjs", + "sha256": "7184c5abb14bb875fab1a3e4cf71c36e5356567efe0d5fc14df7895e943bea6b" + }, + { + "id": "source:libs/chat/install/postinstall.cjs", + "kind": "source", + "path": "libs/chat/install/postinstall.cjs", + "sha256": "5624c16b6e7dc1c61bc4b9233de01ba6d13e1baa78f06a9977b652a59d67a5a2" + }, + { + "id": "source:libs/chat/src/index.ts", + "kind": "source", + "path": "libs/chat/src/index.ts", + "sha256": "78b656b2773792ff12105b63a8d1d143ec3ef929878bfa09054b7ba4d477d5b1" + }, + { + "id": "source:libs/chat/src/lib/a2ui/a2ui-default-fallback.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/a2ui-default-fallback.component.ts", + "sha256": "1a0401ef3fa4fbc538d762972304574a8d6a3a58adedc3d5207ac535ed53200f" + }, + { + "id": "source:libs/chat/src/lib/a2ui/action-label.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/action-label.ts", + "sha256": "cc00c73f189a9929e5a34fb7ae76352a2f41710a62032707e04b5fd82bc94442" + }, + { + "id": "source:libs/chat/src/lib/a2ui/build-action-message.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/build-action-message.ts", + "sha256": "f0db3b7d1491256f85be9598467e18ee57c7c3a14be15b73c0af27ba686b329b" + }, + { + "id": "source:libs/chat/src/lib/a2ui/capabilities.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/capabilities.ts", + "sha256": "ff00296f7b17f08f3b820834b8c5b6f35a86cafbd690635cb3a472bd9ff87cef" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/audio-player.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/audio-player.component.ts", + "sha256": "18dcab405b2a742bc837f238c3a8907b5fd33c1abdc466e0bc00f5c152b224bc" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/button.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/button.component.ts", + "sha256": "744b9f881dfeb8954ac084ec7f2b9779658971c798d49016fd1e6c174b23a58c" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/card.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/card.component.ts", + "sha256": "31d86519175a1da778e605cf900c281a976bac68c1e556bac7f4dd1e7ab5fb12" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/check-box.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/check-box.component.ts", + "sha256": "4551d1d3e8c8a9464a2386d43ecb58074bf35739f3c5f97e59ba71fdaddccae2" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/choice-picker.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/choice-picker.component.ts", + "sha256": "8ea38473bf854bb6ea57a8b12e907b282d9f4fdc44c8083deca42199c7ae2a79" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/column.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/column.component.ts", + "sha256": "3bd111d39c23a1c53d610903fbe806af2770b5c94a2687c4bb333af6dd77966c" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/date-time-input.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/date-time-input.component.ts", + "sha256": "f84a8e05874b1db37db3d8600ec7159ed4ae9e47acd01bdbd1ea7c2d658b9e4d" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/divider.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/divider.component.ts", + "sha256": "be7982a61efe71cb6aaa53f6d8c06f478c2d8409d581c99b0839c7f264c1811d" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/emit-binding.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/emit-binding.ts", + "sha256": "17ef0c28cc3b5840fca08c972f367b85ba2087ca4dd0a1ebd6751a30a8ef6cdf" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/icon.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/icon.component.ts", + "sha256": "5ea2616bb716c9f9d710105a90590de64822b5c7842bef8ae9b971834168ae0d" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/image.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/image.component.ts", + "sha256": "2ee05379e1cf5f7efd882c5c6e41edb6177eb5336511dc2cf584b7fc8fded029" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/index.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/index.ts", + "sha256": "f5a721d3b033c12384515e63dbac8bc5370342b71563ae4d8bbc6895edbfd46e" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/list.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/list.component.ts", + "sha256": "0fc40bb54d08821d2d954354b706ed136813932be4e54653e32fe1f13f2f4515" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/modal.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/modal.component.ts", + "sha256": "9bce1f87a182111468caa3a66281f7e5c5be7ee21ccf4d4ec9b9ebff5cb27854" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/row.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/row.component.ts", + "sha256": "3e5cc7af2987bcfa505ed8eefc72810b3c7d8e1b4a41a66b7203062050f6ebc2" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/slider.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/slider.component.ts", + "sha256": "c2e44823ac013495400d5afd665d490561cc72bd632b35fd124055e335a1420c" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/tabs.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/tabs.component.ts", + "sha256": "b590b2eb69ebf96cc72822fe2e3c6a584bc76b009711b6d985d48092ce05be0c" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/text-field.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/text-field.component.ts", + "sha256": "cde5f0e7065aa7ff68bc7cd4ae7c0b2c96b8499bd8b579c3feb67713f754f26e" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/text.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/text.component.ts", + "sha256": "0320e1dd0675f4759fc5596b341f809111eab7f5aa9acafc8beeb9f66b304ac8" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/video.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/catalog/video.component.ts", + "sha256": "87b682d18844471a193c59993c82f0c8ee986de6bf59615e878e306679b90fbe" + }, + { + "id": "source:libs/chat/src/lib/a2ui/component-view.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/component-view.ts", + "sha256": "c775b5424b95b63d3a042b7af7b22cb3d3a01184ecbaa07a176a98af216514fe" + }, + { + "id": "source:libs/chat/src/lib/a2ui/envelope-normalizer.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/envelope-normalizer.ts", + "sha256": "8e2ff8724bddc35c3570dad8e055890e53d7f03445dace81a4ce3ff7db55a739" + }, + { + "id": "source:libs/chat/src/lib/a2ui/extract-bindings.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/extract-bindings.ts", + "sha256": "648c52bb3ea86227e7db2b93a48e665bd366ae84a796bed051e1ce48409c5999" + }, + { + "id": "source:libs/chat/src/lib/a2ui/partial-args-bridge.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/partial-args-bridge.ts", + "sha256": "b85580929640c3b84c58a1e362abf7e673ad7db6d987dcc0fe37406934676e55" + }, + { + "id": "source:libs/chat/src/lib/a2ui/surface-store.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/surface-store.ts", + "sha256": "928c6b58f35da8e073b9bbfb58cd4f5b778efc40f47bb2b352d1735385464906" + }, + { + "id": "source:libs/chat/src/lib/a2ui/surface-to-spec.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/surface-to-spec.ts", + "sha256": "37d0d01737e92546894701609f0bf1dedaaccc1505caf0e6a1cbb886491b3a02" + }, + { + "id": "source:libs/chat/src/lib/a2ui/surface.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/surface.component.ts", + "sha256": "2cdce37a14a7872375b69159d698f45ddeaf35d64a798269336f5d4900dd3889" + }, + { + "id": "source:libs/chat/src/lib/a2ui/views.ts", + "kind": "source", + "path": "libs/chat/src/lib/a2ui/views.ts", + "sha256": "7cfd168800aac48dedeeb96b19cd42225abc886918974827afcc54c2bf89760f" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-checkpoint.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/agent-checkpoint.ts", + "sha256": "b56f19e0c73c4b111763eb8e1c036d20b0e22188e46f7a9da137ff2ff69edc62" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-error.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/agent-error.ts", + "sha256": "b7cfebca8f3da50b7e8951103b0ae7e7e62c2cbcc38519cbaa5ce24f5b82f6ee" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-event.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/agent-event.ts", + "sha256": "a27590df421e8bdcd1165e9dd8f90293d7c42744e43f1feaa10fe78694f7a3e8" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-interrupt.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/agent-interrupt.ts", + "sha256": "faea0bfa5b12dc8a130906bf2b38d46a587bd1208df9868b00dbf1db6758a36f" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-ref.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/agent-ref.ts", + "sha256": "be52ee779f803663c66044d06ffed6c435ebfdb7dd883334337ba8feef8bdc28" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-status.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/agent-status.ts", + "sha256": "91edecd24cd25304b2d979ba5074e9380de2fb5b95abda31b986b8533f8da860" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-submit.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/agent-submit.ts", + "sha256": "09dcc2b445c1d1951092dc43389ca23cdcc2b5526e6ac5f658b2aba072dfe14a" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-with-history.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/agent-with-history.ts", + "sha256": "74fcd11367574d13511c5b8c0262f2cbe22cd2362cf2b2fae824966cef44b165" + }, + { + "id": "source:libs/chat/src/lib/agent/agent.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/agent.ts", + "sha256": "6ee134c17e2395f04aa94a05b7240e113c7236eb1eab7fa0d2a9b0ebbdb3e715" + }, + { + "id": "source:libs/chat/src/lib/agent/citation-display.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/citation-display.ts", + "sha256": "135d4713e80b3874572256014b2e9a37479c290735c0a2cd7b7e667e8789a0e5" + }, + { + "id": "source:libs/chat/src/lib/agent/citation.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/citation.ts", + "sha256": "26411e92b16a73f03e7b07963f839ba13aaa7841abd8783459379416ffe0f1f9" + }, + { + "id": "source:libs/chat/src/lib/agent/content-block.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/content-block.ts", + "sha256": "f6a22cfaa3f53d21fce9df550c51cb77077dbf455d175d7f85d55423ce691cea" + }, + { + "id": "source:libs/chat/src/lib/agent/index.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/index.ts", + "sha256": "d72b383a511a3b722c4603ce49e8cc125e2ffc03158f64e060bee870ccd1101c" + }, + { + "id": "source:libs/chat/src/lib/agent/message-delivery.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/message-delivery.ts", + "sha256": "4cac8a3a6912fc17a5740f4e767b01c1e6df255dbc64d45e4bb8b9aeef0bb842" + }, + { + "id": "source:libs/chat/src/lib/agent/message.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/message.ts", + "sha256": "c8e69f7c36a1daec9ce6207de02857ca784e6b8594b28309e75525de42db8690" + }, + { + "id": "source:libs/chat/src/lib/agent/runtime-telemetry.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/runtime-telemetry.ts", + "sha256": "bacf56a9f015f8dbac932c64f53b3a59b5ba89d0e59f7d1dea0b5e4b77387d5e" + }, + { + "id": "source:libs/chat/src/lib/agent/subagent.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/subagent.ts", + "sha256": "6ea8666e8e4703499ba08ed21c496407609e052589f6ddf2bf38f36e85f0c59a" + }, + { + "id": "source:libs/chat/src/lib/agent/to-agent-error.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/to-agent-error.ts", + "sha256": "a0d282320745b89ca272652a829972c188b8f4f49dfe8dd816c64eef8f365497" + }, + { + "id": "source:libs/chat/src/lib/agent/tool-call.ts", + "kind": "source", + "path": "libs/chat/src/lib/agent/tool-call.ts", + "sha256": "043aa42715145dae39f7594c89aca4fd048f9b31b4acd7330237db40e3d856fc" + }, + { + "id": "source:libs/chat/src/lib/chat.types.ts", + "kind": "source", + "path": "libs/chat/src/lib/chat.types.ts", + "sha256": "8084d47d70b014bcaa65a4609aa07674adf749c8994dd7eef7aae17b779aab5b" + }, + { + "id": "source:libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "sha256": "632ae7711c1a39b32333d10748bb4dfc8bc6cc70875d246eef1fc17959beb74d" + }, + { + "id": "source:libs/chat/src/lib/client-tools/client-tool-executor.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/client-tool-executor.ts", + "sha256": "ce901806c10d32dec258917b6c58a2b9b5356cea4805f36578e7c10a7921138a" + }, + { + "id": "source:libs/chat/src/lib/client-tools/client-tools-capability.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/client-tools-capability.ts", + "sha256": "ecb567572ef86390adb8dfa020d6d069aafe6680b0661ce9d7e7251024bb94fe" + }, + { + "id": "source:libs/chat/src/lib/client-tools/client-tools-coordinator.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/client-tools-coordinator.ts", + "sha256": "4342c630e4c96bc4cf327ae5c1d0abe15e71ea2d7816487a71bc7ce88b44c64e" + }, + { + "id": "source:libs/chat/src/lib/client-tools/component-inputs.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/component-inputs.ts", + "sha256": "8bd579c48c72b77b2d720897f559e1b2eb2742144da8b5223b397d212ddd2c3d" + }, + { + "id": "source:libs/chat/src/lib/client-tools/execute.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/execute.ts", + "sha256": "adc9b18502d6b5346d2969e163ebff2435233935e455b35b1d270906e8ac4ece" + }, + { + "id": "source:libs/chat/src/lib/client-tools/index.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/index.ts", + "sha256": "6f7f0130ce9c6b3d91688a47438a03668e73de47f43edae1c9457db0cbe2dc90" + }, + { + "id": "source:libs/chat/src/lib/client-tools/select-pending-client-tool-calls.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/select-pending-client-tool-calls.ts", + "sha256": "300783e156ff80efbdcd4f3de2f9f67dbeefe5b9ca7a099a24ef83803145224b" + }, + { + "id": "source:libs/chat/src/lib/client-tools/to-json-schema.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/to-json-schema.ts", + "sha256": "0676e0979edc3e9be097e0068aeb51ed70a024603b1a6a22b955ebe5dd9cffc5" + }, + { + "id": "source:libs/chat/src/lib/client-tools/tool-def.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/tool-def.ts", + "sha256": "489b57de11993572b1cb05159ae4a80c83e949052199be463fb7fbcf9f3171b6" + }, + { + "id": "source:libs/chat/src/lib/client-tools/tools.ts", + "kind": "source", + "path": "libs/chat/src/lib/client-tools/tools.ts", + "sha256": "ea5bd15643641039d9e9f11a03f9db4498c8ff315f50c3fbe1e6f249f60df1e3" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-approval-card/chat-approval-card.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat-approval-card/chat-approval-card.component.ts", + "sha256": "f5516651f86c6737f7a0fe8b9463bd4abf8f33e0d20ca5aac957200765442c11" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-interrupt-panel/chat-interrupt-panel.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat-interrupt-panel/chat-interrupt-panel.component.ts", + "sha256": "5bfa108b1b928f364e8b781764a12354a641d70be7d81011077da5527e85ebcc" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-popup/chat-popup.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat-popup/chat-popup.component.ts", + "sha256": "da350aab61a1dca38bd963e3cf55fc6e0a199ce533a27e5068ef26d6ca1c125e" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-sidebar/chat-sidebar.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat-sidebar/chat-sidebar.component.ts", + "sha256": "861ee59feb94e1d8e608f9c76c48657ef060383f6815dcf22d2dcabde8bb984a" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-sidenav/chat-debug-gate.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat-sidenav/chat-debug-gate.ts", + "sha256": "0fa7c3b3ceacb1efd9f954d5aac0661d4a859880512471b4ae819448b9a57b35" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-sidenav/chat-sidenav.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat-sidenav/chat-sidenav.component.ts", + "sha256": "d1cddcf0d2573efc9184b4ab752527171b581d5b29a8d7a17d235363bd950d5d" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-subagent-card/chat-subagent-card.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat-subagent-card/chat-subagent-card.component.ts", + "sha256": "db5261bcf38d94b26520ec9db1e299f664efcee6fb8b1ff9e0e39f9600b1dedf" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-timeline-slider/chat-timeline-slider.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat-timeline-slider/chat-timeline-slider.component.ts", + "sha256": "11474124ad699c6167c984e0412feaec72640ee21ff8f04fcf0407cd32b343f3" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-tool-call-card/chat-tool-call-card.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat-tool-call-card/chat-tool-call-card.component.ts", + "sha256": "47e10bd9dc1247f04e1b97c63856054050cc4cd3a2359708bbee40c7da945ab0" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat/chat-render-event.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat/chat-render-event.ts", + "sha256": "37d6fb1802e1bc7cf9f92e050edaac10c59f22dfc4f77862d50ffba082335b4f" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat/chat.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/chat/chat.component.ts", + "sha256": "2e7bf58c2e6e99b474cf293dbacc9b489d4a98d02b172592ece92c021ff171fd" + }, + { + "id": "source:libs/chat/src/lib/compositions/shared/message-utils.ts", + "kind": "source", + "path": "libs/chat/src/lib/compositions/shared/message-utils.ts", + "sha256": "22bc4113356bfa8ceb3a1a9cfe947fa64257e829f8903fddd7feee8f95aa4bcb" + }, + { + "id": "source:libs/chat/src/lib/internals/prettify.ts", + "kind": "source", + "path": "libs/chat/src/lib/internals/prettify.ts", + "sha256": "15bf145c86978f1bd2d1b70739a8e595b8ab6a6767581f7b549bdec4b1370276" + }, + { + "id": "source:libs/chat/src/lib/lifecycle.ts", + "kind": "source", + "path": "libs/chat/src/lib/lifecycle.ts", + "sha256": "99f50f184a0284cbccb49fc4a2b8e99b08e58cb89b8b612efe291f9852663772" + }, + { + "id": "source:libs/chat/src/lib/markdown/cacheplane-markdown-views.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/cacheplane-markdown-views.ts", + "sha256": "b3bf43c1ad235d99aed5eb512d93a8920aec0382b279fdddd243dc98cd665453" + }, + { + "id": "source:libs/chat/src/lib/markdown/citations-resolver.service.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/citations-resolver.service.ts", + "sha256": "0d75c09c34b75a52d47dd6829a6f09cc23c644e59ee276d6ca67b6801f3b1534" + }, + { + "id": "source:libs/chat/src/lib/markdown/katex-loader.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/katex-loader.ts", + "sha256": "18e6dd2391e50f983221b96c1d704b8b8be2cba97a5edcd95079914fcb5a4285" + }, + { + "id": "source:libs/chat/src/lib/markdown/markdown-children.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/markdown-children.component.ts", + "sha256": "f3c586d167d43bdddb1d71e285e00311f4872f01d655586a846919ca5dccaff1" + }, + { + "id": "source:libs/chat/src/lib/markdown/markdown-table-row.token.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/markdown-table-row.token.ts", + "sha256": "e56f6d78215da3778a657905c52b7e854517c35927e052e37d4d65cbd51199d0" + }, + { + "id": "source:libs/chat/src/lib/markdown/markdown-view-registry.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/markdown-view-registry.ts", + "sha256": "dedb059711c82f1b34db8111647cc6ee059be90eb1d5e54985ad8b1b049ebac4" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-autolink.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-autolink.component.ts", + "sha256": "829d22f9f86292d53a46df8d0e1d66bd9809da6d9bc2637369c949c02f9fd0ce" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-blockquote.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-blockquote.component.ts", + "sha256": "1d00829894a5f9bff151183b93366bab204b289b738f0e98530617c8af947996" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-citation-reference.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-citation-reference.component.ts", + "sha256": "c3eee03bdd271e95b1583ff4754b4f9148e58de8f40209ba651a8746e82c9066" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-code-block.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-code-block.component.ts", + "sha256": "3001c1b351f8deea0418cf57dc77fe51a9b90e637fd1174daebd21358196620f" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-document.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-document.component.ts", + "sha256": "71c9d93d7100b0ff1416958b2a8e72d8fa5a9ef4d00e4a807858b5f1cabf8329" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-emphasis.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-emphasis.component.ts", + "sha256": "edf34c053e2c237ee9307b3777489c024b0751b1880095d03e3247c01cf4db7a" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-hard-break.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-hard-break.component.ts", + "sha256": "5cb1bb507cd5fd6e5c0e508e61fe75306bf6d8c5d92263a8ab482331e36ffa27" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-heading.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-heading.component.ts", + "sha256": "9f01dd0e0de6862d9c9d87c22a397150977eebc38e2b4f3e9833334d115c7916" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-html.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-html.component.ts", + "sha256": "a19d471e614342183bbf1d215be5d96cf7bbd8506f66a93dc57d99274b1ca1c9" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-image.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-image.component.ts", + "sha256": "7524050f0fbd79918cc5bae27a1748535b5b9716735324963c6fd1f9d53086f8" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-inline-code.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-inline-code.component.ts", + "sha256": "d567c665c34ad007ac86841d721766307f95c648ee243ba8c8926a0a7e2cf22b" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-link.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-link.component.ts", + "sha256": "6bc589504006ccfbab4249afc45b634507ad87ac74a05b0ee82011261ffddb84" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-list-item.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-list-item.component.ts", + "sha256": "1210aadca55cd8195fa547180ee87f497964434698d0d60e27b959879b2e7eca" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-list.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-list.component.ts", + "sha256": "82181a765e32b2d692dc6b3e304899c968e18c83e4eb3eebf9388a1f6ade8b3c" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-math.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-math.component.ts", + "sha256": "cf457e841f448659048943ad2818ce257482c38b490edde8fdbc2e6b560fe338" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-paragraph.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-paragraph.component.ts", + "sha256": "75c55797fc3374c7c8abaa06d72480aea8c18a47c9087a8fbaaf19ed637280bf" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-soft-break.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-soft-break.component.ts", + "sha256": "34521a846738dca4941b0a4aa38b50cb163b451856933031a0406521b16ccfb8" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-strikethrough.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-strikethrough.component.ts", + "sha256": "5ff7228bc3986f93fc2f878869510f5dd6d52a8863f351da35f9888f0c63d3aa" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-strong.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-strong.component.ts", + "sha256": "42a03233f7a79b0624696a9091a7819cf08db482ccc99b3bd2224bd5872906a6" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-table-cell.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-table-cell.component.ts", + "sha256": "2ed9a3f5ff92916188b680e3e167b9d4034e351c5103b7fcd29c11a7a83cf6e2" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-table-row.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-table-row.component.ts", + "sha256": "cc39868f2ad8d49b8cf512952781bb8976c0fa81e0cd0204bee7032d3ab83df2" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-table.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-table.component.ts", + "sha256": "b943ac74f410ab10c7dae71b5789813b2738a0b30e725138c20d39b0528b470f" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-text.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-text.component.ts", + "sha256": "c7d54a501e84c95239d5158260a54037a20a3d800b534d1fbf11e2a4707882ef" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-thematic-break.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/markdown/views/markdown-thematic-break.component.ts", + "sha256": "06723de156a72a3ba50d3018a69fe2cbaba8f752e767705eb0b25af9d446963b" + }, + { + "id": "source:libs/chat/src/lib/package-version.ts", + "kind": "source", + "path": "libs/chat/src/lib/package-version.ts", + "sha256": "653f7da57624a0da7e7d8dec8cf7590de7217ab5f9f98aa0f16b3546088fb3ac" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-citations/chat-citation-preview.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citation-preview.component.ts", + "sha256": "46b0ce4c289a59b4b1c80edfc5e004c8b72e319c57c1839fb3b4ad5b48c9ee5d" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-citations/chat-citations-card.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citations-card.component.ts", + "sha256": "5314c45a01889ccae3b24eec77b45357d6d131238d29f45425896bb6cd14a815" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts", + "sha256": "faea19efefb57d2c74e64d12c307d539894dc689fd8ed55ce1bd812ebbe5c417" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-citations/index.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-citations/index.ts", + "sha256": "30e48ec001eb18993fceeb62e2f8f93075f6b0d0f45cc08ce4b07fc44547958c" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-confirm-dialog/chat-confirm-dialog.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-confirm-dialog/chat-confirm-dialog.component.ts", + "sha256": "8a12d8b21c38b4d6b727193f95619b19222c26352eafaa6e8e5bfe93d03e6372" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-error/chat-error.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-error/chat-error.component.ts", + "sha256": "4e1d58dd80539ab38acbb6ef35890d424818f8e5ef994e4e608f658c48d467e8" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-generative-ui/chat-generative-ui.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-generative-ui/chat-generative-ui.component.ts", + "sha256": "2e7986433bfc67a083951bc30bddbc3eb36235269f57a136d77a889167664b8a" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-generative-ui/normalize-json-render-spec.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-generative-ui/normalize-json-render-spec.ts", + "sha256": "462d140784f9459bd2c286e8c2917104db2a81b91c846d7e8477c18a17818e2e" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-genui-skeleton/chat-genui-skeleton.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-genui-skeleton/chat-genui-skeleton.component.ts", + "sha256": "6e986815ada1d4c821c3e2d01ff818b0cc8b72e131bc6f1e8a273a15a48b8e62" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-history-search-palette/chat-history-search-palette.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-history-search-palette/chat-history-search-palette.component.ts", + "sha256": "91ffe66fa15924ccc0d5f19592c63de87141103306787025158f8c1f959cbe4c" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-input/chat-input.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-input/chat-input.component.ts", + "sha256": "fdd92bbf0f243d6abdc0a45686c6648657993e1de4f37ff5c9deb0352019d8b5" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-interrupt/chat-interrupt.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-interrupt/chat-interrupt.component.ts", + "sha256": "069e7aa3f93bf31bf8d9487dd1ab0ab57733f86c8e53fe0a86c4fd41dfb157d7" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-launcher-button/chat-launcher-button.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-launcher-button/chat-launcher-button.component.ts", + "sha256": "b9a109b8f0d09f3528e0bee2d9b37ac4ccf074647acb4f3a6714bd70ff9962ba" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-message-actions/chat-message-actions.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-message-actions/chat-message-actions.component.ts", + "sha256": "d2f11d20ee51082e58012b65e2aee56d8fc8c302c13dc9789f8abd024250159a" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-message-list/chat-message-list.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-message-list/chat-message-list.component.ts", + "sha256": "a31b3d26e003f57c747c29884162e626d41af2917215f3a3303b2bc1b6387697" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-message-list/message-template.directive.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-message-list/message-template.directive.ts", + "sha256": "7be764f4c9c4709215552402e31fb1deb317c3e5761cbadc07e6f4c54e15683e" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-message/chat-message.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-message/chat-message.component.ts", + "sha256": "0317e771558c5862a84851610c4d5ab7aeac5b0d354bb493c3562790e2ddad89" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-overflow-menu/chat-overflow-menu.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-overflow-menu/chat-overflow-menu.component.ts", + "sha256": "b7472845d52b5e251bbb3f7641b04a3d1ff51a556f6d5030ffdf4a41073e6724" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-project-list/chat-project-list.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-project-list/chat-project-list.component.ts", + "sha256": "ce5b07cb2fc92ccc9acc1a0f1535ec500bec87b684b455837baba8b6a788e322" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-reasoning/chat-reasoning.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-reasoning/chat-reasoning.component.ts", + "sha256": "ffcf3869a0c4a34630ee1616ce64095441bf223262bda011ea42e4d085c39338" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-scroll-bubble/chat-scroll-bubble.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-scroll-bubble/chat-scroll-bubble.component.ts", + "sha256": "0d08b749a949893c7e522d1d67cfc3981100e10ac381dc332780d5fa1e238396" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-select/chat-select.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-select/chat-select.component.ts", + "sha256": "6a1270c41ed362b7881f9247207f9bc64e978055ad23b1b13c979a92e07e9930" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-sidenav-scrim/chat-sidenav-scrim.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-sidenav-scrim/chat-sidenav-scrim.component.ts", + "sha256": "a6e12b0194fa665bc664b1f17a4f7f14e2bb0f371751ecaa839b0070999c34ac" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-subagents/chat-subagents.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-subagents/chat-subagents.component.ts", + "sha256": "a2dbc1b35630bcf9ea7a3877020ac5fdee98aaf3dceeb0efe6f543b053b58be7" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-suggestions/chat-suggestions.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-suggestions/chat-suggestions.component.ts", + "sha256": "76827c9e9ffb8369046451d18b653280e18a75414c6e7a2ee44964c389a7cc78" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-thread-list/chat-thread-list.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-thread-list/chat-thread-list.component.ts", + "sha256": "0135cf141cf07f37ab283b13453e8cd0fc8df5adf9c40401db23447680560830" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-timeline/chat-timeline.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-timeline/chat-timeline.component.ts", + "sha256": "8fa4d27e86ebaac30ccc943150977602856e9328250ea39a8774af65fa07441f" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-call-template.directive.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-call-template.directive.ts", + "sha256": "5b7d7704866bcd5e04fffee9387fe74bf7972ee8a442dddaa0ac78dc40d1e5db" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-calls.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-calls.component.ts", + "sha256": "2f670bdd3513ed6870d190783ef2406d0c01f7fab2b3cb6297e24b96436f18ae" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-tool-calls/group-summary.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-tool-calls/group-summary.ts", + "sha256": "7ef014667cebc1dab41df5101e87c512595b021f27625d82205d2ae3cdf86129" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-tool-calls/resolve-message-tool-calls.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-tool-calls/resolve-message-tool-calls.ts", + "sha256": "e77d12de26837a21af6afbf7d2d40c831ca763df79395e8e256e0c0ea414755b" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-tool-views/chat-tool-views.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-tool-views/chat-tool-views.component.ts", + "sha256": "29c5ac4eb1b19025ca2da5ac68b5dafb0a16028126c253e56f55a81c079c2309" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-trace/chat-trace.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-trace/chat-trace.component.ts", + "sha256": "86f04ccf59aff3bbd654ce3643a522dfe47173a162f5f3a86724424e9ca93c37" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-typing-indicator/chat-typing-indicator.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-typing-indicator/chat-typing-indicator.component.ts", + "sha256": "388d00cd70e7b1229a01ed2ade080e292c39dab66fe87dee2339f560e8cb1320" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-welcome/chat-welcome-suggestion.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-welcome/chat-welcome-suggestion.component.ts", + "sha256": "ea2358d0d37b8d05b90582d2ffddc776d65ef6d7b17b3907b6b1f722cb56f015" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-welcome/chat-welcome.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-welcome/chat-welcome.component.ts", + "sha256": "bf61c24f522586fd917d2153e4f47aa3543cfb3a9787e1070bb1abefb9c19cd7" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-window/chat-window.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/chat-window/chat-window.component.ts", + "sha256": "bd72b48201721768fea76d1983a552574b302d5e2ee8c9f4b433d83cc7edd205" + }, + { + "id": "source:libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts", + "sha256": "fbdcefdbe2fe8ea6d4861f29096801d41fdbfdfd5a0fe8223fdbedb5958f407b" + }, + { + "id": "source:libs/chat/src/lib/primitives/overlay/connected-position.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/overlay/connected-position.ts", + "sha256": "04aac1471ba5f3dc48d294c703c6627462bfb68891a602537803a9a386305ade" + }, + { + "id": "source:libs/chat/src/lib/primitives/overlay/overlay-container.ts", + "kind": "source", + "path": "libs/chat/src/lib/primitives/overlay/overlay-container.ts", + "sha256": "0b456ae174fe6d356828646dfb63ea8b822b2edac5c6b7fe35c740ce8f18dcf6" + }, + { + "id": "source:libs/chat/src/lib/routing/thread-routing.ts", + "kind": "source", + "path": "libs/chat/src/lib/routing/thread-routing.ts", + "sha256": "281da6cb3818eb8a0669853f95667d0cbfce79eec5828d9ce19f463484cd3c02" + }, + { + "id": "source:libs/chat/src/lib/streaming/content-classifier.ts", + "kind": "source", + "path": "libs/chat/src/lib/streaming/content-classifier.ts", + "sha256": "acbfdc23d19d978a43c3e90f989592d540fb1f30b99837c870e3b806122d9a37" + }, + { + "id": "source:libs/chat/src/lib/streaming/markdown-render.ts", + "kind": "source", + "path": "libs/chat/src/lib/streaming/markdown-render.ts", + "sha256": "f4d30337cbf0dbd749e5d16f08930e6c3cb1418955ea32a4e13157d2ba3bfe52" + }, + { + "id": "source:libs/chat/src/lib/streaming/parse-tree-store.ts", + "kind": "source", + "path": "libs/chat/src/lib/streaming/parse-tree-store.ts", + "sha256": "50e0c088c862028f09c6b76759ec34bae88eb00889cc18e8d4c51dc30beb7587" + }, + { + "id": "source:libs/chat/src/lib/streaming/streaming-markdown.component.ts", + "kind": "source", + "path": "libs/chat/src/lib/streaming/streaming-markdown.component.ts", + "sha256": "d6bbe211cd43461a0557f8ec85947009d68d222916d88aac2b45afaab4cad228" + }, + { + "id": "source:libs/chat/src/lib/streaming/trace.ts", + "kind": "source", + "path": "libs/chat/src/lib/streaming/trace.ts", + "sha256": "abf14ec28c1341f9a6c4a6c51ba5dd324c00843990f8e756d1683bcbf82619b0" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-citations.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-citations.styles.ts", + "sha256": "2e9ef1e1aae4f28830024a96812737d408556f7603a9ccbbf6b2f4e13f87887d" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-confirm-dialog.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-confirm-dialog.styles.ts", + "sha256": "d3c86cd462f572e5932c7a93863bc9949728bc036e7bb7bf40bb9f46302e3f31" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-error.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-error.styles.ts", + "sha256": "140ef42c4088e1fd6fadb0f91904e49451f6efe80cee32245ace8c2794797ef7" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-generative-ui.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-generative-ui.styles.ts", + "sha256": "11245c1d703064b83f4d6571427e517d765014b6c576a2dcc888b45c6a015a27" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-history-search-palette.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-history-search-palette.styles.ts", + "sha256": "be71fb7da5f7c4fa5a3316f990c78402e1b160618ef05d6cdce23766d89eda2d" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-icons.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-icons.ts", + "sha256": "2a4cee9dcd1dc762c5782c7485018bdc5d30bcc2ad073d75758f8899da996c5a" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-input.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-input.styles.ts", + "sha256": "236a90847ba5a12e10deac5ea2e3b491a47d6ebc34b5aefb2bf0c55cf1368f6b" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-interrupt.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-interrupt.styles.ts", + "sha256": "9e509df1ec064e286c9c81d87e9262ea683bdc5462c0c6f7b185cf2ef57de56b" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-launcher-button.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-launcher-button.styles.ts", + "sha256": "6e3a3f770516513a4c41c08f2bc4da3df92ebdba22c1f1a4b87a0474a815b342" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-markdown.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-markdown.styles.ts", + "sha256": "288123cf07410db865219a8819e91cc8d0fa3f05cbf38868d88e456090955096" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-message-actions.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-message-actions.styles.ts", + "sha256": "daaac0f3ef234594e985371155c152b99ba75e0d1e337bc41d4c9e83eaab8db4" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-message-list.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-message-list.styles.ts", + "sha256": "41f4bc88f74bbdf56de3aedb8e1727aed79b197106ea890d52aa74171889d0a3" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-message.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-message.styles.ts", + "sha256": "410d4477a99828be94464a491eae0a1789ed777782914d196e98c401cebea9e3" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-overflow-menu.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-overflow-menu.styles.ts", + "sha256": "43efe997288e2c509d54c6510e3c757ea6d5797622731e7239fd87b3d52272be" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-project-list.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-project-list.styles.ts", + "sha256": "e899300a645e6d48014d23cf1ba917b83b8e39662dae5a98085b492680f620dc" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-reasoning.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-reasoning.styles.ts", + "sha256": "87bfd961e64610c934768d36a1555b6e111278c14464fa2e4c00452845ceeaa5" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-scroll-bubble.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-scroll-bubble.styles.ts", + "sha256": "863837bb659def1cbdbf90dc7b95648f2328d5e4a941d42affe3ed987184394b" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-select.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-select.styles.ts", + "sha256": "193b0a0c878bc02b73f4a1a5222a8d2cc4e4d27d823f997464acc4d4c9aecae5" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-sidenav.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-sidenav.styles.ts", + "sha256": "ff15d9a62866fade31feac5ccef1842a456d4f32788f3182a744bc75bddc005a" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-suggestions.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-suggestions.styles.ts", + "sha256": "4a9de2a5fda5ccbede0869f9ef0dd9319b90d56ff99faf8c8fdd9056e4ce00fa" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-thread-list.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-thread-list.styles.ts", + "sha256": "eb6c542439a9ef58c0e1fc06f782a0e48450147588ab837be8835bf6e7145284" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-tokens.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-tokens.ts", + "sha256": "40028373e8f996edbbd042614a328af3e139a268a281112d423481da51cc69dc" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-trace.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-trace.styles.ts", + "sha256": "4a0596a022b01c0d1dcf321812c1a83a0f3956de59c7a0c874e081e3e74a47c2" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-typing-indicator.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-typing-indicator.styles.ts", + "sha256": "3c6d840c83df4d8e5101bc92e80e7464b379ea3a5593e345a2cca1286a7137ec" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-welcome.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-welcome.styles.ts", + "sha256": "36041fd63e33aec8d3b7de3e0079f9163ff090a3ded68b4f23339618ec96e52f" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-window.styles.ts", + "kind": "source", + "path": "libs/chat/src/lib/styles/chat-window.styles.ts", + "sha256": "5241da16b80d3626d55e6915a5449718c109f5e55fc14c749867c619ce7edbee" + }, + { + "id": "source:libs/chat/src/lib/testing/mock-agent.ts", + "kind": "source", + "path": "libs/chat/src/lib/testing/mock-agent.ts", + "sha256": "5ad115d8ef01edf386458929051657686a2de0e88122100aeb9bd3d3b53099fa" + }, + { + "id": "source:libs/chat/src/lib/utils/format-duration.ts", + "kind": "source", + "path": "libs/chat/src/lib/utils/format-duration.ts", + "sha256": "3296dc42d20c79f9cae60db2856856200d36cd3e8506011bb71430db01cb153c" + }, + { + "id": "source:libs/chat/src/public-api.ts", + "kind": "source", + "path": "libs/chat/src/public-api.ts", + "sha256": "caae3d2c6f5f1d978375f0081e6a85613c4f6a3fabb2ec3a5b232ea3007b7df7" + }, + { + "id": "source:libs/chat/src/test-setup.ts", + "kind": "source", + "path": "libs/chat/src/test-setup.ts", + "sha256": "762fc33fb355ba827df74a017c3ff22545da38af4b273100787ce67e1ee66fc0" + }, + { + "id": "source:libs/chat/src/testing/type-assert.ts", + "kind": "source", + "path": "libs/chat/src/testing/type-assert.ts", + "sha256": "030b8cb199795a1c8b47b6e2cec574ff5fac9e31dfa98b7cb2cbf2bc1e887638" + }, + { + "id": "source:libs/chat/testing/agent-conformance.ts", + "kind": "source", + "path": "libs/chat/testing/agent-conformance.ts", + "sha256": "1a9df15a02bb3a10c9eebf54008c83887b771043fd726c52a399282b061078ff" + }, + { + "id": "source:libs/chat/testing/agent-with-history-conformance.ts", + "kind": "source", + "path": "libs/chat/testing/agent-with-history-conformance.ts", + "sha256": "6a37b01653715b4516ecceda654369a5cd095c5916b1ff05d643cc468cc9557a" + }, + { + "id": "source:libs/chat/testing/fake-agent-config.ts", + "kind": "source", + "path": "libs/chat/testing/fake-agent-config.ts", + "sha256": "b95f6d85a5a102d3d9c9cd208155f165eda7005d6cba7d978a816c0b362cc5fb" + }, + { + "id": "source:libs/chat/testing/interrupt-conformance.ts", + "kind": "source", + "path": "libs/chat/testing/interrupt-conformance.ts", + "sha256": "1db70c2bc68a50047211d9c326d979d4119753799f3f508f7f9a96e4d9b54924" + }, + { + "id": "source:libs/chat/testing/public-api.ts", + "kind": "source", + "path": "libs/chat/testing/public-api.ts", + "sha256": "9b239fb7f5b1ce50c3ec6d173ce8d99a17cbf0014fe1aade4da89b6fdfc2da6e" + }, + { + "id": "source:libs/chat/testing/reasoning-fixture.ts", + "kind": "source", + "path": "libs/chat/testing/reasoning-fixture.ts", + "sha256": "b26a39a3f25b81ce3555e0529418fefc8c90b31ebf572b30b9cbfb40d2016732" + }, + { + "id": "source:libs/chat/vite.config.mts", + "kind": "source", + "path": "libs/chat/vite.config.mts", + "sha256": "c1afeb8d76bb58b54fc601ea871743a500ebdeb54bbe7cde47aa075e64f433e8" + }, + { + "id": "source:libs/cockpit-registry/eslint.config.mjs", + "kind": "source", + "path": "libs/cockpit-registry/eslint.config.mjs", + "sha256": "19ed44f44a208badb8db8c977b66b43356110bc8ab014cefb7b9782707d05f7c" + }, + { + "id": "source:libs/cockpit-registry/src/index.ts", + "kind": "source", + "path": "libs/cockpit-registry/src/index.ts", + "sha256": "5f55e314ea97b8bb364ebbaaa7e42f41af9c51e9ae3a4424adf7f689a77258a7" + }, + { + "id": "source:libs/cockpit-registry/src/lib/capability-registry.ts", + "kind": "source", + "path": "libs/cockpit-registry/src/lib/capability-registry.ts", + "sha256": "25e248c19db7679f0efb0c9cb53fe38806294956a94a4161a8ce0ceb0809bf28" + }, + { + "id": "source:libs/cockpit-registry/src/lib/content-descriptors.ts", + "kind": "source", + "path": "libs/cockpit-registry/src/lib/content-descriptors.ts", + "sha256": "38ec3c863ecc0dd2e09364e0d140224b7ef4d2ceb11a6954259a3bd1e40cd90f" + }, + { + "id": "source:libs/cockpit-registry/src/lib/docs-links.ts", + "kind": "source", + "path": "libs/cockpit-registry/src/lib/docs-links.ts", + "sha256": "c69c193131686e9d63cf861ead39544d821f574474dc87ff69e236d2545d80aa" + }, + { + "id": "source:libs/cockpit-registry/src/lib/manifest.ts", + "kind": "source", + "path": "libs/cockpit-registry/src/lib/manifest.ts", + "sha256": "586181b6bbfcf9073e30c5088b48fe5dcdf5b0c56e0c7754d433dcc945c76d9b" + }, + { + "id": "source:libs/cockpit-registry/src/lib/manifest.types.ts", + "kind": "source", + "path": "libs/cockpit-registry/src/lib/manifest.types.ts", + "sha256": "e3083cfb19daa04c698f3a86d3e73c0b2e45607cd866a90a78643741c623e902" + }, + { + "id": "source:libs/cockpit-registry/src/lib/resolve-language.ts", + "kind": "source", + "path": "libs/cockpit-registry/src/lib/resolve-language.ts", + "sha256": "462d90237baa0dd06dd6dd355f417e27d7c6e1ba5a2796f8b936d0c6fac03dcd" + }, + { + "id": "source:libs/cockpit-registry/src/lib/validate-manifest.ts", + "kind": "source", + "path": "libs/cockpit-registry/src/lib/validate-manifest.ts", + "sha256": "b70540bd20e82c16795459f6e8ca1926f590855cbb7f35f69ff640008e827701" + }, + { + "id": "source:libs/cockpit-registry/src/lib/workspace-resolution.ts", + "kind": "source", + "path": "libs/cockpit-registry/src/lib/workspace-resolution.ts", + "sha256": "c62f08b2951eaaf37353205f96cd96b7e87b4514c4f50665dddf47536db6f8a8" + }, + { + "id": "source:libs/cockpit-registry/vite.config.mts", + "kind": "source", + "path": "libs/cockpit-registry/vite.config.mts", + "sha256": "aa42bfd546d8e6f968c790c370a39811de24eca29b1262f56fecfd4c226bb3a5" + }, + { + "id": "source:libs/cockpit-runtime-bridge/eslint.config.mjs", + "kind": "source", + "path": "libs/cockpit-runtime-bridge/eslint.config.mjs", + "sha256": "19ed44f44a208badb8db8c977b66b43356110bc8ab014cefb7b9782707d05f7c" + }, + { + "id": "source:libs/cockpit-runtime-bridge/src/index.ts", + "kind": "source", + "path": "libs/cockpit-runtime-bridge/src/index.ts", + "sha256": "dd05cda7b02faf2765a00df453e8207570c7c4dbda3a2550c919ce9b2959d57d" + }, + { + "id": "source:libs/cockpit-runtime-bridge/src/lib/generated-runtime-parent-origins.ts", + "kind": "source", + "path": "libs/cockpit-runtime-bridge/src/lib/generated-runtime-parent-origins.ts", + "sha256": "e58d4e20229ecf06d35999030fa70a30b1151bf5edf554e44dbf49ce7c63222c" + }, + { + "id": "source:libs/cockpit-runtime-bridge/src/lib/install-runtime-bridge.ts", + "kind": "source", + "path": "libs/cockpit-runtime-bridge/src/lib/install-runtime-bridge.ts", + "sha256": "6c28f340bcd4b0c088865005b95d2d00f71a44a99b73b156163aacf3d45bf097" + }, + { + "id": "source:libs/cockpit-runtime-bridge/src/lib/protocol.ts", + "kind": "source", + "path": "libs/cockpit-runtime-bridge/src/lib/protocol.ts", + "sha256": "0dc2ad5628121805e7e74d6aaaff51cb1f8550f9eb2d59c19c24a4e4be08760e" + }, + { + "id": "source:libs/cockpit-runtime-bridge/src/lib/runtime-parent-origins.ts", + "kind": "source", + "path": "libs/cockpit-runtime-bridge/src/lib/runtime-parent-origins.ts", + "sha256": "77b8626c6ff3e1f7ec9afa4fc1cfea3621edc89ad598a698282b6891a6767dfd" + }, + { + "id": "source:libs/cockpit-runtime-bridge/vite.config.mts", + "kind": "source", + "path": "libs/cockpit-runtime-bridge/vite.config.mts", + "sha256": "a50c4086650ecdd9cf4999cf327d50fb684d7919474a51a7917e791babd5e4f2" + }, + { + "id": "source:libs/cockpit-shell/src/index.ts", + "kind": "source", + "path": "libs/cockpit-shell/src/index.ts", + "sha256": "1300251e57258f488db5463b2bce753932929c3418ae261d172b0471eb1e4001" + }, + { + "id": "source:libs/cockpit-shell/src/lib/capability-contract.ts", + "kind": "source", + "path": "libs/cockpit-shell/src/lib/capability-contract.ts", + "sha256": "851f58a4ed816c5686861acbeb69a235b18ed0e0f16ac72eccf21009a1dcf1f8" + }, + { + "id": "source:libs/cockpit-shell/src/lib/extract-docs.ts", + "kind": "source", + "path": "libs/cockpit-shell/src/lib/extract-docs.ts", + "sha256": "07b5bb0fd9d8282bc85d0af5f6995bdae7051484be1f27b20e7b12015a93bdac" + }, + { + "id": "source:libs/cockpit-shell/src/lib/route-home.ts", + "kind": "source", + "path": "libs/cockpit-shell/src/lib/route-home.ts", + "sha256": "0641efe3d62a5bce91b9d3dc46eeb94305199edde45645c9c53af6f043eec640" + }, + { + "id": "source:libs/cockpit-shell/src/lib/shell-contracts.ts", + "kind": "source", + "path": "libs/cockpit-shell/src/lib/shell-contracts.ts", + "sha256": "a960d64d20d94dd91e46a62a7945815ea05e3bdec91a2ac4ea541ba51a690b91" + }, + { + "id": "source:libs/cockpit-shell/src/lib/workspace-content.ts", + "kind": "source", + "path": "libs/cockpit-shell/src/lib/workspace-content.ts", + "sha256": "93dcb10f05cb6f51f77fd5aa796065e9e25bb558fd0ac801ddbefdcb34808f14" + }, + { + "id": "source:libs/cockpit-shell/src/lib/workspace-presentation.ts", + "kind": "source", + "path": "libs/cockpit-shell/src/lib/workspace-presentation.ts", + "sha256": "325d72b4d087f1b995600527c0665b91fa4ce61b192d0c8e46f8337ebcee7a62" + }, + { + "id": "source:libs/cockpit-shell/vite.config.mts", + "kind": "source", + "path": "libs/cockpit-shell/vite.config.mts", + "sha256": "da75d3d522338946205aeb3d885a18bb00752836d981d25f5bf8e131a7197b14" + }, + { + "id": "source:libs/cockpit-telemetry/eslint.config.mjs", + "kind": "source", + "path": "libs/cockpit-telemetry/eslint.config.mjs", + "sha256": "8c09e2fc8462b42d122b7dec6fb0dda433268b9d77f0304f0b9e559d53142402" + }, + { + "id": "source:libs/cockpit-telemetry/src/index.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/index.ts", + "sha256": "78b656b2773792ff12105b63a8d1d143ec3ef929878bfa09054b7ba4d477d5b1" + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/activation-aggregator.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/lib/activation-aggregator.ts", + "sha256": "1e47e996c7864d17f92446170aa8f82a34e1c598bd72a988e8dd5e751ee9db57" + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/cockpit-telemetry.service.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/lib/cockpit-telemetry.service.ts", + "sha256": "135c5cd03df82bc5274a145b4fc7b94e102240448d4654571bb95c13d8d069eb" + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/distinct-id.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/lib/distinct-id.ts", + "sha256": "b0fe95483d1649044b34dadf7f7bd2132d3dfd68c7007e0872897ef57022c8c3" + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/events.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/lib/events.ts", + "sha256": "3ad0173efc998175eec6b795ba43dfb62c88d027d60dd07ea9452911462c1832" + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/harness.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/lib/harness.ts", + "sha256": "584c659103521d654759874125154da43e826c836229ef5b0f01919754e59465" + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/provide-cockpit-telemetry.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/lib/provide-cockpit-telemetry.ts", + "sha256": "215dd62ec09f8cb89000d8cf95671ecb4b6cb0886e9b2f8a25fe1a989bf106a0" + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/runtime-connection.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/lib/runtime-connection.ts", + "sha256": "719899373512ba57a36c594da88afb413b9489648fd5f0584a37c71faa5aeb54" + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/tokens.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/lib/tokens.ts", + "sha256": "e1767f3939107b8af9e5e891bde15dafd3f25e9e08ae72eba8c04c240cddf847" + }, + { + "id": "source:libs/cockpit-telemetry/src/public-api.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/public-api.ts", + "sha256": "2b66b4f516676621bf3ebf830bb42293fdc961f9a1c7d14f13afaa46711e6e79" + }, + { + "id": "source:libs/cockpit-telemetry/src/test-setup.ts", + "kind": "source", + "path": "libs/cockpit-telemetry/src/test-setup.ts", + "sha256": "2208f32187a2197d8004cc6672e5afa1f11aa267479ab296cf354aa7e1c0aa15" + }, + { + "id": "source:libs/cockpit-telemetry/vite.config.mts", + "kind": "source", + "path": "libs/cockpit-telemetry/vite.config.mts", + "sha256": "c1afeb8d76bb58b54fc601ea871743a500ebdeb54bbe7cde47aa075e64f433e8" + }, + { + "id": "source:libs/design-tokens/scripts/generate-theme-css.ts", + "kind": "source", + "path": "libs/design-tokens/scripts/generate-theme-css.ts", + "sha256": "1baeff7e19adde54f715882077d35785cb6bcecd00119c7e0581acadb39005cb" + }, + { + "id": "source:libs/design-tokens/src/index.ts", + "kind": "source", + "path": "libs/design-tokens/src/index.ts", + "sha256": "fd92ae115d9d0f8b1640e86f16dd29421b83867de541d85325acb8ed7784392e" + }, + { + "id": "source:libs/design-tokens/src/lib/base.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/base.ts", + "sha256": "80d7883304a2eb4dc6e90a20603d9596376073beb655229538e43911d97cc725" + }, + { + "id": "source:libs/design-tokens/src/lib/colors.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/colors.ts", + "sha256": "a171618e401c8f245bf0429de73e406d4a18c29e3778a81220177ffe3160bf1f" + }, + { + "id": "source:libs/design-tokens/src/lib/css-vars.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/css-vars.ts", + "sha256": "30b783666fd21db4273741e3d44f2177246cbd7f79c8f2ca201e3c91424e1d78" + }, + { + "id": "source:libs/design-tokens/src/lib/dark.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/dark.ts", + "sha256": "c502bb57971bf1cfd0f9fd132b49e6f2044b95123128919104a1af37c0067b5e" + }, + { + "id": "source:libs/design-tokens/src/lib/light.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/light.ts", + "sha256": "8f17ecb1fc936ec01d98b8deb98c7393fcd9589b06718ff5c1f8991102524e33" + }, + { + "id": "source:libs/design-tokens/src/lib/radius.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/radius.ts", + "sha256": "776280f7048fa00a56141dac9ae7f1c909e0a67c451aa14b9da2fa38516e01ef" + }, + { + "id": "source:libs/design-tokens/src/lib/shadows.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/shadows.ts", + "sha256": "2ea146a8a3fbc02142b9881ca95fb88a4f94662a4f1f6ffb7e826189909fd2ec" + }, + { + "id": "source:libs/design-tokens/src/lib/space.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/space.ts", + "sha256": "193b14a780e22b131208b88985fa9c0e1b47074a12f4a52094605e670567adf3" + }, + { + "id": "source:libs/design-tokens/src/lib/surfaces.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/surfaces.ts", + "sha256": "64cf9b30adb01bc6cae022d62a5300789f48811bccd4807361f80fb0c0c0e64d" + }, + { + "id": "source:libs/design-tokens/src/lib/theme.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/theme.ts", + "sha256": "9714d3920bb51016c047413f5cbfedf05a57802da2316e4dff4f1a68a7af4ec4" + }, + { + "id": "source:libs/design-tokens/src/lib/tokens.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/tokens.ts", + "sha256": "fcdf1ce86a23fe72bf0b4a89fb511d81ce27b9ed966d3edb9038593a94b143d1" + }, + { + "id": "source:libs/design-tokens/src/lib/typography.ts", + "kind": "source", + "path": "libs/design-tokens/src/lib/typography.ts", + "sha256": "26902c7bcb5f7932281063f6619a749ac1c14071e1ba3d0b1913a863686bde00" + }, + { + "id": "source:libs/design-tokens/vite.config.mts", + "kind": "source", + "path": "libs/design-tokens/vite.config.mts", + "sha256": "da75d3d522338946205aeb3d885a18bb00752836d981d25f5bf8e131a7197b14" + }, + { + "id": "source:libs/e2e-harness/src/ag-ui-global-setup-factory.ts", + "kind": "source", + "path": "libs/e2e-harness/src/ag-ui-global-setup-factory.ts", + "sha256": "302ad0615b36e1f2fb6c32df475163b9155a475cd48103892f7dbf9f80289229" + }, + { + "id": "source:libs/e2e-harness/src/aimock-mode.ts", + "kind": "source", + "path": "libs/e2e-harness/src/aimock-mode.ts", + "sha256": "8a10fd1160430d430afe872d74f0e207617e4b364ee52d5fb4a98bfba511b75c" + }, + { + "id": "source:libs/e2e-harness/src/aimock-runner.ts", + "kind": "source", + "path": "libs/e2e-harness/src/aimock-runner.ts", + "sha256": "2683eaf82b21536ade84ca305774be297960c91ac324d5716e9b9923410b32fc" + }, + { + "id": "source:libs/e2e-harness/src/drift-lib.ts", + "kind": "source", + "path": "libs/e2e-harness/src/drift-lib.ts", + "sha256": "2204b9f3c289eeb2d226173394146a0f22db08802e806bd670f3959c262d4885" + }, + { + "id": "source:libs/e2e-harness/src/drift.ts", + "kind": "source", + "path": "libs/e2e-harness/src/drift.ts", + "sha256": "ce403e734b60f05c3a036257561834ddff4cad4aa968e692ef4469f306a8abb3" + }, + { + "id": "source:libs/e2e-harness/src/global-setup-factory.ts", + "kind": "source", + "path": "libs/e2e-harness/src/global-setup-factory.ts", + "sha256": "78e17419e00f7dabbfb234241581d5fd92d93f55573167d3ed8f112081243536" + }, + { + "id": "source:libs/e2e-harness/src/global-teardown.ts", + "kind": "source", + "path": "libs/e2e-harness/src/global-teardown.ts", + "sha256": "222e5ed4c8b1eafb9c9c57834d0381e825703b82b996faef91356204d73c42f0" + }, + { + "id": "source:libs/e2e-harness/src/index.ts", + "kind": "source", + "path": "libs/e2e-harness/src/index.ts", + "sha256": "56ec160f624152b8b0859ff879231b4080f0a3ae31d9e0b8f4bac2894dfbb0c9" + }, + { + "id": "source:libs/e2e-harness/src/test-helpers.ts", + "kind": "source", + "path": "libs/e2e-harness/src/test-helpers.ts", + "sha256": "3af4796bc9b037ffc04e4b6622ddb4154a128341a0372fc26331d3e8803cc1b4" + }, + { + "id": "source:libs/example-layouts/src/lib/example-chat-layout.component.ts", + "kind": "source", + "path": "libs/example-layouts/src/lib/example-chat-layout.component.ts", + "sha256": "5eebab0c701695e5f472c0b7cdf1e643e96a02d5359c781a4927e40a59ff7d65" + }, + { + "id": "source:libs/example-layouts/src/lib/example-split-layout.component.ts", + "kind": "source", + "path": "libs/example-layouts/src/lib/example-split-layout.component.ts", + "sha256": "70f5bbd277f50fa48a0adb5d17c94cb30d268ca97a321fb1360ff6dcbf791394" + }, + { + "id": "source:libs/example-layouts/src/lib/install-embedded-theme.ts", + "kind": "source", + "path": "libs/example-layouts/src/lib/install-embedded-theme.ts", + "sha256": "43ac4509c68c7e5b07afea1100f12b1db30ab8273c99d7bf7c9bdcd479d9b6bf" + }, + { + "id": "source:libs/example-layouts/src/public-api.ts", + "kind": "source", + "path": "libs/example-layouts/src/public-api.ts", + "sha256": "6ae76a26f8deb94ced5d4fec9ec9a3e340da3157d8133f8f07fef6827e5e45ad" + }, + { + "id": "source:libs/example-layouts/src/test-setup.ts", + "kind": "source", + "path": "libs/example-layouts/src/test-setup.ts", + "sha256": "2208f32187a2197d8004cc6672e5afa1f11aa267479ab296cf354aa7e1c0aa15" + }, + { + "id": "source:libs/example-layouts/vite.config.mts", + "kind": "source", + "path": "libs/example-layouts/vite.config.mts", + "sha256": "728ad9cb948160a25027368808ae7858c3d03c5542f797f47a7ea792f08a5660" + }, + { + "id": "source:libs/langgraph/.install-collector/development-install.d.ts", + "kind": "source", + "path": "libs/langgraph/.install-collector/development-install.d.ts", + "sha256": "bb95a098f92383f2d131eb1b9ff9d9e7d0ee7304a8debc188c033017a14284ce" + }, + { + "id": "source:libs/langgraph/.install-collector/development-install.mjs", + "kind": "source", + "path": "libs/langgraph/.install-collector/development-install.mjs", + "sha256": "a69938ff45c56be138849066563917e17169fc7e0d9143e95801af40f472cbe4" + }, + { + "id": "source:libs/langgraph/eslint.config.mjs", + "kind": "source", + "path": "libs/langgraph/eslint.config.mjs", + "sha256": "d1924a267c02bcc6777cdc9fc8d3d48bda67f1c3c7798e9710b8c8291b835ca6" + }, + { + "id": "source:libs/langgraph/install/postinstall.cjs", + "kind": "source", + "path": "libs/langgraph/install/postinstall.cjs", + "sha256": "5624c16b6e7dc1c61bc4b9233de01ba6d13e1baa78f06a9977b652a59d67a5a2" + }, + { + "id": "source:libs/langgraph/src/lib/agent-lifecycle-registry.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/agent-lifecycle-registry.ts", + "sha256": "8096922ed1428743a3b459df1741271d8941803c7b78f81a81ffa8c812a4c51d" + }, + { + "id": "source:libs/langgraph/src/lib/agent.fn.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/agent.fn.ts", + "sha256": "44211ee473890adc98cd9cfe94540aa35dd1195daed35de2e7711738381fa2b4" + }, + { + "id": "source:libs/langgraph/src/lib/agent.provider.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/agent.provider.ts", + "sha256": "d1bb3ff89c239a8c3e28de62de2de39f0a475690d4acf572ee1b03e2c5c79ee8" + }, + { + "id": "source:libs/langgraph/src/lib/agent.types.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/agent.types.ts", + "sha256": "6df8e889912898c0f3a11b6a4a8651bfe02ac08f107fae83d1a940793deda2de" + }, + { + "id": "source:libs/langgraph/src/lib/client-tools.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/client-tools.ts", + "sha256": "ccc7fa87ee655925f36225f874c314578a5124f0693dc84bce00f792090636ca" + }, + { + "id": "source:libs/langgraph/src/lib/client/client-options.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/client/client-options.ts", + "sha256": "36b4f20ba547104121aad03d2717eba523cc6a21f458f5a1e2a9cee5b4b2e97a" + }, + { + "id": "source:libs/langgraph/src/lib/client/create-langgraph-client.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/client/create-langgraph-client.ts", + "sha256": "46795d05f61c696dd1bb2910c12129684907c7b006ac35015effd3a53d0164ea" + }, + { + "id": "source:libs/langgraph/src/lib/inject-agent.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/inject-agent.ts", + "sha256": "8171644caec5a26c41166e6af114a5c2620a16791206d6b477ee4978b145e014" + }, + { + "id": "source:libs/langgraph/src/lib/internals/branch-tree.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/internals/branch-tree.ts", + "sha256": "5a39787273f9e8447a32b3dee673aa9da78bc0aca9e71f0480b611c8feab341d" + }, + { + "id": "source:libs/langgraph/src/lib/internals/extract-citations.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/internals/extract-citations.ts", + "sha256": "bafeca3c422659792e986b76aa5d8117592402bbdfbb60fbed7d356d8e901ffb" + }, + { + "id": "source:libs/langgraph/src/lib/internals/stream-manager.bridge.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/internals/stream-manager.bridge.ts", + "sha256": "4cbeace27cfef09ace95f50739a89aa9f2a7fdc629242e1f0dabfe2dda79d255" + }, + { + "id": "source:libs/langgraph/src/lib/internals/subagent-tracker.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/internals/subagent-tracker.ts", + "sha256": "f67c64a814413c7c2f5fb9645b361bb6e3176f5045a5f40279aee3d5fea04e8a" + }, + { + "id": "source:libs/langgraph/src/lib/lifecycle.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/lifecycle.ts", + "sha256": "cdd4401f3c2bbd49152a96a3093937df9394a65edaee905af88a9c975776bea4" + }, + { + "id": "source:libs/langgraph/src/lib/package-version.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/package-version.ts", + "sha256": "653f7da57624a0da7e7d8dec8cf7590de7217ab5f9f98aa0f16b3546088fb3ac" + }, + { + "id": "source:libs/langgraph/src/lib/runtime-operation-reporter.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/runtime-operation-reporter.ts", + "sha256": "9bdd7e56d28f9f7cb03ba59ab38d36ab15c8c2f47a444d90ee15816c276c1d73" + }, + { + "id": "source:libs/langgraph/src/lib/testing/fake-stream.transport.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/testing/fake-stream.transport.ts", + "sha256": "5db102dba03f56c45e47db4377acd31cc367eee931e0526782bb146e87977466" + }, + { + "id": "source:libs/langgraph/src/lib/testing/mock-langgraph-agent.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/testing/mock-langgraph-agent.ts", + "sha256": "fbce931562ce9b3ab4c6c02d4c0c737844f40eb3cd26426dc0f2b1778db1a466" + }, + { + "id": "source:libs/langgraph/src/lib/testing/provide-fake-agent.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/testing/provide-fake-agent.ts", + "sha256": "f7ea443643ae997c1714756e3a9917d1782e02b94d233d037a05d3ab9fb5fbf8" + }, + { + "id": "source:libs/langgraph/src/lib/threads/refresh-on.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/threads/refresh-on.ts", + "sha256": "c74efc2d0672e4f6b1f5ffc2ca68e8277c2245ced70c33755769686d4ba37e21" + }, + { + "id": "source:libs/langgraph/src/lib/threads/threads-adapter.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/threads/threads-adapter.ts", + "sha256": "125a0d11f9078c6b9effa0a32e27ac786f8982514beec0ca5d22344fcce6ee7c" + }, + { + "id": "source:libs/langgraph/src/lib/transport/fetch-stream.transport.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/transport/fetch-stream.transport.ts", + "sha256": "7eb00a24edd3f7d316b874e02b07169bc024782fb5894ece782537ef1fcafae2" + }, + { + "id": "source:libs/langgraph/src/lib/transport/mock-stream.transport.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/transport/mock-stream.transport.ts", + "sha256": "fc5aca26a0cabfe3bbd9744105840258e6fe972fe27012edb56792b92b2fbad5" + }, + { + "id": "source:libs/langgraph/src/lib/transport/transport.interface.ts", + "kind": "source", + "path": "libs/langgraph/src/lib/transport/transport.interface.ts", + "sha256": "6e4bd1d1896711a4921c481fa54472597304b41b021c4fd1e44427b0d6191147" + }, + { + "id": "source:libs/langgraph/src/public-api.ts", + "kind": "source", + "path": "libs/langgraph/src/public-api.ts", + "sha256": "3effe8f90bcd9967bb99b9902b3bb6ffbe2769c8c5b46824d2742e2906f6536b" + }, + { + "id": "source:libs/langgraph/src/test-setup.ts", + "kind": "source", + "path": "libs/langgraph/src/test-setup.ts", + "sha256": "8875a42d0fef8f38aa0ac638ef1905fea20a65e9df944514356e959aebad9c1d" + }, + { + "id": "source:libs/langgraph/src/testing/type-assert.ts", + "kind": "source", + "path": "libs/langgraph/src/testing/type-assert.ts", + "sha256": "c658a8dbcf3657af7867f2c7bff92d56b8bd31c8a9c0c397a3b1ce1af62ecc59" + }, + { + "id": "source:libs/langgraph/test/fixtures/capture-streaming-reasoning-puzzle.mjs", + "kind": "source", + "path": "libs/langgraph/test/fixtures/capture-streaming-reasoning-puzzle.mjs", + "sha256": "55303b0fcedb5b7e6e49c283574d0a78a11984ebab675e81f5d1a94f0b6a30e4" + }, + { + "id": "source:libs/langgraph/vite.config.mts", + "kind": "source", + "path": "libs/langgraph/vite.config.mts", + "sha256": "0539aa4a1cdbeefe419f64fd3867d6266ffbef589f9aff2c81f1a198b06379d8" + }, + { + "id": "source:libs/middleware/eslint.config.mjs", + "kind": "source", + "path": "libs/middleware/eslint.config.mjs", + "sha256": "95a389a9b97c42ad8dc4e7d3fdd8f3bbd30ae1b0cf77d8d33d1c237c65ed7b01" + }, + { + "id": "source:libs/middleware/src/langgraph/channel.ts", + "kind": "source", + "path": "libs/middleware/src/langgraph/channel.ts", + "sha256": "95b4fe5d599b1f9874284e4c7e38d28396d4fc503d6f698cea17ad22aa6a4d9f" + }, + { + "id": "source:libs/middleware/src/langgraph/client-tool-execution-store.ts", + "kind": "source", + "path": "libs/middleware/src/langgraph/client-tool-execution-store.ts", + "sha256": "08f74dd9648bd9c762e4a22169052a8426ed00426359d9b583c02b6662811cea" + }, + { + "id": "source:libs/middleware/src/langgraph/client-tool-result-guard.ts", + "kind": "source", + "path": "libs/middleware/src/langgraph/client-tool-result-guard.ts", + "sha256": "05c3bdfa13d1d79666afcf377c3ca90b5799bc02c27c9dd2136d2d5f433f3b68" + }, + { + "id": "source:libs/middleware/src/langgraph/index.ts", + "kind": "source", + "path": "libs/middleware/src/langgraph/index.ts", + "sha256": "e401a9c62b732d3257efb6c6f272a0367c5a6a7e085505563b493bd945b9422b" + }, + { + "id": "source:libs/middleware/src/langgraph/middleware.ts", + "kind": "source", + "path": "libs/middleware/src/langgraph/middleware.ts", + "sha256": "979418eee795c4f66034b559006900cbca1e8e846d7d012514af29bc5bcc60b6" + }, + { + "id": "source:libs/middleware/src/langgraph/postgres-client-tool-execution-store.ts", + "kind": "source", + "path": "libs/middleware/src/langgraph/postgres-client-tool-execution-store.ts", + "sha256": "a579cbdb494c1d89181c031e8db4691fea7c7e938a26c4f28f469c59d4d28c6b" + }, + { + "id": "source:libs/middleware/src/langgraph/router.ts", + "kind": "source", + "path": "libs/middleware/src/langgraph/router.ts", + "sha256": "ca8ac2f2c8b26bc54cf2be10bd406bb693e2c9272334ff5730cf4119c55a53b8" + }, + { + "id": "source:libs/middleware/src/langgraph/types.ts", + "kind": "source", + "path": "libs/middleware/src/langgraph/types.ts", + "sha256": "a2e46ea8dbe5fcfee22c068565d386449c52866d6b14b715059d5de73f8ff7a8" + }, + { + "id": "source:libs/middleware/vite.config.mts", + "kind": "source", + "path": "libs/middleware/vite.config.mts", + "sha256": "56dba6e5f8e0ec195271f37e8de4cbe0eb98c0ad8f04f60749ea7a54e621384d" + }, + { + "id": "source:libs/render/.install-collector/development-install.d.ts", + "kind": "source", + "path": "libs/render/.install-collector/development-install.d.ts", + "sha256": "bb95a098f92383f2d131eb1b9ff9d9e7d0ee7304a8debc188c033017a14284ce" + }, + { + "id": "source:libs/render/.install-collector/development-install.mjs", + "kind": "source", + "path": "libs/render/.install-collector/development-install.mjs", + "sha256": "a69938ff45c56be138849066563917e17169fc7e0d9143e95801af40f472cbe4" + }, + { + "id": "source:libs/render/eslint.config.mjs", + "kind": "source", + "path": "libs/render/eslint.config.mjs", + "sha256": "375b46fbc87ef7ea47b1386bdb4e7244a06f98e2ae4d12de39b1386dce0fed9c" + }, + { + "id": "source:libs/render/install/postinstall.cjs", + "kind": "source", + "path": "libs/render/install/postinstall.cjs", + "sha256": "5624c16b6e7dc1c61bc4b9233de01ba6d13e1baa78f06a9977b652a59d67a5a2" + }, + { + "id": "source:libs/render/src/lib/contexts/render-context.ts", + "kind": "source", + "path": "libs/render/src/lib/contexts/render-context.ts", + "sha256": "d9ffa28f306252944966a3eafe50bf4cfbd572191df359a1edcdd002a8b21b74" + }, + { + "id": "source:libs/render/src/lib/contexts/render-host.ts", + "kind": "source", + "path": "libs/render/src/lib/contexts/render-host.ts", + "sha256": "6b35299c99ca0c8a9c37746028ca09ab18c7a145767c186f0b90b1ae4ac35d83" + }, + { + "id": "source:libs/render/src/lib/contexts/repeat-scope.ts", + "kind": "source", + "path": "libs/render/src/lib/contexts/repeat-scope.ts", + "sha256": "4575eb6ccefe6714a1ceb525ae40c26a3e549ab335d3d4b20d9f6ac7fd2e4929" + }, + { + "id": "source:libs/render/src/lib/default-fallback.component.ts", + "kind": "source", + "path": "libs/render/src/lib/default-fallback.component.ts", + "sha256": "2c9637c3e53024ece4cfd2ba201473fde416738a37609654d9f355a4cc0d3f17" + }, + { + "id": "source:libs/render/src/lib/define-angular-registry.ts", + "kind": "source", + "path": "libs/render/src/lib/define-angular-registry.ts", + "sha256": "2a00d974e156aa9103afee9241e1e29d3280fe9caeb5079270f081271d7c6777" + }, + { + "id": "source:libs/render/src/lib/internals/element-readiness.ts", + "kind": "source", + "path": "libs/render/src/lib/internals/element-readiness.ts", + "sha256": "9ae5bd8520c2248319187088845f6826ca2ea14b091b3a8ccc47f983bd8dedeb" + }, + { + "id": "source:libs/render/src/lib/internals/guarded-emit.ts", + "kind": "source", + "path": "libs/render/src/lib/internals/guarded-emit.ts", + "sha256": "c76b6ed51c056e531c6afc8332f2efc3bc1eb71bbbd0cffd2d416d9e6b540d82" + }, + { + "id": "source:libs/render/src/lib/internals/prop-signal.ts", + "kind": "source", + "path": "libs/render/src/lib/internals/prop-signal.ts", + "sha256": "e04d592f9cb736ebb506642ac0029d73995b12d0b73113fda5fa4757f456494c" + }, + { + "id": "source:libs/render/src/lib/lifecycle.ts", + "kind": "source", + "path": "libs/render/src/lib/lifecycle.ts", + "sha256": "cb0e5153a36de1a6ba6a10f76c04c8749c44927a1f26e3a6682c06924de0d2de" + }, + { + "id": "source:libs/render/src/lib/package-version.ts", + "kind": "source", + "path": "libs/render/src/lib/package-version.ts", + "sha256": "653f7da57624a0da7e7d8dec8cf7590de7217ab5f9f98aa0f16b3546088fb3ac" + }, + { + "id": "source:libs/render/src/lib/provide-render.ts", + "kind": "source", + "path": "libs/render/src/lib/provide-render.ts", + "sha256": "c1d256c894722081bfe77786485469781dc5ab44e8c3ea5bb36630d598796599" + }, + { + "id": "source:libs/render/src/lib/provide-views.ts", + "kind": "source", + "path": "libs/render/src/lib/provide-views.ts", + "sha256": "a279b0108cca4e25d7c95140e7639b508fa9cb97cfc68cd54c4c6fcb03edaa8c" + }, + { + "id": "source:libs/render/src/lib/render-element.component.ts", + "kind": "source", + "path": "libs/render/src/lib/render-element.component.ts", + "sha256": "b9a75d0280c7ba7f0969a4e708fad2f9ed48854029eb715c0a8953d0b19234c8" + }, + { + "id": "source:libs/render/src/lib/render-event.ts", + "kind": "source", + "path": "libs/render/src/lib/render-event.ts", + "sha256": "83a16986d228440276dbdde9c697e1b63bcbf0588e2b431377724a87b101e6e3" + }, + { + "id": "source:libs/render/src/lib/render-lifecycle.service.ts", + "kind": "source", + "path": "libs/render/src/lib/render-lifecycle.service.ts", + "sha256": "e1201e8a9da494d27aed8dea2eb8bd578d855b06e8e82b2c496729d2c1a17359" + }, + { + "id": "source:libs/render/src/lib/render-spec.component.ts", + "kind": "source", + "path": "libs/render/src/lib/render-spec.component.ts", + "sha256": "6641ab6e84d97a24c7d63d0b3e04c8e14e2f0609c04d56a79931db1de70aae00" + }, + { + "id": "source:libs/render/src/lib/render.types.ts", + "kind": "source", + "path": "libs/render/src/lib/render.types.ts", + "sha256": "d9ce704c19fb0c88deeb8d58bce1c670c1a1bb5cc7183b0a4baabf9e3f00ad00" + }, + { + "id": "source:libs/render/src/lib/signal-state-store.ts", + "kind": "source", + "path": "libs/render/src/lib/signal-state-store.ts", + "sha256": "25982a53de56996702e683d8d516a04267f1c30b46ec9204138581afa9b28efd" + }, + { + "id": "source:libs/render/src/lib/standard-schema.ts", + "kind": "source", + "path": "libs/render/src/lib/standard-schema.ts", + "sha256": "da43007f7b936d87923f7a2d0b1eb2c1320511a4aa17b1b188a44724399b2265" + }, + { + "id": "source:libs/render/src/lib/views.ts", + "kind": "source", + "path": "libs/render/src/lib/views.ts", + "sha256": "e91e80bb36cfe78c444644a96dfa7b175aa61b3d31ab673aedbba6947fbec99b" + }, + { + "id": "source:libs/render/src/public-api.ts", + "kind": "source", + "path": "libs/render/src/public-api.ts", + "sha256": "2061dbf71fe1f640e83951b8fda6d4a06e75bf964168a80c4f2b518ad69904f6" + }, + { + "id": "source:libs/render/src/test-setup.ts", + "kind": "source", + "path": "libs/render/src/test-setup.ts", + "sha256": "03c82fe0121539c11d6dda7b3a91bbb7ce1f41eea2866c5c5eca547c45821eab" + }, + { + "id": "source:libs/render/vite.config.mts", + "kind": "source", + "path": "libs/render/vite.config.mts", + "sha256": "c1afeb8d76bb58b54fc601ea871743a500ebdeb54bbe7cde47aa075e64f433e8" + }, + { + "id": "source:libs/telemetry/eslint.config.mjs", + "kind": "source", + "path": "libs/telemetry/eslint.config.mjs", + "sha256": "95a389a9b97c42ad8dc4e7d3fdd8f3bbd30ae1b0cf77d8d33d1c237c65ed7b01" + }, + { + "id": "source:libs/telemetry/install/assemble-package.mjs", + "kind": "source", + "path": "libs/telemetry/install/assemble-package.mjs", + "sha256": "7d715e89330cf1aed8f1b20888ac38e23195c5fb184b420cb3b9b51da31a0578" + }, + { + "id": "source:libs/telemetry/install/bridge.cjs", + "kind": "source", + "path": "libs/telemetry/install/bridge.cjs", + "sha256": "7e35d136e1c0da49eda76ef7ca6c53891cf3fb5aaecc4fba8ae0adcc0c275c74" + }, + { + "id": "source:libs/telemetry/install/collector.cjs", + "kind": "source", + "path": "libs/telemetry/install/collector.cjs", + "sha256": "dad9a55018c34610cd6fdad3b3d87aa133c6bdc52aed791476587cc23e42f6df" + }, + { + "id": "source:libs/telemetry/install/files.cjs", + "kind": "source", + "path": "libs/telemetry/install/files.cjs", + "sha256": "178aba8b167b12644bc7ed080da7afd0fc07fa384cd1d3481bf26f35d1b49f83" + }, + { + "id": "source:libs/telemetry/install/git-context.cjs", + "kind": "source", + "path": "libs/telemetry/install/git-context.cjs", + "sha256": "d1b557b46a17559bf6a7c07d20af85941d6973f2522224fce3a7a07f04758ec5" + }, + { + "id": "source:libs/telemetry/install/identity.cjs", + "kind": "source", + "path": "libs/telemetry/install/identity.cjs", + "sha256": "1084fead3297056492b71d9f2a3c3cb61dd7a60a919c535fd3ca307556a13847" + }, + { + "id": "source:libs/telemetry/install/policy.cjs", + "kind": "source", + "path": "libs/telemetry/install/policy.cjs", + "sha256": "f6233be49dd7d21ae1a8294501c3262b75995db37da1547e5d47f4710ba24012" + }, + { + "id": "source:libs/telemetry/install/postinstall.cjs", + "kind": "source", + "path": "libs/telemetry/install/postinstall.cjs", + "sha256": "d23262fee7a9aafd8f69d9cef74602064e57bf98bb9a54476b5514be7168b743" + }, + { + "id": "source:libs/telemetry/install/verify-pack.mjs", + "kind": "source", + "path": "libs/telemetry/install/verify-pack.mjs", + "sha256": "5adfab0a3e37b70e2b7c84c6ce280e96414de51344ecd16ae6841a5f82863a18" + }, + { + "id": "source:libs/telemetry/scripts/assemble-dist.mjs", + "kind": "source", + "path": "libs/telemetry/scripts/assemble-dist.mjs", + "sha256": "359d7dbeaded00d72bf9712145b1506ba6e2017fc9e4c30097f5ca61a27f9828" + }, + { + "id": "source:libs/telemetry/scripts/verify-angular-install-bridge.mjs", + "kind": "source", + "path": "libs/telemetry/scripts/verify-angular-install-bridge.mjs", + "sha256": "1e0d8e129d89ec3c5f2aaaa1180ef5bcadb31dea70bb3367f593aa8667c53668" + }, + { + "id": "source:libs/telemetry/scripts/verify-development-bundle.mjs", + "kind": "source", + "path": "libs/telemetry/scripts/verify-development-bundle.mjs", + "sha256": "00b6372dc2743e014d7fff7c31b8162f051e5c0fea43621aeef36448148aac39" + }, + { + "id": "source:libs/telemetry/src/browser/development/announcements.ts", + "kind": "source", + "path": "libs/telemetry/src/browser/development/announcements.ts", + "sha256": "d4a4484064a4d29dbb4dc5663723694917dbe11eaff7b24c167e5b547f1a53ad" + }, + { + "id": "source:libs/telemetry/src/browser/development/collector.ts", + "kind": "source", + "path": "libs/telemetry/src/browser/development/collector.ts", + "sha256": "497d0735d3a232d9e45c35b4bbbc667b5c0c0fbab11c7d9fefbd4384d8180632" + }, + { + "id": "source:libs/telemetry/src/browser/development/runtime.ts", + "kind": "source", + "path": "libs/telemetry/src/browser/development/runtime.ts", + "sha256": "fa744831b8b709d27e1e90ee4c6d5635088e256e0a11eb2879f201913063cf84" + }, + { + "id": "source:libs/telemetry/src/browser/development/session.ts", + "kind": "source", + "path": "libs/telemetry/src/browser/development/session.ts", + "sha256": "fa7c814663e3dd6e73f419949be26e75f3845081d9737755bf437b001f80ddcf" + }, + { + "id": "source:libs/telemetry/src/browser/development/types.ts", + "kind": "source", + "path": "libs/telemetry/src/browser/development/types.ts", + "sha256": "9fbe0ef0bcb5f88d45d4090ebd205838be076cfdfaed399ff21be0f4e9f55313" + }, + { + "id": "source:libs/telemetry/src/browser/properties.ts", + "kind": "source", + "path": "libs/telemetry/src/browser/properties.ts", + "sha256": "fafee46b3b26107bb121488b19fe3cb164483fdbc0805b38c067d8ffa99e50af" + }, + { + "id": "source:libs/telemetry/src/browser/provide.ts", + "kind": "source", + "path": "libs/telemetry/src/browser/provide.ts", + "sha256": "dd2327fa710a6f09c2953316e3e6385de967a5320a65a73684402a6c7f02e53a" + }, + { + "id": "source:libs/telemetry/src/browser/public-api.ts", + "kind": "source", + "path": "libs/telemetry/src/browser/public-api.ts", + "sha256": "095825f7ed15877c25b98b46f205b8df481f94515714327b2b25edab1f869230" + }, + { + "id": "source:libs/telemetry/src/browser/service.ts", + "kind": "source", + "path": "libs/telemetry/src/browser/service.ts", + "sha256": "96bcf66563b7545af355f0e38791eca42078d028f2b90ae03b956b5d5e9c4088" + }, + { + "id": "source:libs/telemetry/src/browser/tokens.ts", + "kind": "source", + "path": "libs/telemetry/src/browser/tokens.ts", + "sha256": "eb20d72c20bedc24605f3dc65c68e47e6fe1ce759099bd4c2e1cfba76d1d771e" + }, + { + "id": "source:libs/telemetry/src/index.ts", + "kind": "source", + "path": "libs/telemetry/src/index.ts", + "sha256": "d958bfb526dced1268b2314a734d19b38d5dfdd2d7f2af95121a52114cee23ec" + }, + { + "id": "source:libs/telemetry/src/node/adapter.ts", + "kind": "source", + "path": "libs/telemetry/src/node/adapter.ts", + "sha256": "d6a518fb109cce9b8edb0016609a4a27eed20ee92fe698b42c550ddb11f67c01" + }, + { + "id": "source:libs/telemetry/src/node/client.ts", + "kind": "source", + "path": "libs/telemetry/src/node/client.ts", + "sha256": "8b4bb17d81b14e326b1f30c4bcd30dd71bf3d303b64589b36e7b5ef0132ca614" + }, + { + "id": "source:libs/telemetry/src/node/disable.ts", + "kind": "source", + "path": "libs/telemetry/src/node/disable.ts", + "sha256": "7a367f85ca780637c050901bfa9f10822d09622afecc941d48e4ce2ed9e11307" + }, + { + "id": "source:libs/telemetry/src/node/index.ts", + "kind": "source", + "path": "libs/telemetry/src/node/index.ts", + "sha256": "27311eee18ae888d0206d3a9680aa28609e9509a217ca949902d0d3c0efaa1ec" + }, + { + "id": "source:libs/telemetry/src/shared/anon-id.ts", + "kind": "source", + "path": "libs/telemetry/src/shared/anon-id.ts", + "sha256": "e79b5a152b8062aa2707faf6e3325560d8b46d0dbd65baa9a760b96b6fad421b" + }, + { + "id": "source:libs/telemetry/src/shared/env.ts", + "kind": "source", + "path": "libs/telemetry/src/shared/env.ts", + "sha256": "3aab492106332ba7f711295cc4938e1ee5023e12c4b89f99427c5f1b18cf58c1" + }, + { + "id": "source:libs/telemetry/src/shared/events.ts", + "kind": "source", + "path": "libs/telemetry/src/shared/events.ts", + "sha256": "c70ca7f4ab195dee247afafbea05d777740545338a1c339e0f8cb212cd896bee" + }, + { + "id": "source:libs/telemetry/src/shared/hash.ts", + "kind": "source", + "path": "libs/telemetry/src/shared/hash.ts", + "sha256": "ed1425d73ac9720c40ff1c175f015f884e0b0bda06113f229c517e3cf18eed3a" + }, + { + "id": "source:libs/telemetry/src/shared/ingest.ts", + "kind": "source", + "path": "libs/telemetry/src/shared/ingest.ts", + "sha256": "7ecbcedf4f6c810c7371a5fd697da32a4174faaf441ffbc97804310b7d63af7a" + }, + { + "id": "source:libs/telemetry/src/shared/personal-email-domains.ts", + "kind": "source", + "path": "libs/telemetry/src/shared/personal-email-domains.ts", + "sha256": "f6223ae9586a351ba6b02abeb157f5c0398d8d5e53939dd907907ad77df3da58" + }, + { + "id": "source:libs/telemetry/src/shared/properties.ts", + "kind": "source", + "path": "libs/telemetry/src/shared/properties.ts", + "sha256": "0e131b1ba5e734d110a22b16c56fc25b0ebc4fe80ae86dad6f2712a2f46ca1c9" + }, + { + "id": "source:libs/telemetry/src/shared/public-api.ts", + "kind": "source", + "path": "libs/telemetry/src/shared/public-api.ts", + "sha256": "cc462a63caf4eb1164269e4d5ca8235135a6d75bdceaea91838356ee51f4e7d7" + }, + { + "id": "source:libs/telemetry/src/shared/sample.ts", + "kind": "source", + "path": "libs/telemetry/src/shared/sample.ts", + "sha256": "2165cb1e1b56edfda66d2385c43924357304ca970ff9ff7ae5744648ab9a3b0a" + }, + { + "id": "source:libs/telemetry/src/test-setup.ts", + "kind": "source", + "path": "libs/telemetry/src/test-setup.ts", + "sha256": "2208f32187a2197d8004cc6672e5afa1f11aa267479ab296cf354aa7e1c0aa15" + }, + { + "id": "source:libs/telemetry/vite.config.mts", + "kind": "source", + "path": "libs/telemetry/vite.config.mts", + "sha256": "21fa44f3fcc8c9e62e3b87e23d79fffa49fb70bbea1e5b4edb750cd017d09b5c" + }, + { + "id": "source:libs/ui-react/src/index.ts", + "kind": "source", + "path": "libs/ui-react/src/index.ts", + "sha256": "b08b2f2dc5b082e6d12583cb0ad3f71606c90a0bef66a1389ce9cbf93730bc85" + }, + { + "id": "source:libs/ui-react/src/lib/control-plane/control-plane-preferences.ts", + "kind": "source", + "path": "libs/ui-react/src/lib/control-plane/control-plane-preferences.ts", + "sha256": "47991ce0c8b155f55c72b4d263eea20b13d5b8013f90f44d4b00357bb5714236" + }, + { + "id": "source:libs/ui-react/src/lib/control-plane/control-plane.tsx", + "kind": "source", + "path": "libs/ui-react/src/lib/control-plane/control-plane.tsx", + "sha256": "a1e87af964541ba81746705c2a057798cacf7a5f9e190682d8289580560955c3" + }, + { + "id": "source:libs/ui-react/src/lib/theme-context.tsx", + "kind": "source", + "path": "libs/ui-react/src/lib/theme-context.tsx", + "sha256": "134f6237bdb4e7b0ade48bb9748e58c90a76bbd0a1a212d76fe3e2409aa21e02" + }, + { + "id": "source:libs/ui-react/src/lib/theme-toggle.tsx", + "kind": "source", + "path": "libs/ui-react/src/lib/theme-toggle.tsx", + "sha256": "4ddba25c2b9ced1dcb93e86066277eb025b218109948038648e469c8094b8711" + }, + { + "id": "source:libs/ui-react/src/lib/themed-frame.tsx", + "kind": "source", + "path": "libs/ui-react/src/lib/themed-frame.tsx", + "sha256": "6304a2d5d036d77439a4a843e5da4ce68ed5dc367f73a9c3c2fa0210948f8e58" + }, + { + "id": "source:libs/ui-react/src/lib/use-embedded-theme.ts", + "kind": "source", + "path": "libs/ui-react/src/lib/use-embedded-theme.ts", + "sha256": "c6d50b762f6c28f4ccf760badb40adf9b3bccdcdf4f768baa9971db19765176b" + }, + { + "id": "source:libs/ui-react/src/lib/utils.ts", + "kind": "source", + "path": "libs/ui-react/src/lib/utils.ts", + "sha256": "9304a861c8673bee09e0f12de31773abbde503b02e59dfd74763ddec2e37cf05" + }, + { + "id": "source:libs/ui-react/vite.config.mts", + "kind": "source", + "path": "libs/ui-react/vite.config.mts", + "sha256": "d81d81cc9d85a97ce620b962622bf28359aa06ca81cf48da0a0883240653b0ae" + }, + { + "id": "source:libs/workspace-react/src/index.ts", + "kind": "source", + "path": "libs/workspace-react/src/index.ts", + "sha256": "73d94e5ff91e0f36165124501981a9cc5628933b4a56c1915709672ca5783340" + }, + { + "id": "source:libs/workspace-react/src/lib/activity-types.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/activity-types.ts", + "sha256": "586f0b43e8c07f86eaafc7fa946e9315ba02443e9001c408a78bf362d6b7d424" + }, + { + "id": "source:libs/workspace-react/src/lib/components/api-mode/api-mode.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/api-mode/api-mode.tsx", + "sha256": "fbce0f2aafab085c70505f5ef1ab57cd7159f6a55838b398162ad872c9cb9764" + }, + { + "id": "source:libs/workspace-react/src/lib/components/code-mode/code-mode.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/code-mode/code-mode.tsx", + "sha256": "73dd092ea1ac482cd3947def92f7987cbcc79bef9a2ff37bf77fec56a870dec5" + }, + { + "id": "source:libs/workspace-react/src/lib/components/code-mode/file-tree.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/code-mode/file-tree.tsx", + "sha256": "07dd2850832e22db9d236df45d7ebdd3cc98a6c04f8b388178ed750d8714efbe" + }, + { + "id": "source:libs/workspace-react/src/lib/components/code-mode/file-tree.utils.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/code-mode/file-tree.utils.ts", + "sha256": "b3c0f9901dcdd9494b3d007e7fcbe8846a01dc6eab8ed8708363f3bfe6432b72" + }, + { + "id": "source:libs/workspace-react/src/lib/components/code-pane/code-pane.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/code-pane/code-pane.tsx", + "sha256": "3e25e486d4a63d4530137b4edc074f47e174b5d6bc85f33fefd93c3db24c7281" + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/activity-panel-boundary.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/control-plane/activity-panel-boundary.tsx", + "sha256": "5cb5351b0b1731c5a0330a335daa56e5d181b9d5cb650d1322d69ea374b7a1a1" + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/activity-panel.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/control-plane/activity-panel.tsx", + "sha256": "7ed9fafb7a990f0a4bb5b4df9538c79f5da64ed8ec28c4c9f27682ee85fc6a8f" + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/cockpit-control-plane.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/control-plane/cockpit-control-plane.tsx", + "sha256": "d0d5c4df2aebae45458d1189a75611c7e6ef464803023c30d3cb99d71d5732f8" + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/control-plane-overflow-menu.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/control-plane/control-plane-overflow-menu.tsx", + "sha256": "7ab7e02d8b36361b513478e5c46e6d7ed0114504c4e06c6e50925d88a5617441" + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/runtime-section.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/control-plane/runtime-section.tsx", + "sha256": "9b5cab3c614e295ad3b28696f9a0d9fd0a81f44fd56f2a45048f17745f00b8ef" + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/runtime-target-settings.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/control-plane/runtime-target-settings.tsx", + "sha256": "259e5bf6a36ef1603616e18d5512180fa15c761853c1de6e4907221d2c453ae8" + }, + { + "id": "source:libs/workspace-react/src/lib/components/mobile-nav-overlay.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/mobile-nav-overlay.tsx", + "sha256": "93475a450e256fb51024c3413e3f981755edec06a4bba5c374ef38d4df2bbc43" + }, + { + "id": "source:libs/workspace-react/src/lib/components/modes/mode-switcher.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/modes/mode-switcher.tsx", + "sha256": "3160d11b93820e36b287e295e17c8c1d04ab38e64f40825ffebcf81071636381" + }, + { + "id": "source:libs/workspace-react/src/lib/components/run-mode/run-mode.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/run-mode/run-mode.tsx", + "sha256": "72da94169c4a6a9ca665bca040ea96647f338ced4604e991b78882604c7d1567" + }, + { + "id": "source:libs/workspace-react/src/lib/components/sidebar/cockpit-sidebar.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/sidebar/cockpit-sidebar.tsx", + "sha256": "c6c2b9a5d8a700a1433e2fe73df9cab328754a057af3b565810985ebc1a47581" + }, + { + "id": "source:libs/workspace-react/src/lib/components/sidebar/language-picker.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/sidebar/language-picker.tsx", + "sha256": "9f586a4daefbc502a6a595fcc67a28e9a7baf9c9ec3d62f609b828fa709a8054" + }, + { + "id": "source:libs/workspace-react/src/lib/components/sidebar/navigation-groups.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/sidebar/navigation-groups.tsx", + "sha256": "a9ad481d5333cdc1a2f4a48087ed82ff3295cb2a781f18a3044c0391e879a307" + }, + { + "id": "source:libs/workspace-react/src/lib/components/ui/tabs.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/components/ui/tabs.tsx", + "sha256": "dfb203074f309230f745ca61044a3f28fd34c5fd0cb3ee7aa5fb8c031a471190" + }, + { + "id": "source:libs/workspace-react/src/lib/host-services.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/host-services.ts", + "sha256": "ad98ef3c81d09eaa254ec8d44cae70afdc7b5bbbd84e3f1b875ee753c9153e27" + }, + { + "id": "source:libs/workspace-react/src/lib/mode-panels.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/mode-panels.tsx", + "sha256": "35ec44957e504bbc3676c36ef705d9568985529ab84e6ae91f885eabf14b6541" + }, + { + "id": "source:libs/workspace-react/src/lib/navigation-labels.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/navigation-labels.ts", + "sha256": "fc1aac9326b91be84812b796e076a0a30c0e1fb292478dba6b56b191dba99a71" + }, + { + "id": "source:libs/workspace-react/src/lib/runtime-contracts.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/runtime-contracts.ts", + "sha256": "e18fb32f1190e1ce07b96c2bda5e5cea5e9b36f02a557047d11e1706e328d34f" + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/runtime-diagnostics.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/runtime/runtime-diagnostics.ts", + "sha256": "7b99216aafbb0dd89900101541236002f564cf01505b81559c89a1cbf48aadb0" + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/runtime-state.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/runtime/runtime-state.ts", + "sha256": "40c1907411f77b230aab076e7c857faddec0e0723393e7307e51c1d44d25f083" + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/runtime-target-provider.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/runtime/runtime-target-provider.tsx", + "sha256": "49616e1fe15c6720905074f404ef71f012d10ce3514fd6b6166dc3771b7082f5" + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/runtime-target-session.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/runtime/runtime-target-session.ts", + "sha256": "060496aa25b3226f8d900c3b24743d4e85fade3ec13199953b42b00d51184102" + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/session-activity.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/runtime/session-activity.ts", + "sha256": "c1799fb3e3aed329061fd275bfe666d48da73c0f172a200874a42be826c8b000" + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/use-runtime-controller.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/runtime/use-runtime-controller.ts", + "sha256": "8befa56de8a9dbb86bfbfcd182fab1a151f2d9b8d009239c8f91f953be9b593e" + }, + { + "id": "source:libs/workspace-react/src/lib/workspace-contracts.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/workspace-contracts.ts", + "sha256": "9339129c87227fc03332c4db0a46055613663b24226f7b8fff138d3413f6fde7" + }, + { + "id": "source:libs/workspace-react/src/lib/workspace-navigation.ts", + "kind": "source", + "path": "libs/workspace-react/src/lib/workspace-navigation.ts", + "sha256": "a66c3318c08641a767212adb75725eb24d92c994760eb11ff64d7604912f8179" + }, + { + "id": "source:libs/workspace-react/src/lib/workspace-provider.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/workspace-provider.tsx", + "sha256": "20d69639854308e34e008b67e51e0eadce3a79b1696b8ef7cdae502bcfb11e8d" + }, + { + "id": "source:libs/workspace-react/src/lib/workspace-shell.tsx", + "kind": "source", + "path": "libs/workspace-react/src/lib/workspace-shell.tsx", + "sha256": "999821ac7637d5463c55d4ee03e899209e1b247606f8932f82f042e037255852" + }, + { + "id": "source:libs/workspace-react/vite.config.mts", + "kind": "source", + "path": "libs/workspace-react/vite.config.mts", + "sha256": "d81d81cc9d85a97ce620b962622bf28359aa06ca81cf48da0a0883240653b0ae" + }, + { + "id": "topic:ag-ui-a2ui-angular", + "kind": "topic", + "path": "cockpit/ag-ui/a2ui/angular/src/index.ts", + "topicId": "ag-ui-a2ui-angular", + "project": "cockpit/ag-ui/a2ui/angular/project.json", + "sha256": "9bb2ae93bf3dfe1cd44a2e203f973b97ce95f98df655498862455b4dc499fc25" + }, + { + "id": "topic:ag-ui-client-tools-angular", + "kind": "topic", + "path": "cockpit/ag-ui/client-tools/angular/src/index.ts", + "topicId": "ag-ui-client-tools-angular", + "project": "cockpit/ag-ui/client-tools/angular/project.json", + "sha256": "e00cd0354a7200ce74932dbd126e55a795cdf9207d6b37660d3a057b6eda9ce2" + }, + { + "id": "topic:ag-ui-interrupts-angular", + "kind": "topic", + "path": "cockpit/ag-ui/interrupts/angular/src/index.ts", + "topicId": "ag-ui-interrupts-angular", + "project": "cockpit/ag-ui/interrupts/angular/project.json", + "sha256": "5bd0185363bf130ccb554dd595c577db4951c6a3188c6c3f716b7e1ffd85a5f2" + }, + { + "id": "topic:ag-ui-json-render-angular", + "kind": "topic", + "path": "cockpit/ag-ui/json-render/angular/src/index.ts", + "topicId": "ag-ui-json-render-angular", + "project": "cockpit/ag-ui/json-render/angular/project.json", + "sha256": "3a0328de317b9aee90c60e15634a16854f1b2da8864498072c600036c699d00b" + }, + { + "id": "topic:ag-ui-streaming-angular", + "kind": "topic", + "path": "cockpit/ag-ui/streaming/angular/src/index.ts", + "topicId": "ag-ui-streaming-angular", + "project": "cockpit/ag-ui/streaming/angular/project.json", + "sha256": "de9180ace2052f51f2800a26dda8892300645c85c2bf0ca056147db2827c6bbe" + }, + { + "id": "topic:ag-ui-subagents-angular", + "kind": "topic", + "path": "cockpit/ag-ui/subagents/angular/src/index.ts", + "topicId": "ag-ui-subagents-angular", + "project": "cockpit/ag-ui/subagents/angular/project.json", + "sha256": "e3bcfedc96858a6cb241d767bb9afdb23c00c87d7c6c7adb65031c5b9ab0f2c2" + }, + { + "id": "topic:ag-ui-tool-views-angular", + "kind": "topic", + "path": "cockpit/ag-ui/tool-views/angular/src/index.ts", + "topicId": "ag-ui-tool-views-angular", + "project": "cockpit/ag-ui/tool-views/angular/project.json", + "sha256": "eb764e22d30bf0d0f69593ad909c44028f29814a9200aefa0237a3d64a521166" + }, + { + "id": "topic:chat-a2ui-angular", + "kind": "topic", + "path": "cockpit/chat/a2ui/angular/src/index.ts", + "topicId": "chat-a2ui-angular", + "project": "cockpit/chat/a2ui/angular/project.json", + "sha256": "d8299669272030dcc0bd9dc711fd631f72c4666f8e5275329f325fe570498d47" + }, + { + "id": "topic:chat-debug-angular", + "kind": "topic", + "path": "cockpit/chat/debug/angular/src/index.ts", + "topicId": "chat-debug-angular", + "project": "cockpit/chat/debug/angular/project.json", + "sha256": "0f823fadf03acf4e033c4680e3a5b8cd1c49146633f5a7357f30e3eac1fcc84b" + }, + { + "id": "topic:chat-generative-ui-angular", + "kind": "topic", + "path": "cockpit/chat/generative-ui/angular/src/index.ts", + "topicId": "chat-generative-ui-angular", + "project": "cockpit/chat/generative-ui/angular/project.json", + "sha256": "38ec1252ae09969fbcc1ce6edfe4559951d09a2ec90b756e1c1050a76ca277e0" + }, + { + "id": "topic:chat-input-angular", + "kind": "topic", + "path": "cockpit/chat/input/angular/src/index.ts", + "topicId": "chat-input-angular", + "project": "cockpit/chat/input/angular/project.json", + "sha256": "743b35d8c9313311aba9937acd1968dbd8fe026bacfbbec520708021df3b854e" + }, + { + "id": "topic:chat-interrupts-angular", + "kind": "topic", + "path": "cockpit/chat/interrupts/angular/src/index.ts", + "topicId": "chat-interrupts-angular", + "project": "cockpit/chat/interrupts/angular/project.json", + "sha256": "926355b2d768178ab40d49e55f6e8955083b0a82052d2a2e9559a460207baa30" + }, + { + "id": "topic:chat-messages-angular", + "kind": "topic", + "path": "cockpit/chat/messages/angular/src/index.ts", + "topicId": "chat-messages-angular", + "project": "cockpit/chat/messages/angular/project.json", + "sha256": "f0c7d6f4aad884fa479f5ddf0866877eec0d894827b8b68d36ea120c1cc05506" + }, + { + "id": "topic:chat-subagents-angular", + "kind": "topic", + "path": "cockpit/chat/subagents/angular/src/index.ts", + "topicId": "chat-subagents-angular", + "project": "cockpit/chat/subagents/angular/project.json", + "sha256": "9adc85273d87d11bd7ac8bcb772781b5ef01647eddf4cc221ee85caaeadca348" + }, + { + "id": "topic:chat-theming-angular", + "kind": "topic", + "path": "cockpit/chat/theming/angular/src/index.ts", + "topicId": "chat-theming-angular", + "project": "cockpit/chat/theming/angular/project.json", + "sha256": "340a50d32da2f0ecb5deb1d9ab253d69e0ea76bbb4ad7842fe04fbc1b5832667" + }, + { + "id": "topic:chat-threads-angular", + "kind": "topic", + "path": "cockpit/chat/threads/angular/src/index.ts", + "topicId": "chat-threads-angular", + "project": "cockpit/chat/threads/angular/project.json", + "sha256": "02d046245f72fd51ea84c180f2ea3990f5c09756ed6e73b1d167d848e51e5160" + }, + { + "id": "topic:chat-timeline-angular", + "kind": "topic", + "path": "cockpit/chat/timeline/angular/src/index.ts", + "topicId": "chat-timeline-angular", + "project": "cockpit/chat/timeline/angular/project.json", + "sha256": "f6668a50c8ee5ae69e5b02d19bb2291227bbbd4d5c3bc68e272580af72455c8d" + }, + { + "id": "topic:chat-tool-calls-angular", + "kind": "topic", + "path": "cockpit/chat/tool-calls/angular/src/index.ts", + "topicId": "chat-tool-calls-angular", + "project": "cockpit/chat/tool-calls/angular/project.json", + "sha256": "2bed815e185651258890e88e3514db23eb4e6c28c5357b170fbb7a35e2f63f13" + }, + { + "id": "topic:deep-agents-filesystem-angular", + "kind": "topic", + "path": "cockpit/deep-agents/filesystem/angular/src/index.ts", + "topicId": "deep-agents-filesystem-angular", + "project": "cockpit/deep-agents/filesystem/angular/project.json", + "sha256": "aeeb4fb36cf973c519ecf1fb65629dac7800cb3325db66ebee89e89c60574a19" + }, + { + "id": "topic:deep-agents-memory-angular", + "kind": "topic", + "path": "cockpit/deep-agents/memory/angular/src/index.ts", + "topicId": "deep-agents-memory-angular", + "project": "cockpit/deep-agents/memory/angular/project.json", + "sha256": "0ea7c1635af0a895addf50a1825fd66b1a4d6337c1a77423df4d82310d691dad" + }, + { + "id": "topic:deep-agents-planning-angular", + "kind": "topic", + "path": "cockpit/deep-agents/planning/angular/src/index.ts", + "topicId": "deep-agents-planning-angular", + "project": "cockpit/deep-agents/planning/angular/project.json", + "sha256": "22409bbfccd2323aef9e691c38d5ad618f911100f9efe6f09d94f1f9c963ff72" + }, + { + "id": "topic:deep-agents-skills-angular", + "kind": "topic", + "path": "cockpit/deep-agents/skills/angular/src/index.ts", + "topicId": "deep-agents-skills-angular", + "project": "cockpit/deep-agents/skills/angular/project.json", + "sha256": "a82938aa5dba244958800952b68064fa248dbeabd528a89c347ec6cfeb831695" + }, + { + "id": "topic:deep-agents-subagents-angular", + "kind": "topic", + "path": "cockpit/deep-agents/subagents/angular/src/index.ts", + "topicId": "deep-agents-subagents-angular", + "project": "cockpit/deep-agents/subagents/angular/project.json", + "sha256": "0ce46083fe7d51f9dbf0fb41525d0639ba4349f041d420699d051ac121728ad3" + }, + { + "id": "topic:langgraph-client-tools-angular", + "kind": "topic", + "path": "cockpit/langgraph/client-tools/angular/src/index.ts", + "topicId": "langgraph-client-tools-angular", + "project": "cockpit/langgraph/client-tools/angular/project.json", + "sha256": "dda897444b5d36f5b251c8f0de3a206bb0859e6a6e9f29cd67cadbfb77308482" + }, + { + "id": "topic:langgraph-deployment-runtime-angular", + "kind": "topic", + "path": "cockpit/langgraph/deployment-runtime/angular/src/index.ts", + "topicId": "langgraph-deployment-runtime-angular", + "project": "cockpit/langgraph/deployment-runtime/angular/project.json", + "sha256": "96b551d75183e7f27a9d7173ce2d4f0c5cf3f5d237a9627cf1e96d98cccd4eaf" + }, + { + "id": "topic:langgraph-durable-execution-angular", + "kind": "topic", + "path": "cockpit/langgraph/durable-execution/angular/src/index.ts", + "topicId": "langgraph-durable-execution-angular", + "project": "cockpit/langgraph/durable-execution/angular/project.json", + "sha256": "75395039fc09235179670f158c58750bcea93a740377f861cb631a51c25329d2" + }, + { + "id": "topic:langgraph-interrupts-angular", + "kind": "topic", + "path": "cockpit/langgraph/interrupts/angular/src/index.ts", + "topicId": "langgraph-interrupts-angular", + "project": "cockpit/langgraph/interrupts/angular/project.json", + "sha256": "eb8a4139426550323dd1523839ad699d50cd90f462fc475b3e6bc77990c8bf98" + }, + { + "id": "topic:langgraph-memory-angular", + "kind": "topic", + "path": "cockpit/langgraph/memory/angular/src/index.ts", + "topicId": "langgraph-memory-angular", + "project": "cockpit/langgraph/memory/angular/project.json", + "sha256": "09b7c247af8848d47a4b834bf0ec7291afc32a9d9f9888dba20b0225cd2d1241" + }, + { + "id": "topic:langgraph-persistence-angular", + "kind": "topic", + "path": "cockpit/langgraph/persistence/angular/src/index.ts", + "topicId": "langgraph-persistence-angular", + "project": "cockpit/langgraph/persistence/angular/project.json", + "sha256": "05e731d9d54ff342429ab8ed7816563397fed6124eed1ee5e103b90aa763e2a1" + }, + { + "id": "topic:langgraph-streaming-angular", + "kind": "topic", + "path": "cockpit/langgraph/streaming/angular/src/index.ts", + "topicId": "langgraph-streaming-angular", + "project": "cockpit/langgraph/streaming/angular/project.json", + "sha256": "a2d8e125e2a8cc2d80f87ce8bf29bf11529042674b70d14837dcdcf2bdc8c0a1" + }, + { + "id": "topic:langgraph-subgraphs-angular", + "kind": "topic", + "path": "cockpit/langgraph/subgraphs/angular/src/index.ts", + "topicId": "langgraph-subgraphs-angular", + "project": "cockpit/langgraph/subgraphs/angular/project.json", + "sha256": "be6bce55cf7b0d6bab6802d0595e1ece4d404bab69075456e87c1e5f29dbdd91" + }, + { + "id": "topic:langgraph-time-travel-angular", + "kind": "topic", + "path": "cockpit/langgraph/time-travel/angular/src/index.ts", + "topicId": "langgraph-time-travel-angular", + "project": "cockpit/langgraph/time-travel/angular/project.json", + "sha256": "6d93c7fc7d88d75ca36a54113f4fe99f2dd4f51917d88f90cca7f89436f6c772" + }, + { + "id": "topic:render-computed-functions-angular", + "kind": "topic", + "path": "cockpit/render/computed-functions/angular/src/index.ts", + "topicId": "render-computed-functions-angular", + "project": "cockpit/render/computed-functions/angular/project.json", + "sha256": "ca39ba412335accb91e0b54c3d5d30736dbd14fc17f90d94057a4e55605b56b4" + }, + { + "id": "topic:render-element-rendering-angular", + "kind": "topic", + "path": "cockpit/render/element-rendering/angular/src/index.ts", + "topicId": "render-element-rendering-angular", + "project": "cockpit/render/element-rendering/angular/project.json", + "sha256": "fa31e6a0162f3c6047a44603571b7fe4cb5d34bb51f6af1038622b273aca6335" + }, + { + "id": "topic:render-registry-angular", + "kind": "topic", + "path": "cockpit/render/registry/angular/src/index.ts", + "topicId": "render-registry-angular", + "project": "cockpit/render/registry/angular/project.json", + "sha256": "6ba990b9dad668b58932992a71f84d21c1805eebd60972f77cfda1f78e768531" + }, + { + "id": "topic:render-repeat-loops-angular", + "kind": "topic", + "path": "cockpit/render/repeat-loops/angular/src/index.ts", + "topicId": "render-repeat-loops-angular", + "project": "cockpit/render/repeat-loops/angular/project.json", + "sha256": "c4382f196dae124e7984aac78012d13cf9b87305be1110a3387c1f958e84eb0c" + }, + { + "id": "topic:render-spec-rendering-angular", + "kind": "topic", + "path": "cockpit/render/spec-rendering/angular/src/index.ts", + "topicId": "render-spec-rendering-angular", + "project": "cockpit/render/spec-rendering/angular/project.json", + "sha256": "eaaec11379371015deb85cd9306a7d928df642cb2f9480c1817fd9ddf7ecb47c" + }, + { + "id": "topic:render-state-management-angular", + "kind": "topic", + "path": "cockpit/render/state-management/angular/src/index.ts", + "topicId": "render-state-management-angular", + "project": "cockpit/render/state-management/angular/project.json", + "sha256": "5d03a18f0127ca32a6d124bbac896e4da977a6d60f3ed11e4a612245b61f8ae1" + }, + { + "id": "topic:runtimes-aws-strands-angular", + "kind": "topic", + "path": "cockpit/runtimes/aws-strands/angular/src/index.ts", + "topicId": "runtimes-aws-strands-angular", + "project": "cockpit/runtimes/aws-strands/angular/project.json", + "sha256": "339fad3127b70a38751045df49898f11f78f0328987852875930e2f6294dc1bd" + }, + { + "id": "topic:runtimes-mastra-angular", + "kind": "topic", + "path": "cockpit/runtimes/mastra/angular/src/index.ts", + "topicId": "runtimes-mastra-angular", + "project": "cockpit/runtimes/mastra/angular/project.json", + "sha256": "b6e225a6090c6510fb6e69c474ad81fee10476b7d8ce356fb20d4022beefca6b" + }, + { + "id": "topic:runtimes-microsoft-agent-framework-angular", + "kind": "topic", + "path": "cockpit/runtimes/microsoft-agent-framework/angular/src/index.ts", + "topicId": "runtimes-microsoft-agent-framework-angular", + "project": "cockpit/runtimes/microsoft-agent-framework/angular/project.json", + "sha256": "b8d272fb10d05fe3a6ae734e98d6f716c434380ea163e487d70c3ea050435659" + } + ] +} diff --git a/scripts/react-parity/dispositions.json b/scripts/react-parity/dispositions.json new file mode 100644 index 000000000..d9a04cd40 --- /dev/null +++ b/scripts/react-parity/dispositions.json @@ -0,0 +1,12860 @@ +{ + "schemaVersion": 1, + "purpose": "Planning ownership for T01. Status is planned until task-specific implementation and verification are recorded; inventory validation is not React parity.", + "rows": [ + { + "id": "asset:libs/a2ui/LICENSE.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/a2ui/README.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/a2ui/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/a2ui/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/a2ui/schemas/README.md", + "taskIds": [ + "T19" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/a2ui/schemas/basic-catalog.json", + "taskIds": [ + "T19" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/a2ui/schemas/common_types.json", + "taskIds": [ + "T19" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/a2ui/schemas/server_to_client.json", + "taskIds": [ + "T19" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/a2ui/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/a2ui/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/LICENSE.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/README.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/maf-hitl-interrupt.sse", + "taskIds": [ + "T05", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/maf-hitl-resume.sse", + "taskIds": [ + "T05", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/mastra-interrupt.sse", + "taskIds": [ + "T05", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/mastra-reinterrupt.sse", + "taskIds": [ + "T05", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/mastra-resume-correct.request.json", + "taskIds": [ + "T05", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/strands-interrupt.sse", + "taskIds": [ + "T05", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/strands-plain-chat.sse", + "taskIds": [ + "T05", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/strands-resume.request.json", + "taskIds": [ + "T05", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/fixtures/runtime-transcripts/subagent-lifecycle.json", + "taskIds": [ + "T05", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/ng-package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/tsconfig.lib.prod.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ag-ui/tsconfig.type-tests.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/CHANGELOG.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/LICENSE.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/NOTICE.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/README.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/debug/ng-package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/ng-package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/src/themes/default-dark.css", + "taskIds": [ + "T22" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/src/themes/default-light.css", + "taskIds": [ + "T22" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/src/themes/material-dark.css", + "taskIds": [ + "T22" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/src/themes/material-light.css", + "taskIds": [ + "T22" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/testing/ng-package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/tsconfig.lib.prod.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/tsconfig.spec.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/chat/tsconfig.type-tests.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-registry/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-registry/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-registry/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-registry/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-runtime-bridge/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-runtime-bridge/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-runtime-bridge/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-runtime-bridge/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-shell/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-shell/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-shell/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-shell/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-telemetry/README.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-telemetry/ng-package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-telemetry/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-telemetry/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-telemetry/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-telemetry/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/cockpit-telemetry/tsconfig.spec.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/design-tokens/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/design-tokens/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/design-tokens/src/lib/theme.css", + "taskIds": [ + "T22" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/design-tokens/src/lib/tokens-dark.css", + "taskIds": [ + "T22" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/design-tokens/src/lib/tokens.css", + "taskIds": [ + "T22" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/design-tokens/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/design-tokens/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/e2e-harness/README.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/e2e-harness/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/e2e-harness/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/example-layouts/ng-package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/example-layouts/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/example-layouts/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/example-layouts/src/theme.css", + "taskIds": [ + "T22" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/example-layouts/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/example-layouts/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/example-layouts/tsconfig.lib.prod.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/example-layouts/tsconfig.spec.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/langgraph/LICENSE.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/langgraph/README.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/langgraph/ng-package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/langgraph/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/langgraph/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/langgraph/test/fixtures/streaming-reasoning-puzzle.json", + "taskIds": [ + "T05", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/langgraph/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/langgraph/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/langgraph/tsconfig.lib.prod.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/langgraph/tsconfig.type-tests.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/middleware/CHANGELOG.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/middleware/README.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/middleware/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/middleware/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/middleware/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/middleware/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/middleware/tsconfig.spec.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/render/LICENSE.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/render/README.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/render/ng-package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/render/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/render/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/render/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/render/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/render/tsconfig.lib.prod.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/render/tsconfig.spec.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/telemetry/LICENSE.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/telemetry/README.md", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/telemetry/ng-package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/telemetry/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/telemetry/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/telemetry/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/telemetry/tsconfig.lib.browser.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/telemetry/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/telemetry/tsconfig.spec.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ui-react/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ui-react/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ui-react/src/lib/.gitkeep", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ui-react/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/ui-react/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/workspace-react/package.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/workspace-react/project.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/workspace-react/src/styles/workspace.css", + "taskIds": [ + "T22" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/workspace-react/tsconfig.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "asset:libs/workspace-react/tsconfig.lib.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/chat-debug.component.ts#ChatDebugComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/debug/chat-debug.tsx", + "reason": "Opt-in public component. Opt-in debug entry point; dock/open persistence and replay/fork callbacks; guard storage during SSR." + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/debug-checkpoint-card.component.ts#DebugCheckpointCardComponent", + "taskIds": [ + "T29" + ], + "treatment": "internal", + "status": "planned", + "target": "libs/react/src/debug/debug-checkpoint-card.tsx", + "reason": "Internal debug view. Internal checkpoint selection view; stable checkpoint identity." + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/debug-state-diff.component.ts#DebugStateDiffComponent", + "taskIds": [ + "T29" + ], + "treatment": "internal", + "status": "planned", + "target": "libs/react/src/debug/debug-state-diff.tsx", + "reason": "Internal debug view. Internal diff presentation; share diff calculation, native semantic rendering." + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/debug-state-inspector.component.ts#DebugStateInspectorComponent", + "taskIds": [ + "T29" + ], + "treatment": "internal", + "status": "planned", + "target": "libs/react/src/debug/debug-state-inspector.tsx", + "reason": "Internal debug view. Internal state tree; safe rendering and bounded large-value display." + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/inspectors/state-inspector.component.ts#StateInspectorComponent", + "taskIds": [ + "T29" + ], + "treatment": "internal", + "status": "planned", + "target": "libs/react/src/debug/state-inspector.tsx", + "reason": "Internal debug view. Internal inspection/copy view; asynchronous clipboard and error state." + }, + { + "id": "component:libs/chat/debug/src/lib/compositions/chat-debug/inspectors/timeline-inspector.component.ts#TimelineInspectorComponent", + "taskIds": [ + "T29" + ], + "treatment": "internal", + "status": "planned", + "target": "libs/react/src/debug/timeline-inspector.tsx", + "reason": "Internal debug view. Internal keyboard timeline; replay/fork identity and previous-state selection." + }, + { + "id": "component:libs/chat/src/lib/a2ui/a2ui-default-fallback.component.ts#A2uiDefaultFallbackComponent", + "taskIds": [ + "T27" + ], + "treatment": "internal", + "status": "planned", + "target": "libs/react/src/a2ui/default-fallback.tsx", + "reason": "Native component. Internal partial-spec fallback; preserve readiness transition without form remount." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/audio-player.component.ts#A2uiAudioPlayerComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/audio-player.tsx", + "reason": "Native component. Native audio controls; safe URL, label, browser-only playback, no autoplay assumption." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/button.component.ts#A2uiButtonComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/button.tsx", + "reason": "Native component. Variant/disabled/loading semantics; child rendering and scoped press action." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/card.component.ts#A2uiCardComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/card.tsx", + "reason": "Native component. Container semantics and child registry rendering." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/check-box.component.ts#A2uiCheckBoxComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/check-box.tsx", + "reason": "Native component. Boolean controlled binding; label/error association and change emission." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/choice-picker.component.ts#A2uiChoicePickerComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/choice-picker.tsx", + "reason": "Native component. Filter/chips/options and selection limits; single/multi-value binding and keyboard behavior." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/column.component.ts#A2uiColumnComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/column.tsx", + "reason": "Native component. Layout properties and nested child rendering; scoped CSS." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/date-time-input.component.ts#A2uiDateTimeInputComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/date-time-input.tsx", + "reason": "Native component. Date/time value conversion, bounds, controlled binding and validation." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/divider.component.ts#A2uiDividerComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/divider.tsx", + "reason": "Native component. Semantic separator and orientation styling." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/icon.component.ts#A2uiIconComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/icon.tsx", + "reason": "Native component. Constrained icon lookup; no arbitrary model HTML injection." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/image.component.ts#A2uiImageComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/image.tsx", + "reason": "Native component. Safe source, alt text, fit/size behavior and failed-image presentation." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/list.component.ts#A2uiListComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/list.tsx", + "reason": "Native component. Template/repeat scope and identity; verify reorder behavior and binding paths." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/modal.component.ts#A2uiModalComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/modal.tsx", + "reason": "Native component. Portal/dialog behavior, trigger children, focus trap/restore and scoped theme." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/row.component.ts#A2uiRowComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/row.tsx", + "reason": "Native component. Horizontal layout/wrap/alignment; nested children and responsive behavior." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/slider.component.ts#A2uiSliderComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/slider.tsx", + "reason": "Native component. Numeric conversion, range/step and accessible value/label binding." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/tabs.component.ts#A2uiTabsComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/tabs.tsx", + "reason": "Native component. Selected index/key policy, tab/panel ARIA and keyboard navigation." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/text-field.component.ts#A2uiTextFieldComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/text-field.tsx", + "reason": "Native component. Text/multiline/password variants, controlled value, constraints and errors." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/text.component.ts#A2uiTextComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/text.tsx", + "reason": "Native component. Text variants, Markdown/content policy and constrained typography." + }, + { + "id": "component:libs/chat/src/lib/a2ui/catalog/video.component.ts#A2uiVideoComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/video.tsx", + "reason": "Native component. Native video controls; safe URL, sizing, loading and accessibility." + }, + { + "id": "component:libs/chat/src/lib/a2ui/surface.component.ts#A2uiSurfaceComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/surface.tsx", + "reason": "Native component. Extract surface/form orchestration; preserve dirty edits, checks, theme identity and wire actions." + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-approval-card/chat-approval-card.component.ts#ChatApprovalCardComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/approval-card.tsx", + "reason": "Native component. Decision UI tied to attempt/run identity; submitting/uncertain/recovery states." + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-interrupt-panel/chat-interrupt-panel.component.ts#ChatInterruptPanelComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/interrupt-panel.tsx", + "reason": "Native component. Action list and custom content; batch completeness and disabled state." + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-popup/chat-popup.component.ts#ChatPopupComponent", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/popup.tsx", + "reason": "Native component. Controlled/uncontrolled open, portal positioning, focus and close behavior; ref methods if needed." + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-sidebar/chat-sidebar.component.ts#ChatSidebarComponent", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/sidebar.tsx", + "reason": "Native component. Controlled/uncontrolled open and docking; focus/layout behavior and custom composition." + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-sidenav/chat-sidenav.component.ts#ChatSidenavComponent", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/sidenav.tsx", + "reason": "Native component. Mode-specific responsive navigation, widths, selected content and controlled state." + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-subagent-card/chat-subagent-card.component.ts#ChatSubagentCardComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/subagent-card.tsx", + "reason": "Native component. Nested child subscription, status color/label and disclosure; stable child identity." + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-timeline-slider/chat-timeline-slider.component.ts#ChatTimelineSliderComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/timeline-slider.tsx", + "reason": "Native component. Checkpoint slider, replay/fork commands, history capabilities and keyboard values." + }, + { + "id": "component:libs/chat/src/lib/compositions/chat-tool-call-card/chat-tool-call-card.component.ts#ChatToolCallCardComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/tool-call-card.tsx", + "reason": "Native component. Arguments/result/status/error rendering; safe JSON and local disclosure." + }, + { + "id": "component:libs/chat/src/lib/compositions/chat/chat.component.ts#ChatComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/chat.tsx", + "reason": "Native component. Thin native composition over content/execution services; slots, event correlation, scroll and message actions." + }, + { + "id": "component:libs/chat/src/lib/markdown/markdown-children.component.ts#MarkdownChildrenComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/children.tsx", + "reason": "Native component. Registry dispatch, stable node identity and scoped citation/table context." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-autolink.component.ts#MarkdownAutolinkComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/autolink.tsx", + "reason": "Native component. Explicit allowed URL schemes and safe navigation; streaming incomplete URLs." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-blockquote.component.ts#MarkdownBlockquoteComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/blockquote.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-citation-reference.component.ts#MarkdownCitationReferenceComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/citation-reference.tsx", + "reason": "Native component. Message-scoped resolution, keyboard/hover preview, stable ARIA identifiers." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-code-block.component.ts#MarkdownCodeBlockComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/code-block.tsx", + "reason": "Native component. Escaped code, language metadata, streaming body identity and overflow." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-document.component.ts#MarkdownDocumentComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/document.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-emphasis.component.ts#MarkdownEmphasisComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/emphasis.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-hard-break.component.ts#MarkdownHardBreakComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/hard-break.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-heading.component.ts#MarkdownHeadingComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/heading.tsx", + "reason": "Native component. Correct heading level and nested inline children; no hydration-unstable IDs." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-html.component.ts#MarkdownHtmlComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/html.tsx", + "reason": "Native component. Preserve escaped-text policy; do not introduce raw HTML rendering." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-image.component.ts#MarkdownImageComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/image.tsx", + "reason": "Native component. Alt/source/title semantics, URL policy and broken-image fallback." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-inline-code.component.ts#MarkdownInlineCodeComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/inline-code.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-link.component.ts#MarkdownLinkComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/link.tsx", + "reason": "Native component. URL policy, inline children/title and external-link behavior." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-list-item.component.ts#MarkdownListItemComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/list-item.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-list.component.ts#MarkdownListComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/list.tsx", + "reason": "Native component. Ordered/unordered/start semantics with stable nested children." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-math.component.ts#MarkdownMathComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/math.tsx", + "reason": "Native component. Lazy optional KaTeX, constrained generated HTML and CSS; loading/failure path." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-paragraph.component.ts#MarkdownParagraphComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/paragraph.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-soft-break.component.ts#MarkdownSoftBreakComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/soft-break.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-strikethrough.component.ts#MarkdownStrikethroughComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/strikethrough.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-strong.component.ts#MarkdownStrongComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/strong.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-table-cell.component.ts#MarkdownTableCellComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/table-cell.tsx", + "reason": "Native component. Header/data cell semantics and alignment." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-table-row.component.ts#MarkdownTableRowComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/table-row.tsx", + "reason": "Native component. Header-row context and stable cell identity during streaming." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-table.component.ts#MarkdownTableComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/table.tsx", + "reason": "Native component. Stable streamed table structure and accessible overflow." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-text.component.ts#MarkdownTextComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/text.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/markdown/views/markdown-thematic-break.component.ts#MarkdownThematicBreakComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/thematic-break.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-citations/chat-citation-preview.component.ts#ChatCitationPreviewComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/citation-preview.tsx", + "reason": "Native component. Interactive preview overlay; hover delay, keyboard access and focus restoration." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-citations/chat-citations-card.component.ts#ChatCitationsCardComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/citations-card.tsx", + "reason": "Native component. Source metadata, image/monogram fallback, safe links and display utilities." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts#ChatCitationCardTemplateDirective", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/citations.tsx", + "reason": "Typed renderCard prop, no directive export. Replace directive with typed citation render prop/component slot." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts#ChatCitationsComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/citations.tsx", + "reason": "Native component. Grouped citation display, expansion and custom card rendering; message scope." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-confirm-dialog/chat-confirm-dialog.component.ts#ChatConfirmDialogComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/confirm-dialog.tsx", + "reason": "Native component. Accessible modal, pending/destructive actions, Escape and focus restoration." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-error/chat-error.component.ts#ChatErrorComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/error.tsx", + "reason": "Native component. Preserve accessible announcements and recovery-specific retry/check/no-action affordances, including absent checkStatus." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-generative-ui/chat-generative-ui.component.ts#ChatGenerativeUiComponent", + "taskIds": [ + "T25" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/generative-ui.tsx", + "reason": "Native component. Spec/registry/state/handler facade; fallback readiness and correlated events." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-genui-skeleton/chat-genui-skeleton.component.ts#ChatGenuiSkeletonComponent", + "taskIds": [ + "T25" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/genui-skeleton.tsx", + "reason": "Native component. Loading placeholder without false mount acknowledgement; reduced motion." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-history-search-palette/chat-history-search-palette.component.ts#ChatHistorySearchPaletteComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/history-search-palette.tsx", + "reason": "Native component. Query/navigation/selection callbacks, highlighted matches, keyboard and focus." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-input/chat-input.component.ts#ChatInputComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/input.tsx", + "reason": "Native component. Draft control, all projection slots, IME/Shift+Enter, input blocking, stop, resize and focus ref." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-interrupt/chat-interrupt.component.ts#ChatInterruptComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/interrupt.tsx", + "reason": "Native component. Capability-aware interrupt projection and custom rendering; no duplicate resume." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-launcher-button/chat-launcher-button.component.ts#ChatLauncherButtonComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/launcher-button.tsx", + "reason": "Native component. Accessible open trigger and badge/status styling." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-message-actions/chat-message-actions.component.ts#ChatMessageActionsComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/message-actions.tsx", + "reason": "Native component. Copy/rate/regenerate target identity, clipboard outcome and custom action slots." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-message-list/chat-message-list.component.ts#ChatMessageListComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/message-list.tsx", + "reason": "Native component. Message-ID ordering, custom role/type render functions, narrow subscriptions." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-message-list/message-template.directive.ts#MessageTemplateDirective", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/message-list.tsx", + "reason": "Typed message renderer prop. Replace role/type template registration with typed renderers/slots." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-message/chat-message.component.ts#ChatMessageComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/message.tsx", + "reason": "Native component. Role/alignment/avatar/content slots and semantic transcript rendering." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-overflow-menu/chat-overflow-menu.component.ts#ChatOverflowMenuComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/overflow-menu.tsx", + "reason": "Native component. Accessible menu positioning, navigation, disabled/destructive items and close rules." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-project-list/chat-project-list.component.ts#ChatProjectListComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/project-list.tsx", + "reason": "Native component. Create/rename/delete async adapters, selection and error/optimistic behavior." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-reasoning/chat-reasoning.component.ts#ChatReasoningComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/reasoning.tsx", + "reason": "Native component. Streaming duration and disclosure without losing manual choice; stable timing." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-scroll-bubble/chat-scroll-bubble.component.ts#ChatScrollBubbleComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/scroll-bubble.tsx", + "reason": "Native component. Scroll/unread modes; user-pinned state and accessible jump action." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-select/chat-select.component.ts#ChatSelectComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/select.tsx", + "reason": "Native component. Controlled selected value, keyboard options, disabled state and label association." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-sidenav-scrim/chat-sidenav-scrim.component.ts#ChatSidenavScrimComponent", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/sidenav-scrim.tsx", + "reason": "Native component. Accessible dismissal behavior, layering and pointer handling." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-subagents/chat-subagents.component.ts#ChatSubagentsComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/subagents.tsx", + "reason": "Native component. Child Map projection into stable records; custom child rendering and independent updates." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-suggestions/chat-suggestions.component.ts#ChatSuggestionsComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/suggestions.tsx", + "reason": "Native component. Suggestion selection/submission semantics and empty/loading behavior." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-thread-list/chat-thread-list.component.ts#ChatThreadListComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/thread-list.tsx", + "reason": "Native component. Rename/delete/archive/pin/project/reorder, pending overlays, keyboard and drag paths." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-timeline/chat-timeline.component.ts#ChatTimelineComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/timeline.tsx", + "reason": "Native component. History capability, custom checkpoint rendering and selection callback." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-call-template.directive.ts#ChatToolCallTemplateDirective", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/tool-calls.tsx", + "reason": "Named/wildcard renderer map. Replace named/wildcard template directive with typed renderer map." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-calls.component.ts#ChatToolCallsComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/tool-calls.tsx", + "reason": "Native component. Message-to-tool indexing, grouping/exclusion, custom templates and subagent association." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-tool-views/chat-tool-views.component.ts#ChatToolViewsComponent", + "taskIds": [ + "T25" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/tool-views.tsx", + "reason": "Native component. Args/result/lifecycle projection and per-call host identity, not name-only result routing." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-trace/chat-trace.component.ts#ChatTraceComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/trace.tsx", + "reason": "Native component. Pending/running/done/error disclosure policy and manual override reset." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-typing-indicator/chat-typing-indicator.component.ts#ChatTypingIndicatorComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/typing-indicator.tsx", + "reason": "Native component. Shared typing selector; accessible announcement policy distinct from token text." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-welcome/chat-welcome-suggestion.component.ts#ChatWelcomeSuggestionComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/welcome-suggestion.tsx", + "reason": "Native component. Label/value/description semantics and selection callback." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-welcome/chat-welcome.component.ts#ChatWelcomeComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/welcome.tsx", + "reason": "Native component. Composable semantic empty-state wrapper." + }, + { + "id": "component:libs/chat/src/lib/primitives/chat-window/chat-window.component.ts#ChatWindowComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/window.tsx", + "reason": "Native component. Structural chat container, scoped tokens and projected sections." + }, + { + "id": "component:libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts#ChatConnectedOverlayDirective", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/internal/overlay.tsx", + "reason": "Ref/portal primitive, no Angular directive. Portal/ref overlay API; positioning, outside click, Escape, resize and cleanup." + }, + { + "id": "component:libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts#ChatOverlayOriginDirective", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/internal/overlay.tsx", + "reason": "Ref/portal primitive, no Angular directive. Replace ElementRef directive with trigger/ref abstraction." + }, + { + "id": "component:libs/chat/src/lib/streaming/streaming-markdown.component.ts#ChatStreamingMdComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/streaming-markdown.tsx", + "reason": "Native component. Neutral per-generation document controller; React subscription and registry rendering." + }, + { + "id": "component:libs/example-layouts/src/lib/example-chat-layout.component.ts#ExampleChatLayoutComponent", + "taskIds": [ + "T33" + ], + "treatment": "internal", + "status": "planned", + "target": "apps/cockpit-react/src/layouts/example-chat-layout.tsx", + "reason": "Private example layout. Private example shell only; port layout/slots without public package commitment." + }, + { + "id": "component:libs/example-layouts/src/lib/example-split-layout.component.ts#ExampleSplitLayoutComponent", + "taskIds": [ + "T33" + ], + "treatment": "internal", + "status": "planned", + "target": "apps/cockpit-react/src/layouts/example-split-layout.tsx", + "reason": "Private example layout. Private split-pane demo shell; responsive layout and projected areas." + }, + { + "id": "component:libs/render/src/lib/default-fallback.component.ts#DefaultFallbackComponent", + "taskIds": [ + "T24" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/render/components/default-fallback.tsx", + "reason": "Native component. Unknown/unready render fallback with safe metadata display. Future React package ownership; not implemented by the empty scaffold." + }, + { + "id": "component:libs/render/src/lib/render-element.component.ts#RenderElementComponent", + "taskIds": [ + "T24" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/render/components/render-element.tsx", + "reason": "Native component. Native registry dispatch, scoped bindings/repeats, readiness latch, actions and host events. Future React package ownership; not implemented by the empty scaffold." + }, + { + "id": "component:libs/render/src/lib/render-spec.component.ts#RenderSpecComponent", + "taskIds": [ + "T24" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/render/components/render-spec.tsx", + "reason": "Native component. Root spec/state lifecycle, registry/context composition, events and cleanup. Future React package ownership; not implemented by the empty scaffold." + }, + { + "id": "config:.github/workflows/ci.yml", + "taskIds": [ + "T02", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:.github/workflows/publish-middleware-npm.yml", + "taskIds": [ + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:.github/workflows/publish-middleware-python.yml", + "taskIds": [ + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:.github/workflows/publish.yml", + "taskIds": [ + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:.github/workflows/release-provenance.yml", + "taskIds": [ + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:apps/website/scripts/generate-agent-context.ts", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:apps/website/scripts/generate-api-docs.ts", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:apps/website/scripts/generate-narrative-docs.ts", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:nx.json", + "taskIds": [ + "T02", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:package-lock.json", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:package.json", + "taskIds": [ + "T02", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:scripts/assemble-examples.ts", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:scripts/cockpit-matrix.mjs", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:scripts/examples/serve-example.ts", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:scripts/verify-release-versions.mjs", + "taskIds": [ + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "config:tsconfig.base.json", + "taskIds": [ + "T02", + "T36" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/a2ui/getting-started/introduction.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/a2ui/getting-started/quickstart.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/a2ui/guides/adapters-and-validation.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/a2ui/guides/data-model.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/a2ui/guides/message-protocol.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/a2ui/reference/parser-resolver-guards.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/a2ui/reference/schema.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/api/fake-agent.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/api/inject-agent.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/api/provide-agent.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/api/to-agent.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/concepts/architecture.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/getting-started/installation.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/getting-started/introduction.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/getting-started/quickstart.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/citations.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/client-tools.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/custom-events.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/deployment.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/fake-agent.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/interrupts.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/json-render.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/subagents.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/testing.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/tool-views.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/guides/troubleshooting.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/ag-ui/reference/event-mapping.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/a2ui/catalog.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/a2ui/overview.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/a2ui/surface-component.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/a2ui/surface-store.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/api/content-classifier.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/api/mock-agent.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/api/parse-tree-store.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-debug.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-input.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-interrupt-panel.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-message-list.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-popup.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-reasoning.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-select.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-sidebar.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-sidenav.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-subagent-card.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-tool-call-card.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-tool-call-template.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-tool-calls.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat-trace.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/components/chat.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/concepts/message-model.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/concepts/primitives-vs-compositions.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/changelog.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/coding-agents.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/installation.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/introduction.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/quickstart.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/getting-started/try-without-a-backend.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/client-tools.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/custom-catalogs.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/error-handling.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/generative-ui.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/layout-modes.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/lifecycle.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/markdown.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/streaming.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/theming.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/thread-routing.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/chat/guides/writing-an-adapter.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/choosing-an-adapter/index.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/capabilities/filesystem.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/capabilities/memory.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/capabilities/planning.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/capabilities/skills.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/capabilities/subagents.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/deep-agents/getting-started/introduction.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/api/fetch-stream-transport.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/api/inject-agent.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/api/langgraph-threads-adapter.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/api/mock-stream-transport.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/api/provide-agent.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/concepts/agent-architecture.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/concepts/agent-contract.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/concepts/angular-signals.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/concepts/langgraph-basics.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/concepts/state-management.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/getting-started/installation.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/getting-started/introduction.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/getting-started/quickstart.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/deployment.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/durable-execution.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/interrupts.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/lifecycle.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/memory.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/persistence.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/streaming.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/subgraphs.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/testing.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/langgraph/guides/time-travel.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/middleware/api/client-tool-helpers.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/middleware/getting-started/introduction.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/middleware/getting-started/quickstart.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/middleware/guides/langgraph-client-tools.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/middleware/guides/python-langgraph.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/api/define-angular-registry.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/api/provide-render.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/api/render-spec-component.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/api/signal-state-store.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/api/views.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/concepts/json-render-vs-a2ui.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/getting-started/installation.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/getting-started/introduction.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/getting-started/quickstart.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/guides/events.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/guides/lifecycle.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/guides/registry.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/guides/repeat-loops.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/guides/specs.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/render/guides/state-store.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/runtimes/aws-strands/how-it-connects.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/runtimes/aws-strands/overview.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/runtimes/aws-strands/quickstart.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/runtimes/getting-started/introduction.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/runtimes/mastra/how-it-connects.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/runtimes/mastra/overview.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/runtimes/mastra/quickstart.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/runtimes/microsoft-agent-framework/how-it-connects.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/runtimes/microsoft-agent-framework/overview.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "doc:apps/website/content/docs/runtimes/microsoft-agent-framework/quickstart.mdx", + "taskIds": [ + "T34", + "T35" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/a2ui/src/index.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/ag-ui/src/public-api.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/chat/debug/public-api.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/chat/src/public-api.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/chat/testing/public-api.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/langgraph/src/public-api.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/middleware/src/langgraph/index.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/render/src/public-api.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/telemetry/src/browser/public-api.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/telemetry/src/index.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/telemetry/src/node/index.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "entry:libs/telemetry/src/shared/public-api.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2UI_BASIC_CATALOG_ID", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2UI_MIME_TYPE", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2UI_WIRE_VERSION", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiAction", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiActionMessage", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiAudioPlayer", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiButton", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCard", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCatalogComponent", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCheck", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCheckBox", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCheckable", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiChildren", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiChoicePicker", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiClientCapabilities", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiClientDataModel", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiColumn", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiComponent", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiComponentBase", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiCreateSurface", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiDateTimeInput", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiDeleteSurface", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiDivider", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiErrorMessage", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiEventAction", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiFunctionAction", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiFunctionCall", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiFunctionContext", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiFunctionImpl", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiFunctionRegistry", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiIcon", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiImage", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiList", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiMessage", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiMessageParser", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiModal", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiPathRef", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiRow", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiScope", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiSlider", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiSurface", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiTabs", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiText", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiTextField", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiTheme", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiUpdateComponents", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiUpdateDataModel", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#A2uiVideo", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#DynamicBoolean", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#DynamicNumber", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#DynamicString", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#DynamicStringList", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#DynamicValue", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#createA2uiFunctionRegistry", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#createA2uiMessageParser", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#deleteByPointer", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#getByPointer", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#isFunctionCall", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#isPathRef", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#resolveDynamic", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/a2ui/src/index.ts#setByPointer", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgUiAgent", + "taskIds": [ + "T14" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgUiFakeAgentConfig", + "taskIds": [ + "T14" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgUiInterruptPersistence", + "taskIds": [ + "T13" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgUiSubmitOptions", + "taskIds": [ + "T14" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgUiThreadRecord", + "taskIds": [ + "T13" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#AgentConfig", + "taskIds": [ + "T14" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#CustomStreamEvent", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#FakeAgent", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#FakeAgentScript", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#InterruptSessionPhase", + "taskIds": [ + "T13" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#InterruptSessionSnapshot", + "taskIds": [ + "T13" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#InterruptTransport", + "taskIds": [ + "T13" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#ResumeAttempt", + "taskIds": [ + "T13" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#ThreadSnapshot", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#ToAgentOptions", + "taskIds": [ + "T14" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#bridgeCitationsState", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#injectAgent", + "taskIds": [ + "T14" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#provideAgent", + "taskIds": [ + "T14" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#provideFakeAgent", + "taskIds": [ + "T14" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#toAgent", + "taskIds": [ + "T14" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#\u0275AG_UI_RUNTIME_OPERATION_REPORTER", + "taskIds": [ + "T14" + ], + "treatment": "internal", + "status": "planned", + "reason": "Existing \u0275-prefixed implementation seam; retain required behavior without promising a new public React API." + }, + { + "id": "export:libs/ag-ui/src/public-api.ts#\u0275AgUiRuntimeOperationFailureReporter", + "taskIds": [ + "T14" + ], + "treatment": "internal", + "status": "planned", + "reason": "Existing \u0275-prefixed implementation seam; retain required behavior without promising a new public React API." + }, + { + "id": "export:libs/chat/debug/public-api.ts#ChatDebugComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/debug/chat-debug.tsx", + "reason": "Opt-in public component. Opt-in debug entry point; dock/open persistence and replay/fork callbacks; guard storage during SSR." + }, + { + "id": "export:libs/chat/debug/public-api.ts#DockPosition", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2UI_BASIC_CATALOG_ID", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2UI_MIME_TYPE", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2UI_WIRE_VERSION", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiAction", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiActionMessage", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiAudioPlayerComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/audio-player.tsx", + "reason": "Native component. Native audio controls; safe URL, label, browser-only playback, no autoplay assumption." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiButtonComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/button.tsx", + "reason": "Native component. Variant/disabled/loading semantics; child rendering and scoped press action." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiCardComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/card.tsx", + "reason": "Native component. Container semantics and child registry rendering." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiCatalogComponent", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiCheck", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiCheckBoxComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/check-box.tsx", + "reason": "Native component. Boolean controlled binding; label/error association and change emission." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiChildren", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiChoicePickerComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/choice-picker.tsx", + "reason": "Native component. Filter/chips/options and selection limits; single/multi-value binding and keyboard behavior." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiClientCapabilities", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiClientDataModel", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiColumnComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/column.tsx", + "reason": "Native component. Layout properties and nested child rendering; scoped CSS." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiComponent", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiComponentBase", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiComponentView", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiDateTimeInputComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/date-time-input.tsx", + "reason": "Native component. Date/time value conversion, bounds, controlled binding and validation." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiDividerComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/divider.tsx", + "reason": "Native component. Semantic separator and orientation styling." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiErrorMessage", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiEventAction", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiFunctionAction", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiFunctionCall", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiIconComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/icon.tsx", + "reason": "Native component. Constrained icon lookup; no arbitrary model HTML injection." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiImageComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/image.tsx", + "reason": "Native component. Safe source, alt text, fit/size behavior and failed-image presentation." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiListComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/list.tsx", + "reason": "Native component. Template/repeat scope and identity; verify reorder behavior and binding paths." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiModalComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/modal.tsx", + "reason": "Native component. Portal/dialog behavior, trigger children, focus trap/restore and scoped theme." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiPathRef", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiRowComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/row.tsx", + "reason": "Native component. Horizontal layout/wrap/alignment; nested children and responsive behavior." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiSliderComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/slider.tsx", + "reason": "Native component. Numeric conversion, range/step and accessible value/label binding." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiSurface", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiSurfaceComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/surface.tsx", + "reason": "Native component. Extract surface/form orchestration; preserve dirty edits, checks, theme identity and wire actions." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiSurfaceState", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiSurfaceStore", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiTabsComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/tabs.tsx", + "reason": "Native component. Selected index/key policy, tab/panel ARIA and keyboard navigation." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiTextComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/text.tsx", + "reason": "Native component. Text variants, Markdown/content policy and constrained typography." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiTextFieldComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/text-field.tsx", + "reason": "Native component. Text/multiline/password variants, controlled value, constraints and errors." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiTheme", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiVideoComponent", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/a2ui/catalog/video.tsx", + "reason": "Native component. Native video controls; safe URL, sizing, loading and accessibility." + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiViewEntry", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#A2uiViews", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AGENT_ERROR_MESSAGES", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AGENT_RECOVERY_DETAILS", + "taskIds": [ + "T03", + "T21", + "T23", + "T35" + ], + "treatment": "shared", + "status": "planned", + "reason": "Public v0.2.0 recovery contract; preserve safe retry/check/none behavior and user-facing error details across framework bindings." + }, + { + "id": "export:libs/chat/src/public-api.ts#AGENT_RECOVERY_MESSAGES", + "taskIds": [ + "T03", + "T21", + "T23", + "T35" + ], + "treatment": "shared", + "status": "planned", + "reason": "Public v0.2.0 recovery contract; preserve safe retry/check/none behavior and user-facing error details across framework bindings." + }, + { + "id": "export:libs/chat/src/public-api.ts#Agent", + "taskIds": [ + "T03", + "T04", + "T05", + "T09", + "T10", + "T11", + "T12", + "T13", + "T14" + ], + "treatment": "shared", + "status": "planned", + "reason": "Preserve optional read-only checkStatus; an uncertain dispatched run must never be resubmitted by a status check. Suppress stale reconciliation completions." + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentCheckpoint", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentCustomEvent", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentError", + "taskIds": [ + "T03", + "T04", + "T21", + "T23", + "T35" + ], + "treatment": "shared", + "status": "planned", + "reason": "Preserve recovery/detail, runtime error identity, safe dehydration, and recovery-specific UI actions." + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentErrorKind", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentEvent", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentInterrupt", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRecovery", + "taskIds": [ + "T03", + "T21", + "T23", + "T35" + ], + "treatment": "shared", + "status": "planned", + "reason": "Public v0.2.0 recovery contract; preserve safe retry/check/none behavior and user-facing error details across framework bindings." + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRef", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRuntimeTelemetryEvent", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRuntimeTelemetryPayload", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRuntimeTelemetryProperties", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentRuntimeTelemetrySink", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentStateUpdateEvent", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentStatus", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentSubmitInput", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentSubmitOptions", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AgentWithHistory", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#AnyFunctionToolDef", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain tool declaration/coordination capability without a schema DSL, automatic argument validation/transformation or JSON Schema derivation. Optional JSON Schema metadata is caller-supplied; current Angular behavior is unchanged and future view/ask presentation remains deferred." + }, + { + "id": "export:libs/chat/src/public-api.ts#AskToolDef", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain tool declaration/coordination capability without a schema DSL, automatic argument validation/transformation or JSON Schema derivation. Optional JSON Schema metadata is caller-supplied; current Angular behavior is unchanged and future view/ask presentation remains deferred." + }, + { + "id": "export:libs/chat/src/public-api.ts#CHAT_LIFECYCLE", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatApprovalAction", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatApprovalCardComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/approval-card.tsx", + "reason": "Native component. Decision UI tied to attempt/run identity; submitting/uncertain/recovery states." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatCitationCardTemplateDirective", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/citations.tsx", + "reason": "Typed renderCard prop, no directive export. Replace directive with typed citation render prop/component slot." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatCitationPreviewComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/citation-preview.tsx", + "reason": "Native component. Interactive preview overlay; hover delay, keyboard access and focus restoration." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatCitationsCardComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/citations-card.tsx", + "reason": "Native component. Source metadata, image/monogram fallback, safe links and display utilities." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatCitationsComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/citations.tsx", + "reason": "Native component. Grouped citation display, expansion and custom card rendering; message scope." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/chat.tsx", + "reason": "Native component. Thin native composition over content/execution services; slots, event correlation, scroll and message actions." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatConfirmDialogComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/confirm-dialog.tsx", + "reason": "Native component. Accessible modal, pending/destructive actions, Escape and focus restoration." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatConnectedOverlayDirective", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/internal/overlay.tsx", + "reason": "Ref/portal primitive, no Angular directive. Portal/ref overlay API; positioning, outside click, Escape, resize and cleanup." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatErrorComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/error.tsx", + "reason": "Native component. Agent error normalization, retry affordance and accessible announcement." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatGenerativeUiComponent", + "taskIds": [ + "T25" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/generative-ui.tsx", + "reason": "Native component. Spec/registry/state/handler facade; fallback readiness and correlated events." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatGenuiSkeletonComponent", + "taskIds": [ + "T25" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/genui-skeleton.tsx", + "reason": "Native component. Loading placeholder without false mount acknowledgement; reduced motion." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatHistorySearchPaletteComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/history-search-palette.tsx", + "reason": "Native component. Query/navigation/selection callbacks, highlighted matches, keyboard and focus." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatInputComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/input.tsx", + "reason": "Native component. Draft control, all projection slots, IME/Shift+Enter, input blocking, stop, resize and focus ref." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatInterruptComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/interrupt.tsx", + "reason": "Native component. Capability-aware interrupt projection and custom rendering; no duplicate resume." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatInterruptPanelComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/interrupt-panel.tsx", + "reason": "Native component. Action list and custom content; batch completeness and disabled state." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatLauncherButtonComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/launcher-button.tsx", + "reason": "Native component. Accessible open trigger and badge/status styling." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatLifecycle", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatMessageActionsComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/message-actions.tsx", + "reason": "Native component. Copy/rate/regenerate target identity, clipboard outcome and custom action slots." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatMessageComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/message.tsx", + "reason": "Native component. Role/alignment/avatar/content slots and semantic transcript rendering." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatMessageListComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/message-list.tsx", + "reason": "Native component. Message-ID ordering, custom role/type render functions, narrow subscriptions." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatMessageRole", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatOverflowMenuComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/overflow-menu.tsx", + "reason": "Native component. Accessible menu positioning, navigation, disabled/destructive items and close rules." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatOverlayOriginDirective", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/internal/overlay.tsx", + "reason": "Ref/portal primitive, no Angular directive. Replace ElementRef directive with trigger/ref abstraction." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatPopupComponent", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/popup.tsx", + "reason": "Native component. Controlled/uncontrolled open, portal positioning, focus and close behavior; ref methods if needed." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatProjectListComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/project-list.tsx", + "reason": "Native component. Create/rename/delete async adapters, selection and error/optimistic behavior." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatReasoningComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/reasoning.tsx", + "reason": "Native component. Streaming duration and disclosure without losing manual choice; stable timing." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatRenderEvent", + "taskIds": [ + "T22", + "T23" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatScrollBubbleComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/scroll-bubble.tsx", + "reason": "Native component. Scroll/unread modes; user-pinned state and accessible jump action." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatScrollBubbleMode", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSelectComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/select.tsx", + "reason": "Native component. Controlled selected value, keyboard options, disabled state and label association." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSelectOption", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSidebarComponent", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/sidebar.tsx", + "reason": "Native component. Controlled/uncontrolled open and docking; focus/layout behavior and custom composition." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSidenavComponent", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/sidenav.tsx", + "reason": "Native component. Mode-specific responsive navigation, widths, selected content and controlled state." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSidenavMode", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSidenavScrimComponent", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/sidenav-scrim.tsx", + "reason": "Native component. Accessible dismissal behavior, layering and pointer handling." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatStreamingMdComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/streaming-markdown.tsx", + "reason": "Native component. Neutral per-generation document controller; React subscription and registry rendering." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSubagentCardComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/subagent-card.tsx", + "reason": "Native component. Nested child subscription, status color/label and disclosure; stable child identity." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSubagentsComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/subagents.tsx", + "reason": "Native component. Child Map projection into stable records; custom child rendering and independent updates." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatSuggestionsComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/suggestions.tsx", + "reason": "Native component. Suggestion selection/submission semantics and empty/loading behavior." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatThreadListComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/thread-list.tsx", + "reason": "Native component. Rename/delete/archive/pin/project/reorder, pending overlays, keyboard and drag paths." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatTimelineComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/timeline.tsx", + "reason": "Native component. History capability, custom checkpoint rendering and selection callback." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatTimelineSliderComponent", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/timeline-slider.tsx", + "reason": "Native component. Checkpoint slider, replay/fork commands, history capabilities and keyboard values." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatToolCallCardComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/tool-call-card.tsx", + "reason": "Native component. Arguments/result/status/error rendering; safe JSON and local disclosure." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatToolCallTemplateContext", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatToolCallTemplateDirective", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/tool-calls.tsx", + "reason": "Named/wildcard renderer map. Replace named/wildcard template directive with typed renderer map." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatToolCallsComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/tool-calls.tsx", + "reason": "Native component. Message-to-tool indexing, grouping/exclusion, custom templates and subagent association." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatToolViewsComponent", + "taskIds": [ + "T25" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/tool-views.tsx", + "reason": "Native component. Args/result/lifecycle projection and per-call host identity, not name-only result routing." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatTraceComponent", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/trace.tsx", + "reason": "Native component. Pending/running/done/error disclosure policy and manual override reset." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatTypingIndicatorComponent", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/typing-indicator.tsx", + "reason": "Native component. Shared typing selector; accessible announcement policy distinct from token text." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatWelcomeComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/welcome.tsx", + "reason": "Native component. Composable semantic empty-state wrapper." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatWelcomeSuggestionComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/welcome-suggestion.tsx", + "reason": "Native component. Label/value/description semantics and selection callback." + }, + { + "id": "export:libs/chat/src/public-api.ts#ChatWindowComponent", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/window.tsx", + "reason": "Native component. Structural chat container, scoped tokens and projected sections." + }, + { + "id": "export:libs/chat/src/public-api.ts#Citation", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationImageVisual", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationMonogramVisual", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationSourceVisual", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationTypeIcon", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationTypeIconVisual", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationTypeMeta", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#CitationsResolverService", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolContinuationLimitEvent", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolContinuationOptions", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolContinuationPolicy", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolDef", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutionGuard", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutionKey", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutionOptions", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutionRecord", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutionStore", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolExecutorOptions", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolLifecycle", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolLifecyclePhase", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolRegistry", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolResult", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolSpec", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain tool declaration/coordination capability without a schema DSL, automatic argument validation/transformation or JSON Schema derivation. Optional JSON Schema metadata is caller-supplied; current Angular behavior is unchanged and future view/ask presentation remains deferred." + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolViewProps", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain tool declaration/coordination capability without a schema DSL, automatic argument validation/transformation or JSON Schema derivation. Optional JSON Schema metadata is caller-supplied; current Angular behavior is unchanged and future view/ask presentation remains deferred." + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolsCapability", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ClientToolsCoordinator", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#CompleteOutcome", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ConnectedPosition", + "taskIds": [ + "T22", + "T23" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ContentBlock", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ContentClassifier", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ContentType", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#DynamicBoolean", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#DynamicNumber", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#DynamicString", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#DynamicStringList", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#DynamicValue", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ElementAccumulationState", + "taskIds": [ + "T18" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#FunctionToolDef", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain tool declaration/coordination capability without a schema DSL, automatic argument validation/transformation or JSON Schema derivation. Optional JSON Schema metadata is caller-supplied; current Angular behavior is unchanged and future view/ask presentation remains deferred." + }, + { + "id": "export:libs/chat/src/public-api.ts#FunctionToolHandlerContext", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#IS_HEADER_ROW", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#InterruptAction", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#MARKDOWN_VIEW_REGISTRY", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownAutolinkComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/autolink.tsx", + "reason": "Native component. Explicit allowed URL schemes and safe navigation; streaming incomplete URLs." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownBlockquoteComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/blockquote.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownChildrenComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/children.tsx", + "reason": "Native component. Registry dispatch, stable node identity and scoped citation/table context." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownCitationReferenceComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/citation-reference.tsx", + "reason": "Native component. Message-scoped resolution, keyboard/hover preview, stable ARIA identifiers." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownCodeBlockComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/code-block.tsx", + "reason": "Native component. Escaped code, language metadata, streaming body identity and overflow." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownDocumentComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/document.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownEmphasisComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/emphasis.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownHardBreakComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/hard-break.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownHeadingComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/heading.tsx", + "reason": "Native component. Correct heading level and nested inline children; no hydration-unstable IDs." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownHtmlComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/html.tsx", + "reason": "Native component. Preserve escaped-text policy; do not introduce raw HTML rendering." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownImageComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/image.tsx", + "reason": "Native component. Alt/source/title semantics, URL policy and broken-image fallback." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownInlineCodeComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/inline-code.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownLinkComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/link.tsx", + "reason": "Native component. URL policy, inline children/title and external-link behavior." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownListComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/list.tsx", + "reason": "Native component. Ordered/unordered/start semantics with stable nested children." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownListItemComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/list-item.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownMathComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/math.tsx", + "reason": "Native component. Lazy optional KaTeX, constrained generated HTML and CSS; loading/failure path." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownParagraphComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/paragraph.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownSoftBreakComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/soft-break.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownStrikethroughComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/strikethrough.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownStrongComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/strong.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownTableCellComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/table-cell.tsx", + "reason": "Native component. Header/data cell semantics and alignment." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownTableComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/table.tsx", + "reason": "Native component. Stable streamed table structure and accessible overflow." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownTableRowComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/table-row.tsx", + "reason": "Native component. Header-row context and stable cell identity during streaming." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownTextComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/text.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#MarkdownThematicBreakComponent", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/markdown/views/thematic-break.tsx", + "reason": "Native component. Native semantic Markdown node and recursive children through the typed registry; preserve streaming identity and custom overrides." + }, + { + "id": "export:libs/chat/src/public-api.ts#Message", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#MessageDelivery", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#MessageTemplateDirective", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/chat/message-list.tsx", + "reason": "Typed message renderer prop. Replace role/type template registration with typed renderers/slots." + }, + { + "id": "export:libs/chat/src/public-api.ts#MessageTemplateType", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#MockAgent", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#MockAgentOptions", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#OverflowMenuItem", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#OverlayPositionResult", + "taskIds": [ + "T22", + "T23" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ParseTreeStore", + "taskIds": [ + "T18" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#PartialArgsBridge", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#Project", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ProjectActionAdapter", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ResolvedCitation", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#Role", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#STREAMING_MARKDOWN_CONTRACT_VIOLATION_POLICY", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#SelectPendingClientToolCallsInput", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#StandardSchemaInferInput", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "excluded", + "status": "planned", + "reason": "Do not migrate validator/inference contracts into a shared tool/schema layer. Argument validation belongs to callers; optional JSON Schema metadata is supplied directly. Current Angular behavior, protocol schema assets, form validation and transport decoding are unaffected." + }, + { + "id": "export:libs/chat/src/public-api.ts#StandardSchemaInferOutput", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "excluded", + "status": "planned", + "reason": "Do not migrate validator/inference contracts into a shared tool/schema layer. Argument validation belongs to callers; optional JSON Schema metadata is supplied directly. Current Angular behavior, protocol schema assets, form validation and transport decoding are unaffected." + }, + { + "id": "export:libs/chat/src/public-api.ts#StandardSchemaV1", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "excluded", + "status": "planned", + "reason": "Do not migrate validator/inference contracts into a shared tool/schema layer. Argument validation belongs to callers; optional JSON Schema metadata is supplied directly. Current Angular behavior, protocol schema assets, form validation and transport decoding are unaffected." + }, + { + "id": "export:libs/chat/src/public-api.ts#StreamingMarkdownContractViolationPolicy", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#StreamingMarkdownDocument", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#Subagent", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#SubagentStatus", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#Thread", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ThreadActionAdapter", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ThreadMatch", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ThreadRoutingConfig", + "taskIds": [ + "T29" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/chat/src/public-api.ts#ToolArgs", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ToolCall", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ToolCallInfo", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ToolCallStatus", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#TraceState", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ViewProps", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ViewRegistry", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ViewToolDef", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain tool declaration/coordination capability without a schema DSL, automatic argument validation/transformation or JSON Schema derivation. Optional JSON Schema metadata is caller-supplied; current Angular behavior is unchanged and future view/ask presentation remains deferred." + }, + { + "id": "export:libs/chat/src/public-api.ts#a2uiBasicCatalog", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#a2uiClientCapabilities", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#action", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#ask", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#buildA2uiActionMessage", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#cacheplaneMarkdownViews", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#cancelledClientToolResult", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#citationSourceVisual", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#citationTypeLabel", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#citationTypeMeta", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#clientToolGuardFailureResult", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#completeDelivery", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#createA2uiSurfaceStore", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#createAgentRef", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#createContentClassifier", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#createParseTreeStore", + "taskIds": [ + "T18" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#createPartialArgsBridge", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#defaultInterruptedClientToolResult", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#deriveDomain", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#deriveJsonSchema", + "taskIds": [ + "T15" + ], + "treatment": "excluded", + "status": "planned", + "reason": "Omitted from the new tool contract: no validator-to-JSON-Schema conversion or schema DSL. Callers may supply optional JSON Schema metadata; current Angular conversion remains unchanged." + }, + { + "id": "export:libs/chat/src/public-api.ts#deriveMonogram", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#deriveSourceType", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#emitBinding", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#executeFunctionTool", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain handler execution, cancellation context and outcome normalization. Omit automatic validateArgs validation/transformation; pass arguments to caller-owned handlers. This is future work; current Angular execution remains unchanged." + }, + { + "id": "export:libs/chat/src/public-api.ts#extractErrorMessage", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#formatDuration", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#formatPublished", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#getInterrupt", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#getMessageType", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#injectThreadRouting", + "taskIds": [ + "T29" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/chat/src/public-api.ts#isAbortError", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#isAssistantMessage", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#isFunctionCall", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#isPathRef", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#isSystemMessage", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#isToolMessage", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#isTyping", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#isUserMessage", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#markdownDocument", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#messageContent", + "taskIds": [ + "T22", + "T23" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#mockAgent", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#monogramColor", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#monogramHue", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#normalizeEnvelopeArgs", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#normalizeViewEntry", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#renderMarkdown", + "taskIds": [ + "T18" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#selectPendingClientToolCalls", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#shouldClaimBeforeExecute", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#startClientToolExecutor", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#staticDelivery", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#statusColor", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#streamingDelivery", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#submitMessage", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#toAgentError", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#toClientToolSpecs", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#toRenderRegistry", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#tools", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#validateArgs", + "taskIds": [ + "T15" + ], + "treatment": "excluded", + "status": "planned", + "reason": "Omitted from the new tool contract: handlers own argument validation and transformation. Existing Angular validation remains unchanged; this is a migration omission, not implemented parity." + }, + { + "id": "export:libs/chat/src/public-api.ts#view", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#views", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#withViews", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/src/public-api.ts#withoutViews", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#AbstractEvent", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#FakeAgentConfig", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#INTERRUPT_CONFORMANCE_BATCH", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#InterruptConformanceHarness", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#InterruptConformanceRequest", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#REASONING_FIXTURE_EVENTS", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#REASONING_FIXTURE_MESSAGE_ID", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#REASONING_FIXTURE_REASONING", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#REASONING_FIXTURE_RESPONSE", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#assertReasoningFixtureMessages", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#runAgentConformance", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#runAgentWithHistoryConformance", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/chat/testing/public-api.ts#runInterruptConformance", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AGENT_LIFECYCLE", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentBranchTree", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentBranchTreeFork", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentBranchTreeNode", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentConfig", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentLifecycle", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentLifecycleRegistry", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentOptions", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentQueue", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentQueueEntry", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#AgentTransport", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#BagTemplate", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#CustomStreamEvent", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#FakeStreamTransport", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#FetchStreamTransport", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#InferBag", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#Interrupt", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LANGGRAPH_CLIENT", + "taskIds": [ + "T11" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LANGGRAPH_CLIENT_OPTIONS", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LANGGRAPH_THREADS_CONFIG", + "taskIds": [ + "T11" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphAgent", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphClientOptions", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphMultitaskStrategy", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphSubmitOptions", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphThreadsAdapter", + "taskIds": [ + "T11" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#LangGraphThreadsConfig", + "taskIds": [ + "T11" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#MockAgentTransport", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#MockLangGraphAgent", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#ResourceStatus", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#StreamEvent", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#SubagentStreamRef", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#SubmitOptions", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#ThreadState", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#createLangGraphClient", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#extractCitations", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#injectAgent", + "taskIds": [ + "T11" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/langgraph/src/public-api.ts#mockLangGraphAgent", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#provideAgent", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#provideFakeAgent", + "taskIds": [ + "T08" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/langgraph/src/public-api.ts#refreshOnRunEnd", + "taskIds": [ + "T11" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#refreshOnTransition", + "taskIds": [ + "T11" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#toAbsoluteApiUrl", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/langgraph/src/public-api.ts#\u0275LANGGRAPH_RUNTIME_OPERATION_REPORTER", + "taskIds": [ + "T08" + ], + "treatment": "internal", + "status": "planned", + "reason": "Existing \u0275-prefixed implementation seam; retain required behavior without promising a new public React API." + }, + { + "id": "export:libs/langgraph/src/public-api.ts#\u0275LangGraphRuntimeOperationFailureReporter", + "taskIds": [ + "T08" + ], + "treatment": "internal", + "status": "planned", + "reason": "Existing \u0275-prefixed implementation seam; retain required behavior without promising a new public React API." + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#BaseMessage", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#BindableModel", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolExecutionKey", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolExecutionRecord", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolExecutionStatus", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolExecutionStore", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolResult", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolResultMessage", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolSpec", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#ClientToolsState", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#OpenAIFunctionTool", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#PostgresClientToolExecutionStoreOptions", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#PostgresRow", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#PostgresTaggedSql", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#RecordClientToolResultsInput", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#RecordClientToolResultsResult", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#THREADPLANE_CLIENT_TOOL_EXECUTIONS_SCHEMA", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#bindClientTools", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#clientToolNames", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#clientToolSpecs", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#clientToolsChannel", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#clientToolsRouter", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#createInMemoryClientToolExecutionStore", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#createPostgresClientToolExecutionStore", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#extractClientToolResultMessages", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#filterDuplicateClientToolResultMessages", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#hasClientToolCall", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#hasServerToolCall", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#lastMessage", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#lookupClientToolExecutions", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#recordClientToolResults", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/middleware/src/langgraph/index.ts#routeAfterAgent", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#AngularComponentInputs", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#AngularComponentRenderer", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#AngularRegistry", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#DefaultFallbackComponent", + "taskIds": [ + "T24" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/render/components/default-fallback.tsx", + "reason": "Native component. Unknown/unready render fallback with safe metadata display. Future React package ownership; not implemented by the empty scaffold." + }, + { + "id": "export:libs/render/src/public-api.ts#RENDER_CONFIG", + "taskIds": [ + "T24" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/render/src/public-api.ts#RENDER_CONTEXT", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RENDER_HOST", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RENDER_LIFECYCLE", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#REPEAT_SCOPE", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RenderConfig", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RenderContext", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RenderElementComponent", + "taskIds": [ + "T24" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/render/components/render-element.tsx", + "reason": "Native component. Native registry dispatch, scoped bindings/repeats, readiness latch, actions and host events. Future React package ownership; not implemented by the empty scaffold." + }, + { + "id": "export:libs/render/src/public-api.ts#RenderEvent", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RenderHandlerEvent", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RenderHost", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RenderLifecycle", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RenderLifecycleEvent", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RenderResultEvent", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RenderSpecComponent", + "taskIds": [ + "T24" + ], + "treatment": "react", + "status": "planned", + "target": "libs/react/src/render/components/render-spec.tsx", + "reason": "Native component. Root spec/state lifecycle, registry/context composition, events and cleanup. Future React package ownership; not implemented by the empty scaffold." + }, + { + "id": "export:libs/render/src/public-api.ts#RenderStateChangeEvent", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RenderViewEntry", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#RepeatScope", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#SignalStateStore", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#StandardSchemaInferInput", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "excluded", + "status": "planned", + "reason": "Do not migrate validator/inference contracts into a shared tool/schema layer. Argument validation belongs to callers; optional JSON Schema metadata is supplied directly. Current Angular behavior, protocol schema assets, form validation and transport decoding are unaffected." + }, + { + "id": "export:libs/render/src/public-api.ts#StandardSchemaInferOutput", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "excluded", + "status": "planned", + "reason": "Do not migrate validator/inference contracts into a shared tool/schema layer. Argument validation belongs to callers; optional JSON Schema metadata is supplied directly. Current Angular behavior, protocol schema assets, form validation and transport decoding are unaffected." + }, + { + "id": "export:libs/render/src/public-api.ts#StandardSchemaV1", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "excluded", + "status": "planned", + "reason": "Do not migrate validator/inference contracts into a shared tool/schema layer. Argument validation belongs to callers; optional JSON Schema metadata is supplied directly. Current Angular behavior, protocol schema assets, form validation and transport decoding are unaffected." + }, + { + "id": "export:libs/render/src/public-api.ts#StateChangeRecord", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#VIEW_REGISTRY", + "taskIds": [ + "T24" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/render/src/public-api.ts#ViewRegistry", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#defineAngularRegistry", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#injectRenderHost", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#overrideViews", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#provideRender", + "taskIds": [ + "T24" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/render/src/public-api.ts#provideViews", + "taskIds": [ + "T24" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/render/src/public-api.ts#signalStateStore", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#toRenderRegistry", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#views", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#withViews", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/render/src/public-api.ts#withoutViews", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#CaptureConfig", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#DEVELOPMENT_COLLECTION_POLICY", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#DevelopmentMilestone", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#DevelopmentRuntime", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#DevelopmentRuntimeOptions", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#THREADPLANE_TELEMETRY_CONFIG", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneBrowserEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneBrowserRuntimeTelemetry", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneBrowserStreamErrorTelemetry", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneBrowserStreamTelemetry", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneTelemetryConfig", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneTelemetryEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneTelemetryEventPayload", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneTelemetryService", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#ThreadplaneTelemetrySink", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#createDevelopmentRuntime", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#getDevelopmentCollectionDiagnostics", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#isDevelopmentRuntimeEnabled", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#isLocalAnalyticsHost", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#provideThreadplaneTelemetry", + "taskIds": [ + "T17" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#registerDevelopmentRuntimePolicy", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#setDevelopmentCollectionEnabled", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/browser/public-api.ts#shouldCaptureAnalytics", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/index.ts#ThreadplaneBrowserEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/index.ts#ThreadplaneEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/index.ts#ThreadplaneNodeEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/index.ts#getAnonId", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/index.ts#getDisableReason", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/index.ts#isTelemetryDisabled", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/index.ts#sha256", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/index.ts#shouldSample", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#CaptureResult", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#RuntimeInstanceTelemetry", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#RuntimeRequestTelemetry", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#StreamTelemetry", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureRuntimeInstanceCreated", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureRuntimeRequestCreated", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureStreamEnded", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureStreamErrored", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#captureStreamStarted", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/node/index.ts#disableTelemetry", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#PERSONAL_EMAIL_DOMAINS", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#ParsedTelemetryEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#ThreadplaneBrowserEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#ThreadplaneEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#ThreadplaneNodeEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#getEmailDomain", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#getSourcePage", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#isPersonalEmailDomain", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#normalizePostHogHost", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#parseTelemetryEvent", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "export:libs/telemetry/src/shared/public-api.ts#toSafeAnalyticsString", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/a2ui/src/index.ts", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/a2ui/src/lib/functions.ts", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/a2ui/src/lib/guards.ts", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/a2ui/src/lib/parser.ts", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/a2ui/src/lib/pointer.ts", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/a2ui/src/lib/resolve.ts", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/a2ui/src/lib/types.ts", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/a2ui/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/.install-collector/development-install.d.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/.install-collector/development-install.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/eslint.config.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/install/postinstall.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/bridge-citations-state.ts", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/client-tools.ts", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/internal/apply-patch.ts", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/interrupt-persistence.ts", + "taskIds": [ + "T13" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/interrupt-session.ts", + "taskIds": [ + "T13" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/interrupt-session.types.ts", + "taskIds": [ + "T13" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/package-version.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/provide-agent.ts", + "taskIds": [ + "T14" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "source:libs/ag-ui/src/lib/reducer.ts", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/run-state-transaction.ts", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/runtime-operation-reporter.ts", + "taskIds": [ + "T14" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/testing/fake-agent.ts", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/lib/testing/provide-fake-agent.ts", + "taskIds": [ + "T14" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "source:libs/ag-ui/src/lib/to-agent.ts", + "taskIds": [ + "T12", + "T13", + "T14", + "T38" + ], + "treatment": "shared", + "status": "planned", + "reason": "Preserve v0.2.0 terminal/abort/read-error distinctions and safe interrupted-run reconciliation before extraction." + }, + { + "id": "source:libs/ag-ui/src/public-api.ts", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/test-setup.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/src/testing/type-assert.ts", + "taskIds": [ + "T12" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/ag-ui/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/chat/.install-collector/development-install.d.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/chat/.install-collector/development-install.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/public-api.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/chat-debug-root-styles.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/chat-debug-tokens.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/chat-debug.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/debug-agent.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/debug-checkpoint-card.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/debug-state-diff.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/debug-state-inspector.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/debug-utils.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/inspectors/state-inspector.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/inspectors/timeline-inspector.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/persistence.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/debug/src/lib/compositions/chat-debug/state-diff.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/eslint.config.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/chat/install/postinstall.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/chat/src/index.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/a2ui-default-fallback.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/action-label.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/build-action-message.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/capabilities.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/audio-player.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/button.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/card.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/check-box.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/choice-picker.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/column.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/date-time-input.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/divider.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/emit-binding.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/icon.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/image.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/index.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/list.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/modal.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/row.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/slider.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/tabs.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/text-field.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/text.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/catalog/video.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/component-view.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/envelope-normalizer.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/extract-bindings.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/partial-args-bridge.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/surface-store.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/surface-to-spec.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/surface.component.ts", + "taskIds": [ + "T27" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/a2ui/views.ts", + "taskIds": [ + "T19", + "T27" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-checkpoint.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-error.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-event.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-interrupt.ts", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-ref.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-status.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-submit.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/agent-with-history.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/agent.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/citation-display.ts", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/citation.ts", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/content-block.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/index.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/message-delivery.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/message.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/runtime-telemetry.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/subagent.ts", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/to-agent-error.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/agent/tool-call.ts", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/chat.types.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/client-tools/client-tool-execution-guard.ts", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/client-tools/client-tool-executor.ts", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/client-tools/client-tools-capability.ts", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/client-tools/client-tools-coordinator.ts", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain tool declaration/coordination capability without a schema DSL, automatic argument validation/transformation or JSON Schema derivation. Optional JSON Schema metadata is caller-supplied; current Angular behavior is unchanged and future view/ask presentation remains deferred." + }, + { + "id": "source:libs/chat/src/lib/client-tools/component-inputs.ts", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/client-tools/execute.ts", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain handler execution, cancellation context and outcome normalization. Omit automatic validateArgs validation/transformation; pass arguments to caller-owned handlers. This is future work; current Angular execution remains unchanged." + }, + { + "id": "source:libs/chat/src/lib/client-tools/index.ts", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/client-tools/select-pending-client-tool-calls.ts", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/client-tools/to-json-schema.ts", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain the tool metadata contract with optional caller-supplied JSON Schema. The deriveJsonSchema converter and its Zod ownership are deliberately omitted; the corresponding export is explicitly excluded. Existing Angular implementation remains unchanged." + }, + { + "id": "source:libs/chat/src/lib/client-tools/tool-def.ts", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned", + "reason": "Retain tool declaration/coordination capability without a schema DSL, automatic argument validation/transformation or JSON Schema derivation. Optional JSON Schema metadata is caller-supplied; current Angular behavior is unchanged and future view/ask presentation remains deferred." + }, + { + "id": "source:libs/chat/src/lib/client-tools/tools.ts", + "taskIds": [ + "T15" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-approval-card/chat-approval-card.component.ts", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-interrupt-panel/chat-interrupt-panel.component.ts", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-popup/chat-popup.component.ts", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-sidebar/chat-sidebar.component.ts", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-sidenav/chat-debug-gate.ts", + "taskIds": [ + "T30" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-sidenav/chat-sidenav.component.ts", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-subagent-card/chat-subagent-card.component.ts", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-timeline-slider/chat-timeline-slider.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat-tool-call-card/chat-tool-call-card.component.ts", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat/chat-render-event.ts", + "taskIds": [ + "T22", + "T23" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/chat/chat.component.ts", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/compositions/shared/message-utils.ts", + "taskIds": [ + "T22", + "T23" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/internals/prettify.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/lifecycle.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/cacheplane-markdown-views.ts", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/citations-resolver.service.ts", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/katex-loader.ts", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/markdown-children.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/markdown-table-row.token.ts", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/markdown-view-registry.ts", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-autolink.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-blockquote.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-citation-reference.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-code-block.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-document.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-emphasis.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-hard-break.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-heading.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-html.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-image.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-inline-code.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-link.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-list-item.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-list.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-math.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-paragraph.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-soft-break.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-strikethrough.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-strong.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-table-cell.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-table-row.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-table.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-text.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/markdown/views/markdown-thematic-break.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/package-version.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-citations/chat-citation-preview.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-citations/chat-citations-card.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-citations/chat-citations.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-citations/index.ts", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-confirm-dialog/chat-confirm-dialog.component.ts", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-error/chat-error.component.ts", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-generative-ui/chat-generative-ui.component.ts", + "taskIds": [ + "T25" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-generative-ui/normalize-json-render-spec.ts", + "taskIds": [ + "T20", + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-genui-skeleton/chat-genui-skeleton.component.ts", + "taskIds": [ + "T25" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-history-search-palette/chat-history-search-palette.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-input/chat-input.component.ts", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-interrupt/chat-interrupt.component.ts", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-launcher-button/chat-launcher-button.component.ts", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-message-actions/chat-message-actions.component.ts", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-message-list/chat-message-list.component.ts", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-message-list/message-template.directive.ts", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-message/chat-message.component.ts", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-overflow-menu/chat-overflow-menu.component.ts", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-project-list/chat-project-list.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-reasoning/chat-reasoning.component.ts", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-scroll-bubble/chat-scroll-bubble.component.ts", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-select/chat-select.component.ts", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-sidenav-scrim/chat-sidenav-scrim.component.ts", + "taskIds": [ + "T30" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-subagents/chat-subagents.component.ts", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-suggestions/chat-suggestions.component.ts", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-thread-list/chat-thread-list.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-timeline/chat-timeline.component.ts", + "taskIds": [ + "T29" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-call-template.directive.ts", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-tool-calls/chat-tool-calls.component.ts", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-tool-calls/group-summary.ts", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-tool-calls/resolve-message-tool-calls.ts", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-tool-views/chat-tool-views.component.ts", + "taskIds": [ + "T25" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-trace/chat-trace.component.ts", + "taskIds": [ + "T28" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-typing-indicator/chat-typing-indicator.component.ts", + "taskIds": [ + "T23" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-welcome/chat-welcome-suggestion.component.ts", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-welcome/chat-welcome.component.ts", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/chat-window/chat-window.component.ts", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts", + "taskIds": [ + "T22" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/overlay/connected-position.ts", + "taskIds": [ + "T22", + "T23" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/primitives/overlay/overlay-container.ts", + "taskIds": [ + "T22", + "T23" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/routing/thread-routing.ts", + "taskIds": [ + "T29" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "source:libs/chat/src/lib/streaming/content-classifier.ts", + "taskIds": [ + "T19" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/streaming/markdown-render.ts", + "taskIds": [ + "T18" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/streaming/parse-tree-store.ts", + "taskIds": [ + "T18" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/streaming/streaming-markdown.component.ts", + "taskIds": [ + "T26" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/streaming/trace.ts", + "taskIds": [ + "T18" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-citations.styles.ts", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-confirm-dialog.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-error.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-generative-ui.styles.ts", + "taskIds": [ + "T20", + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-history-search-palette.styles.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-icons.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-input.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-interrupt.styles.ts", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-launcher-button.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-markdown.styles.ts", + "taskIds": [ + "T18", + "T26" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-message-actions.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-message-list.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-message.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-overflow-menu.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-project-list.styles.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-reasoning.styles.ts", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-scroll-bubble.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-select.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-sidenav.styles.ts", + "taskIds": [ + "T30" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-suggestions.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-thread-list.styles.ts", + "taskIds": [ + "T29" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-tokens.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-trace.styles.ts", + "taskIds": [ + "T28" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-typing-indicator.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-welcome.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/styles/chat-window.styles.ts", + "taskIds": [ + "T22" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/testing/mock-agent.ts", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/lib/utils/format-duration.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/public-api.ts", + "taskIds": [ + "T03", + "T04" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/src/test-setup.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/chat/src/testing/type-assert.ts", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/testing/agent-conformance.ts", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/testing/agent-with-history-conformance.ts", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/testing/fake-agent-config.ts", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/testing/interrupt-conformance.ts", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/testing/public-api.ts", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/testing/reasoning-fixture.ts", + "taskIds": [ + "T05", + "T31" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/chat/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/cockpit-registry/eslint.config.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/cockpit-registry/src/index.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-registry/src/lib/capability-registry.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-registry/src/lib/content-descriptors.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-registry/src/lib/docs-links.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-registry/src/lib/manifest.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-registry/src/lib/manifest.types.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-registry/src/lib/resolve-language.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-registry/src/lib/validate-manifest.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-registry/src/lib/workspace-resolution.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-registry/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/cockpit-runtime-bridge/eslint.config.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/cockpit-runtime-bridge/src/index.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-runtime-bridge/src/lib/generated-runtime-parent-origins.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-runtime-bridge/src/lib/install-runtime-bridge.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-runtime-bridge/src/lib/protocol.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-runtime-bridge/src/lib/runtime-parent-origins.ts", + "taskIds": [ + "T32", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-runtime-bridge/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/cockpit-shell/src/index.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-shell/src/lib/capability-contract.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-shell/src/lib/extract-docs.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-shell/src/lib/route-home.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-shell/src/lib/shell-contracts.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-shell/src/lib/workspace-content.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-shell/src/lib/workspace-presentation.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-shell/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/cockpit-telemetry/eslint.config.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/cockpit-telemetry/src/index.ts", + "taskIds": [ + "T17" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/activation-aggregator.ts", + "taskIds": [ + "T17" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/cockpit-telemetry.service.ts", + "taskIds": [ + "T17" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/distinct-id.ts", + "taskIds": [ + "T17" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/events.ts", + "taskIds": [ + "T17" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/harness.ts", + "taskIds": [ + "T17" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/provide-cockpit-telemetry.ts", + "taskIds": [ + "T17" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/runtime-connection.ts", + "taskIds": [ + "T17" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-telemetry/src/lib/tokens.ts", + "taskIds": [ + "T17" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-telemetry/src/public-api.ts", + "taskIds": [ + "T17" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/cockpit-telemetry/src/test-setup.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/cockpit-telemetry/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/scripts/generate-theme-css.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/index.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/base.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/colors.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/css-vars.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/dark.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/light.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/radius.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/shadows.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/space.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/surfaces.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/theme.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/tokens.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/src/lib/typography.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/design-tokens/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/e2e-harness/src/ag-ui-global-setup-factory.ts", + "taskIds": [ + "T31", + "T36" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/e2e-harness/src/aimock-mode.ts", + "taskIds": [ + "T31", + "T36" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/e2e-harness/src/aimock-runner.ts", + "taskIds": [ + "T31", + "T36" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/e2e-harness/src/drift-lib.ts", + "taskIds": [ + "T31", + "T36" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/e2e-harness/src/drift.ts", + "taskIds": [ + "T31", + "T36" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/e2e-harness/src/global-setup-factory.ts", + "taskIds": [ + "T31", + "T36" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/e2e-harness/src/global-teardown.ts", + "taskIds": [ + "T31", + "T36" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/e2e-harness/src/index.ts", + "taskIds": [ + "T31", + "T36" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/e2e-harness/src/test-helpers.ts", + "taskIds": [ + "T31", + "T36" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/example-layouts/src/lib/example-chat-layout.component.ts", + "taskIds": [ + "T33" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/example-layouts/src/lib/example-split-layout.component.ts", + "taskIds": [ + "T33" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/example-layouts/src/lib/install-embedded-theme.ts", + "taskIds": [ + "T33" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/example-layouts/src/public-api.ts", + "taskIds": [ + "T33" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/example-layouts/src/test-setup.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/example-layouts/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/langgraph/.install-collector/development-install.d.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/langgraph/.install-collector/development-install.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/langgraph/eslint.config.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/langgraph/install/postinstall.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/agent-lifecycle-registry.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/agent.fn.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/agent.provider.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/agent.types.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/client-tools.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/client/client-options.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/client/create-langgraph-client.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/inject-agent.ts", + "taskIds": [ + "T11" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "source:libs/langgraph/src/lib/internals/branch-tree.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/internals/extract-citations.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/internals/stream-manager.bridge.ts", + "taskIds": [ + "T09", + "T10", + "T11", + "T38" + ], + "treatment": "shared", + "status": "planned", + "reason": "Carry forward terminal-event versus unexpected-close handling, dispatch uncertainty, status checks, and stale-completion suppression from v0.2.0." + }, + { + "id": "source:libs/langgraph/src/lib/internals/subagent-tracker.ts", + "taskIds": [ + "T10" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/lifecycle.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/package-version.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/runtime-operation-reporter.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/testing/fake-stream.transport.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/testing/mock-langgraph-agent.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/testing/provide-fake-agent.ts", + "taskIds": [ + "T08" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "source:libs/langgraph/src/lib/threads/refresh-on.ts", + "taskIds": [ + "T11" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/threads/threads-adapter.ts", + "taskIds": [ + "T11" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/transport/fetch-stream.transport.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/transport/mock-stream.transport.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/lib/transport/transport.interface.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/public-api.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/test-setup.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/langgraph/src/testing/type-assert.ts", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/test/fixtures/capture-streaming-reasoning-puzzle.mjs", + "taskIds": [ + "T08" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/langgraph/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/middleware/eslint.config.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/middleware/src/langgraph/channel.ts", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/middleware/src/langgraph/client-tool-execution-store.ts", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/middleware/src/langgraph/client-tool-result-guard.ts", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/middleware/src/langgraph/index.ts", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/middleware/src/langgraph/middleware.ts", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/middleware/src/langgraph/postgres-client-tool-execution-store.ts", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/middleware/src/langgraph/router.ts", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/middleware/src/langgraph/types.ts", + "taskIds": [ + "T16" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/middleware/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/render/.install-collector/development-install.d.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/render/.install-collector/development-install.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/render/eslint.config.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/render/install/postinstall.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/contexts/render-context.ts", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/contexts/render-host.ts", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/contexts/repeat-scope.ts", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/default-fallback.component.ts", + "taskIds": [ + "T24" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/define-angular-registry.ts", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/internals/element-readiness.ts", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/internals/guarded-emit.ts", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/internals/prop-signal.ts", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/lifecycle.ts", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/package-version.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/provide-render.ts", + "taskIds": [ + "T24" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "source:libs/render/src/lib/provide-views.ts", + "taskIds": [ + "T24" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "source:libs/render/src/lib/render-element.component.ts", + "taskIds": [ + "T24" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/render-event.ts", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/render-lifecycle.service.ts", + "taskIds": [ + "T25" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/render-spec.component.ts", + "taskIds": [ + "T24" + ], + "treatment": "react", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/render.types.ts", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/signal-state-store.ts", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/lib/standard-schema.ts", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "excluded", + "status": "planned", + "reason": "Do not migrate validator/inference contracts into a shared tool/schema layer. Argument validation belongs to callers; optional JSON Schema metadata is supplied directly. Current Angular behavior, protocol schema assets, form validation and transport decoding are unaffected." + }, + { + "id": "source:libs/render/src/lib/views.ts", + "taskIds": [ + "T24" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/public-api.ts", + "taskIds": [ + "T07", + "T20" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/render/src/test-setup.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/render/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/eslint.config.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/install/assemble-package.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/install/bridge.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/install/collector.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/install/files.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/install/git-context.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/install/identity.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/install/policy.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/install/postinstall.cjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/install/verify-pack.mjs", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/scripts/assemble-dist.mjs", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/scripts/verify-angular-install-bridge.mjs", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/scripts/verify-development-bundle.mjs", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/browser/development/announcements.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/browser/development/collector.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/browser/development/runtime.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/browser/development/session.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/browser/development/types.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/browser/properties.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/browser/provide.ts", + "taskIds": [ + "T17" + ], + "treatment": "angular-only", + "status": "planned", + "reason": "Retain the Angular DI/router facade for compatibility; assigned task supplies the neutral seam and React counterpart separately." + }, + { + "id": "source:libs/telemetry/src/browser/public-api.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/browser/service.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/browser/tokens.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/index.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/node/adapter.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/node/client.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/node/disable.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/node/index.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/shared/anon-id.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/shared/env.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/shared/events.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/shared/hash.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/shared/ingest.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/shared/personal-email-domains.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/shared/properties.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/shared/public-api.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/shared/sample.ts", + "taskIds": [ + "T17" + ], + "treatment": "shared", + "status": "planned" + }, + { + "id": "source:libs/telemetry/src/test-setup.ts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/telemetry/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/ui-react/src/index.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/ui-react/src/lib/control-plane/control-plane-preferences.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/ui-react/src/lib/control-plane/control-plane.tsx", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/ui-react/src/lib/theme-context.tsx", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/ui-react/src/lib/theme-toggle.tsx", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/ui-react/src/lib/themed-frame.tsx", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/ui-react/src/lib/use-embedded-theme.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/ui-react/src/lib/utils.ts", + "taskIds": [ + "T22", + "T33" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/ui-react/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "source:libs/workspace-react/src/index.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/activity-types.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/api-mode/api-mode.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/code-mode/code-mode.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/code-mode/file-tree.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/code-mode/file-tree.utils.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/code-pane/code-pane.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/activity-panel-boundary.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/activity-panel.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/cockpit-control-plane.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/control-plane-overflow-menu.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/runtime-section.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/control-plane/runtime-target-settings.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/mobile-nav-overlay.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/modes/mode-switcher.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/run-mode/run-mode.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/sidebar/cockpit-sidebar.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/sidebar/language-picker.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/sidebar/navigation-groups.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/components/ui/tabs.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/host-services.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/mode-panels.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/navigation-labels.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/runtime-contracts.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/runtime-diagnostics.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/runtime-state.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/runtime-target-provider.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/runtime-target-session.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/session-activity.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/runtime/use-runtime-controller.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/workspace-contracts.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/workspace-navigation.ts", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/workspace-provider.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/src/lib/workspace-shell.tsx", + "taskIds": [ + "T33", + "T34" + ], + "treatment": "internal", + "status": "planned", + "reason": "Private cockpit, example, or test infrastructure; adapt for React scenarios without adding a public package API." + }, + { + "id": "source:libs/workspace-react/vite.config.mts", + "taskIds": [ + "T02", + "T36", + "T37" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:ag-ui-a2ui-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:ag-ui-client-tools-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:ag-ui-interrupts-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:ag-ui-json-render-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:ag-ui-streaming-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:ag-ui-subagents-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:ag-ui-tool-views-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-a2ui-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-debug-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-generative-ui-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-input-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-interrupts-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-messages-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-subagents-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-theming-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-threads-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-timeline-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:chat-tool-calls-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:deep-agents-filesystem-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:deep-agents-memory-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:deep-agents-planning-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:deep-agents-skills-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:deep-agents-subagents-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:langgraph-client-tools-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:langgraph-deployment-runtime-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:langgraph-durable-execution-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:langgraph-interrupts-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:langgraph-memory-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:langgraph-persistence-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:langgraph-streaming-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:langgraph-subgraphs-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:langgraph-time-travel-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:render-computed-functions-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:render-element-rendering-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:render-registry-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:render-repeat-loops-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:render-spec-rendering-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:render-state-management-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:runtimes-aws-strands-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:runtimes-mastra-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + }, + { + "id": "topic:runtimes-microsoft-agent-framework-angular", + "taskIds": [ + "T32", + "T33" + ], + "treatment": "infrastructure", + "status": "planned" + } + ] +} diff --git a/scripts/react-parity/inventory.mjs b/scripts/react-parity/inventory.mjs new file mode 100644 index 000000000..41e4a2091 --- /dev/null +++ b/scripts/react-parity/inventory.mjs @@ -0,0 +1,258 @@ +#!/usr/bin/env node +/** T01 source evidence, not a typecheck or a claim that React parity is implemented. */ +import { createHash } from 'node:crypto'; +import { execFileSync } from 'node:child_process'; +import { existsSync, readFileSync, writeFileSync } from 'node:fs'; +import { dirname, relative, resolve, sep } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import ts from 'typescript'; + +export const DEFAULT_SCOPE = { + libraries: ['a2ui', 'ag-ui', 'chat', 'cockpit-registry', 'cockpit-runtime-bridge', 'cockpit-shell', 'cockpit-telemetry', 'design-tokens', 'e2e-harness', 'example-layouts', 'langgraph', 'middleware', 'render', 'telemetry', 'ui-react', 'workspace-react'], + entryPoints: ['libs/a2ui/src/index.ts', 'libs/ag-ui/src/public-api.ts', 'libs/chat/src/public-api.ts', 'libs/chat/debug/public-api.ts', 'libs/chat/testing/public-api.ts', 'libs/langgraph/src/public-api.ts', 'libs/middleware/src/langgraph/index.ts', 'libs/render/src/public-api.ts', 'libs/telemetry/src/index.ts', 'libs/telemetry/src/browser/public-api.ts', 'libs/telemetry/src/node/index.ts', 'libs/telemetry/src/shared/public-api.ts'], + docsRoot: 'apps/website/content/docs', + topicsRoot: 'cockpit', + configFiles: ['package.json', 'package-lock.json', 'nx.json', 'tsconfig.base.json', '.github/workflows/ci.yml', '.github/workflows/publish.yml', '.github/workflows/release-provenance.yml', '.github/workflows/publish-middleware-npm.yml', '.github/workflows/publish-middleware-python.yml', 'scripts/verify-release-versions.mjs', 'scripts/cockpit-matrix.mjs', 'scripts/assemble-examples.ts', 'scripts/examples/serve-example.ts', 'apps/website/scripts/generate-api-docs.ts', 'apps/website/scripts/generate-narrative-docs.ts', 'apps/website/scripts/generate-agent-context.ts'], +}; + +const lexical = (a, b) => a < b ? -1 : a > b ? 1 : 0; +const portable = path => path.split(sep).join('/'); +const sha256 = value => createHash('sha256').update(value).digest('hex'); +const isSource = path => /\.(?:[cm]?[jt]s|tsx|jsx)$/.test(path); +const isTest = path => /\.(?:spec|test|type-spec|type-test)\.[^.]+$/.test(path); +const printer = ts.createPrinter({ removeComments: true, newLine: ts.NewLineKind.LineFeed }); +const signature = node => printer.printNode(ts.EmitHint.Unspecified, node, node.getSourceFile()); + +function pathsInRepository(root, scope) { + // --others is intentional: a new source file must not escape review until git add. + const paths = execFileSync('git', ['ls-files', '-z', '--cached', '--others', '--exclude-standard', '--', ...scope.libraries.map(name => `libs/${name}`), scope.docsRoot, scope.topicsRoot, ...scope.configFiles], { cwd: root, encoding: 'utf8' }); + return [...new Set(paths.split('\0').filter(path => path && existsSync(resolve(root, path))))].sort(lexical); +} + +function createProgram(root, paths) { + const configPath = resolve(root, 'tsconfig.base.json'); + const config = existsSync(configPath) ? ts.readConfigFile(configPath, ts.sys.readFile) : { config: {} }; + if (config.error) throw new Error(ts.flattenDiagnosticMessageText(config.error.messageText, '\n')); + const converted = ts.convertCompilerOptionsFromJson(config.config.compilerOptions ?? {}, root); + const options = { ...converted.options, noEmit: true, noLib: true, allowJs: true, checkJs: false, types: [], module: ts.ModuleKind.ESNext, moduleResolution: ts.ModuleResolutionKind.Bundler }; + const host = ts.createCompilerHost(options); + // Inventory the repository's source contract. Installed dependency declarations + // are deliberately excluded: their graph is separately pinned by package-lock. + host.resolveModuleNames = (names, containingFile) => names.map(name => { + const resolved = ts.resolveModuleName(name, containingFile, options, host).resolvedModule; + return resolved && !portable(resolved.resolvedFileName).includes('/node_modules/') ? resolved : undefined; + }); + return ts.createProgram(paths.map(path => resolve(root, path)), options, host); +} + +function decoratorName(decorator, source) { + const expression = ts.isCallExpression(decorator.expression) ? decorator.expression.expression : decorator.expression; + if (ts.isPropertyAccessExpression(expression)) { + const namespace = source.statements.find(statement => ts.isImportDeclaration(statement) && statement.moduleSpecifier.text === '@angular/core' && statement.importClause?.namedBindings && ts.isNamespaceImport(statement.importClause.namedBindings) && statement.importClause.namedBindings.name.text === expression.expression.getText(source)); + return namespace ? expression.name.text : undefined; + } + if (!ts.isIdentifier(expression)) return undefined; + for (const statement of source.statements) { + if (!ts.isImportDeclaration(statement) || statement.moduleSpecifier.text !== '@angular/core') continue; + const bindings = statement.importClause?.namedBindings; + if (!bindings || !ts.isNamedImports(bindings)) continue; + const binding = bindings.elements.find(element => element.name.text === expression.text); + if (binding) return binding.propertyName?.text ?? binding.name.text; + } + return undefined; +} + +export function collectInventory(root, scope = DEFAULT_SCOPE) { + root = resolve(root); + const paths = pathsInRepository(root, scope); + const scoped = paths.filter(path => scope.libraries.some(name => path.startsWith(`libs/${name}/`))); + const sources = scoped.filter(path => isSource(path) && !isTest(path)); + const topicProjects = paths.filter(path => path.startsWith(`${scope.topicsRoot}/`) && /\/angular\/project.json$/.test(path)); + const topicSources = topicProjects.map(path => path.replace(/project.json$/, 'src/index.ts')); + const program = createProgram(root, [...sources, ...scope.entryPoints, ...topicSources]); + const syntaxErrors = program.getSyntacticDiagnostics(); + if (syntaxErrors.length) throw new Error(syntaxErrors.map(error => `Syntax error ${portable(relative(root, error.file.fileName))}: ${ts.flattenDiagnosticMessageText(error.messageText, '\n')}`).join('\n')); + const checker = program.getTypeChecker(); + const rows = []; + const fileRow = (kind, path) => rows.push({ id: `${kind}:${path}`, kind, path, sha256: sha256(readFileSync(resolve(root, path))) }); + for (const path of sources) fileRow('source', path); + // These are the selected libraries' non-source package assets/configuration, + // including styles, notices, manifests, and build metadata; no whole-repo dump. + for (const path of scoped.filter(path => !isSource(path))) fileRow('asset', path); + for (const path of scope.configFiles.filter(path => paths.includes(path))) fileRow('config', path); + for (const path of paths.filter(path => path.startsWith(`${scope.docsRoot}/`) && path.endsWith('.mdx'))) fileRow('doc', path); + + const describe = node => ({ + path: portable(relative(root, node.getSourceFile().fileName)), + symbol: node.name?.getText(node.getSourceFile()) ?? '(anonymous)', + syntaxKind: ts.SyntaxKind[node.kind], + // Keeping normalized declaration text makes review useful, while source-file + // digests also catch changes to private types used by a public signature. + signature: signature(ts.isImportSpecifier(node) ? node.parent.parent.parent : ts.isExportSpecifier(node) ? node.parent.parent : node), + }); + for (const path of scope.entryPoints) { + const source = program.getSourceFile(resolve(root, path)); + if (!source) throw new Error(`Missing entry point: ${path}`); + const module = checker.getSymbolAtLocation(source); + if (!module) throw new Error(`Entry point is not a module: ${path}`); + rows.push({ id: `entry:${path}`, kind: 'entry', path }); + for (const symbol of checker.getExportsOfModule(module)) { + let target = symbol; + const visited = new Set(); + while (target.flags & ts.SymbolFlags.Alias && !visited.has(target)) { + visited.add(target); + const next = checker.getImmediateAliasedSymbol(target); + if (!next?.declarations?.length) break; + target = next; + } + const declarations = target.declarations; + if (!declarations?.length) throw new Error(`Unresolved export: ${path}#${symbol.name}`); + rows.push({ id: `export:${path}#${symbol.name}`, kind: 'export', path, symbol: symbol.name, declarations: declarations.map(describe).sort((a, b) => lexical(JSON.stringify(a), JSON.stringify(b))) }); + } + } + for (const path of sources) { + const source = program.getSourceFile(resolve(root, path)); + if (!source) continue; + const visit = node => { + if (ts.isClassDeclaration(node)) { + const decorators = (ts.getDecorators(node) ?? []).map(decorator => decoratorName(decorator, source)).filter(name => name === 'Component' || name === 'Directive'); + if (decorators.length) { + if (!node.name) throw new Error(`Unnamed decorated declaration: ${path}`); + rows.push({ id: `component:${path}#${node.name.text}`, kind: 'component', path, symbol: node.name.text, decorators, signature: signature(node) }); + } + } + ts.forEachChild(node, visit); + }; + visit(source); + } + for (const path of topicSources) { + const source = program.getSourceFile(resolve(root, path)); + if (!source) throw new Error(`Missing topic source: ${path}`); + const ids = []; + const visit = node => { + if (ts.isVariableDeclaration(node) && node.initializer && ts.isObjectLiteralExpression(node.initializer)) { + const id = node.initializer.properties.find(property => ts.isPropertyAssignment(property) && property.name.getText(source).replaceAll(/['"]/g, '') === 'id'); + if (id && ts.isStringLiteralLike(id.initializer)) ids.push(id.initializer.text); + } + ts.forEachChild(node, visit); + }; + visit(source); + if (ids.length !== 1) throw new Error(`Expected one topic ID in ${path}, found ${ids.length}`); + rows.push({ id: `topic:${ids[0]}`, kind: 'topic', path, topicId: ids[0], project: path.replace(/src\/index.ts$/, 'project.json'), sha256: sha256(readFileSync(resolve(root, path))) }); + } + rows.sort((a, b) => lexical(a.id, b.id)); + return { schemaVersion: 1, scope, rows }; +} + +function indexRows(rows, label, errors) { + const result = new Map(); + for (const row of rows) { + if (result.has(row.id)) errors.push(`Duplicate ${label}: ${row.id}`); + result.set(row.id, row); + } + return result; +} + +export function compareInventories(baseline, actual) { + const errors = []; + if (baseline.schemaVersion !== actual.schemaVersion) errors.push('Unsupported inventory schemaVersion'); + if (JSON.stringify(baseline.scope) !== JSON.stringify(actual.scope)) errors.push('Inventory scope changed'); + const previous = indexRows(baseline.rows, 'baseline record', errors); + const current = indexRows(actual.rows, 'current record', errors); + for (const [id, row] of previous) { + if (!current.has(id)) errors.push(`Missing ${id}`); + else if (JSON.stringify(row) !== JSON.stringify(current.get(id))) errors.push(`Changed ${id}`); + } + for (const id of current.keys()) if (!previous.has(id)) errors.push(`Added ${id}`); + return errors; +} + +export function validateDispositions(inventory, dispositions) { + const errors = []; + if (dispositions.schemaVersion !== 1) errors.push('Unsupported dispositions schemaVersion'); + const facts = indexRows(inventory.rows, 'inventory record', errors); + const assignments = indexRows(dispositions.rows, 'disposition', errors); + const treatments = new Set(['shared', 'angular-only', 'react', 'internal', 'infrastructure', 'excluded']); + for (const id of facts.keys()) if (!assignments.has(id)) errors.push(`Missing disposition: ${id}`); + for (const [id, row] of assignments) { + if (!facts.has(id)) errors.push(`Stale disposition source reference: ${id}`); + if (!Array.isArray(row.taskIds) || row.taskIds.length === 0) errors.push(`Missing task IDs: ${id}`); + else { + for (const task of row.taskIds) if (typeof task !== 'string' || !/^T(?:0[1-9]|[12][0-9]|3[0-9])$/.test(task)) errors.push(`Unknown task ID ${task}: ${id}`); + if (new Set(row.taskIds).size !== row.taskIds.length) errors.push(`Duplicate task ID: ${id}`); + } + if (!treatments.has(row.treatment)) errors.push(`Unknown treatment: ${id}`); + if (['angular-only', 'internal', 'excluded'].includes(row.treatment) && (typeof row.reason !== 'string' || !row.reason.trim())) errors.push(`Explicit reason required for ${row.treatment}: ${id}`); + if (!['planned', 'in-progress', 'complete'].includes(row.status)) errors.push(`Unknown planning status: ${id}`); + } + return errors; +} + +export function summarize(inventory) { + const counts = {}; + for (const row of inventory.rows) counts[row.kind] = (counts[row.kind] ?? 0) + 1; + counts.uniqueExportDefinitions = new Set(inventory.rows.filter(row => row.kind === 'export').flatMap(row => row.declarations.map(declaration => `${declaration.path}#${declaration.symbol}:${declaration.syntaxKind}`))).size; + counts.componentFiles = new Set(inventory.rows.filter(row => row.kind === 'component').map(row => row.path)).size; + counts.libraries = inventory.scope.libraries.length; + return counts; +} + +function main(args) { + if (args.length === 1 && args[0] === '--help') { + console.log(`Usage: node scripts/react-parity/inventory.mjs --check | --write-baseline + --check Read-only drift and planning-ownership validation. + --write-baseline Explicitly regenerate facts; never rewrites dispositions. + --root PATH Repository root (default: the script's repository). + --baseline PATH Inventory facts JSON (default: scripts/react-parity/baseline.json). + --dispositions PATH Ownership JSON (default: scripts/react-parity/dispositions.json). + +The baseline scope declares selected libraries, public entries, docs, topics and +distribution configuration; initial generation uses DEFAULT_SCOPE in this script. +Git-tracked and non-ignored untracked scoped files are included. Test source is +excluded; package test configuration and fixture assets remain in scope. +AST declaration signatures include implementation text; file digests intentionally +detect source, asset and documentation edits as well as structural API changes. +External dependencies are represented by local import contracts, not node_modules. +Explicit regeneration records the current Git HEAD and scoped modified/untracked +paths; review this provenance change with the fact diff and preserve the prior +baseline in Git history. It does not certify React implementation parity. Adjust +dispositions separately. No research Markdown is read at runtime.`); + return; + } + const options = {}; + for (let index = 0; index < args.length; index++) { + const arg = args[index]; + if (['--check', '--write-baseline'].includes(arg)) options[arg] = true; + else if (['--root', '--baseline', '--dispositions'].includes(arg) && args[index + 1]) options[arg] = args[++index]; + else throw new Error(`Unknown or incomplete option: ${arg}`); + } + if (Boolean(options['--check']) === Boolean(options['--write-baseline'])) throw new Error('Choose --check (read only) or --write-baseline (explicitly update facts; dispositions remain manual).'); + const root = resolve(options['--root'] ?? resolve(dirname(fileURLToPath(import.meta.url)), '../..')); + const baselinePath = resolve(options['--baseline'] ?? resolve(root, 'scripts/react-parity/baseline.json')); + const dispositionsPath = resolve(options['--dispositions'] ?? resolve(root, 'scripts/react-parity/dispositions.json')); + const baseline = existsSync(baselinePath) ? JSON.parse(readFileSync(baselinePath, 'utf8')) : undefined; + const actual = collectInventory(root, baseline?.scope ?? DEFAULT_SCOPE); + if (options['--write-baseline']) { + const baselineHead = execFileSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' }).trim(); + const paths = new Set([...actual.rows, ...(baseline?.rows ?? [])].flatMap(row => [row.path, ...(row.declarations ?? []).map(declaration => declaration.path)])); + const changedPaths = args => execFileSync('git', args, { cwd: root, encoding: 'utf8' }).split('\0').filter(path => paths.has(path)).sort(lexical); + const sourceState = { + modified: changedPaths(['diff', 'HEAD', '--name-only', '-z']), + untracked: changedPaths(['ls-files', '--others', '--exclude-standard', '-z']), + }; + const recorded = { schemaVersion: actual.schemaVersion, baselineHead, sourceState, scope: actual.scope, rows: actual.rows }; + writeFileSync(baselinePath, `${JSON.stringify(recorded, null, 2)}\n`); + console.log(`Wrote inventory facts; review and update dispositions separately. ${JSON.stringify(summarize(actual))}`); + return; + } + if (!baseline) throw new Error(`Missing baseline: ${baselinePath}`); + const dispositions = JSON.parse(readFileSync(dispositionsPath, 'utf8')); + const errors = [...compareInventories(baseline, actual), ...validateDispositions(actual, dispositions)]; + if (!/^[a-f0-9]{40}$/.test(baseline.baselineHead ?? '')) errors.push('Missing or invalid baselineHead provenance'); + if (errors.length) throw new Error(errors.join('\n')); + console.log(`Parity inventory and planning ownership valid (not implementation parity). ${JSON.stringify(summarize(actual))}`); +} + +if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { + try { main(process.argv.slice(2)); } catch (error) { console.error(error.message); process.exitCode = 1; } +} diff --git a/scripts/react-parity/inventory.spec.mjs b/scripts/react-parity/inventory.spec.mjs new file mode 100644 index 000000000..a1dc136de --- /dev/null +++ b/scripts/react-parity/inventory.spec.mjs @@ -0,0 +1,213 @@ +import assert from 'node:assert/strict'; +import { mkdtempSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { execFileSync, spawnSync } from 'node:child_process'; +import { test } from 'node:test'; + +import { DEFAULT_SCOPE, collectInventory, compareInventories, validateDispositions } from './inventory.mjs'; +const scope = { + libraries: ['sample'], + entryPoints: ['libs/sample/src/public-api.ts', 'libs/sample/testing/public-api.ts'], + docsRoot: 'apps/website/content/docs', topicsRoot: 'cockpit', configFiles: [], +}; + +function fixture(t) { + const root = mkdtempSync(join(tmpdir(), 'react-parity-')); + t.after(() => rmSync(root, { recursive: true, force: true })); + const put = (path, content) => { + mkdirSync(join(root, path, '..'), { recursive: true }); + writeFileSync(join(root, path), content); + }; + execFileSync('git', ['init', '-q', root]); + put('.gitignore', 'ignored.ts\n'); + put('libs/sample/src/public-api.ts', "export { Original as Alias } from './barrel'; export * from './view';"); + put('libs/sample/testing/public-api.ts', "export { Original } from '../src/definition';"); + put('libs/sample/src/barrel.ts', "export * from './definition';"); + put('libs/sample/src/definition.ts', 'export interface Original { value: string; }'); + put('libs/sample/src/view.ts', "import { Component as View, Directive } from '@angular/core'; @View({selector: 'demo'}) export class Demo { value = 1; } @Directive({selector: '[extra]'}) export class Extra {}"); + put('libs/sample/package.json', '{"name":"sample","exports":{"./theme.css":"./theme.css"}}'); + put('libs/sample/theme.css', ':root { color: red; }'); + put('libs/sample/src/example.spec.ts', 'const test = true;'); + put('libs/sample/src/ignored.ts', 'const ignore = true;'); + put('apps/website/content/docs/sample/overview.mdx', '# Sample'); + put('cockpit/sample/demo/angular/project.json', '{"name":"sample-demo"}'); + put('cockpit/sample/demo/angular/src/index.ts', "export const demo = { id: 'sample-demo-angular', manifestIdentity: {product: 'sample', topic: 'demo', language: 'angular'} };"); + return { root, put, collect: () => collectInventory(root, scope) }; +} + +function ownership(inventory) { + return { schemaVersion: 1, rows: inventory.rows.map(({ id }) => ({ id, taskIds: ['T03'], treatment: 'shared', status: 'planned' })) }; +} + +test('inventory API exists', () => assert.equal(typeof collectInventory, 'function')); + +test('AST inventory resolves renamed exports, barrels and secondary entries; scans aliased decorators', t => { + const { collect } = fixture(t); + const inventory = collect(); + const alias = inventory.rows.find(row => row.kind === 'export' && row.symbol === 'Alias'); + assert.equal(alias.declarations[0].path, 'libs/sample/src/definition.ts'); + assert.match(alias.declarations[0].signature, /value: string/); + assert.equal(inventory.rows.filter(row => row.kind === 'export').length, 4); + assert.deepEqual(inventory.rows.filter(row => row.kind === 'component').map(row => row.symbol).sort(), ['Demo', 'Extra']); + assert.ok(inventory.rows.some(row => row.kind === 'topic' && row.topicId === 'sample-demo-angular')); + assert.ok(!inventory.rows.some(row => /ignored|example.spec/.test(row.path))); +}); + +test('inventory is deterministic and independent of checkout location', t => { + const a = fixture(t), b = fixture(t); + assert.deepEqual(a.collect(), b.collect()); + assert.doesNotMatch(JSON.stringify(a.collect()), /react-parity-[/A-Za-z0-9]+/); +}); + +test('source names ending in -spec remain in scope; type-spec tests do not', t => { + const { collect, put } = fixture(t); + put('libs/sample/src/surface-to-spec.ts', 'export function toSpec() {}'); + put('libs/sample/src/contract.type-spec.ts', 'const typeTest = true;'); + const paths = collect().rows.filter(row => row.kind === 'source').map(row => row.path); + assert.ok(paths.includes('libs/sample/src/surface-to-spec.ts')); + assert.ok(!paths.includes('libs/sample/src/contract.type-spec.ts')); +}); + +test('external re-exports preserve the local import contract without installed dependency paths', t => { + const { collect, put } = fixture(t); + put('libs/sample/src/definition.ts', "import type { External as Original } from 'external-package'; export type { Original };"); + const row = collect().rows.find(row => row.kind === 'export' && row.symbol === 'Alias'); + assert.equal(row.declarations[0].path, 'libs/sample/src/definition.ts'); + assert.match(row.declarations[0].signature, /import type.*External as Original.*external-package/); +}); + +test('malformed source syntax fails closed instead of producing a partial inventory', t => { + const { collect, put } = fixture(t); + put('libs/sample/src/definition.ts', 'export interface Original { value: ; }'); + assert.throws(collect, /Syntax error.*definition.ts/); +}); + +test('package test configuration remains an asset even when its filename contains .spec', t => { + const { collect, put } = fixture(t); + put('libs/sample/tsconfig.spec.json', '{"extends":"./tsconfig.json"}'); + assert.ok(collect().rows.some(row => row.id === 'asset:libs/sample/tsconfig.spec.json')); +}); + +test('default configuration scope rejects a lockfile-only dependency change', t => { + const { root, put } = fixture(t); + const collect = () => collectInventory(root, { ...scope, configFiles: DEFAULT_SCOPE.configFiles }); + put('package-lock.json', '{"lockfileVersion":3,"packages":{"node_modules/sdk":{"version":"1.0.0"}}}'); + const baseline = collect(); + put('package-lock.json', '{"lockfileVersion":3,"packages":{"node_modules/sdk":{"version":"1.1.0"}}}'); + assert.ok(compareInventories(baseline, collect()).includes('Changed config:package-lock.json')); +}); + +for (const [name, path, text] of [ + ['missing export', 'libs/sample/src/public-api.ts', "export * from './view';"], + ['added export', 'libs/sample/src/public-api.ts', "export { Original as Alias, Original as Added } from './definition'; export * from './view';"], + ['renamed export', 'libs/sample/src/public-api.ts', "export { Original as Renamed } from './definition'; export * from './view';"], + ['aliased definition signature', 'libs/sample/src/definition.ts', 'export interface Original { value: number; }'], + ['untracked source', 'libs/sample/src/new.ts', 'export interface Added {}'], + ['component', 'libs/sample/src/new-view.ts', "import {Component} from '@angular/core'; @Component({}) export class NewView {}"], + ['docs page', 'apps/website/content/docs/sample/new.mdx', '# New'], + ['package asset', 'libs/sample/new.css', ':root {}'], + ['package configuration', 'libs/sample/package.json', '{"name":"renamed"}'], + ['topic identity', 'cockpit/sample/demo/angular/src/index.ts', "export const demo = {id: 'renamed-angular'};"], +]) { + test(`rejects drift in ${name}`, t => { + const { collect, put } = fixture(t), baseline = collect(); + put(path, text); + const errors = compareInventories(baseline, collect()); + assert.ok(errors.length > 0); + if (name === 'aliased definition signature') assert.ok(errors.some(error => /export.*Alias/.test(error))); + }); +} + +test('rejects missing components, docs, topics and assets', t => { + const { collect, root } = fixture(t), baseline = collect(); + for (const path of ['libs/sample/src/view.ts', 'apps/website/content/docs/sample/overview.mdx', 'cockpit/sample/demo/angular', 'libs/sample/theme.css']) rmSync(join(root, path), { recursive: true }); + const errors = compareInventories(baseline, collect()); + for (const kind of ['component', 'doc', 'topic', 'asset']) assert.ok(errors.some(error => error.includes(`${kind}:`)), kind); +}); + +test('rejects duplicate baseline records and stale source references', t => { + const actual = fixture(t).collect(), baseline = structuredClone(actual); + baseline.rows.push(baseline.rows[0]); + baseline.rows.find(row => row.kind === 'export').declarations[0].path = 'libs/sample/gone.ts'; + const errors = compareInventories(baseline, actual); + assert.ok(errors.some(error => /Duplicate/.test(error))); + assert.ok(errors.some(error => /Changed export/.test(error))); +}); + +test('ownership is complete planning evidence, not an implementation-completion claim', t => { + const inventory = fixture(t).collect(); + assert.deepEqual(validateDispositions(inventory, ownership(inventory)), []); +}); + +for (const [name, mutate, expected] of [ + ['missing row', rows => rows.pop(), /Missing disposition/], + ['duplicate row', rows => rows.push(rows[0]), /Duplicate disposition/], + ['unknown task ID', rows => { rows[0].taskIds = ['T40']; }, /Unknown task/], + ['non-string task ID', rows => { rows[0].taskIds = [['T03']]; }, /Unknown task/], + ['stale reference', rows => { rows[0].id = 'source:missing.ts'; }, /Stale disposition/], + ['Angular-only reason', rows => { rows[0].treatment = 'angular-only'; }, /reason/], + ['internal reason', rows => { rows[0].treatment = 'internal'; }, /reason/], +]) { + test(`rejects ${name}`, t => { + const inventory = fixture(t).collect(), dispositions = ownership(inventory); + mutate(dispositions.rows); + assert.ok(validateDispositions(inventory, dispositions).some(error => expected.test(error))); + }); +} + +test('CLI check fails on drift without changing either manifest', t => { + const { root, collect, put } = fixture(t), baseline = collect(); + execFileSync('git', ['add', '.'], { cwd: root }); + execFileSync('git', ['-c', 'user.name=Fixture', '-c', 'user.email=fixture@example.invalid', 'commit', '-qm', 'fixture'], { cwd: root }); + baseline.baselineHead = execFileSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' }).trim(); + put('baseline.json', JSON.stringify(baseline)); + put('dispositions.json', JSON.stringify(ownership(baseline))); + const before = ['baseline.json', 'dispositions.json'].map(path => readFileSync(join(root, path), 'utf8')); + const check = () => spawnSync(process.execPath, ['scripts/react-parity/inventory.mjs', '--check', '--root', root, '--baseline', join(root, 'baseline.json'), '--dispositions', join(root, 'dispositions.json')], { encoding: 'utf8' }); + const unchanged = check(); + assert.equal(unchanged.status, 0, unchanged.stderr); + put('libs/sample/src/new.ts', 'export const newFile = true;'); + const result = check(); + assert.equal(result.status, 1); + assert.match(result.stderr, /Added source:libs\/sample\/src\/new.ts/); + assert.deepEqual(['baseline.json', 'dispositions.json'].map(path => readFileSync(join(root, path), 'utf8')), before); +}); + +test('CLI help documents check, explicit fact regeneration, and scope without scanning', () => { + const result = spawnSync(process.execPath, ['scripts/react-parity/inventory.mjs', '--help'], { encoding: 'utf8' }); + assert.equal(result.status, 0); + assert.match(result.stdout, /--check/); + assert.match(result.stdout, /--write-baseline/); + assert.match(result.stdout, /scope/); +}); + +test('explicit regeneration records the checked-out commit and preserves ownership', t => { + const { root, collect, put } = fixture(t); + execFileSync('git', ['add', '.'], { cwd: root }); + const commit = () => execFileSync('git', ['-c', 'user.name=Fixture', '-c', 'user.email=fixture@example.invalid', 'commit', '-qm', 'fixture'], { cwd: root }); + commit(); + put('baseline.json', JSON.stringify(collect())); + put('dispositions.json', JSON.stringify(ownership(collect()))); + const ownedBefore = readFileSync(join(root, 'dispositions.json'), 'utf8'); + const generate = () => { + const result = spawnSync(process.execPath, ['scripts/react-parity/inventory.mjs', '--write-baseline', '--root', root, '--baseline', join(root, 'baseline.json')], { encoding: 'utf8' }); + assert.equal(result.status, 0, result.stderr); + return JSON.parse(readFileSync(join(root, 'baseline.json'), 'utf8')); + }; + const first = generate(); + assert.equal(first.baselineHead, execFileSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' }).trim()); + put('unrelated.txt', 'A second commit changes provenance, not selected facts.'); + execFileSync('git', ['add', 'unrelated.txt'], { cwd: root }); + commit(); + const second = generate(); + assert.notEqual(second.baselineHead, first.baselineHead); + assert.equal(second.baselineHead, execFileSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' }).trim()); + assert.deepEqual(second.rows, first.rows); + put('libs/sample/src/definition.ts', 'export interface Original { value: boolean; }'); + put('libs/sample/src/added.ts', 'export const added = true;'); + const dirty = generate(); + assert.deepEqual(dirty.sourceState.modified, ['libs/sample/src/definition.ts']); + assert.deepEqual(dirty.sourceState.untracked, ['libs/sample/src/added.ts']); + assert.equal(readFileSync(join(root, 'dispositions.json'), 'utf8'), ownedBefore); +}); diff --git a/scripts/react-parity/package-policy.mjs b/scripts/react-parity/package-policy.mjs new file mode 100644 index 000000000..31a479766 --- /dev/null +++ b/scripts/react-parity/package-policy.mjs @@ -0,0 +1,82 @@ +// Final package roles are independent of the packages temporarily retained +// during migration. Removing a scaffold must not weaken the final-role gate. +export const finalPackageDependencies = { + core: [], + langgraph: ['core'], + 'ag-ui': ['core'], + render: ['core'], + a2ui: [], + content: ['core', 'render', 'a2ui'], + angular: ['core', 'content', 'render', 'a2ui'], + react: ['core', 'content', 'render', 'a2ui'], + telemetry: ['core'], +}; +export const privateScaffoldProjects = ['core', 'content', 'angular', 'react']; +export const angularTransitionProjects = ['chat', 'langgraph', 'ag-ui', 'render']; +export const scanProjects = [...new Set([...privateScaffoldProjects, ...angularTransitionProjects, 'a2ui', 'telemetry'])]; +const retiredProjects = ['chat', 'langgraph-core', 'ag-ui-core', 'react-render']; + +export function packageOf(specifier) { + return specifier.startsWith('@') ? specifier.split('/').slice(0, 2).join('/') : specifier.split('/')[0]; +} + +export function sourceEntry(project, angularTransitions = angularTransitionProjects) { + return project === 'angular' || angularTransitions.includes(project) ? 'src/public-api.ts' : 'src/index.ts'; +} + +export function forbiddenDependency(project, specifier, { angularTransitions = [], browserTransition = false } = {}) { + const pkg = packageOf(specifier); + const internal = pkg.startsWith('@threadplane/') ? pkg.slice('@threadplane/'.length) : undefined; + const angular = pkg.startsWith('@angular/'); + const react = ['react', 'react-dom', '@types/react', '@types/react-dom'].includes(pkg) || ['react', 'react-render', 'ui-react', 'workspace-react'].includes(internal); + // These are intentionally the only whole-project exceptions. Their current + // Angular graphs are scanned transitively and still cannot reach React. + if (angularTransitionProjects.includes(project) && angularTransitions.includes(project)) return react; + const role = project; + if (internal) { + if (internal === project) return false; + return !finalPackageDependencies[role]?.includes(internal); + } + if (react && role !== 'react') return true; + if (angular && role !== 'angular' && !(role === 'telemetry' && browserTransition)) return true; + const backend = pkg.startsWith('@langchain/') || pkg.startsWith('@ag-ui/'); + if (backend && !['langgraph', 'ag-ui'].includes(role)) return true; + const parser = ['@cacheplane/partial-json', '@cacheplane/partial-markdown', 'marked', 'remark-gfm', 'katex', 'shiki'].includes(pkg); + return (role === 'core' && (parser || pkg === 'zod')) || + (['core', 'content', 'render', 'a2ui', 'telemetry'].includes(role) && pkg === 'rxjs'); +} + +export function manifestViolations(project, manifest, { angularTransitions = [], telemetryBrowserTransition = false } = {}) { + const errors = []; + for (const field of ['dependencies', 'peerDependencies', 'optionalDependencies']) { + for (const dependency of Object.keys(manifest[field] ?? {})) { + const optionalBrowserPeer = project === 'telemetry' && telemetryBrowserTransition && + field === 'peerDependencies' && dependency === '@angular/core' && manifest.peerDependenciesMeta?.[dependency]?.optional === true; + // Core's install graph must stay empty even when source never imports a + // declared dependency. This also covers optional and peer installation. + if (project === 'core' || (!optionalBrowserPeer && forbiddenDependency(project, dependency, { angularTransitions }))) errors.push(`${project}: forbidden ${field} entry ${dependency}`); + } + } + return errors; +} + +// Deliberately opt-in until the topology migration has removed all exceptions. +export function assertFinalRelease({ projects = scanProjects, angularTransitions = angularTransitionProjects, telemetryBrowserTransition = true } = {}) { + return [ + ...projects.filter((project) => retiredProjects.includes(project)).map((project) => `${project}: transition package remains in final release`), + ...angularTransitions.map((project) => `${project}: Angular transition remains enabled`), + ...(telemetryBrowserTransition ? ['telemetry/browser: Angular transition remains enabled'] : []), + ]; +} + +// Both APF conditional exports and legacy @nx/js manifests are valid. Explicit +// exports maps take precedence: never invent a subpath they do not expose. +export function emittedEntries(manifest, subpath = '.') { + const strings = (value) => typeof value === 'string' ? [value] : Object.values(value ?? {}).flatMap(strings); + if (manifest?.exports) { + const exports = manifest.exports; + const entry = typeof exports === 'string' || !Object.keys(exports).some((key) => key.startsWith('.')) ? (subpath === '.' ? exports : undefined) : exports[subpath]; + return [...new Set(strings(entry))]; + } + return subpath === '.' ? [...new Set([manifest?.types, manifest?.typings, manifest?.module, manifest?.main].filter(Boolean))] : []; +} diff --git a/scripts/react-parity/package-policy.spec.mjs b/scripts/react-parity/package-policy.spec.mjs new file mode 100644 index 000000000..670c87c25 --- /dev/null +++ b/scripts/react-parity/package-policy.spec.mjs @@ -0,0 +1,75 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import * as policy from './package-policy.mjs'; + +test('final internal dependencies follow the approved package roles', () => { + const expected = { core: [], langgraph: ['core'], 'ag-ui': ['core'], render: ['core'], a2ui: [], content: ['core', 'render', 'a2ui'], angular: ['core', 'content', 'render', 'a2ui'], react: ['core', 'content', 'render', 'a2ui'], telemetry: ['core'] }; + for (const [project, allowed] of Object.entries(expected)) { + for (const dependency of Object.keys(expected).filter((name) => name !== project)) { + assert.equal(policy.forbiddenDependency(project, `@threadplane/${dependency}`), !allowed.includes(dependency), `${project} -> ${dependency}`); + } + } +}); + +test('private scaffolds and temporary Angular exceptions are separate inventories', () => { + assert.deepEqual(policy.privateScaffoldProjects, ['core', 'content', 'angular', 'react']); + for (const retired of ['langgraph-core', 'ag-ui-core', 'react-render']) assert.ok(!policy.scanProjects.includes(retired)); + assert.deepEqual(policy.angularTransitionProjects, ['chat', 'langgraph', 'ag-ui', 'render']); + assert.ok(policy.scanProjects.includes('telemetry')); + assert.equal(policy.sourceEntry('angular'), 'src/public-api.ts'); + assert.equal(policy.sourceEntry('react'), 'src/index.ts'); +}); + +test('Angular facade allows Angular peers without a transition exception', () => { + assert.deepEqual(policy.manifestViolations('angular', { peerDependencies: { '@angular/core': '*', '@angular/common': '*' } }), []); + for (const dependency of ['react', 'react-dom', '@langchain/core', '@ag-ui/client', '@threadplane/langgraph', '@threadplane/ag-ui', '@threadplane/telemetry']) { + assert.equal(policy.forbiddenDependency('angular', dependency, { angularTransitions: ['angular'] }), true, dependency); + } +}); + +test('retired backend scaffolds do not inherit final backend roles', () => { + for (const project of ['langgraph-core', 'ag-ui-core']) { + assert.equal(policy.forbiddenDependency(project, '@threadplane/core'), true); + assert.equal(policy.forbiddenDependency(project, '@langchain/core'), true); + } +}); + +test('core does not reserve an optional Zod validation integration', () => { + assert.equal(policy.forbiddenDependency('core', 'zod'), true); +}); + +test('final release rejects retained transition packages and exceptions', () => { + assert.ok(policy.assertFinalRelease().length > 0); + assert.deepEqual(policy.assertFinalRelease({ projects: Object.keys(policy.finalPackageDependencies), angularTransitions: [], telemetryBrowserTransition: false }), []); + assert.ok(policy.assertFinalRelease({ projects: ['langgraph-core'], angularTransitions: [], telemetryBrowserTransition: false }).some((error) => error.includes('langgraph-core'))); + assert.ok(policy.assertFinalRelease({ projects: ['react-render'], angularTransitions: [], telemetryBrowserTransition: false }).some((error) => error.includes('react-render'))); +}); + +test('manifest policy rejects dependency edges without needing imports', () => { + for (const field of ['dependencies', 'peerDependencies', 'optionalDependencies']) { + for (const [project, dependency] of [['render', 'content'], ['angular', 'telemetry'], ['react', 'telemetry'], ['langgraph', 'angular'], ['ag-ui', 'render'], ['content', 'langgraph'], ['core', 'content']]) { + assert.ok(policy.manifestViolations(project, { [field]: { [`@threadplane/${dependency}`]: '*' } }).length > 0, `${project} ${field} ${dependency}`); + } + } +}); + +for (const field of ['dependencies', 'peerDependencies', 'optionalDependencies']) { + test(`core rejects arbitrary manifest-only ${field}`, () => { + assert.deepEqual(policy.manifestViolations('core', { [field]: { lodash: '*' } }), [`core: forbidden ${field} entry lodash`]); + }); +} + +test('emitted entries follow APF and legacy manifests without inventing exports', () => { + assert.deepEqual(policy.emittedEntries({ exports: { '.': { types: './types/index.d.ts', default: './fesm2022/index.mjs' } } }), ['./types/index.d.ts', './fesm2022/index.mjs']); + assert.deepEqual(policy.emittedEntries({ types: './index.d.ts', module: './index.js', main: './index.js' }), ['./index.d.ts', './index.js']); + assert.deepEqual(policy.emittedEntries({ exports: { './browser': './browser.js' }, main: './index.js' }), []); + assert.deepEqual(policy.emittedEntries({ types: './index.d.ts', main: './index.js' }, './missing'), []); +}); + +test('telemetry optional Angular peer requires the browser transition', () => { + const manifest = { peerDependencies: { '@angular/core': '*' }, peerDependenciesMeta: { '@angular/core': { optional: true } } }; + assert.deepEqual(policy.manifestViolations('telemetry', manifest, { telemetryBrowserTransition: true }), []); + assert.ok(policy.manifestViolations('telemetry', manifest).length > 0); + assert.ok(policy.manifestViolations('telemetry', { peerDependencies: manifest.peerDependencies }, { telemetryBrowserTransition: true }).length > 0); + assert.ok(policy.manifestViolations('telemetry', { ...manifest, dependencies: { '@angular/core': '*' } }, { telemetryBrowserTransition: true }).length > 0); +}); diff --git a/scripts/react-parity/verify-angular-package.mjs b/scripts/react-parity/verify-angular-package.mjs new file mode 100644 index 000000000..2c427f101 --- /dev/null +++ b/scripts/react-parity/verify-angular-package.mjs @@ -0,0 +1,58 @@ +import { cpSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { assertParserFreeInputs, consumerSpecifiers, installConsumer, packLocalArtifacts, runConsumer } from './verify-packages.mjs'; + +export function lockedAngularManifest(template, lock) { + const dependencies = ['@angular/core', '@angular/common', '@angular/compiler', '@angular/platform-browser', 'rxjs', 'tslib']; + const devDependencies = ['@angular/build', '@angular/cli', '@angular/compiler-cli', 'typescript']; + const version = (name) => { + const value = lock.packages?.[`node_modules/${name}`]?.version; + if (!value) throw new Error(`Missing root lock version for ${name}`); + return value; + }; + const angularVersions = [...dependencies, ...devDependencies].filter((name) => name.startsWith('@angular/')).map(version); + if (new Set(angularVersions.map((value) => value.split('.')[0])).size !== 1) throw new Error('Angular compiler/build/runtime major versions differ in root lock'); + return { + ...template, + dependencies: Object.fromEntries(dependencies.map((name) => [name, version(name)])), + devDependencies: Object.fromEntries(devDependencies.map((name) => [name, version(name)])), + }; +} + +export function angularBuildCommand(consumer) { + return [join(consumer, 'node_modules/@angular/cli/bin/ng.js'), 'build', '--configuration=production', '--stats-json']; +} + +export function angularConsumerSource(template, specifiers) { + const extra = specifiers.filter((specifier) => specifier !== '@threadplane/angular'); + return template.replace('/* PACKAGE_IMPORTS */', extra.map((specifier, index) => `import * as entry${index} from ${JSON.stringify(specifier)};`).join('\n')) + .replace('/* PACKAGE_EXPORT_COUNT */', extra.map((_, index) => `+ Object.keys(entry${index}).length`).join(' ')); +} + +export function verifyAngularPackage(root = process.cwd()) { + root = resolve(root); + const temporary = mkdtempSync(join(tmpdir(), 'threadplane-angular-consumer-')); + try { + const tarballs = packLocalArtifacts(root, temporary, ['angular']); + const consumer = join(temporary, 'consumer'); + cpSync(join(root, 'fixtures/react-parity/consumers/angular'), consumer, { recursive: true }); + const template = JSON.parse(readFileSync(join(consumer, 'package.json'), 'utf8')); + const manifest = lockedAngularManifest(template, JSON.parse(readFileSync(join(root, 'package-lock.json'), 'utf8'))); + console.log(`Angular consumer toolchain: ${JSON.stringify({ ...manifest.dependencies, ...manifest.devDependencies })}`); + installConsumer(consumer, manifest, tarballs, 'angular'); + const installed = JSON.parse(readFileSync(join(consumer, 'node_modules/@threadplane/angular/package.json'), 'utf8')); + const specifiers = consumerSpecifiers(installed); + const main = join(consumer, 'src/main.ts'); + writeFileSync(main, angularConsumerSource(readFileSync(main, 'utf8'), specifiers)); + console.log(runConsumer(process.execPath, angularBuildCommand(consumer), consumer)); + const stats = JSON.parse(readFileSync(join(consumer, 'dist/consumer/stats.json'), 'utf8')); + assertParserFreeInputs(stats.inputs); + if (!Object.keys(stats.inputs).some((path) => path.includes('node_modules/@threadplane/angular/'))) throw new Error('Angular stats did not include the installed APF artifact'); + console.log(`Angular root bundle: ${Object.keys(stats.inputs).length} inputs, no content parsers. Threadplane inputs: ${Object.keys(stats.inputs).filter((path) => path.includes('node_modules/@threadplane/')).join(', ')}.`); + console.log(`Verified ${specifiers.length} Angular APF exports through CLI compilation/linking with skipLibCheck:false. Empty scaffold only; no runtime behavior is claimed.`); + } finally { rmSync(temporary, { recursive: true, force: true }); } +} + +if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) verifyAngularPackage(); diff --git a/scripts/react-parity/verify-angular-package.spec.mjs b/scripts/react-parity/verify-angular-package.spec.mjs new file mode 100644 index 000000000..5fe46d860 --- /dev/null +++ b/scripts/react-parity/verify-angular-package.spec.mjs @@ -0,0 +1,46 @@ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import test from 'node:test'; +import * as angularVerifier from './verify-angular-package.mjs'; + +const versions = { '@angular/core': '21.1.6', '@angular/common': '21.1.6', '@angular/compiler': '21.1.6', '@angular/platform-browser': '21.1.6', '@angular/compiler-cli': '21.1.6', '@angular/cli': '21.1.5', '@angular/build': '21.1.5', typescript: '5.9.3', rxjs: '7.8.2', tslib: '2.8.1' }; +const lock = () => ({ packages: Object.fromEntries(Object.entries(versions).map(([name, version]) => [`node_modules/${name}`, { version }])) }); +test('Angular consumer pins runtime and tool versions from the root lock, not smoke lanes', () => { + assert.equal(typeof angularVerifier.lockedAngularManifest, 'function'); + const result = angularVerifier.lockedAngularManifest({ private: true }, lock()); + assert.equal(result.dependencies['@angular/core'], '21.1.6'); + assert.equal(result.dependencies['@angular/compiler'], '21.1.6'); + assert.equal(result.devDependencies['@angular/compiler-cli'], '21.1.6'); + assert.equal(result.devDependencies['@angular/cli'], '21.1.5'); + assert.equal(result.devDependencies['@angular/build'], '21.1.5'); + assert.equal(result.devDependencies.typescript, '5.9.3'); +}); +test('Angular consumer refuses missing or mixed-major toolchain entries', () => { + assert.equal(typeof angularVerifier.lockedAngularManifest, 'function'); + const missing = lock(); + delete missing.packages['node_modules/@angular/cli']; + assert.throws(() => angularVerifier.lockedAngularManifest({}, missing), /lock/); + const mixed = lock(); + mixed.packages['node_modules/@angular/build'].version = '22.0.0'; + assert.throws(() => angularVerifier.lockedAngularManifest({}, mixed), /major/); +}); +test('Angular consumer uses installed CLI build with actual bundle stats, never raw Node APF execution', () => { + assert.equal(typeof angularVerifier.angularBuildCommand, 'function'); + assert.deepEqual(angularVerifier.angularBuildCommand('/tmp/consumer'), ['/tmp/consumer/node_modules/@angular/cli/bin/ng.js', 'build', '--configuration=production', '--stats-json']); +}); +test('Angular app imports every supported executable entry and counts namespace exports', () => { + assert.equal(typeof angularVerifier.angularConsumerSource, 'function'); + const template = "import * as angular from '@threadplane/angular';\n/* PACKAGE_IMPORTS */\nconst count = Object.keys(angular).length /* PACKAGE_EXPORT_COUNT */;"; + const source = angularVerifier.angularConsumerSource(template, ['@threadplane/angular', '@threadplane/angular/tools']); + assert.match(source, /from '@threadplane\/angular'/); + assert.match(source, /from "@threadplane\/angular\/tools"/); + assert.match(source, /Object.keys\(entry0\).length/); +}); +test('Angular fixture uses strict declarations and an application builder', () => { + const base = 'fixtures/react-parity/consumers/angular/'; + const config = JSON.parse(readFileSync(`${base}tsconfig.json`, 'utf8')); + assert.equal(config.compilerOptions.skipLibCheck, false); + assert.equal(config.angularCompilerOptions.strictTemplates, true); + const workspace = JSON.parse(readFileSync(`${base}angular.json`, 'utf8')); + assert.equal(workspace.projects.consumer.architect.build.builder, '@angular/build:application'); +}); diff --git a/scripts/react-parity/verify-boundaries.mjs b/scripts/react-parity/verify-boundaries.mjs new file mode 100644 index 000000000..b4a025725 --- /dev/null +++ b/scripts/react-parity/verify-boundaries.mjs @@ -0,0 +1,129 @@ +import { existsSync, readFileSync, readdirSync } from 'node:fs'; +import { dirname, join, relative, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import ts from 'typescript'; +import { angularTransitionProjects, assertFinalRelease, emittedEntries, forbiddenDependency, manifestViolations, packageOf, privateScaffoldProjects, scanProjects, sourceEntry } from './package-policy.mjs'; + +export const foundationProjects = privateScaffoldProjects; +const optional = /(?:^|\/)(?:testing|zod|math)(?:\/|$)/; +const reactFeature = /^(?:chat|markdown|a2ui|debug|tools|testing|render)(?:\/|$)/; +const sourceFile = /\.(?:[cm]?[jt]sx?)$/; +const testFile = /(?:\.(?:spec|test|type-test)\.[cm]?[jt]sx?$|\/test-setup\.)/; +const readJson = (path) => JSON.parse(readFileSync(path, 'utf8')); + +function filesIn(directory) { + if (!existsSync(directory)) return []; + return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => { + const path = join(directory, entry.name); + return entry.isDirectory() ? filesIn(path) : sourceFile.test(path) && !testFile.test(path) ? [path] : []; + }); +} + +// Parse syntax rather than matching source text: type-only imports, import types, +// re-exports, dynamic imports and CommonJS imports all contribute dependency edges. +function importsIn(path) { + const text = readFileSync(path, 'utf8'); + const source = ts.createSourceFile(path, text, ts.ScriptTarget.Latest, true); + const imports = []; + const add = (node) => { if (node && ts.isStringLiteralLike(node)) imports.push(node.text); }; + function visit(node) { + if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) add(node.moduleSpecifier); + if (ts.isImportTypeNode(node) && ts.isLiteralTypeNode(node.argument)) add(node.argument.literal); + if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference)) add(node.moduleReference.expression); + if (ts.isCallExpression(node) && (node.expression.kind === ts.SyntaxKind.ImportKeyword || (ts.isIdentifier(node.expression) && node.expression.text === 'require'))) add(node.arguments[0]); + ts.forEachChild(node, visit); + } + visit(source); + // Triple-slash type references can leak a dependency without an import node. + imports.push(...source.typeReferenceDirectives.map((reference) => reference.fileName)); + imports.push(...source.referencedFiles.map((reference) => reference.fileName.startsWith('.') ? reference.fileName : `./${reference.fileName}`)); + return imports; +} + +function projectOf(path) { + return path.replaceAll('\\', '/').match(/(?:^|\/)(?:dist\/)?libs\/([^/]+)\//)?.[1]; +} +export function verifyBoundaries({ root = process.cwd(), mode = 'source', projects = scanProjects, angularTransitions = angularTransitionProjects, telemetryBrowserTransition = true, finalRelease = false } = {}) { + root = resolve(root); + const errors = new Set(finalRelease ? assertFinalRelease({ projects, angularTransitions, telemetryBrowserTransition }) : []); + const configPath = join(root, 'tsconfig.base.json'); + const config = existsSync(configPath) ? ts.readConfigFile(configPath, ts.sys.readFile).config : {}; + const options = ts.convertCompilerOptionsFromJson(config.compilerOptions ?? {}, root).options; + options.pathsBasePath = root; + options.moduleResolution = ts.ModuleResolutionKind.Bundler; + const cache = new Map(); + const prefix = mode === 'built' ? 'dist/libs' : 'libs'; + const manifestFor = (project) => { + const path = join(root, prefix, project, 'package.json'); + return existsSync(path) ? readJson(path) : undefined; + }; + function resolveImport(specifier, from) { + if (mode === 'source') return ts.resolveModuleName(specifier, from, options, ts.sys).resolvedModule?.resolvedFileName; + if (specifier.startsWith('.')) { + const base = resolve(dirname(from), specifier); + const declaration = from.endsWith('.d.ts'); + const candidates = declaration ? [base.replace(/\.js$/, '.d.ts'), base, `${base}.d.ts`, join(base, 'index.d.ts')] : [base, `${base}.js`, join(base, 'index.js')]; + return candidates.find((path) => existsSync(path) && sourceFile.test(path)); + } + const match = specifier.match(/^@threadplane\/([^/]+)(?:\/(.*))?$/); + if (!match) return undefined; + const manifest = manifestFor(match[1]); + const declaration = from.endsWith('.d.ts'); + const target = emittedEntries(manifest, match[2] ? `./${match[2]}` : '.').find((entry) => declaration ? /\.d\.[cm]?ts$/.test(entry) : /\.[cm]?js$/.test(entry)); + return target ? join(root, prefix, match[1], target) : undefined; + } + for (const project of projects) { + const directory = join(root, prefix, project); + if (!existsSync(directory)) { errors.add(`${project}: missing ${mode} package`); continue; } + const manifestPath = join(directory, 'package.json'); + if (existsSync(manifestPath)) { + const manifest = readJson(manifestPath); + for (const error of manifestViolations(project, manifest, { angularTransitions, telemetryBrowserTransition })) errors.add(error); + } + const allFiles = filesIn(mode === 'source' ? join(directory, 'src') : directory); + // Existing Angular secondary entry points live alongside src. + if (mode === 'source' && (project === 'angular' || angularTransitions.includes(project))) allFiles.push(...filesIn(directory).filter((path) => !path.includes('/src/'))); + const manifest = manifestFor(project); + const roots = mode === 'source' ? [join(directory, sourceEntry(project, angularTransitions))] : emittedEntries(manifest).filter((value) => sourceFile.test(value)).map((value) => join(directory, value)); + const browserEntries = mode === 'built' ? emittedEntries(manifest, './browser').map((value) => join(directory, value)) : []; + const browserPath = (path) => project === 'telemetry' && telemetryBrowserTransition && (path.startsWith(join(directory, mode === 'source' ? 'src/browser' : 'browser') + '/') || browserEntries.includes(path)); + const visited = new Set(); + function visit(path, rootRuntime, ancestry = [], browserTransition = false) { + const key = `${path}:${rootRuntime}:${browserTransition}`; + if (visited.has(key)) return; + visited.add(key); + if (!existsSync(path)) { errors.add(`${project}: unresolved ${relative(root, path)}`); return; } + const dependencies = cache.get(path) ?? importsIn(path); + cache.set(path, dependencies); + for (const specifier of dependencies) { + const target = resolveImport(specifier, path); + const targetProject = target && projectOf(target); + const normalized = targetProject ? `@threadplane/${targetProject}` : specifier; + const trail = [...ancestry, relative(root, path), specifier].join(' -> '); + const policy = { angularTransitions, rootRuntime, browserTransition: browserTransition && browserPath(path) }; + if (forbiddenDependency(project, specifier, policy) || forbiddenDependency(project, normalized, policy)) errors.add(`${project}: forbidden dependency ${trail}`); + // Every core entry is dependency-free. Explicitly + // review any future external dependency instead of allowing a wrapper + // package to hide a framework/parser dependency behind its own imports. + if (project === 'core' && (!target || target.includes('/node_modules/')) && !specifier.startsWith('.')) errors.add(`${project}: unreviewed dependency ${trail}`); + if (rootRuntime && (optional.test(specifier) || ['zod', 'katex'].includes(packageOf(specifier)) || (target && optional.test(relative(directory, target))))) errors.add(`${project}: optional/testing dependency reachable from root: ${trail}`); + if (project === 'react' && rootRuntime && ((specifier.startsWith('@threadplane/react/') && reactFeature.test(specifier.slice('@threadplane/react/'.length))) || (targetProject === 'react' && reactFeature.test(relative(join(directory, 'src'), target))))) errors.add(`${project}: feature dependency reachable from root: ${trail}`); + if (target && !target.includes('/node_modules/')) visit(target, rootRuntime, [...ancestry, relative(root, path)], browserTransition && browserPath(target)); + else if (!target && (specifier.startsWith('.') || specifier.startsWith('@threadplane/'))) errors.add(`${project}: unresolved dependency ${trail}`); + } + } + for (const path of allFiles) visit(path, false, [], browserPath(path)); + if (!angularTransitions.includes(project)) { + if (!roots.length) errors.add(`${project}: missing root exports`); + for (const path of roots) visit(path, true); + } + } + return [...errors].sort(); +} + +if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { + const mode = process.argv.includes('--built') ? 'built' : 'source'; + const errors = verifyBoundaries({ mode, finalRelease: process.argv.includes('--final-release') }); + if (errors.length) { console.error(errors.join('\n')); process.exitCode = 1; } + else console.log(`React parity ${mode} boundaries verified.`); +} diff --git a/scripts/react-parity/verify-boundaries.spec.mjs b/scripts/react-parity/verify-boundaries.spec.mjs new file mode 100644 index 000000000..135b56e0b --- /dev/null +++ b/scripts/react-parity/verify-boundaries.spec.mjs @@ -0,0 +1,324 @@ +import assert from 'node:assert/strict'; +import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { dirname, join } from 'node:path'; +import test from 'node:test'; +import { verifyBoundaries } from './verify-boundaries.mjs'; + +const finalOptions = { angularTransitions: [], telemetryBrowserTransition: false }; +for (const mode of ['source', 'built']) { + for (const field of ['dependencies', 'peerDependencies', 'optionalDependencies']) { + test(`empty ${mode} core rejects manifest-only ${field}`, (t) => { + const prefix = mode === 'source' ? 'libs/core' : 'dist/libs/core'; + const root = fixture(t, { + [`${prefix}/package.json`]: JSON.stringify({ [field]: { lodash: '*' }, exports: { '.': { types: './src/index.d.ts', default: './src/index.js' } } }), + [`${prefix}/src/index.ts`]: 'export {};', + [`${prefix}/src/index.js`]: 'export {};', + [`${prefix}/src/index.d.ts`]: 'export {};', + }); + assert.ok(verifyBoundaries({ root, mode, projects: ['core'] }).includes(`core: forbidden ${field} entry lodash`)); + }); + } +} +const finalCases = [ + ['react', '@angular/core'], ['react', '@threadplane/langgraph'], + ['langgraph', '@threadplane/angular'], ['ag-ui', '@threadplane/render'], + ['core', '@angular/core'], ['core', 'marked'], ['core', 'rxjs'], + ['content', '@threadplane/ag-ui'], ['render', '@threadplane/content'], + ['render', '@angular/core'], ['angular', '@threadplane/telemetry'], + ['angular', 'react'], ['angular', '@threadplane/langgraph'], ['angular', '@ag-ui/client'], +]; +for (const variant of ['source', 'built-js', 'built-d.ts']) { + const mode = variant === 'source' ? 'source' : 'built'; + for (const [project, dependency] of finalCases) { + test(`final role ${variant} transitively rejects ${project} -> ${dependency}`, (t) => { + const prefix = mode === 'source' ? 'libs' : 'dist/libs'; + const extension = mode === 'source' ? 'ts' : variant.slice('built-'.length); + const entry = project === 'angular' ? 'public-api' : 'index'; + const files = { + [`${prefix}/${project}/package.json`]: JSON.stringify({ exports: { '.': { types: `./src/${entry}.d.ts`, default: `./src/${entry}.js` } } }), + [`${prefix}/${project}/src/${entry}.js`]: 'export {};', + [`${prefix}/${project}/src/${entry}.d.ts`]: 'export {};', + [`${prefix}/${project}/src/${entry}.${extension}`]: extension === 'js' ? "export * from './bridge.js';" : "export type { X } from './bridge.js';", + [`${prefix}/${project}/src/bridge.${extension}`]: extension === 'js' ? `export * from '${dependency}';` : `export type { X } from '${dependency}';`, + }; + const errors = verifyBoundaries({ root: fixture(t, files), projects: [project], mode, ...finalOptions }); + assert.ok(errors.some((error) => error.includes('forbidden dependency') && error.includes(dependency)), errors.join('\n')); + }); + } +} + +for (const mode of ['source', 'built']) { + for (const entry of ['index', 'shared/public-api', 'node/index']) { + test(`telemetry ${mode} ${entry} cannot reach Angular through browser`, (t) => { + const prefix = mode === 'source' ? 'libs/telemetry/src' : 'dist/libs/telemetry'; + const extension = mode === 'source' ? 'ts' : 'd.ts'; + const browser = mode === 'source' ? 'browser/public-api' : 'browser/index'; + const files = { + [`${prefix}/index.${extension}`]: 'export {};', + [`${prefix}/${entry}.${extension}`]: `export * from '${entry.includes('/') ? '../' : './'}${browser}.js';`, + [`${prefix}/${browser}.${extension}`]: "export type { Signal } from '@angular/core';", + }; + if (mode === 'built') files['dist/libs/telemetry/package.json'] = JSON.stringify({ exports: { '.': { types: './index.d.ts' }, './browser': { types: './browser/index.d.ts' } } }); + const errors = verifyBoundaries({ root: fixture(t, files), projects: ['telemetry'], mode }); + assert.ok(errors.some((error) => error.includes('forbidden dependency') && error.includes('@angular/core')), errors.join('\n')); + }); + } + test(`telemetry ${mode} browser transition allows Angular but never React`, (t) => { + const prefix = mode === 'source' ? 'libs/telemetry/src' : 'dist/libs/telemetry'; + const extension = mode === 'source' ? 'ts' : 'd.ts'; + const browser = mode === 'source' ? 'browser/public-api' : 'browser/index'; + const files = { + [`${prefix}/index.${extension}`]: 'export {};', + [`${prefix}/${browser}.${extension}`]: "export type { Signal } from '@angular/core';", + }; + if (mode === 'built') files['dist/libs/telemetry/package.json'] = JSON.stringify({ exports: { '.': { types: './index.d.ts' }, './browser': { types: './browser/index.d.ts' } } }); + const root = fixture(t, files); + assert.deepEqual(verifyBoundaries({ root, projects: ['telemetry'], mode }), []); + writeFileSync(join(root, prefix, `${browser}.${extension}`), "export type { ReactNode } from 'react';"); + assert.ok(verifyBoundaries({ root, projects: ['telemetry'], mode }).some((error) => error.includes('forbidden dependency') && error.includes('react'))); + }); +} + +test('default source scan always includes telemetry', (t) => { + const errors = verifyBoundaries({ root: fixture(t, { 'libs/telemetry/src/index.ts': "export * from '@angular/core';" }) }); + assert.ok(errors.some((error) => error.startsWith('telemetry: forbidden dependency'))); +}); + +test('new Angular facade uses its public-api source entry', (t) => { + const root = fixture(t, { 'libs/angular/src/public-api.ts': 'export {};' }); + assert.deepEqual(verifyBoundaries({ root, projects: ['angular'], ...finalOptions }), []); +}); + +test('new Angular facade requires its declared public-api source entry', (t) => { + const root = fixture(t, { 'libs/angular/src/index.ts': 'export {};' }); + assert.ok(verifyBoundaries({ root, projects: ['angular'], ...finalOptions }).some((error) => error.includes('public-api.ts'))); +}); + +test('final-release assertion is opt-in and fails while transitions remain', (t) => { + const root = fixture(t, { 'libs/react/src/index.ts': 'export {};' }); + assert.deepEqual(verifyBoundaries({ root, projects: ['react'] }), []); + assert.ok(verifyBoundaries({ root, projects: ['react'], finalRelease: true }).some((error) => error.includes('transition remains enabled'))); +}); + +test('default built scan never omits telemetry', (t) => { + const root = fixture(t, { 'dist/libs/telemetry/package.json': JSON.stringify({ exports: { '.': { types: './index.d.ts' } } }), 'dist/libs/telemetry/index.d.ts': "export type { Signal } from '@angular/core';" }); + assert.ok(verifyBoundaries({ root, mode: 'built' }).some((error) => error.startsWith('telemetry: forbidden dependency'))); +}); + +function fixture(t, files) { + const root = mkdtempSync(join(tmpdir(), 'threadplane-boundaries-')); + t.after(() => rmSync(root, { recursive: true, force: true })); + for (const [path, content] of Object.entries(files)) { + mkdirSync(dirname(join(root, path)), { recursive: true }); + writeFileSync(join(root, path), content); + } + return root; +} + +const sourceCases = [ + ['core type-only React import', 'core', "import type { ReactNode } from 'react'; export type X = ReactNode;"], + ['core Angular re-export', 'core', "export type { Signal } from '@angular/core';"], + ['backend UI import', 'langgraph', "export * from '@threadplane/react';"], + ['AG-UI backend renderer import', 'ag-ui', "export * from '@threadplane/render';"], + ['React Angular import', 'react', "export * from '@angular/core';"], + ['React backend type import', 'react', "type X = import('@threadplane/langgraph').X; export type { X };"], + ['Angular React import', 'chat', "export * from '@threadplane/react';"], + ['core parser import', 'core', "export * from '@cacheplane/partial-markdown';"], + ['core RxJS import', 'core', "export * from 'rxjs';"], +]; +for (const [label, project, code] of sourceCases) { + test(`rejects ${label}`, (t) => { + const root = fixture(t, { [`libs/${project}/src/index.ts`]: code }); + assert.ok(verifyBoundaries({ root, projects: [project], ...finalOptions }).some((error) => error.includes('forbidden dependency'))); + }); +} +test('follows TS aliases and relative re-exports transitively, including types', (t) => { + const root = fixture(t, { + 'tsconfig.base.json': JSON.stringify({ compilerOptions: { paths: { '@shared': ['./shared/index.ts'] } } }), + 'libs/core/src/index.ts': "export type { X } from '@shared';", + 'shared/index.ts': "export type { X } from './hidden.js';", + 'shared/hidden.ts': "export type { ReactNode as X } from 'react';", + }); + assert.ok(verifyBoundaries({ root, projects: ['core'] }).some((error) => error.includes('react'))); +}); +test('rejects cross-package relative imports', (t) => { + const root = fixture(t, { + 'libs/core/src/index.ts': "export * from '../../react/src/index.js';", + 'libs/react/src/index.ts': 'export {};', + }); + assert.ok(verifyBoundaries({ root, projects: ['core'] }).length > 0); +}); +for (const optional of ['testing', 'schema/zod', 'math']) { + test(`isolates ${optional} from root transitive declarations`, (t) => { + const root = fixture(t, { + 'libs/core/src/index.ts': "export type { X } from './bridge.js';", + 'libs/core/src/bridge.ts': `export type { X } from './${optional}/index.js';`, + [`libs/core/src/${optional}/index.ts`]: 'export type X = string;', + }); + assert.ok(verifyBoundaries({ root, projects: ['core'] }).length > 0); + }); +} +test('allows isolated testing entries without making them root dependencies', (t) => { + const root = fixture(t, { + 'libs/core/src/index.ts': 'export {};', + 'libs/core/src/testing/index.ts': 'export {};', + }); + assert.deepEqual(verifyBoundaries({ root, projects: ['core'] }), []); +}); +test('rejects core validation dependencies outside the root graph', (t) => { + const root = fixture(t, { + 'libs/core/src/index.ts': 'export {};', + 'libs/core/src/tools/index.ts': "export type { ZodType } from 'zod';", + }); + assert.ok(verifyBoundaries({ root, projects: ['core'] }).some((error) => error.includes('forbidden dependency') && error.includes('zod'))); +}); +for (const extension of ['ts', 'js', 'd.ts']) { + for (const dependency of ['some-validator', 'zod', 'tslib']) { + test(`rejects off-root core ${extension} dependency on ${dependency}`, (t) => { + const mode = extension === 'ts' ? 'source' : 'built'; + const prefix = mode === 'source' ? 'libs/core' : 'dist/libs/core'; + const root = fixture(t, { + [`${prefix}/package.json`]: JSON.stringify({ exports: { '.': { types: './src/index.d.ts', import: './src/index.js' } } }), + [`${prefix}/src/index.ts`]: 'export {};', + [`${prefix}/src/index.js`]: 'export {};', + [`${prefix}/src/index.d.ts`]: 'export {};', + [`${prefix}/src/tools/index.${extension}`]: `export * from '${dependency}';`, + }); + assert.ok(verifyBoundaries({ root, mode, projects: ['core'] }).some((error) => error.includes('unreviewed') && error.includes(dependency))); + }); + } +} +for (const extension of ['js', 'd.ts']) { + test(`inspects built ${extension} imports`, (t) => { + const root = fixture(t, { + 'dist/libs/core/package.json': JSON.stringify({ name: '@threadplane/core', exports: { '.': { import: './src/index.js', types: './src/index.d.ts' } } }), + 'dist/libs/core/src/index.js': 'export {};', + 'dist/libs/core/src/index.d.ts': 'export {};', + [`dist/libs/core/src/index.${extension}`]: "export * from './bridge.js';", + [`dist/libs/core/src/bridge.${extension}`]: "export * from 'react';", + }); + assert.ok(verifyBoundaries({ root, mode: 'built', projects: ['core'] }).length > 0); + }); +} +test('does not mistake comments or ordinary strings for imports', (t) => { + const root = fixture(t, { 'libs/core/src/index.ts': "// import 'react';\nexport const example = \"import 'react'\";" }); + assert.deepEqual(verifyBoundaries({ root, projects: ['core'] }), []); +}); +test('fails closed for unresolved local imports', (t) => { + const root = fixture(t, { 'libs/core/src/index.ts': "export * from './missing.js';" }); + assert.ok(verifyBoundaries({ root, projects: ['core'] }).some((error) => error.includes('unresolved'))); +}); +test('rejects unreviewed external dependencies from the core root', (t) => { + const root = fixture(t, { 'libs/core/src/index.ts': "export * from 'some-parser';" }); + assert.ok(verifyBoundaries({ root, projects: ['core'] }).some((error) => error.includes('some-parser'))); +}); +test('keeps optional math dependencies out of content root declarations', (t) => { + const root = fixture(t, { 'libs/content/src/index.ts': "export type { KatexOptions } from 'katex';" }); + assert.ok(verifyBoundaries({ root, projects: ['content'] }).some((error) => error.includes('katex'))); +}); +test('rejects a missing foundation root entry', (t) => { + const root = fixture(t, { 'libs/core/src/other.ts': 'export {};' }); + assert.ok(verifyBoundaries({ root, projects: ['core'] }).length > 0); +}); +test('checks declared dependencies even when no source imports them yet', (t) => { + const root = fixture(t, { + 'libs/langgraph/src/index.ts': 'export {};', + 'libs/langgraph/package.json': JSON.stringify({ dependencies: { react: '^19.0.0' } }), + }); + assert.ok(verifyBoundaries({ root, projects: ['langgraph'], ...finalOptions }).some((error) => error.includes('react'))); +}); + +const builtCases = [ + ['core to Angular', 'core', '@angular/core'], + ['core to React', 'core', 'react'], + ['LangGraph backend to UI', 'langgraph', '@threadplane/react'], + ['AG-UI backend to UI', 'ag-ui', '@threadplane/render'], + ['backend to Angular UI', 'langgraph', '@threadplane/angular'], + ['React to Angular', 'react', '@angular/core'], + ['React to backend', 'react', '@threadplane/langgraph'], + ['React to retired renderer', 'react', '@threadplane/react-render'], +]; +for (const extension of ['js', 'd.ts']) { + for (const [label, project, dependency] of builtCases) { + test(`rejects built ${extension} ${label}`, (t) => { + const root = fixture(t, { + [`dist/libs/${project}/package.json`]: JSON.stringify({ name: `@threadplane/${project}`, exports: { '.': { import: './src/index.js', types: './src/index.d.ts' } } }), + [`dist/libs/${project}/src/index.js`]: 'export {};', + [`dist/libs/${project}/src/index.d.ts`]: 'export {};', + [`dist/libs/${project}/src/index.${extension}`]: extension === 'd.ts' ? `export type X = import('${dependency}').X;` : `export * from '${dependency}';`, + }); + const errors = verifyBoundaries({ root, mode: 'built', projects: [project], ...finalOptions }); + assert.ok(errors.some((error) => error.includes('forbidden dependency') && error.includes(dependency)), errors.join('\n')); + }); + } +} + +// Exercise the default CLI project selection as well as Angular's actual APF +// layout: .mjs in fesm2022 and declarations under types, with a default export +// condition rather than an import condition. +for (const project of ['chat', 'langgraph', 'ag-ui', 'render']) { + for (const extension of ['mjs', 'd.ts']) { + test(`default built scan rejects ${project} ${extension} importing React`, (t) => { + const files = {}; + for (const name of ['core', 'content', 'angular', 'react', 'chat', 'langgraph', 'ag-ui', 'render', 'a2ui', 'telemetry']) { + files[`dist/libs/${name}/package.json`] = JSON.stringify({ name: `@threadplane/${name}`, exports: { '.': { types: `./types/${name}.d.ts`, default: `./fesm2022/${name}.mjs` } } }); + files[`dist/libs/${name}/fesm2022/${name}.mjs`] = 'export {};'; + files[`dist/libs/${name}/types/${name}.d.ts`] = 'export {};'; + } + const directory = extension === 'mjs' ? 'fesm2022' : 'types'; + files[`dist/libs/${project}/${directory}/${project}.${extension}`] = extension === 'd.ts' ? "export type X = import('react').ReactNode;" : "export * from '@threadplane/react';"; + const errors = verifyBoundaries({ root: fixture(t, files), mode: 'built' }); + assert.ok(errors.some((error) => error.startsWith(`${project}: forbidden dependency`) && error.includes('react')), errors.join('\n')); + }); + } +} + +for (const extension of ['ts', 'js', 'd.ts']) { + for (const feature of ['chat', 'markdown', 'a2ui', 'debug', 'tools', 'testing', 'render', 'render/types']) { + test(`React root excludes ${feature} from transitive ${extension} exports`, (t) => { + const mode = extension === 'ts' ? 'source' : 'built'; + const prefix = mode === 'source' ? 'libs/react' : 'dist/libs/react'; + const root = fixture(t, { + [`${prefix}/package.json`]: JSON.stringify({ exports: { '.': { types: './src/index.d.ts', import: './src/index.js' } } }), + [`${prefix}/src/index.js`]: 'export {};', + [`${prefix}/src/index.d.ts`]: 'export {};', + [`${prefix}/src/index.${extension}`]: "export * from './bridge.js';", + [`${prefix}/src/bridge.${extension}`]: `export * from './${feature}/index.js';`, + [`${prefix}/src/${feature}/index.${extension}`]: 'export {};', + }); + assert.ok(verifyBoundaries({ root, mode, projects: ['react'] }).some((error) => error.includes('reachable from root') && error.includes(feature))); + }); + } +} + +test('React root permits binding implementation and core contracts', (t) => { + const root = fixture(t, { + 'tsconfig.base.json': JSON.stringify({ compilerOptions: { paths: { '@threadplane/core': ['./libs/core/src/index.ts'] } } }), + 'libs/react/src/index.ts': "'use client'; export * from './use-agent.js';", + 'libs/react/src/use-agent.ts': "export type { Agent } from '@threadplane/core';", + 'libs/core/src/index.ts': 'export interface Agent {}', + }); + assert.deepEqual(verifyBoundaries({ root, projects: ['react'] }), []); +}); + +for (const extension of ['mjs', 'd.ts']) { + test(`resolves legacy built main/module/types for Angular ${extension} dependencies`, (t) => { + const files = { + 'dist/libs/chat/package.json': JSON.stringify({ name: '@threadplane/chat', exports: { '.': { types: './index.d.ts', default: './index.mjs' } } }), + 'dist/libs/chat/index.mjs': 'export {};', + 'dist/libs/chat/index.d.ts': 'export {};', + [`dist/libs/chat/index.${extension}`]: "export * from '@threadplane/a2ui';", + 'dist/libs/a2ui/package.json': JSON.stringify({ name: '@threadplane/a2ui', types: './src/index.d.ts', module: './src/index.js', main: './src/index.js' }), + 'dist/libs/a2ui/src/index.js': 'export {};', + 'dist/libs/a2ui/src/index.d.ts': 'export {};', + }; + const root = fixture(t, files); + assert.deepEqual(verifyBoundaries({ root, mode: 'built', projects: ['chat'] }), []); + // Following the legacy entry is mandatory, not just accepting the package + // name: an indirect React edge must still fail in either output format. + const entry = extension === 'd.ts' ? 'index.d.ts' : 'index.js'; + writeFileSync(join(root, 'dist/libs/a2ui/src', entry), "export * from 'react';"); + assert.ok(verifyBoundaries({ root, mode: 'built', projects: ['chat'] }).some((error) => error.includes('forbidden dependency') && error.includes('react'))); + }); +} diff --git a/scripts/react-parity/verify-packages.mjs b/scripts/react-parity/verify-packages.mjs new file mode 100644 index 000000000..a4b93c56d --- /dev/null +++ b/scripts/react-parity/verify-packages.mjs @@ -0,0 +1,198 @@ +import { execFileSync } from 'node:child_process'; +import { existsSync, lstatSync, mkdtempSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join, relative, resolve, sep } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import ts from 'typescript'; +import { buildSync } from 'esbuild'; +import { satisfies } from 'semver'; +import { angularTransitionProjects, emittedEntries, manifestViolations, privateScaffoldProjects, scanProjects } from './package-policy.mjs'; + +function filesIn(directory) { + return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() ? filesIn(join(directory, entry.name)) : [join(directory, entry.name)]); +} +function clientDirective(path) { + const source = ts.createSourceFile(path, readFileSync(path, 'utf8'), ts.ScriptTarget.Latest, true); + const first = source.statements[0]; + return first && ts.isExpressionStatement(first) && ts.isStringLiteral(first.expression) && first.expression.text === 'use client'; +} + +function metadataExport(subpath, entry) { + if (!/\.(?:md|json)$/.test(subpath)) return false; + return typeof entry === 'string' ? subpath === entry : + entry !== null && typeof entry === 'object' && !Array.isArray(entry) && + Object.keys(entry).length === 1 && entry.default === subpath; +} + +export function consumerSpecifiers(manifest) { + return Object.entries(manifest.exports).filter(([subpath, entry]) => !metadataExport(subpath, entry)) + .map(([subpath]) => manifest.name + (subpath === '.' ? '' : subpath.slice(1))); +} + +export function validatePackage(directory, { angularTransitions = angularTransitionProjects, telemetryBrowserTransition = true } = {}) { + const errors = []; + const manifest = JSON.parse(readFileSync(join(directory, 'package.json'), 'utf8')); + const project = manifest.name?.replace(/^@threadplane\//, ''); + const scaffold = privateScaffoldProjects.includes(project); + errors.push(...manifestViolations(project, manifest, { angularTransitions, telemetryBrowserTransition })); + if (scaffold && manifest.private !== true) errors.push('Foundation package must remain private.'); + if (manifest.type !== 'module') errors.push('Foundation package must emit ESM.'); + if (manifest.license !== 'MIT') errors.push('Expected MIT package license.'); + for (const file of ['LICENSE.md', 'README.md']) if (!existsSync(join(directory, file))) errors.push(`Missing ${file}`); + if (!emittedEntries(manifest).length) errors.push('Missing root export.'); + const exports = manifest.exports ?? { '.': { types: manifest.types ?? manifest.typings, default: manifest.module ?? manifest.main } }; + for (const [subpath, entry] of Object.entries(exports)) { + const conditions = typeof entry === 'string' ? { default: entry } : entry; + const metadataAsset = metadataExport(subpath, entry); + if (!conditions || typeof conditions !== 'object' || Array.isArray(conditions) || !Object.keys(conditions).length) { errors.push(`${subpath}: invalid export conditions.`); continue; } + if (scaffold && !metadataAsset) { + // ng-packagr's APF root uses types/default, without an import condition. + const angularRoot = project === 'angular' && subpath === '.'; + if (!conditions.types || !conditions.default || (!angularRoot && !conditions.import)) errors.push(`${subpath}: requires ${angularRoot ? 'types and default' : 'types, import and default'} export conditions.`); + } + for (const [condition, target] of Object.entries(conditions)) { + if (typeof target !== 'string' || !target.startsWith('./') || !resolve(directory, target).startsWith(resolve(directory) + sep)) { errors.push(`${subpath}: invalid export target ${target}`); continue; } + const path = join(directory, target); + if (!existsSync(path)) { errors.push(`${subpath}: missing export target ${target}`); continue; } + if (condition === 'types' && !target.endsWith('.d.ts')) errors.push(`${subpath}: types must resolve to declarations.`); + if (condition !== 'types' && !metadataAsset && !/\.m?js$/.test(target)) errors.push(`${subpath}: runtime must resolve to JavaScript ESM (.js or .mjs).`); + if (!metadataAsset && ['import', 'default'].includes(condition) && manifest.name === '@threadplane/react' && !clientDirective(path)) errors.push(`${subpath}: missing use client directive.`); + } + } + for (const file of filesIn(directory)) if (/\.(?:spec|test|type-test)\.[cm]?[jt]sx?$|\/test-setup\./.test(file) || (/\.tsx?$/.test(file) && !file.endsWith('.d.ts'))) errors.push(`Unexpected production artifact ${relative(directory, file)}`); + return errors; +} + +// Resolve only declared local dependencies, including peers, before npm sees a +// manifest. Unknown Threadplane packages fail closed instead of using npm. +export function localDependencyProjects(projects, readManifest) { + const selected = new Set(); + const manifests = new Map(); + function visit(project) { + if (selected.has(project)) return; + if (!scanProjects.includes(project)) throw new Error(`No local artifact policy for ${project}`); + selected.add(project); + const manifest = readManifest(project); + manifests.set(project, manifest); + for (const field of ['dependencies', 'peerDependencies', 'optionalDependencies']) { + for (const [name, range] of Object.entries(manifest[field] ?? {})) { + if (!name.startsWith('@threadplane/')) continue; + const dependency = name.slice('@threadplane/'.length); + visit(dependency); + const version = manifests.get(dependency).version; + if (!version || !satisfies(version, range)) throw new Error(`Local ${name}@${version} does not satisfy ${project} ${field} range ${range}`); + } + } + } + projects.forEach(visit); + return [...selected]; +} + +export function runConsumer(command, args, cwd) { + console.log(`$ ${command} ${args.join(' ')} (cwd: ${cwd})`); + return execFileSync(command, args, { + cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'inherit'], + env: { ...process.env, npm_config_legacy_peer_deps: 'false', NPM_CONFIG_LEGACY_PEER_DEPS: 'false', NG_CLI_ANALYTICS: 'false' }, + }); +} + +export function packLocalArtifacts(root, temporary, projects) { + const selected = localDependencyProjects(projects, (project) => + JSON.parse(readFileSync(join(root, 'dist/libs', project, 'package.json'), 'utf8'))); + const dependencies = {}; + for (const project of selected) { + const packed = JSON.parse(runConsumer('npm', ['pack', join(root, 'dist/libs', project), '--ignore-scripts', '--json', '--pack-destination', temporary], temporary)); + const tarball = join(temporary, packed[0].filename); + dependencies[`@threadplane/${project}`] = `file:${tarball}`; + const unpacked = join(temporary, `packed-${project}`); + mkdirSync(unpacked); + runConsumer('tar', ['-xzf', tarball, '-C', unpacked], temporary); + const errors = validatePackage(join(unpacked, 'package')); + if (errors.length) throw new Error(`${project}:\n${errors.join('\n')}`); + } + return dependencies; +} + +export function installGraphViolations(lock, kind) { + const errors = []; + for (const [path, entry] of Object.entries(lock.packages ?? {})) { + if (!path.includes('node_modules/')) continue; + const name = path.split('node_modules/').at(-1); + if (kind === 'core' && name !== '@threadplane/core') errors.push(`Core installed dependency ${name}`); + if (kind === 'plain' && name.startsWith('@angular/')) errors.push(`Plain consumer installed Angular: ${name}`); + if (kind === 'angular' && ['react', 'react-dom', '@types/react', '@types/react-dom', '@threadplane/react'].includes(name)) errors.push(`Angular consumer installed React: ${name}`); + if (name.startsWith('@langchain/') || name.startsWith('@ag-ui/') || ['openai', '@anthropic-ai/sdk'].includes(name)) errors.push(`Consumer installed backend SDK: ${name}`); + if (name.startsWith('@threadplane/') && (entry.link || !/^file:.*\.tgz$/.test(entry.resolved ?? ''))) errors.push(`${name} must resolve to a local tarball`); + } + return errors; +} + +export function installConsumer(consumer, manifest, localDependencies, kind) { + writeFileSync(join(consumer, 'package.json'), JSON.stringify({ + ...manifest, + dependencies: { ...manifest.dependencies, ...localDependencies }, + // npm must use our candidate for every transitive Threadplane edge too. + overrides: { ...manifest.overrides, ...Object.fromEntries(Object.keys(localDependencies).map((name) => [name, `$${name}`])) }, + }, null, 2)); + console.log(runConsumer('npm', ['install', '--ignore-scripts', '--no-audit', '--no-fund'], consumer)); + const lock = JSON.parse(readFileSync(join(consumer, 'package-lock.json'), 'utf8')); + const errors = installGraphViolations(lock, kind); + if (errors.length) throw new Error(errors.join('\n')); + const footprint = installFootprint(consumer, lock); + const names = Object.keys(lock.packages).filter((path) => path.includes('node_modules/@threadplane/')); + console.log(`${kind} install footprint${kind === 'angular' ? ' (includes Angular CLI/build/compiler dev tooling)' : ''}: ${footprint.installedPackages} installed packages, ${footprint.fileBytes} file bytes; ${footprint.lockedPackages} lock entries including optional platforms. Threadplane artifacts: ${names.join(', ')}. Installation size is separate from framework root bundle size.`); +} + +export function installFootprint(consumer, lock) { + const packages = Object.keys(lock.packages).filter((path) => path.includes('node_modules/')); + const fileBytes = (directory) => readdirSync(directory).reduce((total, name) => { + const path = join(directory, name); + const entry = lstatSync(path); + return total + (entry.isDirectory() ? fileBytes(path) : entry.isFile() ? entry.size : 0); + }, 0); + return { + installedPackages: packages.filter((path) => existsSync(join(consumer, path, 'package.json'))).length, + lockedPackages: packages.length, + fileBytes: fileBytes(join(consumer, 'node_modules')), + }; +} + +export function assertParserFreeInputs(inputs) { + if (!inputs || typeof inputs !== 'object' || !Object.keys(inputs).length) throw new Error('Missing bundler inputs evidence'); + const parser = /(?:^|\/)node_modules\/(?:@cacheplane\/(?:partial-json|partial-markdown)|marked|remark-gfm|katex|shiki)(?:\/|$)/; + const found = Object.keys(inputs).filter((path) => parser.test(path.replaceAll('\\', '/'))); + if (found.length) throw new Error(`Framework root includes content parser inputs: ${found.join(', ')}`); +} + +function verifyPlainExports(root, consumer, projects) { + const specifiers = projects.flatMap((project) => consumerSpecifiers(JSON.parse(readFileSync(join(consumer, 'node_modules/@threadplane', project, 'package.json'), 'utf8')))); + writeFileSync(join(consumer, 'index.mjs'), specifiers.map((specifier) => `await import(${JSON.stringify(specifier)});`).join('\n')); + writeFileSync(join(consumer, 'index.ts'), specifiers.map((specifier, index) => `import * as entry${index} from ${JSON.stringify(specifier)};\nexport type Entry${index} = typeof entry${index};`).join('\n')); + writeFileSync(join(consumer, 'tsconfig.json'), JSON.stringify({ compilerOptions: { target: 'ES2022', module: 'NodeNext', moduleResolution: 'NodeNext', lib: ['ES2022'], types: [], strict: true, skipLibCheck: false, noEmit: true }, files: ['index.ts'] })); + runConsumer(process.execPath, ['index.mjs'], consumer); + runConsumer(process.execPath, [join(root, 'node_modules/typescript/bin/tsc'), '-p', 'tsconfig.json'], consumer); + return specifiers.length; +} + +export function verifyPackedConsumers(root = process.cwd()) { + root = resolve(root); + const temporary = mkdtempSync(join(tmpdir(), 'threadplane-consumer-')); + try { + const projects = privateScaffoldProjects.filter((project) => project !== 'angular'); + const tarballs = packLocalArtifacts(root, temporary, projects); + const core = join(temporary, 'core-consumer'); + mkdirSync(core); + installConsumer(core, { private: true, type: 'module' }, { '@threadplane/core': tarballs['@threadplane/core'] }, 'core'); + const coreCount = verifyPlainExports(root, core, ['core']); + const plain = join(temporary, 'plain-consumer'); + mkdirSync(plain); + installConsumer(plain, { private: true, type: 'module' }, tarballs, 'plain'); + const count = verifyPlainExports(root, plain, Object.keys(tarballs).map((name) => name.slice('@threadplane/'.length))); + writeFileSync(join(plain, 'react-root.mjs'), "import * as react from '@threadplane/react';\nconsole.log(Object.keys(react));\n"); + const bundle = buildSync({ absWorkingDir: plain, entryPoints: [join(plain, 'react-root.mjs')], bundle: true, platform: 'browser', format: 'esm', write: false, metafile: true }); + assertParserFreeInputs(bundle.metafile.inputs); + console.log(`React root bundle: ${Object.keys(bundle.metafile.inputs).length} inputs, ${bundle.outputFiles[0].contents.length} bytes, no content parsers. Inputs: ${Object.keys(bundle.metafile.inputs).join(', ')}.`); + console.log(`Verified ${Object.keys(tarballs).length} private plain tarballs, ${count} ESM/type exports, and ${coreCount} isolated core exports with skipLibCheck:false. These are empty scaffolds; no framework runtime behavior is claimed.`); + } finally { rmSync(temporary, { recursive: true, force: true }); } +} +if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) verifyPackedConsumers(); diff --git a/scripts/react-parity/verify-packages.spec.mjs b/scripts/react-parity/verify-packages.spec.mjs new file mode 100644 index 000000000..718602871 --- /dev/null +++ b/scripts/react-parity/verify-packages.spec.mjs @@ -0,0 +1,134 @@ +import assert from 'node:assert/strict'; +import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { dirname, join } from 'node:path'; +import test from 'node:test'; +import * as packageVerifier from './verify-packages.mjs'; +const { validatePackage } = packageVerifier; + +function fixture(t, change = {}) { + const directory = mkdtempSync(join(tmpdir(), 'threadplane-package-')); + t.after(() => rmSync(directory, { recursive: true, force: true })); + const manifest = { name: '@threadplane/react', private: true, type: 'module', license: 'MIT', exports: { '.': { types: './src/index.d.ts', import: './src/index.js', default: './src/index.js' } }, ...change.manifest }; + const files = { 'package.json': JSON.stringify(manifest), 'README.md': 'Private scaffolding', 'LICENSE.md': 'MIT', 'src/index.js': "'use client';\nexport {};", 'src/index.d.ts': 'export {};', ...change.files }; + for (const [path, text] of Object.entries(files)) if (text !== null) { mkdirSync(dirname(join(directory, path)), { recursive: true }); writeFileSync(join(directory, path), text); } + return directory; +} +test('accepts private ESM exports with declarations and client directive', (t) => assert.deepEqual(validatePackage(fixture(t)), [])); +test('private core rejects CommonJS executable exports', (t) => { + const directory = fixture(t, { manifest: { name: '@threadplane/core', exports: { '.': { types: './src/index.d.ts', import: './src/index.cjs', default: './src/index.cjs' } } }, files: { 'src/index.cjs': 'module.exports = {};' } }); + assert.ok(validatePackage(directory).some((error) => error.includes('runtime must resolve to JavaScript'))); +}); +test('validates final package manifests separately from private scaffolding', (t) => { + const directory = fixture(t, { manifest: { name: '@threadplane/render', private: false } }); + assert.deepEqual(validatePackage(directory, { angularTransitions: [] }), []); +}); +test('package validation rejects final-role manifest dependencies without imports', (t) => { + const directory = fixture(t, { manifest: { name: '@threadplane/render', dependencies: { '@threadplane/content': '*' } } }); + assert.ok(validatePackage(directory, { angularTransitions: [] }).some((error) => error.includes('forbidden dependencies'))); +}); +const angularManifest = { name: '@threadplane/angular', exports: { './package.json': { default: './package.json' }, '.': { types: './types/threadplane-angular.d.ts', default: './fesm2022/threadplane-angular.mjs' } } }; +const angularFiles = { 'types/threadplane-angular.d.ts': 'export {};', 'fesm2022/threadplane-angular.mjs': 'export {};' }; +test('package validation accepts private Angular APF declarations and default ESM exports', (t) => { + const directory = fixture(t, { manifest: angularManifest, files: angularFiles }); + assert.deepEqual(validatePackage(directory), []); +}); +test('APF metadata exports are excluded from executable consumer imports', () => { + assert.equal(typeof packageVerifier.consumerSpecifiers, 'function'); + assert.deepEqual(packageVerifier.consumerSpecifiers(angularManifest), ['@threadplane/angular']); +}); +for (const [label, change] of [ + ['public Angular manifest', { manifest: { ...angularManifest, private: false }, files: angularFiles }], + ['missing Angular declaration', { manifest: angularManifest, files: { ...angularFiles, 'types/threadplane-angular.d.ts': null } }], + ['missing Angular executable', { manifest: angularManifest, files: { ...angularFiles, 'fesm2022/threadplane-angular.mjs': null } }], + ['missing Angular root', { manifest: { ...angularManifest, exports: { './package.json': { default: './package.json' } } }, files: angularFiles }], + ['missing Angular readme', { manifest: angularManifest, files: { ...angularFiles, 'README.md': null } }], + ['missing Angular license', { manifest: angularManifest, files: { ...angularFiles, 'LICENSE.md': null } }], + ['Angular CommonJS', { manifest: { ...angularManifest, exports: { '.': { types: './types/threadplane-angular.d.ts', default: './index.cjs' } } }, files: { ...angularFiles, 'index.cjs': 'module.exports = {};' } }], + ['Angular test artifact', { manifest: angularManifest, files: { ...angularFiles, 'leak.type-test.ts': 'export {};' } }], + ['Angular test setup', { manifest: angularManifest, files: { ...angularFiles, 'test-setup.js': 'export {};' } }], + ['Angular raw source', { manifest: angularManifest, files: { ...angularFiles, 'public-api.ts': 'export {};' } }], + ['Angular runtime disguised as metadata', { manifest: { ...angularManifest, exports: { ...angularManifest.exports, './package.json': { default: './README.md' } } }, files: angularFiles }], + ['missing exported metadata asset', { manifest: { ...angularManifest, exports: { ...angularManifest.exports, './missing.json': { default: './missing.json' } } }, files: angularFiles }], +]) test(`rejects ${label}`, (t) => assert.ok(validatePackage(fixture(t, change)).length > 0)); +for (const project of ['core', 'content', 'react']) { + test(`${project} still requires an import condition`, (t) => { + const directory = fixture(t, { manifest: { name: `@threadplane/${project}`, exports: { '.': { types: './src/index.d.ts', default: './src/index.js' } } } }); + assert.ok(validatePackage(directory).some((error) => error.includes('requires types, import and default'))); + }); +} +test('final packages reject non-JavaScript executable exports', (t) => { + const directory = fixture(t, { manifest: { name: '@threadplane/render', exports: { '.': { types: './src/index.d.ts', default: './README.md' } } } }); + assert.ok(validatePackage(directory).some((error) => error.includes('runtime must resolve to JavaScript'))); +}); +for (const project of ['render', 'react']) { + test(`${project} metadata asset subpaths remain valid`, (t) => { + const directory = fixture(t, { manifest: { name: `@threadplane/${project}`, exports: { '.': { types: './src/index.d.ts', import: './src/index.js', default: './src/index.js' }, './README.md': './README.md' } } }); + assert.deepEqual(validatePackage(directory), []); + }); +} +for (const entry of [null, 42, []]) { + test(`malformed export ${JSON.stringify(entry)} produces a validation error`, (t) => { + const directory = fixture(t, { manifest: { name: '@threadplane/render', exports: { '.': entry } } }); + assert.ok(validatePackage(directory).length > 0); + }); +} +for (const [label, change] of [ + ['public manifest', { manifest: { private: false } }], + ['missing declaration target', { files: { 'src/index.d.ts': null } }], + ['missing root export', { manifest: { exports: {} } }], + ['non-declaration types target', { manifest: { exports: { '.': { types: './src/index.js', import: './src/index.js', default: './src/index.js' } } } }], + ['missing license', { files: { 'LICENSE.md': null } }], + ['missing readme', { files: { 'README.md': null } }], + ['lost client directive', { files: { 'src/index.js': 'export {};' } }], + ['lost default client directive', { manifest: { exports: { '.': { types: './src/index.d.ts', import: './src/index.js', default: './src/default.js' } } }, files: { 'src/default.js': 'export {};' } }], + ['production test artifact', { files: { 'src/leak.spec.js': 'export {};' } }], + ['escaping export', { manifest: { exports: { '.': { import: '../outside.js', types: './src/index.d.ts' } } } }], + ['missing import condition', { manifest: { exports: { '.': { types: './src/index.d.ts' } } } }], + ['non-JavaScript runtime', { manifest: { exports: { '.': { types: './src/index.d.ts', import: './runtime.txt', default: './runtime.txt' } } }, files: { 'runtime.txt': 'export {};' } }], +]) test(`rejects ${label}`, (t) => assert.ok(validatePackage(fixture(t, change)).length > 0)); + +const lockFor = (names) => ({ packages: Object.fromEntries(names.map((name) => [`node_modules/${name}`, { version: '1.0.0', resolved: name.startsWith('@threadplane/') ? 'file:/tmp/local.tgz' : 'https://registry.npmjs.org/pkg.tgz' }])) }); +test('isolated graph distinguishes installation footprint from bundle inputs', () => { + assert.equal(typeof packageVerifier.installGraphViolations, 'function'); + assert.deepEqual(packageVerifier.installGraphViolations(lockFor(['@threadplane/core']), 'core'), []); + assert.ok(packageVerifier.installGraphViolations(lockFor(['@threadplane/core', 'tslib']), 'core').length); + for (const name of ['@angular/core', '@langchain/core', '@ag-ui/client']) assert.ok(packageVerifier.installGraphViolations(lockFor([name]), 'plain').length); + for (const name of ['react', '@types/react', '@langchain/langgraph-sdk']) assert.ok(packageVerifier.installGraphViolations(lockFor([name]), 'angular').length); + assert.deepEqual(packageVerifier.installGraphViolations(lockFor(['@threadplane/react', 'react', 'marked']), 'plain'), []); +}); +test('consumer graph refuses registry Threadplane resolutions even when nested', () => { + const lock = lockFor(['@threadplane/core']); + lock.packages['node_modules/@threadplane/core'].resolved = 'https://registry.npmjs.org/@threadplane/core/-/core.tgz'; + assert.equal(typeof packageVerifier.installGraphViolations, 'function'); + assert.ok(packageVerifier.installGraphViolations(lock, 'plain').some((e) => e.includes('local tarball'))); + assert.ok(packageVerifier.installGraphViolations(lockFor(['x/node_modules/@angular/core']), 'plain').length); +}); +test('root bundle evidence rejects parser inputs, not parser strings in generated code', () => { + assert.equal(typeof packageVerifier.assertParserFreeInputs, 'function'); + assert.doesNotThrow(() => packageVerifier.assertParserFreeInputs({ 'node_modules/@threadplane/react/src/index.js': {} })); + for (const name of ['marked', '@cacheplane/partial-json', '@cacheplane/partial-markdown', 'remark-gfm', 'katex', 'shiki']) assert.throws(() => packageVerifier.assertParserFreeInputs({ [`node_modules/${name}/index.js`]: {} }), /parser/); + assert.throws(() => packageVerifier.assertParserFreeInputs(undefined), /inputs/); +}); +test('packing selects only actual local Threadplane dependency closure', () => { + assert.equal(typeof packageVerifier.localDependencyProjects, 'function'); + const manifests = { angular: { version: '0.0.0', peerDependencies: { '@angular/core': '^21' } }, core: { version: '0.0.0' }, content: { version: '0.0.0', dependencies: { '@threadplane/core': '*' } } }; + assert.deepEqual(packageVerifier.localDependencyProjects(['angular'], (p) => manifests[p]), ['angular']); + assert.deepEqual(packageVerifier.localDependencyProjects(['content'], (p) => manifests[p]), ['content', 'core']); + assert.throws(() => packageVerifier.localDependencyProjects(['content'], () => ({ dependencies: { '@threadplane/missing': '*' } })), /local/); +}); +test('local tarball selection refuses incompatible dependency and peer ranges before npm overrides', () => { + for (const field of ['dependencies', 'peerDependencies', 'optionalDependencies']) { + const manifests = { core: { version: '0.0.0' }, content: { [field]: { '@threadplane/core': '^1.0.0' } } }; + assert.throws(() => packageVerifier.localDependencyProjects(['content'], (project) => manifests[project]), /does not satisfy/); + } +}); +test('installation footprint counts actual package files and bytes separately from optional lock entries', (t) => { + assert.equal(typeof packageVerifier.installFootprint, 'function'); + const directory = mkdtempSync(join(tmpdir(), 'threadplane-footprint-')); + t.after(() => rmSync(directory, { recursive: true, force: true })); + mkdirSync(join(directory, 'node_modules/core'), { recursive: true }); + writeFileSync(join(directory, 'node_modules/core/package.json'), '{}'); + writeFileSync(join(directory, 'node_modules/core/index.js'), 'abc'); + assert.deepEqual(packageVerifier.installFootprint(directory, lockFor(['core', 'optional-platform'])), { installedPackages: 1, lockedPackages: 2, fileBytes: 5 }); +}); diff --git a/tsconfig.base.json b/tsconfig.base.json index bd1425983..0b8d8135e 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -26,6 +26,16 @@ // Removing this needs an Nx fix (or the Nx TS-solution setup) first. "baseUrl": ".", "paths": { + "@threadplane/angular": ["libs/angular/src/public-api.ts"], + "@threadplane/core": ["libs/core/src/index.ts"], + "@threadplane/core/tools": ["libs/core/src/tools/index.ts"], + "@threadplane/core/testing": ["libs/core/src/testing/index.ts"], + "@threadplane/content": ["libs/content/src/index.ts"], + "@threadplane/content/markdown": ["libs/content/src/markdown/index.ts"], + "@threadplane/content/json": ["libs/content/src/json/index.ts"], + "@threadplane/content/a2ui": ["libs/content/src/a2ui/index.ts"], + "@threadplane/content/testing": ["libs/content/src/testing/index.ts"], + "@threadplane/react": ["libs/react/src/index.ts"], "@threadplane/design-tokens": ["libs/design-tokens/src/index.ts"], "@threadplane/ag-ui": ["libs/ag-ui/src/public-api.ts"], "@threadplane/a2ui": ["libs/a2ui/src/index.ts"],