Found while adding render coverage for decompiler.component.html (wave-5 coverage loop, angular branch test/component-coverage-wave5).
Symptom
In the .NET decompiler tool, after decompiling a DLL:
Typing in the type/member search box does nothing. The tree keeps showing every namespace and type.
Clicking the All / Methods / Properties / Fields / Events filter chips highlights the chip but does not change the member lists. Selecting "Methods" still shows fields, properties and events.
Both controls look functional (the search text persists, the chip gets an active style), which makes this read as "my search found everything" rather than "search is broken".
Root cause
DecompilerComponent.getFilteredNamespaces() (libraries/features/dev-tools-decompiler/src/lib/decompiler.component.ts:234) is the method the template iterates, and it never reads either filter signal:
getFilteredNamespaces():unknown[]{constdata=this.decompiledData();if(!data?.tree?.namespaces)return[];returnObject.entries(data.tree.namespaces).map(([name,namespace])=>({name,types: Object.entries(namespace.types).map(([typeName,typeInfo])=>({/* every field, unconditionally */})),}));}
searchQuery and selectedFilter are written by onSearchChange() / setFilter(), but across the whole 803-line template they appear in exactly two kinds of place:
[value]="searchQuery()" — the input echoing its own text back (line 426)
Nothing else consumes them. So the name getFilteredNamespaces is aspirational: it is an unfiltered projection.
Impact
The decompiler's whole purpose is exploring a large assembly's type tree. On a real DLL (dozens of namespaces, hundreds of types) search and filtering are the only practical navigation, and both are no-ops. Users are left scrolling and manually expanding.
Fix sketch
Make getFilteredNamespaces() a computed() that reads searchQuery() and selectedFilter():
case-insensitive substring match against namespace name, type name/fullName, and member names;
drop namespaces/types that end up with no matches (and consider auto-expanding matches, since a match hidden inside a collapsed node is still invisible);
selectedFilter should restrict which member collections are projected (methods → only methods, etc., all → all four).
It is called from @for in the template, so converting it to a computed() also removes a per-change-detection re-projection of the entire tree.
Current behavior is pinned
decompiler.render.spec.ts has two characterization tests referencing this ticket which assert the broken behavior (search leaves the result count unchanged; "Methods" still renders fields) so the suite stays green. Both are written to fail once filtering works — update them as part of the fix.
Found while adding render coverage for `decompiler.component.html` (wave-5 coverage loop, angular branch `test/component-coverage-wave5`).
## Symptom
In the **.NET decompiler** tool, after decompiling a DLL:
- Typing in the type/member **search box** does nothing. The tree keeps showing every namespace and type.
- Clicking the **All / Methods / Properties / Fields / Events** filter chips highlights the chip but does not change the member lists. Selecting "Methods" still shows fields, properties and events.
Both controls look functional (the search text persists, the chip gets an active style), which makes this read as "my search found everything" rather than "search is broken".
## Root cause
`DecompilerComponent.getFilteredNamespaces()` (`libraries/features/dev-tools-decompiler/src/lib/decompiler.component.ts:234`) is the method the template iterates, and it never reads either filter signal:
```ts
getFilteredNamespaces(): unknown[] {
const data = this.decompiledData();
if (!data?.tree?.namespaces) return [];
return Object.entries(data.tree.namespaces).map(([name, namespace]) => ({
name,
types: Object.entries(namespace.types).map(([typeName, typeInfo]) => ({ /* every field, unconditionally */ })),
}));
}
```
`searchQuery` and `selectedFilter` are written by `onSearchChange()` / `setFilter()`, but across the whole 803-line template they appear in exactly two kinds of place:
- `[value]="searchQuery()"` — the input echoing its own text back (line 426)
- `[class.active]="selectedFilter() === '…'"` — chip styling (lines 436, 445, 454, 463, 472)
Nothing else consumes them. So the name `getFilteredNamespaces` is aspirational: it is an unfiltered projection.
## Impact
The decompiler's whole purpose is exploring a large assembly's type tree. On a real DLL (dozens of namespaces, hundreds of types) search and filtering are the only practical navigation, and both are no-ops. Users are left scrolling and manually expanding.
## Fix sketch
- Make `getFilteredNamespaces()` a `computed()` that reads `searchQuery()` and `selectedFilter()`:
- case-insensitive substring match against namespace name, type name/fullName, and member names;
- drop namespaces/types that end up with no matches (and consider auto-expanding matches, since a match hidden inside a collapsed node is still invisible);
- `selectedFilter` should restrict which member collections are projected (`methods` → only `methods`, etc., `all` → all four).
- It is called from `@for` in the template, so converting it to a `computed()` also removes a per-change-detection re-projection of the entire tree.
## Current behavior is pinned
`decompiler.render.spec.ts` has two characterization tests referencing this ticket which assert the *broken* behavior (search leaves the result count unchanged; "Methods" still renders fields) so the suite stays green. **Both are written to fail once filtering works — update them as part of the fix.**
Verified 2026-08-07 against spikersoft-angular@8e5a404, and live against the deployed main-KZKZUOSX.js bundle on learn.spikersoft.com.
Code: Unchanged. libraries/features/dev-tools-decompiler/src/lib/decompiler.component.ts:234-256 — getFilteredNamespaces() reads only this.decompiledData() and returns an unconditional projection of every namespace, type and member collection. searchQuery (:68) and selectedFilter (:69) are written by onSearchChange() (:230-232) and setFilter() (:322) but consumed nowhere else: in the template they appear only at decompiler.component.html:426 ([value]="searchQuery()") and :436,:445,:454,:463,:472 ([class.active]). The @for at :487 iterates the unfiltered projection.
No reference to the search or filter signals in the shipped body, and the template still calls getFilteredNamespaces() from its @for. Search and filtering are no-ops in production today.
Status: not done — The whole fix: make it a computed() over searchQuery() + selectedFilter() with case-insensitive matching on namespace/type/member names, prune empty branches, auto-expand matches, and have selectedFilter restrict which member collections are projected. Then flip the two characterization tests in decompiler.render.spec.ts that currently pin the broken behaviour.
Closing here. Work now lives in the repo that holds the fix, so fixes #649 in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.
— Opus 5 Agent
Migrated to **spikerj/spikersoft-angular#649** as part of the umbrella-tracker breakup.
Verified 2026-08-07 against `spikersoft-angular@8e5a404`, and live against the deployed `main-KZKZUOSX.js` bundle on learn.spikersoft.com.
- **Code:** Unchanged. `libraries/features/dev-tools-decompiler/src/lib/decompiler.component.ts:234-256` — `getFilteredNamespaces()` reads only `this.decompiledData()` and returns an unconditional projection of every namespace, type and member collection. `searchQuery` (`:68`) and `selectedFilter` (`:69`) are written by `onSearchChange()` (`:230-232`) and `setFilter()` (`:322`) but consumed nowhere else: in the template they appear only at `decompiler.component.html:426` (`[value]="searchQuery()"`) and `:436,:445,:454,:463,:472` (`[class.active]`). The `@for` at `:487` iterates the unfiltered projection.
- **Live:** **Confirmed deployed.** `learn.spikersoft.com` → `main-KZKZUOSX.js` → `chunk-CHLW0UZC2.js` ships the minified method verbatim:
```js
getFilteredNamespaces(){let e=this.decompiledData();return e?.tree?.namespaces?Object.entries(e.tree.namespaces).map(([t,r])=>({name:t,types:Object.entries(r.types).map(([l,x])=>({name:l,fullName:x.fullName,kind:x.kind,accessModifier:x.accessModifier,isStatic:x.isStatic,baseType:x.baseType,interfaces:x.interfaces||[],methods:x.methods||[],properties:x.properties||[],fields:x.fields||[],events:x.events||[]}))})):[]}
```
No reference to the search or filter signals in the shipped body, and the template still calls `getFilteredNamespaces()` from its `@for`. Search and filtering are no-ops in production today.
Status: **not done** — The whole fix: make it a `computed()` over `searchQuery()` + `selectedFilter()` with case-insensitive matching on namespace/type/member names, prune empty branches, auto-expand matches, and have `selectedFilter` restrict which member collections are projected. Then flip the two characterization tests in `decompiler.render.spec.ts` that currently pin the broken behaviour.
Closing here. Work now lives in the repo that holds the fix, so `fixes #649` in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.
— Opus 5 Agent
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found while adding render coverage for
decompiler.component.html(wave-5 coverage loop, angular branchtest/component-coverage-wave5).Symptom
In the .NET decompiler tool, after decompiling a DLL:
Both controls look functional (the search text persists, the chip gets an active style), which makes this read as "my search found everything" rather than "search is broken".
Root cause
DecompilerComponent.getFilteredNamespaces()(libraries/features/dev-tools-decompiler/src/lib/decompiler.component.ts:234) is the method the template iterates, and it never reads either filter signal:searchQueryandselectedFilterare written byonSearchChange()/setFilter(), but across the whole 803-line template they appear in exactly two kinds of place:[value]="searchQuery()"— the input echoing its own text back (line 426)[class.active]="selectedFilter() === '…'"— chip styling (lines 436, 445, 454, 463, 472)Nothing else consumes them. So the name
getFilteredNamespacesis aspirational: it is an unfiltered projection.Impact
The decompiler's whole purpose is exploring a large assembly's type tree. On a real DLL (dozens of namespaces, hundreds of types) search and filtering are the only practical navigation, and both are no-ops. Users are left scrolling and manually expanding.
Fix sketch
getFilteredNamespaces()acomputed()that readssearchQuery()andselectedFilter():selectedFiltershould restrict which member collections are projected (methods→ onlymethods, etc.,all→ all four).@forin the template, so converting it to acomputed()also removes a per-change-detection re-projection of the entire tree.Current behavior is pinned
decompiler.render.spec.tshas two characterization tests referencing this ticket which assert the broken behavior (search leaves the result count unchanged; "Methods" still renders fields) so the suite stays green. Both are written to fail once filtering works — update them as part of the fix.Migrated to spikerj/spikersoft-angular#649 as part of the umbrella-tracker breakup.
Verified 2026-08-07 against
spikersoft-angular@8e5a404, and live against the deployedmain-KZKZUOSX.jsbundle on learn.spikersoft.com.libraries/features/dev-tools-decompiler/src/lib/decompiler.component.ts:234-256—getFilteredNamespaces()reads onlythis.decompiledData()and returns an unconditional projection of every namespace, type and member collection.searchQuery(:68) andselectedFilter(:69) are written byonSearchChange()(:230-232) andsetFilter()(:322) but consumed nowhere else: in the template they appear only atdecompiler.component.html:426([value]="searchQuery()") and:436,:445,:454,:463,:472([class.active]). The@forat:487iterates the unfiltered projection.learn.spikersoft.com→main-KZKZUOSX.js→chunk-CHLW0UZC2.jsships the minified method verbatim:getFilteredNamespaces()from its@for. Search and filtering are no-ops in production today.Status: not done — The whole fix: make it a
computed()oversearchQuery()+selectedFilter()with case-insensitive matching on namespace/type/member names, prune empty branches, auto-expand matches, and haveselectedFilterrestrict which member collections are projected. Then flip the two characterization tests indecompiler.render.spec.tsthat currently pin the broken behaviour.Closing here. Work now lives in the repo that holds the fix, so
fixes #649in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.— Opus 5 Agent