@lasso-ai/cli 2.1.10 → 2.1.12

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.
Files changed (2) hide show
  1. package/dist/overlay.js +93 -39
  2. package/package.json +1 -1
package/dist/overlay.js CHANGED
@@ -20294,6 +20294,36 @@
20294
20294
  }
20295
20295
  return;
20296
20296
  }
20297
+ const fileCheck = target.closest(".lasso-command-file-check");
20298
+ if (fileCheck) {
20299
+ const msgId = fileCheck.closest(".lasso-command-msg")?.dataset.msgId;
20300
+ const filePath = fileCheck.dataset.filePath;
20301
+ const msg = commandMessages.find((m) => m.id === msgId);
20302
+ if (msg && filePath) {
20303
+ msg.rejectedFilePaths = msg.rejectedFilePaths || [];
20304
+ if (fileCheck.checked) {
20305
+ msg.rejectedFilePaths = msg.rejectedFilePaths.filter((p) => p !== filePath);
20306
+ } else {
20307
+ if (!msg.rejectedFilePaths.includes(filePath)) {
20308
+ msg.rejectedFilePaths.push(filePath);
20309
+ }
20310
+ }
20311
+ renderMessages();
20312
+ }
20313
+ return;
20314
+ }
20315
+ const viewFileDiffBtn = target.closest(".lasso-command-view-file-diff-btn");
20316
+ if (viewFileDiffBtn) {
20317
+ const msgId = viewFileDiffBtn.closest(".lasso-command-msg")?.dataset.msgId;
20318
+ const filePath = viewFileDiffBtn.dataset.filePath;
20319
+ const msg = commandMessages.find((m) => m.id === msgId);
20320
+ if (msg && filePath) {
20321
+ msg.activeDiffFile = filePath;
20322
+ msg.showDiff = true;
20323
+ renderMessages();
20324
+ }
20325
+ return;
20326
+ }
20297
20327
  const diffToggle = target.closest(".lasso-command-toggle-diff");
20298
20328
  if (diffToggle) {
20299
20329
  const msgId = diffToggle.closest(".lasso-command-msg")?.dataset.msgId;
@@ -20309,6 +20339,12 @@
20309
20339
  const msgId = applyBtn.closest(".lasso-command-msg")?.dataset.msgId;
20310
20340
  const msg = commandMessages.find((m) => m.id === msgId);
20311
20341
  if (msg && msg.changes?.length && state.bridgeSocket?.readyState === WebSocket.OPEN) {
20342
+ const rejected = new Set(msg.rejectedFilePaths || []);
20343
+ const approvedChanges = msg.changes.filter((c) => !rejected.has(c.filePath));
20344
+ if (approvedChanges.length === 0) {
20345
+ alert("Please select at least one file to keep.");
20346
+ return;
20347
+ }
20312
20348
  applyBtn.disabled = true;
20313
20349
  applyBtn.textContent = "Applying\u2026";
20314
20350
  state.runtimeErrors = [];
@@ -20316,7 +20352,7 @@
20316
20352
  JSON.stringify({
20317
20353
  type: "apply",
20318
20354
  taskId: msg.id,
20319
- changes: msg.changes
20355
+ changes: approvedChanges
20320
20356
  })
20321
20357
  );
20322
20358
  }
@@ -20646,26 +20682,22 @@ Please proceed directly with the implementation and code changes from this point
20646
20682
  }
20647
20683
  const hasChanges = Array.isArray(message.changes) && message.changes.length > 0;
