just-cli 0.3.0__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.
Files changed (135) hide show
  1. just_cli-0.3.1/.claude/plans/2026-04-18-edit-installer-macos-micro.md +237 -0
  2. just_cli-0.3.1/.claude/settings.local.json +9 -0
  3. {just_cli-0.3.0 → just_cli-0.3.1}/PKG-INFO +1 -1
  4. {just_cli-0.3.0 → just_cli-0.3.1}/pyproject.toml +1 -1
  5. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/workspace.py +5 -2
  6. just_cli-0.3.1/src/just/installers/edit/installer.py +72 -0
  7. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/tui/workspace.py +101 -8
  8. just_cli-0.3.0/.claude/settings.local.json +0 -7
  9. just_cli-0.3.0/src/just/installers/edit/installer.py +0 -31
  10. {just_cli-0.3.0 → just_cli-0.3.1}/.claude/skills/textual/README.md +0 -0
  11. {just_cli-0.3.0 → just_cli-0.3.1}/.claude/skills/textual/SKILL.md +0 -0
  12. {just_cli-0.3.0 → just_cli-0.3.1}/.claude/skills/textual/guide.md +0 -0
  13. {just_cli-0.3.0 → just_cli-0.3.1}/.claude/skills/textual/quick-reference.md +0 -0
  14. {just_cli-0.3.0 → just_cli-0.3.1}/.github/workflows/publish.yml +0 -0
  15. {just_cli-0.3.0 → just_cli-0.3.1}/.gitignore +0 -0
  16. {just_cli-0.3.0 → just_cli-0.3.1}/AGENTS.md +0 -0
  17. {just_cli-0.3.0 → just_cli-0.3.1}/Dockerfile +0 -0
  18. {just_cli-0.3.0 → just_cli-0.3.1}/README.md +0 -0
  19. {just_cli-0.3.0 → just_cli-0.3.1}/docs/extension_guide.md +0 -0
  20. {just_cli-0.3.0 → just_cli-0.3.1}/docs/images/editor_demo.png +0 -0
  21. {just_cli-0.3.0 → just_cli-0.3.1}/docs/images/viewer_demo.png +0 -0
  22. {just_cli-0.3.0 → just_cli-0.3.1}/scripts/system/linux/proxy/proxy.sh +0 -0
  23. {just_cli-0.3.0 → just_cli-0.3.1}/scripts/system/mac/proxy/proxy.sh +0 -0
  24. {just_cli-0.3.0 → just_cli-0.3.1}/scripts/system/windows/proxy/proxy.bat +0 -0
  25. {just_cli-0.3.0 → just_cli-0.3.1}/scripts/system/windows/proxy/proxy.ps1 +0 -0
  26. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/__init__.py +0 -0
  27. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/cli.py +0 -0
  28. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/__init__.py +0 -0
  29. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/download.py +0 -0
  30. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/edit.py +0 -0
  31. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/ext/__init__.py +0 -0
  32. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/ext/add.py +0 -0
  33. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/ext/edit.py +0 -0
  34. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/ext/list.py +0 -0
  35. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/ext/remove.py +0 -0
  36. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/extract.py +0 -0
  37. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/install.py +0 -0
  38. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/linux.py +0 -0
  39. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/note.py +0 -0
  40. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/tunnel.py +0 -0
  41. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/commands/view.py +0 -0
  42. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/__init__.py +0 -0
  43. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/config/__init__.py +0 -0
  44. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/config/config.py +0 -0
  45. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/config/utils.py +0 -0
  46. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/extension/__init__.py +0 -0
  47. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/extension/generator.py +0 -0
  48. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/extension/parser.py +0 -0
  49. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/extension/utils.py +0 -0
  50. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/extension/validator.py +0 -0
  51. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/AGENTS.md +0 -0
  52. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/__init__.py +0 -0
  53. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/decorator.py +0 -0
  54. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/install_package.py +0 -0
  55. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/installers/__init__.py +0 -0
  56. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/installers/binary_release.py +0 -0
  57. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/installers/remote_script.py +0 -0
  58. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/package_info.py +0 -0
  59. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/source/__init__.py +0 -0
  60. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/source/base.py +0 -0
  61. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/source/http.py +0 -0
  62. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/source/local.py +0 -0
  63. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/installer/utils.py +0 -0
  64. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/system_probe/__init__.py +0 -0
  65. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/system_probe/system_info.py +0 -0
  66. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/core/system_probe/system_probe.py +0 -0
  67. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/AGENTS.md +0 -0
  68. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/__init__.py +0 -0
  69. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/brew/installer.py +0 -0
  70. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/claude-code/__init__.py +0 -0
  71. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/claude-code/installer.py +0 -0
  72. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/cloudflare/__init__.py +0 -0
  73. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/cloudflare/installer.py +0 -0
  74. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/docker/__init__.py +0 -0
  75. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/docker/installer.py +0 -0
  76. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/edit/__init__.py +0 -0
  77. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/gh/__init__.py +0 -0
  78. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/gh/installer.py +0 -0
  79. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/miniconda3/installer.py +0 -0
  80. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/mssh/__init__.py +0 -0
  81. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/mssh/installer.py +0 -0
  82. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/nvm/__init__.py +0 -0
  83. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/nvm/installer.py +0 -0
  84. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/openclaw/installer.py +0 -0
  85. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/opencode/installer.py +0 -0
  86. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/qodercli/__init__.py +0 -0
  87. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/qodercli/installer.py +0 -0
  88. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/tailscale/__init__.py +0 -0
  89. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/tailscale/installer.py +0 -0
  90. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/uv/__init__.py +0 -0
  91. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/installers/uv/installer.py +0 -0
  92. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/tui/__init__.py +0 -0
  93. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/tui/editor.py +0 -0
  94. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/tui/extension.py +0 -0
  95. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/tui/markdown.py +0 -0
  96. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/tui/note.py +0 -0
  97. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/AGENTS.md +0 -0
  98. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/__init__.py +0 -0
  99. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/archive/__init__.py +0 -0
  100. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/archive/compression_handler.py +0 -0
  101. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/archive/extractor.py +0 -0
  102. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/archive/format_detect.py +0 -0
  103. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/archive/sevenzip_handler.py +0 -0
  104. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/archive/tar_handler.py +0 -0
  105. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/archive/zip_handler.py +0 -0
  106. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/docker_utils.py +0 -0
  107. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/download_utils.py +0 -0
  108. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/echo_utils.py +0 -0
  109. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/env_utils.py +0 -0
  110. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/file_utils.py +0 -0
  111. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/format_utils.py +0 -0
  112. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/note_utils.py +0 -0
  113. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/progress.py +0 -0
  114. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/shell_utils.py +0 -0
  115. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/system_probe.py +0 -0
  116. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/typer_utils.py +0 -0
  117. {just_cli-0.3.0 → just_cli-0.3.1}/src/just/utils/user_interaction.py +0 -0
  118. {just_cli-0.3.0 → just_cli-0.3.1}/tests/AGENTS.md +0 -0
  119. {just_cli-0.3.0 → just_cli-0.3.1}/tests/requirements.txt +0 -0
  120. {just_cli-0.3.0 → just_cli-0.3.1}/tests/run_tests.py +0 -0
  121. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_archive_extraction.py +0 -0
  122. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_bash_script_installer.py +0 -0
  123. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_download.py +0 -0
  124. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_extension/README.md +0 -0
  125. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_extension/test_ext.py +0 -0
  126. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_extension/test_extension_add.py +0 -0
  127. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_extension.py +0 -0
  128. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_file_utils.py +0 -0
  129. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_init.py +0 -0
  130. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_installer_e2e.py +0 -0
  131. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_linux_commands.py +0 -0
  132. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_progress_utils.py +0 -0
  133. {just_cli-0.3.0 → just_cli-0.3.1}/tests/test_system_probe.py +0 -0
  134. {just_cli-0.3.0 → just_cli-0.3.1}/tests/testing.py +0 -0
  135. {just_cli-0.3.0 → just_cli-0.3.1}/uv.lock +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,9 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "mcp__web-search-prime__web_search_prime",
