zjcode 0.0.1__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.
Files changed (163) hide show
  1. deepagents_code/__init__.py +42 -0
  2. deepagents_code/__main__.py +6 -0
  3. deepagents_code/_ask_user_types.py +90 -0
  4. deepagents_code/_cli_context.py +96 -0
  5. deepagents_code/_constants.py +41 -0
  6. deepagents_code/_debug.py +148 -0
  7. deepagents_code/_debug_buffer.py +204 -0
  8. deepagents_code/_env_vars.py +411 -0
  9. deepagents_code/_fake_models.py +66 -0
  10. deepagents_code/_git.py +521 -0
  11. deepagents_code/_paths.py +69 -0
  12. deepagents_code/_server_config.py +576 -0
  13. deepagents_code/_session_stats.py +235 -0
  14. deepagents_code/_startup_error.py +45 -0
  15. deepagents_code/_testing_models.py +305 -0
  16. deepagents_code/_textual_patches.py +420 -0
  17. deepagents_code/_tool_stream.py +694 -0
  18. deepagents_code/_version.py +46 -0
  19. deepagents_code/agent.py +1976 -0
  20. deepagents_code/app.py +19239 -0
  21. deepagents_code/app.tcss +438 -0
  22. deepagents_code/approval_mode.py +131 -0
  23. deepagents_code/ask_user.py +306 -0
  24. deepagents_code/auth_display.py +185 -0
  25. deepagents_code/auth_store.py +545 -0
  26. deepagents_code/built_in_skills/__init__.py +5 -0
  27. deepagents_code/built_in_skills/remember/SKILL.md +118 -0
  28. deepagents_code/built_in_skills/skill-creator/SKILL.md +383 -0
  29. deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +366 -0
  30. deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +158 -0
  31. deepagents_code/client/__init__.py +1 -0
  32. deepagents_code/client/commands/__init__.py +1 -0
  33. deepagents_code/client/commands/auth.py +541 -0
  34. deepagents_code/client/commands/config.py +714 -0
  35. deepagents_code/client/commands/mcp.py +250 -0
  36. deepagents_code/client/commands/tools.py +416 -0
  37. deepagents_code/client/launch/__init__.py +1 -0
  38. deepagents_code/client/launch/server.py +978 -0
  39. deepagents_code/client/launch/server_manager.py +540 -0
  40. deepagents_code/client/non_interactive.py +1758 -0
  41. deepagents_code/client/remote_client.py +794 -0
  42. deepagents_code/clipboard.py +217 -0
  43. deepagents_code/command_registry.py +450 -0
  44. deepagents_code/config.py +4829 -0
  45. deepagents_code/config_manifest.py +1451 -0
  46. deepagents_code/configurable_model.py +577 -0
  47. deepagents_code/default_agent_prompt.md +12 -0
  48. deepagents_code/doctor.py +559 -0
  49. deepagents_code/editor.py +142 -0
  50. deepagents_code/event_bus.py +411 -0
  51. deepagents_code/extras_info.py +661 -0
  52. deepagents_code/file_ops.py +576 -0
  53. deepagents_code/formatting.py +135 -0
  54. deepagents_code/goal_rubric.py +497 -0
  55. deepagents_code/goal_tools.py +459 -0
  56. deepagents_code/hooks.py +348 -0
  57. deepagents_code/input.py +1041 -0
  58. deepagents_code/integrations/__init__.py +1 -0
  59. deepagents_code/integrations/openai_codex.py +551 -0
  60. deepagents_code/integrations/sandbox_config.py +198 -0
  61. deepagents_code/integrations/sandbox_factory.py +1124 -0
  62. deepagents_code/integrations/sandbox_provider.py +137 -0
  63. deepagents_code/integrations/sandbox_registry.py +350 -0
  64. deepagents_code/iterm_cursor_guide.py +176 -0
  65. deepagents_code/local_context.py +926 -0
  66. deepagents_code/main.py +3985 -0
  67. deepagents_code/managed_tools.py +642 -0
  68. deepagents_code/mcp_auth.py +1950 -0
  69. deepagents_code/mcp_config.py +176 -0
  70. deepagents_code/mcp_disabled.py +212 -0
  71. deepagents_code/mcp_login_service.py +281 -0
  72. deepagents_code/mcp_oauth_ui.py +199 -0
  73. deepagents_code/mcp_providers/__init__.py +23 -0
  74. deepagents_code/mcp_providers/_registry.py +39 -0
  75. deepagents_code/mcp_providers/base.py +133 -0
  76. deepagents_code/mcp_providers/github.py +102 -0
  77. deepagents_code/mcp_providers/slack.py +175 -0
  78. deepagents_code/mcp_tools.py +2427 -0
  79. deepagents_code/mcp_trust.py +207 -0
  80. deepagents_code/media_utils.py +826 -0
  81. deepagents_code/memory_guard.py +474 -0
  82. deepagents_code/model_config.py +4156 -0
  83. deepagents_code/notifications.py +247 -0
  84. deepagents_code/offload.py +402 -0
  85. deepagents_code/onboarding.py +223 -0
  86. deepagents_code/output.py +69 -0
  87. deepagents_code/paste_collapse.py +103 -0
  88. deepagents_code/project_utils.py +231 -0
  89. deepagents_code/py.typed +0 -0
  90. deepagents_code/reasoning_effort.py +641 -0
  91. deepagents_code/reliable_rubric.py +97 -0
  92. deepagents_code/resume_state.py +237 -0
  93. deepagents_code/server_graph.py +310 -0
  94. deepagents_code/session_end_summary.py +329 -0
  95. deepagents_code/sessions.py +1716 -0
  96. deepagents_code/skills/__init__.py +18 -0
  97. deepagents_code/skills/commands.py +1252 -0
  98. deepagents_code/skills/invocation.py +112 -0
  99. deepagents_code/skills/load.py +196 -0
  100. deepagents_code/skills/trust.py +547 -0
  101. deepagents_code/state_migration.py +136 -0
  102. deepagents_code/subagents.py +278 -0
  103. deepagents_code/system_prompt.md +204 -0
  104. deepagents_code/terminal_capabilities.py +115 -0
  105. deepagents_code/terminal_escape.py +287 -0
  106. deepagents_code/theme.py +891 -0
  107. deepagents_code/todo_list_prompt.md +12 -0
  108. deepagents_code/tool_catalog.py +509 -0
  109. deepagents_code/tool_display.py +367 -0
  110. deepagents_code/tools.py +516 -0
  111. deepagents_code/tui/__init__.py +1 -0
  112. deepagents_code/tui/textual_adapter.py +2553 -0
  113. deepagents_code/tui/widgets/__init__.py +9 -0
  114. deepagents_code/tui/widgets/_js_eval_display.py +139 -0
  115. deepagents_code/tui/widgets/_links.py +261 -0
  116. deepagents_code/tui/widgets/agent_selector.py +420 -0
  117. deepagents_code/tui/widgets/approval.py +602 -0
  118. deepagents_code/tui/widgets/ask_user.py +515 -0
  119. deepagents_code/tui/widgets/auth.py +1997 -0
  120. deepagents_code/tui/widgets/autocomplete.py +890 -0
  121. deepagents_code/tui/widgets/chat_input.py +3181 -0
  122. deepagents_code/tui/widgets/codex_auth.py +452 -0
  123. deepagents_code/tui/widgets/cwd_switch.py +242 -0
  124. deepagents_code/tui/widgets/debug_console.py +868 -0
  125. deepagents_code/tui/widgets/diff.py +252 -0
  126. deepagents_code/tui/widgets/effort_selector.py +189 -0
  127. deepagents_code/tui/widgets/goal_review.py +390 -0
  128. deepagents_code/tui/widgets/goal_status.py +50 -0
  129. deepagents_code/tui/widgets/history.py +194 -0
  130. deepagents_code/tui/widgets/install_confirm.py +248 -0
  131. deepagents_code/tui/widgets/launch_init.py +482 -0
  132. deepagents_code/tui/widgets/loading.py +227 -0
  133. deepagents_code/tui/widgets/mcp_login.py +539 -0
  134. deepagents_code/tui/widgets/mcp_reconnect.py +212 -0
  135. deepagents_code/tui/widgets/mcp_viewer.py +1634 -0
  136. deepagents_code/tui/widgets/message_store.py +999 -0
  137. deepagents_code/tui/widgets/messages.py +3846 -0
  138. deepagents_code/tui/widgets/model_selector.py +2343 -0
  139. deepagents_code/tui/widgets/notification_center.py +456 -0
  140. deepagents_code/tui/widgets/notification_detail.py +257 -0
  141. deepagents_code/tui/widgets/notification_settings.py +170 -0
  142. deepagents_code/tui/widgets/restart_prompt.py +158 -0
  143. deepagents_code/tui/widgets/skill_trust.py +131 -0
  144. deepagents_code/tui/widgets/startup_tip.py +91 -0
  145. deepagents_code/tui/widgets/status.py +781 -0
  146. deepagents_code/tui/widgets/subagent_panel.py +969 -0
  147. deepagents_code/tui/widgets/theme_selector.py +401 -0
  148. deepagents_code/tui/widgets/thread_selector.py +2564 -0
  149. deepagents_code/tui/widgets/tool_renderers.py +190 -0
  150. deepagents_code/tui/widgets/tool_widgets.py +304 -0
  151. deepagents_code/tui/widgets/update_available.py +311 -0
  152. deepagents_code/tui/widgets/update_confirm.py +184 -0
  153. deepagents_code/tui/widgets/update_progress.py +327 -0
  154. deepagents_code/tui/widgets/welcome.py +508 -0
  155. deepagents_code/turn_end_summary.py +522 -0
  156. deepagents_code/ui.py +858 -0
  157. deepagents_code/unicode_security.py +563 -0
  158. deepagents_code/update_check.py +3124 -0
  159. zjcode-0.0.1.data/data/deepagents_code/default_agent_prompt.md +12 -0
  160. zjcode-0.0.1.dist-info/METADATA +220 -0
  161. zjcode-0.0.1.dist-info/RECORD +163 -0
  162. zjcode-0.0.1.dist-info/WHEEL +4 -0
  163. zjcode-0.0.1.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,287 @@
