* feat(kotlin): bind Spring @Value and ConfigurationProperties consumers
Kotlin sources were skipping the Java-only config-binding attach path, so mixed JVM apps under-reported blast radius for Kotlin placeholders. Capture from the live AST, serialize on the existing side channel, and reuse the shared binder. (U1-U4)
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(review): require exact Spring annotation FQNs and skip raw-string escapes
Reject similarly named third-party imports and leave Kotlin triple-quoted bodies undecoded so capture stays fail-closed.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(kotlin): use only grammar-valid Kotlin string and class-name nodes
The coverage shard failed the #1920 literal gate on invented string node types and a Java-style name field.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(kotlin): fail closed on non-literal prefixes and persist unresolved config markers
Reject constant and boolean @ConfigurationProperties arguments, scope nested Value shadows to their owner, and rewrite drifted consumer files when a config key is deleted.
Co-authored-by: Cursor <cursoragent@cursor.com>
* test(kotlin): add config-consumer capture benchmark and fix JVM feature stamps
The Kotlin capture path had no performance or behavior guard: a file-wide
lexical shadow regression silently dropped two of every three facts. The new
bench arm fingerprints @Value / @ConfigurationProperties facts from an
explicit-import control against a wildcard-import corpus whose files each
declare a sibling nested `Value` type, so parity between the arms is the
regression gate, and CI runs it with scaling + widening budgets.
Broadening spring.config-bindings to .kt also means Kotlin-only JVM repos now
stamp the feature, which the two exact-map orchestration expectations still
denied.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(kotlin): let an explicit import shadow the Spring wildcard import
importedAs accepted a star import of the Spring package even when the same
simple name was explicitly bound to another type, so a file importing
com.example.Value alongside the Spring annotation package emitted a false
@Value consumer fact. Kotlin resolves the explicit import first, so the
wildcard branch now only applies when the name is otherwise unbound.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* chore(deps)(deps): bump js-yaml from 4.3.0 to 5.0.0 in /gitnexus
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.3.0 to 5.0.0.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.3.0...5.0.0)
---
updated-dependencies:
- dependency-name: js-yaml
dependency-version: 5.0.0
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* fix(spring-config): migrate YAML parsing to js-yaml 5 event API
js-yaml 5 removed the loadAll `listener` callback, the EventType/State
types, and DEFAULT_SCHEMA that spring-config relied on, breaking the build.
Rebuild the per-key line tree from parseEvents()/constructFromEvents()
(positions are source offsets → mapped to lines), apply the `<<` merge tag
via CORE_SCHEMA.withTags(mergeTag) (CORE alone leaves merge keys unexpanded),
and resolve aliases by anchor name, which lets the object-identity WeakMap go.
Behavior preserved: 9 unit + 8 integration spring-config tests pass, including
merged-key declaration-line, cyclic-alias termination, and the depth budget.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(spring-config): restore v4 tag coverage, cover the v5 rewrite with tests
Review follow-up for #2618.
CORE_SCHEMA.withTags(mergeTag) was a narrowing, not a port: js-yaml 5
throws "unknown tag" on !!timestamp/!!binary/!!set/!!omap/!!pairs, and an
unknown tag aborts the whole parse, which readConfigKeys swallows — so an
application.yml using any of them would have gone from its full key set to
zero keys, silently. Carry the rest of what DEFAULT_SCHEMA was; none of
these tags can execute code.
Add tests for every path the review flagged as uncovered: multi-document
files, empty/comment-only/bare-`---`/bare-scalar documents, sequence-form
merge keys, and explicitly tagged values (which fail against the one-tag
schema, so they target the changed line).
Clear the anchor map per document. It cannot change output today —
constructFromEvents rejects a cross-document alias before the event tree is
built, now asserted — but it keeps both layers on YAML's scoping rule.
Drop the stale @types/js-yaml devDependency; js-yaml 5 ships its own types
and tsc --noEmit is clean without it. Lockfile hand-edited because npm
uninstall also strips every libc field.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore(autofix): apply prettier + eslint fixes via /autofix command
* fix(spring-config): flatten !!set members, walk YAML iteratively
Review follow-up for #2618.
js-yaml 5 constructs `!!set` as a native Set; v4 built a plain
`{member: null}` object. Object.entries of a Set is empty, so a tagged set
collapsed to a bare leaf key and lost every member. Enumerate the Set
instead. Sets arrive as mapping events with key/value scalar pairs, so
member lines resolve through the usual lookup. !!binary and !!timestamp are
unaffected — both are scalar events and take the leaf path, which is why a
Uint8Array never explodes into one key per byte.
Convert findYamlMappingLocation and flattenYamlValue from recursion to an
explicit stack. Children are pushed in reverse so pops happen in
declaration order, preserving "first match" and `out` insertion order;
`leave` frames release the cycle guard where the old `finally` did. The
depth budget still throws at the same boundary with the same message.
Cover the gaps the review named: !!pairs (both duplicate entries survive),
anchor-name reuse resolving to the nearest preceding declaration, and
marker-only leading documents staying index-aligned across the two streams.
buildYamlEventTree keeps no node budget by design — one node per event over
an already-materialized array, bounded by MAX_CONFIG_FILE_BYTES. The
docstring now says so rather than implying MAX_YAML_TRAVERSAL_NODES covers
it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>