snow-ai 0.6.21 → 0.6.23

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
@@ -1449,7 +1449,7 @@ var require_react_development = __commonJS({
1449
1449
  var dispatcher = resolveDispatcher();
1450
1450
  return dispatcher.useCallback(callback, deps);
1451
1451
  }
1452
- function useMemo35(create3, deps) {
1452
+ function useMemo36(create3, deps) {
1453
1453
  var dispatcher = resolveDispatcher();
1454
1454
  return dispatcher.useMemo(create3, deps);
1455
1455
  }
@@ -2221,7 +2221,7 @@ var require_react_development = __commonJS({
2221
2221
  exports2.useImperativeHandle = useImperativeHandle2;
2222
2222
  exports2.useInsertionEffect = useInsertionEffect;
2223
2223
  exports2.useLayoutEffect = useLayoutEffect2;
2224
- exports2.useMemo = useMemo35;
2224
+ exports2.useMemo = useMemo36;
2225
2225
  exports2.useReducer = useReducer8;
2226
2226
  exports2.useRef = useRef16;
2227
2227
  exports2.useState = useState67;
@@ -48070,8 +48070,8 @@ PLACEHOLDER_FOR_WORKFLOW_SECTION
48070
48070
  - Enables recovery if conversation is interrupted
48071
48071
 
48072
48072
  **Formatting rule:**
48073
- - TODO item content SHOULD start with a numeric prefix to explicitly mark execution order, e.g. "1. ...", "2. ...", "3. ..."
48074
- - In continuous conversations, BEFORE calling todo-add, run todo-get (paired with an action tool) to inspect existing items and choose the next available sequence number (typically max(existingPrefix)+1). This prevents duplicate numbering across multiple turns.
48073
+ - TODO item content should be clear and actionable
48074
+ - **REQUIRED: Get existing TODOs first** - BEFORE calling todo-add, ALWAYS run todo-get (paired with an action tool in the same call) to inspect current items
48075
48075
 
48076
48076
  **WHEN TO USE (Default for most work):**
48077
48077
  - ANY task touching 2+ files
@@ -48085,8 +48085,8 @@ PLACEHOLDER_FOR_WORKFLOW_SECTION
48085
48085
  - Simple queries that don't change code
48086
48086
 
48087
48087
  **STANDARD WORKFLOW - Always Plan First:**
48088
- 1. **Receive task** \u2192 Run todo-get (paired with an action tool) to see current list and determine the next sequence number
48089
- 2. **Plan** \u2192 Create TODO with todo-add (batch add all steps at once, using the next available sequence number)
48088
+ 1. **Receive task** \u2192 Run todo-get (paired with an action tool) to see current list
48089
+ 2. **Plan** \u2192 Create TODO with todo-add (batch add all steps at once)
48090
48090
  3. **Execute** \u2192 Update progress with todo-update as each step is completed
48091
48091
  4. **Complete** \u2192 Clean up obsolete, incorrect, or superseded items with todo-delete
48092
48092
 
@@ -48104,10 +48104,10 @@ ALWAYS pair TODO tools with action tools in same call:
48104
48104
  **Examples:**
48105
48105
  \`\`\`
48106
48106
  User: "Fix authentication bug and add logging"
48107
- AI: todo-add(content=["1. Fix auth bug in auth.ts", "2. Add logging to login flow", "3. Test login with new logs"]) + filesystem-read("auth.ts")
48107
+ AI: todo-add(content=["Fix auth bug in auth.ts", "Add logging to login flow", "Test login with new logs"]) + filesystem-read("auth.ts")
48108
48108
 
48109
48109
  User: "Refactor utils module"
48110
- AI: todo-add(content=["1. Read utils module structure", "2. Identify refactor targets", "3. Extract common functions", "4. Update imports", "5. Run tests"]) + filesystem-read("utils/")
48110
+ AI: todo-add(content=["Read utils module structure", "Identify refactor targets", "Extract common functions", "Update imports", "Run tests"]) + filesystem-read("utils/")
48111
48111
  \`\`\`
48112
48112
 
48113
48113
 
@@ -363309,6 +363309,7 @@ var init_security_utils = __esm({
363309
363309
  var useTerminalExecutionState_exports = {};
363310
363310
  __export(useTerminalExecutionState_exports, {
363311
363311
  appendTerminalOutput: () => appendTerminalOutput,
363312
+ flushOutputBuffer: () => flushOutputBuffer,
363312
363313
  registerInputCallback: () => registerInputCallback,
363313
363314
  sendTerminalInput: () => sendTerminalInput,
363314
363315
  setTerminalExecutionState: () => setTerminalExecutionState,
@@ -363339,6 +363340,7 @@ function useTerminalExecutionState() {
363339
363340
  });
363340
363341
  }, []);
363341
363342
  const endExecution = (0, import_react65.useCallback)(() => {
363343
+ flushOutputBuffer();
363342
363344
  setState({
363343
363345
  isExecuting: false,
363344
363346
  command: null,
@@ -363367,13 +363369,33 @@ function setTerminalExecutionState(state) {
363367
363369
  globalSetState(state);
363368
363370
  }
363369
363371
  }
363372
+ function flushOutputBuffer() {
363373
+ if (outputFlushTimer) {
363374
+ clearTimeout(outputFlushTimer);
363375
+ outputFlushTimer = null;
363376
+ }
363377
+ if (outputBuffer.length === 0 || !globalSetState || !globalState) {
363378
+ return;
363379
+ }
363380
+ const linesToFlush = outputBuffer.splice(0, outputBuffer.length);
363381
+ globalSetState({
363382
+ ...globalState,
363383
+ output: [...globalState.output, ...linesToFlush]
363384
+ });
363385
+ }
363370
363386
  function appendTerminalOutput(line) {
363371
- if (globalSetState && globalState) {
363372
- globalSetState({
363373
- ...globalState,
363374
- output: [...globalState.output, line]
363375
- });
363387
+ if (!globalSetState || !globalState) {
363388
+ return;
363389
+ }
363390
+ outputBuffer.push(line);
363391
+ if (outputBuffer.length >= OUTPUT_BATCH_SIZE) {
363392
+ flushOutputBuffer();
363393
+ return;
363376
363394
  }
363395
+ if (outputFlushTimer) {
363396
+ clearTimeout(outputFlushTimer);
363397
+ }
363398
+ outputFlushTimer = setTimeout(flushOutputBuffer, OUTPUT_FLUSH_DELAY);
363377
363399
  }
363378
363400
  function setTerminalNeedsInput(needsInput, prompt) {
363379
363401
  if (globalSetState && globalState) {
@@ -363392,13 +363414,17 @@ function sendTerminalInput(input2) {
363392
363414
  globalInputCallback(input2);
363393
363415
  }
363394
363416
  }
363395
- var import_react65, globalSetState, globalState, globalInputCallback;
363417
+ var import_react65, globalSetState, globalState, outputBuffer, outputFlushTimer, OUTPUT_BATCH_SIZE, OUTPUT_FLUSH_DELAY, globalInputCallback;
363396
363418
  var init_useTerminalExecutionState = __esm({
363397
363419
  "dist/hooks/execution/useTerminalExecutionState.js"() {
363398
363420
  "use strict";
363399
363421
  import_react65 = __toESM(require_react(), 1);
363400
363422
  globalSetState = null;
363401
363423
  globalState = null;
363424
+ outputBuffer = [];
363425
+ outputFlushTimer = null;
363426
+ OUTPUT_BATCH_SIZE = 10;
363427
+ OUTPUT_FLUSH_DELAY = 50;
363402
363428
  globalInputCallback = null;
363403
363429
  }
363404
363430
  });
@@ -363916,6 +363942,7 @@ var init_bash = __esm({
363916
363942
  clearInterval(inputCheckInterval);
363917
363943
  registerInputCallback(null);
363918
363944
  setTerminalNeedsInput(false);
363945
+ flushOutputBuffer();
363919
363946
  if (backgroundProcessId) {
363920
363947
  const status = code2 === 0 ? "completed" : "failed";
363921
363948
  Promise.resolve().then(() => (init_useBackgroundProcesses(), useBackgroundProcesses_exports)).then(({ updateBackgroundProcessStatus: updateBackgroundProcessStatus2 }) => {
@@ -441737,6 +441764,7 @@ var init_sessionManager = __esm({
441737
441764
  }
441738
441765
  }
441739
441766
  async deleteSession(sessionId) {
441767
+ var _a21;
441740
441768
  let sessionDeleted = false;
441741
441769
  try {
441742
441770
  const oldSessionPath = path35.join(this.sessionsDir, `${sessionId}.json`);
@@ -441779,6 +441807,10 @@ var init_sessionManager = __esm({
441779
441807
  }
441780
441808
  }
441781
441809
  if (sessionDeleted) {
441810
+ this.invalidateCache();
441811
+ if (((_a21 = this.currentSession) == null ? void 0 : _a21.id) === sessionId) {
441812
+ this.clearCurrentSession();
441813
+ }
441782
441814
  try {
441783
441815
  const todoService2 = getTodoService();
441784
441816
  await todoService2.deleteTodoList(sessionId);
@@ -442515,8 +442547,8 @@ This ensures efficient workflow and prevents unnecessary wait times.`,
442515
442547
  },
442516
442548
  status: {
442517
442549
  type: "string",
442518
- enum: ["pending", "completed"],
442519
- description: 'New status - "pending" (not done) or "completed" (100% finished and verified)'
442550
+ enum: ["pending", "inProgress", "completed"],
442551
+ description: 'New status - "pending" (not started), "inProgress" (currently working on), or "completed" (100% finished and verified)'
442520
442552
  },
442521
442553
  content: {
442522
442554
  type: "string",
@@ -442540,9 +442572,7 @@ WHEN TO USE (Very common):
442540
442572
 
442541
442573
  SUPPORTS BATCH ADDING:
442542
442574
  - Single: content="Task description"
442543
- - Multiple: content=["Task 1", "Task 2", "Task 3"] (recommended for multi-step work)
442544
-
442545
- EXAMPLE: todo-add(content=["Read file", "Modify code", "Test changes"]) + filesystem-read("file.ts")`,
442575
+ - Multiple: content=["Task 1", "Task 2", "Task 3"] (recommended for multi-step work)`,
442546
442576
  inputSchema: {
442547
442577
  type: "object",
442548
442578
  properties: {
@@ -555489,16 +555519,21 @@ var init_ProfilePanel = __esm({
555489
555519
  function parseSkillIdFromHeaderLine(line) {
555490
555520
  return line.replace(/^# Skill:\s*/i, "").trim() || "unknown";
555491
555521
  }
555492
- function restoreTextWithSkillPlaceholders(buffer, text3) {
555522
+ function restoreTextWithSkillPlaceholders(buffer, text3, options3 = {}) {
555493
555523
  if (!text3)
555494
555524
  return;
555525
+ const { usePastePlaceholderForLongPlainText = false, pastePlaceholderThreshold = 300 } = options3;
555495
555526
  const lines = text3.split("\n");
555496
555527
  let plain = "";
555497
555528
  const flushPlain = () => {
555498
- if (plain) {
555529
+ if (!plain)
555530
+ return;
555531
+ if (usePastePlaceholderForLongPlainText && plain.length > pastePlaceholderThreshold) {
555532
+ buffer.insert(plain);
555533
+ } else {
555499
555534
  buffer.insertRestoredText(plain);
555500
- plain = "";
555501
555535
  }
555536
+ plain = "";
555502
555537
  };
555503
555538
  let i = 0;
555504
555539
  while (i < lines.length) {
@@ -555683,7 +555718,9 @@ function ChatInput({ onSubmit, onCommand, placeholder = "Type your message...",
555683
555718
  const images = initialContent.images || [];
555684
555719
  if (images.length === 0) {
555685
555720
  if (text3) {
555686
- restoreTextWithSkillPlaceholders(buffer, text3);
555721
+ restoreTextWithSkillPlaceholders(buffer, text3, {
555722
+ usePastePlaceholderForLongPlainText: true
555723
+ });
555687
555724
  }
555688
555725
  } else {
555689
555726
  const imagePlaceholderPattern = /\[image #\d+\]/g;
@@ -555691,7 +555728,9 @@ function ChatInput({ onSubmit, onCommand, placeholder = "Type your message...",
555691
555728
  for (let i = 0; i < parts.length; i++) {
555692
555729
  const part = parts[i];
555693
555730
  if (part) {
555694
- restoreTextWithSkillPlaceholders(buffer, part);
555731
+ restoreTextWithSkillPlaceholders(buffer, part, {
555732
+ usePastePlaceholderForLongPlainText: true
555733
+ });
555695
555734
  }
555696
555735
  if (i < images.length) {
555697
555736
  const img = images[i];
@@ -556659,10 +556698,19 @@ function TodoTree({ todos }) {
556659
556698
  const completedCount = todos.reduce((acc, t2) => acc + (t2.status === "completed" ? 1 : 0), 0);
556660
556699
  const sortedTodos = (0, import_react104.useMemo)(() => {
556661
556700
  return todos.map((t2, originalIndex) => ({ t: t2, originalIndex })).slice().sort((a, b) => {
556662
- const aCompleted = a.t.status === "completed" ? 1 : 0;
556663
- const bCompleted = b.t.status === "completed" ? 1 : 0;
556664
- if (aCompleted !== bCompleted)
556665
- return aCompleted - bCompleted;
556701
+ const getPriority = (status) => {
556702
+ if (status === "inProgress")
556703
+ return 0;
556704
+ if (status === "pending")
556705
+ return 1;
556706
+ if (status === "completed")
556707
+ return 2;
556708
+ return 1;
556709
+ };
556710
+ const aPriority = getPriority(a.t.status);
556711
+ const bPriority = getPriority(b.t.status);
556712
+ if (aPriority !== bPriority)
556713
+ return aPriority - bPriority;
556666
556714
  return a.originalIndex - b.originalIndex;
556667
556715
  }).map(({ t: t2 }) => t2);
556668
556716
  }, [todos]);
@@ -556679,10 +556727,18 @@ function TodoTree({ todos }) {
556679
556727
  const visibleTodos = sortedTodos.slice(pageIndex * PAGE_SIZE2, pageIndex * PAGE_SIZE2 + PAGE_SIZE2);
556680
556728
  const hiddenCount = Math.max(0, sortedTodos.length - visibleTodos.length);
556681
556729
  const getStatusIcon = (status) => {
556682
- return status === "completed" ? "\u2713" : "\u25CB";
556730
+ if (status === "completed")
556731
+ return "\u2713";
556732
+ if (status === "inProgress")
556733
+ return "~";
556734
+ return "\u25CB";
556683
556735
  };
556684
556736
  const getStatusColor = (status) => {
556685
- return status === "completed" ? theme14.colors.success : theme14.colors.menuSecondary;
556737
+ if (status === "completed")
556738
+ return theme14.colors.success;
556739
+ if (status === "inProgress")
556740
+ return theme14.colors.warning;
556741
+ return theme14.colors.menuSecondary;
556686
556742
  };
556687
556743
  const renderTodoLine = (todo, index) => {
556688
556744
  const statusIcon = getStatusIcon(todo.status);
@@ -558071,11 +558127,7 @@ var init_AskUserQuestion = __esm({
558071
558127
 
558072
558128
  // dist/ui/components/bash/BashCommandConfirmation.js
558073
558129
  function sanitizePreviewLine(text3) {
558074
- const withoutOsc = text3.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "");
558075
- const withoutAnsi = withoutOsc.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "");
558076
- const withoutControls = withoutAnsi.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "");
558077
- const withoutTabs = withoutControls.replace(/\t/g, " ");
558078
- return withoutTabs.replace(/[\s\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]+$/g, "").trim();
558130
+ return text3.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "").replace(/\t/g, " ").replace(/[\s\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]+$/g, "").trim();
558079
558131
  }
558080
558132
  function truncateCommand2(text3, maxWidth = 100) {
558081
558133
  if (text3.length <= maxWidth) {
@@ -558244,13 +558296,16 @@ function BashCommandExecutionStatus({ command, timeout: timeout2 = 3e4, terminal
558244
558296
  }
558245
558297
  };
558246
558298
  }, []);
558247
- const omittedCount = Math.max(0, totalCommittedLineCountRef.current - maxOutputLines);
558248
- const visibleOutputLines = omittedCount > 0 ? displayOutputLines.slice(-(maxOutputLines - 1)) : displayOutputLines.slice(-maxOutputLines);
558249
- const rawProcessedOutput = omittedCount > 0 ? [...visibleOutputLines, `... (${omittedCount} lines omitted)`] : visibleOutputLines;
558250
- const processedOutput = [...rawProcessedOutput];
558251
- while (processedOutput.length < maxOutputLines) {
558252
- processedOutput.unshift("");
558253
- }
558299
+ const processedOutput = (0, import_react112.useMemo)(() => {
558300
+ const omittedCount = Math.max(0, totalCommittedLineCountRef.current - maxOutputLines);
558301
+ const visibleOutputLines = omittedCount > 0 ? displayOutputLines.slice(-(maxOutputLines - 1)) : displayOutputLines.slice(-maxOutputLines);
558302
+ const rawProcessedOutput = omittedCount > 0 ? [...visibleOutputLines, `... (${omittedCount} lines omitted)`] : visibleOutputLines;
558303
+ const output3 = [...rawProcessedOutput];
558304
+ while (output3.length < maxOutputLines) {
558305
+ output3.unshift("");
558306
+ }
558307
+ return output3;
558308
+ }, [displayOutputLines, maxOutputLines]);
558254
558309
  const handleInputSubmit = (value) => {
558255
558310
  sendTerminalInput(value);
558256
558311
  setInputValue("");
@@ -558274,7 +558329,7 @@ function BashCommandExecutionStatus({ command, timeout: timeout2 = 3e4, terminal
558274
558329
  { paddingLeft: 2 },
558275
558330
  import_react112.default.createElement(Text, { dimColor: true, wrap: "truncate" }, displayCommand)
558276
558331
  ),
558277
- import_react112.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 2, marginTop: 1, height: maxOutputLines }, processedOutput.map((line, index) => import_react112.default.createElement(Text, { key: index, wrap: "truncate", dimColor: true }, truncateText2(sanitizePreviewLine(line), maxCommandWidth)))),
558332
+ import_react112.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 2, marginTop: 1, height: maxOutputLines }, processedOutput.map((line, index) => import_react112.default.createElement(Text, { key: index, wrap: "truncate", dimColor: true }, truncateText2(line, maxCommandWidth)))),
558278
558333
  needsInput && import_react112.default.createElement(
558279
558334
  Box_default,
558280
558335
  { flexDirection: "column", marginTop: 1, paddingLeft: 2 },
@@ -564781,6 +564836,7 @@ function formatTodoContext(todos) {
564781
564836
  }
564782
564837
  const statusSymbol = {
564783
564838
  pending: "[ ]",
564839
+ inProgress: "[~]",
564784
564840
  completed: "[x]"
564785
564841
  };
564786
564842
  const lines = [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snow-ai",
3
- "version": "0.6.21",
3
+ "version": "0.6.23",
4
4
  "description": "Agentic coding in your terminal",
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.6.21",
3
+ "version": "0.6.23",
4
4
  "description": "Agentic coding in your terminal",
5
5
  "license": "MIT",
6
6
  "bin": {