mct-cli 0.2.3__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.
mct/config.py ADDED
@@ -0,0 +1,428 @@
1
+ """Configuration management for declarative macOS settings."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ import yaml
8
+
9
+ from . import defaults
10
+
11
+
12
+ CONFIG_PATH = Path.home() / ".config" / "mct" / "config.yaml"
13
+
14
+
15
+ @dataclass
16
+ class Setting:
17
+ """Represents a macOS setting that can be read/written."""
18
+
19
+ domain: str
20
+ key: str
21
+ value_type: str # 'bool', 'int', 'float', 'string'
22
+ restart_app: str | None = None # App to restart after changing
23
+ description: str = ""
24
+
25
+
26
+ # Registry of all supported settings
27
+ # Format: config_key -> Setting
28
+ SETTINGS: dict[str, Setting] = {
29
+ # Dock settings
30
+ "dock.size": Setting(
31
+ domain="com.apple.dock",
32
+ key="tilesize",
33
+ value_type="int",
34
+ restart_app="Dock",
35
+ description="Dock icon size (32-128)",
36
+ ),
37
+ "dock.autohide": Setting(
38
+ domain="com.apple.dock",
39
+ key="autohide",
40
+ value_type="bool",
41
+ restart_app="Dock",
42
+ description="Auto-hide the Dock",
43
+ ),
44
+ "dock.size_immutable": Setting(
45
+ domain="com.apple.dock",
46
+ key="size-immutable",
47
+ value_type="bool",
48
+ restart_app="Dock",
49
+ description="Lock Dock size",
50
+ ),
51
+ "dock.magnification": Setting(
52
+ domain="com.apple.dock",
53
+ key="magnification",
54
+ value_type="bool",
55
+ restart_app="Dock",
56
+ description="Enable Dock magnification",
57
+ ),
58
+ "dock.largesize": Setting(
59
+ domain="com.apple.dock",
60
+ key="largesize",
61
+ value_type="int",
62
+ restart_app="Dock",
63
+ description="Magnified icon size (16-128)",
64
+ ),
65
+ "dock.orientation": Setting(
66
+ domain="com.apple.dock",
67
+ key="orientation",
68
+ value_type="string",
69
+ restart_app="Dock",
70
+ description="Dock position: left, bottom, right",
71
+ ),
72
+ "dock.mineffect": Setting(
73
+ domain="com.apple.dock",
74
+ key="mineffect",
75
+ value_type="string",
76
+ restart_app="Dock",
77
+ description="Minimize effect: genie, scale, suck",
78
+ ),
79
+ "dock.minimize_to_application": Setting(
80
+ domain="com.apple.dock",
81
+ key="minimize-to-application",
82
+ value_type="bool",
83
+ restart_app="Dock",
84
+ description="Minimize windows into application icon",
85
+ ),
86
+ "dock.show_recents": Setting(
87
+ domain="com.apple.dock",
88
+ key="show-recents",
89
+ value_type="bool",
90
+ restart_app="Dock",
91
+ description="Show recent applications in Dock",
92
+ ),
93
+ "dock.static_only": Setting(
94
+ domain="com.apple.dock",
95
+ key="static-only",
96
+ value_type="bool",
97
+ restart_app="Dock",
98
+ description="Show only open applications",
99
+ ),
100
+ # Finder settings
101
+ "finder.show_extensions": Setting(
102
+ domain="NSGlobalDomain",
103
+ key="AppleShowAllExtensions",
104
+ value_type="bool",
105
+ restart_app="Finder",
106
+ description="Show all file extensions",
107
+ ),
108
+ "finder.show_hidden": Setting(
109
+ domain="com.apple.finder",
110
+ key="AppleShowAllFiles",
111
+ value_type="bool",
112
+ restart_app="Finder",
113
+ description="Show hidden files",
114
+ ),
115
+ "finder.show_path_bar": Setting(
116
+ domain="com.apple.finder",
117
+ key="ShowPathbar",
118
+ value_type="bool",
119
+ restart_app="Finder",
120
+ description="Show path bar at bottom",
121
+ ),
122
+ "finder.show_status_bar": Setting(
123
+ domain="com.apple.finder",
124
+ key="ShowStatusBar",
125
+ value_type="bool",
126
+ restart_app="Finder",
127
+ description="Show status bar at bottom",
128
+ ),
129
+ "finder.default_view": Setting(
130
+ domain="com.apple.finder",
131
+ key="FXPreferredViewStyle",
132
+ value_type="string",
133
+ restart_app="Finder",
134
+ description="Default view: icnv, Nlsv, clmv, glyv",
135
+ ),
136
+ "finder.search_scope": Setting(
137
+ domain="com.apple.finder",
138
+ key="FXDefaultSearchScope",
139
+ value_type="string",
140
+ restart_app="Finder",
141
+ description="Search scope: SCcf (current folder), SCsp (previous scope), SCev (entire Mac)",
142
+ ),
143
+ "finder.empty_trash_warning": Setting(
144
+ domain="com.apple.finder",
145
+ key="WarnOnEmptyTrash",
146
+ value_type="bool",
147
+ restart_app="Finder",
148
+ description="Warn before emptying trash",
149
+ ),
150
+ "finder.new_window_target": Setting(
151
+ domain="com.apple.finder",
152
+ key="NewWindowTarget",
153
+ value_type="string",
154
+ restart_app="Finder",
155
+ description="New window target: PfHm (Home), PfDe (Desktop), PfDo (Documents), PfLo (other)",
156
+ ),
157
+ # Screenshot settings
158
+ "screenshot.location": Setting(
159
+ domain="com.apple.screencapture",
160
+ key="location",
161
+ value_type="string",
162
+ restart_app="SystemUIServer",
163
+ description="Screenshot save location",
164
+ ),
165
+ "screenshot.format": Setting(
166
+ domain="com.apple.screencapture",
167
+ key="type",
168
+ value_type="string",
169
+ restart_app="SystemUIServer",
170
+ description="Screenshot format: png, jpg, gif, pdf, tiff",
171
+ ),
172
+ "screenshot.disable_shadow": Setting(
173
+ domain="com.apple.screencapture",
174
+ key="disable-shadow",
175
+ value_type="bool",
176
+ restart_app="SystemUIServer",
177
+ description="Disable window shadow in screenshots",
178
+ ),
179
+ "screenshot.include_date": Setting(
180
+ domain="com.apple.screencapture",
181
+ key="include-date",
182
+ value_type="bool",
183
+ restart_app="SystemUIServer",
184
+ description="Include date in screenshot filename",
185
+ ),
186
+ "screenshot.show_thumbnail": Setting(
187
+ domain="com.apple.screencapture",
188
+ key="show-thumbnail",
189
+ value_type="bool",
190
+ restart_app="SystemUIServer",
191
+ description="Show floating thumbnail after capture",
192
+ ),
193
+ # Keyboard settings
194
+ "keyboard.press_and_hold": Setting(
195
+ domain="NSGlobalDomain",
196
+ key="ApplePressAndHoldEnabled",
197
+ value_type="bool",
198
+ restart_app=None,
199
+ description="Enable press-and-hold for accents (false = key repeat)",
200
+ ),
201
+ "keyboard.key_repeat_rate": Setting(
202
+ domain="NSGlobalDomain",
203
+ key="KeyRepeat",
204
+ value_type="int",
205
+ restart_app=None,
206
+ description="Key repeat rate (lower = faster, 1-15)",
207
+ ),
208
+ "keyboard.initial_key_repeat": Setting(
209
+ domain="NSGlobalDomain",
210
+ key="InitialKeyRepeat",
211
+ value_type="int",
212
+ restart_app=None,
213
+ description="Delay before key repeat starts (lower = faster, 10-120)",
214
+ ),
215
+ # Trackpad settings
216
+ "trackpad.tap_to_click": Setting(
217
+ domain="com.apple.AppleMultitouchTrackpad",
218
+ key="Clicking",
219
+ value_type="bool",
220
+ restart_app=None,
221
+ description="Enable tap to click",
222
+ ),
223
+ "trackpad.natural_scrolling": Setting(
224
+ domain="NSGlobalDomain",
225
+ key="com.apple.swipescrolldirection",
226
+ value_type="bool",
227
+ restart_app=None,
228
+ description="Natural scrolling direction",
229
+ ),
230
+ "trackpad.tracking_speed": Setting(
231
+ domain="NSGlobalDomain",
232
+ key="com.apple.trackpad.scaling",
233
+ value_type="float",
234
+ restart_app=None,
235
+ description="Tracking speed (0.0-3.0)",
236
+ ),
237
+ # Menu bar settings
238
+ "menubar.autohide": Setting(
239
+ domain="NSGlobalDomain",
240
+ key="_HIHideMenuBar",
241
+ value_type="bool",
242
+ restart_app="SystemUIServer",
243
+ description="Auto-hide menu bar",
244
+ ),
245
+ "menubar.show_background": Setting(
246
+ domain="NSGlobalDomain",
247
+ key="NSStatusBarShowsMenuBarBackground",
248
+ value_type="bool",
249
+ restart_app="SystemUIServer",
250
+ description="Show menu bar background (Tahoe)",
251
+ ),
252
+ # Mission Control settings
253
+ "mission_control.auto_rearrange": Setting(
254
+ domain="com.apple.dock",
255
+ key="mru-spaces",
256
+ value_type="bool",
257
+ restart_app="Dock",
258
+ description="Automatically rearrange Spaces based on recent use",
259
+ ),
260
+ "mission_control.group_by_app": Setting(
261
+ domain="com.apple.dock",
262
+ key="expose-group-apps",
263
+ value_type="bool",
264
+ restart_app="Dock",
265
+ description="Group windows by application",
266
+ ),
267
+ # Accessibility settings
268
+ "accessibility.reduce_transparency": Setting(
269
+ domain="com.apple.universalaccess",
270
+ key="reduceTransparency",
271
+ value_type="bool",
272
+ restart_app=None,
273
+ description="Reduce transparency (helps with Liquid Glass)",
274
+ ),
275
+ "accessibility.reduce_motion": Setting(
276
+ domain="com.apple.universalaccess",
277
+ key="reduceMotion",
278
+ value_type="bool",
279
+ restart_app=None,
280
+ description="Reduce motion effects",
281
+ ),
282
+ }
283
+
284
+
285
+ @dataclass
286
+ class ConfigDiff:
287
+ """Represents differences between current state and config."""
288
+
289
+ key: str
290
+ current: Any
291
+ desired: Any
292
+ setting: Setting
293
+
294
+
295
+ def load_config() -> dict[str, Any]:
296
+ """Load configuration from YAML file.
297
+
298
+ Returns:
299
+ Nested dict of configuration values
300
+ """
301
+ if not CONFIG_PATH.exists():
302
+ return {}
303
+
304
+ with open(CONFIG_PATH) as f:
305
+ return yaml.safe_load(f) or {}
306
+
307
+
308
+ def save_config(config: dict[str, Any]) -> None:
309
+ """Save configuration to YAML file."""
310
+ CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
311
+ with open(CONFIG_PATH, "w") as f:
312
+ yaml.dump(config, f, default_flow_style=False, sort_keys=False)
313
+
314
+
315
+ def flatten_config(config: dict[str, Any], prefix: str = "") -> dict[str, Any]:
316
+ """Flatten nested config dict to dot-notation keys.
317
+
318
+ Example: {'dock': {'size': 48}} -> {'dock.size': 48}
319
+ """
320
+ result = {}
321
+ for key, value in config.items():
322
+ full_key = f"{prefix}.{key}" if prefix else key
323
+ if isinstance(value, dict):
324
+ result.update(flatten_config(value, full_key))
325
+ else:
326
+ result[full_key] = value
327
+ return result
328
+
329
+
330
+ def unflatten_config(flat: dict[str, Any]) -> dict[str, Any]:
331
+ """Unflatten dot-notation keys to nested dict.
332
+
333
+ Example: {'dock.size': 48} -> {'dock': {'size': 48}}
334
+ """
335
+ result: dict[str, Any] = {}
336
+ for key, value in flat.items():
337
+ parts = key.split(".")
338
+ current = result
339
+ for part in parts[:-1]:
340
+ if part not in current:
341
+ current[part] = {}
342
+ current = current[part]
343
+ current[parts[-1]] = value
344
+ return result
345
+
346
+
347
+ def read_current_state() -> dict[str, Any]:
348
+ """Read all supported settings from the system."""
349
+ state = {}
350
+ for key, setting in SETTINGS.items():
351
+ value = defaults.read(setting.domain, setting.key)
352
+ if value is not None:
353
+ # Convert to proper type based on setting definition
354
+ if setting.value_type == "bool":
355
+ # macOS returns 0/1 for bools
356
+ value = bool(value) if isinstance(value, int) else value
357
+ state[key] = value
358
+ return state
359
+
360
+
361
+ def compute_diff(config: dict[str, Any]) -> list[ConfigDiff]:
362
+ """Compute differences between config and current system state.
363
+
364
+ Args:
365
+ config: Flattened config dict
366
+
367
+ Returns:
368
+ List of ConfigDiff for settings that differ
369
+ """
370
+ diffs = []
371
+ current_state = read_current_state()
372
+
373
+ for key, desired in config.items():
374
+ if key not in SETTINGS:
375
+ continue
376
+
377
+ setting = SETTINGS[key]
378
+ current = current_state.get(key)
379
+
380
+ if current != desired:
381
+ diffs.append(
382
+ ConfigDiff(key=key, current=current, desired=desired, setting=setting)
383
+ )
384
+
385
+ return diffs
386
+
387
+
388
+ def apply_setting(key: str, value: Any) -> str | None:
389
+ """Apply a single setting.
390
+
391
+ Returns:
392
+ App name that needs restart, or None
393
+ """
394
+ if key not in SETTINGS:
395
+ raise ValueError(f"Unknown setting: {key}")
396
+
397
+ setting = SETTINGS[key]
398
+ defaults.write(setting.domain, setting.key, value, setting.value_type)
399
+ return setting.restart_app
400
+
401
+
402
+ def apply_config(config: dict[str, Any], dry_run: bool = False) -> list[ConfigDiff]:
403
+ """Apply configuration to the system.
404
+
405
+ Args:
406
+ config: Flattened config dict
407
+ dry_run: If True, don't actually apply changes
408
+
409
+ Returns:
410
+ List of changes that were (or would be) applied
411
+ """
412
+ diffs = compute_diff(config)
413
+
414
+ if dry_run:
415
+ return diffs
416
+
417
+ apps_to_restart: set[str] = set()
418
+
419
+ for diff in diffs:
420
+ restart_app = apply_setting(diff.key, diff.desired)
421
+ if restart_app:
422
+ apps_to_restart.add(restart_app)
423
+
424
+ # Restart affected apps
425
+ for app in apps_to_restart:
426
+ defaults.restart_app(app)
427
+
428
+ return diffs
mct/defaults.py ADDED
@@ -0,0 +1,124 @@
1
+ """Helper module for macOS defaults commands."""
2
+
3
+ import subprocess
4
+ from typing import Any
5
+
6
+
7
+ class DefaultsError(Exception):
8
+ """Error when reading/writing macOS defaults."""
9
+
10
+ pass
11
+
12
+
13
+ def read(domain: str, key: str) -> Any:
14
+ """Read a value from macOS defaults.
15
+
16
+ Args:
17
+ domain: The defaults domain (e.g., 'com.apple.dock')
18
+ key: The key to read
19
+
20
+ Returns:
21
+ The value, or None if not found
22
+
23
+ Raises:
24
+ DefaultsError: If there's an error reading the value
25
+ """
26
+ try:
27
+ result = subprocess.run(
28
+ ["defaults", "read", domain, key],
29
+ capture_output=True,
30
+ text=True,
31
+ check=True,
32
+ )
33
+ value = result.stdout.strip()
34
+
35
+ # Try to parse as int
36
+ try:
37
+ return int(value)
38
+ except ValueError:
39
+ pass
40
+
41
+ # Try to parse as float
42
+ try:
43
+ return float(value)
44
+ except ValueError:
45
+ pass
46
+
47
+ # Handle boolean strings
48
+ if value in ("1", "true", "yes"):
49
+ return True
50
+ if value in ("0", "false", "no"):
51
+ return False
52
+
53
+ return value
54
+ except subprocess.CalledProcessError:
55
+ return None
56
+
57
+
58
+ def read_global(key: str) -> Any:
59
+ """Read a value from global defaults (-g)."""
60
+ return read("-g", key)
61
+
62
+
63
+ def write(domain: str, key: str, value: Any, value_type: str | None = None) -> None:
64
+ """Write a value to macOS defaults.
65
+
66
+ Args:
67
+ domain: The defaults domain (e.g., 'com.apple.dock')
68
+ key: The key to write
69
+ value: The value to write
70
+ value_type: Optional type hint ('bool', 'int', 'float', 'string')
71
+
72
+ Raises:
73
+ DefaultsError: If there's an error writing the value
74
+ """
75
+ cmd = ["defaults", "write", domain, key]
76
+
77
+ if value_type == "bool" or isinstance(value, bool):
78
+ cmd.extend(["-bool", "true" if value else "false"])
79
+ elif value_type == "int" or isinstance(value, int):
80
+ cmd.extend(["-int", str(value)])
81
+ elif value_type == "float" or isinstance(value, float):
82
+ cmd.extend(["-float", str(value)])
83
+ else:
84
+ cmd.append(str(value))
85
+
86
+ try:
87
+ subprocess.run(cmd, check=True, capture_output=True, text=True)
88
+ except subprocess.CalledProcessError as e:
89
+ raise DefaultsError(f"Failed to write {domain} {key}: {e.stderr}") from e
90
+
91
+
92
+ def write_global(key: str, value: Any, value_type: str | None = None) -> None:
93
+ """Write a value to global defaults (-g)."""
94
+ write("-g", key, value, value_type)
95
+
96
+
97
+ def delete(domain: str, key: str) -> None:
98
+ """Delete a key from macOS defaults."""
99
+ try:
100
+ subprocess.run(
101
+ ["defaults", "delete", domain, key],
102
+ check=True,
103
+ capture_output=True,
104
+ text=True,
105
+ )
106
+ except subprocess.CalledProcessError:
107
+ pass # Key might not exist
108
+
109
+
110
+ def restart_app(app_name: str) -> None:
111
+ """Restart an application to apply changes.
112
+
113
+ Args:
114
+ app_name: The application name (e.g., 'Dock', 'Finder', 'SystemUIServer')
115
+ """
116
+ try:
117
+ subprocess.run(
118
+ ["killall", app_name],
119
+ check=True,
120
+ capture_output=True,
121
+ text=True,
122
+ )
123
+ except subprocess.CalledProcessError:
124
+ pass # App might not be running
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.4
2
+ Name: mct-cli
3
+ Version: 0.2.3
4
+ Summary: macOS Configuration Tools
5
+ Author-email: Oscar Colunga <oscar@ancile.dev>
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: pyyaml>=6.0
9
+ Requires-Dist: typer>=0.9.0
10
+ Description-Content-Type: text/markdown
11
+
12
+ # macOS Configuration Tools (mct)
13
+
14
+ A personal collection of CLI tools for managing macOS settings through a simple, intuitive interface.
15
+
16
+ ## Features
17
+
18
+ Currently implemented:
19
+
20
+ ### General
21
+ - Check version: `mct --version` or `mct -v` - Display the installed version
22
+
23
+ ### Dock Management
24
+ - Set dock size: `mct dock size <value>` (32-128)
25
+ - Show current dock size: `mct dock size`
26
+ - Auto-hide controls:
27
+ - `mct dock hide` - Enable auto-hide
28
+ - `mct dock show` - Disable auto-hide
29
+ - Size lock controls:
30
+ - `mct dock lock` - Lock dock size
31
+ - `mct dock unlock` - Unlock dock size
32
+ - Reset options:
33
+ - `mct dock reset -s` - Reset size to default (64)
34
+ - `mct dock reset -h` - Reset auto-hide to default (disabled)
35
+ - `mct dock reset -l` - Reset size lock to default (unlocked)
36
+ - `mct dock reset -a` - Reset all dock settings
37
+
38
+ ### Keyboard Management
39
+ - Key repeat controls:
40
+ - `mct keyboard hold` - Enable press-and-hold for accented characters
41
+ - `mct keyboard repeat` - Enable key repeat (disables accents)
42
+ - Reset options:
43
+ - `mct keyboard reset -h` - Reset key hold to default (enabled)
44
+ - `mct keyboard reset -a` - Reset all keyboard settings
45
+
46
+ ### System Management
47
+ - Touch ID for sudo:
48
+ - `mct system touchid` - Enable Touch ID authentication for sudo with interactive backup management
49
+ - `mct system reset -t` - Reset Touch ID sudo configuration from backup
50
+ - `mct system reset -a` - Reset all system settings to defaults
51
+
52
+ Planned features:
53
+ - Configuration file support (`~/.config/mct/config.toml`) for:
54
+ - Setting default values for commands
55
+ - Storing preferred configurations
56
+ - Batch applying multiple settings at once
57
+ - Example configuration:
58
+ ```toml
59
+ [dock]
60
+ default_size = 48
61
+ auto_hide = true
62
+ size_locked = false
63
+
64
+ [keyboard]
65
+ key_hold = true
66
+
67
+ [system]
68
+ touch_id_sudo = true
69
+ ```
70
+ - More dock management options
71
+ - System preferences management
72
+ - And more...
73
+
74
+ ## Installation
75
+
76
+ ### Using Homebrew (recommended)
77
+ ```bash
78
+ # Add the tap repository
79
+ brew tap ocolunga/mct-cli
80
+
81
+ # Install mct-cli
82
+ brew install mct-cli
83
+ ```
84
+
85
+ ### Using pip
86
+ ```bash
87
+ pip install mct-cli
88
+ ```
89
+
90
+ ### Using uv
91
+ ```bash
92
+ uv tool install mct-cli
93
+ ```
94
+
95
+ ### From source
96
+ ```bash
97
+ git clone https://github.com/ocolunga/mct.git
98
+ cd mct
99
+ uv sync
100
+ uv run mct --help
101
+ ```
102
+
103
+ ## Usage Examples
104
+
105
+ ```bash
106
+ # Show help
107
+ mct --help
108
+ mct dock --help
109
+ mct keyboard --help
110
+ mct system --help
111
+
112
+ # Check version
113
+ mct --version
114
+
115
+ # Dock Examples
116
+ mct dock size 48 # Set dock size to 48
117
+ mct dock size # Show current dock size
118
+ mct dock hide # Enable auto-hide
119
+ mct dock show # Disable auto-hide
120
+ mct dock lock # Lock dock size
121
+ mct dock unlock # Unlock dock size
122
+ mct dock reset -s -h # Reset both size and auto-hide
123
+
124
+ # Keyboard Examples
125
+ mct keyboard hold # Enable press-and-hold for accents
126
+ mct keyboard repeat # Enable key repeat (disable accents)
127
+ mct keyboard reset -a # Reset all keyboard settings
128
+
129
+ # System Examples
130
+ mct system touchid # Enable Touch ID for sudo with interactive backup
131
+ mct system reset -t # Reset Touch ID sudo configuration from backup
132
+ mct system reset -a # Reset all system settings to defaults
133
+ ```
134
+
135
+ Note: Some commands may require restarting applications to take effect.
136
+
137
+ ## License
138
+
139
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,14 @@
1
+ mct/__init__.py,sha256=2XBV1zscKmG3c5detK3HeeI1fdhVxfUpku_d_3DgxXk,168
2
+ mct/cli.py,sha256=hqVp11SQzR7pyVFmj59jPnIRo3YkvUXMqHxIK7aiIt4,6616
3
+ mct/config.py,sha256=CQ8mMdKsAIZNJCHonpjCfVHEBGIAzm82A7VnADBNEjs,12675
4
+ mct/defaults.py,sha256=6wLX5ODd39k7t-PSo0XdYsMICoUJ31aekN0HwrTMWVM,3303
5
+ mct/commands/dock.py,sha256=tSZFtcAJInDoG6gvJRsslSMTaOdqRgCloLUTyM9GI9o,5124
6
+ mct/commands/finder.py,sha256=devM03j4VquMQGDQM24_or5le9_3_I-Q7GAKaph6wLQ,4990
7
+ mct/commands/keyboard.py,sha256=uKFKQlIE0dO9nwVq-YWVPGhdq7Mqp5E1pU-I19TLXm4,2414
8
+ mct/commands/screenshot.py,sha256=v1s_89sL7gX_KKt4uyjc0zKHgUO9XzItmfdRGrdZ8x8,4920
9
+ mct/commands/system.py,sha256=Zf7PlvwqY1Go3K4BCjSc6GIaOwfw5SaZ-yjjRNsCCjc,8351
10
+ mct_cli-0.2.3.dist-info/METADATA,sha256=TOmgnQtOEHgk0Nof6K5An7cUru2XDVfqh4gi6Bfrxbk,3644
11
+ mct_cli-0.2.3.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
12
+ mct_cli-0.2.3.dist-info/entry_points.txt,sha256=QiGrcxAWYra7JelqpSF1reNTg8fNMMrTMHRV5hb--lA,37
13
+ mct_cli-0.2.3.dist-info/licenses/LICENSE,sha256=FyuBsNr3YLXHPRQfWIpCAC4brUeSdYelr01V-Fkog8U,1066
14
+ mct_cli-0.2.3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any