@lasso-ai/cli 2.1.7 → 2.1.9

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.
@@ -22,6 +22,37 @@ const backends_1 = require("./backends");
22
22
  const local_runtime_1 = require("./local-runtime");
23
23
  exports.DEFAULT_BRIDGE_PORT = 3056;
24
24
  const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
25
+ function isConversationalPrompt(prompt) {
26
+ const p = prompt.trim().toLowerCase().replace(/[!?.,;:]+$/, "");
27
+ // 1. Direct greetings and conversational niceties
28
+ const greetings = [
29
+ "hi", "hello", "hey", "heya", "howdy", "sup", "yo",
30
+ "good morning", "good afternoon", "good evening",
31
+ "thanks", "thank you", "thx", "ty", "cool", "awesome", "great", "nice",
32
+ "who are you", "what are you", "what can you do", "help", "help me",
33
+ "what is lasso", "how do you work", "how does this work",
34
+ ];
35
+ if (greetings.includes(p))
36
+ return true;
37
+ // Short greetings
38
+ if (/^(hi|hello|hey|howdy|yo)\b/i.test(p) && p.split(/\s+/).length <= 4) {
39
+ const buildKeywords = /\b(build|create|add|make|fix|update|modify|change|refactor|implement|delete|remove|style|install|wire|code)\b/i;
40
+ if (!buildKeywords.test(p))
41
+ return true;
42
+ }
43
+ // 2. Action verbs indicating deliberate code changes
44
+ const mutationVerbs = /\b(build|create|add|make|fix|update|modify|change|refactor|implement|delete|remove|style|install|wire|code|replace|set|switch|swap|rewrite|restyle|rebuild|apply)\b/i;
45
+ // 3. Question / informational prefixes
46
+ const infoPrefixes = /^(what|how|why|when|where|who|which|can you explain|explain|describe|tell me|check out|check|look at|summarize|give me an overview|overview|inspect)\b/i;
47
+ if (infoPrefixes.test(p) && !mutationVerbs.test(p)) {
48
+ return true;
49
+ }
50
+ // 4. Questions about the project / app / page without mutation verbs
51
+ if (/\b(about|doing|does this|is this|mean|purpose|work|repo|project|codebase|app|application|page|overview|summary)\b/i.test(p) && !mutationVerbs.test(p)) {
52
+ return true;
53
+ }
54
+ return false;
55
+ }
25
56
  function cleanConversationReply(value) {
26
57
  const text = typeof value === "string" ? value.trim() : "";
27
58
  if (!text)
@@ -463,11 +494,18 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
463
494
  return { filePath: change.filePath, content };
464
495
  }));
465
496
  (0, snapshot_1.createSnapshot)(cwd, taskId, instruction, changes.map((change) => change.filePath), undefined, session.id);
497
+ // Extract the assistant's reply from the session conversation so the user
498
+ // sees both the explanation and the review panel — not just "Review changes".
499
+ const sessionConvo = finalSession.conversation || [];
500
+ const assistantReply = [...sessionConvo]
501
+ .reverse()
502
+ .find((m) => m?.role === "assistant" && typeof m.content === "string")
503
+ ?.content?.trim();
466
504
  socket.send(JSON.stringify({
467
505
  type: "agent_status",
468
506
  taskId,
469
507
  status: "review",
470
- message: "Review changes",
508
+ message: assistantReply || "Review changes",
471
509
  changes,
472
510
  }));
473
511
  }
@@ -567,7 +605,7 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
567
605
  const controller = new AbortController();
568
606
  taskControllers.set(taskId, controller);
569
607
  const isLocalAgent = ["claude_code", "opencode", "codex_cli", "cursor"].includes(provider || "");
