@lasso-ai/cli 1.0.15 → 1.0.16

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/agent.js CHANGED
@@ -314,7 +314,7 @@ function localCommand(provider, model, prompt) {
314
314
  return { command: "codex", args: ["exec", "--json", "--sandbox", "read-only", "--skip-git-repo-check", ...(selectedModel ? ["--model", selectedModel] : []), prompt || ""] };
315
315
  }
316
316
  async function proposeWithLocalAgent(cwd, instruction, context, config, signal, onProgress) {
317
- const outputContract = `Return ONLY valid JSON in this exact shape: {"summary":"short explanation","changes":[{"filePath":"relative/path","oldString":"exact existing text","newString":"replacement text"}]}. Every oldString must occur exactly once. Do not edit files, run write commands, commit, or produce markdown fences.`;
317
+ const outputContract = `Return ONLY valid JSON in this exact shape: {"summary":"short explanation","changes":[{"filePath":"relative/path","oldString":"exact existing text","newString":"replacement text"}]}. Treat the supplied source context as read-only. Before returning, verify every oldString against that context. Use project-relative paths only. Do not edit files, run write commands, commit, or produce markdown fences.`;
318
318
  const prompt = `${instruction}\n\n${outputContract}\n\nLasso has already assembled this source context:\n${context || "No matching source context was found."}`;
319
319
  const local = localCommand(config.provider, config.model, prompt);
320
320
  const command = local.command;
@@ -136,6 +136,9 @@ function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort = expo
136
136
  const wss = new ws_1.WebSocketServer({ server: bridgeServer });
137
137
  let overlaySocket = null;
138
138
  let lastSnapshot = [];
139
+ let lastEditRequest = null;
140
+ let lastEditConfig = null;
141
+ let reviewRefreshAttempts = 0;
139
142
  const envRoots = [cwd, node_path_1.default.join(cwd, "web"), node_path_1.default.join(cwd, "server")];
140
143
  const fileEnv = envRoots.reduce((values, root) => ({
141
144
  ...values,
@@ -310,6 +313,9 @@ function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort = expo
310
313
  const selectedConfig = localProvider
311
314
  ? { provider: cliProvider, model: msg.model }
312
315
  : { ...agentConfig, provider: (msg.provider || agentConfig.provider), model: msg.model };
316
+ lastEditRequest = msg;
317
+ lastEditConfig = selectedConfig;
318
+ reviewRefreshAttempts = 0;
313
319
  void (0, agent_1.proposeChanges)(cwd, msg, selectedConfig, controller.signal, (message, detail) => {
314
320
  if (!controller.signal.aborted && socket.readyState === socket.OPEN) {
315
321
  socket.send(JSON.stringify({ type: "agent_status", status: "working", message, detail }));
@@ -463,7 +469,37 @@ function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort = expo
463
469
  for (const snapshot of lastSnapshot)
464
470
  node_fs_1.default.writeFileSync(snapshot.filePath, snapshot.content);
465
471
  lastSnapshot = [];
466
- socket.send(JSON.stringify({ type: "agent_status", status: "error", message: error instanceof Error ? error.message : "The change could not be applied." }));
472
+ const message = error instanceof Error ? error.message : "The change could not be applied.";
473
+ const sourceChanged = message.includes("The source changed after the suggestion was generated");
474
+ if (sourceChanged && lastEditRequest && lastEditConfig && reviewRefreshAttempts < 1) {
475
+ reviewRefreshAttempts += 1;
476
+ socket.send(JSON.stringify({ type: "agent_status", status: "working", message: "The source changed. Refreshing the review against the current file…" }));
477
+ activeAgentController?.abort();
478
+ const controller = new AbortController();
479
+ activeAgentController = controller;
480
+ void (0, agent_1.proposeChanges)(cwd, lastEditRequest, lastEditConfig, controller.signal, (progress, detail) => {
481
+ if (!controller.signal.aborted && socket.readyState === socket.OPEN) {
482
+ socket.send(JSON.stringify({ type: "agent_status", status: "working", message: progress, detail }));
483
+ }
484
+ })
485
+ .then((proposal) => {
486
+ if (!controller.signal.aborted && socket.readyState === socket.OPEN) {
487
+ socket.send(JSON.stringify({ type: "agent_status", status: "review", message: `Review refreshed: ${proposal.summary}`, changes: proposal.changes }));
488
+ }
489
+ })
490
+ .catch((refreshError) => {
491
+ if (!controller.signal.aborted && socket.readyState === socket.OPEN) {
492
+ socket.send(JSON.stringify({ type: "agent_status", status: "error", message: refreshError instanceof Error ? refreshError.message : "The refreshed review could not be prepared." }));
493
+ }
494
+ })
495
+ .finally(() => {
496
+ if (activeAgentController === controller)
497
+ activeAgentController = null;
498
+ });
499
+ }
500
+ else {
501
+ socket.send(JSON.stringify({ type: "agent_status", status: "error", message }));
502
+ }
467
503
  }
468
504
  }
469
505
  else if (msg.type === "undo") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lasso-ai/cli",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
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",