| ... | ... | @@ -68,10 +68,7 @@ import { |
| 68 | 68 | clearComposerDraftsEnvironment, |
| 69 | 69 | composerDraftHasUserContent, |
| 70 | 70 | finalizePromotedDraftThreadByRef, |
| 71 | | markPromotedDraftThread, |
| 72 | 71 | markPromotedDraftThreadByRef, |
| 73 | | markPromotedDraftThreads, |
| 74 | | markPromotedDraftThreadsByRef, |
| 75 | 72 | type ComposerFileAttachment, |
| 76 | 73 | type ComposerImageAttachment, |
| 77 | 74 | composerFileNeedsReattach, |
| ... | ... | @@ -1200,7 +1197,7 @@ describe("composerDraftStore project draft thread mapping", () => { |
| 1200 | 1197 | interactionMode: "plan", |
| 1201 | 1198 | }); |
| 1202 | 1199 | store.setPrompt(draftId, "keep this prompt"); |
| 1203 | | markPromotedDraftThread(threadId); |
| 1200 | markPromotedDraftThreadByRef(scopeThreadRef(TEST_ENVIRONMENT_ID, threadId)); |
| 1204 | 1201 | |
| 1205 | 1202 | store.setLogicalProjectDraftThreadId(scopedProjectKey(projectRef), projectRef, draftId, { |
| 1206 | 1203 | threadId: retryThreadId, |
| ... | ... | @@ -1363,12 +1360,12 @@ describe("composerDraftStore project draft thread mapping", () => { |
| 1363 | 1360 | expect(draftByKey(draftId)).toBeUndefined(); |
| 1364 | 1361 | }); |
| 1365 | 1362 | |
| 1366 | | it("marks a promoted draft by thread id without deleting composer state", () => { |
| 1363 | it("marks a promoted draft by scoped ref without deleting composer state", () => { |
| 1367 | 1364 | const store = useComposerDraftStore.getState(); |
| 1368 | 1365 | store.setProjectDraftThreadId(projectRef, draftId, { threadId }); |
| 1369 | 1366 | store.setPrompt(draftId, "promote me"); |
| 1370 | 1367 | |
| 1371 | | markPromotedDraftThread(threadId); |
| 1368 | markPromotedDraftThreadByRef(scopeThreadRef(TEST_ENVIRONMENT_ID, threadId)); |
| 1372 | 1369 | |
| 1373 | 1370 | expect(useComposerDraftStore.getState().getDraftThreadByProjectRef(projectRef)).toBeNull(); |
| 1374 | 1371 | expect(useComposerDraftStore.getState().getDraftThread(draftId)?.promotedTo).toEqual( |
| ... | ... | @@ -1393,20 +1390,20 @@ describe("composerDraftStore project draft thread mapping", () => { |
| 1393 | 1390 | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 1394 | 1391 | store.setPrompt(threadRef, "keep me"); |
| 1395 | 1392 | |
| 1396 | | markPromotedDraftThread(threadId); |
| 1393 | markPromotedDraftThreadByRef(scopeThreadRef(TEST_ENVIRONMENT_ID, threadId)); |
| 1397 | 1394 | |
| 1398 | 1395 | expect(useComposerDraftStore.getState().getDraftThread(threadRef)).toBeNull(); |
| 1399 | 1396 | expect(draftFor(threadId, TEST_ENVIRONMENT_ID)?.prompt).toBe("keep me"); |
| 1400 | 1397 | }); |
| 1401 | 1398 | |
| 1402 | | it("marks promoted drafts from an iterable of server thread ids", () => { |
| 1399 | it("promotes a draft without changing another thread's draft", () => { |
| 1403 | 1400 | const store = useComposerDraftStore.getState(); |
| 1404 | 1401 | store.setProjectDraftThreadId(projectRef, draftId, { threadId }); |
| 1405 | 1402 | store.setPrompt(draftId, "promote me"); |
| 1406 | 1403 | store.setProjectDraftThreadId(otherProjectRef, otherDraftId, { threadId: otherThreadId }); |
| 1407 | 1404 | store.setPrompt(otherDraftId, "keep me"); |
| 1408 | 1405 | |
| 1409 | | markPromotedDraftThreads([threadId]); |
| 1406 | markPromotedDraftThreadByRef(scopeThreadRef(TEST_ENVIRONMENT_ID, threadId)); |
| 1410 | 1407 | |
| 1411 | 1408 | expect(useComposerDraftStore.getState().getDraftThread(draftId)?.promotedTo).toEqual( |
| 1412 | 1409 | scopeThreadRef(TEST_ENVIRONMENT_ID, threadId), |
| ... | ... | @@ -1418,7 +1415,7 @@ describe("composerDraftStore project draft thread mapping", () => { |
| 1418 | 1415 | expect(draftByKey(otherDraftId)?.prompt).toBe("keep me"); |
| 1419 | 1416 | }); |
| 1420 | 1417 | |
| 1421 | | it("marks every matching scoped draft when multiple environments share a thread id", () => { |
| 1418 | it("promotes matching thread ids separately for each environment", () => { |
| 1422 | 1419 | const store = useComposerDraftStore.getState(); |
| 1423 | 1420 | const localThreadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 1424 | 1421 | const remoteThreadRef = scopeThreadRef(OTHER_TEST_ENVIRONMENT_ID, threadId); |
| ... | ... | @@ -1428,7 +1425,16 @@ describe("composerDraftStore project draft thread mapping", () => { |
| 1428 | 1425 | store.setProjectDraftThreadId(remoteProjectRef, remoteDraftId, { threadId }); |
| 1429 | 1426 | store.setPrompt(remoteDraftId, "remote draft"); |
| 1430 | 1427 | |
| 1431 | | markPromotedDraftThread(threadId); |
| 1428 | markPromotedDraftThreadByRef(localThreadRef); |
| 1429 | |
| 1430 | expect(store.getDraftThreadByProjectRef(projectRef)).toBeNull(); |
| 1431 | expect(store.getDraftThreadByProjectRef(remoteProjectRef)?.threadId).toBe(threadId); |
| 1432 | expect(store.getDraftThreadByRef(localThreadRef)?.promotedTo).toEqual(localThreadRef); |
| 1433 | expect(store.getDraftThreadByRef(remoteThreadRef)?.promotedTo).toBeNull(); |
| 1434 | expect(draftByKey(localDraftId)?.prompt).toBe("local draft"); |
| 1435 | expect(draftByKey(remoteDraftId)?.prompt).toBe("remote draft"); |
| 1436 | |
| 1437 | markPromotedDraftThreadByRef(remoteThreadRef); |
| 1432 | 1438 | |
| 1433 | 1439 | expect(store.getDraftThreadByProjectRef(projectRef)).toBeNull(); |
| 1434 | 1440 | expect(store.getDraftThreadByProjectRef(remoteProjectRef)).toBeNull(); |
| ... | ... | @@ -1451,34 +1457,10 @@ describe("composerDraftStore project draft thread mapping", () => { |
| 1451 | 1457 | expect(draftByKey(draftId)?.prompt).toBe("promote me"); |
| 1452 | 1458 | }); |
| 1453 | 1459 | |
| 1454 | | it("only marks iterable promotion cleanup entries for the matching environment refs", () => { |
| 1455 | | const store = useComposerDraftStore.getState(); |
| 1456 | | store.setProjectDraftThreadId(projectRef, draftId, { threadId }); |
| 1457 | | store.setPrompt(draftId, "promote me"); |
| 1458 | | |
| 1459 | | markPromotedDraftThreadsByRef([scopeThreadRef(OTHER_TEST_ENVIRONMENT_ID, threadId)]); |
| 1460 | | |
| 1461 | | expect(useComposerDraftStore.getState().getDraftThreadByProjectRef(projectRef)?.threadId).toBe( |
| 1462 | | threadId, |
| 1463 | | ); |
| 1464 | | expect(draftByKey(draftId)?.prompt).toBe("promote me"); |
| 1465 | | }); |
| 1466 | | |
| 1467 | | it("keeps existing server-thread composer drafts during iterable promotion cleanup", () => { |
| 1468 | | const store = useComposerDraftStore.getState(); |
| 1469 | | const threadRef = scopeThreadRef(TEST_ENVIRONMENT_ID, threadId); |
| 1470 | | store.setPrompt(threadRef, "keep me"); |
| 1471 | | |
| 1472 | | markPromotedDraftThreads([threadId]); |
| 1473 | | |
| 1474 | | expect(useComposerDraftStore.getState().getDraftThread(threadRef)).toBeNull(); |
| 1475 | | expect(draftFor(threadId, TEST_ENVIRONMENT_ID)?.prompt).toBe("keep me"); |
| 1476 | | }); |
| 1477 | | |
| 1478 | 1460 | it("moves composer edits made during promotion to the canonical thread", () => { |
| 1479 | 1461 | const store = useComposerDraftStore.getState(); |
| 1480 | 1462 | store.setProjectDraftThreadId(projectRef, draftId, { threadId }); |
| 1481 | | markPromotedDraftThread(threadId); |
| 1463 | markPromotedDraftThreadByRef(scopeThreadRef(TEST_ENVIRONMENT_ID, threadId)); |
| 1482 | 1464 | store.setPrompt(draftId, "typed during setup"); |
| 1483 | 1465 | |
| 1484 | 1466 | finalizePromotedDraftThreadByRef(scopeThreadRef(TEST_ENVIRONMENT_ID, threadId)); |