5
+ "mcp__web-reader__webReader",
6
+ "mcp__context7__query-docs"
7
+ ]
8
+ }
9
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: just-cli
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: Your all-in-one CLI Toolkit
5
5
  Author-email: zzzcb <zjxs.zzzcb@gmail.com>
6
6
  Requires-Python: >=3.10
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "just-cli"
3
- version = "0.3.0"
3
+ version = "0.3.1"
4
4
  description = "Your all-in-one CLI Toolkit"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,4 +1,7 @@
1
1
  from pathlib import Path
2
+ from typing_extensions import Annotated
3
+
4
+ import typer
2
5
 
3
6
  from just import just_cli, capture_exception
4
7
  from just.tui.workspace import WorkspaceApp
@@ -7,12 +10,12 @@ from just.tui.workspace import WorkspaceApp
7
10
  @just_cli.command(name="code")
8
11
  @capture_exception
9
12
  def workspace_command(
10
- path: str = ".",
13
+ workdir: Annotated[str, typer.Argument(help="Working directory")] = ".",
11
14
  ):
12
15
  """
13
16
  Open a VSCode-style workspace editor.
14
17
  """
15
- workspace_path = Path(path).resolve()
18
+ workspace_path = Path(workdir).resolve()
16
19
  if not workspace_path.exists():
