@lasso-ai/cli 2.1.9 → 2.1.11
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.js +5 -3
- package/dist/overlay.js +216 -45
- package/package.json +1 -1
package/dist/cli/bridge.js
CHANGED
|
@@ -523,7 +523,7 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
523
523
|
}
|
|
524
524
|
}
|
|
525
525
|
// Handler for edit/ask - uses runtime
|
|
526
|
-
async function handleHostedConversation(taskId, prompt, model, provider, messages, socket, signal) {
|
|
526
|
+
async function handleHostedConversation(taskId, prompt, model, provider, messages, socket, signal, conversationId) {
|
|
527
527
|
const requestController = new AbortController();
|
|
528
528
|
const abortRequest = () => requestController.abort();
|
|
529
529
|
signal.addEventListener("abort", abortRequest, { once: true });
|
|
@@ -549,6 +549,8 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
549
549
|
prompt,
|
|
550
550
|
model: { id: model, provider },
|
|
551
551
|
messages: Array.isArray(messages) ? messages : undefined,
|
|
552
|
+
conversationId: conversationId || undefined,
|
|
553
|
+
projectId: projectId || undefined,
|
|
552
554
|
}),
|
|
553
555
|
signal: requestController.signal,
|
|
554
556
|
});
|
|
@@ -606,7 +608,7 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
606
608
|
taskControllers.set(taskId, controller);
|
|
607
609
|
const isLocalAgent = ["claude_code", "opencode", "codex_cli", "cursor"].includes(provider || "");
|
|
608
610
|
if ((message.type === "ask" || isConversationalPrompt(instruction)) && !isLocalAgent) {
|
|
609
|
-
await handleHostedConversation(taskId, instruction, model, provider, messages, socket, controller.signal);
|
|
611
|
+
await handleHostedConversation(taskId, instruction, model, provider, messages, socket, controller.signal, message.conversationId);
|
|
610
612
|
return;
|
|
611
613
|
}
|
|
612
614
|
// Do not echo the user's prompt into the thinking feed. The prompt is
|
|
@@ -935,7 +937,7 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
935
937
|
try {
|
|
936
938
|
const isLocalAgent = ["claude_code", "opencode", "codex_cli", "cursor"].includes(provider || "");
|
|
937
939
|
if (isConversationalPrompt(prompt) && !isLocalAgent) {
|
|
938
|
-
await handleHostedConversation(taskId, prompt, model, provider, message.messages, socket, controller.signal);
|
|
940
|
+
await handleHostedConversation(taskId, prompt, model, provider, message.messages, socket, controller.signal, message.conversationId);
|
|
939
941
|
return;
|
|
940
942
|
}
|
|
941
943
|
const backendModelId = (0, backends_1.modelIdForBackend)(model || "", provider || "");
|
package/dist/overlay.js
CHANGED
|
@@ -19679,6 +19679,63 @@
|
|
|
19679
19679
|
return null;
|
|
19680
19680
|
}
|
|
19681
19681
|
}
|
|
19682
|
+
function getStorageProjectKey() {
|
|
19683
|
+
const proj = state.collab?.projectId || state.collabProjectId || "default";
|
|
19684
|
+
return `lasso:sessions:${proj}`;
|
|
19685
|
+
}
|
|
19686
|
+
function saveLocalSession() {
|
|
19687
|
+
try {
|
|
19688
|
+
const projKey = getStorageProjectKey();
|
|
19689
|
+
if (!activeConversationId) {
|
|
19690
|
+
activeConversationId = `local-session-${Date.now()}`;
|
|
19691
|
+
}
|
|
19692
|
+
const sessionData = {
|
|
19693
|
+
id: activeConversationId,
|
|
19694
|
+
messages: commandMessages,
|
|
19695
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19696
|
+
title: commandMessages.find((m) => m.role === "user")?.content?.slice(0, 80) || "Untitled Session"
|
|
19697
|
+
};
|
|
19698
|
+
localStorage.setItem(`lasso:session:${activeConversationId}`, JSON.stringify(sessionData));
|
|
19699
|
+
const listRaw = localStorage.getItem(projKey);
|
|
19700
|
+
let list2 = listRaw ? JSON.parse(listRaw) : [];
|
|
19701
|
+
list2 = list2.filter((item) => item.id !== activeConversationId);
|
|
19702
|
+
list2.unshift({
|
|
19703
|
+
id: activeConversationId,
|
|
19704
|
+
title: sessionData.title,
|
|
19705
|
+
updatedAt: sessionData.updatedAt
|
|
19706
|
+
});
|
|
19707
|
+
localStorage.setItem(projKey, JSON.stringify(list2.slice(0, 30)));
|
|
19708
|
+
} catch (err) {
|
|
19709
|
+
}
|
|
19710
|
+
}
|
|
19711
|
+
function loadLocalSession(convId) {
|
|
19712
|
+
try {
|
|
19713
|
+
const raw = localStorage.getItem(`lasso:session:${convId}`);
|
|
19714
|
+
if (!raw) return false;
|
|
19715
|
+
const session = JSON.parse(raw);
|
|
19716
|
+
if (session && Array.isArray(session.messages)) {
|
|
19717
|
+
commandMessages = session.messages;
|
|
19718
|
+
activeConversationId = convId;
|
|
19719
|
+
renderMessages();
|
|
19720
|
+
scrollToBottom();
|
|
19721
|
+
return true;
|
|
19722
|
+
}
|
|
19723
|
+
} catch {
|
|
19724
|
+
}
|
|
19725
|
+
return false;
|
|
19726
|
+
}
|
|
19727
|
+
function restoreLatestSession() {
|
|
19728
|
+
try {
|
|
19729
|
+
const projKey = getStorageProjectKey();
|
|
19730
|
+
const listRaw = localStorage.getItem(projKey);
|
|
19731
|
+
if (!listRaw) return;
|
|
19732
|
+
const list2 = JSON.parse(listRaw);
|
|
19733
|
+
if (list2 && list2.length > 0 && !activeConversationId) {
|
|
19734
|
+
loadLocalSession(list2[0].id);
|
|
19735
|
+
}
|
|
19736
|
+
} catch {
|
|
19737
|
+
}
|
|
19738
|
+
}
|
|
19682
19739
|
async function createServerConversation(scope2 = "private") {
|
|
19683
19740
|
const projectId = state.collab?.projectId || state.collabProjectId;
|
|
19684
19741
|
if (!projectId) return null;
|
|
@@ -19690,10 +19747,29 @@
|
|
|
19690
19747
|
}
|
|
19691
19748
|
async function loadConversationList() {
|
|
19692
19749
|
const projectId = state.collab?.projectId || state.collabProjectId;
|
|
19750
|
+
try {
|
|
19751
|
+
const projKey = getStorageProjectKey();
|
|
19752
|
+
const listRaw = localStorage.getItem(projKey);
|
|
19753
|
+
if (listRaw) {
|
|
19754
|
+
const localList = JSON.parse(listRaw);
|
|
19755
|
+
conversationList = localList.map((item) => ({
|
|
19756
|
+
id: item.id,
|
|
19757
|
+
title: item.title,
|
|
19758
|
+
scope: "local",
|
|
19759
|
+
updatedAt: item.updatedAt
|
|
19760
|
+
}));
|
|
19761
|
+
}
|
|
19762
|
+
} catch {
|
|
19763
|
+
}
|
|
19693
19764
|
if (!projectId) return;
|
|
19694
19765
|
const data6 = await apiFetch(`/agent/conversations?projectId=${encodeURIComponent(projectId)}`);
|
|
19695
|
-
if (data6?.conversations) {
|
|
19696
|
-
|
|
19766
|
+
if (data6?.conversations && Array.isArray(data6.conversations)) {
|
|
19767
|
+
const serverIds = new Set(data6.conversations.map((c) => c.id));
|
|
19768
|
+
const merged = [
|
|
19769
|
+
...data6.conversations,
|
|
19770
|
+
...conversationList.filter((local) => !serverIds.has(local.id))
|
|
19771
|
+
];
|
|
19772
|
+
conversationList = merged;
|
|
19697
19773
|
}
|
|
19698
19774
|
}
|
|
19699
19775
|
function formatDateAgo(dateStr) {
|
|
@@ -19745,6 +19821,9 @@
|
|
|
19745
19821
|
activeConversationId = convId;
|
|
19746
19822
|
if (commandHistoryPopover) commandHistoryPopover.hidden = true;
|
|
19747
19823
|
commandHistoryBtn?.classList.remove("active");
|
|
19824
|
+
if (loadLocalSession(convId)) {
|
|
19825
|
+
return;
|
|
19826
|
+
}
|
|
19748
19827
|
const data6 = await apiFetch(`/agent/conversations/${convId}`);
|
|
19749
19828
|
if (data6?.conversation?.messages && Array.isArray(data6.conversation.messages)) {
|
|
19750
19829
|
commandMessages = data6.conversation.messages.map((m, idx) => ({
|
|
@@ -19762,6 +19841,7 @@
|
|
|
19762
19841
|
changesApplied: m.changesApplied,
|
|
19763
19842
|
error: m.error
|
|
19764
19843
|
}));
|
|
19844
|
+
saveLocalSession();
|
|
19765
19845
|
} else {
|
|
19766
19846
|
commandMessages = [];
|
|
19767
19847
|
}
|
|
@@ -20214,6 +20294,36 @@
|
|
|
20214
20294
|
}
|
|
20215
20295
|
return;
|
|
20216
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
|
+
}
|
|
20217
20327
|
const diffToggle = target.closest(".lasso-command-toggle-diff");
|
|
20218
20328
|
if (diffToggle) {
|
|
20219
20329
|
const msgId = diffToggle.closest(".lasso-command-msg")?.dataset.msgId;
|
|
@@ -20229,6 +20339,12 @@
|
|
|
20229
20339
|
const msgId = applyBtn.closest(".lasso-command-msg")?.dataset.msgId;
|
|
20230
20340
|
const msg = commandMessages.find((m) => m.id === msgId);
|
|
20231
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
|
+
}
|
|
20232
20348
|
applyBtn.disabled = true;
|
|
20233
20349
|
applyBtn.textContent = "Applying\u2026";
|
|
20234
20350
|
state.runtimeErrors = [];
|
|
@@ -20236,7 +20352,7 @@
|
|
|
20236
20352
|
JSON.stringify({
|
|
20237
20353
|
type: "apply",
|
|
20238
20354
|
taskId: msg.id,
|
|
20239
|
-
changes:
|
|
20355
|
+
changes: approvedChanges
|
|
20240
20356
|
})
|
|
20241
20357
|
);
|
|
20242
20358
|
}
|
|
@@ -20258,6 +20374,12 @@
|
|
|
20258
20374
|
}
|
|
20259
20375
|
return;
|
|
20260
20376
|
}
|
|
20377
|
+
const continueBtn = target.closest(".lasso-command-continue-btn");
|
|
20378
|
+
if (continueBtn) {
|
|
20379
|
+
const msgId = continueBtn.closest(".lasso-command-msg")?.dataset.msgId;
|
|
20380
|
+
continueWithThoughts(msgId);
|
|
20381
|
+
return;
|
|
20382
|
+
}
|
|
20261
20383
|
const retryBtn = target.closest(".lasso-command-retry-btn");
|
|
20262
20384
|
if (retryBtn) {
|
|
20263
20385
|
const msgId = retryBtn.closest(".lasso-command-msg")?.dataset.msgId;
|
|
@@ -20289,6 +20411,9 @@
|
|
|
20289
20411
|
updateEmptyStateUserName();
|
|
20290
20412
|
renderSuggestions();
|
|
20291
20413
|
populateModelMenu();
|
|
20414
|
+
if (commandMessages.length === 0) {
|
|
20415
|
+
restoreLatestSession();
|
|
20416
|
+
}
|
|
20292
20417
|
renderMessages();
|
|
20293
20418
|
loadConversationList();
|
|
20294
20419
|
}
|
|
@@ -20359,6 +20484,24 @@
|
|
|
20359
20484
|
commandMessages.splice(failedIndex, 1);
|
|
20360
20485
|
void runPrompt(promptToRetry, true);
|
|
20361
20486
|
}
|
|
20487
|
+
function continueWithThoughts(msgId) {
|
|
20488
|
+
if (activeTaskId) return;
|
|
20489
|
+
const targetMsg = msgId ? commandMessages.find((m) => m.id === msgId) : [...commandMessages].reverse().find((m) => m.role === "assistant");
|
|
20490
|
+
if (!targetMsg) return;
|
|
20491
|
+
const targetIndex = commandMessages.indexOf(targetMsg);
|
|
20492
|
+
const precedingUserMsg = [...commandMessages].slice(0, targetIndex).reverse().find((m) => m.role === "user");
|
|
20493
|
+
const originalPrompt = precedingUserMsg?.content || "";
|
|
20494
|
+
const thoughtSummary = (targetMsg.thinking?.steps || []).map((s) => `- ${s.title}${s.detail ? `: ${s.detail}` : ""}`).join("\n");
|
|
20495
|
+
const continuationPrompt = thoughtSummary ? `Continue executing the previous task: "${originalPrompt}".
|
|
20496
|
+
|
|
20497
|
+
Here is your prior analysis and plan:
|
|
20498
|
+
${thoughtSummary}
|
|
20499
|
+
|
|
20500
|
+
Please proceed directly with the implementation and code changes from this point.` : originalPrompt;
|
|
20501
|
+
targetMsg.error = void 0;
|
|
20502
|
+
saveLocalSession();
|
|
20503
|
+
void runPrompt(continuationPrompt);
|
|
20504
|
+
}
|
|
20362
20505
|
async function handleSubmit() {
|
|
20363
20506
|
if (!commandInput) return;
|
|
20364
20507
|
if (activeTaskId) {
|
|
@@ -20539,26 +20682,22 @@
|
|
|
20539
20682
|
}
|
|
20540
20683
|
const hasChanges = Array.isArray(message.changes) && message.changes.length > 0;
|
|
20541
20684
|
if (targetMsg.thinking) {
|
|
20542
|
-
|
|
20543
|
-
|
|
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));
|
|
20544
20692
|
} else {
|
|
20545
|
-
|
|
20546
|
-
|
|
20547
|
-
|
|
20548
|
-
targetMsg.thinking.
|
|
20549
|
-
|
|
20550
|
-
|
|
20551
|
-
|
|
20552
|
-
}
|
|
20553
|
-
targetMsg.thinking.durationSeconds = Math.max(1, Math.round((Date.now() - activeStartTime) / 1e3));
|
|
20554
|
-
}
|
|
20555
|
-
if (Array.isArray(message.thinking) && message.thinking.length) {
|
|
20556
|
-
targetMsg.thinking.steps = message.thinking.map((s) => ({
|
|
20557
|
-
title: s.title || "Completed step",
|
|
20558
|
-
detail: s.detail,
|
|
20559
|
-
status: "completed"
|
|
20560
|
-
}));
|
|
20561
|
-
}
|
|
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
|
+
}));
|
|
20562
20701
|
}
|
|
20563
20702
|
}
|
|
20564
20703
|
targetMsg.content = message.message || "";
|
|
@@ -20590,6 +20729,7 @@
|
|
|
20590
20729
|
});
|
|
20591
20730
|
}
|
|
20592
20731
|
}
|
|
20732
|
+
saveLocalSession();
|
|
20593
20733
|
renderMessages();
|
|
20594
20734
|
scrollToBottom();
|
|
20595
20735
|
} else if (message.status === "error" || message.status === "stopped") {
|
|
@@ -20610,6 +20750,7 @@
|
|
|
20610
20750
|
sessionId: state.collabProjectId,
|
|
20611
20751
|
status: "idle"
|
|
20612
20752
|
});
|
|
20753
|
+
saveLocalSession();
|
|
20613
20754
|
renderMessages();
|
|
20614
20755
|
scrollToBottom();
|
|
20615
20756
|
}
|
|
@@ -20639,7 +20780,13 @@
|
|
|
20639
20780
|
clearInterval(activeThinkingInterval);
|
|
20640
20781
|
activeThinkingInterval = null;
|
|
20641
20782
|
}
|
|
20642
|
-
targetMsg.thinking
|
|
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
|
+
}
|
|
20643
20790
|
const question = message.prompt?.question || message.message || "";
|
|
20644
20791
|
targetMsg.content = question;
|
|
20645
20792
|
targetMsg.isStreaming = false;
|
|
@@ -20688,10 +20835,18 @@
|
|
|
20688
20835
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
|
|
20689
20836
|
${escapeHtml4(msg.error)}
|
|
20690
20837
|
</div>
|
|
20691
|
-
<
|
|
20692
|
-
|
|
20693
|
-
|
|
20694
|
-
|
|
20838
|
+
<div class="lasso-command-error-actions" style="display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap;">
|
|
20839
|
+
${msg.thinking && msg.thinking.steps.length > 0 ? `
|
|
20840
|
+
<button class="lasso-command-continue-btn" type="button" title="Continue execution using the thoughts and analysis generated so far" style="display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; font-size: 12px; font-weight: 500; border-radius: 6px; background: rgba(59, 130, 246, 0.15); border: 1px solid rgba(59, 130, 246, 0.3); color: #93c5fd; cursor: pointer;">
|
|
20841
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
|
20842
|
+
Continue with thoughts so far
|
|
20843
|
+
</button>
|
|
20844
|
+
` : ""}
|
|
20845
|
+
<button class="lasso-command-retry-btn" type="button" title="Retry from start" style="display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; font-size: 12px; font-weight: 500; border-radius: 6px; background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.15); color: #e2e8f0; cursor: pointer;">
|
|
20846
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>
|
|
20847
|
+
Retry
|
|
20848
|
+
</button>
|
|
20849
|
+
</div>
|
|
20695
20850
|
` : ""}
|
|
20696
20851
|
</div>
|
|
20697
20852
|
`;
|
|
@@ -20766,7 +20921,9 @@
|
|
|
20766
20921
|
const changes = msg.changes;
|
|
20767
20922
|
const isApplied = msg.changesApplied;
|
|
20768
20923
|
const isUndone = msg.changesUndone;
|
|
20769
|
-
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;
|
|
20770
20927
|
const scopeHtml = msg.todo && msg.todo.length ? `
|
|
20771
20928
|
<div class="lasso-command-scope-list">
|
|
20772
20929
|
${msg.todo.map((item) => `
|
|
@@ -20778,34 +20935,43 @@
|
|
|
20778
20935
|
`).join("")}
|
|
20779
20936
|
</div>
|
|
20780
20937
|
` : "";
|
|
20938
|
+
const approvedCount = changes.length - rejected.size;
|
|
20781
20939
|
return `
|
|
20782
20940
|
<div class="lasso-command-changes-card">
|
|
20783
20941
|
<div class="lasso-command-changes-header">
|
|
20784
20942
|
<div class="lasso-command-changes-title">
|
|
20785
|
-
<svg width="
|
|
20943
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
20786
20944
|
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
20787
20945
|
<polyline points="14 2 14 8 20 8"/>
|
|
20788
20946
|
</svg>
|
|
20789
|
-
<span
|
|
20947
|
+
<span>Proposed changes (${approvedCount}/${changes.length} files selected)</span>
|
|
20790
20948
|
</div>
|
|
20791
20949
|
<button class="lasso-command-toggle-diff" type="button">
|
|
20792
|
-
${showDiff ? "Hide
|
|
20950
|
+
${showDiff ? "Hide diffs" : "Inspect diffs"}
|
|
20793
20951
|
</button>
|
|
20794
20952
|
</div>
|
|
20795
20953
|
${scopeHtml}
|
|
20796
20954
|
|
|
20797
20955
|
<div class="lasso-command-files-list">
|
|
20798
|
-
${changes.map(
|
|
20799
|
-
(c)
|
|
20800
|
-
|
|
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>
|
|
20801
20964
|
<span class="lasso-command-file-badge ${c.oldString ? "modified" : "added"}">${c.oldString ? "M" : "+"}</span>
|
|
20802
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>
|
|
20803
20969
|
</div>
|
|
20804
|
-
|
|
20805
|
-
).join("")}
|
|
20970
|
+
`;
|
|
20971
|
+
}).join("")}
|
|
20806
20972
|
</div>
|
|
20807
20973
|
|
|
20808
|
-
${showDiff ? renderDiffPreview(changes) : ""}
|
|
20974
|
+
${showDiff ? renderDiffPreview(changes, activeFile, rejected) : ""}
|
|
20809
20975
|
|
|
20810
20976
|
<div class="lasso-command-changes-footer">
|
|
20811
20977
|
${isApplied ? `
|
|
@@ -20821,7 +20987,7 @@
|
|
|
20821
20987
|
<button class="lasso-command-apply-btn primary" type="button">Re-apply</button>
|
|
20822
20988
|
` : `
|
|
20823
20989
|
<button class="lasso-command-apply-btn primary" type="button">
|
|
20824
|
-
<span>Keep
|
|
20990
|
+
<span>Keep Selected (${approvedCount})</span>
|
|
20825
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>
|
|
20826
20992
|
</button>
|
|
20827
20993
|
<button class="lasso-command-undo-btn secondary" type="button">Discard</button>
|
|
@@ -20830,16 +20996,21 @@
|
|
|
20830
20996
|
</div>
|
|
20831
20997
|
`;
|
|
20832
20998
|
}
|
|
20833
|
-
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;
|
|
20834
21002
|
return `
|
|
20835
21003
|
<div class="lasso-command-diff-container">
|
|
20836
|
-
${
|
|
21004
|
+
${listToRender.map(
|
|
20837
21005
|
(c) => `
|
|
20838
|
-
<div class="lasso-command-diff-file">
|
|
20839
|
-
<div class="lasso-command-diff-file-header"
|
|
20840
|
-
|
|
20841
|
-
|
|
20842
|
-
|
|
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>
|
|
20843
21014
|
</div>
|
|
20844
21015
|
`
|
|
20845
21016
|
).join("")}
|
package/package.json
CHANGED