@lasso-ai/cli 1.3.5 → 1.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/bridge.d.ts +1 -11
- package/dist/cli/bridge.js +46 -126
- package/dist/overlay.js +0 -202
- package/package.json +1 -1
package/dist/cli/bridge.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type SourceChange, type AgentPrompt } from "./agent";
|
|
2
2
|
import type { CollabConfig } from "./project";
|
|
3
|
-
import { type TimelineSnapshot
|
|
3
|
+
import { type TimelineSnapshot } from "./snapshot";
|
|
4
4
|
export declare const DEFAULT_BRIDGE_PORT = 3056;
|
|
5
5
|
type GitState = {
|
|
6
6
|
isRepo: boolean;
|
|
@@ -144,11 +144,6 @@ export type BridgeMessage = {
|
|
|
144
144
|
}>;
|
|
145
145
|
taskId?: string;
|
|
146
146
|
pageContext?: any;
|
|
147
|
-
} | {
|
|
148
|
-
type: "resolve_conflict";
|
|
149
|
-
taskId: string;
|
|
150
|
-
action: "retry" | "force" | "rebase";
|
|
151
|
-
conflicts: ConflictInfo[];
|
|
152
147
|
} | {
|
|
153
148
|
type: "restore_snapshot";
|
|
154
149
|
snapshotId: string;
|
|
@@ -249,11 +244,6 @@ export type ServerBridgeMessage = {
|
|
|
249
244
|
text?: string;
|
|
250
245
|
provider?: string;
|
|
251
246
|
error?: string;
|
|
252
|
-
} | {
|
|
253
|
-
type: "conflict_detected";
|
|
254
|
-
taskId: string;
|
|
255
|
-
conflicts: ConflictInfo[];
|
|
256
|
-
message: string;
|
|
257
247
|
} | {
|
|
258
248
|
type: "timeline";
|
|
259
249
|
snapshots: TimelineSnapshot[];
|
package/dist/cli/bridge.js
CHANGED
|
@@ -1183,29 +1183,47 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
1183
1183
|
}
|
|
1184
1184
|
else if (msg.type === "apply") {
|
|
1185
1185
|
try {
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
const snapshots = [];
|
|
1192
|
-
const planned = new Map();
|
|
1193
|
-
// Check for conflicts before applying
|
|
1194
|
-
const expectedFiles = msg.changes.map(change => ({
|
|
1195
|
-
filePath: change.filePath,
|
|
1196
|
-
content: change.oldString || null,
|
|
1186
|
+
socket.send(JSON.stringify({
|
|
1187
|
+
type: "agent_status",
|
|
1188
|
+
taskId: msg.taskId,
|
|
1189
|
+
status: "working",
|
|
1190
|
+
message: "Re-generating changes with current file state..."
|
|
1197
1191
|
}));
|
|
1198
|
-
|
|
1199
|
-
|
|
1192
|
+
// Re-run the edit request to get fresh changes based on current file state
|
|
1193
|
+
const editRequest = editRequests.get(msg.taskId);
|
|
1194
|
+
const editConfig = editConfigs.get(msg.taskId);
|
|
1195
|
+
if (!editRequest || !editConfig) {
|
|
1200
1196
|
socket.send(JSON.stringify({
|
|
1201
|
-
type: "
|
|
1197
|
+
type: "agent_status",
|
|
1202
1198
|
taskId: msg.taskId,
|
|
1203
|
-
|
|
1204
|
-
message:
|
|
1199
|
+
status: "error",
|
|
1200
|
+
message: "Could not re-generate changes: original request not found."
|
|
1205
1201
|
}));
|
|
1206
1202
|
return;
|
|
1207
1203
|
}
|
|
1208
|
-
|
|
1204
|
+
const controller = new AbortController();
|
|
1205
|
+
taskControllers.set(msg.taskId, controller);
|
|
1206
|
+
const freshProposal = await (0, agent_1.proposeChanges)(cwd, editRequest, editConfig, controller.signal, (message, detail, level) => {
|
|
1207
|
+
if (!controller.signal.aborted && socket.readyState === socket.OPEN) {
|
|
1208
|
+
socket.send(JSON.stringify({ type: "agent_status", taskId: msg.taskId, status: level === "error" ? "error" : "working", message, detail }));
|
|
1209
|
+
}
|
|
1210
|
+
}, (prompt) => {
|
|
1211
|
+
if (!controller.signal.aborted && socket.readyState === socket.OPEN) {
|
|
1212
|
+
socket.send(JSON.stringify({ type: "agent_prompt", taskId: msg.taskId, prompt }));
|
|
1213
|
+
}
|
|
1214
|
+
});
|
|
1215
|
+
if (controller.signal.aborted) {
|
|
1216
|
+
socket.send(JSON.stringify({ type: "agent_status", taskId: msg.taskId, status: "stopped", message: "Agent stopped." }));
|
|
1217
|
+
return;
|
|
1218
|
+
}
|
|
1219
|
+
// Apply the fresh changes
|
|
1220
|
+
const filePaths = [...new Set(freshProposal.changes.map(c => c.filePath))];
|
|
1221
|
+
const parentSnapshot = (0, snapshot_1.getSnapshotByTaskId)(cwd, msg.taskId);
|
|
1222
|
+
// Create pre-apply snapshot
|
|
1223
|
+
const preSnapshot = (0, snapshot_1.createSnapshot)(cwd, msg.taskId, `Pre-apply: ${freshProposal.changes.length} file${freshProposal.changes.length === 1 ? "" : "s"}`, filePaths, parentSnapshot?.id);
|
|
1224
|
+
const snapshots = [];
|
|
1225
|
+
const planned = new Map();
|
|
1226
|
+
for (const change of freshProposal.changes) {
|
|
1209
1227
|
const isNew = !change.oldString;
|
|
1210
1228
|
const filePath = resolveProposedFile(cwd, change.filePath, true);
|
|
1211
1229
|
const exists = node_fs_1.default.existsSync(filePath);
|
|
@@ -1220,8 +1238,7 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
1220
1238
|
fileChanges.push({ filePath, content, exists, ...prepared });
|
|
1221
1239
|
planned.set(filePath, fileChanges);
|
|
1222
1240
|
}
|
|
1223
|
-
//
|
|
1224
|
-
// file's replacements from the end toward the beginning.
|
|
1241
|
+
// Apply each file's replacements from the end toward the beginning
|
|
1225
1242
|
taskSnapshots.set(msg.taskId, snapshots);
|
|
1226
1243
|
for (const [filePath, changes] of planned) {
|
|
1227
1244
|
const exists = changes[0].exists;
|
|
@@ -1236,7 +1253,7 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
1236
1253
|
node_fs_1.default.writeFileSync(filePath, nextContent);
|
|
1237
1254
|
}
|
|
1238
1255
|
// Create post-apply snapshot
|
|
1239
|
-
(0, snapshot_1.createSnapshot)(cwd, msg.taskId, `Applied: ${
|
|
1256
|
+
(0, snapshot_1.createSnapshot)(cwd, msg.taskId, `Applied: ${freshProposal.changes.length} file${freshProposal.changes.length === 1 ? "" : "s"}`, filePaths, preSnapshot.id);
|
|
1240
1257
|
// Run build validation after applying changes
|
|
1241
1258
|
const validation = await validateBuild(cwd);
|
|
1242
1259
|
if (!validation.passed) {
|
|
@@ -1253,23 +1270,22 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
1253
1270
|
buildErrorContext.set(msg.taskId, {
|
|
1254
1271
|
errors: validation.errors,
|
|
1255
1272
|
command: validation.command,
|
|
1256
|
-
originalChanges:
|
|
1273
|
+
originalChanges: freshProposal.changes,
|
|
1257
1274
|
retryCount: 0
|
|
1258
1275
|
});
|
|
1259
1276
|
// Trigger automatic build fix
|
|
1260
|
-
await triggerBuildFix(cwd, msg.taskId, validation.errors, validation.command,
|
|
1277
|
+
await triggerBuildFix(cwd, msg.taskId, validation.errors, validation.command, freshProposal.changes, resolvedLassoKey, agentConfig, collabConfig, socket, taskControllers, taskSnapshots, buildErrorContext);
|
|
1261
1278
|
return;
|
|
1262
1279
|
}
|
|
1263
1280
|
socket.send(JSON.stringify({
|
|
1264
1281
|
type: "applied",
|
|
1265
1282
|
taskId: msg.taskId,
|
|
1266
|
-
message: `${
|
|
1283
|
+
message: `${freshProposal.changes.length} file${freshProposal.changes.length === 1 ? "" : "s"} updated. Your dev server will reload.`,
|
|
1267
1284
|
validation
|
|
1268
1285
|
}));
|
|
1269
1286
|
}
|
|
1270
1287
|
catch (error) {
|
|
1271
|
-
//
|
|
1272
|
-
// if a filesystem error occurs during the write phase.
|
|
1288
|
+
// Restore this task's snapshot if a filesystem error occurs
|
|
1273
1289
|
for (const snapshot of taskSnapshots.get(msg.taskId) || []) {
|
|
1274
1290
|
if (snapshot.content === null) {
|
|
1275
1291
|
if (node_fs_1.default.existsSync(snapshot.filePath))
|
|
@@ -1281,18 +1297,11 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
1281
1297
|
}
|
|
1282
1298
|
taskSnapshots.delete(msg.taskId);
|
|
1283
1299
|
const message = error instanceof Error ? error.message : "The change could not be applied.";
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
reviewRefreshAttempts.set(msg.taskId, refreshAttempts + 1);
|
|
1290
|
-
enqueueTask(msg.taskId, editRequest, editConfig, 0);
|
|
1291
|
-
socket.send(JSON.stringify({ type: "agent_status", taskId: msg.taskId, status: "working", message: "The source changed. Refreshing the review against the current file…" }));
|
|
1292
|
-
}
|
|
1293
|
-
else {
|
|
1294
|
-
socket.send(JSON.stringify({ type: "agent_status", taskId: msg.taskId, status: "error", message }));
|
|
1295
|
-
}
|
|
1300
|
+
socket.send(JSON.stringify({ type: "agent_status", taskId: msg.taskId, status: "error", message }));
|
|
1301
|
+
}
|
|
1302
|
+
finally {
|
|
1303
|
+
if (taskControllers.get(msg.taskId))
|
|
1304
|
+
taskControllers.delete(msg.taskId);
|
|
1296
1305
|
}
|
|
1297
1306
|
}
|
|
1298
1307
|
else if (msg.type === "undo") {
|
|
@@ -1309,95 +1318,6 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
1309
1318
|
taskSnapshots.delete(msg.taskId || "");
|
|
1310
1319
|
socket.send(JSON.stringify({ type: "undone", taskId: msg.taskId, message: snapshots.length ? "The accepted change was reverted." : "There is no accepted change to undo." }));
|
|
1311
1320
|
}
|
|
1312
|
-
else if (msg.type === "resolve_conflict") {
|
|
1313
|
-
const { taskId, action, conflicts } = msg;
|
|
1314
|
-
if (action === "retry") {
|
|
1315
|
-
// Re-run the edit request with current file content
|
|
1316
|
-
const editRequest = editRequests.get(taskId);
|
|
1317
|
-
const editConfig = editConfigs.get(taskId);
|
|
1318
|
-
if (editRequest && editConfig) {
|
|
1319
|
-
reviewRefreshAttempts.set(taskId, 0);
|
|
1320
|
-
enqueueTask(taskId, editRequest, editConfig, 0);
|
|
1321
|
-
socket.send(JSON.stringify({ type: "agent_status", taskId, status: "working", message: "Retrying with current file content..." }));
|
|
1322
|
-
}
|
|
1323
|
-
else {
|
|
1324
|
-
socket.send(JSON.stringify({ type: "agent_status", taskId, status: "error", message: "Could not retry: original request not found." }));
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
else if (action === "force") {
|
|
1328
|
-
// Force apply despite conflicts (user's choice)
|
|
1329
|
-
try {
|
|
1330
|
-
const snapshots = [];
|
|
1331
|
-
const planned = new Map();
|
|
1332
|
-
// Get the original changes from the edit request
|
|
1333
|
-
const editRequest = editRequests.get(taskId);
|
|
1334
|
-
if (!editRequest) {
|
|
1335
|
-
socket.send(JSON.stringify({ type: "agent_status", taskId, status: "error", message: "Could not force apply: original request not found." }));
|
|
1336
|
-
return;
|
|
1337
|
-
}
|
|
1338
|
-
// Re-prepare changes with current content (may fail, but that's expected)
|
|
1339
|
-
for (const change of editRequest.changesHistory?.[editRequest.changesHistory.length - 1]?.changes || []) {
|
|
1340
|
-
const isNew = !change.oldString;
|
|
1341
|
-
const filePath = resolveProposedFile(cwd, change.filePath, true);
|
|
1342
|
-
const exists = node_fs_1.default.existsSync(filePath);
|
|
1343
|
-
const content = exists ? node_fs_1.default.readFileSync(filePath, "utf8") : "";
|
|
1344
|
-
const prepared = (!exists || isNew)
|
|
1345
|
-
? { start: 0, end: content.length, oldString: content, newString: change.newString }
|
|
1346
|
-
: prepareChange(content, change);
|
|
1347
|
-
const fileChanges = planned.get(filePath) || [];
|
|
1348
|
-
if (fileChanges.some((item) => prepared.start < item.end && item.start < prepared.end)) {
|
|
1349
|
-
throw new Error(`Could not safely apply ${change.filePath}. Proposed changes overlap.`);
|
|
1350
|
-
}
|
|
1351
|
-
fileChanges.push({ filePath, content, exists, ...prepared });
|
|
1352
|
-
planned.set(filePath, fileChanges);
|
|
1353
|
-
}
|
|
1354
|
-
taskSnapshots.set(taskId, snapshots);
|
|
1355
|
-
for (const [filePath, changes] of planned) {
|
|
1356
|
-
const exists = changes[0].exists;
|
|
1357
|
-
const content = changes[0].content;
|
|
1358
|
-
snapshots.push({ filePath, content: exists ? content : null });
|
|
1359
|
-
const nextContent = exists
|
|
1360
|
-
? [...changes]
|
|
1361
|
-
.sort((a, b) => b.start - a.start)
|
|
1362
|
-
.reduce((value, change) => value.slice(0, change.start) + change.newString + value.slice(change.end), content)
|
|
1363
|
-
: changes[0].newString;
|
|
1364
|
-
node_fs_1.default.mkdirSync(node_path_1.default.dirname(filePath), { recursive: true });
|
|
1365
|
-
node_fs_1.default.writeFileSync(filePath, nextContent);
|
|
1366
|
-
}
|
|
1367
|
-
socket.send(JSON.stringify({
|
|
1368
|
-
type: "applied",
|
|
1369
|
-
taskId,
|
|
1370
|
-
message: "Changes force-applied despite conflicts."
|
|
1371
|
-
}));
|
|
1372
|
-
}
|
|
1373
|
-
catch (error) {
|
|
1374
|
-
for (const snapshot of taskSnapshots.get(taskId) || []) {
|
|
1375
|
-
if (snapshot.content === null) {
|
|
1376
|
-
if (node_fs_1.default.existsSync(snapshot.filePath))
|
|
1377
|
-
node_fs_1.default.unlinkSync(snapshot.filePath);
|
|
1378
|
-
}
|
|
1379
|
-
else {
|
|
1380
|
-
node_fs_1.default.writeFileSync(snapshot.filePath, snapshot.content);
|
|
1381
|
-
}
|
|
1382
|
-
}
|
|
1383
|
-
taskSnapshots.delete(taskId);
|
|
1384
|
-
socket.send(JSON.stringify({ type: "agent_status", taskId, status: "error", message: error instanceof Error ? error.message : "Force apply failed." }));
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
else if (action === "rebase") {
|
|
1388
|
-
// User wants to rebase - re-run the edit with updated context
|
|
1389
|
-
const editRequest = editRequests.get(taskId);
|
|
1390
|
-
const editConfig = editConfigs.get(taskId);
|
|
1391
|
-
if (editRequest && editConfig) {
|
|
1392
|
-
reviewRefreshAttempts.set(taskId, 0);
|
|
1393
|
-
enqueueTask(taskId, editRequest, editConfig, 0);
|
|
1394
|
-
socket.send(JSON.stringify({ type: "agent_status", taskId, status: "working", message: "Rebasing changes against current file content..." }));
|
|
1395
|
-
}
|
|
1396
|
-
else {
|
|
1397
|
-
socket.send(JSON.stringify({ type: "agent_status", taskId, status: "error", message: "Could not rebase: original request not found." }));
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
1321
|
else if (msg.type === "restore_snapshot") {
|
|
1402
1322
|
const success = (0, snapshot_1.restoreSnapshot)(cwd, msg.snapshotId);
|
|
1403
1323
|
socket.send(JSON.stringify({
|
package/dist/overlay.js
CHANGED
|
@@ -10556,127 +10556,6 @@
|
|
|
10556
10556
|
color: var(--lo-text-2);
|
|
10557
10557
|
}
|
|
10558
10558
|
|
|
10559
|
-
/* ==========================================================
|
|
10560
|
-
CONFLICT PANEL
|
|
10561
|
-
========================================================== */
|
|
10562
|
-
|
|
10563
|
-
.lasso-conflict {
|
|
10564
|
-
position: fixed;
|
|
10565
|
-
width: min(540px, calc(100vw - 24px));
|
|
10566
|
-
max-height: min(400px, calc(100vh - 24px));
|
|
10567
|
-
overflow: auto;
|
|
10568
|
-
padding: 18px;
|
|
10569
|
-
border: 1px solid #f59e0b;
|
|
10570
|
-
border-radius: var(--lo-radius-xl);
|
|
10571
|
-
background: rgba(30, 27, 22, 0.98);
|
|
10572
|
-
backdrop-filter: blur(24px);
|
|
10573
|
-
-webkit-backdrop-filter: blur(24px);
|
|
10574
|
-
color: var(--lo-text);
|
|
10575
|
-
box-shadow: 0 20px 48px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(245, 158, 11, 0.2);
|
|
10576
|
-
pointer-events: auto;
|
|
10577
|
-
font-family: inherit;
|
|
10578
|
-
z-index: 25;
|
|
10579
|
-
}
|
|
10580
|
-
|
|
10581
|
-
.lasso-conflict[hidden] {
|
|
10582
|
-
display: none;
|
|
10583
|
-
}
|
|
10584
|
-
|
|
10585
|
-
.lasso-conflict-header {
|
|
10586
|
-
display: flex;
|
|
10587
|
-
align-items: flex-start;
|
|
10588
|
-
justify-content: space-between;
|
|
10589
|
-
gap: 16px;
|
|
10590
|
-
margin-bottom: 14px;
|
|
10591
|
-
}
|
|
10592
|
-
|
|
10593
|
-
.lasso-conflict-title {
|
|
10594
|
-
margin: 0;
|
|
10595
|
-
font-size: 15px;
|
|
10596
|
-
font-weight: 700;
|
|
10597
|
-
color: #f59e0b;
|
|
10598
|
-
}
|
|
10599
|
-
|
|
10600
|
-
.lasso-conflict-subtitle {
|
|
10601
|
-
margin: 4px 0 0;
|
|
10602
|
-
color: var(--lo-text-2);
|
|
10603
|
-
font-size: 12px;
|
|
10604
|
-
line-height: 1.4;
|
|
10605
|
-
}
|
|
10606
|
-
|
|
10607
|
-
.lasso-conflict-close {
|
|
10608
|
-
border: 0;
|
|
10609
|
-
background: transparent;
|
|
10610
|
-
color: var(--lo-text-3);
|
|
10611
|
-
font-size: 18px;
|
|
10612
|
-
cursor: pointer;
|
|
10613
|
-
}
|
|
10614
|
-
|
|
10615
|
-
.lasso-conflict-close:hover {
|
|
10616
|
-
color: var(--lo-text);
|
|
10617
|
-
}
|
|
10618
|
-
|
|
10619
|
-
.lasso-conflict-file {
|
|
10620
|
-
margin-top: 10px;
|
|
10621
|
-
overflow: hidden;
|
|
10622
|
-
border: 1px solid var(--lo-border);
|
|
10623
|
-
border-radius: var(--lo-radius-md);
|
|
10624
|
-
}
|
|
10625
|
-
|
|
10626
|
-
.lasso-conflict-file-name {
|
|
10627
|
-
padding: 8px 10px;
|
|
10628
|
-
background: rgba(245, 158, 11, 0.1);
|
|
10629
|
-
color: #f59e0b;
|
|
10630
|
-
font: 600 11px/1.2 var(--lo-font-mono);
|
|
10631
|
-
}
|
|
10632
|
-
|
|
10633
|
-
.lasso-conflict-details {
|
|
10634
|
-
padding: 10px;
|
|
10635
|
-
font-size: 11px;
|
|
10636
|
-
color: var(--lo-text-2);
|
|
10637
|
-
}
|
|
10638
|
-
|
|
10639
|
-
.lasso-conflict-hash {
|
|
10640
|
-
display: flex;
|
|
10641
|
-
flex-direction: column;
|
|
10642
|
-
gap: 4px;
|
|
10643
|
-
font-family: var(--lo-font-mono);
|
|
10644
|
-
}
|
|
10645
|
-
|
|
10646
|
-
.lasso-conflict-actions {
|
|
10647
|
-
display: flex;
|
|
10648
|
-
justify-content: flex-end;
|
|
10649
|
-
gap: 8px;
|
|
10650
|
-
margin-top: 16px;
|
|
10651
|
-
}
|
|
10652
|
-
|
|
10653
|
-
.lasso-conflict-actions button {
|
|
10654
|
-
min-height: 34px;
|
|
10655
|
-
padding: 0 14px;
|
|
10656
|
-
border: 1px solid var(--lo-border);
|
|
10657
|
-
border-radius: var(--lo-radius-md);
|
|
10658
|
-
background: var(--lo-surface-2);
|
|
10659
|
-
color: var(--lo-text);
|
|
10660
|
-
font: 600 12px/1 inherit;
|
|
10661
|
-
cursor: pointer;
|
|
10662
|
-
transition: background 120ms ease, transform 120ms ease;
|
|
10663
|
-
}
|
|
10664
|
-
|
|
10665
|
-
.lasso-conflict-actions button:hover {
|
|
10666
|
-
background: var(--lo-surface-hover);
|
|
10667
|
-
transform: translateY(-1px);
|
|
10668
|
-
}
|
|
10669
|
-
|
|
10670
|
-
.lasso-conflict-force {
|
|
10671
|
-
border-color: #f59e0b;
|
|
10672
|
-
background: rgba(245, 158, 11, 0.1);
|
|
10673
|
-
color: #f59e0b;
|
|
10674
|
-
}
|
|
10675
|
-
|
|
10676
|
-
.lasso-conflict-force:hover {
|
|
10677
|
-
background: rgba(245, 158, 11, 0.2);
|
|
10678
|
-
}
|
|
10679
|
-
|
|
10680
10559
|
/* ==========================================================
|
|
10681
10560
|
TIMELINE PANEL
|
|
10682
10561
|
========================================================== */
|
|
@@ -21874,13 +21753,6 @@
|
|
|
21874
21753
|
}
|
|
21875
21754
|
}
|
|
21876
21755
|
}
|
|
21877
|
-
if (message.type === "conflict_detected" && message.conflicts && message.taskId) {
|
|
21878
|
-
const taskId2 = message.taskId;
|
|
21879
|
-
if (taskId2 === state.promptTaskId) {
|
|
21880
|
-
showConflict(message.conflicts, message.message);
|
|
21881
|
-
}
|
|
21882
|
-
void notifyAgent("Conflict detected", message.message);
|
|
21883
|
-
}
|
|
21884
21756
|
if (message.type === "timeline" && message.snapshots) {
|
|
21885
21757
|
state.timelineSnapshots = message.snapshots;
|
|
21886
21758
|
showTimeline();
|
|
@@ -22206,7 +22078,6 @@ The agent is automatically attempting to fix the build errors...`;
|
|
|
22206
22078
|
var reviewPanel = null;
|
|
22207
22079
|
var agentPromptPanel = null;
|
|
22208
22080
|
var agentPromptTaskId = null;
|
|
22209
|
-
var conflictPanel = null;
|
|
22210
22081
|
var timelinePanel = null;
|
|
22211
22082
|
var modelBtn = null;
|
|
22212
22083
|
var modelName = null;
|
|
@@ -22427,30 +22298,6 @@ The agent is automatically attempting to fix the build errors...`;
|
|
|
22427
22298
|
`;
|
|
22428
22299
|
dom.shadow.appendChild(rev);
|
|
22429
22300
|
reviewPanel = rev;
|
|
22430
|
-
const conflict = document.createElement("div");
|
|
22431
|
-
conflict.className = "lasso-conflict";
|
|
22432
|
-
conflict.hidden = true;
|
|
22433
|
-
conflict.innerHTML = `
|
|
22434
|
-
<div class="lasso-conflict-header">
|
|
22435
|
-
<div>
|
|
22436
|
-
<h3 class="lasso-conflict-title">\u26A0\uFE0F Source conflict detected</h3>
|
|
22437
|
-
<p class="lasso-conflict-subtitle">The file(s) have changed since the suggestion was generated.</p>
|
|
22438
|
-
</div>
|
|
22439
|
-
<button class="lasso-conflict-close" type="button" aria-label="Close conflict panel">\xD7</button>
|
|
22440
|
-
</div>
|
|
22441
|
-
<div class="lasso-conflict-files"></div>
|
|
22442
|
-
<div class="lasso-conflict-actions">
|
|
22443
|
-
<button class="lasso-conflict-retry" type="button">Retry with current content</button>
|
|
22444
|
-
<button class="lasso-conflict-rebase" type="button">Rebase changes</button>
|
|
22445
|
-
<button class="lasso-conflict-force" type="button">Force apply</button>
|
|
22446
|
-
</div>
|
|
22447
|
-
`;
|
|
22448
|
-
dom.shadow.appendChild(conflict);
|
|
22449
|
-
conflictPanel = conflict;
|
|
22450
|
-
conflict.querySelector(".lasso-conflict-close").addEventListener("click", closeConflict2);
|
|
22451
|
-
conflict.querySelector(".lasso-conflict-retry").addEventListener("click", () => resolveConflict("retry"));
|
|
22452
|
-
conflict.querySelector(".lasso-conflict-rebase").addEventListener("click", () => resolveConflict("rebase"));
|
|
22453
|
-
conflict.querySelector(".lasso-conflict-force").addEventListener("click", () => resolveConflict("force"));
|
|
22454
22301
|
const timeline = document.createElement("div");
|
|
22455
22302
|
timeline.className = "lasso-timeline";
|
|
22456
22303
|
timeline.hidden = true;
|
|
@@ -23077,7 +22924,6 @@ The agent is automatically attempting to fix the build errors...`;
|
|
|
23077
22924
|
}
|
|
23078
22925
|
function hideReview() {
|
|
23079
22926
|
if (reviewPanel) reviewPanel.hidden = true;
|
|
23080
|
-
closeConflict2();
|
|
23081
22927
|
}
|
|
23082
22928
|
function resetPromptSession(element = state.selected) {
|
|
23083
22929
|
state.promptTaskId = null;
|
|
@@ -23179,54 +23025,6 @@ The agent is automatically attempting to fix the build errors...`;
|
|
|
23179
23025
|
hideReview();
|
|
23180
23026
|
resetAgentState();
|
|
23181
23027
|
}
|
|
23182
|
-
function showConflict(conflicts, message) {
|
|
23183
|
-
if (!conflictPanel) return;
|
|
23184
|
-
const subtitle = conflictPanel.querySelector(".lasso-conflict-subtitle");
|
|
23185
|
-
const files = conflictPanel.querySelector(".lasso-conflict-files");
|
|
23186
|
-
if (!subtitle || !files) return;
|
|
23187
|
-
subtitle.textContent = message;
|
|
23188
|
-
files.replaceChildren(
|
|
23189
|
-
...conflicts.map((conflict) => {
|
|
23190
|
-
const file = document.createElement("div");
|
|
23191
|
-
file.className = "lasso-conflict-file";
|
|
23192
|
-
const name = document.createElement("div");
|
|
23193
|
-
name.className = "lasso-conflict-file-name";
|
|
23194
|
-
name.textContent = conflict.filePath;
|
|
23195
|
-
const details = document.createElement("div");
|
|
23196
|
-
details.className = "lasso-conflict-details";
|
|
23197
|
-
details.innerHTML = `
|
|
23198
|
-
<div class="lasso-conflict-hash">
|
|
23199
|
-
<span>Expected: ${conflict.expectedHash.slice(0, 8)}...</span>
|
|
23200
|
-
<span>Actual: ${conflict.actualHash.slice(0, 8)}...</span>
|
|
23201
|
-
</div>
|
|
23202
|
-
`;
|
|
23203
|
-
file.append(name, details);
|
|
23204
|
-
return file;
|
|
23205
|
-
})
|
|
23206
|
-
);
|
|
23207
|
-
conflictPanel.hidden = false;
|
|
23208
|
-
const left = Math.max(12, (window.innerWidth - Math.min(520, window.innerWidth - 24)) / 2);
|
|
23209
|
-
const top = Math.max(12, (window.innerHeight - Math.min(400, window.innerHeight - 24)) / 2);
|
|
23210
|
-
conflictPanel.style.left = `${left}px`;
|
|
23211
|
-
conflictPanel.style.top = `${top}px`;
|
|
23212
|
-
}
|
|
23213
|
-
function closeConflict2() {
|
|
23214
|
-
if (!conflictPanel) return;
|
|
23215
|
-
conflictPanel.hidden = true;
|
|
23216
|
-
}
|
|
23217
|
-
function resolveConflict(action) {
|
|
23218
|
-
const taskId2 = state.promptTaskId;
|
|
23219
|
-
if (!taskId2 || !state.bridgeSocket || state.bridgeSocket.readyState !== WebSocket.OPEN) return;
|
|
23220
|
-
state.bridgeSocket.send(JSON.stringify({
|
|
23221
|
-
type: "resolve_conflict",
|
|
23222
|
-
taskId: taskId2,
|
|
23223
|
-
action,
|
|
23224
|
-
conflicts: []
|
|
23225
|
-
// Bridge will re-detect conflicts
|
|
23226
|
-
}));
|
|
23227
|
-
closeConflict2();
|
|
23228
|
-
closeReview();
|
|
23229
|
-
}
|
|
23230
23028
|
function showTimeline() {
|
|
23231
23029
|
if (!timelinePanel) return;
|
|
23232
23030
|
const list2 = timelinePanel.querySelector(".lasso-timeline-list");
|
package/package.json
CHANGED