snow-ai 0.5.12 → 0.5.14

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/bundle/cli.mjs CHANGED
@@ -353011,10 +353011,11 @@ var init_bash = __esm({
353011
353011
  * Execute a terminal command in the working directory
353012
353012
  * @param command - The command to execute (e.g., "npm -v", "git status")
353013
353013
  * @param timeout - Timeout in milliseconds (default: 30000ms = 30s)
353014
+ * @param abortSignal - Optional AbortSignal to cancel command execution (e.g., ESC key)
353014
353015
  * @returns Execution result including stdout, stderr, and exit code
353015
353016
  * @throws Error if command execution fails critically
353016
353017
  */
353017
- async executeCommand(command, timeout2 = 3e4) {
353018
+ async executeCommand(command, timeout2 = 3e4, abortSignal) {
353018
353019
  const executedAt = (/* @__PURE__ */ new Date()).toISOString();
353019
353020
  try {
353020
353021
  if (isDangerousCommand(command)) {
@@ -353033,6 +353034,24 @@ var init_bash = __esm({
353033
353034
  }
353034
353035
  });
353035
353036
  processManager.register(childProcess2);
353037
+ let abortHandler;
353038
+ if (abortSignal) {
353039
+ abortHandler = () => {
353040
+ if (childProcess2.pid && !childProcess2.killed) {
353041
+ try {
353042
+ if (process.platform === "win32") {
353043
+ exec4(`taskkill /PID ${childProcess2.pid} /T /F 2>NUL`, {
353044
+ windowsHide: true
353045
+ });
353046
+ } else {
353047
+ childProcess2.kill("SIGTERM");
353048
+ }
353049
+ } catch {
353050
+ }
353051
+ }
353052
+ };
353053
+ abortSignal.addEventListener("abort", abortHandler);
353054
+ }
353036
353055
  const { stdout, stderr } = await new Promise((resolve10, reject2) => {
353037
353056
  var _a21, _b14;
353038
353057
  let stdoutData = "";
@@ -353045,6 +353064,9 @@ var init_bash = __esm({
353045
353064
  });
353046
353065
  childProcess2.on("error", reject2);
353047
353066
  childProcess2.on("close", (code2, signal) => {
353067
+ if (abortHandler && abortSignal) {
353068
+ abortSignal.removeEventListener("abort", abortHandler);
353069
+ }
353048
353070
  if (signal) {
353049
353071
  const error = new Error(`Process killed by signal ${signal}`);
353050
353072
  error.code = code2 || 1;
@@ -353074,6 +353096,16 @@ var init_bash = __esm({
353074
353096
  if (error.code === "ETIMEDOUT") {
353075
353097
  throw new Error(`Command timed out after ${timeout2}ms: ${command}`);
353076
353098
  }
353099
+ if (abortSignal == null ? void 0 : abortSignal.aborted) {
353100
+ return {
353101
+ stdout: truncateOutput(error.stdout || "", this.maxOutputLength),
353102
+ stderr: truncateOutput(error.stderr || "Command execution interrupted by user (ESC key pressed)", this.maxOutputLength),
353103
+ exitCode: 130,
353104
+ // Standard exit code for SIGINT/user interrupt
353105
+ command,
353106
+ executedAt
353107
+ };
353108
+ }
353077
353109
  return {
353078
353110
  stdout: truncateOutput(error.stdout || "", this.maxOutputLength),
353079
353111
  stderr: truncateOutput(error.stderr || error.message || "", this.maxOutputLength),
@@ -439049,7 +439081,7 @@ AI Tip: Provide searchContent (string) and replaceContent (string).`);
439049
439081
  timeout: args2.timeout || 3e4
439050
439082
  });
439051
439083
  try {
439052
- result2 = await terminalService2.executeCommand(args2.command, args2.timeout);
439084
+ result2 = await terminalService2.executeCommand(args2.command, args2.timeout, abortSignal);
439053
439085
  } finally {
439054
439086
  setTerminalExecutionState2({
439055
439087
  isExecuting: false,
@@ -446229,7 +446261,9 @@ function useKeyboardInput(options3) {
446229
446261
  executeCommand(selectedCommand.name).then((result2) => {
446230
446262
  commandUsageManager.recordUsage(selectedCommand.name);
446231
446263
  if (onCommand) {
446232
- onCommand(selectedCommand.name, result2);
446264
+ Promise.resolve(onCommand(selectedCommand.name, result2)).catch((error) => {
446265
+ console.error("Command execution error:", error);
446266
+ });
446233
446267
  }
446234
446268
  });
446235
446269
  buffer.setText("");
@@ -446281,7 +446315,9 @@ function useKeyboardInput(options3) {
446281
446315
  executeCommand(commandName, commandArgs).then((result2) => {
446282
446316
  commandUsageManager.recordUsage(commandName);
446283
446317
  if (onCommand) {
446284
- onCommand(commandName, result2);
446318
+ Promise.resolve(onCommand(commandName, result2)).catch((error) => {
446319
+ console.error("Command execution error:", error);
446320
+ });
446285
446321
  }
446286
446322
  });
446287
446323
  buffer.setText("");
@@ -527768,6 +527804,23 @@ function extractMultimodalContent(result2) {
527768
527804
  async function executeToolCall(toolCall, abortSignal, onTokenUpdate, onSubAgentMessage, requestToolConfirmation, isToolAutoApproved, yoloMode, addToAlwaysApproved, onUserInteractionNeeded) {
527769
527805
  let result2;
527770
527806
  let executionError = null;
527807
+ let escKeyListener;
527808
+ let abortController;
527809
+ if (toolCall.function.name === "terminal-execute" && !abortSignal) {
527810
+ abortController = new AbortController();
527811
+ abortSignal = abortController.signal;
527812
+ escKeyListener = (data) => {
527813
+ const str2 = data.toString();
527814
+ if (str2 === "\x1B" && abortController && !(abortSignal == null ? void 0 : abortSignal.aborted)) {
527815
+ console.log("\n[ESC] Interrupting command execution...");
527816
+ abortController.abort();
527817
+ }
527818
+ };
527819
+ if (process.stdin.isTTY && process.stdin.setRawMode) {
527820
+ process.stdin.setRawMode(true);
527821
+ process.stdin.on("data", escKeyListener);
527822
+ }
527823
+ }
527771
527824
  try {
527772
527825
  const args2 = JSON.parse(toolCall.function.arguments);
527773
527826
  try {
@@ -527915,6 +527968,12 @@ ${combinedOutput}`;
527915
527968
  console.warn("Failed to execute afterToolCall hook:", error);
527916
527969
  }
527917
527970
  }
527971
+ if (escKeyListener) {
527972
+ if (process.stdin.isTTY && process.stdin.setRawMode) {
527973
+ process.stdin.setRawMode(false);
527974
+ process.stdin.off("data", escKeyListener);
527975
+ }
527976
+ }
527918
527977
  return result2;
527919
527978
  }
527920
527979
  function getToolResourceType(toolName) {
@@ -528783,33 +528842,46 @@ async function executeContextCompression(sessionId) {
528783
528842
  };
528784
528843
  }
528785
528844
  const newSessionMessages = [];
528786
- newSessionMessages.push({
528787
- role: "user",
528788
- content: `[Context Summary from Previous Conversation]
528845
+ let finalContent = `[Context Summary from Previous Conversation]
528789
528846
 
528790
- ${compressionResult.summary}`,
528791
- timestamp: Date.now()
528792
- });
528847
+ ${compressionResult.summary}`;
528793
528848
  if (compressionResult.preservedMessages && compressionResult.preservedMessages.length > 0) {
528849
+ finalContent += "\n\n---\n\n[Last Interaction - Preserved for Continuity]\n\n";
528794
528850
  for (const msg of compressionResult.preservedMessages) {
528795
- newSessionMessages.push({
528796
- role: msg.role,
528797
- content: msg.content,
528798
- timestamp: Date.now(),
528799
- ...msg.tool_call_id !== void 0 && {
528800
- tool_call_id: msg.tool_call_id
528801
- },
528802
- ...msg.tool_calls !== void 0 && { tool_calls: msg.tool_calls },
528803
- ...msg.images !== void 0 && { images: msg.images },
528804
- ...msg.reasoning !== void 0 && { reasoning: msg.reasoning },
528805
- ...msg.thinking !== void 0 && { thinking: msg.thinking },
528806
- // 保留 thinking 字段(Anthropic Extended Thinking)
528807
- ...msg.subAgentInternal !== void 0 && {
528808
- subAgentInternal: msg.subAgentInternal
528851
+ if (msg.role === "user") {
528852
+ finalContent += `**User:**
528853
+ ${msg.content}
528854
+
528855
+ `;
528856
+ } else if (msg.role === "assistant") {
528857
+ finalContent += `**Assistant:**
528858
+ ${msg.content}`;
528859
+ if (msg.tool_calls && msg.tool_calls.length > 0) {
528860
+ finalContent += "\n\n**[Tool Calls Initiated]:**\n```json\n";
528861
+ finalContent += JSON.stringify(msg.tool_calls, null, 2);
528862
+ finalContent += "\n```\n\n";
528863
+ } else {
528864
+ finalContent += "\n\n";
528809
528865
  }
528810
- });
528866
+ } else if (msg.role === "tool") {
528867
+ finalContent += `**[Tool Result - ${msg.tool_call_id}]:**
528868
+ `;
528869
+ try {
528870
+ const parsed = JSON.parse(msg.content);
528871
+ finalContent += "```json\n" + JSON.stringify(parsed, null, 2) + "\n```\n\n";
528872
+ } catch {
528873
+ finalContent += `${msg.content}
528874
+
528875
+ `;
528876
+ }
528877
+ }
528811
528878
  }
528812
528879
  }
528880
+ newSessionMessages.push({
528881
+ role: "user",
528882
+ content: finalContent,
528883
+ timestamp: Date.now()
528884
+ });
528813
528885
  const compressedSession = await sessionManager.createNewSession(false);
528814
528886
  compressedSession.messages = newSessionMessages;
528815
528887
  compressedSession.messageCount = newSessionMessages.length;
@@ -528864,6 +528936,7 @@ function useCommandHandler(options3) {
528864
528936
  const { stdout } = use_stdout_default();
528865
528937
  const handleCommandExecution = (0, import_react121.useCallback)(async (commandName, result2) => {
528866
528938
  if (commandName === "compact" && result2.success && result2.action === "compact") {
528939
+ console.log("[Compact] Starting compression, setting isCompressing=true");
528867
528940
  options3.setIsCompressing(true);
528868
528941
  options3.setCompressionError(null);
528869
528942
  try {
@@ -528871,16 +528944,19 @@ function useCommandHandler(options3) {
528871
528944
  if (!currentSession) {
528872
528945
  throw new Error("No active session to compress");
528873
528946
  }
528947
+ console.log("[Compact] Executing compression for session:", currentSession.id);
528874
528948
  const compressionResult = await executeContextCompression(currentSession.id);
528875
528949
  if (!compressionResult) {
528876
528950
  throw new Error("Compression failed");
528877
528951
  }
528952
+ console.log("[Compact] Compression completed successfully");
528878
528953
  options3.clearSavedMessages();
528879
528954
  options3.setMessages(compressionResult.uiMessages);
528880
528955
  options3.setRemountKey((prev) => prev + 1);
528881
528956
  options3.setContextUsage(compressionResult.usage);
528882
528957
  } catch (error) {
528883
528958
  const errorMsg = error instanceof Error ? error.message : "Unknown compression error";
528959
+ console.error("[Compact] Compression error:", errorMsg);
528884
528960
  options3.setCompressionError(errorMsg);
528885
528961
  const errorMessage = {
528886
528962
  role: "assistant",
@@ -528891,6 +528967,7 @@ ${errorMsg}`,
528891
528967
  };
528892
528968
  options3.setMessages((prev) => [...prev, errorMessage]);
528893
528969
  } finally {
528970
+ console.log("[Compact] Setting isCompressing=false");
528894
528971
  options3.setIsCompressing(false);
528895
528972
  }
528896
528973
  return;
@@ -530619,27 +530696,27 @@ var init_promptOptimizeAgent = __esm({
530619
530696
  return `${msg.role}: ${content}`;
530620
530697
  }).join("\n");
530621
530698
  }
530622
- const optimizationPrompt = `You are a prompt optimization assistant. Your task is to improve user prompts for better AI understanding while maintaining HIGH FIDELITY to the original content.
530699
+ const optimizationPrompt = `I want you to help me optimize this prompt so the AI can better understand my intent while maintaining HIGH FIDELITY to the original content.
530623
530700
 
530624
- User's original prompt:
530701
+ Here's my original prompt:
530625
530702
  ${userPrompt}${contextSummary}
530626
530703
 
530627
- Your optimization goals (in priority order):
530628
- 1. **HIGH FIDELITY REQUIREMENT**: Preserve ALL important information, details, and requirements from the user's original prompt - DO NOT lose or omit any critical content
530629
- 2. Preserve the EXACT SAME LANGUAGE as the user (if Chinese, stay Chinese; if English, stay English)
530630
- 3. Keep the core intent and meaning unchanged
530631
- 4. Make the prompt clearer and more specific ONLY if vague - if already clear, keep it as-is
530632
- 5. Add relevant context if the user is asking follow-up questions
530633
- 6. Break down complex requests into clear requirements without losing details
530704
+ I want you to follow these optimization goals (in priority order):
530705
+ 1. **HIGH FIDELITY REQUIREMENT**: Preserve ALL important information, details, and requirements from my original prompt - DO NOT lose or omit any critical content
530706
+ 2. Preserve the EXACT SAME LANGUAGE I'm using (if I wrote in Chinese, keep it Chinese; if English, keep it English)
530707
+ 3. Keep my core intent and meaning unchanged
530708
+ 4. Make my prompt clearer and more specific ONLY if it's vague - if it's already clear, keep it as-is
530709
+ 5. Add relevant context if I'm asking follow-up questions
530710
+ 6. Break down my complex requests into clear requirements without losing details
530634
530711
  7. Keep the tone natural and conversational
530635
- 8. DO NOT add unnecessary formality or change the user's communication style
530636
- 9. If the prompt is already clear and specific, return it as-is
530712
+ 8. DO NOT add unnecessary formality or change my communication style
530713
+ 9. If my prompt is already clear and specific, return it as-is
530637
530714
 
530638
530715
  CRITICAL RULES:
530639
- - NEVER remove important details, specific requirements, file paths, code snippets, or technical specifications
530640
- - NEVER simplify the prompt if it means losing user-provided information
530641
- - When in doubt, prefer preserving the original over optimizing
530642
- - The goal is CLARITY, not BREVITY - keep all important content
530716
+ - NEVER remove important details, specific requirements, file paths, code snippets, or technical specifications I provided
530717
+ - NEVER simplify my prompt if it means losing information I gave you
530718
+ - When in doubt, prefer preserving my original content over optimizing
530719
+ - The goal is CLARITY, not BREVITY - keep all my important content
530643
530720
 
530644
530721
  IMPORTANT: Output ONLY the optimized prompt text. No explanations, no meta-commentary, no JSON format. Just the optimized prompt itself.`;
530645
530722
  const messages = [
@@ -535806,7 +535883,7 @@ You can now edit these files to customize your skill.`,
535806
535883
  )
535807
535884
  ),
535808
535885
  snapshotState.pendingRollback && import_react128.default.createElement(FileRollbackConfirmation, { fileCount: snapshotState.pendingRollback.fileCount, filePaths: snapshotState.pendingRollback.filePaths || [], onConfirm: handleRollbackConfirm }),
535809
- !pendingToolConfirmation && !pendingUserQuestion && !bashSensitiveCommand && !isCompressing && !(panelState.showSessionPanel || panelState.showMcpPanel || panelState.showUsagePanel || panelState.showHelpPanel || panelState.showCustomCommandConfig || panelState.showSkillsCreation || panelState.showWorkingDirPanel || showPermissionsPanel) && !snapshotState.pendingRollback && import_react128.default.createElement(ChatFooter, { onSubmit: handleMessageSubmit, onCommand: handleCommandExecution, onHistorySelect: handleHistorySelect, onSwitchProfile: handleSwitchProfile, handleProfileSelect, handleHistorySelect, disabled: !!pendingToolConfirmation || !!bashSensitiveCommand || isExecutingTerminalCommand, isProcessing: streamingState.isStreaming || isSaving || bashMode.state.isExecuting, chatHistory: messages, yoloMode, setYoloMode, planMode, setPlanMode, vulnerabilityHuntingMode, setVulnerabilityHuntingMode, contextUsage: streamingState.contextUsage ? {
535886
+ !pendingToolConfirmation && !pendingUserQuestion && !bashSensitiveCommand && !(panelState.showSessionPanel || panelState.showMcpPanel || panelState.showUsagePanel || panelState.showHelpPanel || panelState.showCustomCommandConfig || panelState.showSkillsCreation || panelState.showWorkingDirPanel || showPermissionsPanel) && !snapshotState.pendingRollback && import_react128.default.createElement(ChatFooter, { onSubmit: handleMessageSubmit, onCommand: handleCommandExecution, onHistorySelect: handleHistorySelect, onSwitchProfile: handleSwitchProfile, handleProfileSelect, handleHistorySelect, disabled: !!pendingToolConfirmation || !!bashSensitiveCommand || isExecutingTerminalCommand || isCompressing, isProcessing: streamingState.isStreaming || isSaving || bashMode.state.isExecuting || isCompressing, chatHistory: messages, yoloMode, setYoloMode, planMode, setPlanMode, vulnerabilityHuntingMode, setVulnerabilityHuntingMode, contextUsage: streamingState.contextUsage ? {
535810
535887
  inputTokens: streamingState.contextUsage.prompt_tokens,
535811
535888
  maxContextTokens: getOpenAiConfig().maxContextTokens || 4e3,
535812
535889
  cacheCreationTokens: streamingState.contextUsage.cache_creation_input_tokens,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snow-ai",
3
- "version": "0.5.12",
3
+ "version": "0.5.14",
4
4
  "description": "Intelligent Command Line Assistant powered by AI",
5
5
  "license": "MIT",
6
6
  "bin": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snow-ai",
3
- "version": "0.5.12",
3
+ "version": "0.5.14",
4
4
  "description": "Intelligent Command Line Assistant powered by AI",
5
5
  "license": "MIT",
6
6
  "bin": {