17
20
  print(f"Error: Path does not exist: {workspace_path}")
18
21
  return
@@ -0,0 +1,72 @@
1
+ import just
2
+
3
+ from just.core.installer.utils import create_symlink_or_wrapper
4
+ from just.core.config.utils import get_bin_dir
5
+
6
+
7
+ @just.installer(check="edit -v")
8
+ def install_edit(
9
+ version: just.Annotated[
10
+ str, just.Option("-v", "--version", help="The version of Edit to install.")
11
+ ] = None,
12
+ ):
13
+ """
14
+ Install a terminal text editor.
15
+
16
+ - Windows/Linux: Microsoft Edit
17
+ - macOS: micro (with 'edit' symlink)
18
+ """
19
+ # Resolve default version based on platform
20
+ if version is None:
21
+ if just.system.platform == "darwin":
22
+ version = "2.0.15" # micro latest stable
23
+ else:
24
+ version = "1.2.0" # Microsoft Edit
25
+
26
+ if just.system.platform == "windows":
27
+ just.echo.info(f"Installing Microsoft Edit v{version} as the default editor...")
28
+ url = f"https://github.com/microsoft/edit/releases/download/v{version}/edit-{version}-{just.system.arch}-windows.zip"
29
+ just.ArchiveInstaller(
30
+ url=url,
31
+ executables=["edit.exe"],
32
+ name="edit",
33
+ ).run()
34
+ elif just.system.platform == "linux":
35
+ just.echo.info(f"Installing Microsoft Edit v{version} as the default editor...")
36
+ url = f"https://github.com/microsoft/edit/releases/download/v{version}/edit-{version}-{just.system.arch}-linux-gnu.tar.zst"
37
+ just.ArchiveInstaller(
38
+ url,
39
+ executables=["edit"],
40
+ name="edit",
41
+ ).run()
42
+ elif just.system.platform == "darwin":
43
+ # Install micro text editor for macOS
44
+ editor_name = "micro"
45
+ # Map architecture to micro's platform naming
46
+ micro_platform = "macos-arm64" if just.system.arch == "aarch64" else "osx"
47
+ url = f"https://github.com/micro-editor/micro/releases/download/v{version}/micro-{version}-{micro_platform}.tar.gz"
48
+
49
+ just.echo.info(f"Installing {editor_name} v{version} as the default editor...")
50
+
51
+ just.ArchiveInstaller(
52
+ url=url,
53
+ executables=["micro"],
54
+ name="micro",
55
+ ).run()
56
+
57
+ # Create edit -> micro symlink for consistency
58
+ micro_path = get_bin_dir() / "micro"
59
+
60
+ # Verify micro was installed successfully before creating symlink
61
+ if not micro_path.exists():
62
+ raise RuntimeError(f"micro installation failed - executable not found at {micro_path}")
63
+
64
+ create_symlink_or_wrapper(
65
+ target=micro_path,
66
+ link_dir=get_bin_dir(),
67
+ link_name="edit"
68
+ )
69
+ else:
70
+ raise NotImplementedError(
71
+ f"No editor is available for {just.system.platform}."
72
+ )
@@ -1,12 +1,106 @@
1
1
  """Minimal workspace editor with file tree and editor"""
