@lasso-ai/cli 1.3.5 → 1.3.7

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.
@@ -1,6 +1,6 @@
1
1
  import { type SourceChange, type AgentPrompt } from "./agent";
2
2
  import type { CollabConfig } from "./project";
3
- import { type TimelineSnapshot, type ConflictInfo } from "./snapshot";
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[];
@@ -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
- // Create snapshot before applying changes
1187
- const filePaths = [...new Set(msg.changes.map(c => c.filePath))];
1188
- const parentSnapshot = (0, snapshot_1.getSnapshotByTaskId)(cwd, msg.taskId);
1189
- // Create pre-apply snapshot
1190
- const preSnapshot = (0, snapshot_1.createSnapshot)(cwd, msg.taskId, `Pre-apply: ${msg.changes.length} file${msg.changes.length === 1 ? "" : "s"}`, filePaths, parentSnapshot?.id);
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
- const conflicts = (0, snapshot_1.detectConflicts)(cwd, expectedFiles);
1199
- if (conflicts.length > 0) {
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: "conflict_detected",
1197
+ type: "agent_status",
1202
1198
  taskId: msg.taskId,
1203
- conflicts,
1204
- message: `Conflict detected in ${conflicts.length} file${conflicts.length === 1 ? "" : "s"}. The source has changed since the suggestion was generated.`
1199
+ status: "error",
1200
+ message: "Could not re-generate changes: original request not found."
1205
1201
  }));
1206
1202
  return;
1207
1203
  }
1208
- for (const change of msg.changes) {
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
- // Validate every change before writing any file, then apply each
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: ${msg.changes.length} file${msg.changes.length === 1 ? "" : "s"}`, filePaths, preSnapshot.id);
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: msg.changes,
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, msg.changes, resolvedLassoKey, agentConfig, collabConfig, socket, taskControllers, taskSnapshots, buildErrorContext);
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: `${msg.changes.length} file${msg.changes.length === 1 ? "" : "s"} updated. Your dev server will reload.`,
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
- // Validation happens before writes, but restore this task's snapshot
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
- const sourceChanged = message.includes("The source changed after the suggestion was generated");
1285
- const editRequest = editRequests.get(msg.taskId);
1286
- const editConfig = editConfigs.get(msg.taskId);
1287
- const refreshAttempts = reviewRefreshAttempts.get(msg.taskId) || 0;
1288
- if (sourceChanged && editRequest && editConfig && refreshAttempts < 1) {
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({
@@ -13,10 +13,24 @@ const node_child_process_1 = require("node:child_process");
13
13
  const PUBLIC_PORT = 3000; // what the user opens in the browser
14
14
  const INTERNAL_PORT = 3055; // where the real `next dev` actually runs
15
15
  function serveOverlayBundle(res, cwd) {
16
- const bundlePath = (0, node_path_1.resolve)(cwd, "node_modules/lasso/dist/overlay.js");
17
- // when running from within the Lasso repo itself (not yet published),
18
- // this resolves relative to Lasso's own dist folder instead — adjust
19
- // the path to point at your actual dist/overlay.js location for now.
16
+ // Try multiple possible paths for the overlay bundle
17
+ const possiblePaths = [
18
+ (0, node_path_1.resolve)(cwd, "node_modules/@lasso-ai/cli/dist/overlay.js"),
19
+ (0, node_path_1.resolve)(cwd, "node_modules/lasso/dist/overlay.js"),
20
+ (0, node_path_1.resolve)(__dirname, "../../overlay.js"), // When running from Lasso repo
21
+ ];
22
+ let bundlePath;
23
+ for (const path of possiblePaths) {
24
+ if ((0, node_fs_1.existsSync)(path)) {
25
+ bundlePath = path;
26
+ break;
27
+ }
28
+ }
29
+ if (!bundlePath) {
30
+ res.writeHead(404, { "Content-Type": "text/plain" });
31
+ res.end("Lasso overlay bundle not found. Make sure @lasso-ai/cli is installed.");
32
+ return;
33
+ }
20
34
  res.setHeader("Content-Type", "application/javascript");
21
35
  res.end((0, node_fs_1.readFileSync)(bundlePath, "utf-8"));
22
36
  }
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lasso-ai/cli",
3
- "version": "1.3.5",
3
+ "version": "1.3.7",
4
4
  "description": "Select any part of your running app, describe a change, and let AI edit the real source code.",
5
5
  "type": "commonjs",
6
6
  "main": "dist/cli/index.js",
@@ -31,6 +31,7 @@
31
31
  "start": "node dist/cli/index.js",
32
32
  "prepublishOnly": "npm run build",
33
33
  "format": "prettier --write .",
34
+ "deploy": "pnpm build && npm publish --access public",
34
35
  "format:check": "prettier --check .",
35
36
  "test": "echo \"Error: no test specified\" && exit 1"
36
37
  },