deepy-cli 0.2.5__tar.gz → 0.2.6__tar.gz

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.
Files changed (95) hide show
  1. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/PKG-INFO +24 -2
  2. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/README.md +21 -0
  3. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/pyproject.toml +3 -2
  4. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/__init__.py +1 -1
  5. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/cli.py +28 -11
  6. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/mcp.py +21 -2
  7. deepy_cli-0.2.6/src/deepy/tui/__init__.py +5 -0
  8. deepy_cli-0.2.6/src/deepy/tui/app.py +1728 -0
  9. deepy_cli-0.2.6/src/deepy/tui/commands.py +89 -0
  10. deepy_cli-0.2.6/src/deepy/tui/compat.py +7 -0
  11. deepy_cli-0.2.6/src/deepy/tui/diff.py +115 -0
  12. deepy_cli-0.2.6/src/deepy/tui/runner.py +34 -0
  13. deepy_cli-0.2.6/src/deepy/tui/screens.py +409 -0
  14. deepy_cli-0.2.6/src/deepy/tui/state.py +101 -0
  15. deepy_cli-0.2.6/src/deepy/tui/widgets.py +872 -0
  16. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/message_view.py +6 -2
  17. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/slash_commands.py +5 -1
  18. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/terminal.py +2 -2
  19. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/__main__.py +0 -0
  20. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/config/__init__.py +0 -0
  21. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/config/settings.py +0 -0
  22. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/__init__.py +0 -0
  23. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/skills/skill-creator/SKILL.md +0 -0
  24. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/skills/skill-installer/SKILL.md +0 -0
  25. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/tools/AskUserQuestion.md +0 -0
  26. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/tools/WebFetch.md +0 -0
  27. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/tools/WebSearch.md +0 -0
  28. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/tools/__init__.py +0 -0
  29. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/tools/edit.md +0 -0
  30. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/tools/modify.md +0 -0
  31. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/tools/read.md +0 -0
  32. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/tools/shell.md +0 -0
  33. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/tools/todo_write.md +0 -0
  34. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/data/tools/write.md +0 -0
  35. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/errors.py +0 -0
  36. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/llm/__init__.py +0 -0
  37. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/llm/agent.py +0 -0
  38. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/llm/compaction.py +0 -0
  39. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/llm/context.py +0 -0
  40. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/llm/events.py +0 -0
  41. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/llm/model_capabilities.py +0 -0
  42. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/llm/provider.py +0 -0
  43. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/llm/replay.py +0 -0
  44. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/llm/runner.py +0 -0
  45. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/llm/thinking.py +0 -0
  46. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/prompts/__init__.py +0 -0
  47. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/prompts/compact.py +0 -0
  48. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/prompts/init_agents.py +0 -0
  49. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/prompts/rules.py +0 -0
  50. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/prompts/runtime_context.py +0 -0
  51. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/prompts/system.py +0 -0
  52. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/prompts/tool_docs.py +0 -0
  53. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/sessions/__init__.py +0 -0
  54. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/sessions/jsonl.py +0 -0
  55. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/sessions/manager.py +0 -0
  56. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/skill_market.py +0 -0
  57. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/skills.py +0 -0
  58. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/status.py +0 -0
  59. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/todos.py +0 -0
  60. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/tools/__init__.py +0 -0
  61. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/tools/agents.py +0 -0
  62. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/tools/builtin.py +0 -0
  63. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/tools/file_state.py +0 -0
  64. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/tools/result.py +0 -0
  65. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/tools/shell_output.py +0 -0
  66. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/tools/shell_utils.py +0 -0
  67. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/types/__init__.py +0 -0
  68. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/types/sdk.py +0 -0
  69. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/types/tool_payloads.py +0 -0
  70. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/__init__.py +0 -0
  71. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/app.py +0 -0
  72. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/ask_user_question.py +0 -0
  73. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/exit_summary.py +0 -0
  74. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/file_mentions.py +0 -0
  75. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/loading_text.py +0 -0
  76. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/local_command.py +0 -0
  77. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/markdown.py +0 -0
  78. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/model_picker.py +0 -0
  79. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/prompt_buffer.py +0 -0
  80. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/prompt_input.py +0 -0
  81. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/session_list.py +0 -0
  82. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/session_picker.py +0 -0
  83. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/skill_picker.py +0 -0
  84. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/status_footer.py +0 -0
  85. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/styles.py +0 -0
  86. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/theme_picker.py +0 -0
  87. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/thinking_state.py +0 -0
  88. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/ui/welcome.py +0 -0
  89. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/update_check.py +0 -0
  90. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/usage.py +0 -0
  91. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/utils/__init__.py +0 -0
  92. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/utils/debug_logger.py +0 -0
  93. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/utils/error_logger.py +0 -0
  94. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/utils/json.py +0 -0
  95. {deepy_cli-0.2.5 → deepy_cli-0.2.6}/src/deepy/utils/notify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: deepy-cli
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: Deepy - Vibe coding for DeepSeek models in your terminal
5
5
  Keywords: deepseek,coding-agent,terminal,cli,agents
6
6
  Author: kirineko
@@ -18,7 +18,8 @@ Requires-Dist: orjson>=3.10,<4
18
18
  Requires-Dist: pydantic>=2.12,<3
19
19
  Requires-Dist: prompt-toolkit>=3.0,<4
20
20
  Requires-Dist: pyyaml>=6.0,<7
21
- Requires-Dist: rich>=13.9,<15
21
+ Requires-Dist: rich>=14.2,<15
22
+ Requires-Dist: textual>=8.2,<9
22
23
  Requires-Dist: tiktoken>=0.9,<1
23
24
  Requires-Dist: tomli-w>=1
24
25
  Requires-Python: >=3.12
@@ -153,6 +154,27 @@ cd your-project
153
154
  deepy
154
155
  ```
155
156
 
157
+ ### Experimental Textual TUI
158
+
159
+ Deepy's stable default UI is still launched with `deepy`. Users who want to try
160
+ the new opt-in Textual interface can run:
161
+
162
+ ```bash
163
+ deepy tui
164
+ ```
165
+
166
+ This first iteration focuses on experience and TUI-native interactions: a
167
+ scrollable transcript, live thinking and assistant blocks, prompt suggestions
168
+ for slash commands and `@file` mentions, status/help surfaces, and a Deepy-owned
169
+ diff view. It is experimental and may change between releases.
170
+
171
+ Known limitations: the TUI does not add interactive shell/PTTY support yet, and
172
+ toad / textual-diff-view are only design references. Deepy does not copy their
173
+ AGPL source or depend on those packages.
174
+
175
+ Please report feedback through GitHub Issues and include your terminal, shell,
176
+ operating system, and the exact `deepy tui` workflow you tried.
177
+
156
178
  ## Installation Notes
157
179
 
158
180
  Use this order for a fresh machine:
@@ -124,6 +124,27 @@ cd your-project
124
124
  deepy
125
125
  ```
126
126
 
127
+ ### Experimental Textual TUI
128
+
129
+ Deepy's stable default UI is still launched with `deepy`. Users who want to try
130
+ the new opt-in Textual interface can run:
131
+
132
+ ```bash
133
+ deepy tui
134
+ ```
135
+
136
+ This first iteration focuses on experience and TUI-native interactions: a
137
+ scrollable transcript, live thinking and assistant blocks, prompt suggestions
138
+ for slash commands and `@file` mentions, status/help surfaces, and a Deepy-owned
139
+ diff view. It is experimental and may change between releases.
140
+
141
+ Known limitations: the TUI does not add interactive shell/PTTY support yet, and
142
+ toad / textual-diff-view are only design references. Deepy does not copy their
143
+ AGPL source or depend on those packages.
144
+
145
+ Please report feedback through GitHub Issues and include your terminal, shell,
146
+ operating system, and the exact `deepy tui` workflow you tried.
147
+
127
148
  ## Installation Notes
128
149
 
129
150
  Use this order for a fresh machine:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "deepy-cli"
3
- version = "0.2.5"
3
+ version = "0.2.6"
4
4
  description = "Deepy - Vibe coding for DeepSeek models in your terminal"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -24,7 +24,8 @@ dependencies = [
24
24
  "pydantic>=2.12,<3",
25
25
  "prompt-toolkit>=3.0,<4",
26
26
  "pyyaml>=6.0,<7",
27
- "rich>=13.9,<15",
27
+ "rich>=14.2,<15",
28
+ "textual>=8.2,<9",
28
29
  "tiktoken>=0.9,<1",
29
30
  "tomli-w>=1",
30
31
  ]
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.2.5"
3
+ __version__ = "0.2.6"
4
4
 
5
5
 
6
6
  def main() -> None:
@@ -78,6 +78,8 @@ def _build_parser() -> argparse.ArgumentParser:
78
78
  run_parser.add_argument("--session", help="Resume an existing session id.")
79
79
  run_parser.add_argument("--skill", action="append", default=[], help="Load a skill by name.")
80
80
 
81
+ subparsers.add_parser("tui", help="Start the experimental Textual TUI.")
82
+
81
83
  sessions_parser = subparsers.add_parser("sessions", help="Inspect project sessions.")
82
84
  sessions_sub = sessions_parser.add_subparsers(dest="sessions_command", required=True)
