zettcode 0.1.2__tar.gz → 0.1.4__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 (166) hide show
  1. {zettcode-0.1.2 → zettcode-0.1.4}/.gitignore +1 -0
  2. zettcode-0.1.4/PKG-INFO +145 -0
  3. zettcode-0.1.4/README.md +112 -0
  4. zettcode-0.1.4/README.zh-CN.md +106 -0
  5. {zettcode-0.1.2 → zettcode-0.1.4}/pyproject.toml +20 -1
  6. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/__init__.py +1 -1
  7. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/__init__.py +3 -2
  8. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/agent.py +191 -20
  9. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/approval.py +20 -3
  10. zettcode-0.1.4/src/zettcode/app/agent/ask.py +96 -0
  11. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/capabilities.py +2 -2
  12. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/compaction.py +14 -0
  13. zettcode-0.1.4/src/zettcode/app/agent/context.py +532 -0
  14. zettcode-0.1.4/src/zettcode/app/agent/entries.py +218 -0
  15. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/export.py +5 -0
  16. zettcode-0.1.4/src/zettcode/app/agent/mentions.py +303 -0
  17. zettcode-0.1.4/src/zettcode/app/agent/permission.py +146 -0
  18. zettcode-0.1.4/src/zettcode/app/agent/presenters.py +615 -0
  19. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/projection.py +18 -4
  20. zettcode-0.1.4/src/zettcode/app/agent/readonly.py +435 -0
  21. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/rendering.py +60 -4
  22. zettcode-0.1.4/src/zettcode/app/agent/replay.py +156 -0
  23. zettcode-0.1.4/src/zettcode/app/agent/rows.py +388 -0
  24. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/runtime.py +232 -62
  25. zettcode-0.1.4/src/zettcode/app/agent/side.py +109 -0
  26. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/storage/__init__.py +2 -1
  27. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/storage/records.py +120 -15
  28. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/storage/store.py +151 -3
  29. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/subagents.py +40 -23
  30. zettcode-0.1.4/src/zettcode/app/agent/transcript/__init__.py +73 -0
  31. zettcode-0.1.4/src/zettcode/app/agent/transcript/fold.py +56 -0
  32. zettcode-0.1.4/src/zettcode/app/agent/transcript/log.py +182 -0
  33. zettcode-0.1.4/src/zettcode/app/agent/transcript/oneoff.py +54 -0
  34. zettcode-0.1.4/src/zettcode/app/agent/transcript/stream.py +165 -0
  35. zettcode-0.1.4/src/zettcode/app/agent/transcript/turn.py +164 -0
  36. zettcode-0.1.4/src/zettcode/app/brand.py +63 -0
  37. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/commands.py +12 -0
  38. zettcode-0.1.4/src/zettcode/app/pipeline.py +191 -0
  39. zettcode-0.1.4/src/zettcode/app/ui/app.py +743 -0
  40. zettcode-0.1.4/src/zettcode/app/ui/boot.py +111 -0
  41. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/commands.py +78 -2
  42. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/demo.py +18 -18
  43. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/keys.py +45 -2
  44. zettcode-0.1.4/src/zettcode/app/ui/labels.py +108 -0
  45. zettcode-0.1.4/src/zettcode/app/ui/notices.py +199 -0
  46. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/rows.py +62 -6
  47. zettcode-0.1.4/src/zettcode/app/ui/sessions.py +266 -0
  48. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/settings.py +23 -0
  49. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/shell.py +70 -2
  50. zettcode-0.1.4/src/zettcode/app/ui/updating.py +97 -0
  51. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/widgets/__init__.py +12 -0
  52. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/widgets/approval_page.py +38 -8
  53. zettcode-0.1.4/src/zettcode/app/ui/widgets/ask_page.py +386 -0
  54. zettcode-0.1.4/src/zettcode/app/ui/widgets/context_page.py +114 -0
  55. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/widgets/model_page.py +17 -9
  56. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/widgets/root.py +8 -1
  57. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/widgets/transcript.py +26 -15
  58. zettcode-0.1.4/src/zettcode/app/ui/widgets/update_page.py +62 -0
  59. zettcode-0.1.4/src/zettcode/app/ui/widgets/welcome.py +21 -0
  60. zettcode-0.1.4/src/zettcode/cli.py +415 -0
  61. zettcode-0.1.4/src/zettcode/collector.py +44 -0
  62. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/config.py +150 -51
  63. zettcode-0.1.4/src/zettcode/paths.py +60 -0
  64. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/plugins/builtins.py +26 -12
  65. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/plugins/state.py +5 -0
  66. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/app.py +41 -3
  67. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/scheduler.py +1 -1
  68. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/theme.py +8 -0
  69. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/input/decoder.py +35 -1
  70. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/input/events.py +5 -1
  71. zettcode-0.1.4/src/zettcode/tui/input/keys.py +259 -0
  72. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/render/__init__.py +2 -0
  73. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/render/style.py +23 -4
  74. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/render/text.py +50 -3
  75. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/runner.py +47 -17
  76. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/terminal.py +19 -24
  77. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/theme_file.py +1 -0
  78. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/list_page.py +17 -4
  79. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/markdown.py +61 -3
  80. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/text.py +7 -5
  81. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/textarea.py +9 -9
  82. zettcode-0.1.4/src/zettcode/update.py +316 -0
  83. zettcode-0.1.2/PKG-INFO +0 -136
  84. zettcode-0.1.2/README.md +0 -107
  85. zettcode-0.1.2/README.zh-CN.md +0 -98
  86. zettcode-0.1.2/src/zettcode/app/agent/blocks.py +0 -381
  87. zettcode-0.1.2/src/zettcode/app/agent/context.py +0 -293
  88. zettcode-0.1.2/src/zettcode/app/agent/entries.py +0 -189
  89. zettcode-0.1.2/src/zettcode/app/agent/mentions.py +0 -126
  90. zettcode-0.1.2/src/zettcode/app/agent/replay.py +0 -79
  91. zettcode-0.1.2/src/zettcode/app/agent/rows.py +0 -215
  92. zettcode-0.1.2/src/zettcode/app/agent/transcript.py +0 -520
  93. zettcode-0.1.2/src/zettcode/app/ui/app.py +0 -398
  94. zettcode-0.1.2/src/zettcode/app/ui/notices.py +0 -98
  95. zettcode-0.1.2/src/zettcode/app/ui/sessions.py +0 -89
  96. zettcode-0.1.2/src/zettcode/app/ui/widgets/context_page.py +0 -70
  97. zettcode-0.1.2/src/zettcode/app/ui/widgets/welcome.py +0 -19
  98. zettcode-0.1.2/src/zettcode/cli.py +0 -162
  99. zettcode-0.1.2/src/zettcode/tui/input/keys.py +0 -60
  100. {zettcode-0.1.2 → zettcode-0.1.4}/LICENSE +0 -0
  101. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/_compat.py +0 -0
  102. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/__init__.py +0 -0
  103. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/mcp.py +0 -0
  104. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/storage/metadata.py +0 -0
  105. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/title.py +0 -0
  106. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/trace/script.js +0 -0
  107. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/trace/style.css +0 -0
  108. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/trace/template.html +0 -0
  109. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/agent/usage.py +0 -0
  110. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/registry.py +0 -0
  111. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/__init__.py +0 -0
  112. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/clipboard.py +0 -0
  113. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/widgets/completer.py +0 -0
  114. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/widgets/composer.py +0 -0
  115. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/widgets/panel.py +0 -0
  116. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/widgets/sessions_page.py +0 -0
  117. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/app/ui/widgets/steering.py +0 -0
  118. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/plugins/__init__.py +0 -0
  119. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/plugins/container.py +0 -0
  120. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/plugins/extension.py +0 -0
  121. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/plugins/loader.py +0 -0
  122. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/plugins/mixins.py +0 -0
  123. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/plugins/plugin.py +0 -0
  124. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/__init__.py +0 -0
  125. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/capabilities.py +0 -0
  126. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/console.py +0 -0
  127. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/__init__.py +0 -0
  128. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/events.py +0 -0
  129. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/focus.py +0 -0
  130. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/geometry.py +0 -0
  131. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/host.py +0 -0
  132. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/keymap.py +0 -0
  133. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/screen.py +0 -0
  134. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/core/widget.py +0 -0
  135. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/gallery.py +0 -0
  136. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/glyphs.py +0 -0
  137. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/input/__init__.py +0 -0
  138. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/input/bridge.py +0 -0
  139. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/input/reader.py +0 -0
  140. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/layout/__init__.py +0 -0
  141. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/layout/box.py +0 -0
  142. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/layout/overlay.py +0 -0
  143. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/layout/scroll.py +0 -0
  144. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/layout/solver.py +0 -0
  145. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/layout/spacing.py +0 -0
  146. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/render/canvas.py +0 -0
  147. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/render/code.py +0 -0
  148. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/render/color.py +0 -0
  149. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/render/renderer.py +0 -0
  150. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/render/rich_text.py +0 -0
  151. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/render/sweep.py +0 -0
  152. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/testing/__init__.py +0 -0
  153. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/testing/harness.py +0 -0
  154. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/testing/snapshot.py +0 -0
  155. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/__init__.py +0 -0
  156. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/collapsible.py +0 -0
  157. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/completion.py +0 -0
  158. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/dialog.py +0 -0
  159. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/diff.py +0 -0
  160. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/list.py +0 -0
  161. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/progress.py +0 -0
  162. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/rich_text.py +0 -0
  163. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/status.py +0 -0
  164. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/table.py +0 -0
  165. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/tasks.py +0 -0
  166. {zettcode-0.1.2 → zettcode-0.1.4}/src/zettcode/tui/widgets/toast.py +0 -0