2
2
 
3
3
  from pathlib import Path
4
+ from typing import Iterable
4
5
 
5
6
  from textual.app import App, ComposeResult
6
7
  from textual.binding import Binding
7
8
  from textual.containers import Horizontal, Vertical
8
9
  from textual.screen import ModalScreen
9
- from textual.widgets import DirectoryTree, TextArea, Input, Button, Label
10
+ from textual.widgets import DirectoryTree, TextArea, Input, Button, Label, Footer
11
+ from rich.text import Text
12
+
13
+
14
+ class IconDirectoryTree(DirectoryTree):
15
+ """DirectoryTree with custom file type icons."""
16
+
17
+ # File icon mapping by extension
18
+ FILE_ICONS: dict[str, str] = {
19
+ # Python
20
+ ".py": "🐍",
21
+ # JavaScript/TypeScript
22
+ ".js": "📜",
23
+ ".ts": "📜",
24
+ ".jsx": "📜",
25
+ ".tsx": "📜",
26
+ # Config files
27
+ ".json": "⚙️",
28
+ ".yaml": "⚙️",
29
+ ".yml": "⚙️",
30
+ ".toml": "⚙️",
31
+ ".xml": "⚙️",
32
+ ".ini": "⚙️",
33
+ ".conf": "⚙️",
34
+ ".cfg": "⚙️",
35
+ # Markdown
36
+ ".md": "📝",
37
+ ".markdown": "📝",
38
+ # Text
39
+ ".txt": "📄",
40
+ # Styles
41
+ ".css": "🎨",
42
+ ".scss": "🎨",
43
+ ".sass": "🎨",
44
+ ".less": "🎨",
45
+ # HTML
46
+ ".html": "🌐",
47
+ ".htm": "🌐",
48
+ # Shell
49
+ ".sh": "🖥️",
50
+ ".bash": "🖥️",
51
+ ".zsh": "🖥️",
52
+ ".fish": "🖥️",
53
+ # Rust
54
+ ".rs": "🦀",
55
+ # Go
56
+ ".go": "🐹",
57
+ # Java
58
+ ".java": "☕",
59
+ # C/C++
60
+ ".c": "🏗️",
61
+ ".cpp": "🏗️",
62
+ ".h": "🏗️",
63
+ ".hpp": "🏗️",
64
+ ".cc": "🏗️",
65
+ ".cxx": "🏗️",
66
+ # Other common files
67
+ ".lock": "🔒",
68
+ ".gitignore": "🙈",
69
+ ".env": "🔐",
70
+ "dockerfile": "🐳",
71
+ "dockerignore": "🐳",
72
+ "makefile": "🛠️",
73
+ # Fallback
74
+ "": "📄",
75
+ }
76
+
77
+ def render_label(
78
+ self, node, base_style: str, style: str
79
+ ) -> Text:
80
+ """Render label with custom icon based on file extension."""
81
+ if node.data is None:
82
+ return Text("")
83
+
84
+ # node.data is DirEntry, which has a path attribute
85
+ entry = node.data
86
+ path = entry.path
87
+
88
+ if path.is_dir():
89
+ # Folder icon
90
+ return Text(f"📁 {path.name}")
91
+
92
+ # Get file extension
93
+ ext = path.suffix.lower()
94
+ name_lower = path.name.lower()
95
+
96
+ # Check for special files by name
97
+ if name_lower in self.FILE_ICONS:
98
+ icon = self.FILE_ICONS[name_lower]
99
+ else:
100
+ # Check by extension
101
+ icon = self.FILE_ICONS.get(ext, self.FILE_ICONS[""])
102
+
103
+ return Text(f"{icon} {path.name}")
10
104
 
