cmdbox-cli 1.0.0__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 (112) hide show
  1. cmdbox/__init__.py +0 -0
  2. cmdbox/cli/__init__.py +0 -0
  3. cmdbox/cli/app.py +125 -0
  4. cmdbox/cli/commands/__init__.py +0 -0
  5. cmdbox/cli/commands/alias_fallback.py +102 -0
  6. cmdbox/cli/commands/command_crud.py +429 -0
  7. cmdbox/cli/commands/command_run.py +255 -0
  8. cmdbox/cli/commands/history.py +109 -0
  9. cmdbox/cli/commands/init.py +54 -0
  10. cmdbox/cli/commands/settings.py +62 -0
  11. cmdbox/cli/commands/tag_crud.py +277 -0
  12. cmdbox/cli/commands/variable_crud.py +349 -0
  13. cmdbox/cli/common/__init__.py +0 -0
  14. cmdbox/cli/common/errors.py +58 -0
  15. cmdbox/cli/common/update_fields.py +88 -0
  16. cmdbox/cli/completions/__init__.py +0 -0
  17. cmdbox/cli/completions/commands.py +26 -0
  18. cmdbox/cli/completions/fields.py +31 -0
  19. cmdbox/cli/completions/tags.py +24 -0
  20. cmdbox/cli/completions/variables.py +26 -0
  21. cmdbox/cli/handlers/__init__.py +0 -0
  22. cmdbox/cli/handlers/command_handlers.py +357 -0
  23. cmdbox/cli/handlers/common_handlers.py +15 -0
  24. cmdbox/cli/handlers/history_handlers.py +94 -0
  25. cmdbox/cli/handlers/init_handler.py +127 -0
  26. cmdbox/cli/handlers/run_handler.py +178 -0
  27. cmdbox/cli/handlers/settings_handler.py +59 -0
  28. cmdbox/cli/handlers/tag_handlers.py +220 -0
  29. cmdbox/cli/handlers/variable_handlers.py +272 -0
  30. cmdbox/cli/prompts/__init__.py +0 -0
  31. cmdbox/cli/prompts/completers.py +161 -0
  32. cmdbox/cli/prompts/prompts.py +108 -0
  33. cmdbox/cli/prompts/validators.py +46 -0
  34. cmdbox/cli/ui/__init__.py +0 -0
  35. cmdbox/cli/ui/console.py +31 -0
  36. cmdbox/cli/ui/editor.py +141 -0
  37. cmdbox/cli/ui/presenters/__init__.py +0 -0
  38. cmdbox/cli/ui/presenters/app_presenter.py +8 -0
  39. cmdbox/cli/ui/presenters/command_presenter.py +168 -0
  40. cmdbox/cli/ui/presenters/history_presenter.py +83 -0
  41. cmdbox/cli/ui/presenters/init_instructions.py +52 -0
  42. cmdbox/cli/ui/presenters/init_presenter.py +57 -0
  43. cmdbox/cli/ui/presenters/result_presenter.py +144 -0
  44. cmdbox/cli/ui/presenters/settings_presenter.py +130 -0
  45. cmdbox/cli/ui/presenters/tag_presenter.py +97 -0
  46. cmdbox/cli/ui/presenters/variable_presenter.py +103 -0
  47. cmdbox/cli/ui/primitives.py +410 -0
  48. cmdbox/cli/ui/theme.py +43 -0
  49. cmdbox/cli/ui/theme_builder.py +49 -0
  50. cmdbox/common/__init__.py +0 -0
  51. cmdbox/common/io.py +34 -0
  52. cmdbox/container.py +156 -0
  53. cmdbox/core/__init__.py +0 -0
  54. cmdbox/core/fields.py +48 -0
  55. cmdbox/core/paths.py +52 -0
  56. cmdbox/database.py +65 -0
  57. cmdbox/exceptions.py +10 -0
  58. cmdbox/init/__init__.py +0 -0
  59. cmdbox/init/detect.py +82 -0
  60. cmdbox/init/integrations/bash.sh +10 -0
  61. cmdbox/init/integrations/cmd.bat +14 -0
  62. cmdbox/init/integrations/fish.fish +11 -0
  63. cmdbox/init/integrations/powershell.ps1 +14 -0
  64. cmdbox/init/integrations/zsh.sh +10 -0
  65. cmdbox/init/io.py +68 -0
  66. cmdbox/init/specs.py +54 -0
  67. cmdbox/logging_setup/__init__.py +0 -0
  68. cmdbox/logging_setup/log_config.py +123 -0
  69. cmdbox/logging_setup/log_decorators.py +40 -0
  70. cmdbox/logging_setup/log_handlers.py +94 -0
  71. cmdbox/migrations/__init__.py +1 -0
  72. cmdbox/migrations/errors.py +10 -0
  73. cmdbox/migrations/runner.py +127 -0
  74. cmdbox/migrations/versions/__init__.py +0 -0
  75. cmdbox/models.py +165 -0
  76. cmdbox/repositories/__init__.py +0 -0
  77. cmdbox/repositories/base_repository.py +181 -0
  78. cmdbox/repositories/command_repository.py +391 -0
  79. cmdbox/repositories/errors.py +120 -0
  80. cmdbox/repositories/history_repository.py +155 -0
  81. cmdbox/repositories/results.py +37 -0
  82. cmdbox/repositories/tag_repository.py +91 -0
  83. cmdbox/repositories/validators.py +256 -0
  84. cmdbox/repositories/variable_repository.py +324 -0
  85. cmdbox/resolve/__init__.py +0 -0
  86. cmdbox/resolve/errors.py +65 -0
  87. cmdbox/resolve/lookup.py +137 -0
  88. cmdbox/resolve/resolver.py +402 -0
  89. cmdbox/resolve/type_defs.py +96 -0
  90. cmdbox/runtime/__init__.py +0 -0
  91. cmdbox/runtime/executor.py +454 -0
  92. cmdbox/runtime/results.py +25 -0
  93. cmdbox/runtime/shell.py +90 -0
  94. cmdbox/services/__init__.py +0 -0
  95. cmdbox/services/command_services.py +261 -0
  96. cmdbox/services/errors.py +37 -0
  97. cmdbox/services/field_selection.py +162 -0
  98. cmdbox/services/history_service.py +68 -0
  99. cmdbox/services/run_service.py +204 -0
  100. cmdbox/services/tag_services.py +134 -0
  101. cmdbox/services/variable_services.py +224 -0
  102. cmdbox/settings/__init__.py +0 -0
  103. cmdbox/settings/models.py +129 -0
  104. cmdbox/settings/settings_repository.py +36 -0
  105. cmdbox/settings/settings_service.py +144 -0
  106. cmdbox/version.py +1 -0
  107. cmdbox_cli-1.0.0.dist-info/METADATA +125 -0
  108. cmdbox_cli-1.0.0.dist-info/RECORD +112 -0
  109. cmdbox_cli-1.0.0.dist-info/WHEEL +5 -0
  110. cmdbox_cli-1.0.0.dist-info/entry_points.txt +2 -0
  111. cmdbox_cli-1.0.0.dist-info/licenses/LICENSE +21 -0
  112. cmdbox_cli-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,36 @@
1
+ from pathlib import Path
2
+ from tomlkit import dumps, parse, document
3
+
4
+ from cmdbox.common.io import atomic_write_text
5
+
6
+
7
+ class SettingsRepository:
8
+ """
9
+ Handles loading and saving settings to a file.
10
+
11
+ Provides functionality to persist and retrieve application settings from a file
12
+ on the filesystem. The settings are managed as a dictionary and stored in a
13
+ structured format.
14
+
15
+ Attributes:
16
+ path (Path): Path to the file where settings are stored.
17
+ """
18
+
19
+ def __init__(self, path: Path):
20
+ self.path = path
21
+
22
+ def load(self) -> dict:
23
+ if not self.path.exists():
24
+ return {}
25
+ doc = parse(self.path.read_text(encoding="utf-8"))
26
+ return doc.unwrap()
27
+
28
+ def save(self, data: dict) -> None:
29
+ doc = document()
30
+ doc.update(data)
31
+ atomic_write_text(self.path, dumps(doc), encoding="utf-8")
32
+
33
+ def dict_to_text(self, data: dict) -> str:
34
+ doc = document()
35
+ doc.update(data)
36
+ return dumps(doc)
@@ -0,0 +1,144 @@
1
+ from dataclasses import asdict, is_dataclass, fields
2
+ from tomlkit import parse
3
+
4
+ from cmdbox.cli.ui.editor import EditCanceled
5
+ from cmdbox.settings.models import Settings
6
+ from cmdbox.settings.settings_repository import SettingsRepository
7
+
8
+
9
+ def build_dataclass(cls, data: dict):
10
+ """
11
+ Builds an instance of the given dataclass type populated with the provided
12
+ data dictionary. This function recursively handles nested dataclasses,
13
+ ensuring that each property is assigned correctly, even if the value
14
+ is itself a dictionary representing another dataclass.
15
+
16
+ Args:
17
+ cls: The dataclass type to instantiate.
18
+ data (dict): The dictionary containing data to populate the dataclass.
19
+
20
+ Returns:
21
+ Any: An instance of the provided dataclass, populated with the provided data.
22
+ """
23
+ kwargs = {}
24
+ for f in fields(cls):
25
+ if f.name not in data:
26
+ continue
27
+ v = data[f.name]
28
+ t = f.type
29
+ if is_dataclass(t) and isinstance(v, dict):
30
+ kwargs[f.name] = build_dataclass(t, v)
31
+ else:
32
+ kwargs[f.name] = v
33
+ return cls(**kwargs)
34
+
35
+
36
+ class SettingsService:
37
+ """
38
+ Manages application settings, providing functionality to load, update, and reload
39
+ settings dynamically.
40
+
41
+ This class serves as a service layer between a settings repository and the application,
42
+ allowing for the merging of default settings with those persisted in a repository.
43
+ It ensures that the latest settings are always available and maintains the current
44
+ state of the settings in memory.
45
+
46
+ Attributes:
47
+ repo (SettingsRepository): The repository interface used to persist and load settings.
48
+ defaults (Settings): The default settings structure applied when no overrides are
49
+ provided by the repository.
50
+ current (Settings): The in-memory representation of the current active settings,
51
+ updated after every load, reload, or update operation.
52
+ """
53
+
54
+ def __init__(self, repo: SettingsRepository, defaults: Settings | None = None):
55
+ self._repo = repo
56
+ self._defaults = defaults or Settings()
57
+ self._current = self._load()
58
+
59
+ def _load(self) -> Settings:
60
+ raw = self._repo.load()
61
+ merged = self._merge(asdict(self._defaults), raw)
62
+ return build_dataclass(Settings, merged)
63
+
64
+ def get(self) -> Settings:
65
+ return self._current
66
+
67
+ def reload(self) -> Settings:
68
+ self._current = self._load()
69
+ return self._current
70
+
71
+ def update(self, patch: dict) -> Settings:
72
+ """
73
+ Updates the settings by merging the given patch with existing settings and saving the result.
74
+
75
+ This method applies a provided patch (a dictionary) to the current settings. It first merges
76
+ the default settings with those loaded from the repository, then applies the patch on top of
77
+ this merged result. The updated settings are saved back to the repository, and the current
78
+ settings are reloaded to reflect these changes.
79
+
80
+ Args:
81
+ patch (dict): A dictionary containing new settings to be merged with the existing settings.
82
+
83
+ Returns:
84
+ Settings: An updated instance of the settings after applying the patch.
85
+ """
86
+ current_raw = self._merge(asdict(self._defaults), self._repo.load())
87
+ new_raw = self._merge(current_raw, patch)
88
+ self._repo.save(new_raw)
89
+ self._current = self._load()
90
+ return self._current
91
+
92
+ def edit(self, edit_text_fn) -> Settings:
93
+ merged = self._merge(asdict(self._defaults), self._repo.load())
94
+ initial_text = self._repo.dict_to_text(merged)
95
+
96
+ try:
97
+ edited_text = edit_text_fn(initial_text)
98
+ except EditCanceled:
99
+ raise
100
+
101
+ if edited_text == initial_text:
102
+ return self._current
103
+
104
+ try:
105
+ doc = parse(edited_text)
106
+ edited_raw = doc.unwrap()
107
+ except Exception as exc:
108
+ raise ValueError(f"Invalid TOML: {exc}") from exc
109
+
110
+ try:
111
+ merged_new = self._merge(asdict(self._defaults), edited_raw)
112
+ # This will raise TypeError if types don't match or missing required fields
113
+ _ = build_dataclass(Settings, merged_new)
114
+ except Exception as exc:
115
+ raise ValueError(f"Settings validation failed: {exc}") from exc
116
+
117
+ self._repo.save(edited_raw)
118
+ self._current = self._load()
119
+ return self._current
120
+
121
+ def _merge(self, base: dict, override: dict) -> dict:
122
+ """
123
+ Merges two dictionaries recursively. Values in the `override` dictionary
124
+ replace or update the corresponding entries in the `base` dictionary. If both
125
+ dictionaries contain a value for the same key and those values are themselves
126
+ dictionaries, the function calls itself recursively to merge the nested
127
+ dictionaries.
128
+
129
+ Args:
130
+ base (dict): The base dictionary.
131
+ override (dict): The dictionary containing values to override or update
132
+ the base dictionary.
133
+
134
+ Returns:
135
+ dict: A new dictionary that represents the merged result of the `base`
136
+ and `override` dictionaries.
137
+ """
138
+ out = dict(base)
139
+ for k, v in override.items():
140
+ if isinstance(v, dict) and isinstance(out.get(k), dict):
141
+ out[k] = self._merge(out[k], v)
142
+ else:
143
+ out[k] = v
144
+ return out
cmdbox/version.py ADDED
@@ -0,0 +1 @@
1
+ __version__ = "1.0.0"
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: cmdbox-cli
3
+ Version: 1.0.0
4
+ Summary: A cross-platform command manager for terminal workflows.
5
+ Author-email: MalloyDelacroix <malloydelacroix@phantomlamb.com>
6
+ Requires-Python: >=3.12
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: typer>=0.21.0
10
+ Requires-Dist: rich>=14.0.0
11
+ Requires-Dist: peewee>=3.18.3
12
+ Requires-Dist: prompt-toolkit>=3.0.52
13
+ Requires-Dist: pyyaml>=6.0.0
14
+ Requires-Dist: tomlkit>=0.13.3
15
+ Requires-Dist: psutil>=7.2.1
16
+ Provides-Extra: dev
17
+ Requires-Dist: black>=25.0.0; extra == "dev"
18
+ Requires-Dist: isort>=5.13.0; extra == "dev"
19
+ Requires-Dist: mkdocs>=1.6.1; extra == "dev"
20
+ Requires-Dist: ruff>=0.14.0; extra == "dev"
21
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
22
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
23
+ Dynamic: license-file
24
+
25
+ # CmdBox
26
+
27
+ A fast, structured, and searchable command runner for the terminal.
28
+
29
+ CmdBox replaces fragile shell history and scattered notes with a clean, organized system for
30
+ storing, searching, and executing commands. Designed for anyone who works in the terminal,
31
+ from occasional users to seasoned developers.
32
+
33
+ ---
34
+
35
+ ## Why CmdBox?
36
+
37
+ Most terminal users have commands they run regularly. Some are short. Many are long and
38
+ complex, packed with flags and options that are easy to forget. Recalling them means digging
39
+ through shell history, hunting through notes, or searching online every time.
40
+
41
+ CmdBox gives every command a short, memorable alias. Run it instantly. No retyping, no
42
+ searching, no forgetting.
43
+
44
+ ---
45
+
46
+ ## Features
47
+
48
+ - Named commands with short, memorable aliases
49
+ - Parameterized templates with saved and runtime variables
50
+ - Stored execution context per command (working directory, shell, environment variables, and timeout) with runtime
51
+ overrides
52
+ - Command execution history with the ability to rerun past executions
53
+ - Tag-based organization and filtering
54
+ - Field-based search across commands, variables, and tags
55
+ - Multi-line template execution via script
56
+ - Rich terminal UI with configurable display fields
57
+
58
+ ---
59
+
60
+ ## Quick Start
61
+
62
+ #### Save and run a command
63
+
64
+ ```bash
65
+ # Save a command under an alias
66
+ cb cmd add git-graph "git log --oneline --graph --decorate --all"
67
+
68
+ # Run it by alias, no subcommand needed
69
+ cb git-graph
70
+
71
+ # List all saved commands
72
+ cb cmd list
73
+
74
+ # Search saved commands
75
+ cb cmd search git
76
+ ```
77
+
78
+ #### Use variables for flexible commands
79
+
80
+ ```bash
81
+ # Save a command with variable placeholders
82
+ cb cmd add ssh-connect "ssh <user>@<host> -p <port>"
83
+
84
+ # Save variable values so they fill in automatically
85
+ cb var add user admin
86
+ cb var add host 10.0.0.5
87
+ cb var add port 22
88
+
89
+ # Run the command, variables are resolved before executing
90
+ cb ssh-connect
91
+
92
+ # What gets executed:
93
+ ssh admin@10.0.0.5 -p 22
94
+
95
+ # Supply a different value at runtime to override a saved one
96
+ cb ssh-connect --host 192.168.1.1
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Installation
102
+
103
+ ```bash
104
+ pip install cmdbox-cli
105
+ ```
106
+
107
+ Or install from source:
108
+
109
+ ```bash
110
+ git clone https://github.com/PhantomLambSoft/CmdBox.git
111
+ cd cmdbox
112
+ pip install .
113
+ ```
114
+
115
+ After installation, verify it worked:
116
+
117
+ ```bash
118
+ cb --version
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Documentation
124
+
125
+ Full documentation is available at [phantomlambsoft.github.io/CmdBox](https://phantomlambsoft.github.io/CmdBox).
@@ -0,0 +1,112 @@
1
+ cmdbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ cmdbox/container.py,sha256=iHIyHEM1DuF6vfTzJoZLg4WIHnkVYQ1XMmhFzThyeZs,4595
3
+ cmdbox/database.py,sha256=VeYkYD3xvm4cOgUCmsBClbs1ni-GZ2NwYYH75IfLSe4,1756
4
+ cmdbox/exceptions.py,sha256=JgYWezrO5FI2zBk8rRiy6AEG79P3TO8hFizYTZ09KwM,295
5
+ cmdbox/models.py,sha256=TPtgpNUXhrmeesfT_Wh0oXsUq015VWV0ozIXODglpFo,6100
6
+ cmdbox/version.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
7
+ cmdbox/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ cmdbox/cli/app.py,sha256=t_Hnq87xv-ctgEJGTqLkx3HX4ftSpKVLL7BTDDGr7kg,3724
9
+ cmdbox/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ cmdbox/cli/commands/alias_fallback.py,sha256=tv03MhtuVO0Rbvy2fql6PEOp9JxJphtx0RGRIkIrTvM,3991
11
+ cmdbox/cli/commands/command_crud.py,sha256=dPNrLmDFLNg44rQ2m-eq1HqBaSXbmKTMTuUamfz1ttQ,12215
12
+ cmdbox/cli/commands/command_run.py,sha256=72ghw4GlagI2KlsocilXQydiEb1kS6eB3XBRsPn1Qfg,7028
13
+ cmdbox/cli/commands/history.py,sha256=LQYh15xC_5cJjR0pYFBBkAeEKYtFQ-6Ckrs7Ck9JkEo,2665
14
+ cmdbox/cli/commands/init.py,sha256=golVxpTxevWA9mOBi2Uazc834Txl_aIINQWSI7poOhM,1526
15
+ cmdbox/cli/commands/settings.py,sha256=N4xhDY43ZyZ1jdXNxSv-YVjCIo6Syhs8kxwEk9usgmA,1608
16
+ cmdbox/cli/commands/tag_crud.py,sha256=-sT5GmiYKArs1I4X0t3FN3L_wPutfH3KQl8QUfHlQUg,7622
17
+ cmdbox/cli/commands/variable_crud.py,sha256=o7FP8nIzqt7P5_OoE6M_ybLwGo9Ra84iC2JEPhxVl0o,9899
18
+ cmdbox/cli/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ cmdbox/cli/common/errors.py,sha256=p_nHhSBB9k8s8xXPFfGafh7Yu6pkwRzdYMy8j7BIdHw,1933
20
+ cmdbox/cli/common/update_fields.py,sha256=hvy1-zNQxQooYuenHPn6dHvHTqX-5WcG2jwkYoE_b8s,3254
21
+ cmdbox/cli/completions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ cmdbox/cli/completions/commands.py,sha256=C2e41_9SmupvuX2lnjWgwhyXP_I6AtGcpZ3o-mveY6A,1111
23
+ cmdbox/cli/completions/fields.py,sha256=TWKTAJO23fjBPyf2pZr4H4zgGlrd_GhZOq9nPD6mHjg,1103
24
+ cmdbox/cli/completions/tags.py,sha256=qgfEjGi0ANHv-y7sNqm4ZUdb1uTz0bb1YIZHT024X0I,997
25
+ cmdbox/cli/completions/variables.py,sha256=N54UHGd4XTnW-GnrfitzASl6-Dh4jDaD0MoOEOhA2Kk,1124
26
+ cmdbox/cli/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ cmdbox/cli/handlers/command_handlers.py,sha256=eomSTzsEFUp-E8iJbqLjxGfem1rtP9y3M7EbfUBpKsY,11177
28
+ cmdbox/cli/handlers/common_handlers.py,sha256=KScAzRzVfaUu8064mAhl7mAiaYZSqfcD8uNlD8SxDOY,599
29
+ cmdbox/cli/handlers/history_handlers.py,sha256=3pOZ6fm8ki_Bm_PmCSB-YQpF1twwGDr2tdSnBnW5M-8,2895
30
+ cmdbox/cli/handlers/init_handler.py,sha256=iQDyA4FD_v99gKwepuXqrYg0PuAwkyA-2JVw89QBUaY,4486
31
+ cmdbox/cli/handlers/run_handler.py,sha256=0bYsWQ3TMuoi463QReFfsMMIOC2aX4i4G7Z4-_UaejM,5884
32
+ cmdbox/cli/handlers/settings_handler.py,sha256=GY_S7lSru_RAWNgM1TZDVuEqttBrHGU6QeQysdIsyp0,1825
33
+ cmdbox/cli/handlers/tag_handlers.py,sha256=fp52_mB9DA72Qa-NEFESwBKFYT6EYA5tXrcBqGOYbQ8,6509
34
+ cmdbox/cli/handlers/variable_handlers.py,sha256=jN-e3j8nrWbv1CRHCLGvHyLpYJOvHch7Ha0w8vhnAgw,8393
35
+ cmdbox/cli/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ cmdbox/cli/prompts/completers.py,sha256=r47CM6tT4ONnhIoY7aypMirzJx3VlqqiRuTxEWzxvcc,5424
37
+ cmdbox/cli/prompts/prompts.py,sha256=xYgzbisQ57OmMqWTkU07Wrxyp8KwH0X1nIeSAWT6Oww,3149
38
+ cmdbox/cli/prompts/validators.py,sha256=UdIKMg8pqTsezu0Il8mjL05VL9DzliE4FjDOwrT5tmY,1592
39
+ cmdbox/cli/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ cmdbox/cli/ui/console.py,sha256=m0i7hVazBczNsH-IxT7IGXkWQzTERgbQVw4ZSCh8Ojc,941
41
+ cmdbox/cli/ui/editor.py,sha256=u1VcWQ3-a6BQ7rH248nUto5CrScGcGnSDYH-ZrP8Y5c,4341
42
+ cmdbox/cli/ui/primitives.py,sha256=K7ts7gRBN5uP0Q-nvsmCtfeZMIb-q7SVNAbYxSBpUCo,10821
43
+ cmdbox/cli/ui/theme.py,sha256=eNMDOlbpL6jF8O9EZXxxY6hAXDGO7o6PjTCkFu7LFAw,1268
44
+ cmdbox/cli/ui/theme_builder.py,sha256=aFo_h4qcVVQBreeGcnxCxZNhCA01juf61rh65QAhDvg,1523
45
+ cmdbox/cli/ui/presenters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ cmdbox/cli/ui/presenters/app_presenter.py,sha256=F54334zm-yAlbwmoYeXiq1YhXivIWxJl1v9dq4OWKRg,157
47
+ cmdbox/cli/ui/presenters/command_presenter.py,sha256=He2FDLgl_ra3BGVm1M2jcx2rkBwrW_h5KVkywkh13s0,4626
48
+ cmdbox/cli/ui/presenters/history_presenter.py,sha256=bFelQ8moJt_DN-zMuPbpFfEZA3yIouWWbgaE2KS1A40,2327
49
+ cmdbox/cli/ui/presenters/init_instructions.py,sha256=c1dQ431U_7OxNM-VsR5twvVaJTwxyff17SZpLOntyH8,1876
50
+ cmdbox/cli/ui/presenters/init_presenter.py,sha256=aU48eNkiHrVEmhN34-LkauVbEdsY3dZhzmRiIxjAoeo,1539
51
+ cmdbox/cli/ui/presenters/result_presenter.py,sha256=xfr2Wcfi7T_O3-tMk6LqfQhCjiQjfFAqix-NWUgSh4k,4353
52
+ cmdbox/cli/ui/presenters/settings_presenter.py,sha256=L6-t-ykrrAALCFRvDpMEBCJKJ_wOsGj2Xf685Ztl-Bs,4773
53
+ cmdbox/cli/ui/presenters/tag_presenter.py,sha256=AnzYGlX63LfocMEnbMOaKws-jPMAFnzOtcQuVtdEBQo,2287
54
+ cmdbox/cli/ui/presenters/variable_presenter.py,sha256=LxSdIDsl8tf_IPQzA-PgA75EQzGTXHff1gEnrINndaM,2677
55
+ cmdbox/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ cmdbox/common/io.py,sha256=t4teMlSSSVDzlbN-HGz-fnSe_o7qitlrZ1LhksUeSe0,1027
57
+ cmdbox/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
+ cmdbox/core/fields.py,sha256=ycqU4sATapp_ILDAOIYNIjVHIVbjWV6hGSYjL_wxk3U,723
59
+ cmdbox/core/paths.py,sha256=rNbsLG-XtskmLcrJhQGkX3g5ibSABD1tcG8BHA_K9L4,1522
60
+ cmdbox/init/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
+ cmdbox/init/detect.py,sha256=ZOjjINtBqJVu6vkPfzG_CMh7egB67qc7JTWiUvfDMjU,2429
62
+ cmdbox/init/io.py,sha256=LTeXe-QEFgC-sVSreujexXj_PsUx3pa6WenkMYSQU20,2347
63
+ cmdbox/init/specs.py,sha256=dCzLuemIdBWzZ3b7iMqhYAf45bvi-2p-ITJGEqse19k,1597
64
+ cmdbox/init/integrations/bash.sh,sha256=4FPsabzf_R45jhsZvqb9IJZrUu02VrqDQZPXVUzn3Q0,170
65
+ cmdbox/init/integrations/cmd.bat,sha256=_5bm3hlOC181fdyRzBzVQz0rIvfihgediCrM2akSoWk,252
66
+ cmdbox/init/integrations/fish.fish,sha256=vyiVqzeDB32IbIShBX84X_KvWU4SE2GIIJ5JcATtOfQ,201
67
+ cmdbox/init/integrations/powershell.ps1,sha256=NSrtcDsqf2bG8qGjz6V1S2okzclKlyaem7Ga_jUPoLk,232
68
+ cmdbox/init/integrations/zsh.sh,sha256=4FPsabzf_R45jhsZvqb9IJZrUu02VrqDQZPXVUzn3Q0,170
69
+ cmdbox/logging_setup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
+ cmdbox/logging_setup/log_config.py,sha256=KEok7f_0HAi-BN_OelDWuhIRMragju9V7Hra97UoU5w,3993
71
+ cmdbox/logging_setup/log_decorators.py,sha256=uoF9PRKkfE4Q29V6_gUI8EBLTQed7M18p7SQY51CUlc,1220
72
+ cmdbox/logging_setup/log_handlers.py,sha256=kXGnEvRC6GYH_E-CCZRH4VdTZLjRuElyMft2qXGk008,3102
73
+ cmdbox/migrations/__init__.py,sha256=KtyxjdmzCl70_KkxA2eNZm8p4lm0cUxt3mlAQZcoYVs,61
74
+ cmdbox/migrations/errors.py,sha256=pDa2llwaFq69xmfpN3Pbj2Ebvm6U7gPp8ivQPrrpE7E,245
75
+ cmdbox/migrations/runner.py,sha256=zFDQlOvvwODr2UvwENXvATZOfKlnxygPp-fKvBWUjXQ,4076
76
+ cmdbox/migrations/versions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
+ cmdbox/repositories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
+ cmdbox/repositories/base_repository.py,sha256=Q7zuMvxMdjsdLJmlBEx6cZ3kbBpQ0CdQKkWoDIoTyzo,7117
79
+ cmdbox/repositories/command_repository.py,sha256=01TQPPWq7QKy707nbIN7Em0rfBqulMDCfEuscthKsFM,15179
80
+ cmdbox/repositories/errors.py,sha256=zuYc94iTLGO8zMu4d8ckJ4ehgtbn6s56f9jm3Cka3MY,3081
81
+ cmdbox/repositories/history_repository.py,sha256=alJeUZS0lqkSfmtCf26TW-OOhg1hGObHsFk9IYON8ng,6168
82
+ cmdbox/repositories/results.py,sha256=R-IN1PSasSTBU82jVmvcOcKPCDbnQ6Ch5JR1lvxN-aY,1040
83
+ cmdbox/repositories/tag_repository.py,sha256=Tr6ShE3kpswWG58ErqtZQ293zk9bJ8N_nzMsWgCalOQ,2972
84
+ cmdbox/repositories/validators.py,sha256=6GHximSP05eGUO0ge916dtoqY66VpLkVO6FCH4gu3PE,8510
85
+ cmdbox/repositories/variable_repository.py,sha256=xSa6ME5l5QP_L-o9GMg1bDNsXjLrHDnTOjkKuCg3VbU,12740
86
+ cmdbox/resolve/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
+ cmdbox/resolve/errors.py,sha256=1HlWg8CsRZjmApl3DopJAu6gwsSlLIzVeJG1LTfxqSg,1964
88
+ cmdbox/resolve/lookup.py,sha256=7_bH4Tbhp-Dj7nCpgSls8UjaFvkdvodbzSAGQSl_WTo,5449
89
+ cmdbox/resolve/resolver.py,sha256=XbQaoJlKUBWc7u6X6xT3A7GrSIiGEtJagEAxeCdWyKw,15713
90
+ cmdbox/resolve/type_defs.py,sha256=5uRsQlTObQAJZ5iXqguetLEmMuP9SAiG4Z5cvcAn0cY,3048
91
+ cmdbox/runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
+ cmdbox/runtime/executor.py,sha256=rYelCmQf_RpU2x_HmUU6MJWbjpA8fMdrOwCRY9-n8UQ,17183
93
+ cmdbox/runtime/results.py,sha256=pirEknfaApsFeMNWnVxiS4sUVjo9OxMbPei6zhj7olY,865
94
+ cmdbox/runtime/shell.py,sha256=Bo5HSzuHdlyLGoNZbErRmohJbFBQZGNyl5jpXGP8ssk,3017
95
+ cmdbox/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
+ cmdbox/services/command_services.py,sha256=SjHkTvSUy0UFnWjY_7tqsTjrXUfFVNAVVtcZhYr9ews,9928
97
+ cmdbox/services/errors.py,sha256=kdx4lP0F-Lls6qdAi-7D-7jT91WJd_ygaLL_ZdwYURU,923
98
+ cmdbox/services/field_selection.py,sha256=pgmLe1omRuIYu6XXtd5fF4RQ-5rsHr7rB3RFEfEg6FA,6599
99
+ cmdbox/services/history_service.py,sha256=o4Es0q9eM00M-Cerp2gEGDZJffrOEeo1_u6bKJq7XJQ,2483
100
+ cmdbox/services/run_service.py,sha256=ogfSc8GzkPhgU35e_VKT65U6YUo66baf3fqJFXZ6uVY,8321
101
+ cmdbox/services/tag_services.py,sha256=lhqaBt0Lt6vP1uAbrvgZKd7ZjtMaHMKGWgSlUeXNSa4,4462
102
+ cmdbox/services/variable_services.py,sha256=T9Lk3aliJk5KA9U3VqAAQU5iznm1lWvABYSxFSJE0E0,8352
103
+ cmdbox/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
104
+ cmdbox/settings/models.py,sha256=PrgiFvp0yiM2ejJlkGKnOW0m9PVEGPDZcb4hFKoJJOY,3372
105
+ cmdbox/settings/settings_repository.py,sha256=O7waVxKE5jg7IdECaypti1OEPO1Q1O1mZRIF64WC7vw,998
106
+ cmdbox/settings/settings_service.py,sha256=sH39lCwnoBzYjd4O8H2kVUTwABAFkd6A52LUk48ZPsU,5490
107
+ cmdbox_cli-1.0.0.dist-info/licenses/LICENSE,sha256=OSLgtZVjvB0aJpJal0yre-GKBXdRZSTKr1zaDx2Sj30,1069
108
+ cmdbox_cli-1.0.0.dist-info/METADATA,sha256=YgUrPnGtF_kg7KfSRSiy2wrwxYom4xZcKYOxD3BMch8,3180
109
+ cmdbox_cli-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
110
+ cmdbox_cli-1.0.0.dist-info/entry_points.txt,sha256=RhXPl2B9pZ5L7M9gyqTuL3k7BNOChXywuk2zOy91-bA,43
111
+ cmdbox_cli-1.0.0.dist-info/top_level.txt,sha256=eMEkD5jn8_0PkCAL8h5xJu4qAzF2O8Wf3vegFkKUXR4,7
112
+ cmdbox_cli-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cb = cmdbox.cli.app:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Phantom Lamb
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ cmdbox