20648
20684
  if (targetMsg.thinking) {
20649
- if (!hasChanges) {
20650
- targetMsg.thinking = void 0;
20685
+ for (const step of targetMsg.thinking.steps) {
20686
+ step.status = "completed";
20687
+ }
20688
+ targetMsg.thinking.completed = true;
20689
+ targetMsg.thinking.expanded = false;
20690
+ if (message.totalThinkingTimeMs) {
20691
+ targetMsg.thinking.durationSeconds = Math.max(1, Math.round(message.totalThinkingTimeMs / 1e3));
20651
20692
  } else {
20652
- for (const step of targetMsg.thinking.steps) {
20653
- step.status = "completed";
20654
- }
20655
- targetMsg.thinking.completed = true;
20656
- targetMsg.thinking.expanded = false;
20657
- if (message.totalThinkingTimeMs) {
20658
- targetMsg.thinking.durationSeconds = Math.max(1, Math.round(message.totalThinkingTimeMs / 1e3));
20659
- } else {
20660
- targetMsg.thinking.durationSeconds = Math.max(1, Math.round((Date.now() - activeStartTime) / 1e3));
20661
- }
20662
- if (Array.isArray(message.thinking) && message.thinking.length) {
20663
- targetMsg.thinking.steps = message.thinking.map((s) => ({
20664
- title: s.title || "Completed step",
20665
- detail: s.detail,
20666
- status: "completed"
20667
- }));
20668
- }
20693
+ targetMsg.thinking.durationSeconds = Math.max(1, Math.round((Date.now() - activeStartTime) / 1e3));
20694
+ }
20695
+ if (Array.isArray(message.thinking) && message.thinking.length) {
20696
+ targetMsg.thinking.steps = message.thinking.map((s) => ({
20697
+ title: s.title || "Completed step",
20698
+ detail: s.detail,
20699
+ status: "completed"
20700
+ }));
20669
20701
  }
20670
20702
  }
20671
20703
  targetMsg.content = message.message || "";
@@ -20748,7 +20780,13 @@ Please proceed directly with the implementation and code changes from this point
20748
20780
  clearInterval(activeThinkingInterval);
20749
20781
  activeThinkingInterval = null;
20750
20782
  }
20751
- targetMsg.thinking = void 0;
20783
+ if (targetMsg.thinking) {
20784
+ for (const step of targetMsg.thinking.steps) {
20785
+ step.status = "completed";
20786
+ }
20787
+ targetMsg.thinking.completed = true;
20788
+ targetMsg.thinking.expanded = false;
20789
+ }
20752
20790
  const question = message.prompt?.question || message.message || "";
20753
20791
  targetMsg.content = question;
20754
20792
  targetMsg.isStreaming = false;
@@ -20883,7 +20921,9 @@ Please proceed directly with the implementation and code changes from this point
20883
20921
  const changes = msg.changes;
20884
20922
  const isApplied = msg.changesApplied;
20885
20923
  const isUndone = msg.changesUndone;
20886
- const showDiff = msg.showDiff;
20924
+ const showDiff = msg.showDiff !== false;
20925
+ const rejected = new Set(msg.rejectedFilePaths || []);
20926
+ const activeFile = msg.activeDiffFile || changes[0]?.filePath;
20887
20927
  const scopeHtml = msg.todo && msg.todo.length ? `
20888
20928
  <div class="lasso-command-scope-list">
20889
20929
  ${msg.todo.map((item) => `
@@ -20895,34 +20935,43 @@ Please proceed directly with the implementation and code changes from this point
20895
20935
  `).join("")}
20896
20936
  </div>
20897
20937
  ` : "";