1
+ """Best-effort writer for terminal escape/control sequences.
2
+
3
+ Centralizes the "fire and forget" pattern the app uses for cosmetic terminal
4
+ control (OSC 9;4 taskbar progress today; eventually OSC 52 clipboard and the
5
+ iTerm2 cursor guide). Writes prefer `/dev/tty` so output reaches the terminal
6
+ even when stdout/stderr are redirected, fall back to `sys.__stderr__`, and
7
+ never raise — cosmetic control output must not crash the app.
8
+
9
+ Set `DEEPAGENTS_CODE_NO_TERMINAL_ESCAPE=1` to disable all output (useful for
10
+ unsupported terminals or noisy logs).
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import atexit
16
+ import logging
17
+ import pathlib
18
+ import sys
19
+ import threading
20
+ from enum import StrEnum
21
+ from typing import TYPE_CHECKING
22
+
23
+ from deepagents_code._env_vars import NO_TERMINAL_ESCAPE, is_env_truthy
24
+
25
+ if TYPE_CHECKING:
26
+ from typing import TextIO
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+ _PROGRESS_MIN = 0
31
+ """Lower clamp bound for determinate `OSC 9;4` progress percentages."""
32
+
33
+ _PROGRESS_MAX = 100
34
+ """Upper clamp bound for determinate `OSC 9;4` progress percentages."""
35
+
36
+
37
+ class TerminalProgressState(StrEnum):
38
+ """`OSC 9;4` progress states.
39
+
40
+ See https://learn.microsoft.com/en-us/windows/terminal/tutorials/progress-bar-sequences.
41
+ """
42
+
43
+ CLEAR = "0"
44
+ """Remove any progress indicator. Percentage is ignored."""
45
+
46
+ NORMAL = "1"
47
+ """Determinate progress shown with the default (success) color."""
48
+
49
+ ERROR = "2"
50
+ """Determinate progress shown with the error/red color."""
51
+
52
+ INDETERMINATE = "3"
53
+ """Activity in progress with no known percentage; renders as a pulse."""
54
+
55
+ WARNING = "4"
56
+ """Determinate progress shown with the warning/yellow color."""
57
+
58
+
59
+ def _is_disabled() -> bool:
60
+ """Return whether terminal-escape output is opt-out disabled."""
61
+ return is_env_truthy(NO_TERMINAL_ESCAPE)
62
+
63
+
64
+ def _open_tty() -> TextIO | None:
65
+ """Return an open `/dev/tty` handle, or `None` if unavailable."""
66
+ try:
67
+ return pathlib.Path("/dev/tty").open("w", encoding="utf-8")
68
+ except OSError:
69
+ return None
70
+
71
+
72
+ def _is_stream_tty(stream: TextIO | None) -> bool:
73
+ """Return whether `stream` is a real TTY."""
74
+ if stream is None:
75
+ return False
76
+ try:
77
+ return bool(stream.isatty())
78
+ except (ValueError, OSError):
79
+ return False
80
+
81
+
82
+ def write_terminal_escape(sequence: str) -> bool:
83
+ r"""Best-effort write of a terminal control sequence.
84
+
85
+ Prefers `/dev/tty` so the sequence reaches the terminal even when stdout
86
+ or stderr are redirected. Falls back to `sys.__stderr__` only if it is a
87
+ TTY.
88
+
89
+ Returns `False` (no-op) when output is disabled or no TTY is reachable.
90
+
91
+ Args:
92
+ sequence: Raw escape sequence to write, including leading `\x1b`/`ESC`
93
+ and terminator.
94
+
95
+ Returns:
96
+ `True` if the sequence was written and flushed without error.
97
+ """
98
+ if _is_disabled() or not sequence:
99
+ return False
100
+ tty = _open_tty()
101
+ if tty is not None:
102
+ try:
103
+ with tty:
104
+ tty.write(sequence)
105
+ tty.flush()
106
+ except (OSError, UnicodeError) as exc:
107
+ logger.debug("terminal_escape /dev/tty write failed: %s", exc)
108
+ else:
109
+ return True
110
+ stderr = sys.__stderr__
111
+ if stderr is not None and _is_stream_tty(stderr):
112
+ try:
113
+ stderr.write(sequence)
114
+ stderr.flush()
115
+ except (OSError, ValueError) as exc:
116
+ logger.debug("terminal_escape stderr write failed: %s", exc)
117
+ return False
118
+ return True
119
+ return False
120
+
121
+
122
+ def write_osc(command: str, payload: str = "", *, st: bool = False) -> bool:
123
+ r"""Write an `OSC <command>;<payload>` sequence.
124
+
125
+ Args:
126
+ command: The numeric OSC command (e.g. `"9;4"` for taskbar progress).
127
+ payload: Optional semicolon-joined payload appended after the command.
128
+ st: When `True`, terminate with String Terminator (`ESC \`) instead of
129
+ the default BEL (`\a`).
130
+
131
+ BEL matches the Windows Terminal docs and works on most terminals;
132
+ VTE-derived terminals may prefer ST.
133
+
134
+ Returns:
135
+ `True` if the sequence was written.
136
+ """
137
+ body = f"{command};{payload}" if payload else command
138
+ terminator = "\x1b\\" if st else "\a"
139
+ return write_terminal_escape(f"\x1b]{body}{terminator}")
140
+
141
+
142
+ _progress_active = False
143
+ _terminal_background_active = False
144
+ _atexit_registered = False
145
+ _atexit_lock = threading.Lock()
146
+
147
+
148
+ def _ensure_atexit_registered() -> None:
149
+ """Register terminal-state cleanup exactly once."""
150
+ global _atexit_registered # noqa: PLW0603
151
+
152
+ with _atexit_lock:
153
+ if not _atexit_registered:
154
+ atexit.register(_atexit_clear)
155
+ _atexit_registered = True
156
+
157
+
158
+ def _validate_progress(progress: int | None, state: TerminalProgressState) -> int:
159
+ """Clamp/normalize `progress` for a given `state`.
160
+
161
+ Determinate states (`NORMAL`, `ERROR`, `WARNING`) clamp to `[0, 100]`;
162
+ `INDETERMINATE` and `CLEAR` always emit `0`. A non-`None` `progress`
163
+ supplied with `CLEAR`/`INDETERMINATE` is dropped with a debug log so
164
+ misuse stays observable without raising on a cosmetic write path. A
165
+ `progress` that can't be coerced to `int` is treated the same way.
166
+
167
+ Args:
168
+ progress: Raw percentage, or `None`.
169
+ state: The OSC 9;4 progress state.
170
+
171
+ Returns:
172
+ The normalized progress integer to emit.
173
+ """
174
+ if state in {TerminalProgressState.CLEAR, TerminalProgressState.INDETERMINATE}:
175
+ if progress is not None and progress != 0:
176
+ logger.debug(
177
+ "terminal_progress: ignoring progress=%r for state=%s",
178
+ progress,
179
+ state.name,
180
+ )
181
+ return 0
182
+ if progress is None:
183
+ return 0
184
+ try:
185
+ coerced = int(progress)
186
+ except (TypeError, ValueError) as exc:
187
+ logger.debug(
188
+ "terminal_progress: non-numeric progress=%r ignored (%s)", progress, exc
189
+ )
190
+ return 0
191
+ return max(_PROGRESS_MIN, min(_PROGRESS_MAX, coerced))
192
+
193
+
194
+ def set_terminal_progress(
195
+ progress: int | None = None,
196
+ *,
197
+ state: TerminalProgressState = TerminalProgressState.NORMAL,
198
+ ) -> bool:
199
+ """Set the terminal's `OSC 9;4` progress indicator.
200
+
201
+ Fires unconditionally — terminals that don't recognize `OSC 9;4` silently
202
+ ignore the sequence. Set `DEEPAGENTS_CODE_NO_TERMINAL_ESCAPE=1` to opt out
203
+ entirely.
204
+
205
+ Args:
206
+ progress: Percentage `0-100` for determinate states. Ignored for
207
+ `INDETERMINATE` and `CLEAR`.
208
+ state: One of `TerminalProgressState`.
209
+
210
+ Returns:
211
+ `True` if the sequence was written.
212
+ """
213
+ global _progress_active # noqa: PLW0603
214
+
215
+ value = _validate_progress(progress, state)
216
+ payload = f"{state.value};{value}"
217
+ written = write_osc("9;4", payload)
218
+ if written and state is not TerminalProgressState.CLEAR:
219
+ _ensure_atexit_registered()
220
+ _progress_active = True
221
+ elif state is TerminalProgressState.CLEAR:
222
+ _progress_active = False
223
+ return written
224
+
225
+
226
+ def clear_terminal_progress() -> bool:
227
+ """Clear the terminal's progress indicator.
228
+
229
+ Emits `OSC 9;4;0;0`.
230
+
231
+ Returns:
232
+ `True` if the sequence was written.
233
+ """
234
+ return set_terminal_progress(state=TerminalProgressState.CLEAR)
235
+
236
+
237
+ def set_terminal_background(color: str) -> bool:
238
+ """Set the terminal's dynamic default background color with `OSC 11`.
239
+
240
+ This is cosmetic and intentionally best-effort. Terminals that don't
241
+ support `OSC 11` ignore it; `OSC 111` is emitted from `atexit` to restore
242
+ the default background when this call succeeds.
243
+
244
+ Args:
245
+ color: Terminal color payload, usually a CSS-style hex color such as
246
+ `#11121D`.
247
+
248
+ Returns:
249
+ `True` if the sequence was written.
250
+ """
251
+ global _terminal_background_active # noqa: PLW0603
252
+
253
+ if not color:
254
+ return False
255
+ written = write_osc("11", color, st=True)
256
+ if written:
257
+ _ensure_atexit_registered()
258
+ _terminal_background_active = True
259
+ return written
260
+
261
+
262
+ def reset_terminal_background() -> bool:
263
+ """Reset the terminal's dynamic default background color with `OSC 111`.
264
+
265
+ Returns:
266
+ `True` if the sequence was written.
267
+ """
268
+ global _terminal_background_active # noqa: PLW0603
269
+
270
+ written = write_osc("111", st=True)
271
+ if written:
272
+ _terminal_background_active = False
273
+ return written
274
+
275
+
276
+ def _atexit_clear() -> None:
277
+ """`atexit` hook that clears any leftover terminal state."""
278
+ if _progress_active:
279
+ try:
280
+ clear_terminal_progress()
281
+ except Exception:
282
+ logger.warning("Failed to clear terminal progress at exit", exc_info=True)
283
+ if _terminal_background_active:
284
+ try:
285
+ reset_terminal_background()
286
+ except Exception:
287
+ logger.warning("Failed to reset terminal background at exit", exc_info=True)