11
105
 
12
106
  class InputDialog(ModalScreen[str]):
@@ -160,8 +254,8 @@ class WorkspaceApp(App):
160
254
  BINDINGS = [
161
255
  Binding("ctrl+s", "save", "Save"),
162
256
  Binding("ctrl+n", "new", "New"),
163
- Binding("d", "delete", "Delete"),
164
- Binding("q", "quit", "Quit"),
257
+ Binding("ctrl+d", "delete", "Delete"),
258
+ Binding("escape", "quit", "ESC"),
165
259
  ]
166
260
 
167
261
  def __init__(self, path: str = "."):
@@ -172,8 +266,9 @@ class WorkspaceApp(App):
172
266
  def compose(self) -> ComposeResult:
173
267
  with Horizontal():
174
268
  with Vertical(id="sidebar"):
175
- yield DirectoryTree(self.workspace_path)
269
+ yield IconDirectoryTree(self.workspace_path)
176
270
  yield CodeEditor(Path("/dev/null"), id="editor")
271
+ yield Footer()
177
272
 
178
273
  def on_mount(self) -> None:
179
274
  self.title = str(self.workspace_path)
@@ -201,13 +296,11 @@ class WorkspaceApp(App):
201
296
  def _create_note(self, name: str) -> None:
202
297
  if not name:
203
298
  return
204
- if not name.endswith(".md"):
205
- name += ".md"
206
299
  file_path = self.workspace_path / name
207
300
  if file_path.exists():
208
301
  self.notify("File already exists", severity="error")
209
302
  return
210
- file_path.write_text(f"# {name[:-3]}\n\n", encoding="utf-8")
303
+ file_path.write_text("", encoding="utf-8")
211
304
  self._refresh_tree()
212
305
  self._open_file(file_path)
213
306
 
@@ -233,7 +326,7 @@ class WorkspaceApp(App):
233
326
  self.notify("Deleted")
234
327
 
235
328
  def _refresh_tree(self) -> None:
236
- tree = self.query_one(DirectoryTree)
329
+ tree = self.query_one(IconDirectoryTree)
237
330
  tree.reload()
238
331
 
239
332
  def _open_file(self, file_path: Path) -> None:
@@ -1,7 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "mcp__web-search-prime__web_search_prime"
5
- ]
6
- }
7
- }
@@ -1,31 +0,0 @@
1
- import just
2
-
3
-
4
- @just.installer(check="edit -v")
5
- def install_edit(
6
- version: just.Annotated[
7
- str, just.Option("-v", "--version", help="The version of Edit to install.")
8
- ] = "1.2.0",
9
- ):
10
- """
11
- Install Microsoft Edit.
12
- """
13
-
14
- if just.system.platform == "windows":
15
- url = f"https://github.com/microsoft/edit/releases/download/v{version}/edit-{version}-{just.system.arch}-windows.zip"
16
- just.ArchiveInstaller(
17
- url=url,
18
- executables=["edit.exe"],
19
- name="edit",
20
- ).run()
21
- elif just.system.platform == "linux":
22
- url = f"https://github.com/microsoft/edit/releases/download/v{version}/edit-{version}-{just.system.arch}-linux-gnu.tar.zst"
23
- just.ArchiveInstaller(
24
- url,
25
- executables=["edit"],
26
- name="edit",
27
- ).run()
28
- else:
29
- raise NotImplementedError(
30
- f"Microsoft Edit is not supported on {just.system.platform}."
31
- )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes