just-cli 0.2.1__tar.gz → 0.3.1__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.
- just_cli-0.3.1/.claude/plans/2026-04-18-edit-installer-macos-micro.md +237 -0
- just_cli-0.3.1/.claude/settings.local.json +9 -0
- just_cli-0.3.1/.claude/skills/textual/README.md +139 -0
- just_cli-0.3.1/.claude/skills/textual/SKILL.md +447 -0
- just_cli-0.3.1/.claude/skills/textual/guide.md +1064 -0
- just_cli-0.3.1/.claude/skills/textual/quick-reference.md +920 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/.gitignore +4 -2
- just_cli-0.3.1/AGENTS.md +69 -0
- just_cli-0.3.1/Dockerfile +22 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/PKG-INFO +4 -2
- {just_cli-0.2.1 → just_cli-0.3.1}/README.md +1 -1
- {just_cli-0.2.1 → just_cli-0.3.1}/pyproject.toml +33 -28
- just_cli-0.3.1/scripts/system/mac/proxy/proxy.sh +136 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/scripts/system/windows/proxy/proxy.bat +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/__init__.py +12 -6
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/cli.py +105 -105
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/download.py +67 -67
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/ext/__init__.py +23 -23
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/ext/add.py +101 -101
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/ext/list.py +154 -154
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/install.py +88 -78
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/linux.py +213 -213
- just_cli-0.3.1/src/just/commands/note.py +12 -0
- just_cli-0.3.1/src/just/commands/workspace.py +24 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/config/utils.py +117 -94
- just_cli-0.3.1/src/just/core/installer/AGENTS.md +70 -0
- just_cli-0.3.1/src/just/core/installer/__init__.py +23 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/installer/decorator.py +19 -15
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/installer/install_package.py +143 -122
- just_cli-0.3.1/src/just/core/installer/installers/__init__.py +20 -0
- just_cli-0.3.1/src/just/core/installer/installers/binary_release.py +307 -0
- just_cli-0.3.1/src/just/core/installer/installers/remote_script.py +291 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/installer/package_info.py +3 -1
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/installer/source/__init__.py +5 -3
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/installer/source/base.py +2 -1
- just_cli-0.3.1/src/just/core/installer/utils.py +98 -0
- just_cli-0.3.1/src/just/installers/AGENTS.md +72 -0
- just_cli-0.3.1/src/just/installers/brew/installer.py +18 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/claude-code/installer.py +21 -21
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/cloudflare/installer.py +7 -3
- just_cli-0.3.1/src/just/installers/edit/installer.py +72 -0
- just_cli-0.3.1/src/just/installers/gh/__init__.py +1 -0
- just_cli-0.3.1/src/just/installers/gh/installer.py +49 -0
- just_cli-0.3.1/src/just/installers/miniconda3/installer.py +33 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/mssh/installer.py +14 -14
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/nvm/installer.py +29 -31
- just_cli-0.3.1/src/just/installers/openclaw/installer.py +24 -0
- just_cli-0.3.1/src/just/installers/opencode/installer.py +20 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/qodercli/installer.py +14 -14
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/tailscale/installer.py +18 -15
- just_cli-0.3.1/src/just/installers/uv/__init__.py +1 -0
- just_cli-0.3.1/src/just/installers/uv/installer.py +30 -0
- just_cli-0.3.1/src/just/tui/__init__.py +5 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/tui/extension.py +657 -657
- just_cli-0.3.1/src/just/tui/note.py +339 -0
- just_cli-0.3.1/src/just/tui/workspace.py +337 -0
- just_cli-0.3.1/src/just/utils/AGENTS.md +44 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/__init__.py +36 -36
- just_cli-0.3.1/src/just/utils/docker_utils.py +123 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/download_utils.py +551 -551
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/env_utils.py +26 -0
- just_cli-0.3.1/src/just/utils/note_utils.py +205 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/progress.py +456 -456
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/system_probe.py +8 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/user_interaction.py +24 -24
- just_cli-0.3.1/tests/AGENTS.md +54 -0
- just_cli-0.3.1/tests/test_bash_script_installer.py +240 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_download.py +130 -130
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_extension/README.md +20 -20
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_extension/test_ext.py +36 -36
- just_cli-0.3.1/tests/test_installer_e2e.py +141 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/uv.lock +105 -10
- just_cli-0.2.1/src/just/core/installer/__init__.py +0 -10
- just_cli-0.2.1/src/just/core/installer/binary.py +0 -148
- just_cli-0.2.1/src/just/core/installer/simple_release.py +0 -296
- just_cli-0.2.1/src/just/installers/edit/installer.py +0 -23
- just_cli-0.2.1/src/just/tui/__init__.py +0 -4
- just_cli-0.2.1/tests/Dockerfile +0 -23
- just_cli-0.2.1/tests/test_installer.py +0 -166
- {just_cli-0.2.1 → just_cli-0.3.1}/.github/workflows/publish.yml +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/docs/extension_guide.md +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/docs/images/editor_demo.png +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/docs/images/viewer_demo.png +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/scripts/system/linux/proxy/proxy.sh +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/scripts/system/windows/proxy/proxy.ps1 +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/edit.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/ext/edit.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/ext/remove.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/extract.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/tunnel.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/commands/view.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/config/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/config/config.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/extension/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/extension/generator.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/extension/parser.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/extension/utils.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/extension/validator.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/installer/source/http.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/installer/source/local.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/system_probe/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/system_probe/system_info.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/core/system_probe/system_probe.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/claude-code/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/cloudflare/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/docker/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/docker/installer.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/edit/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/mssh/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/nvm/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/qodercli/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/installers/tailscale/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/tui/editor.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/tui/markdown.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/archive/__init__.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/archive/compression_handler.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/archive/extractor.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/archive/format_detect.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/archive/sevenzip_handler.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/archive/tar_handler.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/archive/zip_handler.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/echo_utils.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/file_utils.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/format_utils.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/shell_utils.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/src/just/utils/typer_utils.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/requirements.txt +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/run_tests.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_archive_extraction.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_extension/test_extension_add.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_extension.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_file_utils.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_init.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_linux_commands.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_progress_utils.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/test_system_probe.py +0 -0
- {just_cli-0.2.1 → just_cli-0.3.1}/tests/testing.py +0 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# Edit Installer: macOS Support with micro Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Add macOS support to `just install edit` by installing the `micro` text editor
|
|
6
|
+
|
|
7
|
+
**Architecture:** Platform-specific branching in installer function - Windows/Linux continue using Microsoft Edit, macOS uses micro with symlink from `edit` to `micro`.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Python 3.10+, typer, just installer framework
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## File Structure
|
|
14
|
+
|
|
15
|
+
**Files to modify:**
|
|
16
|
+
- `src/just/installers/edit/installer.py` - Main installer implementation
|
|
17
|
+
|
|
18
|
+
**No new files needed.**
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Chunk 1: Update installer.py with macOS micro support
|
|
23
|
+
|
|
24
|
+
### Task 1: Modify version parameter and add platform detection
|
|
25
|
+
|
|
26
|
+
**Files:**
|
|
27
|
+
- Modify: `src/just/installers/edit/installer.py`
|
|
28
|
+
|
|
29
|
+
- [ ] **Step 1: Update the version parameter default**
|
|
30
|
+
|
|
31
|
+
Change the `version` parameter default from `"1.2.0"` to `None`:
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
def install_edit(
|
|
35
|
+
version: just.Annotated[
|
|
36
|
+
str, just.Option("-v", "--version", help="The version of Edit to install.")
|
|
37
|
+
] = None, # Changed from "1.2.0"
|
|
38
|
+
):
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- [ ] **Step 2: Add version resolution logic**
|
|
42
|
+
|
|
43
|
+
Add platform-specific default version after the function definition:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
# Resolve default version based on platform
|
|
47
|
+
if version is None:
|
|
48
|
+
if just.system.platform == "darwin":
|
|
49
|
+
version = "2.0.15" # micro latest stable
|
|
50
|
+
else:
|
|
51
|
+
version = "1.2.0" # Microsoft Edit
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- [ ] **Step 3: Update docstring**
|
|
55
|
+
|
|
56
|
+
Update the docstring to reflect macOS support:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
"""
|
|
60
|
+
Install a terminal text editor.
|
|
61
|
+
|
|
62
|
+
- Windows/Linux: Microsoft Edit
|
|
63
|
+
- macOS: micro (with 'edit' symlink)
|
|
64
|
+
"""
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- [ ] **Step 4: Commit**
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
git add src/just/installers/edit/installer.py
|
|
71
|
+
git commit -m "feat(edit): add version parameter resolution for platform defaults"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### Task 2: Add macOS branch with micro installation
|
|
77
|
+
|
|
78
|
+
**Files:**
|
|
79
|
+
- Modify: `src/just/installers/edit/installer.py`
|
|
80
|
+
|
|
81
|
+
- [ ] **Step 1: Add macOS platform branch**
|
|
82
|
+
|
|
83
|
+
Add the `elif just.system.platform == "darwin":` branch before the `else` clause:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
elif just.system.platform == "darwin":
|
|
87
|
+
# Install micro text editor for macOS
|
|
88
|
+
editor_name = "micro"
|
|
89
|
+
url = f"https://github.com/zyedidia/micro/releases/download/v{version}/micro-{version}-{just.system.arch}-darwin.tar.gz"
|
|
90
|
+
|
|
91
|
+
just.echo.info(f"Installing {editor_name} v{version} as the default editor...")
|
|
92
|
+
|
|
93
|
+
just.ArchiveInstaller(
|
|
94
|
+
url=url,
|
|
95
|
+
executables=["micro"],
|
|
96
|
+
name="micro",
|
|
97
|
+
).run()
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- [ ] **Step 2: Add edit -> micro symlink creation**
|
|
101
|
+
|
|
102
|
+
After the `ArchiveInstaller().run()` call in the macOS branch, add symlink creation:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
# Create edit -> micro symlink for consistency
|
|
106
|
+
from just.core.installer.utils import create_symlink_or_wrapper
|
|
107
|
+
from just.core.config.utils import get_bin_dir
|
|
108
|
+
|
|
109
|
+
micro_path = get_bin_dir() / "micro"
|
|
110
|
+
create_symlink_or_wrapper(
|
|
111
|
+
target=micro_path,
|
|
112
|
+
link_dir=get_bin_dir(),
|
|
113
|
+
link_name="edit"
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- [ ] **Step 3: Add info log for Windows/Linux branches**
|
|
118
|
+
|
|
119
|
+
Add `just.echo.info()` calls before `ArchiveInstaller().run()` in Windows and Linux branches:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
just.echo.info(f"Installing Microsoft Edit v{version} as the default editor...")
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
- [ ] **Step 4: Commit**
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
git add src/just/installers/edit/installer.py
|
|
129
|
+
git commit -m "feat(edit): add macOS support with micro editor"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### Task 3: Update installer decorator check command
|
|
135
|
+
|
|
136
|
+
**Files:**
|
|
137
|
+
- Modify: `src/just/installers/edit/installer.py`
|
|
138
|
+
|
|
139
|
+
- [ ] **Step 1: Update check command for platform detection**
|
|
140
|
+
|
|
141
|
+
The current `@just.installer(check="edit -v")` won't work for macOS since we install micro first.
|
|
142
|
+
Update to use a dynamic check or remove the check parameter for now:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
@just.installer(check="edit --version") # Works for both after symlink is created
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Note: `micro --version` works, and after symlink `edit --version` will invoke micro.
|
|
149
|
+
|
|
150
|
+
- [ ] **Step 2: Commit**
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
git add src/just/installers/edit/installer.py
|
|
154
|
+
git commit -m "fix(edit): update check command to work with micro"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Chunk 2: Testing
|
|
160
|
+
|
|
161
|
+
### Task 4: Manual testing on macOS
|
|
162
|
+
|
|
163
|
+
**Files:**
|
|
164
|
+
- None (manual testing)
|
|
165
|
+
|
|
166
|
+
- [ ] **Step 1: Test macOS installation**
|
|
167
|
+
|
|
168
|
+
Run on macOS:
|
|
169
|
+
```bash
|
|
170
|
+
just install edit
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Expected output:
|
|
174
|
+
```
|
|
175
|
+
Installing micro v2.0.15 as the default editor...
|
|
176
|
+
...
|
|
177
|
+
Installing micro v2.0.15 as the default editor...
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
- [ ] **Step 2: Verify edit command works**
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
edit --version
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Expected: micro version output
|
|
187
|
+
|
|
188
|
+
- [ ] **Step 3: Verify symlink exists**
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
ls -la ~/.just/bin/edit
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Expected: symlink pointing to micro
|
|
195
|
+
|
|
196
|
+
- [ ] **Step 4: Test version override**
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
just install edit -v 2.0.14
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Expected: installs specified micro version
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
### Task 5: Verify existing platforms unchanged
|
|
207
|
+
|
|
208
|
+
**Files:**
|
|
209
|
+
- None (manual testing on Windows/Linux)
|
|
210
|
+
|
|
211
|
+
- [ ] **Step 1: Test default behavior**
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
just install edit
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Expected: installs Microsoft Edit v1.2.0
|
|
218
|
+
|
|
219
|
+
- [ ] **Step 2: Test version override**
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
just install edit -v 1.1.0
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Expected: installs specified Microsoft Edit version
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Final State
|
|
230
|
+
|
|
231
|
+
After implementation, `just install edit` will:
|
|
232
|
+
|
|
233
|
+
| Platform | Editor | Default Version | Command Available |
|
|
234
|
+
|----------|--------|-----------------|-------------------|
|
|
235
|
+
| macOS | micro | 2.0.15 | `edit` (-> micro) |
|
|
236
|
+
| Windows | Microsoft Edit | 1.2.0 | `edit` |
|
|
237
|
+
| Linux | Microsoft Edit | 1.2.0 | `edit` |
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Textual Skill
|
|
2
|
+
|
|
3
|
+
Expert guidance for building TUI (Text User Interface) applications with the Textual framework.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This skill provides comprehensive knowledge about building terminal user interfaces with Textual, a modern Python framework by Textualize.io. It covers:
|
|
8
|
+
|
|
9
|
+
- **Core Concepts**: App architecture, screens, widgets, reactive programming, CSS styling
|
|
10
|
+
- **Best Practices**: Design patterns, code organization, performance optimization
|
|
11
|
+
- **Testing**: Testing strategies with pytest and Pilot
|
|
12
|
+
- **Debugging**: Development console, logging, visual debugging
|
|
13
|
+
- **Common Patterns**: Ready-to-use code templates and examples
|
|
14
|
+
- **Error Prevention**: Common pitfalls and how to avoid them
|
|
15
|
+
|
|
16
|
+
## Files
|
|
17
|
+
|
|
18
|
+
- **SKILL.md**: Main skill definition with invocation triggers and high-level guidance
|
|
19
|
+
- **quick-reference.md**: Concise cheat sheets, templates, and quick lookups
|
|
20
|
+
- **guide.md**: Comprehensive architectural guide with detailed explanations
|
|
21
|
+
- **README.md**: This file - skill documentation
|
|
22
|
+
|
|
23
|
+
## When This Skill is Invoked
|
|
24
|
+
|
|
25
|
+
Claude will automatically use this skill when you:
|
|
26
|
+
|
|
27
|
+
- Ask about building TUI applications
|
|
28
|
+
- Mention the Textual framework
|
|
29
|
+
- Need help with widgets, screens, or layouts
|
|
30
|
+
- Have questions about CSS styling (TCSS)
|
|
31
|
+
- Want to implement reactive programming
|
|
32
|
+
- Need testing guidance for Textual apps
|
|
33
|
+
- Encounter errors with Textual code
|
|
34
|
+
- Ask about TUI design patterns
|
|
35
|
+
|
|
36
|
+
## Usage Examples
|
|
37
|
+
|
|
38
|
+
**Basic Questions:**
|
|
39
|
+
- "How do I create a Textual app?"
|
|
40
|
+
- "What's the best way to organize a Textual project?"
|
|
41
|
+
- "How do I test Textual applications?"
|
|
42
|
+
|
|
43
|
+
**Specific Features:**
|
|
44
|
+
- "How do I create a modal dialog in Textual?"
|
|
45
|
+
- "What's the difference between reactive and var?"
|
|
46
|
+
- "How do I make a widget focusable?"
|
|
47
|
+
|
|
48
|
+
**Debugging:**
|
|
49
|
+
- "Why isn't my reactive attribute updating the UI?"
|
|
50
|
+
- "My test is failing - what am I doing wrong?"
|
|
51
|
+
- "How do I debug a Textual app?"
|
|
52
|
+
|
|
53
|
+
**Design & Architecture:**
|
|
54
|
+
- "What's the best state management approach for my Textual app?"
|
|
55
|
+
- "Should I use composition or inheritance for my widgets?"
|
|
56
|
+
- "How do I implement the 'attributes down, messages up' pattern?"
|
|
57
|
+
|
|
58
|
+
## Key Concepts Covered
|
|
59
|
+
|
|
60
|
+
### Architecture
|
|
61
|
+
- Event-driven message queue system
|
|
62
|
+
- DOM-like widget hierarchy
|
|
63
|
+
- Screen navigation and modes
|
|
64
|
+
- Widget lifecycle methods
|
|
65
|
+
|
|
66
|
+
### Reactive Programming
|
|
67
|
+
- Reactive attributes with auto-refresh
|
|
68
|
+
- Validation and watch methods
|
|
69
|
+
- Computed properties
|
|
70
|
+
- Data binding between widgets
|
|
71
|
+
- Recompose for dynamic layouts
|
|
72
|
+
|
|
73
|
+
### CSS Styling (TCSS)
|
|
74
|
+
- Selector types and specificity
|
|
75
|
+
- Layout with docking and FR units
|
|
76
|
+
- Theme system with semantic colors
|
|
77
|
+
- Pseudo-classes and nesting
|
|
78
|
+
- Live reload during development
|
|
79
|
+
|
|
80
|
+
### Testing
|
|
81
|
+
- pytest with async support
|
|
82
|
+
- Pilot for simulating interactions
|
|
83
|
+
- Snapshot testing (optional)
|
|
84
|
+
- Common testing patterns
|
|
85
|
+
- Best practices and pitfalls
|
|
86
|
+
|
|
87
|
+
### Best Practices
|
|
88
|
+
- "Attributes down, messages up" pattern
|
|
89
|
+
- Composition over inheritance
|
|
90
|
+
- Single responsibility principle
|
|
91
|
+
- Separation of UI and business logic
|
|
92
|
+
- Performance optimization
|
|
93
|
+
- Accessibility considerations
|
|
94
|
+
|
|
95
|
+
## Quick Start
|
|
96
|
+
|
|
97
|
+
To build a minimal Textual app:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from textual.app import App, ComposeResult
|
|
101
|
+
from textual.widgets import Header, Footer, Static
|
|
102
|
+
|
|
103
|
+
class MyApp(App):
|
|
104
|
+
def compose(self) -> ComposeResult:
|
|
105
|
+
yield Header()
|
|
106
|
+
yield Static("Hello, Textual!")
|
|
107
|
+
yield Footer()
|
|
108
|
+
|
|
109
|
+
if __name__ == "__main__":
|
|
110
|
+
MyApp().run()
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Run with:
|
|
114
|
+
```bash
|
|
115
|
+
python my_app.py
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Or use development mode for live reload:
|
|
119
|
+
```bash
|
|
120
|
+
textual run --dev my_app.py
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Resources
|
|
124
|
+
|
|
125
|
+
- **Official Documentation**: https://textual.textualize.io
|
|
126
|
+
- **GitHub**: https://github.com/Textualize/textual
|
|
127
|
+
- **Discord**: Join the Textual Discord for community support
|
|
128
|
+
|
|
129
|
+
## Skill Maintenance
|
|
130
|
+
|
|
131
|
+
This skill is based on the Textual documentation and best practices as of January 2025. The framework is actively developed, so refer to the official documentation for the latest features and changes.
|
|
132
|
+
|
|
133
|
+
### Original Source Files
|
|
134
|
+
|
|
135
|
+
This skill was created from:
|
|
136
|
+
- `textual-quick-reference.md` - Quick reference templates
|
|
137
|
+
- `textual-guide.md` - Comprehensive framework guide
|
|
138
|
+
|
|
139
|
+
These files can be updated and the skill regenerated if needed.
|