just-bash 0.1.5__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 (193) hide show
  1. just_bash/__init__.py +55 -0
  2. just_bash/ast/__init__.py +213 -0
  3. just_bash/ast/factory.py +320 -0
  4. just_bash/ast/types.py +953 -0
  5. just_bash/bash.py +220 -0
  6. just_bash/commands/__init__.py +23 -0
  7. just_bash/commands/argv/__init__.py +5 -0
  8. just_bash/commands/argv/argv.py +21 -0
  9. just_bash/commands/awk/__init__.py +5 -0
  10. just_bash/commands/awk/awk.py +1168 -0
  11. just_bash/commands/base64/__init__.py +5 -0
  12. just_bash/commands/base64/base64.py +138 -0
  13. just_bash/commands/basename/__init__.py +5 -0
  14. just_bash/commands/basename/basename.py +72 -0
  15. just_bash/commands/bash/__init__.py +5 -0
  16. just_bash/commands/bash/bash.py +188 -0
  17. just_bash/commands/cat/__init__.py +5 -0
  18. just_bash/commands/cat/cat.py +173 -0
  19. just_bash/commands/checksum/__init__.py +5 -0
  20. just_bash/commands/checksum/checksum.py +179 -0
  21. just_bash/commands/chmod/__init__.py +5 -0
  22. just_bash/commands/chmod/chmod.py +216 -0
  23. just_bash/commands/column/__init__.py +5 -0
  24. just_bash/commands/column/column.py +180 -0
  25. just_bash/commands/comm/__init__.py +5 -0
  26. just_bash/commands/comm/comm.py +150 -0
  27. just_bash/commands/compression/__init__.py +5 -0
  28. just_bash/commands/compression/compression.py +298 -0
  29. just_bash/commands/cp/__init__.py +5 -0
  30. just_bash/commands/cp/cp.py +149 -0
  31. just_bash/commands/curl/__init__.py +5 -0
  32. just_bash/commands/curl/curl.py +801 -0
  33. just_bash/commands/cut/__init__.py +5 -0
  34. just_bash/commands/cut/cut.py +327 -0
  35. just_bash/commands/date/__init__.py +5 -0
  36. just_bash/commands/date/date.py +258 -0
  37. just_bash/commands/diff/__init__.py +5 -0
  38. just_bash/commands/diff/diff.py +118 -0
  39. just_bash/commands/dirname/__init__.py +5 -0
  40. just_bash/commands/dirname/dirname.py +56 -0
  41. just_bash/commands/du/__init__.py +5 -0
  42. just_bash/commands/du/du.py +150 -0
  43. just_bash/commands/echo/__init__.py +5 -0
  44. just_bash/commands/echo/echo.py +125 -0
  45. just_bash/commands/env/__init__.py +5 -0
  46. just_bash/commands/env/env.py +163 -0
  47. just_bash/commands/expand/__init__.py +5 -0
  48. just_bash/commands/expand/expand.py +299 -0
  49. just_bash/commands/expr/__init__.py +5 -0
  50. just_bash/commands/expr/expr.py +273 -0
  51. just_bash/commands/file/__init__.py +5 -0
  52. just_bash/commands/file/file.py +274 -0
  53. just_bash/commands/find/__init__.py +5 -0
  54. just_bash/commands/find/find.py +623 -0
  55. just_bash/commands/fold/__init__.py +5 -0
  56. just_bash/commands/fold/fold.py +160 -0
  57. just_bash/commands/grep/__init__.py +5 -0
  58. just_bash/commands/grep/grep.py +418 -0
  59. just_bash/commands/head/__init__.py +5 -0
  60. just_bash/commands/head/head.py +167 -0
  61. just_bash/commands/help/__init__.py +5 -0
  62. just_bash/commands/help/help.py +67 -0
  63. just_bash/commands/hostname/__init__.py +5 -0
  64. just_bash/commands/hostname/hostname.py +21 -0
  65. just_bash/commands/html_to_markdown/__init__.py +5 -0
  66. just_bash/commands/html_to_markdown/html_to_markdown.py +191 -0
  67. just_bash/commands/join/__init__.py +5 -0
  68. just_bash/commands/join/join.py +252 -0
  69. just_bash/commands/jq/__init__.py +5 -0
  70. just_bash/commands/jq/jq.py +280 -0
  71. just_bash/commands/ln/__init__.py +5 -0
  72. just_bash/commands/ln/ln.py +127 -0
  73. just_bash/commands/ls/__init__.py +5 -0
  74. just_bash/commands/ls/ls.py +280 -0
  75. just_bash/commands/mkdir/__init__.py +5 -0
  76. just_bash/commands/mkdir/mkdir.py +92 -0
  77. just_bash/commands/mv/__init__.py +5 -0
  78. just_bash/commands/mv/mv.py +142 -0
  79. just_bash/commands/nl/__init__.py +5 -0
  80. just_bash/commands/nl/nl.py +180 -0
  81. just_bash/commands/od/__init__.py +5 -0
  82. just_bash/commands/od/od.py +157 -0
  83. just_bash/commands/paste/__init__.py +5 -0
  84. just_bash/commands/paste/paste.py +100 -0
  85. just_bash/commands/printf/__init__.py +5 -0
  86. just_bash/commands/printf/printf.py +157 -0
  87. just_bash/commands/pwd/__init__.py +5 -0
  88. just_bash/commands/pwd/pwd.py +23 -0
  89. just_bash/commands/read/__init__.py +5 -0
  90. just_bash/commands/read/read.py +185 -0
  91. just_bash/commands/readlink/__init__.py +5 -0
  92. just_bash/commands/readlink/readlink.py +86 -0
  93. just_bash/commands/registry.py +844 -0
  94. just_bash/commands/rev/__init__.py +5 -0
  95. just_bash/commands/rev/rev.py +74 -0
  96. just_bash/commands/rg/__init__.py +5 -0
  97. just_bash/commands/rg/rg.py +1048 -0
  98. just_bash/commands/rm/__init__.py +5 -0
  99. just_bash/commands/rm/rm.py +106 -0
  100. just_bash/commands/search_engine/__init__.py +13 -0
  101. just_bash/commands/search_engine/matcher.py +170 -0
  102. just_bash/commands/search_engine/regex.py +159 -0
  103. just_bash/commands/sed/__init__.py +5 -0
  104. just_bash/commands/sed/sed.py +863 -0
  105. just_bash/commands/seq/__init__.py +5 -0
  106. just_bash/commands/seq/seq.py +190 -0
  107. just_bash/commands/shell/__init__.py +5 -0
  108. just_bash/commands/shell/shell.py +206 -0
  109. just_bash/commands/sleep/__init__.py +5 -0
  110. just_bash/commands/sleep/sleep.py +62 -0
  111. just_bash/commands/sort/__init__.py +5 -0
  112. just_bash/commands/sort/sort.py +411 -0
  113. just_bash/commands/split/__init__.py +5 -0
  114. just_bash/commands/split/split.py +237 -0
  115. just_bash/commands/sqlite3/__init__.py +5 -0
  116. just_bash/commands/sqlite3/sqlite3_cmd.py +505 -0
  117. just_bash/commands/stat/__init__.py +5 -0
  118. just_bash/commands/stat/stat.py +150 -0
  119. just_bash/commands/strings/__init__.py +5 -0
  120. just_bash/commands/strings/strings.py +150 -0
  121. just_bash/commands/tac/__init__.py +5 -0
  122. just_bash/commands/tac/tac.py +158 -0
  123. just_bash/commands/tail/__init__.py +5 -0
  124. just_bash/commands/tail/tail.py +180 -0
  125. just_bash/commands/tar/__init__.py +5 -0
  126. just_bash/commands/tar/tar.py +1067 -0
  127. just_bash/commands/tee/__init__.py +5 -0
  128. just_bash/commands/tee/tee.py +63 -0
  129. just_bash/commands/timeout/__init__.py +5 -0
  130. just_bash/commands/timeout/timeout.py +188 -0
  131. just_bash/commands/touch/__init__.py +5 -0
  132. just_bash/commands/touch/touch.py +91 -0
  133. just_bash/commands/tr/__init__.py +5 -0
  134. just_bash/commands/tr/tr.py +297 -0
  135. just_bash/commands/tree/__init__.py +5 -0
  136. just_bash/commands/tree/tree.py +139 -0
  137. just_bash/commands/true/__init__.py +5 -0
  138. just_bash/commands/true/true.py +32 -0
  139. just_bash/commands/uniq/__init__.py +5 -0
  140. just_bash/commands/uniq/uniq.py +323 -0
  141. just_bash/commands/wc/__init__.py +5 -0
  142. just_bash/commands/wc/wc.py +169 -0
  143. just_bash/commands/which/__init__.py +5 -0
  144. just_bash/commands/which/which.py +52 -0
  145. just_bash/commands/xan/__init__.py +5 -0
  146. just_bash/commands/xan/xan.py +1663 -0
  147. just_bash/commands/xargs/__init__.py +5 -0
  148. just_bash/commands/xargs/xargs.py +136 -0
  149. just_bash/commands/yq/__init__.py +5 -0
  150. just_bash/commands/yq/yq.py +848 -0
  151. just_bash/fs/__init__.py +29 -0
  152. just_bash/fs/in_memory_fs.py +621 -0
  153. just_bash/fs/mountable_fs.py +504 -0
  154. just_bash/fs/overlay_fs.py +894 -0
  155. just_bash/fs/read_write_fs.py +455 -0
  156. just_bash/interpreter/__init__.py +37 -0
  157. just_bash/interpreter/builtins/__init__.py +92 -0
  158. just_bash/interpreter/builtins/alias.py +154 -0
  159. just_bash/interpreter/builtins/cd.py +76 -0
  160. just_bash/interpreter/builtins/control.py +127 -0
  161. just_bash/interpreter/builtins/declare.py +336 -0
  162. just_bash/interpreter/builtins/export.py +56 -0
  163. just_bash/interpreter/builtins/let.py +44 -0
  164. just_bash/interpreter/builtins/local.py +57 -0
  165. just_bash/interpreter/builtins/mapfile.py +152 -0
  166. just_bash/interpreter/builtins/misc.py +378 -0
  167. just_bash/interpreter/builtins/readonly.py +80 -0
  168. just_bash/interpreter/builtins/set.py +234 -0
  169. just_bash/interpreter/builtins/shopt.py +201 -0
  170. just_bash/interpreter/builtins/source.py +136 -0
  171. just_bash/interpreter/builtins/test.py +290 -0
  172. just_bash/interpreter/builtins/unset.py +53 -0
  173. just_bash/interpreter/conditionals.py +387 -0
  174. just_bash/interpreter/control_flow.py +381 -0
  175. just_bash/interpreter/errors.py +116 -0
  176. just_bash/interpreter/expansion.py +1156 -0
  177. just_bash/interpreter/interpreter.py +813 -0
  178. just_bash/interpreter/types.py +134 -0
  179. just_bash/network/__init__.py +1 -0
  180. just_bash/parser/__init__.py +39 -0
  181. just_bash/parser/lexer.py +948 -0
  182. just_bash/parser/parser.py +2162 -0
  183. just_bash/py.typed +0 -0
  184. just_bash/query_engine/__init__.py +83 -0
  185. just_bash/query_engine/builtins/__init__.py +1283 -0
  186. just_bash/query_engine/evaluator.py +578 -0
  187. just_bash/query_engine/parser.py +525 -0
  188. just_bash/query_engine/tokenizer.py +329 -0
  189. just_bash/query_engine/types.py +373 -0
  190. just_bash/types.py +180 -0
  191. just_bash-0.1.5.dist-info/METADATA +410 -0
  192. just_bash-0.1.5.dist-info/RECORD +193 -0
  193. just_bash-0.1.5.dist-info/WHEEL +4 -0
@@ -0,0 +1,844 @@
1
+ """Command registry with lazy loading.
2
+
3
+ Each command has an explicit loader function for import optimization.
4
+ """
5
+
6
+ from dataclasses import dataclass
7
+ from typing import Callable, Awaitable
8
+
9
+ from ..types import Command, CommandContext, ExecResult
10
+
11
+
12
+ @dataclass
13
+ class LazyCommandDef:
14
+ """Definition for a lazily-loaded command."""
15
+
16
+ name: str
17
+ load: Callable[[], Awaitable[Command]]
18
+
19
+
20
+ # Cache for loaded commands
21
+ _cache: dict[str, Command] = {}
22
+
23
+
24
+ class LazyCommand:
25
+ """A command that loads its implementation on first execution."""
26
+
27
+ def __init__(self, def_: LazyCommandDef):
28
+ self._def = def_
29
+ self.name = def_.name
30
+
31
+ async def execute(self, args: list[str], ctx: CommandContext) -> ExecResult:
32
+ """Execute the command, loading it if necessary."""
33
+ if self._def.name not in _cache:
34
+ cmd = await self._def.load()
35
+ _cache[self._def.name] = cmd
36
+ return await _cache[self._def.name].execute(args, ctx)
37
+
38
+
39
+ # All available command names
40
+ COMMAND_NAMES = [
41
+ # Basic I/O
42
+ "echo",
43
+ "cat",
44
+ "printf",
45
+ # File operations
46
+ "ls",
47
+ "mkdir",
48
+ "touch",
49
+ "rm",
50
+ "cp",
51
+ "mv",
52
+ "ln",
53
+ "chmod",
54
+ # Navigation
55
+ "pwd",
56
+ "readlink",
57
+ # File viewing
58
+ "head",
59
+ "tail",
60
+ "wc",
61
+ "stat",
62
+ # Text processing
63
+ "grep",
64
+ "fgrep",
65
+ "egrep",
66
+ "rg",
67
+ "sed",
68
+ "awk",
69
+ "sort",
70
+ "uniq",
71
+ "comm",
72
+ "cut",
73
+ "paste",
74
+ "tr",
75
+ "rev",
76
+ "nl",
77
+ "fold",
78
+ "expand",
79
+ "unexpand",
80
+ "strings",
81
+ "split",
82
+ "column",
83
+ "join",
84
+ "tee",
85
+ # Search
86
+ "find",
87
+ # Path utilities
88
+ "basename",
89
+ "dirname",
90
+ # Directory utilities
91
+ "tree",
92
+ "du",
93
+ # Environment
94
+ "env",
95
+ "printenv",
96
+ "alias",
97
+ "unalias",
98
+ "history",
99
+ # Utilities
100
+ "xargs",
101
+ "true",
102
+ "false",
103
+ "clear",
104
+ # Shell
105
+ "bash",
106
+ "sh",
107
+ # Data processing
108
+ "jq",
109
+ "base64",
110
+ "diff",
111
+ "date",
112
+ "sleep",
113
+ "timeout",
114
+ "seq",
115
+ "expr",
116
+ # Checksums
117
+ "md5sum",
118
+ "sha1sum",
119
+ "sha256sum",
120
+ # File type detection
121
+ "file",
122
+ # Help
123
+ "help",
124
+ "which",
125
+ # Misc utilities
126
+ "tac",
127
+ "hostname",
128
+ "od",
129
+ # Testing utilities
130
+ "argv.py",
131
+ # Builtins
132
+ "read",
133
+ # Compression
134
+ "gzip",
135
+ "gunzip",
136
+ "zcat",
137
+ "tar",
138
+ # Data formats
139
+ "yq",
140
+ "xan",
141
+ "sqlite3",
142
+ # HTML conversion
143
+ "html-to-markdown",
144
+ ]
145
+
146
+ # Network command names
147
+ NETWORK_COMMAND_NAMES = [
148
+ "curl",
149
+ ]
150
+
151
+ # Command loaders - statically analyzable for bundlers
152
+ _command_loaders: list[LazyCommandDef] = [
153
+ # Basic I/O
154
+ LazyCommandDef(name="echo", load=lambda: _load_echo()),
155
+ LazyCommandDef(name="cat", load=lambda: _load_cat()),
156
+ # File operations
157
+ LazyCommandDef(name="ls", load=lambda: _load_ls()),
158
+ LazyCommandDef(name="mkdir", load=lambda: _load_mkdir()),
159
+ LazyCommandDef(name="touch", load=lambda: _load_touch()),
160
+ LazyCommandDef(name="rm", load=lambda: _load_rm()),
161
+ LazyCommandDef(name="cp", load=lambda: _load_cp()),
162
+ LazyCommandDef(name="mv", load=lambda: _load_mv()),
163
+ LazyCommandDef(name="ln", load=lambda: _load_ln()),
164
+ LazyCommandDef(name="chmod", load=lambda: _load_chmod()),
165
+ # Navigation
166
+ LazyCommandDef(name="pwd", load=lambda: _load_pwd()),
167
+ # File viewing
168
+ LazyCommandDef(name="head", load=lambda: _load_head()),
169
+ LazyCommandDef(name="tail", load=lambda: _load_tail()),
170
+ LazyCommandDef(name="wc", load=lambda: _load_wc()),
171
+ # Text processing
172
+ LazyCommandDef(name="grep", load=lambda: _load_grep()),
173
+ LazyCommandDef(name="uniq", load=lambda: _load_uniq()),
174
+ LazyCommandDef(name="cut", load=lambda: _load_cut()),
175
+ LazyCommandDef(name="tr", load=lambda: _load_tr()),
176
+ LazyCommandDef(name="sort", load=lambda: _load_sort()),
177
+ LazyCommandDef(name="sed", load=lambda: _load_sed()),
178
+ LazyCommandDef(name="awk", load=lambda: _load_awk()),
179
+ # Search
180
+ LazyCommandDef(name="find", load=lambda: _load_find()),
181
+ # Utilities
182
+ LazyCommandDef(name="true", load=lambda: _load_true()),
183
+ LazyCommandDef(name="false", load=lambda: _load_false()),
184
+ # Data processing
185
+ LazyCommandDef(name="base64", load=lambda: _load_base64()),
186
+ LazyCommandDef(name="date", load=lambda: _load_date()),
187
+ LazyCommandDef(name="seq", load=lambda: _load_seq()),
188
+ LazyCommandDef(name="expr", load=lambda: _load_expr()),
189
+ # JSON processing
190
+ LazyCommandDef(name="jq", load=lambda: _load_jq()),
191
+ # High priority commands
192
+ LazyCommandDef(name="printf", load=lambda: _load_printf()),
193
+ LazyCommandDef(name="tee", load=lambda: _load_tee()),
194
+ LazyCommandDef(name="xargs", load=lambda: _load_xargs()),
195
+ LazyCommandDef(name="basename", load=lambda: _load_basename()),
196
+ LazyCommandDef(name="dirname", load=lambda: _load_dirname()),
197
+ LazyCommandDef(name="readlink", load=lambda: _load_readlink()),
198
+ LazyCommandDef(name="stat", load=lambda: _load_stat()),
199
+ LazyCommandDef(name="diff", load=lambda: _load_diff()),
200
+ # Text processing
201
+ LazyCommandDef(name="tac", load=lambda: _load_tac()),
202
+ LazyCommandDef(name="rev", load=lambda: _load_rev()),
203
+ LazyCommandDef(name="nl", load=lambda: _load_nl()),
204
+ LazyCommandDef(name="paste", load=lambda: _load_paste()),
205
+ # Environment
206
+ LazyCommandDef(name="env", load=lambda: _load_env()),
207
+ LazyCommandDef(name="printenv", load=lambda: _load_printenv()),
208
+ LazyCommandDef(name="hostname", load=lambda: _load_hostname()),
209
+ # Timing
210
+ LazyCommandDef(name="sleep", load=lambda: _load_sleep()),
211
+ LazyCommandDef(name="timeout", load=lambda: _load_timeout()),
212
+ # File utilities
213
+ LazyCommandDef(name="tree", load=lambda: _load_tree()),
214
+ LazyCommandDef(name="du", load=lambda: _load_du()),
215
+ LazyCommandDef(name="file", load=lambda: _load_file()),
216
+ LazyCommandDef(name="which", load=lambda: _load_which()),
217
+ LazyCommandDef(name="help", load=lambda: _load_help()),
218
+ # Search
219
+ LazyCommandDef(name="rg", load=lambda: _load_rg()),
220
+ # Grep variants
221
+ LazyCommandDef(name="fgrep", load=lambda: _load_fgrep()),
222
+ LazyCommandDef(name="egrep", load=lambda: _load_egrep()),
223
+ # Checksums
224
+ LazyCommandDef(name="md5sum", load=lambda: _load_md5sum()),
225
+ LazyCommandDef(name="sha1sum", load=lambda: _load_sha1sum()),
226
+ LazyCommandDef(name="sha256sum", load=lambda: _load_sha256sum()),
227
+ # Compression
228
+ LazyCommandDef(name="gzip", load=lambda: _load_gzip()),
229
+ LazyCommandDef(name="gunzip", load=lambda: _load_gunzip()),
230
+ LazyCommandDef(name="zcat", load=lambda: _load_zcat()),
231
+ # Shell utilities
232
+ LazyCommandDef(name="clear", load=lambda: _load_clear()),
233
+ LazyCommandDef(name="alias", load=lambda: _load_alias()),
234
+ LazyCommandDef(name="unalias", load=lambda: _load_unalias()),
235
+ LazyCommandDef(name="history", load=lambda: _load_history()),
236
+ # Text processing - additional
237
+ LazyCommandDef(name="expand", load=lambda: _load_expand()),
238
+ LazyCommandDef(name="unexpand", load=lambda: _load_unexpand()),
239
+ LazyCommandDef(name="fold", load=lambda: _load_fold()),
240
+ LazyCommandDef(name="column", load=lambda: _load_column()),
241
+ LazyCommandDef(name="comm", load=lambda: _load_comm()),
242
+ LazyCommandDef(name="strings", load=lambda: _load_strings()),
243
+ LazyCommandDef(name="od", load=lambda: _load_od()),
244
+ # Testing utilities
245
+ LazyCommandDef(name="argv.py", load=lambda: _load_argv()),
246
+ # Builtins
247
+ LazyCommandDef(name="read", load=lambda: _load_read()),
248
+ LazyCommandDef(name="split", load=lambda: _load_split()),
249
+ LazyCommandDef(name="join", load=lambda: _load_join()),
250
+ # Shell commands
251
+ LazyCommandDef(name="bash", load=lambda: _load_bash()),
252
+ LazyCommandDef(name="sh", load=lambda: _load_sh()),
253
+ # Archive commands
254
+ LazyCommandDef(name="tar", load=lambda: _load_tar()),
255
+ # Data format commands
256
+ LazyCommandDef(name="yq", load=lambda: _load_yq()),
257
+ # CSV toolkit
258
+ LazyCommandDef(name="xan", load=lambda: _load_xan()),
259
+ # Database
260
+ LazyCommandDef(name="sqlite3", load=lambda: _load_sqlite3()),
261
+ # HTML conversion
262
+ LazyCommandDef(name="html-to-markdown", load=lambda: _load_html_to_markdown()),
263
+ ]
264
+
265
+
266
+ async def _load_echo() -> Command:
267
+ """Load the echo command."""
268
+ from .echo.echo import EchoCommand
269
+ return EchoCommand()
270
+
271
+
272
+ async def _load_cat() -> Command:
273
+ """Load the cat command."""
274
+ from .cat.cat import CatCommand
275
+ return CatCommand()
276
+
277
+
278
+ async def _load_ls() -> Command:
279
+ """Load the ls command."""
280
+ from .ls.ls import LsCommand
281
+ return LsCommand()
282
+
283
+
284
+ async def _load_pwd() -> Command:
285
+ """Load the pwd command."""
286
+ from .pwd.pwd import PwdCommand
287
+ return PwdCommand()
288
+
289
+
290
+ async def _load_head() -> Command:
291
+ """Load the head command."""
292
+ from .head.head import HeadCommand
293
+ return HeadCommand()
294
+
295
+
296
+ async def _load_tail() -> Command:
297
+ """Load the tail command."""
298
+ from .tail.tail import TailCommand
299
+ return TailCommand()
300
+
301
+
302
+ async def _load_wc() -> Command:
303
+ """Load the wc command."""
304
+ from .wc.wc import WcCommand
305
+ return WcCommand()
306
+
307
+
308
+ async def _load_grep() -> Command:
309
+ """Load the grep command."""
310
+ from .grep.grep import GrepCommand
311
+ return GrepCommand()
312
+
313
+
314
+ async def _load_true() -> Command:
315
+ """Load the true command."""
316
+ from .true.true import TrueCommand
317
+ return TrueCommand()
318
+
319
+
320
+ async def _load_false() -> Command:
321
+ """Load the false command."""
322
+ from .true.true import FalseCommand
323
+ return FalseCommand()
324
+
325
+
326
+ async def _load_mkdir() -> Command:
327
+ """Load the mkdir command."""
328
+ from .mkdir.mkdir import MkdirCommand
329
+ return MkdirCommand()
330
+
331
+
332
+ async def _load_touch() -> Command:
333
+ """Load the touch command."""
334
+ from .touch.touch import TouchCommand
335
+ return TouchCommand()
336
+
337
+
338
+ async def _load_rm() -> Command:
339
+ """Load the rm command."""
340
+ from .rm.rm import RmCommand
341
+ return RmCommand()
342
+
343
+
344
+ async def _load_cp() -> Command:
345
+ """Load the cp command."""
346
+ from .cp.cp import CpCommand
347
+ return CpCommand()
348
+
349
+
350
+ async def _load_mv() -> Command:
351
+ """Load the mv command."""
352
+ from .mv.mv import MvCommand
353
+ return MvCommand()
354
+
355
+
356
+ async def _load_ln() -> Command:
357
+ """Load the ln command."""
358
+ from .ln.ln import LnCommand
359
+ return LnCommand()
360
+
361
+
362
+ async def _load_chmod() -> Command:
363
+ """Load the chmod command."""
364
+ from .chmod.chmod import ChmodCommand
365
+ return ChmodCommand()
366
+
367
+
368
+ async def _load_base64() -> Command:
369
+ """Load the base64 command."""
370
+ from .base64.base64 import Base64Command
371
+ return Base64Command()
372
+
373
+
374
+ async def _load_date() -> Command:
375
+ """Load the date command."""
376
+ from .date.date import DateCommand
377
+ return DateCommand()
378
+
379
+
380
+ async def _load_seq() -> Command:
381
+ """Load the seq command."""
382
+ from .seq.seq import SeqCommand
383
+ return SeqCommand()
384
+
385
+
386
+ async def _load_expr() -> Command:
387
+ """Load the expr command."""
388
+ from .expr.expr import ExprCommand
389
+ return ExprCommand()
390
+
391
+
392
+ async def _load_uniq() -> Command:
393
+ """Load the uniq command."""
394
+ from .uniq.uniq import UniqCommand
395
+ return UniqCommand()
396
+
397
+
398
+ async def _load_cut() -> Command:
399
+ """Load the cut command."""
400
+ from .cut.cut import CutCommand
401
+ return CutCommand()
402
+
403
+
404
+ async def _load_tr() -> Command:
405
+ """Load the tr command."""
406
+ from .tr.tr import TrCommand
407
+ return TrCommand()
408
+
409
+
410
+ async def _load_sort() -> Command:
411
+ """Load the sort command."""
412
+ from .sort.sort import SortCommand
413
+ return SortCommand()
414
+
415
+
416
+ async def _load_sed() -> Command:
417
+ """Load the sed command."""
418
+ from .sed.sed import SedCommand
419
+ return SedCommand()
420
+
421
+
422
+ async def _load_awk() -> Command:
423
+ """Load the awk command."""
424
+ from .awk.awk import AwkCommand
425
+ return AwkCommand()
426
+
427
+
428
+ async def _load_find() -> Command:
429
+ """Load the find command."""
430
+ from .find.find import FindCommand
431
+ return FindCommand()
432
+
433
+
434
+ async def _load_jq() -> Command:
435
+ """Load the jq command."""
436
+ from .jq.jq import JqCommand
437
+ return JqCommand()
438
+
439
+
440
+ async def _load_printf() -> Command:
441
+ """Load the printf command."""
442
+ from .printf.printf import PrintfCommand
443
+ return PrintfCommand()
444
+
445
+
446
+ async def _load_tee() -> Command:
447
+ """Load the tee command."""
448
+ from .tee.tee import TeeCommand
449
+ return TeeCommand()
450
+
451
+
452
+ async def _load_xargs() -> Command:
453
+ """Load the xargs command."""
454
+ from .xargs.xargs import XargsCommand
455
+ return XargsCommand()
456
+
457
+
458
+ async def _load_basename() -> Command:
459
+ """Load the basename command."""
460
+ from .basename.basename import BasenameCommand
461
+ return BasenameCommand()
462
+
463
+
464
+ async def _load_dirname() -> Command:
465
+ """Load the dirname command."""
466
+ from .dirname.dirname import DirnameCommand
467
+ return DirnameCommand()
468
+
469
+
470
+ async def _load_readlink() -> Command:
471
+ """Load the readlink command."""
472
+ from .readlink.readlink import ReadlinkCommand
473
+ return ReadlinkCommand()
474
+
475
+
476
+ async def _load_stat() -> Command:
477
+ """Load the stat command."""
478
+ from .stat.stat import StatCommand
479
+ return StatCommand()
480
+
481
+
482
+ async def _load_diff() -> Command:
483
+ """Load the diff command."""
484
+ from .diff.diff import DiffCommand
485
+ return DiffCommand()
486
+
487
+
488
+ async def _load_tac() -> Command:
489
+ """Load the tac command."""
490
+ from .tac.tac import TacCommand
491
+ return TacCommand()
492
+
493
+
494
+ async def _load_rev() -> Command:
495
+ """Load the rev command."""
496
+ from .rev.rev import RevCommand
497
+ return RevCommand()
498
+
499
+
500
+ async def _load_nl() -> Command:
501
+ """Load the nl command."""
502
+ from .nl.nl import NlCommand
503
+ return NlCommand()
504
+
505
+
506
+ async def _load_paste() -> Command:
507
+ """Load the paste command."""
508
+ from .paste.paste import PasteCommand
509
+ return PasteCommand()
510
+
511
+
512
+ async def _load_env() -> Command:
513
+ """Load the env command."""
514
+ from .env.env import EnvCommand
515
+ return EnvCommand()
516
+
517
+
518
+ async def _load_printenv() -> Command:
519
+ """Load the printenv command."""
520
+ from .env.env import PrintenvCommand
521
+ return PrintenvCommand()
522
+
523
+
524
+ async def _load_hostname() -> Command:
525
+ """Load the hostname command."""
526
+ from .hostname.hostname import HostnameCommand
527
+ return HostnameCommand()
528
+
529
+
530
+ async def _load_sleep() -> Command:
531
+ """Load the sleep command."""
532
+ from .sleep.sleep import SleepCommand
533
+ return SleepCommand()
534
+
535
+
536
+ async def _load_timeout() -> Command:
537
+ """Load the timeout command."""
538
+ from .timeout.timeout import TimeoutCommand
539
+ return TimeoutCommand()
540
+
541
+
542
+ async def _load_tree() -> Command:
543
+ """Load the tree command."""
544
+ from .tree.tree import TreeCommand
545
+ return TreeCommand()
546
+
547
+
548
+ async def _load_du() -> Command:
549
+ """Load the du command."""
550
+ from .du.du import DuCommand
551
+ return DuCommand()
552
+
553
+
554
+ async def _load_file() -> Command:
555
+ """Load the file command."""
556
+ from .file.file import FileCommand
557
+ return FileCommand()
558
+
559
+
560
+ async def _load_which() -> Command:
561
+ """Load the which command."""
562
+ from .which.which import WhichCommand
563
+ return WhichCommand()
564
+
565
+
566
+ async def _load_help() -> Command:
567
+ """Load the help command."""
568
+ from .help.help import HelpCommand
569
+ return HelpCommand()
570
+
571
+
572
+ async def _load_rg() -> Command:
573
+ """Load the rg command."""
574
+ from .rg.rg import RgCommand
575
+ return RgCommand()
576
+
577
+
578
+ async def _load_fgrep() -> Command:
579
+ """Load the fgrep command."""
580
+ from .grep.grep import FgrepCommand
581
+ return FgrepCommand()
582
+
583
+
584
+ async def _load_egrep() -> Command:
585
+ """Load the egrep command."""
586
+ from .grep.grep import EgrepCommand
587
+ return EgrepCommand()
588
+
589
+
590
+ async def _load_md5sum() -> Command:
591
+ """Load the md5sum command."""
592
+ from .checksum.checksum import Md5sumCommand
593
+ return Md5sumCommand()
594
+
595
+
596
+ async def _load_sha1sum() -> Command:
597
+ """Load the sha1sum command."""
598
+ from .checksum.checksum import Sha1sumCommand
599
+ return Sha1sumCommand()
600
+
601
+
602
+ async def _load_sha256sum() -> Command:
603
+ """Load the sha256sum command."""
604
+ from .checksum.checksum import Sha256sumCommand
605
+ return Sha256sumCommand()
606
+
607
+
608
+ async def _load_gzip() -> Command:
609
+ """Load the gzip command."""
610
+ from .compression.compression import GzipCommand
611
+ return GzipCommand()
612
+
613
+
614
+ async def _load_gunzip() -> Command:
615
+ """Load the gunzip command."""
616
+ from .compression.compression import GunzipCommand
617
+ return GunzipCommand()
618
+
619
+
620
+ async def _load_zcat() -> Command:
621
+ """Load the zcat command."""
622
+ from .compression.compression import ZcatCommand
623
+ return ZcatCommand()
624
+
625
+
626
+ async def _load_clear() -> Command:
627
+ """Load the clear command."""
628
+ from .shell.shell import ClearCommand
629
+ return ClearCommand()
630
+
631
+
632
+ async def _load_alias() -> Command:
633
+ """Load the alias command."""
634
+ from .shell.shell import AliasCommand
635
+ return AliasCommand()
636
+
637
+
638
+ async def _load_unalias() -> Command:
639
+ """Load the unalias command."""
640
+ from .shell.shell import UnaliasCommand
641
+ return UnaliasCommand()
642
+
643
+
644
+ async def _load_history() -> Command:
645
+ """Load the history command."""
646
+ from .shell.shell import HistoryCommand
647
+ return HistoryCommand()
648
+
649
+
650
+ async def _load_expand() -> Command:
651
+ """Load the expand command."""
652
+ from .expand.expand import ExpandCommand
653
+ return ExpandCommand()
654
+
655
+
656
+ async def _load_unexpand() -> Command:
657
+ """Load the unexpand command."""
658
+ from .expand.expand import UnexpandCommand
659
+ return UnexpandCommand()
660
+
661
+
662
+ async def _load_fold() -> Command:
663
+ """Load the fold command."""
664
+ from .fold.fold import FoldCommand
665
+ return FoldCommand()
666
+
667
+
668
+ async def _load_column() -> Command:
669
+ """Load the column command."""
670
+ from .column.column import ColumnCommand
671
+ return ColumnCommand()
672
+
673
+
674
+ async def _load_comm() -> Command:
675
+ """Load the comm command."""
676
+ from .comm.comm import CommCommand
677
+ return CommCommand()
678
+
679
+
680
+ async def _load_strings() -> Command:
681
+ """Load the strings command."""
682
+ from .strings.strings import StringsCommand
683
+ return StringsCommand()
684
+
685
+
686
+ async def _load_od() -> Command:
687
+ """Load the od command."""
688
+ from .od.od import OdCommand
689
+ return OdCommand()
690
+
691
+
692
+ async def _load_argv() -> Command:
693
+ """Load the argv.py command."""
694
+ from .argv.argv import ArgvCommand
695
+ return ArgvCommand()
696
+
697
+
698
+ async def _load_read() -> Command:
699
+ """Load the read command."""
700
+ from .read.read import ReadCommand
701
+ return ReadCommand()
702
+
703
+
704
+ async def _load_split() -> Command:
705
+ """Load the split command."""
706
+ from .split.split import SplitCommand
707
+ return SplitCommand()
708
+
709
+
710
+ async def _load_join() -> Command:
711
+ """Load the join command."""
712
+ from .join.join import JoinCommand
713
+ return JoinCommand()
714
+
715
+
716
+ async def _load_bash() -> Command:
717
+ """Load the bash command."""
718
+ from .bash.bash import BashCommand
719
+ return BashCommand()
720
+
721
+
722
+ async def _load_sh() -> Command:
723
+ """Load the sh command."""
724
+ from .bash.bash import ShCommand
725
+ return ShCommand()
726
+
727
+
728
+ async def _load_tar() -> Command:
729
+ """Load the tar command."""
730
+ from .tar.tar import TarCommand
731
+ return TarCommand()
732
+
733
+
734
+ async def _load_curl() -> Command:
735
+ """Load the curl command."""
736
+ from .curl.curl import CurlCommand
737
+ return CurlCommand()
738
+
739
+
740
+ async def _load_yq() -> Command:
741
+ """Load the yq command."""
742
+ from .yq.yq import YqCommand
743
+ return YqCommand()
744
+
745
+
746
+ async def _load_xan() -> Command:
747
+ """Load the xan command."""
748
+ from .xan.xan import XanCommand
749
+ return XanCommand()
750
+
751
+
752
+ async def _load_sqlite3() -> Command:
753
+ """Load the sqlite3 command."""
754
+ from .sqlite3.sqlite3_cmd import Sqlite3Command
755
+ return Sqlite3Command()
756
+
757
+
758
+ async def _load_html_to_markdown() -> Command:
759
+ """Load the html-to-markdown command."""
760
+ from .html_to_markdown.html_to_markdown import HtmlToMarkdownCommand
761
+ return HtmlToMarkdownCommand()
762
+
763
+
764
+ # Network command loaders
765
+ _network_command_loaders: list[LazyCommandDef] = [
766
+ LazyCommandDef(name="curl", load=lambda: _load_curl()),
767
+ ]
768
+
769
+
770
+ def get_command_names() -> list[str]:
771
+ """Get all available command names (excludes network commands)."""
772
+ return COMMAND_NAMES.copy()
773
+
774
+
775
+ def get_network_command_names() -> list[str]:
776
+ """Get all network command names."""
777
+ return NETWORK_COMMAND_NAMES.copy()
778
+
779
+
780
+ def create_lazy_commands(filter_names: list[str] | None = None) -> list[Command]:
781
+ """Create all lazy commands for registration.
782
+
783
+ Args:
784
+ filter_names: Optional list of command names to include.
785
+ If not provided, all commands are created.
786
+
787
+ Returns:
788
+ List of Command objects (lazy-loaded).
789
+ """
790
+ loaders = _command_loaders
791
+ if filter_names:
792
+ loaders = [d for d in loaders if d.name in filter_names]
793
+ return [LazyCommand(d) for d in loaders]
794
+
795
+
796
+ def create_network_lazy_commands(
797
+ filter_names: list[str] | None = None,
798
+ ) -> list[Command]:
799
+ """Create all network lazy commands for registration.
800
+
801
+ Args:
802
+ filter_names: Optional list of command names to include.
803
+ If not provided, all network commands are created.
804
+
805
+ Returns:
806
+ List of Command objects (lazy-loaded).
807
+ """
808
+ loaders = _network_command_loaders
809
+ if filter_names:
810
+ loaders = [d for d in loaders if d.name in filter_names]
811
+ return [LazyCommand(d) for d in loaders]
812
+
813
+
814
+ def create_command_registry(
815
+ filter_names: list[str] | None = None, include_network: bool = False
816
+ ) -> dict[str, Command]:
817
+ """Create a command registry dictionary.
818
+
819
+ Args:
820
+ filter_names: Optional list of command names to include.
821
+ include_network: Whether to include network commands.
822
+
823
+ Returns:
824
+ Dictionary mapping command names to Command objects.
825
+ """
826
+ commands = create_lazy_commands(filter_names)
827
+ registry = {cmd.name: cmd for cmd in commands}
828
+
829
+ if include_network:
830
+ network_commands = create_network_lazy_commands(filter_names)
831
+ for cmd in network_commands:
832
+ registry[cmd.name] = cmd
833
+
834
+ return registry
835
+
836
+
837
+ def clear_command_cache() -> None:
838
+ """Clear the command cache (for testing)."""
839
+ _cache.clear()
840
+
841
+
842
+ def get_loaded_command_count() -> int:
843
+ """Get the number of loaded commands (for testing)."""
844
+ return len(_cache)