fix(detection): stop generic Node claiming Vite apps and Android claiming Flutter#817
Merged
Merged
Conversation
…ming Flutter Two misdetections from the 2026-07-07 triage (the "$8.29 bug" — wrong-framework integrations burning agent spend): - javascript-node's detect() matched on package.json alone, and it sits before javascript_web in the detection loop, so every Vite app was claimed as a server-side Node project and got posthog-node integrated into a browser codebase (2 users hit this). It now returns false when `vite` is a declared dependency or a vite.config.* exists, letting detection fall through to javascript_web. - android's detect() claimed Flutter projects via their android/ subtree (manifests + MainActivity.kt satisfy strategy 2 — the code even had a "we'll figure that out later" comment). It now bails when pubspec.yaml sits at the project root. A proper flutter framework config (integration-flutter already exists in the skill menu) is the follow-up; this stops the wrong integration today. Adds the first framework-detection test file, including a registry-order guard that language fallbacks stay after every framework in the Integration enum, and an end-to-end assertion that a Vite React app resolves to javascript_web. Generated-By: PostHog Code Task-Id: bcb96bcb-e37f-421d-841d-738647c73b8e
🧙 Wizard CIRun the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands: Test all apps:
Test all apps in a directory:
Test an individual app:
Show more apps
Results will be posted here when complete. |
…eneric Node last Per review: the structural problem was ordering, not just the Vite special case. detectFramework relied on the Integration enum's declaration order, which put javascriptNode (matches any package.json) BEFORE javascript_web (needs lockfile + a frontend signal) — so generic Node shadowed the web fallback for every frontend project that matched no specific framework, not only Vite apps. detectFramework now walks an explicit DETECTION_ORDER: every real framework first, then the language fallbacks (python, ruby, javascript_web, javascriptNode) as a second phase, with generic Node dead last. Built explicitly rather than trusting enum order so adding an Integration in the wrong enum position can't silently put a broad fallback ahead of a specific framework. Better tests: order invariants against the exported DETECTION_ORDER (full coverage/no dupes, fallbacks after every framework, web before node, node last overall) plus end-to-end fixtures — a Next.js app beats the fallbacks, a Vite React app and a plain browser app (lockfile + index.html, previously misclaimed by node) resolve to javascript_web, an express project still falls through to javascript_node, and a Flutter project is claimed by nothing. The vite/pubspec detect() exclusions from the previous commit stay as belt-and-suspenders for lockfile-less scaffolds. Generated-By: PostHog Code Task-Id: bcb96bcb-e37f-421d-841d-738647c73b8e
…e, no new machinery Per review: framework.ts's plain first-match loop over Object.values(Integration) was already the right mechanism — its doc comment even says "Detection order matters" — so the fix is a two-line enum reorder, not a DETECTION_ORDER layer. Reverted framework.ts and the javascript-node config to main (Vite knowledge doesn't belong in Node detection logic) and swapped javascript_web ahead of javascriptNode in the enum's fallback section, with a comment explaining why node must stay last. A Vite/browser app now falls to javascript_web via ordering alone (lockfile + frontend signal wins before node's any-package.json). The android pubspec.yaml exclusion stays — Flutter has no config of its own to reorder ahead, so the exclusion is the only lever there. Tests: enum-order invariants (fallbacks after every framework; javascriptNode last) + the same end-to-end fixtures (Next.js beats fallbacks, Vite React → web, plain browser app → web, express → node, Flutter → nothing) + the android pair. Generated-By: PostHog Code Task-Id: bcb96bcb-e37f-421d-841d-738647c73b8e
Cut the multi-line ordering explanations down to one line each. The enum docblock and the order tests already carry the invariant. Generated-By: PostHog Code Task-Id: bcb96bcb-e37f-421d-841d-738647c73b8e
edwinyjlim
approved these changes
Jul 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Item E1–E2 from the 2026-07-07 triage — the "$8.29 bug": wrong-framework detection burning agent spend. Simplified per review: no new detection machinery, no framework knowledge in the wrong config — the whole ordering fix is a two-line enum reorder.
The fix
detectFramework's first-match loop overObject.values(Integration)was already the right mechanism (the enum's doc comment even says "Detection order matters") — but the fallback section declaredjavascriptNode(matches anypackage.json) beforejavascript_web(requires a lockfile + a frontend signal). So generic Node claimed every frontend project that matched no specific framework — Vite apps were just the reported case.The enum's fallback section is now
python, ruby, javascript_web, javascriptNode, with a comment explaining why node must stay last.framework.tsis untouched. A Vite/browser app falls tojavascript_webvia ordering alone.Flutter-as-Android
android'sdetect()bails on a rootpubspec.yaml, so Flutter projects are never claimed via theirandroid/subtree (manifests +MainActivity.ktsatisfy its glob strategy — the code carried a "we'll figure that out later" comment about exactly this). Unlike the JS case there's no more-specific config to order ahead — Flutter has no framework config yet — so the exclusion is the only lever. A Flutter project now gets "could not auto-detect" instead of a wrong integration; a proper flutter config (integration-flutterexists in the skill menu) is the follow-up.Tests (9)
javascriptNodelast overall (anything after it would be unreachable for a JS project).javascript_web, a plain browser app (lockfile + index.html — previously misclaimed by node) →javascript_web, an express project still →javascript_node, a Flutter project claimed by nothing.pnpm build && pnpm testgreen (1220 tests).🤖 Generated with Claude Code