83
85
  sessions_sub.add_parser("list", help="List sessions for the current project.")
@@ -410,6 +412,29 @@ def _cmd_status(args: argparse.Namespace) -> int:
410
412
  return 0
411
413
 
412
414
 
415
+ def _ensure_interactive_settings(args: argparse.Namespace) -> Settings:
416
+ settings = load_settings(args.config)
417
+ if not settings.model.api_key:
418
+ print("Deepy needs a DeepSeek API key before starting interactive mode.")
419
+ setup_args = argparse.Namespace(config=args.config, force=True)
420
+ _cmd_config_setup(setup_args)
421
+ settings = load_settings(args.config)
422
+ if settings.path is not None and not settings.ui.theme_configured:
423
+ theme = _prompt_theme_value(default=settings.ui.theme)
424
+ update_config_theme(settings.path, theme)
425
+ settings = load_settings(args.config)
426
+ return settings
427
+
428
+
429
+ def _cmd_tui(args: argparse.Namespace) -> int:
430
+ if not sys.stdin.isatty():
431
+ print("experimental TUI requires a TTY; use `deepy` for the stable terminal UI.", file=sys.stderr)
432
+ return 1
433
+ from deepy.tui import run_tui
434
+
435
+ return run_tui(_ensure_interactive_settings(args), project_root=Path.cwd())
436
+
437
+
413
438
  def main(argv: Sequence[str] | None = None) -> int:
414
439
  parser = _build_parser()
415
440
  args = parser.parse_args(argv)
@@ -435,20 +460,12 @@ def main(argv: Sequence[str] | None = None) -> int:
435
460
  return _cmd_skills(args)
436
461
  if args.command == "status":
437
462
  return _cmd_status(args)
463
+ if args.command == "tui":
464
+ return _cmd_tui(args)
438
465
 
439
466
  if not sys.stdin.isatty():
440
467
  parser.error("interactive mode requires a TTY; use `deepy doctor` or `deepy config show`.")
441
- settings = load_settings(args.config)
442
- if not settings.model.api_key:
443
- print("Deepy needs a DeepSeek API key before starting interactive mode.")
444
- setup_args = argparse.Namespace(config=args.config, force=True)
445
- _cmd_config_setup(setup_args)
446
- settings = load_settings(args.config)
447
- if settings.path is not None and not settings.ui.theme_configured:
448
- theme = _prompt_theme_value(default=settings.ui.theme)
449
- update_config_theme(settings.path, theme)
450
- settings = load_settings(args.config)
451
- return run_interactive(settings)
468
+ return run_interactive(_ensure_interactive_settings(args))
452
469
 
453
470
 
454
471
  if __name__ == "__main__":
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import os
4
4
  import re
5
+ from contextlib import asynccontextmanager
5
6
  from dataclasses import dataclass, field
6
7
  from pathlib import Path
7
8
  from typing import Any, Literal, Mapping
@@ -156,7 +157,6 @@ class DeepyMcpRuntime:
156
157
 
157
158
  def _build_sdk_servers(self) -> list[Any]:
158
159
  from agents.mcp import (
159
- MCPServerStdio,
160
160
  MCPServerStdioParams,
161
161
  MCPServerStreamableHttp,
162
162
  MCPServerStreamableHttpParams,
@@ -185,7 +185,7 @@ class DeepyMcpRuntime:
185
185
  params["env"] = dict(definition.env)
186
186
  if definition.cwd:
187
187
  params["cwd"] = definition.cwd
188
- server = MCPServerStdio(
188
+ server = _quiet_stdio_server(
189
189
  params=params,
190
190
  name=definition.name,
191
191
  cache_tools_list=self.settings.mcp.cache_tools_list,
@@ -419,6 +419,25 @@ def _status_from_definition(
419
419
  )
420
420
 
421
421
 
422
+ def _quiet_stdio_server(**kwargs: Any) -> Any:
423
+ from agents.mcp import MCPServerStdio
424
+
425
+ class DeepyQuietMCPServerStdio(MCPServerStdio):
426
+ def create_streams(self) -> Any:
427
+ return _quiet_stdio_client(self.params)
428
+
429
+ return DeepyQuietMCPServerStdio(**kwargs)
430
+
431
+
432
+ @asynccontextmanager
433
+ async def _quiet_stdio_client(params: Any):
434
+ from mcp import stdio_client
435
+
436
+ with open(os.devnull, "w", encoding="utf-8") as errlog:
437
+ async with stdio_client(params, errlog=errlog) as streams:
438
+ yield streams
439
+
440
+
422
441
  def _load_mcp_file(
423
442
  path: Path,
424
443
  source: str,
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .runner import run_tui
4
+
5
+ __all__ = ["run_tui"]