@@ -4,6 +4,7 @@
4
4
  *.egg-info/
5
5
  build/
6
6
  dist/
7
+ .smoke/
7
8
  .coverage
8
9
  **/.pytest_cache/
9
10
  **/.ruff_cache/
@@ -0,0 +1,145 @@
1
+ Metadata-Version: 2.5
2
+ Name: zettcode
3
+ Version: 0.1.4
4
+ Summary: A focused terminal coding agent powered by zett-agent
5
+ Project-URL: Repository, https://github.com/Chang-LeHung/zettcode
6
+ Project-URL: Issues, https://github.com/Chang-LeHung/zettcode/issues
7
+ Author: Chang-LeHung
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: agent,coding-agent,llm,terminal,tui
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Operating System :: MacOS
14
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 10
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: exceptiongroup<2,>=1.2; python_version < '3.11'
24
+ Requires-Dist: pydantic<3,>=2
25
+ Requires-Dist: pyperclip<2,>=1.9
26
+ Requires-Dist: setproctitle<2,>=1.3.7; os_name == 'posix'
27
+ Requires-Dist: tiktoken<1,>=0.12
28
+ Requires-Dist: tomli<3,>=2; python_version < '3.11'
29
+ Requires-Dist: truststore<1,>=0.10
30
+ Requires-Dist: wcwidth<1,>=0.2
31
+ Requires-Dist: zett-agent<0.2,>=0.1.14
32
+ Description-Content-Type: text/markdown
33
+
34
+ <p align="center">
35
+ <img src="docs/public/logo.svg" width="88" height="88" alt="ZettCode pixel robot with a warm heart" />
36
+ </p>
37
+ <h1 align="center">ZettCode</h1>
38
+ <p align="center"><strong>Your terminal. Your coding partner.</strong></p>
39
+ <p align="center">A focused coding agent that reads your project, shows its work, and keeps you in control.</p>
40
+ <p align="center">
41
+ <strong>English</strong> · <a href="README.zh-CN.md">简体中文</a><br />
42
+ <a href="https://chang-lehung.github.io/zettcode/guide/getting-started">Get started</a> ·
43
+ <a href="https://chang-lehung.github.io/zettcode/">Documentation</a> ·
44
+ <a href="https://chang-lehung.github.io/zettcode/guide/commands">Commands</a>
45
+ </p>
46
+
47
+ <p align="center">
48
+ <img src="docs/public/terminal.svg" width="1000" alt="ZettCode showing a task, thinking, file reads, a code edit, passing tests, and a Markdown answer" />
49
+ </p>
50
+ <p align="center"><sub>Illustrative conversation, rendered with ZettCode’s actual terminal widgets.</sub></p>
51
+
52
+ ## Get running
53
+
54
+ You need **Python 3.10+**, a UTF-8 terminal, and an **OpenAI-compatible API**
55
+ (or Anthropic's **Messages API**).
56
+ Works on macOS, Linux, and Windows (use Windows Terminal).
57
+
58
+ ### 1. Install
59
+
60
+ ```bash
61
+ uv tool install zettcode
62
+ # or: pip install zettcode
63
+ ```
64
+
65
+ ### 2. Connect a model
66
+
67
+ Create `~/.zettcode/config.toml` (and its parent directory) with one model:
68
+
69
+ ```toml
70
+ [[models]]
71
+ model = "deepseek-v4-pro" # the model id sent to DeepSeek
72
+ display_model = "DeepSeek Pro" # the name shown in ZettCode
73
+ token = "sk-..." # replace with your DeepSeek API key
74
+ base_url = "https://api.deepseek.com" # DeepSeek's OpenAI-compatible API root
75
+ context_window = 1000000 # verify against the endpoint's current limits
76
+ multimodal = false # this model accepts text, not images
77
+ ```
78
+
79
+ Get a key from the [DeepSeek platform](https://platform.deepseek.com/), not from
80
+ the chat website. Alternatively, omit `token` and set `OPENAI_API_KEY` to that
81
+ key. Add more `[[models]]` entries to switch with `/model`; the first is selected
82
+ at startup. See the
83
+ [configuration reference](https://chang-lehung.github.io/zettcode/guide/config)
84
+ for complete examples, defaults, and troubleshooting.
85
+
86
+ ### 3. Start a task
87
+
88
+ ```bash
89
+ cd /path/to/project
90
+ zettcode
91
+ # or: zettcode --workspace /path/to/project
92
+ ```
93
+
94
+ Describe a change and press **Enter**. Type `/` for commands, `@` to reference a
95
+ skill, and **Ctrl-C** to stop a request. **Ctrl-D** with an empty composer exits
96
+ and prints the command to resume your session.
97
+
98
+ ## Built for the way you work
99
+
100
+ | | |
101
+ | --- | --- |
102
+ | **See every step** | Reasoning, answers, and tool calls stream as readable rows — not raw JSON. |
103
+ | **Keep the decision** | Review shell commands before they run. When the agent needs your input, choose an option or type an answer. |
104
+ | **Keep moving** | Send a steering message during a reply. Use `/btw` for a side question that stays out of later context. |
105
+ | **Come back later** | `/resume` restores a conversation; `/export` saves a readable HTML record. |
106
+ | **Understand the context** | Monitor token usage and caching, inspect `/context`, and compact when needed. |
107
+ | **Bring your tools** | Use project `AGENTS.md` instructions, skills, MCP servers, and Python plugins. |
108
+
109
+ The palette follows your terminal’s background, or your own `theme.toml`.
110
+ Select and copy text, scroll through answers, and paste images when your model
111
+ supports them.
112
+
113
+ ## Find your next step
114
+
115
+ The **[user guide](https://chang-lehung.github.io/zettcode/guide/overview)** is
116
+ available in English and [简体中文](https://chang-lehung.github.io/zettcode/zh/guide/overview).
117
+
118
+ | First time | Everyday use | Configuration & extensions |
119
+ | --- | --- | --- |
120
+ | [Getting started](https://chang-lehung.github.io/zettcode/guide/getting-started) | [Keys & mouse](https://chang-lehung.github.io/zettcode/guide/keys) | [Configuration](https://chang-lehung.github.io/zettcode/guide/config) |
121
+ | [The interface](https://chang-lehung.github.io/zettcode/guide/interface) | [Commands](https://chang-lehung.github.io/zettcode/guide/commands) | [Models & context](https://chang-lehung.github.io/zettcode/guide/models) |
122
+ | [Problems & questions](https://chang-lehung.github.io/zettcode/guide/faq) | [Sessions](https://chang-lehung.github.io/zettcode/guide/sessions) | [Project instructions](https://chang-lehung.github.io/zettcode/guide/instructions) |
123
+ | | | [Skills & MCP](https://chang-lehung.github.io/zettcode/guide/skills-and-mcp) · [Plugins](https://chang-lehung.github.io/zettcode/guide/plugins) |
124
+
125
+ ## Development
126
+
127
+ ```bash
128
+ uv sync # install dependencies
129
+ make check # Ruff, mypy, and tests
130
+ make hooks # enforce mypy before commits
131
+ make demo # browse terminal widgets
132
+ make docs # preview the user guide locally
133
+ uv run zettcode --workspace . # run from the checkout
134
+ ```
135
+
136
+ ZettCode provides the terminal application; the agent runtime is
137
+ [`zett-agent`](https://github.com/Chang-LeHung/zett-agent). Contributor notes and
138
+ invariants live in [`AGENTS.md`](AGENTS.md) and
139
+ [`docs/internal/`](docs/internal/), separately from the user guide. See
140
+ [`docs/internal/site-design.md`](docs/internal/site-design.md) for preview and
141
+ asset-generation instructions.
142
+
143
+ ## License
144
+
145
+ MIT. See [`LICENSE`](LICENSE).
@@ -0,0 +1,112 @@
1
+ <p align="center">
2
+ <img src="docs/public/logo.svg" width="88" height="88" alt="ZettCode pixel robot with a warm heart" />
3
+ </p>
4
+ <h1 align="center">ZettCode</h1>
5
+ <p align="center"><strong>Your terminal. Your coding partner.</strong></p>
6
+ <p align="center">A focused coding agent that reads your project, shows its work, and keeps you in control.</p>
7
+ <p align="center">
8
+ <strong>English</strong> · <a href="README.zh-CN.md">简体中文</a><br />
9
+ <a href="https://chang-lehung.github.io/zettcode/guide/getting-started">Get started</a> ·
10
+ <a href="https://chang-lehung.github.io/zettcode/">Documentation</a> ·
11
+ <a href="https://chang-lehung.github.io/zettcode/guide/commands">Commands</a>
12
+ </p>
13
+
14
+ <p align="center">
15
+ <img src="docs/public/terminal.svg" width="1000" alt="ZettCode showing a task, thinking, file reads, a code edit, passing tests, and a Markdown answer" />
16
+ </p>
17
+ <p align="center"><sub>Illustrative conversation, rendered with ZettCode’s actual terminal widgets.</sub></p>
18
+
19
+ ## Get running
20
+
21
+ You need **Python 3.10+**, a UTF-8 terminal, and an **OpenAI-compatible API**
22
+ (or Anthropic's **Messages API**).
23
+ Works on macOS, Linux, and Windows (use Windows Terminal).
24
+
25
+ ### 1. Install
26
+
27
+ ```bash
28
+ uv tool install zettcode
29
+ # or: pip install zettcode
30
+ ```
31
+
32
+ ### 2. Connect a model
33
+
34
+ Create `~/.zettcode/config.toml` (and its parent directory) with one model:
35
+
36
+ ```toml
37
+ [[models]]
38
+ model = "deepseek-v4-pro" # the model id sent to DeepSeek
39
+ display_model = "DeepSeek Pro" # the name shown in ZettCode
40
+ token = "sk-..." # replace with your DeepSeek API key
41
+ base_url = "https://api.deepseek.com" # DeepSeek's OpenAI-compatible API root
42
+ context_window = 1000000 # verify against the endpoint's current limits
43
+ multimodal = false # this model accepts text, not images
44
+ ```
45
+
46
+ Get a key from the [DeepSeek platform](https://platform.deepseek.com/), not from
47
+ the chat website. Alternatively, omit `token` and set `OPENAI_API_KEY` to that
48
+ key. Add more `[[models]]` entries to switch with `/model`; the first is selected
49
+ at startup. See the
50
+ [configuration reference](https://chang-lehung.github.io/zettcode/guide/config)
51
+ for complete examples, defaults, and troubleshooting.
52
+
53
+ ### 3. Start a task
54
+
55
+ ```bash
56
+ cd /path/to/project
57
+ zettcode
58
+ # or: zettcode --workspace /path/to/project
59
+ ```
60
+
61
+ Describe a change and press **Enter**. Type `/` for commands, `@` to reference a
62
+ skill, and **Ctrl-C** to stop a request. **Ctrl-D** with an empty composer exits
63
+ and prints the command to resume your session.
64
+
65
+ ## Built for the way you work
66
+
67
+ | | |
68
+ | --- | --- |
69
+ | **See every step** | Reasoning, answers, and tool calls stream as readable rows — not raw JSON. |
70
+ | **Keep the decision** | Review shell commands before they run. When the agent needs your input, choose an option or type an answer. |
71
+ | **Keep moving** | Send a steering message during a reply. Use `/btw` for a side question that stays out of later context. |
72
+ | **Come back later** | `/resume` restores a conversation; `/export` saves a readable HTML record. |
73
+ | **Understand the context** | Monitor token usage and caching, inspect `/context`, and compact when needed. |
74
+ | **Bring your tools** | Use project `AGENTS.md` instructions, skills, MCP servers, and Python plugins. |
75
+
76
+ The palette follows your terminal’s background, or your own `theme.toml`.
77
+ Select and copy text, scroll through answers, and paste images when your model
78
+ supports them.
79
+
80
+ ## Find your next step
81
+
82
+ The **[user guide](https://chang-lehung.github.io/zettcode/guide/overview)** is
83
+ available in English and [简体中文](https://chang-lehung.github.io/zettcode/zh/guide/overview).
84
+
85
+ | First time | Everyday use | Configuration & extensions |
86
+ | --- | --- | --- |
87
+ | [Getting started](https://chang-lehung.github.io/zettcode/guide/getting-started) | [Keys & mouse](https://chang-lehung.github.io/zettcode/guide/keys) | [Configuration](https://chang-lehung.github.io/zettcode/guide/config) |
88
+ | [The interface](https://chang-lehung.github.io/zettcode/guide/interface) | [Commands](https://chang-lehung.github.io/zettcode/guide/commands) | [Models & context](https://chang-lehung.github.io/zettcode/guide/models) |
89
+ | [Problems & questions](https://chang-lehung.github.io/zettcode/guide/faq) | [Sessions](https://chang-lehung.github.io/zettcode/guide/sessions) | [Project instructions](https://chang-lehung.github.io/zettcode/guide/instructions) |
90
+ | | | [Skills & MCP](https://chang-lehung.github.io/zettcode/guide/skills-and-mcp) · [Plugins](https://chang-lehung.github.io/zettcode/guide/plugins) |
91
+
92
+ ## Development
93
+
94
+ ```bash
95
+ uv sync # install dependencies
96
+ make check # Ruff, mypy, and tests
97
+ make hooks # enforce mypy before commits
98
+ make demo # browse terminal widgets
99
+ make docs # preview the user guide locally
100
+ uv run zettcode --workspace . # run from the checkout
101
+ ```
102
+
103
+ ZettCode provides the terminal application; the agent runtime is
104
+ [`zett-agent`](https://github.com/Chang-LeHung/zett-agent). Contributor notes and
105
+ invariants live in [`AGENTS.md`](AGENTS.md) and
106
+ [`docs/internal/`](docs/internal/), separately from the user guide. See
107
+ [`docs/internal/site-design.md`](docs/internal/site-design.md) for preview and
108
+ asset-generation instructions.
109
+
110
+ ## License
111
+
112
+ MIT. See [`LICENSE`](LICENSE).
@@ -0,0 +1,106 @@
1
+ <p align="center">
2
+ <img src="docs/public/logo.svg" width="88" height="88" alt="ZettCode 像素机器人,中间是一颗暖色的心" />
3
+ </p>
4
+ <h1 align="center">ZettCode</h1>
5
+ <p align="center"><strong>你的终端。你的编码伙伴。</strong></p>
6
+ <p align="center">专注的编码智能体:读懂项目、展示过程,把决定权留给你。</p>
7
+ <p align="center">
8
+ <a href="README.md">English</a> · <strong>简体中文</strong><br />
9
+ <a href="https://chang-lehung.github.io/zettcode/zh/guide/getting-started">快速开始</a> ·
10
+ <a href="https://chang-lehung.github.io/zettcode/zh/">使用文档</a> ·
11
+ <a href="https://chang-lehung.github.io/zettcode/zh/guide/commands">命令参考</a>
12
+ </p>
13
+
14
+ <p align="center">
15
+ <img src="docs/public/terminal.svg" width="1000" alt="ZettCode 依次展示任务、思考、读文件、改代码、通过的测试和 Markdown 回答" />
16
+ </p>
17
+ <p align="center"><sub>示例对话由 ZettCode 的实际终端组件渲染。</sub></p>
18
+
19
+ ## 先跑起来
20
+
21
+ 需要 **Python 3.10+**、支持 UTF-8 的终端和 **OpenAI 兼容接口**(或 Anthropic 的 **Messages API**)。
22
+ 支持 macOS、Linux 和 Windows(请使用 Windows Terminal)。
23
+
24
+ ### 1. 安装
25
+
26
+ ```bash
27
+ uv tool install zettcode
28
+ # 或者:pip install zettcode
29
+ ```
30
+
31
+ ### 2. 连接模型
32
+
33
+ 创建 `~/.zettcode/config.toml`(以及父目录),先配置一个模型:
34
+
35
+ ```toml
36
+ [[models]]
37
+ model = "deepseek-v4-pro" # 发给 DeepSeek 的模型 id
38
+ display_model = "DeepSeek Pro" # ZettCode 界面中显示的名字
39
+ token = "sk-..." # 替换成你的 DeepSeek API key
40
+ base_url = "https://api.deepseek.com" # DeepSeek 的 OpenAI 兼容接口根地址
41
+ context_window = 1000000 # 以接入点当前公布的实际限制为准
42
+ multimodal = false # 这个模型接受文本,不接受图片
43
+ ```
44
+
45
+ 在 [DeepSeek 开放平台](https://platform.deepseek.com/)创建 API key,不是聊天网页的登录信息。
46
+ 也可以省略 `token`,改用 `OPENAI_API_KEY` 环境变量保存这个 key。
47
+ 添加更多 `[[models]]`,就能用 `/model` 切换;启动时默认选择第一项。
48
+ 完整示例、默认值和排错步骤见[配置参考](https://chang-lehung.github.io/zettcode/zh/guide/config)。
49
+
50
+ ### 3. 发出任务
51
+
52
+ ```bash
53
+ cd /path/to/project
54
+ zettcode
55
+ # 或者:zettcode --workspace /path/to/project
56
+ ```
57
+
58
+ 描述要改什么,按 **Enter**。`/` 打开命令菜单,`@` 引用 skill,**Ctrl-C** 停止请求。
59
+ 输入框为空时按 **Ctrl-D** 退出,终端会打印恢复当前会话的命令。
60
+
61
+ ## 按你的方式工作
62
+
63
+ | | |
64
+ | --- | --- |
65
+ | **看清每一步** | 思考、回答和工具调用实时呈现为可读的行,不是原始 JSON。 |
66
+ | **决定权在你手上** | 执行 shell 命令前先审阅;智能体需要你的决定时,可以选选项,也可以打字回答。 |
67
+ | **工作不中断** | 回复过程中发送 steering(引导)消息;用 `/btw` 问一句,不让它进入后续上下文。 |
68
+ | **随时接着做** | `/resume` 恢复对话,`/export` 导出便于阅读的 HTML。 |
69
+ | **看懂上下文** | 查看 token 与缓存统计,用 `/context` 检查占用,在需要时压缩。 |
70
+ | **接入你的工具** | 使用项目 `AGENTS.md` 指令、skills、MCP 服务器和 Python 插件。 |
71
+
72
+ 主题跟随终端背景,也可以使用你自己的 `theme.toml`。
73
+ 选中复制文字、滚动查看回答;模型支持多模态时,还能粘贴图片。
74
+
75
+ ## 找到你的下一步
76
+
77
+ **[用户指南](https://chang-lehung.github.io/zettcode/zh/guide/overview)** 提供简体中文与
78
+ [English](https://chang-lehung.github.io/zettcode/guide/overview) 两个版本。
79
+
80
+ | 第一次使用 | 日常使用 | 配置与扩展 |
81
+ | --- | --- | --- |
82
+ | [快速开始](https://chang-lehung.github.io/zettcode/zh/guide/getting-started) | [快捷键与鼠标](https://chang-lehung.github.io/zettcode/zh/guide/keys) | [配置参考](https://chang-lehung.github.io/zettcode/zh/guide/config) |
83
+ | [认识界面](https://chang-lehung.github.io/zettcode/zh/guide/interface) | [命令参考](https://chang-lehung.github.io/zettcode/zh/guide/commands) | [模型与上下文](https://chang-lehung.github.io/zettcode/zh/guide/models) |
84
+ | [常见问题](https://chang-lehung.github.io/zettcode/zh/guide/faq) | [会话管理](https://chang-lehung.github.io/zettcode/zh/guide/sessions) | [项目指令](https://chang-lehung.github.io/zettcode/zh/guide/instructions) |
85
+ | | | [Skills 与 MCP](https://chang-lehung.github.io/zettcode/zh/guide/skills-and-mcp) · [插件](https://chang-lehung.github.io/zettcode/zh/guide/plugins) |
86
+
87
+ ## 开发
88
+
89
+ ```bash
90
+ uv sync # 安装依赖
91
+ make check # Ruff、mypy 与测试
92
+ make hooks # 每次提交前强制检查 mypy
93
+ make demo # 浏览终端组件
94
+ make docs # 本地预览使用文档
95
+ uv run zettcode --workspace . # 从源码运行
96
+ ```
97
+
98
+ ZettCode 提供终端应用,智能体运行时来自
99
+ [`zett-agent`](https://github.com/Chang-LeHung/zett-agent)。贡献者约定和不变量放在
100
+ [`AGENTS.md`](AGENTS.md) 与 [`docs/internal/`](docs/internal/),不进入用户指南。
101
+ 本地预览、重新生成效果图的方法见
102
+ [`docs/internal/site-design.md`](docs/internal/site-design.md)。
103
+
104
+ ## 许可证
105
+
106
+ MIT,见 [`LICENSE`](LICENSE)。
@@ -24,10 +24,29 @@ classifiers = [
24
24
  dependencies = [
25
25
  # The stdlib gained both of these in 3.11; older runtimes take the backports.
26
26
  "exceptiongroup>=1.2,<2; python_version < '3.11'",
27
+ # Imported directly by the session store's record and metadata codecs, so it
28
+ # is declared here rather than borrowed from the runtime that brings it today.
29
+ "pydantic>=2,<3",
27
30
  "pyperclip>=1.9,<2",
31
+ "setproctitle>=1.3.7,<2; os_name == 'posix'",
32
+ # The counter behind ``/context`` measures a request with it, and imports it
33
+ # itself: the floor matches the runtime's, so neither resolver has to fight.
34
+ "tiktoken>=0.12,<1",
28
35
  "tomli>=2,<3; python_version < '3.11'",
36
+ # The system trust store, so the release check works behind a proxy.
37
+ "truststore>=0.10,<1",
29
38
  "wcwidth>=0.2,<1",
30
- "zett-agent==0.1.10",
39
+ # A range, not a pin: 0.1.13 is the oldest runtime whose tool argument schemas
40
+ # are self-contained — Pydantic's ``$defs``/``$ref`` are expanded when the
41
+ # schema is built — and a gateway that refuses to resolve a pointer otherwise
42
+ # answers 400 to every request on its Messages route. It also keeps the two
43
+ # the floor below it was raised for: the shell tool called ``bash``, which this
44
+ # client's phrasing, colours, and approval path are keyed on, and SQLAlchemy,
45
+ # tiktoken, and httpx behind their first use, so warming a runtime costs less
46
+ # than it did. An exact pin would make zettcode fight every other tool that
47
+ # shares the dependency — including an upgrade of zett-agent itself, which pip
48
+ # would downgrade to satisfy it.
49
+ "zett-agent>=0.1.14,<0.2",
31
50
  ]
32
51
 
33
52
  [project.scripts]
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING
7
7
 
8
8
  #: The one place the version is written. ``pyproject.toml`` reads it from here
9
9
  #: and the release workflow checks the tag against it, so a bump is one edit.
10
- __version__ = "0.1.2"
10
+ __version__ = "0.1.4"
11
11
 
12
12
  #: Where each public name lives; read by :func:`__getattr__` on first use.
13
13
  _EXPORTS = {
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING
7
7
 
8
8
  #: Where each public name lives; read by :func:`__getattr__` on first use.
9
9
  _EXPORTS = {
10
- "Entry": ".transcript",
10
+ "Entry": ".entries",
11
11
  "Transcript": ".transcript",
12
12
  "TranscriptProjector": ".projection",
13
13
  "ZettCodeAgent": ".agent",
@@ -17,9 +17,10 @@ _EXPORTS = {
17
17
 
18
18
  if TYPE_CHECKING: # pragma: no cover - for type checkers, not the runtime
19
19
  from .agent import ZettCodeAgent
20
+ from .entries import Entry
20
21
  from .projection import TranscriptProjector
21
22
  from .runtime import ZettCodeRuntime
22
- from .transcript import Entry, Transcript
23
+ from .transcript import Transcript
23
24
 
24
25
 
25
26
  def __getattr__(name: str) -> object: