* fix(oauth): mark empty Antigravity projectId as degraded (#11284)
The #11284 gate only fired when projectDiscoveryOutcome was set. Paste
credentials, persistOAuthConnection, and agy CLI import could persist
projectId="" as testStatus=active, so the dashboard showed Connected
while fetchAvailableModels returned 403.
Degrade on empty projectId itself. Keep the refresh token stored so
request-time bootstrap can still self-heal.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
* fix(oauth): clear stale degrade fields and bind CLI imports to builtin client
persistOAuthConnection left errorCode/lastError on the row when a later
connect discovered a Cloud Code projectId. agy CLI import also kept a
leftover custom: oauthClient marker from dashboard OAuth, so the next
refresh hit the operator web client instead of the public desktop client.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
* fix(oauth): null error fields on healthy create paths too
Update already cleared errorCode/lastError* when a projectId appeared.
Create payloads still omitted the keys; match the update shape so a
fresh row cannot keep a leftover degrade marker.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
* test(oauth): pin healthy create/upsert nulling of degrade fields
Forge flagged create payloads omitting errorCode/lastError* when a
projectId is present. Production already writes explicit nulls; the
reader strips them via cleanNulls, so pin both the payload shape and
the upsert path that must overwrite a leftover degrade marker.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
* fix(oauth): type create payload from AntigravityDegradedProjectState
The persistence helper duplicated a subset of the degrade type and
dropped warning. Align the parameter so the HTTP-only warning field
cannot drift from the exported type.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
* fix(oauth): persist degrade status through a single override helper
OAuth exchange/poll-callback spread the whole degrade object, which
wrote warning into the SQLite row and left healthy updates as {}.
Centralize testStatus/errorCode/lastError* so they always win over a
spread tokenData payload.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
---------
Signed-off-by: Minxi Hou <houminxi@gmail.com>
Retargetado para release/v3.8.51 (release/v3.8.50 está congelada — freeze issue #11439). Validado em lote combinado (batch-0824h2, junto de #11435/#11436/#11437) contra o tip de release/v3.8.51: typecheck:core limpo, gates estáticos OK, 127/127 testes focados passando.
Investigação sólida com repro real via container isolado, três causas independentes identificadas e corrigidas com testes de regressão dedicados para cada uma. Obrigado pela contribuição!