20938
+ const approvedCount = changes.length - rejected.size;
20898
20939
  return `
20899
20940
  <div class="lasso-command-changes-card">
20900
20941
  <div class="lasso-command-changes-header">
20901
20942
  <div class="lasso-command-changes-title">
20902
- <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
20943
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
20903
20944
  <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
20904
20945
  <polyline points="14 2 14 8 20 8"/>
20905
20946
  </svg>
20906
- <span>${changes.length} file${changes.length === 1 ? "" : "s"} modified</span>
20947
+ <span>Proposed changes (${approvedCount}/${changes.length} files selected)</span>
20907
20948
  </div>
20908
20949
  <button class="lasso-command-toggle-diff" type="button">
20909
- ${showDiff ? "Hide diff" : "View diff"}
20950
+ ${showDiff ? "Hide diffs" : "Inspect diffs"}
20910
20951
  </button>
20911
20952
  </div>
20912
20953
  ${scopeHtml}
20913
20954
 
20914
20955
  <div class="lasso-command-files-list">
20915
- ${changes.map(
20916
- (c) => `
20917
- <div class="lasso-command-file-row">
20956
+ ${changes.map((c) => {
20957
+ const isExcluded = rejected.has(c.filePath);
20958
+ const isSelected = activeFile === c.filePath;
20959
+ return `
20960
+ <div class="lasso-command-file-row ${isSelected ? "selected" : ""} ${isExcluded ? "excluded" : ""}" data-file-path="${escapeHtml4(c.filePath)}">
20961
+ <label class="lasso-command-file-checkbox-label" title="${isExcluded ? "Click to include file" : "Click to exclude file"}">
20962
+ <input type="checkbox" class="lasso-command-file-check" ${isExcluded ? "" : "checked"} data-file-path="${escapeHtml4(c.filePath)}" />
20963
+ </label>
20918
20964
  <span class="lasso-command-file-badge ${c.oldString ? "modified" : "added"}">${c.oldString ? "M" : "+"}</span>
20919
20965
  <span class="lasso-command-file-name" title="${c.filePath}">${escapeHtml4(c.filePath)}</span>
20966
+ <button class="lasso-command-view-file-diff-btn" type="button" data-file-path="${escapeHtml4(c.filePath)}" title="View diff for this file">
20967
+ ${isSelected ? "Active" : "Inspect"}
20968
+ </button>
20920
20969
  </div>
20921
- `
20922
- ).join("")}
20970
+ `;
20971
+ }).join("")}
20923
20972
  </div>
20924
20973
 
20925
- ${showDiff ? renderDiffPreview(changes) : ""}
20974
+ ${showDiff ? renderDiffPreview(changes, activeFile, rejected) : ""}
20926
20975
 
20927
20976
  <div class="lasso-command-changes-footer">
20928
20977
  ${isApplied ? `
@@ -20938,7 +20987,7 @@ Please proceed directly with the implementation and code changes from this point
20938
20987
  <button class="lasso-command-apply-btn primary" type="button">Re-apply</button>
20939
20988
  ` : `
20940
20989
  <button class="lasso-command-apply-btn primary" type="button">
20941
- <span>Keep Changes</span>
20990
+ <span>Keep Selected (${approvedCount})</span>
20942
20991
  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>
20943
20992
  </button>
20944
20993
  <button class="lasso-command-undo-btn secondary" type="button">Discard</button>
@@ -20947,16 +20996,21 @@ Please proceed directly with the implementation and code changes from this point
20947
20996
  </div>
20948
20997
  `;
20949
20998
  }
20950
- function renderDiffPreview(changes) {
20999
+ function renderDiffPreview(changes, activeFilePath, rejected) {
21000
+ const filtered = activeFilePath ? changes.filter((c) => c.filePath === activeFilePath) : changes;
21001
+ const listToRender = filtered.length > 0 ? filtered : changes;
20951
21002
  return `
20952
21003
  <div class="lasso-command-diff-container">
20953
- ${changes.map(
21004
+ ${listToRender.map(
20954
21005
  (c) => `
20955
- <div class="lasso-command-diff-file">
20956
- <div class="lasso-command-diff-file-header">${escapeHtml4(c.filePath)}</div>
20957
- <pre class="lasso-command-diff-content">${c.operation === "deleted" || c.newString === "" && c.oldString !== "" ? `<span class="lasso-diff-del">- ${escapeHtml4(c.oldString.slice(0, 300))}</span>
20958
- <span class="lasso-diff-del">(file deleted)</span>` : `${c.oldString ? `<span class="lasso-diff-del">- ${escapeHtml4(c.oldString.slice(0, 300))}</span>
20959
- ` : ""}${c.newString ? `<span class="lasso-diff-add">+ ${escapeHtml4(c.newString.slice(0, 300))}</span>` : ""}`}</pre>
21006
+ <div class="lasso-command-diff-file ${rejected?.has(c.filePath) ? "excluded-diff" : ""}">
21007
+ <div class="lasso-command-diff-file-header">
21008
+ <span>${escapeHtml4(c.filePath)}</span>
21009
+ ${rejected?.has(c.filePath) ? `<span style="color: #f87171; font-size: 11px; margin-left: 8px;">(Excluded from apply)</span>` : ""}
21010
+ </div>
21011
+ <pre class="lasso-command-diff-content">${c.operation === "deleted" || c.newString === "" && c.oldString !== "" ? `<span class="lasso-diff-del">- ${escapeHtml4(c.oldString.slice(0, 1e3))}</span>
21012
+ <span class="lasso-diff-del">(file deleted)</span>` : `${c.oldString ? `<span class="lasso-diff-del">- ${escapeHtml4(c.oldString.slice(0, 1e3))}</span>
21013
+ ` : ""}${c.newString ? `<span class="lasso-diff-add">+ ${escapeHtml4(c.newString.slice(0, 1e3))}</span>` : ""}`}</pre>
20960
21014
  </div>
20961
21015
  `
20962
21016
  ).join("")}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lasso-ai/cli",
3
- "version": "2.1.10",
3
+ "version": "2.1.12",
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",