Skip to content

Commit c19e349

Browse files
paulr34cursoragent
andcommitted
cleanup
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 1b79c24 commit c19e349

3 files changed

Lines changed: 37 additions & 119 deletions

File tree

src-electron/ide-integration/studio-rest-api.js

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -364,22 +364,12 @@ async function wsMessageHandler(db, session, message) {
364364
)}`
365365
)
366366
let parsedTree = null
367-
if (typeof resp.tree === 'string') {
368-
try {
369-
parsedTree = JSON.parse(resp.tree)
370-
} catch (e) {
371-
parsedTree = null
372-
}
373-
} else if (
374-
Array.isArray(resp.tree) ||
375-
(resp.tree && typeof resp.tree === 'object')
376-
) {
377-
parsedTree = resp.tree
367+
try {
368+
parsedTree = JSON.parse(resp.tree)
369+
} catch (e) {
370+
parsedTree = null
378371
}
379-
sendSelectedUcComponents(db, session, {
380-
tree: parsedTree,
381-
delta: resp.delta == null ? null : resp.delta
382-
})
372+
sendSelectedUcComponents(db, session, parsedTree)
383373
}
384374
} catch (error) {
385375
env.logError(

src/store/zap/actions.js

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -296,14 +296,13 @@ export function updateSelectedComponent(context, payload) {
296296
// WS messages can spuriously mark just-installed components as
297297
// isSelected:false during settle, which used to make the missing-component
298298
// warning flicker back. We trust two things:
299-
// 1. The component ids Studio returned 2xx for (mirrored into
300-
// selectedUcComponents).
299+
// 1. The component ids Studio returned 2xx (or its "fake-ok" 4xx with
300+
// componentAdded/componentRemoved) for, mirrored into
301+
// selectedUcComponents.
301302
// 2. The cluster id we just acted on -- recorded here directly so the
302303
// missing-component check can short-circuit regardless of any
303304
// id-format mismatches between POST responses and Studio's tree.
304305
const list = Array.isArray(response?.data) ? response.data : []
305-
const httpOk =
306-
Number(response?.status) >= 200 && Number(response?.status) < 300
307306
const successIds = list
308307
.filter((r) => {
309308
const s = Number(r?.status)
@@ -320,15 +319,12 @@ export function updateSelectedComponent(context, payload) {
320319
added: payload.added === true,
321320
ids: successIds
322321
})
323-
}
324-
// Cluster-level bookkeeping for the warning gate. Use the clusterId the
325-
// user (or UI) targeted. successIds may be empty when Studio fast-paths
326-
// an "already installed" reply, so we don't predicate this on them.
327-
if (payload?.clusterId != null && (httpOk || successIds.length)) {
328-
context.commit('markClusterInstallRequested', {
329-
clusterId: payload.clusterId,
330-
added: payload.added === true
331-
})
322+
if (payload?.clusterId != null) {
323+
context.commit('markClusterInstallRequested', {
324+
clusterId: payload.clusterId,
325+
added: payload.added === true
326+
})
327+
}
332328
}
333329
return response
334330
})
@@ -1330,21 +1326,17 @@ export function updateUcComponentState(context, projectInfo) {
13301326

13311327
/**
13321328
* Update the selected UC component state for Simplicity Studio.
1329+
*
1330+
* Driven by Studio's "updateComponents" WebSocket notification. The backend
1331+
* forwards the parsed component tree; we flatten it to leaves and let the
1332+
* mutation merge them into our local state.
1333+
*
13331334
* @param {*} context
1334-
* @param {*} projectInfo
1335+
* @param {*} tree Parsed Studio component tree.
13351336
*/
1336-
export function updateSelectedUcComponentState(context, payload) {
1337-
// Backward compat: older backends sent the raw tree as the payload.
1338-
let tree = null
1339-
let delta = null
1340-
if (Array.isArray(payload)) {
1341-
tree = payload
1342-
} else if (payload && typeof payload === 'object') {
1343-
tree = payload.tree == null ? null : payload.tree
1344-
delta = payload.delta == null ? null : payload.delta
1345-
}
1337+
export function updateSelectedUcComponentState(context, tree) {
13461338
const treeLeaves = tree ? Util.getUcComponents(tree) : []
1347-
context.commit('applyUcComponentUpdate', { treeLeaves, delta })
1339+
context.commit('applyUcComponentUpdate', treeLeaves)
13481340
}
13491341

13501342
/**

src/store/zap/mutations.js

Lines changed: 15 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -989,28 +989,26 @@ export function updateSelectedUcComponentState(state, data) {
989989
/**
990990
* Apply a Studio WebSocket UC component update.
991991
*
992-
* Studio's "updateComponents" notification carries both a full `tree` snapshot
993-
* and a `delta` of what just changed. After a successful install, Studio has
994-
* been observed to emit a follow-up snapshot that re-marks the just-installed
995-
* leaf with isSelected:false, which previously caused the missing-component
996-
* warning to flicker back.
992+
* Studio's "updateComponents" notification carries a full tree snapshot. After
993+
* a successful install, Studio has been observed to emit a follow-up snapshot
994+
* that re-marks the just-installed leaf with isSelected:false, which used to
995+
* make the missing-component warning flicker back.
997996
*
998-
* ZAP is therefore the authoritative source for its own selection set:
999-
* - tree/delta leaves with isSelected:true -> upserted (Studio can ADD)
1000-
* - tree/delta leaves with isSelected:false -> ignored (Studio cannot remove)
1001-
* - leaves not mentioned at all -> left alone (no wipe)
997+
* The fix is to treat Studio's WS updates as ADD-ONLY for the local selection
998+
* set:
999+
* - leaves with isSelected:true -> upserted (Studio can ADD)
1000+
* - leaves with isSelected:false -> ignored (Studio cannot remove)
1001+
* - leaves not mentioned at all -> left alone (no wipe)
10021002
*
1003-
* Removals happen only via applyLocalUcComponentChange when ZAP itself issues
1004-
* a remove POST and Studio responds 2xx. ucComponents (the catalog used for
1003+
* Removals happen only via locallyMarkUcComponents when ZAP itself issues a
1004+
* remove POST and Studio responds 2xx. ucComponents (the catalog used for
10051005
* labels / metadata) is always merged so we keep accumulating entries.
10061006
*
10071007
* @param {*} state
1008-
* @param {{ treeLeaves: any[], delta: any }} payload
1008+
* @param {any[]} treeLeaves Flattened list of leaf nodes from Studio's tree.
10091009
*/
1010-
export function applyUcComponentUpdate(state, payload) {
1011-
if (!payload) return
1012-
const treeLeaves = Array.isArray(payload.treeLeaves) ? payload.treeLeaves : []
1013-
const delta = payload.delta
1010+
export function applyUcComponentUpdate(state, treeLeaves) {
1011+
const leaves = Array.isArray(treeLeaves) ? treeLeaves : []
10141012

10151013
const prevSelected = Array.isArray(state.studio.selectedUcComponents)
10161014
? state.studio.selectedUcComponents
@@ -1026,69 +1024,7 @@ export function applyUcComponentUpdate(state, payload) {
10261024
prevAll.filter((x) => x && x.id != null).map((x) => [String(x.id), x])
10271025
)
10281026

1029-
/**
1030-
* Upsert a component into the selected and catalog maps for this mutation.
1031-
* @param {*} id Component id to add.
1032-
* @param {*} node Optional node payload to store; falls back to a stub.
1033-
*/
1034-
function applyAdded(id, node) {
1035-
if (id == null) return
1036-
const key = String(id)
1037-
selectedById.set(key, node || { id: key, isSelected: true })
1038-
if (node) allById.set(key, node)
1039-
}
1040-
1041-
// Studio's WebSocket updates are ADD-ONLY for selectedUcComponents.
1042-
//
1043-
// Background: after we POST a component install, Studio sometimes emits a
1044-
// follow-up "updateComponents" tree where the freshly-installed leaf has
1045-
// isSelected:false. We don't know whether that's a bona-fide Studio bug or
1046-
// a settle artifact (a recomputed snapshot from a stale internal source);
1047-
// either way the result is the missing-component warning flickering back.
1048-
//
1049-
// To make ZAP authoritative for its own POST results we accept Studio's
1050-
// tree/delta as evidence that a component IS selected, but we never let it
1051-
// unselect a component. Removals happen only via locallyMarkUcComponents
1052-
// when ZAP itself POSTs a remove and gets a 2xx back.
1053-
if (delta) {
1054-
if (Array.isArray(delta)) {
1055-
for (const entry of delta) {
1056-
if (!entry) continue
1057-
if (typeof entry === 'string') {
1058-
applyAdded(entry, null)
1059-
} else if (typeof entry === 'object') {
1060-
const id = entry.id != null ? entry.id : entry.componentId
1061-
const sel =
1062-
entry.isSelected != null
1063-
? entry.isSelected
1064-
: entry.selected != null
1065-
? entry.selected
1066-
: entry.installed != null
1067-
? entry.installed
1068-
: null
1069-
if (sel === true) applyAdded(id, entry)
1070-
else if (entry.action === 'add' || entry.action === 'added')
1071-
applyAdded(id, entry)
1072-
}
1073-
}
1074-
} else if (typeof delta === 'object') {
1075-
const added = [].concat(
1076-
delta.added || [],
1077-
delta.installed || [],
1078-
delta.selected || []
1079-
)
1080-
for (const item of added) {
1081-
if (item == null) continue
1082-
if (typeof item === 'string') applyAdded(item, null)
1083-
else if (typeof item === 'object')
1084-
applyAdded(item.id != null ? item.id : item.componentId, item)
1085-
}
1086-
}
1087-
}
1088-
1089-
// Tree merge: add isSelected:true leaves, ignore isSelected:false. Always
1090-
// merge into the ucComponents catalog so labels/metadata stay fresh.
1091-
for (const node of treeLeaves) {
1027+
for (const node of leaves) {
10921028
if (!node || node.id == null) continue
10931029
const key = String(node.id)
10941030
allById.set(key, node)

0 commit comments

Comments
 (0)