570
- if (message.type === "ask" && !isLocalAgent) {
608
+ if ((message.type === "ask" || isConversationalPrompt(instruction)) && !isLocalAgent) {
571
609
  await handleHostedConversation(taskId, instruction, model, provider, messages, socket, controller.signal);
572
610
  return;
573
611
  }
@@ -896,6 +934,10 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
896
934
  // there are no canned assistant responses in the bridge.
897
935
  try {
898
936
  const isLocalAgent = ["claude_code", "opencode", "codex_cli", "cursor"].includes(provider || "");
937
+ if (isConversationalPrompt(prompt) && !isLocalAgent) {
938
+ await handleHostedConversation(taskId, prompt, model, provider, message.messages, socket, controller.signal);
939
+ return;
940
+ }
899
941
  const backendModelId = (0, backends_1.modelIdForBackend)(model || "", provider || "");
900
942
  const sessionInput = {
901
943
  userPrompt: prompt,
package/dist/overlay.js CHANGED
@@ -19632,12 +19632,15 @@
19632
19632
  ];
19633
19633
  if (greetings.includes(p)) return true;
19634
19634
  if (/^(hi|hello|hey|howdy|yo)\b/i.test(p) && p.split(/\s+/).length <= 4) {
19635
- const buildKeywords = /(build|create|add|make|fix|update|modify|change|refactor|implement|delete|remove|style|install|wire|code)/i;
19635
+ const buildKeywords = /\b(build|create|add|make|fix|update|modify|change|refactor|implement|delete|remove|style|install|wire|code)\b/i;
19636
19636
  if (!buildKeywords.test(p)) return true;
19637
19637
  }
19638
- const questionOnly = /^(what is|what's|how do i|why does|can you explain|tell me about)\b/i.test(p);
19639
- const actionVerbs = /(build|create|add|make|fix|update|modify|change|refactor|implement|write code|code this|delete|remove|generate)/i;
19640
- if (questionOnly && !actionVerbs.test(p)) {
19638
+ const mutationVerbs = /\b(build|create|add|make|fix|update|modify|change|refactor|implement|delete|remove|style|install|wire|code|replace|set|switch|swap|rewrite|restyle|rebuild|apply)\b/i;
19639
+ const infoPrefixes = /^(what|how|why|when|where|who|which|can you explain|explain|describe|tell me|check out|check|look at|summarize|give me an overview|overview|inspect)\b/i;
19640
+ if (infoPrefixes.test(p) && !mutationVerbs.test(p)) {
19641
+ return true;
19642
+ }
19643
+ if (/\b(about|doing|does this|is this|mean|purpose|work|repo|project|codebase|app|application|page|overview|summary)\b/i.test(p) && !mutationVerbs.test(p)) {
19641
19644
  return true;
19642
19645
  }
19643
19646
  return false;
@@ -49,6 +49,15 @@ const DEFAULT_IGNORE_DIRS = new Set([
49
49
  ".gradle",
50
50
  ".terraform",
51
51
  ]);
52
+ const DEFAULT_IGNORE_FILES = new Set([
53
+ "next-env.d.ts",
54
+ "tsconfig.tsbuildinfo",
55
+ ".DS_Store",
56
+ "Thumbs.db",
57
+ ]);
58
+ function shouldIgnoreFile(name) {
59
+ return DEFAULT_IGNORE_FILES.has(name) || name.endsWith(".tsbuildinfo");
60
+ }
52
61
  function hashBuffer(buf) {
53
62
  return node_crypto_1.default.createHash("sha256").update(buf).digest("hex");
54
63
  }
@@ -110,8 +119,9 @@ class WorkspaceGuard {
110
119
  walk(absPath, relPath, depth + 1);
111
120
  continue;
112
121
  }
113
- if (!entry.isFile()) {
114
- guard.skipped.push(relPath);
122
+ if (!entry.isFile() || shouldIgnoreFile(entry.name)) {
123
+ if (!entry.isFile())
124
+ guard.skipped.push(relPath);
115
125
  continue;
116
126
  }
117
127
  try {
@@ -278,7 +288,7 @@ class WorkspaceGuard {
278
288
  walk(absPath, relPath, depth + 1);
279
289
  continue;
280
290
  }
281
- if (!entry.isFile())
291
+ if (!entry.isFile() || shouldIgnoreFile(entry.name))
282
292
  continue;
283
293
  if (this.ignoreFn && this.ignoreFn(relPath, false))
284
294
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lasso-ai/cli",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
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",