emdash-cli 0.1.30__py3-none-any.whl → 0.1.35__py3-none-any.whl

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.
@@ -43,6 +43,7 @@ class SSERenderer:
43
43
  self._spec = None
44
44
  self._spec_submitted = False
45
45
  self._plan_submitted = None # Plan data when submit_plan tool is called
46
+ self._plan_mode_requested = None # Plan mode request data
46
47
  self._pending_clarification = None
47
48
 
48
49
  # Live display state
@@ -55,6 +56,8 @@ class SSERenderer:
55
56
  # Sub-agent state (for inline updates)
56
57
  self._subagent_tool_count = 0
57
58
  self._subagent_current_tool = None
59
+ self._subagent_type = None
60
+ self._in_subagent_mode = False # Track when sub-agent is running
58
61
 
59
62
  # Spinner animation thread
60
63
  self._spinner_thread: Optional[threading.Thread] = None
@@ -83,6 +86,9 @@ class SSERenderer:
83
86
  final_response = ""
84
87
  interrupted = False
85
88
  self._last_thinking = None # Reset thinking storage
89
+ self._pending_clarification = None # Reset clarification state
90
+ self._plan_submitted = None # Reset plan state
91
+ self._plan_mode_requested = None # Reset plan mode request state
86
92
 
87
93
  # Start spinner while waiting for first event
88
94
  if self.verbose:
@@ -127,6 +133,7 @@ class SSERenderer:
127
133
  "spec": self._spec,
128
134
  "spec_submitted": self._spec_submitted,
129
135
  "plan_submitted": self._plan_submitted,
136
+ "plan_mode_requested": self._plan_mode_requested,
130
137
  "clarification": self._pending_clarification,
131
138
  "interrupted": interrupted,
132
139
  "thinking": self._last_thinking,
@@ -183,8 +190,10 @@ class SSERenderer:
183
190
  if not isinstance(data, dict):
184
191
  data = {}
185
192
 
186
- # Clear waiting indicator when new event arrives
187
- self._clear_waiting()
193
+ # Clear waiting indicator when new event arrives (but not for sub-agent events)
194
+ subagent_id = data.get("subagent_id") if isinstance(data, dict) else None
195
+ if not subagent_id and not self._in_subagent_mode:
196
+ self._clear_waiting()
188
197
 
189
198
  if event_type == "session_start":
190
199
  self._render_session_start(data)
@@ -196,8 +205,14 @@ class SSERenderer:
196
205
  self._waiting_for_next = True
197
206
  if self.verbose:
198
207
  self._start_spinner("thinking")
208
+ elif event_type == "subagent_start":
209
+ self._render_subagent_start(data)
210
+ elif event_type == "subagent_end":
211
+ self._render_subagent_end(data)
199
212
  elif event_type == "thinking":
200
213
  self._render_thinking(data)
214
+ elif event_type == "assistant_text":
215
+ self._render_assistant_text(data)
201
216
  elif event_type == "progress":
202
217
  self._render_progress(data)
203
218
  elif event_type == "partial_response":
@@ -206,6 +221,8 @@ class SSERenderer:
206
221
  return self._render_response(data)
207
222
  elif event_type == "clarification":
208
223
  self._render_clarification(data)
224
+ elif event_type == "plan_mode_requested":
225
+ self._render_plan_mode_requested(data)
209
226
  elif event_type == "plan_submitted":
210
227
  self._render_plan_submitted(data)
211
228
  elif event_type == "error":
@@ -239,6 +256,9 @@ class SSERenderer:
239
256
  self._tool_count = 0
240
257
  self._completed_tools = []
241
258
 
259
+ # Start spinner while waiting for first tool
260
+ self._start_spinner("thinking")
261
+
242
262
  def _render_tool_start(self, data: dict) -> None:
243
263
  """Render tool start event."""
244
264
  if not self.verbose:
@@ -246,11 +266,22 @@ class SSERenderer:
246
266
 
247
267
  name = data.get("name", "unknown")
248
268
  args = data.get("args", {})
269
+ tool_id = data.get("tool_id")
249
270
  subagent_id = data.get("subagent_id")
250
271
  subagent_type = data.get("subagent_type")
251
272
 
252
273
  self._tool_count += 1
253
- self._current_tool = {"name": name, "args": args, "start_time": time.time()}
274
+
275
+ # Store tool info for result rendering (keyed by tool_id for parallel support)
276
+ if not hasattr(self, '_pending_tools'):
277
+ self._pending_tools = {}
278
+ # Use tool_id if available, otherwise fall back to name
279
+ key = tool_id or name
280
+ self._pending_tools[key] = {"name": name, "args": args, "start_time": time.time(), "tool_id": tool_id}
281
+ self._current_tool = self._pending_tools[key]
282
+
283
+ # Stop spinner when tool starts
284
+ self._stop_spinner()
254
285
 
255
286
  # Special handling for task tool (spawning sub-agents)
256
287
  if name == "task":
@@ -264,59 +295,49 @@ class SSERenderer:
264
295
  self._render_subagent_progress(subagent_type or "Agent", name, args)
265
296
  return
266
297
 
267
- # Format args summary (compact)
268
- args_summary = self._format_args_summary(args)
269
-
270
- # Show spinner with tool name
271
- spinner = SPINNER_FRAMES[0]
272
- self.console.print(
273
- f" [dim]┃[/dim] [yellow]{spinner}[/yellow] [bold]{name}[/bold] {args_summary}",
274
- end="\r"
275
- )
298
+ # Don't print anything here - wait for tool_result to print complete line
299
+ # This handles parallel tool execution correctly
276
300
 
277
301
  def _render_subagent_progress(self, agent_type: str, tool_name: str, args: dict) -> None:
278
302
  """Render sub-agent progress on a single updating line."""
279
303
  self._spinner_idx = (self._spinner_idx + 1) % len(SPINNER_FRAMES)
280
304
  spinner = SPINNER_FRAMES[self._spinner_idx]
281
305
 
306
+ # Use stored type if not provided
307
+ agent_type = agent_type or self._subagent_type or "Agent"
308
+
282
309
  # Get a short summary of what's being done
283
310
  summary = ""
284
311
  if "path" in args:
285
312
  path = str(args["path"])
286
313
  # Shorten long paths
287
- if len(path) > 40:
288
- summary = "..." + path[-37:]
314
+ if len(path) > 30:
315
+ summary = "..." + path[-27:]
289
316
  else:
290
317
  summary = path
291
318
  elif "pattern" in args:
292
- summary = str(args["pattern"])[:30]
319
+ summary = str(args["pattern"])[:25]
293
320
 
294
- # Clear line and show progress
295
- line = f" [dim][/dim] [yellow]{spinner}[/yellow] [dim cyan]({agent_type})[/dim cyan] {self._subagent_tool_count} tools... [bold]{tool_name}[/bold] [dim]{summary}[/dim]"
296
- # Pad to clear previous content
297
- sys.stdout.write(f"\r{' ' * 120}\r")
298
- self.console.print(line, end="")
321
+ # Build compact progress line
322
+ line = f" │ {spinner} ({agent_type}) {self._subagent_tool_count} tools... {tool_name} {summary}"
323
+ # Use ANSI: move to column 0, clear line, print
324
+ sys.stdout.write(f"\r\033[K{line}")
325
+ sys.stdout.flush()
299
326
 
300
327
  def _render_agent_spawn_start(self, args: dict) -> None:
301
- """Render sub-agent spawn start with special UI."""
328
+ """Track sub-agent spawn state (rendering done by subagent_start event)."""
302
329
  agent_type = args.get("subagent_type", "Explore")
303
- description = args.get("description", "")
304
- prompt = args.get("prompt", "")
330
+
331
+ # Enter sub-agent mode: stop spinner, track state
332
+ self._stop_spinner()
333
+ self._in_subagent_mode = True
305
334
 
306
335
  # Reset sub-agent tracking
307
336
  self._subagent_tool_count = 0
308
337
  self._subagent_current_tool = None
338
+ self._subagent_type = agent_type
309
339
 
310
- # Truncate prompt for display
311
- prompt_display = prompt[:60] + "..." if len(prompt) > 60 else prompt
312
-
313
- self.console.print()
314
- self.console.print(
315
- f" [bold magenta]◆ Spawning {agent_type} Agent[/bold magenta]"
316
- )
317
- if description:
318
- self.console.print(f" [dim]{description}[/dim]")
319
- self.console.print(f" [cyan]→[/cyan] {prompt_display}")
340
+ # Don't render here - subagent_start event will render the UI
320
341
 
321
342
  def _render_tool_result(self, data: dict) -> None:
322
343
  """Render tool result event."""
@@ -342,31 +363,35 @@ class SSERenderer:
342
363
 
343
364
  # Sub-agent events: don't print result lines, just keep updating progress
344
365
  if subagent_id:
345
- # Progress is already shown by _render_tool_start, nothing to do here
346
366
  return
347
367
 
368
+ # Get tool info from pending tools (use tool_id if available)
369
+ pending_tools = getattr(self, '_pending_tools', {})
370
+ tool_id = data.get("tool_id")
371
+ key = tool_id or name
372
+ tool_info = pending_tools.pop(key, None) or self._current_tool or {}
373
+ args = tool_info.get("args", {})
374
+
348
375
  # Calculate duration
349
376
  duration = ""
350
- if self._current_tool and self._current_tool.get("start_time"):
351
- elapsed = time.time() - self._current_tool["start_time"]
352
- if elapsed >= 0.1:
353
- duration = f" [dim]{elapsed:.1f}s[/dim]"
377
+ start_time = tool_info.get("start_time")
378
+ if start_time:
379
+ elapsed = time.time() - start_time
380
+ if elapsed >= 0.5: # Only show if >= 0.5s
381
+ duration = f" {elapsed:.1f}s"
354
382
 
355
- args_summary = ""
356
- if self._current_tool:
357
- args_summary = self._format_args_summary(self._current_tool.get("args", {}))
383
+ # Format args for display
384
+ args_display = self._format_tool_args(name, args)
358
385
 
386
+ # Build complete line: • ToolName(args)
359
387
  if success:
360
- status_icon = "[green]✓[/green]"
361
- result_text = f"[dim]{summary}[/dim]" if summary else ""
388
+ # Format: • tool(args) result 1.2s
389
+ result_text = f" [dim]{summary}[/dim]" if summary else ""
390
+ duration_text = f" [dim]{duration}[/dim]" if duration else ""
391
+ self.console.print(f" [green]✓[/green] [bold]{name}[/bold]({args_display}){result_text}{duration_text}")
362
392
  else:
363
- status_icon = "[red]✗[/red]"
364
- result_text = f"[red]{summary}[/red]" if summary else "[red]failed[/red]"
365
-
366
- # Overwrite the spinner line
367
- self.console.print(
368
- f" [dim]┃[/dim] {status_icon} [bold]{name}[/bold] {args_summary}{duration} {result_text}"
369
- )
393
+ error_text = summary or "failed"
394
+ self.console.print(f" [red]✗[/red] [bold]{name}[/bold]({args_display}) [red]{error_text}[/red]")
370
395
 
371
396
  self._completed_tools.append({
372
397
  "name": name,
@@ -380,8 +405,11 @@ class SSERenderer:
380
405
  success = data.get("success", True)
381
406
  result_data = data.get("data") or {}
382
407
 
383
- # Clear the progress line
384
- sys.stdout.write(f"\r{' ' * 120}\r")
408
+ # Exit sub-agent mode
409
+ self._in_subagent_mode = False
410
+
411
+ # Clear the progress line and move to new line
412
+ sys.stdout.write(f"\r\033[K")
385
413
  sys.stdout.flush()
386
414
 
387
415
  # Calculate duration
@@ -415,6 +443,66 @@ class SSERenderer:
415
443
  self.console.print()
416
444
  self._current_tool = None
417
445
  self._subagent_tool_count = 0
446
+ self._subagent_type = None
447
+
448
+ def _render_subagent_start(self, data: dict) -> None:
449
+ """Render subagent start event - shows when Explore/Plan agent is spawned."""
450
+ agent_type = data.get("agent_type", "Agent")
451
+ prompt = data.get("prompt", "")
452
+ description = data.get("description", "")
453
+
454
+ # Stop any existing spinner
455
+ self._stop_spinner()
456
+
457
+ # Truncate prompt for display
458
+ prompt_display = prompt[:80] + "..." if len(prompt) > 80 else prompt
459
+
460
+ self.console.print()
461
+ # Use different colors for different agent types
462
+ if agent_type == "Plan":
463
+ self.console.print(f" [bold blue]◆ Spawning {agent_type} Agent[/bold blue]")
464
+ else:
465
+ self.console.print(f" [bold magenta]◆ Spawning {agent_type} Agent[/bold magenta]")
466
+
467
+ if description:
468
+ self.console.print(f" [dim]{description}[/dim]")
469
+ self.console.print(f" [cyan]→[/cyan] {prompt_display}")
470
+
471
+ # Enter subagent mode for tool tracking
472
+ self._in_subagent_mode = True
473
+ self._subagent_type = agent_type
474
+ self._subagent_tool_count = 0
475
+ self._subagent_start_time = time.time()
476
+
477
+ def _render_subagent_end(self, data: dict) -> None:
478
+ """Render subagent end event - shows completion summary."""
479
+ agent_type = data.get("agent_type", "Agent")
480
+ success = data.get("success", True)
481
+ iterations = data.get("iterations", 0)
482
+ files_explored = data.get("files_explored", 0)
483
+ execution_time = data.get("execution_time", 0)
484
+
485
+ # Exit subagent mode
486
+ self._in_subagent_mode = False
487
+
488
+ if success:
489
+ self.console.print(
490
+ f" [green]✓[/green] {agent_type} completed [dim]({execution_time:.1f}s)[/dim]"
491
+ )
492
+ # Show stats
493
+ stats = []
494
+ if iterations > 0:
495
+ stats.append(f"{iterations} turns")
496
+ if files_explored > 0:
497
+ stats.append(f"{files_explored} files")
498
+ if stats:
499
+ self.console.print(f" [dim]{' · '.join(stats)}[/dim]")
500
+ else:
501
+ self.console.print(f" [red]✗[/red] {agent_type} failed")
502
+
503
+ self.console.print()
504
+ self._subagent_type = None
505
+ self._subagent_tool_count = 0
418
506
 
419
507
  def _format_args_summary(self, args: dict) -> str:
420
508
  """Format args into a compact summary string."""
@@ -422,7 +510,7 @@ class SSERenderer:
422
510
  return ""
423
511
 
424
512
  parts = []
425
- for k, v in list(args.items())[:2]:
513
+ for _, v in list(args.items())[:2]:
426
514
  v_str = str(v)
427
515
  if len(v_str) > 40:
428
516
  v_str = v_str[:37] + "..."
@@ -430,6 +518,41 @@ class SSERenderer:
430
518
 
431
519
  return " ".join(parts)
432
520
 
521
+ def _format_tool_args(self, tool_name: str, args: dict) -> str:
522
+ """Format tool args in Claude Code style: ToolName(key_arg_value).
523
+
524
+ Shows the most relevant arg for each tool type.
525
+ """
526
+ if not args:
527
+ return ""
528
+
529
+ # Tool-specific formatting for cleaner display
530
+ if tool_name in ("glob", "grep", "semantic_search"):
531
+ pattern = args.get("pattern", args.get("query", ""))
532
+ if pattern:
533
+ return f'[dim]pattern:[/dim] "{pattern}"' if len(pattern) < 50 else f'[dim]pattern:[/dim] "{pattern[:47]}..."'
534
+ elif tool_name in ("read_file", "write_to_file", "list_files"):
535
+ path = args.get("path", "")
536
+ if path:
537
+ return f"[dim]{path}[/dim]"
538
+ elif tool_name == "bash":
539
+ cmd = args.get("command", "")
540
+ if cmd:
541
+ return f"[dim]{cmd[:60]}{'...' if len(cmd) > 60 else ''}[/dim]"
542
+ elif tool_name == "edit_file":
543
+ path = args.get("path", "")
544
+ if path:
545
+ return f"[dim]{path}[/dim]"
546
+
547
+ # Default: show first arg value
548
+ if args:
549
+ first_val = str(list(args.values())[0])
550
+ if len(first_val) > 50:
551
+ first_val = first_val[:47] + "..."
552
+ return f"[dim]{first_val}[/dim]"
553
+
554
+ return ""
555
+
433
556
  def _render_thinking(self, data: dict) -> None:
434
557
  """Render thinking event.
435
558
 
@@ -442,15 +565,15 @@ class SSERenderer:
442
565
 
443
566
  # Check if this is extended thinking (long content) vs short progress message
444
567
  if len(message) > 200:
445
- # Extended thinking - show summary with collapsible indicator
568
+ # Extended thinking - show full content
446
569
  self._stop_spinner()
447
570
  lines = message.strip().split("\n")
448
- preview = lines[0][:80] + "..." if len(lines[0]) > 80 else lines[0]
449
571
  line_count = len(lines)
450
572
  char_count = len(message)
451
573
 
452
574
  self.console.print(f" [dim]┃[/dim] [dim italic]💭 Thinking ({char_count:,} chars, {line_count} lines)[/dim italic]")
453
- self.console.print(f" [dim]┃[/dim] [dim] {preview}[/dim]")
575
+ for line in lines:
576
+ self.console.print(f" [dim]┃[/dim] [dim] {line}[/dim]")
454
577
 
455
578
  # Store thinking for potential later display
456
579
  self._last_thinking = message
@@ -458,6 +581,24 @@ class SSERenderer:
458
581
  # Short progress message
459
582
  self.console.print(f" [dim]┃[/dim] [dim italic]💭 {message}[/dim italic]")
460
583
 
584
+ def _render_assistant_text(self, data: dict) -> None:
585
+ """Render intermediate assistant text (between tool calls)."""
586
+ if not self.verbose:
587
+ return
588
+
589
+ content = data.get("content", "").strip()
590
+ if not content:
591
+ return
592
+
593
+ # Stop spinner while showing text
594
+ self._stop_spinner()
595
+
596
+ # Show as bullet point like Claude Code (cyan for assistant reasoning)
597
+ # Truncate long content
598
+ if len(content) > 200:
599
+ content = content[:197] + "..."
600
+ self.console.print(f" [cyan]•[/cyan] [italic]{content}[/italic]")
601
+
461
602
  def _render_progress(self, data: dict) -> None:
462
603
  """Render progress event."""
463
604
  if not self.verbose:
@@ -507,73 +648,47 @@ class SSERenderer:
507
648
  self.console.print(f" [yellow][{i}][/yellow] {opt}")
508
649
  self.console.print()
509
650
 
510
- self._pending_clarification = {
511
- "question": question,
512
- "context": context,
513
- "options": options,
514
- }
515
- else:
516
- self._pending_clarification = None
651
+ # Always store clarification (with or without options)
652
+ self._pending_clarification = {
653
+ "question": question,
654
+ "context": context,
655
+ "options": options,
656
+ }
657
+
658
+ def _render_plan_mode_requested(self, data: dict) -> None:
659
+ """Render plan mode request event and store for menu display."""
660
+ from rich.panel import Panel
661
+
662
+ reason = data.get("reason", "")
663
+
664
+ # Store the request data for the CLI to show the menu
665
+ self._plan_mode_requested = data
666
+
667
+ # Display the request
668
+ self.console.print()
669
+ self.console.print(Panel(
670
+ f"[bold]Request to Enter Plan Mode[/bold]\n\n{reason}",
671
+ title="[yellow]⚡ Plan Mode Request[/yellow]",
672
+ border_style="yellow",
673
+ ))
517
674
 
518
675
  def _render_plan_submitted(self, data: dict) -> None:
519
676
  """Render plan submission event and store for menu display."""
520
677
  from rich.panel import Panel
521
- from rich.table import Table
522
- from rich.text import Text
678
+ from rich.markdown import Markdown
523
679
 
524
- title = data.get("title", "Plan")
525
- summary = data.get("summary", "")
526
- files_to_modify = data.get("files_to_modify", [])
527
- implementation_steps = data.get("implementation_steps", [])
528
- risks = data.get("risks", [])
529
- testing_strategy = data.get("testing_strategy", "")
680
+ plan = data.get("plan", "")
530
681
 
531
682
  # Store the plan data for the CLI to show the menu
532
683
  self._plan_submitted = data
533
684
 
534
- # Build plan display
685
+ # Render plan as markdown in a panel
535
686
  self.console.print()
536
687
  self.console.print(Panel(
537
- f"[bold]{title}[/bold]\n\n{summary}",
688
+ Markdown(plan),
538
689
  title="[cyan]📋 Plan[/cyan]",
539
690
  border_style="cyan",
540
691
  ))
541
-
542
- # Critical Files table (always shown)
543
- if files_to_modify:
544
- files_table = Table(title="Critical Files", show_header=True, header_style="bold cyan")
545
- files_table.add_column("File", style="yellow")
546
- files_table.add_column("Lines", style="dim")
547
- files_table.add_column("Changes", style="white")
548
-
549
- for f in files_to_modify:
550
- if isinstance(f, dict):
551
- files_table.add_row(
552
- f.get("path", ""),
553
- f.get("lines", ""),
554
- f.get("changes", "")
555
- )
556
- else:
557
- files_table.add_row(str(f), "", "")
558
-
559
- self.console.print(files_table)
560
-
561
- # Implementation Steps (only if provided)
562
- if implementation_steps:
563
- self.console.print("\n[bold cyan]Implementation Steps[/bold cyan]")
564
- for i, step in enumerate(implementation_steps, 1):
565
- self.console.print(f" [dim]{i}.[/dim] {step}")
566
-
567
- # Risks (only if provided)
568
- if risks:
569
- self.console.print("\n[bold yellow]⚠ Risks[/bold yellow]")
570
- for risk in risks:
571
- self.console.print(f" [yellow]•[/yellow] {risk}")
572
-
573
- # Testing (only if provided)
574
- if testing_strategy:
575
- self.console.print(f"\n[bold green]Testing:[/bold green] {testing_strategy}")
576
-
577
692
  self.console.print()
578
693
 
579
694
  def _render_error(self, data: dict) -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: emdash-cli
3
- Version: 0.1.30
3
+ Version: 0.1.35
4
4
  Summary: EmDash CLI - Command-line interface for code intelligence
5
5
  Author: Em Dash Team
6
6
  Requires-Python: >=3.10,<4.0
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3.13
12
12
  Classifier: Programming Language :: Python :: 3.14
13
13
  Provides-Extra: images
14
14
  Requires-Dist: click (>=8.1.7,<9.0.0)
15
- Requires-Dist: emdash-core (>=0.1.30)
15
+ Requires-Dist: emdash-core (>=0.1.35)
16
16
  Requires-Dist: httpx (>=0.25.0)
17
17
  Requires-Dist: pillow (>=10.0.0) ; extra == "images"
18
18
  Requires-Dist: prompt_toolkit (>=3.0.43,<4.0.0)
@@ -1,8 +1,8 @@
1
- emdash_cli/__init__.py,sha256=Rnn2O7B8OCEKlVtNRbWOU2-GN75_KLmhEJgOZzY-KwE,232
2
- emdash_cli/client.py,sha256=aQO_wF4XQaqig6RWhTA3FIJslweo7LsZHCk_GBVGdvw,17117
1
+ emdash_cli/__init__.py,sha256=21JmQcWge3QOM4hLjtBdu-7AoxJonJuIwMeobWIjr2w,690
2
+ emdash_cli/client.py,sha256=MZCyajCM7UghFVv_lKoPAaX0lUUDTe4FI4qlIPCYvcc,21008
3
3
  emdash_cli/clipboard.py,sha256=hcg5sbIhbixqzpJdonoFLGBlSo2AKjplNrWy5PGnqaY,3564
4
4
  emdash_cli/commands/__init__.py,sha256=D9edXBHm69tueUtE4DggTA1_Yjsl9YZaKjBVDY2D_gQ,712
5
- emdash_cli/commands/agent.py,sha256=dLNNyJNL9uzZcBapzFghdjb-Xa27PglpbFNAMPGa3qc,28772
5
+ emdash_cli/commands/agent.py,sha256=ZBCJWxX-Ze6UlmU3POO3EMjCdOc6D_akxlr6T4U-p74,48445
6
6
  emdash_cli/commands/analyze.py,sha256=c9ztbv0Ra7g2AlDmMOy-9L51fDVuoqbuzxnRfomoFIQ,4403
7
7
  emdash_cli/commands/auth.py,sha256=SpWdqO1bJCgt4x1B4Pr7hNOucwTuBFJ1oGPOzXtvwZM,3816
8
8
  emdash_cli/commands/db.py,sha256=nZK7gLDVE2lAQVYrMx6Swscml5OAtkbg-EcSNSvRIlA,2922
@@ -22,8 +22,9 @@ emdash_cli/commands/team.py,sha256=K1-IJg6iG-9HMF_3JmpNDlNs1PYbb-ThFHU9KU_jKRo,1
22
22
  emdash_cli/keyboard.py,sha256=haYYAuhYGtdjomzhIFy_3Z3eN3BXfMdb4uRQjwB0tbk,4593
23
23
  emdash_cli/main.py,sha256=c-faWp-jzf9a0BbXhVoPvPQfGWSryXpYfswehqZCYPM,2593
24
24
  emdash_cli/server_manager.py,sha256=RrLteSHUmcFV4cyHJAEmgM9qHru2mJS08QNLWno6Y3Y,7051
25
- emdash_cli/sse_renderer.py,sha256=aDOoHKglOkaYEXuKg937mH6yFPDxjU7Rqa_-APyM9Dc,23215
26
- emdash_cli-0.1.30.dist-info/METADATA,sha256=czNXf-GzyfHKHe8g8Dfd7Bm7kI189H-VLRpFDVgtejc,738
27
- emdash_cli-0.1.30.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
28
- emdash_cli-0.1.30.dist-info/entry_points.txt,sha256=31CuYD0k-tM8csFWDunc-JoZTxXaifj3oIXz4V0p6F0,122
29
- emdash_cli-0.1.30.dist-info/RECORD,,
25
+ emdash_cli/session_store.py,sha256=GjS73GLSZ3oTNtrFHMcyiP6GnH0Dvfvs6r4s3-bfEaM,9424
26
+ emdash_cli/sse_renderer.py,sha256=QRykGh1BirtRC_2_3X48zJ0gctDEF7OV5VgiM0QUwtQ,27750
27
+ emdash_cli-0.1.35.dist-info/METADATA,sha256=Imi3rtfGyvWLC_ddLV8GiPPeSQlavqcB78XgowoJufg,738
28
+ emdash_cli-0.1.35.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
29
+ emdash_cli-0.1.35.dist-info/entry_points.txt,sha256=31CuYD0k-tM8csFWDunc-JoZTxXaifj3oIXz4V0p6F0,122
30
+ emdash_cli-0.1.35.dist-info/RECORD,,